summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.cpp5
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.h3
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp10
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.cpp50
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.h3
5 files changed, 31 insertions, 40 deletions
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
index 1b9611c59..192828300 100644
--- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
+++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
@@ -61,8 +61,9 @@ void FixedPipelineState::Fill(const Maxwell& regs, bool has_extended_dynamic_sta
61 topology.Assign(regs.draw.topology); 61 topology.Assign(regs.draw.topology);
62 62
63 alpha_raw = 0; 63 alpha_raw = 0;
64 alpha_test_enabled.Assign(regs.alpha_test_enabled); 64 const auto test_func =
65 alpha_test_func.Assign(PackComparisonOp(regs.alpha_test_func)); 65 regs.alpha_test_enabled == 1 ? regs.alpha_test_func : Maxwell::ComparisonOp::Always;
66 alpha_test_func.Assign(PackComparisonOp(test_func));
66 std::memcpy(&alpha_test_ref, &regs.alpha_test_ref, sizeof(u32)); // TODO: C++20 std::bit_cast 67 std::memcpy(&alpha_test_ref, &regs.alpha_test_ref, sizeof(u32)); // TODO: C++20 std::bit_cast
67 68
68 std::memcpy(&point_size, &regs.point_size, sizeof(point_size)); // TODO: C++20 std::bit_cast 69 std::memcpy(&point_size, &regs.point_size, sizeof(point_size)); // TODO: C++20 std::bit_cast
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.h b/src/video_core/renderer_vulkan/fixed_pipeline_state.h
index 9a45ec6b7..42480e8d0 100644
--- a/src/video_core/renderer_vulkan/fixed_pipeline_state.h
+++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.h
@@ -188,11 +188,10 @@ struct FixedPipelineState {
188 BitField<24, 4, Maxwell::PrimitiveTopology> topology; 188 BitField<24, 4, Maxwell::PrimitiveTopology> topology;
189 }; 189 };
190 190
191 u32 alpha_test_ref; /// < Alpha test reference 191 u32 alpha_test_ref; ///< Alpha test reference value
192 union { 192 union {
193 u32 alpha_raw; 193 u32 alpha_raw;
194 BitField<0, 3, u32> alpha_test_func; 194 BitField<0, 3, u32> alpha_test_func;
195 BitField<3, 1, u32> alpha_test_enabled;
196 }; 195 };
197 196
198 u32 point_size; 197 u32 point_size;
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index 9ccf5d011..a66a841fb 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -345,12 +345,10 @@ VKPipelineCache::DecompileShaders(const FixedPipelineState& fixed_state) {
345 specialization.ndc_minus_one_to_one = fixed_state.ndc_minus_one_to_one; 345 specialization.ndc_minus_one_to_one = fixed_state.ndc_minus_one_to_one;
346 346
347 // Alpha test 347 // Alpha test
348 if (fixed_state.alpha_test_enabled == 1) { 348 specialization.alpha_test_func =
349 specialization.alpha_test_enabled = true; 349 FixedPipelineState::UnpackComparisonOp(fixed_state.alpha_test_func.Value());
350 specialization.alpha_test_func = static_cast<u8>(fixed_state.alpha_test_func); 350 // memcpy from u32 to float TODO: C++20 std::bit_cast
351 // memcpy from u32 to float TODO: C++20 std::bit_cast 351 std::memcpy(&specialization.alpha_test_ref, &fixed_state.alpha_test_ref, sizeof(float));
352 std::memcpy(&specialization.alpha_test_ref, &fixed_state.alpha_test_ref, sizeof(float));
353 }
354 352
355 SPIRVProgram program; 353 SPIRVProgram program;
356 std::vector<VkDescriptorSetLayoutBinding> bindings; 354 std::vector<VkDescriptorSetLayoutBinding> bindings;
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
index 356d2ab7a..81550bc96 100644
--- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
+++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
@@ -2075,48 +2075,42 @@ private:
2075 return {}; 2075 return {};
2076 } 2076 }
2077 2077
2078 void AlphaTest(const Id& pointer) { 2078 void AlphaTest(Id pointer) {
2079 const Id true_label = OpLabel(); 2079 const Id true_label = OpLabel();
2080 const Id skip_label = OpLabel(); 2080 const Id skip_label = OpLabel();
2081 const Id alpha_reference = Constant(t_float, specialization.alpha_test_ref);
2082 const Id alpha_value = OpLoad(t_float, pointer);
2081 Id condition; 2083 Id condition;
2084 using Compare = Maxwell::ComparisonOp;
2082 switch (specialization.alpha_test_func) { 2085 switch (specialization.alpha_test_func) {
2083 case VK_COMPARE_OP_NEVER: 2086 case Compare::NeverOld:
2084 condition = Constant(t_float, false); // Never true 2087 condition = v_false; // Never true
2085 break; 2088 break;
2086 case VK_COMPARE_OP_LESS: 2089 case Compare::LessOld:
2087 condition = OpFOrdLessThan(t_bool, Constant(t_float, specialization.alpha_test_ref), 2090 condition = OpFOrdLessThan(t_bool, alpha_reference, alpha_value);
2088 OpLoad(t_float, pointer));
2089 break; 2091 break;
2090 case VK_COMPARE_OP_EQUAL: 2092 case Compare::EqualOld:
2091 condition = OpFOrdEqual(t_bool, Constant(t_float, specialization.alpha_test_ref), 2093 condition = OpFOrdEqual(t_bool, alpha_reference, alpha_value);
2092 OpLoad(t_float, pointer));
2093 break; 2094 break;
2094 case VK_COMPARE_OP_LESS_OR_EQUAL: 2095 case Compare::LessEqualOld:
2095 condition = OpFOrdLessThanEqual( 2096 condition = OpFOrdLessThanEqual(t_bool, alpha_reference, alpha_value);
2096 t_bool, Constant(t_float, specialization.alpha_test_ref), OpLoad(t_float, pointer));
2097 break; 2097 break;
2098 case VK_COMPARE_OP_GREATER: 2098 case Compare::GreaterOld:
2099 // Note: requires "Equal" to properly work for ssbu. perhaps a precision issue 2099 // Note: requires "Equal" to properly work for ssbu. perhaps a precision issue
2100 condition = OpFOrdGreaterThanEqual( 2100 condition = OpFOrdGreaterThanEqual(t_bool, alpha_reference, alpha_value);
2101 t_bool, Constant(t_float, specialization.alpha_test_ref), OpLoad(t_float, pointer));
2102 break; 2101 break;
2103 case VK_COMPARE_OP_NOT_EQUAL: 2102 case Compare::NotEqualOld:
2104 // Note: not accurate when tested against a unit test 2103 // Note: not accurate when tested against a unit test
2105 // TODO: confirm if used by games 2104 // TODO: confirm if used by games
2106 condition = OpFOrdNotEqual(t_bool, Constant(t_float, specialization.alpha_test_ref), 2105 condition = OpFOrdNotEqual(t_bool, alpha_reference, alpha_value);
2107 OpLoad(t_float, pointer));
2108 break; 2106 break;
2109 case VK_COMPARE_OP_GREATER_OR_EQUAL: 2107 case Compare::GreaterEqualOld:
2110 condition = OpFOrdGreaterThanEqual( 2108 condition = OpFOrdGreaterThanEqual(t_bool, alpha_reference, alpha_value);
2111 t_bool, Constant(t_float, specialization.alpha_test_ref), OpLoad(t_float, pointer));
2112 break;
2113 case VK_COMPARE_OP_ALWAYS:
2114 condition = Constant(t_bool, true); // Always true
2115 break; 2109 break;
2110 case Compare::AlwaysOld:
2111 return;
2116 default: 2112 default:
2117 LOG_WARNING(Render_Vulkan, "Unimplemented alpha test function"); 2113 UNREACHABLE();
2118 condition = Constant(t_bool, true); // Always true
2119 break;
2120 } 2114 }
2121 OpBranchConditional(condition, true_label, skip_label); 2115 OpBranchConditional(condition, true_label, skip_label);
2122 AddLabel(true_label); 2116 AddLabel(true_label);
@@ -2157,7 +2151,7 @@ private:
2157 } 2151 }
2158 const Id pointer = AccessElement(t_out_float, frag_colors[rt], component); 2152 const Id pointer = AccessElement(t_out_float, frag_colors[rt], component);
2159 OpStore(pointer, SafeGetRegister(current_reg)); 2153 OpStore(pointer, SafeGetRegister(current_reg));
2160 if (specialization.alpha_test_enabled && component == 3) { 2154 if (rt == 0 && component == 3) {
2161 AlphaTest(pointer); 2155 AlphaTest(pointer);
2162 } 2156 }
2163 ++current_reg; 2157 ++current_reg;
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.h b/src/video_core/renderer_vulkan/vk_shader_decompiler.h
index ddbcb0b41..cd3d0a415 100644
--- a/src/video_core/renderer_vulkan/vk_shader_decompiler.h
+++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.h
@@ -95,9 +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 bool alpha_test_enabled{};
99 float alpha_test_ref{}; 98 float alpha_test_ref{};
100 u8 alpha_test_func{}; 99 Maxwell::ComparisonOp alpha_test_func{};
101}; 100};
102// Old gcc versions don't consider this trivially copyable. 101// Old gcc versions don't consider this trivially copyable.
103// static_assert(std::is_trivially_copyable_v<Specialization>); 102// static_assert(std::is_trivially_copyable_v<Specialization>);