i965/fs: Lower 32x32 bit multiplication on BXT.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_wm.c
index a0eda3a8b94537247abc54f4caf26e9f5bf1cd7d..9b90a7c191f72815b8c89b831111189396a1d15a 100644 (file)
@@ -1,34 +1,28 @@
 /*
- Copyright (C) Intel Corp.  2006.  All Rights Reserved.
- Intel funded Tungsten Graphics to
- develop this 3D driver.
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice (including the
- next paragraph) shall be included in all copies or substantial
- portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- **********************************************************************/
- /*
-  * Authors:
-  *   Keith Whitwell <keithw@vmware.com>
-  */
-
+ * Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ * Intel funded Tungsten Graphics to
+ * develop this 3D driver.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
 #include "brw_context.h"
 #include "brw_wm.h"
 #include "brw_state.h"
@@ -36,6 +30,7 @@
 #include "main/formats.h"
 #include "main/fbobject.h"
 #include "main/samplerobj.h"
+#include "main/framebuffer.h"
 #include "program/prog_parameter.h"
 #include "program/program.h"
 #include "intel_mipmap_tree.h"
@@ -159,10 +154,11 @@ brw_wm_prog_data_compare(const void *in_a, const void *in_b)
  * Depending on the instructions used (i.e. flow control instructions)
  * we'll use one of two code generators.
  */
-bool do_wm_prog(struct brw_context *brw,
-               struct gl_shader_program *prog,
-               struct brw_fragment_program *fp,
-               struct brw_wm_prog_key *key)
+bool
+brw_codegen_wm_prog(struct brw_context *brw,
+                    struct gl_shader_program *prog,
+                    struct brw_fragment_program *fp,
+                    struct brw_wm_prog_key *key)
 {
    struct gl_context *ctx = &brw->ctx;
    void *mem_ctx = ralloc_context(NULL);
@@ -179,7 +175,8 @@ bool do_wm_prog(struct brw_context *brw,
     * so the shader definitely kills pixels.
     */
    prog_data.uses_kill = fp->program.UsesKill || key->alpha_test_func;
-
+   prog_data.uses_omask =
+      fp->program.Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK);
    prog_data.computed_depth_mode = computed_depth_mode(&fp->program);
 
    /* Use ALT floating point mode for ARB programs so that 0^0 == 1. */
@@ -265,6 +262,14 @@ brw_debug_recompile_sampler_key(struct brw_context *brw,
                       old_key->gl_clamp_mask[2], key->gl_clamp_mask[2]);
    found |= key_debug(brw, "gather channel quirk on any texture unit",
                       old_key->gather_channel_quirk_mask, key->gather_channel_quirk_mask);
+   found |= key_debug(brw, "compressed multisample layout",
+                      old_key->compressed_multisample_layout_mask,
+                      key->compressed_multisample_layout_mask);
+
+   for (unsigned int i = 0; i < MAX_SAMPLERS; i++) {
+      found |= key_debug(brw, "textureGather workarounds",
+                         old_key->gen6_gather_wa[i], key->gen6_gather_wa[i]);
+   }
 
    return found;
 }
@@ -339,13 +344,15 @@ static uint8_t
 gen6_gather_workaround(GLenum internalformat)
 {
    switch (internalformat) {
-      case GL_R8I: return WA_SIGN | WA_8BIT;
-      case GL_R8UI: return WA_8BIT;
-      case GL_R16I: return WA_SIGN | WA_16BIT;
-      case GL_R16UI: return WA_16BIT;
-      /* note that even though GL_R32I and GL_R32UI have format overrides
-       * in the surface state, there is no shader w/a required */
-      default: return 0;
+   case GL_R8I: return WA_SIGN | WA_8BIT;
+   case GL_R8UI: return WA_8BIT;
+   case GL_R16I: return WA_SIGN | WA_16BIT;
+   case GL_R16UI: return WA_16BIT;
+   default:
+      /* Note that even though GL_R32I and GL_R32UI have format overrides in
+       * the surface state, there is no shader w/a required.
+       */
+      return 0;
    }
 }
 
@@ -392,8 +399,9 @@ brw_populate_sampler_prog_key_data(struct gl_context *ctx,
               key->gl_clamp_mask[2] |= 1 << s;
         }
 
-         /* gather4's channel select for green from RG32F is broken;
-          * requires a shader w/a on IVB; fixable with just SCS on HSW. */
+         /* gather4's channel select for green from RG32F is broken; requires
+          * a shader w/a on IVB; fixable with just SCS on HSW.
+          */
          if (brw->gen == 7 && !brw->is_haswell && prog->UsesGather) {
             if (img->InternalFormat == GL_RG32F)
                key->gather_channel_quirk_mask |= 1 << s;
@@ -421,18 +429,39 @@ brw_populate_sampler_prog_key_data(struct gl_context *ctx,
    }
 }
 
-static void brw_wm_populate_key( struct brw_context *brw,
-                                struct brw_wm_prog_key *key )
+static bool
+brw_wm_state_dirty (struct brw_context *brw)
+{
+   return brw_state_dirty(brw,
+                          _NEW_BUFFERS |
+                          _NEW_COLOR |
+                          _NEW_DEPTH |
+                          _NEW_FRAG_CLAMP |
+                          _NEW_HINT |
+                          _NEW_LIGHT |
+                          _NEW_LINE |
+                          _NEW_MULTISAMPLE |
+                          _NEW_POLYGON |
+                          _NEW_STENCIL |
+                          _NEW_TEXTURE,
+                          BRW_NEW_FRAGMENT_PROGRAM |
+                          BRW_NEW_REDUCED_PRIMITIVE |
+                          BRW_NEW_STATS_WM |
+                          BRW_NEW_VUE_MAP_GEOM_OUT);
+}
+
+static void
+brw_wm_populate_key(struct brw_context *brw, struct brw_wm_prog_key *key)
 {
    struct gl_context *ctx = &brw->ctx;
    /* BRW_NEW_FRAGMENT_PROGRAM */
    const struct brw_fragment_program *fp =
-      (struct brw_fragment_program *)brw->fragment_program;
+      (struct brw_fragment_program *) brw->fragment_program;
    const struct gl_program *prog = (struct gl_program *) brw->fragment_program;
    GLuint lookup = 0;
    GLuint line_aa;
    bool program_uses_dfdy = fp->program.UsesDFdy;
-   bool multisample_fbo = ctx->DrawBuffer->Visual.samples > 1;
+   const bool multisample_fbo = _mesa_geometric_samples(ctx->DrawBuffer) > 1;
 
    memset(key, 0, sizeof(*key));
 
@@ -531,7 +560,7 @@ static void brw_wm_populate_key( struct brw_context *brw,
     * drawable height in order to invert the Y axis.
     */
    if (fp->program.Base.InputsRead & VARYING_BIT_POS) {
-      key->drawable_height = ctx->DrawBuffer->Height;
+      key->drawable_height = _mesa_geometric_height(ctx->DrawBuffer);
    }
 
    if ((fp->program.Base.InputsRead & VARYING_BIT_POS) || program_uses_dfdy) {
@@ -550,7 +579,7 @@ static void brw_wm_populate_key( struct brw_context *brw,
    key->persample_shading =
       _mesa_get_min_invocations_per_fragment(ctx, &fp->program, true) > 1;
    if (key->persample_shading)
-      key->persample_2x = ctx->DrawBuffer->Visual.samples == 2;
+      key->persample_2x = _mesa_geometric_samples(ctx->DrawBuffer) == 2;
 
    key->compute_pos_offset =
       _mesa_get_min_invocations_per_fragment(ctx, &fp->program, false) > 1 &&
@@ -573,7 +602,8 @@ static void brw_wm_populate_key( struct brw_context *brw,
     * like GL requires.  Fix that by building the alpha test into the
     * shader, and we'll skip enabling the fixed function alpha test.
     */
-   if (brw->gen < 6 && ctx->DrawBuffer->_NumColorDrawBuffers > 1 && ctx->Color.AlphaEnabled) {
+   if (brw->gen < 6 && ctx->DrawBuffer->_NumColorDrawBuffers > 1 &&
+       ctx->Color.AlphaEnabled) {
       key->alpha_test_func = ctx->Color.AlphaFunc;
       key->alpha_test_ref = ctx->Color.AlphaRef;
    }
@@ -586,26 +616,12 @@ void
 brw_upload_wm_prog(struct brw_context *brw)
 {
    struct gl_context *ctx = &brw->ctx;
+   struct gl_shader_program *current = ctx->_Shader->_CurrentFragmentProgram;
    struct brw_wm_prog_key key;
    struct brw_fragment_program *fp = (struct brw_fragment_program *)
       brw->fragment_program;
 
-   if (!brw_state_dirty(brw,
-                        _NEW_BUFFERS |
-                        _NEW_COLOR |
-                        _NEW_DEPTH |
-                        _NEW_FRAG_CLAMP |
-                        _NEW_HINT |
-                        _NEW_LIGHT |
-                        _NEW_LINE |
-                        _NEW_MULTISAMPLE |
-                        _NEW_POLYGON |
-                        _NEW_STENCIL |
-                        _NEW_TEXTURE,
-                        BRW_NEW_FRAGMENT_PROGRAM |
-                        BRW_NEW_REDUCED_PRIMITIVE |
-                        BRW_NEW_STATS_WM |
-                        BRW_NEW_VUE_MAP_GEOM_OUT))
+   if (!brw_wm_state_dirty(brw))
       return;
 
    brw_wm_populate_key(brw, &key);
@@ -613,8 +629,7 @@ brw_upload_wm_prog(struct brw_context *brw)
    if (!brw_search_cache(&brw->cache, BRW_CACHE_FS_PROG,
                         &key, sizeof(key),
                         &brw->wm.base.prog_offset, &brw->wm.prog_data)) {
-      bool success = do_wm_prog(brw, ctx->_Shader->_CurrentFragmentProgram, fp,
-                               &key);
+      bool success = brw_codegen_wm_prog(brw, current, fp, &key);
       (void) success;
       assert(success);
    }