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#include "d3d12_screen.h"
25
26#include "d3d12_bufmgr.h"
27#include "d3d12_compiler.h"
28#include "d3d12_context.h"
29#include "d3d12_debug.h"
30#include "d3d12_fence.h"
31#ifdef HAVE_GALLIUM_D3D12_VIDEO
32#include "d3d12_video_screen.h"
33#endif
34#include "d3d12_format.h"
35#include "d3d12_residency.h"
36#include "d3d12_resource.h"
37#include "d3d12_nir_passes.h"
38
39#include "pipebuffer/pb_bufmgr.h"
40#include "util/debug.h"
41#include "util/u_math.h"
42#include "util/u_memory.h"
43#include "util/u_screen.h"
44#include "util/u_dl.h"
45#include "util/mesa-sha1.h"
46
47#include "nir.h"
48#include "frontend/sw_winsys.h"
49
50#include "nir_to_dxil.h"
51#include "git_sha1.h"
52
53#include <directx/d3d12sdklayers.h>
54
55#include <dxguids/dxguids.h>
56static GUID OpenGLOn12CreatorID = { 0x6bb3cd34, 0x0d19, 0x45ab, 0x97, 0xed, 0xd7, 0x20, 0xba, 0x3d, 0xfc, 0x80 };
57
58static const struct debug_named_value
59d3d12_debug_options[] = {
60   { "verbose",      D3D12_DEBUG_VERBOSE,       NULL },
61   { "blit",         D3D12_DEBUG_BLIT,          "Trace blit and copy resource calls" },
62   { "experimental", D3D12_DEBUG_EXPERIMENTAL,  "Enable experimental shader models feature" },
63   { "dxil",         D3D12_DEBUG_DXIL,          "Dump DXIL during program compile" },
64   { "disass",       D3D12_DEBUG_DISASS,        "Dump disassambly of created DXIL shader" },
65   { "res",          D3D12_DEBUG_RESOURCE,      "Debug resources" },
66   { "debuglayer",   D3D12_DEBUG_DEBUG_LAYER,   "Enable debug layer" },
67   { "gpuvalidator", D3D12_DEBUG_GPU_VALIDATOR, "Enable GPU validator" },
68   DEBUG_NAMED_VALUE_END
69};
70
71DEBUG_GET_ONCE_FLAGS_OPTION(d3d12_debug, "D3D12_DEBUG", d3d12_debug_options, 0)
72
73uint32_t
74d3d12_debug;
75
76enum {
77    HW_VENDOR_AMD                   = 0x1002,
78    HW_VENDOR_INTEL                 = 0x8086,
79    HW_VENDOR_MICROSOFT             = 0x1414,
80    HW_VENDOR_NVIDIA                = 0x10de,
81};
82
83static const char *
84d3d12_get_vendor(struct pipe_screen *pscreen)
85{
86   return "Microsoft Corporation";
87}
88
89static const char *
90d3d12_get_device_vendor(struct pipe_screen *pscreen)
91{
92   struct d3d12_screen* screen = d3d12_screen(pscreen);
93
94   switch (screen->vendor_id) {
95   case HW_VENDOR_MICROSOFT:
96      return "Microsoft";
97   case HW_VENDOR_AMD:
98      return "AMD";
99   case HW_VENDOR_NVIDIA:
100      return "NVIDIA";
101   case HW_VENDOR_INTEL:
102      return "Intel";
103   default:
104      return "Unknown";
105   }
106}
107
108static int
109d3d12_get_video_mem(struct pipe_screen *pscreen)
110{
111   struct d3d12_screen* screen = d3d12_screen(pscreen);
112
113   return screen->memory_size_megabytes;
114}
115
116static int
117d3d12_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
118{
119   struct d3d12_screen *screen = d3d12_screen(pscreen);
120
121   switch (param) {
122   case PIPE_CAP_NPOT_TEXTURES:
123      return 1;
124
125   case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
126      /* D3D12 only supports dual-source blending for a single
127       * render-target. From the D3D11 functional spec (which also defines
128       * this for D3D12):
129       *
130       * "When Dual Source Color Blending is enabled, the Pixel Shader must
131       *  have only a single RenderTarget bound, at slot 0, and must output
132       *  both o0 and o1. Writing to other outputs (o2, o3 etc.) produces
133       *  undefined results for the corresponding RenderTargets, if bound
134       *  illegally."
135       *
136       * Source: https://microsoft.github.io/DirectX-Specs/d3d/archive/D3D11_3_FunctionalSpec.htm#17.6%20Dual%20Source%20Color%20Blending
137       */
138      return 1;
139
140   case PIPE_CAP_ANISOTROPIC_FILTER:
141      return 1;
142
143   case PIPE_CAP_MAX_RENDER_TARGETS:
144      return D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT;
145
146   case PIPE_CAP_TEXTURE_SWIZZLE:
147      return 1;
148
149   case PIPE_CAP_MAX_TEXTURE_2D_SIZE:
150      return D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION;
151
152   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
153      return 11; // D3D12_REQ_TEXTURE3D_U_V_OR_W_DIMENSION == 2^10
154
155   case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
156      return D3D12_REQ_MIP_LEVELS;
157
158   case PIPE_CAP_PRIMITIVE_RESTART:
159   case PIPE_CAP_INDEP_BLEND_ENABLE:
160   case PIPE_CAP_INDEP_BLEND_FUNC:
161   case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD:
162   case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES:
163   case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
164   case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
165   case PIPE_CAP_RGB_OVERRIDE_DST_ALPHA_BLEND:
166   case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
167      return 1;
168
169   /* We need to do some lowering that requires a link to the sampler */
170   case PIPE_CAP_NIR_SAMPLERS_AS_DEREF:
171      return 1;
172
173   case PIPE_CAP_NIR_IMAGES_AS_DEREF:
174      return 1;
175
176   case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
177      /* Divide by 6 because this also applies to cubemaps */
178      return D3D12_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION / 6;
179
180   case PIPE_CAP_DEPTH_CLIP_DISABLE:
181      return 1;
182
183   case PIPE_CAP_TGSI_TEXCOORD:
184      return 1;
185
186   case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
187      return 1;
188
189   case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
190      return 1;
191
192   case PIPE_CAP_GLSL_FEATURE_LEVEL:
193      return 420;
194   case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
195      return 420;
196   case PIPE_CAP_ESSL_FEATURE_LEVEL:
197      return 310;
198
199   case PIPE_CAP_COMPUTE:
200      return 1;
201
202   case PIPE_CAP_TEXTURE_MULTISAMPLE:
203      return 1;
204
205   case PIPE_CAP_CUBE_MAP_ARRAY:
206      return 1;
207
208   case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
209      return 1;
210
211   case PIPE_CAP_TEXTURE_TRANSFER_MODES:
212      return 0; /* unsure */
213
214   case PIPE_CAP_ENDIANNESS:
215      return PIPE_ENDIAN_NATIVE; /* unsure */
216
217   case PIPE_CAP_MAX_VIEWPORTS:
218      return D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
219
220   case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
221      return 1;
222
223   case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
224      return 4;
225
226   case PIPE_CAP_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
227   case PIPE_CAP_FS_COORD_ORIGIN_UPPER_LEFT:
228      return 1;
229
230   case PIPE_CAP_FS_FACE_IS_INTEGER_SYSVAL:
231      return 1;
232
233   case PIPE_CAP_ACCELERATED:
234      return screen->vendor_id != HW_VENDOR_MICROSOFT;
235
236   case PIPE_CAP_VIDEO_MEMORY:
237      return d3d12_get_video_mem(pscreen);
238
239   case PIPE_CAP_UMA:
240      return screen->architecture.UMA;
241
242   case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE:
243      return 2048; /* FIXME: no clue how to query this */
244
245   case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
246   case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
247      return 1;
248
249   case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
250      return D3D12_RAW_UAV_SRV_BYTE_ALIGNMENT;
251
252   case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
253      return D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT;
254
255   case PIPE_CAP_PCI_GROUP:
256   case PIPE_CAP_PCI_BUS:
257   case PIPE_CAP_PCI_DEVICE:
258   case PIPE_CAP_PCI_FUNCTION:
259      return 0; /* TODO: figure these out */
260
261   case PIPE_CAP_FLATSHADE:
262   case PIPE_CAP_ALPHA_TEST:
263   case PIPE_CAP_TWO_SIDED_COLOR:
264   case PIPE_CAP_CLIP_PLANES:
265      return 0;
266
267   case PIPE_CAP_SHADER_STENCIL_EXPORT:
268      return screen->opts.PSSpecifiedStencilRefSupported;
269
270   case PIPE_CAP_SEAMLESS_CUBE_MAP:
271   case PIPE_CAP_TEXTURE_QUERY_LOD:
272   case PIPE_CAP_VS_INSTANCEID:
273   case PIPE_CAP_TGSI_TEX_TXF_LZ:
274   case PIPE_CAP_OCCLUSION_QUERY:
275   case PIPE_CAP_POINT_SPRITE:
276   case PIPE_CAP_VIEWPORT_TRANSFORM_LOWERED:
277   case PIPE_CAP_PSIZ_CLAMPED:
278   case PIPE_CAP_BLEND_EQUATION_SEPARATE:
279   case PIPE_CAP_CONDITIONAL_RENDER:
280   case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
281   case PIPE_CAP_QUERY_TIMESTAMP:
282   case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
283   case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
284   case PIPE_CAP_IMAGE_STORE_FORMATTED:
285   case PIPE_CAP_GLSL_TESS_LEVELS_AS_INPUTS:
286      return 1;
287
288   case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
289      return D3D12_SO_BUFFER_SLOT_COUNT;
290
291   case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
292   case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
293      return D3D12_SO_OUTPUT_COMPONENT_COUNT;
294
295   /* Geometry shader output. */
296   case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
297      return D3D12_GS_MAX_OUTPUT_VERTEX_COUNT_ACROSS_INSTANCES;
298   case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
299      return D3D12_REQ_GS_INVOCATION_32BIT_OUTPUT_COMPONENT_LIMIT;
300
301   case PIPE_CAP_MAX_VARYINGS:
302      /* Subtract one so that implicit position can be added */
303      return D3D12_PS_INPUT_REGISTER_COUNT - 1;
304
305   case PIPE_CAP_NIR_COMPACT_ARRAYS:
306      return 1;
307
308   case PIPE_CAP_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
309      if (screen->max_feature_level <= D3D_FEATURE_LEVEL_11_0)
310         return D3D12_PS_CS_UAV_REGISTER_COUNT;
311      if (screen->opts.ResourceBindingTier <= D3D12_RESOURCE_BINDING_TIER_2)
312         return D3D12_UAV_SLOT_COUNT;
313      return 0;
314
315   case PIPE_CAP_START_INSTANCE:
316   case PIPE_CAP_DRAW_PARAMETERS:
317   case PIPE_CAP_DRAW_INDIRECT:
318   case PIPE_CAP_MULTI_DRAW_INDIRECT:
319   case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS:
320   case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
321   case PIPE_CAP_SAMPLE_SHADING:
322   case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
323   case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
324   case PIPE_CAP_INT64:
325   case PIPE_CAP_INT64_DIVMOD:
326   case PIPE_CAP_DOUBLES:
327   case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
328   case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
329   case PIPE_CAP_MEMOBJ:
330   case PIPE_CAP_FENCE_SIGNAL:
331   case PIPE_CAP_TIMELINE_SEMAPHORE_IMPORT:
332   case PIPE_CAP_CLIP_HALFZ:
333      return 1;
334
335   case PIPE_CAP_MAX_VERTEX_STREAMS:
336      return D3D12_SO_BUFFER_SLOT_COUNT;
337
338   case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
339      /* This is asking about varyings, not total registers, so remove the 2 tess factor registers. */
340      return D3D12_HS_OUTPUT_PATCH_CONSTANT_REGISTER_COUNT - 2;
341
342   default:
343      return u_pipe_screen_get_param_defaults(pscreen, param);
344   }
345}
346
347static float
348d3d12_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
349{
350   switch (param) {
351   case PIPE_CAPF_MIN_LINE_WIDTH:
352   case PIPE_CAPF_MIN_LINE_WIDTH_AA:
353   case PIPE_CAPF_MIN_POINT_SIZE:
354   case PIPE_CAPF_MIN_POINT_SIZE_AA:
355      return 1;
356
357   case PIPE_CAPF_POINT_SIZE_GRANULARITY:
358   case PIPE_CAPF_LINE_WIDTH_GRANULARITY:
359      return 0.1;
360
361   case PIPE_CAPF_MAX_LINE_WIDTH:
362   case PIPE_CAPF_MAX_LINE_WIDTH_AA:
363      return 1.0f; /* no clue */
364
365   case PIPE_CAPF_MAX_POINT_SIZE:
366   case PIPE_CAPF_MAX_POINT_SIZE_AA:
367      return D3D12_MAX_POINT_SIZE;
368
369   case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
370      return D3D12_MAX_MAXANISOTROPY;
371
372   case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
373      return 15.99f;
374
375   case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE:
376   case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE:
377   case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY:
378      return 0.0f; /* not implemented */
379
380   default:
381      unreachable("unknown pipe_capf");
382   }
383
384   return 0.0;
385}
386
387static int
388d3d12_get_shader_param(struct pipe_screen *pscreen,
389                       enum pipe_shader_type shader,
390                       enum pipe_shader_cap param)
391{
392   struct d3d12_screen *screen = d3d12_screen(pscreen);
393
394   switch (param) {
395   case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
396   case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
397   case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
398   case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
399   case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
400         return INT_MAX;
401      return 0;
402
403   case PIPE_SHADER_CAP_MAX_INPUTS:
404      switch (shader) {
405      case PIPE_SHADER_VERTEX: return D3D12_VS_INPUT_REGISTER_COUNT;
406      case PIPE_SHADER_FRAGMENT: return D3D12_PS_INPUT_REGISTER_COUNT;
407      case PIPE_SHADER_GEOMETRY: return D3D12_GS_INPUT_REGISTER_COUNT;
408      case PIPE_SHADER_TESS_CTRL: return D3D12_HS_CONTROL_POINT_PHASE_INPUT_REGISTER_COUNT;
409      case PIPE_SHADER_TESS_EVAL: return D3D12_DS_INPUT_CONTROL_POINT_REGISTER_COUNT;
410      case PIPE_SHADER_COMPUTE: return 0;
411      default: unreachable("Unexpected shader");
412      }
413      break;
414
415   case PIPE_SHADER_CAP_MAX_OUTPUTS:
416      switch (shader) {
417      case PIPE_SHADER_VERTEX: return D3D12_VS_OUTPUT_REGISTER_COUNT;
418      case PIPE_SHADER_FRAGMENT: return D3D12_PS_OUTPUT_REGISTER_COUNT;
419      case PIPE_SHADER_GEOMETRY: return D3D12_GS_OUTPUT_REGISTER_COUNT;
420      case PIPE_SHADER_TESS_CTRL: return D3D12_HS_CONTROL_POINT_PHASE_OUTPUT_REGISTER_COUNT;
421      case PIPE_SHADER_TESS_EVAL: return D3D12_DS_OUTPUT_REGISTER_COUNT;
422      case PIPE_SHADER_COMPUTE: return 0;
423      default: unreachable("Unexpected shader");
424      }
425      break;
426
427   case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
428      if (screen->opts.ResourceBindingTier == D3D12_RESOURCE_BINDING_TIER_1)
429         return 16;
430      return PIPE_MAX_SAMPLERS;
431
432   case PIPE_SHADER_CAP_MAX_CONST_BUFFER0_SIZE:
433      return 65536;
434
435   case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
436      return 13; /* 15 - 2 for lowered uniforms and state vars*/
437
438   case PIPE_SHADER_CAP_MAX_TEMPS:
439      return INT_MAX;
440
441   case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
442   case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
443   case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
444   case PIPE_SHADER_CAP_SUBROUTINES:
445      return 0; /* not implemented */
446
447   case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
448   case PIPE_SHADER_CAP_INTEGERS:
449      return 1;
450
451   case PIPE_SHADER_CAP_INT64_ATOMICS:
452   case PIPE_SHADER_CAP_FP16:
453      return 0; /* not implemented */
454
455   case PIPE_SHADER_CAP_PREFERRED_IR:
456      return PIPE_SHADER_IR_NIR;
457
458   case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
459      return 0; /* not implemented */
460
461   case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
462      /* Note: This is wrong, but this is the max value that
463       * TC can support to avoid overflowing an array.
464       */
465      return PIPE_MAX_SAMPLERS;
466
467   case PIPE_SHADER_CAP_DROUND_SUPPORTED:
468   case PIPE_SHADER_CAP_DFRACEXP_DLDEXP_SUPPORTED:
469      return 0; /* not implemented */
470
471   case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
472      return 0; /* no idea */
473
474   case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
475      return
476         (screen->max_feature_level >= D3D_FEATURE_LEVEL_11_1 ||
477          screen->opts.ResourceBindingTier >= D3D12_RESOURCE_BINDING_TIER_3) ?
478         PIPE_MAX_SHADER_BUFFERS : D3D12_PS_CS_UAV_REGISTER_COUNT;
479
480   case PIPE_SHADER_CAP_SUPPORTED_IRS:
481      return 1 << PIPE_SHADER_IR_NIR;
482
483   case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
484      if (!screen->support_shader_images)
485         return 0;
486      return
487         (screen->max_feature_level >= D3D_FEATURE_LEVEL_11_1 ||
488          screen->opts.ResourceBindingTier >= D3D12_RESOURCE_BINDING_TIER_3) ?
489         PIPE_MAX_SHADER_IMAGES : D3D12_PS_CS_UAV_REGISTER_COUNT;
490
491   case PIPE_SHADER_CAP_LDEXP_SUPPORTED:
492   case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
493   case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
494   case PIPE_SHADER_CAP_CONT_SUPPORTED:
495      return 0; /* not implemented */
496
497   /* should only get here on unhandled cases */
498   default: return 0;
499   }
500}
501
502static int
503d3d12_get_compute_param(struct pipe_screen *pscreen,
504                        enum pipe_shader_ir ir,
505                        enum pipe_compute_cap cap,
506                        void *ret)
507{
508   switch (cap) {
509   case PIPE_COMPUTE_CAP_MAX_GRID_SIZE: {
510      uint64_t *grid = (uint64_t *)ret;
511      grid[0] = grid[1] = grid[2] = D3D12_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION;
512      return sizeof(uint64_t) * 3;
513   }
514   case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE: {
515      uint64_t *block = (uint64_t *)ret;
516      block[0] = D3D12_CS_THREAD_GROUP_MAX_X;
517      block[1] = D3D12_CS_THREAD_GROUP_MAX_Y;
518      block[2] = D3D12_CS_THREAD_GROUP_MAX_Z;
519      return sizeof(uint64_t) * 3;
520   }
521   case PIPE_COMPUTE_CAP_MAX_VARIABLE_THREADS_PER_BLOCK:
522   case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK:
523      *(uint64_t *)ret = D3D12_CS_THREAD_GROUP_MAX_THREADS_PER_GROUP;
524      return sizeof(uint64_t);
525   case PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE:
526      *(uint64_t *)ret = D3D12_CS_TGSM_REGISTER_COUNT /*DWORDs*/ * 4;
527      return sizeof(uint64_t);
528   default:
529      return 0;
530   }
531}
532
533static bool
534d3d12_is_format_supported(struct pipe_screen *pscreen,
535                          enum pipe_format format,
536                          enum pipe_texture_target target,
537                          unsigned sample_count,
538                          unsigned storage_sample_count,
539                          unsigned bind)
540{
541   struct d3d12_screen *screen = d3d12_screen(pscreen);
542
543   if (MAX2(1, sample_count) != MAX2(1, storage_sample_count))
544      return false;
545
546   if (target == PIPE_BUFFER) {
547      /* Replace emulated vertex element formats for the tests */
548      format = d3d12_emulated_vtx_format(format);
549   } else {
550      /* Allow 3-comp 32 bit formats only for BOs (needed for ARB_tbo_rgb32) */
551      if ((format == PIPE_FORMAT_R32G32B32_FLOAT ||
552           format == PIPE_FORMAT_R32G32B32_SINT ||
553           format == PIPE_FORMAT_R32G32B32_UINT))
554         return false;
555   }
556
557   /* Don't advertise alpha/luminance_alpha formats because they can't be used
558    * for render targets (except A8_UNORM) and can't be emulated by R/RG formats.
559    * Let the state tracker choose an RGBA format instead. For YUV formats, we
560    * want the state tracker to lower these to individual planes. */
561   if (format != PIPE_FORMAT_A8_UNORM &&
562       (util_format_is_alpha(format) ||
563        util_format_is_luminance_alpha(format) ||
564        util_format_is_yuv(format)))
565      return false;
566
567   if (format == PIPE_FORMAT_NONE) {
568      /* For UAV-only rendering, aka ARB_framebuffer_no_attachments */
569      switch (sample_count) {
570      case 0:
571      case 1:
572      case 4:
573      case 8:
574      case 16:
575         return true;
576      default:
577         return false;
578      }
579   }
580
581   DXGI_FORMAT dxgi_format = d3d12_get_format(format);
582   if (dxgi_format == DXGI_FORMAT_UNKNOWN)
583      return false;
584
585   enum D3D12_FORMAT_SUPPORT1 dim_support = D3D12_FORMAT_SUPPORT1_NONE;
586   switch (target) {
587   case PIPE_TEXTURE_1D:
588   case PIPE_TEXTURE_1D_ARRAY:
589      dim_support = D3D12_FORMAT_SUPPORT1_TEXTURE1D;
590      break;
591   case PIPE_TEXTURE_2D:
592   case PIPE_TEXTURE_RECT:
593   case PIPE_TEXTURE_2D_ARRAY:
594      dim_support = D3D12_FORMAT_SUPPORT1_TEXTURE2D;
595      break;
596   case PIPE_TEXTURE_3D:
597      dim_support = D3D12_FORMAT_SUPPORT1_TEXTURE3D;
598      break;
599   case PIPE_TEXTURE_CUBE:
600   case PIPE_TEXTURE_CUBE_ARRAY:
601      dim_support = D3D12_FORMAT_SUPPORT1_TEXTURECUBE;
602      break;
603   case PIPE_BUFFER:
604      dim_support = D3D12_FORMAT_SUPPORT1_BUFFER;
605      break;
606   default:
607      unreachable("Unknown target");
608   }
609
610   D3D12_FEATURE_DATA_FORMAT_SUPPORT fmt_info;
611   fmt_info.Format = d3d12_get_resource_rt_format(format);
612   if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT,
613                                               &fmt_info, sizeof(fmt_info))))
614      return false;
615
616   if (!(fmt_info.Support1 & dim_support))
617      return false;
618
619   if (target == PIPE_BUFFER) {
620      if (bind & PIPE_BIND_VERTEX_BUFFER &&
621          !(fmt_info.Support1 & D3D12_FORMAT_SUPPORT1_IA_VERTEX_BUFFER))
622         return false;
623
624      if (bind & PIPE_BIND_INDEX_BUFFER) {
625         if (format != PIPE_FORMAT_R16_UINT &&
626             format != PIPE_FORMAT_R32_UINT)
627            return false;
628      }
629
630      if (sample_count > 0)
631         return false;
632   } else {
633      /* all other targets are texture-targets */
634      if (bind & PIPE_BIND_RENDER_TARGET &&
635          !(fmt_info.Support1 & D3D12_FORMAT_SUPPORT1_RENDER_TARGET))
636         return false;
637
638      if (bind & PIPE_BIND_BLENDABLE &&
639         !(fmt_info.Support1 & D3D12_FORMAT_SUPPORT1_BLENDABLE))
640         return false;
641
642      if (bind & PIPE_BIND_SHADER_IMAGE &&
643         (fmt_info.Support2 & (D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD | D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE)) !=
644            (D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD | D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE))
645         return false;
646
647      D3D12_FEATURE_DATA_FORMAT_SUPPORT fmt_info_sv;
648      if (util_format_is_depth_or_stencil(format)) {
649         fmt_info_sv.Format = d3d12_get_resource_srv_format(format, target);
650         if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT,
651                                                     &fmt_info_sv, sizeof(fmt_info_sv))))
652            return false;
653      } else
654         fmt_info_sv = fmt_info;
655
656#ifdef _WIN32
657      if (bind & PIPE_BIND_DISPLAY_TARGET &&
658         (!(fmt_info.Support1 & D3D12_FORMAT_SUPPORT1_DISPLAY) ||
659            // Disable formats that don't support flip model
660            dxgi_format == DXGI_FORMAT_B8G8R8X8_UNORM ||
661            dxgi_format == DXGI_FORMAT_B5G5R5A1_UNORM ||
662            dxgi_format == DXGI_FORMAT_B5G6R5_UNORM ||
663            dxgi_format == DXGI_FORMAT_B4G4R4A4_UNORM))
664         return false;
665#endif
666
667      if (bind & PIPE_BIND_DEPTH_STENCIL &&
668          !(fmt_info.Support1 & D3D12_FORMAT_SUPPORT1_DEPTH_STENCIL))
669            return false;
670
671      if (sample_count > 0) {
672         if (!(fmt_info_sv.Support1 & D3D12_FORMAT_SUPPORT1_MULTISAMPLE_LOAD))
673            return false;
674
675         if (!util_is_power_of_two_nonzero(sample_count))
676            return false;
677
678         if (bind & PIPE_BIND_SHADER_IMAGE)
679            return false;
680
681         D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS ms_info = {};
682         ms_info.Format = dxgi_format;
683         ms_info.SampleCount = sample_count;
684         if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS,
685                                                     &ms_info,
686                                                     sizeof(ms_info))) ||
687             !ms_info.NumQualityLevels)
688            return false;
689      }
690   }
691   return true;
692}
693
694void
695d3d12_deinit_screen(struct d3d12_screen *screen)
696{
697   if (screen->rtv_pool) {
698      d3d12_descriptor_pool_free(screen->rtv_pool);
699      screen->rtv_pool = nullptr;
700   }
701   if (screen->dsv_pool) {
702      d3d12_descriptor_pool_free(screen->dsv_pool);
703      screen->dsv_pool = nullptr;
704   }
705   if (screen->view_pool) {
706      d3d12_descriptor_pool_free(screen->view_pool);
707      screen->view_pool = nullptr;
708   }
709   if (screen->readback_slab_bufmgr) {
710      screen->readback_slab_bufmgr->destroy(screen->readback_slab_bufmgr);
711      screen->readback_slab_bufmgr = nullptr;
712   }
713   if (screen->slab_bufmgr) {
714      screen->slab_bufmgr->destroy(screen->slab_bufmgr);
715      screen->slab_bufmgr = nullptr;
716   }
717   if (screen->cache_bufmgr) {
718      screen->cache_bufmgr->destroy(screen->cache_bufmgr);
719      screen->cache_bufmgr = nullptr;
720   }
721   if (screen->bufmgr) {
722      screen->bufmgr->destroy(screen->bufmgr);
723      screen->bufmgr = nullptr;
724   }
725   d3d12_deinit_residency(screen);
726   if (screen->fence) {
727      screen->fence->Release();
728      screen->fence = nullptr;
729   }
730   if (screen->cmdqueue) {
731      screen->cmdqueue->Release();
732      screen->cmdqueue = nullptr;
733   }
734   if (screen->dev) {
735      screen->dev->Release();
736      screen->dev = nullptr;
737   }
738}
739
740void
741d3d12_destroy_screen(struct d3d12_screen *screen)
742{
743   slab_destroy_parent(&screen->transfer_pool);
744   mtx_destroy(&screen->submit_mutex);
745   mtx_destroy(&screen->descriptor_pool_mutex);
746   glsl_type_singleton_decref();
747   FREE(screen);
748}
749
750static void
751d3d12_flush_frontbuffer(struct pipe_screen * pscreen,
752                        struct pipe_context *pctx,
753                        struct pipe_resource *pres,
754                        unsigned level, unsigned layer,
755                        void *winsys_drawable_handle,
756                        struct pipe_box *sub_box)
757{
758   struct d3d12_screen *screen = d3d12_screen(pscreen);
759   struct sw_winsys *winsys = screen->winsys;
760   struct d3d12_resource *res = d3d12_resource(pres);
761
762   if (!winsys || !pctx)
763     return;
764
765   assert(res->dt);
766   void *map = winsys->displaytarget_map(winsys, res->dt, 0);
767
768   if (map) {
769      pctx = threaded_context_unwrap_sync(pctx);
770      pipe_transfer *transfer = nullptr;
771      void *res_map = pipe_texture_map(pctx, pres, level, layer, PIPE_MAP_READ, 0, 0,
772                                        u_minify(pres->width0, level),
773                                        u_minify(pres->height0, level),
774                                        &transfer);
775      if (res_map) {
776         util_copy_rect((ubyte*)map, pres->format, res->dt_stride, 0, 0,
777                        transfer->box.width, transfer->box.height,
778                        (const ubyte*)res_map, transfer->stride, 0, 0);
779         pipe_texture_unmap(pctx, transfer);
780      }
781      winsys->displaytarget_unmap(winsys, res->dt);
782   }
783
784#ifdef _WIN32
785   // WindowFromDC is Windows-only, and this method requires an HWND, so only use it on Windows
786   ID3D12SharingContract *sharing_contract;
787   if (SUCCEEDED(screen->cmdqueue->QueryInterface(IID_PPV_ARGS(&sharing_contract)))) {
788      ID3D12Resource *d3d12_res = d3d12_resource_resource(res);
789      sharing_contract->Present(d3d12_res, 0, WindowFromDC((HDC)winsys_drawable_handle));
790   }
791#endif
792
793   winsys->displaytarget_display(winsys, res->dt, winsys_drawable_handle, sub_box);
794}
795
796static ID3D12Debug *
797get_debug_interface()
798{
799   typedef HRESULT(WINAPI *PFN_D3D12_GET_DEBUG_INTERFACE)(REFIID riid, void **ppFactory);
800   PFN_D3D12_GET_DEBUG_INTERFACE D3D12GetDebugInterface;
801
802   util_dl_library *d3d12_mod = util_dl_open(UTIL_DL_PREFIX "d3d12" UTIL_DL_EXT);
803   if (!d3d12_mod) {
804      debug_printf("D3D12: failed to load D3D12.DLL\n");
805      return NULL;
806   }
807
808   D3D12GetDebugInterface = (PFN_D3D12_GET_DEBUG_INTERFACE)util_dl_get_proc_address(d3d12_mod, "D3D12GetDebugInterface");
809   if (!D3D12GetDebugInterface) {
810      debug_printf("D3D12: failed to load D3D12GetDebugInterface from D3D12.DLL\n");
811      return NULL;
812   }
813
814   ID3D12Debug *debug;
815   if (FAILED(D3D12GetDebugInterface(IID_PPV_ARGS(&debug)))) {
816      debug_printf("D3D12: D3D12GetDebugInterface failed\n");
817      return NULL;
818   }
819
820   return debug;
821}
822
823static void
824enable_d3d12_debug_layer()
825{
826   ID3D12Debug *debug = get_debug_interface();
827   if (debug) {
828      debug->EnableDebugLayer();
829      debug->Release();
830   }
831}
832
833static void
834enable_gpu_validation()
835{
836   ID3D12Debug *debug = get_debug_interface();
837   ID3D12Debug3 *debug3;
838   if (debug) {
839      if (SUCCEEDED(debug->QueryInterface(IID_PPV_ARGS(&debug3)))) {
840         debug3->SetEnableGPUBasedValidation(true);
841         debug3->Release();
842      }
843      debug->Release();
844   }
845}
846
847static ID3D12Device3 *
848create_device(IUnknown *adapter)
849{
850   typedef HRESULT(WINAPI *PFN_D3D12CREATEDEVICE)(IUnknown*, D3D_FEATURE_LEVEL, REFIID, void**);
851   typedef HRESULT(WINAPI *PFN_D3D12ENABLEEXPERIMENTALFEATURES)(UINT, const IID*, void*, UINT*);
852   PFN_D3D12CREATEDEVICE D3D12CreateDevice;
853   PFN_D3D12ENABLEEXPERIMENTALFEATURES D3D12EnableExperimentalFeatures;
854
855   util_dl_library *d3d12_mod = util_dl_open(UTIL_DL_PREFIX "d3d12" UTIL_DL_EXT);
856   if (!d3d12_mod) {
857      debug_printf("D3D12: failed to load D3D12.DLL\n");
858      return NULL;
859   }
860
861#ifdef _WIN32
862   if (d3d12_debug & D3D12_DEBUG_EXPERIMENTAL)
863#endif
864   {
865      D3D12EnableExperimentalFeatures = (PFN_D3D12ENABLEEXPERIMENTALFEATURES)util_dl_get_proc_address(d3d12_mod, "D3D12EnableExperimentalFeatures");
866      if (FAILED(D3D12EnableExperimentalFeatures(1, &D3D12ExperimentalShaderModels, NULL, NULL))) {
867         debug_printf("D3D12: failed to enable experimental shader models\n");
868         return nullptr;
869      }
870   }
871
872   D3D12CreateDevice = (PFN_D3D12CREATEDEVICE)util_dl_get_proc_address(d3d12_mod, "D3D12CreateDevice");
873   if (!D3D12CreateDevice) {
874      debug_printf("D3D12: failed to load D3D12CreateDevice from D3D12.DLL\n");
875      return NULL;
876   }
877
878   ID3D12Device3 *dev;
879   if (SUCCEEDED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0,
880                 IID_PPV_ARGS(&dev))))
881      return dev;
882
883   debug_printf("D3D12: D3D12CreateDevice failed\n");
884   return NULL;
885}
886
887static bool
888can_attribute_at_vertex(struct d3d12_screen *screen)
889{
890   switch (screen->vendor_id)  {
891   case HW_VENDOR_MICROSOFT:
892      return true;
893   default:
894      return screen->opts3.BarycentricsSupported;
895   }
896}
897
898static bool
899can_shader_image_load_all_formats(struct d3d12_screen *screen)
900{
901   if (!screen->opts.TypedUAVLoadAdditionalFormats)
902      return false;
903
904   /* All of these are required by ARB_shader_image_load_store */
905   static const DXGI_FORMAT additional_formats[] = {
906      DXGI_FORMAT_R16G16B16A16_UNORM,
907      DXGI_FORMAT_R16G16B16A16_SNORM,
908      DXGI_FORMAT_R32G32_FLOAT,
909      DXGI_FORMAT_R32G32_UINT,
910      DXGI_FORMAT_R32G32_SINT,
911      DXGI_FORMAT_R10G10B10A2_UNORM,
912      DXGI_FORMAT_R10G10B10A2_UINT,
913      DXGI_FORMAT_R11G11B10_FLOAT,
914      DXGI_FORMAT_R8G8B8A8_SNORM,
915      DXGI_FORMAT_R16G16_FLOAT,
916      DXGI_FORMAT_R16G16_UNORM,
917      DXGI_FORMAT_R16G16_UINT,
918      DXGI_FORMAT_R16G16_SNORM,
919      DXGI_FORMAT_R16G16_SINT,
920      DXGI_FORMAT_R8G8_UNORM,
921      DXGI_FORMAT_R8G8_UINT,
922      DXGI_FORMAT_R8G8_SNORM,
923      DXGI_FORMAT_R8G8_SINT,
924      DXGI_FORMAT_R16_UNORM,
925      DXGI_FORMAT_R16_SNORM,
926      DXGI_FORMAT_R8_SNORM,
927   };
928
929   for (unsigned i = 0; i < ARRAY_SIZE(additional_formats); ++i) {
930      D3D12_FEATURE_DATA_FORMAT_SUPPORT support = { additional_formats[i] };
931      if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &support, sizeof(support))) ||
932         (support.Support1 & D3D12_FORMAT_SUPPORT1_TYPED_UNORDERED_ACCESS_VIEW) == D3D12_FORMAT_SUPPORT1_NONE ||
933         (support.Support2 & (D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD | D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE)) !=
934            (D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD | D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE))
935         return false;
936   }
937
938   return true;
939}
940
941static void
942d3d12_init_null_srvs(struct d3d12_screen *screen)
943{
944   for (unsigned i = 0; i < RESOURCE_DIMENSION_COUNT; ++i) {
945      D3D12_SHADER_RESOURCE_VIEW_DESC srv = {};
946
947      srv.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
948      srv.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
949      switch (i) {
950      case RESOURCE_DIMENSION_BUFFER:
951      case RESOURCE_DIMENSION_UNKNOWN:
952         srv.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
953         srv.Buffer.FirstElement = 0;
954         srv.Buffer.NumElements = 0;
955         srv.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE;
956         srv.Buffer.StructureByteStride = 0;
957         break;
958      case RESOURCE_DIMENSION_TEXTURE1D:
959         srv.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1D;
960         srv.Texture1D.MipLevels = 1;
961         srv.Texture1D.MostDetailedMip = 0;
962         srv.Texture1D.ResourceMinLODClamp = 0.0f;
963         break;
964      case RESOURCE_DIMENSION_TEXTURE1DARRAY:
965         srv.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1DARRAY;
966         srv.Texture1DArray.MipLevels = 1;
967         srv.Texture1DArray.ArraySize = 1;
968         srv.Texture1DArray.MostDetailedMip = 0;
969         srv.Texture1DArray.FirstArraySlice = 0;
970         srv.Texture1DArray.ResourceMinLODClamp = 0.0f;
971         break;
972      case RESOURCE_DIMENSION_TEXTURE2D:
973         srv.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
974         srv.Texture2D.MipLevels = 1;
975         srv.Texture2D.MostDetailedMip = 0;
976         srv.Texture2D.PlaneSlice = 0;
977         srv.Texture2D.ResourceMinLODClamp = 0.0f;
978         break;
979      case RESOURCE_DIMENSION_TEXTURE2DARRAY:
980         srv.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY;
981         srv.Texture2DArray.MipLevels = 1;
982         srv.Texture2DArray.ArraySize = 1;
983         srv.Texture2DArray.MostDetailedMip = 0;
984         srv.Texture2DArray.FirstArraySlice = 0;
985         srv.Texture2DArray.PlaneSlice = 0;
986         srv.Texture2DArray.ResourceMinLODClamp = 0.0f;
987         break;
988      case RESOURCE_DIMENSION_TEXTURE2DMS:
989         srv.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DMS;
990         break;
991      case RESOURCE_DIMENSION_TEXTURE2DMSARRAY:
992         srv.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY;
993         srv.Texture2DMSArray.ArraySize = 1;
994         srv.Texture2DMSArray.FirstArraySlice = 0;
995         break;
996      case RESOURCE_DIMENSION_TEXTURE3D:
997         srv.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D;
998         srv.Texture3D.MipLevels = 1;
999         srv.Texture3D.MostDetailedMip = 0;
1000         srv.Texture3D.ResourceMinLODClamp = 0.0f;
1001         break;
1002      case RESOURCE_DIMENSION_TEXTURECUBE:
1003         srv.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE;
1004         srv.TextureCube.MipLevels = 1;
1005         srv.TextureCube.MostDetailedMip = 0;
1006         srv.TextureCube.ResourceMinLODClamp = 0.0f;
1007         break;
1008      case RESOURCE_DIMENSION_TEXTURECUBEARRAY:
1009         srv.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBEARRAY;
1010         srv.TextureCubeArray.MipLevels = 1;
1011         srv.TextureCubeArray.NumCubes = 1;
1012         srv.TextureCubeArray.MostDetailedMip = 0;
1013         srv.TextureCubeArray.First2DArrayFace = 0;
1014         srv.TextureCubeArray.ResourceMinLODClamp = 0.0f;
1015         break;
1016      }
1017
1018      if (srv.ViewDimension != D3D12_SRV_DIMENSION_UNKNOWN)
1019      {
1020         d3d12_descriptor_pool_alloc_handle(screen->view_pool, &screen->null_srvs[i]);
1021         screen->dev->CreateShaderResourceView(NULL, &srv, screen->null_srvs[i].cpu_handle);
1022      }
1023   }
1024}
1025
1026static void
1027d3d12_init_null_uavs(struct d3d12_screen *screen)
1028{
1029   for (unsigned i = 0; i < RESOURCE_DIMENSION_COUNT; ++i) {
1030      D3D12_UNORDERED_ACCESS_VIEW_DESC uav = {};
1031
1032      uav.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
1033      switch (i) {
1034      case RESOURCE_DIMENSION_BUFFER:
1035      case RESOURCE_DIMENSION_UNKNOWN:
1036         uav.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
1037         uav.Buffer.FirstElement = 0;
1038         uav.Buffer.NumElements = 0;
1039         uav.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE;
1040         uav.Buffer.StructureByteStride = 0;
1041         uav.Buffer.CounterOffsetInBytes = 0;
1042         break;
1043      case RESOURCE_DIMENSION_TEXTURE1D:
1044         uav.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE1D;
1045         uav.Texture1D.MipSlice = 0;
1046         break;
1047      case RESOURCE_DIMENSION_TEXTURE1DARRAY:
1048         uav.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE1DARRAY;
1049         uav.Texture1DArray.MipSlice = 0;
1050         uav.Texture1DArray.ArraySize = 1;
1051         uav.Texture1DArray.FirstArraySlice = 0;
1052         break;
1053      case RESOURCE_DIMENSION_TEXTURE2D:
1054         uav.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
1055         uav.Texture2D.MipSlice = 0;
1056         uav.Texture2D.PlaneSlice = 0;
1057         break;
1058      case RESOURCE_DIMENSION_TEXTURE2DARRAY:
1059      case RESOURCE_DIMENSION_TEXTURECUBE:
1060      case RESOURCE_DIMENSION_TEXTURECUBEARRAY:
1061         uav.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2DARRAY;
1062         uav.Texture2DArray.MipSlice = 0;
1063         uav.Texture2DArray.ArraySize = 1;
1064         uav.Texture2DArray.FirstArraySlice = 0;
1065         uav.Texture2DArray.PlaneSlice = 0;
1066         break;
1067      case RESOURCE_DIMENSION_TEXTURE2DMS:
1068      case RESOURCE_DIMENSION_TEXTURE2DMSARRAY:
1069         break;
1070      case RESOURCE_DIMENSION_TEXTURE3D:
1071         uav.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE3D;
1072         uav.Texture3D.MipSlice = 0;
1073         uav.Texture3D.FirstWSlice = 0;
1074         uav.Texture3D.WSize = 1;
1075         break;
1076      }
1077
1078      if (uav.ViewDimension != D3D12_UAV_DIMENSION_UNKNOWN)
1079      {
1080         d3d12_descriptor_pool_alloc_handle(screen->view_pool, &screen->null_uavs[i]);
1081         screen->dev->CreateUnorderedAccessView(NULL, NULL, &uav, screen->null_uavs[i].cpu_handle);
1082      }
1083   }
1084}
1085
1086static void
1087d3d12_init_null_rtv(struct d3d12_screen *screen)
1088{
1089   D3D12_RENDER_TARGET_VIEW_DESC rtv = {};
1090   rtv.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
1091   rtv.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
1092   rtv.Texture2D.MipSlice = 0;
1093   rtv.Texture2D.PlaneSlice = 0;
1094   d3d12_descriptor_pool_alloc_handle(screen->rtv_pool, &screen->null_rtv);
1095   screen->dev->CreateRenderTargetView(NULL, &rtv, screen->null_rtv.cpu_handle);
1096}
1097
1098static void
1099d3d12_get_adapter_luid(struct pipe_screen *pscreen, char *luid)
1100{
1101   struct d3d12_screen *screen = d3d12_screen(pscreen);
1102   memcpy(luid, &screen->adapter_luid, PIPE_LUID_SIZE);
1103}
1104
1105static void
1106d3d12_get_device_uuid(struct pipe_screen *pscreen, char *uuid)
1107{
1108   struct d3d12_screen *screen = d3d12_screen(pscreen);
1109   memcpy(uuid, &screen->device_uuid, PIPE_UUID_SIZE);
1110}
1111
1112static void
1113d3d12_get_driver_uuid(struct pipe_screen *pscreen, char *uuid)
1114{
1115   struct d3d12_screen *screen = d3d12_screen(pscreen);
1116   memcpy(uuid, &screen->driver_uuid, PIPE_UUID_SIZE);
1117}
1118
1119static uint32_t
1120d3d12_get_node_mask(struct pipe_screen *pscreen)
1121{
1122   /* This implementation doesn't support linked adapters */
1123   return 1;
1124}
1125
1126static void
1127d3d12_create_fence_win32(struct pipe_screen *pscreen, struct pipe_fence_handle **pfence, void *handle, const void *name, enum pipe_fd_type type)
1128{
1129   d3d12_fence_reference((struct d3d12_fence **)pfence,
1130                         type == PIPE_FD_TYPE_TIMELINE_SEMAPHORE ?
1131                           d3d12_open_fence(d3d12_screen(pscreen), handle, name) :
1132                           nullptr);
1133}
1134
1135static void
1136d3d12_set_fence_timeline_value(struct pipe_screen *pscreen, struct pipe_fence_handle *pfence, uint64_t value)
1137{
1138   d3d12_fence(pfence)->value = value;
1139}
1140
1141void
1142d3d12_init_screen_base(struct d3d12_screen *screen, struct sw_winsys *winsys, LUID *adapter_luid)
1143{
1144   d3d12_debug = debug_get_option_d3d12_debug();
1145
1146   screen->winsys = winsys;
1147   if (adapter_luid)
1148      screen->adapter_luid = *adapter_luid;
1149   mtx_init(&screen->descriptor_pool_mutex, mtx_plain);
1150   mtx_init(&screen->submit_mutex, mtx_plain);
1151
1152   list_inithead(&screen->context_list);
1153
1154   screen->base.get_vendor = d3d12_get_vendor;
1155   screen->base.get_device_vendor = d3d12_get_device_vendor;
1156   screen->base.get_param = d3d12_get_param;
1157   screen->base.get_paramf = d3d12_get_paramf;
1158   screen->base.get_shader_param = d3d12_get_shader_param;
1159   screen->base.get_compute_param = d3d12_get_compute_param;
1160   screen->base.is_format_supported = d3d12_is_format_supported;
1161   screen->base.get_compiler_options = d3d12_get_compiler_options;
1162   screen->base.context_create = d3d12_context_create;
1163   screen->base.flush_frontbuffer = d3d12_flush_frontbuffer;
1164   screen->base.get_device_luid = d3d12_get_adapter_luid;
1165   screen->base.get_device_uuid = d3d12_get_device_uuid;
1166   screen->base.get_driver_uuid = d3d12_get_driver_uuid;
1167   screen->base.get_device_node_mask = d3d12_get_node_mask;
1168   screen->base.create_fence_win32 = d3d12_create_fence_win32;
1169   screen->base.set_fence_timeline_value = d3d12_set_fence_timeline_value;
1170}
1171
1172bool
1173d3d12_init_screen(struct d3d12_screen *screen, IUnknown *adapter)
1174{
1175   assert(screen->base.destroy != nullptr);
1176
1177#ifndef DEBUG
1178   if (d3d12_debug & D3D12_DEBUG_DEBUG_LAYER)
1179#endif
1180      enable_d3d12_debug_layer();
1181
1182   if (d3d12_debug & D3D12_DEBUG_GPU_VALIDATOR)
1183      enable_gpu_validation();
1184
1185   screen->dev = create_device(adapter);
1186
1187   if (!screen->dev) {
1188      debug_printf("D3D12: failed to create device\n");
1189      return false;
1190   }
1191
1192   screen->adapter_luid = GetAdapterLuid(screen->dev);
1193
1194   ID3D12InfoQueue *info_queue;
1195   if (SUCCEEDED(screen->dev->QueryInterface(IID_PPV_ARGS(&info_queue)))) {
1196      D3D12_MESSAGE_SEVERITY severities[] = {
1197         D3D12_MESSAGE_SEVERITY_INFO,
1198         D3D12_MESSAGE_SEVERITY_WARNING,
1199      };
1200
1201      D3D12_MESSAGE_ID msg_ids[] = {
1202         D3D12_MESSAGE_ID_CLEARRENDERTARGETVIEW_MISMATCHINGCLEARVALUE,
1203      };
1204
1205      D3D12_INFO_QUEUE_FILTER NewFilter = {};
1206      NewFilter.DenyList.NumSeverities = ARRAY_SIZE(severities);
1207      NewFilter.DenyList.pSeverityList = severities;
1208      NewFilter.DenyList.NumIDs = ARRAY_SIZE(msg_ids);
1209      NewFilter.DenyList.pIDList = msg_ids;
1210
1211      info_queue->PushStorageFilter(&NewFilter);
1212      info_queue->Release();
1213   }
1214
1215   if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS,
1216                                               &screen->opts,
1217                                               sizeof(screen->opts)))) {
1218      debug_printf("D3D12: failed to get device options\n");
1219      return false;
1220   }
1221   if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS1,
1222                                               &screen->opts1,
1223                                               sizeof(screen->opts1)))) {
1224      debug_printf("D3D12: failed to get device options\n");
1225      return false;
1226   }
1227   if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS2,
1228                                               &screen->opts2,
1229                                               sizeof(screen->opts2)))) {
1230      debug_printf("D3D12: failed to get device options\n");
1231      return false;
1232   }
1233   if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS3,
1234                                               &screen->opts3,
1235                                               sizeof(screen->opts3)))) {
1236      debug_printf("D3D12: failed to get device options\n");
1237      return false;
1238   }
1239   if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS4,
1240                                               &screen->opts4,
1241                                               sizeof(screen->opts4)))) {
1242      debug_printf("D3D12: failed to get device options\n");
1243      return false;
1244   }
1245
1246   screen->architecture.NodeIndex = 0;
1247   if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_ARCHITECTURE,
1248                                               &screen->architecture,
1249                                               sizeof(screen->architecture)))) {
1250      debug_printf("D3D12: failed to get device architecture\n");
1251      return false;
1252   }
1253
1254   D3D12_FEATURE_DATA_FEATURE_LEVELS feature_levels;
1255   static const D3D_FEATURE_LEVEL levels[] = {
1256      D3D_FEATURE_LEVEL_11_0,
1257      D3D_FEATURE_LEVEL_11_1,
1258      D3D_FEATURE_LEVEL_12_0,
1259      D3D_FEATURE_LEVEL_12_1,
1260   };
1261   feature_levels.NumFeatureLevels = ARRAY_SIZE(levels);
1262   feature_levels.pFeatureLevelsRequested = levels;
1263   if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_FEATURE_LEVELS,
1264                                               &feature_levels,
1265                                               sizeof(feature_levels)))) {
1266      debug_printf("D3D12: failed to get device feature levels\n");
1267      return false;
1268   }
1269   screen->max_feature_level = feature_levels.MaxSupportedFeatureLevel;
1270
1271   D3D12_COMMAND_QUEUE_DESC queue_desc;
1272   queue_desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
1273   queue_desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
1274   queue_desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
1275   queue_desc.NodeMask = 0;
1276
1277   ID3D12Device9 *device9;
1278   if (SUCCEEDED(screen->dev->QueryInterface(&device9))) {
1279      if (FAILED(device9->CreateCommandQueue1(&queue_desc, OpenGLOn12CreatorID,
1280                                              IID_PPV_ARGS(&screen->cmdqueue))))
1281         return false;
1282      device9->Release();
1283   } else {
1284      if (FAILED(screen->dev->CreateCommandQueue(&queue_desc,
1285                                                 IID_PPV_ARGS(&screen->cmdqueue))))
1286         return false;
1287   }
1288
1289   if (FAILED(screen->dev->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&screen->fence))))
1290      return false;
1291
1292   if (!d3d12_init_residency(screen))
1293      return false;
1294
1295   UINT64 timestamp_freq;
1296   if (FAILED(screen->cmdqueue->GetTimestampFrequency(&timestamp_freq)))
1297       timestamp_freq = 10000000;
1298   screen->timestamp_multiplier = 1000000000.0 / timestamp_freq;
1299
1300   d3d12_screen_fence_init(&screen->base);
1301   d3d12_screen_resource_init(&screen->base);
1302#ifdef HAVE_GALLIUM_D3D12_VIDEO
1303   d3d12_screen_video_init(&screen->base);
1304#endif
1305   slab_create_parent(&screen->transfer_pool, sizeof(struct d3d12_transfer), 16);
1306
1307   struct pb_desc desc;
1308   desc.alignment = D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT;
1309   desc.usage = (pb_usage_flags)(PB_USAGE_CPU_WRITE | PB_USAGE_GPU_READ);
1310
1311   screen->bufmgr = d3d12_bufmgr_create(screen);
1312   if (!screen->bufmgr)
1313      return false;
1314
1315   screen->cache_bufmgr = pb_cache_manager_create(screen->bufmgr, 0xfffff, 2, 0, 512 * 1024 * 1024);
1316   if (!screen->cache_bufmgr)
1317      return false;
1318
1319   screen->slab_bufmgr = pb_slab_range_manager_create(screen->cache_bufmgr, 16,
1320                                                      D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT,
1321                                                      D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT,
1322                                                      &desc);
1323   if (!screen->slab_bufmgr)
1324      return false;
1325
1326   desc.usage = (pb_usage_flags)(PB_USAGE_CPU_READ_WRITE | PB_USAGE_GPU_WRITE);
1327   screen->readback_slab_bufmgr = pb_slab_range_manager_create(screen->cache_bufmgr, 16,
1328                                                               D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT,
1329                                                               D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT,
1330                                                               &desc);
1331   if (!screen->readback_slab_bufmgr)
1332      return false;
1333
1334   screen->rtv_pool = d3d12_descriptor_pool_new(screen,
1335                                                D3D12_DESCRIPTOR_HEAP_TYPE_RTV,
1336                                                64);
1337   screen->dsv_pool = d3d12_descriptor_pool_new(screen,
1338                                                D3D12_DESCRIPTOR_HEAP_TYPE_DSV,
1339                                                64);
1340   screen->view_pool = d3d12_descriptor_pool_new(screen,
1341                                                 D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
1342                                                 1024);
1343   if (!screen->rtv_pool || !screen->dsv_pool || !screen->view_pool)
1344      return false;
1345
1346   d3d12_init_null_srvs(screen);
1347   d3d12_init_null_uavs(screen);
1348   d3d12_init_null_rtv(screen);
1349
1350   screen->have_load_at_vertex = can_attribute_at_vertex(screen);
1351   screen->support_shader_images = can_shader_image_load_all_formats(screen);
1352   ID3D12Device8 *dev8;
1353   if (SUCCEEDED(screen->dev->QueryInterface(&dev8))) {
1354      dev8->Release();
1355      screen->support_create_not_resident = true;
1356   }
1357
1358   screen->nir_options = *dxil_get_nir_compiler_options();
1359
1360   static constexpr uint64_t known_good_warp_version = 10ull << 48 | 22000ull << 16;
1361   if ((screen->vendor_id == HW_VENDOR_MICROSOFT &&
1362        screen->driver_version < known_good_warp_version) ||
1363      !screen->opts1.Int64ShaderOps) {
1364      /* Work around old versions of WARP that are completely broken for 64bit shifts */
1365      screen->nir_options.lower_pack_64_2x32_split = false;
1366      screen->nir_options.lower_unpack_64_2x32_split = false;
1367      screen->nir_options.lower_int64_options = (nir_lower_int64_options)~0;
1368   }
1369
1370   if (!screen->opts.DoublePrecisionFloatShaderOps)
1371      screen->nir_options.lower_doubles_options = (nir_lower_doubles_options)~0;
1372
1373   const char *mesa_version = "Mesa " PACKAGE_VERSION MESA_GIT_SHA1;
1374   struct mesa_sha1 sha1_ctx;
1375   uint8_t sha1[SHA1_DIGEST_LENGTH];
1376   STATIC_ASSERT(PIPE_UUID_SIZE <= sizeof(sha1));
1377
1378   /* The driver UUID is used for determining sharability of images and memory
1379    * between two instances in separate processes.  People who want to
1380    * share memory need to also check the device UUID or LUID so all this
1381    * needs to be is the build-id.
1382    */
1383   _mesa_sha1_compute(mesa_version, strlen(mesa_version), sha1);
1384   memcpy(screen->driver_uuid, sha1, PIPE_UUID_SIZE);
1385
1386   /* The device UUID uniquely identifies the given device within the machine. */
1387   _mesa_sha1_init(&sha1_ctx);
1388   _mesa_sha1_update(&sha1_ctx, &screen->vendor_id, sizeof(screen->vendor_id));
1389   _mesa_sha1_update(&sha1_ctx, &screen->device_id, sizeof(screen->device_id));
1390   _mesa_sha1_update(&sha1_ctx, &screen->subsys_id, sizeof(screen->subsys_id));
1391   _mesa_sha1_update(&sha1_ctx, &screen->revision, sizeof(screen->revision));
1392   _mesa_sha1_final(&sha1_ctx, sha1);
1393   memcpy(screen->device_uuid, sha1, PIPE_UUID_SIZE);
1394
1395   glsl_type_singleton_init_or_ref();
1396   return true;
1397}
1398