vkd3d-shader/hlsl: Add support for writing RWStructuredBuffer declarations.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
This commit is contained in:
Nikolay Sivov 2023-05-16 12:55:31 +02:00 committed by Alexandre Julliard
parent 3de824bfd8
commit cff22ecde8
Notes: Alexandre Julliard 2023-05-22 23:19:48 +02:00
Approved-by: Giovanni Mascellani (@giomasce)
Approved-by: Zebediah Figura (@zfigura)
Approved-by: Henri Verbeet (@hverbeet)
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/193
5 changed files with 46 additions and 5 deletions

View File

@ -2039,6 +2039,8 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru
case HLSL_TYPE_UAV: case HLSL_TYPE_UAV:
if (type->sampler_dim == HLSL_SAMPLER_DIM_BUFFER) if (type->sampler_dim == HLSL_SAMPLER_DIM_BUFFER)
vkd3d_string_buffer_printf(string, "RWBuffer"); vkd3d_string_buffer_printf(string, "RWBuffer");
else if (type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER)
vkd3d_string_buffer_printf(string, "RWStructuredBuffer");
else else
vkd3d_string_buffer_printf(string, "RWTexture%s", dimensions[type->sampler_dim]); vkd3d_string_buffer_printf(string, "RWTexture%s", dimensions[type->sampler_dim]);
if ((inner_string = hlsl_type_to_string(ctx, type->e.resource_format))) if ((inner_string = hlsl_type_to_string(ctx, type->e.resource_format)))

View File

@ -117,7 +117,8 @@ enum hlsl_sampler_dim
HLSL_SAMPLER_DIM_CUBEARRAY, HLSL_SAMPLER_DIM_CUBEARRAY,
HLSL_SAMPLER_DIM_LAST_TEXTURE = HLSL_SAMPLER_DIM_CUBEARRAY, HLSL_SAMPLER_DIM_LAST_TEXTURE = HLSL_SAMPLER_DIM_CUBEARRAY,
HLSL_SAMPLER_DIM_BUFFER, 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 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_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, * 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, * 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 */ * Otherwise, sampler_dim is not used */
enum hlsl_sampler_dim sampler_dim; enum hlsl_sampler_dim sampler_dim;
/* Name, in case the type is a named struct or a typedef. */ /* 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_1D:
case HLSL_SAMPLER_DIM_BUFFER: case HLSL_SAMPLER_DIM_BUFFER:
case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER:
return 1; return 1;
case HLSL_SAMPLER_DIM_1DARRAY: case HLSL_SAMPLER_DIM_1DARRAY:
case HLSL_SAMPLER_DIM_2D: case HLSL_SAMPLER_DIM_2D:

View File

@ -105,6 +105,7 @@ RenderTargetView {return KW_RENDERTARGETVIEW; }
return {return KW_RETURN; } return {return KW_RETURN; }
register {return KW_REGISTER; } register {return KW_REGISTER; }
RWBuffer {return KW_RWBUFFER; } RWBuffer {return KW_RWBUFFER; }
RWStructuredBuffer {return KW_RWSTRUCTUREDBUFFER; }
RWTexture1D {return KW_RWTEXTURE1D; } RWTexture1D {return KW_RWTEXTURE1D; }
RWTexture2D {return KW_RWTEXTURE2D; } RWTexture2D {return KW_RWTEXTURE2D; }
RWTexture3D {return KW_RWTEXTURE3D; } RWTexture3D {return KW_RWTEXTURE3D; }

View File

@ -4147,6 +4147,7 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type
%token KW_REGISTER %token KW_REGISTER
%token KW_ROW_MAJOR %token KW_ROW_MAJOR
%token KW_RWBUFFER %token KW_RWBUFFER
%token KW_RWSTRUCTUREDBUFFER
%token KW_RWTEXTURE1D %token KW_RWTEXTURE1D
%token KW_RWTEXTURE2D %token KW_RWTEXTURE2D
%token KW_RWTEXTURE3D %token KW_RWTEXTURE3D
@ -4960,6 +4961,10 @@ uav_type:
{ {
$$ = HLSL_SAMPLER_DIM_BUFFER; $$ = HLSL_SAMPLER_DIM_BUFFER;
} }
| KW_RWSTRUCTUREDBUFFER
{
$$ = HLSL_SAMPLER_DIM_STRUCTURED_BUFFER;
}
| KW_RWTEXTURE1D | KW_RWTEXTURE1D
{ {
$$ = HLSL_SAMPLER_DIM_1D; $$ = HLSL_SAMPLER_DIM_1D;

View File

@ -2960,6 +2960,7 @@ static D3D_SRV_DIMENSION sm4_rdef_resource_dimension(const struct hlsl_type *typ
case HLSL_SAMPLER_DIM_CUBEARRAY: case HLSL_SAMPLER_DIM_CUBEARRAY:
return D3D_SRV_DIMENSION_TEXTURECUBEARRAY; return D3D_SRV_DIMENSION_TEXTURECUBEARRAY;
case HLSL_SAMPLER_DIM_BUFFER: case HLSL_SAMPLER_DIM_BUFFER:
case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER:
return D3D_SRV_DIMENSION_BUFFER; return D3D_SRV_DIMENSION_BUFFER;
default: default:
vkd3d_unreachable(); vkd3d_unreachable();
@ -3261,6 +3262,7 @@ static enum vkd3d_sm4_resource_type sm4_resource_dimension(const struct hlsl_typ
case HLSL_SAMPLER_DIM_CUBEARRAY: case HLSL_SAMPLER_DIM_CUBEARRAY:
return VKD3D_SM4_RESOURCE_TEXTURE_CUBEARRAY; return VKD3D_SM4_RESOURCE_TEXTURE_CUBEARRAY;
case HLSL_SAMPLER_DIM_BUFFER: case HLSL_SAMPLER_DIM_BUFFER:
case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER:
return VKD3D_SM4_RESOURCE_BUFFER; return VKD3D_SM4_RESOURCE_BUFFER;
default: default:
vkd3d_unreachable(); vkd3d_unreachable();
@ -3336,6 +3338,8 @@ struct sm4_instruction
} srcs[4]; } srcs[4];
unsigned int src_count; unsigned int src_count;
unsigned int byte_stride;
uint32_t idx[3]; uint32_t idx[3];
unsigned int idx_count; 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) for (i = 0; i < instr->src_count; ++i)
size += sm4_register_order(&instr->srcs[i].reg); size += sm4_register_order(&instr->srcs[i].reg);
size += instr->idx_count; size += instr->idx_count;
if (instr->byte_stride)
++size;
token |= (size << VKD3D_SM4_INSTRUCTION_LENGTH_SHIFT); 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) for (j = 0; j < instr->idx_count; ++j)
put_u32(buffer, instr->idx[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) 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.type = uav ? VKD3D_SM5_RT_UAV : VKD3D_SM4_RT_RESOURCE,
.dsts[0].reg.idx = {var->regs[regset].id + i}, .dsts[0].reg.idx = {var->regs[regset].id + i},
.dsts[0].reg.idx_count = 1, .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, .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 if (component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS
|| component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY) || component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY)
{ {
@ -4964,6 +4989,12 @@ static void write_sm4_resource_store(struct hlsl_ctx *ctx,
return; 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); write_sm4_store_uav_typed(ctx, buffer, &store->resource, store->coords.node, store->value.node);
} }