From: Jean-Philippe Bruyère Date: Mon, 24 Jan 2022 22:16:13 +0000 (+0100) Subject: clean dev, surf, ctx error handling X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=e32b2212f0ebd9f988b3fca2433c6db69bb29992;p=jp%2Fvkvg.git clean dev, surf, ctx error handling --- diff --git a/include/vkvg.h b/include/vkvg.h index 2da756e..06539e8 100644 --- a/include/vkvg.h +++ b/include/vkvg.h @@ -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. * diff --git a/src/vkvg_context.c b/src/vkvg_context.c index 0aef28f..0d5cec6 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -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; diff --git a/src/vkvg_device.c b/src/vkvg_device.c index 1677399..5f0d19b 100644 --- a/src/vkvg_device.c +++ b/src/vkvg_device.c @@ -29,36 +29,132 @@ 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; } diff --git a/src/vkvg_surface.c b/src/vkvg_surface.c index 9162775..89ff376 100644 --- a/src/vkvg_surface.c +++ b/src/vkvg_surface.c @@ -31,12 +31,14 @@ #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; } diff --git a/src/vkvg_surface_internal.c b/src/vkvg_surface_internal.c index 19cf0d8..a8cc8ff 100644 --- a/src/vkvg_surface_internal.c +++ b/src/vkvg_surface_internal.c @@ -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; } diff --git a/src/vkvg_surface_internal.h b/src/vkvg_surface_internal.h index e6b474c..506cd44 100644 --- a/src/vkvg_surface_internal.h +++ b/src/vkvg_surface_internal.h @@ -27,16 +27,17 @@ #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);