[Mesa-dev] [PATCH 48/74] i965/fs: Implement SSBO reads
Iago Toral Quiroga
itoral at igalia.com
Thu May 14 07:06:51 PDT 2015
---
src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 70 +++++++++++++++++++++++++++-
1 file changed, 68 insertions(+), 2 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index 7518b1f..e2624616 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -1197,10 +1197,76 @@ fs_visitor::visit(ir_expression *ir)
emit(FS_OPCODE_PACK_HALF_2x16_SPLIT, this->result, op[0], op[1]);
break;
- case ir_binop_ssbo_load:
+ case ir_binop_ssbo_load: {
assert(brw->gen >= 7);
- assert(!"Not implemented");
+
+ ir_constant *const_uniform_block = ir->operands[0]->as_constant();
+ ir_constant *const_offset = ir->operands[1]->as_constant();
+
+ fs_reg surf_index;
+ if (const_uniform_block) {
+ unsigned index = stage_prog_data->binding_table.ubo_start +
+ const_uniform_block->value.u[0];
+ surf_index = fs_reg(index);
+ brw_mark_surface_used(prog_data, index);
+ } else {
+ surf_index = vgrf(glsl_type::uint_type);
+ emit(ADD(surf_index, op[0],
+ fs_reg(stage_prog_data->binding_table.ubo_start)))
+ ->force_writemask_all = true;
+
+ /* Assume this may touch any UBO. It would be nice to provide
+ * a tighter bound, but the array information is already lowered away.
+ */
+ brw_mark_surface_used(prog_data,
+ stage_prog_data->binding_table.ubo_start +
+ shader_prog->NumUniformBlocks - 1);
+ }
+
+ /* Get the offset to read from */
+ unsigned const_offset_bytes = 0;
+ if (const_offset)
+ const_offset_bytes = const_offset->value.u[0];
+ fs_reg offset_reg = vgrf(glsl_type::uint_type);
+ emit(MOV(offset_reg, op[1]));
+
+ /* Read the vector */
+ const bool uses_kill = (stage == MESA_SHADER_FRAGMENT &&
+ ((brw_wm_prog_data *)prog_data)->uses_kill);
+ fs_builder bld(devinfo, mem_ctx, alloc, instructions, dispatch_width,
+ stage, uses_kill);
+
+ bld.set_annotation(current_annotation);
+ bld.set_base_ir(base_ir);
+
+ for (int i = 0; i < ir->type->vector_elements; i++) {
+ fs_reg read_result = emit_untyped_read(bld, surf_index, offset_reg,
+ 1 /* dims */, 1 /* size */,
+ BRW_PREDICATE_NONE);
+ read_result.type = result.type;
+
+ if (ir->type->base_type == GLSL_TYPE_BOOL) {
+ emit(CMP(result, read_result, fs_reg(0u), BRW_CONDITIONAL_NZ));
+ } else {
+ emit(MOV(result, read_result));
+ }
+
+ result = offset(result, 1);
+
+ /* Vector components are stored contiguous in memory */
+ if (i < ir->type->vector_elements) {
+ if (const_offset) {
+ const_offset_bytes += 4;
+ emit(MOV(offset_reg, fs_reg(const_offset_bytes)));
+ } else {
+ emit(ADD(offset_reg, offset_reg, brw_imm_ud(4)));
+ }
+ }
+ }
+
+ result.reg_offset = 0;
break;
+ }
case ir_binop_ubo_load: {
/* This IR node takes a constant uniform block and a constant or
--
1.9.1
More information about the mesa-dev
mailing list