implement SetData and GetData
parent
0c095fa56d
commit
6674076423
|
@ -695,11 +695,32 @@ static const VulkanResourceAccessInfo AccessMap[RESOURCE_ACCESS_TYPES_COUNT] =
|
|||
|
||||
/* Memory structures */
|
||||
|
||||
typedef struct VulkanBufferContainer /* cast from Refresh_Buffer */
|
||||
/* We use pointer indirection so that defrag can occur without objects
|
||||
* needing to be aware of the backing buffers changing.
|
||||
*/
|
||||
typedef struct VulkanBufferContainer
|
||||
{
|
||||
VulkanBuffer *vulkanBuffer;
|
||||
} VulkanBufferContainer;
|
||||
|
||||
/* CpuBuffers consist of multiple backing buffer containers so that data transfers
|
||||
* can occur safely without the client having to explicitly manage transfer timing.
|
||||
*/
|
||||
typedef struct VulkanCpuBufferContainer /* cast from Refresh_CpuBuffer */
|
||||
{
|
||||
uint32_t sizeInBytes;
|
||||
VulkanBufferContainer *activeBuffer;
|
||||
|
||||
/* These are all the buffers that have been used by this container.
|
||||
* If a buffer is bound and then updated with Discard, a new buffer
|
||||
* will be added to this list.
|
||||
* These can be reused after they are submitted and command processing is complete.
|
||||
*/
|
||||
uint32_t bufferCapacity;
|
||||
uint32_t bufferCount;
|
||||
VulkanBufferContainer **backingBuffers;
|
||||
} VulkanCpuBufferContainer;
|
||||
|
||||
struct VulkanBuffer
|
||||
{
|
||||
VkBuffer buffer;
|
||||
|
@ -711,10 +732,13 @@ struct VulkanBuffer
|
|||
uint8_t requireHostVisible;
|
||||
uint8_t preferDeviceLocal;
|
||||
uint8_t requireHostLocal;
|
||||
uint8_t preserveContentsOnDefrag;
|
||||
|
||||
SDL_atomic_t referenceCount; /* Tracks command buffer usage */
|
||||
|
||||
VulkanBufferContainer *container;
|
||||
|
||||
uint8_t markedForDestroy; /* so that defrag doesn't double-free */
|
||||
};
|
||||
|
||||
typedef enum VulkanUniformBufferType
|
||||
|
@ -802,6 +826,8 @@ struct VulkanTexture
|
|||
SDL_atomic_t referenceCount;
|
||||
|
||||
VulkanTextureContainer *container;
|
||||
|
||||
uint8_t markedForDestroy; /* so that defrag doesn't double-free */
|
||||
};
|
||||
|
||||
typedef struct VulkanRenderTarget
|
||||
|
@ -3248,6 +3274,28 @@ static void VULKAN_INTERNAL_ImageMemoryBarrier(
|
|||
|
||||
/* Resource tracking */
|
||||
|
||||
#define ADD_TO_ARRAY_UNIQUE(resource, type, array, count, capacity) \
|
||||
uint32_t i; \
|
||||
\
|
||||
for (i = 0; i < commandBuffer->count; i += 1) \
|
||||
{ \
|
||||
if (commandBuffer->array[i] == resource) \
|
||||
{ \
|
||||
return; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
if (commandBuffer->count == commandBuffer->capacity) \
|
||||
{ \
|
||||
commandBuffer->capacity += 1; \
|
||||
commandBuffer->array = SDL_realloc( \
|
||||
commandBuffer->array, \
|
||||
commandBuffer->capacity * sizeof(type) \
|
||||
); \
|
||||
} \
|
||||
commandBuffer->array[commandBuffer->count] = resource; \
|
||||
commandBuffer->count += 1;
|
||||
|
||||
#define TRACK_RESOURCE(resource, type, array, count, capacity) \
|
||||
uint32_t i; \
|
||||
\
|
||||
|
@ -3269,10 +3317,8 @@ static void VULKAN_INTERNAL_ImageMemoryBarrier(
|
|||
} \
|
||||
commandBuffer->array[commandBuffer->count] = resource; \
|
||||
commandBuffer->count += 1; \
|
||||
\
|
||||
SDL_AtomicIncRef(&resource->referenceCount);
|
||||
|
||||
|
||||
static void VULKAN_INTERNAL_TrackBuffer(
|
||||
VulkanRenderer *renderer,
|
||||
VulkanCommandBuffer *commandBuffer,
|
||||
|
@ -3391,7 +3437,7 @@ static void VULKAN_INTERNAL_TrackCopiedTexture(
|
|||
VulkanCommandBuffer *commandBuffer,
|
||||
VulkanTexture *texture
|
||||
) {
|
||||
TRACK_RESOURCE(
|
||||
ADD_TO_ARRAY_UNIQUE(
|
||||
texture,
|
||||
VulkanTexture*,
|
||||
copiedTextures,
|
||||
|
@ -3406,7 +3452,7 @@ static void VULKAN_INTERNAL_TrackCopiedBuffer(
|
|||
VulkanCommandBuffer *commandBuffer,
|
||||
VulkanBuffer *buffer
|
||||
) {
|
||||
TRACK_RESOURCE(
|
||||
ADD_TO_ARRAY_UNIQUE(
|
||||
buffer,
|
||||
VulkanBuffer*,
|
||||
copiedGpuBuffers,
|
||||
|
@ -4145,7 +4191,8 @@ static VulkanBuffer* VULKAN_INTERNAL_CreateBuffer(
|
|||
uint8_t requireHostVisible,
|
||||
uint8_t requireHostLocal,
|
||||
uint8_t preferDeviceLocal,
|
||||
uint8_t dedicatedAllocation
|
||||
uint8_t dedicatedAllocation,
|
||||
uint8_t preserveContentsOnDefrag
|
||||
) {
|
||||
VulkanBuffer* buffer;
|
||||
VkResult vulkanResult;
|
||||
|
@ -4160,6 +4207,8 @@ static VulkanBuffer* VULKAN_INTERNAL_CreateBuffer(
|
|||
buffer->requireHostVisible = requireHostVisible;
|
||||
buffer->requireHostLocal = requireHostLocal;
|
||||
buffer->preferDeviceLocal = preferDeviceLocal;
|
||||
buffer->preserveContentsOnDefrag = preserveContentsOnDefrag;
|
||||
buffer->markedForDestroy = 0;
|
||||
|
||||
bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||
bufferCreateInfo.pNext = NULL;
|
||||
|
@ -4277,6 +4326,7 @@ static VulkanUniformBufferObject* VULKAN_INTERNAL_CreateUniformBufferObject(
|
|||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1
|
||||
);
|
||||
|
||||
|
@ -4321,12 +4371,17 @@ static VulkanUniformBufferObject* VULKAN_INTERNAL_CreateUniformBufferObject(
|
|||
return uniformBufferObject;
|
||||
}
|
||||
|
||||
/* Buffer indirection so we can cleanly defrag GpuBuffers */
|
||||
/* Indirection so we can cleanly defrag buffers */
|
||||
static VulkanBufferContainer* VULKAN_INTERNAL_CreateBufferContainer(
|
||||
VulkanRenderer *renderer,
|
||||
uint32_t sizeInBytes,
|
||||
VulkanResourceAccessType resourceAccessType,
|
||||
VkBufferUsageFlags usageFlags
|
||||
VkBufferUsageFlags usageFlags,
|
||||
uint8_t requireHostVisible,
|
||||
uint8_t requireHostLocal,
|
||||
uint8_t preferDeviceLocal,
|
||||
uint8_t dedicatedAllocation,
|
||||
uint8_t preserveContentsOnDefrag
|
||||
) {
|
||||
VulkanBufferContainer* bufferContainer;
|
||||
VulkanBuffer* buffer;
|
||||
|
@ -4339,10 +4394,11 @@ static VulkanBufferContainer* VULKAN_INTERNAL_CreateBufferContainer(
|
|||
sizeInBytes,
|
||||
resourceAccessType,
|
||||
usageFlags,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0
|
||||
requireHostVisible,
|
||||
requireHostLocal,
|
||||
preferDeviceLocal,
|
||||
dedicatedAllocation,
|
||||
preserveContentsOnDefrag
|
||||
);
|
||||
|
||||
if (buffer == NULL)
|
||||
|
@ -5413,6 +5469,7 @@ static VulkanTexture* VULKAN_INTERNAL_CreateTexture(
|
|||
|
||||
texture->isCube = 0;
|
||||
texture->is3D = 0;
|
||||
texture->markedForDestroy = 0;
|
||||
|
||||
if (isCube)
|
||||
{
|
||||
|
@ -6812,20 +6869,26 @@ static Refresh_GpuBuffer* VULKAN_CreateGpuBuffer(
|
|||
(VulkanRenderer*) driverData,
|
||||
sizeInBytes,
|
||||
resourceAccessType,
|
||||
vulkanUsageFlags
|
||||
vulkanUsageFlags,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
static Refresh_CpuBuffer* VULKAN_CreateCpuBuffer(
|
||||
Refresh_Renderer *driverData,
|
||||
uint32_t sizeInBytes,
|
||||
void **pDataPtr
|
||||
uint32_t sizeInBytes
|
||||
) {
|
||||
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
|
||||
VkBufferUsageFlags vulkanUsageFlags =
|
||||
VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||
VulkanCpuBufferContainer *bufferContainer = (VulkanCpuBufferContainer*) SDL_malloc(sizeof(VulkanCpuBufferContainer));
|
||||
|
||||
VulkanBuffer *vulkanBuffer = VULKAN_INTERNAL_CreateBuffer(
|
||||
bufferContainer->sizeInBytes = sizeInBytes;
|
||||
bufferContainer->activeBuffer = VULKAN_INTERNAL_CreateBufferContainer(
|
||||
renderer,
|
||||
sizeInBytes,
|
||||
RESOURCE_ACCESS_NONE,
|
||||
|
@ -6833,12 +6896,18 @@ static Refresh_CpuBuffer* VULKAN_CreateCpuBuffer(
|
|||
1,
|
||||
1,
|
||||
0,
|
||||
1
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
*pDataPtr = vulkanBuffer->usedRegion->allocation->mapPointer;
|
||||
bufferContainer->bufferCapacity = 1;
|
||||
bufferContainer->bufferCount = 1;
|
||||
bufferContainer->backingBuffers = SDL_malloc(
|
||||
bufferContainer->bufferCapacity * sizeof(VulkanBufferContainer*)
|
||||
);
|
||||
bufferContainer->backingBuffers[0] = bufferContainer->activeBuffer;
|
||||
|
||||
return (Refresh_CpuBuffer*) vulkanBuffer;
|
||||
return (Refresh_CpuBuffer*) bufferContainer;
|
||||
}
|
||||
|
||||
/* Setters */
|
||||
|
@ -7169,6 +7238,8 @@ static void VULKAN_INTERNAL_QueueDestroyTexture(
|
|||
VulkanRenderer *renderer,
|
||||
VulkanTexture *vulkanTexture
|
||||
) {
|
||||
if (vulkanTexture->markedForDestroy) { return; }
|
||||
|
||||
SDL_LockMutex(renderer->disposeLock);
|
||||
|
||||
EXPAND_ARRAY_IF_NEEDED(
|
||||
|
@ -7184,6 +7255,8 @@ static void VULKAN_INTERNAL_QueueDestroyTexture(
|
|||
] = vulkanTexture;
|
||||
renderer->texturesToDestroyCount += 1;
|
||||
|
||||
vulkanTexture->markedForDestroy = 1;
|
||||
|
||||
SDL_UnlockMutex(renderer->disposeLock);
|
||||
}
|
||||
|
||||
|
@ -7232,6 +7305,8 @@ static void VULKAN_INTERNAL_QueueDestroyBuffer(
|
|||
VulkanRenderer *renderer,
|
||||
VulkanBuffer *vulkanBuffer
|
||||
) {
|
||||
if (vulkanBuffer->markedForDestroy) { return; }
|
||||
|
||||
SDL_LockMutex(renderer->disposeLock);
|
||||
|
||||
EXPAND_ARRAY_IF_NEEDED(
|
||||
|
@ -7247,6 +7322,8 @@ static void VULKAN_INTERNAL_QueueDestroyBuffer(
|
|||
] = vulkanBuffer;
|
||||
renderer->buffersToDestroyCount += 1;
|
||||
|
||||
vulkanBuffer->markedForDestroy = 1;
|
||||
|
||||
SDL_UnlockMutex(renderer->disposeLock);
|
||||
}
|
||||
|
||||
|
@ -7262,7 +7339,7 @@ static void VULKAN_QueueDestroyGpuBuffer(
|
|||
|
||||
VULKAN_INTERNAL_QueueDestroyBuffer(renderer, vulkanBuffer);
|
||||
|
||||
/* Containers are just client handles, so we can destroy immediately */
|
||||
/* Containers are just client handles, so we can free immediately */
|
||||
SDL_free(vulkanBufferContainer);
|
||||
|
||||
SDL_UnlockMutex(renderer->disposeLock);
|
||||
|
@ -7273,11 +7350,20 @@ static void VULKAN_QueueDestroyCpuBuffer(
|
|||
Refresh_CpuBuffer *buffer
|
||||
) {
|
||||
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
|
||||
VulkanBuffer *vulkanBuffer = (VulkanBuffer*) buffer;
|
||||
VulkanCpuBufferContainer *bufferContainer = (VulkanCpuBufferContainer*) buffer;
|
||||
uint32_t i;
|
||||
|
||||
SDL_LockMutex(renderer->disposeLock);
|
||||
|
||||
VULKAN_INTERNAL_QueueDestroyBuffer(renderer, vulkanBuffer);
|
||||
for (i = 0; i < bufferContainer->bufferCount; i += 1)
|
||||
{
|
||||
VULKAN_INTERNAL_QueueDestroyBuffer(renderer, bufferContainer->backingBuffers[i]->vulkanBuffer);
|
||||
SDL_free(bufferContainer->backingBuffers[i]);
|
||||
}
|
||||
|
||||
/* Containers are just client handles, so we can free immediately */
|
||||
SDL_free(bufferContainer->backingBuffers);
|
||||
SDL_free(bufferContainer);
|
||||
|
||||
SDL_UnlockMutex(renderer->disposeLock);
|
||||
}
|
||||
|
@ -8342,6 +8428,108 @@ static void VULKAN_EndComputePass(
|
|||
vulkanCommandBuffer->currentComputePipeline = NULL;
|
||||
}
|
||||
|
||||
static void VULKAN_INTERNAL_DiscardActiveCpuBuffer(
|
||||
VulkanRenderer *renderer,
|
||||
VulkanCpuBufferContainer *cpuBufferContainer
|
||||
) {
|
||||
VulkanBufferContainer *cpuBuffer;
|
||||
uint32_t i;
|
||||
|
||||
cpuBufferContainer->activeBuffer->vulkanBuffer->preserveContentsOnDefrag = 0;
|
||||
|
||||
/* If a previously-discarded buffer is available, we can use that. */
|
||||
for (i = 0; i < cpuBufferContainer->bufferCount; i += 1)
|
||||
{
|
||||
cpuBuffer = cpuBufferContainer->backingBuffers[i];
|
||||
if (SDL_AtomicGet(&cpuBuffer->vulkanBuffer->referenceCount) == 0)
|
||||
{
|
||||
cpuBufferContainer->activeBuffer = cpuBuffer;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* No buffer is available, generate a new one. */
|
||||
cpuBufferContainer->activeBuffer = VULKAN_INTERNAL_CreateBufferContainer(
|
||||
renderer,
|
||||
cpuBufferContainer->sizeInBytes,
|
||||
RESOURCE_ACCESS_NONE,
|
||||
VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
EXPAND_ARRAY_IF_NEEDED(
|
||||
cpuBufferContainer->backingBuffers,
|
||||
VulkanBufferContainer*,
|
||||
cpuBufferContainer->bufferCount + 1,
|
||||
cpuBufferContainer->bufferCapacity,
|
||||
cpuBufferContainer->bufferCapacity * 2
|
||||
);
|
||||
|
||||
cpuBufferContainer->backingBuffers[
|
||||
cpuBufferContainer->bufferCount
|
||||
] = cpuBufferContainer->activeBuffer;
|
||||
cpuBufferContainer->bufferCount += 1;
|
||||
}
|
||||
|
||||
static void VULKAN_SetData(
|
||||
Refresh_Renderer *driverData,
|
||||
void* data,
|
||||
Refresh_CpuBuffer *cpuBuffer,
|
||||
Refresh_BufferCopy *copyParams,
|
||||
Refresh_SetDataOptions option
|
||||
) {
|
||||
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
|
||||
VulkanCpuBufferContainer *cpuBufferContainer = (VulkanCpuBufferContainer*) cpuBuffer;
|
||||
VulkanBuffer *vulkanBuffer = cpuBufferContainer->activeBuffer->vulkanBuffer;
|
||||
|
||||
if (option == REFRESH_SETDATAOPTIONS_DISCARD && SDL_AtomicGet(&vulkanBuffer->referenceCount) > 0)
|
||||
{
|
||||
VULKAN_INTERNAL_DiscardActiveCpuBuffer(
|
||||
renderer,
|
||||
cpuBufferContainer
|
||||
);
|
||||
}
|
||||
|
||||
uint8_t *bufferPointer =
|
||||
vulkanBuffer->usedRegion->allocation->mapPointer +
|
||||
vulkanBuffer->usedRegion->resourceOffset +
|
||||
copyParams->dstOffset;
|
||||
|
||||
SDL_memcpy(
|
||||
bufferPointer,
|
||||
((uint8_t*) data) + copyParams->srcOffset,
|
||||
copyParams->size
|
||||
);
|
||||
}
|
||||
|
||||
static void VULKAN_GetData(
|
||||
Refresh_Renderer *driverData,
|
||||
Refresh_CpuBuffer *cpuBuffer,
|
||||
void* data,
|
||||
Refresh_BufferCopy *copyParams
|
||||
) {
|
||||
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
|
||||
VulkanCpuBufferContainer *cpuBufferContainer = (VulkanCpuBufferContainer*) cpuBuffer;
|
||||
VulkanBuffer *vulkanBuffer = cpuBufferContainer->activeBuffer->vulkanBuffer;
|
||||
|
||||
uint8_t *bufferPointer =
|
||||
vulkanBuffer->usedRegion->allocation->mapPointer +
|
||||
vulkanBuffer->usedRegion->resourceOffset +
|
||||
copyParams->srcOffset;
|
||||
|
||||
SDL_memcpy(
|
||||
((uint8_t*) data) + copyParams->dstOffset,
|
||||
bufferPointer,
|
||||
copyParams->size
|
||||
);
|
||||
|
||||
vulkanBuffer->preserveContentsOnDefrag = 0;
|
||||
}
|
||||
|
||||
static void VULKAN_BeginCopyPass(
|
||||
Refresh_Renderer *driverData,
|
||||
Refresh_CommandBuffer *commandBuffer
|
||||
|
@ -8362,7 +8550,7 @@ static void VULKAN_UploadToTexture(
|
|||
) {
|
||||
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
|
||||
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
|
||||
VulkanBuffer *vulkanCpuBuffer = (VulkanBuffer*) cpuBuffer;
|
||||
VulkanCpuBufferContainer *bufferContainer = (VulkanCpuBufferContainer*) cpuBuffer;
|
||||
VulkanTexture *vulkanTexture = ((VulkanTextureContainer*) textureSlice->texture)->vulkanTexture;
|
||||
VkBufferImageCopy imageCopy;
|
||||
|
||||
|
@ -8370,7 +8558,7 @@ static void VULKAN_UploadToTexture(
|
|||
renderer,
|
||||
vulkanCommandBuffer->commandBuffer,
|
||||
RESOURCE_ACCESS_TRANSFER_READ,
|
||||
vulkanCpuBuffer
|
||||
bufferContainer->activeBuffer->vulkanBuffer
|
||||
);
|
||||
|
||||
VULKAN_INTERNAL_ImageMemoryBarrier(
|
||||
|
@ -8403,14 +8591,14 @@ static void VULKAN_UploadToTexture(
|
|||
|
||||
renderer->vkCmdCopyBufferToImage(
|
||||
vulkanCommandBuffer->commandBuffer,
|
||||
vulkanCpuBuffer->buffer,
|
||||
bufferContainer->activeBuffer->vulkanBuffer->buffer,
|
||||
vulkanTexture->image,
|
||||
AccessMap[vulkanTexture->resourceAccessType].imageLayout,
|
||||
1,
|
||||
&imageCopy
|
||||
);
|
||||
|
||||
VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanCpuBuffer);
|
||||
VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, bufferContainer->activeBuffer->vulkanBuffer);
|
||||
VULKAN_INTERNAL_TrackTexture(renderer, vulkanCommandBuffer, vulkanTexture);
|
||||
VULKAN_INTERNAL_TrackCopiedTexture(renderer, vulkanCommandBuffer, vulkanTexture);
|
||||
}
|
||||
|
@ -8424,7 +8612,7 @@ static void VULKAN_UploadToBuffer(
|
|||
) {
|
||||
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
|
||||
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
|
||||
VulkanBuffer *vulkanCpuBuffer = (VulkanBuffer*) cpuBuffer;
|
||||
VulkanCpuBufferContainer *cpuBufferContainer = (VulkanCpuBufferContainer*) cpuBuffer;
|
||||
VulkanBuffer *vulkanGpuBuffer = ((VulkanBufferContainer*) gpuBuffer)->vulkanBuffer;
|
||||
VkBufferCopy bufferCopy;
|
||||
|
||||
|
@ -8432,7 +8620,7 @@ static void VULKAN_UploadToBuffer(
|
|||
renderer,
|
||||
vulkanCommandBuffer->commandBuffer,
|
||||
RESOURCE_ACCESS_TRANSFER_READ,
|
||||
vulkanCpuBuffer
|
||||
cpuBufferContainer->activeBuffer->vulkanBuffer
|
||||
);
|
||||
|
||||
VULKAN_INTERNAL_BufferMemoryBarrier(
|
||||
|
@ -8448,13 +8636,13 @@ static void VULKAN_UploadToBuffer(
|
|||
|
||||
renderer->vkCmdCopyBuffer(
|
||||
vulkanCommandBuffer->commandBuffer,
|
||||
vulkanCpuBuffer->buffer,
|
||||
cpuBufferContainer->activeBuffer->vulkanBuffer->buffer,
|
||||
vulkanGpuBuffer->buffer,
|
||||
1,
|
||||
&bufferCopy
|
||||
);
|
||||
|
||||
VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanCpuBuffer);
|
||||
VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, cpuBufferContainer->activeBuffer->vulkanBuffer);
|
||||
VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanGpuBuffer);
|
||||
VULKAN_INTERNAL_TrackCopiedBuffer(renderer, vulkanCommandBuffer, vulkanGpuBuffer);
|
||||
}
|
||||
|
@ -8469,14 +8657,14 @@ static void VULKAN_DownloadFromTexture(
|
|||
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
|
||||
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
|
||||
VulkanTexture *vulkanTexture = ((VulkanTextureContainer*) textureSlice->texture)->vulkanTexture;
|
||||
VulkanBuffer *vulkanCpuBuffer = (VulkanBuffer*) cpuBuffer;
|
||||
VulkanCpuBufferContainer *cpuBufferContainer = (VulkanCpuBufferContainer*) cpuBuffer;
|
||||
VkBufferImageCopy imageCopy;
|
||||
|
||||
VULKAN_INTERNAL_BufferMemoryBarrier(
|
||||
renderer,
|
||||
vulkanCommandBuffer->commandBuffer,
|
||||
RESOURCE_ACCESS_TRANSFER_WRITE,
|
||||
vulkanCpuBuffer
|
||||
cpuBufferContainer->activeBuffer->vulkanBuffer
|
||||
);
|
||||
|
||||
VULKAN_INTERNAL_ImageMemoryBarrier(
|
||||
|
@ -8511,14 +8699,16 @@ static void VULKAN_DownloadFromTexture(
|
|||
vulkanCommandBuffer->commandBuffer,
|
||||
vulkanTexture->image,
|
||||
AccessMap[vulkanTexture->resourceAccessType].imageLayout,
|
||||
vulkanCpuBuffer->buffer,
|
||||
cpuBufferContainer->activeBuffer->vulkanBuffer->buffer,
|
||||
1,
|
||||
&imageCopy
|
||||
);
|
||||
|
||||
VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanCpuBuffer);
|
||||
VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, cpuBufferContainer->activeBuffer->vulkanBuffer);
|
||||
VULKAN_INTERNAL_TrackTexture(renderer, vulkanCommandBuffer, vulkanTexture);
|
||||
VULKAN_INTERNAL_TrackCopiedTexture(renderer, vulkanCommandBuffer, vulkanTexture);
|
||||
|
||||
cpuBufferContainer->activeBuffer->vulkanBuffer->preserveContentsOnDefrag = 1;
|
||||
}
|
||||
|
||||
static void VULKAN_DownloadFromBuffer(
|
||||
|
@ -8530,7 +8720,7 @@ static void VULKAN_DownloadFromBuffer(
|
|||
) {
|
||||
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
|
||||
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
|
||||
VulkanBuffer *vulkanCpuBuffer = (VulkanBuffer*) cpuBuffer;
|
||||
VulkanCpuBufferContainer *cpuBufferContainer = (VulkanCpuBufferContainer*) cpuBuffer;
|
||||
VulkanBuffer *vulkanGpuBuffer = ((VulkanBufferContainer*) gpuBuffer)->vulkanBuffer;
|
||||
VkBufferCopy bufferCopy;
|
||||
|
||||
|
@ -8538,7 +8728,7 @@ static void VULKAN_DownloadFromBuffer(
|
|||
renderer,
|
||||
vulkanCommandBuffer->commandBuffer,
|
||||
RESOURCE_ACCESS_TRANSFER_WRITE,
|
||||
vulkanCpuBuffer
|
||||
cpuBufferContainer->activeBuffer->vulkanBuffer
|
||||
);
|
||||
|
||||
VULKAN_INTERNAL_BufferMemoryBarrier(
|
||||
|
@ -8555,14 +8745,16 @@ static void VULKAN_DownloadFromBuffer(
|
|||
renderer->vkCmdCopyBuffer(
|
||||
vulkanCommandBuffer->commandBuffer,
|
||||
vulkanGpuBuffer->buffer,
|
||||
vulkanCpuBuffer->buffer,
|
||||
cpuBufferContainer->activeBuffer->vulkanBuffer->buffer,
|
||||
1,
|
||||
&bufferCopy
|
||||
);
|
||||
|
||||
VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanCpuBuffer);
|
||||
VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, cpuBufferContainer->activeBuffer->vulkanBuffer);
|
||||
VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanGpuBuffer);
|
||||
VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanGpuBuffer);
|
||||
|
||||
cpuBufferContainer->activeBuffer->vulkanBuffer->preserveContentsOnDefrag = 1;
|
||||
}
|
||||
|
||||
static void VULKAN_CopyTextureToTexture(
|
||||
|
@ -10118,7 +10310,7 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory(
|
|||
currentRegion = allocation->usedRegions[i];
|
||||
copyResourceAccessType = RESOURCE_ACCESS_NONE;
|
||||
|
||||
if (currentRegion->isBuffer)
|
||||
if (currentRegion->isBuffer && !currentRegion->vulkanBuffer->markedForDestroy)
|
||||
{
|
||||
currentRegion->vulkanBuffer->usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||
|
||||
|
@ -10130,7 +10322,8 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory(
|
|||
currentRegion->vulkanBuffer->requireHostVisible,
|
||||
currentRegion->vulkanBuffer->requireHostLocal,
|
||||
currentRegion->vulkanBuffer->preferDeviceLocal,
|
||||
0
|
||||
0,
|
||||
currentRegion->vulkanBuffer->preserveContentsOnDefrag
|
||||
);
|
||||
|
||||
if (newBuffer == NULL)
|
||||
|
@ -10139,43 +10332,47 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory(
|
|||
return 0;
|
||||
}
|
||||
|
||||
originalResourceAccessType = currentRegion->vulkanBuffer->resourceAccessType;
|
||||
/* Copy buffer contents if necessary */
|
||||
if (currentRegion->vulkanBuffer->preserveContentsOnDefrag)
|
||||
{
|
||||
originalResourceAccessType = currentRegion->vulkanBuffer->resourceAccessType;
|
||||
|
||||
VULKAN_INTERNAL_BufferMemoryBarrier(
|
||||
renderer,
|
||||
commandBuffer->commandBuffer,
|
||||
RESOURCE_ACCESS_TRANSFER_READ,
|
||||
currentRegion->vulkanBuffer
|
||||
);
|
||||
VULKAN_INTERNAL_BufferMemoryBarrier(
|
||||
renderer,
|
||||
commandBuffer->commandBuffer,
|
||||
RESOURCE_ACCESS_TRANSFER_READ,
|
||||
currentRegion->vulkanBuffer
|
||||
);
|
||||
|
||||
VULKAN_INTERNAL_BufferMemoryBarrier(
|
||||
renderer,
|
||||
commandBuffer->commandBuffer,
|
||||
RESOURCE_ACCESS_TRANSFER_WRITE,
|
||||
newBuffer
|
||||
);
|
||||
VULKAN_INTERNAL_BufferMemoryBarrier(
|
||||
renderer,
|
||||
commandBuffer->commandBuffer,
|
||||
RESOURCE_ACCESS_TRANSFER_WRITE,
|
||||
newBuffer
|
||||
);
|
||||
|
||||
bufferCopy.srcOffset = 0;
|
||||
bufferCopy.dstOffset = 0;
|
||||
bufferCopy.size = currentRegion->resourceSize;
|
||||
bufferCopy.srcOffset = 0;
|
||||
bufferCopy.dstOffset = 0;
|
||||
bufferCopy.size = currentRegion->resourceSize;
|
||||
|
||||
renderer->vkCmdCopyBuffer(
|
||||
commandBuffer->commandBuffer,
|
||||
currentRegion->vulkanBuffer->buffer,
|
||||
newBuffer->buffer,
|
||||
1,
|
||||
&bufferCopy
|
||||
);
|
||||
renderer->vkCmdCopyBuffer(
|
||||
commandBuffer->commandBuffer,
|
||||
currentRegion->vulkanBuffer->buffer,
|
||||
newBuffer->buffer,
|
||||
1,
|
||||
&bufferCopy
|
||||
);
|
||||
|
||||
VULKAN_INTERNAL_BufferMemoryBarrier(
|
||||
renderer,
|
||||
commandBuffer->commandBuffer,
|
||||
originalResourceAccessType,
|
||||
newBuffer
|
||||
);
|
||||
VULKAN_INTERNAL_BufferMemoryBarrier(
|
||||
renderer,
|
||||
commandBuffer->commandBuffer,
|
||||
originalResourceAccessType,
|
||||
newBuffer
|
||||
);
|
||||
|
||||
VULKAN_INTERNAL_TrackBuffer(renderer, commandBuffer, currentRegion->vulkanBuffer);
|
||||
VULKAN_INTERNAL_TrackBuffer(renderer, commandBuffer, newBuffer);
|
||||
VULKAN_INTERNAL_TrackBuffer(renderer, commandBuffer, currentRegion->vulkanBuffer);
|
||||
VULKAN_INTERNAL_TrackBuffer(renderer, commandBuffer, newBuffer);
|
||||
}
|
||||
|
||||
/* re-point original container to new buffer */
|
||||
if (currentRegion->vulkanBuffer->container != NULL)
|
||||
|
@ -10189,7 +10386,7 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory(
|
|||
|
||||
renderer->needDefrag = 1;
|
||||
}
|
||||
else
|
||||
else if (!currentRegion->vulkanTexture->markedForDestroy)
|
||||
{
|
||||
newTexture = VULKAN_INTERNAL_CreateTexture(
|
||||
renderer,
|
||||
|
|
Loading…
Reference in New Issue