Add support for pixel unpack buffers to TexImage3D.
TRAC #23846
Signed-off-by: Shannon Woods
Signed-off-by: Geoff Lang
diff --git a/src/libGLESv2/Texture.cpp b/src/libGLESv2/Texture.cpp
index 40ce046..5af2fdb 100644
--- a/src/libGLESv2/Texture.cpp
+++ b/src/libGLESv2/Texture.cpp
@@ -1723,7 +1723,28 @@
: GetSizedInternalFormat(format, type, clientVersion);
redefineImage(level, sizedInternalFormat, width, height, depth);
- Texture::setImage(unpack, type, pixels, mImageArray[level]);
+ bool fastUnpacked = false;
+
+ // Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer
+ if (isFastUnpackable(unpack, sizedInternalFormat))
+ {
+ // Will try to create RT storage if it does not exist
+ rx::RenderTarget *destRenderTarget = getRenderTarget(level);
+ Box destArea(0, 0, 0, getWidth(level), getHeight(level), getDepth(level));
+
+ if (destRenderTarget && fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget))
+ {
+ // Ensure we don't overwrite our newly initialized data
+ mImageArray[level]->markClean();
+
+ fastUnpacked = true;
+ }
+ }
+
+ if (!fastUnpacked)
+ {
+ Texture::setImage(unpack, type, pixels, mImageArray[level]);
+ }
}
void Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
@@ -2058,6 +2079,25 @@
mDirtyImages = true;
}
+rx::RenderTarget *Texture3D::getRenderTarget(GLint level)
+{
+ // ensure the underlying texture is created
+ if (getStorage(true) == NULL)
+ {
+ return NULL;
+ }
+
+ updateTexture();
+
+ // ensure this is NOT a depth texture
+ if (isDepth(level))
+ {
+ return NULL;
+ }
+
+ return mTexStorage->getRenderTarget(level);
+}
+
rx::RenderTarget *Texture3D::getRenderTarget(GLint level, GLint layer)
{
// ensure the underlying texture is created
diff --git a/src/libGLESv2/Texture.h b/src/libGLESv2/Texture.h
index b7e51e9..14704f6 100644
--- a/src/libGLESv2/Texture.h
+++ b/src/libGLESv2/Texture.h
@@ -313,6 +313,7 @@
protected:
friend class RenderbufferTexture3DLayer;
+ rx::RenderTarget *getRenderTarget(GLint level);
rx::RenderTarget *getRenderTarget(GLint level, GLint layer);
rx::RenderTarget *getDepthStencil(GLint level, GLint layer);
virtual int levelCount();
diff --git a/src/libGLESv2/renderer/TextureStorage.cpp b/src/libGLESv2/renderer/TextureStorage.cpp
index 705c327..9ef059b 100644
--- a/src/libGLESv2/renderer/TextureStorage.cpp
+++ b/src/libGLESv2/renderer/TextureStorage.cpp
@@ -146,6 +146,11 @@
mInstance->generateMipmap(level);
}
+RenderTarget *TextureStorageInterface3D::getRenderTarget(GLint level) const
+{
+ return mInstance->getRenderTarget(level);
+}
+
RenderTarget *TextureStorageInterface3D::getRenderTarget(GLint level, GLint layer) const
{
return mInstance->getRenderTargetLayer(level, layer);
diff --git a/src/libGLESv2/renderer/TextureStorage.h b/src/libGLESv2/renderer/TextureStorage.h
index bd335db..47a192c 100644
--- a/src/libGLESv2/renderer/TextureStorage.h
+++ b/src/libGLESv2/renderer/TextureStorage.h
@@ -111,6 +111,7 @@
virtual ~TextureStorageInterface3D();
void generateMipmap(int level);
+ RenderTarget *getRenderTarget(GLint level) const;
RenderTarget *getRenderTarget(GLint level, GLint layer) const;
virtual unsigned int getRenderTargetSerial(GLint level, GLint layer) const;