summaryrefslogtreecommitdiffstats
path: root/src/shader_recompiler
diff options
context:
space:
mode:
authorameerj <52414509+ameerj@users.noreply.github.com>2021-04-14 06:32:18 +0200
committerameerj <52414509+ameerj@users.noreply.github.com>2021-07-23 03:51:27 +0200
commit6c512f4bffde6bd8e4dbc74ed27cc84cd7fffadb (patch)
tree600283ca680de2c1efc2fd14bd24ca9862ccf125 /src/shader_recompiler
parentshader: Implement transform feedbacks and define file format (diff)
downloadyuzu-6c512f4bffde6bd8e4dbc74ed27cc84cd7fffadb.tar
yuzu-6c512f4bffde6bd8e4dbc74ed27cc84cd7fffadb.tar.gz
yuzu-6c512f4bffde6bd8e4dbc74ed27cc84cd7fffadb.tar.bz2
yuzu-6c512f4bffde6bd8e4dbc74ed27cc84cd7fffadb.tar.lz
yuzu-6c512f4bffde6bd8e4dbc74ed27cc84cd7fffadb.tar.xz
yuzu-6c512f4bffde6bd8e4dbc74ed27cc84cd7fffadb.tar.zst
yuzu-6c512f4bffde6bd8e4dbc74ed27cc84cd7fffadb.zip
Diffstat (limited to 'src/shader_recompiler')
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_special.cpp45
-rw-r--r--src/shader_recompiler/profile.h15
2 files changed, 59 insertions, 1 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp
index 7af29e4dd..8bb94f546 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp
@@ -37,6 +37,48 @@ Id DefaultVarying(EmitContext& ctx, u32 num_components, u32 element, Id zero, Id
}
throw InvalidArgument("Bad element");
}
+
+Id ComparisonFunction(EmitContext& ctx, CompareFunction comparison, Id operand_1, Id operand_2) {
+ switch (comparison) {
+ case CompareFunction::Never:
+ return ctx.false_value;
+ case CompareFunction::Less:
+ return ctx.OpFOrdLessThan(ctx.U1, operand_1, operand_2);
+ case CompareFunction::Equal:
+ return ctx.OpFOrdEqual(ctx.U1, operand_1, operand_2);
+ case CompareFunction::LessThanEqual:
+ return ctx.OpFOrdLessThanEqual(ctx.U1, operand_1, operand_2);
+ case CompareFunction::Greater:
+ return ctx.OpFOrdGreaterThan(ctx.U1, operand_1, operand_2);
+ case CompareFunction::NotEqual:
+ return ctx.OpFOrdNotEqual(ctx.U1, operand_1, operand_2);
+ case CompareFunction::GreaterThanEqual:
+ return ctx.OpFOrdGreaterThanEqual(ctx.U1, operand_1, operand_2);
+ case CompareFunction::Always:
+ return ctx.true_value;
+ }
+ throw InvalidArgument("Comparison function {}", comparison);
+}
+
+void AlphaTest(EmitContext& ctx) {
+ const auto comparison{*ctx.profile.alpha_test_func};
+ if (comparison == CompareFunction::Always) {
+ return;
+ }
+ const Id type{ctx.F32[1]};
+ const Id rt0_color{ctx.OpLoad(ctx.F32[4], ctx.frag_color[0])};
+ const Id alpha{ctx.OpCompositeExtract(type, rt0_color, 3u)};
+
+ const Id true_label{ctx.OpLabel()};
+ const Id discard_label{ctx.OpLabel()};
+ const Id alpha_reference{ctx.Constant(ctx.F32[1], ctx.profile.alpha_test_reference)};
+ const Id condition{ComparisonFunction(ctx, comparison, alpha, alpha_reference)};
+
+ ctx.OpBranchConditional(condition, true_label, discard_label);
+ ctx.AddLabel(discard_label);
+ ctx.OpKill();
+ ctx.AddLabel(true_label);
+}
} // Anonymous namespace
void EmitPrologue(EmitContext& ctx) {
@@ -68,6 +110,9 @@ void EmitEpilogue(EmitContext& ctx) {
if (ctx.stage == Stage::VertexB && ctx.profile.convert_depth_mode) {
ConvertDepthMode(ctx);
}
+ if (ctx.stage == Stage::Fragment) {
+ AlphaTest(ctx);
+ }
}
void EmitEmitVertex(EmitContext& ctx, const IR::Value& stream) {
diff --git a/src/shader_recompiler/profile.h b/src/shader_recompiler/profile.h
index 5ecae71b9..c26017d75 100644
--- a/src/shader_recompiler/profile.h
+++ b/src/shader_recompiler/profile.h
@@ -5,8 +5,8 @@
#pragma once
#include <array>
-#include <vector>
#include <optional>
+#include <vector>
#include "common/common_types.h"
@@ -27,6 +27,17 @@ enum class InputTopology {
TrianglesAdjacency,
};
+enum class CompareFunction {
+ Never,
+ Less,
+ Equal,
+ LessThanEqual,
+ Greater,
+ NotEqual,
+ GreaterThanEqual,
+ Always,
+};
+
struct TransformFeedbackVarying {
u32 buffer{};
u32 stride{};
@@ -66,6 +77,8 @@ struct Profile {
InputTopology input_topology{};
std::optional<float> fixed_state_point_size;
+ std::optional<CompareFunction> alpha_test_func;
+ float alpha_test_reference{};
std::vector<TransformFeedbackVarying> xfb_varyings;
};