Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl_sm4.c | 2 +- libs/vkd3d-shader/sm4.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 9d45e1633..f8eb0a1ef 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -561,7 +561,7 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) put_u32(&buffer, sm4_resource_format(var->data_type)); put_u32(&buffer, sm4_rdef_resource_dimension(var->data_type)); put_u32(&buffer, ~0u); /* FIXME: multisample count */ - flags |= (var->data_type->e.resource_format->dimx - 1) << 2; + flags |= (var->data_type->e.resource_format->dimx - 1) << VKD3D_SM4_SIF_TEXTURE_COMPONENTS_SHIFT; } put_u32(&buffer, var->reg.id); put_u32(&buffer, 1); /* bind count */ diff --git a/libs/vkd3d-shader/sm4.h b/libs/vkd3d-shader/sm4.h index ddcb9a861..17a08ee27 100644 --- a/libs/vkd3d-shader/sm4.h +++ b/libs/vkd3d-shader/sm4.h @@ -526,4 +526,7 @@ enum vkd3d_sm4_shader_data_type VKD3D_SM4_SHADER_DATA_MESSAGE = 0x4, };
+/* The shift that corresponds to the D3D_SIF_TEXTURE_COMPONENTS mask. */ +#define VKD3D_SM4_SIF_TEXTURE_COMPONENTS_SHIFT 2 + #endif /* __VKD3D_SM4_H */
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl_sm4.c | 95 +++++++++++++++++++++++++++++++++--- 1 file changed, 88 insertions(+), 7 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index f8eb0a1ef..5ab7df5f9 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -763,6 +763,7 @@ static unsigned int sm4_swizzle_type(enum vkd3d_sm4_register_type type)
case VKD3D_SM4_RT_CONSTBUFFER: case VKD3D_SM4_RT_INPUT: + case VKD3D_SM4_RT_RESOURCE: case VKD3D_SM4_RT_TEMP: return VKD3D_SM4_SWIZZLE_VEC4;
@@ -779,14 +780,26 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r
if (var->is_uniform) { - unsigned int offset = hlsl_offset_from_deref(deref) + var->buffer_offset; + if (data_type->type == HLSL_CLASS_OBJECT && data_type->base_type == HLSL_TYPE_TEXTURE) + { + reg->type = VKD3D_SM4_RT_RESOURCE; + reg->dim = VKD3D_SM4_DIMENSION_VEC4; + reg->idx[0] = var->reg.id; + reg->idx_count = 1; + *writemask = VKD3DSP_WRITEMASK_ALL; + } + else + { + unsigned int offset = hlsl_offset_from_deref(deref) + var->buffer_offset;
- reg->type = VKD3D_SM4_RT_CONSTBUFFER; - reg->dim = VKD3D_SM4_DIMENSION_VEC4; - reg->idx[0] = var->buffer->reg.id; - reg->idx[1] = offset / 4; - reg->idx_count = 2; - *writemask = ((1u << data_type->dimx) - 1) << (offset & 3); + assert(data_type->type <= HLSL_CLASS_VECTOR); + reg->type = VKD3D_SM4_RT_CONSTBUFFER; + reg->dim = VKD3D_SM4_DIMENSION_VEC4; + reg->idx[0] = var->buffer->reg.id; + reg->idx[1] = offset / 4; + reg->idx_count = 2; + *writemask = ((1u << data_type->dimx) - 1) << (offset & 3); + } } else if (var->is_input_semantic) { @@ -1154,6 +1167,50 @@ static void write_sm4_constant(struct hlsl_ctx *ctx, write_sm4_instruction(buffer, &instr); }
+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) +{ + struct sm4_instruction instr; + unsigned int writemask; + + memset(&instr, 0, sizeof(instr)); + instr.opcode = VKD3D_SM4_OP_LD; + + sm4_register_from_node(&instr.dsts[0].reg, &instr.dsts[0].writemask, dst); + instr.dst_count = 1; + + sm4_register_from_node(&instr.srcs[0].reg, &writemask, coords); + instr.srcs[0].swizzle = hlsl_swizzle_from_writemask(writemask); + + /* Mipmap level is in the last component in the IR, but needs to be in the W + * component in the instruction. */ + switch (resource_type->sampler_dim) + { + case HLSL_SAMPLER_DIM_1D: + instr.srcs[0].swizzle = hlsl_combine_swizzles(instr.srcs[0].swizzle, HLSL_SWIZZLE(X, X, X, Y), 4); + break; + + case HLSL_SAMPLER_DIM_2D: + instr.srcs[0].swizzle = hlsl_combine_swizzles(instr.srcs[0].swizzle, HLSL_SWIZZLE(X, Y, X, Z), 4); + break; + + case HLSL_SAMPLER_DIM_3D: + case HLSL_SAMPLER_DIM_CUBE: + break; + + case HLSL_SAMPLER_DIM_GENERIC: + assert(0); + } + + sm4_register_from_deref(ctx, &instr.srcs[1].reg, &writemask, resource, resource_type); + instr.srcs[1].swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), instr.dsts[0].writemask); + + instr.src_count = 2; + + write_sm4_instruction(buffer, &instr); +} + static void write_sm4_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_expr *expr) { @@ -1375,6 +1432,26 @@ static void write_sm4_load(struct hlsl_ctx *ctx, write_sm4_instruction(buffer, &instr); }
+static void write_sm4_resource_load(struct hlsl_ctx *ctx, + struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_resource_load *load) +{ + const struct hlsl_type *resource_type = load->resource.var->data_type; + const struct hlsl_ir_node *coords = load->coords.node; + + if (!load->resource.var->is_uniform) + { + hlsl_fixme(ctx, load->node.loc, "Load from non-uniform resource variable."); + return; + } + + switch (load->load_type) + { + case HLSL_RESOURCE_LOAD: + write_sm4_ld(ctx, buffer, resource_type, &load->node, &load->resource, coords); + break; + } +} + static void write_sm4_store(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_store *store) { @@ -1504,6 +1581,10 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx, write_sm4_load(ctx, &buffer, hlsl_ir_load(instr)); break;
+ case HLSL_IR_RESOURCE_LOAD: + write_sm4_resource_load(ctx, &buffer, hlsl_ir_resource_load(instr)); + break; + case HLSL_IR_STORE: write_sm4_store(ctx, &buffer, hlsl_ir_store(instr)); break;
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
On 02/11/21 01:43, Zebediah Figura wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl_sm4.c | 95 +++++++++++++++++++++++++++++++++--- 1 file changed, 88 insertions(+), 7 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index f8eb0a1ef..5ab7df5f9 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -763,6 +763,7 @@ static unsigned int sm4_swizzle_type(enum vkd3d_sm4_register_type type)
case VKD3D_SM4_RT_CONSTBUFFER: case VKD3D_SM4_RT_INPUT:
case VKD3D_SM4_RT_RESOURCE: case VKD3D_SM4_RT_TEMP: return VKD3D_SM4_SWIZZLE_VEC4;
@@ -779,14 +780,26 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r
if (var->is_uniform) {
unsigned int offset = hlsl_offset_from_deref(deref) + var->buffer_offset;
if (data_type->type == HLSL_CLASS_OBJECT && data_type->base_type == HLSL_TYPE_TEXTURE)
{
reg->type = VKD3D_SM4_RT_RESOURCE;
reg->dim = VKD3D_SM4_DIMENSION_VEC4;
reg->idx[0] = var->reg.id;
reg->idx_count = 1;
*writemask = VKD3DSP_WRITEMASK_ALL;
}
else
{
unsigned int offset = hlsl_offset_from_deref(deref) + var->buffer_offset;
reg->type = VKD3D_SM4_RT_CONSTBUFFER;
reg->dim = VKD3D_SM4_DIMENSION_VEC4;
reg->idx[0] = var->buffer->reg.id;
reg->idx[1] = offset / 4;
reg->idx_count = 2;
*writemask = ((1u << data_type->dimx) - 1) << (offset & 3);
assert(data_type->type <= HLSL_CLASS_VECTOR);
reg->type = VKD3D_SM4_RT_CONSTBUFFER;
reg->dim = VKD3D_SM4_DIMENSION_VEC4;
reg->idx[0] = var->buffer->reg.id;
reg->idx[1] = offset / 4;
reg->idx_count = 2;
*writemask = ((1u << data_type->dimx) - 1) << (offset & 3);
} } else if (var->is_input_semantic) {
@@ -1154,6 +1167,50 @@ static void write_sm4_constant(struct hlsl_ctx *ctx, write_sm4_instruction(buffer, &instr); }
+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)
+{
- struct sm4_instruction instr;
- unsigned int writemask;
- memset(&instr, 0, sizeof(instr));
- instr.opcode = VKD3D_SM4_OP_LD;
- sm4_register_from_node(&instr.dsts[0].reg, &instr.dsts[0].writemask, dst);
- instr.dst_count = 1;
- sm4_register_from_node(&instr.srcs[0].reg, &writemask, coords);
- instr.srcs[0].swizzle = hlsl_swizzle_from_writemask(writemask);
- /* Mipmap level is in the last component in the IR, but needs to be in the W
* component in the instruction. */
- switch (resource_type->sampler_dim)
- {
case HLSL_SAMPLER_DIM_1D:
instr.srcs[0].swizzle = hlsl_combine_swizzles(instr.srcs[0].swizzle, HLSL_SWIZZLE(X, X, X, Y), 4);
break;
case HLSL_SAMPLER_DIM_2D:
instr.srcs[0].swizzle = hlsl_combine_swizzles(instr.srcs[0].swizzle, HLSL_SWIZZLE(X, Y, X, Z), 4);
break;
case HLSL_SAMPLER_DIM_3D:
case HLSL_SAMPLER_DIM_CUBE:
break;
case HLSL_SAMPLER_DIM_GENERIC:
assert(0);
- }
- sm4_register_from_deref(ctx, &instr.srcs[1].reg, &writemask, resource, resource_type);
- instr.srcs[1].swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), instr.dsts[0].writemask);
- instr.src_count = 2;
- write_sm4_instruction(buffer, &instr);
+}
- static void write_sm4_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_expr *expr) {
@@ -1375,6 +1432,26 @@ static void write_sm4_load(struct hlsl_ctx *ctx, write_sm4_instruction(buffer, &instr); }
+static void write_sm4_resource_load(struct hlsl_ctx *ctx,
struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_resource_load *load)
+{
- const struct hlsl_type *resource_type = load->resource.var->data_type;
- const struct hlsl_ir_node *coords = load->coords.node;
- if (!load->resource.var->is_uniform)
- {
hlsl_fixme(ctx, load->node.loc, "Load from non-uniform resource variable.");
return;
- }
- switch (load->load_type)
- {
case HLSL_RESOURCE_LOAD:
write_sm4_ld(ctx, buffer, resource_type, &load->node, &load->resource, coords);
break;
- }
+}
- static void write_sm4_store(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_store *store) {
@@ -1504,6 +1581,10 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx, write_sm4_load(ctx, &buffer, hlsl_ir_load(instr)); break;
case HLSL_IR_RESOURCE_LOAD:
write_sm4_resource_load(ctx, &buffer, hlsl_ir_resource_load(instr));
break;
case HLSL_IR_STORE: write_sm4_store(ctx, &buffer, hlsl_ir_store(instr)); break;
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- Makefile.am | 2 + tests/sampler.shader_test | 34 ++++++++ tests/shader_runner_d3d12.c | 166 +++++++++++++++++++++++++++++++++--- 3 files changed, 191 insertions(+), 11 deletions(-) create mode 100644 tests/sampler.shader_test
diff --git a/Makefile.am b/Makefile.am index eaa4f8168..d6e14cf14 100644 --- a/Makefile.am +++ b/Makefile.am @@ -90,6 +90,7 @@ vkd3d_shader_tests = \ tests/preproc-invalid.shader_test \ tests/preproc-macro.shader_test \ tests/preproc-misc.shader_test \ + tests/sampler.shader_test \ tests/saturate.shader_test \ tests/swizzle-0.shader_test \ tests/swizzle-1.shader_test \ @@ -302,6 +303,7 @@ XFAIL_TESTS = \ tests/hlsl-vector-indexing-uniform.shader_test \ tests/math.shader_test \ tests/max.shader_test \ + tests/sampler.shader_test \ tests/texture-load.shader_test \ tests/texture-load-typed.shader_test \ tests/trigonometry.shader_test \ diff --git a/tests/sampler.shader_test b/tests/sampler.shader_test new file mode 100644 index 000000000..3970fb510 --- /dev/null +++ b/tests/sampler.shader_test @@ -0,0 +1,34 @@ +[sampler 0] +filter linear linear linear +address clamp clamp clamp + +[texture 0] +size (2, 2) +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 1.0 0.0 1.0 0.0 + +[pixel shader] +sampler s; +Texture2D t; + +float4 main() : sv_target +{ + return t.Sample(s, float2(0.5, 0.5)); +} + +[test] +draw quad +probe all rgba (0.25, 0, 0.25, 0) + +[pixel shader] +SamplerState s; +Texture2D t; + +float4 main() : sv_target +{ + return t.Sample(s, float2(0.5, 0.5)); +} + +[test] +draw quad +probe all rgba (0.25, 0, 0.25, 0) diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index e47083765..de5a12835 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -80,6 +80,14 @@ enum texture_data_type TEXTURE_DATA_UINT, };
+struct sampler +{ + unsigned int slot; + + D3D12_FILTER filter; + D3D12_TEXTURE_ADDRESS_MODE u_address, v_address, w_address; +}; + struct texture { unsigned int slot; @@ -108,6 +116,9 @@ struct shader_context
struct texture *textures; size_t texture_count; + + struct sampler *samplers; + size_t sampler_count; };
static ID3D10Blob *compile_shader(const char *source, const char *target) @@ -139,6 +150,7 @@ enum parse_state STATE_NONE, STATE_PREPROC, STATE_PREPROC_INVALID, + STATE_SAMPLER, STATE_SHADER_INVALID_PIXEL, STATE_SHADER_PIXEL, STATE_TEXTURE, @@ -195,6 +207,69 @@ static void parse_texture_format(struct texture *texture, const char *line) texture->texel_size = 16; }
+static D3D12_TEXTURE_ADDRESS_MODE parse_sampler_address_mode(const char *line, const char **rest) +{ + if (match_string(line, "border", rest)) + return D3D12_TEXTURE_ADDRESS_MODE_BORDER; + if (match_string(line, "clamp", rest)) + return D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + if (match_string(line, "mirror once", rest)) + return D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE; + if (match_string(line, "mirror", rest)) + return D3D12_TEXTURE_ADDRESS_MODE_MIRROR; + if (match_string(line, "wrap", rest)) + return D3D12_TEXTURE_ADDRESS_MODE_WRAP; + fprintf(stderr, "Malformed address mode '%s'.\n", line); + return D3D12_TEXTURE_ADDRESS_MODE_WRAP; +} + +static void parse_sampler_directive(struct sampler *sampler, const char *line) +{ + const char *const orig_line = line; + + if (match_string(line, "address", &line)) + { + sampler->u_address = parse_sampler_address_mode(line, &line); + sampler->v_address = parse_sampler_address_mode(line, &line); + sampler->w_address = parse_sampler_address_mode(line, &line); + } + else if (match_string(line, "filter", &line)) + { + static const struct + { + const char *string; + D3D12_FILTER filter; + } + filters[] = + { + {"point point point", D3D12_FILTER_MIN_MAG_MIP_POINT}, + {"point point linear", D3D12_FILTER_MIN_MAG_POINT_MIP_LINEAR}, + {"point linear point", D3D12_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT}, + {"point linear linear", D3D12_FILTER_MIN_POINT_MAG_MIP_LINEAR}, + {"linear point point", D3D12_FILTER_MIN_LINEAR_MAG_MIP_POINT}, + {"linear point linear", D3D12_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR}, + {"linear linear point", D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT}, + {"linear linear linear", D3D12_FILTER_MIN_MAG_MIP_LINEAR}, + }; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(filters); ++i) + { + if (match_string(line, filters[i].string, &line)) + sampler->filter = filters[i].filter; + } + } + else + { + goto err; + } + + return; + +err: + fprintf(stderr, "Ignoring malformed line '%s'.\n", orig_line); +} + static void parse_texture_directive(struct texture *texture, const char *line) { const char *const orig_line = line; @@ -266,6 +341,7 @@ static void parse_test_directive(struct shader_context *context, const char *lin ID3D12GraphicsCommandList *command_list = context->c.list; D3D12_ROOT_SIGNATURE_DESC root_signature_desc = {0}; D3D12_ROOT_PARAMETER root_params[3], *root_param; + D3D12_STATIC_SAMPLER_DESC static_samplers[1]; static const float clear_color[4]; unsigned int uniform_index; ID3D12PipelineState *pso; @@ -274,6 +350,8 @@ static void parse_test_directive(struct shader_context *context, const char *lin
root_signature_desc.NumParameters = 0; root_signature_desc.pParameters = root_params; + root_signature_desc.NumStaticSamplers = 0; + root_signature_desc.pStaticSamplers = static_samplers;
if (context->uniform_count) { @@ -305,21 +383,40 @@ static void parse_test_directive(struct shader_context *context, const char *lin range->RegisterSpace = 0; range->OffsetInDescriptorsFromTableStart = 0;
- texture->heap = create_gpu_descriptor_heap(context->c.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1); - texture->resource = create_default_texture(context->c.device, texture->width, texture->height, - texture->format, 0, D3D12_RESOURCE_STATE_COPY_DEST); - resource_data.pData = texture->data; - resource_data.SlicePitch = resource_data.RowPitch = texture->width * texture->texel_size; - upload_texture_data(texture->resource, &resource_data, 1, context->c.queue, command_list); - reset_command_list(command_list, context->c.allocator); - transition_resource_state(command_list, texture->resource, D3D12_RESOURCE_STATE_COPY_DEST, - D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); - ID3D12Device_CreateShaderResourceView(context->c.device, texture->resource, - NULL, get_cpu_descriptor_handle(&context->c, texture->heap, 0)); + if (!texture->resource) + { + texture->heap = create_gpu_descriptor_heap(context->c.device, + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1); + texture->resource = create_default_texture(context->c.device, texture->width, texture->height, + texture->format, 0, D3D12_RESOURCE_STATE_COPY_DEST); + resource_data.pData = texture->data; + resource_data.SlicePitch = resource_data.RowPitch = texture->width * texture->texel_size; + upload_texture_data(texture->resource, &resource_data, 1, context->c.queue, command_list); + reset_command_list(command_list, context->c.allocator); + transition_resource_state(command_list, texture->resource, D3D12_RESOURCE_STATE_COPY_DEST, + D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + ID3D12Device_CreateShaderResourceView(context->c.device, texture->resource, + NULL, get_cpu_descriptor_handle(&context->c, texture->heap, 0)); + } }
assert(root_signature_desc.NumParameters <= ARRAY_SIZE(root_params));
+ for (i = 0; i < context->sampler_count; ++i) + { + D3D12_STATIC_SAMPLER_DESC *sampler_desc = &static_samplers[root_signature_desc.NumStaticSamplers++]; + const struct sampler *sampler = &context->samplers[i]; + + memset(sampler_desc, 0, sizeof(*sampler_desc)); + sampler_desc->Filter = sampler->filter; + sampler_desc->AddressU = sampler->u_address; + sampler_desc->AddressV = sampler->v_address; + sampler_desc->AddressW = sampler->w_address; + sampler_desc->ShaderRegister = sampler->slot; + sampler_desc->RegisterSpace = 0; + sampler_desc->ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + } + if (context->c.root_signature) ID3D12RootSignature_Release(context->c.root_signature); hr = create_root_signature(context->c.device, &root_signature_desc, &context->c.root_signature); @@ -482,6 +579,22 @@ err: fprintf(stderr, "Ignoring malformed line '%s'.\n", orig_line); }
+static struct sampler *get_sampler(struct shader_context *context, unsigned int slot) +{ + struct sampler *sampler; + size_t i; + + for (i = 0; i < context->sampler_count; ++i) + { + sampler = &context->samplers[i]; + + if (sampler->slot == slot) + return sampler; + } + + return NULL; +} + static struct texture *get_texture(struct shader_context *context, unsigned int slot) { struct texture *texture; @@ -509,6 +622,7 @@ START_TEST(shader_runner_d3d12) size_t shader_source_size = 0, shader_source_len = 0; enum parse_state state = STATE_NONE; unsigned int i, line_number = 0; + struct sampler *current_sampler; struct texture *current_texture; struct shader_context context; const char *filename = NULL; @@ -555,6 +669,7 @@ START_TEST(shader_runner_d3d12) switch (state) { case STATE_NONE: + case STATE_SAMPLER: case STATE_TEST: case STATE_TEXTURE: break; @@ -650,11 +765,36 @@ START_TEST(shader_runner_d3d12) if (!strcmp(line, "[pixel shader]\n")) { state = STATE_SHADER_PIXEL; + + if (context.ps_code) + ID3D10Blob_Release(context.ps_code); + context.ps_code = NULL; } else if (!strcmp(line, "[pixel shader fail]\n")) { state = STATE_SHADER_INVALID_PIXEL; } + else if (sscanf(line, "[sampler %u]\n", &index)) + { + state = STATE_SAMPLER; + + if ((current_sampler = get_sampler(&context, index))) + { + memset(current_sampler, 0, sizeof(*current_sampler)); + } + else + { + context.samplers = realloc(context.samplers, + ++context.sampler_count * sizeof(*context.samplers)); + current_sampler = &context.samplers[context.sampler_count - 1]; + memset(current_sampler, 0, sizeof(*current_sampler)); + } + current_sampler->slot = index; + current_sampler->filter = D3D12_FILTER_MIN_MAG_MIP_POINT; + current_sampler->u_address = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + current_sampler->v_address = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + current_sampler->w_address = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + } else if (sscanf(line, "[texture %u]\n", &index)) { state = STATE_TEXTURE; @@ -711,6 +851,10 @@ START_TEST(shader_runner_d3d12) break; }
+ case STATE_SAMPLER: + parse_sampler_directive(current_sampler, line); + break; + case STATE_TEXTURE: parse_texture_directive(current_texture, line); break;
Hi,
On 02/11/21 01:43, Zebediah Figura wrote:
+static D3D12_TEXTURE_ADDRESS_MODE parse_sampler_address_mode(const char *line, const char **rest) +{
- if (match_string(line, "border", rest))
return D3D12_TEXTURE_ADDRESS_MODE_BORDER;
- if (match_string(line, "clamp", rest))
return D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
- if (match_string(line, "mirror once", rest))
return D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE;
- if (match_string(line, "mirror", rest))
return D3D12_TEXTURE_ADDRESS_MODE_MIRROR;
- if (match_string(line, "wrap", rest))
return D3D12_TEXTURE_ADDRESS_MODE_WRAP;
- fprintf(stderr, "Malformed address mode '%s'.\n", line);
- return D3D12_TEXTURE_ADDRESS_MODE_WRAP;
+}
I don't like very much the "mirror once" thing: the structure of the file hints that spaces are used for token separation, and here we would be using two tokens for an option that seems to be completely similar to the other options using just one token. Also, the hypothetical line "mirror_once mirror mirror_once" would be easier to mentally scan than "mirror once mirror mirror once". Can we change to "mirror_once"?
Also, the validation fundamentalist that is in me would happily swap the last return statement with a call to abort(), but I guess I can silence him for a test program.
+static void parse_sampler_directive(struct sampler *sampler, const char *line) +{
- const char *const orig_line = line;
- if (match_string(line, "address", &line))
- {
sampler->u_address = parse_sampler_address_mode(line, &line);
sampler->v_address = parse_sampler_address_mode(line, &line);
sampler->w_address = parse_sampler_address_mode(line, &line);
- }
- else if (match_string(line, "filter", &line))
- {
static const struct
{
const char *string;
D3D12_FILTER filter;
}
filters[] =
{
{"point point point", D3D12_FILTER_MIN_MAG_MIP_POINT},
{"point point linear", D3D12_FILTER_MIN_MAG_POINT_MIP_LINEAR},
{"point linear point", D3D12_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT},
{"point linear linear", D3D12_FILTER_MIN_POINT_MAG_MIP_LINEAR},
{"linear point point", D3D12_FILTER_MIN_LINEAR_MAG_MIP_POINT},
{"linear point linear", D3D12_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR},
{"linear linear point", D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT},
{"linear linear linear", D3D12_FILTER_MIN_MAG_MIP_LINEAR},
};
unsigned int i;
for (i = 0; i < ARRAY_SIZE(filters); ++i)
{
if (match_string(line, filters[i].string, &line))
sampler->filter = filters[i].filter;
}
- }
- else
- {
goto err;
- }
- return;
+err:
- fprintf(stderr, "Ignoring malformed line '%s'.\n", orig_line);
+}
I don't find the goto statement very useful: you could just print the error in the "else" branch. Unless you have plans to extend the function in ways I don't see now, I think this is just complicating the control flow.
@@ -305,21 +383,40 @@ static void parse_test_directive(struct shader_context *context, const char *lin range->RegisterSpace = 0; range->OffsetInDescriptorsFromTableStart = 0;
texture->heap = create_gpu_descriptor_heap(context->c.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
texture->resource = create_default_texture(context->c.device, texture->width, texture->height,
texture->format, 0, D3D12_RESOURCE_STATE_COPY_DEST);
resource_data.pData = texture->data;
resource_data.SlicePitch = resource_data.RowPitch = texture->width * texture->texel_size;
upload_texture_data(texture->resource, &resource_data, 1, context->c.queue, command_list);
reset_command_list(command_list, context->c.allocator);
transition_resource_state(command_list, texture->resource, D3D12_RESOURCE_STATE_COPY_DEST,
D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
ID3D12Device_CreateShaderResourceView(context->c.device, texture->resource,
NULL, get_cpu_descriptor_handle(&context->c, texture->heap, 0));
if (!texture->resource)
{
texture->heap = create_gpu_descriptor_heap(context->c.device,
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
texture->resource = create_default_texture(context->c.device, texture->width, texture->height,
texture->format, 0, D3D12_RESOURCE_STATE_COPY_DEST);
resource_data.pData = texture->data;
resource_data.SlicePitch = resource_data.RowPitch = texture->width * texture->texel_size;
upload_texture_data(texture->resource, &resource_data, 1, context->c.queue, command_list);
reset_command_list(command_list, context->c.allocator);
transition_resource_state(command_list, texture->resource, D3D12_RESOURCE_STATE_COPY_DEST,
D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
ID3D12Device_CreateShaderResourceView(context->c.device, texture->resource,
NULL, get_cpu_descriptor_handle(&context->c, texture->heap, 0));
}
Is this hunk related to the patch? AFAIU, it just prevents recreating the texture resource if it's already there, which is a good thing, but probably worthy of another patch.
@@ -650,11 +765,36 @@ START_TEST(shader_runner_d3d12) if (!strcmp(line, "[pixel shader]\n")) { state = STATE_SHADER_PIXEL;
if (context.ps_code)
ID3D10Blob_Release(context.ps_code);
context.ps_code = NULL; }
This hunk too seems unrelated to this patch.
Thanks, Giovanni.
On 11/2/21 08:46, Giovanni Mascellani wrote:
Hi,
On 02/11/21 01:43, Zebediah Figura wrote:
+static D3D12_TEXTURE_ADDRESS_MODE parse_sampler_address_mode(const char *line, const char **rest) +{ + if (match_string(line, "border", rest)) + return D3D12_TEXTURE_ADDRESS_MODE_BORDER; + if (match_string(line, "clamp", rest)) + return D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + if (match_string(line, "mirror once", rest)) + return D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE; + if (match_string(line, "mirror", rest)) + return D3D12_TEXTURE_ADDRESS_MODE_MIRROR; + if (match_string(line, "wrap", rest)) + return D3D12_TEXTURE_ADDRESS_MODE_WRAP; + fprintf(stderr, "Malformed address mode '%s'.\n", line); + return D3D12_TEXTURE_ADDRESS_MODE_WRAP; +}
I don't like very much the "mirror once" thing: the structure of the file hints that spaces are used for token separation, and here we would be using two tokens for an option that seems to be completely similar to the other options using just one token. Also, the hypothetical line "mirror_once mirror mirror_once" would be easier to mentally scan than "mirror once mirror mirror once". Can we change to "mirror_once"?
Sure, seems reasonable to me.
Also, the validation fundamentalist that is in me would happily swap the last return statement with a call to abort(), but I guess I can silence him for a test program.
It probably would be a good idea to fail more noisily in general, honestly. I'll send a follow-up patch.
+static void parse_sampler_directive(struct sampler *sampler, const char *line) +{ + const char *const orig_line = line;
+ if (match_string(line, "address", &line)) + { + sampler->u_address = parse_sampler_address_mode(line, &line); + sampler->v_address = parse_sampler_address_mode(line, &line); + sampler->w_address = parse_sampler_address_mode(line, &line); + } + else if (match_string(line, "filter", &line)) + { + static const struct + { + const char *string; + D3D12_FILTER filter; + } + filters[] = + { + {"point point point", D3D12_FILTER_MIN_MAG_MIP_POINT}, + {"point point linear", D3D12_FILTER_MIN_MAG_POINT_MIP_LINEAR}, + {"point linear point", D3D12_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT}, + {"point linear linear", D3D12_FILTER_MIN_POINT_MAG_MIP_LINEAR}, + {"linear point point", D3D12_FILTER_MIN_LINEAR_MAG_MIP_POINT}, + {"linear point linear", D3D12_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR}, + {"linear linear point", D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT}, + {"linear linear linear", D3D12_FILTER_MIN_MAG_MIP_LINEAR}, + }; + unsigned int i;
+ for (i = 0; i < ARRAY_SIZE(filters); ++i) + { + if (match_string(line, filters[i].string, &line)) + sampler->filter = filters[i].filter; + } + } + else + { + goto err; + }
+ return;
+err: + fprintf(stderr, "Ignoring malformed line '%s'.\n", orig_line); +}
I don't find the goto statement very useful: you could just print the error in the "else" branch. Unless you have plans to extend the function in ways I don't see now, I think this is just complicating the control flow.
Not for parse_sampler_directive() specifically, but in general yes.
But something like a fatal_error(...) function would also obviate the need for a goto.
@@ -305,21 +383,40 @@ static void parse_test_directive(struct shader_context *context, const char *lin range->RegisterSpace = 0; range->OffsetInDescriptorsFromTableStart = 0; - texture->heap = create_gpu_descriptor_heap(context->c.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1); - texture->resource = create_default_texture(context->c.device, texture->width, texture->height, - texture->format, 0, D3D12_RESOURCE_STATE_COPY_DEST); - resource_data.pData = texture->data; - resource_data.SlicePitch = resource_data.RowPitch = texture->width * texture->texel_size; - upload_texture_data(texture->resource, &resource_data, 1, context->c.queue, command_list); - reset_command_list(command_list, context->c.allocator); - transition_resource_state(command_list, texture->resource, D3D12_RESOURCE_STATE_COPY_DEST, - D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); - ID3D12Device_CreateShaderResourceView(context->c.device, texture->resource, - NULL, get_cpu_descriptor_handle(&context->c, texture->heap, 0)); + if (!texture->resource) + { + texture->heap = create_gpu_descriptor_heap(context->c.device, + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1); + texture->resource = create_default_texture(context->c.device, texture->width, texture->height, + texture->format, 0, D3D12_RESOURCE_STATE_COPY_DEST); + resource_data.pData = texture->data; + resource_data.SlicePitch = resource_data.RowPitch = texture->width * texture->texel_size; + upload_texture_data(texture->resource, &resource_data, 1, context->c.queue, command_list); + reset_command_list(command_list, context->c.allocator); + transition_resource_state(command_list, texture->resource, D3D12_RESOURCE_STATE_COPY_DEST,
D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
ID3D12Device_CreateShaderResourceView(context->c.device, texture->resource, + NULL, get_cpu_descriptor_handle(&context->c, texture->heap, 0)); + }
Is this hunk related to the patch? AFAIU, it just prevents recreating the texture resource if it's already there, which is a good thing, but probably worthy of another patch.
Mostly because this is the first shader_test file that includes more than one valid [test] directive. But yes, it could use a separate patch.
Same for the hunk quoted below.
@@ -650,11 +765,36 @@ START_TEST(shader_runner_d3d12) if (!strcmp(line, "[pixel shader]\n")) { state = STATE_SHADER_PIXEL;
+ if (context.ps_code) + ID3D10Blob_Release(context.ps_code); + context.ps_code = NULL; }
This hunk too seems unrelated to this patch.
Thanks, Giovanni.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.l | 1 + 1 file changed, 1 insertion(+)
diff --git a/libs/vkd3d-shader/hlsl.l b/libs/vkd3d-shader/hlsl.l index 762a8a026..caf8fe8f9 100644 --- a/libs/vkd3d-shader/hlsl.l +++ b/libs/vkd3d-shader/hlsl.l @@ -109,6 +109,7 @@ sampler3D {return KW_SAMPLER3D; } samplerCUBE {return KW_SAMPLERCUBE; } sampler_state {return KW_SAMPLER_STATE; } SamplerComparisonState {return KW_SAMPLERCOMPARISONSTATE;} +SamplerState {return KW_SAMPLER; } shared {return KW_SHARED; } stateblock {return KW_STATEBLOCK; } stateblock_state {return KW_STATEBLOCK_STATE; }
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
On 02/11/21 01:43, Zebediah Figura wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl.l | 1 + 1 file changed, 1 insertion(+)
diff --git a/libs/vkd3d-shader/hlsl.l b/libs/vkd3d-shader/hlsl.l index 762a8a026..caf8fe8f9 100644 --- a/libs/vkd3d-shader/hlsl.l +++ b/libs/vkd3d-shader/hlsl.l @@ -109,6 +109,7 @@ sampler3D {return KW_SAMPLER3D; } samplerCUBE {return KW_SAMPLERCUBE; } sampler_state {return KW_SAMPLER_STATE; } SamplerComparisonState {return KW_SAMPLERCOMPARISONSTATE;} +SamplerState {return KW_SAMPLER; } shared {return KW_SHARED; } stateblock {return KW_STATEBLOCK; } stateblock_state {return KW_STATEBLOCK_STATE; }
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 30 +++++++++++++++------ libs/vkd3d-shader/hlsl.h | 8 +++--- libs/vkd3d-shader/hlsl.y | 46 +++++++++++++++++++++++++++++++- libs/vkd3d-shader/hlsl_codegen.c | 8 ++++++ libs/vkd3d-shader/hlsl_sm4.c | 4 +++ 5 files changed, 84 insertions(+), 12 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index a72e0a18f..da4f10a9f 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -627,8 +627,9 @@ struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var }
struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, struct hlsl_type *data_type, - enum hlsl_resource_load_type type, struct hlsl_ir_var *resource, struct hlsl_ir_node *offset, - struct hlsl_ir_node *coords, const struct vkd3d_shader_location *loc) + enum hlsl_resource_load_type type, struct hlsl_ir_var *resource, struct hlsl_ir_node *resource_offset, + struct hlsl_ir_var *sampler, struct hlsl_ir_node *sampler_offset, struct hlsl_ir_node *coords, + const struct vkd3d_shader_location *loc) { struct hlsl_ir_resource_load *load;
@@ -637,7 +638,9 @@ struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, struc init_node(&load->node, HLSL_IR_RESOURCE_LOAD, data_type, *loc); load->load_type = type; load->resource.var = resource; - hlsl_src_from_node(&load->resource.offset, offset); + hlsl_src_from_node(&load->resource.offset, resource_offset); + load->sampler.var = sampler; + hlsl_src_from_node(&load->sampler.offset, sampler_offset); hlsl_src_from_node(&load->coords, coords); return load; } @@ -1059,12 +1062,19 @@ static void dump_ir_var(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer
static void dump_deref(struct vkd3d_string_buffer *buffer, const struct hlsl_deref *deref) { - vkd3d_string_buffer_printf(buffer, "%s", deref->var->name); - if (deref->offset.node) + if (deref->var) + { + vkd3d_string_buffer_printf(buffer, "%s", deref->var->name); + if (deref->offset.node) + { + vkd3d_string_buffer_printf(buffer, "["); + dump_src(buffer, &deref->offset); + vkd3d_string_buffer_printf(buffer, "]"); + } + } + else { - vkd3d_string_buffer_printf(buffer, "["); - dump_src(buffer, &deref->offset); - vkd3d_string_buffer_printf(buffer, "]"); + vkd3d_string_buffer_printf(buffer, "(nil)"); } }
@@ -1239,10 +1249,13 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru static const char *const type_names[] = { [HLSL_RESOURCE_LOAD] = "load_resource", + [HLSL_RESOURCE_SAMPLE] = "sample", };
vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[load->load_type]); dump_deref(buffer, &load->resource); + vkd3d_string_buffer_printf(buffer, ", sampler = "); + dump_deref(buffer, &load->sampler); vkd3d_string_buffer_printf(buffer, ", coords = "); dump_src(buffer, &load->coords); vkd3d_string_buffer_printf(buffer, ")"); @@ -1419,6 +1432,7 @@ static void free_ir_loop(struct hlsl_ir_loop *loop) static void free_ir_resource_load(struct hlsl_ir_resource_load *load) { hlsl_src_remove(&load->coords); + hlsl_src_remove(&load->sampler.offset); hlsl_src_remove(&load->resource.offset); vkd3d_free(load); } diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index a7503d5c8..eae962321 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -376,13 +376,14 @@ struct hlsl_ir_load enum hlsl_resource_load_type { HLSL_RESOURCE_LOAD, + HLSL_RESOURCE_SAMPLE, };
struct hlsl_ir_resource_load { struct hlsl_ir_node node; enum hlsl_resource_load_type load_type; - struct hlsl_deref resource; + struct hlsl_deref resource, sampler; struct hlsl_src coords; };
@@ -703,8 +704,9 @@ struct hlsl_ir_load *hlsl_new_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var struct hlsl_type *type, struct vkd3d_shader_location loc); struct hlsl_ir_loop *hlsl_new_loop(struct hlsl_ctx *ctx, struct vkd3d_shader_location loc); struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, struct hlsl_type *data_type, - enum hlsl_resource_load_type type, struct hlsl_ir_var *resource, struct hlsl_ir_node *offset, - struct hlsl_ir_node *coords, const struct vkd3d_shader_location *loc); + enum hlsl_resource_load_type type, struct hlsl_ir_var *resource, struct hlsl_ir_node *resource_offset, + struct hlsl_ir_var *sampler, struct hlsl_ir_node *sampler_offset, struct hlsl_ir_node *coords, + const struct vkd3d_shader_location *loc); struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs); struct hlsl_ir_store *hlsl_new_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, struct hlsl_ir_node *offset, struct hlsl_ir_node *rhs, unsigned int writemask, struct vkd3d_shader_location loc); diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index aae0ebcea..58dd0e349 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1803,7 +1803,51 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl return false;
if (!(load = hlsl_new_resource_load(ctx, object_type->e.resource_format, HLSL_RESOURCE_LOAD, - object_load->src.var, object_load->src.offset.node, coords, loc))) + object_load->src.var, object_load->src.offset.node, NULL, NULL, coords, loc))) + return false; + list_add_tail(instrs, &load->node.entry); + return true; + } + else if (!strcmp(name, "Sample")) + { + const unsigned int sampler_dim = sampler_dim_count(object_type->sampler_dim); + const struct hlsl_type *sampler_type; + struct hlsl_ir_resource_load *load; + struct hlsl_ir_load *sampler_load; + struct hlsl_ir_node *coords; + + if (params->args_count != 2 && params->args_count != 3) + { + hlsl_error(ctx, *loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Wrong number of arguments to method 'Sample': expected 2 or 3, but got %u.", params->args_count); + return false; + } + if (params->args_count == 3) + FIXME("Ignoring offset parameter.\n"); + + sampler_type = params->args[0]->data_type; + if (sampler_type->type != HLSL_CLASS_OBJECT || sampler_type->base_type != HLSL_TYPE_SAMPLER + || sampler_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, sampler_type))) + hlsl_error(ctx, *loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Wrong type for argument 0 of Sample(): expected 'sampler', but got '%s'.", string->buffer); + hlsl_release_string_buffer(ctx, string); + return false; + } + + /* Only HLSL_IR_LOAD can return an object. */ + sampler_load = hlsl_ir_load(params->args[0]); + + if (!(coords = add_implicit_conversion(ctx, instrs, params->args[1], + ctx->builtin_types.vector[HLSL_TYPE_FLOAT][sampler_dim - 1], loc))) + coords = params->args[1]; + + if (!(load = hlsl_new_resource_load(ctx, object_type->e.resource_format, + HLSL_RESOURCE_SAMPLE, object_load->src.var, object_load->src.offset.node, + sampler_load->src.var, sampler_load->src.offset.node, coords, loc))) return false; list_add_tail(instrs, &load->node.entry); return true; diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index df10ca272..24b8205c1 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -651,6 +651,14 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop var->last_read = max(var->last_read, var_last_read); if (load->resource.offset.node) load->resource.offset.node->last_read = instr->index; + + if ((var = load->sampler.var)) + { + var->last_read = max(var->last_read, var_last_read); + if (load->sampler.offset.node) + load->sampler.offset.node->last_read = instr->index; + } + load->coords.node->last_read = instr->index; break; } diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 5ab7df5f9..cef7d6b0f 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -1449,6 +1449,10 @@ 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); break; + + case HLSL_RESOURCE_SAMPLE: + hlsl_fixme(ctx, load->node.loc, "Resource sample instruction."); + break; } }
Hi,
On 02/11/21 01:43, Zebediah Figura wrote:
if (!(coords = add_implicit_conversion(ctx, instrs, params->args[1],
ctx->builtin_types.vector[HLSL_TYPE_FLOAT][sampler_dim - 1], loc)))
coords = params->args[1];
I would suggest to use the hlsl_get_vector_type helper.
Thanks, Giovanni.
On 11/2/21 09:04, Giovanni Mascellani wrote:
Hi,
On 02/11/21 01:43, Zebediah Figura wrote:
+ if (!(coords = add_implicit_conversion(ctx, instrs, params->args[1],
ctx->builtin_types.vector[HLSL_TYPE_FLOAT][sampler_dim - 1], loc))) + coords = params->args[1];
I would suggest to use the hlsl_get_vector_type helper.
Right, thanks. Most of these patches I've been submitting were written before that helper was...
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
On 02/11/21 01:43, Zebediah Figura wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl_sm4.c | 2 +- libs/vkd3d-shader/sm4.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 9d45e1633..f8eb0a1ef 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -561,7 +561,7 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) put_u32(&buffer, sm4_resource_format(var->data_type)); put_u32(&buffer, sm4_rdef_resource_dimension(var->data_type)); put_u32(&buffer, ~0u); /* FIXME: multisample count */
flags |= (var->data_type->e.resource_format->dimx - 1) << 2;
flags |= (var->data_type->e.resource_format->dimx - 1) << VKD3D_SM4_SIF_TEXTURE_COMPONENTS_SHIFT; } put_u32(&buffer, var->reg.id); put_u32(&buffer, 1); /* bind count */
diff --git a/libs/vkd3d-shader/sm4.h b/libs/vkd3d-shader/sm4.h index ddcb9a861..17a08ee27 100644 --- a/libs/vkd3d-shader/sm4.h +++ b/libs/vkd3d-shader/sm4.h @@ -526,4 +526,7 @@ enum vkd3d_sm4_shader_data_type VKD3D_SM4_SHADER_DATA_MESSAGE = 0x4, };
+/* The shift that corresponds to the D3D_SIF_TEXTURE_COMPONENTS mask. */ +#define VKD3D_SM4_SIF_TEXTURE_COMPONENTS_SHIFT 2
- #endif /* __VKD3D_SM4_H */