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()47 Result TransferBuffer::Initialize() {
48 if (buffer_) {
49 return Result(
50 "Vulkan: TransferBuffer::Initialize() transfer buffer already "
51 "initialized.");
52 }
53
54 Result r = CreateVkBuffer(&buffer_, usage_flags_);
55 if (!r.IsSuccess())
56 return r;
57
58 uint32_t memory_type_index = 0;
59 r = AllocateAndBindMemoryToVkBuffer(buffer_, &memory_,
60 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
61 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
62 true, &memory_type_index);
63 if (!r.IsSuccess())
64 return r;
65
66 // Create buffer view
67 if (usage_flags_ & (VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT |
68 VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT)) {
69 VkBufferViewCreateInfo buffer_view_info = VkBufferViewCreateInfo();
70 buffer_view_info.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
71 buffer_view_info.buffer = buffer_;
72 buffer_view_info.format = format_;
73 buffer_view_info.offset = 0;
74 buffer_view_info.range = VK_WHOLE_SIZE;
75
76 if (device_->GetPtrs()->vkCreateBufferView(device_->GetVkDevice(),
77 &buffer_view_info, nullptr,
78 &view_) != VK_SUCCESS) {
79 return Result("Vulkan::Calling vkCreateBufferView Fail");
80 }
81 }
82
83 if (!device_->IsMemoryHostAccessible(memory_type_index) ||
84 !device_->IsMemoryHostCoherent(memory_type_index)) {
85 return Result(
86 "Vulkan: TransferBuffer::Initialize() buffer is not host accessible or"
87 " not host coherent.");
88 }
89
90 return MapMemory(memory_);
91 }
92
CopyToDevice(CommandBuffer * command_buffer)93 void TransferBuffer::CopyToDevice(CommandBuffer* command_buffer) {
94 // This is redundant because this buffer is always host visible
95 // and coherent and vkQueueSubmit will make writes from host
96 // available (See chapter 6.9. "Host Write Ordering Guarantees" in
97 // Vulkan spec), but we prefer to keep it to simplify our own code.
98 MemoryBarrier(command_buffer);
99 }
100
CopyToHost(CommandBuffer * command_buffer)101 void TransferBuffer::CopyToHost(CommandBuffer* command_buffer) {
102 MemoryBarrier(command_buffer);
103 }
104
105 } // namespace vulkan
106 } // namespace amber
107