summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorameerj <aj662@drexel.edu>2020-11-19 08:25:37 +0100
committerameerj <aj662@drexel.edu>2020-11-25 04:46:45 +0100
commit1dbf71ceb3b84691101228a2981cafed477b27e9 (patch)
treeec6f0d2a7cd22e9d17f5379a5134cbb37e101601 /src
parentvulkan_renderer: Alpha Test Culling Implementation (diff)
downloadyuzu-1dbf71ceb3b84691101228a2981cafed477b27e9.tar
yuzu-1dbf71ceb3b84691101228a2981cafed477b27e9.tar.gz
yuzu-1dbf71ceb3b84691101228a2981cafed477b27e9.tar.bz2
yuzu-1dbf71ceb3b84691101228a2981cafed477b27e9.tar.lz
yuzu-1dbf71ceb3b84691101228a2981cafed477b27e9.tar.xz
yuzu-1dbf71ceb3b84691101228a2981cafed477b27e9.tar.zst
yuzu-1dbf71ceb3b84691101228a2981cafed477b27e9.zip
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
topology.Assign(regs.draw.topology);
alpha_raw = 0;
- alpha_test_enabled.Assign(regs.alpha_test_enabled);
- alpha_test_func.Assign(PackComparisonOp(regs.alpha_test_func));
+ const auto test_func =
+ regs.alpha_test_enabled == 1 ? regs.alpha_test_func : Maxwell::ComparisonOp::Always;
+ alpha_test_func.Assign(PackComparisonOp(test_func));
std::memcpy(&alpha_test_ref, &regs.alpha_test_ref, sizeof(u32)); // TODO: C++20 std::bit_cast
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 {
BitField<24, 4, Maxwell::PrimitiveTopology> topology;
};
- u32 alpha_test_ref; /// < Alpha test reference
+ u32 alpha_test_ref; ///< Alpha test reference value
union {
u32 alpha_raw;
BitField<0, 3, u32> alpha_test_func;
- BitField<3, 1, u32> alpha_test_enabled;
};
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) {
specialization.ndc_minus_one_to_one = fixed_state.ndc_minus_one_to_one;
// Alpha test
- if (fixed_state.alpha_test_enabled == 1) {
- specialization.alpha_test_enabled = true;
- specialization.alpha_test_func = static_cast<u8>(fixed_state.alpha_test_func);
- // memcpy from u32 to float TODO: C++20 std::bit_cast
- std::memcpy(&specialization.alpha_test_ref, &fixed_state.alpha_test_ref, sizeof(float));
- }
+ specialization.alpha_test_func =
+ FixedPipelineState::UnpackComparisonOp(fixed_state.alpha_test_func.Value());
+ // memcpy from u32 to float TODO: C++20 std::bit_cast
+ std::memcpy(&specialization.alpha_test_ref, &fixed_state.alpha_test_ref, sizeof(float));
SPIRVProgram program;
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:
return {};
}
- void AlphaTest(const Id& pointer) {
+ void AlphaTest(Id pointer) {
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;
switch (specialization.alpha_test_func) {
- case VK_COMPARE_OP_NEVER:
- condition = Constant(t_float, false); // Never true
+ case Compare::NeverOld:
+ condition = v_false; // Never true
break;
- case VK_COMPARE_OP_LESS:
- condition = OpFOrdLessThan(t_bool, Constant(t_float, specialization.alpha_test_ref),
- OpLoad(t_float, pointer));
+ case Compare::LessOld:
+ condition = OpFOrdLessThan(t_bool, alpha_reference, alpha_value);
break;
- case VK_COMPARE_OP_EQUAL:
- condition = OpFOrdEqual(t_bool, Constant(t_float, specialization.alpha_test_ref),
- OpLoad(t_float, pointer));
+ case Compare::EqualOld:
+ condition = OpFOrdEqual(t_bool, alpha_reference, alpha_value);
break;
- case VK_COMPARE_OP_LESS_OR_EQUAL:
- condition = OpFOrdLessThanEqual(
- t_bool, Constant(t_float, specialization.alpha_test_ref), OpLoad(t_float, pointer));
+ case Compare::LessEqualOld:
+ condition = OpFOrdLessThanEqual(t_bool, alpha_reference, alpha_value);
break;
- case VK_COMPARE_OP_GREATER:
+ case Compare::GreaterOld:
// Note: requires "Equal" to properly work for ssbu. perhaps a precision issue
- condition = OpFOrdGreaterThanEqual(
- t_bool, Constant(t_float, specialization.alpha_test_ref), OpLoad(t_float, pointer));
+ condition = OpFOrdGreaterThanEqual(t_bool, alpha_reference, alpha_value);
break;
- case VK_COMPARE_OP_NOT_EQUAL:
+ case Compare::NotEqualOld:
// Note: not accurate when tested against a unit test
// TODO: confirm if used by games
- condition = OpFOrdNotEqual(t_bool, Constant(t_float, specialization.alpha_test_ref),
- OpLoad(t_float, pointer));
+ condition = OpFOrdNotEqual(t_bool, alpha_reference, alpha_value);
break;
- case VK_COMPARE_OP_GREATER_OR_EQUAL:
- condition = OpFOrdGreaterThanEqual(
- t_bool, Constant(t_float, specialization.alpha_test_ref), OpLoad(t_float, pointer));
- break;
- case VK_COMPARE_OP_ALWAYS:
- condition = Constant(t_bool, true); // Always true
+ case Compare::GreaterEqualOld:
+ condition = OpFOrdGreaterThanEqual(t_bool, alpha_reference, alpha_value);
break;
+ case Compare::AlwaysOld:
+ return;
default:
- LOG_WARNING(Render_Vulkan, "Unimplemented alpha test function");
- condition = Constant(t_bool, true); // Always true
- break;
+ UNREACHABLE();
}
OpBranchConditional(condition, true_label, skip_label);
AddLabel(true_label);
@@ -2157,7 +2151,7 @@ private:
}
const Id pointer = AccessElement(t_out_float, frag_colors[rt], component);
OpStore(pointer, SafeGetRegister(current_reg));
- if (specialization.alpha_test_enabled && component == 3) {
+ if (rt == 0 && component == 3) {
AlphaTest(pointer);
}
++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 {
std::bitset<Maxwell::NumVertexAttributes> enabled_attributes;
std::array<Maxwell::VertexAttribute::Type, Maxwell::NumVertexAttributes> attribute_types{};
bool ndc_minus_one_to_one{};
- bool alpha_test_enabled{};
float alpha_test_ref{};
- u8 alpha_test_func{};
+ Maxwell::ComparisonOp alpha_test_func{};
};
// Old gcc versions don't consider this trivially copyable.
// static_assert(std::is_trivially_copyable_v<Specialization>);