2
2
3
3
#include "log.h"
4
4
5
+ #include <string.h>
6
+
5
7
typedef enum {
6
8
AllocDeviceLocal ,
7
9
AllocHostVisible
@@ -33,16 +35,16 @@ static uint32_t find_suitable_memory_type(VkrDevice* device, uint32_t memory_typ
33
35
assert (false && "Unable to find a suitable memory type" );
34
36
}
35
37
36
- static Buffer make_base_buffer ();
38
+ static Buffer make_base_buffer (VkrDevice * );
37
39
38
- VkrBuffer * vkr_allocate_buffer_device (VkrDevice * device , size_t size ) {
40
+ VkrBuffer * vkr_allocate_buffer_device_ (VkrDevice * device , size_t size , AllocHeap heap ) {
39
41
if (!device -> caps .features .buffer_device_address .bufferDeviceAddress ) {
40
42
error_print ("device buffers require VK_KHR_buffer_device_address\n" );
41
43
return NULL ;
42
44
}
43
45
44
46
VkrBuffer * buffer = calloc (sizeof (VkrBuffer ), 1 );
45
- buffer -> base = make_base_buffer ();
47
+ buffer -> base = make_base_buffer (device );
46
48
buffer -> device = device ;
47
49
buffer -> imported = true;
48
50
buffer -> offset = 0 ;
@@ -75,7 +77,7 @@ VkrBuffer* vkr_allocate_buffer_device(VkrDevice* device, size_t size) {
75
77
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO ,
76
78
.pNext = NULL ,
77
79
.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 ),
79
81
};
80
82
VkMemoryAllocateFlagsInfo allocate_flags = {
81
83
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO ,
@@ -100,6 +102,10 @@ VkrBuffer* vkr_allocate_buffer_device(VkrDevice* device, size_t size) {
100
102
return NULL ;
101
103
}
102
104
105
+ VkrBuffer * vkr_allocate_buffer_device (VkrDevice * device , size_t size ) {
106
+ return vkr_allocate_buffer_device_ (device , size , AllocDeviceLocal );
107
+ }
108
+
103
109
static bool vkr_can_import_host_memory_ (VkrDevice * device , bool log ) {
104
110
if (!device -> caps .supported_extensions [ShadySupportsEXT_external_memory_host ]) {
105
111
if (log )
@@ -124,7 +130,7 @@ VkrBuffer* vkr_import_buffer_host(VkrDevice* device, void* ptr, size_t size) {
124
130
}
125
131
126
132
VkrBuffer * buffer = calloc (sizeof (VkrBuffer ), 1 );
127
- buffer -> base = make_base_buffer ();
133
+ buffer -> base = make_base_buffer (device );
128
134
buffer -> device = device ;
129
135
buffer -> host_ptr = ptr ;
130
136
@@ -246,7 +252,53 @@ static VkrCommand* submit_buffer_copy(VkrDevice* device, VkBuffer src, size_t sr
246
252
return NULL ;
247
253
}
248
254
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 ) {
250
302
VkrDevice * device = dst -> device ;
251
303
252
304
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,
264
316
return false;
265
317
}
266
318
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 ) {
268
320
VkrDevice * device = src -> device ;
269
321
270
322
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
282
334
return false;
283
335
}
284
336
285
- static Buffer make_base_buffer () {
286
- return ( Buffer ) {
337
+ static Buffer make_base_buffer (VkrDevice * device ) {
338
+ Buffer buffer = {
287
339
.destroy = (void (* )(Buffer * )) vkr_destroy_buffer ,
288
340
.get_device_ptr = (uint64_t (* )(Buffer * )) vkr_get_buffer_device_pointer ,
289
341
.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 ,
292
344
};
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 ;
293
350
}
0 commit comments