Texture API Refactor (#9)

pull/1/head
thatcosmonaut 2021-01-03 14:37:02 -08:00 committed by GitHub
parent 3066fce16b
commit b4dee16f80
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 97 additions and 571 deletions

View File

@ -391,7 +391,9 @@ typedef struct REFRESH_Viewport
typedef struct REFRESH_TextureSlice typedef struct REFRESH_TextureSlice
{ {
REFRESH_Texture *texture; 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; uint32_t level;
} REFRESH_TextureSlice; } REFRESH_TextureSlice;
@ -890,81 +892,19 @@ REFRESHAPI REFRESH_Buffer* REFRESH_CreateBuffer(
/* Setters */ /* Setters */
/* Uploads image data to a 2D texture object. /* Uploads image data to a texture object.
* *
* texture: The texture to be updated. * textureSlice: The texture slice 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. * data: A pointer to the image data.
* dataLength: The size of the image data in bytes. * dataLengthInBytes: The size of the image data.
*/ */
REFRESHAPI void REFRESH_SetTextureData2D( REFRESHAPI void REFRESH_SetTextureData(
REFRESH_Device *driverData, REFRESH_Device *driverData,
REFRESH_Texture *texture, REFRESH_TextureSlice *textureSlice,
uint32_t x,
uint32_t y,
uint32_t w,
uint32_t h,
uint32_t level,
void *data, void *data,
uint32_t dataLengthInBytes 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. /* Uploads YUV image data to three R8 texture objects.
* *
* y: The texture storing the Y data. * y: The texture storing the Y data.
@ -994,8 +934,6 @@ REFRESHAPI void REFRESH_SetTextureDataYUV(
* *
* sourceTextureSlice: The texture slice from which to copy. * sourceTextureSlice: The texture slice from which to copy.
* destinationTextureSlice: The texture slice to copy to. * 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. * filter: The filter that will be used if the copy requires scaling.
*/ */
REFRESHAPI void REFRESH_CopyTextureToTexture( REFRESHAPI void REFRESH_CopyTextureToTexture(
@ -1003,8 +941,6 @@ REFRESHAPI void REFRESH_CopyTextureToTexture(
REFRESH_CommandBuffer *commandBuffer, REFRESH_CommandBuffer *commandBuffer,
REFRESH_TextureSlice *sourceTextureSlice, REFRESH_TextureSlice *sourceTextureSlice,
REFRESH_TextureSlice *destinationTextureSlice, REFRESH_TextureSlice *destinationTextureSlice,
REFRESH_Rect *sourceRectangle,
REFRESH_Rect *destinationRectangle,
REFRESH_Filter filter REFRESH_Filter filter
); );
@ -1015,21 +951,12 @@ REFRESHAPI void REFRESH_CopyTextureToTexture(
* is submitted and completed. * is submitted and completed.
* *
* textureSlice: The texture object being copied. * 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. * buffer: The buffer being filled with the image data.
*/ */
REFRESHAPI void REFRESH_CopyTextureToBuffer( REFRESHAPI void REFRESH_CopyTextureToBuffer(
REFRESH_Device *device, REFRESH_Device *device,
REFRESH_CommandBuffer *commandBuffer, REFRESH_CommandBuffer *commandBuffer,
REFRESH_TextureSlice *texture, REFRESH_TextureSlice *textureSlice,
uint32_t x,
uint32_t y,
uint32_t w,
uint32_t h,
REFRESH_Buffer *buffer REFRESH_Buffer *buffer
); );
@ -1392,15 +1319,13 @@ REFRESHAPI REFRESH_CommandBuffer* REFRESH_AcquireCommandBuffer(
* It is an error to call this function in headless mode. * It is an error to call this function in headless mode.
* *
* textureSlice: The texture slice to present. * textureSlice: The texture slice to present.
* sourceRectangle: The region of the image to present (or NULL). * destinationRectangle: The region of the window to update. Can be NULL.
* destinationRectangle: The region of the window to update (or NULL).
* filter: The filter to use if scaling is required. * 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 *destinationRectangle, REFRESH_Rect *destinationRectangle,
REFRESH_Filter filter REFRESH_Filter filter
); );

View File

@ -432,87 +432,21 @@ REFRESH_Buffer* REFRESH_CreateBuffer(
); );
} }
void REFRESH_SetTextureData2D( void REFRESH_SetTextureData(
REFRESH_Device *device, REFRESH_Device *device,
REFRESH_Texture *texture, REFRESH_TextureSlice *textureSlice,
uint32_t x,
uint32_t y,
uint32_t w,
uint32_t h,
uint32_t level,
void *data, void *data,
uint32_t dataLengthInBytes uint32_t dataLengthInBytes
) { ) {
NULL_RETURN(device); NULL_RETURN(device);
device->SetTextureData2D( device->SetTextureData(
device->driverData, device->driverData,
texture, textureSlice,
x,
y,
w,
h,
level,
data, data,
dataLengthInBytes 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( void REFRESH_SetTextureDataYUV(
REFRESH_Device *device, REFRESH_Device *device,
REFRESH_Texture *y, REFRESH_Texture *y,
@ -545,8 +479,6 @@ void REFRESH_CopyTextureToTexture(
REFRESH_CommandBuffer *commandBuffer, REFRESH_CommandBuffer *commandBuffer,
REFRESH_TextureSlice *sourceTextureSlice, REFRESH_TextureSlice *sourceTextureSlice,
REFRESH_TextureSlice *destinationTextureSlice, REFRESH_TextureSlice *destinationTextureSlice,
REFRESH_Rect *sourceRectangle,
REFRESH_Rect *destinationRectangle,
REFRESH_Filter filter REFRESH_Filter filter
) { ) {
NULL_RETURN(device); NULL_RETURN(device);
@ -555,8 +487,6 @@ void REFRESH_CopyTextureToTexture(
commandBuffer, commandBuffer,
sourceTextureSlice, sourceTextureSlice,
destinationTextureSlice, destinationTextureSlice,
sourceRectangle,
destinationRectangle,
filter filter
); );
} }
@ -565,10 +495,6 @@ void REFRESH_CopyTextureToBuffer(
REFRESH_Device *device, REFRESH_Device *device,
REFRESH_CommandBuffer *commandBuffer, REFRESH_CommandBuffer *commandBuffer,
REFRESH_TextureSlice *textureSlice, REFRESH_TextureSlice *textureSlice,
uint32_t x,
uint32_t y,
uint32_t w,
uint32_t h,
REFRESH_Buffer *buffer REFRESH_Buffer *buffer
) { ) {
NULL_RETURN(device); NULL_RETURN(device);
@ -576,10 +502,6 @@ void REFRESH_CopyTextureToBuffer(
device->driverData, device->driverData,
commandBuffer, commandBuffer,
textureSlice, textureSlice,
x,
y,
w,
h,
buffer buffer
); );
} }
@ -938,7 +860,6 @@ 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 *destinationRectangle, REFRESH_Rect *destinationRectangle,
REFRESH_Filter filter REFRESH_Filter filter
) { ) {
@ -947,7 +868,6 @@ void REFRESH_QueuePresent(
device->driverData, device->driverData,
commandBuffer, commandBuffer,
textureSlice, textureSlice,
sourceRectangle,
destinationRectangle, destinationRectangle,
filter filter
); );

View File

@ -305,45 +305,13 @@ struct REFRESH_Device
/* Setters */ /* Setters */
void(*SetTextureData2D)( void(*SetTextureData)(
REFRESH_Renderer *driverData, REFRESH_Renderer *driverData,
REFRESH_Texture *texture, REFRESH_TextureSlice *textureSlice,
uint32_t x,
uint32_t y,
uint32_t w,
uint32_t h,
uint32_t level,
void *data, void *data,
uint32_t dataLengthInBytes 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)( void(*SetTextureDataYUV)(
REFRESH_Renderer *driverData, REFRESH_Renderer *driverData,
REFRESH_Texture *y, REFRESH_Texture *y,
@ -361,9 +329,7 @@ struct REFRESH_Device
REFRESH_Renderer *driverData, REFRESH_Renderer *driverData,
REFRESH_CommandBuffer *commandBuffer, REFRESH_CommandBuffer *commandBuffer,
REFRESH_TextureSlice *sourceTextureSlice, REFRESH_TextureSlice *sourceTextureSlice,
REFRESH_TextureSlice *destinationTexture, REFRESH_TextureSlice *destinationTextureSlice,
REFRESH_Rect *sourceRectangle,
REFRESH_Rect *destinationRectangle,
REFRESH_Filter filter REFRESH_Filter filter
); );
@ -371,10 +337,6 @@ struct REFRESH_Device
REFRESH_Renderer *driverData, REFRESH_Renderer *driverData,
REFRESH_CommandBuffer *commandBuffer, REFRESH_CommandBuffer *commandBuffer,
REFRESH_TextureSlice *textureSlice, REFRESH_TextureSlice *textureSlice,
uint32_t x,
uint32_t y,
uint32_t w,
uint32_t h,
REFRESH_Buffer *buffer REFRESH_Buffer *buffer
); );
@ -550,7 +512,6 @@ struct REFRESH_Device
REFRESH_Renderer *driverData, REFRESH_Renderer *driverData,
REFRESH_CommandBuffer *commandBuffer, REFRESH_CommandBuffer *commandBuffer,
REFRESH_TextureSlice *textureSlice, REFRESH_TextureSlice *textureSlice,
REFRESH_Rect *sourceRectangle,
REFRESH_Rect *destinationRectangle, REFRESH_Rect *destinationRectangle,
REFRESH_Filter filter REFRESH_Filter filter
); );
@ -590,9 +551,7 @@ struct REFRESH_Device
ASSIGN_DRIVER_FUNC(CreateColorTarget, name) \ ASSIGN_DRIVER_FUNC(CreateColorTarget, name) \
ASSIGN_DRIVER_FUNC(CreateDepthStencilTarget, name) \ ASSIGN_DRIVER_FUNC(CreateDepthStencilTarget, name) \
ASSIGN_DRIVER_FUNC(CreateBuffer, name) \ ASSIGN_DRIVER_FUNC(CreateBuffer, name) \
ASSIGN_DRIVER_FUNC(SetTextureData2D, name) \ ASSIGN_DRIVER_FUNC(SetTextureData, name) \
ASSIGN_DRIVER_FUNC(SetTextureData3D, name) \
ASSIGN_DRIVER_FUNC(SetTextureDataCube, name) \
ASSIGN_DRIVER_FUNC(SetTextureDataYUV, name) \ ASSIGN_DRIVER_FUNC(SetTextureDataYUV, name) \
ASSIGN_DRIVER_FUNC(CopyTextureToTexture, name) \ ASSIGN_DRIVER_FUNC(CopyTextureToTexture, name) \
ASSIGN_DRIVER_FUNC(CopyTextureToBuffer, name) \ ASSIGN_DRIVER_FUNC(CopyTextureToBuffer, name) \

View File

@ -749,6 +749,10 @@ typedef struct VulkanTexture
VkImage image; VkImage image;
VkImageView view; VkImageView view;
VkExtent2D dimensions; VkExtent2D dimensions;
uint8_t is3D;
uint8_t isCube;
uint32_t depth; uint32_t depth;
uint32_t layerCount; uint32_t layerCount;
uint32_t levelCount; uint32_t levelCount;
@ -5412,13 +5416,18 @@ static uint8_t VULKAN_INTERNAL_CreateTexture(
uint8_t layerCount = isCube ? 6 : 1; uint8_t layerCount = isCube ? 6 : 1;
VkComponentMapping swizzle = IDENTITY_SWIZZLE; VkComponentMapping swizzle = IDENTITY_SWIZZLE;
texture->isCube = 0;
texture->is3D = 0;
if (isCube) if (isCube)
{ {
imageCreateFlags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; imageCreateFlags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
texture->isCube = 1;
} }
else if (is3D) else if (is3D)
{ {
imageCreateFlags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT; imageCreateFlags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT;
texture->is3D = 1;
} }
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 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.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageViewCreateInfo.subresourceRange.baseMipLevel = 0; imageViewCreateInfo.subresourceRange.baseMipLevel = 0;
imageViewCreateInfo.subresourceRange.levelCount = 1; imageViewCreateInfo.subresourceRange.levelCount = 1;
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.baseArrayLayer = textureSlice->layer;
}
imageViewCreateInfo.subresourceRange.layerCount = 1; imageViewCreateInfo.subresourceRange.layerCount = 1;
imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; 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_Renderer *driverData,
REFRESH_Texture *texture, REFRESH_TextureSlice *textureSlice,
uint32_t x,
uint32_t y,
uint32_t w,
uint32_t h,
uint32_t level,
void *data, void *data,
uint32_t dataLengthInBytes uint32_t dataLengthInBytes
) { ) {
VulkanRenderer *renderer = (VulkanRenderer*) driverData; VulkanRenderer *renderer = (VulkanRenderer*) driverData;
VulkanTexture *vulkanTexture = (VulkanTexture*) textureSlice->texture;
VkCommandBuffer commandBuffer = renderer->transferCommandBuffers[renderer->frameIndex]; VkCommandBuffer commandBuffer = renderer->transferCommandBuffers[renderer->frameIndex];
VkResult vulkanResult;
VulkanTexture *vulkanTexture = (VulkanTexture*) texture;
VkBufferImageCopy imageCopy; VkBufferImageCopy imageCopy;
VkResult vulkanResult;
uint8_t *mapPointer; uint8_t *mapPointer;
SDL_LockMutex(renderer->stagingLock); SDL_LockMutex(renderer->stagingLock);
@ -6051,25 +6063,25 @@ static void VULKAN_SetTextureData2D(
commandBuffer, commandBuffer,
RESOURCE_ACCESS_TRANSFER_WRITE, RESOURCE_ACCESS_TRANSFER_WRITE,
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_ASPECT_COLOR_BIT,
0, textureSlice->layer,
vulkanTexture->layerCount, 1,
0, textureSlice->level,
vulkanTexture->levelCount, 1,
0, 0,
vulkanTexture->image, vulkanTexture->image,
&vulkanTexture->resourceAccessType &vulkanTexture->resourceAccessType
); );
imageCopy.imageExtent.width = w; imageCopy.imageExtent.width = textureSlice->rectangle.w;
imageCopy.imageExtent.height = h; imageCopy.imageExtent.height = textureSlice->rectangle.h;
imageCopy.imageExtent.depth = 1; imageCopy.imageExtent.depth = 1;
imageCopy.imageOffset.x = x; imageCopy.imageOffset.x = textureSlice->rectangle.x;
imageCopy.imageOffset.y = y; imageCopy.imageOffset.y = textureSlice->rectangle.y;
imageCopy.imageOffset.z = 0; imageCopy.imageOffset.z = textureSlice->depth;
imageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; imageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageCopy.imageSubresource.baseArrayLayer = 0; imageCopy.imageSubresource.baseArrayLayer = textureSlice->layer;
imageCopy.imageSubresource.layerCount = 1; imageCopy.imageSubresource.layerCount = 1;
imageCopy.imageSubresource.mipLevel = level; imageCopy.imageSubresource.mipLevel = textureSlice->level;
imageCopy.bufferOffset = renderer->textureStagingBufferOffset; imageCopy.bufferOffset = renderer->textureStagingBufferOffset;
imageCopy.bufferRowLength = 0; imageCopy.bufferRowLength = 0;
imageCopy.bufferImageHeight = 0; imageCopy.bufferImageHeight = 0;
@ -6092,235 +6104,10 @@ static void VULKAN_SetTextureData2D(
commandBuffer, commandBuffer,
RESOURCE_ACCESS_ANY_SHADER_READ_SAMPLED_IMAGE, RESOURCE_ACCESS_ANY_SHADER_READ_SAMPLED_IMAGE,
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_ASPECT_COLOR_BIT,
0, textureSlice->layer,
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, 1,
&imageCopy textureSlice->level,
);
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, 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, 0,
vulkanTexture->image, vulkanTexture->image,
&vulkanTexture->resourceAccessType &vulkanTexture->resourceAccessType
@ -6538,12 +6325,14 @@ static void VULKAN_INTERNAL_BlitImage(
VulkanRenderer *renderer, VulkanRenderer *renderer,
VkCommandBuffer commandBuffer, VkCommandBuffer commandBuffer,
REFRESH_Rect *sourceRectangle, REFRESH_Rect *sourceRectangle,
uint32_t sourceDepth,
uint32_t sourceLayer, uint32_t sourceLayer,
uint32_t sourceLevel, uint32_t sourceLevel,
VkImage sourceImage, VkImage sourceImage,
VulkanResourceAccessType *currentSourceAccessType, VulkanResourceAccessType *currentSourceAccessType,
VulkanResourceAccessType nextSourceAccessType, VulkanResourceAccessType nextSourceAccessType,
REFRESH_Rect *destinationRectangle, REFRESH_Rect *destinationRectangle,
uint32_t destinationDepth,
uint32_t destinationLayer, uint32_t destinationLayer,
uint32_t destinationLevel, uint32_t destinationLevel,
VkImage destinationImage, VkImage destinationImage,
@ -6583,7 +6372,7 @@ static void VULKAN_INTERNAL_BlitImage(
blit.srcOffsets[0].x = sourceRectangle->x; blit.srcOffsets[0].x = sourceRectangle->x;
blit.srcOffsets[0].y = sourceRectangle->y; 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].x = sourceRectangle->x + sourceRectangle->w;
blit.srcOffsets[1].y = sourceRectangle->y + sourceRectangle->h; blit.srcOffsets[1].y = sourceRectangle->y + sourceRectangle->h;
blit.srcOffsets[1].z = 1; blit.srcOffsets[1].z = 1;
@ -6595,7 +6384,7 @@ static void VULKAN_INTERNAL_BlitImage(
blit.dstOffsets[0].x = destinationRectangle->x; blit.dstOffsets[0].x = destinationRectangle->x;
blit.dstOffsets[0].y = destinationRectangle->y; 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].x = destinationRectangle->x + destinationRectangle->w;
blit.dstOffsets[1].y = destinationRectangle->y + destinationRectangle->h; blit.dstOffsets[1].y = destinationRectangle->y + destinationRectangle->h;
blit.dstOffsets[1].z = 1; blit.dstOffsets[1].z = 1;
@ -6650,8 +6439,6 @@ REFRESHAPI void VULKAN_CopyTextureToTexture(
REFRESH_CommandBuffer *commandBuffer, REFRESH_CommandBuffer *commandBuffer,
REFRESH_TextureSlice *sourceTextureSlice, REFRESH_TextureSlice *sourceTextureSlice,
REFRESH_TextureSlice *destinationTextureSlice, REFRESH_TextureSlice *destinationTextureSlice,
REFRESH_Rect *sourceRectangle,
REFRESH_Rect *destinationRectangle,
REFRESH_Filter filter REFRESH_Filter filter
) { ) {
VulkanRenderer *renderer = (VulkanRenderer*)driverData; VulkanRenderer *renderer = (VulkanRenderer*)driverData;
@ -6659,43 +6446,18 @@ REFRESHAPI void VULKAN_CopyTextureToTexture(
VulkanTexture *sourceTexture = (VulkanTexture*) sourceTextureSlice->texture; VulkanTexture *sourceTexture = (VulkanTexture*) sourceTextureSlice->texture;
VulkanTexture *destinationTexture = (VulkanTexture*) destinationTextureSlice->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( VULKAN_INTERNAL_BlitImage(
renderer, renderer,
vulkanCommandBuffer->commandBuffer, vulkanCommandBuffer->commandBuffer,
&srcRect, &sourceTextureSlice->rectangle,
sourceTextureSlice->depth,
sourceTextureSlice->layer, sourceTextureSlice->layer,
sourceTextureSlice->level, sourceTextureSlice->level,
sourceTexture->image, sourceTexture->image,
&sourceTexture->resourceAccessType, &sourceTexture->resourceAccessType,
sourceTexture->resourceAccessType, sourceTexture->resourceAccessType,
&dstRect, &destinationTextureSlice->rectangle,
destinationTextureSlice->depth,
destinationTextureSlice->layer, destinationTextureSlice->layer,
destinationTextureSlice->level, destinationTextureSlice->level,
destinationTexture->image, destinationTexture->image,
@ -7298,21 +7060,15 @@ static void VULKAN_GetBufferData(
SDL_UnlockMutex(vulkanBuffer->subBuffers[vulkanBuffer->currentSubBufferIndex]->allocation->memoryLock); SDL_UnlockMutex(vulkanBuffer->subBuffers[vulkanBuffer->currentSubBufferIndex]->allocation->memoryLock);
} }
static void VULKAN_INTERNAL_CopyTextureData( static void VULKAN_CopyTextureToBuffer(
REFRESH_Renderer *driverData, REFRESH_Renderer *driverData,
REFRESH_CommandBuffer *commandBuffer, REFRESH_CommandBuffer *commandBuffer,
REFRESH_Texture *texture, REFRESH_TextureSlice *textureSlice,
int32_t x,
int32_t y,
int32_t w,
int32_t h,
int32_t level,
int32_t layer,
REFRESH_Buffer *buffer REFRESH_Buffer *buffer
) { ) {
VulkanRenderer *renderer = (VulkanRenderer*) driverData; VulkanRenderer *renderer = (VulkanRenderer*) driverData;
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
VulkanTexture *vulkanTexture = (VulkanTexture*) texture; VulkanTexture *vulkanTexture = (VulkanTexture*) textureSlice->texture;
VulkanBuffer *vulkanBuffer = (VulkanBuffer*) buffer; VulkanBuffer *vulkanBuffer = (VulkanBuffer*) buffer;
VulkanResourceAccessType prevResourceAccess; VulkanResourceAccessType prevResourceAccess;
@ -7326,10 +7082,10 @@ static void VULKAN_INTERNAL_CopyTextureData(
vulkanCommandBuffer->commandBuffer, vulkanCommandBuffer->commandBuffer,
RESOURCE_ACCESS_TRANSFER_READ, RESOURCE_ACCESS_TRANSFER_READ,
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_ASPECT_COLOR_BIT,
0, textureSlice->layer,
vulkanTexture->layerCount, 1,
0, textureSlice->level,
vulkanTexture->levelCount, 1,
0, 0,
vulkanTexture->image, vulkanTexture->image,
&vulkanTexture->resourceAccessType &vulkanTexture->resourceAccessType
@ -7337,18 +7093,18 @@ static void VULKAN_INTERNAL_CopyTextureData(
/* Save texture data to buffer */ /* Save texture data to buffer */
imageCopy.imageExtent.width = w; imageCopy.imageExtent.width = textureSlice->rectangle.w;
imageCopy.imageExtent.height = h; imageCopy.imageExtent.height = textureSlice->rectangle.h;
imageCopy.imageExtent.depth = 1; imageCopy.imageExtent.depth = 1;
imageCopy.bufferRowLength = w; imageCopy.bufferRowLength = textureSlice->rectangle.w;
imageCopy.bufferImageHeight = h; imageCopy.bufferImageHeight = textureSlice->rectangle.h;
imageCopy.imageOffset.x = x; imageCopy.imageOffset.x = textureSlice->rectangle.x;
imageCopy.imageOffset.y = y; imageCopy.imageOffset.y = textureSlice->rectangle.y;
imageCopy.imageOffset.z = 0; imageCopy.imageOffset.z = textureSlice->depth;
imageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; imageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageCopy.imageSubresource.baseArrayLayer = layer; imageCopy.imageSubresource.baseArrayLayer = textureSlice->layer;
imageCopy.imageSubresource.layerCount = 1; imageCopy.imageSubresource.layerCount = 1;
imageCopy.imageSubresource.mipLevel = level; imageCopy.imageSubresource.mipLevel = textureSlice->level;
imageCopy.bufferOffset = 0; imageCopy.bufferOffset = 0;
renderer->vkCmdCopyImageToBuffer( renderer->vkCmdCopyImageToBuffer(
@ -7367,40 +7123,16 @@ static void VULKAN_INTERNAL_CopyTextureData(
vulkanCommandBuffer->commandBuffer, vulkanCommandBuffer->commandBuffer,
prevResourceAccess, prevResourceAccess,
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_ASPECT_COLOR_BIT,
0, textureSlice->layer,
vulkanTexture->layerCount, 1,
0, textureSlice->level,
vulkanTexture->levelCount, 1,
0, 0,
vulkanTexture->image, vulkanTexture->image,
&vulkanTexture->resourceAccessType &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( static void VULKAN_AddDisposeTexture(
REFRESH_Renderer *driverData, REFRESH_Renderer *driverData,
REFRESH_Texture *texture REFRESH_Texture *texture
@ -8162,14 +7894,12 @@ static void VULKAN_QueuePresent(
REFRESH_Renderer *driverData, REFRESH_Renderer *driverData,
REFRESH_CommandBuffer *commandBuffer, REFRESH_CommandBuffer *commandBuffer,
REFRESH_TextureSlice *textureSlice, REFRESH_TextureSlice *textureSlice,
REFRESH_Rect *sourceRectangle,
REFRESH_Rect *destinationRectangle, REFRESH_Rect *destinationRectangle,
REFRESH_Filter filter REFRESH_Filter filter
) { ) {
VkResult acquireResult; VkResult acquireResult;
uint32_t swapChainImageIndex; uint32_t swapChainImageIndex;
REFRESH_Rect srcRect;
REFRESH_Rect dstRect; REFRESH_Rect dstRect;
VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanRenderer* renderer = (VulkanRenderer*) driverData;
@ -8202,18 +7932,6 @@ static void VULKAN_QueuePresent(
renderer->swapChainImageAcquired = 1; renderer->swapChainImageAcquired = 1;
renderer->currentSwapChainIndex = swapChainImageIndex; 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) if (destinationRectangle != NULL)
{ {
dstRect = *destinationRectangle; dstRect = *destinationRectangle;
@ -8231,7 +7949,8 @@ static void VULKAN_QueuePresent(
VULKAN_INTERNAL_BlitImage( VULKAN_INTERNAL_BlitImage(
renderer, renderer,
vulkanCommandBuffer->commandBuffer, vulkanCommandBuffer->commandBuffer,
&srcRect, &textureSlice->rectangle,
textureSlice->depth,
textureSlice->layer, textureSlice->layer,
textureSlice->level, textureSlice->level,
vulkanTexture->image, vulkanTexture->image,
@ -8240,6 +7959,7 @@ static void VULKAN_QueuePresent(
&dstRect, &dstRect,
0, 0,
0, 0,
0,
renderer->swapChainImages[swapChainImageIndex], renderer->swapChainImages[swapChainImageIndex],
&renderer->swapChainResourceAccessTypes[swapChainImageIndex], &renderer->swapChainResourceAccessTypes[swapChainImageIndex],
RESOURCE_ACCESS_PRESENT, RESOURCE_ACCESS_PRESENT,
@ -8447,7 +8167,7 @@ static void VULKAN_Submit(
uint32_t i; uint32_t i;
uint8_t present; uint8_t present;
VkPipelineStageFlags waitStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; VkPipelineStageFlags waitStages[2];
VkSemaphore waitSemaphores[2]; VkSemaphore waitSemaphores[2];
uint32_t waitSemaphoreCount = 0; uint32_t waitSemaphoreCount = 0;
VkPresentInfoKHR presentInfo; VkPresentInfoKHR presentInfo;
@ -8467,6 +8187,7 @@ static void VULKAN_Submit(
transferSubmitInfo.signalSemaphoreCount = 1; transferSubmitInfo.signalSemaphoreCount = 1;
waitSemaphores[waitSemaphoreCount] = renderer->transferFinishedSemaphore; waitSemaphores[waitSemaphoreCount] = renderer->transferFinishedSemaphore;
waitStages[waitSemaphoreCount] = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
waitSemaphoreCount += 1; waitSemaphoreCount += 1;
} }
@ -8489,9 +8210,10 @@ static void VULKAN_Submit(
if (present) if (present)
{ {
waitSemaphores[waitSemaphoreCount] = renderer->imageAvailableSemaphore; waitSemaphores[waitSemaphoreCount] = renderer->imageAvailableSemaphore;
waitStages[waitSemaphoreCount] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
waitSemaphoreCount += 1; waitSemaphoreCount += 1;
submitInfo.pWaitDstStageMask = &waitStage; submitInfo.pWaitDstStageMask = waitStages;
submitInfo.signalSemaphoreCount = 1; submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = &renderer->renderFinishedSemaphore; submitInfo.pSignalSemaphores = &renderer->renderFinishedSemaphore;
} }