From: Evan Tang etang@codeweavers.com
--- libs/vkd3d-shader/hlsl.c | 4 +- libs/vkd3d-shader/hlsl.h | 40 +++--- libs/vkd3d-shader/hlsl.l | 7 + libs/vkd3d-shader/hlsl.y | 127 ++++++++++++------ libs/vkd3d-shader/tpf.c | 3 + tests/hlsl/uav-rwbuffer.shader_test | 6 +- tests/hlsl/uav-rwstructuredbuffer.shader_test | 2 +- tests/hlsl/uav-rwtexture.shader_test | 10 +- 8 files changed, 130 insertions(+), 69 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 04c37498d..3d068ac6d 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -758,7 +758,8 @@ struct hlsl_type *hlsl_new_texture_type(struct hlsl_ctx *ctx, enum hlsl_sampler_ return type; }
-struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, struct hlsl_type *format) +struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, + enum hlsl_sampler_dim dim, struct hlsl_type *format, uint32_t modifiers) { struct hlsl_type *type;
@@ -769,6 +770,7 @@ struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim type->dimx = format->dimx; type->dimy = 1; type->sampler_dim = dim; + type->modifiers = modifiers; type->e.resource_format = format; hlsl_type_calculate_reg_size(ctx, type); list_add_tail(&ctx->types, &type->entry); diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 58188ce6f..43bc079db 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -348,27 +348,28 @@ struct hlsl_attribute struct hlsl_src args[]; };
-#define HLSL_STORAGE_EXTERN 0x00000001 -#define HLSL_STORAGE_NOINTERPOLATION 0x00000002 -#define HLSL_MODIFIER_PRECISE 0x00000004 -#define HLSL_STORAGE_SHARED 0x00000008 -#define HLSL_STORAGE_GROUPSHARED 0x00000010 -#define HLSL_STORAGE_STATIC 0x00000020 -#define HLSL_STORAGE_UNIFORM 0x00000040 -#define HLSL_MODIFIER_VOLATILE 0x00000080 -#define HLSL_MODIFIER_CONST 0x00000100 -#define HLSL_MODIFIER_ROW_MAJOR 0x00000200 -#define HLSL_MODIFIER_COLUMN_MAJOR 0x00000400 -#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_STORAGE_LINEAR 0x00010000 +#define HLSL_STORAGE_EXTERN 0x00000001 +#define HLSL_STORAGE_NOINTERPOLATION 0x00000002 +#define HLSL_MODIFIER_PRECISE 0x00000004 +#define HLSL_STORAGE_SHARED 0x00000008 +#define HLSL_STORAGE_GROUPSHARED 0x00000010 +#define HLSL_STORAGE_STATIC 0x00000020 +#define HLSL_STORAGE_UNIFORM 0x00000040 +#define HLSL_MODIFIER_VOLATILE 0x00000080 +#define HLSL_MODIFIER_CONST 0x00000100 +#define HLSL_MODIFIER_ROW_MAJOR 0x00000200 +#define HLSL_MODIFIER_COLUMN_MAJOR 0x00000400 +#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_STORAGE_LINEAR 0x00010000 +#define HLSL_MODIFIER_RASTERIZER_ORDERED 0x00020000
#define HLSL_TYPE_MODIFIERS_MASK (HLSL_MODIFIER_PRECISE | HLSL_MODIFIER_VOLATILE | \ HLSL_MODIFIER_CONST | HLSL_MODIFIER_ROW_MAJOR | \ - HLSL_MODIFIER_COLUMN_MAJOR) + HLSL_MODIFIER_COLUMN_MAJOR | HLSL_MODIFIER_RASTERIZER_ORDERED)
#define HLSL_INTERPOLATION_MODIFIERS_MASK (HLSL_STORAGE_NOINTERPOLATION | HLSL_STORAGE_CENTROID | \ HLSL_STORAGE_NOPERSPECTIVE | HLSL_STORAGE_LINEAR) @@ -1270,7 +1271,8 @@ struct hlsl_ir_var *hlsl_new_synthetic_var_named(struct hlsl_ctx *ctx, const cha struct hlsl_type *type, const struct vkd3d_shader_location *loc, bool dummy_scope); struct hlsl_type *hlsl_new_texture_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, struct hlsl_type *format, unsigned int sample_count); -struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, struct hlsl_type *format); +struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, + enum hlsl_sampler_dim dim, struct hlsl_type *format, uint32_t modifiers); struct hlsl_ir_node *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned int n, const struct vkd3d_shader_location *loc); struct hlsl_ir_node *hlsl_new_unary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, diff --git a/libs/vkd3d-shader/hlsl.l b/libs/vkd3d-shader/hlsl.l index 6cef0e02e..558506db1 100644 --- a/libs/vkd3d-shader/hlsl.l +++ b/libs/vkd3d-shader/hlsl.l @@ -106,6 +106,13 @@ packoffset {return KW_PACKOFFSET; } pass {return KW_PASS; } PixelShader {return KW_PIXELSHADER; } precise {return KW_PRECISE; } +RasterizerOrderedBuffer {return KW_RASTERIZERORDEREDBUFFER; } +RasterizerOrderedStructuredBuffer {return KW_RASTERIZERORDEREDSTRUCTUREDBUFFER; } +RasterizerOrderedTexture1D {return KW_RASTERIZERORDEREDTEXTURE1D; } +RasterizerOrderedTexture1DArray {return KW_RASTERIZERORDEREDTEXTURE1DARRAY; } +RasterizerOrderedTexture2D {return KW_RASTERIZERORDEREDTEXTURE2D; } +RasterizerOrderedTexture2DArray {return KW_RASTERIZERORDEREDTEXTURE2DARRAY; } +RasterizerOrderedTexture3D {return KW_RASTERIZERORDEREDTEXTURE3D; } RasterizerState {return KW_RASTERIZERSTATE; } register {return KW_REGISTER; } RenderTargetView {return KW_RENDERTARGETVIEW; } diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 5f6334a4d..37a372893 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -5005,6 +5005,48 @@ static void check_duplicated_switch_cases(struct hlsl_ctx *ctx, const struct hls } }
+static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, + struct hlsl_type *format, const struct vkd3d_shader_location* loc) +{ + struct vkd3d_string_buffer *string = hlsl_type_to_string(ctx, format); + + if (!type_contains_only_numerics(format)) + { + if (string) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "UAV type %s is not numeric.", string->buffer); + } + + switch (dim) + { + case HLSL_SAMPLER_DIM_BUFFER: + case HLSL_SAMPLER_DIM_1D: + case HLSL_SAMPLER_DIM_1DARRAY: + case HLSL_SAMPLER_DIM_2D: + case HLSL_SAMPLER_DIM_2DARRAY: + case HLSL_SAMPLER_DIM_3D: + if (format->class == HLSL_CLASS_ARRAY) + { + if (string) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "This type of UAV does not support array type."); + } + else if (hlsl_type_component_count(format) > 4) + { + if (string) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "UAV data type %s size exceeds maximum size.", string->buffer); + } + break; + case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: + break; + default: + vkd3d_unreachable(); + } + + hlsl_release_string_buffer(ctx, string); +} + }
%locations @@ -5084,6 +5126,13 @@ static void check_duplicated_switch_cases(struct hlsl_ctx *ctx, const struct hls %token KW_PASS %token KW_PIXELSHADER %token KW_PRECISE +%token KW_RASTERIZERORDEREDBUFFER +%token KW_RASTERIZERORDEREDSTRUCTUREDBUFFER +%token KW_RASTERIZERORDEREDTEXTURE1D +%token KW_RASTERIZERORDEREDTEXTURE1DARRAY +%token KW_RASTERIZERORDEREDTEXTURE2D +%token KW_RASTERIZERORDEREDTEXTURE2DARRAY +%token KW_RASTERIZERORDEREDTEXTURE3D %token KW_RASTERIZERSTATE %token KW_RENDERTARGETVIEW %token KW_RETURN @@ -5244,7 +5293,7 @@ static void check_duplicated_switch_cases(struct hlsl_ctx *ctx, const struct hls %type <reg_reservation> register_opt %type <reg_reservation> packoffset_opt
-%type <sampler_dim> texture_type texture_ms_type uav_type +%type <sampler_dim> texture_type texture_ms_type uav_type rov_type
%type <semantic> semantic
@@ -6057,6 +6106,36 @@ uav_type: $$ = HLSL_SAMPLER_DIM_3D; }
+rov_type: + KW_RASTERIZERORDEREDBUFFER + { + $$ = HLSL_SAMPLER_DIM_BUFFER; + } + | KW_RASTERIZERORDEREDSTRUCTUREDBUFFER + { + $$ = HLSL_SAMPLER_DIM_STRUCTURED_BUFFER; + } + | KW_RASTERIZERORDEREDTEXTURE1D + { + $$ = HLSL_SAMPLER_DIM_1D; + } + | KW_RASTERIZERORDEREDTEXTURE1DARRAY + { + $$ = HLSL_SAMPLER_DIM_1DARRAY; + } + | KW_RASTERIZERORDEREDTEXTURE2D + { + $$ = HLSL_SAMPLER_DIM_2D; + } + | KW_RASTERIZERORDEREDTEXTURE2DARRAY + { + $$ = HLSL_SAMPLER_DIM_2DARRAY; + } + | KW_RASTERIZERORDEREDTEXTURE3D + { + $$ = HLSL_SAMPLER_DIM_3D; + } + type_no_void: KW_VECTOR '<' type ',' C_INTEGER '>' { @@ -6185,45 +6264,13 @@ type_no_void: } | uav_type '<' type '>' { - struct vkd3d_string_buffer *string = hlsl_type_to_string(ctx, $3); - - if (!type_contains_only_numerics($3)) - { - if (string) - hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "UAV type %s is not numeric.", string->buffer); - } - - switch ($1) - { - case HLSL_SAMPLER_DIM_BUFFER: - case HLSL_SAMPLER_DIM_1D: - case HLSL_SAMPLER_DIM_1DARRAY: - case HLSL_SAMPLER_DIM_2D: - case HLSL_SAMPLER_DIM_2DARRAY: - case HLSL_SAMPLER_DIM_3D: - if ($3->class == HLSL_CLASS_ARRAY) - { - if (string) - hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "This type of UAV does not support array type."); - } - else if (hlsl_type_component_count($3) > 4) - { - if (string) - hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "UAV data type %s size exceeds maximum size.", string->buffer); - } - break; - case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: - break; - default: - vkd3d_unreachable(); - } - - hlsl_release_string_buffer(ctx, string); - - $$ = hlsl_new_uav_type(ctx, $1, $3); + validate_uav_type(ctx, $1, $3, &@3); + $$ = hlsl_new_uav_type(ctx, $1, $3, 0); + } + | rov_type '<' type '>' + { + validate_uav_type(ctx, $1, $3, &@3); + $$ = hlsl_new_uav_type(ctx, $1, $3, HLSL_MODIFIER_RASTERIZER_ORDERED); } | TYPE_IDENTIFIER { diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index adfddd320..f70606e6f 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -4271,6 +4271,9 @@ static void write_sm4_dcl_textures(const struct tpf_writer *tpf, const struct ex instr.extra_bits |= component_type->sample_count << VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT; }
+ if (resource->data_type->modifiers & HLSL_MODIFIER_RASTERIZER_ORDERED) + instr.opcode |= VKD3DSUF_RASTERISER_ORDERED_VIEW << VKD3D_SM5_UAV_FLAGS_SHIFT; + write_sm4_instruction(tpf, &instr); } } diff --git a/tests/hlsl/uav-rwbuffer.shader_test b/tests/hlsl/uav-rwbuffer.shader_test index fd948543b..a9d7997d7 100644 --- a/tests/hlsl/uav-rwbuffer.shader_test +++ b/tests/hlsl/uav-rwbuffer.shader_test @@ -27,7 +27,7 @@ float4 main() : sv_target1 return 0; }
-[pixel shader todo] +[pixel shader] struct s { float3 a; @@ -87,7 +87,7 @@ float4 main() : sv_target1 return 0; }
-[pixel shader fail(sm<6)] +[pixel shader fail(sm<6) todo] RasterizerOrderedBuffer<double3> u;
float4 main() : sv_target1 @@ -95,7 +95,7 @@ float4 main() : sv_target1 return 0; }
-[pixel shader todo] +[pixel shader] RasterizerOrderedBuffer<double2> u;
float4 main() : sv_target1 diff --git a/tests/hlsl/uav-rwstructuredbuffer.shader_test b/tests/hlsl/uav-rwstructuredbuffer.shader_test index 03fa789ef..37f52ee75 100644 --- a/tests/hlsl/uav-rwstructuredbuffer.shader_test +++ b/tests/hlsl/uav-rwstructuredbuffer.shader_test @@ -59,7 +59,7 @@ float4 main() : sv_target1 return 0; }
-[pixel shader todo] +[pixel shader] typedef float arr[2]; RasterizerOrderedStructuredBuffer<arr> u;
diff --git a/tests/hlsl/uav-rwtexture.shader_test b/tests/hlsl/uav-rwtexture.shader_test index ecf0d2905..8f9ec24ec 100644 --- a/tests/hlsl/uav-rwtexture.shader_test +++ b/tests/hlsl/uav-rwtexture.shader_test @@ -182,7 +182,7 @@ float4 main() : sv_target1 }
% RasterizerOrderedTexture1D types -[pixel shader todo] +[pixel shader] struct s { float3 a; @@ -218,7 +218,7 @@ float4 main() : sv_target1 }
% RasterizerOrderedTexture1DArray types -[pixel shader todo] +[pixel shader] struct s { float3 a; @@ -254,7 +254,7 @@ float4 main() : sv_target1 }
% RasterizerOrderedTexture2D types -[pixel shader todo] +[pixel shader] struct s { float3 a; @@ -290,7 +290,7 @@ float4 main() : sv_target1 }
% RasterizerOrderedTexture2DArray types -[pixel shader todo] +[pixel shader] struct s { float3 a; @@ -326,7 +326,7 @@ float4 main() : sv_target1 }
% RasterizerOrderedTexture3D types -[pixel shader todo] +[pixel shader] struct s { float3 a;
Modifiers are otherwise for actual modifier keywords. I can't say this is wrong but it's definitely weird. Less weird would be to use a dedicated HLSL_TYPE_* or a UAV-specific flag.
Modifiers are otherwise for actual modifier keywords. I can't say this is wrong but it's definitely weird. Less weird would be to use a dedicated HLSL_TYPE_* or a UAV-specific flag.
Something like ```c if (uav && resource->data_type->e.uav.rasteriser_ordered) instr.opcode |= VKD3DSUF_RASTERISER_ORDERED_VIEW << VKD3D_SM5_UAV_FLAGS_SHIFT; ``` you mean?
Something like
if (uav && resource->data_type->e.uav.rasteriser_ordered) instr.opcode |= VKD3DSUF_RASTERISER_ORDERED_VIEW << VKD3D_SM5_UAV_FLAGS_SHIFT;
you mean?
Yes, I think that's what I would do.