diff --git a/cogl/cogl/cogl-private.h b/cogl/cogl/cogl-private.h index 5a714fc1a..f842047f0 100644 --- a/cogl/cogl/cogl-private.h +++ b/cogl/cogl/cogl-private.h @@ -57,6 +57,7 @@ typedef enum COGL_PRIVATE_FEATURE_ALPHA_TEXTURES, COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE, COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL, + COGL_PRIVATE_FEATURE_TEXTURE_LOD_BIAS, COGL_PRIVATE_FEATURE_OES_EGL_SYNC, /* If this is set then the winsys is responsible for queueing dirty * events. Otherwise a dirty event will be queued when the onscreen diff --git a/cogl/cogl/driver/gl/cogl-pipeline-opengl.c b/cogl/cogl/driver/gl/cogl-pipeline-opengl.c index 8986e0466..d1e76f965 100644 --- a/cogl/cogl/driver/gl/cogl-pipeline-opengl.c +++ b/cogl/cogl/driver/gl/cogl-pipeline-opengl.c @@ -682,6 +682,22 @@ _cogl_sampler_gl_init (CoglContext *context, CoglSamplerCacheEntry *entry) GE (context, glSamplerParameteri (entry->sampler_object, GL_TEXTURE_WRAP_T, entry->wrap_mode_t) ); + + /* While COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS implies support for + * GL_TEXTURE_LOD_BIAS in GL, the same is not true in GLES. So check, + * and also only apply GL_TEXTURE_LOD_BIAS in mipmap modes: + */ + if (_cogl_has_private_feature (context, + COGL_PRIVATE_FEATURE_TEXTURE_LOD_BIAS) && + entry->min_filter != GL_NEAREST && + entry->min_filter != GL_LINEAR) + { + GLfloat bias = _cogl_texture_min_filter_get_lod_bias (entry->min_filter); + + GE (context, glSamplerParameterf (entry->sampler_object, + GL_TEXTURE_LOD_BIAS, + bias)); + } } else { diff --git a/cogl/cogl/driver/gl/cogl-texture-2d-gl.c b/cogl/cogl/driver/gl/cogl-texture-2d-gl.c index 23111eabf..61ccd75cf 100644 --- a/cogl/cogl/driver/gl/cogl-texture-2d-gl.c +++ b/cogl/cogl/driver/gl/cogl-texture-2d-gl.c @@ -470,6 +470,15 @@ _cogl_texture_2d_gl_flush_legacy_texobj_filters (CoglTexture *tex, tex_2d->gl_texture); GE( ctx, glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter) ); GE( ctx, glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter) ); + + if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_LOD_BIAS) && + min_filter != GL_NEAREST && + min_filter != GL_LINEAR) + { + GLfloat bias = _cogl_texture_min_filter_get_lod_bias (min_filter); + + GE (ctx, glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, bias)); + } } void diff --git a/cogl/cogl/driver/gl/cogl-texture-gl-private.h b/cogl/cogl/driver/gl/cogl-texture-gl-private.h index a8fbd2866..7804f8e7e 100644 --- a/cogl/cogl/driver/gl/cogl-texture-gl-private.h +++ b/cogl/cogl/driver/gl/cogl-texture-gl-private.h @@ -62,4 +62,11 @@ _cogl_texture_gl_generate_mipmaps (CoglTexture *texture); GLenum _cogl_texture_gl_get_format (CoglTexture *texture); +static inline GLfloat +_cogl_texture_min_filter_get_lod_bias (GLenum min_filter) +{ + return (min_filter == GL_NEAREST_MIPMAP_NEAREST || + min_filter == GL_LINEAR_MIPMAP_NEAREST) ? -0.5f : 0.0f; +} + #endif /* _COGL_TEXTURE_GL_PRIVATE_H_ */ diff --git a/cogl/cogl/driver/gl/cogl-util-gl-private.h b/cogl/cogl/driver/gl/cogl-util-gl-private.h index be8fa1eeb..2929e1c2d 100644 --- a/cogl/cogl/driver/gl/cogl-util-gl-private.h +++ b/cogl/cogl/driver/gl/cogl-util-gl-private.h @@ -250,4 +250,8 @@ cogl_gl_get_gpu_time_ns (CoglContext *context); #define GL_QUERY_RESULT 0x8866 #endif +#ifndef GL_TEXTURE_LOD_BIAS +#define GL_TEXTURE_LOD_BIAS 0x8501 +#endif + #endif /* _COGL_UTIL_GL_PRIVATE_H_ */ diff --git a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c index e498263aa..7c9449f5b 100644 --- a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c +++ b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c @@ -526,6 +526,13 @@ _cogl_driver_update_features (CoglContext *ctx, COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL, TRUE); + if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 3, 1) || + _cogl_check_extension ("GL_EXT_texture_lod_bias", gl_extensions)) + { + COGL_FLAGS_SET (private_features, + COGL_PRIVATE_FEATURE_TEXTURE_LOD_BIAS, TRUE); + } + if (ctx->glFenceSync) COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_FENCE, TRUE); diff --git a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c index de080a99d..0904f5a04 100644 --- a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c +++ b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c @@ -437,6 +437,12 @@ _cogl_driver_update_features (CoglContext *context, COGL_FEATURE_ID_TEXTURE_RG, TRUE); + if (_cogl_check_extension ("GL_EXT_texture_lod_bias", gl_extensions)) + { + COGL_FLAGS_SET (private_features, + COGL_PRIVATE_FEATURE_TEXTURE_LOD_BIAS, TRUE); + } + if (context->glGenQueries && context->glQueryCounter && context->glGetInteger64v) COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_TIMESTAMP_QUERY, TRUE); diff --git a/cogl/cogl/gl-prototypes/cogl-all-functions.h b/cogl/cogl/gl-prototypes/cogl-all-functions.h index fe9feaa5c..f98ea02f6 100644 --- a/cogl/cogl/gl-prototypes/cogl-all-functions.h +++ b/cogl/cogl/gl-prototypes/cogl-all-functions.h @@ -178,6 +178,10 @@ COGL_EXT_FUNCTION (void, glSamplerParameteri, (GLuint sampler, GLenum pname, GLint param)) +COGL_EXT_FUNCTION (void, glSamplerParameterf, + (GLuint sampler, + GLenum pname, + GLfloat param)) COGL_EXT_END () COGL_EXT_BEGIN (only_gl3, 3, 0, diff --git a/cogl/cogl/gl-prototypes/cogl-core-functions.h b/cogl/cogl/gl-prototypes/cogl-core-functions.h index e04b443ae..e362e797d 100644 --- a/cogl/cogl/gl-prototypes/cogl-core-functions.h +++ b/cogl/cogl/gl-prototypes/cogl-core-functions.h @@ -174,6 +174,8 @@ COGL_EXT_FUNCTION (void, glTexImage2D, const GLvoid* pixels)) COGL_EXT_FUNCTION (void, glTexParameteri, (GLenum target, GLenum pname, GLint param)) +COGL_EXT_FUNCTION (void, glTexParameterf, + (GLenum target, GLenum pname, GLfloat param)) COGL_EXT_FUNCTION (void, glTexParameteriv, (GLenum target, GLenum pname, const GLint* params)) COGL_EXT_FUNCTION (void, glTexSubImage2D,