yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1// metal-command-queue.cpp 2#include "metal-command-queue.h" 3 4#include "metal-command-buffer.h" 5#include "metal-fence.h" 6#include "metal-util.h" 7 8namespace gfx 9{ 10 11using namespace Slang ; 12 13namespace metal 14{ 15 16ICommandQueue * CommandQueueImpl ::getInterface (const Guid & guid ) 17{ 18if (guid == GfxGUID ::IID_ISlangUnknown || guid == GfxGUID ::IID_ICommandQueue ) 19return static_cast < ICommandQueue *> (this ); 20return nullptr ; 21} 22 23CommandQueueImpl ::~CommandQueueImpl () {} 24 25void CommandQueueImpl ::init (DeviceImpl * device ,NS ::SharedPtr < MTL ::CommandQueue > commandQueue ) 26{ 27m_device = device ; 28m_commandQueue = commandQueue ; 29} 30 31void CommandQueueImpl ::waitOnHost () 32{ 33// TODO implement 34} 35 36Result CommandQueueImpl ::getNativeHandle (InteropHandle * outHandle ) 37{ 38outHandle -> api = InteropHandleAPI ::Metal ; 39outHandle -> handleValue = reinterpret_cast < intptr_t > (m_commandQueue .get ()); 40return SLANG_OK ; 41} 42 43const CommandQueueImpl ::Desc & CommandQueueImpl ::getDesc () 44{ 45return m_desc ; 46} 47 48Result CommandQueueImpl ::waitForFenceValuesOnDevice ( 49GfxCount fenceCount , 50IFence ** fences , 51uint64_t * waitValues ) 52{ 53for (GfxCount i = 0 ;i < fenceCount ;++ i ) 54 { 55FenceWaitInfo waitInfo ; 56waitInfo .fence = static_cast < FenceImpl *> (fences [i ]); 57waitInfo .waitValue = waitValues [i ]; 58m_pendingWaitFences .add (waitInfo ); 59 } 60return SLANG_OK ; 61} 62 63void CommandQueueImpl ::queueSubmitImpl ( 64uint32_t count , 65ICommandBuffer * const * commandBuffers , 66IFence * fence , 67uint64_t valueToSignal ) 68{ 69// If there are any pending wait fences, encode them to a new command buffer. 70// Metal ensures that command buffers are executed in the order they are committed. 71if (m_pendingWaitFences .getCount ()> 0 ) 72 { 73MTL ::CommandBuffer * commandBuffer = m_commandQueue -> commandBuffer (); 74for (const auto & fenceInfo :m_pendingWaitFences ) 75 { 76commandBuffer -> encodeWait (fenceInfo .fence -> m_event .get (),fenceInfo .waitValue ); 77 } 78commandBuffer -> commit (); 79m_pendingWaitFences .clear (); 80 } 81 82for (uint32_t i = 0 ;i < count ;++ i ) 83 { 84CommandBufferImpl * cmdBufImpl = static_cast < CommandBufferImpl *> (commandBuffers [i ]); 85// If this is the last command buffer and a fence is provided, signal the fence. 86if (i == count - 1 && fence != nullptr ) 87 { 88cmdBufImpl -> m_commandBuffer -> encodeSignalEvent ( 89static_cast < FenceImpl *> (fence )-> m_event .get (), 90valueToSignal ); 91 } 92cmdBufImpl -> m_commandBuffer -> commit (); 93 } 94 95// If there are no command buffers to submit, but a fence is provided, signal the fence. 96if (count == 0 && fence != nullptr ) 97 { 98MTL ::CommandBuffer * commandBuffer = m_commandQueue -> commandBuffer (); 99commandBuffer -> encodeSignalEvent ( 100static_cast < FenceImpl *> (fence )-> m_event .get (), 101valueToSignal ); 102commandBuffer -> commit (); 103 } 104} 105 106void CommandQueueImpl ::executeCommandBuffers ( 107GfxCount count , 108ICommandBuffer * const * commandBuffers , 109IFence * fence , 110uint64_t valueToSignal ) 111{ 112AUTORELEASEPOOL 113 114if (count == 0 && fence == nullptr ) 115 { 116return ; 117 } 118queueSubmitImpl (count ,commandBuffers ,fence ,valueToSignal ); 119} 120 121}// namespace metal 122}// namespace gfx