summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/draw/draw_prim_assembler.c
diff options
context:
space:
mode:
authorZack Rusin <zackr@vmware.com>2013-08-08 15:44:10 -0400
committerZack Rusin <zackr@vmware.com>2013-08-08 20:54:25 -0400
commit662a4d4a120cb0a07023f00e3c5e4a0809428a53 (patch)
treead0d0a704411cdccb2a81ea0599209bb350f8077 /src/gallium/auxiliary/draw/draw_prim_assembler.c
parent1d425c4c6df2affd3b36b98e28357c59f7f02f58 (diff)
downloadexternal_mesa3d-662a4d4a120cb0a07023f00e3c5e4a0809428a53.tar.gz
external_mesa3d-662a4d4a120cb0a07023f00e3c5e4a0809428a53.tar.bz2
external_mesa3d-662a4d4a120cb0a07023f00e3c5e4a0809428a53.zip
draw: rewrite primitive assembler
We can't be injecting the primitive id's in the pipeline because by that time the primitives have already been decomposed. To properly number the primitives we need to handle the adjacency primitives by hand. This patch moves the prim id injection into the original primitive assembler and completely removes the useless pipeline stage. Signed-off-by: Zack Rusin <zackr@vmware.com> Reviewed-by: Roland Scheidegger <sroland@vmware.com>
Diffstat (limited to 'src/gallium/auxiliary/draw/draw_prim_assembler.c')
-rw-r--r--src/gallium/auxiliary/draw/draw_prim_assembler.c168
1 files changed, 158 insertions, 10 deletions
diff --git a/src/gallium/auxiliary/draw/draw_prim_assembler.c b/src/gallium/auxiliary/draw/draw_prim_assembler.c
index 9bedeeadb4..eba441c17a 100644
--- a/src/gallium/auxiliary/draw/draw_prim_assembler.c
+++ b/src/gallium/auxiliary/draw/draw_prim_assembler.c
@@ -27,6 +27,9 @@
#include "draw_prim_assembler.h"
+#include "draw_fs.h"
+#include "draw_gs.h"
+
#include "util/u_debug.h"
#include "util/u_memory.h"
#include "util/u_prim.h"
@@ -42,8 +45,28 @@ struct draw_assembler
const struct draw_prim_info *input_prims;
const struct draw_vertex_info *input_verts;
+
+ boolean needs_primid;
+ int primid_slot;
+ unsigned primid;
+
+ boolean is_strip;
+ boolean is_first_prim;
+ unsigned num_prims;
};
+
+static boolean
+needs_primid(const struct draw_context *draw)
+{
+ const struct draw_fragment_shader *fs = draw->fs.fragment_shader;
+ const struct draw_geometry_shader *gs = draw->gs.geometry_shader;
+ if (fs && fs->info.uses_primid) {
+ return !gs || !gs->info.uses_primid;
+ }
+ return FALSE;
+}
+
boolean
draw_prim_assembler_is_required(const struct draw_context *draw,
const struct draw_prim_info *prim_info,
@@ -56,7 +79,7 @@ draw_prim_assembler_is_required(const struct draw_context *draw,
case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
return TRUE;
default:
- return FALSE;
+ return needs_primid(draw);
}
}
@@ -84,16 +107,43 @@ copy_verts(struct draw_assembler *asmblr,
asmblr->input_verts->vertex_size);
asmblr->output_verts->count += 1;
}
+ ++asmblr->num_prims;
+}
+
+
+static void
+inject_primid(struct draw_assembler *asmblr,
+ unsigned idx,
+ unsigned primid)
+{
+ int slot = asmblr->primid_slot;
+ char *input = (char*)asmblr->input_verts->verts;
+ unsigned input_offset = asmblr->input_verts->stride * idx;
+ struct vertex_header *v = (struct vertex_header*)(input + input_offset);
+
+ /* In case the backend doesn't care about it */
+ if (slot < 0) {
+ return;
+ }
+
+ memcpy(&v->data[slot][0], &primid, sizeof(primid));
+ memcpy(&v->data[slot][1], &primid, sizeof(primid));
+ memcpy(&v->data[slot][2], &primid, sizeof(primid));
+ memcpy(&v->data[slot][3], &primid, sizeof(primid));
}
+
static void
prim_point(struct draw_assembler *asmblr,
unsigned idx)
{
unsigned indices[1];
+ if (asmblr->needs_primid) {
+ inject_primid(asmblr, idx, asmblr->primid++);
+ }
indices[0] = idx;
-
+
copy_verts(asmblr, indices, 1);
}
@@ -103,6 +153,18 @@ prim_line(struct draw_assembler *asmblr,
{
unsigned indices[2];
+ if (asmblr->needs_primid) {
+ if (asmblr->is_strip && asmblr->is_first_prim) {
+ inject_primid(asmblr, i0, asmblr->primid++);
+ inject_primid(asmblr, i1, asmblr->primid++);
+ asmblr->is_first_prim = FALSE;
+ } else if (asmblr->is_strip) {
+ inject_primid(asmblr, i1, asmblr->primid++);
+ } else {
+ inject_primid(asmblr, i0, asmblr->primid);
+ inject_primid(asmblr, i1, asmblr->primid++);
+ }
+ }
indices[0] = i0;
indices[1] = i1;
@@ -115,6 +177,19 @@ prim_line_adj(struct draw_assembler *asmblr,
{
unsigned indices[2];
+ if (asmblr->needs_primid) {
+ if (asmblr->is_strip && asmblr->is_first_prim) {
+ inject_primid(asmblr, i1, asmblr->primid++);
+ inject_primid(asmblr, i2, asmblr->primid++);
+ asmblr->is_first_prim = FALSE;
+ } else if (asmblr->is_strip) {
+ inject_primid(asmblr, i2, asmblr->primid++);
+ } else {
+ inject_primid(asmblr, i1, asmblr->primid);
+ inject_primid(asmblr, i2, asmblr->primid++);
+ }
+ }
+
indices[0] = i1;
indices[1] = i2;
@@ -127,6 +202,24 @@ prim_tri(struct draw_assembler *asmblr,
{
unsigned indices[3];
+ if (asmblr->needs_primid) {
+ if (asmblr->is_strip && asmblr->is_first_prim) {
+ inject_primid(asmblr, i0, asmblr->primid++);
+ inject_primid(asmblr, i1, asmblr->primid++);
+ inject_primid(asmblr, i2, asmblr->primid++);
+ asmblr->is_first_prim = FALSE;
+ } else if (asmblr->is_strip) {
+ if (asmblr->num_prims & 1) {
+ inject_primid(asmblr, i1, asmblr->primid++);
+ } else {
+ inject_primid(asmblr, i2, asmblr->primid++);
+ }
+ } else {
+ inject_primid(asmblr, i0, asmblr->primid);
+ inject_primid(asmblr, i1, asmblr->primid);
+ inject_primid(asmblr, i2, asmblr->primid++);
+ }
+ }
indices[0] = i0;
indices[1] = i1;
indices[2] = i2;
@@ -141,6 +234,25 @@ prim_tri_adj(struct draw_assembler *asmblr,
{
unsigned indices[3];
+ if (asmblr->needs_primid) {
+ if (asmblr->is_strip && asmblr->is_first_prim) {
+ inject_primid(asmblr, i0, asmblr->primid++);
+ inject_primid(asmblr, i2, asmblr->primid++);
+ inject_primid(asmblr, i4, asmblr->primid++);
+ asmblr->is_first_prim = FALSE;
+ } else if (asmblr->is_strip) {
+ if (asmblr->num_prims & 1) {
+ inject_primid(asmblr, i2, asmblr->primid++);
+ } else {
+ inject_primid(asmblr, i4, asmblr->primid++);
+ }
+ } else {
+ inject_primid(asmblr, i0, asmblr->primid);
+ inject_primid(asmblr, i2, asmblr->primid);
+ inject_primid(asmblr, i4, asmblr->primid);
+ asmblr->primid++;
+ }
+ }
indices[0] = i0;
indices[1] = i2;
indices[2] = i4;
@@ -148,6 +260,18 @@ prim_tri_adj(struct draw_assembler *asmblr,
copy_verts(asmblr, indices, 3);
}
+void
+draw_prim_assembler_prepare_outputs(struct draw_assembler *ia)
+{
+ struct draw_context *draw = ia->draw;
+ if (needs_primid(draw)) {
+ ia->primid_slot = draw_alloc_extra_vertex_attrib(
+ ia->draw, TGSI_SEMANTIC_PRIMID, 0);
+ } else {
+ ia->primid_slot = -1;
+ }
+ ia->primid = 0;
+}
#define FUNC assembler_run_linear
@@ -178,18 +302,26 @@ draw_prim_assembler_run(struct draw_context *draw,
struct draw_prim_info *output_prims,
struct draw_vertex_info *output_verts)
{
- struct draw_assembler asmblr;
+ struct draw_assembler *asmblr = draw->ia;
unsigned start, i;
unsigned assembled_prim = u_assembled_prim(input_prims->prim);
unsigned max_primitives = u_decomposed_prims_for_vertices(
input_prims->prim, input_prims->count);
unsigned max_verts = u_vertices_per_prim(assembled_prim) * max_primitives;
- asmblr.draw = draw;
- asmblr.output_prims = output_prims;
- asmblr.output_verts = output_verts;
- asmblr.input_prims = input_prims;
- asmblr.input_verts = input_verts;
+ asmblr->output_prims = output_prims;
+ asmblr->output_verts = output_verts;
+ asmblr->input_prims = input_prims;
+ asmblr->input_verts = input_verts;
+ asmblr->is_strip =
+ (input_prims->prim == PIPE_PRIM_TRIANGLE_STRIP ||
+ input_prims->prim == PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY) ||
+ (input_prims->prim == PIPE_PRIM_LINE_STRIP ||
+ input_prims->prim == PIPE_PRIM_LINE_STRIP_ADJACENCY);
+ asmblr->needs_primid = needs_primid(asmblr->draw);
+ asmblr->is_first_prim = asmblr->is_strip;
+ asmblr->primid = 0;
+ asmblr->num_prims = 0;
output_prims->linear = TRUE;
output_prims->elts = NULL;
@@ -212,10 +344,10 @@ draw_prim_assembler_run(struct draw_context *draw,
{
unsigned count = input_prims->primitive_lengths[i];
if (input_prims->linear) {
- assembler_run_linear(&asmblr, input_prims, input_verts,
+ assembler_run_linear(asmblr, input_prims, input_verts,
start, count);
} else {
- assembler_run_elts(&asmblr, input_prims, input_verts,
+ assembler_run_elts(asmblr, input_prims, input_verts,
start, count);
}
}
@@ -223,3 +355,19 @@ draw_prim_assembler_run(struct draw_context *draw,
output_prims->primitive_lengths[0] = output_verts->count;
output_prims->count = output_verts->count;
}
+
+struct draw_assembler *
+draw_prim_assembler_create(struct draw_context *draw)
+{
+ struct draw_assembler *ia = CALLOC_STRUCT( draw_assembler );
+
+ ia->draw = draw;
+
+ return ia;
+}
+
+void
+draw_prim_assembler_destroy(struct draw_assembler *ia)
+{
+ FREE(ia);
+}