summaryrefslogtreecommitdiffstatsci
path: root/src
diff options
context:
space:
mode:
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>2022-01-23 19:20:16 +0100
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>2022-01-23 19:20:16 +0100
commitf46d8a40db6bfddea6636cbc3583cf3a46f5c8e0 (patch)
treecd2f749fe8c5b6072108e5f0c988064864177b8e /src
parent4915cbe0ada941b77a64fcc9a9fed16b51b7922e (diff)
provide 2 steps blit if blitting not supported in linear tiling
Diffstat (limited to 'src')
-rw-r--r--src/vkvg_device_internal.c5
-rw-r--r--src/vkvg_device_internal.h1
-rw-r--r--src/vkvg_surface.c52
3 files changed, 52 insertions, 6 deletions
diff --git a/src/vkvg_device_internal.c b/src/vkvg_device_internal.c
index 1e73616..af32d92 100644
--- a/src/vkvg_device_internal.c
+++ b/src/vkvg_device_internal.c
@@ -489,6 +489,11 @@ void _check_best_image_tiling (VkvgDevice dev, VkFormat format) {
vkGetPhysicalDeviceFormatProperties(dev->phy, pngBlitFormats[i], &phyImgProps);
if ((phyImgProps.linearTilingFeatures & VKVG_PNG_WRITE_IMG_REQUIREMENTS) == VKVG_PNG_WRITE_IMG_REQUIREMENTS) {
dev->pngStagFormat = pngBlitFormats[i];
+ dev->pngStagTiling = VK_IMAGE_TILING_LINEAR;
+ break;
+ } else if ((phyImgProps.optimalTilingFeatures & VKVG_PNG_WRITE_IMG_REQUIREMENTS) == VKVG_PNG_WRITE_IMG_REQUIREMENTS) {
+ dev->pngStagFormat = pngBlitFormats[i];
+ dev->pngStagTiling = VK_IMAGE_TILING_OPTIMAL;
break;
}
}
diff --git a/src/vkvg_device_internal.h b/src/vkvg_device_internal.h
index 14b807a..3537326 100644
--- a/src/vkvg_device_internal.h
+++ b/src/vkvg_device_internal.h
@@ -61,6 +61,7 @@ typedef struct _vkvg_device_t{
VkImageTiling supportedTiling; /**< Supported image tiling for surface, 0xFF=no support */
VkFormat stencilFormat; /**< Supported vulkan image format for stencil */
VkFormat pngStagFormat; /**< Supported vulkan image format png write staging img */
+ VkImageTiling pngStagTiling; /**< tiling for the blit operation */
VkhQueue gQueue; /**< Vulkan Queue with Graphic flag */
MUTEX gQMutex; /**< queue submission has to be externally syncronized */
diff --git a/src/vkvg_surface.c b/src/vkvg_surface.c
index e2394e7..9162775 100644
--- a/src/vkvg_surface.c
+++ b/src/vkvg_surface.c
@@ -247,9 +247,16 @@ void vkvg_surface_write_to_png (VkvgSurface surf, const char* path){
VkvgDevice dev = surf->dev;
//RGBA to blit to, surf img is bgra
- VkhImage stagImg= vkh_image_create ((VkhDevice)surf->dev, dev->pngStagFormat, surf->width,surf->height,VK_IMAGE_TILING_LINEAR,
+ VkhImage stagImg;
+
+ if (dev->pngStagTiling == VK_IMAGE_TILING_LINEAR)
+ stagImg = vkh_image_create ((VkhDevice)surf->dev, dev->pngStagFormat, surf->width, surf->height, dev->pngStagTiling,
VMA_MEMORY_USAGE_GPU_TO_CPU,
VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT);
+ else
+ stagImg = vkh_image_create ((VkhDevice)surf->dev, dev->pngStagFormat, surf->width,surf->height, dev->pngStagTiling,
+ VMA_MEMORY_USAGE_GPU_ONLY,
+ VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT);
VkCommandBuffer cmd = dev->cmd;
_wait_and_reset_device_fence (dev);
@@ -274,16 +281,49 @@ void vkvg_surface_write_to_png (VkvgSurface surf, const char* path){
vkh_cmd_end (cmd);
_submit_cmd (dev, &cmd, dev->fence);
- vkWaitForFences (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX);
- void* img = vkh_image_map (stagImg);
+ VkhImage stagImgLinear = stagImg;
- uint64_t stride = vkh_image_get_stride(stagImg);
+ if (dev->pngStagTiling == VK_IMAGE_TILING_OPTIMAL) {
+ stagImgLinear = vkh_image_create ((VkhDevice)surf->dev, dev->pngStagFormat, surf->width, surf->height, VK_IMAGE_TILING_LINEAR,
+ VMA_MEMORY_USAGE_GPU_TO_CPU,
+ VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT);
+ VkImageCopy cpy = {
+ .srcSubresource = imgSubResLayers,
+ .srcOffset = {0},
+ .dstSubresource = imgSubResLayers,
+ .dstOffset = {0},
+ .extent = {(int32_t)surf->width, (int32_t)surf->height, 1}
+ };
+ _wait_and_reset_device_fence (dev);
+
+ vkh_cmd_begin (cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
+ vkh_image_set_layout (cmd, stagImgLinear, VK_IMAGE_ASPECT_COLOR_BIT,
+ VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+ VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
+ vkh_image_set_layout (cmd, stagImg, VK_IMAGE_ASPECT_COLOR_BIT,
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+ VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
+ vkCmdCopyImage(cmd,
+ vkh_image_get_vkimage (stagImg), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+ vkh_image_get_vkimage (stagImgLinear), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cpy);
+
+ vkh_cmd_end (cmd);
+ _submit_cmd (dev, &cmd, dev->fence);
+
+ vkWaitForFences (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX);
+ vkh_image_destroy (stagImg);
+ } else
+ vkWaitForFences (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX);
+
+ void* img = vkh_image_map (stagImgLinear);
+
+ uint64_t stride = vkh_image_get_stride(stagImgLinear);
stbi_write_png (path, (int32_t)surf->width, (int32_t)surf->height, 4, img, (int32_t)stride);
- vkh_image_unmap (stagImg);
- vkh_image_destroy (stagImg);
+ vkh_image_unmap (stagImgLinear);
+ vkh_image_destroy (stagImgLinear);
}
void vkvg_surface_write_to_memory (VkvgSurface surf, unsigned char* const bitmap){