• 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 "dzn_private.h"
25 
26 #define D3D12_IGNORE_SDK_LAYERS
27 #define COBJMACROS
28 #include <directx/d3d12.h>
29 
30 #include <vulkan/vulkan.h>
31 
32 #include "util/format/u_format.h"
33 #include "util/log.h"
34 
35 #include <directx/d3d12sdklayers.h>
36 #include <util/u_dl.h>
37 
38 static const DXGI_FORMAT formats[PIPE_FORMAT_COUNT] = {
39 #define MAP_FORMAT_NORM(FMT) \
40    [PIPE_FORMAT_ ## FMT ## _UNORM] = DXGI_FORMAT_ ## FMT ## _UNORM, \
41    [PIPE_FORMAT_ ## FMT ## _SNORM] = DXGI_FORMAT_ ## FMT ## _SNORM,
42 
43 #define MAP_FORMAT_INT(FMT) \
44    [PIPE_FORMAT_ ## FMT ## _UINT] = DXGI_FORMAT_ ## FMT ## _UINT, \
45    [PIPE_FORMAT_ ## FMT ## _SINT] = DXGI_FORMAT_ ## FMT ## _SINT,
46 
47 #define MAP_FORMAT_SRGB(FMT) \
48    [PIPE_FORMAT_ ## FMT ## _SRGB] = DXGI_FORMAT_ ## FMT ## _UNORM_SRGB,
49 
50 #define MAP_FORMAT_FLOAT(FMT) \
51    [PIPE_FORMAT_ ## FMT ## _FLOAT] = DXGI_FORMAT_ ## FMT ## _FLOAT,
52 
53 #define MAP_EMU_FORMAT_NO_ALPHA(BITS, TYPE) \
54    [PIPE_FORMAT_L ## BITS ## _ ## TYPE] = DXGI_FORMAT_R ## BITS ## _ ## TYPE, \
55    [PIPE_FORMAT_I ## BITS ## _ ## TYPE] = DXGI_FORMAT_R ## BITS ## _ ## TYPE, \
56    [PIPE_FORMAT_L ## BITS ## A ## BITS ## _ ## TYPE] = \
57           DXGI_FORMAT_R ## BITS ## G ## BITS ## _ ## TYPE,
58 
59 #define MAP_EMU_FORMAT(BITS, TYPE) \
60    [PIPE_FORMAT_A ## BITS ## _ ## TYPE] = DXGI_FORMAT_R ## BITS ## _ ## TYPE, \
61    MAP_EMU_FORMAT_NO_ALPHA(BITS, TYPE)
62 
63    MAP_FORMAT_NORM(R8)
64    MAP_FORMAT_INT(R8)
65 
66    MAP_FORMAT_NORM(R8G8)
67    MAP_FORMAT_INT(R8G8)
68 
69    MAP_FORMAT_NORM(R8G8B8A8)
70    MAP_FORMAT_INT(R8G8B8A8)
71    MAP_FORMAT_SRGB(R8G8B8A8)
72 
73    [PIPE_FORMAT_B8G8R8X8_UNORM] = DXGI_FORMAT_B8G8R8X8_UNORM,
74    [PIPE_FORMAT_B8G8R8A8_UNORM] = DXGI_FORMAT_B8G8R8A8_UNORM,
75    [PIPE_FORMAT_B4G4R4A4_UNORM] = DXGI_FORMAT_B4G4R4A4_UNORM,
76    [PIPE_FORMAT_A4R4G4B4_UNORM] = DXGI_FORMAT_B4G4R4A4_UNORM,
77    [PIPE_FORMAT_B5G6R5_UNORM] = DXGI_FORMAT_B5G6R5_UNORM,
78    [PIPE_FORMAT_B5G5R5A1_UNORM] = DXGI_FORMAT_B5G5R5A1_UNORM,
79 
80    MAP_FORMAT_SRGB(B8G8R8A8)
81 
82    MAP_FORMAT_INT(R32)
83    MAP_FORMAT_FLOAT(R32)
84    MAP_FORMAT_INT(R32G32)
85    MAP_FORMAT_FLOAT(R32G32)
86    MAP_FORMAT_INT(R32G32B32)
87    MAP_FORMAT_FLOAT(R32G32B32)
88    MAP_FORMAT_INT(R32G32B32A32)
89    MAP_FORMAT_FLOAT(R32G32B32A32)
90 
91    MAP_FORMAT_NORM(R16)
92    MAP_FORMAT_INT(R16)
93    MAP_FORMAT_FLOAT(R16)
94 
95    MAP_FORMAT_NORM(R16G16)
96    MAP_FORMAT_INT(R16G16)
97    MAP_FORMAT_FLOAT(R16G16)
98 
99    MAP_FORMAT_NORM(R16G16B16A16)
100    MAP_FORMAT_INT(R16G16B16A16)
101    MAP_FORMAT_FLOAT(R16G16B16A16)
102 
103    [PIPE_FORMAT_A8_UNORM] = DXGI_FORMAT_A8_UNORM,
104    MAP_EMU_FORMAT_NO_ALPHA(8, UNORM)
105    MAP_EMU_FORMAT(8, SNORM)
106    MAP_EMU_FORMAT(8, SINT)
107    MAP_EMU_FORMAT(8, UINT)
108    MAP_EMU_FORMAT(16, UNORM)
109    MAP_EMU_FORMAT(16, SNORM)
110    MAP_EMU_FORMAT(16, SINT)
111    MAP_EMU_FORMAT(16, UINT)
112    MAP_EMU_FORMAT(16, FLOAT)
113    MAP_EMU_FORMAT(32, SINT)
114    MAP_EMU_FORMAT(32, UINT)
115    MAP_EMU_FORMAT(32, FLOAT)
116 
117    [PIPE_FORMAT_R9G9B9E5_FLOAT] = DXGI_FORMAT_R9G9B9E5_SHAREDEXP,
118    [PIPE_FORMAT_R11G11B10_FLOAT] = DXGI_FORMAT_R11G11B10_FLOAT,
119    [PIPE_FORMAT_R10G10B10A2_UINT] = DXGI_FORMAT_R10G10B10A2_UINT,
120    [PIPE_FORMAT_R10G10B10A2_UNORM] = DXGI_FORMAT_R10G10B10A2_UNORM,
121 
122    [PIPE_FORMAT_DXT1_RGB] = DXGI_FORMAT_BC1_UNORM,
123    [PIPE_FORMAT_DXT1_RGBA] = DXGI_FORMAT_BC1_UNORM,
124    [PIPE_FORMAT_DXT3_RGBA] = DXGI_FORMAT_BC2_UNORM,
125    [PIPE_FORMAT_DXT5_RGBA] = DXGI_FORMAT_BC3_UNORM,
126 
127    [PIPE_FORMAT_DXT1_SRGB] = DXGI_FORMAT_BC1_UNORM_SRGB,
128    [PIPE_FORMAT_DXT1_SRGBA] = DXGI_FORMAT_BC1_UNORM_SRGB,
129    [PIPE_FORMAT_DXT3_SRGBA] = DXGI_FORMAT_BC2_UNORM_SRGB,
130    [PIPE_FORMAT_DXT5_SRGBA] = DXGI_FORMAT_BC3_UNORM_SRGB,
131 
132    [PIPE_FORMAT_RGTC1_UNORM] = DXGI_FORMAT_BC4_UNORM,
133    [PIPE_FORMAT_RGTC1_SNORM] = DXGI_FORMAT_BC4_SNORM,
134    [PIPE_FORMAT_RGTC2_UNORM] = DXGI_FORMAT_BC5_UNORM,
135    [PIPE_FORMAT_RGTC2_SNORM] = DXGI_FORMAT_BC5_SNORM,
136 
137    [PIPE_FORMAT_BPTC_RGB_UFLOAT] = DXGI_FORMAT_BC6H_UF16,
138    [PIPE_FORMAT_BPTC_RGB_FLOAT] = DXGI_FORMAT_BC6H_SF16,
139    [PIPE_FORMAT_BPTC_RGBA_UNORM] = DXGI_FORMAT_BC7_UNORM,
140    [PIPE_FORMAT_BPTC_SRGBA] = DXGI_FORMAT_BC7_UNORM_SRGB,
141 
142    [PIPE_FORMAT_Z32_FLOAT] = DXGI_FORMAT_R32_TYPELESS,
143    [PIPE_FORMAT_Z16_UNORM] = DXGI_FORMAT_R16_TYPELESS,
144    [PIPE_FORMAT_Z24X8_UNORM] = DXGI_FORMAT_R24G8_TYPELESS,
145    [PIPE_FORMAT_X24S8_UINT] = DXGI_FORMAT_R24G8_TYPELESS,
146 
147    [PIPE_FORMAT_Z24_UNORM_S8_UINT] = DXGI_FORMAT_R24G8_TYPELESS,
148    [PIPE_FORMAT_Z32_FLOAT_S8X24_UINT] = DXGI_FORMAT_R32G8X24_TYPELESS,
149    [PIPE_FORMAT_X32_S8X24_UINT] = DXGI_FORMAT_R32G8X24_TYPELESS,
150 };
151 
152 DXGI_FORMAT
dzn_pipe_to_dxgi_format(enum pipe_format in)153 dzn_pipe_to_dxgi_format(enum pipe_format in)
154 {
155    return formats[in];
156 }
157 
158 DXGI_FORMAT
dzn_get_typeless_dxgi_format(DXGI_FORMAT in)159 dzn_get_typeless_dxgi_format(DXGI_FORMAT in)
160 {
161    if (in >= DXGI_FORMAT_R32G32B32A32_TYPELESS && in <= DXGI_FORMAT_R32G32B32A32_SINT)
162       return DXGI_FORMAT_R32G32B32A32_TYPELESS;
163    if (in >= DXGI_FORMAT_R32G32B32_TYPELESS && in <= DXGI_FORMAT_R32G32B32_SINT)
164       return DXGI_FORMAT_R32G32B32_TYPELESS;
165    if (in >= DXGI_FORMAT_R16G16B16A16_TYPELESS && in <= DXGI_FORMAT_R16G16B16A16_SINT)
166       return DXGI_FORMAT_R16G16B16A16_TYPELESS;
167    if (in >= DXGI_FORMAT_R32G32_TYPELESS && in <= DXGI_FORMAT_R32G32_SINT)
168       return DXGI_FORMAT_R32G32_TYPELESS;
169    if (in >= DXGI_FORMAT_R32G8X24_TYPELESS && in <= DXGI_FORMAT_X32_TYPELESS_G8X24_UINT)
170       return DXGI_FORMAT_R32G8X24_TYPELESS;
171    if (in >= DXGI_FORMAT_R10G10B10A2_TYPELESS && in <= DXGI_FORMAT_R10G10B10A2_UINT)
172       return DXGI_FORMAT_R10G10B10A2_TYPELESS;
173    if (in >= DXGI_FORMAT_R8G8B8A8_TYPELESS && in <= DXGI_FORMAT_R8G8B8A8_SINT)
174       return DXGI_FORMAT_R8G8B8A8_TYPELESS;
175    if (in >= DXGI_FORMAT_R16G16_TYPELESS && in <= DXGI_FORMAT_R16G16_SINT)
176       return DXGI_FORMAT_R16G16_TYPELESS;
177    if (in >= DXGI_FORMAT_R32_TYPELESS && in <= DXGI_FORMAT_R32_SINT)
178       return DXGI_FORMAT_R32_TYPELESS;
179    if (in >= DXGI_FORMAT_R24G8_TYPELESS && in <= DXGI_FORMAT_X24_TYPELESS_G8_UINT)
180       return DXGI_FORMAT_R24G8_TYPELESS;
181    if (in >= DXGI_FORMAT_R8G8_TYPELESS && in <= DXGI_FORMAT_R8G8_SINT)
182       return DXGI_FORMAT_R8G8_TYPELESS;
183    if (in >= DXGI_FORMAT_R16_TYPELESS && in <= DXGI_FORMAT_R16_SINT)
184       return DXGI_FORMAT_R16_TYPELESS;
185    if (in >= DXGI_FORMAT_R8_TYPELESS && in <= DXGI_FORMAT_R8_SINT)
186       return DXGI_FORMAT_R8_TYPELESS;
187    if (in >= DXGI_FORMAT_BC1_TYPELESS && in <= DXGI_FORMAT_BC1_UNORM_SRGB)
188       return DXGI_FORMAT_BC1_TYPELESS;
189    if (in >= DXGI_FORMAT_BC2_TYPELESS && in <= DXGI_FORMAT_BC2_UNORM_SRGB)
190       return DXGI_FORMAT_BC2_TYPELESS;
191    if (in >= DXGI_FORMAT_BC3_TYPELESS && in <= DXGI_FORMAT_BC3_UNORM_SRGB)
192       return DXGI_FORMAT_BC3_TYPELESS;
193    if (in >= DXGI_FORMAT_BC4_TYPELESS && in <= DXGI_FORMAT_BC4_SNORM)
194       return DXGI_FORMAT_BC4_TYPELESS;
195    if (in >= DXGI_FORMAT_BC5_TYPELESS && in <= DXGI_FORMAT_BC5_SNORM)
196       return DXGI_FORMAT_BC5_TYPELESS;
197    if (in == DXGI_FORMAT_B8G8R8A8_UNORM ||
198        (in >= DXGI_FORMAT_B8G8R8A8_TYPELESS && in <= DXGI_FORMAT_B8G8R8A8_UNORM_SRGB))
199       return DXGI_FORMAT_B8G8R8A8_TYPELESS;
200    if (in == DXGI_FORMAT_B8G8R8X8_UNORM ||
201        (in >= DXGI_FORMAT_B8G8R8X8_TYPELESS && in <= DXGI_FORMAT_B8G8R8X8_UNORM_SRGB))
202       return DXGI_FORMAT_B8G8R8X8_TYPELESS;
203    if (in >= DXGI_FORMAT_BC6H_TYPELESS && in <= DXGI_FORMAT_BC6H_SF16)
204       return DXGI_FORMAT_BC6H_TYPELESS;
205    if (in >= DXGI_FORMAT_BC7_TYPELESS && in <= DXGI_FORMAT_BC7_UNORM_SRGB)
206       return DXGI_FORMAT_BC7_TYPELESS;
207 
208    return in;
209 }
210 
211 struct dzn_sampler_filter_info {
212    VkFilter min, mag;
213    VkSamplerMipmapMode mipmap;
214 };
215 
216 #define FILTER(__min, __mag, __mipmap) \
217 { \
218    .min = VK_FILTER_ ## __min, \
219    .mag = VK_FILTER_ ## __mag, \
220    .mipmap = VK_SAMPLER_MIPMAP_MODE_ ## __mipmap, \
221 }
222 
223 static const struct dzn_sampler_filter_info filter_table[] = {
224    [D3D12_FILTER_MIN_MAG_MIP_POINT] = FILTER(NEAREST, NEAREST, NEAREST),
225    [D3D12_FILTER_MIN_MAG_POINT_MIP_LINEAR] = FILTER(NEAREST, NEAREST, LINEAR),
226    [D3D12_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT] = FILTER(NEAREST, LINEAR, NEAREST),
227    [D3D12_FILTER_MIN_POINT_MAG_MIP_LINEAR] = FILTER(NEAREST, LINEAR, LINEAR),
228    [D3D12_FILTER_MIN_LINEAR_MAG_MIP_POINT] = FILTER(LINEAR, NEAREST, NEAREST),
229    [D3D12_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR] = FILTER(LINEAR, NEAREST, LINEAR),
230    [D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT] = FILTER(LINEAR, LINEAR, NEAREST),
231    [D3D12_FILTER_MIN_MAG_MIP_LINEAR] = FILTER(LINEAR, LINEAR, LINEAR),
232 };
233 
234 D3D12_FILTER
dzn_translate_sampler_filter(const VkSamplerCreateInfo * create_info)235 dzn_translate_sampler_filter(const VkSamplerCreateInfo *create_info)
236 {
237    D3D12_FILTER filter = (D3D12_FILTER)0;
238 
239    if (!create_info->anisotropyEnable) {
240       unsigned i;
241       for (i = 0; i < ARRAY_SIZE(filter_table); i++) {
242          if (create_info->minFilter == filter_table[i].min &&
243              create_info->magFilter == filter_table[i].mag &&
244              create_info->mipmapMode == filter_table[i].mipmap) {
245             filter = (D3D12_FILTER)i;
246             break;
247          }
248       }
249 
250       assert(i < ARRAY_SIZE(filter_table));
251    } else {
252       filter = D3D12_FILTER_ANISOTROPIC;
253    }
254 
255    if (create_info->compareEnable)
256       filter = (D3D12_FILTER)(filter + D3D12_FILTER_COMPARISON_MIN_MAG_MIP_POINT);
257 
258    return filter;
259 }
260 
261 D3D12_COMPARISON_FUNC
dzn_translate_compare_op(VkCompareOp in)262 dzn_translate_compare_op(VkCompareOp in)
263 {
264    switch (in) {
265    case VK_COMPARE_OP_NEVER: return D3D12_COMPARISON_FUNC_NEVER;
266    case VK_COMPARE_OP_LESS: return D3D12_COMPARISON_FUNC_LESS;
267    case VK_COMPARE_OP_EQUAL: return D3D12_COMPARISON_FUNC_EQUAL;
268    case VK_COMPARE_OP_LESS_OR_EQUAL: return D3D12_COMPARISON_FUNC_LESS_EQUAL;
269    case VK_COMPARE_OP_GREATER: return D3D12_COMPARISON_FUNC_GREATER;
270    case VK_COMPARE_OP_NOT_EQUAL: return D3D12_COMPARISON_FUNC_NOT_EQUAL;
271    case VK_COMPARE_OP_GREATER_OR_EQUAL: return D3D12_COMPARISON_FUNC_GREATER_EQUAL;
272    case VK_COMPARE_OP_ALWAYS: return D3D12_COMPARISON_FUNC_ALWAYS;
273    default: unreachable("Invalid compare op");
274    }
275 }
276 
277 void
dzn_translate_viewport(D3D12_VIEWPORT * out,const VkViewport * in)278 dzn_translate_viewport(D3D12_VIEWPORT *out,
279                        const VkViewport *in)
280 {
281    out->TopLeftX = in->x;
282    out->TopLeftY = in->height < 0 ? in->height + in->y : in->y;
283    out->Width = in->width;
284    out->Height = fabs(in->height);
285    out->MinDepth = MIN2(in->minDepth, in->maxDepth);
286    out->MaxDepth = MAX2(in->maxDepth, in->minDepth);
287 }
288 
289 void
dzn_translate_rect(D3D12_RECT * out,const VkRect2D * in)290 dzn_translate_rect(D3D12_RECT *out,
291                    const VkRect2D *in)
292 {
293    out->left = in->offset.x;
294    out->top = in->offset.y;
295    out->right = in->offset.x + in->extent.width;
296    out->bottom = in->offset.y + in->extent.height;
297 }
298 
299 static ID3D12Debug *
get_debug_interface()300 get_debug_interface()
301 {
302    typedef HRESULT(WINAPI *PFN_D3D12_GET_DEBUG_INTERFACE)(REFIID riid, void **ppFactory);
303    PFN_D3D12_GET_DEBUG_INTERFACE D3D12GetDebugInterface;
304 
305    struct util_dl_library *d3d12_mod = util_dl_open(UTIL_DL_PREFIX "d3d12" UTIL_DL_EXT);
306    if (!d3d12_mod) {
307       mesa_loge("failed to load D3D12\n");
308       return NULL;
309    }
310 
311    D3D12GetDebugInterface = (PFN_D3D12_GET_DEBUG_INTERFACE)util_dl_get_proc_address(d3d12_mod, "D3D12GetDebugInterface");
312    if (!D3D12GetDebugInterface) {
313       mesa_loge("failed to load D3D12GetDebugInterface from D3D12.DLL\n");
314       return NULL;
315    }
316 
317    ID3D12Debug *debug;
318    if (FAILED(D3D12GetDebugInterface(&IID_ID3D12Debug, (void **)&debug))) {
319       mesa_loge("D3D12GetDebugInterface failed\n");
320       return NULL;
321    }
322 
323    return debug;
324 }
325 
326 void
d3d12_enable_debug_layer(void)327 d3d12_enable_debug_layer(void)
328 {
329    ID3D12Debug *debug = get_debug_interface();
330    if (debug) {
331       ID3D12Debug_EnableDebugLayer(debug);
332       ID3D12Debug_Release(debug);
333    }
334 }
335 
336 void
d3d12_enable_gpu_validation(void)337 d3d12_enable_gpu_validation(void)
338 {
339    ID3D12Debug *debug = get_debug_interface();
340    if (debug) {
341       ID3D12Debug3 *debug3;
342       if (SUCCEEDED(ID3D12Debug_QueryInterface(debug,
343                                                &IID_ID3D12Debug3,
344                                                (void **)&debug3))) {
345          ID3D12Debug3_SetEnableGPUBasedValidation(debug3, true);
346          ID3D12Debug3_Release(debug3);
347       }
348       ID3D12Debug_Release(debug);
349    }
350 }
351 
352 ID3D12Device2 *
d3d12_create_device(IUnknown * adapter,bool experimental_features)353 d3d12_create_device(IUnknown *adapter, bool experimental_features)
354 {
355    typedef HRESULT(WINAPI *PFN_D3D12CREATEDEVICE)(IUnknown *, D3D_FEATURE_LEVEL, REFIID, void **);
356    PFN_D3D12CREATEDEVICE D3D12CreateDevice;
357 
358    struct util_dl_library *d3d12_mod = util_dl_open(UTIL_DL_PREFIX "d3d12" UTIL_DL_EXT);
359    if (!d3d12_mod) {
360       mesa_loge("failed to load D3D12\n");
361       return NULL;
362    }
363 
364 #ifdef _WIN32
365    if (experimental_features)
366 #endif
367    {
368       typedef HRESULT(WINAPI *PFN_D3D12ENABLEEXPERIMENTALFEATURES)(UINT, const IID *, void *, UINT *);
369       PFN_D3D12ENABLEEXPERIMENTALFEATURES D3D12EnableExperimentalFeatures =
370          (PFN_D3D12ENABLEEXPERIMENTALFEATURES)util_dl_get_proc_address(d3d12_mod, "D3D12EnableExperimentalFeatures");
371       if (FAILED(D3D12EnableExperimentalFeatures(1, &D3D12ExperimentalShaderModels, NULL, NULL))) {
372          mesa_loge("failed to enable experimental shader models\n");
373          return NULL;
374       }
375    }
376 
377    D3D12CreateDevice = (PFN_D3D12CREATEDEVICE)util_dl_get_proc_address(d3d12_mod, "D3D12CreateDevice");
378    if (!D3D12CreateDevice) {
379       mesa_loge("failed to load D3D12CreateDevice from D3D12\n");
380       return NULL;
381    }
382 
383    ID3D12Device2 *dev;
384    if (SUCCEEDED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0,
385                  &IID_ID3D12Device2,
386                  (void **)&dev)))
387       return dev;
388 
389    mesa_loge("D3D12CreateDevice failed\n");
390    return NULL;
391 }
392 
393 PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE
d3d12_get_serialize_root_sig(void)394 d3d12_get_serialize_root_sig(void)
395 {
396    struct util_dl_library *d3d12_mod = util_dl_open(UTIL_DL_PREFIX "d3d12" UTIL_DL_EXT);
397    if (!d3d12_mod) {
398       mesa_loge("failed to load D3D12\n");
399       return NULL;
400    }
401 
402    return (PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE)
403       util_dl_get_proc_address(d3d12_mod, "D3D12SerializeVersionedRootSignature");
404 }
405