mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2025-02-17 01:21:12 +00:00
Rework memory allocation
This commit is contained in:
parent
59e5c4fca5
commit
39e69c90f0
5 changed files with 387 additions and 57 deletions
|
@ -25,15 +25,24 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
|
||||
typedef struct BufferResource_s {
|
||||
VkBuffer buffer;
|
||||
// shared memory used for image
|
||||
VkDeviceMemory memory;
|
||||
size_t size;
|
||||
int is_mapped;
|
||||
// image size
|
||||
VkDeviceSize size;
|
||||
// posision in shared memory
|
||||
VkDeviceSize offset;
|
||||
// is mapped?
|
||||
VkBool32 is_mapped;
|
||||
} BufferResource_t;
|
||||
|
||||
typedef struct ImageResource_s {
|
||||
VkImage image;
|
||||
// shared memory used for image
|
||||
VkDeviceMemory memory;
|
||||
size_t size;
|
||||
// image size
|
||||
VkDeviceSize size;
|
||||
// posision in shared memory
|
||||
VkDeviceSize offset;
|
||||
} ImageResource_t;
|
||||
|
||||
VkResult buffer_create(BufferResource_t *buf,
|
||||
|
@ -53,4 +62,8 @@ VkResult image_create(ImageResource_t *img,
|
|||
VkMemoryPropertyFlags mem_preferences);
|
||||
VkResult image_destroy(ImageResource_t *img);
|
||||
|
||||
void vulkan_memory_init(void);
|
||||
void vulkan_memory_free_unused(void);
|
||||
void vulkan_memory_delete(void);
|
||||
|
||||
#endif /*__VK_UTIL_H__*/
|
||||
|
|
|
@ -1555,6 +1555,9 @@ void QVk_Shutdown( void )
|
|||
vkDestroyFence(vk_device.logical, vk_fences[i], NULL);
|
||||
}
|
||||
}
|
||||
// free all memory
|
||||
vulkan_memory_delete();
|
||||
|
||||
if (vk_device.logical != VK_NULL_HANDLE)
|
||||
vkDestroyDevice(vk_device.logical, NULL);
|
||||
if(vk_surface != VK_NULL_HANDLE)
|
||||
|
|
|
@ -284,6 +284,8 @@ qboolean QVk_CreateDevice(int preferredDeviceIdx)
|
|||
vkGetDeviceQueue(vk_device.logical, vk_device.presentFamilyIndex, 0, &vk_device.presentQueue);
|
||||
vkGetDeviceQueue(vk_device.logical, vk_device.transferFamilyIndex, 0, &vk_device.transferQueue);
|
||||
vkGetPhysicalDeviceMemoryProperties(vk_device.physical, &vk_device.mem_properties);
|
||||
// init our memory management
|
||||
vulkan_memory_init();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1384,6 +1384,9 @@ void Vk_FreeUnusedImages (void)
|
|||
QVk_ReleaseTexture(&image->vk_texture);
|
||||
memset(image, 0, sizeof(*image));
|
||||
}
|
||||
|
||||
// free all unused blocks
|
||||
vulkan_memory_free_unused();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -33,6 +33,349 @@ get_memory_type(uint32_t mem_req_type_bits, VkMemoryPropertyFlags mem_prop)
|
|||
return -1;
|
||||
}
|
||||
|
||||
typedef struct MemoryResource_s {
|
||||
// type of memory
|
||||
uint32_t memory_type;
|
||||
// offset step
|
||||
VkDeviceSize alignment;
|
||||
// id memory used
|
||||
VkBool32 used;
|
||||
// suballocate
|
||||
VkBool32 suballocate;
|
||||
// shared memory used for image
|
||||
VkDeviceMemory memory;
|
||||
// image size
|
||||
VkDeviceSize size;
|
||||
// posision in shared memory
|
||||
VkDeviceSize offset;
|
||||
} MemoryResource_t;
|
||||
|
||||
// 1MB buffers / 512 x 512 * RGBA
|
||||
#define MEMORY_THRESHOLD (512 * 512 * 4)
|
||||
|
||||
static VkDeviceSize memory_block_threshold;
|
||||
static MemoryResource_t *used_memory;
|
||||
static VkDeviceSize used_memory_size;
|
||||
|
||||
void
|
||||
vulkan_memory_init(void)
|
||||
{
|
||||
memory_block_threshold = MEMORY_THRESHOLD;
|
||||
used_memory_size = 1024; // Size of buffers history
|
||||
used_memory = malloc(used_memory_size * sizeof(MemoryResource_t));
|
||||
memset(used_memory, 0, used_memory_size * sizeof(MemoryResource_t));
|
||||
}
|
||||
|
||||
static VkBool32
|
||||
vulkan_memory_is_used(int start_pos, int end_pos, VkDeviceMemory memory)
|
||||
{
|
||||
int pos;
|
||||
|
||||
for (pos = start_pos; pos < end_pos; pos++)
|
||||
{
|
||||
if (used_memory[pos].memory == memory && used_memory[pos].used)
|
||||
return VK_TRUE;
|
||||
}
|
||||
|
||||
return VK_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
vulkan_memory_free_unused(void)
|
||||
{
|
||||
int pos_global;
|
||||
|
||||
for (pos_global = 0; pos_global < used_memory_size; pos_global ++)
|
||||
{
|
||||
VkDeviceMemory memory = used_memory[pos_global].memory;
|
||||
if (memory != VK_NULL_HANDLE && !used_memory[pos_global].used)
|
||||
{
|
||||
int pos_local;
|
||||
|
||||
// is used somewhere else after
|
||||
if (vulkan_memory_is_used(pos_global, used_memory_size, memory))
|
||||
continue;
|
||||
|
||||
// is used somewhere else before
|
||||
if (vulkan_memory_is_used(0, pos_global, memory))
|
||||
continue;
|
||||
|
||||
// free current memory block
|
||||
vkFreeMemory(vk_device.logical, memory, NULL);
|
||||
memset(&used_memory[pos_global], 0, sizeof(MemoryResource_t));
|
||||
|
||||
// cleanup same block
|
||||
for (pos_local = pos_global + 1; pos_local < used_memory_size; pos_local++)
|
||||
{
|
||||
if (used_memory[pos_local].memory == memory)
|
||||
{
|
||||
memset(&used_memory[pos_local], 0, sizeof(MemoryResource_t));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
vulkan_memory_delete(void)
|
||||
{
|
||||
int pos_global;
|
||||
for (pos_global = 0; pos_global < used_memory_size; pos_global ++)
|
||||
{
|
||||
VkDeviceMemory memory = used_memory[pos_global].memory;
|
||||
if (memory != VK_NULL_HANDLE)
|
||||
{
|
||||
int pos_local;
|
||||
|
||||
// free current memory block
|
||||
vkFreeMemory(vk_device.logical, memory, NULL);
|
||||
memset(&used_memory[pos_global], 0, sizeof(MemoryResource_t));
|
||||
|
||||
// cleanup same block
|
||||
for (pos_local = pos_global + 1; pos_local < used_memory_size; pos_local++)
|
||||
{
|
||||
if (used_memory[pos_local].memory == memory)
|
||||
{
|
||||
memset(&used_memory[pos_local], 0, sizeof(MemoryResource_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(used_memory);
|
||||
}
|
||||
|
||||
static VkResult
|
||||
memory_block_min(VkDeviceSize size,
|
||||
uint32_t memory_type,
|
||||
VkDeviceSize alignment,
|
||||
VkBool32 suballocate,
|
||||
int* block_pos)
|
||||
{
|
||||
int pos;
|
||||
VkDeviceSize min_size = memory_block_threshold;
|
||||
VkResult result = VK_ERROR_OUT_OF_DEVICE_MEMORY;
|
||||
|
||||
// update max_size
|
||||
if (min_size < size)
|
||||
{
|
||||
*block_pos = -1;
|
||||
return result;
|
||||
}
|
||||
|
||||
// search minimal posible size
|
||||
for (pos = 0; pos < used_memory_size; pos ++)
|
||||
{
|
||||
if (used_memory[pos].memory_type == memory_type &&
|
||||
used_memory[pos].suballocate == suballocate &&
|
||||
used_memory[pos].alignment == alignment &&
|
||||
used_memory[pos].memory != VK_NULL_HANDLE &&
|
||||
used_memory[pos].used == VK_FALSE &&
|
||||
used_memory[pos].size < min_size &&
|
||||
used_memory[pos].size >= size)
|
||||
{
|
||||
// save minimal size
|
||||
min_size = used_memory[pos].size;
|
||||
*block_pos = pos;
|
||||
result = VK_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
memory_block_empty(int *block_pos)
|
||||
{
|
||||
int pos;
|
||||
MemoryResource_t *memory;
|
||||
|
||||
// search empty memory
|
||||
for (pos = *block_pos; pos < used_memory_size; pos ++)
|
||||
{
|
||||
if (used_memory[pos].memory == VK_NULL_HANDLE)
|
||||
{
|
||||
*block_pos = pos;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
memory = realloc(used_memory, (used_memory_size * 2) * sizeof(MemoryResource_t));
|
||||
if (!memory)
|
||||
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
|
||||
|
||||
// use previous end
|
||||
*block_pos = used_memory_size;
|
||||
|
||||
// update old struct
|
||||
memset(memory + used_memory_size, 0, used_memory_size * sizeof(MemoryResource_t));
|
||||
used_memory_size *= 2;
|
||||
used_memory = memory;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
memory_block_allocate(VkDeviceSize size,
|
||||
uint32_t memory_type,
|
||||
VkDeviceSize alignment,
|
||||
VkBool32 suballocate,
|
||||
int *block_pos)
|
||||
{
|
||||
int pos = 0;
|
||||
if (memory_block_empty(&pos) == VK_SUCCESS)
|
||||
{
|
||||
VkResult result;
|
||||
VkDeviceMemory memory;
|
||||
|
||||
if (size < MEMORY_THRESHOLD)
|
||||
size = MEMORY_THRESHOLD;
|
||||
|
||||
// allocate only aligned
|
||||
size = ROUNDUP(size, alignment);
|
||||
|
||||
// Need to split only buffers with suballocate support
|
||||
if (suballocate)
|
||||
{
|
||||
// requested bigger then usual
|
||||
if (size > memory_block_threshold)
|
||||
{
|
||||
size *= 2;
|
||||
// up threshold for next allocations
|
||||
memory_block_threshold = size;
|
||||
}
|
||||
// allcate bigger memory for reuse
|
||||
else if (size < memory_block_threshold)
|
||||
{
|
||||
size = memory_block_threshold;
|
||||
}
|
||||
}
|
||||
|
||||
VkMemoryAllocateInfo mem_alloc_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
||||
.allocationSize = size,
|
||||
.memoryTypeIndex = memory_type
|
||||
};
|
||||
|
||||
result = vkAllocateMemory(vk_device.logical, &mem_alloc_info, NULL, &memory);
|
||||
if (result == VK_SUCCESS)
|
||||
{
|
||||
used_memory[pos].memory = memory;
|
||||
used_memory[pos].memory_type = memory_type;
|
||||
used_memory[pos].alignment = alignment;
|
||||
used_memory[pos].offset = 0;
|
||||
used_memory[pos].size = size;
|
||||
used_memory[pos].suballocate = suballocate;
|
||||
used_memory[pos].used = VK_FALSE;
|
||||
*block_pos = pos;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
memory_create(VkDeviceSize size,
|
||||
uint32_t memory_type,
|
||||
VkBool32 suballocate,
|
||||
VkDeviceSize alignment,
|
||||
VkDeviceMemory *memory,
|
||||
VkDeviceSize *offset)
|
||||
{
|
||||
int pos = -1;
|
||||
VkResult result;
|
||||
result = memory_block_min(size, memory_type, alignment, suballocate, &pos);
|
||||
|
||||
if (result != VK_SUCCESS)
|
||||
{
|
||||
result = memory_block_allocate(size, memory_type, alignment, suballocate, &pos);
|
||||
}
|
||||
if (result == VK_SUCCESS)
|
||||
{
|
||||
// check size of block,
|
||||
// new block should be at least same size as current
|
||||
// and beger than double minimal offset
|
||||
// and marked as not for mmap
|
||||
if (used_memory[pos].size > (size * 2) &&
|
||||
(used_memory[pos].size > (used_memory[pos].alignment * 2)) &&
|
||||
used_memory[pos].suballocate)
|
||||
{
|
||||
// search from next slot
|
||||
int new_pos = pos + 1;
|
||||
result = memory_block_empty(&new_pos);
|
||||
if (result == VK_SUCCESS)
|
||||
{
|
||||
VkDeviceSize new_size = ROUNDUP(size, used_memory[pos].alignment);
|
||||
|
||||
// split to several blocks
|
||||
memcpy(&used_memory[new_pos], &used_memory[pos], sizeof(MemoryResource_t));
|
||||
used_memory[new_pos].offset = used_memory[pos].offset + new_size;
|
||||
used_memory[new_pos].size = used_memory[pos].size - new_size;
|
||||
|
||||
// save new size to block, it can be bigger than required
|
||||
used_memory[pos].size = used_memory[new_pos].offset - used_memory[pos].offset;
|
||||
assert(used_memory[pos].size > 0);
|
||||
}
|
||||
}
|
||||
|
||||
used_memory[pos].used = VK_TRUE;
|
||||
*offset = used_memory[pos].offset;
|
||||
*memory = used_memory[pos].memory;
|
||||
return result;
|
||||
}
|
||||
|
||||
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
|
||||
}
|
||||
|
||||
static void
|
||||
memory_destroy(VkDeviceMemory memory, VkDeviceSize offset)
|
||||
{
|
||||
int pos;
|
||||
for (pos = 0; pos < used_memory_size; pos ++)
|
||||
{
|
||||
if (used_memory[pos].memory == memory && used_memory[pos].offset == offset)
|
||||
{
|
||||
used_memory[pos].used = VK_FALSE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// looks as no such memory registered
|
||||
vkFreeMemory(vk_device.logical, memory, NULL);
|
||||
}
|
||||
|
||||
static VkResult
|
||||
memory_create_by_property(VkMemoryRequirements* mem_reqs,
|
||||
VkMemoryPropertyFlags mem_properties,
|
||||
VkMemoryPropertyFlags mem_preferences,
|
||||
VkDeviceMemory *memory,
|
||||
VkDeviceSize *offset)
|
||||
{
|
||||
uint32_t memory_index;
|
||||
VkMemoryPropertyFlags host_visible;
|
||||
|
||||
memory_index = get_memory_type(mem_reqs->memoryTypeBits,
|
||||
mem_properties | mem_preferences);
|
||||
if (memory_index == -1)
|
||||
{
|
||||
memory_index = get_memory_type(mem_reqs->memoryTypeBits,
|
||||
mem_properties);
|
||||
}
|
||||
if (memory_index == -1)
|
||||
{
|
||||
R_Printf(PRINT_ALL, "%s:%d: Have not found required memory type.\n",
|
||||
__func__, __LINE__);
|
||||
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
|
||||
}
|
||||
|
||||
host_visible = mem_properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
|
||||
|
||||
return memory_create(mem_reqs->size, memory_index,
|
||||
// suballocate allowed
|
||||
host_visible != VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
|
||||
mem_reqs->alignment, memory, offset);
|
||||
}
|
||||
|
||||
VkResult
|
||||
buffer_create(BufferResource_t *buf,
|
||||
VkBufferCreateInfo buf_create_info,
|
||||
|
@ -42,10 +385,9 @@ buffer_create(BufferResource_t *buf,
|
|||
assert(buf_create_info.size > 0);
|
||||
assert(buf);
|
||||
VkResult result = VK_SUCCESS;
|
||||
int memory_index;
|
||||
|
||||
buf->size = buf_create_info.size;
|
||||
buf->is_mapped = 0;
|
||||
buf->is_mapped = VK_FALSE;
|
||||
|
||||
result = vkCreateBuffer(vk_device.logical, &buf_create_info, NULL, &buf->buffer);
|
||||
if(result != VK_SUCCESS) {
|
||||
|
@ -58,25 +400,8 @@ buffer_create(BufferResource_t *buf,
|
|||
VkMemoryRequirements mem_reqs;
|
||||
vkGetBufferMemoryRequirements(vk_device.logical, buf->buffer, &mem_reqs);
|
||||
|
||||
memory_index = get_memory_type(mem_reqs.memoryTypeBits, mem_properties | mem_preferences);
|
||||
if (memory_index == -1)
|
||||
{
|
||||
memory_index = get_memory_type(mem_reqs.memoryTypeBits, mem_properties);
|
||||
}
|
||||
if (memory_index == -1)
|
||||
{
|
||||
R_Printf(PRINT_ALL, "%s:%d: Have found required memory type.\n",
|
||||
__func__, __LINE__);
|
||||
goto fail_mem_alloc;
|
||||
}
|
||||
|
||||
VkMemoryAllocateInfo mem_alloc_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
||||
.allocationSize = mem_reqs.size,
|
||||
.memoryTypeIndex = get_memory_type(mem_reqs.memoryTypeBits, mem_properties)
|
||||
};
|
||||
|
||||
result = vkAllocateMemory(vk_device.logical, &mem_alloc_info, NULL, &buf->memory);
|
||||
result = memory_create_by_property(&mem_reqs, mem_properties, mem_preferences,
|
||||
&buf->memory, &buf->offset);
|
||||
if(result != VK_SUCCESS) {
|
||||
R_Printf(PRINT_ALL, "%s:%d: VkResult verification: %s\n",
|
||||
__func__, __LINE__, QVk_GetError(result));
|
||||
|
@ -85,7 +410,7 @@ buffer_create(BufferResource_t *buf,
|
|||
|
||||
assert(buf->memory != VK_NULL_HANDLE);
|
||||
|
||||
result = vkBindBufferMemory(vk_device.logical, buf->buffer, buf->memory, 0);
|
||||
result = vkBindBufferMemory(vk_device.logical, buf->buffer, buf->memory, buf->offset);
|
||||
if(result != VK_SUCCESS) {
|
||||
R_Printf(PRINT_ALL, "%s:%d: VkResult verification: %s\n",
|
||||
__func__, __LINE__, QVk_GetError(result));
|
||||
|
@ -95,7 +420,7 @@ buffer_create(BufferResource_t *buf,
|
|||
return VK_SUCCESS;
|
||||
|
||||
fail_bind_buf_memory:
|
||||
vkFreeMemory(vk_device.logical, buf->memory, NULL);
|
||||
memory_destroy(buf->memory, buf->offset);
|
||||
fail_mem_alloc:
|
||||
vkDestroyBuffer(vk_device.logical, buf->buffer, NULL);
|
||||
fail_buffer:
|
||||
|
@ -113,7 +438,6 @@ image_create(ImageResource_t *img,
|
|||
{
|
||||
assert(img);
|
||||
VkResult result = VK_SUCCESS;
|
||||
int memory_index;
|
||||
|
||||
result = vkCreateImage(vk_device.logical, &img_create_info, NULL, &img->image);
|
||||
if(result != VK_SUCCESS) {
|
||||
|
@ -127,25 +451,8 @@ image_create(ImageResource_t *img,
|
|||
vkGetImageMemoryRequirements(vk_device.logical, img->image, &mem_reqs);
|
||||
img->size = mem_reqs.size;
|
||||
|
||||
memory_index = get_memory_type(mem_reqs.memoryTypeBits, mem_properties | mem_preferences);
|
||||
if (memory_index == -1)
|
||||
{
|
||||
memory_index = get_memory_type(mem_reqs.memoryTypeBits, mem_properties);
|
||||
}
|
||||
if (memory_index == -1)
|
||||
{
|
||||
R_Printf(PRINT_ALL, "%s:%d: Have found required memory type.\n",
|
||||
__func__, __LINE__);
|
||||
goto fail_mem_alloc;
|
||||
}
|
||||
|
||||
VkMemoryAllocateInfo mem_alloc_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
||||
.allocationSize = mem_reqs.size,
|
||||
.memoryTypeIndex = get_memory_type(mem_reqs.memoryTypeBits, mem_properties)
|
||||
};
|
||||
|
||||
result = vkAllocateMemory(vk_device.logical, &mem_alloc_info, NULL, &img->memory);
|
||||
result = memory_create_by_property(&mem_reqs, mem_properties, mem_preferences,
|
||||
&img->memory, &img->offset);
|
||||
if(result != VK_SUCCESS) {
|
||||
R_Printf(PRINT_ALL, "%s:%d: VkResult verification: %s\n",
|
||||
__func__, __LINE__, QVk_GetError(result));
|
||||
|
@ -154,7 +461,7 @@ image_create(ImageResource_t *img,
|
|||
|
||||
assert(img->memory != VK_NULL_HANDLE);
|
||||
|
||||
result = vkBindImageMemory(vk_device.logical, img->image, img->memory, 0);
|
||||
result = vkBindImageMemory(vk_device.logical, img->image, img->memory, img->offset);
|
||||
if(result != VK_SUCCESS) {
|
||||
R_Printf(PRINT_ALL, "%s:%d: VkResult verification: %s\n",
|
||||
__func__, __LINE__, QVk_GetError(result));
|
||||
|
@ -164,7 +471,7 @@ image_create(ImageResource_t *img,
|
|||
return VK_SUCCESS;
|
||||
|
||||
fail_bind_buf_memory:
|
||||
vkFreeMemory(vk_device.logical, img->memory, NULL);
|
||||
memory_destroy(img->memory, img->offset);
|
||||
fail_mem_alloc:
|
||||
vkDestroyImage(vk_device.logical, img->image, NULL);
|
||||
fail_buffer:
|
||||
|
@ -189,11 +496,12 @@ buffer_destroy(BufferResource_t *buf)
|
|||
// buffer desroed, we can free up memory
|
||||
if(buf->memory != VK_NULL_HANDLE)
|
||||
{
|
||||
vkFreeMemory(vk_device.logical, buf->memory, NULL);
|
||||
memory_destroy(buf->memory, buf->offset);
|
||||
buf->memory = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
buf->size = 0;
|
||||
buf->size = 0;
|
||||
buf->offset = 0;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
@ -211,11 +519,12 @@ image_destroy(ImageResource_t *img)
|
|||
// image destroed, we can free up memory
|
||||
if(img->memory != VK_NULL_HANDLE)
|
||||
{
|
||||
vkFreeMemory(vk_device.logical, img->memory, NULL);
|
||||
memory_destroy(img->memory, img->offset);
|
||||
img->memory = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
img->size = 0;
|
||||
img->size = 0;
|
||||
img->offset = 0;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
@ -228,7 +537,7 @@ buffer_flush(BufferResource_t *buf)
|
|||
VkMappedMemoryRange ranges[1] = {{
|
||||
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
|
||||
.memory = buf->memory,
|
||||
.offset = 0,
|
||||
.offset = buf->offset,
|
||||
.size = buf->size
|
||||
}};
|
||||
result = vkFlushMappedMemoryRanges(vk_device.logical, 1, ranges);
|
||||
|
@ -243,7 +552,7 @@ buffer_invalidate(BufferResource_t *buf)
|
|||
VkMappedMemoryRange ranges[1] = {{
|
||||
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
|
||||
.memory = buf->memory,
|
||||
.offset = 0,
|
||||
.offset = buf->offset,
|
||||
.size = buf->size
|
||||
}};
|
||||
result = vkInvalidateMappedMemoryRanges(vk_device.logical, 1, ranges);
|
||||
|
@ -255,12 +564,12 @@ void *
|
|||
buffer_map(BufferResource_t *buf)
|
||||
{
|
||||
assert(!buf->is_mapped);
|
||||
buf->is_mapped = 1;
|
||||
buf->is_mapped = VK_TRUE;
|
||||
void *ret = NULL;
|
||||
assert(buf->memory != VK_NULL_HANDLE);
|
||||
assert(buf->size > 0);
|
||||
VK_VERIFY(vkMapMemory(vk_device.logical, buf->memory,
|
||||
0 /*offset*/, buf->size, 0 /*flags*/, &ret));
|
||||
buf->offset/*offset*/, buf->size, 0 /*flags*/, &ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -268,6 +577,6 @@ void
|
|||
buffer_unmap(BufferResource_t *buf)
|
||||
{
|
||||
assert(buf->is_mapped);
|
||||
buf->is_mapped = 0;
|
||||
buf->is_mapped = VK_FALSE;
|
||||
vkUnmapMemory(vk_device.logical, buf->memory);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue