Support compressed textures with unpack buffers.
BUG=angle:792
Change-Id: I32f32422232bd4cb04c8a70005cb51482224bf3e
Reviewed-on: https://chromium-review.googlesource.com/224655
Reviewed-by: Shannon Woods <shannonwoods@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libGLESv2/renderer/d3d/TextureD3D.cpp b/src/libGLESv2/renderer/d3d/TextureD3D.cpp
index 42fea65..51593b3 100644
--- a/src/libGLESv2/renderer/d3d/TextureD3D.cpp
+++ b/src/libGLESv2/renderer/d3d/TextureD3D.cpp
@@ -26,11 +26,43 @@
namespace rx
{
+namespace
+{
+
+gl::Error GetUnpackPointer(const gl::PixelUnpackState &unpack, const void *pixels, const uint8_t **pointerOut)
+{
+ if (unpack.pixelBuffer.id() != 0)
+ {
+ // Do a CPU readback here, if we have an unpack buffer bound and the fast GPU path is not supported
+ gl::Buffer *pixelBuffer = unpack.pixelBuffer.get();
+ ptrdiff_t offset = reinterpret_cast<ptrdiff_t>(pixels);
+
+ // TODO: this is the only place outside of renderer that asks for a buffers raw data.
+ // This functionality should be moved into renderer and the getData method of BufferImpl removed.
+ const uint8_t *bufferData = NULL;
+ gl::Error error = pixelBuffer->getImplementation()->getData(&bufferData);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ *pointerOut = bufferData + offset;
+ }
+ else
+ {
+ *pointerOut = static_cast<const uint8_t *>(pixels);
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
bool IsRenderTargetUsage(GLenum usage)
{
return (usage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
}
+}
+
TextureD3D::TextureD3D(Renderer *renderer)
: mRenderer(renderer),
mUsage(GL_NONE),
@@ -124,25 +156,10 @@
// We no longer need the "GLenum format" parameter to TexImage to determine what data format "pixels" contains.
// From our image internal format we know how many channels to expect, and "type" gives the format of pixel's components.
const uint8_t *pixelData = NULL;
-
- if (unpack.pixelBuffer.id() != 0)
+ gl::Error error = GetUnpackPointer(unpack, pixels, &pixelData);
+ if (error.isError())
{
- // Do a CPU readback here, if we have an unpack buffer bound and the fast GPU path is not supported
- gl::Buffer *pixelBuffer = unpack.pixelBuffer.get();
- ptrdiff_t offset = reinterpret_cast<ptrdiff_t>(pixels);
- // TODO: setImage/subImage is the only place outside of renderer that asks for a buffers raw data.
- // This functionality should be moved into renderer and the getData method of BufferImpl removed.
- const uint8_t *bufferData = NULL;
- gl::Error error = pixelBuffer->getImplementation()->getData(&bufferData);
- if (error.isError())
- {
- return error;
- }
- pixelData = bufferData + offset;
- }
- else
- {
- pixelData = static_cast<const uint8_t *>(pixels);
+ return error;
}
if (pixelData != NULL)
@@ -172,22 +189,12 @@
gl::Error TextureD3D::subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels, const gl::ImageIndex &index)
{
- const uint8_t *pixelData = static_cast<const uint8_t *>(pixels);
-
// CPU readback & copy where direct GPU copy is not supported
- if (unpack.pixelBuffer.id() != 0)
+ const uint8_t *pixelData = NULL;
+ gl::Error error = GetUnpackPointer(unpack, pixels, &pixelData);
+ if (error.isError())
{
- gl::Buffer *pixelBuffer = unpack.pixelBuffer.get();
- uintptr_t offset = reinterpret_cast<uintptr_t>(pixels);
- // TODO: setImage/subImage is the only place outside of renderer that asks for a buffers raw data.
- // This functionality should be moved into renderer and the getData method of BufferImpl removed.
- const uint8_t *bufferData = NULL;
- gl::Error error = pixelBuffer->getImplementation()->getData(&bufferData);
- if (error.isError())
- {
- return error;
- }
- pixelData = bufferData + offset;
+ return error;
}
if (pixelData != NULL)
@@ -220,11 +227,20 @@
return gl::Error(GL_NO_ERROR);
}
-gl::Error TextureD3D::setCompressedImage(GLsizei imageSize, const void *pixels, Image *image)
+gl::Error TextureD3D::setCompressedImage(const gl::PixelUnpackState &unpack, GLsizei imageSize, const void *pixels, Image *image)
{
- if (pixels != NULL)
+ // We no longer need the "GLenum format" parameter to TexImage to determine what data format "pixels" contains.
+ // From our image internal format we know how many channels to expect, and "type" gives the format of pixel's components.
+ const uint8_t *pixelData = NULL;
+ gl::Error error = GetUnpackPointer(unpack, pixels, &pixelData);
+ if (error.isError())
{
- gl::Error error = image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth(), pixels);
+ return error;
+ }
+
+ if (pixelData != NULL)
+ {
+ gl::Error error = image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth(), pixelData);
if (error.isError())
{
return error;
@@ -237,11 +253,18 @@
}
gl::Error TextureD3D::subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLsizei imageSize, const void *pixels, Image *image)
+ GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels, Image *image)
{
- if (pixels != NULL)
+ const uint8_t *pixelData = NULL;
+ gl::Error error = GetUnpackPointer(unpack, pixels, &pixelData);
+ if (error.isError())
{
- gl::Error error = image->loadCompressedData(xoffset, yoffset, zoffset, width, height, depth, pixels);
+ return error;
+ }
+
+ if (pixelData != NULL)
+ {
+ gl::Error error = image->loadCompressedData(xoffset, yoffset, zoffset, width, height, depth, pixelData);
if (error.isError())
{
return error;
@@ -600,14 +623,14 @@
gl::Error TextureD3D_2D::setCompressedImage(GLenum target, GLint level, GLenum format,
GLsizei width, GLsizei height, GLsizei depth,
- GLsizei imageSize, const void *pixels)
+ GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(target == GL_TEXTURE_2D && depth == 1);
// compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
redefineImage(level, format, width, height);
- return TextureD3D::setCompressedImage(imageSize, pixels, mImageArray[level]);
+ return TextureD3D::setCompressedImage(unpack, imageSize, pixels, mImageArray[level]);
}
gl::Error TextureD3D_2D::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
@@ -652,11 +675,11 @@
gl::Error TextureD3D_2D::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth, GLenum format,
- GLsizei imageSize, const void *pixels)
+ GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(target == GL_TEXTURE_2D && depth == 1 && zoffset == 0);
- gl::Error error = TextureD3D::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, mImageArray[level]);
+ gl::Error error = TextureD3D::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, unpack, pixels, mImageArray[level]);
if (error.isError())
{
return error;
@@ -1157,7 +1180,7 @@
gl::Error TextureD3D_Cube::setCompressedImage(GLenum target, GLint level, GLenum format,
GLsizei width, GLsizei height, GLsizei depth,
- GLsizei imageSize, const void *pixels)
+ GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(depth == 1);
@@ -1166,7 +1189,7 @@
redefineImage(faceIndex, level, format, width, height);
- return TextureD3D::setCompressedImage(imageSize, pixels, mImageArray[faceIndex][level]);
+ return TextureD3D::setCompressedImage(unpack, imageSize, pixels, mImageArray[faceIndex][level]);
}
gl::Error TextureD3D_Cube::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
@@ -1180,13 +1203,13 @@
gl::Error TextureD3D_Cube::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth, GLenum format,
- GLsizei imageSize, const void *pixels)
+ GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(depth == 1 && zoffset == 0);
gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
- gl::Error error = TextureD3D::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, mImageArray[index.layerIndex][level]);
+ gl::Error error = TextureD3D::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, unpack, pixels, mImageArray[index.layerIndex][level]);
if (error.isError())
{
return error;
@@ -1758,14 +1781,14 @@
gl::Error TextureD3D_3D::setCompressedImage(GLenum target, GLint level, GLenum format,
GLsizei width, GLsizei height,GLsizei depth,
- GLsizei imageSize, const void *pixels)
+ GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(target == GL_TEXTURE_3D);
// compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
redefineImage(level, format, width, height, depth);
- return TextureD3D::setCompressedImage(imageSize, pixels, mImageArray[level]);
+ return TextureD3D::setCompressedImage(unpack, imageSize, pixels, mImageArray[level]);
}
gl::Error TextureD3D_3D::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
@@ -1812,12 +1835,12 @@
gl::Error TextureD3D_3D::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth, GLenum format,
- GLsizei imageSize, const void *pixels)
+ GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(target == GL_TEXTURE_3D);
gl::Error error = TextureD3D::subImageCompressed(xoffset, yoffset, zoffset, width, height, depth,
- format, imageSize, pixels, mImageArray[level]);
+ format, imageSize, unpack, pixels, mImageArray[level]);
if (error.isError())
{
return error;
@@ -2279,7 +2302,7 @@
gl::Error TextureD3D_2DArray::setCompressedImage(GLenum target, GLint level, GLenum format,
GLsizei width, GLsizei height, GLsizei depth,
- GLsizei imageSize, const void *pixels)
+ GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(target == GL_TEXTURE_2D_ARRAY);
@@ -2292,7 +2315,7 @@
for (int i = 0; i < depth; i++)
{
const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
- gl::Error error = TextureD3D::setCompressedImage(imageSize, layerPixels, mImageArray[level][i]);
+ gl::Error error = TextureD3D::setCompressedImage(unpack, imageSize, layerPixels, mImageArray[level][i]);
if (error.isError())
{
return error;
@@ -2330,7 +2353,7 @@
gl::Error TextureD3D_2DArray::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth, GLenum format,
- GLsizei imageSize, const void *pixels)
+ GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(target == GL_TEXTURE_2D_ARRAY);
@@ -2342,7 +2365,7 @@
int layer = zoffset + i;
const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
- gl::Error error = TextureD3D::subImageCompressed(xoffset, yoffset, zoffset, width, height, 1, format, imageSize, layerPixels, mImageArray[level][layer]);
+ gl::Error error = TextureD3D::subImageCompressed(xoffset, yoffset, zoffset, width, height, 1, format, imageSize, unpack, layerPixels, mImageArray[level][layer]);
if (error.isError())
{
return error;