summaryrefslogtreecommitdiffstats
path: root/Graphics
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-09-01 19:02:31 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-09-01 19:02:31 +0000
commit590c98bfe02f1758f3828b8e3cc813c0dbee654e (patch)
treee5072aad7d2944a6b03aa1141b1a5ced90975959 /Graphics
parentDisabled notification messages in OpenGL (diff)
downloadDiligentCore-590c98bfe02f1758f3828b8e3cc813c0dbee654e.tar.gz
DiligentCore-590c98bfe02f1758f3828b8e3cc813c0dbee654e.zip
Updated texture map/unmap intererface; implemented texture mapping in D3D12
Diffstat (limited to 'Graphics')
-rw-r--r--Graphics/GraphicsEngine/include/TextureBase.h28
-rw-r--r--Graphics/GraphicsEngine/interface/Texture.h28
-rw-r--r--Graphics/GraphicsEngine/src/Texture.cpp56
-rw-r--r--Graphics/GraphicsEngineD3D11/include/TextureBaseD3D11.h11
-rw-r--r--Graphics/GraphicsEngineD3D11/src/TextureBaseD3D11.cpp16
-rw-r--r--Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h57
-rw-r--r--Graphics/GraphicsEngineD3D12/include/TextureD3D12Impl.h10
-rw-r--r--Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp149
-rw-r--r--Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp47
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.h10
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp15
-rw-r--r--Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h10
-rw-r--r--Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp14
13 files changed, 333 insertions, 118 deletions
diff --git a/Graphics/GraphicsEngine/include/TextureBase.h b/Graphics/GraphicsEngine/include/TextureBase.h
index b20e3761..949d8d98 100644
--- a/Graphics/GraphicsEngine/include/TextureBase.h
+++ b/Graphics/GraphicsEngine/include/TextureBase.h
@@ -40,6 +40,12 @@ void ValidateUpdateDataParams( const TextureDesc &TexDesc, Uint32 MipLevel, Uint
void VliadateCopyTextureDataParams( const TextureDesc& SrcTexDesc, Uint32 SrcMipLevel, Uint32 SrcSlice, const Box* pSrcBox,
const TextureDesc& DstTexDesc, Uint32 DstMipLevel, Uint32 DstSlice,
Uint32 DstX, Uint32 DstY, Uint32 DstZ );
+void ValidateMapTextureParams(const TextureDesc& TexDesc,
+ Uint32 MipLevel,
+ Uint32 ArraySlice,
+ MAP_TYPE MapType,
+ Uint32 MapFlags,
+ const Box* pMapRegion);
/// Base implementation of the ITexture interface
@@ -146,10 +152,16 @@ public:
Uint32 DstZ )override = 0;
/// Base implementaiton of ITexture::Map()
- virtual void Map( IDeviceContext* pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags, MappedTextureSubresource& MappedData )override = 0;
+ virtual void Map(IDeviceContext* pContext,
+ Uint32 MipLevel,
+ Uint32 ArraySlice,
+ MAP_TYPE MapType,
+ Uint32 MapFlags,
+ const Box* pMapRegion,
+ MappedTextureSubresource& MappedData)override = 0;
/// Base implementaiton of ITexture::Unmap()
- virtual void Unmap( IDeviceContext* pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags )override = 0;
+ virtual void Unmap( IDeviceContext* pContext, Uint32 MipLevel, Uint32 ArraySlice)override = 0;
/// Creates default texture views.
@@ -483,12 +495,20 @@ void TextureBase<BaseInterface, TRenderDeviceImpl, TTextureViewImpl, TTexViewObj
}
template<class BaseInterface, class TRenderDeviceImpl,class TTextureViewImpl, class TTexViewObjAllocator>
-void TextureBase<BaseInterface, TRenderDeviceImpl, TTextureViewImpl, TTexViewObjAllocator> :: Map( IDeviceContext* pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags, MappedTextureSubresource &MappedData )
+void TextureBase<BaseInterface, TRenderDeviceImpl, TTextureViewImpl, TTexViewObjAllocator> :: Map(
+ IDeviceContext* pContext,
+ Uint32 MipLevel,
+ Uint32 ArraySlice,
+ MAP_TYPE MapType,
+ Uint32 MapFlags,
+ const Box* pMapRegion,
+ MappedTextureSubresource& MappedData)
{
+ ValidateMapTextureParams(m_Desc, MipLevel, ArraySlice, MapType, MapFlags, pMapRegion);
}
template<class BaseInterface, class TRenderDeviceImpl,class TTextureViewImpl, class TTexViewObjAllocator>
-void TextureBase<BaseInterface, TRenderDeviceImpl, TTextureViewImpl, TTexViewObjAllocator> :: Unmap( IDeviceContext* pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags )
+void TextureBase<BaseInterface, TRenderDeviceImpl, TTextureViewImpl, TTexViewObjAllocator> :: Unmap(IDeviceContext* pContext, Uint32 MipLevel, Uint32 ArraySlice)
{
}
diff --git a/Graphics/GraphicsEngine/interface/Texture.h b/Graphics/GraphicsEngine/interface/Texture.h
index 121a86c3..ba739d96 100644
--- a/Graphics/GraphicsEngine/interface/Texture.h
+++ b/Graphics/GraphicsEngine/interface/Texture.h
@@ -346,10 +346,30 @@ public:
Uint32 DstY,
Uint32 DstZ) = 0;
- /// Map the texture - not implemented yet
- virtual void Map( IDeviceContext *pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags, MappedTextureSubresource &MappedData ) = 0;
- /// Unmap the textute - not implemented yet
- virtual void Unmap( IDeviceContext *pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags ) = 0;
+ /// Map the texture
+
+ /// \param [in] pContext - Pointer to the device context interface to be used to perform the operation.
+ /// \param [in] MipLevel - Mip level to map.
+ /// \param [in] ArraySlice - Array slice to map. This parameter must be 0 for non-array textures.
+ /// \param [in] MapType - Type of the map operation. See Diligent::MAP_TYPE.
+ /// \param [in] MapFlags - Special map flags. See Diligent::MAP_FLAGS.
+ /// \param [in] pMapRegion - Texture region to map. If this parameter is null, the entire subresource is mapped.
+ /// \param [out] MappedData - Mapped texture region data
+ ///
+ /// \remarks This method is supported in D3D11, D3D12 and Vulkan backends. In D3D11 backend, only the entire
+ /// subresource can be mapped, so pMapRegion must either be null, or cover the entire subresource.
+ /// In D3D11 and Vulkan backends, dynamic textures are no different from non-dynamic textures, and mapping
+ /// with MAP_FLAG_DISCARD has exactly the same behavior
+ virtual void Map( IDeviceContext* pContext,
+ Uint32 MipLevel,
+ Uint32 ArraySlice,
+ MAP_TYPE MapType,
+ Uint32 MapFlags,
+ const Box* pMapRegion,
+ MappedTextureSubresource& MappedData ) = 0;
+
+ /// Unmap the textute
+ virtual void Unmap(IDeviceContext *pContext, Uint32 MipLevel, Uint32 ArraySlice) = 0;
/// Returns native texture handle specific to the underlying graphics API
diff --git a/Graphics/GraphicsEngine/src/Texture.cpp b/Graphics/GraphicsEngine/src/Texture.cpp
index 76741d48..3411ee20 100644
--- a/Graphics/GraphicsEngine/src/Texture.cpp
+++ b/Graphics/GraphicsEngine/src/Texture.cpp
@@ -248,39 +248,31 @@ void VliadateCopyTextureDataParams( const TextureDesc &SrcTexDesc, Uint32 SrcMip
ValidateTextureRegion(DstTexDesc, DstMipLevel, DstSlice, DstBox);
}
+void ValidateMapTextureParams(const TextureDesc& TexDesc,
+ Uint32 MipLevel,
+ Uint32 ArraySlice,
+ MAP_TYPE MapType,
+ Uint32 MapFlags,
+ const Box* pMapRegion)
+{
+ VERIFY_TEX_PARAMS( MipLevel < TexDesc.MipLevels, "Mip level (", MipLevel, ") is out of allowed range [0, ", TexDesc.MipLevels-1, "]" );
+ if (TexDesc.Type == RESOURCE_DIM_TEX_1D_ARRAY ||
+ TexDesc.Type == RESOURCE_DIM_TEX_2D_ARRAY ||
+ TexDesc.Type == RESOURCE_DIM_TEX_CUBE ||
+ TexDesc.Type == RESOURCE_DIM_TEX_CUBE_ARRAY)
+ {
+ VERIFY_TEX_PARAMS( ArraySlice < TexDesc.ArraySize, "Array slice (", ArraySlice, ") is out of range [0,", TexDesc.ArraySize-1, "]" );
+ }
+ else
+ {
+ VERIFY_TEX_PARAMS( ArraySlice == 0, "Array slice (", ArraySlice, ") must be 0 for non-array textures" );
+ }
-//void CTexture :: Map(MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData)
-//{
- //switch(MapType)
- //{
- // case MAP_READ:
- // VERIFY( "Only buffers with usage USAGE_CPU_ACCESSIBLE can be read from" && m_Desc.Usage == USAGE_CPU_ACCESSIBLE);
- // VERIFY( "Buffer being mapped for reading was not created with CPU_ACCESS_READ flag" && (m_Desc.CPUAccessFlags & CPU_ACCESS_READ));
- // break;
-
- // case MAP_WRITE:
- // VERIFY( "Only buffers with usage USAGE_CPU_ACCESSIBLE can be written to" && m_Desc.Usage == USAGE_CPU_ACCESSIBLE );
- // VERIFY( "Buffer being mapped for writing was not created with CPU_ACCESS_WRITE flag" && (m_Desc.CPUAccessFlags & CPU_ACCESS_WRITE));
- // break;
-
- // case MAP_READ_WRITE:
- // VERIFY( "Only buffers with usage USAGE_CPU_ACCESSIBLE can be read and written" && m_Desc.Usage == USAGE_CPU_ACCESSIBLE );
- // VERIFY( "Buffer being mapped for reading & writing was not created with CPU_ACCESS_WRITE flag" && (m_Desc.CPUAccessFlags & CPU_ACCESS_WRITE));
- // VERIFY( "Buffer being mapped for reading & writing was not created with CPU_ACCESS_READ flag" && (m_Desc.CPUAccessFlags & CPU_ACCESS_READ));
- // break;
-
- // case MAP_WRITE_DISCARD:
- // VERIFY( "Only dynamic buffers can be mapped with write discard flag" && m_Desc.Usage == USAGE_DYNAMIC );
- // VERIFY( "Dynamic buffer must be created with CPU_ACCESS_WRITE flag" && (m_Desc.CPUAccessFlags & CPU_ACCESS_WRITE) );
- // break;
-
- // case MAP_WRITE_NO_OVERWRITE:
- // VERIFY( "Only dynamic buffers can be mapped with write no overwrite flag" && m_Desc.Usage == USAGE_DYNAMIC );
- // VERIFY( "Dynamic buffer must be created with CPU_ACCESS_WRITE flag" && (m_Desc.CPUAccessFlags & CPU_ACCESS_WRITE) );
- // break;
+ if(pMapRegion != nullptr)
+ {
+ ValidateTextureRegion(TexDesc, MipLevel, ArraySlice, *pMapRegion);
+ }
- // default: VERIFY("Unknown map type" && false);
- //}
-//}
+}
} \ No newline at end of file
diff --git a/Graphics/GraphicsEngineD3D11/include/TextureBaseD3D11.h b/Graphics/GraphicsEngineD3D11/include/TextureBaseD3D11.h
index 1284c52e..662220a4 100644
--- a/Graphics/GraphicsEngineD3D11/include/TextureBaseD3D11.h
+++ b/Graphics/GraphicsEngineD3D11/include/TextureBaseD3D11.h
@@ -65,8 +65,15 @@ public:
virtual void UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box& DstBox, const TextureSubResData& SubresData )override final;
//virtual void CopyData(CTexture *pSrcTexture, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size);
- virtual void Map( IDeviceContext *pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags, MappedTextureSubresource &MappedData )override final;
- virtual void Unmap( IDeviceContext *pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags )override final;
+ virtual void Map( IDeviceContext* pContext,
+ Uint32 MipLevel,
+ Uint32 ArraySlice,
+ MAP_TYPE MapType,
+ Uint32 MapFlags,
+ const Box* pMapRegion,
+ MappedTextureSubresource& MappedData )override final;
+
+ virtual void Unmap(IDeviceContext *pContext, Uint32 MipLevel, Uint32 ArraySlice)override final;
virtual ID3D11Resource* GetD3D11Texture()override final{ return m_pd3d11Texture; }
diff --git a/Graphics/GraphicsEngineD3D11/src/TextureBaseD3D11.cpp b/Graphics/GraphicsEngineD3D11/src/TextureBaseD3D11.cpp
index 625b6668..e672cf86 100644
--- a/Graphics/GraphicsEngineD3D11/src/TextureBaseD3D11.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/TextureBaseD3D11.cpp
@@ -213,15 +213,22 @@ void TextureBaseD3D11 :: CopyData(IDeviceContext* pContext,
pd3d11DeviceContext->CopySubresourceRegion(m_pd3d11Texture, DstSubRes, DstX, DstY, DstZ, pSrTextureBaseD3D11->GetD3D11Texture(), SrcSubRes, pD3D11SrcBox);
}
-void TextureBaseD3D11 :: Map( IDeviceContext* pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags, MappedTextureSubresource& MappedData )
+void TextureBaseD3D11 :: Map(IDeviceContext* pContext,
+ Uint32 MipLevel,
+ Uint32 ArraySlice,
+ MAP_TYPE MapType,
+ Uint32 MapFlags,
+ const Box* pMapRegion,
+ MappedTextureSubresource& MappedData)
{
- TTextureBase::Map( pContext, Subresource, MapType, MapFlags, MappedData );
+ TTextureBase::Map(pContext, MipLevel, ArraySlice, MapType, MapFlags, pMapRegion, MappedData);
auto* pd3d11DeviceContext = static_cast<DeviceContextD3D11Impl*>(pContext)->GetD3D11DeviceContext();
D3D11_MAP d3d11MapType = static_cast<D3D11_MAP>(0);
UINT d3d11MapFlags = 0;
MapParamsToD3D11MapParams(MapType, MapFlags, d3d11MapType, d3d11MapFlags);
+ auto Subresource = D3D11CalcSubresource(MipLevel, ArraySlice, m_Desc.MipLevels);
D3D11_MAPPED_SUBRESOURCE MappedTex;
auto hr = pd3d11DeviceContext->Map(m_pd3d11Texture, Subresource, d3d11MapType, d3d11MapFlags, &MappedTex);
if( FAILED(hr) )
@@ -237,11 +244,12 @@ void TextureBaseD3D11 :: Map( IDeviceContext* pContext, Uint32 Subresource, MAP_
}
}
-void TextureBaseD3D11::Unmap( IDeviceContext* pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags )
+void TextureBaseD3D11::Unmap( IDeviceContext* pContext, Uint32 MipLevel, Uint32 ArraySlice)
{
- TTextureBase::Unmap( pContext, Subresource, MapType, MapFlags );
+ TTextureBase::Unmap( pContext, MipLevel, ArraySlice);
auto* pd3d11DeviceContext = static_cast<DeviceContextD3D11Impl*>(pContext)->GetD3D11DeviceContext();
+ auto Subresource = D3D11CalcSubresource(MipLevel, ArraySlice, m_Desc.MipLevels);
pd3d11DeviceContext->Unmap(m_pd3d11Texture, Subresource);
}
diff --git a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h
index ae006d32..bfde19bb 100644
--- a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h
+++ b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h
@@ -26,15 +26,14 @@
/// \file
/// Declaration of Diligent::DeviceContextD3D12Impl class
+#include <unordered_map>
+
#include "DeviceContextD3D12.h"
#include "DeviceContextBase.h"
#include "GenerateMips.h"
#include "BufferD3D12Impl.h"
#include "TextureViewD3D12Impl.h"
#include "PipelineStateD3D12Impl.h"
-#ifdef _DEBUG
-# define VERIFY_CONTEXT_BINDINGS
-#endif
namespace Diligent
{
@@ -115,7 +114,7 @@ public:
Uint32 SrcOffset,
Uint32 SrcStride,
Uint32 SrcDepthStride,
- class TextureD3D12Impl* pTextureD3D12,
+ class TextureD3D12Impl& TextureD3D12,
Uint32 DstSubResIndex,
const Box& DstBox);
void CopyTextureRegion(ID3D12Resource* pd3d12Buffer,
@@ -123,17 +122,29 @@ public:
Uint32 SrcStride,
Uint32 SrcDepthStride,
Uint32 BufferSize,
- class TextureD3D12Impl* pTextureD3D12,
+ class TextureD3D12Impl& TextureD3D12,
Uint32 DstSubResIndex,
const Box& DstBox);
void UpdateTextureRegion(const void* pSrcData,
Uint32 SrcStride,
Uint32 SrcDepthStride,
- class TextureD3D12Impl* pTextureD3D12,
+ class TextureD3D12Impl& TextureD3D12,
Uint32 DstSubResIndex,
const Box& DstBox);
+ void MapTexture( class TextureD3D12Impl& TextureD3D12,
+ Uint32 MipLevel,
+ Uint32 ArraySlice,
+ MAP_TYPE MapType,
+ Uint32 MapFlags,
+ const Box& MapRegion,
+ MappedTextureSubresource& MappedData );
+
+ void UnmapTexture( class TextureD3D12Impl& TextureD3D12,
+ Uint32 MipLevel,
+ Uint32 ArraySlice);
+
void GenerateMips(class TextureViewD3D12Impl *pTexView);
struct DynamicAllocation AllocateDynamicSpace(size_t NumBytes, size_t Alignment);
@@ -151,6 +162,20 @@ private:
void CommitScissorRects(class GraphicsContext &GraphCtx, bool ScissorEnable);
void Flush(bool RequestNewCmdCtx);
+ struct TextureUploadSpace
+ {
+ DynamicAllocation Allocation;
+ Uint32 AlignedOffset = 0;
+ Uint32 Stride = 0;
+ Uint32 DepthStride = 0;
+ Uint32 RowSize = 0;
+ Uint32 RowCount = 0;
+ Box Region;
+ };
+ TextureUploadSpace AllocateTextureUploadSpace(TEXTURE_FORMAT TexFmt,
+ const Box& Region);
+
+
friend class SwapChainD3D12Impl;
inline class CommandContext* RequestCmdContext()
{
@@ -186,6 +211,26 @@ private:
const Uint32 m_ContextId;
std::vector<std::pair<Uint64, RefCntAutoPtr<IFence> > > m_PendingFences;
+
+ struct TextureUploadAllocationKey
+ {
+ TextureD3D12Impl* const Texture;
+ UINT const Subresource;
+
+ bool operator == (const TextureUploadAllocationKey& rhs)const
+ {
+ return Texture == rhs.Texture &&
+ Subresource == rhs.Subresource;
+ }
+ struct Hasher
+ {
+ size_t operator()(const TextureUploadAllocationKey& Key)const
+ {
+ return ComputeHash(Key.Texture, Key.Subresource);
+ }
+ };
+ };
+ std::unordered_map<TextureUploadAllocationKey, TextureUploadSpace, TextureUploadAllocationKey::Hasher> m_TextureUploadAllocations;
};
}
diff --git a/Graphics/GraphicsEngineD3D12/include/TextureD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/TextureD3D12Impl.h
index 95430ade..3a314a37 100644
--- a/Graphics/GraphicsEngineD3D12/include/TextureD3D12Impl.h
+++ b/Graphics/GraphicsEngineD3D12/include/TextureD3D12Impl.h
@@ -63,8 +63,14 @@ public:
virtual void UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData )override final;
//virtual void CopyData(CTexture *pSrcTexture, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size);
- virtual void Map( IDeviceContext *pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags, MappedTextureSubresource &MappedData )override final;
- virtual void Unmap( IDeviceContext *pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags )override final;
+ virtual void Map( IDeviceContext* pContext,
+ Uint32 MipLevel,
+ Uint32 ArraySlice,
+ MAP_TYPE MapType,
+ Uint32 MapFlags,
+ const Box* pMapRegion,
+ MappedTextureSubresource& MappedData )override final;
+ virtual void Unmap( IDeviceContext *pContext, Uint32 MipLevel, Uint32 ArraySlice)override final;
virtual ID3D12Resource* GetD3D12Texture(){ return GetD3D12Resource(); }
diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
index ab1ae905..52898a5d 100644
--- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
@@ -759,17 +759,17 @@ namespace Diligent
Uint32 SrcStride,
Uint32 SrcDepthStride,
Uint32 BufferSize,
- class TextureD3D12Impl* pTextureD3D12,
+ class TextureD3D12Impl& TextureD3D12,
Uint32 DstSubResIndex,
const Box& DstBox)
{
- const auto& TexDesc = pTextureD3D12->GetDesc();
+ const auto& TexDesc = TextureD3D12.GetDesc();
auto *pCmdCtx = RequestCmdContext();
auto *pCmdList = pCmdCtx->GetCommandList();
- auto TextureState = pTextureD3D12->GetState();
+ auto TextureState = TextureD3D12.GetState();
D3D12_RESOURCE_BARRIER BarrierDesc;
BarrierDesc.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
- BarrierDesc.Transition.pResource = pTextureD3D12->GetD3D12Resource();
+ BarrierDesc.Transition.pResource = TextureD3D12.GetD3D12Resource();
BarrierDesc.Transition.Subresource = DstSubResIndex;
BarrierDesc.Transition.StateBefore = TextureState;
BarrierDesc.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST;
@@ -780,7 +780,7 @@ namespace Diligent
D3D12_TEXTURE_COPY_LOCATION DstLocation;
DstLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
- DstLocation.pResource = pTextureD3D12->GetD3D12Resource();
+ DstLocation.pResource = TextureD3D12.GetD3D12Resource();
DstLocation.SubresourceIndex = static_cast<UINT>(DstSubResIndex);
D3D12_TEXTURE_COPY_LOCATION SrcLocation;
@@ -830,7 +830,7 @@ namespace Diligent
Uint32 SrcOffset,
Uint32 SrcStride,
Uint32 SrcDepthStride,
- class TextureD3D12Impl* pTextureD3D12,
+ class TextureD3D12Impl& TextureD3D12,
Uint32 DstSubResIndex,
const Box& DstBox)
{
@@ -841,71 +841,136 @@ namespace Diligent
RequestCmdContext()->TransitionResource(pBufferD3D12, D3D12_RESOURCE_STATE_GENERIC_READ, true);
size_t DataStartByteOffset = 0;
auto* pd3d12Buffer = pBufferD3D12->GetD3D12Buffer(DataStartByteOffset, m_ContextId);
- CopyTextureRegion(pd3d12Buffer, static_cast<Uint32>(DataStartByteOffset) + SrcOffset, SrcStride, SrcDepthStride, pBufferD3D12->GetDesc().uiSizeInBytes, pTextureD3D12, DstSubResIndex, DstBox);
+ CopyTextureRegion(pd3d12Buffer, static_cast<Uint32>(DataStartByteOffset) + SrcOffset, SrcStride, SrcDepthStride, pBufferD3D12->GetDesc().uiSizeInBytes, TextureD3D12, DstSubResIndex, DstBox);
}
- void DeviceContextD3D12Impl::UpdateTextureRegion(const void* pSrcData,
- Uint32 SrcStride,
- Uint32 SrcDepthStride,
- TextureD3D12Impl* pTextureD3D12,
- Uint32 DstSubResIndex,
- const Box& DstBox)
+ DeviceContextD3D12Impl::TextureUploadSpace DeviceContextD3D12Impl::AllocateTextureUploadSpace(TEXTURE_FORMAT TexFmt,
+ const Box& Region)
{
- const auto& TexDesc = pTextureD3D12->GetDesc();
- const auto& FmtAttribs = GetTextureFormatAttribs(TexDesc.Format);
- VERIFY_EXPR(DstBox.MaxX > DstBox.MinX && DstBox.MaxY > DstBox.MinY && DstBox.MaxZ > DstBox.MinZ);
- auto UpdateRegionWidth = DstBox.MaxX - DstBox.MinX;
- auto UpdateRegionHeight = DstBox.MaxY - DstBox.MinY;
- auto UpdateRegionDepth = DstBox.MaxZ - DstBox.MinZ;
- Uint32 RowSize = 0;
- Uint32 RowCount = 0;
+ TextureUploadSpace UploadSpace;
+ VERIFY_EXPR(Region.MaxX > Region.MinX && Region.MaxY > Region.MinY && Region.MaxZ > Region.MinZ);
+ auto UpdateRegionWidth = Region.MaxX - Region.MinX;
+ auto UpdateRegionHeight = Region.MaxY - Region.MinY;
+ auto UpdateRegionDepth = Region.MaxZ - Region.MinZ;
+ const auto& FmtAttribs = GetTextureFormatAttribs(TexFmt);
if(FmtAttribs.ComponentType == COMPONENT_TYPE_COMPRESSED)
{
// Box must be aligned by the calling function
VERIFY_EXPR((UpdateRegionWidth % FmtAttribs.BlockWidth) == 0);
VERIFY_EXPR((UpdateRegionHeight % FmtAttribs.BlockHeight) == 0);
- RowSize = UpdateRegionWidth / Uint32{FmtAttribs.BlockWidth} * Uint32{FmtAttribs.ComponentSize};
- RowCount = UpdateRegionHeight / FmtAttribs.BlockHeight;
+ UploadSpace.RowSize = UpdateRegionWidth / Uint32{FmtAttribs.BlockWidth} * Uint32{FmtAttribs.ComponentSize};
+ UploadSpace.RowCount = UpdateRegionHeight / FmtAttribs.BlockHeight;
}
else
{
- RowSize = UpdateRegionWidth * Uint32{FmtAttribs.ComponentSize} * Uint32{FmtAttribs.NumComponents};
- RowCount = UpdateRegionHeight;
+ UploadSpace.RowSize = UpdateRegionWidth * Uint32{FmtAttribs.ComponentSize} * Uint32{FmtAttribs.NumComponents};
+ UploadSpace.RowCount = UpdateRegionHeight;
}
+ // RowPitch must be a multiple of 256 (aka. D3D12_TEXTURE_DATA_PITCH_ALIGNMENT)
+ UploadSpace.Stride = (UploadSpace.RowSize + D3D12_TEXTURE_DATA_PITCH_ALIGNMENT-1) & ~(D3D12_TEXTURE_DATA_PITCH_ALIGNMENT-1);
+ UploadSpace.DepthStride = UploadSpace.RowCount * UploadSpace.Stride;
+ const auto MemorySize = UpdateRegionDepth * UploadSpace.DepthStride;
+ UploadSpace.Allocation = AllocateDynamicSpace(MemorySize, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT);
+ UploadSpace.AlignedOffset = (UploadSpace.Allocation.Offset + (D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT-1)) & ~(D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT-1);
+ UploadSpace.Region = Region;
+
+ return UploadSpace;
+ }
+
+ void DeviceContextD3D12Impl::UpdateTextureRegion(const void* pSrcData,
+ Uint32 SrcStride,
+ Uint32 SrcDepthStride,
+ TextureD3D12Impl& TextureD3D12,
+ Uint32 DstSubResIndex,
+ const Box& DstBox)
+ {
+ const auto& TexDesc = TextureD3D12.GetDesc();
+ auto UploadSpace = AllocateTextureUploadSpace(TexDesc.Format, DstBox);
+ auto UpdateRegionDepth = DstBox.MaxZ-DstBox.MinZ;
#ifdef _DEBUG
{
- VERIFY(SrcStride >= RowSize, "Source data stride (", SrcStride, ") is below the image row size (", RowSize, ")");
- const Uint32 PlaneSize = SrcStride * RowCount;
+ VERIFY(SrcStride >= UploadSpace.RowSize, "Source data stride (", SrcStride, ") is below the image row size (", UploadSpace.RowSize, ")");
+ const Uint32 PlaneSize = SrcStride * UploadSpace.RowCount;
VERIFY(UpdateRegionDepth == 1 || SrcDepthStride >= PlaneSize, "Source data depth stride (", SrcDepthStride, ") is below the image plane size (", PlaneSize, ")");
}
#endif
- // RowPitch must be a multiple of 256 (aka. D3D12_TEXTURE_DATA_PITCH_ALIGNMENT)
- const auto AlignedStride = (RowSize + D3D12_TEXTURE_DATA_PITCH_ALIGNMENT-1) & ~(D3D12_TEXTURE_DATA_PITCH_ALIGNMENT-1);
- const auto AlignedDepthStride = RowCount * AlignedStride;
- const auto MemorySize = UpdateRegionDepth * AlignedDepthStride;
- const auto UploadSpace = AllocateDynamicSpace(MemorySize, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT);
- const auto AlignedOffset = (UploadSpace.Offset + (D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT-1)) & ~(D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT-1);
+ const auto AlignedOffset = UploadSpace.AlignedOffset;
- for(Uint32 slice = 0; slice < UpdateRegionDepth; ++slice)
+ for(Uint32 DepthSlice = 0; DepthSlice < UpdateRegionDepth; ++DepthSlice)
{
- for(Uint32 row = 0; row < RowCount; ++row)
+ for(Uint32 row = 0; row < UploadSpace.RowCount; ++row)
{
const auto* pSrcPtr =
reinterpret_cast<const Uint8*>(pSrcData)
+ row * SrcStride
- + slice * SrcDepthStride;
+ + DepthSlice * SrcDepthStride;
auto* pDstPtr =
- reinterpret_cast<Uint8*>(UploadSpace.CPUAddress)
- + (AlignedOffset - UploadSpace.Offset)
- + row * AlignedStride
- + slice * AlignedDepthStride;
+ reinterpret_cast<Uint8*>(UploadSpace.Allocation.CPUAddress)
+ + (AlignedOffset - UploadSpace.Allocation.Offset)
+ + row * UploadSpace.Stride
+ + DepthSlice * UploadSpace.DepthStride;
- memcpy(pDstPtr, pSrcPtr, RowSize);
+ memcpy(pDstPtr, pSrcPtr, UploadSpace.RowSize);
}
}
- CopyTextureRegion(UploadSpace.pBuffer, static_cast<Uint32>(AlignedOffset), AlignedStride, AlignedDepthStride, MemorySize, pTextureD3D12, DstSubResIndex, DstBox);
+ CopyTextureRegion(UploadSpace.Allocation.pBuffer,
+ static_cast<Uint32>(AlignedOffset),
+ UploadSpace.Stride,
+ UploadSpace.DepthStride,
+ static_cast<Uint32>(UploadSpace.Allocation.Size - (AlignedOffset - UploadSpace.Allocation.Offset)),
+ TextureD3D12,
+ DstSubResIndex,
+ DstBox);
+ }
+
+ void DeviceContextD3D12Impl::MapTexture( TextureD3D12Impl& TextureD3D12,
+ Uint32 MipLevel,
+ Uint32 ArraySlice,
+ MAP_TYPE MapType,
+ Uint32 MapFlags,
+ const Box& MapRegion,
+ MappedTextureSubresource& MappedData )
+ {
+ const auto& TexDesc = TextureD3D12.GetDesc();
+ auto UploadSpace = AllocateTextureUploadSpace(TexDesc.Format, MapRegion);
+ const auto AlignedOffset = (UploadSpace.Allocation.Offset + (D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT-1)) & ~(D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT-1);
+ MappedData.pData = reinterpret_cast<Uint8*>(UploadSpace.Allocation.CPUAddress) + (UploadSpace.AlignedOffset - UploadSpace.Allocation.Offset);
+ MappedData.Stride = UploadSpace.Stride;
+ MappedData.DepthStride = UploadSpace.DepthStride;
+
+ auto Subres = D3D12CalcSubresource(MipLevel, ArraySlice, 0, TexDesc.MipLevels, TexDesc.ArraySize);
+ auto it = m_TextureUploadAllocations.emplace(TextureUploadAllocationKey{&TextureD3D12, Subres}, std::move(UploadSpace));
+ if(!it.second)
+ LOG_ERROR_MESSAGE("Mip level ", MipLevel, ", slice ", ArraySlice, " of texture '", TexDesc.Name, "' has already been mapped");
}
+ void DeviceContextD3D12Impl::UnmapTexture( TextureD3D12Impl& TextureD3D12,
+ Uint32 MipLevel,
+ Uint32 ArraySlice)
+ {
+ const auto& TexDesc = TextureD3D12.GetDesc();
+ auto Subres = D3D12CalcSubresource(MipLevel, ArraySlice, 0, TexDesc.MipLevels, TexDesc.ArraySize);
+ auto UploadSpaceIt = m_TextureUploadAllocations.find(TextureUploadAllocationKey{&TextureD3D12, Subres});
+ if(UploadSpaceIt != m_TextureUploadAllocations.end())
+ {
+ auto& UploadSpace = UploadSpaceIt->second;
+ CopyTextureRegion(UploadSpace.Allocation.pBuffer,
+ UploadSpace.AlignedOffset,
+ UploadSpace.Stride,
+ UploadSpace.DepthStride,
+ static_cast<Uint32>(UploadSpace.Allocation.Size - (UploadSpace.AlignedOffset - UploadSpace.Allocation.Offset)),
+ TextureD3D12,
+ Subres,
+ UploadSpace.Region);
+ m_TextureUploadAllocations.erase(UploadSpaceIt);
+ }
+ else
+ {
+ LOG_ERROR_MESSAGE("Failed to unmap mip level ", MipLevel, ", slice ", ArraySlice, " of texture '", TexDesc.Name, "'. The texture has either been unmapped already or has not been mapped");
+ }
+ }
+
+
void DeviceContextD3D12Impl::GenerateMips(TextureViewD3D12Impl* pTexView)
{
auto *pCtx = RequestCmdContext();
diff --git a/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp
index 77d959a6..21eeeca4 100644
--- a/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp
@@ -438,9 +438,9 @@ void TextureD3D12Impl::UpdateData( IDeviceContext* pContext,
auto *pCtxD3D12 = ValidatedCast<DeviceContextD3D12Impl>(pContext);
auto DstSubResIndex = D3D12CalcSubresource(MipLevel, Slice, 0, m_Desc.MipLevels, m_Desc.ArraySize);
if (SubresData.pSrcBuffer == nullptr)
- pCtxD3D12->UpdateTextureRegion(SubresData.pData, SubresData.Stride, SubresData.DepthStride, this, DstSubResIndex, *pBox);
+ pCtxD3D12->UpdateTextureRegion(SubresData.pData, SubresData.Stride, SubresData.DepthStride, *this, DstSubResIndex, *pBox);
else
- pCtxD3D12->CopyTextureRegion(SubresData.pSrcBuffer, 0, SubresData.Stride, SubresData.DepthStride, this, DstSubResIndex, *pBox);
+ pCtxD3D12->CopyTextureRegion(SubresData.pSrcBuffer, 0, SubresData.Stride, SubresData.DepthStride, *this, DstSubResIndex, *pBox);
}
void TextureD3D12Impl :: CopyData(IDeviceContext* pContext,
@@ -477,19 +477,46 @@ void TextureD3D12Impl :: CopyData(IDeviceContext* pContext,
pCtxD3D12->CopyTextureRegion(pSrcTexD3D12, SrcSubResIndex, pD3D12SrcBox, this, DstSubResIndex, DstX, DstY, DstZ);
}
-void TextureD3D12Impl :: Map(IDeviceContext* pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags, MappedTextureSubresource &MappedData)
+void TextureD3D12Impl :: Map( IDeviceContext* pContext,
+ Uint32 MipLevel,
+ Uint32 ArraySlice,
+ MAP_TYPE MapType,
+ Uint32 MapFlags,
+ const Box* pMapRegion,
+ MappedTextureSubresource& MappedData )
{
- TTextureBase::Map( pContext, Subresource, MapType, MapFlags, MappedData );
- UNSUPPORTED("TextureD3D12Impl::Map() is not implemented");
+ TTextureBase::Map(pContext, MipLevel, ArraySlice, MapType, MapFlags, pMapRegion, MappedData);
- //static char TmpDummyBuffer[1024*1024*64];
- MappedData.pData = nullptr;//TmpDummyBuffer;
+ auto* pDeviceContextD3D12 = ValidatedCast<DeviceContextD3D12Impl>(pContext);
+ MappedData = MappedTextureSubresource{};
+
+ Box FullExtentBox;
+ if (pMapRegion == nullptr)
+ {
+ FullExtentBox.MaxX = std::max(m_Desc.Width >> MipLevel, 1u);
+ FullExtentBox.MaxY = std::max(m_Desc.Height >> MipLevel, 1u);
+ if (m_Desc.Type == RESOURCE_DIM_TEX_3D)
+ FullExtentBox.MaxZ = std::max(m_Desc.Depth >> MipLevel, 1u);
+ pMapRegion = &FullExtentBox;
+ }
+
+ if(MapType == MAP_WRITE)
+ {
+ if( (MapFlags & (MAP_FLAG_DISCARD | MAP_FLAG_DO_NOT_SYNCHRONIZE)) != 0 )
+ LOG_WARNING_MESSAGE_ONCE("Mapping textures with flags MAP_FLAG_DISCARD or MAP_FLAG_DO_NOT_SYNCHRONIZE has no effect in D3D12 backend");
+ pDeviceContextD3D12->MapTexture(*this, MipLevel, ArraySlice, MapType, MapFlags, *pMapRegion, MappedData);
+ }
+ else
+ {
+ LOG_ERROR("Textures can currently only be mapped for writing in D3D12 backend");
+ }
}
-void TextureD3D12Impl::Unmap( IDeviceContext* pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags )
+void TextureD3D12Impl::Unmap(IDeviceContext* pContext, Uint32 MipLevel, Uint32 ArraySlice)
{
- TTextureBase::Unmap( pContext, Subresource, MapType, MapFlags );
- UNSUPPORTED("TextureD3D12Impl::Unmap() is not implemented");
+ TTextureBase::Unmap(pContext, MipLevel, ArraySlice);
+ auto* pDeviceContextD3D12 = ValidatedCast<DeviceContextD3D12Impl>(pContext);
+ pDeviceContextD3D12->UnmapTexture(*this, MipLevel, ArraySlice);
}
diff --git a/Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.h b/Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.h
index 1af707a0..4f80aa05 100644
--- a/Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.h
+++ b/Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.h
@@ -67,8 +67,14 @@ public:
virtual void UpdateData( class GLContextState &CtxState, IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData );
//virtual void CopyData(CTexture *pSrcTexture, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size);
- virtual void Map( IDeviceContext *pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags, MappedTextureSubresource &MappedData )override;
- virtual void Unmap( IDeviceContext *pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags )override;
+ virtual void Map(IDeviceContext* pContext,
+ Uint32 MipLevel,
+ Uint32 ArraySlice,
+ MAP_TYPE MapType,
+ Uint32 MapFlags,
+ const Box* pMapRegion,
+ MappedTextureSubresource& MappedData)override;
+ virtual void Unmap(IDeviceContext *pContext, Uint32 MipLevel, Uint32 ArraySlice)override;
const GLObjectWrappers::GLTextureObj& GetGLHandle()const{ return m_GlTexture; }
virtual GLenum GetBindTarget()const override final{return m_BindTarget;}
diff --git a/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp b/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp
index f5e6034b..a0f0820b 100644
--- a/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp
@@ -494,15 +494,22 @@ void TextureBaseGL :: CopyData(IDeviceContext *pContext,
}
-void TextureBaseGL :: Map(IDeviceContext *pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags, MappedTextureSubresource &MappedData)
+void TextureBaseGL :: Map(IDeviceContext* pContext,
+ Uint32 MipLevel,
+ Uint32 ArraySlice,
+ MAP_TYPE MapType,
+ Uint32 MapFlags,
+ const Box* pMapRegion,
+ MappedTextureSubresource& MappedData)
{
- TTextureBase::Map( pContext, Subresource, MapType, MapFlags, MappedData );
+ TTextureBase::Map(pContext, MipLevel, ArraySlice, MapType, MapFlags, pMapRegion, MappedData);
LOG_ERROR_MESSAGE("Texture mapping is not supported in OpenGL");
+ MappedData = MappedTextureSubresource{};
}
-void TextureBaseGL::Unmap( IDeviceContext *pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags )
+void TextureBaseGL::Unmap(IDeviceContext* pContext, Uint32 MipLevel, Uint32 ArraySlice)
{
- TTextureBase::Unmap(pContext, Subresource, MapType, MapFlags);
+ TTextureBase::Unmap(pContext, MipLevel, ArraySlice);
LOG_ERROR_MESSAGE("Texture mapping is not supported in OpenGL");
}
diff --git a/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h b/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h
index eee1a938..c4fdcdc5 100644
--- a/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h
+++ b/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h
@@ -65,8 +65,14 @@ public:
virtual void UpdateData( IDeviceContext* pContext, Uint32 MipLevel, Uint32 Slice, const Box& DstBox, const TextureSubResData& SubresData )override;
//virtual void CopyData(CTexture* pSrcTexture, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size);
- virtual void Map( IDeviceContext* pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags, MappedTextureSubresource& MappedData )override;
- virtual void Unmap( IDeviceContext* pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags )override;
+ virtual void Map(IDeviceContext* pContext,
+ Uint32 MipLevel,
+ Uint32 ArraySlice,
+ MAP_TYPE MapType,
+ Uint32 MapFlags,
+ const Box* pMapRegion,
+ MappedTextureSubresource& MappedData)override;
+ virtual void Unmap(IDeviceContext* pContext, Uint32 MipLevel, Uint32 ArraySlice)override;
virtual VkImage GetVkImage()const override final{ return m_VulkanImage; }
virtual void* GetNativeHandle()override final
diff --git a/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp
index 796ddf56..5cff0d89 100644
--- a/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp
@@ -555,15 +555,21 @@ void TextureVkImpl :: CopyData(IDeviceContext* pContext,
pCtxVk->CopyTextureRegion(pSrcTexVk, this, CopyRegion);
}
-void TextureVkImpl :: Map(IDeviceContext *pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags, MappedTextureSubresource &MappedData)
+void TextureVkImpl :: Map(IDeviceContext* pContext,
+ Uint32 MipLevel,
+ Uint32 ArraySlice,
+ MAP_TYPE MapType,
+ Uint32 MapFlags,
+ const Box* pMapRegion,
+ MappedTextureSubresource& MappedData)
{
- TTextureBase::Map( pContext, Subresource, MapType, MapFlags, MappedData );
+ TTextureBase::Map(pContext, MipLevel, ArraySlice, MapType, MapFlags, pMapRegion, MappedData);
UNEXPECTED("TextureVkImpl::Map() is not implemented");
}
-void TextureVkImpl::Unmap( IDeviceContext *pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags )
+void TextureVkImpl::Unmap(IDeviceContext *pContext, Uint32 MipLevel, Uint32 ArraySlice)
{
- TTextureBase::Unmap( pContext, Subresource, MapType, MapFlags );
+ TTextureBase::Unmap(pContext, MipLevel, ArraySlice);
UNEXPECTED("TextureVkImpl::Unmap() is not implemented");
}