shader: keep scalar data native and preserve raw addresses

This commit is contained in:
nmzik
2026-10-04 10:04:12 +04:00
parent c17fa5b936
commit cd9fc6ff2d
6 changed files with 184 additions and 50 deletions
+41 -7
View File
@@ -30,7 +30,8 @@ AddValueBlock(Libs::Graphics::ShaderRecompiler::IR::Program &program) {
return *result;
}
Libs::Graphics::ShaderRecompiler::IR::ResourcePlan SrtPlan(uint64_t address) {
Libs::Graphics::ShaderRecompiler::IR::ResourcePlan SrtPlan(uint64_t address,
bool buffer = false) {
using namespace Libs::Graphics::ShaderRecompiler::IR;
Program program;
program.stage = Libs::Graphics::ShaderType::Compute;
@@ -39,16 +40,22 @@ Libs::Graphics::ShaderRecompiler::IR::ResourcePlan SrtPlan(uint64_t address) {
auto &value_block = AddValueBlock(program);
MemoryInfo memory;
memory.kind = ResourceKind::ScalarAddress;
memory.kind = buffer ? ResourceKind::ScalarBuffer : ResourceKind::ScalarAddress;
memory.planning_only = true;
program.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)});
auto &handle = buffer
? value_block.AppendNewInst(ValueOpcode::GetBufferResource,
{low, high, Value(4u), Value(0u)})
: value_block.AppendNewInst(ValueOpcode::GetAddressResource,
{low, high});
auto &raw = buffer
? value_block.AppendNewInst(ValueOpcode::ReadConstBuffer,
{Value(&handle), Value(0u)})
: value_block.AppendNewInst(
ValueOpcode::LoadAddressU32,
{Value(&handle), Value(0u), Value(0u), Value(true)});
raw.SetFlags(MemoryFlags{.index = 0, .pc = 0x40});
program.srt_reads.push_back({Value(&raw), 0});
@@ -163,6 +170,32 @@ void TestMappedSrtUsesDirectReaderByDefault() {
"cache rematerialization did not use the direct reader by default");
}
void TestRawScalarAddressPreservesHighBits() {
using namespace Libs::Graphics::ShaderRecompiler::IR;
constexpr uint64_t address = 0xabcd000156780003ull;
for (const bool buffer : {false, true}) {
auto plan = SrtPlan(address, buffer);
uint64_t observed = 0;
const SrtRuntime runtime{
.read_memory = [](void *userdata, uint64_t requested,
std::span<uint32_t> words) {
if (words.size() != 1) return false;
*static_cast<uint64_t *>(userdata) = requested;
words[0] = 0x12345678;
return true;
},
.userdata = &observed};
ResourceSnapshot snapshot;
ResourceSpecialization specialization;
Check(MaterializeResources(plan, runtime, snapshot, specialization),
"scalar address materialization failed");
Check(observed == (buffer ? 0x0000000156780000ull : address & ~uint64_t{3}),
"raw pointer high bits and buffer descriptor flags were conflated");
Check(snapshot.flattened_srt == std::vector<uint32_t>{0x12345678},
"scalar address read did not reach its flattened slot");
}
}
void TestIntegerRuntimeValueFollowsSrtReads() {
using namespace Libs::Graphics::ShaderRecompiler::IR;
auto plan = SrtPlan(0x10000);
@@ -454,6 +487,7 @@ void DbgExit(int) { std::abort(); }
int main() {
TestMappedSrtUsesDirectReaderByDefault();
TestRawScalarAddressPreservesHighBits();
TestIntegerRuntimeValueFollowsSrtReads();
TestUnbasedFlatCacheHitMaterializes();
TestWrittenDescriptorUsesStrictReaderOnce();