Merge branch 'gallium-0.1' of git+ssh://marcheu@git.freedesktop.org/git/nouveau/mesa into gallium-0.1

This commit is contained in:
Stephane Marchesin 2008-04-02 05:10:52 +02:00
commit 901700888e
51 changed files with 715 additions and 902 deletions

View file

@ -15,7 +15,6 @@ C_SOURCES = \
draw_debug.c \
draw_flatshade.c \
draw_offset.c \
draw_passthrough.c \
draw_pt.c \
draw_pt_vcache.c \
draw_pt_fetch_emit.c \

View file

@ -14,7 +14,6 @@ draw = env.ConvenienceLibrary(
'draw_debug.c',
'draw_flatshade.c',
'draw_offset.c',
'draw_passthrough.c', # going away soon
'draw_pt.c',
'draw_pt_vcache.c',
'draw_pt_fetch_emit.c',

View file

@ -228,6 +228,14 @@ void draw_set_viewport_state( struct draw_context *draw,
{
draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
draw->viewport = *viewport; /* struct copy */
draw->identity_viewport = (viewport->scale[0] == 1.0f &&
viewport->scale[1] == 1.0f &&
viewport->scale[2] == 1.0f &&
viewport->scale[3] == 1.0f &&
viewport->translate[0] == 0.0f &&
viewport->translate[1] == 0.0f &&
viewport->translate[2] == 0.0f &&
viewport->translate[3] == 0.0f);
}

View file

@ -84,8 +84,25 @@ static INLINE void copy_colors2( struct draw_stage *stage,
* Flatshade tri. Required for clipping and when unfilled tris are
* active, otherwise handled by hardware.
*/
static void flatshade_tri( struct draw_stage *stage,
struct prim_header *header )
static void flatshade_tri_0( struct draw_stage *stage,
struct prim_header *header )
{
struct prim_header tmp;
tmp.det = header->det;
tmp.edgeflags = header->edgeflags;
tmp.v[0] = header->v[0];
tmp.v[1] = dup_vert(stage, header->v[1], 0);
tmp.v[2] = dup_vert(stage, header->v[2], 1);
copy_colors2(stage, tmp.v[1], tmp.v[2], tmp.v[0]);
stage->next->tri( stage->next, &tmp );
}
static void flatshade_tri_2( struct draw_stage *stage,
struct prim_header *header )
{
struct prim_header tmp;
@ -101,11 +118,27 @@ static void flatshade_tri( struct draw_stage *stage,
}
/**
* Flatshade line. Required for clipping.
*/
static void flatshade_line( struct draw_stage *stage,
struct prim_header *header )
static void flatshade_line_0( struct draw_stage *stage,
struct prim_header *header )
{
struct prim_header tmp;
tmp.v[0] = header->v[0];
tmp.v[1] = dup_vert(stage, header->v[1], 0);
copy_colors(stage, tmp.v[1], tmp.v[0]);
stage->next->line( stage->next, &tmp );
}
static void flatshade_line_1( struct draw_stage *stage,
struct prim_header *header )
{
struct prim_header tmp;
@ -118,6 +151,8 @@ static void flatshade_line( struct draw_stage *stage,
}
/* Flatshade point -- passthrough.
*/
static void flatshade_point( struct draw_stage *stage,
struct prim_header *header )
{
@ -140,8 +175,16 @@ static void flatshade_init_state( struct draw_stage *stage )
}
}
stage->line = flatshade_line;
stage->tri = flatshade_tri;
/* Choose flatshade routine according to provoking vertex:
*/
if (stage->draw->rasterizer->flatshade_first) {
stage->line = flatshade_line_0;
stage->tri = flatshade_tri_0;
}
else {
stage->line = flatshade_line_1;
stage->tri = flatshade_tri_2;
}
}
static void flatshade_first_tri( struct draw_stage *stage,

View file

@ -1,473 +0,0 @@
/**************************************************************************
*
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* 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, sub license, 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 (including the
* next paragraph) 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 NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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 <keith@tungstengraphics.com>
*/
/* This code is a prototype of what a passhthrough vertex shader might
* look like.
*
* Probably the best approach for us is to do:
* - vertex fetch
* - vertex shader
* - cliptest / viewport transform
*
* in one step, then examine the clipOrMask & choose between two paths:
*
* Either:
* - build primitive headers
* - clip and the primitive path
* - build clipped vertex buffers,
* - vertex-emit to vbuf buffers
*
* Or, if no clipping:
* - vertex-emit directly to vbuf buffers
*
* But when bypass clipping is enabled, we just take the latter
* choice. If (some new) passthrough-vertex-shader flag is also set,
* the pipeline degenerates to:
*
* - vertex fetch
* - vertex emit to vbuf buffers
*
* Which is what is prototyped here.
*/
#include "pipe/p_util.h"
#include "draw/draw_context.h"
#include "draw/draw_private.h"
#include "draw/draw_vbuf.h"
#include "draw/draw_vertex.h"
/**
* General-purpose fetch from user's vertex arrays, emit to driver's
* vertex buffer.
*
* XXX this is totally temporary.
*/
static void
fetch_store_general( struct draw_context *draw,
float *out,
unsigned start,
unsigned count )
{
const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render);
const unsigned nr_attrs = vinfo->num_attribs;
uint i, j;
const unsigned *pitch = draw->vertex_fetch.pitch;
const ubyte **src = draw->vertex_fetch.src_ptr;
for (i = start; i < start + count; i++) {
for (j = 0; j < nr_attrs; j++) {
/* vinfo->src_index is the output of the vertex shader
* matching this hw-vertex component.
*
* In passthrough, we require a 1:1 mapping between vertex
* shader outputs and inputs, which in turn correspond to
* vertex elements in the state. So, this is the vertex
* element we're interested in...
*/
const uint jj = vinfo->src_index[j];
const enum pipe_format srcFormat = draw->vertex_element[jj].src_format;
const ubyte *from = src[jj] + i * pitch[jj];
float attrib[4];
/* Except... When we're not. Two cases EMIT_HEADER &
* EMIT_1F_PSIZE don't consume an input. Should have some
* method for indicating this, or change the logic here
* somewhat so it doesn't matter.
*
* Just hack this up now, do something better about it later.
*/
if (vinfo->emit[j] == EMIT_HEADER) {
memset(out, 0, sizeof(struct vertex_header));
out += sizeof(struct vertex_header) / 4;
continue;
}
else if (vinfo->emit[j] == EMIT_1F_PSIZE) {
out[0] = 1.0; /* xxx */
out += 1;
continue;
}
/* The normal fetch/emit code:
*/
switch (srcFormat) {
case PIPE_FORMAT_B8G8R8A8_UNORM:
{
ubyte *ub = (ubyte *) from;
attrib[2] = UBYTE_TO_FLOAT(ub[0]);
attrib[1] = UBYTE_TO_FLOAT(ub[1]);
attrib[0] = UBYTE_TO_FLOAT(ub[2]);
attrib[3] = UBYTE_TO_FLOAT(ub[3]);
}
break;
case PIPE_FORMAT_R32G32B32A32_FLOAT:
{
float *f = (float *) from;
attrib[0] = f[0];
attrib[1] = f[1];
attrib[2] = f[2];
attrib[3] = f[3];
}
break;
case PIPE_FORMAT_R32G32B32_FLOAT:
{
float *f = (float *) from;
attrib[0] = f[0];
attrib[1] = f[1];
attrib[2] = f[2];
attrib[3] = 1.0;
}
break;
case PIPE_FORMAT_R32G32_FLOAT:
{
float *f = (float *) from;
attrib[0] = f[0];
attrib[1] = f[1];
attrib[2] = 0.0;
attrib[3] = 1.0;
}
break;
case PIPE_FORMAT_R32_FLOAT:
{
float *f = (float *) from;
attrib[0] = f[0];
attrib[1] = 0.0;
attrib[2] = 0.0;
attrib[3] = 1.0;
}
break;
default:
assert(0);
}
debug_printf("attrib %d: %f %f %f %f\n", j,
attrib[0], attrib[1], attrib[2], attrib[3]);
switch (vinfo->emit[j]) {
case EMIT_1F:
out[0] = attrib[0];
out += 1;
break;
case EMIT_2F:
out[0] = attrib[0];
out[1] = attrib[1];
out += 2;
break;
case EMIT_4F:
out[0] = attrib[0];
out[1] = attrib[1];
out[2] = attrib[2];
out[3] = attrib[3];
out += 4;
break;
default:
assert(0);
}
}
debug_printf("\n");
}
}
static boolean update_shader( struct draw_context *draw )
{
const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render);
unsigned nr_attrs = vinfo->num_attribs;
unsigned i;
for (i = 0; i < nr_attrs; i++) {
unsigned buf = draw->vertex_element[i].vertex_buffer_index;
draw->vertex_fetch.src_ptr[i] = (const ubyte *) draw->user.vbuffer[buf] +
draw->vertex_buffer[buf].buffer_offset +
draw->vertex_element[i].src_offset;
draw->vertex_fetch.pitch[i] = draw->vertex_buffer[buf].pitch;
draw->vertex_fetch.fetch[i] = NULL;
}
draw->vertex_fetch.nr_attrs = nr_attrs;
draw->vertex_fetch.fetch_func = NULL;
draw->vertex_fetch.pt_fetch = NULL;
draw->pt.hw_vertex_size = vinfo->size * 4;
draw->vertex_fetch.pt_fetch = fetch_store_general;
return TRUE;
}
static boolean split_prim_inplace(unsigned prim, unsigned *first, unsigned *incr)
{
switch (prim) {
case PIPE_PRIM_POINTS:
*first = 1;
*incr = 1;
return TRUE;
case PIPE_PRIM_LINES:
*first = 2;
*incr = 2;
return TRUE;
case PIPE_PRIM_LINE_STRIP:
*first = 2;
*incr = 1;
return TRUE;
case PIPE_PRIM_TRIANGLES:
*first = 3;
*incr = 3;
return TRUE;
case PIPE_PRIM_TRIANGLE_STRIP:
*first = 3;
*incr = 1;
return TRUE;
case PIPE_PRIM_QUADS:
*first = 4;
*incr = 4;
return TRUE;
case PIPE_PRIM_QUAD_STRIP:
*first = 4;
*incr = 2;
return TRUE;
default:
*first = 0;
*incr = 1; /* set to one so that count % incr works */
return FALSE;
}
}
static boolean set_prim( struct draw_context *draw,
unsigned prim,
unsigned count )
{
assert(!draw->user.elts);
switch (prim) {
case PIPE_PRIM_LINE_LOOP:
if (count > 1024)
return FALSE;
return draw->render->set_primitive( draw->render, PIPE_PRIM_LINE_STRIP );
case PIPE_PRIM_TRIANGLE_FAN:
case PIPE_PRIM_POLYGON:
if (count > 1024)
return FALSE;
return draw->render->set_primitive( draw->render, prim );
case PIPE_PRIM_QUADS:
case PIPE_PRIM_QUAD_STRIP:
return draw->render->set_primitive( draw->render, PIPE_PRIM_TRIANGLES );
default:
return draw->render->set_primitive( draw->render, prim );
break;
}
return TRUE;
}
#define INDEX(i) (start + (i))
static void pt_draw_arrays( struct draw_context *draw,
unsigned start,
unsigned length )
{
ushort *tmp = NULL;
unsigned i, j;
switch (draw->pt.prim) {
case PIPE_PRIM_LINE_LOOP:
tmp = MALLOC( sizeof(ushort) * (length + 1) );
for (i = 0; i < length; i++)
tmp[i] = INDEX(i);
tmp[length] = 0;
draw->render->draw( draw->render,
tmp,
length+1 );
break;
case PIPE_PRIM_QUAD_STRIP:
tmp = MALLOC( sizeof(ushort) * (length / 2 * 6) );
for (j = i = 0; i + 3 < length; i += 2, j += 6) {
tmp[j+0] = INDEX(i+0);
tmp[j+1] = INDEX(i+1);
tmp[j+2] = INDEX(i+3);
tmp[j+3] = INDEX(i+2);
tmp[j+4] = INDEX(i+0);
tmp[j+5] = INDEX(i+3);
}
if (j)
draw->render->draw( draw->render, tmp, j );
break;
case PIPE_PRIM_QUADS:
tmp = MALLOC( sizeof(int) * (length / 4 * 6) );
for (j = i = 0; i + 3 < length; i += 4, j += 6) {
tmp[j+0] = INDEX(i+0);
tmp[j+1] = INDEX(i+1);
tmp[j+2] = INDEX(i+3);
tmp[j+3] = INDEX(i+1);
tmp[j+4] = INDEX(i+2);
tmp[j+5] = INDEX(i+3);
}
if (j)
draw->render->draw( draw->render, tmp, j );
break;
default:
draw->render->draw_arrays( draw->render,
start,
length );
break;
}
if (tmp)
FREE(tmp);
}
static boolean do_draw( struct draw_context *draw,
unsigned start, unsigned count )
{
float *hw_verts =
draw->render->allocate_vertices( draw->render,
(ushort)draw->pt.hw_vertex_size,
(ushort)count );
if (!hw_verts)
return FALSE;
/* Single routine to fetch vertices and emit HW verts.
*/
draw->vertex_fetch.pt_fetch( draw,
hw_verts,
start, count );
/* Draw arrays path to avoid re-emitting index list again and
* again.
*/
pt_draw_arrays( draw,
0,
count );
draw->render->release_vertices( draw->render,
hw_verts,
draw->pt.hw_vertex_size,
count );
return TRUE;
}
boolean
draw_passthrough_arrays(struct draw_context *draw,
unsigned prim,
unsigned start,
unsigned count)
{
unsigned i = 0;
unsigned first, incr;
//debug_printf("%s prim %d start %d count %d\n", __FUNCTION__, prim, start, count);
split_prim_inplace(prim, &first, &incr);
count -= (count - first) % incr;
debug_printf("%s %d %d %d\n", __FUNCTION__, prim, start, count);
if (draw_need_pipeline(draw, prim))
return FALSE;
debug_printf("%s AAA\n", __FUNCTION__);
if (!set_prim(draw, prim, count))
return FALSE;
/* XXX: need a single value that reflects the most recent call to
* driver->set_primitive:
*/
draw->pt.prim = prim;
debug_printf("%s BBB\n", __FUNCTION__);
if (!update_shader(draw))
return FALSE;
debug_printf("%s CCC\n", __FUNCTION__);
/* Chop this up into bite-sized pieces that a driver should be able
* to devour -- problem is we don't have a quick way to query the
* driver on the maximum size for this chunk in the current state.
*/
while (i + first <= count) {
int nr = MIN2( count - i, 1024 );
/* snap to prim boundary
*/
nr -= (nr - first) % incr;
if (!do_draw( draw, start + i, nr )) {
assert(0);
return FALSE;
}
/* increment allowing for repeated vertices
*/
i += nr - (first - incr);
}
debug_printf("%s DONE\n", __FUNCTION__);
return TRUE;
}

View file

@ -343,21 +343,11 @@ draw_prim( struct draw_context *draw,
break;
case PIPE_PRIM_LINES:
if (flatfirst) {
for (i = 0; i+1 < count; i += 2) {
do_line( draw,
TRUE,
start + i + 1,
start + i + 0);
}
}
else {
for (i = 0; i+1 < count; i += 2) {
do_line( draw,
TRUE,
start + i + 0,
start + i + 1);
}
for (i = 0; i+1 < count; i += 2) {
do_line( draw,
TRUE,
start + i + 0,
start + i + 1);
}
break;
@ -378,63 +368,31 @@ draw_prim( struct draw_context *draw,
break;
case PIPE_PRIM_LINE_STRIP:
if (flatfirst) {
for (i = 1; i < count; i++) {
do_line( draw,
i == 1,
start + i,
start + i - 1 );
}
}
else {
for (i = 1; i < count; i++) {
do_line( draw,
i == 1,
start + i - 1,
start + i );
}
for (i = 1; i < count; i++) {
do_line( draw,
i == 1,
start + i - 1,
start + i );
}
break;
case PIPE_PRIM_TRIANGLES:
if (flatfirst) {
if (unfilled) {
for (i = 0; i+2 < count; i += 3) {
do_ef_triangle( draw,
1,
~0,
start + i + 1,
start + i + 2,
start + i + 0 );
}
}
else {
for (i = 0; i+2 < count; i += 3) {
do_triangle( draw,
start + i + 1,
start + i + 2,
start + i + 0 );
}
if (unfilled) {
for (i = 0; i+2 < count; i += 3) {
do_ef_triangle( draw,
1,
~0,
start + i + 0,
start + i + 1,
start + i + 2 );
}
}
}
else {
if (unfilled) {
for (i = 0; i+2 < count; i += 3) {
do_ef_triangle( draw,
1,
~0,
start + i + 0,
start + i + 1,
start + i + 2 );
}
}
else {
for (i = 0; i+2 < count; i += 3) {
do_triangle( draw,
start + i + 0,
start + i + 1,
start + i + 2 );
}
for (i = 0; i+2 < count; i += 3) {
do_triangle( draw,
start + i + 0,
start + i + 1,
start + i + 2 );
}
}
break;
@ -444,15 +402,15 @@ draw_prim( struct draw_context *draw,
for (i = 0; i+2 < count; i++) {
if (i & 1) {
do_triangle( draw,
start + i + 0,
start + i + 2,
start + i + 1,
start + i + 0 );
start + i + 1 );
}
else {
do_triangle( draw,
start + i + 0,
start + i + 1,
start + i + 2,
start + i + 0 );
start + i + 2 );
}
}
}
@ -479,9 +437,9 @@ draw_prim( struct draw_context *draw,
if (flatfirst) {
for (i = 0; i+2 < count; i++) {
do_triangle( draw,
start + i + 1,
start + i + 2,
start + 0,
start + i + 1 );
start + 0 );
}
}
else {
@ -593,8 +551,7 @@ draw_arrays(struct draw_context *draw, unsigned prim,
}
/* drawing done here: */
if (!draw->rasterizer->bypass_vs ||
!draw_pt_arrays(draw, prim, start, count)) {
if (!draw_pt_arrays(draw, prim, start, count)) {
/* we have to run the whole pipeline */
draw_prim(draw, prim, start, count);
}

View file

@ -232,6 +232,8 @@ struct draw_context
struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
struct draw_vertex_shader *vertex_shader;
boolean identity_viewport;
uint num_vs_outputs; /**< convenience, from vertex_shader */
/* user-space vertex data, buffers */

View file

@ -36,6 +36,9 @@
#include "draw/draw_pt.h"
/* XXX: Shouldn't those two functions below use the '>' operator???
*/
static boolean too_many_verts( struct draw_context *draw,
unsigned verts )
{
@ -164,6 +167,10 @@ draw_pt_arrays(struct draw_context *draw,
frontend = draw->pt.front.vcache;
#endif
/* XXX: need to flush to get prim_vbuf.c to release its allocation??
*/
draw_do_flush( draw, DRAW_FLUSH_BACKEND );
frontend->prepare( frontend, middle );
frontend->run( frontend,
@ -184,7 +191,7 @@ boolean draw_pt_init( struct draw_context *draw )
if (!draw->pt.middle.fetch_emit)
return FALSE;
draw->pt.front.vcache = draw_pt_vcache();
draw->pt.front.vcache = draw_pt_vcache( draw );
if (!draw->pt.front.vcache)
return FALSE;

View file

@ -110,7 +110,7 @@ const void *draw_pt_elt_ptr( struct draw_context *draw,
/* Implementations:
*/
struct draw_pt_front_end *draw_pt_vcache( void );
struct draw_pt_front_end *draw_pt_vcache( struct draw_context *draw );
struct draw_pt_middle_end *draw_pt_fetch_emit( struct draw_context *draw );

View file

@ -44,6 +44,7 @@
struct vcache_frontend {
struct draw_pt_front_end base;
struct draw_context *draw;
unsigned in[CACHE_MAX];
ushort out[CACHE_MAX];
@ -157,14 +158,6 @@ static void vcache_quad( struct vcache_frontend *vcache,
}
static void vcache_prepare( struct draw_pt_front_end *frontend,
struct draw_pt_middle_end *middle )
{
struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
vcache->middle = middle;
middle->prepare( middle );
}
static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = {
PIPE_PRIM_POINTS,
PIPE_PRIM_LINES,
@ -179,11 +172,11 @@ static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = {
};
static void vcache_run( struct draw_pt_front_end *frontend,
unsigned prim,
pt_elt_func get_elt,
const void *elts,
unsigned count )
static void vcache_run_pv2( struct draw_pt_front_end *frontend,
unsigned prim,
pt_elt_func get_elt,
const void *elts,
unsigned count )
{
struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
unsigned i;
@ -309,6 +302,109 @@ static void vcache_run( struct draw_pt_front_end *frontend,
vcache_flush( vcache );
}
static void vcache_run_pv0( struct draw_pt_front_end *frontend,
unsigned prim,
pt_elt_func get_elt,
const void *elts,
unsigned count )
{
struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
unsigned i;
/* These are for validation only:
*/
vcache->elt_func = get_elt;
vcache->elt_ptr = elts;
vcache->output_prim = reduced_prim[prim];
switch (prim) {
case PIPE_PRIM_POINTS:
for (i = 0; i < count; i ++) {
vcache_point( vcache,
get_elt(elts, i) );
}
break;
case PIPE_PRIM_LINES:
for (i = 0; i+1 < count; i += 2) {
vcache_line( vcache,
TRUE,
get_elt(elts, i + 0),
get_elt(elts, i + 1));
}
break;
case PIPE_PRIM_LINE_STRIP:
for (i = 1; i < count; i++) {
vcache_line( vcache,
i == 1,
get_elt(elts, i - 1),
get_elt(elts, i) );
}
break;
case PIPE_PRIM_TRIANGLES:
for (i = 0; i+2 < count; i += 3) {
vcache_triangle( vcache,
get_elt(elts, i + 0),
get_elt(elts, i + 1),
get_elt(elts, i + 2) );
}
break;
case PIPE_PRIM_TRIANGLE_STRIP:
for (i = 0; i+2 < count; i++) {
if (i & 1) {
vcache_triangle( vcache,
get_elt(elts, i + 0),
get_elt(elts, i + 2),
get_elt(elts, i + 1) );
}
else {
vcache_triangle( vcache,
get_elt(elts, i + 0),
get_elt(elts, i + 1),
get_elt(elts, i + 2) );
}
}
break;
case PIPE_PRIM_TRIANGLE_FAN:
for (i = 0; i+2 < count; i++) {
vcache_triangle( vcache,
get_elt(elts, i + 1),
get_elt(elts, i + 2),
get_elt(elts, 0) );
}
break;
default:
assert(0);
break;
}
vcache_flush( vcache );
}
static void vcache_prepare( struct draw_pt_front_end *frontend,
struct draw_pt_middle_end *middle )
{
struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
if (vcache->draw->rasterizer->flatshade_first)
vcache->base.run = vcache_run_pv0;
else
vcache->base.run = vcache_run_pv2;
vcache->middle = middle;
middle->prepare( middle );
}
static void vcache_finish( struct draw_pt_front_end *frontend )
{
struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
@ -322,14 +418,15 @@ static void vcache_destroy( struct draw_pt_front_end *frontend )
}
struct draw_pt_front_end *draw_pt_vcache( void )
struct draw_pt_front_end *draw_pt_vcache( struct draw_context *draw )
{
struct vcache_frontend *vcache = CALLOC_STRUCT( vcache_frontend );
vcache->base.prepare = vcache_prepare;
vcache->base.run = vcache_run;
vcache->base.run = NULL;
vcache->base.finish = vcache_finish;
vcache->base.destroy = vcache_destroy;
vcache->draw = draw;
memset(vcache->in, ~0, sizeof(vcache->in));

View file

@ -110,13 +110,20 @@ vs_exec_run( struct draw_vertex_shader *shader,
machine->Consts = (float (*)[4]) draw->user.constants;
machine->Inputs = ALIGN16_ASSIGN(inputs);
machine->Outputs = ALIGN16_ASSIGN(outputs);
if (draw->rasterizer->bypass_vs) {
/* outputs are just the inputs */
machine->Outputs = machine->Inputs;
}
else {
machine->Outputs = ALIGN16_ASSIGN(outputs);
}
draw->vertex_fetch.fetch_func( draw, machine, elts, count );
/* run interpreter */
tgsi_exec_machine_run( machine );
if (!draw->rasterizer->bypass_vs) {
/* run interpreter */
tgsi_exec_machine_run( machine );
}
/* store machine results */
for (j = 0; j < count; j++) {
@ -136,14 +143,19 @@ vs_exec_run( struct draw_vertex_shader *shader,
if (!draw->rasterizer->bypass_clipping) {
vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes);
vOut[j]->edgeflag = 1;
/* divide by w */
w = 1.0f / w;
x *= w;
y *= w;
z *= w;
z *= w;
}
else {
vOut[j]->clipmask = 0;
}
vOut[j]->edgeflag = 1;
if (!draw->identity_viewport) {
/* Viewport mapping */
vOut[j]->data[0][0] = x * scale[0] + trans[0];
vOut[j]->data[0][1] = y * scale[1] + trans[1];
@ -151,8 +163,6 @@ vs_exec_run( struct draw_vertex_shader *shader,
vOut[j]->data[0][3] = w;
}
else {
vOut[j]->clipmask = 0;
vOut[j]->edgeflag = 1;
vOut[j]->data[0][0] = x;
vOut[j]->data[0][1] = y;
vOut[j]->data[0][2] = z;

View file

@ -121,37 +121,51 @@ vs_llvm_run( struct draw_vertex_shader *base,
machine->Consts = (float (*)[4]) draw->user.constants;
machine->Inputs = ALIGN16_ASSIGN(inputs);
machine->Outputs = ALIGN16_ASSIGN(outputs);
if (draw->rasterizer->bypass_vs) {
/* outputs are just the inputs */
machine->Outputs = machine->Inputs;
}
else {
machine->Outputs = ALIGN16_ASSIGN(outputs);
}
draw->vertex_fetch.fetch_func( draw, machine, elts, count );
/* run shader */
gallivm_cpu_vs_exec(shader->llvm_prog,
machine->Inputs,
machine->Outputs,
machine->Consts,
machine->Temps);
if (!draw->rasterizer->bypass_vs) {
/* run shader */
gallivm_cpu_vs_exec(shader->llvm_prog,
machine->Inputs,
machine->Outputs,
machine->Consts,
machine->Temps);
}
/* store machine results */
for (j = 0; j < count; j++) {
unsigned slot;
float x, y, z, w;
if (!draw->rasterizer->bypass_clipping) {
x = vOut[j]->clip[0] = machine->Outputs[0].xyzw[0].f[j];
y = vOut[j]->clip[1] = machine->Outputs[0].xyzw[1].f[j];
z = vOut[j]->clip[2] = machine->Outputs[0].xyzw[2].f[j];
w = vOut[j]->clip[3] = machine->Outputs[0].xyzw[3].f[j];
x = vOut[j]->clip[0] = machine->Outputs[0].xyzw[0].f[j];
y = vOut[j]->clip[1] = machine->Outputs[0].xyzw[1].f[j];
z = vOut[j]->clip[2] = machine->Outputs[0].xyzw[2].f[j];
w = vOut[j]->clip[3] = machine->Outputs[0].xyzw[3].f[j];
if (!draw->rasterizer->bypass_clipping) {
vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes);
vOut[j]->edgeflag = 1;
/* divide by w */
w = 1.0f / w;
x *= w;
y *= w;
z *= w;
z *= w;
}
else {
vOut[j]->clipmask = 0;
}
vOut[j]->edgeflag = 1;
if (!draw->identity_viewport) {
/* Viewport mapping */
vOut[j]->data[0][0] = x * scale[0] + trans[0];
vOut[j]->data[0][1] = y * scale[1] + trans[1];
@ -159,8 +173,6 @@ vs_llvm_run( struct draw_vertex_shader *base,
vOut[j]->data[0][3] = w;
}
else {
vOut[j]->clipmask = 0;
vOut[j]->edgeflag = 1;
vOut[j]->data[0][0] = x;
vOut[j]->data[0][1] = y;
vOut[j]->data[0][2] = z;

View file

@ -126,7 +126,13 @@ vs_sse_run( struct draw_vertex_shader *base,
/* Consts does not require 16 byte alignment. */
machine->Consts = (float (*)[4]) draw->user.constants;
machine->Inputs = ALIGN16_ASSIGN(inputs);
machine->Outputs = ALIGN16_ASSIGN(outputs);
if (draw->rasterizer->bypass_vs) {
/* outputs are just the inputs */
machine->Outputs = machine->Inputs;
}
else {
machine->Outputs = ALIGN16_ASSIGN(outputs);
}
/* Fetch vertices. This may at some point be integrated into the
@ -137,13 +143,14 @@ vs_sse_run( struct draw_vertex_shader *base,
draw->vertex_fetch.fetch_func( draw, machine, elts, count );
/* run compiled shader
*/
shader->func(
machine->Inputs,
machine->Outputs,
machine->Consts,
machine->Temps );
if (!draw->rasterizer->bypass_vs) {
/* run compiled shader
*/
shader->func(machine->Inputs,
machine->Outputs,
machine->Consts,
machine->Temps );
}
/* XXX: Computing the clipmask and emitting results should be done
@ -161,14 +168,19 @@ vs_sse_run( struct draw_vertex_shader *base,
if (!draw->rasterizer->bypass_clipping) {
vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes);
vOut[j]->edgeflag = 1;
/* divide by w */
w = 1.0f / w;
x *= w;
y *= w;
z *= w;
}
else {
vOut[j]->clipmask = 0;
}
vOut[j]->edgeflag = 1;
if (!draw->identity_viewport) {
/* Viewport mapping */
vOut[j]->data[0][0] = x * scale[0] + trans[0];
vOut[j]->data[0][1] = y * scale[1] + trans[1];
@ -176,8 +188,6 @@ vs_sse_run( struct draw_vertex_shader *base,
vOut[j]->data[0][3] = w;
}
else {
vOut[j]->clipmask = 0;
vOut[j]->edgeflag = 1;
vOut[j]->data[0][0] = x;
vOut[j]->data[0][1] = y;
vOut[j]->data[0][2] = z;

View file

@ -29,8 +29,8 @@
* \file
* Implementation of fenced buffers.
*
* \author José Fonseca <jrfonseca-at-tungstengraphics-dot-com>
* \author Thomas Hellström <thomas-at-tungstengraphics-dot-com>
* \author José Fonseca <jrfonseca-at-tungstengraphics-dot-com>
* \author Thomas Hellström <thomas-at-tungstengraphics-dot-com>
*/
@ -44,7 +44,7 @@
#include "pb_buffer.h"
#include "pb_buffer_fenced.h"
#ifndef __MSC__
#ifndef WIN32
#include <unistd.h>
#endif
@ -93,8 +93,6 @@ fenced_buffer(struct pb_buffer *buf)
}
static void
_fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list,
int wait)
@ -105,15 +103,6 @@ _fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list,
int signaled = -1;
list = fenced_list->delayed.next;
if (fenced_list->numDelayed > 3) {
unsigned i;
for (i = 0; i < fenced_list->numDelayed; i += 3) {
list = list->next;
}
}
prev = list->prev;
for (; list != &fenced_list->delayed; list = prev, prev = list->prev) {
@ -128,11 +117,17 @@ _fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list,
}
}
if (signaled != 0)
if (signaled != 0) {
#if 0
/* XXX: we are assuming that buffers are freed in the same order they
* are fenced which may not always be true...
*/
break;
#else
signaled = -1;
continue;
#endif
}
winsys->fence_reference(winsys, &fenced_buf->fence, NULL);
@ -154,8 +149,16 @@ fenced_buffer_destroy(struct pb_buffer *buf)
struct fenced_buffer_list *fenced_list = fenced_buf->list;
if (fenced_buf->fence) {
LIST_ADDTAIL(&fenced_buf->head, &fenced_list->delayed);
fenced_list->numDelayed++;
struct pipe_winsys *winsys = fenced_list->winsys;
if(winsys->fence_finish(winsys, fenced_buf->fence, 0) != 0) {
LIST_ADDTAIL(&fenced_buf->head, &fenced_list->delayed);
fenced_list->numDelayed++;
}
else {
winsys->fence_reference(winsys, &fenced_buf->fence, NULL);
pb_reference(&fenced_buf->buffer, NULL);
FREE(fenced_buf);
}
}
else {
pb_reference(&fenced_buf->buffer, NULL);
@ -285,7 +288,7 @@ fenced_buffer_list_destroy(struct fenced_buffer_list *fenced_list)
/* Wait on outstanding fences */
while (fenced_list->numDelayed) {
_glthread_UNLOCK_MUTEX(fenced_list->mutex);
#ifndef __MSC__
#ifndef WIN32
sched_yield();
#endif
_fenced_buffer_list_check_free(fenced_list, 1);

View file

@ -36,6 +36,7 @@
#include "pipe/p_compiler.h"
#include "pipe/p_util.h"
#include "pipe/p_format.h"
#include "pipe/p_state.h"
/** The standard assert macro doesn't seem to work reliably */
@ -66,6 +67,8 @@
#define CELL_MAX_SPUS 6
#define CELL_MAX_SAMPLERS 4
#define TILE_SIZE 32
@ -109,7 +112,7 @@
*/
struct cell_command_depth_stencil_alpha_test {
uint64_t base; /**< Effective address of code start. */
unsigned size; /**< Size in bytes of test code. */
unsigned size; /**< Size in bytes of SPE code. */
unsigned read_depth; /**< Flag: should depth be read? */
unsigned read_stencil; /**< Flag: should stencil be read? */
};
@ -120,14 +123,14 @@ struct cell_command_depth_stencil_alpha_test {
*/
struct cell_command_blend {
uint64_t base; /**< Effective address of code start. */
unsigned size; /**< Size in bytes of test code. */
unsigned size; /**< Size in bytes of SPE code. */
unsigned read_fb; /**< Flag: should framebuffer be read? */
};
struct cell_command_logicop {
uint64_t base; /**< Effective address of code start. */
unsigned size; /**< Size in bytes of test code. */
unsigned size; /**< Size in bytes of SPE code. */
};
@ -226,10 +229,20 @@ struct cell_command_release_verts
};
struct cell_command_sampler
{
uint64_t opcode; /**< CELL_CMD_STATE_SAMPLER */
uint unit;
struct pipe_sampler_state state;
};
struct cell_command_texture
{
uint64_t opcode; /**< CELL_CMD_STATE_TEXTURE */
uint unit;
void *start; /**< Address in main memory */
uint width, height;
ushort width, height;
};

View file

@ -273,6 +273,7 @@ cell_set_sampler_textures(struct pipe_context *pipe,
pipe_texture_reference((struct pipe_texture **) &cell->texture[i], tex);
}
cell->num_textures = num;
cell_update_texture_mapping(cell);

View file

@ -55,11 +55,11 @@ cell_get_param(struct pipe_screen *screen, int param)
{
switch (param) {
case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
return 8;
return PIPE_MAX_SAMPLERS;
case PIPE_CAP_NPOT_TEXTURES:
return 1;
return 0;
case PIPE_CAP_TWO_SIDED_STENCIL:
return 1;
return 0;
case PIPE_CAP_GLSL:
return 1;
case PIPE_CAP_S3TC:
@ -67,13 +67,13 @@ cell_get_param(struct pipe_screen *screen, int param)
case PIPE_CAP_ANISOTROPIC_FILTER:
return 0;
case PIPE_CAP_POINT_SPRITE:
return 1;
return 0;
case PIPE_CAP_MAX_RENDER_TARGETS:
return 1;
case PIPE_CAP_OCCLUSION_QUERY:
return 1;
return 0;
case PIPE_CAP_TEXTURE_SHADOW_MAP:
return 1;
return 0;
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
return 12; /* max 2Kx2K */
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
@ -118,8 +118,12 @@ cell_is_format_supported( struct pipe_screen *screen,
{
switch (type) {
case PIPE_TEXTURE:
/* cell supports all texture formats, XXX for now anyway */
return TRUE;
/* cell supports most texture formats, XXX for now anyway */
if (format == PIPE_FORMAT_DXT5_RGBA ||
format == PIPE_FORMAT_R8G8B8A8_SRGB)
return FALSE;
else
return TRUE;
case PIPE_SURFACE:
/* cell supports all (off-screen) surface formats, XXX for now */
return TRUE;

View file

@ -121,27 +121,36 @@ cell_emit_state(struct cell_context *cell)
}
if (cell->dirty & CELL_NEW_SAMPLER) {
if (cell->sampler[0]) {
emit_state_cmd(cell, CELL_CMD_STATE_SAMPLER,
cell->sampler[0], sizeof(struct pipe_sampler_state));
uint i;
for (i = 0; i < CELL_MAX_SAMPLERS; i++) {
if (cell->sampler[i]) {
struct cell_command_sampler *sampler
= cell_batch_alloc(cell, sizeof(*sampler));
sampler->opcode = CELL_CMD_STATE_SAMPLER;
sampler->unit = i;
sampler->state = *cell->sampler[i];
}
}
}
if (cell->dirty & CELL_NEW_TEXTURE) {
struct cell_command_texture texture;
if (cell->texture[0]) {
texture.start = cell->texture[0]->tiled_data;
texture.width = cell->texture[0]->base.width[0];
texture.height = cell->texture[0]->base.height[0];
uint i;
for (i = 0;i < CELL_MAX_SAMPLERS; i++) {
struct cell_command_texture *texture
= cell_batch_alloc(cell, sizeof(*texture));
texture->opcode = CELL_CMD_STATE_TEXTURE;
texture->unit = i;
if (cell->texture[i]) {
texture->start = cell->texture[i]->tiled_data;
texture->width = cell->texture[i]->base.width[0];
texture->height = cell->texture[i]->base.height[0];
}
else {
texture->start = NULL;
texture->width = 1;
texture->height = 1;
}
}
else {
texture.start = NULL;
texture.width = 0;
texture.height = 0;
}
emit_state_cmd(cell, CELL_CMD_STATE_TEXTURE,
&texture, sizeof(struct cell_command_texture));
}
if (cell->dirty & CELL_NEW_VERTEX_INFO) {

View file

@ -1164,10 +1164,11 @@ int PC_OFFSET(const struct spe_function *f, const void *d)
* masking.
*
* \bug
* This routine is hard-coded to only work with ARGB8 data.
* Only two framebuffer formats are supported at this time.
*/
void
cell_generate_logic_op(struct spe_function *f, struct pipe_blend_state *blend,
cell_generate_logic_op(struct spe_function *f,
const struct pipe_blend_state *blend,
struct pipe_surface *surf)
{
const unsigned logic_op = (blend->logicop_enable)
@ -1235,15 +1236,31 @@ cell_generate_logic_op(struct spe_function *f, struct pipe_blend_state *blend,
/* Convert fragment colors to framebuffer format in AoS layout.
*/
data[0] = 0x00010203;
data[1] = 0x10111213;
data[2] = 0x04050607;
data[3] = 0x14151617;
data[4] = 0x0c000408;
data[5] = 0x80808080;
data[6] = 0x80808080;
data[7] = 0x80808080;
switch (surf->format) {
case PIPE_FORMAT_A8R8G8B8_UNORM:
data[0] = 0x00010203;
data[1] = 0x10111213;
data[2] = 0x04050607;
data[3] = 0x14151617;
data[4] = 0x0c000408;
data[5] = 0x80808080;
data[6] = 0x80808080;
data[7] = 0x80808080;
break;
case PIPE_FORMAT_B8G8R8A8_UNORM:
data[0] = 0x03020100;
data[1] = 0x13121110;
data[2] = 0x07060504;
data[3] = 0x17161514;
data[4] = 0x0804000c;
data[5] = 0x80808080;
data[6] = 0x80808080;
data[7] = 0x80808080;
break;
default:
fprintf(stderr, "CELL: Bad pixel format in cell_generate_logic_op()");
ASSERT(0);
}
spe_ilh(f, tmp[0], 0x0808);
spe_lqr(f, shuf_xpose_hi, PC_OFFSET(f, data+0));

View file

@ -32,7 +32,8 @@ extern void
cell_generate_alpha_blend(struct cell_blend_state *cb);
extern void
cell_generate_logic_op(struct spe_function *f, struct pipe_blend_state *blend,
struct pipe_surface *surf);
cell_generate_logic_op(struct spe_function *f,
const struct pipe_blend_state *blend,
struct pipe_surface *surf);
#endif /* CELL_STATE_PER_FRAGMENT_H */

View file

@ -312,13 +312,13 @@ cmd_state_depth_stencil(const struct cell_command_depth_stencil_alpha_test *stat
static void
cmd_state_sampler(const struct pipe_sampler_state *state)
cmd_state_sampler(const struct cell_command_sampler *sampler)
{
if (Debug)
printf("SPU %u: SAMPLER\n",
spu.init.id);
printf("SPU %u: SAMPLER [%u]\n",
spu.init.id, sampler->unit);
memcpy(&spu.sampler[0], state, sizeof(*state));
spu.sampler[sampler->unit] = sampler->state;
if (spu.sampler[0].min_img_filter == PIPE_TEX_FILTER_LINEAR)
spu.sample_texture = sample_texture_bilinear;
else
@ -329,17 +329,25 @@ cmd_state_sampler(const struct pipe_sampler_state *state)
static void
cmd_state_texture(const struct cell_command_texture *texture)
{
if (Debug)
printf("SPU %u: TEXTURE at %p size %u x %u\n",
spu.init.id, texture->start, texture->width, texture->height);
const uint unit = texture->unit;
const uint width = texture->width;
const uint height = texture->height;
memcpy(&spu.texture, texture, sizeof(*texture));
spu.tex_size = (vector float)
{ spu.texture.width, spu.texture.height, 0.0, 0.0};
spu.tex_size_mask = (vector unsigned int)
{ spu.texture.width - 1, spu.texture.height - 1, 0, 0 };
spu.tex_size_x_mask = spu_splats(spu.texture.width - 1);
spu.tex_size_y_mask = spu_splats(spu.texture.height - 1);
if (Debug) {
printf("SPU %u: TEXTURE [%u] at %p size %u x %u\n", spu.init.id,
texture->unit, texture->start,
texture->width, texture->height);
}
spu.texture[unit].start = texture->start;
spu.texture[unit].width = width;
spu.texture[unit].height = height;
spu.texture[unit].tex_size = (vector float) { width, height, 0.0, 0.0};
spu.texture[unit].tex_size_mask = (vector unsigned int)
{ width - 1, height - 1, 0, 0 };
spu.texture[unit].tex_size_x_mask = spu_splats(width - 1);
spu.texture[unit].tex_size_y_mask = spu_splats(height - 1);
}
@ -471,12 +479,20 @@ cmd_batch(uint opcode)
pos += (1 + ROUNDUP8(sizeof(struct cell_command_depth_stencil_alpha_test)) / 8);
break;
case CELL_CMD_STATE_SAMPLER:
cmd_state_sampler((struct pipe_sampler_state *) &buffer[pos+1]);
pos += (1 + ROUNDUP8(sizeof(struct pipe_sampler_state)) / 8);
{
struct cell_command_sampler *sampler
= (struct cell_command_sampler *) &buffer[pos];
cmd_state_sampler(sampler);
pos += sizeof(*sampler) / 8;
}
break;
case CELL_CMD_STATE_TEXTURE:
cmd_state_texture((struct cell_command_texture *) &buffer[pos+1]);
pos += (1 + ROUNDUP8(sizeof(struct cell_command_texture)) / 8);
{
struct cell_command_texture *texture
= (struct cell_command_texture *) &buffer[pos];
cmd_state_texture(texture);
pos += sizeof(*texture) / 8;
}
break;
case CELL_CMD_STATE_VERTEX_INFO:
cmd_state_vertex_info((struct vertex_info *) &buffer[pos+1]);

View file

@ -100,6 +100,17 @@ struct spu_framebuffer {
} ALIGN16_ATTRIB;
struct spu_texture
{
void *start;
uint width, height;
vector float tex_size;
vector unsigned int tex_size_mask; /**< == int(size - 1) */
vector unsigned int tex_size_x_mask; /**< == int(size - 1) */
vector unsigned int tex_size_y_mask; /**< == int(size - 1) */
} ALIGN16_ATTRIB;
/**
* All SPU global/context state will be in singleton object of this type:
*/
@ -119,7 +130,7 @@ struct spu_global
logicop_func logicop;
struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS];
struct cell_command_texture texture;
struct spu_texture texture[PIPE_MAX_SAMPLERS];
struct vertex_info vertex_info;
@ -141,11 +152,6 @@ struct spu_global
/** for converting RGBA to PIPE_FORMAT_x colors */
vector unsigned char color_shuffle;
vector float tex_size;
vector unsigned int tex_size_mask; /**< == int(size - 1) */
vector unsigned int tex_size_x_mask; /**< == int(size - 1) */
vector unsigned int tex_size_y_mask; /**< == int(size - 1) */
vector float (*sample_texture)(vector float texcoord);
} ALIGN16_ATTRIB;

View file

@ -40,25 +40,29 @@
void
invalidate_tex_cache(void)
{
spu_dcache_mark_dirty((unsigned) spu.texture.start,
4 * spu.texture.width * spu.texture.height);
uint unit = 0;
uint bytes = 4 * spu.texture[unit].width
* spu.texture[unit].height;
spu_dcache_mark_dirty((unsigned) spu.texture[unit].start, bytes);
}
static uint
get_texel(vec_uint4 coordinate)
{
const uint unit = 0;
vec_uint4 tmp;
unsigned x = spu_extract(coordinate, 0);
unsigned y = spu_extract(coordinate, 1);
const unsigned tiles_per_row = spu.texture.width / TILE_SIZE;
const unsigned tiles_per_row = spu.texture[unit].width / TILE_SIZE;
unsigned tile_offset = sizeof(tile_t) * ((y / TILE_SIZE * tiles_per_row)
+ (x / TILE_SIZE));
unsigned texel_offset = 4 * (((y % TILE_SIZE) * TILE_SIZE)
+ (x % TILE_SIZE));
spu_dcache_fetch_unaligned((qword *) & tmp,
spu.texture.start + tile_offset + texel_offset,
spu.texture[unit].start + tile_offset + texel_offset,
4);
return spu_extract(tmp, 0);
}
@ -67,13 +71,14 @@ get_texel(vec_uint4 coordinate)
static void
get_four_texels(vec_uint4 x, vec_uint4 y, vec_uint4 *texels)
{
const unsigned texture_ea = (uintptr_t) spu.texture.start;
const uint unit = 0;
const unsigned texture_ea = (uintptr_t) spu.texture[unit].start;
vec_uint4 tile_x = spu_rlmask(x, -5);
vec_uint4 tile_y = spu_rlmask(y, -5);
const qword offset_x = si_andi((qword) x, 0x1f);
const qword offset_y = si_andi((qword) y, 0x1f);
const qword tiles_per_row = (qword) spu_splats(spu.texture.width / TILE_SIZE);
const qword tiles_per_row = (qword) spu_splats(spu.texture[unit].width / TILE_SIZE);
const qword tile_size = (qword) spu_splats(sizeof(tile_t));
qword tile_offset = si_mpya((qword) tile_y, tiles_per_row, (qword) tile_x);
@ -101,9 +106,10 @@ get_four_texels(vec_uint4 x, vec_uint4 y, vec_uint4 *texels)
vector float
sample_texture_nearest(vector float texcoord)
{
vector float tc = spu_mul(texcoord, spu.tex_size);
const uint unit = 0;
vector float tc = spu_mul(texcoord, spu.texture[unit].tex_size);
vector unsigned int itc = spu_convtu(tc, 0); /* convert to int */
itc = spu_and(itc, spu.tex_size_mask); /* mask (GL_REPEAT) */
itc = spu_and(itc, spu.texture[unit].tex_size_mask); /* mask (GL_REPEAT) */
uint texel = get_texel(itc);
return spu_unpack_A8R8G8B8(texel);
}
@ -112,10 +118,11 @@ sample_texture_nearest(vector float texcoord)
vector float
sample_texture_bilinear(vector float texcoord)
{
const uint unit = 0;
static const vec_uint4 offset_x = {0, 0, 1, 1};
static const vec_uint4 offset_y = {0, 1, 0, 1};
vector float tc = spu_mul(texcoord, spu.tex_size);
vector float tc = spu_mul(texcoord, spu.texture[unit].tex_size);
tc = spu_add(tc, spu_splats(-0.5f)); /* half texel bias */
/* integer texcoords S,T: */
@ -129,8 +136,8 @@ sample_texture_bilinear(vector float texcoord)
x = spu_add(x, offset_x);
y = spu_add(y, offset_y);
x = spu_and(x, spu.tex_size_x_mask);
y = spu_and(y, spu.tex_size_y_mask);
x = spu_and(x, spu.texture[unit].tex_size_x_mask);
y = spu_and(y, spu.texture[unit].tex_size_y_mask);
get_four_texels(x, y, texels);

View file

@ -309,7 +309,7 @@ emit_quad( int x, int y, mask_t mask )
spu.cur_ctile_status = TILE_STATUS_DIRTY;
if (spu.texture.start) {
if (spu.texture[0].start) {
/* texture mapping */
vector float texcoords[4];
eval_coeff(2, (float) x, (float) y, texcoords);

View file

@ -30,6 +30,7 @@
#include "i915_winsys.h"
#include "i915_debug.h"
#include "pipe/p_winsys.h"
#include "pipe/p_debug.h"
static void
@ -39,11 +40,9 @@ PRINTF(
... )
{
va_list args;
char buffer[256];
va_start( args, fmt );
vsprintf( buffer, fmt, args );
stream->winsys->printf( stream->winsys, buffer );
debug_vprintf( fmt, args );
va_end( args );
}
@ -200,14 +199,12 @@ BITS(
... )
{
va_list args;
char buffer[256];
unsigned himask = ~0UL >> (31 - (hi));
PRINTF(stream, "\t\t ");
va_start( args, fmt );
vsprintf( buffer, fmt, args );
stream->winsys->printf( stream->winsys, buffer );
debug_vprintf( fmt, args );
va_end( args );
PRINTF(stream, ": 0x%x\n", ((dw) & himask) >> (lo));
@ -231,13 +228,11 @@ FLAG(
{
if (((dw) >> (bit)) & 1) {
va_list args;
char buffer[256];
PRINTF(stream, "\t\t ");
va_start( args, fmt );
vsprintf( buffer, fmt, args );
stream->winsys->printf( stream->winsys, buffer );
debug_vprintf( fmt, args );
va_end( args );
PRINTF(stream, "\n");
@ -877,11 +872,11 @@ i915_dump_batchbuffer( struct i915_context *i915 )
stream.winsys = i915->pipe.winsys;
if (!start || !end) {
stream.winsys->printf( stream.winsys, "\n\nBATCH: ???\n");
debug_printf( "\n\nBATCH: ???\n");
return;
}
stream.winsys->printf( stream.winsys, "\n\nBATCH: (%d)\n", bytes / 4);
debug_printf( "\n\nBATCH: (%d)\n", bytes / 4);
while (!done &&
stream.offset < bytes)
@ -893,7 +888,7 @@ i915_dump_batchbuffer( struct i915_context *i915 )
stream.offset >= 0);
}
stream.winsys->printf( stream.winsys, "END-BATCH\n\n\n");
debug_printf( "END-BATCH\n\n\n");
}

View file

@ -83,11 +83,9 @@ I915_DBG(
{
if ((i915)->debug & FILE_DEBUG_FLAG) {
va_list args;
char buffer[256];
va_start( args, fmt );
vsprintf( buffer, fmt, args );
i915->pipe.winsys->printf( i915->pipe.winsys, buffer );
debug_vprintf( fmt, args );
va_end( args );
}
}

View file

@ -39,11 +39,9 @@ PRINTF(
... )
{
va_list args;
char buffer[256];
va_start( args, fmt );
vsprintf( buffer, fmt, args );
stream->winsys->printf( stream->winsys, buffer );
debug_vprintf( fmt, args );
va_end( args );
}

View file

@ -226,9 +226,8 @@ i915_create_screen(struct pipe_winsys *winsys, uint pci_id)
break;
default:
winsys->printf(winsys,
"%s: unknown pci id 0x%x, cannot create screen\n",
__FUNCTION__, pci_id);
debug_printf("%s: unknown pci id 0x%x, cannot create screen\n",
__FUNCTION__, pci_id);
return NULL;
}

View file

@ -77,9 +77,8 @@ struct pipe_context *brw_create(struct pipe_screen *screen,
{
struct brw_context *brw;
screen->winsys->printf(screen->winsys,
"%s: creating brw_context with pci id 0x%x\n",
__FUNCTION__, pci_id);
debug_printf("%s: creating brw_context with pci id 0x%x\n",
__FUNCTION__, pci_id);
brw = CALLOC_STRUCT(brw_context);
if (brw == NULL)

View file

@ -183,12 +183,12 @@ extern int BRW_DEBUG;
#define DEBUG_MIPTREE 0x800000
#define DBG(...) do { \
if (BRW_DEBUG & FILE_DEBUG_FLAG) \
brw->pipe.winsys->printf(brw->pipe.winsys, __VA_ARGS__); \
if (BRW_DEBUG & FILE_DEBUG_FLAG) \
debug_printf(__VA_ARGS__); \
} while(0)
#define PRINT(...) do { \
brw->pipe.winsys->printf(brw->pipe.winsys, __VA_ARGS__); \
debug_printf(brw->pipe.winsys, __VA_ARGS__); \
} while(0)
struct brw_state_flags {

View file

@ -133,7 +133,7 @@ struct nv40_context {
unsigned fallback_swrast;
/* Context state */
unsigned dirty;
unsigned dirty, draw_dirty;
struct pipe_scissor_state scissor;
unsigned stipple[32];
struct pipe_clip_state clip;
@ -153,8 +153,10 @@ struct nv40_context {
unsigned nr_samplers;
unsigned nr_textures;
unsigned dirty_samplers;
struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX];
struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX];
unsigned vtxbuf_nr;
struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX];
unsigned vtxelt_nr;
};
static INLINE struct nv40_context *

View file

@ -423,10 +423,9 @@ nv40_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso)
struct nv40_context *nv40 = nv40_context(pipe);
struct nv40_rasterizer_state *rsso = hwcso;
draw_set_rasterizer_state(nv40->draw, &rsso->pipe);
nv40->rasterizer = hwcso;
nv40->dirty |= NV40_NEW_RAST;
nv40->draw_dirty |= NV40_NEW_RAST;
}
static void
@ -445,19 +444,20 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe,
struct nv40_context *nv40 = nv40_context(pipe);
struct nv40_zsa_state *zsaso = CALLOC(1, sizeof(*zsaso));
struct nouveau_stateobj *so = so_new(32, 0);
struct nouveau_grobj *curie = nv40->screen->curie;
so_method(so, nv40->screen->curie, NV40TCL_DEPTH_FUNC, 3);
so_method(so, curie, NV40TCL_DEPTH_FUNC, 3);
so_data (so, nvgl_comparison_op(cso->depth.func));
so_data (so, cso->depth.writemask ? 1 : 0);
so_data (so, cso->depth.enabled ? 1 : 0);
so_method(so, nv40->screen->curie, NV40TCL_ALPHA_TEST_ENABLE, 3);
so_method(so, curie, NV40TCL_ALPHA_TEST_ENABLE, 3);
so_data (so, cso->alpha.enabled ? 1 : 0);
so_data (so, nvgl_comparison_op(cso->alpha.func));
so_data (so, float_to_ubyte(cso->alpha.ref));
if (cso->stencil[0].enabled) {
so_method(so, nv40->screen->curie, NV40TCL_STENCIL_FRONT_ENABLE, 8);
so_method(so, curie, NV40TCL_STENCIL_FRONT_ENABLE, 8);
so_data (so, cso->stencil[0].enabled ? 1 : 0);
so_data (so, cso->stencil[0].write_mask);
so_data (so, nvgl_comparison_op(cso->stencil[0].func));
@ -467,12 +467,12 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe,
so_data (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
so_data (so, nvgl_stencil_op(cso->stencil[0].zpass_op));
} else {
so_method(so, nv40->screen->curie, NV40TCL_STENCIL_FRONT_ENABLE, 1);
so_method(so, curie, NV40TCL_STENCIL_FRONT_ENABLE, 1);
so_data (so, 0);
}
if (cso->stencil[1].enabled) {
so_method(so, nv40->screen->curie, NV40TCL_STENCIL_BACK_ENABLE, 8);
so_method(so, curie, NV40TCL_STENCIL_BACK_ENABLE, 8);
so_data (so, cso->stencil[1].enabled ? 1 : 0);
so_data (so, cso->stencil[1].write_mask);
so_data (so, nvgl_comparison_op(cso->stencil[1].func));
@ -482,7 +482,7 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe,
so_data (so, nvgl_stencil_op(cso->stencil[1].zfail_op));
so_data (so, nvgl_stencil_op(cso->stencil[1].zpass_op));
} else {
so_method(so, nv40->screen->curie, NV40TCL_STENCIL_BACK_ENABLE, 1);
so_method(so, curie, NV40TCL_STENCIL_BACK_ENABLE, 1);
so_data (so, 0);
}
@ -529,10 +529,9 @@ nv40_vp_state_bind(struct pipe_context *pipe, void *hwcso)
struct nv40_context *nv40 = nv40_context(pipe);
struct nv40_vertex_program *vp = hwcso;
draw_bind_vertex_shader(nv40->draw, vp ? vp->draw : NULL);
nv40->vertprog = hwcso;
nv40->dirty |= NV40_NEW_VERTPROG;
nv40->draw_dirty |= NV40_NEW_VERTPROG;
}
static void
@ -595,10 +594,9 @@ nv40_set_clip_state(struct pipe_context *pipe,
{
struct nv40_context *nv40 = nv40_context(pipe);
draw_set_clip_state(nv40->draw, clip);
nv40->clip = *clip;
nv40->dirty |= NV40_NEW_UCP;
nv40->draw_dirty |= NV40_NEW_UCP;
}
static void
@ -653,10 +651,9 @@ nv40_set_viewport_state(struct pipe_context *pipe,
{
struct nv40_context *nv40 = nv40_context(pipe);
draw_set_viewport_state(nv40->draw, vpt);
nv40->viewport = *vpt;
nv40->dirty |= NV40_NEW_VIEWPORT;
nv40->draw_dirty |= NV40_NEW_VIEWPORT;
}
static void
@ -665,10 +662,11 @@ nv40_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
{
struct nv40_context *nv40 = nv40_context(pipe);
draw_set_vertex_buffers(nv40->draw, count, vb);
memcpy(nv40->vtxbuf, vb, sizeof(*vb) * count);
nv40->vtxbuf_nr = count;
nv40->dirty |= NV40_NEW_ARRAYS;
nv40->draw_dirty |= NV40_NEW_ARRAYS;
}
static void
@ -677,10 +675,11 @@ nv40_set_vertex_elements(struct pipe_context *pipe, unsigned count,
{
struct nv40_context *nv40 = nv40_context(pipe);
draw_set_vertex_elements(nv40->draw, count, ve);
memcpy(nv40->vtxelt, ve, sizeof(*ve) * count);
nv40->vtxelt_nr = count;
nv40->dirty |= NV40_NEW_ARRAYS;
nv40->draw_dirty |= NV40_NEW_ARRAYS;
}
void

View file

@ -42,6 +42,7 @@ struct nv40_vertex_program {
uint32_t ir;
uint32_t or;
uint32_t clip_ctrl;
struct nouveau_stateobj *so;
};

View file

@ -144,6 +144,8 @@ nv40_state_validate(struct nv40_context *nv40)
boolean
nv40_state_validate_swtnl(struct nv40_context *nv40)
{
struct draw_context *draw = nv40->draw;
/* Setup for swtnl */
if (nv40->render_mode == HW) {
NOUVEAU_ERR("hw->swtnl 0x%08x\n", nv40->fallback_swtnl);
@ -155,12 +157,30 @@ nv40_state_validate_swtnl(struct nv40_context *nv40)
nv40->render_mode = SWTNL;
}
if (nv40->draw_dirty & NV40_NEW_VERTPROG)
draw_bind_vertex_shader(draw, nv40->vertprog->draw);
if (nv40->draw_dirty & NV40_NEW_RAST)
draw_set_rasterizer_state(draw, &nv40->rasterizer->pipe);
if (nv40->draw_dirty & NV40_NEW_UCP)
draw_set_clip_state(draw, &nv40->clip);
if (nv40->draw_dirty & NV40_NEW_VIEWPORT)
draw_set_viewport_state(draw, &nv40->viewport);
if (nv40->draw_dirty & NV40_NEW_ARRAYS) {
draw_set_vertex_buffers(draw, nv40->vtxbuf_nr, nv40->vtxbuf);
draw_set_vertex_elements(draw, nv40->vtxelt_nr, nv40->vtxelt);
}
nv40_state_do_validate(nv40, swtnl_states);
if (nv40->fallback_swrast) {
NOUVEAU_ERR("swtnl->swrast 0x%08x\n", nv40->fallback_swrast);
return FALSE;
}
nv40->draw_dirty = 0;
return TRUE;
}

View file

@ -32,7 +32,7 @@ nv40_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp)
case PIPE_FORMAT_R16G16_SSCALED:
case PIPE_FORMAT_R16G16B16_SSCALED:
case PIPE_FORMAT_R16G16B16A16_SSCALED:
*fmt = 5;
*fmt = NV40TCL_VTXFMT_TYPE_USHORT;
break;
default:
pf_sprint_name(fs, pipe);

View file

@ -37,6 +37,8 @@
#define neg(s) nv40_sr_neg((s))
#define abs(s) nv40_sr_abs((s))
#define NV40_VP_INST_DEST_CLIP(n) ((~0 - 6) + (n))
struct nv40_vpc {
struct nv40_vertex_program *vp;
@ -200,6 +202,36 @@ emit_dst(struct nv40_vpc *vpc, uint32_t *hw, int slot, struct nv40_sreg dst)
case NV40_VP_INST_DEST_TC(5): vp->or |= (1 << 19); break;
case NV40_VP_INST_DEST_TC(6): vp->or |= (1 << 20); break;
case NV40_VP_INST_DEST_TC(7): vp->or |= (1 << 21); break;
case NV40_VP_INST_DEST_CLIP(0):
vp->or |= (1 << 6);
vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE0;
dst.index = NV40_VP_INST_DEST_FOGC;
break;
case NV40_VP_INST_DEST_CLIP(1):
vp->or |= (1 << 7);
vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE1;
dst.index = NV40_VP_INST_DEST_FOGC;
break;
case NV40_VP_INST_DEST_CLIP(2):
vp->or |= (1 << 8);
vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE2;
dst.index = NV40_VP_INST_DEST_FOGC;
break;
case NV40_VP_INST_DEST_CLIP(3):
vp->or |= (1 << 9);
vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE3;
dst.index = NV40_VP_INST_DEST_PSZ;
break;
case NV40_VP_INST_DEST_CLIP(4):
vp->or |= (1 << 10);
vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE4;
dst.index = NV40_VP_INST_DEST_PSZ;
break;
case NV40_VP_INST_DEST_CLIP(5):
vp->or |= (1 << 11);
vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE5;
dst.index = NV40_VP_INST_DEST_PSZ;
break;
default:
break;
}
@ -391,6 +423,11 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc,
int ai = -1, ci = -1, ii = -1;
int i;
struct {
struct nv40_sreg dst;
unsigned m;
} clip;
if (finst->Instruction.Opcode == TGSI_OPCODE_END)
return TRUE;
@ -464,6 +501,47 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc,
dst = tgsi_dst(vpc, &finst->FullDstRegisters[0]);
mask = tgsi_mask(finst->FullDstRegisters[0].DstRegister.WriteMask);
/* If writing to clip distance regs, need to modify instruction to
* change which component is written to. On NV40 the clip regs
* are the unused components (yzw) of FOGC/PSZ.
*/
clip.dst = none;
if (dst.type == NV40SR_OUTPUT &&
dst.index >= NV40_VP_INST_DEST_CLIP(0) &&
dst.index <= NV40_VP_INST_DEST_CLIP(5)) {
unsigned n = dst.index - NV40_VP_INST_DEST_CLIP(0);
unsigned m[] =
{ MASK_Y, MASK_Z, MASK_W, MASK_Y, MASK_Z, MASK_W };
/* Some instructions we can get away with swizzling and/or
* changing the writemask. Others, we'll use a temp reg.
*/
switch (finst->Instruction.Opcode) {
case TGSI_OPCODE_DST:
case TGSI_OPCODE_EXP:
case TGSI_OPCODE_LIT:
case TGSI_OPCODE_LOG:
case TGSI_OPCODE_XPD:
clip.dst = dst;
clip.m = m[n];
dst = temp(vpc);
break;
case TGSI_OPCODE_DP3:
case TGSI_OPCODE_DP4:
case TGSI_OPCODE_DPH:
case TGSI_OPCODE_POW:
case TGSI_OPCODE_RCP:
case TGSI_OPCODE_RSQ:
mask = m[n];
break;
default:
for (i = 0; i < finst->Instruction.NumSrcRegs; i++)
src[i] = swz(src[i], X, X, X, X);
mask = m[n];
break;
}
}
switch (finst->Instruction.Opcode) {
case TGSI_OPCODE_ABS:
arith(vpc, 0, OP_MOV, dst, mask, abs(src[0]), none, none);
@ -561,6 +639,11 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc,
return FALSE;
}
if (clip.dst.type != NV40SR_NONE) {
arith(vpc, 0, OP_MOV, clip.dst, clip.m,
swz(dst, X, X, X, X), none, none);
}
release_temps(vpc);
return TRUE;
}
@ -612,6 +695,15 @@ nv40_vertprog_parse_decl_output(struct nv40_vpc *vpc,
return FALSE;
}
break;
#if 0
case TGSI_SEMANTIC_CLIP:
if (fdec->Semantic.SemanticIndex >= 6) {
NOUVEAU_ERR("bad clip distance index\n");
return FALSE;
}
hw = NV40_VP_INST_DEST_CLIP(fdec->Semantic.SemanticIndex);
break;
#endif
default:
NOUVEAU_ERR("bad output semantic\n");
return FALSE;
@ -782,6 +874,7 @@ nv40_vertprog_validate(struct nv40_context *nv40)
{
struct nouveau_winsys *nvws = nv40->nvws;
struct pipe_winsys *ws = nv40->pipe.winsys;
struct nouveau_grobj *curie = nv40->screen->curie;
struct nv40_vertex_program *vp;
struct pipe_buffer *constbuf;
boolean upload_code = FALSE, upload_data = FALSE;
@ -825,12 +918,14 @@ check_gpu_resources:
assert(0);
}
so = so_new(5, 0);
so_method(so, nv40->screen->curie, NV40TCL_VP_START_FROM_ID, 1);
so = so_new(7, 0);
so_method(so, curie, NV40TCL_VP_START_FROM_ID, 1);
so_data (so, vp->exec->start);
so_method(so, nv40->screen->curie, NV40TCL_VP_ATTRIB_EN, 2);
so_method(so, curie, NV40TCL_VP_ATTRIB_EN, 2);
so_data (so, vp->ir);
so_data (so, vp->or);
so_method(so, curie, NV40TCL_CLIP_PLANE_ENABLE, 1);
so_data (so, vp->clip_ctrl);
so_ref(so, &vp->so);
upload_code = TRUE;

View file

@ -439,7 +439,8 @@ static INLINE uint pf_get_component_bits( enum pipe_format format, uint comp )
*/
static INLINE uint pf_get_bits( enum pipe_format format )
{
if (pf_layout(format) == PIPE_FORMAT_LAYOUT_RGBAZS) {
switch (pf_layout(format)) {
case PIPE_FORMAT_LAYOUT_RGBAZS:
return
pf_get_component_bits( format, PIPE_FORMAT_COMP_R ) +
pf_get_component_bits( format, PIPE_FORMAT_COMP_G ) +
@ -447,11 +448,11 @@ static INLINE uint pf_get_bits( enum pipe_format format )
pf_get_component_bits( format, PIPE_FORMAT_COMP_A ) +
pf_get_component_bits( format, PIPE_FORMAT_COMP_Z ) +
pf_get_component_bits( format, PIPE_FORMAT_COMP_S );
}
else {
assert( pf_layout(format) == PIPE_FORMAT_LAYOUT_YCBCR );
/* TODO */
case PIPE_FORMAT_LAYOUT_YCBCR:
assert( format == PIPE_FORMAT_YCBCR || format == PIPE_FORMAT_YCBCR_REV );
/* return effective bits per pixel */
return 16;
default:
assert( 0 );
return 0;
}

View file

@ -111,7 +111,8 @@ struct pipe_rasterizer_state
unsigned line_stipple_pattern:16;
unsigned line_last_pixel:1;
unsigned bypass_clipping:1;
unsigned bypass_vs:1; /**< vertices are already fully transformed */
unsigned bypass_vs:1; /**< Skip the vertex shader. Note that the shader is
still needed though, to indicate inputs/outputs */
unsigned origin_lower_left:1; /**< Is (0,0) the lower-left corner? */
unsigned flatshade_first:1; /**< take color attribute from the first vertex of a primitive */

View file

@ -73,10 +73,6 @@ struct pipe_winsys
struct pipe_surface *surf,
void *context_private );
/** Debug output */
void (*printf)( struct pipe_winsys *sws,
const char *, ... );
/** allocate a new surface (no context dependency) */
struct pipe_surface *(*surface_alloc)(struct pipe_winsys *ws);

View file

@ -1,6 +1,6 @@
Import('*')
if dri:
if 'intel' in env['winsys'] and dri:
SConscript([
'dri/SConscript',
])

View file

@ -243,15 +243,6 @@ intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
static void
intel_printf( struct pipe_winsys *winsys, const char *fmtString, ... )
{
va_list args;
va_start( args, fmtString );
vfprintf(stderr, fmtString, args);
va_end( args );
}
static const char *
intel_get_name( struct pipe_winsys *winsys )
{
@ -277,7 +268,6 @@ intel_create_pipe_winsys( int fd )
iws->winsys.buffer_unmap = intel_buffer_unmap;
iws->winsys.buffer_destroy = intel_buffer_destroy;
iws->winsys.flush_frontbuffer = intel_flush_frontbuffer;
iws->winsys.printf = intel_printf;
iws->winsys.get_name = intel_get_name;
iws->winsys.surface_alloc = intel_i915_surface_alloc;
iws->winsys.surface_alloc_storage = intel_i915_surface_alloc_storage;

View file

@ -20,15 +20,6 @@ nouveau_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf,
nouveau_copy_buffer(dPriv, surf, NULL);
}
static void
nouveau_printf(struct pipe_winsys *pws, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
}
static const char *
nouveau_get_name(struct pipe_winsys *pws)
{
@ -215,7 +206,6 @@ nouveau_create_pipe_winsys(struct nouveau_context *nv)
pws = &nvpws->pws;
pws->flush_frontbuffer = nouveau_flush_frontbuffer;
pws->printf = nouveau_printf;
pws->surface_alloc = nouveau_surface_alloc;
pws->surface_alloc_storage = nouveau_surface_alloc_storage;

View file

@ -303,16 +303,6 @@ xm_flush_frontbuffer(struct pipe_winsys *pws,
static void
xm_printf(struct pipe_winsys *pws, const char *fmtString, ...)
{
va_list args;
va_start( args, fmtString );
vfprintf(stderr, fmtString, args);
va_end( args );
}
static const char *
xm_get_name(struct pipe_winsys *pws)
{
@ -635,7 +625,6 @@ xmesa_get_pipe_winsys_aub(struct xmesa_visual *xm_vis)
ws->base.fence_finish = xm_fence_finish;
ws->base.flush_frontbuffer = xm_flush_frontbuffer;
ws->base.printf = xm_printf;
ws->base.get_name = xm_get_name;
}

View file

@ -311,15 +311,6 @@ aub_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
static void
aub_printf( struct pipe_winsys *winsys, const char *fmtString, ... )
{
va_list args;
va_start( args, fmtString );
vfprintf(stderr, fmtString, args);
va_end( args );
}
static const char *
aub_get_name( struct pipe_winsys *winsys )
{
@ -344,7 +335,6 @@ xmesa_create_pipe_winsys_aub( void )
iws->winsys.buffer_unmap = aub_buffer_unmap;
iws->winsys.buffer_destroy = aub_buffer_destroy;
iws->winsys.flush_frontbuffer = aub_flush_frontbuffer;
iws->winsys.printf = aub_printf;
iws->winsys.get_name = aub_get_name;
iws->winsys.surface_alloc = aub_i915_surface_alloc;

View file

@ -193,15 +193,6 @@ xm_wait_idle(struct pipe_winsys *pws)
/* no-op */
}
static void
xm_printf(struct pipe_winsys *pws, const char *fmtString, ...)
{
va_list args;
va_start( args, fmtString );
vfprintf(stderr, fmtString, args);
va_end( args );
}
static const char *
xm_get_name(struct pipe_winsys *pws)
{
@ -353,7 +344,6 @@ xmesa_create_pipe_winsys( XMesaContext xmesa )
xws->winsys.flush_frontbuffer = xm_flush_frontbuffer;
xws->winsys.wait_idle = xm_wait_idle;
xws->winsys.printf = xm_printf;
xws->winsys.get_name = xm_get_name;
xws->xmesa = xmesa;

View file

@ -2643,14 +2643,14 @@ white_char
' ' .or '\t' .or '\n' .or '\r';
comment_block
'#' .and .loop comment_char .and new_line;
'#' .and .loop comment_char .and optional_new_line;
/* All ASCII characters except '\r', '\n' and '\0' */
comment_char
'\x0E'-'\xFF' .or '\x01'-'\x09' .or '\x0B'-'\x0C';
new_line
'\n' .or crlf .or '\0';
optional_new_line
'\n' .or crlf .or .true;
crlf
'\r' .and '\n';

View file

@ -1242,11 +1242,11 @@
"white_char\n"
" ' ' .or '\\t' .or '\\n' .or '\\r';\n"
"comment_block\n"
" '#' .and .loop comment_char .and new_line;\n"
" '#' .and .loop comment_char .and optional_new_line;\n"
"comment_char\n"
" '\\x0E'-'\\xFF' .or '\\x01'-'\\x09' .or '\\x0B'-'\\x0C';\n"
"new_line\n"
" '\\n' .or crlf .or '\\0';\n"
"optional_new_line\n"
" '\\n' .or crlf .or .true;\n"
"crlf\n"
" '\\r' .and '\\n';\n"
"semicolon\n"

View file

@ -59,6 +59,19 @@
/**
* glBitmaps are drawn as textured quads. The user's bitmap pattern
* is stored in a texture image. An alpha8 texture format is used.
* The fragment shader samples a bit (texel) from the texture, then
* discards the fragment if the bit is off.
*
* Note that we actually store the inverse image of the bitmap to
* simplify the fragment program. An "on" bit gets stored as texel=0x0
* and an "off" bit is stored as texel=0xff. Then we kill the
* fragment if the negated texel value is less than zero.
*/
/**
* The bitmap cache attempts to accumulate multiple glBitmap calls in a
* buffer which is then rendered en mass upon a flush, state change, etc.
@ -102,7 +115,7 @@ make_bitmap_fragment_program(GLcontext *ctx)
if (!p)
return NULL;
p->NumInstructions = 5;
p->NumInstructions = 3;
p->Instructions = _mesa_alloc_instructions(p->NumInstructions);
if (!p->Instructions) {
@ -121,33 +134,11 @@ make_bitmap_fragment_program(GLcontext *ctx)
p->Instructions[ic].TexSrcTarget = TEXTURE_2D_INDEX;
ic++;
/* SWZ tmp0.x, tmp0.x, 1111; # tmp0.x = 1.0 */
p->Instructions[ic].Opcode = OPCODE_SWZ;
p->Instructions[ic].DstReg.File = PROGRAM_TEMPORARY;
p->Instructions[ic].DstReg.Index = 0;
p->Instructions[ic].DstReg.WriteMask = WRITEMASK_X;
p->Instructions[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
p->Instructions[ic].SrcReg[0].Index = 0;
p->Instructions[ic].SrcReg[0].Swizzle
= MAKE_SWIZZLE4(SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE );
ic++;
/* SUB tmp0, tmp0.wwww, tmp0.xxxx; # tmp0.w -= 1 */
p->Instructions[ic].Opcode = OPCODE_SUB;
p->Instructions[ic].DstReg.File = PROGRAM_TEMPORARY;
p->Instructions[ic].DstReg.Index = 0;
p->Instructions[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
p->Instructions[ic].SrcReg[0].Index = 0;
p->Instructions[ic].SrcReg[0].Swizzle = SWIZZLE_WWWW;
p->Instructions[ic].SrcReg[1].File = PROGRAM_TEMPORARY;
p->Instructions[ic].SrcReg[1].Index = 0;
p->Instructions[ic].SrcReg[1].Swizzle = SWIZZLE_XXXX; /* 1.0 */
ic++;
/* KIL if tmp0 < 0 */
/* KIL if -tmp0 < 0 # texel=0 -> keep / texel=0 -> discard */
p->Instructions[ic].Opcode = OPCODE_KIL;
p->Instructions[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
p->Instructions[ic].SrcReg[0].Index = 0;
p->Instructions[ic].SrcReg[0].NegateBase = NEGATE_XYZW;
ic++;
/* END; */
@ -289,7 +280,7 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
for (col = 0; col < width; col++) {
/* set texel to 255 if bit is set */
destRow[comp] = (*src & mask) ? 255 : 0;
destRow[comp] = (*src & mask) ? 0x0 : 0xff;
destRow += cpp;
if (mask == 128U) {
@ -311,7 +302,7 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
for (col = 0; col < width; col++) {
/* set texel to 255 if bit is set */
destRow[comp] =(*src & mask) ? 255 : 0;
destRow[comp] =(*src & mask) ? 0x0 : 0xff;
destRow += cpp;
if (mask == 1U) {
@ -350,16 +341,21 @@ setup_bitmap_vertex_data(struct st_context *st,
{
struct pipe_context *pipe = st->pipe;
const struct gl_framebuffer *fb = st->ctx->DrawBuffer;
const GLboolean invert = (st_fb_orientation(fb) == Y_0_TOP);
const GLfloat fb_width = fb->Width;
const GLfloat fb_height = fb->Height;
const GLfloat x0 = x;
const GLfloat x1 = x + width;
const GLfloat y0 = invert ? ((int) fb->Height - y - height) : y;
const GLfloat y1 = invert ? (y0 + height) : y + height;
const GLfloat y0 = y;
const GLfloat y1 = y + height;
const GLfloat bias = st->bitmap_texcoord_bias;
const GLfloat xBias = bias / (x1-x0);
const GLfloat yBias = bias / (y1-y0);
const GLfloat sLeft = 0.0 + xBias, sRight = 1.0 + xBias;
const GLfloat tTop = 1.0 - yBias, tBot = 1.0 - tTop - yBias;
const GLfloat tTop = yBias, tBot = 1.0 - tTop - yBias;
const GLfloat clip_x0 = x0 / fb_width * 2.0 - 1.0;
const GLfloat clip_y0 = y0 / fb_height * 2.0 - 1.0;
const GLfloat clip_x1 = x1 / fb_width * 2.0 - 1.0;
const GLfloat clip_y1 = y1 / fb_height * 2.0 - 1.0;
GLuint i;
void *buf;
@ -369,24 +365,26 @@ setup_bitmap_vertex_data(struct st_context *st,
sizeof(st->bitmap.vertices));
}
/* positions, texcoords */
st->bitmap.vertices[0][0][0] = x0;
st->bitmap.vertices[0][0][1] = y0;
/* Positions are in clip coords since we need to do clipping in case
* the bitmap quad goes beyond the window bounds.
*/
st->bitmap.vertices[0][0][0] = clip_x0;
st->bitmap.vertices[0][0][1] = clip_y0;
st->bitmap.vertices[0][2][0] = sLeft;
st->bitmap.vertices[0][2][1] = tTop;
st->bitmap.vertices[1][0][0] = x1;
st->bitmap.vertices[1][0][1] = y0;
st->bitmap.vertices[1][0][0] = clip_x1;
st->bitmap.vertices[1][0][1] = clip_y0;
st->bitmap.vertices[1][2][0] = sRight;
st->bitmap.vertices[1][2][1] = tTop;
st->bitmap.vertices[2][0][0] = x1;
st->bitmap.vertices[2][0][1] = y1;
st->bitmap.vertices[2][0][0] = clip_x1;
st->bitmap.vertices[2][0][1] = clip_y1;
st->bitmap.vertices[2][2][0] = sRight;
st->bitmap.vertices[2][2][1] = tBot;
st->bitmap.vertices[3][0][0] = x0;
st->bitmap.vertices[3][0][1] = y1;
st->bitmap.vertices[3][0][0] = clip_x0;
st->bitmap.vertices[3][0][1] = clip_y1;
st->bitmap.vertices[3][2][0] = sLeft;
st->bitmap.vertices[3][2][1] = tBot;
@ -437,17 +435,12 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
cso_save_rasterizer(cso);
cso_save_samplers(cso);
cso_save_sampler_textures(cso);
cso_save_viewport(cso);
/* rasterizer state: just scissor */
{
struct pipe_rasterizer_state rasterizer;
memset(&rasterizer, 0, sizeof(rasterizer));
if (ctx->Scissor.Enabled)
rasterizer.scissor = 1;
rasterizer.bypass_clipping = 1;
cso_set_rasterizer(cso, &rasterizer);
}
st->bitmap.rasterizer.scissor = ctx->Scissor.Enabled;
cso_set_rasterizer(cso, &st->bitmap.rasterizer);
/* fragment shader state: TEX lookup program */
pipe->bind_fs_state(pipe, stfp->driver_shader);
@ -456,21 +449,26 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
pipe->bind_vs_state(pipe, st->bitmap.vs);
/* sampler / texture state */
cso_single_sampler(cso, 0, &st->bitmap.sampler);
cso_single_sampler_done(cso);
pipe->set_sampler_textures(pipe, 1, &pt);
/* viewport state: viewport matching window dims */
{
struct pipe_sampler_state sampler;
memset(&sampler, 0, sizeof(sampler));
sampler.wrap_s = PIPE_TEX_WRAP_CLAMP;
sampler.wrap_t = PIPE_TEX_WRAP_CLAMP;
sampler.wrap_r = PIPE_TEX_WRAP_CLAMP;
sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
sampler.normalized_coords = 1;
cso_single_sampler(cso, 0, &sampler);
cso_single_sampler_done(cso);
pipe->set_sampler_textures(pipe, 1, &pt);
const struct gl_framebuffer *fb = st->ctx->DrawBuffer;
const GLboolean invert = (st_fb_orientation(fb) == Y_0_TOP);
const float width = fb->Width;
const float height = fb->Height;
struct pipe_viewport_state vp;
vp.scale[0] = 0.5 * width;
vp.scale[1] = height * (invert ? -0.5 : 0.5);
vp.scale[2] = 1.0;
vp.scale[3] = 1.0;
vp.translate[0] = 0.5 * width;
vp.translate[1] = 0.5 * height;
vp.translate[2] = 0.0;
vp.translate[3] = 0.0;
cso_set_viewport(cso, &vp);
}
/* draw textured quad */
@ -487,18 +485,18 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
/* restore state */
cso_restore_rasterizer(cso);
cso_restore_samplers(cso);
cso_restore_sampler_textures(cso);
cso_restore_viewport(cso);
/* shaders don't go through cso yet */
pipe->bind_fs_state(pipe, st->fp->driver_shader);
pipe->bind_vs_state(pipe, st->vp->driver_shader);
pipe->set_sampler_textures(pipe, ctx->st->state.num_textures,
ctx->st->state.sampler_texture);
}
static void
reset_cache(struct st_context *st)
{
memset(st->bitmap.cache->buffer, 0, sizeof(st->bitmap.cache->buffer));
memset(st->bitmap.cache->buffer, 0xff, sizeof(st->bitmap.cache->buffer));
st->bitmap.cache->empty = GL_TRUE;
st->bitmap.cache->xmin = 1000000;
@ -635,7 +633,7 @@ accum_bitmap(struct st_context *st,
/* XXX try to combine this code with code in make_bitmap_texture() */
#define SET_PIXEL(COL, ROW) \
cache->buffer[py + (ROW)][px + (COL)] = 0xff;
cache->buffer[py + (ROW)][px + (COL)] = 0x0;
for (row = 0; row < height; row++) {
const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack,
@ -742,6 +740,22 @@ st_init_bitmap_functions(struct dd_function_table *functions)
void
st_init_bitmap(struct st_context *st)
{
struct pipe_sampler_state *sampler = &st->bitmap.sampler;
/* init sampler state once */
memset(sampler, 0, sizeof(*sampler));
sampler->wrap_s = PIPE_TEX_WRAP_CLAMP;
sampler->wrap_t = PIPE_TEX_WRAP_CLAMP;
sampler->wrap_r = PIPE_TEX_WRAP_CLAMP;
sampler->min_img_filter = PIPE_TEX_FILTER_NEAREST;
sampler->min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
sampler->mag_img_filter = PIPE_TEX_FILTER_NEAREST;
sampler->normalized_coords = 1;
/* init baseline rasterizer state once */
memset(&st->bitmap.rasterizer, 0, sizeof(st->bitmap.rasterizer));
st->bitmap.rasterizer.bypass_vs = 1;
init_bitmap_cache(st);
}

View file

@ -530,14 +530,13 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
cso_save_rasterizer(cso);
cso_save_viewport(cso);
cso_save_samplers(cso);
cso_save_sampler_textures(cso);
/* rasterizer state: just scissor */
{
struct pipe_rasterizer_state rasterizer;
memset(&rasterizer, 0, sizeof(rasterizer));
if (ctx->Scissor.Enabled)
rasterizer.scissor = 1;
rasterizer.scissor = ctx->Scissor.Enabled;
cso_set_rasterizer(cso, &rasterizer);
}
@ -581,9 +580,7 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
}
/* texture state: */
{
pipe->set_sampler_textures(pipe, 1, &pt);
}
pipe->set_sampler_textures(pipe, 1, &pt);
/* Compute window coords (y=0=bottom) with pixel zoom.
* Recall that these coords are transformed by the current
@ -604,12 +601,11 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
cso_restore_rasterizer(cso);
cso_restore_viewport(cso);
cso_restore_samplers(cso);
cso_restore_sampler_textures(cso);
/* shaders don't go through cso yet */
pipe->bind_fs_state(pipe, st->fp->driver_shader);
pipe->bind_vs_state(pipe, st->vp->driver_shader);
pipe->set_sampler_textures(pipe, ctx->st->state.num_textures,
ctx->st->state.sampler_texture);
}

View file

@ -105,7 +105,7 @@ static void st_glFlush(GLcontext *ctx)
void st_finish( struct st_context *st )
{
struct pipe_fence_handle *fence;
struct pipe_fence_handle *fence = NULL;
st_gl_flush(st, PIPE_FLUSH_RENDER_CACHE, &fence);

View file

@ -148,6 +148,8 @@ struct st_context
struct st_fragment_program *program; /**< bitmap tex/kil program */
GLuint user_prog_sn; /**< user fragment program serial no. */
struct st_fragment_program *combined_prog;
struct pipe_rasterizer_state rasterizer;
struct pipe_sampler_state sampler;
struct pipe_shader_state vert_shader;
void *vs;
float vertices[4][3][4]; /**< vertex pos + color + texcoord */