diff --git a/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d-shader/d3d_asm.c index 7c5444f6..f008770a 100644 --- a/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d-shader/d3d_asm.c @@ -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; diff --git a/libs/vkd3d-shader/glsl.c b/libs/vkd3d-shader/glsl.c index 0df0e30f..ad834613 100644 --- a/libs/vkd3d-shader/glsl.c +++ b/libs/vkd3d-shader/glsl.c @@ -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; diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index 53b26dac..8a8fe6a7 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -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); diff --git a/libs/vkd3d-shader/msl.c b/libs/vkd3d-shader/msl.c index 9a3c3ed8..76eaef47 100644 --- a/libs/vkd3d-shader/msl.c +++ b/libs/vkd3d-shader/msl.c @@ -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; diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 2765997c..cac76e69 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -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) diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 4c9795e4..09e0e66c 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -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;