Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/virtio/vulkan/vn_buffer.c
4560 views
1
/*
2
* Copyright 2019 Google LLC
3
* SPDX-License-Identifier: MIT
4
*
5
* based in part on anv and radv which are:
6
* Copyright © 2015 Intel Corporation
7
* Copyright © 2016 Red Hat.
8
* Copyright © 2016 Bas Nieuwenhuizen
9
*/
10
11
#include "vn_buffer.h"
12
13
#include "venus-protocol/vn_protocol_driver_buffer.h"
14
#include "venus-protocol/vn_protocol_driver_buffer_view.h"
15
16
#include "vn_android.h"
17
#include "vn_device.h"
18
#include "vn_device_memory.h"
19
20
/* buffer commands */
21
22
VkResult
23
vn_buffer_create(struct vn_device *dev,
24
const VkBufferCreateInfo *create_info,
25
const VkAllocationCallbacks *alloc,
26
struct vn_buffer **out_buf)
27
{
28
VkDevice device = vn_device_to_handle(dev);
29
struct vn_buffer *buf = NULL;
30
VkBuffer buffer = VK_NULL_HANDLE;
31
VkResult result;
32
33
buf = vk_zalloc(alloc, sizeof(*buf), VN_DEFAULT_ALIGN,
34
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
35
if (!buf)
36
return VK_ERROR_OUT_OF_HOST_MEMORY;
37
38
vn_object_base_init(&buf->base, VK_OBJECT_TYPE_BUFFER, &dev->base);
39
40
buffer = vn_buffer_to_handle(buf);
41
/* TODO async */
42
result = vn_call_vkCreateBuffer(dev->instance, device, create_info, NULL,
43
&buffer);
44
if (result != VK_SUCCESS) {
45
vk_free(alloc, buf);
46
return result;
47
}
48
49
/* TODO add a per-device cache for the requirements */
50
buf->memory_requirements.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
51
buf->memory_requirements.pNext = &buf->dedicated_requirements;
52
buf->dedicated_requirements.sType =
53
VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
54
buf->dedicated_requirements.pNext = NULL;
55
56
vn_call_vkGetBufferMemoryRequirements2(
57
dev->instance, device,
58
&(VkBufferMemoryRequirementsInfo2){
59
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,
60
.buffer = buffer,
61
},
62
&buf->memory_requirements);
63
64
*out_buf = buf;
65
66
return VK_SUCCESS;
67
}
68
69
VkResult
70
vn_CreateBuffer(VkDevice device,
71
const VkBufferCreateInfo *pCreateInfo,
72
const VkAllocationCallbacks *pAllocator,
73
VkBuffer *pBuffer)
74
{
75
struct vn_device *dev = vn_device_from_handle(device);
76
const VkAllocationCallbacks *alloc =
77
pAllocator ? pAllocator : &dev->base.base.alloc;
78
struct vn_buffer *buf = NULL;
79
VkResult result;
80
81
const VkExternalMemoryBufferCreateInfo *external_info =
82
vk_find_struct_const(pCreateInfo->pNext,
83
EXTERNAL_MEMORY_BUFFER_CREATE_INFO);
84
const bool ahb_info =
85
external_info &&
86
external_info->handleTypes ==
87
VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
88
89
if (ahb_info)
90
result = vn_android_buffer_from_ahb(dev, pCreateInfo, alloc, &buf);
91
else
92
result = vn_buffer_create(dev, pCreateInfo, alloc, &buf);
93
94
if (result != VK_SUCCESS)
95
return vn_error(dev->instance, result);
96
97
*pBuffer = vn_buffer_to_handle(buf);
98
99
return VK_SUCCESS;
100
}
101
102
void
103
vn_DestroyBuffer(VkDevice device,
104
VkBuffer buffer,
105
const VkAllocationCallbacks *pAllocator)
106
{
107
struct vn_device *dev = vn_device_from_handle(device);
108
struct vn_buffer *buf = vn_buffer_from_handle(buffer);
109
const VkAllocationCallbacks *alloc =
110
pAllocator ? pAllocator : &dev->base.base.alloc;
111
112
if (!buf)
113
return;
114
115
vn_async_vkDestroyBuffer(dev->instance, device, buffer, NULL);
116
117
vn_object_base_fini(&buf->base);
118
vk_free(alloc, buf);
119
}
120
121
VkDeviceAddress
122
vn_GetBufferDeviceAddress(VkDevice device,
123
const VkBufferDeviceAddressInfo *pInfo)
124
{
125
struct vn_device *dev = vn_device_from_handle(device);
126
127
return vn_call_vkGetBufferDeviceAddress(dev->instance, device, pInfo);
128
}
129
130
uint64_t
131
vn_GetBufferOpaqueCaptureAddress(VkDevice device,
132
const VkBufferDeviceAddressInfo *pInfo)
133
{
134
struct vn_device *dev = vn_device_from_handle(device);
135
136
return vn_call_vkGetBufferOpaqueCaptureAddress(dev->instance, device,
137
pInfo);
138
}
139
140
void
141
vn_GetBufferMemoryRequirements(VkDevice device,
142
VkBuffer buffer,
143
VkMemoryRequirements *pMemoryRequirements)
144
{
145
const struct vn_buffer *buf = vn_buffer_from_handle(buffer);
146
147
*pMemoryRequirements = buf->memory_requirements.memoryRequirements;
148
}
149
150
void
151
vn_GetBufferMemoryRequirements2(VkDevice device,
152
const VkBufferMemoryRequirementsInfo2 *pInfo,
153
VkMemoryRequirements2 *pMemoryRequirements)
154
{
155
const struct vn_buffer *buf = vn_buffer_from_handle(pInfo->buffer);
156
union {
157
VkBaseOutStructure *pnext;
158
VkMemoryRequirements2 *two;
159
VkMemoryDedicatedRequirements *dedicated;
160
} u = { .two = pMemoryRequirements };
161
162
while (u.pnext) {
163
switch (u.pnext->sType) {
164
case VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2:
165
u.two->memoryRequirements =
166
buf->memory_requirements.memoryRequirements;
167
break;
168
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS:
169
u.dedicated->prefersDedicatedAllocation =
170
buf->dedicated_requirements.prefersDedicatedAllocation;
171
u.dedicated->requiresDedicatedAllocation =
172
buf->dedicated_requirements.requiresDedicatedAllocation;
173
break;
174
default:
175
break;
176
}
177
u.pnext = u.pnext->pNext;
178
}
179
}
180
181
VkResult
182
vn_BindBufferMemory(VkDevice device,
183
VkBuffer buffer,
184
VkDeviceMemory memory,
185
VkDeviceSize memoryOffset)
186
{
187
struct vn_device *dev = vn_device_from_handle(device);
188
struct vn_device_memory *mem = vn_device_memory_from_handle(memory);
189
190
if (mem->base_memory) {
191
memory = vn_device_memory_to_handle(mem->base_memory);
192
memoryOffset += mem->base_offset;
193
}
194
195
vn_async_vkBindBufferMemory(dev->instance, device, buffer, memory,
196
memoryOffset);
197
198
return VK_SUCCESS;
199
}
200
201
VkResult
202
vn_BindBufferMemory2(VkDevice device,
203
uint32_t bindInfoCount,
204
const VkBindBufferMemoryInfo *pBindInfos)
205
{
206
struct vn_device *dev = vn_device_from_handle(device);
207
const VkAllocationCallbacks *alloc = &dev->base.base.alloc;
208
209
VkBindBufferMemoryInfo *local_infos = NULL;
210
for (uint32_t i = 0; i < bindInfoCount; i++) {
211
const VkBindBufferMemoryInfo *info = &pBindInfos[i];
212
struct vn_device_memory *mem =
213
vn_device_memory_from_handle(info->memory);
214
if (!mem->base_memory)
215
continue;
216
217
if (!local_infos) {
218
const size_t size = sizeof(*local_infos) * bindInfoCount;
219
local_infos = vk_alloc(alloc, size, VN_DEFAULT_ALIGN,
220
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
221
if (!local_infos)
222
return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
223
224
memcpy(local_infos, pBindInfos, size);
225
}
226
227
local_infos[i].memory = vn_device_memory_to_handle(mem->base_memory);
228
local_infos[i].memoryOffset += mem->base_offset;
229
}
230
if (local_infos)
231
pBindInfos = local_infos;
232
233
vn_async_vkBindBufferMemory2(dev->instance, device, bindInfoCount,
234
pBindInfos);
235
236
vk_free(alloc, local_infos);
237
238
return VK_SUCCESS;
239
}
240
241
/* buffer view commands */
242
243
VkResult
244
vn_CreateBufferView(VkDevice device,
245
const VkBufferViewCreateInfo *pCreateInfo,
246
const VkAllocationCallbacks *pAllocator,
247
VkBufferView *pView)
248
{
249
struct vn_device *dev = vn_device_from_handle(device);
250
const VkAllocationCallbacks *alloc =
251
pAllocator ? pAllocator : &dev->base.base.alloc;
252
253
struct vn_buffer_view *view =
254
vk_zalloc(alloc, sizeof(*view), VN_DEFAULT_ALIGN,
255
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
256
if (!view)
257
return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
258
259
vn_object_base_init(&view->base, VK_OBJECT_TYPE_BUFFER_VIEW, &dev->base);
260
261
VkBufferView view_handle = vn_buffer_view_to_handle(view);
262
vn_async_vkCreateBufferView(dev->instance, device, pCreateInfo, NULL,
263
&view_handle);
264
265
*pView = view_handle;
266
267
return VK_SUCCESS;
268
}
269
270
void
271
vn_DestroyBufferView(VkDevice device,
272
VkBufferView bufferView,
273
const VkAllocationCallbacks *pAllocator)
274
{
275
struct vn_device *dev = vn_device_from_handle(device);
276
struct vn_buffer_view *view = vn_buffer_view_from_handle(bufferView);
277
const VkAllocationCallbacks *alloc =
278
pAllocator ? pAllocator : &dev->base.base.alloc;
279
280
if (!view)
281
return;
282
283
vn_async_vkDestroyBufferView(dev->instance, device, bufferView, NULL);
284
285
vn_object_base_fini(&view->base);
286
vk_free(alloc, view);
287
}
288
289