shader_recompiler: Separate vertex inputs from LS stage, cleanup tess

This commit is contained in:
IndecisiveTurtle 2025-07-13 20:53:25 +03:00
parent b16b9a1544
commit dde954a3cb
6 changed files with 48 additions and 48 deletions

View File

@ -52,7 +52,7 @@ Id VsOutputAttrPointer(EmitContext& ctx, VsOutput output) {
Id OutputAttrPointer(EmitContext& ctx, IR::Attribute attr, u32 element) {
if (IR::IsParam(attr)) {
const u32 attr_index{u32(attr) - u32(IR::Attribute::Param0)};
if (ctx.stage == Stage::Local && ctx.runtime_info.ls_info.links_with_tcs) {
if (ctx.stage == Stage::Local) {
const auto component_ptr = ctx.TypePointer(spv::StorageClass::Output, ctx.F32[1]);
return ctx.OpAccessChain(component_ptr, ctx.output_attr_array, ctx.ConstU32(attr_index),
ctx.ConstU32(element));
@ -94,14 +94,10 @@ Id OutputAttrPointer(EmitContext& ctx, IR::Attribute attr, u32 element) {
std::pair<Id, bool> OutputAttrComponentType(EmitContext& ctx, IR::Attribute attr) {
if (IR::IsParam(attr)) {
if (ctx.stage == Stage::Local && ctx.runtime_info.ls_info.links_with_tcs) {
return {ctx.F32[1], false};
} else {
const u32 index{u32(attr) - u32(IR::Attribute::Param0)};
const auto& info{ctx.output_params.at(index)};
return {info.component_type, info.is_integer};
}
}
if (IR::IsMrt(attr)) {
const u32 index{u32(attr) - u32(IR::Attribute::RenderTarget0)};
const auto& info{ctx.frag_outputs.at(index)};

View File

@ -551,7 +551,7 @@ void EmitContext::DefineOutputs() {
cull_distances =
DefineVariable(type, spv::BuiltIn::CullDistance, spv::StorageClass::Output);
}
if (stage == Shader::Stage::Local && runtime_info.ls_info.links_with_tcs) {
if (stage == Stage::Local) {
const u32 num_attrs = Common::AlignUp(runtime_info.ls_info.ls_stride, 16) >> 4;
if (num_attrs > 0) {
const Id type{TypeArray(F32[4], ConstU32(num_attrs))};
@ -737,19 +737,19 @@ EmitContext::BufferSpv EmitContext::DefineBuffer(bool is_storage, bool is_writte
Decorate(id, spv::Decoration::NonWritable);
}
switch (buffer_type) {
case Shader::BufferType::GdsBuffer:
case BufferType::GdsBuffer:
Name(id, "gds_buffer");
break;
case Shader::BufferType::Flatbuf:
case BufferType::Flatbuf:
Name(id, "srt_flatbuf");
break;
case Shader::BufferType::BdaPagetable:
case BufferType::BdaPagetable:
Name(id, "bda_pagetable");
break;
case Shader::BufferType::FaultBuffer:
case BufferType::FaultBuffer:
Name(id, "fault_buffer");
break;
case Shader::BufferType::SharedMemory:
case BufferType::SharedMemory:
Name(id, "ssbo_shmem");
break;
default:

View File

@ -90,10 +90,21 @@ void Translator::EmitPrologue(IR::Block* first_block) {
case LogicalStage::Vertex:
// v0: vertex ID, always present
ir.SetVectorReg(dst_vreg++, ir.GetAttributeU32(IR::Attribute::VertexId));
if (info.stage == Stage::Local) {
// v1: rel patch ID
if (runtime_info.num_input_vgprs > 0) {
ir.SetVectorReg(dst_vreg++, ir.Imm32(0));
}
// v2: instance ID
if (runtime_info.num_input_vgprs > 1) {
ir.SetVectorReg(dst_vreg++, ir.GetAttributeU32(IR::Attribute::InstanceId));
}
} else {
// v1: instance ID, step rate 0
if (runtime_info.num_input_vgprs > 0) {
if (runtime_info.vs_info.step_rate_0 != 0) {
ir.SetVectorReg(dst_vreg++, ir.IDiv(ir.GetAttributeU32(IR::Attribute::InstanceId),
ir.SetVectorReg(dst_vreg++,
ir.IDiv(ir.GetAttributeU32(IR::Attribute::InstanceId),
ir.Imm32(runtime_info.vs_info.step_rate_0)));
} else {
ir.SetVectorReg(dst_vreg++, ir.Imm32(0));
@ -102,7 +113,8 @@ void Translator::EmitPrologue(IR::Block* first_block) {
// v2: instance ID, step rate 1
if (runtime_info.num_input_vgprs > 1) {
if (runtime_info.vs_info.step_rate_1 != 0) {
ir.SetVectorReg(dst_vreg++, ir.IDiv(ir.GetAttributeU32(IR::Attribute::InstanceId),
ir.SetVectorReg(dst_vreg++,
ir.IDiv(ir.GetAttributeU32(IR::Attribute::InstanceId),
ir.Imm32(runtime_info.vs_info.step_rate_1)));
} else {
ir.SetVectorReg(dst_vreg++, ir.Imm32(0));
@ -112,6 +124,7 @@ void Translator::EmitPrologue(IR::Block* first_block) {
if (runtime_info.num_input_vgprs > 2) {
ir.SetVectorReg(dst_vreg++, ir.GetAttributeU32(IR::Attribute::InstanceId));
}
}
break;
case LogicalStage::Fragment:
dst_vreg = dst_frag_vreg;

View File

@ -33,12 +33,9 @@ void RingAccessElimination(const IR::Program& program, const RuntimeInfo& runtim
bool is_composite = opcode == IR::Opcode::WriteSharedU64;
u32 num_components = opcode == IR::Opcode::WriteSharedU32 ? 1 : 2;
u32 offset = 0;
const auto* addr = inst.Arg(0).InstRecursive();
if (addr->GetOpcode() == IR::Opcode::IAdd32) {
ASSERT(addr->Arg(1).IsImmediate());
offset = addr->Arg(1).U32();
}
ASSERT(inst.Arg(0).IsImmediate());
u32 offset = inst.Arg(0).U32();
IR::Value data = is_composite ? ir.UnpackUint2x32(IR::U64{inst.Arg(1).Resolve()})
: inst.Arg(1).Resolve();
for (s32 i = 0; i < num_components; i++) {

View File

@ -42,7 +42,6 @@ constexpr u32 MaxStageTypes = static_cast<u32>(LogicalStage::NumLogicalStages);
struct LocalRuntimeInfo {
u32 ls_stride;
bool links_with_tcs;
auto operator<=>(const LocalRuntimeInfo&) const noexcept = default;
};

View File

@ -94,15 +94,10 @@ const Shader::RuntimeInfo& PipelineCache::BuildRuntimeInfo(Stage stage, LogicalS
switch (stage) {
case Stage::Local: {
BuildCommon(regs.ls_program);
if (regs.stage_enable.IsStageEnabled(static_cast<u32>(Stage::Hull))) {
info.ls_info.links_with_tcs = true;
Shader::TessellationDataConstantBuffer tess_constants;
const auto* pgm = regs.ProgramForStage(static_cast<u32>(Stage::Hull));
const auto params = Liverpool::GetParams(*pgm);
const auto& hull_info = program_cache.at(params.hash)->info;
hull_info.ReadTessConstantBuffer(tess_constants);
const auto* hull_info = infos[u32(Shader::LogicalStage::TessellationControl)];
hull_info->ReadTessConstantBuffer(tess_constants);
info.ls_info.ls_stride = tess_constants.ls_stride;
}
break;
}
case Stage::Hull: {