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/GraphicsEngineOpenGL | |
| parent | Fixed debug checks (diff) | |
| download | DiligentCore-7dcb7b4a2c5965a90a7fdd5fd1950d5a1036900a.tar.gz DiligentCore-7dcb7b4a2c5965a90a7fdd5fd1950d5a1036900a.zip | |
Fixed handling of small compressed texture subresources
Diffstat (limited to 'Graphics/GraphicsEngineOpenGL')
7 files changed, 56 insertions, 32 deletions
diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture1DArray_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture1DArray_OGL.cpp index d636f8b4..57478e47 100644 --- a/Graphics/GraphicsEngineOpenGL/src/Texture1DArray_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/Texture1DArray_OGL.cpp @@ -66,8 +66,8 @@ Texture1DArray_OGL::Texture1DArray_OGL( IReferenceCounters *pRefCounters, { for(Uint32 Mip = 0; Mip < m_Desc.MipLevels; ++Mip) { - Box DstBox(0, std::max(m_Desc.Width>>Mip, 1U), - 0, 1 ); + Box DstBox{0, std::max(m_Desc.Width>>Mip, 1U), + 0, 1 }; // UpdateData() is a virtual function. If we try to call it through vtbl from here, // we will get into TextureBaseGL::UpdateData(), because instance of Texture1DArray_OGL // is not fully constructed yet. diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture1D_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture1D_OGL.cpp index 2a4a1fd7..f5ee0def 100644 --- a/Graphics/GraphicsEngineOpenGL/src/Texture1D_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/Texture1D_OGL.cpp @@ -64,8 +64,8 @@ Texture1D_OGL::Texture1D_OGL( IReferenceCounters *pRefCounters, { for(Uint32 Mip = 0; Mip < m_Desc.MipLevels; ++Mip) { - Box DstBox(0, std::max(m_Desc.Width>>Mip, 1U), - 0, 1); + Box DstBox{0, std::max(m_Desc.Width>>Mip, 1U), + 0, 1}; // UpdateData() is a virtual function. If we try to call it through vtbl from here, // we will get into TextureBaseGL::UpdateData(), because instance of Texture1D_OGL // is not fully constructed yet. diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture2DArray_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture2DArray_OGL.cpp index 5368281a..e1cc57c1 100644 --- a/Graphics/GraphicsEngineOpenGL/src/Texture2DArray_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/Texture2DArray_OGL.cpp @@ -84,8 +84,8 @@ Texture2DArray_OGL::Texture2DArray_OGL( IReferenceCounters *pRefCounters, { for(Uint32 Mip = 0; Mip < m_Desc.MipLevels; ++Mip) { - Box DstBox(0, std::max(m_Desc.Width >>Mip, 1U), - 0, std::max(m_Desc.Height>>Mip, 1U) ); + Box DstBox{0, std::max(m_Desc.Width >>Mip, 1U), + 0, std::max(m_Desc.Height>>Mip, 1U)}; // UpdateData() is a virtual function. If we try to call it through vtbl from here, // we will get into TextureBaseGL::UpdateData(), because instance of Texture2DArray_OGL // is not fully constructed yet. @@ -147,9 +147,11 @@ void Texture2DArray_OGL::UpdateData(IDeviceContext *pContext, Uint32 MipLevel, U if( TransferAttribs.IsCompressed ) { - VERIFY( (DstBox.MinX % 4) == 0 && (DstBox.MinY % 4) == 0 && - ((DstBox.MaxX % 4) == 0 || DstBox.MaxX == std::max(m_Desc.Width >>MipLevel, 1U)) && - ((DstBox.MaxY % 4) == 0 || DstBox.MaxY == std::max(m_Desc.Height>>MipLevel, 1U)), + auto MipWidth = std::max(m_Desc.Width >> MipLevel, 1U); + auto MipHeight = std::max(m_Desc.Height >> MipLevel, 1U); + VERIFY( (DstBox.MinX % 4) == 0 && (DstBox.MinY % 4) == 0 && + ((DstBox.MaxX % 4) == 0 || DstBox.MaxX == MipWidth) && + ((DstBox.MaxY % 4) == 0 || DstBox.MaxY == MipHeight), "Compressed texture update region must be 4 pixel-aligned" ); const auto &FmtAttribs = GetTextureFormatAttribs(m_Desc.Format); auto BlockBytesInRow = ((DstBox.MaxX - DstBox.MinX + 3)/4) * Uint32{FmtAttribs.ComponentSize}; @@ -158,12 +160,16 @@ void Texture2DArray_OGL::UpdateData(IDeviceContext *pContext, Uint32 MipLevel, U //glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); //glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, 0); + auto UpdateRegionWidth = DstBox.MaxX - DstBox.MinX; + auto UpdateRegionHeight = DstBox.MaxY - DstBox.MinY; + UpdateRegionWidth = std::min(UpdateRegionWidth, MipWidth - DstBox.MinX); + UpdateRegionHeight = std::min(UpdateRegionHeight, MipHeight - DstBox.MinY); glCompressedTexSubImage3D(m_BindTarget, MipLevel, DstBox.MinX, DstBox.MinY, Slice, - DstBox.MaxX - DstBox.MinX, - DstBox.MaxY - DstBox.MinY, + UpdateRegionWidth, + UpdateRegionHeight, 1, // The format must be the same compressed-texture format previously // specified by glTexStorage2D() (thank you OpenGL for another useless diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture2D_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture2D_OGL.cpp index f4171812..631b44ca 100644 --- a/Graphics/GraphicsEngineOpenGL/src/Texture2D_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/Texture2D_OGL.cpp @@ -88,8 +88,8 @@ Texture2D_OGL::Texture2D_OGL( IReferenceCounters *pRefCounters, { for(Uint32 Mip = 0; Mip < m_Desc.MipLevels; ++Mip) { - Box DstBox(0, std::max(m_Desc.Width >>Mip, 1U), - 0, std::max(m_Desc.Height>>Mip, 1U) ); + Box DstBox{0, std::max(m_Desc.Width >>Mip, 1U), + 0, std::max(m_Desc.Height>>Mip, 1U)}; // UpdateData() is a virtual function. If we try to call it through vtbl from here, // we will get into TextureBaseGL::UpdateData(), because instance of Texture2D_OGL // is not fully constructed yet. @@ -149,9 +149,11 @@ void Texture2D_OGL::UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint3 if( TransferAttribs.IsCompressed ) { + auto MipWidth = std::max(m_Desc.Width >> MipLevel, 1U); + auto MipHeight = std::max(m_Desc.Height >> MipLevel, 1U); VERIFY( (DstBox.MinX % 4) == 0 && (DstBox.MinY % 4) == 0 && - ((DstBox.MaxX % 4) == 0 || DstBox.MaxX == std::max(m_Desc.Width >>MipLevel, 1U)) && - ((DstBox.MaxY % 4) == 0 || DstBox.MaxY == std::max(m_Desc.Height>>MipLevel, 1U)), + ((DstBox.MaxX % 4) == 0 || DstBox.MaxX == MipWidth) && + ((DstBox.MaxY % 4) == 0 || DstBox.MaxY == MipHeight), "Compressed texture update region must be 4 pixel-aligned" ); const auto &FmtAttribs = GetTextureFormatAttribs(m_Desc.Format); auto BlockBytesInRow = ((DstBox.MaxX - DstBox.MinX + 3)/4) * Uint32{FmtAttribs.ComponentSize}; @@ -160,11 +162,15 @@ void Texture2D_OGL::UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint3 //glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); //glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, 0); + auto UpdateRegionWidth = DstBox.MaxX - DstBox.MinX; + auto UpdateRegionHeight = DstBox.MaxY - DstBox.MinY; + UpdateRegionWidth = std::min(UpdateRegionWidth, MipWidth - DstBox.MinX); + UpdateRegionHeight = std::min(UpdateRegionHeight, MipHeight - DstBox.MinY); glCompressedTexSubImage2D(m_BindTarget, MipLevel, DstBox.MinX, DstBox.MinY, - DstBox.MaxX - DstBox.MinX, - DstBox.MaxY - DstBox.MinY, + UpdateRegionWidth, + UpdateRegionHeight, // The format must be the same compressed-texture format previously // specified by glTexStorage2D() (thank you OpenGL for another useless // parameter that is nothing but the source of confusion), otherwise diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture3D_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture3D_OGL.cpp index 51b52c88..6fb7645a 100644 --- a/Graphics/GraphicsEngineOpenGL/src/Texture3D_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/Texture3D_OGL.cpp @@ -66,9 +66,9 @@ Texture3D_OGL::Texture3D_OGL( IReferenceCounters *pRefCounters, { for(Uint32 Mip = 0; Mip < m_Desc.MipLevels; ++Mip) { - Box DstBox(0, std::max(m_Desc.Width >>Mip, 1U), - 0, std::max(m_Desc.Height>>Mip, 1U), - 0, std::max(m_Desc.Depth >>Mip, 1U)); + Box DstBox{0, std::max(m_Desc.Width >>Mip, 1U), + 0, std::max(m_Desc.Height>>Mip, 1U), + 0, std::max(m_Desc.Depth >>Mip, 1U)}; // UpdateData() is a virtual function. If we try to call it through vtbl from here, // we will get into TextureBaseGL::UpdateData(), because instance of Texture3D_OGL // is not fully constructed yet. diff --git a/Graphics/GraphicsEngineOpenGL/src/TextureCubeArray_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/TextureCubeArray_OGL.cpp index 3851d31f..eddea87a 100644 --- a/Graphics/GraphicsEngineOpenGL/src/TextureCubeArray_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/TextureCubeArray_OGL.cpp @@ -73,8 +73,8 @@ TextureCubeArray_OGL::TextureCubeArray_OGL( IReferenceCounters *pRefCounters, { for(Uint32 Mip = 0; Mip < m_Desc.MipLevels; ++Mip) { - Box DstBox(0, std::max(m_Desc.Width >>Mip, 1U), - 0, std::max(m_Desc.Height>>Mip, 1U) ); + Box DstBox{0, std::max(m_Desc.Width >>Mip, 1U), + 0, std::max(m_Desc.Height>>Mip, 1U)}; // UpdateData() is a virtual function. If we try to call it through vtbl from here, // we will get into TextureBaseGL::UpdateData(), because instance of TextureCubeArray_OGL // is not fully constructed yet. @@ -133,9 +133,11 @@ void TextureCubeArray_OGL::UpdateData( IDeviceContext *pContext, Uint32 MipLevel if( TransferAttribs.IsCompressed ) { + auto MipWidth = std::max(m_Desc.Width >> MipLevel, 1U); + auto MipHeight = std::max(m_Desc.Height >> MipLevel, 1U); VERIFY( (DstBox.MinX % 4) == 0 && (DstBox.MinY % 4) == 0 && - ((DstBox.MaxX % 4) == 0 || DstBox.MaxX == std::max(m_Desc.Width >>MipLevel, 1U)) && - ((DstBox.MaxY % 4) == 0 || DstBox.MaxY == std::max(m_Desc.Height>>MipLevel, 1U)), + ((DstBox.MaxX % 4) == 0 || DstBox.MaxX == MipWidth) && + ((DstBox.MaxY % 4) == 0 || DstBox.MaxY == MipHeight), "Compressed texture update region must be 4 pixel-aligned" ); const auto &FmtAttribs = GetTextureFormatAttribs(m_Desc.Format); auto BlockBytesInRow = ((DstBox.MaxX - DstBox.MinX + 3)/4) * Uint32{FmtAttribs.ComponentSize}; @@ -146,12 +148,16 @@ void TextureCubeArray_OGL::UpdateData( IDeviceContext *pContext, Uint32 MipLevel //glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); //glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, 0); + auto UpdateRegionWidth = DstBox.MaxX - DstBox.MinX; + auto UpdateRegionHeight = DstBox.MaxY - DstBox.MinY; + UpdateRegionWidth = std::min(UpdateRegionWidth, MipWidth - DstBox.MinX); + UpdateRegionHeight = std::min(UpdateRegionHeight, MipHeight - DstBox.MinY); glCompressedTexSubImage3D(m_BindTarget, MipLevel, DstBox.MinX, DstBox.MinY, Slice, - DstBox.MaxX - DstBox.MinX, - DstBox.MaxY - DstBox.MinY, + UpdateRegionWidth, + UpdateRegionHeight, 1, // The format must be the same compressed-texture format previously // specified by glTexStorage2D() (thank you OpenGL for another useless diff --git a/Graphics/GraphicsEngineOpenGL/src/TextureCube_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/TextureCube_OGL.cpp index 508ee6b2..ce7fe1d5 100644 --- a/Graphics/GraphicsEngineOpenGL/src/TextureCube_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/TextureCube_OGL.cpp @@ -71,8 +71,8 @@ TextureCube_OGL::TextureCube_OGL( IReferenceCounters *pRefCounters, { for(Uint32 Mip = 0; Mip < m_Desc.MipLevels; ++Mip) { - Box DstBox(0, std::max(m_Desc.Width >>Mip, 1U), - 0, std::max(m_Desc.Height>>Mip, 1U) ); + Box DstBox{0, std::max(m_Desc.Width >>Mip, 1U), + 0, std::max(m_Desc.Height>>Mip, 1U)}; // UpdateData() is a virtual function. If we try to call it through vtbl from here, // we will get into TextureBaseGL::UpdateData(), because instance of TextureCube_OGL // is not fully constructed yet. @@ -147,9 +147,11 @@ void TextureCube_OGL::UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uin if( TransferAttribs.IsCompressed ) { + auto MipWidth = std::max(m_Desc.Width >> MipLevel, 1U); + auto MipHeight = std::max(m_Desc.Height >> MipLevel, 1U); VERIFY( (DstBox.MinX % 4) == 0 && (DstBox.MinY % 4) == 0 && - ((DstBox.MaxX % 4) == 0 || DstBox.MaxX == std::max(m_Desc.Width >>MipLevel, 1U)) && - ((DstBox.MaxY % 4) == 0 || DstBox.MaxY == std::max(m_Desc.Height>>MipLevel, 1U)), + ((DstBox.MaxX % 4) == 0 || DstBox.MaxX == MipWidth) && + ((DstBox.MaxY % 4) == 0 || DstBox.MaxY == MipHeight), "Compressed texture update region must be 4 pixel-aligned" ); const auto &FmtAttribs = GetTextureFormatAttribs(m_Desc.Format); auto BlockBytesInRow = ((DstBox.MaxX - DstBox.MinX + 3)/4) * Uint32{FmtAttribs.ComponentSize}; @@ -161,11 +163,15 @@ void TextureCube_OGL::UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uin // Texture must be bound as GL_TEXTURE_CUBE_MAP, but glCompressedTexSubImage2D() // takes one of GL_TEXTURE_CUBE_MAP_POSITIVE_X ... GL_TEXTURE_CUBE_MAP_NEGATIVE_Z + auto UpdateRegionWidth = DstBox.MaxX - DstBox.MinX; + auto UpdateRegionHeight = DstBox.MaxY - DstBox.MinY; + UpdateRegionWidth = std::min(UpdateRegionWidth, MipWidth - DstBox.MinX); + UpdateRegionHeight = std::min(UpdateRegionHeight, MipHeight - DstBox.MinY); glCompressedTexSubImage2D(CubeMapFaceBindTarget, MipLevel, DstBox.MinX, DstBox.MinY, - DstBox.MaxX - DstBox.MinX, - DstBox.MaxY - DstBox.MinY, + UpdateRegionWidth, + UpdateRegionHeight, // The format must be the same compressed-texture format previously // specified by glTexStorage2D() (thank you OpenGL for another useless // parameter that is nothing but the source of confusion), otherwise |
