mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-01-28 13:05:02 -08:00
vkd3d-shader/ir: Synthesize the default control point phase in the HS control point I/O normaliser.
This makes it available to all backends, without requiring an ad-hoc solution for each of them. It also gets rid of an undocumented flag we're currently passing to DCL_CONTROL_POINT_PHASE.
This commit is contained in:
parent
198c3dc7b9
commit
1cfe23569c
Notes:
Henri Verbeet
2024-11-27 14:11:54 +01:00
Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1281
@ -201,6 +201,14 @@ static void src_param_init_const_uint(struct vkd3d_shader_src_param *src, uint32
|
|||||||
src->reg.u.immconst_u32[0] = value;
|
src->reg.u.immconst_u32[0] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void vsir_src_param_init_io(struct vkd3d_shader_src_param *src,
|
||||||
|
enum vkd3d_shader_register_type reg_type, const struct signature_element *e, unsigned int idx_count)
|
||||||
|
{
|
||||||
|
vsir_src_param_init(src, reg_type, vkd3d_data_type_from_component_type(e->component_type), idx_count);
|
||||||
|
src->reg.dimension = VSIR_DIMENSION_VEC4;
|
||||||
|
src->swizzle = vsir_swizzle_from_writemask(e->mask);
|
||||||
|
}
|
||||||
|
|
||||||
void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned int label_id)
|
void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned int label_id)
|
||||||
{
|
{
|
||||||
vsir_src_param_init(param, VKD3DSPR_LABEL, VKD3D_DATA_UNUSED, 1);
|
vsir_src_param_init(param, VKD3DSPR_LABEL, VKD3D_DATA_UNUSED, 1);
|
||||||
@ -278,6 +286,14 @@ void vsir_dst_param_init(struct vkd3d_shader_dst_param *param, enum vkd3d_shader
|
|||||||
param->shift = 0;
|
param->shift = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void vsir_dst_param_init_io(struct vkd3d_shader_dst_param *dst, enum vkd3d_shader_register_type reg_type,
|
||||||
|
const struct signature_element *e, unsigned int idx_count)
|
||||||
|
{
|
||||||
|
vsir_dst_param_init(dst, reg_type, vkd3d_data_type_from_component_type(e->component_type), idx_count);
|
||||||
|
dst->reg.dimension = VSIR_DIMENSION_VEC4;
|
||||||
|
dst->write_mask = e->mask;
|
||||||
|
}
|
||||||
|
|
||||||
static void dst_param_init_ssa_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx)
|
static void dst_param_init_ssa_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx)
|
||||||
{
|
{
|
||||||
vsir_dst_param_init(dst, VKD3DSPR_SSA, VKD3D_DATA_BOOL, 1);
|
vsir_dst_param_init(dst, VKD3DSPR_SSA, VKD3D_DATA_BOOL, 1);
|
||||||
@ -1370,26 +1386,17 @@ static void shader_dst_param_normalise_outpointid(struct vkd3d_shader_dst_param
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void shader_dst_param_io_init(struct vkd3d_shader_dst_param *param, const struct signature_element *e,
|
|
||||||
enum vkd3d_shader_register_type reg_type, unsigned int idx_count)
|
|
||||||
{
|
|
||||||
param->write_mask = e->mask;
|
|
||||||
param->modifiers = 0;
|
|
||||||
param->shift = 0;
|
|
||||||
vsir_register_init(¶m->reg, reg_type, vkd3d_data_type_from_component_type(e->component_type), idx_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_point_normaliser *normaliser,
|
static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_point_normaliser *normaliser,
|
||||||
const struct shader_signature *s, unsigned int input_control_point_count, unsigned int dst,
|
const struct shader_signature *s, unsigned int input_control_point_count, unsigned int dst,
|
||||||
const struct vkd3d_shader_location *location)
|
const struct vkd3d_shader_location *location)
|
||||||
{
|
{
|
||||||
struct vkd3d_shader_instruction *ins;
|
struct vkd3d_shader_instruction *ins;
|
||||||
struct vkd3d_shader_dst_param *param;
|
|
||||||
const struct signature_element *e;
|
const struct signature_element *e;
|
||||||
unsigned int i, count;
|
unsigned int i, count, stride = 0;
|
||||||
|
|
||||||
for (i = 0, count = 1; i < s->element_count; ++i)
|
for (i = 0; i < s->element_count; ++i)
|
||||||
count += !!s->elements[i].used_mask;
|
stride += !!s->elements[i].used_mask;
|
||||||
|
count = 2 + 3 * stride;
|
||||||
|
|
||||||
if (!shader_instruction_array_reserve(&normaliser->instructions, normaliser->instructions.count + count))
|
if (!shader_instruction_array_reserve(&normaliser->instructions, normaliser->instructions.count + count))
|
||||||
return VKD3D_ERROR_OUT_OF_MEMORY;
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||||
@ -1400,31 +1407,75 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p
|
|||||||
|
|
||||||
ins = &normaliser->instructions.elements[dst];
|
ins = &normaliser->instructions.elements[dst];
|
||||||
vsir_instruction_init(ins, location, VKD3DSIH_HS_CONTROL_POINT_PHASE);
|
vsir_instruction_init(ins, location, VKD3DSIH_HS_CONTROL_POINT_PHASE);
|
||||||
ins->flags = 1;
|
|
||||||
++ins;
|
ins = &normaliser->instructions.elements[dst + 1 + 3 * stride];
|
||||||
|
vsir_instruction_init(ins, location, VKD3DSIH_RET);
|
||||||
|
|
||||||
|
ins = &normaliser->instructions.elements[dst + 1];
|
||||||
|
|
||||||
for (i = 0; i < s->element_count; ++i)
|
for (i = 0; i < s->element_count; ++i)
|
||||||
{
|
{
|
||||||
|
struct vkd3d_shader_instruction *ins_in, *ins_out, *ins_mov;
|
||||||
|
struct vkd3d_shader_dst_param *param_in, *param_out;
|
||||||
|
|
||||||
e = &s->elements[i];
|
e = &s->elements[i];
|
||||||
if (!e->used_mask)
|
if (!e->used_mask)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
ins_in = ins;
|
||||||
|
ins_out = &ins[stride];
|
||||||
|
ins_mov = &ins[2 * stride];
|
||||||
|
|
||||||
if (e->sysval_semantic != VKD3D_SHADER_SV_NONE)
|
if (e->sysval_semantic != VKD3D_SHADER_SV_NONE)
|
||||||
{
|
{
|
||||||
vsir_instruction_init(ins, location, VKD3DSIH_DCL_INPUT_SIV);
|
vsir_instruction_init(ins_in, location, VKD3DSIH_DCL_INPUT_SIV);
|
||||||
param = &ins->declaration.register_semantic.reg;
|
param_in = &ins_in->declaration.register_semantic.reg;
|
||||||
ins->declaration.register_semantic.sysval_semantic = vkd3d_siv_from_sysval(e->sysval_semantic);
|
ins_in->declaration.register_semantic.sysval_semantic = vkd3d_siv_from_sysval(e->sysval_semantic);
|
||||||
|
|
||||||
|
vsir_instruction_init(ins_out, location, VKD3DSIH_DCL_OUTPUT_SIV);
|
||||||
|
param_out = &ins_out->declaration.register_semantic.reg;
|
||||||
|
ins_out->declaration.register_semantic.sysval_semantic = vkd3d_siv_from_sysval(e->sysval_semantic);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vsir_instruction_init(ins, location, VKD3DSIH_DCL_INPUT);
|
vsir_instruction_init(ins_in, location, VKD3DSIH_DCL_INPUT);
|
||||||
param = &ins->declaration.dst;
|
param_in = &ins_in->declaration.dst;
|
||||||
|
|
||||||
|
vsir_instruction_init(ins_out, location, VKD3DSIH_DCL_OUTPUT);
|
||||||
|
param_out = &ins_out->declaration.dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
shader_dst_param_io_init(param, e, VKD3DSPR_INPUT, 2);
|
vsir_dst_param_init_io(param_in, VKD3DSPR_INPUT, e, 2);
|
||||||
param->reg.idx[0].offset = input_control_point_count;
|
param_in->reg.idx[0].offset = input_control_point_count;
|
||||||
param->reg.idx[1].offset = e->register_index;
|
param_in->reg.idx[1].offset = e->register_index;
|
||||||
param->write_mask = e->mask;
|
param_in->write_mask = e->mask;
|
||||||
|
|
||||||
|
vsir_dst_param_init_io(param_out, VKD3DSPR_OUTPUT, e, 2);
|
||||||
|
param_out->reg.idx[0].offset = input_control_point_count;
|
||||||
|
param_out->reg.idx[1].offset = e->register_index;
|
||||||
|
param_out->write_mask = e->mask;
|
||||||
|
|
||||||
|
vsir_instruction_init(ins_mov, location, VKD3DSIH_MOV);
|
||||||
|
ins_mov->dst = shader_dst_param_allocator_get(&normaliser->instructions.dst_params, 1);
|
||||||
|
ins_mov->dst_count = 1;
|
||||||
|
ins_mov->src = shader_src_param_allocator_get(&normaliser->instructions.src_params, 1);
|
||||||
|
ins_mov->src_count = 1;
|
||||||
|
|
||||||
|
if (!ins_mov->dst || ! ins_mov->src)
|
||||||
|
{
|
||||||
|
WARN("Failed to allocate dst/src param.\n");
|
||||||
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
vsir_dst_param_init_io(&ins_mov->dst[0], VKD3DSPR_OUTPUT, e, 2);
|
||||||
|
ins_mov->dst[0].reg.idx[0].offset = 0;
|
||||||
|
ins_mov->dst[0].reg.idx[0].rel_addr = normaliser->outpointid_param;
|
||||||
|
ins_mov->dst[0].reg.idx[1].offset = e->register_index;
|
||||||
|
|
||||||
|
vsir_src_param_init_io(&ins_mov->src[0], VKD3DSPR_INPUT, e, 2);
|
||||||
|
ins_mov->src[0].reg.idx[0].offset = 0;
|
||||||
|
ins_mov->src[0].reg.idx[0].rel_addr = normaliser->outpointid_param;
|
||||||
|
ins_mov->src[0].reg.idx[1].offset = e->register_index;
|
||||||
|
|
||||||
++ins;
|
++ins;
|
||||||
}
|
}
|
||||||
|
@ -2471,7 +2471,6 @@ struct spirv_compiler
|
|||||||
bool emit_point_size;
|
bool emit_point_size;
|
||||||
|
|
||||||
enum vkd3d_shader_opcode phase;
|
enum vkd3d_shader_opcode phase;
|
||||||
bool emit_default_control_point_phase;
|
|
||||||
struct vkd3d_shader_phase control_point_phase;
|
struct vkd3d_shader_phase control_point_phase;
|
||||||
struct vkd3d_shader_phase patch_constant_phase;
|
struct vkd3d_shader_phase patch_constant_phase;
|
||||||
|
|
||||||
@ -6912,15 +6911,10 @@ static void spirv_compiler_emit_thread_group_size(struct spirv_compiler *compile
|
|||||||
SpvExecutionModeLocalSize, local_size, ARRAY_SIZE(local_size));
|
SpvExecutionModeLocalSize, local_size, ARRAY_SIZE(local_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void spirv_compiler_emit_default_control_point_phase(struct spirv_compiler *compiler);
|
|
||||||
|
|
||||||
static void spirv_compiler_leave_shader_phase(struct spirv_compiler *compiler)
|
static void spirv_compiler_leave_shader_phase(struct spirv_compiler *compiler)
|
||||||
{
|
{
|
||||||
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
||||||
|
|
||||||
if (is_in_control_point_phase(compiler) && compiler->emit_default_control_point_phase)
|
|
||||||
spirv_compiler_emit_default_control_point_phase(compiler);
|
|
||||||
|
|
||||||
vkd3d_spirv_build_op_function_end(builder);
|
vkd3d_spirv_build_op_function_end(builder);
|
||||||
|
|
||||||
if (is_in_control_point_phase(compiler))
|
if (is_in_control_point_phase(compiler))
|
||||||
@ -6965,9 +6959,6 @@ static void spirv_compiler_enter_shader_phase(struct spirv_compiler *compiler,
|
|||||||
phase->function_id = function_id;
|
phase->function_id = function_id;
|
||||||
/* The insertion location must be set after the label is emitted. */
|
/* The insertion location must be set after the label is emitted. */
|
||||||
phase->function_location = 0;
|
phase->function_location = 0;
|
||||||
|
|
||||||
if (instruction->opcode == VKD3DSIH_HS_CONTROL_POINT_PHASE)
|
|
||||||
compiler->emit_default_control_point_phase = instruction->flags;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void spirv_compiler_initialise_block(struct spirv_compiler *compiler)
|
static void spirv_compiler_initialise_block(struct spirv_compiler *compiler)
|
||||||
@ -6996,63 +6987,6 @@ static void spirv_compiler_initialise_block(struct spirv_compiler *compiler)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void spirv_compiler_emit_default_control_point_phase(struct spirv_compiler *compiler)
|
|
||||||
{
|
|
||||||
const struct shader_signature *output_signature = &compiler->output_signature;
|
|
||||||
const struct shader_signature *input_signature = &compiler->input_signature;
|
|
||||||
uint32_t type_id, output_ptr_type_id, input_id, dst_id, invocation_id;
|
|
||||||
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
||||||
enum vkd3d_shader_component_type component_type;
|
|
||||||
struct vkd3d_shader_src_param invocation;
|
|
||||||
struct vkd3d_shader_register input_reg;
|
|
||||||
unsigned int component_count;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
vkd3d_spirv_build_op_label(builder, vkd3d_spirv_alloc_id(builder));
|
|
||||||
spirv_compiler_initialise_block(compiler);
|
|
||||||
invocation_id = spirv_compiler_emit_load_invocation_id(compiler);
|
|
||||||
|
|
||||||
memset(&invocation, 0, sizeof(invocation));
|
|
||||||
vsir_register_init(&invocation.reg, VKD3DSPR_OUTPOINTID, VKD3D_DATA_INT, 0);
|
|
||||||
invocation.swizzle = VKD3D_SHADER_NO_SWIZZLE;
|
|
||||||
|
|
||||||
vsir_register_init(&input_reg, VKD3DSPR_INPUT, VKD3D_DATA_FLOAT, 2);
|
|
||||||
input_reg.idx[0].offset = 0;
|
|
||||||
input_reg.idx[0].rel_addr = &invocation;
|
|
||||||
input_reg.idx[1].offset = 0;
|
|
||||||
input_id = spirv_compiler_get_register_id(compiler, &input_reg);
|
|
||||||
|
|
||||||
VKD3D_ASSERT(input_signature->element_count == output_signature->element_count);
|
|
||||||
for (i = 0; i < output_signature->element_count; ++i)
|
|
||||||
{
|
|
||||||
const struct signature_element *output = &output_signature->elements[i];
|
|
||||||
const struct signature_element *input = &input_signature->elements[i];
|
|
||||||
struct vkd3d_shader_register_info output_reg_info;
|
|
||||||
struct vkd3d_shader_register output_reg;
|
|
||||||
|
|
||||||
VKD3D_ASSERT(input->mask == output->mask);
|
|
||||||
VKD3D_ASSERT(input->component_type == output->component_type);
|
|
||||||
|
|
||||||
input_reg.idx[1].offset = i;
|
|
||||||
input_id = spirv_compiler_get_register_id(compiler, &input_reg);
|
|
||||||
|
|
||||||
vsir_register_init(&output_reg, VKD3DSPR_OUTPUT, VKD3D_DATA_FLOAT, 1);
|
|
||||||
output_reg.idx[0].offset = i;
|
|
||||||
spirv_compiler_get_register_info(compiler, &output_reg, &output_reg_info);
|
|
||||||
|
|
||||||
component_type = output->component_type;
|
|
||||||
component_count = vsir_write_mask_component_count(output->mask);
|
|
||||||
type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count);
|
|
||||||
output_ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassOutput, type_id);
|
|
||||||
|
|
||||||
dst_id = vkd3d_spirv_build_op_access_chain1(builder, output_ptr_type_id, output_reg_info.id, invocation_id);
|
|
||||||
|
|
||||||
vkd3d_spirv_build_op_copy_memory(builder, dst_id, input_id, SpvMemoryAccessMaskNone);
|
|
||||||
}
|
|
||||||
|
|
||||||
vkd3d_spirv_build_op_return(builder);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void spirv_compiler_emit_barrier(struct spirv_compiler *compiler,
|
static void spirv_compiler_emit_barrier(struct spirv_compiler *compiler,
|
||||||
SpvScope execution_scope, SpvScope memory_scope, SpvMemorySemanticsMask semantics)
|
SpvScope execution_scope, SpvScope memory_scope, SpvMemorySemanticsMask semantics)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user