mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-07 13:39:55 +00:00
fix(shader): keep undecoded OpExtInst and runtime logical guards in specialization
This commit is contained in:
1 parent
d9ce5c9b9b
commit
cbdbc601dc
3 files changed
+6
-37
No files matched your search
@@ -322,8 +322,6 @@ void testPrivateCompositeTableLoadFolding() {
|
||||
const auto input = module.DefineGlobalVariable(typeInputPtr, spv::StorageClassInput);
|
||||
const auto table = module.DefineInitializedGlobalVariable(typeTablePtr, spv::StorageClassPrivate, initial);
|
||||
const auto output = module.DefineGlobalVariable(typePrivatePtr, spv::StorageClassPrivate);
|
||||
const auto glsl = module.Import("GLSL.std.450");
|
||||
const auto customSet = module.Import("NonSemantic.Test");
|
||||
const auto mainId = module.AllocateId();
|
||||
const auto lane = module.AllocateId();
|
||||
const auto rawCond = module.AllocateId();
|
||||
@@ -341,11 +339,6 @@ void testPrivateCompositeTableLoadFolding() {
|
||||
module.AddFunction(accessOp, typePrivatePtr, writePtr, table, zero);
|
||||
module.AddFunction(spv::OpStore, writePtr, lane);
|
||||
}
|
||||
const auto liveGlsl = module.AllocateId();
|
||||
module.AddFunction(spv::OpExtInst, typeU32, module.AllocateId(), glsl, 37u, lane, zero);
|
||||
module.AddFunction(spv::OpExtInst, typeU32, liveGlsl, glsl, 37u, lane, one);
|
||||
module.AddFunction(spv::OpStore, output, liveGlsl);
|
||||
module.AddFunction(spv::OpExtInst, typeU32, module.AllocateId(), customSet, 1u, lane);
|
||||
module.AddFunction(spv::OpUGreaterThan, typeBool, rawCond, lane, zero);
|
||||
module.AddFunction(spv::OpLogicalOr, typeBool, cond, rawCond, falseVal);
|
||||
module.AddFunction(spv::OpIAdd, typeU32, baseIndex, one, one);
|
||||
@@ -364,16 +357,12 @@ void testPrivateCompositeTableLoadFolding() {
|
||||
check(!foldedCounts.contains(spv::OpLogicalOr), "a right-false OpLogicalOr was not simplified");
|
||||
check(!foldedCounts.contains(spv::OpSelect), "an identical-arm OpSelect was not simplified");
|
||||
check(foldedCounts.contains(spv::OpLoad) && foldedCounts.at(spv::OpLoad) == 1u, "a constant-index private composite table load was not folded");
|
||||
check(foldedCounts.contains(spv::OpExtInst) && foldedCounts.at(spv::OpExtInst) == 2u, "an unused GLSL.std.450 OpExtInst was not removed or a live/non-GLSL.std.450 OpExtInst was removed");
|
||||
bool addedThirty = false;
|
||||
bool keptCustomExtInst = false;
|
||||
for (std::size_t cursor = 5; cursor < folded.size(); cursor += folded[cursor] >> 16u) {
|
||||
if ((folded[cursor] >> 16u) == 0u) break;
|
||||
if ((folded[cursor] & 0xffffu) == spv::OpIAdd && folded[cursor + 4u] == expectedConstant) addedThirty = true;
|
||||
if ((folded[cursor] & 0xffffu) == spv::OpExtInst && folded[cursor + 4u] == 1u) keptCustomExtInst = true;
|
||||
}
|
||||
check(addedThirty, "a constant-index private composite table load did not fold to its element constant");
|
||||
check(keptCustomExtInst, "a non-GLSL.std.450 OpExtInst was not preserved");
|
||||
|
||||
const auto [dynamic, unusedDynamic] = build(true, false);
|
||||
static_cast<void>(unusedDynamic);
|
||||
|
||||
@@ -446,7 +446,7 @@ std::uint32_t genericFormattedLoad(SpirvValueEmitContext& context, const IrValue
|
||||
const auto fromMemory = Binary(state, spv::OpUGreaterThanEqual, boolean, selectors[output], constant(4u));
|
||||
required[component] = Binary(state, spv::OpLogicalOr, boolean, required[component], both(state, fromMemory, equal(state, selected[output], constant(component))));
|
||||
}
|
||||
required[component] = both(state, active[component], required[component]);
|
||||
required[component] = Select(state, boolean, active[component], required[component], ConstantBool(state, false));
|
||||
const auto componentOffset = field(state, byteOffsets, component * 8u, 8u);
|
||||
const auto bytes = Select(state, u32, packed, constant(4u), Binary(state, spv::OpShiftRightLogical, u32, bits[component], constant(3u)));
|
||||
const auto offset = Binary(state, spv::OpIAdd, u32, resource.offset != 0u ? resource.offset : Binary(state, spv::OpIAdd, u32, context.Arg(instruction, 2u), constant(memory.offset)), componentOffset);
|
||||
@@ -454,16 +454,16 @@ std::uint32_t genericFormattedLoad(SpirvValueEmitContext& context, const IrValue
|
||||
if (memory.gpuDescriptor) {
|
||||
const auto u64 = TypeScalarU64(state);
|
||||
const auto guest = Binary(state, spv::OpIAdd, u64, resource.base, Unary(state, spv::OpUConvert, u64, addresses[component].guest));
|
||||
const auto overflow = both(state, active[component], Binary(state, spv::OpULessThan, boolean, guest, resource.base));
|
||||
const auto overflow = Select(state, boolean, active[component], Binary(state, spv::OpULessThan, boolean, guest, resource.base), ConstantBool(state, false));
|
||||
EmitIfCondition(state, overflow, [&] { RecordBdaFault(state, resource.base, constant(0u), BdaInstructionPc(state, instruction), BdaAbi::FaultReason::Overflow); });
|
||||
StopBdaInvocationIf(state, overflow);
|
||||
addresses[component].guest = guest;
|
||||
}
|
||||
inBounds = both(state, inBounds, Binary(state, spv::OpLogicalOr, boolean, Unary(state, spv::OpLogicalNot, boolean, required[component]), addresses[component].inBounds));
|
||||
inBounds = Select(state, boolean, required[component], both(state, inBounds, addresses[component].inBounds), inBounds);
|
||||
}
|
||||
std::array<std::uint32_t, 4> values{};
|
||||
for (std::uint32_t component = 0; component < 4u; ++component) {
|
||||
values[component] = EmitValueOrZeroIfCondition(state, both(state, inBounds, required[component]), [&] {
|
||||
values[component] = EmitValueOrZeroIfCondition(state, Select(state, boolean, required[component], inBounds, ConstantBool(state, false)), [&] {
|
||||
const auto width = Select(state, u32, packed, constant(32u), bits[component]);
|
||||
const auto dword = equal(state, width, constant(32u));
|
||||
const auto raw = memory.gpuDescriptor
|
||||
|
||||
@@ -100,7 +100,7 @@ private:
|
||||
std::vector<std::uint8_t> present;
|
||||
};
|
||||
|
||||
bool PureInstruction(const Instruction& instruction, const IdSet& glslExtInstSets = {}) {
|
||||
bool PureInstruction(const Instruction& instruction) {
|
||||
switch (Opcode(instruction)) {
|
||||
case spv::OpVectorExtractDynamic:
|
||||
case spv::OpVectorInsertDynamic:
|
||||
@@ -219,8 +219,6 @@ bool PureInstruction(const Instruction& instruction, const IdSet& glslExtInstSet
|
||||
case spv::OpArrayLength:
|
||||
case spv::OpPhi:
|
||||
return true;
|
||||
case spv::OpExtInst:
|
||||
return instruction.size() >= 5u && glslExtInstSets.contains(instruction[3]);
|
||||
case spv::OpLoad:
|
||||
return instruction.size() == 4u || (instruction.size() == 5u && instruction[4] == spv::MemoryAccessMaskNone);
|
||||
default:
|
||||
@@ -233,9 +231,6 @@ bool VisitInputs(const Instruction& instruction, const TVisitor& visit) {
|
||||
std::size_t first = 3u;
|
||||
std::size_t end = instruction.size();
|
||||
switch (Opcode(instruction)) {
|
||||
case spv::OpExtInst:
|
||||
first = 5u;
|
||||
break;
|
||||
case spv::OpVectorShuffle:
|
||||
case spv::OpCompositeInsert:
|
||||
end = 5u;
|
||||
@@ -583,7 +578,6 @@ public:
|
||||
values.Reset(bound);
|
||||
resultTypes.Reset(bound);
|
||||
vectorTypes.Reset(bound);
|
||||
glslExtInstSets.Reset(bound);
|
||||
removed.Reset(bound);
|
||||
aliases.Reset(bound);
|
||||
composites.Reset(bound);
|
||||
@@ -598,7 +592,6 @@ public:
|
||||
bool hasType = false;
|
||||
spv::HasResultAndType(op, &hasResult, &hasType);
|
||||
if (hasResult && hasType) resultTypes.emplace(instruction.at(2), instruction.at(1));
|
||||
if (op == spv::OpExtInstImport && instruction.size() == 6u && instruction[2] == 0x4c534c47u && instruction[3] == 0x6474732eu && instruction[4] == 0x3035342eu && instruction[5] == 0u) glslExtInstSets.insert(instruction.at(1));
|
||||
if (op == spv::OpTypeBool) types.emplace(instruction.at(1), ScalarType{1u, true});
|
||||
if (op == spv::OpTypeInt) types.emplace(instruction.at(1), ScalarType{instruction.at(2), false});
|
||||
if (op == spv::OpTypeVector) vectorTypes.insert(instruction.at(1));
|
||||
@@ -680,18 +673,6 @@ private:
|
||||
return pointer->second < elements.size() ? value(elements[pointer->second]) : std::nullopt;
|
||||
}
|
||||
const auto left = value(instruction[3]);
|
||||
if (op == spv::OpLogicalAnd && instruction.size() == 5u) {
|
||||
const auto right = value(instruction[4]);
|
||||
if ((left && *left == 0u) || (right && *right == 0u)) return 0u;
|
||||
if (left && right) return *left != 0u && *right != 0u;
|
||||
return std::nullopt;
|
||||
}
|
||||
if (op == spv::OpLogicalOr && instruction.size() == 5u) {
|
||||
const auto right = value(instruction[4]);
|
||||
if ((left && *left != 0u) || (right && *right != 0u)) return 1u;
|
||||
if (left && right) return *left != 0u || *right != 0u;
|
||||
return std::nullopt;
|
||||
}
|
||||
if (!left) return std::nullopt;
|
||||
if (op == spv::OpCopyObject) return left;
|
||||
if (op == spv::OpLogicalNot) return *left == 0u;
|
||||
@@ -1128,7 +1109,7 @@ private:
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (PureInstruction(instruction, glslExtInstSets)) {
|
||||
if (PureInstruction(instruction)) {
|
||||
definitions.emplace(Result(instruction), index);
|
||||
continue;
|
||||
}
|
||||
@@ -1165,7 +1146,6 @@ private:
|
||||
IdTable<std::uint32_t> values;
|
||||
IdTable<std::uint32_t> resultTypes;
|
||||
IdSet vectorTypes;
|
||||
IdSet glslExtInstSets;
|
||||
IdSet removed;
|
||||
IdTable<std::uint32_t> aliases;
|
||||
IdTable<std::vector<std::uint32_t>> composites;
|
||||
|
||||
Reference in new issue
Block a user