[Mesa-dev] [PATCH 30/37] i965/gen6/gs: Buffer PSIZ/flags vertex data in gen6_gs_visitor
Jordan Justen
jljusten at gmail.com
Thu Sep 18 16:59:33 PDT 2014
Reviewed-by: Jordan Justen <jordan.l.justen at intel.com>
On Thu, Aug 14, 2014 at 4:12 AM, Iago Toral Quiroga <itoral at igalia.com> wrote:
> From: Samuel Iglesias Gonsalvez <siglesias at igalia.com>
>
> Since geometry shaders can alter the value of varyings packed in the first
> output VUE slot (PSIZ), we need to buffer it together with all the other
> vertex data so we can emit the right value for each vertex when we do the
> URB writes.
>
> This fixes the following piglit test in gen6:
> tests/spec/glsl-1.50/execution/redeclare-pervertex-out-subset-gs.shader_test
>
> Signed-off-by: Samuel Iglesias Gonsalvez <siglesias at igalia.com>
> ---
> src/mesa/drivers/dri/i965/gen6_gs_visitor.cpp | 79 ++++++++++++++-------------
> 1 file changed, 41 insertions(+), 38 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/i965/gen6_gs_visitor.cpp b/src/mesa/drivers/dri/i965/gen6_gs_visitor.cpp
> index b8eaa58..fca7536 100644
> --- a/src/mesa/drivers/dri/i965/gen6_gs_visitor.cpp
> +++ b/src/mesa/drivers/dri/i965/gen6_gs_visitor.cpp
> @@ -178,16 +178,33 @@ gen6_gs_visitor::visit(ir_emit_vertex *)
>
> /* Buffer all output slots for this vertex in vertex_output */
> for (int slot = 0; slot < prog_data->vue_map.num_slots; ++slot) {
> - /* We will handle PSIZ for each vertex at thread end time since it
> - * is not computed by the GS algorithm and requires specific handling.
> - */
> int varying = prog_data->vue_map.slot_to_varying[slot];
> if (varying != VARYING_SLOT_PSIZ) {
> dst_reg dst(this->vertex_output);
> dst.reladdr = ralloc(mem_ctx, src_reg);
> memcpy(dst.reladdr, &this->vertex_output_offset, sizeof(src_reg));
> emit_urb_slot(dst, varying);
> + } else {
> + /* The PSIZ slot can pack multiple varyings in different channels
> + * and emit_urb_slot() will produce a MOV instruction for each of
> + * them. Since we are writing to an array, that will translate to
> + * possibly multiple MOV instructions with an array destination and
> + * each will generate a scratch write with the same offset into
> + * scratch space (thus, each one overwriting the previous). This is
> + * not what we want. What we will do instead is emit PSIZ to a
> + * a regular temporary register, then move that resgister into the
> + * array. This way we only have one instruction with an array
> + * destination and we only produce a single scratch write.
> + */
> + dst_reg tmp = dst_reg(src_reg(this, glsl_type::uvec4_type));
> + emit_urb_slot(tmp, varying);
> + dst_reg dst(this->vertex_output);
> + dst.reladdr = ralloc(mem_ctx, src_reg);
> + memcpy(dst.reladdr, &this->vertex_output_offset, sizeof(src_reg));
> + vec4_instruction *inst = emit(MOV(dst, src_reg(tmp)));
> + inst->force_writemask_all = true;
> }
> +
> emit(ADD(dst_reg(this->vertex_output_offset),
> this->vertex_output_offset, 1u));
> }
> @@ -427,17 +444,12 @@ gen6_gs_visitor::emit_thread_end()
> memcpy(data.reladdr, &this->vertex_output_offset,
> sizeof(src_reg));
>
> - if (varying == VARYING_SLOT_PSIZ) {
> - /* We did not buffer PSIZ, emit it directly here */
> - emit_urb_slot(dst_reg(MRF, mrf), varying);
> - } else {
> - /* Copy this slot to the appropriate message register */
> - dst_reg reg = dst_reg(MRF, mrf);
> - reg.type = output_reg[varying].type;
> - data.type = reg.type;
> - vec4_instruction *inst = emit(MOV(reg, data));
> - inst->force_writemask_all = true;
> - }
> + /* Copy this slot to the appropriate message register */
> + dst_reg reg = dst_reg(MRF, mrf);
> + reg.type = output_reg[varying].type;
> + data.type = reg.type;
> + vec4_instruction *inst = emit(MOV(reg, data));
> + inst->force_writemask_all = true;
>
> mrf++;
> emit(ADD(dst_reg(this->vertex_output_offset),
> @@ -585,22 +597,19 @@ gen6_gs_visitor::xfb_buffer_output()
> /* Buffer all TF outputs for this vertex in xfb_output */
> for (int binding = 0; binding < prog_data->num_transform_feedback_bindings;
> binding++) {
> - /* We will handle PSIZ for each vertex at thread end time since it
> - * is not computed by the GS algorithm and requires specific handling.
> - */
> unsigned varying =
> prog_data->transform_feedback_bindings[binding];
> - if (varying != VARYING_SLOT_PSIZ) {
> - dst_reg dst(this->xfb_output);
> - dst.reladdr = ralloc(mem_ctx, src_reg);
> - memcpy(dst.reladdr, &this->xfb_output_offset, sizeof(src_reg));
> - dst.type = output_reg[varying].type;
> + dst_reg dst(this->xfb_output);
> + dst.reladdr = ralloc(mem_ctx, src_reg);
> + memcpy(dst.reladdr, &this->xfb_output_offset, sizeof(src_reg));
> + dst.type = output_reg[varying].type;
> +
> + this->current_annotation = output_reg_annotation[varying];
> + src_reg out_reg = src_reg(output_reg[varying]);
> + out_reg.swizzle = varying == VARYING_SLOT_PSIZ
> + ? BRW_SWIZZLE_WWWW : prog_data->transform_feedback_swizzles[binding];
> + emit(MOV(dst, out_reg));
>
> - this->current_annotation = output_reg_annotation[varying];
> - src_reg out_reg = src_reg(output_reg[varying]);
> - out_reg.swizzle = prog_data->transform_feedback_swizzles[binding];
> - emit(MOV(dst, out_reg));
> - }
> emit(ADD(dst_reg(this->xfb_output_offset), this->xfb_output_offset, 1u));
> }
> }
> @@ -742,18 +751,12 @@ gen6_gs_visitor::xfb_program(unsigned num_verts)
> src_reg out_reg;
> this->current_annotation = output_reg_annotation[varying];
>
> - if (varying == VARYING_SLOT_PSIZ) {
> - /* We did not buffer PSIZ, emit it directly here */
> - out_reg = src_reg(output_reg[varying]);
> - out_reg.swizzle = BRW_SWIZZLE_WWWW;
> - } else {
> - /* Copy this varying to the appropriate message register */
> - out_reg = src_reg(this, glsl_type::uvec4_type);
> - out_reg.type = output_reg[varying].type;
> + /* Copy this varying to the appropriate message register */
> + out_reg = src_reg(this, glsl_type::uvec4_type);
> + out_reg.type = output_reg[varying].type;
>
> - data.type = output_reg[varying].type;
> - emit(MOV(dst_reg(out_reg), data));
> - }
> + data.type = output_reg[varying].type;
> + emit(MOV(dst_reg(out_reg), data));
>
> /* Write data and send SVB Write */
> inst = emit(GS_OPCODE_SVB_WRITE, mrf_reg, out_reg, this->sol_temp);
> --
> 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