Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
-- v3: tests: Enable RWBuffer test. vkd3d-shader/hlsl: Improve UAV format type checking for buffer types. vkd3d-shader/hlsl: Add support for writing RWStructuredBuffer declarations. vkd3d-shader/hlsl: Add support for RWBuffer object. vkd3d-shader: Fix dcl_uav_typed_* formatting.
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/d3d_asm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d-shader/d3d_asm.c index 9438bfac..3357b450 100644 --- a/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d-shader/d3d_asm.c @@ -661,8 +661,9 @@ static void shader_dump_decl_usage(struct vkd3d_d3d_asm_compiler *compiler, else if (semantic->resource.reg.reg.type == VKD3DSPR_RESOURCE || semantic->resource.reg.reg.type == VKD3DSPR_UAV) { if (semantic->resource.reg.reg.type == VKD3DSPR_RESOURCE) - shader_addline(buffer, "_resource_"); + shader_addline(buffer, "_resource");
+ shader_addline(buffer, "_"); shader_dump_resource_type(compiler, semantic->resource_type); if (semantic->resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS || semantic->resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY)
From: Nikolay Sivov nsivov@codeweavers.com
--- libs/vkd3d-shader/hlsl.h | 4 +++- libs/vkd3d-shader/hlsl.l | 1 + libs/vkd3d-shader/hlsl.y | 7 ++++++- libs/vkd3d-shader/tpf.c | 4 ++++ tests/uav.shader_test | 9 +++++++++ 5 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 45c17717..f77e31d6 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -115,7 +115,8 @@ enum hlsl_sampler_dim HLSL_SAMPLER_DIM_2DMS, HLSL_SAMPLER_DIM_2DMSARRAY, HLSL_SAMPLER_DIM_CUBEARRAY, - HLSL_SAMPLER_DIM_MAX = HLSL_SAMPLER_DIM_CUBEARRAY, + HLSL_SAMPLER_DIM_BUFFER, + HLSL_SAMPLER_DIM_MAX = HLSL_SAMPLER_DIM_BUFFER, };
enum hlsl_regset @@ -1000,6 +1001,7 @@ static inline unsigned int hlsl_sampler_dim_count(enum hlsl_sampler_dim dim) switch (dim) { case HLSL_SAMPLER_DIM_1D: + case HLSL_SAMPLER_DIM_BUFFER: return 1; case HLSL_SAMPLER_DIM_1DARRAY: case HLSL_SAMPLER_DIM_2D: diff --git a/libs/vkd3d-shader/hlsl.l b/libs/vkd3d-shader/hlsl.l index 10751bbe..9c76cc4e 100644 --- a/libs/vkd3d-shader/hlsl.l +++ b/libs/vkd3d-shader/hlsl.l @@ -103,6 +103,7 @@ RasterizerState {return KW_RASTERIZERSTATE; } RenderTargetView {return KW_RENDERTARGETVIEW; } return {return KW_RETURN; } register {return KW_REGISTER; } +RWBuffer {return KW_RWBUFFER; } RWTexture1D {return KW_RWTEXTURE1D; } RWTexture2D {return KW_RWTEXTURE2D; } RWTexture3D {return KW_RWTEXTURE3D; } diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 75c0e421..b1559ceb 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -4108,6 +4108,7 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type %token KW_RETURN %token KW_REGISTER %token KW_ROW_MAJOR +%token KW_RWBUFFER %token KW_RWTEXTURE1D %token KW_RWTEXTURE2D %token KW_RWTEXTURE3D @@ -4917,7 +4918,11 @@ texture_ms_type: }
uav_type: - KW_RWTEXTURE1D + KW_RWBUFFER + { + $$ = HLSL_SAMPLER_DIM_BUFFER; + } + | KW_RWTEXTURE1D { $$ = HLSL_SAMPLER_DIM_1D; } diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index fcd7cf93..8c362d50 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -2654,6 +2654,8 @@ static D3D_SRV_DIMENSION sm4_rdef_resource_dimension(const struct hlsl_type *typ return D3D_SRV_DIMENSION_TEXTURE2DMSARRAY; case HLSL_SAMPLER_DIM_CUBEARRAY: return D3D_SRV_DIMENSION_TEXTURECUBEARRAY; + case HLSL_SAMPLER_DIM_BUFFER: + return D3D_SRV_DIMENSION_BUFFER; default: vkd3d_unreachable(); } @@ -2951,6 +2953,8 @@ static enum vkd3d_sm4_resource_type sm4_resource_dimension(const struct hlsl_typ return VKD3D_SM4_RESOURCE_TEXTURE_2DMSARRAY; case HLSL_SAMPLER_DIM_CUBEARRAY: return VKD3D_SM4_RESOURCE_TEXTURE_CUBEARRAY; + case HLSL_SAMPLER_DIM_BUFFER: + return VKD3D_SM4_RESOURCE_BUFFER; default: vkd3d_unreachable(); } diff --git a/tests/uav.shader_test b/tests/uav.shader_test index f0eade4d..a41720bc 100644 --- a/tests/uav.shader_test +++ b/tests/uav.shader_test @@ -161,3 +161,12 @@ float4 main() : sv_target1 todo draw quad probe uav 2 (0, 0) rgba (1.1, 1.2, 1.3, 1.4) probe uav 3 (0, 0) rgba (2.1, 2.2, 2.3, 2.4) + +[pixel shader] +RWBuffer<float4> u : register(u2); + +float4 main() : sv_target1 +{ + u[0] = float4(1.1, 1.2, 1.3, 1.4); + return 0; +}
From: Nikolay Sivov nsivov@codeweavers.com
--- libs/vkd3d-shader/hlsl.h | 28 +++++++++++++++------------- libs/vkd3d-shader/hlsl.l | 1 + libs/vkd3d-shader/hlsl.y | 5 +++++ libs/vkd3d-shader/tpf.c | 29 ++++++++++++++++++++++++++--- 4 files changed, 47 insertions(+), 16 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index f77e31d6..81dce62d 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -104,19 +104,20 @@ enum hlsl_base_type
enum hlsl_sampler_dim { - HLSL_SAMPLER_DIM_GENERIC, - HLSL_SAMPLER_DIM_1D, - HLSL_SAMPLER_DIM_2D, - HLSL_SAMPLER_DIM_3D, - HLSL_SAMPLER_DIM_CUBE, - HLSL_SAMPLER_DIM_LAST_SAMPLER = HLSL_SAMPLER_DIM_CUBE, - HLSL_SAMPLER_DIM_1DARRAY, - HLSL_SAMPLER_DIM_2DARRAY, - HLSL_SAMPLER_DIM_2DMS, - HLSL_SAMPLER_DIM_2DMSARRAY, - HLSL_SAMPLER_DIM_CUBEARRAY, - HLSL_SAMPLER_DIM_BUFFER, - HLSL_SAMPLER_DIM_MAX = HLSL_SAMPLER_DIM_BUFFER, + HLSL_SAMPLER_DIM_GENERIC, + HLSL_SAMPLER_DIM_1D, + HLSL_SAMPLER_DIM_2D, + HLSL_SAMPLER_DIM_3D, + HLSL_SAMPLER_DIM_CUBE, + HLSL_SAMPLER_DIM_LAST_SAMPLER = HLSL_SAMPLER_DIM_CUBE, + HLSL_SAMPLER_DIM_1DARRAY, + HLSL_SAMPLER_DIM_2DARRAY, + HLSL_SAMPLER_DIM_2DMS, + HLSL_SAMPLER_DIM_2DMSARRAY, + HLSL_SAMPLER_DIM_CUBEARRAY, + HLSL_SAMPLER_DIM_BUFFER, + HLSL_SAMPLER_DIM_STRUCTURED_BUFFER, + HLSL_SAMPLER_DIM_MAX = HLSL_SAMPLER_DIM_STRUCTURED_BUFFER, };
enum hlsl_regset @@ -1002,6 +1003,7 @@ static inline unsigned int hlsl_sampler_dim_count(enum hlsl_sampler_dim dim) { case HLSL_SAMPLER_DIM_1D: case HLSL_SAMPLER_DIM_BUFFER: + case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: return 1; case HLSL_SAMPLER_DIM_1DARRAY: case HLSL_SAMPLER_DIM_2D: diff --git a/libs/vkd3d-shader/hlsl.l b/libs/vkd3d-shader/hlsl.l index 9c76cc4e..19e0f2fa 100644 --- a/libs/vkd3d-shader/hlsl.l +++ b/libs/vkd3d-shader/hlsl.l @@ -104,6 +104,7 @@ RenderTargetView {return KW_RENDERTARGETVIEW; } return {return KW_RETURN; } register {return KW_REGISTER; } RWBuffer {return KW_RWBUFFER; } +RWStructuredBuffer {return KW_RWSTRUCTUREDBUFFER; } RWTexture1D {return KW_RWTEXTURE1D; } RWTexture2D {return KW_RWTEXTURE2D; } RWTexture3D {return KW_RWTEXTURE3D; } diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index b1559ceb..e69382d4 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -4109,6 +4109,7 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type %token KW_REGISTER %token KW_ROW_MAJOR %token KW_RWBUFFER +%token KW_RWSTRUCTUREDBUFFER %token KW_RWTEXTURE1D %token KW_RWTEXTURE2D %token KW_RWTEXTURE3D @@ -4922,6 +4923,10 @@ uav_type: { $$ = HLSL_SAMPLER_DIM_BUFFER; } + | KW_RWSTRUCTUREDBUFFER + { + $$ = HLSL_SAMPLER_DIM_STRUCTURED_BUFFER; + } | KW_RWTEXTURE1D { $$ = HLSL_SAMPLER_DIM_1D; diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index 8c362d50..19e411af 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -2655,6 +2655,7 @@ static D3D_SRV_DIMENSION sm4_rdef_resource_dimension(const struct hlsl_type *typ case HLSL_SAMPLER_DIM_CUBEARRAY: return D3D_SRV_DIMENSION_TEXTURECUBEARRAY; case HLSL_SAMPLER_DIM_BUFFER: + case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: return D3D_SRV_DIMENSION_BUFFER; default: vkd3d_unreachable(); @@ -2954,6 +2955,7 @@ static enum vkd3d_sm4_resource_type sm4_resource_dimension(const struct hlsl_typ case HLSL_SAMPLER_DIM_CUBEARRAY: return VKD3D_SM4_RESOURCE_TEXTURE_CUBEARRAY; case HLSL_SAMPLER_DIM_BUFFER: + case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: return VKD3D_SM4_RESOURCE_BUFFER; default: vkd3d_unreachable(); @@ -3029,6 +3031,8 @@ struct sm4_instruction } srcs[4]; unsigned int src_count;
+ unsigned int byte_stride; + uint32_t idx[3]; unsigned int idx_count; }; @@ -3255,6 +3259,8 @@ static void write_sm4_instruction(struct vkd3d_bytecode_buffer *buffer, const st for (i = 0; i < instr->src_count; ++i) size += sm4_register_order(&instr->srcs[i].reg); size += instr->idx_count; + if (instr->byte_stride) + ++size;
token |= (size << VKD3D_SM4_INSTRUCTION_LENGTH_SHIFT);
@@ -3309,6 +3315,9 @@ static void write_sm4_instruction(struct vkd3d_bytecode_buffer *buffer, const st } }
+ if (instr->byte_stride) + put_u32(buffer, instr->byte_stride); + for (j = 0; j < instr->idx_count; ++j) put_u32(buffer, instr->idx[j]); } @@ -3372,9 +3381,6 @@ static void write_sm4_dcl_texture(struct vkd3d_bytecode_buffer *buffer, const st bool uav = (var->data_type->base_type == HLSL_TYPE_UAV); struct sm4_instruction instr = { - .opcode = (uav ? VKD3D_SM5_OP_DCL_UAV_TYPED : VKD3D_SM4_OP_DCL_RESOURCE) - | (sm4_resource_dimension(var->data_type) << VKD3D_SM4_RESOURCE_TYPE_SHIFT), - .dsts[0].reg.type = uav ? VKD3D_SM5_RT_UAV : VKD3D_SM4_RT_RESOURCE, .dsts[0].reg.idx = {uav ? var->regs[HLSL_REGSET_UAVS].id : var->regs[HLSL_REGSET_TEXTURES].id}, .dsts[0].reg.idx_count = 1, @@ -3384,6 +3390,23 @@ static void write_sm4_dcl_texture(struct vkd3d_bytecode_buffer *buffer, const st .idx_count = 1, };
+ if (uav) + { + switch (var->data_type->sampler_dim) + { + case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: + instr.opcode = VKD3D_SM5_OP_DCL_UAV_STRUCTURED; + instr.byte_stride = var->data_type->e.resource_format->reg_size[HLSL_REGSET_NUMERIC] * 4; + break; + default: + instr.opcode = VKD3D_SM5_OP_DCL_UAV_TYPED; + break; + } + } + else + instr.opcode = VKD3D_SM4_OP_DCL_RESOURCE; + instr.opcode |= (sm4_resource_dimension(var->data_type) << VKD3D_SM4_RESOURCE_TYPE_SHIFT); + if (var->data_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS || var->data_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY) {
From: Nikolay Sivov nsivov@codeweavers.com
--- libs/vkd3d-shader/hlsl.y | 48 +++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 8 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index e69382d4..91a22235 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -5059,16 +5059,48 @@ type_no_void: } | uav_type '<' type '>' { - if ($3->class > HLSL_CLASS_VECTOR) - { - struct vkd3d_string_buffer *string; + struct vkd3d_string_buffer *string = hlsl_type_to_string(ctx, $3);
- string = hlsl_type_to_string(ctx, $3); - if (string) - hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "UAV data type %s is not scalar or vector.", string->buffer); - hlsl_release_string_buffer(ctx, string); + switch ($1) + { + case HLSL_SAMPLER_DIM_BUFFER: + if ($3->class > HLSL_CLASS_MATRIX) + { + if (string) + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "UAV data type %s is not scalar, vector, or matrix.", string->buffer); + } + else if ($3->reg_size[HLSL_REGSET_NUMERIC] > 4) + { + if (string) + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "UAV data type %s size exceeds 4-component register size.", string->buffer); + } + break; + case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: + if ($3->class > HLSL_CLASS_STRUCT) + { + if (string) + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "UAV data type %s can't be used with structured buffers.", string->buffer); + } + break; + case HLSL_SAMPLER_DIM_1D: + case HLSL_SAMPLER_DIM_2D: + case HLSL_SAMPLER_DIM_3D: + if ($3->class > HLSL_CLASS_VECTOR) + { + if (string) + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "UAV data type %s is not scalar or vector.", string->buffer); + } + break; + default: + vkd3d_unreachable(); } + + hlsl_release_string_buffer(ctx, string); + $$ = hlsl_new_uav_type(ctx, $1, $3); } | TYPE_IDENTIFIER
From: Nikolay Sivov nsivov@codeweavers.com
--- tests/uav.shader_test | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/tests/uav.shader_test b/tests/uav.shader_test index a41720bc..7204153d 100644 --- a/tests/uav.shader_test +++ b/tests/uav.shader_test @@ -167,6 +167,10 @@ RWBuffer<float4> u : register(u2);
float4 main() : sv_target1 { - u[0] = float4(1.1, 1.2, 1.3, 1.4); + u[0] = float4(11.1, 12.2, 13.3, 14.4); return 0; } + +[test] +todo draw quad +probe uav 2 (0, 0) rgba (11.1, 12.2, 13.3, 14.4)
On Thu May 4 14:50:29 2023 +0000, Zebediah Figura wrote:
Patches look mostly fine now, except that structured buffers are supposed to be able to support types other than a vector, and of course we'd like tests for both types.
Thanks, I added some type checks per buffer type. I'm going to look at tests now, the one that I pushed just now works on Windows, but on Linux vulkan I get this:
`vkd3d:fixme:spirv_compiler_get_descriptor_binding Could not find descriptor binding for type 0x1, space 0, registers [2:2], shader type 0.`
So maybe resource type is somehow is not handled correctly yet, presumably in shader runner? I'm going to look at that to see if I can understand anything there.
On Thu May 4 14:50:48 2023 +0000, Nikolay Sivov wrote:
Thanks, I added some type checks per buffer type. I'm going to look at tests now, the one that I pushed just now works on Windows, but on Linux vulkan I get this: `vkd3d:fixme:spirv_compiler_get_descriptor_binding Could not find descriptor binding for type 0x1, space 0, registers [2:2], shader type 0.` So maybe resource type is somehow is not handled correctly yet, presumably in shader runner? I'm going to look at that to see if I can understand anything there.
The shader runner only declares image UAVs; it'll need separate handling for buffer UAVs. Probably best is to add a new resource type RESOURCE_TYPE_BUFFER_UAV.
It shouldn't be too difficult, but I can also look into this if you'd prefer.