[Mesa-dev] [PATCH 2/3] i965: Store the SamplerUnits array in the program cache key.

Kenneth Graunke kenneth at whitecape.org
Wed Jan 11 01:55:45 PST 2012


Since sampler unit information is encoded inside the sampler SEND
instruction, we need to create specialized shaders for different values
of the SamplerUnits array.  In particular, we need to recompile whenever
SamplerUnits changes.

This is exactly what the program keys are for: when we need to get a
shader, we populate the program key with the current state, and use it
to look up in the program cache.  If we haven't seen it before, we'll
compile a new variant.  Otherwise, we'll return the cached copy.

To make this work, add the _NEW_PROGRAM dirty bit to the brw_vs_prog and
brw_wm_prog tracked state atoms, since it's required for us to be
notified when SamplerUnits changes.

This patch should not have any functional change, as we were already
recompiling when this changed via a much uglier mechanism which will be
removed in the next commit.

Cc: Eric Anholt <eric at anholt.net>
Cc: Ian Romanick <idr at freedesktop.org>
Cc: Marek Olšák <maraeo at gmail.com>
Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
---
 src/mesa/drivers/dri/i965/brw_fs_visitor.cpp   |    2 +-
 src/mesa/drivers/dri/i965/brw_program.h        |    6 ++++++
 src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp |    2 +-
 src/mesa/drivers/dri/i965/brw_vs.c             |    1 +
 src/mesa/drivers/dri/i965/brw_wm.c             |    4 ++++
 src/mesa/drivers/dri/i965/brw_wm_fp.c          |    4 ++--
 6 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index 44c9ee8..b4f7977 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -1063,7 +1063,7 @@ fs_visitor::visit(ir_texture *ir)
    fs_inst *inst = NULL;
 
    int sampler = _mesa_get_sampler_uniform_value(ir->sampler, prog, &fp->Base);
-   sampler = fp->Base.SamplerUnits[sampler];
+   sampler = c->key.tex.SamplerUnits[sampler];
 
    /* Our hardware doesn't have a sample_d_c message, so shadow compares
     * for textureGrad/TXD need to be emulated with instructions.
diff --git a/src/mesa/drivers/dri/i965/brw_program.h b/src/mesa/drivers/dri/i965/brw_program.h
index 5fe5202..f2ee431 100644
--- a/src/mesa/drivers/dri/i965/brw_program.h
+++ b/src/mesa/drivers/dri/i965/brw_program.h
@@ -29,6 +29,12 @@
  */
 struct brw_sampler_prog_key_data {
    /**
+    * A map from sampler unit to texture unit (set by glUniform1i()).
+    * This is a copy of gl_program::SamplerUnits.
+    */
+   unsigned char SamplerUnits[MAX_SAMPLERS];
+
+   /**
     * Per-sampler comparison functions:
     *
     * If comparison mode is GL_COMPARE_R_TO_TEXTURE, then this is set to one
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
index 20da487..ba1e446 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
@@ -1757,7 +1757,7 @@ void
 vec4_visitor::visit(ir_texture *ir)
 {
    int sampler = _mesa_get_sampler_uniform_value(ir->sampler, prog, &vp->Base);
-   sampler = vp->Base.SamplerUnits[sampler];
+   sampler = c->key.tex.SamplerUnits[sampler];
 
    /* Should be lowered by do_lower_texture_projection */
    assert(!ir->projector);
diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c
index c9fcea8..a258075 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.c
+++ b/src/mesa/drivers/dri/i965/brw_vs.c
@@ -349,6 +349,7 @@ static void brw_upload_vs_prog(struct brw_context *brw)
 const struct brw_tracked_state brw_vs_prog = {
    .dirty = {
       .mesa  = (_NEW_TRANSFORM | _NEW_POLYGON | _NEW_POINT | _NEW_LIGHT |
+		_NEW_PROGRAM |
 		_NEW_TEXTURE |
 		_NEW_BUFFERS),
       .brw   = (BRW_NEW_VERTEX_PROGRAM |
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
index cbf9e23..f6f87ae 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -325,6 +325,9 @@ brw_populate_sampler_prog_key_data(struct gl_context *ctx,
 				   struct gl_program *prog,
 				   struct brw_sampler_prog_key_data *key)
 {
+   /* _NEW_PROGRAM | _NEW_TEXTURE */
+   memcpy(key->SamplerUnits, prog->SamplerUnits, sizeof(key->SamplerUnits));
+
    for (int i = 0; i < BRW_MAX_TEX_UNIT; i++) {
       if (!prog->TexturesUsed[i])
 	 continue;
@@ -563,6 +566,7 @@ const struct brw_tracked_state brw_wm_prog = {
 		_NEW_LIGHT |
 		_NEW_FRAG_CLAMP |
 		_NEW_BUFFERS |
+		_NEW_PROGRAM |
 		_NEW_TEXTURE),
       .brw   = (BRW_NEW_FRAGMENT_PROGRAM |
 		BRW_NEW_WM_INPUT_DIMENSIONS |
diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c
index 1358e74..3975699 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_fp.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c
@@ -664,7 +664,7 @@ static void precalc_tex( struct brw_wm_compile *c,
    struct intel_context *intel = &p->brw->intel;
    struct prog_src_register coord;
    struct prog_dst_register tmpcoord = { 0 };
-   const GLuint unit = c->fp->program.Base.SamplerUnits[inst->TexSrcUnit];
+   const GLuint unit = c->key.tex.SamplerUnits[inst->TexSrcUnit];
    struct prog_dst_register unswizzled_tmp;
 
    /* If we are doing EXT_texture_swizzle, we need to write our result into a
@@ -1142,7 +1142,7 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
 
       case OPCODE_TXB:
 	 out = emit_insn(c, inst);
-	 out->TexSrcUnit = fp->program.Base.SamplerUnits[inst->TexSrcUnit];
+	 out->TexSrcUnit = c->key.tex.SamplerUnits[inst->TexSrcUnit];
          assert(out->TexSrcUnit < BRW_MAX_TEX_UNIT);
 	 break;
 
-- 
1.7.7.5



More information about the mesa-dev mailing list