shader_recompiler: add SSA

This commit is contained in:
nmzik committed 2026-08-18 03:53:41 +02:00
1 parent bc2f077c37
commit b42380ced6
113 files changed
+40415 -32616

No files matched your search

File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+111 -64
View File
@@ -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
View File
File diff suppressed because it is too large. Load diff