Line data Source code
1 : /* Copyright (C) 2023 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
4 : * 0 A.D. is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 2 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * 0 A.D. is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : #include "precompiled.h"
19 :
20 : #include "Buffer.h"
21 :
22 : #include "renderer/backend/vulkan/Device.h"
23 :
24 : namespace Renderer
25 : {
26 :
27 : namespace Backend
28 : {
29 :
30 : namespace Vulkan
31 : {
32 :
33 : // static
34 0 : std::unique_ptr<CBuffer> CBuffer::Create(
35 : CDevice* device, const char* name, const Type type, const uint32_t size,
36 : const bool dynamic)
37 : {
38 0 : std::unique_ptr<CBuffer> buffer(new CBuffer());
39 0 : buffer->m_Device = device;
40 0 : buffer->m_Type = type;
41 0 : buffer->m_Size = size;
42 0 : buffer->m_Dynamic = dynamic;
43 :
44 0 : VkMemoryPropertyFlags properties = 0;
45 0 : VkBufferUsageFlags usage = VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM;
46 0 : VmaMemoryUsage memoryUsage = VMA_MEMORY_USAGE_AUTO;
47 0 : switch (type)
48 : {
49 0 : case Type::VERTEX:
50 0 : usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
51 0 : properties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
52 0 : memoryUsage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
53 0 : break;
54 0 : case Type::INDEX:
55 0 : usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
56 0 : properties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
57 0 : memoryUsage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
58 0 : break;
59 0 : case Type::UPLOAD:
60 0 : usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
61 0 : properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
62 0 : break;
63 0 : case Type::UNIFORM:
64 0 : usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
65 0 : properties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
66 0 : memoryUsage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
67 0 : break;
68 : }
69 :
70 0 : VkBufferCreateInfo bufferCreateInfo{};
71 0 : bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
72 0 : bufferCreateInfo.size = size;
73 0 : bufferCreateInfo.usage = usage;
74 0 : bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
75 :
76 0 : VmaAllocationCreateInfo allocationCreateInfo{};
77 0 : if (type == Type::UPLOAD)
78 0 : allocationCreateInfo.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
79 : #ifndef NDEBUG
80 0 : allocationCreateInfo.flags |= VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT;
81 0 : allocationCreateInfo.pUserData = const_cast<char*>(name);
82 : #endif
83 0 : allocationCreateInfo.requiredFlags = properties;
84 0 : allocationCreateInfo.usage = memoryUsage;
85 0 : const VkResult createBufferResult = vmaCreateBuffer(
86 : device->GetVMAAllocator(), &bufferCreateInfo, &allocationCreateInfo,
87 0 : &buffer->m_Buffer, &buffer->m_Allocation, &buffer->m_AllocationInfo);
88 0 : if (createBufferResult != VK_SUCCESS)
89 : {
90 0 : LOGERROR("Failed to create VkBuffer: %d", static_cast<int>(createBufferResult));
91 0 : return nullptr;
92 : }
93 :
94 0 : device->SetObjectName(VK_OBJECT_TYPE_BUFFER, buffer->m_Buffer, name);
95 :
96 0 : return buffer;
97 : }
98 :
99 : CBuffer::CBuffer() = default;
100 :
101 0 : CBuffer::~CBuffer()
102 : {
103 0 : if (m_Allocation != VK_NULL_HANDLE)
104 0 : m_Device->ScheduleObjectToDestroy(
105 0 : VK_OBJECT_TYPE_BUFFER, m_Buffer, m_Allocation);
106 0 : }
107 :
108 0 : IDevice* CBuffer::GetDevice()
109 : {
110 0 : return m_Device;
111 : }
112 :
113 : } // namespace Vulkan
114 :
115 : } // namespace Backend
116 :
117 3 : } // namespace Renderer
|