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