mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-01-28 13:05:02 -08:00
vkd3d-shader/ir: Encode I/O declarations in vsir_program.
Most I/O registers are already described by the shader signatures. The registers that are not do not have any property other then being used by the program or not, so they can be collectively described with a bitmap.
This commit is contained in:
parent
a92b602b33
commit
18e422dfe4
Notes:
Henri Verbeet
2024-12-03 14:56:21 +01:00
Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1288
@ -2547,6 +2547,33 @@ static void trace_signature(const struct shader_signature *signature, const char
|
||||
vkd3d_string_buffer_cleanup(&buffer);
|
||||
}
|
||||
|
||||
static void trace_io_declarations(const struct vsir_program *program)
|
||||
{
|
||||
struct vkd3d_string_buffer buffer;
|
||||
bool empty = true;
|
||||
unsigned int i;
|
||||
|
||||
vkd3d_string_buffer_init(&buffer);
|
||||
|
||||
vkd3d_string_buffer_printf(&buffer, "Input/output declarations:");
|
||||
|
||||
for (i = 0; i < sizeof(program->io_dcls) * CHAR_BIT; ++i)
|
||||
{
|
||||
if (bitmap_is_set(program->io_dcls, i))
|
||||
{
|
||||
empty = false;
|
||||
vkd3d_string_buffer_printf(&buffer, " %u", i);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty)
|
||||
vkd3d_string_buffer_printf(&buffer, " empty");
|
||||
|
||||
TRACE("%s\n", buffer.buffer);
|
||||
|
||||
vkd3d_string_buffer_cleanup(&buffer);
|
||||
}
|
||||
|
||||
void vsir_program_trace(const struct vsir_program *program)
|
||||
{
|
||||
const unsigned int flags = VSIR_ASM_FLAG_DUMP_TYPES | VSIR_ASM_FLAG_DUMP_ALL_INDICES;
|
||||
@ -2556,6 +2583,7 @@ void vsir_program_trace(const struct vsir_program *program)
|
||||
trace_signature(&program->input_signature, "Input");
|
||||
trace_signature(&program->output_signature, "Output");
|
||||
trace_signature(&program->patch_constant_signature, "Patch-constant");
|
||||
trace_io_declarations(program);
|
||||
|
||||
if (d3d_asm_compile(program, NULL, &code, flags) != VKD3D_OK)
|
||||
return;
|
||||
|
@ -1507,12 +1507,9 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen,
|
||||
case VKD3DSIH_DCL_INDEXABLE_TEMP:
|
||||
shader_glsl_dcl_indexable_temp(gen, ins);
|
||||
break;
|
||||
case VKD3DSIH_DCL_INPUT:
|
||||
case VKD3DSIH_DCL_INPUT_PS:
|
||||
case VKD3DSIH_DCL_INPUT_PS_SGV:
|
||||
case VKD3DSIH_DCL_INPUT_PS_SIV:
|
||||
case VKD3DSIH_DCL_INPUT_SGV:
|
||||
case VKD3DSIH_DCL_OUTPUT:
|
||||
case VKD3DSIH_DCL_OUTPUT_SIV:
|
||||
case VKD3DSIH_NOP:
|
||||
break;
|
||||
|
@ -7143,6 +7143,89 @@ static enum vkd3d_result vsir_program_insert_vertex_fog(struct vsir_program *pro
|
||||
return VKD3D_OK;
|
||||
}
|
||||
|
||||
static enum vkd3d_result vsir_program_remove_io_decls(struct vsir_program *program,
|
||||
struct vsir_transformation_context *ctx)
|
||||
{
|
||||
enum vkd3d_result ret = VKD3D_OK;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < program->instructions.count; ++i)
|
||||
{
|
||||
struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
|
||||
|
||||
if (ins->opcode == VKD3DSIH_DCL_INPUT || ins->opcode == VKD3DSIH_DCL_INPUT_PS)
|
||||
{
|
||||
switch (ins->declaration.dst.reg.type)
|
||||
{
|
||||
case VKD3DSPR_INPUT:
|
||||
case VKD3DSPR_OUTPUT:
|
||||
case VKD3DSPR_PATCHCONST:
|
||||
case VKD3DSPR_INCONTROLPOINT:
|
||||
case VKD3DSPR_OUTCONTROLPOINT:
|
||||
break;
|
||||
|
||||
case VKD3DSPR_PRIMID:
|
||||
case VKD3DSPR_FORKINSTID:
|
||||
case VKD3DSPR_JOININSTID:
|
||||
case VKD3DSPR_THREADID:
|
||||
case VKD3DSPR_THREADGROUPID:
|
||||
case VKD3DSPR_LOCALTHREADID:
|
||||
case VKD3DSPR_LOCALTHREADINDEX:
|
||||
case VKD3DSPR_COVERAGE:
|
||||
case VKD3DSPR_TESSCOORD:
|
||||
case VKD3DSPR_OUTPOINTID:
|
||||
case VKD3DSPR_GSINSTID:
|
||||
case VKD3DSPR_WAVELANECOUNT:
|
||||
case VKD3DSPR_WAVELANEINDEX:
|
||||
bitmap_set(program->io_dcls, ins->declaration.dst.reg.type);
|
||||
break;
|
||||
|
||||
default:
|
||||
vkd3d_shader_error(ctx->message_context, &ins->location,
|
||||
VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
|
||||
"Internal compiler error: invalid register type %#x for input declaration.",
|
||||
ins->declaration.dst.reg.type);
|
||||
ret = VKD3D_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
vkd3d_shader_instruction_make_nop(ins);
|
||||
}
|
||||
else if (ins->opcode == VKD3DSIH_DCL_OUTPUT)
|
||||
{
|
||||
switch (ins->declaration.dst.reg.type)
|
||||
{
|
||||
case VKD3DSPR_INPUT:
|
||||
case VKD3DSPR_OUTPUT:
|
||||
case VKD3DSPR_PATCHCONST:
|
||||
case VKD3DSPR_INCONTROLPOINT:
|
||||
case VKD3DSPR_OUTCONTROLPOINT:
|
||||
break;
|
||||
|
||||
case VKD3DSPR_DEPTHOUT:
|
||||
case VKD3DSPR_SAMPLEMASK:
|
||||
case VKD3DSPR_DEPTHOUTGE:
|
||||
case VKD3DSPR_DEPTHOUTLE:
|
||||
case VKD3DSPR_OUTSTENCILREF:
|
||||
bitmap_set(program->io_dcls, ins->declaration.dst.reg.type);
|
||||
break;
|
||||
|
||||
default:
|
||||
vkd3d_shader_error(ctx->message_context, &ins->location,
|
||||
VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
|
||||
"Internal compiler error: invalid register type %#x for output declaration.",
|
||||
ins->declaration.dst.reg.type);
|
||||
ret = VKD3D_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
vkd3d_shader_instruction_make_nop(ins);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct validation_context
|
||||
{
|
||||
struct vkd3d_shader_message_context *message_context;
|
||||
@ -9139,6 +9222,41 @@ enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t c
|
||||
vsir_validate_signature(&ctx, &program->output_signature, SIGNATURE_TYPE_OUTPUT);
|
||||
vsir_validate_signature(&ctx, &program->patch_constant_signature, SIGNATURE_TYPE_PATCH_CONSTANT);
|
||||
|
||||
for (i = 0; i < sizeof(program->io_dcls) * CHAR_BIT; ++i)
|
||||
{
|
||||
if (!bitmap_is_set(program->io_dcls, i))
|
||||
continue;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
/* Input registers */
|
||||
case VKD3DSPR_PRIMID:
|
||||
case VKD3DSPR_FORKINSTID:
|
||||
case VKD3DSPR_JOININSTID:
|
||||
case VKD3DSPR_THREADID:
|
||||
case VKD3DSPR_THREADGROUPID:
|
||||
case VKD3DSPR_LOCALTHREADID:
|
||||
case VKD3DSPR_LOCALTHREADINDEX:
|
||||
case VKD3DSPR_COVERAGE:
|
||||
case VKD3DSPR_TESSCOORD:
|
||||
case VKD3DSPR_OUTPOINTID:
|
||||
case VKD3DSPR_GSINSTID:
|
||||
case VKD3DSPR_WAVELANECOUNT:
|
||||
case VKD3DSPR_WAVELANEINDEX:
|
||||
/* Output registers */
|
||||
case VKD3DSPR_DEPTHOUT:
|
||||
case VKD3DSPR_SAMPLEMASK:
|
||||
case VKD3DSPR_DEPTHOUTGE:
|
||||
case VKD3DSPR_DEPTHOUTLE:
|
||||
case VKD3DSPR_OUTSTENCILREF:
|
||||
break;
|
||||
|
||||
default:
|
||||
validator_error(&ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE,
|
||||
"Invalid input/output declaration %u.", i);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(ctx.temps = vkd3d_calloc(ctx.program->temp_count, sizeof(*ctx.temps))))
|
||||
goto fail;
|
||||
|
||||
@ -9290,6 +9408,8 @@ enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t
|
||||
vsir_transform(&ctx, vsir_program_insert_fragment_fog);
|
||||
vsir_transform(&ctx, vsir_program_insert_vertex_fog);
|
||||
|
||||
vsir_transform(&ctx, vsir_program_remove_io_decls);
|
||||
|
||||
if (TRACE_ON())
|
||||
vsir_program_trace(program);
|
||||
|
||||
|
@ -513,8 +513,6 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d
|
||||
case VKD3DSIH_AND:
|
||||
msl_binop(gen, ins, "&");
|
||||
break;
|
||||
case VKD3DSIH_DCL_INPUT:
|
||||
case VKD3DSIH_DCL_OUTPUT:
|
||||
case VKD3DSIH_DCL_OUTPUT_SIV:
|
||||
case VKD3DSIH_NOP:
|
||||
break;
|
||||
|
@ -5801,16 +5801,6 @@ static void spirv_compiler_emit_shader_epilogue_function(struct spirv_compiler *
|
||||
compiler->epilogue_function_id = 0;
|
||||
}
|
||||
|
||||
static void spirv_compiler_emit_hull_shader_builtins(struct spirv_compiler *compiler)
|
||||
{
|
||||
struct vkd3d_shader_dst_param dst;
|
||||
|
||||
memset(&dst, 0, sizeof(dst));
|
||||
vsir_register_init(&dst.reg, VKD3DSPR_OUTPOINTID, VKD3D_DATA_FLOAT, 0);
|
||||
dst.write_mask = VKD3DSP_WRITEMASK_0;
|
||||
spirv_compiler_emit_io_register(compiler, &dst);
|
||||
}
|
||||
|
||||
static void spirv_compiler_emit_initial_declarations(struct spirv_compiler *compiler)
|
||||
{
|
||||
const struct vkd3d_shader_transform_feedback_info *xfb_info = compiler->xfb_info;
|
||||
@ -5823,7 +5813,6 @@ static void spirv_compiler_emit_initial_declarations(struct spirv_compiler *comp
|
||||
break;
|
||||
case VKD3D_SHADER_TYPE_HULL:
|
||||
vkd3d_spirv_set_execution_model(builder, SpvExecutionModelTessellationControl);
|
||||
spirv_compiler_emit_hull_shader_builtins(compiler);
|
||||
break;
|
||||
case VKD3D_SHADER_TYPE_DOMAIN:
|
||||
vkd3d_spirv_set_execution_model(builder, SpvExecutionModelTessellationEvaluation);
|
||||
@ -6643,27 +6632,6 @@ static void spirv_compiler_emit_dcl_tgsm_structured(struct spirv_compiler *compi
|
||||
tgsm_structured->structure_count * stride, stride, tgsm_structured->zero_init);
|
||||
}
|
||||
|
||||
static void spirv_compiler_emit_dcl_input(struct spirv_compiler *compiler,
|
||||
const struct vkd3d_shader_instruction *instruction)
|
||||
{
|
||||
const struct vkd3d_shader_dst_param *dst = &instruction->declaration.dst;
|
||||
|
||||
/* INPUT and PATCHCONST are handled in spirv_compiler_emit_io_declarations().
|
||||
* OUTPOINTID is handled in spirv_compiler_emit_hull_shader_builtins(). */
|
||||
if (dst->reg.type != VKD3DSPR_INPUT && dst->reg.type != VKD3DSPR_PATCHCONST
|
||||
&& dst->reg.type != VKD3DSPR_OUTPOINTID)
|
||||
spirv_compiler_emit_io_register(compiler, dst);
|
||||
}
|
||||
|
||||
static void spirv_compiler_emit_dcl_output(struct spirv_compiler *compiler,
|
||||
const struct vkd3d_shader_instruction *instruction)
|
||||
{
|
||||
const struct vkd3d_shader_dst_param *dst = &instruction->declaration.dst;
|
||||
|
||||
if (dst->reg.type != VKD3DSPR_OUTPUT && dst->reg.type != VKD3DSPR_PATCHCONST)
|
||||
spirv_compiler_emit_io_register(compiler, dst);
|
||||
}
|
||||
|
||||
static void spirv_compiler_emit_dcl_stream(struct spirv_compiler *compiler,
|
||||
const struct vkd3d_shader_instruction *instruction)
|
||||
{
|
||||
@ -10089,13 +10057,6 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler,
|
||||
case VKD3DSIH_DCL_TGSM_STRUCTURED:
|
||||
spirv_compiler_emit_dcl_tgsm_structured(compiler, instruction);
|
||||
break;
|
||||
case VKD3DSIH_DCL_INPUT_PS:
|
||||
case VKD3DSIH_DCL_INPUT:
|
||||
spirv_compiler_emit_dcl_input(compiler, instruction);
|
||||
break;
|
||||
case VKD3DSIH_DCL_OUTPUT:
|
||||
spirv_compiler_emit_dcl_output(compiler, instruction);
|
||||
break;
|
||||
case VKD3DSIH_DCL_STREAM:
|
||||
spirv_compiler_emit_dcl_stream(compiler, instruction);
|
||||
break;
|
||||
@ -10458,6 +10419,8 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler,
|
||||
|
||||
static void spirv_compiler_emit_io_declarations(struct spirv_compiler *compiler)
|
||||
{
|
||||
struct vkd3d_shader_dst_param dst;
|
||||
|
||||
for (unsigned int i = 0; i < compiler->input_signature.element_count; ++i)
|
||||
spirv_compiler_emit_input(compiler, VKD3DSPR_INPUT, i);
|
||||
|
||||
@ -10481,8 +10444,6 @@ static void spirv_compiler_emit_io_declarations(struct spirv_compiler *compiler)
|
||||
|
||||
if (compiler->program->has_point_size)
|
||||
{
|
||||
struct vkd3d_shader_dst_param dst;
|
||||
|
||||
vsir_dst_param_init(&dst, VKD3DSPR_RASTOUT, VKD3D_DATA_FLOAT, 1);
|
||||
dst.reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE;
|
||||
spirv_compiler_emit_io_register(compiler, &dst);
|
||||
@ -10490,11 +10451,21 @@ static void spirv_compiler_emit_io_declarations(struct spirv_compiler *compiler)
|
||||
|
||||
if (compiler->program->has_point_coord)
|
||||
{
|
||||
struct vkd3d_shader_dst_param dst;
|
||||
|
||||
vsir_dst_param_init(&dst, VKD3DSPR_POINT_COORD, VKD3D_DATA_FLOAT, 0);
|
||||
spirv_compiler_emit_io_register(compiler, &dst);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < sizeof(compiler->program->io_dcls) * CHAR_BIT; ++i)
|
||||
{
|
||||
/* For hull shaders we internally generate references to OUTPOINTID,
|
||||
* so that must always be enabled. */
|
||||
if (bitmap_is_set(compiler->program->io_dcls, i)
|
||||
|| (compiler->program->shader_version.type == VKD3D_SHADER_TYPE_HULL && i == VKD3DSPR_OUTPOINTID))
|
||||
{
|
||||
vsir_dst_param_init(&dst, i, VKD3D_DATA_FLOAT, 0);
|
||||
spirv_compiler_emit_io_register(compiler, &dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void spirv_compiler_emit_descriptor_declarations(struct spirv_compiler *compiler)
|
||||
|
@ -1433,6 +1433,7 @@ struct vsir_program
|
||||
enum vsir_control_flow_type cf_type;
|
||||
enum vsir_normalisation_level normalisation_level;
|
||||
enum vkd3d_tessellator_domain tess_domain;
|
||||
uint32_t io_dcls[VKD3D_BITMAP_SIZE(VKD3DSPR_COUNT)];
|
||||
|
||||
const char **block_names;
|
||||
size_t block_name_count;
|
||||
|
Loading…
x
Reference in New Issue
Block a user