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