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