mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-09-13 09:16:14 -07:00
vkd3d-shader/hlsl: Save hlsl_ir_constants in the vsir_program for SM1.
This commit is contained in:
parent
a61846c28a
commit
23e3ec84f7
Notes:
Henri Verbeet
2024-09-04 18:48:04 +02:00
Approved-by: Elizabeth Figura (@zfigura) Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/941
@ -1468,6 +1468,7 @@ bool hlsl_sm1_usage_from_semantic(const char *semantic_name,
|
|||||||
|
|
||||||
struct d3dbc_compiler
|
struct d3dbc_compiler
|
||||||
{
|
{
|
||||||
|
const struct vkd3d_sm1_opcode_info *opcode_table;
|
||||||
struct vsir_program *program;
|
struct vsir_program *program;
|
||||||
struct vkd3d_bytecode_buffer buffer;
|
struct vkd3d_bytecode_buffer buffer;
|
||||||
struct vkd3d_shader_message_context *message_context;
|
struct vkd3d_shader_message_context *message_context;
|
||||||
@ -2170,6 +2171,75 @@ static void d3dbc_write_cast(struct d3dbc_compiler *d3dbc, const struct hlsl_ir_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info_from_vsir(
|
||||||
|
struct d3dbc_compiler *d3dbc, enum vkd3d_shader_opcode vkd3d_opcode)
|
||||||
|
{
|
||||||
|
const struct vkd3d_shader_version *version = &d3dbc->program->shader_version;
|
||||||
|
const struct vkd3d_sm1_opcode_info *info;
|
||||||
|
unsigned int i = 0;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
info = &d3dbc->opcode_table[i++];
|
||||||
|
if (info->vkd3d_opcode == VKD3DSIH_INVALID)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (vkd3d_opcode == info->vkd3d_opcode
|
||||||
|
&& vkd3d_shader_ver_ge(version, info->min_version.major, info->min_version.minor)
|
||||||
|
&& (vkd3d_shader_ver_le(version, info->max_version.major, info->max_version.minor)
|
||||||
|
|| !info->max_version.major))
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t swizzle_from_vsir(uint32_t swizzle)
|
||||||
|
{
|
||||||
|
uint32_t x = vsir_swizzle_get_component(swizzle, 0);
|
||||||
|
uint32_t y = vsir_swizzle_get_component(swizzle, 1);
|
||||||
|
uint32_t z = vsir_swizzle_get_component(swizzle, 2);
|
||||||
|
uint32_t w = vsir_swizzle_get_component(swizzle, 3);
|
||||||
|
|
||||||
|
if (x & ~0x3u || y & ~0x3u || z & ~0x3u || w & ~0x3u)
|
||||||
|
ERR("Unexpected vsir swizzle: 0x%08x.\n", swizzle);
|
||||||
|
|
||||||
|
return ((x & 0x3u) << VKD3D_SM1_SWIZZLE_COMPONENT_SHIFT(0))
|
||||||
|
| ((y & 0x3) << VKD3D_SM1_SWIZZLE_COMPONENT_SHIFT(1))
|
||||||
|
| ((z & 0x3) << VKD3D_SM1_SWIZZLE_COMPONENT_SHIFT(2))
|
||||||
|
| ((w & 0x3) << VKD3D_SM1_SWIZZLE_COMPONENT_SHIFT(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sm1_src_reg_from_vsir(struct d3dbc_compiler *d3dbc, const struct vkd3d_shader_src_param *param,
|
||||||
|
struct sm1_src_register *src, const struct vkd3d_shader_location *loc)
|
||||||
|
{
|
||||||
|
src->mod = (uint32_t)param->modifiers << VKD3D_SM1_SRC_MODIFIER_SHIFT;
|
||||||
|
src->reg = param->reg.idx[0].offset;
|
||||||
|
src->type = param->reg.type;
|
||||||
|
src->swizzle = swizzle_from_vsir(param->swizzle);
|
||||||
|
|
||||||
|
if (param->reg.idx[0].rel_addr)
|
||||||
|
{
|
||||||
|
vkd3d_shader_error(d3dbc->message_context, loc, VKD3D_SHADER_ERROR_D3DBC_NOT_IMPLEMENTED,
|
||||||
|
"Unhandled relative addressing on source register.");
|
||||||
|
d3dbc->failed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sm1_dst_reg_from_vsir(struct d3dbc_compiler *d3dbc, const struct vkd3d_shader_dst_param *param,
|
||||||
|
struct sm1_dst_register *dst, const struct vkd3d_shader_location *loc)
|
||||||
|
{
|
||||||
|
dst->mod = (uint32_t)param->modifiers << VKD3D_SM1_DST_MODIFIER_SHIFT;
|
||||||
|
dst->reg = param->reg.idx[0].offset;
|
||||||
|
dst->type = param->reg.type;
|
||||||
|
dst->writemask = param->write_mask;
|
||||||
|
|
||||||
|
if (param->reg.idx[0].rel_addr)
|
||||||
|
{
|
||||||
|
vkd3d_shader_error(d3dbc->message_context, loc, VKD3D_SHADER_ERROR_D3DBC_NOT_IMPLEMENTED,
|
||||||
|
"Unhandled relative addressing on destination register.");
|
||||||
|
d3dbc->failed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void d3dbc_write_vsir_def(struct d3dbc_compiler *d3dbc, const struct vkd3d_shader_instruction *ins)
|
static void d3dbc_write_vsir_def(struct d3dbc_compiler *d3dbc, const struct vkd3d_shader_instruction *ins)
|
||||||
{
|
{
|
||||||
const struct vkd3d_shader_version *version = &d3dbc->program->shader_version;
|
const struct vkd3d_shader_version *version = &d3dbc->program->shader_version;
|
||||||
@ -2258,6 +2328,43 @@ static void d3dbc_write_vsir_dcl(struct d3dbc_compiler *d3dbc, const struct vkd3
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void d3dbc_write_vsir_simple_instruction(struct d3dbc_compiler *d3dbc,
|
||||||
|
const struct vkd3d_shader_instruction *ins)
|
||||||
|
{
|
||||||
|
const struct vkd3d_sm1_opcode_info *info;
|
||||||
|
struct sm1_instruction instr = {0};
|
||||||
|
|
||||||
|
info = shader_sm1_get_opcode_info_from_vsir(d3dbc, ins->opcode);
|
||||||
|
|
||||||
|
if (ins->dst_count != info->dst_count)
|
||||||
|
{
|
||||||
|
vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_COUNT,
|
||||||
|
"Invalid destination count %u for vsir instruction %#x (expected %u).",
|
||||||
|
ins->dst_count, ins->opcode, info->dst_count);
|
||||||
|
d3dbc->failed = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ins->src_count != info->src_count)
|
||||||
|
{
|
||||||
|
vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_COUNT,
|
||||||
|
"Invalid source count %u for vsir instruction %#x (expected %u).",
|
||||||
|
ins->src_count, ins->opcode, info->src_count);
|
||||||
|
d3dbc->failed = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
instr.opcode = (D3DSHADER_INSTRUCTION_OPCODE_TYPE)info->sm1_opcode;
|
||||||
|
instr.has_dst = info->dst_count;
|
||||||
|
instr.src_count = info->src_count;
|
||||||
|
|
||||||
|
if (instr.has_dst)
|
||||||
|
sm1_dst_reg_from_vsir(d3dbc, &ins->dst[0], &instr.dst, &ins->location);
|
||||||
|
for (unsigned int i = 0; i < instr.src_count; ++i)
|
||||||
|
sm1_src_reg_from_vsir(d3dbc, &ins->src[i], &instr.srcs[i], &ins->location);
|
||||||
|
|
||||||
|
d3dbc_write_instruction(d3dbc, &instr);
|
||||||
|
}
|
||||||
|
|
||||||
static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const struct vkd3d_shader_instruction *ins)
|
static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const struct vkd3d_shader_instruction *ins)
|
||||||
{
|
{
|
||||||
switch (ins->opcode)
|
switch (ins->opcode)
|
||||||
@ -2270,6 +2377,10 @@ static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const str
|
|||||||
d3dbc_write_vsir_dcl(d3dbc, ins);
|
d3dbc_write_vsir_dcl(d3dbc, ins);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VKD3DSIH_MOV:
|
||||||
|
d3dbc_write_vsir_simple_instruction(d3dbc, ins);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_INVALID_OPCODE,
|
vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_INVALID_OPCODE,
|
||||||
"vsir instruction with opcode %#x.", ins->opcode);
|
"vsir instruction with opcode %#x.", ins->opcode);
|
||||||
@ -2343,30 +2454,6 @@ static void d3dbc_write_semantic_dcls(struct d3dbc_compiler *d3dbc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void d3dbc_write_constant(struct d3dbc_compiler *d3dbc, const struct hlsl_ir_node *instr)
|
|
||||||
{
|
|
||||||
const struct hlsl_ir_constant *constant = hlsl_ir_constant(instr);
|
|
||||||
struct sm1_instruction sm1_instr =
|
|
||||||
{
|
|
||||||
.opcode = D3DSIO_MOV,
|
|
||||||
|
|
||||||
.dst.type = VKD3DSPR_TEMP,
|
|
||||||
.dst.reg = instr->reg.id,
|
|
||||||
.dst.writemask = instr->reg.writemask,
|
|
||||||
.has_dst = 1,
|
|
||||||
|
|
||||||
.srcs[0].type = VKD3DSPR_CONST,
|
|
||||||
.srcs[0].reg = constant->reg.id,
|
|
||||||
.srcs[0].swizzle = hlsl_swizzle_from_writemask(constant->reg.writemask),
|
|
||||||
.src_count = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
VKD3D_ASSERT(instr->reg.allocated);
|
|
||||||
VKD3D_ASSERT(constant->reg.allocated);
|
|
||||||
sm1_map_src_swizzle(&sm1_instr.srcs[0], sm1_instr.dst.writemask);
|
|
||||||
d3dbc_write_instruction(d3dbc, &sm1_instr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void d3dbc_write_per_component_unary_op(struct d3dbc_compiler *d3dbc,
|
static void d3dbc_write_per_component_unary_op(struct d3dbc_compiler *d3dbc,
|
||||||
const struct hlsl_ir_node *instr, D3DSHADER_INSTRUCTION_OPCODE_TYPE opcode)
|
const struct hlsl_ir_node *instr, D3DSHADER_INSTRUCTION_OPCODE_TYPE opcode)
|
||||||
{
|
{
|
||||||
@ -2847,10 +2934,6 @@ static void d3dbc_write_block(struct d3dbc_compiler *d3dbc, const struct hlsl_bl
|
|||||||
case HLSL_IR_CALL:
|
case HLSL_IR_CALL:
|
||||||
vkd3d_unreachable();
|
vkd3d_unreachable();
|
||||||
|
|
||||||
case HLSL_IR_CONSTANT:
|
|
||||||
d3dbc_write_constant(d3dbc, instr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HLSL_IR_EXPR:
|
case HLSL_IR_EXPR:
|
||||||
d3dbc_write_expr(d3dbc, instr);
|
d3dbc_write_expr(d3dbc, instr);
|
||||||
break;
|
break;
|
||||||
@ -2911,6 +2994,21 @@ int d3dbc_compile(struct vsir_program *program, uint64_t config_flags,
|
|||||||
d3dbc.ctx = ctx;
|
d3dbc.ctx = ctx;
|
||||||
d3dbc.program = program;
|
d3dbc.program = program;
|
||||||
d3dbc.message_context = message_context;
|
d3dbc.message_context = message_context;
|
||||||
|
switch (version->type)
|
||||||
|
{
|
||||||
|
case VKD3D_SHADER_TYPE_VERTEX:
|
||||||
|
d3dbc.opcode_table = vs_opcode_table;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VKD3D_SHADER_TYPE_PIXEL:
|
||||||
|
d3dbc.opcode_table = ps_opcode_table;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_D3DBC_INVALID_PROFILE,
|
||||||
|
"Invalid shader type %u.", version->type);
|
||||||
|
return VKD3D_ERROR_INVALID_SHADER;
|
||||||
|
}
|
||||||
|
|
||||||
put_u32(buffer, sm1_version(version->type, version->major, version->minor));
|
put_u32(buffer, sm1_version(version->type, version->major, version->minor));
|
||||||
|
|
||||||
|
@ -70,6 +70,14 @@ static inline unsigned int hlsl_swizzle_get_component(uint32_t swizzle, unsigned
|
|||||||
return (swizzle >> HLSL_SWIZZLE_SHIFT(idx)) & HLSL_SWIZZLE_MASK;
|
return (swizzle >> HLSL_SWIZZLE_SHIFT(idx)) & HLSL_SWIZZLE_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint32_t vsir_swizzle_from_hlsl(uint32_t swizzle)
|
||||||
|
{
|
||||||
|
return vkd3d_shader_create_swizzle(hlsl_swizzle_get_component(swizzle, 0),
|
||||||
|
hlsl_swizzle_get_component(swizzle, 1),
|
||||||
|
hlsl_swizzle_get_component(swizzle, 2),
|
||||||
|
hlsl_swizzle_get_component(swizzle, 3));
|
||||||
|
}
|
||||||
|
|
||||||
enum hlsl_type_class
|
enum hlsl_type_class
|
||||||
{
|
{
|
||||||
HLSL_CLASS_SCALAR,
|
HLSL_CLASS_SCALAR,
|
||||||
|
@ -6014,6 +6014,16 @@ static void sm1_generate_vsir_signature(struct hlsl_ctx *ctx, struct vsir_progra
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t sm1_generate_vsir_get_src_swizzle(uint32_t src_writemask, uint32_t dst_writemask)
|
||||||
|
{
|
||||||
|
uint32_t swizzle;
|
||||||
|
|
||||||
|
swizzle = hlsl_swizzle_from_writemask(src_writemask);
|
||||||
|
swizzle = hlsl_map_swizzle(swizzle, dst_writemask);
|
||||||
|
swizzle = vsir_swizzle_from_hlsl(swizzle);
|
||||||
|
return swizzle;
|
||||||
|
}
|
||||||
|
|
||||||
static void sm1_generate_vsir_constant_defs(struct hlsl_ctx *ctx, struct vsir_program *program,
|
static void sm1_generate_vsir_constant_defs(struct hlsl_ctx *ctx, struct vsir_program *program,
|
||||||
struct hlsl_block *block)
|
struct hlsl_block *block)
|
||||||
{
|
{
|
||||||
@ -6157,6 +6167,70 @@ static void sm1_generate_vsir_sampler_dcls(struct hlsl_ctx *ctx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sm1_generate_vsir_instr_constant(struct hlsl_ctx *ctx,
|
||||||
|
struct vsir_program *program, struct hlsl_ir_constant *constant)
|
||||||
|
{
|
||||||
|
struct vkd3d_shader_instruction_array *instructions = &program->instructions;
|
||||||
|
struct hlsl_ir_node *instr = &constant->node;
|
||||||
|
struct vkd3d_shader_dst_param *dst_param;
|
||||||
|
struct vkd3d_shader_src_param *src_param;
|
||||||
|
struct vkd3d_shader_instruction *ins;
|
||||||
|
struct hlsl_ir_node *vsir_instr;
|
||||||
|
|
||||||
|
VKD3D_ASSERT(instr->reg.allocated);
|
||||||
|
VKD3D_ASSERT(constant->reg.allocated);
|
||||||
|
|
||||||
|
if (!shader_instruction_array_reserve(instructions, instructions->count + 1))
|
||||||
|
{
|
||||||
|
ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ins = &instructions->elements[instructions->count];
|
||||||
|
if (!vsir_instruction_init_with_params(program, ins, &instr->loc, VKD3DSIH_MOV, 1, 1))
|
||||||
|
{
|
||||||
|
ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
++instructions->count;
|
||||||
|
|
||||||
|
src_param = &ins->src[0];
|
||||||
|
vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VKD3D_DATA_FLOAT, 1);
|
||||||
|
src_param->reg.idx[0].offset = constant->reg.id;
|
||||||
|
src_param->swizzle = sm1_generate_vsir_get_src_swizzle(constant->reg.writemask, instr->reg.writemask);
|
||||||
|
|
||||||
|
dst_param = &ins->dst[0];
|
||||||
|
vsir_register_init(&dst_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1);
|
||||||
|
dst_param->reg.idx[0].offset = instr->reg.id;
|
||||||
|
dst_param->write_mask = instr->reg.writemask;
|
||||||
|
|
||||||
|
if (!(vsir_instr = hlsl_new_vsir_instruction_ref(ctx, instructions->count - 1,
|
||||||
|
instr->data_type, &instr->reg, &instr->loc)))
|
||||||
|
{
|
||||||
|
ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
list_add_before(&instr->entry, &vsir_instr->entry);
|
||||||
|
hlsl_replace_node(instr, vsir_instr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool sm1_generate_vsir_instr(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
|
||||||
|
{
|
||||||
|
struct vsir_program *program = context;
|
||||||
|
|
||||||
|
switch (instr->type)
|
||||||
|
{
|
||||||
|
case HLSL_IR_CONSTANT:
|
||||||
|
sm1_generate_vsir_instr_constant(ctx, program, hlsl_ir_constant(instr));
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* OBJECTIVE: Translate all the information from ctx and entry_func to the
|
/* OBJECTIVE: Translate all the information from ctx and entry_func to the
|
||||||
* vsir_program and ctab blob, so they can be used as input to d3dbc_compile()
|
* vsir_program and ctab blob, so they can be used as input to d3dbc_compile()
|
||||||
* without relying on ctx and entry_func. */
|
* without relying on ctx and entry_func. */
|
||||||
@ -6192,6 +6266,8 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl
|
|||||||
sm1_generate_vsir_constant_defs(ctx, program, &block);
|
sm1_generate_vsir_constant_defs(ctx, program, &block);
|
||||||
sm1_generate_vsir_sampler_dcls(ctx, program, &block);
|
sm1_generate_vsir_sampler_dcls(ctx, program, &block);
|
||||||
list_move_head(&entry_func->body.instrs, &block.instrs);
|
list_move_head(&entry_func->body.instrs, &block.instrs);
|
||||||
|
|
||||||
|
hlsl_transform_ir(ctx, sm1_generate_vsir_instr, &entry_func->body, program);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct hlsl_ir_jump *loop_unrolling_find_jump(struct hlsl_block *block, struct hlsl_ir_node *stop_point,
|
static struct hlsl_ir_jump *loop_unrolling_find_jump(struct hlsl_block *block, struct hlsl_ir_node *stop_point,
|
||||||
|
@ -170,6 +170,9 @@ enum vkd3d_shader_error
|
|||||||
VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_INDEX = 7005,
|
VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_INDEX = 7005,
|
||||||
VKD3D_SHADER_ERROR_D3DBC_UNDECLARED_SEMANTIC = 7006,
|
VKD3D_SHADER_ERROR_D3DBC_UNDECLARED_SEMANTIC = 7006,
|
||||||
VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_TYPE = 7007,
|
VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_TYPE = 7007,
|
||||||
|
VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_COUNT = 7008,
|
||||||
|
VKD3D_SHADER_ERROR_D3DBC_NOT_IMPLEMENTED = 7009,
|
||||||
|
VKD3D_SHADER_ERROR_D3DBC_INVALID_PROFILE = 7010,
|
||||||
|
|
||||||
VKD3D_SHADER_WARNING_D3DBC_IGNORED_INSTRUCTION_FLAGS= 7300,
|
VKD3D_SHADER_WARNING_D3DBC_IGNORED_INSTRUCTION_FLAGS= 7300,
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user