// 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 #include "src/vulkan/command_buffer.h" #include "src/vulkan/device.h" namespace amber { namespace vulkan { TransferBuffer::TransferBuffer(Device* device, uint32_t size_in_bytes) : Resource(device, size_in_bytes) {} TransferBuffer::~TransferBuffer() { if (memory_ != VK_NULL_HANDLE) { UnMapMemory(memory_); device_->GetPtrs()->vkFreeMemory(device_->GetVkDevice(), memory_, nullptr); } if (buffer_ != VK_NULL_HANDLE) device_->GetPtrs()->vkDestroyBuffer(device_->GetVkDevice(), buffer_, nullptr); } Result TransferBuffer::Initialize(const VkBufferUsageFlags usage) { Result r = CreateVkBuffer(&buffer_, usage); 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; 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); } void TransferBuffer::UpdateMemoryWithRawData( const std::vector& raw_data) { size_t effective_size = raw_data.size() > GetSizeInBytes() ? GetSizeInBytes() : raw_data.size(); std::memcpy(HostAccessibleMemoryPtr(), raw_data.data(), effective_size); } } // namespace vulkan } // namespace amber