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 22:31, 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 --- tests/shader_runner_d3d12.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-)
diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index e47083765..a17a171ef 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -305,17 +305,21 @@ 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)); @@ -650,6 +654,10 @@ 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")) {
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
On 02/11/21 22:31, Zebediah Figura wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
tests/shader_runner_d3d12.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-)
diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index e47083765..a17a171ef 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -305,17 +305,21 @@ 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));
@@ -650,6 +654,10 @@ 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")) {
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- Makefile.am | 2 + tests/sampler.shader_test | 34 +++++++++ tests/shader_runner_d3d12.c | 136 ++++++++++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+) 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 a17a171ef..d52382978 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) { @@ -324,6 +402,21 @@ static void parse_test_directive(struct shader_context *context, const char *lin
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); @@ -486,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; @@ -513,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; @@ -559,6 +669,7 @@ START_TEST(shader_runner_d3d12) switch (state) { case STATE_NONE: + case STATE_SAMPLER: case STATE_TEST: case STATE_TEXTURE: break; @@ -663,6 +774,27 @@ START_TEST(shader_runner_d3d12) { 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; @@ -719,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;
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
On 02/11/21 22:31, Zebediah Figura wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Makefile.am | 2 + tests/sampler.shader_test | 34 +++++++++ tests/shader_runner_d3d12.c | 136 ++++++++++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+) 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 a17a171ef..d52382978 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) {
@@ -324,6 +402,21 @@ static void parse_test_directive(struct shader_context *context, const char *lin
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);
@@ -486,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;
@@ -513,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;
@@ -559,6 +669,7 @@ START_TEST(shader_runner_d3d12) switch (state) { case STATE_NONE:
case STATE_SAMPLER: case STATE_TEST: case STATE_TEXTURE: break;
@@ -663,6 +774,27 @@ START_TEST(shader_runner_d3d12) { 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;
@@ -719,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;
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- include/private/vkd3d_common.h | 2 + tests/shader_runner_d3d12.c | 70 +++++++++++++++------------------- 2 files changed, 33 insertions(+), 39 deletions(-)
diff --git a/include/private/vkd3d_common.h b/include/private/vkd3d_common.h index 18cc3cab2..482cabf96 100644 --- a/include/private/vkd3d_common.h +++ b/include/private/vkd3d_common.h @@ -48,6 +48,7 @@ static inline size_t align(size_t addr, size_t alignment) }
#ifdef __GNUC__ +# define VKD3D_NORETURN __attribute__((noreturn)) # if defined(__MINGW32__) && (defined(_UCRT) || __USE_MINGW_ANSI_STDIO) # define VKD3D_PRINTF_FUNC(fmt, args) __attribute__((format(gnu_printf, fmt, args))) # else @@ -55,6 +56,7 @@ static inline size_t align(size_t addr, size_t alignment) # endif # define VKD3D_UNUSED __attribute__((unused)) #else +# define VKD3D_NORETURN # define VKD3D_PRINTF_FUNC(fmt, args) # define VKD3D_UNUSED #endif /* __GNUC__ */ diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index d52382978..169271242 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -45,6 +45,16 @@ #include "d3d12_crosstest.h" #include <errno.h>
+static void VKD3D_NORETURN VKD3D_PRINTF_FUNC(1, 2) fatal_error(const char *format, ...) +{ + va_list args; + + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + exit(1); +} + static bool vkd3d_array_reserve(void **elements, size_t *capacity, size_t element_count, size_t element_size) { size_t new_capacity, max_capacity; @@ -201,10 +211,7 @@ static void parse_texture_format(struct texture *texture, const char *line) } }
- fprintf(stderr, "Unknown format '%s'.\n", line); - texture->format = DXGI_FORMAT_R32G32B32A32_FLOAT; - texture->data_type = TEXTURE_DATA_FLOAT; - texture->texel_size = 16; + fatal_error("Unknown format '%s'.\n", line); }
static D3D12_TEXTURE_ADDRESS_MODE parse_sampler_address_mode(const char *line, const char **rest) @@ -219,14 +226,12 @@ static D3D12_TEXTURE_ADDRESS_MODE parse_sampler_address_mode(const char *line, c 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; + + fatal_error("Unknown sampler address mode '%s'.\n", line); }
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); @@ -256,23 +261,22 @@ static void parse_sampler_directive(struct sampler *sampler, const char *line) for (i = 0; i < ARRAY_SIZE(filters); ++i) { if (match_string(line, filters[i].string, &line)) + { sampler->filter = filters[i].filter; + return; + } } + + fatal_error("Unknown sampler filter '%s'.\n", line); } else { - goto err; + fatal_error("Unknown sampler directive '%s'.\n", line); } - - 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; int ret;
if (match_string(line, "format", &line)) @@ -283,7 +287,7 @@ static void parse_texture_directive(struct texture *texture, const char *line) { ret = sscanf(line, "( %u , %u )", &texture->width, &texture->height); if (ret < 2) - goto err; + fatal_error("Malformed texture size '%s'.\n", line); } else { @@ -323,17 +327,10 @@ static void parse_texture_directive(struct texture *texture, const char *line) line = rest; } } - - return; - -err: - fprintf(stderr, "Ignoring malformed line '%s'.\n", orig_line); }
static void parse_test_directive(struct shader_context *context, const char *line) { - const char *const orig_line = line; - if (match_string(line, "draw quad", &line)) { D3D12_SHADER_BYTECODE ps @@ -454,7 +451,7 @@ static void parse_test_directive(struct shader_context *context, const char *lin
ret = sscanf(line, "( %f , %f , %f , %f ) %u", &v.x, &v.y, &v.z, &v.w, &ulps); if (ret < 4) - goto err; + fatal_error("Malformed probe arguments '%s'.\n", line); if (ret < 5) ulps = 0; check_sub_resource_vec4(context->c.render_target, 0, context->c.queue, context->c.list, &v, ulps); @@ -471,7 +468,7 @@ static void parse_test_directive(struct shader_context *context, const char *lin ret = sscanf(line, "( %u , %u , %u , %u ) ( %f , %f , %f , %f ) %u", &x, &y, &w, &h, &v.x, &v.y, &v.z, &v.w, &ulps); if (ret < 8) - goto err; + fatal_error("Malformed probe arguments '%s'.\n", line); if (ret < 9) ulps = 0;
@@ -494,7 +491,7 @@ static void parse_test_directive(struct shader_context *context, const char *lin
ret = sscanf(line, "( %u , %u ) ( %f , %f , %f , %f ) %u", &x, &y, &v.x, &v.y, &v.z, &v.w, &ulps); if (ret < 6) - goto err; + fatal_error("Malformed probe arguments '%s'.\n", line); if (ret < 7) ulps = 0;
@@ -512,7 +509,7 @@ static void parse_test_directive(struct shader_context *context, const char *lin unsigned int offset;
if (!sscanf(line, "%u", &offset)) - goto err; + fatal_error("Unknown uniform type '%s'.\n", line); line = strchr(line, ' ') + 1;
if (match_string(line, "float4", &line)) @@ -520,7 +517,7 @@ static void parse_test_directive(struct shader_context *context, const char *lin struct vec4 v;
if (sscanf(line, "%f %f %f %f", &v.x, &v.y, &v.z, &v.w) < 4) - goto err; + fatal_error("Malformed float4 constant '%s'.\n", line); if (offset + 4 > context->uniform_count) { context->uniform_count = offset + 4; @@ -533,7 +530,7 @@ static void parse_test_directive(struct shader_context *context, const char *lin float f;
if (sscanf(line, "%f", &f) < 1) - goto err; + fatal_error("Malformed float constant '%s'.\n", line); if (offset + 1 > context->uniform_count) { context->uniform_count = offset + 1; @@ -546,7 +543,7 @@ static void parse_test_directive(struct shader_context *context, const char *lin int i;
if (sscanf(line, "%i", &i) < 1) - goto err; + fatal_error("Malformed int constant '%s'.\n", line); if (offset + 1 > context->uniform_count) { context->uniform_count = offset + 1; @@ -559,7 +556,7 @@ static void parse_test_directive(struct shader_context *context, const char *lin unsigned int u;
if (sscanf(line, "%u", &u) < 1) - goto err; + fatal_error("Malformed uint constant '%s'.\n", line); if (offset + 1 > context->uniform_count) { context->uniform_count = offset + 1; @@ -570,13 +567,8 @@ static void parse_test_directive(struct shader_context *context, const char *lin } else { - goto err; + fatal_error("Unknown test directive '%s'.\n", line); } - - return; - -err: - fprintf(stderr, "Ignoring malformed line '%s'.\n", orig_line); }
static struct sampler *get_sampler(struct shader_context *context, unsigned int slot) @@ -651,7 +643,7 @@ START_TEST(shader_runner_d3d12)
if (!(f = fopen(filename, "r"))) { - fprintf(stderr, "Unable to open '%s' for reading: %s\n", argv[1], strerror(errno)); + fatal_error("Unable to open '%s' for reading: %s\n", argv[1], strerror(errno)); return; }
@@ -835,7 +827,7 @@ START_TEST(shader_runner_d3d12) switch (state) { case STATE_NONE: - fprintf(stderr, "Ignoring line '%s' in %s.\n", line, argv[1]); + fatal_error("Malformed line '%s'.\n", line); break;
case STATE_PREPROC:
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- The first hunk conflicts with current master, but it's easy to fix.
On 02/11/21 22:31, Zebediah Figura wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
include/private/vkd3d_common.h | 2 + tests/shader_runner_d3d12.c | 70 +++++++++++++++------------------- 2 files changed, 33 insertions(+), 39 deletions(-)
diff --git a/include/private/vkd3d_common.h b/include/private/vkd3d_common.h index 18cc3cab2..482cabf96 100644 --- a/include/private/vkd3d_common.h +++ b/include/private/vkd3d_common.h @@ -48,6 +48,7 @@ static inline size_t align(size_t addr, size_t alignment) }
#ifdef __GNUC__ +# define VKD3D_NORETURN __attribute__((noreturn)) # if defined(__MINGW32__) && (defined(_UCRT) || __USE_MINGW_ANSI_STDIO) # define VKD3D_PRINTF_FUNC(fmt, args) __attribute__((format(gnu_printf, fmt, args))) # else @@ -55,6 +56,7 @@ static inline size_t align(size_t addr, size_t alignment) # endif # define VKD3D_UNUSED __attribute__((unused)) #else +# define VKD3D_NORETURN # define VKD3D_PRINTF_FUNC(fmt, args) # define VKD3D_UNUSED #endif /* __GNUC__ */ diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index d52382978..169271242 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -45,6 +45,16 @@ #include "d3d12_crosstest.h" #include <errno.h>
+static void VKD3D_NORETURN VKD3D_PRINTF_FUNC(1, 2) fatal_error(const char *format, ...) +{
- va_list args;
- va_start(args, format);
- vfprintf(stderr, format, args);
- va_end(args);
- exit(1);
+}
- static bool vkd3d_array_reserve(void **elements, size_t *capacity, size_t element_count, size_t element_size) { size_t new_capacity, max_capacity;
@@ -201,10 +211,7 @@ static void parse_texture_format(struct texture *texture, const char *line) } }
- fprintf(stderr, "Unknown format '%s'.\n", line);
- texture->format = DXGI_FORMAT_R32G32B32A32_FLOAT;
- texture->data_type = TEXTURE_DATA_FLOAT;
- texture->texel_size = 16;
fatal_error("Unknown format '%s'.\n", line); }
static D3D12_TEXTURE_ADDRESS_MODE parse_sampler_address_mode(const char *line, const char **rest)
@@ -219,14 +226,12 @@ static D3D12_TEXTURE_ADDRESS_MODE parse_sampler_address_mode(const char *line, c 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;
fatal_error("Unknown sampler address mode '%s'.\n", line); }
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);
@@ -256,23 +261,22 @@ static void parse_sampler_directive(struct sampler *sampler, const char *line) for (i = 0; i < ARRAY_SIZE(filters); ++i) { if (match_string(line, filters[i].string, &line))
{ sampler->filter = filters[i].filter;
return;
} }
fatal_error("Unknown sampler filter '%s'.\n", line); } else {
goto err;
fatal_error("Unknown sampler directive '%s'.\n", line); }
- 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; int ret;
if (match_string(line, "format", &line))
@@ -283,7 +287,7 @@ static void parse_texture_directive(struct texture *texture, const char *line) { ret = sscanf(line, "( %u , %u )", &texture->width, &texture->height); if (ret < 2)
goto err;
fatal_error("Malformed texture size '%s'.\n", line); } else {
@@ -323,17 +327,10 @@ static void parse_texture_directive(struct texture *texture, const char *line) line = rest; } }
- return;
-err:
fprintf(stderr, "Ignoring malformed line '%s'.\n", orig_line); }
static void parse_test_directive(struct shader_context *context, const char *line) {
const char *const orig_line = line;
if (match_string(line, "draw quad", &line)) { D3D12_SHADER_BYTECODE ps
@@ -454,7 +451,7 @@ static void parse_test_directive(struct shader_context *context, const char *lin
ret = sscanf(line, "( %f , %f , %f , %f ) %u", &v.x, &v.y, &v.z, &v.w, &ulps); if (ret < 4)
goto err;
fatal_error("Malformed probe arguments '%s'.\n", line); if (ret < 5) ulps = 0; check_sub_resource_vec4(context->c.render_target, 0, context->c.queue, context->c.list, &v, ulps);
@@ -471,7 +468,7 @@ static void parse_test_directive(struct shader_context *context, const char *lin ret = sscanf(line, "( %u , %u , %u , %u ) ( %f , %f , %f , %f ) %u", &x, &y, &w, &h, &v.x, &v.y, &v.z, &v.w, &ulps); if (ret < 8)
goto err;
fatal_error("Malformed probe arguments '%s'.\n", line); if (ret < 9) ulps = 0;
@@ -494,7 +491,7 @@ static void parse_test_directive(struct shader_context *context, const char *lin
ret = sscanf(line, "( %u , %u ) ( %f , %f , %f , %f ) %u", &x, &y, &v.x, &v.y, &v.z, &v.w, &ulps); if (ret < 6)
goto err;
fatal_error("Malformed probe arguments '%s'.\n", line); if (ret < 7) ulps = 0;
@@ -512,7 +509,7 @@ static void parse_test_directive(struct shader_context *context, const char *lin unsigned int offset;
if (!sscanf(line, "%u", &offset))
goto err;
fatal_error("Unknown uniform type '%s'.\n", line); line = strchr(line, ' ') + 1; if (match_string(line, "float4", &line))
@@ -520,7 +517,7 @@ static void parse_test_directive(struct shader_context *context, const char *lin struct vec4 v;
if (sscanf(line, "%f %f %f %f", &v.x, &v.y, &v.z, &v.w) < 4)
goto err;
fatal_error("Malformed float4 constant '%s'.\n", line); if (offset + 4 > context->uniform_count) { context->uniform_count = offset + 4;
@@ -533,7 +530,7 @@ static void parse_test_directive(struct shader_context *context, const char *lin float f;
if (sscanf(line, "%f", &f) < 1)
goto err;
fatal_error("Malformed float constant '%s'.\n", line); if (offset + 1 > context->uniform_count) { context->uniform_count = offset + 1;
@@ -546,7 +543,7 @@ static void parse_test_directive(struct shader_context *context, const char *lin int i;
if (sscanf(line, "%i", &i) < 1)
goto err;
fatal_error("Malformed int constant '%s'.\n", line); if (offset + 1 > context->uniform_count) { context->uniform_count = offset + 1;
@@ -559,7 +556,7 @@ static void parse_test_directive(struct shader_context *context, const char *lin unsigned int u;
if (sscanf(line, "%u", &u) < 1)
goto err;
fatal_error("Malformed uint constant '%s'.\n", line); if (offset + 1 > context->uniform_count) { context->uniform_count = offset + 1;
@@ -570,13 +567,8 @@ static void parse_test_directive(struct shader_context *context, const char *lin } else {
goto err;
fatal_error("Unknown test directive '%s'.\n", line); }
- return;
-err:
fprintf(stderr, "Ignoring malformed line '%s'.\n", orig_line); }
static struct sampler *get_sampler(struct shader_context *context, unsigned int slot)
@@ -651,7 +643,7 @@ START_TEST(shader_runner_d3d12)
if (!(f = fopen(filename, "r"))) {
fprintf(stderr, "Unable to open '%s' for reading: %s\n", argv[1], strerror(errno));
fatal_error("Unable to open '%s' for reading: %s\n", argv[1], strerror(errno)); return; }
@@ -835,7 +827,7 @@ START_TEST(shader_runner_d3d12) switch (state) { case STATE_NONE:
fprintf(stderr, "Ignoring line '%s' in %s.\n", line, argv[1]);
fatal_error("Malformed line '%s'.\n", line); break; case STATE_PREPROC:
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 22:31, 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..3d0a9ceda 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], + hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), 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; } }
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
On 02/11/21 22:31, Zebediah Figura wrote:
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,
{ struct hlsl_ir_resource_load *load;const struct vkd3d_shader_location *loc)
@@ -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,
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);const struct vkd3d_shader_location *loc);
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index aae0ebcea..3d0a9ceda 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],
hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), 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; }
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- Rebased onto the series beginning with 218669, with which some of these patches conflicted, but not otherwise modified.
libs/vkd3d-shader/hlsl_sm4.c | 105 +++++++++++++++++++---------------- 1 file changed, 56 insertions(+), 49 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index cef7d6b0f..b6cb96775 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -1503,13 +1503,67 @@ static void write_sm4_swizzle(struct hlsl_ctx *ctx, write_sm4_instruction(buffer, &instr); }
+static void write_sm4_block(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, + const struct hlsl_block *block) +{ + const struct hlsl_ir_node *instr; + + LIST_FOR_EACH_ENTRY(instr, &block->instrs, struct hlsl_ir_node, entry) + { + if (instr->data_type) + { + if (instr->data_type->type == HLSL_CLASS_MATRIX) + { + FIXME("Matrix operations need to be lowered.\n"); + break; + } + else if (instr->data_type->type == HLSL_CLASS_OBJECT) + { + hlsl_fixme(ctx, instr->loc, "Object copy.\n"); + break; + } + + assert(instr->data_type->type == HLSL_CLASS_SCALAR || instr->data_type->type == HLSL_CLASS_VECTOR); + } + + switch (instr->type) + { + case HLSL_IR_CONSTANT: + write_sm4_constant(ctx, buffer, hlsl_ir_constant(instr)); + break; + + case HLSL_IR_EXPR: + write_sm4_expr(ctx, buffer, hlsl_ir_expr(instr)); + break; + + case HLSL_IR_LOAD: + 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; + + case HLSL_IR_SWIZZLE: + write_sm4_swizzle(ctx, buffer, hlsl_ir_swizzle(instr)); + break; + + default: + FIXME("Unhandled instruction type %s.\n", hlsl_node_type_to_string(instr->type)); + } + } +} + static void write_sm4_shdr(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *entry_func, struct dxbc_writer *dxbc) { const struct hlsl_profile_info *profile = ctx->profile; struct vkd3d_bytecode_buffer buffer = {0}; const struct hlsl_buffer *cbuffer; - const struct hlsl_ir_node *instr; const struct hlsl_ir_var *var; size_t token_count_position;
@@ -1553,54 +1607,7 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx, if (ctx->temp_count) write_sm4_dcl_temps(&buffer, ctx->temp_count);
- LIST_FOR_EACH_ENTRY(instr, &entry_func->body.instrs, struct hlsl_ir_node, entry) - { - if (instr->data_type) - { - if (instr->data_type->type == HLSL_CLASS_MATRIX) - { - FIXME("Matrix operations need to be lowered.\n"); - break; - } - else if (instr->data_type->type == HLSL_CLASS_OBJECT) - { - hlsl_fixme(ctx, instr->loc, "Object copy.\n"); - break; - } - - assert(instr->data_type->type == HLSL_CLASS_SCALAR || instr->data_type->type == HLSL_CLASS_VECTOR); - } - - switch (instr->type) - { - case HLSL_IR_CONSTANT: - write_sm4_constant(ctx, &buffer, hlsl_ir_constant(instr)); - break; - - case HLSL_IR_EXPR: - write_sm4_expr(ctx, &buffer, hlsl_ir_expr(instr)); - break; - - case HLSL_IR_LOAD: - 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; - - case HLSL_IR_SWIZZLE: - write_sm4_swizzle(ctx, &buffer, hlsl_ir_swizzle(instr)); - break; - - default: - FIXME("Unhandled instruction type %s.\n", hlsl_node_type_to_string(instr->type)); - } - } + write_sm4_block(ctx, &buffer, &entry_func->body);
write_sm4_ret(&buffer);
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl_sm4.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index b6cb96775..9d4319b6f 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -23,6 +23,8 @@ #include "vkd3d_d3dcommon.h" #include "sm4.h"
+static void write_sm4_block(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_block *block); + bool hlsl_sm4_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic, bool output, enum vkd3d_sm4_register_type *type, bool *has_idx) { @@ -1432,6 +1434,22 @@ static void write_sm4_load(struct hlsl_ctx *ctx, write_sm4_instruction(buffer, &instr); }
+static void write_sm4_loop(struct hlsl_ctx *ctx, + struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_loop *loop) +{ + struct sm4_instruction instr = + { + .opcode = VKD3D_SM4_OP_LOOP, + }; + + write_sm4_instruction(buffer, &instr); + + write_sm4_block(ctx, buffer, &loop->body); + + instr.opcode = VKD3D_SM4_OP_ENDLOOP; + 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) { @@ -1544,6 +1562,10 @@ static void write_sm4_block(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer * write_sm4_resource_load(ctx, buffer, hlsl_ir_resource_load(instr)); break;
+ case HLSL_IR_LOOP: + write_sm4_loop(ctx, buffer, hlsl_ir_loop(instr)); + break; + case HLSL_IR_STORE: write_sm4_store(ctx, buffer, hlsl_ir_store(instr)); break;
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl_sm4.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 9d4319b6f..d48a41d11 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -1415,6 +1415,33 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, } }
+static void write_sm4_if(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_if *iff) +{ + struct sm4_instruction instr = + { + .opcode = VKD3D_SM4_OP_IF | VKD3D_SM4_CONDITIONAL_NZ, + .src_count = 1, + }; + unsigned int writemask; + + assert(iff->condition.node->data_type->dimx == 1); + + sm4_register_from_node(&instr.srcs[0].reg, &writemask, iff->condition.node); + instr.srcs[0].swizzle = hlsl_swizzle_from_writemask(writemask); + write_sm4_instruction(buffer, &instr); + + write_sm4_block(ctx, buffer, &iff->then_instrs); + + instr.opcode = VKD3D_SM4_OP_ELSE; + instr.src_count = 0; + write_sm4_instruction(buffer, &instr); + + write_sm4_block(ctx, buffer, &iff->else_instrs); + + instr.opcode = VKD3D_SM4_OP_ENDIF; + write_sm4_instruction(buffer, &instr); +} + static void write_sm4_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_load *load) { @@ -1554,6 +1581,10 @@ static void write_sm4_block(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer * write_sm4_expr(ctx, buffer, hlsl_ir_expr(instr)); break;
+ case HLSL_IR_IF: + write_sm4_if(ctx, buffer, hlsl_ir_if(instr)); + break; + case HLSL_IR_LOAD: write_sm4_load(ctx, buffer, hlsl_ir_load(instr)); break;
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index da4f10a9f..c71eac3f1 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1208,11 +1208,11 @@ static void dump_ir_if(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, { vkd3d_string_buffer_printf(buffer, "if ("); dump_src(buffer, &if_node->condition); - vkd3d_string_buffer_printf(buffer, ")\n{\n"); + vkd3d_string_buffer_printf(buffer, ") {\n"); dump_instr_list(ctx, buffer, &if_node->then_instrs.instrs); - vkd3d_string_buffer_printf(buffer, "}\nelse\n{\n"); + vkd3d_string_buffer_printf(buffer, " %10s } else {\n", ""); dump_instr_list(ctx, buffer, &if_node->else_instrs.instrs); - vkd3d_string_buffer_printf(buffer, "}\n"); + vkd3d_string_buffer_printf(buffer, " %10s }", ""); }
static void dump_ir_jump(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_jump *jump) @@ -1239,9 +1239,9 @@ static void dump_ir_jump(struct vkd3d_string_buffer *buffer, const struct hlsl_i
static void dump_ir_loop(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, const struct hlsl_ir_loop *loop) { - vkd3d_string_buffer_printf(buffer, "for (;;)\n{\n"); + vkd3d_string_buffer_printf(buffer, "for (;;) {\n"); dump_instr_list(ctx, buffer, &loop->body.instrs); - vkd3d_string_buffer_printf(buffer, "}\n"); + vkd3d_string_buffer_printf(buffer, " %10s }", ""); }
static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_resource_load *load)
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.y | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 3d0a9ceda..2120b26fc 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2190,7 +2190,7 @@ struct_declaration: "Anonymous struct type must declare a variable."); if (modifiers) hlsl_error(ctx, @1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, - "Modifiers are not allowed on struct type declataions."); + "Modifiers are not allowed on struct type declarations."); }
if (!(type = apply_type_modifiers(ctx, $2, &modifiers, @1)))
From: Joshua Ashton joshua@froggi.es
Signed-off-by: Joshua Ashton joshua@froggi.es Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index c71eac3f1..42ea7b385 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -915,7 +915,7 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru
case HLSL_CLASS_OBJECT: { - static const char dimensions[5][HLSL_SAMPLER_DIM_MAX + 1] = + static const char dimensions[HLSL_SAMPLER_DIM_MAX + 1][5] = { [HLSL_SAMPLER_DIM_1D] = "1D", [HLSL_SAMPLER_DIM_2D] = "2D",
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
On 02/11/21 22:31, 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 */