mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 10:50:10 +01:00
Cell: draw smooth-shaded triangle
This commit is contained in:
parent
9828310a1b
commit
b2ad30d571
4 changed files with 120 additions and 60 deletions
|
|
@ -75,10 +75,8 @@ struct cell_command_clear_tiles
|
|||
|
||||
struct cell_command_triangle
|
||||
{
|
||||
float x0, y0;
|
||||
float x1, y1;
|
||||
float x2, y2;
|
||||
uint color;
|
||||
float vert[3][4];
|
||||
float color[3][4];
|
||||
} ALIGN16_ATTRIB;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -69,20 +69,31 @@ cell_clear_surface(struct pipe_context *pipe, struct pipe_surface *ps,
|
|||
#if 1
|
||||
/* XXX Draw a test triangle over the cleared surface */
|
||||
for (i = 0; i < cell->num_spus; i++) {
|
||||
/* Same triangle data for all SPUs, of course: */
|
||||
/* Same triangle data for all SPUs */
|
||||
struct cell_command_triangle *tri = &cell_global.command[i].tri;
|
||||
tri->vert[0][0] = 20.0;
|
||||
tri->vert[0][1] = ps->height - 20;
|
||||
|
||||
tri->x0 = 20.0;
|
||||
tri->y0 = ps->height - 20;
|
||||
tri->vert[1][0] = ps->width - 20.0;
|
||||
tri->vert[1][1] = ps->height - 20;
|
||||
|
||||
tri->x1 = ps->width - 20.0;
|
||||
tri->y1 = ps->height - 20;
|
||||
tri->vert[2][0] = ps->width / 2;
|
||||
tri->vert[2][1] = 20.0;
|
||||
|
||||
tri->x2 = ps->width / 2;
|
||||
tri->y2 = 20.0;
|
||||
tri->color[0][0] = 1.0;
|
||||
tri->color[0][1] = 0.0;
|
||||
tri->color[0][2] = 0.0;
|
||||
tri->color[0][3] = 0.0;
|
||||
|
||||
/* XXX color varies per SPU */
|
||||
tri->color = 0xffff00 | ((i*40)<<24); /* yellow */
|
||||
tri->color[1][0] = 0.0;
|
||||
tri->color[1][1] = 1.0;
|
||||
tri->color[1][2] = 0.0;
|
||||
tri->color[1][3] = 0.0;
|
||||
|
||||
tri->color[2][0] = 0.0;
|
||||
tri->color[2][1] = 0.0;
|
||||
tri->color[2][2] = 1.0;
|
||||
tri->color[2][3] = 0.0;
|
||||
|
||||
send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_TRIANGLE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -138,13 +138,13 @@ triangle(const struct cell_command_triangle *tri)
|
|||
struct prim_header prim;
|
||||
uint i;
|
||||
|
||||
prim.v[0].data[0][0] = tri->x0;
|
||||
prim.v[0].data[0][1] = tri->y0;
|
||||
prim.v[1].data[0][0] = tri->x1;
|
||||
prim.v[1].data[0][1] = tri->y1;
|
||||
prim.v[2].data[0][0] = tri->x2;
|
||||
prim.v[2].data[0][1] = tri->y2;
|
||||
prim.color = tri->color;
|
||||
COPY_4V(prim.v[0].data[0], tri->vert[0]);
|
||||
COPY_4V(prim.v[1].data[0], tri->vert[1]);
|
||||
COPY_4V(prim.v[2].data[0], tri->vert[2]);
|
||||
|
||||
COPY_4V(prim.v[0].data[1], tri->color[0]);
|
||||
COPY_4V(prim.v[1].data[1], tri->color[1]);
|
||||
COPY_4V(prim.v[2].data[1], tri->color[2]);
|
||||
|
||||
for (i = init.id; i < num_tiles; i += init.num_spus) {
|
||||
uint tx = i % fb.width_tiles;
|
||||
|
|
@ -212,11 +212,7 @@ main_loop(void)
|
|||
clear_tiles(&cmd.clear);
|
||||
break;
|
||||
case CELL_CMD_TRIANGLE:
|
||||
printf("SPU %u: TRIANGLE (%g,%g) (%g,%g) (%g,%g)\n",
|
||||
init.id,
|
||||
cmd.tri.x0, cmd.tri.y0,
|
||||
cmd.tri.x1, cmd.tri.y1,
|
||||
cmd.tri.x2, cmd.tri.y2);
|
||||
printf("SPU %u: TRIANGLE\n", init.id);
|
||||
triangle(&cmd.tri);
|
||||
break;
|
||||
case CELL_CMD_FINISH:
|
||||
|
|
|
|||
|
|
@ -46,6 +46,11 @@
|
|||
#include "main.h"
|
||||
#include "tri.h"
|
||||
|
||||
/*
|
||||
#include <vmx2spu.h>
|
||||
#include <spu_internals.h>
|
||||
*/
|
||||
|
||||
|
||||
#if 1
|
||||
|
||||
|
|
@ -64,6 +69,8 @@
|
|||
#define MASK_BOTTOM_RIGHT (1 << QUAD_BOTTOM_RIGHT)
|
||||
#define MASK_ALL 0xf
|
||||
|
||||
#define PIPE_MAX_SHADER_INPUTS 8 /* XXX temp */
|
||||
|
||||
static int cliprect_minx, cliprect_maxx, cliprect_miny, cliprect_maxy;
|
||||
|
||||
static uint tile[TILE_SIZE][TILE_SIZE] ALIGN16_ATTRIB;
|
||||
|
|
@ -85,6 +92,13 @@ struct edge {
|
|||
};
|
||||
|
||||
|
||||
struct interp_coef
|
||||
{
|
||||
float a0[4];
|
||||
float dadx[4];
|
||||
float dady[4];
|
||||
};
|
||||
|
||||
/**
|
||||
* Triangle setup info (derived from draw_stage).
|
||||
* Also used for line drawing (taking some liberties).
|
||||
|
|
@ -113,7 +127,10 @@ struct setup_stage {
|
|||
|
||||
#if 0
|
||||
struct tgsi_interp_coef coef[PIPE_MAX_SHADER_INPUTS];
|
||||
#else
|
||||
struct interp_coef coef[PIPE_MAX_SHADER_INPUTS];
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
struct quad_header quad;
|
||||
#endif
|
||||
|
|
@ -188,6 +205,41 @@ clip_emit_quad(struct setup_stage *setup)
|
|||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Evaluate attribute coefficients (plane equations) to compute
|
||||
* attribute values for the four fragments in a quad.
|
||||
* Eg: four colors will be compute.
|
||||
*/
|
||||
static INLINE void
|
||||
eval_coeff( struct setup_stage *setup, uint slot,
|
||||
float x, float y, float result[4][4])
|
||||
{
|
||||
uint i;
|
||||
const float *dadx = setup->coef[slot].dadx;
|
||||
const float *dady = setup->coef[slot].dady;
|
||||
|
||||
/* loop over XYZW comps */
|
||||
for (i = 0; i < 4; i++) {
|
||||
result[QUAD_TOP_LEFT][i] = setup->coef[slot].a0[i] + x * dadx[i] + y * dady[i];
|
||||
result[QUAD_TOP_RIGHT][i] = result[0][i] + dadx[i];
|
||||
result[QUAD_BOTTOM_LEFT][i] = result[0][i] + dady[i];
|
||||
result[QUAD_BOTTOM_RIGHT][i] = result[0][i] + dadx[i] + dady[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static INLINE uint
|
||||
pack_color(const float color[4])
|
||||
{
|
||||
uint r = (uint) (color[0] * 255.0);
|
||||
uint g = (uint) (color[1] * 255.0);
|
||||
uint b = (uint) (color[2] * 255.0);
|
||||
uint a = (uint) (color[3] * 255.0);
|
||||
uint icolor = (b << 24) | (g << 16) | (r << 8) | a;
|
||||
return icolor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Emit a quad (pass to next stage). No clipping is done.
|
||||
*/
|
||||
|
|
@ -204,14 +256,18 @@ emit_quad( struct setup_stage *setup, int x, int y, unsigned mask )
|
|||
/* Cell: "write" quad fragments to the tile by setting prim color */
|
||||
int ix = x - cliprect_minx;
|
||||
int iy = y - cliprect_miny;
|
||||
float colors[4][4];
|
||||
|
||||
eval_coeff(setup, 1, (float) x, (float) y, colors);
|
||||
|
||||
if (mask & MASK_TOP_LEFT)
|
||||
tile[iy][ix] = setup->color;
|
||||
tile[iy][ix] = pack_color(colors[QUAD_TOP_LEFT]);
|
||||
if (mask & MASK_TOP_RIGHT)
|
||||
tile[iy][ix+1] = setup->color;
|
||||
tile[iy][ix+1] = pack_color(colors[QUAD_TOP_RIGHT]);
|
||||
if (mask & MASK_BOTTOM_LEFT)
|
||||
tile[iy+1][ix] = setup->color;
|
||||
tile[iy+1][ix] = pack_color(colors[QUAD_BOTTOM_LEFT]);
|
||||
if (mask & MASK_BOTTOM_RIGHT)
|
||||
tile[iy+1][ix+1] = setup->color;
|
||||
tile[iy+1][ix+1] = pack_color(colors[QUAD_BOTTOM_RIGHT]);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -445,41 +501,41 @@ static void const_coeff( struct setup_stage *setup,
|
|||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Compute a0, dadx and dady for a linearly interpolated coefficient,
|
||||
* for a triangle.
|
||||
*/
|
||||
static void tri_linear_coeff( struct setup_stage *setup,
|
||||
unsigned slot,
|
||||
unsigned i)
|
||||
unsigned slot )
|
||||
{
|
||||
float botda = setup->vmid->data[slot][i] - setup->vmin->data[slot][i];
|
||||
float majda = setup->vmax->data[slot][i] - setup->vmin->data[slot][i];
|
||||
float a = setup->ebot.dy * majda - botda * setup->emaj.dy;
|
||||
float b = setup->emaj.dx * botda - majda * setup->ebot.dx;
|
||||
uint i;
|
||||
for (i = 0; i < 4; i++) {
|
||||
float botda = setup->vmid->data[slot][i] - setup->vmin->data[slot][i];
|
||||
float majda = setup->vmax->data[slot][i] - setup->vmin->data[slot][i];
|
||||
float a = setup->ebot.dy * majda - botda * setup->emaj.dy;
|
||||
float b = setup->emaj.dx * botda - majda * setup->ebot.dx;
|
||||
|
||||
assert(slot < PIPE_MAX_SHADER_INPUTS);
|
||||
assert(i <= 3);
|
||||
assert(slot < PIPE_MAX_SHADER_INPUTS);
|
||||
|
||||
setup->coef[slot].dadx[i] = a * setup->oneoverarea;
|
||||
setup->coef[slot].dady[i] = b * setup->oneoverarea;
|
||||
setup->coef[slot].dadx[i] = a * setup->oneoverarea;
|
||||
setup->coef[slot].dady[i] = b * setup->oneoverarea;
|
||||
|
||||
/* calculate a0 as the value which would be sampled for the
|
||||
* fragment at (0,0), taking into account that we want to sample at
|
||||
* pixel centers, in other words (0.5, 0.5).
|
||||
*
|
||||
* this is neat but unfortunately not a good way to do things for
|
||||
* triangles with very large values of dadx or dady as it will
|
||||
* result in the subtraction and re-addition from a0 of a very
|
||||
* large number, which means we'll end up loosing a lot of the
|
||||
* fractional bits and precision from a0. the way to fix this is
|
||||
* to define a0 as the sample at a pixel center somewhere near vmin
|
||||
* instead - i'll switch to this later.
|
||||
*/
|
||||
setup->coef[slot].a0[i] = (setup->vmin->data[slot][i] -
|
||||
(setup->coef[slot].dadx[i] * (setup->vmin->data[0][0] - 0.5f) +
|
||||
setup->coef[slot].dady[i] * (setup->vmin->data[0][1] - 0.5f)));
|
||||
/* calculate a0 as the value which would be sampled for the
|
||||
* fragment at (0,0), taking into account that we want to sample at
|
||||
* pixel centers, in other words (0.5, 0.5).
|
||||
*
|
||||
* this is neat but unfortunately not a good way to do things for
|
||||
* triangles with very large values of dadx or dady as it will
|
||||
* result in the subtraction and re-addition from a0 of a very
|
||||
* large number, which means we'll end up loosing a lot of the
|
||||
* fractional bits and precision from a0. the way to fix this is
|
||||
* to define a0 as the sample at a pixel center somewhere near vmin
|
||||
* instead - i'll switch to this later.
|
||||
*/
|
||||
setup->coef[slot].a0[i] = (setup->vmin->data[slot][i] -
|
||||
(setup->coef[slot].dadx[i] * (setup->vmin->data[0][0] - 0.5f) +
|
||||
setup->coef[slot].dady[i] * (setup->vmin->data[0][1] - 0.5f)));
|
||||
}
|
||||
|
||||
/*
|
||||
_mesa_printf("attr[%d].%c: %f dx:%f dy:%f\n",
|
||||
|
|
@ -489,7 +545,6 @@ static void tri_linear_coeff( struct setup_stage *setup,
|
|||
setup->coef[slot].dady[i]);
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
|
|
@ -536,13 +591,13 @@ static void tri_persp_coeff( struct setup_stage *setup,
|
|||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Compute the setup->coef[] array dadx, dady, a0 values.
|
||||
* Must be called after setup->vmin,vmid,vmax,vprovoke are initialized.
|
||||
*/
|
||||
static void setup_tri_coefficients( struct setup_stage *setup )
|
||||
{
|
||||
#if 0
|
||||
const enum interp_mode *interp = setup->softpipe->vertex_info.interp_mode;
|
||||
unsigned slot, j;
|
||||
|
||||
|
|
@ -575,8 +630,10 @@ static void setup_tri_coefficients( struct setup_stage *setup )
|
|||
assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
tri_linear_coeff(setup, 1); /* slot 1 = color */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void setup_tri_edges( struct setup_stage *setup )
|
||||
|
|
@ -710,9 +767,7 @@ static void setup_tri(
|
|||
*/
|
||||
|
||||
setup_sort_vertices( setup, prim );
|
||||
#if 0
|
||||
setup_tri_coefficients( setup );
|
||||
#endif
|
||||
setup_tri_edges( setup );
|
||||
|
||||
#if 0
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue