summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/draw
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary/draw')
-rw-r--r--src/gallium/auxiliary/draw/draw_context.c11
-rw-r--r--src/gallium/auxiliary/draw/draw_decompose_tmp.h425
-rw-r--r--src/gallium/auxiliary/draw/draw_gs.c42
-rw-r--r--src/gallium/auxiliary/draw/draw_gs.h3
-rw-r--r--src/gallium/auxiliary/draw/draw_gs_tmp.h186
-rw-r--r--src/gallium/auxiliary/draw/draw_llvm.c24
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe.c206
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_clip.c40
-rw-r--r--src/gallium/auxiliary/draw/draw_private.h7
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.c20
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_decompose.h199
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_emit.c1
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c4
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c3
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_so_emit.c20
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_util.c6
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h7
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_vcache.c157
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h209
-rw-r--r--src/gallium/auxiliary/draw/draw_so_emit_tmp.h156
-rw-r--r--src/gallium/auxiliary/draw/draw_vertex.h2
-rw-r--r--src/gallium/auxiliary/draw/draw_vs.c16
-rw-r--r--src/gallium/auxiliary/draw/draw_vs.h3
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_exec.c8
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_llvm.c1
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_sse.c1
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_varient.c6
27 files changed, 825 insertions, 938 deletions
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index c127f741881..995b675b9a1 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -288,12 +288,19 @@ draw_set_mapped_constant_buffer(struct draw_context *draw,
shader_type == PIPE_SHADER_GEOMETRY);
debug_assert(slot < PIPE_MAX_CONSTANT_BUFFERS);
- if (shader_type == PIPE_SHADER_VERTEX) {
+ switch (shader_type) {
+ case PIPE_SHADER_VERTEX:
draw->pt.user.vs_constants[slot] = buffer;
+ draw->pt.user.vs_constants_size[slot] = size;
draw_vs_set_constants(draw, slot, buffer, size);
- } else if (shader_type == PIPE_SHADER_GEOMETRY) {
+ break;
+ case PIPE_SHADER_GEOMETRY:
draw->pt.user.gs_constants[slot] = buffer;
+ draw->pt.user.gs_constants_size[slot] = size;
draw_gs_set_constants(draw, slot, buffer, size);
+ break;
+ default:
+ assert(0 && "invalid shader type in draw_set_mapped_constant_buffer");
}
}
diff --git a/src/gallium/auxiliary/draw/draw_decompose_tmp.h b/src/gallium/auxiliary/draw/draw_decompose_tmp.h
new file mode 100644
index 00000000000..a52d2b50588
--- /dev/null
+++ b/src/gallium/auxiliary/draw/draw_decompose_tmp.h
@@ -0,0 +1,425 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Keith Whitwell <[email protected]>
+ * Chia-I Wu <[email protected]>
+ */
+
+/* these macros are optional */
+#ifndef LOCAL_VARS
+#define LOCAL_VARS
+#endif
+#ifndef FUNC_ENTER
+#define FUNC_ENTER do {} while (0)
+#endif
+#ifndef FUNC_EXIT
+#define FUNC_EXIT do {} while (0)
+#endif
+#ifndef LINE_ADJ
+#define LINE_ADJ(flags, a0, i0, i1, a1) LINE(flags, i0, i1)
+#endif
+#ifndef TRIANGLE_ADJ
+#define TRIANGLE_ADJ(flags, i0, a0, i1, a1, i2, a2) TRIANGLE(flags, i0, i1, i2)
+#endif
+
+static void
+FUNC(FUNC_VARS)
+{
+ unsigned idx[6], i;
+ ushort flags;
+ LOCAL_VARS
+
+ FUNC_ENTER;
+
+ /* prim, count, and last_vertex_last should have been defined */
+ if (0) {
+ debug_printf("%s: prim 0x%x, count %d, last_vertex_last %d\n",
+ __FUNCTION__, prim, count, last_vertex_last);
+ }
+
+ switch (prim) {
+ case PIPE_PRIM_POINTS:
+ for (i = 0; i < count; i++) {
+ idx[0] = GET_ELT(i);
+ POINT(idx[0]);
+ }
+ break;
+
+ case PIPE_PRIM_LINES:
+ flags = DRAW_PIPE_RESET_STIPPLE;
+ for (i = 0; i + 1 < count; i += 2) {
+ idx[0] = GET_ELT(i);
+ idx[1] = GET_ELT(i + 1);
+ LINE(flags, idx[0], idx[1]);
+ }
+ break;
+
+ case PIPE_PRIM_LINE_LOOP:
+ case PIPE_PRIM_LINE_STRIP:
+ if (count >= 2) {
+ flags = DRAW_PIPE_RESET_STIPPLE;
+ idx[1] = GET_ELT(0);
+ idx[2] = idx[1];
+
+ for (i = 1; i < count; i++, flags = 0) {
+ idx[0] = idx[1];
+ idx[1] = GET_ELT(i);
+ LINE(flags, idx[0], idx[1]);
+ }
+ /* close the loop */
+ if (prim == PIPE_PRIM_LINE_LOOP)
+ LINE(flags, idx[1], idx[2]);
+ }
+ break;
+
+ case PIPE_PRIM_TRIANGLES:
+ flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;
+ for (i = 0; i + 2 < count; i += 3) {
+ idx[0] = GET_ELT(i);
+ idx[1] = GET_ELT(i + 1);
+ idx[2] = GET_ELT(i + 2);
+ TRIANGLE(flags, idx[0], idx[1], idx[2]);
+ }
+ break;
+
+ case PIPE_PRIM_TRIANGLE_STRIP:
+ if (count >= 3) {
+ flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;
+ idx[1] = GET_ELT(0);
+ idx[2] = GET_ELT(1);
+
+ if (last_vertex_last) {
+ for (i = 0; i + 2 < count; i++) {
+ idx[0] = idx[1];
+ idx[1] = idx[2];
+ idx[2] = GET_ELT(i + 2);
+ /* always emit idx[2] last */
+ if (i & 1)
+ TRIANGLE(flags, idx[1], idx[0], idx[2]);
+ else
+ TRIANGLE(flags, idx[0], idx[1], idx[2]);
+ }
+ }
+ else {
+ for (i = 0; i + 2 < count; i++) {
+ idx[0] = idx[1];
+ idx[1] = idx[2];
+ idx[2] = GET_ELT(i + 2);
+ /* always emit idx[0] first */
+ if (i & 1)
+ TRIANGLE(flags, idx[0], idx[2], idx[1]);
+ else
+ TRIANGLE(flags, idx[0], idx[1], idx[2]);
+ }
+ }
+ }
+ break;
+
+ case PIPE_PRIM_TRIANGLE_FAN:
+ if (count >= 3) {
+ flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;
+ idx[0] = GET_ELT(0);
+ idx[2] = GET_ELT(1);
+
+ /* idx[0] is neither the first nor the last vertex */
+ if (last_vertex_last) {
+ for (i = 0; i + 2 < count; i++) {
+ idx[1] = idx[2];
+ idx[2] = GET_ELT(i + 2);
+ /* always emit idx[2] last */
+ TRIANGLE(flags, idx[0], idx[1], idx[2]);
+ }
+ }
+ else {
+ for (i = 0; i + 2 < count; i++) {
+ idx[1] = idx[2];
+ idx[2] = GET_ELT(i + 2);
+ /* always emit idx[1] first */
+ TRIANGLE(flags, idx[1], idx[2], idx[0]);
+ }
+ }
+ }
+ break;
+
+ case PIPE_PRIM_QUADS:
+ if (last_vertex_last) {
+ for (i = 0; i + 3 < count; i += 4) {
+ idx[0] = GET_ELT(i);
+ idx[1] = GET_ELT(i + 1);
+ idx[2] = GET_ELT(i + 2);
+ idx[3] = GET_ELT(i + 3);
+
+ flags = DRAW_PIPE_RESET_STIPPLE |
+ DRAW_PIPE_EDGE_FLAG_0 |
+ DRAW_PIPE_EDGE_FLAG_2;
+ /* always emit idx[3] last */
+ TRIANGLE(flags, idx[0], idx[1], idx[3]);
+
+ flags = DRAW_PIPE_EDGE_FLAG_0 |
+ DRAW_PIPE_EDGE_FLAG_1;
+ TRIANGLE(flags, idx[1], idx[2], idx[3]);
+ }
+ }
+ else {
+ for (i = 0; i + 3 < count; i += 4) {
+ idx[0] = GET_ELT(i);
+ idx[1] = GET_ELT(i + 1);
+ idx[2] = GET_ELT(i + 2);
+ idx[3] = GET_ELT(i + 3);
+
+ flags = DRAW_PIPE_RESET_STIPPLE |
+ DRAW_PIPE_EDGE_FLAG_0 |
+ DRAW_PIPE_EDGE_FLAG_1;
+ /* XXX should always emit idx[0] first */
+ /* always emit idx[3] first */
+ TRIANGLE(flags, idx[3], idx[0], idx[1]);
+
+ flags = DRAW_PIPE_EDGE_FLAG_1 |
+ DRAW_PIPE_EDGE_FLAG_2;
+ TRIANGLE(flags, idx[3], idx[1], idx[2]);
+ }
+ }
+ break;
+
+ case PIPE_PRIM_QUAD_STRIP:
+ if (count >= 4) {
+ idx[2] = GET_ELT(0);
+ idx[3] = GET_ELT(1);
+
+ if (last_vertex_last) {
+ for (i = 0; i + 3 < count; i += 2) {
+ idx[0] = idx[2];
+ idx[1] = idx[3];
+ idx[2] = GET_ELT(i + 2);
+ idx[3] = GET_ELT(i + 3);
+
+ /* always emit idx[3] last */
+ flags = DRAW_PIPE_RESET_STIPPLE |
+ DRAW_PIPE_EDGE_FLAG_0 |
+ DRAW_PIPE_EDGE_FLAG_2;
+ TRIANGLE(flags, idx[2], idx[0], idx[3]);
+
+ flags = DRAW_PIPE_EDGE_FLAG_0 |
+ DRAW_PIPE_EDGE_FLAG_1;
+ TRIANGLE(flags, idx[0], idx[1], idx[3]);
+ }
+ }
+ else {
+ for (i = 0; i + 3 < count; i += 2) {
+ idx[0] = idx[2];
+ idx[1] = idx[3];
+ idx[2] = GET_ELT(i + 2);
+ idx[3] = GET_ELT(i + 3);
+
+ flags = DRAW_PIPE_RESET_STIPPLE |
+ DRAW_PIPE_EDGE_FLAG_0 |
+ DRAW_PIPE_EDGE_FLAG_1;
+ /* XXX should always emit idx[0] first */
+ /* always emit idx[3] first */
+ TRIANGLE(flags, idx[3], idx[2], idx[0]);
+
+ flags = DRAW_PIPE_EDGE_FLAG_1 |
+ DRAW_PIPE_EDGE_FLAG_2;
+ TRIANGLE(flags, idx[3], idx[0], idx[1]);
+ }
+ }
+ }
+ break;
+
+ case PIPE_PRIM_POLYGON:
+ if (count >= 3) {
+ ushort edge_next, edge_finish;
+
+ if (last_vertex_last) {
+ flags = (DRAW_PIPE_RESET_STIPPLE |
+ DRAW_PIPE_EDGE_FLAG_2 |
+ DRAW_PIPE_EDGE_FLAG_0);
+ edge_next = DRAW_PIPE_EDGE_FLAG_0;
+ edge_finish = DRAW_PIPE_EDGE_FLAG_1;
+ }
+ else {
+ flags = (DRAW_PIPE_RESET_STIPPLE |
+ DRAW_PIPE_EDGE_FLAG_0 |
+ DRAW_PIPE_EDGE_FLAG_1);
+ edge_next = DRAW_PIPE_EDGE_FLAG_1;
+ edge_finish = DRAW_PIPE_EDGE_FLAG_2;
+ }
+
+ idx[0] = GET_ELT(0);
+ idx[2] = GET_ELT(1);
+
+ for (i = 0; i + 2 < count; i++, flags = edge_next) {
+ idx[1] = idx[2];
+ idx[2] = GET_ELT(i + 2);
+
+ if (i + 3 == count)
+ flags |= edge_finish;
+
+ /* idx[0] is both the first and the last vertex */
+ if (last_vertex_last)
+ TRIANGLE(flags, idx[1], idx[2], idx[0]);
+ else
+ TRIANGLE(flags, idx[0], idx[1], idx[2]);
+ }
+ }
+ break;
+
+ case PIPE_PRIM_LINES_ADJACENCY:
+ flags = DRAW_PIPE_RESET_STIPPLE;
+ for (i = 0; i + 3 < count; i += 4) {
+ idx[0] = GET_ELT(i);
+ idx[1] = GET_ELT(i + 1);
+ idx[2] = GET_ELT(i + 2);
+ idx[3] = GET_ELT(i + 3);
+ LINE_ADJ(flags, idx[0], idx[1], idx[2], idx[3]);
+ }
+ break;
+
+ case PIPE_PRIM_LINE_STRIP_ADJACENCY:
+ if (count >= 4) {
+ flags = DRAW_PIPE_RESET_STIPPLE;
+ idx[1] = GET_ELT(0);
+ idx[2] = GET_ELT(1);
+ idx[3] = GET_ELT(2);
+
+ for (i = 1; i + 2 < count; i++, flags = 0) {
+ idx[0] = idx[1];
+ idx[1] = idx[2];
+ idx[2] = idx[3];
+ idx[3] = GET_ELT(i + 2);
+ LINE_ADJ(flags, idx[0], idx[1], idx[2], idx[3]);
+ }
+ }
+ break;
+
+ case PIPE_PRIM_TRIANGLES_ADJACENCY:
+ flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;
+ for (i = 0; i + 5 < count; i += 6) {
+ idx[0] = GET_ELT(i);
+ idx[1] = GET_ELT(i + 1);
+ idx[2] = GET_ELT(i + 2);
+ idx[3] = GET_ELT(i + 3);
+ idx[4] = GET_ELT(i + 4);
+ idx[5] = GET_ELT(i + 5);
+ TRIANGLE_ADJ(flags, idx[0], idx[1], idx[2], idx[3], idx[4], idx[5]);
+ }
+ break;
+
+ case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
+ if (count >= 6) {
+ flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;
+ idx[0] = GET_ELT(1);
+ idx[2] = GET_ELT(0);
+ idx[4] = GET_ELT(2);
+ idx[3] = GET_ELT(4);
+
+ /*
+ * The vertices of the i-th triangle are stored in
+ * idx[0,2,4] = { 2*i, 2*i+2, 2*i+4 };
+ *
+ * The adjacent vertices are stored in
+ * idx[1,3,5] = { 2*i-2, 2*i+6, 2*i+3 }.
+ *
+ * However, there are two exceptions:
+ *
+ * For the first triangle, idx[1] = 1;
+ * For the last triangle, idx[3] = 2*i+5.
+ */
+ if (last_vertex_last) {
+ for (i = 0; i + 5 < count; i += 2) {
+ idx[1] = idx[0];
+
+ idx[0] = idx[2];
+ idx[2] = idx[4];
+ idx[4] = idx[3];
+
+ idx[3] = GET_ELT(i + ((i + 7 < count) ? 6 : 5));
+ idx[5] = GET_ELT(i + 3);
+
+ /*
+ * alternate the first two vertices (idx[0] and idx[2]) and the
+ * corresponding adjacent vertices (idx[3] and idx[5]) to have
+ * the correct orientation
+ */
+ if (i & 2) {
+ TRIANGLE_ADJ(flags,
+ idx[2], idx[1], idx[0], idx[5], idx[4], idx[3]);
+ }
+ else {
+ TRIANGLE_ADJ(flags,
+ idx[0], idx[1], idx[2], idx[3], idx[4], idx[5]);
+ }
+ }
+ }
+ else {
+ for (i = 0; i + 5 < count; i += 2) {
+ idx[1] = idx[0];
+
+ idx[0] = idx[2];
+ idx[2] = idx[4];
+ idx[4] = idx[3];
+
+ idx[3] = GET_ELT(i + ((i + 7 < count) ? 6 : 5));
+ idx[5] = GET_ELT(i + 3);
+
+ /*
+ * alternate the last two vertices (idx[2] and idx[4]) and the
+ * corresponding adjacent vertices (idx[1] and idx[5]) to have
+ * the correct orientation
+ */
+ if (i & 2) {
+ TRIANGLE_ADJ(flags,
+ idx[0], idx[5], idx[4], idx[3], idx[2], idx[1]);
+ }
+ else {
+ TRIANGLE_ADJ(flags,
+ idx[0], idx[1], idx[2], idx[3], idx[4], idx[5]);
+ }
+ }
+ }
+ }
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+
+ FUNC_EXIT;
+}
+
+#undef LOCAL_VARS
+#undef FUNC_ENTER
+#undef FUNC_EXIT
+#undef LINE_ADJ
+#undef TRIANGLE_ADJ
+
+#undef FUNC
+#undef FUNC_VARS
+#undef GET_ELT
+#undef POINT
+#undef LINE
+#undef TRIANGLE
diff --git a/src/gallium/auxiliary/draw/draw_gs.c b/src/gallium/auxiliary/draw/draw_gs.c
index 79a57a67f3e..4a1013e79a5 100644
--- a/src/gallium/auxiliary/draw/draw_gs.c
+++ b/src/gallium/auxiliary/draw/draw_gs.c
@@ -1,6 +1,6 @@
/**************************************************************************
*
- * Copyright 2009 VMWare Inc.
+ * Copyright 2009 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -75,7 +75,10 @@ draw_gs_set_constants(struct draw_context *draw,
const void *constants,
unsigned size)
{
- /* noop */
+ /* noop. added here for symmetry with the VS
+ * code and in case we'll ever want to allign
+ * the constants, e.g. when we'll change to a
+ * different interpreter */
}
@@ -370,32 +373,23 @@ static void gs_tri_adj(struct draw_geometry_shader *shader,
gs_flush(shader, 1);
}
-#define TRIANGLE(gs,i0,i1,i2) gs_tri(gs,i0,i1,i2)
-#define TRI_ADJ(gs,i0,i1,i2,i3,i4,i5) gs_tri_adj(gs,i0,i1,i2,i3,i4,i5)
-#define LINE(gs,i0,i1) gs_line(gs,i0,i1)
-#define LINE_ADJ(gs,i0,i1,i2,i3) gs_line_adj(gs,i0,i1,i2,i3)
-#define POINT(gs,i0) gs_point(gs,i0)
-#define FUNC gs_run
-#define LOCAL_VARS
+#define FUNC gs_run
+#define GET_ELT(idx) (idx)
#include "draw_gs_tmp.h"
-#define TRIANGLE(gs,i0,i1,i2) gs_tri(gs,elts[i0],elts[i1],elts[i2])
-#define TRI_ADJ(gs,i0,i1,i2,i3,i4,i5) \
- gs_tri_adj(gs,elts[i0],elts[i1],elts[i2],elts[i3], \
- elts[i4],elts[i5])
-#define LINE(gs,i0,i1) gs_line(gs,elts[i0],elts[i1])
-#define LINE_ADJ(gs,i0,i1,i2,i3) gs_line_adj(gs,elts[i0], \
- elts[i1], \
- elts[i2],elts[i3])
-#define POINT(gs,i0) gs_point(gs,elts[i0])
-#define FUNC gs_run_elts
-#define LOCAL_VARS \
- const ushort *elts = input_prims->elts;
+#define FUNC gs_run_elts
+#define LOCAL_VARS const ushort *elts = input_prims->elts;
+#define GET_ELT(idx) (elts[idx] & ~DRAW_PIPE_FLAG_MASK)
#include "draw_gs_tmp.h"
+
+/**
+ * Execute geometry shader using TGSI interpreter.
+ */
int draw_geometry_shader_run(struct draw_geometry_shader *shader,
const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
+ const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS],
const struct draw_vertex_info *input_verts,
const struct draw_prim_info *input_prim,
struct draw_vertex_info *output_verts,
@@ -405,7 +399,6 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
unsigned input_stride = input_verts->vertex_size;
unsigned vertex_size = input_verts->vertex_size;
struct tgsi_exec_machine *machine = shader->machine;
- unsigned int i;
unsigned num_input_verts = input_prim->linear ?
input_verts->count :
input_prim->count;
@@ -447,9 +440,8 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
}
shader->primitive_lengths = MALLOC(max_out_prims * sizeof(unsigned));
- for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
- machine->Consts[i] = constants[i];
- }
+ tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS,
+ constants, constants_size);
if (input_prim->linear)
gs_run(shader, input_prim, input_verts,
diff --git a/src/gallium/auxiliary/draw/draw_gs.h b/src/gallium/auxiliary/draw/draw_gs.h
index 2cb634818c2..67bc1aa73ff 100644
--- a/src/gallium/auxiliary/draw/draw_gs.h
+++ b/src/gallium/auxiliary/draw/draw_gs.h
@@ -1,6 +1,6 @@
/**************************************************************************
*
- * Copyright 2009 VMWare Inc.
+ * Copyright 2009 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -73,6 +73,7 @@ struct draw_geometry_shader {
*/
int draw_geometry_shader_run(struct draw_geometry_shader *shader,
const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
+ const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS],
const struct draw_vertex_info *input_verts,
const struct draw_prim_info *input_prim,
struct draw_vertex_info *output_verts,
diff --git a/src/gallium/auxiliary/draw/draw_gs_tmp.h b/src/gallium/auxiliary/draw/draw_gs_tmp.h
index 7a8683cf7c2..4a17af0dea3 100644
--- a/src/gallium/auxiliary/draw/draw_gs_tmp.h
+++ b/src/gallium/auxiliary/draw/draw_gs_tmp.h
@@ -1,152 +1,34 @@
-
-static void FUNC( struct draw_geometry_shader *shader,
- const struct draw_prim_info *input_prims,
- const struct draw_vertex_info *input_verts,
- struct draw_prim_info *output_prims,
- struct draw_vertex_info *output_verts)
-{
- struct draw_context *draw = shader->draw;
-
- boolean flatfirst = (draw->rasterizer->flatshade &&
- draw->rasterizer->flatshade_first);
- unsigned i, j;
- unsigned count = input_prims->count;
- LOCAL_VARS
-
- if (0) debug_printf("%s %d\n", __FUNCTION__, count);
-
- debug_assert(input_prims->primitive_count == 1);
-
- switch (input_prims->prim) {
- case PIPE_PRIM_POINTS:
- for (i = 0; i < count; i++) {
- POINT( shader, i + 0 );
- }
- break;
-
- case PIPE_PRIM_LINES:
- for (i = 0; i+1 < count; i += 2) {
- LINE( shader , i + 0 , i + 1 );
- }
- break;
-
- case PIPE_PRIM_LINE_LOOP:
- if (count >= 2) {
-
- for (i = 1; i < count; i++) {
- LINE( shader, i - 1, i );
- }
-
- LINE( shader, i - 1, 0 );
- }
- break;
-
- case PIPE_PRIM_LINE_STRIP:
- for (i = 1; i < count; i++) {
- LINE( shader, i - 1, i );
- }
- break;
-
- case PIPE_PRIM_TRIANGLES:
- for (i = 0; i+2 < count; i += 3) {
- TRIANGLE( shader, i + 0, i + 1, i + 2 );
- }
- break;
-
- case PIPE_PRIM_TRIANGLE_STRIP:
- if (flatfirst) {
- for (i = 0; i+2 < count; i++) {
- TRIANGLE( shader,
- i + 0,
- i + 1 + (i&1),
- i + 2 - (i&1) );
- }
- }
- else {
- for (i = 0; i+2 < count; i++) {
- TRIANGLE( shader,
- i + 0 + (i&1),
- i + 1 - (i&1),
- i + 2 );
- }
- }
- break;
-
- case PIPE_PRIM_TRIANGLE_FAN:
- if (count >= 3) {
- if (flatfirst) {
- for (i = 0; i+2 < count; i++) {
- TRIANGLE( shader,
- i + 1,
- i + 2,
- 0 );
- }
- }
- else {
- for (i = 0; i+2 < count; i++) {
- TRIANGLE( shader,
- 0,
- i + 1,
- i + 2 );
- }
- }
- }
- break;
-
- case PIPE_PRIM_POLYGON:
- {
- for (i = 0; i+2 < count; i++) {
-
- if (flatfirst) {
- TRIANGLE( shader, 0, i + 1, i + 2 );
- }
- else {
- TRIANGLE( shader, i + 1, i + 2, 0 );
- }
- }
- }
- break;
-
- case PIPE_PRIM_LINES_ADJACENCY:
- for (i = 0; i+3 < count; i += 4) {
- LINE_ADJ( shader , i + 0 , i + 1, i + 2, i + 3 );
- }
- break;
- case PIPE_PRIM_LINE_STRIP_ADJACENCY:
- for (i = 1; i + 2 < count; i++) {
- LINE_ADJ( shader, i - 1, i, i + 1, i + 2 );
- }
- break;
-
- case PIPE_PRIM_TRIANGLES_ADJACENCY:
- for (i = 0; i+5 < count; i += 5) {
- TRI_ADJ( shader, i + 0, i + 1, i + 2,
- i + 3, i + 4, i + 5);
- }
- break;
- case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
- for (i = 0, j = 0; i+5 < count; i += 2, ++j) {
- TRI_ADJ( shader,
- i + 0,
- i + 1 + 2*(j&1),
- i + 2 + 2*(j&1),
- i + 3 - 2*(j&1),
- i + 4 - 2*(j&1),
- i + 5);
- }
- break;
-
- default:
- debug_assert(!"Unsupported primitive in geometry shader");
- break;
- }
-}
-
-
-#undef TRIANGLE
-#undef TRI_ADJ
-#undef POINT
-#undef LINE
-#undef LINE_ADJ
-#undef FUNC
-#undef LOCAL_VARS
+#define FUNC_VARS struct draw_geometry_shader *gs, \
+ const struct draw_prim_info *input_prims, \
+ const struct draw_vertex_info *input_verts, \
+ struct draw_prim_info *output_prims, \
+ struct draw_vertex_info *output_verts
+
+#define FUNC_ENTER \
+ /* declare more local vars */ \
+ struct draw_context *draw = gs->draw; \
+ const unsigned prim = input_prims->prim; \
+ const unsigned count = input_prims->count; \
+ const boolean last_vertex_last = \
+ !(draw->rasterizer->flatshade && \
+ draw->rasterizer->flatshade_first); \
+ do { \
+ debug_assert(input_prims->primitive_count == 1); \
+ switch (prim) { \
+ case PIPE_PRIM_QUADS: \
+ case PIPE_PRIM_QUAD_STRIP: \
+ case PIPE_PRIM_POLYGON: \
+ debug_assert(!"unexpected primitive type in GS"); \
+ return; \
+ default: \
+ break; \
+ } \
+ } while (0) \
+
+#define POINT(i0) gs_point(gs,i0)
+#define LINE(flags,i0,i1) gs_line(gs,i0,i1)
+#define TRIANGLE(flags,i0,i1,i2) gs_tri(gs,i0,i1,i2)
+#define LINE_ADJ(flags,i0,i1,i2,i3) gs_line_adj(gs,i0,i1,i2,i3)
+#define TRIANGLE_ADJ(flags,i0,i1,i2,i3,i4,i5) gs_tri_adj(gs,i0,i1,i2,i3,i4,i5)
+
+#include "draw_decompose_tmp.h"
diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
index 19f96c37ab4..8d53601d195 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_llvm.c
@@ -37,6 +37,8 @@
#include "gallivm/lp_bld_debug.h"
#include "gallivm/lp_bld_tgsi.h"
#include "gallivm/lp_bld_printf.h"
+#include "gallivm/lp_bld_intr.h"
+#include "gallivm/lp_bld_init.h"
#include "tgsi/tgsi_exec.h"
#include "tgsi/tgsi_dump.h"
@@ -681,7 +683,6 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
unsigned i, j;
struct lp_build_context bld;
struct lp_build_loop_state lp_loop;
- struct lp_type vs_type = lp_type_float_vec(32);
const int max_vertices = 4;
LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS];
void *code;
@@ -730,7 +731,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
builder = LLVMCreateBuilder();
LLVMPositionBuilderAtEnd(builder, block);
- lp_build_context_init(&bld, builder, vs_type);
+ lp_build_context_init(&bld, builder, lp_type_int(32));
end = lp_build_add(&bld, start, count);
@@ -793,6 +794,11 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
sampler->destroy(sampler);
+#ifdef PIPE_ARCH_X86
+ /* Avoid corrupting the FPU stack on 32bit OSes. */
+ lp_build_intrinsic(builder, "llvm.x86.mmx.emms", LLVMVoidType(), NULL, 0);
+#endif
+
LLVMBuildRetVoid(builder);
LLVMDisposeBuilder(builder);
@@ -820,6 +826,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
if (gallivm_debug & GALLIVM_DEBUG_ASM) {
lp_disassemble(code);
}
+ lp_func_delete_body(variant->function);
}
@@ -837,9 +844,7 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
struct draw_context *draw = llvm->draw;
unsigned i, j;
struct lp_build_context bld;
- struct lp_build_context bld_int;
struct lp_build_loop_state lp_loop;
- struct lp_type vs_type = lp_type_float_vec(32);
const int max_vertices = 4;
LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS];
LLVMValueRef fetch_max;
@@ -891,8 +896,7 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
builder = LLVMCreateBuilder();
LLVMPositionBuilderAtEnd(builder, block);
- lp_build_context_init(&bld, builder, vs_type);
- lp_build_context_init(&bld_int, builder, lp_type_int(32));
+ lp_build_context_init(&bld, builder, lp_type_int(32));
step = LLVMConstInt(LLVMInt32Type(), max_vertices, 0);
@@ -927,7 +931,7 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
/* make sure we're not out of bounds which can happen
* if fetch_count % 4 != 0, because on the last iteration
* a few of the 4 vertex fetches will be out of bounds */
- true_index = lp_build_min(&bld_int, true_index, fetch_max);
+ true_index = lp_build_min(&bld, true_index, fetch_max);
fetch_ptr = LLVMBuildGEP(builder, fetch_elts,
&true_index, 1, "");
@@ -963,6 +967,11 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
sampler->destroy(sampler);
+#ifdef PIPE_ARCH_X86
+ /* Avoid corrupting the FPU stack on 32bit OSes. */
+ lp_build_intrinsic(builder, "llvm.x86.mmx.emms", LLVMVoidType(), NULL, 0);
+#endif
+
LLVMBuildRetVoid(builder);
LLVMDisposeBuilder(builder);
@@ -990,6 +999,7 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
if (gallivm_debug & GALLIVM_DEBUG_ASM) {
lp_disassemble(code);
}
+ lp_func_delete_body(variant->function_elts);
}
void
diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c
index 8cd75ecf9a3..58995e07248 100644
--- a/src/gallium/auxiliary/draw/draw_pipe.c
+++ b/src/gallium/auxiliary/draw/draw_pipe.c
@@ -169,77 +169,50 @@ static void do_triangle( struct draw_context *draw,
/*
* Set up macros for draw_pt_decompose.h template code.
* This code uses vertex indexes / elements.
+ *
+ * Flags are needed by the stipple and unfilled stages. When the two stages
+ * are active, vcache_run_extras is called and the flags are stored in the
+ * higher bits of i0. Otherwise, flags do not matter.
*/
-/* emit first quad vertex as first vertex in triangles */
-#define QUAD_FIRST_PV(i0,i1,i2,i3) \
- do_triangle( draw, \
- ( DRAW_PIPE_RESET_STIPPLE | \
- DRAW_PIPE_EDGE_FLAG_0 | \
- DRAW_PIPE_EDGE_FLAG_1 ), \
- verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \
- verts + stride * (elts[i1] & ~DRAW_PIPE_FLAG_MASK), \
- verts + stride * (elts[i2] & ~DRAW_PIPE_FLAG_MASK)); \
- do_triangle( draw, \
- ( DRAW_PIPE_EDGE_FLAG_1 | \
- DRAW_PIPE_EDGE_FLAG_2 ), \
- verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \
- verts + stride * (elts[i2] & ~DRAW_PIPE_FLAG_MASK), \
- verts + stride * (elts[i3] & ~DRAW_PIPE_FLAG_MASK))
-
-/* emit last quad vertex as last vertex in triangles */
-#define QUAD_LAST_PV(i0,i1,i2,i3) \
- do_triangle( draw, \
- ( DRAW_PIPE_RESET_STIPPLE | \
- DRAW_PIPE_EDGE_FLAG_0 | \
- DRAW_PIPE_EDGE_FLAG_2 ), \
- verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \
- verts + stride * (elts[i1] & ~DRAW_PIPE_FLAG_MASK), \
- verts + stride * (elts[i3] & ~DRAW_PIPE_FLAG_MASK)); \
- do_triangle( draw, \
- ( DRAW_PIPE_EDGE_FLAG_0 | \
- DRAW_PIPE_EDGE_FLAG_1 ), \
- verts + stride * (elts[i1] & ~DRAW_PIPE_FLAG_MASK), \
- verts + stride * (elts[i2] & ~DRAW_PIPE_FLAG_MASK), \
- verts + stride * (elts[i3] & ~DRAW_PIPE_FLAG_MASK))
-
-#define TRIANGLE(flags,i0,i1,i2) \
- do_triangle( draw, \
- elts[i0], /* flags */ \
- verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \
- verts + stride * (elts[i1] & ~DRAW_PIPE_FLAG_MASK), \
- verts + stride * (elts[i2] & ~DRAW_PIPE_FLAG_MASK) );
-
-#define LINE(flags,i0,i1) \
- do_line( draw, \
- elts[i0], \
- verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \
- verts + stride * (elts[i1] & ~DRAW_PIPE_FLAG_MASK) );
+#define TRIANGLE(flags,i0,i1,i2) \
+ do { \
+ assert(!((i1) & DRAW_PIPE_FLAG_MASK)); \
+ assert(!((i2) & DRAW_PIPE_FLAG_MASK)); \
+ do_triangle( draw, \
+ i0, /* flags */ \
+ verts + stride * (i0 & ~DRAW_PIPE_FLAG_MASK), \
+ verts + stride * (i1), \
+ verts + stride * (i2) ); \
+ } while (0)
+
+#define LINE(flags,i0,i1) \
+ do { \
+ assert(!((i1) & DRAW_PIPE_FLAG_MASK)); \
+ do_line( draw, \
+ i0, /* flags */ \
+ verts + stride * (i0 & ~DRAW_PIPE_FLAG_MASK), \
+ verts + stride * (i1) ); \
+ } while (0)
#define POINT(i0) \
- do_point( draw, \
- verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK) )
+ do { \
+ assert(!((i0) & DRAW_PIPE_FLAG_MASK)); \
+ do_point( draw, verts + stride * (i0) ); \
+ } while (0)
+
+#define GET_ELT(idx) (elts[idx])
-#define FUNC pipe_run
-#define ARGS \
+#define FUNC pipe_run_elts
+#define FUNC_VARS \
struct draw_context *draw, \
unsigned prim, \
struct vertex_header *vertices, \
unsigned stride, \
- const ushort *elts
-
-#define LOCAL_VARS \
- char *verts = (char *)vertices; \
- boolean flatfirst = (draw->rasterizer->flatshade && \
- draw->rasterizer->flatshade_first); \
- unsigned i; \
- ushort flags
-
-#define FLUSH
+ const ushort *elts, \
+ unsigned count
#include "draw_pt_decompose.h"
-#undef ARGS
-#undef LOCAL_VARS
@@ -269,14 +242,29 @@ void draw_pipeline_run( struct draw_context *draw,
i < prim_info->primitive_count;
start += prim_info->primitive_lengths[i], i++)
{
- unsigned count = prim_info->primitive_lengths[i];
-
- pipe_run(draw,
- prim_info->prim,
- vert_info->verts,
- vert_info->stride,
- prim_info->elts + start,
- count);
+ const unsigned count = prim_info->primitive_lengths[i];
+
+#if DEBUG
+ /* make sure none of the element indexes go outside the vertex buffer */
+ {
+ unsigned max_index = 0x0, i;
+ /* find the largest element index */
+ for (i = 0; i < count; i++) {
+ unsigned int index = (prim_info->elts[start + i]
+ & ~DRAW_PIPE_FLAG_MASK);
+ if (index > max_index)
+ max_index = index;
+ }
+ assert(max_index <= vert_info->count);
+ }
+#endif
+
+ pipe_run_elts(draw,
+ prim_info->prim,
+ vert_info->verts,
+ vert_info->stride,
+ prim_info->elts + start,
+ count);
}
draw->pipeline.verts = NULL;
@@ -289,70 +277,30 @@ void draw_pipeline_run( struct draw_context *draw,
* This code is for non-indexed (aka linear) rendering (no elts).
*/
-/* emit first quad vertex as first vertex in triangles */
-#define QUAD_FIRST_PV(i0,i1,i2,i3) \
- do_triangle( draw, \
- ( DRAW_PIPE_RESET_STIPPLE | \
- DRAW_PIPE_EDGE_FLAG_0 | \
- DRAW_PIPE_EDGE_FLAG_1 ), \
- verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \
- verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK), \
- verts + stride * ((i2) & ~DRAW_PIPE_FLAG_MASK)); \
- do_triangle( draw, \
- ( DRAW_PIPE_EDGE_FLAG_1 | \
- DRAW_PIPE_EDGE_FLAG_2 ), \
- verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \
- verts + stride * ((i2) & ~DRAW_PIPE_FLAG_MASK), \
- verts + stride * ((i3) & ~DRAW_PIPE_FLAG_MASK))
-
-/* emit last quad vertex as last vertex in triangles */
-#define QUAD_LAST_PV(i0,i1,i2,i3) \
- do_triangle( draw, \
- ( DRAW_PIPE_RESET_STIPPLE | \
- DRAW_PIPE_EDGE_FLAG_0 | \
- DRAW_PIPE_EDGE_FLAG_2 ), \
- verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \
- verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK), \
- verts + stride * ((i3) & ~DRAW_PIPE_FLAG_MASK)); \
- do_triangle( draw, \
- ( DRAW_PIPE_EDGE_FLAG_0 | \
- DRAW_PIPE_EDGE_FLAG_1 ), \
- verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK), \
- verts + stride * ((i2) & ~DRAW_PIPE_FLAG_MASK), \
- verts + stride * ((i3) & ~DRAW_PIPE_FLAG_MASK))
-
-#define TRIANGLE(flags,i0,i1,i2) \
- do_triangle( draw, \
- flags, /* flags */ \
- verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \
- verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK), \
- verts + stride * ((i2) & ~DRAW_PIPE_FLAG_MASK))
-
-#define LINE(flags,i0,i1) \
- do_line( draw, \
- flags, \
- verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \
- verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK))
+#define TRIANGLE(flags,i0,i1,i2) \
+ do_triangle( draw, flags, \
+ verts + stride * (i0), \
+ verts + stride * (i1), \
+ verts + stride * (i2) )
-#define POINT(i0) \
- do_point( draw, \
- verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK) )
+#define LINE(flags,i0,i1) \
+ do_line( draw, flags, \
+ verts + stride * (i0), \
+ verts + stride * (i1) )
-#define FUNC pipe_run_linear
-#define ARGS \
- struct draw_context *draw, \
- unsigned prim, \
- struct vertex_header *vertices, \
- unsigned stride
+#define POINT(i0) \
+ do_point( draw, verts + stride * (i0) )
-#define LOCAL_VARS \
- char *verts = (char *)vertices; \
- boolean flatfirst = (draw->rasterizer->flatshade && \
- draw->rasterizer->flatshade_first); \
- unsigned i; \
- ushort flags
-#define FLUSH
+#define GET_ELT(idx) (idx)
+
+#define FUNC pipe_run_linear
+#define FUNC_VARS \
+ struct draw_context *draw, \
+ unsigned prim, \
+ struct vertex_header *vertices, \
+ unsigned stride, \
+ unsigned count
#include "draw_pt_decompose.h"
@@ -378,6 +326,8 @@ void draw_pipeline_run_linear( struct draw_context *draw,
draw->pipeline.vertex_stride = vert_info->stride;
draw->pipeline.vertex_count = count;
+ assert(count <= vert_info->count);
+
pipe_run_linear(draw,
prim_info->prim,
(struct vertex_header*)verts,
diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c
index 1cf6ee7a7f9..8a3d499febb 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_clip.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c
@@ -68,8 +68,7 @@ struct clip_stage {
};
-/* This is a bit confusing:
- */
+/** Cast wrapper */
static INLINE struct clip_stage *clip_stage( struct draw_stage *stage )
{
return (struct clip_stage *)stage;
@@ -81,18 +80,22 @@ static INLINE struct clip_stage *clip_stage( struct draw_stage *stage )
/* All attributes are float[4], so this is easy:
*/
-static void interp_attr( float *fdst,
+static void interp_attr( float dst[4],
float t,
- const float *fin,
- const float *fout )
+ const float in[4],
+ const float out[4] )
{
- fdst[0] = LINTERP( t, fout[0], fin[0] );
- fdst[1] = LINTERP( t, fout[1], fin[1] );
- fdst[2] = LINTERP( t, fout[2], fin[2] );
- fdst[3] = LINTERP( t, fout[3], fin[3] );
+ dst[0] = LINTERP( t, out[0], in[0] );
+ dst[1] = LINTERP( t, out[1], in[1] );
+ dst[2] = LINTERP( t, out[2], in[2] );
+ dst[3] = LINTERP( t, out[3], in[3] );
}
+/**
+ * Copy front/back, primary/secondary colors from src vertex to dst vertex.
+ * Used when flat shading.
+ */
static void copy_colors( struct draw_stage *stage,
struct vertex_header *dst,
const struct vertex_header *src )
@@ -121,20 +124,17 @@ static void interp( const struct clip_stage *clip,
/* Vertex header.
*/
- {
- dst->clipmask = 0;
- dst->edgeflag = 0; /* will get overwritten later */
- dst->pad = 0;
- dst->vertex_id = UNDEFINED_VERTEX_ID;
- }
+ dst->clipmask = 0;
+ dst->edgeflag = 0; /* will get overwritten later */
+ dst->pad = 0;
+ dst->vertex_id = UNDEFINED_VERTEX_ID;
- /* Clip coordinates: interpolate normally
+ /* Interpolate the clip-space coords.
*/
- {
- interp_attr(dst->clip, t, in->clip, out->clip);
- }
+ interp_attr(dst->clip, t, in->clip, out->clip);
- /* Do the projective divide and insert window coordinates:
+ /* Do the projective divide and viewport transformation to get
+ * new window coordinates:
*/
{
const float *pos = dst->clip;
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index 058aeedc17a..397d4bf653c 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -163,9 +163,11 @@ struct draw_context
/** vertex arrays */
const void *vbuffer[PIPE_MAX_ATTRIBS];
- /** constant buffer (for vertex/geometry shader) */
+ /** constant buffers (for vertex/geometry shader) */
const void *vs_constants[PIPE_MAX_CONSTANT_BUFFERS];
+ unsigned vs_constants_size[PIPE_MAX_CONSTANT_BUFFERS];
const void *gs_constants[PIPE_MAX_CONSTANT_BUFFERS];
+ unsigned gs_constants_size[PIPE_MAX_CONSTANT_BUFFERS];
} user;
boolean test_fse; /* enable FSE even though its not correct (eg for softpipe) */
@@ -198,6 +200,7 @@ struct draw_context
struct pipe_viewport_state viewport;
boolean identity_viewport;
+ /** Vertex shader state */
struct {
struct draw_vertex_shader *vertex_shader;
uint num_vs_outputs; /**< convenience, from vertex_shader */
@@ -227,6 +230,7 @@ struct draw_context
struct translate_cache *emit_cache;
} vs;
+ /** Geometry shader state */
struct {
struct draw_geometry_shader *geometry_shader;
uint num_gs_outputs; /**< convenience, from geometry_shader */
@@ -239,6 +243,7 @@ struct draw_context
struct tgsi_sampler **samplers;
} gs;
+ /** Stream output (vertex feedback) state */
struct {
struct pipe_stream_output_state state;
void *buffers[PIPE_MAX_SO_BUFFERS];
diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c
index 92d4113b4c6..248927505da 100644
--- a/src/gallium/auxiliary/draw/draw_pt.c
+++ b/src/gallium/auxiliary/draw/draw_pt.c
@@ -259,6 +259,12 @@ draw_print_arrays(struct draw_context *draw, uint prim, int start, uint count)
for (j = 0; j < draw->pt.nr_vertex_elements; j++) {
uint buf = draw->pt.vertex_element[j].vertex_buffer_index;
ubyte *ptr = (ubyte *) draw->pt.user.vbuffer[buf];
+
+ if (draw->pt.vertex_element[j].instance_divisor) {
+ ii = draw->instance_id / draw->pt.vertex_element[j].instance_divisor;
+ }
+
+ ptr += draw->pt.vertex_buffer[buf].buffer_offset;
ptr += draw->pt.vertex_buffer[buf].stride * ii;
ptr += draw->pt.vertex_element[j].src_offset;
@@ -341,19 +347,22 @@ draw_arrays_instanced(struct draw_context *draw,
unsigned reduced_prim = u_reduced_prim(mode);
unsigned instance;
+ assert(instanceCount > 0);
+
if (reduced_prim != draw->reduced_prim) {
draw_do_flush(draw, DRAW_FLUSH_STATE_CHANGE);
draw->reduced_prim = reduced_prim;
}
if (0)
- draw_print_arrays(draw, mode, start, MIN2(count, 20));
-
- if (0) {
- unsigned int i;
debug_printf("draw_arrays(mode=%u start=%u count=%u):\n",
mode, start, count);
+
+ if (0)
tgsi_dump(draw->vs.vertex_shader->state.tokens, 0);
+
+ if (0) {
+ unsigned int i;
debug_printf("Elements:\n");
for (i = 0; i < draw->pt.nr_vertex_elements; i++) {
debug_printf(" %u: src_offset=%u inst_div=%u vbuf=%u format=%s\n",
@@ -374,6 +383,9 @@ draw_arrays_instanced(struct draw_context *draw,
}
}
+ if (0)
+ draw_print_arrays(draw, mode, start, MIN2(count, 20));
+
for (instance = 0; instance < instanceCount; instance++) {
draw->instance_id = instance + startInstance;
draw_pt_arrays(draw, mode, start, count);
diff --git a/src/gallium/auxiliary/draw/draw_pt_decompose.h b/src/gallium/auxiliary/draw/draw_pt_decompose.h
index 52f9593d46e..3127aad7310 100644
--- a/src/gallium/auxiliary/draw/draw_pt_decompose.h
+++ b/src/gallium/auxiliary/draw/draw_pt_decompose.h
@@ -1,194 +1,7 @@
+#define LOCAL_VARS \
+ char *verts = (char *) vertices; \
+ const boolean last_vertex_last = \
+ !(draw->rasterizer->flatshade && \
+ draw->rasterizer->flatshade_first);
-
-static void FUNC( ARGS,
- unsigned count )
-{
- LOCAL_VARS;
-
- switch (prim) {
- case PIPE_PRIM_POINTS:
- for (i = 0; i < count; i ++) {
- POINT( (i + 0) );
- }
- break;
-
- case PIPE_PRIM_LINES:
- for (i = 0; i+1 < count; i += 2) {
- LINE( DRAW_PIPE_RESET_STIPPLE,
- (i + 0),
- (i + 1));
- }
- break;
-
- case PIPE_PRIM_LINE_LOOP:
- if (count >= 2) {
- flags = DRAW_PIPE_RESET_STIPPLE;
-
- for (i = 1; i < count; i++, flags = 0) {
- LINE( flags,
- (i - 1),
- (i ));
- }
-
- LINE( flags,
- (i - 1),
- (0 ));
- }
- break;
-
- case PIPE_PRIM_LINE_STRIP:
- flags = DRAW_PIPE_RESET_STIPPLE;
- for (i = 1; i < count; i++, flags = 0) {
- LINE( flags,
- (i - 1),
- (i ));
- }
- break;
-
- case PIPE_PRIM_TRIANGLES:
- for (i = 0; i+2 < count; i += 3) {
- TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
- (i + 0),
- (i + 1),
- (i + 2 ));
- }
- break;
-
- case PIPE_PRIM_TRIANGLE_STRIP:
- if (flatfirst) {
- for (i = 0; i+2 < count; i++) {
- /* Emit first triangle vertex as first triangle vertex */
- TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
- (i + 0),
- (i + 1 + (i&1)),
- (i + 2 - (i&1)) );
- }
- }
- else {
- for (i = 0; i+2 < count; i++) {
- /* Emit last triangle vertex as last triangle vertex */
- TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
- (i + 0 + (i&1)),
- (i + 1 - (i&1)),
- (i + 2 ));
- }
- }
- break;
-
- case PIPE_PRIM_TRIANGLE_FAN:
- if (count >= 3) {
- if (flatfirst) {
- for (i = 0; i+2 < count; i++) {
- TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
- (i + 1),
- (i + 2),
- 0 );
- }
- }
- else {
- for (i = 0; i+2 < count; i++) {
- TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
- (0),
- (i + 1),
- (i + 2 ));
- }
- }
- }
- break;
-
-
- case PIPE_PRIM_QUADS:
- /* GL quads don't follow provoking vertex convention */
- if (flatfirst) {
- for (i = 0; i+3 < count; i += 4) {
- /* emit last quad vertex as first triangle vertex */
- QUAD_FIRST_PV( (i + 3),
- (i + 0),
- (i + 1),
- (i + 2) );
- }
- }
- else {
- for (i = 0; i+3 < count; i += 4) {
- /* emit last quad vertex as last triangle vertex */
- QUAD_LAST_PV( (i + 0),
- (i + 1),
- (i + 2),
- (i + 3) );
- }
- }
- break;
-
- case PIPE_PRIM_QUAD_STRIP:
- /* GL quad strips don't follow provoking vertex convention */
- if (flatfirst) {
- for (i = 0; i+3 < count; i += 2) {
- /* emit last quad vertex as first triangle vertex */
- QUAD_FIRST_PV( (i + 3),
- (i + 2),
- (i + 0),
- (i + 1) );
-
- }
- }
- else {
- for (i = 0; i+3 < count; i += 2) {
- /* emit last quad vertex as last triangle vertex */
- QUAD_LAST_PV( (i + 2),
- (i + 0),
- (i + 1),
- (i + 3) );
- }
- }
- break;
-
- case PIPE_PRIM_POLYGON:
- /* GL polygons don't follow provoking vertex convention */
- {
- /* These bitflags look a little odd because we submit the
- * vertices as (1,2,0) to satisfy flatshade requirements.
- */
- const ushort edge_first = DRAW_PIPE_EDGE_FLAG_2;
- const ushort edge_middle = DRAW_PIPE_EDGE_FLAG_0;
- const ushort edge_last = DRAW_PIPE_EDGE_FLAG_1;
-
- flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle;
-
- for (i = 0; i+2 < count; i++, flags = edge_middle) {
-
- if (i + 3 == count)
- flags |= edge_last;
-
- if (flatfirst) {
- /* emit first polygon vertex as first triangle vertex */
- TRIANGLE( flags,
- (0),
- (i + 1),
- (i + 2) );
- }
- else {
- /* emit first polygon vertex as last triangle vertex */
- TRIANGLE( flags,
- (i + 1),
- (i + 2),
- (0));
- }
- }
- }
- break;
-
- default:
- assert(0);
- break;
- }
-
- FLUSH;
-}
-
-
-#undef TRIANGLE
-#undef QUAD_FIRST_PV
-#undef QUAD_LAST_PV
-#undef POINT
-#undef LINE
-#undef FUNC
+#include "draw_decompose_tmp.h"
diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c
index 0229bcc7fe1..5568fbb9f88 100644
--- a/src/gallium/auxiliary/draw/draw_pt_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_emit.c
@@ -182,6 +182,7 @@ void draw_pt_emit( struct pt_emit *emit,
0,
~0);
+ /* fetch/translate vertex attribs to fill hw_verts[] */
translate->run( translate,
0,
vertex_count,
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
index 121dfc414a4..5b16c3788e5 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
@@ -176,6 +176,7 @@ static void emit(struct pt_emit *emit,
static void draw_vertex_shader_run(struct draw_vertex_shader *vshader,
const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
+ unsigned const_size[PIPE_MAX_CONSTANT_BUFFERS],
const struct draw_vertex_info *input_verts,
struct draw_vertex_info *output_verts )
{
@@ -190,6 +191,7 @@ static void draw_vertex_shader_run(struct draw_vertex_shader *vshader,
(const float (*)[4])input_verts->verts->data,
( float (*)[4])output_verts->verts->data,
constants,
+ const_size,
input_verts->count,
input_verts->vertex_size,
input_verts->vertex_size);
@@ -236,6 +238,7 @@ static void fetch_pipeline_generic( struct draw_pt_middle_end *middle,
if (fpme->opt & PT_SHADE) {
draw_vertex_shader_run(vshader,
draw->pt.user.vs_constants,
+ draw->pt.user.vs_constants_size,
vert_info,
&vs_vert_info);
@@ -246,6 +249,7 @@ static void fetch_pipeline_generic( struct draw_pt_middle_end *middle,
if ((fpme->opt & PT_SHADE) && gshader) {
draw_geometry_shader_run(gshader,
draw->pt.user.gs_constants,
+ draw->pt.user.gs_constants_size,
vert_info,
prim_info,
&gs_vert_info,
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
index bc074df8c2a..4b99bee86a0 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
@@ -1,6 +1,6 @@
/**************************************************************************
*
- * Copyright 2010 VMWare, Inc.
+ * Copyright 2010 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -254,6 +254,7 @@ llvm_pipeline_generic( struct draw_pt_middle_end *middle,
if ((opt & PT_SHADE) && gshader) {
draw_geometry_shader_run(gshader,
draw->pt.user.gs_constants,
+ draw->pt.user.gs_constants_size,
vert_info,
prim_info,
&gs_vert_info,
diff --git a/src/gallium/auxiliary/draw/draw_pt_so_emit.c b/src/gallium/auxiliary/draw/draw_pt_so_emit.c
index 5d82934889b..f7f4f24d354 100644
--- a/src/gallium/auxiliary/draw/draw_pt_so_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_so_emit.c
@@ -218,25 +218,15 @@ static void so_tri(struct pt_so_emit *so, int i0, int i1, int i2)
}
-#define TRIANGLE(gs,i0,i1,i2) so_tri(so,i0,i1,i2)
-#define LINE(gs,i0,i1) so_line(so,i0,i1)
-#define POINT(gs,i0) so_point(so,i0)
-#define FUNC so_run_linear
-#define LOCAL_VARS
+#define FUNC so_run_linear
+#define GET_ELT(idx) (start + (idx))
#include "draw_so_emit_tmp.h"
-#undef LOCAL_VARS
-#undef FUNC
-#define TRIANGLE(gs,i0,i1,i2) so_tri(gs,elts[i0],elts[i1],elts[i2])
-#define LINE(gs,i0,i1) so_line(gs,elts[i0],elts[i1])
-#define POINT(gs,i0) so_point(gs,elts[i0])
-#define FUNC so_run_elts
-#define LOCAL_VARS \
- const ushort *elts = input_prims->elts;
+#define FUNC so_run_elts
+#define LOCAL_VARS const ushort *elts = input_prims->elts;
+#define GET_ELT(idx) (elts[start + (idx)] & ~DRAW_PIPE_FLAG_MASK)
#include "draw_so_emit_tmp.h"
-#undef LOCAL_VARS
-#undef FUNC
void draw_pt_so_emit( struct pt_so_emit *emit,
diff --git a/src/gallium/auxiliary/draw/draw_pt_util.c b/src/gallium/auxiliary/draw/draw_pt_util.c
index 3236d38e6ab..182a597cca2 100644
--- a/src/gallium/auxiliary/draw/draw_pt_util.c
+++ b/src/gallium/auxiliary/draw/draw_pt_util.c
@@ -53,7 +53,7 @@ void draw_pt_split_prim(unsigned prim, unsigned *first, unsigned *incr)
break;
case PIPE_PRIM_LINES_ADJACENCY:
*first = 4;
- *incr = 2;
+ *incr = 4;
break;
case PIPE_PRIM_LINE_STRIP_ADJACENCY:
*first = 4;
@@ -65,7 +65,7 @@ void draw_pt_split_prim(unsigned prim, unsigned *first, unsigned *incr)
break;
case PIPE_PRIM_TRIANGLES_ADJACENCY:
*first = 6;
- *incr = 3;
+ *incr = 6;
break;
case PIPE_PRIM_TRIANGLE_STRIP:
case PIPE_PRIM_TRIANGLE_FAN:
@@ -75,7 +75,7 @@ void draw_pt_split_prim(unsigned prim, unsigned *first, unsigned *incr)
break;
case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
*first = 6;
- *incr = 1;
+ *incr = 2;
break;
case PIPE_PRIM_QUADS:
*first = 4;
diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h
index a292346be95..55e43b2a714 100644
--- a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h
+++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h
@@ -1,6 +1,11 @@
static unsigned trim( unsigned count, unsigned first, unsigned incr )
{
- return count - (count - first) % incr;
+ /*
+ * count either has been trimmed in draw_pt_arrays or is set to
+ * (driver)_fetch_max which is hopefully always larger than first.
+ */
+ assert(count >= first);
+ return count - (count - first) % incr;
}
static void FUNC(struct draw_pt_front_end *frontend,
diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c
index 8ef94c3163c..a848b54f7d2 100644
--- a/src/gallium/auxiliary/draw/draw_pt_vcache.c
+++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c
@@ -95,7 +95,7 @@ static INLINE void
vcache_check_flush( struct vcache_frontend *vcache )
{
if (vcache->draw_count + 6 >= DRAW_MAX ||
- vcache->fetch_count + 4 >= FETCH_MAX) {
+ vcache->fetch_count + 6 >= FETCH_MAX) {
vcache_flush( vcache );
}
}
@@ -180,59 +180,61 @@ vcache_point( struct vcache_frontend *vcache,
}
-static INLINE void
-vcache_quad( struct vcache_frontend *vcache,
- unsigned i0,
- unsigned i1,
- unsigned i2,
- unsigned i3 )
+static INLINE void
+vcache_line_adj_flags( struct vcache_frontend *vcache,
+ unsigned flags,
+ unsigned a0, unsigned i0, unsigned i1, unsigned a1 )
{
- if (vcache->draw->rasterizer->flatshade_first) {
- /* pass last quad vertex as first triangle vertex */
- vcache_triangle( vcache, i3, i0, i1 );
- vcache_triangle( vcache, i3, i1, i2 );
- }
- else {
- /* pass last quad vertex as last triangle vertex */
- vcache_triangle( vcache, i0, i1, i3 );
- vcache_triangle( vcache, i1, i2, i3 );
- }
+ vcache_elt(vcache, a0, 0);
+ vcache_elt(vcache, i0, flags);
+ vcache_elt(vcache, i1, 0);
+ vcache_elt(vcache, a1, 0);
+ vcache_check_flush(vcache);
}
-static INLINE void
-vcache_ef_quad( struct vcache_frontend *vcache,
- unsigned i0,
- unsigned i1,
- unsigned i2,
- unsigned i3 )
+static INLINE void
+vcache_line_adj( struct vcache_frontend *vcache,
+ unsigned a0, unsigned i0, unsigned i1, unsigned a1 )
{
- if (vcache->draw->rasterizer->flatshade_first) {
- /* pass last quad vertex as first triangle vertex */
- vcache_triangle_flags( vcache,
- ( DRAW_PIPE_RESET_STIPPLE |
- DRAW_PIPE_EDGE_FLAG_0 |
- DRAW_PIPE_EDGE_FLAG_1 ),
- i3, i0, i1 );
-
- vcache_triangle_flags( vcache,
- ( DRAW_PIPE_EDGE_FLAG_1 |
- DRAW_PIPE_EDGE_FLAG_2 ),
- i3, i1, i2 );
- }
- else {
- /* pass last quad vertex as last triangle vertex */
- vcache_triangle_flags( vcache,
- ( DRAW_PIPE_RESET_STIPPLE |
- DRAW_PIPE_EDGE_FLAG_0 |
- DRAW_PIPE_EDGE_FLAG_2 ),
- i0, i1, i3 );
-
- vcache_triangle_flags( vcache,
- ( DRAW_PIPE_EDGE_FLAG_0 |
- DRAW_PIPE_EDGE_FLAG_1 ),
- i1, i2, i3 );
- }
+ vcache_elt(vcache, a0, 0);
+ vcache_elt(vcache, i0, 0);
+ vcache_elt(vcache, i1, 0);
+ vcache_elt(vcache, a1, 0);
+ vcache_check_flush(vcache);
+}
+
+
+static INLINE void
+vcache_triangle_adj_flags( struct vcache_frontend *vcache,
+ unsigned flags,
+ unsigned i0, unsigned a0,
+ unsigned i1, unsigned a1,
+ unsigned i2, unsigned a2 )
+{
+ vcache_elt(vcache, i0, flags);
+ vcache_elt(vcache, a0, 0);
+ vcache_elt(vcache, i1, 0);
+ vcache_elt(vcache, a1, 0);
+ vcache_elt(vcache, i2, 0);
+ vcache_elt(vcache, a2, 0);
+ vcache_check_flush(vcache);
+}
+
+
+static INLINE void
+vcache_triangle_adj( struct vcache_frontend *vcache,
+ unsigned i0, unsigned a0,
+ unsigned i1, unsigned a1,
+ unsigned i2, unsigned a2 )
+{
+ vcache_elt(vcache, i0, 0);
+ vcache_elt(vcache, a0, 0);
+ vcache_elt(vcache, i1, 0);
+ vcache_elt(vcache, a1, 0);
+ vcache_elt(vcache, i2, 0);
+ vcache_elt(vcache, a2, 0);
+ vcache_check_flush(vcache);
}
@@ -240,17 +242,23 @@ vcache_ef_quad( struct vcache_frontend *vcache,
* this. The two paths aren't too different though - it may be
* possible to reunify them.
*/
-#define TRIANGLE(vc,flags,i0,i1,i2) vcache_triangle_flags(vc,flags,i0,i1,i2)
-#define QUAD(vc,i0,i1,i2,i3) vcache_ef_quad(vc,i0,i1,i2,i3)
-#define LINE(vc,flags,i0,i1) vcache_line_flags(vc,flags,i0,i1)
-#define POINT(vc,i0) vcache_point(vc,i0)
+#define TRIANGLE(flags,i0,i1,i2) vcache_triangle_flags(vcache,flags,i0,i1,i2)
+#define LINE(flags,i0,i1) vcache_line_flags(vcache,flags,i0,i1)
+#define POINT(i0) vcache_point(vcache,i0)
+#define LINE_ADJ(flags,a0,i0,i1,a1) \
+ vcache_line_adj_flags(vcache,flags,a0,i0,i1,a1)
+#define TRIANGLE_ADJ(flags,i0,a0,i1,a1,i2,a2) \
+ vcache_triangle_adj_flags(vcache,flags,i0,a0,i1,a1,i2,a2)
#define FUNC vcache_run_extras
#include "draw_pt_vcache_tmp.h"
-#define TRIANGLE(vc,flags,i0,i1,i2) vcache_triangle(vc,i0,i1,i2)
-#define QUAD(vc,i0,i1,i2,i3) vcache_quad(vc,i0,i1,i2,i3)
-#define LINE(vc,flags,i0,i1) vcache_line(vc,i0,i1)
-#define POINT(vc,i0) vcache_point(vc,i0)
+#define TRIANGLE(flags,i0,i1,i2) vcache_triangle(vcache,i0,i1,i2)
+#define LINE(flags,i0,i1) vcache_line(vcache,i0,i1)
+#define POINT(i0) vcache_point(vcache,i0)
+#define LINE_ADJ(flags,a0,i0,i1,a1) \
+ vcache_line_adj(vcache,a0,i0,i1,a1)
+#define TRIANGLE_ADJ(flags,i0,a0,i1,a1,i2,a2) \
+ vcache_triangle_adj(vcache,i0,a0,i1,a1,i2,a2)
#define FUNC vcache_run
#include "draw_pt_vcache_tmp.h"
@@ -339,6 +347,25 @@ format_from_get_elt( pt_elt_func get_elt )
#endif
+/**
+ * Check if any vertex attributes use instance divisors.
+ * Note that instance divisors complicate vertex fetching so we need
+ * to take the vcache path when they're in use.
+ */
+static boolean
+any_instance_divisors(const struct draw_context *draw)
+{
+ uint i;
+
+ for (i = 0; i < draw->pt.nr_vertex_elements; i++) {
+ uint div = draw->pt.vertex_element[i].instance_divisor;
+ if (div)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
static INLINE void
vcache_check_run( struct draw_pt_front_end *frontend,
pt_elt_func get_elt,
@@ -382,6 +409,9 @@ vcache_check_run( struct draw_pt_front_end *frontend,
if (max_index >= (unsigned) DRAW_PIPE_MAX_VERTICES)
goto fail;
+ if (any_instance_divisors(draw))
+ goto fail;
+
fetch_count = max_index + 1 - min_index;
if (0)
@@ -518,7 +548,18 @@ vcache_prepare( struct draw_pt_front_end *frontend,
* which is a separate issue.
*/
vcache->input_prim = in_prim;
- vcache->output_prim = u_reduced_prim(in_prim);
+ switch (in_prim) {
+ case PIPE_PRIM_LINES_ADJACENCY:
+ case PIPE_PRIM_LINE_STRIP_ADJACENCY:
+ vcache->output_prim = PIPE_PRIM_LINES_ADJACENCY;
+ break;
+ case PIPE_PRIM_TRIANGLES_ADJACENCY:
+ case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
+ vcache->output_prim = PIPE_PRIM_TRIANGLES_ADJACENCY;
+ break;
+ default:
+ vcache->output_prim = u_reduced_prim(in_prim);
+ }
vcache->middle = middle;
vcache->opt = opt;
diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h b/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h
index dac68ad4398..1a3748d5f0b 100644
--- a/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h
+++ b/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h
@@ -1,198 +1,19 @@
+#define FUNC_VARS \
+ struct draw_pt_front_end *frontend, \
+ pt_elt_func get_elt, \
+ const void *elts, \
+ int elt_bias, \
+ unsigned count
+#define LOCAL_VARS \
+ struct vcache_frontend *vcache = (struct vcache_frontend *) frontend; \
+ struct draw_context *draw = vcache->draw; \
+ const unsigned prim = vcache->input_prim; \
+ const boolean last_vertex_last = !(draw->rasterizer->flatshade && \
+ draw->rasterizer->flatshade_first);
-static void FUNC( struct draw_pt_front_end *frontend,
- pt_elt_func get_elt,
- const void *elts,
- int elt_bias,
- unsigned count )
-{
- struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
- struct draw_context *draw = vcache->draw;
+#define GET_ELT(idx) (get_elt(elts, idx) + elt_bias)
- boolean flatfirst = (draw->rasterizer->flatshade &&
- draw->rasterizer->flatshade_first);
- unsigned i;
- ushort flags;
+#define FUNC_EXIT do { vcache_flush(vcache); } while (0)
- if (0) debug_printf("%s %d\n", __FUNCTION__, count);
-
-
- switch (vcache->input_prim) {
- case PIPE_PRIM_POINTS:
- for (i = 0; i < count; i ++) {
- POINT( vcache,
- get_elt(elts, i + 0) + elt_bias );
- }
- break;
-
- case PIPE_PRIM_LINES:
- for (i = 0; i+1 < count; i += 2) {
- LINE( vcache,
- DRAW_PIPE_RESET_STIPPLE,
- get_elt(elts, i + 0) + elt_bias,
- get_elt(elts, i + 1) + elt_bias);
- }
- break;
-
- case PIPE_PRIM_LINE_LOOP:
- if (count >= 2) {
- flags = DRAW_PIPE_RESET_STIPPLE;
-
- for (i = 1; i < count; i++, flags = 0) {
- LINE( vcache,
- flags,
- get_elt(elts, i - 1) + elt_bias,
- get_elt(elts, i ) + elt_bias);
- }
-
- LINE( vcache,
- flags,
- get_elt(elts, i - 1) + elt_bias,
- get_elt(elts, 0 ) + elt_bias);
- }
- break;
-
- case PIPE_PRIM_LINE_STRIP:
- flags = DRAW_PIPE_RESET_STIPPLE;
- for (i = 1; i < count; i++, flags = 0) {
- LINE( vcache,
- flags,
- get_elt(elts, i - 1) + elt_bias,
- get_elt(elts, i ) + elt_bias);
- }
- break;
-
- case PIPE_PRIM_TRIANGLES:
- for (i = 0; i+2 < count; i += 3) {
- TRIANGLE( vcache,
- DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
- get_elt(elts, i + 0) + elt_bias,
- get_elt(elts, i + 1) + elt_bias,
- get_elt(elts, i + 2 ) + elt_bias);
- }
- break;
-
- case PIPE_PRIM_TRIANGLE_STRIP:
- if (flatfirst) {
- for (i = 0; i+2 < count; i++) {
- TRIANGLE( vcache,
- DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
- get_elt(elts, i + 0) + elt_bias,
- get_elt(elts, i + 1 + (i&1)) + elt_bias,
- get_elt(elts, i + 2 - (i&1)) + elt_bias);
- }
- }
- else {
- for (i = 0; i+2 < count; i++) {
- TRIANGLE( vcache,
- DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
- get_elt(elts, i + 0 + (i&1)) + elt_bias,
- get_elt(elts, i + 1 - (i&1)) + elt_bias,
- get_elt(elts, i + 2 ) + elt_bias);
- }
- }
- break;
-
- case PIPE_PRIM_TRIANGLE_FAN:
- if (count >= 3) {
- if (flatfirst) {
- for (i = 0; i+2 < count; i++) {
- TRIANGLE( vcache,
- DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
- get_elt(elts, i + 1) + elt_bias,
- get_elt(elts, i + 2) + elt_bias,
- get_elt(elts, 0 ) + elt_bias);
- }
- }
- else {
- for (i = 0; i+2 < count; i++) {
- TRIANGLE( vcache,
- DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
- get_elt(elts, 0) + elt_bias,
- get_elt(elts, i + 1) + elt_bias,
- get_elt(elts, i + 2 ) + elt_bias);
- }
- }
- }
- break;
-
-
- case PIPE_PRIM_QUADS:
- for (i = 0; i+3 < count; i += 4) {
- QUAD( vcache,
- get_elt(elts, i + 0) + elt_bias,
- get_elt(elts, i + 1) + elt_bias,
- get_elt(elts, i + 2) + elt_bias,
- get_elt(elts, i + 3) + elt_bias );
- }
- break;
-
- case PIPE_PRIM_QUAD_STRIP:
- for (i = 0; i+3 < count; i += 2) {
- QUAD( vcache,
- get_elt(elts, i + 2) + elt_bias,
- get_elt(elts, i + 0) + elt_bias,
- get_elt(elts, i + 1) + elt_bias,
- get_elt(elts, i + 3) + elt_bias );
- }
- break;
-
- case PIPE_PRIM_POLYGON:
- {
- /* These bitflags look a little odd because we submit the
- * vertices as (1,2,0) to satisfy flatshade requirements.
- */
- ushort edge_next, edge_finish;
-
- if (flatfirst) {
- flags = (DRAW_PIPE_RESET_STIPPLE |
- DRAW_PIPE_EDGE_FLAG_1 |
- DRAW_PIPE_EDGE_FLAG_2);
- edge_next = DRAW_PIPE_EDGE_FLAG_2;
- edge_finish = DRAW_PIPE_EDGE_FLAG_0;
- }
- else {
- flags = (DRAW_PIPE_RESET_STIPPLE |
- DRAW_PIPE_EDGE_FLAG_2 |
- DRAW_PIPE_EDGE_FLAG_0);
- edge_next = DRAW_PIPE_EDGE_FLAG_0;
- edge_finish = DRAW_PIPE_EDGE_FLAG_1;
- }
-
- for (i = 0; i+2 < count; i++, flags = edge_next) {
-
- if (i + 3 == count)
- flags |= edge_finish;
-
- if (flatfirst) {
- TRIANGLE( vcache,
- flags,
- get_elt(elts, 0) + elt_bias,
- get_elt(elts, i + 1) + elt_bias,
- get_elt(elts, i + 2) + elt_bias );
- }
- else {
- TRIANGLE( vcache,
- flags,
- get_elt(elts, i + 1) + elt_bias,
- get_elt(elts, i + 2) + elt_bias,
- get_elt(elts, 0) + elt_bias);
- }
- }
- }
- break;
-
- default:
- assert(0);
- break;
- }
-
- vcache_flush( vcache );
-}
-
-
-#undef TRIANGLE
-#undef QUAD
-#undef POINT
-#undef LINE
-#undef FUNC
+#include "draw_decompose_tmp.h"
diff --git a/src/gallium/auxiliary/draw/draw_so_emit_tmp.h b/src/gallium/auxiliary/draw/draw_so_emit_tmp.h
index 01212a8e536..6d8937a0b41 100644
--- a/src/gallium/auxiliary/draw/draw_so_emit_tmp.h
+++ b/src/gallium/auxiliary/draw/draw_so_emit_tmp.h
@@ -1,123 +1,33 @@
-
-static void FUNC( struct pt_so_emit *so,
- const struct draw_prim_info *input_prims,
- const struct draw_vertex_info *input_verts,
- unsigned start,
- unsigned count)
-{
- struct draw_context *draw = so->draw;
-
- boolean flatfirst = (draw->rasterizer->flatshade &&
- draw->rasterizer->flatshade_first);
- unsigned i;
- LOCAL_VARS
-
- if (0) debug_printf("%s %d\n", __FUNCTION__, count);
-
- debug_assert(input_prims->primitive_count == 1);
-
- switch (input_prims->prim) {
- case PIPE_PRIM_POINTS:
- for (i = 0; i < count; i++) {
- POINT( so, start + i + 0 );
- }
- break;
-
- case PIPE_PRIM_LINES:
- for (i = 0; i+1 < count; i += 2) {
- LINE( so , start + i + 0 , start + i + 1 );
- }
- break;
-
- case PIPE_PRIM_LINE_LOOP:
- if (count >= 2) {
-
- for (i = 1; i < count; i++) {
- LINE( so, start + i - 1, start + i );
- }
-
- LINE( so, start + i - 1, start );
- }
- break;
-
- case PIPE_PRIM_LINE_STRIP:
- for (i = 1; i < count; i++) {
- LINE( so, start + i - 1, start + i );
- }
- break;
-
- case PIPE_PRIM_TRIANGLES:
- for (i = 0; i+2 < count; i += 3) {
- TRIANGLE( so, start + i + 0, start + i + 1, start + i + 2 );
- }
- break;
-
- case PIPE_PRIM_TRIANGLE_STRIP:
- if (flatfirst) {
- for (i = 0; i+2 < count; i++) {
- TRIANGLE( so,
- start + i + 0,
- start + i + 1 + (i&1),
- start + i + 2 - (i&1) );
- }
- }
- else {
- for (i = 0; i+2 < count; i++) {
- TRIANGLE( so,
- start + i + 0 + (i&1),
- start + i + 1 - (i&1),
- start + i + 2 );
- }
- }
- break;
-
- case PIPE_PRIM_TRIANGLE_FAN:
- if (count >= 3) {
- if (flatfirst) {
- for (i = 0; i+2 < count; i++) {
- TRIANGLE( so,
- start + i + 1,
- start + i + 2,
- start );
- }
- }
- else {
- for (i = 0; i+2 < count; i++) {
- TRIANGLE( so,
- start,
- start + i + 1,
- start + i + 2 );
- }
- }
- }
- break;
-
- case PIPE_PRIM_POLYGON:
- {
- /* These bitflags look a little odd because we submit the
- * vertices as (1,2,0) to satisfy flatshade requirements.
- */
-
- for (i = 0; i+2 < count; i++) {
-
- if (flatfirst) {
- TRIANGLE( so, start + 0, start + i + 1, start + i + 2 );
- }
- else {
- TRIANGLE( so, start + i + 1, start + i + 2, start + 0 );
- }
- }
- }
- break;
-
- default:
- debug_assert(!"Unsupported primitive in stream output");
- break;
- }
-}
-
-
-#undef TRIANGLE
-#undef POINT
-#undef LINE
-#undef FUNC
+#define FUNC_VARS \
+ struct pt_so_emit *so, \
+ const struct draw_prim_info *input_prims, \
+ const struct draw_vertex_info *input_verts, \
+ unsigned start, \
+ unsigned count
+
+#define FUNC_ENTER \
+ /* declare more local vars */ \
+ struct draw_context *draw = so->draw; \
+ const unsigned prim = input_prims->prim; \
+ const boolean last_vertex_last = \
+ !(draw->rasterizer->flatshade && \
+ draw->rasterizer->flatshade_first); \
+ do { \
+ debug_assert(input_prims->primitive_count == 1); \
+ switch (prim) { \
+ case PIPE_PRIM_LINES_ADJACENCY: \
+ case PIPE_PRIM_LINE_STRIP_ADJACENCY: \
+ case PIPE_PRIM_TRIANGLES_ADJACENCY: \
+ case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: \
+ debug_assert(!"unexpected primitive type in stream output"); \
+ return; \
+ default: \
+ break; \
+ } \
+ } while (0) \
+
+#define POINT(i0) so_point(so,i0)
+#define LINE(flags,i0,i1) so_line(so,i0,i1)
+#define TRIANGLE(flags,i0,i1,i2) so_tri(so,i0,i1,i2)
+
+#include "draw_decompose_tmp.h"
diff --git a/src/gallium/auxiliary/draw/draw_vertex.h b/src/gallium/auxiliary/draw/draw_vertex.h
index 3af31ffe126..e63cf5f4f98 100644
--- a/src/gallium/auxiliary/draw/draw_vertex.h
+++ b/src/gallium/auxiliary/draw/draw_vertex.h
@@ -166,7 +166,7 @@ static INLINE enum pipe_format draw_translate_vinfo_format(enum attrib_emit emit
}
}
-static INLINE enum attrib_emit draw_translate_vinfo_size(enum attrib_emit emit)
+static INLINE unsigned draw_translate_vinfo_size(enum attrib_emit emit)
{
switch (emit) {
case EMIT_OMIT:
diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c
index 57ea63fc060..fb665b08fff 100644
--- a/src/gallium/auxiliary/draw/draw_vs.c
+++ b/src/gallium/auxiliary/draw/draw_vs.c
@@ -48,18 +48,30 @@
DEBUG_GET_ONCE_BOOL_OPTION(gallium_dump_vs, "GALLIUM_DUMP_VS", FALSE)
+
+/**
+ * Set a vertex shader constant buffer.
+ * \param slot which constant buffer in [0, PIPE_MAX_CONSTANT_BUFFERS-1]
+ * \param constants the mapped buffer
+ * \param size size of buffer in bytes
+ */
void
draw_vs_set_constants(struct draw_context *draw,
unsigned slot,
const void *constants,
unsigned size)
{
- if (((uintptr_t)constants) & 0xf) {
+ const int alignment = 16;
+
+ /* check if buffer is 16-byte aligned */
+ if (((uintptr_t)constants) & (alignment - 1)) {
+ /* if not, copy the constants into a new, 16-byte aligned buffer */
if (size > draw->vs.const_storage_size[slot]) {
if (draw->vs.aligned_constant_storage[slot]) {
align_free((void *)draw->vs.aligned_constant_storage[slot]);
}
- draw->vs.aligned_constant_storage[slot] = align_malloc(size, 16);
+ draw->vs.aligned_constant_storage[slot] =
+ align_malloc(size, alignment);
}
assert(constants);
memcpy((void *)draw->vs.aligned_constant_storage[slot],
diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h
index a7319945234..f9a038788fb 100644
--- a/src/gallium/auxiliary/draw/draw_vs.h
+++ b/src/gallium/auxiliary/draw/draw_vs.h
@@ -133,7 +133,8 @@ struct draw_vertex_shader {
void (*run_linear)( struct draw_vertex_shader *shader,
const float (*input)[4],
float (*output)[4],
- const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
+ const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
+ const unsigned const_size[PIPE_MAX_CONSTANT_BUFFERS],
unsigned count,
unsigned input_stride,
unsigned output_stride );
diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c
index bc34d390dae..dab3eb1ca8e 100644
--- a/src/gallium/auxiliary/draw/draw_vs_exec.c
+++ b/src/gallium/auxiliary/draw/draw_vs_exec.c
@@ -85,7 +85,8 @@ static void
vs_exec_run_linear( struct draw_vertex_shader *shader,
const float (*input)[4],
float (*output)[4],
- const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
+ const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
+ const unsigned const_size[PIPE_MAX_CONSTANT_BUFFERS],
unsigned count,
unsigned input_stride,
unsigned output_stride )
@@ -95,9 +96,8 @@ vs_exec_run_linear( struct draw_vertex_shader *shader,
unsigned int i, j;
unsigned slot;
- for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
- machine->Consts[i] = constants[i];
- }
+ tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS,
+ constants, const_size);
for (i = 0; i < count; i += MAX_TGSI_VERTICES) {
unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i);
diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c
index 6c13df79132..d13ad24fff0 100644
--- a/src/gallium/auxiliary/draw/draw_vs_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c
@@ -49,6 +49,7 @@ vs_llvm_run_linear( struct draw_vertex_shader *shader,
const float (*input)[4],
float (*output)[4],
const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
+ const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS],
unsigned count,
unsigned input_stride,
unsigned output_stride )
diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c
index 14c95082a9d..0b0c6077c6f 100644
--- a/src/gallium/auxiliary/draw/draw_vs_sse.c
+++ b/src/gallium/auxiliary/draw/draw_vs_sse.c
@@ -84,6 +84,7 @@ vs_sse_run_linear( struct draw_vertex_shader *base,
const float (*input)[4],
float (*output)[4],
const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
+ const unsigned const_size[PIPE_MAX_CONSTANT_BUFFERS],
unsigned count,
unsigned input_stride,
unsigned output_stride )
diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c
index 6eb26927f27..eacd1601877 100644
--- a/src/gallium/auxiliary/draw/draw_vs_varient.c
+++ b/src/gallium/auxiliary/draw/draw_vs_varient.c
@@ -149,7 +149,8 @@ static void PIPE_CDECL vsvg_run_elts( struct draw_vs_varient *varient,
vsvg->base.vs->run_linear( vsvg->base.vs,
temp_buffer,
temp_buffer,
- vsvg->base.vs->draw->pt.user.vs_constants,
+ vsvg->base.vs->draw->pt.user.vs_constants,
+ vsvg->base.vs->draw->pt.user.vs_constants_size,
count,
temp_vertex_stride,
temp_vertex_stride);
@@ -214,7 +215,8 @@ static void PIPE_CDECL vsvg_run_linear( struct draw_vs_varient *varient,
vsvg->base.vs->run_linear( vsvg->base.vs,
temp_buffer,
temp_buffer,
- vsvg->base.vs->draw->pt.user.vs_constants,
+ vsvg->base.vs->draw->pt.user.vs_constants,
+ vsvg->base.vs->draw->pt.user.vs_constants_size,
count,
temp_vertex_stride,
temp_vertex_stride);