From 38d304f2fe187e4a748cc811b9b4569e15d5b606 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 17 Jan 2021 12:10:42 +0100 Subject: [PATCH] glgsg: Force nearest filtering on isampler/usampler Without this, Intel drivers will sample (0, 0, 0, 1) --- .../glstuff/glGraphicsStateGuardian_src.cxx | 18 ++++++++++++++---- panda/src/glstuff/glShaderContext_src.cxx | 5 +++++ panda/src/gobj/texture.cxx | 19 +++++++++++++++++++ panda/src/gobj/texture.h | 1 + 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index bb2dfdc6fb..38f6ccb24f 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -12409,10 +12409,20 @@ specify_texture(CLP(TextureContext) *gtc, const SamplerState &sampler) { } } - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, - get_texture_filter_type(minfilter, !uses_mipmaps)); - glTexParameteri(target, GL_TEXTURE_MAG_FILTER, - get_texture_filter_type(magfilter, true)); + if (Texture::is_integer(tex->get_format())) { + // Integer format textures can't have filtering enabled, and in fact, some + // drivers (looking at you, Intel) will always sample (0, 0, 0, 1) if we + // don't set this correctly! + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, + uses_mipmaps ? GL_NEAREST_MIPMAP_NEAREST + : GL_NEAREST); + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } else { + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, + get_texture_filter_type(minfilter, !uses_mipmaps)); + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, + get_texture_filter_type(magfilter, true)); + } // Set anisotropic filtering. if (_supports_anisotropy) { diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index b0dfd4531b..424cf2ca83 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -2849,6 +2849,11 @@ update_shader_texture_bindings(ShaderContext *prev) { } continue; } + else if (Texture::is_integer(tex->get_format())) { + // Required to satisfy Intel drivers, which will otherwise sample zero. + sampler.set_minfilter(sampler.uses_mipmaps() ? SamplerState::FT_nearest_mipmap_nearest : SamplerState::FT_nearest); + sampler.set_magfilter(SamplerState::FT_nearest); + } if (tex->get_texture_type() != spec._desired_type) { switch (spec._part) { diff --git a/panda/src/gobj/texture.cxx b/panda/src/gobj/texture.cxx index d1d76d471c..a5658c8146 100644 --- a/panda/src/gobj/texture.cxx +++ b/panda/src/gobj/texture.cxx @@ -2628,6 +2628,25 @@ is_srgb(Format format) { } } +/** + * Returns true if the indicated format is an integer format, false otherwise. + */ +bool Texture:: +is_integer(Format format) { + switch (format) { + case F_r32i: + case F_r8i: + case F_rg8i: + case F_rgb8i: + case F_rgba8i: + case F_r16i: + return true; + + default: + return false; + } +} + /** * Computes the proper size of the texture, based on the original size, the * filename, and the resizing whims of the config file. diff --git a/panda/src/gobj/texture.h b/panda/src/gobj/texture.h index 7cb5f305fb..af96f49d1d 100644 --- a/panda/src/gobj/texture.h +++ b/panda/src/gobj/texture.h @@ -625,6 +625,7 @@ public: static bool has_alpha(Format format); static bool has_binary_alpha(Format format); static bool is_srgb(Format format); + static bool is_integer(Format format); static bool adjust_size(int &x_size, int &y_size, const std::string &name, bool for_padding, AutoTextureScale auto_texture_scale = ATS_unspecified);