Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
-- v2: 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 b15950f4..778b8560 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 1ce65e84..a4ae82ba 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -4148,6 +4148,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 @@ -4957,7 +4958,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 38d5c180..12f21963 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 778b8560..da55e434 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 a4ae82ba..8ed6bbc8 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -4149,6 +4149,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 @@ -4962,6 +4963,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 12f21963..a4f90528 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) {
Now without additional UAV type field. RWBuffer test will fail a probe, I haven't looked at why, but generated shader looks fine. I'm going to revisit once general approach is approved.
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.