summaryrefslogtreecommitdiff
path: root/tools/gfx
diff options
context:
space:
mode:
authorlucy96chen <47800040+lucy96chen@users.noreply.github.com>2021-12-09 15:15:16 -0800
committerGitHub <noreply@github.com>2021-12-09 15:15:16 -0800
commit62161b802a8efbf6820ba79f880c99e455ab3bf6 (patch)
treeef242700b665abe3094ded3e21dcbfcf593ede14 /tools/gfx
parent1c99a986ae12a3f1ce4cee86191052183d37208a (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.cpp90
-rw-r--r--tools/gfx/vulkan/render-vk.cpp87
-rw-r--r--tools/gfx/vulkan/vk-api.h2
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) \