diff options
Diffstat (limited to 'src/gallium/auxiliary/draw/draw_pt_so_emit.c')
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_so_emit.c | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/src/gallium/auxiliary/draw/draw_pt_so_emit.c b/src/gallium/auxiliary/draw/draw_pt_so_emit.c index 80a164a0d7d..13d8470e4ec 100644 --- a/src/gallium/auxiliary/draw/draw_pt_so_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_so_emit.c @@ -42,20 +42,24 @@ struct pt_so_emit { unsigned input_vertex_stride; const float (*inputs)[4]; - + const float (*pre_clip_pos)[4]; boolean has_so; - + boolean use_pre_clip_pos; + int pos_idx; unsigned emitted_primitives; unsigned emitted_vertices; unsigned generated_primitives; }; -void draw_pt_so_emit_prepare(struct pt_so_emit *emit) +void draw_pt_so_emit_prepare(struct pt_so_emit *emit, boolean use_pre_clip_pos) { struct draw_context *draw = emit->draw; + emit->use_pre_clip_pos = use_pre_clip_pos; emit->has_so = (draw->vs.vertex_shader->state.stream_output.num_outputs > 0); + if (use_pre_clip_pos) + emit->pos_idx = draw_current_shader_position_output(draw); /* if we have a state with outputs make sure we have * buffers to output to */ @@ -87,12 +91,15 @@ static void so_emit_prim(struct pt_so_emit *so, unsigned input_vertex_stride = so->input_vertex_stride; struct draw_context *draw = so->draw; const float (*input_ptr)[4]; + const float (*pcp_ptr)[4] = NULL; const struct pipe_stream_output_info *state = &draw->vs.vertex_shader->state.stream_output; float *buffer; int buffer_total_bytes[PIPE_MAX_SO_BUFFERS]; input_ptr = so->inputs; + if (so->use_pre_clip_pos) + pcp_ptr = so->pre_clip_pos; ++so->generated_primitives; @@ -117,12 +124,17 @@ static void so_emit_prim(struct pt_so_emit *so, for (i = 0; i < num_vertices; ++i) { const float (*input)[4]; + const float (*pre_clip_pos)[4]; unsigned total_written_compos = 0; int ob; /*debug_printf("%d) vertex index = %d (prim idx = %d)\n", i, indices[i], prim_idx);*/ input = (const float (*)[4])( (const char *)input_ptr + (indices[i] * input_vertex_stride)); + if (pcp_ptr) + pre_clip_pos = (const float (*)[4])( + (const char *)pcp_ptr + (indices[i] * input_vertex_stride)); + for (slot = 0; slot < state->num_outputs; ++slot) { unsigned idx = state->output[slot].register_index; unsigned start_comp = state->output[slot].start_component; @@ -133,7 +145,10 @@ static void so_emit_prim(struct pt_so_emit *so, buffer = (float *)((char *)draw->so.targets[ob]->mapping + draw->so.targets[ob]->target.buffer_offset + draw->so.targets[ob]->internal_offset) + state->output[slot].dst_offset; - memcpy(buffer, &input[idx][start_comp], num_comps * sizeof(float)); + if (idx == so->pos_idx && pcp_ptr) + memcpy(buffer, &pre_clip_pos[start_comp], num_comps * sizeof(float)); + else + memcpy(buffer, &input[idx][start_comp], num_comps * sizeof(float)); total_written_compos += num_comps; } for (ob = 0; ob < draw->so.num_targets; ++ob) @@ -203,6 +218,9 @@ void draw_pt_so_emit( struct pt_so_emit *emit, emit->emitted_primitives = 0; emit->generated_primitives = 0; emit->input_vertex_stride = input_verts->stride; + if (emit->use_pre_clip_pos) + emit->pre_clip_pos = (const float (*)[4])input_verts->verts->pre_clip_pos; + emit->inputs = (const float (*)[4])input_verts->verts->data; /* XXX: need to flush to get prim_vbuf.c to release its allocation??*/ |