Merge pull request #2790 from tototomate123/fix/hfw-shader-split
fix(shader): evaluate signed minimum in runtime SRT expressions
This commit is contained in:
commit
6968564656
|
|
@ -7,6 +7,7 @@
|
|||
#include "Optimization/ShaderStageInputInfo.hpp"
|
||||
#include "Optimization/SrtWalker/SrtDescriptorEvaluation.hpp"
|
||||
#include "Optimization/SrtWalker/SrtEvaluator.hpp"
|
||||
#include "Optimization/SrtWalker/SrtInstructionPredicates.hpp"
|
||||
#include "Optimization/SrtWalker/SrtFlatSlotClasses.hpp"
|
||||
#include "SpirvBackend/SpirvAnalysis.hpp"
|
||||
#if ANYPS5_ENABLE_SPIRV_TOOLS
|
||||
|
|
@ -360,6 +361,28 @@ void verifyRegisterSources() {
|
|||
require(!EquivalentValue(plan, &samplerRegister, &firstVector), "different register types were merged");
|
||||
}
|
||||
|
||||
void verifySignedMinimum() {
|
||||
using namespace ShaderRecompiler;
|
||||
IrResourcePlan plan;
|
||||
IrValue reg(IrOpcode::Void, IrType::ScalarReg, 0);
|
||||
reg.SetRegister({RegisterBank::Scalar, 0});
|
||||
IrValue input(IrOpcode::GetUserData, IrType::U32, 1);
|
||||
input.AddArgument(®);
|
||||
IrValue limit(IrOpcode::Void, IrType::U32, 2);
|
||||
limit.SetImmediateU32(8);
|
||||
IrValue minimum(IrOpcode::SMin32, IrType::U32, 3);
|
||||
minimum.AddArgument(&input);
|
||||
minimum.AddArgument(&limit);
|
||||
require(Detail::IsRuntimeUniformOp(IrOpcode::SMin32), "signed minimum must be a runtime uniform operation");
|
||||
for (const auto& [value, expected] : std::array<std::pair<std::uint32_t, std::uint32_t>, 6>{{{0, 0}, {4, 4}, {20, 8}, {0x7fffffffu, 8}, {0xffffffffu, 0xffffffffu}, {0x80000000u, 0x80000000u}}}) {
|
||||
std::array<std::uint32_t, 1> data{value};
|
||||
SrtRuntime runtime{data};
|
||||
Detail::Evaluator evaluator(plan, runtime);
|
||||
std::uint32_t result = 0;
|
||||
require(evaluator.Evaluate(&minimum, result) && result == expected, "SRT signed minimum used unsigned ordering or failed evaluation");
|
||||
}
|
||||
}
|
||||
|
||||
void verifyEvaluatedValues() {
|
||||
using namespace ShaderRecompiler;
|
||||
std::vector<std::unique_ptr<IrValue>> values;
|
||||
|
|
@ -2588,6 +2611,7 @@ int main(int argc, char** argv) {
|
|||
verifyEvaluatedValues();
|
||||
verifyFrontendPair();
|
||||
verifySignedSrtComparison();
|
||||
verifySignedMinimum();
|
||||
verifyPureFlatSlots();
|
||||
verifyBindlessTable();
|
||||
verifyDescriptorPhis();
|
||||
|
|
|
|||
|
|
@ -262,6 +262,12 @@ bool Evaluator::EvaluateInst(IrValue& inst, std::uint64_t& result) {
|
|||
return true;
|
||||
}
|
||||
return false;
|
||||
case IrOpcode::SMin32:
|
||||
if (binary()) {
|
||||
result = static_cast<std::uint32_t>(std::min(std::bit_cast<std::int32_t>(static_cast<std::uint32_t>(a)), std::bit_cast<std::int32_t>(static_cast<std::uint32_t>(b))));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case IrOpcode::UMin32:
|
||||
if (binary()) {
|
||||
result = std::min(static_cast<std::uint32_t>(a), static_cast<std::uint32_t>(b));
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ bool IsRuntimeUniformOp(IrOpcode opcode) {
|
|||
case IrOpcode::ISub64:
|
||||
case IrOpcode::IMul32:
|
||||
case IrOpcode::IMul64:
|
||||
case IrOpcode::SMin32:
|
||||
case IrOpcode::UMin32:
|
||||
case IrOpcode::ShiftLeftLogical32:
|
||||
case IrOpcode::ShiftLeftLogical64:
|
||||
|
|
|
|||
Loading…
Reference in New Issue