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. * h: The height of the subregion being read.
* level: The mipmap level being read. * level: The mipmap level being read.
* data: The pointer being filled with the image data. * data: The pointer being filled with the image data.
* dataLength: The size of the image data in bytes.
*/ */
REFRESHAPI void REFRESH_GetTextureData2D( REFRESHAPI void REFRESH_GetTextureData2D(
REFRESH_Device *device, REFRESH_Device *device,
@ -1073,8 +1072,7 @@ REFRESHAPI void REFRESH_GetTextureData2D(
uint32_t w, uint32_t w,
uint32_t h, uint32_t h,
uint32_t level, uint32_t level,
void* data, void* data
uint32_t dataLength
); );
/* Pulls image data from a single face of a texture cube object into client /* Pulls image data from a single face of a texture cube object into client
@ -1090,7 +1088,6 @@ REFRESHAPI void REFRESH_GetTextureData2D(
* cubeMapFace: The face of the cube being read. * cubeMapFace: The face of the cube being read.
* level: The mipmap level being read. * level: The mipmap level being read.
* data: The pointer being filled with the image data. * data: The pointer being filled with the image data.
* dataLength: The size of the image data in bytes.
*/ */
REFRESHAPI void REFRESH_GetTextureDataCube( REFRESHAPI void REFRESH_GetTextureDataCube(
REFRESH_Device *device, REFRESH_Device *device,
@ -1101,8 +1098,7 @@ REFRESHAPI void REFRESH_GetTextureDataCube(
uint32_t h, uint32_t h,
REFRESH_CubeMapFace cubeMapFace, REFRESH_CubeMapFace cubeMapFace,
uint32_t level, uint32_t level,
void* data, void* data
uint32_t dataLength
); );
/* Disposal */ /* Disposal */

View File

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

View File

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

View File

@ -713,8 +713,14 @@ typedef struct VulkanTexture
uint32_t layerCount; uint32_t layerCount;
uint32_t levelCount; uint32_t levelCount;
VkFormat format; VkFormat format;
REFRESH_SurfaceFormat refreshFormat;
VulkanResourceAccessType resourceAccessType; VulkanResourceAccessType resourceAccessType;
REFRESH_TextureUsageFlags usageFlags; REFRESH_TextureUsageFlags usageFlags;
REFRESHNAMELESS union
{
REFRESH_SurfaceFormat colorFormat;
REFRESH_DepthFormat depthStencilFormat;
};
} VulkanTexture; } VulkanTexture;
typedef struct VulkanColorTarget typedef struct VulkanColorTarget
@ -4805,6 +4811,7 @@ static REFRESH_Texture* VULKAN_CreateTexture2D(
usageFlags, usageFlags,
result result
); );
result->colorFormat = format;
return (REFRESH_Texture*) result; return (REFRESH_Texture*) result;
} }
@ -4849,6 +4856,7 @@ static REFRESH_Texture* VULKAN_CreateTexture3D(
usageFlags, usageFlags,
result result
); );
result->colorFormat = format;
return (REFRESH_Texture*) result; return (REFRESH_Texture*) result;
} }
@ -4891,6 +4899,7 @@ static REFRESH_Texture* VULKAN_CreateTextureCube(
usageFlags, usageFlags,
result result
); );
result->colorFormat = format;
return (REFRESH_Texture*) result; return (REFRESH_Texture*) result;
} }
@ -4925,7 +4934,7 @@ static REFRESH_ColorTarget* VULKAN_CreateColorTarget(
0, 0,
RefreshToVK_SampleCount[multisampleCount], RefreshToVK_SampleCount[multisampleCount],
1, 1,
RefreshToVK_SurfaceFormat[colorTarget->texture->format], colorTarget->texture->format,
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_TYPE_2D, VK_IMAGE_TYPE_2D,
@ -4933,6 +4942,7 @@ static REFRESH_ColorTarget* VULKAN_CreateColorTarget(
REFRESH_TEXTUREUSAGE_COLOR_TARGET_BIT, REFRESH_TEXTUREUSAGE_COLOR_TARGET_BIT,
colorTarget->multisampleTexture colorTarget->multisampleTexture
); );
colorTarget->multisampleTexture->colorFormat = colorTarget->texture->colorFormat;
colorTarget->multisampleCount = multisampleCount; colorTarget->multisampleCount = multisampleCount;
VULKAN_INTERNAL_ImageMemoryBarrier( VULKAN_INTERNAL_ImageMemoryBarrier(
@ -5027,6 +5037,7 @@ static REFRESH_DepthStencilTarget* VULKAN_CreateDepthStencilTarget(
0, 0,
texture texture
); );
texture->depthStencilFormat = format;
depthStencilTarget->texture = texture; depthStencilTarget->texture = texture;
depthStencilTarget->view = texture->view; 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( static void VULKAN_GetTextureData2D(
REFRESH_Renderer *driverData, REFRESH_Renderer *driverData,
REFRESH_Texture *texture, REFRESH_Texture *texture,
@ -5968,10 +6097,19 @@ static void VULKAN_GetTextureData2D(
uint32_t w, uint32_t w,
uint32_t h, uint32_t h,
uint32_t level, uint32_t level,
void* data, void* data
uint32_t dataLength
) { ) {
SDL_assert(0); VULKAN_INTERNAL_GetTextureData(
driverData,
texture,
x,
y,
w,
h,
level,
0,
data
);
} }
static void VULKAN_GetTextureDataCube( static void VULKAN_GetTextureDataCube(
@ -5983,10 +6121,19 @@ static void VULKAN_GetTextureDataCube(
uint32_t h, uint32_t h,
REFRESH_CubeMapFace cubeMapFace, REFRESH_CubeMapFace cubeMapFace,
uint32_t level, uint32_t level,
void* data, void* data
uint32_t dataLength
) { ) {
SDL_assert(0); VULKAN_INTERNAL_GetTextureData(
driverData,
texture,
x,
y,
w,
h,
level,
cubeMapFace,
data
);
} }
static void VULKAN_AddDisposeTexture( static void VULKAN_AddDisposeTexture(