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
parent 7051b97e
......@@ -181,6 +181,9 @@ struct State
GLuint samplerTexture[SAMPLER_TYPE_COUNT][MAX_TEXTURE_IMAGE_UNITS];
unsigned int startIndex;
GLint unpackAlignment;
GLint packAlignment;
};
class Context : public State
......
......@@ -130,6 +130,9 @@ Context::Context(const egl::Config *config)
currentProgram = 0;
packAlignment = 4;
unpackAlignment = 4;
mBufferBackEnd = NULL;
mVertexDataManager = NULL;
......@@ -1741,7 +1744,7 @@ Texture *Context::getIncompleteTexture(SamplerType type)
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 @@ Texture *Context::getIncompleteTexture(SamplerType type)
{
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;
}
......
......@@ -163,12 +163,20 @@ int Texture::imagePitch(const Image &img) const
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::loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei
}
}
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 @@ void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type
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 @@ void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type
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 @@ void Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei heig
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 @@ GLenum Texture2D::getTarget() const
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::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei wi
}
}
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 @@ GLenum TextureCubeMap::getTarget() const
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::commitRect(GLenum faceTarget, GLint level, GLint xoffset, G
}
}
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 @@ IDirect3DSurface9 *TextureCubeMap::getSurface(GLenum target)
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)
{
......
......@@ -79,8 +79,8 @@ class Texture : public Colorbuffer
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 @@ class Texture : public Colorbuffer
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 @@ class Texture2D : public Texture
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 @@ class TextureCubeMap : public Texture
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 @@ class TextureCubeMap : public Texture
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];
......
......@@ -1795,6 +1795,8 @@ void __stdcall glGetIntegerv(GLenum pname, GLint* params)
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 @@ void __stdcall glPixelStorei(GLenum pname, GLint param)
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 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
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 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
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 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
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 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
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
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment