[Mesa-dev] [PATCH 5/6] i965/gen7: Handle atomic instructions from the VEC4 back-end.
Paul Berry
stereotype441 at gmail.com
Fri Nov 1 10:26:45 PDT 2013
On 29 October 2013 16:37, Francisco Jerez <currojerez at riseup.net> wrote:
> 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.
>
> v2: Represent atomics as GLSL intrinsics. Add support for variably
> indexed atomic counter arrays.
> ---
> src/mesa/drivers/dri/i965/brw_vec4.h | 9 +++
> src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp | 100
> ++++++++++++++++++++++++-
> 2 files changed, 107 insertions(+), 2 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h
> b/src/mesa/drivers/dri/i965/brw_vec4.h
> index a479646..1f29e57 100644
> --- a/src/mesa/drivers/dri/i965/brw_vec4.h
> +++ b/src/mesa/drivers/dri/i965/brw_vec4.h
> @@ -489,6 +489,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,
> + dst_reg dst, src_reg offset, src_reg src0,
> + src_reg src1);
> +
> + void emit_untyped_surface_read(unsigned surf_index, dst_reg dst,
> + src_reg offset);
> +
> src_reg get_scratch_offset(vec4_instruction *inst,
> src_reg *reladdr, int reg_offset);
> src_reg get_pull_constant_offset(vec4_instruction *inst,
> @@ -514,6 +521,8 @@ public:
>
> void dump_instruction(backend_instruction *inst);
>
> + void visit_atomic_counter_intrinsic(ir_call *ir);
> +
> protected:
> void emit_vertex();
> void lower_attributes_to_hw_regs(const int *attribute_map,
> diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
> b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
> index 7f2ca95..7f8d49c 100644
> --- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
> @@ -975,7 +975,7 @@ vec4_visitor::visit(ir_variable *ir)
> * 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->is_in_uniform_block())
> + if (ir->is_in_uniform_block() || ir->type->contains_atomic())
>
As with the previous patch, the comment above this "if" statement should be
updated to explain why it's ok to return when encountering a variable that
contains an atomic.
With that fixed, this patch is:
Reviewed-by: Paul Berry <stereotype441 at gmail.com>
> return;
>
> /* Track how big the whole uniform variable is, in case we need to
> put a
> @@ -2160,9 +2160,56 @@ vec4_visitor::visit(ir_constant *ir)
> }
>
> void
> +vec4_visitor::visit_atomic_counter_intrinsic(ir_call *ir)
> +{
> + ir_dereference *deref = static_cast<ir_dereference *>(
> + ir->actual_parameters.get_head());
> + ir_variable *location = deref->variable_referenced();
> + unsigned surf_index = (prog_data->base.binding_table.abo_start +
> + location->atomic.buffer_index);
> +
> + /* Calculate the surface offset */
> + src_reg offset(this, glsl_type::uint_type);
> + ir_dereference_array *deref_array = deref->as_dereference_array();
> + if (deref_array) {
> + deref_array->array_index->accept(this);
> +
> + src_reg tmp(this, glsl_type::uint_type);
> + emit(MUL(dst_reg(tmp), this->result, ATOMIC_COUNTER_SIZE));
> + emit(ADD(dst_reg(offset), tmp, location->atomic.offset));
> + } else {
> + offset = location->atomic.offset;
> + }
> +
> + /* Emit the appropriate machine instruction */
> + const char *callee = ir->callee->function_name();
> + dst_reg dst = get_assignment_lhs(ir->return_deref, this);
> +
> + if (!strcmp("__intrinsic_atomic_read", callee)) {
> + emit_untyped_surface_read(surf_index, dst, offset);
> +
> + } else if (!strcmp("__intrinsic_atomic_increment", callee)) {
> + emit_untyped_atomic(BRW_AOP_INC, surf_index, dst, offset,
> + src_reg(), src_reg());
> +
> + } else if (!strcmp("__intrinsic_atomic_predecrement", callee)) {
> + emit_untyped_atomic(BRW_AOP_PREDEC, surf_index, dst, offset,
> + src_reg(), src_reg());
> + }
> +}
> +
> +void
> vec4_visitor::visit(ir_call *ir)
> {
> - assert(!"not reached");
> + const char *callee = ir->callee->function_name();
> +
> + if (!strcmp("__intrinsic_atomic_read", callee) ||
> + !strcmp("__intrinsic_atomic_increment", callee) ||
> + !strcmp("__intrinsic_atomic_predecrement", callee)) {
> + visit_atomic_counter_intrinsic(ir);
> + } else {
> + assert(!"Unsupported intrinsic.");
> + }
> }
>
> void
> @@ -2557,6 +2604,55 @@ vec4_visitor::visit(ir_end_primitive *)
> }
>
> void
> +vec4_visitor::emit_untyped_atomic(unsigned atomic_op, unsigned surf_index,
> + dst_reg dst, src_reg offset,
> + 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),
> 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. Note that this maps to the normal SIMD8
> + * untyped atomic message on Ivy Bridge, but that's OK because
> + * unused channels will be masked out.
> + */
> + 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, dst_reg dst,
> + src_reg offset)
> +{
> + /* Set the surface read offset. */
> + emit(MOV(brw_writemask(brw_uvec_mrf(8, 0, 0), WRITEMASK_X), offset));
> +
> + /* Emit the instruction. Note that this maps to the normal SIMD8
> + * untyped surface read message, but that's OK because unused
> + * channels will be masked out.
> + */
> + vec4_instruction *inst = emit(SHADER_OPCODE_UNTYPED_SURFACE_READ,
> + dst, src_reg(surf_index));
> + inst->base_mrf = 0;
> + inst->mlen = 1;
> +}
> +
> +void
> vec4_visitor::emit_ndc_computation()
> {
> /* Get the position */
> --
> 1.8.3.4
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20131101/850dec10/attachment-0001.html>
More information about the mesa-dev
mailing list