diff options
Diffstat (limited to 'src')
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, ®s.alpha_test_ref, sizeof(u32)); // TODO: C++20 std::bit_cast | 67 | std::memcpy(&alpha_test_ref, ®s.alpha_test_ref, sizeof(u32)); // TODO: C++20 std::bit_cast |
| 67 | 68 | ||
| 68 | std::memcpy(&point_size, ®s.point_size, sizeof(point_size)); // TODO: C++20 std::bit_cast | 69 | std::memcpy(&point_size, ®s.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>); |