mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 10:56:58 +02:00
perf(shader): cache analysis (#259)
perf(shader): cache SPIR-V requirement analysis Co-authored-by: nmzik <Nmzik@mail.ru>
This commit is contained in:
@@ -88,161 +88,6 @@ uint32_t OutputVariableForExport(const EmitterState& state, const IR::ExportInfo
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ProgramNeedsComputeDerivatives(const IR::Program& program) {
|
||||
if (program.values == nullptr) {
|
||||
return false;
|
||||
}
|
||||
for (const auto* block: program.values->blocks) {
|
||||
for (const auto& inst: *block) {
|
||||
if (inst.GetOpcode() == IR::ValueOpcode::ImageQueryLod) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ProgramNeedsImageGatherExtended(const IR::Program& program) {
|
||||
if (program.values == nullptr) {
|
||||
return false;
|
||||
}
|
||||
for (const auto* block: program.values->blocks) {
|
||||
for (const auto& inst: *block) {
|
||||
if (inst.GetOpcode() == IR::ValueOpcode::ImageGatherRaw) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ProgramNeedsFunctionLds(const IR::Program& program) {
|
||||
if (program.stage == ShaderType::Compute || program.values == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto* block: program.values->blocks) {
|
||||
for (const auto& inst: *block) {
|
||||
switch (inst.GetOpcode()) {
|
||||
case IR::ValueOpcode::SwizzleU32: return true;
|
||||
case IR::ValueOpcode::LoadSharedU8:
|
||||
case IR::ValueOpcode::LoadSharedU16:
|
||||
case IR::ValueOpcode::LoadSharedU32:
|
||||
case IR::ValueOpcode::WriteSharedU8:
|
||||
case IR::ValueOpcode::WriteSharedU16:
|
||||
case IR::ValueOpcode::WriteSharedU32:
|
||||
case IR::ValueOpcode::SharedAtomicFMin32:
|
||||
case IR::ValueOpcode::SharedAtomicFMax32:
|
||||
case IR::ValueOpcode::SharedAtomicSwap32:
|
||||
case IR::ValueOpcode::SharedAtomicIAdd32:
|
||||
case IR::ValueOpcode::SharedAtomicISub32:
|
||||
case IR::ValueOpcode::SharedAtomicSMin32:
|
||||
case IR::ValueOpcode::SharedAtomicUMin32:
|
||||
case IR::ValueOpcode::SharedAtomicSMax32:
|
||||
case IR::ValueOpcode::SharedAtomicUMax32:
|
||||
case IR::ValueOpcode::SharedAtomicAnd32:
|
||||
case IR::ValueOpcode::SharedAtomicOr32:
|
||||
case IR::ValueOpcode::SharedAtomicXor32:
|
||||
case IR::ValueOpcode::DataAppend:
|
||||
case IR::ValueOpcode::DataConsume: {
|
||||
const auto index = inst.Flags<IR::MemoryFlags>().index;
|
||||
if (index < program.values->memory_info.size() &&
|
||||
program.values->memory_info[index].kind == IR::ResourceKind::Lds) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ProgramNeedsPixelValidMask(const IR::Program& program) {
|
||||
if (program.stage != ShaderType::Pixel || program.values == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto* block: program.values->blocks) {
|
||||
for (const auto& inst: *block) {
|
||||
if (inst.GetOpcode() != IR::ValueOpcode::SetAttribute) {
|
||||
continue;
|
||||
}
|
||||
const auto index = inst.Flags<IR::ExportFlags>().index;
|
||||
if (index < program.values->export_info.size() &&
|
||||
program.values->export_info[index].vm) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ProgramNeedsSubgroupBallot(const IR::Program& program) {
|
||||
if (program.values == nullptr) {
|
||||
return false;
|
||||
}
|
||||
if (program.lane_mask_mode == ShaderLaneMaskMode::PerInvocation) {
|
||||
for (const auto* block: program.values->blocks) {
|
||||
for (const auto& inst: *block) {
|
||||
if (inst.GetOpcode() == IR::ValueOpcode::WqmMask) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ProgramRequiresExactSubgroupSize(program);
|
||||
}
|
||||
|
||||
bool ProgramNeedsSubgroupShuffle(const IR::Program& program) {
|
||||
if (program.values == nullptr) {
|
||||
return false;
|
||||
}
|
||||
for (const auto* block: program.values->blocks) {
|
||||
for (const auto& inst: *block) {
|
||||
switch (inst.GetOpcode()) {
|
||||
case IR::ValueOpcode::DppMoveU32:
|
||||
case IR::ValueOpcode::ReadFirstLane:
|
||||
case IR::ValueOpcode::ReadLane:
|
||||
case IR::ValueOpcode::Permlane16U32:
|
||||
case IR::ValueOpcode::DataAppend:
|
||||
case IR::ValueOpcode::DataConsume:
|
||||
case IR::ValueOpcode::GdsDataAppend:
|
||||
case IR::ValueOpcode::GdsDataConsume:
|
||||
case IR::ValueOpcode::SwizzleU32: return true;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ProgramNeedsSubgroupLocalInvocationId(const IR::Program& program) {
|
||||
if (program.values == nullptr) {
|
||||
return false;
|
||||
}
|
||||
for (const auto* block: program.values->blocks) {
|
||||
for (const auto& inst: *block) {
|
||||
switch (inst.GetOpcode()) {
|
||||
case IR::ValueOpcode::DppMoveU32:
|
||||
case IR::ValueOpcode::DppUpdateU32:
|
||||
case IR::ValueOpcode::WqmMask:
|
||||
case IR::ValueOpcode::LaneId:
|
||||
case IR::ValueOpcode::WriteLane:
|
||||
case IR::ValueOpcode::Permlane16U32:
|
||||
case IR::ValueOpcode::DataAppend:
|
||||
case IR::ValueOpcode::DataConsume:
|
||||
case IR::ValueOpcode::GdsDataAppend:
|
||||
case IR::ValueOpcode::GdsDataConsume:
|
||||
case IR::ValueOpcode::SwizzleU32: return true;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t PointerForRegister(const EmitterState& state, IR::Register reg) {
|
||||
for (const auto& binding: state.registers) {
|
||||
if (binding.reg == reg) {
|
||||
|
||||
Reference in New Issue
Block a user