forked from suyu/suyu
spirv: Implement alpha test
This commit is contained in:
parent
b126987c59
commit
6c512f4bff
3 changed files with 95 additions and 1 deletions
|
@ -37,6 +37,48 @@ Id DefaultVarying(EmitContext& ctx, u32 num_components, u32 element, Id zero, Id
|
||||||
}
|
}
|
||||||
throw InvalidArgument("Bad element");
|
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
|
} // Anonymous namespace
|
||||||
|
|
||||||
void EmitPrologue(EmitContext& ctx) {
|
void EmitPrologue(EmitContext& ctx) {
|
||||||
|
@ -68,6 +110,9 @@ void EmitEpilogue(EmitContext& ctx) {
|
||||||
if (ctx.stage == Stage::VertexB && ctx.profile.convert_depth_mode) {
|
if (ctx.stage == Stage::VertexB && ctx.profile.convert_depth_mode) {
|
||||||
ConvertDepthMode(ctx);
|
ConvertDepthMode(ctx);
|
||||||
}
|
}
|
||||||
|
if (ctx.stage == Stage::Fragment) {
|
||||||
|
AlphaTest(ctx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitEmitVertex(EmitContext& ctx, const IR::Value& stream) {
|
void EmitEmitVertex(EmitContext& ctx, const IR::Value& stream) {
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <vector>
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
|
@ -27,6 +27,17 @@ enum class InputTopology {
|
||||||
TrianglesAdjacency,
|
TrianglesAdjacency,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class CompareFunction {
|
||||||
|
Never,
|
||||||
|
Less,
|
||||||
|
Equal,
|
||||||
|
LessThanEqual,
|
||||||
|
Greater,
|
||||||
|
NotEqual,
|
||||||
|
GreaterThanEqual,
|
||||||
|
Always,
|
||||||
|
};
|
||||||
|
|
||||||
struct TransformFeedbackVarying {
|
struct TransformFeedbackVarying {
|
||||||
u32 buffer{};
|
u32 buffer{};
|
||||||
u32 stride{};
|
u32 stride{};
|
||||||
|
@ -66,6 +77,8 @@ struct Profile {
|
||||||
InputTopology input_topology{};
|
InputTopology input_topology{};
|
||||||
|
|
||||||
std::optional<float> fixed_state_point_size;
|
std::optional<float> fixed_state_point_size;
|
||||||
|
std::optional<CompareFunction> alpha_test_func;
|
||||||
|
float alpha_test_reference{};
|
||||||
|
|
||||||
std::vector<TransformFeedbackVarying> xfb_varyings;
|
std::vector<TransformFeedbackVarying> xfb_varyings;
|
||||||
};
|
};
|
||||||
|
|
|
@ -492,6 +492,37 @@ private:
|
||||||
u32 read_lowest{};
|
u32 read_lowest{};
|
||||||
u32 read_highest{};
|
u32 read_highest{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Shader::CompareFunction MaxwellToCompareFunction(Maxwell::ComparisonOp comparison) {
|
||||||
|
switch (comparison) {
|
||||||
|
case Maxwell::ComparisonOp::Never:
|
||||||
|
case Maxwell::ComparisonOp::NeverOld:
|
||||||
|
return Shader::CompareFunction::Never;
|
||||||
|
case Maxwell::ComparisonOp::Less:
|
||||||
|
case Maxwell::ComparisonOp::LessOld:
|
||||||
|
return Shader::CompareFunction::Less;
|
||||||
|
case Maxwell::ComparisonOp::Equal:
|
||||||
|
case Maxwell::ComparisonOp::EqualOld:
|
||||||
|
return Shader::CompareFunction::Equal;
|
||||||
|
case Maxwell::ComparisonOp::LessEqual:
|
||||||
|
case Maxwell::ComparisonOp::LessEqualOld:
|
||||||
|
return Shader::CompareFunction::LessThanEqual;
|
||||||
|
case Maxwell::ComparisonOp::Greater:
|
||||||
|
case Maxwell::ComparisonOp::GreaterOld:
|
||||||
|
return Shader::CompareFunction::Greater;
|
||||||
|
case Maxwell::ComparisonOp::NotEqual:
|
||||||
|
case Maxwell::ComparisonOp::NotEqualOld:
|
||||||
|
return Shader::CompareFunction::NotEqual;
|
||||||
|
case Maxwell::ComparisonOp::GreaterEqual:
|
||||||
|
case Maxwell::ComparisonOp::GreaterEqualOld:
|
||||||
|
return Shader::CompareFunction::GreaterThanEqual;
|
||||||
|
case Maxwell::ComparisonOp::Always:
|
||||||
|
case Maxwell::ComparisonOp::AlwaysOld:
|
||||||
|
return Shader::CompareFunction::Always;
|
||||||
|
}
|
||||||
|
UNIMPLEMENTED_MSG("Unimplemented comparison op={}", comparison);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading,
|
void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading,
|
||||||
|
@ -1016,6 +1047,11 @@ Shader::Profile PipelineCache::MakeProfile(const GraphicsPipelineCacheKey& key,
|
||||||
}
|
}
|
||||||
profile.convert_depth_mode = gl_ndc;
|
profile.convert_depth_mode = gl_ndc;
|
||||||
break;
|
break;
|
||||||
|
case Shader::Stage::Fragment:
|
||||||
|
profile.alpha_test_func = MaxwellToCompareFunction(
|
||||||
|
key.state.UnpackComparisonOp(key.state.alpha_test_func.Value()));
|
||||||
|
profile.alpha_test_reference = Common::BitCast<float>(key.state.alpha_test_ref);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue