Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- 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 --- 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: Zebediah Figura zfigura@codeweavers.com --- include/vkd3d_d3d9types.h | 41 +++++++++ libs/vkd3d-shader/hlsl_codegen.c | 137 +++++++++++++++++++++++++++---- 2 files changed, 164 insertions(+), 14 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_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 0fd1f6bd..21ebcfc2 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -804,7 +804,19 @@ static void allocate_temp_registers_recurse(struct list *instrs, struct liveness } }
-static void allocate_const_registers_recurse(struct list *instrs, struct liveness *liveness) +struct vec4 +{ + float f[4]; +}; + +struct constant_defs +{ + struct vec4 *values; + size_t count, size; +}; + +static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, struct list *instrs, struct liveness *liveness, + struct constant_defs *defs) { struct hlsl_ir_node *instr;
@@ -815,28 +827,83 @@ 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, 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 = constant->reg.id + reg_size; + + assert(type->type <= HLSL_CLASS_LAST_NUMERIC); + + if (!(writemask = constant->reg.writemask)) + writemask = (1 << type->dimx) - 1; + + for (y = 0; y < type->dimy; ++y) + { + for (x = 0, i = 0; x < 4; ++x) + { + float f; + + if (!(writemask & (1 << 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, defs); + allocate_const_registers_recurse(ctx, &iff->else_instrs, liveness, defs); 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, defs); break; }
@@ -846,11 +913,14 @@ static void allocate_const_registers_recurse(struct list *instrs, struct livenes } }
-static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) +static struct constant_defs allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) { + struct constant_defs defs = {0}; struct liveness liveness = {0}; struct hlsl_ir_var *var;
+ allocate_const_registers_recurse(ctx, entry_func->body, &liveness, &defs); + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { if (var->is_uniform && var->last_read) @@ -866,7 +936,7 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi } }
- allocate_const_registers_recurse(entry_func->body, &liveness); + return defs; }
/* Simple greedy temporary register allocation pass that just assigns a unique @@ -1186,8 +1256,44 @@ 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, struct constant_defs *defs) +{ + unsigned int i, x; + + for (i = 0; i < 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) + { + union + { + float f; + uint32_t u; + } u; + u.f = defs->values[i].f[x]; + put_dword(buffer, u.u); + } + } +} + static int write_sm1_shader(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, - struct vkd3d_shader_code *out) + struct constant_defs *constant_defs, struct vkd3d_shader_code *out) { struct bytecode_buffer buffer = {0}; int ret; @@ -1196,6 +1302,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, constant_defs); + put_dword(&buffer, D3DSIO_END);
if (!(ret = buffer.status)) @@ -1208,6 +1316,7 @@ static int write_sm1_shader(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *
int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out) { + struct constant_defs constant_defs; struct hlsl_ir_var *var;
list_move_head(entry_func->body, &ctx->static_initializers); @@ -1249,13 +1358,13 @@ 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); + constant_defs = allocate_const_registers(ctx, entry_func);
if (ctx->failed) return VKD3D_ERROR_INVALID_SHADER;
if (ctx->profile->major_version < 4) - return write_sm1_shader(ctx, entry_func, out); + return write_sm1_shader(ctx, entry_func, &constant_defs, out); else return VKD3D_ERROR_NOT_IMPLEMENTED; }
On Wed, 21 Apr 2021 at 06:30, Zebediah Figura zfigura@codeweavers.com wrote:
+#define D3DSP_REGTYPE_SHIFT 28 +#define D3DSP_REGTYPE_SHIFT2 8 +#define D3DSP_REGTYPE_MASK (0x7 << D3DSP_REGTYPE_SHIFT)
It ends up working out here, but note that shifting signed integers produces implementation defined or undefined results in various cases. (We have -Wshift-overflow for that in Wine; I think for vkd3d it's enabled implicitly by -std=c99) It's generally best to make mask constants explicitly unsigned for that reason. On the other hand, these being signed probably matches the PSDK, so perhaps we don't care.
On Wed, Apr 21, 2021 at 6:30 AM Zebediah Figura zfigura@codeweavers.com wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
include/vkd3d_d3d9types.h | 41 +++++++++ libs/vkd3d-shader/hlsl_codegen.c | 137 +++++++++++++++++++++++++++---- 2 files changed, 164 insertions(+), 14 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 0fd1f6bd..21ebcfc2 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -804,7 +804,19 @@ static void allocate_temp_registers_recurse(struct list *instrs, struct liveness } }
-static void allocate_const_registers_recurse(struct list *instrs, struct liveness *liveness) +struct vec4 +{
- float f[4];
+};
+struct constant_defs +{
- struct vec4 *values;
- size_t count, size;
+};
+static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, struct list *instrs, struct liveness *liveness,
struct constant_defs *defs)
{ struct hlsl_ir_node *instr;
@@ -815,28 +827,83 @@ 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, 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 = constant->reg.id + reg_size;
Maybe it's overkill, but I'd prefer if this was a max(defs->count, ...) so that it keeps working if allocate_range() / allocate_register() become smarter at some point in the future.
assert(type->type <= HLSL_CLASS_LAST_NUMERIC);
if (!(writemask = constant->reg.writemask))
writemask = (1 << type->dimx) - 1;
Usual nitpick, here and elsewhere: 1u as the shift operand.
@@ -1208,6 +1316,7 @@ static int write_sm1_shader(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *
int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out) {
struct constant_defs constant_defs; struct hlsl_ir_var *var;
list_move_head(entry_func->body, &ctx->static_initializers);
@@ -1249,13 +1358,13 @@ 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);
constant_defs = allocate_const_registers(ctx, entry_func);
if (ctx->failed) return VKD3D_ERROR_INVALID_SHADER;
if (ctx->profile->major_version < 4)
return write_sm1_shader(ctx, entry_func, out);
else return VKD3D_ERROR_NOT_IMPLEMENTED;return write_sm1_shader(ctx, entry_func, &constant_defs, out);
}
I guess it's a matter of taste but any particular reason why constant_defs isn't part of the context?
On 4/26/21 7:48 AM, Matteo Bruni wrote:
On Wed, Apr 21, 2021 at 6:30 AM Zebediah Figura zfigura@codeweavers.com wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
include/vkd3d_d3d9types.h | 41 +++++++++ libs/vkd3d-shader/hlsl_codegen.c | 137 +++++++++++++++++++++++++++---- 2 files changed, 164 insertions(+), 14 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 0fd1f6bd..21ebcfc2 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -804,7 +804,19 @@ static void allocate_temp_registers_recurse(struct list *instrs, struct liveness } }
-static void allocate_const_registers_recurse(struct list *instrs, struct liveness *liveness) +struct vec4 +{
- float f[4];
+};
+struct constant_defs +{
- struct vec4 *values;
- size_t count, size;
+};
+static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, struct list *instrs, struct liveness *liveness,
{ struct hlsl_ir_node *instr;struct constant_defs *defs)
@@ -815,28 +827,83 @@ 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, 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 = constant->reg.id + reg_size;
Maybe it's overkill, but I'd prefer if this was a max(defs->count, ...) so that it keeps working if allocate_range() / allocate_register() become smarter at some point in the future.
assert(type->type <= HLSL_CLASS_LAST_NUMERIC);
if (!(writemask = constant->reg.writemask))
writemask = (1 << type->dimx) - 1;
Usual nitpick, here and elsewhere: 1u as the shift operand.
@@ -1208,6 +1316,7 @@ static int write_sm1_shader(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *
int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out) {
struct constant_defs constant_defs; struct hlsl_ir_var *var;
list_move_head(entry_func->body, &ctx->static_initializers);
@@ -1249,13 +1358,13 @@ 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);
constant_defs = allocate_const_registers(ctx, entry_func); if (ctx->failed) return VKD3D_ERROR_INVALID_SHADER; if (ctx->profile->major_version < 4)
return write_sm1_shader(ctx, entry_func, out);
}return write_sm1_shader(ctx, entry_func, &constant_defs, out); else return VKD3D_ERROR_NOT_IMPLEMENTED;
I guess it's a matter of taste but any particular reason why constant_defs isn't part of the context?
Probably just "it doesn't need to be", but I don't object to putting it there.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 50b40d65..b48bd250 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -576,6 +576,7 @@ struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, struct hl vkd3d_free(decl); return NULL; } + return_var->is_output_varying = 1; list_add_tail(&ctx->globals->vars, &return_var->scope_entry); decl->return_var = return_var; }
On Wed, Apr 21, 2021 at 6:30 AM Zebediah Figura zfigura@codeweavers.com wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 50b40d65..b48bd250 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -576,6 +576,7 @@ struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, struct hl vkd3d_free(decl); return NULL; }
}return_var->is_output_varying = 1; list_add_tail(&ctx->globals->vars, &return_var->scope_entry); decl->return_var = return_var;
This doesn't seem right. I don't think that this should apply to non-main functions at least. I'm not sure that it is so clear cut for the entry point function either (unless there are already tests that I missed, in which case, nevermind).
On 4/26/21 7:49 AM, Matteo Bruni wrote:
On Wed, Apr 21, 2021 at 6:30 AM Zebediah Figura zfigura@codeweavers.com wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 50b40d65..b48bd250 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -576,6 +576,7 @@ struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, struct hl vkd3d_free(decl); return NULL; }
return_var->is_output_varying = 1; list_add_tail(&ctx->globals->vars, &return_var->scope_entry); decl->return_var = return_var; }
This doesn't seem right. I don't think that this should apply to non-main functions at least. I'm not sure that it is so clear cut for the entry point function either (unless there are already tests that I missed, in which case, nevermind).
See line 98 of hlsl-invalid.shader_test.
We currently mark all function arguments as varyings, which I would agree isn't really correct, though it doesn't cause problems, since we only care about those flags for the entry point.
I guess we could defer setting those flags, one way or another.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 28 +++++++++-------- libs/vkd3d-shader/hlsl.h | 15 ++++++--- libs/vkd3d-shader/hlsl.y | 34 +++++++++++++-------- libs/vkd3d-shader/hlsl_codegen.c | 52 +++++++++++++++++++++----------- 4 files changed, 83 insertions(+), 46 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index b48bd250..19b676bd 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); @@ -388,7 +391,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 struct hlsl_semantic *semantic, const struct hlsl_reg_reservation *reg_reservation) { struct hlsl_ir_var *var;
@@ -398,7 +401,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->reg_reservation = reg_reservation; return var; } @@ -555,7 +559,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;
@@ -876,8 +880,8 @@ static void dump_ir_var(struct vkd3d_string_buffer *buffer, const struct hlsl_ir if (var->is_uniform) vkd3d_string_buffer_printf(buffer, "uniform "); 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) @@ -1179,7 +1183,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); } } @@ -1662,14 +1666,14 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
LIST_FOR_EACH_ENTRY(var, entry_func->parameters, struct hlsl_ir_var, param_entry) { - if (var->data_type->type != HLSL_CLASS_STRUCT && !var->semantic + if (var->data_type->type != HLSL_CLASS_STRUCT && !var->semantic.name && (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) + && entry_func->return_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_point);
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 0c755f46..b77ee078 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; const struct hlsl_reg_reservation *reg_reservation; struct list scope_entry, param_entry, extern_entry;
@@ -557,7 +563,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, @@ -579,7 +586,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, const struct hlsl_reg_reservation *reg_reservation) DECLSPEC_HIDDEN; + const struct hlsl_semantic *semantic, 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..893bad9a 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->reg_reservation))) + if (!(var = hlsl_new_var(param->name, param->type, loc, ¶m->semantic, param->reg_reservation))) return false; var->is_param = 1;
@@ -1384,7 +1384,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); } @@ -1424,7 +1424,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, v->reg_reservation))) { free_parse_variable_def(v); continue; @@ -1459,7 +1459,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."); } @@ -1590,6 +1590,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 @@ -1755,13 +1756,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 @@ -1978,7 +1980,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."); @@ -1989,7 +1991,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; @@ -2020,7 +2022,7 @@ var_identifier: colon_attribute: %empty { - $$.semantic = NULL; + $$.semantic.name = NULL; $$.reg_reservation = NULL; } | semantic @@ -2030,14 +2032,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 21ebcfc2..b1faa8a0 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -71,9 +71,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; @@ -84,13 +85,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), 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, 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; @@ -128,8 +137,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); @@ -143,16 +152,17 @@ 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);
var->is_input_varying = 0; }
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; @@ -163,9 +173,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), 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, NULL))) { + vkd3d_free((void *)new_semantic.name); vkd3d_string_buffer_release(&ctx->string_buffers, name); ctx->failed = true; return; @@ -207,8 +225,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); @@ -222,8 +240,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);
var->is_output_varying = 0; } @@ -1186,7 +1204,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;
@@ -1224,7 +1242,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)); @@ -1238,7 +1256,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);
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- 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 b1faa8a0..ab291545 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -967,6 +967,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_varying_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_varying_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_varying && var->last_read) + allocate_varying_register(ctx, var, &input_counter, false); + if (var->is_output_varying && var->first_write) + allocate_varying_register(ctx, var, &output_counter, true); + } +} + struct bytecode_buffer { uint32_t *data; @@ -1377,6 +1475,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) constant_defs = allocate_const_registers(ctx, entry_func); + allocate_varying_registers(ctx);
if (ctx->failed) return VKD3D_ERROR_INVALID_SHADER;
On Wed, Apr 21, 2021 at 6:30 AM Zebediah Figura zfigura@codeweavers.com wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
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 b1faa8a0..ab291545 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -967,6 +967,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_varying_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_varying_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_varying && var->last_read)
allocate_varying_register(ctx, var, &input_counter, false);
if (var->is_output_varying && var->first_write)
allocate_varying_register(ctx, var, &output_counter, true);
- }
+}
struct bytecode_buffer { uint32_t *data; @@ -1377,6 +1475,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) constant_defs = allocate_const_registers(ctx, entry_func);
allocate_varying_registers(ctx);
if (ctx->failed) return VKD3D_ERROR_INVALID_SHADER;
Nothing new as of this patch but I just realized it now: the naming here isn't entirely correct. AFAIK varying is an old name that was used for the variables that are traditionally output by the vertex shader and end into the fixed function rasterizer, and the interpolated variables that constitute the output of the rasterizer and the input of the pixel shader. So a couple points: - calling "varying" a VS input or a PS output isn't entirely proper - things become even more muddied with the additional geometry shader stages in SM4+; technically only the final geometry stage would produce a varying So calling all of the shader inputs and outputs "varyings" is maybe not ideal. Not that I necessarily have a great replacement. I guess some of the usual modern terms for this would be input / output, interface.
On 4/26/21 7:50 AM, Matteo Bruni wrote:
On Wed, Apr 21, 2021 at 6:30 AM Zebediah Figura zfigura@codeweavers.com wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
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 b1faa8a0..ab291545 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -967,6 +967,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_varying_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_varying_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_varying && var->last_read)
allocate_varying_register(ctx, var, &input_counter, false);
if (var->is_output_varying && var->first_write)
allocate_varying_register(ctx, var, &output_counter, true);
- }
+}
- struct bytecode_buffer { uint32_t *data;
@@ -1377,6 +1475,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) constant_defs = allocate_const_registers(ctx, entry_func);
allocate_varying_registers(ctx);
if (ctx->failed) return VKD3D_ERROR_INVALID_SHADER;
Nothing new as of this patch but I just realized it now: the naming here isn't entirely correct. AFAIK varying is an old name that was used for the variables that are traditionally output by the vertex shader and end into the fixed function rasterizer, and the interpolated variables that constitute the output of the rasterizer and the input of the pixel shader. So a couple points:
- calling "varying" a VS input or a PS output isn't entirely proper
- things become even more muddied with the additional geometry shader
stages in SM4+; technically only the final geometry stage would produce a varying So calling all of the shader inputs and outputs "varyings" is maybe not ideal. Not that I necessarily have a great replacement. I guess some of the usual modern terms for this would be input / output, interface.
Doesn't "interface" also encompass uniforms?
"semantic" is another potential option...
On Wed, Apr 21, 2021 at 6:30 AM Zebediah Figura zfigura@codeweavers.com wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
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;
};
Splitting hairs, but I didn't mind the blank line before reg_offset (the idea being that it's a codegen / backend field vs the above which is pretty much parse / abstract level stuff).
On 4/26/21 7:48 AM, Matteo Bruni wrote:
On Wed, Apr 21, 2021 at 6:30 AM Zebediah Figura zfigura@codeweavers.com wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
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; };
Splitting hairs, but I didn't mind the blank line before reg_offset (the idea being that it's a codegen / backend field vs the above which is pretty much parse / abstract level stuff).
That also may have been my reasoning...