From e82bce10dcdff1e96616c2fb2512e344e558c750 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Sun, 3 Jan 2021 13:01:29 -0800 Subject: [PATCH] texture copy API --- include/Refresh.h | 113 ++++++------- src/Refresh.c | 102 ++++++------ src/Refresh_Driver.h | 53 +++--- src/Refresh_Driver_Vulkan.c | 318 ++++++++++++++++++++++-------------- 4 files changed, 322 insertions(+), 264 deletions(-) diff --git a/include/Refresh.h b/include/Refresh.h index 37914d8..e802c5b 100644 --- a/include/Refresh.h +++ b/include/Refresh.h @@ -315,11 +315,12 @@ typedef enum REFRESH_ShaderStageType REFRESH_SHADERSTAGE_FRAGMENT } REFRESH_ShaderStageType; -typedef enum REFRESH_SamplerFilter +typedef enum REFRESH_Filter { - REFRESH_SAMPLERFILTER_NEAREST, - REFRESH_SAMPLERFILTER_LINEAR -} REFRESH_SamplerFilter; + REFRESH_FILTER_NEAREST, + REFRESH_FILTER_LINEAR, + REFRESH_FILTER_CUBIC +} REFRESH_Filter; typedef enum REFRESH_SamplerMipmapMode { @@ -391,6 +392,7 @@ typedef struct REFRESH_TextureSlice { REFRESH_Texture *texture; uint32_t layer; /* 0-5 for cube, or z-slice for 3D */ + uint32_t level; } REFRESH_TextureSlice; typedef struct REFRESH_PresentationParameters @@ -403,8 +405,8 @@ typedef struct REFRESH_PresentationParameters typedef struct REFRESH_SamplerStateCreateInfo { - REFRESH_SamplerFilter minFilter; - REFRESH_SamplerFilter magFilter; + REFRESH_Filter minFilter; + REFRESH_Filter magFilter; REFRESH_SamplerMipmapMode mipmapMode; REFRESH_SamplerAddressMode addressModeU; REFRESH_SamplerAddressMode addressModeV; @@ -988,6 +990,49 @@ REFRESHAPI void REFRESH_SetTextureDataYUV( uint32_t dataLength ); +/* Performs an asynchronous texture-to-texture copy. + * + * 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( + REFRESH_Device *driverData, + REFRESH_CommandBuffer *commandBuffer, + REFRESH_TextureSlice *sourceTextureSlice, + REFRESH_TextureSlice *destinationTextureSlice, + REFRESH_Rect *sourceRectangle, + REFRESH_Rect *destinationRectangle, + REFRESH_Filter filter +); + +/* Asynchronously copies image data from a texture slice into a buffer. + * + * NOTE: + * The buffer will not contain correct data until the command buffer + * 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_Buffer *buffer +); + /* Sets a region of the buffer with client data. * * NOTE: @@ -1106,58 +1151,6 @@ REFRESHAPI void REFRESH_GetBufferData( uint32_t dataLengthInBytes ); -/* Asynchronously copies image data from a 2D texture into a buffer. - * - * NOTE: - * The buffer will not contain correct data until the command buffer - * is submitted and completed. - * - * texture: The texture object being read. - * 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_CopyTextureData2D( - REFRESH_Device *device, - REFRESH_CommandBuffer *commandBuffer, - REFRESH_Texture *texture, - uint32_t x, - uint32_t y, - uint32_t w, - uint32_t h, - uint32_t level, - REFRESH_Buffer *buffer -); - -/* Asynchronously copies image data from a single face of a texture cube - * object into a buffer. You must wait for the command buffer to be - * submitted and completed before reading the buffer. - * - * texture: The texture object being read. - * 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. - * cubeMapFace: The face of the cube being read. - * level: The mipmap level being read. - * buffer: The buffer being filled with the image data. - */ -REFRESHAPI void REFRESH_CopyTextureDataCube( - REFRESH_Device *device, - REFRESH_CommandBuffer *commandBuffer, - REFRESH_Texture *texture, - uint32_t x, - uint32_t y, - uint32_t w, - uint32_t h, - REFRESH_CubeMapFace cubeMapFace, - uint32_t level, - REFRESH_Buffer *buffer -); - /* Disposal */ /* Sends a texture to be destroyed by the renderer. Note that we call it @@ -1401,13 +1394,15 @@ REFRESHAPI REFRESH_CommandBuffer* REFRESH_AcquireCommandBuffer( * 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). + * 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_Rect *destinationRectangle, + REFRESH_Filter filter ); /* Submits all of the enqueued commands. */ diff --git a/src/Refresh.c b/src/Refresh.c index 75a2d8c..a5b8af1 100644 --- a/src/Refresh.c +++ b/src/Refresh.c @@ -540,6 +540,50 @@ void REFRESH_SetTextureDataYUV( ); } +void REFRESH_CopyTextureToTexture( + REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, + REFRESH_TextureSlice *sourceTextureSlice, + REFRESH_TextureSlice *destinationTextureSlice, + REFRESH_Rect *sourceRectangle, + REFRESH_Rect *destinationRectangle, + REFRESH_Filter filter +) { + NULL_RETURN(device); + device->CopyTextureToTexture( + device->driverData, + commandBuffer, + sourceTextureSlice, + destinationTextureSlice, + sourceRectangle, + destinationRectangle, + filter + ); +} + +void REFRESH_CopyTextureToBuffer( + REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, + REFRESH_TextureSlice *textureSlice, + uint32_t x, + uint32_t y, + uint32_t w, + uint32_t h, + REFRESH_Buffer* buffer +) { + NULL_RETURN(device); + device->CopyTextureToBuffer( + device->driverData, + commandBuffer, + textureSlice, + x, + y, + w, + h, + buffer + ); +} + void REFRESH_SetBufferData( REFRESH_Device *device, REFRESH_Buffer *buffer, @@ -647,58 +691,6 @@ void REFRESH_GetBufferData( ); } -void REFRESH_CopyTextureData2D( - REFRESH_Device *device, - REFRESH_CommandBuffer *commandBuffer, - REFRESH_Texture *texture, - uint32_t x, - uint32_t y, - uint32_t w, - uint32_t h, - uint32_t level, - REFRESH_Buffer* buffer -) { - NULL_RETURN(device); - device->CopyTextureData2D( - device->driverData, - commandBuffer, - texture, - x, - y, - w, - h, - level, - buffer - ); -} - -void REFRESH_GetTextureDataCube( - REFRESH_Device *device, - REFRESH_CommandBuffer *commandBuffer, - REFRESH_Texture *texture, - uint32_t x, - uint32_t y, - uint32_t w, - uint32_t h, - REFRESH_CubeMapFace cubeMapFace, - uint32_t level, - REFRESH_Buffer* buffer -) { - NULL_RETURN(device); - device->CopyTextureDataCube( - device->driverData, - commandBuffer, - texture, - x, - y, - w, - h, - cubeMapFace, - level, - buffer - ); -} - void REFRESH_AddDisposeTexture( REFRESH_Device *device, REFRESH_Texture *texture @@ -947,7 +939,8 @@ void REFRESH_QueuePresent( REFRESH_CommandBuffer *commandBuffer, REFRESH_TextureSlice* textureSlice, REFRESH_Rect *sourceRectangle, - REFRESH_Rect *destinationRectangle + REFRESH_Rect *destinationRectangle, + REFRESH_Filter filter ) { NULL_RETURN(device); device->QueuePresent( @@ -955,7 +948,8 @@ void REFRESH_QueuePresent( commandBuffer, textureSlice, sourceRectangle, - destinationRectangle + destinationRectangle, + filter ); } diff --git a/src/Refresh_Driver.h b/src/Refresh_Driver.h index 2796037..aa181eb 100644 --- a/src/Refresh_Driver.h +++ b/src/Refresh_Driver.h @@ -357,6 +357,27 @@ struct REFRESH_Device uint32_t dataLength ); + void(*CopyTextureToTexture)( + REFRESH_Renderer *driverData, + REFRESH_CommandBuffer *commandBuffer, + REFRESH_TextureSlice *sourceTextureSlice, + REFRESH_TextureSlice *destinationTexture, + REFRESH_Rect *sourceRectangle, + REFRESH_Rect *destinationRectangle, + REFRESH_Filter filter + ); + + void(*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 + ); + void(*SetBufferData)( REFRESH_Renderer *driverData, REFRESH_Buffer *buffer, @@ -409,31 +430,6 @@ struct REFRESH_Device uint32_t dataLengthInBytes ); - void(*CopyTextureData2D)( - REFRESH_Renderer *driverData, - REFRESH_CommandBuffer *commandBuffer, - REFRESH_Texture *texture, - uint32_t x, - uint32_t y, - uint32_t w, - uint32_t h, - uint32_t level, - REFRESH_Buffer* buffer - ); - - void(*CopyTextureDataCube)( - REFRESH_Renderer *driverData, - REFRESH_CommandBuffer *commandBuffer, - REFRESH_Texture *texture, - uint32_t x, - uint32_t y, - uint32_t w, - uint32_t h, - REFRESH_CubeMapFace cubeMapFace, - uint32_t level, - REFRESH_Buffer* buffer - ); - /* Disposal */ void(*AddDisposeTexture)( @@ -555,7 +551,8 @@ struct REFRESH_Device REFRESH_CommandBuffer *commandBuffer, REFRESH_TextureSlice *textureSlice, REFRESH_Rect *sourceRectangle, - REFRESH_Rect *destinationRectangle + REFRESH_Rect *destinationRectangle, + REFRESH_Filter filter ); void(*Submit)( @@ -597,6 +594,8 @@ struct REFRESH_Device ASSIGN_DRIVER_FUNC(SetTextureData3D, name) \ ASSIGN_DRIVER_FUNC(SetTextureDataCube, name) \ ASSIGN_DRIVER_FUNC(SetTextureDataYUV, name) \ + ASSIGN_DRIVER_FUNC(CopyTextureToTexture, name) \ + ASSIGN_DRIVER_FUNC(CopyTextureToBuffer, name) \ ASSIGN_DRIVER_FUNC(SetBufferData, name) \ ASSIGN_DRIVER_FUNC(PushVertexShaderParams, name) \ ASSIGN_DRIVER_FUNC(PushFragmentShaderParams, name) \ @@ -604,8 +603,6 @@ struct REFRESH_Device ASSIGN_DRIVER_FUNC(SetVertexSamplers, name) \ ASSIGN_DRIVER_FUNC(SetFragmentSamplers, name) \ ASSIGN_DRIVER_FUNC(GetBufferData, name) \ - ASSIGN_DRIVER_FUNC(CopyTextureData2D, name) \ - ASSIGN_DRIVER_FUNC(CopyTextureDataCube, name) \ ASSIGN_DRIVER_FUNC(AddDisposeTexture, name) \ ASSIGN_DRIVER_FUNC(AddDisposeSampler, name) \ ASSIGN_DRIVER_FUNC(AddDisposeBuffer, name) \ diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 6f6a79a..db6b37c 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -367,10 +367,11 @@ static VkVertexInputRate RefreshToVK_VertexInputRate[] = VK_VERTEX_INPUT_RATE_INSTANCE }; -static VkFilter RefreshToVK_SamplerFilter[] = +static VkFilter RefreshToVK_Filter[] = { VK_FILTER_NEAREST, - VK_FILTER_LINEAR + VK_FILTER_LINEAR, + VK_FILTER_CUBIC_EXT }; static VkSamplerMipmapMode RefreshToVK_SamplerMipmapMode[] = @@ -5221,10 +5222,10 @@ static REFRESH_Sampler* VULKAN_CreateSampler( vkSamplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; vkSamplerCreateInfo.pNext = NULL; vkSamplerCreateInfo.flags = 0; - vkSamplerCreateInfo.magFilter = RefreshToVK_SamplerFilter[ + vkSamplerCreateInfo.magFilter = RefreshToVK_Filter[ samplerStateCreateInfo->magFilter ]; - vkSamplerCreateInfo.minFilter = RefreshToVK_SamplerFilter[ + vkSamplerCreateInfo.minFilter = RefreshToVK_Filter[ samplerStateCreateInfo->minFilter ]; vkSamplerCreateInfo.mipmapMode = RefreshToVK_SamplerMipmapMode[ @@ -6478,6 +6479,177 @@ static void VULKAN_SetTextureDataYUV( } } +static void VULKAN_INTERNAL_BlitImage( + VulkanRenderer *renderer, + VkCommandBuffer commandBuffer, + REFRESH_Rect *sourceRectangle, + uint32_t sourceLayer, + uint32_t sourceLevel, + VkImage sourceImage, + VulkanResourceAccessType *currentSourceAccessType, + VulkanResourceAccessType nextSourceAccessType, + REFRESH_Rect *destinationRectangle, + uint32_t destinationLayer, + uint32_t destinationLevel, + VkImage destinationImage, + VulkanResourceAccessType *currentDestinationAccessType, + VulkanResourceAccessType nextDestinationAccessType, + VkFilter filter +) { + VkImageBlit blit; + + VULKAN_INTERNAL_ImageMemoryBarrier( + renderer, + commandBuffer, + RESOURCE_ACCESS_TRANSFER_READ, + VK_IMAGE_ASPECT_COLOR_BIT, + sourceLayer, + 1, + sourceLevel, + 1, + 0, + sourceImage, + currentSourceAccessType + ); + + VULKAN_INTERNAL_ImageMemoryBarrier( + renderer, + commandBuffer, + RESOURCE_ACCESS_TRANSFER_WRITE, + VK_IMAGE_ASPECT_COLOR_BIT, + destinationLayer, + 1, + destinationLevel, + 1, + 0, + destinationImage, + currentDestinationAccessType + ); + + blit.srcOffsets[0].x = sourceRectangle->x; + blit.srcOffsets[0].y = sourceRectangle->y; + blit.srcOffsets[0].z = 0; + blit.srcOffsets[1].x = sourceRectangle->x + sourceRectangle->w; + blit.srcOffsets[1].y = sourceRectangle->y + sourceRectangle->h; + blit.srcOffsets[1].z = 1; + + blit.srcSubresource.mipLevel = sourceLevel; + blit.srcSubresource.baseArrayLayer = sourceLayer; + blit.srcSubresource.layerCount = 1; + blit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + + blit.dstOffsets[0].x = destinationRectangle->x; + blit.dstOffsets[0].y = destinationRectangle->y; + blit.dstOffsets[0].z = 0; + blit.dstOffsets[1].x = destinationRectangle->x + destinationRectangle->w; + blit.dstOffsets[1].y = destinationRectangle->y + destinationRectangle->h; + blit.dstOffsets[1].z = 1; + + blit.dstSubresource.mipLevel = destinationLevel; + blit.dstSubresource.baseArrayLayer = destinationLayer; + blit.dstSubresource.layerCount = 1; + blit.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + + renderer->vkCmdBlitImage( + commandBuffer, + sourceImage, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + destinationImage, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 1, + &blit, + filter + ); + + VULKAN_INTERNAL_ImageMemoryBarrier( + renderer, + commandBuffer, + nextSourceAccessType, + VK_IMAGE_ASPECT_COLOR_BIT, + sourceLayer, + 1, + sourceLevel, + 1, + 0, + sourceImage, + currentSourceAccessType + ); + + VULKAN_INTERNAL_ImageMemoryBarrier( + renderer, + commandBuffer, + nextDestinationAccessType, + VK_IMAGE_ASPECT_COLOR_BIT, + destinationLayer, + 1, + destinationLevel, + 1, + 0, + destinationImage, + currentDestinationAccessType + ); +} + +REFRESHAPI void VULKAN_CopyTextureToTexture( + REFRESH_Renderer *driverData, + REFRESH_CommandBuffer *commandBuffer, + REFRESH_TextureSlice *sourceTextureSlice, + REFRESH_TextureSlice *destinationTextureSlice, + REFRESH_Rect *sourceRectangle, + REFRESH_Rect *destinationRectangle, + REFRESH_Filter filter +) { + VulkanRenderer *renderer = (VulkanRenderer*)driverData; + VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; + 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->layer, + sourceTextureSlice->level, + sourceTexture->image, + &sourceTexture->resourceAccessType, + sourceTexture->resourceAccessType, + &dstRect, + destinationTextureSlice->layer, + destinationTextureSlice->level, + destinationTexture->image, + &destinationTexture->resourceAccessType, + destinationTexture->resourceAccessType, + RefreshToVK_Filter[filter] + ); +} + static void VULKAN_SetBufferData( REFRESH_Renderer *driverData, REFRESH_Buffer *buffer, @@ -7141,53 +7313,26 @@ static void VULKAN_INTERNAL_CopyTextureData( ); } -static void VULKAN_CopyTextureData2D( +static void VULKAN_CopyTextureToBuffer( REFRESH_Renderer *driverData, REFRESH_CommandBuffer *commandBuffer, - REFRESH_Texture *texture, + REFRESH_TextureSlice *textureSlice, uint32_t x, uint32_t y, uint32_t w, uint32_t h, - uint32_t level, REFRESH_Buffer *buffer ) { VULKAN_INTERNAL_CopyTextureData( driverData, commandBuffer, - texture, + textureSlice->texture, x, y, w, h, - level, - 0, - buffer - ); -} - -static void VULKAN_CopyTextureDataCube( - REFRESH_Renderer *driverData, - REFRESH_CommandBuffer *commandBuffer, - REFRESH_Texture *texture, - uint32_t x, - uint32_t y, - uint32_t w, - uint32_t h, - REFRESH_CubeMapFace cubeMapFace, - uint32_t level, - REFRESH_Buffer *buffer -) { - VULKAN_INTERNAL_CopyTextureData( - driverData, - commandBuffer, - texture, - x, - y, - w, - h, - level, - cubeMapFace, + textureSlice->level, + textureSlice->layer, buffer ); } @@ -7952,16 +8097,16 @@ static REFRESH_CommandBuffer* VULKAN_AcquireCommandBuffer( static void VULKAN_QueuePresent( REFRESH_Renderer *driverData, REFRESH_CommandBuffer *commandBuffer, - REFRESH_TextureSlice* textureSlice, - REFRESH_Rect* sourceRectangle, - REFRESH_Rect* destinationRectangle + REFRESH_TextureSlice *textureSlice, + REFRESH_Rect *sourceRectangle, + REFRESH_Rect *destinationRectangle, + REFRESH_Filter filter ) { VkResult acquireResult; uint32_t swapChainImageIndex; REFRESH_Rect srcRect; REFRESH_Rect dstRect; - VkImageBlit blit; VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; @@ -8017,97 +8162,24 @@ static void VULKAN_QueuePresent( dstRect.h = renderer->swapChainExtent.height; } - /* Blit the framebuffer! */ + /* Blit! */ - VULKAN_INTERNAL_ImageMemoryBarrier( + VULKAN_INTERNAL_BlitImage( renderer, vulkanCommandBuffer->commandBuffer, - RESOURCE_ACCESS_TRANSFER_READ, - VK_IMAGE_ASPECT_COLOR_BIT, - 0, - 1, - 0, - 1, - 0, + &srcRect, + textureSlice->layer, + textureSlice->level, vulkanTexture->image, - &vulkanTexture->resourceAccessType - ); - - VULKAN_INTERNAL_ImageMemoryBarrier( - renderer, - vulkanCommandBuffer->commandBuffer, - RESOURCE_ACCESS_TRANSFER_WRITE, - VK_IMAGE_ASPECT_COLOR_BIT, + &vulkanTexture->resourceAccessType, + vulkanTexture->resourceAccessType, + &dstRect, 0, - 1, - 0, - 1, 0, renderer->swapChainImages[swapChainImageIndex], - &renderer->swapChainResourceAccessTypes[swapChainImageIndex] - ); - - blit.srcOffsets[0].x = srcRect.x; - blit.srcOffsets[0].y = srcRect.y; - blit.srcOffsets[0].z = 0; - blit.srcOffsets[1].x = srcRect.x + srcRect.w; - blit.srcOffsets[1].y = srcRect.y + srcRect.h; - blit.srcOffsets[1].z = 1; - - blit.srcSubresource.mipLevel = 0; - blit.srcSubresource.baseArrayLayer = 0; - blit.srcSubresource.layerCount = 1; - blit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - - blit.dstOffsets[0].x = dstRect.x; - blit.dstOffsets[0].y = dstRect.y; - blit.dstOffsets[0].z = 0; - blit.dstOffsets[1].x = dstRect.x + dstRect.w; - blit.dstOffsets[1].y = dstRect.y + dstRect.h; - blit.dstOffsets[1].z = 1; - - blit.dstSubresource.mipLevel = 0; - blit.dstSubresource.baseArrayLayer = textureSlice->layer; - blit.dstSubresource.layerCount = 1; - blit.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - - renderer->vkCmdBlitImage( - vulkanCommandBuffer->commandBuffer, - vulkanTexture->image, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - renderer->swapChainImages[swapChainImageIndex], - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - 1, - &blit, - VK_FILTER_LINEAR - ); - - VULKAN_INTERNAL_ImageMemoryBarrier( - renderer, - vulkanCommandBuffer->commandBuffer, + &renderer->swapChainResourceAccessTypes[swapChainImageIndex], RESOURCE_ACCESS_PRESENT, - VK_IMAGE_ASPECT_COLOR_BIT, - 0, - 1, - 0, - 1, - 0, - renderer->swapChainImages[swapChainImageIndex], - &renderer->swapChainResourceAccessTypes[swapChainImageIndex] - ); - - VULKAN_INTERNAL_ImageMemoryBarrier( - renderer, - vulkanCommandBuffer->commandBuffer, - RESOURCE_ACCESS_COLOR_ATTACHMENT_READ_WRITE, - VK_IMAGE_ASPECT_COLOR_BIT, - 0, - 1, - 0, - 1, - 0, - vulkanTexture->image, - &vulkanTexture->resourceAccessType + RefreshToVK_Filter[filter] ); }