mesa: add/update comments in _mesa_copy_buffer_subdata()
[mesa.git] / src / mesa / drivers / dri / i965 / brw_wm.c
index 81dad4f76da4ffb4694c05dbf46c7061fa6cae2a..cad0af8c1acdc56c3b22500d0e474d8927194ecc 100644 (file)
@@ -129,10 +129,41 @@ brw_wm_non_glsl_emit(struct brw_context *brw, struct brw_wm_compile *c)
  * (see enum brw_wm_barycentric_interp_mode) is needed by the fragment shader.
  */
 unsigned
-brw_compute_barycentric_interp_modes(void)
+brw_compute_barycentric_interp_modes(bool shade_model_flat,
+                                     const struct gl_fragment_program *fprog)
 {
-   /* At the moment the only interpolation mode we support is perspective. */
-   return (1 << BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC);
+   unsigned barycentric_interp_modes = 0;
+   int attr;
+
+   /* Loop through all fragment shader inputs to figure out what interpolation
+    * modes are in use, and set the appropriate bits in
+    * barycentric_interp_modes.
+    */
+   for (attr = 0; attr < FRAG_ATTRIB_MAX; ++attr) {
+      enum glsl_interp_qualifier interp_qualifier =
+         fprog->InterpQualifier[attr];
+      bool is_gl_Color = attr == FRAG_ATTRIB_COL0 || attr == FRAG_ATTRIB_COL1;
+
+      /* Ignore unused inputs. */
+      if (!(fprog->Base.InputsRead & BITFIELD64_BIT(attr)))
+         continue;
+
+      /* Ignore WPOS and FACE, because they don't require interpolation. */
+      if (attr == FRAG_ATTRIB_WPOS || attr == FRAG_ATTRIB_FACE)
+         continue;
+
+      if (interp_qualifier == INTERP_QUALIFIER_NOPERSPECTIVE) {
+         barycentric_interp_modes |=
+            1 << BRW_WM_NONPERSPECTIVE_PIXEL_BARYCENTRIC;
+      } else if (interp_qualifier == INTERP_QUALIFIER_SMOOTH ||
+                 (!(shade_model_flat && is_gl_Color) &&
+                  interp_qualifier == INTERP_QUALIFIER_NONE)) {
+         barycentric_interp_modes |=
+            1 << BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC;
+      }
+   }
+
+   return barycentric_interp_modes;
 }
 
 
@@ -144,7 +175,8 @@ brw_wm_payload_setup(struct brw_context *brw,
    bool uses_depth = (c->fp->program.Base.InputsRead &
                      (1 << FRAG_ATTRIB_WPOS)) != 0;
    unsigned barycentric_interp_modes =
-      brw_compute_barycentric_interp_modes();
+      brw_compute_barycentric_interp_modes(c->key.flat_shade,
+                                           &c->fp->program);
    int i;
 
    if (intel->gen >= 6) {
@@ -288,7 +320,90 @@ bool do_wm_prog(struct brw_context *brw,
    return true;
 }
 
+void
+brw_populate_sampler_prog_key_data(struct gl_context *ctx,
+                                  struct brw_sampler_prog_key_data *key,
+                                  int i)
+{
+   const struct gl_texture_unit *unit = &ctx->Texture.Unit[i];
+
+   if (unit->_ReallyEnabled) {
+      const struct gl_texture_object *t = unit->_Current;
+      const struct gl_texture_image *img = t->Image[0][t->BaseLevel];
+      struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, i);
+      int swizzles[SWIZZLE_NIL + 1] = {
+        SWIZZLE_X,
+        SWIZZLE_Y,
+        SWIZZLE_Z,
+        SWIZZLE_W,
+        SWIZZLE_ZERO,
+        SWIZZLE_ONE,
+        SWIZZLE_NIL
+      };
+
+      if (img->_BaseFormat == GL_DEPTH_COMPONENT ||
+         img->_BaseFormat == GL_DEPTH_STENCIL) {
+        if (sampler->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB)
+           key->compare_funcs[i] = sampler->CompareFunc;
 
+        /* We handle GL_DEPTH_TEXTURE_MODE here instead of as surface format
+         * overrides because shadow comparison always returns the result of
+         * the comparison in all channels anyway.
+         */
+        switch (sampler->DepthMode) {
+        case GL_ALPHA:
+           swizzles[0] = SWIZZLE_ZERO;
+           swizzles[1] = SWIZZLE_ZERO;
+           swizzles[2] = SWIZZLE_ZERO;
+           swizzles[3] = SWIZZLE_X;
+           break;
+        case GL_LUMINANCE:
+           swizzles[0] = SWIZZLE_X;
+           swizzles[1] = SWIZZLE_X;
+           swizzles[2] = SWIZZLE_X;
+           swizzles[3] = SWIZZLE_ONE;
+           break;
+        case GL_INTENSITY:
+           swizzles[0] = SWIZZLE_X;
+           swizzles[1] = SWIZZLE_X;
+           swizzles[2] = SWIZZLE_X;
+           swizzles[3] = SWIZZLE_X;
+           break;
+        case GL_RED:
+           swizzles[0] = SWIZZLE_X;
+           swizzles[1] = SWIZZLE_ZERO;
+           swizzles[2] = SWIZZLE_ZERO;
+           swizzles[3] = SWIZZLE_ONE;
+           break;
+        }
+      }
+
+      if (img->InternalFormat == GL_YCBCR_MESA) {
+        key->yuvtex_mask |= 1 << i;
+        if (img->TexFormat == MESA_FORMAT_YCBCR)
+            key->yuvtex_swap_mask |= 1 << i;
+      }
+
+      key->swizzles[i] =
+        MAKE_SWIZZLE4(swizzles[GET_SWZ(t->_Swizzle, 0)],
+                      swizzles[GET_SWZ(t->_Swizzle, 1)],
+                      swizzles[GET_SWZ(t->_Swizzle, 2)],
+                      swizzles[GET_SWZ(t->_Swizzle, 3)]);
+
+      if (sampler->MinFilter != GL_NEAREST &&
+         sampler->MagFilter != GL_NEAREST) {
+        if (sampler->WrapS == GL_CLAMP)
+           key->gl_clamp_mask[0] |= 1 << i;
+        if (sampler->WrapT == GL_CLAMP)
+           key->gl_clamp_mask[1] |= 1 << i;
+        if (sampler->WrapR == GL_CLAMP)
+           key->gl_clamp_mask[2] |= 1 << i;
+      }
+   }
+   else {
+      key->swizzles[i] = SWIZZLE_NOOP;
+   }
+}
 
 static void brw_wm_populate_key( struct brw_context *brw,
                                 struct brw_wm_prog_key *key )
@@ -297,6 +412,7 @@ static void brw_wm_populate_key( struct brw_context *brw,
    /* BRW_NEW_FRAGMENT_PROGRAM */
    const struct brw_fragment_program *fp = 
       (struct brw_fragment_program *)brw->fragment_program;
+   const struct gl_program *prog = (struct gl_program *) brw->fragment_program;
    GLuint lookup = 0;
    GLuint line_aa;
    GLuint i;
@@ -372,69 +488,8 @@ static void brw_wm_populate_key( struct brw_context *brw,
 
    /* _NEW_TEXTURE */
    for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
-      const struct gl_texture_unit *unit = &ctx->Texture.Unit[i];
-
-      if (unit->_ReallyEnabled) {
-         const struct gl_texture_object *t = unit->_Current;
-         const struct gl_texture_image *img = t->Image[0][t->BaseLevel];
-        struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, i);
-        int swizzles[SWIZZLE_NIL + 1] = {
-           SWIZZLE_X,
-           SWIZZLE_Y,
-           SWIZZLE_Z,
-           SWIZZLE_W,
-           SWIZZLE_ZERO,
-           SWIZZLE_ONE,
-           SWIZZLE_NIL
-        };
-
-        /* GL_DEPTH_TEXTURE_MODE is normally handled through
-         * brw_wm_surface_state, but it applies to shadow compares as
-         * well and our shadow compares always return the result in
-         * all 4 channels.
-         */
-        if (sampler->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) {
-           key->compare_funcs[i] = sampler->CompareFunc;
-
-           if (sampler->DepthMode == GL_ALPHA) {
-              swizzles[0] = SWIZZLE_ZERO;
-              swizzles[1] = SWIZZLE_ZERO;
-              swizzles[2] = SWIZZLE_ZERO;
-           } else if (sampler->DepthMode == GL_LUMINANCE) {
-              swizzles[3] = SWIZZLE_ONE;
-           } else if (sampler->DepthMode == GL_RED) {
-              /* See table 3.23 of the GL 3.0 spec. */
-              swizzles[1] = SWIZZLE_ZERO;
-              swizzles[2] = SWIZZLE_ZERO;
-              swizzles[3] = SWIZZLE_ONE;
-           }
-        }
-
-        if (img->InternalFormat == GL_YCBCR_MESA) {
-           key->yuvtex_mask |= 1 << i;
-           if (img->TexFormat == MESA_FORMAT_YCBCR)
-               key->yuvtex_swap_mask |= 1 << i;
-        }
-
-        key->tex_swizzles[i] =
-           MAKE_SWIZZLE4(swizzles[GET_SWZ(t->_Swizzle, 0)],
-                         swizzles[GET_SWZ(t->_Swizzle, 1)],
-                         swizzles[GET_SWZ(t->_Swizzle, 2)],
-                         swizzles[GET_SWZ(t->_Swizzle, 3)]);
-
-        if (sampler->MinFilter != GL_NEAREST &&
-            sampler->MagFilter != GL_NEAREST) {
-           if (sampler->WrapS == GL_CLAMP)
-              key->gl_clamp_mask[0] |= 1 << i;
-           if (sampler->WrapT == GL_CLAMP)
-              key->gl_clamp_mask[1] |= 1 << i;
-           if (sampler->WrapR == GL_CLAMP)
-              key->gl_clamp_mask[2] |= 1 << i;
-        }
-      }
-      else {
-         key->tex_swizzles[i] = SWIZZLE_NOOP;
-      }
+      if (prog->TexturesUsed[i])
+        brw_populate_sampler_prog_key_data(ctx, &key->tex, i);
    }
 
    /* _NEW_BUFFERS */
@@ -474,7 +529,8 @@ static void brw_wm_populate_key( struct brw_context *brw,
 }
 
 
-static void brw_prepare_wm_prog(struct brw_context *brw)
+static void
+brw_upload_wm_prog(struct brw_context *brw)
 {
    struct intel_context *intel = &brw->intel;
    struct gl_context *ctx = &intel->ctx;
@@ -511,6 +567,6 @@ const struct brw_tracked_state brw_wm_prog = {
                BRW_NEW_REDUCED_PRIMITIVE),
       .cache = CACHE_NEW_VS_PROG,
    },
-   .prepare = brw_prepare_wm_prog
+   .emit = brw_upload_wm_prog
 };