Module: vkd3d Branch: master Commit: 4fc15d4b4adbc08614656bc33c92429b6dc40e65 URL: https://gitlab.winehq.org/wine/vkd3d/-/commit/4fc15d4b4adbc08614656bc33c9242...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Tue Feb 13 12:52:11 2024 +0100
vkd3d-shader/fx: Add initial support for writing fx_2_0 parameters.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
---
libs/vkd3d-shader/d3dbc.c | 8 +- libs/vkd3d-shader/fx.c | 155 +++++++++++++++++++++- libs/vkd3d-shader/hlsl.h | 2 + tests/hlsl/effect-shader-objects-fx_2.shader_test | 2 +- 4 files changed, 159 insertions(+), 8 deletions(-)
diff --git a/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d-shader/d3dbc.c index 9f153a1d..3b935b07 100644 --- a/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d-shader/d3dbc.c @@ -1494,12 +1494,12 @@ static uint32_t sm1_version(enum vkd3d_shader_type type, unsigned int major, uns return D3DPS_VERSION(major, minor); }
-static D3DXPARAMETER_CLASS sm1_class(const struct hlsl_type *type) +D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type) { switch (type->class) { case HLSL_CLASS_ARRAY: - return sm1_class(type->e.array.type); + return hlsl_sm1_class(type->e.array.type); case HLSL_CLASS_MATRIX: assert(type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK); if (type->modifiers & HLSL_MODIFIER_COLUMN_MAJOR) @@ -1520,7 +1520,7 @@ static D3DXPARAMETER_CLASS sm1_class(const struct hlsl_type *type) } }
-static D3DXPARAMETER_TYPE sm1_base_type(const struct hlsl_type *type) +D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type) { switch (type->base_type) { @@ -1615,7 +1615,7 @@ static void write_sm1_type(struct vkd3d_bytecode_buffer *buffer, struct hlsl_typ } }
- type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(sm1_class(type), sm1_base_type(array_type))); + type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(hlsl_sm1_class(type), hlsl_sm1_base_type(array_type))); put_u32(buffer, vkd3d_make_u32(type->dimy, type->dimx)); put_u32(buffer, vkd3d_make_u32(array_size, field_count)); put_u32(buffer, fields_offset); diff --git a/libs/vkd3d-shader/fx.c b/libs/vkd3d-shader/fx.c index aaa9f015..718ba8aa 100644 --- a/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d-shader/fx.c @@ -86,6 +86,7 @@ struct fx_write_context uint32_t object_variable_count; uint32_t shared_object_count; uint32_t shader_variable_count; + uint32_t parameter_count; int status;
bool child_effect; @@ -613,6 +614,73 @@ static uint32_t write_fx_2_string(const char *string, struct fx_write_context *f return offset; }
+static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *name, const struct hlsl_semantic *semantic, + struct fx_write_context *fx) +{ + 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. */ + if (type->class == HLSL_CLASS_ARRAY) + { + elements_count = hlsl_get_multiarray_size(type); + type = hlsl_get_multiarray_element_type(type); + } + + name_offset = write_string(name, fx); + semantic_offset = write_string(semantic->name, fx); + + switch (type->base_type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_BOOL: + case HLSL_TYPE_INT: + case HLSL_TYPE_VOID: + 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); + put_u32(buffer, semantic_offset); + put_u32(buffer, elements_count); + + switch (type->class) + { + case HLSL_CLASS_VECTOR: + put_u32(buffer, type->dimx); + put_u32(buffer, type->dimy); + break; + case HLSL_CLASS_SCALAR: + case HLSL_CLASS_MATRIX: + put_u32(buffer, type->dimy); + put_u32(buffer, type->dimx); + break; + case HLSL_CLASS_STRUCT: + put_u32(buffer, type->e.record.field_count); + break; + default: + ; + } + + if (type->class == HLSL_CLASS_STRUCT) + { + for (i = 0; i < type->e.record.field_count; ++i) + { + const struct hlsl_struct_field *field = &type->e.record.fields[i]; + write_fx_2_parameter(field->type, field->name, &field->semantic, fx); + } + } + + return offset; +} + static void write_fx_2_technique(struct hlsl_ir_var *var, struct fx_write_context *fx) { struct vkd3d_bytecode_buffer *buffer = &fx->structured; @@ -635,6 +703,86 @@ static void write_fx_2_technique(struct hlsl_ir_var *var, struct fx_write_contex set_u32(buffer, count_offset, count); }
+static uint32_t get_fx_2_type_size(const struct hlsl_type *type) +{ + uint32_t size = 0, elements_count; + size_t i; + + if (type->class == HLSL_CLASS_ARRAY) + { + elements_count = hlsl_get_multiarray_size(type); + type = hlsl_get_multiarray_element_type(type); + return get_fx_2_type_size(type) * elements_count; + } + else if (type->class == HLSL_CLASS_STRUCT) + { + for (i = 0; i < type->e.record.field_count; ++i) + { + const struct hlsl_struct_field *field = &type->e.record.fields[i]; + size += get_fx_2_type_size(field->type); + } + + return size; + } + + return type->dimx * type->dimy * sizeof(float); +} + +static uint32_t write_fx_2_initial_value(const struct hlsl_ir_var *var, struct fx_write_context *fx) +{ + struct vkd3d_bytecode_buffer *buffer = &fx->unstructured; + const struct hlsl_type *type = var->data_type; + uint32_t i, offset, size, elements_count = 1; + + size = get_fx_2_type_size(type); + + if (type->class == HLSL_CLASS_ARRAY) + { + elements_count = hlsl_get_multiarray_size(type); + 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 + { + /* FIXME: write actual initial value */ + offset = put_u32(buffer, 0); + + for (i = 1; i < size / sizeof(uint32_t); ++i) + put_u32(buffer, 0); + } + + return offset; +} + +static void write_fx_2_parameters(struct fx_write_context *fx) +{ + struct vkd3d_bytecode_buffer *buffer = &fx->structured; + uint32_t desc_offset, value_offset; + struct hlsl_ir_var *var; + + LIST_FOR_EACH_ENTRY(var, &fx->ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + desc_offset = write_fx_2_parameter(var->data_type, var->name, &var->semantic, fx); + value_offset = write_fx_2_initial_value(var, fx); + + put_u32(buffer, desc_offset); /* Parameter description */ + put_u32(buffer, value_offset); /* Value */ + put_u32(buffer, 0); /* Flags */ + + put_u32(buffer, 0); /* Annotations count */ + /* FIXME: write annotations */ + + ++fx->parameter_count; + } +} + static const struct fx_write_context_ops fx_2_ops = { .write_string = write_fx_2_string, @@ -644,9 +792,9 @@ static const struct fx_write_context_ops fx_2_ops =
static int hlsl_fx_2_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) { + uint32_t offset, size, technique_count, parameter_count; struct vkd3d_bytecode_buffer buffer = { 0 }; struct vkd3d_bytecode_buffer *structured; - uint32_t offset, size, technique_count; struct fx_write_context fx;
fx_write_context_init(ctx, &fx_2_ops, &fx); @@ -658,12 +806,13 @@ static int hlsl_fx_2_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) put_u32(&buffer, 0xfeff0901); /* Version. */ offset = put_u32(&buffer, 0);
- put_u32(structured, 0); /* Parameter count */ + parameter_count = put_u32(structured, 0); /* Parameter count */ technique_count = put_u32(structured, 0); put_u32(structured, 0); /* Unknown */ put_u32(structured, 0); /* Object count */
- /* TODO: parameters */ + write_fx_2_parameters(&fx); + set_u32(structured, parameter_count, fx.parameter_count);
write_techniques(ctx->globals, &fx); set_u32(structured, technique_count, fx.technique_count); diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index fd6c4f16..93ec67d0 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -1363,6 +1363,8 @@ bool hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, struct hlsl_ir_node *, void *), struct hlsl_block *block, void *context);
+D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type); +D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type); bool hlsl_sm1_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic, bool output, D3DSHADER_PARAM_REGISTER_TYPE *type, unsigned int *reg); bool hlsl_sm1_usage_from_semantic(const struct hlsl_semantic *semantic, D3DDECLUSAGE *usage, uint32_t *usage_idx); diff --git a/tests/hlsl/effect-shader-objects-fx_2.shader_test b/tests/hlsl/effect-shader-objects-fx_2.shader_test index 7c6a8947..8801ed1f 100644 --- a/tests/hlsl/effect-shader-objects-fx_2.shader_test +++ b/tests/hlsl/effect-shader-objects-fx_2.shader_test @@ -26,7 +26,7 @@ float4 main() : sv_target return 0; }
-[effect] +[effect todo] vertexshader vs1; verteXshadeR vs2; pixelshader ps1;