forked from suyu/suyu
Refactor MaxwellToSpirvComparison. Use Common::BitCast
Co-Authored-By: Rodrigo Locatti <reinuseslisp@airmail.cc>
This commit is contained in:
parent
1dbf71ceb3
commit
e87670ee48
3 changed files with 34 additions and 31 deletions
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <boost/functional/hash.hpp>
|
#include <boost/functional/hash.hpp>
|
||||||
|
|
||||||
|
#include "common/bit_cast.h"
|
||||||
#include "common/cityhash.h"
|
#include "common/cityhash.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "video_core/renderer_vulkan/fixed_pipeline_state.h"
|
#include "video_core/renderer_vulkan/fixed_pipeline_state.h"
|
||||||
|
@ -64,9 +65,9 @@ void FixedPipelineState::Fill(const Maxwell& regs, bool has_extended_dynamic_sta
|
||||||
const auto test_func =
|
const auto test_func =
|
||||||
regs.alpha_test_enabled == 1 ? regs.alpha_test_func : Maxwell::ComparisonOp::Always;
|
regs.alpha_test_enabled == 1 ? regs.alpha_test_func : Maxwell::ComparisonOp::Always;
|
||||||
alpha_test_func.Assign(PackComparisonOp(test_func));
|
alpha_test_func.Assign(PackComparisonOp(test_func));
|
||||||
std::memcpy(&alpha_test_ref, ®s.alpha_test_ref, sizeof(u32)); // TODO: C++20 std::bit_cast
|
alpha_test_ref = Common::BitCast<u32>(regs.alpha_test_ref);
|
||||||
|
|
||||||
std::memcpy(&point_size, ®s.point_size, sizeof(point_size)); // TODO: C++20 std::bit_cast
|
point_size = Common::BitCast<u32>(regs.point_size);
|
||||||
|
|
||||||
for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) {
|
for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) {
|
||||||
binding_divisors[index] =
|
binding_divisors[index] =
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "common/bit_cast.h"
|
||||||
#include "common/microprofile.h"
|
#include "common/microprofile.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
@ -347,8 +348,7 @@ VKPipelineCache::DecompileShaders(const FixedPipelineState& fixed_state) {
|
||||||
// Alpha test
|
// Alpha test
|
||||||
specialization.alpha_test_func =
|
specialization.alpha_test_func =
|
||||||
FixedPipelineState::UnpackComparisonOp(fixed_state.alpha_test_func.Value());
|
FixedPipelineState::UnpackComparisonOp(fixed_state.alpha_test_func.Value());
|
||||||
// memcpy from u32 to float TODO: C++20 std::bit_cast
|
specialization.alpha_test_ref = Common::BitCast<float>(fixed_state.alpha_test_ref);
|
||||||
std::memcpy(&specialization.alpha_test_ref, &fixed_state.alpha_test_ref, sizeof(float));
|
|
||||||
|
|
||||||
SPIRVProgram program;
|
SPIRVProgram program;
|
||||||
std::vector<VkDescriptorSetLayoutBinding> bindings;
|
std::vector<VkDescriptorSetLayoutBinding> bindings;
|
||||||
|
|
|
@ -2075,47 +2075,49 @@ private:
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void AlphaTest(Id pointer) {
|
Id MaxwellToSpirvComparison(Maxwell::ComparisonOp compare_op, Id operand_1, Id operand_2) {
|
||||||
const Id true_label = OpLabel();
|
|
||||||
const Id skip_label = OpLabel();
|
|
||||||
const Id alpha_reference = Constant(t_float, specialization.alpha_test_ref);
|
|
||||||
const Id alpha_value = OpLoad(t_float, pointer);
|
|
||||||
Id condition;
|
|
||||||
using Compare = Maxwell::ComparisonOp;
|
using Compare = Maxwell::ComparisonOp;
|
||||||
switch (specialization.alpha_test_func) {
|
switch (compare_op) {
|
||||||
case Compare::NeverOld:
|
case Compare::NeverOld:
|
||||||
condition = v_false; // Never true
|
return v_false; // Never let the test pass
|
||||||
break;
|
|
||||||
case Compare::LessOld:
|
case Compare::LessOld:
|
||||||
condition = OpFOrdLessThan(t_bool, alpha_reference, alpha_value);
|
return OpFOrdLessThan(t_bool, operand_1, operand_2);
|
||||||
break;
|
|
||||||
case Compare::EqualOld:
|
case Compare::EqualOld:
|
||||||
condition = OpFOrdEqual(t_bool, alpha_reference, alpha_value);
|
// Note: not accurate when tested against a unit test
|
||||||
break;
|
// TODO: confirm if used by games
|
||||||
|
return OpFOrdEqual(t_bool, operand_1, operand_2);
|
||||||
case Compare::LessEqualOld:
|
case Compare::LessEqualOld:
|
||||||
condition = OpFOrdLessThanEqual(t_bool, alpha_reference, alpha_value);
|
return OpFOrdLessThanEqual(t_bool, operand_1, operand_2);
|
||||||
break;
|
|
||||||
case Compare::GreaterOld:
|
case Compare::GreaterOld:
|
||||||
// Note: requires "Equal" to properly work for ssbu. perhaps a precision issue
|
return OpFOrdGreaterThan(t_bool, operand_1, operand_2);
|
||||||
condition = OpFOrdGreaterThanEqual(t_bool, alpha_reference, alpha_value);
|
|
||||||
break;
|
|
||||||
case Compare::NotEqualOld:
|
case Compare::NotEqualOld:
|
||||||
// Note: not accurate when tested against a unit test
|
// Note: not accurate when tested against a unit test
|
||||||
// TODO: confirm if used by games
|
// TODO: confirm if used by games
|
||||||
condition = OpFOrdNotEqual(t_bool, alpha_reference, alpha_value);
|
return OpFOrdNotEqual(t_bool, operand_1, operand_2);
|
||||||
break;
|
|
||||||
case Compare::GreaterEqualOld:
|
case Compare::GreaterEqualOld:
|
||||||
condition = OpFOrdGreaterThanEqual(t_bool, alpha_reference, alpha_value);
|
return OpFOrdGreaterThanEqual(t_bool, operand_1, operand_2);
|
||||||
break;
|
|
||||||
case Compare::AlwaysOld:
|
|
||||||
return;
|
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
OpBranchConditional(condition, true_label, skip_label);
|
}
|
||||||
AddLabel(true_label);
|
|
||||||
|
void AlphaTest(Id pointer) {
|
||||||
|
if (specialization.alpha_test_func == Maxwell::ComparisonOp::AlwaysOld) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Id true_label = OpLabel();
|
||||||
|
const Id discard_label = OpLabel();
|
||||||
|
const Id alpha_reference = Constant(t_float, specialization.alpha_test_ref);
|
||||||
|
const Id alpha_value = OpLoad(t_float, pointer);
|
||||||
|
|
||||||
|
const Id condition =
|
||||||
|
MaxwellToSpirvComparison(specialization.alpha_test_func, alpha_value, alpha_reference);
|
||||||
|
|
||||||
|
OpBranchConditional(condition, true_label, discard_label);
|
||||||
|
AddLabel(discard_label);
|
||||||
OpKill();
|
OpKill();
|
||||||
AddLabel(skip_label);
|
AddLabel(true_label);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreExit() {
|
void PreExit() {
|
||||||
|
|
Loading…
Reference in a new issue