Refactor MaxwellToSpirvComparison. Use Common::BitCast

Co-Authored-By: Rodrigo Locatti <reinuseslisp@airmail.cc>
This commit is contained in:
ameerj 2020-11-25 00:33:20 -05:00
parent 1dbf71ceb3
commit e87670ee48
3 changed files with 34 additions and 31 deletions

View file

@ -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, &regs.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, &regs.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] =

View file

@ -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;

View file

@ -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() {