Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
-- v4: vkd3d-shader/tpf: Output interpolation modifiers for input declarations. vkd3d-shader/hlsl: Propagate structure fields modifiers when copying shader inputs. vkd3d-shader/hlsl: Allow interpolation modifiers on structure fields. vkd3d-shader/hlsl: Parse 'centroid' and 'noperspective' modifiers. tests: Add a test for interpolation modifiers specified on structure fields.
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- tests/hlsl/nointerpolation.shader_test | 132 +++++++++++++++++++++++++ 1 file changed, 132 insertions(+)
diff --git a/tests/hlsl/nointerpolation.shader_test b/tests/hlsl/nointerpolation.shader_test index 8f15be6ed..e31527801 100644 --- a/tests/hlsl/nointerpolation.shader_test +++ b/tests/hlsl/nointerpolation.shader_test @@ -25,3 +25,135 @@ float4 main(nointerpolation float4 t : texcoord) : sv_target [test] draw triangle list 3 probe all rgba (0.0, 1.0, 0.0, 1.0) + +[vertex shader] +struct ps_input +{ + nointerpolation float4 t : texcoord; +}; + +void main(uint id : sv_vertexid, inout ps_input input, out float4 pos : sv_position) +{ + float2 coords = float2((id << 1) & 2, id & 2); + pos = float4(coords * float2(2, -2) + float2(-1, 1), 0, 1); +} + +[pixel shader] +struct ps_input +{ + nointerpolation float4 t : texcoord; +}; + +float4 main(ps_input input) : sv_target +{ + return input.t; +} + +[test] +draw triangle list 3 +todo probe all rgba (0.0, 1.0, 0.0, 1.0) + +[vertex shader] +struct ps_input +{ + nointerpolation float4 t : texcoord; +}; + +void main(uint id : sv_vertexid, inout ps_input input, out float4 pos : sv_position) +{ + float2 coords = float2((id << 1) & 2, id & 2); + pos = float4(coords * float2(2, -2) + float2(-1, 1), 0, 1); +} + +[pixel shader] +struct ps_input +{ + float4 t : texcoord; +}; + +float4 main(nointerpolation ps_input input) : sv_target +{ + return input.t; +} + +[test] +draw triangle list 3 +probe all rgba (0.0, 1.0, 0.0, 1.0) + +[vertex shader] +struct ps_input +{ + nointerpolation float4 t : texcoord; +}; + +void main(uint id : sv_vertexid, inout ps_input input, out float4 pos : sv_position) +{ + float2 coords = float2((id << 1) & 2, id & 2); + pos = float4(coords * float2(2, -2) + float2(-1, 1), 0, 1); +} + +[pixel shader todo] +struct ps_input +{ + nointerpolation float4 t : texcoord; +}; + +float4 main(centroid ps_input input) : sv_target +{ + return input.t; +} + +[test] +todo draw triangle list 3 +todo probe all rgba (0.0, 1.0, 0.0, 1.0) + +[vertex shader] +struct ps_input +{ + nointerpolation float4 t : texcoord; +}; + +void main(uint id : sv_vertexid, inout ps_input input, out float4 pos : sv_position) +{ + float2 coords = float2((id << 1) & 2, id & 2); + pos = float4(coords * float2(2, -2) + float2(-1, 1), 0, 1); +} + +[pixel shader todo] +struct ps_input +{ + centroid float4 t : texcoord; +}; + +float4 main(nointerpolation ps_input input) : sv_target +{ + return input.t; +} + +[test] +todo draw triangle list 3 +todo probe all rgba (0.0, 1.0, 0.0, 1.0) + +[vertex shader fail] +struct ps_input +{ + nointerpolation centroid float4 t : texcoord; +}; + +void main(uint id : sv_vertexid, inout ps_input input, out float4 pos : sv_position) +{ + float2 coords = float2((id << 1) & 2, id & 2); + pos = float4(coords * float2(2, -2) + float2(-1, 1), 0, 1); +} + +[vertex shader todo] +struct ps_input +{ + nointerpolation float4 t : texcoord; +}; + +void main(uint id : sv_vertexid, inout centroid ps_input input, out float4 pos : sv_position) +{ + float2 coords = float2((id << 1) & 2, id & 2); + pos = float4(coords * float2(2, -2) + float2(-1, 1), 0, 1); +}
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 4 ++++ libs/vkd3d-shader/hlsl.h | 2 ++ libs/vkd3d-shader/hlsl.l | 2 ++ libs/vkd3d-shader/hlsl.y | 10 ++++++++++ tests/hlsl/nointerpolation.shader_test | 6 +++--- 5 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 0bfba35f4..653b6b293 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -2211,6 +2211,10 @@ struct vkd3d_string_buffer *hlsl_modifiers_to_string(struct hlsl_ctx *ctx, unsig vkd3d_string_buffer_printf(string, "extern "); if (modifiers & HLSL_STORAGE_NOINTERPOLATION) vkd3d_string_buffer_printf(string, "nointerpolation "); + if (modifiers & HLSL_STORAGE_CENTROID) + vkd3d_string_buffer_printf(string, "centroid "); + if (modifiers & HLSL_STORAGE_NOPERSPECTIVE) + vkd3d_string_buffer_printf(string, "noperspective "); if (modifiers & HLSL_MODIFIER_PRECISE) vkd3d_string_buffer_printf(string, "precise "); if (modifiers & HLSL_STORAGE_SHARED) diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index e45256bce..e2046d3c2 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -357,6 +357,8 @@ struct hlsl_attribute #define HLSL_STORAGE_IN 0x00000800 #define HLSL_STORAGE_OUT 0x00001000 #define HLSL_MODIFIER_INLINE 0x00002000 +#define HLSL_STORAGE_CENTROID 0x00004000 +#define HLSL_STORAGE_NOPERSPECTIVE 0x00008000
#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.l b/libs/vkd3d-shader/hlsl.l index e9ae3ccf3..90abd64a3 100644 --- a/libs/vkd3d-shader/hlsl.l +++ b/libs/vkd3d-shader/hlsl.l @@ -74,6 +74,7 @@ BlendState {return KW_BLENDSTATE; } break {return KW_BREAK; } Buffer {return KW_BUFFER; } cbuffer {return KW_CBUFFER; } +centroid {return KW_CENTROID; } compile {return KW_COMPILE; } const {return KW_CONST; } continue {return KW_CONTINUE; } @@ -95,6 +96,7 @@ inout {return KW_INOUT; } matrix {return KW_MATRIX; } namespace {return KW_NAMESPACE; } nointerpolation {return KW_NOINTERPOLATION; } +noperspective {return KW_NOPERSPECTIVE; } out {return KW_OUT; } packoffset {return KW_PACKOFFSET; } pass {return KW_PASS; } diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 8c327c79e..440cae197 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -4631,6 +4631,7 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type %token KW_BREAK %token KW_BUFFER %token KW_CBUFFER +%token KW_CENTROID %token KW_COLUMN_MAJOR %token KW_COMPILE %token KW_CONST @@ -4653,6 +4654,7 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type %token KW_MATRIX %token KW_NAMESPACE %token KW_NOINTERPOLATION +%token KW_NOPERSPECTIVE %token KW_OUT %token KW_PACKOFFSET %token KW_PASS @@ -5944,6 +5946,14 @@ var_modifiers: { $$ = add_modifiers(ctx, $2, HLSL_STORAGE_NOINTERPOLATION, &@1); } + | KW_CENTROID var_modifiers + { + $$ = add_modifiers(ctx, $2, HLSL_STORAGE_CENTROID, &@1); + } + | KW_NOPERSPECTIVE var_modifiers + { + $$ = add_modifiers(ctx, $2, HLSL_STORAGE_NOPERSPECTIVE, &@1); + } | KW_PRECISE var_modifiers { $$ = add_modifiers(ctx, $2, HLSL_MODIFIER_PRECISE, &@1); diff --git a/tests/hlsl/nointerpolation.shader_test b/tests/hlsl/nointerpolation.shader_test index e31527801..3193b2e66 100644 --- a/tests/hlsl/nointerpolation.shader_test +++ b/tests/hlsl/nointerpolation.shader_test @@ -92,7 +92,7 @@ void main(uint id : sv_vertexid, inout ps_input input, out float4 pos : sv_posit pos = float4(coords * float2(2, -2) + float2(-1, 1), 0, 1); }
-[pixel shader todo] +[pixel shader] struct ps_input { nointerpolation float4 t : texcoord; @@ -104,7 +104,7 @@ float4 main(centroid ps_input input) : sv_target }
[test] -todo draw triangle list 3 +draw triangle list 3 todo probe all rgba (0.0, 1.0, 0.0, 1.0)
[vertex shader] @@ -146,7 +146,7 @@ void main(uint id : sv_vertexid, inout ps_input input, out float4 pos : sv_posit pos = float4(coords * float2(2, -2) + float2(-1, 1), 0, 1); }
-[vertex shader todo] +[vertex shader] struct ps_input { nointerpolation float4 t : texcoord;
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl.h | 3 +++ libs/vkd3d-shader/hlsl.y | 2 +- tests/hlsl/nointerpolation.shader_test | 8 ++++---- 3 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index e2046d3c2..8345758e7 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -364,6 +364,9 @@ struct hlsl_attribute HLSL_MODIFIER_CONST | HLSL_MODIFIER_ROW_MAJOR | \ HLSL_MODIFIER_COLUMN_MAJOR)
+#define HLSL_INTERPOLATION_MODIFIERS_MASK (HLSL_STORAGE_NOINTERPOLATION | HLSL_STORAGE_CENTROID | \ + HLSL_STORAGE_NOPERSPECTIVE) + #define HLSL_MODIFIERS_MAJORITY_MASK (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)
#define HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT 0 diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 440cae197..ff5e5ad20 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -4997,7 +4997,7 @@ field:
if (!(type = apply_type_modifiers(ctx, $2, &modifiers, true, &@1))) YYABORT; - if (modifiers & ~HLSL_STORAGE_NOINTERPOLATION) + if (modifiers & ~HLSL_INTERPOLATION_MODIFIERS_MASK) { struct vkd3d_string_buffer *string;
diff --git a/tests/hlsl/nointerpolation.shader_test b/tests/hlsl/nointerpolation.shader_test index 3193b2e66..04f39a8ec 100644 --- a/tests/hlsl/nointerpolation.shader_test +++ b/tests/hlsl/nointerpolation.shader_test @@ -119,7 +119,7 @@ void main(uint id : sv_vertexid, inout ps_input input, out float4 pos : sv_posit pos = float4(coords * float2(2, -2) + float2(-1, 1), 0, 1); }
-[pixel shader todo] +[pixel shader] struct ps_input { centroid float4 t : texcoord; @@ -131,10 +131,10 @@ float4 main(nointerpolation ps_input input) : sv_target }
[test] -todo draw triangle list 3 -todo probe all rgba (0.0, 1.0, 0.0, 1.0) +draw triangle list 3 +probe all rgba (0.0, 1.0, 0.0, 1.0)
-[vertex shader fail] +[vertex shader fail todo] struct ps_input { nointerpolation centroid float4 t : texcoord;
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl_codegen.c | 15 ++++++++++++++- tests/hlsl/nointerpolation.shader_test | 4 ++-- 2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index c0d18a3ef..5c816e895 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -377,6 +377,8 @@ static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block *
for (i = 0; i < hlsl_type_element_count(type); ++i) { + unsigned int element_modifiers = modifiers; + if (type->class == HLSL_CLASS_ARRAY) { elem_semantic_index = semantic_index @@ -391,6 +393,17 @@ static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block * semantic = &field->semantic; elem_semantic_index = semantic->index; loc = &field->loc; + element_modifiers |= field->storage_modifiers; + + /* TODO: 'sample' modifier is not supported yet */ + + /* 'nointerpolation' always takes precedence, next the same is done for 'sample', + remaining modifiers are combined. */ + if (element_modifiers & HLSL_STORAGE_NOINTERPOLATION) + { + element_modifiers &= ~HLSL_INTERPOLATION_MODIFIERS_MASK; + element_modifiers |= HLSL_STORAGE_NOINTERPOLATION; + } }
if (!(c = hlsl_new_uint_constant(ctx, i, &var->loc))) @@ -402,7 +415,7 @@ static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block * return; list_add_after(&c->entry, &element_load->node.entry);
- prepend_input_copy_recurse(ctx, block, element_load, modifiers, semantic, elem_semantic_index); + prepend_input_copy_recurse(ctx, block, element_load, element_modifiers, semantic, elem_semantic_index); } } else diff --git a/tests/hlsl/nointerpolation.shader_test b/tests/hlsl/nointerpolation.shader_test index 04f39a8ec..6c218be86 100644 --- a/tests/hlsl/nointerpolation.shader_test +++ b/tests/hlsl/nointerpolation.shader_test @@ -51,7 +51,7 @@ float4 main(ps_input input) : sv_target
[test] draw triangle list 3 -todo probe all rgba (0.0, 1.0, 0.0, 1.0) +probe all rgba (0.0, 1.0, 0.0, 1.0)
[vertex shader] struct ps_input @@ -105,7 +105,7 @@ float4 main(centroid ps_input input) : sv_target
[test] draw triangle list 3 -todo probe all rgba (0.0, 1.0, 0.0, 1.0) +probe all rgba (0.0, 1.0, 0.0, 1.0)
[vertex shader] struct ps_input
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/tpf.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index 0fc16b4c7..4d38400b6 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -4221,7 +4221,33 @@ static void write_sm4_dcl_semantic(const struct tpf_writer *tpf, const struct hl enum vkd3d_shader_interpolation_mode mode = VKD3DSIM_LINEAR;
if ((var->storage_modifiers & HLSL_STORAGE_NOINTERPOLATION) || type_is_integer(var->data_type)) + { mode = VKD3DSIM_CONSTANT; + } + else + { + static const struct + { + unsigned int modifiers; + enum vkd3d_shader_interpolation_mode mode; + } + modes[] = + { + { HLSL_STORAGE_CENTROID | HLSL_STORAGE_NOPERSPECTIVE, VKD3DSIM_LINEAR_NOPERSPECTIVE_CENTROID }, + { HLSL_STORAGE_NOPERSPECTIVE, VKD3DSIM_LINEAR_NOPERSPECTIVE }, + { HLSL_STORAGE_CENTROID, VKD3DSIM_LINEAR_CENTROID }, + }; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(modes); ++i) + { + if ((var->storage_modifiers & modes[i].modifiers) == modes[i].modifiers) + { + mode = modes[i].mode; + break; + } + } + }
instr.extra_bits |= mode << VKD3D_SM4_INTERPOLATION_MODE_SHIFT; }
On Fri Oct 6 09:34:41 2023 +0000, Zebediah Figura wrote:
This is... technically addressed, but I'd say we should, along the same lines, call these HLSL_STORAGE_CENTROID and HLSL_STORAGE_NOPERSPECTIVE. HLSL_MODIFIER_* is only for those valid on typedefs.
Changed that, thanks.
On Thu Oct 5 20:51:16 2023 +0000, Nikolay Sivov wrote:
Or maybe they are not. The order of precedence is 'nointerpolation' -> 'sample' -> 'centroid' or 'noperspective'. Conflicts are tested only at the same level - on fields or variables.
Added some more tests.
This merge request was approved by Zebediah Figura.
This merge request was approved by Henri Verbeet.