From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- Makefile.am | 1 + libs/vkd3d-shader/hlsl.l | 1 - libs/vkd3d-shader/hlsl.y | 14 ++++++++------ libs/vkd3d-shader/vkd3d_shader_private.h | 1 + tests/hlsl/precise-modifier.shader_test | 13 +++++++++++++ 5 files changed, 23 insertions(+), 7 deletions(-) create mode 100644 tests/hlsl/precise-modifier.shader_test
diff --git a/Makefile.am b/Makefile.am index 06fd43ab0..bd1905ba8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -155,6 +155,7 @@ vkd3d_shader_tests = \ tests/hlsl/object-parameters.shader_test \ tests/hlsl/object-references.shader_test \ tests/hlsl/pow.shader_test \ + tests/hlsl/precise-modifier.shader_test \ tests/hlsl/rasteriser-ordered-views.shader_test \ tests/hlsl/reflect.shader_test \ tests/hlsl/register-reservations-numeric.shader_test \ diff --git a/libs/vkd3d-shader/hlsl.l b/libs/vkd3d-shader/hlsl.l index 8dcceb94c..600e2cf2c 100644 --- a/libs/vkd3d-shader/hlsl.l +++ b/libs/vkd3d-shader/hlsl.l @@ -109,7 +109,6 @@ packoffset {return KW_PACKOFFSET; } pass {return KW_PASS; } PixelShader {return KW_PIXELSHADER; } pixelshader {return KW_PIXELSHADER; } -precise {return KW_PRECISE; } RasterizerOrderedBuffer {return KW_RASTERIZERORDEREDBUFFER; } RasterizerOrderedStructuredBuffer {return KW_RASTERIZERORDEREDSTRUCTUREDBUFFER; } RasterizerOrderedTexture1D {return KW_RASTERIZERORDEREDTEXTURE1D; } diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index b484a9524..957cf56e8 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -5363,7 +5363,6 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, %token KW_PACKOFFSET %token KW_PASS %token KW_PIXELSHADER -%token KW_PRECISE %token KW_RASTERIZERORDEREDBUFFER %token KW_RASTERIZERORDEREDSTRUCTUREDBUFFER %token KW_RASTERIZERORDEREDTEXTURE1D @@ -6815,10 +6814,6 @@ var_modifiers: { $$ = add_modifiers(ctx, $2, HLSL_STORAGE_NOPERSPECTIVE, &@1); } - | KW_PRECISE var_modifiers - { - $$ = add_modifiers(ctx, $2, HLSL_MODIFIER_PRECISE, &@1); - } | KW_SHARED var_modifiers { $$ = add_modifiers(ctx, $2, HLSL_STORAGE_SHARED, &@1); @@ -6867,7 +6862,14 @@ var_modifiers: { $$ = add_modifiers(ctx, $2, HLSL_MODIFIER_INLINE, &@1); } - + | var_identifier var_modifiers + { + if (!strcmp($1, "precise")) + $$ = add_modifiers(ctx, $2, HLSL_MODIFIER_PRECISE, &@1); + else + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_UNKNOWN_MODIFIER, + "Unknown modifier %s.", debugstr_a($1)); + }
complex_initializer: initializer_expr diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 831fb9bc4..653f01d50 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -149,6 +149,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_HLSL_NON_FINITE_RESULT = 5027, VKD3D_SHADER_ERROR_HLSL_DUPLICATE_SWITCH_CASE = 5028, VKD3D_SHADER_ERROR_HLSL_MISSING_TECHNIQUE = 5029, + VKD3D_SHADER_ERROR_HLSL_UNKNOWN_MODIFIER = 5030,
VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION = 5300, VKD3D_SHADER_WARNING_HLSL_DIVISION_BY_ZERO = 5301, diff --git a/tests/hlsl/precise-modifier.shader_test b/tests/hlsl/precise-modifier.shader_test new file mode 100644 index 000000000..bb603226e --- /dev/null +++ b/tests/hlsl/precise-modifier.shader_test @@ -0,0 +1,13 @@ +[pixel shader] +// 'precise' is not a keyword +float4 precise; + +float4 main() : sv_target +{ + return precise; +} + +[test] +uniform 0 float4 0.1 0.2 0.3 0.4 +draw quad +probe all rgba (0.1, 0.2, 0.3, 0.4)
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl.h | 1 + libs/vkd3d-shader/hlsl.y | 2 ++ tests/hlsl/cbuffer.shader_test | 12 ++++++++++++ 3 files changed, 15 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index da4bb1e78..36e144962 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -374,6 +374,7 @@ struct hlsl_attribute #define HLSL_STORAGE_CENTROID 0x00004000 #define HLSL_STORAGE_NOPERSPECTIVE 0x00008000 #define HLSL_STORAGE_LINEAR 0x00010000 +#define HLSL_MODIFIER_SINGLE 0x00020000
#define HLSL_TYPE_MODIFIERS_MASK (HLSL_MODIFIER_PRECISE | HLSL_MODIFIER_VOLATILE | \ HLSL_MODIFIER_CONST | HLSL_MODIFIER_ROW_MAJOR | \ diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 957cf56e8..02ec2c9e9 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -6866,6 +6866,8 @@ var_modifiers: { if (!strcmp($1, "precise")) $$ = add_modifiers(ctx, $2, HLSL_MODIFIER_PRECISE, &@1); + else if (!strcmp($1, "single")) + $$ = add_modifiers(ctx, $2, HLSL_MODIFIER_SINGLE, &@1); else hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_UNKNOWN_MODIFIER, "Unknown modifier %s.", debugstr_a($1)); diff --git a/tests/hlsl/cbuffer.shader_test b/tests/hlsl/cbuffer.shader_test index bb0937ed0..dea05877f 100644 --- a/tests/hlsl/cbuffer.shader_test +++ b/tests/hlsl/cbuffer.shader_test @@ -29,6 +29,18 @@ float4 main() : sv_target return foo; }
+[pixel shader fail(sm>=6)] +// The 'single' modifier is not a keyword. It's meaningful only for fx_5_0. +single cbuffer cb +{ + float4 single; +}; + +float4 main() : sv_target +{ + return single; +} + [test] uniform 0 float4 1.0 2.0 3.0 4.0 draw quad
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/fx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/fx.c b/libs/vkd3d-shader/fx.c index fd5c84432..c26958b90 100644 --- a/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d-shader/fx.c @@ -734,7 +734,8 @@ static void write_fx_4_buffer(struct hlsl_buffer *b, struct fx_write_context *fx bind_point = b->reservation.reg_index; if (b->type == HLSL_BUFFER_TEXTURE) flags |= IS_TBUFFER; - /* FIXME: set 'single' flag for fx_5_0 */ + if (ctx->profile->major_version == 5 && b->modifiers & HLSL_MODIFIER_SINGLE) + flags |= IS_SINGLE;
name_offset = write_string(b->name, fx);
Unfortunately this doesn't quite work, because "precise" can also be a type. But changing var_identifier to any_identifier is going to run into shift/reduce conflicts. (There's no actual conflicts in the language, but there's not enough lookahead to know how to parse the first "precise" in e.g. "precise foobar".
This may need to be handled on the lexer side, probably by keeping KW_PRECISE but only returning it if it's not defined as a specific identifier.
On Sun Mar 10 21:53:18 2024 +0000, Zebediah Figura wrote:
Unfortunately this doesn't quite work, because "precise" can also be a type. But changing var_identifier to any_identifier is going to run into shift/reduce conflicts. (There's no actual conflicts in the language, but there's not enough lookahead to know how to parse the first "precise" in e.g. "precise foobar". This may need to be handled on the lexer side, probably by keeping KW_PRECISE but only returning it if it's not defined as a specific identifier.
What would be a test case for this? A test like this:
``` precise float4 var; typedef float4 precise;
precise main() : sv_target { return var; } ```
is already working for me. Once 'precise' is defined as a type, it can't be used as a modifier.
On Sun Mar 10 21:53:18 2024 +0000, Nikolay Sivov wrote:
What would be a test case for this? A test like this:
precise float4 var; typedef float4 precise; precise main() : sv_target { return var; }
is already working for me. Once 'precise' is defined as a type, it can't be used as a modifier.
Oh, you're right, that does work. So it's the other way around—that should probably be NEW_IDENTIFIER, not var_identifier. Unless you can use 'precise' as a modifier after you've declared it as a variable name?
On Mon Mar 11 04:20:14 2024 +0000, Zebediah Figura wrote:
Oh, you're right, that does work. So it's the other way around—that should probably be NEW_IDENTIFIER, not var_identifier. Unless you can use 'precise' as a modifier after you've declared it as a variable name?
Yes, you can do that. That might be on purpose, for compatibility with existing sources, if this modifier was added in later versions. I'll add some more tests.