This can deal with all the 15 32-bit untyped atomic operations the hardware supports, but only INC and PREDEC are going to be exposed through the API for now. --- src/mesa/drivers/dri/i965/brw_vec4.h | 7 +++ src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp | 64 ++++++++++++++++++++++++++ 2 files changed, 71 insertions(+)
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h index 37e1da0..7678925 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4.h +++ b/src/mesa/drivers/dri/i965/brw_vec4.h @@ -499,6 +499,13 @@ public: void emit_shader_time_write(enum shader_time_shader_type type, src_reg value); + void emit_untyped_atomic(unsigned atomic_op, unsigned surf_index, + unsigned offset, dst_reg dst, src_reg src0, + src_reg src1); + + void emit_untyped_surface_read(unsigned surf_index, unsigned offset, + dst_reg dst); + src_reg get_scratch_offset(vec4_instruction *inst, src_reg *reladdr, int reg_offset); src_reg get_pull_constant_offset(vec4_instruction *inst, diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp index a19686b..c3d4506 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp @@ -2464,8 +2464,72 @@ vec4_visitor::visit(ir_end_primitive *) } void +vec4_visitor::emit_untyped_atomic(unsigned atomic_op, unsigned surf_index, + unsigned offset, dst_reg dst, + src_reg src0, src_reg src1) +{ + unsigned mlen = 0; + + /* Set the atomic operation offset. */ + emit(MOV(brw_writemask(brw_uvec_mrf(8, mlen, 0), WRITEMASK_X), + src_reg(offset))); + mlen++; + + /* Set the atomic operation arguments. */ + if (src0.file != BAD_FILE) { + emit(MOV(brw_writemask(brw_uvec_mrf(8, mlen, 0), WRITEMASK_X), src0)); + mlen++; + } + + if (src1.file != BAD_FILE) { + emit(MOV(brw_writemask(brw_uvec_mrf(8, mlen, 0), WRITEMASK_X), src1)); + mlen++; + } + + /* Emit the instruction. */ + vec4_instruction *inst = emit(SHADER_OPCODE_UNTYPED_ATOMIC, dst, + src_reg(atomic_op), src_reg(surf_index)); + inst->base_mrf = 0; + inst->mlen = mlen; +} + +void +vec4_visitor::emit_untyped_surface_read(unsigned surf_index, + unsigned offset, dst_reg dst) +{ + /* Set the surface read offset. */ + emit(MOV(brw_writemask(brw_uvec_mrf(8, 0, 0), WRITEMASK_X), + src_reg(offset))); + + /* Emit the instruction. */ + vec4_instruction *inst = emit(SHADER_OPCODE_UNTYPED_SURFACE_READ, + dst, src_reg(surf_index)); + inst->base_mrf = 0; + inst->mlen = 1; +} + +void vec4_visitor::visit(ir_atomic *ir) { + ir_variable *loc = ir->location->variable_referenced(); + unsigned surf_index = SURF_INDEX_VEC4_ABO(loc->atomic.buffer_index); + + result = src_reg(this, ir->type); + + switch (ir->op) { + case ir_atomic_read: + emit_untyped_surface_read(surf_index, loc->atomic.offset, + dst_reg(result)); + break; + case ir_atomic_inc: + emit_untyped_atomic(BRW_AOP_INC, surf_index, loc->atomic.offset, + dst_reg(result), src_reg(), src_reg()); + break; + case ir_atomic_dec: + emit_untyped_atomic(BRW_AOP_PREDEC, surf_index, loc->atomic.offset, + dst_reg(result), src_reg(), src_reg()); + break; + } } void -- 1.8.3.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev