i965/blorp: Emit sample index in SAMPLE_LD message when necessary
authorPaul Berry <stereotype441@gmail.com>
Wed, 9 May 2012 13:57:06 +0000 (06:57 -0700)
committerPaul Berry <stereotype441@gmail.com>
Fri, 25 May 2012 15:45:10 +0000 (08:45 -0700)
This patch modifies the function brw_blorp_blit_program::texel_fetch()
to emit the SI (sample index) argument to the SAMPLE_LD message when
reading from a sample index other than zero.

Previously we were using the ugly hack of configuring multisampled
source surfaces as single-sampled, and accessing sample indices other
than zero by swizzling the texture coordinates in the WM program.

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_blorp.cpp
src/mesa/drivers/dri/i965/brw_blorp_blit.cpp

index b18e141f9051ef31dde595f43e8f82a2fa393167..d80e4f1540549b7b9efc0d66cf86762474384336 100644 (file)
@@ -57,19 +57,16 @@ brw_blorp_surface_info::set(struct intel_mipmap_tree *mt,
                             unsigned int level, unsigned int layer)
 {
    brw_blorp_mip_info::set(mt, level, layer);
+   this->num_samples = mt->num_samples;
 
    if (mt->format == MESA_FORMAT_S8) {
       /* The miptree is a W-tiled stencil buffer.  Surface states can't be set
        * up for W tiling, so we'll need to use Y tiling and have the WM
-       * program swizzle the coordinates.  Furthermore, we need to set up the
-       * surface state as single-sampled, because the memory layout of related
-       * samples doesn't match between W and Y tiling.
+       * program swizzle the coordinates.
        */
       this->map_stencil_as_y_tiled = true;
-      this->num_samples = 0;
    } else {
       this->map_stencil_as_y_tiled = false;
-      this->num_samples = mt->num_samples;
    }
 }
 
index 790b472c5eb7a7e3ac6c969e4b15726edd708615..26a3514c4e25b5b2d4586b60249552a2e6fc82ac 100644 (file)
@@ -220,6 +220,8 @@ enum sampler_message_arg
    SAMPLER_MESSAGE_ARG_V_FLOAT,
    SAMPLER_MESSAGE_ARG_U_INT,
    SAMPLER_MESSAGE_ARG_V_INT,
+   SAMPLER_MESSAGE_ARG_SI_INT,
+   SAMPLER_MESSAGE_ARG_ZERO_INT,
 };
 
 /**
@@ -435,14 +437,6 @@ brw_blorp_blit_program::compile(struct brw_context *brw,
                                 GLuint *program_size)
 {
    /* Sanity checks */
-   if (key->src_tiled_w) {
-      /* If the source image is W tiled, then tex_samples must be 0.
-       * Otherwise, after conversion between W and Y tiling, there's no
-       * guarantee that the sample index will be 0.
-       */
-      assert(key->tex_samples == 0);
-   }
-
    if (key->dst_tiled_w) {
       /* If the destination image is W tiled, then dst_samples must be 0.
        * Otherwise, after conversion between W and Y tiling, there's no
@@ -920,13 +914,15 @@ brw_blorp_blit_program::sample()
 void
 brw_blorp_blit_program::texel_fetch()
 {
-   static const sampler_message_arg args[2] = {
+   static const sampler_message_arg args[5] = {
       SAMPLER_MESSAGE_ARG_U_INT,
-      SAMPLER_MESSAGE_ARG_V_INT
+      SAMPLER_MESSAGE_ARG_V_INT,
+      SAMPLER_MESSAGE_ARG_ZERO_INT, /* R */
+      SAMPLER_MESSAGE_ARG_ZERO_INT, /* LOD */
+      SAMPLER_MESSAGE_ARG_SI_INT
    };
 
-   assert(s_is_zero);
-   texture_lookup(GEN5_SAMPLER_MESSAGE_SAMPLE_LD, args, ARRAY_SIZE(args));
+   texture_lookup(GEN5_SAMPLER_MESSAGE_SAMPLE_LD, args, s_is_zero ? 2 : 5);
 }
 
 void
@@ -960,6 +956,20 @@ brw_blorp_blit_program::texture_lookup(GLuint msg_type,
       case SAMPLER_MESSAGE_ARG_V_INT:
          expand_to_32_bits(Y, mrf);
          break;
+      case SAMPLER_MESSAGE_ARG_SI_INT:
+         /* Note: on Gen7, this code may be reached with s_is_zero==true
+          * because in Gen7's ld2dss message, the sample index is the first
+          * argument.  When this happens, we need to move a 0 into the
+          * appropriate message register.
+          */
+         if (s_is_zero)
+            brw_MOV(&func, mrf, brw_imm_ud(0));
+         else
+            expand_to_32_bits(S, mrf);
+         break;
+      case SAMPLER_MESSAGE_ARG_ZERO_INT:
+         brw_MOV(&func, mrf, brw_imm_ud(0));
+         break;
       }
       mrf.nr += 2;
    }
@@ -1061,14 +1071,22 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct intel_mipmap_tree *src_mt,
    use_wm_prog = true;
    memset(&wm_prog_key, 0, sizeof(wm_prog_key));
 
+   if (dst.map_stencil_as_y_tiled) {
+      /* If the destination surface is a W-tiled stencil buffer that we're
+       * mapping as Y tiled, then we need to set up the surface state as
+       * single-sampled, because the memory layout of related samples doesn't
+       * match between W and Y tiling.
+       */
+      dst.num_samples = 0;
+   }
+
    if (src_mt->num_samples > 0 && dst_mt->num_samples > 0) {
       /* We are blitting from a multisample buffer to a multisample buffer, so
        * we must preserve samples within a pixel.  This means we have to
-       * configure the render target and texture surface states as
-       * single-sampled, so that the WM program can access each sample
-       * individually.
+       * configure the render target as single-sampled, so that the WM program
+       * generate each sample separately.
        */
-      src.num_samples = dst.num_samples = 0;
+      dst.num_samples = 0;
    }
 
    /* The render path must be configured to use the same number of samples as