From 12fb7d700861fb0af639fa21c1e3b65981ee81e4 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Mon, 20 Apr 2020 14:17:53 +0200 Subject: [PATCH] mesa: add gl_coontext::ForceIntegerTexNearest MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Some applications incorrectly use GL_LINEAR* values for integers texture. copyimage.c already implemented a tolerance for such app in prepare_target_err. This commit adds a boolean that will treat GL_LINEAR* filters as GL_NEAREST for integer textures. CC: 20.1 Reviewed-by: Timothy Arceri Reviewed-by: Marek Olšák Part-of: --- src/mesa/main/mtypes.h | 5 +++++ src/mesa/main/texobj.h | 15 ++++++++++--- src/mesa/main/texstate.c | 12 +++++++---- src/mesa/main/texturebindless.c | 27 ++++++++++++++++-------- src/mesa/state_tracker/st_atom_sampler.c | 9 ++++++-- src/mesa/swrast/s_texfilter.c | 3 ++- 6 files changed, 52 insertions(+), 19 deletions(-) diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 7e31adcfaad..e334de0672d 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -3871,6 +3871,11 @@ struct gl_constants */ GLboolean GLSLZeroInit; + /** + * Treat integer textures using GL_LINEAR filters as GL_NEAREST. + */ + GLboolean ForceIntegerTexNearest; + /** * Does the driver support real 32-bit integers? (Otherwise, integers are * simulated via floats.) diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h index be8c6e4e6c2..91901617c68 100644 --- a/src/mesa/main/texobj.h +++ b/src/mesa/main/texobj.h @@ -122,7 +122,8 @@ _mesa_unlock_texture(struct gl_context *ctx, struct gl_texture_object *texObj) /** Is the texture "complete" with respect to the given sampler state? */ static inline GLboolean _mesa_is_texture_complete(const struct gl_texture_object *texObj, - const struct gl_sampler_object *sampler) + const struct gl_sampler_object *sampler, + bool linear_as_nearest_for_int_tex) { struct gl_texture_image *img = texObj->Image[0][texObj->BaseLevel]; bool isMultisample = img && img->NumSamples >= 2; @@ -149,8 +150,16 @@ _mesa_is_texture_complete(const struct gl_texture_object *texObj, (sampler->MagFilter != GL_NEAREST || (sampler->MinFilter != GL_NEAREST && sampler->MinFilter != GL_NEAREST_MIPMAP_NEAREST))) { - /* If the format is integer, only nearest filtering is allowed */ - return GL_FALSE; + /* If the format is integer, only nearest filtering is allowed, + * but some applications (eg: Grid Autosport) uses the default + * filtering values. + */ + if (texObj->_IsIntegerFormat && + linear_as_nearest_for_int_tex) { + /* Skip return */ + } else { + return GL_FALSE; + } } /* Section 8.17 (texture completeness) of the OpenGL 4.6 core profile spec: diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index dfcfc4e8015..f21f83edba5 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -670,11 +670,13 @@ update_single_program_texture(struct gl_context *ctx, struct gl_program *prog, texUnit->Sampler : &texObj->Sampler; if (likely(texObj)) { - if (_mesa_is_texture_complete(texObj, sampler)) + if (_mesa_is_texture_complete(texObj, sampler, + ctx->Const.ForceIntegerTexNearest)) return texObj; _mesa_test_texobj_completeness(ctx, texObj); - if (_mesa_is_texture_complete(texObj, sampler)) + if (_mesa_is_texture_complete(texObj, sampler, + ctx->Const.ForceIntegerTexNearest)) return texObj; } @@ -816,10 +818,12 @@ update_ff_texture_state(struct gl_context *ctx, struct gl_sampler_object *sampler = texUnit->Sampler ? texUnit->Sampler : &texObj->Sampler; - if (!_mesa_is_texture_complete(texObj, sampler)) { + if (!_mesa_is_texture_complete(texObj, sampler, + ctx->Const.ForceIntegerTexNearest)) { _mesa_test_texobj_completeness(ctx, texObj); } - if (_mesa_is_texture_complete(texObj, sampler)) { + if (_mesa_is_texture_complete(texObj, sampler, + ctx->Const.ForceIntegerTexNearest)) { _mesa_reference_texobj(&texUnit->_Current, texObj); complete = true; break; diff --git a/src/mesa/main/texturebindless.c b/src/mesa/main/texturebindless.c index c1cef4b1e46..a4d700e6362 100644 --- a/src/mesa/main/texturebindless.c +++ b/src/mesa/main/texturebindless.c @@ -546,7 +546,8 @@ _mesa_GetTextureHandleARB_no_error(GLuint texture) GET_CURRENT_CONTEXT(ctx); texObj = _mesa_lookup_texture(ctx, texture); - if (!_mesa_is_texture_complete(texObj, &texObj->Sampler)) + if (!_mesa_is_texture_complete(texObj, &texObj->Sampler, + ctx->Const.ForceIntegerTexNearest)) _mesa_test_texobj_completeness(ctx, texObj); return get_texture_handle(ctx, texObj, &texObj->Sampler); @@ -585,9 +586,11 @@ _mesa_GetTextureHandleARB(GLuint texture) * GetTextureSamplerHandleARB if the texture object specified by * is not complete." */ - if (!_mesa_is_texture_complete(texObj, &texObj->Sampler)) { + if (!_mesa_is_texture_complete(texObj, &texObj->Sampler, + ctx->Const.ForceIntegerTexNearest)) { _mesa_test_texobj_completeness(ctx, texObj); - if (!_mesa_is_texture_complete(texObj, &texObj->Sampler)) { + if (!_mesa_is_texture_complete(texObj, &texObj->Sampler, + ctx->Const.ForceIntegerTexNearest)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTextureHandleARB(incomplete texture)"); return 0; @@ -614,7 +617,8 @@ _mesa_GetTextureSamplerHandleARB_no_error(GLuint texture, GLuint sampler) texObj = _mesa_lookup_texture(ctx, texture); sampObj = _mesa_lookup_samplerobj(ctx, sampler); - if (!_mesa_is_texture_complete(texObj, sampObj)) + if (!_mesa_is_texture_complete(texObj, sampObj, + ctx->Const.ForceIntegerTexNearest)) _mesa_test_texobj_completeness(ctx, texObj); return get_texture_handle(ctx, texObj, sampObj); @@ -667,9 +671,11 @@ _mesa_GetTextureSamplerHandleARB(GLuint texture, GLuint sampler) * GetTextureSamplerHandleARB if the texture object specified by * is not complete." */ - if (!_mesa_is_texture_complete(texObj, sampObj)) { + if (!_mesa_is_texture_complete(texObj, sampObj, + ctx->Const.ForceIntegerTexNearest)) { _mesa_test_texobj_completeness(ctx, texObj); - if (!_mesa_is_texture_complete(texObj, sampObj)) { + if (!_mesa_is_texture_complete(texObj, sampObj, + ctx->Const.ForceIntegerTexNearest)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTextureSamplerHandleARB(incomplete texture)"); return 0; @@ -786,7 +792,8 @@ _mesa_GetImageHandleARB_no_error(GLuint texture, GLint level, GLboolean layered, GET_CURRENT_CONTEXT(ctx); texObj = _mesa_lookup_texture(ctx, texture); - if (!_mesa_is_texture_complete(texObj, &texObj->Sampler)) + if (!_mesa_is_texture_complete(texObj, &texObj->Sampler, + ctx->Const.ForceIntegerTexNearest)) _mesa_test_texobj_completeness(ctx, texObj); return get_image_handle(ctx, texObj, level, layered, layer, format); @@ -845,9 +852,11 @@ _mesa_GetImageHandleARB(GLuint texture, GLint level, GLboolean layered, * is not a three-dimensional, one-dimensional array, two * dimensional array, cube map, or cube map array texture." */ - if (!_mesa_is_texture_complete(texObj, &texObj->Sampler)) { + if (!_mesa_is_texture_complete(texObj, &texObj->Sampler, + ctx->Const.ForceIntegerTexNearest)) { _mesa_test_texobj_completeness(ctx, texObj); - if (!_mesa_is_texture_complete(texObj, &texObj->Sampler)) { + if (!_mesa_is_texture_complete(texObj, &texObj->Sampler, + ctx->Const.ForceIntegerTexNearest)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetImageHandleARB(incomplete texture)"); return 0; diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c index b74d47b691f..7ae981b71b4 100644 --- a/src/mesa/state_tracker/st_atom_sampler.c +++ b/src/mesa/state_tracker/st_atom_sampler.c @@ -114,9 +114,14 @@ st_convert_sampler(const struct st_context *st, sampler->wrap_t = gl_wrap_xlate(msamp->WrapT); sampler->wrap_r = gl_wrap_xlate(msamp->WrapR); - sampler->min_img_filter = gl_filter_to_img_filter(msamp->MinFilter); + if (texobj->_IsIntegerFormat && st->ctx->Const.ForceIntegerTexNearest) { + sampler->min_img_filter = gl_filter_to_img_filter(GL_NEAREST); + sampler->mag_img_filter = gl_filter_to_img_filter(GL_NEAREST); + } else { + sampler->min_img_filter = gl_filter_to_img_filter(msamp->MinFilter); + sampler->mag_img_filter = gl_filter_to_img_filter(msamp->MagFilter); + } sampler->min_mip_filter = gl_filter_to_mip_filter(msamp->MinFilter); - sampler->mag_img_filter = gl_filter_to_img_filter(msamp->MagFilter); if (texobj->Target != GL_TEXTURE_RECTANGLE_ARB) sampler->normalized_coords = 1; diff --git a/src/mesa/swrast/s_texfilter.c b/src/mesa/swrast/s_texfilter.c index 7f1354785a4..381eb343812 100644 --- a/src/mesa/swrast/s_texfilter.c +++ b/src/mesa/swrast/s_texfilter.c @@ -3712,7 +3712,8 @@ _swrast_choose_texture_sample_func( struct gl_context *ctx, const struct gl_texture_object *t, const struct gl_sampler_object *sampler) { - if (!t || !_mesa_is_texture_complete(t, sampler)) { + if (!t || !_mesa_is_texture_complete(t, sampler, + ctx->Const.ForceIntegerTexNearest)) { return null_sample_func; } else { -- 2.30.2