diff options
author | ameerj <52414509+ameerj@users.noreply.github.com> | 2021-04-14 06:32:18 +0200 |
---|---|---|
committer | ameerj <52414509+ameerj@users.noreply.github.com> | 2021-07-23 03:51:27 +0200 |
commit | 6c512f4bffde6bd8e4dbc74ed27cc84cd7fffadb (patch) | |
tree | 600283ca680de2c1efc2fd14bd24ca9862ccf125 /src/shader_recompiler | |
parent | shader: Implement transform feedbacks and define file format (diff) | |
download | yuzu-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.cpp | 45 | ||||
-rw-r--r-- | src/shader_recompiler/profile.h | 15 |
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; }; |