Tracks sized internal formats for textures.

TRAC #21609 Signed-off-by: Daniel Koch Author: Shannon Woods <shannon.woods@transgaming.com> git-svn-id: https://angleproject.googlecode.com/svn/trunk@1301 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent c60c15c0
...@@ -2507,7 +2507,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, ...@@ -2507,7 +2507,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
GLsizei outputPitch = ComputePitch(width, format, type, mState.packAlignment); GLsizei outputPitch = ComputePitch(width, ConvertSizedInternalFormat(format, type), mState.packAlignment);
// sized query sanity check // sized query sanity check
if (bufSize) if (bufSize)
{ {
......
...@@ -301,13 +301,14 @@ GLenum Framebuffer::completeness() ...@@ -301,13 +301,14 @@ GLenum Framebuffer::completeness()
} }
else if (IsInternalTextureTarget(mColorbufferType)) else if (IsInternalTextureTarget(mColorbufferType))
{ {
GLenum internalformat = colorbuffer->getInternalFormat(); GLint internalformat = colorbuffer->getInternalFormat();
GLenum format = gl::ExtractFormat(internalformat);
D3DFORMAT d3dformat = colorbuffer->getD3DFormat(); D3DFORMAT d3dformat = colorbuffer->getD3DFormat();
if (IsCompressed(internalformat) || if (IsCompressed(format) ||
internalformat == GL_ALPHA || format == GL_ALPHA ||
internalformat == GL_LUMINANCE || format == GL_LUMINANCE ||
internalformat == GL_LUMINANCE_ALPHA) format == GL_LUMINANCE_ALPHA)
{ {
return GL_FRAMEBUFFER_UNSUPPORTED; return GL_FRAMEBUFFER_UNSUPPORTED;
} }
......
...@@ -28,52 +28,50 @@ namespace gl ...@@ -28,52 +28,50 @@ namespace gl
{ {
unsigned int TextureStorage::mCurrentTextureSerial = 1; unsigned int TextureStorage::mCurrentTextureSerial = 1;
static D3DFORMAT ConvertTextureFormatType(GLenum format, GLenum type) static D3DFORMAT ConvertTextureFormatType(GLint internalformat)
{ {
if (IsDepthTexture(format)) switch (internalformat)
{ {
case GL_DEPTH_COMPONENT16:
case GL_DEPTH_COMPONENT32_OES:
case GL_DEPTH24_STENCIL8_OES:
return D3DFMT_INTZ; return D3DFMT_INTZ;
} case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
else if (format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT || case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
{
return D3DFMT_DXT1; return D3DFMT_DXT1;
} case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
else if (format == GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE)
{
return D3DFMT_DXT3; return D3DFMT_DXT3;
} case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
else if (format == GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE)
{
return D3DFMT_DXT5; return D3DFMT_DXT5;
} case GL_RGBA32F_EXT:
else if (type == GL_FLOAT) case GL_RGB32F_EXT:
{ case GL_ALPHA32F_EXT:
case GL_LUMINANCE32F_EXT:
case GL_LUMINANCE_ALPHA32F_EXT:
return D3DFMT_A32B32G32R32F; return D3DFMT_A32B32G32R32F;
} case GL_RGBA16F_EXT:
else if (type == GL_HALF_FLOAT_OES) case GL_RGB16F_EXT:
{ case GL_ALPHA16F_EXT:
case GL_LUMINANCE16F_EXT:
case GL_LUMINANCE_ALPHA16F_EXT:
return D3DFMT_A16B16G16R16F; return D3DFMT_A16B16G16R16F;
} case GL_LUMINANCE8_EXT:
else if (type == GL_UNSIGNED_BYTE) if (getContext()->supportsLuminanceTextures())
{
if (format == GL_LUMINANCE && getContext()->supportsLuminanceTextures())
{ {
return D3DFMT_L8; return D3DFMT_L8;
} }
else if (format == GL_LUMINANCE_ALPHA && getContext()->supportsLuminanceAlphaTextures()) break;
case GL_LUMINANCE8_ALPHA8_EXT:
if (getContext()->supportsLuminanceAlphaTextures())
{ {
return D3DFMT_A8L8; return D3DFMT_A8L8;
} }
else if (format == GL_RGB) break;
{ case GL_RGB8_OES:
return D3DFMT_X8R8G8B8; return D3DFMT_X8R8G8B8;
} }
return D3DFMT_A8R8G8B8; return D3DFMT_A8R8G8B8;
}
return D3DFMT_A8R8G8B8;
} }
static bool IsTextureFormatRenderable(D3DFORMAT format) static bool IsTextureFormatRenderable(D3DFORMAT format)
...@@ -141,8 +139,7 @@ Image::Image() ...@@ -141,8 +139,7 @@ Image::Image()
{ {
mWidth = 0; mWidth = 0;
mHeight = 0; mHeight = 0;
mFormat = GL_NONE; mInternalFormat = GL_NONE;
mType = GL_UNSIGNED_BYTE;
mSurface = NULL; mSurface = NULL;
...@@ -160,20 +157,18 @@ Image::~Image() ...@@ -160,20 +157,18 @@ Image::~Image()
} }
} }
bool Image::redefine(GLenum format, GLsizei width, GLsizei height, GLenum type, bool forceRelease) bool Image::redefine(GLint internalformat, GLsizei width, GLsizei height, bool forceRelease)
{ {
if (mWidth != width || if (mWidth != width ||
mHeight != height || mHeight != height ||
mFormat != format || mInternalFormat != internalformat ||
mType != type ||
forceRelease) forceRelease)
{ {
mWidth = width; mWidth = width;
mHeight = height; mHeight = height;
mFormat = format; mInternalFormat = internalformat;
mType = type;
// compute the d3d format that will be used // compute the d3d format that will be used
mD3DFormat = ConvertTextureFormatType(mFormat, mType); mD3DFormat = ConvertTextureFormatType(internalformat);
if (mSurface) if (mSurface)
{ {
...@@ -205,7 +200,7 @@ void Image::createSurface() ...@@ -205,7 +200,7 @@ void Image::createSurface()
int levelToFetch = 0; int levelToFetch = 0;
GLsizei requestWidth = mWidth; GLsizei requestWidth = mWidth;
GLsizei requestHeight = mHeight; GLsizei requestHeight = mHeight;
MakeValidSize(true, IsCompressed(mFormat), &requestWidth, &requestHeight, &levelToFetch); MakeValidSize(true, IsCompressed(mInternalFormat), &requestWidth, &requestHeight, &levelToFetch);
HRESULT result = getDevice()->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, NULL, d3dFormat, HRESULT result = getDevice()->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, NULL, d3dFormat,
poolToUse, &newTexture, NULL); poolToUse, &newTexture, NULL);
...@@ -318,7 +313,7 @@ void Image::updateSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint y ...@@ -318,7 +313,7 @@ void Image::updateSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint y
// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input // Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input
// into the target pixel rectangle. // into the target pixel rectangle.
void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum type, void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
GLint unpackAlignment, const void *input) GLint unpackAlignment, const void *input)
{ {
RECT lockRect = RECT lockRect =
...@@ -334,14 +329,12 @@ void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height ...@@ -334,14 +329,12 @@ void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height
return; return;
} }
GLsizei inputPitch = ComputePitch(width, mFormat, type, unpackAlignment);
switch (type) GLsizei inputPitch = ComputePitch(width, mInternalFormat, unpackAlignment);
{
case GL_UNSIGNED_BYTE: switch (mInternalFormat)
switch (mFormat)
{ {
case GL_ALPHA: case GL_ALPHA8_EXT:
if (supportsSSE2()) if (supportsSSE2())
{ {
loadAlphaDataSSE2(width, height, inputPitch, input, locked.Pitch, locked.pBits); loadAlphaDataSSE2(width, height, inputPitch, input, locked.Pitch, locked.pBits);
...@@ -351,16 +344,37 @@ void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height ...@@ -351,16 +344,37 @@ void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height
loadAlphaData(width, height, inputPitch, input, locked.Pitch, locked.pBits); loadAlphaData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
} }
break; break;
case GL_LUMINANCE: case GL_LUMINANCE8_EXT:
loadLuminanceData(width, height, inputPitch, input, locked.Pitch, locked.pBits, getD3DFormat() == D3DFMT_L8); loadLuminanceData(width, height, inputPitch, input, locked.Pitch, locked.pBits, getD3DFormat() == D3DFMT_L8);
break; break;
case GL_LUMINANCE_ALPHA: case GL_ALPHA32F_EXT:
loadAlphaFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
case GL_LUMINANCE32F_EXT:
loadLuminanceFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
case GL_ALPHA16F_EXT:
loadAlphaHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
case GL_LUMINANCE16F_EXT:
loadLuminanceHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
case GL_LUMINANCE8_ALPHA8_EXT:
loadLuminanceAlphaData(width, height, inputPitch, input, locked.Pitch, locked.pBits, getD3DFormat() == D3DFMT_A8L8); loadLuminanceAlphaData(width, height, inputPitch, input, locked.Pitch, locked.pBits, getD3DFormat() == D3DFMT_A8L8);
break; break;
case GL_RGB: case GL_LUMINANCE_ALPHA32F_EXT:
loadLuminanceAlphaFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
case GL_LUMINANCE_ALPHA16F_EXT:
loadLuminanceAlphaHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
case GL_RGB8_OES:
loadRGBUByteData(width, height, inputPitch, input, locked.Pitch, locked.pBits); loadRGBUByteData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break; break;
case GL_RGBA: case GL_RGB565:
loadRGB565Data(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
case GL_RGBA8_OES:
if (supportsSSE2()) if (supportsSSE2())
{ {
loadRGBAUByteDataSSE2(width, height, inputPitch, input, locked.Pitch, locked.pBits); loadRGBAUByteDataSSE2(width, height, inputPitch, input, locked.Pitch, locked.pBits);
...@@ -370,82 +384,27 @@ void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height ...@@ -370,82 +384,27 @@ void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height
loadRGBAUByteData(width, height, inputPitch, input, locked.Pitch, locked.pBits); loadRGBAUByteData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
} }
break; break;
case GL_BGRA_EXT: case GL_RGBA4:
loadBGRAData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
default: UNREACHABLE();
}
break;
case GL_UNSIGNED_SHORT_5_6_5:
switch (mFormat)
{
case GL_RGB:
loadRGB565Data(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
default: UNREACHABLE();
}
break;
case GL_UNSIGNED_SHORT_4_4_4_4:
switch (mFormat)
{
case GL_RGBA:
loadRGBA4444Data(width, height, inputPitch, input, locked.Pitch, locked.pBits); loadRGBA4444Data(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break; break;
default: UNREACHABLE(); case GL_RGB5_A1:
}
break;
case GL_UNSIGNED_SHORT_5_5_5_1:
switch (mFormat)
{
case GL_RGBA:
loadRGBA5551Data(width, height, inputPitch, input, locked.Pitch, locked.pBits); loadRGBA5551Data(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break; break;
default: UNREACHABLE(); case GL_BGRA8_EXT:
} loadBGRAData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break; break;
case GL_FLOAT:
switch (mFormat)
{
// float textures are converted to RGBA, not BGRA, as they're stored that way in D3D // float textures are converted to RGBA, not BGRA, as they're stored that way in D3D
case GL_ALPHA: case GL_RGB32F_EXT:
loadAlphaFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
case GL_LUMINANCE:
loadLuminanceFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
case GL_LUMINANCE_ALPHA:
loadLuminanceAlphaFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
case GL_RGB:
loadRGBFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits); loadRGBFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break; break;
case GL_RGBA: case GL_RGB16F_EXT:
loadRGBAFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
default: UNREACHABLE();
}
break;
case GL_HALF_FLOAT_OES:
switch (mFormat)
{
// float textures are converted to RGBA, not BGRA, as they're stored that way in D3D
case GL_ALPHA:
loadAlphaHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
case GL_LUMINANCE:
loadLuminanceHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
case GL_LUMINANCE_ALPHA:
loadLuminanceAlphaHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
case GL_RGB:
loadRGBHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits); loadRGBHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break; break;
case GL_RGBA: case GL_RGBA32F_EXT:
loadRGBAHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits); loadRGBAFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break; break;
default: UNREACHABLE(); case GL_RGBA16F_EXT:
} loadRGBAHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break; break;
default: UNREACHABLE(); default: UNREACHABLE();
} }
...@@ -849,8 +808,8 @@ void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsi ...@@ -849,8 +808,8 @@ void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsi
return; return;
} }
GLsizei inputSize = ComputeCompressedSize(width, height, mFormat); GLsizei inputSize = ComputeCompressedSize(width, height, mInternalFormat);
GLsizei inputPitch = ComputeCompressedPitch(width, mFormat); GLsizei inputPitch = ComputeCompressedPitch(width, mInternalFormat);
int rows = inputSize / inputPitch; int rows = inputSize / inputPitch;
for (int i = 0; i < rows; ++i) for (int i = 0; i < rows; ++i)
{ {
...@@ -1246,7 +1205,7 @@ void Texture::setImage(GLint unpackAlignment, const void *pixels, Image *image) ...@@ -1246,7 +1205,7 @@ void Texture::setImage(GLint unpackAlignment, const void *pixels, Image *image)
{ {
if (pixels != NULL) if (pixels != NULL)
{ {
image->loadData(0, 0, image->getWidth(), image->getHeight(), image->getType(), unpackAlignment, pixels); image->loadData(0, 0, image->getWidth(), image->getHeight(), unpackAlignment, pixels);
mDirtyImages = true; mDirtyImages = true;
} }
} }
...@@ -1264,7 +1223,7 @@ bool Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei heig ...@@ -1264,7 +1223,7 @@ bool Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei heig
{ {
if (pixels != NULL) if (pixels != NULL)
{ {
image->loadData(xoffset, yoffset, width, height, type, unpackAlignment, pixels); image->loadData(xoffset, yoffset, width, height, unpackAlignment, pixels);
mDirtyImages = true; mDirtyImages = true;
} }
...@@ -1524,7 +1483,7 @@ GLsizei Texture2D::getHeight(GLint level) const ...@@ -1524,7 +1483,7 @@ GLsizei Texture2D::getHeight(GLint level) const
GLenum Texture2D::getInternalFormat(GLint level) const GLenum Texture2D::getInternalFormat(GLint level) const
{ {
if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
return mImageArray[level].getFormat(); return mImageArray[level].getInternalFormat();
else else
return GL_NONE; return GL_NONE;
} }
...@@ -1537,11 +1496,11 @@ D3DFORMAT Texture2D::getD3DFormat(GLint level) const ...@@ -1537,11 +1496,11 @@ D3DFORMAT Texture2D::getD3DFormat(GLint level) const
return D3DFMT_UNKNOWN; return D3DFMT_UNKNOWN;
} }
void Texture2D::redefineImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type) void Texture2D::redefineImage(GLint level, GLint internalformat, GLsizei width, GLsizei height)
{ {
releaseTexImage(); releaseTexImage();
bool redefined = mImageArray[level].redefine(format, width, height, type, false); bool redefined = mImageArray[level].redefine(internalformat, width, height, false);
if (mTexStorage && redefined) if (mTexStorage && redefined)
{ {
...@@ -1558,7 +1517,8 @@ void Texture2D::redefineImage(GLint level, GLenum format, GLsizei width, GLsizei ...@@ -1558,7 +1517,8 @@ void Texture2D::redefineImage(GLint level, GLenum format, GLsizei width, GLsizei
void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
{ {
redefineImage(level, format, width, height, type); GLint internalformat = ConvertSizedInternalFormat(format, type);
redefineImage(level, internalformat, width, height);
Texture::setImage(unpackAlignment, pixels, &mImageArray[level]); Texture::setImage(unpackAlignment, pixels, &mImageArray[level]);
} }
...@@ -1567,22 +1527,22 @@ void Texture2D::bindTexImage(egl::Surface *surface) ...@@ -1567,22 +1527,22 @@ void Texture2D::bindTexImage(egl::Surface *surface)
{ {
releaseTexImage(); releaseTexImage();
GLenum format; GLint internalformat;
switch(surface->getFormat()) switch(surface->getFormat())
{ {
case D3DFMT_A8R8G8B8: case D3DFMT_A8R8G8B8:
format = GL_RGBA; internalformat = GL_RGBA8_OES;
break; break;
case D3DFMT_X8R8G8B8: case D3DFMT_X8R8G8B8:
format = GL_RGB; internalformat = GL_RGB8_OES;
break; break;
default: default:
UNIMPLEMENTED(); UNIMPLEMENTED();
return; return;
} }
mImageArray[0].redefine(format, surface->getWidth(), surface->getHeight(), GL_UNSIGNED_BYTE, true); mImageArray[0].redefine(internalformat, surface->getWidth(), surface->getHeight(), true);
delete mTexStorage; delete mTexStorage;
mTexStorage = new TextureStorage2D(surface->getOffscreenTexture()); mTexStorage = new TextureStorage2D(surface->getOffscreenTexture());
...@@ -1607,14 +1567,15 @@ void Texture2D::releaseTexImage() ...@@ -1607,14 +1567,15 @@ void Texture2D::releaseTexImage()
for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
{ {
mImageArray[i].redefine(GL_RGBA, 0, 0, GL_UNSIGNED_BYTE, true); mImageArray[i].redefine(GL_RGBA8_OES, 0, 0, true);
} }
} }
} }
void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels) void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
{ {
redefineImage(level, format, width, height, GL_UNSIGNED_BYTE); // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
redefineImage(level, format, width, height);
Texture::setCompressedImage(imageSize, pixels, &mImageArray[level]); Texture::setCompressedImage(imageSize, pixels, &mImageArray[level]);
} }
...@@ -1664,7 +1625,8 @@ void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei ...@@ -1664,7 +1625,8 @@ void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei
return error(GL_OUT_OF_MEMORY); return error(GL_OUT_OF_MEMORY);
} }
redefineImage(level, format, width, height, GL_UNSIGNED_BYTE); GLint internalformat = ConvertSizedInternalFormat(format, GL_UNSIGNED_BYTE);
redefineImage(level, internalformat, width, height);
if (!mImageArray[level].isRenderableFormat()) if (!mImageArray[level].isRenderableFormat())
{ {
...@@ -1742,7 +1704,9 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo ...@@ -1742,7 +1704,9 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo
if (dest) if (dest)
{ {
getBlitter()->copy(renderTarget, sourceRect, mImageArray[0].getFormat(), xoffset, yoffset, dest); getBlitter()->copy(renderTarget, sourceRect,
gl::ExtractFormat(mImageArray[0].getInternalFormat()),
xoffset, yoffset, dest);
dest->Release(); dest->Release();
} }
} }
...@@ -1753,9 +1717,7 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo ...@@ -1753,9 +1717,7 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo
void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
{ {
GLenum format = gl::ExtractFormat(internalformat); D3DFORMAT d3dfmt = ConvertTextureFormatType(internalformat);
GLenum type = gl::ExtractType(internalformat);
D3DFORMAT d3dfmt = ConvertTextureFormatType(format, type);
DWORD d3dusage = GetTextureUsage(d3dfmt, mUsage, false); DWORD d3dusage = GetTextureUsage(d3dfmt, mUsage, false);
delete mTexStorage; delete mTexStorage;
...@@ -1764,14 +1726,14 @@ void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GL ...@@ -1764,14 +1726,14 @@ void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GL
for (int level = 0; level < levels; level++) for (int level = 0; level < levels; level++)
{ {
mImageArray[level].redefine(format, width, height, type, true); mImageArray[level].redefine(internalformat, width, height, true);
width = std::max(1, width >> 1); width = std::max(1, width >> 1);
height = std::max(1, height >> 1); height = std::max(1, height >> 1);
} }
for (int level = levels; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) for (int level = levels; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
{ {
mImageArray[level].redefine(GL_NONE, 0, 0, GL_UNSIGNED_BYTE, true); mImageArray[level].redefine(GL_NONE, 0, 0, true);
} }
if (mTexStorage->isManaged()) if (mTexStorage->isManaged())
...@@ -1814,8 +1776,8 @@ bool Texture2D::isSamplerComplete() const ...@@ -1814,8 +1776,8 @@ bool Texture2D::isSamplerComplete() const
default: UNREACHABLE(); default: UNREACHABLE();
} }
if ((getInternalFormat(0) == GL_FLOAT && !getContext()->supportsFloat32LinearFilter()) || if ((gl::ExtractType(getInternalFormat(0)) == GL_FLOAT && !getContext()->supportsFloat32LinearFilter()) ||
(getInternalFormat(0) == GL_HALF_FLOAT_OES && !getContext()->supportsFloat16LinearFilter())) (gl::ExtractType(getInternalFormat(0)) == GL_HALF_FLOAT_OES && !getContext()->supportsFloat16LinearFilter()))
{ {
if (mMagFilter != GL_NEAREST || (mMinFilter != GL_NEAREST && mMinFilter != GL_NEAREST_MIPMAP_NEAREST)) if (mMagFilter != GL_NEAREST || (mMinFilter != GL_NEAREST && mMinFilter != GL_NEAREST_MIPMAP_NEAREST))
{ {
...@@ -1873,12 +1835,7 @@ bool Texture2D::isMipmapComplete() const ...@@ -1873,12 +1835,7 @@ bool Texture2D::isMipmapComplete() const
for (int level = 1; level <= q; level++) for (int level = 1; level <= q; level++)
{ {
if (mImageArray[level].getFormat() != mImageArray[0].getFormat()) if (mImageArray[level].getInternalFormat() != mImageArray[0].getInternalFormat())
{
return false;
}
if (mImageArray[level].getType() != mImageArray[0].getType())
{ {
return false; return false;
} }
...@@ -2013,10 +1970,9 @@ void Texture2D::generateMipmaps() ...@@ -2013,10 +1970,9 @@ void Texture2D::generateMipmaps()
unsigned int q = log2(std::max(mImageArray[0].getWidth(), mImageArray[0].getHeight())); unsigned int q = log2(std::max(mImageArray[0].getWidth(), mImageArray[0].getHeight()));
for (unsigned int i = 1; i <= q; i++) for (unsigned int i = 1; i <= q; i++)
{ {
redefineImage(i, mImageArray[0].getFormat(), redefineImage(i, mImageArray[0].getInternalFormat(),
std::max(mImageArray[0].getWidth() >> i, 1), std::max(mImageArray[0].getWidth() >> i, 1),
std::max(mImageArray[0].getHeight() >> i, 1), std::max(mImageArray[0].getHeight() >> i, 1));
mImageArray[0].getType());
} }
if (mTexStorage && mTexStorage->isRenderTarget()) if (mTexStorage && mTexStorage->isRenderTarget())
...@@ -2267,7 +2223,7 @@ GLsizei TextureCubeMap::getHeight(GLenum target, GLint level) const ...@@ -2267,7 +2223,7 @@ GLsizei TextureCubeMap::getHeight(GLenum target, GLint level) const
GLenum TextureCubeMap::getInternalFormat(GLenum target, GLint level) const GLenum TextureCubeMap::getInternalFormat(GLenum target, GLint level) const
{ {
if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
return mImageArray[faceIndex(target)][level].getFormat(); return mImageArray[faceIndex(target)][level].getInternalFormat();
else else
return GL_NONE; return GL_NONE;
} }
...@@ -2312,7 +2268,8 @@ void TextureCubeMap::setImageNegZ(GLint level, GLsizei width, GLsizei height, GL ...@@ -2312,7 +2268,8 @@ void TextureCubeMap::setImageNegZ(GLint level, GLsizei width, GLsizei height, GL
void TextureCubeMap::setCompressedImage(GLenum face, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels) void TextureCubeMap::setCompressedImage(GLenum face, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
{ {
redefineImage(faceIndex(face), level, format, width, height, GL_UNSIGNED_BYTE); // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
redefineImage(faceIndex(face), level, format, width, height);
Texture::setCompressedImage(imageSize, pixels, &mImageArray[faceIndex(face)][level]); Texture::setCompressedImage(imageSize, pixels, &mImageArray[faceIndex(face)][level]);
} }
...@@ -2377,8 +2334,8 @@ bool TextureCubeMap::isSamplerComplete() const ...@@ -2377,8 +2334,8 @@ bool TextureCubeMap::isSamplerComplete() const
return false; return false;
} }
if ((getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0) == GL_FLOAT && !getContext()->supportsFloat32LinearFilter()) || if ((gl::ExtractType(getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0)) == GL_FLOAT && !getContext()->supportsFloat32LinearFilter()) ||
(getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0) == GL_HALF_FLOAT_OES && !getContext()->supportsFloat16LinearFilter())) (gl::ExtractType(getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0) == GL_HALF_FLOAT_OES) && !getContext()->supportsFloat16LinearFilter()))
{ {
if (mMagFilter != GL_NEAREST || (mMinFilter != GL_NEAREST && mMinFilter != GL_NEAREST_MIPMAP_NEAREST)) if (mMagFilter != GL_NEAREST || (mMinFilter != GL_NEAREST && mMinFilter != GL_NEAREST_MIPMAP_NEAREST))
{ {
...@@ -2424,8 +2381,7 @@ bool TextureCubeMap::isCubeComplete() const ...@@ -2424,8 +2381,7 @@ bool TextureCubeMap::isCubeComplete() const
{ {
if (mImageArray[face][0].getWidth() != mImageArray[0][0].getWidth() || if (mImageArray[face][0].getWidth() != mImageArray[0][0].getWidth() ||
mImageArray[face][0].getWidth() != mImageArray[0][0].getHeight() || mImageArray[face][0].getWidth() != mImageArray[0][0].getHeight() ||
mImageArray[face][0].getFormat() != mImageArray[0][0].getFormat() || mImageArray[face][0].getInternalFormat() != mImageArray[0][0].getInternalFormat())
mImageArray[face][0].getType() != mImageArray[0][0].getType())
{ {
return false; return false;
} }
...@@ -2454,12 +2410,7 @@ bool TextureCubeMap::isMipmapCubeComplete() const ...@@ -2454,12 +2410,7 @@ bool TextureCubeMap::isMipmapCubeComplete() const
{ {
for (int level = 1; level <= q; level++) for (int level = 1; level <= q; level++)
{ {
if (mImageArray[face][level].getFormat() != mImageArray[0][0].getFormat()) if (mImageArray[face][level].getInternalFormat() != mImageArray[0][0].getInternalFormat())
{
return false;
}
if (mImageArray[face][level].getType() != mImageArray[0][0].getType())
{ {
return false; return false;
} }
...@@ -2579,7 +2530,8 @@ void TextureCubeMap::convertToRenderTarget() ...@@ -2579,7 +2530,8 @@ void TextureCubeMap::convertToRenderTarget()
void TextureCubeMap::setImage(int faceIndex, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) void TextureCubeMap::setImage(int faceIndex, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
{ {
redefineImage(faceIndex, level, format, width, height, type); GLint internalformat = ConvertSizedInternalFormat(format, type);
redefineImage(faceIndex, level, internalformat, width, height);
Texture::setImage(unpackAlignment, pixels, &mImageArray[faceIndex][level]); Texture::setImage(unpackAlignment, pixels, &mImageArray[faceIndex][level]);
} }
...@@ -2595,9 +2547,9 @@ unsigned int TextureCubeMap::faceIndex(GLenum face) ...@@ -2595,9 +2547,9 @@ unsigned int TextureCubeMap::faceIndex(GLenum face)
return face - GL_TEXTURE_CUBE_MAP_POSITIVE_X; return face - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
} }
void TextureCubeMap::redefineImage(int face, GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type) void TextureCubeMap::redefineImage(int face, GLint level, GLint internalformat, GLsizei width, GLsizei height)
{ {
bool redefined = mImageArray[face][level].redefine(format, width, height, type, false); bool redefined = mImageArray[face][level].redefine(internalformat, width, height, false);
if (mTexStorage && redefined) if (mTexStorage && redefined)
{ {
...@@ -2627,7 +2579,8 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint ...@@ -2627,7 +2579,8 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint
} }
unsigned int faceindex = faceIndex(target); unsigned int faceindex = faceIndex(target);
redefineImage(faceindex, level, format, width, height, GL_UNSIGNED_BYTE); GLint internalformat = gl::ConvertSizedInternalFormat(format, GL_UNSIGNED_BYTE);
redefineImage(faceindex, level, internalformat, width, height);
if (!mImageArray[faceindex][level].isRenderableFormat()) if (!mImageArray[faceindex][level].isRenderableFormat())
{ {
...@@ -2711,7 +2664,7 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi ...@@ -2711,7 +2664,7 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi
if (dest) if (dest)
{ {
getBlitter()->copy(renderTarget, sourceRect, mImageArray[0][0].getFormat(), xoffset, yoffset, dest); getBlitter()->copy(renderTarget, sourceRect, gl::ExtractFormat(mImageArray[0][0].getInternalFormat()), xoffset, yoffset, dest);
dest->Release(); dest->Release();
} }
} }
...@@ -2722,9 +2675,7 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi ...@@ -2722,9 +2675,7 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi
void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size) void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size)
{ {
GLenum format = gl::ExtractFormat(internalformat); D3DFORMAT d3dfmt = ConvertTextureFormatType(internalformat);
GLenum type = gl::ExtractType(internalformat);
D3DFORMAT d3dfmt = ConvertTextureFormatType(format, type);
DWORD d3dusage = GetTextureUsage(d3dfmt, mUsage, false); DWORD d3dusage = GetTextureUsage(d3dfmt, mUsage, false);
delete mTexStorage; delete mTexStorage;
...@@ -2735,7 +2686,7 @@ void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size ...@@ -2735,7 +2686,7 @@ void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size
{ {
for (int face = 0; face < 6; face++) for (int face = 0; face < 6; face++)
{ {
mImageArray[face][level].redefine(format, size, size, type, true); mImageArray[face][level].redefine(internalformat, size, size, true);
size = std::max(1, size >> 1); size = std::max(1, size >> 1);
} }
} }
...@@ -2744,7 +2695,7 @@ void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size ...@@ -2744,7 +2695,7 @@ void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size
{ {
for (int face = 0; face < 6; face++) for (int face = 0; face < 6; face++)
{ {
mImageArray[face][level].redefine(GL_NONE, 0, 0, GL_UNSIGNED_BYTE, true); mImageArray[face][level].redefine(GL_NONE, 0, 0, true);
} }
} }
...@@ -2784,10 +2735,9 @@ void TextureCubeMap::generateMipmaps() ...@@ -2784,10 +2735,9 @@ void TextureCubeMap::generateMipmaps()
{ {
for (unsigned int i = 1; i <= q; i++) for (unsigned int i = 1; i <= q; i++)
{ {
redefineImage(f, i, mImageArray[f][0].getFormat(), redefineImage(f, i, mImageArray[f][0].getInternalFormat(),
std::max(mImageArray[f][0].getWidth() >> i, 1),
std::max(mImageArray[f][0].getWidth() >> i, 1), std::max(mImageArray[f][0].getWidth() >> i, 1),
mImageArray[f][0].getType()); std::max(mImageArray[f][0].getWidth() >> i, 1));
} }
} }
......
...@@ -49,7 +49,7 @@ class Image ...@@ -49,7 +49,7 @@ class Image
Image(); Image();
~Image(); ~Image();
bool redefine(GLenum format, GLsizei width, GLsizei height, GLenum type, bool forceRelease); bool redefine(GLint internalformat, GLsizei width, GLsizei height, bool forceRelease);
void markDirty() {mDirty = true;} void markDirty() {mDirty = true;}
void markClean() {mDirty = false;} void markClean() {mDirty = false;}
...@@ -58,15 +58,14 @@ class Image ...@@ -58,15 +58,14 @@ class Image
GLsizei getWidth() const {return mWidth;} GLsizei getWidth() const {return mWidth;}
GLsizei getHeight() const {return mHeight;} GLsizei getHeight() const {return mHeight;}
GLenum getFormat() const {return mFormat;} GLenum getInternalFormat() const {return mInternalFormat;}
GLenum getType() const {return mType;}
bool isDirty() const {return mSurface && mDirty;} bool isDirty() const {return mSurface && mDirty;}
IDirect3DSurface9 *getSurface(); IDirect3DSurface9 *getSurface();
void setManagedSurface(IDirect3DSurface9 *surface); void setManagedSurface(IDirect3DSurface9 *surface);
void updateSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); void updateSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum type, void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
GLint unpackAlignment, const void *input); GLint unpackAlignment, const void *input);
void loadAlphaData(GLsizei width, GLsizei height, void loadAlphaData(GLsizei width, GLsizei height,
...@@ -126,8 +125,7 @@ class Image ...@@ -126,8 +125,7 @@ class Image
GLsizei mWidth; GLsizei mWidth;
GLsizei mHeight; GLsizei mHeight;
GLenum mFormat; GLint mInternalFormat;
GLenum mType;
bool mDirty; bool mDirty;
...@@ -321,7 +319,7 @@ class Texture2D : public Texture ...@@ -321,7 +319,7 @@ class Texture2D : public Texture
bool isMipmapComplete() const; bool isMipmapComplete() const;
void redefineImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type); void redefineImage(GLint level, GLint internalformat, GLsizei width, GLsizei height);
void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
Image mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS]; Image mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
...@@ -416,7 +414,7 @@ class TextureCubeMap : public Texture ...@@ -416,7 +414,7 @@ class TextureCubeMap : public Texture
void setImage(int faceIndex, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); void setImage(int faceIndex, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
void commitRect(int faceIndex, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); void commitRect(int faceIndex, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
void redefineImage(int faceIndex, GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type); void redefineImage(int faceIndex, GLint level, GLint internalformat, GLsizei width, GLsizei height);
Image mImageArray[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS]; Image mImageArray[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS];
......
...@@ -148,8 +148,9 @@ bool checkTextureFormatType(GLenum format, GLenum type) ...@@ -148,8 +148,9 @@ bool checkTextureFormatType(GLenum format, GLenum type)
return error(GL_INVALID_ENUM, false); return error(GL_INVALID_ENUM, false);
} }
} }
bool validateSubImageParams2D(bool compressed, GLsizei width, GLsizei height, bool validateSubImageParams2D(bool compressed, GLsizei width, GLsizei height,
GLint xoffset, GLint yoffset, GLint level, GLenum format, GLint xoffset, GLint yoffset, GLint level, GLenum format, GLenum type,
gl::Texture2D *texture) gl::Texture2D *texture)
{ {
if (!texture) if (!texture)
...@@ -162,10 +163,14 @@ bool validateSubImageParams2D(bool compressed, GLsizei width, GLsizei height, ...@@ -162,10 +163,14 @@ bool validateSubImageParams2D(bool compressed, GLsizei width, GLsizei height,
return error(GL_INVALID_OPERATION, false); return error(GL_INVALID_OPERATION, false);
} }
if (format != GL_NONE && format != texture->getInternalFormat(level)) if (format != GL_NONE)
{
GLenum internalformat = gl::ConvertSizedInternalFormat(format, type);
if (internalformat != texture->getInternalFormat(level))
{ {
return error(GL_INVALID_OPERATION, false); return error(GL_INVALID_OPERATION, false);
} }
}
if (compressed) if (compressed)
{ {
...@@ -186,7 +191,7 @@ bool validateSubImageParams2D(bool compressed, GLsizei width, GLsizei height, ...@@ -186,7 +191,7 @@ bool validateSubImageParams2D(bool compressed, GLsizei width, GLsizei height,
} }
bool validateSubImageParamsCube(bool compressed, GLsizei width, GLsizei height, bool validateSubImageParamsCube(bool compressed, GLsizei width, GLsizei height,
GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, GLenum type,
gl::TextureCubeMap *texture) gl::TextureCubeMap *texture)
{ {
if (!texture) if (!texture)
...@@ -199,10 +204,14 @@ bool validateSubImageParamsCube(bool compressed, GLsizei width, GLsizei height, ...@@ -199,10 +204,14 @@ bool validateSubImageParamsCube(bool compressed, GLsizei width, GLsizei height,
return error(GL_INVALID_OPERATION, false); return error(GL_INVALID_OPERATION, false);
} }
if (format != GL_NONE && format != texture->getInternalFormat(target, level)) if (format != GL_NONE)
{
GLenum internalformat = gl::ConvertSizedInternalFormat(format, type);
if (internalformat != texture->getInternalFormat(target, level))
{ {
return error(GL_INVALID_OPERATION, false); return error(GL_INVALID_OPERATION, false);
} }
}
if (compressed) if (compressed)
{ {
...@@ -1218,7 +1227,7 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs ...@@ -1218,7 +1227,7 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs
if (target == GL_TEXTURE_2D) if (target == GL_TEXTURE_2D)
{ {
gl::Texture2D *texture = context->getTexture2D(); gl::Texture2D *texture = context->getTexture2D();
if (validateSubImageParams2D(true, width, height, xoffset, yoffset, level, format, texture)) if (validateSubImageParams2D(true, width, height, xoffset, yoffset, level, format, GL_NONE, texture))
{ {
texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data); texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
} }
...@@ -1226,7 +1235,7 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs ...@@ -1226,7 +1235,7 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs
else if (gl::IsCubemapTextureTarget(target)) else if (gl::IsCubemapTextureTarget(target))
{ {
gl::TextureCubeMap *texture = context->getTextureCubeMap(); gl::TextureCubeMap *texture = context->getTextureCubeMap();
if (validateSubImageParamsCube(true, width, height, xoffset, yoffset, target, level, format, texture)) if (validateSubImageParamsCube(true, width, height, xoffset, yoffset, target, level, format, GL_NONE, texture))
{ {
texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data); texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
} }
...@@ -1319,8 +1328,7 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma ...@@ -1319,8 +1328,7 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
switch (internalformat) switch (internalformat)
{ {
case GL_ALPHA: case GL_ALPHA:
if (colorbufferFormat != GL_ALPHA && if (colorbufferFormat != GL_ALPHA8_EXT &&
colorbufferFormat != GL_RGBA &&
colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES) colorbufferFormat != GL_RGBA8_OES)
...@@ -1329,11 +1337,17 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma ...@@ -1329,11 +1337,17 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
} }
break; break;
case GL_LUMINANCE: case GL_LUMINANCE:
if (colorbufferFormat != GL_RGB565 &&
colorbufferFormat != GL_RGB8_OES &&
colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES)
{
return error(GL_INVALID_OPERATION);
}
case GL_RGB: case GL_RGB:
if (colorbufferFormat != GL_RGB && if (colorbufferFormat != GL_RGB565 &&
colorbufferFormat != GL_RGB565 &&
colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGB8_OES &&
colorbufferFormat != GL_RGBA &&
colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES) colorbufferFormat != GL_RGBA8_OES)
...@@ -1343,8 +1357,7 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma ...@@ -1343,8 +1357,7 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
break; break;
case GL_LUMINANCE_ALPHA: case GL_LUMINANCE_ALPHA:
case GL_RGBA: case GL_RGBA:
if (colorbufferFormat != GL_RGBA && if (colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES) colorbufferFormat != GL_RGBA8_OES)
{ {
...@@ -1498,22 +1511,22 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL ...@@ -1498,22 +1511,22 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
{ {
gl::Texture2D *tex2d = context->getTexture2D(); gl::Texture2D *tex2d = context->getTexture2D();
if (!validateSubImageParams2D(false, width, height, xoffset, yoffset, level, GL_NONE, tex2d)) if (!validateSubImageParams2D(false, width, height, xoffset, yoffset, level, GL_NONE, GL_NONE, tex2d))
{ {
return; // error already registered by validateSubImageParams return; // error already registered by validateSubImageParams
} }
textureFormat = tex2d->getInternalFormat(level); textureFormat = gl::ExtractFormat(tex2d->getInternalFormat(level));
texture = tex2d; texture = tex2d;
} }
else if (gl::IsCubemapTextureTarget(target)) else if (gl::IsCubemapTextureTarget(target))
{ {
gl::TextureCubeMap *texcube = context->getTextureCubeMap(); gl::TextureCubeMap *texcube = context->getTextureCubeMap();
if (!validateSubImageParamsCube(false, width, height, xoffset, yoffset, target, level, GL_NONE, texcube)) if (!validateSubImageParamsCube(false, width, height, xoffset, yoffset, target, level, GL_NONE, GL_NONE, texcube))
{ {
return; // error already registered by validateSubImageParams return; // error already registered by validateSubImageParams
} }
textureFormat = texcube->getInternalFormat(target, level); textureFormat = gl::ExtractFormat(texcube->getInternalFormat(target, level));
texture = texcube; texture = texcube;
} }
else UNREACHABLE(); else UNREACHABLE();
...@@ -1522,8 +1535,7 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL ...@@ -1522,8 +1535,7 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
switch (textureFormat) switch (textureFormat)
{ {
case GL_ALPHA: case GL_ALPHA:
if (colorbufferFormat != GL_ALPHA && if (colorbufferFormat != GL_ALPHA8_EXT &&
colorbufferFormat != GL_RGBA &&
colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES) colorbufferFormat != GL_RGBA8_OES)
...@@ -1532,9 +1544,7 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL ...@@ -1532,9 +1544,7 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
} }
break; break;
case GL_LUMINANCE: case GL_LUMINANCE:
case GL_RGB: if (colorbufferFormat != GL_RGB565 &&
if (colorbufferFormat != GL_RGB &&
colorbufferFormat != GL_RGB565 &&
colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGB8_OES &&
colorbufferFormat != GL_RGBA && colorbufferFormat != GL_RGBA &&
colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGBA4 &&
...@@ -1544,10 +1554,19 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL ...@@ -1544,10 +1554,19 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
break; break;
case GL_RGB:
if (colorbufferFormat != GL_RGB565 &&
colorbufferFormat != GL_RGB8_OES &&
colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES)
{
return error(GL_INVALID_OPERATION);
}
break;
case GL_LUMINANCE_ALPHA: case GL_LUMINANCE_ALPHA:
case GL_RGBA: case GL_RGBA:
if (colorbufferFormat != GL_RGBA && if (colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES) colorbufferFormat != GL_RGBA8_OES)
{ {
...@@ -5910,7 +5929,7 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint ...@@ -5910,7 +5929,7 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
if (target == GL_TEXTURE_2D) if (target == GL_TEXTURE_2D)
{ {
gl::Texture2D *texture = context->getTexture2D(); gl::Texture2D *texture = context->getTexture2D();
if (validateSubImageParams2D(false, width, height, xoffset, yoffset, level, format, texture)) if (validateSubImageParams2D(false, width, height, xoffset, yoffset, level, format, type, texture))
{ {
texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels); texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
} }
...@@ -5918,7 +5937,7 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint ...@@ -5918,7 +5937,7 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
else if (gl::IsCubemapTextureTarget(target)) else if (gl::IsCubemapTextureTarget(target))
{ {
gl::TextureCubeMap *texture = context->getTextureCubeMap(); gl::TextureCubeMap *texture = context->getTextureCubeMap();
if (validateSubImageParamsCube(false, width, height, xoffset, yoffset, target, level, format, texture)) if (validateSubImageParamsCube(false, width, height, xoffset, yoffset, target, level, format, type, texture))
{ {
texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels); texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
} }
......
...@@ -229,22 +229,22 @@ int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsig ...@@ -229,22 +229,22 @@ int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsig
return -1; return -1;
} }
GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment) GLsizei ComputePitch(GLsizei width, GLint internalformat, GLint alignment)
{ {
ASSERT(alignment > 0 && isPow2(alignment)); ASSERT(alignment > 0 && isPow2(alignment));
GLsizei rawPitch = ComputePixelSize(format, type) * width; GLsizei rawPitch = ComputePixelSize(internalformat) * width;
return (rawPitch + alignment - 1) & ~(alignment - 1); return (rawPitch + alignment - 1) & ~(alignment - 1);
} }
GLsizei ComputeCompressedPitch(GLsizei width, GLenum format) GLsizei ComputeCompressedPitch(GLsizei width, GLenum internalformat)
{ {
return ComputeCompressedSize(width, 1, format); return ComputeCompressedSize(width, 1, internalformat);
} }
GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format) GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum internalformat)
{ {
switch (format) switch (internalformat)
{ {
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
...@@ -277,7 +277,10 @@ bool IsCompressed(GLenum format) ...@@ -277,7 +277,10 @@ bool IsCompressed(GLenum format)
bool IsDepthTexture(GLenum format) bool IsDepthTexture(GLenum format)
{ {
if (format == GL_DEPTH_COMPONENT || if (format == GL_DEPTH_COMPONENT ||
format == GL_DEPTH_STENCIL_OES) format == GL_DEPTH_STENCIL_OES ||
format == GL_DEPTH_COMPONENT16 ||
format == GL_DEPTH_COMPONENT32_OES ||
format == GL_DEPTH24_STENCIL8_OES)
{ {
return true; return true;
} }
...@@ -286,54 +289,29 @@ bool IsDepthTexture(GLenum format) ...@@ -286,54 +289,29 @@ bool IsDepthTexture(GLenum format)
} }
// Returns the size, in bytes, of a single texel in an Image // Returns the size, in bytes, of a single texel in an Image
int ComputePixelSize(GLenum format, GLenum type) int ComputePixelSize(GLint internalformat)
{ {
switch (type) switch (internalformat)
{
case GL_UNSIGNED_BYTE:
switch (format)
{
case GL_ALPHA: return sizeof(unsigned char);
case GL_LUMINANCE: return sizeof(unsigned char);
case GL_LUMINANCE_ALPHA: return sizeof(unsigned char) * 2;
case GL_RGB: return sizeof(unsigned char) * 3;
case GL_RGBA: return sizeof(unsigned char) * 4;
case GL_BGRA_EXT: return sizeof(unsigned char) * 4;
default: UNREACHABLE();
}
break;
case GL_UNSIGNED_SHORT_4_4_4_4:
case GL_UNSIGNED_SHORT_5_5_5_1:
case GL_UNSIGNED_SHORT_5_6_5:
case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
case GL_UNSIGNED_SHORT:
return sizeof(unsigned short);
case GL_UNSIGNED_INT:
case GL_UNSIGNED_INT_24_8_OES:
return sizeof(unsigned int);
case GL_FLOAT:
switch (format)
{
case GL_ALPHA: return sizeof(float);
case GL_LUMINANCE: return sizeof(float);
case GL_LUMINANCE_ALPHA: return sizeof(float) * 2;
case GL_RGB: return sizeof(float) * 3;
case GL_RGBA: return sizeof(float) * 4;
default: UNREACHABLE();
}
break;
case GL_HALF_FLOAT_OES:
switch (format)
{ {
case GL_ALPHA: return sizeof(unsigned short); case GL_ALPHA8_EXT: return sizeof(unsigned char);
case GL_LUMINANCE: return sizeof(unsigned short); case GL_LUMINANCE8_EXT: return sizeof(unsigned char);
case GL_LUMINANCE_ALPHA: return sizeof(unsigned short) * 2; case GL_ALPHA32F_EXT: return sizeof(float);
case GL_RGB: return sizeof(unsigned short) * 3; case GL_LUMINANCE32F_EXT: return sizeof(float);
case GL_RGBA: return sizeof(unsigned short) * 4; case GL_ALPHA16F_EXT: return sizeof(unsigned short);
default: UNREACHABLE(); case GL_LUMINANCE16F_EXT: return sizeof(unsigned short);
} case GL_LUMINANCE8_ALPHA8_EXT: return sizeof(unsigned char) * 2;
break; case GL_LUMINANCE_ALPHA32F_EXT: return sizeof(float) * 2;
case GL_LUMINANCE_ALPHA16F_EXT: return sizeof(unsigned short) * 2;
case GL_RGB8_OES: return sizeof(unsigned char) * 3;
case GL_RGB565: return sizeof(unsigned short);
case GL_RGB32F_EXT: return sizeof(float) * 3;
case GL_RGB16F_EXT: return sizeof(unsigned short) * 3;
case GL_RGBA8_OES: return sizeof(unsigned char) * 4;
case GL_RGBA4: return sizeof(unsigned short);
case GL_RGB5_A1: return sizeof(unsigned short);
case GL_RGBA32F_EXT: return sizeof(float) * 4;
case GL_RGBA16F_EXT: return sizeof(unsigned short) * 4;
case GL_BGRA8_EXT: return sizeof(unsigned char) * 4;
default: UNREACHABLE(); default: UNREACHABLE();
} }
...@@ -350,6 +328,94 @@ bool IsInternalTextureTarget(GLenum target) ...@@ -350,6 +328,94 @@ bool IsInternalTextureTarget(GLenum target)
return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target); return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target);
} }
GLint ConvertSizedInternalFormat(GLenum format, GLenum type)
{
switch (format)
{
case GL_ALPHA:
switch (type)
{
case GL_UNSIGNED_BYTE: return GL_ALPHA8_EXT;
case GL_FLOAT: return GL_ALPHA32F_EXT;
case GL_HALF_FLOAT_OES: return GL_ALPHA16F_EXT;
default: UNIMPLEMENTED();
}
break;
case GL_LUMINANCE:
switch (type)
{
case GL_UNSIGNED_BYTE: return GL_LUMINANCE8_EXT;
case GL_FLOAT: return GL_LUMINANCE32F_EXT;
case GL_HALF_FLOAT_OES: return GL_LUMINANCE16F_EXT;
default: UNIMPLEMENTED();
}
break;
case GL_LUMINANCE_ALPHA:
switch (type)
{
case GL_UNSIGNED_BYTE: return GL_LUMINANCE8_ALPHA8_EXT;
case GL_FLOAT: return GL_LUMINANCE_ALPHA32F_EXT;
case GL_HALF_FLOAT_OES: return GL_LUMINANCE_ALPHA16F_EXT;
default: UNIMPLEMENTED();
}
break;
case GL_RGB:
switch (type)
{
case GL_UNSIGNED_BYTE: return GL_RGB8_OES;
case GL_UNSIGNED_SHORT_5_6_5: return GL_RGB565;
case GL_FLOAT: return GL_RGB32F_EXT;
case GL_HALF_FLOAT_OES: return GL_RGB16F_EXT;
default: UNIMPLEMENTED();
}
break;
case GL_RGBA:
switch (type)
{
case GL_UNSIGNED_BYTE: return GL_RGBA8_OES;
case GL_UNSIGNED_SHORT_4_4_4_4: return GL_RGBA4;
case GL_UNSIGNED_SHORT_5_5_5_1: return GL_RGB5_A1;
case GL_FLOAT: return GL_RGBA32F_EXT;
case GL_HALF_FLOAT_OES: return GL_RGBA16F_EXT;
break;
default: UNIMPLEMENTED();
}
break;
case GL_BGRA_EXT:
switch (type)
{
// Are there sized internal formats for the packed BGRA types?
case GL_UNSIGNED_BYTE: return GL_BGRA8_EXT;
default: UNIMPLEMENTED();
}
break;
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
return format;
case GL_DEPTH_COMPONENT:
switch (type)
{
case GL_UNSIGNED_SHORT: return GL_DEPTH_COMPONENT16;
case GL_UNSIGNED_INT: return GL_DEPTH_COMPONENT32_OES;
default: UNIMPLEMENTED();
}
break;
case GL_DEPTH_STENCIL_OES:
switch (type)
{
case GL_UNSIGNED_INT_24_8_OES: return GL_DEPTH24_STENCIL8_OES;
default: UNIMPLEMENTED();
}
break;
default:
UNIMPLEMENTED();
}
return GL_NONE;
}
GLenum ExtractFormat(GLenum internalformat) GLenum ExtractFormat(GLenum internalformat)
{ {
switch (internalformat) switch (internalformat)
......
...@@ -34,14 +34,15 @@ int VariableColumnCount(GLenum type); ...@@ -34,14 +34,15 @@ int VariableColumnCount(GLenum type);
int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize); int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize);
int ComputePixelSize(GLenum format, GLenum type); int ComputePixelSize(GLint internalformat);
GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment); GLsizei ComputePitch(GLsizei width, GLint internalformat, GLint alignment);
GLsizei ComputeCompressedPitch(GLsizei width, GLenum format); GLsizei ComputeCompressedPitch(GLsizei width, GLenum format);
GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format); GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format);
bool IsCompressed(GLenum format); bool IsCompressed(GLenum format);
bool IsDepthTexture(GLenum format); bool IsDepthTexture(GLenum format);
bool IsCubemapTextureTarget(GLenum target); bool IsCubemapTextureTarget(GLenum target);
bool IsInternalTextureTarget(GLenum target); bool IsInternalTextureTarget(GLenum target);
GLint ConvertSizedInternalFormat(GLenum format, GLenum type);
GLenum ExtractFormat(GLenum internalformat); GLenum ExtractFormat(GLenum internalformat);
GLenum ExtractType(GLenum internalformat); GLenum ExtractType(GLenum internalformat);
......
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