-- v2: vkd3d-shader/fx: Do not align structured data section. vkd3d-shader/fx: Add initial support for writing buffers descriptions. vkd3d-shader/fx: Mark constant buffers empty on creation. vkd3d-shader/fx: Do not align strings for fx_4/fx_5 profiles.
From: Nikolay Sivov nsivov@codeweavers.com
The helper will need to access group annotations later, and these are available for variables.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/fx.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/libs/vkd3d-shader/fx.c b/libs/vkd3d-shader/fx.c index e1459f76c..b56dfa216 100644 --- a/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d-shader/fx.c @@ -227,10 +227,10 @@ static void write_techniques(struct hlsl_scope *scope, struct fx_write_context * set_status(fx, fx->structured.status); }
-static void write_group(struct hlsl_scope *scope, const char *name, struct fx_write_context *fx) +static void write_group(struct hlsl_ir_var *var, struct fx_write_context *fx) { struct vkd3d_bytecode_buffer *buffer = &fx->structured; - uint32_t name_offset = write_string(name, fx); + uint32_t name_offset = write_string(var ? var->name : NULL, fx); uint32_t count_offset, count;
put_u32(buffer, name_offset); @@ -238,14 +238,15 @@ static void write_group(struct hlsl_scope *scope, const char *name, struct fx_wr put_u32(buffer, 0); /* Annotation count */
count = fx->technique_count; - write_techniques(scope, fx); + write_techniques(var ? var->scope : fx->ctx->globals, fx); set_u32(buffer, count_offset, fx->technique_count - count);
++fx->group_count; }
-static void write_groups(struct hlsl_scope *scope, struct fx_write_context *fx) +static void write_groups(struct fx_write_context *fx) { + struct hlsl_scope *scope = fx->ctx->globals; bool needs_default_group = false; struct hlsl_ir_var *var;
@@ -259,13 +260,13 @@ static void write_groups(struct hlsl_scope *scope, struct fx_write_context *fx) }
if (needs_default_group) - write_group(scope, NULL, fx); + write_group(NULL, fx); LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry) { const struct hlsl_type *type = var->data_type;
if (type->base_type == HLSL_TYPE_EFFECT_GROUP) - write_group(var->scope, var->name, fx); + write_group(var, fx); } }
@@ -444,7 +445,7 @@ static int hlsl_fx_5_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) /* TODO: objects */ /* TODO: interface variables */
- write_groups(ctx->globals, &fx); + write_groups(&fx);
put_u32(&buffer, 0xfeff2001); /* Version. */ put_u32(&buffer, 0); /* Buffer count. */
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/fx.c | 2 +- libs/vkd3d-shader/vkd3d_shader_main.c | 14 ++++++++++++-- libs/vkd3d-shader/vkd3d_shader_private.h | 1 + 3 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/libs/vkd3d-shader/fx.c b/libs/vkd3d-shader/fx.c index b56dfa216..ac7ffae8c 100644 --- a/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d-shader/fx.c @@ -145,7 +145,7 @@ static uint32_t write_fx_4_string(const char *string, struct fx_write_context *f if (!(string_entry = hlsl_alloc(fx->ctx, sizeof(*string_entry)))) return 0;
- string_entry->offset = put_string(&fx->unstructured, string); + string_entry->offset = bytecode_put_bytes_unaligned(&fx->unstructured, string, strlen(string) + 1); string_entry->string = string;
rb_put(&fx->strings, string, &string_entry->entry); diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index 1ef8d9494..2210d793f 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -366,9 +366,9 @@ size_t bytecode_align(struct vkd3d_bytecode_buffer *buffer) return aligned_size; }
-size_t bytecode_put_bytes(struct vkd3d_bytecode_buffer *buffer, const void *bytes, size_t size) +static size_t bytecode_put_bytes_internal(struct vkd3d_bytecode_buffer *buffer, const void *bytes, size_t size, bool align) { - size_t offset = bytecode_align(buffer); + size_t offset = align ? bytecode_align(buffer) : buffer->size;
if (buffer->status) return offset; @@ -383,6 +383,16 @@ size_t bytecode_put_bytes(struct vkd3d_bytecode_buffer *buffer, const void *byte return offset; }
+size_t bytecode_put_bytes(struct vkd3d_bytecode_buffer *buffer, const void *bytes, size_t size) +{ + return bytecode_put_bytes_internal(buffer, bytes, size, true); +} + +size_t bytecode_put_bytes_unaligned(struct vkd3d_bytecode_buffer *buffer, const void *bytes, size_t size) +{ + return bytecode_put_bytes_internal(buffer, bytes, size, false); +} + size_t bytecode_reserve_bytes(struct vkd3d_bytecode_buffer *buffer, size_t size) { size_t offset = bytecode_align(buffer); diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 3d043c249..6a8c2e98c 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -1415,6 +1415,7 @@ struct vkd3d_bytecode_buffer /* Align to the next 4-byte offset, and return that offset. */ size_t bytecode_align(struct vkd3d_bytecode_buffer *buffer); size_t bytecode_put_bytes(struct vkd3d_bytecode_buffer *buffer, const void *bytes, size_t size); +size_t bytecode_put_bytes_unaligned(struct vkd3d_bytecode_buffer *buffer, const void *bytes, size_t size); size_t bytecode_reserve_bytes(struct vkd3d_bytecode_buffer *buffer, size_t size); void set_u32(struct vkd3d_bytecode_buffer *buffer, size_t offset, uint32_t value); void set_string(struct vkd3d_bytecode_buffer *buffer, size_t offset, const char *string, size_t length);
From: Nikolay Sivov nsivov@codeweavers.com
This is useful for implicit $Globals buffer when writing effects binaries. It should not be written out if there is no global variables, but when there are some, it should appear first in order.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 1 + libs/vkd3d-shader/hlsl.h | 2 ++ libs/vkd3d-shader/hlsl.y | 1 + 3 files changed, 4 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 04c37498d..7522c270d 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -2012,6 +2012,7 @@ struct hlsl_buffer *hlsl_new_buffer(struct hlsl_ctx *ctx, enum hlsl_buffer_type if (reservation) buffer->reservation = *reservation; buffer->loc = *loc; + buffer->empty = true; list_add_tail(&ctx->buffers, &buffer->entry); return buffer; } diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 58188ce6f..57d7ad781 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -804,6 +804,8 @@ struct hlsl_buffer
bool manually_packed_elements; bool automatically_packed_elements; + /* Marks buffers with no elements. Implicit buffers are created like that. */ + bool empty; };
struct hlsl_ctx diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 8dc353e11..1981390e6 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2237,6 +2237,7 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) }
var->buffer = ctx->cur_buffer; + var->buffer->empty = false;
if (var->buffer == ctx->globals_buffer) {
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/fx.c | 337 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 319 insertions(+), 18 deletions(-)
diff --git a/libs/vkd3d-shader/fx.c b/libs/vkd3d-shader/fx.c index ac7ffae8c..2930e6dc2 100644 --- a/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d-shader/fx.c @@ -20,6 +20,11 @@
#include "hlsl.h"
+static inline size_t put_u32_unaligned(struct vkd3d_bytecode_buffer *buffer, uint32_t value) +{ + return bytecode_put_bytes_unaligned(buffer, &value, sizeof(value)); +} + struct string_entry { struct rb_entry entry; @@ -28,6 +33,13 @@ struct string_entry uint32_t offset; };
+struct type_entry +{ + struct rb_entry entry; + const char *name; + uint32_t offset; +}; + static int string_storage_compare(const void *key, const struct rb_entry *entry) { struct string_entry *string_entry = RB_ENTRY_VALUE(entry, struct string_entry, entry); @@ -43,11 +55,27 @@ static void string_storage_destroy(struct rb_entry *entry, void *context) vkd3d_free(string_entry); }
+static int type_storage_compare(const void *key, const struct rb_entry *entry) +{ + struct type_entry *type_entry = RB_ENTRY_VALUE(entry, struct type_entry, entry); + const char *name = key; + + return strcmp(name, type_entry->name); +} + +static void type_storage_destroy(struct rb_entry *entry, void *context) +{ + struct type_entry *type_entry = RB_ENTRY_VALUE(entry, struct type_entry, entry); + + vkd3d_free(type_entry); +} + 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); }; @@ -60,17 +88,28 @@ struct fx_write_context struct vkd3d_bytecode_buffer structured;
struct rb_tree strings; + struct rb_tree types;
unsigned int min_technique_version; unsigned int max_technique_version;
uint32_t technique_count; uint32_t group_count; + uint32_t buffer_count; + uint32_t numeric_variable_count; int status;
const struct fx_write_context_ops *ops; };
+static void set_status(struct fx_write_context *fx, int status) +{ + if (fx->status < 0) + return; + if (status < 0) + fx->status = status; +} + static uint32_t write_string(const char *string, struct fx_write_context *fx) { return fx->ops->write_string(string, fx); @@ -81,6 +120,28 @@ static void write_pass(struct hlsl_ir_var *var, struct fx_write_context *fx) fx->ops->write_pass(var, fx); }
+static uint32_t write_type(const struct hlsl_type *type, struct fx_write_context *fx) +{ + struct type_entry *type_entry; + struct rb_entry *entry; + + if ((entry = rb_get(&fx->types, type->name))) + { + type_entry = RB_ENTRY_VALUE(entry, struct type_entry, entry); + return type_entry->offset; + } + + if (!(type_entry = hlsl_alloc(fx->ctx, sizeof(*type_entry)))) + return 0; + + type_entry->offset = fx->ops->write_type(type, fx); + type_entry->name = type->name; + + rb_put(&fx->types, type->name, &type_entry->entry); + + return type_entry->offset; +} + static void fx_write_context_init(struct hlsl_ctx *ctx, const struct fx_write_context_ops *ops, struct fx_write_context *fx) { @@ -107,12 +168,15 @@ static void fx_write_context_init(struct hlsl_ctx *ctx, const struct fx_write_co }
rb_init(&fx->strings, string_storage_compare); + rb_init(&fx->types, type_storage_compare); }
static int fx_write_context_cleanup(struct fx_write_context *fx) { int status = fx->status; + rb_destroy(&fx->strings, string_storage_destroy, NULL); + rb_destroy(&fx->types, type_storage_destroy, NULL);
return status; } @@ -181,6 +245,157 @@ static void write_fx_2_pass(struct hlsl_ir_var *var, struct fx_write_context *fx /* TODO: assignments */ }
+static uint32_t get_fx_4_type_size(const struct hlsl_type *type) +{ + uint32_t elements_count; + + elements_count = hlsl_get_multiarray_size(type); + type = hlsl_get_multiarray_element_type(type); + + return type->reg_size[HLSL_REGSET_NUMERIC] * sizeof(float) * elements_count; +} + +static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_context *fx) +{ + struct fx_4_numeric_type + { + uint32_t type_class : 3; + uint32_t base_type : 5; + uint32_t rows : 3; + uint32_t columns : 3; + uint32_t column_major : 1; + uint32_t unknown : 17; + }; + struct vkd3d_bytecode_buffer *buffer = &fx->unstructured; + uint32_t name_offset, offset, size; + uint32_t elements_count = 0; + union + { + struct fx_4_numeric_type type; + uint32_t data; + } numeric_desc; + 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, + }; + STATIC_ASSERT(sizeof(numeric_desc) == sizeof(uint32_t)); + + name_offset = write_string(type->name, fx); + offset = put_u32_unaligned(buffer, name_offset); + + /* 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); + } + + switch (type->class) + { + case HLSL_CLASS_SCALAR: + case HLSL_CLASS_VECTOR: + case HLSL_CLASS_MATRIX: + case HLSL_CLASS_OBJECT: + case HLSL_CLASS_STRUCT: + put_u32_unaligned(buffer, variable_type[type->class]); + break; + default: + FIXME("Writing type class %u is not implemented.\n", type->class); + set_status(fx, VKD3D_ERROR_NOT_IMPLEMENTED); + return 0; + } + + size = type->reg_size[HLSL_REGSET_NUMERIC] * sizeof(float); + + put_u32_unaligned(buffer, elements_count); + put_u32_unaligned(buffer, size); /* Total size. */ + put_u32_unaligned(buffer, align(size, 4 * sizeof(float))); /* Stride. */ + put_u32_unaligned(buffer, size); + + if (type->class == HLSL_CLASS_STRUCT) + { + size_t i; + + put_u32_unaligned(buffer, type->e.record.field_count); + for (i = 0; i < type->e.record.field_count; ++i) + { + const struct hlsl_struct_field *field = &type->e.record.fields[i]; + uint32_t semantic_offset, field_type_offset; + + name_offset = write_string(field->name, fx); + semantic_offset = write_string(field->semantic.name, fx); + field_type_offset = write_type(field->type, fx); + + put_u32_unaligned(buffer, name_offset); + put_u32_unaligned(buffer, semantic_offset); + put_u32_unaligned(buffer, field->reg_offset[HLSL_REGSET_NUMERIC]); + put_u32_unaligned(buffer, field_type_offset); + } + } + else if (type->class == HLSL_CLASS_OBJECT) + { + FIXME("Object types are not supported.\n"); + set_status(fx, VKD3D_ERROR_NOT_IMPLEMENTED); + return 0; + } + else /* Numeric type */ + { + static const uint32_t numeric_type_class[] = + { + [HLSL_CLASS_SCALAR] = 1, + [HLSL_CLASS_VECTOR] = 2, + [HLSL_CLASS_MATRIX] = 3, + }; + + static const uint32_t numeric_base_type[] = + { + [HLSL_TYPE_FLOAT] = 1, + [HLSL_TYPE_INT ] = 2, + [HLSL_TYPE_UINT ] = 3, + [HLSL_TYPE_BOOL ] = 4, + }; + + switch (type->class) + { + case HLSL_CLASS_SCALAR: + case HLSL_CLASS_VECTOR: + case HLSL_CLASS_MATRIX: + numeric_desc.type.type_class = numeric_type_class[type->class]; + break; + default: + FIXME("Unexpected type class %u.\n", type->class); + set_status(fx, VKD3D_ERROR_NOT_IMPLEMENTED); + return 0; + } + + switch (type->base_type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + case HLSL_TYPE_BOOL: + numeric_desc.type.base_type = numeric_base_type[type->base_type]; + break; + default: + FIXME("Unexpected base type %u.\n", type->base_type); + set_status(fx, VKD3D_ERROR_NOT_IMPLEMENTED); + return 0; + } + + numeric_desc.type.rows = type->dimx; + numeric_desc.type.columns = type->dimy; + numeric_desc.type.column_major = !!(type->modifiers & HLSL_MODIFIER_COLUMN_MAJOR); + numeric_desc.type.unknown = 0; + put_u32_unaligned(buffer, numeric_desc.data); + } + + return offset; +} + static void write_fx_4_technique(struct hlsl_ir_var *var, struct fx_write_context *fx) { struct vkd3d_bytecode_buffer *buffer = &fx->structured; @@ -202,14 +417,6 @@ static void write_fx_4_technique(struct hlsl_ir_var *var, struct fx_write_contex set_u32(buffer, count_offset, count); }
-static void set_status(struct fx_write_context *fx, int status) -{ - if (fx->status < 0) - return; - if (status < 0) - fx->status = status; -} - static void write_techniques(struct hlsl_scope *scope, struct fx_write_context *fx) { struct hlsl_ir_var *var; @@ -367,21 +574,115 @@ 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, };
+static void write_fx_4_variable(struct hlsl_ir_var *var, struct fx_write_context *fx) +{ + struct vkd3d_bytecode_buffer *buffer = &fx->structured; + uint32_t semantic_offset, flags = 0; + uint32_t name_offset, type_offset; + enum fx_4_variable_flags + { + HAS_EXPLICIT_BIND_POINT = 0x4, + }; + + /* Explicit bind point. */ + if (var->reg_reservation.reg_type) + flags |= HAS_EXPLICIT_BIND_POINT; + + type_offset = write_type(var->data_type, fx); + name_offset = write_string(var->name, fx); + semantic_offset = write_string(var->semantic.name, fx); + + put_u32(buffer, name_offset); + put_u32(buffer, type_offset); + + semantic_offset = put_u32(buffer, semantic_offset); /* Semantic */ + put_u32(buffer, var->buffer_offset); /* Offset in the constant buffer */ + put_u32(buffer, 0); /* FIXME: default value offset */ + put_u32(buffer, flags); /* Flags */ + + put_u32(buffer, 0); /* Annotations count */ + /* FIXME: write annotations */ +} + +static void write_fx_4_buffer(struct hlsl_buffer *b, struct fx_write_context *fx) +{ + enum fx_4_buffer_flags + { + IS_TBUFFER = 0x1, + IS_SINGLE = 0x2, + }; + struct vkd3d_bytecode_buffer *buffer = &fx->structured; + uint32_t count = 0, bind_point = ~0u, flags = 0, size; + uint32_t name_offset, size_offset; + struct hlsl_ctx *ctx = fx->ctx; + struct hlsl_ir_var *var; + uint32_t count_offset; + + if (b->reservation.reg_type) + bind_point = b->reservation.reg_index; + if (b->type == HLSL_BUFFER_TEXTURE) + flags |= IS_TBUFFER; + /* FIXME: set 'single' flag for fx_5_0 */ + + name_offset = write_string(b->name, fx); + + put_u32(buffer, name_offset); /* Name */ + size_offset = put_u32(buffer, 0); /* Data size */ + put_u32(buffer, flags); /* Flags */ + count_offset = put_u32(buffer, 0); + put_u32(buffer, bind_point); /* Bind point */ + + put_u32(buffer, 0); /* Annotations count */ + /* FIXME: write annotations */ + + count = 0; + size = 0; + LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry) + { + if (var->buffer != b) + continue; + + write_fx_4_variable(var, fx); + size += get_fx_4_type_size(var->data_type); + ++count; + } + + set_u32(buffer, count_offset, count); + set_u32(buffer, size_offset, align(size, 16)); + + fx->numeric_variable_count += count; +} + +static void write_buffers(struct fx_write_context *fx) +{ + struct hlsl_buffer *buffer; + + LIST_FOR_EACH_ENTRY(buffer, &fx->ctx->buffers, struct hlsl_buffer, entry) + { + if (buffer->empty) + continue; + + write_fx_4_buffer(buffer, fx); + ++fx->buffer_count; + } +} + static int hlsl_fx_4_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) { struct vkd3d_bytecode_buffer buffer = { 0 }; - struct fx_write_context fx; uint32_t size_offset, size; + struct fx_write_context fx;
fx_write_context_init(ctx, &fx_4_ops, &fx);
put_u32(&fx.unstructured, 0); /* Empty string placeholder. */
- /* TODO: buffers */ + write_buffers(&fx); /* TODO: objects */ /* TODO: shared buffers */ /* TODO: shared objects */ @@ -389,9 +690,9 @@ static int hlsl_fx_4_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) write_techniques(ctx->globals, &fx);
put_u32(&buffer, ctx->profile->minor_version == 0 ? 0xfeff1001 : 0xfeff1011); /* Version. */ - put_u32(&buffer, 0); /* Buffer count. */ - put_u32(&buffer, 0); /* Variable count. */ - put_u32(&buffer, 0); /* Object count. */ + put_u32(&buffer, fx.buffer_count); /* Buffer count. */ + put_u32(&buffer, fx.numeric_variable_count); /* Numeric variable count. */ + put_u32(&buffer, 0); /* Object variable count. */ put_u32(&buffer, 0); /* Pool buffer count. */ put_u32(&buffer, 0); /* Pool variable count. */ put_u32(&buffer, 0); /* Pool object count. */ @@ -434,23 +735,23 @@ static int hlsl_fx_4_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) static int hlsl_fx_5_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) { struct vkd3d_bytecode_buffer buffer = { 0 }; - struct fx_write_context fx; uint32_t size_offset, size; + struct fx_write_context fx;
fx_write_context_init(ctx, &fx_4_ops, &fx);
put_u32(&fx.unstructured, 0); /* Empty string placeholder. */
- /* TODO: buffers */ + write_buffers(&fx); /* TODO: objects */ /* TODO: interface variables */
write_groups(&fx);
put_u32(&buffer, 0xfeff2001); /* Version. */ - put_u32(&buffer, 0); /* Buffer count. */ - put_u32(&buffer, 0); /* Variable count. */ - put_u32(&buffer, 0); /* Object count. */ + put_u32(&buffer, fx.buffer_count); /* Buffer count. */ + put_u32(&buffer, fx.numeric_variable_count); /* Numeric variable count. */ + put_u32(&buffer, 0); /* Object variable count. */ put_u32(&buffer, 0); /* Pool buffer count. */ put_u32(&buffer, 0); /* Pool variable count. */ put_u32(&buffer, 0); /* Pool object count. */
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/fx.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/libs/vkd3d-shader/fx.c b/libs/vkd3d-shader/fx.c index 2930e6dc2..ddc10ad60 100644 --- a/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d-shader/fx.c @@ -675,8 +675,8 @@ static void write_buffers(struct fx_write_context *fx) static int hlsl_fx_4_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) { struct vkd3d_bytecode_buffer buffer = { 0 }; - uint32_t size_offset, size; struct fx_write_context fx; + uint32_t size_offset;
fx_write_context_init(ctx, &fx_4_ops, &fx);
@@ -709,11 +709,10 @@ static int hlsl_fx_4_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) put_u32(&buffer, 0); /* Shader count. */ put_u32(&buffer, 0); /* Inline shader count. */
- size = align(fx.unstructured.size, 4); - set_u32(&buffer, size_offset, size); + set_u32(&buffer, size_offset, fx.unstructured.size);
bytecode_put_bytes(&buffer, fx.unstructured.data, fx.unstructured.size); - bytecode_put_bytes(&buffer, fx.structured.data, fx.structured.size); + bytecode_put_bytes_unaligned(&buffer, fx.structured.data, fx.structured.size);
vkd3d_free(fx.unstructured.data); vkd3d_free(fx.structured.data); @@ -735,8 +734,8 @@ static int hlsl_fx_4_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) static int hlsl_fx_5_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) { struct vkd3d_bytecode_buffer buffer = { 0 }; - uint32_t size_offset, size; struct fx_write_context fx; + uint32_t size_offset;
fx_write_context_init(ctx, &fx_4_ops, &fx);
@@ -773,11 +772,10 @@ static int hlsl_fx_5_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) put_u32(&buffer, 0); /* Interface variable element count. */ put_u32(&buffer, 0); /* Class instance elements count. */
- size = align(fx.unstructured.size, 4); - set_u32(&buffer, size_offset, size); + set_u32(&buffer, size_offset, fx.unstructured.size);
bytecode_put_bytes(&buffer, fx.unstructured.data, fx.unstructured.size); - bytecode_put_bytes(&buffer, fx.structured.data, fx.structured.size); + bytecode_put_bytes_unaligned(&buffer, fx.structured.data, fx.structured.size);
vkd3d_free(fx.unstructured.data); vkd3d_free(fx.structured.data);
On Wed Feb 7 10:22:31 2024 +0000, Giovanni Mascellani wrote:
BTW, superficially it looks like as if code could be shared between `hlsl_fx_4_write()` and `hlsl_fx_5_write()`.
Yes, it's possible to do, but I wanted to keep it as simple as possible first, avoiding conditionally added format fields. There won't be any more duplication there than it already is.
On Wed Feb 7 10:37:53 2024 +0000, Giovanni Mascellani wrote:
Could you please `STATIC_ASSERT()` that the size of `numeric_dest` is indeed that of `uint32_t`? Just in case somebody messes up with the bit widths.
Done.
On Wed Feb 7 10:42:08 2024 +0000, Nikolay Sivov wrote:
Yes, it's possible to do, but I wanted to keep it as simple as possible first, avoiding conditionally added format fields. There won't be any more duplication there than it already is.
Ok, fine.
+ struct fx_4_numeric_type + { + uint32_t type_class : 3; + uint32_t base_type : 5; + uint32_t rows : 3; + uint32_t columns : 3; + uint32_t column_major : 1; + uint32_t unknown : 17; + }; [...] + union + { + struct fx_4_numeric_type type; + uint32_t data; + } numeric_desc; [...] + put_u32_unaligned(buffer, numeric_desc.data);
I don't think bit-field memory layout is particularly portable.
On Wed Feb 7 15:39:23 2024 +0000, Henri Verbeet wrote:
+ struct fx_4_numeric_type + { + uint32_t type_class : 3; + uint32_t base_type : 5; + uint32_t rows : 3; + uint32_t columns : 3; + uint32_t column_major : 1; + uint32_t unknown : 17; + }; [...] + union + { + struct fx_4_numeric_type type; + uint32_t data; + } numeric_desc; [...] + put_u32_unaligned(buffer, numeric_desc.data);
I don't think bit-field memory layout is particularly portable.
I see, that's unfortunate. Should I use masks and shifts instead?
P.S. do you think we need to revert wine@3724385c86eeedd6de8fa91d6179b64ba0fd9597 for the same reason?
I see, that's unfortunate. Should I use masks and shifts instead?
It seems preferable to me, yes.
P.S. do you think we need to revert wine@3724385c86eeedd6de8fa91d6179b64ba0fd9597 for the same reason?
I wouldn't have written it that way, but my opinion on Wine's d3d10/d3dcompiler module isn't necessarily relevant. :) One thing to perhaps point out though is that the code in Wine targets a potentially narrower set of platforms than vkd3d.