Reviewed-by: Jordan Justen <jordan.l.jus...@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@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev