xref: /aosp_15_r20/external/mesa3d/src/microsoft/vulkan/dzn_private.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © Microsoft Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #ifndef DZN_PRIVATE_H
25 #define DZN_PRIVATE_H
26 
27 #define COBJMACROS
28 
29 #include "vk_command_pool.h"
30 #include "vk_command_buffer.h"
31 #include "vk_cmd_queue.h"
32 #include "vk_debug_report.h"
33 #include "vk_descriptor_set_layout.h"
34 #include "vk_device.h"
35 #include "vk_image.h"
36 #include "vk_log.h"
37 #include "vk_physical_device.h"
38 #include "vk_pipeline_layout.h"
39 #include "vk_render_pass.h"
40 #include "vk_sync.h"
41 #include "vk_sync_binary.h"
42 #include "vk_queue.h"
43 #include "vk_shader_module.h"
44 #include "wsi_common.h"
45 
46 #include "util/bitset.h"
47 #include "util/blob.h"
48 #include "util/hash_table.h"
49 #include "util/u_dynarray.h"
50 #include "util/log.h"
51 #include "util/xmlconfig.h"
52 
53 #include "shader_enums.h"
54 
55 #include "dzn_entrypoints.h"
56 #include "dzn_nir.h"
57 #include "dzn_physical_device_enum.h"
58 
59 #include <vulkan/vulkan.h>
60 #include <vulkan/vk_icd.h>
61 
62 #define D3D12_IGNORE_SDK_LAYERS
63 #include <unknwn.h>
64 #include <directx/d3d12.h>
65 
66 #include "spirv_to_dxil.h"
67 #include "dzn_abi_helper.h"
68 
69 #define DZN_SWAP(t, a, b) \
70    do { \
71       t __tmp = a; \
72       a = b; \
73       b = __tmp; \
74    } while (0)
75 
76 #define dzn_stub() unreachable("Unsupported feature")
77 
78 #if defined(VK_USE_PLATFORM_WIN32_KHR) || \
79     defined(VK_USE_PLATFORM_WAYLAND_KHR) || \
80     defined(VK_USE_PLATFORM_XCB_KHR) || \
81     defined(VK_USE_PLATFORM_XLIB_KHR)
82 #define DZN_USE_WSI_PLATFORM
83 #endif
84 
85 struct dxil_validator;
86 struct util_dl_library;
87 
88 struct dzn_instance;
89 struct dzn_device;
90 
91 struct dzn_meta_indirect_draw {
92    ID3D12RootSignature *root_sig;
93    ID3D12PipelineState *pipeline_state;
94 };
95 
96 enum dzn_index_type {
97    DZN_NO_INDEX,
98    DZN_INDEX_2B,
99    DZN_INDEX_4B,
100    DZN_INDEX_2B_WITH_PRIM_RESTART,
101    DZN_INDEX_4B_WITH_PRIM_RESTART,
102    DZN_NUM_INDEX_TYPE,
103 };
104 
105 static inline enum dzn_index_type
dzn_index_type_from_size(uint8_t index_size)106 dzn_index_type_from_size(uint8_t index_size)
107 {
108    switch (index_size) {
109    case 0: return DZN_NO_INDEX;
110    case 2: return DZN_INDEX_2B;
111    case 4: return DZN_INDEX_4B;
112    default: unreachable("Invalid index size");
113    }
114 }
115 
116 static inline enum dzn_index_type
dzn_index_type_from_dxgi_format(DXGI_FORMAT format,bool prim_restart)117 dzn_index_type_from_dxgi_format(DXGI_FORMAT format, bool prim_restart)
118 {
119    switch (format) {
120    case DXGI_FORMAT_UNKNOWN: return DZN_NO_INDEX;
121    case DXGI_FORMAT_R16_UINT:
122       return prim_restart ? DZN_INDEX_2B_WITH_PRIM_RESTART : DZN_INDEX_2B;
123    case DXGI_FORMAT_R32_UINT:
124       return prim_restart ? DZN_INDEX_4B_WITH_PRIM_RESTART : DZN_INDEX_4B;
125    default: unreachable("Invalid index format");
126    }
127 }
128 
129 static inline uint8_t
dzn_index_size(enum dzn_index_type type)130 dzn_index_size(enum dzn_index_type type)
131 {
132    switch (type) {
133    case DZN_NO_INDEX:
134       return 0;
135    case DZN_INDEX_2B_WITH_PRIM_RESTART:
136    case DZN_INDEX_2B:
137       return 2;
138    case DZN_INDEX_4B_WITH_PRIM_RESTART:
139    case DZN_INDEX_4B:
140       return 4;
141    default: unreachable("Invalid index type");
142    }
143 }
144 
145 struct dzn_meta_triangle_fan_rewrite_index {
146    ID3D12RootSignature *root_sig;
147    ID3D12PipelineState *pipeline_state;
148    ID3D12CommandSignature *cmd_sig;
149 };
150 
151 struct dzn_meta_blit_key {
152    union {
153       struct {
154          DXGI_FORMAT out_format;
155          uint32_t samples : 6;
156          uint32_t loc : 4;
157          uint32_t out_type : 4;
158          uint32_t sampler_dim : 4;
159          uint32_t src_is_array : 1;
160          uint32_t resolve_mode : 3;
161          uint32_t linear_filter : 1;
162          uint32_t stencil_bit : 4;
163          uint32_t padding : 5;
164       };
165       const uint64_t u64;
166    };
167 };
168 
169 struct dzn_meta_blit {
170    ID3D12RootSignature *root_sig;
171    ID3D12PipelineState *pipeline_state;
172 };
173 
174 struct dzn_meta_blits {
175    mtx_t shaders_lock;
176    D3D12_SHADER_BYTECODE vs;
177    struct hash_table *fs;
178    mtx_t contexts_lock;
179    struct hash_table_u64 *contexts;
180 };
181 
182 const struct dzn_meta_blit *
183 dzn_meta_blits_get_context(struct dzn_device *device,
184                            const struct dzn_meta_blit_key *key);
185 
186 #define MAX_SYNC_TYPES 3
187 #define MAX_QUEUE_FAMILIES 2
188 
189 struct dzn_physical_device {
190    struct vk_physical_device vk;
191 
192    struct vk_physical_device_dispatch_table dispatch;
193 
194    IUnknown *adapter;
195    struct dzn_physical_device_desc desc;
196 
197    uint32_t queue_family_count;
198    struct dzn_queue_family {
199       VkQueueFamilyProperties props;
200       D3D12_COMMAND_QUEUE_DESC desc;
201    } queue_families[MAX_QUEUE_FAMILIES];
202 
203    uint8_t pipeline_cache_uuid[VK_UUID_SIZE];
204    uint8_t device_uuid[VK_UUID_SIZE];
205    uint8_t driver_uuid[VK_UUID_SIZE];
206 
207    struct wsi_device wsi_device;
208 
209    ID3D12Device4 *dev;
210    ID3D12Device10 *dev10;
211    ID3D12Device11 *dev11;
212    ID3D12Device12 *dev12;
213    ID3D12Device13 *dev13;
214    D3D_FEATURE_LEVEL feature_level;
215    D3D_SHADER_MODEL shader_model;
216    D3D_ROOT_SIGNATURE_VERSION root_sig_version;
217    D3D12_FEATURE_DATA_ARCHITECTURE1 architecture;
218    D3D12_FEATURE_DATA_D3D12_OPTIONS options;
219    D3D12_FEATURE_DATA_D3D12_OPTIONS1 options1;
220    D3D12_FEATURE_DATA_D3D12_OPTIONS2 options2;
221    D3D12_FEATURE_DATA_D3D12_OPTIONS3 options3;
222    D3D12_FEATURE_DATA_D3D12_OPTIONS4 options4;
223    D3D12_FEATURE_DATA_D3D12_OPTIONS12 options12;
224    D3D12_FEATURE_DATA_D3D12_OPTIONS13 options13;
225    D3D12_FEATURE_DATA_D3D12_OPTIONS14 options14;
226    D3D12_FEATURE_DATA_D3D12_OPTIONS15 options15;
227    D3D12_FEATURE_DATA_D3D12_OPTIONS16 options16;
228    D3D12_FEATURE_DATA_D3D12_OPTIONS17 options17;
229    D3D12_FEATURE_DATA_D3D12_OPTIONS19 options19;
230    D3D12_FEATURE_DATA_D3D12_OPTIONS21 options21;
231    VkPhysicalDeviceMemoryProperties memory;
232    D3D12_HEAP_FLAGS heap_flags_for_mem_type[VK_MAX_MEMORY_TYPES];
233    const struct vk_sync_type *sync_types[MAX_SYNC_TYPES + 1];
234    float timestamp_period;
235    bool support_a4b4g4r4;
236 };
237 
238 D3D12_FEATURE_DATA_FORMAT_SUPPORT
239 dzn_physical_device_get_format_support(struct dzn_physical_device *pdev,
240                                        VkFormat format,
241                                        VkImageCreateFlags create_flags);
242 
243 uint32_t
244 dzn_physical_device_get_mem_type_mask_for_resource(const struct dzn_physical_device *pdev,
245                                                    const D3D12_RESOURCE_DESC *desc,
246                                                    bool shared);
247 
248 enum dxil_shader_model
249 dzn_get_shader_model(const struct dzn_physical_device *pdev);
250 
251 PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE
252 d3d12_get_serialize_root_sig(struct util_dl_library *d3d12_mod);
253 
254 void
255 d3d12_enable_debug_layer(struct util_dl_library *d3d12_mod, ID3D12DeviceFactory *factory);
256 
257 void
258 d3d12_enable_gpu_validation(struct util_dl_library *d3d12_mod, ID3D12DeviceFactory *factory);
259 
260 ID3D12Device4 *
261 d3d12_create_device(struct util_dl_library *d3d12_mod, IUnknown *adapter, ID3D12DeviceFactory *factory, bool experimental_features);
262 
263 struct dzn_queue {
264    struct vk_queue vk;
265 
266    ID3D12CommandQueue *cmdqueue;
267    ID3D12Fence *fence;
268    uint64_t fence_point;
269 };
270 
271 struct dzn_descriptor_heap {
272    ID3D12DescriptorHeap *heap;
273    SIZE_T cpu_base;
274    uint64_t gpu_base;
275    uint32_t desc_count;
276    uint32_t desc_sz;
277 };
278 
279 struct dzn_device_descriptor_heap {
280    struct dzn_descriptor_heap heap;
281    mtx_t lock;
282    struct util_dynarray slot_freelist;
283    uint32_t next_alloc_slot;
284 };
285 
286 #define NUM_POOL_TYPES D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER + 1
287 
288 struct dzn_device {
289    struct vk_device vk;
290    struct vk_device_extension_table enabled_extensions;
291    struct vk_device_dispatch_table cmd_dispatch;
292 
293    ID3D12Device4 *dev;
294    ID3D12Device10 *dev10;
295    ID3D12Device11 *dev11;
296    ID3D12Device12 *dev12;
297    ID3D12Device13 *dev13;
298    ID3D12DeviceConfiguration *dev_config;
299 
300    struct dzn_meta_indirect_draw indirect_draws[DZN_NUM_INDIRECT_DRAW_TYPES];
301    struct dzn_meta_triangle_fan_rewrite_index triangle_fan[DZN_NUM_INDEX_TYPE];
302    struct dzn_meta_blits blits;
303 
304    struct {
305 #define DZN_QUERY_REFS_SECTION_SIZE 4096
306 #define DZN_QUERY_REFS_ALL_ONES_OFFSET 0
307 #define DZN_QUERY_REFS_ALL_ZEROS_OFFSET (DZN_QUERY_REFS_ALL_ONES_OFFSET + DZN_QUERY_REFS_SECTION_SIZE)
308 #define DZN_QUERY_REFS_RES_SIZE (DZN_QUERY_REFS_ALL_ZEROS_OFFSET + DZN_QUERY_REFS_SECTION_SIZE)
309       ID3D12Resource *refs;
310    } queries;
311 
312    /* Will be the app's graphics queue if there's exactly one, otherwise this will be
313     * a dedicated graphics queue to host swapchain blits.
314     */
315    bool need_swapchain_blits;
316    struct dzn_queue *swapchain_queue;
317 
318    bool bindless;
319    bool support_static_samplers;
320    struct dzn_device_descriptor_heap device_heaps[NUM_POOL_TYPES];
321 };
322 
323 void dzn_meta_finish(struct dzn_device *device);
324 
325 VkResult dzn_meta_init(struct dzn_device *device);
326 
327 const struct dzn_meta_blit *
328 dzn_meta_blits_get_context(struct dzn_device *device,
329                            const struct dzn_meta_blit_key *key);
330 
331 ID3D12RootSignature *
332 dzn_device_create_root_sig(struct dzn_device *device,
333                            const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *desc);
334 
335 struct dzn_device_memory {
336    struct vk_object_base base;
337 
338    struct list_head link;
339 
340    /* Dedicated image/buffer resource. Can be used for import (e.g. from a swapchain)
341     * or just from a dedicated allocation request.
342     */
343    ID3D12Resource *dedicated_res;
344 
345    ID3D12Heap *heap;
346    VkDeviceSize size;
347 
348    /* A buffer-resource spanning the entire heap, used for mapping memory */
349    ID3D12Resource *map_res;
350 
351    VkDeviceSize map_size;
352    void *map;
353 
354    /* If the resource is exportable, this is the pre-created handle for that */
355    HANDLE export_handle;
356 
357    /* These flags need to be added into all resources created on this heap */
358    D3D12_RESOURCE_FLAGS res_flags;
359 };
360 
361 enum dzn_cmd_bindpoint_dirty {
362    DZN_CMD_BINDPOINT_DIRTY_PIPELINE = 1 << 0,
363    DZN_CMD_BINDPOINT_DIRTY_DYNAMIC_BUFFERS = 1 << 1,
364    DZN_CMD_BINDPOINT_DIRTY_SYSVALS = 1 << 2,
365    DZN_CMD_BINDPOINT_DIRTY_DESC_SET0 = 1 << 3,
366    DZN_CMD_BINDPOINT_DIRTY_DESC_SET1 = 1 << 4,
367    DZN_CMD_BINDPOINT_DIRTY_DESC_SET2 = 1 << 5,
368    DZN_CMD_BINDPOINT_DIRTY_DESC_SET3 = 1 << 6,
369    DZN_CMD_BINDPOINT_DIRTY_DESC_SET4 = 1 << 7,
370    DZN_CMD_BINDPOINT_DIRTY_DESC_SET5 = 1 << 8,
371    DZN_CMD_BINDPOINT_DIRTY_DESC_SET6 = 1 << 9,
372    DZN_CMD_BINDPOINT_DIRTY_DESC_SET7 = 1 << 10,
373    DZN_CMD_BINDPOINT_DIRTY_DESC_SETS =
374       DZN_CMD_BINDPOINT_DIRTY_DESC_SET0 |
375       DZN_CMD_BINDPOINT_DIRTY_DESC_SET1 |
376       DZN_CMD_BINDPOINT_DIRTY_DESC_SET2 |
377       DZN_CMD_BINDPOINT_DIRTY_DESC_SET3 |
378       DZN_CMD_BINDPOINT_DIRTY_DESC_SET4 |
379       DZN_CMD_BINDPOINT_DIRTY_DESC_SET5 |
380       DZN_CMD_BINDPOINT_DIRTY_DESC_SET6 |
381       DZN_CMD_BINDPOINT_DIRTY_DESC_SET7,
382    DZN_CMD_BINDPOINT_DIRTY_HEAPS =
383       DZN_CMD_BINDPOINT_DIRTY_DYNAMIC_BUFFERS |
384       DZN_CMD_BINDPOINT_DIRTY_SYSVALS |
385       DZN_CMD_BINDPOINT_DIRTY_DESC_SETS,
386 };
387 
388 enum dzn_cmd_dirty {
389    DZN_CMD_DIRTY_VIEWPORTS = 1 << 0,
390    DZN_CMD_DIRTY_SCISSORS = 1 << 1,
391    DZN_CMD_DIRTY_IB = 1 << 2,
392    DZN_CMD_DIRTY_STENCIL_REF = 1 << 3,
393    DZN_CMD_DIRTY_STENCIL_COMPARE_MASK = 1 << 4,
394    DZN_CMD_DIRTY_STENCIL_WRITE_MASK = 1 << 5,
395    DZN_CMD_DIRTY_BLEND_CONSTANTS = 1 << 6,
396    DZN_CMD_DIRTY_DEPTH_BOUNDS = 1 << 7,
397    DZN_CMD_DIRTY_DEPTH_BIAS = 1 << 8,
398 };
399 
400 #define MAX_VBS D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT
401 #define MAX_VP D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE
402 #define MAX_SCISSOR D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE
403 #define MAX_SETS 8
404 #define MAX_DYNAMIC_UNIFORM_BUFFERS 8
405 #define MAX_DYNAMIC_STORAGE_BUFFERS 4
406 #define MAX_DYNAMIC_BUFFERS                                                  \
407    (MAX_DYNAMIC_UNIFORM_BUFFERS + MAX_DYNAMIC_STORAGE_BUFFERS)
408 #define MAX_PUSH_CONSTANT_DWORDS 32
409 
410 #define NUM_BIND_POINT VK_PIPELINE_BIND_POINT_COMPUTE + 1
411 
412 #define dzn_foreach_pool_type(type) \
413    for (D3D12_DESCRIPTOR_HEAP_TYPE type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; \
414         type <= D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; \
415         type = (D3D12_DESCRIPTOR_HEAP_TYPE)(type + 1))
416 
417 struct dzn_cmd_event_signal {
418    struct dzn_event *event;
419    bool value;
420 };
421 
422 struct dzn_cmd_buffer;
423 
424 struct dzn_descriptor_state {
425    struct {
426       const struct dzn_descriptor_set *set;
427       uint32_t dynamic_offsets[MAX_DYNAMIC_BUFFERS];
428    } sets[MAX_SETS];
429    struct dzn_descriptor_heap *heaps[NUM_POOL_TYPES];
430 };
431 
432 struct dzn_sampler;
433 struct dzn_image_view;
434 struct dzn_buffer_view;
435 
436 struct dzn_buffer_desc {
437    VkDescriptorType type;
438    struct dzn_buffer *buffer;
439    VkDeviceSize range;
440    VkDeviceSize offset;
441 };
442 
443 #define MAX_DESCS_PER_SAMPLER_HEAP     D3D12_MAX_SHADER_VISIBLE_SAMPLER_HEAP_SIZE
444 #define MAX_DESCS_PER_CBV_SRV_UAV_HEAP D3D12_MAX_SHADER_VISIBLE_DESCRIPTOR_HEAP_SIZE_TIER_1
445 
446 VkResult
447 dzn_descriptor_heap_init(struct dzn_descriptor_heap *heap,
448                          struct dzn_device *device,
449                          D3D12_DESCRIPTOR_HEAP_TYPE type,
450                          uint32_t desc_count,
451                          bool shader_visible);
452 
453 void
454 dzn_descriptor_heap_finish(struct dzn_descriptor_heap *heap);
455 
456 D3D12_CPU_DESCRIPTOR_HANDLE
457 dzn_descriptor_heap_get_cpu_handle(const struct dzn_descriptor_heap *heap, uint32_t slot);
458 
459 D3D12_GPU_DESCRIPTOR_HANDLE
460 dzn_descriptor_heap_get_gpu_handle(const struct dzn_descriptor_heap *heap, uint32_t slot);
461 
462 void
463 dzn_descriptor_heap_write_image_view_desc(struct dzn_device *device,
464                                           struct dzn_descriptor_heap *heap,
465                                           uint32_t heap_offset,
466                                           bool writeable,
467                                           bool cube_as_2darray,
468                                           const struct dzn_image_view *iview);
469 
470 void
471 dzn_descriptor_heap_write_buffer_view_desc(struct dzn_device *device,
472                                            struct dzn_descriptor_heap *heap,
473                                            uint32_t heap_offset,
474                                            bool writeable,
475                                            const struct dzn_buffer_view *bview);
476 
477 void
478 dzn_descriptor_heap_write_buffer_desc(struct dzn_device *device,
479                                       struct dzn_descriptor_heap *heap,
480                                       uint32_t heap_offset,
481                                       bool writeable,
482                                       const struct dzn_buffer_desc *bdesc);
483 
484 void
485 dzn_descriptor_heap_write_sampler_desc(struct dzn_device *device,
486                                        struct dzn_descriptor_heap *heap,
487                                        uint32_t desc_offset,
488                                        const struct dzn_sampler *sampler);
489 
490 void
491 dzn_descriptor_heap_copy(struct dzn_device *device,
492                          struct dzn_descriptor_heap *dst_heap, uint32_t dst_heap_offset,
493                          const struct dzn_descriptor_heap *src_heap, uint32_t src_heap_offset,
494                          uint32_t desc_count, D3D12_DESCRIPTOR_HEAP_TYPE type);
495 
496 struct dzn_descriptor_heap_pool_entry {
497    struct list_head link;
498    struct dzn_descriptor_heap heap;
499 };
500 
501 struct dzn_descriptor_heap_pool {
502    const VkAllocationCallbacks *alloc;
503    D3D12_DESCRIPTOR_HEAP_TYPE type;
504    bool shader_visible;
505    struct list_head active_heaps, free_heaps;
506    uint32_t offset;
507    uint32_t desc_sz;
508 };
509 
510 void
511 dzn_descriptor_heap_pool_init(struct dzn_descriptor_heap_pool *pool,
512                               struct dzn_device *device,
513                               D3D12_DESCRIPTOR_HEAP_TYPE type,
514                               bool shader_visible,
515                               const VkAllocationCallbacks *alloc);
516 
517 void
518 dzn_descriptor_heap_pool_finish(struct dzn_descriptor_heap_pool *pool);
519 
520 void
521 dzn_descriptor_heap_pool_reset(struct dzn_descriptor_heap_pool *pool);
522 
523 VkResult
524 dzn_descriptor_heap_pool_alloc_slots(struct dzn_descriptor_heap_pool *pool,
525                                      struct dzn_device *device,
526                                      uint32_t num_slots,
527                                      struct dzn_descriptor_heap **heap,
528                                      uint32_t *first_slot);
529 
530 int
531 dzn_device_descriptor_heap_alloc_slot(struct dzn_device *device,
532                                       D3D12_DESCRIPTOR_HEAP_TYPE type);
533 
534 void
535 dzn_device_descriptor_heap_free_slot(struct dzn_device *device,
536                                      D3D12_DESCRIPTOR_HEAP_TYPE type,
537                                      int slot);
538 
539 struct dzn_cmd_buffer_query_range {
540    struct dzn_query_pool *qpool;
541    uint32_t start, count;
542 };
543 
544 struct dzn_cmd_buffer_query_pool_state {
545    struct util_dynarray reset, collect, signal, zero;
546 };
547 
548 struct dzn_internal_resource {
549    struct list_head link;
550    ID3D12Resource *res;
551    uint64_t size;
552 };
553 
554 enum dzn_event_state {
555    DZN_EVENT_STATE_RESET = 0,
556    DZN_EVENT_STATE_SET = 1,
557 };
558 
559 struct dzn_cmd_buffer_push_constant_state {
560    uint32_t offset;
561    uint32_t end;
562    uint32_t values[MAX_PUSH_CONSTANT_DWORDS];
563 };
564 
565 struct dzn_rendering_attachment {
566    struct dzn_image_view *iview;
567    VkImageLayout layout;
568    struct {
569       VkResolveModeFlagBits mode;
570       struct dzn_image_view *iview;
571       VkImageLayout layout;
572    } resolve;
573    VkAttachmentStoreOp store_op;
574 };
575 
576 struct dzn_graphics_pipeline_variant_key {
577    D3D12_INDEX_BUFFER_STRIP_CUT_VALUE ib_strip_cut;
578    struct {
579       int constant_factor;
580       float slope_factor;
581       float clamp;
582    } depth_bias;
583    struct {
584       struct {
585          uint32_t ref, compare_mask, write_mask;
586       } front, back;
587    } stencil_test;
588 };
589 
590 struct dzn_graphics_pipeline_variant {
591    struct dzn_graphics_pipeline_variant_key key;
592    ID3D12PipelineState *state;
593 };
594 
595 #define MAX_RTS D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT
596 
597 struct dzn_cmd_buffer_state {
598    const struct dzn_pipeline *pipeline;
599    struct dzn_descriptor_heap *heaps[NUM_POOL_TYPES];
600    struct dzn_graphics_pipeline_variant_key pipeline_variant;
601    struct {
602       VkRenderingFlags flags;
603       D3D12_RECT area;
604       uint32_t layer_count;
605       uint32_t view_mask;
606       struct {
607          uint32_t color_count;
608          struct dzn_rendering_attachment colors[MAX_RTS];
609          struct dzn_rendering_attachment depth, stencil;
610       } attachments;
611    } render;
612    struct {
613       BITSET_DECLARE(dirty, MAX_VBS);
614       D3D12_VERTEX_BUFFER_VIEW views[MAX_VBS];
615    } vb;
616    struct {
617       D3D12_INDEX_BUFFER_VIEW view;
618    } ib;
619    struct {
620       struct {
621          struct {
622             uint32_t ref, compare_mask, write_mask;
623          } front, back;
624       } stencil_test;
625       struct {
626          float min, max;
627       } depth_bounds;
628    } zsa;
629    struct {
630       float constants[4];
631    } blend;
632    D3D12_VIEWPORT viewports[MAX_VP];
633    D3D12_RECT scissors[MAX_SCISSOR];
634    struct {
635       struct dzn_cmd_buffer_push_constant_state gfx, compute;
636    } push_constant;
637    uint32_t dirty;
638    struct {
639       struct dzn_pipeline *pipeline;
640       ID3D12RootSignature *root_sig;
641       struct dzn_descriptor_state desc_state;
642       uint32_t dirty;
643    } bindpoint[NUM_BIND_POINT];
644    union {
645       struct dxil_spirv_vertex_runtime_data gfx;
646       struct dxil_spirv_compute_runtime_data compute;
647    } sysvals;
648    struct {
649       uint32_t num_views;
650       uint32_t view_mask;
651    } multiview;
652 };
653 
654 struct dzn_cmd_buffer_rtv_key {
655    const struct dzn_image *image;
656    D3D12_RENDER_TARGET_VIEW_DESC desc;
657 };
658 
659 struct dzn_cmd_buffer_rtv_entry {
660    struct dzn_cmd_buffer_rtv_key key;
661    D3D12_CPU_DESCRIPTOR_HANDLE handle;
662 };
663 
664 struct dzn_cmd_buffer_dsv_key {
665    const struct dzn_image *image;
666    D3D12_DEPTH_STENCIL_VIEW_DESC desc;
667 };
668 
669 struct dzn_cmd_buffer_dsv_entry {
670    struct dzn_cmd_buffer_dsv_key key;
671    D3D12_CPU_DESCRIPTOR_HANDLE handle;
672 };
673 
674 enum dzn_internal_buf_bucket {
675    DZN_INTERNAL_BUF_UPLOAD,
676    DZN_INTERNAL_BUF_DEFAULT,
677    DZN_INTERNAL_BUF_BUCKET_COUNT,
678 };
679 
680 struct dzn_cmd_buffer {
681    struct vk_command_buffer vk;
682    struct dzn_cmd_buffer_state state;
683 
684    struct {
685       struct hash_table *ht;
686       struct util_dynarray reset;
687       struct util_dynarray signal;
688    } queries;
689 
690    struct {
691       struct hash_table *ht;
692       struct util_dynarray signal;
693    } events;
694 
695    struct {
696       struct hash_table *ht;
697       struct dzn_descriptor_heap_pool pool;
698    } rtvs, dsvs;
699 
700    bool enhanced_barriers;
701    struct hash_table *transition_barriers;
702 
703    struct dzn_descriptor_heap_pool cbv_srv_uav_pool, sampler_pool;
704    D3D12_CPU_DESCRIPTOR_HANDLE null_rtv;
705 
706    struct list_head internal_bufs[DZN_INTERNAL_BUF_BUCKET_COUNT];
707    struct dzn_internal_resource *cur_upload_buf;
708    uint64_t cur_upload_buf_offset;
709 
710    ID3D12CommandAllocator *cmdalloc;
711    ID3D12GraphicsCommandList1 *cmdlist;
712    ID3D12GraphicsCommandList8 *cmdlist8;
713    ID3D12GraphicsCommandList9 *cmdlist9;
714 
715    D3D12_COMMAND_LIST_TYPE type;
716    D3D12_BARRIER_SYNC valid_sync;
717    D3D12_BARRIER_ACCESS valid_access;
718 };
719 
720 struct dxil_spirv_bindless_entry;
721 struct dzn_descriptor_pool {
722    struct vk_object_base base;
723    VkAllocationCallbacks alloc;
724 
725    uint32_t set_count;
726    uint32_t used_set_count;
727    struct dzn_descriptor_set *sets;
728    union {
729       struct dzn_descriptor_heap heaps[NUM_POOL_TYPES];
730       struct {
731          ID3D12Resource *buf;
732          volatile struct dxil_spirv_bindless_entry *map;
733          uint64_t gpuva;
734       } bindless;
735    };
736    uint32_t desc_count[NUM_POOL_TYPES];
737    uint32_t used_desc_count[NUM_POOL_TYPES];
738    uint32_t free_offset[NUM_POOL_TYPES];
739 };
740 
741 #define MAX_SHADER_VISIBILITIES (D3D12_SHADER_VISIBILITY_PIXEL + 1)
742 #define STATIC_SAMPLER_TAG (~0u - 1)
743 
744 struct dzn_descriptor_set_layout_binding {
745    VkDescriptorType type;
746    uint32_t stages;
747    D3D12_SHADER_VISIBILITY visibility;
748    uint32_t base_shader_register;
749    uint32_t range_idx[NUM_POOL_TYPES];
750    union {
751       /* For sampler types, index into the set layout's immutable sampler list,
752        * or STATIC_SAMPLER_TAG for static samplers, or ~0 for dynamic samplers. */
753       uint32_t immutable_sampler_idx;
754       /* For dynamic buffer types, index into the set's dynamic buffer list.
755        * For non-dynamic buffer types, index into the set's buffer descriptor slot list when bindless. */
756       uint32_t buffer_idx;
757    };
758    bool variable_size;
759 };
760 
761 struct dzn_descriptor_set_layout {
762    struct vk_descriptor_set_layout vk;
763 
764    /* Ranges are bucketed by shader visibility so that each visibility can have
765     * a single descriptor table in the root signature, with all ranges concatenated. */
766    uint32_t range_count[MAX_SHADER_VISIBILITIES][NUM_POOL_TYPES];
767    const D3D12_DESCRIPTOR_RANGE1 *ranges[MAX_SHADER_VISIBILITIES][NUM_POOL_TYPES];
768 
769    /* The number of descriptors across all ranges/visibilities for this type */
770    uint32_t range_desc_count[NUM_POOL_TYPES];
771 
772    /* Static samplers actually go into the D3D12 root signature.
773     * Immutable samplers are only stored here to be copied into descriptor tables later. */
774    uint32_t static_sampler_count;
775    const D3D12_STATIC_SAMPLER_DESC1 *static_samplers;
776    uint32_t immutable_sampler_count;
777    const struct dzn_sampler **immutable_samplers;
778 
779    struct {
780       uint32_t bindings[MAX_DYNAMIC_BUFFERS];
781       uint32_t count;
782       uint32_t desc_count;
783       uint32_t range_offset;
784    } dynamic_buffers;
785    uint32_t buffer_count;
786    uint32_t stages;
787 
788    uint32_t binding_count;
789    const struct dzn_descriptor_set_layout_binding *bindings;
790 };
791 
792 struct dzn_descriptor_set {
793    struct vk_object_base base;
794    struct dzn_buffer_desc dynamic_buffers[MAX_DYNAMIC_BUFFERS];
795    struct dzn_descriptor_pool *pool;
796    /* The offset in the current active staging descriptor heap for the set's pool. */
797    uint32_t heap_offsets[NUM_POOL_TYPES];
798    /* The number of descriptors needed for this set */
799    uint32_t heap_sizes[NUM_POOL_TYPES];
800    /* Layout (and pool) is null for a freed descriptor set */
801    const struct dzn_descriptor_set_layout *layout;
802 };
803 
804 struct dzn_pipeline_layout_set {
805    /* The offset from the start of a descriptor table where the set should be copied */
806    uint32_t heap_offsets[NUM_POOL_TYPES];
807    struct {
808       uint32_t primary, alt;
809    } dynamic_buffer_heap_offsets[MAX_DYNAMIC_BUFFERS];
810    uint32_t dynamic_buffer_count;
811    uint32_t range_desc_count[NUM_POOL_TYPES];
812 };
813 
814 enum dzn_pipeline_binding_class {
815    DZN_PIPELINE_BINDING_NORMAL,
816    DZN_PIPELINE_BINDING_DYNAMIC_BUFFER,
817    DZN_PIPELINE_BINDING_STATIC_SAMPLER,
818 };
819 
820 struct dzn_pipeline_layout {
821    struct vk_pipeline_layout vk;
822    struct dzn_pipeline_layout_set sets[MAX_SETS];
823    struct {
824       uint32_t binding_count;
825       /* A mapping from a binding value, which can be shared among multiple descriptors
826        * in an array, to unique 0-based registers. This mapping is applied to the shaders
827        * during pipeline creation. */
828       uint32_t *base_reg;
829       uint8_t *binding_class;
830    } binding_translation[MAX_SETS];
831    uint32_t set_count;
832    /* How much space needs to be allocated to copy descriptors during cmdbuf recording? */
833    uint32_t desc_count[NUM_POOL_TYPES];
834    uint32_t dynamic_buffer_count;
835    struct {
836       uint32_t param_count;
837       uint32_t sets_param_count;
838       uint32_t sysval_cbv_param_idx;
839       uint32_t push_constant_cbv_param_idx;
840       uint32_t dynamic_buffer_bindless_param_idx;
841       D3D12_DESCRIPTOR_HEAP_TYPE type[MAX_SHADER_VISIBILITIES];
842       ID3D12RootSignature *sig;
843    } root;
844    struct {
845       uint8_t hash[SHA1_DIGEST_LENGTH];
846    } stages[MESA_VULKAN_SHADER_STAGES];
847 };
848 
849 struct dzn_descriptor_update_template_entry {
850    VkDescriptorType type;
851    uint32_t desc_count;
852    uint32_t buffer_idx;
853    struct {
854       uint32_t cbv_srv_uav;
855       union {
856          uint32_t sampler, extra_srv;
857       };
858    } heap_offsets;
859    struct {
860       size_t offset;
861       size_t stride;
862    } user_data;
863 };
864 
865 struct dzn_descriptor_update_template {
866    struct vk_object_base base;
867    uint32_t entry_count;
868    const struct dzn_descriptor_update_template_entry *entries;
869 };
870 
871 enum dzn_register_space {
872    DZN_REGISTER_SPACE_SYSVALS = MAX_SETS,
873    DZN_REGISTER_SPACE_PUSH_CONSTANT,
874 };
875 
876 #define D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(__type) \
877    ALIGN_POT(ALIGN_POT(sizeof(D3D12_PIPELINE_STATE_SUBOBJECT_TYPE), alignof(__type)) + sizeof(__type), alignof(void *))
878 
879 static_assert(sizeof(D3D12_DEPTH_STENCIL_DESC2) > sizeof(D3D12_DEPTH_STENCIL_DESC1),
880               "Using just one of these descs in the max size calculation");
881 static_assert(sizeof(D3D12_RASTERIZER_DESC) >= sizeof(D3D12_RASTERIZER_DESC1) &&
882               sizeof(D3D12_RASTERIZER_DESC) >= sizeof(D3D12_RASTERIZER_DESC2),
883               "Using just one of these descs in the max size calculation");
884 
885 #define MAX_GFX_PIPELINE_STATE_STREAM_SIZE \
886    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(ID3D12RootSignature *) + \
887    (D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_SHADER_BYTECODE) * 5) + /* VS, PS, DS, HS, GS */ \
888    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_STREAM_OUTPUT_DESC) + \
889    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_BLEND_DESC) + \
890    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(UINT) + /* SampleMask */ \
891    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_RASTERIZER_DESC) + \
892    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_INPUT_LAYOUT_DESC) + \
893    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_INDEX_BUFFER_STRIP_CUT_VALUE) + \
894    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_PRIMITIVE_TOPOLOGY_TYPE) + \
895    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(struct D3D12_RT_FORMAT_ARRAY) + \
896    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(DXGI_FORMAT) + /* DS format */ \
897    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(DXGI_SAMPLE_DESC) + \
898    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_NODE_MASK) + \
899    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_CACHED_PIPELINE_STATE) + \
900    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_PIPELINE_STATE_FLAGS) + \
901    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_DEPTH_STENCIL_DESC2) + \
902    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_VIEW_INSTANCING_DESC) + \
903    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_PIPELINE_STATE_FLAGS)
904 
905 #define MAX_COMPUTE_PIPELINE_STATE_STREAM_SIZE \
906    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(ID3D12RootSignature *) + \
907    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_SHADER_BYTECODE) + \
908    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_CACHED_PIPELINE_STATE)
909 
910 struct dzn_pipeline {
911    struct vk_object_base base;
912    VkPipelineBindPoint type;
913    VkPipelineCreateFlags2KHR flags;
914    struct dzn_device *device;
915    struct {
916       uint32_t sets_param_count;
917       uint32_t sysval_cbv_param_idx;
918       uint32_t push_constant_cbv_param_idx;
919       uint32_t dynamic_buffer_bindless_param_idx;
920       D3D12_DESCRIPTOR_HEAP_TYPE type[MAX_SHADER_VISIBILITIES];
921       ID3D12RootSignature *sig;
922    } root;
923    struct dzn_pipeline_layout_set sets[MAX_SETS];
924    uint32_t set_count;
925    uint32_t desc_count[NUM_POOL_TYPES];
926    uint32_t dynamic_buffer_count;
927    ID3D12PipelineState *state;
928 };
929 
930 extern const struct vk_pipeline_cache_object_ops dzn_cached_blob_ops;
931 
932 struct dzn_indirect_draw_cmd_sig_key {
933    union {
934       struct {
935          uint8_t indexed : 1;
936          uint8_t draw_params : 1;
937          uint8_t draw_id : 1;
938          uint8_t triangle_fan : 1;
939       };
940       uint8_t value;
941    };
942 
943    uint8_t padding[3];
944    uint32_t custom_stride;
945 };
946 #define DZN_NUM_INDIRECT_DRAW_CMD_SIGS (1 << 4)
947 
948 struct dzn_graphics_pipeline {
949    struct dzn_pipeline base;
950    struct {
951       unsigned count;
952       uint32_t strides[MAX_VBS];
953    } vb;
954 
955    struct {
956       bool triangle_fan;
957       D3D_PRIMITIVE_TOPOLOGY topology;
958    } ia;
959 
960    struct {
961       unsigned count;
962       bool dynamic;
963       D3D12_VIEWPORT desc[MAX_VP];
964    } vp;
965 
966    struct {
967       unsigned count;
968       bool dynamic;
969       D3D12_RECT desc[MAX_SCISSOR];
970    } scissor;
971 
972    struct {
973       struct {
974          bool enable;
975          bool dynamic_ref;
976          bool dynamic_write_mask;
977          bool dynamic_compare_mask;
978          struct {
979             uint32_t ref;
980             uint32_t write_mask;
981             uint32_t compare_mask;
982             bool uses_ref;
983         } front, back;
984       } stencil_test;
985       struct {
986          bool enable;
987          bool dynamic;
988          float min, max;
989       } depth_bounds;
990       bool dynamic_depth_bias;
991       DXGI_FORMAT ds_fmt;
992    } zsa;
993 
994    struct {
995       bool dynamic_constants;
996       float constants[4];
997    } blend;
998 
999    bool rast_disabled_from_missing_position;
1000    bool use_gs_for_polygon_mode_point;
1001    bool needs_draw_sysvals;
1002 
1003    struct {
1004       uint32_t view_mask;
1005       bool native_view_instancing;
1006    } multiview;
1007 
1008    struct {
1009       uintptr_t stream_buf[MAX_GFX_PIPELINE_STATE_STREAM_SIZE / sizeof(uintptr_t)];
1010       D3D12_PIPELINE_STATE_STREAM_DESC stream_desc;
1011       struct {
1012          uint32_t ib_strip_cut;
1013          uint32_t rast;
1014          uint32_t ds;
1015       } desc_offsets;
1016       D3D12_INPUT_ELEMENT_DESC inputs[D3D12_VS_INPUT_REGISTER_COUNT];
1017       struct {
1018          D3D12_SHADER_BYTECODE *bc;
1019          nir_shader *nir;
1020       } shaders[MESA_VULKAN_SHADER_STAGES];
1021    } templates;
1022 
1023    struct hash_table *variants;
1024 
1025    ID3D12CommandSignature *indirect_cmd_sigs[DZN_NUM_INDIRECT_DRAW_CMD_SIGS];
1026    struct hash_table *custom_stride_cmd_sigs;
1027 };
1028 
1029 #define dzn_graphics_pipeline_get_desc(pipeline, streambuf, name) \
1030    (void *)(pipeline->templates.desc_offsets.name == 0 ? NULL : \
1031             (uint8_t *)streambuf + pipeline->templates.desc_offsets.name)
1032 
1033 #define dzn_graphics_pipeline_get_desc_template(pipeline, name) \
1034    (const void *)dzn_graphics_pipeline_get_desc(pipeline, pipeline->templates.stream_buf, name)
1035 
1036 ID3D12PipelineState *
1037 dzn_graphics_pipeline_get_state(struct dzn_graphics_pipeline *pipeline,
1038                                 const struct dzn_graphics_pipeline_variant_key *key);
1039 
1040 ID3D12CommandSignature *
1041 dzn_graphics_pipeline_get_indirect_cmd_sig(struct dzn_graphics_pipeline *pipeline,
1042                                            struct dzn_indirect_draw_cmd_sig_key key);
1043 
1044 VkFormat dzn_graphics_pipeline_patch_vi_format(VkFormat format);
1045 
1046 struct dzn_compute_pipeline {
1047    struct dzn_pipeline base;
1048    struct {
1049       uint32_t x, y, z;
1050    } local_size;
1051 
1052    ID3D12CommandSignature *indirect_cmd_sig;
1053 };
1054 
1055 ID3D12CommandSignature *
1056 dzn_compute_pipeline_get_indirect_cmd_sig(struct dzn_compute_pipeline *pipeline);
1057 
1058 #define MAX_MIP_LEVELS 14
1059 
1060 struct dzn_image {
1061    struct vk_image vk;
1062 
1063    struct {
1064       uint32_t row_stride;
1065       uint32_t size;
1066    } linear;
1067    D3D12_RESOURCE_DESC desc;
1068    ID3D12Resource *res;
1069    struct dzn_device_memory *mem;
1070    uint32_t castable_format_count;
1071    const DXGI_FORMAT *castable_formats;
1072 
1073    D3D12_BARRIER_ACCESS valid_access;
1074 };
1075 
1076 bool
1077 dzn_image_formats_are_compatible(const struct dzn_device *device,
1078                                  VkFormat orig_fmt, VkFormat new_fmt,
1079                                  VkImageUsageFlags usage,
1080                                  VkImageAspectFlagBits aspect);
1081 
1082 void
1083 dzn_image_align_extent(const struct dzn_image *image,
1084                        VkExtent3D *extent);
1085 
1086 DXGI_FORMAT
1087 dzn_image_get_dxgi_format(const struct dzn_physical_device *pdev,
1088                           VkFormat format,
1089                           VkImageUsageFlags usage,
1090                           VkImageAspectFlags aspects);
1091 
1092 VkFormat
1093 dzn_image_get_plane_format(VkFormat fmt, VkImageAspectFlags aspect);
1094 
1095 DXGI_FORMAT
1096 dzn_image_get_placed_footprint_format(const struct dzn_physical_device *pdev,
1097                                       VkFormat fmt, VkImageAspectFlags aspect);
1098 
1099 D3D12_DEPTH_STENCIL_VIEW_DESC
1100 dzn_image_get_dsv_desc(const struct dzn_image *image,
1101                        const VkImageSubresourceRange *range,
1102                        uint32_t level);
1103 
1104 D3D12_RENDER_TARGET_VIEW_DESC
1105 dzn_image_get_rtv_desc(const struct dzn_image *image,
1106                        const VkImageSubresourceRange *range,
1107                        uint32_t level);
1108 
1109 D3D12_RESOURCE_STATES
1110 dzn_image_layout_to_state(const struct dzn_image *image,
1111                           VkImageLayout layout,
1112                           VkImageAspectFlagBits aspect,
1113                           D3D12_COMMAND_LIST_TYPE type);
1114 
1115 D3D12_BARRIER_LAYOUT
1116 dzn_vk_layout_to_d3d_layout(VkImageLayout layout,
1117                             D3D12_COMMAND_LIST_TYPE type,
1118                             VkImageAspectFlags aspect);
1119 
1120 uint32_t
1121 dzn_image_layers_get_subresource_index(const struct dzn_image *image,
1122                                        const VkImageSubresourceLayers *subres,
1123                                        VkImageAspectFlagBits aspect,
1124                                        uint32_t layer);
1125 uint32_t
1126 dzn_image_range_get_subresource_index(const struct dzn_image *image,
1127                                       const VkImageSubresourceRange *range,
1128                                       VkImageAspectFlagBits aspect,
1129                                       uint32_t level, uint32_t layer);
1130 
1131 D3D12_TEXTURE_COPY_LOCATION
1132 dzn_image_get_copy_loc(const struct dzn_image *image,
1133                        const VkImageSubresourceLayers *layers,
1134                        VkImageAspectFlagBits aspect,
1135                        uint32_t layer);
1136 
1137 struct dzn_image_view {
1138    struct vk_image_view vk;
1139    D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc;
1140    D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
1141    D3D12_RENDER_TARGET_VIEW_DESC rtv_desc;
1142    D3D12_DEPTH_STENCIL_VIEW_DESC dsv_desc;
1143    int srv_bindless_slot;
1144    int uav_bindless_slot;
1145 };
1146 
1147 void
1148 dzn_image_view_init(struct dzn_device *device,
1149                     struct dzn_image_view *iview,
1150                     const VkImageViewCreateInfo *info);
1151 
1152 void
1153 dzn_image_view_finish(struct dzn_image_view *iview);
1154 
1155 struct dzn_buffer {
1156    struct vk_object_base base;
1157 
1158    VkDeviceSize size;
1159 
1160    D3D12_RESOURCE_DESC desc;
1161    ID3D12Resource *res;
1162 
1163    VkBufferCreateFlags create_flags;
1164    VkBufferUsageFlags usage;
1165    bool shared;
1166 
1167    D3D12_BARRIER_ACCESS valid_access;
1168    D3D12_GPU_VIRTUAL_ADDRESS gpuva;
1169 
1170    mtx_t bindless_view_lock;
1171    int cbv_bindless_slot;
1172    int uav_bindless_slot;
1173    struct hash_table *custom_views;
1174 };
1175 
1176 void
1177 dzn_buffer_get_bindless_buffer_descriptor(struct dzn_device *device,
1178                                           const struct dzn_buffer_desc *bdesc,
1179                                           volatile struct dxil_spirv_bindless_entry *out);
1180 
1181 DXGI_FORMAT
1182 dzn_buffer_get_dxgi_format(VkFormat format);
1183 
1184 D3D12_TEXTURE_COPY_LOCATION
1185 dzn_buffer_get_copy_loc(const struct dzn_buffer *buf, VkFormat format,
1186                         const VkBufferImageCopy2 *info,
1187                         VkImageAspectFlagBits aspect,
1188                         uint32_t layer);
1189 
1190 D3D12_TEXTURE_COPY_LOCATION
1191 dzn_buffer_get_line_copy_loc(const struct dzn_buffer *buf, VkFormat format,
1192                              const VkBufferImageCopy2 *region,
1193                              const D3D12_TEXTURE_COPY_LOCATION *loc,
1194                              uint32_t y, uint32_t z, uint32_t *start_x);
1195 
1196 bool
1197 dzn_buffer_supports_region_copy(struct dzn_physical_device *pdev,
1198                                 const D3D12_TEXTURE_COPY_LOCATION *loc);
1199 
1200 struct dzn_buffer_view {
1201    struct vk_object_base base;
1202 
1203    const struct dzn_buffer *buffer;
1204 
1205    D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc;
1206    D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
1207    int srv_bindless_slot;
1208    int uav_bindless_slot;
1209 };
1210 
1211 struct dzn_sampler {
1212    struct vk_object_base base;
1213    D3D12_SAMPLER_DESC2 desc;
1214    D3D12_STATIC_BORDER_COLOR static_border_color;
1215    int bindless_slot;
1216 };
1217 
1218 /* This is defined as a macro so that it works for both
1219  * VkImageSubresourceRange and VkImageSubresourceLayers
1220  */
1221 #define dzn_get_layer_count(_image, _range) \
1222    ((_range)->layerCount == VK_REMAINING_ARRAY_LAYERS ? \
1223     (_image)->vk.array_layers - (_range)->baseArrayLayer : (_range)->layerCount)
1224 
1225 #define dzn_get_level_count(_image, _range) \
1226    ((_range)->levelCount == VK_REMAINING_MIP_LEVELS ? \
1227     (_image)->vk.mip_levels - (_range)->baseMipLevel : (_range)->levelCount)
1228 
1229 DXGI_FORMAT dzn_pipe_to_dxgi_format(enum pipe_format in);
1230 DXGI_FORMAT dzn_get_typeless_dxgi_format(DXGI_FORMAT in);
1231 D3D12_FILTER dzn_translate_sampler_filter(const struct dzn_physical_device *pdev,
1232                                           const VkSamplerCreateInfo *create_info);
1233 D3D12_COMPARISON_FUNC dzn_translate_compare_op(VkCompareOp in);
1234 void dzn_translate_viewport(D3D12_VIEWPORT *out, const VkViewport *in);
1235 void dzn_translate_rect(D3D12_RECT *out, const VkRect2D *in);
1236 
1237 #define dzn_foreach_aspect(aspect, mask) \
1238         for (VkImageAspectFlagBits aspect = VK_IMAGE_ASPECT_COLOR_BIT; \
1239              aspect <= VK_IMAGE_ASPECT_STENCIL_BIT; \
1240              aspect = (VkImageAspectFlagBits)(aspect << 1)) \
1241            if (mask & aspect)
1242 
1243 VkResult dzn_wsi_init(struct dzn_physical_device *physical_device);
1244 void dzn_wsi_finish(struct dzn_physical_device *physical_device);
1245 
1246 struct dzn_app_info {
1247    const char *app_name;
1248    uint32_t app_version;
1249    const char *engine_name;
1250    uint32_t engine_version;
1251    uint32_t api_version;
1252 };
1253 
1254 enum dzn_debug_flags {
1255    DZN_DEBUG_SYNC = 1 << 0,
1256    DZN_DEBUG_NIR = 1 << 1,
1257    DZN_DEBUG_DXIL = 1 << 2,
1258    DZN_DEBUG_WARP = 1 << 3,
1259    DZN_DEBUG_INTERNAL = 1 << 4,
1260    DZN_DEBUG_SIG = 1 << 5,
1261    DZN_DEBUG_GBV = 1 << 6,
1262    DZN_DEBUG_D3D12 = 1 << 7,
1263    DZN_DEBUG_DEBUGGER = 1 << 8,
1264    DZN_DEBUG_REDIRECTS = 1 << 9,
1265    DZN_DEBUG_BINDLESS = 1 << 10,
1266    DZN_DEBUG_NO_BINDLESS = 1 << 11,
1267    DZN_DEBUG_EXPERIMENTAL = 1 << 12,
1268    DZN_DEBUG_MULTIVIEW = 1 << 13,
1269 };
1270 
1271 struct dzn_instance {
1272    struct vk_instance vk;
1273 
1274    struct dxil_validator *dxil_validator;
1275    struct util_dl_library *d3d12_mod;
1276    ID3D12DeviceFactory *factory;
1277    struct {
1278       PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE serialize_root_sig;
1279    } d3d12;
1280    uint32_t debug_flags;
1281 
1282    struct vk_sync_binary_type sync_binary_type;
1283 
1284    struct driOptionCache dri_options;
1285    struct driOptionCache available_dri_options;
1286 };
1287 
1288 struct dzn_event {
1289    struct vk_object_base base;
1290    ID3D12Fence *fence;
1291 };
1292 
1293 struct dzn_sync {
1294    struct vk_sync vk;
1295    ID3D12Fence *fence;
1296    HANDLE export_handle;
1297 };
1298 
1299 extern const struct vk_sync_type dzn_sync_type;
1300 
1301 struct dzn_query {
1302    D3D12_QUERY_TYPE type;
1303    ID3D12Fence *fence;
1304    uint64_t fence_value;
1305 };
1306 
1307 struct dzn_query_pool {
1308    struct vk_object_base base;
1309 
1310    D3D12_QUERY_HEAP_TYPE heap_type;
1311    ID3D12QueryHeap *heap;
1312    uint32_t query_count;
1313    struct dzn_query *queries;
1314    mtx_t queries_lock;
1315    ID3D12Resource *resolve_buffer;
1316    ID3D12Resource *collect_buffer;
1317    VkQueryPipelineStatisticFlags pipeline_statistics;
1318    uint32_t query_size;
1319    uint64_t *collect_map;
1320 };
1321 
1322 D3D12_QUERY_TYPE
1323 dzn_query_pool_get_query_type(const struct dzn_query_pool *qpool, VkQueryControlFlags flag);
1324 
1325 uint32_t
1326 dzn_query_pool_get_result_offset(const struct dzn_query_pool *qpool, uint32_t query);
1327 
1328 uint32_t
1329 dzn_query_pool_get_availability_offset(const struct dzn_query_pool *qpool, uint32_t query);
1330 
1331 uint32_t
1332 dzn_query_pool_get_result_size(const struct dzn_query_pool *qpool, uint32_t count);
1333 
1334 VKAPI_ATTR void VKAPI_CALL
1335 dzn_CmdPipelineBarrier2_enhanced(VkCommandBuffer commandBuffer,
1336                                  const VkDependencyInfo *info);
1337 
1338 VK_DEFINE_HANDLE_CASTS(dzn_cmd_buffer, vk.base, VkCommandBuffer, VK_OBJECT_TYPE_COMMAND_BUFFER)
1339 VK_DEFINE_HANDLE_CASTS(dzn_device, vk.base, VkDevice, VK_OBJECT_TYPE_DEVICE)
1340 VK_DEFINE_HANDLE_CASTS(dzn_instance, vk.base, VkInstance, VK_OBJECT_TYPE_INSTANCE)
1341 VK_DEFINE_HANDLE_CASTS(dzn_physical_device, vk.base, VkPhysicalDevice, VK_OBJECT_TYPE_PHYSICAL_DEVICE)
1342 VK_DEFINE_HANDLE_CASTS(dzn_queue, vk.base, VkQueue, VK_OBJECT_TYPE_QUEUE)
1343 
1344 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_buffer, base, VkBuffer, VK_OBJECT_TYPE_BUFFER)
1345 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_buffer_view, base, VkBufferView, VK_OBJECT_TYPE_BUFFER_VIEW)
1346 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_device_memory, base, VkDeviceMemory, VK_OBJECT_TYPE_DEVICE_MEMORY)
1347 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_descriptor_pool, base, VkDescriptorPool, VK_OBJECT_TYPE_DESCRIPTOR_POOL)
1348 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_descriptor_set, base, VkDescriptorSet, VK_OBJECT_TYPE_DESCRIPTOR_SET)
1349 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_descriptor_set_layout, vk.base, VkDescriptorSetLayout, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT)
1350 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_descriptor_update_template, base, VkDescriptorUpdateTemplate, VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE)
1351 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_event, base, VkEvent, VK_OBJECT_TYPE_EVENT)
1352 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_image, vk.base, VkImage, VK_OBJECT_TYPE_IMAGE)
1353 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_image_view, vk.base, VkImageView, VK_OBJECT_TYPE_IMAGE_VIEW)
1354 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_pipeline, base, VkPipeline, VK_OBJECT_TYPE_PIPELINE)
1355 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_graphics_pipeline, base.base, VkPipeline, VK_OBJECT_TYPE_PIPELINE)
1356 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_compute_pipeline, base.base, VkPipeline, VK_OBJECT_TYPE_PIPELINE)
1357 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_pipeline_layout, vk.base, VkPipelineLayout, VK_OBJECT_TYPE_PIPELINE_LAYOUT)
1358 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_query_pool, base, VkQueryPool, VK_OBJECT_TYPE_QUERY_POOL)
1359 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_sampler, base, VkSampler, VK_OBJECT_TYPE_SAMPLER)
1360 
1361 #endif /* DZN_PRIVATE_H */
1362