summaryrefslogtreecommitdiffstats
path: root/tools/gfx/d3d11
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2021-06-04 14:32:22 -0700
committerGitHub <noreply@github.com>2021-06-04 14:32:22 -0700
commit95a90d7fda3097d085cde1fea5213667277e729b (patch)
tree54558aabdaaa27b2298a214781e13218cc3881e9 /tools/gfx/d3d11
parentbf068b17406a202ae3112f5617bbb4da595c9ae9 (diff)
Fix D3D11 `uploadBufferResource`. (#1869)
Diffstat (limited to 'tools/gfx/d3d11')
-rw-r--r--tools/gfx/d3d11/render-d3d11.cpp82
1 files changed, 62 insertions, 20 deletions
diff --git a/tools/gfx/d3d11/render-d3d11.cpp b/tools/gfx/d3d11/render-d3d11.cpp
index d4a55543c..3e71ff3d4 100644
--- a/tools/gfx/d3d11/render-d3d11.cpp
+++ b/tools/gfx/d3d11/render-d3d11.cpp
@@ -117,7 +117,7 @@ public:
const ComputePipelineStateDesc& desc, IPipelineState** outState) override;
virtual void* map(IBufferResource* buffer, MapFlavor flavor) override;
- virtual void unmap(IBufferResource* buffer) override;
+ virtual void unmap(IBufferResource* buffer, size_t offsetWritten, size_t sizeWritten) override;
virtual void copyBuffer(
IBufferResource* dst,
size_t dstOffset,
@@ -181,8 +181,10 @@ protected:
}
MapFlavor m_mapFlavor;
+ D3D11_USAGE m_d3dUsage;
ComPtr<ID3D11Buffer> m_buffer;
ComPtr<ID3D11Buffer> m_staging;
+ List<uint8_t> m_uploadStagingBuffer;
};
class TextureResourceImpl : public TextureResource
{
@@ -1462,7 +1464,7 @@ protected:
auto ordinaryData = device->map(m_ordinaryDataBuffer, gfx::MapFlavor::WriteDiscard);
auto result = _writeOrdinaryData(ordinaryData, specializedOrdinaryDataSize, specializedLayout);
- device->unmap(m_ordinaryDataBuffer);
+ device->unmap(m_ordinaryDataBuffer, 0, specializedOrdinaryDataSize);
return result;
}
@@ -2013,7 +2015,11 @@ static bool _isSupportedNVAPIOp(IUnknown* dev, uint32_t op)
SlangResult D3D11Device::initialize(const Desc& desc)
{
- SLANG_RETURN_ON_FAIL(slangContext.initialize(desc.slang, SLANG_DXBC, "sm_5_0"));
+ SLANG_RETURN_ON_FAIL(slangContext.initialize(
+ desc.slang,
+ SLANG_DXBC,
+ "sm_5_0",
+ makeArray(slang::PreprocessorMacroDesc{ "__D3D11__", "1" }).getView()));
SLANG_RETURN_ON_FAIL(RendererBase::initialize(desc));
@@ -2603,8 +2609,10 @@ Result D3D11Device::createBufferResource(const IBufferResource::Desc& descIn, co
RefPtr<BufferResourceImpl> buffer(new BufferResourceImpl(srcDesc));
SLANG_RETURN_ON_FAIL(m_device->CreateBuffer(&bufferDesc, initData ? &subResourceData : nullptr, buffer->m_buffer.writeRef()));
+ buffer->m_d3dUsage = bufferDesc.Usage;
- if (srcDesc.cpuAccessFlags & IResource::AccessFlag::Read)
+ if ((srcDesc.cpuAccessFlags & IResource::AccessFlag::Read) ||
+ ((srcDesc.cpuAccessFlags & IResource::AccessFlag::Write) && bufferDesc.Usage != D3D11_USAGE_DYNAMIC))
{
D3D11_BUFFER_DESC bufDesc = {};
bufDesc.BindFlags = 0;
@@ -2614,7 +2622,6 @@ Result D3D11Device::createBufferResource(const IBufferResource::Desc& descIn, co
SLANG_RETURN_ON_FAIL(m_device->CreateBuffer(&bufDesc, nullptr, buffer->m_staging.writeRef()));
}
-
returnComPtr(outResource, buffer);
return SLANG_OK;
}
@@ -2981,37 +2988,72 @@ void* D3D11Device::map(IBufferResource* bufferIn, MapFlavor flavor)
break;
case MapFlavor::HostRead:
mapType = D3D11_MAP_READ;
-
- buffer = bufferResource->m_staging;
- if (!buffer)
- {
- return nullptr;
- }
-
- // Okay copy the data over
- m_immediateContext->CopyResource(buffer, bufferResource->m_buffer);
-
break;
default:
return nullptr;
}
+ bufferResource->m_mapFlavor = flavor;
+
+ switch (flavor)
+ {
+ case MapFlavor::WriteDiscard:
+ case MapFlavor::HostWrite:
+ // If buffer is not dynamic, we need to use staging buffer.
+ if (bufferResource->m_d3dUsage != D3D11_USAGE_DYNAMIC)
+ {
+ bufferResource->m_uploadStagingBuffer.setCount(bufferResource->getDesc()->sizeInBytes);
+ return bufferResource->m_uploadStagingBuffer.getBuffer();
+ }
+ break;
+ case MapFlavor::HostRead:
+ buffer = bufferResource->m_staging;
+ if (!buffer)
+ {
+ return nullptr;
+ }
+
+ // Okay copy the data over
+ m_immediateContext->CopyResource(buffer, bufferResource->m_buffer);
+
+ }
+
// We update our constant buffer per-frame, just for the purposes
// of the example, but we don't actually load different data
// per-frame (we always use an identity projection).
D3D11_MAPPED_SUBRESOURCE mappedSub;
SLANG_RETURN_NULL_ON_FAIL(m_immediateContext->Map(buffer, 0, mapType, 0, &mappedSub));
- bufferResource->m_mapFlavor = flavor;
-
return mappedSub.pData;
}
-void D3D11Device::unmap(IBufferResource* bufferIn)
+void D3D11Device::unmap(IBufferResource* bufferIn, size_t offsetWritten, size_t sizeWritten)
{
BufferResourceImpl* bufferResource = static_cast<BufferResourceImpl*>(bufferIn);
- ID3D11Buffer* buffer = (bufferResource->m_mapFlavor == MapFlavor::HostRead) ? bufferResource->m_staging : bufferResource->m_buffer;
- m_immediateContext->Unmap(buffer, 0);
+ switch (bufferResource->m_mapFlavor)
+ {
+ case MapFlavor::WriteDiscard:
+ case MapFlavor::HostWrite:
+ // If buffer is not dynamic, the CPU has already written to the staging buffer,
+ // and we need to copy the content over to the GPU buffer.
+ if (bufferResource->m_d3dUsage != D3D11_USAGE_DYNAMIC && sizeWritten != 0)
+ {
+ D3D11_BOX dstBox = {};
+ dstBox.left = (UINT)offsetWritten;
+ dstBox.right = (UINT)(offsetWritten + sizeWritten);
+ dstBox.back = 1;
+ dstBox.bottom = 1;
+ m_immediateContext->UpdateSubresource(
+ bufferResource->m_buffer,
+ 0,
+ &dstBox,
+ bufferResource->m_uploadStagingBuffer.getBuffer() + offsetWritten,
+ 0,
+ 0);
+ return;
+ }
+ }
+ m_immediateContext->Unmap(bufferResource->m_mapFlavor == MapFlavor::HostRead ? bufferResource->m_staging : bufferResource->m_buffer, 0);
}
#if 0