From d4145519dd86f6d18b07393d989141bda4d4ceb3 Mon Sep 17 00:00:00 2001 From: Yong He Date: Wed, 16 Feb 2022 22:34:20 -0800 Subject: Various gfx fixes. (#2132) * Various gfx fixes. * Fix test case. * Fix crash. * Trigger build * Trigger build 2 * Fix vulkan unit tests. Co-authored-by: Yong He --- tools/gfx/d3d12/render-d3d12.cpp | 2153 +++++++++++++++++++------------------- 1 file changed, 1080 insertions(+), 1073 deletions(-) (limited to 'tools/gfx/d3d12/render-d3d12.cpp') diff --git a/tools/gfx/d3d12/render-d3d12.cpp b/tools/gfx/d3d12/render-d3d12.cpp index 36ec173d7..8457889df 100644 --- a/tools/gfx/d3d12/render-d3d12.cpp +++ b/tools/gfx/d3d12/render-d3d12.cpp @@ -9,6 +9,7 @@ #include "../simple-render-pass-layout.h" #include "../d3d/d3d-swapchain.h" #include "../mutable-shader-object.h" +#include "../command-encoder-com-forward.h" #include "core/slang-blob.h" #include "core/slang-basic.h" #include "core/slang-chunked-list.h" @@ -63,8 +64,14 @@ struct ID3D12GraphicsCommandList1 {}; #define ENABLE_DEBUG_LAYER 1 namespace gfx { + using namespace Slang; +// Define function pointer types for PIX library. +typedef HRESULT(WINAPI* PFN_BeginEventOnCommandList)( + ID3D12GraphicsCommandList* commandList, UINT64 color, _In_ PCSTR formatString); +typedef HRESULT(WINAPI* PFN_EndEventOnCommandList)(ID3D12GraphicsCommandList* commandList); + class D3D12Device : public RendererBase { public: @@ -3600,1233 +3607,1245 @@ public: m_cmdList->QueryInterface(m_cmdList1.writeRef()); } - class RenderCommandEncoderImpl - : public IRenderCommandEncoder + + class ResourceCommandEncoderImpl + : public IResourceCommandEncoder , public PipelineCommandEncoder { public: - RefPtr m_renderPass; - RefPtr m_framebuffer; - - List m_boundVertexBuffers; - - RefPtr m_boundIndexBuffer; - - D3D12_VIEWPORT m_viewports[kMaxRTVCount]; - D3D12_RECT m_scissorRects[kMaxRTVCount]; - - DXGI_FORMAT m_boundIndexFormat; - UINT m_boundIndexOffset; - - D3D12_PRIMITIVE_TOPOLOGY_TYPE m_primitiveTopologyType; - D3D12_PRIMITIVE_TOPOLOGY m_primitiveTopology; - - void init( - D3D12Device* renderer, - TransientResourceHeapImpl* transientHeap, - CommandBufferImpl* cmdBuffer, - RenderPassLayoutImpl* renderPass, - FramebufferImpl* framebuffer) + virtual SLANG_NO_THROW void SLANG_MCALL copyBuffer( + IBufferResource* dst, + size_t dstOffset, + IBufferResource* src, + size_t srcOffset, + size_t size) override { - PipelineCommandEncoder::init(cmdBuffer); - m_preCmdList = nullptr; - m_renderPass = renderPass; - m_framebuffer = framebuffer; - m_transientHeap = transientHeap; - m_boundVertexBuffers.clear(); - m_boundIndexBuffer = nullptr; - m_primitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; - m_primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; - m_boundIndexFormat = DXGI_FORMAT_UNKNOWN; - m_boundIndexOffset = 0; - m_currentPipeline = nullptr; + auto dstBuffer = static_cast(dst); + auto srcBuffer = static_cast(src); - // Set render target states. - if (!framebuffer) - { - return; - } - m_d3dCmdList->OMSetRenderTargets( - (UINT)framebuffer->renderTargetViews.getCount(), - framebuffer->renderTargetDescriptors.getArrayView().getBuffer(), - FALSE, - framebuffer->depthStencilView ? &framebuffer->depthStencilDescriptor : nullptr); + m_commandBuffer->m_cmdList->CopyBufferRegion( + dstBuffer->m_resource.getResource(), + dstOffset, + srcBuffer->m_resource.getResource(), + srcOffset, + size); + } + virtual SLANG_NO_THROW void SLANG_MCALL uploadBufferData( + IBufferResource* dst, size_t offset, size_t size, void* data) override + { + _uploadBufferData( + m_commandBuffer->m_renderer->m_device, + m_commandBuffer->m_cmdList, + m_commandBuffer->m_transientHeap, + static_cast(dst), + offset, + size, + data); + } + virtual SLANG_NO_THROW void SLANG_MCALL textureBarrier( + size_t count, + ITextureResource* const* textures, + ResourceState src, + ResourceState dst) override + { + ShortList barriers; - // Issue clear commands based on render pass set up. - for (Index i = 0; i < framebuffer->renderTargetViews.getCount(); i++) + for (size_t i = 0; i < count; i++) { - if (i >= renderPass->m_renderTargetAccesses.getCount()) - continue; - - auto& access = renderPass->m_renderTargetAccesses[i]; - - // Transit resource states. + auto textureImpl = static_cast(textures[i]); + auto d3dFormat = D3DUtil::getMapFormat(textureImpl->getDesc()->format); + auto textureDesc = textureImpl->getDesc(); + D3D12_RESOURCE_BARRIER barrier; + barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + if (src == dst && src == ResourceState::UnorderedAccess) { - D3D12BarrierSubmitter submitter(m_d3dCmdList); - auto resourceViewImpl = framebuffer->renderTargetViews[i].Ptr(); - if (resourceViewImpl) + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; + barrier.UAV.pResource = textureImpl->m_resource.getResource(); + } + else + { + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Transition.StateBefore = D3DUtil::getResourceState(src); + barrier.Transition.StateAfter = D3DUtil::getResourceState(dst); + if (barrier.Transition.StateBefore == barrier.Transition.StateAfter) + continue; + barrier.Transition.pResource = textureImpl->m_resource.getResource(); + auto planeCount = D3DUtil::getPlaneSliceCount( + D3DUtil::getMapFormat(textureImpl->getDesc()->format)); + auto arraySize = textureDesc->arraySize; + if (arraySize == 0) + arraySize = 1; + for (uint32_t planeIndex = 0; planeIndex < planeCount; planeIndex++) { - auto textureResource = static_cast( - resourceViewImpl->m_resource.Ptr()); - if (textureResource) + for (int layer = 0; layer < arraySize; layer++) { - D3D12_RESOURCE_STATES initialState; - if (access.initialState == ResourceState::Undefined) - { - initialState = textureResource->m_defaultState; - } - else + for (int mip = 0; mip < textureDesc->numMipLevels; mip++) { - initialState = D3DUtil::getResourceState(access.initialState); + barrier.Transition.Subresource = D3DUtil::getSubresourceIndex( + mip, + layer, + planeIndex, + textureImpl->getDesc()->numMipLevels, + arraySize); + barriers.add(barrier); } - textureResource->m_resource.transition( - initialState, D3D12_RESOURCE_STATE_RENDER_TARGET, submitter); } } } - // Clear. - if (access.loadOp == IRenderPassLayout::AttachmentLoadOp::Clear) - { - m_d3dCmdList->ClearRenderTargetView( - framebuffer->renderTargetDescriptors[i], - framebuffer->renderTargetClearValues[i].values, - 0, - nullptr); - } } + if (barriers.getCount()) + { + m_commandBuffer->m_cmdList->ResourceBarrier( + (UINT)barriers.getCount(), barriers.getArrayView().getBuffer()); + } + } + virtual SLANG_NO_THROW void SLANG_MCALL bufferBarrier( + size_t count, + IBufferResource* const* buffers, + ResourceState src, + ResourceState dst) override + { - if (renderPass->m_hasDepthStencil) + List barriers; + barriers.reserve(count); + + for (size_t i = 0; i < count; i++) { - // Transit resource states. - { - D3D12BarrierSubmitter submitter(m_d3dCmdList); - auto resourceViewImpl = framebuffer->depthStencilView.Ptr(); - auto textureResource = - static_cast(resourceViewImpl->m_resource.Ptr()); - D3D12_RESOURCE_STATES initialState; - if (renderPass->m_depthStencilAccess.initialState == - ResourceState::Undefined) - { - initialState = textureResource->m_defaultState; - } - else - { - initialState = D3DUtil::getResourceState( - renderPass->m_depthStencilAccess.initialState); - } - textureResource->m_resource.transition( - initialState, - D3D12_RESOURCE_STATE_DEPTH_WRITE, - submitter); - } - // Clear. - uint32_t clearFlags = 0; - if (renderPass->m_depthStencilAccess.loadOp == - IRenderPassLayout::AttachmentLoadOp::Clear) - { - clearFlags |= D3D12_CLEAR_FLAG_DEPTH; - } - if (renderPass->m_depthStencilAccess.stencilLoadOp == - IRenderPassLayout::AttachmentLoadOp::Clear) + auto bufferImpl = static_cast(buffers[i]); + + D3D12_RESOURCE_BARRIER barrier = {}; + // If the src == dst, it must be a UAV barrier. + barrier.Type = (src == dst && dst == ResourceState::UnorderedAccess) + ? D3D12_RESOURCE_BARRIER_TYPE_UAV + : D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + + if (barrier.Type == D3D12_RESOURCE_BARRIER_TYPE_UAV) { - clearFlags |= D3D12_CLEAR_FLAG_STENCIL; + barrier.UAV.pResource = bufferImpl->m_resource; } - if (clearFlags) + else { - m_d3dCmdList->ClearDepthStencilView( - framebuffer->depthStencilDescriptor, - (D3D12_CLEAR_FLAGS)clearFlags, - framebuffer->depthStencilClearValue.depth, - framebuffer->depthStencilClearValue.stencil, - 0, - nullptr); + barrier.Transition.pResource = bufferImpl->m_resource; + barrier.Transition.StateBefore = D3DUtil::getResourceState(src); + barrier.Transition.StateAfter = D3DUtil::getResourceState(dst); + barrier.Transition.Subresource = 0; + if (barrier.Transition.StateAfter == barrier.Transition.StateBefore) + continue; } + barriers.add(barrier); } - } - - virtual SLANG_NO_THROW Result SLANG_MCALL - bindPipeline(IPipelineState* state, IShaderObject** outRootObject) override - { - return bindPipelineImpl(state, outRootObject); - } - - virtual SLANG_NO_THROW void SLANG_MCALL - setViewports(uint32_t count, const Viewport* viewports) override - { - static const int kMaxViewports = - D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; - assert(count <= kMaxViewports && count <= kMaxRTVCount); - for (UInt ii = 0; ii < count; ++ii) + if (barriers.getCount()) { - auto& inViewport = viewports[ii]; - auto& dxViewport = m_viewports[ii]; - - dxViewport.TopLeftX = inViewport.originX; - dxViewport.TopLeftY = inViewport.originY; - dxViewport.Width = inViewport.extentX; - dxViewport.Height = inViewport.extentY; - dxViewport.MinDepth = inViewport.minZ; - dxViewport.MaxDepth = inViewport.maxZ; + m_commandBuffer->m_cmdList4->ResourceBarrier( + (UINT)barriers.getCount(), barriers.getArrayView().getBuffer()); } - m_d3dCmdList->RSSetViewports(UINT(count), m_viewports); } - + virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() {} virtual SLANG_NO_THROW void SLANG_MCALL - setScissorRects(uint32_t count, const ScissorRect* rects) override + writeTimestamp(IQueryPool* pool, SlangInt index) override { - static const int kMaxScissorRects = - D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; - assert(count <= kMaxScissorRects && count <= kMaxRTVCount); - - for (UInt ii = 0; ii < count; ++ii) - { - auto& inRect = rects[ii]; - auto& dxRect = m_scissorRects[ii]; - - dxRect.left = LONG(inRect.minX); - dxRect.top = LONG(inRect.minY); - dxRect.right = LONG(inRect.maxX); - dxRect.bottom = LONG(inRect.maxY); - } - - m_d3dCmdList->RSSetScissorRects(UINT(count), m_scissorRects); + static_cast(pool)->writeTimestamp( + m_commandBuffer->m_cmdList, index); } - - virtual SLANG_NO_THROW void SLANG_MCALL - setPrimitiveTopology(PrimitiveTopology topology) override + virtual SLANG_NO_THROW void SLANG_MCALL copyTexture( + ITextureResource* dst, + ResourceState dstState, + SubresourceRange dstSubresource, + ITextureResource::Offset3D dstOffset, + ITextureResource* src, + ResourceState srcState, + SubresourceRange srcSubresource, + ITextureResource::Offset3D srcOffset, + ITextureResource::Size extent) override { - m_primitiveTopologyType = D3DUtil::getPrimitiveType(topology); - m_primitiveTopology = D3DUtil::getPrimitiveTopology(topology); - } + auto dstTexture = static_cast(dst); + auto srcTexture = static_cast(src); - virtual SLANG_NO_THROW void SLANG_MCALL setVertexBuffers( - uint32_t startSlot, - uint32_t slotCount, - IBufferResource* const* buffers, - const uint32_t* offsets) override - { + if (dstSubresource.layerCount == 0 && dstSubresource.mipLevelCount == 0 && + srcSubresource.layerCount == 0 && srcSubresource.mipLevelCount == 0) { - const Index num = startSlot + slotCount; - if (num > m_boundVertexBuffers.getCount()) - { - m_boundVertexBuffers.setCount(num); - } + m_commandBuffer->m_cmdList->CopyResource( + dstTexture->m_resource.getResource(), srcTexture->m_resource.getResource()); + return; } - for (UInt i = 0; i < slotCount; i++) + auto d3dFormat = D3DUtil::getMapFormat(dstTexture->getDesc()->format); + auto aspectMask = (int32_t)dstSubresource.aspectMask; + if (dstSubresource.aspectMask == TextureAspect::Default) + aspectMask = (int32_t)TextureAspect::Color; + while (aspectMask) { - BufferResourceImpl* buffer = static_cast(buffers[i]); + auto aspect = Math::getLowestBit((int32_t)aspectMask); + aspectMask &= ~aspect; + auto planeIndex = D3DUtil::getPlaneSlice(d3dFormat, (TextureAspect)aspect); + for (uint32_t layer = 0; layer < dstSubresource.layerCount; layer++) + { + for (uint32_t mipLevel = 0; mipLevel < dstSubresource.mipLevelCount; + mipLevel++) + { + D3D12_TEXTURE_COPY_LOCATION dstRegion = {}; - BoundVertexBuffer& boundBuffer = m_boundVertexBuffers[startSlot + i]; - boundBuffer.m_buffer = buffer; - boundBuffer.m_offset = int(offsets[i]); - } - } + dstRegion.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + dstRegion.pResource = dstTexture->m_resource.getResource(); + dstRegion.SubresourceIndex = D3DUtil::getSubresourceIndex( + dstSubresource.mipLevel + mipLevel, + dstSubresource.baseArrayLayer + layer, + planeIndex, + dstTexture->getDesc()->numMipLevels, + dstTexture->getDesc()->arraySize); - virtual SLANG_NO_THROW void SLANG_MCALL setIndexBuffer( - IBufferResource* buffer, Format indexFormat, uint32_t offset = 0) override - { - m_boundIndexBuffer = (BufferResourceImpl*)buffer; - m_boundIndexFormat = D3DUtil::getMapFormat(indexFormat); - m_boundIndexOffset = offset; + D3D12_TEXTURE_COPY_LOCATION srcRegion = {}; + srcRegion.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + srcRegion.pResource = srcTexture->m_resource.getResource(); + srcRegion.SubresourceIndex = D3DUtil::getSubresourceIndex( + srcSubresource.mipLevel + mipLevel, + srcSubresource.baseArrayLayer + layer, + planeIndex, + srcTexture->getDesc()->numMipLevels, + srcTexture->getDesc()->arraySize); + + D3D12_BOX srcBox = {}; + srcBox.left = srcOffset.x; + srcBox.top = srcOffset.y; + srcBox.front = srcOffset.z; + srcBox.right = srcBox.left + extent.width; + srcBox.bottom = srcBox.top + extent.height; + srcBox.back = srcBox.front + extent.depth; + + m_commandBuffer->m_cmdList->CopyTextureRegion( + &dstRegion, + dstOffset.x, + dstOffset.y, + dstOffset.z, + &srcRegion, + &srcBox); + } + } + } } - void prepareDraw() + virtual SLANG_NO_THROW void SLANG_MCALL uploadTextureData( + ITextureResource* dst, + SubresourceRange subResourceRange, + ITextureResource::Offset3D offset, + ITextureResource::Size extent, + ITextureResource::SubresourceData* subResourceData, + size_t subResourceDataCount) override { - auto pipelineState = m_currentPipeline.Ptr(); - if (!pipelineState || (pipelineState->desc.type != PipelineType::Graphics)) + auto dstTexture = static_cast(dst); + auto baseSubresourceIndex = D3DUtil::getSubresourceIndex( + subResourceRange.mipLevel, + subResourceRange.baseArrayLayer, + 0, + dstTexture->getDesc()->numMipLevels, + dstTexture->getDesc()->arraySize); + auto textureSize = dstTexture->getDesc()->size; + FormatInfo formatInfo = {}; + gfxGetFormatInfo(dstTexture->getDesc()->format, &formatInfo); + for (uint32_t i = 0; i < (uint32_t)subResourceDataCount; i++) { - assert(!"No graphics pipeline state set"); - return; - } + auto subresourceIndex = baseSubresourceIndex + i; + // Get the footprint + D3D12_RESOURCE_DESC texDesc = dstTexture->m_resource.getResource()->GetDesc(); - // Submit - setting for graphics - { - GraphicsSubmitter submitter(m_d3dCmdList); - RefPtr newPipeline; - if(SLANG_FAILED(_bindRenderState(&submitter, newPipeline))) + D3D12_TEXTURE_COPY_LOCATION dstRegion = {}; + + dstRegion.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + dstRegion.SubresourceIndex = subresourceIndex; + dstRegion.pResource = dstTexture->m_resource.getResource(); + + D3D12_TEXTURE_COPY_LOCATION srcRegion = {}; + srcRegion.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + D3D12_PLACED_SUBRESOURCE_FOOTPRINT& footprint = srcRegion.PlacedFootprint; + + footprint.Offset = 0; + footprint.Footprint.Format = texDesc.Format; + uint32_t mipLevel = D3DUtil::getSubresourceMipLevel( + subresourceIndex, dstTexture->getDesc()->numMipLevels); + if (extent.width != ITextureResource::kRemainingTextureSize) { - assert(!"Failed to bind render state"); + footprint.Footprint.Width = extent.width; } - } + else + { + footprint.Footprint.Width = + Math::Max(1, (textureSize.width >> mipLevel)) - offset.x; + } + if (extent.height != ITextureResource::kRemainingTextureSize) + { + footprint.Footprint.Height = extent.height; + } + else + { + footprint.Footprint.Height = + Math::Max(1, (textureSize.height >> mipLevel)) - offset.y; + } + if (extent.depth != ITextureResource::kRemainingTextureSize) + { + footprint.Footprint.Depth = extent.depth; + } + else + { + footprint.Footprint.Depth = + Math::Max(1, (textureSize.depth >> mipLevel)) - offset.z; + } + auto rowSize = (footprint.Footprint.Width + formatInfo.blockWidth - 1) / + formatInfo.blockWidth * formatInfo.blockSizeInBytes; + auto rowCount = (footprint.Footprint.Height + formatInfo.blockHeight - 1) / + formatInfo.blockHeight; + footprint.Footprint.RowPitch = (UINT)D3DUtil::calcAligned( + rowSize, (uint32_t)D3D12_TEXTURE_DATA_PITCH_ALIGNMENT); - m_d3dCmdList->IASetPrimitiveTopology(m_primitiveTopology); + auto bufferSize = + footprint.Footprint.RowPitch * rowCount * footprint.Footprint.Depth; - // Set up vertex buffer views - { - auto inputLayout = (InputLayoutImpl*)pipelineState->inputLayout.Ptr(); - if (inputLayout) + IBufferResource* stagingBuffer; + m_commandBuffer->m_transientHeap->allocateStagingBuffer( + bufferSize, stagingBuffer, ResourceState::General); + + BufferResourceImpl* bufferImpl = + static_cast(stagingBuffer); + uint8_t* bufferData = nullptr; + D3D12_RANGE mapRange = {0, 0}; + bufferImpl->m_resource.getResource()->Map(0, &mapRange, (void**)&bufferData); + for (uint32_t z = 0; z < footprint.Footprint.Depth; z++) { - int numVertexViews = 0; - D3D12_VERTEX_BUFFER_VIEW vertexViews[16]; - for (Index i = 0; i < m_boundVertexBuffers.getCount(); i++) + auto imageStart = + bufferData + footprint.Footprint.RowPitch * rowCount * (size_t)z; + auto srcData = + (uint8_t*)subResourceData->data + subResourceData->strideZ * z; + for (uint32_t row = 0; row < rowCount; row++) { - const BoundVertexBuffer& boundVertexBuffer = m_boundVertexBuffers[i]; - BufferResourceImpl* buffer = boundVertexBuffer.m_buffer; - if (buffer) - { - D3D12_VERTEX_BUFFER_VIEW& vertexView = - vertexViews[numVertexViews++]; - vertexView.BufferLocation = - buffer->m_resource.getResource()->GetGPUVirtualAddress() + - boundVertexBuffer.m_offset; - vertexView.SizeInBytes = UINT( - buffer->getDesc()->sizeInBytes - boundVertexBuffer.m_offset); - vertexView.StrideInBytes = inputLayout->m_vertexStreamStrides[i]; - } + memcpy( + imageStart + row * (size_t)footprint.Footprint.RowPitch, + srcData + subResourceData->strideY * row, + rowSize); } - m_d3dCmdList->IASetVertexBuffers(0, numVertexViews, vertexViews); } - } - // Set up index buffer - if (m_boundIndexBuffer) - { - D3D12_INDEX_BUFFER_VIEW indexBufferView; - indexBufferView.BufferLocation = - m_boundIndexBuffer->m_resource.getResource()->GetGPUVirtualAddress() + - m_boundIndexOffset; - indexBufferView.SizeInBytes = - UINT(m_boundIndexBuffer->getDesc()->sizeInBytes - m_boundIndexOffset); - indexBufferView.Format = m_boundIndexFormat; + bufferImpl->m_resource.getResource()->Unmap(0, nullptr); - m_d3dCmdList->IASetIndexBuffer(&indexBufferView); + srcRegion.pResource = bufferImpl->m_resource.getResource(); + + m_commandBuffer->m_cmdList->CopyTextureRegion( + &dstRegion, offset.x, offset.y, offset.z, &srcRegion, nullptr); } } - virtual SLANG_NO_THROW void SLANG_MCALL - draw(uint32_t vertexCount, uint32_t startVertex = 0) override + + virtual SLANG_NO_THROW void SLANG_MCALL clearResourceView( + IResourceView* view, + ClearValue* clearValue, + ClearResourceViewFlags::Enum flags) override { - prepareDraw(); - m_d3dCmdList->DrawInstanced(vertexCount, 1, startVertex, 0); - } - virtual SLANG_NO_THROW void SLANG_MCALL drawIndexed( - uint32_t indexCount, uint32_t startIndex = 0, uint32_t baseVertex = 0) override - { - prepareDraw(); - m_d3dCmdList->DrawIndexedInstanced(indexCount, 1, startIndex, baseVertex, 0); - } - virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override - { - PipelineCommandEncoder::endEncodingImpl(); - if (!m_framebuffer) - return; - // Issue clear commands based on render pass set up. - for (Index i = 0; i < m_renderPass->m_renderTargetAccesses.getCount(); i++) + auto viewImpl = static_cast(view); + switch (view->getViewDesc()->type) { - auto& access = m_renderPass->m_renderTargetAccesses[i]; - - // Transit resource states. + case IResourceView::Type::RenderTarget: + m_commandBuffer->m_cmdList->ClearRenderTargetView( + viewImpl->m_descriptor.cpuHandle, + clearValue->color.floatValues, + 0, + nullptr); + break; + case IResourceView::Type::DepthStencil: { - D3D12BarrierSubmitter submitter(m_d3dCmdList); - auto resourceViewImpl = m_framebuffer->renderTargetViews[i].Ptr(); - if (!resourceViewImpl) - continue; - auto textureResource = - static_cast(resourceViewImpl->m_resource.Ptr()); - if (textureResource) + D3D12_CLEAR_FLAGS clearFlags = (D3D12_CLEAR_FLAGS)0; + if (flags & ClearResourceViewFlags::ClearDepth) { - textureResource->m_resource.transition( - D3D12_RESOURCE_STATE_RENDER_TARGET, - D3DUtil::getResourceState(access.finalState), - submitter); + clearFlags |= D3D12_CLEAR_FLAG_DEPTH; + } + if (flags & ClearResourceViewFlags::ClearStencil) + { + clearFlags |= D3D12_CLEAR_FLAG_STENCIL; } + m_commandBuffer->m_cmdList->ClearDepthStencilView( + viewImpl->m_descriptor.cpuHandle, + clearFlags, + clearValue->depthStencil.depth, + (UINT8)clearValue->depthStencil.stencil, + 0, + nullptr); + break; } - } + case IResourceView::Type::UnorderedAccess: + { + ID3D12Resource* d3dResource = nullptr; + switch (viewImpl->m_resource->getType()) + { + case IResource::Type::Buffer: + d3dResource = + static_cast(viewImpl->m_resource.Ptr()) + ->m_resource.getResource(); + break; + default: + d3dResource = + static_cast(viewImpl->m_resource.Ptr()) + ->m_resource.getResource(); + break; + } + auto gpuHandleIndex = + m_commandBuffer->m_transientHeap->getCurrentViewHeap().allocate(1); + if (gpuHandleIndex == -1) + { + m_commandBuffer->m_transientHeap->allocateNewViewDescriptorHeap( + m_commandBuffer->m_renderer); + gpuHandleIndex = + m_commandBuffer->m_transientHeap->getCurrentViewHeap().allocate(1); + auto d3dViewHeap = + m_commandBuffer->m_transientHeap->getCurrentViewHeap().getHeap(); + m_commandBuffer->bindDescriptorHeaps(); + } + this->m_commandBuffer->m_renderer->m_device->CopyDescriptorsSimple( + 1, + m_commandBuffer->m_transientHeap->getCurrentViewHeap().getCpuHandle( + gpuHandleIndex), + viewImpl->m_descriptor.cpuHandle, + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - if (m_renderPass->m_hasDepthStencil) - { - // Transit resource states. - D3D12BarrierSubmitter submitter(m_d3dCmdList); - auto resourceViewImpl = m_framebuffer->depthStencilView.Ptr(); - auto textureResource = - static_cast(resourceViewImpl->m_resource.Ptr()); - textureResource->m_resource.transition( - D3D12_RESOURCE_STATE_DEPTH_WRITE, - D3DUtil::getResourceState( - m_renderPass->m_depthStencilAccess.finalState), - submitter); + if (flags & ClearResourceViewFlags::FloatClearValues) + { + m_commandBuffer->m_cmdList->ClearUnorderedAccessViewFloat( + m_commandBuffer->m_transientHeap->getCurrentViewHeap().getGpuHandle( + gpuHandleIndex), + viewImpl->m_descriptor.cpuHandle, + d3dResource, + clearValue->color.floatValues, + 0, + nullptr); + } + else + { + m_commandBuffer->m_cmdList->ClearUnorderedAccessViewUint( + m_commandBuffer->m_transientHeap->getCurrentViewHeap().getGpuHandle( + gpuHandleIndex), + viewImpl->m_descriptor.cpuHandle, + d3dResource, + clearValue->color.uintValues, + 0, + nullptr); + } + break; + } + default: + break; } - m_framebuffer = nullptr; - } - - virtual SLANG_NO_THROW void SLANG_MCALL writeTimestamp(IQueryPool* pool, SlangInt index) override - { - static_cast(pool)->writeTimestamp(m_d3dCmdList, index); } - virtual SLANG_NO_THROW void SLANG_MCALL - setStencilReference(uint32_t referenceValue) override + virtual SLANG_NO_THROW void SLANG_MCALL resolveResource( + ITextureResource* source, + ResourceState sourceState, + SubresourceRange sourceRange, + ITextureResource* dest, + ResourceState destState, + SubresourceRange destRange) override { - m_d3dCmdList->OMSetStencilRef((UINT)referenceValue); - } + auto srcTexture = static_cast(source); + auto srcDesc = srcTexture->getDesc(); + auto dstTexture = static_cast(dest); + auto dstDesc = dstTexture->getDesc(); - virtual SLANG_NO_THROW void SLANG_MCALL drawIndirect( - uint32_t maxDrawCount, - IBufferResource* argBuffer, - uint64_t argOffset, - IBufferResource* countBuffer, - uint64_t countOffset) override - { - prepareDraw(); + for (uint32_t layer = 0; layer < sourceRange.layerCount; ++layer) + { + for (uint32_t mip = 0; mip < sourceRange.mipLevelCount; ++mip) + { + auto srcSubresourceIndex = D3DUtil::getSubresourceIndex( + mip + sourceRange.mipLevel, + layer + sourceRange.baseArrayLayer, + 0, + srcDesc->numMipLevels, + srcDesc->arraySize); + auto dstSubresourceIndex = D3DUtil::getSubresourceIndex( + mip + destRange.mipLevel, + layer + destRange.baseArrayLayer, + 0, + dstDesc->numMipLevels, + dstDesc->arraySize); - auto argBufferImpl = static_cast(argBuffer); - auto countBufferImpl = static_cast(countBuffer); + DXGI_FORMAT format = D3DUtil::getMapFormat(srcDesc->format); - m_d3dCmdList->ExecuteIndirect( - m_renderer->drawIndirectCmdSignature, - maxDrawCount, - argBufferImpl->m_resource, - argOffset, - countBufferImpl ? countBufferImpl->m_resource.getResource() : nullptr, - countOffset); + m_commandBuffer->m_cmdList->ResolveSubresource( + dstTexture->m_resource.getResource(), + dstSubresourceIndex, + srcTexture->m_resource.getResource(), + srcSubresourceIndex, + format); + } + } } - virtual SLANG_NO_THROW void SLANG_MCALL drawIndexedIndirect( - uint32_t maxDrawCount, - IBufferResource* argBuffer, - uint64_t argOffset, - IBufferResource* countBuffer, - uint64_t countOffset) override + virtual SLANG_NO_THROW void SLANG_MCALL resolveQuery( + IQueryPool* queryPool, + uint32_t index, + uint32_t count, + IBufferResource* buffer, + uint64_t offset) override { - prepareDraw(); + auto queryBase = static_cast(queryPool); + switch (queryBase->m_desc.type) + { + case QueryType::AccelerationStructureCompactedSize: + case QueryType::AccelerationStructureCurrentSize: + case QueryType::AccelerationStructureSerializedSize: + { + auto queryPoolImpl = static_cast(queryPool); + auto bufferImpl = static_cast(buffer); + auto srcQueryBuffer = + queryPoolImpl->m_bufferResource->m_resource.getResource(); - auto argBufferImpl = static_cast(argBuffer); - auto countBufferImpl = static_cast(countBuffer); + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_UNORDERED_ACCESS; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE; + barrier.Transition.pResource = srcQueryBuffer; + m_commandBuffer->m_cmdList->ResourceBarrier(1, &barrier); - m_d3dCmdList->ExecuteIndirect( - m_renderer->drawIndexedIndirectCmdSignature, - maxDrawCount, - argBufferImpl->m_resource, - argOffset, - countBufferImpl ? countBufferImpl->m_resource.getResource() : nullptr, - countOffset); - } + m_commandBuffer->m_cmdList->CopyBufferRegion( + bufferImpl->m_resource.getResource(), + offset, + srcQueryBuffer, + index * sizeof(uint64_t), + count * sizeof(uint64_t)); - virtual SLANG_NO_THROW Result SLANG_MCALL setSamplePositions( - uint32_t samplesPerPixel, - uint32_t pixelCount, - const SamplePosition* samplePositions) override - { - if (m_commandBuffer->m_cmdList1) - { - m_commandBuffer->m_cmdList1->SetSamplePositions( - samplesPerPixel, pixelCount, (D3D12_SAMPLE_POSITION*)samplePositions); - return SLANG_OK; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_SOURCE; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_UNORDERED_ACCESS; + barrier.Transition.pResource = srcQueryBuffer; + m_commandBuffer->m_cmdList->ResourceBarrier(1, &barrier); + } + break; + default: + { + auto queryPoolImpl = static_cast(queryPool); + auto bufferImpl = static_cast(buffer); + m_commandBuffer->m_cmdList->ResolveQueryData( + queryPoolImpl->m_queryHeap.get(), + queryPoolImpl->m_queryType, + index, + count, + bufferImpl->m_resource.getResource(), + offset); + } + break; } - return SLANG_E_NOT_AVAILABLE; } - virtual SLANG_NO_THROW void SLANG_MCALL drawInstanced( - uint32_t vertexCount, - uint32_t instanceCount, - uint32_t startVertex, - uint32_t startInstanceLocation) override + virtual SLANG_NO_THROW void SLANG_MCALL copyTextureToBuffer( + IBufferResource* dst, + size_t dstOffset, + size_t dstSize, + ITextureResource* src, + ResourceState srcState, + SubresourceRange srcSubresource, + ITextureResource::Offset3D srcOffset, + ITextureResource::Size extent) override { - prepareDraw(); - m_d3dCmdList->DrawInstanced( - vertexCount, instanceCount, startVertex, startInstanceLocation); - } + assert(srcSubresource.mipLevelCount <= 1); - virtual SLANG_NO_THROW void SLANG_MCALL drawIndexedInstanced( - uint32_t indexCount, - uint32_t instanceCount, - uint32_t startIndexLocation, - int32_t baseVertexLocation, - uint32_t startInstanceLocation) override - { - prepareDraw(); - m_d3dCmdList->DrawIndexedInstanced(indexCount, instanceCount, startIndexLocation, baseVertexLocation, startInstanceLocation); - } - }; + auto srcTexture = static_cast(src); + auto dstBuffer = static_cast(dst); + auto baseSubresourceIndex = D3DUtil::getSubresourceIndex( + srcSubresource.mipLevel, + srcSubresource.baseArrayLayer, + 0, + srcTexture->getDesc()->numMipLevels, + srcTexture->getDesc()->arraySize); + auto textureSize = srcTexture->getDesc()->size; + FormatInfo formatInfo = {}; + gfxGetFormatInfo(srcTexture->getDesc()->format, &formatInfo); + if (srcSubresource.mipLevelCount == 0) + srcSubresource.mipLevelCount = srcTexture->getDesc()->numMipLevels; + if (srcSubresource.layerCount == 0) + srcSubresource.layerCount = srcTexture->getDesc()->arraySize; - RenderCommandEncoderImpl m_renderCommandEncoder; - virtual SLANG_NO_THROW void SLANG_MCALL encodeRenderCommands( - IRenderPassLayout* renderPass, - IFramebuffer* framebuffer, - IRenderCommandEncoder** outEncoder) override - { - m_renderCommandEncoder.init( - m_renderer, - m_transientHeap, - this, - static_cast(renderPass), - static_cast(framebuffer)); - *outEncoder = &m_renderCommandEncoder; - } + for (uint32_t layer = 0; layer < srcSubresource.layerCount; layer++) + { + // Get the footprint + D3D12_RESOURCE_DESC texDesc = srcTexture->m_resource.getResource()->GetDesc(); - class ComputeCommandEncoderImpl - : public IComputeCommandEncoder - , public PipelineCommandEncoder - { - public: - virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override - { - PipelineCommandEncoder::endEncodingImpl(); - } - virtual SLANG_NO_THROW void SLANG_MCALL writeTimestamp(IQueryPool* pool, SlangInt index) override - { - static_cast(pool)->writeTimestamp(m_d3dCmdList, index); - } - void init( - D3D12Device* renderer, - TransientResourceHeapImpl* transientHeap, - CommandBufferImpl* cmdBuffer) - { - PipelineCommandEncoder::init(cmdBuffer); - m_preCmdList = nullptr; - m_transientHeap = transientHeap; - m_currentPipeline = nullptr; - } + D3D12_TEXTURE_COPY_LOCATION dstRegion = {}; + dstRegion.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + dstRegion.pResource = dstBuffer->m_resource.getResource(); + D3D12_PLACED_SUBRESOURCE_FOOTPRINT& footprint = dstRegion.PlacedFootprint; - virtual SLANG_NO_THROW Result SLANG_MCALL - bindPipeline(IPipelineState* state, IShaderObject** outRootObject) override - { - return bindPipelineImpl(state, outRootObject); + D3D12_TEXTURE_COPY_LOCATION srcRegion = {}; + srcRegion.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + srcRegion.SubresourceIndex = D3DUtil::getSubresourceIndex( + srcSubresource.mipLevel, + layer + srcSubresource.baseArrayLayer, + 0, + srcTexture->getDesc()->numMipLevels, + srcTexture->getDesc()->arraySize); + srcRegion.pResource = srcTexture->m_resource.getResource(); + + footprint.Offset = dstOffset; + footprint.Footprint.Format = texDesc.Format; + uint32_t mipLevel = srcSubresource.mipLevel; + if (extent.width != 0xFFFFFFFF) + { + footprint.Footprint.Width = extent.width; + } + else + { + footprint.Footprint.Width = + Math::Max(1, (textureSize.width >> mipLevel)) - srcOffset.x; + } + if (extent.height != 0xFFFFFFFF) + { + footprint.Footprint.Height = extent.height; + } + else + { + footprint.Footprint.Height = + Math::Max(1, (textureSize.height >> mipLevel)) - srcOffset.y; + } + if (extent.depth != 0xFFFFFFFF) + { + footprint.Footprint.Depth = extent.depth; + } + else + { + footprint.Footprint.Depth = + Math::Max(1, (textureSize.depth >> mipLevel)) - srcOffset.z; + } + footprint.Footprint.RowPitch = (UINT)D3DUtil::calcAligned( + footprint.Footprint.Width * (UInt)formatInfo.blockSizeInBytes, + (uint32_t)D3D12_TEXTURE_DATA_PITCH_ALIGNMENT); + + auto bufferSize = footprint.Footprint.RowPitch * footprint.Footprint.Height * + footprint.Footprint.Depth; + + D3D12_BOX srcBox = {}; + srcBox.left = srcOffset.x; + srcBox.top = srcOffset.y; + srcBox.front = srcOffset.z; + srcBox.right = srcOffset.x + extent.width; + srcBox.bottom = srcOffset.y + extent.height; + srcBox.back = srcOffset.z + extent.depth; + m_commandBuffer->m_cmdList->CopyTextureRegion( + &dstRegion, 0, 0, 0, &srcRegion, &srcBox); + } } - virtual SLANG_NO_THROW void SLANG_MCALL dispatchCompute(int x, int y, int z) override + virtual SLANG_NO_THROW void SLANG_MCALL textureSubresourceBarrier( + ITextureResource* texture, + SubresourceRange subresourceRange, + ResourceState src, + ResourceState dst) override { - // Submit binding for compute + auto textureImpl = static_cast(texture); + + if (subresourceRange.mipLevelCount == 0) + subresourceRange.mipLevelCount = textureImpl->getDesc()->numMipLevels; + if (subresourceRange.layerCount == 0) + subresourceRange.layerCount = textureImpl->getDesc()->arraySize; + + auto d3dFormat = D3DUtil::getMapFormat(textureImpl->getDesc()->format); + + ShortList barriers; + D3D12_RESOURCE_BARRIER barrier; + barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + if (src == dst && src == ResourceState::UnorderedAccess) { - ComputeSubmitter submitter(m_d3dCmdList); - RefPtr newPipeline; - if (SLANG_FAILED(_bindRenderState(&submitter, newPipeline))) + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; + barrier.UAV.pResource = textureImpl->m_resource.getResource(); + } + else + { + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Transition.StateBefore = D3DUtil::getResourceState(src); + barrier.Transition.StateAfter = D3DUtil::getResourceState(dst); + barrier.Transition.pResource = textureImpl->m_resource.getResource(); + auto aspectMask = (int32_t)subresourceRange.aspectMask; + if (subresourceRange.aspectMask == TextureAspect::Default) + aspectMask = (int32_t)TextureAspect::Color; + while (aspectMask) { - assert(!"Failed to bind render state"); + auto aspect = Math::getLowestBit((int32_t)aspectMask); + aspectMask &= ~aspect; + auto planeIndex = D3DUtil::getPlaneSlice(d3dFormat, (TextureAspect)aspect); + for (uint32_t layer = 0; layer < subresourceRange.layerCount; layer++) + { + for (uint32_t mip = 0; mip < subresourceRange.mipLevelCount; mip++) + { + barrier.Transition.Subresource = D3DUtil::getSubresourceIndex( + mip + subresourceRange.mipLevel, + layer + subresourceRange.baseArrayLayer, + planeIndex, + textureImpl->getDesc()->numMipLevels, + textureImpl->getDesc()->arraySize); + barriers.add(barrier); + } + } } } - m_d3dCmdList->Dispatch(x, y, z); + m_commandBuffer->m_cmdList->ResourceBarrier( + (UINT)barriers.getCount(), barriers.getArrayView().getBuffer()); } virtual SLANG_NO_THROW void SLANG_MCALL - dispatchComputeIndirect(IBufferResource* argBuffer, uint64_t offset) override + beginDebugEvent(const char* name, float rgbColor[3]) override { - // Submit binding for compute + auto beginEvent = m_commandBuffer->m_renderer->m_BeginEventOnCommandList; + if (beginEvent) { - ComputeSubmitter submitter(m_d3dCmdList); - RefPtr newPipeline; - if (SLANG_FAILED(_bindRenderState(&submitter, newPipeline))) - { - assert(!"Failed to bind render state"); - } + beginEvent( + m_commandBuffer->m_cmdList, + 0xff000000 | (uint8_t(rgbColor[0] * 255.0f) << 16) | + (uint8_t(rgbColor[1] * 255.0f) << 8) | uint8_t(rgbColor[2] * 255.0f), + name); + } + } + virtual SLANG_NO_THROW void SLANG_MCALL endDebugEvent() override + { + auto endEvent = m_commandBuffer->m_renderer->m_EndEventOnCommandList; + if (endEvent) + { + endEvent(m_commandBuffer->m_cmdList); } - auto argBufferImpl = static_cast(argBuffer); - - m_d3dCmdList->ExecuteIndirect( - m_renderer->dispatchIndirectCmdSignature, - 1, - argBufferImpl->m_resource, - offset, - nullptr, - 0); } }; - ComputeCommandEncoderImpl m_computeCommandEncoder; + ResourceCommandEncoderImpl m_resourceCommandEncoder; + virtual SLANG_NO_THROW void SLANG_MCALL - encodeComputeCommands(IComputeCommandEncoder** outEncoder) override + encodeResourceCommands(IResourceCommandEncoder** outEncoder) override { - m_computeCommandEncoder.init(m_renderer, m_transientHeap, this); - *outEncoder = &m_computeCommandEncoder; + m_resourceCommandEncoder.init(this); + *outEncoder = &m_resourceCommandEncoder; } - class ResourceCommandEncoderImpl : public IResourceCommandEncoder + class RenderCommandEncoderImpl + : public IRenderCommandEncoder + , public ResourceCommandEncoderImpl { public: - CommandBufferImpl* m_commandBuffer; - void init(D3D12Device* renderer, CommandBufferImpl* commandBuffer) - { - m_commandBuffer = commandBuffer; - } - virtual SLANG_NO_THROW void SLANG_MCALL copyBuffer( - IBufferResource* dst, - size_t dstOffset, - IBufferResource* src, - size_t srcOffset, - size_t size) override - { - auto dstBuffer = static_cast(dst); - auto srcBuffer = static_cast(src); + SLANG_GFX_FORWARD_RESOURCE_COMMAND_ENCODER_IMPL(ResourceCommandEncoderImpl) + public: + RefPtr m_renderPass; + RefPtr m_framebuffer; - m_commandBuffer->m_cmdList->CopyBufferRegion( - dstBuffer->m_resource.getResource(), - dstOffset, - srcBuffer->m_resource.getResource(), - srcOffset, - size); - } - virtual SLANG_NO_THROW void SLANG_MCALL uploadBufferData( - IBufferResource* dst, - size_t offset, - size_t size, - void* data) override - { - _uploadBufferData( - m_commandBuffer->m_renderer->m_device, - m_commandBuffer->m_cmdList, - m_commandBuffer->m_transientHeap, - static_cast(dst), - offset, - size, - data); - } - virtual SLANG_NO_THROW void SLANG_MCALL textureBarrier( - size_t count, - ITextureResource* const* textures, - ResourceState src, - ResourceState dst) override + List m_boundVertexBuffers; + + RefPtr m_boundIndexBuffer; + + D3D12_VIEWPORT m_viewports[kMaxRTVCount]; + D3D12_RECT m_scissorRects[kMaxRTVCount]; + + DXGI_FORMAT m_boundIndexFormat; + UINT m_boundIndexOffset; + + D3D12_PRIMITIVE_TOPOLOGY_TYPE m_primitiveTopologyType; + D3D12_PRIMITIVE_TOPOLOGY m_primitiveTopology; + + void init( + D3D12Device* renderer, + TransientResourceHeapImpl* transientHeap, + CommandBufferImpl* cmdBuffer, + RenderPassLayoutImpl* renderPass, + FramebufferImpl* framebuffer) { - ShortList barriers; + PipelineCommandEncoder::init(cmdBuffer); + m_preCmdList = nullptr; + m_renderPass = renderPass; + m_framebuffer = framebuffer; + m_transientHeap = transientHeap; + m_boundVertexBuffers.clear(); + m_boundIndexBuffer = nullptr; + m_primitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + m_primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + m_boundIndexFormat = DXGI_FORMAT_UNKNOWN; + m_boundIndexOffset = 0; + m_currentPipeline = nullptr; - for (size_t i = 0; i < count; i++) + // Set render target states. + if (!framebuffer) { - auto textureImpl = static_cast(textures[i]); - auto d3dFormat = D3DUtil::getMapFormat(textureImpl->getDesc()->format); - auto textureDesc = textureImpl->getDesc(); - D3D12_RESOURCE_BARRIER barrier; - barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - if (src == dst && src == ResourceState::UnorderedAccess) - { - barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; - barrier.UAV.pResource = textureImpl->m_resource.getResource(); - } - else + return; + } + m_d3dCmdList->OMSetRenderTargets( + (UINT)framebuffer->renderTargetViews.getCount(), + framebuffer->renderTargetDescriptors.getArrayView().getBuffer(), + FALSE, + framebuffer->depthStencilView ? &framebuffer->depthStencilDescriptor : nullptr); + + // Issue clear commands based on render pass set up. + for (Index i = 0; i < framebuffer->renderTargetViews.getCount(); i++) + { + if (i >= renderPass->m_renderTargetAccesses.getCount()) + continue; + + auto& access = renderPass->m_renderTargetAccesses[i]; + + // Transit resource states. { - barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - barrier.Transition.StateBefore = D3DUtil::getResourceState(src); - barrier.Transition.StateAfter = D3DUtil::getResourceState(dst); - if (barrier.Transition.StateBefore == barrier.Transition.StateAfter) - continue; - barrier.Transition.pResource = textureImpl->m_resource.getResource(); - auto planeCount = D3DUtil::getPlaneSliceCount( - D3DUtil::getMapFormat(textureImpl->getDesc()->format)); - auto arraySize = textureDesc->arraySize; - if (arraySize == 0) - arraySize = 1; - for (uint32_t planeIndex = 0; planeIndex < planeCount; planeIndex++) + D3D12BarrierSubmitter submitter(m_d3dCmdList); + auto resourceViewImpl = framebuffer->renderTargetViews[i].Ptr(); + if (resourceViewImpl) { - for (int layer = 0; layer < arraySize; layer++) + auto textureResource = static_cast( + resourceViewImpl->m_resource.Ptr()); + if (textureResource) { - for (int mip = 0; mip < textureDesc->numMipLevels; mip++) + D3D12_RESOURCE_STATES initialState; + if (access.initialState == ResourceState::Undefined) { - barrier.Transition.Subresource = D3DUtil::getSubresourceIndex( - mip, - layer, - planeIndex, - textureImpl->getDesc()->numMipLevels, - arraySize); - barriers.add(barrier); + initialState = textureResource->m_defaultState; + } + else + { + initialState = D3DUtil::getResourceState(access.initialState); } + textureResource->m_resource.transition( + initialState, D3D12_RESOURCE_STATE_RENDER_TARGET, submitter); } } } + // Clear. + if (access.loadOp == IRenderPassLayout::AttachmentLoadOp::Clear) + { + m_d3dCmdList->ClearRenderTargetView( + framebuffer->renderTargetDescriptors[i], + framebuffer->renderTargetClearValues[i].values, + 0, + nullptr); + } } - if (barriers.getCount()) + + if (renderPass->m_hasDepthStencil) { - m_commandBuffer->m_cmdList->ResourceBarrier( - (UINT)barriers.getCount(), barriers.getArrayView().getBuffer()); + // Transit resource states. + { + D3D12BarrierSubmitter submitter(m_d3dCmdList); + auto resourceViewImpl = framebuffer->depthStencilView.Ptr(); + auto textureResource = + static_cast(resourceViewImpl->m_resource.Ptr()); + D3D12_RESOURCE_STATES initialState; + if (renderPass->m_depthStencilAccess.initialState == + ResourceState::Undefined) + { + initialState = textureResource->m_defaultState; + } + else + { + initialState = D3DUtil::getResourceState( + renderPass->m_depthStencilAccess.initialState); + } + textureResource->m_resource.transition( + initialState, + D3D12_RESOURCE_STATE_DEPTH_WRITE, + submitter); + } + // Clear. + uint32_t clearFlags = 0; + if (renderPass->m_depthStencilAccess.loadOp == + IRenderPassLayout::AttachmentLoadOp::Clear) + { + clearFlags |= D3D12_CLEAR_FLAG_DEPTH; + } + if (renderPass->m_depthStencilAccess.stencilLoadOp == + IRenderPassLayout::AttachmentLoadOp::Clear) + { + clearFlags |= D3D12_CLEAR_FLAG_STENCIL; + } + if (clearFlags) + { + m_d3dCmdList->ClearDepthStencilView( + framebuffer->depthStencilDescriptor, + (D3D12_CLEAR_FLAGS)clearFlags, + framebuffer->depthStencilClearValue.depth, + framebuffer->depthStencilClearValue.stencil, + 0, + nullptr); + } } } - virtual SLANG_NO_THROW void SLANG_MCALL bufferBarrier( - size_t count, - IBufferResource* const* buffers, - ResourceState src, - ResourceState dst) override - { - List barriers; - barriers.reserve(count); + virtual SLANG_NO_THROW Result SLANG_MCALL + bindPipeline(IPipelineState* state, IShaderObject** outRootObject) override + { + return bindPipelineImpl(state, outRootObject); + } - for (size_t i = 0; i < count; i++) + virtual SLANG_NO_THROW void SLANG_MCALL + setViewports(uint32_t count, const Viewport* viewports) override + { + static const int kMaxViewports = + D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; + assert(count <= kMaxViewports && count <= kMaxRTVCount); + for (UInt ii = 0; ii < count; ++ii) { - auto bufferImpl = static_cast(buffers[i]); - - D3D12_RESOURCE_BARRIER barrier = {}; - // If the src == dst, it must be a UAV barrier. - barrier.Type = (src == dst && dst == ResourceState::UnorderedAccess) - ? D3D12_RESOURCE_BARRIER_TYPE_UAV - : D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + auto& inViewport = viewports[ii]; + auto& dxViewport = m_viewports[ii]; - if (barrier.Type == D3D12_RESOURCE_BARRIER_TYPE_UAV) - { - barrier.UAV.pResource = bufferImpl->m_resource; - } - else - { - barrier.Transition.pResource = bufferImpl->m_resource; - barrier.Transition.StateBefore = D3DUtil::getResourceState(src); - barrier.Transition.StateAfter = D3DUtil::getResourceState(dst); - barrier.Transition.Subresource = 0; - if (barrier.Transition.StateAfter == barrier.Transition.StateBefore) - continue; - } - barriers.add(barrier); + dxViewport.TopLeftX = inViewport.originX; + dxViewport.TopLeftY = inViewport.originY; + dxViewport.Width = inViewport.extentX; + dxViewport.Height = inViewport.extentY; + dxViewport.MinDepth = inViewport.minZ; + dxViewport.MaxDepth = inViewport.maxZ; } - if (barriers.getCount()) + m_d3dCmdList->RSSetViewports(UINT(count), m_viewports); + } + + virtual SLANG_NO_THROW void SLANG_MCALL + setScissorRects(uint32_t count, const ScissorRect* rects) override + { + static const int kMaxScissorRects = + D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; + assert(count <= kMaxScissorRects && count <= kMaxRTVCount); + + for (UInt ii = 0; ii < count; ++ii) { - m_commandBuffer->m_cmdList4->ResourceBarrier( - (UINT)barriers.getCount(), barriers.getArrayView().getBuffer()); + auto& inRect = rects[ii]; + auto& dxRect = m_scissorRects[ii]; + + dxRect.left = LONG(inRect.minX); + dxRect.top = LONG(inRect.minY); + dxRect.right = LONG(inRect.maxX); + dxRect.bottom = LONG(inRect.maxY); } + + m_d3dCmdList->RSSetScissorRects(UINT(count), m_scissorRects); } - virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() {} - virtual SLANG_NO_THROW void SLANG_MCALL writeTimestamp(IQueryPool* pool, SlangInt index) override + + virtual SLANG_NO_THROW void SLANG_MCALL + setPrimitiveTopology(PrimitiveTopology topology) override { - static_cast(pool)->writeTimestamp(m_commandBuffer->m_cmdList, index); + m_primitiveTopologyType = D3DUtil::getPrimitiveType(topology); + m_primitiveTopology = D3DUtil::getPrimitiveTopology(topology); } - virtual SLANG_NO_THROW void SLANG_MCALL copyTexture( - ITextureResource* dst, - ResourceState dstState, - SubresourceRange dstSubresource, - ITextureResource::Offset3D dstOffset, - ITextureResource* src, - ResourceState srcState, - SubresourceRange srcSubresource, - ITextureResource::Offset3D srcOffset, - ITextureResource::Size extent) override - { - auto dstTexture = static_cast(dst); - auto srcTexture = static_cast(src); - if (dstSubresource.layerCount == 0 && dstSubresource.mipLevelCount == 0 && - srcSubresource.layerCount == 0 && srcSubresource.mipLevelCount == 0) + virtual SLANG_NO_THROW void SLANG_MCALL setVertexBuffers( + uint32_t startSlot, + uint32_t slotCount, + IBufferResource* const* buffers, + const uint32_t* offsets) override + { { - m_commandBuffer->m_cmdList->CopyResource( - dstTexture->m_resource.getResource(), srcTexture->m_resource.getResource()); - return; + const Index num = startSlot + slotCount; + if (num > m_boundVertexBuffers.getCount()) + { + m_boundVertexBuffers.setCount(num); + } } - auto d3dFormat = D3DUtil::getMapFormat(dstTexture->getDesc()->format); - auto aspectMask = (int32_t)dstSubresource.aspectMask; - if (dstSubresource.aspectMask == TextureAspect::Default) - aspectMask = (int32_t)TextureAspect::Color; - while (aspectMask) + for (UInt i = 0; i < slotCount; i++) { - auto aspect = Math::getLowestBit((int32_t)aspectMask); - aspectMask &= ~aspect; - auto planeIndex = D3DUtil::getPlaneSlice(d3dFormat, (TextureAspect)aspect); - for (uint32_t layer = 0; layer < dstSubresource.layerCount; layer++) - { - for (uint32_t mipLevel = 0; mipLevel < dstSubresource.mipLevelCount; - mipLevel++) - { - D3D12_TEXTURE_COPY_LOCATION dstRegion = {}; - - dstRegion.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - dstRegion.pResource = dstTexture->m_resource.getResource(); - dstRegion.SubresourceIndex = D3DUtil::getSubresourceIndex( - dstSubresource.mipLevel + mipLevel, - dstSubresource.baseArrayLayer + layer, - planeIndex, - dstTexture->getDesc()->numMipLevels, - dstTexture->getDesc()->arraySize); - - D3D12_TEXTURE_COPY_LOCATION srcRegion = {}; - srcRegion.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - srcRegion.pResource = srcTexture->m_resource.getResource(); - srcRegion.SubresourceIndex = D3DUtil::getSubresourceIndex( - srcSubresource.mipLevel + mipLevel, - srcSubresource.baseArrayLayer + layer, - planeIndex, - srcTexture->getDesc()->numMipLevels, - srcTexture->getDesc()->arraySize); - - D3D12_BOX srcBox = {}; - srcBox.left = srcOffset.x; - srcBox.top = srcOffset.y; - srcBox.front = srcOffset.z; - srcBox.right = srcBox.left + extent.width; - srcBox.bottom = srcBox.top + extent.height; - srcBox.back = srcBox.front + extent.depth; + BufferResourceImpl* buffer = static_cast(buffers[i]); - m_commandBuffer->m_cmdList->CopyTextureRegion( - &dstRegion, - dstOffset.x, - dstOffset.y, - dstOffset.z, - &srcRegion, - &srcBox); - } - } + BoundVertexBuffer& boundBuffer = m_boundVertexBuffers[startSlot + i]; + boundBuffer.m_buffer = buffer; + boundBuffer.m_offset = int(offsets[i]); } } - virtual SLANG_NO_THROW void SLANG_MCALL uploadTextureData( - ITextureResource* dst, - SubresourceRange subResourceRange, - ITextureResource::Offset3D offset, - ITextureResource::Size extent, - ITextureResource::SubresourceData* subResourceData, - size_t subResourceDataCount) override + virtual SLANG_NO_THROW void SLANG_MCALL setIndexBuffer( + IBufferResource* buffer, Format indexFormat, uint32_t offset = 0) override { - auto dstTexture = static_cast(dst); - auto baseSubresourceIndex = D3DUtil::getSubresourceIndex( - subResourceRange.mipLevel, - subResourceRange.baseArrayLayer, - 0, - dstTexture->getDesc()->numMipLevels, - dstTexture->getDesc()->arraySize); - auto textureSize = dstTexture->getDesc()->size; - FormatInfo formatInfo = {}; - gfxGetFormatInfo(dstTexture->getDesc()->format, &formatInfo); - for (uint32_t i = 0; i < (uint32_t)subResourceDataCount; i++) - { - auto subresourceIndex = baseSubresourceIndex + i; - // Get the footprint - D3D12_RESOURCE_DESC texDesc = dstTexture->m_resource.getResource()->GetDesc(); - - D3D12_TEXTURE_COPY_LOCATION dstRegion = {}; + m_boundIndexBuffer = (BufferResourceImpl*)buffer; + m_boundIndexFormat = D3DUtil::getMapFormat(indexFormat); + m_boundIndexOffset = offset; + } - dstRegion.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - dstRegion.SubresourceIndex = subresourceIndex; - dstRegion.pResource = dstTexture->m_resource.getResource(); + void prepareDraw() + { + auto pipelineState = m_currentPipeline.Ptr(); + if (!pipelineState || (pipelineState->desc.type != PipelineType::Graphics)) + { + assert(!"No graphics pipeline state set"); + return; + } - D3D12_TEXTURE_COPY_LOCATION srcRegion = {}; - srcRegion.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; - D3D12_PLACED_SUBRESOURCE_FOOTPRINT& footprint = srcRegion.PlacedFootprint; - - footprint.Offset = 0; - footprint.Footprint.Format = texDesc.Format; - uint32_t mipLevel = D3DUtil::getSubresourceMipLevel( - subresourceIndex, dstTexture->getDesc()->numMipLevels); - if (extent.width != ITextureResource::kRemainingTextureSize) - { - footprint.Footprint.Width = extent.width; - } - else - { - footprint.Footprint.Width = Math::Max(1, (textureSize.width >> mipLevel)) - offset.x; - } - if (extent.height != ITextureResource::kRemainingTextureSize) - { - footprint.Footprint.Height = extent.height; - } - else - { - footprint.Footprint.Height = - Math::Max(1, (textureSize.height >> mipLevel)) - offset.y; - } - if (extent.depth != ITextureResource::kRemainingTextureSize) - { - footprint.Footprint.Depth = extent.depth; - } - else + // Submit - setting for graphics + { + GraphicsSubmitter submitter(m_d3dCmdList); + RefPtr newPipeline; + if(SLANG_FAILED(_bindRenderState(&submitter, newPipeline))) { - footprint.Footprint.Depth = - Math::Max(1, (textureSize.depth >> mipLevel)) - offset.z; + assert(!"Failed to bind render state"); } - auto rowSize = (footprint.Footprint.Width + formatInfo.blockWidth - 1) / - formatInfo.blockWidth * formatInfo.blockSizeInBytes; - auto rowCount = (footprint.Footprint.Height + formatInfo.blockHeight - 1) / - formatInfo.blockHeight; - footprint.Footprint.RowPitch = (UINT)D3DUtil::calcAligned( - rowSize, (uint32_t)D3D12_TEXTURE_DATA_PITCH_ALIGNMENT); - - auto bufferSize = - footprint.Footprint.RowPitch * rowCount * footprint.Footprint.Depth; + } - IBufferResource* stagingBuffer; - m_commandBuffer->m_transientHeap->allocateStagingBuffer( - bufferSize, stagingBuffer, ResourceState::General); + m_d3dCmdList->IASetPrimitiveTopology(m_primitiveTopology); - BufferResourceImpl* bufferImpl = static_cast(stagingBuffer); - uint8_t* bufferData = nullptr; - D3D12_RANGE mapRange = {0, 0}; - bufferImpl->m_resource.getResource()->Map(0, &mapRange, (void**)&bufferData); - for (uint32_t z = 0; z < footprint.Footprint.Depth; z++) + // Set up vertex buffer views + { + auto inputLayout = (InputLayoutImpl*)pipelineState->inputLayout.Ptr(); + if (inputLayout) { - auto imageStart = bufferData + footprint.Footprint.RowPitch * rowCount * (size_t)z; - auto srcData = - (uint8_t*)subResourceData->data + subResourceData->strideZ * z; - for (uint32_t row = 0; row < rowCount; row++) + int numVertexViews = 0; + D3D12_VERTEX_BUFFER_VIEW vertexViews[16]; + for (Index i = 0; i < m_boundVertexBuffers.getCount(); i++) { - memcpy( - imageStart + row * (size_t)footprint.Footprint.RowPitch, - srcData + subResourceData->strideY * row, - rowSize); + const BoundVertexBuffer& boundVertexBuffer = m_boundVertexBuffers[i]; + BufferResourceImpl* buffer = boundVertexBuffer.m_buffer; + if (buffer) + { + D3D12_VERTEX_BUFFER_VIEW& vertexView = + vertexViews[numVertexViews++]; + vertexView.BufferLocation = + buffer->m_resource.getResource()->GetGPUVirtualAddress() + + boundVertexBuffer.m_offset; + vertexView.SizeInBytes = UINT( + buffer->getDesc()->sizeInBytes - boundVertexBuffer.m_offset); + vertexView.StrideInBytes = inputLayout->m_vertexStreamStrides[i]; + } } + m_d3dCmdList->IASetVertexBuffers(0, numVertexViews, vertexViews); } - bufferImpl->m_resource.getResource()->Unmap(0, nullptr); - - srcRegion.pResource = bufferImpl->m_resource.getResource(); + } + // Set up index buffer + if (m_boundIndexBuffer) + { + D3D12_INDEX_BUFFER_VIEW indexBufferView; + indexBufferView.BufferLocation = + m_boundIndexBuffer->m_resource.getResource()->GetGPUVirtualAddress() + + m_boundIndexOffset; + indexBufferView.SizeInBytes = + UINT(m_boundIndexBuffer->getDesc()->sizeInBytes - m_boundIndexOffset); + indexBufferView.Format = m_boundIndexFormat; - m_commandBuffer->m_cmdList->CopyTextureRegion( - &dstRegion, offset.x, offset.y, offset.z, &srcRegion, nullptr); + m_d3dCmdList->IASetIndexBuffer(&indexBufferView); } } - - virtual SLANG_NO_THROW void SLANG_MCALL clearResourceView( - IResourceView* view, - ClearValue* clearValue, - ClearResourceViewFlags::Enum flags) override + virtual SLANG_NO_THROW void SLANG_MCALL + draw(uint32_t vertexCount, uint32_t startVertex = 0) override + { + prepareDraw(); + m_d3dCmdList->DrawInstanced(vertexCount, 1, startVertex, 0); + } + virtual SLANG_NO_THROW void SLANG_MCALL drawIndexed( + uint32_t indexCount, uint32_t startIndex = 0, uint32_t baseVertex = 0) override { - auto viewImpl = static_cast(view); - switch (view->getViewDesc()->type) + prepareDraw(); + m_d3dCmdList->DrawIndexedInstanced(indexCount, 1, startIndex, baseVertex, 0); + } + virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override + { + PipelineCommandEncoder::endEncodingImpl(); + if (!m_framebuffer) + return; + // Issue clear commands based on render pass set up. + for (Index i = 0; i < m_renderPass->m_renderTargetAccesses.getCount(); i++) { - case IResourceView::Type::RenderTarget: - m_commandBuffer->m_cmdList->ClearRenderTargetView( - viewImpl->m_descriptor.cpuHandle, - clearValue->color.floatValues, - 0, - nullptr); - break; - case IResourceView::Type::DepthStencil: + auto& access = m_renderPass->m_renderTargetAccesses[i]; + + // Transit resource states. { - D3D12_CLEAR_FLAGS clearFlags = (D3D12_CLEAR_FLAGS)0; - if (flags & ClearResourceViewFlags::ClearDepth) - { - clearFlags |= D3D12_CLEAR_FLAG_DEPTH; - } - if (flags & ClearResourceViewFlags::ClearStencil) + D3D12BarrierSubmitter submitter(m_d3dCmdList); + auto resourceViewImpl = m_framebuffer->renderTargetViews[i].Ptr(); + if (!resourceViewImpl) + continue; + auto textureResource = + static_cast(resourceViewImpl->m_resource.Ptr()); + if (textureResource) { - clearFlags |= D3D12_CLEAR_FLAG_STENCIL; + textureResource->m_resource.transition( + D3D12_RESOURCE_STATE_RENDER_TARGET, + D3DUtil::getResourceState(access.finalState), + submitter); } - m_commandBuffer->m_cmdList->ClearDepthStencilView( - viewImpl->m_descriptor.cpuHandle, - clearFlags, - clearValue->depthStencil.depth, - (UINT8)clearValue->depthStencil.stencil, - 0, - nullptr); - break; } - case IResourceView::Type::UnorderedAccess: - { - ID3D12Resource* d3dResource = nullptr; - switch (viewImpl->m_resource->getType()) - { - case IResource::Type::Buffer: - d3dResource = - static_cast(viewImpl->m_resource.Ptr()) - ->m_resource.getResource(); - break; - default: - d3dResource = - static_cast(viewImpl->m_resource.Ptr()) - ->m_resource.getResource(); - break; - } - auto gpuHandleIndex = - m_commandBuffer->m_transientHeap->getCurrentViewHeap().allocate(1); - if (gpuHandleIndex == -1) - { - m_commandBuffer->m_transientHeap->allocateNewViewDescriptorHeap( - m_commandBuffer->m_renderer); - gpuHandleIndex = - m_commandBuffer->m_transientHeap->getCurrentViewHeap().allocate(1); - auto d3dViewHeap = - m_commandBuffer->m_transientHeap->getCurrentViewHeap().getHeap(); - m_commandBuffer->bindDescriptorHeaps(); - } - this->m_commandBuffer->m_renderer->m_device->CopyDescriptorsSimple( - 1, - m_commandBuffer->m_transientHeap->getCurrentViewHeap().getCpuHandle( - gpuHandleIndex), - viewImpl->m_descriptor.cpuHandle, - D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + } - if (flags & ClearResourceViewFlags::FloatClearValues) - { - m_commandBuffer->m_cmdList->ClearUnorderedAccessViewFloat( - m_commandBuffer->m_transientHeap->getCurrentViewHeap().getGpuHandle( - gpuHandleIndex), - viewImpl->m_descriptor.cpuHandle, - d3dResource, - clearValue->color.floatValues, - 0, - nullptr); - } - else - { - m_commandBuffer->m_cmdList->ClearUnorderedAccessViewUint( - m_commandBuffer->m_transientHeap->getCurrentViewHeap().getGpuHandle( - gpuHandleIndex), - viewImpl->m_descriptor.cpuHandle, - d3dResource, - clearValue->color.uintValues, - 0, - nullptr); - } - break; - } - default: - break; + if (m_renderPass->m_hasDepthStencil) + { + // Transit resource states. + D3D12BarrierSubmitter submitter(m_d3dCmdList); + auto resourceViewImpl = m_framebuffer->depthStencilView.Ptr(); + auto textureResource = + static_cast(resourceViewImpl->m_resource.Ptr()); + textureResource->m_resource.transition( + D3D12_RESOURCE_STATE_DEPTH_WRITE, + D3DUtil::getResourceState( + m_renderPass->m_depthStencilAccess.finalState), + submitter); } + m_framebuffer = nullptr; } - virtual SLANG_NO_THROW void SLANG_MCALL resolveResource( - ITextureResource* source, - ResourceState sourceState, - SubresourceRange sourceRange, - ITextureResource* dest, - ResourceState destState, - SubresourceRange destRange) override + virtual SLANG_NO_THROW void SLANG_MCALL + setStencilReference(uint32_t referenceValue) override { - auto srcTexture = static_cast(source); - auto srcDesc = srcTexture->getDesc(); - auto dstTexture = static_cast(dest); - auto dstDesc = dstTexture->getDesc(); + m_d3dCmdList->OMSetStencilRef((UINT)referenceValue); + } - for (uint32_t layer = 0; layer < sourceRange.layerCount; ++layer) - { - for (uint32_t mip = 0; mip < sourceRange.mipLevelCount; ++mip) - { - auto srcSubresourceIndex = D3DUtil::getSubresourceIndex( - mip + sourceRange.mipLevel, - layer + sourceRange.baseArrayLayer, - 0, - srcDesc->numMipLevels, - srcDesc->arraySize); - auto dstSubresourceIndex = D3DUtil::getSubresourceIndex( - mip + destRange.mipLevel, - layer + destRange.baseArrayLayer, - 0, - dstDesc->numMipLevels, - dstDesc->arraySize); + virtual SLANG_NO_THROW void SLANG_MCALL drawIndirect( + uint32_t maxDrawCount, + IBufferResource* argBuffer, + uint64_t argOffset, + IBufferResource* countBuffer, + uint64_t countOffset) override + { + prepareDraw(); - DXGI_FORMAT format = D3DUtil::getMapFormat(srcDesc->format); + auto argBufferImpl = static_cast(argBuffer); + auto countBufferImpl = static_cast(countBuffer); - m_commandBuffer->m_cmdList->ResolveSubresource( - dstTexture->m_resource.getResource(), - dstSubresourceIndex, - srcTexture->m_resource.getResource(), - srcSubresourceIndex, - format); - } - } + m_d3dCmdList->ExecuteIndirect( + m_renderer->drawIndirectCmdSignature, + maxDrawCount, + argBufferImpl->m_resource, + argOffset, + countBufferImpl ? countBufferImpl->m_resource.getResource() : nullptr, + countOffset); } - virtual SLANG_NO_THROW void SLANG_MCALL resolveQuery( - IQueryPool* queryPool, - uint32_t index, - uint32_t count, - IBufferResource* buffer, - uint64_t offset) override + virtual SLANG_NO_THROW void SLANG_MCALL drawIndexedIndirect( + uint32_t maxDrawCount, + IBufferResource* argBuffer, + uint64_t argOffset, + IBufferResource* countBuffer, + uint64_t countOffset) override { - auto queryBase = static_cast(queryPool); - switch (queryBase->m_desc.type) - { - case QueryType::AccelerationStructureCompactedSize: - case QueryType::AccelerationStructureCurrentSize: - case QueryType::AccelerationStructureSerializedSize: - { - auto queryPoolImpl = static_cast(queryPool); - auto bufferImpl = static_cast(buffer); - auto srcQueryBuffer = - queryPoolImpl->m_bufferResource->m_resource.getResource(); - - D3D12_RESOURCE_BARRIER barrier = {}; - barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_UNORDERED_ACCESS; - barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE; - barrier.Transition.pResource = srcQueryBuffer; - m_commandBuffer->m_cmdList->ResourceBarrier(1, &barrier); + prepareDraw(); - m_commandBuffer->m_cmdList->CopyBufferRegion( - bufferImpl->m_resource.getResource(), - offset, - srcQueryBuffer, - index * sizeof(uint64_t), - count * sizeof(uint64_t)); + auto argBufferImpl = static_cast(argBuffer); + auto countBufferImpl = static_cast(countBuffer); - barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_SOURCE; - barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_UNORDERED_ACCESS; - barrier.Transition.pResource = srcQueryBuffer; - m_commandBuffer->m_cmdList->ResourceBarrier(1, &barrier); - } - break; - default: - { - auto queryPoolImpl = static_cast(queryPool); - auto bufferImpl = static_cast(buffer); - m_commandBuffer->m_cmdList->ResolveQueryData( - queryPoolImpl->m_queryHeap.get(), - queryPoolImpl->m_queryType, - index, - count, - bufferImpl->m_resource.getResource(), - offset); - } - break; + m_d3dCmdList->ExecuteIndirect( + m_renderer->drawIndexedIndirectCmdSignature, + maxDrawCount, + argBufferImpl->m_resource, + argOffset, + countBufferImpl ? countBufferImpl->m_resource.getResource() : nullptr, + countOffset); + } + + virtual SLANG_NO_THROW Result SLANG_MCALL setSamplePositions( + uint32_t samplesPerPixel, + uint32_t pixelCount, + const SamplePosition* samplePositions) override + { + if (m_commandBuffer->m_cmdList1) + { + m_commandBuffer->m_cmdList1->SetSamplePositions( + samplesPerPixel, pixelCount, (D3D12_SAMPLE_POSITION*)samplePositions); + return SLANG_OK; } + return SLANG_E_NOT_AVAILABLE; } - virtual SLANG_NO_THROW void SLANG_MCALL copyTextureToBuffer( - IBufferResource* dst, - size_t dstOffset, - size_t dstSize, - ITextureResource* src, - ResourceState srcState, - SubresourceRange srcSubresource, - ITextureResource::Offset3D srcOffset, - ITextureResource::Size extent) override + virtual SLANG_NO_THROW void SLANG_MCALL drawInstanced( + uint32_t vertexCount, + uint32_t instanceCount, + uint32_t startVertex, + uint32_t startInstanceLocation) override { - assert(srcSubresource.mipLevelCount <= 1); + prepareDraw(); + m_d3dCmdList->DrawInstanced( + vertexCount, instanceCount, startVertex, startInstanceLocation); + } - auto srcTexture = static_cast(src); - auto dstBuffer = static_cast(dst); - auto baseSubresourceIndex = D3DUtil::getSubresourceIndex( - srcSubresource.mipLevel, - srcSubresource.baseArrayLayer, - 0, - srcTexture->getDesc()->numMipLevels, - srcTexture->getDesc()->arraySize); - auto textureSize = srcTexture->getDesc()->size; - FormatInfo formatInfo = {}; - gfxGetFormatInfo(srcTexture->getDesc()->format, &formatInfo); - if (srcSubresource.mipLevelCount == 0) - srcSubresource.mipLevelCount = srcTexture->getDesc()->numMipLevels; - if (srcSubresource.layerCount == 0) - srcSubresource.layerCount = srcTexture->getDesc()->arraySize; + virtual SLANG_NO_THROW void SLANG_MCALL drawIndexedInstanced( + uint32_t indexCount, + uint32_t instanceCount, + uint32_t startIndexLocation, + int32_t baseVertexLocation, + uint32_t startInstanceLocation) override + { + prepareDraw(); + m_d3dCmdList->DrawIndexedInstanced(indexCount, instanceCount, startIndexLocation, baseVertexLocation, startInstanceLocation); + } + }; - for (uint32_t layer = 0; layer < srcSubresource.layerCount; layer++) - { - // Get the footprint - D3D12_RESOURCE_DESC texDesc = - srcTexture->m_resource.getResource()->GetDesc(); + RenderCommandEncoderImpl m_renderCommandEncoder; + virtual SLANG_NO_THROW void SLANG_MCALL encodeRenderCommands( + IRenderPassLayout* renderPass, + IFramebuffer* framebuffer, + IRenderCommandEncoder** outEncoder) override + { + m_renderCommandEncoder.init( + m_renderer, + m_transientHeap, + this, + static_cast(renderPass), + static_cast(framebuffer)); + *outEncoder = &m_renderCommandEncoder; + } - D3D12_TEXTURE_COPY_LOCATION dstRegion = {}; - dstRegion.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; - dstRegion.pResource = dstBuffer->m_resource.getResource(); - D3D12_PLACED_SUBRESOURCE_FOOTPRINT& footprint = dstRegion.PlacedFootprint; + class ComputeCommandEncoderImpl + : public IComputeCommandEncoder + , public ResourceCommandEncoderImpl + { + public: + SLANG_GFX_FORWARD_RESOURCE_COMMAND_ENCODER_IMPL(ResourceCommandEncoderImpl) + public: + virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override + { + PipelineCommandEncoder::endEncodingImpl(); + } + void init( + D3D12Device* renderer, + TransientResourceHeapImpl* transientHeap, + CommandBufferImpl* cmdBuffer) + { + PipelineCommandEncoder::init(cmdBuffer); + m_preCmdList = nullptr; + m_transientHeap = transientHeap; + m_currentPipeline = nullptr; + } - D3D12_TEXTURE_COPY_LOCATION srcRegion = {}; - srcRegion.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - srcRegion.SubresourceIndex = D3DUtil::getSubresourceIndex( - srcSubresource.mipLevel, - layer + srcSubresource.baseArrayLayer, - 0, - srcTexture->getDesc()->numMipLevels, - srcTexture->getDesc()->arraySize); - srcRegion.pResource = srcTexture->m_resource.getResource(); + virtual SLANG_NO_THROW Result SLANG_MCALL + bindPipeline(IPipelineState* state, IShaderObject** outRootObject) override + { + return bindPipelineImpl(state, outRootObject); + } - footprint.Offset = dstOffset; - footprint.Footprint.Format = texDesc.Format; - uint32_t mipLevel = srcSubresource.mipLevel; - if (extent.width != 0xFFFFFFFF) - { - footprint.Footprint.Width = extent.width; - } - else - { - footprint.Footprint.Width = - Math::Max(1, (textureSize.width >> mipLevel)) - srcOffset.x; - } - if (extent.height != 0xFFFFFFFF) - { - footprint.Footprint.Height = extent.height; - } - else - { - footprint.Footprint.Height = - Math::Max(1, (textureSize.height >> mipLevel)) - srcOffset.y; - } - if (extent.depth != 0xFFFFFFFF) - { - footprint.Footprint.Depth = extent.depth; - } - else + virtual SLANG_NO_THROW void SLANG_MCALL dispatchCompute(int x, int y, int z) override + { + // Submit binding for compute + { + ComputeSubmitter submitter(m_d3dCmdList); + RefPtr newPipeline; + if (SLANG_FAILED(_bindRenderState(&submitter, newPipeline))) { - footprint.Footprint.Depth = - Math::Max(1, (textureSize.depth >> mipLevel)) - srcOffset.z; + assert(!"Failed to bind render state"); } - footprint.Footprint.RowPitch = (UINT)D3DUtil::calcAligned( - footprint.Footprint.Width * (UInt)formatInfo.blockSizeInBytes, - (uint32_t)D3D12_TEXTURE_DATA_PITCH_ALIGNMENT); - - auto bufferSize = footprint.Footprint.RowPitch * - footprint.Footprint.Height * footprint.Footprint.Depth; - - D3D12_BOX srcBox = {}; - srcBox.left = srcOffset.x; - srcBox.top = srcOffset.y; - srcBox.front = srcOffset.z; - srcBox.right = srcOffset.x + extent.width; - srcBox.bottom = srcOffset.y + extent.height; - srcBox.back = srcOffset.z + extent.depth; - m_commandBuffer->m_cmdList->CopyTextureRegion( - &dstRegion, 0, 0, 0, &srcRegion, &srcBox); } + m_d3dCmdList->Dispatch(x, y, z); } - virtual SLANG_NO_THROW void SLANG_MCALL textureSubresourceBarrier( - ITextureResource* texture, - SubresourceRange subresourceRange, - ResourceState src, - ResourceState dst) override + virtual SLANG_NO_THROW void SLANG_MCALL + dispatchComputeIndirect(IBufferResource* argBuffer, uint64_t offset) override { - auto textureImpl = static_cast(texture); - - if (subresourceRange.mipLevelCount == 0) - subresourceRange.mipLevelCount = textureImpl->getDesc()->numMipLevels; - if (subresourceRange.layerCount == 0) - subresourceRange.layerCount = textureImpl->getDesc()->arraySize; - - auto d3dFormat = D3DUtil::getMapFormat(textureImpl->getDesc()->format); - - ShortList barriers; - D3D12_RESOURCE_BARRIER barrier; - barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - if (src == dst && src == ResourceState::UnorderedAccess) - { - barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; - barrier.UAV.pResource = textureImpl->m_resource.getResource(); - } - else + // Submit binding for compute { - barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - barrier.Transition.StateBefore = D3DUtil::getResourceState(src); - barrier.Transition.StateAfter = D3DUtil::getResourceState(dst); - barrier.Transition.pResource = textureImpl->m_resource.getResource(); - auto aspectMask = (int32_t)subresourceRange.aspectMask; - if (subresourceRange.aspectMask == TextureAspect::Default) - aspectMask = (int32_t)TextureAspect::Color; - while (aspectMask) + ComputeSubmitter submitter(m_d3dCmdList); + RefPtr newPipeline; + if (SLANG_FAILED(_bindRenderState(&submitter, newPipeline))) { - auto aspect = Math::getLowestBit((int32_t)aspectMask); - aspectMask &= ~aspect; - auto planeIndex = D3DUtil::getPlaneSlice(d3dFormat, (TextureAspect)aspect); - for (uint32_t layer = 0; layer < subresourceRange.layerCount; layer++) - { - for (uint32_t mip = 0; mip < subresourceRange.mipLevelCount; mip++) - { - barrier.Transition.Subresource = D3DUtil::getSubresourceIndex( - mip + subresourceRange.mipLevel, - layer + subresourceRange.baseArrayLayer, - planeIndex, - textureImpl->getDesc()->numMipLevels, - textureImpl->getDesc()->arraySize); - barriers.add(barrier); - } - } + assert(!"Failed to bind render state"); } } - m_commandBuffer->m_cmdList->ResourceBarrier( - (UINT)barriers.getCount(), barriers.getArrayView().getBuffer()); + auto argBufferImpl = static_cast(argBuffer); + + m_d3dCmdList->ExecuteIndirect( + m_renderer->dispatchIndirectCmdSignature, + 1, + argBufferImpl->m_resource, + offset, + nullptr, + 0); } }; - ResourceCommandEncoderImpl m_resourceCommandEncoder; - + ComputeCommandEncoderImpl m_computeCommandEncoder; virtual SLANG_NO_THROW void SLANG_MCALL - encodeResourceCommands(IResourceCommandEncoder** outEncoder) override + encodeComputeCommands(IComputeCommandEncoder** outEncoder) override { - m_resourceCommandEncoder.init(m_renderer, this); - *outEncoder = &m_resourceCommandEncoder; + m_computeCommandEncoder.init(m_renderer, m_transientHeap, this); + *outEncoder = &m_computeCommandEncoder; } #if SLANG_GFX_HAS_DXR_SUPPORT class RayTracingCommandEncoderImpl : public IRayTracingCommandEncoder - , public PipelineCommandEncoder + , public ResourceCommandEncoderImpl { public: - CommandBufferImpl* m_commandBuffer; - void init(D3D12Device* renderer, CommandBufferImpl* commandBuffer) - { - PipelineCommandEncoder::init(commandBuffer); - m_commandBuffer = commandBuffer; - } + SLANG_GFX_FORWARD_RESOURCE_COMMAND_ENCODER_IMPL(ResourceCommandEncoderImpl) + public: virtual SLANG_NO_THROW void SLANG_MCALL buildAccelerationStructure( const IAccelerationStructure::BuildDesc& desc, int propertyQueryCount, @@ -4846,11 +4865,6 @@ public: virtual SLANG_NO_THROW void SLANG_MCALL deserializeAccelerationStructure( IAccelerationStructure* dest, DeviceAddress source) override; - virtual SLANG_NO_THROW void SLANG_MCALL memoryBarrier( - int count, - IAccelerationStructure* const* structures, - AccessFlag sourceAccess, - AccessFlag destAccess) override; virtual SLANG_NO_THROW void SLANG_MCALL bindPipeline(IPipelineState* state, IShaderObject** outRootObject) override; virtual SLANG_NO_THROW void SLANG_MCALL dispatchRays( @@ -4860,18 +4874,12 @@ public: int32_t height, int32_t depth) override; virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() {} - virtual SLANG_NO_THROW void SLANG_MCALL - writeTimestamp(IQueryPool* pool, SlangInt index) override - { - static_cast(pool)->writeTimestamp( - m_commandBuffer->m_cmdList, index); - } }; RayTracingCommandEncoderImpl m_rayTracingCommandEncoder; virtual SLANG_NO_THROW void SLANG_MCALL encodeRayTracingCommands(IRayTracingCommandEncoder** outEncoder) override { - m_rayTracingCommandEncoder.init(m_renderer, this); + m_rayTracingCommandEncoder.init(this); *outEncoder = &m_rayTracingCommandEncoder; } #else @@ -5234,6 +5242,9 @@ public: PFN_D3D12_CREATE_DEVICE m_D3D12CreateDevice = nullptr; PFN_D3D12_SERIALIZE_ROOT_SIGNATURE m_D3D12SerializeRootSignature = nullptr; + PFN_BeginEventOnCommandList m_BeginEventOnCommandList = nullptr; + PFN_EndEventOnCommandList m_EndEventOnCommandList = nullptr; + bool m_nvapi = false; // Command signatures required for indirect draws. These indicate the format of the indirect @@ -5889,6 +5900,15 @@ Result D3D12Device::initialize(const Desc& desc) return SLANG_FAIL; } + HMODULE pixModule = LoadLibraryW(L"WinPixEventRuntime.dll"); + if (pixModule) + { + m_BeginEventOnCommandList = + (PFN_BeginEventOnCommandList)GetProcAddress(pixModule, "PIXBeginEventOnCommandList"); + m_EndEventOnCommandList = + (PFN_EndEventOnCommandList)GetProcAddress(pixModule, "PIXEndEventOnCommandList"); + } + #if ENABLE_DEBUG_LAYER m_D3D12GetDebugInterface = (PFN_D3D12_GET_DEBUG_INTERFACE)loadProc(d3dModule, "D3D12GetDebugInterface"); if (m_D3D12GetDebugInterface) @@ -6851,37 +6871,41 @@ Result D3D12Device::createTextureView(ITextureResource* texture, IResourceView:: viewImpl->m_allocator = m_rtvAllocator; D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = {}; rtvDesc.Format = D3DUtil::getMapFormat(desc.format); - isArray = desc.renderTarget.arraySize > 1; + isArray = desc.subresourceRange.layerCount > 1; switch (desc.renderTarget.shape) { case IResource::Type::Texture1D: rtvDesc.ViewDimension = isArray ? D3D12_RTV_DIMENSION_TEXTURE1DARRAY : D3D12_RTV_DIMENSION_TEXTURE1D; - rtvDesc.Texture1D.MipSlice = desc.renderTarget.mipSlice; + rtvDesc.Texture1D.MipSlice = desc.subresourceRange.mipLevel; break; case IResource::Type::Texture2D: if (isMultiSample) { rtvDesc.ViewDimension = isArray ? D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY : D3D12_RTV_DIMENSION_TEXTURE2DMS; - rtvDesc.Texture2DMSArray.ArraySize = desc.renderTarget.arraySize; - rtvDesc.Texture2DMSArray.FirstArraySlice = desc.renderTarget.arrayIndex; + rtvDesc.Texture2DMSArray.ArraySize = desc.subresourceRange.layerCount; + rtvDesc.Texture2DMSArray.FirstArraySlice = desc.subresourceRange.baseArrayLayer; } else { rtvDesc.ViewDimension = isArray ? D3D12_RTV_DIMENSION_TEXTURE2DARRAY : D3D12_RTV_DIMENSION_TEXTURE2D; - rtvDesc.Texture2DArray.MipSlice = desc.renderTarget.mipSlice; - rtvDesc.Texture2DArray.PlaneSlice = desc.renderTarget.planeIndex; - rtvDesc.Texture2DArray.ArraySize = desc.renderTarget.arraySize; - rtvDesc.Texture2DArray.FirstArraySlice = desc.renderTarget.arrayIndex; + rtvDesc.Texture2DArray.MipSlice = desc.subresourceRange.mipLevel; + rtvDesc.Texture2DArray.PlaneSlice = + resourceImpl ? D3DUtil::getPlaneSlice( + D3DUtil::getMapFormat(resourceImpl->getDesc()->format), + desc.subresourceRange.aspectMask) + : 0; + rtvDesc.Texture2DArray.ArraySize = desc.subresourceRange.layerCount; + rtvDesc.Texture2DArray.FirstArraySlice = desc.subresourceRange.baseArrayLayer; } break; case IResource::Type::Texture3D: rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE3D; - rtvDesc.Texture3D.MipSlice = desc.renderTarget.mipSlice; - rtvDesc.Texture3D.FirstWSlice = desc.renderTarget.arrayIndex; - rtvDesc.Texture3D.WSize = desc.renderTarget.arraySize; + rtvDesc.Texture3D.MipSlice = desc.subresourceRange.mipLevel; + rtvDesc.Texture3D.FirstWSlice = desc.subresourceRange.baseArrayLayer; + rtvDesc.Texture3D.WSize = desc.subresourceRange.layerCount; break; case IResource::Type::Buffer: rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_BUFFER; @@ -6902,28 +6926,28 @@ Result D3D12Device::createTextureView(ITextureResource* texture, IResourceView:: viewImpl->m_allocator = m_dsvAllocator; D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = {}; dsvDesc.Format = D3DUtil::getMapFormat(desc.format); - isArray = desc.renderTarget.arraySize > 1; + isArray = desc.subresourceRange.layerCount > 1; switch (desc.renderTarget.shape) { case IResource::Type::Texture1D: dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE1D; - dsvDesc.Texture1D.MipSlice = desc.renderTarget.mipSlice; + dsvDesc.Texture1D.MipSlice = desc.subresourceRange.mipLevel; break; case IResource::Type::Texture2D: if (isMultiSample) { dsvDesc.ViewDimension = isArray ? D3D12_DSV_DIMENSION_TEXTURE2DMSARRAY : D3D12_DSV_DIMENSION_TEXTURE2DMS; - dsvDesc.Texture2DMSArray.ArraySize = desc.renderTarget.arraySize; - dsvDesc.Texture2DMSArray.FirstArraySlice = desc.renderTarget.arrayIndex; + dsvDesc.Texture2DMSArray.ArraySize = desc.subresourceRange.layerCount; + dsvDesc.Texture2DMSArray.FirstArraySlice = desc.subresourceRange.baseArrayLayer; } else { dsvDesc.ViewDimension = isArray ? D3D12_DSV_DIMENSION_TEXTURE2DARRAY : D3D12_DSV_DIMENSION_TEXTURE2D; - dsvDesc.Texture2DArray.MipSlice = desc.renderTarget.mipSlice; - dsvDesc.Texture2DArray.ArraySize = desc.renderTarget.arraySize; - dsvDesc.Texture2DArray.FirstArraySlice = desc.renderTarget.arrayIndex; + dsvDesc.Texture2DArray.MipSlice = desc.subresourceRange.mipLevel; + dsvDesc.Texture2DArray.ArraySize = desc.subresourceRange.layerCount; + dsvDesc.Texture2DArray.FirstArraySlice = desc.subresourceRange.baseArrayLayer; } break; default: @@ -8143,23 +8167,6 @@ void D3D12Device::CommandBufferImpl::RayTracingCommandEncoderImpl::deserializeAc D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_DESERIALIZE); } -void D3D12Device::CommandBufferImpl::RayTracingCommandEncoderImpl::memoryBarrier( - int count, - IAccelerationStructure* const* structures, - AccessFlag sourceAccess, - AccessFlag destAccess) -{ - ShortList barriers; - barriers.setCount(count); - for (int i = 0; i < count; i++) - { - barriers[i].Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; - barriers[i].UAV.pResource = static_cast(structures[i]) - ->m_buffer->m_resource.getResource(); - } - m_commandBuffer->m_cmdList4->ResourceBarrier((UINT)count, barriers.getArrayView().getBuffer()); -} - void D3D12Device::CommandBufferImpl::RayTracingCommandEncoderImpl::bindPipeline( IPipelineState* state, IShaderObject** outRootObject) { @@ -8202,7 +8209,7 @@ void D3D12Device::CommandBufferImpl::RayTracingCommandEncoderImpl::dispatchRays( auto shaderTableImpl = static_cast(shaderTable); ResourceCommandEncoderImpl resourceCopyEncoder; - resourceCopyEncoder.init(m_renderer, m_commandBuffer); + resourceCopyEncoder.init(m_commandBuffer); auto shaderTableBuffer = shaderTableImpl->getOrCreateBuffer(pipelineImpl, m_transientHeap, &resourceCopyEncoder); auto shaderTableAddr = shaderTableBuffer->getDeviceAddress(); -- cgit v1.2.3