diff options
author | Eric Anholt <[email protected]> | 2012-06-25 14:55:01 -0700 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2012-08-07 13:54:52 -0700 |
commit | 04871058eb01c5b51a0180055e7dbdc967f56604 (patch) | |
tree | a96922d05ccda01c4aaeeb51dfa822cc5964f669 | |
parent | 90de96ff0d6d54ba0f9a337a6a107acf4134682d (diff) |
i965/vs: Add support for loading uniform buffer variables as pull constants.
Unlike the FS side in the previous commit, this does variable indexing just
fine, using the same code as we used for other variable-indexed pull
constants.
Reviewed-by: Kenneth Graunke <[email protected]>
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp | 52 | ||||
-rw-r--r-- | 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 19001bfab29..8f697c401eb 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 feec4558762..ba818fda353 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) { |