Skip to content

Commit ebb8b1a

Browse files
committed
vk_runtime: added a fallback path for copies
1 parent 05fedd4 commit ebb8b1a

File tree

1 file changed

+68
-11
lines changed

1 file changed

+68
-11
lines changed

src/runtime/vulkan/vk_runtime_buffer.c

Lines changed: 68 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
#include "log.h"
44

5+
#include <string.h>
6+
57
typedef enum {
68
AllocDeviceLocal,
79
AllocHostVisible
@@ -33,16 +35,16 @@ static uint32_t find_suitable_memory_type(VkrDevice* device, uint32_t memory_typ
3335
assert(false && "Unable to find a suitable memory type");
3436
}
3537

36-
static Buffer make_base_buffer();
38+
static Buffer make_base_buffer(VkrDevice*);
3739

38-
VkrBuffer* vkr_allocate_buffer_device(VkrDevice* device, size_t size) {
40+
VkrBuffer* vkr_allocate_buffer_device_(VkrDevice* device, size_t size, AllocHeap heap) {
3941
if (!device->caps.features.buffer_device_address.bufferDeviceAddress) {
4042
error_print("device buffers require VK_KHR_buffer_device_address\n");
4143
return NULL;
4244
}
4345

4446
VkrBuffer* buffer = calloc(sizeof(VkrBuffer), 1);
45-
buffer->base = make_base_buffer();
47+
buffer->base = make_base_buffer(device);
4648
buffer->device = device;
4749
buffer->imported = true;
4850
buffer->offset = 0;
@@ -75,7 +77,7 @@ VkrBuffer* vkr_allocate_buffer_device(VkrDevice* device, size_t size) {
7577
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
7678
.pNext = NULL,
7779
.allocationSize = mem_requirements.memoryRequirements.size,
78-
.memoryTypeIndex = find_suitable_memory_type(device, mem_requirements.memoryRequirements.memoryTypeBits, AllocDeviceLocal),
80+
.memoryTypeIndex = find_suitable_memory_type(device, mem_requirements.memoryRequirements.memoryTypeBits, heap),
7981
};
8082
VkMemoryAllocateFlagsInfo allocate_flags = {
8183
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO,
@@ -100,6 +102,10 @@ VkrBuffer* vkr_allocate_buffer_device(VkrDevice* device, size_t size) {
100102
return NULL;
101103
}
102104

105+
VkrBuffer* vkr_allocate_buffer_device(VkrDevice* device, size_t size) {
106+
return vkr_allocate_buffer_device_(device, size, AllocDeviceLocal);
107+
}
108+
103109
static bool vkr_can_import_host_memory_(VkrDevice* device, bool log) {
104110
if (!device->caps.supported_extensions[ShadySupportsEXT_external_memory_host]) {
105111
if (log)
@@ -124,7 +130,7 @@ VkrBuffer* vkr_import_buffer_host(VkrDevice* device, void* ptr, size_t size) {
124130
}
125131

126132
VkrBuffer* buffer = calloc(sizeof(VkrBuffer), 1);
127-
buffer->base = make_base_buffer();
133+
buffer->base = make_base_buffer(device);
128134
buffer->device = device;
129135
buffer->host_ptr = ptr;
130136

@@ -246,7 +252,53 @@ static VkrCommand* submit_buffer_copy(VkrDevice* device, VkBuffer src, size_t sr
246252
return NULL;
247253
}
248254

249-
static bool vkr_copy_to_buffer(VkrBuffer* dst, size_t buffer_offset, void* src, size_t size) {
255+
static bool vkr_copy_to_buffer_fallback(VkrBuffer* dst, size_t buffer_offset, void* src, size_t size) {
256+
VkrDevice* device = dst->device;
257+
258+
VkrBuffer* src_buf = vkr_allocate_buffer_device_(device, size, AllocHostVisible);
259+
if (!src_buf)
260+
return false;
261+
262+
void* mapped;
263+
CHECK_VK(vkMapMemory(device->device, src_buf->memory, src_buf->offset, src_buf->size, 0, &mapped), goto err_post_buffer_create);
264+
memcpy(mapped, src, size);
265+
266+
if (!wait_completion(submit_buffer_copy(device, src_buf->buffer, src_buf->offset, dst->buffer, dst->offset + buffer_offset, size)))
267+
goto err_post_buffer_create;
268+
269+
vkUnmapMemory(device->device, src_buf->memory);
270+
vkr_destroy_buffer(src_buf);
271+
return true;
272+
273+
err_post_buffer_create:
274+
vkr_destroy_buffer(src_buf);
275+
return false;
276+
}
277+
278+
static bool vkr_copy_from_buffer_fallback(VkrBuffer* src, size_t buffer_offset, void* dst, size_t size) {
279+
VkrDevice* device = src->device;
280+
281+
VkrBuffer* dst_buf = vkr_allocate_buffer_device_(device, size, AllocHostVisible);
282+
if (!dst_buf)
283+
return false;
284+
285+
void* mapped;
286+
CHECK_VK(vkMapMemory(device->device, dst_buf->memory, dst_buf->offset, dst_buf->size, 0, &mapped), goto err_post_buffer_create);
287+
memcpy(mapped, src, size);
288+
289+
if (!wait_completion(submit_buffer_copy(device, src->buffer, src->offset + buffer_offset, dst_buf->buffer, dst_buf->offset, size)))
290+
goto err_post_buffer_create;
291+
292+
vkUnmapMemory(device->device, dst_buf->memory);
293+
vkr_destroy_buffer(dst_buf);
294+
return true;
295+
296+
err_post_buffer_create:
297+
vkr_destroy_buffer(dst_buf);
298+
return false;
299+
}
300+
301+
static bool vkr_copy_to_buffer_importing(VkrBuffer* dst, size_t buffer_offset, void* src, size_t size) {
250302
VkrDevice* device = dst->device;
251303

252304
VkrBuffer* src_buf = vkr_import_buffer_host(device, src, size);
@@ -264,7 +316,7 @@ static bool vkr_copy_to_buffer(VkrBuffer* dst, size_t buffer_offset, void* src,
264316
return false;
265317
}
266318

267-
static bool vkr_copy_from_buffer(VkrBuffer* src, size_t buffer_offset, void* dst, size_t size) {
319+
static bool vkr_copy_from_buffer_importing(VkrBuffer* src, size_t buffer_offset, void* dst, size_t size) {
268320
VkrDevice* device = src->device;
269321

270322
VkrBuffer* dst_buf = vkr_import_buffer_host(device, dst, size);
@@ -282,12 +334,17 @@ static bool vkr_copy_from_buffer(VkrBuffer* src, size_t buffer_offset, void* dst
282334
return false;
283335
}
284336

285-
static Buffer make_base_buffer() {
286-
return (Buffer) {
337+
static Buffer make_base_buffer(VkrDevice* device) {
338+
Buffer buffer = {
287339
.destroy = (void(*)(Buffer*)) vkr_destroy_buffer,
288340
.get_device_ptr = (uint64_t(*)(Buffer*)) vkr_get_buffer_device_pointer,
289341
.get_host_ptr = (void*(*)(Buffer*)) vkr_get_buffer_host_pointer,
290-
.copy_into = (bool(*)(Buffer*, size_t, void*, size_t)) vkr_copy_to_buffer,
291-
.copy_from = (bool(*)(Buffer*, size_t, void*, size_t)) vkr_copy_from_buffer,
342+
.copy_into = (bool(*)(Buffer*, size_t, void*, size_t)) vkr_copy_to_buffer_fallback,
343+
.copy_from = (bool(*)(Buffer*, size_t, void*, size_t)) vkr_copy_from_buffer_fallback,
292344
};
345+
if (vkr_can_import_host_memory(device)) {
346+
buffer.copy_from = (bool(*)(Buffer*, size_t, void*, size_t)) vkr_copy_from_buffer_importing;
347+
buffer.copy_into = (bool(*)(Buffer*, size_t, void*, size_t)) vkr_copy_to_buffer_importing;
348+
}
349+
return buffer;
293350
}

0 commit comments

Comments
 (0)