i965: Properly reset SVBI counters on ResumeTransformFeedback().
[mesa.git] / src / mesa / drivers / dri / i965 / brw_sampler_state.c
index c20a02817f975b18de69700416a6b4e75de1f4f8..b99a89893f61103f600b576190e099ab27670071 100644 (file)
@@ -88,6 +88,7 @@ brw_emit_sampler_state(struct brw_context *brw,
                        unsigned wrap_s,
                        unsigned wrap_t,
                        unsigned wrap_r,
+                       unsigned base_level,
                        unsigned min_lod,
                        unsigned max_lod,
                        int lod_bias,
@@ -132,6 +133,21 @@ brw_emit_sampler_state(struct brw_context *brw,
       ss[0] |= SET_FIELD(lod_bias & 0x7ff, GEN4_SAMPLER_LOD_BIAS) |
                SET_FIELD(shadow_function, GEN4_SAMPLER_SHADOW_FUNCTION);
 
+      /* This field has existed since the original i965, but is declared MBZ
+       * until Sandy Bridge.  According to the PRM:
+       *
+       *    "This was added to match OpenGL semantics"
+       *
+       * In particular, OpenGL allowed you to offset by 0.5 in certain cases
+       * to get slightly better filtering.  On Ivy Bridge and above, it
+       * appears that this is added to RENDER_SURFACE_STATE::SurfaceMinLOD so
+       * the right value is 0.0 or 0.5 (if you want the wacky behavior).  On
+       * Sandy Bridge, however, this sum does not seem to occur and you have
+       * to set it to the actual base level of the texture.
+       */
+      if (brw->gen == 6)
+         ss[0] |= SET_FIELD(base_level, BRW_SAMPLER_BASE_MIPLEVEL);
+
       if (brw->gen == 6 && min_filter != mag_filter)
          ss[0] |= GEN6_SAMPLER_MIN_MAG_NOT_EQUAL;
 
@@ -149,7 +165,7 @@ brw_emit_sampler_state(struct brw_context *brw,
 static uint32_t
 translate_wrap_mode(struct brw_context *brw, GLenum wrap, bool using_nearest)
 {
-   switch( wrap ) {
+   switch (wrap) {
    case GL_REPEAT:
       return BRW_TEXCOORDMODE_WRAP;
    case GL_CLAMP:
@@ -196,6 +212,16 @@ wrap_mode_needs_border_color(unsigned wrap_mode)
           wrap_mode == GEN8_TEXCOORDMODE_HALF_BORDER;
 }
 
+static bool
+has_component(mesa_format format, int i)
+{
+   if (_mesa_is_format_color_format(format))
+      return _mesa_format_has_color_component(format, i);
+
+   /* depth and stencil have only one component */
+   return i == 0;
+}
+
 /**
  * Upload SAMPLER_BORDER_COLOR_STATE.
  */
@@ -203,7 +229,7 @@ static void
 upload_default_color(struct brw_context *brw,
                      const struct gl_sampler_object *sampler,
                      mesa_format format, GLenum base_format,
-                     bool is_integer_format,
+                     bool is_integer_format, bool is_stencil_sampling,
                      uint32_t *sdc_offset)
 {
    union gl_color_union color;
@@ -267,7 +293,7 @@ upload_default_color(struct brw_context *brw,
       uint32_t *sdc = brw_state_batch(brw, AUB_TRACE_SAMPLER_DEFAULT_COLOR,
                                       4 * 4, 64, sdc_offset);
       memcpy(sdc, color.ui, 4 * 4);
-   } else if (brw->is_haswell && is_integer_format) {
+   } else if (brw->is_haswell && (is_integer_format || is_stencil_sampling)) {
       /* Haswell's integer border color support is completely insane:
        * SAMPLER_BORDER_COLOR_STATE is 20 DWords.  The first four are
        * for float colors.  The next 12 DWords are MBZ and only exist to
@@ -281,7 +307,9 @@ upload_default_color(struct brw_context *brw,
       memset(sdc, 0, 20 * 4);
       sdc = &sdc[16];
 
-      int bits_per_channel = _mesa_get_format_bits(format, GL_RED_BITS);
+      bool stencil = format == MESA_FORMAT_S_UINT8 || is_stencil_sampling;
+      const int bits_per_channel =
+         _mesa_get_format_bits(format, stencil ? GL_STENCIL_BITS : GL_RED_BITS);
 
       /* From the Haswell PRM, "Command Reference: Structures", Page 36:
        * "If any color channel is missing from the surface format,
@@ -291,7 +319,7 @@ upload_default_color(struct brw_context *brw,
        */
       unsigned c[4] = { 0, 0, 0, 1 };
       for (int i = 0; i < 4; i++) {
-         if (_mesa_format_has_color_component(format, i))
+         if (has_component(format, i))
             c[i] = color.ui[i];
       }
 
@@ -376,12 +404,12 @@ upload_default_color(struct brw_context *brw,
  * Sets the sampler state for a single unit based off of the sampler key
  * entry.
  */
-void
+static void
 brw_update_sampler_state(struct brw_context *brw,
                          GLenum target, bool tex_cube_map_seamless,
                          GLfloat tex_unit_lod_bias,
                          mesa_format format, GLenum base_format,
-                         bool is_integer_format,
+                         const struct gl_texture_object *texObj,
                          const struct gl_sampler_object *sampler,
                          uint32_t *sampler_state,
                          uint32_t batch_offset_for_sampler_state)
@@ -459,10 +487,12 @@ brw_update_sampler_state(struct brw_context *brw,
        target == GL_TEXTURE_CUBE_MAP_ARRAY) {
       /* Cube maps must use the same wrap mode for all three coordinate
        * dimensions.  Prior to Haswell, only CUBE and CLAMP are valid.
+       *
+       * Ivybridge and Baytrail seem to have problems with CUBE mode and
+       * integer formats.  Fall back to CLAMP for now.
        */
       if ((tex_cube_map_seamless || sampler->CubeMapSeamless) &&
-         (sampler->MinFilter != GL_NEAREST ||
-          sampler->MagFilter != GL_NEAREST)) {
+          !(brw->gen == 7 && !brw->is_haswell && texObj->_IsIntegerFormat)) {
         wrap_s = BRW_TEXCOORDMODE_CUBE;
         wrap_t = BRW_TEXCOORDMODE_CUBE;
         wrap_r = BRW_TEXCOORDMODE_CUBE;
@@ -488,8 +518,13 @@ brw_update_sampler_state(struct brw_context *brw,
    }
 
    const int lod_bits = brw->gen >= 7 ? 8 : 6;
-   const unsigned min_lod = U_FIXED(CLAMP(sampler->MinLod, 0, 13), lod_bits);
-   const unsigned max_lod = U_FIXED(CLAMP(sampler->MaxLod, 0, 13), lod_bits);
+   const float hw_max_lod = brw->gen >= 7 ? 14 : 13;
+   const unsigned base_level =
+      U_FIXED(CLAMP(texObj->MinLevel + texObj->BaseLevel, 0, hw_max_lod), 1);
+   const unsigned min_lod =
+      U_FIXED(CLAMP(sampler->MinLod, 0, hw_max_lod), lod_bits);
+   const unsigned max_lod =
+      U_FIXED(CLAMP(sampler->MaxLod, 0, hw_max_lod), lod_bits);
    const int lod_bias =
       S_FIXED(CLAMP(tex_unit_lod_bias + sampler->LodBias, -16, 15), lod_bits);
 
@@ -501,8 +536,8 @@ brw_update_sampler_state(struct brw_context *brw,
    if (wrap_mode_needs_border_color(wrap_s) ||
        wrap_mode_needs_border_color(wrap_t) ||
        wrap_mode_needs_border_color(wrap_r)) {
-      upload_default_color(brw, sampler,
-                           format, base_format, is_integer_format,
+      upload_default_color(brw, sampler, format, base_format,
+                           texObj->_IsIntegerFormat, texObj->StencilSampling,
                            &border_color_offset);
    }
 
@@ -515,7 +550,7 @@ brw_update_sampler_state(struct brw_context *brw,
                           max_anisotropy,
                           address_rounding,
                           wrap_s, wrap_t, wrap_r,
-                          min_lod, max_lod, lod_bias,
+                          base_level, min_lod, max_lod, lod_bias,
                           shadow_function,
                           non_normalized_coords,
                           border_color_offset);
@@ -540,8 +575,7 @@ update_sampler_state(struct brw_context *brw,
    brw_update_sampler_state(brw, texObj->Target, ctx->Texture.CubeMapSeamless,
                             texUnit->LodBias,
                             firstImage->TexFormat, firstImage->_BaseFormat,
-                            texObj->_IsIntegerFormat,
-                            sampler,
+                            texObj, sampler,
                             sampler_state, batch_offset_for_sampler_state);
 }
 
@@ -605,6 +639,7 @@ const struct brw_tracked_state brw_fs_samplers = {
    .dirty = {
       .mesa = _NEW_TEXTURE,
       .brw = BRW_NEW_BATCH |
+             BRW_NEW_BLORP |
              BRW_NEW_FRAGMENT_PROGRAM,
    },
    .emit = brw_upload_fs_samplers,
@@ -623,6 +658,7 @@ const struct brw_tracked_state brw_vs_samplers = {
    .dirty = {
       .mesa = _NEW_TEXTURE,
       .brw = BRW_NEW_BATCH |
+             BRW_NEW_BLORP |
              BRW_NEW_VERTEX_PROGRAM,
    },
    .emit = brw_upload_vs_samplers,
@@ -645,6 +681,7 @@ const struct brw_tracked_state brw_gs_samplers = {
    .dirty = {
       .mesa = _NEW_TEXTURE,
       .brw = BRW_NEW_BATCH |
+             BRW_NEW_BLORP |
              BRW_NEW_GEOMETRY_PROGRAM,
    },
    .emit = brw_upload_gs_samplers,
@@ -667,6 +704,7 @@ const struct brw_tracked_state brw_tcs_samplers = {
    .dirty = {
       .mesa = _NEW_TEXTURE,
       .brw = BRW_NEW_BATCH |
+             BRW_NEW_BLORP |
              BRW_NEW_TESS_PROGRAMS,
    },
    .emit = brw_upload_tcs_samplers,
@@ -689,6 +727,7 @@ const struct brw_tracked_state brw_tes_samplers = {
    .dirty = {
       .mesa = _NEW_TEXTURE,
       .brw = BRW_NEW_BATCH |
+             BRW_NEW_BLORP |
              BRW_NEW_TESS_PROGRAMS,
    },
    .emit = brw_upload_tes_samplers,
@@ -709,6 +748,7 @@ const struct brw_tracked_state brw_cs_samplers = {
    .dirty = {
       .mesa = _NEW_TEXTURE,
       .brw = BRW_NEW_BATCH |
+             BRW_NEW_BLORP |
              BRW_NEW_COMPUTE_PROGRAM,
    },
    .emit = brw_upload_cs_samplers,