yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1// d3d12-command-queue.cpp 2#include "d3d12-command-queue.h" 3 4#include "d3d12-command-buffer.h" 5#include "d3d12-device.h" 6#include "d3d12-fence.h" 7 8namespace gfx 9{ 10namespace d3d12 11{ 12 13using namespace Slang ; 14 15Result CommandQueueImpl ::init (DeviceImpl * device ,uint32_t queueIndex ) 16{ 17m_queueIndex = queueIndex ; 18m_renderer = device ; 19m_device = device -> m_device ; 20D3D12_COMMAND_QUEUE_DESC queueDesc = {}; 21queueDesc .Type = D3D12_COMMAND_LIST_TYPE_DIRECT ; 22SLANG_RETURN_ON_FAIL ( 23m_device -> CreateCommandQueue (& queueDesc ,IID_PPV_ARGS (m_d3dQueue .writeRef ()))); 24SLANG_RETURN_ON_FAIL ( 25m_device -> CreateFence (0 ,D3D12_FENCE_FLAG_NONE ,IID_PPV_ARGS (m_fence .writeRef ()))); 26globalWaitHandle = CreateEventEx ( 27nullptr , 28nullptr , 29CREATE_EVENT_INITIAL_SET |CREATE_EVENT_MANUAL_RESET , 30EVENT_ALL_ACCESS ); 31return SLANG_OK ; 32} 33 34CommandQueueImpl ::~CommandQueueImpl () 35{ 36waitOnHost (); 37CloseHandle (globalWaitHandle ); 38m_renderer -> m_queueIndexAllocator .free ((int )m_queueIndex ,1 ); 39} 40 41void CommandQueueImpl ::executeCommandBuffers ( 42GfxCount count , 43ICommandBuffer * const * commandBuffers , 44IFence * fence , 45uint64_t valueToSignal ) 46{ 47ShortList < ID3D12CommandList *> commandLists ; 48for (GfxCount i = 0 ;i < count ;i ++ ) 49 { 50auto cmdImpl = static_cast < CommandBufferImpl *> (commandBuffers [i ]); 51commandLists .add (cmdImpl -> m_cmdList ); 52 } 53if (count > 0 ) 54 { 55m_d3dQueue -> ExecuteCommandLists ((UINT )count ,commandLists .getArrayView ().getBuffer ()); 56 57m_fenceValue ++ ; 58 59for (GfxCount i = 0 ;i < count ;i ++ ) 60 { 61if (i > 0 && commandBuffers [i ]== commandBuffers [i - 1 ]) 62continue ; 63auto cmdImpl = static_cast < CommandBufferImpl *> (commandBuffers [i ]); 64auto transientHeap = cmdImpl -> m_transientHeap ; 65auto & waitInfo = transientHeap -> getQueueWaitInfo (m_queueIndex ); 66waitInfo .waitValue = m_fenceValue ; 67waitInfo .fence = m_fence ; 68waitInfo .queue = m_d3dQueue ; 69 } 70 } 71 72if (fence ) 73 { 74auto fenceImpl = static_cast < FenceImpl *> (fence ); 75m_d3dQueue -> Signal (fenceImpl -> m_fence .get (),valueToSignal ); 76 } 77} 78 79void CommandQueueImpl ::waitOnHost () 80{ 81m_fenceValue ++ ; 82m_d3dQueue -> Signal (m_fence ,m_fenceValue ); 83ResetEvent (globalWaitHandle ); 84m_fence -> SetEventOnCompletion (m_fenceValue ,globalWaitHandle ); 85WaitForSingleObject (globalWaitHandle ,INFINITE ); 86} 87 88Result CommandQueueImpl ::waitForFenceValuesOnDevice ( 89GfxCount fenceCount , 90IFence ** fences , 91uint64_t * waitValues ) 92{ 93for (GfxCount i = 0 ;i < fenceCount ;++ i ) 94 { 95auto fenceImpl = static_cast < FenceImpl *> (fences [i ]); 96m_d3dQueue -> Wait (fenceImpl -> m_fence .get (),waitValues [i ]); 97 } 98return SLANG_OK ; 99} 100 101const CommandQueueImpl ::Desc & CommandQueueImpl ::getDesc () 102{ 103return m_desc ; 104} 105 106ICommandQueue * CommandQueueImpl ::getInterface (const Guid & guid ) 107{ 108if (guid == GfxGUID ::IID_ISlangUnknown || guid == GfxGUID ::IID_ICommandQueue ) 109return static_cast < ICommandQueue *> (this ); 110return nullptr ; 111} 112 113Result CommandQueueImpl ::getNativeHandle (InteropHandle * handle ) 114{ 115handle -> api = InteropHandleAPI ::D3D12 ; 116handle -> handleValue = (uint64_t )m_d3dQueue .get (); 117return SLANG_OK ; 118} 119 120}// namespace d3d12 121}// namespace gfx