Retrieve texture width, height and type from the top-level image.

TRAC #15703 Issue=86 Signed-off-by: Daniel Koch Author: Nicolas Capens git-svn-id: https://angleproject.googlecode.com/svn/trunk@584 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent b5a3a6b6
...@@ -40,9 +40,6 @@ Texture::Image::~Image() ...@@ -40,9 +40,6 @@ Texture::Image::~Image()
Texture::Texture(GLuint id) : RefCountObject(id) Texture::Texture(GLuint id) : RefCountObject(id)
{ {
mWidth = 0;
mHeight = 0;
mMinFilter = GL_NEAREST_MIPMAP_LINEAR; mMinFilter = GL_NEAREST_MIPMAP_LINEAR;
mMagFilter = GL_LINEAR; mMagFilter = GL_LINEAR;
mWrapS = GL_REPEAT; mWrapS = GL_REPEAT;
...@@ -50,7 +47,6 @@ Texture::Texture(GLuint id) : RefCountObject(id) ...@@ -50,7 +47,6 @@ Texture::Texture(GLuint id) : RefCountObject(id)
mDirtyParameters = true; mDirtyParameters = true;
mIsRenderable = false; mIsRenderable = false;
mType = GL_UNSIGNED_BYTE;
} }
Texture::~Texture() Texture::~Texture()
...@@ -169,19 +165,9 @@ GLenum Texture::getWrapT() const ...@@ -169,19 +165,9 @@ GLenum Texture::getWrapT() const
return mWrapT; return mWrapT;
} }
GLsizei Texture::getWidth() const
{
return mWidth;
}
GLsizei Texture::getHeight() const
{
return mHeight;
}
bool Texture::isFloatingPoint() const bool Texture::isFloatingPoint() const
{ {
return (mType == GL_FLOAT || mType == GL_HALF_FLOAT_OES); return (getType() == GL_FLOAT || getType() == GL_HALF_FLOAT_OES);
} }
bool Texture::isRenderableFormat() const bool Texture::isRenderableFormat() const
...@@ -796,17 +782,17 @@ void Texture::loadCompressedImageData(GLint xoffset, GLint yoffset, GLsizei widt ...@@ -796,17 +782,17 @@ void Texture::loadCompressedImageData(GLint xoffset, GLint yoffset, GLsizei widt
} }
} }
void Texture::createSurface(GLsizei width, GLsizei height, GLenum format, GLenum type, Image *image) void Texture::createSurface(Image *image)
{ {
IDirect3DTexture9 *newTexture = NULL; IDirect3DTexture9 *newTexture = NULL;
IDirect3DSurface9 *newSurface = NULL; IDirect3DSurface9 *newSurface = NULL;
if (width != 0 && height != 0) if (image->width != 0 && image->height != 0)
{ {
int levelToFetch = 0; int levelToFetch = 0;
GLsizei requestWidth = width; GLsizei requestWidth = image->width;
GLsizei requestHeight = height; GLsizei requestHeight = image->height;
if (IsCompressed(format) && (width % 4 != 0 || height % 4 != 0)) if (IsCompressed(image->format) && (image->width % 4 != 0 || image->height % 4 != 0))
{ {
bool isMult4 = false; bool isMult4 = false;
int upsampleCount = 0; int upsampleCount = 0;
...@@ -823,7 +809,7 @@ void Texture::createSurface(GLsizei width, GLsizei height, GLenum format, GLenum ...@@ -823,7 +809,7 @@ void Texture::createSurface(GLsizei width, GLsizei height, GLenum format, GLenum
levelToFetch = upsampleCount; levelToFetch = upsampleCount;
} }
HRESULT result = getDevice()->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, NULL, selectFormat(format, type), HRESULT result = getDevice()->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, NULL, selectFormat(image->format, image->type),
D3DPOOL_SYSTEMMEM, &newTexture, NULL); D3DPOOL_SYSTEMMEM, &newTexture, NULL);
if (FAILED(result)) if (FAILED(result))
...@@ -842,16 +828,11 @@ void Texture::createSurface(GLsizei width, GLsizei height, GLenum format, GLenum ...@@ -842,16 +828,11 @@ void Texture::createSurface(GLsizei width, GLsizei height, GLenum format, GLenum
} }
image->surface = newSurface; image->surface = newSurface;
image->width = width;
image->height = height;
image->format = format;
image->type = type;
} }
void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image) void Texture::setImage(GLint unpackAlignment, const void *pixels, Image *image)
{ {
createSurface(width, height, format, type, image); createSurface(image);
if (pixels != NULL && image->surface != NULL) if (pixels != NULL && image->surface != NULL)
{ {
...@@ -865,7 +846,7 @@ void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type ...@@ -865,7 +846,7 @@ void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
loadImageData(0, 0, width, height, format, type, unpackAlignment, pixels, locked.Pitch, locked.pBits, &description); loadImageData(0, 0, image->width, image->height, image->format, image->type, unpackAlignment, pixels, locked.Pitch, locked.pBits, &description);
image->surface->UnlockRect(); image->surface->UnlockRect();
} }
...@@ -873,9 +854,9 @@ void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type ...@@ -873,9 +854,9 @@ void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type
} }
} }
void Texture::setCompressedImage(GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *image) void Texture::setCompressedImage(GLsizei imageSize, const void *pixels, Image *image)
{ {
createSurface(width, height, format, GL_UNSIGNED_BYTE, image); createSurface(image);
if (pixels != NULL && image->surface != NULL) if (pixels != NULL && image->surface != NULL)
{ {
...@@ -886,9 +867,9 @@ void Texture::setCompressedImage(GLsizei width, GLsizei height, GLenum format, G ...@@ -886,9 +867,9 @@ void Texture::setCompressedImage(GLsizei width, GLsizei height, GLenum format, G
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
int inputPitch = ComputeCompressedPitch(width, format); int inputPitch = ComputeCompressedPitch(image->width, image->format);
int inputSize = ComputeCompressedSize(width, height, format); int inputSize = ComputeCompressedSize(image->width, image->height, image->format);
loadCompressedImageData(0, 0, width, height, -inputPitch, static_cast<const char*>(pixels) + inputSize - inputPitch, locked.Pitch, locked.pBits); loadCompressedImageData(0, 0, image->width, image->height, -inputPitch, static_cast<const char*>(pixels) + inputSize - inputPitch, locked.Pitch, locked.pBits);
image->surface->UnlockRect(); image->surface->UnlockRect();
} }
...@@ -906,7 +887,7 @@ bool Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei heig ...@@ -906,7 +887,7 @@ bool Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei heig
if (!image->surface) if (!image->surface)
{ {
createSurface(image->width, image->height, format, type, image); createSurface(image);
} }
if (pixels != NULL && image->surface != NULL) if (pixels != NULL && image->surface != NULL)
...@@ -947,7 +928,7 @@ bool Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GL ...@@ -947,7 +928,7 @@ bool Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GL
if (!image->surface) if (!image->surface)
{ {
createSurface(image->width, image->height, format, GL_UNSIGNED_BYTE, image); createSurface(image);
} }
if (pixels != NULL && image->surface != NULL) if (pixels != NULL && image->surface != NULL)
...@@ -1016,7 +997,7 @@ void Texture::copyNonRenderable(Image *image, GLenum format, GLint xoffset, GLin ...@@ -1016,7 +997,7 @@ void Texture::copyNonRenderable(Image *image, GLenum format, GLint xoffset, GLin
if (!image->surface) if (!image->surface)
{ {
createSurface(width, height, format, mType, image); createSurface(image);
} }
if (image->surface == NULL) if (image->surface == NULL)
...@@ -1148,7 +1129,7 @@ void Texture::copyNonRenderable(Image *image, GLenum format, GLint xoffset, GLin ...@@ -1148,7 +1129,7 @@ void Texture::copyNonRenderable(Image *image, GLenum format, GLint xoffset, GLin
D3DFORMAT Texture::getD3DFormat() const D3DFORMAT Texture::getD3DFormat() const
{ {
return selectFormat(getInternalFormat(), mType); return selectFormat(getInternalFormat(), getType());
} }
IDirect3DBaseTexture9 *Texture::getTexture() IDirect3DBaseTexture9 *Texture::getTexture()
...@@ -1173,17 +1154,6 @@ bool Texture::isDirty() const ...@@ -1173,17 +1154,6 @@ bool Texture::isDirty() const
return true;//(mDirty || mDirtyMetaData || dirtyImageData()); return true;//(mDirty || mDirtyMetaData || dirtyImageData());
} }
// Returns the top-level texture surface as a render target
void Texture::needRenderTarget()
{
if (!mIsRenderable)
{
convertToRenderTarget();
}
updateTexture();
}
GLint Texture::creationLevels(GLsizei width, GLsizei height, GLint maxlevel) const GLint Texture::creationLevels(GLsizei width, GLsizei height, GLint maxlevel) const
{ {
if (isPow2(width) && isPow2(height)) if (isPow2(width) && isPow2(height))
...@@ -1228,46 +1198,54 @@ GLenum Texture2D::getTarget() const ...@@ -1228,46 +1198,54 @@ GLenum Texture2D::getTarget() const
return GL_TEXTURE_2D; return GL_TEXTURE_2D;
} }
GLenum Texture2D::getInternalFormat() const GLsizei Texture2D::getWidth() const
{ {
return mImageArray[0].format; return mImageArray[0].width;
} }
// While OpenGL doesn't check texture consistency until draw-time, D3D9 requires a complete texture GLsizei Texture2D::getHeight() const
// for render-to-texture (such as CopyTexImage). We have no way of keeping individual inconsistent levels.
// Call this when a particular level of the texture must be defined with a specific format, width and height.
//
// Returns true if the existing texture was unsuitable and had to be destroyed. If so, it will also set
// a new height and width for the texture by working backwards from the given width and height.
bool Texture2D::redefineTexture(GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type)
{ {
bool widthOkay = (mWidth >> level == width); return mImageArray[0].height;
bool heightOkay = (mHeight >> level == height); }
bool sizeOkay = ((widthOkay && heightOkay) GLenum Texture2D::getInternalFormat() const
|| (widthOkay && mHeight >> level == 0 && height == 1) {
|| (heightOkay && mWidth >> level == 0 && width == 1)); return mImageArray[0].format;
}
bool typeOkay = (type == mType); GLenum Texture2D::getType() const
{
return mImageArray[0].type;
}
bool textureOkay = (sizeOkay && typeOkay && format == mImageArray[0].format); void Texture2D::redefineTexture(GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type)
{
mImageArray[level].width = width;
mImageArray[level].height = height;
mImageArray[level].format = format;
mImageArray[level].type = type;
if (!textureOkay) if (!mTexture)
{ {
TRACE("Redefining 2D texture (%d, 0x%04X, %d, %d => 0x%04X, %d, %d).", level, return;
mImageArray[0].format, mWidth, mHeight, }
format, width, height);
// Purge all the levels and the texture. D3DSURFACE_DESC texture;
mTexture->GetLevelDesc(0, &texture);
bool widthOkay = (texture.Width >> level == width) || (texture.Width >> level == 0 && width == 1);
bool heightOkay = (texture.Height >> level == height) || (texture.Height >> level == 0 && height == 1);
bool textureOkay = (widthOkay && heightOkay && texture.Format == selectFormat(format, type));
if (!textureOkay) // Purge all the levels and the texture.
{
for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
{ {
if (mImageArray[i].surface != NULL) if (mImageArray[i].surface != NULL)
{ {
mImageArray[i].dirty = false;
mImageArray[i].surface->Release(); mImageArray[i].surface->Release();
mImageArray[i].surface = NULL; mImageArray[i].surface = NULL;
mImageArray[i].dirty = true;
} }
} }
...@@ -1277,28 +1255,21 @@ bool Texture2D::redefineTexture(GLint level, GLenum format, GLsizei width, GLsiz ...@@ -1277,28 +1255,21 @@ bool Texture2D::redefineTexture(GLint level, GLenum format, GLsizei width, GLsiz
mTexture = NULL; mTexture = NULL;
mIsRenderable = false; mIsRenderable = false;
} }
mWidth = width << level;
mHeight = height << level;
mImageArray[0].format = format;
mType = type;
} }
return !textureOkay;
} }
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)
{ {
redefineTexture(level, format, width, height, type); redefineTexture(level, format, width, height, type);
Texture::setImage(width, height, format, type, unpackAlignment, pixels, &mImageArray[level]); Texture::setImage(unpackAlignment, pixels, &mImageArray[level]);
} }
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)
{ {
redefineTexture(level, format, width, height, GL_UNSIGNED_BYTE); redefineTexture(level, format, width, height, GL_UNSIGNED_BYTE);
Texture::setCompressedImage(width, height, format, imageSize, pixels, &mImageArray[level]); Texture::setCompressedImage(imageSize, pixels, &mImageArray[level]);
} }
void Texture2D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) void Texture2D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
...@@ -1358,7 +1329,7 @@ void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei ...@@ -1358,7 +1329,7 @@ void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei
return error(GL_OUT_OF_MEMORY); return error(GL_OUT_OF_MEMORY);
} }
bool redefined = redefineTexture(level, format, width, height, GL_UNSIGNED_BYTE); redefineTexture(level, format, width, height, GL_UNSIGNED_BYTE);
if (!isRenderableFormat()) if (!isRenderableFormat())
{ {
...@@ -1366,14 +1337,12 @@ void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei ...@@ -1366,14 +1337,12 @@ void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei
} }
else else
{ {
if (redefined) if (!mTexture || !mIsRenderable)
{ {
convertToRenderTarget(); convertToRenderTarget();
} }
else
{ updateTexture();
needRenderTarget();
}
if (width != 0 && height != 0 && level < levelCount()) if (width != 0 && height != 0 && level < levelCount())
{ {
...@@ -1390,11 +1359,6 @@ void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei ...@@ -1390,11 +1359,6 @@ void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei
dest->Release(); dest->Release();
} }
} }
mImageArray[level].width = width;
mImageArray[level].height = height;
mImageArray[level].format = format;
mImageArray[level].type = GL_UNSIGNED_BYTE;
} }
void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
...@@ -1412,7 +1376,7 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo ...@@ -1412,7 +1376,7 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo
return error(GL_OUT_OF_MEMORY); return error(GL_OUT_OF_MEMORY);
} }
bool redefined = redefineTexture(0, mImageArray[0].format, mImageArray[0].width, mImageArray[0].height, mType); redefineTexture(0, mImageArray[0].format, mImageArray[0].width, mImageArray[0].height, GL_UNSIGNED_BYTE);
if (!isRenderableFormat()) if (!isRenderableFormat())
{ {
...@@ -1420,14 +1384,12 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo ...@@ -1420,14 +1384,12 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo
} }
else else
{ {
if (redefined) if (!mTexture || !mIsRenderable)
{ {
convertToRenderTarget(); convertToRenderTarget();
} }
else
{ updateTexture();
needRenderTarget();
}
if (level < levelCount()) if (level < levelCount())
{ {
...@@ -1542,10 +1504,11 @@ IDirect3DBaseTexture9 *Texture2D::getBaseTexture() const ...@@ -1542,10 +1504,11 @@ IDirect3DBaseTexture9 *Texture2D::getBaseTexture() const
void Texture2D::createTexture() void Texture2D::createTexture()
{ {
IDirect3DDevice9 *device = getDevice(); IDirect3DDevice9 *device = getDevice();
D3DFORMAT format = selectFormat(mImageArray[0].format, mType); D3DFORMAT format = selectFormat(mImageArray[0].format, mImageArray[0].type);
GLint levels = creationLevels(mImageArray[0].width, mImageArray[0].height, 0);
IDirect3DTexture9 *texture = NULL; IDirect3DTexture9 *texture = NULL;
HRESULT result = device->CreateTexture(mWidth, mHeight, creationLevels(mWidth, mHeight, 0), 0, format, D3DPOOL_DEFAULT, &texture, NULL); HRESULT result = device->CreateTexture(mImageArray[0].width, mImageArray[0].height, levels, 0, format, D3DPOOL_DEFAULT, &texture, NULL);
if (FAILED(result)) if (FAILED(result))
{ {
...@@ -1570,7 +1533,7 @@ void Texture2D::updateTexture() ...@@ -1570,7 +1533,7 @@ void Texture2D::updateTexture()
for (int level = 0; level < levels; level++) for (int level = 0; level < levels; level++)
{ {
if (mImageArray[level].dirty) if (mImageArray[level].surface && mImageArray[level].dirty)
{ {
IDirect3DSurface9 *levelSurface = NULL; IDirect3DSurface9 *levelSurface = NULL;
HRESULT result = mTexture->GetSurfaceLevel(level, &levelSurface); HRESULT result = mTexture->GetSurfaceLevel(level, &levelSurface);
...@@ -1594,13 +1557,14 @@ void Texture2D::convertToRenderTarget() ...@@ -1594,13 +1557,14 @@ void Texture2D::convertToRenderTarget()
{ {
IDirect3DTexture9 *texture = NULL; IDirect3DTexture9 *texture = NULL;
if (mWidth != 0 && mHeight != 0) if (mImageArray[0].width != 0 && mImageArray[0].height != 0)
{ {
egl::Display *display = getDisplay(); egl::Display *display = getDisplay();
IDirect3DDevice9 *device = getDevice(); IDirect3DDevice9 *device = getDevice();
D3DFORMAT format = selectFormat(mImageArray[0].format, mType); D3DFORMAT format = selectFormat(mImageArray[0].format, mImageArray[0].type);
GLint levels = creationLevels(mImageArray[0].width, mImageArray[0].height, 0);
HRESULT result = device->CreateTexture(mWidth, mHeight, creationLevels(mWidth, mHeight, 0), D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &texture, NULL); HRESULT result = device->CreateTexture(mImageArray[0].width, mImageArray[0].height, levels, D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &texture, NULL);
if (FAILED(result)) if (FAILED(result))
{ {
...@@ -1675,7 +1639,7 @@ void Texture2D::generateMipmaps() ...@@ -1675,7 +1639,7 @@ void Texture2D::generateMipmaps()
} }
// Purge array levels 1 through q and reset them to represent the generated mipmap levels. // Purge array levels 1 through q and reset them to represent the generated mipmap levels.
unsigned int q = log2(std::max(mWidth, mHeight)); unsigned int q = log2(std::max(mImageArray[0].width, mImageArray[0].height));
for (unsigned int i = 1; i <= q; i++) for (unsigned int i = 1; i <= q; i++)
{ {
if (mImageArray[i].surface != NULL) if (mImageArray[i].surface != NULL)
...@@ -1684,8 +1648,6 @@ void Texture2D::generateMipmaps() ...@@ -1684,8 +1648,6 @@ void Texture2D::generateMipmaps()
mImageArray[i].surface = NULL; mImageArray[i].surface = NULL;
} }
mImageArray[i].dirty = false;
mImageArray[i].width = std::max(mImageArray[0].width >> i, 1); mImageArray[i].width = std::max(mImageArray[0].width >> i, 1);
mImageArray[i].height = std::max(mImageArray[0].height >> i, 1); mImageArray[i].height = std::max(mImageArray[0].height >> i, 1);
mImageArray[i].format = mImageArray[0].format; mImageArray[i].format = mImageArray[0].format;
...@@ -1715,13 +1677,16 @@ void Texture2D::generateMipmaps() ...@@ -1715,13 +1677,16 @@ void Texture2D::generateMipmaps()
if (upper != NULL) upper->Release(); if (upper != NULL) upper->Release();
if (lower != NULL) lower->Release(); if (lower != NULL) lower->Release();
mImageArray[i].dirty = false;
} }
} }
else else
{ {
for (unsigned int i = 1; i <= q; i++) for (unsigned int i = 1; i <= q; i++)
{ {
createSurface(mImageArray[i].width, mImageArray[i].height, mImageArray[i].format, mType, &mImageArray[i]); createSurface(&mImageArray[i]);
if (mImageArray[i].surface == NULL) if (mImageArray[i].surface == NULL)
{ {
return error(GL_OUT_OF_MEMORY); return error(GL_OUT_OF_MEMORY);
...@@ -1756,13 +1721,18 @@ IDirect3DSurface9 *Texture2D::getRenderTarget(GLenum target) ...@@ -1756,13 +1721,18 @@ IDirect3DSurface9 *Texture2D::getRenderTarget(GLenum target)
{ {
ASSERT(target == GL_TEXTURE_2D); ASSERT(target == GL_TEXTURE_2D);
needRenderTarget(); if (!mIsRenderable)
{
convertToRenderTarget();
}
if (mTexture == NULL) if (mTexture == NULL)
{ {
return NULL; return NULL;
} }
updateTexture();
IDirect3DSurface9 *renderTarget = NULL; IDirect3DSurface9 *renderTarget = NULL;
mTexture->GetSurfaceLevel(0, &renderTarget); mTexture->GetSurfaceLevel(0, &renderTarget);
...@@ -1793,11 +1763,26 @@ GLenum TextureCubeMap::getTarget() const ...@@ -1793,11 +1763,26 @@ GLenum TextureCubeMap::getTarget() const
return GL_TEXTURE_CUBE_MAP; return GL_TEXTURE_CUBE_MAP;
} }
GLsizei TextureCubeMap::getWidth() const
{
return mImageArray[0][0].width;
}
GLsizei TextureCubeMap::getHeight() const
{
return mImageArray[0][0].height;
}
GLenum TextureCubeMap::getInternalFormat() const GLenum TextureCubeMap::getInternalFormat() const
{ {
return mImageArray[0][0].format; return mImageArray[0][0].format;
} }
GLenum TextureCubeMap::getType() const
{
return mImageArray[0][0].type;
}
void TextureCubeMap::setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) void TextureCubeMap::setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
{ {
setImage(0, level, width, height, format, type, unpackAlignment, pixels); setImage(0, level, width, height, format, type, unpackAlignment, pixels);
...@@ -1830,9 +1815,9 @@ void TextureCubeMap::setImageNegZ(GLint level, GLsizei width, GLsizei height, GL ...@@ -1830,9 +1815,9 @@ 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)
{ {
redefineTexture(level, format, width, GL_UNSIGNED_BYTE); redefineTexture(faceIndex(face), level, format, width, height, GL_UNSIGNED_BYTE);
Texture::setCompressedImage(width, height, format, imageSize, pixels, &mImageArray[faceIndex(face)][level]); Texture::setCompressedImage(imageSize, pixels, &mImageArray[faceIndex(face)][level]);
} }
void TextureCubeMap::commitRect(GLenum faceTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) void TextureCubeMap::commitRect(GLenum faceTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
...@@ -1975,10 +1960,11 @@ IDirect3DBaseTexture9 *TextureCubeMap::getBaseTexture() const ...@@ -1975,10 +1960,11 @@ IDirect3DBaseTexture9 *TextureCubeMap::getBaseTexture() const
void TextureCubeMap::createTexture() void TextureCubeMap::createTexture()
{ {
IDirect3DDevice9 *device = getDevice(); IDirect3DDevice9 *device = getDevice();
D3DFORMAT format = selectFormat(mImageArray[0][0].format, mType); D3DFORMAT format = selectFormat(mImageArray[0][0].format, mImageArray[0][0].type);
GLint levels = creationLevels(mImageArray[0][0].width, 0);
IDirect3DCubeTexture9 *texture = NULL; IDirect3DCubeTexture9 *texture = NULL;
HRESULT result = device->CreateCubeTexture(mWidth, creationLevels(mWidth, 0), 0, format, D3DPOOL_DEFAULT, &texture, NULL); HRESULT result = device->CreateCubeTexture(mImageArray[0][0].width, levels, 0, format, D3DPOOL_DEFAULT, &texture, NULL);
if (FAILED(result)) if (FAILED(result))
{ {
...@@ -2006,7 +1992,7 @@ void TextureCubeMap::updateTexture() ...@@ -2006,7 +1992,7 @@ void TextureCubeMap::updateTexture()
{ {
Image *image = &mImageArray[face][level]; Image *image = &mImageArray[face][level];
if (image->dirty) if (image->surface && image->dirty)
{ {
IDirect3DSurface9 *levelSurface = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level); IDirect3DSurface9 *levelSurface = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level);
ASSERT(levelSurface != NULL); ASSERT(levelSurface != NULL);
...@@ -2029,13 +2015,14 @@ void TextureCubeMap::convertToRenderTarget() ...@@ -2029,13 +2015,14 @@ void TextureCubeMap::convertToRenderTarget()
{ {
IDirect3DCubeTexture9 *texture = NULL; IDirect3DCubeTexture9 *texture = NULL;
if (mWidth != 0) if (mImageArray[0][0].width != 0)
{ {
egl::Display *display = getDisplay(); egl::Display *display = getDisplay();
IDirect3DDevice9 *device = getDevice(); IDirect3DDevice9 *device = getDevice();
D3DFORMAT format = selectFormat(mImageArray[0][0].format, mType); D3DFORMAT format = selectFormat(mImageArray[0][0].format, mImageArray[0][0].type);
GLint levels = creationLevels(mImageArray[0][0].width, 0);
HRESULT result = device->CreateCubeTexture(mWidth, creationLevels(mWidth, 0), D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &texture, NULL); HRESULT result = device->CreateCubeTexture(mImageArray[0][0].width, levels, D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &texture, NULL);
if (FAILED(result)) if (FAILED(result))
{ {
...@@ -2102,11 +2089,11 @@ void TextureCubeMap::convertToRenderTarget() ...@@ -2102,11 +2089,11 @@ void TextureCubeMap::convertToRenderTarget()
mIsRenderable = true; mIsRenderable = true;
} }
void TextureCubeMap::setImage(int face, 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)
{ {
redefineTexture(level, format, width, type); redefineTexture(faceIndex, level, format, width, height, type);
Texture::setImage(width, height, format, type, unpackAlignment, pixels, &mImageArray[face][level]); Texture::setImage(unpackAlignment, pixels, &mImageArray[faceIndex][level]);
} }
unsigned int TextureCubeMap::faceIndex(GLenum face) unsigned int TextureCubeMap::faceIndex(GLenum face)
...@@ -2120,36 +2107,35 @@ unsigned int TextureCubeMap::faceIndex(GLenum face) ...@@ -2120,36 +2107,35 @@ unsigned int TextureCubeMap::faceIndex(GLenum face)
return face - GL_TEXTURE_CUBE_MAP_POSITIVE_X; return face - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
} }
// While OpenGL doesn't check texture consistency until draw-time, D3D9 requires a complete texture void TextureCubeMap::redefineTexture(int face, GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type)
// for render-to-texture (such as CopyTexImage). We have no way of keeping individual inconsistent levels & faces.
// Call this when a particular level of the texture must be defined with a specific format, width and height.
//
// Returns true if the existing texture was unsuitable had to be destroyed. If so, it will also set
// a new size for the texture by working backwards from the given size.
bool TextureCubeMap::redefineTexture(GLint level, GLenum format, GLsizei width, GLenum type)
{ {
// Are these settings compatible with level 0? mImageArray[face][level].width = width;
bool sizeOkay = (mImageArray[0][0].width >> level == width); mImageArray[face][level].height = height;
mImageArray[face][level].format = format;
bool textureOkay = (sizeOkay && format == mImageArray[0][0].format); mImageArray[face][level].type = type;
if (!textureOkay) if (!mTexture)
{ {
TRACE("Redefining cube texture (%d, 0x%04X, %d => 0x%04X, %d).", level, return;
mImageArray[0][0].format, mImageArray[0][0].width, }
format, width);
// Purge all the levels and the texture. D3DSURFACE_DESC texture;
mTexture->GetLevelDesc(0, &texture);
bool sizeOkay = (texture.Width >> level == width);
bool textureOkay = (sizeOkay && texture.Format == selectFormat(format, type));
if (!textureOkay) // Purge all the levels and the texture.
{
for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
{ {
for (int f = 0; f < 6; f++) for (int f = 0; f < 6; f++)
{ {
if (mImageArray[f][i].surface != NULL) if (mImageArray[f][i].surface != NULL)
{ {
mImageArray[f][i].dirty = false;
mImageArray[f][i].surface->Release(); mImageArray[f][i].surface->Release();
mImageArray[f][i].surface = NULL; mImageArray[f][i].surface = NULL;
mImageArray[f][i].dirty = true;
} }
} }
} }
...@@ -2160,17 +2146,7 @@ bool TextureCubeMap::redefineTexture(GLint level, GLenum format, GLsizei width, ...@@ -2160,17 +2146,7 @@ bool TextureCubeMap::redefineTexture(GLint level, GLenum format, GLsizei width,
mTexture = NULL; mTexture = NULL;
mIsRenderable = false; mIsRenderable = false;
} }
mWidth = width << level;
mImageArray[0][0].width = width << level;
mHeight = width << level;
mImageArray[0][0].height = width << level;
mImageArray[0][0].format = format;
mImageArray[0][0].type = type;
} }
return !textureOkay;
} }
void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
...@@ -2184,7 +2160,7 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint ...@@ -2184,7 +2160,7 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint
} }
unsigned int faceindex = faceIndex(target); unsigned int faceindex = faceIndex(target);
bool redefined = redefineTexture(level, format, width, GL_UNSIGNED_BYTE); redefineTexture(faceindex, level, format, width, height, GL_UNSIGNED_BYTE);
if (!isRenderableFormat()) if (!isRenderableFormat())
{ {
...@@ -2192,14 +2168,12 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint ...@@ -2192,14 +2168,12 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint
} }
else else
{ {
if (redefined) if (!mTexture || !mIsRenderable)
{ {
convertToRenderTarget(); convertToRenderTarget();
} }
else
{ updateTexture();
needRenderTarget();
}
ASSERT(width == height); ASSERT(width == height);
...@@ -2217,11 +2191,6 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint ...@@ -2217,11 +2191,6 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint
dest->Release(); dest->Release();
} }
} }
mImageArray[faceindex][level].width = width;
mImageArray[faceindex][level].height = height;
mImageArray[faceindex][level].format = format;
mImageArray[faceindex][level].type = GL_UNSIGNED_BYTE;
} }
IDirect3DSurface9 *TextureCubeMap::getCubeMapSurface(GLenum face, unsigned int level) IDirect3DSurface9 *TextureCubeMap::getCubeMapSurface(GLenum face, unsigned int level)
...@@ -2257,7 +2226,7 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi ...@@ -2257,7 +2226,7 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi
} }
unsigned int faceindex = faceIndex(target); unsigned int faceindex = faceIndex(target);
bool redefined = redefineTexture(0, mImageArray[0][0].format, mImageArray[0][0].width, GL_UNSIGNED_BYTE); redefineTexture(0, 0, mImageArray[0][0].format, mImageArray[0][0].width, mImageArray[0][0].height, GL_UNSIGNED_BYTE);
if (!isRenderableFormat()) if (!isRenderableFormat())
{ {
...@@ -2265,14 +2234,12 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi ...@@ -2265,14 +2234,12 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi
} }
else else
{ {
if (redefined) if (!mTexture || !mIsRenderable)
{ {
convertToRenderTarget(); convertToRenderTarget();
} }
else
{ updateTexture();
needRenderTarget();
}
if (level < levelCount()) if (level < levelCount())
{ {
...@@ -2330,8 +2297,6 @@ void TextureCubeMap::generateMipmaps() ...@@ -2330,8 +2297,6 @@ void TextureCubeMap::generateMipmaps()
mImageArray[f][i].surface = NULL; mImageArray[f][i].surface = NULL;
} }
mImageArray[f][i].dirty = false;
mImageArray[f][i].width = std::max(mImageArray[f][0].width >> i, 1); mImageArray[f][i].width = std::max(mImageArray[f][0].width >> i, 1);
mImageArray[f][i].height = mImageArray[f][i].width; mImageArray[f][i].height = mImageArray[f][i].width;
mImageArray[f][i].format = mImageArray[f][0].format; mImageArray[f][i].format = mImageArray[f][0].format;
...@@ -2360,6 +2325,8 @@ void TextureCubeMap::generateMipmaps() ...@@ -2360,6 +2325,8 @@ void TextureCubeMap::generateMipmaps()
if (upper != NULL) upper->Release(); if (upper != NULL) upper->Release();
if (lower != NULL) lower->Release(); if (lower != NULL) lower->Release();
mImageArray[f][i].dirty = false;
} }
} }
} }
...@@ -2369,7 +2336,7 @@ void TextureCubeMap::generateMipmaps() ...@@ -2369,7 +2336,7 @@ void TextureCubeMap::generateMipmaps()
{ {
for (unsigned int i = 1; i <= q; i++) for (unsigned int i = 1; i <= q; i++)
{ {
createSurface(mImageArray[f][i].width, mImageArray[f][i].height, mImageArray[f][i].format, mType, &mImageArray[f][i]); createSurface(&mImageArray[f][i]);
if (mImageArray[f][i].surface == NULL) if (mImageArray[f][i].surface == NULL)
{ {
return error(GL_OUT_OF_MEMORY); return error(GL_OUT_OF_MEMORY);
...@@ -2407,13 +2374,18 @@ IDirect3DSurface9 *TextureCubeMap::getRenderTarget(GLenum target) ...@@ -2407,13 +2374,18 @@ IDirect3DSurface9 *TextureCubeMap::getRenderTarget(GLenum target)
{ {
ASSERT(IsCubemapTextureTarget(target)); ASSERT(IsCubemapTextureTarget(target));
needRenderTarget(); if (!mIsRenderable)
{
convertToRenderTarget();
}
if (mTexture == NULL) if (mTexture == NULL)
{ {
return NULL; return NULL;
} }
updateTexture();
IDirect3DSurface9 *renderTarget = NULL; IDirect3DSurface9 *renderTarget = NULL;
mTexture->GetCubeMapSurface(es2dx::ConvertCubeFace(target), 0, &renderTarget); mTexture->GetCubeMapSurface(es2dx::ConvertCubeFace(target), 0, &renderTarget);
......
...@@ -57,10 +57,11 @@ class Texture : public RefCountObject ...@@ -57,10 +57,11 @@ class Texture : public RefCountObject
GLenum getWrapS() const; GLenum getWrapS() const;
GLenum getWrapT() const; GLenum getWrapT() const;
GLsizei getWidth() const; virtual GLsizei getWidth() const = 0;
GLsizei getHeight() const; virtual GLsizei getHeight() const = 0;
virtual GLenum getInternalFormat() const = 0; virtual GLenum getInternalFormat() const = 0;
virtual GLenum getType() const = 0;
virtual bool isComplete() const = 0; virtual bool isComplete() const = 0;
virtual bool isCompressed() const = 0; virtual bool isCompressed() const = 0;
bool isFloatingPoint() const; bool isFloatingPoint() const;
...@@ -98,14 +99,12 @@ class Texture : public RefCountObject ...@@ -98,14 +99,12 @@ class Texture : public RefCountObject
static D3DFORMAT selectFormat(GLenum format, GLenum type); static D3DFORMAT selectFormat(GLenum format, GLenum type);
void setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image); void setImage(GLint unpackAlignment, const void *pixels, Image *image);
bool subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image); bool subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image);
void setCompressedImage(GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *image); void setCompressedImage(GLsizei imageSize, const void *pixels, Image *image);
bool subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *image); bool subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *image);
void copyNonRenderable(Image *image, GLenum format, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget); void copyNonRenderable(Image *image, GLenum format, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget);
void needRenderTarget();
GLint creationLevels(GLsizei width, GLsizei height, GLint maxlevel) const; GLint creationLevels(GLsizei width, GLsizei height, GLint maxlevel) const;
GLint creationLevels(GLsizei size, GLint maxlevel) const; GLint creationLevels(GLsizei size, GLint maxlevel) const;
...@@ -115,15 +114,12 @@ class Texture : public RefCountObject ...@@ -115,15 +114,12 @@ class Texture : public RefCountObject
virtual void convertToRenderTarget() = 0; virtual void convertToRenderTarget() = 0;
virtual IDirect3DSurface9 *getRenderTarget(GLenum target) = 0; virtual IDirect3DSurface9 *getRenderTarget(GLenum target) = 0;
void createSurface(GLsizei width, GLsizei height, GLenum format, GLenum type, Image *image); void createSurface(Image *image);
Blit *getBlitter(); Blit *getBlitter();
int levelCount() const; int levelCount() const;
GLsizei mWidth;
GLsizei mHeight;
GLenum mMinFilter; GLenum mMinFilter;
GLenum mMagFilter; GLenum mMagFilter;
GLenum mWrapS; GLenum mWrapS;
...@@ -131,7 +127,6 @@ class Texture : public RefCountObject ...@@ -131,7 +127,6 @@ class Texture : public RefCountObject
bool mDirtyParameters; bool mDirtyParameters;
bool mIsRenderable; bool mIsRenderable;
GLenum mType;
private: private:
DISALLOW_COPY_AND_ASSIGN(Texture); DISALLOW_COPY_AND_ASSIGN(Texture);
...@@ -189,7 +184,11 @@ class Texture2D : public Texture ...@@ -189,7 +184,11 @@ class Texture2D : public Texture
~Texture2D(); ~Texture2D();
GLenum getTarget() const; GLenum getTarget() const;
GLenum getInternalFormat() const;
virtual GLsizei getWidth() const;
virtual GLsizei getHeight() const;
virtual GLenum getInternalFormat() const;
virtual GLenum getType() const;
void setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); void setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
...@@ -214,7 +213,7 @@ class Texture2D : public Texture ...@@ -214,7 +213,7 @@ class Texture2D : public Texture
virtual void convertToRenderTarget(); virtual void convertToRenderTarget();
virtual IDirect3DSurface9 *getRenderTarget(GLenum target); virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
bool redefineTexture(GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type); void redefineTexture(GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type);
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];
...@@ -231,8 +230,12 @@ class TextureCubeMap : public Texture ...@@ -231,8 +230,12 @@ class TextureCubeMap : public Texture
~TextureCubeMap(); ~TextureCubeMap();
GLenum getTarget() const; virtual GLenum getTarget() const;
GLenum getInternalFormat() const;
virtual GLsizei getWidth() const;
virtual GLsizei getHeight() const;
virtual GLenum getInternalFormat() const;
virtual GLenum getType() const;
void setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); void setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
void setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); void setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
...@@ -272,9 +275,9 @@ class TextureCubeMap : public Texture ...@@ -272,9 +275,9 @@ class TextureCubeMap : public Texture
bool isCubeComplete() const; bool isCubeComplete() const;
void setImage(int face, 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(GLenum faceTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); void commitRect(GLenum faceTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
bool redefineTexture(GLint level, GLenum format, GLsizei width, GLenum type); void redefineTexture(int faceIndex, GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type);
Image mImageArray[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS]; Image mImageArray[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS];
......
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