<div dir="ltr">On 20 August 2013 11:30, Paul Berry <span dir="ltr"><<a href="mailto:stereotype441@gmail.com" target="_blank">stereotype441@gmail.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">+int<br>
+vec4_gs_visitor::setup_varying_inputs(int payload_reg, int *attribute_map)<br>
+{<br>
+ /* For geometry shaders there are N copies of the input attributes, where N<br>
+ * is the number of input vertices. attribute_map[BRW_VARYING_SLOT_COUNT *<br>
+ * i + j] represents attribute j for vertex i.<br>
+ *<br>
+ * Note that GS inputs are read from the VUE 256 bits (2 vec4's) at a time,<br>
+ * so the total number of input slots that will be delivered to the GS (and<br>
+ * thus the stride of the input arrays) is urb_read_length * 2.<br>
+ */<br>
+ unsigned num_input_vertices = c->gp->program.VerticesIn;<br></blockquote><div><br>From our in-person code review yesterday:<br><br></div><div>num_input_vertices should be const.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+ assert(num_input_vertices <= MAX_GS_INPUT_VERTICES);<br>
+ unsigned input_array_stride = c->prog_data.base.urb_read_length * 2;<br>
+<br>
+ for (int slot = 0; slot < c->key.input_vue_map.num_slots; slot++) {<br>
+ int varying = c->key.input_vue_map.slot_to_varying[slot];<br>
+ for (unsigned vertex = 0; vertex < num_input_vertices; vertex++) {<br>
+ attribute_map[BRW_VARYING_SLOT_COUNT * vertex + varying] =<br>
+ payload_reg + input_array_stride * vertex + slot;<br>
+ }<br>
+ }<br>
+<br>
+ return payload_reg + input_array_stride * num_input_vertices;<br>
+}<br>
+<br>
+<br>
+void<br>
+vec4_gs_visitor::setup_payload()<br>
+{<br>
+ int attribute_map[BRW_VARYING_SLOT_COUNT * MAX_GS_INPUT_VERTICES];<br>
+<br>
+ /* If a geometry shader tries to read from an input that wasn't written by<br>
+ * the vertex shader, that produces undefined results, but it shouldn't<br>
+ * crash anything. So initialize attribute_map to zeros--that ensures that<br>
+ * these undefined results are read from r0.<br>
+ */<br>
+ memset(attribute_map, 0, sizeof(attribute_map));<br>
+<br>
+ int reg = 0;<br>
+<br>
+ /* The payload always contains important data in g0, which contains<br>
+ * the URB handles that are passed on to the URB write at the end<br>
+ * of the thread.<br>
+ */<br></blockquote><div><br>From our in-person code review yesterday:<br><br></div><div>We decided to try to start consistently using "r" rather than "g" to refer to these registers, since the PRMs use "r".<br>
</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+ reg++;<br>
+<br>
+ reg = setup_uniforms(reg);<br>
+<br>
+ reg = setup_varying_inputs(reg, attribute_map);<br>
+<br>
+ lower_attributes_to_hw_regs(attribute_map);<br>
+<br>
+ this->first_non_payload_grf = reg;<br>
+}<br>
+<br>
+<br>
+void<br>
+vec4_gs_visitor::emit_urb_write_header(int mrf)<br>
+{<br>
+ /* The SEND instruction that writes the vertex data to the VUE will use<br>
+ * per_slot_offset=true, which means that DWORDs 3 and 4 of the message<br>
+ * header specify an offset (in multiples of 256 bits) into the URB entry<br>
+ * at which the write should take place.<br>
+ *<br>
+ * So we have to prepare a message header with the apropriate offset<br>
+ * values.<br></blockquote><div><br>From our in-person code review yesterday:<br><br></div><div>s/apropriate/appropriate/<br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+ */<br>
+ dst_reg mrf_reg(MRF, mrf);<br>
+ src_reg r0(retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD));<br>
+ this->current_annotation = "URB write header";<br>
+ vec4_instruction *inst = emit(MOV(mrf_reg, r0));<br>
+ inst->force_writemask_all = true;<br>
+ emit(GS_OPCODE_SET_WRITE_OFFSET, mrf_reg, this->vertex_count,<br>
+ (uint32_t) c->prog_data.output_vertex_size_hwords);<br>
+}<br>
+<br>
+<br>
+void<br>
+vec4_gs_visitor::visit(ir_emit_vertex *)<br>
+{<br>
+ this->current_annotation = "emit vertex: safety check";<br>
+<br>
+ /* To ensure that the vertex counter doesn't get too big, do the logic<br>
+ * inside a conditional of the form "if (vertex_count < MAX)"<br></blockquote><div><br>From our in-person code review yesterday:<br><br></div><div>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"<br>
</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+ */<br>
+ unsigned num_output_vertices = c->gp->program.VerticesOut;<br>
+ emit(CMP(dst_null_d(), this->vertex_count,<br>
+ src_reg(num_output_vertices), BRW_CONDITIONAL_L));<br>
+ emit(IF(BRW_PREDICATE_NORMAL));<br>
+<br>
+ this->current_annotation = "emit vertex: vertex data";<br>
+ emit_vertex();<br>
+<br>
+ this->current_annotation = "emit vertex: increment vertex count";<br>
+ emit(ADD(dst_reg(this->vertex_count), this->vertex_count,<br>
+ src_reg(1u)));<br>
+<br>
+ emit(BRW_OPCODE_ENDIF);<br></blockquote><div><br>From our in-person code review yesterday:<br><br></div><div>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).<br>
</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+ this->current_annotation = NULL;<br>
+}<br>
+<br>
+void<br>
+vec4_gs_visitor::visit(ir_end_primitive *)<br>
+{<br>
+ assert(!"Not implemented yet");<br>
+}<br>
+<br>
+<br>
+} /* namespace brw */<br></blockquote></div></div></div>