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);
|
D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_IMMUTABLE);
|
||||||
|
|
||||||
const uint8_t* dataIt = static_cast<const uint8_t*>(data);
|
const uint8_t* dataIt = static_cast<const uint8_t*>(data);
|
||||||
D3D11_SUBRESOURCE_DATA upData[16] = {};
|
if (layers > 16)
|
||||||
for (size_t i=0 ; i<layers && i<16 ; ++i)
|
{
|
||||||
|
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].pSysMem = dataIt;
|
||||||
upData[i].SysMemPitch = width * pixelPitch;
|
upData[i].SysMemPitch = width * pixelPitch;
|
||||||
upData[i].SysMemSlicePitch = upData[i].SysMemPitch * height;
|
upData[i].SysMemSlicePitch = upData[i].SysMemPitch * height;
|
||||||
dataIt += upData[i].SysMemSlicePitch;
|
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(),
|
ThrowIfFailed(ctx->m_dev->CreateShaderResourceView(m_tex.Get(),
|
||||||
&CD3D11_SHADER_RESOURCE_VIEW_DESC(m_tex.Get(), D3D_SRV_DIMENSION_TEXTURE2DARRAY, pixelFmt), &m_srv));
|
&CD3D11_SHADER_RESOURCE_VIEW_DESC(m_tex.Get(), D3D_SRV_DIMENSION_TEXTURE2DARRAY, pixelFmt), &m_srv));
|
||||||
}
|
}
|
||||||
|
@ -628,6 +643,7 @@ struct D3D11CommandQueue : IGraphicsCommandQueue
|
||||||
break;
|
break;
|
||||||
self->m_drawBuf = self->m_completeBuf;
|
self->m_drawBuf = self->m_completeBuf;
|
||||||
|
|
||||||
|
/* Process dynamic loads */
|
||||||
ID3D11CommandList* list = self->m_dynamicList.Get();
|
ID3D11CommandList* list = self->m_dynamicList.Get();
|
||||||
self->m_ctx->m_devCtx->ExecuteCommandList(list, false);
|
self->m_ctx->m_devCtx->ExecuteCommandList(list, false);
|
||||||
self->m_dynamicList.Reset();
|
self->m_dynamicList.Reset();
|
||||||
|
@ -1061,8 +1077,14 @@ void D3D11CommandQueue::execute()
|
||||||
ThrowIfFailed(m_deferredCtx->FinishCommandList(false, &m_cmdLists[m_fillBuf]));
|
ThrowIfFailed(m_deferredCtx->FinishCommandList(false, &m_cmdLists[m_fillBuf]));
|
||||||
m_workDoPresent[m_fillBuf] = m_doPresent;
|
m_workDoPresent[m_fillBuf] = m_doPresent;
|
||||||
m_doPresent = nullptr;
|
m_doPresent = nullptr;
|
||||||
|
|
||||||
|
/* Wait for worker thread to become ready */
|
||||||
std::unique_lock<std::mutex> lk(m_mt);
|
std::unique_lock<std::mutex> lk(m_mt);
|
||||||
|
|
||||||
|
/* Gather dynamic uploads for worker thread */
|
||||||
ThrowIfFailed(m_dynamicCtx->FinishCommandList(false, &m_dynamicList));
|
ThrowIfFailed(m_dynamicCtx->FinishCommandList(false, &m_dynamicList));
|
||||||
|
|
||||||
|
/* Ready for next frame */
|
||||||
m_completeBuf = m_fillBuf;
|
m_completeBuf = m_fillBuf;
|
||||||
for (size_t i=0 ; i<3 ; ++i)
|
for (size_t i=0 ; i<3 ; ++i)
|
||||||
{
|
{
|
||||||
|
@ -1071,6 +1093,8 @@ void D3D11CommandQueue::execute()
|
||||||
m_fillBuf = i;
|
m_fillBuf = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return control to worker thread */
|
||||||
lk.unlock();
|
lk.unlock();
|
||||||
m_cv.notify_one();
|
m_cv.notify_one();
|
||||||
}
|
}
|
||||||
|
|
|
@ -243,18 +243,34 @@ class D3D12TextureSA : public ITextureSA
|
||||||
D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, __uuidof(ID3D12Resource), &m_tex));
|
D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, __uuidof(ID3D12Resource), &m_tex));
|
||||||
|
|
||||||
const uint8_t* dataIt = static_cast<const uint8_t*>(data);
|
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)
|
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].pData = dataIt;
|
||||||
upData[i].RowPitch = width * pxPitch;
|
upData[i].RowPitch = width * pxPitch;
|
||||||
upData[i].SlicePitch = upData[i].RowPitch * height;
|
upData[i].SlicePitch = upData[i].RowPitch * height;
|
||||||
dataIt += upData[i].SlicePitch;
|
dataIt += upData[i].SlicePitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PrepSubresources<16>(ctx->m_dev.Get(), &m_gpuDesc, m_tex.Get(), 0, 0, layers, upData))
|
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");
|
Log.report(LogVisor::FatalError, "error preparing resource for upload");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
public:
|
public:
|
||||||
ComPtr<ID3D12Resource> m_tex;
|
ComPtr<ID3D12Resource> m_tex;
|
||||||
ComPtr<ID3D12Resource> m_gpuTex;
|
ComPtr<ID3D12Resource> m_gpuTex;
|
||||||
|
@ -266,9 +282,18 @@ public:
|
||||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||||
nullptr, __uuidof(ID3D12Resource), &m_gpuTex));
|
nullptr, __uuidof(ID3D12Resource), &m_gpuTex));
|
||||||
|
|
||||||
|
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);
|
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(),
|
ctx->m_loadlist->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_gpuTex.Get(),
|
||||||
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE));
|
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE));
|
||||||
|
}
|
||||||
|
|
||||||
return NextHeapOffset(offset, ctx->m_dev->GetResourceAllocationInfo(0, 1, &m_gpuDesc));
|
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>
|
template <UINT MaxSubresources>
|
||||||
inline UINT64 PrepSubresources(
|
inline UINT64 PrepSubresources(
|
||||||
_In_ ID3D12Device* pDevice,
|
_In_ ID3D12Device* pDevice,
|
||||||
_In_ D3D12_RESOURCE_DESC* DestinationDesc,
|
_In_ D3D12_RESOURCE_DESC* DestinationDesc,
|
||||||
_In_ ID3D12Resource* pIntermediate,
|
_In_ ID3D12Resource* pIntermediate,
|
||||||
UINT64 IntermediateOffset,
|
UINT64 IntermediateOffset,
|
||||||
_In_range_(0, MaxSubresources) UINT FirstSubresource,
|
_In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
|
||||||
_In_range_(1, MaxSubresources - FirstSubresource) UINT NumSubresources,
|
_In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
|
||||||
_In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData)
|
_In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData)
|
||||||
{
|
{
|
||||||
UINT64 RequiredSize = 0;
|
UINT64 RequiredSize = 0;
|
||||||
|
@ -1561,6 +1594,56 @@ inline UINT64 PrepSubresources(
|
||||||
return PrepSubresources(pDevice, DestinationDesc, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pSrcData);
|
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>
|
template <UINT MaxSubresources>
|
||||||
inline void CommandSubresourcesTransfer(
|
inline void CommandSubresourcesTransfer(
|
||||||
_In_ ID3D12Device* pDevice,
|
_In_ ID3D12Device* pDevice,
|
||||||
|
|
Loading…
Reference in New Issue