yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
b118451e3
master
1#include "immediate-renderer-base.h" 2 3#include "command-encoder-com-forward.h" 4#include "command-writer.h" 5#include "core/slang-basic.h" 6#include "core/slang-blob.h" 7#include "simple-render-pass-layout.h" 8#include "simple-transient-resource-heap.h" 9 10namespace gfx 11{ 12using Slang ::RefPtr ; 13using Slang ::List ; 14using Slang ::ShortList ; 15using Slang ::ListBlob ; 16using Slang ::Index ; 17using Slang ::RefObject ; 18using Slang ::ComPtr ; 19using Slang ::Guid ; 20 21namespace 22{ 23 24class CommandBufferImpl :public ICommandBuffer ,public Slang ::ComObject 25{ 26public : 27SLANG_COM_OBJECT_IUNKNOWN_ALL 28ICommandBuffer * getInterface (const Guid & guid ) 29 { 30if (guid == GfxGUID ::IID_ISlangUnknown || guid == GfxGUID ::IID_ICommandBuffer ) 31return static_cast < ICommandBuffer *> (this ); 32return nullptr ; 33 } 34 35public : 36CommandWriter m_writer ; 37bool m_hasWriteTimestamps = false; 38RefPtr < ImmediateRendererBase > m_renderer ; 39RefPtr < ShaderObjectBase > m_rootShaderObject ; 40TransientResourceHeapBase * m_transientHeap ; 41 42void init (ImmediateRendererBase * renderer ,TransientResourceHeapBase * transientHeap ) 43 { 44m_renderer = renderer ; 45m_transientHeap = transientHeap ; 46 } 47 48void reset () {m_writer .clear (); } 49 50class ResourceCommandEncoderImpl :public IResourceCommandEncoder 51 { 52public : 53CommandWriter * m_writer ; 54CommandBufferImpl * m_commandBuffer ; 55void init (CommandBufferImpl * cmdBuffer ) 56 { 57m_writer = & cmdBuffer -> m_writer ; 58m_commandBuffer = cmdBuffer ; 59 } 60 61virtual void * getInterface (SlangUUID const & uuid ) 62 { 63if (uuid == GfxGUID ::IID_IResourceCommandEncoder || 64uuid == ISlangUnknown ::getTypeGuid ()) 65 { 66return this ; 67 } 68return nullptr ; 69 } 70virtual SLANG_NO_THROW SlangResult SLANG_MCALL 71queryInterface (SlangUUID const & uuid ,void ** outObject )override 72 { 73if (auto ptr = getInterface (uuid )) 74 { 75* outObject = ptr ; 76return SLANG_OK ; 77 } 78return SLANG_E_NO_INTERFACE ; 79 } 80virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef ()override {return 1 ; } 81virtual SLANG_NO_THROW uint32_t SLANG_MCALL release ()override {return 1 ; } 82 83virtual SLANG_NO_THROW void SLANG_MCALL endEncoding ()override {} 84virtual SLANG_NO_THROW void SLANG_MCALL copyBuffer ( 85IBufferResource * dst , 86size_t dstOffset , 87IBufferResource * src , 88size_t srcOffset , 89size_t size )override 90 { 91m_writer -> copyBuffer (dst ,dstOffset ,src ,srcOffset ,size ); 92 } 93 94virtual SLANG_NO_THROW void SLANG_MCALL 95uploadBufferData (IBufferResource * dst ,size_t offset ,size_t size ,void * data )override 96 { 97m_writer -> uploadBufferData (dst ,offset ,size ,data ); 98 } 99 100virtual SLANG_NO_THROW void SLANG_MCALL 101writeTimestamp (IQueryPool * pool ,GfxIndex index )override 102 { 103m_writer -> writeTimestamp (pool ,index ); 104 } 105 106virtual SLANG_NO_THROW void SLANG_MCALL textureBarrier ( 107GfxCount count , 108ITextureResource * const * textures , 109ResourceState src , 110ResourceState dst )override 111 { 112 } 113 114virtual SLANG_NO_THROW void SLANG_MCALL bufferBarrier ( 115GfxCount count , 116IBufferResource * const * buffers , 117ResourceState src , 118ResourceState dst )override 119 { 120 } 121 122virtual SLANG_NO_THROW void SLANG_MCALL copyTexture ( 123ITextureResource * dst , 124ResourceState dstState , 125SubresourceRange dstSubresource , 126ITextureResource ::Offset3D dstOffset , 127ITextureResource * src , 128ResourceState srcState , 129SubresourceRange srcSubresource , 130ITextureResource ::Offset3D srcOffset , 131ITextureResource ::Extents extent )override 132 { 133SLANG_UNUSED (dst ); 134SLANG_UNUSED (dstState ); 135SLANG_UNUSED (dstSubresource ); 136SLANG_UNUSED (dstOffset ); 137SLANG_UNUSED (src ); 138SLANG_UNUSED (srcState ); 139SLANG_UNUSED (srcSubresource ); 140SLANG_UNUSED (srcOffset ); 141SLANG_UNUSED (extent ); 142SLANG_UNIMPLEMENTED_X ("copyTexture" ); 143 } 144 145virtual SLANG_NO_THROW void SLANG_MCALL uploadTextureData ( 146ITextureResource * dst , 147SubresourceRange subResourceRange , 148ITextureResource ::Offset3D offset , 149ITextureResource ::Extents extend , 150ITextureResource ::SubresourceData * subResourceData , 151GfxCount subResourceDataCount )override 152 { 153SLANG_UNUSED (dst ); 154SLANG_UNUSED (subResourceRange ); 155SLANG_UNUSED (offset ); 156SLANG_UNUSED (extend ); 157SLANG_UNUSED (subResourceData ); 158SLANG_UNUSED (subResourceDataCount ); 159SLANG_UNIMPLEMENTED_X ("uploadTextureData" ); 160 } 161 162virtual SLANG_NO_THROW void SLANG_MCALL clearResourceView ( 163IResourceView * view , 164ClearValue * clearValue , 165ClearResourceViewFlags ::Enum flags )override 166 { 167SLANG_UNUSED (view ); 168SLANG_UNUSED (clearValue ); 169SLANG_UNUSED (flags ); 170SLANG_UNIMPLEMENTED_X ("clearResourceView" ); 171 } 172 173virtual SLANG_NO_THROW void SLANG_MCALL resolveResource ( 174ITextureResource * source , 175ResourceState sourceState , 176SubresourceRange sourceRange , 177ITextureResource * dest , 178ResourceState destState , 179SubresourceRange destRange )override 180 { 181SLANG_UNUSED (source ); 182SLANG_UNUSED (sourceState ); 183SLANG_UNUSED (sourceRange ); 184SLANG_UNUSED (dest ); 185SLANG_UNUSED (destState ); 186SLANG_UNUSED (destRange ); 187SLANG_UNIMPLEMENTED_X ("resolveResource" ); 188 } 189 190virtual SLANG_NO_THROW void SLANG_MCALL resolveQuery ( 191IQueryPool * queryPool , 192GfxIndex index , 193GfxCount count , 194IBufferResource * buffer , 195Offset offset )override 196 { 197SLANG_UNUSED (queryPool ); 198SLANG_UNUSED (index ); 199SLANG_UNUSED (count ); 200SLANG_UNUSED (buffer ); 201SLANG_UNUSED (offset ); 202SLANG_UNIMPLEMENTED_X ("resolveQuery" ); 203 } 204 205virtual SLANG_NO_THROW void SLANG_MCALL copyTextureToBuffer ( 206IBufferResource * dst , 207Offset dstOffset , 208Size dstSize , 209Size dstRowStride , 210ITextureResource * src , 211ResourceState srcState , 212SubresourceRange srcSubresource , 213ITextureResource ::Offset3D srcOffset , 214ITextureResource ::Extents extent )override 215 { 216SLANG_UNUSED (dst ); 217SLANG_UNUSED (dstOffset ); 218SLANG_UNUSED (dstSize ); 219SLANG_UNUSED (dstRowStride ); 220SLANG_UNUSED (src ); 221SLANG_UNUSED (srcState ); 222SLANG_UNUSED (srcSubresource ); 223SLANG_UNUSED (srcOffset ); 224SLANG_UNUSED (extent ); 225SLANG_UNIMPLEMENTED_X ("copyTextureToBuffer" ); 226 } 227 228virtual SLANG_NO_THROW void SLANG_MCALL textureSubresourceBarrier ( 229ITextureResource * texture , 230SubresourceRange subresourceRange , 231ResourceState src , 232ResourceState dst )override 233 { 234SLANG_UNUSED (texture ); 235SLANG_UNUSED (subresourceRange ); 236SLANG_UNUSED (src ); 237SLANG_UNUSED (dst ); 238SLANG_UNIMPLEMENTED_X ("textureSubresourceBarrier" ); 239 } 240 241virtual SLANG_NO_THROW void SLANG_MCALL 242beginDebugEvent (const char * name ,float rgbColor [3 ])override 243 { 244SLANG_UNUSED (name ); 245SLANG_UNUSED (rgbColor ); 246 } 247virtual SLANG_NO_THROW void SLANG_MCALL endDebugEvent ()override {} 248 }; 249 250ResourceCommandEncoderImpl m_resourceCommandEncoder ; 251 252virtual SLANG_NO_THROW void SLANG_MCALL 253encodeResourceCommands (IResourceCommandEncoder ** outEncoder )override 254 { 255m_resourceCommandEncoder .init (this ); 256* outEncoder = & m_resourceCommandEncoder ; 257 } 258 259class RenderCommandEncoderImpl :public IRenderCommandEncoder ,public ResourceCommandEncoderImpl 260 { 261public : 262SLANG_GFX_FORWARD_RESOURCE_COMMAND_ENCODER_IMPL (ResourceCommandEncoderImpl ) 263virtual void * getInterface (SlangUUID const & uuid )override 264 { 265if (uuid == GfxGUID ::IID_IResourceCommandEncoder || 266uuid == GfxGUID ::IID_IRenderCommandEncoder || uuid == ISlangUnknown ::getTypeGuid ()) 267 { 268return this ; 269 } 270return nullptr ; 271 } 272 273public : 274virtual SLANG_NO_THROW void SLANG_MCALL endEncoding ()override {} 275 276void init ( 277CommandBufferImpl * cmdBuffer , 278SimpleRenderPassLayout * renderPass , 279IFramebuffer * framebuffer ) 280 { 281ResourceCommandEncoderImpl ::init (cmdBuffer ); 282 283// Encode clear commands. 284m_writer -> setFramebuffer (framebuffer ); 285uint32_t clearMask = 0 ; 286for (Index i = 0 ;i < renderPass -> m_renderTargetAccesses .getCount ();i ++ ) 287 { 288auto & access = renderPass -> m_renderTargetAccesses [i ]; 289// Clear. 290if (access .loadOp == IRenderPassLayout ::TargetLoadOp ::Clear ) 291 { 292clearMask |= (1 << (uint32_t )i ); 293 } 294 } 295bool clearDepth = false; 296bool clearStencil = false; 297if (renderPass -> m_hasDepthStencil ) 298 { 299// Clear. 300if (renderPass -> m_depthStencilAccess .loadOp == 301IRenderPassLayout ::TargetLoadOp ::Clear ) 302 { 303clearDepth = true; 304 } 305if (renderPass -> m_depthStencilAccess .stencilLoadOp == 306IRenderPassLayout ::TargetLoadOp ::Clear ) 307 { 308clearStencil = true; 309 } 310 } 311m_writer -> clearFrame (clearMask ,clearDepth ,clearStencil ); 312 } 313 314virtual SLANG_NO_THROW Result SLANG_MCALL 315bindPipeline (IPipelineState * state ,IShaderObject ** outRootObject )override 316 { 317m_writer -> setPipelineState (state ); 318auto stateImpl = static_cast < PipelineStateBase *> (state ); 319SLANG_RETURN_ON_FAIL (m_commandBuffer -> m_renderer -> createRootShaderObject ( 320stateImpl -> m_program , 321m_commandBuffer -> m_rootShaderObject .writeRef ())); 322* outRootObject = m_commandBuffer -> m_rootShaderObject .Ptr (); 323return SLANG_OK ; 324 } 325 326virtual SLANG_NO_THROW Result SLANG_MCALL 327bindPipelineWithRootObject (IPipelineState * state ,IShaderObject * rootObject )override 328 { 329m_writer -> setPipelineState (state ); 330auto stateImpl = static_cast < PipelineStateBase *> (state ); 331SLANG_RETURN_ON_FAIL (m_commandBuffer -> m_renderer -> createRootShaderObject ( 332stateImpl -> m_program , 333m_commandBuffer -> m_rootShaderObject .writeRef ())); 334m_commandBuffer -> m_rootShaderObject -> copyFrom ( 335rootObject , 336m_commandBuffer -> m_transientHeap ); 337return SLANG_OK ; 338 } 339 340virtual SLANG_NO_THROW void SLANG_MCALL 341setViewports (GfxCount count ,const Viewport * viewports )override 342 { 343m_writer -> setViewports (count ,viewports ); 344 } 345virtual SLANG_NO_THROW void SLANG_MCALL 346setScissorRects (GfxCount count ,const ScissorRect * scissors )override 347 { 348m_writer -> setScissorRects (count ,scissors ); 349 } 350virtual SLANG_NO_THROW void SLANG_MCALL 351setPrimitiveTopology (PrimitiveTopology topology )override 352 { 353m_writer -> setPrimitiveTopology (topology ); 354 } 355virtual SLANG_NO_THROW void SLANG_MCALL setVertexBuffers ( 356GfxIndex startSlot , 357GfxCount slotCount , 358IBufferResource * const * buffers , 359const Offset * offsets )override 360 { 361m_writer -> setVertexBuffers (startSlot ,slotCount ,buffers ,offsets ); 362 } 363 364virtual SLANG_NO_THROW void SLANG_MCALL 365setIndexBuffer (IBufferResource * buffer ,Format indexFormat ,Offset offset )override 366 { 367m_writer -> setIndexBuffer (buffer ,indexFormat ,offset ); 368 } 369 370virtual SLANG_NO_THROW Result SLANG_MCALL 371draw (GfxCount vertexCount ,GfxIndex startVertex )override 372 { 373m_writer -> bindRootShaderObject (m_commandBuffer -> m_rootShaderObject ); 374m_writer -> draw (vertexCount ,startVertex ); 375return SLANG_OK ; 376 } 377 378virtual SLANG_NO_THROW Result SLANG_MCALL 379drawIndexed (GfxCount indexCount ,GfxIndex startIndex ,GfxIndex baseVertex )override 380 { 381m_writer -> bindRootShaderObject (m_commandBuffer -> m_rootShaderObject ); 382m_writer -> drawIndexed (indexCount ,startIndex ,baseVertex ); 383return SLANG_OK ; 384 } 385 386virtual SLANG_NO_THROW void SLANG_MCALL 387setStencilReference (uint32_t referenceValue )override 388 { 389m_writer -> setStencilReference (referenceValue ); 390 } 391 392virtual SLANG_NO_THROW Result SLANG_MCALL drawIndirect ( 393GfxCount maxDrawCount , 394IBufferResource * argBuffer , 395Offset argOffset , 396IBufferResource * countBuffer , 397Offset countOffset )override 398 { 399SLANG_UNUSED (maxDrawCount ); 400SLANG_UNUSED (argBuffer ); 401SLANG_UNUSED (argOffset ); 402SLANG_UNUSED (countBuffer ); 403SLANG_UNUSED (countOffset ); 404SLANG_UNIMPLEMENTED_X ("ImmediateRenderBase::drawIndirect" ); 405return SLANG_OK ; 406 } 407 408virtual SLANG_NO_THROW Result SLANG_MCALL drawIndexedIndirect ( 409GfxCount maxDrawCount , 410IBufferResource * argBuffer , 411Offset argOffset , 412IBufferResource * countBuffer , 413Offset countOffset )override 414 { 415SLANG_UNUSED (maxDrawCount ); 416SLANG_UNUSED (argBuffer ); 417SLANG_UNUSED (argOffset ); 418SLANG_UNUSED (countBuffer ); 419SLANG_UNUSED (countOffset ); 420SLANG_UNIMPLEMENTED_X ("ImmediateRenderBase::drawIndirect" ); 421return SLANG_OK ; 422 } 423 424virtual SLANG_NO_THROW Result SLANG_MCALL drawMeshTasks (int ,int ,int )override 425 { 426SLANG_UNIMPLEMENTED_X ("ImmediateRenderBase::drawMeshTasks" ); 427 } 428 429virtual SLANG_NO_THROW Result SLANG_MCALL setSamplePositions ( 430GfxCount samplesPerPixel , 431GfxCount pixelCount , 432const SamplePosition * samplePositions )override 433 { 434SLANG_UNUSED (samplesPerPixel ); 435SLANG_UNUSED (pixelCount ); 436SLANG_UNUSED (samplePositions ); 437return SLANG_E_NOT_AVAILABLE ; 438 } 439 440virtual SLANG_NO_THROW Result SLANG_MCALL drawInstanced ( 441GfxCount vertexCount , 442GfxCount instanceCount , 443GfxIndex startVertex , 444GfxIndex startInstanceLocation )override 445 { 446m_writer -> bindRootShaderObject (m_commandBuffer -> m_rootShaderObject ); 447m_writer -> drawInstanced (vertexCount ,instanceCount ,startVertex ,startInstanceLocation ); 448return SLANG_OK ; 449 } 450 451virtual SLANG_NO_THROW Result SLANG_MCALL drawIndexedInstanced ( 452GfxCount indexCount , 453GfxCount instanceCount , 454GfxIndex startIndexLocation , 455GfxIndex baseVertexLocation , 456GfxIndex startInstanceLocation )override 457 { 458m_writer -> bindRootShaderObject (m_commandBuffer -> m_rootShaderObject ); 459m_writer -> drawIndexedInstanced ( 460indexCount , 461instanceCount , 462startIndexLocation , 463baseVertexLocation , 464startInstanceLocation ); 465return SLANG_OK ; 466 } 467 }; 468 469RenderCommandEncoderImpl m_renderCommandEncoder ; 470virtual SLANG_NO_THROW void SLANG_MCALL encodeRenderCommands ( 471IRenderPassLayout * renderPass , 472IFramebuffer * framebuffer , 473IRenderCommandEncoder ** outEncoder )override 474 { 475m_renderCommandEncoder .init ( 476this , 477static_cast < SimpleRenderPassLayout *> (renderPass ), 478framebuffer ); 479* outEncoder = & m_renderCommandEncoder ; 480 } 481 482class ComputeCommandEncoderImpl :public IComputeCommandEncoder , 483public ResourceCommandEncoderImpl 484 { 485public : 486SLANG_GFX_FORWARD_RESOURCE_COMMAND_ENCODER_IMPL (ResourceCommandEncoderImpl ) 487virtual void * getInterface (SlangUUID const & uuid )override 488 { 489if (uuid == GfxGUID ::IID_IResourceCommandEncoder || 490uuid == GfxGUID ::IID_IComputeCommandEncoder || uuid == ISlangUnknown ::getTypeGuid ()) 491 { 492return this ; 493 } 494return nullptr ; 495 } 496 497public : 498virtual SLANG_NO_THROW void SLANG_MCALL endEncoding ()override {} 499 500virtual SLANG_NO_THROW Result SLANG_MCALL 501bindPipeline (IPipelineState * state ,IShaderObject ** outRootObject )override 502 { 503m_writer -> setPipelineState (state ); 504auto stateImpl = static_cast < PipelineStateBase *> (state ); 505SLANG_RETURN_ON_FAIL (m_commandBuffer -> m_renderer -> createRootShaderObject ( 506stateImpl -> m_program , 507m_commandBuffer -> m_rootShaderObject .writeRef ())); 508* outRootObject = m_commandBuffer -> m_rootShaderObject .Ptr (); 509return SLANG_OK ; 510 } 511 512virtual SLANG_NO_THROW Result SLANG_MCALL 513bindPipelineWithRootObject (IPipelineState * state ,IShaderObject * rootObject )override 514 { 515m_writer -> setPipelineState (state ); 516auto stateImpl = static_cast < PipelineStateBase *> (state ); 517SLANG_RETURN_ON_FAIL (m_commandBuffer -> m_renderer -> createRootShaderObject ( 518stateImpl -> m_program , 519m_commandBuffer -> m_rootShaderObject .writeRef ())); 520m_commandBuffer -> m_rootShaderObject -> copyFrom ( 521rootObject , 522m_commandBuffer -> m_transientHeap ); 523return SLANG_OK ; 524 } 525 526virtual SLANG_NO_THROW Result SLANG_MCALL dispatchCompute (int x ,int y ,int z )override 527 { 528m_writer -> bindRootShaderObject (m_commandBuffer -> m_rootShaderObject ); 529m_writer -> dispatchCompute (x ,y ,z ); 530return SLANG_OK ; 531 } 532 533virtual SLANG_NO_THROW Result SLANG_MCALL 534dispatchComputeIndirect (IBufferResource * argBuffer ,Offset offset )override 535 { 536SLANG_UNIMPLEMENTED_X ("ImmediateRenderBase::dispatchComputeIndirect" ); 537 } 538 }; 539 540ComputeCommandEncoderImpl m_computeCommandEncoder ; 541virtual SLANG_NO_THROW void SLANG_MCALL 542encodeComputeCommands (IComputeCommandEncoder ** outEncoder )override 543 { 544m_computeCommandEncoder .init (this ); 545* outEncoder = & m_computeCommandEncoder ; 546 } 547 548virtual SLANG_NO_THROW void SLANG_MCALL 549encodeRayTracingCommands (IRayTracingCommandEncoder ** outEncoder )override 550 { 551* outEncoder = nullptr ; 552 } 553 554virtual SLANG_NO_THROW void SLANG_MCALL close ()override {} 555 556virtual SLANG_NO_THROW Result SLANG_MCALL getNativeHandle (InteropHandle * outHandle )override 557 { 558return SLANG_FAIL ; 559 } 560 561void execute () 562 { 563for (auto & cmd :m_writer .m_commands ) 564 { 565auto name = cmd .name ; 566switch (name ) 567 { 568case CommandName ::SetPipelineState : 569m_renderer -> setPipelineState ( 570m_writer .getObject < PipelineStateBase > (cmd .operands [0 ])); 571break ; 572case CommandName ::BindRootShaderObject : 573m_renderer -> bindRootShaderObject ( 574m_writer .getObject < ShaderObjectBase > (cmd .operands [0 ])); 575break ; 576case CommandName ::SetFramebuffer : 577m_renderer -> setFramebuffer (m_writer .getObject < FramebufferBase > (cmd .operands [0 ])); 578break ; 579case CommandName ::ClearFrame : 580m_renderer -> clearFrame ( 581cmd .operands [0 ], 582 (cmd .operands [1 ]!= 0 ), 583 (cmd .operands [2 ]!= 0 )); 584break ; 585case CommandName ::SetViewports : 586m_renderer -> setViewports ( 587 (UInt )cmd .operands [0 ], 588m_writer .getData < Viewport > (cmd .operands [1 ])); 589break ; 590case CommandName ::SetScissorRects : 591m_renderer -> setScissorRects ( 592 (UInt )cmd .operands [0 ], 593m_writer .getData < ScissorRect > (cmd .operands [1 ])); 594break ; 595case CommandName ::SetPrimitiveTopology : 596m_renderer -> setPrimitiveTopology ((PrimitiveTopology )cmd .operands [0 ]); 597break ; 598case CommandName ::SetVertexBuffers : 599 { 600ShortList < IBufferResource *> bufferResources ; 601for (uint32_t i = 0 ;i < cmd .operands [1 ];i ++ ) 602 { 603bufferResources .add ( 604m_writer .getObject < BufferResource > (cmd .operands [2 ]+ i )); 605 } 606m_renderer -> setVertexBuffers ( 607cmd .operands [0 ], 608cmd .operands [1 ], 609bufferResources .getArrayView ().getBuffer (), 610m_writer .getData < Offset > (cmd .operands [3 ])); 611 } 612break ; 613case CommandName ::SetIndexBuffer : 614m_renderer -> setIndexBuffer ( 615m_writer .getObject < BufferResource > (cmd .operands [0 ]), 616 (Format )cmd .operands [1 ], 617 (UInt )cmd .operands [2 ]); 618break ; 619case CommandName ::Draw : 620m_renderer -> draw (cmd .operands [0 ],cmd .operands [1 ]); 621break ; 622case CommandName ::DrawIndexed : 623m_renderer -> drawIndexed (cmd .operands [0 ],cmd .operands [1 ],cmd .operands [2 ]); 624break ; 625case CommandName ::DrawInstanced : 626m_renderer -> drawInstanced ( 627cmd .operands [0 ], 628cmd .operands [1 ], 629cmd .operands [2 ], 630cmd .operands [3 ]); 631break ; 632case CommandName ::DrawIndexedInstanced : 633m_renderer -> drawIndexedInstanced ( 634cmd .operands [0 ], 635cmd .operands [1 ], 636cmd .operands [2 ], 637cmd .operands [3 ], 638cmd .operands [4 ]); 639break ; 640case CommandName ::SetStencilReference : 641m_renderer -> setStencilReference (cmd .operands [0 ]); 642break ; 643case CommandName ::DispatchCompute : 644m_renderer -> dispatchCompute ( 645int (cmd .operands [0 ]), 646int (cmd .operands [1 ]), 647int (cmd .operands [2 ])); 648break ; 649case CommandName ::UploadBufferData : 650m_renderer -> uploadBufferData ( 651m_writer .getObject < BufferResource > (cmd .operands [0 ]), 652cmd .operands [1 ], 653cmd .operands [2 ], 654m_writer .getData < uint8_t > (cmd .operands [3 ])); 655break ; 656case CommandName ::CopyBuffer : 657m_renderer -> copyBuffer ( 658m_writer .getObject < BufferResource > (cmd .operands [0 ]), 659cmd .operands [1 ], 660m_writer .getObject < BufferResource > (cmd .operands [2 ]), 661cmd .operands [3 ], 662cmd .operands [4 ]); 663break ; 664case CommandName ::WriteTimestamp : 665m_renderer -> writeTimestamp ( 666m_writer .getObject < QueryPoolBase > (cmd .operands [0 ]), 667 (GfxIndex )cmd .operands [1 ]); 668break ; 669default : 670assert (!"unknown command" ); 671break ; 672 } 673 } 674m_writer .clear (); 675 } 676}; 677 678class CommandQueueImpl :public ImmediateCommandQueueBase 679{ 680public : 681ICommandQueue ::Desc m_desc ; 682 683ImmediateRendererBase * getRenderer () 684 { 685return static_cast < ImmediateRendererBase *> (m_renderer .get ()); 686 } 687 688CommandQueueImpl (ImmediateRendererBase * renderer ) 689 { 690// Don't establish strong reference to `Device` at start, because 691// there will be only one instance of command queue and it will be 692// owned by `Device`. We should establish a strong reference only 693// when there are external references to the command queue. 694m_renderer .setWeakReference (renderer ); 695m_desc .type = ICommandQueue ::QueueType ::Graphics ; 696 } 697 698 ~CommandQueueImpl () {getRenderer ()-> m_queueCreateCount -- ; } 699 700virtual SLANG_NO_THROW const Desc & SLANG_MCALL getDesc ()override {return m_desc ; } 701 702virtual SLANG_NO_THROW void SLANG_MCALL executeCommandBuffers ( 703GfxCount count , 704ICommandBuffer * const * commandBuffers , 705IFence * fence , 706uint64_t valueToSignal )override 707 { 708// TODO: implement fence signal. 709assert (fence == nullptr ); 710 711CommandBufferInfo info = {}; 712for (GfxIndex i = 0 ;i < count ;i ++ ) 713 { 714info .hasWriteTimestamps |= 715static_cast < CommandBufferImpl *> (commandBuffers [i ])-> m_writer .m_hasWriteTimestamps ; 716 } 717static_cast < ImmediateRendererBase *> (m_renderer .get ())-> beginCommandBuffer (info ); 718for (GfxIndex i = 0 ;i < count ;i ++ ) 719 { 720static_cast < CommandBufferImpl *> (commandBuffers [i ])-> execute (); 721 } 722static_cast < ImmediateRendererBase *> (m_renderer .get ())-> endCommandBuffer (info ); 723 } 724 725virtual SLANG_NO_THROW void SLANG_MCALL waitOnHost ()override {getRenderer ()-> waitForGpu (); } 726 727virtual SLANG_NO_THROW Result SLANG_MCALL 728waitForFenceValuesOnDevice (GfxCount fenceCount ,IFence ** fences ,uint64_t * waitValues )override 729 { 730return SLANG_FAIL ; 731 } 732 733virtual SLANG_NO_THROW Result SLANG_MCALL getNativeHandle (InteropHandle * outHandle )override 734 { 735return getRenderer ()-> m_queue -> getNativeHandle (outHandle ); 736 } 737}; 738 739using TransientResourceHeapImpl = 740SimpleTransientResourceHeap < ImmediateRendererBase ,CommandBufferImpl > ; 741 742}// namespace 743 744ImmediateRendererBase ::ImmediateRendererBase () 745{ 746m_queue = new CommandQueueImpl (this ); 747} 748 749SLANG_NO_THROW Result SLANG_MCALL ImmediateRendererBase ::createTransientResourceHeap ( 750const ITransientResourceHeap ::Desc & desc , 751ITransientResourceHeap ** outHeap ) 752{ 753RefPtr < TransientResourceHeapImpl > result = new TransientResourceHeapImpl (); 754SLANG_RETURN_ON_FAIL (result -> init (this ,desc )); 755returnComPtr (outHeap ,result ); 756return SLANG_OK ; 757} 758 759SLANG_NO_THROW Result SLANG_MCALL 760ImmediateRendererBase ::createCommandQueue (const ICommandQueue ::Desc & desc ,ICommandQueue ** outQueue ) 761{ 762SLANG_UNUSED (desc ); 763// Only one queue is supported. 764if (m_queueCreateCount != 0 ) 765return SLANG_FAIL ; 766m_queue -> establishStrongReferenceToDevice (); 767returnComPtr (outQueue ,m_queue ); 768return SLANG_OK ; 769} 770 771SLANG_NO_THROW Result SLANG_MCALL ImmediateRendererBase ::createRenderPassLayout ( 772const IRenderPassLayout ::Desc & desc , 773IRenderPassLayout ** outRenderPassLayout ) 774{ 775RefPtr < SimpleRenderPassLayout > renderPass = new SimpleRenderPassLayout (); 776renderPass -> init (desc ); 777returnComPtr (outRenderPassLayout ,renderPass ); 778return SLANG_OK ; 779} 780 781void ImmediateRendererBase ::uploadBufferData ( 782IBufferResource * dst , 783size_t offset , 784size_t size , 785void * data ) 786{ 787auto buffer = map (dst , gfx::MapFlavor ::WriteDiscard ); 788memcpy ((uint8_t * )buffer + offset ,data ,size ); 789unmap (dst ,offset ,size ); 790} 791 792SLANG_NO_THROW SlangResult SLANG_MCALL ImmediateRendererBase ::readBufferResource ( 793IBufferResource * buffer , 794size_t offset , 795size_t size , 796ISlangBlob ** outBlob ) 797{ 798List < uint8_t > blobData ; 799 800blobData .setCount ((Index )size ); 801auto content = (uint8_t * )map (buffer , gfx::MapFlavor ::HostRead ); 802if (!content ) 803return SLANG_FAIL ; 804memcpy (blobData .getBuffer (),content + offset ,size ); 805unmap (buffer ,offset ,size ); 806 807auto blob = ListBlob ::moveCreate (blobData ); 808 809returnComPtr (outBlob ,blob ); 810return SLANG_OK ; 811} 812 813}// namespace gfx