Texture Rectangle implementation
This adds support for GL_ARB_texture_rectangle, as it is used in Chromium.
This is required in order to use EGL/GLES on MacOS using IOSurface,
in order to be able to run Chromium on top of SwiftShader on MacOS.
Change-Id: I3c0b6a137892583bbfbc68149874d5bec3026b4a
Reviewed-on: https://swiftshader-review.googlesource.com/16368
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp
index 82d9bcf..5759467 100644
--- a/src/OpenGL/libGLESv2/Context.cpp
+++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -142,6 +142,7 @@
mTexture3DZero = new Texture3D(0);
mTexture2DArrayZero = new Texture2DArray(0);
mTextureCubeMapZero = new TextureCubeMap(0);
+ mTexture2DRectZero = new Texture2DRect(0);
mTextureExternalZero = new TextureExternal(0);
mState.activeSampler = 0;
@@ -262,6 +263,7 @@
mTexture3DZero = nullptr;
mTexture2DArrayZero = nullptr;
mTextureCubeMapZero = nullptr;
+ mTexture2DRectZero = nullptr;
mTextureExternalZero = nullptr;
delete mVertexDataManager;
@@ -1209,6 +1211,13 @@
mState.samplerTexture[TEXTURE_2D_ARRAY][mState.activeSampler] = getTexture(texture);
}
+void Context::bindTexture2DRect(GLuint texture)
+{
+ mResourceManager->checkTextureAllocation(texture, TEXTURE_2D_RECT);
+
+ mState.samplerTexture[TEXTURE_2D_RECT][mState.activeSampler] = getTexture(texture);
+}
+
void Context::bindReadFramebuffer(GLuint framebuffer)
{
if(!getFramebuffer(framebuffer))
@@ -1681,6 +1690,19 @@
return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
}
+Texture2D *Context::getTexture2D(GLenum target) const
+{
+ switch(target)
+ {
+ case GL_TEXTURE_2D: return getTexture2D();
+ case GL_TEXTURE_RECTANGLE_ARB: return getTexture2DRect();
+ case GL_TEXTURE_EXTERNAL_OES: return getTextureExternal();
+ default: UNREACHABLE(target);
+ }
+
+ return nullptr;
+}
+
Texture3D *Context::getTexture3D() const
{
return static_cast<Texture3D*>(getSamplerTexture(mState.activeSampler, TEXTURE_3D));
@@ -1696,6 +1718,11 @@
return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
}
+Texture2DRect *Context::getTexture2DRect() const
+{
+ return static_cast<Texture2DRect*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D_RECT));
+}
+
TextureExternal *Context::getTextureExternal() const
{
return static_cast<TextureExternal*>(getSamplerTexture(mState.activeSampler, TEXTURE_EXTERNAL));
@@ -1713,6 +1740,7 @@
case TEXTURE_3D: return mTexture3DZero;
case TEXTURE_2D_ARRAY: return mTexture2DArrayZero;
case TEXTURE_CUBE: return mTextureCubeMapZero;
+ case TEXTURE_2D_RECT: return mTexture2DRectZero;
case TEXTURE_EXTERNAL: return mTextureExternalZero;
default: UNREACHABLE(type);
}
@@ -2113,6 +2141,15 @@
*params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name();
return true;
+ case GL_TEXTURE_BINDING_RECTANGLE_ARB:
+ if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
+ {
+ error(GL_INVALID_OPERATION);
+ return false;
+ }
+
+ *params = mState.samplerTexture[TEXTURE_2D_RECT][mState.activeSampler].name();
+ return true;
case GL_TEXTURE_BINDING_EXTERNAL_OES:
if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
{
@@ -2541,6 +2578,7 @@
case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
case GL_TEXTURE_BINDING_2D:
case GL_TEXTURE_BINDING_CUBE_MAP:
+ case GL_TEXTURE_BINDING_RECTANGLE_ARB:
case GL_TEXTURE_BINDING_EXTERNAL_OES:
case GL_TEXTURE_BINDING_3D_OES:
case GL_COPY_READ_BUFFER_BINDING:
@@ -3186,7 +3224,11 @@
int baseLevel = baseTexture->getBaseLevel();
int maxLevel = std::min(baseTexture->getTopLevel(), baseTexture->getMaxLevel());
- if(baseTexture->getTarget() == GL_TEXTURE_2D || baseTexture->getTarget() == GL_TEXTURE_EXTERNAL_OES)
+ switch(baseTexture->getTarget())
+ {
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_EXTERNAL_OES:
+ case GL_TEXTURE_RECTANGLE_ARB:
{
Texture2D *texture = static_cast<Texture2D*>(baseTexture);
@@ -3203,7 +3245,8 @@
device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D);
}
}
- else if(baseTexture->getTarget() == GL_TEXTURE_3D)
+ break;
+ case GL_TEXTURE_3D:
{
Texture3D *texture = static_cast<Texture3D*>(baseTexture);
@@ -3220,7 +3263,8 @@
device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_3D);
}
}
- else if(baseTexture->getTarget() == GL_TEXTURE_2D_ARRAY)
+ break;
+ case GL_TEXTURE_2D_ARRAY:
{
Texture2DArray *texture = static_cast<Texture2DArray*>(baseTexture);
@@ -3237,7 +3281,8 @@
device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D_ARRAY);
}
}
- else if(baseTexture->getTarget() == GL_TEXTURE_CUBE_MAP)
+ break;
+ case GL_TEXTURE_CUBE_MAP:
{
TextureCubeMap *cubeTexture = static_cast<TextureCubeMap*>(baseTexture);
@@ -3259,7 +3304,11 @@
}
}
}
- else UNIMPLEMENTED();
+ break;
+ default:
+ UNIMPLEMENTED();
+ break;
+ }
}
else
{
@@ -4397,6 +4446,7 @@
"GL_KHR_texture_compression_astc_hdr",
"GL_KHR_texture_compression_astc_ldr",
#endif
+ "GL_ARB_texture_rectangle",
"GL_ANGLE_framebuffer_blit",
"GL_ANGLE_framebuffer_multisample",
"GL_ANGLE_instanced_arrays",
diff --git a/src/OpenGL/libGLESv2/Context.h b/src/OpenGL/libGLESv2/Context.h
index e2b517d..c42a12a 100644
--- a/src/OpenGL/libGLESv2/Context.h
+++ b/src/OpenGL/libGLESv2/Context.h
@@ -53,6 +53,7 @@
class Texture3D;
class Texture2DArray;
class TextureCubeMap;
+class Texture2DRect;
class TextureExternal;
class Framebuffer;
class Renderbuffer;
@@ -598,6 +599,7 @@
void bindTextureExternal(GLuint texture);
void bindTexture3D(GLuint texture);
void bindTexture2DArray(GLuint texture);
+ void bindTexture2DRect(GLuint texture);
void bindReadFramebuffer(GLuint framebuffer);
void bindDrawFramebuffer(GLuint framebuffer);
void bindRenderbuffer(GLuint renderbuffer);
@@ -651,9 +653,11 @@
bool getBuffer(GLenum target, es2::Buffer **buffer) const;
Program *getCurrentProgram() const;
Texture2D *getTexture2D() const;
+ Texture2D *getTexture2D(GLenum target) const;
Texture3D *getTexture3D() const;
Texture2DArray *getTexture2DArray() const;
TextureCubeMap *getTextureCubeMap() const;
+ Texture2DRect *getTexture2DRect() const;
TextureExternal *getTextureExternal() const;
Texture *getSamplerTexture(unsigned int sampler, TextureType type) const;
Framebuffer *getReadFramebuffer() const;
@@ -743,6 +747,7 @@
gl::BindingPointer<Texture3D> mTexture3DZero;
gl::BindingPointer<Texture2DArray> mTexture2DArrayZero;
gl::BindingPointer<TextureCubeMap> mTextureCubeMapZero;
+ gl::BindingPointer<Texture2DRect> mTexture2DRectZero;
gl::BindingPointer<TextureExternal> mTextureExternalZero;
gl::NameSpace<Framebuffer> mFramebufferNameSpace;
diff --git a/src/OpenGL/libGLESv2/Program.cpp b/src/OpenGL/libGLESv2/Program.cpp
index b93bd2a..d2cff33 100644
--- a/src/OpenGL/libGLESv2/Program.cpp
+++ b/src/OpenGL/libGLESv2/Program.cpp
@@ -1153,6 +1153,7 @@
case GL_FLOAT_MAT4: applyUniformMatrix4fv(device, location, size, f); break;
case GL_SAMPLER_2D:
case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_2D_RECT_ARB:
case GL_SAMPLER_EXTERNAL_OES:
case GL_SAMPLER_3D_OES:
case GL_SAMPLER_2D_ARRAY:
@@ -1761,6 +1762,7 @@
case GL_INT_SAMPLER_3D:
case GL_UNSIGNED_INT_SAMPLER_3D:
case GL_SAMPLER_3D_OES: samplersVS[index].textureType = TEXTURE_3D; break;
+ case GL_SAMPLER_2D_RECT_ARB: samplersVS[index].textureType = TEXTURE_2D_RECT; break;
case GL_SAMPLER_EXTERNAL_OES: samplersVS[index].textureType = TEXTURE_EXTERNAL; break;
case GL_INT_SAMPLER_2D_ARRAY:
case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
@@ -1796,6 +1798,7 @@
case GL_INT_SAMPLER_3D:
case GL_UNSIGNED_INT_SAMPLER_3D:
case GL_SAMPLER_3D_OES: samplersPS[index].textureType = TEXTURE_3D; break;
+ case GL_SAMPLER_2D_RECT_ARB: samplersPS[index].textureType = TEXTURE_2D_RECT; break;
case GL_SAMPLER_EXTERNAL_OES: samplersPS[index].textureType = TEXTURE_EXTERNAL; break;
case GL_INT_SAMPLER_2D_ARRAY:
case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
diff --git a/src/OpenGL/libGLESv2/ResourceManager.cpp b/src/OpenGL/libGLESv2/ResourceManager.cpp
index 04e1f0d..51a7bc1 100644
--- a/src/OpenGL/libGLESv2/ResourceManager.cpp
+++ b/src/OpenGL/libGLESv2/ResourceManager.cpp
@@ -308,6 +308,10 @@
{
textureObject = new Texture2DArray(texture);
}
+ else if(type == TEXTURE_2D_RECT)
+ {
+ textureObject = new Texture2DRect(texture);
+ }
else
{
UNREACHABLE(type);
diff --git a/src/OpenGL/libGLESv2/ResourceManager.h b/src/OpenGL/libGLESv2/ResourceManager.h
index efd0e20..c076653 100644
--- a/src/OpenGL/libGLESv2/ResourceManager.h
+++ b/src/OpenGL/libGLESv2/ResourceManager.h
@@ -40,6 +40,7 @@
TEXTURE_3D,
TEXTURE_2D_ARRAY,
TEXTURE_CUBE,
+ TEXTURE_2D_RECT,
TEXTURE_EXTERNAL,
TEXTURE_TYPE_COUNT,
diff --git a/src/OpenGL/libGLESv2/Shader.cpp b/src/OpenGL/libGLESv2/Shader.cpp
index fe1b830..9cb6bd5 100644
--- a/src/OpenGL/libGLESv2/Shader.cpp
+++ b/src/OpenGL/libGLESv2/Shader.cpp
@@ -181,6 +181,7 @@
resources.OES_fragment_precision_high = 1;
resources.OES_EGL_image_external = 1;
resources.EXT_draw_buffers = 1;
+ resources.ARB_texture_rectangle = 1;
resources.MaxCallStackDepth = 64;
assembler->Init(resources);
diff --git a/src/OpenGL/libGLESv2/Texture.cpp b/src/OpenGL/libGLESv2/Texture.cpp
index c2665e7..9b3a5f0 100644
--- a/src/OpenGL/libGLESv2/Texture.cpp
+++ b/src/OpenGL/libGLESv2/Texture.cpp
@@ -22,6 +22,7 @@
#include "mathutil.h"
#include "Framebuffer.h"
#include "Device.hpp"
+#include "Shader.h"
#include "libEGL/Display.h"
#include "common/Surface.hpp"
#include "common/debug.h"
@@ -577,25 +578,25 @@
GLsizei Texture2D::getWidth(GLenum target, GLint level) const
{
- ASSERT(target == GL_TEXTURE_2D);
+ ASSERT(target == getTarget());
return image[level] ? image[level]->getWidth() : 0;
}
GLsizei Texture2D::getHeight(GLenum target, GLint level) const
{
- ASSERT(target == GL_TEXTURE_2D);
+ ASSERT(target == getTarget());
return image[level] ? image[level]->getHeight() : 0;
}
GLenum Texture2D::getFormat(GLenum target, GLint level) const
{
- ASSERT(target == GL_TEXTURE_2D);
+ ASSERT(target == getTarget());
return image[level] ? image[level]->getFormat() : GL_NONE;
}
GLenum Texture2D::getType(GLenum target, GLint level) const
{
- ASSERT(target == GL_TEXTURE_2D);
+ ASSERT(target == getTarget());
return image[level] ? image[level]->getType() : GL_NONE;
}
@@ -913,7 +914,7 @@
Renderbuffer *Texture2D::getRenderbuffer(GLenum target, GLint level)
{
- if(target != GL_TEXTURE_2D)
+ if(target != getTarget())
{
return error(GL_INVALID_OPERATION, (Renderbuffer*)nullptr);
}
@@ -932,7 +933,7 @@
egl::Image *Texture2D::getRenderTarget(GLenum target, unsigned int level)
{
- ASSERT(target == GL_TEXTURE_2D);
+ ASSERT(target == getTarget());
ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
if(image[level])
@@ -945,7 +946,7 @@
bool Texture2D::isShared(GLenum target, unsigned int level) const
{
- ASSERT(target == GL_TEXTURE_2D);
+ ASSERT(target == getTarget());
ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
if(mSurface) // Bound to an EGLSurface
@@ -961,6 +962,15 @@
return image[level]->isShared();
}
+Texture2DRect::Texture2DRect(GLuint name) : Texture2D(name)
+{
+}
+
+GLenum Texture2DRect::getTarget() const
+{
+ return GL_TEXTURE_RECTANGLE_ARB;
+}
+
TextureCubeMap::TextureCubeMap(GLuint name) : Texture(name)
{
for(int f = 0; f < 6; f++)
diff --git a/src/OpenGL/libGLESv2/Texture.h b/src/OpenGL/libGLESv2/Texture.h
index 53b4bfb..026c75a 100644
--- a/src/OpenGL/libGLESv2/Texture.h
+++ b/src/OpenGL/libGLESv2/Texture.h
@@ -203,6 +203,14 @@
unsigned int mProxyRefs;
};
+class Texture2DRect : public Texture2D
+{
+public:
+ explicit Texture2DRect(GLuint name);
+
+ GLenum getTarget() const override;
+};
+
class TextureCubeMap : public Texture
{
public:
diff --git a/src/OpenGL/libGLESv2/libGLESv2.cpp b/src/OpenGL/libGLESv2/libGLESv2.cpp
index 6db0a79..aa743e7 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv2.cpp
@@ -389,6 +389,9 @@
case GL_TEXTURE_3D:
context->bindTexture3D(texture);
break;
+ case GL_TEXTURE_RECTANGLE_ARB:
+ context->bindTexture2DRect(texture);
+ break;
default:
return error(GL_INVALID_ENUM);
}
@@ -836,6 +839,7 @@
switch(target)
{
case GL_TEXTURE_2D:
+ case GL_TEXTURE_RECTANGLE_ARB:
if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
{
@@ -868,9 +872,9 @@
return error(GL_INVALID_VALUE);
}
- if(target == GL_TEXTURE_2D)
+ if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB)
{
- es2::Texture2D *texture = context->getTexture2D();
+ es2::Texture2D *texture = context->getTexture2D(target);
if(!texture)
{
@@ -958,9 +962,9 @@
GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_NONE);
- if(target == GL_TEXTURE_2D)
+ if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB)
{
- es2::Texture2D *texture = context->getTexture2D();
+ es2::Texture2D *texture = context->getTexture2D(target);
GLenum validationError = ValidateSubImageParams(true, false, target, level, xoffset, yoffset, width, height, format, GL_NONE, texture, context->getClientVersion());
if(validationError != GL_NONE)
@@ -1021,6 +1025,7 @@
switch(target)
{
case GL_TEXTURE_2D:
+ case GL_TEXTURE_RECTANGLE_ARB:
if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
{
@@ -1069,9 +1074,9 @@
return;
}
- if(target == GL_TEXTURE_2D)
+ if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB)
{
- es2::Texture2D *texture = context->getTexture2D();
+ es2::Texture2D *texture = context->getTexture2D(target);
if(!texture)
{
@@ -1141,9 +1146,9 @@
es2::Texture *texture = nullptr;
- if(target == GL_TEXTURE_2D)
+ if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB)
{
- texture = context->getTexture2D();
+ texture = context->getTexture2D(target);
}
else if(es2::IsCubemapTextureTarget(target))
{
@@ -2097,6 +2102,12 @@
return error(GL_INVALID_OPERATION);
}
break;
+ case GL_TEXTURE_RECTANGLE_ARB:
+ if(tex->getTarget() != GL_TEXTURE_RECTANGLE_ARB)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
@@ -2285,6 +2296,9 @@
case GL_TEXTURE_3D:
texture = context->getTexture3D();
break;
+ case GL_TEXTURE_RECTANGLE_ARB:
+ texture = context->getTexture2DRect();
+ break;
default:
return error(GL_INVALID_ENUM);
}
@@ -3588,6 +3602,9 @@
case GL_TEXTURE_3D:
texture = context->getTexture3D();
break;
+ case GL_TEXTURE_RECTANGLE_ARB:
+ texture = context->getTexture2DRect();
+ break;
default:
return error(GL_INVALID_ENUM);
}
@@ -3741,6 +3758,9 @@
case GL_TEXTURE_3D:
texture = context->getTexture3D();
break;
+ case GL_TEXTURE_RECTANGLE_ARB:
+ texture = context->getTexture2DRect();
+ break;
default:
return error(GL_INVALID_ENUM);
}
@@ -5042,6 +5062,7 @@
switch(target)
{
case GL_TEXTURE_2D:
+ case GL_TEXTURE_RECTANGLE_ARB:
if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
{
@@ -5077,9 +5098,9 @@
return error(validationError);
}
- if(target == GL_TEXTURE_2D)
+ if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB)
{
- es2::Texture2D *texture = context->getTexture2D();
+ es2::Texture2D *texture = context->getTexture2D(target);
if(!texture)
{
@@ -5138,6 +5159,9 @@
case GL_TEXTURE_EXTERNAL_OES:
texture = context->getTextureExternal();
break;
+ case GL_TEXTURE_RECTANGLE_ARB:
+ texture = context->getTexture2DRect();
+ break;
default:
return error(GL_INVALID_ENUM);
}
@@ -5287,6 +5311,9 @@
case GL_TEXTURE_EXTERNAL_OES:
texture = context->getTextureExternal();
break;
+ case GL_TEXTURE_RECTANGLE_ARB:
+ texture = context->getTexture2DRect();
+ break;
default:
return error(GL_INVALID_ENUM);
}
@@ -5432,9 +5459,9 @@
if(context)
{
- if(target == GL_TEXTURE_2D)
+ if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB)
{
- es2::Texture2D *texture = context->getTexture2D();
+ es2::Texture2D *texture = context->getTexture2D(target);
GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, width, height, format, type, texture, context->getClientVersion());
if(validationError != GL_NONE)
@@ -6676,6 +6703,7 @@
switch(target)
{
case GL_TEXTURE_2D:
+ case GL_TEXTURE_RECTANGLE_ARB:
case GL_TEXTURE_EXTERNAL_OES:
break;
default:
@@ -6686,14 +6714,7 @@
if(context)
{
- es2::Texture2D *texture = nullptr;
-
- switch(target)
- {
- case GL_TEXTURE_2D: texture = context->getTexture2D(); break;
- case GL_TEXTURE_EXTERNAL_OES: texture = context->getTextureExternal(); break;
- default: UNREACHABLE(target);
- }
+ es2::Texture2D *texture = context->getTexture2D(target);
if(!texture)
{
diff --git a/src/OpenGL/libGLESv2/libGLESv3.cpp b/src/OpenGL/libGLESv2/libGLESv3.cpp
index 056ef53..0a880ad 100644
--- a/src/OpenGL/libGLESv2/libGLESv3.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv3.cpp
@@ -3937,41 +3937,42 @@
switch(target)
{
case GL_TEXTURE_2D:
+ case GL_TEXTURE_RECTANGLE_ARB:
+ {
+ es2::Texture2D *texture = context->getTexture2D(target);
+ if(!texture || texture->name == 0 || texture->getImmutableFormat() == GL_TRUE)
{
- es2::Texture2D *texture = context->getTexture2D();
- if(!texture || texture->name == 0 || texture->getImmutableFormat() == GL_TRUE)
- {
- return error(GL_INVALID_OPERATION);
- }
+ return error(GL_INVALID_OPERATION);
+ }
for(int level = 0; level < levels; level++)
- {
+ {
texture->setImage(context, level, width, height, sizedInternalFormat, sizedInternalFormat, type, context->getUnpackInfo(), nullptr);
- width = std::max(1, (width / 2));
- height = std::max(1, (height / 2));
- }
- texture->makeImmutable(levels);
+ width = std::max(1, (width / 2));
+ height = std::max(1, (height / 2));
}
+ texture->makeImmutable(levels);
+ }
break;
case GL_TEXTURE_CUBE_MAP:
+ {
+ es2::TextureCubeMap *texture = context->getTextureCubeMap();
+ if(!texture || texture->name == 0 || texture->getImmutableFormat())
{
- es2::TextureCubeMap *texture = context->getTextureCubeMap();
- if(!texture || texture->name == 0 || texture->getImmutableFormat())
- {
- return error(GL_INVALID_OPERATION);
- }
+ return error(GL_INVALID_OPERATION);
+ }
for(int level = 0; level < levels; level++)
- {
+ {
for(int face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; face++)
- {
+ {
texture->setImage(context, face, level, width, height, sizedInternalFormat, sizedInternalFormat, type, context->getUnpackInfo(), nullptr);
- }
- width = std::max(1, (width / 2));
- height = std::max(1, (height / 2));
}
- texture->makeImmutable(levels);
+ width = std::max(1, (width / 2));
+ height = std::max(1, (height / 2));
}
+ texture->makeImmutable(levels);
+ }
break;
default:
return error(GL_INVALID_ENUM);
@@ -4003,52 +4004,52 @@
switch(target)
{
case GL_TEXTURE_3D:
+ {
+ if(levels > es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || levels > (log2(std::max(std::max(width, height), depth)) + 1))
{
- if(levels > es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || levels > (log2(std::max(std::max(width, height), depth)) + 1))
- {
- return error(GL_INVALID_OPERATION);
- }
+ return error(GL_INVALID_OPERATION);
+ }
- es2::Texture3D *texture = context->getTexture3D();
- if(!texture || texture->name == 0 || texture->getImmutableFormat() == GL_TRUE)
- {
- return error(GL_INVALID_OPERATION);
- }
+ es2::Texture3D *texture = context->getTexture3D();
+ if(!texture || texture->name == 0 || texture->getImmutableFormat() == GL_TRUE)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
for(int level = 0; level < levels; level++)
- {
+ {
texture->setImage(context, level, width, height, depth, sizedInternalFormat, sizedInternalFormat, type, context->getUnpackInfo(), nullptr);
- width = std::max(1, (width / 2));
- height = std::max(1, (height / 2));
- depth = std::max(1, (depth / 2));
- }
- texture->makeImmutable(levels);
+ width = std::max(1, (width / 2));
+ height = std::max(1, (height / 2));
+ depth = std::max(1, (depth / 2));
}
+ texture->makeImmutable(levels);
+ }
break;
case GL_TEXTURE_2D_ARRAY:
+ {
+ if(levels > es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || levels > (log2(std::max(width, height)) + 1))
{
- if(levels > es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || levels > (log2(std::max(width, height)) + 1))
- {
- return error(GL_INVALID_OPERATION);
- }
+ return error(GL_INVALID_OPERATION);
+ }
- es2::Texture3D *texture = context->getTexture2DArray();
- if(!texture || texture->name == 0 || texture->getImmutableFormat())
- {
- return error(GL_INVALID_OPERATION);
- }
+ es2::Texture3D *texture = context->getTexture2DArray();
+ if(!texture || texture->name == 0 || texture->getImmutableFormat())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
for(int level = 0; level < levels; level++)
- {
+ {
for(int face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; face++)
- {
+ {
texture->setImage(context, level, width, height, depth, sizedInternalFormat, sizedInternalFormat, type, context->getUnpackInfo(), nullptr);
- }
- width = std::max(1, (width / 2));
- height = std::max(1, (height / 2));
}
- texture->makeImmutable(levels);
+ width = std::max(1, (width / 2));
+ height = std::max(1, (height / 2));
}
+ texture->makeImmutable(levels);
+ }
break;
default:
return error(GL_INVALID_ENUM);
diff --git a/src/OpenGL/libGLESv2/utilities.cpp b/src/OpenGL/libGLESv2/utilities.cpp
index 2318057..96c83d4 100644
--- a/src/OpenGL/libGLESv2/utilities.cpp
+++ b/src/OpenGL/libGLESv2/utilities.cpp
@@ -20,6 +20,7 @@
#include "main.h"
#include "mathutil.h"
#include "Context.h"
+#include "Shader.h"
#include "common/debug.h"
#include <limits>
@@ -183,6 +184,7 @@
case GL_UNSIGNED_INT:
case GL_SAMPLER_2D:
case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_2D_RECT_ARB:
case GL_SAMPLER_EXTERNAL_OES:
case GL_SAMPLER_3D_OES:
case GL_SAMPLER_2D_ARRAY:
@@ -260,6 +262,7 @@
case GL_INT:
case GL_SAMPLER_2D:
case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_2D_RECT_ARB:
case GL_SAMPLER_EXTERNAL_OES:
case GL_SAMPLER_3D_OES:
case GL_SAMPLER_2D_ARRAY:
@@ -309,6 +312,7 @@
{
case GL_SAMPLER_2D:
case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_2D_RECT_ARB:
case GL_SAMPLER_EXTERNAL_OES:
case GL_SAMPLER_3D_OES:
case GL_SAMPLER_2D_ARRAY:
@@ -353,6 +357,7 @@
case GL_UNSIGNED_INT_VEC4:
case GL_SAMPLER_2D:
case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_2D_RECT_ARB:
case GL_SAMPLER_EXTERNAL_OES:
case GL_SAMPLER_3D_OES:
case GL_SAMPLER_2D_ARRAY:
@@ -771,7 +776,7 @@
bool IsTextureTarget(GLenum target)
{
- return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target) || target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY;
+ return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target) || target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_RECTANGLE_ARB;
}
GLenum ValidateTextureFormatType(GLenum format, GLenum type, GLint internalformat, GLint clientVersion)