i965/fs: Factor out texturing related data from brw_wm_prog_key.
authorKenneth Graunke <kenneth@whitecape.org>
Tue, 6 Dec 2011 23:36:21 +0000 (15:36 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Tue, 20 Dec 2011 00:33:10 +0000 (16:33 -0800)
The idea is to reuse this for the VS and (in the future) GS as well.

v2: Include yuvtex data since we're not dropping GL_MESA_ycbycr.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Eric Anholt <eric@anholt.net> [v1]
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
src/mesa/drivers/dri/i965/brw_fs.cpp
src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
src/mesa/drivers/dri/i965/brw_program.h [new file with mode: 0644]
src/mesa/drivers/dri/i965/brw_wm.c
src/mesa/drivers/dri/i965/brw_wm.h
src/mesa/drivers/dri/i965/brw_wm_emit.c
src/mesa/drivers/dri/i965/brw_wm_fp.c

index 339044ca11aa810d63204f6a9174d4198197b355..8ca4a8735d045e1d039df7fdaf5e5b107ef7ccfe 100644 (file)
@@ -1904,10 +1904,10 @@ brw_fs_precompile(struct gl_context *ctx, struct gl_shader_program *prog)
 
    for (int i = 0; i < BRW_MAX_TEX_UNIT; i++) {
       if (fp->Base.ShadowSamplers & (1 << i))
-        key.compare_funcs[i] = GL_LESS;
+        key.tex.compare_funcs[i] = GL_LESS;
 
       /* FINISHME: depth compares might use (0,0,0,W) for example */
-      key.tex_swizzles[i] = SWIZZLE_XYZW;
+      key.tex.swizzles[i] = SWIZZLE_XYZW;
    }
 
    if (fp->Base.InputsRead & FRAG_BIT_WPOS) {
index 1143951385d55e6ae618a759b5a855e55dd3c9ed..9f8a44a4742cb0d0523dc65b208dec497f33e887 100644 (file)
@@ -623,7 +623,7 @@ fs_visitor::emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate,
       for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
         fs_inst *inst = emit(BRW_OPCODE_MOV,
                              fs_reg(MRF, base_mrf + mlen + i), coordinate);
-        if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler))
+        if (i < 3 && c->key.tex.gl_clamp_mask[i] & (1 << sampler))
            inst->saturate = true;
 
         coordinate.reg_offset++;
@@ -655,7 +655,7 @@ fs_visitor::emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate,
       for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
         fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i),
                              coordinate);
-        if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler))
+        if (i < 3 && c->key.tex.gl_clamp_mask[i] & (1 << sampler))
            inst->saturate = true;
         coordinate.reg_offset++;
       }
@@ -718,7 +718,7 @@ fs_visitor::emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate,
                                                     base_mrf + mlen + i * 2,
                                                     coordinate.type),
                              coordinate);
-        if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler))
+        if (i < 3 && c->key.tex.gl_clamp_mask[i] & (1 << sampler))
            inst->saturate = true;
         coordinate.reg_offset++;
       }
@@ -830,7 +830,7 @@ fs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate,
                           fs_reg(MRF, base_mrf + mlen + i * reg_width,
                                  coordinate.type),
                           coordinate);
-      if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler))
+      if (i < 3 && c->key.tex.gl_clamp_mask[i] & (1 << sampler))
         inst->saturate = true;
       coordinate.reg_offset++;
    }
@@ -978,7 +978,7 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
       for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
         fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen),
                              coordinate);
-        if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler))
+        if (i < 3 && c->key.tex.gl_clamp_mask[i] & (1 << sampler))
            inst->saturate = true;
         coordinate.reg_offset++;
         mlen += reg_width;
@@ -1023,7 +1023,7 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
       for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
         fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen),
                              coordinate);
-        if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler))
+        if (i < 3 && c->key.tex.gl_clamp_mask[i] & (1 << sampler))
            inst->saturate = true;
         coordinate.reg_offset++;
         mlen += reg_width;
@@ -1064,11 +1064,11 @@ fs_visitor::visit(ir_texture *ir)
     */
    bool hw_compare_supported = ir->op != ir_txd;
    if (ir->shadow_comparitor && !hw_compare_supported) {
-      assert(c->key.compare_funcs[sampler] != GL_NONE);
+      assert(c->key.tex.compare_funcs[sampler] != GL_NONE);
       /* No need to even sample for GL_ALWAYS or GL_NEVER...bail early */
-      if (c->key.compare_funcs[sampler] == GL_ALWAYS)
+      if (c->key.tex.compare_funcs[sampler] == GL_ALWAYS)
         return swizzle_result(ir, fs_reg(1.0f), sampler);
-      else if (c->key.compare_funcs[sampler] == GL_NEVER)
+      else if (c->key.tex.compare_funcs[sampler] == GL_NEVER)
         return swizzle_result(ir, fs_reg(0.0f), sampler);
    }
 
@@ -1177,7 +1177,7 @@ fs_visitor::visit(ir_texture *ir)
         /* FINISHME: This needs to be done pre-filtering. */
 
         uint32_t conditional = 0;
-        switch (c->key.compare_funcs[sampler]) {
+        switch (c->key.tex.compare_funcs[sampler]) {
         /* GL_ALWAYS and GL_NEVER were handled at the top of the function */
         case GL_LESS:     conditional = BRW_CONDITIONAL_L;   break;
         case GL_GREATER:  conditional = BRW_CONDITIONAL_G;   break;
@@ -1224,11 +1224,11 @@ fs_visitor::swizzle_result(ir_texture *ir, fs_reg orig_val, int sampler)
    if (ir->type == glsl_type::float_type) {
       /* Ignore DEPTH_TEXTURE_MODE swizzling. */
       assert(ir->sampler->type->sampler_shadow);
-   } else if (c->key.tex_swizzles[sampler] != SWIZZLE_NOOP) {
+   } else if (c->key.tex.swizzles[sampler] != SWIZZLE_NOOP) {
       fs_reg swizzled_result = fs_reg(this, glsl_type::vec4_type);
 
       for (int i = 0; i < 4; i++) {
-        int swiz = GET_SWZ(c->key.tex_swizzles[sampler], i);
+        int swiz = GET_SWZ(c->key.tex.swizzles[sampler], i);
         fs_reg l = swizzled_result;
         l.reg_offset += i;
 
@@ -1238,7 +1238,7 @@ fs_visitor::swizzle_result(ir_texture *ir, fs_reg orig_val, int sampler)
            emit(BRW_OPCODE_MOV, l, fs_reg(1.0f));
         } else {
            fs_reg r = orig_val;
-           r.reg_offset += GET_SWZ(c->key.tex_swizzles[sampler], i);
+           r.reg_offset += GET_SWZ(c->key.tex.swizzles[sampler], i);
            emit(BRW_OPCODE_MOV, l, r);
         }
       }
diff --git a/src/mesa/drivers/dri/i965/brw_program.h b/src/mesa/drivers/dri/i965/brw_program.h
new file mode 100644 (file)
index 0000000..a2698cf
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+ */
+
+#ifndef BRW_PROGRAM_H
+#define BRW_PROGRAM_H
+
+/**
+ * Sampler information needed by VS, WM, and GS program cache keys.
+ */
+struct brw_sampler_prog_key_data {
+   /**
+    * Per-sampler comparison functions:
+    *
+    * If comparison mode is GL_COMPARE_R_TO_TEXTURE, then this is set to one
+    * of GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL, GL_GREATER, GL_NOTEQUAL,
+    * GL_GEQUAL, or GL_ALWAYS.  Otherwise (comparison mode is GL_NONE), this
+    * field is irrelevant so it's left as GL_NONE (0).
+    *
+    * While this is a GLenum, all possible values fit in 16-bits.
+    */
+   uint16_t compare_funcs[BRW_MAX_TEX_UNIT];
+
+   /**
+    * EXT_texture_swizzle and DEPTH_TEXTURE_MODE swizzles.
+    */
+   uint16_t swizzles[BRW_MAX_TEX_UNIT];
+
+   uint16_t gl_clamp_mask[3];
+
+   /**
+    * YUV conversions, needed for the GL_MESA_ycbcr extension.
+    */
+   uint16_t yuvtex_mask;
+   uint16_t yuvtex_swap_mask; /**< UV swaped */
+};
+
+void brw_populate_sampler_prog_key_data(struct gl_context *ctx,
+                                       struct brw_sampler_prog_key_data *key, int i);
+
+#endif
index 207ffd6c63994c81961ead4fa17f3cfbfab98a46..f23edfa798b20889917a72a7a8dbd380e61ad394 100644 (file)
@@ -320,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 )
@@ -404,84 +487,7 @@ 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
-        };
-
-        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->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;
-      }
+      brw_populate_sampler_prog_key_data(ctx, &key->tex, i);
    }
 
    /* _NEW_BUFFERS */
index 596759269ad110b77ec346e9632b7464cc9e7b98..3bce1f3dd8f0409aeb41f9702cc50984212d8808 100644 (file)
@@ -38,6 +38,7 @@
 #include "program/prog_instruction.h"
 #include "brw_context.h"
 #include "brw_eu.h"
+#include "brw_program.h"
 
 #define SATURATE (1<<5)
 
@@ -68,27 +69,13 @@ struct brw_wm_prog_key {
    GLuint clamp_fragment_color:1;
    GLuint line_aa:2;
 
-   /**
-    * Per-sampler comparison functions:
-    *
-    * If comparison mode is GL_COMPARE_R_TO_TEXTURE, then this is set to one
-    * of GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL, GL_GREATER, GL_NOTEQUAL,
-    * GL_GEQUAL, or GL_ALWAYS.  Otherwise (comparison mode is GL_NONE), this
-    * field is irrelevant so it's left as GL_NONE (0).
-    *
-    * While this is a GLenum, all possible values fit in 16-bits.
-    */
-   uint16_t compare_funcs[BRW_MAX_TEX_UNIT];
-
    GLbitfield proj_attrib_mask; /**< one bit per fragment program attribute */
-   GLuint yuvtex_mask:16;
-   GLuint yuvtex_swap_mask:16; /* UV swaped */
-   uint16_t gl_clamp_mask[3];
 
-   GLushort tex_swizzles[BRW_MAX_TEX_UNIT];
    GLushort drawable_height;
    GLbitfield64 vp_outputs_written;
    GLuint program_string_id:32;
+
+   struct brw_sampler_prog_key_data tex;
 };
 
 
index 5905ba9cd4002c9b8790cf0b582563f2ad0b0b5a..4f2054656fadf65cdff68cd7e5b0901cbd97afe0 100644 (file)
@@ -1109,7 +1109,7 @@ void emit_tex(struct brw_wm_compile *c,
 
    /* Emit the texcoords. */
    for (i = 0; i < nr_texcoords; i++) {
-      if (c->key.gl_clamp_mask[i] & (1 << sampler))
+      if (c->key.tex.gl_clamp_mask[i] & (1 << sampler))
         brw_set_saturate(p, true);
 
       if (emit & (1<<i))
index 4d8ac84223fe42c64fded6e11dd0c2d4031e4cb3..1358e749558ab6038ee82dfdb07ed77b4ecefba9 100644 (file)
@@ -671,7 +671,7 @@ static void precalc_tex( struct brw_wm_compile *c,
     * temporary, otherwise writemasking of the real dst could lose some of our
     * channels.
     */
-   if (c->key.tex_swizzles[unit] != SWIZZLE_NOOP) {
+   if (c->key.tex.swizzles[unit] != SWIZZLE_NOOP) {
       unswizzled_tmp = get_temp(c);
    } else {
       unswizzled_tmp = inst->DstReg;
@@ -771,9 +771,9 @@ static void precalc_tex( struct brw_wm_compile *c,
     * conversion requires allocating a temporary variable which we
     * don't have the facility to do that late in the compilation.
     */
-   if (c->key.yuvtex_mask & (1 << unit)) {
+   if (c->key.tex.yuvtex_mask & (1 << unit)) {
       /* convert ycbcr to RGBA */
-      bool  swap_uv = c->key.yuvtex_swap_mask & (1<<unit);
+      bool swap_uv = c->key.tex.yuvtex_swap_mask & (1 << unit);
 
       /* 
         CONST C0 = { -.5, -.0625,  -.5, 1.164 }
@@ -868,13 +868,13 @@ static void precalc_tex( struct brw_wm_compile *c,
    }
 
    /* For GL_EXT_texture_swizzle: */
-   if (c->key.tex_swizzles[unit] != SWIZZLE_NOOP) {
+   if (c->key.tex.swizzles[unit] != SWIZZLE_NOOP) {
       /* swizzle the result of the TEX instruction */
       struct prog_src_register tmpsrc = src_reg_from_dst(unswizzled_tmp);
       emit_op(c, OPCODE_SWZ,
               inst->DstReg,
               SATURATE_OFF, /* saturate already done above */
-              src_swizzle4(tmpsrc, c->key.tex_swizzles[unit]),
+              src_swizzle4(tmpsrc, c->key.tex.swizzles[unit]),
               src_undef(),
               src_undef());
    }