]> O.S.I.I.S - jp/vkvg.git/commitdiff
provide 2 steps blit if blitting not supported in linear tiling
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sun, 23 Jan 2022 18:20:16 +0000 (19:20 +0100)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sun, 23 Jan 2022 18:20:16 +0000 (19:20 +0100)
src/vkvg_device_internal.c
src/vkvg_device_internal.h
src/vkvg_surface.c

index 1e736164361cbe5621e95c0fcb80bbd338c602a5..af32d92a1650d1d349c872e87c881bf0f3c19919 100644 (file)
@@ -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;
                }
        }
index 14b807aa30fe48dad4d10ed859ddade50b80435c..35373263d676e90e773bce39188e64e2765a7608 100644 (file)
@@ -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 */
index e2394e7e37c7e657379e7dace288f9446feb22c3..916277536970d6b38ea931c54bf1d7285475574e 100644 (file)
@@ -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);
-
-       uint64_t stride = vkh_image_get_stride(stagImg);
+       VkhImage stagImgLinear = 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){