diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index ddf06b72..895a0265 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1878,6 +1878,10 @@ struct hlsl_ir_node *hlsl_new_compile(struct hlsl_ctx *ctx, enum hlsl_compile_ty } break; + + case HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO: + type = hlsl_get_type(ctx->cur_scope, "GeometryShader", true, true); + break; } if (!(compile = hlsl_alloc(ctx, sizeof(*compile)))) @@ -3314,6 +3318,10 @@ static void dump_ir_compile(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *bu case HLSL_COMPILE_TYPE_COMPILE: vkd3d_string_buffer_printf(buffer, "compile %s {\n", compile->profile->name); break; + + case HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO: + vkd3d_string_buffer_printf(buffer, "ConstructGSWithSO {\n"); + break; } dump_block(ctx, buffer, &compile->instrs); diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index c39d58d9..51ef1944 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -879,6 +879,8 @@ struct hlsl_ir_compile { /* A shader compilation through the CompileShader() function or the "compile" syntax. */ HLSL_COMPILE_TYPE_COMPILE, + /* A call to ConstructGSWithSO(), which receives a geometry shader and retrieves one as well. */ + HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO, } compile_type; /* Special field to store the profile argument for HLSL_COMPILE_TYPE_COMPILE. */ diff --git a/libs/vkd3d-shader/hlsl.l b/libs/vkd3d-shader/hlsl.l index e5472709..b7c24266 100644 --- a/libs/vkd3d-shader/hlsl.l +++ b/libs/vkd3d-shader/hlsl.l @@ -82,6 +82,7 @@ ComputeShader {return KW_COMPUTESHADER; } compile {return KW_COMPILE; } CompileShader {return KW_COMPILESHADER; } const {return KW_CONST; } +ConstructGSWithSO {return KW_CONSTRUCTGSWITHSO; } continue {return KW_CONTINUE; } DepthStencilState {return KW_DEPTHSTENCILSTATE; } DepthStencilView {return KW_DEPTHSTENCILVIEW; } diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 46a45bca..787373cc 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -5235,6 +5235,36 @@ static struct hlsl_block *add_shader_compilation(struct hlsl_ctx *ctx, const cha return make_block(ctx, compile); } +static struct hlsl_block *add_compile_variant(struct hlsl_ctx *ctx, enum hlsl_compile_type compile_type, + struct parse_initializer *args, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *compile; + + switch (compile_type) + { + case HLSL_COMPILE_TYPE_COMPILE: + vkd3d_unreachable(); + + case HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO: + if (args->args_count != 2 && args->args_count != 6) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Wrong number of arguments to ConstructGSWithSO: expected 2 or 6, but got %u.", + args->args_count); + } + break; + } + + if (!(compile = hlsl_new_compile(ctx, compile_type, NULL, args->args, args->args_count, args->instrs, loc))) + { + free_parse_initializer(args); + return NULL; + } + + free_parse_initializer(args); + return make_block(ctx, compile); +} + static struct hlsl_block *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type, struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -6236,6 +6266,7 @@ static bool state_block_add_entry(struct hlsl_state_block *state_block, struct h %token KW_COMPILESHADER %token KW_COMPUTESHADER %token KW_CONST +%token KW_CONSTRUCTGSWITHSO %token KW_CONTINUE %token KW_DEFAULT %token KW_DEPTHSTENCILSTATE @@ -8596,6 +8627,11 @@ primary_expr: vkd3d_free($3); vkd3d_free($5); } + | KW_CONSTRUCTGSWITHSO '(' func_arguments ')' + { + if (!($$ = add_compile_variant(ctx, HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO, &$3, &@1))) + YYABORT; + } | var_identifier '(' func_arguments ')' { if (!($$ = add_call(ctx, $1, &$3, &@1))) diff --git a/tests/hlsl/constructgswithso.shader_test b/tests/hlsl/constructgswithso.shader_test index 0ea82708..50e5cbed 100644 --- a/tests/hlsl/constructgswithso.shader_test +++ b/tests/hlsl/constructgswithso.shader_test @@ -18,7 +18,7 @@ float4 main() : sv_target { return 0; } GeometryShader gs1 = CompileShader(gs_5_0, main()); GeometryShader gs2 = ConstructGSWithSO(gs1); -[pixel shader todo] +[pixel shader] float4 main() : sv_target { return 0; } GeometryShader gs2 = ConstructGSWithSO("foo", "bar"); @@ -26,7 +26,7 @@ GeometryShader gs2 = ConstructGSWithSO("foo", "bar"); float4 main() : sv_target { return 0; } GeometryShader gs2 = ConstructGSWithSO(1, 2, 3); -[pixel shader todo] +[pixel shader] float4 main() : sv_target { return 0; } GeometryShader gs2 = ConstructGSWithSO("foo", "bar", float2(42, 42), 3, 4, NULL);