implement buffer defrag
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
parent
746ad10c7b
commit
19ebe7284d
|
@ -689,7 +689,12 @@ static const VulkanResourceAccessInfo AccessMap[RESOURCE_ACCESS_TYPES_COUNT] =
|
|||
|
||||
/* Memory structures */
|
||||
|
||||
struct VulkanBuffer /* cast from Refresh_Buffer */
|
||||
typedef struct VulkanBufferContainer /* cast from Refresh_Buffer */
|
||||
{
|
||||
VulkanBuffer *vulkanBuffer;
|
||||
} VulkanBufferContainer;
|
||||
|
||||
struct VulkanBuffer
|
||||
{
|
||||
VkBuffer buffer;
|
||||
VkDeviceSize size;
|
||||
|
@ -698,6 +703,8 @@ struct VulkanBuffer /* cast from Refresh_Buffer */
|
|||
VkBufferUsageFlags usage;
|
||||
|
||||
SDL_atomic_t referenceCount; /* Tracks command buffer usage */
|
||||
|
||||
VulkanBufferContainer *container;
|
||||
};
|
||||
|
||||
typedef struct VulkanUniformBufferPool VulkanUniformBufferPool;
|
||||
|
@ -1752,6 +1759,10 @@ typedef struct VulkanRenderer
|
|||
uint32_t buffersToDestroyCount;
|
||||
uint32_t buffersToDestroyCapacity;
|
||||
|
||||
VulkanBufferContainer **bufferContainersToDestroy;
|
||||
uint32_t bufferContainersToDestroyCount;
|
||||
uint32_t bufferContainersToDestroyCapacity;
|
||||
|
||||
VulkanSampler **samplersToDestroy;
|
||||
uint32_t samplersToDestroyCount;
|
||||
uint32_t samplersToDestroyCapacity;
|
||||
|
@ -3086,8 +3097,7 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory(
|
|||
VulkanMemoryAllocation *allocation;
|
||||
uint32_t allocationIndexToDefrag;
|
||||
VulkanMemoryUsedRegion *currentRegion;
|
||||
VulkanMemoryUsedRegion *newRegion;
|
||||
VkBuffer copyBuffer;
|
||||
VulkanBuffer* newBuffer;
|
||||
VkBufferCopy bufferCopy;
|
||||
VkImage copyImage;
|
||||
VkImageCopy *imageCopyRegions;
|
||||
|
@ -3101,7 +3111,6 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory(
|
|||
VulkanResourceAccessType copyResourceAccessType = RESOURCE_ACCESS_NONE;
|
||||
VulkanResourceAccessType originalResourceAccessType;
|
||||
|
||||
SDL_LockMutex(renderer->commandLock);
|
||||
SDL_LockMutex(renderer->allocatorLock);
|
||||
|
||||
renderer->needDefrag = 0;
|
||||
|
@ -3125,6 +3134,10 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory(
|
|||
allocation
|
||||
);
|
||||
|
||||
/* For each used region in the allocation
|
||||
* create a new resource, copy the data
|
||||
* and re-point the resource containers
|
||||
*/
|
||||
for (i = 0; i < allocation->usedRegionCount; i += 1)
|
||||
{
|
||||
currentRegion = allocation->usedRegions[i];
|
||||
|
@ -3132,40 +3145,20 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory(
|
|||
|
||||
if (currentRegion->isBuffer)
|
||||
{
|
||||
currentRegion->vulkanBuffer->bufferCreateInfo.usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||
currentRegion->vulkanBuffer->usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||
|
||||
copyBuffer = VULKAN_INTERNAL_CreateBuffer(
|
||||
// TODO: modify this stuff to change the buffer pointers around
|
||||
newBuffer = VULKAN_INTERNAL_CreateBuffer(
|
||||
renderer,
|
||||
currentRegion->vulkanBuffer->bufferCreateInfo.size,
|
||||
currentRegion->vulkanBuffer->size,
|
||||
RESOURCE_ACCESS_NONE,
|
||||
currentRegion->vulkanBuffer->bufferCreateInfo.usage | VK_BUFFER_USAGE_TRANSFER_DST_BIT
|
||||
currentRegion->vulkanBuffer->usage
|
||||
);
|
||||
|
||||
result = renderer->vkCreateBuffer(
|
||||
renderer->logicalDevice,
|
||||
¤tRegion->vulkanBuffer->bufferCreateInfo,
|
||||
NULL,
|
||||
©Buffer
|
||||
);
|
||||
VULKAN_ERROR_CHECK(result, vkCreateBuffer, 0)
|
||||
|
||||
if (
|
||||
VULKAN_INTERNAL_BindMemoryForBuffer(
|
||||
renderer,
|
||||
copyBuffer,
|
||||
currentRegion->resourceSize,
|
||||
currentRegion->vulkanBuffer->preferDeviceLocal,
|
||||
0,
|
||||
&newRegion
|
||||
) != 1)
|
||||
if (newBuffer == NULL)
|
||||
{
|
||||
/* Out of memory, abort */
|
||||
renderer->vkDestroyBuffer(
|
||||
renderer->logicalDevice,
|
||||
copyBuffer,
|
||||
NULL
|
||||
);
|
||||
break;
|
||||
Refresh_LogError("Failed to create defrag buffer!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
originalResourceAccessType = currentRegion->vulkanBuffer->resourceAccessType;
|
||||
|
@ -3180,7 +3173,7 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory(
|
|||
VULKAN_INTERNAL_BufferMemoryBarrier(
|
||||
renderer,
|
||||
RESOURCE_ACCESS_TRANSFER_WRITE,
|
||||
copyBuffer,
|
||||
newBuffer,
|
||||
©ResourceAccessType
|
||||
);
|
||||
|
||||
|
@ -3191,7 +3184,7 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory(
|
|||
renderer->vkCmdCopyBuffer(
|
||||
commandBuffer->commandBuffer,
|
||||
currentRegion->vulkanBuffer->buffer,
|
||||
copyBuffer,
|
||||
newBuffer->buffer,
|
||||
1,
|
||||
&bufferCopy
|
||||
);
|
||||
|
@ -3199,45 +3192,18 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory(
|
|||
VULKAN_INTERNAL_BufferMemoryBarrier(
|
||||
renderer,
|
||||
originalResourceAccessType,
|
||||
copyBuffer,
|
||||
newBuffer,
|
||||
©ResourceAccessType
|
||||
);
|
||||
|
||||
if (renderer->defragmentedBuffersToDestroyCount >= renderer->defragmentedBuffersToDestroyCapacity)
|
||||
{
|
||||
renderer->defragmentedBuffersToDestroyCapacity *= 2;
|
||||
renderer->defragmentedBuffersToDestroy = SDL_realloc(
|
||||
renderer->defragmentedBuffersToDestroy,
|
||||
sizeof(VkBuffer) * renderer->defragmentedBuffersToDestroyCapacity
|
||||
);
|
||||
}
|
||||
SDL_AtomicIncRef(&newBuffer->referenceCount);
|
||||
SDL_AtomicIncRef(¤tRegion->vulkanBuffer->referenceCount);
|
||||
|
||||
if (renderer->usedRegionsToDestroyCount >= renderer->usedRegionsToDestroyCapacity)
|
||||
{
|
||||
renderer->usedRegionsToDestroyCapacity *= 2;
|
||||
renderer->usedRegionsToDestroy = SDL_realloc(
|
||||
renderer->usedRegionsToDestroy,
|
||||
sizeof(VulkanMemoryUsedRegion*) * renderer->usedRegionsToDestroyCapacity
|
||||
);
|
||||
}
|
||||
/* re-point original container to new buffer */
|
||||
newBuffer->container = currentRegion->vulkanBuffer->container;
|
||||
newBuffer->container->vulkanBuffer = newBuffer;
|
||||
|
||||
renderer->defragmentedBuffersToDestroy[
|
||||
renderer->defragmentedBuffersToDestroyCount
|
||||
] = currentRegion->vulkanBuffer->buffer;
|
||||
|
||||
renderer->defragmentedBuffersToDestroyCount += 1;
|
||||
|
||||
renderer->usedRegionsToDestroy[
|
||||
renderer->usedRegionsToDestroyCount
|
||||
] = currentRegion;
|
||||
|
||||
renderer->usedRegionsToDestroyCount += 1;
|
||||
|
||||
newRegion->isBuffer = 1;
|
||||
newRegion->vulkanBuffer = currentRegion->vulkanBuffer;
|
||||
newRegion->vulkanBuffer->usedRegion = newRegion; /* lol */
|
||||
newRegion->vulkanBuffer->buffer = copyBuffer;
|
||||
newRegion->vulkanBuffer->resourceAccessType = copyResourceAccessType;
|
||||
VULKAN_INTERNAL_QueueDestroyBuffer(renderer, currentRegion->vulkanBuffer);
|
||||
|
||||
renderer->needDefrag = 1;
|
||||
}
|
||||
|
@ -3461,7 +3427,6 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory(
|
|||
|
||||
renderer->defragTimer = 0;
|
||||
|
||||
SDL_UnlockMutex(renderer->commandLock);
|
||||
SDL_UnlockMutex(renderer->allocatorLock);
|
||||
|
||||
return 1;
|
||||
|
@ -5825,7 +5790,7 @@ static void VULKAN_DrawPrimitivesIndirect(
|
|||
) {
|
||||
VulkanRenderer* renderer = (VulkanRenderer*) driverData;
|
||||
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
|
||||
VulkanBuffer *vulkanBuffer = (VulkanBuffer*) buffer;
|
||||
VulkanBuffer *vulkanBuffer = ((VulkanBufferContainer*) buffer)->vulkanBuffer;
|
||||
VkDescriptorSet descriptorSets[4];
|
||||
uint32_t dynamicOffsets[2];
|
||||
|
||||
|
@ -7344,6 +7309,7 @@ static Refresh_Buffer* VULKAN_CreateBuffer(
|
|||
Refresh_BufferUsageFlags usageFlags,
|
||||
uint32_t sizeInBytes
|
||||
) {
|
||||
VulkanBufferContainer* bufferContainer;
|
||||
VulkanBuffer* buffer;
|
||||
VulkanResourceAccessType resourceAccessType;
|
||||
VkBufferUsageFlags vulkanUsageFlags =
|
||||
|
@ -7391,6 +7357,11 @@ static Refresh_Buffer* VULKAN_CreateBuffer(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
bufferContainer = SDL_malloc(sizeof(VulkanBufferContainer*));
|
||||
bufferContainer->vulkanBuffer = buffer;
|
||||
|
||||
buffer->container = bufferContainer;
|
||||
|
||||
return (Refresh_Buffer*) buffer;
|
||||
}
|
||||
|
||||
|
@ -7964,7 +7935,7 @@ static void VULKAN_SetBufferData(
|
|||
) {
|
||||
VulkanRenderer* renderer = (VulkanRenderer*) driverData;
|
||||
VulkanCommandBuffer* vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
|
||||
VulkanBuffer* vulkanBuffer = (VulkanBuffer*) buffer;
|
||||
VulkanBuffer* vulkanBuffer = ((VulkanBufferContainer*) buffer)->vulkanBuffer;
|
||||
VulkanTransferBuffer* transferBuffer;
|
||||
uint8_t* transferBufferPointer;
|
||||
VkBufferCopy bufferCopy;
|
||||
|
@ -7983,8 +7954,8 @@ static void VULKAN_SetBufferData(
|
|||
}
|
||||
|
||||
transferBufferPointer =
|
||||
transferBuffer->buffer->allocation->mapPointer +
|
||||
transferBuffer->buffer->offset +
|
||||
transferBuffer->buffer->usedRegion->allocation->mapPointer +
|
||||
transferBuffer->buffer->usedRegion->resourceOffset +
|
||||
transferBuffer->offset;
|
||||
|
||||
SDL_memcpy(
|
||||
|
@ -8392,13 +8363,13 @@ static void VULKAN_GetBufferData(
|
|||
void *data,
|
||||
uint32_t dataLengthInBytes
|
||||
) {
|
||||
VulkanBuffer* vulkanBuffer = (VulkanBuffer*) buffer;
|
||||
VulkanBuffer* vulkanBuffer = ((VulkanBufferContainer*) buffer)->vulkanBuffer;
|
||||
uint8_t *dataPtr = (uint8_t*) data;
|
||||
uint8_t *mapPointer;
|
||||
|
||||
mapPointer =
|
||||
vulkanBuffer->allocation->mapPointer +
|
||||
vulkanBuffer->offset;
|
||||
vulkanBuffer->usedRegion->allocation->mapPointer +
|
||||
vulkanBuffer->usedRegion->resourceOffset;
|
||||
|
||||
SDL_memcpy(
|
||||
dataPtr,
|
||||
|
@ -8416,7 +8387,7 @@ static void VULKAN_CopyTextureToBuffer(
|
|||
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
|
||||
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
|
||||
VulkanTexture *vulkanTexture = (VulkanTexture*) textureSlice->texture;
|
||||
VulkanBuffer* vulkanBuffer = (VulkanBuffer*) buffer;
|
||||
VulkanBuffer* vulkanBuffer = ((VulkanBufferContainer*) buffer)->vulkanBuffer;
|
||||
|
||||
VulkanResourceAccessType prevResourceAccess;
|
||||
VkBufferImageCopy imageCopy;
|
||||
|
@ -8529,13 +8500,10 @@ static void VULKAN_QueueDestroySampler(
|
|||
SDL_UnlockMutex(renderer->disposeLock);
|
||||
}
|
||||
|
||||
static void VULKAN_QueueDestroyBuffer(
|
||||
Refresh_Renderer *driverData,
|
||||
Refresh_Buffer *buffer
|
||||
static void VULKAN_INTERNAL_QueueDestroyBuffer(
|
||||
VulkanRenderer *renderer,
|
||||
VulkanBuffer *vulkanBuffer
|
||||
) {
|
||||
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
|
||||
VulkanBuffer *vulkanBuffer = (VulkanBuffer*) buffer;
|
||||
|
||||
SDL_LockMutex(renderer->disposeLock);
|
||||
|
||||
EXPAND_ARRAY_IF_NEEDED(
|
||||
|
@ -8554,6 +8522,34 @@ static void VULKAN_QueueDestroyBuffer(
|
|||
SDL_UnlockMutex(renderer->disposeLock);
|
||||
}
|
||||
|
||||
static void VULKAN_QueueDestroyBuffer(
|
||||
Refresh_Renderer *driverData,
|
||||
Refresh_Buffer *buffer
|
||||
) {
|
||||
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
|
||||
VulkanBufferContainer *vulkanBufferContainer = (VulkanBufferContainer*) buffer;
|
||||
VulkanBuffer *vulkanBuffer = vulkanBufferContainer->vulkanBuffer;
|
||||
|
||||
SDL_LockMutex(renderer->disposeLock);
|
||||
|
||||
VULKAN_INTERNAL_QueueDestroyBuffer(renderer, vulkanBuffer);
|
||||
|
||||
EXPAND_ARRAY_IF_NEEDED(
|
||||
renderer->bufferContainersToDestroy,
|
||||
VulkanBufferContainer *,
|
||||
renderer->bufferContainersToDestroyCount + 1,
|
||||
renderer->bufferContainersToDestroyCapacity,
|
||||
renderer->bufferContainersToDestroyCapacity * 2
|
||||
)
|
||||
|
||||
renderer->bufferContainersToDestroy[
|
||||
renderer->bufferContainersToDestroyCount
|
||||
] = vulkanBufferContainer;
|
||||
renderer->bufferContainersToDestroyCount += 1;
|
||||
|
||||
SDL_UnlockMutex(renderer->disposeLock);
|
||||
}
|
||||
|
||||
static void VULKAN_QueueDestroyShaderModule(
|
||||
Refresh_Renderer *driverData,
|
||||
Refresh_ShaderModule *shaderModule
|
||||
|
@ -9392,7 +9388,7 @@ static void VULKAN_BindVertexBuffers(
|
|||
|
||||
for (i = 0; i < bindingCount; i += 1)
|
||||
{
|
||||
currentVulkanBuffer = (VulkanBuffer*) pBuffers[i];
|
||||
currentVulkanBuffer = ((VulkanBufferContainer*) pBuffers[i])->vulkanBuffer;
|
||||
buffers[i] = currentVulkanBuffer->buffer;
|
||||
VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, currentVulkanBuffer);
|
||||
}
|
||||
|
@ -9417,7 +9413,7 @@ static void VULKAN_BindIndexBuffer(
|
|||
) {
|
||||
VulkanRenderer* renderer = (VulkanRenderer*) driverData;
|
||||
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
|
||||
VulkanBuffer* vulkanBuffer = (VulkanBuffer*) buffer;
|
||||
VulkanBuffer* vulkanBuffer = ((VulkanBufferContainer*) buffer)->vulkanBuffer;
|
||||
|
||||
VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanBuffer);
|
||||
|
||||
|
@ -9501,7 +9497,7 @@ static void VULKAN_BindComputeBuffers(
|
|||
|
||||
for (i = 0; i < computePipeline->pipelineLayout->bufferDescriptorSetCache->bindingCount; i += 1)
|
||||
{
|
||||
currentVulkanBuffer = (VulkanBuffer*) pBuffers[i];
|
||||
currentVulkanBuffer = ((VulkanBufferContainer*) pBuffers[i])->vulkanBuffer;
|
||||
|
||||
descriptorBufferInfos[i].buffer = currentVulkanBuffer->buffer;
|
||||
descriptorBufferInfos[i].offset = 0;
|
||||
|
@ -10217,14 +10213,20 @@ static void VULKAN_INTERNAL_PerformPendingDestroys(
|
|||
}
|
||||
}
|
||||
|
||||
/* containers are not vulkan resources, so no need for ref counting */
|
||||
for (i = renderer->bufferContainersToDestroyCount - 1; i >= 0; i -= 1)
|
||||
{
|
||||
SDL_free(renderer->bufferContainersToDestroy[i]);
|
||||
renderer->bufferContainersToDestroyCount -= 1;
|
||||
}
|
||||
|
||||
for (i = renderer->buffersToDestroyCount - 1; i >= 0; i -= 1)
|
||||
{
|
||||
if (SDL_AtomicGet(&renderer->buffersToDestroy[i]->referenceCount) == 0)
|
||||
{
|
||||
VULKAN_INTERNAL_DestroyBuffer(
|
||||
renderer,
|
||||
renderer->buffersToDestroy[i]
|
||||
);
|
||||
renderer->buffersToDestroy[i]);
|
||||
|
||||
renderer->buffersToDestroy[i] = renderer->buffersToDestroy[renderer->buffersToDestroyCount - 1];
|
||||
renderer->buffersToDestroyCount -= 1;
|
||||
|
@ -11009,9 +11011,6 @@ static uint8_t VULKAN_INTERNAL_IsDeviceSuitable(
|
|||
static void VULKAN_INTERNAL_GetPhysicalDeviceProperties(
|
||||
VulkanRenderer *renderer
|
||||
) {
|
||||
VkDeviceSize deviceLocalHeapSize;
|
||||
int32_t i;
|
||||
|
||||
renderer->physicalDeviceDriverProperties.sType =
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR;
|
||||
renderer->physicalDeviceDriverProperties.pNext = NULL;
|
||||
|
@ -11030,21 +11029,6 @@ static void VULKAN_INTERNAL_GetPhysicalDeviceProperties(
|
|||
renderer->physicalDevice,
|
||||
&renderer->memoryProperties
|
||||
);
|
||||
|
||||
deviceLocalHeapSize = 0;
|
||||
for (i = 0; i < renderer->memoryProperties.memoryHeapCount; i += 1)
|
||||
{
|
||||
if ( renderer->memoryProperties.memoryHeaps[i].flags &
|
||||
VK_MEMORY_HEAP_DEVICE_LOCAL_BIT )
|
||||
{
|
||||
if (renderer->memoryProperties.memoryHeaps[i].size > deviceLocalHeapSize)
|
||||
{
|
||||
deviceLocalHeapSize = renderer->memoryProperties.memoryHeaps[i].size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
renderer->maxDeviceLocalHeapUsage = deviceLocalHeapSize;
|
||||
}
|
||||
|
||||
static uint8_t VULKAN_INTERNAL_DeterminePhysicalDevice(
|
||||
|
@ -11861,6 +11845,14 @@ static Refresh_Device* VULKAN_CreateDevice(
|
|||
renderer->buffersToDestroyCapacity
|
||||
);
|
||||
|
||||
renderer->bufferContainersToDestroyCapacity = 16;
|
||||
renderer->bufferContainersToDestroyCount = 0;
|
||||
|
||||
renderer->bufferContainersToDestroy = SDL_malloc(
|
||||
sizeof(VulkanBufferContainer *) *
|
||||
renderer->bufferContainersToDestroyCapacity
|
||||
);
|
||||
|
||||
renderer->samplersToDestroyCapacity = 16;
|
||||
renderer->samplersToDestroyCount = 0;
|
||||
|
||||
|
|
Loading…
Reference in New Issue