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
5.3 KiB158 linesraw
1#pragma once
2
3#include "../renderer-shared.h"
4#include "core/slang-basic.h"
5#include "d3d-util.h"
6#include "slang-gfx.h"
7
8#include <dxgi1_4.h>
9
10namespace gfx
11{
12class D3DSwapchainBase : public ISwapchain, public Slang::ComObject
13{
14public:
15    SLANG_COM_OBJECT_IUNKNOWN_ALL
16    ISwapchain* getInterface(const Slang::Guid& guid)
17    {
18        if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_ISwapchain)
19            return static_cast<ISwapchain*>(this);
20        return nullptr;
21    }
22
23public:
24    Result init(const ISwapchain::Desc& desc, WindowHandle window, DXGI_SWAP_EFFECT swapEffect)
25    {
26        // Return fail on non-supported platforms.
27        switch (window.type)
28        {
29        case WindowHandle::Type::Win32Handle:
30            break;
31        default:
32            return SLANG_FAIL;
33        }
34
35        m_desc = desc;
36
37        m_desc.format = srgbToLinearFormat(m_desc.format);
38
39        // Describe the swap chain.
40        DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
41        swapChainDesc.BufferCount = desc.imageCount;
42        swapChainDesc.BufferDesc.Width = desc.width;
43        swapChainDesc.BufferDesc.Height = desc.height;
44        swapChainDesc.BufferDesc.Format = D3DUtil::getMapFormat(m_desc.format);
45        swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
46        swapChainDesc.SwapEffect = swapEffect;
47        swapChainDesc.OutputWindow = (HWND)window.handleValues[0];
48        swapChainDesc.SampleDesc.Count = 1;
49        swapChainDesc.Windowed = TRUE;
50        if (!desc.enableVSync)
51        {
52            swapChainDesc.Flags |= DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
53        }
54
55        // Swap chain needs the queue so that it can force a flush on it.
56        ComPtr<IDXGIFactory2> dxgiFactory2;
57        getDXGIFactory()->QueryInterface(IID_PPV_ARGS(dxgiFactory2.writeRef()));
58        if (!dxgiFactory2)
59        {
60            ComPtr<IDXGISwapChain> swapChain;
61            SLANG_RETURN_ON_FAIL(getDXGIFactory()->CreateSwapChain(
62                getOwningDevice(),
63                &swapChainDesc,
64                swapChain.writeRef()));
65            SLANG_RETURN_ON_FAIL(getDXGIFactory()->MakeWindowAssociation(
66                (HWND)window.handleValues[0],
67                DXGI_MWA_NO_ALT_ENTER));
68            SLANG_RETURN_ON_FAIL(swapChain->QueryInterface(m_swapChain.writeRef()));
69        }
70        else
71        {
72            DXGI_SWAP_CHAIN_DESC1 desc1 = {};
73            desc1.BufferCount = swapChainDesc.BufferCount;
74            desc1.BufferUsage = swapChainDesc.BufferUsage;
75            desc1.Flags = swapChainDesc.Flags;
76            desc1.Format = swapChainDesc.BufferDesc.Format;
77            desc1.Height = swapChainDesc.BufferDesc.Height;
78            desc1.Width = swapChainDesc.BufferDesc.Width;
79            desc1.SampleDesc = swapChainDesc.SampleDesc;
80            desc1.SwapEffect = swapChainDesc.SwapEffect;
81            ComPtr<IDXGISwapChain1> swapChain1;
82            SLANG_RETURN_ON_FAIL(dxgiFactory2->CreateSwapChainForHwnd(
83                getOwningDevice(),
84                (HWND)window.handleValues[0],
85                &desc1,
86                nullptr,
87                nullptr,
88                swapChain1.writeRef()));
89            SLANG_RETURN_ON_FAIL(swapChain1->QueryInterface(m_swapChain.writeRef()));
90        }
91
92        createSwapchainBufferImages();
93        return SLANG_OK;
94    }
95    virtual SLANG_NO_THROW const Desc& SLANG_MCALL getDesc() override { return m_desc; }
96    virtual SLANG_NO_THROW Result SLANG_MCALL
97    getImage(GfxIndex index, ITextureResource** outResource) override
98    {
99        returnComPtr(outResource, m_images[index]);
100        return SLANG_OK;
101    }
102    virtual SLANG_NO_THROW Result SLANG_MCALL present() override
103    {
104        const auto res = m_swapChain->Present(m_desc.enableVSync ? 1 : 0, 0);
105
106        // We may want to wait for crash dump completion for some kinds of debugging scenarios
107        if (res == DXGI_ERROR_DEVICE_REMOVED || res == DXGI_ERROR_DEVICE_RESET)
108        {
109            D3DUtil::waitForCrashDumpCompletion(res);
110        }
111
112        if (SLANG_FAILED(res))
113        {
114            return SLANG_FAIL;
115        }
116        return SLANG_OK;
117    }
118
119    virtual SLANG_NO_THROW int SLANG_MCALL acquireNextImage() override
120    {
121        uint32_t count;
122        m_swapChain->GetLastPresentCount(&count);
123        return (int)(count % m_desc.imageCount);
124    }
125
126
127    virtual SLANG_NO_THROW Result SLANG_MCALL resize(GfxCount width, GfxCount height) override
128    {
129        if (width == m_desc.width && height == m_desc.height)
130            return SLANG_OK;
131
132        m_desc.width = width;
133        m_desc.height = height;
134        for (auto& image : m_images)
135            image = nullptr;
136        m_images.clear();
137        auto result = m_swapChain->ResizeBuffers(
138            m_desc.imageCount,
139            width,
140            height,
141            D3DUtil::getMapFormat(m_desc.format),
142            m_desc.enableVSync ? 0 : DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT);
143        if (result != 0)
144            return SLANG_FAIL;
145        createSwapchainBufferImages();
146        return SLANG_OK;
147    }
148
149public:
150    virtual void createSwapchainBufferImages() = 0;
151    virtual IDXGIFactory* getDXGIFactory() = 0;
152    virtual IUnknown* getOwningDevice() = 0;
153    ISwapchain::Desc m_desc;
154    ComPtr<IDXGISwapChain2> m_swapChain;
155    Slang::ShortList<Slang::RefPtr<TextureResource>> m_images;
156};
157
158} // namespace gfx