| // 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 |
| // |
| // http://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. |
| |
| #include "src/vulkan/transfer_buffer.h" |
| |
| #include "src/vulkan/command_buffer.h" |
| #include "src/vulkan/device.h" |
| |
| namespace amber { |
| namespace vulkan { |
| |
| TransferBuffer::TransferBuffer(Device* device, |
| uint32_t size_in_bytes, |
| Format* format) |
| : Resource(device, size_in_bytes) { |
| if (format) |
| format_ = device->GetVkFormat(*format); |
| } |
| |
| TransferBuffer::~TransferBuffer() { |
| if (device_) { |
| device_->GetPtrs()->vkDestroyBufferView(device_->GetVkDevice(), view_, |
| nullptr); |
| |
| if (memory_ != VK_NULL_HANDLE) { |
| UnMapMemory(memory_); |
| device_->GetPtrs()->vkFreeMemory(device_->GetVkDevice(), memory_, |
| nullptr); |
| } |
| |
| device_->GetPtrs()->vkDestroyBuffer(device_->GetVkDevice(), buffer_, |
| nullptr); |
| } |
| } |
| |
| Result TransferBuffer::Initialize() { |
| if (buffer_) { |
| return Result( |
| "Vulkan: TransferBuffer::Initialize() transfer buffer already " |
| "initialized."); |
| } |
| |
| Result r = CreateVkBuffer(&buffer_, usage_flags_); |
| if (!r.IsSuccess()) |
| return r; |
| |
| uint32_t memory_type_index = 0; |
| r = AllocateAndBindMemoryToVkBuffer(buffer_, &memory_, |
| VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | |
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, |
| true, &memory_type_index); |
| if (!r.IsSuccess()) |
| return r; |
| |
| // Create buffer view |
| if (usage_flags_ & (VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | |
| VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT)) { |
| VkBufferViewCreateInfo buffer_view_info = VkBufferViewCreateInfo(); |
| buffer_view_info.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO; |
| buffer_view_info.buffer = buffer_; |
| buffer_view_info.format = format_; |
| buffer_view_info.offset = 0; |
| buffer_view_info.range = VK_WHOLE_SIZE; |
| |
| if (device_->GetPtrs()->vkCreateBufferView(device_->GetVkDevice(), |
| &buffer_view_info, nullptr, |
| &view_) != VK_SUCCESS) { |
| return Result("Vulkan::Calling vkCreateBufferView Fail"); |
| } |
| } |
| |
| if (!device_->IsMemoryHostAccessible(memory_type_index) || |
| !device_->IsMemoryHostCoherent(memory_type_index)) { |
| return Result( |
| "Vulkan: TransferBuffer::Initialize() buffer is not host accessible or" |
| " not host coherent."); |
| } |
| |
| return MapMemory(memory_); |
| } |
| |
| void TransferBuffer::CopyToDevice(CommandBuffer* command_buffer) { |
| // This is redundant because this buffer is always host visible |
| // and coherent and vkQueueSubmit will make writes from host |
| // available (See chapter 6.9. "Host Write Ordering Guarantees" in |
| // Vulkan spec), but we prefer to keep it to simplify our own code. |
| MemoryBarrier(command_buffer); |
| } |
| |
| void TransferBuffer::CopyToHost(CommandBuffer* command_buffer) { |
| MemoryBarrier(command_buffer); |
| } |
| |
| } // namespace vulkan |
| } // namespace amber |