[Mesa-dev] [PATCH 19/30] i965/gs: add GS visitors.

Paul Berry stereotype441 at gmail.com
Thu Aug 22 08:22:28 PDT 2013


On 20 August 2013 11:30, Paul Berry <stereotype441 at gmail.com> wrote:

> +int
> +vec4_gs_visitor::setup_varying_inputs(int payload_reg, int *attribute_map)
> +{
> +   /* For geometry shaders there are N copies of the input attributes,
> where N
> +    * is the number of input vertices.
>  attribute_map[BRW_VARYING_SLOT_COUNT *
> +    * i + j] represents attribute j for vertex i.
> +    *
> +    * Note that GS inputs are read from the VUE 256 bits (2 vec4's) at a
> time,
> +    * so the total number of input slots that will be delivered to the GS
> (and
> +    * thus the stride of the input arrays) is urb_read_length * 2.
> +    */
> +   unsigned num_input_vertices = c->gp->program.VerticesIn;
>

>From our in-person code review yesterday:

num_input_vertices should be const.


> +   assert(num_input_vertices <= MAX_GS_INPUT_VERTICES);
> +   unsigned input_array_stride = c->prog_data.base.urb_read_length * 2;
> +
> +   for (int slot = 0; slot < c->key.input_vue_map.num_slots; slot++) {
> +      int varying = c->key.input_vue_map.slot_to_varying[slot];
> +      for (unsigned vertex = 0; vertex < num_input_vertices; vertex++) {
> +         attribute_map[BRW_VARYING_SLOT_COUNT * vertex + varying] =
> +            payload_reg + input_array_stride * vertex + slot;
> +      }
> +   }
> +
> +   return payload_reg + input_array_stride * num_input_vertices;
> +}
> +
> +
> +void
> +vec4_gs_visitor::setup_payload()
> +{
> +   int attribute_map[BRW_VARYING_SLOT_COUNT * MAX_GS_INPUT_VERTICES];
> +
> +   /* 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 g0, which contains
> +    * the URB handles that are passed on to the URB write at the end
> +    * of the thread.
> +    */
>

>From our in-person code review yesterday:

We decided to try to start consistently using "r" rather than "g" to refer
to these registers, since the PRMs use "r".


> +   reg++;
> +
> +   reg = setup_uniforms(reg);
> +
> +   reg = setup_varying_inputs(reg, attribute_map);
> +
> +   lower_attributes_to_hw_regs(attribute_map);
> +
> +   this->first_non_payload_grf = reg;
> +}
> +
> +
> +void
> +vec4_gs_visitor::emit_urb_write_header(int mrf)
> +{
> +   /* The SEND instruction that writes the vertex data to the VUE will use
> +    * per_slot_offset=true, which means that DWORDs 3 and 4 of the message
> +    * header specify an offset (in multiples of 256 bits) into the URB
> entry
> +    * at which the write should take place.
> +    *
> +    * So we have to prepare a message header with the apropriate offset
> +    * values.
>

>From our in-person code review yesterday:

s/apropriate/appropriate/


> +    */
> +   dst_reg mrf_reg(MRF, mrf);
> +   src_reg r0(retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD));
> +   this->current_annotation = "URB write header";
> +   vec4_instruction *inst = emit(MOV(mrf_reg, r0));
> +   inst->force_writemask_all = true;
> +   emit(GS_OPCODE_SET_WRITE_OFFSET, mrf_reg, this->vertex_count,
> +        (uint32_t) c->prog_data.output_vertex_size_hwords);
> +}
> +
> +
> +void
> +vec4_gs_visitor::visit(ir_emit_vertex *)
> +{
> +   this->current_annotation = "emit vertex: safety check";
> +
> +   /* To ensure that the vertex counter doesn't get too big, do the logic
> +    * inside a conditional of the form "if (vertex_count < MAX)"
>

>From our in-person code review yesterday:

Instead of "To ensure that the vertex counter doesn't get too big", say
something like "To ensure that we don't output more vertices than the
shader specified using max_vertices"


> +    */
> +   unsigned num_output_vertices = c->gp->program.VerticesOut;
> +   emit(CMP(dst_null_d(), this->vertex_count,
> +            src_reg(num_output_vertices), BRW_CONDITIONAL_L));
> +   emit(IF(BRW_PREDICATE_NORMAL));
> +
> +   this->current_annotation = "emit vertex: vertex data";
> +   emit_vertex();
> +
> +   this->current_annotation = "emit vertex: increment vertex count";
> +   emit(ADD(dst_reg(this->vertex_count), this->vertex_count,
> +            src_reg(1u)));
> +
> +   emit(BRW_OPCODE_ENDIF);
>

>From our in-person code review yesterday:

Add '{' after emit(IF(...)) and '}' before emit(...ENDIF) so that the
conditional code will be indented, as we do in the fixed-function back ends
(e.g. the Gen4-5 clipper).


> +
> +   this->current_annotation = NULL;
> +}
> +
> +void
> +vec4_gs_visitor::visit(ir_end_primitive *)
> +{
> +   assert(!"Not implemented yet");
> +}
> +
> +
> +} /* namespace brw */
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20130822/393dba95/attachment.html>


More information about the mesa-dev mailing list