Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v2: No changes.
libs/vkd3d-shader/hlsl.h | 4 ++-- libs/vkd3d-shader/hlsl_codegen.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 3dc7a26b..0c755f46 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -136,9 +136,9 @@ struct hlsl_struct_field struct hlsl_type *type; const char *name; const char *semantic; - unsigned int reg_offset; - unsigned int name_offset; + + unsigned int name_bytecode_offset; };
struct hlsl_reg diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 1b5e8a27..2c07171b 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1051,7 +1051,7 @@ static void write_sm1_type(struct bytecode_buffer *buffer, struct hlsl_type *typ { LIST_FOR_EACH_ENTRY(field, array_type->e.elements, struct hlsl_struct_field, entry) { - field->name_offset = buffer->count; + field->name_bytecode_offset = buffer->count; put_string(buffer, field->name); write_sm1_type(buffer, field->type, ctab_start); } @@ -1060,7 +1060,7 @@ static void write_sm1_type(struct bytecode_buffer *buffer, struct hlsl_type *typ
LIST_FOR_EACH_ENTRY(field, array_type->e.elements, struct hlsl_struct_field, entry) { - put_dword(buffer, (field->name_offset - ctab_start) * sizeof(*buffer->data)); + put_dword(buffer, (field->name_bytecode_offset - ctab_start) * sizeof(*buffer->data)); put_dword(buffer, (field->type->bytecode_offset - ctab_start) * sizeof(*buffer->data)); ++field_count; }
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v2: No changes.
libs/vkd3d-shader/hlsl_codegen.c | 42 +++++++++++++++++--------------- 1 file changed, 23 insertions(+), 19 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 2c07171b..0fd1f6bd 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -886,17 +886,22 @@ struct bytecode_buffer int status; };
-static void put_dword(struct bytecode_buffer *buffer, uint32_t value) +/* Returns the token index. */ +static unsigned int put_dword(struct bytecode_buffer *buffer, uint32_t value) { + unsigned int index = buffer->count; + if (buffer->status) - return; + return index;
if (!vkd3d_array_reserve((void **)&buffer->data, &buffer->size, buffer->count + 1, sizeof(*buffer->data))) { buffer->status = VKD3D_ERROR_OUT_OF_MEMORY; - return; + return index; } buffer->data[buffer->count++] = value; + + return index; }
static void set_dword(struct bytecode_buffer *buffer, unsigned int index, uint32_t value) @@ -908,23 +913,26 @@ static void set_dword(struct bytecode_buffer *buffer, unsigned int index, uint32 buffer->data[index] = value; }
-static void put_string(struct bytecode_buffer *buffer, const char *str) +/* Returns the token index. */ +static unsigned int put_string(struct bytecode_buffer *buffer, const char *str) { + unsigned int index = buffer->count; size_t len = strlen(str) + 1; unsigned int token_count = (len + 3) / sizeof(*buffer->data);
if (buffer->status) - return; + return index;
if (!vkd3d_array_reserve((void **)&buffer->data, &buffer->size, buffer->count + token_count, sizeof(*buffer->data))) { buffer->status = E_OUTOFMEMORY; - return; + return index; }
buffer->data[buffer->count + token_count - 1] = 0xabababab; memcpy(buffer->data + buffer->count, str, len); buffer->count += token_count; + return index; }
static uint32_t sm1_version(enum vkd3d_shader_type type, unsigned int major, unsigned int minor) @@ -1051,8 +1059,7 @@ static void write_sm1_type(struct bytecode_buffer *buffer, struct hlsl_type *typ { LIST_FOR_EACH_ENTRY(field, array_type->e.elements, struct hlsl_struct_field, entry) { - field->name_bytecode_offset = buffer->count; - put_string(buffer, field->name); + field->name_bytecode_offset = put_string(buffer, field->name); write_sm1_type(buffer, field->type, ctab_start); }
@@ -1066,8 +1073,7 @@ static void write_sm1_type(struct bytecode_buffer *buffer, struct hlsl_type *typ } }
- type->bytecode_offset = buffer->count; - put_dword(buffer, sm1_class(type) | (sm1_base_type(type) << 16)); + type->bytecode_offset = put_dword(buffer, sm1_class(type) | (sm1_base_type(type) << 16)); put_dword(buffer, type->dimy | (type->dimx << 16)); put_dword(buffer, array_size | (field_count << 16)); put_dword(buffer, fields_offset); @@ -1104,7 +1110,7 @@ static void sm1_sort_externs(struct hlsl_ctx *ctx) static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer, struct hlsl_ir_function_decl *entry_func) { - unsigned int ctab_start, vars_start; + unsigned int ctab_start, vars_start, size_offset, creator_offset, offset; unsigned int uniform_count = 0; struct hlsl_ir_var *var;
@@ -1133,13 +1139,11 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct bytecode_buffer *buf
sm1_sort_externs(ctx);
- put_dword(buffer, 0); /* COMMENT tag + size */ + size_offset = put_dword(buffer, 0); put_dword(buffer, MAKEFOURCC('C','T','A','B'));
- ctab_start = buffer->count; - - put_dword(buffer, sizeof(D3DXSHADER_CONSTANTTABLE)); /* size of this header */ - put_dword(buffer, 0); /* creator */ + ctab_start = put_dword(buffer, sizeof(D3DXSHADER_CONSTANTTABLE)); + creator_offset = put_dword(buffer, 0); put_dword(buffer, sm1_version(ctx->profile->type, ctx->profile->major_version, ctx->profile->minor_version)); put_dword(buffer, uniform_count); put_dword(buffer, sizeof(D3DXSHADER_CONSTANTTABLE)); /* offset of constants */ @@ -1176,10 +1180,10 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct bytecode_buffer *buf } }
- set_dword(buffer, ctab_start + 1, (buffer->count - ctab_start) * sizeof(*buffer->data)); - put_string(buffer, vkd3d_shader_get_version(NULL, NULL)); + offset = put_string(buffer, vkd3d_shader_get_version(NULL, NULL)); + set_dword(buffer, creator_offset, (offset - ctab_start) * sizeof(*buffer->data));
- set_dword(buffer, ctab_start - 2, D3DSIO_COMMENT | ((buffer->count - (ctab_start - 1)) << 16)); + set_dword(buffer, size_offset, D3DSIO_COMMENT | ((buffer->count - (ctab_start - 1)) << 16)); }
static int write_sm1_shader(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func,
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v2: use max() when resizing constant defs, use 1u in shift instructions, move struct constant_defs into hlsl_ctx, also introduce a put_float() helper
include/vkd3d_d3d9types.h | 41 +++++++++++ libs/vkd3d-shader/hlsl.h | 11 +++ libs/vkd3d-shader/hlsl_codegen.c | 121 ++++++++++++++++++++++++++++--- 3 files changed, 162 insertions(+), 11 deletions(-)
diff --git a/include/vkd3d_d3d9types.h b/include/vkd3d_d3d9types.h index 7a8c15f4..ba7dcbfb 100644 --- a/include/vkd3d_d3d9types.h +++ b/include/vkd3d_d3d9types.h @@ -27,6 +27,19 @@ ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 )) #endif
+#define D3DSI_INSTLENGTH_SHIFT 24 + +#define D3DSP_REGTYPE_SHIFT 28 +#define D3DSP_REGTYPE_SHIFT2 8 +#define D3DSP_REGTYPE_MASK (0x7 << D3DSP_REGTYPE_SHIFT) +#define D3DSP_REGTYPE_MASK2 0x00001800 + +#define D3DSP_WRITEMASK_0 0x00010000 +#define D3DSP_WRITEMASK_1 0x00020000 +#define D3DSP_WRITEMASK_2 0x00040000 +#define D3DSP_WRITEMASK_3 0x00080000 +#define D3DSP_WRITEMASK_ALL 0x000f0000 + #define D3DPS_VERSION(major, minor) (0xffff0000 | ((major) << 8) | (minor)) #define D3DVS_VERSION(major, minor) (0xfffe0000 | ((major) << 8) | (minor))
@@ -123,5 +136,33 @@ typedef enum _D3DSHADER_INSTRUCTION_OPCODE_TYPE D3DSIO_FORCE_DWORD = 0x7fffffff, } D3DSHADER_INSTRUCTION_OPCODE_TYPE;
+typedef enum _D3DSHADER_PARAM_REGISTER_TYPE +{ + D3DSPR_TEMP = 0x00, + D3DSPR_INPUT = 0x01, + D3DSPR_CONST = 0x02, + D3DSPR_ADDR = 0x03, + D3DSPR_TEXTURE = 0x03, + D3DSPR_RASTOUT = 0x04, + D3DSPR_ATTROUT = 0x05, + D3DSPR_TEXCRDOUT = 0x06, + D3DSPR_OUTPUT = 0x06, + D3DSPR_CONSTINT = 0x07, + D3DSPR_COLOROUT = 0x08, + D3DSPR_DEPTHOUT = 0x09, + D3DSPR_SAMPLER = 0x0a, + D3DSPR_CONST2 = 0x0b, + D3DSPR_CONST3 = 0x0c, + D3DSPR_CONST4 = 0x0d, + D3DSPR_CONSTBOOL = 0x0e, + D3DSPR_LOOP = 0x0f, + D3DSPR_TEMPFLOAT16 = 0x10, + D3DSPR_MISCTYPE = 0x11, + D3DSPR_LABEL = 0x12, + D3DSPR_PREDICATE = 0x13, + + D3DSPR_FORCE_DWORD = 0x7fffffff, +} D3DSHADER_PARAM_REGISTER_TYPE; + #endif /* _d3d9TYPES_H_ */ #endif /* __VKD3D_D3D9TYPES_H */ diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 0c755f46..d65c25e2 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -407,6 +407,11 @@ struct hlsl_profile_info bool software; };
+struct hlsl_vec4 +{ + float f[4]; +}; + struct hlsl_ctx { const struct hlsl_profile_info *profile; @@ -440,6 +445,12 @@ struct hlsl_ctx } builtin_types;
struct list static_initializers; + + struct hlsl_constant_defs + { + struct hlsl_vec4 *values; + size_t count, size; + } constant_defs; };
enum hlsl_error_level diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 0fd1f6bd..b3e59bc7 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -804,8 +804,9 @@ static void allocate_temp_registers_recurse(struct list *instrs, struct liveness } }
-static void allocate_const_registers_recurse(struct list *instrs, struct liveness *liveness) +static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, struct list *instrs, struct liveness *liveness) { + struct hlsl_constant_defs *defs = &ctx->constant_defs; struct hlsl_ir_node *instr;
LIST_FOR_EACH_ENTRY(instr, instrs, struct hlsl_ir_node, entry) @@ -815,28 +816,84 @@ static void allocate_const_registers_recurse(struct list *instrs, struct livenes case HLSL_IR_CONSTANT: { struct hlsl_ir_constant *constant = hlsl_ir_constant(instr); + const struct hlsl_type *type = instr->data_type; + unsigned int reg_size = type->reg_size; + unsigned int x, y, i, writemask;
- if (instr->data_type->reg_size > 1) - constant->reg = allocate_range(liveness, 1, UINT_MAX, instr->data_type->reg_size); + if (reg_size > 1) + constant->reg = allocate_range(liveness, 1, UINT_MAX, reg_size); else - constant->reg = allocate_register(liveness, 1, UINT_MAX, instr->data_type->dimx); - TRACE("Allocated constant @%u to %s.\n", instr->index, - debug_register('c', constant->reg, instr->data_type)); + constant->reg = allocate_register(liveness, 1, UINT_MAX, type->dimx); + TRACE("Allocated constant @%u to %s.\n", instr->index, debug_register('c', constant->reg, type)); + + if (!vkd3d_array_reserve((void **)&defs->values, &defs->size, + constant->reg.id + reg_size, sizeof(*defs->values))) + { + ctx->failed = true; + return; + } + defs->count = max(defs->count, constant->reg.id + reg_size); + + assert(type->type <= HLSL_CLASS_LAST_NUMERIC); + + if (!(writemask = constant->reg.writemask)) + writemask = (1u << type->dimx) - 1; + + for (y = 0; y < type->dimy; ++y) + { + for (x = 0, i = 0; x < 4; ++x) + { + float f; + + if (!(writemask & (1u << x))) + continue; + + switch (type->base_type) + { + case HLSL_TYPE_BOOL: + f = constant->value.b[i++]; + break; + + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + f = constant->value.f[i++]; + break; + + case HLSL_TYPE_INT: + f = constant->value.i[i++]; + break; + + case HLSL_TYPE_UINT: + f = constant->value.u[i++]; + break; + + case HLSL_TYPE_DOUBLE: + FIXME("Double constant.\n"); + return; + + default: + assert(0); + return; + } + defs->values[constant->reg.id + y].f[x] = f; + } + } + break; }
case HLSL_IR_IF: { struct hlsl_ir_if *iff = hlsl_ir_if(instr); - allocate_const_registers_recurse(&iff->then_instrs, liveness); - allocate_const_registers_recurse(&iff->else_instrs, liveness); + allocate_const_registers_recurse(ctx, &iff->then_instrs, liveness); + allocate_const_registers_recurse(ctx, &iff->else_instrs, liveness); break; }
case HLSL_IR_LOOP: { struct hlsl_ir_loop *loop = hlsl_ir_loop(instr); - allocate_const_registers_recurse(&loop->body, liveness); + allocate_const_registers_recurse(ctx, &loop->body, liveness); break; }
@@ -851,6 +908,8 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi struct liveness liveness = {0}; struct hlsl_ir_var *var;
+ allocate_const_registers_recurse(ctx, entry_func->body, &liveness); + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { if (var->is_uniform && var->last_read) @@ -865,8 +924,6 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi TRACE("Allocated %s to %s.\n", var->name, debug_register('c', var->reg, var->data_type)); } } - - allocate_const_registers_recurse(entry_func->body, &liveness); }
/* Simple greedy temporary register allocation pass that just assigns a unique @@ -904,6 +961,18 @@ static unsigned int put_dword(struct bytecode_buffer *buffer, uint32_t value) return index; }
+/* Returns the token index. */ +static unsigned int put_float(struct bytecode_buffer *buffer, float value) +{ + union + { + float f; + uint32_t u; + } u; + u.f = value; + return put_dword(buffer, u.u); +} + static void set_dword(struct bytecode_buffer *buffer, unsigned int index, uint32_t value) { if (buffer->status) @@ -1186,6 +1255,34 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct bytecode_buffer *buf set_dword(buffer, size_offset, D3DSIO_COMMENT | ((buffer->count - (ctab_start - 1)) << 16)); }
+static uint32_t sm1_encode_register_type(D3DSHADER_PARAM_REGISTER_TYPE type) +{ + return ((type << D3DSP_REGTYPE_SHIFT) & D3DSP_REGTYPE_MASK) + | ((type << D3DSP_REGTYPE_SHIFT2) & D3DSP_REGTYPE_MASK2); +} + +static void write_sm1_constant_defs(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer) +{ + unsigned int i, x; + + for (i = 0; i < ctx->constant_defs.count; ++i) + { + uint32_t token = D3DSIO_DEF; + + if (ctx->profile->major_version > 1) + token |= 5 << D3DSI_INSTLENGTH_SHIFT; + put_dword(buffer, token); + + token = (1u << 31); + token |= sm1_encode_register_type(D3DSPR_CONST); + token |= D3DSP_WRITEMASK_ALL; + token |= i; + put_dword(buffer, token); + for (x = 0; x < 4; ++x) + put_float(buffer, ctx->constant_defs.values[i].f[x]); + } +} + static int write_sm1_shader(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out) { @@ -1196,6 +1293,8 @@ static int write_sm1_shader(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *
write_sm1_uniforms(ctx, &buffer, entry_func);
+ write_sm1_constant_defs(ctx, &buffer); + put_dword(&buffer, D3DSIO_END);
if (!(ret = buffer.status))
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
In fact, don't even mark them directly; only mark the synthetic variables.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v2: New patch.
libs/vkd3d-shader/hlsl.c | 38 +++++++++++---------------- libs/vkd3d-shader/hlsl.h | 6 +++-- libs/vkd3d-shader/hlsl.y | 22 ++-------------- libs/vkd3d-shader/hlsl_codegen.c | 45 +++++++++++++++++++++----------- 4 files changed, 51 insertions(+), 60 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 50b40d65..5804c8e5 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -388,7 +388,7 @@ struct hlsl_ir_expr *hlsl_new_copy(struct hlsl_ir_node *node) }
struct hlsl_ir_var *hlsl_new_var(const char *name, struct hlsl_type *type, const struct vkd3d_shader_location loc, - const char *semantic, const struct hlsl_reg_reservation *reg_reservation) + const char *semantic, unsigned int modifiers, const struct hlsl_reg_reservation *reg_reservation) { struct hlsl_ir_var *var;
@@ -399,6 +399,7 @@ struct hlsl_ir_var *hlsl_new_var(const char *name, struct hlsl_type *type, const var->data_type = type; var->loc = loc; var->semantic = semantic; + var->modifiers = modifiers; var->reg_reservation = reg_reservation; return var; } @@ -406,7 +407,7 @@ struct hlsl_ir_var *hlsl_new_var(const char *name, struct hlsl_type *type, const struct hlsl_ir_var *hlsl_new_synthetic_var(struct hlsl_ctx *ctx, const char *name, struct hlsl_type *type, const struct vkd3d_shader_location loc) { - struct hlsl_ir_var *var = hlsl_new_var(vkd3d_strdup(name), type, loc, NULL, NULL); + struct hlsl_ir_var *var = hlsl_new_var(vkd3d_strdup(name), type, loc, NULL, 0, NULL);
if (var) list_add_tail(&ctx->globals->vars, &var->scope_entry); @@ -571,7 +572,7 @@ struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, struct hl char name[28];
sprintf(name, "<retval-%p>", decl); - if (!(return_var = hlsl_new_var(vkd3d_strdup(name), return_type, loc, semantic, NULL))) + if (!(return_var = hlsl_new_var(vkd3d_strdup(name), return_type, loc, semantic, 0, NULL))) { vkd3d_free(decl); return NULL; @@ -868,12 +869,17 @@ static void dump_src(struct vkd3d_string_buffer *buffer, const struct hlsl_src *
static void dump_ir_var(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_var *var) { - if (var->is_input_varying) - vkd3d_string_buffer_printf(buffer, "in "); - if (var->is_output_varying) - vkd3d_string_buffer_printf(buffer, "out "); - if (var->is_uniform) - vkd3d_string_buffer_printf(buffer, "uniform "); + if (var->modifiers) + { + struct vkd3d_string_buffer_cache string_buffers; + struct vkd3d_string_buffer *string; + + vkd3d_string_buffer_cache_init(&string_buffers); + if ((string = hlsl_modifiers_to_string(&string_buffers, var->modifiers))) + vkd3d_string_buffer_printf(buffer, "%s ", string->buffer); + vkd3d_string_buffer_release(&string_buffers, string); + vkd3d_string_buffer_cache_cleanup(&string_buffers); + } vkd3d_string_buffer_printf(buffer, "%s %s", debug_hlsl_type(var->data_type), var->name); if (var->semantic) vkd3d_string_buffer_printf(buffer, " : %s", var->semantic); @@ -1616,7 +1622,6 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d struct hlsl_ir_function_decl *entry_func; const struct hlsl_profile_info *profile; const char *entry_point; - struct hlsl_ir_var *var; struct hlsl_ctx ctx; int ret;
@@ -1659,19 +1664,6 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d return VKD3D_ERROR_INVALID_SHADER; }
- LIST_FOR_EACH_ENTRY(var, entry_func->parameters, struct hlsl_ir_var, param_entry) - { - if (var->data_type->type != HLSL_CLASS_STRUCT && !var->semantic - && (var->is_input_varying || var->is_output_varying)) - hlsl_error(&ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, - "Parameter "%s" is missing a semantic.", var->name); - } - - if (!hlsl_type_is_void(entry_func->return_type) - && entry_func->return_type->type != HLSL_CLASS_STRUCT && !entry_func->return_var->semantic) - hlsl_error(&ctx, entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, - "Entry point "%s" is missing a return value semantic.", entry_point); - ret = hlsl_emit_dxbc(&ctx, entry_func, dxbc);
hlsl_ctx_cleanup(&ctx); diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index d65c25e2..1c5f63aa 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -216,6 +216,7 @@ struct hlsl_ir_var struct vkd3d_shader_location loc; const char *name; const char *semantic; + unsigned int modifiers; const struct hlsl_reg_reservation *reg_reservation; struct list scope_entry, param_entry, extern_entry;
@@ -589,8 +590,9 @@ struct hlsl_ir_constant *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned i const struct vkd3d_shader_location loc) DECLSPEC_HIDDEN; struct hlsl_ir_node *hlsl_new_unary_expr(enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, struct vkd3d_shader_location loc) DECLSPEC_HIDDEN; -struct hlsl_ir_var *hlsl_new_var(const char *name, struct hlsl_type *type, const struct vkd3d_shader_location loc, - const char *semantic, const struct hlsl_reg_reservation *reg_reservation) DECLSPEC_HIDDEN; +struct hlsl_ir_var *hlsl_new_var(const char *name, struct hlsl_type *type, + const struct vkd3d_shader_location loc, const char *semantic, unsigned int modifiers, + const struct hlsl_reg_reservation *reg_reservation) DECLSPEC_HIDDEN; struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ir_var *var, const struct vkd3d_shader_location loc) DECLSPEC_HIDDEN;
void hlsl_error(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc, enum vkd3d_shader_error error, diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 8cd80533..bc4e1b8d 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -763,25 +763,10 @@ static bool add_func_parameter(struct hlsl_ctx *ctx, struct list *list, if (param->type->type == HLSL_CLASS_MATRIX) assert(param->type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK);
- if (!(var = hlsl_new_var(param->name, param->type, loc, param->semantic, param->reg_reservation))) + if (!(var = hlsl_new_var(param->name, param->type, loc, param->semantic, param->modifiers, param->reg_reservation))) return false; var->is_param = 1;
- if (param->type->type != HLSL_CLASS_OBJECT) - { - if (param->modifiers & HLSL_STORAGE_UNIFORM) - { - var->is_uniform = 1; - } - else - { - if (param->modifiers & HLSL_STORAGE_IN) - var->is_input_varying = 1; - if (param->modifiers & HLSL_STORAGE_OUT) - var->is_output_varying = 1; - } - } - if (!hlsl_add_var(ctx, var, false)) { hlsl_free_var(var); @@ -1424,7 +1409,7 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t if (type->type != HLSL_CLASS_MATRIX) check_invalid_matrix_modifiers(ctx, modifiers, v->loc);
- if (!(var = hlsl_new_var(v->name, type, v->loc, v->semantic, v->reg_reservation))) + if (!(var = hlsl_new_var(v->name, type, v->loc, v->semantic, modifiers, v->reg_reservation))) { free_parse_variable_def(v); continue; @@ -1432,9 +1417,6 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t
if (ctx->cur_scope == ctx->globals) { - if (type->type != HLSL_CLASS_OBJECT && !(modifiers & HLSL_STORAGE_STATIC)) - var->is_uniform = 1; - local = false;
if ((func = hlsl_get_func_decl(ctx, var->name))) diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index b3e59bc7..3fadc288 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -35,14 +35,13 @@ static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct list *instrs, stru /* Use the synthetic name for the temp, rather than the uniform, so that we * can write the uniform name into the shader reflection data. */
- if (!(uniform = hlsl_new_var(temp->name, temp->data_type, temp->loc, NULL, temp->reg_reservation))) + if (!(uniform = hlsl_new_var(temp->name, temp->data_type, temp->loc, NULL, 0, temp->reg_reservation))) { ctx->failed = true; return; } list_add_before(&temp->scope_entry, &uniform->scope_entry); list_add_tail(&ctx->extern_vars, &uniform->extern_entry); - temp->is_uniform = 0; uniform->is_uniform = 1; uniform->is_param = temp->is_param;
@@ -85,7 +84,7 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct return; } vkd3d_string_buffer_printf(name, "<input-%s>", semantic); - if (!(varying = hlsl_new_var(vkd3d_strdup(name->buffer), type, var->loc, vkd3d_strdup(semantic), NULL))) + if (!(varying = hlsl_new_var(vkd3d_strdup(name->buffer), type, var->loc, vkd3d_strdup(semantic), 0, NULL))) { vkd3d_string_buffer_release(&ctx->string_buffers, name); ctx->failed = true; @@ -145,8 +144,6 @@ static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct list *instrs, st prepend_input_struct_copy(ctx, instrs, var, var->data_type, 0); else if (var->semantic) prepend_input_copy(ctx, instrs, var, var->data_type, 0, var->semantic); - - var->is_input_varying = 0; }
static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var, @@ -164,7 +161,7 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct return; } vkd3d_string_buffer_printf(name, "<output-%s>", semantic); - if (!(varying = hlsl_new_var(vkd3d_strdup(name->buffer), type, var->loc, vkd3d_strdup(semantic), NULL))) + if (!(varying = hlsl_new_var(vkd3d_strdup(name->buffer), type, var->loc, vkd3d_strdup(semantic), 0, NULL))) { vkd3d_string_buffer_release(&ctx->string_buffers, name); ctx->failed = true; @@ -224,8 +221,6 @@ static void append_output_var_copy(struct hlsl_ctx *ctx, struct list *instrs, st append_output_struct_copy(ctx, instrs, var, var->data_type, 0); else if (var->semantic) append_output_copy(ctx, instrs, var, var->data_type, 0, var->semantic); - - var->is_output_varying = 0; }
static bool transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, struct hlsl_ir_node *, void *), @@ -1315,23 +1310,43 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun { if (var->data_type->type == HLSL_CLASS_OBJECT) list_add_tail(&ctx->extern_vars, &var->extern_entry); - if (var->is_uniform) + else if (!(var->modifiers & HLSL_STORAGE_STATIC)) prepend_uniform_copy(ctx, entry_func->body, var); }
LIST_FOR_EACH_ENTRY(var, entry_func->parameters, struct hlsl_ir_var, param_entry) { if (var->data_type->type == HLSL_CLASS_OBJECT) + { list_add_tail(&ctx->extern_vars, &var->extern_entry); - if (var->is_uniform) - prepend_uniform_copy(ctx, entry_func->body, var); - if (var->is_input_varying) - prepend_input_var_copy(ctx, entry_func->body, var); - if (var->is_output_varying) - append_output_var_copy(ctx, entry_func->body, var); + } + else + { + if (var->modifiers & HLSL_STORAGE_UNIFORM) + { + prepend_uniform_copy(ctx, entry_func->body, var); + } + else + { + if (var->data_type->type != HLSL_CLASS_STRUCT && !var->semantic) + 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) + prepend_input_var_copy(ctx, entry_func->body, var); + if (var->modifiers & HLSL_STORAGE_OUT) + append_output_var_copy(ctx, entry_func->body, var); + } + } } if (entry_func->return_var) + { + if (entry_func->return_var->data_type->type != HLSL_CLASS_STRUCT && !entry_func->return_var->semantic) + hlsl_error(ctx, entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, + "Entry point "%s" is missing a return value semantic.", entry_func->func->name); + append_output_var_copy(ctx, entry_func->body, entry_func->return_var); + }
while (transform_ir(ctx, fold_redundant_casts, entry_func->body, NULL)); while (transform_ir(ctx, split_struct_copies, entry_func->body, NULL));
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
On Tue, Apr 27, 2021 at 7:30 PM Zebediah Figura zfigura@codeweavers.com wrote:
In fact, don't even mark them directly; only mark the synthetic variables.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
v2: New patch.
Nice patch, just a nitpick.
libs/vkd3d-shader/hlsl.c | 38 +++++++++++---------------- libs/vkd3d-shader/hlsl.h | 6 +++-- libs/vkd3d-shader/hlsl.y | 22 ++-------------- libs/vkd3d-shader/hlsl_codegen.c | 45 +++++++++++++++++++++----------- 4 files changed, 51 insertions(+), 60 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 50b40d65..5804c8e5 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -388,7 +388,7 @@ struct hlsl_ir_expr *hlsl_new_copy(struct hlsl_ir_node *node) }
struct hlsl_ir_var *hlsl_new_var(const char *name, struct hlsl_type *type, const struct vkd3d_shader_location loc,
const char *semantic, const struct hlsl_reg_reservation *reg_reservation)
const char *semantic, unsigned int modifiers, const struct hlsl_reg_reservation *reg_reservation)
{ struct hlsl_ir_var *var;
@@ -399,6 +399,7 @@ struct hlsl_ir_var *hlsl_new_var(const char *name, struct hlsl_type *type, const var->data_type = type; var->loc = loc; var->semantic = semantic;
- var->modifiers = modifiers; var->reg_reservation = reg_reservation; return var;
} @@ -406,7 +407,7 @@ struct hlsl_ir_var *hlsl_new_var(const char *name, struct hlsl_type *type, const struct hlsl_ir_var *hlsl_new_synthetic_var(struct hlsl_ctx *ctx, const char *name, struct hlsl_type *type, const struct vkd3d_shader_location loc) {
- struct hlsl_ir_var *var = hlsl_new_var(vkd3d_strdup(name), type, loc, NULL, NULL);
struct hlsl_ir_var *var = hlsl_new_var(vkd3d_strdup(name), type, loc, NULL, 0, NULL);
if (var) list_add_tail(&ctx->globals->vars, &var->scope_entry);
@@ -571,7 +572,7 @@ struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, struct hl char name[28];
sprintf(name, "<retval-%p>", decl);
if (!(return_var = hlsl_new_var(vkd3d_strdup(name), return_type, loc, semantic, NULL)))
if (!(return_var = hlsl_new_var(vkd3d_strdup(name), return_type, loc, semantic, 0, NULL))) { vkd3d_free(decl); return NULL;
@@ -868,12 +869,17 @@ static void dump_src(struct vkd3d_string_buffer *buffer, const struct hlsl_src *
static void dump_ir_var(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_var *var) {
- if (var->is_input_varying)
vkd3d_string_buffer_printf(buffer, "in ");
- if (var->is_output_varying)
vkd3d_string_buffer_printf(buffer, "out ");
- if (var->is_uniform)
vkd3d_string_buffer_printf(buffer, "uniform ");
- if (var->modifiers)
- {
struct vkd3d_string_buffer_cache string_buffers;
struct vkd3d_string_buffer *string;
vkd3d_string_buffer_cache_init(&string_buffers);
if ((string = hlsl_modifiers_to_string(&string_buffers, var->modifiers)))
vkd3d_string_buffer_printf(buffer, "%s ", string->buffer);
vkd3d_string_buffer_release(&string_buffers, string);
vkd3d_string_buffer_cache_cleanup(&string_buffers);
- } vkd3d_string_buffer_printf(buffer, "%s %s", debug_hlsl_type(var->data_type), var->name); if (var->semantic) vkd3d_string_buffer_printf(buffer, " : %s", var->semantic);
I guess this is okay for now (also I don't know how "temporary" this code is) but, in general, creating and destroying a vkd3d_string_buffer_cache every time kinda defeats the purpose of the structure. Passing struct hlsl_ctx around might require some changes in this area but it's probably the direction to move towards.
On 5/10/21 7:19 AM, Matteo Bruni wrote:
On Tue, Apr 27, 2021 at 7:30 PM Zebediah Figura zfigura@codeweavers.com wrote:
In fact, don't even mark them directly; only mark the synthetic variables.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
v2: New patch.
Nice patch, just a nitpick.
libs/vkd3d-shader/hlsl.c | 38 +++++++++++---------------- libs/vkd3d-shader/hlsl.h | 6 +++-- libs/vkd3d-shader/hlsl.y | 22 ++-------------- libs/vkd3d-shader/hlsl_codegen.c | 45 +++++++++++++++++++++----------- 4 files changed, 51 insertions(+), 60 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 50b40d65..5804c8e5 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -388,7 +388,7 @@ struct hlsl_ir_expr *hlsl_new_copy(struct hlsl_ir_node *node) }
struct hlsl_ir_var *hlsl_new_var(const char *name, struct hlsl_type *type, const struct vkd3d_shader_location loc,
const char *semantic, const struct hlsl_reg_reservation *reg_reservation)
{ struct hlsl_ir_var *var;const char *semantic, unsigned int modifiers, const struct hlsl_reg_reservation *reg_reservation)
@@ -399,6 +399,7 @@ struct hlsl_ir_var *hlsl_new_var(const char *name, struct hlsl_type *type, const var->data_type = type; var->loc = loc; var->semantic = semantic;
- var->modifiers = modifiers; var->reg_reservation = reg_reservation; return var; }
@@ -406,7 +407,7 @@ struct hlsl_ir_var *hlsl_new_var(const char *name, struct hlsl_type *type, const struct hlsl_ir_var *hlsl_new_synthetic_var(struct hlsl_ctx *ctx, const char *name, struct hlsl_type *type, const struct vkd3d_shader_location loc) {
- struct hlsl_ir_var *var = hlsl_new_var(vkd3d_strdup(name), type, loc, NULL, NULL);
struct hlsl_ir_var *var = hlsl_new_var(vkd3d_strdup(name), type, loc, NULL, 0, NULL);
if (var) list_add_tail(&ctx->globals->vars, &var->scope_entry);
@@ -571,7 +572,7 @@ struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, struct hl char name[28];
sprintf(name, "<retval-%p>", decl);
if (!(return_var = hlsl_new_var(vkd3d_strdup(name), return_type, loc, semantic, NULL)))
if (!(return_var = hlsl_new_var(vkd3d_strdup(name), return_type, loc, semantic, 0, NULL))) { vkd3d_free(decl); return NULL;
@@ -868,12 +869,17 @@ static void dump_src(struct vkd3d_string_buffer *buffer, const struct hlsl_src *
static void dump_ir_var(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_var *var) {
- if (var->is_input_varying)
vkd3d_string_buffer_printf(buffer, "in ");
- if (var->is_output_varying)
vkd3d_string_buffer_printf(buffer, "out ");
- if (var->is_uniform)
vkd3d_string_buffer_printf(buffer, "uniform ");
- if (var->modifiers)
- {
struct vkd3d_string_buffer_cache string_buffers;
struct vkd3d_string_buffer *string;
vkd3d_string_buffer_cache_init(&string_buffers);
if ((string = hlsl_modifiers_to_string(&string_buffers, var->modifiers)))
vkd3d_string_buffer_printf(buffer, "%s ", string->buffer);
vkd3d_string_buffer_release(&string_buffers, string);
vkd3d_string_buffer_cache_cleanup(&string_buffers);
- } vkd3d_string_buffer_printf(buffer, "%s %s", debug_hlsl_type(var->data_type), var->name); if (var->semantic) vkd3d_string_buffer_printf(buffer, " : %s", var->semantic);
I guess this is okay for now (also I don't know how "temporary" this code is) but, in general, creating and destroying a vkd3d_string_buffer_cache every time kinda defeats the purpose of the structure. Passing struct hlsl_ctx around might require some changes in this area but it's probably the direction to move towards.
I didn't put any priority towards it as it's in the debug path, but it's probably a good idea regardless.
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v2: Rebase.
libs/vkd3d-shader/hlsl.c | 27 ++++++++------- libs/vkd3d-shader/hlsl.h | 15 ++++++--- libs/vkd3d-shader/hlsl.y | 34 +++++++++++-------- libs/vkd3d-shader/hlsl_codegen.c | 56 +++++++++++++++++++++----------- 4 files changed, 85 insertions(+), 47 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 5804c8e5..e81efa2d 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -93,7 +93,7 @@ struct hlsl_ir_var *hlsl_get_var(struct hlsl_scope *scope, const char *name) void hlsl_free_var(struct hlsl_ir_var *decl) { vkd3d_free((void *)decl->name); - vkd3d_free((void *)decl->semantic); + vkd3d_free((void *)decl->semantic.name); vkd3d_free((void *)decl->reg_reservation); vkd3d_free(decl); } @@ -326,7 +326,7 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, u { LIST_FOR_EACH_ENTRY_SAFE(field, old_field, type->e.elements, struct hlsl_struct_field, entry) { - vkd3d_free((void *)field->semantic); + vkd3d_free((void *)field->semantic.name); vkd3d_free((void *)field->name); vkd3d_free(field); } @@ -338,8 +338,11 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, u field->loc = old_field->loc; field->type = hlsl_type_clone(ctx, old_field->type, default_majority); field->name = vkd3d_strdup(old_field->name); - if (old_field->semantic) - field->semantic = vkd3d_strdup(old_field->semantic); + if (old_field->semantic.name) + { + field->semantic.name = vkd3d_strdup(old_field->semantic.name); + field->semantic.index = old_field->semantic.index; + } field->reg_offset = reg_size; reg_size += field->type->reg_size; list_add_tail(type->e.elements, &field->entry); @@ -387,8 +390,9 @@ struct hlsl_ir_expr *hlsl_new_copy(struct hlsl_ir_node *node) return hlsl_new_cast(node, node->data_type, &node->loc); }
-struct hlsl_ir_var *hlsl_new_var(const char *name, struct hlsl_type *type, const struct vkd3d_shader_location loc, - const char *semantic, unsigned int modifiers, const struct hlsl_reg_reservation *reg_reservation) +struct hlsl_ir_var *hlsl_new_var(const char *name, struct hlsl_type *type, + const struct vkd3d_shader_location loc, const struct hlsl_semantic *semantic, unsigned int modifiers, + const struct hlsl_reg_reservation *reg_reservation) { struct hlsl_ir_var *var;
@@ -398,7 +402,8 @@ struct hlsl_ir_var *hlsl_new_var(const char *name, struct hlsl_type *type, const var->name = name; var->data_type = type; var->loc = loc; - var->semantic = semantic; + if (semantic) + var->semantic = *semantic; var->modifiers = modifiers; var->reg_reservation = reg_reservation; return var; @@ -556,7 +561,7 @@ bool hlsl_type_is_void(const struct hlsl_type *type) }
struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, struct hlsl_type *return_type, - struct list *parameters, const char *semantic, struct vkd3d_shader_location loc) + struct list *parameters, const struct hlsl_semantic *semantic, struct vkd3d_shader_location loc) { struct hlsl_ir_function_decl *decl;
@@ -881,8 +886,8 @@ static void dump_ir_var(struct vkd3d_string_buffer *buffer, const struct hlsl_ir vkd3d_string_buffer_cache_cleanup(&string_buffers); } vkd3d_string_buffer_printf(buffer, "%s %s", debug_hlsl_type(var->data_type), var->name); - if (var->semantic) - vkd3d_string_buffer_printf(buffer, " : %s", var->semantic); + if (var->semantic.name) + vkd3d_string_buffer_printf(buffer, " : %s%u", var->semantic.name, var->semantic.index); }
static void dump_deref(struct vkd3d_string_buffer *buffer, const struct hlsl_deref *deref) @@ -1184,7 +1189,7 @@ void hlsl_free_type(struct hlsl_type *type) LIST_FOR_EACH_ENTRY_SAFE(field, next_field, type->e.elements, struct hlsl_struct_field, entry) { vkd3d_free((void *)field->name); - vkd3d_free((void *)field->semantic); + vkd3d_free((void *)field->semantic.name); vkd3d_free(field); } } diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 1c5f63aa..c698983a 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -129,13 +129,19 @@ struct hlsl_type unsigned int bytecode_offset; };
+struct hlsl_semantic +{ + const char *name; + uint32_t index; +}; + struct hlsl_struct_field { struct list entry; struct vkd3d_shader_location loc; struct hlsl_type *type; const char *name; - const char *semantic; + struct hlsl_semantic semantic; unsigned int reg_offset;
unsigned int name_bytecode_offset; @@ -215,7 +221,7 @@ struct hlsl_ir_var struct hlsl_type *data_type; struct vkd3d_shader_location loc; const char *name; - const char *semantic; + struct hlsl_semantic semantic; unsigned int modifiers; const struct hlsl_reg_reservation *reg_reservation; struct list scope_entry, param_entry, extern_entry; @@ -569,7 +575,8 @@ struct hlsl_ir_expr *hlsl_new_cast(struct hlsl_ir_node *node, struct hlsl_type * struct vkd3d_shader_location *loc) DECLSPEC_HIDDEN; struct hlsl_ir_expr *hlsl_new_copy(struct hlsl_ir_node *node) DECLSPEC_HIDDEN; struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, struct hlsl_type *return_type, - struct list *parameters, const char *semantic, struct vkd3d_shader_location loc) DECLSPEC_HIDDEN; + struct list *parameters, const struct hlsl_semantic *semantic, + struct vkd3d_shader_location loc) DECLSPEC_HIDDEN; struct hlsl_ir_if *hlsl_new_if(struct hlsl_ir_node *condition, struct vkd3d_shader_location loc) DECLSPEC_HIDDEN; struct hlsl_ir_jump *hlsl_new_jump(enum hlsl_ir_jump_type type, struct vkd3d_shader_location loc) DECLSPEC_HIDDEN; struct hlsl_ir_load *hlsl_new_load(struct hlsl_ir_var *var, struct hlsl_ir_node *offset, struct hlsl_type *type, @@ -591,7 +598,7 @@ struct hlsl_ir_constant *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned i struct hlsl_ir_node *hlsl_new_unary_expr(enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, struct vkd3d_shader_location loc) DECLSPEC_HIDDEN; struct hlsl_ir_var *hlsl_new_var(const char *name, struct hlsl_type *type, - const struct vkd3d_shader_location loc, const char *semantic, unsigned int modifiers, + const struct vkd3d_shader_location loc, const struct hlsl_semantic *semantic, unsigned int modifiers, const struct hlsl_reg_reservation *reg_reservation) DECLSPEC_HIDDEN; struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ir_var *var, const struct vkd3d_shader_location loc) DECLSPEC_HIDDEN;
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index bc4e1b8d..4e17e806 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -32,14 +32,14 @@ struct parse_parameter { struct hlsl_type *type; const char *name; - const char *semantic; + struct hlsl_semantic semantic; const struct hlsl_reg_reservation *reg_reservation; unsigned int modifiers; };
struct parse_colon_attribute { - const char *semantic; + struct hlsl_semantic semantic; struct hlsl_reg_reservation *reg_reservation; };
@@ -63,7 +63,7 @@ struct parse_variable_def
char *name; struct parse_array_sizes arrays; - const char *semantic; + struct hlsl_semantic semantic; struct hlsl_reg_reservation *reg_reservation; struct parse_initializer initializer; }; @@ -763,7 +763,7 @@ static bool add_func_parameter(struct hlsl_ctx *ctx, struct list *list, if (param->type->type == HLSL_CLASS_MATRIX) assert(param->type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK);
- if (!(var = hlsl_new_var(param->name, param->type, loc, param->semantic, param->modifiers, param->reg_reservation))) + if (!(var = hlsl_new_var(param->name, param->type, loc, ¶m->semantic, param->modifiers, param->reg_reservation))) return false; var->is_param = 1;
@@ -1369,7 +1369,7 @@ static void free_parse_variable_def(struct parse_variable_def *v) free_parse_initializer(&v->initializer); vkd3d_free(v->arrays.sizes); vkd3d_free(v->name); - vkd3d_free((void *)v->semantic); + vkd3d_free((void *)v->semantic.name); vkd3d_free(v->reg_reservation); vkd3d_free(v); } @@ -1409,7 +1409,7 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t if (type->type != HLSL_CLASS_MATRIX) check_invalid_matrix_modifiers(ctx, modifiers, v->loc);
- if (!(var = hlsl_new_var(v->name, type, v->loc, v->semantic, modifiers, v->reg_reservation))) + if (!(var = hlsl_new_var(v->name, type, v->loc, &v->semantic, modifiers, v->reg_reservation))) { free_parse_variable_def(v); continue; @@ -1441,7 +1441,7 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t "Modifiers '%s' are not allowed on local variables.", string->buffer); vkd3d_string_buffer_release(&ctx->string_buffers, string); } - if (var->semantic) + if (var->semantic.name) hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, "Semantics are not allowed on local variables."); } @@ -1572,6 +1572,7 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t enum parse_assign_op assign_op; struct hlsl_reg_reservation *reg_reservation; struct parse_colon_attribute colon_attribute; + struct hlsl_semantic semantic; }
%token KW_BLENDSTATE @@ -1737,13 +1738,14 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t %type <modifiers> var_modifiers
%type <name> any_identifier -%type <name> semantic %type <name> var_identifier
%type <parameter> parameter
%type <reg_reservation> register_opt
+%type <semantic> semantic + %type <type> base_type %type <type> field_type %type <type> named_struct_spec @@ -1960,7 +1962,7 @@ func_prototype: ""%s" was previously declared here.", $3); YYABORT; } - if (hlsl_type_is_void($2) && $7.semantic) + if (hlsl_type_is_void($2) && $7.semantic.name) { hlsl_error(ctx, @7, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, "Semantics are not allowed on void functions."); @@ -1971,7 +1973,7 @@ func_prototype: FIXME("Unexpected register reservation for a function.\n"); vkd3d_free($7.reg_reservation); } - if (!($$.decl = hlsl_new_func_decl(ctx, $2, $5, $7.semantic, @3))) + if (!($$.decl = hlsl_new_func_decl(ctx, $2, $5, &$7.semantic, @3))) YYABORT; $$.name = $3; ctx->cur_function = $$.decl; @@ -2002,7 +2004,7 @@ var_identifier: colon_attribute: %empty { - $$.semantic = NULL; + $$.semantic.name = NULL; $$.reg_reservation = NULL; } | semantic @@ -2012,14 +2014,20 @@ colon_attribute: } | register_opt { - $$.semantic = NULL; + $$.semantic.name = NULL; $$.reg_reservation = $1; }
semantic: ':' any_identifier { - $$ = $2; + char *p; + + for (p = $2 + strlen($2); p > $2 && isdigit(p[-1]); --p) + ; + $$.name = $2; + $$.index = atoi(p); + *p = 0; }
/* FIXME: Writemasks */ diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 3fadc288..180259f6 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -70,9 +70,10 @@ static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct list *instrs, stru }
static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var, - struct hlsl_type *type, unsigned int field_offset, const char *semantic) + struct hlsl_type *type, unsigned int field_offset, const struct hlsl_semantic *semantic) { struct vkd3d_string_buffer *name; + struct hlsl_semantic new_semantic; struct hlsl_ir_constant *offset; struct hlsl_ir_store *store; struct hlsl_ir_var *varying; @@ -83,13 +84,21 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct ctx->failed = true; return; } - vkd3d_string_buffer_printf(name, "<input-%s>", semantic); - if (!(varying = hlsl_new_var(vkd3d_strdup(name->buffer), type, var->loc, vkd3d_strdup(semantic), 0, NULL))) + vkd3d_string_buffer_printf(name, "<input-%s%u>", semantic->name, semantic->index); + if (!(new_semantic.name = vkd3d_strdup(semantic->name))) { vkd3d_string_buffer_release(&ctx->string_buffers, name); ctx->failed = true; return; } + new_semantic.index = semantic->index; + if (!(varying = hlsl_new_var(vkd3d_strdup(name->buffer), type, var->loc, &new_semantic, 0, NULL))) + { + vkd3d_string_buffer_release(&ctx->string_buffers, name); + vkd3d_free((void *)new_semantic.name); + ctx->failed = true; + return; + } vkd3d_string_buffer_release(&ctx->string_buffers, name); varying->is_input_varying = 1; varying->is_param = var->is_param; @@ -127,8 +136,8 @@ 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, var, field->type, field_offset + field->reg_offset); - else if (field->semantic) - prepend_input_copy(ctx, instrs, var, field->type, field_offset + field->reg_offset, field->semantic); + else if (field->semantic.name) + prepend_input_copy(ctx, instrs, var, field->type, field_offset + field->reg_offset, &field->semantic); else hlsl_error(ctx, field->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, "Field '%s' is missing a semantic.", field->name); @@ -142,14 +151,15 @@ 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, var, var->data_type, 0); - else if (var->semantic) - prepend_input_copy(ctx, instrs, var, var->data_type, 0, var->semantic); + else if (var->semantic.name) + prepend_input_copy(ctx, instrs, var, var->data_type, 0, &var->semantic); }
static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var, - struct hlsl_type *type, unsigned int field_offset, const char *semantic) + struct hlsl_type *type, unsigned int field_offset, const struct hlsl_semantic *semantic) { struct vkd3d_string_buffer *name; + struct hlsl_semantic new_semantic; struct hlsl_ir_constant *offset; struct hlsl_ir_store *store; struct hlsl_ir_var *varying; @@ -160,9 +170,17 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct ctx->failed = true; return; } - vkd3d_string_buffer_printf(name, "<output-%s>", semantic); - if (!(varying = hlsl_new_var(vkd3d_strdup(name->buffer), type, var->loc, vkd3d_strdup(semantic), 0, NULL))) + vkd3d_string_buffer_printf(name, "<output-%s%u>", semantic->name, semantic->index); + if (!(new_semantic.name = vkd3d_strdup(semantic->name))) + { + vkd3d_string_buffer_release(&ctx->string_buffers, name); + ctx->failed = true; + return; + } + new_semantic.index = semantic->index; + if (!(varying = hlsl_new_var(vkd3d_strdup(name->buffer), type, var->loc, &new_semantic, 0, NULL))) { + vkd3d_free((void *)new_semantic.name); vkd3d_string_buffer_release(&ctx->string_buffers, name); ctx->failed = true; return; @@ -204,8 +222,8 @@ 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, var, field->type, field_offset + field->reg_offset); - else if (field->semantic) - append_output_copy(ctx, instrs, var, field->type, field_offset + field->reg_offset, field->semantic); + else if (field->semantic.name) + append_output_copy(ctx, instrs, var, field->type, field_offset + field->reg_offset, &field->semantic); else hlsl_error(ctx, field->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, "Field '%s' is missing a semantic.", field->name); @@ -219,8 +237,8 @@ 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, var, var->data_type, 0); - else if (var->semantic) - append_output_copy(ctx, instrs, var, var->data_type, 0, var->semantic); + else if (var->semantic.name) + append_output_copy(ctx, instrs, var, var->data_type, 0, &var->semantic); }
static bool transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, struct hlsl_ir_node *, void *), @@ -1180,7 +1198,7 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct bytecode_buffer *buf
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { - if (!var->semantic && var->reg.allocated) + if (!var->semantic.name && var->reg.allocated) { ++uniform_count;
@@ -1218,7 +1236,7 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct bytecode_buffer *buf
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { - if (!var->semantic && var->reg.allocated) + if (!var->semantic.name && var->reg.allocated) { put_dword(buffer, 0); /* name */ put_dword(buffer, D3DXRS_FLOAT4 | (var->reg.id << 16)); @@ -1232,7 +1250,7 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct bytecode_buffer *buf
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { - if (!var->semantic && var->reg.allocated) + if (!var->semantic.name && var->reg.allocated) { set_dword(buffer, vars_start + (uniform_count * 5), (buffer->count - ctab_start) * sizeof(*buffer->data)); put_string(buffer, var->name); @@ -1328,7 +1346,7 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun } else { - if (var->data_type->type != HLSL_CLASS_STRUCT && !var->semantic) + if (var->data_type->type != HLSL_CLASS_STRUCT && !var->semantic.name) hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, "Parameter "%s" is missing a semantic.", var->name);
@@ -1341,7 +1359,7 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun } if (entry_func->return_var) { - if (entry_func->return_var->data_type->type != HLSL_CLASS_STRUCT && !entry_func->return_var->semantic) + if (entry_func->return_var->data_type->type != HLSL_CLASS_STRUCT && !entry_func->return_var->semantic.name) hlsl_error(ctx, entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, "Entry point "%s" is missing a return value semantic.", entry_func->func->name);
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
It's not particularly accurate; "varying" only refers to the interface between two consecutive shader stages.
Replace it with "semantic" in most cases.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v2: New patch.
Makefile.am | 4 +- libs/vkd3d-shader/hlsl.h | 4 +- libs/vkd3d-shader/hlsl_codegen.c | 43 +++++++++---------- ...test => hlsl-struct-semantics.shader_test} | 0 4 files changed, 25 insertions(+), 26 deletions(-) rename tests/{hlsl-struct-varying.shader_test => hlsl-struct-semantics.shader_test} (100%)
diff --git a/Makefile.am b/Makefile.am index cbf75ad8..542b66e7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -65,7 +65,7 @@ vkd3d_shader_tests = \ tests/hlsl-return-void.shader_test \ tests/hlsl-static-initializer.shader_test \ tests/hlsl-struct-assignment.shader_test \ - tests/hlsl-struct-varying.shader_test \ + tests/hlsl-struct-semantics.shader_test \ tests/hlsl-vector-indexing.shader_test \ tests/hlsl-vector-indexing-uniform.shader_test \ tests/math.shader_test \ @@ -262,7 +262,7 @@ XFAIL_TESTS = \ tests/hlsl-return-void.shader_test \ tests/hlsl-static-initializer.shader_test \ tests/hlsl-struct-assignment.shader_test \ - tests/hlsl-struct-varying.shader_test \ + tests/hlsl-struct-semantics.shader_test \ tests/hlsl-vector-indexing.shader_test \ tests/hlsl-vector-indexing-uniform.shader_test \ tests/math.shader_test \ diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index c698983a..9081ef37 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -229,8 +229,8 @@ struct hlsl_ir_var unsigned int first_write, last_read; struct hlsl_reg reg;
- uint32_t is_input_varying : 1; - uint32_t is_output_varying : 1; + uint32_t is_input_semantic : 1; + uint32_t is_output_semantic : 1; uint32_t is_uniform : 1; uint32_t is_param : 1; }; diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 180259f6..787d3360 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -76,8 +76,8 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct struct hlsl_semantic new_semantic; struct hlsl_ir_constant *offset; struct hlsl_ir_store *store; - struct hlsl_ir_var *varying; struct hlsl_ir_load *load; + struct hlsl_ir_var *input;
if (!(name = vkd3d_string_buffer_get(&ctx->string_buffers))) { @@ -92,7 +92,7 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct return; } new_semantic.index = semantic->index; - if (!(varying = hlsl_new_var(vkd3d_strdup(name->buffer), type, var->loc, &new_semantic, 0, NULL))) + if (!(input = hlsl_new_var(vkd3d_strdup(name->buffer), type, var->loc, &new_semantic, 0, NULL))) { vkd3d_string_buffer_release(&ctx->string_buffers, name); vkd3d_free((void *)new_semantic.name); @@ -100,12 +100,12 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct return; } vkd3d_string_buffer_release(&ctx->string_buffers, name); - varying->is_input_varying = 1; - varying->is_param = var->is_param; - list_add_before(&var->scope_entry, &varying->scope_entry); - list_add_tail(&ctx->extern_vars, &varying->extern_entry); + input->is_input_semantic = 1; + input->is_param = var->is_param; + list_add_before(&var->scope_entry, &input->scope_entry); + list_add_tail(&ctx->extern_vars, &input->extern_entry);
- if (!(load = hlsl_new_var_load(varying, var->loc))) + if (!(load = hlsl_new_var_load(input, var->loc))) { ctx->failed = true; return; @@ -144,9 +144,8 @@ static void prepend_input_struct_copy(struct hlsl_ctx *ctx, struct list *instrs, } }
-/* Split input varyings into two variables representing the varying and temp - * registers, and copy the former to the latter, so that writes to input - * varyings work. */ +/* Split inputs into two variables representing the semantic and temp registers, + * and copy the former to the latter, so that writes to input variables work. */ static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var) { if (var->data_type->type == HLSL_CLASS_STRUCT) @@ -162,7 +161,7 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct struct hlsl_semantic new_semantic; struct hlsl_ir_constant *offset; struct hlsl_ir_store *store; - struct hlsl_ir_var *varying; + struct hlsl_ir_var *output; struct hlsl_ir_load *load;
if (!(name = vkd3d_string_buffer_get(&ctx->string_buffers))) @@ -178,7 +177,7 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct return; } new_semantic.index = semantic->index; - if (!(varying = hlsl_new_var(vkd3d_strdup(name->buffer), type, var->loc, &new_semantic, 0, NULL))) + if (!(output = hlsl_new_var(vkd3d_strdup(name->buffer), type, var->loc, &new_semantic, 0, NULL))) { vkd3d_free((void *)new_semantic.name); vkd3d_string_buffer_release(&ctx->string_buffers, name); @@ -186,10 +185,10 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct return; } vkd3d_string_buffer_release(&ctx->string_buffers, name); - varying->is_output_varying = 1; - varying->is_param = var->is_param; - list_add_before(&var->scope_entry, &varying->scope_entry); - list_add_tail(&ctx->extern_vars, &varying->extern_entry); + output->is_output_semantic = 1; + output->is_param = var->is_param; + list_add_before(&var->scope_entry, &output->scope_entry); + list_add_tail(&ctx->extern_vars, &output->extern_entry);
if (!(offset = hlsl_new_uint_constant(ctx, field_offset * 4, var->loc))) { @@ -205,7 +204,7 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct } list_add_after(&offset->node.entry, &load->node.entry);
- if (!(store = hlsl_new_store(varying, NULL, &load->node, 0, var->loc))) + if (!(store = hlsl_new_store(output, NULL, &load->node, 0, var->loc))) { ctx->failed = true; return; @@ -230,9 +229,9 @@ static void append_output_struct_copy(struct hlsl_ctx *ctx, struct list *instrs, } }
-/* Split output varyings into two variables representing the temp and varying +/* Split outputs into two variables representing the temp and semantic * registers, and copy the former to the latter, so that reads from output - * varyings work. */ + * variables work. */ static void append_output_var_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var) { if (var->data_type->type == HLSL_CLASS_STRUCT) @@ -618,9 +617,9 @@ static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { - if (var->is_uniform || var->is_input_varying) + if (var->is_uniform || var->is_input_semantic) var->first_write = 1; - else if (var->is_output_varying) + else if (var->is_output_semantic) var->last_read = UINT_MAX; }
@@ -744,7 +743,7 @@ static const char *debug_register(char class, struct hlsl_reg reg, const struct
static void allocate_variable_temp_register(struct hlsl_ir_var *var, struct liveness *liveness) { - if (var->is_input_varying || var->is_output_varying || var->is_uniform) + if (var->is_input_semantic || var->is_output_semantic || var->is_uniform) return;
if (!var->reg.allocated && var->last_read) diff --git a/tests/hlsl-struct-varying.shader_test b/tests/hlsl-struct-semantics.shader_test similarity index 100% rename from tests/hlsl-struct-varying.shader_test rename to tests/hlsl-struct-semantics.shader_test
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- Thank you for the patch :)
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v2: Rebase; replace "varying" with "semantic".
include/vkd3d_d3d9types.h | 15 +++++ libs/vkd3d-shader/hlsl_codegen.c | 99 ++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+)
diff --git a/include/vkd3d_d3d9types.h b/include/vkd3d_d3d9types.h index ba7dcbfb..1f886443 100644 --- a/include/vkd3d_d3d9types.h +++ b/include/vkd3d_d3d9types.h @@ -164,5 +164,20 @@ typedef enum _D3DSHADER_PARAM_REGISTER_TYPE D3DSPR_FORCE_DWORD = 0x7fffffff, } D3DSHADER_PARAM_REGISTER_TYPE;
+typedef enum _D3DSHADER_MISCTYPE_OFFSETS +{ + D3DSMO_POSITION = 0x0, + D3DSMO_FACE = 0x1, +} D3DSHADER_MISCTYPE_OFFSETS; + +typedef enum _D3DVS_RASTOUT_OFFSETS +{ + D3DSRO_POSITION = 0x0, + D3DSRO_FOG = 0x1, + D3DSRO_POINT_SIZE = 0x2, + + D3DSRO_FORCE_DWORD = 0x7fffffff, +} D3DVS_RASTOUT_OFFSETS; + #endif /* _d3d9TYPES_H_ */ #endif /* __VKD3D_D3D9TYPES_H */ diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 787d3360..9f2c278c 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -948,6 +948,104 @@ static void allocate_temp_registers(struct hlsl_ir_function_decl *entry_func) allocate_temp_registers_recurse(entry_func->body, &liveness); }
+static bool sm1_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic, bool output, + D3DSHADER_PARAM_REGISTER_TYPE *type, unsigned int *reg) +{ + unsigned int i; + + static const struct + { + const char *semantic; + bool output; + enum vkd3d_shader_type shader_type; + unsigned int major_version; + D3DSHADER_PARAM_REGISTER_TYPE type; + DWORD offset; + } + register_table[] = + { + {"color", true, VKD3D_SHADER_TYPE_PIXEL, 2, D3DSPR_COLOROUT}, + {"depth", true, VKD3D_SHADER_TYPE_PIXEL, 2, D3DSPR_DEPTHOUT}, + {"sv_depth", true, VKD3D_SHADER_TYPE_PIXEL, 2, D3DSPR_DEPTHOUT}, + {"sv_target", true, VKD3D_SHADER_TYPE_PIXEL, 2, D3DSPR_COLOROUT}, + {"color", false, VKD3D_SHADER_TYPE_PIXEL, 2, D3DSPR_INPUT}, + {"texcoord", false, VKD3D_SHADER_TYPE_PIXEL, 2, D3DSPR_TEXTURE}, + + {"color", true, VKD3D_SHADER_TYPE_PIXEL, 3, D3DSPR_COLOROUT}, + {"depth", true, VKD3D_SHADER_TYPE_PIXEL, 3, D3DSPR_DEPTHOUT}, + {"sv_depth", true, VKD3D_SHADER_TYPE_PIXEL, 3, D3DSPR_DEPTHOUT}, + {"sv_target", true, VKD3D_SHADER_TYPE_PIXEL, 3, D3DSPR_COLOROUT}, + {"sv_position", false, VKD3D_SHADER_TYPE_PIXEL, 3, D3DSPR_MISCTYPE, D3DSMO_POSITION}, + {"vface", false, VKD3D_SHADER_TYPE_PIXEL, 3, D3DSPR_MISCTYPE, D3DSMO_FACE}, + {"vpos", false, VKD3D_SHADER_TYPE_PIXEL, 3, D3DSPR_MISCTYPE, D3DSMO_POSITION}, + + {"color", true, VKD3D_SHADER_TYPE_VERTEX, 1, D3DSPR_ATTROUT}, + {"fog", true, VKD3D_SHADER_TYPE_VERTEX, 1, D3DSPR_RASTOUT, D3DSRO_FOG}, + {"position", true, VKD3D_SHADER_TYPE_VERTEX, 1, D3DSPR_RASTOUT, D3DSRO_POSITION}, + {"psize", true, VKD3D_SHADER_TYPE_VERTEX, 1, D3DSPR_RASTOUT, D3DSRO_POINT_SIZE}, + {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 1, D3DSPR_RASTOUT, D3DSRO_POSITION}, + {"texcoord", true, VKD3D_SHADER_TYPE_VERTEX, 1, D3DSPR_TEXCRDOUT}, + + {"color", true, VKD3D_SHADER_TYPE_VERTEX, 2, D3DSPR_ATTROUT}, + {"fog", true, VKD3D_SHADER_TYPE_VERTEX, 2, D3DSPR_RASTOUT, D3DSRO_FOG}, + {"position", true, VKD3D_SHADER_TYPE_VERTEX, 2, D3DSPR_RASTOUT, D3DSRO_POSITION}, + {"psize", true, VKD3D_SHADER_TYPE_VERTEX, 2, D3DSPR_RASTOUT, D3DSRO_POINT_SIZE}, + {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 2, D3DSPR_RASTOUT, D3DSRO_POSITION}, + {"texcoord", true, VKD3D_SHADER_TYPE_VERTEX, 2, D3DSPR_TEXCRDOUT}, + }; + + for (i = 0; i < ARRAY_SIZE(register_table); ++i) + { + if (!ascii_strcasecmp(semantic->name, register_table[i].semantic) + && output == register_table[i].output + && ctx->profile->type == register_table[i].shader_type + && ctx->profile->major_version == register_table[i].major_version) + { + *type = register_table[i].type; + if (register_table[i].type == D3DSPR_MISCTYPE || register_table[i].type == D3DSPR_RASTOUT) + *reg = register_table[i].offset; + else + *reg = semantic->index; + return true; + } + } + + return false; +} + +static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, unsigned int *counter, bool output) +{ + assert(var->semantic.name); + + if (ctx->profile->major_version < 4) + { + D3DSHADER_PARAM_REGISTER_TYPE type; + unsigned int reg; + + if (!sm1_register_from_semantic(ctx, &var->semantic, output, &type, ®)) + { + var->reg.allocated = true; + var->reg.id = (*counter)++; + var->reg.writemask = (1 << var->data_type->dimx) - 1; + TRACE("Allocated %s to %s.\n", var->name, debug_register(output ? 'o' : 'v', var->reg, var->data_type)); + } + } +} + +static void allocate_semantic_registers(struct hlsl_ctx *ctx) +{ + unsigned int input_counter = 0, output_counter = 0; + struct hlsl_ir_var *var; + + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + if (var->is_input_semantic && var->last_read) + allocate_semantic_register(ctx, var, &input_counter, false); + if (var->is_output_semantic && var->first_write) + allocate_semantic_register(ctx, var, &output_counter, true); + } +} + struct bytecode_buffer { uint32_t *data; @@ -1381,6 +1479,7 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun allocate_temp_registers(entry_func); if (ctx->profile->major_version < 4) allocate_const_registers(ctx, entry_func); + allocate_semantic_registers(ctx);
if (ctx->failed) return VKD3D_ERROR_INVALID_SHADER;
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
On Tue, Apr 27, 2021 at 7:30 PM Zebediah Figura zfigura@codeweavers.com wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
v2: Rebase; replace "varying" with "semantic".
include/vkd3d_d3d9types.h | 15 +++++ libs/vkd3d-shader/hlsl_codegen.c | 99 ++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+)
diff --git a/include/vkd3d_d3d9types.h b/include/vkd3d_d3d9types.h index ba7dcbfb..1f886443 100644 --- a/include/vkd3d_d3d9types.h +++ b/include/vkd3d_d3d9types.h @@ -164,5 +164,20 @@ typedef enum _D3DSHADER_PARAM_REGISTER_TYPE D3DSPR_FORCE_DWORD = 0x7fffffff, } D3DSHADER_PARAM_REGISTER_TYPE;
+typedef enum _D3DSHADER_MISCTYPE_OFFSETS +{
- D3DSMO_POSITION = 0x0,
- D3DSMO_FACE = 0x1,
+} D3DSHADER_MISCTYPE_OFFSETS;
+typedef enum _D3DVS_RASTOUT_OFFSETS +{
- D3DSRO_POSITION = 0x0,
- D3DSRO_FOG = 0x1,
- D3DSRO_POINT_SIZE = 0x2,
- D3DSRO_FORCE_DWORD = 0x7fffffff,
+} D3DVS_RASTOUT_OFFSETS;
#endif /* _d3d9TYPES_H_ */ #endif /* __VKD3D_D3D9TYPES_H */ diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 787d3360..9f2c278c 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -948,6 +948,104 @@ static void allocate_temp_registers(struct hlsl_ir_function_decl *entry_func) allocate_temp_registers_recurse(entry_func->body, &liveness); }
+static bool sm1_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic, bool output,
D3DSHADER_PARAM_REGISTER_TYPE *type, unsigned int *reg)
+{
- unsigned int i;
- static const struct
- {
const char *semantic;
bool output;
enum vkd3d_shader_type shader_type;
unsigned int major_version;
D3DSHADER_PARAM_REGISTER_TYPE type;
DWORD offset;
- }
- register_table[] =
- {
{"color", true, VKD3D_SHADER_TYPE_PIXEL, 2, D3DSPR_COLOROUT},
{"depth", true, VKD3D_SHADER_TYPE_PIXEL, 2, D3DSPR_DEPTHOUT},
{"sv_depth", true, VKD3D_SHADER_TYPE_PIXEL, 2, D3DSPR_DEPTHOUT},
{"sv_target", true, VKD3D_SHADER_TYPE_PIXEL, 2, D3DSPR_COLOROUT},
{"color", false, VKD3D_SHADER_TYPE_PIXEL, 2, D3DSPR_INPUT},
{"texcoord", false, VKD3D_SHADER_TYPE_PIXEL, 2, D3DSPR_TEXTURE},
{"color", true, VKD3D_SHADER_TYPE_PIXEL, 3, D3DSPR_COLOROUT},
{"depth", true, VKD3D_SHADER_TYPE_PIXEL, 3, D3DSPR_DEPTHOUT},
{"sv_depth", true, VKD3D_SHADER_TYPE_PIXEL, 3, D3DSPR_DEPTHOUT},
{"sv_target", true, VKD3D_SHADER_TYPE_PIXEL, 3, D3DSPR_COLOROUT},
{"sv_position", false, VKD3D_SHADER_TYPE_PIXEL, 3, D3DSPR_MISCTYPE, D3DSMO_POSITION},
{"vface", false, VKD3D_SHADER_TYPE_PIXEL, 3, D3DSPR_MISCTYPE, D3DSMO_FACE},
{"vpos", false, VKD3D_SHADER_TYPE_PIXEL, 3, D3DSPR_MISCTYPE, D3DSMO_POSITION},
{"color", true, VKD3D_SHADER_TYPE_VERTEX, 1, D3DSPR_ATTROUT},
{"fog", true, VKD3D_SHADER_TYPE_VERTEX, 1, D3DSPR_RASTOUT, D3DSRO_FOG},
{"position", true, VKD3D_SHADER_TYPE_VERTEX, 1, D3DSPR_RASTOUT, D3DSRO_POSITION},
{"psize", true, VKD3D_SHADER_TYPE_VERTEX, 1, D3DSPR_RASTOUT, D3DSRO_POINT_SIZE},
{"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 1, D3DSPR_RASTOUT, D3DSRO_POSITION},
{"texcoord", true, VKD3D_SHADER_TYPE_VERTEX, 1, D3DSPR_TEXCRDOUT},
{"color", true, VKD3D_SHADER_TYPE_VERTEX, 2, D3DSPR_ATTROUT},
{"fog", true, VKD3D_SHADER_TYPE_VERTEX, 2, D3DSPR_RASTOUT, D3DSRO_FOG},
{"position", true, VKD3D_SHADER_TYPE_VERTEX, 2, D3DSPR_RASTOUT, D3DSRO_POSITION},
{"psize", true, VKD3D_SHADER_TYPE_VERTEX, 2, D3DSPR_RASTOUT, D3DSRO_POINT_SIZE},
{"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 2, D3DSPR_RASTOUT, D3DSRO_POSITION},
{"texcoord", true, VKD3D_SHADER_TYPE_VERTEX, 2, D3DSPR_TEXCRDOUT},
- };
- for (i = 0; i < ARRAY_SIZE(register_table); ++i)
- {
if (!ascii_strcasecmp(semantic->name, register_table[i].semantic)
&& output == register_table[i].output
&& ctx->profile->type == register_table[i].shader_type
&& ctx->profile->major_version == register_table[i].major_version)
{
*type = register_table[i].type;
if (register_table[i].type == D3DSPR_MISCTYPE || register_table[i].type == D3DSPR_RASTOUT)
*reg = register_table[i].offset;
else
*reg = semantic->index;
return true;
This branch could use a TRACE() (e.g. TRACE(""Semantic %s[%u] matches with system value %#x[%u].\n", semantic->name, semantic->index, *type, *reg")). The trace might be clearer in the caller, or maybe you have something already in the following patches.
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- Sorry for taking so long to review this round of patches... I particularly appreciated the changelogs, very useful!