diff --git a/src/gallium/drivers/d3d12/d3d12_blit.cpp b/src/gallium/drivers/d3d12/d3d12_blit.cpp index 0311a6ca59d..476b12c23d3 100644 --- a/src/gallium/drivers/d3d12/d3d12_blit.cpp +++ b/src/gallium/drivers/d3d12/d3d12_blit.cpp @@ -637,14 +637,17 @@ get_stencil_resolve_vs(struct d3d12_context *ctx) } static void * -get_stencil_resolve_fs(struct d3d12_context *ctx) +get_stencil_resolve_fs(struct d3d12_context *ctx, bool no_flip) { - if (ctx->stencil_resolve_fs) + if (!no_flip && ctx->stencil_resolve_fs) return ctx->stencil_resolve_fs; + if (no_flip && ctx->stencil_resolve_fs_no_flip) + return ctx->stencil_resolve_fs_no_flip; + nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT, dxil_get_nir_compiler_options(), - "stencil_resolve_fs"); + no_flip ? "stencil_resolve_fs_no_flip" : "stencil_resolve_fs"); nir_variable *stencil_out = nir_variable_create(b.shader, nir_var_shader_out, @@ -666,11 +669,39 @@ get_stencil_resolve_fs(struct d3d12_context *ctx) pos_in->data.location = VARYING_SLOT_POS; // VARYING_SLOT_VAR0? nir_ssa_def *pos = nir_load_var(&b, pos_in); + nir_ssa_def *pos_src; + + if (no_flip) + pos_src = pos; + else { + nir_tex_instr *txs = nir_tex_instr_create(b.shader, 1); + txs->op = nir_texop_txs; + txs->sampler_dim = GLSL_SAMPLER_DIM_MS; + txs->src[0].src_type = nir_tex_src_texture_deref; + txs->src[0].src = nir_src_for_ssa(tex_deref); + txs->is_array = false; + txs->dest_type = nir_type_int; + + nir_ssa_dest_init(&txs->instr, &txs->dest, 2, 32, "tex"); + nir_builder_instr_insert(&b, &txs->instr); + + pos_src = nir_vec4(&b, + nir_channel(&b, pos, 0), + /*Height - pos_dest.y - 1*/ + nir_fsub(&b, + nir_fsub(&b, + nir_channel(&b, nir_i2f32(&b, &txs->dest.ssa), 1), + nir_channel(&b, pos, 1)), + nir_imm_float(&b, 1.0)), + nir_channel(&b, pos, 2), + nir_channel(&b, pos, 3)); + } + nir_tex_instr *tex = nir_tex_instr_create(b.shader, 3); tex->sampler_dim = GLSL_SAMPLER_DIM_MS; tex->op = nir_texop_txf_ms; tex->src[0].src_type = nir_tex_src_coord; - tex->src[0].src = nir_src_for_ssa(nir_channels(&b, nir_f2i32(&b, pos), 0x3)); + tex->src[0].src = nir_src_for_ssa(nir_channels(&b, nir_f2i32(&b, pos_src), 0x3)); tex->src[1].src_type = nir_tex_src_ms_index; tex->src[1].src = nir_src_for_ssa(nir_imm_int(&b, 0)); /* just use first sample */ tex->src[2].src_type = nir_tex_src_texture_deref; @@ -687,9 +718,16 @@ get_stencil_resolve_fs(struct d3d12_context *ctx) struct pipe_shader_state state = {}; state.type = PIPE_SHADER_IR_NIR; state.ir.nir = b.shader; - ctx->stencil_resolve_fs = ctx->base.create_fs_state(&ctx->base, &state); + void *result; + if (no_flip) { + result = ctx->base.create_fs_state(&ctx->base, &state); + ctx->stencil_resolve_fs_no_flip = result; + } else { + result = ctx->base.create_fs_state(&ctx->base, &state); + ctx->stencil_resolve_fs = result; + } - return ctx->stencil_resolve_fs; + return result; } static void * @@ -743,7 +781,7 @@ resolve_stencil_to_temp(struct d3d12_context *ctx, pctx->bind_sampler_states(pctx, PIPE_SHADER_FRAGMENT, 0, 1, &sampler_state); util_blitter_custom_shader(ctx->blitter, dst_surf, get_stencil_resolve_vs(ctx), - get_stencil_resolve_fs(ctx)); + get_stencil_resolve_fs(ctx, info->src.box.height == info->dst.box.height)); util_blitter_restore_textures(ctx->blitter); pipe_surface_reference(&dst_surf, NULL); pipe_sampler_view_reference(&src_view, NULL); diff --git a/src/gallium/drivers/d3d12/d3d12_context.h b/src/gallium/drivers/d3d12/d3d12_context.h index fc75d7a5627..5d7cdec3fe2 100644 --- a/src/gallium/drivers/d3d12/d3d12_context.h +++ b/src/gallium/drivers/d3d12/d3d12_context.h @@ -251,7 +251,8 @@ struct d3d12_context { #endif struct pipe_query *timestamp_query; - void *stencil_resolve_vs, *stencil_resolve_fs, *sampler_state; /* used by d3d12_blit.cpp */ + /* used by d3d12_blit.cpp */ + void *stencil_resolve_vs, *stencil_resolve_fs, *stencil_resolve_fs_no_flip, *sampler_state; }; static inline struct d3d12_context *