aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/format.h12
-rw-r--r--src/vulkan/compute_pipeline.cc2
-rw-r--r--src/vulkan/engine_vulkan.cc61
-rw-r--r--src/vulkan/graphics_pipeline.cc43
-rw-r--r--src/vulkan/graphics_pipeline.h13
-rw-r--r--src/vulkan/pipeline.cc6
-rw-r--r--src/vulkan/pipeline.h3
-rw-r--r--tests/cases/draw_rectangles.amber58
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)