proper texture staging + fix buffer dispose api

submit_rewrite
cosmonaut 2021-01-02 20:56:40 -08:00 committed by thatcosmonaut
parent 10d326b201
commit 540c0985b7
4 changed files with 182 additions and 118 deletions

View File

@ -1184,26 +1184,14 @@ REFRESHAPI void REFRESH_AddDisposeSampler(
REFRESH_Sampler *sampler REFRESH_Sampler *sampler
); );
/* Sends a vertex buffer to be destroyed by the renderer. Note that we call it /* Sends a buffer to be destroyed by the renderer. Note that we call it
* "AddDispose" because it may not be immediately destroyed by the renderer if * "AddDispose" because it may not be immediately destroyed by the renderer if
* this is not called from the main thread (for example, if a garbage collector * this is not called from the main thread (for example, if a garbage collector
* deletes the resource instead of the programmer). * deletes the resource instead of the programmer).
* *
* buffer: The REFRESH_Buffer to be destroyed. * buffer: The REFRESH_Buffer to be destroyed.
*/ */
REFRESHAPI void REFRESH_AddDisposeVertexBuffer( REFRESHAPI void REFRESH_AddDisposeBuffer(
REFRESH_Device *device,
REFRESH_Buffer *buffer
);
/* Sends an index buffer to be destroyed by the renderer. Note that we call it
* "AddDispose" because it may not be immediately destroyed by the renderer if
* this is not called from the main thread (for example, if a garbage collector
* deletes the resource instead of the programmer).
*
* buffer: The REFRESH_Buffer to be destroyed.
*/
REFRESHAPI void REFRESH_AddDisposeIndexBuffer(
REFRESH_Device *device, REFRESH_Device *device,
REFRESH_Buffer *buffer REFRESH_Buffer *buffer
); );

View File

@ -721,23 +721,12 @@ void REFRESH_AddDisposeSampler(
); );
} }
void REFRESH_AddDisposeVertexBuffer( void REFRESH_AddDisposeBuffer(
REFRESH_Device *device, REFRESH_Device *device,
REFRESH_Buffer *buffer REFRESH_Buffer *buffer
) { ) {
NULL_RETURN(device); NULL_RETURN(device);
device->AddDisposeVertexBuffer( device->AddDisposeBuffer(
device->driverData,
buffer
);
}
void REFRESH_AddDisposeIndexBuffer(
REFRESH_Device *device,
REFRESH_Buffer *buffer
) {
NULL_RETURN(device);
device->AddDisposeIndexBuffer(
device->driverData, device->driverData,
buffer buffer
); );

View File

@ -446,12 +446,7 @@ struct REFRESH_Device
REFRESH_Sampler *sampler REFRESH_Sampler *sampler
); );
void(*AddDisposeVertexBuffer)( void(*AddDisposeBuffer)(
REFRESH_Renderer *driverData,
REFRESH_Buffer *buffer
);
void(*AddDisposeIndexBuffer)(
REFRESH_Renderer *driverData, REFRESH_Renderer *driverData,
REFRESH_Buffer *buffer REFRESH_Buffer *buffer
); );
@ -609,8 +604,7 @@ struct REFRESH_Device
ASSIGN_DRIVER_FUNC(CopyTextureDataCube, name) \ ASSIGN_DRIVER_FUNC(CopyTextureDataCube, name) \
ASSIGN_DRIVER_FUNC(AddDisposeTexture, name) \ ASSIGN_DRIVER_FUNC(AddDisposeTexture, name) \
ASSIGN_DRIVER_FUNC(AddDisposeSampler, name) \ ASSIGN_DRIVER_FUNC(AddDisposeSampler, name) \
ASSIGN_DRIVER_FUNC(AddDisposeVertexBuffer, name) \ ASSIGN_DRIVER_FUNC(AddDisposeBuffer, name) \
ASSIGN_DRIVER_FUNC(AddDisposeIndexBuffer, name) \
ASSIGN_DRIVER_FUNC(AddDisposeColorTarget, name) \ ASSIGN_DRIVER_FUNC(AddDisposeColorTarget, name) \
ASSIGN_DRIVER_FUNC(AddDisposeDepthStencilTarget, name) \ ASSIGN_DRIVER_FUNC(AddDisposeDepthStencilTarget, name) \
ASSIGN_DRIVER_FUNC(AddDisposeFramebuffer, name) \ ASSIGN_DRIVER_FUNC(AddDisposeFramebuffer, name) \

View File

@ -72,6 +72,7 @@ static uint32_t deviceExtensionCount = SDL_arraysize(deviceExtensionNames);
#define STARTING_ALLOCATION_SIZE 64000000 /* 64MB */ #define STARTING_ALLOCATION_SIZE 64000000 /* 64MB */
#define MAX_ALLOCATION_SIZE 256000000 /* 256MB */ #define MAX_ALLOCATION_SIZE 256000000 /* 256MB */
#define TEXTURE_STAGING_SIZE 8000000 /* 8MB */ #define TEXTURE_STAGING_SIZE 8000000 /* 8MB */
#define MAX_TEXTURE_STAGING_SIZE 128000000 /* 128MB */
#define UBO_BUFFER_SIZE 8000000 /* 8MB */ #define UBO_BUFFER_SIZE 8000000 /* 8MB */
#define UBO_ACTUAL_SIZE (UBO_BUFFER_SIZE * 2) #define UBO_ACTUAL_SIZE (UBO_BUFFER_SIZE * 2)
#define DESCRIPTOR_POOL_STARTING_SIZE 128 #define DESCRIPTOR_POOL_STARTING_SIZE 128
@ -1324,6 +1325,7 @@ typedef struct VulkanRenderer
VulkanBuffer *dummyComputeUniformBuffer; VulkanBuffer *dummyComputeUniformBuffer;
VulkanBuffer *textureStagingBuffer; VulkanBuffer *textureStagingBuffer;
uint32_t textureStagingBufferOffset;
VulkanBuffer** buffersInUse; VulkanBuffer** buffersInUse;
uint32_t buffersInUseCount; uint32_t buffersInUseCount;
@ -1448,6 +1450,7 @@ typedef struct VulkanRenderer
static void VULKAN_INTERNAL_BeginCommandBuffer(VulkanRenderer *renderer, VulkanCommandBuffer *commandBuffer); static void VULKAN_INTERNAL_BeginCommandBuffer(VulkanRenderer *renderer, VulkanCommandBuffer *commandBuffer);
static void VULKAN_Submit(REFRESH_Renderer *driverData, REFRESH_CommandBuffer **pCommandBuffers, uint32_t commandBufferCount); static void VULKAN_Submit(REFRESH_Renderer *driverData, REFRESH_CommandBuffer **pCommandBuffers, uint32_t commandBufferCount);
static void VULKAN_INTERNAL_FlushTransfers(VulkanRenderer *renderer);
/* Error Handling */ /* Error Handling */
@ -2141,31 +2144,6 @@ static void VULKAN_INTERNAL_ImageMemoryBarrier(
/* Resource Disposal */ /* Resource Disposal */
static void VULKAN_INTERNAL_RemoveBuffer(
REFRESH_Renderer *driverData,
REFRESH_Buffer *buffer
) {
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
VulkanBuffer *vulkanBuffer = (VulkanBuffer*) buffer;
SDL_LockMutex(renderer->disposeLock);
EXPAND_ARRAY_IF_NEEDED(
renderer->buffersToDestroy,
VulkanBuffer*,
renderer->buffersToDestroyCount + 1,
renderer->buffersToDestroyCapacity,
renderer->buffersToDestroyCapacity * 2
)
renderer->buffersToDestroy[
renderer->buffersToDestroyCount
] = vulkanBuffer;
renderer->buffersToDestroyCount += 1;
SDL_UnlockMutex(renderer->disposeLock);
}
static void VULKAN_INTERNAL_DestroyTexture( static void VULKAN_INTERNAL_DestroyTexture(
VulkanRenderer* renderer, VulkanRenderer* renderer,
VulkanTexture* texture VulkanTexture* texture
@ -2299,10 +2277,10 @@ static void VULKAN_INTERNAL_DestroyCommandPool(
VulkanRenderer *renderer, VulkanRenderer *renderer,
VulkanCommandPool *commandPool VulkanCommandPool *commandPool
) { ) {
renderer->vkResetCommandPool( renderer->vkDestroyCommandPool(
renderer->logicalDevice, renderer->logicalDevice,
commandPool->commandPool, commandPool->commandPool,
VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT NULL
); );
SDL_free(commandPool->inactiveCommandBuffers); SDL_free(commandPool->inactiveCommandBuffers);
@ -3488,6 +3466,12 @@ static void VULKAN_DestroyDevice(
} }
} }
renderer->vkDestroyCommandPool(
renderer->logicalDevice,
renderer->transferCommandPool,
NULL
);
for (i = 0; i < NUM_PIPELINE_LAYOUT_BUCKETS; i += 1) for (i = 0; i < NUM_PIPELINE_LAYOUT_BUCKETS; i += 1)
{ {
graphicsPipelineLayoutHashArray = renderer->graphicsPipelineLayoutHashTable.buckets[i]; graphicsPipelineLayoutHashArray = renderer->graphicsPipelineLayoutHashTable.buckets[i];
@ -5847,20 +5831,28 @@ static REFRESH_Buffer* VULKAN_CreateBuffer(
static void VULKAN_INTERNAL_MaybeExpandStagingBuffer( static void VULKAN_INTERNAL_MaybeExpandStagingBuffer(
VulkanRenderer *renderer, VulkanRenderer *renderer,
VkDeviceSize size uint32_t textureSize
) { ) {
if (size <= renderer->textureStagingBuffer->size) VkDeviceSize currentStagingSize = renderer->textureStagingBuffer->size;
if (renderer->textureStagingBufferOffset + textureSize <= renderer->textureStagingBuffer->size)
{ {
return; return;
} }
/* not enough room in the staging buffer, time to flush */
VULKAN_INTERNAL_FlushTransfers(renderer);
/* double staging buffer size up to max */
if (currentStagingSize * 2 <= MAX_TEXTURE_STAGING_SIZE)
{
VULKAN_INTERNAL_DestroyTextureStagingBuffer(renderer); VULKAN_INTERNAL_DestroyTextureStagingBuffer(renderer);
renderer->textureStagingBuffer = (VulkanBuffer*) SDL_malloc(sizeof(VulkanBuffer)); renderer->textureStagingBuffer = (VulkanBuffer*) SDL_malloc(sizeof(VulkanBuffer));
if (!VULKAN_INTERNAL_CreateBuffer( if (!VULKAN_INTERNAL_CreateBuffer(
renderer, renderer,
size, currentStagingSize * 2,
RESOURCE_ACCESS_MEMORY_TRANSFER_READ_WRITE, RESOURCE_ACCESS_MEMORY_TRANSFER_READ_WRITE,
VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
1, 1,
@ -5869,6 +5861,7 @@ static void VULKAN_INTERNAL_MaybeExpandStagingBuffer(
REFRESH_LogError("Failed to expand texture staging buffer!"); REFRESH_LogError("Failed to expand texture staging buffer!");
return; return;
} }
}
} }
static void VULKAN_INTERNAL_MaybeBeginTransferCommandBuffer( static void VULKAN_INTERNAL_MaybeBeginTransferCommandBuffer(
@ -5903,6 +5896,88 @@ static void VULKAN_INTERNAL_EndTransferCommandBuffer(
} }
} }
/* Hard sync point! */
static void VULKAN_INTERNAL_FlushTransfers(
VulkanRenderer *renderer
) {
VkSubmitInfo transferSubmitInfo;
VkResult vulkanResult;
if (renderer->pendingTransfer)
{
VULKAN_INTERNAL_EndTransferCommandBuffer(renderer);
transferSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
transferSubmitInfo.pNext = NULL;
transferSubmitInfo.commandBufferCount = 1;
transferSubmitInfo.pCommandBuffers = &renderer->transferCommandBuffers[renderer->frameIndex];
transferSubmitInfo.pWaitDstStageMask = NULL;
transferSubmitInfo.pWaitSemaphores = NULL;
transferSubmitInfo.waitSemaphoreCount = 0;
transferSubmitInfo.pSignalSemaphores = NULL;
transferSubmitInfo.signalSemaphoreCount = 0;
/* Wait for the previous submission to complete */
vulkanResult = renderer->vkWaitForFences(
renderer->logicalDevice,
1,
&renderer->inFlightFence,
VK_TRUE,
UINT64_MAX
);
if (vulkanResult != VK_SUCCESS)
{
LogVulkanResult("vkWaitForFences", vulkanResult);
return;
}
renderer->vkResetFences(
renderer->logicalDevice,
1,
&renderer->inFlightFence
);
/* Submit transfers */
vulkanResult = renderer->vkQueueSubmit(
renderer->transferQueue,
1,
&transferSubmitInfo,
NULL
);
if (vulkanResult != VK_SUCCESS)
{
LogVulkanResult("vkQueueSubmit", vulkanResult);
return;
}
/* Wait again */
vulkanResult = renderer->vkWaitForFences(
renderer->logicalDevice,
1,
&renderer->inFlightFence,
VK_TRUE,
UINT64_MAX
);
if (vulkanResult != VK_SUCCESS)
{
LogVulkanResult("vkWaitForFences", vulkanResult);
return;
}
renderer->vkResetFences(
renderer->logicalDevice,
1,
&renderer->inFlightFence
);
renderer->pendingTransfer = 0;
renderer->textureStagingBufferOffset = 0;
}
}
static void VULKAN_SetTextureData2D( static void VULKAN_SetTextureData2D(
REFRESH_Renderer *driverData, REFRESH_Renderer *driverData,
REFRESH_Texture *texture, REFRESH_Texture *texture,
@ -5922,13 +5997,13 @@ static void VULKAN_SetTextureData2D(
VkBufferImageCopy imageCopy; VkBufferImageCopy imageCopy;
uint8_t *mapPointer; uint8_t *mapPointer;
VULKAN_INTERNAL_MaybeBeginTransferCommandBuffer(renderer);
VULKAN_INTERNAL_MaybeExpandStagingBuffer(renderer, dataLengthInBytes); VULKAN_INTERNAL_MaybeExpandStagingBuffer(renderer, dataLengthInBytes);
VULKAN_INTERNAL_MaybeBeginTransferCommandBuffer(renderer);
vulkanResult = renderer->vkMapMemory( vulkanResult = renderer->vkMapMemory(
renderer->logicalDevice, renderer->logicalDevice,
renderer->textureStagingBuffer->subBuffers[0]->allocation->memory, renderer->textureStagingBuffer->subBuffers[0]->allocation->memory,
renderer->textureStagingBuffer->subBuffers[0]->offset, renderer->textureStagingBuffer->subBuffers[0]->offset + renderer->textureStagingBufferOffset,
renderer->textureStagingBuffer->subBuffers[0]->size, renderer->textureStagingBuffer->subBuffers[0]->size,
0, 0,
(void**) &mapPointer (void**) &mapPointer
@ -5971,7 +6046,7 @@ static void VULKAN_SetTextureData2D(
imageCopy.imageSubresource.baseArrayLayer = 0; imageCopy.imageSubresource.baseArrayLayer = 0;
imageCopy.imageSubresource.layerCount = 1; imageCopy.imageSubresource.layerCount = 1;
imageCopy.imageSubresource.mipLevel = level; imageCopy.imageSubresource.mipLevel = level;
imageCopy.bufferOffset = 0; imageCopy.bufferOffset = renderer->textureStagingBufferOffset;
imageCopy.bufferRowLength = 0; imageCopy.bufferRowLength = 0;
imageCopy.bufferImageHeight = 0; imageCopy.bufferImageHeight = 0;
@ -5984,6 +6059,8 @@ static void VULKAN_SetTextureData2D(
&imageCopy &imageCopy
); );
renderer->textureStagingBufferOffset += dataLengthInBytes;
if (vulkanTexture->usageFlags & REFRESH_TEXTUREUSAGE_SAMPLER_BIT) if (vulkanTexture->usageFlags & REFRESH_TEXTUREUSAGE_SAMPLER_BIT)
{ {
VULKAN_INTERNAL_ImageMemoryBarrier( VULKAN_INTERNAL_ImageMemoryBarrier(
@ -6023,13 +6100,13 @@ static void VULKAN_SetTextureData3D(
VkBufferImageCopy imageCopy; VkBufferImageCopy imageCopy;
uint8_t *mapPointer; uint8_t *mapPointer;
VULKAN_INTERNAL_MaybeBeginTransferCommandBuffer(renderer);
VULKAN_INTERNAL_MaybeExpandStagingBuffer(renderer, dataLength); VULKAN_INTERNAL_MaybeExpandStagingBuffer(renderer, dataLength);
VULKAN_INTERNAL_MaybeBeginTransferCommandBuffer(renderer);
vulkanResult = renderer->vkMapMemory( vulkanResult = renderer->vkMapMemory(
renderer->logicalDevice, renderer->logicalDevice,
renderer->textureStagingBuffer->subBuffers[0]->allocation->memory, renderer->textureStagingBuffer->subBuffers[0]->allocation->memory,
renderer->textureStagingBuffer->subBuffers[0]->offset, renderer->textureStagingBuffer->subBuffers[0]->offset + renderer->textureStagingBufferOffset,
renderer->textureStagingBuffer->subBuffers[0]->size, renderer->textureStagingBuffer->subBuffers[0]->size,
0, 0,
(void**) &mapPointer (void**) &mapPointer
@ -6072,7 +6149,7 @@ static void VULKAN_SetTextureData3D(
imageCopy.imageSubresource.baseArrayLayer = 0; imageCopy.imageSubresource.baseArrayLayer = 0;
imageCopy.imageSubresource.layerCount = 1; imageCopy.imageSubresource.layerCount = 1;
imageCopy.imageSubresource.mipLevel = level; imageCopy.imageSubresource.mipLevel = level;
imageCopy.bufferOffset = 0; imageCopy.bufferOffset = renderer->textureStagingBufferOffset;
imageCopy.bufferRowLength = 0; imageCopy.bufferRowLength = 0;
imageCopy.bufferImageHeight = 0; imageCopy.bufferImageHeight = 0;
@ -6085,6 +6162,8 @@ static void VULKAN_SetTextureData3D(
&imageCopy &imageCopy
); );
renderer->textureStagingBufferOffset += dataLength;
if (vulkanTexture->usageFlags & REFRESH_TEXTUREUSAGE_SAMPLER_BIT) if (vulkanTexture->usageFlags & REFRESH_TEXTUREUSAGE_SAMPLER_BIT)
{ {
VULKAN_INTERNAL_ImageMemoryBarrier( VULKAN_INTERNAL_ImageMemoryBarrier(
@ -6123,13 +6202,13 @@ static void VULKAN_SetTextureDataCube(
VkBufferImageCopy imageCopy; VkBufferImageCopy imageCopy;
uint8_t *mapPointer; uint8_t *mapPointer;
VULKAN_INTERNAL_MaybeBeginTransferCommandBuffer(renderer);
VULKAN_INTERNAL_MaybeExpandStagingBuffer(renderer, dataLength); VULKAN_INTERNAL_MaybeExpandStagingBuffer(renderer, dataLength);
VULKAN_INTERNAL_MaybeBeginTransferCommandBuffer(renderer);
vulkanResult = renderer->vkMapMemory( vulkanResult = renderer->vkMapMemory(
renderer->logicalDevice, renderer->logicalDevice,
renderer->textureStagingBuffer->subBuffers[0]->allocation->memory, renderer->textureStagingBuffer->subBuffers[0]->allocation->memory,
renderer->textureStagingBuffer->subBuffers[0]->offset, renderer->textureStagingBuffer->subBuffers[0]->offset + renderer->textureStagingBufferOffset,
renderer->textureStagingBuffer->subBuffers[0]->size, renderer->textureStagingBuffer->subBuffers[0]->size,
0, 0,
(void**) &mapPointer (void**) &mapPointer
@ -6172,7 +6251,7 @@ static void VULKAN_SetTextureDataCube(
imageCopy.imageSubresource.baseArrayLayer = cubeMapFace; imageCopy.imageSubresource.baseArrayLayer = cubeMapFace;
imageCopy.imageSubresource.layerCount = 1; imageCopy.imageSubresource.layerCount = 1;
imageCopy.imageSubresource.mipLevel = level; imageCopy.imageSubresource.mipLevel = level;
imageCopy.bufferOffset = 0; imageCopy.bufferOffset = renderer->textureStagingBufferOffset;
imageCopy.bufferRowLength = 0; /* assumes tightly packed data */ imageCopy.bufferRowLength = 0; /* assumes tightly packed data */
imageCopy.bufferImageHeight = 0; /* assumes tightly packed data */ imageCopy.bufferImageHeight = 0; /* assumes tightly packed data */
@ -6185,6 +6264,8 @@ static void VULKAN_SetTextureDataCube(
&imageCopy &imageCopy
); );
renderer->textureStagingBufferOffset += dataLength;
if (vulkanTexture->usageFlags & REFRESH_TEXTUREUSAGE_SAMPLER_BIT) if (vulkanTexture->usageFlags & REFRESH_TEXTUREUSAGE_SAMPLER_BIT)
{ {
VULKAN_INTERNAL_ImageMemoryBarrier( VULKAN_INTERNAL_ImageMemoryBarrier(
@ -6226,8 +6307,8 @@ static void VULKAN_SetTextureDataYUV(
uint8_t *mapPointer; uint8_t *mapPointer;
VkResult vulkanResult; VkResult vulkanResult;
VULKAN_INTERNAL_MaybeBeginTransferCommandBuffer(renderer);
VULKAN_INTERNAL_MaybeExpandStagingBuffer(renderer, dataLength); VULKAN_INTERNAL_MaybeExpandStagingBuffer(renderer, dataLength);
VULKAN_INTERNAL_MaybeBeginTransferCommandBuffer(renderer);
/* Initialize values that are the same for Y, U, and V */ /* Initialize values that are the same for Y, U, and V */
@ -6239,7 +6320,6 @@ static void VULKAN_SetTextureDataYUV(
imageCopy.imageSubresource.baseArrayLayer = 0; imageCopy.imageSubresource.baseArrayLayer = 0;
imageCopy.imageSubresource.layerCount = 1; imageCopy.imageSubresource.layerCount = 1;
imageCopy.imageSubresource.mipLevel = 0; imageCopy.imageSubresource.mipLevel = 0;
imageCopy.bufferOffset = 0;
/* Y */ /* Y */
@ -6248,7 +6328,7 @@ static void VULKAN_SetTextureDataYUV(
vulkanResult = renderer->vkMapMemory( vulkanResult = renderer->vkMapMemory(
renderer->logicalDevice, renderer->logicalDevice,
renderer->textureStagingBuffer->subBuffers[0]->allocation->memory, renderer->textureStagingBuffer->subBuffers[0]->allocation->memory,
renderer->textureStagingBuffer->subBuffers[0]->offset, renderer->textureStagingBuffer->subBuffers[0]->offset + renderer->textureStagingBufferOffset,
renderer->textureStagingBuffer->subBuffers[0]->size, renderer->textureStagingBuffer->subBuffers[0]->size,
0, 0,
(void**) &mapPointer (void**) &mapPointer
@ -6280,8 +6360,10 @@ static void VULKAN_SetTextureDataYUV(
&tex->resourceAccessType &tex->resourceAccessType
); );
imageCopy.imageExtent.width = yWidth; imageCopy.imageExtent.width = yWidth;
imageCopy.imageExtent.height = yHeight; imageCopy.imageExtent.height = yHeight;
imageCopy.bufferOffset = renderer->textureStagingBufferOffset;
imageCopy.bufferRowLength = yWidth; imageCopy.bufferRowLength = yWidth;
imageCopy.bufferImageHeight = yHeight; imageCopy.bufferImageHeight = yHeight;
@ -6303,7 +6385,7 @@ static void VULKAN_SetTextureDataYUV(
/* U */ /* U */
imageCopy.bufferOffset = yDataLength; imageCopy.bufferOffset = renderer->textureStagingBufferOffset + yDataLength;
tex = (VulkanTexture*) u; tex = (VulkanTexture*) u;
@ -6338,7 +6420,7 @@ static void VULKAN_SetTextureDataYUV(
/* V */ /* V */
imageCopy.bufferOffset = yDataLength + uvDataLength; imageCopy.bufferOffset = renderer->textureStagingBufferOffset + uvDataLength;
tex = (VulkanTexture*) v; tex = (VulkanTexture*) v;
@ -6376,6 +6458,8 @@ static void VULKAN_SetTextureDataYUV(
&imageCopy &imageCopy
); );
renderer->textureStagingBufferOffset += dataLength;
if (tex->usageFlags & REFRESH_TEXTUREUSAGE_SAMPLER_BIT) if (tex->usageFlags & REFRESH_TEXTUREUSAGE_SAMPLER_BIT)
{ {
VULKAN_INTERNAL_ImageMemoryBarrier( VULKAN_INTERNAL_ImageMemoryBarrier(
@ -7154,18 +7238,29 @@ static void VULKAN_AddDisposeSampler(
SDL_UnlockMutex(renderer->disposeLock); SDL_UnlockMutex(renderer->disposeLock);
} }
static void VULKAN_AddDisposeVertexBuffer( static void VULKAN_AddDisposeBuffer(
REFRESH_Renderer *driverData, REFRESH_Renderer *driverData,
REFRESH_Buffer *buffer REFRESH_Buffer *buffer
) { ) {
VULKAN_INTERNAL_RemoveBuffer(driverData, buffer); VulkanRenderer *renderer = (VulkanRenderer*) driverData;
} VulkanBuffer *vulkanBuffer = (VulkanBuffer*) buffer;
static void VULKAN_AddDisposeIndexBuffer( SDL_LockMutex(renderer->disposeLock);
REFRESH_Renderer *driverData,
REFRESH_Buffer *buffer EXPAND_ARRAY_IF_NEEDED(
) { renderer->buffersToDestroy,
VULKAN_INTERNAL_RemoveBuffer(driverData, buffer); VulkanBuffer*,
renderer->buffersToDestroyCount + 1,
renderer->buffersToDestroyCapacity,
renderer->buffersToDestroyCapacity * 2
)
renderer->buffersToDestroy[
renderer->buffersToDestroyCount
] = vulkanBuffer;
renderer->buffersToDestroyCount += 1;
SDL_UnlockMutex(renderer->disposeLock);
} }
static void VULKAN_AddDisposeColorTarget( static void VULKAN_AddDisposeColorTarget(
@ -8216,7 +8311,9 @@ static void VULKAN_Submit(
uint32_t i; uint32_t i;
uint8_t present; uint8_t present;
VkPipelineStageFlags waitStages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; VkPipelineStageFlags waitStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
VkSemaphore waitSemaphores[2];
uint32_t waitSemaphoreCount = 0;
VkPresentInfoKHR presentInfo; VkPresentInfoKHR presentInfo;
if (renderer->pendingTransfer) if (renderer->pendingTransfer)
@ -8232,6 +8329,9 @@ static void VULKAN_Submit(
transferSubmitInfo.waitSemaphoreCount = 0; transferSubmitInfo.waitSemaphoreCount = 0;
transferSubmitInfo.pSignalSemaphores = &renderer->transferFinishedSemaphore; transferSubmitInfo.pSignalSemaphores = &renderer->transferFinishedSemaphore;
transferSubmitInfo.signalSemaphoreCount = 1; transferSubmitInfo.signalSemaphoreCount = 1;
waitSemaphores[waitSemaphoreCount] = renderer->transferFinishedSemaphore;
waitSemaphoreCount += 1;
} }
present = !renderer->headless && renderer->shouldPresent; present = !renderer->headless && renderer->shouldPresent;
@ -8252,21 +8352,23 @@ static void VULKAN_Submit(
if (present) if (present)
{ {
submitInfo.waitSemaphoreCount = 1; waitSemaphores[waitSemaphoreCount] = renderer->imageAvailableSemaphore;
submitInfo.pWaitSemaphores = &renderer->imageAvailableSemaphore; waitSemaphoreCount += 1;
submitInfo.pWaitDstStageMask = &waitStages;
submitInfo.pWaitDstStageMask = &waitStage;
submitInfo.signalSemaphoreCount = 1; submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = &renderer->renderFinishedSemaphore; submitInfo.pSignalSemaphores = &renderer->renderFinishedSemaphore;
} }
else else
{ {
submitInfo.waitSemaphoreCount = 0;
submitInfo.pWaitSemaphores = NULL;
submitInfo.pWaitDstStageMask = NULL; submitInfo.pWaitDstStageMask = NULL;
submitInfo.signalSemaphoreCount = 0; submitInfo.signalSemaphoreCount = 0;
submitInfo.pSignalSemaphores = NULL; submitInfo.pSignalSemaphores = NULL;
} }
submitInfo.waitSemaphoreCount = waitSemaphoreCount;
submitInfo.pWaitSemaphores = waitSemaphores;
/* Wait for the previous submission to complete */ /* Wait for the previous submission to complete */
vulkanResult = renderer->vkWaitForFences( vulkanResult = renderer->vkWaitForFences(
renderer->logicalDevice, renderer->logicalDevice,
@ -8394,6 +8496,7 @@ static void VULKAN_Submit(
renderer->swapChainImageAcquired = 0; renderer->swapChainImageAcquired = 0;
renderer->shouldPresent = 0; renderer->shouldPresent = 0;
renderer->pendingTransfer = 0; renderer->pendingTransfer = 0;
renderer->textureStagingBufferOffset = 0;
SDL_stack_free(commandBuffers); SDL_stack_free(commandBuffers);
} }
@ -8901,12 +9004,11 @@ static uint8_t VULKAN_INTERNAL_CreateLogicalDevice(
VkDeviceCreateInfo deviceCreateInfo; VkDeviceCreateInfo deviceCreateInfo;
VkPhysicalDeviceFeatures deviceFeatures; VkPhysicalDeviceFeatures deviceFeatures;
VkDeviceQueueCreateInfo queueCreateInfos[3]; VkDeviceQueueCreateInfo queueCreateInfos[2];
VkDeviceQueueCreateInfo queueCreateInfoGraphics; VkDeviceQueueCreateInfo queueCreateInfoGraphics;
VkDeviceQueueCreateInfo queueCreateInfoPresent; VkDeviceQueueCreateInfo queueCreateInfoPresent;
VkDeviceQueueCreateInfo queueCreateInfoTransfer;
int32_t queueInfoCount = 2; int32_t queueInfoCount = 1;
float queuePriority = 1.0f; float queuePriority = 1.0f;
queueCreateInfoGraphics.sType = queueCreateInfoGraphics.sType =
@ -8920,17 +9022,6 @@ static uint8_t VULKAN_INTERNAL_CreateLogicalDevice(
queueCreateInfos[0] = queueCreateInfoGraphics; queueCreateInfos[0] = queueCreateInfoGraphics;
queueCreateInfoTransfer.sType =
VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueCreateInfoTransfer.pNext = NULL;
queueCreateInfoTransfer.flags = 0;
queueCreateInfoTransfer.queueFamilyIndex =
renderer->queueFamilyIndices.transferFamily;
queueCreateInfoTransfer.queueCount = 1;
queueCreateInfoTransfer.pQueuePriorities = &queuePriority;
queueCreateInfos[1] = queueCreateInfoTransfer;
if (renderer->queueFamilyIndices.presentFamily != renderer->queueFamilyIndices.graphicsFamily) if (renderer->queueFamilyIndices.presentFamily != renderer->queueFamilyIndices.graphicsFamily)
{ {
queueCreateInfoPresent.sType = queueCreateInfoPresent.sType =
@ -9606,6 +9697,8 @@ static REFRESH_Device* VULKAN_CreateDevice(
return NULL; return NULL;
} }
renderer->textureStagingBufferOffset = 0;
/* Dummy Uniform Buffers */ /* Dummy Uniform Buffers */
renderer->dummyVertexUniformBuffer = (VulkanBuffer*) SDL_malloc(sizeof(VulkanBuffer)); renderer->dummyVertexUniformBuffer = (VulkanBuffer*) SDL_malloc(sizeof(VulkanBuffer));