diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2018-08-29 15:42:31 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2018-08-29 15:42:31 +0000 |
| commit | 5e399e3e17973ad1d5efb0de2a9c378ede73f377 (patch) | |
| tree | ef79f8a86fba3eab4192489cf04675967bae17c4 /Graphics/GraphicsEngine | |
| parent | Added few debug checks (diff) | |
| download | DiligentCore-5e399e3e17973ad1d5efb0de2a9c378ede73f377.tar.gz DiligentCore-5e399e3e17973ad1d5efb0de2a9c378ede73f377.zip | |
Fixed update data for compressed textures
Diffstat (limited to 'Graphics/GraphicsEngine')
| -rw-r--r-- | Graphics/GraphicsEngine/src/Texture.cpp | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/Graphics/GraphicsEngine/src/Texture.cpp b/Graphics/GraphicsEngine/src/Texture.cpp index c459fa59..9ce2125c 100644 --- a/Graphics/GraphicsEngine/src/Texture.cpp +++ b/Graphics/GraphicsEngine/src/Texture.cpp @@ -112,7 +112,7 @@ void ValidateTextureDesc( const TextureDesc& Desc ) } -void ValidateTextureRegion(const TextureDesc &TexDesc, Uint32 MipLevel, Uint32 Slice, const Box &Box) +void ValidateTextureRegion(const TextureDesc& TexDesc, Uint32 MipLevel, Uint32 Slice, const Box& Box) { #define VERIFY_TEX_PARAMS(Expr, ...) if(!(Expr))LOG_ERROR("Texture \"", TexDesc.Name ? TexDesc.Name : "", "\": ", ##__VA_ARGS__) #ifdef DEVELOPMENT @@ -121,7 +121,7 @@ void ValidateTextureRegion(const TextureDesc &TexDesc, Uint32 MipLevel, Uint32 S VERIFY_TEX_PARAMS( Box.MinY < Box.MaxY, "Invalid Y range: ", Box.MinY, "..", Box.MaxY); VERIFY_TEX_PARAMS( Box.MinZ < Box.MaxZ, "Invalid Z range: ", Box.MinZ, "..", Box.MaxZ); - if( TexDesc.Type == RESOURCE_DIM_TEX_1D_ARRAY || + 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) @@ -136,22 +136,31 @@ void ValidateTextureRegion(const TextureDesc &TexDesc, Uint32 MipLevel, Uint32 S 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( TexDesc.Type != RESOURCE_DIM_TEX_1D && - TexDesc.Type != RESOURCE_DIM_TEX_1D_ARRAY ) + 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( TexDesc.Type == RESOURCE_DIM_TEX_3D ) + if (TexDesc.Type == RESOURCE_DIM_TEX_3D) { 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) + { + 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, ")" ); + } #endif } -void ValidateUpdateDataParams( const TextureDesc &TexDesc, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) +void ValidateUpdateDataParams( const TextureDesc& TexDesc, Uint32 MipLevel, Uint32 Slice, const Box& DstBox, const TextureSubResData& SubresData ) { VERIFY((SubresData.pData != nullptr) ^ (SubresData.pSrcBuffer != nullptr), "Either CPU memory pointer or GPU buffer must be provided, exclusively"); ValidateTextureRegion(TexDesc, MipLevel, Slice, DstBox); @@ -161,6 +170,15 @@ void ValidateUpdateDataParams( const TextureDesc &TexDesc, Uint32 MipLevel, Uint VERIFY_TEX_PARAMS( TexDesc.SampleCount == 1, "Only non-multisampled textures can be updated with UpdateData()" ); 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; + 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}; + 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, "Source data depth stride (", SubresData.DepthStride, ") is below the image plane size (", SubresData.Stride * UpdateRegionHeight, ")"); #endif } |
