From 8b145a6c89dcdb4ec28173339dd176fb7b6f43ed Mon Sep 17 00:00:00 2001 From: asuonpaa <34128694+asuonpaa@users.noreply.github.com> Date: Thu, 21 Apr 2022 11:17:13 +0300 Subject: Add depth compare support for samplers (#987) --- docs/amber_script.md | 16 ++++++++++++++-- src/amberscript/parser.cc | 24 ++++++++++++++++++++++++ src/amberscript/parser_sampler_test.cc | 8 +++++++- src/sampler.h | 11 +++++++++++ src/vulkan/sampler.cc | 28 ++++++++++++++++++++++++++++ 5 files changed, 84 insertions(+), 3 deletions(-) diff --git a/docs/amber_script.md b/docs/amber_script.md index 7c78d82..9bd58d7 100644 --- a/docs/amber_script.md +++ b/docs/amber_script.md @@ -350,9 +350,19 @@ sampled image or combined image sampler. * `float_opaque_white` * `int_opaque_white` +#### Compare operations +* `never` +* `less` +* `equal` +* `less_or_equal` +* `greater` +* `not_equal` +* `greater_or_equal` +* `always` + ```groovy -# Creates a sampler with |name|. +# Creates a sampler with |name|. |compare_enable| is either on or off. SAMPLER {name} \ [ MAG_FILTER {filter_type} (default nearest) ] \ [ MIN_FILTER {filter_type} (default nearest) ] \ @@ -362,7 +372,9 @@ SAMPLER {name} \ [ BORDER_COLOR {border_color} (default float_transparent_black) ] \ [ MIN_LOD _val_ (default 0.0) ] \ [ MAX_LOD _val_ (default 1.0) ] \ - [ NORMALIZED_COORDS | UNNORMALIZED_COORDS (default NORMALIZED_COORDS) ] + [ NORMALIZED_COORDS | UNNORMALIZED_COORDS (default NORMALIZED_COORDS) ] \ + [ COMPARE _compare_enable_ (default off) ] \ + [ COMPARE_OP _compare_op_ (default never) ] ``` Note: unnormalized coordinates will override MIN\_LOD and MAX\_LOD to 0.0. diff --git a/src/amberscript/parser.cc b/src/amberscript/parser.cc index d3e0eb6..8cd6e19 100644 --- a/src/amberscript/parser.cc +++ b/src/amberscript/parser.cc @@ -3893,6 +3893,30 @@ Result Parser::ParseSampler() { sampler->SetNormalizedCoords(false); sampler->SetMinLOD(0.0f); sampler->SetMaxLOD(0.0f); + } else if (param == "COMPARE") { + token = tokenizer_->NextToken(); + + if (!token->IsIdentifier()) + return Result("invalid value for COMPARE"); + + if (token->AsString() == "on") + sampler->SetCompareEnable(true); + else if (token->AsString() == "off") + sampler->SetCompareEnable(false); + else + return Result("invalid value for COMPARE: " + token->AsString()); + } else if (param == "COMPARE_OP") { + token = tokenizer_->NextToken(); + + if (!token->IsIdentifier()) + return Result("invalid value for COMPARE_OP"); + + CompareOp compare_op = StrToCompareOp(token->AsString()); + if (compare_op != CompareOp::kUnknown) { + sampler->SetCompareOp(compare_op); + } else { + return Result("invalid value for COMPARE_OP: " + token->AsString()); + } } else { return Result("unexpected sampler parameter " + param); } diff --git a/src/amberscript/parser_sampler_test.cc b/src/amberscript/parser_sampler_test.cc index 6cba69d..d4b0dd1 100644 --- a/src/amberscript/parser_sampler_test.cc +++ b/src/amberscript/parser_sampler_test.cc @@ -45,6 +45,8 @@ TEST_F(AmberScriptParserTest, SamplerDefaultValues) { EXPECT_EQ(0.0, sampler->GetMinLOD()); EXPECT_EQ(1.0, sampler->GetMaxLOD()); EXPECT_EQ(true, sampler->GetNormalizedCoords()); + EXPECT_EQ(false, sampler->GetCompareEnable()); + EXPECT_EQ(CompareOp::kNever, sampler->GetCompareOp()); } TEST_F(AmberScriptParserTest, SamplerCustomValues) { @@ -57,7 +59,9 @@ SAMPLER sampler MAG_FILTER linear \ BORDER_COLOR float_opaque_white \ MIN_LOD 2.5 \ MAX_LOD 5.0 \ - NORMALIZED_COORDS)"; + NORMALIZED_COORDS \ + COMPARE on \ + COMPARE_OP greater)"; Parser parser; Result r = parser.Parse(in); @@ -81,6 +85,8 @@ SAMPLER sampler MAG_FILTER linear \ EXPECT_EQ(2.5, sampler->GetMinLOD()); EXPECT_EQ(5.0, sampler->GetMaxLOD()); EXPECT_EQ(true, sampler->GetNormalizedCoords()); + EXPECT_EQ(true, sampler->GetCompareEnable()); + EXPECT_EQ(CompareOp::kGreater, sampler->GetCompareOp()); } TEST_F(AmberScriptParserTest, SamplerUnexpectedParameter) { diff --git a/src/sampler.h b/src/sampler.h index c44316a..f16e4cd 100644 --- a/src/sampler.h +++ b/src/sampler.h @@ -23,6 +23,7 @@ #include "amber/result.h" #include "amber/value.h" +#include "src/command_data.h" #include "src/format.h" namespace amber { @@ -86,6 +87,14 @@ class Sampler { void SetNormalizedCoords(bool norm) { normalized_coords_ = norm; } bool GetNormalizedCoords() const { return normalized_coords_; } + void SetCompareEnable(bool compare_enable) { + compare_enable_ = compare_enable; + } + bool GetCompareEnable() const { return compare_enable_; } + + void SetCompareOp(CompareOp compare_op) { compare_op_ = compare_op; } + CompareOp GetCompareOp() const { return compare_op_; } + private: std::string name_; FilterType min_filter_ = FilterType::kNearest; @@ -98,6 +107,8 @@ class Sampler { float min_lod_ = 0.0f; float max_lod_ = 1.0f; bool normalized_coords_ = true; + bool compare_enable_ = false; + CompareOp compare_op_ = CompareOp::kNever; }; } // namespace amber diff --git a/src/vulkan/sampler.cc b/src/vulkan/sampler.cc index 979c098..c8995e8 100644 --- a/src/vulkan/sampler.cc +++ b/src/vulkan/sampler.cc @@ -52,6 +52,31 @@ VkBorderColor GetVkBorderColor(BorderColor color) { } } +VkCompareOp ToVkCompareOp(CompareOp op) { + switch (op) { + case CompareOp::kNever: + return VK_COMPARE_OP_NEVER; + case CompareOp::kLess: + return VK_COMPARE_OP_LESS; + case CompareOp::kEqual: + return VK_COMPARE_OP_EQUAL; + case CompareOp::kLessOrEqual: + return VK_COMPARE_OP_LESS_OR_EQUAL; + case CompareOp::kGreater: + return VK_COMPARE_OP_GREATER; + case CompareOp::kNotEqual: + return VK_COMPARE_OP_NOT_EQUAL; + case CompareOp::kGreaterOrEqual: + return VK_COMPARE_OP_GREATER_OR_EQUAL; + case CompareOp::kAlways: + return VK_COMPARE_OP_ALWAYS; + case CompareOp::kUnknown: + break; + } + assert(false && "Vulkan::Unknown CompareOp"); + return VK_COMPARE_OP_NEVER; +} + } // namespace Sampler::Sampler(Device* device) : device_(device) {} @@ -76,6 +101,9 @@ Result Sampler::CreateSampler(amber::Sampler* sampler) { sampler_info.maxLod = sampler->GetMaxLOD(); sampler_info.unnormalizedCoordinates = (sampler->GetNormalizedCoords() ? VK_FALSE : VK_TRUE); + sampler_info.compareEnable = + (sampler->GetCompareEnable() ? VK_TRUE : VK_FALSE); + sampler_info.compareOp = ToVkCompareOp(sampler->GetCompareOp()); if (device_->GetPtrs()->vkCreateSampler(device_->GetVkDevice(), &sampler_info, nullptr, &sampler_) != VK_SUCCESS) { -- cgit v1.2.3