mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-12-15 08:03:30 -08:00
vkd3d-shader/ir: Execute PHI SSA to TEMP materialization in each function.
This commit is contained in:
committed by
Henri Verbeet
parent
2d508a2fa6
commit
3c117e2331
Notes:
Henri Verbeet
2025-10-03 00:55:36 +02:00
Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1763
@@ -4747,11 +4747,11 @@ static void ssas_to_temps_block_info_cleanup(struct ssas_to_temps_block_info *bl
|
|||||||
vkd3d_free(block_info);
|
vkd3d_free(block_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_program *program,
|
static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps_in_function(
|
||||||
struct vsir_transformation_context *ctx)
|
struct vsir_program *program, struct vsir_program_iterator *it)
|
||||||
{
|
{
|
||||||
struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
|
|
||||||
struct ssas_to_temps_block_info *info, *block_info = NULL;
|
struct ssas_to_temps_block_info *info, *block_info = NULL;
|
||||||
|
struct vsir_program_iterator it_begin = *it;
|
||||||
struct ssas_to_temps_alloc alloc = {0};
|
struct ssas_to_temps_alloc alloc = {0};
|
||||||
struct vkd3d_shader_instruction *ins;
|
struct vkd3d_shader_instruction *ins;
|
||||||
size_t phi_count, incoming_count;
|
size_t phi_count, incoming_count;
|
||||||
@@ -4770,14 +4770,31 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_
|
|||||||
|
|
||||||
phi_count = 0;
|
phi_count = 0;
|
||||||
incoming_count = 0;
|
incoming_count = 0;
|
||||||
for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
|
for (ins = vsir_program_iterator_current(it); ins; ins = vsir_program_iterator_next(it))
|
||||||
{
|
{
|
||||||
unsigned int j, temp_idx;
|
unsigned int j, temp_idx;
|
||||||
|
bool finish = false;
|
||||||
|
|
||||||
/* Only phi src/dst SSA values need be converted here. Structurisation may
|
/* Only phi src/dst SSA values need be converted here. Structurisation may
|
||||||
* introduce new cases of undominated SSA use, which will be handled later. */
|
* introduce new cases of undominated SSA use, which will be handled later. */
|
||||||
if (ins->opcode != VSIR_OP_PHI)
|
switch (ins->opcode)
|
||||||
continue;
|
{
|
||||||
|
case VSIR_OP_PHI:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VSIR_OP_HS_CONTROL_POINT_PHASE:
|
||||||
|
case VSIR_OP_HS_FORK_PHASE:
|
||||||
|
case VSIR_OP_HS_JOIN_PHASE:
|
||||||
|
finish = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (finish)
|
||||||
|
break;
|
||||||
|
|
||||||
++phi_count;
|
++phi_count;
|
||||||
|
|
||||||
temp_idx = alloc.next_temp_idx++;
|
temp_idx = alloc.next_temp_idx++;
|
||||||
@@ -4814,9 +4831,12 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_
|
|||||||
if (!shader_instruction_array_reserve(&program->instructions, program->instructions.count + incoming_count))
|
if (!shader_instruction_array_reserve(&program->instructions, program->instructions.count + incoming_count))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
|
*it = it_begin;
|
||||||
|
|
||||||
|
for (ins = vsir_program_iterator_current(it); ins; ins = vsir_program_iterator_next(it))
|
||||||
{
|
{
|
||||||
struct vkd3d_shader_instruction *mov_ins;
|
struct vkd3d_shader_instruction *mov_ins;
|
||||||
|
bool finish = false;
|
||||||
size_t j;
|
size_t j;
|
||||||
|
|
||||||
for (j = 0; j < ins->dst_count; ++j)
|
for (j = 0; j < ins->dst_count; ++j)
|
||||||
@@ -4835,7 +4855,7 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_
|
|||||||
case VSIR_OP_SWITCH_MONOLITHIC:
|
case VSIR_OP_SWITCH_MONOLITHIC:
|
||||||
info = &block_info[current_label - 1];
|
info = &block_info[current_label - 1];
|
||||||
|
|
||||||
mov_ins = vsir_program_iterator_insert_before_and_move(&it, info->incoming_count);
|
mov_ins = vsir_program_iterator_insert_before_and_move(it, info->incoming_count);
|
||||||
VKD3D_ASSERT(mov_ins);
|
VKD3D_ASSERT(mov_ins);
|
||||||
|
|
||||||
for (j = 0; j < info->incoming_count; ++j)
|
for (j = 0; j < info->incoming_count; ++j)
|
||||||
@@ -4851,7 +4871,7 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_
|
|||||||
mov_ins->src = incoming->src;
|
mov_ins->src = incoming->src;
|
||||||
mov_ins->src_count = 1;
|
mov_ins->src_count = 1;
|
||||||
|
|
||||||
mov_ins = vsir_program_iterator_next(&it);
|
mov_ins = vsir_program_iterator_next(it);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -4859,9 +4879,18 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_
|
|||||||
vkd3d_shader_instruction_make_nop(ins);
|
vkd3d_shader_instruction_make_nop(ins);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VSIR_OP_HS_CONTROL_POINT_PHASE:
|
||||||
|
case VSIR_OP_HS_FORK_PHASE:
|
||||||
|
case VSIR_OP_HS_JOIN_PHASE:
|
||||||
|
finish = true;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (finish)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
program->temp_count = alloc.next_temp_idx;
|
program->temp_count = alloc.next_temp_idx;
|
||||||
@@ -4878,6 +4907,45 @@ fail:
|
|||||||
return VKD3D_ERROR_OUT_OF_MEMORY;
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_program *program,
|
||||||
|
struct vsir_transformation_context *ctx)
|
||||||
|
{
|
||||||
|
struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
|
||||||
|
struct vkd3d_shader_instruction *ins;
|
||||||
|
enum vkd3d_result ret;
|
||||||
|
|
||||||
|
VKD3D_ASSERT(program->cf_type == VSIR_CF_BLOCKS);
|
||||||
|
|
||||||
|
for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_current(&it))
|
||||||
|
{
|
||||||
|
switch (ins->opcode)
|
||||||
|
{
|
||||||
|
case VSIR_OP_LABEL:
|
||||||
|
VKD3D_ASSERT(program->shader_version.type != VKD3D_SHADER_TYPE_HULL);
|
||||||
|
TRACE("Materializing undominated SSAs in a non-hull shader.\n");
|
||||||
|
if ((ret = vsir_program_materialise_phi_ssas_to_temps_in_function(program, &it)) < 0)
|
||||||
|
return ret;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VSIR_OP_HS_CONTROL_POINT_PHASE:
|
||||||
|
case VSIR_OP_HS_FORK_PHASE:
|
||||||
|
case VSIR_OP_HS_JOIN_PHASE:
|
||||||
|
VKD3D_ASSERT(program->shader_version.type == VKD3D_SHADER_TYPE_HULL);
|
||||||
|
TRACE("Materializing undominated SSAs in phase %u of a hull shader.\n", ins->opcode);
|
||||||
|
vsir_program_iterator_next(&it);
|
||||||
|
if ((ret = vsir_program_materialise_phi_ssas_to_temps_in_function(program, &it)) < 0)
|
||||||
|
return ret;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
vsir_program_iterator_next(&it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return VKD3D_OK;
|
||||||
|
}
|
||||||
|
|
||||||
struct vsir_block_list
|
struct vsir_block_list
|
||||||
{
|
{
|
||||||
struct vsir_block **blocks;
|
struct vsir_block **blocks;
|
||||||
|
|||||||
Reference in New Issue
Block a user