From de48960b33cf2d6713044b2a38c52967ee528c7b Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Wed, 7 Aug 2024 18:35:51 +0200 Subject: [PATCH] vkd3d-shader/fx: Add support for the OMSetRenderTargets() state. --- libs/vkd3d-shader/fx.c | 42 ++++++++++++++++--- libs/vkd3d-shader/hlsl_codegen.c | 4 +- .../hlsl/effect-pass-states-fx_5.shader_test | 3 ++ 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/libs/vkd3d-shader/fx.c b/libs/vkd3d-shader/fx.c index 5adb61d7..6b8db1fe 100644 --- a/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d-shader/fx.c @@ -111,7 +111,7 @@ static void get_state_block_function_components(const struct state_block_functio { unsigned int i; - assert(comp_count >= info->max_args); + assert(comp_count <= info->max_args); if (info->min_args == info->max_args) { @@ -125,7 +125,7 @@ static void get_state_block_function_components(const struct state_block_functio { for (i = 0; i < comp_count - 2; ++i) add_function_component(&components, "RenderTargetView", true, i + 1); - add_function_component(&components, "DepthStencilView", true, 0); + add_function_component(&components, "DepthStencilView", false, 0); add_function_component(&components, "RenderTargetView", true, 0); } } @@ -1393,11 +1393,8 @@ static void write_fx_4_state_assignment(const struct hlsl_ir_var *var, struct hl struct hlsl_ctx *ctx = fx->ctx; struct hlsl_ir_node *value = entry->args->node; - if (entry->lhs_has_index) - hlsl_fixme(ctx, &var->loc, "Unsupported assignment to array element."); - put_u32(buffer, entry->name_id); - put_u32(buffer, 0); /* TODO: destination index */ + put_u32(buffer, entry->lhs_index); type_offset = put_u32(buffer, 0); rhs_offset = put_u32(buffer, 0); @@ -1504,6 +1501,8 @@ enum state_property_component_type FX_HULLSHADER, FX_COMPUTESHADER, FX_TEXTURE, + FX_DEPTHSTENCILVIEW, + FX_RENDERTARGETVIEW, }; static inline bool is_object_fx_type(enum state_property_component_type type) @@ -1516,6 +1515,8 @@ static inline bool is_object_fx_type(enum state_property_component_type type) case FX_HULLSHADER: case FX_COMPUTESHADER: case FX_TEXTURE: + case FX_RENDERTARGETVIEW: + case FX_DEPTHSTENCILVIEW: return true; default: return false; @@ -1538,6 +1539,10 @@ static inline enum hlsl_type_class hlsl_type_class_from_fx_type(enum state_prope return HLSL_CLASS_COMPUTE_SHADER; case FX_TEXTURE: return HLSL_CLASS_TEXTURE; + case FX_RENDERTARGETVIEW: + return HLSL_CLASS_RENDER_TARGET_VIEW; + case FX_DEPTHSTENCILVIEW: + return HLSL_CLASS_DEPTH_STENCIL_VIEW; default: vkd3d_unreachable(); } @@ -1671,6 +1676,10 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl { { "RasterizerState", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_RASTERIZER, 1, 1, 0 }, { "DepthStencilState", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_DEPTHSTENCIL, 1, 1, 1 }, + + { "RenderTargetView", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_RENDERTARGETVIEW, 1, 8, 3 }, + { "DepthStencilView", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_DEPTHSTENCILVIEW, 1, 1, 4 }, + { "DS_StencilRef", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 9 }, { "FillMode", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 12, fill_values }, @@ -1748,6 +1757,27 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl return; } + if (entry->lhs_has_index && state->array_size == 1) + { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Can't use array-style access for non-array state %s.", + entry->name); + return; + } + + if (!entry->lhs_has_index && state->array_size > 1) + { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Expected array index for array state %s.", + entry->name); + return; + } + + if (entry->lhs_has_index && (state->array_size <= entry->lhs_index)) + { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Invalid element index %u for the state %s[%u].", + entry->lhs_index, state->name, state->array_size); + return; + } + entry->name_id = state->id; replace_context.values = state->values; diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 9a076c4a..b87f4420 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1645,6 +1645,8 @@ static bool copy_propagation_transform_load(struct hlsl_ctx *ctx, case HLSL_CLASS_COMPUTE_SHADER: case HLSL_CLASS_DOMAIN_SHADER: case HLSL_CLASS_HULL_SHADER: + case HLSL_CLASS_RENDER_TARGET_VIEW: + case HLSL_CLASS_DEPTH_STENCIL_VIEW: break; case HLSL_CLASS_MATRIX: @@ -1655,10 +1657,8 @@ static bool copy_propagation_transform_load(struct hlsl_ctx *ctx, * matrices yet. */ return false; - case HLSL_CLASS_DEPTH_STENCIL_VIEW: case HLSL_CLASS_EFFECT_GROUP: case HLSL_CLASS_PASS: - case HLSL_CLASS_RENDER_TARGET_VIEW: case HLSL_CLASS_TECHNIQUE: case HLSL_CLASS_VOID: vkd3d_unreachable(); diff --git a/tests/hlsl/effect-pass-states-fx_5.shader_test b/tests/hlsl/effect-pass-states-fx_5.shader_test index 0da43436..6770aa32 100644 --- a/tests/hlsl/effect-pass-states-fx_5.shader_test +++ b/tests/hlsl/effect-pass-states-fx_5.shader_test @@ -8,6 +8,8 @@ RasterizerState rs; HullShader hs; ComputeShader cs; DomainShader doms; +RenderTargetView rtv1; +DepthStencilView dsv; technique11 { @@ -18,5 +20,6 @@ technique11 SetHullShader(hs); SetComputeShader(cs); SetDomainShader(doms); + OMSetRenderTargets(rtv1, dsv); } }