• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
52 #include "shader_enums.h"
53 
54 #include "dzn_entrypoints.h"
55 #include "dzn_nir.h"
56 #include "dzn_physical_device_enum.h"
57 
58 #include <vulkan/vulkan.h>
59 #include <vulkan/vk_icd.h>
60 
61 #define D3D12_IGNORE_SDK_LAYERS
62 #include <unknwn.h>
63 #include <directx/d3d12.h>
64 
65 #include "spirv_to_dxil.h"
66 #include "dzn_abi_helper.h"
67 
68 #define DZN_SWAP(t, a, b) \
69    do { \
70       t __tmp = a; \
71       a = b; \
72       b = __tmp; \
73    } while (0)
74 
75 #define dzn_stub() unreachable("Unsupported feature")
76 
77 struct dxil_validator;
78 
79 struct dzn_instance;
80 struct dzn_device;
81 
82 struct dzn_meta_indirect_draw {
83    ID3D12RootSignature *root_sig;
84    ID3D12PipelineState *pipeline_state;
85 };
86 
87 enum dzn_index_type {
88    DZN_NO_INDEX,
89    DZN_INDEX_2B,
90    DZN_INDEX_4B,
91    DZN_INDEX_2B_WITH_PRIM_RESTART,
92    DZN_INDEX_4B_WITH_PRIM_RESTART,
93    DZN_NUM_INDEX_TYPE,
94 };
95 
96 static inline enum dzn_index_type
dzn_index_type_from_size(uint8_t index_size)97 dzn_index_type_from_size(uint8_t index_size)
98 {
99    switch (index_size) {
100    case 0: return DZN_NO_INDEX;
101    case 2: return DZN_INDEX_2B;
102    case 4: return DZN_INDEX_4B;
103    default: unreachable("Invalid index size");
104    }
105 }
106 
107 static inline enum dzn_index_type
dzn_index_type_from_dxgi_format(DXGI_FORMAT format,bool prim_restart)108 dzn_index_type_from_dxgi_format(DXGI_FORMAT format, bool prim_restart)
109 {
110    switch (format) {
111    case DXGI_FORMAT_UNKNOWN: return DZN_NO_INDEX;
112    case DXGI_FORMAT_R16_UINT:
113       return prim_restart ? DZN_INDEX_2B_WITH_PRIM_RESTART : DZN_INDEX_2B;
114    case DXGI_FORMAT_R32_UINT:
115       return prim_restart ? DZN_INDEX_4B_WITH_PRIM_RESTART : DZN_INDEX_4B;
116    default: unreachable("Invalid index format");
117    }
118 }
119 
120 static inline uint8_t
dzn_index_size(enum dzn_index_type type)121 dzn_index_size(enum dzn_index_type type)
122 {
123    switch (type) {
124    case DZN_NO_INDEX:
125       return 0;
126    case DZN_INDEX_2B_WITH_PRIM_RESTART:
127    case DZN_INDEX_2B:
128       return 2;
129    case DZN_INDEX_4B_WITH_PRIM_RESTART:
130    case DZN_INDEX_4B:
131       return 4;
132    default: unreachable("Invalid index type");
133    }
134 }
135 
136 struct dzn_meta_triangle_fan_rewrite_index {
137    ID3D12RootSignature *root_sig;
138    ID3D12PipelineState *pipeline_state;
139    ID3D12CommandSignature *cmd_sig;
140 };
141 
142 struct dzn_meta_blit_key {
143    union {
144       struct {
145          DXGI_FORMAT out_format;
146          uint32_t samples : 6;
147          uint32_t loc : 4;
148          uint32_t out_type : 4;
149          uint32_t sampler_dim : 4;
150          uint32_t src_is_array : 1;
151          uint32_t resolve : 1;
152          uint32_t linear_filter : 1;
153          uint32_t padding : 11;
154       };
155       const uint64_t u64;
156    };
157 };
158 
159 struct dzn_meta_blit {
160    ID3D12RootSignature *root_sig;
161    ID3D12PipelineState *pipeline_state;
162 };
163 
164 struct dzn_meta_blits {
165    mtx_t shaders_lock;
166    D3D12_SHADER_BYTECODE vs;
167    struct hash_table *fs;
168    mtx_t contexts_lock;
169    struct hash_table_u64 *contexts;
170 };
171 
172 const struct dzn_meta_blit *
173 dzn_meta_blits_get_context(struct dzn_device *device,
174                            const struct dzn_meta_blit_key *key);
175 
176 #define MAX_SYNC_TYPES 3
177 #define MAX_QUEUE_FAMILIES 3
178 
179 struct dzn_physical_device {
180    struct vk_physical_device vk;
181    struct list_head link;
182 
183    struct vk_device_extension_table supported_extensions;
184    struct vk_physical_device_dispatch_table dispatch;
185 
186    IUnknown *adapter;
187    struct dzn_physical_device_desc desc;
188 
189    uint32_t queue_family_count;
190    struct dzn_queue_family {
191       VkQueueFamilyProperties props;
192       D3D12_COMMAND_QUEUE_DESC desc;
193    } queue_families[MAX_QUEUE_FAMILIES];
194 
195    uint8_t pipeline_cache_uuid[VK_UUID_SIZE];
196    uint8_t device_uuid[VK_UUID_SIZE];
197    uint8_t driver_uuid[VK_UUID_SIZE];
198 
199    struct wsi_device wsi_device;
200 
201    mtx_t dev_lock;
202    ID3D12Device2 *dev;
203    D3D_FEATURE_LEVEL feature_level;
204    D3D12_FEATURE_DATA_ARCHITECTURE1 architecture;
205    D3D12_FEATURE_DATA_D3D12_OPTIONS options;
206    D3D12_FEATURE_DATA_D3D12_OPTIONS2 options2;
207    D3D12_FEATURE_DATA_D3D12_OPTIONS3 options3;
208    VkPhysicalDeviceMemoryProperties memory;
209    D3D12_HEAP_FLAGS heap_flags_for_mem_type[VK_MAX_MEMORY_TYPES];
210    const struct vk_sync_type *sync_types[MAX_SYNC_TYPES + 1];
211    float timestamp_period;
212 };
213 
214 D3D12_FEATURE_DATA_FORMAT_SUPPORT
215 dzn_physical_device_get_format_support(struct dzn_physical_device *pdev,
216                                        VkFormat format);
217 
218 uint32_t
219 dzn_physical_device_get_mem_type_mask_for_resource(const struct dzn_physical_device *pdev,
220                                                    const D3D12_RESOURCE_DESC *desc);
221 
222 #define dzn_debug_ignored_stype(sType) \
223    mesa_logd("%s: ignored VkStructureType %u\n", __func__, (sType))
224 
225 PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE
226 d3d12_get_serialize_root_sig(void);
227 
228 void
229 d3d12_enable_debug_layer(void);
230 
231 void
232 d3d12_enable_gpu_validation(void);
233 
234 ID3D12Device2 *
235 d3d12_create_device(IUnknown *adapter, bool experimental_features);
236 
237 struct dzn_queue {
238    struct vk_queue vk;
239 
240    ID3D12CommandQueue *cmdqueue;
241    ID3D12Fence *fence;
242    uint64_t fence_point;
243 };
244 
245 struct dzn_device {
246    struct vk_device vk;
247    struct vk_device_extension_table enabled_extensions;
248    struct vk_device_dispatch_table cmd_dispatch;
249 
250    ID3D12Device2 *dev;
251 
252    struct dzn_meta_indirect_draw indirect_draws[DZN_NUM_INDIRECT_DRAW_TYPES];
253    struct dzn_meta_triangle_fan_rewrite_index triangle_fan[DZN_NUM_INDEX_TYPE];
254    struct dzn_meta_blits blits;
255 
256    struct {
257 #define DZN_QUERY_REFS_SECTION_SIZE 4096
258 #define DZN_QUERY_REFS_ALL_ONES_OFFSET 0
259 #define DZN_QUERY_REFS_ALL_ZEROS_OFFSET (DZN_QUERY_REFS_ALL_ONES_OFFSET + DZN_QUERY_REFS_SECTION_SIZE)
260 #define DZN_QUERY_REFS_RES_SIZE (DZN_QUERY_REFS_ALL_ZEROS_OFFSET + DZN_QUERY_REFS_SECTION_SIZE)
261       ID3D12Resource *refs;
262    } queries;
263 };
264 
265 void dzn_meta_finish(struct dzn_device *device);
266 
267 VkResult dzn_meta_init(struct dzn_device *device);
268 
269 const struct dzn_meta_blit *
270 dzn_meta_blits_get_context(struct dzn_device *device,
271                            const struct dzn_meta_blit_key *key);
272 
273 ID3D12RootSignature *
274 dzn_device_create_root_sig(struct dzn_device *device,
275                            const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *desc);
276 
277 struct dzn_device_memory {
278    struct vk_object_base base;
279 
280    struct list_head link;
281 
282    ID3D12Heap *heap;
283    VkDeviceSize size;
284    D3D12_RESOURCE_STATES initial_state; /* initial state for this memory type */
285 
286    /* A buffer-resource spanning the entire heap, used for mapping memory */
287    ID3D12Resource *map_res;
288 
289    VkDeviceSize map_size;
290    void *map;
291 };
292 
293 enum dzn_cmd_bindpoint_dirty {
294    DZN_CMD_BINDPOINT_DIRTY_PIPELINE = 1 << 0,
295    DZN_CMD_BINDPOINT_DIRTY_HEAPS = 1 << 1,
296    DZN_CMD_BINDPOINT_DIRTY_SYSVALS = 1 << 2,
297 };
298 
299 enum dzn_cmd_dirty {
300    DZN_CMD_DIRTY_VIEWPORTS = 1 << 0,
301    DZN_CMD_DIRTY_SCISSORS = 1 << 1,
302    DZN_CMD_DIRTY_IB = 1 << 2,
303    DZN_CMD_DIRTY_STENCIL_REF = 1 << 3,
304    DZN_CMD_DIRTY_STENCIL_COMPARE_MASK = 1 << 4,
305    DZN_CMD_DIRTY_STENCIL_WRITE_MASK = 1 << 5,
306    DZN_CMD_DIRTY_BLEND_CONSTANTS = 1 << 6,
307    DZN_CMD_DIRTY_DEPTH_BOUNDS = 1 << 7,
308 };
309 
310 #define MAX_VBS 16
311 #define MAX_VP 16
312 #define MAX_SCISSOR 16
313 #define MAX_SETS 4
314 #define MAX_DYNAMIC_UNIFORM_BUFFERS 8
315 #define MAX_DYNAMIC_STORAGE_BUFFERS 4
316 #define MAX_DYNAMIC_BUFFERS                                                  \
317    (MAX_DYNAMIC_UNIFORM_BUFFERS + MAX_DYNAMIC_STORAGE_BUFFERS)
318 #define MAX_PUSH_CONSTANT_DWORDS 32
319 
320 #define NUM_BIND_POINT VK_PIPELINE_BIND_POINT_COMPUTE + 1
321 #define NUM_POOL_TYPES D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER + 1
322 
323 #define dzn_foreach_pool_type(type) \
324    for (D3D12_DESCRIPTOR_HEAP_TYPE type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; \
325         type <= D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; \
326         type = (D3D12_DESCRIPTOR_HEAP_TYPE)(type + 1))
327 
328 struct dzn_cmd_event_signal {
329    struct dzn_event *event;
330    bool value;
331 };
332 
333 struct dzn_cmd_buffer;
334 
335 struct dzn_descriptor_state {
336    struct {
337       const struct dzn_descriptor_set *set;
338       uint32_t dynamic_offsets[MAX_DYNAMIC_BUFFERS];
339    } sets[MAX_SETS];
340    struct dzn_descriptor_heap *heaps[NUM_POOL_TYPES];
341 };
342 
343 struct dzn_sampler;
344 struct dzn_image_view;
345 
346 struct dzn_buffer_desc {
347    VkDescriptorType type;
348    const struct dzn_buffer *buffer;
349    VkDeviceSize range;
350    VkDeviceSize offset;
351 };
352 
353 #define MAX_DESCS_PER_SAMPLER_HEAP 2048u
354 #define MAX_DESCS_PER_CBV_SRV_UAV_HEAP 1000000u
355 
356 struct dzn_descriptor_heap {
357    ID3D12Device2 *dev;
358    ID3D12DescriptorHeap *heap;
359    D3D12_DESCRIPTOR_HEAP_TYPE type;
360    SIZE_T cpu_base;
361    uint64_t gpu_base;
362    uint32_t desc_count;
363    uint32_t desc_sz;
364 };
365 
366 D3D12_CPU_DESCRIPTOR_HANDLE
367 dzn_descriptor_heap_get_cpu_handle(const struct dzn_descriptor_heap *heap, uint32_t slot);
368 
369 D3D12_GPU_DESCRIPTOR_HANDLE
370 dzn_descriptor_heap_get_gpu_handle(const struct dzn_descriptor_heap *heap, uint32_t slot);
371 
372 void
373 dzn_descriptor_heap_write_image_view_desc(struct dzn_descriptor_heap *heap,
374                                           uint32_t heap_offset,
375                                           bool writeable,
376                                           bool cube_as_2darray,
377                                           const struct dzn_image_view *iview);
378 
379 void
380 dzn_descriptor_heap_write_buffer_desc(struct dzn_descriptor_heap *heap,
381                                       uint32_t heap_offset,
382                                       bool writeable,
383                                       const struct dzn_buffer_desc *bdesc);
384 
385 void
386 dzn_descriptor_heap_copy(struct dzn_descriptor_heap *dst_heap, uint32_t dst_heap_offset,
387                          const struct dzn_descriptor_heap *src_heap, uint32_t src_heap_offset,
388                          uint32_t desc_count);
389 
390 struct dzn_descriptor_heap_pool_entry {
391    struct list_head link;
392    struct dzn_descriptor_heap heap;
393 };
394 
395 struct dzn_descriptor_heap_pool {
396    const VkAllocationCallbacks *alloc;
397    D3D12_DESCRIPTOR_HEAP_TYPE type;
398    bool shader_visible;
399    struct list_head active_heaps, free_heaps;
400    uint32_t offset;
401    uint32_t desc_sz;
402 };
403 
404 void
405 dzn_descriptor_heap_pool_init(struct dzn_descriptor_heap_pool *pool,
406                               struct dzn_device *device,
407                               D3D12_DESCRIPTOR_HEAP_TYPE type,
408                               bool shader_visible,
409                               const VkAllocationCallbacks *alloc);
410 
411 void
412 dzn_descriptor_heap_pool_finish(struct dzn_descriptor_heap_pool *pool);
413 
414 void
415 dzn_descriptor_heap_pool_reset(struct dzn_descriptor_heap_pool *pool);
416 
417 VkResult
418 dzn_descriptor_heap_pool_alloc_slots(struct dzn_descriptor_heap_pool *pool,
419                                      struct dzn_device *device,
420                                      uint32_t num_slots,
421                                      struct dzn_descriptor_heap **heap,
422                                      uint32_t *first_slot);
423 
424 struct dzn_cmd_buffer_query_range {
425    struct dzn_query_pool *qpool;
426    uint32_t start, count;
427 };
428 
429 struct dzn_cmd_buffer_query_pool_state {
430    struct util_dynarray reset, collect, wait, signal;
431 };
432 
433 struct dzn_internal_resource {
434    struct list_head link;
435    ID3D12Resource *res;
436 };
437 
438 enum dzn_event_state {
439    DZN_EVENT_STATE_EXTERNAL_WAIT = -1,
440    DZN_EVENT_STATE_RESET = 0,
441    DZN_EVENT_STATE_SET = 1,
442 };
443 
444 struct dzn_cmd_buffer_push_constant_state {
445    uint32_t offset;
446    uint32_t end;
447    uint32_t values[MAX_PUSH_CONSTANT_DWORDS];
448 };
449 
450 struct dzn_rendering_attachment {
451    struct dzn_image_view *iview;
452    VkImageLayout layout;
453    struct {
454       VkResolveModeFlagBits mode;
455       struct dzn_image_view *iview;
456       VkImageLayout layout;
457    } resolve;
458    VkAttachmentStoreOp store_op;
459 };
460 
461 struct dzn_graphics_pipeline_variant_key {
462    D3D12_INDEX_BUFFER_STRIP_CUT_VALUE ib_strip_cut;
463    struct {
464       int constant_factor;
465       float slope_factor;
466       float clamp;
467    } depth_bias;
468    struct {
469       struct {
470          uint32_t ref, compare_mask, write_mask;
471       } front, back;
472    } stencil_test;
473 };
474 
475 struct dzn_graphics_pipeline_variant {
476    struct dzn_graphics_pipeline_variant_key key;
477    ID3D12PipelineState *state;
478 };
479 
480 #define MAX_RTS D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT
481 
482 struct dzn_cmd_buffer_state {
483    const struct dzn_pipeline *pipeline;
484    struct dzn_descriptor_heap *heaps[NUM_POOL_TYPES];
485    struct dzn_graphics_pipeline_variant_key pipeline_variant;
486    struct {
487       VkRenderingFlags flags;
488       D3D12_RECT area;
489       uint32_t layer_count;
490       uint32_t view_mask;
491       struct {
492          uint32_t color_count;
493          struct dzn_rendering_attachment colors[MAX_RTS];
494          struct dzn_rendering_attachment depth, stencil;
495       } attachments;
496    } render;
497    struct {
498       BITSET_DECLARE(dirty, MAX_VBS);
499       D3D12_VERTEX_BUFFER_VIEW views[MAX_VBS];
500    } vb;
501    struct {
502       D3D12_INDEX_BUFFER_VIEW view;
503    } ib;
504    struct {
505       struct {
506          struct {
507             uint32_t ref, compare_mask, write_mask;
508          } front, back;
509       } stencil_test;
510       struct {
511          float min, max;
512       } depth_bounds;
513    } zsa;
514    struct {
515       float constants[4];
516    } blend;
517    D3D12_VIEWPORT viewports[MAX_VP];
518    D3D12_RECT scissors[MAX_SCISSOR];
519    struct {
520       struct dzn_cmd_buffer_push_constant_state gfx, compute;
521    } push_constant;
522    uint32_t dirty;
523    struct {
524       struct dzn_pipeline *pipeline;
525       struct dzn_descriptor_state desc_state;
526       uint32_t dirty;
527    } bindpoint[NUM_BIND_POINT];
528    union {
529       struct dxil_spirv_vertex_runtime_data gfx;
530       struct dxil_spirv_compute_runtime_data compute;
531    } sysvals;
532 };
533 
534 struct dzn_cmd_buffer_rtv_key {
535    const struct dzn_image *image;
536    D3D12_RENDER_TARGET_VIEW_DESC desc;
537 };
538 
539 struct dzn_cmd_buffer_rtv_entry {
540    struct dzn_cmd_buffer_rtv_key key;
541    D3D12_CPU_DESCRIPTOR_HANDLE handle;
542 };
543 
544 struct dzn_cmd_buffer_dsv_key {
545    const struct dzn_image *image;
546    D3D12_DEPTH_STENCIL_VIEW_DESC desc;
547 };
548 
549 struct dzn_cmd_buffer_dsv_entry {
550    struct dzn_cmd_buffer_dsv_key key;
551    D3D12_CPU_DESCRIPTOR_HANDLE handle;
552 };
553 
554 struct dzn_cmd_buffer {
555    struct vk_command_buffer vk;
556    VkResult error;
557    struct dzn_cmd_buffer_state state;
558 
559    struct {
560       struct hash_table *ht;
561       struct util_dynarray reset;
562       struct util_dynarray wait;
563       struct util_dynarray signal;
564    } queries;
565 
566    struct {
567       struct hash_table *ht;
568       struct util_dynarray wait;
569       struct util_dynarray signal;
570    } events;
571 
572    struct {
573       struct hash_table *ht;
574       struct dzn_descriptor_heap_pool pool;
575    } rtvs, dsvs;
576 
577    struct hash_table *transition_barriers;
578 
579    struct dzn_descriptor_heap_pool cbv_srv_uav_pool, sampler_pool;
580    D3D12_CPU_DESCRIPTOR_HANDLE null_rtv;
581 
582    struct list_head internal_bufs;
583 
584    ID3D12CommandAllocator *cmdalloc;
585    ID3D12GraphicsCommandList1 *cmdlist;
586 };
587 
588 struct dzn_descriptor_pool {
589    struct vk_object_base base;
590    VkAllocationCallbacks alloc;
591 
592    uint32_t set_count;
593    uint32_t used_set_count;
594    struct dzn_descriptor_set *sets;
595    struct dzn_descriptor_heap heaps[NUM_POOL_TYPES];
596    uint32_t desc_count[NUM_POOL_TYPES];
597    uint32_t used_desc_count[NUM_POOL_TYPES];
598    uint32_t free_offset[NUM_POOL_TYPES];
599    mtx_t defragment_lock;
600 };
601 
602 #define MAX_SHADER_VISIBILITIES (D3D12_SHADER_VISIBILITY_PIXEL + 1)
603 
604 struct dzn_descriptor_set_layout_binding {
605    VkDescriptorType type;
606    uint32_t stages;
607    D3D12_SHADER_VISIBILITY visibility;
608    uint32_t base_shader_register;
609    uint32_t range_idx[NUM_POOL_TYPES];
610    union {
611       struct {
612          uint32_t static_sampler_idx;
613          uint32_t immutable_sampler_idx;
614       };
615       uint32_t dynamic_buffer_idx;
616    };
617 };
618 
619 struct dzn_descriptor_set_layout {
620    struct vk_descriptor_set_layout vk;
621    uint32_t range_count[MAX_SHADER_VISIBILITIES][NUM_POOL_TYPES];
622    const D3D12_DESCRIPTOR_RANGE1 *ranges[MAX_SHADER_VISIBILITIES][NUM_POOL_TYPES];
623    uint32_t range_desc_count[NUM_POOL_TYPES];
624    uint32_t static_sampler_count;
625    const D3D12_STATIC_SAMPLER_DESC *static_samplers;
626    uint32_t immutable_sampler_count;
627    const struct dzn_sampler **immutable_samplers;
628    struct {
629       uint32_t bindings[MAX_DYNAMIC_BUFFERS];
630       uint32_t count;
631       uint32_t desc_count;
632       uint32_t range_offset;
633    } dynamic_buffers;
634    uint32_t stages;
635    uint32_t binding_count;
636    const struct dzn_descriptor_set_layout_binding *bindings;
637 };
638 
639 struct dzn_descriptor_set {
640    struct vk_object_base base;
641    struct dzn_buffer_desc dynamic_buffers[MAX_DYNAMIC_BUFFERS];
642    struct dzn_descriptor_pool *pool;
643    uint32_t heap_offsets[NUM_POOL_TYPES];
644    uint32_t heap_sizes[NUM_POOL_TYPES];
645    const struct dzn_descriptor_set_layout *layout;
646 };
647 
648 struct dzn_pipeline_layout {
649    struct vk_pipeline_layout vk;
650    struct {
651       uint32_t heap_offsets[NUM_POOL_TYPES];
652       struct {
653          uint32_t srv, uav;
654       } dynamic_buffer_heap_offsets[MAX_DYNAMIC_BUFFERS];
655       uint32_t dynamic_buffer_count;
656       uint32_t range_desc_count[NUM_POOL_TYPES];
657    } sets[MAX_SETS];
658    struct {
659       uint32_t binding_count;
660       uint32_t *base_reg;
661    } binding_translation[MAX_SETS];
662    uint32_t set_count;
663    uint32_t desc_count[NUM_POOL_TYPES];
664    struct {
665       uint32_t param_count;
666       uint32_t sets_param_count;
667       uint32_t sysval_cbv_param_idx;
668       uint32_t push_constant_cbv_param_idx;
669       D3D12_DESCRIPTOR_HEAP_TYPE type[MAX_SHADER_VISIBILITIES];
670       ID3D12RootSignature *sig;
671    } root;
672    struct {
673       uint8_t hash[SHA1_DIGEST_LENGTH];
674    } stages[MESA_VULKAN_SHADER_STAGES];
675 };
676 
677 struct dzn_descriptor_update_template_entry {
678    VkDescriptorType type;
679    uint32_t desc_count;
680    union {
681       struct {
682          uint32_t cbv_srv_uav;
683          union {
684             uint32_t sampler, extra_uav;
685          };
686       } heap_offsets;
687       uint32_t dynamic_buffer_idx;
688    };
689    struct {
690       size_t offset;
691       size_t stride;
692    } user_data;
693 };
694 
695 struct dzn_descriptor_update_template {
696    struct vk_object_base base;
697    uint32_t entry_count;
698    const struct dzn_descriptor_update_template_entry *entries;
699 };
700 
701 enum dzn_register_space {
702    DZN_REGISTER_SPACE_SYSVALS = MAX_SETS,
703    DZN_REGISTER_SPACE_PUSH_CONSTANT,
704 };
705 
706 #define D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(__type) \
707    ALIGN_POT(ALIGN_POT(sizeof(D3D12_PIPELINE_STATE_SUBOBJECT_TYPE), alignof(__type)) + sizeof(__type), alignof(void *))
708 
709 #define MAX_GFX_PIPELINE_STATE_STREAM_SIZE \
710    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(ID3D12RootSignature *) + \
711    (D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_SHADER_BYTECODE) * 5) + /* VS, PS, DS, HS, GS */ \
712    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_STREAM_OUTPUT_DESC) + \
713    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_BLEND_DESC) + \
714    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(UINT) + /* SampleMask */ \
715    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_RASTERIZER_DESC) + \
716    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_INPUT_LAYOUT_DESC) + \
717    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_INDEX_BUFFER_STRIP_CUT_VALUE) + \
718    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_PRIMITIVE_TOPOLOGY_TYPE) + \
719    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(struct D3D12_RT_FORMAT_ARRAY) + \
720    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(DXGI_FORMAT) + /* DS format */ \
721    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(DXGI_SAMPLE_DESC) + \
722    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_NODE_MASK) + \
723    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_CACHED_PIPELINE_STATE) + \
724    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_PIPELINE_STATE_FLAGS) + \
725    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_DEPTH_STENCIL_DESC1) + \
726    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_VIEW_INSTANCING_DESC)
727 
728 #define MAX_COMPUTE_PIPELINE_STATE_STREAM_SIZE \
729    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(ID3D12RootSignature *) + \
730    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_SHADER_BYTECODE) + \
731    D3D12_PIPELINE_STATE_STREAM_DESC_SIZE(D3D12_CACHED_PIPELINE_STATE)
732 
733 struct dzn_pipeline {
734    struct vk_object_base base;
735    VkPipelineBindPoint type;
736    struct dzn_device *device;
737    struct {
738       uint32_t sets_param_count;
739       uint32_t sysval_cbv_param_idx;
740       uint32_t push_constant_cbv_param_idx;
741       D3D12_DESCRIPTOR_HEAP_TYPE type[MAX_SHADER_VISIBILITIES];
742       ID3D12RootSignature *sig;
743    } root;
744    struct {
745       uint32_t heap_offsets[NUM_POOL_TYPES];
746       struct {
747          uint32_t srv, uav;
748       } dynamic_buffer_heap_offsets[MAX_DYNAMIC_BUFFERS];
749       uint32_t dynamic_buffer_count;
750       uint32_t range_desc_count[NUM_POOL_TYPES];
751    } sets[MAX_SETS];
752    uint32_t desc_count[NUM_POOL_TYPES];
753    ID3D12PipelineState *state;
754 };
755 
756 extern const struct vk_pipeline_cache_object_ops dzn_cached_blob_ops;
757 
758 enum dzn_indirect_draw_cmd_sig_type {
759    DZN_INDIRECT_DRAW_CMD_SIG,
760    DZN_INDIRECT_INDEXED_DRAW_CMD_SIG,
761    DZN_INDIRECT_DRAW_TRIANGLE_FAN_CMD_SIG,
762    DZN_NUM_INDIRECT_DRAW_CMD_SIGS,
763 };
764 
765 struct dzn_graphics_pipeline {
766    struct dzn_pipeline base;
767    struct {
768       unsigned count;
769       uint32_t strides[MAX_VBS];
770    } vb;
771 
772    struct {
773       bool triangle_fan;
774       D3D_PRIMITIVE_TOPOLOGY topology;
775    } ia;
776 
777    struct {
778       unsigned count;
779       bool dynamic;
780       D3D12_VIEWPORT desc[MAX_VP];
781    } vp;
782 
783    struct {
784       unsigned count;
785       bool dynamic;
786       D3D12_RECT desc[MAX_SCISSOR];
787    } scissor;
788 
789    struct {
790       struct {
791          bool enable;
792          bool independent_front_back;
793          bool dynamic_ref;
794          bool dynamic_write_mask;
795          bool dynamic_compare_mask;
796          struct {
797             uint32_t ref;
798             uint32_t write_mask;
799             uint32_t compare_mask;
800             bool uses_ref;
801         } front, back;
802       } stencil_test;
803       struct {
804          bool enable;
805          bool dynamic;
806          float min, max;
807       } depth_bounds;
808       bool dynamic_depth_bias;
809    } zsa;
810 
811    struct {
812       bool dynamic_constants;
813       float constants[4];
814    } blend;
815 
816    struct {
817       uintptr_t stream_buf[MAX_GFX_PIPELINE_STATE_STREAM_SIZE / sizeof(uintptr_t)];
818       D3D12_PIPELINE_STATE_STREAM_DESC stream_desc;
819       struct {
820          uint32_t ib_strip_cut;
821          uint32_t rast;
822          uint32_t ds;
823       } desc_offsets;
824       D3D12_INPUT_ELEMENT_DESC inputs[D3D12_VS_INPUT_REGISTER_COUNT];
825       struct {
826          D3D12_SHADER_BYTECODE *bc;
827          nir_shader *nir;
828       } shaders[MESA_VULKAN_SHADER_STAGES];
829    } templates;
830 
831    struct hash_table *variants;
832 
833    ID3D12CommandSignature *indirect_cmd_sigs[DZN_NUM_INDIRECT_DRAW_CMD_SIGS];
834 };
835 
836 #define dzn_graphics_pipeline_get_desc(pipeline, streambuf, name) \
837    (void *)(pipeline->templates.desc_offsets.name == 0 ? NULL : \
838             (uint8_t *)streambuf + pipeline->templates.desc_offsets.name)
839 
840 #define dzn_graphics_pipeline_get_desc_template(pipeline, name) \
841    (const void *)dzn_graphics_pipeline_get_desc(pipeline, pipeline->templates.stream_buf, name)
842 
843 ID3D12PipelineState *
844 dzn_graphics_pipeline_get_state(struct dzn_graphics_pipeline *pipeline,
845                                 const struct dzn_graphics_pipeline_variant_key *key);
846 
847 ID3D12CommandSignature *
848 dzn_graphics_pipeline_get_indirect_cmd_sig(struct dzn_graphics_pipeline *pipeline,
849                                            enum dzn_indirect_draw_cmd_sig_type cmd_sig_type);
850 
851 VkFormat dzn_graphics_pipeline_patch_vi_format(VkFormat format);
852 
853 struct dzn_compute_pipeline {
854    struct dzn_pipeline base;
855    struct {
856       uint32_t x, y, z;
857    } local_size;
858 
859    ID3D12CommandSignature *indirect_cmd_sig;
860 };
861 
862 ID3D12CommandSignature *
863 dzn_compute_pipeline_get_indirect_cmd_sig(struct dzn_compute_pipeline *pipeline);
864 
865 #define MAX_MIP_LEVELS 14
866 
867 struct dzn_image {
868    struct vk_image vk;
869 
870    struct {
871       uint32_t row_stride;
872       uint32_t size;
873    } linear;
874    D3D12_RESOURCE_DESC desc;
875    ID3D12Resource *res;
876    struct dzn_device_memory *mem;
877    VkDeviceSize mem_offset;
878 };
879 
880 bool
881 dzn_image_formats_are_compatible(const struct dzn_device *device,
882                                  VkFormat orig_fmt, VkFormat new_fmt,
883                                  VkImageUsageFlags usage,
884                                  VkImageAspectFlagBits aspect);
885 
886 void
887 dzn_image_align_extent(const struct dzn_image *image,
888                        VkExtent3D *extent);
889 
890 DXGI_FORMAT
891 dzn_image_get_dxgi_format(VkFormat format,
892                           VkImageUsageFlags usage,
893                           VkImageAspectFlags aspects);
894 
895 VkFormat
896 dzn_image_get_plane_format(VkFormat fmt, VkImageAspectFlags aspect);
897 
898 DXGI_FORMAT
899 dzn_image_get_placed_footprint_format(VkFormat fmt, VkImageAspectFlags aspect);
900 
901 D3D12_DEPTH_STENCIL_VIEW_DESC
902 dzn_image_get_dsv_desc(const struct dzn_image *image,
903                        const VkImageSubresourceRange *range,
904                        uint32_t level);
905 
906 D3D12_RENDER_TARGET_VIEW_DESC
907 dzn_image_get_rtv_desc(const struct dzn_image *image,
908                        const VkImageSubresourceRange *range,
909                        uint32_t level);
910 
911 D3D12_RESOURCE_STATES
912 dzn_image_layout_to_state(const struct dzn_image *image,
913                           VkImageLayout layout,
914                           VkImageAspectFlagBits aspect);
915 
916 uint32_t
917 dzn_image_layers_get_subresource_index(const struct dzn_image *image,
918                                        const VkImageSubresourceLayers *subres,
919                                        VkImageAspectFlagBits aspect,
920                                        uint32_t layer);
921 uint32_t
922 dzn_image_range_get_subresource_index(const struct dzn_image *image,
923                                       const VkImageSubresourceRange *range,
924                                       VkImageAspectFlagBits aspect,
925                                       uint32_t level, uint32_t layer);
926 
927 D3D12_TEXTURE_COPY_LOCATION
928 dzn_image_get_copy_loc(const struct dzn_image *image,
929                        const VkImageSubresourceLayers *layers,
930                        VkImageAspectFlagBits aspect,
931                        uint32_t layer);
932 
933 struct dzn_image_view {
934    struct vk_image_view vk;
935    D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc;
936    D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
937    D3D12_RENDER_TARGET_VIEW_DESC rtv_desc;
938    D3D12_DEPTH_STENCIL_VIEW_DESC dsv_desc;
939 };
940 
941 void
942 dzn_image_view_init(struct dzn_device *device,
943                     struct dzn_image_view *iview,
944                     const VkImageViewCreateInfo *info);
945 
946 void
947 dzn_image_view_finish(struct dzn_image_view *iview);
948 
949 struct dzn_buffer {
950    struct vk_object_base base;
951 
952    VkDeviceSize size;
953 
954    D3D12_RESOURCE_DESC desc;
955    ID3D12Resource *res;
956 
957    VkBufferCreateFlags create_flags;
958    VkBufferUsageFlags usage;
959 };
960 
961 DXGI_FORMAT
962 dzn_buffer_get_dxgi_format(VkFormat format);
963 
964 D3D12_TEXTURE_COPY_LOCATION
965 dzn_buffer_get_copy_loc(const struct dzn_buffer *buf, VkFormat format,
966                         const VkBufferImageCopy2 *info,
967                         VkImageAspectFlagBits aspect,
968                         uint32_t layer);
969 
970 D3D12_TEXTURE_COPY_LOCATION
971 dzn_buffer_get_line_copy_loc(const struct dzn_buffer *buf, VkFormat format,
972                              const VkBufferImageCopy2 *region,
973                              const D3D12_TEXTURE_COPY_LOCATION *loc,
974                              uint32_t y, uint32_t z, uint32_t *start_x);
975 
976 bool
977 dzn_buffer_supports_region_copy(const D3D12_TEXTURE_COPY_LOCATION *loc);
978 
979 struct dzn_buffer_view {
980    struct vk_object_base base;
981 
982    const struct dzn_buffer *buffer;
983 
984    D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc;
985    D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
986 };
987 
988 struct dzn_sampler {
989    struct vk_object_base base;
990    D3D12_SAMPLER_DESC desc;
991    D3D12_STATIC_BORDER_COLOR static_border_color;
992 };
993 
994 /* This is defined as a macro so that it works for both
995  * VkImageSubresourceRange and VkImageSubresourceLayers
996  */
997 #define dzn_get_layer_count(_image, _range) \
998    ((_range)->layerCount == VK_REMAINING_ARRAY_LAYERS ? \
999     (_image)->vk.array_layers - (_range)->baseArrayLayer : (_range)->layerCount)
1000 
1001 #define dzn_get_level_count(_image, _range) \
1002    ((_range)->levelCount == VK_REMAINING_MIP_LEVELS ? \
1003     (_image)->vk.mip_levels - (_range)->baseMipLevel : (_range)->levelCount)
1004 
1005 DXGI_FORMAT dzn_pipe_to_dxgi_format(enum pipe_format in);
1006 DXGI_FORMAT dzn_get_typeless_dxgi_format(DXGI_FORMAT in);
1007 D3D12_FILTER dzn_translate_sampler_filter(const VkSamplerCreateInfo *create_info);
1008 D3D12_COMPARISON_FUNC dzn_translate_compare_op(VkCompareOp in);
1009 void dzn_translate_viewport(D3D12_VIEWPORT *out, const VkViewport *in);
1010 void dzn_translate_rect(D3D12_RECT *out, const VkRect2D *in);
1011 
1012 #define dzn_foreach_aspect(aspect, mask) \
1013         for (VkImageAspectFlagBits aspect = VK_IMAGE_ASPECT_COLOR_BIT; \
1014              aspect <= VK_IMAGE_ASPECT_STENCIL_BIT; \
1015              aspect = (VkImageAspectFlagBits)(aspect << 1)) \
1016            if (mask & aspect)
1017 
1018 VkResult dzn_wsi_init(struct dzn_physical_device *physical_device);
1019 void dzn_wsi_finish(struct dzn_physical_device *physical_device);
1020 
1021 struct dzn_app_info {
1022    const char *app_name;
1023    uint32_t app_version;
1024    const char *engine_name;
1025    uint32_t engine_version;
1026    uint32_t api_version;
1027 };
1028 
1029 enum dzn_debug_flags {
1030    DZN_DEBUG_SYNC = 1 << 0,
1031    DZN_DEBUG_NIR = 1 << 1,
1032    DZN_DEBUG_DXIL = 1 << 2,
1033    DZN_DEBUG_WARP = 1 << 3,
1034    DZN_DEBUG_INTERNAL = 1 << 4,
1035    DZN_DEBUG_SIG = 1 << 5,
1036    DZN_DEBUG_GBV = 1 << 6,
1037    DZN_DEBUG_D3D12 = 1 << 7,
1038    DZN_DEBUG_DEBUGGER = 1 << 8,
1039    DZN_DEBUG_REDIRECTS = 1 << 9,
1040 };
1041 
1042 struct dzn_instance {
1043    struct vk_instance vk;
1044 
1045    struct dxil_validator *dxil_validator;
1046    struct {
1047       PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE serialize_root_sig;
1048    } d3d12;
1049    bool physical_devices_enumerated;
1050    uint32_t debug_flags;
1051 
1052    struct vk_sync_binary_type sync_binary_type;
1053 
1054    struct list_head physical_devices;
1055 };
1056 
1057 struct dzn_event {
1058    struct vk_object_base base;
1059    ID3D12Fence *fence;
1060 };
1061 
1062 struct dzn_sync {
1063    struct vk_sync vk;
1064    ID3D12Fence *fence;
1065 };
1066 
1067 extern const struct vk_sync_type dzn_sync_type;
1068 
1069 struct dzn_query {
1070    D3D12_QUERY_TYPE type;
1071    ID3D12Fence *fence;
1072    uint64_t fence_value;
1073 };
1074 
1075 struct dzn_query_pool {
1076    struct vk_object_base base;
1077 
1078    D3D12_QUERY_HEAP_TYPE heap_type;
1079    ID3D12QueryHeap *heap;
1080    uint32_t query_count;
1081    struct dzn_query *queries;
1082    mtx_t queries_lock;
1083    ID3D12Resource *resolve_buffer;
1084    ID3D12Resource *collect_buffer;
1085    VkQueryPipelineStatisticFlags pipeline_statistics;
1086    uint32_t query_size;
1087    uint64_t *collect_map;
1088 };
1089 
1090 D3D12_QUERY_TYPE
1091 dzn_query_pool_get_query_type(const struct dzn_query_pool *qpool, VkQueryControlFlags flag);
1092 
1093 uint32_t
1094 dzn_query_pool_get_result_offset(const struct dzn_query_pool *qpool, uint32_t query);
1095 
1096 uint32_t
1097 dzn_query_pool_get_availability_offset(const struct dzn_query_pool *qpool, uint32_t query);
1098 
1099 uint32_t
1100 dzn_query_pool_get_result_size(const struct dzn_query_pool *qpool, uint32_t count);
1101 
1102 VK_DEFINE_HANDLE_CASTS(dzn_cmd_buffer, vk.base, VkCommandBuffer, VK_OBJECT_TYPE_COMMAND_BUFFER)
1103 VK_DEFINE_HANDLE_CASTS(dzn_device, vk.base, VkDevice, VK_OBJECT_TYPE_DEVICE)
1104 VK_DEFINE_HANDLE_CASTS(dzn_instance, vk.base, VkInstance, VK_OBJECT_TYPE_INSTANCE)
1105 VK_DEFINE_HANDLE_CASTS(dzn_physical_device, vk.base, VkPhysicalDevice, VK_OBJECT_TYPE_PHYSICAL_DEVICE)
1106 VK_DEFINE_HANDLE_CASTS(dzn_queue, vk.base, VkQueue, VK_OBJECT_TYPE_QUEUE)
1107 
1108 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_buffer, base, VkBuffer, VK_OBJECT_TYPE_BUFFER)
1109 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_buffer_view, base, VkBufferView, VK_OBJECT_TYPE_BUFFER_VIEW)
1110 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_device_memory, base, VkDeviceMemory, VK_OBJECT_TYPE_DEVICE_MEMORY)
1111 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_descriptor_pool, base, VkDescriptorPool, VK_OBJECT_TYPE_DESCRIPTOR_POOL)
1112 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_descriptor_set, base, VkDescriptorSet, VK_OBJECT_TYPE_DESCRIPTOR_SET)
1113 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_descriptor_set_layout, vk.base, VkDescriptorSetLayout, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT)
1114 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_descriptor_update_template, base, VkDescriptorUpdateTemplate, VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE)
1115 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_event, base, VkEvent, VK_OBJECT_TYPE_EVENT)
1116 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_image, vk.base, VkImage, VK_OBJECT_TYPE_IMAGE)
1117 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_image_view, vk.base, VkImageView, VK_OBJECT_TYPE_IMAGE_VIEW)
1118 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_pipeline, base, VkPipeline, VK_OBJECT_TYPE_PIPELINE)
1119 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_graphics_pipeline, base.base, VkPipeline, VK_OBJECT_TYPE_PIPELINE)
1120 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_compute_pipeline, base.base, VkPipeline, VK_OBJECT_TYPE_PIPELINE)
1121 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_pipeline_layout, vk.base, VkPipelineLayout, VK_OBJECT_TYPE_PIPELINE_LAYOUT)
1122 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_query_pool, base, VkQueryPool, VK_OBJECT_TYPE_QUERY_POOL)
1123 VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_sampler, base, VkSampler, VK_OBJECT_TYPE_SAMPLER)
1124 
1125 #endif /* DZN_PRIVATE_H */
1126