When NONPOW2CONDITIONAL is set, limit NPOTs to a single level.

TRAC #12250 Signed-off-by: Nicolas Capens Signed-off-by: Daniel Koch Author: Andrew Lewycky git-svn-id: https://angleproject.googlecode.com/svn/trunk@283 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 4af7acca
...@@ -214,12 +214,28 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface) ...@@ -214,12 +214,28 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
{ {
IDirect3DDevice9 *device = display->getDevice(); IDirect3DDevice9 *device = display->getDevice();
if (!mBufferBackEnd) if (!mHasBeenCurrent)
{ {
device->GetDeviceCaps(&mDeviceCaps);
mBufferBackEnd = new Dx9BackEnd(device); mBufferBackEnd = new Dx9BackEnd(device);
mVertexDataManager = new VertexDataManager(this, mBufferBackEnd); mVertexDataManager = new VertexDataManager(this, mBufferBackEnd);
mIndexDataManager = new IndexDataManager(this, mBufferBackEnd); mIndexDataManager = new IndexDataManager(this, mBufferBackEnd);
mBlit = new Blit(this); mBlit = new Blit(this);
initExtensionString();
mState.viewportX = 0;
mState.viewportY = 0;
mState.viewportWidth = surface->getWidth();
mState.viewportHeight = surface->getHeight();
mState.scissorX = 0;
mState.scissorY = 0;
mState.scissorWidth = surface->getWidth();
mState.scissorHeight = surface->getHeight();
mHasBeenCurrent = true;
} }
// Wrap the existing Direct3D 9 resources into GL objects and assign them to the '0' names // Wrap the existing Direct3D 9 resources into GL objects and assign them to the '0' names
...@@ -240,23 +256,6 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface) ...@@ -240,23 +256,6 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
framebufferZero->setDepthbuffer(GL_RENDERBUFFER, 0); framebufferZero->setDepthbuffer(GL_RENDERBUFFER, 0);
framebufferZero->setStencilbuffer(GL_RENDERBUFFER, 0); framebufferZero->setStencilbuffer(GL_RENDERBUFFER, 0);
if (!mHasBeenCurrent)
{
initExtensionString();
mState.viewportX = 0;
mState.viewportY = 0;
mState.viewportWidth = surface->getWidth();
mState.viewportHeight = surface->getHeight();
mState.scissorX = 0;
mState.scissorY = 0;
mState.scissorWidth = surface->getWidth();
mState.scissorHeight = surface->getHeight();
mHasBeenCurrent = true;
}
defaultRenderTarget->Release(); defaultRenderTarget->Release();
if (depthStencil) if (depthStencil)
......
...@@ -379,6 +379,8 @@ class Context ...@@ -379,6 +379,8 @@ class Context
Blit *getBlitter() { return mBlit; } Blit *getBlitter() { return mBlit; }
const D3DCAPS9 &getDeviceCaps() { return mDeviceCaps; }
private: private:
DISALLOW_COPY_AND_ASSIGN(Context); DISALLOW_COPY_AND_ASSIGN(Context);
...@@ -464,6 +466,8 @@ class Context ...@@ -464,6 +466,8 @@ class Context
bool mSampleStateDirty; bool mSampleStateDirty;
bool mFrontFaceDirty; bool mFrontFaceDirty;
bool mDitherStateDirty; bool mDitherStateDirty;
D3DCAPS9 mDeviceCaps;
}; };
} }
......
...@@ -418,6 +418,29 @@ void Texture::pushTexture(IDirect3DBaseTexture9 *newTexture, bool renderable) ...@@ -418,6 +418,29 @@ void Texture::pushTexture(IDirect3DBaseTexture9 *newTexture, bool renderable)
} }
GLint Texture::creationLevels(GLsizei width, GLsizei height, GLint maxlevel) const
{
if (isPow2(width) && isPow2(height))
{
return maxlevel;
}
else
{
// One of the restrictions of NONPOW2CONDITIONAL is that NPOTs may only have a single level.
return (getContext()->getDeviceCaps().TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) ? 1 : maxlevel;
}
}
GLint Texture::creationLevels(GLsizei size, GLint maxlevel) const
{
return creationLevels(size, size, maxlevel);
}
int Texture::levelCount() const
{
return mBaseTexture ? mBaseTexture->GetLevelCount() : 0;
}
Texture2D::Texture2D(Context *context) : Texture(context) Texture2D::Texture2D(Context *context) : Texture(context)
{ {
mTexture = NULL; mTexture = NULL;
...@@ -502,7 +525,7 @@ void Texture2D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei wi ...@@ -502,7 +525,7 @@ void Texture2D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei wi
{ {
ASSERT(mImageArray[level].surface != NULL); ASSERT(mImageArray[level].surface != NULL);
if (mTexture != NULL) if (level < levelCount())
{ {
IDirect3DSurface9 *destLevel = NULL; IDirect3DSurface9 *destLevel = NULL;
HRESULT result = mTexture->GetSurfaceLevel(level, &destLevel); HRESULT result = mTexture->GetSurfaceLevel(level, &destLevel);
...@@ -547,7 +570,7 @@ void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, ...@@ -547,7 +570,7 @@ void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y,
pushTexture(mTexture, true); pushTexture(mTexture, true);
} }
if (width != 0 && height != 0) if (width != 0 && height != 0 && level < levelCount())
{ {
RECT sourceRect; RECT sourceRect;
sourceRect.left = x; sourceRect.left = x;
...@@ -584,17 +607,20 @@ void Texture2D::copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x, ...@@ -584,17 +607,20 @@ void Texture2D::copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x,
needRenderTarget(); needRenderTarget();
} }
RECT sourceRect; if (level < levelCount())
sourceRect.left = x; {
sourceRect.right = x + width; RECT sourceRect;
sourceRect.top = y; sourceRect.left = x;
sourceRect.bottom = y + height; sourceRect.right = x + width;
sourceRect.top = y;
sourceRect.bottom = y + height;
IDirect3DSurface9 *dest; IDirect3DSurface9 *dest;
HRESULT hr = mTexture->GetSurfaceLevel(level, &dest); HRESULT hr = mTexture->GetSurfaceLevel(level, &dest);
getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, mImageArray[0].format, xoffset, yoffset, dest); getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, mImageArray[0].format, xoffset, yoffset, dest);
dest->Release(); dest->Release();
}
} }
// Tests for GL texture object completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81. // Tests for GL texture object completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
...@@ -665,7 +691,7 @@ IDirect3DBaseTexture9 *Texture2D::createTexture() ...@@ -665,7 +691,7 @@ IDirect3DBaseTexture9 *Texture2D::createTexture()
IDirect3DDevice9 *device = getDevice(); IDirect3DDevice9 *device = getDevice();
D3DFORMAT format = selectFormat(mImageArray[0].format); D3DFORMAT format = selectFormat(mImageArray[0].format);
HRESULT result = device->CreateTexture(mWidth, mHeight, 0, 0, format, D3DPOOL_DEFAULT, &texture, NULL); HRESULT result = device->CreateTexture(mWidth, mHeight, creationLevels(mWidth, mHeight, 0), 0, format, D3DPOOL_DEFAULT, &texture, NULL);
if (FAILED(result)) if (FAILED(result))
{ {
...@@ -682,9 +708,9 @@ void Texture2D::updateTexture() ...@@ -682,9 +708,9 @@ void Texture2D::updateTexture()
{ {
IDirect3DDevice9 *device = getDevice(); IDirect3DDevice9 *device = getDevice();
int levelCount = mTexture->GetLevelCount(); int levels = levelCount();
for (int level = 0; level < levelCount; level++) for (int level = 0; level < levels; level++)
{ {
if (mImageArray[level].dirty) if (mImageArray[level].dirty)
{ {
...@@ -716,7 +742,7 @@ IDirect3DBaseTexture9 *Texture2D::convertToRenderTarget() ...@@ -716,7 +742,7 @@ IDirect3DBaseTexture9 *Texture2D::convertToRenderTarget()
IDirect3DDevice9 *device = getDevice(); IDirect3DDevice9 *device = getDevice();
D3DFORMAT format = selectFormat(mImageArray[0].format); D3DFORMAT format = selectFormat(mImageArray[0].format);
HRESULT result = device->CreateTexture(mWidth, mHeight, 0, D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &texture, NULL); HRESULT result = device->CreateTexture(mWidth, mHeight, creationLevels(mWidth, mHeight, 0), D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &texture, NULL);
if (FAILED(result)) if (FAILED(result))
{ {
...@@ -726,7 +752,7 @@ IDirect3DBaseTexture9 *Texture2D::convertToRenderTarget() ...@@ -726,7 +752,7 @@ IDirect3DBaseTexture9 *Texture2D::convertToRenderTarget()
if (mTexture != NULL) if (mTexture != NULL)
{ {
int levels = texture->GetLevelCount(); int levels = levelCount();
for (int i = 0; i < levels; i++) for (int i = 0; i < levels; i++)
{ {
IDirect3DSurface9 *source; IDirect3DSurface9 *source;
...@@ -931,7 +957,7 @@ void TextureCubeMap::commitRect(GLenum faceTarget, GLint level, GLint xoffset, G ...@@ -931,7 +957,7 @@ void TextureCubeMap::commitRect(GLenum faceTarget, GLint level, GLint xoffset, G
ASSERT(mImageArray[face][level].surface != NULL); ASSERT(mImageArray[face][level].surface != NULL);
if (mTexture != NULL) if (level < levelCount())
{ {
IDirect3DSurface9 *destLevel = getCubeMapSurface(face, level); IDirect3DSurface9 *destLevel = getCubeMapSurface(face, level);
ASSERT(destLevel != NULL); ASSERT(destLevel != NULL);
...@@ -1040,7 +1066,7 @@ IDirect3DBaseTexture9 *TextureCubeMap::createTexture() ...@@ -1040,7 +1066,7 @@ IDirect3DBaseTexture9 *TextureCubeMap::createTexture()
IDirect3DCubeTexture9 *texture; IDirect3DCubeTexture9 *texture;
HRESULT result = device->CreateCubeTexture(mWidth, 0, 0, format, D3DPOOL_DEFAULT, &texture, NULL); HRESULT result = device->CreateCubeTexture(mWidth, creationLevels(mWidth, 0), 0, format, D3DPOOL_DEFAULT, &texture, NULL);
if (FAILED(result)) if (FAILED(result))
{ {
...@@ -1060,7 +1086,8 @@ void TextureCubeMap::updateTexture() ...@@ -1060,7 +1086,8 @@ void TextureCubeMap::updateTexture()
for (int face = 0; face < 6; face++) for (int face = 0; face < 6; face++)
{ {
for (int level = 0; level <= log2(mWidth); level++) int levels = levelCount();
for (int level = 0; level < levels; level++)
{ {
Image *img = &mImageArray[face][level]; Image *img = &mImageArray[face][level];
...@@ -1093,7 +1120,7 @@ IDirect3DBaseTexture9 *TextureCubeMap::convertToRenderTarget() ...@@ -1093,7 +1120,7 @@ IDirect3DBaseTexture9 *TextureCubeMap::convertToRenderTarget()
IDirect3DDevice9 *device = getDevice(); IDirect3DDevice9 *device = getDevice();
D3DFORMAT format = selectFormat(mImageArray[0][0].format); 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, creationLevels(mWidth, 0), D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &texture, NULL);
if (FAILED(result)) if (FAILED(result))
{ {
...@@ -1103,7 +1130,7 @@ IDirect3DBaseTexture9 *TextureCubeMap::convertToRenderTarget() ...@@ -1103,7 +1130,7 @@ IDirect3DBaseTexture9 *TextureCubeMap::convertToRenderTarget()
if (mTexture != NULL) if (mTexture != NULL)
{ {
int levels = texture->GetLevelCount(); int levels = levelCount();
for (int f = 0; f < 6; f++) for (int f = 0; f < 6; f++)
{ {
for (int i = 0; i < levels; i++) for (int i = 0; i < levels; i++)
...@@ -1257,7 +1284,7 @@ void TextureCubeMap::copyImage(GLenum face, GLint level, GLenum internalFormat, ...@@ -1257,7 +1284,7 @@ void TextureCubeMap::copyImage(GLenum face, GLint level, GLenum internalFormat,
ASSERT(width == height); ASSERT(width == height);
if (width > 0) if (width > 0 && level < levelCount())
{ {
RECT sourceRect; RECT sourceRect;
sourceRect.left = x; sourceRect.left = x;
...@@ -1326,16 +1353,19 @@ void TextureCubeMap::copySubImage(GLenum face, GLint level, GLint xoffset, GLint ...@@ -1326,16 +1353,19 @@ void TextureCubeMap::copySubImage(GLenum face, GLint level, GLint xoffset, GLint
getRenderTarget(face); getRenderTarget(face);
} }
RECT sourceRect; if (level < levelCount())
sourceRect.left = x; {
sourceRect.right = x + width; RECT sourceRect;
sourceRect.top = y; sourceRect.left = x;
sourceRect.bottom = y + height; sourceRect.right = x + width;
sourceRect.top = y;
sourceRect.bottom = y + height;
IDirect3DSurface9 *dest = getCubeMapSurface(face, level); IDirect3DSurface9 *dest = getCubeMapSurface(face, level);
getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, mImageArray[0][0].format, xoffset, yoffset, dest); getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, mImageArray[0][0].format, xoffset, yoffset, dest);
dest->Release(); dest->Release();
}
} }
bool TextureCubeMap::isCubeComplete() const bool TextureCubeMap::isCubeComplete() const
......
...@@ -111,6 +111,9 @@ class Texture ...@@ -111,6 +111,9 @@ class Texture
void needRenderTarget(); void needRenderTarget();
GLint creationLevels(GLsizei width, GLsizei height, GLint maxlevel) const;
GLint creationLevels(GLsizei size, GLint maxlevel) const;
// The pointer returned is weak and it is assumed the derived class will keep a strong pointer until the next createTexture() call. // The pointer returned is weak and it is assumed the derived class will keep a strong pointer until the next createTexture() call.
virtual IDirect3DBaseTexture9 *createTexture() = 0; virtual IDirect3DBaseTexture9 *createTexture() = 0;
virtual void updateTexture() = 0; virtual void updateTexture() = 0;
...@@ -127,6 +130,8 @@ class Texture ...@@ -127,6 +130,8 @@ class Texture
unsigned int mWidth; unsigned int mWidth;
unsigned int mHeight; unsigned int mHeight;
int levelCount() const;
private: private:
DISALLOW_COPY_AND_ASSIGN(Texture); DISALLOW_COPY_AND_ASSIGN(Texture);
......
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