diff options
author | Jaebaek Seo <duke.acacia@gmail.com> | 2018-11-16 10:30:55 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-16 10:30:55 -0500 |
commit | 01c586239b4d1c7d3a19d23b2f022cd6ddddb846 (patch) | |
tree | 21cdab24d9800d1f578c0334eddacd54653e5e8a | |
parent | 6083a8a0ca2a03c241afb06ec20d7b9f68121033 (diff) | |
download | amber-01c586239b4d1c7d3a19d23b2f022cd6ddddb846.tar.gz |
Vulkan: add draw triangles (#52)
Vulkan: add draw triangles
Add tests/cases/draw_triangle_list.amber to test drawing simple
triangles and update engine to conduct draw based on parameters of
draw array command.
Fixes #57
-rw-r--r-- | src/vulkan/engine_vulkan.cc | 7 | ||||
-rw-r--r-- | src/vulkan/graphics_pipeline.cc | 54 | ||||
-rw-r--r-- | src/vulkan/graphics_pipeline.h | 4 | ||||
-rw-r--r-- | tests/cases/clear.amber | 4 | ||||
-rw-r--r-- | tests/cases/clear_and_probe_all_wrong_color.expect_fail.amber | 4 | ||||
-rw-r--r-- | tests/cases/clear_and_probe_small_wrong_color.expect_fail.amber | 4 | ||||
-rw-r--r-- | tests/cases/clear_and_probe_too_large_rect.expect_fail.amber | 4 | ||||
-rw-r--r-- | tests/cases/clear_color.amber | 4 | ||||
-rw-r--r-- | tests/cases/clear_color_without_clear_command.expect_fail.amber | 4 | ||||
-rw-r--r-- | tests/cases/draw_triangle_list.amber | 100 | ||||
-rw-r--r-- | tests/cases/multiple_clear_color.amber | 4 |
11 files changed, 157 insertions, 36 deletions
diff --git a/src/vulkan/engine_vulkan.cc b/src/vulkan/engine_vulkan.cc index a22bb5c..2130c11 100644 --- a/src/vulkan/engine_vulkan.cc +++ b/src/vulkan/engine_vulkan.cc @@ -15,6 +15,7 @@ #include "src/vulkan/engine_vulkan.h" #include <algorithm> +#include <cassert> #include "src/make_unique.h" #include "src/vulkan/format_data.h" @@ -44,7 +45,7 @@ VkShaderStageFlagBits ToVkShaderStage(ShaderType type) { return VK_SHADER_STAGE_COMPUTE_BIT; } - // Unreachable + assert(false && "Vulkan::Unknown shader stage"); return VK_SHADER_STAGE_FRAGMENT_BIT; } @@ -235,11 +236,11 @@ Result EngineVulkan::DoDrawRect(const DrawRectCommand*) { return Result("Vulkan::DoDrawRect Not Implemented"); } -Result EngineVulkan::DoDrawArrays(const DrawArraysCommand*) { +Result EngineVulkan::DoDrawArrays(const DrawArraysCommand* command) { if (!pipeline_->IsGraphics()) return Result("Vulkan::DrawArrays for Non-Graphics Pipeline"); - return pipeline_->AsGraphics()->Draw(); + return pipeline_->AsGraphics()->Draw(command); } Result EngineVulkan::DoCompute(const ComputeCommand*) { diff --git a/src/vulkan/graphics_pipeline.cc b/src/vulkan/graphics_pipeline.cc index 0bbceba..a13405c 100644 --- a/src/vulkan/graphics_pipeline.cc +++ b/src/vulkan/graphics_pipeline.cc @@ -14,6 +14,7 @@ #include "src/vulkan/graphics_pipeline.h" +#include <cassert> #include <cmath> #include "src/command.h" @@ -74,6 +75,38 @@ bool IsFloatPixelEqualInt(float pixel, uint8_t expected) { return std::fabs(pixel - static_cast<float>(expected) / 255.0f) < kEpsilon; } +VkPrimitiveTopology ToVkTopology(Topology topology) { + switch (topology) { + case Topology::kPointList: + return VK_PRIMITIVE_TOPOLOGY_POINT_LIST; + case Topology::kLineList: + return VK_PRIMITIVE_TOPOLOGY_LINE_LIST; + case Topology::kLineStrip: + return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP; + case Topology::kTriangleList: + return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + case Topology::kTriangleStrip: + return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; + case Topology::kTriangleFan: + return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN; + case Topology::kLineListWithAdjacency: + return VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY; + case Topology::kLineStripWithAdjacency: + return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY; + case Topology::kTriangleListWithAdjacency: + return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY; + case Topology::kTriangleStripWithAdjacency: + return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY; + case Topology::kPatchList: + return VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; + default: + break; + } + + assert(false && "Vulkan::Unknown topology"); + return VK_PRIMITIVE_TOPOLOGY_POINT_LIST; +} + } // namespace GraphicsPipeline::GraphicsPipeline( @@ -166,7 +199,8 @@ GraphicsPipeline::GetPipelineColorBlendAttachmentState() { return colorblend_attachment; } -Result GraphicsPipeline::CreateVkGraphicsPipeline() { +Result GraphicsPipeline::CreateVkGraphicsPipeline( + VkPrimitiveTopology topology) { if (pipeline_ != VK_NULL_HANDLE) return Result("Vulkan::Pipeline already created"); @@ -202,7 +236,7 @@ Result GraphicsPipeline::CreateVkGraphicsPipeline() { input_assembly_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; // TODO(jaebaek): Handle the given index if exists. - input_assembly_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + input_assembly_info.topology = topology; input_assembly_info.primitiveRestartEnable = VK_FALSE; VkViewport viewport = {0, @@ -431,10 +465,10 @@ Result GraphicsPipeline::ClearBuffer(const VkClearValue& clear_value, return {}; } -Result GraphicsPipeline::Draw() { +Result GraphicsPipeline::Draw(const DrawArraysCommand* command) { // TODO(jaebaek): Handle primitive topology. if (pipeline_ == VK_NULL_HANDLE) { - Result r = CreateVkGraphicsPipeline(); + Result r = CreateVkGraphicsPipeline(ToVkTopology(command->GetTopology())); if (!r.IsSuccess()) return r; } @@ -455,15 +489,15 @@ Result GraphicsPipeline::Draw() { vkCmdBindPipeline(command_->GetCommandBuffer(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_); - uint32_t vertex_count = 0; - uint32_t instance_count = 0; - if (vertex_buffer_) { + if (vertex_buffer_) vertex_buffer_->BindToCommandBuffer(command_->GetCommandBuffer()); - vertex_count = static_cast<uint32_t>(vertex_buffer_->GetVertexCount()); + + uint32_t instance_count = command->GetInstanceCount(); + if (instance_count == 0 && command->GetVertexCount() != 0) instance_count = 1; - } - vkCmdDraw(command_->GetCommandBuffer(), vertex_count, instance_count, 0, 0); + vkCmdDraw(command_->GetCommandBuffer(), command->GetVertexCount(), + instance_count, command->GetFirstVertexIndex(), 0); return {}; } diff --git a/src/vulkan/graphics_pipeline.h b/src/vulkan/graphics_pipeline.h index 9608dc9..6b0b26b 100644 --- a/src/vulkan/graphics_pipeline.h +++ b/src/vulkan/graphics_pipeline.h @@ -66,7 +66,7 @@ class GraphicsPipeline : public Pipeline { Result SetClearStencil(uint32_t stencil); Result SetClearDepth(float depth); - Result Draw(); + Result Draw(const DrawArraysCommand* command); private: enum class RenderPassState : uint8_t { @@ -74,7 +74,7 @@ class GraphicsPipeline : public Pipeline { kInactive, }; - Result CreateVkGraphicsPipeline(); + Result CreateVkGraphicsPipeline(VkPrimitiveTopology topology); Result CreateRenderPass(); void ActivateRenderPassIfNeeded(); diff --git a/tests/cases/clear.amber b/tests/cases/clear.amber index b178987..6068b98 100644 --- a/tests/cases/clear.amber +++ b/tests/cases/clear.amber @@ -20,9 +20,7 @@ layout(location = 0) in vec4 color_in; layout(location = 0) out vec4 color_out; -void -main() -{ +void main() { color_out = color_in; } diff --git a/tests/cases/clear_and_probe_all_wrong_color.expect_fail.amber b/tests/cases/clear_and_probe_all_wrong_color.expect_fail.amber index fda1da2..82f34cd 100644 --- a/tests/cases/clear_and_probe_all_wrong_color.expect_fail.amber +++ b/tests/cases/clear_and_probe_all_wrong_color.expect_fail.amber @@ -20,9 +20,7 @@ layout(location = 0) in vec4 color_in; layout(location = 0) out vec4 color_out; -void -main() -{ +void main() { color_out = color_in; } diff --git a/tests/cases/clear_and_probe_small_wrong_color.expect_fail.amber b/tests/cases/clear_and_probe_small_wrong_color.expect_fail.amber index 54eee4f..431fb31 100644 --- a/tests/cases/clear_and_probe_small_wrong_color.expect_fail.amber +++ b/tests/cases/clear_and_probe_small_wrong_color.expect_fail.amber @@ -20,9 +20,7 @@ layout(location = 0) in vec4 color_in; layout(location = 0) out vec4 color_out; -void -main() -{ +void main() { color_out = color_in; } diff --git a/tests/cases/clear_and_probe_too_large_rect.expect_fail.amber b/tests/cases/clear_and_probe_too_large_rect.expect_fail.amber index ed58f41..a4c8bfb 100644 --- a/tests/cases/clear_and_probe_too_large_rect.expect_fail.amber +++ b/tests/cases/clear_and_probe_too_large_rect.expect_fail.amber @@ -20,9 +20,7 @@ layout(location = 0) in vec4 color_in; layout(location = 0) out vec4 color_out; -void -main() -{ +void main() { color_out = color_in; } diff --git a/tests/cases/clear_color.amber b/tests/cases/clear_color.amber index 74433de..634ae8b 100644 --- a/tests/cases/clear_color.amber +++ b/tests/cases/clear_color.amber @@ -20,9 +20,7 @@ layout(location = 0) in vec4 color_in; layout(location = 0) out vec4 color_out; -void -main() -{ +void main() { color_out = color_in; } diff --git a/tests/cases/clear_color_without_clear_command.expect_fail.amber b/tests/cases/clear_color_without_clear_command.expect_fail.amber index e367c6d..608c0c9 100644 --- a/tests/cases/clear_color_without_clear_command.expect_fail.amber +++ b/tests/cases/clear_color_without_clear_command.expect_fail.amber @@ -20,9 +20,7 @@ layout(location = 0) in vec4 color_in; layout(location = 0) out vec4 color_out; -void -main() -{ +void main() { color_out = color_in; } diff --git a/tests/cases/draw_triangle_list.amber b/tests/cases/draw_triangle_list.amber new file mode 100644 index 0000000..a15c0a1 --- /dev/null +++ b/tests/cases/draw_triangle_list.amber @@ -0,0 +1,100 @@ +# Copyright 2018 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. + +[vertex shader] +#version 430 + +layout(location = 0) in vec4 position; +layout(location = 1) in vec4 vert_color; +layout(location = 0) out vec4 frag_color; + +void main() { + gl_Position = position; + frag_color = vert_color; +} + +[fragment shader] +#version 430 + +layout(location = 0) in vec4 frag_color; +layout(location = 0) out vec4 final_color; + +void main() { + final_color = frag_color; +} + +[vertex data] +# position vert_color + 0/R8G8_SNORM 1/R8G8B8_UNORM + +# Red for entire frame +# R8 G8 R8 G8 B8 + -128 -128 255 0 0 + 127 127 255 0 0 + -128 127 255 0 0 + + -128 -128 255 0 0 + 127 127 255 0 0 + 127 -128 255 0 0 + +# Green for half frame +# R8 G8 R8 G8 B8 + 0 -128 0 255 0 + 127 127 0 255 0 + 0 127 0 255 0 + + 0 -128 0 255 0 + 127 127 0 255 0 + 127 -128 0 255 0 + +# Blue for quarter frame +# R8 G8 R8 G8 B8 + -128 0 0 0 255 + 0 127 0 0 255 + -128 127 0 0 255 + + -128 0 0 0 255 + 0 127 0 0 255 + 0 0 0 0 255 + +# Mixed color for quarter frame +# R8 G8 R8 G8 B8 + 0 0 128 128 128 + 127 127 128 128 128 + 0 127 128 128 128 + + 0 0 128 128 128 + 127 127 128 128 128 + 127 0 128 128 128 + +[test] +clear + +draw arrays TRIANGLE_LIST 0 6 +relative probe rect rgb (0.0, 0.0, 1.0, 1.0) (1.0, 0, 0) + +draw arrays TRIANGLE_LIST 6 6 +relative probe rect rgb (0.0, 0.0, 0.5, 1.0) (1.0, 0, 0) +relative probe rect rgb (0.5, 0.0, 0.5, 1.0) (0, 1.0, 0) + +draw arrays TRIANGLE_LIST 12 6 +relative probe rect rgb (0.0, 0.0, 0.5, 0.5) (1.0, 0, 0) +relative probe rect rgb (0.5, 0.0, 0.5, 1.0) (0, 1.0, 0) +relative probe rect rgb (0.0, 0.5, 0.5, 0.5) (0, 0, 1.0) + +draw arrays TRIANGLE_LIST 18 6 +relative probe rect rgb (0.0, 0.0, 0.5, 0.5) (1.0, 0, 0) +relative probe rect rgb (0.5, 0.0, 0.5, 0.5) (0, 1.0, 0) +relative probe rect rgb (0.0, 0.5, 0.5, 0.5) (0, 0, 1.0) +relative probe rect rgb (0.5, 0.5, 0.5, 0.5) (0.5, 0.5, 0.5) diff --git a/tests/cases/multiple_clear_color.amber b/tests/cases/multiple_clear_color.amber index ede2d82..f70d97e 100644 --- a/tests/cases/multiple_clear_color.amber +++ b/tests/cases/multiple_clear_color.amber @@ -20,9 +20,7 @@ layout(location = 0) in vec4 color_in; layout(location = 0) out vec4 color_out; -void -main() -{ +void main() { color_out = color_in; } |