vkd3d-shader/hlsl: Parse texture index expressions.

This commit is contained in:
Zebediah Figura 2021-08-12 18:26:53 -05:00 committed by Alexandre Julliard
parent 7115a94063
commit fea50d243c
Notes: Alexandre Julliard 2022-10-19 22:07:47 +02:00
Approved-by: Giovanni Mascellani (@giomasce)
Approved-by: Henri Verbeet (@hverbeet)
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/30
2 changed files with 87 additions and 2 deletions

View File

@ -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;

View File

@ -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)