[Mesa-dev] [PATCH v2 27/82] mesa: Add new IR node ir_ssbo_store

Jordan Justen jordan.l.justen at intel.com
Mon Jun 22 14:45:08 PDT 2015


Reviewed-by: Jordan Justen <jordan.l.justen at intel.com>

On 2015-06-03 00:01:17, Iago Toral Quiroga wrote:
> Shader storage buffer objects (SSBO) require special handling: when we
> detect writes to any channel of a shader buffer variable we need to
> emit the corresponding write to memory. We will later add a lowering pass
> that detects these writes and injects ir_ssbo_store nodes in the IR so
> drivers can  generate code for the memory writes.
> ---
>  src/glsl/ir.h                                  | 38 ++++++++++++++++++++++++++
>  src/glsl/ir_hierarchical_visitor.cpp           | 18 ++++++++++++
>  src/glsl/ir_hierarchical_visitor.h             |  2 ++
>  src/glsl/ir_hv_accept.cpp                      | 23 ++++++++++++++++
>  src/glsl/ir_print_visitor.cpp                  | 12 ++++++++
>  src/glsl/ir_print_visitor.h                    |  1 +
>  src/glsl/ir_rvalue_visitor.cpp                 | 21 ++++++++++++++
>  src/glsl/ir_rvalue_visitor.h                   |  3 ++
>  src/glsl/ir_visitor.h                          |  2 ++
>  src/glsl/nir/glsl_to_nir.cpp                   |  7 +++++
>  src/mesa/drivers/dri/i965/brw_vec4.h           |  1 +
>  src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp |  6 ++++
>  src/mesa/program/ir_to_mesa.cpp                |  7 +++++
>  src/mesa/state_tracker/st_glsl_to_tgsi.cpp     |  7 +++++
>  14 files changed, 148 insertions(+)
> 
> diff --git a/src/glsl/ir.h b/src/glsl/ir.h
> index 1118732..2a0b28c 100644
> --- a/src/glsl/ir.h
> +++ b/src/glsl/ir.h
> @@ -78,6 +78,7 @@ enum ir_node_type {
>     ir_type_discard,
>     ir_type_emit_vertex,
>     ir_type_end_primitive,
> +   ir_type_ssbo_store,
>     ir_type_max, /**< maximum ir_type enum number, for validation */
>     ir_type_unset = ir_type_max
>  };
> @@ -2407,6 +2408,43 @@ public:
>     ir_rvalue *stream;
>  };
>  
> +/**
> + * IR instruction to write to a shader storage buffer object (SSBO)
> + */
> +class ir_ssbo_store : public ir_instruction {
> +public:
> +   ir_ssbo_store(ir_rvalue *block, ir_rvalue *offset, ir_rvalue *val,
> +                 unsigned write_mask)
> +      : ir_instruction(ir_type_ssbo_store),
> +        block(block), offset(offset), val(val), write_mask(write_mask)
> +   {
> +      assert(block);
> +      assert(offset);
> +      assert(val);
> +      assert(write_mask != 0);
> +   }
> +
> +   virtual void accept(ir_visitor *v)
> +   {
> +      v->visit(this);
> +   }
> +
> +   virtual ir_ssbo_store *clone(void *mem_ctx, struct hash_table *ht) const
> +   {
> +      return new(mem_ctx) ir_ssbo_store(this->block->clone(mem_ctx, ht),
> +                                        this->offset->clone(mem_ctx, ht),
> +                                        this->val->clone(mem_ctx, ht),
> +                                        this->write_mask);
> +   }
> +
> +   virtual ir_visitor_status accept(ir_hierarchical_visitor *);
> +
> +   ir_rvalue *block;
> +   ir_rvalue *offset;
> +   ir_rvalue *val;
> +   unsigned write_mask;
> +};
> +
>  /*@}*/
>  
>  /**
> diff --git a/src/glsl/ir_hierarchical_visitor.cpp b/src/glsl/ir_hierarchical_visitor.cpp
> index adb6294..1aa5cc0 100644
> --- a/src/glsl/ir_hierarchical_visitor.cpp
> +++ b/src/glsl/ir_hierarchical_visitor.cpp
> @@ -349,6 +349,24 @@ ir_hierarchical_visitor::visit_leave(ir_end_primitive *ir)
>     return visit_continue;
>  }
>  
> +ir_visitor_status
> +ir_hierarchical_visitor::visit_enter(ir_ssbo_store *ir)
> +{
> +   if (this->callback_enter != NULL)
> +      this->callback_enter(ir, this->data_enter);
> +
> +   return visit_continue;
> +}
> +
> +ir_visitor_status
> +ir_hierarchical_visitor::visit_leave(ir_ssbo_store *ir)
> +{
> +   if (this->callback_leave != NULL)
> +      this->callback_leave(ir, this->data_leave);
> +
> +   return visit_continue;
> +}
> +
>  void
>  ir_hierarchical_visitor::run(exec_list *instructions)
>  {
> diff --git a/src/glsl/ir_hierarchical_visitor.h b/src/glsl/ir_hierarchical_visitor.h
> index faa52fd..49dc37e 100644
> --- a/src/glsl/ir_hierarchical_visitor.h
> +++ b/src/glsl/ir_hierarchical_visitor.h
> @@ -139,6 +139,8 @@ public:
>     virtual ir_visitor_status visit_leave(class ir_emit_vertex *);
>     virtual ir_visitor_status visit_enter(class ir_end_primitive *);
>     virtual ir_visitor_status visit_leave(class ir_end_primitive *);
> +   virtual ir_visitor_status visit_enter(class ir_ssbo_store *);
> +   virtual ir_visitor_status visit_leave(class ir_ssbo_store *);
>     /*@}*/
>  
>  
> diff --git a/src/glsl/ir_hv_accept.cpp b/src/glsl/ir_hv_accept.cpp
> index be5b3ea..500ce4b 100644
> --- a/src/glsl/ir_hv_accept.cpp
> +++ b/src/glsl/ir_hv_accept.cpp
> @@ -429,3 +429,26 @@ ir_end_primitive::accept(ir_hierarchical_visitor *v)
>  
>     return (s == visit_stop) ? s : v->visit_leave(this);
>  }
> +
> +
> +ir_visitor_status
> +ir_ssbo_store::accept(ir_hierarchical_visitor *v)
> +{
> +   ir_visitor_status s = v->visit_enter(this);
> +   if (s != visit_continue)
> +      return (s == visit_continue_with_parent) ? visit_continue : s;
> +
> +   s = this->block->accept(v);
> +   if (s != visit_continue)
> +      return (s == visit_continue_with_parent) ? visit_continue : s;
> +
> +   s = this->offset->accept(v);
> +   if (s != visit_continue)
> +      return (s == visit_continue_with_parent) ? visit_continue : s;
> +
> +   s = this->val->accept(v);
> +   if (s != visit_continue)
> +      return (s == visit_continue_with_parent) ? visit_continue : s;
> +
> +   return (s == visit_stop) ? s : v->visit_leave(this);
> +}
> diff --git a/src/glsl/ir_print_visitor.cpp b/src/glsl/ir_print_visitor.cpp
> index 4ecc65f..f2b2103 100644
> --- a/src/glsl/ir_print_visitor.cpp
> +++ b/src/glsl/ir_print_visitor.cpp
> @@ -576,3 +576,15 @@ ir_print_visitor::visit(ir_end_primitive *ir)
>     fprintf(f, ")\n");
>  
>  }
> +
> +void
> +ir_print_visitor::visit(ir_ssbo_store *ir)
> +{
> +   fprintf(f, "(ssbo_store ");
> +   ir->block->accept(this);
> +   ir->offset->accept(this);
> +   ir->val->accept(this);
> +   fprintf(f, "(writemask=0x%x)", ir->write_mask);
> +   fprintf(f, ")\n");
> +
> +}
> diff --git a/src/glsl/ir_print_visitor.h b/src/glsl/ir_print_visitor.h
> index 98f041d..2e2a177 100644
> --- a/src/glsl/ir_print_visitor.h
> +++ b/src/glsl/ir_print_visitor.h
> @@ -71,6 +71,7 @@ public:
>     virtual void visit(ir_loop_jump *);
>     virtual void visit(ir_emit_vertex *);
>     virtual void visit(ir_end_primitive *);
> +   virtual void visit(ir_ssbo_store *);
>     /*@}*/
>  
>  private:
> diff --git a/src/glsl/ir_rvalue_visitor.cpp b/src/glsl/ir_rvalue_visitor.cpp
> index 2eee3da..d5a586b 100644
> --- a/src/glsl/ir_rvalue_visitor.cpp
> +++ b/src/glsl/ir_rvalue_visitor.cpp
> @@ -170,6 +170,15 @@ ir_rvalue_base_visitor::rvalue_visit(ir_end_primitive *ir)
>  }
>  
>  ir_visitor_status
> +ir_rvalue_base_visitor::rvalue_visit(ir_ssbo_store *ir)
> +{
> +   handle_rvalue(&ir->block);
> +   handle_rvalue(&ir->offset);
> +   handle_rvalue(&ir->val);
> +   return visit_continue;
> +}
> +
> +ir_visitor_status
>  ir_rvalue_visitor::visit_leave(ir_expression *ir)
>  {
>     return rvalue_visit(ir);
> @@ -242,6 +251,12 @@ ir_rvalue_visitor::visit_leave(ir_end_primitive *ir)
>  }
>  
>  ir_visitor_status
> +ir_rvalue_visitor::visit_leave(ir_ssbo_store *ir)
> +{
> +   return rvalue_visit(ir);
> +}
> +
> +ir_visitor_status
>  ir_rvalue_enter_visitor::visit_enter(ir_expression *ir)
>  {
>     return rvalue_visit(ir);
> @@ -312,3 +327,9 @@ ir_rvalue_enter_visitor::visit_enter(ir_end_primitive *ir)
>  {
>     return rvalue_visit(ir);
>  }
> +
> +ir_visitor_status
> +ir_rvalue_enter_visitor::visit_enter(ir_ssbo_store *ir)
> +{
> +   return rvalue_visit(ir);
> +}
> diff --git a/src/glsl/ir_rvalue_visitor.h b/src/glsl/ir_rvalue_visitor.h
> index 185c72a..a209b78 100644
> --- a/src/glsl/ir_rvalue_visitor.h
> +++ b/src/glsl/ir_rvalue_visitor.h
> @@ -44,6 +44,7 @@ public:
>     ir_visitor_status rvalue_visit(ir_texture *);
>     ir_visitor_status rvalue_visit(ir_emit_vertex *);
>     ir_visitor_status rvalue_visit(ir_end_primitive *);
> +   ir_visitor_status rvalue_visit(ir_ssbo_store *);
>  
>     virtual void handle_rvalue(ir_rvalue **rvalue) = 0;
>  };
> @@ -63,6 +64,7 @@ public:
>     virtual ir_visitor_status visit_leave(ir_texture *);
>     virtual ir_visitor_status visit_leave(ir_emit_vertex *);
>     virtual ir_visitor_status visit_leave(ir_end_primitive *);
> +   virtual ir_visitor_status visit_leave(ir_ssbo_store *);
>  };
>  
>  class ir_rvalue_enter_visitor : public ir_rvalue_base_visitor {
> @@ -80,4 +82,5 @@ public:
>     virtual ir_visitor_status visit_enter(ir_texture *);
>     virtual ir_visitor_status visit_enter(ir_emit_vertex *);
>     virtual ir_visitor_status visit_enter(ir_end_primitive *);
> +   virtual ir_visitor_status visit_enter(ir_ssbo_store *);
>  };
> diff --git a/src/glsl/ir_visitor.h b/src/glsl/ir_visitor.h
> index 40f96ff..3a68c27 100644
> --- a/src/glsl/ir_visitor.h
> +++ b/src/glsl/ir_visitor.h
> @@ -65,6 +65,7 @@ public:
>     virtual void visit(class ir_loop_jump *) = 0;
>     virtual void visit(class ir_emit_vertex *) = 0;
>     virtual void visit(class ir_end_primitive *) = 0;
> +   virtual void visit(class ir_ssbo_store *) {};
>     /*@}*/
>  };
>  
> @@ -85,6 +86,7 @@ public:
>     virtual void visit(class ir_call *) {}
>     virtual void visit(class ir_emit_vertex *) {}
>     virtual void visit(class ir_end_primitive *) {}
> +   virtual void visit(class ir_ssbo_store *) {}
>  };
>  #endif /* __cplusplus */
>  
> diff --git a/src/glsl/nir/glsl_to_nir.cpp b/src/glsl/nir/glsl_to_nir.cpp
> index bcf897c..f80481b 100644
> --- a/src/glsl/nir/glsl_to_nir.cpp
> +++ b/src/glsl/nir/glsl_to_nir.cpp
> @@ -58,6 +58,7 @@ public:
>     virtual void visit(ir_assignment *);
>     virtual void visit(ir_emit_vertex *);
>     virtual void visit(ir_end_primitive *);
> +   virtual void visit(ir_ssbo_store *);
>     virtual void visit(ir_expression *);
>     virtual void visit(ir_swizzle *);
>     virtual void visit(ir_texture *);
> @@ -574,6 +575,12 @@ nir_visitor::visit(ir_end_primitive *ir)
>  }
>  
>  void
> +nir_visitor::visit(ir_ssbo_store *ir)
> +{
> +   assert("Not implemented yet");
> +}
> +
> +void
>  nir_visitor::visit(ir_loop_jump *ir)
>  {
>     nir_jump_type type;
> diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
> index 06a16a4..e6b356d 100644
> --- a/src/mesa/drivers/dri/i965/brw_vec4.h
> +++ b/src/mesa/drivers/dri/i965/brw_vec4.h
> @@ -160,6 +160,7 @@ public:
>     virtual void visit(ir_if *);
>     virtual void visit(ir_emit_vertex *);
>     virtual void visit(ir_end_primitive *);
> +   virtual void visit(ir_ssbo_store *);
>     /*@}*/
>  
>     src_reg result;
> diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
> index bf8c6b4..a2a75a4 100644
> --- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
> @@ -2970,6 +2970,12 @@ vec4_visitor::visit(ir_end_primitive *)
>  }
>  
>  void
> +vec4_visitor::visit(ir_ssbo_store *)
> +{
> +   unreachable("not implemented yet");
> +}
> +
> +void
>  vec4_visitor::emit_untyped_atomic(unsigned atomic_op, unsigned surf_index,
>                                    dst_reg dst, src_reg offset,
>                                    src_reg src0, src_reg src1)
> diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
> index b86718c..8cdb704 100644
> --- a/src/mesa/program/ir_to_mesa.cpp
> +++ b/src/mesa/program/ir_to_mesa.cpp
> @@ -262,6 +262,7 @@ public:
>     virtual void visit(ir_if *);
>     virtual void visit(ir_emit_vertex *);
>     virtual void visit(ir_end_primitive *);
> +   virtual void visit(ir_ssbo_store *);
>     /*@}*/
>  
>     src_reg result;
> @@ -2118,6 +2119,12 @@ ir_to_mesa_visitor::visit(ir_end_primitive *)
>     assert(!"Geometry shaders not supported.");
>  }
>  
> +void
> +ir_to_mesa_visitor::visit(ir_ssbo_store *)
> +{
> +   assert(!"Shader storage buffer object (SSBO) writes not supported.");
> +}
> +
>  ir_to_mesa_visitor::ir_to_mesa_visitor()
>  {
>     result.file = PROGRAM_UNDEFINED;
> diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> index 95b2d52..5a2bdc3 100644
> --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> @@ -372,6 +372,7 @@ public:
>     virtual void visit(ir_if *);
>     virtual void visit(ir_emit_vertex *);
>     virtual void visit(ir_end_primitive *);
> +   virtual void visit(ir_ssbo_store *);
>     /*@}*/
>  
>     st_src_reg result;
> @@ -3344,6 +3345,12 @@ glsl_to_tgsi_visitor::visit(ir_end_primitive *ir)
>     emit(ir, TGSI_OPCODE_ENDPRIM, undef_dst, this->result);
>  }
>  
> +void
> +glsl_to_tgsi_visitor::visit(ir_ssbo_store *ir)
> +{
> +   assert(!"Not implemented yet");
> +}
> +
>  glsl_to_tgsi_visitor::glsl_to_tgsi_visitor()
>  {
>     result.file = PROGRAM_UNDEFINED;
> -- 
> 1.9.1
> 
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list