Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
-- v13: vkd3d-shader/tpf: Add initial support for writing fx_4_0/fx_4_1 binaries. vkd3d-shader: Add separate binary target type for effects. vkd3d-shader/hlsl: Handle effect group statement. vkd3d-shader/hlsl: Add variables for techniques.
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- tests/hlsl/technique-fx_2.shader_test | 31 +++++++++++++ tests/hlsl/technique-fx_4.shader_test | 24 ++++++++++ tests/hlsl/technique-fx_5.shader_test | 66 +++++++++++++++++++++++++++ 3 files changed, 121 insertions(+)
diff --git a/tests/hlsl/technique-fx_2.shader_test b/tests/hlsl/technique-fx_2.shader_test index 90c734d53..42e523f22 100644 --- a/tests/hlsl/technique-fx_2.shader_test +++ b/tests/hlsl/technique-fx_2.shader_test @@ -38,6 +38,13 @@ float4 main() : sv_target return float4(0, 0, 0, 0); }
+[pixel shader fail todo] +float4 main() : sv_target +{ + float4 fxgroup = {0, 0, 0, 0}; + return fxgroup; +} + [pixel shader] typedef float4 Technique10; typedef float4 Technique11; @@ -62,6 +69,13 @@ float4 main() : sv_target return teChnique11; }
+[pixel shader] +float4 main() : sv_target +{ + float4 fxGroup = {0, 0, 0, 0}; + return fxGroup; +} + [effect todo] technique { @@ -103,6 +117,11 @@ tEchnique11 { }
+[effect fail] +fxgroup group +{ +} + % Regular shaders with technique blocks [vertex shader todo] float4 main() : sv_position @@ -122,6 +141,12 @@ technique11 { }
+// Empty groups are not allowed +fxgroup group +{ + technique10 {} +} + [pixel shader todo] float4 main() : sv_target { @@ -139,3 +164,9 @@ technique10 technique11 { } + +// Empty groups are not allowed +fxgroup group +{ + technique10 {} +} diff --git a/tests/hlsl/technique-fx_4.shader_test b/tests/hlsl/technique-fx_4.shader_test index fb8a3e675..2fc481de5 100644 --- a/tests/hlsl/technique-fx_4.shader_test +++ b/tests/hlsl/technique-fx_4.shader_test @@ -9,6 +9,13 @@ float4 main() : sv_target return teChnique; }
+[pixel shader fail todo] +float4 main() : sv_target +{ + float4 fxgroup = {0, 0, 0, 0}; + return fxgroup; +} + [pixel shader] float4 main() : sv_target { @@ -23,6 +30,13 @@ float4 main() : sv_target return teChnique11; }
+[pixel shader] +float4 main() : sv_target +{ + float4 fxGroup = {0, 0, 0, 0}; + return fxGroup; +} + [effect todo] technique { @@ -101,6 +115,11 @@ technique11 { }
+fxgroup group +{ + technique10 {} +} + [pixel shader todo] float4 main() : sv_target { @@ -118,3 +137,8 @@ technique10 technique11 { } + +fxgroup group +{ + technique10 {} +} diff --git a/tests/hlsl/technique-fx_5.shader_test b/tests/hlsl/technique-fx_5.shader_test index aeea1a84f..152227c62 100644 --- a/tests/hlsl/technique-fx_5.shader_test +++ b/tests/hlsl/technique-fx_5.shader_test @@ -9,6 +9,13 @@ float4 main() : sv_target return teChnique; }
+[pixel shader fail todo] +float4 main() : sv_target +{ + float4 fxgroup = {0, 0, 0, 0}; + return fxgroup; +} + [pixel shader] float4 main() : sv_target { @@ -23,6 +30,13 @@ float4 main() : sv_target return teChnique11; }
+[pixel shader] +float4 main() : sv_target +{ + float4 fxGroup = {0, 0, 0, 0}; + return fxGroup; +} + [effect todo] technique { @@ -101,6 +115,11 @@ technique11 { }
+fxgroup group +{ + technique10 {} +} + [pixel shader todo] float4 main() : sv_target { @@ -118,3 +137,50 @@ technique10 technique11 { } + +fxgroup group +{ + technique10 {} +} + +% Groups syntax + +% Name has to be specified, it belongs to global scope +[effect fail] +fxgroup +{ +} + +% Group can't be empty +[effect fail] +fxgroup group +{ +} + +[effect fail] +float4 group; + +fxgroup group +{ +} + +% Groups can only contain a list of techniques +[effect fail] +fxgroup group +{ + float4 v; + + technique11 {} +} + +% Group provides scope for techniques +[effect todo] +fxgroup group1 +{ + technique11 tech0 {} +} + +fxgroup group2 +{ + technique11 tech0 {} +}
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl.l | 1 + libs/vkd3d-shader/hlsl.y | 1 + tests/hlsl/technique-fx_2.shader_test | 2 +- tests/hlsl/technique-fx_4.shader_test | 2 +- tests/hlsl/technique-fx_5.shader_test | 2 +- 5 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.l b/libs/vkd3d-shader/hlsl.l index fe8387507..6cef0e02e 100644 --- a/libs/vkd3d-shader/hlsl.l +++ b/libs/vkd3d-shader/hlsl.l @@ -89,6 +89,7 @@ else {return KW_ELSE; } extern {return KW_EXTERN; } false {return KW_FALSE; } for {return KW_FOR; } +fxgroup {return KW_FXGROUP; } GeometryShader {return KW_GEOMETRYSHADER; } groupshared {return KW_GROUPSHARED; } if {return KW_IF; } diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index ed053f163..c04094737 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -4887,6 +4887,7 @@ static void check_duplicated_switch_cases(struct hlsl_ctx *ctx, const struct hls %token KW_EXTERN %token KW_FALSE %token KW_FOR +%token KW_FXGROUP %token KW_GEOMETRYSHADER %token KW_GROUPSHARED %token KW_IF diff --git a/tests/hlsl/technique-fx_2.shader_test b/tests/hlsl/technique-fx_2.shader_test index 42e523f22..f86cc005d 100644 --- a/tests/hlsl/technique-fx_2.shader_test +++ b/tests/hlsl/technique-fx_2.shader_test @@ -38,7 +38,7 @@ float4 main() : sv_target return float4(0, 0, 0, 0); }
-[pixel shader fail todo] +[pixel shader fail] float4 main() : sv_target { float4 fxgroup = {0, 0, 0, 0}; diff --git a/tests/hlsl/technique-fx_4.shader_test b/tests/hlsl/technique-fx_4.shader_test index 2fc481de5..7968cb9de 100644 --- a/tests/hlsl/technique-fx_4.shader_test +++ b/tests/hlsl/technique-fx_4.shader_test @@ -9,7 +9,7 @@ float4 main() : sv_target return teChnique; }
-[pixel shader fail todo] +[pixel shader fail] float4 main() : sv_target { float4 fxgroup = {0, 0, 0, 0}; diff --git a/tests/hlsl/technique-fx_5.shader_test b/tests/hlsl/technique-fx_5.shader_test index 152227c62..29aa616f9 100644 --- a/tests/hlsl/technique-fx_5.shader_test +++ b/tests/hlsl/technique-fx_5.shader_test @@ -9,7 +9,7 @@ float4 main() : sv_target return teChnique; }
-[pixel shader fail todo] +[pixel shader fail] float4 main() : sv_target { float4 fxgroup = {0, 0, 0, 0};
From: Nikolay Sivov nsivov@codeweavers.com
Only technique10 and technique11 types could be nested in groups.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl.y | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index c04094737..0123f4df1 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -5094,7 +5094,7 @@ hlsl_prog: destroy_block($2); } | hlsl_prog preproc_directive - | hlsl_prog technique + | hlsl_prog global_technique | hlsl_prog ';'
technique_name: @@ -5133,7 +5133,7 @@ technique11: hlsl_fixme(ctx, &@$, "Unsupported 'technique11' declaration."); }
-technique: +global_technique: technique9 | technique10 | technique11
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 51 +++++++++++++++++++++------ libs/vkd3d-shader/hlsl.h | 9 +++-- libs/vkd3d-shader/hlsl.y | 33 +++++++++++++++-- tests/hlsl/technique-fx_2.shader_test | 6 ++-- tests/hlsl/technique-fx_4.shader_test | 4 +-- tests/hlsl/technique-fx_5.shader_test | 4 +-- 6 files changed, 85 insertions(+), 22 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index da3bbda1b..3556b167e 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -98,19 +98,22 @@ bool hlsl_add_var(struct hlsl_ctx *ctx, struct hlsl_ir_var *decl, bool local_var struct hlsl_scope *scope = ctx->cur_scope; struct hlsl_ir_var *var;
- LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry) - { - if (!strcmp(decl->name, var->name)) - return false; - } - if (local_var && scope->upper->upper == ctx->globals) + if (decl->name) { - /* Check whether the variable redefines a function parameter. */ - LIST_FOR_EACH_ENTRY(var, &scope->upper->vars, struct hlsl_ir_var, scope_entry) + LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry) { - if (!strcmp(decl->name, var->name)) + if (var->name && !strcmp(decl->name, var->name)) return false; } + if (local_var && scope->upper->upper == ctx->globals) + { + /* Check whether the variable redefines a function parameter. */ + LIST_FOR_EACH_ENTRY(var, &scope->upper->vars, struct hlsl_ir_var, scope_entry) + { + if (var->name && !strcmp(decl->name, var->name)) + return false; + } + } }
list_add_tail(&scope->vars, &decl->scope_entry); @@ -123,7 +126,7 @@ struct hlsl_ir_var *hlsl_get_var(struct hlsl_scope *scope, const char *name)
LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry) { - if (!strcmp(name, var->name)) + if (var->name && !strcmp(name, var->name)) return var; } if (!scope->upper) @@ -915,6 +918,8 @@ bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2 if (t1->class == HLSL_CLASS_ARRAY) return t1->e.array.elements_count == t2->e.array.elements_count && hlsl_types_are_equal(t1->e.array.type, t2->e.array.type); + if (t1->base_type == HLSL_TYPE_TECHNIQUE && t1->e.version != t2->e.version) + return false;
return true; } @@ -993,6 +998,13 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, break; }
+ case HLSL_CLASS_OBJECT: + { + if (type->base_type == HLSL_TYPE_TECHNIQUE) + type->e.version = old->e.version; + break; + } + default: break; } @@ -3355,6 +3367,18 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) {"VERTEXSHADER", HLSL_CLASS_OBJECT, HLSL_TYPE_VERTEXSHADER, 1, 1}, };
+ static const struct + { + char *name; + unsigned int version; + } + technique_types[] = + { + {"technique", 9}, + {"technique10", 10}, + {"technique11", 11}, + }; + for (bt = 0; bt <= HLSL_TYPE_LAST_SCALAR; ++bt) { for (y = 1; y <= 4; ++y) @@ -3459,6 +3483,13 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) effect_types[i].base_type, effect_types[i].dimx, effect_types[i].dimy); hlsl_scope_add_type(ctx->globals, type); } + + for (i = 0; i < ARRAY_SIZE(technique_types); ++i) + { + type = hlsl_new_type(ctx, technique_types[i].name, HLSL_CLASS_OBJECT, HLSL_TYPE_TECHNIQUE, 1, 1); + type->e.version = technique_types[i].version; + hlsl_scope_add_type(ctx->globals, type); + } }
static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info, diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 21b2fe383..6cdd56378 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -95,6 +95,7 @@ enum hlsl_base_type HLSL_TYPE_UAV, HLSL_TYPE_PIXELSHADER, HLSL_TYPE_VERTEXSHADER, + HLSL_TYPE_TECHNIQUE, HLSL_TYPE_STRING, HLSL_TYPE_VOID, }; @@ -138,8 +139,10 @@ struct hlsl_type struct rb_entry scope_entry;
enum hlsl_type_class class; - /* If type is <= HLSL_CLASS_LAST_NUMERIC, then base_type is <= HLSL_TYPE_LAST_SCALAR. - * If type is HLSL_CLASS_OBJECT, then base_type is > HLSL_TYPE_LAST_SCALAR. + /* If class is <= HLSL_CLASS_LAST_NUMERIC, then base_type is <= HLSL_TYPE_LAST_SCALAR. + * If class is HLSL_CLASS_OBJECT, then base_type is > HLSL_TYPE_LAST_SCALAR. + * If class is HLSL_CLASS_OBJECT and base_type is HLSL_TYPE_TECHNIQUE, additional version + * field is used to distinguish between technique types. * Otherwise, base_type is not used. */ enum hlsl_base_type base_type;
@@ -191,6 +194,8 @@ struct hlsl_type /* Format of the data contained within the type if the base_type is HLSL_TYPE_TEXTURE or * HLSL_TYPE_UAV. */ struct hlsl_type *resource_format; + /* Additional field to distinguish object types. Currently used only for technique types. */ + unsigned int version; } e;
/* Number of numeric register components used by one value of this type, for each regset. diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 0123f4df1..ff10de9b9 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1096,6 +1096,30 @@ static bool add_func_parameter(struct hlsl_ctx *ctx, struct hlsl_func_parameters return true; }
+static bool add_technique(struct hlsl_ctx *ctx, const char *name, const char *typename, + const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_var *var; + struct hlsl_type *type; + + type = hlsl_get_type(ctx->globals, typename, false, false); + if (!(var = hlsl_new_var(ctx, name, type, loc, NULL, 0, NULL))) + return false; + + if (!hlsl_add_var(ctx, var, false)) + { + struct hlsl_ir_var *old = hlsl_get_var(ctx->cur_scope, var->name); + + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, + "Variable "%s" was already declared in this scope.", var->name); + hlsl_note(ctx, &old->loc, VKD3D_SHADER_LOG_ERROR, ""%s" was previously declared here.", old->name); + hlsl_free_var(var); + return false; + } + + return true; +} + static struct hlsl_reg_reservation parse_reg_reservation(const char *reg_string) { struct hlsl_reg_reservation reservation = {0}; @@ -5110,7 +5134,8 @@ pass_list: technique9: KW_TECHNIQUE technique_name '{' pass_list '}' { - hlsl_fixme(ctx, &@$, "Unsupported 'technique' declaration."); + if (!add_technique(ctx, $2, "technique", &@1)) + YYABORT; }
technique10: @@ -5120,7 +5145,8 @@ technique10: hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "The 'technique10' keyword is invalid for this profile.");
- hlsl_fixme(ctx, &@$, "Unsupported 'technique10' declaration."); + if (!add_technique(ctx, $2, "technique10", &@1)) + YYABORT; }
technique11: @@ -5130,7 +5156,8 @@ technique11: hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "The 'technique11' keyword is invalid for this profile.");
- hlsl_fixme(ctx, &@$, "Unsupported 'technique11' declaration."); + if (!add_technique(ctx, $2, "technique11", &@1)) + YYABORT; }
global_technique: diff --git a/tests/hlsl/technique-fx_2.shader_test b/tests/hlsl/technique-fx_2.shader_test index f86cc005d..e0ac1901e 100644 --- a/tests/hlsl/technique-fx_2.shader_test +++ b/tests/hlsl/technique-fx_2.shader_test @@ -90,7 +90,7 @@ technique10 float4 f;
% fx_5_0 keyword fails with fx_2_0 profile -[effect fail todo] +[effect fail] technique { } @@ -99,7 +99,7 @@ technique11 { }
-[effect fail todo] +[effect fail] technique { } @@ -108,7 +108,7 @@ tEchnique10 { }
-[effect fail todo] +[effect fail] technique { } diff --git a/tests/hlsl/technique-fx_4.shader_test b/tests/hlsl/technique-fx_4.shader_test index 7968cb9de..02317483a 100644 --- a/tests/hlsl/technique-fx_4.shader_test +++ b/tests/hlsl/technique-fx_4.shader_test @@ -60,7 +60,7 @@ technique11 { }
-[effect fail todo] +[effect fail] technique { } @@ -69,7 +69,7 @@ tEchnique10 { }
-[effect fail todo] +[effect fail] technique { } diff --git a/tests/hlsl/technique-fx_5.shader_test b/tests/hlsl/technique-fx_5.shader_test index 29aa616f9..fd1cf4cf9 100644 --- a/tests/hlsl/technique-fx_5.shader_test +++ b/tests/hlsl/technique-fx_5.shader_test @@ -60,7 +60,7 @@ technique11 { }
-[effect fail todo] +[effect fail] technique { } @@ -69,7 +69,7 @@ tEchnique10 { }
-[effect fail todo] +[effect fail] technique { }
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 1 + libs/vkd3d-shader/hlsl.h | 3 ++ libs/vkd3d-shader/hlsl.y | 43 +++++++++++++++++++++++++++ tests/hlsl/technique-fx_2.shader_test | 4 +-- tests/hlsl/technique-fx_4.shader_test | 4 +-- tests/hlsl/technique-fx_5.shader_test | 4 +-- 6 files changed, 53 insertions(+), 6 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 3556b167e..ae53eda78 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -3361,6 +3361,7 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) {"float", HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1}, {"vector", HLSL_CLASS_VECTOR, HLSL_TYPE_FLOAT, 4, 1}, {"matrix", HLSL_CLASS_MATRIX, HLSL_TYPE_FLOAT, 4, 4}, + {"fxgroup", HLSL_CLASS_OBJECT, HLSL_TYPE_EFFECT_GROUP, 1, 1}, {"STRING", HLSL_CLASS_OBJECT, HLSL_TYPE_STRING, 1, 1}, {"TEXTURE", HLSL_CLASS_OBJECT, HLSL_TYPE_TEXTURE, 1, 1}, {"PIXELSHADER", HLSL_CLASS_OBJECT, HLSL_TYPE_PIXELSHADER, 1, 1}, diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 6cdd56378..50e28ffae 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -96,6 +96,7 @@ enum hlsl_base_type HLSL_TYPE_PIXELSHADER, HLSL_TYPE_VERTEXSHADER, HLSL_TYPE_TECHNIQUE, + HLSL_TYPE_EFFECT_GROUP, HLSL_TYPE_STRING, HLSL_TYPE_VOID, }; @@ -405,6 +406,8 @@ struct hlsl_ir_var struct list scope_entry; /* Item entry in hlsl_ctx.extern_vars, if the variable is extern. */ struct list extern_entry; + /* Scope that variable itself defines, used to provide a container for techniques and passes. */ + struct hlsl_scope *scope;
/* Indexes of the IR instructions where the variable is first written and last read (liveness * range). The IR instructions are numerated starting from 2, because 0 means unused, and 1 diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index ff10de9b9..be96de7eb 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1120,6 +1120,31 @@ static bool add_technique(struct hlsl_ctx *ctx, const char *name, const char *ty return true; }
+static bool add_effect_group(struct hlsl_ctx *ctx, const char *name, struct hlsl_scope *scope, + const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_var *var; + struct hlsl_type *type; + + type = hlsl_get_type(ctx->globals, "fxgroup", false, false); + if (!(var = hlsl_new_var(ctx, name, type, loc, NULL, 0, NULL))) + return false; + var->scope = scope; + + if (!hlsl_add_var(ctx, var, false)) + { + struct hlsl_ir_var *old = hlsl_get_var(ctx->cur_scope, var->name); + + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, + "Variable "%s" was already declared in this scope.", var->name); + hlsl_note(ctx, &old->loc, VKD3D_SHADER_LOG_ERROR, ""%s" was previously declared here.", old->name); + hlsl_free_var(var); + return false; + } + + return true; +} + static struct hlsl_reg_reservation parse_reg_reservation(const char *reg_string) { struct hlsl_reg_reservation reservation = {0}; @@ -5119,6 +5144,7 @@ hlsl_prog: } | hlsl_prog preproc_directive | hlsl_prog global_technique + | hlsl_prog effect_group | hlsl_prog ';'
technique_name: @@ -5165,6 +5191,23 @@ global_technique: | technique10 | technique11
+group_technique: + technique10 + | technique11 + +group_techniques: + group_technique + | group_techniques group_technique + +effect_group: + KW_FXGROUP any_identifier '{' scope_start group_techniques '}' + { + struct hlsl_scope *scope = ctx->cur_scope; + hlsl_pop_scope(ctx); + if (!(add_effect_group(ctx, $2, scope, &@2))) + YYABORT; + } + buffer_declaration: buffer_type any_identifier colon_attribute { diff --git a/tests/hlsl/technique-fx_2.shader_test b/tests/hlsl/technique-fx_2.shader_test index e0ac1901e..4a18430ad 100644 --- a/tests/hlsl/technique-fx_2.shader_test +++ b/tests/hlsl/technique-fx_2.shader_test @@ -123,7 +123,7 @@ fxgroup group }
% Regular shaders with technique blocks -[vertex shader todo] +[vertex shader] float4 main() : sv_position { return 0; @@ -147,7 +147,7 @@ fxgroup group technique10 {} }
-[pixel shader todo] +[pixel shader] float4 main() : sv_target { return 0; diff --git a/tests/hlsl/technique-fx_4.shader_test b/tests/hlsl/technique-fx_4.shader_test index 02317483a..9bd1a8d74 100644 --- a/tests/hlsl/technique-fx_4.shader_test +++ b/tests/hlsl/technique-fx_4.shader_test @@ -97,7 +97,7 @@ float4 technIque10; float4 technIque11;
% Regular shaders with technique blocks -[vertex shader todo] +[vertex shader] float4 main() : sv_position { return 0; @@ -120,7 +120,7 @@ fxgroup group technique10 {} }
-[pixel shader todo] +[pixel shader] float4 main() : sv_target { return 0; diff --git a/tests/hlsl/technique-fx_5.shader_test b/tests/hlsl/technique-fx_5.shader_test index fd1cf4cf9..0ef88cd0e 100644 --- a/tests/hlsl/technique-fx_5.shader_test +++ b/tests/hlsl/technique-fx_5.shader_test @@ -97,7 +97,7 @@ float4 technIque10; float4 technIque11;
% Regular shaders with technique blocks -[vertex shader todo] +[vertex shader] float4 main() : sv_position { return 0; @@ -120,7 +120,7 @@ fxgroup group technique10 {} }
-[pixel shader todo] +[pixel shader] float4 main() : sv_target { return 0;
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- Makefile.am | 1 + libs/vkd3d-shader/fx.c | 158 +++++++++++++++++++++++ libs/vkd3d-shader/hlsl.c | 8 ++ libs/vkd3d-shader/hlsl.h | 1 + libs/vkd3d-shader/vkd3d_shader_main.c | 35 ++++- libs/vkd3d-shader/vkd3d_shader_private.h | 2 + tests/hlsl/technique-fx_2.shader_test | 2 +- tests/hlsl/technique-fx_4.shader_test | 10 +- 8 files changed, 208 insertions(+), 9 deletions(-) create mode 100644 libs/vkd3d-shader/fx.c
diff --git a/Makefile.am b/Makefile.am index 23e7add3c..bc648b631 100644 --- a/Makefile.am +++ b/Makefile.am @@ -294,6 +294,7 @@ libvkd3d_shader_la_SOURCES = \ libs/vkd3d-shader/d3dbc.c \ libs/vkd3d-shader/dxbc.c \ libs/vkd3d-shader/dxil.c \ + libs/vkd3d-shader/fx.c \ libs/vkd3d-shader/glsl.c \ libs/vkd3d-shader/hlsl.c \ libs/vkd3d-shader/hlsl.h \ diff --git a/libs/vkd3d-shader/fx.c b/libs/vkd3d-shader/fx.c new file mode 100644 index 000000000..6c4c1203d --- /dev/null +++ b/libs/vkd3d-shader/fx.c @@ -0,0 +1,158 @@ +/* + * FX (Direct3D 9/10/11 effect) support + * + * Copyright 2023 Nikolay Sivov for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "hlsl.h" + +struct fx_write_context +{ + struct vkd3d_bytecode_buffer unstructured; + struct vkd3d_bytecode_buffer structured; + + uint32_t technique_count; + int status; +}; + +static uint32_t fx_put_raw_string(struct fx_write_context *fx, const char *string) +{ + /* NULLs are emitted as empty strings using the same 4 bytes at the start of the section. */ + return string ? put_string(&fx->unstructured, string) : 0; +} + +static void write_technique(struct hlsl_ir_var *var, struct fx_write_context *fx) +{ + struct vkd3d_bytecode_buffer *buffer = &fx->structured; + uint32_t name_offset; + + name_offset = fx_put_raw_string(fx, var->name); + put_u32(buffer, name_offset); + put_u32(buffer, 0); /* Pass count. */ + put_u32(buffer, 0); /* Annotation count. */ + + /* TODO: passes */ +} + +static void set_status(struct fx_write_context *fx, int status) +{ + if (fx->status < 0) + return; + if (status < 0) + fx->status = status; +} + +static void write_techniques(struct hlsl_scope *scope, struct fx_write_context *fx) +{ + struct hlsl_ir_var *var; + + LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry) + { + const struct hlsl_type *type = var->data_type; + + if (type->base_type == HLSL_TYPE_TECHNIQUE && type->e.version == 10) + { + write_technique(var, fx); + ++fx->technique_count; + } + } + + set_status(fx, fx->unstructured.status); + set_status(fx, fx->structured.status); +} + +static int hlsl_fx_4_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) +{ + struct vkd3d_bytecode_buffer buffer = { 0 }; + struct fx_write_context fx; + uint32_t size_offset, size; + + memset(&fx, 0, sizeof(fx)); + + put_u32(&fx.unstructured, 0); /* Empty string placeholder. */ + + /* TODO: buffers */ + /* TODO: objects */ + /* TODO: shared buffers */ + /* TODO: shared objects */ + + write_techniques(ctx->globals, &fx); + + put_u32(&buffer, ctx->profile->minor_version == 0 ? 0xfeff1001 : 0xfeff1011); /* Version. */ + put_u32(&buffer, 0); /* Buffer count. */ + put_u32(&buffer, 0); /* Variable count. */ + put_u32(&buffer, 0); /* Object count. */ + put_u32(&buffer, 0); /* Pool buffer count. */ + put_u32(&buffer, 0); /* Pool variable count. */ + put_u32(&buffer, 0); /* Pool object count. */ + put_u32(&buffer, fx.technique_count); + size_offset = put_u32(&buffer, 0); /* Unstructured size. */ + put_u32(&buffer, 0); /* String count. */ + put_u32(&buffer, 0); /* Texture object count. */ + put_u32(&buffer, 0); /* Depth stencil state count. */ + put_u32(&buffer, 0); /* Blend state count. */ + put_u32(&buffer, 0); /* Rasterizer state count. */ + put_u32(&buffer, 0); /* Sampler state count. */ + put_u32(&buffer, 0); /* Rendertarget view count. */ + put_u32(&buffer, 0); /* Depth stencil view count. */ + put_u32(&buffer, 0); /* Shader count. */ + put_u32(&buffer, 0); /* Inline shader count. */ + + size = align(fx.unstructured.size, 4); + set_u32(&buffer, size_offset, size); + + bytecode_put_bytes(&buffer, fx.unstructured.data, fx.unstructured.size); + bytecode_put_bytes(&buffer, fx.structured.data, fx.structured.size); + + vkd3d_free(fx.unstructured.data); + vkd3d_free(fx.structured.data); + + set_status(&fx, buffer.status); + + if (!fx.status) + { + out->code = buffer.data; + out->size = buffer.size; + } + + if (fx.status < 0) + ctx->result = fx.status; + + return fx.status; +} + +int hlsl_emit_effect_binary(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) +{ + if (ctx->profile->major_version == 2) + { + hlsl_fixme(ctx, &ctx->location, "Writing fx_2_0 binaries is not implemented."); + return VKD3D_ERROR_NOT_IMPLEMENTED; + } + else if (ctx->profile->major_version == 4) + { + return hlsl_fx_4_write(ctx, out); + } + else if (ctx->profile->major_version == 5) + { + hlsl_fixme(ctx, &ctx->location, "Writing fx_5_0 binaries is not implemented."); + return VKD3D_ERROR_NOT_IMPLEMENTED; + } + else + { + vkd3d_unreachable(); + } +} diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 69da9b287..e8148addf 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -3668,6 +3668,14 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d return VKD3D_ERROR_NOT_IMPLEMENTED; }
+ if (ctx.profile->type == VKD3D_SHADER_TYPE_EFFECT) + { + ret = hlsl_emit_effect_binary(&ctx, out); + + hlsl_ctx_cleanup(&ctx); + return ret; + } + if ((func = hlsl_get_function(&ctx, entry_point))) { LIST_FOR_EACH_ENTRY(decl, &func->overloads, struct hlsl_ir_function_decl, entry) diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 50e28ffae..e1af55080 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -1168,6 +1168,7 @@ void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl
int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out); +int hlsl_emit_effect_binary(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out);
bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_node *chain); bool hlsl_copy_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, const struct hlsl_deref *other); diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index 399b040ad..a2e5391a0 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -373,13 +373,42 @@ size_t bytecode_put_bytes(struct vkd3d_bytecode_buffer *buffer, const void *byte return offset; }
-void set_u32(struct vkd3d_bytecode_buffer *buffer, size_t offset, uint32_t value) +size_t bytecode_reserve_bytes(struct vkd3d_bytecode_buffer *buffer, size_t size) +{ + size_t offset = bytecode_align(buffer); + + if (buffer->status) + return offset; + + if (!vkd3d_array_reserve((void **)&buffer->data, &buffer->capacity, offset + size, 1)) + { + buffer->status = VKD3D_ERROR_OUT_OF_MEMORY; + return offset; + } + + memset(buffer->data + offset, 0, size); + buffer->size = offset + size; + return offset; +} + +static void bytecode_set_bytes(struct vkd3d_bytecode_buffer *buffer, size_t offset, + const void *value, size_t size) { if (buffer->status) return;
- assert(vkd3d_bound_range(offset, sizeof(value), buffer->size)); - memcpy(buffer->data + offset, &value, sizeof(value)); + assert(vkd3d_bound_range(offset, size, buffer->size)); + memcpy(buffer->data + offset, value, size); +} + +void set_u32(struct vkd3d_bytecode_buffer *buffer, size_t offset, uint32_t value) +{ + bytecode_set_bytes(buffer, offset, &value, sizeof(value)); +} + +void set_string(struct vkd3d_bytecode_buffer *buffer, size_t offset, const char *string, size_t length) +{ + bytecode_set_bytes(buffer, offset, string, length); }
static void vkd3d_shader_dump_blob(const char *path, const char *profile, diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index f1cc9ad7b..39d736ca1 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -1349,7 +1349,9 @@ struct vkd3d_bytecode_buffer /* Align to the next 4-byte offset, and return that offset. */ size_t bytecode_align(struct vkd3d_bytecode_buffer *buffer); size_t bytecode_put_bytes(struct vkd3d_bytecode_buffer *buffer, const void *bytes, size_t size); +size_t bytecode_reserve_bytes(struct vkd3d_bytecode_buffer *buffer, size_t size); void set_u32(struct vkd3d_bytecode_buffer *buffer, size_t offset, uint32_t value); +void set_string(struct vkd3d_bytecode_buffer *buffer, size_t offset, const char *string, size_t length);
static inline size_t put_u32(struct vkd3d_bytecode_buffer *buffer, uint32_t value) { diff --git a/tests/hlsl/technique-fx_2.shader_test b/tests/hlsl/technique-fx_2.shader_test index 4a18430ad..10b6fdf09 100644 --- a/tests/hlsl/technique-fx_2.shader_test +++ b/tests/hlsl/technique-fx_2.shader_test @@ -86,7 +86,7 @@ technique10 }
% Effects without techniques are not allowed for fx_2_0 -[effect fail] +[effect fail todo] float4 f;
% fx_5_0 keyword fails with fx_2_0 profile diff --git a/tests/hlsl/technique-fx_4.shader_test b/tests/hlsl/technique-fx_4.shader_test index 9bd1a8d74..cdc5746e0 100644 --- a/tests/hlsl/technique-fx_4.shader_test +++ b/tests/hlsl/technique-fx_4.shader_test @@ -37,7 +37,7 @@ float4 main() : sv_target return fxGroup; }
-[effect todo] +[effect] technique { } @@ -47,11 +47,11 @@ technique10 }
% Effects without techniques are allowed for fx_4_0+ -[effect todo] +[effect] float4 f;
% fx_2_0 keyword is allowed with fx_4_0+ profiles -[effect todo] +[effect] technique { } @@ -90,10 +90,10 @@ float4 technique10; [effect fail] float4 technique11;
-[effect todo] +[effect] float4 technIque10;
-[effect todo] +[effect] float4 technIque11;
% Regular shaders with technique blocks
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- include/private/vkd3d_common.h | 1 + include/vkd3d_shader.h | 5 ++ libs/vkd3d-shader/hlsl.c | 6 ++ libs/vkd3d-shader/vkd3d_shader_main.c | 1 + libs/vkd3d-utils/vkd3d_utils_main.c | 90 ++++++++++++++++++--------- programs/vkd3d-compiler/main.c | 3 + 6 files changed, 76 insertions(+), 30 deletions(-)
diff --git a/include/private/vkd3d_common.h b/include/private/vkd3d_common.h index 5557df41a..4bb94ee5b 100644 --- a/include/private/vkd3d_common.h +++ b/include/private/vkd3d_common.h @@ -52,6 +52,7 @@ #define TAG_AON9 VKD3D_MAKE_TAG('A', 'o', 'n', '9') #define TAG_DXBC VKD3D_MAKE_TAG('D', 'X', 'B', 'C') #define TAG_DXIL VKD3D_MAKE_TAG('D', 'X', 'I', 'L') +#define TAG_FX10 VKD3D_MAKE_TAG('F', 'X', '1', '0') #define TAG_ISG1 VKD3D_MAKE_TAG('I', 'S', 'G', '1') #define TAG_ISGN VKD3D_MAKE_TAG('I', 'S', 'G', 'N') #define TAG_OSG1 VKD3D_MAKE_TAG('O', 'S', 'G', '1') diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h index a6bf89641..97b4d39e3 100644 --- a/include/vkd3d_shader.h +++ b/include/vkd3d_shader.h @@ -785,6 +785,11 @@ enum vkd3d_shader_target_type * An 'OpenGL Shading Language' shader. \since 1.3 */ VKD3D_SHADER_TARGET_GLSL, + /** + * Binary format used by Direct3D 9/10.x/11 effects profiles. + * Output is a raw FX section without container. \since 1.10 + */ + VKD3D_SHADER_TARGET_FX,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_TARGET_TYPE), }; diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index ae53eda78..69da9b287 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -3638,6 +3638,12 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d "The '%s' target profile is incompatible with the 'dxbc-tpf' target type.", profile->name); return VKD3D_ERROR_INVALID_ARGUMENT; } + else if ((compile_info->target_type == VKD3D_SHADER_TARGET_FX) != (profile->type == VKD3D_SHADER_TYPE_EFFECT)) + { + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, + "The '%s' target profile is incompatible with the 'fx' target type.", profile->name); + return VKD3D_ERROR_INVALID_ARGUMENT; + }
if (!hlsl_ctx_init(&ctx, compile_info, profile, message_context)) return VKD3D_ERROR_OUT_OF_MEMORY; diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index de7a66e01..399b040ad 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -1903,6 +1903,7 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( { VKD3D_SHADER_TARGET_D3D_BYTECODE, VKD3D_SHADER_TARGET_DXBC_TPF, + VKD3D_SHADER_TARGET_FX, };
static const enum vkd3d_shader_target_type d3dbc_types[] = diff --git a/libs/vkd3d-utils/vkd3d_utils_main.c b/libs/vkd3d-utils/vkd3d_utils_main.c index a2edf4036..b0ea6081c 100644 --- a/libs/vkd3d-utils/vkd3d_utils_main.c +++ b/libs/vkd3d-utils/vkd3d_utils_main.c @@ -179,28 +179,12 @@ static void close_include(const struct vkd3d_shader_code *code, void *context) ID3DInclude_Close(iface, code->code); }
-HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filename, - const D3D_SHADER_MACRO *macros, ID3DInclude *include, const char *entry_point, - const char *profile, UINT flags, UINT effect_flags, UINT secondary_flags, - const void *secondary_data, SIZE_T secondary_data_size, ID3DBlob **shader_blob, - ID3DBlob **messages_blob) +static enum vkd3d_shader_target_type get_target_for_profile(const char *profile) { - struct vkd3d_shader_preprocess_info preprocess_info; - struct vkd3d_shader_hlsl_source_info hlsl_info; - struct vkd3d_shader_compile_option options[4]; - struct vkd3d_shader_compile_info compile_info; - struct vkd3d_shader_compile_option *option; - struct vkd3d_shader_code byte_code; - const D3D_SHADER_MACRO *macro; size_t profile_len, i; - char *messages; - HRESULT hr; - int ret;
static const char * const d3dbc_profiles[] = { - "fx_2_", - "ps.1.", "ps.2.", "ps.3.", @@ -220,6 +204,49 @@ HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filen "tx_1_", };
+ static const char * const fx_profiles[] = + { + "fx_2_0", + "fx_4_0", + "fx_4_1", + "fx_5_0", + }; + + profile_len = strlen(profile); + for (i = 0; i < ARRAY_SIZE(d3dbc_profiles); ++i) + { + size_t len = strlen(d3dbc_profiles[i]); + + if (len <= profile_len && !memcmp(profile, d3dbc_profiles[i], len)) + return VKD3D_SHADER_TARGET_D3D_BYTECODE; + } + + for (i = 0; i < ARRAY_SIZE(fx_profiles); ++i) + { + if (!strcmp(profile, fx_profiles[i])) + return VKD3D_SHADER_TARGET_FX; + } + + return VKD3D_SHADER_TARGET_DXBC_TPF; +} + +HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filename, + const D3D_SHADER_MACRO *macros, ID3DInclude *include, const char *entry_point, + const char *profile, UINT flags, UINT effect_flags, UINT secondary_flags, + const void *secondary_data, SIZE_T secondary_data_size, ID3DBlob **shader_blob, + ID3DBlob **messages_blob) +{ + struct vkd3d_shader_preprocess_info preprocess_info; + struct vkd3d_shader_hlsl_source_info hlsl_info; + struct vkd3d_shader_compile_option options[4]; + struct vkd3d_shader_compile_info compile_info; + struct vkd3d_shader_compile_option *option; + struct vkd3d_shader_code byte_code; + const D3D_SHADER_MACRO *macro; + char *messages; + HRESULT hr; + int ret; + TRACE("data %p, data_size %lu, filename %s, macros %p, include %p, entry_point %s, " "profile %s, flags %#x, effect_flags %#x, secondary_flags %#x, secondary_data %p, " "secondary_data_size %lu, shader_blob %p, messages_blob %p.\n", @@ -246,24 +273,12 @@ HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filen compile_info.source.code = data; compile_info.source.size = data_size; compile_info.source_type = VKD3D_SHADER_SOURCE_HLSL; - compile_info.target_type = VKD3D_SHADER_TARGET_DXBC_TPF; + compile_info.target_type = get_target_for_profile(profile); compile_info.options = options; compile_info.option_count = 1; compile_info.log_level = VKD3D_SHADER_LOG_INFO; compile_info.source_name = filename;
- profile_len = strlen(profile); - for (i = 0; i < ARRAY_SIZE(d3dbc_profiles); ++i) - { - size_t len = strlen(d3dbc_profiles[i]); - - if (len <= profile_len && !memcmp(profile, d3dbc_profiles[i], len)) - { - compile_info.target_type = VKD3D_SHADER_TARGET_D3D_BYTECODE; - break; - } - } - preprocess_info.type = VKD3D_SHADER_STRUCTURE_TYPE_PREPROCESS_INFO; preprocess_info.next = &hlsl_info; preprocess_info.macros = (const struct vkd3d_shader_macro *)macros; @@ -325,6 +340,21 @@ HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filen
if (!ret) { + /* Unlike other effect profiles fx_4_x is using DXBC container. */ + if (!strcmp(profile, "fx_4_0") || !strcmp(profile, "fx_4_1")) + { + struct vkd3d_shader_dxbc_section_desc section = { .tag = TAG_FX10, .data = byte_code }; + struct vkd3d_shader_code dxbc; + + if ((ret = vkd3d_shader_serialize_dxbc(1, §ion, &dxbc, NULL))) + { + vkd3d_shader_free_shader_code(&byte_code); + return hresult_from_vkd3d_result(ret); + } + + byte_code = dxbc; + } + if (FAILED(hr = vkd3d_blob_create((void *)byte_code.code, byte_code.size, shader_blob))) { vkd3d_shader_free_shader_code(&byte_code); diff --git a/programs/vkd3d-compiler/main.c b/programs/vkd3d-compiler/main.c index 9af228237..4aa368b04 100644 --- a/programs/vkd3d-compiler/main.c +++ b/programs/vkd3d-compiler/main.c @@ -106,6 +106,9 @@ target_type_info[] = "dxbc-tpf", "A 'Tokenized Program Format' shader embedded in a DXBC container.\n" " This is the format used for Direct3D shader model 4 and 5 shaders.\n", true}, + {VKD3D_SHADER_TARGET_FX, + "fx", "Binary format used by Direct3D 9/10.x/11 effects.\n", + true}, {VKD3D_SHADER_TARGET_GLSL, "glsl", "An 'OpenGL Shading Language' shader.\n", false}
On Wed Dec 13 10:58:30 2023 +0000, Giovanni Mascellani wrote:
I don't think it's a good idea to use `base_type` before having made sure that it is relevant for this type. Maybe it doesn't happen in practice now, but in theory `base_type` could happen to be `HLSL_TYPE_TECHNIQUE` even if, say, `class` is `HLSL_CLASS_STRUCT`, just because the irrelevant field was left uninitialized, and then setting `version` would be wrong. Defensively, I would try to avoid that and check `base_type` only if `class == HLSL_CLASS_OBJECT`. Speaking of that, your changes make the documentation comment for field `base_type` in `struct hlsl_type` outdated, so you should fix that too. Notice that `type` is now called `class`, so you could take the chance to fix that too.
One option to improve readability is to have additional data using the same name as its class, so record -> struct, array as it is, new struct for object to hold both version and UAV format.
Addressed current round of comments.
One option to improve readability is to have additional data using the same name as its class, so record -> struct, array as it is, new struct for object to hold both version and UAV format.
I guess that `record` is used instead of `struct` because `struct` is a keyword in C. It could be `struct_`, sure.
The updated comment looks fine to me, but `hlsl_types_are_equal()` still doesn't check `class` before comparing `version`.
On Wed Dec 20 12:15:09 2023 +0000, Giovanni Mascellani wrote:
One option to improve readability is to have additional data using the
same name as its class, so record -> struct, array as it is, new struct for object to hold both version and UAV format. I guess that `record` is used instead of `struct` because `struct` is a keyword in C. It could be `struct_`, sure. The updated comment looks fine to me, but `hlsl_types_are_equal()` still doesn't check `class` before comparing `version`.
Specific name to use is not very important, the point was to use separate structures per-class, regardless of specific type within the class.