[Mesa-dev] [PATCH 21/22] i965/vs: Add support for loading uniform buffer variables as pull constants.

Eric Anholt eric at anholt.net
Tue Jul 31 15:01:50 PDT 2012


---
 src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp |   52 +++++++++++++++++++++++-
 src/mesa/drivers/dri/i965/brw_vs.c             |    5 +++
 2 files changed, 55 insertions(+), 2 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
index 33078a0..f7244d4 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
@@ -830,6 +830,13 @@ vec4_visitor::visit(ir_variable *ir)
    case ir_var_uniform:
       reg = new(this->mem_ctx) dst_reg(UNIFORM, this->uniforms);
 
+      /* Thanks to the lower_ubo_reference pass, we will see only
+       * ir_binop_ubo_load expressions and not ir_dereference_variable for UBO
+       * variables, so no need for them to be in variable_ht.
+       */
+      if (ir->uniform_block != -1)
+         return;
+
       /* Track how big the whole uniform variable is, in case we need to put a
        * copy of its data into pull constants for array access.
        */
@@ -1314,9 +1321,50 @@ vec4_visitor::visit(ir_expression *ir)
 	 inst = emit(BRW_OPCODE_SHR, result_dst, op[0], op[1]);
       break;
 
-   case ir_binop_ubo_load:
-      assert(!"not yet supported");
+   case ir_binop_ubo_load: {
+      ir_constant *uniform_block = ir->operands[0]->as_constant();
+      ir_constant *const_offset_ir = ir->operands[1]->as_constant();
+      unsigned const_offset = const_offset_ir ? const_offset_ir->value.u[0] : 0;
+      src_reg offset = op[1];
+
+      /* Now, load the vector from that offset. */
+      assert(ir->type->is_vector() || ir->type->is_scalar());
+
+      src_reg packed_consts = src_reg(this, glsl_type::vec4_type);
+      packed_consts.type = result.type;
+      src_reg surf_index =
+         src_reg(SURF_INDEX_VS_UBO(uniform_block->value.u[0]));
+      if (const_offset_ir) {
+         offset = src_reg(const_offset / 16);
+      } else {
+         emit(BRW_OPCODE_SHR, dst_reg(offset), offset, src_reg(4));
+      }
+
+      vec4_instruction *pull =
+         emit(new(mem_ctx) vec4_instruction(this,
+                                            VS_OPCODE_PULL_CONSTANT_LOAD,
+                                            dst_reg(packed_consts),
+                                            surf_index,
+                                            offset));
+      pull->base_mrf = 14;
+      pull->mlen = 1;
+
+      packed_consts.swizzle = swizzle_for_size(ir->type->vector_elements);
+      packed_consts.swizzle += BRW_SWIZZLE4(const_offset % 16 / 4,
+                                            const_offset % 16 / 4,
+                                            const_offset % 16 / 4,
+                                            const_offset % 16 / 4);
+
+      /* UBO bools are any nonzero int.  We store bools as either 0 or 1. */
+      if (ir->type->base_type == GLSL_TYPE_BOOL) {
+         emit(CMP(result_dst, packed_consts, src_reg(0u),
+                  BRW_CONDITIONAL_NZ));
+         emit(AND(result_dst, result, src_reg(0x1)));
+      } else {
+         emit(MOV(result_dst, packed_consts));
+      }
       break;
+   }
 
    case ir_quadop_vector:
       assert(!"not reached: should be handled by lower_quadop_vector");
diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c
index 81c586a..2b504b9 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.c
+++ b/src/mesa/drivers/dri/i965/brw_vs.c
@@ -251,6 +251,11 @@ do_vs_prog(struct brw_context *brw,
       c.prog_data.num_surfaces = 1;
    if (c.vp->program.Base.SamplersUsed)
       c.prog_data.num_surfaces = SURF_INDEX_VS_TEXTURE(BRW_MAX_TEX_UNIT);
+   if (prog &&
+       prog->_LinkedShaders[MESA_SHADER_VERTEX]->NumUniformBlocks) {
+      c.prog_data.num_surfaces =
+	 SURF_INDEX_VS_UBO(prog->_LinkedShaders[MESA_SHADER_VERTEX]->NumUniformBlocks);
+   }
 
    /* Scratch space is used for register spilling */
    if (c.last_scratch) {
-- 
1.7.10.4



More information about the mesa-dev mailing list