yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

Ellie HermaszewskaMove switch statement bodies to their own lines (#5493)b118451e3

master
36.2 KiB1185 linesraw
1// d3d-util.cpp
2#include "d3d-util.h"
3
4#include <d3d12.h>
5#include <dxgi1_4.h>
6#include <dxgidebug.h>
7#if SLANG_ENABLE_DXBC_SUPPORT
8#include <d3dcompiler.h>
9#endif
10
11// We will use the C standard library just for printing error messages.
12#include "core/slang-basic.h"
13#include "core/slang-platform.h"
14
15#include <stdio.h>
16
17#ifdef GFX_NV_AFTERMATH
18#include "GFSDK_Aftermath.h"
19#include "GFSDK_Aftermath_Defines.h"
20#include "GFSDK_Aftermath_GpuCrashDump.h"
21#include "core/slang-process.h"
22#endif
23
24namespace gfx
25{
26using namespace Slang;
27
28/* static */ D3D_PRIMITIVE_TOPOLOGY D3DUtil::getPrimitiveTopology(PrimitiveTopology topology)
29{
30    switch (topology)
31    {
32    case PrimitiveTopology::TriangleList:
33        return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
34    case PrimitiveTopology::TriangleStrip:
35        return D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
36    case PrimitiveTopology::LineList:
37        return D3D_PRIMITIVE_TOPOLOGY_LINELIST;
38    case PrimitiveTopology::LineStrip:
39        return D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
40    case PrimitiveTopology::PointList:
41        return D3D_PRIMITIVE_TOPOLOGY_POINTLIST;
42    default:
43        break;
44    }
45    return D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
46}
47
48D3D12_PRIMITIVE_TOPOLOGY_TYPE D3DUtil::getPrimitiveType(PrimitiveTopology topology)
49{
50    switch (topology)
51    {
52    case PrimitiveTopology::TriangleList:
53    case PrimitiveTopology::TriangleStrip:
54        return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
55    case PrimitiveTopology::LineList:
56    case PrimitiveTopology::LineStrip:
57        return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
58    case PrimitiveTopology::PointList:
59        return D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT;
60    default:
61        break;
62    }
63    return D3D12_PRIMITIVE_TOPOLOGY_TYPE_UNDEFINED;
64}
65
66D3D12_PRIMITIVE_TOPOLOGY_TYPE D3DUtil::getPrimitiveType(PrimitiveType type)
67{
68    switch (type)
69    {
70    case PrimitiveType::Point:
71        return D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT;
72    case PrimitiveType::Line:
73        return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
74    case PrimitiveType::Triangle:
75        return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
76    case PrimitiveType::Patch:
77        return D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH;
78    default:
79        break;
80    }
81    return D3D12_PRIMITIVE_TOPOLOGY_TYPE_UNDEFINED;
82}
83
84D3D12_COMPARISON_FUNC D3DUtil::getComparisonFunc(ComparisonFunc func)
85{
86    switch (func)
87    {
88    case gfx::ComparisonFunc::Never:
89        return D3D12_COMPARISON_FUNC_NEVER;
90    case gfx::ComparisonFunc::Less:
91        return D3D12_COMPARISON_FUNC_LESS;
92    case gfx::ComparisonFunc::Equal:
93        return D3D12_COMPARISON_FUNC_EQUAL;
94    case gfx::ComparisonFunc::LessEqual:
95        return D3D12_COMPARISON_FUNC_LESS_EQUAL;
96    case gfx::ComparisonFunc::Greater:
97        return D3D12_COMPARISON_FUNC_GREATER;
98    case gfx::ComparisonFunc::NotEqual:
99        return D3D12_COMPARISON_FUNC_NOT_EQUAL;
100    case gfx::ComparisonFunc::GreaterEqual:
101        return D3D12_COMPARISON_FUNC_GREATER_EQUAL;
102    case gfx::ComparisonFunc::Always:
103        return D3D12_COMPARISON_FUNC_ALWAYS;
104    default:
105        return D3D12_COMPARISON_FUNC_NEVER;
106    }
107}
108
109static D3D12_STENCIL_OP translateStencilOp(StencilOp op)
110{
111    switch (op)
112    {
113    case gfx::StencilOp::Keep:
114        return D3D12_STENCIL_OP_KEEP;
115    case gfx::StencilOp::Zero:
116        return D3D12_STENCIL_OP_ZERO;
117    case gfx::StencilOp::Replace:
118        return D3D12_STENCIL_OP_REPLACE;
119    case gfx::StencilOp::IncrementSaturate:
120        return D3D12_STENCIL_OP_INCR_SAT;
121    case gfx::StencilOp::DecrementSaturate:
122        return D3D12_STENCIL_OP_DECR_SAT;
123    case gfx::StencilOp::Invert:
124        return D3D12_STENCIL_OP_INVERT;
125    case gfx::StencilOp::IncrementWrap:
126        return D3D12_STENCIL_OP_INCR;
127    case gfx::StencilOp::DecrementWrap:
128        return D3D12_STENCIL_OP_DECR;
129    default:
130        return D3D12_STENCIL_OP_KEEP;
131    }
132}
133
134D3D12_DEPTH_STENCILOP_DESC D3DUtil::translateStencilOpDesc(DepthStencilOpDesc desc)
135{
136    D3D12_DEPTH_STENCILOP_DESC rs;
137    rs.StencilDepthFailOp = translateStencilOp(desc.stencilDepthFailOp);
138    rs.StencilFailOp = translateStencilOp(desc.stencilFailOp);
139    rs.StencilFunc = getComparisonFunc(desc.stencilFunc);
140    rs.StencilPassOp = translateStencilOp(desc.stencilPassOp);
141    return rs;
142}
143
144/* static */ DXGI_FORMAT D3DUtil::getMapFormat(Format format)
145{
146    switch (format)
147    {
148    case Format::R32G32B32A32_TYPELESS:
149        return DXGI_FORMAT_R32G32B32A32_TYPELESS;
150    case Format::R32G32B32_TYPELESS:
151        return DXGI_FORMAT_R32G32B32_TYPELESS;
152    case Format::R32G32_TYPELESS:
153        return DXGI_FORMAT_R32G32_TYPELESS;
154    case Format::R32_TYPELESS:
155        return DXGI_FORMAT_R32_TYPELESS;
156
157    case Format::R16G16B16A16_TYPELESS:
158        return DXGI_FORMAT_R16G16B16A16_TYPELESS;
159    case Format::R16G16_TYPELESS:
160        return DXGI_FORMAT_R16G16_TYPELESS;
161    case Format::R16_TYPELESS:
162        return DXGI_FORMAT_R16_TYPELESS;
163
164    case Format::R8G8B8A8_TYPELESS:
165        return DXGI_FORMAT_R8G8B8A8_TYPELESS;
166    case Format::R8G8_TYPELESS:
167        return DXGI_FORMAT_R8G8_TYPELESS;
168    case Format::R8_TYPELESS:
169        return DXGI_FORMAT_R8_TYPELESS;
170    case Format::B8G8R8A8_TYPELESS:
171        return DXGI_FORMAT_B8G8R8A8_TYPELESS;
172
173    case Format::R32G32B32A32_FLOAT:
174        return DXGI_FORMAT_R32G32B32A32_FLOAT;
175    case Format::R32G32B32_FLOAT:
176        return DXGI_FORMAT_R32G32B32_FLOAT;
177    case Format::R32G32_FLOAT:
178        return DXGI_FORMAT_R32G32_FLOAT;
179    case Format::R32_FLOAT:
180        return DXGI_FORMAT_R32_FLOAT;
181
182    case Format::R16G16B16A16_FLOAT:
183        return DXGI_FORMAT_R16G16B16A16_FLOAT;
184    case Format::R16G16_FLOAT:
185        return DXGI_FORMAT_R16G16_FLOAT;
186    case Format::R16_FLOAT:
187        return DXGI_FORMAT_R16_FLOAT;
188
189    case Format::R64_UINT:
190        return DXGI_FORMAT_R32G32_UINT;
191
192    case Format::R32G32B32A32_UINT:
193        return DXGI_FORMAT_R32G32B32A32_UINT;
194    case Format::R32G32B32_UINT:
195        return DXGI_FORMAT_R32G32B32_UINT;
196    case Format::R32G32_UINT:
197        return DXGI_FORMAT_R32G32_UINT;
198    case Format::R32_UINT:
199        return DXGI_FORMAT_R32_UINT;
200
201    case Format::R16G16B16A16_UINT:
202        return DXGI_FORMAT_R16G16B16A16_UINT;
203    case Format::R16G16_UINT:
204        return DXGI_FORMAT_R16G16_UINT;
205    case Format::R16_UINT:
206        return DXGI_FORMAT_R16_UINT;
207
208    case Format::R8G8B8A8_UINT:
209        return DXGI_FORMAT_R8G8B8A8_UINT;
210    case Format::R8G8_UINT:
211        return DXGI_FORMAT_R8G8_UINT;
212    case Format::R8_UINT:
213        return DXGI_FORMAT_R8_UINT;
214
215    case Format::R64_SINT:
216        return DXGI_FORMAT_R32G32_SINT;
217
218    case Format::R32G32B32A32_SINT:
219        return DXGI_FORMAT_R32G32B32A32_SINT;
220    case Format::R32G32B32_SINT:
221        return DXGI_FORMAT_R32G32B32_SINT;
222    case Format::R32G32_SINT:
223        return DXGI_FORMAT_R32G32_SINT;
224    case Format::R32_SINT:
225        return DXGI_FORMAT_R32_SINT;
226
227    case Format::R16G16B16A16_SINT:
228        return DXGI_FORMAT_R16G16B16A16_SINT;
229    case Format::R16G16_SINT:
230        return DXGI_FORMAT_R16G16_SINT;
231    case Format::R16_SINT:
232        return DXGI_FORMAT_R16_SINT;
233
234    case Format::R8G8B8A8_SINT:
235        return DXGI_FORMAT_R8G8B8A8_SINT;
236    case Format::R8G8_SINT:
237        return DXGI_FORMAT_R8G8_SINT;
238    case Format::R8_SINT:
239        return DXGI_FORMAT_R8_SINT;
240
241    case Format::R16G16B16A16_UNORM:
242        return DXGI_FORMAT_R16G16B16A16_UNORM;
243    case Format::R16G16_UNORM:
244        return DXGI_FORMAT_R16G16_UNORM;
245    case Format::R16_UNORM:
246        return DXGI_FORMAT_R16_UNORM;
247
248    case Format::R8G8B8A8_UNORM:
249        return DXGI_FORMAT_R8G8B8A8_UNORM;
250    case Format::R8G8B8A8_UNORM_SRGB:
251        return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
252    case Format::R8G8_UNORM:
253        return DXGI_FORMAT_R8G8_UNORM;
254    case Format::R8_UNORM:
255        return DXGI_FORMAT_R8_UNORM;
256    case Format::B8G8R8A8_UNORM:
257        return DXGI_FORMAT_B8G8R8A8_UNORM;
258    case Format::B8G8R8X8_UNORM:
259        return DXGI_FORMAT_B8G8R8X8_UNORM;
260    case Format::B8G8R8A8_UNORM_SRGB:
261        return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
262    case Format::B8G8R8X8_UNORM_SRGB:
263        return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB;
264
265    case Format::R16G16B16A16_SNORM:
266        return DXGI_FORMAT_R16G16B16A16_SNORM;
267    case Format::R16G16_SNORM:
268        return DXGI_FORMAT_R16G16_SNORM;
269    case Format::R16_SNORM:
270        return DXGI_FORMAT_R16_SNORM;
271
272    case Format::R8G8B8A8_SNORM:
273        return DXGI_FORMAT_R8G8B8A8_SNORM;
274    case Format::R8G8_SNORM:
275        return DXGI_FORMAT_R8G8_SNORM;
276    case Format::R8_SNORM:
277        return DXGI_FORMAT_R8_SNORM;
278
279    case Format::D32_FLOAT:
280        return DXGI_FORMAT_D32_FLOAT;
281    case Format::D16_UNORM:
282        return DXGI_FORMAT_D16_UNORM;
283    case Format::D32_FLOAT_S8_UINT:
284        return DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
285    case Format::R32_FLOAT_X32_TYPELESS:
286        return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
287
288    case Format::B4G4R4A4_UNORM:
289        return DXGI_FORMAT_B4G4R4A4_UNORM;
290    case Format::B5G6R5_UNORM:
291        return DXGI_FORMAT_B5G6R5_UNORM;
292    case Format::B5G5R5A1_UNORM:
293        return DXGI_FORMAT_B5G5R5A1_UNORM;
294
295    case Format::R9G9B9E5_SHAREDEXP:
296        return DXGI_FORMAT_R9G9B9E5_SHAREDEXP;
297    case Format::R10G10B10A2_TYPELESS:
298        return DXGI_FORMAT_R10G10B10A2_TYPELESS;
299    case Format::R10G10B10A2_UINT:
300        return DXGI_FORMAT_R10G10B10A2_UINT;
301    case Format::R10G10B10A2_UNORM:
302        return DXGI_FORMAT_R10G10B10A2_UNORM;
303    case Format::R11G11B10_FLOAT:
304        return DXGI_FORMAT_R11G11B10_FLOAT;
305
306    case Format::BC1_UNORM:
307        return DXGI_FORMAT_BC1_UNORM;
308    case Format::BC1_UNORM_SRGB:
309        return DXGI_FORMAT_BC1_UNORM_SRGB;
310    case Format::BC2_UNORM:
311        return DXGI_FORMAT_BC2_UNORM;
312    case Format::BC2_UNORM_SRGB:
313        return DXGI_FORMAT_BC2_UNORM_SRGB;
314    case Format::BC3_UNORM:
315        return DXGI_FORMAT_BC3_UNORM;
316    case Format::BC3_UNORM_SRGB:
317        return DXGI_FORMAT_BC3_UNORM_SRGB;
318    case Format::BC4_UNORM:
319        return DXGI_FORMAT_BC4_UNORM;
320    case Format::BC4_SNORM:
321        return DXGI_FORMAT_BC4_SNORM;
322    case Format::BC5_UNORM:
323        return DXGI_FORMAT_BC5_UNORM;
324    case Format::BC5_SNORM:
325        return DXGI_FORMAT_BC5_SNORM;
326    case Format::BC6H_UF16:
327        return DXGI_FORMAT_BC6H_UF16;
328    case Format::BC6H_SF16:
329        return DXGI_FORMAT_BC6H_SF16;
330    case Format::BC7_UNORM:
331        return DXGI_FORMAT_BC7_UNORM;
332    case Format::BC7_UNORM_SRGB:
333        return DXGI_FORMAT_BC7_UNORM_SRGB;
334
335    default:
336        return DXGI_FORMAT_UNKNOWN;
337    }
338}
339
340/* static */ DXGI_FORMAT
341D3DUtil::calcResourceFormat(UsageType usage, Int usageFlags, DXGI_FORMAT format)
342{
343    SLANG_UNUSED(usage);
344    if (usageFlags)
345    {
346        switch (format)
347        {
348        case DXGI_FORMAT_R32_FLOAT: /* fallthru */
349        case DXGI_FORMAT_R32_UINT:
350        case DXGI_FORMAT_D32_FLOAT:
351            {
352                return DXGI_FORMAT_R32_TYPELESS;
353            }
354        case DXGI_FORMAT_D24_UNORM_S8_UINT:
355            return DXGI_FORMAT_R24G8_TYPELESS;
356        default:
357            break;
358        }
359        return format;
360    }
361    return format;
362}
363
364/* static */ DXGI_FORMAT D3DUtil::calcFormat(UsageType usage, DXGI_FORMAT format)
365{
366    switch (usage)
367    {
368    case USAGE_COUNT_OF:
369    case USAGE_UNKNOWN:
370        {
371            return DXGI_FORMAT_UNKNOWN;
372        }
373    case USAGE_DEPTH_STENCIL:
374        {
375            switch (format)
376            {
377            case DXGI_FORMAT_D32_FLOAT: /* fallthru */
378            case DXGI_FORMAT_R32_TYPELESS:
379                {
380                    return DXGI_FORMAT_D32_FLOAT;
381                }
382            case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
383                return DXGI_FORMAT_D24_UNORM_S8_UINT;
384            case DXGI_FORMAT_R24G8_TYPELESS:
385                return DXGI_FORMAT_D24_UNORM_S8_UINT;
386            default:
387                break;
388            }
389            return format;
390        }
391    case USAGE_TARGET:
392        {
393            switch (format)
394            {
395            case DXGI_FORMAT_D32_FLOAT: /* fallthru */
396            case DXGI_FORMAT_D24_UNORM_S8_UINT:
397                {
398                    return DXGI_FORMAT_UNKNOWN;
399                }
400            case DXGI_FORMAT_R32_TYPELESS:
401                return DXGI_FORMAT_R32_FLOAT;
402            default:
403                break;
404            }
405            return format;
406        }
407    case USAGE_SRV:
408        {
409            switch (format)
410            {
411            case DXGI_FORMAT_D32_FLOAT: /* fallthru */
412            case DXGI_FORMAT_R32_TYPELESS:
413                {
414                    return DXGI_FORMAT_R32_FLOAT;
415                }
416            case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
417                return DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
418            default:
419                break;
420            }
421
422            return format;
423        }
424    }
425
426    assert(!"Not reachable");
427    return DXGI_FORMAT_UNKNOWN;
428}
429
430bool D3DUtil::isTypeless(DXGI_FORMAT format)
431{
432    switch (format)
433    {
434    case DXGI_FORMAT_R32G32B32A32_TYPELESS:
435    case DXGI_FORMAT_R32G32B32_TYPELESS:
436    case DXGI_FORMAT_R16G16B16A16_TYPELESS:
437    case DXGI_FORMAT_R32G32_TYPELESS:
438    case DXGI_FORMAT_R32G8X24_TYPELESS:
439    case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
440    case DXGI_FORMAT_R10G10B10A2_TYPELESS:
441    case DXGI_FORMAT_R8G8B8A8_TYPELESS:
442    case DXGI_FORMAT_R16G16_TYPELESS:
443    case DXGI_FORMAT_R32_TYPELESS:
444    case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
445    case DXGI_FORMAT_R24G8_TYPELESS:
446    case DXGI_FORMAT_R8G8_TYPELESS:
447    case DXGI_FORMAT_R16_TYPELESS:
448    case DXGI_FORMAT_R8_TYPELESS:
449    case DXGI_FORMAT_BC1_TYPELESS:
450    case DXGI_FORMAT_BC2_TYPELESS:
451    case DXGI_FORMAT_BC3_TYPELESS:
452    case DXGI_FORMAT_BC4_TYPELESS:
453    case DXGI_FORMAT_BC5_TYPELESS:
454    case DXGI_FORMAT_B8G8R8A8_TYPELESS:
455    case DXGI_FORMAT_BC6H_TYPELESS:
456    case DXGI_FORMAT_BC7_TYPELESS:
457        {
458            return true;
459        }
460    default:
461        break;
462    }
463    return false;
464}
465
466/* static */ Int D3DUtil::getNumColorChannelBits(DXGI_FORMAT fmt)
467{
468    switch (fmt)
469    {
470    case DXGI_FORMAT_R32G32B32A32_TYPELESS:
471    case DXGI_FORMAT_R32G32B32A32_FLOAT:
472    case DXGI_FORMAT_R32G32B32A32_UINT:
473    case DXGI_FORMAT_R32G32B32A32_SINT:
474    case DXGI_FORMAT_R32G32B32_TYPELESS:
475    case DXGI_FORMAT_R32G32B32_FLOAT:
476    case DXGI_FORMAT_R32G32B32_UINT:
477    case DXGI_FORMAT_R32G32B32_SINT:
478        {
479            return 32;
480        }
481    case DXGI_FORMAT_R16G16B16A16_TYPELESS:
482    case DXGI_FORMAT_R16G16B16A16_FLOAT:
483    case DXGI_FORMAT_R16G16B16A16_UNORM:
484    case DXGI_FORMAT_R16G16B16A16_UINT:
485    case DXGI_FORMAT_R16G16B16A16_SNORM:
486    case DXGI_FORMAT_R16G16B16A16_SINT:
487        {
488            return 16;
489        }
490    case DXGI_FORMAT_R10G10B10A2_TYPELESS:
491    case DXGI_FORMAT_R10G10B10A2_UNORM:
492    case DXGI_FORMAT_R10G10B10A2_UINT:
493    case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
494        {
495            return 10;
496        }
497    case DXGI_FORMAT_R8G8B8A8_TYPELESS:
498    case DXGI_FORMAT_R8G8B8A8_UNORM:
499    case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
500    case DXGI_FORMAT_R8G8B8A8_UINT:
501    case DXGI_FORMAT_R8G8B8A8_SNORM:
502    case DXGI_FORMAT_R8G8B8A8_SINT:
503    case DXGI_FORMAT_B8G8R8A8_UNORM:
504    case DXGI_FORMAT_B8G8R8X8_UNORM:
505    case DXGI_FORMAT_B8G8R8A8_TYPELESS:
506    case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
507    case DXGI_FORMAT_B8G8R8X8_TYPELESS:
508    case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
509        {
510            return 8;
511        }
512    case DXGI_FORMAT_B5G6R5_UNORM:
513    case DXGI_FORMAT_B5G5R5A1_UNORM:
514        {
515            return 5;
516        }
517    case DXGI_FORMAT_B4G4R4A4_UNORM:
518        return 4;
519
520    default:
521        return 0;
522    }
523}
524
525// Note: this subroutine is now only used by D3D11 for generating bytecode to go into input layouts.
526//
527// TODO: we can probably remove that code completely by switching to a PSO-like model across all
528// APIs.
529//
530/* static */ Result D3DUtil::compileHLSLShader(
531    char const* sourcePath,
532    char const* source,
533    char const* entryPointName,
534    char const* dxProfileName,
535    ComPtr<ID3DBlob>& shaderBlobOut)
536{
537#if !SLANG_ENABLE_DXBC_SUPPORT
538    return SLANG_E_NOT_IMPLEMENTED;
539#else
540    // Rather than statically link against the `d3dcompile` library, we
541    // dynamically load it.
542    //
543    // Note: A more realistic application would compile from HLSL text to D3D
544    // shader bytecode as part of an offline process, rather than doing it
545    // on-the-fly like this
546    //
547    static pD3DCompile compileFunc = nullptr;
548    if (!compileFunc)
549    {
550        // On Linux, vkd3d-utils isn't suitable as a unix replacement for fxc
551        // due to at least the following missing feature:
552        // https://bugs.winehq.org/show_bug.cgi?id=54872
553
554        // TODO(tfoley): maybe want to search for one of a few versions of the DLL
555        const char* const libName = "d3dcompiler_47";
556        SharedLibrary::Handle compilerModule;
557        if (SLANG_FAILED(SharedLibrary::load(libName, compilerModule)))
558        {
559            fprintf(stderr, "error: failed to load '%s'\n", libName);
560            return SLANG_FAIL;
561        }
562
563        compileFunc =
564            (pD3DCompile)SharedLibrary::findSymbolAddressByName(compilerModule, "D3DCompile");
565        if (!compileFunc)
566        {
567            fprintf(stderr, "error: failed load symbol 'D3DCompile'\n");
568            return SLANG_FAIL;
569        }
570    }
571
572    // For this example, we turn on debug output, and turn off all
573    // optimization. A real application would only use these flags
574    // when shader debugging is needed.
575    UINT flags = 0;
576    flags |= D3DCOMPILE_DEBUG;
577    flags |= D3DCOMPILE_OPTIMIZATION_LEVEL0 | D3DCOMPILE_SKIP_OPTIMIZATION;
578
579    // We will always define `__HLSL__` when compiling here, so that
580    // input code can react differently to being compiled as pure HLSL.
581    D3D_SHADER_MACRO defines[] = {
582        {"__HLSL__", "1"},
583        {nullptr, nullptr},
584    };
585
586    // The `D3DCompile` entry point takes a bunch of parameters, but we
587    // don't really need most of them for Slang-generated code.
588    ComPtr<ID3DBlob> shaderBlob;
589    ComPtr<ID3DBlob> errorBlob;
590
591    HRESULT hr = compileFunc(
592        source,
593        strlen(source),
594        sourcePath,
595        &defines[0],
596        nullptr,
597        entryPointName,
598        dxProfileName,
599        flags,
600        0,
601        shaderBlob.writeRef(),
602        errorBlob.writeRef());
603
604    // If the HLSL-to-bytecode compilation produced any diagnostic messages
605    // then we will print them out (whether or not the compilation failed).
606    if (errorBlob)
607    {
608        ::fputs((const char*)errorBlob->GetBufferPointer(), stderr);
609        ::fflush(stderr);
610#if SLANG_WINDOWS_FAMILY
611        ::OutputDebugStringA((const char*)errorBlob->GetBufferPointer());
612#endif
613    }
614
615    SLANG_RETURN_ON_FAIL(hr);
616    shaderBlobOut.swap(shaderBlob);
617    return SLANG_OK;
618#endif // SLANG_ENABLE_DXBC_SUPPORT
619}
620
621/* static */ SharedLibrary::Handle D3DUtil::getDxgiModule()
622{
623    const char* const libName = SLANG_ENABLE_DXVK ? "dxvk_dxgi" : "dxgi";
624
625    static SharedLibrary::Handle s_dxgiModule = [&]()
626    {
627        SharedLibrary::Handle h = nullptr;
628        SharedLibrary::load(libName, h);
629        if (!h)
630        {
631            fprintf(stderr, "error: failed to load dll '%s'\n", libName);
632        }
633        return h;
634    }();
635    return s_dxgiModule;
636}
637
638/* static */ SlangResult D3DUtil::createFactory(
639    DeviceCheckFlags flags,
640    ComPtr<IDXGIFactory>& outFactory)
641{
642    auto dxgiModule = getDxgiModule();
643    if (!dxgiModule)
644    {
645        return SLANG_FAIL;
646    }
647
648    typedef HRESULT(WINAPI * PFN_DXGI_CREATE_FACTORY)(REFIID riid, void** ppFactory);
649    typedef HRESULT(WINAPI * PFN_DXGI_CREATE_FACTORY_2)(UINT Flags, REFIID riid, void** ppFactory);
650
651    {
652        auto createFactory2 = (PFN_DXGI_CREATE_FACTORY_2)SharedLibrary::findSymbolAddressByName(
653            dxgiModule,
654            "CreateDXGIFactory2");
655        if (createFactory2)
656        {
657            UINT dxgiFlags = 0;
658
659            if (flags & DeviceCheckFlag::UseDebug)
660            {
661                dxgiFlags |= DXGI_CREATE_FACTORY_DEBUG;
662            }
663
664            ComPtr<IDXGIFactory4> factory;
665            SLANG_RETURN_ON_FAIL(createFactory2(dxgiFlags, IID_PPV_ARGS(factory.writeRef())));
666
667            outFactory = factory;
668            return SLANG_OK;
669        }
670    }
671
672    {
673        auto createFactory = (PFN_DXGI_CREATE_FACTORY)SharedLibrary::findSymbolAddressByName(
674            dxgiModule,
675            "CreateDXGIFactory");
676        if (!createFactory)
677        {
678            fprintf(stderr, "error: failed load symbol '%s'\n", "CreateDXGIFactory");
679            return SLANG_FAIL;
680        }
681        return createFactory(IID_PPV_ARGS(outFactory.writeRef()));
682    }
683}
684
685/* static */ SlangResult D3DUtil::findAdapters(
686    DeviceCheckFlags flags,
687    const AdapterLUID* adapterLUID,
688    List<ComPtr<IDXGIAdapter>>& outDxgiAdapters)
689{
690    ComPtr<IDXGIFactory> factory;
691    SLANG_RETURN_ON_FAIL(createFactory(flags, factory));
692    return findAdapters(flags, adapterLUID, factory, outDxgiAdapters);
693}
694
695/* static */ AdapterLUID D3DUtil::getAdapterLUID(IDXGIAdapter* dxgiAdapter)
696{
697    DXGI_ADAPTER_DESC desc;
698    dxgiAdapter->GetDesc(&desc);
699    AdapterLUID luid = {};
700    SLANG_ASSERT(sizeof(AdapterLUID) >= sizeof(LUID));
701    memcpy(&luid, &desc.AdapterLuid, sizeof(LUID));
702    return luid;
703}
704
705/* static */ bool D3DUtil::isWarp(IDXGIFactory* dxgiFactory, IDXGIAdapter* adapterIn)
706{
707    ComPtr<IDXGIFactory4> dxgiFactory4;
708    if (SLANG_SUCCEEDED(dxgiFactory->QueryInterface(IID_PPV_ARGS(dxgiFactory4.writeRef()))))
709    {
710        ComPtr<IDXGIAdapter> warpAdapter;
711        dxgiFactory4->EnumWarpAdapter(IID_PPV_ARGS(warpAdapter.writeRef()));
712
713        return adapterIn == warpAdapter;
714    }
715
716    return false;
717}
718
719bool D3DUtil::isUAVBinding(slang::BindingType bindingType)
720{
721    switch (bindingType)
722    {
723    case slang::BindingType::MutableRawBuffer:
724    case slang::BindingType::MutableTexture:
725    case slang::BindingType::MutableTypedBuffer:
726        return true;
727    default:
728        return false;
729    }
730}
731
732int D3DUtil::getShaderModelFromProfileName(const char* name)
733{
734    UnownedStringSlice nameSlice(name);
735
736    if (nameSlice.endsWith("5_1"))
737        return D3D_SHADER_MODEL_5_1;
738    if (nameSlice.endsWith("6_0"))
739        return D3D_SHADER_MODEL_6_0;
740    if (nameSlice.endsWith("6_1"))
741        return D3D_SHADER_MODEL_6_1;
742    if (nameSlice.endsWith("6_2"))
743        return D3D_SHADER_MODEL_6_2;
744    if (nameSlice.endsWith("6_3"))
745        return D3D_SHADER_MODEL_6_3;
746    if (nameSlice.endsWith("6_4"))
747        return D3D_SHADER_MODEL_6_4;
748    if (nameSlice.endsWith("6_5"))
749        return D3D_SHADER_MODEL_6_5;
750    if (nameSlice.endsWith("6_6"))
751        return D3D_SHADER_MODEL_6_6;
752    if (nameSlice.endsWith("6_7"))
753        return 0x67;
754    return 0;
755}
756
757uint32_t D3DUtil::getPlaneSliceCount(DXGI_FORMAT format)
758{
759    switch (format)
760    {
761    case DXGI_FORMAT_D24_UNORM_S8_UINT:
762    case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
763        return 2;
764    default:
765        return 1;
766    }
767}
768
769uint32_t D3DUtil::getPlaneSlice(DXGI_FORMAT format, TextureAspect aspect)
770{
771    switch (aspect)
772    {
773    case TextureAspect::Default:
774    case TextureAspect::Color:
775        return 0;
776    case TextureAspect::Depth:
777        return 0;
778    case TextureAspect::Stencil:
779        switch (format)
780        {
781        case DXGI_FORMAT_D24_UNORM_S8_UINT:
782        case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
783            return 1;
784        default:
785            return 0;
786        }
787    case TextureAspect::Plane0:
788        return 0;
789    case TextureAspect::Plane1:
790        return 1;
791    case TextureAspect::Plane2:
792        return 2;
793    default:
794        SLANG_ASSERT_FAILURE("Unknown texture aspect.");
795        return 0;
796    }
797}
798
799D3D12_INPUT_CLASSIFICATION D3DUtil::getInputSlotClass(InputSlotClass slotClass)
800{
801    switch (slotClass)
802    {
803    case InputSlotClass::PerVertex:
804        return D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA;
805    case InputSlotClass::PerInstance:
806        return D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA;
807    default:
808        SLANG_ASSERT_FAILURE("Unknown input slot class.");
809        return D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA;
810    }
811}
812
813D3D12_FILL_MODE D3DUtil::getFillMode(FillMode mode)
814{
815    switch (mode)
816    {
817    case FillMode::Solid:
818        return D3D12_FILL_MODE_SOLID;
819    case FillMode::Wireframe:
820        return D3D12_FILL_MODE_WIREFRAME;
821    default:
822        SLANG_ASSERT_FAILURE("Unknown fill mode.");
823        return D3D12_FILL_MODE_SOLID;
824    }
825}
826
827D3D12_CULL_MODE D3DUtil::getCullMode(CullMode mode)
828{
829    switch (mode)
830    {
831    case CullMode::None:
832        return D3D12_CULL_MODE_NONE;
833    case CullMode::Front:
834        return D3D12_CULL_MODE_FRONT;
835    case CullMode::Back:
836        return D3D12_CULL_MODE_BACK;
837    default:
838        SLANG_ASSERT_FAILURE("Unknown cull mode.");
839        return D3D12_CULL_MODE_NONE;
840    }
841}
842
843D3D12_BLEND_OP D3DUtil::getBlendOp(BlendOp op)
844{
845    switch (op)
846    {
847    case BlendOp::Add:
848        return D3D12_BLEND_OP_ADD;
849    case BlendOp::Subtract:
850        return D3D12_BLEND_OP_SUBTRACT;
851    case BlendOp::ReverseSubtract:
852        return D3D12_BLEND_OP_REV_SUBTRACT;
853    case BlendOp::Min:
854        return D3D12_BLEND_OP_MIN;
855    case BlendOp::Max:
856        return D3D12_BLEND_OP_MAX;
857    default:
858        SLANG_ASSERT_FAILURE("Unknown blend op.");
859        return D3D12_BLEND_OP_ADD;
860    }
861}
862
863D3D12_BLEND D3DUtil::getBlendFactor(BlendFactor factor)
864{
865    switch (factor)
866    {
867    case BlendFactor::Zero:
868        return D3D12_BLEND_ZERO;
869    case BlendFactor::One:
870        return D3D12_BLEND_ONE;
871    case BlendFactor::SrcColor:
872        return D3D12_BLEND_SRC_COLOR;
873    case BlendFactor::InvSrcColor:
874        return D3D12_BLEND_INV_SRC_COLOR;
875    case BlendFactor::SrcAlpha:
876        return D3D12_BLEND_SRC_ALPHA;
877    case BlendFactor::InvSrcAlpha:
878        return D3D12_BLEND_INV_SRC_ALPHA;
879    case BlendFactor::DestAlpha:
880        return D3D12_BLEND_DEST_ALPHA;
881    case BlendFactor::InvDestAlpha:
882        return D3D12_BLEND_INV_DEST_ALPHA;
883    case BlendFactor::DestColor:
884        return D3D12_BLEND_DEST_COLOR;
885    case BlendFactor::InvDestColor:
886        return D3D12_BLEND_INV_DEST_COLOR;
887    case BlendFactor::SrcAlphaSaturate:
888        return D3D12_BLEND_SRC_ALPHA_SAT;
889    case BlendFactor::BlendColor:
890        return D3D12_BLEND_BLEND_FACTOR;
891    case BlendFactor::InvBlendColor:
892        return D3D12_BLEND_INV_BLEND_FACTOR;
893    case BlendFactor::SecondarySrcColor:
894        return D3D12_BLEND_SRC1_COLOR;
895    case BlendFactor::InvSecondarySrcColor:
896        return D3D12_BLEND_INV_SRC1_COLOR;
897    case BlendFactor::SecondarySrcAlpha:
898        return D3D12_BLEND_SRC1_ALPHA;
899    case BlendFactor::InvSecondarySrcAlpha:
900        return D3D12_BLEND_INV_SRC1_ALPHA;
901    default:
902        SLANG_ASSERT_FAILURE("Unknown blend factor.");
903        return D3D12_BLEND_ZERO;
904    }
905}
906
907uint32_t D3DUtil::getSubresourceIndex(
908    uint32_t mipIndex,
909    uint32_t arrayIndex,
910    uint32_t planeIndex,
911    uint32_t mipLevelCount,
912    uint32_t arraySize)
913{
914    return mipIndex + arrayIndex * mipLevelCount + planeIndex * mipLevelCount * arraySize;
915}
916
917uint32_t D3DUtil::getSubresourceMipLevel(uint32_t subresourceIndex, uint32_t mipLevelCount)
918{
919    return subresourceIndex % mipLevelCount;
920}
921
922D3D12_RESOURCE_STATES D3DUtil::getResourceState(ResourceState state)
923{
924    switch (state)
925    {
926    case ResourceState::Undefined:
927        return D3D12_RESOURCE_STATE_COMMON;
928    case ResourceState::General:
929        return D3D12_RESOURCE_STATE_COMMON;
930    case ResourceState::PreInitialized:
931        return D3D12_RESOURCE_STATE_COMMON;
932    case ResourceState::VertexBuffer:
933        return D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER;
934    case ResourceState::IndexBuffer:
935        return D3D12_RESOURCE_STATE_INDEX_BUFFER;
936    case ResourceState::ConstantBuffer:
937        return D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER;
938    case ResourceState::StreamOutput:
939        return D3D12_RESOURCE_STATE_STREAM_OUT;
940    case ResourceState::ShaderResource:
941    case ResourceState::AccelerationStructureBuildInput:
942        return D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE |
943               D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
944    case ResourceState::PixelShaderResource:
945        return D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
946    case ResourceState::NonPixelShaderResource:
947        return D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
948    case ResourceState::UnorderedAccess:
949        return D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
950    case ResourceState::RenderTarget:
951        return D3D12_RESOURCE_STATE_RENDER_TARGET;
952    case ResourceState::DepthRead:
953        return D3D12_RESOURCE_STATE_DEPTH_READ;
954    case ResourceState::DepthWrite:;
955        return D3D12_RESOURCE_STATE_DEPTH_WRITE;
956    case ResourceState::Present:
957        return D3D12_RESOURCE_STATE_PRESENT;
958    case ResourceState::IndirectArgument:
959        return D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT;
960    case ResourceState::CopySource:
961        return D3D12_RESOURCE_STATE_COPY_SOURCE;
962    case ResourceState::CopyDestination:
963        return D3D12_RESOURCE_STATE_COPY_DEST;
964    case ResourceState::ResolveSource:
965        return D3D12_RESOURCE_STATE_RESOLVE_SOURCE;
966    case ResourceState::ResolveDestination:
967        return D3D12_RESOURCE_STATE_RESOLVE_DEST;
968    case ResourceState::AccelerationStructure:
969        return D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE;
970    default:
971        return D3D12_RESOURCE_STATE_COMMON;
972    }
973}
974
975/* static */ SlangResult D3DUtil::reportLiveObjects()
976{
977    static IDXGIDebug* dxgiDebug = nullptr;
978
979#if SLANG_ENABLE_DXGI_DEBUG
980    if (!dxgiDebug)
981    {
982        HMODULE debugModule = LoadLibraryA("dxgidebug.dll");
983        if (debugModule != INVALID_HANDLE_VALUE)
984        {
985            auto fun = reinterpret_cast<decltype(&DXGIGetDebugInterface)>(
986                GetProcAddress(debugModule, "DXGIGetDebugInterface"));
987            if (fun)
988            {
989                fun(__uuidof(IDXGIDebug), (void**)&dxgiDebug);
990            }
991        }
992    }
993#endif
994
995    if (dxgiDebug)
996    {
997        const GUID DXGI_DEBUG_ALL_ =
998            {0xe48ae283, 0xda80, 0x490b, {0x87, 0xe6, 0x43, 0xe9, 0xa9, 0xcf, 0xda, 0x8}};
999        dxgiDebug->ReportLiveObjects(DXGI_DEBUG_ALL_, DXGI_DEBUG_RLO_ALL);
1000        return SLANG_OK;
1001    }
1002
1003    return SLANG_E_NOT_AVAILABLE;
1004}
1005
1006Result SLANG_MCALL reportD3DLiveObjects()
1007{
1008    return D3DUtil::reportLiveObjects();
1009}
1010
1011
1012/* static */ SlangResult D3DUtil::waitForCrashDumpCompletion(HRESULT res)
1013{
1014    // If it's not a device remove/reset then theres nothing to wait for
1015    if (!(res == DXGI_ERROR_DEVICE_REMOVED || res == DXGI_ERROR_DEVICE_RESET))
1016    {
1017        return SLANG_OK;
1018    }
1019
1020#if GFX_NV_AFTERMATH
1021    {
1022        GFSDK_Aftermath_CrashDump_Status status = GFSDK_Aftermath_CrashDump_Status_Unknown;
1023        if (GFSDK_Aftermath_GetCrashDumpStatus(&status) != GFSDK_Aftermath_Result_Success)
1024        {
1025            return SLANG_FAIL;
1026        }
1027
1028        const auto startTick = Process::getClockTick();
1029        const auto frequency = Process::getClockFrequency();
1030
1031        float timeOutInSecs = 1.0f;
1032
1033        uint64_t timeOutTicks = uint64_t(frequency * timeOutInSecs) + 1;
1034
1035        // Loop while Aftermath crash dump data collection has not finished or
1036        // the application is still processing the crash dump data.
1037        while (status != GFSDK_Aftermath_CrashDump_Status_CollectingDataFailed &&
1038               status != GFSDK_Aftermath_CrashDump_Status_Finished &&
1039               Process::getClockTick() - startTick < timeOutTicks)
1040        {
1041            // Sleep a couple of milliseconds and poll the status again.
1042            Process::sleepCurrentThread(50);
1043            if (GFSDK_Aftermath_GetCrashDumpStatus(&status) != GFSDK_Aftermath_Result_Success)
1044            {
1045                return SLANG_FAIL;
1046            }
1047        }
1048
1049        if (status == GFSDK_Aftermath_CrashDump_Status_Finished)
1050        {
1051            return SLANG_OK;
1052        }
1053        else
1054        {
1055            return SLANG_E_TIME_OUT;
1056        }
1057    }
1058#endif
1059
1060    return SLANG_OK;
1061}
1062
1063/* static */ SlangResult D3DUtil::findAdapters(
1064    DeviceCheckFlags flags,
1065    const AdapterLUID* adapterLUID,
1066    IDXGIFactory* dxgiFactory,
1067    List<ComPtr<IDXGIAdapter>>& outDxgiAdapters)
1068{
1069    outDxgiAdapters.clear();
1070
1071    ComPtr<IDXGIAdapter> warpAdapter;
1072    if ((flags & DeviceCheckFlag::UseHardwareDevice) == 0)
1073    {
1074        ComPtr<IDXGIFactory4> dxgiFactory4;
1075        if (SLANG_SUCCEEDED(dxgiFactory->QueryInterface(IID_PPV_ARGS(dxgiFactory4.writeRef()))))
1076        {
1077            dxgiFactory4->EnumWarpAdapter(IID_PPV_ARGS(warpAdapter.writeRef()));
1078            if (!adapterLUID || D3DUtil::getAdapterLUID(warpAdapter) == *adapterLUID)
1079            {
1080                outDxgiAdapters.add(warpAdapter);
1081            }
1082        }
1083    }
1084
1085    for (UINT adapterIndex = 0; true; adapterIndex++)
1086    {
1087        ComPtr<IDXGIAdapter> dxgiAdapter;
1088        if (dxgiFactory->EnumAdapters(adapterIndex, dxgiAdapter.writeRef()) == DXGI_ERROR_NOT_FOUND)
1089            break;
1090
1091        // Skip if warp (as we will have already added it)
1092        if (dxgiAdapter == warpAdapter)
1093        {
1094            continue;
1095        }
1096        if (adapterLUID && D3DUtil::getAdapterLUID(dxgiAdapter) != *adapterLUID)
1097        {
1098            continue;
1099        }
1100
1101        // Get if it's software
1102        UINT deviceFlags = 0;
1103        ComPtr<IDXGIAdapter1> dxgiAdapter1;
1104        if (SLANG_SUCCEEDED(dxgiAdapter->QueryInterface(IID_PPV_ARGS(dxgiAdapter1.writeRef()))))
1105        {
1106            DXGI_ADAPTER_DESC1 desc;
1107            dxgiAdapter1->GetDesc1(&desc);
1108            deviceFlags = desc.Flags;
1109        }
1110
1111        // If the right type then add it
1112        if ((deviceFlags & DXGI_ADAPTER_FLAG_SOFTWARE) == 0 &&
1113            (flags & DeviceCheckFlag::UseHardwareDevice) != 0)
1114        {
1115            outDxgiAdapters.add(dxgiAdapter);
1116        }
1117    }
1118
1119    return SLANG_OK;
1120}
1121
1122#if SLANG_GFX_HAS_DXR_SUPPORT
1123Result D3DAccelerationStructureInputsBuilder::build(
1124    const IAccelerationStructure::BuildInputs& buildInputs,
1125    IDebugCallback* callback)
1126{
1127    if (buildInputs.geometryDescs)
1128    {
1129        geomDescs.setCount(buildInputs.descCount);
1130        for (Index i = 0; i < geomDescs.getCount(); i++)
1131        {
1132            auto& inputGeomDesc = buildInputs.geometryDescs[i];
1133            geomDescs[i].Flags = translateGeometryFlags(inputGeomDesc.flags);
1134            switch (inputGeomDesc.type)
1135            {
1136            case IAccelerationStructure::GeometryType::Triangles:
1137                geomDescs[i].Type = D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES;
1138                geomDescs[i].Triangles.IndexBuffer = inputGeomDesc.content.triangles.indexData;
1139                geomDescs[i].Triangles.IndexCount = inputGeomDesc.content.triangles.indexCount;
1140                geomDescs[i].Triangles.IndexFormat =
1141                    D3DUtil::getMapFormat(inputGeomDesc.content.triangles.indexFormat);
1142                geomDescs[i].Triangles.Transform3x4 = inputGeomDesc.content.triangles.transform3x4;
1143                geomDescs[i].Triangles.VertexBuffer.StartAddress =
1144                    inputGeomDesc.content.triangles.vertexData;
1145                geomDescs[i].Triangles.VertexBuffer.StrideInBytes =
1146                    inputGeomDesc.content.triangles.vertexStride;
1147                geomDescs[i].Triangles.VertexCount = inputGeomDesc.content.triangles.vertexCount;
1148                geomDescs[i].Triangles.VertexFormat =
1149                    D3DUtil::getMapFormat(inputGeomDesc.content.triangles.vertexFormat);
1150                break;
1151            case IAccelerationStructure::GeometryType::ProcedurePrimitives:
1152                geomDescs[i].Type = D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS;
1153                geomDescs[i].AABBs.AABBCount = inputGeomDesc.content.proceduralAABBs.count;
1154                geomDescs[i].AABBs.AABBs.StartAddress = inputGeomDesc.content.proceduralAABBs.data;
1155                geomDescs[i].AABBs.AABBs.StrideInBytes =
1156                    inputGeomDesc.content.proceduralAABBs.stride;
1157                break;
1158            default:
1159                callback->handleMessage(
1160                    DebugMessageType::Error,
1161                    DebugMessageSource::Layer,
1162                    "invalid value of IAccelerationStructure::GeometryType.");
1163                return SLANG_E_INVALID_ARG;
1164            }
1165        }
1166    }
1167    desc.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
1168    desc.NumDescs = buildInputs.descCount;
1169    switch (buildInputs.kind)
1170    {
1171    case IAccelerationStructure::Kind::TopLevel:
1172        desc.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL;
1173        desc.InstanceDescs = buildInputs.instanceDescs;
1174        break;
1175    case IAccelerationStructure::Kind::BottomLevel:
1176        desc.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL;
1177        desc.pGeometryDescs = geomDescs.getBuffer();
1178        break;
1179    }
1180    desc.Flags = (D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS)buildInputs.flags;
1181    return SLANG_OK;
1182}
1183#endif
1184
1185} // namespace gfx