Fix texture completeness test when using sampler objects.
When a sampler object is bound to a texture unit, it overrides the
texture's filter modes. A texture without mipmaps can thus be complete
even if it has a filter mode which requires mipmaps, if there's a
sampler object with a filter mode which doesn't require mipmaps.
Fixes https://github.com/google/filament/pull/220
Change-Id: I200c0bba467d904ac0fd6d93b935e052c47b2030
Reviewed-on: https://swiftshader-review.googlesource.com/20529
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Chris Forbes <chrisforbes@google.com>
Reviewed-by: Jeff McGlynn <jwmcglynn@google.com>
Tested-by: Jeff McGlynn <jwmcglynn@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp
index 2273e65..584b56d 100644
--- a/src/OpenGL/libGLESv2/Context.cpp
+++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -3086,13 +3086,13 @@
TextureType textureType = programObject->getSamplerTextureType(samplerType, samplerIndex);
Texture *texture = getSamplerTexture(textureUnit, textureType);
+ Sampler *samplerObject = mState.sampler[textureUnit];
- if(texture->isSamplerComplete())
+ if(texture->isSamplerComplete(samplerObject))
{
GLenum wrapS, wrapT, wrapR, minFilter, magFilter, compFunc, compMode;
GLfloat minLOD, maxLOD, maxAnisotropy;
- Sampler *samplerObject = mState.sampler[textureUnit];
if(samplerObject)
{
wrapS = samplerObject->getWrapS();
@@ -4372,12 +4372,12 @@
return EGL_BAD_ACCESS;
}
- if(textureLevel != 0 && !texture->isSamplerComplete())
+ if(textureLevel != 0 && !texture->isSamplerComplete(nullptr))
{
return EGL_BAD_PARAMETER;
}
- if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getTopLevel() == 0))
+ if(textureLevel == 0 && !(texture->isSamplerComplete(nullptr) && texture->getTopLevel() == 0))
{
return EGL_BAD_PARAMETER;
}
diff --git a/src/OpenGL/libGLESv2/Texture.cpp b/src/OpenGL/libGLESv2/Texture.cpp
index dae52ee..4e63750 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 "Sampler.h"
#include "Shader.h"
#include "libEGL/Display.h"
#include "common/Surface.hpp"
@@ -397,9 +398,11 @@
return true;
}
-bool Texture::isMipmapFiltered() const
+bool Texture::isMipmapFiltered(Sampler *sampler) const
{
- switch(mMinFilter)
+ GLenum minFilter = sampler ? sampler->getMinFilter() : mMinFilter;
+
+ switch(minFilter)
{
case GL_NEAREST:
case GL_LINEAR:
@@ -409,7 +412,7 @@
case GL_NEAREST_MIPMAP_LINEAR:
case GL_LINEAR_MIPMAP_LINEAR:
return true;
- default: UNREACHABLE(mMinFilter);
+ default: UNREACHABLE(minFilter);
}
return false;
@@ -517,7 +520,6 @@
int Texture2D::getTopLevel() const
{
- ASSERT(isSamplerComplete());
int level = mBaseLevel;
while(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[level])
@@ -702,7 +704,7 @@
}
// Tests for 2D texture sampling completeness. [OpenGL ES 3.0.5] section 3.8.13 page 160.
-bool Texture2D::isSamplerComplete() const
+bool Texture2D::isSamplerComplete(Sampler *sampler) const
{
if(!image[mBaseLevel])
{
@@ -717,7 +719,7 @@
return false;
}
- if(isMipmapFiltered())
+ if(isMipmapFiltered(sampler))
{
if(!isMipmapComplete())
{
@@ -1021,7 +1023,6 @@
int TextureCubeMap::getTopLevel() const
{
- ASSERT(isSamplerComplete());
int level = mBaseLevel;
while(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[0][level])
@@ -1078,7 +1079,7 @@
}
// Tests for cube map sampling completeness. [OpenGL ES 3.0.5] section 3.8.13 page 161.
-bool TextureCubeMap::isSamplerComplete() const
+bool TextureCubeMap::isSamplerComplete(Sampler *sampler) const
{
for(int face = 0; face < 6; face++)
{
@@ -1095,7 +1096,7 @@
return false;
}
- if(!isMipmapFiltered())
+ if(!isMipmapFiltered(sampler))
{
if(!isCubeComplete())
{
@@ -1545,7 +1546,6 @@
int Texture3D::getTopLevel() const
{
- ASSERT(isSamplerComplete());
int level = mBaseLevel;
while(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[level])
@@ -1698,7 +1698,7 @@
}
// Tests for 3D texture sampling completeness. [OpenGL ES 3.0.5] section 3.8.13 page 160.
-bool Texture3D::isSamplerComplete() const
+bool Texture3D::isSamplerComplete(Sampler *sampler) const
{
if(!image[mBaseLevel])
{
@@ -1714,7 +1714,7 @@
return false;
}
- if(isMipmapFiltered())
+ if(isMipmapFiltered(sampler))
{
if(!isMipmapComplete())
{
diff --git a/src/OpenGL/libGLESv2/Texture.h b/src/OpenGL/libGLESv2/Texture.h
index ddd915e..017acab 100644
--- a/src/OpenGL/libGLESv2/Texture.h
+++ b/src/OpenGL/libGLESv2/Texture.h
@@ -33,6 +33,8 @@
namespace es2
{
+class Sampler;
+
enum
{
IMPLEMENTATION_MAX_TEXTURE_LEVELS = sw::MIPMAP_LEVELS,
@@ -99,7 +101,7 @@
virtual int getTopLevel() const = 0;
virtual bool requiresSync() const = 0;
- virtual bool isSamplerComplete() const = 0;
+ virtual bool isSamplerComplete(Sampler *sampler) const = 0;
virtual bool isCompressed(GLenum target, GLint level) const = 0;
virtual bool isDepth(GLenum target, GLint level) const = 0;
@@ -121,7 +123,7 @@
bool copy(egl::Image *source, const sw::SliceRect &sourceRect, GLint xoffset, GLint yoffset, GLint zoffset, egl::Image *dest);
- bool isMipmapFiltered() const;
+ bool isMipmapFiltered(Sampler *sampler) const;
GLenum mMinFilter;
GLenum mMagFilter;
@@ -171,7 +173,7 @@
void setSharedImage(egl::Image *image);
- bool isSamplerComplete() const override;
+ bool isSamplerComplete(Sampler *sampler) const override;
bool isCompressed(GLenum target, GLint level) const override;
bool isDepth(GLenum target, GLint level) const override;
void bindTexImage(gl::Surface *surface);
@@ -238,7 +240,7 @@
void copyImage(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source);
void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source) override;
- bool isSamplerComplete() const override;
+ bool isSamplerComplete(Sampler *sampler) const override;
bool isCompressed(GLenum target, GLint level) const override;
bool isDepth(GLenum target, GLint level) const override;
void releaseTexImage() override;
@@ -301,7 +303,7 @@
void setSharedImage(egl::Image *image);
- bool isSamplerComplete() const override;
+ bool isSamplerComplete(Sampler *sampler) const override;
bool isCompressed(GLenum target, GLint level) const override;
bool isDepth(GLenum target, GLint level) const override;
void releaseTexImage() override;