From aee4aa3528072e4b5e95ccc4e571868716b47d50 Mon Sep 17 00:00:00 2001 From: lucy96chen <47800040+lucy96chen@users.noreply.github.com> Date: Mon, 10 Jan 2022 11:00:50 -0800 Subject: Draw call tests for Vulkan (#2073) * Added instancing support to Vulkan, drawInstanced() test image is upside-down * Fixed inverted drawInstanced() test output by changing Vulkan viewport convention * Replaced vkCmdDraw with vkCmdDrawIndexed in all non-indirect indexed draws, drawIndexedIndirect test now working for Vulkan * Moved index and vertex buffer binding into setIndexBuffer and setVertexBuffers; Defaulted countBuffer to nullptr and countOffset to 0 and added a check for non-null countBuffer to drawIndirect and drawIndexedIndirect in Vulkan; All Vulkan draw tests working (but D3D12 tests broken) * Added support for drawInstanced and drawIndexedInstanced to D3D11 and added tests for both, however D3D11 tests are currently disabled due to readTextureResource assuming a fixed pixel size (among other possible problems); Fixed issues causing D3D12 tests to fail after major back-end fixes to get Vulkan up and running * Removed testing function for dumping images and some other commented out code * Removed some commented out code * Fix initializer list causing builds to fail (attempt 1) * Removed initializer list for VertexStreamDesc in createInputLayout() and fill in struct fields normally (build fix attempt 2) * Removed default values from VertexStreamDesc and changed all initializer lists to reflect this change * Moved applyBinding before setVertexBuffer in RenderTestApp::renderFrame() to ensure the pipeline has already been bound before vertex buffers are * Changed D3D11's readTextureResource to calculate pixel size using format-specific size information; Removed wrapper around D3D11 instanced and indexed instanced draw tests --- tools/gfx/d3d11/render-d3d11.cpp | 78 ++++++++++++++++++++++++++++++++++------ 1 file changed, 67 insertions(+), 11 deletions(-) (limited to 'tools/gfx/d3d11/render-d3d11.cpp') diff --git a/tools/gfx/d3d11/render-d3d11.cpp b/tools/gfx/d3d11/render-d3d11.cpp index aa5136873..f31cce931 100644 --- a/tools/gfx/d3d11/render-d3d11.cpp +++ b/tools/gfx/d3d11/render-d3d11.cpp @@ -97,8 +97,7 @@ public: IResourceView** outView) override; virtual SLANG_NO_THROW Result SLANG_MCALL createInputLayout( - const InputElementDesc* inputElements, - UInt inputElementCount, + IInputLayout::Desc const& desc, IInputLayout** outLayout) override; virtual SLANG_NO_THROW Result SLANG_MCALL createQueryPool( @@ -138,7 +137,6 @@ public: uint32_t startSlot, uint32_t slotCount, IBufferResource* const* buffers, - const uint32_t* strides, const uint32_t* offsets) override; virtual void setIndexBuffer( IBufferResource* buffer, Format indexFormat, uint32_t offset) override; @@ -148,6 +146,17 @@ public: virtual void draw(uint32_t vertexCount, uint32_t startVertex) override; virtual void drawIndexed( uint32_t indexCount, uint32_t startIndex, uint32_t baseVertex) override; + virtual void drawInstanced( + uint32_t vertexCount, + uint32_t instanceCount, + uint32_t startVertex, + uint32_t startInstanceLocation) override; + virtual void drawIndexedInstanced( + uint32_t indexCount, + uint32_t instanceCount, + uint32_t startIndexLocation, + int32_t baseVertexLocation, + uint32_t startInstanceLocation) override; virtual void dispatchCompute(int x, int y, int z) override; virtual void submitGpuWork() override {} virtual void waitForGpu() override @@ -350,6 +359,7 @@ protected: { public: ComPtr m_layout; + List m_vertexStreamStrides; }; class QueryPoolImpl : public QueryPoolBase @@ -2412,7 +2422,7 @@ Result D3D11Device::createFramebuffer( framebuffer->d3dRenderTargetViews[i] = framebuffer->renderTargetViews[i]->m_rtv; } framebuffer->depthStencilView = static_cast(desc.depthStencilView); - framebuffer->d3dDepthStencilView = framebuffer->depthStencilView->m_dsv; + framebuffer->d3dDepthStencilView = framebuffer->depthStencilView ? framebuffer->depthStencilView->m_dsv : nullptr; returnComPtr(outFramebuffer, framebuffer); return SLANG_OK; } @@ -2452,7 +2462,9 @@ SlangResult D3D11Device::readTextureResource( return E_INVALIDARG; } - size_t bytesPerPixel = sizeof(uint32_t); + FormatInfo sizeInfo; + gfxGetFormatInfo(texture->getDesc()->format, &sizeInfo); + size_t bytesPerPixel = sizeInfo.blockSizeInBytes / sizeInfo.pixelsPerBlock; size_t rowPitch = int(texture->getDesc()->size.width) * bytesPerPixel; size_t bufferSize = rowPitch * int(texture->getDesc()->size.height); if (outRowPitch) @@ -3069,7 +3081,7 @@ Result D3D11Device::createBufferView(IBufferResource* buffer, IResourceView::Des } } -Result D3D11Device::createInputLayout(const InputElementDesc* inputElementsIn, UInt inputElementCount, IInputLayout** outLayout) +Result D3D11Device::createInputLayout(IInputLayout::Desc const& desc, IInputLayout** outLayout) { D3D11_INPUT_ELEMENT_DESC inputElements[16] = {}; @@ -3078,15 +3090,21 @@ Result D3D11Device::createInputLayout(const InputElementDesc* inputElementsIn, U hlslCursor += sprintf(hlslCursor, "float4 main(\n"); + auto inputElementCount = desc.inputElementCount; + auto inputElementsIn = desc.inputElements; for (UInt ii = 0; ii < inputElementCount; ++ii) { + auto vertexStreamIndex = inputElementsIn[ii].bufferSlotIndex; + auto& vertexStream = desc.vertexStreams[vertexStreamIndex]; + inputElements[ii].SemanticName = inputElementsIn[ii].semanticName; inputElements[ii].SemanticIndex = (UINT)inputElementsIn[ii].semanticIndex; inputElements[ii].Format = D3DUtil::getMapFormat(inputElementsIn[ii].format); - inputElements[ii].InputSlot = 0; + inputElements[ii].InputSlot = vertexStreamIndex; inputElements[ii].AlignedByteOffset = (UINT)inputElementsIn[ii].offset; - inputElements[ii].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; - inputElements[ii].InstanceDataStepRate = 0; + inputElements[ii].InputSlotClass = + (vertexStream.slotClass == InputSlotClass::PerInstance) ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA; + inputElements[ii].InstanceDataStepRate = vertexStream.instanceDataStepRate; if (ii != 0) { @@ -3132,6 +3150,13 @@ Result D3D11Device::createInputLayout(const InputElementDesc* inputElementsIn, U RefPtr impl = new InputLayoutImpl; impl->m_layout.swap(inputLayout); + auto vertexStreamCount = desc.vertexStreamCount; + impl->m_vertexStreamStrides.setCount(vertexStreamCount); + for (Int i = 0; i < vertexStreamCount; ++i) + { + impl->m_vertexStreamStrides[i] = desc.vertexStreams[i].stride; + } + returnComPtr(outLayout, impl); return SLANG_OK; } @@ -3246,11 +3271,11 @@ void D3D11Device::setVertexBuffers( uint32_t startSlot, uint32_t slotCount, IBufferResource* const* buffersIn, - const uint32_t* stridesIn, const uint32_t* offsetsIn) { static const int kMaxVertexBuffers = 16; assert(slotCount <= kMaxVertexBuffers); + assert(m_currentPipelineState); // The pipeline state should be created before setting vertex buffers. UINT vertexStrides[kMaxVertexBuffers]; UINT vertexOffsets[kMaxVertexBuffers]; @@ -3260,7 +3285,8 @@ void D3D11Device::setVertexBuffers( for (UInt ii = 0; ii < slotCount; ++ii) { - vertexStrides[ii] = (UINT)stridesIn[ii]; + auto inputLayout = (InputLayoutImpl*)m_currentPipelineState->inputLayout.Ptr(); + vertexStrides[ii] = inputLayout->m_vertexStreamStrides[startSlot + ii]; vertexOffsets[ii] = (UINT)offsetsIn[ii]; dxBuffers[ii] = buffers[ii]->m_buffer; } @@ -3400,6 +3426,36 @@ void D3D11Device::drawIndexed(uint32_t indexCount, uint32_t startIndex, uint32_t m_immediateContext->DrawIndexed(indexCount, startIndex, baseVertex); } +void D3D11Device::drawInstanced( + uint32_t vertexCount, + uint32_t instanceCount, + uint32_t startVertex, + uint32_t startInstanceLocation) +{ + _flushGraphicsState(); + m_immediateContext->DrawInstanced( + vertexCount, + instanceCount, + startVertex, + startInstanceLocation); +} + +void D3D11Device::drawIndexedInstanced( + uint32_t indexCount, + uint32_t instanceCount, + uint32_t startIndexLocation, + int32_t baseVertexLocation, + uint32_t startInstanceLocation) +{ + _flushGraphicsState(); + m_immediateContext->DrawIndexedInstanced( + indexCount, + instanceCount, + startIndexLocation, + baseVertexLocation, + startInstanceLocation); +} + Result D3D11Device::createProgram(const IShaderProgram::Desc& desc, IShaderProgram** outProgram) { SLANG_ASSERT(desc.slangProgram); -- cgit v1.2.3