1 // Copyright 2018 The Amber Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "src/vulkan/transfer_buffer.h"
16
17 #include "src/vulkan/command_buffer.h"
18 #include "src/vulkan/device.h"
19
20 namespace amber {
21 namespace vulkan {
22
TransferBuffer(Device * device,uint32_t size_in_bytes,Format * format)23 TransferBuffer::TransferBuffer(Device* device,
24 uint32_t size_in_bytes,
25 Format* format)
26 : Resource(device, size_in_bytes) {
27 if (format)
28 format_ = device->GetVkFormat(*format);
29 }
30
~TransferBuffer()31 TransferBuffer::~TransferBuffer() {
32 if (device_) {
33 device_->GetPtrs()->vkDestroyBufferView(device_->GetVkDevice(), view_,
34 nullptr);
35
36 if (memory_ != VK_NULL_HANDLE) {
37 UnMapMemory(memory_);
38 device_->GetPtrs()->vkFreeMemory(device_->GetVkDevice(), memory_,
39 nullptr);
40 }
41
42 device_->GetPtrs()->vkDestroyBuffer(device_->GetVkDevice(), buffer_,
43 nullptr);
44 }
45 }
46
Initialize(const VkBufferUsageFlags usage)47 Result TransferBuffer::Initialize(const VkBufferUsageFlags usage) {
48 Result r = CreateVkBuffer(&buffer_, usage);
49 if (!r.IsSuccess())
50 return r;
51
52 uint32_t memory_type_index = 0;
53 r = AllocateAndBindMemoryToVkBuffer(buffer_, &memory_,
54 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
55 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
56 true, &memory_type_index);
57 if (!r.IsSuccess())
58 return r;
59
60 // Create buffer view
61 if (usage & (VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT |
62 VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT)) {
63 VkBufferViewCreateInfo buffer_view_info = VkBufferViewCreateInfo();
64 buffer_view_info.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
65 buffer_view_info.buffer = buffer_;
66 buffer_view_info.format = format_;
67 buffer_view_info.offset = 0;
68 buffer_view_info.range = VK_WHOLE_SIZE;
69
70 if (device_->GetPtrs()->vkCreateBufferView(device_->GetVkDevice(),
71 &buffer_view_info, nullptr,
72 &view_) != VK_SUCCESS) {
73 return Result("Vulkan::Calling vkCreateBufferView Fail");
74 }
75 }
76
77 if (!device_->IsMemoryHostAccessible(memory_type_index) ||
78 !device_->IsMemoryHostCoherent(memory_type_index)) {
79 return Result(
80 "Vulkan: TransferBuffer::Initialize() buffer is not host accessible or"
81 " not host coherent.");
82 }
83
84 return MapMemory(memory_);
85 }
86
CopyToDevice(CommandBuffer * command_buffer)87 void TransferBuffer::CopyToDevice(CommandBuffer* command_buffer) {
88 // This is redundant because this buffer is always host visible
89 // and coherent and vkQueueSubmit will make writes from host
90 // available (See chapter 6.9. "Host Write Ordering Guarantees" in
91 // Vulkan spec), but we prefer to keep it to simplify our own code.
92 MemoryBarrier(command_buffer);
93 }
94
CopyToHost(CommandBuffer * command_buffer)95 void TransferBuffer::CopyToHost(CommandBuffer* command_buffer) {
96 MemoryBarrier(command_buffer);
97 }
98
99 } // namespace vulkan
100 } // namespace amber
101