@@ -54,7 +54,7 @@ class UploadBufferD3D11 : public UploadBufferBase
5454{
5555public:
5656 UploadBufferD3D11 (IReferenceCounters* pRefCounters, const UploadBufferDesc& Desc, ID3D11Texture2D* pStagingTexture) :
57- UploadBufferBase{pRefCounters, Desc},
57+ UploadBufferBase{pRefCounters, Desc, /* AllocateStagingData = */ pStagingTexture == nullptr },
5858 m_pStagingTexture{pStagingTexture}
5959 {}
6060
@@ -65,7 +65,10 @@ class UploadBufferD3D11 : public UploadBufferBase
6565 // http://en.cppreference.com/w/cpp/thread/condition_variable
6666 void WaitForMap ()
6767 {
68- m_BufferMappedSignal.Wait ();
68+ if (!HasStagingData ())
69+ {
70+ m_BufferMappedSignal.Wait ();
71+ }
6972 }
7073
7174 void SignalMapped ()
@@ -275,11 +278,13 @@ void TextureUploaderD3D11::InternalData::Execute(ID3D11DeviceContext* pd3d11N
275278{
276279 RefCntAutoPtr<UploadBufferD3D11>& pBuffer = Operation.pUploadBuffer ;
277280 const UploadBufferDesc& UploadBuffDesc = pBuffer->GetDesc ();
281+ ID3D11Texture2D* pStagingTex = pBuffer->GetStagingTex ();
278282
279283 switch (Operation.OpType )
280284 {
281285 case InternalData::PendingBufferOperation::Type::Map:
282286 {
287+ VERIFY_EXPR (pStagingTex != nullptr );
283288 bool AllMapped = true ;
284289 for (Uint32 Slice = 0 ; Slice < UploadBuffDesc.ArraySize ; ++Slice)
285290 {
@@ -291,7 +296,7 @@ void TextureUploaderD3D11::InternalData::Execute(ID3D11DeviceContext* pd3d11N
291296
292297 UINT Subres = D3D11CalcSubresource (static_cast <UINT>(Mip), static_cast <UINT>(Slice), static_cast <UINT>(UploadBuffDesc.MipLevels ));
293298
294- HRESULT hr = pd3d11NativeCtx->Map (pBuffer-> GetStagingTex () , Subres, D3D11_MAP_WRITE,
299+ HRESULT hr = pd3d11NativeCtx->Map (pStagingTex , Subres, D3D11_MAP_WRITE,
295300 ExecuteImmediately ? 0 : D3D11_MAP_FLAG_DO_NOT_WAIT,
296301 &MappedData);
297302 if (SUCCEEDED (hr))
@@ -329,10 +334,13 @@ void TextureUploaderD3D11::InternalData::Execute(ID3D11DeviceContext* pd3d11N
329334 case InternalData::PendingBufferOperation::Type::Copy:
330335 {
331336 VERIFY (pBuffer->DbgIsMapped (), " Upload buffer must be copied only after it has been mapped" );
332- // Unmap all subresources first to avoid D3D11 warnings
333- for (Uint32 Subres = 0 ; Subres < UploadBuffDesc.MipLevels * UploadBuffDesc.ArraySize ; ++Subres)
337+ if (pStagingTex != nullptr )
334338 {
335- pd3d11NativeCtx->Unmap (pBuffer->GetStagingTex (), Subres);
339+ // Unmap all subresources first to avoid D3D11 warnings
340+ for (Uint32 Subres = 0 ; Subres < UploadBuffDesc.MipLevels * UploadBuffDesc.ArraySize ; ++Subres)
341+ {
342+ pd3d11NativeCtx->Unmap (pBuffer->GetStagingTex (), Subres);
343+ }
336344 }
337345
338346 for (Uint32 Slice = 0 ; Slice < UploadBuffDesc.ArraySize ; ++Slice)
@@ -347,12 +355,26 @@ void TextureUploaderD3D11::InternalData::Execute(ID3D11DeviceContext* pd3d11N
347355 static_cast <UINT>(Operation.DstMip + Mip),
348356 static_cast <UINT>(Operation.DstSlice + Slice),
349357 static_cast <UINT>(Operation.DstMipLevels ));
350- pd3d11NativeCtx->CopySubresourceRegion (Operation.pd3d11NativeDstTexture , DstSubres,
351- 0 , 0 , 0 , // DstX, DstY, DstZ
352- pBuffer->GetStagingTex (),
353- SrcSubres,
354- nullptr // pSrcBox
355- );
358+ if (pStagingTex != nullptr )
359+ {
360+ pd3d11NativeCtx->CopySubresourceRegion (Operation.pd3d11NativeDstTexture , DstSubres,
361+ 0 , 0 , 0 , // DstX, DstY, DstZ
362+ pBuffer->GetStagingTex (),
363+ SrcSubres,
364+ nullptr // pSrcBox
365+ );
366+ }
367+ else
368+ {
369+ const MappedTextureSubresource& MappedData = pBuffer->GetMappedData (Mip, Slice);
370+ pd3d11NativeCtx->UpdateSubresource (
371+ Operation.pd3d11NativeDstTexture ,
372+ DstSubres,
373+ nullptr , // pDstBox
374+ pBuffer->GetMappedData (Mip, Slice).pData ,
375+ static_cast <UINT>(MappedData.Stride ),
376+ static_cast <UINT>(MappedData.DepthStride ));
377+ }
356378 }
357379 }
358380 pBuffer->SignalCopyScheduled ();
@@ -395,51 +417,59 @@ void TextureUploaderD3D11::AllocateUploadBuffer(IDeviceContext* pContext
395417
396418 if (!pUploadBuffer)
397419 {
398- // clang-format off
399- D3D11_TEXTURE2D_DESC StagingTexDesc =
400- {
401- static_cast <UINT>(Desc.Width ),
402- static_cast <UINT>(Desc.Height ),
403- static_cast <UINT>(Desc.MipLevels ),
404- static_cast <UINT>(Desc.ArraySize ),
405- TexFormatToDXGI_Format (Desc.Format ),
406- {1 , 0 }, // DXGI_SAMPLE_DESC SampleDesc;
407- D3D11_USAGE_STAGING,
408- 0 , // UINT BindFlags;
409- D3D11_CPU_ACCESS_WRITE, // UINT CPUAccessFlags;
410- 0 , // UINT MiscFlags;
411- };
412- // clang-format on
413-
414420 CComPtr<ID3D11Texture2D> pStagingTex;
415421
416- HRESULT hr = m_pInternalData->m_pd3d11NativeDevice ->CreateTexture2D (&StagingTexDesc, nullptr , &pStagingTex);
417- if (FAILED (hr))
422+ if (m_Desc.Mode == TEXTURE_UPLOADER_MODE_STAGING_RESOURCE)
418423 {
419- LOG_ERROR_MESSAGE (" Failed to allocate staging D3D11 texture" );
420- return ;
424+ D3D11_TEXTURE2D_DESC StagingTexDesc =
425+ {
426+ static_cast <UINT>(Desc.Width ),
427+ static_cast <UINT>(Desc.Height ),
428+ static_cast <UINT>(Desc.MipLevels ),
429+ static_cast <UINT>(Desc.ArraySize ),
430+ TexFormatToDXGI_Format (Desc.Format ),
431+ {1 , 0 }, // DXGI_SAMPLE_DESC SampleDesc;
432+ D3D11_USAGE_STAGING,
433+ 0 , // UINT BindFlags;
434+ D3D11_CPU_ACCESS_WRITE, // UINT CPUAccessFlags;
435+ 0 , // UINT MiscFlags;
436+ };
437+
438+ HRESULT hr = m_pInternalData->m_pd3d11NativeDevice ->CreateTexture2D (&StagingTexDesc, nullptr , &pStagingTex);
439+ if (FAILED (hr))
440+ {
441+ LOG_ERROR_MESSAGE (" Failed to allocate staging D3D11 texture" );
442+ return ;
443+ }
421444 }
422445
423446 LOG_INFO_MESSAGE (" TextureUploaderD3D11: created " , Desc.Width , ' x' , Desc.Height , ' x' , Desc.Depth , ' ' ,
424447 Desc.MipLevels , " -mip " , Desc.ArraySize , " -slice " ,
425- m_pDevice->GetTextureFormatInfo (Desc.Format ).Name , " staging texture" );
448+ m_pDevice->GetTextureFormatInfo (Desc.Format ).Name , pStagingTex ? " staging texture" : " CPU upload buffer " );
426449
427450 pUploadBuffer = MakeNewRCObj<UploadBufferD3D11>()(Desc, pStagingTex);
428451 }
429452
430453 if (pUploadBuffer)
431454 {
432- if (pContext != nullptr )
455+ if (m_Desc. Mode == TEXTURE_UPLOADER_MODE_STAGING_RESOURCE )
433456 {
434- // Main thread
435- InternalData::PendingBufferOperation MapOp{InternalData::PendingBufferOperation::Type::Map, pUploadBuffer};
436- m_pInternalData->ExecuteImmediately (pContext, MapOp);
457+ if (pContext != nullptr )
458+ {
459+ // Main thread
460+ InternalData::PendingBufferOperation MapOp{InternalData::PendingBufferOperation::Type::Map, pUploadBuffer};
461+ m_pInternalData->ExecuteImmediately (pContext, MapOp);
462+ }
463+ else
464+ {
465+ // Worker thread
466+ m_pInternalData->EnqueueMap (pUploadBuffer, InternalData::PendingBufferOperation::Type::Map);
467+ pUploadBuffer->WaitForMap ();
468+ }
437469 }
438470 else
439471 {
440- // Worker thread
441- m_pInternalData->EnqueueMap (pUploadBuffer, InternalData::PendingBufferOperation::Type::Map);
442- pUploadBuffer->WaitForMap ();
472+ pUploadBuffer->SignalMapped ();
443473 }
444474 }
445475
0 commit comments