diff options
author | dan sinclair <dj2@everburning.com> | 2019-02-21 17:27:25 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-21 17:27:25 -0500 |
commit | 12389f2889a16b6f9f9a2fe7d9176af9710d9af2 (patch) | |
tree | 5d99df0fd1067cd65c5181f478987fc0fff51748 /src | |
parent | 4c4ad39c0dca8621c6f8c00a9402b28cc760306c (diff) | |
download | amber-12389f2889a16b6f9f9a2fe7d9176af9710d9af2.tar.gz |
[vulkan] Code cleanup (#310)
This CL cleans up various things in the src/vulkan directory. Code is
moved closer to usage if a subclass is the only caller. CommandBuffer
and CommandPool are passed instead of VkCommandBuffer and VkCommandPool.
Diffstat (limited to 'src')
27 files changed, 216 insertions, 200 deletions
diff --git a/src/vulkan/buffer.cc b/src/vulkan/buffer.cc index 14c4c1f..43dc870 100644 --- a/src/vulkan/buffer.cc +++ b/src/vulkan/buffer.cc @@ -14,10 +14,28 @@ #include "src/vulkan/buffer.h" +#include "src/vulkan/command_buffer.h" #include "src/vulkan/device.h" namespace amber { namespace vulkan { +namespace { + +bool IsMemoryHostAccessible(const VkPhysicalDeviceMemoryProperties& props, + uint32_t memory_type_index) { + return (props.memoryTypes[memory_type_index].propertyFlags & + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; +} + +bool IsMemoryHostCoherent(const VkPhysicalDeviceMemoryProperties& props, + uint32_t memory_type_index) { + return (props.memoryTypes[memory_type_index].propertyFlags & + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; +} + +} // namespace Buffer::Buffer(Device* device, size_t size_in_bytes, @@ -31,16 +49,16 @@ Result Buffer::Initialize(const VkBufferUsageFlags usage) { if (!r.IsSuccess()) return r; - AllocateResult allocate_result = - AllocateAndBindMemoryToVkBuffer(buffer_, &memory_, + uint32_t memory_type_index = 0; + r = AllocateAndBindMemoryToVkBuffer(buffer_, &memory_, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, - true); - if (!allocate_result.r.IsSuccess()) - return allocate_result.r; + true, &memory_type_index); + if (!r.IsSuccess()) + return r; - if (!IsMemoryHostAccessible(allocate_result.memory_type_index) || - !IsMemoryHostCoherent(allocate_result.memory_type_index)) { + if (!IsMemoryHostAccessible(GetMemoryProperties(), memory_type_index) || + !IsMemoryHostCoherent(GetMemoryProperties(), memory_type_index)) { return Result( "Vulkan: Buffer::Initialize() Buffer is not host accessible or not " "host coherent."); @@ -65,7 +83,7 @@ Result Buffer::CreateVkBufferView(VkFormat format) { return {}; } -Result Buffer::CopyToDevice(VkCommandBuffer command) { +Result Buffer::CopyToDevice(CommandBuffer* command) { // This is redundant because this buffer is always host visible // and coherent and vkQueueSubmit will make writes from host // avaliable (See chapter 6.9. "Host Write Ordering Guarantees" in @@ -74,19 +92,19 @@ Result Buffer::CopyToDevice(VkCommandBuffer command) { return {}; } -Result Buffer::CopyToHost(VkCommandBuffer command) { +Result Buffer::CopyToHost(CommandBuffer* command) { MemoryBarrier(command); return {}; } -void Buffer::CopyFromBuffer(VkCommandBuffer command, const Buffer& src) { +void Buffer::CopyFromBuffer(CommandBuffer* command, const Buffer& src) { VkBufferCopy region = VkBufferCopy(); region.srcOffset = 0; region.dstOffset = 0; region.size = src.GetSizeInBytes(); - device_->GetPtrs()->vkCmdCopyBuffer(command, src.buffer_, buffer_, 1, - ®ion); + device_->GetPtrs()->vkCmdCopyBuffer(command->GetCommandBuffer(), src.buffer_, + buffer_, 1, ®ion); MemoryBarrier(command); } diff --git a/src/vulkan/buffer.h b/src/vulkan/buffer.h index 8d736ae..d5e4c69 100644 --- a/src/vulkan/buffer.h +++ b/src/vulkan/buffer.h @@ -22,6 +22,7 @@ namespace amber { namespace vulkan { +class CommandBuffer; class Device; // Class managing Vulkan Buffer i.e., VkBuffer |buffer_|. |memory_| @@ -48,7 +49,7 @@ class Buffer : public Resource { // Since |buffer_| is mapped to host accessible and host coherent // memory |memory_|, this method only conducts memory barrier to // make it available to device domain. - virtual Result CopyToDevice(VkCommandBuffer command); + virtual Result CopyToDevice(CommandBuffer* command); // Resource VkDeviceMemory GetHostAccessMemory() const override { return memory_; } @@ -56,13 +57,13 @@ class Buffer : public Resource { // Since |buffer_| is mapped to host accessible and host coherent // memory |memory_|, this method only conducts memory barrier to // make it available to host domain. - Result CopyToHost(VkCommandBuffer command) override; + Result CopyToHost(CommandBuffer* command) override; // Copy all data from |src| to |this| and wait until // the memory update is effective by calling vkCmdPipelineBarrier(). // Note that this method only records the copy command and the // actual submission of the command must be done later. - void CopyFromBuffer(VkCommandBuffer command, const Buffer& src); + void CopyFromBuffer(CommandBuffer* command, const Buffer& src); void Shutdown() override; diff --git a/src/vulkan/buffer_descriptor.cc b/src/vulkan/buffer_descriptor.cc index 1de7000..d63a722 100644 --- a/src/vulkan/buffer_descriptor.cc +++ b/src/vulkan/buffer_descriptor.cc @@ -22,6 +22,7 @@ #include "src/engine.h" #include "src/make_unique.h" +#include "src/vulkan/command_buffer.h" namespace amber { namespace vulkan { @@ -91,7 +92,7 @@ Result BufferDescriptor::CreateResourceIfNeeded( } Result BufferDescriptor::RecordCopyDataToResourceIfNeeded( - VkCommandBuffer command) { + CommandBuffer* command) { auto& buffer_output = GetBufferOutput(); if (!buffer_output.empty()) { buffer_->UpdateMemoryWithRawData(buffer_output); @@ -114,7 +115,7 @@ Result BufferDescriptor::RecordCopyDataToResourceIfNeeded( return {}; } -Result BufferDescriptor::RecordCopyDataToHost(VkCommandBuffer command) { +Result BufferDescriptor::RecordCopyDataToHost(CommandBuffer* command) { if (!buffer_) { return Result( "Vulkan: BufferDescriptor::RecordCopyDataToHost() |buffer_| is empty"); diff --git a/src/vulkan/buffer_descriptor.h b/src/vulkan/buffer_descriptor.h index 65db9be..cc01f53 100644 --- a/src/vulkan/buffer_descriptor.h +++ b/src/vulkan/buffer_descriptor.h @@ -29,6 +29,7 @@ namespace amber { namespace vulkan { +class CommandBuffer; class Device; // Among Vulkan descriptor types, this class handles Storage Buffer @@ -44,8 +45,8 @@ class BufferDescriptor : public Descriptor { // Descriptor Result CreateResourceIfNeeded( const VkPhysicalDeviceMemoryProperties& properties) override; - Result RecordCopyDataToResourceIfNeeded(VkCommandBuffer command) override; - Result RecordCopyDataToHost(VkCommandBuffer command) override; + Result RecordCopyDataToResourceIfNeeded(CommandBuffer* command) override; + Result RecordCopyDataToHost(CommandBuffer* command) override; Result MoveResourceToBufferOutput() override; Result UpdateDescriptorSetIfNeeded(VkDescriptorSet descriptor_set) override; ResourceInfo GetResourceInfo() override; diff --git a/src/vulkan/command_buffer.cc b/src/vulkan/command_buffer.cc index 20c2b31..2e00307 100644 --- a/src/vulkan/command_buffer.cc +++ b/src/vulkan/command_buffer.cc @@ -14,12 +14,13 @@ #include "src/vulkan/command_buffer.h" +#include "src/vulkan/command_pool.h" #include "src/vulkan/device.h" namespace amber { namespace vulkan { -CommandBuffer::CommandBuffer(Device* device, VkCommandPool pool, VkQueue queue) +CommandBuffer::CommandBuffer(Device* device, CommandPool* pool, VkQueue queue) : device_(device), pool_(pool), queue_(queue) {} CommandBuffer::~CommandBuffer() = default; @@ -27,7 +28,7 @@ CommandBuffer::~CommandBuffer() = default; Result CommandBuffer::Initialize() { VkCommandBufferAllocateInfo command_info = VkCommandBufferAllocateInfo(); command_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - command_info.commandPool = pool_; + command_info.commandPool = pool_->GetCommandPool(); command_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; command_info.commandBufferCount = 1; @@ -114,8 +115,8 @@ void CommandBuffer::Shutdown() { device_->GetPtrs()->vkDestroyFence(device_->GetDevice(), fence_, nullptr); if (command_ != VK_NULL_HANDLE) { - device_->GetPtrs()->vkFreeCommandBuffers(device_->GetDevice(), pool_, 1, - &command_); + device_->GetPtrs()->vkFreeCommandBuffers( + device_->GetDevice(), pool_->GetCommandPool(), 1, &command_); } } diff --git a/src/vulkan/command_buffer.h b/src/vulkan/command_buffer.h index 25dfa90..cbfab45 100644 --- a/src/vulkan/command_buffer.h +++ b/src/vulkan/command_buffer.h @@ -31,11 +31,12 @@ enum class CommandBufferState : uint8_t { kInvalid, }; +class CommandPool; class Device; class CommandBuffer { public: - CommandBuffer(Device* device, VkCommandPool pool, VkQueue queue); + CommandBuffer(Device* device, CommandPool* pool, VkQueue queue); ~CommandBuffer(); Result Initialize(); @@ -52,7 +53,7 @@ class CommandBuffer { private: Device* device_ = nullptr; - VkCommandPool pool_ = VK_NULL_HANDLE; + CommandPool* pool_ = nullptr; VkQueue queue_ = VK_NULL_HANDLE; VkCommandBuffer command_ = VK_NULL_HANDLE; VkFence fence_ = VK_NULL_HANDLE; diff --git a/src/vulkan/compute_pipeline.cc b/src/vulkan/compute_pipeline.cc index 04d80f1..2af4784 100644 --- a/src/vulkan/compute_pipeline.cc +++ b/src/vulkan/compute_pipeline.cc @@ -14,6 +14,7 @@ #include "src/vulkan/compute_pipeline.h" +#include "src/vulkan/command_pool.h" #include "src/vulkan/device.h" namespace amber { @@ -34,7 +35,7 @@ ComputePipeline::ComputePipeline( ComputePipeline::~ComputePipeline() = default; -Result ComputePipeline::Initialize(VkCommandPool pool, VkQueue queue) { +Result ComputePipeline::Initialize(CommandPool* pool, VkQueue queue) { return Pipeline::Initialize(pool, queue); } diff --git a/src/vulkan/compute_pipeline.h b/src/vulkan/compute_pipeline.h index 203c500..83761e3 100644 --- a/src/vulkan/compute_pipeline.h +++ b/src/vulkan/compute_pipeline.h @@ -34,7 +34,7 @@ class ComputePipeline : public Pipeline { const std::vector<VkPipelineShaderStageCreateInfo>& shader_stage_info); ~ComputePipeline() override; - Result Initialize(VkCommandPool pool, VkQueue queue); + Result Initialize(CommandPool* pool, VkQueue queue); Result Compute(uint32_t x, uint32_t y, uint32_t z); diff --git a/src/vulkan/descriptor.h b/src/vulkan/descriptor.h index 66310a3..bf86d2c 100644 --- a/src/vulkan/descriptor.h +++ b/src/vulkan/descriptor.h @@ -41,6 +41,7 @@ enum class DescriptorType : uint8_t { kInputAttachment, }; +class CommandBuffer; class Device; VkDescriptorType ToVkDescriptorType(DescriptorType type); @@ -114,12 +115,12 @@ class Descriptor { // it clears |buffer_output_| and |buffer_input_queue_|. Note that // it only records the command and the actual submission must be // done later. - virtual Result RecordCopyDataToResourceIfNeeded(VkCommandBuffer command) = 0; + virtual Result RecordCopyDataToResourceIfNeeded(CommandBuffer* command) = 0; // Only record the copy command for copying the resource data to // the host accessible memory. The actual submission of the command // must be done later. - virtual Result RecordCopyDataToHost(VkCommandBuffer command) = 0; + virtual Result RecordCopyDataToHost(CommandBuffer* command) = 0; // Copy contents of resource e.g., VkBuffer to host buffer // |buffer_output_|. This method assumes that we already copy diff --git a/src/vulkan/engine_vulkan.cc b/src/vulkan/engine_vulkan.cc index 1deead3..728e0eb 100644 --- a/src/vulkan/engine_vulkan.cc +++ b/src/vulkan/engine_vulkan.cc @@ -191,8 +191,8 @@ Result EngineVulkan::CreatePipeline(amber::Pipeline* pipeline) { device_.get(), device_->GetPhysicalDeviceProperties(), device_->GetPhysicalMemoryProperties(), engine_data.fence_timeout_ms, GetShaderStageInfo()); - Result r = pipeline_->AsCompute()->Initialize(pool_->GetCommandPool(), - device_->GetQueue()); + Result r = + pipeline_->AsCompute()->Initialize(pool_.get(), device_->GetQueue()); if (!r.IsSuccess()) return r; } else { @@ -205,7 +205,7 @@ Result EngineVulkan::CreatePipeline(amber::Pipeline* pipeline) { Result r = pipeline_->AsGraphics()->Initialize( pipeline->GetFramebufferWidth(), pipeline->GetFramebufferHeight(), - pool_->GetCommandPool(), device_->GetQueue()); + pool_.get(), device_->GetQueue()); if (!r.IsSuccess()) return r; } diff --git a/src/vulkan/frame_buffer.cc b/src/vulkan/frame_buffer.cc index bf3c26f..a3d3039 100644 --- a/src/vulkan/frame_buffer.cc +++ b/src/vulkan/frame_buffer.cc @@ -19,6 +19,7 @@ #include <vector> #include "src/make_unique.h" +#include "src/vulkan/command_buffer.h" #include "src/vulkan/device.h" #include "src/vulkan/format_data.h" @@ -82,7 +83,7 @@ Result FrameBuffer::Initialize( return {}; } -Result FrameBuffer::ChangeFrameImageLayout(VkCommandBuffer command, +Result FrameBuffer::ChangeFrameImageLayout(CommandBuffer* command, FrameImageState layout) { if (layout == FrameImageState::kInit) { return Result( diff --git a/src/vulkan/frame_buffer.h b/src/vulkan/frame_buffer.h index f641c21..d4c2b2f 100644 --- a/src/vulkan/frame_buffer.h +++ b/src/vulkan/frame_buffer.h @@ -28,6 +28,7 @@ enum class FrameImageState : uint8_t { kProbe, }; +class CommandBuffer; class Device; class FrameBuffer { @@ -41,8 +42,7 @@ class FrameBuffer { const VkPhysicalDeviceMemoryProperties& properties); void Shutdown(); - Result ChangeFrameImageLayout(VkCommandBuffer command, - FrameImageState layout); + Result ChangeFrameImageLayout(CommandBuffer* command, FrameImageState layout); VkFramebuffer GetFrameBuffer() const { return frame_; } const void* GetColorBufferPtr() const { @@ -53,7 +53,7 @@ class FrameBuffer { // Only record the command for copying the image that backs this // framebuffer to the host accessible buffer. The actual submission // of the command must be done later. - Result CopyColorImageToHost(VkCommandBuffer command) { + Result CopyColorImageToHost(CommandBuffer* command) { ChangeFrameImageLayout(command, FrameImageState::kProbe); return color_image_->CopyToHost(command); } diff --git a/src/vulkan/graphics_pipeline.cc b/src/vulkan/graphics_pipeline.cc index 2684f14..7ef24b9 100644 --- a/src/vulkan/graphics_pipeline.cc +++ b/src/vulkan/graphics_pipeline.cc @@ -19,6 +19,7 @@ #include "src/command.h" #include "src/make_unique.h" +#include "src/vulkan/command_pool.h" #include "src/vulkan/device.h" #include "src/vulkan/format_data.h" @@ -651,7 +652,7 @@ Result GraphicsPipeline::CreateVkGraphicsPipeline( Result GraphicsPipeline::Initialize(uint32_t width, uint32_t height, - VkCommandPool pool, + CommandPool* pool, VkQueue queue) { Result r = Pipeline::Initialize(pool, queue); if (!r.IsSuccess()) @@ -687,8 +688,7 @@ Result GraphicsPipeline::SendVertexBufferDataIfNeeded( DeactivateRenderPassIfNeeded(); - return vertex_buffer->SendVertexData(command_->GetCommandBuffer(), - memory_properties_); + return vertex_buffer->SendVertexData(command_.get(), memory_properties_); } Result GraphicsPipeline::SetIndexBuffer(const std::vector<Value>& values) { @@ -706,8 +706,7 @@ Result GraphicsPipeline::SetIndexBuffer(const std::vector<Value>& values) { DeactivateRenderPassIfNeeded(); - r = index_buffer_->SendIndexData(command_->GetCommandBuffer(), - memory_properties_, values); + r = index_buffer_->SendIndexData(command_.get(), memory_properties_, values); if (!r.IsSuccess()) return r; @@ -722,7 +721,7 @@ Result GraphicsPipeline::ActivateRenderPassIfNeeded() { if (render_pass_state_ == RenderPassState::kActive) return {}; - Result r = frame_->ChangeFrameImageLayout(command_->GetCommandBuffer(), + Result r = frame_->ChangeFrameImageLayout(command_.get(), FrameImageState::kClearOrDraw); if (!r.IsSuccess()) return r; @@ -835,7 +834,7 @@ Result GraphicsPipeline::ClearBuffer(const VkClearValue& clear_value, DeactivateRenderPassIfNeeded(); - return frame_->CopyColorImageToHost(command_->GetCommandBuffer()); + return frame_->CopyColorImageToHost(command_.get()); } Result GraphicsPipeline::ResetPipeline() { @@ -918,7 +917,7 @@ Result GraphicsPipeline::Draw(const DrawArraysCommand* command, return r; if (vertex_buffer != nullptr) - vertex_buffer->BindToCommandBuffer(command_->GetCommandBuffer()); + vertex_buffer->BindToCommandBuffer(command_.get()); uint32_t instance_count = command->GetInstanceCount(); if (instance_count == 0 && command->GetVertexCount() != 0) @@ -928,7 +927,7 @@ Result GraphicsPipeline::Draw(const DrawArraysCommand* command, if (!index_buffer_) return Result("Vulkan: Draw indexed is used without given indices"); - r = index_buffer_->BindToCommandBuffer(command_->GetCommandBuffer()); + r = index_buffer_->BindToCommandBuffer(command_.get()); if (!r.IsSuccess()) return r; @@ -950,7 +949,7 @@ Result GraphicsPipeline::Draw(const DrawArraysCommand* command, DeactivateRenderPassIfNeeded(); - r = frame_->CopyColorImageToHost(command_->GetCommandBuffer()); + r = frame_->CopyColorImageToHost(command_.get()); if (!r.IsSuccess()) return r; diff --git a/src/vulkan/graphics_pipeline.h b/src/vulkan/graphics_pipeline.h index e25810a..30567e2 100644 --- a/src/vulkan/graphics_pipeline.h +++ b/src/vulkan/graphics_pipeline.h @@ -34,6 +34,8 @@ class ProbeCommand; namespace vulkan { +class CommandPool; + class GraphicsPipeline : public Pipeline { public: GraphicsPipeline(Device* device, @@ -47,7 +49,7 @@ class GraphicsPipeline : public Pipeline { Result Initialize(uint32_t width, uint32_t height, - VkCommandPool pool, + CommandPool* pool, VkQueue queue); Result SetIndexBuffer(const std::vector<Value>& values); diff --git a/src/vulkan/image.cc b/src/vulkan/image.cc index 2cda372..573b81a 100644 --- a/src/vulkan/image.cc +++ b/src/vulkan/image.cc @@ -16,6 +16,7 @@ #include <limits> +#include "src/vulkan/command_buffer.h" #include "src/vulkan/device.h" #include "src/vulkan/format_data.h" @@ -71,12 +72,14 @@ Result Image::Initialize(VkImageUsageFlags usage) { return Result("Vulkan::Calling vkCreateImage Fail"); } - AllocateResult allocate_result = AllocateAndBindMemoryToVkImage( - image_, &memory_, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, false); - if (!allocate_result.r.IsSuccess()) - return allocate_result.r; + uint32_t memory_type_index = 0; + Result r = AllocateAndBindMemoryToVkImage(image_, &memory_, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + false, &memory_type_index); + if (!r.IsSuccess()) + return r; - Result r = CreateVkImageView(); + r = CreateVkImageView(); if (!r.IsSuccess()) return r; @@ -132,7 +135,7 @@ void Image::Shutdown() { Resource::Shutdown(); } -Result Image::CopyToHost(VkCommandBuffer command) { +Result Image::CopyToHost(CommandBuffer* command) { VkBufferImageCopy copy_region = VkBufferImageCopy(); copy_region.bufferOffset = 0; // Row length of 0 results in tight packing of rows, so the row stride @@ -150,14 +153,14 @@ Result Image::CopyToHost(VkCommandBuffer command) { image_info_.extent.height, 1}; device_->GetPtrs()->vkCmdCopyImageToBuffer( - command, image_, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + command->GetCommandBuffer(), image_, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, GetHostAccessibleBuffer(), 1, ©_region); MemoryBarrier(command); return {}; } -void Image::ChangeLayout(VkCommandBuffer command, +void Image::ChangeLayout(CommandBuffer* command, VkImageLayout old_layout, VkImageLayout new_layout, VkPipelineStageFlags from, @@ -232,8 +235,49 @@ void Image::ChangeLayout(VkCommandBuffer command, break; } - device_->GetPtrs()->vkCmdPipelineBarrier(command, from, to, 0, 0, NULL, 0, - NULL, 1, &barrier); + device_->GetPtrs()->vkCmdPipelineBarrier( + command->GetCommandBuffer(), from, to, 0, 0, NULL, 0, NULL, 1, &barrier); +} + +Result Image::AllocateAndBindMemoryToVkImage(VkImage image, + VkDeviceMemory* memory, + VkMemoryPropertyFlags flags, + bool force_flags, + uint32_t* memory_type_index) { + assert(memory_type_index); + + *memory_type_index = 0; + + if (image == VK_NULL_HANDLE) + return Result("Vulkan::Given VkImage is VK_NULL_HANDLE"); + if (memory == nullptr) + return Result("Vulkan::Given VkDeviceMemory pointer is nullptr"); + + auto requirement = GetVkImageMemoryRequirements(image); + + *memory_type_index = + ChooseMemory(requirement.memoryTypeBits, flags, force_flags); + if (*memory_type_index == std::numeric_limits<uint32_t>::max()) + return Result("Vulkan::Find Proper Memory Fail"); + + Result r = AllocateMemory(memory, requirement.size, *memory_type_index); + if (!r.IsSuccess()) + return r; + + if (device_->GetPtrs()->vkBindImageMemory(device_->GetDevice(), image, + *memory, 0) != VK_SUCCESS) { + return Result("Vulkan::Calling vkBindImageMemory Fail"); + } + + return {}; +} + +const VkMemoryRequirements Image::GetVkImageMemoryRequirements( + VkImage image) const { + VkMemoryRequirements requirement; + device_->GetPtrs()->vkGetImageMemoryRequirements(device_->GetDevice(), image, + &requirement); + return requirement; } } // namespace vulkan diff --git a/src/vulkan/image.h b/src/vulkan/image.h index fdad649..052e320 100644 --- a/src/vulkan/image.h +++ b/src/vulkan/image.h @@ -22,6 +22,7 @@ namespace amber { namespace vulkan { +class CommandBuffer; class Device; class Image : public Resource { @@ -41,26 +42,27 @@ class Image : public Resource { // TODO(jaebaek): Implement CopyToDevice - void ChangeLayout(VkCommandBuffer command, + void ChangeLayout(CommandBuffer* command, VkImageLayout old_layout, VkImageLayout new_layout, VkPipelineStageFlags from, VkPipelineStageFlags to); - // Resource - VkDeviceMemory GetHostAccessMemory() const override { - return Resource::GetHostAccessMemory(); - } - // Only record the command for copying this image to its secondary // host-accessible buffer. The actual submission of the command // must be done later. - Result CopyToHost(VkCommandBuffer command) override; + Result CopyToHost(CommandBuffer* command) override; void Shutdown() override; private: Result CreateVkImageView(); + Result AllocateAndBindMemoryToVkImage(VkImage image, + VkDeviceMemory* memory, + VkMemoryPropertyFlags flags, + bool force_flags, + uint32_t* memory_type_index); + const VkMemoryRequirements GetVkImageMemoryRequirements(VkImage image) const; VkImageCreateInfo image_info_; VkImageAspectFlags aspect_; diff --git a/src/vulkan/index_buffer.cc b/src/vulkan/index_buffer.cc index 59608b2..c826c42 100644 --- a/src/vulkan/index_buffer.cc +++ b/src/vulkan/index_buffer.cc @@ -18,6 +18,7 @@ #include <cstring> #include "src/make_unique.h" +#include "src/vulkan/command_buffer.h" #include "src/vulkan/device.h" #include "src/vulkan/format_data.h" @@ -34,7 +35,7 @@ void IndexBuffer::Shutdown() { } Result IndexBuffer::SendIndexData( - VkCommandBuffer command, + CommandBuffer* command, const VkPhysicalDeviceMemoryProperties& properties, const std::vector<Value>& values) { if (buffer_) { @@ -59,11 +60,12 @@ Result IndexBuffer::SendIndexData( return buffer_->CopyToDevice(command); } -Result IndexBuffer::BindToCommandBuffer(VkCommandBuffer command) { +Result IndexBuffer::BindToCommandBuffer(CommandBuffer* command) { if (!buffer_) return Result("IndexBuffer::BindToCommandBuffer |buffer_| is nullptr"); - device_->GetPtrs()->vkCmdBindIndexBuffer(command, buffer_->GetVkBuffer(), 0, + device_->GetPtrs()->vkCmdBindIndexBuffer(command->GetCommandBuffer(), + buffer_->GetVkBuffer(), 0, VK_INDEX_TYPE_UINT32); return {}; } diff --git a/src/vulkan/index_buffer.h b/src/vulkan/index_buffer.h index fcb44f9..7e1c42c 100644 --- a/src/vulkan/index_buffer.h +++ b/src/vulkan/index_buffer.h @@ -27,6 +27,7 @@ namespace amber { namespace vulkan { +class CommandBuffer; class Device; // A class providing abstraction for index buffer. Only a single @@ -44,12 +45,12 @@ class IndexBuffer { // Assuming that |buffer_| is nullptr and |values| is not empty, // it creates |buffer_| whose size is |sizeof(uint32_t) * values.size()| // and coverts |values| as uint32 values and copies them to |buffer_|. - Result SendIndexData(VkCommandBuffer command, + Result SendIndexData(CommandBuffer* command, const VkPhysicalDeviceMemoryProperties& properties, const std::vector<Value>& values); // Bind |buffer_| as index buffer if it is not nullptr. - Result BindToCommandBuffer(VkCommandBuffer command); + Result BindToCommandBuffer(CommandBuffer* command); private: Device* device_ = nullptr; diff --git a/src/vulkan/pipeline.cc b/src/vulkan/pipeline.cc index 303a435..0983d27 100644 --- a/src/vulkan/pipeline.cc +++ b/src/vulkan/pipeline.cc @@ -59,7 +59,7 @@ ComputePipeline* Pipeline::AsCompute() { return static_cast<ComputePipeline*>(this); } -Result Pipeline::Initialize(VkCommandPool pool, VkQueue queue) { +Result Pipeline::Initialize(CommandPool* pool, VkQueue queue) { push_constant_ = MakeUnique<PushConstant>( device_, physical_device_properties_.limits.maxPushConstantsSize); @@ -268,8 +268,8 @@ Result Pipeline::UpdateDescriptorSetsIfNeeded() { } Result Pipeline::RecordPushConstant() { - return push_constant_->RecordPushConstantVkCommand( - command_->GetCommandBuffer(), pipeline_layout_); + return push_constant_->RecordPushConstantVkCommand(command_.get(), + pipeline_layout_); } Result Pipeline::AddPushConstant(const BufferCommand* command) { @@ -394,7 +394,7 @@ Result Pipeline::SendDescriptorDataToDeviceIfNeeded() { for (auto& info : descriptor_set_info_) { for (auto& desc : info.descriptors_) { - r = desc->RecordCopyDataToResourceIfNeeded(command_->GetCommandBuffer()); + r = desc->RecordCopyDataToResourceIfNeeded(command_.get()); if (!r.IsSuccess()) return r; } @@ -432,7 +432,7 @@ Result Pipeline::ReadbackDescriptorsToHostDataQueue() { for (auto& desc_set : descriptor_set_info_) { for (auto& desc : desc_set.descriptors_) { - r = desc->RecordCopyDataToHost(command_->GetCommandBuffer()); + r = desc->RecordCopyDataToHost(command_.get()); if (!r.IsSuccess()) return r; } diff --git a/src/vulkan/pipeline.h b/src/vulkan/pipeline.h index 8f88b3f..e1b52c4 100644 --- a/src/vulkan/pipeline.h +++ b/src/vulkan/pipeline.h @@ -83,10 +83,8 @@ class Pipeline { uint32_t fence_timeout_ms, const std::vector<VkPipelineShaderStageCreateInfo>& shader_stage_info); - // Create |push_constant_| and |command_|. This method also - // initializes |command_| that abstracts VkCommandBuffer and - // VkFence objects. - Result Initialize(VkCommandPool pool, VkQueue queue); + // Initialize the pipeline. + Result Initialize(CommandPool* pool, VkQueue queue); // Create Vulkan descriptor related objects i.e., // VkDescriptorSetLayout, VkDescriptorPool, VkDescriptorSet if diff --git a/src/vulkan/push_constant.cc b/src/vulkan/push_constant.cc index e54254c..43f6040 100644 --- a/src/vulkan/push_constant.cc +++ b/src/vulkan/push_constant.cc @@ -18,6 +18,7 @@ #include <cassert> #include <limits> +#include "src/vulkan/command_buffer.h" #include "src/vulkan/device.h" namespace amber { @@ -72,7 +73,7 @@ VkPushConstantRange PushConstant::GetPushConstantRange() { } Result PushConstant::RecordPushConstantVkCommand( - VkCommandBuffer command_buffer, + CommandBuffer* command, VkPipelineLayout pipeline_layout) { if (push_constant_data_.empty()) return {}; @@ -96,7 +97,7 @@ Result PushConstant::RecordPushConstantVkCommand( assert(push_const_range.offset % 4U == 0 && push_const_range.size % 4U == 0); device_->GetPtrs()->vkCmdPushConstants( - command_buffer, pipeline_layout, VK_SHADER_STAGE_ALL, + command->GetCommandBuffer(), pipeline_layout, VK_SHADER_STAGE_ALL, push_const_range.offset, push_const_range.size, memory_.data() + push_const_range.offset); return {}; diff --git a/src/vulkan/push_constant.h b/src/vulkan/push_constant.h index 63f218e..7270074 100644 --- a/src/vulkan/push_constant.h +++ b/src/vulkan/push_constant.h @@ -26,6 +26,7 @@ namespace amber { namespace vulkan { +class CommandBuffer; class Device; // Class to handle push constant. @@ -50,7 +51,7 @@ class PushConstant : public Resource { // |max_push_constant_size_|. |command_buffer| is a Vulkan command // buffer that keeps the recorded command and |pipeline_layout| is // the graphics / compute pipeline that it currently uses. - Result RecordPushConstantVkCommand(VkCommandBuffer command_buffer, + Result RecordPushConstantVkCommand(CommandBuffer* command, VkPipelineLayout pipeline_layout); // Add a new set of values in an offset range to the push constants @@ -59,7 +60,7 @@ class PushConstant : public Resource { // Resource VkDeviceMemory GetHostAccessMemory() const override { return VK_NULL_HANDLE; } - Result CopyToHost(VkCommandBuffer) override { + Result CopyToHost(CommandBuffer*) override { return Result("Vulkan: should not call CopyToHost() for PushConstant"); } void Shutdown() override {} diff --git a/src/vulkan/resource.cc b/src/vulkan/resource.cc index 62be694..7581d65 100644 --- a/src/vulkan/resource.cc +++ b/src/vulkan/resource.cc @@ -18,6 +18,7 @@ #include <limits> #include "src/make_unique.h" +#include "src/vulkan/command_buffer.h" #include "src/vulkan/device.h" #include "src/vulkan/format_data.h" @@ -148,13 +149,14 @@ Result Resource::Initialize() { if (!r.IsSuccess()) return r; - AllocateResult allocate_result = AllocateAndBindMemoryToVkBuffer( - host_accessible_buffer_, &host_accessible_memory_, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | - VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, - true); - if (!allocate_result.r.IsSuccess()) - return allocate_result.r; + uint32_t memory_type_index = 0; + r = AllocateAndBindMemoryToVkBuffer(host_accessible_buffer_, + &host_accessible_memory_, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, + true, &memory_type_index); + if (!r.IsSuccess()) + return r; return MapMemory(host_accessible_memory_); } @@ -217,37 +219,37 @@ const VkMemoryRequirements Resource::GetVkBufferMemoryRequirements( return requirement; } -const VkMemoryRequirements Resource::GetVkImageMemoryRequirements( - VkImage image) const { - VkMemoryRequirements requirement; - device_->GetPtrs()->vkGetImageMemoryRequirements(device_->GetDevice(), image, - &requirement); - return requirement; -} +Result Resource::AllocateAndBindMemoryToVkBuffer(VkBuffer buffer, + VkDeviceMemory* memory, + VkMemoryPropertyFlags flags, + bool force_flags, + uint32_t* memory_type_index) { + assert(memory_type_index); -Resource::AllocateResult Resource::AllocateAndBindMemoryToVkBuffer( - VkBuffer buffer, - VkDeviceMemory* memory, - VkMemoryPropertyFlags flags, - bool force_flags) { - if (buffer == VK_NULL_HANDLE) - return {Result("Vulkan::Given VkBuffer is VK_NULL_HANDLE"), 0}; + *memory_type_index = 0; + if (buffer == VK_NULL_HANDLE) + return Result("Vulkan::Given VkBuffer is VK_NULL_HANDLE"); if (memory == nullptr) - return {Result("Vulkan::Given VkDeviceMemory pointer is nullptr"), 0}; + return Result("Vulkan::Given VkDeviceMemory pointer is nullptr"); auto requirement = GetVkBufferMemoryRequirements(buffer); - uint32_t memory_type_index = + *memory_type_index = ChooseMemory(requirement.memoryTypeBits, flags, force_flags); - if (memory_type_index == std::numeric_limits<uint32_t>::max()) - return {Result("Vulkan::Find Proper Memory Fail"), 0}; + if (*memory_type_index == std::numeric_limits<uint32_t>::max()) + return Result("Vulkan::Find Proper Memory Fail"); - Result r = AllocateMemory(memory, requirement.size, memory_type_index); + Result r = AllocateMemory(memory, requirement.size, *memory_type_index); if (!r.IsSuccess()) - return {r, 0}; + return r; - return {BindMemoryToVkBuffer(buffer, *memory), memory_type_index}; + if (device_->GetPtrs()->vkBindBufferMemory(device_->GetDevice(), buffer, + *memory, 0) != VK_SUCCESS) { + return Result("Vulkan::Calling vkBindBufferMemory Fail"); + } + + return {}; } Result Resource::AllocateMemory(VkDeviceMemory* memory, @@ -265,49 +267,6 @@ Result Resource::AllocateMemory(VkDeviceMemory* memory, return {}; } -Result Resource::BindMemoryToVkBuffer(VkBuffer buffer, VkDeviceMemory memory) { - if (device_->GetPtrs()->vkBindBufferMemory(device_->GetDevice(), buffer, - memory, 0) != VK_SUCCESS) { - return Result("Vulkan::Calling vkBindBufferMemory Fail"); - } - - return {}; -} - -Resource::AllocateResult Resource::AllocateAndBindMemoryToVkImage( - VkImage image, - VkDeviceMemory* memory, - VkMemoryPropertyFlags flags, - bool force_flags) { - if (image == VK_NULL_HANDLE) - return {Result("Vulkan::Given VkImage is VK_NULL_HANDLE"), 0}; - - if (memory == nullptr) - return {Result("Vulkan::Given VkDeviceMemory pointer is nullptr"), 0}; - - auto requirement = GetVkImageMemoryRequirements(image); - - uint32_t memory_type_index = - ChooseMemory(requirement.memoryTypeBits, flags, force_flags); - if (memory_type_index == std::numeric_limits<uint32_t>::max()) - return {Result("Vulkan::Find Proper Memory Fail"), 0}; - - Result r = AllocateMemory(memory, requirement.size, memory_type_index); - if (!r.IsSuccess()) - return {r, 0}; - - return {BindMemoryToVkImage(image, *memory), memory_type_index}; -} - -Result Resource::BindMemoryToVkImage(VkImage image, VkDeviceMemory memory) { - if (device_->GetPtrs()->vkBindImageMemory(device_->GetDevice(), image, memory, - 0) != VK_SUCCESS) { - return Result("Vulkan::Calling vkBindImageMemory Fail"); - } - - return {}; -} - Result Resource::MapMemory(VkDeviceMemory memory) { if (device_->GetPtrs()->vkMapMemory(device_->GetDevice(), memory, 0, VK_WHOLE_SIZE, 0, @@ -322,7 +281,7 @@ void Resource::UnMapMemory(VkDeviceMemory memory) { device_->GetPtrs()->vkUnmapMemory(device_->GetDevice(), memory); } -void Resource::MemoryBarrier(VkCommandBuffer command) { +void Resource::MemoryBarrier(CommandBuffer* command) { // TODO(jaebaek): Current memory barrier is natively implemented. // Update it with the following access flags: // (r = read, w = write) @@ -344,7 +303,7 @@ void Resource::MemoryBarrier(VkCommandBuffer command) { // ReadOnly Descriptors host w shader r // transfer w transfer r device_->GetPtrs()->vkCmdPipelineBarrier( - command, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + command->GetCommandBuffer(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 1, &kMemoryBarrierForAll, 0, nullptr, 0, nullptr); } diff --git a/src/vulkan/resource.h b/src/vulkan/resource.h index 538bbca..6d937c0 100644 --- a/src/vulkan/resource.h +++ b/src/vulkan/resource.h @@ -26,6 +26,7 @@ namespace amber { namespace vulkan { +class CommandBuffer; class Device; // Contain information of filling memory @@ -50,7 +51,7 @@ class Resource { return host_accessible_memory_; } - virtual Result CopyToHost(VkCommandBuffer command) = 0; + virtual Result CopyToHost(CommandBuffer* command) = 0; virtual void Shutdown(); @@ -74,33 +75,11 @@ class Resource { VkBuffer GetHostAccessibleBuffer() const { return host_accessible_buffer_; } - struct AllocateResult { - Result r; - uint32_t memory_type_index; - }; - - AllocateResult AllocateAndBindMemoryToVkBuffer(VkBuffer buffer, - VkDeviceMemory* memory, - VkMemoryPropertyFlags flags, - bool force_flags); - AllocateResult AllocateAndBindMemoryToVkImage(VkImage image, - VkDeviceMemory* memory, - VkMemoryPropertyFlags flags, - bool force_flags); - - bool IsMemoryHostAccessible(uint32_t memory_type_index) { - return (physical_memory_properties_.memoryTypes[memory_type_index] - .propertyFlags & - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; - } - - bool IsMemoryHostCoherent(uint32_t memory_type_index) { - return (physical_memory_properties_.memoryTypes[memory_type_index] - .propertyFlags & - VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == - VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; - } + Result AllocateAndBindMemoryToVkBuffer(VkBuffer buffer, + VkDeviceMemory* memory, + VkMemoryPropertyFlags flags, + bool force_flags, + uint32_t* memory_type_index); Result MapMemory(VkDeviceMemory memory); void UnMapMemory(VkDeviceMemory memory); @@ -112,11 +91,12 @@ class Resource { // Make all memory operations before calling this method effective i.e., // prevent hazards caused by out-of-order execution. - void MemoryBarrier(VkCommandBuffer command); + void MemoryBarrier(CommandBuffer* command); - Device* device_ = nullptr; + const VkPhysicalDeviceMemoryProperties& GetMemoryProperties() const { + return physical_memory_properties_; + } - private: uint32_t ChooseMemory(uint32_t memory_type_bits, VkMemoryPropertyFlags flags, bool force_flags); @@ -124,13 +104,12 @@ class Resource { VkDeviceSize size, uint32_t memory_type_index); - Result BindMemoryToVkBuffer(VkBuffer buffer, VkDeviceMemory memory); + Device* device_ = nullptr; + + private: const VkMemoryRequirements GetVkBufferMemoryRequirements( VkBuffer buffer) const; - Result BindMemoryToVkImage(VkImage image, VkDeviceMemory memory); - const VkMemoryRequirements GetVkImageMemoryRequirements(VkImage image) const; - size_t size_in_bytes_ = 0; VkPhysicalDeviceMemoryProperties physical_memory_properties_; diff --git a/src/vulkan/vertex_buffer.cc b/src/vulkan/vertex_buffer.cc index a09d64e..babfe85 100644 --- a/src/vulkan/vertex_buffer.cc +++ b/src/vulkan/vertex_buffer.cc @@ -18,6 +18,7 @@ #include <cstring> #include "src/make_unique.h" +#include "src/vulkan/command_buffer.h" #include "src/vulkan/device.h" #include "src/vulkan/format_data.h" @@ -213,7 +214,7 @@ void VertexBuffer::SetData(uint8_t location, data_.push_back(values); } -Result VertexBuffer::FillVertexBufferWithData(VkCommandBuffer command) { +Result VertexBuffer::FillVertexBufferWithData(CommandBuffer* command) { // Send vertex data from host to device. uint8_t* ptr_in_stride_begin = static_cast<uint8_t*>(buffer_->HostAccessibleMemoryPtr()); @@ -258,15 +259,16 @@ Result VertexBuffer::FillVertexBufferWithData(VkCommandBuffer command) { return buffer_->CopyToDevice(command); } -void VertexBuffer::BindToCommandBuffer(VkCommandBuffer command) { +void VertexBuffer::BindToCommandBuffer(CommandBuffer* command) { const VkDeviceSize offset = 0; const VkBuffer buffer = buffer_->GetVkBuffer(); // TODO(jaebaek): Support multiple binding - device_->GetPtrs()->vkCmdBindVertexBuffers(command, 0, 1, &buffer, &offset); + device_->GetPtrs()->vkCmdBindVertexBuffers(command->GetCommandBuffer(), 0, 1, + &buffer, &offset); } Result VertexBuffer::SendVertexData( - VkCommandBuffer command, + CommandBuffer* command, const VkPhysicalDeviceMemoryProperties& properties) { if (!is_vertex_data_pending_) return Result("Vulkan::Vertices data was already sent"); diff --git a/src/vulkan/vertex_buffer.h b/src/vulkan/vertex_buffer.h index 428bfac..cdf6e63 100644 --- a/src/vulkan/vertex_buffer.h +++ b/src/vulkan/vertex_buffer.h @@ -27,6 +27,7 @@ namespace amber { namespace vulkan { +class CommandBuffer; class Device; class VertexBuffer { @@ -36,7 +37,7 @@ class VertexBuffer { void Shutdown(); - Result SendVertexData(VkCommandBuffer command, + Result SendVertexData(CommandBuffer* command, const VkPhysicalDeviceMemoryProperties& properties); bool VertexDataSent() const { return !is_vertex_data_pending_; } @@ -65,13 +66,13 @@ class VertexBuffer { return data_[0].size() / formats_[0].GetComponents().size(); } - void BindToCommandBuffer(VkCommandBuffer command); + void BindToCommandBuffer(CommandBuffer* command); // Must be used only for unit tests. void SetBufferForTest(std::unique_ptr<Buffer> buffer); private: - Result FillVertexBufferWithData(VkCommandBuffer command); + Result FillVertexBufferWithData(CommandBuffer* command); // Return |stride_in_bytes_| rounded up by 4. uint32_t Get4BytesAlignedStride() const { diff --git a/src/vulkan/vertex_buffer_test.cc b/src/vulkan/vertex_buffer_test.cc index 814305c..0d01ef2 100644 --- a/src/vulkan/vertex_buffer_test.cc +++ b/src/vulkan/vertex_buffer_test.cc @@ -42,7 +42,7 @@ class BufferForTest : public Buffer { void* HostAccessibleMemoryPtr() const override { return memory_ptr_; } - Result CopyToDevice(VkCommandBuffer) override { return Result(); } + Result CopyToDevice(CommandBuffer*) override { return Result(); } private: std::vector<uint8_t> memory_; @@ -66,8 +66,7 @@ class VertexBufferTest : public testing::Test { const Format& format, const std::vector<Value>& values) { vertex_buffer_->SetData(location, format, values); - VkCommandBuffer null_cmd_buf = VK_NULL_HANDLE; - return vertex_buffer_->SendVertexData(null_cmd_buf, kMemoryProperties); + return vertex_buffer_->SendVertexData(nullptr, kMemoryProperties); } const void* GetVkBufferPtr() const { return buffer_memory_; } |