Module: vkd3d Branch: master Commit: dfa0076473e0d4b56b0fba51a953ff8419d9e833 URL: https://gitlab.winehq.org/wine/vkd3d/-/commit/dfa0076473e0d4b56b0fba51a953ff...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Thu Apr 27 10:15:36 2023 +0200
vkd3d-shader/hlsl: Add support for sample index argument in Load().
---
libs/vkd3d-shader/hlsl.c | 8 ++++++++ libs/vkd3d-shader/hlsl.h | 4 ++-- libs/vkd3d-shader/hlsl.y | 8 +++++--- libs/vkd3d-shader/hlsl_codegen.c | 2 ++ libs/vkd3d-shader/tpf.c | 42 +++++++++++++++++++++++++++++++++++++--- tests/texture-load.shader_test | 15 ++++++++++++++ 6 files changed, 71 insertions(+), 8 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 617aef30..80541cac 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1351,6 +1351,7 @@ struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx, }
hlsl_src_from_node(&load->coords, params->coords); + hlsl_src_from_node(&load->sample_index, params->sample_index); hlsl_src_from_node(&load->texel_offset, params->texel_offset); hlsl_src_from_node(&load->lod, params->lod); load->sampling_dim = params->sampling_dim; @@ -1643,6 +1644,7 @@ static struct hlsl_ir_node *clone_resource_load(struct hlsl_ctx *ctx, } clone_src(map, &dst->coords, &src->coords); clone_src(map, &dst->lod, &src->lod); + clone_src(map, &dst->sample_index, &src->sample_index); clone_src(map, &dst->texel_offset, &src->texel_offset); dst->sampling_dim = src->sampling_dim; return &dst->node; @@ -2439,6 +2441,11 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru dump_deref(buffer, &load->sampler); vkd3d_string_buffer_printf(buffer, ", coords = "); dump_src(buffer, &load->coords); + if (load->sample_index.node) + { + vkd3d_string_buffer_printf(buffer, ", sample index = "); + dump_src(buffer, &load->sample_index); + } if (load->texel_offset.node) { vkd3d_string_buffer_printf(buffer, ", offset = "); @@ -2685,6 +2692,7 @@ static void free_ir_resource_load(struct hlsl_ir_resource_load *load) hlsl_src_remove(&load->coords); hlsl_src_remove(&load->lod); hlsl_src_remove(&load->texel_offset); + hlsl_src_remove(&load->sample_index); vkd3d_free(load); }
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 6a4e314d..7b042f5b 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -623,7 +623,7 @@ struct hlsl_ir_resource_load struct hlsl_ir_node node; enum hlsl_resource_load_type load_type; struct hlsl_deref resource, sampler; - struct hlsl_src coords, lod, texel_offset; + struct hlsl_src coords, lod, sample_index, texel_offset; enum hlsl_sampler_dim sampling_dim; };
@@ -825,7 +825,7 @@ struct hlsl_resource_load_params struct hlsl_type *format; enum hlsl_resource_load_type type; struct hlsl_ir_node *resource, *sampler; - struct hlsl_ir_node *coords, *lod, *texel_offset; + struct hlsl_ir_node *coords, *lod, *sample_index, *texel_offset; enum hlsl_sampler_dim sampling_dim; };
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 86f23665..c43e8163 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -3743,7 +3743,9 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, stru } if (multisampled) { - hlsl_fixme(ctx, loc, "Load() sampling index parameter."); + if (!(load_params.sample_index = add_implicit_conversion(ctx, instrs, params->args[1], + hlsl_get_scalar_type(ctx, HLSL_TYPE_INT), loc))) + return false; }
assert(offset_dim); @@ -3758,9 +3760,9 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, stru hlsl_fixme(ctx, loc, "Tiled resource status argument."); }
- /* +1 for the mipmap level */ + /* +1 for the mipmap level for non-multisampled textures */ if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[0], - hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim + 1), loc))) + hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim + !multisampled), loc))) return false;
load_params.format = object_type->e.resource_format; diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 638dab6e..6fae97db 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -2674,6 +2674,8 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop load->texel_offset.node->last_read = instr->index; if (load->lod.node) load->lod.node->last_read = instr->index; + if (load->sample_index.node) + load->sample_index.node->last_read = instr->index; break; } case HLSL_IR_RESOURCE_STORE: diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index eadad3b9..da7f6368 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -2809,6 +2809,8 @@ static D3D_SHADER_VARIABLE_TYPE sm4_base_type(const struct hlsl_type *type) return D3D_SVT_TEXTURE1D; case HLSL_SAMPLER_DIM_2D: return D3D_SVT_TEXTURE2D; + case HLSL_SAMPLER_DIM_2DMS: + return D3D_SVT_TEXTURE2DMS; case HLSL_SAMPLER_DIM_3D: return D3D_SVT_TEXTURE3D; case HLSL_SAMPLER_DIM_CUBE: @@ -3984,14 +3986,20 @@ static void write_sm4_constant(struct hlsl_ctx *ctx, static void write_sm4_ld(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_type *resource_type, const struct hlsl_ir_node *dst, const struct hlsl_deref *resource, const struct hlsl_ir_node *coords, - const struct hlsl_ir_node *texel_offset, enum hlsl_sampler_dim dim) + const struct hlsl_ir_node *sample_index, const struct hlsl_ir_node *texel_offset, + enum hlsl_sampler_dim dim) { + bool multisampled = resource_type->base_type == HLSL_TYPE_TEXTURE + && (resource_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS || resource_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY); bool uav = (hlsl_type_get_regset(resource_type) == HLSL_REGSET_UAVS); struct sm4_instruction instr; unsigned int dim_count;
memset(&instr, 0, sizeof(instr)); - instr.opcode = uav ? VKD3D_SM5_OP_LD_UAV_TYPED : VKD3D_SM4_OP_LD; + if (uav) + instr.opcode = VKD3D_SM5_OP_LD_UAV_TYPED; + else + instr.opcode = multisampled ? VKD3D_SM4_OP_LD2DMS : VKD3D_SM4_OP_LD;
if (texel_offset) { @@ -4023,6 +4031,33 @@ static void write_sm4_ld(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buf
instr.src_count = 2;
+ if (multisampled) + { + if (sample_index->type == HLSL_IR_CONSTANT) + { + struct sm4_register *reg = &instr.srcs[2].reg; + struct hlsl_ir_constant *index; + + index = hlsl_ir_constant(sample_index); + + memset(&instr.srcs[2], 0, sizeof(instr.srcs[2])); + instr.srcs[2].swizzle_type = VKD3D_SM4_SWIZZLE_NONE; + reg->type = VKD3D_SM4_RT_IMMCONST; + reg->dim = VKD3D_SM4_DIMENSION_SCALAR; + reg->immconst_uint[0] = index->value.u[0].u; + } + else if (ctx->profile->major_version == 4 && ctx->profile->minor_version == 0) + { + hlsl_error(ctx, &sample_index->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Expected literal sample index."); + } + else + { + sm4_src_from_node(&instr.srcs[2], sample_index, 0); + } + + ++instr.src_count; + } + write_sm4_instruction(buffer, &instr); }
@@ -4833,6 +4868,7 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx, { const struct hlsl_type *resource_type = load->resource.var->data_type; const struct hlsl_ir_node *texel_offset = load->texel_offset.node; + const struct hlsl_ir_node *sample_index = load->sample_index.node; const struct hlsl_ir_node *coords = load->coords.node;
if (!hlsl_type_is_resource(resource_type)) @@ -4868,7 +4904,7 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx, { case HLSL_RESOURCE_LOAD: write_sm4_ld(ctx, buffer, resource_type, &load->node, &load->resource, - coords, texel_offset, load->sampling_dim); + coords, sample_index, texel_offset, load->sampling_dim); break;
case HLSL_RESOURCE_SAMPLE: diff --git a/tests/texture-load.shader_test b/tests/texture-load.shader_test index 7d39fb65..4893e4d8 100644 --- a/tests/texture-load.shader_test +++ b/tests/texture-load.shader_test @@ -35,3 +35,18 @@ probe (0, 0) rgba (0.1, 0.2, 0.3, 0.4) probe (1, 0) rgba (0.6, 0.5, 0.2, 0.1) probe (0, 1) rgba (0.5, 0.7, 0.6, 0.8) probe (1, 1) rgba (0.8, 0.0, 0.7, 1.0) + +[pixel shader] +Texture2DMS<float4, 1> t; + +float4 main(float4 pos : sv_position) : sv_target +{ + return t.Load(pos.yx, 0); +} + +[test] +draw quad +probe (0, 0) rgba (0.1, 0.2, 0.3, 0.4) +probe (1, 0) rgba (0.6, 0.5, 0.2, 0.1) +probe (0, 1) rgba (0.5, 0.7, 0.6, 0.8) +probe (1, 1) rgba (0.8, 0.0, 0.7, 1.0)