Commit 0988fb8e by Alexis Hetu Committed by Alexis Hétu

Texture rectangle related fixes and associated tests

Imported texture rectangle tests from angle and fixed all texture rectangle related failures: - Rectangle textures can be rendered to - Rectangle textures only support level 0 - Rectangle textures can't be compressed - glTexStorage2D can no longer create a texture larger than the maximum size allowed Change-Id: I089291c94aad79e244782a8d56dd224c7510d237 Reviewed-on: https://swiftshader-review.googlesource.com/16908Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Tested-by: 's avatarAlexis Hétu <sugoi@google.com>
parent a70156b5
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
#include "Texture.h" #include "Texture.h"
#include "utilities.h" #include "utilities.h"
#include "compiler/Compiler.h"
namespace es2 namespace es2
{ {
RenderbufferInterface::RenderbufferInterface() RenderbufferInterface::RenderbufferInterface()
...@@ -132,6 +134,69 @@ GLsizei RenderbufferTexture2D::getSamples() const ...@@ -132,6 +134,69 @@ GLsizei RenderbufferTexture2D::getSamples() const
return 0; // Core OpenGL ES 3.0 does not support multisample textures. return 0; // Core OpenGL ES 3.0 does not support multisample textures.
} }
///// RenderbufferTexture2DRect Implementation ////////
RenderbufferTexture2DRect::RenderbufferTexture2DRect(Texture2DRect *texture)
{
mTexture2DRect = texture;
}
RenderbufferTexture2DRect::~RenderbufferTexture2DRect()
{
mTexture2DRect = NULL;
}
// Textures need to maintain their own reference count for references via
// Renderbuffers acting as proxies. Here, we notify the texture of a reference.
void RenderbufferTexture2DRect::addProxyRef(const Renderbuffer *proxy)
{
mTexture2DRect->addProxyRef(proxy);
}
void RenderbufferTexture2DRect::releaseProxy(const Renderbuffer *proxy)
{
mTexture2DRect->releaseProxy(proxy);
}
// Increments refcount on image.
// caller must release() the returned image
egl::Image *RenderbufferTexture2DRect::getRenderTarget()
{
return mTexture2DRect->getRenderTarget(GL_TEXTURE_RECTANGLE_ARB, 0);
}
// Increments refcount on image.
// caller must release() the returned image
egl::Image *RenderbufferTexture2DRect::createSharedImage()
{
return mTexture2DRect->createSharedImage(GL_TEXTURE_RECTANGLE_ARB, 0);
}
bool RenderbufferTexture2DRect::isShared() const
{
return mTexture2DRect->isShared(GL_TEXTURE_RECTANGLE_ARB, 0);
}
GLsizei RenderbufferTexture2DRect::getWidth() const
{
return mTexture2DRect->getWidth(GL_TEXTURE_RECTANGLE_ARB, 0);
}
GLsizei RenderbufferTexture2DRect::getHeight() const
{
return mTexture2DRect->getHeight(GL_TEXTURE_RECTANGLE_ARB, 0);
}
GLint RenderbufferTexture2DRect::getFormat() const
{
return mTexture2DRect->getFormat(GL_TEXTURE_RECTANGLE_ARB, 0);
}
GLsizei RenderbufferTexture2DRect::getSamples() const
{
return 0; // Core OpenGL ES 3.0 does not support multisample textures.
}
///// RenderbufferTexture3D Implementation //////// ///// RenderbufferTexture3D Implementation ////////
RenderbufferTexture3D::RenderbufferTexture3D(Texture3D *texture, GLint level) : mLevel(level) RenderbufferTexture3D::RenderbufferTexture3D(Texture3D *texture, GLint level) : mLevel(level)
......
...@@ -31,6 +31,7 @@ namespace es2 ...@@ -31,6 +31,7 @@ namespace es2
class Texture2D; class Texture2D;
class Texture3D; class Texture3D;
class TextureCubeMap; class TextureCubeMap;
class Texture2DRect;
class Renderbuffer; class Renderbuffer;
class Colorbuffer; class Colorbuffer;
class DepthStencilbuffer; class DepthStencilbuffer;
...@@ -93,6 +94,29 @@ private: ...@@ -93,6 +94,29 @@ private:
GLint mLevel; GLint mLevel;
}; };
class RenderbufferTexture2DRect : public RenderbufferInterface
{
public:
RenderbufferTexture2DRect(Texture2DRect *texture);
~RenderbufferTexture2DRect() override;
void addProxyRef(const Renderbuffer *proxy) override;
void releaseProxy(const Renderbuffer *proxy) override;
egl::Image *getRenderTarget() override;
egl::Image *createSharedImage() override;
bool isShared() const override;
GLsizei getWidth() const override;
GLsizei getHeight() const override;
GLint getFormat() const override;
GLsizei getSamples() const override;
private:
gl::BindingPointer<Texture2DRect> mTexture2DRect;
};
class RenderbufferTexture3D : public RenderbufferInterface class RenderbufferTexture3D : public RenderbufferInterface
{ {
public: public:
......
...@@ -75,7 +75,7 @@ bool Texture::setMinFilter(GLenum filter) ...@@ -75,7 +75,7 @@ bool Texture::setMinFilter(GLenum filter)
case GL_LINEAR_MIPMAP_NEAREST: case GL_LINEAR_MIPMAP_NEAREST:
case GL_NEAREST_MIPMAP_LINEAR: case GL_NEAREST_MIPMAP_LINEAR:
case GL_LINEAR_MIPMAP_LINEAR: case GL_LINEAR_MIPMAP_LINEAR:
if(getTarget() == GL_TEXTURE_EXTERNAL_OES) if((getTarget() == GL_TEXTURE_EXTERNAL_OES) || (getTarget() == GL_TEXTURE_RECTANGLE_ARB))
{ {
return false; return false;
} }
...@@ -110,7 +110,7 @@ bool Texture::setWrapS(GLenum wrap) ...@@ -110,7 +110,7 @@ bool Texture::setWrapS(GLenum wrap)
{ {
case GL_REPEAT: case GL_REPEAT:
case GL_MIRRORED_REPEAT: case GL_MIRRORED_REPEAT:
if(getTarget() == GL_TEXTURE_EXTERNAL_OES) if((getTarget() == GL_TEXTURE_EXTERNAL_OES) || (getTarget() == GL_TEXTURE_RECTANGLE_ARB))
{ {
return false; return false;
} }
...@@ -130,7 +130,7 @@ bool Texture::setWrapT(GLenum wrap) ...@@ -130,7 +130,7 @@ bool Texture::setWrapT(GLenum wrap)
{ {
case GL_REPEAT: case GL_REPEAT:
case GL_MIRRORED_REPEAT: case GL_MIRRORED_REPEAT:
if(getTarget() == GL_TEXTURE_EXTERNAL_OES) if((getTarget() == GL_TEXTURE_EXTERNAL_OES) || (getTarget() == GL_TEXTURE_RECTANGLE_ARB))
{ {
return false; return false;
} }
...@@ -150,7 +150,7 @@ bool Texture::setWrapR(GLenum wrap) ...@@ -150,7 +150,7 @@ bool Texture::setWrapR(GLenum wrap)
{ {
case GL_REPEAT: case GL_REPEAT:
case GL_MIRRORED_REPEAT: case GL_MIRRORED_REPEAT:
if(getTarget() == GL_TEXTURE_EXTERNAL_OES) if((getTarget() == GL_TEXTURE_EXTERNAL_OES) || (getTarget() == GL_TEXTURE_RECTANGLE_ARB))
{ {
return false; return false;
} }
...@@ -844,6 +844,11 @@ bool Texture2D::isShared(GLenum target, unsigned int level) const ...@@ -844,6 +844,11 @@ bool Texture2D::isShared(GLenum target, unsigned int level) const
Texture2DRect::Texture2DRect(GLuint name) : Texture2D(name) Texture2DRect::Texture2DRect(GLuint name) : Texture2D(name)
{ {
mMinFilter = GL_LINEAR;
mMagFilter = GL_LINEAR;
mWrapS = GL_CLAMP_TO_EDGE;
mWrapT = GL_CLAMP_TO_EDGE;
mWrapR = GL_CLAMP_TO_EDGE;
} }
GLenum Texture2DRect::getTarget() const GLenum Texture2DRect::getTarget() const
...@@ -851,6 +856,21 @@ GLenum Texture2DRect::getTarget() const ...@@ -851,6 +856,21 @@ GLenum Texture2DRect::getTarget() const
return GL_TEXTURE_RECTANGLE_ARB; return GL_TEXTURE_RECTANGLE_ARB;
} }
Renderbuffer *Texture2DRect::getRenderbuffer(GLenum target, GLint level)
{
if((target != getTarget()) || (level != 0))
{
return error(GL_INVALID_OPERATION, (Renderbuffer*)nullptr);
}
if(!mColorbufferProxy)
{
mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture2DRect(this));
}
return mColorbufferProxy;
}
TextureCubeMap::TextureCubeMap(GLuint name) : Texture(name) TextureCubeMap::TextureCubeMap(GLuint name) : Texture(name)
{ {
for(int f = 0; f < 6; f++) for(int f = 0; f < 6; f++)
......
...@@ -205,6 +205,8 @@ public: ...@@ -205,6 +205,8 @@ public:
explicit Texture2DRect(GLuint name); explicit Texture2DRect(GLuint name);
GLenum getTarget() const override; GLenum getTarget() const override;
Renderbuffer *getRenderbuffer(GLenum target, GLint level) override;
}; };
class TextureCubeMap : public Texture class TextureCubeMap : public Texture
......
...@@ -761,7 +761,6 @@ void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLs ...@@ -761,7 +761,6 @@ void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLs
switch(target) switch(target)
{ {
case GL_TEXTURE_2D: case GL_TEXTURE_2D:
case GL_TEXTURE_RECTANGLE_ARB:
if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) || if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level)) height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
{ {
...@@ -785,6 +784,7 @@ void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLs ...@@ -785,6 +784,7 @@ void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLs
return error(GL_INVALID_VALUE); return error(GL_INVALID_VALUE);
} }
break; break;
case GL_TEXTURE_RECTANGLE_ARB: // Rectangle textures cannot be compressed
default: default:
return error(GL_INVALID_ENUM); return error(GL_INVALID_ENUM);
} }
...@@ -920,8 +920,13 @@ void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, ...@@ -920,8 +920,13 @@ void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x,
{ {
switch(target) switch(target)
{ {
case GL_TEXTURE_2D:
case GL_TEXTURE_RECTANGLE_ARB: case GL_TEXTURE_RECTANGLE_ARB:
if(level != 0)
{
return error(GL_INVALID_VALUE);
}
// Fall through
case GL_TEXTURE_2D:
if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) || if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level)) height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
{ {
...@@ -2038,7 +2043,7 @@ void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GL ...@@ -2038,7 +2043,7 @@ void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GL
return error(GL_INVALID_ENUM); return error(GL_INVALID_ENUM);
} }
if((level != 0) && (clientVersion < 3)) if((level != 0) && ((clientVersion < 3) || (textarget == GL_TEXTURE_RECTANGLE_ARB)))
{ {
return error(GL_INVALID_VALUE); return error(GL_INVALID_VALUE);
} }
...@@ -4970,8 +4975,13 @@ void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, ...@@ -4970,8 +4975,13 @@ void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width,
switch(target) switch(target)
{ {
case GL_TEXTURE_2D:
case GL_TEXTURE_RECTANGLE_ARB: case GL_TEXTURE_RECTANGLE_ARB:
if(level != 0)
{
return error(GL_INVALID_VALUE); // Defining level other than 0 is not allowed
}
// Fall through
case GL_TEXTURE_2D:
if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) || if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level)) height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
{ {
...@@ -5266,6 +5276,10 @@ void TexParameteri(GLenum target, GLenum pname, GLint param) ...@@ -5266,6 +5276,10 @@ void TexParameteri(GLenum target, GLenum pname, GLint param)
} }
break; break;
case GL_TEXTURE_BASE_LEVEL: case GL_TEXTURE_BASE_LEVEL:
if((texture->getTarget() == GL_TEXTURE_RECTANGLE_ARB) && (param != 0))
{
return error(GL_INVALID_OPERATION); // Base level has to be 0
}
if(clientVersion < 3 || !texture->setBaseLevel(param)) if(clientVersion < 3 || !texture->setBaseLevel(param))
{ {
return error(GL_INVALID_VALUE); return error(GL_INVALID_VALUE);
......
...@@ -3594,7 +3594,7 @@ GL_APICALL void GL_APIENTRY glTexStorage2D(GLenum target, GLsizei levels, GLenum ...@@ -3594,7 +3594,7 @@ GL_APICALL void GL_APIENTRY glTexStorage2D(GLenum target, GLsizei levels, GLenum
TRACE("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", TRACE("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
target, levels, internalformat, width, height); target, levels, internalformat, width, height);
if(width < 1 || height < 1 || levels < 1) if(width < 1 || height < 1 || levels < 1 || ((target == GL_TEXTURE_RECTANGLE_ARB) && (levels != 1)))
{ {
return error(GL_INVALID_VALUE); return error(GL_INVALID_VALUE);
} }
...@@ -3604,7 +3604,8 @@ GL_APICALL void GL_APIENTRY glTexStorage2D(GLenum target, GLsizei levels, GLenum ...@@ -3604,7 +3604,8 @@ GL_APICALL void GL_APIENTRY glTexStorage2D(GLenum target, GLsizei levels, GLenum
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
if(!IsSizedInternalFormat(internalformat) && !IsCompressed(internalformat, egl::getClientVersion())) bool isCompressed = IsCompressed(internalformat, egl::getClientVersion());
if(!IsSizedInternalFormat(internalformat) && !isCompressed)
{ {
return error(GL_INVALID_ENUM); return error(GL_INVALID_ENUM);
} }
...@@ -3615,9 +3616,19 @@ GL_APICALL void GL_APIENTRY glTexStorage2D(GLenum target, GLsizei levels, GLenum ...@@ -3615,9 +3616,19 @@ GL_APICALL void GL_APIENTRY glTexStorage2D(GLenum target, GLsizei levels, GLenum
{ {
switch(target) switch(target)
{ {
case GL_TEXTURE_2D:
case GL_TEXTURE_RECTANGLE_ARB: case GL_TEXTURE_RECTANGLE_ARB:
if(isCompressed) // Rectangle textures cannot be compressed
{
return error(GL_INVALID_ENUM);
}
case GL_TEXTURE_2D:
{
if((width > es2::IMPLEMENTATION_MAX_TEXTURE_SIZE) ||
(height > es2::IMPLEMENTATION_MAX_TEXTURE_SIZE))
{ {
return error(GL_INVALID_VALUE);
}
es2::Texture2D *texture = context->getTexture2D(target); es2::Texture2D *texture = context->getTexture2D(target);
if(!texture || texture->name == 0 || texture->getImmutableFormat() == GL_TRUE) if(!texture || texture->name == 0 || texture->getImmutableFormat() == GL_TRUE)
{ {
...@@ -3635,6 +3646,12 @@ GL_APICALL void GL_APIENTRY glTexStorage2D(GLenum target, GLsizei levels, GLenum ...@@ -3635,6 +3646,12 @@ GL_APICALL void GL_APIENTRY glTexStorage2D(GLenum target, GLsizei levels, GLenum
break; break;
case GL_TEXTURE_CUBE_MAP: case GL_TEXTURE_CUBE_MAP:
{ {
if((width > es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE) ||
(height > es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE))
{
return error(GL_INVALID_VALUE);
}
es2::TextureCubeMap *texture = context->getTextureCubeMap(); es2::TextureCubeMap *texture = context->getTextureCubeMap();
if(!texture || texture->name == 0 || texture->getImmutableFormat()) if(!texture || texture->name == 0 || texture->getImmutableFormat())
{ {
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#include <EGL/egl.h> #include <EGL/egl.h>
#include <GLES2/gl2.h> #include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <GLES3/gl3.h>
#if defined(_WIN32) #if defined(_WIN32)
#include <Windows.h> #include <Windows.h>
...@@ -37,22 +39,38 @@ protected: ...@@ -37,22 +39,38 @@ protected:
EXPECT_NE((HMODULE)NULL, libGLESv2); EXPECT_NE((HMODULE)NULL, libGLESv2);
#endif #endif
} }
};
TEST_F(SwiftShaderTest, Initalization) void compareColor(unsigned char referenceColor[4])
{ {
unsigned char color[4] = { 0 };
glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &color);
EXPECT_EQ(color[0], referenceColor[0]);
EXPECT_EQ(color[1], referenceColor[1]);
EXPECT_EQ(color[2], referenceColor[2]);
EXPECT_EQ(color[3], referenceColor[3]);
}
void Initialize(int version, bool withChecks)
{
EXPECT_EQ(EGL_SUCCESS, eglGetError()); EXPECT_EQ(EGL_SUCCESS, eglGetError());
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if(withChecks)
{
EXPECT_EQ(EGL_SUCCESS, eglGetError()); EXPECT_EQ(EGL_SUCCESS, eglGetError());
EXPECT_NE(EGL_NO_DISPLAY, display); EXPECT_NE(EGL_NO_DISPLAY, display);
eglQueryString(display, EGL_VENDOR); eglQueryString(display, EGL_VENDOR);
EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError());
}
EGLint major; EGLint major;
EGLint minor; EGLint minor;
EGLBoolean initialized = eglInitialize(display, &major, &minor); EGLBoolean initialized = eglInitialize(display, &major, &minor);
if(withChecks)
{
EXPECT_EQ(EGL_SUCCESS, eglGetError()); EXPECT_EQ(EGL_SUCCESS, eglGetError());
EXPECT_EQ((EGLBoolean)EGL_TRUE, initialized); EXPECT_EQ((EGLBoolean)EGL_TRUE, initialized);
EXPECT_EQ(1, major); EXPECT_EQ(1, major);
...@@ -65,6 +83,7 @@ TEST_F(SwiftShaderTest, Initalization) ...@@ -65,6 +83,7 @@ TEST_F(SwiftShaderTest, Initalization)
const char *eglVersion = eglQueryString(display, EGL_VERSION); const char *eglVersion = eglQueryString(display, EGL_VERSION);
EXPECT_EQ(EGL_SUCCESS, eglGetError()); EXPECT_EQ(EGL_SUCCESS, eglGetError());
EXPECT_THAT(eglVersion, testing::HasSubstr("1.4 SwiftShader ")); EXPECT_THAT(eglVersion, testing::HasSubstr("1.4 SwiftShader "));
}
eglBindAPI(EGL_OPENGL_ES_API); eglBindAPI(EGL_OPENGL_ES_API);
EXPECT_EQ(EGL_SUCCESS, eglGetError()); EXPECT_EQ(EGL_SUCCESS, eglGetError());
...@@ -73,6 +92,7 @@ TEST_F(SwiftShaderTest, Initalization) ...@@ -73,6 +92,7 @@ TEST_F(SwiftShaderTest, Initalization)
{ {
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_ALPHA_SIZE, 8,
EGL_NONE EGL_NONE
}; };
...@@ -83,6 +103,8 @@ TEST_F(SwiftShaderTest, Initalization) ...@@ -83,6 +103,8 @@ TEST_F(SwiftShaderTest, Initalization)
EXPECT_EQ(num_config, 1); EXPECT_EQ(num_config, 1);
EXPECT_EQ((EGLBoolean)EGL_TRUE, success); EXPECT_EQ((EGLBoolean)EGL_TRUE, success);
if(withChecks)
{
EGLint conformant = 0; EGLint conformant = 0;
eglGetConfigAttrib(display, config, EGL_CONFORMANT, &conformant); eglGetConfigAttrib(display, config, EGL_CONFORMANT, &conformant);
EXPECT_EQ(EGL_SUCCESS, eglGetError()); EXPECT_EQ(EGL_SUCCESS, eglGetError());
...@@ -97,6 +119,7 @@ TEST_F(SwiftShaderTest, Initalization) ...@@ -97,6 +119,7 @@ TEST_F(SwiftShaderTest, Initalization)
eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &surfaceType); eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &surfaceType);
EXPECT_EQ(EGL_SUCCESS, eglGetError()); EXPECT_EQ(EGL_SUCCESS, eglGetError());
EXPECT_TRUE(surfaceType & EGL_WINDOW_BIT); EXPECT_TRUE(surfaceType & EGL_WINDOW_BIT);
}
EGLint surfaceAttributes[] = EGLint surfaceAttributes[] =
{ {
...@@ -105,17 +128,17 @@ TEST_F(SwiftShaderTest, Initalization) ...@@ -105,17 +128,17 @@ TEST_F(SwiftShaderTest, Initalization)
EGL_NONE EGL_NONE
}; };
EGLSurface surface = eglCreatePbufferSurface(display, config, surfaceAttributes); surface = eglCreatePbufferSurface(display, config, surfaceAttributes);
EXPECT_EQ(EGL_SUCCESS, eglGetError()); EXPECT_EQ(EGL_SUCCESS, eglGetError());
EXPECT_NE(EGL_NO_SURFACE, surface); EXPECT_NE(EGL_NO_SURFACE, surface);
EGLint contextAttributes[] = EGLint contextAttributes[] =
{ {
EGL_CONTEXT_CLIENT_VERSION, 2, EGL_CONTEXT_CLIENT_VERSION, version,
EGL_NONE EGL_NONE
}; };
EGLContext context = eglCreateContext(display, config, NULL, contextAttributes); context = eglCreateContext(display, config, NULL, contextAttributes);
EXPECT_EQ(EGL_SUCCESS, eglGetError()); EXPECT_EQ(EGL_SUCCESS, eglGetError());
EXPECT_NE(EGL_NO_CONTEXT, context); EXPECT_NE(EGL_NO_CONTEXT, context);
...@@ -123,6 +146,8 @@ TEST_F(SwiftShaderTest, Initalization) ...@@ -123,6 +146,8 @@ TEST_F(SwiftShaderTest, Initalization)
EXPECT_EQ(EGL_SUCCESS, eglGetError()); EXPECT_EQ(EGL_SUCCESS, eglGetError());
EXPECT_EQ((EGLBoolean)EGL_TRUE, success); EXPECT_EQ((EGLBoolean)EGL_TRUE, success);
if(withChecks)
{
EGLDisplay currentDisplay = eglGetCurrentDisplay(); EGLDisplay currentDisplay = eglGetCurrentDisplay();
EXPECT_EQ(EGL_SUCCESS, eglGetError()); EXPECT_EQ(EGL_SUCCESS, eglGetError());
EXPECT_EQ(display, currentDisplay); EXPECT_EQ(display, currentDisplay);
...@@ -138,38 +163,30 @@ TEST_F(SwiftShaderTest, Initalization) ...@@ -138,38 +163,30 @@ TEST_F(SwiftShaderTest, Initalization)
EGLContext currentContext = eglGetCurrentContext(); EGLContext currentContext = eglGetCurrentContext();
EXPECT_EQ(EGL_SUCCESS, eglGetError()); EXPECT_EQ(EGL_SUCCESS, eglGetError());
EXPECT_EQ(context, currentContext); EXPECT_EQ(context, currentContext);
}
EXPECT_EQ((GLenum)GL_NO_ERROR, glGetError()); EXPECT_EQ((GLenum)GL_NO_ERROR, glGetError());
}
const GLubyte *glVendor = glGetString(GL_VENDOR); void Uninitialize()
EXPECT_EQ((GLenum)GL_NO_ERROR, glGetError()); {
EXPECT_STREQ("Google Inc.", (const char*)glVendor); EGLBoolean success = eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
const GLubyte *glRenderer = glGetString(GL_RENDERER);
EXPECT_EQ((GLenum)GL_NO_ERROR, glGetError());
EXPECT_STREQ("Google SwiftShader", (const char*)glRenderer);
const GLubyte *glVersion = glGetString(GL_VERSION);
EXPECT_EQ((GLenum)GL_NO_ERROR, glGetError());
EXPECT_THAT((const char*)glVersion, testing::HasSubstr("OpenGL ES 2.0 SwiftShader "));
success = eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
EXPECT_EQ(EGL_SUCCESS, eglGetError()); EXPECT_EQ(EGL_SUCCESS, eglGetError());
EXPECT_EQ((EGLBoolean)EGL_TRUE, success); EXPECT_EQ((EGLBoolean)EGL_TRUE, success);
currentDisplay = eglGetCurrentDisplay(); EGLDisplay currentDisplay = eglGetCurrentDisplay();
EXPECT_EQ(EGL_SUCCESS, eglGetError()); EXPECT_EQ(EGL_SUCCESS, eglGetError());
EXPECT_EQ(EGL_NO_DISPLAY, currentDisplay); EXPECT_EQ(EGL_NO_DISPLAY, currentDisplay);
currentDrawSurface = eglGetCurrentSurface(EGL_DRAW); EGLSurface currentDrawSurface = eglGetCurrentSurface(EGL_DRAW);
EXPECT_EQ(EGL_SUCCESS, eglGetError()); EXPECT_EQ(EGL_SUCCESS, eglGetError());
EXPECT_EQ(EGL_NO_SURFACE, currentDrawSurface); EXPECT_EQ(EGL_NO_SURFACE, currentDrawSurface);
currentReadSurface = eglGetCurrentSurface(EGL_READ); EGLSurface currentReadSurface = eglGetCurrentSurface(EGL_READ);
EXPECT_EQ(EGL_SUCCESS, eglGetError()); EXPECT_EQ(EGL_SUCCESS, eglGetError());
EXPECT_EQ(EGL_NO_SURFACE, currentReadSurface); EXPECT_EQ(EGL_NO_SURFACE, currentReadSurface);
currentContext = eglGetCurrentContext(); EGLContext currentContext = eglGetCurrentContext();
EXPECT_EQ(EGL_SUCCESS, eglGetError()); EXPECT_EQ(EGL_SUCCESS, eglGetError());
EXPECT_EQ(EGL_NO_CONTEXT, currentContext); EXPECT_EQ(EGL_NO_CONTEXT, currentContext);
...@@ -184,4 +201,446 @@ TEST_F(SwiftShaderTest, Initalization) ...@@ -184,4 +201,446 @@ TEST_F(SwiftShaderTest, Initalization)
success = eglTerminate(display); success = eglTerminate(display);
EXPECT_EQ(EGL_SUCCESS, eglGetError()); EXPECT_EQ(EGL_SUCCESS, eglGetError());
EXPECT_EQ((EGLBoolean)EGL_TRUE, success); EXPECT_EQ((EGLBoolean)EGL_TRUE, success);
}
private:
EGLDisplay display;
EGLSurface surface;
EGLContext context;
};
TEST_F(SwiftShaderTest, Initalization)
{
Initialize(2, true);
const GLubyte *glVendor = glGetString(GL_VENDOR);
EXPECT_EQ((GLenum)GL_NO_ERROR, glGetError());
EXPECT_STREQ("Google Inc.", (const char*)glVendor);
const GLubyte *glRenderer = glGetString(GL_RENDERER);
EXPECT_EQ((GLenum)GL_NO_ERROR, glGetError());
EXPECT_STREQ("Google SwiftShader", (const char*)glRenderer);
const GLubyte *glVersion = glGetString(GL_VERSION);
EXPECT_EQ((GLenum)GL_NO_ERROR, glGetError());
EXPECT_THAT((const char*)glVersion, testing::HasSubstr("OpenGL ES 2.0 SwiftShader "));
Uninitialize();
}
// Note: GL_ARB_texture_rectangle is part of gl2extchromium.h in the Chromium repo
// GL_ARB_texture_rectangle
#ifndef GL_ARB_texture_rectangle
#define GL_ARB_texture_rectangle 1
#ifndef GL_SAMPLER_2D_RECT_ARB
#define GL_SAMPLER_2D_RECT_ARB 0x8B63
#endif
#ifndef GL_TEXTURE_BINDING_RECTANGLE_ARB
#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6
#endif
#ifndef GL_TEXTURE_RECTANGLE_ARB
#define GL_TEXTURE_RECTANGLE_ARB 0x84F5
#endif
#ifndef GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB
#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8
#endif
#endif // GL_ARB_texture_rectangle
// Test using TexImage2D to define a rectangle texture
TEST_F(SwiftShaderTest, TextureRectangle_TexImage2D)
{
Initialize(2, false);
GLuint tex = 1;
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
// Defining level 0 is allowed
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
EXPECT_EQ(GL_NONE, glGetError());
// Defining level other than 0 is not allowed
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 1, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
EXPECT_EQ(GL_INVALID_VALUE, glGetError());
GLint maxSize = 0;
glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &maxSize);
// Defining a texture of the max size is allowed
{
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, maxSize, maxSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
GLenum error = glGetError();
ASSERT_TRUE(error == GL_NO_ERROR || error == GL_OUT_OF_MEMORY);
}
// Defining a texture larger than the max size is disallowed
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, maxSize + 1, maxSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
EXPECT_EQ(GL_INVALID_VALUE, glGetError());
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, maxSize, maxSize + 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
EXPECT_EQ(GL_INVALID_VALUE, glGetError());
Uninitialize();
}
// Test using CompressedTexImage2D cannot be used on a retangle texture
TEST_F(SwiftShaderTest, TextureRectangle_CompressedTexImage2DDisallowed)
{
Initialize(2, false);
const char data[128] = { 0 };
// Control case: 2D texture
{
GLuint tex = 1;
glBindTexture(GL_TEXTURE_2D, tex);
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 16, 16, 0, 128, data);
EXPECT_EQ(GL_NONE, glGetError());
}
// Rectangle textures cannot be compressed
{
GLuint tex = 2;
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
glCompressedTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 16, 16, 0, 128, data);
EXPECT_EQ(GL_INVALID_ENUM, glGetError());
}
Uninitialize();
}
// Test using TexStorage2D to define a rectangle texture (ES3)
TEST_F(SwiftShaderTest, TextureRectangle_TexStorage2D)
{
Initialize(3, false);
// Defining one level is allowed
{
GLuint tex = 1;
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
glTexStorage2D(GL_TEXTURE_RECTANGLE_ARB, 1, GL_RGBA8UI, 16, 16);
EXPECT_EQ(GL_NONE, glGetError());
}
// Having more than one level is not allowed
{
GLuint tex = 2;
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
// Use 5 levels because the EXT_texture_storage extension requires a mip chain all the way
// to a 1x1 mip.
glTexStorage2D(GL_TEXTURE_RECTANGLE_ARB, 5, GL_RGBA8UI, 16, 16);
EXPECT_EQ(GL_INVALID_VALUE, glGetError());
}
GLint maxSize = 0;
glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &maxSize);
// Defining a texture of the max size is allowed but still allow for OOM
{
GLuint tex = 3;
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
glTexStorage2D(GL_TEXTURE_RECTANGLE_ARB, 1, GL_RGBA8UI, maxSize, maxSize);
GLenum error = glGetError();
ASSERT_TRUE(error == GL_NO_ERROR || error == GL_OUT_OF_MEMORY);
}
// Defining a texture larger than the max size is disallowed
{
GLuint tex = 4;
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
glTexStorage2D(GL_TEXTURE_RECTANGLE_ARB, 1, GL_RGBA8UI, maxSize + 1, maxSize);
EXPECT_EQ(GL_INVALID_VALUE, glGetError());
glTexStorage2D(GL_TEXTURE_RECTANGLE_ARB, 1, GL_RGBA8UI, maxSize, maxSize + 1);
EXPECT_EQ(GL_INVALID_VALUE, glGetError());
}
// Compressed formats are disallowed
GLuint tex = 5;
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
glTexStorage2D(GL_TEXTURE_RECTANGLE_ARB, 1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 16, 16);
EXPECT_EQ(GL_INVALID_ENUM, glGetError());
Uninitialize();
}
// Test validation of disallowed texture parameters
TEST_F(SwiftShaderTest, TextureRectangle_TexParameterRestriction)
{
Initialize(3, false);
GLuint tex = 1;
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
// Only wrap mode CLAMP_TO_EDGE is supported
// Wrap S
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
EXPECT_EQ(GL_NONE, glGetError());
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_REPEAT);
EXPECT_EQ(GL_INVALID_ENUM, glGetError());
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
EXPECT_EQ(GL_INVALID_ENUM, glGetError());
// Wrap T
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
EXPECT_EQ(GL_NONE, glGetError());
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_REPEAT);
EXPECT_EQ(GL_INVALID_ENUM, glGetError());
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
EXPECT_EQ(GL_INVALID_ENUM, glGetError());
// Min filter has to be nearest or linear
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
EXPECT_EQ(GL_NONE, glGetError());
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
EXPECT_EQ(GL_NONE, glGetError());
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
EXPECT_EQ(GL_INVALID_ENUM, glGetError());
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
EXPECT_EQ(GL_INVALID_ENUM, glGetError());
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
EXPECT_EQ(GL_INVALID_ENUM, glGetError());
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
EXPECT_EQ(GL_INVALID_ENUM, glGetError());
// Base level has to be 0
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_BASE_LEVEL, 0);
EXPECT_EQ(GL_NONE, glGetError());
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_BASE_LEVEL, 1);
EXPECT_EQ(GL_INVALID_OPERATION, glGetError());
Uninitialize();
}
// Test validation of "level" in FramebufferTexture2D
TEST_F(SwiftShaderTest, TextureRectangle_FramebufferTexture2DLevel)
{
Initialize(3, false);
GLuint tex = 1;
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
EXPECT_EQ(GL_NONE, glGetError());
GLuint fbo = 1;
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
// Using level 0 of a rectangle texture is valid.
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, tex, 0);
EXPECT_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
EXPECT_EQ(GL_NONE, glGetError());
// Setting level != 0 is invalid
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, tex, 1);
EXPECT_EQ(GL_INVALID_VALUE, glGetError());
Uninitialize();
}
// Test sampling from a rectangle texture
TEST_F(SwiftShaderTest, TextureRectangle_SamplingFromRectangle)
{
Initialize(3, false);
GLuint tex = 1;
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
EXPECT_EQ(GL_NONE, glGetError());
unsigned char green[4] = { 0, 255, 0, 255 };
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, green);
EXPECT_EQ(GL_NONE, glGetError());
const std::string vs =
"attribute vec4 position;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(position.xy, 0.0, 1.0);\n"
"}\n";
const std::string fs =
"#extension GL_ARB_texture_rectangle : require\n"
"precision mediump float;\n"
"uniform sampler2DRect tex;\n"
"void main()\n"
"{\n"
" gl_FragColor = texture2DRect(tex, vec2(0, 0));\n"
"}\n";
GLuint program = glCreateProgram();
EXPECT_EQ(GL_NONE, glGetError());
GLuint vsShader = glCreateShader(GL_VERTEX_SHADER);
const char* vsSource[1] = { vs.c_str() };
glShaderSource(vsShader, 1, vsSource, nullptr);
glCompileShader(vsShader);
EXPECT_EQ(GL_NONE, glGetError());
GLuint fsShader = glCreateShader(GL_FRAGMENT_SHADER);
const char* fsSource[1] = { fs.c_str() };
glShaderSource(fsShader, 1, fsSource, nullptr);
glCompileShader(fsShader);
EXPECT_EQ(GL_NONE, glGetError());
glAttachShader(program, vsShader);
glAttachShader(program, fsShader);
glLinkProgram(program);
EXPECT_EQ(GL_NONE, glGetError());
glUseProgram(program);
GLint location = glGetUniformLocation(program, "tex");
ASSERT_NE(-1, location);
glUniform1i(location, 0);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
EXPECT_EQ(GL_NONE, glGetError());
GLint prevProgram = 0;
glGetIntegerv(GL_CURRENT_PROGRAM, &prevProgram);
glUseProgram(program);
EXPECT_EQ(GL_NONE, glGetError());
GLint posLoc = glGetAttribLocation(program, "position");
EXPECT_EQ(GL_NONE, glGetError());
float vertices[18] = { -1.0f, 1.0f, 0.5f,
-1.0f, -1.0f, 0.5f,
1.0f, -1.0f, 0.5f,
-1.0f, 1.0f, 0.5f,
1.0f, -1.0f, 0.5f,
1.0f, 1.0f, 0.5f };
glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, vertices);
glEnableVertexAttribArray(posLoc);
glDrawArrays(GL_TRIANGLES, 0, 6);
EXPECT_EQ(GL_NONE, glGetError());
glVertexAttribPointer(posLoc, 4, GL_FLOAT, GL_FALSE, 0, nullptr);
glDisableVertexAttribArray(posLoc);
glUseProgram(prevProgram);
EXPECT_EQ(GL_NONE, glGetError());
compareColor(green);
EXPECT_EQ(GL_NONE, glGetError());
Uninitialize();
}
// Test attaching a rectangle texture and rendering to it.
TEST_F(SwiftShaderTest, TextureRectangle_RenderToRectangle)
{
Initialize(3, false);
GLuint tex = 1;
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
unsigned char black[4] = { 0, 0, 0, 255 };
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
GLuint fbo = 1;
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, tex, 0);
EXPECT_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
EXPECT_EQ(GL_NONE, glGetError());
// Clearing a texture is just as good as checking we can render to it, right?
glClearColor(0.0, 1.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
unsigned char green[4] = { 0, 255, 0, 255 };
compareColor(green);
EXPECT_EQ(GL_NONE, glGetError());
Uninitialize();
}
TEST_F(SwiftShaderTest, TextureRectangle_DefaultSamplerParameters)
{
Initialize(3, false);
GLuint tex = 1;
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
GLint minFilter = 0;
glGetTexParameteriv(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, &minFilter);
EXPECT_EQ(GL_LINEAR, minFilter);
GLint wrapS = 0;
glGetTexParameteriv(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, &wrapS);
EXPECT_EQ(GL_CLAMP_TO_EDGE, wrapS);
GLint wrapT = 0;
glGetTexParameteriv(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, &wrapT);
EXPECT_EQ(GL_CLAMP_TO_EDGE, wrapT);
Uninitialize();
}
// Test glCopyTexImage with rectangle textures (ES3)
TEST_F(SwiftShaderTest, TextureRectangle_CopyTexImage)
{
Initialize(3, false);
GLuint tex = 1;
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClearColor(0, 1, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
EXPECT_EQ(GL_NONE, glGetError());
// Error case: level != 0
glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 1, GL_RGBA8, 0, 0, 1, 1, 0);
EXPECT_EQ(GL_INVALID_VALUE, glGetError());
// level = 0 works and defines the texture.
glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, 0, 0, 1, 1, 0);
EXPECT_EQ(GL_NONE, glGetError());
GLuint fbo = 1;
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, tex, 0);
unsigned char green[4] = { 0, 255, 0, 255 };
compareColor(green);
EXPECT_EQ(GL_NONE, glGetError());
Uninitialize();
}
// Test glCopyTexSubImage with rectangle textures (ES3)
TEST_F(SwiftShaderTest, TextureRectangle_CopyTexSubImage)
{
Initialize(3, false);
GLuint tex = 1;
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
unsigned char black[4] = { 0, 0, 0, 255 };
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClearColor(0, 1, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
EXPECT_EQ(GL_NONE, glGetError());
// Error case: level != 0
glCopyTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 1, 0, 0, 0, 0, 1, 1);
EXPECT_EQ(GL_INVALID_VALUE, glGetError());
// level = 0 works and defines the texture.
glCopyTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, 0, 0, 1, 1);
EXPECT_EQ(GL_NONE, glGetError());
GLuint fbo = 1;
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, tex, 0);
unsigned char green[4] = { 0, 255, 0, 255 };
compareColor(green);
EXPECT_EQ(GL_NONE, glGetError());
Uninitialize();
} }
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