mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 02:47:02 +02:00
shader: reuse native emitters and simplify memory dispatch
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user