Skip to content

Commit 9adebb7

Browse files
GL: Fix staging 3D texture copy
1 parent ab90b00 commit 9adebb7

File tree

1 file changed

+62
-56
lines changed

1 file changed

+62
-56
lines changed

Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp

Lines changed: 62 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1857,66 +1857,72 @@ void DeviceContextGLImpl::CopyTexture(const CopyTextureAttribs& CopyAttribs)
18571857
}
18581858
else if (SrcTexDesc.Usage != USAGE_STAGING && DstTexDesc.Usage == USAGE_STAGING)
18591859
{
1860-
if (pSrcTexGL->GetGLTextureHandle() == 0)
1861-
{
1862-
GLuint DefaultFBOHandle = m_pSwapChain->GetDefaultFBO();
1863-
glBindFramebuffer(GL_READ_FRAMEBUFFER, DefaultFBOHandle);
1864-
DEV_CHECK_GL_ERROR("Failed to bind default FBO as read framebuffer");
1865-
}
1866-
else
1867-
{
1868-
const TextureFormatAttribs& FmtAttribs = GetTextureFormatAttribs(SrcTexDesc.Format);
1869-
DEV_CHECK_ERR(FmtAttribs.ComponentType != COMPONENT_TYPE_COMPRESSED,
1870-
"Reading pixels from compressed-format textures to pixel pack buffer is not supported");
1871-
1872-
TextureViewDesc SrcTexViewDesc;
1873-
SrcTexViewDesc.Format = SrcTexDesc.Format;
1874-
SrcTexViewDesc.ViewType =
1875-
(FmtAttribs.ComponentType == COMPONENT_TYPE_DEPTH || FmtAttribs.ComponentType == COMPONENT_TYPE_DEPTH_STENCIL) ?
1876-
TEXTURE_VIEW_DEPTH_STENCIL :
1877-
TEXTURE_VIEW_RENDER_TARGET;
1878-
SrcTexViewDesc.MostDetailedMip = CopyAttribs.SrcMipLevel;
1879-
SrcTexViewDesc.FirstArraySlice = CopyAttribs.SrcSlice;
1880-
SrcTexViewDesc.NumArraySlices = 1;
1881-
SrcTexViewDesc.NumMipLevels = 1;
1882-
TextureViewGLImpl SrcTexView //
1883-
{
1884-
nullptr, // pRefCounters
1885-
m_pDevice,
1886-
SrcTexViewDesc,
1887-
pSrcTexGL,
1888-
false, // bCreateGLViewTex
1889-
false // bIsDefaultView
1890-
};
1891-
1892-
GLContext::NativeGLContextType CurrNativeGLCtx = m_ContextState.GetCurrentGLContext();
1893-
FBOCache& fboCache = m_pDevice->GetFBOCache(CurrNativeGLCtx);
1860+
BufferGLImpl* pDstBuffer = ClassPtrCast<BufferGLImpl>(pDstTexGL->GetPBO());
1861+
VERIFY(pDstBuffer != nullptr, "Internal staging buffer must not be null");
1862+
const NativePixelAttribs& TransferAttribs = GetNativePixelTransferAttribs(SrcTexDesc.Format);
18941863

1895-
TextureViewGLImpl* pSrcViews[] = {&SrcTexView};
1864+
GLContext::NativeGLContextType CurrNativeGLCtx = m_ContextState.GetCurrentGLContext();
1865+
FBOCache& fboCache = m_pDevice->GetFBOCache(CurrNativeGLCtx);
18961866

1897-
const GLObjectWrappers::GLFrameBufferObj& SrcFBO =
1898-
(SrcTexViewDesc.ViewType == TEXTURE_VIEW_RENDER_TARGET) ?
1899-
fboCache.GetFBO(1, pSrcViews, nullptr, m_ContextState) :
1900-
fboCache.GetFBO(0, nullptr, pSrcViews[0], m_ContextState);
1901-
glBindFramebuffer(GL_READ_FRAMEBUFFER, SrcFBO);
1902-
DEV_CHECK_GL_ERROR("Failed to bind FBO as read framebuffer");
1903-
}
1867+
for (Uint32 ZSlice = pSrcBox->MinZ; ZSlice < pSrcBox->MaxZ; ++ZSlice)
1868+
{
1869+
if (pSrcTexGL->GetGLTextureHandle() == 0)
1870+
{
1871+
VERIFY(ZSlice == 0, "Default FBO must have only one Z slice");
1872+
GLuint DefaultFBOHandle = m_pSwapChain->GetDefaultFBO();
1873+
glBindFramebuffer(GL_READ_FRAMEBUFFER, DefaultFBOHandle);
1874+
DEV_CHECK_GL_ERROR("Failed to bind default FBO as read framebuffer");
1875+
}
1876+
else
1877+
{
1878+
const TextureFormatAttribs& FmtAttribs = GetTextureFormatAttribs(SrcTexDesc.Format);
1879+
DEV_CHECK_ERR(FmtAttribs.ComponentType != COMPONENT_TYPE_COMPRESSED,
1880+
"Reading pixels from compressed-format textures to pixel pack buffer is not supported");
1881+
1882+
TextureViewDesc SrcTexViewDesc;
1883+
SrcTexViewDesc.Format = SrcTexDesc.Format;
1884+
SrcTexViewDesc.ViewType =
1885+
(FmtAttribs.ComponentType == COMPONENT_TYPE_DEPTH || FmtAttribs.ComponentType == COMPONENT_TYPE_DEPTH_STENCIL) ?
1886+
TEXTURE_VIEW_DEPTH_STENCIL :
1887+
TEXTURE_VIEW_RENDER_TARGET;
1888+
SrcTexViewDesc.MostDetailedMip = CopyAttribs.SrcMipLevel;
1889+
SrcTexViewDesc.FirstArraySlice = CopyAttribs.SrcSlice + ZSlice;
1890+
SrcTexViewDesc.NumArraySlices = 1;
1891+
SrcTexViewDesc.NumMipLevels = 1;
1892+
TextureViewGLImpl SrcTexView //
1893+
{
1894+
nullptr, // pRefCounters
1895+
m_pDevice,
1896+
SrcTexViewDesc,
1897+
pSrcTexGL,
1898+
false, // bCreateGLViewTex
1899+
false, // bIsDefaultView
1900+
};
1901+
1902+
TextureViewGLImpl* pSrcViews[] = {&SrcTexView};
1903+
1904+
const GLObjectWrappers::GLFrameBufferObj& SrcFBO =
1905+
(SrcTexViewDesc.ViewType == TEXTURE_VIEW_RENDER_TARGET) ?
1906+
fboCache.GetFBO(1, pSrcViews, nullptr, m_ContextState) :
1907+
fboCache.GetFBO(0, nullptr, pSrcViews[0], m_ContextState);
1908+
glBindFramebuffer(GL_READ_FRAMEBUFFER, SrcFBO);
1909+
DEV_CHECK_GL_ERROR("Failed to bind FBO as read framebuffer");
1910+
}
19041911

1905-
BufferGLImpl* pDstBuffer = ClassPtrCast<BufferGLImpl>(pDstTexGL->GetPBO());
1906-
VERIFY(pDstBuffer != nullptr, "Internal staging buffer must not be null");
1907-
// GetStagingTextureLocationOffset assumes pixels are tightly packed in every subresource - no padding
1908-
// except between subresources.
1909-
const Uint64 DstOffset =
1910-
GetStagingTextureLocationOffset(DstTexDesc, CopyAttribs.DstSlice, CopyAttribs.DstMipLevel,
1911-
TextureBaseGL::PBOOffsetAlignment,
1912-
CopyAttribs.DstX, CopyAttribs.DstY, CopyAttribs.DstZ);
1912+
// GetStagingTextureLocationOffset assumes pixels are tightly packed in every subresource - no padding
1913+
// except between subresources.
1914+
const Uint64 DstOffset =
1915+
GetStagingTextureLocationOffset(DstTexDesc, CopyAttribs.DstSlice, CopyAttribs.DstMipLevel,
1916+
TextureBaseGL::PBOOffsetAlignment,
1917+
CopyAttribs.DstX, CopyAttribs.DstY, CopyAttribs.DstZ + (ZSlice - pSrcBox->MinZ));
19131918

1914-
m_ContextState.BindBuffer(GL_PIXEL_PACK_BUFFER, pDstBuffer->GetGLHandle(), true);
1919+
m_ContextState.BindBuffer(GL_PIXEL_PACK_BUFFER, pDstBuffer->GetGLHandle(), true);
19151920

1916-
const NativePixelAttribs& TransferAttribs = GetNativePixelTransferAttribs(SrcTexDesc.Format);
1917-
glReadPixels(pSrcBox->MinX, pSrcBox->MinY, pSrcBox->Width(), pSrcBox->Height(),
1918-
TransferAttribs.PixelFormat, TransferAttribs.DataType, reinterpret_cast<void*>(StaticCast<size_t>(DstOffset)));
1919-
DEV_CHECK_GL_ERROR("Failed to read pixel from framebuffer to pixel pack buffer");
1921+
glReadPixels(pSrcBox->MinX, pSrcBox->MinY, pSrcBox->Width(), pSrcBox->Height(),
1922+
TransferAttribs.PixelFormat, TransferAttribs.DataType,
1923+
reinterpret_cast<void*>(StaticCast<size_t>(DstOffset)));
1924+
DEV_CHECK_GL_ERROR("Failed to read pixel from framebuffer to pixel pack buffer");
1925+
}
19201926

19211927
m_ContextState.BindBuffer(GL_PIXEL_PACK_BUFFER, GLObjectWrappers::GLBufferObj::Null(), true);
19221928
// Restore original FBO
@@ -1950,7 +1956,7 @@ void DeviceContextGLImpl::MapTextureSubresource(ITexture* pTextu
19501956
pPBO->MapRange(m_ContextState, MapType, MapFlags, PBOOffset, MipLevelAttribs.MipSize, MappedData.pData);
19511957

19521958
MappedData.Stride = MipLevelAttribs.RowSize;
1953-
MappedData.DepthStride = MipLevelAttribs.MipSize;
1959+
MappedData.DepthStride = MipLevelAttribs.DepthSliceSize;
19541960
}
19551961
else
19561962
{

0 commit comments

Comments
 (0)