First part of v2 of !38, trying to follow the wide feedback provided.
Following patches in: https://gitlab.winehq.org/fcasas/vkd3d/-/tree/documentation
-- v2: vkd3d-shader/hlsl: Add field-level documentation to struct hlsl_src. vkd3d-shader/hlsl: Add field-level documentation to struct hlsl_ir_node. vkd3d-shader/hlsl: Add field-level documentation to struct hlsl_ctx. vkd3d-shader/hlsl: Add field-level documentation to struct hlsl_ir_var. vkd3d-shader/hlsl: Add field-level documentation to struct hlsl_struct_field. vkd3d-shader/hlsl: Add field-level documentation to struct hlsl_type. vkd3d-shader/hlsl: Rename hlsl_struct_field.modifiers to "storage_modifiers". vkd3d-shader/hlsl: Rename hlsl_ir_var.modifiers to "storage_modifiers".
From: Francisco Casas fcasas@codeweavers.com
--- libs/vkd3d-shader/hlsl.c | 6 +++--- libs/vkd3d-shader/hlsl.h | 2 +- libs/vkd3d-shader/hlsl.y | 6 +++--- libs/vkd3d-shader/hlsl_codegen.c | 14 +++++++------- libs/vkd3d-shader/hlsl_sm4.c | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 8aa289ac..5491abad 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -778,7 +778,7 @@ struct hlsl_ir_var *hlsl_new_var(struct hlsl_ctx *ctx, const char *name, struct var->loc = loc; if (semantic) var->semantic = *semantic; - var->modifiers = modifiers; + var->storage_modifiers = modifiers; if (reg_reservation) var->reg_reservation = *reg_reservation; return var; @@ -1556,11 +1556,11 @@ static void dump_src(struct vkd3d_string_buffer *buffer, const struct hlsl_src *
static void dump_ir_var(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, const struct hlsl_ir_var *var) { - if (var->modifiers) + if (var->storage_modifiers) { struct vkd3d_string_buffer *string;
- if ((string = hlsl_modifiers_to_string(ctx, var->modifiers))) + if ((string = hlsl_modifiers_to_string(ctx, var->storage_modifiers))) vkd3d_string_buffer_printf(buffer, "%s ", string->buffer); hlsl_release_string_buffer(ctx, string); } diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index b6a593ca..326653a3 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -256,7 +256,7 @@ struct hlsl_ir_var const char *name; struct hlsl_semantic semantic; struct hlsl_buffer *buffer; - unsigned int modifiers; + unsigned int storage_modifiers; struct hlsl_reg_reservation reg_reservation; struct list scope_entry, param_entry, extern_entry;
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 6461ade5..02ac650e 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2060,9 +2060,9 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t * variables also get put in the global scope, but shouldn't be * considered uniforms, and we have no way of telling otherwise. */ if (!(modifiers & HLSL_STORAGE_STATIC)) - var->modifiers |= HLSL_STORAGE_UNIFORM; + var->storage_modifiers |= HLSL_STORAGE_UNIFORM;
- if (ctx->profile->major_version < 5 && (var->modifiers & HLSL_STORAGE_UNIFORM) && + if (ctx->profile->major_version < 5 && (var->storage_modifiers & HLSL_STORAGE_UNIFORM) && type_has_object_components(var->data_type, true)) { hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, @@ -2096,7 +2096,7 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t "Semantics are not allowed on local variables."); }
- if ((var->modifiers & HLSL_STORAGE_STATIC) && type_has_numeric_components(var->data_type) + if ((var->storage_modifiers & HLSL_STORAGE_STATIC) && type_has_numeric_components(var->data_type) && type_has_object_components(var->data_type, false)) { hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 58d44c4d..7826d22a 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -184,7 +184,7 @@ static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct list *instrs, stru * can write the uniform name into the shader reflection data. */
if (!(uniform = hlsl_new_var(ctx, temp->name, temp->data_type, - temp->loc, NULL, temp->modifiers, &temp->reg_reservation))) + temp->loc, NULL, temp->storage_modifiers, &temp->reg_reservation))) return; list_add_before(&temp->scope_entry, &uniform->scope_entry); list_add_tail(&ctx->extern_vars, &uniform->extern_entry); @@ -334,7 +334,7 @@ static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct list *instrs, st if (var->data_type->type == HLSL_CLASS_STRUCT) prepend_input_struct_copy(ctx, instrs, load); else if (var->semantic.name) - prepend_input_copy(ctx, instrs, load, var->modifiers, &var->semantic); + prepend_input_copy(ctx, instrs, load, var->storage_modifiers, &var->semantic); }
static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_load *rhs, @@ -430,7 +430,7 @@ static void append_output_var_copy(struct hlsl_ctx *ctx, struct list *instrs, st if (var->data_type->type == HLSL_CLASS_STRUCT) append_output_struct_copy(ctx, instrs, load); else if (var->semantic.name) - append_output_copy(ctx, instrs, load, var->modifiers, &var->semantic); + append_output_copy(ctx, instrs, load, var->storage_modifiers, &var->semantic); }
static bool transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, struct hlsl_ir_node *, void *), @@ -2598,13 +2598,13 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry
LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry) { - if (var->modifiers & HLSL_STORAGE_UNIFORM) + if (var->storage_modifiers & HLSL_STORAGE_UNIFORM) prepend_uniform_copy(ctx, &body->instrs, var); }
LIST_FOR_EACH_ENTRY(var, entry_func->parameters, struct hlsl_ir_var, param_entry) { - if (var->data_type->type == HLSL_CLASS_OBJECT || (var->modifiers & HLSL_STORAGE_UNIFORM)) + if (var->data_type->type == HLSL_CLASS_OBJECT || (var->storage_modifiers & HLSL_STORAGE_UNIFORM)) { prepend_uniform_copy(ctx, &body->instrs, var); } @@ -2614,9 +2614,9 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, "Parameter "%s" is missing a semantic.", var->name);
- if (var->modifiers & HLSL_STORAGE_IN) + if (var->storage_modifiers & HLSL_STORAGE_IN) prepend_input_var_copy(ctx, &body->instrs, var); - if (var->modifiers & HLSL_STORAGE_OUT) + if (var->storage_modifiers & HLSL_STORAGE_OUT) append_output_var_copy(ctx, &body->instrs, var); } } diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index ae5bb1ac..d9d05e04 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -1232,7 +1232,7 @@ static void write_sm4_dcl_semantic(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b { enum vkd3d_shader_interpolation_mode mode = VKD3DSIM_LINEAR;
- if ((var->modifiers & HLSL_STORAGE_NOINTERPOLATION) || type_is_integer(var->data_type)) + if ((var->storage_modifiers & HLSL_STORAGE_NOINTERPOLATION) || type_is_integer(var->data_type)) mode = VKD3DSIM_CONSTANT;
instr.opcode |= mode << VKD3D_SM4_INTERPOLATION_MODE_SHIFT;
From: Francisco Casas fcasas@codeweavers.com
--- libs/vkd3d-shader/hlsl.h | 2 +- libs/vkd3d-shader/hlsl.y | 2 +- libs/vkd3d-shader/hlsl_codegen.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 326653a3..2e4a5bc0 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -156,7 +156,7 @@ struct hlsl_struct_field struct hlsl_type *type; const char *name; struct hlsl_semantic semantic; - unsigned int modifiers; + unsigned int storage_modifiers; unsigned int reg_offset;
size_t name_bytecode_offset; diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 02ac650e..0bb993f9 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -983,7 +983,7 @@ static bool gen_struct_fields(struct hlsl_ctx *ctx, struct parse_fields *fields, field->loc = v->loc; field->name = v->name; field->semantic = v->semantic; - field->modifiers = modifiers; + field->storage_modifiers = modifiers; if (v->initializer.args_count) { hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Illegal initializer on a struct field."); diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 7826d22a..ac0afed6 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -313,7 +313,7 @@ static void prepend_input_struct_copy(struct hlsl_ctx *ctx, struct list *instrs, if (field->type->type == HLSL_CLASS_STRUCT) prepend_input_struct_copy(ctx, instrs, field_load); else if (field->semantic.name) - prepend_input_copy(ctx, instrs, field_load, field->modifiers, &field->semantic); + prepend_input_copy(ctx, instrs, field_load, field->storage_modifiers, &field->semantic); else hlsl_error(ctx, &field->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, "Field '%s' is missing a semantic.", field->name); @@ -408,7 +408,7 @@ static void append_output_struct_copy(struct hlsl_ctx *ctx, struct list *instrs, if (field->type->type == HLSL_CLASS_STRUCT) append_output_struct_copy(ctx, instrs, field_load); else if (field->semantic.name) - append_output_copy(ctx, instrs, field_load, field->modifiers, &field->semantic); + append_output_copy(ctx, instrs, field_load, field->storage_modifiers, &field->semantic); else hlsl_error(ctx, &field->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, "Field '%s' is missing a semantic.", field->name);
From: Francisco Casas fcasas@codeweavers.com
--- libs/vkd3d-shader/hlsl.h | 41 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 2e4a5bc0..e2a97b35 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -114,33 +114,74 @@ enum hlsl_matrix_majority HLSL_ROW_MAJOR };
+/* An HLSL source-level data type, including anonymous structs and typedefs. */ struct hlsl_type { + /* Item entry in hlsl_ctx->types. */ struct list entry; + /* Item entry in hlsl_scope->types. hlsl_type->name is used as key (if not NULL). */ struct rb_entry scope_entry; + enum hlsl_type_class type; + /* If type is <= HLSL_CLASS_LAST_NUMERIC, then base_type is <= HLSL_TYPE_LAST_SCALAR. + * If type is HLSL_CLASS_OBJECT, then base_type is > HLSL_TYPE_LAST_SCALAR. + * Otherwise, base_type is not used. */ enum hlsl_base_type base_type; + + /* If base_type is HLSL_TYPE_SAMPLER, then sampler_dim is <= HLSL_SAMPLER_DIM_LAST_SAMPLER. + * If base_type is HLSL_TYPE_TEXTURE, then sampler_dim can have any value of the enum. + * If base_type is HLSL_TYPE_UAV, them sampler_dim must be one of HLSL_SAMPLER_DIM_1D, + * HLSL_SAMPLER_DIM_2D, HLSL_SAMPLER_DIM_3D, HLSL_SAMPLER_DIM_1DARRAY, or HLSL_SAMPLER_DIM_2DARRAY. + * Otherwise, sampler_dim is not used */ enum hlsl_sampler_dim sampler_dim; + /* Name, in case the type is a named struct or a typedef. */ const char *name; + /* Bitfield for storing type modifiers, subset of HLSL_TYPE_MODIFIERS_MASK. + * Modifiers that don't fall inside this mask are to be stored in the variable in + * hlsl_ir_var.modifiers, or in the struct field in hlsl_ir_field.modifiers. */ unsigned int modifiers; + /* Size of the type values on each dimension. For non-numeric types, they are set for the + * convenience of the sm1/sm4 backends. + * If type is HLSL_CLASS_SCALAR, then both dimx = 1 and dimy = 1. + * If type is HLSL_CLASS_VECTOR, then dimx is the size of the vector, and dimy = 1. + * If type is HLSL_CLASS_MATRIX, then dimx is the number of rows, and dimy the number of columns. + * If type is HLSL_CLASS_ARRAY, then dimx and dimy is the same as in the type of the array elements. + * If type is HLSL_CLASS_STRUCT, then dimx is the sum of (dimx * dimy) of every component, and dimy = 1. + * If type is HLSL_CLASS_OBJECT, dimx and dimy depend on the base_type: + * If base_type is HLSL_TYPE_SAMPLER, then both dimx = 1 and dimy = 1. + * If base_type is HLSL_TYPE_TEXTURE, then dimx = 4 and dimy = 1. + * If base_type is HLSL_TYPE_UAV, then dimx is the dimx of e.resource_format, and dimy = 1. + * Otherwise both dimx = 1 and dimy = 1. */ unsigned int dimx; unsigned int dimy; + union { + /* Additional information if type is HLSL_CLASS_STRUCT. */ struct { struct hlsl_struct_field *fields; size_t field_count; } record; + /* Additional information if type is HLSL_CLASS_ARRAY. */ struct { struct hlsl_type *type; + /* Array lenght, or HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT if it is unknown yet while parsing. */ unsigned int elements_count; } array; + /* Format of the data contained within the type if the base_type is HLSL_TYPE_TEXTURE or + * HLSL_TYPE_UAV. */ struct hlsl_type *resource_format; } e;
+ /* Number of numeric register components used by one value of this type (4 components make 1 + * register). + * If type is HLSL_CLASS_STRUCT or HLSL_CLASS_ARRAY, this value includes the reg_size of + * their elements and padding (which varies according to the backend). + * This value is 0 for types without numeric components, like objects. */ unsigned int reg_size; + /* Offset where the type's description starts in the output bytecode, in bytes. */ size_t bytecode_offset; };
From: Francisco Casas fcasas@codeweavers.com
--- libs/vkd3d-shader/hlsl.h | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index e2a97b35..63c0fe55 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -191,15 +191,22 @@ struct hlsl_semantic uint32_t index; };
+/* A field within a struct type declaration, used in hlsl_type.e.fields. */ struct hlsl_struct_field { struct vkd3d_shader_location loc; struct hlsl_type *type; const char *name; struct hlsl_semantic semantic; + + /* Bitfield for storing modifiers that are not in HLSL_TYPE_MODIFIERS_MASK (these are stored in + * type->modifiers instead) and that also are specific to the field and not the whole variable. + * In particular, interpolation modifiers. */ unsigned int storage_modifiers; + /* Offset of the field within the type it belongs to, in numeric register components. */ unsigned int reg_offset;
+ /* Offset where the fields's name starts in the output bytecode, in bytes. */ size_t name_bytecode_offset; };
From: Francisco Casas fcasas@codeweavers.com
--- libs/vkd3d-shader/hlsl.h | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 63c0fe55..f4195f33 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -303,13 +303,40 @@ struct hlsl_ir_var struct vkd3d_shader_location loc; const char *name; struct hlsl_semantic semantic; + /* Buffer where the variable's value is stored, in case it is uniform. */ struct hlsl_buffer *buffer; + /* Bitfield for storage modifiers (type modifiers are stored in data_type->modifiers). */ unsigned int storage_modifiers; + /* Optional register to be used as a starting point for the variable allocation, specified + * by the user via the register(·) syntax. */ struct hlsl_reg_reservation reg_reservation; - struct list scope_entry, param_entry, extern_entry;
+ /* Item entry in hlsl_scope.vars. Specifically hlsl_ctx.globals.vars if the variable is global. */ + struct list scope_entry; + /* Item entry in hlsl_ir_function_decl.parameters, if the variable is a function parameter. */ + struct list param_entry; + /* Item entry in hlsl_ctx.extern_vars, if the variable is extern. */ + struct list extern_entry; + + /* Indexes of the IR instructions where the variable is first written and last read (liveness + * range). The IR instructions are numerated starting from 2, because 0 means unused, and 1 + * means function entry. */ unsigned int first_write, last_read; + /* Offset where the variable's value is stored within its buffer in numeric register components. + * This in case the variable is uniform. */ unsigned int buffer_offset; + /* Register to which the variable is allocated during its lifetime. + * In case that the variable spans multiple registers, this is set to the start of the register + * range. + * The register type is inferred from the data type and the storage of the variable. + * Builtin semantics don't use the field. + * In SM4, uniforms don't use the field because they are located using the buffer's hlsl_reg + * and the buffer_offset instead. + * If the variable is an input semantic copy, the register is 'v'. + * If the variable is an output semantic copy, the register is 'o'. + * Textures are stored on 's' registers in SM1, and 't' registers in SM4. + * Samplers are stored on 's' registers. + * UAVs are stored on 'u' registers. */ struct hlsl_reg reg;
uint32_t is_input_semantic : 1;
From: Francisco Casas fcasas@codeweavers.com
--- libs/vkd3d-shader/hlsl.h | 42 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index f4195f33..ff69d3a3 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -573,48 +573,88 @@ struct hlsl_ctx
const char **source_files; unsigned int source_files_count; + /* Current location being read in the HLSL source, updated while parsing. */ struct vkd3d_shader_location location; + /* Stores the logging messages and logging configuration. */ struct vkd3d_shader_message_context *message_context; + /* Cache for temporary string allocations. */ struct vkd3d_string_buffer_cache string_buffers; + /* A value from enum vkd3d_result with the current success/failure result of the whole + * compilation. + * It is initialized to VKD3D_OK and set to an error code in case a call to hlsl_fixme() or + * hlsl_error() is triggered, or in case of a memory allocation error. + * The value of this field is checked between compilation stages to stop execution in case of + * failure. */ int result;
+ /* Pointer to an opaque data structure managed by FLEX (during lexing), that encapsulates the + * current state of the scanner. This pointer is required by all FLEX API functions when the + * scanner is declared as reentrant, which is the case. */ void *scanner;
+ /* Pointer to the current scope; changes as the parser reads the code. */ struct hlsl_scope *cur_scope; + /* Scope of global variables. */ struct hlsl_scope *globals; + /* List of all the scopes in the program; linked by the hlsl_scope.entry fields. */ struct list scopes; + /* List of all the extern variables; linked by the hlsl_ir_var.extern_entry fields. + * This exists as a convenience because it is often necessary to iterate all extern variables + * and these can be declared in global scope, as function parameters, or as the function + * return value. */ struct list extern_vars;
+ /* List containing both the built-in HLSL buffers ($Globals and $Params) and the ones declared + * in the shader; linked by the hlsl_buffer.entry fields. */ struct list buffers; + /* Current buffer (changes as the parser reads the code), $Globals buffer, and $Params buffer, + * respectively. */ struct hlsl_buffer *cur_buffer, *globals_buffer, *params_buffer; + /* List containing all created hlsl_types, except builtin_types; linked by the hlsl_type.entry + * fields. */ struct list types; + /* Tree map for the declared functions, using hlsl_ir_function.name as key. + * The functions are attached through the hlsl_ir_function.entry fields. */ struct rb_tree functions; + /* Pointer to the current function; changes as the parser reads the code. */ const struct hlsl_ir_function_decl *cur_function;
+ /* Default matrix majority for matrix types. Can be set by a pragma within the HLSL source. */ enum hlsl_matrix_majority matrix_majority;
+ /* Basic data types stored for convenience. */ struct { struct hlsl_type *scalar[HLSL_TYPE_LAST_SCALAR + 1]; struct hlsl_type *vector[HLSL_TYPE_LAST_SCALAR + 1][4]; - /* matrix[float][2][4] is a float4x2, i.e. dimx = 2, dimy = 4 */ + /* matrix[HLSL_TYPE_FLOAT][1][3] is a float4x2, i.e. dimx = 2, dimy = 4 */ struct hlsl_type *matrix[HLSL_TYPE_LAST_SCALAR + 1][4][4]; struct hlsl_type *sampler[HLSL_SAMPLER_DIM_LAST_SAMPLER + 1]; struct hlsl_type *Void; } builtin_types;
+ /* List of the instruction nodes for initializing static variables; linked by the + * hlsl_ir_node.entry fields. */ struct list static_initializers;
+ /* Dynamic array of constant values that appear in the shader, associated to the 'c' registers. + * Only used for SM1 profiles. */ struct hlsl_constant_defs { struct hlsl_vec4 *values; size_t count, size; } constant_defs; + /* Number of temp. registers required for the shader to run, i.e. the largest temp register + * index that will be used in the output bytecode (+1). */ uint32_t temp_count;
+ /* Number of threads to be executed (on the X, Y, and Z dimensions) in a single thread group in + * compute shader profiles. It is set using the numthreads() attribute in the entry point. */ uint32_t thread_count[3];
+ /* Whether the parser is inside an state block (effects' metadata) inside a variable declarition. */ uint32_t in_state_block : 1; + /* Whether the numthreads() attribute has been provided in the entry-point function. */ uint32_t found_numthreads : 1; };
From: Francisco Casas fcasas@codeweavers.com
--- libs/vkd3d-shader/hlsl.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index ff69d3a3..a8029c2c 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -217,6 +217,11 @@ struct hlsl_reg bool allocated; };
+/* Types of instruction nodes for the IR. + * Each type of instruction node is associated to a struct with the same name in lower case. + * e.g. for HLSL_IR_CONSTANT there exists struct hlsl_ir_constant. + * Each one of these structs start with a struct hlsl_ir_node field, so pointers to values of these + * types can be casted seamlessly to (struct hlsl_ir_node *) and vice-versa. */ enum hlsl_ir_node_type { HLSL_IR_CONSTANT, @@ -231,12 +236,22 @@ enum hlsl_ir_node_type HLSL_IR_SWIZZLE, };
+/* Common data for every type of IR instruction node. */ struct hlsl_ir_node { + /* Item entry for storing the instruction in a list of instructions. */ struct list entry; + + /* Type of node, which means that a pointer to this struct hlsl_ir_node can be casted to a + * pointer to the struct with the same name. */ enum hlsl_ir_node_type type; + /* HLSL data type of the node, when used by other nodes as a source (through an hlsl_src). + * HLSL_IR_CONSTANT, HLSL_IR_EXPR, HLSL_IR_LOAD, HLSL_IR_RESOURCE_LOAD, and HLSL_IR_SWIZZLE + * have a data type and can be used through an hlsl_src; other types of node don't. */ struct hlsl_type *data_type;
+ /* List containing all the struct hlsl_src·s that point to this node; linked by the + * hlsl_src.entry fields. */ struct list uses;
struct vkd3d_shader_location loc; @@ -246,6 +261,7 @@ struct hlsl_ir_node * true even for loops, since currently we can't have a reference to a * value generated in an earlier iteration of the loop. */ unsigned int index, last_read; + /* Temp. register allocated to store the result of this instruction (if any). */ struct hlsl_reg reg; };
From: Francisco Casas fcasas@codeweavers.com
--- libs/vkd3d-shader/hlsl.h | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index a8029c2c..2496b05d 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -270,9 +270,16 @@ struct hlsl_block struct list instrs; };
+/* A reference to an instruction node (struct hlsl_ir_node), usable as a field in other structs. + * struct hlsl_src is more powerful than a mere pointer to an hlsl_ir_node because it also + * contains a linked list item entry, which is used by the referenced instruction node to keep + * track of all the hlsl_src·s that reference it. + * This allows replacing any hlsl_ir_node with any other in all the places it is used, or checking + * that a node has no uses before it is removed. */ struct hlsl_src { struct hlsl_ir_node *node; + /* Item entry for node->uses. */ struct list entry; };
On Tue Nov 29 21:14:56 2022 +0000, Francisco Casas wrote:
changed this line in [version 2 of the diff](/wine/vkd3d/-/merge_requests/50/diffs?diff_id=21610&start_sha=5a0eb3f674ac04794263c72548fbc99f628eff7a#b4b2f0df64f7fbb515484cb602382012595ddfb6_202_202)
Eh. The oldest version of the code was a bit inconsistent. I changed some of them more recently to be more consistent, but I left VOLATILE alone. Currently it has no meaning even in the native compiler. Given that it can be put on a typedef, though, and otherwise behaves like "modifiers", I think it should be renamed to HLSL_MODIFIER_VOLATILE.
This merge request was approved by Zebediah Figura.
Giovanni Mascellani (@giomasce) commented about libs/vkd3d-shader/hlsl.h:
* If base_type is HLSL_TYPE_TEXTURE, then sampler_dim can have any value of the enum.
* If base_type is HLSL_TYPE_UAV, them sampler_dim must be one of HLSL_SAMPLER_DIM_1D,
* HLSL_SAMPLER_DIM_2D, HLSL_SAMPLER_DIM_3D, HLSL_SAMPLER_DIM_1DARRAY, or HLSL_SAMPLER_DIM_2DARRAY.
enum hlsl_sampler_dim sampler_dim;* Otherwise, sampler_dim is not used */
- /* Name, in case the type is a named struct or a typedef. */ const char *name;
- /* Bitfield for storing type modifiers, subset of HLSL_TYPE_MODIFIERS_MASK.
* Modifiers that don't fall inside this mask are to be stored in the variable in
unsigned int modifiers;* hlsl_ir_var.modifiers, or in the struct field in hlsl_ir_field.modifiers. */
- /* Size of the type values on each dimension. For non-numeric types, they are set for the
* convenience of the sm1/sm4 backends.
* If type is HLSL_CLASS_SCALAR, then both dimx = 1 and dimy = 1.
* If type is HLSL_CLASS_VECTOR, then dimx is the size of the vector, and dimy = 1.
* If type is HLSL_CLASS_MATRIX, then dimx is the number of rows, and dimy the number of columns.
Isn't that the other way around? My recalling and my notebook agree that `float2x3` is the type of matrices with 2 rows and 3 columns, which have `dimx == 3` and `dimy == 2` (it's the same as type `matrix<float, 3, 2>`, and is stored in `ctx->builtin_types.matrix[FLOAT][2][1]`).
Giovanni Mascellani (@giomasce) commented about libs/vkd3d-shader/hlsl.h:
* If base_type is HLSL_TYPE_UAV, them sampler_dim must be one of HLSL_SAMPLER_DIM_1D,
* HLSL_SAMPLER_DIM_2D, HLSL_SAMPLER_DIM_3D, HLSL_SAMPLER_DIM_1DARRAY, or HLSL_SAMPLER_DIM_2DARRAY.
enum hlsl_sampler_dim sampler_dim;* Otherwise, sampler_dim is not used */
- /* Name, in case the type is a named struct or a typedef. */ const char *name;
- /* Bitfield for storing type modifiers, subset of HLSL_TYPE_MODIFIERS_MASK.
* Modifiers that don't fall inside this mask are to be stored in the variable in
unsigned int modifiers;* hlsl_ir_var.modifiers, or in the struct field in hlsl_ir_field.modifiers. */
- /* Size of the type values on each dimension. For non-numeric types, they are set for the
* convenience of the sm1/sm4 backends.
* If type is HLSL_CLASS_SCALAR, then both dimx = 1 and dimy = 1.
* If type is HLSL_CLASS_VECTOR, then dimx is the size of the vector, and dimy = 1.
* If type is HLSL_CLASS_MATRIX, then dimx is the number of rows, and dimy the number of columns.
* If type is HLSL_CLASS_ARRAY, then dimx and dimy is the same as in the type of the array elements.
Really minor, but shouldn't that be "dimx and dimy *are* the same..."? People with better English knowledge than me already had a look, so maybe I'm wrong.
I agree it's a very useful MR. I'm not accepting yet because I think that `dimx` vs `dimy` bit is wrong, and I would avoid adding a wrong comment. But it's trivial to fix.
On Mon Dec 12 12:39:05 2022 +0000, Giovanni Mascellani wrote:
Isn't that the other way around? My recalling and my notebook agree that `float2x3` is the type of matrices with 2 rows and 3 columns, which have `dimx == 3` and `dimy == 2` (it's the same as type `matrix<float, 3, 2>`, and is stored in `ctx->builtin_types.matrix[FLOAT][2][1]`).
Ah, yes!