[Mesa-dev] [PATCH] mesa: Implement ARB_texture_filter_minmax for i965/gen9+

Plamena Manolova plamena.manolova at intel.com
Tue Jan 31 18:53:40 UTC 2017


This extension provides a new texture and sampler parameter
(TEXTURE_REDUCTION_MODE_ARB) which allows applications to produce a
filtered texel value by computing a component-wise minimum (MIN) or
maximum (MAX) of the texels that would normally be averaged.  The
reduction mode is orthogonal to the minification and magnification filter
parameters.  The filter parameters are used to identify the set of texels
used to produce a final filtered value; the reduction mode identifies how
these texels are combined.
<https://www.opengl.org/registry/specs/ARB/texture_filter_minmax.txt>

Signed-off-by: Plamena Manolova <plamena.manolova at intel.com>
---
 docs/features.txt                             |  2 +-
 docs/relnotes/17.0.0.html                     |  1 +
 src/mesa/drivers/dri/i965/brw_defines.h       |  8 +++
 src/mesa/drivers/dri/i965/brw_sampler_state.c | 31 ++++++++++--
 src/mesa/drivers/dri/i965/brw_state.h         |  3 +-
 src/mesa/drivers/dri/i965/intel_extensions.c  |  1 +
 src/mesa/main/extensions_table.h              |  1 +
 src/mesa/main/mtypes.h                        |  2 +
 src/mesa/main/samplerobj.c                    | 71 +++++++++++++++++++++++++++
 src/mesa/main/texobj.c                        |  1 +
 src/mesa/main/texparam.c                      | 35 +++++++++++++
 11 files changed, 151 insertions(+), 5 deletions(-)

diff --git a/docs/features.txt b/docs/features.txt
index aff0016..da9d77a 100644
--- a/docs/features.txt
+++ b/docs/features.txt
@@ -302,7 +302,7 @@ Khronos, ARB, and OES extensions that are not part of any OpenGL or OpenGL ES ve
   GL_ARB_sparse_texture                                 not started
   GL_ARB_sparse_texture2                                not started
   GL_ARB_sparse_texture_clamp                           not started
-  GL_ARB_texture_filter_minmax                          not started
+  GL_ARB_texture_filter_minmax                          DONE (i965/gen9+)
   GL_ARB_transform_feedback_overflow_query              not started
   GL_KHR_blend_equation_advanced_coherent               DONE (i965/gen9+)
   GL_KHR_no_error                                       not started
diff --git a/docs/relnotes/17.0.0.html b/docs/relnotes/17.0.0.html
index 71fb4c3..eb6341b 100644
--- a/docs/relnotes/17.0.0.html
+++ b/docs/relnotes/17.0.0.html
@@ -44,6 +44,7 @@ Note: some of the new features are only available with certain drivers.
 </p>
 
 <ul>
+<li>GL_ARB_texture_filter_minmax on i965/gen9+</li>
 <li>GL_ARB_post_depth_coverage on i965/gen9+</li>
 <li>GL_KHR_blend_equation_advanced on nvc0</li>
 <li>GL_INTEL_conservative_rasterization on i965/gen9+</li>
diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h
index 3c5c6c4..c671bb0 100644
--- a/src/mesa/drivers/dri/i965/brw_defines.h
+++ b/src/mesa/drivers/dri/i965/brw_defines.h
@@ -259,6 +259,11 @@
 #define BRW_RASTRULE_LOWER_LEFT  2
 #define BRW_RASTRULE_LOWER_RIGHT 3
 
+#define BRW_REDUCTION_TYPE_STD_FILTER 0
+#define BRW_REDUCTION_TYPE_COMPARISON 1
+#define BRW_REDUCTION_TYPE_MINIMUM 2
+#define BRW_REDUCTION_TYPE_MAXIMUM 3
+
 #define BRW_RENDERTARGET_CLAMPRANGE_UNORM    0
 #define BRW_RENDERTARGET_CLAMPRANGE_SNORM    1
 #define BRW_RENDERTARGET_CLAMPRANGE_FORMAT   2
@@ -725,6 +730,8 @@
 /* SAMPLER_STATE DW2 - border color pointer */
 
 /* SAMPLER_STATE DW3 */
+#define BRW_SAMPLER_REDUCTION_TYPE_MASK         INTEL_MASK(23, 22)
+#define BRW_SAMPLER_REDUCTION_TYPE_SHIFT        22
 #define BRW_SAMPLER_MAX_ANISOTROPY_MASK         INTEL_MASK(21, 19)
 #define BRW_SAMPLER_MAX_ANISOTROPY_SHIFT        19
 #define BRW_SAMPLER_ADDRESS_ROUNDING_MASK       INTEL_MASK(18, 13)
@@ -732,6 +739,7 @@
 #define GEN7_SAMPLER_NON_NORMALIZED_COORDINATES (1 << 10)
 /* Gen7+ wrap modes reuse the same BRW_SAMPLER_TC*_WRAP_MODE enums. */
 #define GEN6_SAMPLER_NON_NORMALIZED_COORDINATES (1 << 0)
+#define BRW_SAMPLER_REDUCTION_TYPE_ENABLE       (1 << 9)
 
 enum brw_wrap_mode {
    BRW_TEXCOORDMODE_WRAP         = 0,
diff --git a/src/mesa/drivers/dri/i965/brw_sampler_state.c b/src/mesa/drivers/dri/i965/brw_sampler_state.c
index 412efb9..3a04283 100644
--- a/src/mesa/drivers/dri/i965/brw_sampler_state.c
+++ b/src/mesa/drivers/dri/i965/brw_sampler_state.c
@@ -93,7 +93,8 @@ brw_emit_sampler_state(struct brw_context *brw,
                        int lod_bias,
                        unsigned shadow_function,
                        bool non_normalized_coordinates,
-                       uint32_t border_color_offset)
+                       uint32_t border_color_offset,
+                       unsigned reduction_type)
 {
    ss[0] = BRW_SAMPLER_LOD_PRECLAMP_ENABLE |
            SET_FIELD(mip_filter, BRW_SAMPLER_MIP_FILTER) |
@@ -128,6 +129,11 @@ brw_emit_sampler_state(struct brw_context *brw,
 
       if (non_normalized_coordinates)
          ss[3] |= GEN7_SAMPLER_NON_NORMALIZED_COORDINATES;
+
+      if (reduction_type != 0) {
+         ss[3] |= BRW_SAMPLER_REDUCTION_TYPE_ENABLE;
+         ss[3] |= SET_FIELD(reduction_type, BRW_SAMPLER_REDUCTION_TYPE);
+      }
    } else {
       ss[0] |= SET_FIELD(lod_bias & 0x7ff, GEN4_SAMPLER_LOD_BIAS) |
                SET_FIELD(shadow_function, GEN4_SAMPLER_SHADOW_FUNCTION);
@@ -399,7 +405,7 @@ brw_update_sampler_state(struct brw_context *brw,
                          uint32_t *sampler_state,
                          uint32_t batch_offset_for_sampler_state)
 {
-   unsigned min_filter, mag_filter, mip_filter;
+   unsigned min_filter, mag_filter, mip_filter, reduction_type;
 
    /* Select min and mip filters. */
    switch (sampler->MinFilter) {
@@ -431,6 +437,24 @@ brw_update_sampler_state(struct brw_context *brw,
       unreachable("not reached");
    }
 
+   if (brw->ctx.Extensions.ARB_texture_filter_minmax) {
+      switch (sampler->TextureReductionMode) {
+      case GL_WEIGHTED_AVERAGE_ARB:
+         reduction_type = BRW_REDUCTION_TYPE_STD_FILTER;
+         break;
+      case GL_MIN:
+         reduction_type = BRW_REDUCTION_TYPE_MINIMUM;
+         break;
+      case GL_MAX:
+         reduction_type = BRW_REDUCTION_TYPE_MAXIMUM;
+         break;
+      default:
+         unreachable("not reached");
+      }
+   } else {
+      reduction_type = 0;
+   }
+
    /* Select mag filter. */
    if (sampler->MagFilter == GL_LINEAR)
       mag_filter = BRW_MAPFILTER_LINEAR;
@@ -533,7 +557,8 @@ brw_update_sampler_state(struct brw_context *brw,
                           min_lod, max_lod, lod_bias,
                           shadow_function,
                           non_normalized_coords,
-                          border_color_offset);
+                          border_color_offset,
+                          reduction_type);
 }
 
 static void
diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
index f2349d8..19a49bd 100644
--- a/src/mesa/drivers/dri/i965/brw_state.h
+++ b/src/mesa/drivers/dri/i965/brw_state.h
@@ -340,7 +340,8 @@ void brw_emit_sampler_state(struct brw_context *brw,
                             int lod_bias,
                             unsigned shadow_function,
                             bool non_normalized_coordinates,
-                            uint32_t border_color_offset);
+                            uint32_t border_color_offset,
+                            unsigned reduction_type);
 
 /* gen6_wm_state.c */
 void
diff --git a/src/mesa/drivers/dri/i965/intel_extensions.c b/src/mesa/drivers/dri/i965/intel_extensions.c
index f1290bf..9fb272e 100644
--- a/src/mesa/drivers/dri/i965/intel_extensions.c
+++ b/src/mesa/drivers/dri/i965/intel_extensions.c
@@ -277,6 +277,7 @@ intelInitExtensions(struct gl_context *ctx)
       ctx->Extensions.INTEL_conservative_rasterization = true;
       ctx->Extensions.MESA_shader_framebuffer_fetch = true;
       ctx->Extensions.ARB_post_depth_coverage = true;
+      ctx->Extensions.ARB_texture_filter_minmax = true;
    }
 
    if (ctx->API == API_OPENGL_CORE)
diff --git a/src/mesa/main/extensions_table.h b/src/mesa/main/extensions_table.h
index 91918c2..dbff6ad 100644
--- a/src/mesa/main/extensions_table.h
+++ b/src/mesa/main/extensions_table.h
@@ -142,6 +142,7 @@ EXT(ARB_texture_env_add                     , dummy_true
 EXT(ARB_texture_env_combine                 , ARB_texture_env_combine                , GLL,  x ,  x ,  x , 2001)
 EXT(ARB_texture_env_crossbar                , ARB_texture_env_crossbar               , GLL,  x ,  x ,  x , 2001)
 EXT(ARB_texture_env_dot3                    , ARB_texture_env_dot3                   , GLL,  x ,  x ,  x , 2001)
+EXT(ARB_texture_filter_minmax               , ARB_texture_filter_minmax              , GLL, GLC,  x ,  x , 2015)
 EXT(ARB_texture_float                       , ARB_texture_float                      , GLL, GLC,  x ,  x , 2004)
 EXT(ARB_texture_gather                      , ARB_texture_gather                     , GLL, GLC,  x ,  x , 2009)
 EXT(ARB_texture_mirror_clamp_to_edge        , ARB_texture_mirror_clamp_to_edge       , GLL, GLC,  x ,  x , 2013)
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index b0a97b3..ab6c9da 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -973,6 +973,7 @@ struct gl_sampler_object
    GLenum CompareFunc;		/**< GL_ARB_shadow */
    GLenum sRGBDecode;           /**< GL_DECODE_EXT or GL_SKIP_DECODE_EXT */
    GLboolean CubeMapSeamless;   /**< GL_AMD_seamless_cubemap_per_texture */
+   GLenum TextureReductionMode;  /**< GL_TEXTURE_REDUCTION_MODE_ARB */
 };
 
 
@@ -3835,6 +3836,7 @@ struct gl_extensions
    GLboolean ARB_texture_env_combine;
    GLboolean ARB_texture_env_crossbar;
    GLboolean ARB_texture_env_dot3;
+   GLboolean ARB_texture_filter_minmax;
    GLboolean ARB_texture_float;
    GLboolean ARB_texture_gather;
    GLboolean ARB_texture_mirror_clamp_to_edge;
diff --git a/src/mesa/main/samplerobj.c b/src/mesa/main/samplerobj.c
index 2118f0e..d1bc818 100644
--- a/src/mesa/main/samplerobj.c
+++ b/src/mesa/main/samplerobj.c
@@ -162,6 +162,7 @@ _mesa_init_sampler_object(struct gl_sampler_object *sampObj, GLuint name)
    sampObj->CompareFunc = GL_LEQUAL;
    sampObj->sRGBDecode = GL_DECODE_EXT;
    sampObj->CubeMapSeamless = GL_FALSE;
+   sampObj->TextureReductionMode = GL_WEIGHTED_AVERAGE_ARB;
 }
 
 /**
@@ -646,6 +647,26 @@ set_sampler_border_colorui(struct gl_context *ctx,
    return GL_TRUE;
 }
 
+static GLuint
+set_sampler_texture_reduction_mode(struct gl_context *ctx,
+                                   struct gl_sampler_object *samp,
+                                   GLint param)
+{
+   if (samp->TextureReductionMode == param)
+      return GL_FALSE;
+
+   switch (param) {
+   case GL_WEIGHTED_AVERAGE_ARB:
+   case GL_MIN:
+   case GL_MAX:
+      flush(ctx);
+      samp->TextureReductionMode = param;
+      return GL_TRUE;
+   default:
+      return INVALID_PARAM;
+   }
+
+}
 
 static GLuint
 set_sampler_min_lod(struct gl_context *ctx, struct gl_sampler_object *samp,
@@ -857,6 +878,11 @@ _mesa_SamplerParameteri(GLuint sampler, GLenum pname, GLint param)
    case GL_TEXTURE_SRGB_DECODE_EXT:
       res = set_sampler_srgb_decode(ctx, sampObj, param);
       break;
+   case GL_TEXTURE_REDUCTION_MODE_ARB:
+      if (ctx->Extensions.ARB_texture_filter_minmax) {
+         res = set_sampler_texture_reduction_mode(ctx, sampObj, param);
+         break;
+      }
    case GL_TEXTURE_BORDER_COLOR:
       /* fall-through */
    default:
@@ -948,6 +974,11 @@ _mesa_SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
    case GL_TEXTURE_SRGB_DECODE_EXT:
       res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) param);
       break;
+   case GL_TEXTURE_REDUCTION_MODE_ARB:
+      if (ctx->Extensions.ARB_texture_filter_minmax) {
+         res = set_sampler_texture_reduction_mode(ctx, sampObj, (GLint) param);
+         break;
+      }
    case GL_TEXTURE_BORDER_COLOR:
       /* fall-through */
    default:
@@ -1047,6 +1078,11 @@ _mesa_SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *params)
          res = set_sampler_border_colorf(ctx, sampObj, c);
       }
       break;
+   case GL_TEXTURE_REDUCTION_MODE_ARB:
+      if (ctx->Extensions.ARB_texture_filter_minmax) {
+         res = set_sampler_texture_reduction_mode(ctx, sampObj, params[0]);
+         break;
+      }
    default:
       res = INVALID_PNAME;
    }
@@ -1138,6 +1174,11 @@ _mesa_SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *params)
    case GL_TEXTURE_BORDER_COLOR:
       res = set_sampler_border_colorf(ctx, sampObj, params);
       break;
+   case GL_TEXTURE_REDUCTION_MODE_ARB:
+      if (ctx->Extensions.ARB_texture_filter_minmax) {
+         res = set_sampler_texture_reduction_mode(ctx, sampObj, (GLint) params[0]);
+         break;
+      }
    default:
       res = INVALID_PNAME;
    }
@@ -1223,6 +1264,11 @@ _mesa_SamplerParameterIiv(GLuint sampler, GLenum pname, const GLint *params)
    case GL_TEXTURE_BORDER_COLOR:
       res = set_sampler_border_colori(ctx, sampObj, params);
       break;
+   case GL_TEXTURE_REDUCTION_MODE_ARB:
+      if (ctx->Extensions.ARB_texture_filter_minmax) {
+         res = set_sampler_texture_reduction_mode(ctx, sampObj, params[0]);
+         break;
+      }
    default:
       res = INVALID_PNAME;
    }
@@ -1309,6 +1355,11 @@ _mesa_SamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint *params)
    case GL_TEXTURE_BORDER_COLOR:
       res = set_sampler_border_colorui(ctx, sampObj, params);
       break;
+   case GL_TEXTURE_REDUCTION_MODE_ARB:
+      if (ctx->Extensions.ARB_texture_filter_minmax) {
+         res = set_sampler_texture_reduction_mode(ctx, sampObj, params[0]);
+         break;
+      }
    default:
       res = INVALID_PNAME;
    }
@@ -1419,6 +1470,11 @@ _mesa_GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
          goto invalid_pname;
       *params = (GLenum) sampObj->sRGBDecode;
       break;
+   case GL_TEXTURE_REDUCTION_MODE_ARB:
+      if (!ctx->Extensions.ARB_texture_filter_minmax)
+         goto invalid_pname;
+      *params = sampObj->TextureReductionMode;
+      break;
    default:
       goto invalid_pname;
    }
@@ -1499,6 +1555,11 @@ _mesa_GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
          goto invalid_pname;
       *params = (GLfloat) sampObj->sRGBDecode;
       break;
+   case GL_TEXTURE_REDUCTION_MODE_ARB:
+      if (!ctx->Extensions.ARB_texture_filter_minmax)
+         goto invalid_pname;
+      *params = (GLfloat) sampObj->TextureReductionMode;
+      break;
    default:
       goto invalid_pname;
    }
@@ -1574,6 +1635,11 @@ _mesa_GetSamplerParameterIiv(GLuint sampler, GLenum pname, GLint *params)
          goto invalid_pname;
       *params = (GLenum) sampObj->sRGBDecode;
       break;
+   case GL_TEXTURE_REDUCTION_MODE_ARB:
+      if (!ctx->Extensions.ARB_texture_filter_minmax)
+         goto invalid_pname;
+      *params = (GLint) sampObj->TextureReductionMode;
+      break;
    default:
       goto invalid_pname;
    }
@@ -1649,6 +1715,11 @@ _mesa_GetSamplerParameterIuiv(GLuint sampler, GLenum pname, GLuint *params)
          goto invalid_pname;
       *params = (GLenum) sampObj->sRGBDecode;
       break;
+   case GL_TEXTURE_REDUCTION_MODE_ARB:
+      if (!ctx->Extensions.ARB_texture_filter_minmax)
+         goto invalid_pname;
+      *params = sampObj->TextureReductionMode;
+      break;
    default:
       goto invalid_pname;
    }
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
index 25b959d..9a69c38 100644
--- a/src/mesa/main/texobj.c
+++ b/src/mesa/main/texobj.c
@@ -333,6 +333,7 @@ _mesa_initialize_texture_object( struct gl_context *ctx,
    obj->BufferObjectFormat = GL_R8;
    obj->_BufferObjectFormat = MESA_FORMAT_R_UNORM8;
    obj->ImageFormatCompatibilityType = GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE;
+   obj->Sampler.TextureReductionMode = GL_WEIGHTED_AVERAGE_ARB;
 }
 
 
diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c
index 4db406f..fab7b43 100644
--- a/src/mesa/main/texparam.c
+++ b/src/mesa/main/texparam.c
@@ -480,6 +480,28 @@ set_tex_parameteri(struct gl_context *ctx,
       }
       goto invalid_pname;
 
+   case GL_TEXTURE_REDUCTION_MODE_ARB:
+      if (ctx->Extensions.ARB_texture_filter_minmax) {
+
+         if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
+            goto invalid_enum;
+
+         if (texObj->Sampler.TextureReductionMode == params[0])
+            return GL_FALSE;
+
+         switch (params[0]) {
+            case GL_WEIGHTED_AVERAGE_ARB:
+            case GL_MIN:
+            case GL_MAX:
+               flush(ctx);
+               texObj->Sampler.TextureReductionMode = params[0];
+               return GL_TRUE;
+            default:
+               goto invalid_param;
+         }
+      }
+      goto invalid_pname;
+
    case GL_DEPTH_TEXTURE_MODE_ARB:
       /* GL_DEPTH_TEXTURE_MODE_ARB is removed in core-profile and it has never
        * existed in OpenGL ES.
@@ -781,6 +803,7 @@ _mesa_texture_parameterf(struct gl_context *ctx,
    case GL_TEXTURE_SWIZZLE_G_EXT:
    case GL_TEXTURE_SWIZZLE_B_EXT:
    case GL_TEXTURE_SWIZZLE_A_EXT:
+   case GL_TEXTURE_REDUCTION_MODE_ARB:
       {
          GLint p[4];
          p[0] = (param > 0) ?
@@ -833,6 +856,7 @@ _mesa_texture_parameterfv(struct gl_context *ctx,
    case GL_DEPTH_STENCIL_TEXTURE_MODE:
    case GL_TEXTURE_SRGB_DECODE_EXT:
    case GL_TEXTURE_CUBE_MAP_SEAMLESS:
+   case GL_TEXTURE_REDUCTION_MODE_ARB:
       {
          /* convert float param to int */
          GLint p[4];
@@ -1992,6 +2016,12 @@ get_tex_parameterfv(struct gl_context *ctx,
          *params = ENUM_TO_FLOAT(obj->Target);
          break;
 
+      case GL_TEXTURE_REDUCTION_MODE_ARB:
+         if (!ctx->Extensions.ARB_texture_filter_minmax)
+            goto invalid_pname;
+         *params = (GLfloat) obj->Sampler.TextureReductionMode;
+         break;
+
       default:
          goto invalid_pname;
    }
@@ -2224,6 +2254,11 @@ get_tex_parameteriv(struct gl_context *ctx,
          *params = (GLint) obj->Target;
          break;
 
+      case GL_TEXTURE_REDUCTION_MODE_ARB:
+         if (!ctx->Extensions.ARB_texture_filter_minmax)
+            goto invalid_pname;
+         *params = (GLint) obj->Sampler.TextureReductionMode;
+         break;
       default:
          goto invalid_pname;
    }
-- 
2.4.3



More information about the mesa-dev mailing list