glsl: Add a "ubo_load" expression type for fetches from UBOs.
authorEric Anholt <eric@anholt.net>
Mon, 9 Jul 2012 22:52:53 +0000 (15:52 -0700)
committerEric Anholt <eric@anholt.net>
Tue, 7 Aug 2012 18:47:49 +0000 (11:47 -0700)
Drivers will probably want to be able to take UBO references in a
shader like:

        uniform ubo1 {
                float a;
                float b;
                float c;
                float d;
        }

        void main() {
             gl_FragColor = vec4(a, b, c, d);
        }

and generate a single aligned vec4 load out of the UBO.  For intel,
this involves recognizing the shared offset of the aligned loads and
CSEing them out.  Obviously that involves breaking things down to
loads from an offset from a particular UBO first.  Thus, the driver
doesn't want to see

variable_ref(ir_variable("a")),

and even more so does it not want to see

array_ref(record_ref(variable_ref(ir_variable("a")),
          "field1"), variable_ref(ir_variable("i"))).

where a.field1[i] is a row_major matrix.

Instead, we're going to make a lowering pass to break UBO references
down to expressions that are obvious to codegen, and amenable to
merging through CSE.

v2: Fix some partial thoughts in the ir_binop comment (review by Kenneth)

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/glsl/ir.cpp
src/glsl/ir.h
src/glsl/ir_validate.cpp
src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp
src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
src/mesa/program/ir_to_mesa.cpp
src/mesa/state_tracker/st_glsl_to_tgsi.cpp

index b0e38d8..f59cdd2 100644 (file)
@@ -480,6 +480,7 @@ static const char *const operator_strs[] = {
    "min",
    "max",
    "pow",
+   "ubo_load",
    "vector",
 };
 
index f019837..89c516c 100644 (file)
@@ -1018,9 +1018,17 @@ enum ir_expression_operation {
    ir_binop_pow,
 
    /**
+    * Load a value the size of a given GLSL type from a uniform block.
+    *
+    * operand0 is the ir_constant uniform block index in the linked shader.
+    * operand1 is a byte offset within the uniform block.
+    */
+   ir_binop_ubo_load,
+
+   /**
     * A sentinel marking the last of the binary operations.
     */
-   ir_last_binop = ir_binop_pow,
+   ir_last_binop = ir_binop_ubo_load,
 
    ir_quadop_vector,
 
index 191d398..af0b576 100644 (file)
@@ -423,6 +423,13 @@ ir_validate::visit_leave(ir_expression *ir)
       assert(ir->operands[0]->type == ir->operands[1]->type);
       break;
 
+   case ir_binop_ubo_load:
+      assert(ir->operands[0]->as_constant());
+      assert(ir->operands[0]->type == glsl_type::uint_type);
+
+      assert(ir->operands[1]->type == glsl_type::uint_type);
+      break;
+
    case ir_quadop_vector:
       /* The vector operator collects some number of scalars and generates a
        * vector from them.
index 983d92e..58521ee 100644 (file)
@@ -337,6 +337,11 @@ ir_channel_expressions_visitor::visit_leave(ir_assignment *ir)
    case ir_unop_noise:
       assert(!"noise should have been broken down to function call");
       break;
+
+   case ir_binop_ubo_load:
+      assert(!"not yet supported");
+      break;
+
    case ir_quadop_vector:
       assert(!"should have been lowered");
       break;
index f5090fa..1e18e92 100644 (file)
@@ -571,6 +571,10 @@ fs_visitor::visit(ir_expression *ir)
       else
         inst = emit(BRW_OPCODE_SHR, this->result, op[0], op[1]);
       break;
+
+   case ir_binop_ubo_load:
+      assert(!"not yet supported");
+      break;
    }
 }
 
index 9ae99b4..8a4a1b0 100644 (file)
@@ -1314,6 +1314,10 @@ 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");
+      break;
+
    case ir_quadop_vector:
       assert(!"not reached: should be handled by lower_quadop_vector");
       break;
index 255a8a7..70c4cc8 100644 (file)
@@ -1456,6 +1456,10 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
       emit(ir, OPCODE_MOV, result_dst, op[0]);
       break;
 
+   case ir_binop_ubo_load:
+      assert(!"not supported");
+      break;
+
    case ir_quadop_vector:
       /* This operation should have already been handled.
        */
index 66627ac..43c80be 100644 (file)
@@ -1867,6 +1867,10 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
       assert(!"GLSL 1.30 features unsupported");
       break;
 
+   case ir_binop_ubo_load:
+      assert(!"not yet supported");
+      break;
+
    case ir_quadop_vector:
       /* This operation should have already been handled.
        */