// Copyright (c) 2018-2026 Jean-Philippe Bruyère // // This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) #ifndef VKVG_DEVICE_INTERNAL_H #define VKVG_DEVICE_INTERNAL_H #include "vkvg_fonts.h" #include "vkvg_internal.h" #define STENCIL_FILL_MASK 0x80 #define STENCIL_CLIP_MASK 0x7F #define STENCIL_ALL_BIT 0xFF #define VKVG_MAX_CACHED_CONTEXT_COUNT 2 extern PFN_vkCmdBindPipeline CmdBindPipeline; extern PFN_vkCmdBindDescriptorSets CmdBindDescriptorSets; extern PFN_vkCmdBindIndexBuffer CmdBindIndexBuffer; extern PFN_vkCmdBindVertexBuffers CmdBindVertexBuffers; extern PFN_vkCmdDrawIndexed CmdDrawIndexed; extern PFN_vkCmdDraw CmdDraw; extern PFN_vkCmdSetStencilReference CmdSetStencilReference; extern PFN_vkCmdBeginRenderPass CmdBeginRenderPass; extern PFN_vkCmdEndRenderPass CmdEndRenderPass; extern PFN_vkCmdSetViewport CmdSetViewport; extern PFN_vkCmdSetScissor CmdSetScissor; extern PFN_vkCmdPushConstants CmdPushConstants; extern PFN_vkWaitForFences WaitForFences; extern PFN_vkResetFences ResetFences; extern PFN_vkResetCommandBuffer ResetCommandBuffer; typedef struct _cached_ctx { thrd_t thread; VkvgContext ctx; struct _cached_ctx* pNext; } _cached_ctx; typedef struct _surface_class* SurfaceClass; DIAGNOSTIC_DISABLE_UNUSED CTOR_ARRAY(SurfaceClass) ARRAY_DEL_ELT(SurfaceClass) DIAGNOSTIC_RESTORE_UNUSED typedef struct _vkvg_device_t { vkvg_status_t status; /**< Current status of device, affected by last operation */ VkDevice vkDev; /**< Vulkan Logical Device */ VkPhysicalDevice phy; /**< Vulkan Physical device */ VkInstance instance; /**< Vulkan instance */ VkPhysicalDeviceMemoryProperties phyMemProps; /**< Vulkan Physical device memory properties */ VkDeviceSize minUniformBufferOffsetAlignment; /**< stored for dynamic uniform buffer offsets */ VkSampleCountFlags framebufferColorSampleCounts; VkImageTiling supportedTiling; /**< Supported image tiling for surface, 0xFF=no support */ VkFormat stencilFormat; /**< Supported vulkan image format for stencil */ VkImageAspectFlags stencilAspectFlag; /**< stencil only or depth stencil, could be solved by VK_KHR_separate_depth_stencil_layouts*/ VkFormat pngStagFormat; /**< Supported vulkan image format png write staging img */ VkImageTiling pngStagTiling; /**< tiling for the blit operation */ mtx_t mutex; /**< protect device access (queue, cahes, ...)from ctxs in separate threads */ bool threadAware; /**< if true, mutex is created and guard device queue and caches access */ VkhQueue gQueue; /**< Vulkan Queue with Graphic flag */ atomic_int references; /**< Reference count, prevent destroying device if still in use */ VkCommandPool cmdPool; /**< Global command pool for processing on surfaces without context */ VkCommandBuffer cmd; /**< Global command buffer */ VkFence fence; /**< this fence is kept signaled when idle, wait and reset are called before each recording. */ VkPipelineCache pipelineCache; /**< speed up startup by caching configured pipelines on disk */ VkPipelineLayout pipelineLayout; /**< layout common to all pipelines */ VkDescriptorSetLayout dslFont; /**< font cache descriptors layout */ VkDescriptorSetLayout dslSrc; /**< context source surface descriptors layout */ VkDescriptorSetLayout dslGrad; /**< context gradient descriptors layout */ VkSampler smpFont; /**< font immutable sampler */ VkDescriptorPool descriptorPool; VkDescriptorSet dummySrcSet; VkDescriptorSet dummyGradSet; VkhDevice vkhDev; bool holdVkhDev; /**< vkhDevice should be destroyed */ bool deferredResolve; /**< if true, resolve only on context destruction and set as source */ font_cache_t* fontCache; /**< Store everything relative to common font caching system */ VkvgContext lastCtx; /**< last element of double linked list of context, used to trigger font caching system update on all contexts*/ int32_t cachedContextMaxCount; /**< Maximum context cache element count.*/ int32_t cachedContextCount; /**< Current context cache element count.*/ _cached_ctx* cachedContextLast; /**< Last element of single linked list of saved context for fast reuse.*/ #ifdef VKVG_WIRED_DEBUG VkPipeline pipelineWired; VkPipeline pipelineLineList; #endif #if VKVG_DBG_STATS vkvg_debug_stats_t debug_stats; /**< debug statistics on memory usage and vulkan ressources */ #endif array_SurfaceClass surfaceClasses; } vkvg_device; #define LOCK_DEVICE \ if (dev->threadAware) \ mtx_lock(&dev->mutex); #define UNLOCK_DEVICE \ if (dev->threadAware) \ mtx_unlock(&dev->mutex); bool _device_try_get_phyinfo(VkhPhyInfo* phys, uint32_t phyCount, VkPhysicalDeviceType gpuType, VkhPhyInfo* phy); bool _device_init_function_pointers(VkvgDevice dev); void _device_create_empty_texture(VkvgDevice dev, VkFormat format, VkImageTiling tiling); void _device_get_best_image_tiling(VkvgDevice dev, VkFormat format, VkImageTiling* pTiling); void _device_check_best_image_tiling(VkvgDevice dev, VkFormat format); void _device_create_pipeline_cache(VkvgDevice dev); VkRenderPass _device_createRenderPassMS(VkvgDevice dev, VkAttachmentLoadOp loadOp, VkAttachmentLoadOp stencilLoadOp); VkRenderPass _device_createRenderPassNoResolve(VkvgDevice dev, VkAttachmentLoadOp loadOp, VkAttachmentLoadOp stencilLoadOp); void _device_setupPipelines(VkvgDevice dev); void _device_createDescriptorSetLayout(VkvgDevice dev); void _device_allocalte_dummy_descriptors(VkvgDevice dev); void _device_wait_idle(VkvgDevice dev); void _device_wait_and_reset_device_fence(VkvgDevice dev); void _device_submit_cmd(VkvgDevice dev, VkCommandBuffer* cmd, VkFence fence); bool _device_try_get_cached_context(VkvgDevice dev, VkvgContext* pCtx); void _device_store_context(VkvgContext ctx); #endif