Module: vkd3d Branch: master Commit: fea50d243ccd16df18a448e8475ae120a725ebee URL: https://gitlab.winehq.org/wine/vkd3d/-/commit/fea50d243ccd16df18a448e8475ae1...
Author: Zebediah Figura zfigura@codeweavers.com Date: Thu Aug 12 18:26:53 2021 -0500
vkd3d-shader/hlsl: Parse texture index expressions.
---
libs/vkd3d-shader/hlsl.y | 74 ++++++++++++++++++++++++++++++++++++++++-- tests/texture-load.shader_test | 15 +++++++++ 2 files changed, 87 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index dbb9571d..aee12b83 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -747,13 +747,83 @@ static bool add_matrix_index(struct hlsl_ctx *ctx, struct list *instrs, return true; }
+static struct hlsl_ir_node *add_zero_mipmap_level(struct hlsl_ctx *ctx, struct list *instrs, + struct hlsl_ir_node *index, unsigned int dim_count, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_load *coords_load; + struct hlsl_deref coords_deref; + struct hlsl_ir_constant *zero; + struct hlsl_ir_store *store; + struct hlsl_ir_var *coords; + + if (!(coords = hlsl_new_synthetic_var(ctx, "coords", + hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, dim_count + 1), loc))) + return NULL; + + hlsl_init_simple_deref_from_var(&coords_deref, coords); + if (!(store = hlsl_new_store_index(ctx, &coords_deref, NULL, index, (1u << dim_count) - 1, loc))) + return NULL; + list_add_tail(instrs, &store->node.entry); + + if (!(zero = hlsl_new_uint_constant(ctx, 0, loc))) + return NULL; + list_add_tail(instrs, &zero->node.entry); + + if (!(store = hlsl_new_store_index(ctx, &coords_deref, NULL, &zero->node, 1u << dim_count, loc))) + return NULL; + list_add_tail(instrs, &store->node.entry); + + if (!(coords_load = hlsl_new_var_load(ctx, coords, *loc))) + return NULL; + list_add_tail(instrs, &coords_load->node.entry); + + return &coords_load->node; +} + static bool add_array_load(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *array, struct hlsl_ir_node *index, const struct vkd3d_shader_location *loc) { - const struct hlsl_type *expr_type = array->data_type; + const struct hlsl_type *expr_type = array->data_type, *index_type = index->data_type; struct hlsl_ir_expr *cast;
- if (index->data_type->type != HLSL_CLASS_SCALAR) + if (expr_type->type == HLSL_CLASS_OBJECT && expr_type->base_type == HLSL_TYPE_TEXTURE + && expr_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC) + { + struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_LOAD}; + unsigned int dim_count = hlsl_sampler_dim_count(expr_type->sampler_dim); + /* Only HLSL_IR_LOAD can return an object. */ + struct hlsl_ir_load *object_load = hlsl_ir_load(array); + struct hlsl_ir_resource_load *resource_load; + + if (index_type->type > HLSL_CLASS_VECTOR || index_type->dimx != dim_count) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, expr_type))) + hlsl_error(ctx, &index->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Array index of type '%s' must be of type 'uint%u'.", string->buffer, dim_count); + hlsl_release_string_buffer(ctx, string); + return false; + } + + if (!(index = add_implicit_conversion(ctx, instrs, index, + hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, dim_count), &index->loc))) + return false; + + if (!(index = add_zero_mipmap_level(ctx, instrs, index, dim_count, loc))) + return false; + + load_params.format = expr_type->e.resource_format; + load_params.resource = object_load->src; + load_params.coords = index; + + if (!(resource_load = hlsl_new_resource_load(ctx, &load_params, loc))) + return false; + list_add_tail(instrs, &resource_load->node.entry); + return true; + } + + if (index_type->type != HLSL_CLASS_SCALAR) { hlsl_error(ctx, &index->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Array index is not scalar."); return false; diff --git a/tests/texture-load.shader_test b/tests/texture-load.shader_test index 81d06305..7d39fb65 100644 --- a/tests/texture-load.shader_test +++ b/tests/texture-load.shader_test @@ -20,3 +20,18 @@ probe (0, 0) rgba (0.1, 0.2, 0.3, 0.4) probe (1, 0) rgba (0.5, 0.7, 0.6, 0.8) probe (0, 1) rgba (0.6, 0.5, 0.2, 0.1) probe (1, 1) rgba (0.8, 0.0, 0.7, 1.0) + +[pixel shader] +Texture2D t; + +float4 main(float4 pos : sv_position) : sv_target +{ + return t[pos.yx]; +} + +[test] +draw quad +probe (0, 0) rgba (0.1, 0.2, 0.3, 0.4) +probe (1, 0) rgba (0.6, 0.5, 0.2, 0.1) +probe (0, 1) rgba (0.5, 0.7, 0.6, 0.8) +probe (1, 1) rgba (0.8, 0.0, 0.7, 1.0)