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
10.7 KiB416 linesraw
1// d3d11-helper-functions.cpp
2#include "d3d11-helper-functions.h"
3
4#include "d3d11-device.h"
5
6namespace gfx
7{
8
9using namespace Slang;
10
11namespace d3d11
12{
13bool isSupportedNVAPIOp(IUnknown* dev, uint32_t op)
14{
15#ifdef GFX_NVAPI
16    {
17        bool isSupported;
18        NvAPI_Status status =
19            NvAPI_D3D11_IsNvShaderExtnOpCodeSupported(dev, NvU32(op), &isSupported);
20        return status == NVAPI_OK && isSupported;
21    }
22#else
23    return false;
24#endif
25}
26
27D3D11_BIND_FLAG calcResourceFlag(ResourceState state)
28{
29    switch (state)
30    {
31    case ResourceState::VertexBuffer:
32        return D3D11_BIND_VERTEX_BUFFER;
33    case ResourceState::IndexBuffer:
34        return D3D11_BIND_INDEX_BUFFER;
35    case ResourceState::ConstantBuffer:
36        return D3D11_BIND_CONSTANT_BUFFER;
37    case ResourceState::StreamOutput:
38        return D3D11_BIND_STREAM_OUTPUT;
39    case ResourceState::RenderTarget:
40        return D3D11_BIND_RENDER_TARGET;
41    case ResourceState::DepthRead:
42    case ResourceState::DepthWrite:
43        return D3D11_BIND_DEPTH_STENCIL;
44    case ResourceState::UnorderedAccess:
45        return D3D11_BIND_UNORDERED_ACCESS;
46    case ResourceState::ShaderResource:
47    case ResourceState::PixelShaderResource:
48    case ResourceState::NonPixelShaderResource:
49        return D3D11_BIND_SHADER_RESOURCE;
50    default:
51        return D3D11_BIND_FLAG(0);
52    }
53}
54
55int _calcResourceBindFlags(ResourceStateSet allowedStates)
56{
57    int dstFlags = 0;
58    for (uint32_t i = 0; i < (uint32_t)ResourceState::_Count; i++)
59    {
60        auto state = (ResourceState)i;
61        if (allowedStates.contains(state))
62            dstFlags |= calcResourceFlag(state);
63    }
64    return dstFlags;
65}
66
67int _calcResourceAccessFlags(MemoryType memType)
68{
69    switch (memType)
70    {
71    case MemoryType::DeviceLocal:
72        return 0;
73    case MemoryType::ReadBack:
74        return D3D11_CPU_ACCESS_READ;
75    case MemoryType::Upload:
76        return D3D11_CPU_ACCESS_WRITE;
77    default:
78        assert(!"Invalid flags");
79        return 0;
80    }
81}
82
83D3D11_FILTER_TYPE translateFilterMode(TextureFilteringMode mode)
84{
85    switch (mode)
86    {
87    default:
88        return D3D11_FILTER_TYPE(0);
89
90#define CASE(SRC, DST)              \
91    case TextureFilteringMode::SRC: \
92        return D3D11_FILTER_TYPE_##DST
93
94        CASE(Point, POINT);
95        CASE(Linear, LINEAR);
96
97#undef CASE
98    }
99}
100
101D3D11_FILTER_REDUCTION_TYPE translateFilterReduction(TextureReductionOp op)
102{
103    switch (op)
104    {
105    default:
106        return D3D11_FILTER_REDUCTION_TYPE(0);
107
108#define CASE(SRC, DST)            \
109    case TextureReductionOp::SRC: \
110        return D3D11_FILTER_REDUCTION_TYPE_##DST
111
112        CASE(Average, STANDARD);
113        CASE(Comparison, COMPARISON);
114        CASE(Minimum, MINIMUM);
115        CASE(Maximum, MAXIMUM);
116
117#undef CASE
118    }
119}
120
121D3D11_TEXTURE_ADDRESS_MODE translateAddressingMode(TextureAddressingMode mode)
122{
123    switch (mode)
124    {
125    default:
126        return D3D11_TEXTURE_ADDRESS_MODE(0);
127
128#define CASE(SRC, DST)               \
129    case TextureAddressingMode::SRC: \
130        return D3D11_TEXTURE_ADDRESS_##DST
131
132        CASE(Wrap, WRAP);
133        CASE(ClampToEdge, CLAMP);
134        CASE(ClampToBorder, BORDER);
135        CASE(MirrorRepeat, MIRROR);
136        CASE(MirrorOnce, MIRROR_ONCE);
137
138#undef CASE
139    }
140}
141
142D3D11_COMPARISON_FUNC translateComparisonFunc(ComparisonFunc func)
143{
144    switch (func)
145    {
146    default:
147        // TODO: need to report failures
148        return D3D11_COMPARISON_ALWAYS;
149
150#define CASE(FROM, TO)         \
151    case ComparisonFunc::FROM: \
152        return D3D11_COMPARISON_##TO
153
154        CASE(Never, NEVER);
155        CASE(Less, LESS);
156        CASE(Equal, EQUAL);
157        CASE(LessEqual, LESS_EQUAL);
158        CASE(Greater, GREATER);
159        CASE(NotEqual, NOT_EQUAL);
160        CASE(GreaterEqual, GREATER_EQUAL);
161        CASE(Always, ALWAYS);
162#undef CASE
163    }
164}
165
166D3D11_STENCIL_OP translateStencilOp(StencilOp op)
167{
168    switch (op)
169    {
170    default:
171        // TODO: need to report failures
172        return D3D11_STENCIL_OP_KEEP;
173
174#define CASE(FROM, TO)    \
175    case StencilOp::FROM: \
176        return D3D11_STENCIL_OP_##TO
177
178        CASE(Keep, KEEP);
179        CASE(Zero, ZERO);
180        CASE(Replace, REPLACE);
181        CASE(IncrementSaturate, INCR_SAT);
182        CASE(DecrementSaturate, DECR_SAT);
183        CASE(Invert, INVERT);
184        CASE(IncrementWrap, INCR);
185        CASE(DecrementWrap, DECR);
186#undef CASE
187    }
188}
189
190D3D11_FILL_MODE translateFillMode(FillMode mode)
191{
192    switch (mode)
193    {
194    default:
195        // TODO: need to report failures
196        return D3D11_FILL_SOLID;
197
198    case FillMode::Solid:
199        return D3D11_FILL_SOLID;
200    case FillMode::Wireframe:
201        return D3D11_FILL_WIREFRAME;
202    }
203}
204
205D3D11_CULL_MODE translateCullMode(CullMode mode)
206{
207    switch (mode)
208    {
209    default:
210        // TODO: need to report failures
211        return D3D11_CULL_NONE;
212
213    case CullMode::None:
214        return D3D11_CULL_NONE;
215    case CullMode::Back:
216        return D3D11_CULL_BACK;
217    case CullMode::Front:
218        return D3D11_CULL_FRONT;
219    }
220}
221
222bool isBlendDisabled(AspectBlendDesc const& desc)
223{
224    return desc.op == BlendOp::Add && desc.srcFactor == BlendFactor::One &&
225           desc.dstFactor == BlendFactor::Zero;
226}
227
228
229bool isBlendDisabled(TargetBlendDesc const& desc)
230{
231    return isBlendDisabled(desc.color) && isBlendDisabled(desc.alpha);
232}
233
234D3D11_BLEND_OP translateBlendOp(BlendOp op)
235{
236    switch (op)
237    {
238    default:
239        assert(!"unimplemented");
240        return (D3D11_BLEND_OP)-1;
241
242#define CASE(FROM, TO)  \
243    case BlendOp::FROM: \
244        return D3D11_BLEND_OP_##TO
245        CASE(Add, ADD);
246        CASE(Subtract, SUBTRACT);
247        CASE(ReverseSubtract, REV_SUBTRACT);
248        CASE(Min, MIN);
249        CASE(Max, MAX);
250#undef CASE
251    }
252}
253
254D3D11_BLEND translateBlendFactor(BlendFactor factor)
255{
256    switch (factor)
257    {
258    default:
259        assert(!"unimplemented");
260        return (D3D11_BLEND)-1;
261
262#define CASE(FROM, TO)      \
263    case BlendFactor::FROM: \
264        return D3D11_BLEND_##TO
265        CASE(Zero, ZERO);
266        CASE(One, ONE);
267        CASE(SrcColor, SRC_COLOR);
268        CASE(InvSrcColor, INV_SRC_COLOR);
269        CASE(SrcAlpha, SRC_ALPHA);
270        CASE(InvSrcAlpha, INV_SRC_ALPHA);
271        CASE(DestAlpha, DEST_ALPHA);
272        CASE(InvDestAlpha, INV_DEST_ALPHA);
273        CASE(DestColor, DEST_COLOR);
274        CASE(InvDestColor, INV_DEST_ALPHA);
275        CASE(SrcAlphaSaturate, SRC_ALPHA_SAT);
276        CASE(BlendColor, BLEND_FACTOR);
277        CASE(InvBlendColor, INV_BLEND_FACTOR);
278        CASE(SecondarySrcColor, SRC1_COLOR);
279        CASE(InvSecondarySrcColor, INV_SRC1_COLOR);
280        CASE(SecondarySrcAlpha, SRC1_ALPHA);
281        CASE(InvSecondarySrcAlpha, INV_SRC1_ALPHA);
282#undef CASE
283    }
284}
285
286D3D11_COLOR_WRITE_ENABLE translateRenderTargetWriteMask(RenderTargetWriteMaskT mask)
287{
288    UINT result = 0;
289#define CASE(FROM, TO)                              \
290    if (mask & RenderTargetWriteMask::Enable##FROM) \
291    result |= D3D11_COLOR_WRITE_ENABLE_##TO
292
293    CASE(Red, RED);
294    CASE(Green, GREEN);
295    CASE(Blue, BLUE);
296    CASE(Alpha, ALPHA);
297
298#undef CASE
299    return D3D11_COLOR_WRITE_ENABLE(result);
300}
301
302void initSrvDesc(
303    IResource::Type resourceType,
304    const ITextureResource::Desc& textureDesc,
305    DXGI_FORMAT pixelFormat,
306    D3D11_SHADER_RESOURCE_VIEW_DESC& descOut)
307{
308    // create SRV
309    descOut = D3D11_SHADER_RESOURCE_VIEW_DESC();
310
311    descOut.Format =
312        (pixelFormat == DXGI_FORMAT_UNKNOWN)
313            ? D3DUtil::calcFormat(D3DUtil::USAGE_SRV, D3DUtil::getMapFormat(textureDesc.format))
314            : pixelFormat;
315    const int arraySize = calcEffectiveArraySize(textureDesc);
316    if (arraySize <= 1)
317    {
318        switch (textureDesc.type)
319        {
320        case IResource::Type::Texture1D:
321            descOut.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D;
322            break;
323        case IResource::Type::Texture2D:
324            descOut.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
325            break;
326        case IResource::Type::Texture3D:
327            descOut.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
328            break;
329        default:
330            assert(!"Unknown dimension");
331        }
332
333        descOut.Texture2D.MipLevels = textureDesc.numMipLevels;
334        descOut.Texture2D.MostDetailedMip = 0;
335    }
336    else if (resourceType == IResource::Type::TextureCube)
337    {
338        if (textureDesc.arraySize > 1)
339        {
340            descOut.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY;
341
342            descOut.TextureCubeArray.NumCubes = textureDesc.arraySize;
343            descOut.TextureCubeArray.First2DArrayFace = 0;
344            descOut.TextureCubeArray.MipLevels = textureDesc.numMipLevels;
345            descOut.TextureCubeArray.MostDetailedMip = 0;
346        }
347        else
348        {
349            descOut.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
350
351            descOut.TextureCube.MipLevels = textureDesc.numMipLevels;
352            descOut.TextureCube.MostDetailedMip = 0;
353        }
354    }
355    else
356    {
357        assert(textureDesc.size.depth > 1 || arraySize > 1);
358
359        switch (textureDesc.type)
360        {
361        case IResource::Type::Texture1D:
362            descOut.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY;
363            break;
364        case IResource::Type::Texture2D:
365            descOut.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
366            break;
367        case IResource::Type::Texture3D:
368            descOut.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
369            break;
370
371        default:
372            assert(!"Unknown dimension");
373        }
374
375        descOut.Texture2DArray.ArraySize = std::max(textureDesc.size.depth, arraySize);
376        descOut.Texture2DArray.MostDetailedMip = 0;
377        descOut.Texture2DArray.MipLevels = textureDesc.numMipLevels;
378        descOut.Texture2DArray.FirstArraySlice = 0;
379    }
380}
381} // namespace d3d11
382
383Result SLANG_MCALL getD3D11Adapters(List<AdapterInfo>& outAdapters)
384{
385    List<ComPtr<IDXGIAdapter>> dxgiAdapters;
386    SLANG_RETURN_ON_FAIL(
387        D3DUtil::findAdapters(DeviceCheckFlag::UseHardwareDevice, nullptr, dxgiAdapters));
388
389    outAdapters.clear();
390    for (const auto& dxgiAdapter : dxgiAdapters)
391    {
392        DXGI_ADAPTER_DESC desc;
393        dxgiAdapter->GetDesc(&desc);
394        AdapterInfo info = {};
395        auto name = String::fromWString(desc.Description);
396        memcpy(
397            info.name,
398            name.getBuffer(),
399            Math::Min(name.getLength(), (Index)sizeof(AdapterInfo::name) - 1));
400        info.vendorID = desc.VendorId;
401        info.deviceID = desc.DeviceId;
402        info.luid = D3DUtil::getAdapterLUID(dxgiAdapter);
403        outAdapters.add(info);
404    }
405    return SLANG_OK;
406}
407
408Result SLANG_MCALL createD3D11Device(const IDevice::Desc* desc, IDevice** outDevice)
409{
410    RefPtr<d3d11::DeviceImpl> result = new d3d11::DeviceImpl();
411    SLANG_RETURN_ON_FAIL(result->initialize(*desc));
412    returnComPtr(outDevice, result);
413    return SLANG_OK;
414}
415
416} // namespace gfx