diff options
-rw-r--r-- | src/format.h | 12 | ||||
-rw-r--r-- | src/vulkan/compute_pipeline.cc | 2 | ||||
-rw-r--r-- | src/vulkan/engine_vulkan.cc | 61 | ||||
-rw-r--r-- | src/vulkan/graphics_pipeline.cc | 43 | ||||
-rw-r--r-- | src/vulkan/graphics_pipeline.h | 13 | ||||
-rw-r--r-- | src/vulkan/pipeline.cc | 6 | ||||
-rw-r--r-- | src/vulkan/pipeline.h | 3 | ||||
-rw-r--r-- | tests/cases/draw_rectangles.amber | 58 |
8 files changed, 178 insertions, 20 deletions
diff --git a/src/format.h b/src/format.h index fd900a8..31b1d59 100644 --- a/src/format.h +++ b/src/format.h @@ -40,11 +40,13 @@ class Format { void SetFormatType(FormatType type) { type_ = type; } FormatType GetFormatType() const { return type_; } - void SetPackSize(uint8_t size) { pack_size_ = size; } - uint8_t GetPackSize() const { return pack_size_; } + void SetPackSize(uint8_t size_in_bytes) { + pack_size_in_bytes_ = size_in_bytes; + } + uint8_t GetPackSize() const { return pack_size_in_bytes_; } - void AddComponent(FormatComponentType type, FormatMode mode, uint8_t size) { - components_.emplace_back(type, mode, size); + void AddComponent(FormatComponentType type, FormatMode mode, uint8_t bits) { + components_.emplace_back(type, mode, bits); } const std::vector<Component>& GetComponents() const { return components_; } @@ -58,7 +60,7 @@ class Format { private: FormatType type_; - uint8_t pack_size_ = 0; + uint8_t pack_size_in_bytes_ = 0; std::vector<Component> components_; }; diff --git a/src/vulkan/compute_pipeline.cc b/src/vulkan/compute_pipeline.cc index 97cb7b9..3c1ed32 100644 --- a/src/vulkan/compute_pipeline.cc +++ b/src/vulkan/compute_pipeline.cc @@ -42,7 +42,7 @@ Result ComputePipeline::CreateVkComputePipeline() { "pipeline is not 1"); } - Result r = CreateVkDescriptorRelatedObjects(); + Result r = CreateVkDescriptorRelatedObjectsIfNeeded(); if (!r.IsSuccess()) return r; diff --git a/src/vulkan/engine_vulkan.cc b/src/vulkan/engine_vulkan.cc index 919616b..312e991 100644 --- a/src/vulkan/engine_vulkan.cc +++ b/src/vulkan/engine_vulkan.cc @@ -227,8 +227,65 @@ Result EngineVulkan::DoClear(const ClearCommand*) { return pipeline_->AsGraphics()->Clear(); } -Result EngineVulkan::DoDrawRect(const DrawRectCommand*) { - return Result("Vulkan::DoDrawRect Not Implemented"); +Result EngineVulkan::DoDrawRect(const DrawRectCommand* command) { + if (!pipeline_->IsGraphics()) + return Result("Vulkan::DrawRect for Non-Graphics Pipeline"); + + auto* graphics = pipeline_->AsGraphics(); + + Result r = graphics->ResetPipelineAndVertexBuffer(); + if (!r.IsSuccess()) + return r; + + // |format| is not Format for frame buffer but for vertex buffer. + // Since draw rect command contains its vertex information and it + // does not include a format of vertex buffer, we can choose any + // one that is suitable. We use VK_FORMAT_R32G32_SFLOAT for it. + Format format; + format.SetFormatType(FormatType::kR32G32_SFLOAT); + format.AddComponent(FormatComponentType::kR, FormatMode::kSFloat, 32); + format.AddComponent(FormatComponentType::kG, FormatMode::kSFloat, 32); + + float x = command->GetX(); + float y = command->GetY(); + float width = command->GetWidth(); + float height = command->GetHeight(); + if (command->IsOrtho()) { + const float frame_width = static_cast<float>(graphics->GetWidth()); + const float frame_height = static_cast<float>(graphics->GetHeight()); + x = ((x / frame_width) * 2.0f) - 1.0f; + y = ((y / frame_height) * 2.0f) - 1.0f; + width = ((width / frame_width) * 2.0f) - 1.0f; + height = ((height / frame_height) * 2.0f) - 1.0f; + } + + std::vector<Value> values(8); + // Bottom left + values[0].SetDoubleValue(static_cast<double>(x)); + values[1].SetDoubleValue(static_cast<double>(y + height)); + // Top left + values[2].SetDoubleValue(static_cast<double>(x)); + values[3].SetDoubleValue(static_cast<double>(y)); + // Bottom right + values[4].SetDoubleValue(static_cast<double>(x + width)); + values[5].SetDoubleValue(static_cast<double>(y + height)); + // Top right + values[6].SetDoubleValue(static_cast<double>(x + width)); + values[7].SetDoubleValue(static_cast<double>(y)); + + r = graphics->SetBuffer(BufferType::kVertex, 0, format, values); + if (!r.IsSuccess()) + return r; + + PipelineData data; + DrawArraysCommand draw(data); + draw.SetTopology(command->IsPatch() ? Topology::kPatchList + : Topology::kTriangleStrip); + draw.SetFirstVertexIndex(0); + draw.SetVertexCount(4); + draw.SetInstanceCount(1); + + return graphics->Draw(&draw); } Result EngineVulkan::DoDrawArrays(const DrawArraysCommand* command) { diff --git a/src/vulkan/graphics_pipeline.cc b/src/vulkan/graphics_pipeline.cc index b01facb..36444bf 100644 --- a/src/vulkan/graphics_pipeline.cc +++ b/src/vulkan/graphics_pipeline.cc @@ -200,7 +200,7 @@ Result GraphicsPipeline::CreateVkGraphicsPipeline( if (pipeline_ != VK_NULL_HANDLE) return Result("Vulkan::Pipeline already created"); - Result r = CreateVkDescriptorRelatedObjects(); + Result r = CreateVkDescriptorRelatedObjectsIfNeeded(); if (!r.IsSuccess()) return r; @@ -319,18 +319,25 @@ Result GraphicsPipeline::Initialize(uint32_t width, return {}; } -void GraphicsPipeline::SetBuffer(BufferType type, - uint8_t location, - const Format& format, - const std::vector<Value>& values) { +Result GraphicsPipeline::SetBuffer(BufferType type, + uint8_t location, + const Format& format, + const std::vector<Value>& values) { // TODO(jaebaek): Handle indices data. if (type != BufferType::kVertex) - return; + return {}; if (!vertex_buffer_) vertex_buffer_ = MakeUnique<VertexBuffer>(device_); + DeactivateRenderPassIfNeeded(); + + Result r = command_->BeginIfNotInRecording(); + if (!r.IsSuccess()) + return r; + vertex_buffer_->SetData(location, format, values); + return {}; } Result GraphicsPipeline::SendBufferDataIfNeeded() { @@ -465,6 +472,30 @@ Result GraphicsPipeline::ClearBuffer(const VkClearValue& clear_value, return {}; } +Result GraphicsPipeline::ResetPipelineAndVertexBuffer() { + DeactivateRenderPassIfNeeded(); + + Result r = command_->End(); + if (!r.IsSuccess()) + return r; + + r = command_->SubmitAndReset(GetFenceTimeout()); + if (!r.IsSuccess()) + return r; + + if (vertex_buffer_) { + vertex_buffer_->Shutdown(); + vertex_buffer_.reset(nullptr); + } + + if (pipeline_ != VK_NULL_HANDLE) { + vkDestroyPipeline(device_, pipeline_, nullptr); + pipeline_ = VK_NULL_HANDLE; + } + + return {}; +} + Result GraphicsPipeline::Draw(const DrawArraysCommand* command) { Result r = command_->BeginIfNotInRecording(); if (!r.IsSuccess()) diff --git a/src/vulkan/graphics_pipeline.h b/src/vulkan/graphics_pipeline.h index 2503055..4142482 100644 --- a/src/vulkan/graphics_pipeline.h +++ b/src/vulkan/graphics_pipeline.h @@ -48,10 +48,10 @@ class GraphicsPipeline : public Pipeline { VkCommandPool pool, VkQueue queue); - void SetBuffer(BufferType type, - uint8_t location, - const Format& format, - const std::vector<Value>& values); + Result SetBuffer(BufferType type, + uint8_t location, + const Format& format, + const std::vector<Value>& values); Result Clear(); Result ClearBuffer(const VkClearValue& clear_value, @@ -67,6 +67,11 @@ class GraphicsPipeline : public Pipeline { const FrameBuffer* GetFrame() const { return frame_.get(); } + Result ResetPipelineAndVertexBuffer(); + + uint32_t GetWidth() const { return frame_width_; } + uint32_t GetHeight() const { return frame_height_; } + // Pipeline void Shutdown() override; Result ProcessCommands() override; diff --git a/src/vulkan/pipeline.cc b/src/vulkan/pipeline.cc index 291c04f..e566656 100644 --- a/src/vulkan/pipeline.cc +++ b/src/vulkan/pipeline.cc @@ -199,7 +199,10 @@ Result Pipeline::CreatePipelineLayout() { return {}; } -Result Pipeline::CreateVkDescriptorRelatedObjects() { +Result Pipeline::CreateVkDescriptorRelatedObjectsIfNeeded() { + if (descriptor_related_objects_already_created_) + return {}; + // TODO(jaebaek): Update SSBO dynamically. Result r = CreateDescriptorSetLayouts(); if (!r.IsSuccess()) @@ -230,6 +233,7 @@ Result Pipeline::UpdateDescriptorSetsIfNeeded() { } } + descriptor_related_objects_already_created_ = true; return {}; } diff --git a/src/vulkan/pipeline.h b/src/vulkan/pipeline.h index 490723e..a9f65ed 100644 --- a/src/vulkan/pipeline.h +++ b/src/vulkan/pipeline.h @@ -66,7 +66,7 @@ class Pipeline { uint32_t fence_timeout_ms, const std::vector<VkPipelineShaderStageCreateInfo>& shader_stage_info); Result InitializeCommandBuffer(VkCommandPool pool, VkQueue queue); - Result CreateVkDescriptorRelatedObjects(); + Result CreateVkDescriptorRelatedObjectsIfNeeded(); Result UpdateDescriptorSetsIfNeeded(); Result SendDescriptorDataToDeviceIfNeeded(); @@ -105,6 +105,7 @@ class Pipeline { std::vector<std::unique_ptr<Descriptor>> descriptors_; std::vector<VkPipelineShaderStageCreateInfo> shader_stage_info_; uint32_t fence_timeout_ms_ = 100; + bool descriptor_related_objects_already_created_ = false; }; } // namespace vulkan diff --git a/tests/cases/draw_rectangles.amber b/tests/cases/draw_rectangles.amber new file mode 100644 index 0000000..2e5e5f2 --- /dev/null +++ b/tests/cases/draw_rectangles.amber @@ -0,0 +1,58 @@ +# 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 = 0) out vec4 frag_color; + +layout(set = 0, binding = 0) buffer block1 { + vec4 in_color; +}; + +void main() { + gl_Position = position; + frag_color = in_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; +} + +[test] +clear + +ssbo 0 subdata vec4 0 1.0 0.0 0.0 1.0 +draw rect -1 -1 1 1 + +ssbo 0 subdata vec4 0 0.0 1.0 0.0 1.0 +draw rect -1 0 1 1 + +ssbo 0 subdata vec4 0 0.0 0.0 1.0 1.0 +draw rect 0 -1 1 1 + +ssbo 0 subdata vec4 0 0.5 0.0 0.5 1.0 +draw rect 0 0 1 1 + +relative probe rect rgba (0.0, 0.0, 0.5, 0.5) (1.0, 0, 0, 1.0) +relative probe rect rgba (0.0, 0.5, 0.5, 0.5) ( 0, 1.0, 0, 1.0) +relative probe rect rgba (0.5, 0.0, 0.5, 0.5) ( 0, 0, 1.0, 1.0) +relative probe rect rgba (0.5, 0.5, 0.5, 0.5) (0.5, 0, 0.5, 1.0) |