diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 6ddd64d6..ed0b3a40 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -2039,6 +2039,8 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru case HLSL_TYPE_UAV: if (type->sampler_dim == HLSL_SAMPLER_DIM_BUFFER) vkd3d_string_buffer_printf(string, "RWBuffer"); + else if (type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) + vkd3d_string_buffer_printf(string, "RWStructuredBuffer"); else vkd3d_string_buffer_printf(string, "RWTexture%s", dimensions[type->sampler_dim]); if ((inner_string = hlsl_type_to_string(ctx, type->e.resource_format))) diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 89bd3f8d..4ebc63f7 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -117,7 +117,8 @@ enum hlsl_sampler_dim HLSL_SAMPLER_DIM_CUBEARRAY, HLSL_SAMPLER_DIM_LAST_TEXTURE = HLSL_SAMPLER_DIM_CUBEARRAY, HLSL_SAMPLER_DIM_BUFFER, - HLSL_SAMPLER_DIM_MAX = HLSL_SAMPLER_DIM_BUFFER, + HLSL_SAMPLER_DIM_STRUCTURED_BUFFER, + HLSL_SAMPLER_DIM_MAX = HLSL_SAMPLER_DIM_STRUCTURED_BUFFER, }; enum hlsl_regset @@ -148,7 +149,7 @@ struct hlsl_type * If base_type is HLSL_TYPE_TEXTURE, then sampler_dim is <= HLSL_SAMPLER_DIM_LAST_TEXTURE. * If base_type is HLSL_TYPE_UAV, then sampler_dim must be one of HLSL_SAMPLER_DIM_1D, * HLSL_SAMPLER_DIM_2D, HLSL_SAMPLER_DIM_3D, HLSL_SAMPLER_DIM_1DARRAY, HLSL_SAMPLER_DIM_2DARRAY, - * or HLSL_SAMPLER_DIM_BUFFER. + * HLSL_SAMPLER_DIM_BUFFER, or HLSL_SAMPLER_DIM_STRUCTURED_BUFFER. * Otherwise, sampler_dim is not used */ enum hlsl_sampler_dim sampler_dim; /* Name, in case the type is a named struct or a typedef. */ @@ -1027,6 +1028,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 1bc92789..e9ae3ccf 100644 --- a/libs/vkd3d-shader/hlsl.l +++ b/libs/vkd3d-shader/hlsl.l @@ -105,6 +105,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 fee563a6..c0cb6880 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -4147,6 +4147,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 @@ -4960,6 +4961,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 8b267fc9..7c8541f0 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -2960,6 +2960,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(); @@ -3261,6 +3262,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(); @@ -3336,6 +3338,8 @@ struct sm4_instruction } srcs[4]; unsigned int src_count; + unsigned int byte_stride; + uint32_t idx[3]; unsigned int idx_count; }; @@ -3570,6 +3574,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); @@ -3624,6 +3630,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]); } @@ -3709,9 +3718,6 @@ static void write_sm4_dcl_textures(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b instr = (struct sm4_instruction) { - .opcode = (uav ? VKD3D_SM5_OP_DCL_UAV_TYPED : VKD3D_SM4_OP_DCL_RESOURCE) - | (sm4_resource_dimension(component_type) << VKD3D_SM4_RESOURCE_TYPE_SHIFT), - .dsts[0].reg.type = uav ? VKD3D_SM5_RT_UAV : VKD3D_SM4_RT_RESOURCE, .dsts[0].reg.idx = {var->regs[regset].id + i}, .dsts[0].reg.idx_count = 1, @@ -3721,6 +3727,25 @@ static void write_sm4_dcl_textures(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b .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(component_type) << VKD3D_SM4_RESOURCE_TYPE_SHIFT); + if (component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS || component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY) { @@ -4964,6 +4989,12 @@ static void write_sm4_resource_store(struct hlsl_ctx *ctx, return; } + if (resource_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) + { + hlsl_fixme(ctx, &store->node.loc, "Structured buffers store is not implemented.\n"); + return; + } + write_sm4_store_uav_typed(ctx, buffer, &store->resource, store->coords.node, store->value.node); }