From b4dee16f808d336bfbafafcc239903ba64f006d7 Mon Sep 17 00:00:00 2001 From: thatcosmonaut <2342303+thatcosmonaut@users.noreply.github.com> Date: Sun, 3 Jan 2021 14:37:02 -0800 Subject: [PATCH] Texture API Refactor (#9) --- include/Refresh.h | 97 +-------- src/Refresh.c | 98 +-------- src/Refresh_Driver.h | 51 +---- src/Refresh_Driver_Vulkan.c | 422 ++++++------------------------------ 4 files changed, 97 insertions(+), 571 deletions(-) diff --git a/include/Refresh.h b/include/Refresh.h index e802c5b..f9cbe00 100644 --- a/include/Refresh.h +++ b/include/Refresh.h @@ -391,7 +391,9 @@ typedef struct REFRESH_Viewport typedef struct REFRESH_TextureSlice { REFRESH_Texture *texture; - uint32_t layer; /* 0-5 for cube, or z-slice for 3D */ + REFRESH_Rect rectangle; + uint32_t depth; /* 0 unless 3D */ + uint32_t layer; /* 0 unless cube */ uint32_t level; } REFRESH_TextureSlice; @@ -890,81 +892,19 @@ REFRESHAPI REFRESH_Buffer* REFRESH_CreateBuffer( /* Setters */ -/* Uploads image data to a 2D texture object. +/* Uploads image data to a texture object. * - * texture: The texture to be updated. - * x: The x offset of the subregion being updated. - * y: The y offset of the subregion being updated. - * w: The width of the subregion being updated. - * h: The height of the subregion being updated. - * level: The mipmap level being updated. - * data: A pointer to the image data. - * dataLength: The size of the image data in bytes. + * textureSlice: The texture slice to be updated. + * data: A pointer to the image data. + * dataLengthInBytes: The size of the image data. */ -REFRESHAPI void REFRESH_SetTextureData2D( +REFRESHAPI void REFRESH_SetTextureData( REFRESH_Device *driverData, - REFRESH_Texture *texture, - uint32_t x, - uint32_t y, - uint32_t w, - uint32_t h, - uint32_t level, + REFRESH_TextureSlice *textureSlice, void *data, uint32_t dataLengthInBytes ); -/* Uploads image data to a 3D texture object. - * - * texture: The texture to be updated. - * x: The x offset of the subregion being updated. - * y: The y offset of the subregion being updated. - * z: The z offset of the subregion being updated. - * w: The width of the subregion being updated. - * h: The height of the subregion being updated. - * d: The depth of the subregion being updated. - * level: The mipmap level being updated. - * data: A pointer to the image data. - * dataLength: The size of the image data in bytes. - */ -REFRESHAPI void REFRESH_SetTextureData3D( - REFRESH_Device *driverData, - REFRESH_Texture *texture, - uint32_t x, - uint32_t y, - uint32_t z, - uint32_t w, - uint32_t h, - uint32_t d, - uint32_t level, - void* data, - uint32_t dataLength -); - -/* Uploads image data to a single face of a texture cube object. - * - * texture: The texture to be updated. - * x: The x offset of the subregion being updated. - * y: The y offset of the subregion being updated. - * w: The width of the subregion being updated. - * h: The height of the subregion being updated. - * cubeMapFace: The face of the cube being updated. - * level: The mipmap level being updated. - * data: A pointer to the image data. - * dataLength: The size of the image data in bytes. - */ -REFRESHAPI void REFRESH_SetTextureDataCube( - REFRESH_Device *driverData, - REFRESH_Texture *texture, - uint32_t x, - uint32_t y, - uint32_t w, - uint32_t h, - REFRESH_CubeMapFace cubeMapFace, - uint32_t level, - void* data, - uint32_t dataLength -); - /* Uploads YUV image data to three R8 texture objects. * * y: The texture storing the Y data. @@ -994,8 +934,6 @@ REFRESHAPI void REFRESH_SetTextureDataYUV( * * sourceTextureSlice: The texture slice from which to copy. * destinationTextureSlice: The texture slice to copy to. - * sourceRectangle: The region on the source texture slice to copy from. Can be NULL. - * destinationRectangle: The region on the destination texture slice to copy to. Can be NULL. * filter: The filter that will be used if the copy requires scaling. */ REFRESHAPI void REFRESH_CopyTextureToTexture( @@ -1003,8 +941,6 @@ REFRESHAPI void REFRESH_CopyTextureToTexture( REFRESH_CommandBuffer *commandBuffer, REFRESH_TextureSlice *sourceTextureSlice, REFRESH_TextureSlice *destinationTextureSlice, - REFRESH_Rect *sourceRectangle, - REFRESH_Rect *destinationRectangle, REFRESH_Filter filter ); @@ -1015,21 +951,12 @@ REFRESHAPI void REFRESH_CopyTextureToTexture( * is submitted and completed. * * textureSlice: The texture object being copied. - * x: The x offset of the subregion being read. - * y: The y offset of the subregion being read. - * w: The width of the subregion being read. - * h: The height of the subregion being read. - * level: The mipmap level being read. * buffer: The buffer being filled with the image data. */ REFRESHAPI void REFRESH_CopyTextureToBuffer( REFRESH_Device *device, REFRESH_CommandBuffer *commandBuffer, - REFRESH_TextureSlice *texture, - uint32_t x, - uint32_t y, - uint32_t w, - uint32_t h, + REFRESH_TextureSlice *textureSlice, REFRESH_Buffer *buffer ); @@ -1392,15 +1319,13 @@ REFRESHAPI REFRESH_CommandBuffer* REFRESH_AcquireCommandBuffer( * It is an error to call this function in headless mode. * * textureSlice: The texture slice to present. - * sourceRectangle: The region of the image to present (or NULL). - * destinationRectangle: The region of the window to update (or NULL). + * destinationRectangle: The region of the window to update. Can be NULL. * filter: The filter to use if scaling is required. */ REFRESHAPI void REFRESH_QueuePresent( REFRESH_Device *device, REFRESH_CommandBuffer *commandBuffer, REFRESH_TextureSlice *textureSlice, - REFRESH_Rect *sourceRectangle, REFRESH_Rect *destinationRectangle, REFRESH_Filter filter ); diff --git a/src/Refresh.c b/src/Refresh.c index a5b8af1..bdc97fb 100644 --- a/src/Refresh.c +++ b/src/Refresh.c @@ -432,87 +432,21 @@ REFRESH_Buffer* REFRESH_CreateBuffer( ); } -void REFRESH_SetTextureData2D( +void REFRESH_SetTextureData( REFRESH_Device *device, - REFRESH_Texture *texture, - uint32_t x, - uint32_t y, - uint32_t w, - uint32_t h, - uint32_t level, + REFRESH_TextureSlice *textureSlice, void *data, uint32_t dataLengthInBytes ) { NULL_RETURN(device); - device->SetTextureData2D( + device->SetTextureData( device->driverData, - texture, - x, - y, - w, - h, - level, + textureSlice, data, dataLengthInBytes ); } -void REFRESH_SetTextureData3D( - REFRESH_Device *device, - REFRESH_Texture *texture, - uint32_t x, - uint32_t y, - uint32_t z, - uint32_t w, - uint32_t h, - uint32_t d, - uint32_t level, - void* data, - uint32_t dataLength -) { - NULL_RETURN(device); - device->SetTextureData3D( - device->driverData, - texture, - x, - y, - z, - w, - h, - d, - level, - data, - dataLength - ); -} - -void REFRESH_SetTextureDataCube( - REFRESH_Device *device, - REFRESH_Texture *texture, - uint32_t x, - uint32_t y, - uint32_t w, - uint32_t h, - REFRESH_CubeMapFace cubeMapFace, - uint32_t level, - void* data, - uint32_t dataLength -) { - NULL_RETURN(device); - device->SetTextureDataCube( - device->driverData, - texture, - x, - y, - w, - h, - cubeMapFace, - level, - data, - dataLength - ); -} - void REFRESH_SetTextureDataYUV( REFRESH_Device *device, REFRESH_Texture *y, @@ -542,12 +476,10 @@ void REFRESH_SetTextureDataYUV( void REFRESH_CopyTextureToTexture( REFRESH_Device *device, - REFRESH_CommandBuffer *commandBuffer, - REFRESH_TextureSlice *sourceTextureSlice, + REFRESH_CommandBuffer *commandBuffer, + REFRESH_TextureSlice *sourceTextureSlice, REFRESH_TextureSlice *destinationTextureSlice, - REFRESH_Rect *sourceRectangle, - REFRESH_Rect *destinationRectangle, - REFRESH_Filter filter + REFRESH_Filter filter ) { NULL_RETURN(device); device->CopyTextureToTexture( @@ -555,31 +487,21 @@ void REFRESH_CopyTextureToTexture( commandBuffer, sourceTextureSlice, destinationTextureSlice, - sourceRectangle, - destinationRectangle, filter ); } void REFRESH_CopyTextureToBuffer( REFRESH_Device *device, - REFRESH_CommandBuffer *commandBuffer, + REFRESH_CommandBuffer *commandBuffer, REFRESH_TextureSlice *textureSlice, - uint32_t x, - uint32_t y, - uint32_t w, - uint32_t h, - REFRESH_Buffer* buffer + REFRESH_Buffer *buffer ) { NULL_RETURN(device); device->CopyTextureToBuffer( device->driverData, commandBuffer, textureSlice, - x, - y, - w, - h, buffer ); } @@ -938,7 +860,6 @@ void REFRESH_QueuePresent( REFRESH_Device *device, REFRESH_CommandBuffer *commandBuffer, REFRESH_TextureSlice* textureSlice, - REFRESH_Rect *sourceRectangle, REFRESH_Rect *destinationRectangle, REFRESH_Filter filter ) { @@ -947,7 +868,6 @@ void REFRESH_QueuePresent( device->driverData, commandBuffer, textureSlice, - sourceRectangle, destinationRectangle, filter ); diff --git a/src/Refresh_Driver.h b/src/Refresh_Driver.h index aa181eb..0024be4 100644 --- a/src/Refresh_Driver.h +++ b/src/Refresh_Driver.h @@ -305,45 +305,13 @@ struct REFRESH_Device /* Setters */ - void(*SetTextureData2D)( + void(*SetTextureData)( REFRESH_Renderer *driverData, - REFRESH_Texture *texture, - uint32_t x, - uint32_t y, - uint32_t w, - uint32_t h, - uint32_t level, + REFRESH_TextureSlice *textureSlice, void *data, uint32_t dataLengthInBytes ); - void(*SetTextureData3D)( - REFRESH_Renderer *driverData, - REFRESH_Texture *texture, - uint32_t x, - uint32_t y, - uint32_t z, - uint32_t w, - uint32_t h, - uint32_t d, - uint32_t level, - void* data, - uint32_t dataLength - ); - - void(*SetTextureDataCube)( - REFRESH_Renderer *driverData, - REFRESH_Texture *texture, - uint32_t x, - uint32_t y, - uint32_t w, - uint32_t h, - REFRESH_CubeMapFace cubeMapFace, - uint32_t level, - void* data, - uint32_t dataLength - ); - void(*SetTextureDataYUV)( REFRESH_Renderer *driverData, REFRESH_Texture *y, @@ -361,9 +329,7 @@ struct REFRESH_Device REFRESH_Renderer *driverData, REFRESH_CommandBuffer *commandBuffer, REFRESH_TextureSlice *sourceTextureSlice, - REFRESH_TextureSlice *destinationTexture, - REFRESH_Rect *sourceRectangle, - REFRESH_Rect *destinationRectangle, + REFRESH_TextureSlice *destinationTextureSlice, REFRESH_Filter filter ); @@ -371,11 +337,7 @@ struct REFRESH_Device REFRESH_Renderer *driverData, REFRESH_CommandBuffer *commandBuffer, REFRESH_TextureSlice *textureSlice, - uint32_t x, - uint32_t y, - uint32_t w, - uint32_t h, - REFRESH_Buffer* buffer + REFRESH_Buffer *buffer ); void(*SetBufferData)( @@ -550,7 +512,6 @@ struct REFRESH_Device REFRESH_Renderer *driverData, REFRESH_CommandBuffer *commandBuffer, REFRESH_TextureSlice *textureSlice, - REFRESH_Rect *sourceRectangle, REFRESH_Rect *destinationRectangle, REFRESH_Filter filter ); @@ -590,9 +551,7 @@ struct REFRESH_Device ASSIGN_DRIVER_FUNC(CreateColorTarget, name) \ ASSIGN_DRIVER_FUNC(CreateDepthStencilTarget, name) \ ASSIGN_DRIVER_FUNC(CreateBuffer, name) \ - ASSIGN_DRIVER_FUNC(SetTextureData2D, name) \ - ASSIGN_DRIVER_FUNC(SetTextureData3D, name) \ - ASSIGN_DRIVER_FUNC(SetTextureDataCube, name) \ + ASSIGN_DRIVER_FUNC(SetTextureData, name) \ ASSIGN_DRIVER_FUNC(SetTextureDataYUV, name) \ ASSIGN_DRIVER_FUNC(CopyTextureToTexture, name) \ ASSIGN_DRIVER_FUNC(CopyTextureToBuffer, name) \ diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 89b8f5d..ab6a8f4 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -749,6 +749,10 @@ typedef struct VulkanTexture VkImage image; VkImageView view; VkExtent2D dimensions; + + uint8_t is3D; + uint8_t isCube; + uint32_t depth; uint32_t layerCount; uint32_t levelCount; @@ -5412,13 +5416,18 @@ static uint8_t VULKAN_INTERNAL_CreateTexture( uint8_t layerCount = isCube ? 6 : 1; VkComponentMapping swizzle = IDENTITY_SWIZZLE; + texture->isCube = 0; + texture->is3D = 0; + if (isCube) { imageCreateFlags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; + texture->isCube = 1; } else if (is3D) { imageCreateFlags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT; + texture->is3D = 1; } imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; @@ -5727,7 +5736,15 @@ static REFRESH_ColorTarget* VULKAN_CreateColorTarget( imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; imageViewCreateInfo.subresourceRange.baseMipLevel = 0; imageViewCreateInfo.subresourceRange.levelCount = 1; - imageViewCreateInfo.subresourceRange.baseArrayLayer = textureSlice->layer; + imageViewCreateInfo.subresourceRange.baseArrayLayer = 0; + if (colorTarget->texture->is3D) + { + imageViewCreateInfo.subresourceRange.baseArrayLayer = textureSlice->depth; + } + else if (colorTarget->texture->isCube) + { + imageViewCreateInfo.subresourceRange.baseArrayLayer = textureSlice->layer; + } imageViewCreateInfo.subresourceRange.layerCount = 1; imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; @@ -5994,23 +6011,18 @@ static void VULKAN_INTERNAL_FlushTransfers( } } -static void VULKAN_SetTextureData2D( +static void VULKAN_SetTextureData( REFRESH_Renderer *driverData, - REFRESH_Texture *texture, - uint32_t x, - uint32_t y, - uint32_t w, - uint32_t h, - uint32_t level, + REFRESH_TextureSlice *textureSlice, void *data, uint32_t dataLengthInBytes ) { VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanTexture *vulkanTexture = (VulkanTexture*) textureSlice->texture; VkCommandBuffer commandBuffer = renderer->transferCommandBuffers[renderer->frameIndex]; - VkResult vulkanResult; - VulkanTexture *vulkanTexture = (VulkanTexture*) texture; VkBufferImageCopy imageCopy; + VkResult vulkanResult; uint8_t *mapPointer; SDL_LockMutex(renderer->stagingLock); @@ -6051,25 +6063,25 @@ static void VULKAN_SetTextureData2D( commandBuffer, RESOURCE_ACCESS_TRANSFER_WRITE, VK_IMAGE_ASPECT_COLOR_BIT, - 0, - vulkanTexture->layerCount, - 0, - vulkanTexture->levelCount, + textureSlice->layer, + 1, + textureSlice->level, + 1, 0, vulkanTexture->image, &vulkanTexture->resourceAccessType ); - imageCopy.imageExtent.width = w; - imageCopy.imageExtent.height = h; + imageCopy.imageExtent.width = textureSlice->rectangle.w; + imageCopy.imageExtent.height = textureSlice->rectangle.h; imageCopy.imageExtent.depth = 1; - imageCopy.imageOffset.x = x; - imageCopy.imageOffset.y = y; - imageCopy.imageOffset.z = 0; + imageCopy.imageOffset.x = textureSlice->rectangle.x; + imageCopy.imageOffset.y = textureSlice->rectangle.y; + imageCopy.imageOffset.z = textureSlice->depth; imageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - imageCopy.imageSubresource.baseArrayLayer = 0; + imageCopy.imageSubresource.baseArrayLayer = textureSlice->layer; imageCopy.imageSubresource.layerCount = 1; - imageCopy.imageSubresource.mipLevel = level; + imageCopy.imageSubresource.mipLevel = textureSlice->level; imageCopy.bufferOffset = renderer->textureStagingBufferOffset; imageCopy.bufferRowLength = 0; imageCopy.bufferImageHeight = 0; @@ -6092,235 +6104,10 @@ static void VULKAN_SetTextureData2D( commandBuffer, RESOURCE_ACCESS_ANY_SHADER_READ_SAMPLED_IMAGE, VK_IMAGE_ASPECT_COLOR_BIT, - 0, - vulkanTexture->layerCount, - 0, - vulkanTexture->levelCount, - 0, - vulkanTexture->image, - &vulkanTexture->resourceAccessType - ); - } - - SDL_UnlockMutex(renderer->stagingLock); -} - -static void VULKAN_SetTextureData3D( - REFRESH_Renderer *driverData, - REFRESH_Texture *texture, - uint32_t x, - uint32_t y, - uint32_t z, - uint32_t w, - uint32_t h, - uint32_t d, - uint32_t level, - void* data, - uint32_t dataLength -) { - VulkanRenderer *renderer = (VulkanRenderer*) driverData; - VulkanTexture *vulkanTexture = (VulkanTexture*) texture; - - VkCommandBuffer commandBuffer = renderer->transferCommandBuffers[renderer->frameIndex]; - VkResult vulkanResult; - VkBufferImageCopy imageCopy; - uint8_t *mapPointer; - - SDL_LockMutex(renderer->stagingLock); - - VULKAN_INTERNAL_MaybeExpandStagingBuffer(renderer, dataLength); - VULKAN_INTERNAL_MaybeBeginTransferCommandBuffer(renderer); - - SDL_LockMutex(renderer->textureStagingBuffer->subBuffers[0]->allocation->memoryLock); - - vulkanResult = renderer->vkMapMemory( - renderer->logicalDevice, - renderer->textureStagingBuffer->subBuffers[0]->allocation->memory, - renderer->textureStagingBuffer->subBuffers[0]->offset + renderer->textureStagingBufferOffset, - renderer->textureStagingBuffer->subBuffers[0]->size, - 0, - (void**) &mapPointer - ); - - if (vulkanResult != VK_SUCCESS) - { - REFRESH_LogError("Failed to map buffer memory!"); - SDL_UnlockMutex(renderer->textureStagingBuffer->subBuffers[0]->allocation->memoryLock); - SDL_UnlockMutex(renderer->stagingLock); - return; - } - - SDL_memcpy(mapPointer, data, dataLength); - - renderer->vkUnmapMemory( - renderer->logicalDevice, - renderer->textureStagingBuffer->subBuffers[0]->allocation->memory - ); - - SDL_UnlockMutex(renderer->textureStagingBuffer->subBuffers[0]->allocation->memoryLock); - - VULKAN_INTERNAL_ImageMemoryBarrier( - renderer, - commandBuffer, - RESOURCE_ACCESS_TRANSFER_WRITE, - VK_IMAGE_ASPECT_COLOR_BIT, - 0, - vulkanTexture->layerCount, - 0, - vulkanTexture->levelCount, - 0, - vulkanTexture->image, - &vulkanTexture->resourceAccessType - ); - - imageCopy.imageExtent.width = w; - imageCopy.imageExtent.height = h; - imageCopy.imageExtent.depth = d; - imageCopy.imageOffset.x = x; - imageCopy.imageOffset.y = y; - imageCopy.imageOffset.z = z; - imageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - imageCopy.imageSubresource.baseArrayLayer = 0; - imageCopy.imageSubresource.layerCount = 1; - imageCopy.imageSubresource.mipLevel = level; - imageCopy.bufferOffset = renderer->textureStagingBufferOffset; - imageCopy.bufferRowLength = 0; - imageCopy.bufferImageHeight = 0; - - renderer->vkCmdCopyBufferToImage( - commandBuffer, - renderer->textureStagingBuffer->subBuffers[0]->buffer, - vulkanTexture->image, - AccessMap[vulkanTexture->resourceAccessType].imageLayout, - 1, - &imageCopy - ); - - renderer->textureStagingBufferOffset += dataLength; - - if (vulkanTexture->usageFlags & REFRESH_TEXTUREUSAGE_SAMPLER_BIT) - { - VULKAN_INTERNAL_ImageMemoryBarrier( - renderer, - commandBuffer, - RESOURCE_ACCESS_ANY_SHADER_READ_SAMPLED_IMAGE, - VK_IMAGE_ASPECT_COLOR_BIT, - 0, - vulkanTexture->layerCount, - 0, - vulkanTexture->levelCount, - 0, - vulkanTexture->image, - &vulkanTexture->resourceAccessType - ); - } - - SDL_UnlockMutex(renderer->stagingLock); -} - -static void VULKAN_SetTextureDataCube( - REFRESH_Renderer *driverData, - REFRESH_Texture *texture, - uint32_t x, - uint32_t y, - uint32_t w, - uint32_t h, - REFRESH_CubeMapFace cubeMapFace, - uint32_t level, - void* data, - uint32_t dataLength -) { - VulkanRenderer *renderer = (VulkanRenderer*) driverData; - VulkanTexture *vulkanTexture = (VulkanTexture*) texture; - - VkCommandBuffer commandBuffer = renderer->transferCommandBuffers[renderer->frameIndex]; - VkResult vulkanResult; - VkBufferImageCopy imageCopy; - uint8_t *mapPointer; - - SDL_LockMutex(renderer->stagingLock); - - VULKAN_INTERNAL_MaybeExpandStagingBuffer(renderer, dataLength); - VULKAN_INTERNAL_MaybeBeginTransferCommandBuffer(renderer); - - SDL_LockMutex(renderer->textureStagingBuffer->subBuffers[0]->allocation->memoryLock); - - vulkanResult = renderer->vkMapMemory( - renderer->logicalDevice, - renderer->textureStagingBuffer->subBuffers[0]->allocation->memory, - renderer->textureStagingBuffer->subBuffers[0]->offset + renderer->textureStagingBufferOffset, - renderer->textureStagingBuffer->subBuffers[0]->size, - 0, - (void**) &mapPointer - ); - - if (vulkanResult != VK_SUCCESS) - { - REFRESH_LogError("Failed to map buffer memory!"); - SDL_UnlockMutex(renderer->textureStagingBuffer->subBuffers[0]->allocation->memoryLock); - SDL_UnlockMutex(renderer->stagingLock); - return; - } - - SDL_memcpy(mapPointer, data, dataLength); - - renderer->vkUnmapMemory( - renderer->logicalDevice, - renderer->textureStagingBuffer->subBuffers[0]->allocation->memory - ); - - SDL_UnlockMutex(renderer->textureStagingBuffer->subBuffers[0]->allocation->memoryLock); - - VULKAN_INTERNAL_ImageMemoryBarrier( - renderer, - commandBuffer, - RESOURCE_ACCESS_TRANSFER_WRITE, - VK_IMAGE_ASPECT_COLOR_BIT, - 0, - vulkanTexture->layerCount, - 0, - vulkanTexture->levelCount, - 0, - vulkanTexture->image, - &vulkanTexture->resourceAccessType - ); - - imageCopy.imageExtent.width = w; - imageCopy.imageExtent.height = h; - imageCopy.imageExtent.depth = 1; - imageCopy.imageOffset.x = x; - imageCopy.imageOffset.y = y; - imageCopy.imageOffset.z = 0; - imageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - imageCopy.imageSubresource.baseArrayLayer = cubeMapFace; - imageCopy.imageSubresource.layerCount = 1; - imageCopy.imageSubresource.mipLevel = level; - imageCopy.bufferOffset = renderer->textureStagingBufferOffset; - imageCopy.bufferRowLength = 0; /* assumes tightly packed data */ - imageCopy.bufferImageHeight = 0; /* assumes tightly packed data */ - - renderer->vkCmdCopyBufferToImage( - commandBuffer, - renderer->textureStagingBuffer->subBuffers[0]->buffer, - vulkanTexture->image, - AccessMap[vulkanTexture->resourceAccessType].imageLayout, - 1, - &imageCopy - ); - - renderer->textureStagingBufferOffset += dataLength; - - if (vulkanTexture->usageFlags & REFRESH_TEXTUREUSAGE_SAMPLER_BIT) - { - VULKAN_INTERNAL_ImageMemoryBarrier( - renderer, - commandBuffer, - RESOURCE_ACCESS_ANY_SHADER_READ_SAMPLED_IMAGE, - VK_IMAGE_ASPECT_COLOR_BIT, - 0, - vulkanTexture->layerCount, - 0, - vulkanTexture->levelCount, + textureSlice->layer, + 1, + textureSlice->level, + 1, 0, vulkanTexture->image, &vulkanTexture->resourceAccessType @@ -6538,12 +6325,14 @@ static void VULKAN_INTERNAL_BlitImage( VulkanRenderer *renderer, VkCommandBuffer commandBuffer, REFRESH_Rect *sourceRectangle, + uint32_t sourceDepth, uint32_t sourceLayer, uint32_t sourceLevel, VkImage sourceImage, VulkanResourceAccessType *currentSourceAccessType, VulkanResourceAccessType nextSourceAccessType, REFRESH_Rect *destinationRectangle, + uint32_t destinationDepth, uint32_t destinationLayer, uint32_t destinationLevel, VkImage destinationImage, @@ -6583,7 +6372,7 @@ static void VULKAN_INTERNAL_BlitImage( blit.srcOffsets[0].x = sourceRectangle->x; blit.srcOffsets[0].y = sourceRectangle->y; - blit.srcOffsets[0].z = 0; + blit.srcOffsets[0].z = sourceDepth; blit.srcOffsets[1].x = sourceRectangle->x + sourceRectangle->w; blit.srcOffsets[1].y = sourceRectangle->y + sourceRectangle->h; blit.srcOffsets[1].z = 1; @@ -6595,7 +6384,7 @@ static void VULKAN_INTERNAL_BlitImage( blit.dstOffsets[0].x = destinationRectangle->x; blit.dstOffsets[0].y = destinationRectangle->y; - blit.dstOffsets[0].z = 0; + blit.dstOffsets[0].z = destinationDepth; blit.dstOffsets[1].x = destinationRectangle->x + destinationRectangle->w; blit.dstOffsets[1].y = destinationRectangle->y + destinationRectangle->h; blit.dstOffsets[1].z = 1; @@ -6650,8 +6439,6 @@ REFRESHAPI void VULKAN_CopyTextureToTexture( REFRESH_CommandBuffer *commandBuffer, REFRESH_TextureSlice *sourceTextureSlice, REFRESH_TextureSlice *destinationTextureSlice, - REFRESH_Rect *sourceRectangle, - REFRESH_Rect *destinationRectangle, REFRESH_Filter filter ) { VulkanRenderer *renderer = (VulkanRenderer*)driverData; @@ -6659,43 +6446,18 @@ REFRESHAPI void VULKAN_CopyTextureToTexture( VulkanTexture *sourceTexture = (VulkanTexture*) sourceTextureSlice->texture; VulkanTexture *destinationTexture = (VulkanTexture*) destinationTextureSlice->texture; - REFRESH_Rect srcRect; - REFRESH_Rect dstRect; - - if (sourceRectangle != NULL) - { - srcRect = *sourceRectangle; - } - else - { - srcRect.x = 0; - srcRect.y = 0; - srcRect.w = sourceTexture->dimensions.width; - srcRect.h = sourceTexture->dimensions.height; - } - - if (destinationRectangle != NULL) - { - dstRect = *destinationRectangle; - } - else - { - dstRect.x = 0; - dstRect.y = 0; - dstRect.w = destinationTexture->dimensions.width; - dstRect.h = destinationTexture->dimensions.height; - } - VULKAN_INTERNAL_BlitImage( renderer, vulkanCommandBuffer->commandBuffer, - &srcRect, + &sourceTextureSlice->rectangle, + sourceTextureSlice->depth, sourceTextureSlice->layer, sourceTextureSlice->level, sourceTexture->image, &sourceTexture->resourceAccessType, sourceTexture->resourceAccessType, - &dstRect, + &destinationTextureSlice->rectangle, + destinationTextureSlice->depth, destinationTextureSlice->layer, destinationTextureSlice->level, destinationTexture->image, @@ -7298,21 +7060,15 @@ static void VULKAN_GetBufferData( SDL_UnlockMutex(vulkanBuffer->subBuffers[vulkanBuffer->currentSubBufferIndex]->allocation->memoryLock); } -static void VULKAN_INTERNAL_CopyTextureData( +static void VULKAN_CopyTextureToBuffer( REFRESH_Renderer *driverData, REFRESH_CommandBuffer *commandBuffer, - REFRESH_Texture *texture, - int32_t x, - int32_t y, - int32_t w, - int32_t h, - int32_t level, - int32_t layer, + REFRESH_TextureSlice *textureSlice, REFRESH_Buffer *buffer ) { VulkanRenderer *renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; - VulkanTexture *vulkanTexture = (VulkanTexture*) texture; + VulkanTexture *vulkanTexture = (VulkanTexture*) textureSlice->texture; VulkanBuffer *vulkanBuffer = (VulkanBuffer*) buffer; VulkanResourceAccessType prevResourceAccess; @@ -7326,10 +7082,10 @@ static void VULKAN_INTERNAL_CopyTextureData( vulkanCommandBuffer->commandBuffer, RESOURCE_ACCESS_TRANSFER_READ, VK_IMAGE_ASPECT_COLOR_BIT, - 0, - vulkanTexture->layerCount, - 0, - vulkanTexture->levelCount, + textureSlice->layer, + 1, + textureSlice->level, + 1, 0, vulkanTexture->image, &vulkanTexture->resourceAccessType @@ -7337,18 +7093,18 @@ static void VULKAN_INTERNAL_CopyTextureData( /* Save texture data to buffer */ - imageCopy.imageExtent.width = w; - imageCopy.imageExtent.height = h; + imageCopy.imageExtent.width = textureSlice->rectangle.w; + imageCopy.imageExtent.height = textureSlice->rectangle.h; imageCopy.imageExtent.depth = 1; - imageCopy.bufferRowLength = w; - imageCopy.bufferImageHeight = h; - imageCopy.imageOffset.x = x; - imageCopy.imageOffset.y = y; - imageCopy.imageOffset.z = 0; + imageCopy.bufferRowLength = textureSlice->rectangle.w; + imageCopy.bufferImageHeight = textureSlice->rectangle.h; + imageCopy.imageOffset.x = textureSlice->rectangle.x; + imageCopy.imageOffset.y = textureSlice->rectangle.y; + imageCopy.imageOffset.z = textureSlice->depth; imageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - imageCopy.imageSubresource.baseArrayLayer = layer; + imageCopy.imageSubresource.baseArrayLayer = textureSlice->layer; imageCopy.imageSubresource.layerCount = 1; - imageCopy.imageSubresource.mipLevel = level; + imageCopy.imageSubresource.mipLevel = textureSlice->level; imageCopy.bufferOffset = 0; renderer->vkCmdCopyImageToBuffer( @@ -7367,40 +7123,16 @@ static void VULKAN_INTERNAL_CopyTextureData( vulkanCommandBuffer->commandBuffer, prevResourceAccess, VK_IMAGE_ASPECT_COLOR_BIT, - 0, - vulkanTexture->layerCount, - 0, - vulkanTexture->levelCount, + textureSlice->layer, + 1, + textureSlice->level, + 1, 0, vulkanTexture->image, &vulkanTexture->resourceAccessType ); } -static void VULKAN_CopyTextureToBuffer( - REFRESH_Renderer *driverData, - REFRESH_CommandBuffer *commandBuffer, - REFRESH_TextureSlice *textureSlice, - uint32_t x, - uint32_t y, - uint32_t w, - uint32_t h, - REFRESH_Buffer *buffer -) { - VULKAN_INTERNAL_CopyTextureData( - driverData, - commandBuffer, - textureSlice->texture, - x, - y, - w, - h, - textureSlice->level, - textureSlice->layer, - buffer - ); -} - static void VULKAN_AddDisposeTexture( REFRESH_Renderer *driverData, REFRESH_Texture *texture @@ -8162,14 +7894,12 @@ static void VULKAN_QueuePresent( REFRESH_Renderer *driverData, REFRESH_CommandBuffer *commandBuffer, REFRESH_TextureSlice *textureSlice, - REFRESH_Rect *sourceRectangle, REFRESH_Rect *destinationRectangle, REFRESH_Filter filter ) { VkResult acquireResult; uint32_t swapChainImageIndex; - REFRESH_Rect srcRect; REFRESH_Rect dstRect; VulkanRenderer* renderer = (VulkanRenderer*) driverData; @@ -8202,18 +7932,6 @@ static void VULKAN_QueuePresent( renderer->swapChainImageAcquired = 1; renderer->currentSwapChainIndex = swapChainImageIndex; - if (sourceRectangle != NULL) - { - srcRect = *sourceRectangle; - } - else - { - srcRect.x = 0; - srcRect.y = 0; - srcRect.w = vulkanTexture->dimensions.width; - srcRect.h = vulkanTexture->dimensions.height; - } - if (destinationRectangle != NULL) { dstRect = *destinationRectangle; @@ -8231,7 +7949,8 @@ static void VULKAN_QueuePresent( VULKAN_INTERNAL_BlitImage( renderer, vulkanCommandBuffer->commandBuffer, - &srcRect, + &textureSlice->rectangle, + textureSlice->depth, textureSlice->layer, textureSlice->level, vulkanTexture->image, @@ -8240,6 +7959,7 @@ static void VULKAN_QueuePresent( &dstRect, 0, 0, + 0, renderer->swapChainImages[swapChainImageIndex], &renderer->swapChainResourceAccessTypes[swapChainImageIndex], RESOURCE_ACCESS_PRESENT, @@ -8447,7 +8167,7 @@ static void VULKAN_Submit( uint32_t i; uint8_t present; - VkPipelineStageFlags waitStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + VkPipelineStageFlags waitStages[2]; VkSemaphore waitSemaphores[2]; uint32_t waitSemaphoreCount = 0; VkPresentInfoKHR presentInfo; @@ -8467,6 +8187,7 @@ static void VULKAN_Submit( transferSubmitInfo.signalSemaphoreCount = 1; waitSemaphores[waitSemaphoreCount] = renderer->transferFinishedSemaphore; + waitStages[waitSemaphoreCount] = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; waitSemaphoreCount += 1; } @@ -8489,9 +8210,10 @@ static void VULKAN_Submit( if (present) { waitSemaphores[waitSemaphoreCount] = renderer->imageAvailableSemaphore; + waitStages[waitSemaphoreCount] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; waitSemaphoreCount += 1; - submitInfo.pWaitDstStageMask = &waitStage; + submitInfo.pWaitDstStageMask = waitStages; submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = &renderer->renderFinishedSemaphore; }