diff options
author | gnl21 <gnl021@gmail.com> | 2021-03-16 14:14:57 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-16 14:14:57 +0000 |
commit | dd917bb97dd1a2957ca3e5d2d75f463e5ac91caa (patch) | |
tree | b4c39043f47908ee868a4590252459b86bf2f4e2 | |
parent | dabae26164714abf951c6815a2b4513260f7c6a4 (diff) | |
download | amber-dd917bb97dd1a2957ca3e5d2d75f463e5ac91caa.tar.gz |
Add VIEWPORT to AmberScript (#944)
This allows setting the viewport for graphics pipelines.
-rw-r--r-- | docs/amber_script.md | 6 | ||||
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/amberscript/parser.cc | 71 | ||||
-rw-r--r-- | src/amberscript/parser.h | 1 | ||||
-rw-r--r-- | src/amberscript/parser_viewport_test.cc | 388 | ||||
-rw-r--r-- | src/pipeline_data.h | 20 | ||||
-rw-r--r-- | src/vulkan/graphics_pipeline.cc | 10 | ||||
-rw-r--r-- | tests/cases/viewport.amber | 59 | ||||
-rw-r--r-- | tests/cases/viewport_depth.amber | 61 |
9 files changed, 617 insertions, 0 deletions
diff --git a/docs/amber_script.md b/docs/amber_script.md index 57e0632..3d88b5a 100644 --- a/docs/amber_script.md +++ b/docs/amber_script.md @@ -485,6 +485,12 @@ The following commands are all specified within the `PIPELINE` command. ``` ```groovy + # Set the viewport size. If no viewport is provided then it defaults to the + # whole framebuffer size. Depth range defaults to 0 to 1. + VIEWPORT {x} {y} SIZE {width} {height} [MIN_DEPTH {mind}] [MAX_DEPTH {maxd}] +``` + +```groovy # Set subgroup size control setting. Require that subgroups must be launched # with all invocations active for given shader. Allow SubgroupSize to vary # for given shader. Require a specific SubgroupSize the for given shader. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 00e3e54..901681f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -159,6 +159,7 @@ if (${AMBER_ENABLE_TESTS}) amberscript/parser_struct_test.cc amberscript/parser_subgroup_size_control_test.cc amberscript/parser_test.cc + amberscript/parser_viewport_test.cc buffer_test.cc command_data_test.cc descriptor_set_and_binding_parser_test.cc diff --git a/src/amberscript/parser.cc b/src/amberscript/parser.cc index 50760f0..3b40d00 100644 --- a/src/amberscript/parser.cc +++ b/src/amberscript/parser.cc @@ -602,6 +602,8 @@ Result Parser::ParsePipelineBody(const std::string& cmd_name, r = ParsePipelineShaderOptimizations(pipeline.get()); } else if (tok == "FRAMEBUFFER_SIZE") { r = ParsePipelineFramebufferSize(pipeline.get()); + } else if (tok == "VIEWPORT") { + r = ParsePipelineViewport(pipeline.get()); } else if (tok == "BIND") { r = ParsePipelineBind(pipeline.get()); } else if (tok == "VERTEX_DATA") { @@ -949,6 +951,75 @@ Result Parser::ParsePipelineFramebufferSize(Pipeline* pipeline) { return ValidateEndOfStatement("FRAMEBUFFER_SIZE command"); } +Result Parser::ParsePipelineViewport(Pipeline* pipeline) { + Viewport vp; + vp.mind = 0.0f; + vp.maxd = 1.0f; + + float val[2]; + for (int i = 0; i < 2; i++) { + auto token = tokenizer_->NextToken(); + if (token->IsEOL() || token->IsEOS()) + return Result("missing offset for VIEWPORT command"); + Result r = token->ConvertToDouble(); + if (!r.IsSuccess()) + return Result("invalid offset for VIEWPORT command"); + + val[i] = token->AsFloat(); + } + vp.x = val[0]; + vp.y = val[1]; + + auto token = tokenizer_->NextToken(); + if (!token->IsIdentifier() || token->AsString() != "SIZE") + return Result("missing SIZE for VIEWPORT command"); + + for (int i = 0; i < 2; i++) { + token = tokenizer_->NextToken(); + if (token->IsEOL() || token->IsEOS()) + return Result("missing size for VIEWPORT command"); + Result r = token->ConvertToDouble(); + if (!r.IsSuccess()) + return Result("invalid size for VIEWPORT command"); + + val[i] = token->AsFloat(); + } + vp.w = val[0]; + vp.h = val[1]; + + token = tokenizer_->PeekNextToken(); + while (token->IsIdentifier()) { + if (token->AsString() == "MIN_DEPTH") { + tokenizer_->NextToken(); + token = tokenizer_->NextToken(); + if (token->IsEOL() || token->IsEOS()) + return Result("missing min_depth for VIEWPORT command"); + Result r = token->ConvertToDouble(); + if (!r.IsSuccess()) + return Result("invalid min_depth for VIEWPORT command"); + + vp.mind = token->AsFloat(); + } + if (token->AsString() == "MAX_DEPTH") { + tokenizer_->NextToken(); + token = tokenizer_->NextToken(); + if (token->IsEOL() || token->IsEOS()) + return Result("missing max_depth for VIEWPORT command"); + Result r = token->ConvertToDouble(); + if (!r.IsSuccess()) + return Result("invalid max_depth for VIEWPORT command"); + + vp.maxd = token->AsFloat(); + } + + token = tokenizer_->PeekNextToken(); + } + + pipeline->GetPipelineData()->SetViewport(vp); + + return ValidateEndOfStatement("VIEWPORT command"); +} + Result Parser::ToBufferType(const std::string& name, BufferType* type) { assert(type); if (name == "color") diff --git a/src/amberscript/parser.h b/src/amberscript/parser.h index e8cb835..6fb25ce 100644 --- a/src/amberscript/parser.h +++ b/src/amberscript/parser.h @@ -65,6 +65,7 @@ class Parser : public amber::Parser { Result ParsePipelineShaderCompileOptions(Pipeline*); Result ParsePipelineSubgroup(Pipeline* pipeline); Result ParsePipelineFramebufferSize(Pipeline*); + Result ParsePipelineViewport(Pipeline*); Result ParsePipelineBind(Pipeline*); Result ParsePipelineVertexData(Pipeline*); Result ParsePipelineIndexData(Pipeline*); diff --git a/src/amberscript/parser_viewport_test.cc b/src/amberscript/parser_viewport_test.cc new file mode 100644 index 0000000..ec19fb2 --- /dev/null +++ b/src/amberscript/parser_viewport_test.cc @@ -0,0 +1,388 @@ +// Copyright 2021 The Amber Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or parseried. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "gtest/gtest.h" +#include "src/amberscript/parser.h" + +namespace amber { +namespace amberscript { + +using AmberScriptParserTest = testing::Test; + +TEST_F(AmberScriptParserTest, NoViewport) { + std::string in = R"( +SHADER vertex my_shader PASSTHROUGH +SHADER fragment my_fragment GLSL +# GLSL Shader +END +BUFFER my_fb FORMAT R32G32B32A32_SFLOAT +BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT + +PIPELINE graphics my_pipeline + ATTACH my_shader + ATTACH my_fragment + BIND BUFFER my_fb AS color LOCATION 0 + BIND BUFFER my_ds AS depth_stencil +END)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_TRUE(r.IsSuccess()) << r.Error(); + + auto script = parser.GetScript(); + const auto& pipelines = script->GetPipelines(); + ASSERT_EQ(1U, pipelines.size()); + + auto* pipeline = pipelines[0].get(); + ASSERT_FALSE(pipeline->GetPipelineData()->HasViewportData()); +} + +TEST_F(AmberScriptParserTest, ViewportNoDepth) { + std::string in = R"( +SHADER vertex my_shader PASSTHROUGH +SHADER fragment my_fragment GLSL +# GLSL Shader +END +BUFFER my_fb FORMAT R32G32B32A32_SFLOAT +BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT + +PIPELINE graphics my_pipeline + ATTACH my_shader + ATTACH my_fragment + BIND BUFFER my_fb AS color LOCATION 0 + BIND BUFFER my_ds AS depth_stencil + + VIEWPORT 5.0 7.0 SIZE 10.0 12.0 +END)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_TRUE(r.IsSuccess()) << r.Error(); + + auto script = parser.GetScript(); + const auto& pipelines = script->GetPipelines(); + ASSERT_EQ(1U, pipelines.size()); + + auto* pipeline = pipelines[0].get(); + ASSERT_TRUE(pipeline->GetPipelineData()->HasViewportData()); + ASSERT_FLOAT_EQ(5.0f, pipeline->GetPipelineData()->GetViewport().x); + ASSERT_FLOAT_EQ(7.0f, pipeline->GetPipelineData()->GetViewport().y); + ASSERT_FLOAT_EQ(10.0f, pipeline->GetPipelineData()->GetViewport().w); + ASSERT_FLOAT_EQ(12.0f, pipeline->GetPipelineData()->GetViewport().h); + ASSERT_FLOAT_EQ(0.0f, pipeline->GetPipelineData()->GetViewport().mind); + ASSERT_FLOAT_EQ(1.0f, pipeline->GetPipelineData()->GetViewport().maxd); +} + +TEST_F(AmberScriptParserTest, ViewportMinDepth) { + std::string in = R"( +SHADER vertex my_shader PASSTHROUGH +SHADER fragment my_fragment GLSL +# GLSL Shader +END +BUFFER my_fb FORMAT R32G32B32A32_SFLOAT +BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT + +PIPELINE graphics my_pipeline + ATTACH my_shader + ATTACH my_fragment + BIND BUFFER my_fb AS color LOCATION 0 + BIND BUFFER my_ds AS depth_stencil + + VIEWPORT 12.2 9.7 SIZE 0.5 106.1 MIN_DEPTH 0.3 +END)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_TRUE(r.IsSuccess()) << r.Error(); + + auto script = parser.GetScript(); + const auto& pipelines = script->GetPipelines(); + ASSERT_EQ(1U, pipelines.size()); + + auto* pipeline = pipelines[0].get(); + ASSERT_TRUE(pipeline->GetPipelineData()->HasViewportData()); + ASSERT_FLOAT_EQ(12.2f, pipeline->GetPipelineData()->GetViewport().x); + ASSERT_FLOAT_EQ(9.7f, pipeline->GetPipelineData()->GetViewport().y); + ASSERT_FLOAT_EQ(0.5f, pipeline->GetPipelineData()->GetViewport().w); + ASSERT_FLOAT_EQ(106.1f, pipeline->GetPipelineData()->GetViewport().h); + ASSERT_FLOAT_EQ(0.3f, pipeline->GetPipelineData()->GetViewport().mind); + ASSERT_FLOAT_EQ(1.0f, pipeline->GetPipelineData()->GetViewport().maxd); +} + +TEST_F(AmberScriptParserTest, ViewportMaxDepth) { + std::string in = R"( +SHADER vertex my_shader PASSTHROUGH +SHADER fragment my_fragment GLSL +# GLSL Shader +END +BUFFER my_fb FORMAT R32G32B32A32_SFLOAT +BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT + +PIPELINE graphics my_pipeline + ATTACH my_shader + ATTACH my_fragment + BIND BUFFER my_fb AS color LOCATION 0 + BIND BUFFER my_ds AS depth_stencil + + VIEWPORT 12.2 9.7 SIZE 0.5 106.1 MAX_DEPTH 0.456 +END)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_TRUE(r.IsSuccess()) << r.Error(); + + auto script = parser.GetScript(); + const auto& pipelines = script->GetPipelines(); + ASSERT_EQ(1U, pipelines.size()); + + auto* pipeline = pipelines[0].get(); + ASSERT_TRUE(pipeline->GetPipelineData()->HasViewportData()); + ASSERT_FLOAT_EQ(12.2f, pipeline->GetPipelineData()->GetViewport().x); + ASSERT_FLOAT_EQ(9.7f, pipeline->GetPipelineData()->GetViewport().y); + ASSERT_FLOAT_EQ(0.5f, pipeline->GetPipelineData()->GetViewport().w); + ASSERT_FLOAT_EQ(106.1f, pipeline->GetPipelineData()->GetViewport().h); + ASSERT_FLOAT_EQ(0.0f, pipeline->GetPipelineData()->GetViewport().mind); + ASSERT_FLOAT_EQ(0.456f, pipeline->GetPipelineData()->GetViewport().maxd); +} + +TEST_F(AmberScriptParserTest, ViewportAllValues) { + std::string in = R"( +SHADER vertex my_shader PASSTHROUGH +SHADER fragment my_fragment GLSL +# GLSL Shader +END +BUFFER my_fb FORMAT R32G32B32A32_SFLOAT +BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT + +PIPELINE graphics my_pipeline + ATTACH my_shader + ATTACH my_fragment + BIND BUFFER my_fb AS color LOCATION 0 + BIND BUFFER my_ds AS depth_stencil + + VIEWPORT -0.6 5.2 SIZE 13.8 9.4 MIN_DEPTH 0.5 MAX_DEPTH 0.6 +END)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_TRUE(r.IsSuccess()) << r.Error(); + + auto script = parser.GetScript(); + const auto& pipelines = script->GetPipelines(); + ASSERT_EQ(1U, pipelines.size()); + + auto* pipeline = pipelines[0].get(); + ASSERT_TRUE(pipeline->GetPipelineData()->HasViewportData()); + ASSERT_FLOAT_EQ(-0.6f, pipeline->GetPipelineData()->GetViewport().x); + ASSERT_FLOAT_EQ(5.2f, pipeline->GetPipelineData()->GetViewport().y); + ASSERT_FLOAT_EQ(13.8f, pipeline->GetPipelineData()->GetViewport().w); + ASSERT_FLOAT_EQ(9.4f, pipeline->GetPipelineData()->GetViewport().h); + ASSERT_FLOAT_EQ(0.5f, pipeline->GetPipelineData()->GetViewport().mind); + ASSERT_FLOAT_EQ(0.6f, pipeline->GetPipelineData()->GetViewport().maxd); +} + +TEST_F(AmberScriptParserTest, ViewportIntegers) { + std::string in = R"( +SHADER vertex my_shader PASSTHROUGH +SHADER fragment my_fragment GLSL +# GLSL Shader +END +BUFFER my_fb FORMAT R32G32B32A32_SFLOAT +BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT + +PIPELINE graphics my_pipeline + ATTACH my_shader + ATTACH my_fragment + BIND BUFFER my_fb AS color LOCATION 0 + BIND BUFFER my_ds AS depth_stencil + + VIEWPORT -2 7 SIZE 15 20 MIN_DEPTH 1 MAX_DEPTH 2 +END)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_TRUE(r.IsSuccess()) << r.Error(); + + auto script = parser.GetScript(); + const auto& pipelines = script->GetPipelines(); + ASSERT_EQ(1U, pipelines.size()); + + auto* pipeline = pipelines[0].get(); + ASSERT_TRUE(pipeline->GetPipelineData()->HasViewportData()); + ASSERT_FLOAT_EQ(-2.0f, pipeline->GetPipelineData()->GetViewport().x); + ASSERT_FLOAT_EQ(7.0f, pipeline->GetPipelineData()->GetViewport().y); + ASSERT_FLOAT_EQ(15.0f, pipeline->GetPipelineData()->GetViewport().w); + ASSERT_FLOAT_EQ(20.0f, pipeline->GetPipelineData()->GetViewport().h); + ASSERT_FLOAT_EQ(1.0f, pipeline->GetPipelineData()->GetViewport().mind); + ASSERT_FLOAT_EQ(2.0f, pipeline->GetPipelineData()->GetViewport().maxd); +} + +TEST_F(AmberScriptParserTest, ViewportMixedIntegers) { + std::string in = R"( +SHADER vertex my_shader PASSTHROUGH +SHADER fragment my_fragment GLSL +# GLSL Shader +END +BUFFER my_fb FORMAT R32G32B32A32_SFLOAT +BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT + +PIPELINE graphics my_pipeline + ATTACH my_shader + ATTACH my_fragment + BIND BUFFER my_fb AS color LOCATION 0 + BIND BUFFER my_ds AS depth_stencil + + VIEWPORT -2 13.1 SIZE 15.9 20 +END)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_TRUE(r.IsSuccess()) << r.Error(); + + auto script = parser.GetScript(); + const auto& pipelines = script->GetPipelines(); + ASSERT_EQ(1U, pipelines.size()); + + auto* pipeline = pipelines[0].get(); + ASSERT_TRUE(pipeline->GetPipelineData()->HasViewportData()); + ASSERT_FLOAT_EQ(-2.0f, pipeline->GetPipelineData()->GetViewport().x); + ASSERT_FLOAT_EQ(13.1f, pipeline->GetPipelineData()->GetViewport().y); + ASSERT_FLOAT_EQ(15.9f, pipeline->GetPipelineData()->GetViewport().w); + ASSERT_FLOAT_EQ(20.0f, pipeline->GetPipelineData()->GetViewport().h); + ASSERT_FLOAT_EQ(0.0f, pipeline->GetPipelineData()->GetViewport().mind); + ASSERT_FLOAT_EQ(1.0f, pipeline->GetPipelineData()->GetViewport().maxd); +} + +TEST_F(AmberScriptParserTest, ViewportInvalidMissingSize) { + std::string in = R"( +SHADER vertex my_shader PASSTHROUGH +SHADER fragment my_fragment GLSL +# GLSL Shader +END +BUFFER my_fb FORMAT R32G32B32A32_SFLOAT +BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT + +PIPELINE graphics my_pipeline + ATTACH my_shader + ATTACH my_fragment + BIND BUFFER my_fb AS color LOCATION 0 + BIND BUFFER my_ds AS depth_stencil + + VIEWPORT 0.0 2.0 12.0 24.0 +END)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()) << r.Error(); + EXPECT_EQ("15: missing SIZE for VIEWPORT command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ViewportInvalidSizeNotOptional) { + std::string in = R"( +SHADER vertex my_shader PASSTHROUGH +SHADER fragment my_fragment GLSL +# GLSL Shader +END +BUFFER my_fb FORMAT R32G32B32A32_SFLOAT +BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT + +PIPELINE graphics my_pipeline + ATTACH my_shader + ATTACH my_fragment + BIND BUFFER my_fb AS color LOCATION 0 + BIND BUFFER my_ds AS depth_stencil + + VIEWPORT 0.0 2.0 +END)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()) << r.Error(); + EXPECT_EQ("16: missing SIZE for VIEWPORT command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ViewportInvalidMissingOffset) { + std::string in = R"( +SHADER vertex my_shader PASSTHROUGH +SHADER fragment my_fragment GLSL +# GLSL Shader +END +BUFFER my_fb FORMAT R32G32B32A32_SFLOAT +BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT + +PIPELINE graphics my_pipeline + ATTACH my_shader + ATTACH my_fragment + BIND BUFFER my_fb AS color LOCATION 0 + BIND BUFFER my_ds AS depth_stencil + + VIEWPORT 0.0 SIZE 12.0 24.0 +END)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()) << r.Error(); + EXPECT_EQ("15: invalid offset for VIEWPORT command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ViewportInvalidMissingSizeValue) { + std::string in = R"( +SHADER vertex my_shader PASSTHROUGH +SHADER fragment my_fragment GLSL +# GLSL Shader +END +BUFFER my_fb FORMAT R32G32B32A32_SFLOAT +BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT + +PIPELINE graphics my_pipeline + ATTACH my_shader + ATTACH my_fragment + BIND BUFFER my_fb AS color LOCATION 0 + BIND BUFFER my_ds AS depth_stencil + + VIEWPORT 0.0 2.0 SIZE 12.0 +END)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()) << r.Error(); + EXPECT_EQ("16: missing size for VIEWPORT command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ViewportInvalidMissingDepthValue) { + std::string in = R"( +SHADER vertex my_shader PASSTHROUGH +SHADER fragment my_fragment GLSL +# GLSL Shader +END +BUFFER my_fb FORMAT R32G32B32A32_SFLOAT +BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT + +PIPELINE graphics my_pipeline + ATTACH my_shader + ATTACH my_fragment + BIND BUFFER my_fb AS color LOCATION 0 + BIND BUFFER my_ds AS depth_stencil + + VIEWPORT 0.0 2.0 SIZE 12.0 24.0 MIN_DEPTH MAX_DEPTH 1.0 +END)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()) << r.Error(); + EXPECT_EQ("15: invalid min_depth for VIEWPORT command", r.Error()); +} + +} // namespace amberscript +} // namespace amber diff --git a/src/pipeline_data.h b/src/pipeline_data.h index dc67c03..9a3b4d1 100644 --- a/src/pipeline_data.h +++ b/src/pipeline_data.h @@ -21,6 +21,15 @@ namespace amber { +struct Viewport { + float x; + float y; + float w; + float h; + float mind; + float maxd; +}; + /// Stores information used to configure a pipeline. class PipelineData { public: @@ -161,6 +170,14 @@ class PipelineData { void SetAlphaBlendOp(BlendOp op) { alpha_blend_op_ = op; } BlendOp GetAlphaBlendOp() const { return alpha_blend_op_; } + void SetViewport(const Viewport& v) { + has_viewport_data = true; + vp = v; + } + + bool HasViewportData() const { return has_viewport_data; } + const Viewport& GetViewport() const { return vp; } + private: StencilOp front_fail_op_ = StencilOp::kKeep; StencilOp front_pass_op_ = StencilOp::kKeep; @@ -213,6 +230,9 @@ class PipelineData { float depth_bias_slope_factor_ = 0.0f; float min_depth_bounds_ = 0.0f; float max_depth_bounds_ = 0.0f; + + bool has_viewport_data = false; + Viewport vp; }; } // namespace amber diff --git a/src/vulkan/graphics_pipeline.cc b/src/vulkan/graphics_pipeline.cc index b83bea1..5536440 100644 --- a/src/vulkan/graphics_pipeline.cc +++ b/src/vulkan/graphics_pipeline.cc @@ -579,6 +579,16 @@ Result GraphicsPipeline::CreateVkGraphicsPipeline( 0, 0, static_cast<float>(frame_width_), static_cast<float>(frame_height_), 0, 1}; + if (pipeline_data->HasViewportData()) { + Viewport vp = pipeline_data->GetViewport(); + viewport.x = vp.x; + viewport.y = vp.y; + viewport.width = vp.w; + viewport.height = vp.h; + viewport.minDepth = vp.mind; + viewport.maxDepth = vp.maxd; + } + VkRect2D scissor = {{0, 0}, {frame_width_, frame_height_}}; VkPipelineViewportStateCreateInfo viewport_info = diff --git a/tests/cases/viewport.amber b/tests/cases/viewport.amber new file mode 100644 index 0000000..ca9b0a5 --- /dev/null +++ b/tests/cases/viewport.amber @@ -0,0 +1,59 @@ +#!amber +# +# Copyright 2021 The Amber Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +SHADER vertex vert_shader GLSL +#version 430 + +layout(location = 0) in vec4 position; + +void main() { + gl_Position = vec4(position.xy, 0.5, 1.0); +} +END + +SHADER fragment frag_shader GLSL +#version 430 + +layout(location = 0) out vec4 final_color; + +void main() { + final_color = vec4(0, 1, 0, 1); +} +END + +BUFFER framebuffer FORMAT B8G8R8A8_UNORM + +PIPELINE graphics pipeline1 + ATTACH vert_shader + ATTACH frag_shader + + FRAMEBUFFER_SIZE 256 256 + VIEWPORT 10.0 10.0 SIZE 100.0 100.0 + + BIND BUFFER framebuffer AS color LOCATION 0 +END + +CLEAR_COLOR pipeline1 255 255 255 255 +CLEAR pipeline1 +RUN pipeline1 DRAW_RECT POS 0 0 SIZE 256 256 + +# Check within the viewport +EXPECT framebuffer IDX 10 10 SIZE 100 100 EQ_RGBA 0 255 0 255 +# Check the borders were untouched +EXPECT framebuffer IDX 0 0 SIZE 10 256 EQ_RGBA 255 255 255 255 +EXPECT framebuffer IDX 110 0 SIZE 146 256 EQ_RGBA 255 255 255 255 +EXPECT framebuffer IDX 10 0 SIZE 100 10 EQ_RGBA 255 255 255 255 +EXPECT framebuffer IDX 10 110 SIZE 100 146 EQ_RGBA 255 255 255 255 diff --git a/tests/cases/viewport_depth.amber b/tests/cases/viewport_depth.amber new file mode 100644 index 0000000..2bf7a9e --- /dev/null +++ b/tests/cases/viewport_depth.amber @@ -0,0 +1,61 @@ +#!amber +# +# Copyright 2021 The Amber Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +SHADER vertex vert_shader GLSL +#version 430 + +layout(location = 0) in vec4 position; + +void main() { + gl_Position = vec4(position.xy, 0.5, 1.0); +} +END + +SHADER fragment frag_shader GLSL +#version 430 + +layout(location = 0) out vec4 final_color; + +void main() { + final_color = vec4(0, 1, 0, 1); +} +END + +BUFFER framebuffer FORMAT B8G8R8A8_UNORM +BUFFER depth FORMAT D32_SFLOAT + +PIPELINE graphics pipeline1 + ATTACH vert_shader + ATTACH frag_shader + + DEPTH + TEST on + WRITE on + END + + FRAMEBUFFER_SIZE 256 256 + VIEWPORT 0.0 0.0 SIZE 256.0 256.0 MIN_DEPTH 0.3 MAX_DEPTH 0.9 + + BIND BUFFER framebuffer AS color LOCATION 0 + BIND BUFFER depth AS depth_stencil +END + +CLEAR_DEPTH pipeline1 1.0 +CLEAR_COLOR pipeline1 255 255 255 255 +CLEAR pipeline1 +RUN pipeline1 DRAW_RECT POS 0 0 SIZE 256 256 + +EXPECT depth IDX 0 TOLERANCE 1.0e-6 EQ 0.6 |