mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-29 08:41:20 +00:00
shader_recompiler: add SSA
This commit is contained in:
1 parent
bc2f077c37
commit
b42380ced6
113 files changed
+40415
-32616
No files matched your search
+576
-1891
File diff suppressed because it is too large.
Load diff
+356
-1167
File diff suppressed because it is too large.
Load diff
+18274
-16889
File diff suppressed because it is too large.
Load diff
@@ -1,5 +1,5 @@
|
||||
#include "graphics/shader/recompiler/ir/ResourceMaterialization.h"
|
||||
#include "graphics/shader/recompiler/ir/ShaderIR.h"
|
||||
#include "graphics/shader/recompiler/ir/passes/ResourceMaterialization.h"
|
||||
#include "graphics/shader/recompiler/ir/ValueProgram.h"
|
||||
#include "graphics/shader/shader.h"
|
||||
|
||||
#include <cstdio>
|
||||
@@ -8,81 +8,128 @@
|
||||
|
||||
namespace {
|
||||
|
||||
void Check(bool value, const char* text) {
|
||||
if (!value) {
|
||||
std::fprintf(stderr, "ShaderStageRuntimeTests: failed: %s\n", text);
|
||||
std::abort();
|
||||
}
|
||||
void Check(bool value, const char *text) {
|
||||
if (!value) {
|
||||
std::fprintf(stderr, "ShaderStageRuntimeTests: failed: %s\n", text);
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<const Libs::Graphics::ShaderRecompiler::IR::Program> SrtProgram(uint64_t address) {
|
||||
using namespace Libs::Graphics::ShaderRecompiler::IR;
|
||||
Program program;
|
||||
program.stage = Libs::Graphics::ShaderType::Compute;
|
||||
program.srt_plan_complete = true;
|
||||
program.srt_patching_complete = true;
|
||||
program.resource_tracking_complete = true;
|
||||
program.provenance.values.resize(6);
|
||||
program.provenance.values[0].op = ScalarValueOp::Undefined;
|
||||
program.provenance.values[1].op = ScalarValueOp::Unknown;
|
||||
program.provenance.values[2].op = ScalarValueOp::Constant;
|
||||
program.provenance.values[2].imm = static_cast<uint32_t>(address);
|
||||
program.provenance.values[3].op = ScalarValueOp::Constant;
|
||||
program.provenance.values[3].imm = static_cast<uint32_t>(address >> 32u);
|
||||
program.provenance.values[4].op = ScalarValueOp::Constant;
|
||||
program.provenance.values[5].op = ScalarValueOp::ReadConst;
|
||||
program.provenance.values[5].args = {2, 3, 4};
|
||||
program.srt.reads.push_back({5, 0, 0x40});
|
||||
return std::make_shared<const Program>(std::move(program));
|
||||
Libs::Graphics::ShaderRecompiler::IR::Block &
|
||||
AddValueBlock(Libs::Graphics::ShaderRecompiler::IR::Program &program) {
|
||||
using namespace Libs::Graphics::ShaderRecompiler::IR;
|
||||
program.values = std::make_shared<ValueProgram>();
|
||||
auto block = std::make_unique<Block>();
|
||||
auto *result = block.get();
|
||||
program.values->blocks.push_back(result);
|
||||
program.values->block_info.push_back({.id = 0});
|
||||
program.values->block_storage.push_back(std::move(block));
|
||||
return *result;
|
||||
}
|
||||
|
||||
std::shared_ptr<const Libs::Graphics::ShaderRecompiler::IR::Program> UnbasedFlatProgram() {
|
||||
using namespace Libs::Graphics::ShaderRecompiler::IR;
|
||||
Program program;
|
||||
program.stage = Libs::Graphics::ShaderType::Compute;
|
||||
program.srt_plan_complete = true;
|
||||
program.srt_patching_complete = true;
|
||||
program.resource_tracking_complete = true;
|
||||
AddressResource address;
|
||||
address.source = ScalarProvenance::Unknown;
|
||||
address.first_use_pc = 0x80;
|
||||
address.kind = ResourceKind::Flat;
|
||||
program.info.addresses.push_back(address);
|
||||
return std::make_shared<const Program>(std::move(program));
|
||||
std::shared_ptr<const Libs::Graphics::ShaderRecompiler::IR::Program>
|
||||
SrtProgram(uint64_t address) {
|
||||
using namespace Libs::Graphics::ShaderRecompiler::IR;
|
||||
Program program;
|
||||
program.stage = Libs::Graphics::ShaderType::Compute;
|
||||
program.srt_plan_complete = true;
|
||||
program.resource_tracking_complete = true;
|
||||
auto &value_block = AddValueBlock(program);
|
||||
|
||||
MemoryInfo memory;
|
||||
memory.kind = ResourceKind::ScalarBuffer;
|
||||
memory.planning_only = true;
|
||||
program.values->memory_info.push_back(memory);
|
||||
const auto low = Value(static_cast<uint32_t>(address));
|
||||
const auto high = Value(static_cast<uint32_t>(address >> 32u));
|
||||
auto &handle =
|
||||
value_block.AppendNewInst(ValueOpcode::GetAddressResource, {low, high});
|
||||
auto &raw = value_block.AppendNewInst(
|
||||
ValueOpcode::LoadAddressU32,
|
||||
{Value(&handle), Value(0u), Value(0u), Value(true)});
|
||||
raw.SetFlags(MemoryFlags{.index = 0, .pc = 0x40});
|
||||
program.values->srt_reads.push_back({Value(&raw), 0, 0x40});
|
||||
|
||||
auto &srt = value_block.AppendNewInst(ValueOpcode::GetSrtResource);
|
||||
auto &flat = value_block.AppendNewInst(ValueOpcode::ReadConst,
|
||||
{Value(&srt), Value(0u)});
|
||||
DescriptorSource source;
|
||||
source.dwords[0] = Value(&flat);
|
||||
source.dwords[1] = Value(0u);
|
||||
source.dword_count = 2;
|
||||
program.values->descriptor_sources.push_back(source);
|
||||
return std::make_shared<const Program>(std::move(program));
|
||||
}
|
||||
|
||||
std::shared_ptr<const Libs::Graphics::ShaderRecompiler::IR::Program>
|
||||
UnbasedFlatProgram() {
|
||||
using namespace Libs::Graphics::ShaderRecompiler::IR;
|
||||
Program program;
|
||||
program.stage = Libs::Graphics::ShaderType::Compute;
|
||||
program.srt_plan_complete = true;
|
||||
program.resource_tracking_complete = true;
|
||||
AddValueBlock(program);
|
||||
AddressResource address;
|
||||
address.source = UINT32_MAX;
|
||||
address.first_use_pc = 0x80;
|
||||
address.kind = ResourceKind::Flat;
|
||||
address.unbased = true;
|
||||
program.info.addresses.push_back(address);
|
||||
return std::make_shared<const Program>(std::move(program));
|
||||
}
|
||||
|
||||
void TestMappedSrtUsesDirectReaderByDefault() {
|
||||
using namespace Libs::Graphics;
|
||||
const uint32_t dword = 0x12345678;
|
||||
auto cached_program = SrtProgram(reinterpret_cast<uint64_t>(&dword));
|
||||
ShaderStageRuntime stage;
|
||||
std::string error;
|
||||
Check(ShaderMaterializeStageRuntime(cached_program, {}, 0, stage, &error), error.c_str());
|
||||
Check(stage.program == cached_program && stage.resources != nullptr,
|
||||
"cache rematerialization did not publish the mapped stage");
|
||||
Check(stage.resources->flattened_srt.size() == 1 && stage.resources->flattened_srt[0] == dword,
|
||||
"cache rematerialization did not use the direct reader by default");
|
||||
using namespace Libs::Graphics;
|
||||
const uint32_t dword = 0x12345678;
|
||||
auto cached_program = SrtProgram(reinterpret_cast<uint64_t>(&dword));
|
||||
ShaderStageRuntime stage;
|
||||
std::string error;
|
||||
Check(ShaderMaterializeStageRuntime(cached_program, {}, 0, stage, &error),
|
||||
error.c_str());
|
||||
Check(stage.program == cached_program && stage.resources != nullptr,
|
||||
"cache rematerialization did not publish the mapped stage");
|
||||
Check(stage.resources->flattened_srt.size() == 1 &&
|
||||
stage.resources->flattened_srt[0] == dword,
|
||||
"cache rematerialization did not use the direct reader by default");
|
||||
}
|
||||
|
||||
void TestUnbasedFlatCacheHitFailsClosed() {
|
||||
using namespace Libs::Graphics;
|
||||
auto cached_program = UnbasedFlatProgram();
|
||||
auto prior_program = std::make_shared<const ShaderRecompiler::IR::Program>();
|
||||
auto prior_resources = std::make_shared<const ShaderRecompiler::IR::ResourceSnapshot>();
|
||||
ShaderStageRuntime stage {prior_program, prior_resources};
|
||||
std::string error;
|
||||
Check(!ShaderMaterializeStageRuntime(cached_program, {}, 0, stage, &error) &&
|
||||
error.find("requires runtime guest-address translation") != std::string::npos,
|
||||
"unbased FLAT cache hit did not fail without a runtime translator");
|
||||
Check(stage.program == prior_program && stage.resources == prior_resources,
|
||||
"unbased FLAT cache rejection replaced the prior stage snapshot");
|
||||
using namespace Libs::Graphics;
|
||||
auto cached_program = UnbasedFlatProgram();
|
||||
auto prior_program = std::make_shared<const ShaderRecompiler::IR::Program>();
|
||||
auto prior_resources =
|
||||
std::make_shared<const ShaderRecompiler::IR::ResourceSnapshot>();
|
||||
ShaderStageRuntime stage{prior_program, prior_resources};
|
||||
std::string error;
|
||||
Check(!ShaderMaterializeStageRuntime(cached_program, {}, 0, stage, &error) &&
|
||||
error.find("requires runtime guest-address translation") !=
|
||||
std::string::npos,
|
||||
"unbased FLAT cache hit did not fail without a runtime translator");
|
||||
Check(stage.program == prior_program && stage.resources == prior_resources,
|
||||
"unbased FLAT cache rejection replaced the prior stage snapshot");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace Common {
|
||||
|
||||
int DbgExitIfHandler(const char *, const char *, int) { return 1; }
|
||||
|
||||
void DbgExit(int) { std::abort(); }
|
||||
|
||||
} // namespace Common
|
||||
|
||||
int main() {
|
||||
TestMappedSrtUsesDirectReaderByDefault();
|
||||
TestUnbasedFlatCacheHitFailsClosed();
|
||||
std::puts("ShaderStageRuntimeTests: all cases passed");
|
||||
return 0;
|
||||
TestMappedSrtUsesDirectReaderByDefault();
|
||||
TestUnbasedFlatCacheHitFailsClosed();
|
||||
std::puts("ShaderStageRuntimeTests: all cases passed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Keep this focused standalone target self-contained by amalgamating its small
|
||||
// typed-IR implementation set.
|
||||
#include "graphics/shader/recompiler/ir/Block.cpp"
|
||||
#include "graphics/shader/recompiler/ir/Type.cpp"
|
||||
#include "graphics/shader/recompiler/ir/Value.cpp"
|
||||
#include "graphics/shader/recompiler/ir/opcodes/ValueOpcodes.cpp"
|
||||
#include "graphics/shader/recompiler/ir/ValueProgram.cpp"
|
||||
+8044
-6911
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user