[Mesa-dev] [PATCH 10/14] i965/fs: Factor out texturing related data from brw_wm_prog_key.

Kenneth Graunke kenneth at whitecape.org
Thu Dec 8 17:08:01 PST 2011


The idea is to reuse this for the VS and (in the future) GS as well.

Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
---
 src/mesa/drivers/dri/i965/brw_fs.cpp         |    4 +-
 src/mesa/drivers/dri/i965/brw_fs_visitor.cpp |   26 +++---
 src/mesa/drivers/dri/i965/brw_program.h      |   54 +++++++++
 src/mesa/drivers/dri/i965/brw_wm.c           |  150 +++++++++++++------------
 src/mesa/drivers/dri/i965/brw_wm.h           |   17 +---
 src/mesa/drivers/dri/i965/brw_wm_emit.c      |    2 +-
 src/mesa/drivers/dri/i965/brw_wm_fp.c        |    6 +-
 7 files changed, 154 insertions(+), 105 deletions(-)
 create mode 100644 src/mesa/drivers/dri/i965/brw_program.h

diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 339044c..8ca4a87 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -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) {
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index 1143951..9f8a44a 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -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
index 0000000..0d5a1b6
--- /dev/null
+++ b/src/mesa/drivers/dri/i965/brw_program.h
@@ -0,0 +1,54 @@
+/*
+ * 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];
+};
+
+void brw_populate_sampler_prog_key_data(struct gl_context *ctx,
+				        struct brw_sampler_prog_key_data *key, int i);
+
+#endif
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
index 7394475..73ac37e 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -320,7 +320,84 @@ 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;
+	 }
+      }
 
+      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,78 +481,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;
-	    }
-	 }
-
-	 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 */
diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h
index 666b6a6..3bce1f3 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.h
+++ b/src/mesa/drivers/dri/i965/brw_wm.h
@@ -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,25 +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 */
-   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;
 };
 
 
diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c
index 5905ba9..4f20546 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c
@@ -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))
diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c
index 425695e..409f29c 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_fp.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c
@@ -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;
@@ -779,13 +779,13 @@ static void precalc_tex( struct brw_wm_compile *c,
 	       src_undef());
 
    /* 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());
    }
-- 
1.7.7.3



More information about the mesa-dev mailing list