yum-mirror/slang

Making it easier to work with shaders

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

Gangzheng TongEnable Windows full debug testsuite in CI (#7085)8f20632a0

master
23.9 KiB668 linesraw
1// d3d12-helper-functions.cpp
2#include "d3d12-helper-functions.h"
3
4#ifdef GFX_NVAPI
5#include "../nvapi/nvapi-include.h"
6#endif
7
8#include "../nvapi/nvapi-util.h"
9#include "d3d12-buffer.h"
10#include "d3d12-query.h"
11#include "d3d12-transient-heap.h"
12
13namespace gfx
14{
15using namespace Slang;
16
17namespace d3d12
18{
19
20bool isSupportedNVAPIOp(ID3D12Device* dev, uint32_t op)
21{
22#ifdef GFX_NVAPI
23    {
24        bool isSupported;
25        NvAPI_Status status =
26            NvAPI_D3D12_IsNvShaderExtnOpCodeSupported(dev, NvU32(op), &isSupported);
27        return status == NVAPI_OK && isSupported;
28    }
29#else
30    return false;
31#endif
32}
33
34D3D12_RESOURCE_FLAGS calcResourceFlag(ResourceState state)
35{
36    switch (state)
37    {
38    case ResourceState::RenderTarget:
39        return D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
40    case ResourceState::DepthRead:
41    case ResourceState::DepthWrite:
42        return D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
43    case ResourceState::UnorderedAccess:
44    case ResourceState::AccelerationStructure:
45        return D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
46    default:
47        return D3D12_RESOURCE_FLAG_NONE;
48    }
49}
50
51D3D12_RESOURCE_FLAGS calcResourceFlags(ResourceStateSet states)
52{
53    int dstFlags = 0;
54    for (uint32_t i = 0; i < (uint32_t)ResourceState::_Count; i++)
55    {
56        auto state = (ResourceState)i;
57        if (states.contains(state))
58            dstFlags |= calcResourceFlag(state);
59    }
60    return (D3D12_RESOURCE_FLAGS)dstFlags;
61}
62
63D3D12_RESOURCE_DIMENSION calcResourceDimension(IResource::Type type)
64{
65    switch (type)
66    {
67    case IResource::Type::Buffer:
68        return D3D12_RESOURCE_DIMENSION_BUFFER;
69    case IResource::Type::Texture1D:
70        return D3D12_RESOURCE_DIMENSION_TEXTURE1D;
71    case IResource::Type::TextureCube:
72    case IResource::Type::Texture2D:
73        {
74            return D3D12_RESOURCE_DIMENSION_TEXTURE2D;
75        }
76    case IResource::Type::Texture3D:
77        return D3D12_RESOURCE_DIMENSION_TEXTURE3D;
78    default:
79        return D3D12_RESOURCE_DIMENSION_UNKNOWN;
80    }
81}
82
83DXGI_FORMAT getTypelessFormatFromDepthFormat(Format format)
84{
85    switch (format)
86    {
87    case Format::D16_UNORM:
88        return DXGI_FORMAT_R16_TYPELESS;
89    case Format::D32_FLOAT:
90        return DXGI_FORMAT_R32_TYPELESS;
91    case Format::D32_FLOAT_S8_UINT:
92        return DXGI_FORMAT_R32G8X24_TYPELESS;
93    // case Format::D24_UNORM_S8_UINT:
94    //     return DXGI_FORMAT_R24G8_TYPELESS;
95    default:
96        return D3DUtil::getMapFormat(format);
97    }
98}
99
100bool isTypelessDepthFormat(DXGI_FORMAT format)
101{
102    switch (format)
103    {
104    case DXGI_FORMAT_R16_TYPELESS:
105    case DXGI_FORMAT_R32_TYPELESS:
106    case DXGI_FORMAT_R32G8X24_TYPELESS:
107    case DXGI_FORMAT_R24G8_TYPELESS:
108        return true;
109    default:
110        return false;
111    }
112}
113
114D3D12_FILTER_TYPE translateFilterMode(TextureFilteringMode mode)
115{
116    switch (mode)
117    {
118    default:
119        return D3D12_FILTER_TYPE(0);
120
121#define CASE(SRC, DST)              \
122    case TextureFilteringMode::SRC: \
123        return D3D12_FILTER_TYPE_##DST
124
125        CASE(Point, POINT);
126        CASE(Linear, LINEAR);
127
128#undef CASE
129    }
130}
131
132D3D12_FILTER_REDUCTION_TYPE translateFilterReduction(TextureReductionOp op)
133{
134    switch (op)
135    {
136    default:
137        return D3D12_FILTER_REDUCTION_TYPE(0);
138
139#define CASE(SRC, DST)            \
140    case TextureReductionOp::SRC: \
141        return D3D12_FILTER_REDUCTION_TYPE_##DST
142
143        CASE(Average, STANDARD);
144        CASE(Comparison, COMPARISON);
145        CASE(Minimum, MINIMUM);
146        CASE(Maximum, MAXIMUM);
147
148#undef CASE
149    }
150}
151
152D3D12_TEXTURE_ADDRESS_MODE translateAddressingMode(TextureAddressingMode mode)
153{
154    switch (mode)
155    {
156    default:
157        return D3D12_TEXTURE_ADDRESS_MODE(0);
158
159#define CASE(SRC, DST)               \
160    case TextureAddressingMode::SRC: \
161        return D3D12_TEXTURE_ADDRESS_MODE_##DST
162
163        CASE(Wrap, WRAP);
164        CASE(ClampToEdge, CLAMP);
165        CASE(ClampToBorder, BORDER);
166        CASE(MirrorRepeat, MIRROR);
167        CASE(MirrorOnce, MIRROR_ONCE);
168
169#undef CASE
170    }
171}
172
173D3D12_COMPARISON_FUNC translateComparisonFunc(ComparisonFunc func)
174{
175    switch (func)
176    {
177    default:
178        // TODO: need to report failures
179        return D3D12_COMPARISON_FUNC_ALWAYS;
180
181#define CASE(FROM, TO)         \
182    case ComparisonFunc::FROM: \
183        return D3D12_COMPARISON_FUNC_##TO
184
185        CASE(Never, NEVER);
186        CASE(Less, LESS);
187        CASE(Equal, EQUAL);
188        CASE(LessEqual, LESS_EQUAL);
189        CASE(Greater, GREATER);
190        CASE(NotEqual, NOT_EQUAL);
191        CASE(GreaterEqual, GREATER_EQUAL);
192        CASE(Always, ALWAYS);
193#undef CASE
194    }
195}
196
197uint32_t getViewDescriptorCount(const ITransientResourceHeap::Desc& desc)
198{
199    return Math::Max(
200        Math::Max(
201            desc.srvDescriptorCount,
202            desc.uavDescriptorCount,
203            desc.accelerationStructureDescriptorCount),
204        desc.constantBufferDescriptorCount,
205        2048);
206}
207
208void initSrvDesc(
209    IResource::Type resourceType,
210    const ITextureResource::Desc& textureDesc,
211    const D3D12_RESOURCE_DESC& desc,
212    DXGI_FORMAT pixelFormat,
213    SubresourceRange subresourceRange,
214    D3D12_SHADER_RESOURCE_VIEW_DESC& descOut)
215{
216    // create SRV
217    descOut = D3D12_SHADER_RESOURCE_VIEW_DESC();
218
219    descOut.Format = (pixelFormat == DXGI_FORMAT_UNKNOWN)
220                         ? D3DUtil::calcFormat(D3DUtil::USAGE_SRV, desc.Format)
221                         : pixelFormat;
222    descOut.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
223    if (desc.DepthOrArraySize == 1)
224    {
225        switch (desc.Dimension)
226        {
227        case D3D12_RESOURCE_DIMENSION_TEXTURE1D:
228            descOut.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1D;
229            descOut.Texture1D.MipLevels = subresourceRange.mipLevelCount == 0
230                                              ? desc.MipLevels - subresourceRange.mipLevel
231                                              : subresourceRange.mipLevelCount;
232            descOut.Texture1D.MostDetailedMip = subresourceRange.mipLevel;
233            break;
234        case D3D12_RESOURCE_DIMENSION_TEXTURE2D:
235            descOut.ViewDimension = textureDesc.sampleDesc.numSamples > 1
236                                        ? D3D12_SRV_DIMENSION_TEXTURE2DMS
237                                        : D3D12_SRV_DIMENSION_TEXTURE2D;
238            descOut.Texture2D.PlaneSlice =
239                D3DUtil::getPlaneSlice(descOut.Format, subresourceRange.aspectMask);
240            descOut.Texture2D.ResourceMinLODClamp = 0.0f;
241            descOut.Texture2D.MipLevels = subresourceRange.mipLevelCount == 0
242                                              ? desc.MipLevels - subresourceRange.mipLevel
243                                              : subresourceRange.mipLevelCount;
244            descOut.Texture2D.MostDetailedMip = subresourceRange.mipLevel;
245            break;
246        case D3D12_RESOURCE_DIMENSION_TEXTURE3D:
247            descOut.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D;
248            descOut.Texture3D.MipLevels = subresourceRange.mipLevelCount == 0
249                                              ? desc.MipLevels - subresourceRange.mipLevel
250                                              : subresourceRange.mipLevelCount;
251            descOut.Texture3D.MostDetailedMip = subresourceRange.mipLevel;
252            break;
253        default:
254            assert(!"Unknown dimension");
255        }
256    }
257    else if (resourceType == IResource::Type::TextureCube)
258    {
259        if (textureDesc.arraySize > 1)
260        {
261            descOut.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBEARRAY;
262
263            descOut.TextureCubeArray.NumCubes = subresourceRange.layerCount == 0
264                                                    ? textureDesc.arraySize
265                                                    : subresourceRange.layerCount / 6;
266            descOut.TextureCubeArray.First2DArrayFace = subresourceRange.baseArrayLayer;
267            descOut.TextureCubeArray.MipLevels = subresourceRange.mipLevelCount == 0
268                                                     ? desc.MipLevels - subresourceRange.mipLevel
269                                                     : subresourceRange.mipLevelCount;
270            descOut.TextureCubeArray.MostDetailedMip = subresourceRange.mipLevel;
271            descOut.TextureCubeArray.ResourceMinLODClamp = 0;
272        }
273        else
274        {
275            descOut.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE;
276
277            descOut.TextureCube.MipLevels = subresourceRange.mipLevelCount == 0
278                                                ? desc.MipLevels - subresourceRange.mipLevel
279                                                : subresourceRange.mipLevelCount;
280            descOut.TextureCube.MostDetailedMip = subresourceRange.mipLevel;
281            descOut.TextureCube.ResourceMinLODClamp = 0;
282        }
283    }
284    else
285    {
286        assert(desc.DepthOrArraySize > 1);
287
288        switch (desc.Dimension)
289        {
290        case D3D12_RESOURCE_DIMENSION_TEXTURE1D:
291            descOut.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1DARRAY;
292            descOut.Texture1D.MostDetailedMip = subresourceRange.mipLevel;
293            descOut.Texture1D.MipLevels = subresourceRange.mipLevelCount == 0
294                                              ? desc.MipLevels
295                                              : subresourceRange.mipLevelCount;
296            descOut.Texture1DArray.ArraySize = subresourceRange.layerCount == 0
297                                                   ? desc.DepthOrArraySize
298                                                   : subresourceRange.layerCount;
299            descOut.Texture1DArray.FirstArraySlice = subresourceRange.baseArrayLayer;
300            descOut.Texture1DArray.ResourceMinLODClamp = 0;
301            descOut.Texture1DArray.MostDetailedMip = subresourceRange.mipLevel;
302            descOut.Texture1DArray.MipLevels = subresourceRange.mipLevelCount == 0
303                                                   ? desc.MipLevels - subresourceRange.mipLevel
304                                                   : subresourceRange.mipLevelCount;
305            break;
306        case D3D12_RESOURCE_DIMENSION_TEXTURE2D:
307            descOut.ViewDimension = textureDesc.sampleDesc.numSamples > 1
308                                        ? D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY
309                                        : D3D12_SRV_DIMENSION_TEXTURE2DARRAY;
310            if (descOut.ViewDimension == D3D12_SRV_DIMENSION_TEXTURE2DARRAY)
311            {
312                descOut.Texture2DArray.ArraySize = subresourceRange.layerCount == 0
313                                                       ? desc.DepthOrArraySize
314                                                       : subresourceRange.layerCount;
315                descOut.Texture2DArray.FirstArraySlice = subresourceRange.baseArrayLayer;
316                descOut.Texture2DArray.PlaneSlice =
317                    D3DUtil::getPlaneSlice(descOut.Format, subresourceRange.aspectMask);
318                descOut.Texture2DArray.ResourceMinLODClamp = 0;
319                descOut.Texture2DArray.MostDetailedMip = subresourceRange.mipLevel;
320                descOut.Texture2DArray.MipLevels = subresourceRange.mipLevelCount == 0
321                                                       ? desc.MipLevels - subresourceRange.mipLevel
322                                                       : subresourceRange.mipLevelCount;
323            }
324            else
325            {
326                assert(descOut.ViewDimension == D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY);
327                descOut.Texture2DMSArray.FirstArraySlice = subresourceRange.baseArrayLayer;
328                descOut.Texture2DMSArray.ArraySize = subresourceRange.layerCount == 0
329                                                         ? desc.DepthOrArraySize
330                                                         : subresourceRange.layerCount;
331            }
332
333            break;
334        case D3D12_RESOURCE_DIMENSION_TEXTURE3D:
335            descOut.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D;
336            descOut.Texture3D.MostDetailedMip = subresourceRange.mipLevel;
337            descOut.Texture3D.MipLevels = subresourceRange.mipLevelCount == 0
338                                              ? desc.MipLevels
339                                              : subresourceRange.mipLevelCount;
340            break;
341
342        default:
343            assert(!"Unknown dimension");
344        }
345    }
346}
347
348Result initTextureResourceDesc(
349    D3D12_RESOURCE_DESC& resourceDesc,
350    const ITextureResource::Desc& srcDesc)
351{
352    const DXGI_FORMAT pixelFormat = D3DUtil::getMapFormat(srcDesc.format);
353    if (pixelFormat == DXGI_FORMAT_UNKNOWN)
354    {
355        return SLANG_FAIL;
356    }
357
358    const int arraySize = calcEffectiveArraySize(srcDesc);
359
360    const D3D12_RESOURCE_DIMENSION dimension = calcResourceDimension(srcDesc.type);
361    if (dimension == D3D12_RESOURCE_DIMENSION_UNKNOWN)
362    {
363        return SLANG_FAIL;
364    }
365
366    const int numMipMaps = srcDesc.numMipLevels;
367    resourceDesc.Dimension = dimension;
368    resourceDesc.Format = pixelFormat;
369    resourceDesc.Width = srcDesc.size.width;
370    resourceDesc.Height = srcDesc.size.height;
371    resourceDesc.DepthOrArraySize = (srcDesc.size.depth > 1) ? srcDesc.size.depth : arraySize;
372
373    resourceDesc.MipLevels = numMipMaps;
374    resourceDesc.SampleDesc.Count = srcDesc.sampleDesc.numSamples;
375    resourceDesc.SampleDesc.Quality = srcDesc.sampleDesc.quality;
376
377    resourceDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
378    resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
379
380    resourceDesc.Flags |= calcResourceFlags(srcDesc.allowedStates);
381
382    resourceDesc.Alignment = 0;
383
384    if (isDepthFormat(srcDesc.format) &&
385        (srcDesc.allowedStates.contains(ResourceState::ShaderResource) ||
386         srcDesc.allowedStates.contains(ResourceState::UnorderedAccess)))
387    {
388        resourceDesc.Format = getTypelessFormatFromDepthFormat(srcDesc.format);
389    }
390
391    return SLANG_OK;
392}
393
394void initBufferResourceDesc(Size bufferSize, D3D12_RESOURCE_DESC& out)
395{
396    out = {};
397
398    out.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
399    out.Alignment = 0;
400    out.Width = bufferSize;
401    out.Height = 1;
402    out.DepthOrArraySize = 1;
403    out.MipLevels = 1;
404    out.Format = DXGI_FORMAT_UNKNOWN;
405    out.SampleDesc.Count = 1;
406    out.SampleDesc.Quality = 0;
407    out.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
408    out.Flags = D3D12_RESOURCE_FLAG_NONE;
409}
410
411Result uploadBufferDataImpl(
412    ID3D12Device* device,
413    ID3D12GraphicsCommandList* cmdList,
414    TransientResourceHeapImpl* transientHeap,
415    BufferResourceImpl* buffer,
416    Offset offset,
417    Size size,
418    void* data)
419{
420    IBufferResource* uploadResource;
421    Offset uploadResourceOffset = 0;
422    if (buffer->getDesc()->memoryType != MemoryType::Upload)
423    {
424        SLANG_RETURN_ON_FAIL(transientHeap->allocateStagingBuffer(
425            size,
426            uploadResource,
427            uploadResourceOffset,
428            MemoryType::Upload));
429    }
430    else
431    {
432        uploadResourceOffset = offset;
433    }
434    D3D12Resource& uploadResourceRef =
435        (buffer->getDesc()->memoryType == MemoryType::Upload)
436            ? buffer->m_resource
437            : static_cast<BufferResourceImpl*>(uploadResource)->m_resource;
438
439    D3D12_RANGE readRange = {};
440    readRange.Begin = 0;
441    readRange.End = 0;
442    void* uploadData;
443    SLANG_RETURN_ON_FAIL(
444        uploadResourceRef.getResource()->Map(0, &readRange, reinterpret_cast<void**>(&uploadData)));
445    memcpy((uint8_t*)uploadData + uploadResourceOffset, data, size);
446    D3D12_RANGE writtenRange = {};
447    writtenRange.Begin = uploadResourceOffset;
448    writtenRange.End = uploadResourceOffset + size;
449    uploadResourceRef.getResource()->Unmap(0, &writtenRange);
450
451    if (buffer->getDesc()->memoryType != MemoryType::Upload)
452    {
453        cmdList->CopyBufferRegion(
454            buffer->m_resource.getResource(),
455            offset,
456            uploadResourceRef.getResource(),
457            uploadResourceOffset,
458            size);
459    }
460
461    return SLANG_OK;
462}
463
464Result createNullDescriptor(
465    ID3D12Device* d3dDevice,
466    D3D12_CPU_DESCRIPTOR_HANDLE destDescriptor,
467    const ShaderObjectLayoutImpl::BindingRangeInfo& bindingRange)
468{
469    switch (bindingRange.bindingType)
470    {
471    case slang::BindingType::ConstantBuffer:
472        {
473            D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc = {};
474            cbvDesc.BufferLocation = 0;
475            cbvDesc.SizeInBytes = 0;
476            d3dDevice->CreateConstantBufferView(&cbvDesc, destDescriptor);
477        }
478        break;
479    case slang::BindingType::MutableRawBuffer:
480        {
481            D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
482            uavDesc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
483            uavDesc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_RAW;
484            uavDesc.Format = DXGI_FORMAT_R32_TYPELESS;
485            d3dDevice->CreateUnorderedAccessView(nullptr, nullptr, &uavDesc, destDescriptor);
486        }
487        break;
488    case slang::BindingType::MutableTypedBuffer:
489        {
490            D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
491            uavDesc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
492            uavDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
493            d3dDevice->CreateUnorderedAccessView(nullptr, nullptr, &uavDesc, destDescriptor);
494        }
495        break;
496    case slang::BindingType::RawBuffer:
497        {
498            D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
499            srvDesc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
500            srvDesc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_RAW;
501            srvDesc.Format = DXGI_FORMAT_R32_TYPELESS;
502            srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
503            d3dDevice->CreateShaderResourceView(nullptr, &srvDesc, destDescriptor);
504        }
505        break;
506    case slang::BindingType::TypedBuffer:
507        {
508            D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
509            srvDesc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
510            srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
511            srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
512            d3dDevice->CreateShaderResourceView(nullptr, &srvDesc, destDescriptor);
513        }
514        break;
515    case slang::BindingType::Texture:
516        {
517            D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
518            srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
519            srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
520            switch (bindingRange.resourceShape)
521            {
522            case SLANG_TEXTURE_1D:
523                srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1D;
524                break;
525            case SLANG_TEXTURE_1D_ARRAY:
526                srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1DARRAY;
527                break;
528            case SLANG_TEXTURE_2D:
529                srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
530                break;
531            case SLANG_TEXTURE_2D_ARRAY:
532                srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY;
533                break;
534            case SLANG_TEXTURE_3D:
535                srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D;
536                break;
537            case SLANG_TEXTURE_CUBE:
538                srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE;
539                break;
540            case SLANG_TEXTURE_CUBE_ARRAY:
541                srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBEARRAY;
542                break;
543            case SLANG_TEXTURE_2D_MULTISAMPLE:
544                srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DMS;
545                break;
546            case SLANG_TEXTURE_2D_MULTISAMPLE_ARRAY:
547                srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY;
548                break;
549            default:
550                return SLANG_OK;
551            }
552            d3dDevice->CreateShaderResourceView(nullptr, &srvDesc, destDescriptor);
553        }
554        break;
555    case slang::BindingType::MutableTexture:
556        {
557            D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
558            uavDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
559            switch (bindingRange.resourceShape)
560            {
561            case SLANG_TEXTURE_1D:
562                uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE1D;
563                break;
564            case SLANG_TEXTURE_1D_ARRAY:
565                uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE1DARRAY;
566                break;
567            case SLANG_TEXTURE_2D:
568                uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
569                break;
570            case SLANG_TEXTURE_2D_ARRAY:
571                uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2DARRAY;
572                break;
573            case SLANG_TEXTURE_3D:
574                uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE3D;
575                break;
576            case SLANG_TEXTURE_CUBE:
577            case SLANG_TEXTURE_CUBE_ARRAY:
578            case SLANG_TEXTURE_2D_MULTISAMPLE:
579            case SLANG_TEXTURE_2D_MULTISAMPLE_ARRAY:
580            default:
581                return SLANG_OK;
582            }
583            d3dDevice->CreateUnorderedAccessView(nullptr, nullptr, &uavDesc, destDescriptor);
584        }
585        break;
586    default:
587        break;
588    }
589    return SLANG_OK;
590}
591
592void translatePostBuildInfoDescs(
593    int propertyQueryCount,
594    AccelerationStructureQueryDesc* queryDescs,
595    List<D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC>& postBuildInfoDescs)
596{
597    postBuildInfoDescs.setCount(propertyQueryCount);
598    for (int i = 0; i < propertyQueryCount; i++)
599    {
600        switch (queryDescs[i].queryType)
601        {
602        case QueryType::AccelerationStructureCompactedSize:
603            postBuildInfoDescs[i].InfoType =
604                D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_COMPACTED_SIZE;
605            postBuildInfoDescs[i].DestBuffer =
606                static_cast<PlainBufferProxyQueryPoolImpl*>(queryDescs[i].queryPool)
607                    ->m_bufferResource->getDeviceAddress() +
608                sizeof(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_COMPACTED_SIZE_DESC) *
609                    queryDescs[i].firstQueryIndex;
610            break;
611        case QueryType::AccelerationStructureCurrentSize:
612            postBuildInfoDescs[i].InfoType =
613                D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_CURRENT_SIZE;
614            postBuildInfoDescs[i].DestBuffer =
615                static_cast<PlainBufferProxyQueryPoolImpl*>(queryDescs[i].queryPool)
616                    ->m_bufferResource->getDeviceAddress() +
617                sizeof(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_COMPACTED_SIZE_DESC) *
618                    queryDescs[i].firstQueryIndex;
619            break;
620        case QueryType::AccelerationStructureSerializedSize:
621            postBuildInfoDescs[i].InfoType =
622                D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_SERIALIZATION;
623            postBuildInfoDescs[i].DestBuffer =
624                static_cast<PlainBufferProxyQueryPoolImpl*>(queryDescs[i].queryPool)
625                    ->m_bufferResource->getDeviceAddress() +
626                sizeof(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_SERIALIZATION_DESC) *
627                    queryDescs[i].firstQueryIndex;
628            break;
629        }
630    }
631}
632
633} // namespace d3d12
634
635Result SLANG_MCALL getD3D12Adapters(List<AdapterInfo>& outAdapters)
636{
637    List<ComPtr<IDXGIAdapter>> dxgiAdapters;
638    SLANG_RETURN_ON_FAIL(
639        D3DUtil::findAdapters(DeviceCheckFlag::UseHardwareDevice, nullptr, dxgiAdapters));
640
641    outAdapters.clear();
642    for (const auto& dxgiAdapter : dxgiAdapters)
643    {
644        DXGI_ADAPTER_DESC desc;
645        dxgiAdapter->GetDesc(&desc);
646        AdapterInfo info = {};
647        auto name = String::fromWString(desc.Description);
648        memcpy(
649            info.name,
650            name.getBuffer(),
651            Math::Min(name.getLength(), (Index)sizeof(AdapterInfo::name) - 1));
652        info.vendorID = desc.VendorId;
653        info.deviceID = desc.DeviceId;
654        info.luid = D3DUtil::getAdapterLUID(dxgiAdapter);
655        outAdapters.add(info);
656    }
657    return SLANG_OK;
658}
659
660Result SLANG_MCALL createD3D12Device(const IDevice::Desc* desc, IDevice** outDevice)
661{
662    RefPtr<d3d12::DeviceImpl> result = new d3d12::DeviceImpl();
663    SLANG_RETURN_ON_FAIL(result->initialize(*desc));
664    returnComPtr(outDevice, result);
665    return SLANG_OK;
666}
667
668} // namespace gfx