From: Nikolay Sivov nsivov@codeweavers.com
--- libs/vkd3d-shader/hlsl.c | 18 +++++++++++++++--- libs/vkd3d-shader/hlsl.h | 18 +++++++++++++++--- libs/vkd3d-shader/hlsl.y | 15 ++++++++++----- 3 files changed, 40 insertions(+), 11 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index fbe555c9..df8ae331 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -664,7 +664,7 @@ 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_uav_type uav_type, struct hlsl_type *format) { struct hlsl_type *type;
@@ -674,8 +674,20 @@ struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim type->base_type = HLSL_TYPE_UAV; type->dimx = format->dimx; type->dimy = 1; - type->sampler_dim = dim; - type->e.resource_format = format; + switch (uav_type) + { + case HLSL_UAV_RWTEXTURE2D: + type->sampler_dim = HLSL_SAMPLER_DIM_2D; + break; + case HLSL_UAV_RWTEXTURE3D: + type->sampler_dim = HLSL_SAMPLER_DIM_3D; + break; + default: + type->sampler_dim = HLSL_SAMPLER_DIM_1D; + break; + } + type->e.uav.format = format; + type->e.uav.uav_type = uav_type; hlsl_type_calculate_reg_size(ctx, type); list_add_tail(&ctx->types, &type->entry); return type; diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 0256339c..7186ddd3 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -118,6 +118,13 @@ enum hlsl_sampler_dim HLSL_SAMPLER_DIM_MAX = HLSL_SAMPLER_DIM_CUBEARRAY, };
+enum hlsl_uav_type +{ + HLSL_UAV_RWTEXTURE1D, + HLSL_UAV_RWTEXTURE2D, + HLSL_UAV_RWTEXTURE3D, +}; + enum hlsl_regset { HLSL_REGSET_SAMPLERS, @@ -186,8 +193,13 @@ struct hlsl_type /* Array length, or HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT if it is not known yet at parse time. */ unsigned int elements_count; } array; - /* Format of the data contained within the type if the base_type is HLSL_TYPE_TEXTURE or - * HLSL_TYPE_UAV. */ + /* Additional information if type is HLSL_TYPE_UAV. */ + struct + { + struct hlsl_type *format; + enum hlsl_uav_type uav_type; + } uav; + /* Format of the data contained within the type if the base_type is HLSL_TYPE_TEXTURE */ struct hlsl_type *resource_format; } e;
@@ -1122,7 +1134,7 @@ struct hlsl_ir_var *hlsl_new_synthetic_var(struct hlsl_ctx *ctx, const char *tem struct hlsl_type *type, const struct vkd3d_shader_location *loc); 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_uav_type type, struct hlsl_type *format); struct hlsl_ir_constant *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.y b/libs/vkd3d-shader/hlsl.y index ab0b3f65..3741761d 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -781,7 +781,10 @@ static bool add_array_access(struct hlsl_ctx *ctx, struct list *instrs, struct h if (!(index = add_zero_mipmap_level(ctx, instrs, index, dim_count, loc))) return false;
- load_params.format = expr_type->e.resource_format; + if (expr_type->base_type == HLSL_TYPE_TEXTURE) + load_params.format = expr_type->e.resource_format; + else + load_params.format = expr_type->e.uav.format; load_params.resource = array; load_params.coords = index;
@@ -4111,6 +4114,7 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type struct hlsl_semantic semantic; enum hlsl_buffer_type buffer_type; enum hlsl_sampler_dim sampler_dim; + enum hlsl_uav_type uav_type; struct hlsl_attribute *attr; struct parse_attribute_list attr_list; } @@ -4300,7 +4304,8 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type %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 +%type <uav_type> uav_type
%type <semantic> semantic
@@ -4962,15 +4967,15 @@ texture_ms_type: uav_type: KW_RWTEXTURE1D { - $$ = HLSL_SAMPLER_DIM_1D; + $$ = HLSL_UAV_RWTEXTURE1D; } | KW_RWTEXTURE2D { - $$ = HLSL_SAMPLER_DIM_2D; + $$ = HLSL_UAV_RWTEXTURE2D; } | KW_RWTEXTURE3D { - $$ = HLSL_SAMPLER_DIM_3D; + $$ = HLSL_UAV_RWTEXTURE3D; }
type_no_void:
From: Nikolay Sivov nsivov@codeweavers.com
--- libs/vkd3d-shader/trace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/trace.c b/libs/vkd3d-shader/trace.c index 9438bfac..3357b450 100644 --- a/libs/vkd3d-shader/trace.c +++ b/libs/vkd3d-shader/trace.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 | 1 + libs/vkd3d-shader/hlsl.l | 1 + libs/vkd3d-shader/hlsl.y | 7 ++++++- libs/vkd3d-shader/tpf.c | 17 +++++++++++++++++ tests/uav.shader_test | 5 +++++ 5 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 7186ddd3..a287dcb7 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -120,6 +120,7 @@ enum hlsl_sampler_dim
enum hlsl_uav_type { + HLSL_UAV_RWBUFFER, HLSL_UAV_RWTEXTURE1D, HLSL_UAV_RWTEXTURE2D, HLSL_UAV_RWTEXTURE3D, 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 3741761d..286aa3f9 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -4155,6 +4155,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 @@ -4965,7 +4966,11 @@ texture_ms_type: }
uav_type: - KW_RWTEXTURE1D + KW_RWBUFFER + { + $$ = HLSL_UAV_RWBUFFER; + } + | KW_RWTEXTURE1D { $$ = HLSL_UAV_RWTEXTURE1D; } diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index 38d5c180..dd1b69f5 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -2931,6 +2931,23 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
static enum vkd3d_sm4_resource_type sm4_resource_dimension(const struct hlsl_type *type) { + if (type->base_type == HLSL_TYPE_UAV) + { + switch (type->e.uav.uav_type) + { + case HLSL_UAV_RWBUFFER: + return VKD3D_SM4_RESOURCE_BUFFER; + case HLSL_UAV_RWTEXTURE1D: + return VKD3D_SM4_RESOURCE_TEXTURE_1D; + case HLSL_UAV_RWTEXTURE2D: + return VKD3D_SM4_RESOURCE_TEXTURE_2D; + case HLSL_UAV_RWTEXTURE3D: + return VKD3D_SM4_RESOURCE_TEXTURE_3D; + default: + vkd3d_unreachable(); + } + } + switch (type->sampler_dim) { case HLSL_SAMPLER_DIM_1D: diff --git a/tests/uav.shader_test b/tests/uav.shader_test index f0eade4d..4afdf9df 100644 --- a/tests/uav.shader_test +++ b/tests/uav.shader_test @@ -161,3 +161,8 @@ 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) + +[uav 1] +size (1, 1) + +0.1 0.2 0.3 0.4
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl.h | 1 + libs/vkd3d-shader/hlsl.l | 1 + libs/vkd3d-shader/hlsl.y | 5 +++++ libs/vkd3d-shader/tpf.c | 31 ++++++++++++++++++++++++++++--- 4 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index a287dcb7..b97dbb89 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -121,6 +121,7 @@ enum hlsl_sampler_dim enum hlsl_uav_type { HLSL_UAV_RWBUFFER, + HLSL_UAV_RWSTRUCTUREDBUFFER, HLSL_UAV_RWTEXTURE1D, HLSL_UAV_RWTEXTURE2D, HLSL_UAV_RWTEXTURE3D, 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 286aa3f9..05af739b 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -4156,6 +4156,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 @@ -4970,6 +4971,10 @@ uav_type: { $$ = HLSL_UAV_RWBUFFER; } + | KW_RWSTRUCTUREDBUFFER + { + $$ = HLSL_UAV_RWSTRUCTUREDBUFFER; + } | KW_RWTEXTURE1D { $$ = HLSL_UAV_RWTEXTURE1D; diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index dd1b69f5..4d57ccd9 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -2936,6 +2936,7 @@ static enum vkd3d_sm4_resource_type sm4_resource_dimension(const struct hlsl_typ switch (type->e.uav.uav_type) { case HLSL_UAV_RWBUFFER: + case HLSL_UAV_RWSTRUCTUREDBUFFER: return VKD3D_SM4_RESOURCE_BUFFER; case HLSL_UAV_RWTEXTURE1D: return VKD3D_SM4_RESOURCE_TEXTURE_1D; @@ -3044,6 +3045,8 @@ struct sm4_instruction
uint32_t idx[3]; unsigned int idx_count; + + unsigned int byte_stride; };
static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *reg, @@ -3268,6 +3271,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);
@@ -3322,6 +3327,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]); } @@ -3385,9 +3393,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, @@ -3397,6 +3402,26 @@ static void write_sm4_dcl_texture(struct vkd3d_bytecode_buffer *buffer, const st .idx_count = 1, };
+ if (uav) + { + switch (var->data_type->e.uav.uav_type) + { + case HLSL_UAV_RWBUFFER: + case HLSL_UAV_RWTEXTURE1D: + case HLSL_UAV_RWTEXTURE2D: + case HLSL_UAV_RWTEXTURE3D: + instr.opcode = VKD3D_SM5_OP_DCL_UAV_TYPED; + break; + case HLSL_UAV_RWSTRUCTUREDBUFFER: + instr.opcode = VKD3D_SM5_OP_DCL_UAV_STRUCTURED; + instr.byte_stride = var->data_type->e.uav.format->reg_size[HLSL_REGSET_NUMERIC] * 4; + 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) {
I don't think I see how 1/4 is an improvement?
On Tue May 2 18:18:54 2023 +0000, Zebediah Figura wrote:
I don't think I see how 1/4 is an improvement?
Setting sampler type field is not enough to distinguish between all kinds of all buffer objects.
On Tue May 2 18:18:54 2023 +0000, Nikolay Sivov wrote:
Setting sampler type field is not enough to distinguish between all kinds of all buffer objects.
Sure, but then we can just add more sampler types? Especially because all of the buffer objects are also available in SRV form.
On Tue May 2 18:28:47 2023 +0000, Zebediah Figura wrote:
Sure, but then we can just add more sampler types? Especially because all of the buffer objects are also available in SRV form.
What would you call a sampler type for RWBuffer<> or RWStructuredBuffer<>, or append/consume ones ? What do you mean by SRV form?
On Tue May 2 18:44:06 2023 +0000, Nikolay Sivov wrote:
What would you call a sampler type for RWBuffer<> or RWStructuredBuffer<>, or append/consume ones ? What do you mean by SRV form?
A d3d10/11 SRV ("shader resource view") is one way of exposing resources to a shader read-only. These resources can be buffers or textures. Textures are accessed via HLSL's Texture1D, Texture2D, etc. types. Buffers are accessed via HLSL's Buffer, StructuredBuffer, ByteAddressBuffer types. Almost all SRV types correspond with a UAV type, by adding "RW" to the front of the type name.
We use HLSL_TYPE_TEXTURE for texture SRVs, and I think we should probably continue to use it for buffer SRVs. The naming is perhaps questionable and could be adjusted accordingly (though on the other hand, GL calls the equivalent feature a "buffer texture"). Similarly, "sampler_dim" is not a great name given that buffers can't be sampled, we could change that to "resource_dim" or something.