mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-22 18:15:14 +00:00
shader_recompiler: Separate vertex inputs from LS stage, cleanup tess
This commit is contained in:
parent
b16b9a1544
commit
dde954a3cb
@ -52,7 +52,7 @@ Id VsOutputAttrPointer(EmitContext& ctx, VsOutput output) {
|
|||||||
Id OutputAttrPointer(EmitContext& ctx, IR::Attribute attr, u32 element) {
|
Id OutputAttrPointer(EmitContext& ctx, IR::Attribute attr, u32 element) {
|
||||||
if (IR::IsParam(attr)) {
|
if (IR::IsParam(attr)) {
|
||||||
const u32 attr_index{u32(attr) - u32(IR::Attribute::Param0)};
|
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]);
|
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),
|
return ctx.OpAccessChain(component_ptr, ctx.output_attr_array, ctx.ConstU32(attr_index),
|
||||||
ctx.ConstU32(element));
|
ctx.ConstU32(element));
|
||||||
@ -94,13 +94,9 @@ Id OutputAttrPointer(EmitContext& ctx, IR::Attribute attr, u32 element) {
|
|||||||
|
|
||||||
std::pair<Id, bool> OutputAttrComponentType(EmitContext& ctx, IR::Attribute attr) {
|
std::pair<Id, bool> OutputAttrComponentType(EmitContext& ctx, IR::Attribute attr) {
|
||||||
if (IR::IsParam(attr)) {
|
if (IR::IsParam(attr)) {
|
||||||
if (ctx.stage == Stage::Local && ctx.runtime_info.ls_info.links_with_tcs) {
|
const u32 index{u32(attr) - u32(IR::Attribute::Param0)};
|
||||||
return {ctx.F32[1], false};
|
const auto& info{ctx.output_params.at(index)};
|
||||||
} else {
|
return {info.component_type, info.is_integer};
|
||||||
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)) {
|
if (IR::IsMrt(attr)) {
|
||||||
const u32 index{u32(attr) - u32(IR::Attribute::RenderTarget0)};
|
const u32 index{u32(attr) - u32(IR::Attribute::RenderTarget0)};
|
||||||
|
@ -551,7 +551,7 @@ void EmitContext::DefineOutputs() {
|
|||||||
cull_distances =
|
cull_distances =
|
||||||
DefineVariable(type, spv::BuiltIn::CullDistance, spv::StorageClass::Output);
|
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;
|
const u32 num_attrs = Common::AlignUp(runtime_info.ls_info.ls_stride, 16) >> 4;
|
||||||
if (num_attrs > 0) {
|
if (num_attrs > 0) {
|
||||||
const Id type{TypeArray(F32[4], ConstU32(num_attrs))};
|
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);
|
Decorate(id, spv::Decoration::NonWritable);
|
||||||
}
|
}
|
||||||
switch (buffer_type) {
|
switch (buffer_type) {
|
||||||
case Shader::BufferType::GdsBuffer:
|
case BufferType::GdsBuffer:
|
||||||
Name(id, "gds_buffer");
|
Name(id, "gds_buffer");
|
||||||
break;
|
break;
|
||||||
case Shader::BufferType::Flatbuf:
|
case BufferType::Flatbuf:
|
||||||
Name(id, "srt_flatbuf");
|
Name(id, "srt_flatbuf");
|
||||||
break;
|
break;
|
||||||
case Shader::BufferType::BdaPagetable:
|
case BufferType::BdaPagetable:
|
||||||
Name(id, "bda_pagetable");
|
Name(id, "bda_pagetable");
|
||||||
break;
|
break;
|
||||||
case Shader::BufferType::FaultBuffer:
|
case BufferType::FaultBuffer:
|
||||||
Name(id, "fault_buffer");
|
Name(id, "fault_buffer");
|
||||||
break;
|
break;
|
||||||
case Shader::BufferType::SharedMemory:
|
case BufferType::SharedMemory:
|
||||||
Name(id, "ssbo_shmem");
|
Name(id, "ssbo_shmem");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -90,27 +90,40 @@ void Translator::EmitPrologue(IR::Block* first_block) {
|
|||||||
case LogicalStage::Vertex:
|
case LogicalStage::Vertex:
|
||||||
// v0: vertex ID, always present
|
// v0: vertex ID, always present
|
||||||
ir.SetVectorReg(dst_vreg++, ir.GetAttributeU32(IR::Attribute::VertexId));
|
ir.SetVectorReg(dst_vreg++, ir.GetAttributeU32(IR::Attribute::VertexId));
|
||||||
// v1: instance ID, step rate 0
|
if (info.stage == Stage::Local) {
|
||||||
if (runtime_info.num_input_vgprs > 0) {
|
// v1: rel patch ID
|
||||||
if (runtime_info.vs_info.step_rate_0 != 0) {
|
if (runtime_info.num_input_vgprs > 0) {
|
||||||
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));
|
ir.SetVectorReg(dst_vreg++, ir.Imm32(0));
|
||||||
}
|
}
|
||||||
}
|
// v2: instance ID
|
||||||
// v2: instance ID, step rate 1
|
if (runtime_info.num_input_vgprs > 1) {
|
||||||
if (runtime_info.num_input_vgprs > 1) {
|
ir.SetVectorReg(dst_vreg++, ir.GetAttributeU32(IR::Attribute::InstanceId));
|
||||||
if (runtime_info.vs_info.step_rate_1 != 0) {
|
}
|
||||||
ir.SetVectorReg(dst_vreg++, ir.IDiv(ir.GetAttributeU32(IR::Attribute::InstanceId),
|
} else {
|
||||||
ir.Imm32(runtime_info.vs_info.step_rate_1)));
|
// v1: instance ID, step rate 0
|
||||||
} else {
|
if (runtime_info.num_input_vgprs > 0) {
|
||||||
ir.SetVectorReg(dst_vreg++, ir.Imm32(0));
|
if (runtime_info.vs_info.step_rate_0 != 0) {
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 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.Imm32(runtime_info.vs_info.step_rate_1)));
|
||||||
|
} else {
|
||||||
|
ir.SetVectorReg(dst_vreg++, ir.Imm32(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// v3: instance ID, plain
|
||||||
|
if (runtime_info.num_input_vgprs > 2) {
|
||||||
|
ir.SetVectorReg(dst_vreg++, ir.GetAttributeU32(IR::Attribute::InstanceId));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// v3: instance ID, plain
|
|
||||||
if (runtime_info.num_input_vgprs > 2) {
|
|
||||||
ir.SetVectorReg(dst_vreg++, ir.GetAttributeU32(IR::Attribute::InstanceId));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LogicalStage::Fragment:
|
case LogicalStage::Fragment:
|
||||||
|
@ -33,12 +33,9 @@ void RingAccessElimination(const IR::Program& program, const RuntimeInfo& runtim
|
|||||||
bool is_composite = opcode == IR::Opcode::WriteSharedU64;
|
bool is_composite = opcode == IR::Opcode::WriteSharedU64;
|
||||||
u32 num_components = opcode == IR::Opcode::WriteSharedU32 ? 1 : 2;
|
u32 num_components = opcode == IR::Opcode::WriteSharedU32 ? 1 : 2;
|
||||||
|
|
||||||
u32 offset = 0;
|
ASSERT(inst.Arg(0).IsImmediate());
|
||||||
const auto* addr = inst.Arg(0).InstRecursive();
|
|
||||||
if (addr->GetOpcode() == IR::Opcode::IAdd32) {
|
u32 offset = inst.Arg(0).U32();
|
||||||
ASSERT(addr->Arg(1).IsImmediate());
|
|
||||||
offset = addr->Arg(1).U32();
|
|
||||||
}
|
|
||||||
IR::Value data = is_composite ? ir.UnpackUint2x32(IR::U64{inst.Arg(1).Resolve()})
|
IR::Value data = is_composite ? ir.UnpackUint2x32(IR::U64{inst.Arg(1).Resolve()})
|
||||||
: inst.Arg(1).Resolve();
|
: inst.Arg(1).Resolve();
|
||||||
for (s32 i = 0; i < num_components; i++) {
|
for (s32 i = 0; i < num_components; i++) {
|
||||||
|
@ -42,7 +42,6 @@ constexpr u32 MaxStageTypes = static_cast<u32>(LogicalStage::NumLogicalStages);
|
|||||||
|
|
||||||
struct LocalRuntimeInfo {
|
struct LocalRuntimeInfo {
|
||||||
u32 ls_stride;
|
u32 ls_stride;
|
||||||
bool links_with_tcs;
|
|
||||||
|
|
||||||
auto operator<=>(const LocalRuntimeInfo&) const noexcept = default;
|
auto operator<=>(const LocalRuntimeInfo&) const noexcept = default;
|
||||||
};
|
};
|
||||||
|
@ -94,15 +94,10 @@ const Shader::RuntimeInfo& PipelineCache::BuildRuntimeInfo(Stage stage, LogicalS
|
|||||||
switch (stage) {
|
switch (stage) {
|
||||||
case Stage::Local: {
|
case Stage::Local: {
|
||||||
BuildCommon(regs.ls_program);
|
BuildCommon(regs.ls_program);
|
||||||
if (regs.stage_enable.IsStageEnabled(static_cast<u32>(Stage::Hull))) {
|
Shader::TessellationDataConstantBuffer tess_constants;
|
||||||
info.ls_info.links_with_tcs = true;
|
const auto* hull_info = infos[u32(Shader::LogicalStage::TessellationControl)];
|
||||||
Shader::TessellationDataConstantBuffer tess_constants;
|
hull_info->ReadTessConstantBuffer(tess_constants);
|
||||||
const auto* pgm = regs.ProgramForStage(static_cast<u32>(Stage::Hull));
|
info.ls_info.ls_stride = tess_constants.ls_stride;
|
||||||
const auto params = Liverpool::GetParams(*pgm);
|
|
||||||
const auto& hull_info = program_cache.at(params.hash)->info;
|
|
||||||
hull_info.ReadTessConstantBuffer(tess_constants);
|
|
||||||
info.ls_info.ls_stride = tess_constants.ls_stride;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Stage::Hull: {
|
case Stage::Hull: {
|
||||||
|
Loading…
Reference in New Issue
Block a user