diff options
| author | lucy96chen <47800040+lucy96chen@users.noreply.github.com> | 2021-12-09 15:15:16 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-12-09 15:15:16 -0800 |
| commit | 62161b802a8efbf6820ba79f880c99e455ab3bf6 (patch) | |
| tree | ef242700b665abe3094ded3e21dcbfcf593ede14 /tools/gfx | |
| parent | 1c99a986ae12a3f1ce4cee86191052183d37208a (diff) | |
Implement instanced and indirect draw calls (#2053)
* Added implementations of drawInstanced, drawIndexedInstanced, drawIndirect, and drawIndexedIndirect to both render-d3d12 and render-vk
* drawInstanced test WIP
* Draw calls implemented, working on debugging test
* Added new test and accompanying shader file
* Fixes.
* Fixes.
Co-authored-by: Yong He <yhe@nvidia.com>
Co-authored-by: Yong He <yonghe@outlook.com>
Diffstat (limited to 'tools/gfx')
| -rw-r--r-- | tools/gfx/d3d12/render-d3d12.cpp | 90 | ||||
| -rw-r--r-- | tools/gfx/vulkan/render-vk.cpp | 87 | ||||
| -rw-r--r-- | tools/gfx/vulkan/vk-api.h | 2 |
3 files changed, 128 insertions, 51 deletions
diff --git a/tools/gfx/d3d12/render-d3d12.cpp b/tools/gfx/d3d12/render-d3d12.cpp index 28128a04d..689c9c087 100644 --- a/tools/gfx/d3d12/render-d3d12.cpp +++ b/tools/gfx/d3d12/render-d3d12.cpp @@ -3424,12 +3424,29 @@ public: IBufferResource* countBuffer, uint64_t countOffset) override { - SLANG_UNUSED(maxDrawCount); - SLANG_UNUSED(argBuffer); - SLANG_UNUSED(argOffset); - SLANG_UNUSED(countBuffer); - SLANG_UNUSED(countOffset); - SLANG_UNIMPLEMENTED_X("drawIndirect"); + prepareDraw(); + + D3D12_INDIRECT_ARGUMENT_DESC args[1]; + args[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW; + + D3D12_COMMAND_SIGNATURE_DESC desc; + desc.ByteStride = 36; + desc.NumArgumentDescs = 1; + desc.pArgumentDescs = args; + + ComPtr<ID3D12CommandSignature> cmdSignature = nullptr; + if (FAILED(m_device->CreateCommandSignature(&desc, nullptr, IID_PPV_ARGS(cmdSignature.writeRef())))) + { + return; + } + + m_d3dCmdList->ExecuteIndirect( + cmdSignature, + maxDrawCount, + (ID3D12Resource*)argBuffer, + argOffset, + (ID3D12Resource*)countBuffer, + countOffset); } virtual SLANG_NO_THROW void SLANG_MCALL drawIndexedIndirect( @@ -3439,12 +3456,29 @@ public: IBufferResource* countBuffer, uint64_t countOffset) override { - SLANG_UNUSED(maxDrawCount); - SLANG_UNUSED(argBuffer); - SLANG_UNUSED(argOffset); - SLANG_UNUSED(countBuffer); - SLANG_UNUSED(countOffset); - SLANG_UNIMPLEMENTED_X("drawIndirect"); + prepareDraw(); + + D3D12_INDIRECT_ARGUMENT_DESC args[1]; + args[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED; + + D3D12_COMMAND_SIGNATURE_DESC desc; + desc.ByteStride = 36; + desc.NumArgumentDescs = 1; + desc.pArgumentDescs = args; + + ComPtr<ID3D12CommandSignature> cmdSignature = nullptr; + if (FAILED(m_device->CreateCommandSignature(&desc, nullptr, IID_PPV_ARGS(cmdSignature.writeRef())))) + { + return; + } + + m_d3dCmdList->ExecuteIndirect( + cmdSignature, + maxDrawCount, + (ID3D12Resource*)argBuffer, + argOffset, + (ID3D12Resource*)countBuffer, + countOffset); } virtual SLANG_NO_THROW Result SLANG_MCALL setSamplePositions( @@ -3464,11 +3498,8 @@ public: UInt startVertex, UInt startInstanceLocation) override { - SLANG_UNUSED(vertexCount); - SLANG_UNUSED(instanceCount); - SLANG_UNUSED(startVertex); - SLANG_UNUSED(startInstanceLocation); - SLANG_UNIMPLEMENTED_X("drawInstanced"); + prepareDraw(); + m_d3dCmdList->DrawInstanced(vertexCount, instanceCount, startVertex, startInstanceLocation); } virtual SLANG_NO_THROW void SLANG_MCALL drawIndexedInstanced( @@ -3478,12 +3509,8 @@ public: int32_t baseVertexLocation, uint32_t startInstanceLocation) override { - SLANG_UNUSED(indexCount); - SLANG_UNUSED(instanceCount); - SLANG_UNUSED(startIndexLocation); - SLANG_UNUSED(baseVertexLocation); - SLANG_UNUSED(startInstanceLocation); - SLANG_UNIMPLEMENTED_X("drawIndexedInstanced"); + prepareDraw(); + m_d3dCmdList->DrawIndexedInstanced(indexCount, instanceCount, startIndexLocation, baseVertexLocation, startInstanceLocation); } }; @@ -4145,7 +4172,7 @@ public: bool isShared = false); Result captureTextureToSurface( - D3D12Resource& resource, + TextureResourceImpl* resource, ResourceState state, ISlangBlob** blob, size_t* outRowPitch, @@ -4485,14 +4512,17 @@ Result D3D12Device::createBuffer(const D3D12_RESOURCE_DESC& resourceDesc, const } Result D3D12Device::captureTextureToSurface( - D3D12Resource& resource, + TextureResourceImpl* resourceImpl, ResourceState state, ISlangBlob** outBlob, size_t* outRowPitch, size_t* outPixelSize) { + auto resource = resourceImpl->m_resource; + const D3D12_RESOURCE_STATES initialState = D3DUtil::translateResourceState(state); + const ITextureResource::Desc& gfxDesc = *resourceImpl->getDesc(); const D3D12_RESOURCE_DESC desc = resource.getResource()->GetDesc(); // Don't bother supporting MSAA for right now @@ -4502,8 +4532,12 @@ Result D3D12Device::captureTextureToSurface( return SLANG_FAIL; } - size_t bytesPerPixel = sizeof(uint32_t); + FormatInfo formatInfo; + gfxGetFormatInfo(gfxDesc.format, &formatInfo); + size_t bytesPerPixel = formatInfo.blockSizeInBytes / formatInfo.pixelsPerBlock; size_t rowPitch = int(desc.Width) * bytesPerPixel; + static const size_t align = 256; // D3D requires minimum 256 byte alignment for texture data. + rowPitch = (rowPitch + align - 1) & ~(align - 1); // Bit trick for rounding up size_t bufferSize = rowPitch * int(desc.Height); if (outRowPitch) *outRowPitch = rowPitch; @@ -5023,7 +5057,7 @@ SlangResult D3D12Device::readTextureResource( size_t* outPixelSize) { return captureTextureToSurface( - static_cast<TextureResourceImpl*>(resource)->m_resource, + static_cast<TextureResourceImpl*>(resource), state, outBlob, outRowPitch, @@ -6097,7 +6131,7 @@ Result D3D12Device::createGraphicsPipelineState(const GraphicsPipelineStateDesc& } else { - psoDesc.DSVFormat = DXGI_FORMAT_D32_FLOAT; + psoDesc.DSVFormat = DXGI_FORMAT_UNKNOWN; if (framebufferLayout->m_renderTargets.getCount()) { psoDesc.SampleDesc.Count = framebufferLayout->m_renderTargets[0].sampleCount; diff --git a/tools/gfx/vulkan/render-vk.cpp b/tools/gfx/vulkan/render-vk.cpp index c48faeb7b..015f7e415 100644 --- a/tools/gfx/vulkan/render-vk.cpp +++ b/tools/gfx/vulkan/render-vk.cpp @@ -4093,12 +4093,19 @@ public: IBufferResource* countBuffer, uint64_t countOffset) override { - SLANG_UNUSED(maxDrawCount); - SLANG_UNUSED(argBuffer); - SLANG_UNUSED(argOffset); - SLANG_UNUSED(countBuffer); - SLANG_UNUSED(countOffset); - SLANG_UNIMPLEMENTED_X("drawIndirect"); + prepareDraw(); + auto& api = *m_api; + // Bind the vertex buffer + if (m_boundVertexBuffers.getCount() > 0 && m_boundVertexBuffers[0].m_buffer) + { + const BoundVertexBuffer& boundVertexBuffer = m_boundVertexBuffers[0]; + + VkBuffer vertexBuffers[] = { boundVertexBuffer.m_buffer->m_buffer.m_buffer }; + VkDeviceSize offsets[] = { VkDeviceSize(boundVertexBuffer.m_offset) }; + + api.vkCmdBindVertexBuffers(m_vkCommandBuffer, 0, 1, vertexBuffers, offsets); + } + api.vkCmdDrawIndirect(m_vkCommandBuffer, (VkBuffer)argBuffer, argOffset, maxDrawCount, sizeof(VkDrawIndirectCommand)); } virtual SLANG_NO_THROW void SLANG_MCALL drawIndexedIndirect( @@ -4108,12 +4115,24 @@ public: IBufferResource* countBuffer, uint64_t countOffset) override { - SLANG_UNUSED(maxDrawCount); - SLANG_UNUSED(argBuffer); - SLANG_UNUSED(argOffset); - SLANG_UNUSED(countBuffer); - SLANG_UNUSED(countOffset); - SLANG_UNIMPLEMENTED_X("drawIndirect"); + prepareDraw(); + auto& api = *m_api; + api.vkCmdBindIndexBuffer( + m_vkCommandBuffer, + m_boundIndexBuffer.m_buffer->m_buffer.m_buffer, + m_boundIndexBuffer.m_offset, + m_boundIndexFormat); + // Bind the vertex buffer + if (m_boundVertexBuffers.getCount() > 0 && m_boundVertexBuffers[0].m_buffer) + { + const BoundVertexBuffer& boundVertexBuffer = m_boundVertexBuffers[0]; + + VkBuffer vertexBuffers[] = { boundVertexBuffer.m_buffer->m_buffer.m_buffer }; + VkDeviceSize offsets[] = { VkDeviceSize(boundVertexBuffer.m_offset) }; + + api.vkCmdBindVertexBuffers(m_vkCommandBuffer, 0, 1, vertexBuffers, offsets); + } + api.vkCmdDrawIndirect(m_vkCommandBuffer, (VkBuffer)argBuffer, argOffset, maxDrawCount, sizeof(VkDrawIndexedIndirectCommand)); } virtual SLANG_NO_THROW Result SLANG_MCALL setSamplePositions( @@ -4133,11 +4152,20 @@ public: UInt startVertex, UInt startInstanceLocation) override { - SLANG_UNUSED(vertexCount); - SLANG_UNUSED(instanceCount); - SLANG_UNUSED(startVertex); - SLANG_UNUSED(startInstanceLocation); - SLANG_UNIMPLEMENTED_X("drawInstanced"); + prepareDraw(); + auto& api = *m_api; + // Bind the vertex buffer + if (m_boundVertexBuffers.getCount() > 0 && m_boundVertexBuffers[0].m_buffer) + { + const BoundVertexBuffer& boundVertexBuffer = m_boundVertexBuffers[0]; + + VkBuffer vertexBuffers[] = { boundVertexBuffer.m_buffer->m_buffer.m_buffer }; + VkDeviceSize offsets[] = { VkDeviceSize(boundVertexBuffer.m_offset) }; + + api.vkCmdBindVertexBuffers(m_vkCommandBuffer, 0, 1, vertexBuffers, offsets); + } + api.vkCmdDraw(m_vkCommandBuffer, static_cast<uint32_t>(vertexCount), static_cast<uint32_t>(instanceCount), + static_cast<uint32_t>(startVertex), static_cast<uint32_t>(startInstanceLocation)); } virtual SLANG_NO_THROW void SLANG_MCALL drawIndexedInstanced( @@ -4147,12 +4175,25 @@ public: int32_t baseVertexLocation, uint32_t startInstanceLocation) override { - SLANG_UNUSED(indexCount); - SLANG_UNUSED(instanceCount); - SLANG_UNUSED(startIndexLocation); - SLANG_UNUSED(baseVertexLocation); - SLANG_UNUSED(startInstanceLocation); - SLANG_UNIMPLEMENTED_X("drawIndexedInstanced"); + prepareDraw(); + auto& api = *m_api; + api.vkCmdBindIndexBuffer( + m_vkCommandBuffer, + m_boundIndexBuffer.m_buffer->m_buffer.m_buffer, + m_boundIndexBuffer.m_offset, + m_boundIndexFormat); + // Bind the vertex buffer + if (m_boundVertexBuffers.getCount() > 0 && m_boundVertexBuffers[0].m_buffer) + { + const BoundVertexBuffer& boundVertexBuffer = m_boundVertexBuffers[0]; + + VkBuffer vertexBuffers[] = { boundVertexBuffer.m_buffer->m_buffer.m_buffer }; + VkDeviceSize offsets[] = { VkDeviceSize(boundVertexBuffer.m_offset) }; + + api.vkCmdBindVertexBuffers(m_vkCommandBuffer, 0, 1, vertexBuffers, offsets); + } + api.vkCmdDraw(m_vkCommandBuffer, static_cast<uint32_t>(indexCount), static_cast<uint32_t>(instanceCount), + static_cast<uint32_t>(baseVertexLocation), static_cast<uint32_t>(startInstanceLocation)); } }; diff --git a/tools/gfx/vulkan/vk-api.h b/tools/gfx/vulkan/vk-api.h index 81cfce973..9cbff8ee4 100644 --- a/tools/gfx/vulkan/vk-api.h +++ b/tools/gfx/vulkan/vk-api.h @@ -85,6 +85,8 @@ namespace gfx { x(vkCmdBindDescriptorSets) \ x(vkCmdDispatch) \ x(vkCmdDraw) \ + x(vkCmdDrawIndirect) \ + x(vkCmdDrawIndexedIndirect) \ x(vkCmdSetScissor) \ x(vkCmdSetViewport) \ x(vkCmdBindVertexBuffers) \ |
