yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
edcb2f0b8
master
1// metal-command-encoder.cpp 2#include "metal-command-encoder.h" 3 4#include "metal-buffer.h" 5#include "metal-command-buffer.h" 6#include "metal-helper-functions.h" 7#include "metal-query.h" 8#include "metal-render-pass.h" 9#include "metal-resource-views.h" 10#include "metal-shader-object.h" 11#include "metal-shader-program.h" 12#include "metal-shader-table.h" 13#include "metal-texture.h" 14#include "metal-util.h" 15 16namespace gfx 17{ 18 19using namespace Slang ; 20 21namespace metal 22{ 23 24void PipelineCommandEncoder ::init (CommandBufferImpl * commandBuffer ) 25{ 26m_commandBuffer = commandBuffer ; 27m_metalCommandBuffer = m_commandBuffer -> m_commandBuffer .get (); 28} 29 30void PipelineCommandEncoder ::endEncodingImpl () 31{ 32m_commandBuffer -> endMetalCommandEncoder (); 33} 34 35Result PipelineCommandEncoder ::setPipelineStateImpl ( 36IPipelineState * state , 37IShaderObject ** outRootObject ) 38{ 39m_currentPipeline = static_cast < PipelineStateImpl *> (state ); 40// m_commandBuffer->m_mutableRootShaderObject = nullptr; 41SLANG_RETURN_ON_FAIL (m_commandBuffer -> m_rootObject .init ( 42m_commandBuffer -> m_device , 43m_currentPipeline -> getProgram < ShaderProgramImpl > ()-> m_rootObjectLayout )); 44* outRootObject = & m_commandBuffer -> m_rootObject ; 45return SLANG_OK ; 46} 47 48void ResourceCommandEncoder ::endEncoding () 49{ 50PipelineCommandEncoder ::endEncodingImpl (); 51} 52 53void ResourceCommandEncoder ::writeTimestamp (IQueryPool * queryPool ,GfxIndex index ) 54{ 55auto encoder = m_commandBuffer -> getMetalBlitCommandEncoder (); 56encoder -> sampleCountersInBuffer ( 57static_cast < QueryPoolImpl *> (queryPool )-> m_counterSampleBuffer .get (), 58index , 59 true); 60} 61 62void ResourceCommandEncoder ::copyBuffer ( 63IBufferResource * dst , 64Offset dstOffset , 65IBufferResource * src , 66Offset srcOffset , 67Size size ) 68{ 69auto encoder = m_commandBuffer -> getMetalBlitCommandEncoder (); 70encoder -> copyFromBuffer ( 71static_cast < BufferResourceImpl *> (src )-> m_buffer .get (), 72srcOffset , 73static_cast < BufferResourceImpl *> (dst )-> m_buffer .get (), 74dstOffset , 75size ); 76} 77 78void ResourceCommandEncoder ::copyTexture ( 79ITextureResource * dst , 80ResourceState dstState , 81SubresourceRange dstSubresource , 82ITextureResource ::Offset3D dstOffset , 83ITextureResource * src , 84ResourceState srcState , 85SubresourceRange srcSubresource , 86ITextureResource ::Offset3D srcOffset , 87ITextureResource ::Extents extent ) 88{ 89auto encoder = m_commandBuffer -> getMetalBlitCommandEncoder (); 90 91if (dstSubresource .layerCount == 0 && dstSubresource .mipLevelCount == 0 && 92srcSubresource .layerCount == 0 && srcSubresource .mipLevelCount == 0 ) 93 { 94encoder -> copyFromTexture ( 95static_cast < TextureResourceImpl *> (src )-> m_texture .get (), 96static_cast < TextureResourceImpl *> (dst )-> m_texture .get ()); 97 } 98else 99 { 100for (GfxIndex layer = 0 ;layer < dstSubresource .layerCount ;layer ++ ) 101 { 102encoder -> copyFromTexture ( 103static_cast < TextureResourceImpl *> (src )-> m_texture .get (), 104srcSubresource .baseArrayLayer + layer , 105srcSubresource .mipLevel , 106MTL ::Origin (srcOffset .x ,srcOffset .y ,srcOffset .z ), 107MTL ::Size (extent .width ,extent .height ,extent .depth ), 108static_cast < TextureResourceImpl *> (dst )-> m_texture .get (), 109dstSubresource .baseArrayLayer + layer , 110dstSubresource .mipLevel , 111MTL ::Origin (dstOffset .x ,dstOffset .y ,dstOffset .z )); 112 } 113 } 114} 115 116void ResourceCommandEncoder ::copyTextureToBuffer ( 117IBufferResource * dst , 118Offset dstOffset , 119Size dstSize , 120Size dstRowStride , 121ITextureResource * src , 122ResourceState srcState , 123SubresourceRange srcSubresource , 124ITextureResource ::Offset3D srcOffset , 125ITextureResource ::Extents extent ) 126{ 127assert (srcSubresource .mipLevelCount <=1 ); 128 129auto encoder = m_commandBuffer -> getMetalBlitCommandEncoder (); 130auto & desc = * static_cast < TextureResourceImpl *> (src )-> getDesc (); 131const TextureResource ::Extents mipSize = calcMipSize (desc .size ,srcSubresource .mipLevel ); 132Size bytesPerImage = mipSize .height * dstRowStride ; 133 134encoder -> copyFromTexture ( 135static_cast < TextureResourceImpl *> (src )-> m_texture .get (), 136srcSubresource .baseArrayLayer , 137srcSubresource .mipLevel , 138MTL ::Origin (srcOffset .x ,srcOffset .y ,srcOffset .z ), 139MTL ::Size (extent .width ,extent .height ,extent .depth ), 140static_cast < BufferResourceImpl *> (dst )-> m_buffer .get (), 141dstOffset , 142dstRowStride , 143extent .depth == 1 ?0 :bytesPerImage ); 144} 145 146void ResourceCommandEncoder ::uploadBufferData ( 147IBufferResource * buffer , 148Offset offset , 149Size size , 150void * data ) 151{ 152SLANG_UNIMPLEMENTED_X ("uploadBufferData" ); 153} 154 155void ResourceCommandEncoder ::uploadTextureData ( 156ITextureResource * dst , 157SubresourceRange subResourceRange , 158ITextureResource ::Offset3D offset , 159ITextureResource ::Extents extend , 160ITextureResource ::SubresourceData * subResourceData , 161GfxCount subResourceDataCount ) 162{ 163auto dstTexture = static_cast < TextureResourceImpl *> (dst ); 164auto & desc = * dstTexture -> getDesc (); 165 166// Calculate buffer size needed 167Size bufferSize = 0 ; 168FormatInfo sizeInfo ; 169gfxGetFormatInfo (desc .format ,& sizeInfo ); 170MTL ::PixelFormat pixelFormat = MetalUtil ::translatePixelFormat (desc .format ); 171bool isCompressed = gfxIsCompressedFormat (desc .format ); 172 173Size rowAlignment = 174isCompressed 175 ?1 176 :m_commandBuffer -> m_device -> m_device -> minimumLinearTextureAlignmentForPixelFormat ( 177pixelFormat ); 178 179for (GfxIndex i = 0 ;i < subResourceRange .mipLevelCount ;++ i ) 180 { 181GfxIndex currentLevel = subResourceRange .mipLevel + i ; 182const TextureResource ::Extents mipSize = calcMipSize (desc .size ,currentLevel ); 183 184auto rowSizeInBytes = (mipSize .width + sizeInfo .blockWidth - 1 ) /sizeInfo .blockWidth * 185sizeInfo .blockSizeInBytes ; 186rowSizeInBytes = (rowSizeInBytes + rowAlignment - 1 )& ~(rowAlignment - 1 ); 187 188auto numRows = (mipSize .height + sizeInfo .blockHeight - 1 ) /sizeInfo .blockHeight ; 189bufferSize += (rowSizeInBytes * numRows )* mipSize .depth ; 190 } 191bufferSize *=subResourceRange .layerCount ; 192 193// Create staging buffer 194NS ::SharedPtr < MTL ::Buffer > stagingBuffer = NS ::TransferPtr ( 195m_commandBuffer -> m_device -> m_device -> newBuffer (bufferSize ,MTL ::ResourceStorageModeShared )); 196 197if (!stagingBuffer ) 198return ; 199 200auto encoder = m_commandBuffer -> getMetalBlitCommandEncoder (); 201if (!encoder ) 202return ; 203 204// Copy data to staging buffer and then to texture 205Size bufferOffset = 0 ; 206for (GfxIndex i = 0 ;i < subResourceRange .layerCount ;i ++ ) 207 { 208// We only allocate staging buffer with size of one slice. 209GfxIndex currentSlice = subResourceRange .baseArrayLayer + i ; 210uint8_t * bufferData = (uint8_t * )stagingBuffer -> contents (); 211Size dstOffset = 0 ; 212 213for (GfxIndex j = 0 ;j < subResourceRange .mipLevelCount ;j ++ ) 214 { 215GfxIndex currentLevel = subResourceRange .mipLevel + j ; 216const auto & subresourceData = subResourceData [j ]; 217const TextureResource ::Extents mipSize = calcMipSize (desc .size ,currentLevel ); 218 219auto rowSizeInBytes = (mipSize .width + sizeInfo .blockWidth - 1 ) /sizeInfo .blockWidth * 220sizeInfo .blockSizeInBytes ; 221auto rowSizeInBytesAligned = (rowSizeInBytes + rowAlignment - 1 )& ~(rowAlignment - 1 ); 222 223auto numRows = (mipSize .height + sizeInfo .blockHeight - 1 ) /sizeInfo .blockHeight ; 224 225const uint8_t * srcData = (const uint8_t * )subresourceData .data ; 226if (rowSizeInBytesAligned == rowSizeInBytes ) 227 { 228// If the row size is already aligned, we can copy the data directly. 229memcpy (bufferData + dstOffset ,srcData ,rowSizeInBytes * numRows * mipSize .depth ); 230 } 231else 232 { 233for (GfxIndex k = 0 ;k < mipSize .depth ;++ k ) 234 { 235for (GfxIndex row = 0 ;row < numRows ;++ row ) 236 { 237// Copy data to staging buffer, note that the staging buffer has to have the 238// same alignment as the texture while the src data doesn't have such 239// requirement, therefore we have to copy the data row by row. We don't care 240// about the content of the alignment padding. 241memcpy (bufferData + dstOffset ,srcData ,rowSizeInBytes ); 242dstOffset += rowSizeInBytesAligned ; 243srcData += rowSizeInBytes ; 244 } 245 } 246 } 247 248// Copy from staging buffer to texture 249encoder -> copyFromBuffer ( 250stagingBuffer .get (), 251bufferOffset , 252rowSizeInBytesAligned , 253rowSizeInBytesAligned * numRows , 254MTL ::Size (mipSize .width ,mipSize .height ,mipSize .depth ), 255dstTexture -> m_texture .get (), 256currentSlice , 257currentLevel , 258MTL ::Origin (offset .x ,offset .y ,offset .z )); 259 260bufferOffset += rowSizeInBytes * numRows * mipSize .depth ; 261 } 262 } 263} 264 265void ResourceCommandEncoder ::bufferBarrier ( 266GfxCount count , 267IBufferResource * const * buffers , 268ResourceState src , 269ResourceState dst ) 270{ 271// We use automatic hazard tracking for now, no need for barriers. 272} 273 274void ResourceCommandEncoder ::textureBarrier ( 275GfxCount count , 276ITextureResource * const * textures , 277ResourceState src , 278ResourceState dst ) 279{ 280// We use automatic hazard tracking for now, no need for barriers. 281} 282 283void ResourceCommandEncoder ::textureSubresourceBarrier ( 284ITextureResource * texture , 285SubresourceRange subresourceRange , 286ResourceState src , 287ResourceState dst ) 288{ 289// We use automatic hazard tracking for now, no need for barriers. 290} 291 292void ResourceCommandEncoder ::clearResourceView ( 293IResourceView * view , 294ClearValue * clearValue , 295ClearResourceViewFlags ::Enum flags ) 296{ 297SLANG_UNIMPLEMENTED_X ("clearResourceView" ); 298} 299 300void ResourceCommandEncoder ::resolveResource ( 301ITextureResource * source , 302ResourceState sourceState , 303SubresourceRange sourceRange , 304ITextureResource * dest , 305ResourceState destState , 306SubresourceRange destRange ) 307{ 308SLANG_UNIMPLEMENTED_X ("resolveResource" ); 309} 310 311void ResourceCommandEncoder ::resolveQuery ( 312IQueryPool * queryPool , 313GfxIndex index , 314GfxCount count , 315IBufferResource * buffer , 316Offset offset ) 317{ 318auto encoder = m_commandBuffer -> getMetalBlitCommandEncoder (); 319encoder -> resolveCounters ( 320static_cast < QueryPoolImpl *> (queryPool )-> m_counterSampleBuffer .get (), 321NS ::Range (index ,count ), 322static_cast < BufferResourceImpl *> (buffer )-> m_buffer .get (), 323offset ); 324} 325 326void ResourceCommandEncoder ::beginDebugEvent (const char * name ,float rgbColor [3 ]) 327{ 328NS ::SharedPtr < NS ::String > string = MetalUtil ::createString (name ); 329m_commandBuffer -> m_commandBuffer -> pushDebugGroup (string .get ()); 330} 331 332void ResourceCommandEncoder ::endDebugEvent () 333{ 334m_commandBuffer -> m_commandBuffer -> popDebugGroup (); 335} 336 337void RenderCommandEncoder ::beginPass (IRenderPassLayout * renderPass ,IFramebuffer * framebuffer ) 338{ 339m_renderPassLayout = static_cast < RenderPassLayoutImpl *> (renderPass ); 340m_framebuffer = static_cast < FramebufferImpl *> (framebuffer ); 341if (!m_framebuffer ) 342 { 343// TODO use empty framebuffer 344return ; 345 } 346 347// Create a copy of the render pass descriptor and fill in remaining information. 348m_renderPassDesc = NS ::TransferPtr (m_renderPassLayout -> m_renderPassDesc -> copy ()); 349 350m_renderPassDesc -> setRenderTargetWidth (m_framebuffer -> m_width ); 351m_renderPassDesc -> setRenderTargetHeight (m_framebuffer -> m_height ); 352 353for (Index i = 0 ;i < m_framebuffer -> m_renderTargetViews .getCount ();++ i ) 354 { 355TextureResourceViewImpl * renderTargetView = m_framebuffer -> m_renderTargetViews [i ]; 356MTL ::RenderPassColorAttachmentDescriptor * colorAttachment = 357m_renderPassDesc -> colorAttachments ()-> object (i ); 358colorAttachment -> setTexture (renderTargetView -> m_textureView .get ()); 359colorAttachment -> setLevel (renderTargetView -> m_desc .subresourceRange .mipLevel ); 360colorAttachment -> setSlice (renderTargetView -> m_desc .subresourceRange .baseArrayLayer ); 361 } 362 363if (m_framebuffer -> m_depthStencilView ) 364 { 365TextureResourceViewImpl * depthStencilView = m_framebuffer -> m_depthStencilView .get (); 366MTL ::PixelFormat pixelFormat = 367MetalUtil ::translatePixelFormat (depthStencilView -> m_desc .format ); 368if (MetalUtil ::isDepthFormat (pixelFormat )) 369 { 370MTL ::RenderPassDepthAttachmentDescriptor * depthAttachment = 371m_renderPassDesc -> depthAttachment (); 372depthAttachment -> setTexture (depthStencilView -> m_textureView .get ()); 373depthAttachment -> setLevel (depthStencilView -> m_desc .subresourceRange .mipLevel ); 374depthAttachment -> setSlice (depthStencilView -> m_desc .subresourceRange .baseArrayLayer ); 375 } 376if (MetalUtil ::isStencilFormat (pixelFormat )) 377 { 378MTL ::RenderPassStencilAttachmentDescriptor * stencilAttachment = 379m_renderPassDesc -> stencilAttachment (); 380stencilAttachment -> setTexture (depthStencilView -> m_textureView .get ()); 381stencilAttachment -> setLevel (depthStencilView -> m_desc .subresourceRange .mipLevel ); 382stencilAttachment -> setSlice (depthStencilView -> m_desc .subresourceRange .baseArrayLayer ); 383 } 384 } 385} 386 387void RenderCommandEncoder ::endEncoding () 388{ 389PipelineCommandEncoder ::endEncodingImpl (); 390} 391 392Result RenderCommandEncoder ::bindPipeline ( 393IPipelineState * pipelineState , 394IShaderObject ** outRootObject ) 395{ 396return setPipelineStateImpl (pipelineState ,outRootObject ); 397} 398 399Result RenderCommandEncoder ::bindPipelineWithRootObject ( 400IPipelineState * pipelineState , 401IShaderObject * rootObject ) 402{ 403return SLANG_E_NOT_IMPLEMENTED ; 404} 405 406void RenderCommandEncoder ::setViewports (GfxCount count ,const Viewport * viewports ) 407{ 408m_viewports .setCount (count ); 409for (GfxIndex i = 0 ;i < count ;++ i ) 410 { 411const auto & viewport = viewports [i ]; 412auto & mtlViewport = m_viewports [i ]; 413mtlViewport .originX = viewport .originX ; 414mtlViewport .originY = viewport .originY ; 415mtlViewport .width = viewport .extentX ; 416mtlViewport .height = viewport .extentY ; 417mtlViewport .znear = viewport .minZ ; 418mtlViewport .zfar = viewport .maxZ ; 419 } 420} 421 422void RenderCommandEncoder ::setScissorRects (GfxCount count ,const ScissorRect * rects ) 423{ 424m_scissorRects .setCount (count ); 425for (GfxIndex i = 0 ;i < count ;++ i ) 426 { 427const auto & rect = rects [i ]; 428auto & mtlRect = m_scissorRects [i ]; 429mtlRect .x = rect .minX ; 430mtlRect .y = rect .minY ; 431mtlRect .width = rect .maxX - rect .minX ; 432mtlRect .height = rect .maxY - rect .minY ; 433 } 434} 435 436void RenderCommandEncoder ::setPrimitiveTopology (PrimitiveTopology topology ) 437{ 438m_primitiveType = MetalUtil ::translatePrimitiveType (topology ); 439} 440 441void RenderCommandEncoder ::setVertexBuffers ( 442GfxIndex startSlot , 443GfxCount slotCount , 444IBufferResource * const * buffers , 445const Offset * offsets ) 446{ 447Index count = Math ::Max (m_vertexBuffers .getCount (),Index (startSlot + slotCount )); 448m_vertexBuffers .setCount (count ); 449m_vertexBufferOffsets .setCount (count ); 450 451for (Index i = 0 ;i < Index (slotCount );i ++ ) 452 { 453Index slotIndex = startSlot + i ; 454m_vertexBuffers [slotIndex ]= static_cast < BufferResourceImpl *> (buffers [i ])-> m_buffer .get (); 455m_vertexBufferOffsets [slotIndex ]= offsets [i ]; 456 } 457} 458 459void RenderCommandEncoder ::setIndexBuffer ( 460IBufferResource * buffer , 461Format indexFormat , 462Offset offset ) 463{ 464m_indexBuffer = static_cast < BufferResourceImpl *> (buffer )-> m_buffer .get (); 465m_indexBufferOffset = offset ; 466 467switch (indexFormat ) 468 { 469case Format ::R16_UINT : 470m_indexBufferType = MTL ::IndexTypeUInt16 ; 471break ; 472case Format ::R32_UINT : 473m_indexBufferType = MTL ::IndexTypeUInt32 ; 474break ; 475default : 476assert (!"unsupported index format" ); 477 } 478} 479 480void RenderCommandEncoder ::setStencilReference (uint32_t referenceValue ) 481{ 482m_stencilReferenceValue = referenceValue ; 483} 484 485Result RenderCommandEncoder ::setSamplePositions ( 486GfxCount samplesPerPixel , 487GfxCount pixelCount , 488const SamplePosition * samplePositions ) 489{ 490return SLANG_E_NOT_AVAILABLE ; 491} 492 493Result RenderCommandEncoder ::prepareDraw (MTL ::RenderCommandEncoder *& encoder ) 494{ 495auto pipeline = static_cast < PipelineStateImpl *> (m_currentPipeline .Ptr ()); 496pipeline -> ensureAPIPipelineStateCreated (); 497 498encoder = m_commandBuffer -> getMetalRenderCommandEncoder (m_renderPassDesc .get ()); 499encoder -> setRenderPipelineState (pipeline -> m_renderPipelineState .get ()); 500 501RenderBindingContext bindingContext ; 502bindingContext .init (m_commandBuffer -> m_device ,encoder ); 503auto program = static_cast < ShaderProgramImpl *> (m_currentPipeline -> m_program .get ()); 504m_commandBuffer -> m_rootObject .bindAsRoot (& bindingContext ,program -> m_rootObjectLayout ); 505 506for (Index i = 0 ;i < m_vertexBuffers .getCount ();++ i ) 507 { 508encoder -> setVertexBuffer ( 509m_vertexBuffers [i ], 510m_vertexBufferOffsets [i ], 511m_currentPipeline -> m_vertexBufferOffset + i ); 512 } 513 514encoder -> setViewports (m_viewports .getArrayView ().getBuffer (),m_viewports .getCount ()); 515encoder -> setScissorRects (m_scissorRects .getArrayView ().getBuffer (),m_scissorRects .getCount ()); 516 517const RasterizerDesc & rasterDesc = pipeline -> desc .graphics .rasterizer ; 518const DepthStencilDesc & depthStencilDesc = pipeline -> desc .graphics .depthStencil ; 519encoder -> setFrontFacingWinding (MetalUtil ::translateWinding (rasterDesc .frontFace )); 520encoder -> setCullMode (MetalUtil ::translateCullMode (rasterDesc .cullMode )); 521encoder -> setDepthClipMode ( 522rasterDesc .depthClipEnable ?MTL ::DepthClipModeClip 523 :MTL ::DepthClipModeClamp );// TODO correct? 524encoder -> setDepthBias ( 525rasterDesc .depthBias , 526rasterDesc .slopeScaledDepthBias , 527rasterDesc .depthBiasClamp ); 528encoder -> setTriangleFillMode (MetalUtil ::translateTriangleFillMode (rasterDesc .fillMode )); 529// encoder->setBlendColor(); // not supported by gfx 530if (m_framebuffer -> m_depthStencilView ) 531 { 532encoder -> setDepthStencilState (pipeline -> m_depthStencilState .get ()); 533 } 534encoder -> setStencilReferenceValue (m_stencilReferenceValue ); 535 536return SLANG_OK ; 537} 538 539Result RenderCommandEncoder ::draw (GfxCount vertexCount ,GfxIndex startVertex ) 540{ 541MTL ::RenderCommandEncoder * encoder ; 542SLANG_RETURN_ON_FAIL (prepareDraw (encoder )); 543encoder -> drawPrimitives (m_primitiveType ,startVertex ,vertexCount ); 544return SLANG_OK ; 545} 546 547Result RenderCommandEncoder ::drawIndexed ( 548GfxCount indexCount , 549GfxIndex startIndex , 550GfxIndex baseVertex ) 551{ 552MTL ::RenderCommandEncoder * encoder ; 553SLANG_RETURN_ON_FAIL (prepareDraw (encoder )); 554// TODO baseVertex is not supported by Metal 555encoder -> drawIndexedPrimitives ( 556m_primitiveType , 557indexCount , 558m_indexBufferType , 559m_indexBuffer , 560m_indexBufferOffset ); 561return SLANG_OK ; 562} 563 564Result RenderCommandEncoder ::drawIndirect ( 565GfxCount maxDrawCount , 566IBufferResource * argBuffer , 567Offset argOffset , 568IBufferResource * countBuffer , 569Offset countOffset ) 570{ 571return SLANG_E_NOT_IMPLEMENTED ; 572} 573 574Result RenderCommandEncoder ::drawIndexedIndirect ( 575GfxCount maxDrawCount , 576IBufferResource * argBuffer , 577Offset argOffset , 578IBufferResource * countBuffer , 579Offset countOffset ) 580{ 581return SLANG_E_NOT_IMPLEMENTED ; 582} 583 584Result RenderCommandEncoder ::drawInstanced ( 585GfxCount vertexCount , 586GfxCount instanceCount , 587GfxIndex startVertex , 588GfxIndex startInstanceLocation ) 589{ 590MTL ::RenderCommandEncoder * encoder ; 591SLANG_RETURN_ON_FAIL (prepareDraw (encoder )); 592encoder -> drawPrimitives ( 593m_primitiveType , 594startVertex , 595vertexCount , 596instanceCount , 597startInstanceLocation ); 598return SLANG_OK ; 599} 600 601Result RenderCommandEncoder ::drawIndexedInstanced ( 602GfxCount indexCount , 603GfxCount instanceCount , 604GfxIndex startIndexLocation , 605GfxIndex baseVertexLocation , 606GfxIndex startInstanceLocation ) 607{ 608MTL ::RenderCommandEncoder * encoder ; 609SLANG_RETURN_ON_FAIL (prepareDraw (encoder )); 610encoder -> drawIndexedPrimitives ( 611m_primitiveType , 612indexCount , 613m_indexBufferType , 614m_indexBuffer , 615startIndexLocation , 616instanceCount , 617baseVertexLocation , 618startIndexLocation ); 619return SLANG_OK ; 620} 621 622Result RenderCommandEncoder ::drawMeshTasks (int x ,int y ,int z ) 623{ 624return SLANG_E_NOT_IMPLEMENTED ; 625} 626 627void ComputeCommandEncoder ::endEncoding () 628{ 629ResourceCommandEncoder ::endEncoding (); 630} 631 632Result ComputeCommandEncoder ::bindPipeline ( 633IPipelineState * pipelineState , 634IShaderObject ** outRootObject ) 635{ 636return setPipelineStateImpl (pipelineState ,outRootObject ); 637} 638 639Result ComputeCommandEncoder ::bindPipelineWithRootObject ( 640IPipelineState * pipelineState , 641IShaderObject * rootObject ) 642{ 643return SLANG_E_NOT_IMPLEMENTED ; 644} 645 646Result ComputeCommandEncoder ::dispatchCompute (int x ,int y ,int z ) 647{ 648MTL ::ComputeCommandEncoder * encoder = m_commandBuffer -> getMetalComputeCommandEncoder (); 649 650ComputeBindingContext bindingContext ; 651bindingContext .init (m_commandBuffer -> m_device ,encoder ); 652auto program = static_cast < ShaderProgramImpl *> (m_currentPipeline -> m_program .get ()); 653m_commandBuffer -> m_rootObject .bindAsRoot (& bindingContext ,program -> m_rootObjectLayout ); 654 655auto pipeline = static_cast < PipelineStateImpl *> (m_currentPipeline .Ptr ()); 656RootShaderObjectImpl * rootObjectImpl = & m_commandBuffer -> m_rootObject ; 657RefPtr < PipelineStateBase > newPipeline ; 658SLANG_RETURN_ON_FAIL (m_commandBuffer -> m_device -> maybeSpecializePipeline ( 659m_currentPipeline , 660rootObjectImpl , 661newPipeline )); 662PipelineStateImpl * newPipelineImpl = static_cast < PipelineStateImpl *> (newPipeline .Ptr ()); 663 664SLANG_RETURN_ON_FAIL (newPipelineImpl -> ensureAPIPipelineStateCreated ()); 665m_currentPipeline = newPipelineImpl ; 666 667m_currentPipeline -> ensureAPIPipelineStateCreated (); 668encoder -> setComputePipelineState (m_currentPipeline -> m_computePipelineState .get ()); 669 670 671encoder -> dispatchThreadgroups (MTL ::Size (x ,y ,z ),m_currentPipeline -> m_threadGroupSize ); 672 673return SLANG_OK ; 674} 675 676Result ComputeCommandEncoder ::dispatchComputeIndirect (IBufferResource * argBuffer ,Offset offset ) 677{ 678SLANG_UNIMPLEMENTED_X ("dispatchComputeIndirect" ); 679} 680 681void RayTracingCommandEncoder ::_memoryBarrier ( 682int count , 683IAccelerationStructure * const * structures , 684AccessFlag srcAccess , 685AccessFlag destAccess ) 686{ 687} 688 689void RayTracingCommandEncoder ::_queryAccelerationStructureProperties ( 690GfxCount accelerationStructureCount , 691IAccelerationStructure * const * accelerationStructures , 692GfxCount queryCount , 693AccelerationStructureQueryDesc * queryDescs ) 694{ 695} 696 697void RayTracingCommandEncoder ::buildAccelerationStructure ( 698const IAccelerationStructure ::BuildDesc & desc , 699GfxCount propertyQueryCount , 700AccelerationStructureQueryDesc * queryDescs ) 701{ 702} 703 704void RayTracingCommandEncoder ::copyAccelerationStructure ( 705IAccelerationStructure * dest , 706IAccelerationStructure * src , 707AccelerationStructureCopyMode mode ) 708{ 709} 710 711void RayTracingCommandEncoder ::queryAccelerationStructureProperties ( 712GfxCount accelerationStructureCount , 713IAccelerationStructure * const * accelerationStructures , 714GfxCount queryCount , 715AccelerationStructureQueryDesc * queryDescs ) 716{ 717_queryAccelerationStructureProperties ( 718accelerationStructureCount , 719accelerationStructures , 720queryCount , 721queryDescs ); 722} 723 724void RayTracingCommandEncoder ::serializeAccelerationStructure ( 725DeviceAddress dest , 726IAccelerationStructure * source ) 727{ 728} 729 730void RayTracingCommandEncoder ::deserializeAccelerationStructure ( 731IAccelerationStructure * dest , 732DeviceAddress source ) 733{ 734} 735 736Result RayTracingCommandEncoder ::bindPipeline ( 737IPipelineState * pipeline , 738IShaderObject ** outRootObject ) 739{ 740return SLANG_E_NOT_IMPLEMENTED ; 741} 742 743Result RayTracingCommandEncoder ::bindPipelineWithRootObject ( 744IPipelineState * pipelineState , 745IShaderObject * rootObject ) 746{ 747return SLANG_E_NOT_IMPLEMENTED ; 748} 749 750Result RayTracingCommandEncoder ::dispatchRays ( 751GfxIndex raygenShaderIndex , 752IShaderTable * shaderTable , 753GfxCount width , 754GfxCount height , 755GfxCount depth ) 756{ 757return SLANG_E_NOT_IMPLEMENTED ; 758} 759 760void RayTracingCommandEncoder ::endEncoding () {} 761 762}// namespace metal 763}// namespace gfx