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:
Francisco Casas 2024-11-08 21:22:51 -03:00 committed by Henri Verbeet
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
2 changed files with 113 additions and 312 deletions

View File

@ -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); 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, 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 hlsl_ir_var *var, bool is_patch_constant_func, struct hlsl_block *block,
const struct vkd3d_shader_location *loc) 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) if (var->is_input_semantic && version->type == VKD3D_SHADER_TYPE_PIXEL)
ins->flags = sm4_get_interpolation_mode(var->data_type, var->storage_modifiers); 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, 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; return;
ins->declaration.count = temp_count; 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, 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.data_type = VKD3D_DATA_FLOAT;
ins->declaration.indexable_temp.component_count = comp_count; ins->declaration.indexable_temp.component_count = comp_count;
ins->declaration.indexable_temp.has_function_scope = false; 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) 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) 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 vkd3d_string_buffer *dst_type_string;
struct hlsl_ir_node *instr, *next; 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) 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: case HLSL_IR_EXPR:
if (!(dst_type_string = hlsl_type_to_string(ctx, instr->data_type))) if (!(dst_type_string = hlsl_type_to_string(ctx, instr->data_type)))
break; break;
sm4_generate_vsir_instr_expr(ctx, program, hlsl_ir_expr(instr), dst_type_string->buffer);
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);
hlsl_release_string_buffer(ctx, dst_type_string); hlsl_release_string_buffer(ctx, dst_type_string);
break; break;
case HLSL_IR_IF: case HLSL_IR_IF:
sm4_generate_vsir_block(ctx, &hlsl_ir_if(instr)->then_block, program); sm4_generate_vsir_instr_if(ctx, program, hlsl_ir_if(instr));
sm4_generate_vsir_block(ctx, &hlsl_ir_if(instr)->else_block, program);
break; break;
case HLSL_IR_LOAD: case HLSL_IR_LOAD:
if (sm4_generate_vsir_instr_load(ctx, program, hlsl_ir_load(instr))) sm4_generate_vsir_instr_load(ctx, program, hlsl_ir_load(instr));
replace_instr_with_last_vsir_instr(ctx, program, instr);
break; break;
case HLSL_IR_LOOP: 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; break;
case HLSL_IR_RESOURCE_LOAD: case HLSL_IR_RESOURCE_LOAD:
if (sm4_generate_vsir_instr_resource_load(ctx, program, hlsl_ir_resource_load(instr))) sm4_generate_vsir_instr_resource_load(ctx, program, hlsl_ir_resource_load(instr));
replace_instr_with_last_vsir_instr(ctx, program, instr);
break; break;
case HLSL_IR_RESOURCE_STORE: case HLSL_IR_RESOURCE_STORE:
if (sm4_generate_vsir_instr_resource_store(ctx, program, hlsl_ir_resource_store(instr))) sm4_generate_vsir_instr_resource_store(ctx, program, hlsl_ir_resource_store(instr));
replace_instr_with_last_vsir_instr(ctx, program, instr);
break; break;
case HLSL_IR_JUMP: case HLSL_IR_JUMP:
if (sm4_generate_vsir_instr_jump(ctx, program, hlsl_ir_jump(instr))) sm4_generate_vsir_instr_jump(ctx, program, hlsl_ir_jump(instr));
replace_instr_with_last_vsir_instr(ctx, program, instr);
break; break;
case HLSL_IR_STORE: case HLSL_IR_STORE:
if (sm4_generate_vsir_instr_store(ctx, program, hlsl_ir_store(instr))) sm4_generate_vsir_instr_store(ctx, program, hlsl_ir_store(instr));
replace_instr_with_last_vsir_instr(ctx, program, instr);
break; break;
case HLSL_IR_SWITCH: case HLSL_IR_SWITCH:
LIST_FOR_EACH_ENTRY(c, &hlsl_ir_switch(instr)->cases, struct hlsl_ir_switch_case, entry) sm4_generate_vsir_instr_switch(ctx, program, hlsl_ir_switch(instr));
sm4_generate_vsir_block(ctx, &c->body, program);
break; break;
case HLSL_IR_SWIZZLE: case HLSL_IR_SWIZZLE:
generate_vsir_instr_swizzle(ctx, program, hlsl_ir_swizzle(instr)); generate_vsir_instr_swizzle(ctx, program, hlsl_ir_swizzle(instr));
replace_instr_with_last_vsir_instr(ctx, program, instr);
break; break;
default: default:
@ -9449,6 +9475,8 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx,
hlsl_block_cleanup(&block); hlsl_block_cleanup(&block);
sm4_generate_vsir_block(ctx, &func->body, program); 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 /* 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]; 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); sm4_generate_vsir_add_function(ctx, func, config_flags, program);
if (version.type == VKD3D_SHADER_TYPE_HULL) 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); 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, static struct hlsl_ir_jump *loop_unrolling_find_jump(struct hlsl_block *block, struct hlsl_ir_node *stop_point,

View File

@ -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]; 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( 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) 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; 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, 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) 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; 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, static unsigned int sm4_get_index_addressing_from_reg(const struct vkd3d_shader_register *reg,
unsigned int i) unsigned int i)
{ {
@ -4688,26 +4618,6 @@ static void tpf_write_hs_decls(const struct tpf_compiler *tpf)
write_sm4_instruction(tpf, &instr); 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) static void tpf_write_dcl_input_control_point_count(const struct tpf_compiler *tpf, const uint32_t count)
{ {
struct sm4_instruction instr = 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); 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) static void tpf_simple_instruction(struct tpf_compiler *tpf, const struct vkd3d_shader_instruction *ins)
{ {
struct sm4_instruction_modifier *modifier; 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_ADD:
case VKD3DSIH_AND: case VKD3DSIH_AND:
case VKD3DSIH_BREAK: case VKD3DSIH_BREAK:
case VKD3DSIH_CASE:
case VKD3DSIH_CONTINUE: case VKD3DSIH_CONTINUE:
case VKD3DSIH_DEFAULT:
case VKD3DSIH_DISCARD: case VKD3DSIH_DISCARD:
case VKD3DSIH_DIV: case VKD3DSIH_DIV:
case VKD3DSIH_DP2: 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:
case VKD3DSIH_DSY_COARSE: case VKD3DSIH_DSY_COARSE:
case VKD3DSIH_DSY_FINE: case VKD3DSIH_DSY_FINE:
case VKD3DSIH_ELSE:
case VKD3DSIH_ENDIF:
case VKD3DSIH_ENDLOOP:
case VKD3DSIH_ENDSWITCH:
case VKD3DSIH_EQO: case VKD3DSIH_EQO:
case VKD3DSIH_EXP: case VKD3DSIH_EXP:
case VKD3DSIH_F16TOF32: 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:
case VKD3DSIH_GATHER4_PO: case VKD3DSIH_GATHER4_PO:
case VKD3DSIH_GEO: case VKD3DSIH_GEO:
case VKD3DSIH_HS_CONTROL_POINT_PHASE:
case VKD3DSIH_HS_FORK_PHASE:
case VKD3DSIH_IADD: case VKD3DSIH_IADD:
case VKD3DSIH_IEQ: case VKD3DSIH_IEQ:
case VKD3DSIH_IF:
case VKD3DSIH_IGE: case VKD3DSIH_IGE:
case VKD3DSIH_ILT: case VKD3DSIH_ILT:
case VKD3DSIH_IMAD: 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_RAW:
case VKD3DSIH_LD_UAV_TYPED: case VKD3DSIH_LD_UAV_TYPED:
case VKD3DSIH_LOG: case VKD3DSIH_LOG:
case VKD3DSIH_LOOP:
case VKD3DSIH_LTO: case VKD3DSIH_LTO:
case VKD3DSIH_MAD: case VKD3DSIH_MAD:
case VKD3DSIH_MAX: case VKD3DSIH_MAX:
@ -5026,6 +4851,7 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_
case VKD3DSIH_OR: case VKD3DSIH_OR:
case VKD3DSIH_RCP: case VKD3DSIH_RCP:
case VKD3DSIH_RESINFO: case VKD3DSIH_RESINFO:
case VKD3DSIH_RET:
case VKD3DSIH_ROUND_NE: case VKD3DSIH_ROUND_NE:
case VKD3DSIH_ROUND_NI: case VKD3DSIH_ROUND_NI:
case VKD3DSIH_ROUND_PI: 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_SQRT:
case VKD3DSIH_STORE_RAW: case VKD3DSIH_STORE_RAW:
case VKD3DSIH_STORE_UAV_TYPED: case VKD3DSIH_STORE_UAV_TYPED:
case VKD3DSIH_SWITCH:
case VKD3DSIH_UDIV: case VKD3DSIH_UDIV:
case VKD3DSIH_UGE: case VKD3DSIH_UGE:
case VKD3DSIH_ULT: 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 i;
unsigned int vsir_instr_idx;
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) if (tpf->program->shader_version.type == VKD3D_SHADER_TYPE_COMPUTE)
tpf_dcl_thread_group(tpf, &tpf->program->thread_group_size); tpf_dcl_thread_group(tpf, &tpf->program->thread_group_size);
write_sm4_block(tpf, &func->body); for (i = 0; i < program->instructions.count; ++i)
tpf_handle_instruction(tpf, &program->instructions.elements[i]);
write_sm4_ret(tpf);
} }
static void tpf_write_shdr(struct tpf_compiler *tpf, struct hlsl_ir_function_decl *entry_func) 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); write_sm4_dcl_textures(tpf, resource, true);
} }
if (version->type == VKD3D_SHADER_TYPE_HULL) tpf_write_program(tpf, tpf->program);
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);
}
set_u32(&buffer, token_count_position, bytecode_get_size(&buffer) / sizeof(uint32_t)); set_u32(&buffer, token_count_position, bytecode_get_size(&buffer) / sizeof(uint32_t));