#include "sp_quad.h"
#include "sp_prim_setup.h"
#include "pipe/draw/draw_private.h"
-#include "pipe/p_util.h"
-
#include "pipe/draw/draw_vertex.h"
+#include "pipe/p_util.h"
+#define DEBUG_VERTS 0
/**
* Triangle edge info
float oneoverarea;
- const unsigned *lookup; /**< vertex attribute positions */
-
- struct tgsi_interp_coef coef[TGSI_ATTRIB_MAX];
+ struct tgsi_interp_coef coef[PIPE_MAX_SHADER_INPUTS];
struct quad_header quad;
struct {
setup->span.right[1] = 0;
}
-#if 0
+#if DEBUG_VERTS
static void print_vertex(const struct setup_stage *setup,
const struct vertex_header *v)
{
int i;
- printf("Vertex:\n");
- for (i = 0; i < setup->softpipe->nr_attrs; i++) {
- printf(" %d: %f %f %f\n", i,
- v->data[i][0], v->data[i][1], v->data[i][2]);
+ fprintf(stderr, "Vertex: (%p)\n", v);
+ for (i = 0; i < setup->quad.nr_attrs; i++) {
+ fprintf(stderr, " %d: %f %f %f %f\n", i,
+ v->data[i][0], v->data[i][1], v->data[i][2], v->data[i][3]);
}
}
#endif
const struct vertex_header *v1 = prim->v[1];
const struct vertex_header *v2 = prim->v[2];
-#if 0
- printf("Triangle:\n");
+#if DEBUG_VERTS
+ fprintf(stderr, "Triangle:\n");
print_vertex(setup, v0);
print_vertex(setup, v1);
print_vertex(setup, v2);
* - the GLSL gl_FrontFacing fragment attribute (bool)
* - two-sided stencil test
*/
- setup->quad.facing = (prim->det > 0.0) ^ (setup->softpipe->setup.front_winding == PIPE_WINDING_CW);
+ setup->quad.facing = (prim->det > 0.0) ^ (setup->softpipe->rasterizer->front_winding == PIPE_WINDING_CW);
return TRUE;
}
unsigned slot,
unsigned i )
{
- assert(slot < TGSI_ATTRIB_MAX);
+ assert(slot < PIPE_MAX_SHADER_INPUTS);
assert(i <= 3);
setup->coef[slot].dadx[i] = 0;
float a = setup->ebot.dy * majda - botda * setup->emaj.dy;
float b = setup->emaj.dx * botda - majda * setup->ebot.dx;
- assert(slot < TGSI_ATTRIB_MAX);
+ assert(slot < PIPE_MAX_SHADER_INPUTS);
assert(i <= 3);
setup->coef[slot].dadx[i] = a * setup->oneoverarea;
/**
* Compute a0, dadx and dady for a perspective-corrected interpolant,
* for a triangle.
+ * We basically multiply the vertex value by 1/w before computing
+ * the plane coefficients (a0, dadx, dady).
+ * Later, when we compute the value at a particular fragment position we'll
+ * divide the interpolated value by the interpolated W at that fragment.
*/
static void tri_persp_coeff( struct setup_stage *setup,
unsigned slot,
float a = setup->ebot.dy * majda - botda * setup->emaj.dy;
float b = setup->emaj.dx * botda - majda * setup->ebot.dx;
- assert(slot < TGSI_ATTRIB_MAX);
+ /*
+ printf("tri persp %d,%d: %f %f %f\n", slot, i,
+ setup->vmin->data[slot][i],
+ setup->vmid->data[slot][i],
+ setup->vmax->data[slot][i]
+ );
+ */
+
+ assert(slot < PIPE_MAX_SHADER_INPUTS);
assert(i <= 3);
setup->coef[slot].dadx[i] = a * setup->oneoverarea;
*/
static void setup_tri_coefficients( struct setup_stage *setup )
{
- const enum interp_mode *interp = setup->softpipe->vertex_info.interp_mode;
+ const interp_mode *interp = setup->softpipe->vertex_info.interp_mode;
unsigned slot, j;
/* z and w are done by linear interpolation:
static INLINE void
setup_line_coefficients(struct setup_stage *setup, struct prim_header *prim)
{
- const enum interp_mode *interp = setup->softpipe->vertex_info.interp_mode;
+ const interp_mode *interp = setup->softpipe->vertex_info.interp_mode;
unsigned slot, j;
/* use setup->vmin, vmax to point to vertices */
const int errorDec = error - dx;
for (i = 0; i < dx; i++) {
- if (!sp->setup.line_stipple_enable ||
+ if (!sp->rasterizer->line_stipple_enable ||
stipple_test(sp->line_stipple_counter,
- sp->setup.line_stipple_pattern,
- sp->setup.line_stipple_factor + 1)) {
+ sp->rasterizer->line_stipple_pattern,
+ sp->rasterizer->line_stipple_factor + 1)) {
plot(setup, x0, y0);
}
const int errorDec = error - dy;
for (i = 0; i < dy; i++) {
- if (!sp->setup.line_stipple_enable ||
+ if (!sp->rasterizer->line_stipple_enable ||
stipple_test(sp->line_stipple_counter,
- sp->setup.line_stipple_pattern,
- sp->setup.line_stipple_factor + 1)) {
+ sp->rasterizer->line_stipple_pattern,
+ sp->rasterizer->line_stipple_factor + 1)) {
plot(setup, x0, y0);
}
{
struct setup_stage *setup = setup_stage( stage );
const struct vertex_header *v0 = prim->v[0];
-
- const int sizeAttr = setup->lookup[TGSI_ATTRIB_POINTSIZE];
+ const int sizeAttr = setup->softpipe->psize_slot;
const float halfSize
- = sizeAttr ? (0.5f * v0->data[sizeAttr][0])
- : (0.5f * setup->softpipe->setup.point_size);
- const boolean round = setup->softpipe->setup.point_smooth;
- const float x = v0->data[TGSI_ATTRIB_POS][0];
- const float y = v0->data[TGSI_ATTRIB_POS][1];
+ = sizeAttr > 0 ? (0.5f * v0->data[sizeAttr][0])
+ : (0.5f * setup->softpipe->rasterizer->point_size);
+ const boolean round = setup->softpipe->rasterizer->point_smooth;
+ const float x = v0->data[0][0]; /* Note: data[0] is always position */
+ const float y = v0->data[0][1];
unsigned slot, j;
/* For points, all interpolants are constant-valued.
setup->quad.coef = setup->coef;
- setup->lookup = softpipe->draw->vertex_info.attrib_to_slot;
-
return &setup->stage;
}
+
+
+/* Recalculate det. This is only used in the test harness below:
+ */
+static void calc_det( struct prim_header *header )
+{
+ /* Window coords: */
+ const float *v0 = header->v[0]->data[0];
+ const float *v1 = header->v[1]->data[0];
+ const float *v2 = header->v[2]->data[0];
+
+ /* edge vectors e = v0 - v2, f = v1 - v2 */
+ const float ex = v0[0] - v2[0];
+ const float ey = v0[1] - v2[1];
+ const float fx = v1[0] - v2[0];
+ const float fy = v1[1] - v2[1];
+
+ /* det = cross(e,f).z */
+ header->det = ex * fy - ey * fx;
+}
+
+
+
+/* Test harness - feed vertex buffer back into prim pipeline.
+ *
+ * The big issue at this point is that reset_stipple doesn't make it
+ * through the interface. Probably need to split primitives at reset
+ * stipple, perhaps using the ~0 index marker.
+ */
+void sp_vbuf_setup_draw( struct pipe_context *pipe,
+ unsigned primitive,
+ const ushort *elements,
+ unsigned nr_elements,
+ const void *vertex_buffer,
+ unsigned nr_vertices )
+{
+ struct softpipe_context *softpipe = softpipe_context( pipe );
+ struct setup_stage *setup = setup_stage( softpipe->setup );
+ struct prim_header prim;
+ unsigned vertex_size = setup->stage.draw->vertex_info.size * sizeof(float);
+ int i, j;
+
+ prim.det = 0;
+ prim.reset_line_stipple = 0;
+ prim.edgeflags = 0;
+ prim.pad = 0;
+
+ setup->stage.begin( &setup->stage );
+
+ switch (primitive) {
+ case PIPE_PRIM_TRIANGLES:
+ for (i = 0; i < nr_elements; i += 3) {
+ for (j = 0; j < 3; j++)
+ prim.v[j] = (struct vertex_header *)((char *)vertex_buffer +
+ elements[i+j] * vertex_size);
+
+ calc_det(&prim);
+ setup->stage.tri( &setup->stage, &prim );
+ }
+ break;
+
+ case PIPE_PRIM_LINES:
+ for (i = 0; i < nr_elements; i += 2) {
+ for (j = 0; j < 2; j++)
+ prim.v[j] = (struct vertex_header *)((char *)vertex_buffer +
+ elements[i+j] * vertex_size);
+
+ setup->stage.line( &setup->stage, &prim );
+ }
+ break;
+
+ case PIPE_PRIM_POINTS:
+ for (i = 0; i < nr_elements; i += 2) {
+ prim.v[i] = (struct vertex_header *)((char *)vertex_buffer +
+ elements[i] * vertex_size);
+ setup->stage.point( &setup->stage, &prim );
+ }
+ break;
+ }
+
+ setup->stage.end( &setup->stage );
+}