summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineD3D12
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-08-30 05:33:33 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-08-30 05:33:33 +0000
commit7dcb7b4a2c5965a90a7fdd5fd1950d5a1036900a (patch)
tree7559c64aebaaae5a2c4a2f7a2de7e22377191af2 /Graphics/GraphicsEngineD3D12
parentFixed debug checks (diff)
downloadDiligentCore-7dcb7b4a2c5965a90a7fdd5fd1950d5a1036900a.tar.gz
DiligentCore-7dcb7b4a2c5965a90a7fdd5fd1950d5a1036900a.zip
Fixed handling of small compressed texture subresources
Diffstat (limited to 'Graphics/GraphicsEngineD3D12')
-rw-r--r--Graphics/GraphicsEngineD3D12/include/TextureD3D12Impl.h10
-rw-r--r--Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp62
-rw-r--r--Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp30
3 files changed, 76 insertions, 26 deletions
diff --git a/Graphics/GraphicsEngineD3D12/include/TextureD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/TextureD3D12Impl.h
index 65f0d493..95430ade 100644
--- a/Graphics/GraphicsEngineD3D12/include/TextureD3D12Impl.h
+++ b/Graphics/GraphicsEngineD3D12/include/TextureD3D12Impl.h
@@ -58,13 +58,13 @@ public:
ID3D12Resource* pTexture);
~TextureD3D12Impl();
- virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override;
+ virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override final;
- virtual void UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData )override;
+ 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;
- virtual void Unmap( IDeviceContext *pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags )override;
+ 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 ID3D12Resource* GetD3D12Texture(){ return GetD3D12Resource(); }
@@ -94,7 +94,7 @@ public:
}
protected:
- void CreateViewInternal( const struct TextureViewDesc &ViewDesc, ITextureView **ppView, bool bIsDefaultView )override;
+ void CreateViewInternal( const struct TextureViewDesc &ViewDesc, ITextureView **ppView, bool bIsDefaultView )override final;
//void PrepareD3D12InitData(const TextureData &InitData, Uint32 NumSubresources, std::vector<D3D12_SUBRESOURCE_DATA> &D3D12InitData);
void CreateSRV( TextureViewDesc &SRVDesc, D3D12_CPU_DESCRIPTOR_HANDLE SRVHandle );
diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
index b30925b0..ab1ae905 100644
--- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
@@ -794,8 +794,15 @@ namespace Diligent
Footpring.Footprint.Format = TexFormatToDXGI_Format(TexDesc.Format);
Footpring.Footprint.RowPitch = static_cast<UINT>(SrcStride);
- VERIFY(Footpring.Footprint.RowPitch * Footpring.Footprint.Height * Footpring.Footprint.Depth <= BufferSize, "Buffer is not large enough");
- VERIFY(SrcDepthStride == 0 || static_cast<UINT>(SrcDepthStride) == Footpring.Footprint.RowPitch * Footpring.Footprint.Height, "Depth stride must be equal to the size 2D level");
+
+#ifdef _DEBUG
+ {
+ const auto& FmtAttribs = GetTextureFormatAttribs(TexDesc.Format);
+ const Uint32 RowCount = std::max((Footpring.Footprint.Height/FmtAttribs.BlockHeight), 1u);
+ VERIFY(BufferSize >= Footpring.Footprint.RowPitch * RowCount * Footpring.Footprint.Depth, "Buffer is not large enough");
+ VERIFY(Footpring.Footprint.Depth == 1 || static_cast<UINT>(SrcDepthStride) == Footpring.Footprint.RowPitch * RowCount, "Depth stride must be equal to the size of 2D plane");
+ }
+#endif
D3D12_BOX D3D12SrcBox;
D3D12SrcBox.left = 0;
@@ -847,24 +854,41 @@ namespace Diligent
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);
- const auto UpdateRegionWidth = DstBox.MaxX - DstBox.MinX;
- const auto UpdateRegionHeight = DstBox.MaxY - DstBox.MinY;
- const auto UpdateRegionDepth = DstBox.MaxZ - DstBox.MinZ;
- const Uint32 RowSize = FmtAttribs.ComponentType == COMPONENT_TYPE_COMPRESSED ?
- UpdateRegionWidth / Uint32{FmtAttribs.BlockWidth} * Uint32{FmtAttribs.ComponentSize} :
- UpdateRegionWidth * Uint32{FmtAttribs.ComponentSize} * Uint32{FmtAttribs.NumComponents};
- VERIFY(SrcStride >= RowSize, "Source data stride (", SrcStride, ") is below the image row size (", RowSize, ")");
- VERIFY(SrcDepthStride == 0 || SrcDepthStride >= SrcStride * (UpdateRegionHeight / FmtAttribs.BlockHeight), "Source data depth stride (", SrcDepthStride, ") is below the image plane size (", SrcStride * UpdateRegionHeight, ")");
+ auto UpdateRegionWidth = DstBox.MaxX - DstBox.MinX;
+ auto UpdateRegionHeight = DstBox.MaxY - DstBox.MinY;
+ auto UpdateRegionDepth = DstBox.MaxZ - DstBox.MinZ;
+ Uint32 RowSize = 0;
+ Uint32 RowCount = 0;
+ 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;
+ }
+ else
+ {
+ RowSize = UpdateRegionWidth * Uint32{FmtAttribs.ComponentSize} * Uint32{FmtAttribs.NumComponents};
+ RowCount = UpdateRegionHeight;
+ }
+#ifdef _DEBUG
+ {
+ VERIFY(SrcStride >= RowSize, "Source data stride (", SrcStride, ") is below the image row size (", RowSize, ")");
+ const Uint32 PlaneSize = SrcStride * 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 BufferDataStride = (RowSize + D3D12_TEXTURE_DATA_PITCH_ALIGNMENT-1) & ~(D3D12_TEXTURE_DATA_PITCH_ALIGNMENT-1);
- const auto BufferDataDepthStride = UpdateRegionHeight * BufferDataStride;
- const auto MemorySize = UpdateRegionDepth * BufferDataDepthStride;
- 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 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);
for(Uint32 slice = 0; slice < UpdateRegionDepth; ++slice)
{
- for(Uint32 row = 0; row < UpdateRegionHeight / FmtAttribs.BlockHeight; ++row)
+ for(Uint32 row = 0; row < RowCount; ++row)
{
const auto* pSrcPtr =
reinterpret_cast<const Uint8*>(pSrcData)
@@ -873,13 +897,13 @@ namespace Diligent
auto* pDstPtr =
reinterpret_cast<Uint8*>(UploadSpace.CPUAddress)
+ (AlignedOffset - UploadSpace.Offset)
- + row * BufferDataStride
- + slice * BufferDataDepthStride;
+ + row * AlignedStride
+ + slice * AlignedDepthStride;
memcpy(pDstPtr, pSrcPtr, RowSize);
}
}
- CopyTextureRegion(UploadSpace.pBuffer, static_cast<Uint32>(AlignedOffset), BufferDataStride, BufferDataDepthStride, MemorySize, pTextureD3D12, DstSubResIndex, DstBox);
+ CopyTextureRegion(UploadSpace.pBuffer, static_cast<Uint32>(AlignedOffset), AlignedStride, AlignedDepthStride, MemorySize, pTextureD3D12, DstSubResIndex, DstBox);
}
void DeviceContextD3D12Impl::GenerateMips(TextureViewD3D12Impl* pTexView)
diff --git a/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp
index 77d8894f..2ea0938e 100644
--- a/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp
@@ -409,12 +409,38 @@ void TextureD3D12Impl::UpdateData( IDeviceContext* pContext,
{
TTextureBase::UpdateData( pContext, MipLevel, Slice, DstBox, SubresData );
+ Box BlockAlignedBox;
+ const auto& FmtAttribs = GetTextureFormatAttribs(m_Desc.Format);
+ const Box* pBox = nullptr;
+ if (FmtAttribs.ComponentType == COMPONENT_TYPE_COMPRESSED)
+ {
+ // Align update region by the compressed block size
+
+ VERIFY( (DstBox.MinX % FmtAttribs.BlockWidth) == 0, "Update region min x (", DstBox.MinX, ") must be multiple of a compressed block width (", FmtAttribs.BlockWidth, ")");
+ BlockAlignedBox.MinX = DstBox.MinX;
+ VERIFY( (FmtAttribs.BlockWidth & (FmtAttribs.BlockWidth-1)) == 0, "Compressed block width (", FmtAttribs.BlockWidth, ") is expected to be power of 2");
+ BlockAlignedBox.MaxX = (DstBox.MaxX + FmtAttribs.BlockWidth-1) & ~(FmtAttribs.BlockWidth-1);
+
+ VERIFY( (DstBox.MinY % FmtAttribs.BlockHeight) == 0, "Update region min y (", DstBox.MinY, ") must be multiple of a compressed block height (", FmtAttribs.BlockHeight, ")");
+ BlockAlignedBox.MinY = DstBox.MinY;
+ VERIFY( (FmtAttribs.BlockHeight & (FmtAttribs.BlockHeight-1)) == 0, "Compressed block height (", FmtAttribs.BlockHeight, ") is expected to be power of 2");
+ BlockAlignedBox.MaxY = (DstBox.MaxY + FmtAttribs.BlockHeight-1) & ~(FmtAttribs.BlockHeight-1);
+
+ BlockAlignedBox.MinZ = DstBox.MinZ;
+ BlockAlignedBox.MaxZ = DstBox.MaxZ;
+
+ pBox = &BlockAlignedBox;
+ }
+ else
+ {
+ pBox = &DstBox;
+ }
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, DstBox);
+ pCtxD3D12->UpdateTextureRegion(SubresData.pData, SubresData.Stride, SubresData.DepthStride, this, DstSubResIndex, *pBox);
else
- pCtxD3D12->CopyTextureRegion(SubresData.pSrcBuffer, 0, SubresData.Stride, SubresData.DepthStride, this, DstSubResIndex, DstBox);
+ pCtxD3D12->CopyTextureRegion(SubresData.pSrcBuffer, 0, SubresData.Stride, SubresData.DepthStride, this, DstSubResIndex, *pBox);
}
void TextureD3D12Impl :: CopyData(IDeviceContext* pContext,