diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2018-08-30 05:33:33 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2018-08-30 05:33:33 +0000 |
| commit | 7dcb7b4a2c5965a90a7fdd5fd1950d5a1036900a (patch) | |
| tree | 7559c64aebaaae5a2c4a2f7a2de7e22377191af2 /Graphics/GraphicsEngine | |
| parent | Fixed debug checks (diff) | |
| download | DiligentCore-7dcb7b4a2c5965a90a7fdd5fd1950d5a1036900a.tar.gz DiligentCore-7dcb7b4a2c5965a90a7fdd5fd1950d5a1036900a.zip | |
Fixed handling of small compressed texture subresources
Diffstat (limited to 'Graphics/GraphicsEngine')
| -rw-r--r-- | Graphics/GraphicsEngine/interface/GraphicsTypes.h | 21 | ||||
| -rw-r--r-- | Graphics/GraphicsEngine/src/Texture.cpp | 63 |
2 files changed, 54 insertions, 30 deletions
diff --git a/Graphics/GraphicsEngine/interface/GraphicsTypes.h b/Graphics/GraphicsEngine/interface/GraphicsTypes.h index 8201ebd6..4ac6148a 100644 --- a/Graphics/GraphicsEngine/interface/GraphicsTypes.h +++ b/Graphics/GraphicsEngine/interface/GraphicsTypes.h @@ -1394,21 +1394,12 @@ namespace Diligent /// Box struct Box { - Uint32 MinX; ///< Minimal X coordinate. Default value is 0 - Uint32 MaxX; ///< Maximal X coordinate. Default value is 0 - Uint32 MinY; ///< Minimal Y coordinate. Default value is 0 - Uint32 MaxY; ///< Maximal Y coordinate. Default value is 0 - Uint32 MinZ; ///< Minimal Z coordinate. Default value is 0 - Uint32 MaxZ; ///< Maximal Z coordinate. Default value is 1 - - /// Constructor intializes the structure - Box(Uint32 _MinX = 0, Uint32 _MaxX = 0, - Uint32 _MinY = 0, Uint32 _MaxY = 0, - Uint32 _MinZ = 0, Uint32 _MaxZ = 1) : - MinX(_MinX), MaxX(_MaxX), - MinY(_MinY), MaxY(_MaxY), - MinZ(_MinZ), MaxZ(_MaxZ) - {} + Uint32 MinX = 0; ///< Minimal X coordinate. Default value is 0 + Uint32 MaxX = 0; ///< Maximal X coordinate. Default value is 0 + Uint32 MinY = 0; ///< Minimal Y coordinate. Default value is 0 + Uint32 MaxY = 0; ///< Maximal Y coordinate. Default value is 0 + Uint32 MinZ = 0; ///< Minimal Z coordinate. Default value is 0 + Uint32 MaxZ = 1; ///< Maximal Z coordinate. Default value is 1 }; diff --git a/Graphics/GraphicsEngine/src/Texture.cpp b/Graphics/GraphicsEngine/src/Texture.cpp index 9b78202f..1bb69c72 100644 --- a/Graphics/GraphicsEngine/src/Texture.cpp +++ b/Graphics/GraphicsEngine/src/Texture.cpp @@ -133,14 +133,34 @@ void ValidateTextureRegion(const TextureDesc& TexDesc, Uint32 MipLevel, Uint32 S VERIFY_TEX_PARAMS( Slice == 0, "Array slice (", Slice, ") must be 0 for non-array textures" ); } + const auto& FmtAttribs = GetTextureFormatAttribs(TexDesc.Format); Uint32 MipWidth = std::max(TexDesc.Width >> MipLevel, 1U); - VERIFY_TEX_PARAMS( Box.MaxX <= MipWidth, "Region max X coordinate (", Box.MaxX, ") is out of allowed range [0, ", MipWidth, "]" ); + if(FmtAttribs.ComponentType == COMPONENT_TYPE_COMPRESSED) + { + VERIFY_EXPR( (FmtAttribs.BlockWidth & (FmtAttribs.BlockWidth-1)) == 0); + Uint32 BlockAlignedMipWidth = (MipWidth + (FmtAttribs.BlockWidth-1)) & ~(FmtAttribs.BlockWidth-1); + VERIFY_TEX_PARAMS( Box.MaxX <= BlockAlignedMipWidth, "Region max X coordinate (", Box.MaxX, ") is out of allowed range [0, ", BlockAlignedMipWidth, "]" ); + VERIFY_TEX_PARAMS( (Box.MinX % FmtAttribs.BlockWidth) == 0, "For compressed formats, update region min x (", Box.MinX, ") must be a multiple of block width (", FmtAttribs.BlockWidth, ")" ); + VERIFY_TEX_PARAMS( (Box.MaxX % FmtAttribs.BlockWidth) == 0 || Box.MaxX == MipWidth, "For compressed formats, update region max x (", Box.MaxX, ") must be a multiple of block width (", FmtAttribs.BlockWidth, ") or equal the mip level width (", MipWidth, ")" ); + } + else + VERIFY_TEX_PARAMS( Box.MaxX <= MipWidth, "Region max X coordinate (", Box.MaxX, ") is out of allowed range [0, ", MipWidth, "]" ); + if (TexDesc.Type != RESOURCE_DIM_TEX_1D && TexDesc.Type != RESOURCE_DIM_TEX_1D_ARRAY) { Uint32 MipHeight = std::max(TexDesc.Height >> MipLevel, 1U); - VERIFY_TEX_PARAMS( Box.MaxY <= MipHeight, "Region max Y coordinate (", Box.MaxY, ") is out of allowed range [0, ", MipHeight, "]" ); + if(FmtAttribs.ComponentType == COMPONENT_TYPE_COMPRESSED) + { + VERIFY_EXPR( (FmtAttribs.BlockHeight & (FmtAttribs.BlockHeight-1)) == 0); + Uint32 BlockAlignedMipHeight = (MipHeight + (FmtAttribs.BlockHeight-1)) & ~(FmtAttribs.BlockHeight-1); + VERIFY_TEX_PARAMS( Box.MaxY <= BlockAlignedMipHeight, "Region max Y coordinate (", Box.MaxY, ") is out of allowed range [0, ", BlockAlignedMipHeight, "]" ); + VERIFY_TEX_PARAMS( (Box.MinY % FmtAttribs.BlockHeight) == 0, "For compressed formats, update region min y (", Box.MinY, ") must be a multiple of block height (", FmtAttribs.BlockHeight, ")" ); + VERIFY_TEX_PARAMS( (Box.MaxY % FmtAttribs.BlockHeight) == 0 || Box.MaxY == MipHeight, "For compressed formats, update region max y (", Box.MaxY, ") must be a multiple of block height (", FmtAttribs.BlockHeight, ") or equal the mip level height (", MipHeight, ")" ); + } + else + VERIFY_TEX_PARAMS( Box.MaxY <= MipHeight, "Region max Y coordinate (", Box.MaxY, ") is out of allowed range [0, ", MipHeight, "]" ); } if (TexDesc.Type == RESOURCE_DIM_TEX_3D) @@ -148,14 +168,10 @@ void ValidateTextureRegion(const TextureDesc& TexDesc, Uint32 MipLevel, Uint32 S Uint32 MipDepth = std::max(TexDesc.Depth >> MipLevel, 1U); VERIFY_TEX_PARAMS( Box.MaxZ <= MipDepth, "Region max Z coordinate (", Box.MaxZ, ") is out of allowed range [0, ", MipDepth, "]" ); } - - const auto& FmtAttribs = GetTextureFormatAttribs(TexDesc.Format); - if (FmtAttribs.ComponentType == COMPONENT_TYPE_COMPRESSED) + else { - VERIFY_TEX_PARAMS( (Box.MinX % FmtAttribs.BlockWidth) == 0, "For compressed formats update region min x (", Box.MinX, ") must be a multiple of block width (", FmtAttribs.BlockWidth, ")" ); - VERIFY_TEX_PARAMS( (Box.MaxX % FmtAttribs.BlockWidth) == 0, "For compressed formats update region max x (", Box.MaxX, ") must be a multiple of block width (", FmtAttribs.BlockWidth, ")" ); - VERIFY_TEX_PARAMS( (Box.MinY % FmtAttribs.BlockHeight) == 0, "For compressed formats update region min y (", Box.MinY, ") must be a multiple of block height (", FmtAttribs.BlockHeight, ")" ); - VERIFY_TEX_PARAMS( (Box.MaxY % FmtAttribs.BlockHeight) == 0, "For compressed formats update region max y (", Box.MaxY, ") must be a multiple of block height (", FmtAttribs.BlockHeight, ")" ); + VERIFY_TEX_PARAMS( Box.MinZ == 0, "Region min Z (", Box.MinZ, ") must be 0 for all but 3D textures" ); + VERIFY_TEX_PARAMS( Box.MaxZ == 1, "Region max Z (", Box.MaxZ, ") must be 1 for all but 3D textures" ); } #endif } @@ -171,14 +187,31 @@ void ValidateUpdateDataParams( const TextureDesc& TexDesc, Uint32 MipLevel, Uint VERIFY_TEX_PARAMS( (SubresData.Stride & 0x03) == 0, "Texture data stride (", SubresData.Stride, ") must be at least 32-bit aligned" ); VERIFY_TEX_PARAMS( (SubresData.DepthStride & 0x03) == 0, "Texture data depth stride (", SubresData.DepthStride, ") must be at least 32-bit aligned" ); - const auto UpdateRegionWidth = DstBox.MaxX - DstBox.MinX; - const auto UpdateRegionHeight = DstBox.MaxY - DstBox.MinY; + auto UpdateRegionWidth = DstBox.MaxX - DstBox.MinX; + auto UpdateRegionHeight = DstBox.MaxY - DstBox.MinY; + auto UpdateRegionDepth = DstBox.MaxZ - DstBox.MinZ; const auto& FmtAttribs = GetTextureFormatAttribs(TexDesc.Format); - const Uint32 RowSize = FmtAttribs.ComponentType == COMPONENT_TYPE_COMPRESSED ? - UpdateRegionWidth / Uint32{FmtAttribs.BlockWidth} * Uint32{FmtAttribs.ComponentSize} : - UpdateRegionWidth * Uint32{FmtAttribs.ComponentSize} * Uint32{FmtAttribs.NumComponents}; + Uint32 RowSize = 0; + Uint32 RowCount = 0; + if (FmtAttribs.ComponentType == COMPONENT_TYPE_COMPRESSED) + { + // Align update region size by the block size. This is only necessary when updating + // coarse mip levels. Otherwise UpdateRegionWidth/Height should be multiples of block size + VERIFY_EXPR( (FmtAttribs.BlockWidth & (FmtAttribs.BlockWidth-1)) == 0); + VERIFY_EXPR( (FmtAttribs.BlockHeight & (FmtAttribs.BlockHeight-1)) == 0); + UpdateRegionWidth = (UpdateRegionWidth + (FmtAttribs.BlockWidth-1)) & ~(FmtAttribs.BlockWidth -1); + UpdateRegionHeight = (UpdateRegionHeight + (FmtAttribs.BlockHeight-1)) & ~(FmtAttribs.BlockHeight-1); + RowSize = UpdateRegionWidth / Uint32{FmtAttribs.BlockWidth} * Uint32{FmtAttribs.ComponentSize}; + RowCount = UpdateRegionHeight / FmtAttribs.BlockHeight; + } + else + { + RowSize = UpdateRegionWidth * Uint32{FmtAttribs.ComponentSize} * Uint32{FmtAttribs.NumComponents}; + RowCount = UpdateRegionHeight; + } DEV_CHECK_ERR(SubresData.Stride >= RowSize, "Source data stride (", SubresData.Stride, ") is below the image row size (", RowSize, ")"); - DEV_CHECK_ERR(SubresData.DepthStride == 0 || SubresData.DepthStride >= SubresData.Stride * (UpdateRegionHeight / FmtAttribs.BlockHeight), "Source data depth stride (", SubresData.DepthStride, ") is below the image plane size (", SubresData.Stride * UpdateRegionHeight, ")"); + const Uint32 PlaneSize = SubresData.Stride * RowCount; + DEV_CHECK_ERR(UpdateRegionDepth == 1 || SubresData.DepthStride >= PlaneSize, "Source data depth stride (", SubresData.DepthStride, ") is below the image plane size (", PlaneSize, ")"); #endif } |
