On jue, 2014-09-18 at 00:30 -0700, Jordan Justen wrote: > On Thu, Aug 14, 2014 at 4:11 AM, Iago Toral Quiroga <ito...@igalia.com> wrote: > > For this we will need to move PrimitiveID information, delivered in the > > thread > > payload in r0.1, to a separate register (we use GS_OPCODE_SET_PRIMITIVE_ID > > for this), then map the corresponding varying slot to that register in the > > setup_payload() method. > > > > Notice that we cannot use a virtual register as the destination for the > > PrimitiveID because we need to map all input attributes to hardware > > registers > > in setup_payload(), which happens before virtual registers are mapped to > > hardware registers. We could work around that issue if we were able to > > compute > > the first non-payload register in emit_prolog() and move the PrimitiveID > > information to that register, but we can't because at that point we still > > don't know the final number uniforms that will be included in the payload. > > > > So, what we do is to place PrimitiveID information in r1, which is always > > delivered as part of the payload but its only populated with data > > relevant for transform feedback when we set GEN6_GS_SVBI_PAYLOAD_ENABLE > > in the 3DSTATE_GS state packet. > > > > When we implement transform feedback, we wil make sure to move the value of > > r1 > > to another register before we overwrite it with the PrimitiveID. > > --- > > src/mesa/drivers/dri/i965/gen6_gs_visitor.cpp | 69 > > ++++++++++++++++++++++++++- > > src/mesa/drivers/dri/i965/gen6_gs_visitor.h | 2 + > > 2 files changed, 70 insertions(+), 1 deletion(-) > > > > diff --git a/src/mesa/drivers/dri/i965/gen6_gs_visitor.cpp > > b/src/mesa/drivers/dri/i965/gen6_gs_visitor.cpp > > index 4a440eb..b45c381 100644 > > --- a/src/mesa/drivers/dri/i965/gen6_gs_visitor.cpp > > +++ b/src/mesa/drivers/dri/i965/gen6_gs_visitor.cpp > > @@ -31,6 +31,8 @@ > > > > #include "gen6_gs_visitor.h" > > > > +const unsigned MAX_GS_INPUT_VERTICES = 6; > > + > > namespace brw { > > > > void > > @@ -38,6 +40,7 @@ gen6_gs_visitor::emit_prolog() > > { > > vec4_gs_visitor::emit_prolog(); > > > > + this->current_annotation = "gen6 prolog"; > > /* Gen6 geometry shaders require to allocate an initial VUE handle via > > * FF_SYNC message, however the documentation remarks that only one > > thread > > * can write to the URB simultaneously and the FF_SYNC message provides > > the > > @@ -59,7 +62,6 @@ gen6_gs_visitor::emit_prolog() > > * flags for the next vertex come right after the data items and flags > > for > > * the previous vertex. > > */ > > - this->current_annotation = "gen6 prolog"; > > Seems like this belongs in > "i965/gen6/gs: Add initial implementation for a gen6 geometry shader visitor." > (Or, perhaps just drop the change...)
You are right, I'll fix it. Iago > Patches 21-26 (gs-support-snb-for-submission-02092014) > i965/gen6/gs: Implement support for gl_PrimitiveIdIn. > i965/gen6/gs: Assign geometry shader VUE map properly. > i965/gen6/gs: Enable texture units and upload sampler state. > i965/gen6/gs: implement GS_OPCODE_SVB_WRITE opcode > i965/gen6/gs: implement GS_OPCODE_SVB_SET_DST_INDEX opcode > i965/gen6/gs: implement GS_OPCODE_FF_SYNC_SET_PRIMITIVES opcode > Reviewed-by: Jordan Justen <jordan.l.jus...@intel.com> > > > this->vertex_output = src_reg(this, > > glsl_type::uint_type, > > (prog_data->vue_map.num_slots + 1) * > > @@ -94,6 +96,30 @@ gen6_gs_visitor::emit_prolog() > > */ > > this->prim_count = src_reg(this, glsl_type::uint_type); > > emit(MOV(dst_reg(this->prim_count), 0u)); > > + > > + /* PrimitveID is delivered in r0.1 of the thread payload. If the program > > + * needs it we have to move it to a separate register where we can map > > + * the atttribute. > > + * > > + * Notice that we cannot use a virtual register for this, because we > > need to > > + * map all input attributes to hardware registers in setup_payload(), > > + * which happens before virtual registers are mapped to hardware > > registers. > > + * We could work around that issue if we were able to compute the first > > + * non-payload register here and move the PrimitiveID information to > > that > > + * register, but we can't because at this point we don't know the final > > + * number uniforms that will be included in the payload. > > + * > > + * So, what we do is to place PrimitiveID information in r1, which is > > always > > + * delivered as part of the payload, but its only populated with data > > + * relevant for transform feedback when we set > > GEN6_GS_SVBI_PAYLOAD_ENABLE > > + * in the 3DSTATE_GS state packet. That information can be obtained by > > other > > + * means though, so we can safely use r1 for this purpose. > > + */ > > + if (c->prog_data.include_primitive_id) { > > + this->primitive_id = > > + src_reg(retype(brw_vec8_grf(1, 0), BRW_REGISTER_TYPE_UD)); > > + emit(GS_OPCODE_SET_PRIMITIVE_ID, dst_reg(this->primitive_id)); > > + } > > } > > > > void > > @@ -410,4 +436,45 @@ gen6_gs_visitor::emit_thread_end() > > inst->mlen = 1; > > } > > > > +void > > +gen6_gs_visitor::setup_payload() > > +{ > > + int attribute_map[BRW_VARYING_SLOT_COUNT * MAX_GS_INPUT_VERTICES]; > > + > > + /* Attributes are going to be interleaved, so one register contains two > > + * attribute slots. > > + */ > > + int attributes_per_reg = 2; > > + > > + /* If a geometry shader tries to read from an input that wasn't written > > by > > + * the vertex shader, that produces undefined results, but it shouldn't > > + * crash anything. So initialize attribute_map to zeros--that ensures > > that > > + * these undefined results are read from r0. > > + */ > > + memset(attribute_map, 0, sizeof(attribute_map)); > > + > > + int reg = 0; > > + > > + /* The payload always contains important data in r0. */ > > + reg++; > > + > > + /* r1 is always part of the payload and it holds information relevant > > + * for transform feedback when we set the GEN6_GS_SVBI_PAYLOAD_ENABLE > > bit in > > + * the 3DSTATE_GS packet. We will overwrite it with the PrimitiveID > > + * information (and move the original value to a virtual register if > > + * necessary). > > + */ > > + if (c->prog_data.include_primitive_id) > > + attribute_map[VARYING_SLOT_PRIMITIVE_ID] = attributes_per_reg * reg; > > + reg++; > > + > > + reg = setup_uniforms(reg); > > + > > + reg = setup_varying_inputs(reg, attribute_map, attributes_per_reg); > > + > > + lower_attributes_to_hw_regs(attribute_map, true); > > + > > + this->first_non_payload_grf = reg; > > +} > > + > > } /* namespace brw */ > > diff --git a/src/mesa/drivers/dri/i965/gen6_gs_visitor.h > > b/src/mesa/drivers/dri/i965/gen6_gs_visitor.h > > index 7af6405..8d2386c 100644 > > --- a/src/mesa/drivers/dri/i965/gen6_gs_visitor.h > > +++ b/src/mesa/drivers/dri/i965/gen6_gs_visitor.h > > @@ -52,6 +52,7 @@ protected: > > int base_mrf, > > int last_mrf, > > int urb_offset); > > + virtual void setup_payload(); > > > > private: > > src_reg vertex_output; > > @@ -59,6 +60,7 @@ private: > > src_reg temp; > > src_reg first_vertex; > > src_reg prim_count; > > + src_reg primitive_id; > > }; > > > > } /* namespace brw */ > > -- > > 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