mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-09-12 18:50:22 -07:00
vkd3d-shader: Write SM1 constant definitions.
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com> Signed-off-by: Matteo Bruni <mbruni@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
committed by
Alexandre Julliard
parent
d0ab65c7a1
commit
16e549e579
@@ -27,6 +27,19 @@
|
|||||||
((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 ))
|
((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 ))
|
||||||
#endif
|
#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 D3DPS_VERSION(major, minor) (0xffff0000 | ((major) << 8) | (minor))
|
||||||
#define D3DVS_VERSION(major, minor) (0xfffe0000 | ((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,
|
D3DSIO_FORCE_DWORD = 0x7fffffff,
|
||||||
} D3DSHADER_INSTRUCTION_OPCODE_TYPE;
|
} 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 /* _d3d9TYPES_H_ */
|
||||||
#endif /* __VKD3D_D3D9TYPES_H */
|
#endif /* __VKD3D_D3D9TYPES_H */
|
||||||
|
@@ -407,6 +407,11 @@ struct hlsl_profile_info
|
|||||||
bool software;
|
bool software;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct hlsl_vec4
|
||||||
|
{
|
||||||
|
float f[4];
|
||||||
|
};
|
||||||
|
|
||||||
struct hlsl_ctx
|
struct hlsl_ctx
|
||||||
{
|
{
|
||||||
const struct hlsl_profile_info *profile;
|
const struct hlsl_profile_info *profile;
|
||||||
@@ -440,6 +445,12 @@ struct hlsl_ctx
|
|||||||
} builtin_types;
|
} builtin_types;
|
||||||
|
|
||||||
struct list static_initializers;
|
struct list static_initializers;
|
||||||
|
|
||||||
|
struct hlsl_constant_defs
|
||||||
|
{
|
||||||
|
struct hlsl_vec4 *values;
|
||||||
|
size_t count, size;
|
||||||
|
} constant_defs;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum hlsl_error_level
|
enum hlsl_error_level
|
||||||
|
@@ -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;
|
struct hlsl_ir_node *instr;
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY(instr, instrs, struct hlsl_ir_node, entry)
|
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:
|
case HLSL_IR_CONSTANT:
|
||||||
{
|
{
|
||||||
struct hlsl_ir_constant *constant = hlsl_ir_constant(instr);
|
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)
|
if (reg_size > 1)
|
||||||
constant->reg = allocate_range(liveness, 1, UINT_MAX, instr->data_type->reg_size);
|
constant->reg = allocate_range(liveness, 1, UINT_MAX, reg_size);
|
||||||
else
|
else
|
||||||
constant->reg = allocate_register(liveness, 1, UINT_MAX, instr->data_type->dimx);
|
constant->reg = allocate_register(liveness, 1, UINT_MAX, type->dimx);
|
||||||
TRACE("Allocated constant @%u to %s.\n", instr->index,
|
TRACE("Allocated constant @%u to %s.\n", instr->index, debug_register('c', constant->reg, type));
|
||||||
debug_register('c', constant->reg, instr->data_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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case HLSL_IR_IF:
|
case HLSL_IR_IF:
|
||||||
{
|
{
|
||||||
struct hlsl_ir_if *iff = hlsl_ir_if(instr);
|
struct hlsl_ir_if *iff = hlsl_ir_if(instr);
|
||||||
allocate_const_registers_recurse(&iff->then_instrs, liveness);
|
allocate_const_registers_recurse(ctx, &iff->then_instrs, liveness);
|
||||||
allocate_const_registers_recurse(&iff->else_instrs, liveness);
|
allocate_const_registers_recurse(ctx, &iff->else_instrs, liveness);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case HLSL_IR_LOOP:
|
case HLSL_IR_LOOP:
|
||||||
{
|
{
|
||||||
struct hlsl_ir_loop *loop = hlsl_ir_loop(instr);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -851,6 +908,8 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi
|
|||||||
struct liveness liveness = {0};
|
struct liveness liveness = {0};
|
||||||
struct hlsl_ir_var *var;
|
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)
|
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
|
||||||
{
|
{
|
||||||
if (var->is_uniform && var->last_read)
|
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));
|
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
|
/* 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;
|
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)
|
static void set_dword(struct bytecode_buffer *buffer, unsigned int index, uint32_t value)
|
||||||
{
|
{
|
||||||
if (buffer->status)
|
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));
|
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,
|
static int write_sm1_shader(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func,
|
||||||
struct vkd3d_shader_code *out)
|
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_uniforms(ctx, &buffer, entry_func);
|
||||||
|
|
||||||
|
write_sm1_constant_defs(ctx, &buffer);
|
||||||
|
|
||||||
put_dword(&buffer, D3DSIO_END);
|
put_dword(&buffer, D3DSIO_END);
|
||||||
|
|
||||||
if (!(ret = buffer.status))
|
if (!(ret = buffer.status))
|
||||||
|
Reference in New Issue
Block a user