mirror of https://github.com/AxioDL/boo.git
D3D Crash fix for large array textures
This commit is contained in:
parent
08655b7f93
commit
6062302816
|
@ -158,16 +158,31 @@ class D3D11TextureSA : public ITextureSA
|
|||
D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_IMMUTABLE);
|
||||
|
||||
const uint8_t* dataIt = static_cast<const uint8_t*>(data);
|
||||
D3D11_SUBRESOURCE_DATA upData[16] = {};
|
||||
for (size_t i=0 ; i<layers && i<16 ; ++i)
|
||||
if (layers > 16)
|
||||
{
|
||||
upData[i].pSysMem = dataIt;
|
||||
upData[i].SysMemPitch = width * pixelPitch;
|
||||
upData[i].SysMemSlicePitch = upData[i].SysMemPitch * height;
|
||||
dataIt += upData[i].SysMemSlicePitch;
|
||||
std::unique_ptr<D3D11_SUBRESOURCE_DATA[]> upData(new D3D11_SUBRESOURCE_DATA[layers]);
|
||||
for (size_t i=0 ; i<layers ; ++i)
|
||||
{
|
||||
upData[i].pSysMem = dataIt;
|
||||
upData[i].SysMemPitch = width * pixelPitch;
|
||||
upData[i].SysMemSlicePitch = upData[i].SysMemPitch * height;
|
||||
dataIt += upData[i].SysMemSlicePitch;
|
||||
}
|
||||
ThrowIfFailed(ctx->m_dev->CreateTexture2D(&desc, upData.get(), &m_tex));
|
||||
}
|
||||
else
|
||||
{
|
||||
D3D11_SUBRESOURCE_DATA upData[16] = {};
|
||||
for (size_t i=0 ; i<layers ; ++i)
|
||||
{
|
||||
upData[i].pSysMem = dataIt;
|
||||
upData[i].SysMemPitch = width * pixelPitch;
|
||||
upData[i].SysMemSlicePitch = upData[i].SysMemPitch * height;
|
||||
dataIt += upData[i].SysMemSlicePitch;
|
||||
}
|
||||
ThrowIfFailed(ctx->m_dev->CreateTexture2D(&desc, upData, &m_tex));
|
||||
}
|
||||
|
||||
ThrowIfFailed(ctx->m_dev->CreateTexture2D(&desc, upData, &m_tex));
|
||||
ThrowIfFailed(ctx->m_dev->CreateShaderResourceView(m_tex.Get(),
|
||||
&CD3D11_SHADER_RESOURCE_VIEW_DESC(m_tex.Get(), D3D_SRV_DIMENSION_TEXTURE2DARRAY, pixelFmt), &m_srv));
|
||||
}
|
||||
|
@ -628,6 +643,7 @@ struct D3D11CommandQueue : IGraphicsCommandQueue
|
|||
break;
|
||||
self->m_drawBuf = self->m_completeBuf;
|
||||
|
||||
/* Process dynamic loads */
|
||||
ID3D11CommandList* list = self->m_dynamicList.Get();
|
||||
self->m_ctx->m_devCtx->ExecuteCommandList(list, false);
|
||||
self->m_dynamicList.Reset();
|
||||
|
@ -1061,8 +1077,14 @@ void D3D11CommandQueue::execute()
|
|||
ThrowIfFailed(m_deferredCtx->FinishCommandList(false, &m_cmdLists[m_fillBuf]));
|
||||
m_workDoPresent[m_fillBuf] = m_doPresent;
|
||||
m_doPresent = nullptr;
|
||||
|
||||
/* Wait for worker thread to become ready */
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
|
||||
/* Gather dynamic uploads for worker thread */
|
||||
ThrowIfFailed(m_dynamicCtx->FinishCommandList(false, &m_dynamicList));
|
||||
|
||||
/* Ready for next frame */
|
||||
m_completeBuf = m_fillBuf;
|
||||
for (size_t i=0 ; i<3 ; ++i)
|
||||
{
|
||||
|
@ -1071,6 +1093,8 @@ void D3D11CommandQueue::execute()
|
|||
m_fillBuf = i;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Return control to worker thread */
|
||||
lk.unlock();
|
||||
m_cv.notify_one();
|
||||
}
|
||||
|
|
|
@ -243,17 +243,33 @@ class D3D12TextureSA : public ITextureSA
|
|||
D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, __uuidof(ID3D12Resource), &m_tex));
|
||||
|
||||
const uint8_t* dataIt = static_cast<const uint8_t*>(data);
|
||||
D3D12_SUBRESOURCE_DATA upData[16] = {};
|
||||
for (size_t i=0 ; i<layers && i<16 ; ++i)
|
||||
{
|
||||
upData[i].pData = dataIt;
|
||||
upData[i].RowPitch = width * pxPitch;
|
||||
upData[i].SlicePitch = upData[i].RowPitch * height;
|
||||
dataIt += upData[i].SlicePitch;
|
||||
}
|
||||
|
||||
if (!PrepSubresources<16>(ctx->m_dev.Get(), &m_gpuDesc, m_tex.Get(), 0, 0, layers, upData))
|
||||
Log.report(LogVisor::FatalError, "error preparing resource for upload");
|
||||
if (layers > 16)
|
||||
{
|
||||
std::unique_ptr<D3D12_SUBRESOURCE_DATA[]> upData(new D3D12_SUBRESOURCE_DATA[layers]);
|
||||
for (size_t i=0 ; i<layers ; ++i)
|
||||
{
|
||||
upData[i].pData = dataIt;
|
||||
upData[i].RowPitch = width * pxPitch;
|
||||
upData[i].SlicePitch = upData[i].RowPitch * height;
|
||||
dataIt += upData[i].SlicePitch;
|
||||
}
|
||||
if (!PrepSubresources(ctx->m_dev.Get(), &m_gpuDesc, m_tex.Get(), 0, 0, layers, upData.get()))
|
||||
Log.report(LogVisor::FatalError, "error preparing resource for upload");
|
||||
}
|
||||
else
|
||||
{
|
||||
D3D12_SUBRESOURCE_DATA upData[16] = {};
|
||||
for (size_t i=0 ; i<layers ; ++i)
|
||||
{
|
||||
upData[i].pData = dataIt;
|
||||
upData[i].RowPitch = width * pxPitch;
|
||||
upData[i].SlicePitch = upData[i].RowPitch * height;
|
||||
dataIt += upData[i].SlicePitch;
|
||||
}
|
||||
if (!PrepSubresources<16>(ctx->m_dev.Get(), &m_gpuDesc, m_tex.Get(), 0, 0, layers, upData))
|
||||
Log.report(LogVisor::FatalError, "error preparing resource for upload");
|
||||
}
|
||||
}
|
||||
public:
|
||||
ComPtr<ID3D12Resource> m_tex;
|
||||
|
@ -266,9 +282,18 @@ public:
|
|||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
nullptr, __uuidof(ID3D12Resource), &m_gpuTex));
|
||||
|
||||
CommandSubresourcesTransfer<16>(ctx->m_dev.Get(), ctx->m_loadlist.Get(), m_gpuTex.Get(), m_tex.Get(), 0, 0, m_gpuDesc.DepthOrArraySize);
|
||||
ctx->m_loadlist->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_gpuTex.Get(),
|
||||
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE));
|
||||
if (m_gpuDesc.DepthOrArraySize > 16)
|
||||
{
|
||||
CommandSubresourcesTransfer(ctx->m_dev.Get(), ctx->m_loadlist.Get(), m_gpuTex.Get(), m_tex.Get(), 0, 0, m_gpuDesc.DepthOrArraySize);
|
||||
ctx->m_loadlist->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_gpuTex.Get(),
|
||||
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE));
|
||||
}
|
||||
else
|
||||
{
|
||||
CommandSubresourcesTransfer<16>(ctx->m_dev.Get(), ctx->m_loadlist.Get(), m_gpuTex.Get(), m_tex.Get(), 0, 0, m_gpuDesc.DepthOrArraySize);
|
||||
ctx->m_loadlist->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_gpuTex.Get(),
|
||||
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE));
|
||||
}
|
||||
|
||||
return NextHeapOffset(offset, ctx->m_dev->GetResourceAllocationInfo(0, 1, &m_gpuDesc));
|
||||
}
|
||||
|
|
|
@ -1540,15 +1540,48 @@ inline UINT64 PrepSubresources(
|
|||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
// Stack-allocating UpdateSubresources implementation
|
||||
// Heap-allocating PrepSubresources implementation
|
||||
inline UINT64 PrepSubresources(
|
||||
_In_ ID3D12Device* pDevice,
|
||||
_In_ D3D12_RESOURCE_DESC* DestinationDesc,
|
||||
_In_ ID3D12Resource* pIntermediate,
|
||||
UINT64 IntermediateOffset,
|
||||
_In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
|
||||
_In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
|
||||
_In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData)
|
||||
{
|
||||
UINT64 RequiredSize = 0;
|
||||
UINT64 MemToAlloc = static_cast<UINT64>(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(UINT) + sizeof(UINT64)) * NumSubresources;
|
||||
if (MemToAlloc > SIZE_MAX)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
void* pMem = HeapAlloc(GetProcessHeap(), 0, static_cast<SIZE_T>(MemToAlloc));
|
||||
if (pMem == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts = reinterpret_cast<D3D12_PLACED_SUBRESOURCE_FOOTPRINT*>(pMem);
|
||||
UINT64* pRowSizesInBytes = reinterpret_cast<UINT64*>(pLayouts + NumSubresources);
|
||||
UINT* pNumRows = reinterpret_cast<UINT*>(pRowSizesInBytes + NumSubresources);
|
||||
|
||||
pDevice->GetCopyableFootprints(DestinationDesc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize);
|
||||
|
||||
UINT64 result = PrepSubresources(pDevice, DestinationDesc, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pSrcData);
|
||||
HeapFree(GetProcessHeap(), 0, pMem);
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
// Stack-allocating PrepSubresources implementation
|
||||
template <UINT MaxSubresources>
|
||||
inline UINT64 PrepSubresources(
|
||||
_In_ ID3D12Device* pDevice,
|
||||
_In_ D3D12_RESOURCE_DESC* DestinationDesc,
|
||||
_In_ ID3D12Resource* pIntermediate,
|
||||
UINT64 IntermediateOffset,
|
||||
_In_range_(0, MaxSubresources) UINT FirstSubresource,
|
||||
_In_range_(1, MaxSubresources - FirstSubresource) UINT NumSubresources,
|
||||
_In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
|
||||
_In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
|
||||
_In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData)
|
||||
{
|
||||
UINT64 RequiredSize = 0;
|
||||
|
@ -1561,6 +1594,56 @@ inline UINT64 PrepSubresources(
|
|||
return PrepSubresources(pDevice, DestinationDesc, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pSrcData);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
// Heap-allocating CommandSubresourcesTransfer implementation
|
||||
inline void CommandSubresourcesTransfer(
|
||||
_In_ ID3D12Device* pDevice,
|
||||
_In_ ID3D12GraphicsCommandList* pCmdList,
|
||||
_In_ ID3D12Resource* pDestinationResource,
|
||||
_In_ ID3D12Resource* pIntermediate,
|
||||
UINT64 IntermediateOffset,
|
||||
_In_range_(0, MaxSubresources) UINT FirstSubresource,
|
||||
_In_range_(1, MaxSubresources - FirstSubresource) UINT NumSubresources)
|
||||
{
|
||||
UINT64 RequiredSize = 0;
|
||||
UINT64 MemToAlloc = static_cast<UINT64>(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(UINT) + sizeof(UINT64)) * NumSubresources;
|
||||
if (MemToAlloc > SIZE_MAX)
|
||||
{
|
||||
return;
|
||||
}
|
||||
void* pMem = HeapAlloc(GetProcessHeap(), 0, static_cast<SIZE_T>(MemToAlloc));
|
||||
if (pMem == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts = reinterpret_cast<D3D12_PLACED_SUBRESOURCE_FOOTPRINT*>(pMem);
|
||||
UINT64* pRowSizesInBytes = reinterpret_cast<UINT64*>(pLayouts + NumSubresources);
|
||||
UINT* pNumRows = reinterpret_cast<UINT*>(pRowSizesInBytes + NumSubresources);
|
||||
|
||||
D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc();
|
||||
pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize);
|
||||
|
||||
if (Desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
|
||||
{
|
||||
CD3DX12_BOX SrcBox( UINT( pLayouts[0].Offset ), UINT( pLayouts[0].Offset + pLayouts[0].Footprint.Width ) );
|
||||
pCmdList->CopyBufferRegion(
|
||||
pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (UINT i = 0; i < NumSubresources; ++i)
|
||||
{
|
||||
CD3DX12_TEXTURE_COPY_LOCATION Dst(pDestinationResource, i + FirstSubresource);
|
||||
CD3DX12_TEXTURE_COPY_LOCATION Src(pIntermediate, pLayouts[i]);
|
||||
pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, pMem);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
// Stack-allocating CommandSubresourcesTransfer implementation
|
||||
template <UINT MaxSubresources>
|
||||
inline void CommandSubresourcesTransfer(
|
||||
_In_ ID3D12Device* pDevice,
|
||||
|
|
Loading…
Reference in New Issue