]> O.S.I.I.S - jp/vkvg.git/commitdiff
clean dev, surf, ctx error handling
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Mon, 24 Jan 2022 22:16:13 +0000 (23:16 +0100)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Mon, 24 Jan 2022 22:16:13 +0000 (23:16 +0100)
include/vkvg.h
src/vkvg_context.c
src/vkvg_device.c
src/vkvg_surface.c
src/vkvg_surface_internal.c
src/vkvg_surface_internal.h

index 2da756e20b0838554c8a4a896aefcad1bd929394..06539e8d966125ee5a14b4919a61207a95f297bb 100644 (file)
@@ -140,6 +140,9 @@ typedef enum {
        VKVG_STATUS_INVALID_DASH,                       /*!< invalid value for a dash setting */
        VKVG_STATUS_INVALID_RECT,                       /*!< rectangle with height or width equal to 0. */
        VKVG_STATUS_TIMEOUT,                            /*!< waiting for a vulkan operation to finish resulted in a fence timeout (5 seconds)*/
+       VKVG_STATUS_DEVICE_ERROR,                       /*!< vkvg device initialization error */
+       VKVG_STATUS_INVALID_IMAGE,                      /*!< */
+       VKVG_STATUS_INVALID_SURFACE,            /*!< */
 }vkvg_status_t;
 
 typedef enum {
@@ -702,6 +705,13 @@ uint32_t vkvg_surface_get_reference_count (VkvgSurface surf);
  */
 vkvg_public
 void vkvg_surface_destroy (VkvgSurface surf);
+/**
+ * @brief Query the current status of the surface
+ * @param The vkvg surface to query the status for.
+ * @return The current surface status.
+ */
+vkvg_public
+vkvg_status_t vkvg_surface_status (VkvgSurface surf);
 /**
  * @brief Clear the surface content, alpha is also set to 0 resulting in a transparent image.
  *
@@ -743,16 +753,18 @@ uint32_t vkvg_surface_get_height (VkvgSurface surf);
  * @brief Write surface content to a png file on disk.
  * @param The surface to save on disk.
  * @param The png file path.
+ * @return SUCCESS or not.
  */
 vkvg_public
-void vkvg_surface_write_to_png (VkvgSurface surf, const char* path);
+vkvg_status_t vkvg_surface_write_to_png (VkvgSurface surf, const char* path);
 /**
  * @brief Save surface to memory
  * @param The surface to save
  * @param A valid pointer on cpu memory large enough to contain surface pixels (stride * height)
+ * @return SUCCESS or not.
  */
 vkvg_public
-void vkvg_surface_write_to_memory (VkvgSurface surf, unsigned char* const bitmap);
+vkvg_status_t vkvg_surface_write_to_memory (VkvgSurface surf, unsigned char* const bitmap);
 /**
  * @brief Explicitly resolve a multisampled surface.
  *
index 0aef28ff28e33dffcf6000f8070538d3d41e3157..0d5cec6f19ac590b95b5714873701547b8cbd1ca 100644 (file)
@@ -53,6 +53,10 @@ VkvgContext vkvg_create(VkvgSurface surf)
                dev->status = VKVG_STATUS_NO_MEMORY;
                return NULL;
        }
+       if (!surf || surf->status) {
+               ctx->status = VKVG_STATUS_INVALID_SURFACE;
+               return ctx;
+       }
 
        ctx->sizePoints         = VKVG_PTS_SIZE;
        ctx->sizeVertices       = ctx->sizeVBO = VKVG_VBO_SIZE;
index 1677399333c5a9dcf633357d36e43e196ca4a624..5f0d19be463fa26b66b8fff842107246976a56f3 100644 (file)
 if (vkh_phyinfo_try_get_extension_properties(pi, #ext, NULL))  \
        enabledExts[enabledExtsCount++] = #ext;                                         \
 }
+void _device_init (VkvgDevice dev, VkInstance inst, VkPhysicalDevice phy, VkDevice vkdev, uint32_t qFamIdx, uint32_t qIndex, VkSampleCountFlags samples, bool deferredResolve) {
+       dev->instance = inst;
+       dev->hdpi       = 72;
+       dev->vdpi       = 72;
+       dev->samples= samples;
+       dev->deferredResolve = deferredResolve;
+       dev->vkDev      = vkdev;
+       dev->phy        = phy;
+
+#if VKVG_DBG_STATS
+       dev->debug_stats = (vkvg_debug_stats_t) {0};
+#endif
+
+       VkFormat format = FB_COLOR_FORMAT;
+
+       _check_best_image_tiling(dev, format);
+       if (dev->status != VKVG_STATUS_SUCCESS)
+               return;
+
+       if (!_init_function_pointers (dev)){
+               dev->status = VKVG_STATUS_NULL_POINTER;
+               return;
+       }
+
+       VkhPhyInfo phyInfos = vkh_phyinfo_create (dev->phy, NULL);
+
+       dev->phyMemProps = phyInfos->memProps;
+       dev->gQueue = vkh_queue_create ((VkhDevice)dev, qFamIdx, qIndex);
+       MUTEX_INIT (&dev->gQMutex);
+
+       vkh_phyinfo_destroy (phyInfos);
+
+       VmaAllocatorCreateInfo allocatorInfo = {
+               .physicalDevice = phy,
+               .device = vkdev
+       };
+       vmaCreateAllocator(&allocatorInfo, &dev->allocator);
+
+       dev->lastCtx= NULL;
+
+       dev->cmdPool= vkh_cmd_pool_create               ((VkhDevice)dev, dev->gQueue->familyIndex, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
+       dev->cmd        = vkh_cmd_buff_create           ((VkhDevice)dev, dev->cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+       dev->fence      = vkh_fence_create_signaled ((VkhDevice)dev);
+
+       _create_pipeline_cache          (dev);
+       _init_fonts_cache                       (dev);
+       if (dev->deferredResolve || dev->samples == VK_SAMPLE_COUNT_1_BIT){
+               dev->renderPass = _createRenderPassNoResolve (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD);
+               dev->renderPass_ClearStencil = _createRenderPassNoResolve (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_CLEAR);
+               dev->renderPass_ClearAll = _createRenderPassNoResolve (dev, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_CLEAR);
+       }else{
+               dev->renderPass = _createRenderPassMS (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD);
+               dev->renderPass_ClearStencil = _createRenderPassMS (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_CLEAR);
+               dev->renderPass_ClearAll = _createRenderPassMS (dev, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_CLEAR);
+       }
+       _createDescriptorSetLayout      (dev);
+       _setupPipelines                         (dev);
+
+       _create_empty_texture           (dev, format, dev->supportedTiling);
+
+#if defined(DEBUG) && defined (VKVG_DBG_UTILS)
+       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_POOL, (uint64_t)dev->cmdPool, "Device Cmd Pool");
+       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)dev->cmd, "Device Cmd Buff");
+       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_FENCE, (uint64_t)dev->fence, "Device Fence");
+       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_RENDER_PASS, (uint64_t)dev->renderPass, "RP load img/stencil");
+       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_RENDER_PASS, (uint64_t)dev->renderPass_ClearStencil, "RP clear stencil");
+       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_RENDER_PASS, (uint64_t)dev->renderPass_ClearAll, "RP clear all");
+
+       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, (uint64_t)dev->dslSrc, "DSLayout SOURCE");
+       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, (uint64_t)dev->dslFont, "DSLayout FONT");
+       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, (uint64_t)dev->dslGrad, "DSLayout GRADIENT");
+       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE_LAYOUT, (uint64_t)dev->pipelineLayout, "PLLayout dev");
+
+#ifndef __APPLE__
+       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipelinePolyFill, "PL Poly fill");
+#endif
+       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipelineClipping, "PL Clipping");
+       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipe_OVER, "PL draw Over");
+       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipe_SUB, "PL draw Substract");
+       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipe_CLEAR, "PL draw Clear");
+
+       vkh_image_set_name(dev->emptyImg, "empty IMG");
+       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_IMAGE_VIEW, (uint64_t)vkh_image_get_view(dev->emptyImg), "empty IMG VIEW");
+       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_SAMPLER, (uint64_t)vkh_image_get_sampler(dev->emptyImg), "empty IMG SAMPLER");
+#endif
+       dev->status = VKVG_STATUS_SUCCESS;
+}
 
 VkvgDevice vkvg_device_create(VkSampleCountFlags samples, bool deferredResolve) {
+       LOG(VKVG_LOG_INFO, "CREATE Device\n");
+       VkvgDevice dev = (vkvg_device*)calloc(1,sizeof(vkvg_device));
+       if (!dev) {
+               LOG(VKVG_LOG_ERR, "CREATE Device failed, no memory\n");
+               exit(-1);
+       }
+
+       dev->references = 1;
+
        const char* enabledExts [10];
-    const char* enabledLayers[10];
-    uint32_t enabledExtsCount = 0, enabledLayersCount = 0, phyCount = 0;
+       const char* enabledLayers[10];
+       uint32_t enabledExtsCount = 0, enabledLayersCount = 0, phyCount = 0;
 
-    vkh_layers_check_init();
+       vkh_layers_check_init();
 
 #ifdef VKVG_USE_VALIDATION
-    if (vkh_layer_is_present("VK_LAYER_KHRONOS_validation"))
-        enabledLayers[enabledLayersCount++] = "VK_LAYER_KHRONOS_validation";
+       if (vkh_layer_is_present("VK_LAYER_KHRONOS_validation"))
+               enabledLayers[enabledLayersCount++] = "VK_LAYER_KHRONOS_validation";
 #endif
 
 #ifdef VKVG_USE_RENDERDOC
-    if (vkh_layer_is_present("VK_LAYER_RENDERDOC_Capture"))
-        enabledLayers[enabledLayersCount++] = "VK_LAYER_RENDERDOC_Capture";
+       if (vkh_layer_is_present("VK_LAYER_RENDERDOC_Capture"))
+               enabledLayers[enabledLayersCount++] = "VK_LAYER_RENDERDOC_Capture";
 #endif
-    vkh_layers_check_release();
+       vkh_layers_check_release();
 
-    vkh_instance_extensions_check_init ();
+       vkh_instance_extensions_check_init ();
 
 #if defined(DEBUG) && defined (VKVG_DBG_UTILS)
-    bool dbgUtilsSupported = vkh_instance_extension_supported("VK_EXT_debug_utils");
+       bool dbgUtilsSupported = vkh_instance_extension_supported("VK_EXT_debug_utils");
         if (dbgUtilsSupported)
                enabledExts[enabledExtsCount++] = "VK_EXT_debug_utils";
 #endif
-    if (vkh_instance_extension_supported("VK_KHR_get_physical_device_properties2"))
+       if (vkh_instance_extension_supported("VK_KHR_get_physical_device_properties2"))
                enabledExts[enabledExtsCount++] = "VK_KHR_get_physical_device_properties2";
 
-    vkh_instance_extensions_check_release();
+       vkh_instance_extensions_check_release();
 
        VkhApp app =  vkh_app_create(1, 2, "vkvg", enabledLayersCount, enabledLayers, enabledExtsCount, enabledExts);
 
@@ -71,8 +167,9 @@ VkvgDevice vkvg_device_create(VkSampleCountFlags samples, bool deferredResolve)
 #endif
        VkhPhyInfo* phys = vkh_app_get_phyinfos (app, &phyCount, VK_NULL_HANDLE);
        if (phyCount == 0) {
+               dev->status = VKVG_STATUS_DEVICE_ERROR;
                vkh_app_destroy (app);
-               return NULL;
+               return dev;
        }
 
        VkhPhyInfo pi = 0;
@@ -82,9 +179,10 @@ VkvgDevice vkvg_device_create(VkSampleCountFlags samples, bool deferredResolve)
 
        if (!(pi->properties.limits.framebufferColorSampleCounts&samples)) {
                LOG(VKVG_LOG_ERR, "CREATE Device failed: sample count not supported: %d\n", samples);
+               dev->status = VKVG_STATUS_DEVICE_ERROR;
                vkh_app_free_phyinfos (phyCount, phys);
                vkh_app_destroy (app);
-               return NULL;
+               return dev;
        }
 
        uint32_t qCount = 0;
@@ -127,18 +225,18 @@ VkvgDevice vkvg_device_create(VkSampleCountFlags samples, bool deferredResolve)
 
        VkhDevice vkhd = vkh_device_create(app, pi, &device_info);
 
-       VkvgDevice vkvgDev = vkvg_device_create_from_vk_multisample (
+       _device_init (dev,
                                vkh_app_get_inst(app),
                                vkh_device_get_phy(vkhd),
                                vkh_device_get_vkdev(vkhd),
                                pi->gQueue, 0,
                                samples, deferredResolve);
 
-       vkvgDev->vkhDev = vkhd;
+       dev->vkhDev = vkhd;
 
        vkh_app_free_phyinfos (phyCount, phys);
 
-       return vkvgDev;
+       return dev;
 }
 VkvgDevice vkvg_device_create_from_vk(VkInstance inst, VkPhysicalDevice phy, VkDevice vkdev, uint32_t qFamIdx, uint32_t qIndex)
 {
@@ -146,97 +244,14 @@ VkvgDevice vkvg_device_create_from_vk(VkInstance inst, VkPhysicalDevice phy, VkD
 }
 VkvgDevice vkvg_device_create_from_vk_multisample(VkInstance inst, VkPhysicalDevice phy, VkDevice vkdev, uint32_t qFamIdx, uint32_t qIndex, VkSampleCountFlags samples, bool deferredResolve)
 {
-       LOG(VKVG_LOG_INFO, "CREATE Device: qFam = %d; qIdx = %d\n", qFamIdx, qIndex);
-
+       LOG(VKVG_LOG_INFO, "CREATE Device from vk: qFam = %d; qIdx = %d\n", qFamIdx, qIndex);
        VkvgDevice dev = (vkvg_device*)calloc(1,sizeof(vkvg_device));
-
-       dev->instance = inst;
-       dev->hdpi       = 72;
-       dev->vdpi       = 72;
-       dev->samples= samples;
-       dev->deferredResolve = deferredResolve;
-       dev->vkDev      = vkdev;
-       dev->phy        = phy;
-       dev->status = VKVG_STATUS_SUCCESS;
-
-#if VKVG_DBG_STATS
-       dev->debug_stats = (vkvg_debug_stats_t) {0};
-#endif 
-
-       VkFormat format = FB_COLOR_FORMAT;
-
-       _check_best_image_tiling(dev, format);
-       if (dev->status != VKVG_STATUS_SUCCESS)         
-               return dev;     
-
-       if (!_init_function_pointers (dev)){
-               dev->status = VKVG_STATUS_NULL_POINTER;
-               return dev;
-       }
-
-       VkhPhyInfo phyInfos = vkh_phyinfo_create (dev->phy, NULL);
-
-       dev->phyMemProps = phyInfos->memProps;
-       dev->gQueue = vkh_queue_create ((VkhDevice)dev, qFamIdx, qIndex);
-       MUTEX_INIT (&dev->gQMutex);
-
-       vkh_phyinfo_destroy (phyInfos);
-
-       VmaAllocatorCreateInfo allocatorInfo = {
-               .physicalDevice = phy,
-               .device = vkdev
-       };
-       vmaCreateAllocator(&allocatorInfo, &dev->allocator);
-
-       dev->lastCtx= NULL;
-
-       dev->cmdPool= vkh_cmd_pool_create               ((VkhDevice)dev, dev->gQueue->familyIndex, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
-       dev->cmd        = vkh_cmd_buff_create           ((VkhDevice)dev, dev->cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
-       dev->fence      = vkh_fence_create_signaled ((VkhDevice)dev);
-
-       _create_pipeline_cache          (dev);
-       _init_fonts_cache                       (dev);
-       if (dev->deferredResolve || dev->samples == VK_SAMPLE_COUNT_1_BIT){
-               dev->renderPass = _createRenderPassNoResolve (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD);
-               dev->renderPass_ClearStencil = _createRenderPassNoResolve (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_CLEAR);
-               dev->renderPass_ClearAll = _createRenderPassNoResolve (dev, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_CLEAR);
-       }else{
-               dev->renderPass = _createRenderPassMS (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD);
-               dev->renderPass_ClearStencil = _createRenderPassMS (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_CLEAR);
-               dev->renderPass_ClearAll = _createRenderPassMS (dev, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_CLEAR);
+       if (!dev) {
+               LOG(VKVG_LOG_ERR, "CREATE Device failed, no memory\n");
+               exit(-1);
        }
-       _createDescriptorSetLayout      (dev);
-       _setupPipelines                         (dev);
-
-       _create_empty_texture           (dev, format, dev->supportedTiling);
-
        dev->references = 1;
-
-#if defined(DEBUG) && defined (VKVG_DBG_UTILS)
-       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_POOL, (uint64_t)dev->cmdPool, "Device Cmd Pool");
-       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)dev->cmd, "Device Cmd Buff");
-       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_FENCE, (uint64_t)dev->fence, "Device Fence");
-       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_RENDER_PASS, (uint64_t)dev->renderPass, "RP load img/stencil");
-       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_RENDER_PASS, (uint64_t)dev->renderPass_ClearStencil, "RP clear stencil");
-       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_RENDER_PASS, (uint64_t)dev->renderPass_ClearAll, "RP clear all");
-
-       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, (uint64_t)dev->dslSrc, "DSLayout SOURCE");
-       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, (uint64_t)dev->dslFont, "DSLayout FONT");
-       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, (uint64_t)dev->dslGrad, "DSLayout GRADIENT");
-       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE_LAYOUT, (uint64_t)dev->pipelineLayout, "PLLayout dev");
-
-#ifndef __APPLE__
-       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipelinePolyFill, "PL Poly fill");
-#endif
-       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipelineClipping, "PL Clipping");
-       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipe_OVER, "PL draw Over");
-       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipe_SUB, "PL draw Substract");
-       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipe_CLEAR, "PL draw Clear");
-
-       vkh_image_set_name(dev->emptyImg, "empty IMG");
-       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_IMAGE_VIEW, (uint64_t)vkh_image_get_view(dev->emptyImg), "empty IMG VIEW");
-       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_SAMPLER, (uint64_t)vkh_image_get_sampler(dev->emptyImg), "empty IMG SAMPLER");
-#endif
+       _device_init(dev, inst, phy, vkdev, qFamIdx, qIndex, samples, deferredResolve);
        return dev;
 }
 
index 916277536970d6b38ea931c54bf1d7285475574e..89ff376411a96122dbb416f783e3fd68cc553888 100644 (file)
 
 #define max(x,y)
 void vkvg_surface_clear (VkvgSurface surf) {
+       if (surf->status)
+               return;
        _clear_surface(surf, VK_IMAGE_ASPECT_STENCIL_BIT|VK_IMAGE_ASPECT_COLOR_BIT);
 }
 VkvgSurface vkvg_surface_create (VkvgDevice dev, uint32_t width, uint32_t height){
        VkvgSurface surf = _create_surface(dev, FB_COLOR_FORMAT);
-       if (!surf)
-               return NULL;
+       if (!surf || surf->status)
+               return surf;
 
        surf->width = MAX(1, width);
        surf->height = MAX(1, height);
@@ -44,15 +46,19 @@ VkvgSurface vkvg_surface_create (VkvgDevice dev, uint32_t width, uint32_t height
 
        _create_surface_images (surf);
 
-       surf->references = 1;
        vkvg_device_reference (surf->dev);
-
+       dev->status = VKVG_STATUS_SUCCESS;
        return surf;
 }
 VkvgSurface vkvg_surface_create_for_VkhImage (VkvgDevice dev, void* vkhImg) {
        VkvgSurface surf = _create_surface(dev, FB_COLOR_FORMAT);
-       if (!surf)
-               return NULL;
+       if (!surf || surf->status)
+               return surf;
+
+       if (!vkhImg) {
+               surf->status = VKVG_STATUS_INVALID_IMAGE;
+               return surf;
+       }
 
        VkhImage img = (VkhImage)vkhImg;
        surf->width = img->infos.extent.width;
@@ -63,20 +69,23 @@ VkvgSurface vkvg_surface_create_for_VkhImage (VkvgDevice dev, void* vkhImg) {
        vkh_image_create_sampler(img, VK_FILTER_NEAREST, VK_FILTER_NEAREST,
                                                         VK_SAMPLER_MIPMAP_MODE_NEAREST,VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
 
-       _create_surface_secondary_images   (surf);
-       _create_framebuffer                     (surf);
-       _clear_surface                          (surf, VK_IMAGE_ASPECT_STENCIL_BIT);
+       _create_surface_secondary_images        (surf);
+       _create_framebuffer                                     (surf);
+       _clear_surface                                          (surf, VK_IMAGE_ASPECT_STENCIL_BIT);
 
-       surf->references = 1;
        vkvg_device_reference (surf->dev);
-
+       dev->status = VKVG_STATUS_SUCCESS;
        return surf;
 }
 //TODO: it would be better to blit in original size and create ms final image with dest surf dims
 VkvgSurface vkvg_surface_create_from_bitmap (VkvgDevice dev, unsigned char* img, uint32_t width, uint32_t height) {
        VkvgSurface surf = _create_surface(dev, FB_COLOR_FORMAT);
-       if (!surf)
-               return NULL;
+       if (!surf || surf->status)
+               return surf;
+       if (!img || width <= 0 || height <= 0) {
+               surf->status = VKVG_STATUS_INVALID_IMAGE;
+               return surf;
+       }
 
        surf->width = MAX(1, width);
        surf->height = MAX(1, height);
@@ -169,9 +178,8 @@ VkvgSurface vkvg_surface_create_from_bitmap (VkvgDevice dev, unsigned char* img,
 
        vkh_image_destroy       (tmpImg);
 
-       surf->references = 1;
        vkvg_device_reference (surf->dev);
-
+       dev->status = VKVG_STATUS_SUCCESS;
        return surf;
 }
 VkvgSurface vkvg_surface_create_from_image (VkvgDevice dev, const char* filePath) {
@@ -219,6 +227,8 @@ uint32_t vkvg_surface_get_reference_count (VkvgSurface surf) {
 
 VkImage vkvg_surface_get_vk_image(VkvgSurface surf)
 {
+       if (surf->status)
+               return NULL;
        if (surf->dev->deferredResolve)
                _explicit_ms_resolve(surf);
        return vkh_image_get_vkimage (surf->img);
@@ -237,10 +247,18 @@ uint32_t vkvg_surface_get_height (VkvgSurface surf) {
        return surf->height;
 }
 
-void vkvg_surface_write_to_png (VkvgSurface surf, const char* path){
+vkvg_status_t vkvg_surface_write_to_png (VkvgSurface surf, const char* path){
+       if (surf->status) {
+               LOG(VKVG_LOG_ERR, "vkvg_surface_write_to_png failed, invalid status: %d\n", surf->status);
+               return VKVG_STATUS_INVALID_STATUS;
+       }
        if (surf->dev->pngStagFormat == VK_FORMAT_UNDEFINED) {
                LOG(VKVG_LOG_ERR, "no suitable image format for png write\n");
-               return;
+               return VKVG_STATUS_INVALID_FORMAT;
+       }
+       if (!path) {
+               LOG(VKVG_LOG_ERR, "vkvg_surface_write_to_png failed, null path\n");
+               return VKVG_STATUS_WRITE_ERROR;
        }
 
        VkImageSubresourceLayers imgSubResLayers = {VK_IMAGE_ASPECT_COLOR_BIT,0,0,1};
@@ -324,9 +342,20 @@ void vkvg_surface_write_to_png (VkvgSurface surf, const char* path){
 
        vkh_image_unmap (stagImgLinear);
        vkh_image_destroy (stagImgLinear);
+
+       return VKVG_STATUS_SUCCESS;
 }
 
-void vkvg_surface_write_to_memory (VkvgSurface surf, unsigned char* const bitmap){
+vkvg_status_t vkvg_surface_write_to_memory (VkvgSurface surf, unsigned char* const bitmap){
+       if (surf->status) {
+               LOG(VKVG_LOG_ERR, "vkvg_surface_write_to_memory failed, invalid status: %d\n", surf->status);
+               return VKVG_STATUS_INVALID_STATUS;
+       }
+       if (!bitmap) {
+               LOG(VKVG_LOG_ERR, "vkvg_surface_write_to_memory failed, null path\n");
+               return VKVG_STATUS_INVALID_IMAGE;
+       }
+
        VkImageSubresourceLayers imgSubResLayers = {VK_IMAGE_ASPECT_COLOR_BIT,0,0,1};
        VkvgDevice dev = surf->dev;
 
@@ -373,4 +402,6 @@ void vkvg_surface_write_to_memory (VkvgSurface surf, unsigned char* const bitmap
 
        vkh_image_unmap (stagImg);
        vkh_image_destroy (stagImg);
+
+       return VKVG_STATUS_SUCCESS;
 }
index 19cf0d8e8beca8a20497153f11c3f80e1584207b..a8cc8ff6bece6cb3d9d144ff275c1eb419fad416 100644 (file)
@@ -174,18 +174,17 @@ void _create_surface_images (VkvgSurface surf) {
 #endif
 }
 VkvgSurface _create_surface (VkvgDevice dev, VkFormat format) {        
-       if (dev->status != VKVG_STATUS_SUCCESS)
-               return NULL;
-
        VkvgSurface surf = (vkvg_surface*)calloc(1,sizeof(vkvg_surface));
        if (!surf) {
                dev->status = VKVG_STATUS_NO_MEMORY;
                return NULL;
        }
-
+       surf->references = 1;
+       if (dev->status != VKVG_STATUS_SUCCESS) {
+               surf->status = VKVG_STATUS_DEVICE_ERROR;
+               return surf;
+       }
        surf->dev = dev;
        surf->format = format;
-
-       dev->status = VKVG_STATUS_SUCCESS;
        return surf;
 }
index e6b474cd1db1da2deb311b3c5f04edc97908f6aa..506cd445f3f4f443c43ff06ab295200047417a95 100644 (file)
 #include "vkh.h"
 
 typedef struct _vkvg_surface_t {
-       VkvgDevice      dev;
-       uint32_t        width;
-       uint32_t        height;
-       VkFormat        format;
-       VkFramebuffer fb;
-       VkhImage        img;
-       VkhImage        imgMS;
-       VkhImage        stencil;
-       uint32_t        references;
-       bool            new;
+       VkvgDevice              dev;
+       uint32_t                width;
+       uint32_t                height;
+       VkFormat                format;
+       VkFramebuffer   fb;
+       VkhImage                img;
+       VkhImage                imgMS;
+       VkhImage                stencil;
+       uint32_t                references;
+       vkvg_status_t   status;                                 /**< Current status of surface, affected by last operation */
+       bool                    new;
 }vkvg_surface;
 
 void _explicit_ms_resolve (VkvgSurface surf);