yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
b118451e3
master
1// d3d12-command-encoder.cpp 2#include "d3d12-command-encoder.h" 3 4#include "d3d12-command-buffer.h" 5#include "d3d12-device.h" 6#include "d3d12-helper-functions.h" 7#include "d3d12-pipeline-state.h" 8#include "d3d12-query.h" 9#include "d3d12-shader-object.h" 10#include "d3d12-shader-program.h" 11#include "d3d12-shader-table.h" 12#include "d3d12-texture.h" 13#include "d3d12-transient-heap.h" 14#include "d3d12-vertex-layout.h" 15 16namespace gfx 17{ 18namespace d3d12 19{ 20 21using namespace Slang ; 22 23int PipelineCommandEncoder ::getBindPointIndex (PipelineType type ) 24{ 25switch (type ) 26 { 27case PipelineType ::Graphics : 28return 0 ; 29case PipelineType ::Compute : 30return 1 ; 31case PipelineType ::RayTracing : 32return 2 ; 33default : 34assert (!"unknown pipeline type." ); 35return -1 ; 36 } 37} 38 39void PipelineCommandEncoder ::init (CommandBufferImpl * commandBuffer ) 40{ 41m_commandBuffer = commandBuffer ; 42m_d3dCmdList = m_commandBuffer -> m_cmdList ; 43m_d3dCmdList6 = m_commandBuffer -> m_cmdList6 ; 44m_renderer = commandBuffer -> m_renderer ; 45m_transientHeap = commandBuffer -> m_transientHeap ; 46m_device = commandBuffer -> m_renderer -> m_device ; 47} 48 49Result PipelineCommandEncoder ::bindPipelineImpl ( 50IPipelineState * pipelineState , 51IShaderObject ** outRootObject ) 52{ 53m_currentPipeline = static_cast < PipelineStateBase *> (pipelineState ); 54auto rootObject = & m_commandBuffer -> m_rootShaderObject ; 55m_commandBuffer -> m_mutableRootShaderObject = nullptr ; 56SLANG_RETURN_ON_FAIL (rootObject -> reset ( 57m_renderer , 58m_currentPipeline -> getProgram < ShaderProgramImpl > ()-> m_rootObjectLayout , 59m_commandBuffer -> m_transientHeap )); 60* outRootObject = rootObject ; 61m_bindingDirty = true; 62return SLANG_OK ; 63} 64 65Result PipelineCommandEncoder ::bindPipelineWithRootObjectImpl ( 66IPipelineState * pipelineState , 67IShaderObject * rootObject ) 68{ 69m_currentPipeline = static_cast < PipelineStateBase *> (pipelineState ); 70m_commandBuffer -> m_mutableRootShaderObject = 71static_cast < MutableRootShaderObjectImpl *> (rootObject ); 72m_bindingDirty = true; 73return SLANG_OK ; 74} 75 76Result PipelineCommandEncoder ::_bindRenderState ( 77Submitter * submitter , 78RefPtr < PipelineStateBase >& newPipeline ) 79{ 80RootShaderObjectImpl * rootObjectImpl = m_commandBuffer -> m_mutableRootShaderObject 81 ?m_commandBuffer -> m_mutableRootShaderObject .Ptr () 82 :& m_commandBuffer -> m_rootShaderObject ; 83SLANG_RETURN_ON_FAIL ( 84m_renderer -> maybeSpecializePipeline (m_currentPipeline ,rootObjectImpl ,newPipeline )); 85PipelineStateBase * newPipelineImpl = static_cast < PipelineStateBase *> (newPipeline .Ptr ()); 86auto commandList = m_d3dCmdList ; 87auto pipelineTypeIndex = (int )newPipelineImpl -> desc .type ; 88auto programImpl = static_cast < ShaderProgramImpl *> (newPipelineImpl -> m_program .Ptr ()); 89SLANG_RETURN_ON_FAIL (newPipelineImpl -> ensureAPIPipelineStateCreated ()); 90submitter -> setRootSignature (programImpl -> m_rootObjectLayout -> m_rootSignature ); 91submitter -> setPipelineState (newPipelineImpl ); 92RootShaderObjectLayoutImpl * rootLayoutImpl = programImpl -> m_rootObjectLayout ; 93 94// We need to set up a context for binding shader objects to the pipeline state. 95// This type mostly exists to bundle together a bunch of parameters that would 96// otherwise need to be tunneled down through all the shader object binding 97// logic. 98// 99BindingContext context = {}; 100context .encoder = this ; 101context .submitter = submitter ; 102context .device = m_renderer ; 103context .transientHeap = m_transientHeap ; 104context .outOfMemoryHeap = (D3D12_DESCRIPTOR_HEAP_TYPE )(-1 ); 105// We kick off binding of shader objects at the root object, and the objects 106// themselves will be responsible for allocating, binding, and filling in 107// any descriptor tables or other root parameters needed. 108// 109m_commandBuffer -> bindDescriptorHeaps (); 110if (rootObjectImpl -> bindAsRoot (& context ,rootLayoutImpl )== SLANG_E_OUT_OF_MEMORY ) 111 { 112if (!m_transientHeap -> canResize ()) 113 { 114return SLANG_E_OUT_OF_MEMORY ; 115 } 116 117// If we run out of heap space while binding, allocate new descriptor heaps and try again. 118ID3D12DescriptorHeap * d3dheap = nullptr ; 119m_commandBuffer -> invalidateDescriptorHeapBinding (); 120switch (context .outOfMemoryHeap ) 121 { 122case D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV : 123SLANG_RETURN_ON_FAIL (m_transientHeap -> allocateNewViewDescriptorHeap (m_renderer )); 124d3dheap = m_transientHeap -> getCurrentViewHeap ().getHeap (); 125m_commandBuffer -> bindDescriptorHeaps (); 126break ; 127case D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER : 128SLANG_RETURN_ON_FAIL (m_transientHeap -> allocateNewSamplerDescriptorHeap (m_renderer )); 129d3dheap = m_transientHeap -> getCurrentSamplerHeap ().getHeap (); 130m_commandBuffer -> bindDescriptorHeaps (); 131break ; 132default : 133assert (!"shouldn't be here" ); 134return SLANG_FAIL ; 135 } 136 137// Try again. 138SLANG_RETURN_ON_FAIL (rootObjectImpl -> bindAsRoot (& context ,rootLayoutImpl )); 139 } 140 141return SLANG_OK ; 142} 143 144void ResourceCommandEncoderImpl ::bufferBarrier ( 145GfxCount count , 146IBufferResource * const * buffers , 147ResourceState src , 148ResourceState dst ) 149{ 150ShortList < D3D12_RESOURCE_BARRIER ,16 > barriers ; 151for (GfxIndex i = 0 ;i < count ;i ++ ) 152 { 153auto bufferImpl = static_cast < BufferResourceImpl *> (buffers [i ]); 154 155D3D12_RESOURCE_BARRIER barrier = {}; 156// If the src == dst, it must be a UAV barrier. 157barrier .Type = (src == dst && dst == ResourceState ::UnorderedAccess ) 158 ?D3D12_RESOURCE_BARRIER_TYPE_UAV 159 :D3D12_RESOURCE_BARRIER_TYPE_TRANSITION ; 160barrier .Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE ; 161 162if (barrier .Type == D3D12_RESOURCE_BARRIER_TYPE_UAV ) 163 { 164barrier .UAV .pResource = bufferImpl -> m_resource ; 165 } 166else 167 { 168barrier .Transition .pResource = bufferImpl -> m_resource ; 169barrier .Transition .StateBefore = D3DUtil ::getResourceState (src ); 170barrier .Transition .StateAfter = D3DUtil ::getResourceState (dst ); 171barrier .Transition .Subresource = 0 ; 172if (barrier .Transition .StateAfter == barrier .Transition .StateBefore ) 173continue ; 174 } 175barriers .add (barrier ); 176 } 177if (barriers .getCount ()) 178 { 179m_commandBuffer -> m_cmdList4 -> ResourceBarrier ( 180 (UINT )barriers .getCount (), 181barriers .getArrayView ().getBuffer ()); 182 } 183} 184 185void ResourceCommandEncoderImpl ::writeTimestamp (IQueryPool * pool ,GfxIndex index ) 186{ 187static_cast < QueryPoolImpl *> (pool )-> writeTimestamp (m_commandBuffer -> m_cmdList ,index ); 188} 189 190void ResourceCommandEncoderImpl ::copyTexture ( 191ITextureResource * dst , 192ResourceState dstState , 193SubresourceRange dstSubresource , 194ITextureResource ::Offset3D dstOffset , 195ITextureResource * src , 196ResourceState srcState , 197SubresourceRange srcSubresource , 198ITextureResource ::Offset3D srcOffset , 199ITextureResource ::Extents extent ) 200{ 201auto dstTexture = static_cast < TextureResourceImpl *> (dst ); 202auto srcTexture = static_cast < TextureResourceImpl *> (src ); 203 204if (dstSubresource .layerCount == 0 && dstSubresource .mipLevelCount == 0 && 205srcSubresource .layerCount == 0 && srcSubresource .mipLevelCount == 0 ) 206 { 207m_commandBuffer -> m_cmdList -> CopyResource ( 208dstTexture -> m_resource .getResource (), 209srcTexture -> m_resource .getResource ()); 210return ; 211 } 212 213auto d3dFormat = D3DUtil ::getMapFormat (dstTexture -> getDesc ()-> format ); 214auto aspectMask = (int32_t )dstSubresource .aspectMask ; 215if (dstSubresource .aspectMask == TextureAspect ::Default ) 216aspectMask = (int32_t )TextureAspect ::Color ; 217while (aspectMask ) 218 { 219auto aspect = Math ::getLowestBit ((int32_t )aspectMask ); 220aspectMask &= ~aspect ; 221auto planeIndex = D3DUtil ::getPlaneSlice (d3dFormat , (TextureAspect )aspect ); 222for (GfxIndex layer = 0 ;layer < dstSubresource .layerCount ;layer ++ ) 223 { 224for (GfxIndex mipLevel = 0 ;mipLevel < dstSubresource .mipLevelCount ;mipLevel ++ ) 225 { 226D3D12_TEXTURE_COPY_LOCATION dstRegion = {}; 227 228dstRegion .Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX ; 229dstRegion .pResource = dstTexture -> m_resource .getResource (); 230dstRegion .SubresourceIndex = D3DUtil ::getSubresourceIndex ( 231dstSubresource .mipLevel + mipLevel , 232dstSubresource .baseArrayLayer + layer , 233planeIndex , 234dstTexture -> getDesc ()-> numMipLevels , 235dstTexture -> getDesc ()-> arraySize ); 236 237D3D12_TEXTURE_COPY_LOCATION srcRegion = {}; 238srcRegion .Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX ; 239srcRegion .pResource = srcTexture -> m_resource .getResource (); 240srcRegion .SubresourceIndex = D3DUtil ::getSubresourceIndex ( 241srcSubresource .mipLevel + mipLevel , 242srcSubresource .baseArrayLayer + layer , 243planeIndex , 244srcTexture -> getDesc ()-> numMipLevels , 245srcTexture -> getDesc ()-> arraySize ); 246 247D3D12_BOX srcBox = {}; 248srcBox .left = srcOffset .x ; 249srcBox .top = srcOffset .y ; 250srcBox .front = srcOffset .z ; 251srcBox .right = srcBox .left + extent .width ; 252srcBox .bottom = srcBox .top + extent .height ; 253srcBox .back = srcBox .front + extent .depth ; 254 255m_commandBuffer -> m_cmdList -> CopyTextureRegion ( 256& dstRegion , 257dstOffset .x , 258dstOffset .y , 259dstOffset .z , 260& srcRegion , 261& srcBox ); 262 } 263 } 264 } 265} 266 267void ResourceCommandEncoderImpl ::uploadTextureData ( 268ITextureResource * dst , 269SubresourceRange subResourceRange , 270ITextureResource ::Offset3D offset , 271ITextureResource ::Extents extent , 272ITextureResource ::SubresourceData * subResourceData , 273GfxCount subResourceDataCount ) 274{ 275auto dstTexture = static_cast < TextureResourceImpl *> (dst ); 276auto baseSubresourceIndex = D3DUtil ::getSubresourceIndex ( 277subResourceRange .mipLevel , 278subResourceRange .baseArrayLayer , 2790 , 280dstTexture -> getDesc ()-> numMipLevels , 281dstTexture -> getDesc ()-> arraySize ); 282auto textureSize = dstTexture -> getDesc ()-> size ; 283FormatInfo formatInfo = {}; 284gfxGetFormatInfo (dstTexture -> getDesc ()-> format ,& formatInfo ); 285for (GfxCount i = 0 ;i < subResourceDataCount ;i ++ ) 286 { 287auto subresourceIndex = baseSubresourceIndex + i ; 288// Get the footprint 289D3D12_RESOURCE_DESC texDesc = dstTexture -> m_resource .getResource ()-> GetDesc (); 290 291D3D12_TEXTURE_COPY_LOCATION dstRegion = {}; 292 293dstRegion .Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX ; 294dstRegion .SubresourceIndex = subresourceIndex ; 295dstRegion .pResource = dstTexture -> m_resource .getResource (); 296 297D3D12_TEXTURE_COPY_LOCATION srcRegion = {}; 298srcRegion .Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT ; 299D3D12_PLACED_SUBRESOURCE_FOOTPRINT & footprint = srcRegion .PlacedFootprint ; 300footprint .Offset = 0 ; 301footprint .Footprint .Format = texDesc .Format ; 302uint32_t mipLevel = 303D3DUtil ::getSubresourceMipLevel (subresourceIndex ,dstTexture -> getDesc ()-> numMipLevels ); 304if (extent .width != ITextureResource ::kRemainingTextureSize ) 305 { 306footprint .Footprint .Width = extent .width ; 307 } 308else 309 { 310footprint .Footprint .Width = Math ::Max (1 , (textureSize .width >>mipLevel ))- offset .x ; 311 } 312if (extent .height != ITextureResource ::kRemainingTextureSize ) 313 { 314footprint .Footprint .Height = extent .height ; 315 } 316else 317 { 318footprint .Footprint .Height = Math ::Max (1 , (textureSize .height >>mipLevel ))- offset .y ; 319 } 320if (extent .depth != ITextureResource ::kRemainingTextureSize ) 321 { 322footprint .Footprint .Depth = extent .depth ; 323 } 324else 325 { 326footprint .Footprint .Depth = Math ::Max (1 , (textureSize .depth >>mipLevel ))- offset .z ; 327 } 328auto rowSize = (footprint .Footprint .Width + formatInfo .blockWidth - 1 ) / 329formatInfo .blockWidth * formatInfo .blockSizeInBytes ; 330auto rowCount = 331 (footprint .Footprint .Height + formatInfo .blockHeight - 1 ) /formatInfo .blockHeight ; 332footprint .Footprint .RowPitch = 333 (UINT )D3DUtil ::calcAligned (rowSize , (uint32_t )D3D12_TEXTURE_DATA_PITCH_ALIGNMENT ); 334 335auto bufferSize = footprint .Footprint .RowPitch * rowCount * footprint .Footprint .Depth ; 336 337IBufferResource * stagingBuffer ; 338Offset stagingBufferOffset = 0 ; 339m_commandBuffer -> m_transientHeap -> allocateStagingBuffer ( 340bufferSize , 341stagingBuffer , 342stagingBufferOffset , 343MemoryType ::Upload , 344 true); 345assert (stagingBufferOffset == 0 ); 346BufferResourceImpl * bufferImpl = static_cast < BufferResourceImpl *> (stagingBuffer ); 347uint8_t * bufferData = nullptr ; 348D3D12_RANGE mapRange = {0 ,0 }; 349bufferImpl -> m_resource .getResource ()-> Map (0 ,& mapRange , (void ** )& bufferData ); 350for (uint32_t z = 0 ;z < footprint .Footprint .Depth ;z ++ ) 351 { 352auto imageStart = bufferData + footprint .Footprint .RowPitch * rowCount * (Size )z ; 353auto srcData = (uint8_t * )subResourceData -> data + subResourceData -> strideZ * z ; 354for (uint32_t row = 0 ;row < rowCount ;row ++ ) 355 { 356memcpy ( 357imageStart + row * (Size )footprint .Footprint .RowPitch , 358srcData + subResourceData -> strideY * row , 359rowSize ); 360 } 361 } 362bufferImpl -> m_resource .getResource ()-> Unmap (0 ,nullptr ); 363srcRegion .pResource = bufferImpl -> m_resource .getResource (); 364m_commandBuffer -> m_cmdList 365-> CopyTextureRegion (& dstRegion ,offset .x ,offset .y ,offset .z ,& srcRegion ,nullptr ); 366 } 367} 368 369void ResourceCommandEncoderImpl ::clearResourceView ( 370IResourceView * view , 371ClearValue * clearValue , 372ClearResourceViewFlags ::Enum flags ) 373{ 374auto viewImpl = static_cast < ResourceViewImpl *> (view ); 375m_commandBuffer -> bindDescriptorHeaps (); 376switch (view -> getViewDesc ()-> type ) 377 { 378case IResourceView ::Type ::RenderTarget : 379m_commandBuffer -> m_cmdList -> ClearRenderTargetView ( 380viewImpl -> m_descriptor .cpuHandle , 381clearValue -> color .floatValues , 3820 , 383nullptr ); 384break ; 385case IResourceView ::Type ::DepthStencil : 386 { 387D3D12_CLEAR_FLAGS clearFlags = (D3D12_CLEAR_FLAGS )0 ; 388if (flags & ClearResourceViewFlags ::ClearDepth ) 389 { 390clearFlags |=D3D12_CLEAR_FLAG_DEPTH ; 391 } 392if (flags & ClearResourceViewFlags ::ClearStencil ) 393 { 394clearFlags |=D3D12_CLEAR_FLAG_STENCIL ; 395 } 396m_commandBuffer -> m_cmdList -> ClearDepthStencilView ( 397viewImpl -> m_descriptor .cpuHandle , 398clearFlags , 399clearValue -> depthStencil .depth , 400 (UINT8 )clearValue -> depthStencil .stencil , 4010 , 402nullptr ); 403break ; 404 } 405case IResourceView ::Type ::UnorderedAccess : 406 { 407ID3D12Resource * d3dResource = nullptr ; 408D3D12Descriptor descriptor = viewImpl -> m_descriptor ; 409switch (viewImpl -> m_resource -> getType ()) 410 { 411case IResource ::Type ::Buffer : 412d3dResource = static_cast < BufferResourceImpl *> (viewImpl -> m_resource .Ptr ()) 413-> m_resource .getResource (); 414// D3D12 requires a UAV descriptor with zero buffer stride for calling 415// ClearUnorderedAccessViewUint/Float. 416viewImpl -> getBufferDescriptorForBinding ( 417m_commandBuffer -> m_renderer , 418viewImpl , 4190 , 420descriptor ); 421break ; 422default : 423d3dResource = static_cast < TextureResourceImpl *> (viewImpl -> m_resource .Ptr ()) 424-> m_resource .getResource (); 425break ; 426 } 427auto gpuHandleIndex = 428m_commandBuffer -> m_transientHeap -> getCurrentViewHeap ().allocate (1 ); 429if (gpuHandleIndex == -1 ) 430 { 431m_commandBuffer -> m_transientHeap -> allocateNewViewDescriptorHeap ( 432m_commandBuffer -> m_renderer ); 433gpuHandleIndex = m_commandBuffer -> m_transientHeap -> getCurrentViewHeap ().allocate (1 ); 434m_commandBuffer -> bindDescriptorHeaps (); 435 } 436this -> m_commandBuffer -> m_renderer -> m_device -> CopyDescriptorsSimple ( 4371 , 438m_commandBuffer -> m_transientHeap -> getCurrentViewHeap ().getCpuHandle (gpuHandleIndex ), 439descriptor .cpuHandle , 440D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV ); 441 442if (flags & ClearResourceViewFlags ::FloatClearValues ) 443 { 444m_commandBuffer -> m_cmdList -> ClearUnorderedAccessViewFloat ( 445m_commandBuffer -> m_transientHeap -> getCurrentViewHeap ().getGpuHandle ( 446gpuHandleIndex ), 447descriptor .cpuHandle , 448d3dResource , 449clearValue -> color .floatValues , 4500 , 451nullptr ); 452 } 453else 454 { 455m_commandBuffer -> m_cmdList -> ClearUnorderedAccessViewUint ( 456m_commandBuffer -> m_transientHeap -> getCurrentViewHeap ().getGpuHandle ( 457gpuHandleIndex ), 458descriptor .cpuHandle , 459d3dResource , 460clearValue -> color .uintValues , 4610 , 462nullptr ); 463 } 464break ; 465 } 466default : 467break ; 468 } 469} 470 471void ResourceCommandEncoderImpl ::resolveResource ( 472ITextureResource * source , 473ResourceState sourceState , 474SubresourceRange sourceRange , 475ITextureResource * dest , 476ResourceState destState , 477SubresourceRange destRange ) 478{ 479auto srcTexture = static_cast < TextureResourceImpl *> (source ); 480auto srcDesc = srcTexture -> getDesc (); 481auto dstTexture = static_cast < TextureResourceImpl *> (dest ); 482auto dstDesc = dstTexture -> getDesc (); 483 484for (GfxIndex layer = 0 ;layer < sourceRange .layerCount ;++ layer ) 485 { 486for (GfxIndex mip = 0 ;mip < sourceRange .mipLevelCount ;++ mip ) 487 { 488auto srcSubresourceIndex = D3DUtil ::getSubresourceIndex ( 489mip + sourceRange .mipLevel , 490layer + sourceRange .baseArrayLayer , 4910 , 492srcDesc -> numMipLevels , 493srcDesc -> arraySize ); 494auto dstSubresourceIndex = D3DUtil ::getSubresourceIndex ( 495mip + destRange .mipLevel , 496layer + destRange .baseArrayLayer , 4970 , 498dstDesc -> numMipLevels , 499dstDesc -> arraySize ); 500 501DXGI_FORMAT format = D3DUtil ::getMapFormat (srcDesc -> format ); 502 503m_commandBuffer -> m_cmdList -> ResolveSubresource ( 504dstTexture -> m_resource .getResource (), 505dstSubresourceIndex , 506srcTexture -> m_resource .getResource (), 507srcSubresourceIndex , 508format ); 509 } 510 } 511} 512 513void ResourceCommandEncoderImpl ::resolveQuery ( 514IQueryPool * queryPool , 515GfxIndex index , 516GfxCount count , 517IBufferResource * buffer , 518Offset offset ) 519{ 520auto queryBase = static_cast < QueryPoolBase *> (queryPool ); 521switch (queryBase -> m_desc .type ) 522 { 523case QueryType ::AccelerationStructureCompactedSize : 524case QueryType ::AccelerationStructureCurrentSize : 525case QueryType ::AccelerationStructureSerializedSize : 526 { 527auto queryPoolImpl = static_cast < PlainBufferProxyQueryPoolImpl *> (queryPool ); 528auto bufferImpl = static_cast < BufferResourceImpl *> (buffer ); 529auto srcQueryBuffer = queryPoolImpl -> m_bufferResource -> m_resource .getResource (); 530 531D3D12_RESOURCE_BARRIER barrier = {}; 532barrier .Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION ; 533barrier .Transition .StateBefore = D3D12_RESOURCE_STATE_UNORDERED_ACCESS ; 534barrier .Transition .StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE ; 535barrier .Transition .pResource = srcQueryBuffer ; 536m_commandBuffer -> m_cmdList -> ResourceBarrier (1 ,& barrier ); 537 538m_commandBuffer -> m_cmdList -> CopyBufferRegion ( 539bufferImpl -> m_resource .getResource (), 540 (uint64_t )offset , 541srcQueryBuffer , 542index * sizeof (uint64_t ), 543count * sizeof (uint64_t )); 544 545barrier .Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION ; 546barrier .Transition .StateBefore = D3D12_RESOURCE_STATE_COPY_SOURCE ; 547barrier .Transition .StateAfter = D3D12_RESOURCE_STATE_UNORDERED_ACCESS ; 548barrier .Transition .pResource = srcQueryBuffer ; 549m_commandBuffer -> m_cmdList -> ResourceBarrier (1 ,& barrier ); 550 } 551break ; 552default : 553 { 554auto queryPoolImpl = static_cast < QueryPoolImpl *> (queryPool ); 555auto bufferImpl = static_cast < BufferResourceImpl *> (buffer ); 556m_commandBuffer -> m_cmdList -> ResolveQueryData ( 557queryPoolImpl -> m_queryHeap .get (), 558queryPoolImpl -> m_queryType , 559index , 560count , 561bufferImpl -> m_resource .getResource (), 562offset ); 563 } 564break ; 565 } 566} 567 568void ResourceCommandEncoderImpl ::copyTextureToBuffer ( 569IBufferResource * dst , 570Offset dstOffset , 571Size dstSize , 572Size dstRowStride , 573ITextureResource * src , 574ResourceState srcState , 575SubresourceRange srcSubresource , 576ITextureResource ::Offset3D srcOffset , 577ITextureResource ::Extents extent ) 578{ 579assert (srcSubresource .mipLevelCount <=1 ); 580 581auto srcTexture = static_cast < TextureResourceImpl *> (src ); 582auto dstBuffer = static_cast < BufferResourceImpl *> (dst ); 583auto baseSubresourceIndex = D3DUtil ::getSubresourceIndex ( 584srcSubresource .mipLevel , 585srcSubresource .baseArrayLayer , 5860 , 587srcTexture -> getDesc ()-> numMipLevels , 588srcTexture -> getDesc ()-> arraySize ); 589auto textureSize = srcTexture -> getDesc ()-> size ; 590FormatInfo formatInfo = {}; 591gfxGetFormatInfo (srcTexture -> getDesc ()-> format ,& formatInfo ); 592if (srcSubresource .mipLevelCount == 0 ) 593srcSubresource .mipLevelCount = srcTexture -> getDesc ()-> numMipLevels ; 594if (srcSubresource .layerCount == 0 ) 595srcSubresource .layerCount = srcTexture -> getDesc ()-> arraySize ; 596 597for (GfxCount layer = 0 ;layer < srcSubresource .layerCount ;layer ++ ) 598 { 599// Get the footprint 600D3D12_RESOURCE_DESC texDesc = srcTexture -> m_resource .getResource ()-> GetDesc (); 601 602D3D12_TEXTURE_COPY_LOCATION dstRegion = {}; 603dstRegion .Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT ; 604dstRegion .pResource = dstBuffer -> m_resource .getResource (); 605D3D12_PLACED_SUBRESOURCE_FOOTPRINT & footprint = dstRegion .PlacedFootprint ; 606 607D3D12_TEXTURE_COPY_LOCATION srcRegion = {}; 608srcRegion .Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX ; 609srcRegion .SubresourceIndex = D3DUtil ::getSubresourceIndex ( 610srcSubresource .mipLevel , 611layer + srcSubresource .baseArrayLayer , 6120 , 613srcTexture -> getDesc ()-> numMipLevels , 614srcTexture -> getDesc ()-> arraySize ); 615srcRegion .pResource = srcTexture -> m_resource .getResource (); 616 617footprint .Offset = dstOffset ; 618footprint .Footprint .Format = texDesc .Format ; 619uint32_t mipLevel = srcSubresource .mipLevel ; 620if (extent .width != 0xFFFFFFFF ) 621 { 622footprint .Footprint .Width = extent .width ; 623 } 624else 625 { 626footprint .Footprint .Width = Math ::Max (1 , (textureSize .width >>mipLevel ))- srcOffset .x ; 627 } 628if (extent .height != 0xFFFFFFFF ) 629 { 630footprint .Footprint .Height = extent .height ; 631 } 632else 633 { 634footprint .Footprint .Height = 635Math ::Max (1 , (textureSize .height >>mipLevel ))- srcOffset .y ; 636 } 637if (extent .depth != 0xFFFFFFFF ) 638 { 639footprint .Footprint .Depth = extent .depth ; 640 } 641else 642 { 643footprint .Footprint .Depth = Math ::Max (1 , (textureSize .depth >>mipLevel ))- srcOffset .z ; 644 } 645 646assert (dstRowStride %D3D12_TEXTURE_DATA_PITCH_ALIGNMENT == 0 ); 647footprint .Footprint .RowPitch = (UINT )dstRowStride ; 648 649auto bufferSize = 650footprint .Footprint .RowPitch * footprint .Footprint .Height * footprint .Footprint .Depth ; 651 652D3D12_BOX srcBox = {}; 653srcBox .left = srcOffset .x ; 654srcBox .top = srcOffset .y ; 655srcBox .front = srcOffset .z ; 656srcBox .right = srcOffset .x + extent .width ; 657srcBox .bottom = srcOffset .y + extent .height ; 658srcBox .back = srcOffset .z + extent .depth ; 659m_commandBuffer -> m_cmdList -> CopyTextureRegion (& dstRegion ,0 ,0 ,0 ,& srcRegion ,& srcBox ); 660 } 661} 662 663void ResourceCommandEncoderImpl ::textureSubresourceBarrier ( 664ITextureResource * texture , 665SubresourceRange subresourceRange , 666ResourceState src , 667ResourceState dst ) 668{ 669auto textureImpl = static_cast < TextureResourceImpl *> (texture ); 670 671ShortList < D3D12_RESOURCE_BARRIER > barriers ; 672D3D12_RESOURCE_BARRIER barrier ; 673barrier .Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE ; 674if (src == dst && src == ResourceState ::UnorderedAccess ) 675 { 676barrier .Type = D3D12_RESOURCE_BARRIER_TYPE_UAV ; 677barrier .UAV .pResource = textureImpl -> m_resource .getResource (); 678barriers .add (barrier ); 679 } 680else 681 { 682barrier .Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION ; 683barrier .Transition .StateBefore = D3DUtil ::getResourceState (src ); 684barrier .Transition .StateAfter = D3DUtil ::getResourceState (dst ); 685if (barrier .Transition .StateBefore == barrier .Transition .StateAfter ) 686return ; 687barrier .Transition .pResource = textureImpl -> m_resource .getResource (); 688auto d3dFormat = D3DUtil ::getMapFormat (textureImpl -> getDesc ()-> format ); 689auto aspectMask = (int32_t )subresourceRange .aspectMask ; 690if (subresourceRange .aspectMask == TextureAspect ::Default ) 691aspectMask = (int32_t )TextureAspect ::Color ; 692while (aspectMask ) 693 { 694auto aspect = Math ::getLowestBit ((int32_t )aspectMask ); 695aspectMask &= ~aspect ; 696auto planeIndex = D3DUtil ::getPlaneSlice (d3dFormat , (TextureAspect )aspect ); 697for (GfxCount layer = 0 ;layer < subresourceRange .layerCount ;layer ++ ) 698 { 699for (GfxCount mip = 0 ;mip < subresourceRange .mipLevelCount ;mip ++ ) 700 { 701barrier .Transition .Subresource = D3DUtil ::getSubresourceIndex ( 702mip + subresourceRange .mipLevel , 703layer + subresourceRange .baseArrayLayer , 704planeIndex , 705textureImpl -> getDesc ()-> numMipLevels , 706textureImpl -> getDesc ()-> arraySize ); 707barriers .add (barrier ); 708 } 709 } 710 } 711 } 712m_commandBuffer -> m_cmdList -> ResourceBarrier ( 713 (UINT )barriers .getCount (), 714barriers .getArrayView ().getBuffer ()); 715} 716 717void ResourceCommandEncoderImpl ::beginDebugEvent (const char * name ,float rgbColor [3 ]) 718{ 719auto beginEvent = m_commandBuffer -> m_renderer -> m_BeginEventOnCommandList ; 720if (beginEvent ) 721 { 722beginEvent ( 723m_commandBuffer -> m_cmdList , 7240xff000000 | (uint8_t (rgbColor [0 ]* 255.0f ) <<16 ) | 725 (uint8_t (rgbColor [1 ]* 255.0f ) <<8 ) |uint8_t (rgbColor [2 ]* 255.0f ), 726name ); 727 } 728} 729 730void ResourceCommandEncoderImpl ::endDebugEvent () 731{ 732auto endEvent = m_commandBuffer -> m_renderer -> m_EndEventOnCommandList ; 733if (endEvent ) 734 { 735endEvent (m_commandBuffer -> m_cmdList ); 736 } 737} 738 739void ResourceCommandEncoderImpl ::copyBuffer ( 740IBufferResource * dst , 741Offset dstOffset , 742IBufferResource * src , 743Offset srcOffset , 744Size size ) 745{ 746auto dstBuffer = static_cast < BufferResourceImpl *> (dst ); 747auto srcBuffer = static_cast < BufferResourceImpl *> (src ); 748 749m_commandBuffer -> m_cmdList -> CopyBufferRegion ( 750dstBuffer -> m_resource .getResource (), 751dstOffset , 752srcBuffer -> m_resource .getResource (), 753srcOffset , 754size ); 755} 756 757void ResourceCommandEncoderImpl ::uploadBufferData ( 758IBufferResource * dst , 759Offset offset , 760Size size , 761void * data ) 762{ 763uploadBufferDataImpl ( 764m_commandBuffer -> m_renderer -> m_device , 765m_commandBuffer -> m_cmdList , 766m_commandBuffer -> m_transientHeap , 767static_cast < BufferResourceImpl *> (dst ), 768offset , 769size , 770data ); 771} 772 773void ResourceCommandEncoderImpl ::textureBarrier ( 774GfxCount count , 775ITextureResource * const * textures , 776ResourceState src , 777ResourceState dst ) 778{ 779ShortList < D3D12_RESOURCE_BARRIER > barriers ; 780 781for (GfxIndex i = 0 ;i < count ;i ++ ) 782 { 783auto textureImpl = static_cast < TextureResourceImpl *> (textures [i ]); 784auto d3dFormat = D3DUtil ::getMapFormat (textureImpl -> getDesc ()-> format ); 785auto textureDesc = textureImpl -> getDesc (); 786D3D12_RESOURCE_BARRIER barrier ; 787barrier .Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE ; 788if (src == dst && src == ResourceState ::UnorderedAccess ) 789 { 790barrier .Type = D3D12_RESOURCE_BARRIER_TYPE_UAV ; 791barrier .UAV .pResource = textureImpl -> m_resource .getResource (); 792 } 793else 794 { 795barrier .Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION ; 796barrier .Transition .StateBefore = D3DUtil ::getResourceState (src ); 797barrier .Transition .StateAfter = D3DUtil ::getResourceState (dst ); 798if (barrier .Transition .StateBefore == barrier .Transition .StateAfter ) 799continue ; 800barrier .Transition .pResource = textureImpl -> m_resource .getResource (); 801auto planeCount = 802D3DUtil ::getPlaneSliceCount (D3DUtil ::getMapFormat (textureImpl -> getDesc ()-> format )); 803auto arraySize = textureDesc -> arraySize ; 804if (arraySize == 0 ) 805arraySize = 1 ; 806barrier .Transition .Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES ; 807 } 808barriers .add (barrier ); 809 } 810if (barriers .getCount ()) 811 { 812m_commandBuffer -> m_cmdList -> ResourceBarrier ( 813 (UINT )barriers .getCount (), 814barriers .getArrayView ().getBuffer ()); 815 } 816} 817 818void RenderCommandEncoderImpl ::init ( 819DeviceImpl * renderer , 820TransientResourceHeapImpl * transientHeap , 821CommandBufferImpl * cmdBuffer , 822RenderPassLayoutImpl * renderPass , 823FramebufferImpl * framebuffer ) 824{ 825PipelineCommandEncoder ::init (cmdBuffer ); 826m_preCmdList = nullptr ; 827m_renderPass = renderPass ; 828m_framebuffer = framebuffer ; 829m_transientHeap = transientHeap ; 830m_boundVertexBuffers .clear (); 831m_boundIndexBuffer = nullptr ; 832m_primitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE ; 833m_primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST ; 834m_boundIndexFormat = DXGI_FORMAT_UNKNOWN ; 835m_boundIndexOffset = 0 ; 836m_currentPipeline = nullptr ; 837 838// Set render target states. 839if (!framebuffer ) 840 { 841return ; 842 } 843m_d3dCmdList -> OMSetRenderTargets ( 844 (UINT )framebuffer -> renderTargetViews .getCount (), 845framebuffer -> renderTargetDescriptors .getArrayView ().getBuffer (), 846 FALSE, 847framebuffer -> depthStencilView ?& framebuffer -> depthStencilDescriptor :nullptr ); 848 849// Issue clear commands based on render pass set up. 850for (Index i = 0 ;i < framebuffer -> renderTargetViews .getCount ();i ++ ) 851 { 852if (i >=renderPass -> m_renderTargetAccesses .getCount ()) 853continue ; 854 855auto & access = renderPass -> m_renderTargetAccesses [i ]; 856 857// Transit resource states. 858 { 859D3D12BarrierSubmitter submitter (m_d3dCmdList ); 860auto resourceViewImpl = framebuffer -> renderTargetViews [i ].Ptr (); 861if (resourceViewImpl ) 862 { 863auto textureResource = 864static_cast < TextureResourceImpl *> (resourceViewImpl -> m_resource .Ptr ()); 865if (textureResource ) 866 { 867D3D12_RESOURCE_STATES initialState ; 868if (access .initialState == ResourceState ::Undefined ) 869 { 870initialState = textureResource -> m_defaultState ; 871 } 872else 873 { 874initialState = D3DUtil ::getResourceState (access .initialState ); 875 } 876textureResource -> m_resource .transition ( 877initialState , 878D3D12_RESOURCE_STATE_RENDER_TARGET , 879submitter ); 880 } 881 } 882 } 883// Clear. 884if (access .loadOp == IRenderPassLayout ::TargetLoadOp ::Clear ) 885 { 886m_d3dCmdList -> ClearRenderTargetView ( 887framebuffer -> renderTargetDescriptors [i ], 888framebuffer -> renderTargetClearValues [i ].values , 8890 , 890nullptr ); 891 } 892 } 893 894if (renderPass -> m_hasDepthStencil ) 895 { 896// Transit resource states. 897 { 898D3D12BarrierSubmitter submitter (m_d3dCmdList ); 899auto resourceViewImpl = framebuffer -> depthStencilView .Ptr (); 900auto textureResource = 901static_cast < TextureResourceImpl *> (resourceViewImpl -> m_resource .Ptr ()); 902D3D12_RESOURCE_STATES initialState ; 903if (renderPass -> m_depthStencilAccess .initialState == ResourceState ::Undefined ) 904 { 905initialState = textureResource -> m_defaultState ; 906 } 907else 908 { 909initialState = 910D3DUtil ::getResourceState (renderPass -> m_depthStencilAccess .initialState ); 911 } 912textureResource -> m_resource .transition ( 913initialState , 914D3D12_RESOURCE_STATE_DEPTH_WRITE , 915submitter ); 916 } 917// Clear. 918uint32_t clearFlags = 0 ; 919if (renderPass -> m_depthStencilAccess .loadOp == IRenderPassLayout ::TargetLoadOp ::Clear ) 920 { 921clearFlags |=D3D12_CLEAR_FLAG_DEPTH ; 922 } 923if (renderPass -> m_depthStencilAccess .stencilLoadOp == 924IRenderPassLayout ::TargetLoadOp ::Clear ) 925 { 926clearFlags |=D3D12_CLEAR_FLAG_STENCIL ; 927 } 928if (clearFlags ) 929 { 930m_d3dCmdList -> ClearDepthStencilView ( 931framebuffer -> depthStencilDescriptor , 932 (D3D12_CLEAR_FLAGS )clearFlags , 933framebuffer -> depthStencilClearValue .depth , 934framebuffer -> depthStencilClearValue .stencil , 9350 , 936nullptr ); 937 } 938 } 939} 940 941Result RenderCommandEncoderImpl ::bindPipeline (IPipelineState * state ,IShaderObject ** outRootObject ) 942{ 943return bindPipelineImpl (state ,outRootObject ); 944} 945 946Result RenderCommandEncoderImpl ::bindPipelineWithRootObject ( 947IPipelineState * state , 948IShaderObject * rootObject ) 949{ 950return bindPipelineWithRootObjectImpl (state ,rootObject ); 951} 952 953void RenderCommandEncoderImpl ::setViewports (GfxCount count ,const Viewport * viewports ) 954{ 955static const int kMaxViewports = D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE ; 956assert (count <=kMaxViewports && count <=kMaxRTVCount ); 957for (GfxIndex ii = 0 ;ii < count ;++ ii ) 958 { 959auto & inViewport = viewports [ii ]; 960auto & dxViewport = m_viewports [ii ]; 961 962dxViewport .TopLeftX = inViewport .originX ; 963dxViewport .TopLeftY = inViewport .originY ; 964dxViewport .Width = inViewport .extentX ; 965dxViewport .Height = inViewport .extentY ; 966dxViewport .MinDepth = inViewport .minZ ; 967dxViewport .MaxDepth = inViewport .maxZ ; 968 } 969m_d3dCmdList -> RSSetViewports (UINT (count ),m_viewports ); 970} 971 972void RenderCommandEncoderImpl ::setScissorRects (GfxCount count ,const ScissorRect * rects ) 973{ 974static const int kMaxScissorRects = D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE ; 975assert (count <=kMaxScissorRects && count <=kMaxRTVCount ); 976 977for (GfxIndex ii = 0 ;ii < count ;++ ii ) 978 { 979auto & inRect = rects [ii ]; 980auto & dxRect = m_scissorRects [ii ]; 981 982dxRect .left = LONG (inRect .minX ); 983dxRect .top = LONG (inRect .minY ); 984dxRect .right = LONG (inRect .maxX ); 985dxRect .bottom = LONG (inRect .maxY ); 986 } 987 988m_d3dCmdList -> RSSetScissorRects (UINT (count ),m_scissorRects ); 989} 990 991void RenderCommandEncoderImpl ::setPrimitiveTopology (PrimitiveTopology topology ) 992{ 993m_primitiveTopologyType = D3DUtil ::getPrimitiveType (topology ); 994m_primitiveTopology = D3DUtil ::getPrimitiveTopology (topology ); 995} 996 997void RenderCommandEncoderImpl ::setVertexBuffers ( 998GfxIndex startSlot , 999GfxCount slotCount , 1000IBufferResource * const * buffers , 1001const Offset * offsets ) 1002{ 1003 { 1004const Index num = startSlot + slotCount ; 1005if (num > m_boundVertexBuffers .getCount ()) 1006 { 1007m_boundVertexBuffers .setCount (num ); 1008 } 1009 } 1010 1011for (GfxIndex i = 0 ;i < slotCount ;i ++ ) 1012 { 1013BufferResourceImpl * buffer = static_cast < BufferResourceImpl *> (buffers [i ]); 1014 1015BoundVertexBuffer & boundBuffer = m_boundVertexBuffers [startSlot + i ]; 1016boundBuffer .m_buffer = buffer ; 1017boundBuffer .m_offset = int (offsets [i ]); 1018 } 1019} 1020 1021void RenderCommandEncoderImpl ::setIndexBuffer ( 1022IBufferResource * buffer , 1023Format indexFormat , 1024Offset offset ) 1025{ 1026m_boundIndexBuffer = (BufferResourceImpl * )buffer ; 1027m_boundIndexFormat = D3DUtil ::getMapFormat (indexFormat ); 1028m_boundIndexOffset = (UINT )offset ; 1029} 1030 1031Result RenderCommandEncoderImpl ::prepareDraw () 1032{ 1033auto pipelineState = m_currentPipeline .Ptr (); 1034if (!pipelineState || (pipelineState -> desc .type != PipelineType ::Graphics )) 1035 { 1036return SLANG_FAIL ; 1037 } 1038 1039// Submit - setting for graphics 1040 { 1041GraphicsSubmitter submitter (m_d3dCmdList ); 1042RefPtr < PipelineStateBase > newPipeline ; 1043SLANG_RETURN_ON_FAIL (_bindRenderState (& submitter ,newPipeline )); 1044 } 1045 1046m_d3dCmdList -> IASetPrimitiveTopology (m_primitiveTopology ); 1047 1048// Set up vertex buffer views 1049 { 1050auto inputLayout = (InputLayoutImpl * )pipelineState -> inputLayout .Ptr (); 1051if (inputLayout ) 1052 { 1053int numVertexViews = 0 ; 1054D3D12_VERTEX_BUFFER_VIEW vertexViews [16 ]; 1055for (Index i = 0 ;i < m_boundVertexBuffers .getCount ();i ++ ) 1056 { 1057const BoundVertexBuffer & boundVertexBuffer = m_boundVertexBuffers [i ]; 1058BufferResourceImpl * buffer = boundVertexBuffer .m_buffer ; 1059if (buffer ) 1060 { 1061D3D12_VERTEX_BUFFER_VIEW & vertexView = vertexViews [numVertexViews ++ ]; 1062vertexView .BufferLocation = 1063buffer -> m_resource .getResource ()-> GetGPUVirtualAddress ()+ 1064boundVertexBuffer .m_offset ; 1065vertexView .SizeInBytes = 1066UINT (buffer -> getDesc ()-> sizeInBytes - boundVertexBuffer .m_offset ); 1067vertexView .StrideInBytes = inputLayout -> m_vertexStreamStrides [i ]; 1068 } 1069 } 1070m_d3dCmdList -> IASetVertexBuffers (0 ,numVertexViews ,vertexViews ); 1071 } 1072 } 1073// Set up index buffer 1074if (m_boundIndexBuffer ) 1075 { 1076D3D12_INDEX_BUFFER_VIEW indexBufferView ; 1077indexBufferView .BufferLocation = 1078m_boundIndexBuffer -> m_resource .getResource ()-> GetGPUVirtualAddress ()+ 1079m_boundIndexOffset ; 1080indexBufferView .SizeInBytes = 1081UINT (m_boundIndexBuffer -> getDesc ()-> sizeInBytes - m_boundIndexOffset ); 1082indexBufferView .Format = m_boundIndexFormat ; 1083 1084m_d3dCmdList -> IASetIndexBuffer (& indexBufferView ); 1085 } 1086return SLANG_OK ; 1087} 1088 1089Result RenderCommandEncoderImpl ::draw (GfxCount vertexCount ,GfxIndex startVertex ) 1090{ 1091SLANG_RETURN_ON_FAIL (prepareDraw ()); 1092m_d3dCmdList -> DrawInstanced ((uint32_t )vertexCount ,1 , (uint32_t )startVertex ,0 ); 1093return SLANG_OK ; 1094} 1095 1096Result RenderCommandEncoderImpl ::drawIndexed ( 1097GfxCount indexCount , 1098GfxIndex startIndex , 1099GfxIndex baseVertex ) 1100{ 1101SLANG_RETURN_ON_FAIL (prepareDraw ()); 1102m_d3dCmdList -> DrawIndexedInstanced ( 1103 (uint32_t )indexCount , 11041 , 1105 (uint32_t )startIndex , 1106 (uint32_t )baseVertex , 11070 ); 1108return SLANG_OK ; 1109} 1110 1111void RenderCommandEncoderImpl ::endEncoding () 1112{ 1113PipelineCommandEncoder ::endEncodingImpl (); 1114if (!m_framebuffer ) 1115return ; 1116// Issue clear commands based on render pass set up. 1117for (Index i = 0 ;i < m_renderPass -> m_renderTargetAccesses .getCount ();i ++ ) 1118 { 1119auto & access = m_renderPass -> m_renderTargetAccesses [i ]; 1120 1121// Transit resource states. 1122 { 1123D3D12BarrierSubmitter submitter (m_d3dCmdList ); 1124auto resourceViewImpl = m_framebuffer -> renderTargetViews [i ].Ptr (); 1125if (!resourceViewImpl ) 1126continue ; 1127auto textureResource = 1128static_cast < TextureResourceImpl *> (resourceViewImpl -> m_resource .Ptr ()); 1129if (textureResource ) 1130 { 1131textureResource -> m_resource .transition ( 1132D3D12_RESOURCE_STATE_RENDER_TARGET , 1133D3DUtil ::getResourceState (access .finalState ), 1134submitter ); 1135 } 1136 } 1137 } 1138 1139if (m_renderPass -> m_hasDepthStencil ) 1140 { 1141// Transit resource states. 1142D3D12BarrierSubmitter submitter (m_d3dCmdList ); 1143auto resourceViewImpl = m_framebuffer -> depthStencilView .Ptr (); 1144auto textureResource = 1145static_cast < TextureResourceImpl *> (resourceViewImpl -> m_resource .Ptr ()); 1146textureResource -> m_resource .transition ( 1147D3D12_RESOURCE_STATE_DEPTH_WRITE , 1148D3DUtil ::getResourceState (m_renderPass -> m_depthStencilAccess .finalState ), 1149submitter ); 1150 } 1151m_framebuffer = nullptr ; 1152} 1153 1154void RenderCommandEncoderImpl ::setStencilReference (uint32_t referenceValue ) 1155{ 1156m_d3dCmdList -> OMSetStencilRef ((UINT )referenceValue ); 1157} 1158 1159Result RenderCommandEncoderImpl ::drawIndirect ( 1160GfxCount maxDrawCount , 1161IBufferResource * argBuffer , 1162Offset argOffset , 1163IBufferResource * countBuffer , 1164Offset countOffset ) 1165{ 1166SLANG_RETURN_ON_FAIL (prepareDraw ()); 1167 1168auto argBufferImpl = static_cast < BufferResourceImpl *> (argBuffer ); 1169auto countBufferImpl = static_cast < BufferResourceImpl *> (countBuffer ); 1170 1171m_d3dCmdList -> ExecuteIndirect ( 1172m_renderer -> drawIndirectCmdSignature , 1173 (uint32_t )maxDrawCount , 1174argBufferImpl -> m_resource , 1175 (uint64_t )argOffset , 1176countBufferImpl ?countBufferImpl -> m_resource .getResource () :nullptr , 1177 (uint64_t )countOffset ); 1178return SLANG_OK ; 1179} 1180 1181Result RenderCommandEncoderImpl ::drawIndexedIndirect ( 1182GfxCount maxDrawCount , 1183IBufferResource * argBuffer , 1184Offset argOffset , 1185IBufferResource * countBuffer , 1186Offset countOffset ) 1187{ 1188SLANG_RETURN_ON_FAIL (prepareDraw ()); 1189 1190auto argBufferImpl = static_cast < BufferResourceImpl *> (argBuffer ); 1191auto countBufferImpl = static_cast < BufferResourceImpl *> (countBuffer ); 1192 1193m_d3dCmdList -> ExecuteIndirect ( 1194m_renderer -> drawIndexedIndirectCmdSignature , 1195 (uint32_t )maxDrawCount , 1196argBufferImpl -> m_resource , 1197 (uint64_t )argOffset , 1198countBufferImpl ?countBufferImpl -> m_resource .getResource () :nullptr , 1199 (uint64_t )countOffset ); 1200 1201return SLANG_OK ; 1202} 1203 1204Result RenderCommandEncoderImpl ::setSamplePositions ( 1205GfxCount samplesPerPixel , 1206GfxCount pixelCount , 1207const SamplePosition * samplePositions ) 1208{ 1209if (m_commandBuffer -> m_cmdList1 ) 1210 { 1211m_commandBuffer -> m_cmdList1 -> SetSamplePositions ( 1212 (uint32_t )samplesPerPixel , 1213 (uint32_t )pixelCount , 1214 (D3D12_SAMPLE_POSITION * )samplePositions ); 1215return SLANG_OK ; 1216 } 1217return SLANG_E_NOT_AVAILABLE ; 1218} 1219 1220Result RenderCommandEncoderImpl ::drawInstanced ( 1221GfxCount vertexCount , 1222GfxCount instanceCount , 1223GfxIndex startVertex , 1224GfxIndex startInstanceLocation ) 1225{ 1226SLANG_RETURN_ON_FAIL (prepareDraw ()); 1227m_d3dCmdList -> DrawInstanced ( 1228 (uint32_t )vertexCount , 1229 (uint32_t )instanceCount , 1230 (uint32_t )startVertex , 1231 (uint32_t )startInstanceLocation ); 1232return SLANG_OK ; 1233} 1234 1235Result RenderCommandEncoderImpl ::drawIndexedInstanced ( 1236GfxCount indexCount , 1237GfxCount instanceCount , 1238GfxIndex startIndexLocation , 1239GfxIndex baseVertexLocation , 1240GfxIndex startInstanceLocation ) 1241{ 1242SLANG_RETURN_ON_FAIL (prepareDraw ()); 1243m_d3dCmdList -> DrawIndexedInstanced ( 1244 (uint32_t )indexCount , 1245 (uint32_t )instanceCount , 1246 (uint32_t )startIndexLocation , 1247baseVertexLocation , 1248 (uint32_t )startInstanceLocation ); 1249return SLANG_OK ; 1250} 1251 1252Result RenderCommandEncoderImpl ::drawMeshTasks (int x ,int y ,int z ) 1253{ 1254SLANG_RETURN_ON_FAIL (prepareDraw ()); 1255m_d3dCmdList6 -> DispatchMesh (x ,y ,z ); 1256return SLANG_OK ; 1257} 1258 1259void ComputeCommandEncoderImpl ::endEncoding () 1260{ 1261PipelineCommandEncoder ::endEncodingImpl (); 1262} 1263 1264void ComputeCommandEncoderImpl ::init ( 1265DeviceImpl * renderer , 1266TransientResourceHeapImpl * transientHeap , 1267CommandBufferImpl * cmdBuffer ) 1268{ 1269PipelineCommandEncoder ::init (cmdBuffer ); 1270m_preCmdList = nullptr ; 1271m_transientHeap = transientHeap ; 1272m_currentPipeline = nullptr ; 1273} 1274 1275Result ComputeCommandEncoderImpl ::bindPipeline (IPipelineState * state ,IShaderObject ** outRootObject ) 1276{ 1277return bindPipelineImpl (state ,outRootObject ); 1278} 1279 1280Result ComputeCommandEncoderImpl ::bindPipelineWithRootObject ( 1281IPipelineState * state , 1282IShaderObject * rootObject ) 1283{ 1284return bindPipelineWithRootObjectImpl (state ,rootObject ); 1285} 1286 1287Result ComputeCommandEncoderImpl ::dispatchCompute (int x ,int y ,int z ) 1288{ 1289// Submit binding for compute 1290 { 1291ComputeSubmitter submitter (m_d3dCmdList ); 1292RefPtr < PipelineStateBase > newPipeline ; 1293SLANG_RETURN_ON_FAIL (_bindRenderState (& submitter ,newPipeline )); 1294 } 1295m_d3dCmdList -> Dispatch (x ,y ,z ); 1296return SLANG_OK ; 1297} 1298 1299Result ComputeCommandEncoderImpl ::dispatchComputeIndirect (IBufferResource * argBuffer ,Offset offset ) 1300{ 1301// Submit binding for compute 1302 { 1303ComputeSubmitter submitter (m_d3dCmdList ); 1304RefPtr < PipelineStateBase > newPipeline ; 1305SLANG_RETURN_ON_FAIL (_bindRenderState (& submitter ,newPipeline )); 1306 } 1307auto argBufferImpl = static_cast < BufferResourceImpl *> (argBuffer ); 1308 1309m_d3dCmdList -> ExecuteIndirect ( 1310m_renderer -> dispatchIndirectCmdSignature , 13111 , 1312argBufferImpl -> m_resource , 1313 (uint64_t )offset , 1314nullptr , 13150 ); 1316return SLANG_OK ; 1317} 1318 1319#if SLANG_GFX_HAS_DXR_SUPPORT 1320 1321void RayTracingCommandEncoderImpl ::buildAccelerationStructure ( 1322const IAccelerationStructure ::BuildDesc & desc , 1323GfxCount propertyQueryCount , 1324AccelerationStructureQueryDesc * queryDescs ) 1325{ 1326if (!m_commandBuffer -> m_cmdList4 ) 1327 { 1328getDebugCallback ()-> handleMessage ( 1329DebugMessageType ::Error , 1330DebugMessageSource ::Layer , 1331"Ray-tracing is not supported on current system." ); 1332return ; 1333 } 1334AccelerationStructureImpl * destASImpl = nullptr ; 1335if (desc .dest ) 1336destASImpl = static_cast < AccelerationStructureImpl *> (desc .dest ); 1337AccelerationStructureImpl * srcASImpl = nullptr ; 1338if (desc .source ) 1339srcASImpl = static_cast < AccelerationStructureImpl *> (desc .source ); 1340 1341D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC buildDesc = {}; 1342buildDesc .DestAccelerationStructureData = destASImpl -> getDeviceAddress (); 1343buildDesc .SourceAccelerationStructureData = srcASImpl ?srcASImpl -> getDeviceAddress () :0 ; 1344buildDesc .ScratchAccelerationStructureData = desc .scratchData ; 1345D3DAccelerationStructureInputsBuilder builder ; 1346builder .build (desc .inputs ,getDebugCallback ()); 1347buildDesc .Inputs = builder .desc ; 1348 1349List < D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC > postBuildInfoDescs ; 1350translatePostBuildInfoDescs (propertyQueryCount ,queryDescs ,postBuildInfoDescs ); 1351m_commandBuffer -> m_cmdList4 -> BuildRaytracingAccelerationStructure ( 1352& buildDesc , 1353 (UINT )propertyQueryCount , 1354postBuildInfoDescs .getBuffer ()); 1355} 1356 1357void RayTracingCommandEncoderImpl ::copyAccelerationStructure ( 1358IAccelerationStructure * dest , 1359IAccelerationStructure * src , 1360AccelerationStructureCopyMode mode ) 1361{ 1362auto destASImpl = static_cast < AccelerationStructureImpl *> (dest ); 1363auto srcASImpl = static_cast < AccelerationStructureImpl *> (src ); 1364D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE copyMode ; 1365switch (mode ) 1366 { 1367case AccelerationStructureCopyMode ::Clone : 1368copyMode = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_CLONE ; 1369break ; 1370case AccelerationStructureCopyMode ::Compact : 1371copyMode = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_COMPACT ; 1372break ; 1373default : 1374getDebugCallback ()-> handleMessage ( 1375DebugMessageType ::Error , 1376DebugMessageSource ::Layer , 1377"Unsupported AccelerationStructureCopyMode." ); 1378return ; 1379 } 1380m_commandBuffer -> m_cmdList4 -> CopyRaytracingAccelerationStructure ( 1381destASImpl -> getDeviceAddress (), 1382srcASImpl -> getDeviceAddress (), 1383copyMode ); 1384} 1385 1386void RayTracingCommandEncoderImpl ::queryAccelerationStructureProperties ( 1387GfxCount accelerationStructureCount , 1388IAccelerationStructure * const * accelerationStructures , 1389GfxCount queryCount , 1390AccelerationStructureQueryDesc * queryDescs ) 1391{ 1392List < D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC > postBuildInfoDescs ; 1393List < DeviceAddress > asAddresses ; 1394asAddresses .setCount (accelerationStructureCount ); 1395for (GfxIndex i = 0 ;i < accelerationStructureCount ;i ++ ) 1396asAddresses [i ]= accelerationStructures [i ]-> getDeviceAddress (); 1397translatePostBuildInfoDescs (queryCount ,queryDescs ,postBuildInfoDescs ); 1398m_commandBuffer -> m_cmdList4 -> EmitRaytracingAccelerationStructurePostbuildInfo ( 1399postBuildInfoDescs .getBuffer (), 1400 (UINT )accelerationStructureCount , 1401asAddresses .getBuffer ()); 1402} 1403 1404void RayTracingCommandEncoderImpl ::serializeAccelerationStructure ( 1405DeviceAddress dest , 1406IAccelerationStructure * src ) 1407{ 1408auto srcASImpl = static_cast < AccelerationStructureImpl *> (src ); 1409m_commandBuffer -> m_cmdList4 -> CopyRaytracingAccelerationStructure ( 1410dest , 1411srcASImpl -> getDeviceAddress (), 1412D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_SERIALIZE ); 1413} 1414 1415void RayTracingCommandEncoderImpl ::deserializeAccelerationStructure ( 1416IAccelerationStructure * dest , 1417DeviceAddress source ) 1418{ 1419auto destASImpl = static_cast < AccelerationStructureImpl *> (dest ); 1420m_commandBuffer -> m_cmdList4 -> CopyRaytracingAccelerationStructure ( 1421dest -> getDeviceAddress (), 1422source , 1423D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_DESERIALIZE ); 1424} 1425 1426Result RayTracingCommandEncoderImpl ::bindPipeline ( 1427IPipelineState * state , 1428IShaderObject ** outRootObject ) 1429{ 1430return bindPipelineImpl (state ,outRootObject ); 1431} 1432 1433Result RayTracingCommandEncoderImpl ::dispatchRays ( 1434GfxIndex rayGenShaderIndex , 1435IShaderTable * shaderTable , 1436GfxCount width , 1437GfxCount height , 1438GfxCount depth ) 1439{ 1440RefPtr < PipelineStateBase > newPipeline ; 1441PipelineStateBase * pipeline = m_currentPipeline .Ptr (); 1442 { 1443struct RayTracingSubmitter :public ComputeSubmitter 1444 { 1445ID3D12GraphicsCommandList4 * m_cmdList4 ; 1446RayTracingSubmitter (ID3D12GraphicsCommandList4 * cmdList4 ) 1447 :ComputeSubmitter (cmdList4 ),m_cmdList4 (cmdList4 ) 1448 { 1449 } 1450virtual void setPipelineState (PipelineStateBase * pipeline )override 1451 { 1452auto pipelineImpl = static_cast < RayTracingPipelineStateImpl *> (pipeline ); 1453m_cmdList4 -> SetPipelineState1 (pipelineImpl -> m_stateObject .get ()); 1454 } 1455 }; 1456RayTracingSubmitter submitter (m_commandBuffer -> m_cmdList4 ); 1457SLANG_RETURN_ON_FAIL (_bindRenderState (& submitter ,newPipeline )); 1458if (newPipeline ) 1459pipeline = newPipeline .Ptr (); 1460 } 1461auto pipelineImpl = static_cast < RayTracingPipelineStateImpl *> (pipeline ); 1462 1463auto shaderTableImpl = static_cast < ShaderTableImpl *> (shaderTable ); 1464 1465auto shaderTableBuffer = shaderTableImpl -> getOrCreateBuffer ( 1466pipelineImpl , 1467m_transientHeap , 1468static_cast < ResourceCommandEncoderImpl *> (this )); 1469auto shaderTableAddr = shaderTableBuffer -> getDeviceAddress (); 1470 1471D3D12_DISPATCH_RAYS_DESC dispatchDesc = {}; 1472 1473dispatchDesc .RayGenerationShaderRecord .StartAddress = shaderTableAddr + 1474shaderTableImpl -> m_rayGenTableOffset + 1475rayGenShaderIndex * kRayGenRecordSize ; 1476dispatchDesc .RayGenerationShaderRecord .SizeInBytes = D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES ; 1477 1478if (shaderTableImpl -> m_missShaderCount > 0 ) 1479 { 1480dispatchDesc .MissShaderTable .StartAddress = 1481shaderTableAddr + shaderTableImpl -> m_missTableOffset ; 1482dispatchDesc .MissShaderTable .SizeInBytes = 1483shaderTableImpl -> m_missShaderCount * D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES ; 1484dispatchDesc .MissShaderTable .StrideInBytes = D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES ; 1485 } 1486 1487if (shaderTableImpl -> m_hitGroupCount > 0 ) 1488 { 1489dispatchDesc .HitGroupTable .StartAddress = 1490shaderTableAddr + shaderTableImpl -> m_hitGroupTableOffset ; 1491dispatchDesc .HitGroupTable .SizeInBytes = 1492shaderTableImpl -> m_hitGroupCount * D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES ; 1493dispatchDesc .HitGroupTable .StrideInBytes = D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES ; 1494 } 1495 1496if (shaderTableImpl -> m_callableShaderCount > 0 ) 1497 { 1498dispatchDesc .CallableShaderTable .StartAddress = 1499shaderTableAddr + shaderTableImpl -> m_callableTableOffset ; 1500dispatchDesc .CallableShaderTable .SizeInBytes = 1501shaderTableImpl -> m_callableShaderCount * D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES ; 1502dispatchDesc .CallableShaderTable .StrideInBytes = D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES ; 1503 } 1504 1505dispatchDesc .Width = (UINT )width ; 1506dispatchDesc .Height = (UINT )height ; 1507dispatchDesc .Depth = (UINT )depth ; 1508m_commandBuffer -> m_cmdList4 -> DispatchRays (& dispatchDesc ); 1509 1510return SLANG_OK ; 1511} 1512 1513#endif 1514 1515}// namespace d3d12 1516}// namespace gfx