summaryrefslogtreecommitdiffstatsci
path: root/src/vkvg_device_internal.h
blob: 37cb29f735750b231c82e6583efd223defa83ba1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Copyright (c) 2018-2026 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
//
// 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 */
    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