From: Zebediah Figura zfigura@codeweavers.com
--- libs/vkd3d-shader/d3dbc.c | 9 +++++++++ libs/vkd3d-shader/fx.c | 1 + 2 files changed, 10 insertions(+)
diff --git a/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d-shader/d3dbc.c index 97650942e..1ad97adda 100644 --- a/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d-shader/d3dbc.c @@ -1526,6 +1526,15 @@ D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type) { case HLSL_TYPE_BOOL: return D3DXPT_BOOL; + /* Actually double behaves differently depending on DLL version: + * For <= 36, it maps to D3DXPT_FLOAT. + * For 37-40, it maps to zero (D3DXPT_VOID). + * For >= 41, it maps to 39, which is D3D_SVT_DOUBLE (note D3D_SVT_* + * values are mostly compatible with D3DXPT_*). + * However, the latter two cases look like bugs, and a reasonable + * application certainly wouldn't know what to do with them. + * For fx_2_0 it's always D3DXPT_FLOAT regardless of DLL version. */ + case HLSL_TYPE_DOUBLE: case HLSL_TYPE_FLOAT: case HLSL_TYPE_HALF: return D3DXPT_FLOAT; diff --git a/libs/vkd3d-shader/fx.c b/libs/vkd3d-shader/fx.c index 466908cd8..3b5a4caf0 100644 --- a/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d-shader/fx.c @@ -645,6 +645,7 @@ static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *n
switch (type->base_type) { + case HLSL_TYPE_DOUBLE: case HLSL_TYPE_HALF: case HLSL_TYPE_FLOAT: case HLSL_TYPE_BOOL:
From: Zebediah Figura zfigura@codeweavers.com
We want the base type to stop being a property of all types, and to stop using the same enumeration for objects and numeric types. The backend should do the work of translation; we want a more sensible and convenient representation for the compiler itself. --- libs/vkd3d-shader/d3dbc.c | 132 ++++++++++++++++++++++---------------- 1 file changed, 77 insertions(+), 55 deletions(-)
diff --git a/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d-shader/d3dbc.c index 1ad97adda..4685afa08 100644 --- a/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d-shader/d3dbc.c @@ -1522,72 +1522,94 @@ D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type)
D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type) { - switch (type->base_type) + switch (type->class) { - case HLSL_TYPE_BOOL: - return D3DXPT_BOOL; - /* Actually double behaves differently depending on DLL version: - * For <= 36, it maps to D3DXPT_FLOAT. - * For 37-40, it maps to zero (D3DXPT_VOID). - * For >= 41, it maps to 39, which is D3D_SVT_DOUBLE (note D3D_SVT_* - * values are mostly compatible with D3DXPT_*). - * However, the latter two cases look like bugs, and a reasonable - * application certainly wouldn't know what to do with them. - * For fx_2_0 it's always D3DXPT_FLOAT regardless of DLL version. */ - case HLSL_TYPE_DOUBLE: - case HLSL_TYPE_FLOAT: - case HLSL_TYPE_HALF: - return D3DXPT_FLOAT; - case HLSL_TYPE_INT: - case HLSL_TYPE_UINT: - return D3DXPT_INT; - case HLSL_TYPE_PIXELSHADER: - return D3DXPT_PIXELSHADER; - case HLSL_TYPE_SAMPLER: - switch (type->sampler_dim) + case HLSL_CLASS_SCALAR: + case HLSL_CLASS_VECTOR: + case HLSL_CLASS_MATRIX: + switch (type->base_type) { - case HLSL_SAMPLER_DIM_1D: - return D3DXPT_SAMPLER1D; - case HLSL_SAMPLER_DIM_2D: - return D3DXPT_SAMPLER2D; - case HLSL_SAMPLER_DIM_3D: - return D3DXPT_SAMPLER3D; - case HLSL_SAMPLER_DIM_CUBE: - return D3DXPT_SAMPLERCUBE; - case HLSL_SAMPLER_DIM_GENERIC: - return D3DXPT_SAMPLER; + case HLSL_TYPE_BOOL: + return D3DXPT_BOOL; + /* Actually double behaves differently depending on DLL version: + * For <= 36, it maps to D3DXPT_FLOAT. + * For 37-40, it maps to zero (D3DXPT_VOID). + * For >= 41, it maps to 39, which is D3D_SVT_DOUBLE (note D3D_SVT_* + * values are mostly compatible with D3DXPT_*). + * However, the latter two cases look like bugs, and a reasonable + * application certainly wouldn't know what to do with them. + * For fx_2_0 it's always D3DXPT_FLOAT regardless of DLL version. */ + case HLSL_TYPE_DOUBLE: + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + return D3DXPT_FLOAT; + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + return D3DXPT_INT; default: - ERR("Invalid dimension %#x.\n", type->sampler_dim); vkd3d_unreachable(); } - break; - case HLSL_TYPE_STRING: - return D3DXPT_STRING; - case HLSL_TYPE_TEXTURE: - switch (type->sampler_dim) + + case HLSL_CLASS_OBJECT: + switch (type->base_type) { - case HLSL_SAMPLER_DIM_1D: - return D3DXPT_TEXTURE1D; - case HLSL_SAMPLER_DIM_2D: - return D3DXPT_TEXTURE2D; - case HLSL_SAMPLER_DIM_3D: - return D3DXPT_TEXTURE3D; - case HLSL_SAMPLER_DIM_CUBE: - return D3DXPT_TEXTURECUBE; - case HLSL_SAMPLER_DIM_GENERIC: - return D3DXPT_TEXTURE; + case HLSL_TYPE_PIXELSHADER: + return D3DXPT_PIXELSHADER; + case HLSL_TYPE_SAMPLER: + switch (type->sampler_dim) + { + case HLSL_SAMPLER_DIM_1D: + return D3DXPT_SAMPLER1D; + case HLSL_SAMPLER_DIM_2D: + return D3DXPT_SAMPLER2D; + case HLSL_SAMPLER_DIM_3D: + return D3DXPT_SAMPLER3D; + case HLSL_SAMPLER_DIM_CUBE: + return D3DXPT_SAMPLERCUBE; + case HLSL_SAMPLER_DIM_GENERIC: + return D3DXPT_SAMPLER; + default: + ERR("Invalid dimension %#x.\n", type->sampler_dim); + vkd3d_unreachable(); + } + break; + case HLSL_TYPE_STRING: + return D3DXPT_STRING; + case HLSL_TYPE_TEXTURE: + switch (type->sampler_dim) + { + case HLSL_SAMPLER_DIM_1D: + return D3DXPT_TEXTURE1D; + case HLSL_SAMPLER_DIM_2D: + return D3DXPT_TEXTURE2D; + case HLSL_SAMPLER_DIM_3D: + return D3DXPT_TEXTURE3D; + case HLSL_SAMPLER_DIM_CUBE: + return D3DXPT_TEXTURECUBE; + case HLSL_SAMPLER_DIM_GENERIC: + return D3DXPT_TEXTURE; + default: + ERR("Invalid dimension %#x.\n", type->sampler_dim); + vkd3d_unreachable(); + } + break; + case HLSL_TYPE_VERTEXSHADER: + return D3DXPT_VERTEXSHADER; + case HLSL_TYPE_VOID: + return D3DXPT_VOID; default: - ERR("Invalid dimension %#x.\n", type->sampler_dim); vkd3d_unreachable(); } - break; - case HLSL_TYPE_VERTEXSHADER: - return D3DXPT_VERTEXSHADER; - case HLSL_TYPE_VOID: - return D3DXPT_VOID; - default: vkd3d_unreachable(); + + case HLSL_CLASS_ARRAY: + return hlsl_sm1_base_type(type->e.array.type); + + case HLSL_CLASS_STRUCT: + return D3DXPT_VOID; } + + vkd3d_unreachable(); }
static void write_sm1_type(struct vkd3d_bytecode_buffer *buffer, struct hlsl_type *type, unsigned int ctab_start)
From: Zebediah Figura zfigura@codeweavers.com
--- libs/vkd3d-shader/fx.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-)
diff --git a/libs/vkd3d-shader/fx.c b/libs/vkd3d-shader/fx.c index 3b5a4caf0..db1af5635 100644 --- a/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d-shader/fx.c @@ -401,14 +401,6 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co uint32_t name_offset, offset, size, stride, numeric_desc; uint32_t elements_count = 0; const char *name; - static const uint32_t variable_type[] = - { - [HLSL_CLASS_SCALAR] = 1, - [HLSL_CLASS_VECTOR] = 1, - [HLSL_CLASS_MATRIX] = 1, - [HLSL_CLASS_OBJECT] = 2, - [HLSL_CLASS_STRUCT] = 3, - }; struct hlsl_ctx *ctx = fx->ctx;
/* Resolve arrays to element type and number of elements. */ @@ -428,13 +420,19 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co case HLSL_CLASS_SCALAR: case HLSL_CLASS_VECTOR: case HLSL_CLASS_MATRIX: + put_u32_unaligned(buffer, 1); + break; + case HLSL_CLASS_OBJECT: + put_u32_unaligned(buffer, 2); + break; + case HLSL_CLASS_STRUCT: - put_u32_unaligned(buffer, variable_type[type->class]); + put_u32_unaligned(buffer, 3); break; - default: - hlsl_fixme(ctx, &ctx->location, "Writing type class %u is not implemented.", type->class); - return 0; + + case HLSL_CLASS_ARRAY: + vkd3d_unreachable(); }
size = stride = type->reg_size[HLSL_REGSET_NUMERIC] * sizeof(float);
From: Zebediah Figura zfigura@codeweavers.com
--- libs/vkd3d-shader/fx.c | 93 ++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 49 deletions(-)
diff --git a/libs/vkd3d-shader/fx.c b/libs/vkd3d-shader/fx.c index db1af5635..a8def84e4 100644 --- a/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d-shader/fx.c @@ -628,7 +628,6 @@ static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *n { struct vkd3d_bytecode_buffer *buffer = &fx->unstructured; uint32_t semantic_offset, offset, elements_count = 0, name_offset; - struct hlsl_ctx *ctx = fx->ctx; size_t i;
/* Resolve arrays to element type and number of elements. */ @@ -641,23 +640,6 @@ static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *n name_offset = write_string(name, fx); semantic_offset = write_string(semantic->name, fx);
- switch (type->base_type) - { - case HLSL_TYPE_DOUBLE: - case HLSL_TYPE_HALF: - case HLSL_TYPE_FLOAT: - case HLSL_TYPE_BOOL: - case HLSL_TYPE_INT: - case HLSL_TYPE_UINT: - case HLSL_TYPE_VOID: - case HLSL_TYPE_TEXTURE: - break; - default: - hlsl_fixme(ctx, &ctx->location, "Writing parameter type %u is not implemented.", - type->base_type); - return 0; - }; - offset = put_u32(buffer, hlsl_sm1_base_type(type)); put_u32(buffer, hlsl_sm1_class(type)); put_u32(buffer, name_offset); @@ -687,6 +669,9 @@ static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *n for (i = 0; i < type->e.record.field_count; ++i) { const struct hlsl_struct_field *field = &type->e.record.fields[i]; + + /* Validated in check_invalid_object_fields(). */ + assert(hlsl_is_numeric_type(field->type)); write_fx_2_parameter(field->type, field->name, &field->semantic, fx); } } @@ -774,44 +759,54 @@ static uint32_t write_fx_2_initial_value(const struct hlsl_ir_var *var, struct f return offset; }
-static bool is_type_supported_fx_2(const struct hlsl_type *type) +static bool is_type_supported_fx_2(struct hlsl_ctx *ctx, const struct hlsl_type *type, + const struct vkd3d_shader_location *loc) { - type = hlsl_get_multiarray_element_type(type); - - if (type->class == HLSL_CLASS_STRUCT) - return true; - - switch (type->base_type) + switch (type->class) { - case HLSL_TYPE_FLOAT: - case HLSL_TYPE_HALF: - case HLSL_TYPE_DOUBLE: - case HLSL_TYPE_INT: - case HLSL_TYPE_UINT: - case HLSL_TYPE_BOOL: - case HLSL_TYPE_PIXELSHADER: - case HLSL_TYPE_VERTEXSHADER: - case HLSL_TYPE_STRING: + case HLSL_CLASS_STRUCT: + /* Note that the fields must all be numeric; this was validated in + * check_invalid_object_fields(). */ return true; - case HLSL_TYPE_TEXTURE: - case HLSL_TYPE_SAMPLER: - switch (type->sampler_dim) + + case HLSL_CLASS_SCALAR: + case HLSL_CLASS_VECTOR: + case HLSL_CLASS_MATRIX: + return true; + + case HLSL_CLASS_ARRAY: + return is_type_supported_fx_2(ctx, type->e.array.type, loc); + + case HLSL_CLASS_OBJECT: + switch (type->base_type) { - case HLSL_SAMPLER_DIM_1D: - case HLSL_SAMPLER_DIM_2D: - case HLSL_SAMPLER_DIM_3D: - case HLSL_SAMPLER_DIM_CUBE: - case HLSL_SAMPLER_DIM_GENERIC: - return true; + case HLSL_TYPE_TEXTURE: + switch (type->sampler_dim) + { + case HLSL_SAMPLER_DIM_1D: + case HLSL_SAMPLER_DIM_2D: + case HLSL_SAMPLER_DIM_3D: + case HLSL_SAMPLER_DIM_CUBE: + case HLSL_SAMPLER_DIM_GENERIC: + return true; + default: + return false; + } + break; + + case HLSL_TYPE_SAMPLER: + case HLSL_TYPE_STRING: + case HLSL_TYPE_PIXELSHADER: + case HLSL_TYPE_VERTEXSHADER: + hlsl_fixme(ctx, loc, "Write fx 2.0 parameter object type %#x.", type->base_type); + return false; + default: - ; + return false; } - break; - default: - return false; }
- return false; + vkd3d_unreachable(); }
static void write_fx_2_parameters(struct fx_write_context *fx) @@ -827,7 +822,7 @@ static void write_fx_2_parameters(struct fx_write_context *fx)
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { - if (!is_type_supported_fx_2(var->data_type)) + if (!is_type_supported_fx_2(ctx, var->data_type, &var->loc)) continue;
desc_offset = write_fx_2_parameter(var->data_type, var->name, &var->semantic, fx);
From: Zebediah Figura zfigura@codeweavers.com
--- libs/vkd3d-shader/fx.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-)
diff --git a/libs/vkd3d-shader/fx.c b/libs/vkd3d-shader/fx.c index a8def84e4..bb9e37fa3 100644 --- a/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d-shader/fx.c @@ -730,7 +730,7 @@ static uint32_t write_fx_2_initial_value(const struct hlsl_ir_var *var, struct f { struct vkd3d_bytecode_buffer *buffer = &fx->unstructured; const struct hlsl_type *type = var->data_type; - uint32_t i, offset, size, elements_count = 1; + uint32_t offset, size, elements_count = 1;
size = get_fx_2_type_size(type);
@@ -740,20 +740,27 @@ static uint32_t write_fx_2_initial_value(const struct hlsl_ir_var *var, struct f type = hlsl_get_multiarray_element_type(type); }
- if (type->class == HLSL_CLASS_OBJECT) - { - /* Objects are given sequential ids. */ - offset = put_u32(buffer, fx->object_variable_count++); - for (i = 1; i < elements_count; ++i) - put_u32(buffer, fx->object_variable_count++); - } - else + /* Note that struct fields must all be numeric; + * this was validated in check_invalid_object_fields(). */ + switch (type->class) { - /* FIXME: write actual initial value */ - offset = put_u32(buffer, 0); + case HLSL_CLASS_SCALAR: + case HLSL_CLASS_VECTOR: + case HLSL_CLASS_MATRIX: + case HLSL_CLASS_STRUCT: + /* FIXME: write actual initial value */ + offset = put_u32(buffer, 0); + + for (uint32_t i = 1; i < size / sizeof(uint32_t); ++i) + put_u32(buffer, 0); + break;
- for (i = 1; i < size / sizeof(uint32_t); ++i) - put_u32(buffer, 0); + default: + /* Objects are given sequential ids. */ + offset = put_u32(buffer, fx->object_variable_count++); + for (uint32_t i = 1; i < elements_count; ++i) + put_u32(buffer, fx->object_variable_count++); + break; }
return offset;