summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.cpp9
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.h7
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp6
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.cpp44
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.h2
5 files changed, 65 insertions, 3 deletions
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
index da5c550ea..fffae528e 100644
--- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
+++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
@@ -8,6 +8,7 @@
8 8
9#include <boost/functional/hash.hpp> 9#include <boost/functional/hash.hpp>
10 10
11#include "common/bit_cast.h"
11#include "common/cityhash.h" 12#include "common/cityhash.h"
12#include "common/common_types.h" 13#include "common/common_types.h"
13#include "video_core/renderer_vulkan/fixed_pipeline_state.h" 14#include "video_core/renderer_vulkan/fixed_pipeline_state.h"
@@ -60,7 +61,13 @@ void FixedPipelineState::Fill(const Maxwell& regs, bool has_extended_dynamic_sta
60 rasterize_enable.Assign(regs.rasterize_enable != 0 ? 1 : 0); 61 rasterize_enable.Assign(regs.rasterize_enable != 0 ? 1 : 0);
61 topology.Assign(regs.draw.topology); 62 topology.Assign(regs.draw.topology);
62 63
63 std::memcpy(&point_size, &regs.point_size, sizeof(point_size)); // TODO: C++20 std::bit_cast 64 alpha_raw = 0;
65 const auto test_func =
66 regs.alpha_test_enabled == 1 ? regs.alpha_test_func : Maxwell::ComparisonOp::Always;
67 alpha_test_func.Assign(PackComparisonOp(test_func));
68 alpha_test_ref = Common::BitCast<u32>(regs.alpha_test_ref);
69
70 point_size = Common::BitCast<u32>(regs.point_size);
64 71
65 for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) { 72 for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) {
66 binding_divisors[index] = 73 binding_divisors[index] =
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.h b/src/video_core/renderer_vulkan/fixed_pipeline_state.h
index 2c18eeaae..42480e8d0 100644
--- a/src/video_core/renderer_vulkan/fixed_pipeline_state.h
+++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.h
@@ -187,6 +187,13 @@ struct FixedPipelineState {
187 BitField<23, 1, u32> rasterize_enable; 187 BitField<23, 1, u32> rasterize_enable;
188 BitField<24, 4, Maxwell::PrimitiveTopology> topology; 188 BitField<24, 4, Maxwell::PrimitiveTopology> topology;
189 }; 189 };
190
191 u32 alpha_test_ref; ///< Alpha test reference value
192 union {
193 u32 alpha_raw;
194 BitField<0, 3, u32> alpha_test_func;
195 };
196
190 u32 point_size; 197 u32 point_size;
191 std::array<u32, Maxwell::NumVertexArrays> binding_divisors; 198 std::array<u32, Maxwell::NumVertexArrays> binding_divisors;
192 std::array<VertexAttribute, Maxwell::NumVertexAttributes> attributes; 199 std::array<VertexAttribute, Maxwell::NumVertexAttributes> attributes;
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index dedc9c466..f9efe526d 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -7,6 +7,7 @@
7#include <memory> 7#include <memory>
8#include <vector> 8#include <vector>
9 9
10#include "common/bit_cast.h"
10#include "common/microprofile.h" 11#include "common/microprofile.h"
11#include "core/core.h" 12#include "core/core.h"
12#include "core/memory.h" 13#include "core/memory.h"
@@ -344,6 +345,11 @@ VKPipelineCache::DecompileShaders(const FixedPipelineState& fixed_state) {
344 } 345 }
345 specialization.ndc_minus_one_to_one = fixed_state.ndc_minus_one_to_one; 346 specialization.ndc_minus_one_to_one = fixed_state.ndc_minus_one_to_one;
346 347
348 // Alpha test
349 specialization.alpha_test_func =
350 FixedPipelineState::UnpackComparisonOp(fixed_state.alpha_test_func.Value());
351 specialization.alpha_test_ref = Common::BitCast<float>(fixed_state.alpha_test_ref);
352
347 SPIRVProgram program; 353 SPIRVProgram program;
348 std::vector<VkDescriptorSetLayoutBinding> bindings; 354 std::vector<VkDescriptorSetLayoutBinding> bindings;
349 355
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
index a20452b87..1c52f40bb 100644
--- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
+++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
@@ -2075,6 +2075,45 @@ private:
2075 return {}; 2075 return {};
2076 } 2076 }
2077 2077
2078 Id MaxwellToSpirvComparison(Maxwell::ComparisonOp compare_op, Id operand_1, Id operand_2) {
2079 using Compare = Maxwell::ComparisonOp;
2080 switch (compare_op) {
2081 case Compare::NeverOld:
2082 return v_false; // Never let the test pass
2083 case Compare::LessOld:
2084 return OpFOrdLessThan(t_bool, operand_1, operand_2);
2085 case Compare::EqualOld:
2086 return OpFOrdEqual(t_bool, operand_1, operand_2);
2087 case Compare::LessEqualOld:
2088 return OpFOrdLessThanEqual(t_bool, operand_1, operand_2);
2089 case Compare::GreaterOld:
2090 return OpFOrdGreaterThan(t_bool, operand_1, operand_2);
2091 case Compare::NotEqualOld:
2092 return OpFOrdNotEqual(t_bool, operand_1, operand_2);
2093 case Compare::GreaterEqualOld:
2094 return OpFOrdGreaterThanEqual(t_bool, operand_1, operand_2);
2095 default:
2096 UNREACHABLE();
2097 }
2098 }
2099
2100 void AlphaTest(Id pointer) {
2101 if (specialization.alpha_test_func == Maxwell::ComparisonOp::AlwaysOld) {
2102 return;
2103 }
2104 const Id true_label = OpLabel();
2105 const Id discard_label = OpLabel();
2106 const Id alpha_reference = Constant(t_float, specialization.alpha_test_ref);
2107 const Id alpha_value = OpLoad(t_float, pointer);
2108 const Id condition =
2109 MaxwellToSpirvComparison(specialization.alpha_test_func, alpha_value, alpha_reference);
2110
2111 OpBranchConditional(condition, true_label, discard_label);
2112 AddLabel(discard_label);
2113 OpKill();
2114 AddLabel(true_label);
2115 }
2116
2078 void PreExit() { 2117 void PreExit() {
2079 if (stage == ShaderType::Vertex && specialization.ndc_minus_one_to_one) { 2118 if (stage == ShaderType::Vertex && specialization.ndc_minus_one_to_one) {
2080 const u32 position_index = out_indices.position.value(); 2119 const u32 position_index = out_indices.position.value();
@@ -2097,8 +2136,6 @@ private:
2097 UNIMPLEMENTED_IF_MSG(header.ps.omap.sample_mask != 0, 2136 UNIMPLEMENTED_IF_MSG(header.ps.omap.sample_mask != 0,
2098 "Sample mask write is unimplemented"); 2137 "Sample mask write is unimplemented");
2099 2138
2100 // TODO(Rodrigo): Alpha testing
2101
2102 // Write the color outputs using the data in the shader registers, disabled 2139 // Write the color outputs using the data in the shader registers, disabled
2103 // rendertargets/components are skipped in the register assignment. 2140 // rendertargets/components are skipped in the register assignment.
2104 u32 current_reg = 0; 2141 u32 current_reg = 0;
@@ -2110,6 +2147,9 @@ private:
2110 } 2147 }
2111 const Id pointer = AccessElement(t_out_float, frag_colors[rt], component); 2148 const Id pointer = AccessElement(t_out_float, frag_colors[rt], component);
2112 OpStore(pointer, SafeGetRegister(current_reg)); 2149 OpStore(pointer, SafeGetRegister(current_reg));
2150 if (rt == 0 && component == 3) {
2151 AlphaTest(pointer);
2152 }
2113 ++current_reg; 2153 ++current_reg;
2114 } 2154 }
2115 } 2155 }
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.h b/src/video_core/renderer_vulkan/vk_shader_decompiler.h
index 2b0e90396..cd3d0a415 100644
--- a/src/video_core/renderer_vulkan/vk_shader_decompiler.h
+++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.h
@@ -95,6 +95,8 @@ struct Specialization final {
95 std::bitset<Maxwell::NumVertexAttributes> enabled_attributes; 95 std::bitset<Maxwell::NumVertexAttributes> enabled_attributes;
96 std::array<Maxwell::VertexAttribute::Type, Maxwell::NumVertexAttributes> attribute_types{}; 96 std::array<Maxwell::VertexAttribute::Type, Maxwell::NumVertexAttributes> attribute_types{};
97 bool ndc_minus_one_to_one{}; 97 bool ndc_minus_one_to_one{};
98 float alpha_test_ref{};
99 Maxwell::ComparisonOp alpha_test_func{};
98}; 100};
99// Old gcc versions don't consider this trivially copyable. 101// Old gcc versions don't consider this trivially copyable.
100// static_assert(std::is_trivially_copyable_v<Specialization>); 102// static_assert(std::is_trivially_copyable_v<Specialization>);