texture copy API

pull/9/head
cosmonaut 2021-01-03 13:01:29 -08:00 committed by thatcosmonaut
parent 087a60fa52
commit e82bce10dc
4 changed files with 322 additions and 264 deletions

View File

@ -315,11 +315,12 @@ typedef enum REFRESH_ShaderStageType
REFRESH_SHADERSTAGE_FRAGMENT REFRESH_SHADERSTAGE_FRAGMENT
} REFRESH_ShaderStageType; } REFRESH_ShaderStageType;
typedef enum REFRESH_SamplerFilter typedef enum REFRESH_Filter
{ {
REFRESH_SAMPLERFILTER_NEAREST, REFRESH_FILTER_NEAREST,
REFRESH_SAMPLERFILTER_LINEAR REFRESH_FILTER_LINEAR,
} REFRESH_SamplerFilter; REFRESH_FILTER_CUBIC
} REFRESH_Filter;
typedef enum REFRESH_SamplerMipmapMode typedef enum REFRESH_SamplerMipmapMode
{ {
@ -391,6 +392,7 @@ typedef struct REFRESH_TextureSlice
{ {
REFRESH_Texture *texture; REFRESH_Texture *texture;
uint32_t layer; /* 0-5 for cube, or z-slice for 3D */ uint32_t layer; /* 0-5 for cube, or z-slice for 3D */
uint32_t level;
} REFRESH_TextureSlice; } REFRESH_TextureSlice;
typedef struct REFRESH_PresentationParameters typedef struct REFRESH_PresentationParameters
@ -403,8 +405,8 @@ typedef struct REFRESH_PresentationParameters
typedef struct REFRESH_SamplerStateCreateInfo typedef struct REFRESH_SamplerStateCreateInfo
{ {
REFRESH_SamplerFilter minFilter; REFRESH_Filter minFilter;
REFRESH_SamplerFilter magFilter; REFRESH_Filter magFilter;
REFRESH_SamplerMipmapMode mipmapMode; REFRESH_SamplerMipmapMode mipmapMode;
REFRESH_SamplerAddressMode addressModeU; REFRESH_SamplerAddressMode addressModeU;
REFRESH_SamplerAddressMode addressModeV; REFRESH_SamplerAddressMode addressModeV;
@ -988,6 +990,49 @@ REFRESHAPI void REFRESH_SetTextureDataYUV(
uint32_t dataLength 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. /* Sets a region of the buffer with client data.
* *
* NOTE: * NOTE:
@ -1106,58 +1151,6 @@ REFRESHAPI void REFRESH_GetBufferData(
uint32_t dataLengthInBytes 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 */ /* Disposal */
/* Sends a texture to be destroyed by the renderer. Note that we call it /* 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. * textureSlice: The texture slice to present.
* sourceRectangle: The region of the image to present (or NULL). * 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 (or NULL).
* filter: The filter to use if scaling is required.
*/ */
REFRESHAPI void REFRESH_QueuePresent( REFRESHAPI void REFRESH_QueuePresent(
REFRESH_Device *device, REFRESH_Device *device,
REFRESH_CommandBuffer *commandBuffer, REFRESH_CommandBuffer *commandBuffer,
REFRESH_TextureSlice *textureSlice, REFRESH_TextureSlice *textureSlice,
REFRESH_Rect *sourceRectangle, REFRESH_Rect *sourceRectangle,
REFRESH_Rect *destinationRectangle REFRESH_Rect *destinationRectangle,
REFRESH_Filter filter
); );
/* Submits all of the enqueued commands. */ /* Submits all of the enqueued commands. */

View File

@ -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( void REFRESH_SetBufferData(
REFRESH_Device *device, REFRESH_Device *device,
REFRESH_Buffer *buffer, 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( void REFRESH_AddDisposeTexture(
REFRESH_Device *device, REFRESH_Device *device,
REFRESH_Texture *texture REFRESH_Texture *texture
@ -947,7 +939,8 @@ void REFRESH_QueuePresent(
REFRESH_CommandBuffer *commandBuffer, REFRESH_CommandBuffer *commandBuffer,
REFRESH_TextureSlice* textureSlice, REFRESH_TextureSlice* textureSlice,
REFRESH_Rect *sourceRectangle, REFRESH_Rect *sourceRectangle,
REFRESH_Rect *destinationRectangle REFRESH_Rect *destinationRectangle,
REFRESH_Filter filter
) { ) {
NULL_RETURN(device); NULL_RETURN(device);
device->QueuePresent( device->QueuePresent(
@ -955,7 +948,8 @@ void REFRESH_QueuePresent(
commandBuffer, commandBuffer,
textureSlice, textureSlice,
sourceRectangle, sourceRectangle,
destinationRectangle destinationRectangle,
filter
); );
} }

View File

@ -357,6 +357,27 @@ struct REFRESH_Device
uint32_t dataLength 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)( void(*SetBufferData)(
REFRESH_Renderer *driverData, REFRESH_Renderer *driverData,
REFRESH_Buffer *buffer, REFRESH_Buffer *buffer,
@ -409,31 +430,6 @@ struct REFRESH_Device
uint32_t dataLengthInBytes 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 */ /* Disposal */
void(*AddDisposeTexture)( void(*AddDisposeTexture)(
@ -555,7 +551,8 @@ struct REFRESH_Device
REFRESH_CommandBuffer *commandBuffer, REFRESH_CommandBuffer *commandBuffer,
REFRESH_TextureSlice *textureSlice, REFRESH_TextureSlice *textureSlice,
REFRESH_Rect *sourceRectangle, REFRESH_Rect *sourceRectangle,
REFRESH_Rect *destinationRectangle REFRESH_Rect *destinationRectangle,
REFRESH_Filter filter
); );
void(*Submit)( void(*Submit)(
@ -597,6 +594,8 @@ struct REFRESH_Device
ASSIGN_DRIVER_FUNC(SetTextureData3D, name) \ ASSIGN_DRIVER_FUNC(SetTextureData3D, name) \
ASSIGN_DRIVER_FUNC(SetTextureDataCube, name) \ ASSIGN_DRIVER_FUNC(SetTextureDataCube, name) \
ASSIGN_DRIVER_FUNC(SetTextureDataYUV, name) \ ASSIGN_DRIVER_FUNC(SetTextureDataYUV, name) \
ASSIGN_DRIVER_FUNC(CopyTextureToTexture, name) \
ASSIGN_DRIVER_FUNC(CopyTextureToBuffer, name) \
ASSIGN_DRIVER_FUNC(SetBufferData, name) \ ASSIGN_DRIVER_FUNC(SetBufferData, name) \
ASSIGN_DRIVER_FUNC(PushVertexShaderParams, name) \ ASSIGN_DRIVER_FUNC(PushVertexShaderParams, name) \
ASSIGN_DRIVER_FUNC(PushFragmentShaderParams, name) \ ASSIGN_DRIVER_FUNC(PushFragmentShaderParams, name) \
@ -604,8 +603,6 @@ struct REFRESH_Device
ASSIGN_DRIVER_FUNC(SetVertexSamplers, name) \ ASSIGN_DRIVER_FUNC(SetVertexSamplers, name) \
ASSIGN_DRIVER_FUNC(SetFragmentSamplers, name) \ ASSIGN_DRIVER_FUNC(SetFragmentSamplers, name) \
ASSIGN_DRIVER_FUNC(GetBufferData, name) \ ASSIGN_DRIVER_FUNC(GetBufferData, name) \
ASSIGN_DRIVER_FUNC(CopyTextureData2D, 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(AddDisposeBuffer, name) \ ASSIGN_DRIVER_FUNC(AddDisposeBuffer, name) \

View File

@ -367,10 +367,11 @@ static VkVertexInputRate RefreshToVK_VertexInputRate[] =
VK_VERTEX_INPUT_RATE_INSTANCE VK_VERTEX_INPUT_RATE_INSTANCE
}; };
static VkFilter RefreshToVK_SamplerFilter[] = static VkFilter RefreshToVK_Filter[] =
{ {
VK_FILTER_NEAREST, VK_FILTER_NEAREST,
VK_FILTER_LINEAR VK_FILTER_LINEAR,
VK_FILTER_CUBIC_EXT
}; };
static VkSamplerMipmapMode RefreshToVK_SamplerMipmapMode[] = static VkSamplerMipmapMode RefreshToVK_SamplerMipmapMode[] =
@ -5221,10 +5222,10 @@ static REFRESH_Sampler* VULKAN_CreateSampler(
vkSamplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; vkSamplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
vkSamplerCreateInfo.pNext = NULL; vkSamplerCreateInfo.pNext = NULL;
vkSamplerCreateInfo.flags = 0; vkSamplerCreateInfo.flags = 0;
vkSamplerCreateInfo.magFilter = RefreshToVK_SamplerFilter[ vkSamplerCreateInfo.magFilter = RefreshToVK_Filter[
samplerStateCreateInfo->magFilter samplerStateCreateInfo->magFilter
]; ];
vkSamplerCreateInfo.minFilter = RefreshToVK_SamplerFilter[ vkSamplerCreateInfo.minFilter = RefreshToVK_Filter[
samplerStateCreateInfo->minFilter samplerStateCreateInfo->minFilter
]; ];
vkSamplerCreateInfo.mipmapMode = RefreshToVK_SamplerMipmapMode[ 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( static void VULKAN_SetBufferData(
REFRESH_Renderer *driverData, REFRESH_Renderer *driverData,
REFRESH_Buffer *buffer, REFRESH_Buffer *buffer,
@ -7141,53 +7313,26 @@ static void VULKAN_INTERNAL_CopyTextureData(
); );
} }
static void VULKAN_CopyTextureData2D( static void VULKAN_CopyTextureToBuffer(
REFRESH_Renderer *driverData, REFRESH_Renderer *driverData,
REFRESH_CommandBuffer *commandBuffer, REFRESH_CommandBuffer *commandBuffer,
REFRESH_Texture *texture, REFRESH_TextureSlice *textureSlice,
uint32_t x, uint32_t x,
uint32_t y, uint32_t y,
uint32_t w, uint32_t w,
uint32_t h, uint32_t h,
uint32_t level,
REFRESH_Buffer *buffer REFRESH_Buffer *buffer
) { ) {
VULKAN_INTERNAL_CopyTextureData( VULKAN_INTERNAL_CopyTextureData(
driverData, driverData,
commandBuffer, commandBuffer,
texture, textureSlice->texture,
x, x,
y, y,
w, w,
h, h,
level, textureSlice->level,
0, textureSlice->layer,
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,
buffer buffer
); );
} }
@ -7954,14 +8099,14 @@ static void VULKAN_QueuePresent(
REFRESH_CommandBuffer *commandBuffer, REFRESH_CommandBuffer *commandBuffer,
REFRESH_TextureSlice *textureSlice, REFRESH_TextureSlice *textureSlice,
REFRESH_Rect *sourceRectangle, REFRESH_Rect *sourceRectangle,
REFRESH_Rect* destinationRectangle REFRESH_Rect *destinationRectangle,
REFRESH_Filter filter
) { ) {
VkResult acquireResult; VkResult acquireResult;
uint32_t swapChainImageIndex; uint32_t swapChainImageIndex;
REFRESH_Rect srcRect; REFRESH_Rect srcRect;
REFRESH_Rect dstRect; REFRESH_Rect dstRect;
VkImageBlit blit;
VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanRenderer* renderer = (VulkanRenderer*) driverData;
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
@ -8017,97 +8162,24 @@ static void VULKAN_QueuePresent(
dstRect.h = renderer->swapChainExtent.height; dstRect.h = renderer->swapChainExtent.height;
} }
/* Blit the framebuffer! */ /* Blit! */
VULKAN_INTERNAL_ImageMemoryBarrier( VULKAN_INTERNAL_BlitImage(
renderer, renderer,
vulkanCommandBuffer->commandBuffer, vulkanCommandBuffer->commandBuffer,
RESOURCE_ACCESS_TRANSFER_READ, &srcRect,
VK_IMAGE_ASPECT_COLOR_BIT, textureSlice->layer,
0, textureSlice->level,
1,
0,
1,
0,
vulkanTexture->image, vulkanTexture->image,
&vulkanTexture->resourceAccessType &vulkanTexture->resourceAccessType,
); vulkanTexture->resourceAccessType,
&dstRect,
VULKAN_INTERNAL_ImageMemoryBarrier(
renderer,
vulkanCommandBuffer->commandBuffer,
RESOURCE_ACCESS_TRANSFER_WRITE,
VK_IMAGE_ASPECT_COLOR_BIT,
0, 0,
1,
0,
1,
0, 0,
renderer->swapChainImages[swapChainImageIndex], renderer->swapChainImages[swapChainImageIndex],
&renderer->swapChainResourceAccessTypes[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,
RESOURCE_ACCESS_PRESENT, RESOURCE_ACCESS_PRESENT,
VK_IMAGE_ASPECT_COLOR_BIT, RefreshToVK_Filter[filter]
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
); );
} }