aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJamie Madill <jmadill@chromium.org>2014-10-21 17:46:29 -0400
committerJamie Madill <jmadill@chromium.org>2014-10-27 15:42:58 +0000
commitc751d1e574bdd477eaa2fc1bcb4e040990fb2f72 (patch)
tree467408595c62384e68182af1471e3e15447a117c
parent55d611e780b115e29fdb552bb1f4bbebb3ab8b7a (diff)
downloadangle-c751d1e574bdd477eaa2fc1bcb4e040990fb2f72.tar.gz
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>
-rw-r--r--src/libGLESv2/Texture.cpp32
-rw-r--r--src/libGLESv2/Texture.h16
-rw-r--r--src/libGLESv2/libGLESv2.cpp16
-rw-r--r--src/libGLESv2/renderer/TextureImpl.h4
-rw-r--r--src/libGLESv2/renderer/d3d/TextureD3D.cpp131
-rw-r--r--src/libGLESv2/renderer/d3d/TextureD3D.h20
-rw-r--r--src/libGLESv2/validationES3.cpp16
-rw-r--r--tests/angle_tests/CompressedTextureTest.cpp137
8 files changed, 268 insertions, 104 deletions
diff --git a/src/libGLESv2/Texture.cpp b/src/libGLESv2/Texture.cpp
index deeeeaec..08b07c8a 100644
--- a/src/libGLESv2/Texture.cpp
+++ b/src/libGLESv2/Texture.cpp
@@ -248,11 +248,11 @@ void Texture2D::releaseTexImage()
}
Error Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize,
- const void *pixels)
+ const PixelUnpackState &unpack, const void *pixels)
{
releaseTexImage();
- return mTexture->setCompressedImage(GL_TEXTURE_2D, level, format, width, height, 1, imageSize, pixels);
+ return mTexture->setCompressedImage(GL_TEXTURE_2D, level, format, width, height, 1, imageSize, unpack, pixels);
}
Error Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
@@ -261,9 +261,9 @@ Error Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei wid
}
Error Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
- GLenum format, GLsizei imageSize, const void *pixels)
+ GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
{
- return mTexture->subImageCompressed(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels);
+ return mTexture->subImageCompressed(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, unpack, pixels);
}
Error Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height,
@@ -475,9 +475,9 @@ Error TextureCubeMap::setImage(GLenum target, GLint level, GLsizei width, GLsize
}
Error TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height,
- GLsizei imageSize, const void *pixels)
+ GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
{
- return mTexture->setCompressedImage(target, level, format, width, height, 1, imageSize, pixels);
+ return mTexture->setCompressedImage(target, level, format, width, height, 1, imageSize, unpack, pixels);
}
Error TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
@@ -487,9 +487,9 @@ Error TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint
Error TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height, GLenum format,
- GLsizei imageSize, const void *pixels)
+ GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
{
- return mTexture->subImageCompressed(target, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels);
+ return mTexture->subImageCompressed(target, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, unpack, pixels);
}
// Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
@@ -727,9 +727,9 @@ Error Texture3D::setImage(GLint level, GLsizei width, GLsizei height, GLsizei de
}
Error Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth,
- GLsizei imageSize, const void *pixels)
+ GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
{
- return mTexture->setCompressedImage(GL_TEXTURE_3D, level, format, width, height, depth, imageSize, pixels);
+ return mTexture->setCompressedImage(GL_TEXTURE_3D, level, format, width, height, depth, imageSize, unpack, pixels);
}
Error Texture3D::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
@@ -739,9 +739,9 @@ Error Texture3D::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffs
Error Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth, GLenum format,
- GLsizei imageSize, const void *pixels)
+ GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
{
- return mTexture->subImageCompressed(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels);
+ return mTexture->subImageCompressed(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, unpack, pixels);
}
Error Texture3D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
@@ -894,9 +894,9 @@ Error Texture2DArray::setImage(GLint level, GLsizei width, GLsizei height, GLsiz
}
Error Texture2DArray::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth,
- GLsizei imageSize, const void *pixels)
+ GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
{
- return mTexture->setCompressedImage(GL_TEXTURE_2D_ARRAY, level, format, width, height, depth, imageSize, pixels);
+ return mTexture->setCompressedImage(GL_TEXTURE_2D_ARRAY, level, format, width, height, depth, imageSize, unpack, pixels);
}
Error Texture2DArray::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
@@ -906,9 +906,9 @@ Error Texture2DArray::subImage(GLint level, GLint xoffset, GLint yoffset, GLint
Error Texture2DArray::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth, GLenum format,
- GLsizei imageSize, const void *pixels)
+ GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
{
- return mTexture->subImageCompressed(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels);
+ return mTexture->subImageCompressed(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, unpack, pixels);
}
Error Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
diff --git a/src/libGLESv2/Texture.h b/src/libGLESv2/Texture.h
index a3c7c2c3..2e80be3c 100644
--- a/src/libGLESv2/Texture.h
+++ b/src/libGLESv2/Texture.h
@@ -119,9 +119,9 @@ class Texture2D : public Texture
bool isDepth(GLint level) const;
Error setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- Error setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
+ Error setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
Error subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- Error subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
+ Error subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
Error copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
Error storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
@@ -155,9 +155,9 @@ class TextureCubeMap : public Texture
bool isDepth(GLenum target, GLint level) const;
Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
+ Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
+ Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
Error storage(GLsizei levels, GLenum internalformat, GLsizei size);
@@ -191,9 +191,9 @@ class Texture3D : public Texture
bool isDepth(GLint level) const;
Error setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- Error setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
+ Error setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
Error subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- Error subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
+ Error subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
Error storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
@@ -221,9 +221,9 @@ class Texture2DArray : public Texture
bool isDepth(GLint level) const;
Error setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- Error setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
+ Error setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
Error subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- Error subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
+ Error subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
Error storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp
index 64503fcb..0b6f22d0 100644
--- a/src/libGLESv2/libGLESv2.cpp
+++ b/src/libGLESv2/libGLESv2.cpp
@@ -766,7 +766,7 @@ void GL_APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum inter
case GL_TEXTURE_2D:
{
gl::Texture2D *texture = context->getTexture2D();
- gl::Error error = texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
+ gl::Error error = texture->setCompressedImage(level, internalformat, width, height, imageSize, context->getState().getUnpackState(), data);
if (error.isError())
{
context->recordError(error);
@@ -783,7 +783,7 @@ void GL_APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum inter
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
{
gl::TextureCubeMap *texture = context->getTextureCubeMap();
- gl::Error error = texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
+ gl::Error error = texture->setCompressedImage(target, level, internalformat, width, height, imageSize, context->getState().getUnpackState(), data);
if (error.isError())
{
context->recordError(error);
@@ -836,7 +836,7 @@ void GL_APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xof
case GL_TEXTURE_2D:
{
gl::Texture2D *texture = context->getTexture2D();
- gl::Error error = texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
+ gl::Error error = texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, context->getState().getUnpackState(), data);
if (error.isError())
{
context->recordError(error);
@@ -853,7 +853,7 @@ void GL_APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xof
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
{
gl::TextureCubeMap *texture = context->getTextureCubeMap();
- gl::Error error = texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
+ gl::Error error = texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, context->getState().getUnpackState(), data);
if (error.isError())
{
context->recordError(error);
@@ -5285,7 +5285,7 @@ void GL_APIENTRY glCompressedTexImage3D(GLenum target, GLint level, GLenum inter
case GL_TEXTURE_3D:
{
gl::Texture3D *texture = context->getTexture3D();
- gl::Error error = texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);
+ gl::Error error = texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, context->getState().getUnpackState(), data);
if (error.isError())
{
context->recordError(error);
@@ -5297,7 +5297,7 @@ void GL_APIENTRY glCompressedTexImage3D(GLenum target, GLint level, GLenum inter
case GL_TEXTURE_2D_ARRAY:
{
gl::Texture2DArray *texture = context->getTexture2DArray();
- gl::Error error = texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);
+ gl::Error error = texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, context->getState().getUnpackState(), data);
if (error.isError())
{
context->recordError(error);
@@ -5361,7 +5361,7 @@ void GL_APIENTRY glCompressedTexSubImage3D(GLenum target, GLint level, GLint xof
{
gl::Texture3D *texture = context->getTexture3D();
gl::Error error = texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth,
- format, imageSize, data);
+ format, imageSize, context->getState().getUnpackState(), data);
if (error.isError())
{
context->recordError(error);
@@ -5374,7 +5374,7 @@ void GL_APIENTRY glCompressedTexSubImage3D(GLenum target, GLint level, GLint xof
{
gl::Texture2DArray *texture = context->getTexture2DArray();
gl::Error error = texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth,
- format, imageSize, data);
+ format, imageSize, context->getState().getUnpackState(), data);
if (error.isError())
{
context->recordError(error);
diff --git a/src/libGLESv2/renderer/TextureImpl.h b/src/libGLESv2/renderer/TextureImpl.h
index 6a89d818..ef47582c 100644
--- a/src/libGLESv2/renderer/TextureImpl.h
+++ b/src/libGLESv2/renderer/TextureImpl.h
@@ -48,9 +48,9 @@ class TextureImpl
virtual void setUsage(GLenum usage) = 0;
virtual gl::Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0;
- virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) = 0;
+ virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels) = 0;
virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0;
- virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) = 0;
+ virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels) = 0;
virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0;
virtual gl::Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0;
virtual gl::Error storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) = 0;
diff --git a/src/libGLESv2/renderer/d3d/TextureD3D.cpp b/src/libGLESv2/renderer/d3d/TextureD3D.cpp
index 42fea657..51593b3f 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 @@ gl::Error TextureD3D::setImage(const gl::PixelUnpackState &unpack, GLenum type,
// 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)
- {
- // 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
+ gl::Error error = GetUnpackPointer(unpack, pixels, &pixelData);
+ if (error.isError())
{
- pixelData = static_cast<const uint8_t *>(pixels);
+ return error;
}
if (pixelData != NULL)
@@ -172,22 +189,12 @@ gl::Error TextureD3D::setImage(const gl::PixelUnpackState &unpack, GLenum type,
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 @@ gl::Error TextureD3D::subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsi
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())
+ {
+ return error;
+ }
+
+ if (pixelData != NULL)
{
- gl::Error error = image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth(), pixels);
+ 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::setCompressedImage(GLsizei imageSize, const void *pixels,
}
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())
+ {
+ return error;
+ }
+
+ if (pixelData != NULL)
{
- gl::Error error = image->loadCompressedData(xoffset, yoffset, zoffset, width, height, depth, pixels);
+ 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::setImage(GLenum target, GLint level, GLsizei width, GLs
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::subImage(GLenum target, GLint level, GLint xoffset, GLi
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::setImage(GLenum target, GLint level, GLsizei width, G
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 @@ gl::Error TextureD3D_Cube::setCompressedImage(GLenum target, GLint level, GLenum
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::subImage(GLenum target, GLint level, GLint xoffset, G
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::setImage(GLenum target, GLint level, GLsizei width, GLs
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::subImage(GLenum target, GLint level, GLint xoffset, GLi
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::setImage(GLenum target, GLint level, GLsizei width
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 @@ gl::Error TextureD3D_2DArray::setCompressedImage(GLenum target, GLint level, GLe
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::subImage(GLenum target, GLint level, GLint xoffset
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 @@ gl::Error TextureD3D_2DArray::subImageCompressed(GLenum target, GLint level, GLi
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;
diff --git a/src/libGLESv2/renderer/d3d/TextureD3D.h b/src/libGLESv2/renderer/d3d/TextureD3D.h
index 8635b20b..67e84f48 100644
--- a/src/libGLESv2/renderer/d3d/TextureD3D.h
+++ b/src/libGLESv2/renderer/d3d/TextureD3D.h
@@ -67,9 +67,9 @@ class TextureD3D : public TextureImpl
gl::Error setImage(const gl::PixelUnpackState &unpack, GLenum type, const void *pixels, const gl::ImageIndex &index);
gl::Error 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);
- gl::Error setCompressedImage(GLsizei imageSize, const void *pixels, Image *image);
+ gl::Error setCompressedImage(const gl::PixelUnpackState &unpack, GLsizei imageSize, const void *pixels, Image *image);
gl::Error 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);
bool isFastUnpackable(const gl::PixelUnpackState &unpack, GLenum sizedInternalFormat);
gl::Error fastUnpackPixels(const gl::PixelUnpackState &unpack, const void *pixels, const gl::Box &destArea,
GLenum sizedInternalFormat, GLenum type, RenderTarget *destRenderTarget);
@@ -123,9 +123,9 @@ class TextureD3D_2D : public TextureD3D
bool isDepth(GLint level) const;
virtual gl::Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
+ virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
+ virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
virtual gl::Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
virtual gl::Error storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
@@ -179,9 +179,9 @@ class TextureD3D_Cube : public TextureD3D
bool isDepth(GLint level, GLint layer) const;
virtual gl::Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
+ virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
+ virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
virtual gl::Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
virtual gl::Error storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
@@ -234,9 +234,9 @@ class TextureD3D_3D : public TextureD3D
bool isDepth(GLint level) const;
virtual gl::Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
+ virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
+ virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
virtual gl::Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
virtual gl::Error storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
@@ -287,9 +287,9 @@ class TextureD3D_2DArray : public TextureD3D
bool isDepth(GLint level) const;
virtual gl::Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
+ virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
+ virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
virtual gl::Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
virtual gl::Error storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
diff --git a/src/libGLESv2/validationES3.cpp b/src/libGLESv2/validationES3.cpp
index 251c6ad2..4b305db7 100644
--- a/src/libGLESv2/validationES3.cpp
+++ b/src/libGLESv2/validationES3.cpp
@@ -542,7 +542,8 @@ bool ValidateES3TexImageParameters(Context *context, GLenum target, GLint level,
return false;
}
- size_t copyBytes = widthSize * heightSize * depthSize * pixelBytes;
+ const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(sizedFormat);
+ size_t copyBytes = formatInfo.computeBlockSize(type, width, height);
size_t offset = reinterpret_cast<size_t>(pixels);
if (!rx::IsUnsignedAdditionSafe(offset, copyBytes) ||
@@ -555,12 +556,15 @@ bool ValidateES3TexImageParameters(Context *context, GLenum target, GLint level,
// ...data is not evenly divisible into the number of bytes needed to store in memory a datum
// indicated by type.
- size_t dataBytesPerPixel = static_cast<size_t>(gl::GetTypeInfo(type).bytes);
-
- if ((offset % dataBytesPerPixel) != 0)
+ if (!isCompressed)
{
- context->recordError(Error(GL_INVALID_OPERATION));
- return false;
+ size_t dataBytesPerPixel = static_cast<size_t>(gl::GetTypeInfo(type).bytes);
+
+ if ((offset % dataBytesPerPixel) != 0)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
+ }
}
// ...the buffer object's data store is currently mapped.
diff --git a/tests/angle_tests/CompressedTextureTest.cpp b/tests/angle_tests/CompressedTextureTest.cpp
index 9b07e6cf..53e697ab 100644
--- a/tests/angle_tests/CompressedTextureTest.cpp
+++ b/tests/angle_tests/CompressedTextureTest.cpp
@@ -165,3 +165,140 @@ TYPED_TEST(CompressedTextureTest, CompressedTexStorage)
EXPECT_GL_NO_ERROR();
}
+
+// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
+typedef ::testing::Types<TFT<Gles::Three, Rend::D3D11>> TestFixtureTypesES3;
+TYPED_TEST_CASE(CompressedTextureTestES3, TestFixtureTypesES3);
+
+template<typename T>
+class CompressedTextureTestES3 : public CompressedTextureTest<T> { };
+
+typedef ::testing::Types<TFT<Gles::Two, Rend::D3D11>, TFT<Gles::Three, Rend::D3D11>> TestFixtureTypesD3D11;
+TYPED_TEST_CASE(CompressedTextureTestD3D11, TestFixtureTypesD3D11);
+
+template<typename T>
+class CompressedTextureTestD3D11 : public CompressedTextureTest<T> { };
+
+TYPED_TEST(CompressedTextureTestES3, PBOCompressedTexImage)
+{
+ GLuint texture;
+ glGenTextures(1, &texture);
+ glBindTexture(GL_TEXTURE_2D, texture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ GLuint buffer;
+ glGenBuffers(1, &buffer);
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
+ glBufferData(GL_PIXEL_UNPACK_BUFFER, pixel_0_size, NULL, GL_STREAM_DRAW);
+ EXPECT_GL_NO_ERROR();
+
+ glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_0_size, pixel_0_data);
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width, pixel_0_height, 0, pixel_0_size, NULL);
+ glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_1_size, pixel_1_data);
+ glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_1_width, pixel_1_height, 0, pixel_1_size, NULL);
+ glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_2_size, pixel_2_data);
+ glCompressedTexImage2D(GL_TEXTURE_2D, 2, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_2_width, pixel_2_height, 0, pixel_2_size, NULL);
+ glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_3_size, pixel_3_data);
+ glCompressedTexImage2D(GL_TEXTURE_2D, 3, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_3_width, pixel_3_height, 0, pixel_3_size, NULL);
+ glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_4_size, pixel_4_data);
+ glCompressedTexImage2D(GL_TEXTURE_2D, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_4_width, pixel_4_height, 0, pixel_4_size, NULL);
+ glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_5_size, pixel_5_data);
+ glCompressedTexImage2D(GL_TEXTURE_2D, 5, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_5_width, pixel_5_height, 0, pixel_5_size, NULL);
+ glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_6_size, pixel_6_data);
+ glCompressedTexImage2D(GL_TEXTURE_2D, 6, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_6_width, pixel_6_height, 0, pixel_6_size, NULL);
+ glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_7_size, pixel_7_data);
+ glCompressedTexImage2D(GL_TEXTURE_2D, 7, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_7_width, pixel_7_height, 0, pixel_7_size, NULL);
+ glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_8_size, pixel_8_data);
+ glCompressedTexImage2D(GL_TEXTURE_2D, 8, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_8_width, pixel_8_height, 0, pixel_8_size, NULL);
+ glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_9_size, pixel_9_data);
+ glCompressedTexImage2D(GL_TEXTURE_2D, 9, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_9_width, pixel_9_height, 0, pixel_9_size, NULL);
+
+ EXPECT_GL_NO_ERROR();
+
+ glUseProgram(mTextureProgram);
+ glUniform1i(mTextureUniformLocation, 0);
+
+ drawQuad(mTextureProgram, "position", 0.5f);
+
+ EXPECT_GL_NO_ERROR();
+
+ glDeleteTextures(1, &buffer);
+ glDeleteTextures(1, &texture);
+
+ EXPECT_GL_NO_ERROR();
+}
+
+
+TYPED_TEST(CompressedTextureTestD3D11, PBOCompressedTexStorage)
+{
+ if (getClientVersion() < 3 && !extensionEnabled("GL_EXT_texture_compression_dxt1"))
+ {
+ return;
+ }
+
+ if (getClientVersion() < 3 && (!extensionEnabled("GL_EXT_texture_storage") || !extensionEnabled("GL_OES_rgb8_rgba8")))
+ {
+ return;
+ }
+
+ GLuint texture;
+ glGenTextures(1, &texture);
+ glBindTexture(GL_TEXTURE_2D, texture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ if (getClientVersion() < 3)
+ {
+ glTexStorage2DEXT(GL_TEXTURE_2D, pixel_levels, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width, pixel_0_height);
+ }
+ else
+ {
+ glTexStorage2D(GL_TEXTURE_2D, pixel_levels, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width, pixel_0_height);
+ }
+ EXPECT_GL_NO_ERROR();
+
+ GLuint buffer;
+ glGenBuffers(1, &buffer);
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
+ glBufferData(GL_PIXEL_UNPACK_BUFFER, pixel_0_size, NULL, GL_STREAM_DRAW);
+ EXPECT_GL_NO_ERROR();
+
+ glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_0_size, pixel_0_data);
+ glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pixel_0_width, pixel_0_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_size, NULL);
+ glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_1_size, pixel_1_data);
+ glCompressedTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, pixel_1_width, pixel_1_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_1_size, NULL);
+ glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_2_size, pixel_2_data);
+ glCompressedTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, pixel_2_width, pixel_2_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_2_size, NULL);
+ glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_3_size, pixel_3_data);
+ glCompressedTexSubImage2D(GL_TEXTURE_2D, 3, 0, 0, pixel_3_width, pixel_3_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_3_size, NULL);
+ glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_4_size, pixel_4_data);
+ glCompressedTexSubImage2D(GL_TEXTURE_2D, 4, 0, 0, pixel_4_width, pixel_4_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_4_size, NULL);
+ glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_5_size, pixel_5_data);
+ glCompressedTexSubImage2D(GL_TEXTURE_2D, 5, 0, 0, pixel_5_width, pixel_5_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_5_size, NULL);
+ glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_6_size, pixel_6_data);
+ glCompressedTexSubImage2D(GL_TEXTURE_2D, 6, 0, 0, pixel_6_width, pixel_6_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_6_size, NULL);
+ glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_7_size, pixel_7_data);
+ glCompressedTexSubImage2D(GL_TEXTURE_2D, 7, 0, 0, pixel_7_width, pixel_7_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_7_size, NULL);
+ glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_8_size, pixel_8_data);
+ glCompressedTexSubImage2D(GL_TEXTURE_2D, 8, 0, 0, pixel_8_width, pixel_8_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_8_size, NULL);
+ glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_9_size, pixel_9_data);
+ glCompressedTexSubImage2D(GL_TEXTURE_2D, 9, 0, 0, pixel_9_width, pixel_9_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_9_size, NULL);
+
+ EXPECT_GL_NO_ERROR();
+
+ glUseProgram(mTextureProgram);
+ glUniform1i(mTextureUniformLocation, 0);
+
+ drawQuad(mTextureProgram, "position", 0.5f);
+
+ EXPECT_GL_NO_ERROR();
+
+ glDeleteTextures(1, &texture);
+
+ EXPECT_GL_NO_ERROR();
+}