The objective of this patch series is to converge to the correct argument count checks and offset parameter dimensions when parsing the Load, Sample, SampleLevel, Gather (and variants) methods, for the different texture types.
I made the following table to summarize the expected arguments and their dimensions:
![resource_methods_dims](/uploads/43511fe82e934c2542f6152f9134cb0e/resource_methods_dims.png)
Getting these required some extensive trial-and-error, because: - Official documentation about the methods is spread in different pages and in a somewhat inconsistent manner. - Automatic vector truncation, scalar broadcasting, and type conversion, make shaders that pass inexact types compile. - clamp and status arguments (for tiled resources) are not present in fxc 9, and yet, they are part of ps_5_0 and vs_5_0. - Some methods (Load() in particular) require the mipmap level as part of the location parameter (except for Multi-Sampled textures), while other don't.
For implementing new methods I recommend passing an invalid parameter count to them in fxc 10, so that it lists available overloads. And to do this for each texture type.
-- v2: vkd3d-shader/hlsl: Add offset parameter to 'Load' method. vkd3d-shader/hlsl: Properly check argument count in gather methods. vkd3d-shader/hlsl: Properly check argument count in SampleLevel method. vkd3d-shader/hlsl: Use proper dimensions on SampleLevel method offset parameter. vkd3d-shader/hlsl: Properly check argument count in Sample method. vkd3d-shader/hlsl: Use proper dimensions on gather methods offset parameter. vkd3d-shader/hlsl: Use proper dimensions on Sample method offset parameter. vkd3d-shader/hlsl: Parse the SampleLevel method.
From: Zebediah Figura zfigura@codeweavers.com
---
Changes: - Translated patch to index paths. - Changed error 'argument 0 of Sample()' -> 'argument 0 of SampleLevel()'. - Don't allow calling SampleLevel from multi-sample textures. --- libs/vkd3d-shader/hlsl.c | 21 +++++++++++- libs/vkd3d-shader/hlsl.h | 7 ++-- libs/vkd3d-shader/hlsl.y | 55 ++++++++++++++++++++++++++++++++ libs/vkd3d-shader/hlsl_codegen.c | 2 ++ libs/vkd3d-shader/hlsl_sm4.c | 4 +++ 5 files changed, 86 insertions(+), 3 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index a47e3d2d..773b163d 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1036,6 +1036,18 @@ struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, struc return load; }
+struct hlsl_ir_resource_load *hlsl_new_sample_lod(struct hlsl_ctx *ctx, struct hlsl_type *data_type, + struct hlsl_deref *resource, struct hlsl_deref *sampler, struct hlsl_ir_node *coords, + struct hlsl_ir_node *texel_offset, struct hlsl_ir_node *lod, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_resource_load *load; + + if ((load = hlsl_new_resource_load(ctx, data_type, HLSL_RESOURCE_SAMPLE_LOD, + resource, sampler, coords, texel_offset, loc))) + hlsl_src_from_node(&load->lod, lod); + return load; +} + struct hlsl_ir_swizzle *hlsl_new_swizzle(struct hlsl_ctx *ctx, DWORD s, unsigned int components, struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc) { @@ -1668,6 +1680,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_LOD] = "sample_lod", [HLSL_RESOURCE_GATHER_RED] = "gather_red", [HLSL_RESOURCE_GATHER_GREEN] = "gather_green", [HLSL_RESOURCE_GATHER_BLUE] = "gather_blue", @@ -1686,6 +1699,11 @@ 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) + { + vkd3d_string_buffer_printf(buffer, ", lod = "); + dump_src(buffer, &load->lod); + } vkd3d_string_buffer_printf(buffer, ")"); }
@@ -1873,9 +1891,10 @@ 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_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); vkd3d_free(load); } diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 7970665c..7a17658a 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -391,6 +391,7 @@ enum hlsl_resource_load_type { HLSL_RESOURCE_LOAD, HLSL_RESOURCE_SAMPLE, + HLSL_RESOURCE_SAMPLE_LOD, HLSL_RESOURCE_GATHER_RED, HLSL_RESOURCE_GATHER_GREEN, HLSL_RESOURCE_GATHER_BLUE, @@ -402,8 +403,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; - struct hlsl_src texel_offset; + struct hlsl_src coords, lod, texel_offset; };
struct hlsl_ir_store @@ -773,6 +773,9 @@ struct hlsl_ir_store *hlsl_new_store_component(struct hlsl_ctx *ctx, struct hlsl 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_deref *resource, struct hlsl_deref *sampler, struct hlsl_ir_node *coords, struct hlsl_ir_node *texel_offset, const struct vkd3d_shader_location *loc); +struct hlsl_ir_resource_load *hlsl_new_sample_lod(struct hlsl_ctx *ctx, struct hlsl_type *data_type, + struct hlsl_deref *resource, struct hlsl_deref *sampler, struct hlsl_ir_node *coords, + struct hlsl_ir_node *texel_offset, struct hlsl_ir_node *lod, const struct vkd3d_shader_location *loc);
struct hlsl_ir_loop *hlsl_new_loop(struct hlsl_ctx *ctx, struct vkd3d_shader_location loc); struct hlsl_type *hlsl_new_struct_type(struct hlsl_ctx *ctx, const char *name, diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 7df7afb9..235a42e7 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2589,6 +2589,61 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl list_add_tail(instrs, &load->node.entry); return true; } + else if (!strcmp(name, "SampleLevel") + && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMS + && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) + { + const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); + const struct hlsl_type *sampler_type; + struct hlsl_ir_resource_load *load; + struct hlsl_ir_node *offset = NULL; + struct hlsl_ir_load *sampler_load; + struct hlsl_ir_node *coords, *lod; + + if (params->args_count != 3 && params->args_count != 4) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Wrong number of arguments to method 'SampleLevel': expected 3 or 4, but got %u.", params->args_count); + return false; + } + + 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 SampleLevel(): 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 (!(lod = add_implicit_conversion(ctx, instrs, params->args[2], + hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc))) + lod = params->args[2]; + + if (params->args_count == 4) + { + if (!(offset = add_implicit_conversion(ctx, instrs, params->args[3], + hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim), loc))) + return false; + } + + if (!(load = hlsl_new_sample_lod(ctx, object_type->e.resource_format, + &object_load->src, &sampler_load->src, coords, offset, lod, loc))) + return false; + list_add_tail(instrs, &load->node.entry); + return true; + } else { struct vkd3d_string_buffer *string; diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 36a417e5..77f43984 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1365,6 +1365,8 @@ 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; break; } case HLSL_IR_SWIZZLE: diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index cdd73e57..5e1f61c1 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -2135,6 +2135,10 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx, write_sm4_gather(ctx, buffer, resource_type, &load->node, &load->resource, &load->sampler, coords, HLSL_SWIZZLE(W, W, W, W), texel_offset); break; + + case HLSL_RESOURCE_SAMPLE_LOD: + hlsl_fixme(ctx, &load->node.loc, "SM4 sample-LOD expression."); + break; } }
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com --- v2: - Moved hlsl_offset_dim_count() to hlsl.y. - Changed C99 comment. --- libs/vkd3d-shader/hlsl.y | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 235a42e7..f25ff6a2 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2376,6 +2376,30 @@ static struct list *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type return params->instrs; }
+static unsigned int hlsl_offset_dim_count(enum hlsl_sampler_dim dim) +{ + switch (dim) + { + case HLSL_SAMPLER_DIM_1D: + case HLSL_SAMPLER_DIM_1DARRAY: + return 1; + case HLSL_SAMPLER_DIM_2D: + case HLSL_SAMPLER_DIM_2DMS: + case HLSL_SAMPLER_DIM_2DARRAY: + case HLSL_SAMPLER_DIM_2DMSARRAY: + return 2; + case HLSL_SAMPLER_DIM_3D: + return 3; + case HLSL_SAMPLER_DIM_CUBE: + case HLSL_SAMPLER_DIM_CUBEARRAY: + /* Offset parameters not supported for these types. */ + return 0; + default: + assert(0); + return 0; + } +} + 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) { @@ -2439,6 +2463,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) { 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); const struct hlsl_type *sampler_type; struct hlsl_ir_resource_load *load; struct hlsl_ir_node *offset = NULL; @@ -2472,10 +2497,10 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) return false;
- if (params->args_count == 3) + if (!!offset_dim && params->args_count == 3) { if (!(offset = add_implicit_conversion(ctx, instrs, params->args[2], - hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim), loc))) + hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) return false; }
From: Francisco Casas fcasas@codeweavers.com
--- libs/vkd3d-shader/hlsl.y | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index f25ff6a2..c5da01a9 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2519,6 +2519,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl || object_type->sampler_dim == HLSL_SAMPLER_DIM_CUBEARRAY)) { 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); enum hlsl_resource_load_type load_type; const struct hlsl_type *sampler_type; struct hlsl_ir_resource_load *load; @@ -2575,7 +2576,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl if (params->args_count == 3 || params->args_count == 4) { if (!(offset = add_implicit_conversion(ctx, instrs, params->args[2], - hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim), loc))) + hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) return false; }
From: Francisco Casas fcasas@codeweavers.com
Also, TextureCube and TextureCubeArray don't support the offset argument, so this check is updated.
Signed-off-by: Francisco Casas fcasas@codeweavers.com --- v2: - Changed hlsl_fixme message from ""Tiled resource clamp argument."" to "Sample() clamp parameter." --- libs/vkd3d-shader/hlsl.y | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index c5da01a9..ed9f32fc 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2470,10 +2470,11 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl struct hlsl_ir_load *sampler_load; struct hlsl_ir_node *coords;
- if (params->args_count != 2 && params->args_count != 3) + if (params->args_count < 2 || params->args_count > 4 + !!offset_dim) { 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); + "Wrong number of arguments to method 'Sample': expected from 2 to %u, but got %u.", + 4 + !!offset_dim, params->args_count); return false; }
@@ -2497,13 +2498,18 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) return false;
- if (!!offset_dim && params->args_count == 3) + if (offset_dim && params->args_count > 2) { if (!(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 > 2 + !!offset_dim) + hlsl_fixme(ctx, loc, "Sample() clamp parameter."); + if (params->args_count > 3 + !!offset_dim) + hlsl_fixme(ctx, loc, "Tiled resource status argument."); + if (!(load = hlsl_new_resource_load(ctx, object_type->e.resource_format, HLSL_RESOURCE_SAMPLE, &object_load->src, &sampler_load->src, coords, offset, loc))) return false;
From: Francisco Casas fcasas@codeweavers.com
--- libs/vkd3d-shader/hlsl.y | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index ed9f32fc..50f25b53 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2626,6 +2626,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) { 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); const struct hlsl_type *sampler_type; struct hlsl_ir_resource_load *load; struct hlsl_ir_node *offset = NULL; @@ -2666,7 +2667,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl if (params->args_count == 4) { if (!(offset = add_implicit_conversion(ctx, instrs, params->args[3], - hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim), loc))) + hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) return false; }
From: Francisco Casas fcasas@codeweavers.com
Also, TextureCube and TextureCubeArray don't support the offset argument, so this check is updated here too.
Signed-off-by: Francisco Casas fcasas@codeweavers.com --- v2: - Changed minimum number of arguments expected for SampleLevel() from 2 to 3. --- libs/vkd3d-shader/hlsl.y | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 50f25b53..97292006 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2633,10 +2633,11 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl struct hlsl_ir_load *sampler_load; struct hlsl_ir_node *coords, *lod;
- if (params->args_count != 3 && params->args_count != 4) + if (params->args_count < 3 || params->args_count > 4 + !!offset_dim) { hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, - "Wrong number of arguments to method 'SampleLevel': expected 3 or 4, but got %u.", params->args_count); + "Wrong number of arguments to method 'SampleLevel': expected from 3 to %u, but got %u.", + 4 + !!offset_dim, params->args_count); return false; }
@@ -2664,13 +2665,16 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc))) lod = params->args[2];
- if (params->args_count == 4) + if (offset_dim && params->args_count > 3) { if (!(offset = add_implicit_conversion(ctx, instrs, params->args[3], hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) return false; }
+ if (params->args_count > 3 + !!offset_dim) + hlsl_fixme(ctx, loc, "Tiled resource status argument."); + if (!(load = hlsl_new_sample_lod(ctx, object_type->e.resource_format, &object_load->src, &sampler_load->src, coords, offset, lod, loc))) return false;
From: Francisco Casas fcasas@codeweavers.com
--- libs/vkd3d-shader/hlsl.y | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 97292006..4b02a0aa 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2556,12 +2556,13 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl read_channel = 0; }
- if (!strcmp(name, "Gather")) + if (!strcmp(name, "Gather") || !offset_dim) { - if (params->args_count != 2 && params->args_count != 3) + if (params->args_count < 2 && params->args_count > 3 + !!offset_dim) { hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, - "Wrong number of arguments to method 'Gather': expected 2 or 3, but got %u.", params->args_count); + "Wrong number of arguments to method '%s': expected from 2 to %u, but got %u.", + name, 3 + !!offset_dim, params->args_count); return false; } } @@ -2573,13 +2574,14 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl return false; }
- if (params->args_count == 4 || params->args_count == 7) + if (params->args_count == 3 + !!offset_dim || params->args_count == 7) hlsl_fixme(ctx, loc, "Tiled resource status argument.");
if (params->args_count == 6 || params->args_count == 7) - hlsl_fixme(ctx, loc, "Multiple Gather() offset parameters."); - - if (params->args_count == 3 || params->args_count == 4) + { + hlsl_fixme(ctx, loc, "Multiple %s() offset parameters.", name); + } + else if (offset_dim && params->args_count > 2) { if (!(offset = add_implicit_conversion(ctx, instrs, params->args[2], hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc)))
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com --- v2: - Removed double new line. - Fixed "betweed" -> "between" typo. --- libs/vkd3d-shader/hlsl.y | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 4b02a0aa..6d54c49f 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2426,26 +2426,38 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl && object_type->sampler_dim != HLSL_SAMPLER_DIM_CUBEARRAY) { 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_ir_resource_load *load; + struct hlsl_ir_node *offset = NULL; struct hlsl_ir_node *coords; + bool multisampled; + + multisampled = object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS + || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY;
- if (object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS - || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY) + if (params->args_count < 1 + multisampled || params->args_count > 3 + multisampled) { - FIXME("'Load' method for multi-sample textures.\n"); + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Wrong number of arguments to method 'Load': expected between %u and %u, but got %u.", + 1 + multisampled, 3 + multisampled, params->args_count); return false; } + if (multisampled) + { + hlsl_fixme(ctx, loc, "Load() sampling index parameter."); + }
- if (params->args_count < 1 || params->args_count > 3) + assert(offset_dim); + if (params->args_count > 1 + multisampled) { - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, - "Wrong number of arguments to method 'Load': expected 1, 2, or 3, but got %u.", params->args_count); - return false; + if (!(offset = add_implicit_conversion(ctx, instrs, params->args[1 + multisampled], + hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) + return false; } - if (params->args_count >= 2) - hlsl_fixme(ctx, loc, "Offset parameter."); - if (params->args_count == 3) + if (params->args_count > 2 + multisampled) + { hlsl_fixme(ctx, loc, "Tiled resource status argument."); + }
/* +1 for the mipmap level */ if (!(coords = add_implicit_conversion(ctx, instrs, params->args[0], @@ -2453,7 +2465,7 @@ 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, NULL, coords, NULL, loc))) + &object_load->src, NULL, coords, offset, loc))) return false; list_add_tail(instrs, &load->node.entry); return true;
This merge request was approved by Zebediah Figura.
This merge request was approved by Henri Verbeet.