implement texture getters

pull/8/head
cosmonaut 2020-12-28 23:41:59 -08:00
parent cea9b853a4
commit d6cd3715cb
4 changed files with 169 additions and 32 deletions

View File

@ -1063,7 +1063,6 @@ REFRESHAPI void REFRESH_SetFragmentSamplers(
* h: The height of the subregion being read.
* level: The mipmap level being read.
* data: The pointer being filled with the image data.
* dataLength: The size of the image data in bytes.
*/
REFRESHAPI void REFRESH_GetTextureData2D(
REFRESH_Device *device,
@ -1073,8 +1072,7 @@ REFRESHAPI void REFRESH_GetTextureData2D(
uint32_t w,
uint32_t h,
uint32_t level,
void* data,
uint32_t dataLength
void* data
);
/* Pulls image data from a single face of a texture cube object into client
@ -1082,15 +1080,14 @@ REFRESHAPI void REFRESH_GetTextureData2D(
* point, don't call this unless there's absolutely no other way to use the
* image data!
*
* 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.
* 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.
* data: The pointer being filled with the image data.
* dataLength: The size of the image data in bytes.
* level: The mipmap level being read.
* data: The pointer being filled with the image data.
*/
REFRESHAPI void REFRESH_GetTextureDataCube(
REFRESH_Device *device,
@ -1101,8 +1098,7 @@ REFRESHAPI void REFRESH_GetTextureDataCube(
uint32_t h,
REFRESH_CubeMapFace cubeMapFace,
uint32_t level,
void* data,
uint32_t dataLength
void* data
);
/* Disposal */

View File

@ -607,8 +607,7 @@ void REFRESH_GetTextureData2D(
uint32_t w,
uint32_t h,
uint32_t level,
void* data,
uint32_t dataLength
void* data
) {
NULL_RETURN(device);
device->GetTextureData2D(
@ -619,8 +618,7 @@ void REFRESH_GetTextureData2D(
w,
h,
level,
data,
dataLength
data
);
}
@ -633,8 +631,7 @@ void REFRESH_GetTextureDataCube(
uint32_t h,
REFRESH_CubeMapFace cubeMapFace,
uint32_t level,
void* data,
uint32_t dataLength
void* data
) {
NULL_RETURN(device);
device->GetTextureDataCube(
@ -646,8 +643,7 @@ void REFRESH_GetTextureDataCube(
h,
cubeMapFace,
level,
data,
dataLength
data
);
}

View File

@ -395,8 +395,7 @@ struct REFRESH_Device
uint32_t w,
uint32_t h,
uint32_t level,
void* data,
uint32_t dataLength
void* data
);
void(*GetTextureDataCube)(
@ -408,8 +407,7 @@ struct REFRESH_Device
uint32_t h,
REFRESH_CubeMapFace cubeMapFace,
uint32_t level,
void* data,
uint32_t dataLength
void* data
);
/* Disposal */

View File

@ -713,8 +713,14 @@ typedef struct VulkanTexture
uint32_t layerCount;
uint32_t levelCount;
VkFormat format;
REFRESH_SurfaceFormat refreshFormat;
VulkanResourceAccessType resourceAccessType;
REFRESH_TextureUsageFlags usageFlags;
REFRESHNAMELESS union
{
REFRESH_SurfaceFormat colorFormat;
REFRESH_DepthFormat depthStencilFormat;
};
} VulkanTexture;
typedef struct VulkanColorTarget
@ -4805,6 +4811,7 @@ static REFRESH_Texture* VULKAN_CreateTexture2D(
usageFlags,
result
);
result->colorFormat = format;
return (REFRESH_Texture*) result;
}
@ -4849,6 +4856,7 @@ static REFRESH_Texture* VULKAN_CreateTexture3D(
usageFlags,
result
);
result->colorFormat = format;
return (REFRESH_Texture*) result;
}
@ -4891,6 +4899,7 @@ static REFRESH_Texture* VULKAN_CreateTextureCube(
usageFlags,
result
);
result->colorFormat = format;
return (REFRESH_Texture*) result;
}
@ -4925,7 +4934,7 @@ static REFRESH_ColorTarget* VULKAN_CreateColorTarget(
0,
RefreshToVK_SampleCount[multisampleCount],
1,
RefreshToVK_SurfaceFormat[colorTarget->texture->format],
colorTarget->texture->format,
VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_TYPE_2D,
@ -4933,6 +4942,7 @@ static REFRESH_ColorTarget* VULKAN_CreateColorTarget(
REFRESH_TEXTUREUSAGE_COLOR_TARGET_BIT,
colorTarget->multisampleTexture
);
colorTarget->multisampleTexture->colorFormat = colorTarget->texture->colorFormat;
colorTarget->multisampleCount = multisampleCount;
VULKAN_INTERNAL_ImageMemoryBarrier(
@ -5027,6 +5037,7 @@ static REFRESH_DepthStencilTarget* VULKAN_CreateDepthStencilTarget(
0,
texture
);
texture->depthStencilFormat = format;
depthStencilTarget->texture = texture;
depthStencilTarget->view = texture->view;
@ -5960,6 +5971,124 @@ static void VULKAN_SetFragmentSamplers(
);
}
static void VULKAN_INTERNAL_GetTextureData(
REFRESH_Renderer *driverData,
REFRESH_Texture *texture,
int32_t x,
int32_t y,
int32_t w,
int32_t h,
int32_t level,
int32_t layer,
void* data
) {
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
VulkanTexture *vulkanTexture = (VulkanTexture*) texture;
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,
RESOURCE_ACCESS_TRANSFER_READ,
VK_IMAGE_ASPECT_COLOR_BIT,
0,
vulkanTexture->layerCount,
0,
vulkanTexture->levelCount,
0,
vulkanTexture->image,
&vulkanTexture->resourceAccessType
);
/* Save texture data to staging buffer */
imageCopy.imageExtent.width = w;
imageCopy.imageExtent.height = h;
imageCopy.imageExtent.depth = 1;
imageCopy.bufferRowLength = w;
imageCopy.bufferImageHeight = h;
imageCopy.imageOffset.x = x;
imageCopy.imageOffset.y = y;
imageCopy.imageOffset.z = 0;
imageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageCopy.imageSubresource.baseArrayLayer = layer;
imageCopy.imageSubresource.layerCount = 1;
imageCopy.imageSubresource.mipLevel = level;
imageCopy.bufferOffset = 0;
RECORD_CMD(renderer->vkCmdCopyImageToBuffer(
renderer->currentCommandBuffer,
vulkanTexture->image,
AccessMap[vulkanTexture->resourceAccessType].imageLayout,
renderer->textureStagingBuffer->subBuffers[0]->buffer,
1,
&imageCopy
));
/* Restore the image layout and wait for completion of the render pass */
VULKAN_INTERNAL_ImageMemoryBarrier(
renderer,
prevResourceAccess,
VK_IMAGE_ASPECT_COLOR_BIT,
0,
vulkanTexture->layerCount,
0,
vulkanTexture->levelCount,
0,
vulkanTexture->image,
&vulkanTexture->resourceAccessType
);
/* hard sync point */
VULKAN_Submit(driverData);
renderer->vkWaitForFences(
renderer->logicalDevice,
1,
&renderer->inFlightFence,
VK_TRUE,
UINT64_MAX
);
/* 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(
REFRESH_Renderer *driverData,
REFRESH_Texture *texture,
@ -5968,10 +6097,19 @@ static void VULKAN_GetTextureData2D(
uint32_t w,
uint32_t h,
uint32_t level,
void* data,
uint32_t dataLength
void* data
) {
SDL_assert(0);
VULKAN_INTERNAL_GetTextureData(
driverData,
texture,
x,
y,
w,
h,
level,
0,
data
);
}
static void VULKAN_GetTextureDataCube(
@ -5983,10 +6121,19 @@ static void VULKAN_GetTextureDataCube(
uint32_t h,
REFRESH_CubeMapFace cubeMapFace,
uint32_t level,
void* data,
uint32_t dataLength
void* data
) {
SDL_assert(0);
VULKAN_INTERNAL_GetTextureData(
driverData,
texture,
x,
y,
w,
h,
level,
cubeMapFace,
data
);
}
static void VULKAN_AddDisposeTexture(