aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJaebaek Seo <duke.acacia@gmail.com>2018-11-16 10:30:55 -0500
committerGitHub <noreply@github.com>2018-11-16 10:30:55 -0500
commit01c586239b4d1c7d3a19d23b2f022cd6ddddb846 (patch)
tree21cdab24d9800d1f578c0334eddacd54653e5e8a /src
parent6083a8a0ca2a03c241afb06ec20d7b9f68121033 (diff)
downloadamber-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
Diffstat (limited to 'src')
-rw-r--r--src/vulkan/engine_vulkan.cc7
-rw-r--r--src/vulkan/graphics_pipeline.cc54
-rw-r--r--src/vulkan/graphics_pipeline.h4
3 files changed, 50 insertions, 15 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();