aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordan sinclair <dj2@everburning.com>2019-04-05 22:52:43 -0400
committerGitHub <noreply@github.com>2019-04-05 22:52:43 -0400
commit6a392679a1bb1feb7ae8d93ab2e70cf4fc8c6bb0 (patch)
treeb045589655ff50445231fdd1a0eca2b25a437d57
parent7f72bbfdc7ffde932fc35291e7d041497bb24a21 (diff)
downloadamber-6a392679a1bb1feb7ae8d93ab2e70cf4fc8c6bb0.tar.gz
[vulkan] copy fb data onto device (#452)
This CL copies the framebuffer data from the host to the device before each draw/clear command. This allows sharing a framebuffer over multiple pipelines.
-rw-r--r--src/vulkan/frame_buffer.cc19
-rw-r--r--src/vulkan/frame_buffer.h2
-rw-r--r--src/vulkan/resource.h1
-rw-r--r--src/vulkan/transfer_buffer.h8
-rw-r--r--src/vulkan/transfer_image.cc17
-rw-r--r--src/vulkan/transfer_image.h2
-rw-r--r--src/vulkan/vk-funcs.inc1
7 files changed, 45 insertions, 5 deletions
diff --git a/src/vulkan/frame_buffer.cc b/src/vulkan/frame_buffer.cc
index b5de381..d95cae2 100644
--- a/src/vulkan/frame_buffer.cc
+++ b/src/vulkan/frame_buffer.cc
@@ -167,5 +167,24 @@ void FrameBuffer::CopyImagesToBuffers() {
}
}
+void FrameBuffer::TransferColorImagesToDevice(CommandBuffer* command) {
+ for (auto& img : color_images_)
+ img->CopyToDevice(command);
+}
+
+void FrameBuffer::CopyBuffersToImages() {
+ for (size_t i = 0; i < color_images_.size(); ++i) {
+ auto& img = color_images_[i];
+ auto* info = color_attachments_[i];
+ auto* values = info->buffer->ValuePtr();
+ // Nothing to do if our local buffer is empty
+ if (values->empty())
+ continue;
+
+ std::memcpy(img->HostAccessibleMemoryPtr(), values->data(),
+ info->buffer->GetSizeInBytes());
+ }
+}
+
} // namespace vulkan
} // namespace amber
diff --git a/src/vulkan/frame_buffer.h b/src/vulkan/frame_buffer.h
index 6372401..c101bf5 100644
--- a/src/vulkan/frame_buffer.h
+++ b/src/vulkan/frame_buffer.h
@@ -51,8 +51,10 @@ class FrameBuffer {
// framebuffer to the host accessible buffer. The actual submission
// of the command must be done later.
void TransferColorImagesToHost(CommandBuffer* command);
+ void TransferColorImagesToDevice(CommandBuffer* command);
void CopyImagesToBuffers();
+ void CopyBuffersToImages();
uint32_t GetWidth() const { return width_; }
uint32_t GetHeight() const { return height_; }
diff --git a/src/vulkan/resource.h b/src/vulkan/resource.h
index 48c3c37..934c9e8 100644
--- a/src/vulkan/resource.h
+++ b/src/vulkan/resource.h
@@ -48,6 +48,7 @@ class Resource {
virtual ~Resource();
virtual void CopyToHost(CommandBuffer* command) = 0;
+ virtual void CopyToDevice(CommandBuffer* command) = 0;
void* HostAccessibleMemoryPtr() const { return memory_ptr_; }
diff --git a/src/vulkan/transfer_buffer.h b/src/vulkan/transfer_buffer.h
index 0604cd6..6085563 100644
--- a/src/vulkan/transfer_buffer.h
+++ b/src/vulkan/transfer_buffer.h
@@ -47,16 +47,16 @@ class TransferBuffer : 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 void CopyToDevice(CommandBuffer* command);
-
- // Fill memory from 0 to |raw_data.size()| with |raw_data|.
- void UpdateMemoryWithRawData(const std::vector<uint8_t>& raw_data);
+ void CopyToDevice(CommandBuffer* command) override;
// 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.
void CopyToHost(CommandBuffer* command) override;
+ // Fill memory from 0 to |raw_data.size()| with |raw_data|.
+ void UpdateMemoryWithRawData(const std::vector<uint8_t>& raw_data);
+
private:
VkBuffer buffer_ = VK_NULL_HANDLE;
VkDeviceMemory memory_ = VK_NULL_HANDLE;
diff --git a/src/vulkan/transfer_image.cc b/src/vulkan/transfer_image.cc
index d707e47..68a4744 100644
--- a/src/vulkan/transfer_image.cc
+++ b/src/vulkan/transfer_image.cc
@@ -154,7 +154,7 @@ Result TransferImage::CreateVkImageView() {
return {};
}
-void TransferImage::CopyToHost(CommandBuffer* command) {
+VkBufferImageCopy TransferImage::CreateBufferImageCopy() {
VkBufferImageCopy copy_region = VkBufferImageCopy();
copy_region.bufferOffset = 0;
// Row length of 0 results in tight packing of rows, so the row stride
@@ -170,6 +170,11 @@ void TransferImage::CopyToHost(CommandBuffer* command) {
copy_region.imageOffset = {0, 0, 0};
copy_region.imageExtent = {image_info_.extent.width,
image_info_.extent.height, 1};
+ return copy_region;
+}
+
+void TransferImage::CopyToHost(CommandBuffer* command) {
+ auto copy_region = CreateBufferImageCopy();
device_->GetPtrs()->vkCmdCopyImageToBuffer(
command->GetVkCommandBuffer(), image_,
@@ -179,6 +184,16 @@ void TransferImage::CopyToHost(CommandBuffer* command) {
MemoryBarrier(command);
}
+void TransferImage::CopyToDevice(CommandBuffer* command) {
+ auto copy_region = CreateBufferImageCopy();
+
+ device_->GetPtrs()->vkCmdCopyBufferToImage(
+ command->GetVkCommandBuffer(), host_accessible_buffer_, image_,
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &copy_region);
+
+ MemoryBarrier(command);
+}
+
void TransferImage::ImageBarrier(CommandBuffer* command,
VkImageLayout to_layout,
VkPipelineStageFlags to_stage) {
diff --git a/src/vulkan/transfer_image.h b/src/vulkan/transfer_image.h
index 480c07c..88ad3ce 100644
--- a/src/vulkan/transfer_image.h
+++ b/src/vulkan/transfer_image.h
@@ -47,6 +47,7 @@ class TransferImage : public Resource {
// host-accessible buffer. The actual submission of the command
// must be done later.
void CopyToHost(CommandBuffer* command) override;
+ void CopyToDevice(CommandBuffer* command) override;
private:
Result CreateVkImageView();
@@ -55,6 +56,7 @@ class TransferImage : public Resource {
VkMemoryPropertyFlags flags,
bool force_flags,
uint32_t* memory_type_index);
+ VkBufferImageCopy CreateBufferImageCopy();
VkBuffer host_accessible_buffer_ = VK_NULL_HANDLE;
VkDeviceMemory host_accessible_memory_ = VK_NULL_HANDLE;
diff --git a/src/vulkan/vk-funcs.inc b/src/vulkan/vk-funcs.inc
index ca2f2c5..36d2864 100644
--- a/src/vulkan/vk-funcs.inc
+++ b/src/vulkan/vk-funcs.inc
@@ -11,6 +11,7 @@ AMBER_VK_FUNC(vkCmdBindPipeline)
AMBER_VK_FUNC(vkCmdBindVertexBuffers)
AMBER_VK_FUNC(vkCmdClearAttachments)
AMBER_VK_FUNC(vkCmdCopyBuffer)
+AMBER_VK_FUNC(vkCmdCopyBufferToImage)
AMBER_VK_FUNC(vkCmdCopyImageToBuffer)
AMBER_VK_FUNC(vkCmdDispatch)
AMBER_VK_FUNC(vkCmdDraw)