From: Nikolay Sivov nsivov@codeweavers.com
--- libs/vkd3d-shader/hlsl.y | 68 ++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 24 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 86f23665..0ee5caba 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -3721,6 +3721,18 @@ static unsigned int hlsl_offset_dim_count(enum hlsl_sampler_dim dim) } }
+static bool raise_invalid_method_object_type(struct hlsl_ctx *ctx, const struct hlsl_type *object_type, + const char *method, const struct vkd3d_shader_location *loc) +{ + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, object_type))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, + "Method '%s' is not defined on type '%s'.", method, string->buffer); + hlsl_release_string_buffer(ctx, string); + return false; +} + static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -3731,6 +3743,12 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, stru struct hlsl_ir_node *load; bool multisampled;
+ if (object_type->sampler_dim == HLSL_SAMPLER_DIM_CUBE + || object_type->sampler_dim == HLSL_SAMPLER_DIM_CUBEARRAY) + { + return raise_invalid_method_object_type(ctx, object_type, name, loc); + } + multisampled = object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY;
@@ -3782,6 +3800,12 @@ static bool add_sample_method_call(struct hlsl_ctx *ctx, struct list *instrs, st const struct hlsl_type *sampler_type; struct hlsl_ir_node *load;
+ if (object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS + || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY) + { + return raise_invalid_method_object_type(ctx, object_type, name, loc); + } + if (params->args_count < 2 || params->args_count > 4 + !!offset_dim) { hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, @@ -3841,6 +3865,14 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct list *instrs, st struct hlsl_ir_node *load; unsigned int read_channel;
+ if (object_type->sampler_dim != HLSL_SAMPLER_DIM_2D + && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DARRAY + && object_type->sampler_dim != HLSL_SAMPLER_DIM_CUBE + && object_type->sampler_dim != HLSL_SAMPLER_DIM_CUBEARRAY) + { + return raise_invalid_method_object_type(ctx, object_type, name, loc); + } + if (!strcmp(name, "GatherGreen")) { load_params.type = HLSL_RESOURCE_GATHER_GREEN; @@ -3938,6 +3970,12 @@ static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct list *instrs const struct hlsl_type *sampler_type; struct hlsl_ir_node *load;
+ if (object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS + || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY) + { + return raise_invalid_method_object_type(ctx, object_type, name, loc); + } + if (!strcmp(name, "SampleLevel")) load_params.type = HLSL_RESOURCE_SAMPLE_LOD; else @@ -4009,48 +4047,30 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl return false; }
- if (!strcmp(name, "Load") - && object_type->sampler_dim != HLSL_SAMPLER_DIM_CUBE - && object_type->sampler_dim != HLSL_SAMPLER_DIM_CUBEARRAY) + if (!strcmp(name, "Load")) { return add_load_method_call(ctx, instrs, object, name, params, loc); } - else if (!strcmp(name, "Sample") - && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMS - && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) + else if (!strcmp(name, "Sample")) { return add_sample_method_call(ctx, instrs, object, name, params, loc); } else if ((!strcmp(name, "Gather") || !strcmp(name, "GatherRed") || !strcmp(name, "GatherBlue") - || !strcmp(name, "GatherGreen") || !strcmp(name, "GatherAlpha")) - && (object_type->sampler_dim == HLSL_SAMPLER_DIM_2D - || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DARRAY - || object_type->sampler_dim == HLSL_SAMPLER_DIM_CUBE - || object_type->sampler_dim == HLSL_SAMPLER_DIM_CUBEARRAY)) + || !strcmp(name, "GatherGreen") || !strcmp(name, "GatherAlpha"))) { return add_gather_method_call(ctx, instrs, object, name, params, loc); } - else if (!strcmp(name, "SampleLevel") - && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMS - && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) + else if (!strcmp(name, "SampleLevel")) { return add_sample_lod_method_call(ctx, instrs, object, name, params, loc); } - else if (!strcmp(name, "SampleBias") - && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMS - && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) + else if (!strcmp(name, "SampleBias")) { return add_sample_lod_method_call(ctx, instrs, object, name, params, loc); } else { - struct vkd3d_string_buffer *string; - - if ((string = hlsl_type_to_string(ctx, object_type))) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, - "Method '%s' is not defined on type '%s'.", name, string->buffer); - hlsl_release_string_buffer(ctx, string); - return false; + return raise_invalid_method_object_type(ctx, object_type, name, loc); } }
From: Nikolay Sivov nsivov@codeweavers.com
--- libs/vkd3d-shader/hlsl.y | 51 +++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 19 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 0ee5caba..5e7fe0a2 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -4030,10 +4030,39 @@ static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct list *instrs return true; }
+static const struct method_function +{ + const char *name; + bool (*handler)(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, + const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc); +} +object_methods[] = +{ + { "Gather", add_gather_method_call }, + { "GatherAlpha", add_gather_method_call }, + { "GatherBlue", add_gather_method_call }, + { "GatherGreen", add_gather_method_call }, + { "GatherRed", add_gather_method_call }, + + { "Load", add_load_method_call }, + + { "Sample", add_sample_method_call }, + { "SampleBias", add_sample_lod_method_call }, + { "SampleLevel", add_sample_lod_method_call }, +}; + +static int object_method_function_name_compare(const void *a, const void *b) +{ + const struct method_function *func = b; + + return strcmp(a, func->name); +} + static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { const struct hlsl_type *object_type = object->data_type; + const struct method_function *method;
if (object_type->class != HLSL_CLASS_OBJECT || object_type->base_type != HLSL_TYPE_TEXTURE || object_type->sampler_dim == HLSL_SAMPLER_DIM_GENERIC) @@ -4047,26 +4076,10 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl return false; }
- if (!strcmp(name, "Load")) - { - return add_load_method_call(ctx, instrs, object, name, params, loc); - } - else if (!strcmp(name, "Sample")) - { - return add_sample_method_call(ctx, instrs, object, name, params, loc); - } - else if ((!strcmp(name, "Gather") || !strcmp(name, "GatherRed") || !strcmp(name, "GatherBlue") - || !strcmp(name, "GatherGreen") || !strcmp(name, "GatherAlpha"))) - { - return add_gather_method_call(ctx, instrs, object, name, params, loc); - } - else if (!strcmp(name, "SampleLevel")) - { - return add_sample_lod_method_call(ctx, instrs, object, name, params, loc); - } - else if (!strcmp(name, "SampleBias")) + if ((method = bsearch(name, object_methods, ARRAY_SIZE(object_methods), + sizeof(*method), object_method_function_name_compare))) { - return add_sample_lod_method_call(ctx, instrs, object, name, params, loc); + return method->handler(ctx, instrs, object, name, params, loc); } else {
From: Nikolay Sivov nsivov@codeweavers.com
--- libs/vkd3d-shader/hlsl.c | 36 ++++++++++----- libs/vkd3d-shader/hlsl.h | 30 ++++++------ libs/vkd3d-shader/hlsl.y | 78 +++++++++++++++++++++++++++++++- libs/vkd3d-shader/hlsl_codegen.c | 8 +++- libs/vkd3d-shader/tpf.c | 33 ++++++++------ 5 files changed, 143 insertions(+), 42 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 617aef30..c5ddc874 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1328,6 +1328,7 @@ struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx, const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc) { struct hlsl_ir_resource_load *load; + unsigned int i;
if (!(load = hlsl_alloc(ctx, sizeof(*load)))) return NULL; @@ -1352,7 +1353,8 @@ struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx,
hlsl_src_from_node(&load->coords, params->coords); hlsl_src_from_node(&load->texel_offset, params->texel_offset); - hlsl_src_from_node(&load->lod, params->lod); + for (i = 0; i < ARRAY_SIZE(load->params); ++i) + hlsl_src_from_node(&load->params[i], params->params[i]); load->sampling_dim = params->sampling_dim; if (load->sampling_dim == HLSL_SAMPLER_DIM_GENERIC) load->sampling_dim = hlsl_deref_get_type(ctx, &load->resource)->sampler_dim; @@ -1625,6 +1627,7 @@ static struct hlsl_ir_node *clone_resource_load(struct hlsl_ctx *ctx, struct clone_instr_map *map, struct hlsl_ir_resource_load *src) { struct hlsl_ir_resource_load *dst; + unsigned int i;
if (!(dst = hlsl_alloc(ctx, sizeof(*dst)))) return NULL; @@ -1642,8 +1645,9 @@ static struct hlsl_ir_node *clone_resource_load(struct hlsl_ctx *ctx, return NULL; } clone_src(map, &dst->coords, &src->coords); - clone_src(map, &dst->lod, &src->lod); clone_src(map, &dst->texel_offset, &src->texel_offset); + for (i = 0; i < ARRAY_SIZE(dst->params); ++i) + clone_src(map, &dst->params[i], &src->params[i]); dst->sampling_dim = src->sampling_dim; return &dst->node; } @@ -2424,6 +2428,7 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru { [HLSL_RESOURCE_LOAD] = "load_resource", [HLSL_RESOURCE_SAMPLE] = "sample", + [HLSL_RESOURCE_SAMPLE_CMP] = "sample_cmp", [HLSL_RESOURCE_SAMPLE_LOD] = "sample_lod", [HLSL_RESOURCE_SAMPLE_LOD_BIAS] = "sample_biased", [HLSL_RESOURCE_GATHER_RED] = "gather_red", @@ -2431,6 +2436,11 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru [HLSL_RESOURCE_GATHER_BLUE] = "gather_blue", [HLSL_RESOURCE_GATHER_ALPHA] = "gather_alpha", }; + static const char *const param_0_names[] = + { + [HLSL_RESOURCE_SAMPLE_CMP] = "cmp", + [HLSL_RESOURCE_SAMPLE_LOD] = "lod", + };
assert(load->load_type < ARRAY_SIZE(type_names)); vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[load->load_type]); @@ -2444,10 +2454,10 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru vkd3d_string_buffer_printf(buffer, ", offset = "); dump_src(buffer, &load->texel_offset); } - if (load->lod.node) + if (load->params[0].node) { - vkd3d_string_buffer_printf(buffer, ", lod = "); - dump_src(buffer, &load->lod); + vkd3d_string_buffer_printf(buffer, ", %s = ", param_0_names[load->load_type]); + dump_src(buffer, &load->params[0]); } vkd3d_string_buffer_printf(buffer, ")"); } @@ -2680,11 +2690,14 @@ static void free_ir_loop(struct hlsl_ir_loop *loop)
static void free_ir_resource_load(struct hlsl_ir_resource_load *load) { + unsigned int i; + hlsl_cleanup_deref(&load->sampler); hlsl_cleanup_deref(&load->resource); hlsl_src_remove(&load->coords); - hlsl_src_remove(&load->lod); hlsl_src_remove(&load->texel_offset); + for (i = 0; i < ARRAY_SIZE(load->params); ++i) + hlsl_src_remove(&load->params[i]); vkd3d_free(load); }
@@ -3024,11 +3037,12 @@ static void declare_predefined_types(struct hlsl_ctx *ctx)
static const char *const sampler_names[] = { - [HLSL_SAMPLER_DIM_GENERIC] = "sampler", - [HLSL_SAMPLER_DIM_1D] = "sampler1D", - [HLSL_SAMPLER_DIM_2D] = "sampler2D", - [HLSL_SAMPLER_DIM_3D] = "sampler3D", - [HLSL_SAMPLER_DIM_CUBE] = "samplerCUBE", + [HLSL_SAMPLER_DIM_GENERIC] = "sampler", + [HLSL_SAMPLER_DIM_COMPARISON] = "SamplerComparisonState", + [HLSL_SAMPLER_DIM_1D] = "sampler1D", + [HLSL_SAMPLER_DIM_2D] = "sampler2D", + [HLSL_SAMPLER_DIM_3D] = "sampler3D", + [HLSL_SAMPLER_DIM_CUBE] = "samplerCUBE", };
static const struct diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 6a4e314d..04fa8d9b 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -104,18 +104,19 @@ enum hlsl_base_type
enum hlsl_sampler_dim { - HLSL_SAMPLER_DIM_GENERIC, - HLSL_SAMPLER_DIM_1D, - HLSL_SAMPLER_DIM_2D, - HLSL_SAMPLER_DIM_3D, - HLSL_SAMPLER_DIM_CUBE, - HLSL_SAMPLER_DIM_LAST_SAMPLER = HLSL_SAMPLER_DIM_CUBE, - HLSL_SAMPLER_DIM_1DARRAY, - HLSL_SAMPLER_DIM_2DARRAY, - HLSL_SAMPLER_DIM_2DMS, - HLSL_SAMPLER_DIM_2DMSARRAY, - HLSL_SAMPLER_DIM_CUBEARRAY, - HLSL_SAMPLER_DIM_MAX = HLSL_SAMPLER_DIM_CUBEARRAY, + HLSL_SAMPLER_DIM_GENERIC, + HLSL_SAMPLER_DIM_COMPARISON, + HLSL_SAMPLER_DIM_1D, + HLSL_SAMPLER_DIM_2D, + HLSL_SAMPLER_DIM_3D, + HLSL_SAMPLER_DIM_CUBE, + HLSL_SAMPLER_DIM_LAST_SAMPLER = HLSL_SAMPLER_DIM_CUBE, + HLSL_SAMPLER_DIM_1DARRAY, + HLSL_SAMPLER_DIM_2DARRAY, + HLSL_SAMPLER_DIM_2DMS, + HLSL_SAMPLER_DIM_2DMSARRAY, + HLSL_SAMPLER_DIM_CUBEARRAY, + HLSL_SAMPLER_DIM_MAX = HLSL_SAMPLER_DIM_CUBEARRAY, };
enum hlsl_regset @@ -610,6 +611,7 @@ enum hlsl_resource_load_type { HLSL_RESOURCE_LOAD, HLSL_RESOURCE_SAMPLE, + HLSL_RESOURCE_SAMPLE_CMP, HLSL_RESOURCE_SAMPLE_LOD, HLSL_RESOURCE_SAMPLE_LOD_BIAS, HLSL_RESOURCE_GATHER_RED, @@ -623,7 +625,7 @@ struct hlsl_ir_resource_load struct hlsl_ir_node node; enum hlsl_resource_load_type load_type; struct hlsl_deref resource, sampler; - struct hlsl_src coords, lod, texel_offset; + struct hlsl_src coords, texel_offset, params[1]; enum hlsl_sampler_dim sampling_dim; };
@@ -825,7 +827,7 @@ struct hlsl_resource_load_params struct hlsl_type *format; enum hlsl_resource_load_type type; struct hlsl_ir_node *resource, *sampler; - struct hlsl_ir_node *coords, *lod, *texel_offset; + struct hlsl_ir_node *coords, *texel_offset, *params[1]; enum hlsl_sampler_dim sampling_dim; };
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 5e7fe0a2..cb39f6ce 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -3854,6 +3854,75 @@ static bool add_sample_method_call(struct hlsl_ctx *ctx, struct list *instrs, st return true; }
+static bool add_sample_cmp_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, + const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + const struct hlsl_type *object_type = object->data_type; + const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); + const unsigned int offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); + struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_SAMPLE_CMP}; + const struct hlsl_type *sampler_type; + struct hlsl_ir_node *load; + + if (object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS + || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY) + { + return raise_invalid_method_object_type(ctx, object_type, name, loc); + } + + if (params->args_count < 3 || params->args_count > 5 + !!offset_dim) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Wrong number of arguments to method '%s': expected from 2 to %u, but got %u.", + name, 4 + !!offset_dim, params->args_count); + return false; + } + + sampler_type = params->args[0]->data_type; + if (sampler_type->class != HLSL_CLASS_OBJECT || sampler_type->base_type != HLSL_TYPE_SAMPLER + || sampler_type->sampler_dim != HLSL_SAMPLER_DIM_COMPARISON) + { + 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 %s(): expected 'SamplerComparisonState', but got '%s'.", + name, string->buffer); + hlsl_release_string_buffer(ctx, string); + return false; + } + + if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], + hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) + return false; + + if (!(load_params.params[0] = add_implicit_conversion(ctx, instrs, params->args[2], + hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc))) + load_params.params[0] = params->args[2]; + + if (offset_dim && params->args_count > 3) + { + if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[2], + hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) + return false; + } + + if (params->args_count > 3 + !!offset_dim) + hlsl_fixme(ctx, loc, "%s() clamp parameter.", name); + if (params->args_count > 4 + !!offset_dim) + hlsl_fixme(ctx, loc, "Tiled resource status argument."); + + load_params.format = object_type->e.resource_format; + load_params.resource = object; + load_params.sampler = params->args[0]; + + if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) + return false; + list_add_tail(instrs, &load->entry); + + return true; +} + static bool add_gather_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -4006,9 +4075,9 @@ static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct list *instrs hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) load_params.coords = params->args[1];
- if (!(load_params.lod = add_implicit_conversion(ctx, instrs, params->args[2], + if (!(load_params.params[0] = add_implicit_conversion(ctx, instrs, params->args[2], hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc))) - load_params.lod = params->args[2]; + load_params.params[0] = params->args[2];
if (offset_dim && params->args_count > 3) { @@ -4048,6 +4117,7 @@ object_methods[] =
{ "Sample", add_sample_method_call }, { "SampleBias", add_sample_lod_method_call }, + { "SampleCmp", add_sample_cmp_method_call }, { "SampleLevel", add_sample_lod_method_call }, };
@@ -5064,6 +5134,10 @@ type_no_void: { $$ = ctx->builtin_types.sampler[HLSL_SAMPLER_DIM_GENERIC]; } + | KW_SAMPLERCOMPARISONSTATE + { + $$ = ctx->builtin_types.sampler[HLSL_SAMPLER_DIM_COMPARISON]; + } | KW_SAMPLER1D { $$ = ctx->builtin_types.sampler[HLSL_SAMPLER_DIM_1D]; diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 638dab6e..b7870e37 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -2656,6 +2656,7 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop case HLSL_IR_RESOURCE_LOAD: { struct hlsl_ir_resource_load *load = hlsl_ir_resource_load(instr); + unsigned int i;
var = load->resource.var; var->last_read = max(var->last_read, var_last_read); @@ -2672,8 +2673,11 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop load->coords.node->last_read = instr->index; if (load->texel_offset.node) load->texel_offset.node->last_read = instr->index; - if (load->lod.node) - load->lod.node->last_read = instr->index; + for (i = 0; i < ARRAY_SIZE(load->params); ++i) + { + if (load->params[i].node) + load->params[i].node->last_read = instr->index; + } break; } case HLSL_IR_RESOURCE_STORE: diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index eadad3b9..70f93314 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -3665,23 +3665,24 @@ static void write_sm4_dcl_constant_buffer(struct vkd3d_bytecode_buffer *buffer, static void write_sm4_dcl_samplers(struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_var *var) { unsigned int i, count = var->data_type->reg_size[HLSL_REGSET_SAMPLERS]; - struct sm4_instruction instr; + struct sm4_instruction instr = + { + .opcode = VKD3D_SM4_OP_DCL_SAMPLER, + + .dsts[0].reg.type = VKD3D_SM4_RT_SAMPLER, + .dsts[0].reg.idx_count = 1, + .dst_count = 1, + }; + + if (var->data_type->sampler_dim == HLSL_SAMPLER_DIM_COMPARISON) + instr.opcode |= VKD3D_SM4_SAMPLER_COMPARISON << VKD3D_SM4_SAMPLER_MODE_SHIFT;
for (i = 0; i < count; ++i) { if (!var->objects_usage[HLSL_REGSET_SAMPLERS][i].used) continue;
- instr = (struct sm4_instruction) - { - .opcode = VKD3D_SM4_OP_DCL_SAMPLER, - - .dsts[0].reg.type = VKD3D_SM4_RT_SAMPLER, - .dsts[0].reg.idx = {var->regs[HLSL_REGSET_SAMPLERS].id + i}, - .dsts[0].reg.idx_count = 1, - .dst_count = 1, - }; - + instr.dsts[0].reg.idx[0] = var->regs[HLSL_REGSET_SAMPLERS].id + i; write_sm4_instruction(buffer, &instr); } } @@ -4044,6 +4045,10 @@ static void write_sm4_sample(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer instr.opcode = VKD3D_SM4_OP_SAMPLE; break;
+ case HLSL_RESOURCE_SAMPLE_CMP: + instr.opcode = VKD3D_SM4_OP_SAMPLE_C; + break; + case HLSL_RESOURCE_SAMPLE_LOD_BIAS: instr.opcode = VKD3D_SM4_OP_SAMPLE_B; break; @@ -4070,9 +4075,10 @@ static void write_sm4_sample(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer sm4_src_from_deref(ctx, &instr.srcs[2], sampler, sampler->var->data_type, VKD3DSP_WRITEMASK_ALL); instr.src_count = 3;
- if (load->load_type == HLSL_RESOURCE_SAMPLE_LOD_BIAS) + if (load->load_type == HLSL_RESOURCE_SAMPLE_CMP || + load->load_type == HLSL_RESOURCE_SAMPLE_LOD_BIAS) { - sm4_src_from_node(&instr.srcs[3], load->lod.node, VKD3DSP_WRITEMASK_ALL); + sm4_src_from_node(&instr.srcs[3], load->params[0].node, VKD3DSP_WRITEMASK_ALL); ++instr.src_count; }
@@ -4872,6 +4878,7 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx, break;
case HLSL_RESOURCE_SAMPLE: + case HLSL_RESOURCE_SAMPLE_CMP: case HLSL_RESOURCE_SAMPLE_LOD_BIAS: if (!load->sampler.var) {
Zebediah Figura (@zfigura) commented about libs/vkd3d-shader/hlsl.h:
struct hlsl_ir_node node; enum hlsl_resource_load_type load_type; struct hlsl_deref resource, sampler;
- struct hlsl_src coords, lod, texel_offset;
- struct hlsl_src coords, texel_offset, params[1];
I don't think I'm a fan of this change.
On Tue May 16 17:35:24 2023 +0000, Zebediah Figura wrote:
I don't think I'm a fan of this change.
I suppose I can see the point of doing it like exprs, though in that case it should ideally be done for all of the sources, not just the one. There's also the disadvantage that you have to now look up what the parameter order is every time (which broadly isn't true for exprs.)
Zebediah Figura (@zfigura) commented about libs/vkd3d-shader/hlsl.y:
- struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_SAMPLE_CMP};
- const struct hlsl_type *sampler_type;
- struct hlsl_ir_node *load;
- if (object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS
|| object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY)
- {
return raise_invalid_method_object_type(ctx, object_type, name, loc);
- }
- if (params->args_count < 3 || params->args_count > 5 + !!offset_dim)
- {
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT,
"Wrong number of arguments to method '%s': expected from 2 to %u, but got %u.",
name, 4 + !!offset_dim, params->args_count);
return false;
The message here needs to be modified to match the different parameter count.
I won't ask for it for this patch, since I've already reviewed it, but in the future, please try to split up commits more. It's a lot easier to review with granular changes. E.g. in this case we could have had:
* change "lod" to "params" * parse SamplerComparisonState * parse the SampleCmp() function * emit sm4 for HLSL_RESOURCE_SAMPLE_CMP
On Tue May 16 17:37:08 2023 +0000, Zebediah Figura wrote:
I suppose I can see the point of doing it like exprs, though in that case it should ideally be done for all of the sources, not just the one. There's also the disadvantage that you have to now look up what the parameter order is every time (which broadly isn't true for exprs.)
I see what you mean. Having an array does not help readability I agree. I'll add new fields for new parameters.
On Tue May 16 18:30:55 2023 +0000, Zebediah Figura wrote:
I won't ask for it for this patch, since I've already reviewed it, but in the future, please try to split up commits more. It's a lot easier to review with granular changes. E.g. in this case we could have had:
- change "lod" to "params"
- parse SamplerComparisonState
- parse the SampleCmp() function
- emit sm4 for HLSL_RESOURCE_SAMPLE_CMP
I'll split it, no problem.