From ffc8f98bba00f002f6f9af12f3dbfbbc907f90f5 Mon Sep 17 00:00:00 2001 From: "Anna (navi) Figueiredo Gomes" Date: Wed, 15 Jan 2025 00:03:08 +0100 Subject: [PATCH] vkd3d-shader/fx: Implement shader initializers. --- libs/vkd3d-shader/fx.c | 80 +++++++++++++-------------- libs/vkd3d-shader/hlsl.c | 2 + libs/vkd3d-shader/hlsl.h | 2 + libs/vkd3d-shader/hlsl.y | 32 ++++++----- tests/hlsl/effect-compile.shader_test | 2 +- 5 files changed, 62 insertions(+), 56 deletions(-) diff --git a/libs/vkd3d-shader/fx.c b/libs/vkd3d-shader/fx.c index c8ccab686..24396ec00 100644 --- a/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d-shader/fx.c @@ -2351,23 +2351,25 @@ static uint32_t write_shader_blob(const struct hlsl_ir_compile *compile, struct return offset; } -static uint32_t write_fx_shader(enum fx_shader_type type, - const struct hlsl_ir_compile *compile, struct fx_write_context *fx) +static uint32_t write_fx_shader(enum fx_shader_type type, const struct hlsl_ir_compile *compile, + struct vkd3d_bytecode_buffer *buffer, struct fx_write_context *fx) { - struct vkd3d_bytecode_buffer *buffer = &fx->unstructured; struct fx_5_shader shader = {0}; uint32_t ret; - shader = (struct fx_5_shader) + if (compile) { - .offset = write_shader_blob(compile, fx), - .sodecl_count = compile->output.count > 1 ? 4 : 0, - .rast_stream = compile->output.stream, - }; + shader = (struct fx_5_shader) + { + .offset = write_shader_blob(compile, fx), + .sodecl_count = compile->output.count > 1 ? 4 : 0, + .rast_stream = compile->output.stream, + }; - for (size_t i = 0; i < compile->output.count; ++i) - { - shader.sodecl[i] = write_string(compile->output.decls[i], fx); + for (size_t i = 0; i < compile->output.count; ++i) + { + shader.sodecl[i] = write_string(compile->output.decls[i], fx); + } } switch (type) @@ -2504,7 +2506,7 @@ static void write_fx_4_state_assignment(const struct hlsl_ir_var *var, struct hl shader_type = FX5_SHADER; } - value_offset = write_fx_shader(shader_type, hlsl_ir_compile(value), fx); + value_offset = write_fx_shader(shader_type, hlsl_ir_compile(value), unstructured, fx); break; } default: @@ -3309,35 +3311,33 @@ static void write_fx_4_state_object_initializer(struct hlsl_ir_var *var, struct } } -static void write_fx_4_shader_initializer(struct hlsl_ir_var *var, struct fx_write_context *fx) +static void write_fx_shader_initializer(struct hlsl_ir_var *var, struct fx_write_context *fx) { - struct vkd3d_bytecode_buffer *buffer = &fx->structured; + const struct hlsl_type *var_type = hlsl_get_multiarray_element_type(var->data_type); uint32_t elements_count = hlsl_get_multiarray_size(var->data_type); - unsigned int i; + enum fx_shader_type shader_type; - /* FIXME: write shader blobs, once parser support works. */ - for (i = 0; i < elements_count; ++i) - put_u32(buffer, 0); -} - -static void write_fx_5_shader_initializer(struct hlsl_ir_var *var, struct fx_write_context *fx) -{ - struct vkd3d_bytecode_buffer *buffer = &fx->structured; - uint32_t elements_count = hlsl_get_multiarray_size(var->data_type); - unsigned int i; - - /* FIXME: write shader blobs, once parser support works. */ - for (i = 0; i < elements_count; ++i) + switch (var_type->class) { - put_u32(buffer, 0); /* Blob offset */ - put_u32(buffer, 0); /* SODecl[0] offset */ - put_u32(buffer, 0); /* SODecl[1] offset */ - put_u32(buffer, 0); /* SODecl[2] offset */ - put_u32(buffer, 0); /* SODecl[3] offset */ - put_u32(buffer, 0); /* SODecl count */ - put_u32(buffer, 0); /* Rasterizer stream */ - put_u32(buffer, 0); /* Interface bindings count */ - put_u32(buffer, 0); /* Interface initializer offset */ + case HLSL_CLASS_PIXEL_SHADER: + case HLSL_CLASS_VERTEX_SHADER: + case HLSL_CLASS_GEOMETRY_SHADER: + shader_type = FX4_SHADER; + break; + + case HLSL_CLASS_HULL_SHADER: + case HLSL_CLASS_COMPUTE_SHADER: + case HLSL_CLASS_DOMAIN_SHADER: + shader_type = FX5_SHADER; + break; + + default: + vkd3d_unreachable(); + } + + for (size_t i = 0; i < elements_count; ++i) + { + write_fx_shader(shader_type, var->default_values ? var->default_values[i].shader : NULL, &fx->structured, fx); } } @@ -3384,14 +3384,10 @@ static void write_fx_4_object_variable(struct hlsl_ir_var *var, struct fx_write_ case HLSL_CLASS_PIXEL_SHADER: case HLSL_CLASS_VERTEX_SHADER: - write_fx_4_shader_initializer(var, fx); - fx->shader_count += elements_count; - break; - case HLSL_CLASS_HULL_SHADER: case HLSL_CLASS_COMPUTE_SHADER: case HLSL_CLASS_DOMAIN_SHADER: - write_fx_5_shader_initializer(var, fx); + write_fx_shader_initializer(var, fx); fx->shader_count += elements_count; break; diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index d7bd4febd..4e287c620 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -156,6 +156,8 @@ void hlsl_free_state_block(struct hlsl_state_block *state_block) void hlsl_free_default_value(struct hlsl_default_value *value) { vkd3d_free((void *)value->string); + if (value->shader) + hlsl_free_instr(&value->shader->node); } void hlsl_free_default_values(struct hlsl_ir_var *decl) diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 643b72798..27dcbb487 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -501,6 +501,8 @@ struct hlsl_ir_var const char *string; /* Default value, in case the component is a numeric value. */ union hlsl_constant_value_component number; + /* Default value, in case the component is a shader. otherwise it is NULL. */ + struct hlsl_ir_compile *shader; } *default_values; /* Pointer to the temp copy of the variable, in case it is uniform. */ diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index d744498ea..1dd52d770 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -623,6 +623,11 @@ static struct hlsl_default_value evaluate_static_expression(struct hlsl_ctx *ctx if (!(ret.string = vkd3d_strdup(string->string))) return ret; } + else if (node->type == HLSL_IR_COMPILE) + { + list_remove(&node->entry); + ret.shader = hlsl_ir_compile(node); + } else { hlsl_error(ctx, &node->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, @@ -2253,19 +2258,17 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *i { struct hlsl_default_value default_value = {0}; - if (src->type == HLSL_IR_COMPILE || src->type == HLSL_IR_SAMPLER_STATE) + if ((src->type == HLSL_IR_SAMPLER_STATE || src->type == HLSL_IR_COMPILE) + && hlsl_is_numeric_type(dst_comp_type) && dst->default_values) { /* Default values are discarded if they contain an object * literal expression for a numeric component. */ - if (hlsl_is_numeric_type(dst_comp_type) && dst->default_values) - { - hlsl_warning(ctx, &src->loc, VKD3D_SHADER_WARNING_HLSL_IGNORED_DEFAULT_VALUE, - "Component %u in variable '%s' initializer is object literal. Default values discarded.", - k, dst->name); - hlsl_free_default_values(dst); - } + hlsl_warning(ctx, &src->loc, VKD3D_SHADER_WARNING_HLSL_IGNORED_DEFAULT_VALUE, + "Component %u in variable '%s' initializer is an object literal. Default values discarded.", + k, dst->name); + hlsl_free_default_values(dst); } - else + else if (src->type != HLSL_IR_SAMPLER_STATE) { if (!hlsl_clone_block(ctx, &block, instrs)) return; @@ -2708,8 +2711,6 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var || ctx->cur_scope->annotations; if (hlsl_get_multiarray_element_type(type)->class == HLSL_CLASS_SAMPLER) is_default_values_initializer = false; - if (hlsl_type_is_shader(type)) - is_default_values_initializer = false; static_initialization = var->storage_modifiers & HLSL_STORAGE_STATIC || (var->data_type->modifiers & HLSL_MODIFIER_CONST @@ -5403,8 +5404,13 @@ static bool intrinsic_ConstructGSWithSO(struct hlsl_ctx *ctx, return false; } - hlsl_fixme(ctx, loc, "Unhandled HLSL_IR_LOAD in ConstructGSWithSO()."); - return false; + if (!(compile = var->default_values[0].shader)) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Stream output shaders can't be constructed with NULL shaders."); + return false; + } + break; case HLSL_IR_INDEX: hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, diff --git a/tests/hlsl/effect-compile.shader_test b/tests/hlsl/effect-compile.shader_test index 4463a65ef..b8c784479 100644 --- a/tests/hlsl/effect-compile.shader_test +++ b/tests/hlsl/effect-compile.shader_test @@ -145,7 +145,7 @@ PixelShader ps1 = CompileShader(fs_2_0, main()); % Shaders cannot be passed around to another variable: "Initializer must be literal expressions.". -[pixel shader fail(sm<6) todo] +[pixel shader fail(sm<6)] float4 main() : sv_target { return 0; } PixelShader ps1 = CompileShader(ps_2_0, main());