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
77struct dxil_validator;
78
79struct dzn_instance;
80struct dzn_device;
81
82struct dzn_meta_indirect_draw {
83   ID3D12RootSignature *root_sig;
84   ID3D12PipelineState *pipeline_state;
85};
86
87enum 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
96static inline enum dzn_index_type
97dzn_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
107static inline enum dzn_index_type
108dzn_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
120static inline uint8_t
121dzn_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
136struct dzn_meta_triangle_fan_rewrite_index {
137   ID3D12RootSignature *root_sig;
138   ID3D12PipelineState *pipeline_state;
139   ID3D12CommandSignature *cmd_sig;
140};
141
142struct 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
159struct dzn_meta_blit {
160   ID3D12RootSignature *root_sig;
161   ID3D12PipelineState *pipeline_state;
162};
163
164struct 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
172const struct dzn_meta_blit *
173dzn_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
179struct 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
214D3D12_FEATURE_DATA_FORMAT_SUPPORT
215dzn_physical_device_get_format_support(struct dzn_physical_device *pdev,
216                                       VkFormat format);
217
218uint32_t
219dzn_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
225PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE
226d3d12_get_serialize_root_sig(void);
227
228void
229d3d12_enable_debug_layer(void);
230
231void
232d3d12_enable_gpu_validation(void);
233
234ID3D12Device2 *
235d3d12_create_device(IUnknown *adapter, bool experimental_features);
236
237struct dzn_queue {
238   struct vk_queue vk;
239
240   ID3D12CommandQueue *cmdqueue;
241   ID3D12Fence *fence;
242   uint64_t fence_point;
243};
244
245struct 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
265void dzn_meta_finish(struct dzn_device *device);
266
267VkResult dzn_meta_init(struct dzn_device *device);
268
269const struct dzn_meta_blit *
270dzn_meta_blits_get_context(struct dzn_device *device,
271                           const struct dzn_meta_blit_key *key);
272
273ID3D12RootSignature *
274dzn_device_create_root_sig(struct dzn_device *device,
275                           const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *desc);
276
277struct 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
293enum 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
299enum 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
328struct dzn_cmd_event_signal {
329   struct dzn_event *event;
330   bool value;
331};
332
333struct dzn_cmd_buffer;
334
335struct 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
343struct dzn_sampler;
344struct dzn_image_view;
345
346struct 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
356struct 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
366D3D12_CPU_DESCRIPTOR_HANDLE
367dzn_descriptor_heap_get_cpu_handle(const struct dzn_descriptor_heap *heap, uint32_t slot);
368
369D3D12_GPU_DESCRIPTOR_HANDLE
370dzn_descriptor_heap_get_gpu_handle(const struct dzn_descriptor_heap *heap, uint32_t slot);
371
372void
373dzn_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
379void
380dzn_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
385void
386dzn_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
390struct dzn_descriptor_heap_pool_entry {
391   struct list_head link;
392   struct dzn_descriptor_heap heap;
393};
394
395struct 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
404void
405dzn_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
411void
412dzn_descriptor_heap_pool_finish(struct dzn_descriptor_heap_pool *pool);
413
414void
415dzn_descriptor_heap_pool_reset(struct dzn_descriptor_heap_pool *pool);
416
417VkResult
418dzn_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
424struct dzn_cmd_buffer_query_range {
425   struct dzn_query_pool *qpool;
426   uint32_t start, count;
427};
428
429struct dzn_cmd_buffer_query_pool_state {
430   struct util_dynarray reset, collect, wait, signal;
431};
432
433struct dzn_internal_resource {
434   struct list_head link;
435   ID3D12Resource *res;
436};
437
438enum dzn_event_state {
439   DZN_EVENT_STATE_EXTERNAL_WAIT = -1,
440   DZN_EVENT_STATE_RESET = 0,
441   DZN_EVENT_STATE_SET = 1,
442};
443
444struct dzn_cmd_buffer_push_constant_state {
445   uint32_t offset;
446   uint32_t end;
447   uint32_t values[MAX_PUSH_CONSTANT_DWORDS];
448};
449
450struct 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
461struct 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
475struct 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
482struct 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
534struct dzn_cmd_buffer_rtv_key {
535   const struct dzn_image *image;
536   D3D12_RENDER_TARGET_VIEW_DESC desc;
537};
538
539struct dzn_cmd_buffer_rtv_entry {
540   struct dzn_cmd_buffer_rtv_key key;
541   D3D12_CPU_DESCRIPTOR_HANDLE handle;
542};
543
544struct dzn_cmd_buffer_dsv_key {
545   const struct dzn_image *image;
546   D3D12_DEPTH_STENCIL_VIEW_DESC desc;
547};
548
549struct dzn_cmd_buffer_dsv_entry {
550   struct dzn_cmd_buffer_dsv_key key;
551   D3D12_CPU_DESCRIPTOR_HANDLE handle;
552};
553
554struct 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
588struct 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
604struct 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
619struct 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
639struct 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
648struct 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
677struct 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
695struct 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
701enum 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
733struct 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
756extern const struct vk_pipeline_cache_object_ops dzn_cached_blob_ops;
757
758enum 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
765struct 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
843ID3D12PipelineState *
844dzn_graphics_pipeline_get_state(struct dzn_graphics_pipeline *pipeline,
845                                const struct dzn_graphics_pipeline_variant_key *key);
846
847ID3D12CommandSignature *
848dzn_graphics_pipeline_get_indirect_cmd_sig(struct dzn_graphics_pipeline *pipeline,
849                                           enum dzn_indirect_draw_cmd_sig_type cmd_sig_type);
850
851VkFormat dzn_graphics_pipeline_patch_vi_format(VkFormat format);
852
853struct 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
862ID3D12CommandSignature *
863dzn_compute_pipeline_get_indirect_cmd_sig(struct dzn_compute_pipeline *pipeline);
864
865#define MAX_MIP_LEVELS 14
866
867struct 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
880bool
881dzn_image_formats_are_compatible(const struct dzn_device *device,
882                                 VkFormat orig_fmt, VkFormat new_fmt,
883                                 VkImageUsageFlags usage,
884                                 VkImageAspectFlagBits aspect);
885
886void
887dzn_image_align_extent(const struct dzn_image *image,
888                       VkExtent3D *extent);
889
890DXGI_FORMAT
891dzn_image_get_dxgi_format(VkFormat format,
892                          VkImageUsageFlags usage,
893                          VkImageAspectFlags aspects);
894
895VkFormat
896dzn_image_get_plane_format(VkFormat fmt, VkImageAspectFlags aspect);
897
898DXGI_FORMAT
899dzn_image_get_placed_footprint_format(VkFormat fmt, VkImageAspectFlags aspect);
900
901D3D12_DEPTH_STENCIL_VIEW_DESC
902dzn_image_get_dsv_desc(const struct dzn_image *image,
903                       const VkImageSubresourceRange *range,
904                       uint32_t level);
905
906D3D12_RENDER_TARGET_VIEW_DESC
907dzn_image_get_rtv_desc(const struct dzn_image *image,
908                       const VkImageSubresourceRange *range,
909                       uint32_t level);
910
911D3D12_RESOURCE_STATES
912dzn_image_layout_to_state(const struct dzn_image *image,
913                          VkImageLayout layout,
914                          VkImageAspectFlagBits aspect);
915
916uint32_t
917dzn_image_layers_get_subresource_index(const struct dzn_image *image,
918                                       const VkImageSubresourceLayers *subres,
919                                       VkImageAspectFlagBits aspect,
920                                       uint32_t layer);
921uint32_t
922dzn_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
927D3D12_TEXTURE_COPY_LOCATION
928dzn_image_get_copy_loc(const struct dzn_image *image,
929                       const VkImageSubresourceLayers *layers,
930                       VkImageAspectFlagBits aspect,
931                       uint32_t layer);
932
933struct 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
941void
942dzn_image_view_init(struct dzn_device *device,
943                    struct dzn_image_view *iview,
944                    const VkImageViewCreateInfo *info);
945
946void
947dzn_image_view_finish(struct dzn_image_view *iview);
948
949struct 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
961DXGI_FORMAT
962dzn_buffer_get_dxgi_format(VkFormat format);
963
964D3D12_TEXTURE_COPY_LOCATION
965dzn_buffer_get_copy_loc(const struct dzn_buffer *buf, VkFormat format,
966                        const VkBufferImageCopy2 *info,
967                        VkImageAspectFlagBits aspect,
968                        uint32_t layer);
969
970D3D12_TEXTURE_COPY_LOCATION
971dzn_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
976bool
977dzn_buffer_supports_region_copy(const D3D12_TEXTURE_COPY_LOCATION *loc);
978
979struct 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
988struct 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
1005DXGI_FORMAT dzn_pipe_to_dxgi_format(enum pipe_format in);
1006DXGI_FORMAT dzn_get_typeless_dxgi_format(DXGI_FORMAT in);
1007D3D12_FILTER dzn_translate_sampler_filter(const VkSamplerCreateInfo *create_info);
1008D3D12_COMPARISON_FUNC dzn_translate_compare_op(VkCompareOp in);
1009void dzn_translate_viewport(D3D12_VIEWPORT *out, const VkViewport *in);
1010void 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
1018VkResult dzn_wsi_init(struct dzn_physical_device *physical_device);
1019void dzn_wsi_finish(struct dzn_physical_device *physical_device);
1020
1021struct 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
1029enum 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
1042struct 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
1057struct dzn_event {
1058   struct vk_object_base base;
1059   ID3D12Fence *fence;
1060};
1061
1062struct dzn_sync {
1063   struct vk_sync vk;
1064   ID3D12Fence *fence;
1065};
1066
1067extern const struct vk_sync_type dzn_sync_type;
1068
1069struct dzn_query {
1070   D3D12_QUERY_TYPE type;
1071   ID3D12Fence *fence;
1072   uint64_t fence_value;
1073};
1074
1075struct 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
1090D3D12_QUERY_TYPE
1091dzn_query_pool_get_query_type(const struct dzn_query_pool *qpool, VkQueryControlFlags flag);
1092
1093uint32_t
1094dzn_query_pool_get_result_offset(const struct dzn_query_pool *qpool, uint32_t query);
1095
1096uint32_t
1097dzn_query_pool_get_availability_offset(const struct dzn_query_pool *qpool, uint32_t query);
1098
1099uint32_t
1100dzn_query_pool_get_result_size(const struct dzn_query_pool *qpool, uint32_t count);
1101
1102VK_DEFINE_HANDLE_CASTS(dzn_cmd_buffer, vk.base, VkCommandBuffer, VK_OBJECT_TYPE_COMMAND_BUFFER)
1103VK_DEFINE_HANDLE_CASTS(dzn_device, vk.base, VkDevice, VK_OBJECT_TYPE_DEVICE)
1104VK_DEFINE_HANDLE_CASTS(dzn_instance, vk.base, VkInstance, VK_OBJECT_TYPE_INSTANCE)
1105VK_DEFINE_HANDLE_CASTS(dzn_physical_device, vk.base, VkPhysicalDevice, VK_OBJECT_TYPE_PHYSICAL_DEVICE)
1106VK_DEFINE_HANDLE_CASTS(dzn_queue, vk.base, VkQueue, VK_OBJECT_TYPE_QUEUE)
1107
1108VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_buffer, base, VkBuffer, VK_OBJECT_TYPE_BUFFER)
1109VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_buffer_view, base, VkBufferView, VK_OBJECT_TYPE_BUFFER_VIEW)
1110VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_device_memory, base, VkDeviceMemory, VK_OBJECT_TYPE_DEVICE_MEMORY)
1111VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_descriptor_pool, base, VkDescriptorPool, VK_OBJECT_TYPE_DESCRIPTOR_POOL)
1112VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_descriptor_set, base, VkDescriptorSet, VK_OBJECT_TYPE_DESCRIPTOR_SET)
1113VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_descriptor_set_layout, vk.base, VkDescriptorSetLayout, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT)
1114VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_descriptor_update_template, base, VkDescriptorUpdateTemplate, VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE)
1115VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_event, base, VkEvent, VK_OBJECT_TYPE_EVENT)
1116VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_image, vk.base, VkImage, VK_OBJECT_TYPE_IMAGE)
1117VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_image_view, vk.base, VkImageView, VK_OBJECT_TYPE_IMAGE_VIEW)
1118VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_pipeline, base, VkPipeline, VK_OBJECT_TYPE_PIPELINE)
1119VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_graphics_pipeline, base.base, VkPipeline, VK_OBJECT_TYPE_PIPELINE)
1120VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_compute_pipeline, base.base, VkPipeline, VK_OBJECT_TYPE_PIPELINE)
1121VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_pipeline_layout, vk.base, VkPipelineLayout, VK_OBJECT_TYPE_PIPELINE_LAYOUT)
1122VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_query_pool, base, VkQueryPool, VK_OBJECT_TYPE_QUERY_POOL)
1123VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_sampler, base, VkSampler, VK_OBJECT_TYPE_SAMPLER)
1124
1125#endif /* DZN_PRIVATE_H */
1126