Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
-- v2: vkd3d-shader/fx: Remove newlines from fixme messages. vkd3d-shader/fx: Add initial support for writing fx_2_0 parameters. vkd3d-shader/fx: Populate global variables list during context initialization. vkd3d-shader/fx: Fix an instruction block leak. vkd3d-shader/fx: Use type writing helper only for fx_4+.
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/fx.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/libs/vkd3d-shader/fx.c b/libs/vkd3d-shader/fx.c index fdf132e9e..426826e3d 100644 --- a/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d-shader/fx.c @@ -61,7 +61,6 @@ struct fx_write_context; struct fx_write_context_ops { uint32_t (*write_string)(const char *string, struct fx_write_context *fx); - uint32_t (*write_type)(const struct hlsl_type *type, struct fx_write_context *fx); void (*write_technique)(struct hlsl_ir_var *var, struct fx_write_context *fx); void (*write_pass)(struct hlsl_ir_var *var, struct fx_write_context *fx); bool are_child_effects_supported; @@ -112,12 +111,16 @@ static void write_pass(struct hlsl_ir_var *var, struct fx_write_context *fx) fx->ops->write_pass(var, fx); }
+static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_context *fx); + static uint32_t write_type(const struct hlsl_type *type, struct fx_write_context *fx) { struct type_entry *type_entry; unsigned int elements_count; const char *name;
+ assert(fx->ctx->profile->major_version >= 4); + if (type->class == HLSL_CLASS_ARRAY) { name = hlsl_get_multiarray_element_type(type)->name; @@ -143,7 +146,7 @@ static uint32_t write_type(const struct hlsl_type *type, struct fx_write_context if (!(type_entry = hlsl_alloc(fx->ctx, sizeof(*type_entry)))) return 0;
- type_entry->offset = fx->ops->write_type(type, fx); + type_entry->offset = write_fx_4_type(type, fx); type_entry->name = name; type_entry->elements_count = elements_count;
@@ -692,7 +695,6 @@ static int hlsl_fx_2_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) static const struct fx_write_context_ops fx_4_ops = { .write_string = write_fx_4_string, - .write_type = write_fx_4_type, .write_technique = write_fx_4_technique, .write_pass = write_fx_4_pass, .are_child_effects_supported = true,
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/fx.c b/libs/vkd3d-shader/fx.c index 426826e3d..f68d38fa0 100644 --- a/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d-shader/fx.c @@ -840,7 +840,7 @@ static void write_buffers(struct fx_write_context *fx)
hlsl_block_init(&block); hlsl_prepend_global_uniform_copy(fx->ctx, &block); - hlsl_block_init(&block); + hlsl_block_cleanup(&block); hlsl_calculate_buffer_offsets(fx->ctx);
LIST_FOR_EACH_ENTRY(buffer, &fx->ctx->buffers, struct hlsl_buffer, entry)
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/fx.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/libs/vkd3d-shader/fx.c b/libs/vkd3d-shader/fx.c index f68d38fa0..aaa9f0155 100644 --- a/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d-shader/fx.c @@ -159,6 +159,7 @@ static void fx_write_context_init(struct hlsl_ctx *ctx, const struct fx_write_co struct fx_write_context *fx) { unsigned int version = ctx->profile->major_version; + struct hlsl_block block;
memset(fx, 0, sizeof(*fx));
@@ -184,6 +185,11 @@ static void fx_write_context_init(struct hlsl_ctx *ctx, const struct fx_write_co list_init(&fx->types);
fx->child_effect = fx->ops->are_child_effects_supported && ctx->child_effect; + + hlsl_block_init(&block); + hlsl_prepend_global_uniform_copy(fx->ctx, &block); + hlsl_block_cleanup(&block); + hlsl_calculate_buffer_offsets(fx->ctx); }
static int fx_write_context_cleanup(struct fx_write_context *fx) @@ -836,12 +842,6 @@ static void write_fx_4_buffer(struct hlsl_buffer *b, struct fx_write_context *fx static void write_buffers(struct fx_write_context *fx) { struct hlsl_buffer *buffer; - struct hlsl_block block; - - hlsl_block_init(&block); - hlsl_prepend_global_uniform_copy(fx->ctx, &block); - hlsl_block_cleanup(&block); - hlsl_calculate_buffer_offsets(fx->ctx);
LIST_FOR_EACH_ENTRY(buffer, &fx->ctx->buffers, struct hlsl_buffer, entry) {
From: Nikolay Sivov nsivov@codeweavers.com
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 + .../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 57dd0258a..69f14c2f6 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 aaa9f0155..718ba8aaa 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 9781dd339..559cda140 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -1360,6 +1360,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 7c6a8947a..8801ed1f7 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;
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/fx.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/libs/vkd3d-shader/fx.c b/libs/vkd3d-shader/fx.c index 718ba8aaa..fe1a350a2 100644 --- a/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d-shader/fx.c @@ -312,7 +312,7 @@ static uint32_t get_fx_4_numeric_type_description(const struct hlsl_type *type, value |= numeric_type_class[type->class]; break; default: - hlsl_fixme(ctx, &ctx->location, "Not implemented for type class %u.\n", type->class); + hlsl_fixme(ctx, &ctx->location, "Not implemented for type class %u.", type->class); return 0; }
@@ -325,7 +325,7 @@ static uint32_t get_fx_4_numeric_type_description(const struct hlsl_type *type, value |= (numeric_base_type[type->base_type] << NUMERIC_BASE_TYPE_SHIFT); break; default: - hlsl_fixme(ctx, &ctx->location, "Not implemented for base type %u.\n", type->base_type); + hlsl_fixme(ctx, &ctx->location, "Not implemented for base type %u.", type->base_type); return 0; }
@@ -426,7 +426,7 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co put_u32_unaligned(buffer, variable_type[type->class]); break; default: - hlsl_fixme(ctx, &ctx->location, "Writing type class %u is not implemented.\n", type->class); + hlsl_fixme(ctx, &ctx->location, "Writing type class %u is not implemented.", type->class); return 0; }
@@ -508,7 +508,7 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co put_u32_unaligned(buffer, uav_type[type->sampler_dim]); break; default: - hlsl_fixme(ctx, &ctx->location, "Object type %u is not supported.\n", type->base_type); + hlsl_fixme(ctx, &ctx->location, "Object type %u is not supported.", type->base_type); return 0; } } @@ -928,7 +928,7 @@ static void write_fx_4_object_variable(struct hlsl_ir_var *var, struct fx_write_ ++fx->shader_variable_count; break; default: - hlsl_fixme(ctx, &ctx->location, "Writing initializer for object type %u is not implemented.\n", + hlsl_fixme(ctx, &ctx->location, "Writing initializer for object type %u is not implemented.", type->base_type); }
On Wed Mar 13 19:53:48 2024 +0000, Zebediah Figura wrote:
extern_vars?
Yes, switched to that now.
On Wed Mar 13 19:53:49 2024 +0000, Zebediah Figura wrote:
This belongs in an earlier patch.
Right, it was a later fixup. Changed now.
On Wed Mar 13 19:53:48 2024 +0000, Zebediah Figura wrote:
This is an even worse case, because if I'm not mistaken we can write zero annotations and succeed even when there should be some. I know it's part of the initial fx bringup, and there's other similar problems, but at least in this case it seems easy enough to replace the single "FIXME" comment with something like "if (!list_empty(var->annotations->vars)) hlsl_fixme(...)", and that would avoid that problem.
Yes, that makes sense. I'll do that as a separate patch.