yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1// metal-swap-chain.cpp 2#include "metal-swap-chain.h" 3 4#include "../apple/cocoa-util.h" 5#include "metal-util.h" 6 7namespace gfx 8{ 9 10using namespace Slang ; 11 12namespace metal 13{ 14 15ISwapchain * SwapchainImpl ::getInterface (const Guid & guid ) 16{ 17if (guid == GfxGUID ::IID_ISlangUnknown || guid == GfxGUID ::IID_ISwapchain ) 18return static_cast < ISwapchain *> (this ); 19return nullptr ; 20} 21 22void SwapchainImpl ::getWindowSize (int & widthOut ,int & heightOut )const 23{ 24CocoaUtil ::getNSWindowContentSize ((void * )m_windowHandle .handleValues [0 ],& widthOut ,& heightOut ); 25} 26 27void SwapchainImpl ::createImages () 28{ 29m_images .setCount (m_desc .imageCount ); 30for (GfxCount i = 0 ;i < m_desc .imageCount ;++ i ) 31 { 32ITextureResource ::Desc imageDesc = {}; 33imageDesc .allowedStates = ResourceStateSet ( 34ResourceState ::Present , 35ResourceState ::RenderTarget , 36ResourceState ::CopyDestination , 37ResourceState ::CopySource ); 38imageDesc .type = IResource ::Type ::Texture2D ; 39imageDesc .arraySize = 0 ; 40imageDesc .format = m_desc .format ; 41imageDesc .size .width = m_desc .width ; 42imageDesc .size .height = m_desc .height ; 43imageDesc .size .depth = 1 ; 44imageDesc .numMipLevels = 1 ; 45imageDesc .defaultState = ResourceState ::Present ; 46m_device -> createTextureResource ( 47imageDesc , 48nullptr , 49 (gfx::ITextureResource ** )m_images [i ].writeRef ()); 50 } 51} 52 53SwapchainImpl ::~SwapchainImpl () 54{ 55m_images .clear (); 56CocoaUtil ::destroyMetalLayer (m_metalLayer ); 57} 58 59Result SwapchainImpl ::init (DeviceImpl * device ,const ISwapchain ::Desc & desc ,WindowHandle window ) 60{ 61m_device = device ; 62m_desc = desc ; 63m_windowHandle = window ; 64m_metalFormat = MetalUtil ::translatePixelFormat (desc .format ); 65m_currentImageIndex = -1 ; 66 67getWindowSize (m_desc .width ,m_desc .height ); 68 69m_metalLayer = (CA ::MetalLayer * )CocoaUtil ::createMetalLayer ((void * )window .handleValues [0 ]); 70if (!m_metalLayer ) 71 { 72return SLANG_FAIL ; 73 } 74m_metalLayer -> setPixelFormat (m_metalFormat ); 75m_metalLayer -> setDevice (m_device -> m_device .get ()); 76m_metalLayer -> setDrawableSize (CGSize {(float )m_desc .width , (float )m_desc .height }); 77// We need to be able to copy from a texture. 78m_metalLayer -> setFramebufferOnly (false); 79 80createImages (); 81 82return SLANG_OK ; 83} 84 85Result SwapchainImpl ::getImage (GfxIndex index ,ITextureResource ** outResource ) 86{ 87if (index < 0 || index >=m_desc .imageCount ) 88return SLANG_FAIL ; 89returnComPtr (outResource ,m_images [index ]); 90return SLANG_OK ; 91} 92 93Result SwapchainImpl ::resize (GfxCount width ,GfxCount height ) 94{ 95m_currentImageIndex = -1 ; 96m_currentDrawable .reset (); 97getWindowSize (m_desc .width ,m_desc .height ); 98m_metalLayer -> setDrawableSize (CGSize {(float )m_desc .width , (float )m_desc .height }); 99createImages (); 100return SLANG_OK ; 101} 102 103Result SwapchainImpl ::present () 104{ 105AUTORELEASEPOOL 106 107if (!m_currentDrawable ) 108 { 109return SLANG_FAIL ; 110 } 111 112MTL ::CommandBuffer * commandBuffer = m_device -> m_commandQueue -> commandBuffer (); 113MTL ::BlitCommandEncoder * encoder = commandBuffer -> blitCommandEncoder (); 114encoder -> copyFromTexture ( 115m_images [m_currentImageIndex ]-> m_texture .get (), 116m_currentDrawable -> texture ()); 117encoder -> endEncoding (); 118commandBuffer -> presentDrawable (m_currentDrawable .get ()); 119commandBuffer -> commit (); 120m_currentDrawable .reset (); 121return SLANG_OK ; 122 123// // TODO: Expose controls via some other means 124// static uint32_t frameCount = 0; 125// static uint32_t maxFrameCount = 32; 126// ++frameCount; 127// if (m_device->captureEnabled() && frameCount == maxFrameCount) 128// { 129// MTL::CaptureManager* captureManager = MTL::CaptureManager::sharedCaptureManager(); 130// captureManager->stopCapture(); 131// exit(1); 132// } 133// return SLANG_OK; 134} 135 136int SwapchainImpl ::acquireNextImage () 137{ 138AUTORELEASEPOOL 139 140m_currentDrawable = NS ::RetainPtr (m_metalLayer -> nextDrawable ()); 141if (m_currentDrawable ) 142 { 143m_currentImageIndex = (m_currentImageIndex + 1 ) %m_desc .imageCount ; 144 } 145else 146 { 147m_currentImageIndex = -1 ; 148 } 149return m_currentImageIndex ; 150} 151 152Result SwapchainImpl ::setFullScreenMode (bool mode ) 153{ 154return SLANG_E_NOT_AVAILABLE ; 155} 156 157}// namespace metal 158}// namespace gfx