• 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 #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>
56 static GUID OpenGLOn12CreatorID = { 0x6bb3cd34, 0x0d19, 0x45ab, 0x97, 0xed, 0xd7, 0x20, 0xba, 0x3d, 0xfc, 0x80 };
57 
58 static const struct debug_named_value
59 d3d12_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 
71 DEBUG_GET_ONCE_FLAGS_OPTION(d3d12_debug, "D3D12_DEBUG", d3d12_debug_options, 0)
72 
73 uint32_t
74 d3d12_debug;
75 
76 enum {
77     HW_VENDOR_AMD                   = 0x1002,
78     HW_VENDOR_INTEL                 = 0x8086,
79     HW_VENDOR_MICROSOFT             = 0x1414,
80     HW_VENDOR_NVIDIA                = 0x10de,
81 };
82 
83 static const char *
d3d12_get_vendor(struct pipe_screen * pscreen)84 d3d12_get_vendor(struct pipe_screen *pscreen)
85 {
86    return "Microsoft Corporation";
87 }
88 
89 static const char *
d3d12_get_device_vendor(struct pipe_screen * pscreen)90 d3d12_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 
108 static int
d3d12_get_video_mem(struct pipe_screen * pscreen)109 d3d12_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 
116 static int
d3d12_get_param(struct pipe_screen * pscreen,enum pipe_cap param)117 d3d12_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 
347 static float
d3d12_get_paramf(struct pipe_screen * pscreen,enum pipe_capf param)348 d3d12_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 
387 static int
d3d12_get_shader_param(struct pipe_screen * pscreen,enum pipe_shader_type shader,enum pipe_shader_cap param)388 d3d12_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 
502 static int
d3d12_get_compute_param(struct pipe_screen * pscreen,enum pipe_shader_ir ir,enum pipe_compute_cap cap,void * ret)503 d3d12_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 
533 static bool
d3d12_is_format_supported(struct pipe_screen * pscreen,enum pipe_format format,enum pipe_texture_target target,unsigned sample_count,unsigned storage_sample_count,unsigned bind)534 d3d12_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 
694 void
d3d12_deinit_screen(struct d3d12_screen * screen)695 d3d12_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 
740 void
d3d12_destroy_screen(struct d3d12_screen * screen)741 d3d12_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 
750 static void
d3d12_flush_frontbuffer(struct pipe_screen * pscreen,struct pipe_context * pctx,struct pipe_resource * pres,unsigned level,unsigned layer,void * winsys_drawable_handle,struct pipe_box * sub_box)751 d3d12_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 
796 static ID3D12Debug *
get_debug_interface()797 get_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 
823 static void
enable_d3d12_debug_layer()824 enable_d3d12_debug_layer()
825 {
826    ID3D12Debug *debug = get_debug_interface();
827    if (debug) {
828       debug->EnableDebugLayer();
829       debug->Release();
830    }
831 }
832 
833 static void
enable_gpu_validation()834 enable_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 
847 static ID3D12Device3 *
create_device(IUnknown * adapter)848 create_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 
887 static bool
can_attribute_at_vertex(struct d3d12_screen * screen)888 can_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 
898 static bool
can_shader_image_load_all_formats(struct d3d12_screen * screen)899 can_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 
941 static void
d3d12_init_null_srvs(struct d3d12_screen * screen)942 d3d12_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 
1026 static void
d3d12_init_null_uavs(struct d3d12_screen * screen)1027 d3d12_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 
1086 static void
d3d12_init_null_rtv(struct d3d12_screen * screen)1087 d3d12_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 
1098 static void
d3d12_get_adapter_luid(struct pipe_screen * pscreen,char * luid)1099 d3d12_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 
1105 static void
d3d12_get_device_uuid(struct pipe_screen * pscreen,char * uuid)1106 d3d12_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 
1112 static void
d3d12_get_driver_uuid(struct pipe_screen * pscreen,char * uuid)1113 d3d12_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 
1119 static uint32_t
d3d12_get_node_mask(struct pipe_screen * pscreen)1120 d3d12_get_node_mask(struct pipe_screen *pscreen)
1121 {
1122    /* This implementation doesn't support linked adapters */
1123    return 1;
1124 }
1125 
1126 static void
d3d12_create_fence_win32(struct pipe_screen * pscreen,struct pipe_fence_handle ** pfence,void * handle,const void * name,enum pipe_fd_type type)1127 d3d12_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 
1135 static void
d3d12_set_fence_timeline_value(struct pipe_screen * pscreen,struct pipe_fence_handle * pfence,uint64_t value)1136 d3d12_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 
1141 void
d3d12_init_screen_base(struct d3d12_screen * screen,struct sw_winsys * winsys,LUID * adapter_luid)1142 d3d12_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 
1172 bool
d3d12_init_screen(struct d3d12_screen * screen,IUnknown * adapter)1173 d3d12_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