forked from MoonsideGames/Refresh
make gets and sets async
parent
e0ff380989
commit
f8c99c4e18
|
@ -1092,9 +1092,25 @@ REFRESHAPI void REFRESH_SetFragmentSamplers(
|
|||
|
||||
/* Getters */
|
||||
|
||||
/* Pulls image data from a 2D texture into client memory. Like any GetData,
|
||||
* this is generally asking for a massive CPU/GPU sync point, don't call this
|
||||
* unless there's absolutely no other way to use the image data!
|
||||
/* Synchronously copies data from a buffer to a pointer.
|
||||
* You probably want to wait for a sync point to call this.
|
||||
*
|
||||
* buffer: The buffer to copy data from.
|
||||
* data: The pointer to copy data to.
|
||||
* dataLengthInBytes: The length of data to copy.
|
||||
*/
|
||||
REFRESHAPI void REFRESH_GetBufferData(
|
||||
REFRESH_Device *device,
|
||||
REFRESH_Buffer *buffer,
|
||||
void *data,
|
||||
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.
|
||||
|
@ -1102,23 +1118,23 @@ REFRESHAPI void REFRESH_SetFragmentSamplers(
|
|||
* w: The width of the subregion being read.
|
||||
* h: The height of the subregion being read.
|
||||
* level: The mipmap level being read.
|
||||
* data: The pointer being filled with the image data.
|
||||
* buffer: The buffer being filled with the image data.
|
||||
*/
|
||||
REFRESHAPI void REFRESH_GetTextureData2D(
|
||||
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,
|
||||
void* data
|
||||
REFRESH_Buffer *buffer
|
||||
);
|
||||
|
||||
/* Pulls image data from a single face of a texture cube object into client
|
||||
* memory. Like any GetData, this is generally asking for a massive CPU/GPU sync
|
||||
* point, don't call this unless there's absolutely no other way to use the
|
||||
* image data!
|
||||
/* 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.
|
||||
|
@ -1127,10 +1143,11 @@ REFRESHAPI void REFRESH_GetTextureData2D(
|
|||
* h: The height of the subregion being read.
|
||||
* cubeMapFace: The face of the cube being read.
|
||||
* level: The mipmap level being read.
|
||||
* data: The pointer being filled with the image data.
|
||||
* buffer: The buffer being filled with the image data.
|
||||
*/
|
||||
REFRESHAPI void REFRESH_GetTextureDataCube(
|
||||
REFRESHAPI void REFRESH_CopyTextureDataCube(
|
||||
REFRESH_Device *device,
|
||||
REFRESH_CommandBuffer *commandBuffer,
|
||||
REFRESH_Texture *texture,
|
||||
uint32_t x,
|
||||
uint32_t y,
|
||||
|
@ -1138,7 +1155,7 @@ REFRESHAPI void REFRESH_GetTextureDataCube(
|
|||
uint32_t h,
|
||||
REFRESH_CubeMapFace cubeMapFace,
|
||||
uint32_t level,
|
||||
void* data
|
||||
REFRESH_Buffer *buffer
|
||||
);
|
||||
|
||||
/* Disposal */
|
||||
|
|
|
@ -632,31 +632,49 @@ void REFRESH_SetFragmentSamplers(
|
|||
);
|
||||
}
|
||||
|
||||
void REFRESH_GetTextureData2D(
|
||||
void REFRESH_GetBufferData(
|
||||
REFRESH_Device *device,
|
||||
REFRESH_Buffer *buffer,
|
||||
void *data,
|
||||
uint32_t dataLengthInBytes
|
||||
) {
|
||||
NULL_RETURN(device);
|
||||
device->GetBufferData(
|
||||
device->driverData,
|
||||
buffer,
|
||||
data,
|
||||
dataLengthInBytes
|
||||
);
|
||||
}
|
||||
|
||||
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,
|
||||
void* data
|
||||
REFRESH_Buffer* buffer
|
||||
) {
|
||||
NULL_RETURN(device);
|
||||
device->GetTextureData2D(
|
||||
device->CopyTextureData2D(
|
||||
device->driverData,
|
||||
commandBuffer,
|
||||
texture,
|
||||
x,
|
||||
y,
|
||||
w,
|
||||
h,
|
||||
level,
|
||||
data
|
||||
buffer
|
||||
);
|
||||
}
|
||||
|
||||
void REFRESH_GetTextureDataCube(
|
||||
REFRESH_Device *device,
|
||||
REFRESH_CommandBuffer *commandBuffer,
|
||||
REFRESH_Texture *texture,
|
||||
uint32_t x,
|
||||
uint32_t y,
|
||||
|
@ -664,11 +682,12 @@ void REFRESH_GetTextureDataCube(
|
|||
uint32_t h,
|
||||
REFRESH_CubeMapFace cubeMapFace,
|
||||
uint32_t level,
|
||||
void* data
|
||||
REFRESH_Buffer* buffer
|
||||
) {
|
||||
NULL_RETURN(device);
|
||||
device->GetTextureDataCube(
|
||||
device->CopyTextureDataCube(
|
||||
device->driverData,
|
||||
commandBuffer,
|
||||
texture,
|
||||
x,
|
||||
y,
|
||||
|
@ -676,7 +695,7 @@ void REFRESH_GetTextureDataCube(
|
|||
h,
|
||||
cubeMapFace,
|
||||
level,
|
||||
data
|
||||
buffer
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -402,19 +402,28 @@ struct REFRESH_Device
|
|||
|
||||
/* Getters */
|
||||
|
||||
void(*GetTextureData2D)(
|
||||
void(*GetBufferData)(
|
||||
REFRESH_Renderer *driverData,
|
||||
REFRESH_Buffer *buffer,
|
||||
void *data,
|
||||
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,
|
||||
void* data
|
||||
REFRESH_Buffer* buffer
|
||||
);
|
||||
|
||||
void(*GetTextureDataCube)(
|
||||
void(*CopyTextureDataCube)(
|
||||
REFRESH_Renderer *driverData,
|
||||
REFRESH_CommandBuffer *commandBuffer,
|
||||
REFRESH_Texture *texture,
|
||||
uint32_t x,
|
||||
uint32_t y,
|
||||
|
@ -422,7 +431,7 @@ struct REFRESH_Device
|
|||
uint32_t h,
|
||||
REFRESH_CubeMapFace cubeMapFace,
|
||||
uint32_t level,
|
||||
void* data
|
||||
REFRESH_Buffer* buffer
|
||||
);
|
||||
|
||||
/* Disposal */
|
||||
|
@ -595,8 +604,9 @@ struct REFRESH_Device
|
|||
ASSIGN_DRIVER_FUNC(PushComputeShaderParams, name) \
|
||||
ASSIGN_DRIVER_FUNC(SetVertexSamplers, name) \
|
||||
ASSIGN_DRIVER_FUNC(SetFragmentSamplers, name) \
|
||||
ASSIGN_DRIVER_FUNC(GetTextureData2D, name) \
|
||||
ASSIGN_DRIVER_FUNC(GetTextureDataCube, 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(AddDisposeVertexBuffer, name) \
|
||||
|
|
|
@ -1375,7 +1375,6 @@ typedef struct VulkanRenderer
|
|||
|
||||
static void VULKAN_INTERNAL_BeginCommandBuffer(VulkanRenderer *renderer, VulkanCommandBuffer *commandBuffer);
|
||||
static void VULKAN_Submit(REFRESH_Renderer *driverData, REFRESH_CommandBuffer **pCommandBuffers, uint32_t commandBufferCount);
|
||||
static void VULKAN_INTERNAL_SubmitTransfer(REFRESH_Renderer *driverData);
|
||||
|
||||
/* Error Handling */
|
||||
|
||||
|
@ -5872,8 +5871,6 @@ static void VULKAN_SetTextureData2D(
|
|||
}
|
||||
|
||||
renderer->pendingTransfer = 1;
|
||||
|
||||
VULKAN_INTERNAL_SubmitTransfer(driverData);
|
||||
}
|
||||
|
||||
static void VULKAN_SetTextureData3D(
|
||||
|
@ -5980,8 +5977,6 @@ static void VULKAN_SetTextureData3D(
|
|||
}
|
||||
|
||||
renderer->pendingTransfer = 1;
|
||||
|
||||
VULKAN_INTERNAL_SubmitTransfer(driverData);
|
||||
}
|
||||
|
||||
static void VULKAN_SetTextureDataCube(
|
||||
|
@ -6087,8 +6082,6 @@ static void VULKAN_SetTextureDataCube(
|
|||
}
|
||||
|
||||
renderer->pendingTransfer = 1;
|
||||
|
||||
VULKAN_INTERNAL_SubmitTransfer(driverData);
|
||||
}
|
||||
|
||||
static void VULKAN_SetTextureDataYUV(
|
||||
|
@ -6289,9 +6282,6 @@ static void VULKAN_SetTextureDataYUV(
|
|||
}
|
||||
|
||||
renderer->pendingTransfer = 1;
|
||||
|
||||
/* Hard sync point */
|
||||
VULKAN_INTERNAL_SubmitTransfer(driverData);
|
||||
}
|
||||
|
||||
static void VULKAN_SetBufferData(
|
||||
|
@ -6839,8 +6829,48 @@ static void VULKAN_SetFragmentSamplers(
|
|||
);
|
||||
}
|
||||
|
||||
static void VULKAN_INTERNAL_GetTextureData(
|
||||
static void VULKAN_GetBufferData(
|
||||
REFRESH_Renderer *driverData,
|
||||
REFRESH_Buffer *buffer,
|
||||
void *data,
|
||||
uint32_t dataLengthInBytes
|
||||
) {
|
||||
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
|
||||
VulkanBuffer *vulkanBuffer = (VulkanBuffer*) buffer;
|
||||
uint8_t *dataPtr = (uint8_t*) data;
|
||||
uint8_t *mapPointer;
|
||||
VkResult vulkanResult;
|
||||
|
||||
vulkanResult = renderer->vkMapMemory(
|
||||
renderer->logicalDevice,
|
||||
vulkanBuffer->subBuffers[0]->allocation->memory,
|
||||
vulkanBuffer->subBuffers[0]->offset,
|
||||
vulkanBuffer->subBuffers[0]->size,
|
||||
0,
|
||||
(void**) &mapPointer
|
||||
);
|
||||
|
||||
if (vulkanResult != VK_SUCCESS)
|
||||
{
|
||||
REFRESH_LogError("Failed to map buffer memory!");
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_memcpy(
|
||||
dataPtr,
|
||||
mapPointer,
|
||||
dataLengthInBytes
|
||||
);
|
||||
|
||||
renderer->vkUnmapMemory(
|
||||
renderer->logicalDevice,
|
||||
vulkanBuffer->subBuffers[0]->allocation->memory
|
||||
);
|
||||
}
|
||||
|
||||
static void VULKAN_INTERNAL_CopyTextureData(
|
||||
REFRESH_Renderer *driverData,
|
||||
REFRESH_CommandBuffer *commandBuffer,
|
||||
REFRESH_Texture *texture,
|
||||
int32_t x,
|
||||
int32_t y,
|
||||
|
@ -6848,27 +6878,22 @@ static void VULKAN_INTERNAL_GetTextureData(
|
|||
int32_t h,
|
||||
int32_t level,
|
||||
int32_t layer,
|
||||
void* data
|
||||
REFRESH_Buffer *buffer
|
||||
) {
|
||||
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
|
||||
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
|
||||
VulkanTexture *vulkanTexture = (VulkanTexture*) texture;
|
||||
VulkanBuffer *vulkanBuffer = (VulkanBuffer*) buffer;
|
||||
|
||||
VkCommandBuffer commandBuffer = renderer->transferCommandBuffers[renderer->frameIndex];
|
||||
VulkanResourceAccessType prevResourceAccess;
|
||||
VkBufferImageCopy imageCopy;
|
||||
uint8_t *dataPtr = (uint8_t*) data;
|
||||
uint8_t *mapPointer;
|
||||
VkResult vulkanResult;
|
||||
uint32_t dataLength = BytesPerImage(w, h, vulkanTexture->colorFormat);
|
||||
|
||||
VULKAN_INTERNAL_MaybeExpandStagingBuffer(renderer, dataLength);
|
||||
|
||||
/* Cache this so we can restore it later */
|
||||
prevResourceAccess = vulkanTexture->resourceAccessType;
|
||||
|
||||
VULKAN_INTERNAL_ImageMemoryBarrier(
|
||||
renderer,
|
||||
commandBuffer,
|
||||
vulkanCommandBuffer->commandBuffer,
|
||||
RESOURCE_ACCESS_TRANSFER_READ,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
0,
|
||||
|
@ -6877,12 +6902,12 @@ static void VULKAN_INTERNAL_GetTextureData(
|
|||
vulkanTexture->levelCount,
|
||||
0,
|
||||
vulkanTexture->image,
|
||||
renderer->queueFamilyIndices.transferFamily,
|
||||
&vulkanTexture->queueFamilyIndex,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
NULL,
|
||||
&vulkanTexture->resourceAccessType
|
||||
);
|
||||
|
||||
/* Save texture data to staging buffer */
|
||||
/* Save texture data to buffer */
|
||||
|
||||
imageCopy.imageExtent.width = w;
|
||||
imageCopy.imageExtent.height = h;
|
||||
|
@ -6899,10 +6924,10 @@ static void VULKAN_INTERNAL_GetTextureData(
|
|||
imageCopy.bufferOffset = 0;
|
||||
|
||||
renderer->vkCmdCopyImageToBuffer(
|
||||
commandBuffer,
|
||||
vulkanCommandBuffer->commandBuffer,
|
||||
vulkanTexture->image,
|
||||
AccessMap[vulkanTexture->resourceAccessType].imageLayout,
|
||||
renderer->textureStagingBuffer->subBuffers[0]->buffer,
|
||||
vulkanBuffer->subBuffers[vulkanBuffer->currentSubBufferIndex]->buffer,
|
||||
1,
|
||||
&imageCopy
|
||||
);
|
||||
|
@ -6911,7 +6936,7 @@ static void VULKAN_INTERNAL_GetTextureData(
|
|||
|
||||
VULKAN_INTERNAL_ImageMemoryBarrier(
|
||||
renderer,
|
||||
commandBuffer,
|
||||
vulkanCommandBuffer->commandBuffer,
|
||||
prevResourceAccess,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
0,
|
||||
|
@ -6920,57 +6945,28 @@ static void VULKAN_INTERNAL_GetTextureData(
|
|||
vulkanTexture->levelCount,
|
||||
0,
|
||||
vulkanTexture->image,
|
||||
renderer->queueFamilyIndices.graphicsFamily,
|
||||
&vulkanTexture->queueFamilyIndex,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
NULL,
|
||||
&vulkanTexture->resourceAccessType
|
||||
);
|
||||
|
||||
renderer->pendingTransfer = 1;
|
||||
|
||||
/* Hard sync point */
|
||||
VULKAN_INTERNAL_SubmitTransfer(driverData);
|
||||
|
||||
/* Read from staging buffer */
|
||||
|
||||
vulkanResult = renderer->vkMapMemory(
|
||||
renderer->logicalDevice,
|
||||
renderer->textureStagingBuffer->subBuffers[0]->allocation->memory,
|
||||
renderer->textureStagingBuffer->subBuffers[0]->offset,
|
||||
renderer->textureStagingBuffer->subBuffers[0]->size,
|
||||
0,
|
||||
(void**) &mapPointer
|
||||
);
|
||||
|
||||
if (vulkanResult != VK_SUCCESS)
|
||||
{
|
||||
REFRESH_LogError("Failed to map buffer memory!");
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_memcpy(
|
||||
dataPtr,
|
||||
mapPointer,
|
||||
dataLength
|
||||
);
|
||||
|
||||
renderer->vkUnmapMemory(
|
||||
renderer->logicalDevice,
|
||||
renderer->textureStagingBuffer->subBuffers[0]->allocation->memory
|
||||
);
|
||||
}
|
||||
|
||||
static void VULKAN_GetTextureData2D(
|
||||
static void VULKAN_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,
|
||||
void* data
|
||||
REFRESH_Buffer *buffer
|
||||
) {
|
||||
VULKAN_INTERNAL_GetTextureData(
|
||||
VULKAN_INTERNAL_CopyTextureData(
|
||||
driverData,
|
||||
commandBuffer,
|
||||
texture,
|
||||
x,
|
||||
y,
|
||||
|
@ -6978,12 +6974,13 @@ static void VULKAN_GetTextureData2D(
|
|||
h,
|
||||
level,
|
||||
0,
|
||||
data
|
||||
buffer
|
||||
);
|
||||
}
|
||||
|
||||
static void VULKAN_GetTextureDataCube(
|
||||
static void VULKAN_CopyTextureDataCube(
|
||||
REFRESH_Renderer *driverData,
|
||||
REFRESH_CommandBuffer *commandBuffer,
|
||||
REFRESH_Texture *texture,
|
||||
uint32_t x,
|
||||
uint32_t y,
|
||||
|
@ -6991,10 +6988,11 @@ static void VULKAN_GetTextureDataCube(
|
|||
uint32_t h,
|
||||
REFRESH_CubeMapFace cubeMapFace,
|
||||
uint32_t level,
|
||||
void* data
|
||||
REFRESH_Buffer *buffer
|
||||
) {
|
||||
VULKAN_INTERNAL_GetTextureData(
|
||||
VULKAN_INTERNAL_CopyTextureData(
|
||||
driverData,
|
||||
commandBuffer,
|
||||
texture,
|
||||
x,
|
||||
y,
|
||||
|
@ -7002,7 +7000,7 @@ static void VULKAN_GetTextureDataCube(
|
|||
h,
|
||||
level,
|
||||
cubeMapFace,
|
||||
data
|
||||
buffer
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -8029,23 +8027,6 @@ static void VULKAN_INTERNAL_ResetCommandBuffer(
|
|||
commandPool->inactiveCommandBufferCount += 1;
|
||||
}
|
||||
|
||||
/* This function triggers a hard sync point */
|
||||
static void VULKAN_INTERNAL_SubmitTransfer(
|
||||
REFRESH_Renderer *driverData
|
||||
) {
|
||||
VulkanRenderer* renderer = (VulkanRenderer*)driverData;
|
||||
|
||||
VULKAN_Submit(driverData, NULL, 0);
|
||||
|
||||
renderer->vkWaitForFences(
|
||||
renderer->logicalDevice,
|
||||
1,
|
||||
&renderer->inFlightFence,
|
||||
VK_TRUE,
|
||||
UINT64_MAX
|
||||
);
|
||||
}
|
||||
|
||||
static void VULKAN_Submit(
|
||||
REFRESH_Renderer *driverData,
|
||||
REFRESH_CommandBuffer **pCommandBuffers,
|
||||
|
|
Loading…
Reference in New Issue