Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 25 +++++++++++++++----- libs/vkd3d-shader/hlsl.h | 3 ++- libs/vkd3d-shader/hlsl.y | 49 +++++++++++++++++++++++++++++----------- 3 files changed, 57 insertions(+), 20 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 6462ce8fc..aecc4a639 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -261,7 +261,7 @@ struct hlsl_type *hlsl_new_struct_type(struct hlsl_ctx *ctx, const char *name, s return type; }
-struct hlsl_type *hlsl_new_texture_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim) +struct hlsl_type *hlsl_new_texture_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, struct hlsl_type *format) { struct hlsl_type *type;
@@ -272,6 +272,7 @@ struct hlsl_type *hlsl_new_texture_type(struct hlsl_ctx *ctx, enum hlsl_sampler_ type->dimx = 4; type->dimy = 1; type->sampler_dim = dim; + type->e.resource_format = format; list_add_tail(&ctx->types, &type->entry); return type; } @@ -344,9 +345,14 @@ bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2 return false; if (t1->base_type != t2->base_type) return false; - if ((t1->base_type == HLSL_TYPE_SAMPLER || t1->base_type == HLSL_TYPE_TEXTURE) - && t1->sampler_dim != t2->sampler_dim) - return false; + if (t1->base_type == HLSL_TYPE_SAMPLER || t1->base_type == HLSL_TYPE_TEXTURE) + { + if (t1->sampler_dim != t2->sampler_dim) + return false; + if (t1->base_type == HLSL_TYPE_TEXTURE && t1->sampler_dim != HLSL_SAMPLER_DIM_GENERIC + && !hlsl_types_are_equal(t1->e.resource_format, t2->e.resource_format)) + return false; + } if ((t1->modifiers & HLSL_MODIFIER_ROW_MAJOR) != (t2->modifiers & HLSL_MODIFIER_ROW_MAJOR)) return false; @@ -742,6 +748,8 @@ void hlsl_pop_scope(struct hlsl_ctx *ctx)
static int compare_param_hlsl_types(const struct hlsl_type *t1, const struct hlsl_type *t2) { + int r; + if (t1->type != t2->type) { if (!((t1->type == HLSL_CLASS_SCALAR && t2->type == HLSL_CLASS_VECTOR) @@ -752,7 +760,13 @@ static int compare_param_hlsl_types(const struct hlsl_type *t1, const struct hls return t1->base_type - t2->base_type; if ((t1->base_type == HLSL_TYPE_SAMPLER || t1->base_type == HLSL_TYPE_TEXTURE) && t1->sampler_dim != t2->sampler_dim) - return t1->sampler_dim - t2->sampler_dim; + { + if (t1->sampler_dim != t2->sampler_dim) + return t1->sampler_dim - t2->sampler_dim; + if (t1->base_type == HLSL_TYPE_TEXTURE && t1->sampler_dim != HLSL_SAMPLER_DIM_GENERIC + && (r = compare_param_hlsl_types(t1->e.resource_format, t2->e.resource_format))) + return r; + } if (t1->dimx != t2->dimx) return t1->dimx - t2->dimx; if (t1->dimy != t2->dimy) @@ -761,7 +775,6 @@ static int compare_param_hlsl_types(const struct hlsl_type *t1, const struct hls { struct list *t1cur, *t2cur; struct hlsl_struct_field *t1field, *t2field; - int r;
t1cur = list_head(t1->e.elements); t2cur = list_head(t2->e.elements); diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 65c6f34e0..64a90ffdc 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -126,6 +126,7 @@ struct hlsl_type struct hlsl_type *type; unsigned int elements_count; } array; + struct hlsl_type *resource_format; } e;
unsigned int reg_size; @@ -655,7 +656,7 @@ struct hlsl_ir_swizzle *hlsl_new_swizzle(struct hlsl_ctx *ctx, DWORD s, unsigned struct hlsl_ir_node *val, struct vkd3d_shader_location *loc); struct hlsl_ir_var *hlsl_new_synthetic_var(struct hlsl_ctx *ctx, const char *name, struct hlsl_type *type, const struct vkd3d_shader_location loc); -struct hlsl_type *hlsl_new_texture_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim); +struct hlsl_type *hlsl_new_texture_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, struct hlsl_type *format); struct hlsl_ir_constant *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned int n, const struct vkd3d_shader_location loc); struct hlsl_ir_node *hlsl_new_unary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index b8149950d..32dd418d1 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1789,6 +1789,7 @@ static struct list *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type struct parse_colon_attribute colon_attribute; struct hlsl_semantic semantic; enum hlsl_buffer_type buffer_type; + enum hlsl_sampler_dim sampler_dim; }
%token KW_BLENDSTATE @@ -1963,6 +1964,8 @@ static struct list *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type
%type <reg_reservation> register_opt
+%type <sampler_dim> texture_type + %type <semantic> semantic
%type <type> field_type @@ -2376,6 +2379,24 @@ input_mod: $$ = HLSL_STORAGE_IN | HLSL_STORAGE_OUT; }
+texture_type: + KW_TEXTURE1D + { + $$ = HLSL_SAMPLER_DIM_1D; + } + | KW_TEXTURE2D + { + $$ = HLSL_SAMPLER_DIM_2D; + } + | KW_TEXTURE3D + { + $$ = HLSL_SAMPLER_DIM_3D; + } + | KW_TEXTURECUBE + { + $$ = HLSL_SAMPLER_DIM_CUBE; + } + type: KW_VECTOR '<' type ',' C_INTEGER '>' { @@ -2453,23 +2474,25 @@ type: } | KW_TEXTURE { - $$ = hlsl_new_texture_type(ctx, HLSL_SAMPLER_DIM_GENERIC); - } - | KW_TEXTURE1D - { - $$ = hlsl_new_texture_type(ctx, HLSL_SAMPLER_DIM_1D); + $$ = hlsl_new_texture_type(ctx, HLSL_SAMPLER_DIM_GENERIC, NULL); } - | KW_TEXTURE2D + | texture_type { - $$ = hlsl_new_texture_type(ctx, HLSL_SAMPLER_DIM_2D); + $$ = hlsl_new_texture_type(ctx, $1, ctx->builtin_types.vector[HLSL_TYPE_FLOAT][4 - 1]); } - | KW_TEXTURE3D + | texture_type '<' type '>' { - $$ = hlsl_new_texture_type(ctx, HLSL_SAMPLER_DIM_3D); - } - | KW_TEXTURECUBE - { - $$ = hlsl_new_texture_type(ctx, HLSL_SAMPLER_DIM_CUBE); + if ($3->type > HLSL_CLASS_VECTOR) + { + struct vkd3d_string_buffer *string; + + string = hlsl_type_to_string(ctx, $3); + if (string) + hlsl_error(ctx, @3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Texture data type %s is not scalar or vector.\n", string->buffer); + hlsl_release_string_buffer(ctx, string); + } + $$ = hlsl_new_texture_type(ctx, $1, $3); } | TYPE_IDENTIFIER {