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