Implemented OES_texture_npot support.

TRAC #16871 Signed-off-by: Daniel Koch Author: Nicolas Capens git-svn-id: https://angleproject.googlecode.com/svn/trunk@661 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 24c08c4e
#define MAJOR_VERSION 0
#define MINOR_VERSION 0
#define BUILD_VERSION 0
#define BUILD_REVISION 660
#define BUILD_REVISION 661
#define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x)
......
......@@ -535,7 +535,7 @@ EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle,
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
}
if (textureFormat != EGL_NO_TEXTURE && !getNonPow2TextureSupport() && (!gl::isPow2(width) || !gl::isPow2(height)))
if (textureFormat != EGL_NO_TEXTURE && !getNonPower2TextureSupport() && (!gl::isPow2(width) || !gl::isPow2(height)))
{
return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
}
......@@ -783,11 +783,6 @@ bool Display::getLuminanceAlphaTextureSupport()
return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A8L8));
}
bool Display::getNonPow2TextureSupport()
{
return !(mDeviceCaps.TextureCaps & (D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_NONPOW2CONDITIONAL));
}
D3DPOOL Display::getBufferPool(DWORD usage) const
{
if (mD3d9Ex != NULL)
......@@ -877,4 +872,11 @@ bool Display::getVertexTextureSupport() const
return SUCCEEDED(result);
}
bool Display::getNonPower2TextureSupport() const
{
return !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_POW2) &&
!(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) &&
!(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL);
}
}
......@@ -68,8 +68,8 @@ class Display
virtual bool getHalfFloatTextureSupport(bool *filtering, bool *renderable);
virtual bool getLuminanceTextureSupport();
virtual bool getLuminanceAlphaTextureSupport();
virtual bool getNonPow2TextureSupport();
virtual bool getVertexTextureSupport() const;
virtual bool getNonPower2TextureSupport() const;
virtual D3DPOOL getBufferPool(DWORD usage) const;
bool isD3d9ExDevice() { return mD3d9Ex != NULL; }
......
......@@ -243,6 +243,7 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
mSupportsShaderModel3 = mDeviceCaps.PixelShaderVersion == D3DPS_VERSION(3, 0);
mSupportsVertexTexture = display->getVertexTextureSupport();
mSupportsNonPower2Texture = display->getNonPower2TextureSupport();
mMaxTextureDimension = std::min(std::min((int)mDeviceCaps.MaxTextureWidth, (int)mDeviceCaps.MaxTextureHeight),
(int)gl::IMPLEMENTATION_MAX_TEXTURE_SIZE);
......@@ -3098,6 +3099,11 @@ bool Context::supports32bitIndices() const
return mSupports32bitIndices;
}
bool Context::supportsNonPower2Texture() const
{
return mSupportsNonPower2Texture;
}
void Context::detachBuffer(GLuint buffer)
{
// [OpenGL ES 2.0.24] section 2.9 page 22:
......@@ -3335,6 +3341,11 @@ void Context::initExtensionString()
mExtensionString += "GL_OES_element_index_uint ";
}
if (supportsNonPower2Texture())
{
mExtensionString += "GL_OES_texture_npot ";
}
std::string::size_type end = mExtensionString.find_last_not_of(' ');
if (end != std::string::npos)
{
......
......@@ -447,6 +447,7 @@ class Context
bool supportsLuminanceTextures() const;
bool supportsLuminanceAlphaTextures() const;
bool supports32bitIndices() const;
bool supportsNonPower2Texture() const;
void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
......@@ -523,6 +524,7 @@ class Context
bool mSupportsShaderModel3;
bool mSupportsVertexTexture;
bool mSupportsNonPower2Texture;
int mMaxRenderbufferDimension;
int mMaxTextureDimension;
int mMaxCubeTextureDimension;
......
......@@ -1242,7 +1242,7 @@ unsigned int Texture::getSerial() const
GLint Texture::creationLevels(GLsizei width, GLsizei height, GLint maxlevel) const
{
if (isPow2(width) && isPow2(height))
if ((isPow2(width) && isPow2(height)) || getContext()->supportsNonPower2Texture())
{
return maxlevel;
}
......@@ -1594,17 +1594,25 @@ bool Texture2D::isComplete() const
}
}
if ((getWrapS() != GL_CLAMP_TO_EDGE && !isPow2(width))
|| (getWrapT() != GL_CLAMP_TO_EDGE && !isPow2(height)))
bool npot = getContext()->supportsNonPower2Texture();
if (!npot)
{
return false;
if ((getWrapS() != GL_CLAMP_TO_EDGE && !isPow2(width)) ||
(getWrapT() != GL_CLAMP_TO_EDGE && !isPow2(height)))
{
return false;
}
}
if (mipmapping)
{
if (!isPow2(width) || !isPow2(height))
if (!npot)
{
return false;
if (!isPow2(width) || !isPow2(height))
{
return false;
}
}
int q = log2(std::max(width, height));
......@@ -1781,9 +1789,12 @@ void Texture2D::convertToRenderTarget()
void Texture2D::generateMipmaps()
{
if (!isPow2(mImageArray[0].width) || !isPow2(mImageArray[0].height))
if (!getContext()->supportsNonPower2Texture())
{
return error(GL_INVALID_OPERATION);
if (!isPow2(mImageArray[0].width) || !isPow2(mImageArray[0].height))
{
return error(GL_INVALID_OPERATION);
}
}
// Purge array levels 1 through q and reset them to represent the generated mipmap levels.
......@@ -2063,12 +2074,25 @@ bool TextureCubeMap::isComplete() const
}
}
if (mipmapping)
bool npot = getContext()->supportsNonPower2Texture();
if (!npot)
{
if (!isPow2(size) && (getWrapS() != GL_CLAMP_TO_EDGE || getWrapT() != GL_CLAMP_TO_EDGE))
if ((getWrapS() != GL_CLAMP_TO_EDGE || getWrapT() != GL_CLAMP_TO_EDGE) && !isPow2(size))
{
return false;
}
}
if (mipmapping)
{
if (!npot)
{
if (!isPow2(size))
{
return false;
}
}
int q = log2(size);
......@@ -2440,11 +2464,19 @@ bool TextureCubeMap::isCubeComplete() const
void TextureCubeMap::generateMipmaps()
{
if (!isPow2(mImageArray[0][0].width) || !isCubeComplete())
if (!isCubeComplete())
{
return error(GL_INVALID_OPERATION);
}
if (!getContext()->supportsNonPower2Texture())
{
if (!isPow2(mImageArray[0][0].width))
{
return error(GL_INVALID_OPERATION);
}
}
// Purge array levels 1 through q and reset them to represent the generated mipmap levels.
unsigned int q = log2(mImageArray[0][0].width);
for (unsigned int f = 0; f < 6; f++)
......
......@@ -28,6 +28,31 @@
#include "libGLESv2/Shader.h"
#include "libGLESv2/Texture.h"
bool validImageSize(GLint level, GLsizei width, GLsizei height)
{
if (level < 0 || width < 0 || height < 0)
{
return false;
}
if (gl::getContext() && gl::getContext()->supportsNonPower2Texture())
{
return true;
}
if (level == 0)
{
return true;
}
if (gl::isPow2(width) && gl::isPow2(height))
{
return true;
}
return false;
}
extern "C"
{
......@@ -738,12 +763,7 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna
try
{
if (level < 0)
{
return error(GL_INVALID_VALUE);
}
if (width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || border != 0 || imageSize < 0)
if (!validImageSize(level, width, height) || border != 0 || imageSize < 0)
{
return error(GL_INVALID_VALUE);
}
......@@ -868,13 +888,7 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs
return error(GL_INVALID_ENUM);
}
if (level < 0)
{
return error(GL_INVALID_VALUE);
}
if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 ||
(level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0)
if (xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
{
return error(GL_INVALID_VALUE);
}
......@@ -982,12 +996,7 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
try
{
if (level < 0 || width < 0 || height < 0)
{
return error(GL_INVALID_VALUE);
}
if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
if (!validImageSize(level, width, height))
{
return error(GL_INVALID_VALUE);
}
......@@ -4397,12 +4406,7 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
try
{
if (level < 0 || width < 0 || height < 0)
{
return error(GL_INVALID_VALUE);
}
if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
if (!validImageSize(level, width, height))
{
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