Implement glPixelStorei for Tex(Sub)Image2D.
TRAC #11475
Author: Andrew Lewycky
Signed-off-by: Nicolas Capens
Signed-off-by: Daniel Koch
git-svn-id: https://angleproject.googlecode.com/svn/trunk@55 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/include/Context.h b/src/include/Context.h
index 1a1eec8..51a285f 100644
--- a/src/include/Context.h
+++ b/src/include/Context.h
@@ -181,6 +181,9 @@
GLuint samplerTexture[SAMPLER_TYPE_COUNT][MAX_TEXTURE_IMAGE_UNITS];
unsigned int startIndex;
+
+ GLint unpackAlignment;
+ GLint packAlignment;
};
class Context : public State
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index dc1e0a4..46a58e3 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -130,6 +130,9 @@
currentProgram = 0;
+ packAlignment = 4;
+ unpackAlignment = 4;
+
mBufferBackEnd = NULL;
mVertexDataManager = NULL;
@@ -1741,7 +1744,7 @@
case SAMPLER_2D:
{
Texture2D *incomplete2d = new Texture2D;
- incomplete2d->setImage(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, color);
+ incomplete2d->setImage(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
t = incomplete2d;
}
break;
@@ -1750,12 +1753,12 @@
{
TextureCubeMap *incompleteCube = new TextureCubeMap;
- incompleteCube->setImagePosX(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, color);
- incompleteCube->setImageNegX(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, color);
- incompleteCube->setImagePosY(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, color);
- incompleteCube->setImageNegY(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, color);
- incompleteCube->setImagePosZ(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, color);
- incompleteCube->setImageNegZ(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, color);
+ incompleteCube->setImagePosX(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
+ incompleteCube->setImageNegX(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
+ incompleteCube->setImagePosY(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
+ incompleteCube->setImageNegY(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
+ incompleteCube->setImagePosZ(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
+ incompleteCube->setImageNegZ(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
t = incompleteCube;
}
diff --git a/src/libGLESv2/Texture.cpp b/src/libGLESv2/Texture.cpp
index 9ee9ddc..1012079 100644
--- a/src/libGLESv2/Texture.cpp
+++ b/src/libGLESv2/Texture.cpp
@@ -163,12 +163,20 @@
return img.width * 4;
}
+GLsizei Texture::computePitch(GLsizei width, GLenum format, GLenum type, GLint alignment) const
+{
+ ASSERT(alignment > 0 && isPow2(alignment));
+
+ GLsizei rawPitch = pixelSize(format, type) * width;
+ return (rawPitch + alignment - 1) & ~(alignment - 1);
+}
+
// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input
// into the BGRA8 pixel rectangle at output with outputPitch bytes in between each line.
void Texture::loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type,
- const void *input, size_t outputPitch, void *output) const
+ GLint unpackAlignment, const void *input, size_t outputPitch, void *output) const
{
- size_t inputPitch = width * pixelSize(format, type);
+ GLsizei inputPitch = computePitch(width, format, type, unpackAlignment);
for (int y = 0; y < height; y++)
{
@@ -277,7 +285,7 @@
}
}
-void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels, Image *img)
+void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img)
{
IDirect3DSurface9 *newSurface = NULL;
HRESULT result = getDevice()->CreateOffscreenPlainSurface(width, height, selectFormat(format), D3DPOOL_SYSTEMMEM, &newSurface, NULL);
@@ -304,7 +312,7 @@
if (SUCCEEDED(result))
{
- loadImageData(0, 0, width, height, format, type, pixels, locked.Pitch, locked.pBits);
+ loadImageData(0, 0, width, height, format, type, unpackAlignment, pixels, locked.Pitch, locked.pBits);
newSurface->UnlockRect();
}
@@ -314,7 +322,7 @@
mDirtyMetaData = true;
}
-void Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels, Image *img)
+void Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img)
{
if (width + xoffset > img->width || height + yoffset > img->height) return error(GL_INVALID_VALUE);
@@ -325,7 +333,7 @@
if (SUCCEEDED(result))
{
- loadImageData(xoffset, yoffset, width, height, format, type, pixels, locked.Pitch, locked.pBits);
+ loadImageData(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, locked.Pitch, locked.pBits);
img->surface->UnlockRect();
}
@@ -399,9 +407,9 @@
return GL_TEXTURE_2D;
}
-void Texture2D::setImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)
+void Texture2D::setImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
{
- Texture::setImage(width, height, format, type, pixels, &mImageArray[level]);
+ Texture::setImage(width, height, format, type, unpackAlignment, pixels, &mImageArray[level]);
if (level == 0)
{
@@ -445,9 +453,9 @@
}
}
-void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)
+void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
{
- Texture::subImage(xoffset, yoffset, width, height, format, type, pixels, &mImageArray[level]);
+ Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, &mImageArray[level]);
commitRect(level, xoffset, yoffset, width, height);
}
@@ -665,34 +673,34 @@
return GL_TEXTURE_CUBE_MAP;
}
-void TextureCubeMap::setImagePosX(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)
+void TextureCubeMap::setImagePosX(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
{
- setImage(0, level, internalFormat, width, height, format, type, pixels);
+ setImage(0, level, internalFormat, width, height, format, type, unpackAlignment, pixels);
}
-void TextureCubeMap::setImageNegX(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)
+void TextureCubeMap::setImageNegX(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
{
- setImage(1, level, internalFormat, width, height, format, type, pixels);
+ setImage(1, level, internalFormat, width, height, format, type, unpackAlignment, pixels);
}
-void TextureCubeMap::setImagePosY(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)
+void TextureCubeMap::setImagePosY(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
{
- setImage(2, level, internalFormat, width, height, format, type, pixels);
+ setImage(2, level, internalFormat, width, height, format, type, unpackAlignment, pixels);
}
-void TextureCubeMap::setImageNegY(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)
+void TextureCubeMap::setImageNegY(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
{
- setImage(3, level, internalFormat, width, height, format, type, pixels);
+ setImage(3, level, internalFormat, width, height, format, type, unpackAlignment, pixels);
}
-void TextureCubeMap::setImagePosZ(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)
+void TextureCubeMap::setImagePosZ(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
{
- setImage(4, level, internalFormat, width, height, format, type, pixels);
+ setImage(4, level, internalFormat, width, height, format, type, unpackAlignment, pixels);
}
-void TextureCubeMap::setImageNegZ(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)
+void TextureCubeMap::setImageNegZ(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
{
- setImage(5, level, internalFormat, width, height, format, type, pixels);
+ setImage(5, level, internalFormat, width, height, format, type, unpackAlignment, pixels);
}
void TextureCubeMap::commitRect(GLenum faceTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
@@ -732,9 +740,9 @@
}
}
-void TextureCubeMap::subImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)
+void TextureCubeMap::subImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
{
- Texture::subImage(xoffset, yoffset, width, height, format, type, pixels, &mImageArray[faceIndex(face)][level]);
+ Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, &mImageArray[faceIndex(face)][level]);
commitRect(face, level, xoffset, yoffset, width, height);
}
@@ -932,9 +940,9 @@
return surface;
}
-void TextureCubeMap::setImage(int face, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)
+void TextureCubeMap::setImage(int face, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
{
- Texture::setImage(width, height, format, type, pixels, &mImageArray[face][level]);
+ Texture::setImage(width, height, format, type, unpackAlignment, pixels, &mImageArray[face][level]);
if (face == 0 && level == 0)
{
diff --git a/src/libGLESv2/Texture.h b/src/libGLESv2/Texture.h
index 08aa0f3..2dd3cbe 100644
--- a/src/libGLESv2/Texture.h
+++ b/src/libGLESv2/Texture.h
@@ -79,8 +79,8 @@
GLenum mWrapS;
GLenum mWrapT;
- void setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels, Image *img);
- void subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels, Image *img);
+ void setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img);
+ void subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img);
// The pointer returned is weak and it is assumed the derived class will keep a strong pointer until the next createTexture() call.
virtual IDirect3DBaseTexture9 *createTexture() = 0;
@@ -98,7 +98,9 @@
bool mDirtyMetaData;
void loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type,
- const void *input, std::size_t outputPitch, void *output) const;
+ GLint unpackAlignment, const void *input, std::size_t outputPitch, void *output) const;
+
+ GLsizei computePitch(GLsizei width, GLenum format, GLenum type, GLint alignment) const;
};
class Texture2D : public Texture
@@ -110,8 +112,8 @@
GLenum getTarget() const;
- void setImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
- void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
+ void setImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
+ void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
bool isComplete() const;
@@ -141,14 +143,14 @@
GLenum getTarget() const;
- void setImagePosX(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
- void setImageNegX(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
- void setImagePosY(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
- void setImageNegY(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
- void setImagePosZ(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
- void setImageNegZ(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
+ void setImagePosX(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
+ void setImageNegX(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
+ void setImagePosY(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
+ void setImageNegY(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
+ void setImagePosZ(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
+ void setImageNegZ(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
- void subImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
+ void subImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
bool isComplete() const;
@@ -164,7 +166,7 @@
static unsigned int faceIndex(GLenum face);
- void setImage(int face, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
+ void setImage(int face, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
void commitRect(GLenum faceTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
Image mImageArray[6][MAX_TEXTURE_LEVELS];
diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp
index 444c707..26e347e 100644
--- a/src/libGLESv2/libGLESv2.cpp
+++ b/src/libGLESv2/libGLESv2.cpp
@@ -1795,6 +1795,8 @@
case GL_FRAMEBUFFER_BINDING: *params = context->framebuffer; break;
case GL_RENDERBUFFER_BINDING: *params = context->renderbuffer; break;
case GL_CURRENT_PROGRAM: *params = context->currentProgram; break;
+ case GL_PACK_ALIGNMENT: *params = context->packAlignment; break;
+ case GL_UNPACK_ALIGNMENT: *params = context->unpackAlignment; break;
case GL_RED_BITS:
case GL_GREEN_BITS:
case GL_BLUE_BITS:
@@ -2498,16 +2500,33 @@
try
{
- switch (pname)
+ gl::Context *context = gl::getContext();
+
+ if (context)
{
- case GL_UNPACK_ALIGNMENT:
- // UNIMPLEMENTED(); // FIXME
- break;
- case GL_PACK_ALIGNMENT:
- // UNIMPLEMENTED(); // FIXME
- break;
- default:
- return error(GL_INVALID_ENUM);
+ switch (pname)
+ {
+ case GL_UNPACK_ALIGNMENT:
+ if (param != 1 && param != 2 && param != 4 && param != 8)
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ context->unpackAlignment = param;
+ break;
+
+ case GL_PACK_ALIGNMENT:
+ if (param != 1 && param != 2 && param != 4 && param != 8)
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ context->packAlignment = param;
+ break;
+
+ default:
+ return error(GL_INVALID_ENUM);
+ }
}
}
catch(std::bad_alloc&)
@@ -3057,7 +3076,7 @@
return error(GL_INVALID_OPERATION);
}
- texture->setImage(level, internalformat, width, height, format, type, pixels);
+ texture->setImage(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
}
else
{
@@ -3071,22 +3090,22 @@
switch (target)
{
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- texture->setImagePosX(level, internalformat, width, height, format, type, pixels);
+ texture->setImagePosX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- texture->setImageNegX(level, internalformat, width, height, format, type, pixels);
+ texture->setImageNegX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- texture->setImagePosY(level, internalformat, width, height, format, type, pixels);
+ texture->setImagePosY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- texture->setImageNegY(level, internalformat, width, height, format, type, pixels);
+ texture->setImageNegY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- texture->setImagePosZ(level, internalformat, width, height, format, type, pixels);
+ texture->setImagePosZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- texture->setImageNegZ(level, internalformat, width, height, format, type, pixels);
+ texture->setImageNegZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
break;
default: UNREACHABLE();
}
@@ -3220,7 +3239,7 @@
return error(GL_INVALID_OPERATION);
}
- texture->subImage(level, xoffset, yoffset, width, height, format, type, pixels);
+ texture->subImage(level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
}
else if (es2dx::IsCubemapTextureTarget(target))
{
@@ -3231,7 +3250,7 @@
return error(GL_INVALID_OPERATION);
}
- texture->subImage(target, level, xoffset, yoffset, width, height, format, type, pixels);
+ texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
}
else
{