Creating a 0x0 texture fails.

TRAC #11792 Signed-off-by: Nicolas Capens Signed-off-by: Daniel Koch Author: Andrew Lewycky git-svn-id: https://angleproject.googlecode.com/svn/trunk@150 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent aa1ff879
...@@ -294,12 +294,16 @@ void Texture::loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei ...@@ -294,12 +294,16 @@ void Texture::loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei
void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img) void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img)
{ {
IDirect3DSurface9 *newSurface = NULL; IDirect3DSurface9 *newSurface = NULL;
HRESULT result = getDevice()->CreateOffscreenPlainSurface(width, height, selectFormat(format), D3DPOOL_SYSTEMMEM, &newSurface, NULL);
if (FAILED(result)) if (width != 0 && height != 0)
{ {
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); HRESULT result = getDevice()->CreateOffscreenPlainSurface(width, height, selectFormat(format), D3DPOOL_SYSTEMMEM, &newSurface, NULL);
return error(GL_OUT_OF_MEMORY);
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
return error(GL_OUT_OF_MEMORY);
}
} }
if (img->surface) img->surface->Release(); if (img->surface) img->surface->Release();
...@@ -309,7 +313,7 @@ void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type ...@@ -309,7 +313,7 @@ void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type
img->height = height; img->height = height;
img->format = format; img->format = format;
if (pixels != NULL) if (pixels != NULL && newSurface != NULL)
{ {
D3DLOCKED_RECT locked; D3DLOCKED_RECT locked;
HRESULT result = newSurface->LockRect(&locked, NULL, 0); HRESULT result = newSurface->LockRect(&locked, NULL, 0);
...@@ -541,17 +545,20 @@ void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, ...@@ -541,17 +545,20 @@ void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y,
pushTexture(mTexture); pushTexture(mTexture);
} }
RECT sourceRect; if (width != 0 && height != 0)
sourceRect.left = x; {
sourceRect.top = y + height; RECT sourceRect;
sourceRect.right = x + width; sourceRect.left = x;
sourceRect.bottom = y; sourceRect.top = y + height;
sourceRect.right = x + width;
sourceRect.bottom = y;
IDirect3DSurface9 *dest; IDirect3DSurface9 *dest;
HRESULT hr = mTexture->GetSurfaceLevel(level, &dest); HRESULT hr = mTexture->GetSurfaceLevel(level, &dest);
getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, internalFormat, 0, 0, dest); getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, internalFormat, 0, 0, dest);
dest->Release(); dest->Release();
}
mImageArray[level].width = width; mImageArray[level].width = width;
mImageArray[level].height = height; mImageArray[level].height = height;
...@@ -560,6 +567,11 @@ void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, ...@@ -560,6 +567,11 @@ void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y,
void Texture2D::copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source) void Texture2D::copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
{ {
if (xoffset + width > mImageArray[level].width || yoffset + height > mImageArray[level].height)
{
return error(GL_INVALID_VALUE);
}
if (redefineTexture(0, mImageArray[0].format, mImageArray[0].width, mImageArray[0].height)) if (redefineTexture(0, mImageArray[0].format, mImageArray[0].width, mImageArray[0].height))
{ {
convertToRenderTarget(); convertToRenderTarget();
...@@ -687,66 +699,72 @@ void Texture2D::updateTexture() ...@@ -687,66 +699,72 @@ void Texture2D::updateTexture()
IDirect3DBaseTexture9 *Texture2D::convertToRenderTarget() IDirect3DBaseTexture9 *Texture2D::convertToRenderTarget()
{ {
IDirect3DTexture9 *texture; IDirect3DTexture9 *texture = NULL;
IDirect3DDevice9 *device = getDevice();
D3DFORMAT format = selectFormat(mImageArray[0].format);
HRESULT result = device->CreateTexture(mWidth, mHeight, 0, D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &texture, NULL); if (mWidth != 0 && mHeight != 0)
if (FAILED(result))
{ {
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); IDirect3DDevice9 *device = getDevice();
return error(GL_OUT_OF_MEMORY, (IDirect3DBaseTexture9*)NULL); D3DFORMAT format = selectFormat(mImageArray[0].format);
}
if (mTexture != NULL) HRESULT result = device->CreateTexture(mWidth, mHeight, 0, D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &texture, NULL);
{
int levels = texture->GetLevelCount(); if (FAILED(result))
for (int i = 0; i < levels; i++)
{ {
IDirect3DSurface9 *source; ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
result = mTexture->GetSurfaceLevel(i, &source); return error(GL_OUT_OF_MEMORY, (IDirect3DBaseTexture9*)NULL);
}
if (FAILED(result)) if (mTexture != NULL)
{
int levels = texture->GetLevelCount();
for (int i = 0; i < levels; i++)
{ {
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); IDirect3DSurface9 *source;
result = mTexture->GetSurfaceLevel(i, &source);
texture->Release(); if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
return error(GL_OUT_OF_MEMORY, (IDirect3DBaseTexture9*)NULL); texture->Release();
}
IDirect3DSurface9 *dest; return error(GL_OUT_OF_MEMORY, (IDirect3DBaseTexture9*)NULL);
result = texture->GetSurfaceLevel(i, &dest); }
if (FAILED(result)) IDirect3DSurface9 *dest;
{ result = texture->GetSurfaceLevel(i, &dest);
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
texture->Release(); if (FAILED(result))
source->Release(); {
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
return error(GL_OUT_OF_MEMORY, (IDirect3DBaseTexture9*)NULL); texture->Release();
} source->Release();
result = device->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE); return error(GL_OUT_OF_MEMORY, (IDirect3DBaseTexture9*)NULL);
}
if (FAILED(result)) result = device->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE);
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
texture->Release();
source->Release();
dest->Release();
return error(GL_OUT_OF_MEMORY, (IDirect3DBaseTexture9*)NULL);
}
texture->Release();
source->Release(); source->Release();
dest->Release(); dest->Release();
return error(GL_OUT_OF_MEMORY, (IDirect3DBaseTexture9*)NULL);
} }
source->Release();
dest->Release();
} }
}
if (mTexture != NULL)
{
mTexture->Release(); mTexture->Release();
} }
...@@ -983,66 +1001,72 @@ void TextureCubeMap::updateTexture() ...@@ -983,66 +1001,72 @@ void TextureCubeMap::updateTexture()
IDirect3DBaseTexture9 *TextureCubeMap::convertToRenderTarget() IDirect3DBaseTexture9 *TextureCubeMap::convertToRenderTarget()
{ {
IDirect3DCubeTexture9 *texture; IDirect3DCubeTexture9 *texture = NULL;
IDirect3DDevice9 *device = getDevice(); if (mWidth != 0)
D3DFORMAT format = selectFormat(mImageArray[0][0].format); {
IDirect3DDevice9 *device = getDevice();
D3DFORMAT format = selectFormat(mImageArray[0][0].format);
HRESULT result = device->CreateCubeTexture(mWidth, 0, D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &texture, NULL); HRESULT result = device->CreateCubeTexture(mWidth, 0, D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &texture, NULL);
if (FAILED(result)) if (FAILED(result))
{ {
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
return error(GL_OUT_OF_MEMORY, (IDirect3DBaseTexture9*)NULL); return error(GL_OUT_OF_MEMORY, (IDirect3DBaseTexture9*)NULL);
} }
if (mTexture != NULL) if (mTexture != NULL)
{
int levels = texture->GetLevelCount();
for (int f = 0; f < 6; f++)
{ {
for (int i = 0; i < levels; i++) int levels = texture->GetLevelCount();
for (int f = 0; f < 6; f++)
{ {
IDirect3DSurface9 *source; for (int i = 0; i < levels; i++)
result = mTexture->GetCubeMapSurface(static_cast<D3DCUBEMAP_FACES>(f), i, &source);
if (FAILED(result))
{ {
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); IDirect3DSurface9 *source;
result = mTexture->GetCubeMapSurface(static_cast<D3DCUBEMAP_FACES>(f), i, &source);
texture->Release(); if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
return error(GL_OUT_OF_MEMORY, (IDirect3DBaseTexture9*)NULL); texture->Release();
}
IDirect3DSurface9 *dest; return error(GL_OUT_OF_MEMORY, (IDirect3DBaseTexture9*)NULL);
result = texture->GetCubeMapSurface(static_cast<D3DCUBEMAP_FACES>(f), i, &dest); }
if (FAILED(result)) IDirect3DSurface9 *dest;
{ result = texture->GetCubeMapSurface(static_cast<D3DCUBEMAP_FACES>(f), i, &dest);
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
texture->Release(); if (FAILED(result))
source->Release(); {
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
return error(GL_OUT_OF_MEMORY, (IDirect3DBaseTexture9*)NULL); texture->Release();
} source->Release();
result = device->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE); return error(GL_OUT_OF_MEMORY, (IDirect3DBaseTexture9*)NULL);
}
if (FAILED(result)) result = device->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE);
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
texture->Release(); if (FAILED(result))
source->Release(); {
dest->Release(); ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
return error(GL_OUT_OF_MEMORY, (IDirect3DBaseTexture9*)NULL); texture->Release();
source->Release();
dest->Release();
return error(GL_OUT_OF_MEMORY, (IDirect3DBaseTexture9*)NULL);
}
} }
} }
} }
}
if (mTexture != NULL)
{
mTexture->Release(); mTexture->Release();
} }
...@@ -1154,16 +1178,21 @@ void TextureCubeMap::copyImage(GLenum face, GLint level, GLenum internalFormat, ...@@ -1154,16 +1178,21 @@ void TextureCubeMap::copyImage(GLenum face, GLint level, GLenum internalFormat,
pushTexture(mTexture); pushTexture(mTexture);
} }
RECT sourceRect; ASSERT(width == height);
sourceRect.left = x;
sourceRect.top = y + height;
sourceRect.right = x + width;
sourceRect.bottom = y;
IDirect3DSurface9 *dest = getCubeMapSurface(face, level); if (width > 0)
{
RECT sourceRect;
sourceRect.left = x;
sourceRect.top = y + height;
sourceRect.right = x + width;
sourceRect.bottom = y;
getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, internalFormat, 0, 0, dest); IDirect3DSurface9 *dest = getCubeMapSurface(face, level);
dest->Release();
getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, internalFormat, 0, 0, dest);
dest->Release();
}
mImageArray[faceindex][level].width = width; mImageArray[faceindex][level].width = width;
mImageArray[faceindex][level].height = height; mImageArray[faceindex][level].height = height;
...@@ -1203,6 +1232,13 @@ IDirect3DSurface9 *TextureCubeMap::getCubeMapSurface(unsigned int faceIdentifier ...@@ -1203,6 +1232,13 @@ IDirect3DSurface9 *TextureCubeMap::getCubeMapSurface(unsigned int faceIdentifier
void TextureCubeMap::copySubImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source) void TextureCubeMap::copySubImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
{ {
GLsizei size = mImageArray[faceIndex(face)][level].width;
if (xoffset + width > size || yoffset + height > size)
{
return error(GL_INVALID_VALUE);
}
if (redefineTexture(0, mImageArray[0][0].format, mImageArray[0][0].width)) if (redefineTexture(0, mImageArray[0][0].format, mImageArray[0][0].width))
{ {
convertToRenderTarget(); convertToRenderTarget();
......
...@@ -822,7 +822,7 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma ...@@ -822,7 +822,7 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
if (!gl::isPow2(width) || !gl::isPow2(height)) if (width != height)
{ {
return error(GL_INVALID_VALUE); return error(GL_INVALID_VALUE);
} }
...@@ -3506,7 +3506,7 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL ...@@ -3506,7 +3506,7 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
if (!gl::isPow2(width) || !gl::isPow2(height)) if (width != height)
{ {
return error(GL_INVALID_VALUE); return error(GL_INVALID_VALUE);
} }
......
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