mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-01-28 13:05:02 -08:00
vkd3d-shader/hlsl: Migrate SM4 control flow instructions to the vsir program.
Translate the instructions that contain hlsl_blocks. Also move other control flow instructions such as HS_CONTROL_POINT_PHASE and RET to the vsir_program so that we can directly iterate over it now.
This commit is contained in:
parent
81fa4d45b9
commit
d6d6f37578
Notes:
Henri Verbeet
2024-11-27 14:11:33 +01:00
Approved-by: Elizabeth Figura (@zfigura) Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1280
@ -7925,40 +7925,6 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl
|
||||
sm1_generate_vsir_block(ctx, &entry_func->body, program);
|
||||
}
|
||||
|
||||
static void add_last_vsir_instr_to_block(struct hlsl_ctx *ctx, struct vsir_program *program, struct hlsl_block *block)
|
||||
{
|
||||
struct vkd3d_shader_location *loc;
|
||||
struct hlsl_ir_node *vsir_instr;
|
||||
|
||||
loc = &program->instructions.elements[program->instructions.count - 1].location;
|
||||
|
||||
if (!(vsir_instr = hlsl_new_vsir_instruction_ref(ctx, program->instructions.count - 1, NULL, NULL, loc)))
|
||||
{
|
||||
ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
|
||||
return;
|
||||
}
|
||||
hlsl_block_add_instr(block, vsir_instr);
|
||||
}
|
||||
|
||||
static void replace_instr_with_last_vsir_instr(struct hlsl_ctx *ctx,
|
||||
struct vsir_program *program, struct hlsl_ir_node *instr)
|
||||
{
|
||||
struct vkd3d_shader_location *loc;
|
||||
struct hlsl_ir_node *vsir_instr;
|
||||
|
||||
loc = &program->instructions.elements[program->instructions.count - 1].location;
|
||||
|
||||
if (!(vsir_instr = hlsl_new_vsir_instruction_ref(ctx,
|
||||
program->instructions.count - 1, instr->data_type, &instr->reg, loc)))
|
||||
{
|
||||
ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
|
||||
return;
|
||||
}
|
||||
|
||||
list_add_before(&instr->entry, &vsir_instr->entry);
|
||||
hlsl_replace_node(instr, vsir_instr);
|
||||
}
|
||||
|
||||
static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vsir_program *program,
|
||||
const struct hlsl_ir_var *var, bool is_patch_constant_func, struct hlsl_block *block,
|
||||
const struct vkd3d_shader_location *loc)
|
||||
@ -8072,8 +8038,6 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs
|
||||
|
||||
if (var->is_input_semantic && version->type == VKD3D_SHADER_TYPE_PIXEL)
|
||||
ins->flags = sm4_get_interpolation_mode(var->data_type, var->storage_modifiers);
|
||||
|
||||
add_last_vsir_instr_to_block(ctx, program, block);
|
||||
}
|
||||
|
||||
static void sm4_generate_vsir_instr_dcl_temps(struct hlsl_ctx *ctx, struct vsir_program *program,
|
||||
@ -8085,8 +8049,6 @@ static void sm4_generate_vsir_instr_dcl_temps(struct hlsl_ctx *ctx, struct vsir_
|
||||
return;
|
||||
|
||||
ins->declaration.count = temp_count;
|
||||
|
||||
add_last_vsir_instr_to_block(ctx, program, block);
|
||||
}
|
||||
|
||||
static void sm4_generate_vsir_instr_dcl_indexable_temp(struct hlsl_ctx *ctx,
|
||||
@ -8104,8 +8066,6 @@ static void sm4_generate_vsir_instr_dcl_indexable_temp(struct hlsl_ctx *ctx,
|
||||
ins->declaration.indexable_temp.data_type = VKD3D_DATA_FLOAT;
|
||||
ins->declaration.indexable_temp.component_count = comp_count;
|
||||
ins->declaration.indexable_temp.has_function_scope = false;
|
||||
|
||||
add_last_vsir_instr_to_block(ctx, program, block);
|
||||
}
|
||||
|
||||
static bool type_is_float(const struct hlsl_type *type)
|
||||
@ -9311,11 +9271,88 @@ static bool sm4_generate_vsir_instr_jump(struct hlsl_ctx *ctx,
|
||||
}
|
||||
}
|
||||
|
||||
static void sm4_generate_vsir_block(struct hlsl_ctx *ctx, struct hlsl_block *block, struct vsir_program *program);
|
||||
|
||||
static void sm4_generate_vsir_instr_if(struct hlsl_ctx *ctx, struct vsir_program *program, struct hlsl_ir_if *iff)
|
||||
{
|
||||
struct hlsl_ir_node *instr = &iff->node;
|
||||
struct vkd3d_shader_instruction *ins;
|
||||
|
||||
VKD3D_ASSERT(iff->condition.node->data_type->dimx == 1);
|
||||
|
||||
if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_IF, 0, 1)))
|
||||
return;
|
||||
ins->flags = VKD3D_SHADER_CONDITIONAL_OP_NZ;
|
||||
|
||||
vsir_src_from_hlsl_node(&ins->src[0], ctx, iff->condition.node, VKD3DSP_WRITEMASK_ALL);
|
||||
|
||||
sm4_generate_vsir_block(ctx, &iff->then_block, program);
|
||||
|
||||
if (!list_empty(&iff->else_block.instrs))
|
||||
{
|
||||
if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_ELSE, 0, 0)))
|
||||
return;
|
||||
sm4_generate_vsir_block(ctx, &iff->else_block, program);
|
||||
}
|
||||
|
||||
if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_ENDIF, 0, 0)))
|
||||
return;
|
||||
}
|
||||
|
||||
static void sm4_generate_vsir_instr_loop(struct hlsl_ctx *ctx,
|
||||
struct vsir_program *program, struct hlsl_ir_loop *loop)
|
||||
{
|
||||
struct hlsl_ir_node *instr = &loop->node;
|
||||
struct vkd3d_shader_instruction *ins;
|
||||
|
||||
if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_LOOP, 0, 0)))
|
||||
return;
|
||||
|
||||
sm4_generate_vsir_block(ctx, &loop->body, program);
|
||||
|
||||
if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_ENDLOOP, 0, 0)))
|
||||
return;
|
||||
}
|
||||
|
||||
static void sm4_generate_vsir_instr_switch(struct hlsl_ctx *ctx,
|
||||
struct vsir_program *program, struct hlsl_ir_switch *swi)
|
||||
{
|
||||
const struct hlsl_ir_node *selector = swi->selector.node;
|
||||
struct hlsl_ir_node *instr = &swi->node;
|
||||
struct vkd3d_shader_instruction *ins;
|
||||
struct hlsl_ir_switch_case *cas;
|
||||
|
||||
if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_SWITCH, 0, 1)))
|
||||
return;
|
||||
vsir_src_from_hlsl_node(&ins->src[0], ctx, selector, VKD3DSP_WRITEMASK_ALL);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(cas, &swi->cases, struct hlsl_ir_switch_case, entry)
|
||||
{
|
||||
if (cas->is_default)
|
||||
{
|
||||
if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_DEFAULT, 0, 0)))
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct hlsl_constant_value value = {.u[0].u = cas->value};
|
||||
|
||||
if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_CASE, 0, 1)))
|
||||
return;
|
||||
vsir_src_from_hlsl_constant_value(&ins->src[0], ctx, &value, VKD3D_DATA_UINT, 1, VKD3DSP_WRITEMASK_ALL);
|
||||
}
|
||||
|
||||
sm4_generate_vsir_block(ctx, &cas->body, program);
|
||||
}
|
||||
|
||||
if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_ENDSWITCH, 0, 0)))
|
||||
return;
|
||||
}
|
||||
|
||||
static void sm4_generate_vsir_block(struct hlsl_ctx *ctx, struct hlsl_block *block, struct vsir_program *program)
|
||||
{
|
||||
struct vkd3d_string_buffer *dst_type_string;
|
||||
struct hlsl_ir_node *instr, *next;
|
||||
struct hlsl_ir_switch_case *c;
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(instr, next, &block->instrs, struct hlsl_ir_node, entry)
|
||||
{
|
||||
@ -9340,55 +9377,44 @@ static void sm4_generate_vsir_block(struct hlsl_ctx *ctx, struct hlsl_block *blo
|
||||
case HLSL_IR_EXPR:
|
||||
if (!(dst_type_string = hlsl_type_to_string(ctx, instr->data_type)))
|
||||
break;
|
||||
|
||||
if (sm4_generate_vsir_instr_expr(ctx, program, hlsl_ir_expr(instr), dst_type_string->buffer))
|
||||
replace_instr_with_last_vsir_instr(ctx, program, instr);
|
||||
|
||||
sm4_generate_vsir_instr_expr(ctx, program, hlsl_ir_expr(instr), dst_type_string->buffer);
|
||||
hlsl_release_string_buffer(ctx, dst_type_string);
|
||||
break;
|
||||
|
||||
case HLSL_IR_IF:
|
||||
sm4_generate_vsir_block(ctx, &hlsl_ir_if(instr)->then_block, program);
|
||||
sm4_generate_vsir_block(ctx, &hlsl_ir_if(instr)->else_block, program);
|
||||
sm4_generate_vsir_instr_if(ctx, program, hlsl_ir_if(instr));
|
||||
break;
|
||||
|
||||
case HLSL_IR_LOAD:
|
||||
if (sm4_generate_vsir_instr_load(ctx, program, hlsl_ir_load(instr)))
|
||||
replace_instr_with_last_vsir_instr(ctx, program, instr);
|
||||
sm4_generate_vsir_instr_load(ctx, program, hlsl_ir_load(instr));
|
||||
break;
|
||||
|
||||
case HLSL_IR_LOOP:
|
||||
sm4_generate_vsir_block(ctx, &hlsl_ir_loop(instr)->body, program);
|
||||
sm4_generate_vsir_instr_loop(ctx, program, hlsl_ir_loop(instr));
|
||||
break;
|
||||
|
||||
case HLSL_IR_RESOURCE_LOAD:
|
||||
if (sm4_generate_vsir_instr_resource_load(ctx, program, hlsl_ir_resource_load(instr)))
|
||||
replace_instr_with_last_vsir_instr(ctx, program, instr);
|
||||
sm4_generate_vsir_instr_resource_load(ctx, program, hlsl_ir_resource_load(instr));
|
||||
break;
|
||||
|
||||
case HLSL_IR_RESOURCE_STORE:
|
||||
if (sm4_generate_vsir_instr_resource_store(ctx, program, hlsl_ir_resource_store(instr)))
|
||||
replace_instr_with_last_vsir_instr(ctx, program, instr);
|
||||
sm4_generate_vsir_instr_resource_store(ctx, program, hlsl_ir_resource_store(instr));
|
||||
break;
|
||||
|
||||
case HLSL_IR_JUMP:
|
||||
if (sm4_generate_vsir_instr_jump(ctx, program, hlsl_ir_jump(instr)))
|
||||
replace_instr_with_last_vsir_instr(ctx, program, instr);
|
||||
sm4_generate_vsir_instr_jump(ctx, program, hlsl_ir_jump(instr));
|
||||
break;
|
||||
|
||||
case HLSL_IR_STORE:
|
||||
if (sm4_generate_vsir_instr_store(ctx, program, hlsl_ir_store(instr)))
|
||||
replace_instr_with_last_vsir_instr(ctx, program, instr);
|
||||
sm4_generate_vsir_instr_store(ctx, program, hlsl_ir_store(instr));
|
||||
break;
|
||||
|
||||
case HLSL_IR_SWITCH:
|
||||
LIST_FOR_EACH_ENTRY(c, &hlsl_ir_switch(instr)->cases, struct hlsl_ir_switch_case, entry)
|
||||
sm4_generate_vsir_block(ctx, &c->body, program);
|
||||
sm4_generate_vsir_instr_switch(ctx, program, hlsl_ir_switch(instr));
|
||||
break;
|
||||
|
||||
case HLSL_IR_SWIZZLE:
|
||||
generate_vsir_instr_swizzle(ctx, program, hlsl_ir_swizzle(instr));
|
||||
replace_instr_with_last_vsir_instr(ctx, program, instr);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -9449,6 +9475,8 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx,
|
||||
hlsl_block_cleanup(&block);
|
||||
|
||||
sm4_generate_vsir_block(ctx, &func->body, program);
|
||||
|
||||
generate_vsir_add_program_instruction(ctx, program, &func->loc, VKD3DSIH_RET, 0, 0);
|
||||
}
|
||||
|
||||
/* OBJECTIVE: Translate all the information from ctx and entry_func to the
|
||||
@ -9480,9 +9508,16 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl
|
||||
program->thread_group_size.z = ctx->thread_count[2];
|
||||
}
|
||||
|
||||
if (version.type == VKD3D_SHADER_TYPE_HULL)
|
||||
generate_vsir_add_program_instruction(ctx, program,
|
||||
&ctx->patch_constant_func->loc, VKD3DSIH_HS_CONTROL_POINT_PHASE, 0, 0);
|
||||
sm4_generate_vsir_add_function(ctx, func, config_flags, program);
|
||||
if (version.type == VKD3D_SHADER_TYPE_HULL)
|
||||
{
|
||||
generate_vsir_add_program_instruction(ctx, program,
|
||||
&ctx->patch_constant_func->loc, VKD3DSIH_HS_FORK_PHASE, 0, 0);
|
||||
sm4_generate_vsir_add_function(ctx, ctx->patch_constant_func, config_flags, program);
|
||||
}
|
||||
}
|
||||
|
||||
static struct hlsl_ir_jump *loop_unrolling_find_jump(struct hlsl_block *block, struct hlsl_ir_node *stop_point,
|
||||
|
@ -1969,16 +1969,6 @@ static const struct vkd3d_sm4_register_type_info *get_info_from_vkd3d_register_t
|
||||
return lookup->register_type_info_from_vkd3d[vkd3d_type];
|
||||
}
|
||||
|
||||
static enum vkd3d_sm4_swizzle_type vkd3d_sm4_get_default_swizzle_type(
|
||||
const struct vkd3d_sm4_lookup_tables *lookup, enum vkd3d_shader_register_type vkd3d_type)
|
||||
{
|
||||
const struct vkd3d_sm4_register_type_info *register_type_info =
|
||||
get_info_from_vkd3d_register_type(lookup, vkd3d_type);
|
||||
|
||||
VKD3D_ASSERT(register_type_info);
|
||||
return register_type_info->default_src_swizzle_type;
|
||||
}
|
||||
|
||||
static enum vkd3d_sm4_stat_field get_stat_field_from_sm4_opcode(
|
||||
const struct vkd3d_sm4_lookup_tables *lookup, enum vkd3d_sm4_opcode sm4_opcode)
|
||||
{
|
||||
@ -2995,8 +2985,6 @@ int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t con
|
||||
return VKD3D_OK;
|
||||
}
|
||||
|
||||
static void write_sm4_block(struct tpf_compiler *tpf, const struct hlsl_block *block);
|
||||
|
||||
bool sm4_register_from_semantic_name(const struct vkd3d_shader_version *version,
|
||||
const char *semantic_name, bool output, enum vkd3d_shader_register_type *type, bool *has_idx)
|
||||
{
|
||||
@ -4099,64 +4087,6 @@ struct sm4_instruction
|
||||
unsigned int idx_src_count;
|
||||
};
|
||||
|
||||
static void sm4_register_from_node(struct vkd3d_shader_register *reg, uint32_t *writemask,
|
||||
const struct hlsl_ir_node *instr)
|
||||
{
|
||||
VKD3D_ASSERT(instr->reg.allocated);
|
||||
reg->type = VKD3DSPR_TEMP;
|
||||
reg->dimension = VSIR_DIMENSION_VEC4;
|
||||
reg->idx[0].offset = instr->reg.id;
|
||||
reg->idx_count = 1;
|
||||
*writemask = instr->reg.writemask;
|
||||
}
|
||||
|
||||
static void sm4_src_from_constant_value(struct vkd3d_shader_src_param *src,
|
||||
const struct hlsl_constant_value *value, unsigned int width, unsigned int map_writemask)
|
||||
{
|
||||
src->swizzle = 0;
|
||||
src->reg.type = VKD3DSPR_IMMCONST;
|
||||
if (width == 1)
|
||||
{
|
||||
src->reg.dimension = VSIR_DIMENSION_SCALAR;
|
||||
src->reg.u.immconst_u32[0] = value->u[0].u;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int i, j = 0;
|
||||
|
||||
src->reg.dimension = VSIR_DIMENSION_VEC4;
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
if ((map_writemask & (1u << i)) && (j < width))
|
||||
src->reg.u.immconst_u32[i] = value->u[j++].u;
|
||||
else
|
||||
src->reg.u.immconst_u32[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void sm4_src_from_node(const struct tpf_compiler *tpf, struct vkd3d_shader_src_param *src,
|
||||
const struct hlsl_ir_node *instr, uint32_t map_writemask)
|
||||
{
|
||||
unsigned int hlsl_swizzle;
|
||||
uint32_t writemask;
|
||||
|
||||
if (instr->type == HLSL_IR_CONSTANT)
|
||||
{
|
||||
struct hlsl_ir_constant *constant = hlsl_ir_constant(instr);
|
||||
|
||||
sm4_src_from_constant_value(src, &constant->value, instr->data_type->dimx, map_writemask);
|
||||
return;
|
||||
}
|
||||
|
||||
sm4_register_from_node(&src->reg, &writemask, instr);
|
||||
if (vkd3d_sm4_get_default_swizzle_type(&tpf->lookup, src->reg.type) == VKD3D_SM4_SWIZZLE_VEC4)
|
||||
{
|
||||
hlsl_swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), map_writemask);
|
||||
src->swizzle = swizzle_from_sm4(hlsl_swizzle);
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int sm4_get_index_addressing_from_reg(const struct vkd3d_shader_register *reg,
|
||||
unsigned int i)
|
||||
{
|
||||
@ -4688,26 +4618,6 @@ static void tpf_write_hs_decls(const struct tpf_compiler *tpf)
|
||||
write_sm4_instruction(tpf, &instr);
|
||||
}
|
||||
|
||||
static void tpf_write_hs_control_point_phase(const struct tpf_compiler *tpf)
|
||||
{
|
||||
struct sm4_instruction instr =
|
||||
{
|
||||
.opcode = VKD3D_SM5_OP_HS_CONTROL_POINT_PHASE,
|
||||
};
|
||||
|
||||
write_sm4_instruction(tpf, &instr);
|
||||
}
|
||||
|
||||
static void tpf_write_hs_fork_phase(const struct tpf_compiler *tpf)
|
||||
{
|
||||
struct sm4_instruction instr =
|
||||
{
|
||||
.opcode = VKD3D_SM5_OP_HS_FORK_PHASE,
|
||||
};
|
||||
|
||||
write_sm4_instruction(tpf, &instr);
|
||||
}
|
||||
|
||||
static void tpf_write_dcl_input_control_point_count(const struct tpf_compiler *tpf, const uint32_t count)
|
||||
{
|
||||
struct sm4_instruction instr =
|
||||
@ -4765,101 +4675,6 @@ static void tpf_write_dcl_tessellator_output_primitive(const struct tpf_compiler
|
||||
write_sm4_instruction(tpf, &instr);
|
||||
}
|
||||
|
||||
static void write_sm4_ret(const struct tpf_compiler *tpf)
|
||||
{
|
||||
struct sm4_instruction instr =
|
||||
{
|
||||
.opcode = VKD3D_SM4_OP_RET,
|
||||
};
|
||||
|
||||
write_sm4_instruction(tpf, &instr);
|
||||
}
|
||||
|
||||
static void write_sm4_if(struct tpf_compiler *tpf, const struct hlsl_ir_if *iff)
|
||||
{
|
||||
struct sm4_instruction instr =
|
||||
{
|
||||
.opcode = VKD3D_SM4_OP_IF,
|
||||
.extra_bits = VKD3D_SM4_CONDITIONAL_NZ,
|
||||
.src_count = 1,
|
||||
};
|
||||
|
||||
VKD3D_ASSERT(iff->condition.node->data_type->dimx == 1);
|
||||
|
||||
sm4_src_from_node(tpf, &instr.srcs[0], iff->condition.node, VKD3DSP_WRITEMASK_ALL);
|
||||
write_sm4_instruction(tpf, &instr);
|
||||
|
||||
write_sm4_block(tpf, &iff->then_block);
|
||||
|
||||
if (!list_empty(&iff->else_block.instrs))
|
||||
{
|
||||
instr.opcode = VKD3D_SM4_OP_ELSE;
|
||||
instr.src_count = 0;
|
||||
write_sm4_instruction(tpf, &instr);
|
||||
|
||||
write_sm4_block(tpf, &iff->else_block);
|
||||
}
|
||||
|
||||
instr.opcode = VKD3D_SM4_OP_ENDIF;
|
||||
instr.src_count = 0;
|
||||
write_sm4_instruction(tpf, &instr);
|
||||
}
|
||||
|
||||
static void write_sm4_loop(struct tpf_compiler *tpf, const struct hlsl_ir_loop *loop)
|
||||
{
|
||||
struct sm4_instruction instr =
|
||||
{
|
||||
.opcode = VKD3D_SM4_OP_LOOP,
|
||||
};
|
||||
|
||||
write_sm4_instruction(tpf, &instr);
|
||||
|
||||
write_sm4_block(tpf, &loop->body);
|
||||
|
||||
instr.opcode = VKD3D_SM4_OP_ENDLOOP;
|
||||
write_sm4_instruction(tpf, &instr);
|
||||
}
|
||||
|
||||
static void write_sm4_switch(struct tpf_compiler *tpf, const struct hlsl_ir_switch *s)
|
||||
{
|
||||
const struct hlsl_ir_node *selector = s->selector.node;
|
||||
struct hlsl_ir_switch_case *c;
|
||||
struct sm4_instruction instr;
|
||||
|
||||
memset(&instr, 0, sizeof(instr));
|
||||
instr.opcode = VKD3D_SM4_OP_SWITCH;
|
||||
|
||||
sm4_src_from_node(tpf, &instr.srcs[0], selector, VKD3DSP_WRITEMASK_ALL);
|
||||
instr.src_count = 1;
|
||||
|
||||
write_sm4_instruction(tpf, &instr);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(c, &s->cases, struct hlsl_ir_switch_case, entry)
|
||||
{
|
||||
memset(&instr, 0, sizeof(instr));
|
||||
if (c->is_default)
|
||||
{
|
||||
instr.opcode = VKD3D_SM4_OP_DEFAULT;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct hlsl_constant_value value = { .u[0].u = c->value };
|
||||
|
||||
instr.opcode = VKD3D_SM4_OP_CASE;
|
||||
sm4_src_from_constant_value(&instr.srcs[0], &value, 1, VKD3DSP_WRITEMASK_ALL);
|
||||
instr.src_count = 1;
|
||||
}
|
||||
|
||||
write_sm4_instruction(tpf, &instr);
|
||||
write_sm4_block(tpf, &c->body);
|
||||
}
|
||||
|
||||
memset(&instr, 0, sizeof(instr));
|
||||
instr.opcode = VKD3D_SM4_OP_ENDSWITCH;
|
||||
|
||||
write_sm4_instruction(tpf, &instr);
|
||||
}
|
||||
|
||||
static void tpf_simple_instruction(struct tpf_compiler *tpf, const struct vkd3d_shader_instruction *ins)
|
||||
{
|
||||
struct sm4_instruction_modifier *modifier;
|
||||
@ -4974,7 +4789,9 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_
|
||||
case VKD3DSIH_ADD:
|
||||
case VKD3DSIH_AND:
|
||||
case VKD3DSIH_BREAK:
|
||||
case VKD3DSIH_CASE:
|
||||
case VKD3DSIH_CONTINUE:
|
||||
case VKD3DSIH_DEFAULT:
|
||||
case VKD3DSIH_DISCARD:
|
||||
case VKD3DSIH_DIV:
|
||||
case VKD3DSIH_DP2:
|
||||
@ -4986,6 +4803,10 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_
|
||||
case VKD3DSIH_DSY:
|
||||
case VKD3DSIH_DSY_COARSE:
|
||||
case VKD3DSIH_DSY_FINE:
|
||||
case VKD3DSIH_ELSE:
|
||||
case VKD3DSIH_ENDIF:
|
||||
case VKD3DSIH_ENDLOOP:
|
||||
case VKD3DSIH_ENDSWITCH:
|
||||
case VKD3DSIH_EQO:
|
||||
case VKD3DSIH_EXP:
|
||||
case VKD3DSIH_F16TOF32:
|
||||
@ -4996,8 +4817,11 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_
|
||||
case VKD3DSIH_GATHER4:
|
||||
case VKD3DSIH_GATHER4_PO:
|
||||
case VKD3DSIH_GEO:
|
||||
case VKD3DSIH_HS_CONTROL_POINT_PHASE:
|
||||
case VKD3DSIH_HS_FORK_PHASE:
|
||||
case VKD3DSIH_IADD:
|
||||
case VKD3DSIH_IEQ:
|
||||
case VKD3DSIH_IF:
|
||||
case VKD3DSIH_IGE:
|
||||
case VKD3DSIH_ILT:
|
||||
case VKD3DSIH_IMAD:
|
||||
@ -5014,6 +4838,7 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_
|
||||
case VKD3DSIH_LD_RAW:
|
||||
case VKD3DSIH_LD_UAV_TYPED:
|
||||
case VKD3DSIH_LOG:
|
||||
case VKD3DSIH_LOOP:
|
||||
case VKD3DSIH_LTO:
|
||||
case VKD3DSIH_MAD:
|
||||
case VKD3DSIH_MAX:
|
||||
@ -5026,6 +4851,7 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_
|
||||
case VKD3DSIH_OR:
|
||||
case VKD3DSIH_RCP:
|
||||
case VKD3DSIH_RESINFO:
|
||||
case VKD3DSIH_RET:
|
||||
case VKD3DSIH_ROUND_NE:
|
||||
case VKD3DSIH_ROUND_NI:
|
||||
case VKD3DSIH_ROUND_PI:
|
||||
@ -5042,6 +4868,7 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_
|
||||
case VKD3DSIH_SQRT:
|
||||
case VKD3DSIH_STORE_RAW:
|
||||
case VKD3DSIH_STORE_UAV_TYPED:
|
||||
case VKD3DSIH_SWITCH:
|
||||
case VKD3DSIH_UDIV:
|
||||
case VKD3DSIH_UGE:
|
||||
case VKD3DSIH_ULT:
|
||||
@ -5059,67 +4886,15 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_
|
||||
}
|
||||
}
|
||||
|
||||
static void write_sm4_block(struct tpf_compiler *tpf, const struct hlsl_block *block)
|
||||
static void tpf_write_program(struct tpf_compiler *tpf, const struct vsir_program *program)
|
||||
{
|
||||
const struct hlsl_ir_node *instr;
|
||||
unsigned int vsir_instr_idx;
|
||||
unsigned int i;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(instr, &block->instrs, struct hlsl_ir_node, entry)
|
||||
{
|
||||
if (instr->data_type)
|
||||
{
|
||||
if (instr->data_type->class != HLSL_CLASS_SCALAR && instr->data_type->class != HLSL_CLASS_VECTOR)
|
||||
{
|
||||
hlsl_fixme(tpf->ctx, &instr->loc, "Class %#x should have been lowered or removed.",
|
||||
instr->data_type->class);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!instr->reg.allocated)
|
||||
{
|
||||
VKD3D_ASSERT(instr->type == HLSL_IR_CONSTANT);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
switch (instr->type)
|
||||
{
|
||||
case HLSL_IR_CALL:
|
||||
case HLSL_IR_CONSTANT:
|
||||
case HLSL_IR_RESOURCE_LOAD:
|
||||
vkd3d_unreachable();
|
||||
|
||||
case HLSL_IR_IF:
|
||||
write_sm4_if(tpf, hlsl_ir_if(instr));
|
||||
break;
|
||||
|
||||
case HLSL_IR_LOOP:
|
||||
write_sm4_loop(tpf, hlsl_ir_loop(instr));
|
||||
break;
|
||||
|
||||
case HLSL_IR_SWITCH:
|
||||
write_sm4_switch(tpf, hlsl_ir_switch(instr));
|
||||
break;
|
||||
|
||||
case HLSL_IR_VSIR_INSTRUCTION_REF:
|
||||
vsir_instr_idx = hlsl_ir_vsir_instruction_ref(instr)->vsir_instr_idx;
|
||||
tpf_handle_instruction(tpf, &tpf->program->instructions.elements[vsir_instr_idx]);
|
||||
break;
|
||||
|
||||
default:
|
||||
hlsl_fixme(tpf->ctx, &instr->loc, "Instruction type %s.", hlsl_node_type_to_string(instr->type));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void tpf_write_shader_function(struct tpf_compiler *tpf, struct hlsl_ir_function_decl *func)
|
||||
{
|
||||
if (tpf->program->shader_version.type == VKD3D_SHADER_TYPE_COMPUTE)
|
||||
tpf_dcl_thread_group(tpf, &tpf->program->thread_group_size);
|
||||
|
||||
write_sm4_block(tpf, &func->body);
|
||||
|
||||
write_sm4_ret(tpf);
|
||||
for (i = 0; i < program->instructions.count; ++i)
|
||||
tpf_handle_instruction(tpf, &program->instructions.elements[i]);
|
||||
}
|
||||
|
||||
static void tpf_write_shdr(struct tpf_compiler *tpf, struct hlsl_ir_function_decl *entry_func)
|
||||
@ -5208,16 +4983,7 @@ static void tpf_write_shdr(struct tpf_compiler *tpf, struct hlsl_ir_function_dec
|
||||
write_sm4_dcl_textures(tpf, resource, true);
|
||||
}
|
||||
|
||||
if (version->type == VKD3D_SHADER_TYPE_HULL)
|
||||
tpf_write_hs_control_point_phase(tpf);
|
||||
|
||||
tpf_write_shader_function(tpf, entry_func);
|
||||
|
||||
if (version->type == VKD3D_SHADER_TYPE_HULL)
|
||||
{
|
||||
tpf_write_hs_fork_phase(tpf);
|
||||
tpf_write_shader_function(tpf, ctx->patch_constant_func);
|
||||
}
|
||||
tpf_write_program(tpf, tpf->program);
|
||||
|
||||
set_u32(&buffer, token_count_position, bytecode_get_size(&buffer) / sizeof(uint32_t));
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user