shader: reuse native emitters and simplify memory dispatch

This commit is contained in:
nmzik
2026-09-11 19:10:48 +04:00
parent 59ef88c959
commit 20e57994cf
10 changed files with 721 additions and 993 deletions
+39
View File
@@ -16687,6 +16687,44 @@ TestCase VectorVop3LshlrevB64Captured() {
return test;
}
TestCase VectorDynamicU64ShiftEdges() {
using O = ShaderOpcode;
TestCase test;
test.name = "VectorDynamicU64ShiftEdges";
test.initial = {0u, 1u, 31u, 32u, 33u, 63u, 64u, 65u};
test.expected = test.initial;
auto& code = test.code;
for (const uint64_t source : {uint64_t{0}, uint64_t{1},
uint64_t{0x8000000000000000ull},
uint64_t{0xffffffffffffffffull},
uint64_t{0x0123456789abcdefull}}) {
AppendVMovLiteral(&code, 4, static_cast<u32>(source));
AppendVMovLiteral(&code, 5, static_cast<u32>(source >> 32u));
for (u32 index = 0; index < test.initial.size(); ++index) {
// A buffer load prevents the constant-shift specialization.
AppendVMovU32(&code, 30, index * sizeof(u32));
AppendBufferLoadDword(&code, 3, 30);
for (const bool left : {true, false}) {
AppendVop3(&code, left ? 0x2ff : 0x300, 33, Vgpr(3), Vgpr(4));
const auto amount = test.initial[index] & 63u;
const auto expected = left ? source << amount : source >> amount;
const auto output = static_cast<u32>(test.expected.size());
AppendStoreVgpr(&code, 33, output);
AppendStoreVgpr(&code, 34, output + 1u);
test.expected.push_back(static_cast<u32>(expected));
test.expected.push_back(static_cast<u32>(expected >> 32u));
}
}
}
AppendEnd(&code);
test.initial.resize(test.expected.size());
test.opcodes = {O::V_MOV_B32, O::BUFFER_LOAD_DWORD, O::V_LSHLREV_B64,
O::V_LSHRREV_B64, O::BUFFER_STORE_DWORD, O::S_ENDPGM};
test.required_spirv = {"OpShiftLeftLogical", "OpShiftRightLogical", "OpSelect"};
test.forbidden_spirv = {"OpTypeInt 64"};
return test;
}
TestCase VectorVop3IntegerOps() {
using O = ShaderOpcode;
@@ -24745,6 +24783,7 @@ std::vector<TestCase> MakeCases() {
AddCase(ScalarBfeI32CapturedRawSignExtends);
AddCase(BitfieldExtractWidthPastEndEdges);
AddCase(Scalar64BitOps);
AddCase(VectorDynamicU64ShiftEdges);
AddCase(ScalarConditionalMoveB64);
AddCase(ScalarConditionalMoveB64PreservesMasks);
AddCase(ScalarAndn2B64SccUsesMaskShadow);
+33
View File
@@ -8708,6 +8708,38 @@ void TestNewShaderRecompilerDispatcherSpillsU32x3() {
"dispatcher did not use one canonical U32x3 spill slot");
}
void TestNewShaderRecompilerPlanningOnlyLoads() {
using namespace ShaderRecompiler;
const uint32_t shader[] = {EncodeSopp(0x01)};
auto options = MakeCompileOptions(ShaderType::Compute);
auto result = RecompileForTest(shader, options);
auto& program = result.program;
IR::IREmitter ir(program.blocks.front());
IR::MemoryInfo memory;
memory.kind = IR::ResourceKind::ScalarAddress;
memory.planning_only = true;
program.memory_info.push_back(memory);
const auto address = ir.Emit(IR::ValueOpcode::GetAddressResource,
{IR::Value(0x1000u), IR::Value(0u)});
const auto load = ir.Emit(IR::ValueOpcode::LoadAddressU32,
{address, IR::Value(0u), IR::Value(0u), IR::Value(true)});
load.Instruction()->SetFlags(IR::MemoryFlags{.index = 0});
memory.kind = IR::ResourceKind::ScalarBuffer;
program.memory_info.push_back(memory);
const auto buffer = ir.Emit(IR::ValueOpcode::GetBufferResource,
{IR::Value(0x2000u), IR::Value(0u),
IR::Value(16u), IR::Value(0u)});
const auto read = ir.Emit(IR::ValueOpcode::ReadConstBuffer,
{buffer, IR::Value(0u)});
read.Instruction()->SetFlags(IR::MemoryFlags{.index = 1});
ir.Emit(IR::ValueOpcode::ReferenceU32, {load});
ir.Emit(IR::ValueOpcode::ReferenceU32, {read});
const auto spirv = Spirv::EmitProgram(program, options.input_info);
CheckSpirvBinaryValidates(spirv);
Check(spirv == result.spirv,
"planning-only loads or references emitted GPU operands/instructions");
}
void TestNewShaderRecompilerU64PairTranslation() {
using namespace ShaderRecompiler;
@@ -13017,6 +13049,7 @@ int main() {
TestNewShaderRecompilerCfgPrunesUnreachableSelectionEntry();
TestNewShaderRecompilerCfgIrreducibleDispatcher();
TestNewShaderRecompilerDispatcherSpillsU32x3();
TestNewShaderRecompilerPlanningOnlyLoads();
TestNewShaderRecompilerU64PairTranslation();
TestComputeDispatchWaveSize();
TestNewShaderRecompilerBufferLoadsGuardedByExec();