summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/cell
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/cell')
-rw-r--r--src/gallium/drivers/cell/ppu/cell_clear.c4
-rw-r--r--src/gallium/drivers/cell/ppu/cell_context.c4
-rw-r--r--src/gallium/drivers/cell/ppu/cell_draw_arrays.c35
-rw-r--r--src/gallium/drivers/cell/ppu/cell_draw_arrays.h24
-rw-r--r--src/gallium/drivers/cell/ppu/cell_pipe_state.c6
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_emit.c14
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_shader.c4
-rw-r--r--src/gallium/drivers/cell/ppu/cell_surface.c11
-rw-r--r--src/gallium/drivers/cell/ppu/cell_texture.c69
-rw-r--r--src/gallium/drivers/cell/ppu/cell_texture.h1
-rw-r--r--src/gallium/drivers/cell/ppu/cell_vbuf.c1
-rw-r--r--src/gallium/drivers/cell/ppu/cell_vertex_fetch.c4
-rw-r--r--src/gallium/drivers/cell/ppu/cell_vertex_shader.c5
-rw-r--r--src/gallium/drivers/cell/spu/spu_exec.h2
-rw-r--r--src/gallium/drivers/cell/spu/spu_render.c2
-rw-r--r--src/gallium/drivers/cell/spu/spu_tri.c1
-rw-r--r--src/gallium/drivers/cell/spu/spu_util.c2
-rw-r--r--src/gallium/drivers/cell/spu/spu_vertex_shader.c26
18 files changed, 176 insertions, 39 deletions
diff --git a/src/gallium/drivers/cell/ppu/cell_clear.c b/src/gallium/drivers/cell/ppu/cell_clear.c
index cee0917b631..a421c95c8e8 100644
--- a/src/gallium/drivers/cell/ppu/cell_clear.c
+++ b/src/gallium/drivers/cell/ppu/cell_clear.c
@@ -48,6 +48,7 @@ void
cell_clear_surface(struct pipe_context *pipe, struct pipe_surface *ps,
unsigned clearValue)
{
+ struct pipe_screen *screen = pipe->screen;
struct cell_context *cell = cell_context(pipe);
uint surfIndex;
@@ -56,7 +57,8 @@ cell_clear_surface(struct pipe_context *pipe, struct pipe_surface *ps,
if (!cell->cbuf_map[0])
- cell->cbuf_map[0] = pipe_surface_map(ps);
+ cell->cbuf_map[0] = screen->surface_map(screen, ps,
+ PIPE_BUFFER_USAGE_GPU_WRITE);
if (ps == cell->framebuffer.zsbuf) {
surfIndex = 1;
diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c
index 5af95a3c103..9ff4e86943b 100644
--- a/src/gallium/drivers/cell/ppu/cell_context.c
+++ b/src/gallium/drivers/cell/ppu/cell_context.c
@@ -73,11 +73,13 @@ cell_draw_create(struct cell_context *cell)
{
struct draw_context *draw = draw_create();
+#if 0 /* broken */
if (getenv("GALLIUM_CELL_VS")) {
/* plug in SPU-based vertex transformation code */
draw->shader_queue_flush = cell_vertex_shader_queue_flush;
draw->driver_private = cell;
}
+#endif
return draw;
}
@@ -108,6 +110,8 @@ cell_create_context(struct pipe_screen *screen,
cell->pipe.draw_arrays = cell_draw_arrays;
cell->pipe.draw_elements = cell_draw_elements;
+ cell->pipe.draw_range_elements = cell_draw_range_elements;
+ cell->pipe.set_edgeflags = cell_set_edgeflags;
cell->pipe.clear = cell_clear_surface;
cell->pipe.flush = cell_flush;
diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
index 6e08cf6fe88..f02dffe1245 100644
--- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
+++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
@@ -59,7 +59,8 @@ cell_map_constant_buffers(struct cell_context *sp)
}
draw_set_mapped_constant_buffer(sp->draw,
- sp->mapped_constants[PIPE_SHADER_VERTEX]);
+ sp->mapped_constants[PIPE_SHADER_VERTEX],
+ sp->constants[PIPE_SHADER_VERTEX].size);
}
static void
@@ -92,10 +93,12 @@ cell_draw_arrays(struct pipe_context *pipe, unsigned mode,
* XXX should the element buffer be specified/bound with a separate function?
*/
boolean
-cell_draw_elements(struct pipe_context *pipe,
- struct pipe_buffer *indexBuffer,
- unsigned indexSize,
- unsigned mode, unsigned start, unsigned count)
+cell_draw_range_elements(struct pipe_context *pipe,
+ struct pipe_buffer *indexBuffer,
+ unsigned indexSize,
+ unsigned min_index,
+ unsigned max_index,
+ unsigned mode, unsigned start, unsigned count)
{
struct cell_context *sp = cell_context(pipe);
struct draw_context *draw = sp->draw;
@@ -152,3 +155,25 @@ cell_draw_elements(struct pipe_context *pipe,
return TRUE;
}
+
+
+boolean
+cell_draw_elements(struct pipe_context *pipe,
+ struct pipe_buffer *indexBuffer,
+ unsigned indexSize,
+ unsigned mode, unsigned start, unsigned count)
+{
+ return cell_draw_range_elements( pipe, indexBuffer,
+ indexSize,
+ 0, 0xffffffff,
+ mode, start, count );
+}
+
+
+
+void
+cell_set_edgeflags(struct pipe_context *pipe, const unsigned *edgeflags)
+{
+ struct cell_context *cell = cell_context(pipe);
+ draw_set_edgeflags(cell->draw, edgeflags);
+}
diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.h b/src/gallium/drivers/cell/ppu/cell_draw_arrays.h
index d5df4aa05f8..cd35ec17b4e 100644
--- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.h
+++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.h
@@ -29,14 +29,26 @@
#define CELL_DRAW_ARRAYS_H
-boolean cell_draw_arrays(struct pipe_context *pipe, unsigned mode,
- unsigned start, unsigned count);
+extern boolean
+cell_draw_arrays(struct pipe_context *pipe, unsigned mode,
+ unsigned start, unsigned count);
-boolean cell_draw_elements(struct pipe_context *pipe,
- struct pipe_buffer *indexBuffer,
- unsigned indexSize,
- unsigned mode, unsigned start, unsigned count);
+extern boolean
+cell_draw_elements(struct pipe_context *pipe,
+ struct pipe_buffer *indexBuffer,
+ unsigned indexSize,
+ unsigned mode, unsigned start, unsigned count);
+extern boolean
+cell_draw_range_elements(struct pipe_context *pipe,
+ struct pipe_buffer *indexBuffer,
+ unsigned indexSize,
+ unsigned min_index,
+ unsigned max_index,
+ unsigned mode, unsigned start, unsigned count);
+
+extern void
+cell_set_edgeflags(struct pipe_context *pipe, const unsigned *edgeflags);
#endif /* CELL_DRAW_ARRAYS_H */
diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c
index 971d65d09e4..fe5437023b9 100644
--- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c
+++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c
@@ -294,6 +294,8 @@ cell_set_framebuffer_state(struct pipe_context *pipe,
struct pipe_surface *csurf = fb->cbufs[0];
struct pipe_surface *zsurf = fb->zsbuf;
uint i;
+ uint flags = (PIPE_BUFFER_USAGE_GPU_WRITE |
+ PIPE_BUFFER_USAGE_GPU_READ);
/* unmap old surfaces */
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
@@ -313,10 +315,10 @@ cell_set_framebuffer_state(struct pipe_context *pipe,
/* map new surfaces */
if (csurf)
- cell->cbuf_map[0] = pipe_surface_map(csurf);
+ cell->cbuf_map[0] = pipe_surface_map(csurf, flags);
if (zsurf)
- cell->zsbuf_map = pipe_surface_map(zsurf);
+ cell->zsbuf_map = pipe_surface_map(zsurf, flags);
cell->dirty |= CELL_NEW_FRAMEBUFFER;
}
diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c
index 3646a0ee4f3..9d88c1cf3d2 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_emit.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c
@@ -162,13 +162,13 @@ cell_emit_state(struct cell_context *cell)
const struct draw_context *const draw = cell->draw;
struct cell_shader_info info;
- info.num_outputs = draw->num_vs_outputs;
- info.declarations = (uintptr_t) draw->machine.Declarations;
- info.num_declarations = draw->machine.NumDeclarations;
- info.instructions = (uintptr_t) draw->machine.Instructions;
- info.num_instructions = draw->machine.NumInstructions;
- info.immediates = (uintptr_t) draw->machine.Imms;
- info.num_immediates = draw->machine.ImmLimit / 4;
+ info.num_outputs = draw_num_vs_outputs(draw);
+ info.declarations = (uintptr_t) draw->vs.machine.Declarations;
+ info.num_declarations = draw->vs.machine.NumDeclarations;
+ info.instructions = (uintptr_t) draw->vs.machine.Instructions;
+ info.num_instructions = draw->vs.machine.NumInstructions;
+ info.immediates = (uintptr_t) draw->vs.machine.Imms;
+ info.num_immediates = draw->vs.machine.ImmLimit / 4;
emit_state_cmd(cell, CELL_CMD_STATE_BIND_VS,
& info, sizeof(info));
diff --git a/src/gallium/drivers/cell/ppu/cell_state_shader.c b/src/gallium/drivers/cell/ppu/cell_state_shader.c
index cd96b317faa..86bcad05e9e 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_shader.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_shader.c
@@ -41,7 +41,7 @@
static INLINE struct cell_fragment_shader_state *
cell_fragment_shader_state(void *shader)
{
- return (struct pipe_shader_state *) shader;
+ return (struct cell_fragment_shader_state *) shader;
}
@@ -49,7 +49,7 @@ cell_fragment_shader_state(void *shader)
static INLINE struct cell_vertex_shader_state *
cell_vertex_shader_state(void *shader)
{
- return (struct pipe_shader_state *) shader;
+ return (struct cell_vertex_shader_state *) shader;
}
diff --git a/src/gallium/drivers/cell/ppu/cell_surface.c b/src/gallium/drivers/cell/ppu/cell_surface.c
index 2d31ad89a66..d9e3b510dc0 100644
--- a/src/gallium/drivers/cell/ppu/cell_surface.c
+++ b/src/gallium/drivers/cell/ppu/cell_surface.c
@@ -26,11 +26,12 @@
**************************************************************************/
#include "pipe/p_defines.h"
-#include "util/u_memory.h"
#include "pipe/p_inlines.h"
#include "pipe/p_winsys.h"
-#include "util/p_tile.h"
+#include "util/u_memory.h"
#include "util/u_rect.h"
+#include "util/u_tile.h"
+
#include "cell_context.h"
#include "cell_surface.h"
@@ -46,12 +47,12 @@ cell_surface_copy(struct pipe_context *pipe,
{
assert( dst->cpp == src->cpp );
- pipe_copy_rect(pipe_surface_map(dst),
+ pipe_copy_rect(pipe_surface_map(dst, PIPE_BUFFER_USAGE_CPU_WRITE),
&dst->block,
dst->stride,
dstx, dsty,
width, height,
- pipe_surface_map(src),
+ pipe_surface_map(src, PIPE_BUFFER_USAGE_CPU_READ),
do_flip ? -src->stride : src->stride,
srcx, do_flip ? height - 1 - srcy : srcy);
@@ -81,7 +82,7 @@ cell_surface_fill(struct pipe_context *pipe,
unsigned width, unsigned height, unsigned value)
{
unsigned i, j;
- void *dst_map = pipe_surface_map(dst);
+ void *dst_map = pipe_surface_map(dst, PIPE_BUFFER_USAGE_CPU_WRITE);
assert(dst->stride > 0);
diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c
index 1add81373db..5a0942bbd6e 100644
--- a/src/gallium/drivers/cell/ppu/cell_texture.c
+++ b/src/gallium/drivers/cell/ppu/cell_texture.c
@@ -33,8 +33,9 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_inlines.h"
-#include "util/u_memory.h"
#include "pipe/p_winsys.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
#include "cell_context.h"
#include "cell_state.h"
@@ -68,11 +69,13 @@ cell_texture_layout(struct cell_texture * spt)
pt->nblocksx[level] = pf_get_nblocksx(&pt->block, width);
pt->nblocksy[level] = pf_get_nblocksy(&pt->block, height);
+ spt->stride[level] = pt->nblocksx[level] * pt->block.size;
+
spt->level_offset[level] = spt->buffer_size;
spt->buffer_size += (pt->nblocksy[level] *
((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) *
- pt->nblocksx[level] * pt->block.size;
+ pt->nblocksx[level] * pt->block.size);
width = minify(width);
height = minify(height);
@@ -147,7 +150,8 @@ cell_texture_update(struct pipe_context *pipe, struct pipe_texture *texture,
static struct pipe_surface *
cell_get_tex_surface_screen(struct pipe_screen *screen,
struct pipe_texture *pt,
- unsigned face, unsigned level, unsigned zslice)
+ unsigned face, unsigned level, unsigned zslice,
+ unsigned usage)
{
struct pipe_winsys *ws = screen->winsys;
struct cell_texture *spt = cell_texture(pt);
@@ -166,6 +170,10 @@ cell_get_tex_surface_screen(struct pipe_screen *screen,
ps->nblocksy = pt->nblocksy[level];
ps->stride = spt->stride[level];
ps->offset = spt->level_offset[level];
+ ps->usage = usage;
+
+ /* XXX may need to override usage flags (see sp_texture.c) */
+
if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) {
ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) *
@@ -228,10 +236,11 @@ cell_tile_texture(struct cell_context *cell,
assert(w % TILE_SIZE == 0);
assert(h % TILE_SIZE == 0);
- surf = screen->get_tex_surface(screen, &texture->base, face, level, zslice);
+ surf = screen->get_tex_surface(screen, &texture->base, face, level, zslice,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
ASSERT(surf);
- src = (const uint *) pipe_surface_map(surf);
+ src = (const uint *) pipe_surface_map(surf, PIPE_BUFFER_USAGE_CPU_WRITE);
if (texture->tiled_data) {
align_free(texture->tiled_data);
@@ -246,11 +255,12 @@ cell_tile_texture(struct cell_context *cell,
}
-
void
cell_update_texture_mapping(struct cell_context *cell)
{
+#if 0
uint face = 0, level = 0, zslice = 0;
+#endif
uint i;
for (i = 0; i < CELL_MAX_SAMPLERS; i++) {
@@ -275,10 +285,52 @@ cell_update_texture_mapping(struct cell_context *cell)
}
+static void *
+cell_surface_map( struct pipe_screen *screen,
+ struct pipe_surface *surface,
+ unsigned flags )
+{
+ ubyte *map;
+
+ if (flags & ~surface->usage) {
+ assert(0);
+ return NULL;
+ }
+
+ map = screen->winsys->buffer_map( screen->winsys, surface->buffer, flags );
+ if (map == NULL)
+ return NULL;
+
+ /* May want to different things here depending on read/write nature
+ * of the map:
+ */
+ if (surface->texture &&
+ (flags & PIPE_BUFFER_USAGE_CPU_WRITE))
+ {
+ /* Do something to notify sharing contexts of a texture change.
+ * In softpipe, that would mean flushing the texture cache.
+ */
+#if 0
+ cell_screen(screen)->timestamp++;
+#endif
+ }
+
+ return map + surface->offset;
+}
+
+
+static void
+cell_surface_unmap(struct pipe_screen *screen,
+ struct pipe_surface *surface)
+{
+ screen->winsys->buffer_unmap( screen->winsys, surface->buffer );
+}
+
+
void
cell_init_texture_functions(struct cell_context *cell)
{
- cell->pipe.texture_update = cell_texture_update;
+ /*cell->pipe.texture_update = cell_texture_update;*/
}
void
@@ -287,4 +339,7 @@ cell_init_screen_texture_funcs(struct pipe_screen *screen)
screen->texture_create = cell_texture_create_screen;
screen->texture_release = cell_texture_release_screen;
screen->get_tex_surface = cell_get_tex_surface_screen;
+
+ screen->surface_map = cell_surface_map;
+ screen->surface_unmap = cell_surface_unmap;
}
diff --git a/src/gallium/drivers/cell/ppu/cell_texture.h b/src/gallium/drivers/cell/ppu/cell_texture.h
index fcee069d055..6d37e95ebce 100644
--- a/src/gallium/drivers/cell/ppu/cell_texture.h
+++ b/src/gallium/drivers/cell/ppu/cell_texture.h
@@ -41,6 +41,7 @@ struct cell_texture
struct pipe_texture base;
unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned long stride[PIPE_MAX_TEXTURE_LEVELS];
/* The data is held here:
*/
diff --git a/src/gallium/drivers/cell/ppu/cell_vbuf.c b/src/gallium/drivers/cell/ppu/cell_vbuf.c
index 3a181b585c5..e4230c7a5ff 100644
--- a/src/gallium/drivers/cell/ppu/cell_vbuf.c
+++ b/src/gallium/drivers/cell/ppu/cell_vbuf.c
@@ -37,6 +37,7 @@
#include "cell_spu.h"
#include "cell_vbuf.h"
#include "draw/draw_vbuf.h"
+#include "util/u_memory.h"
/** Allow vertex data to be inlined after RENDER command */
diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c b/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c
index 49d5443cde7..2ece0250f6f 100644
--- a/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c
+++ b/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c
@@ -260,6 +260,7 @@ emit_fetch(struct spe_function *p,
void cell_update_vertex_fetch(struct draw_context *draw)
{
+#if 0
struct cell_context *const cell =
(struct cell_context *) draw->driver_private;
struct spe_function *p = &cell->attrib_fetch;
@@ -337,4 +338,7 @@ void cell_update_vertex_fetch(struct draw_context *draw)
cell->attrib_fetch_offsets[function_index[i]];
}
}
+#else
+ assert(0);
+#endif
}
diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c
index f753960a0fb..3658947715f 100644
--- a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c
+++ b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c
@@ -32,6 +32,7 @@
#include "pipe/p_defines.h"
#include "pipe/p_context.h"
#include "pipe/p_winsys.h"
+#include "util/u_math.h"
#include "cell_context.h"
#include "cell_draw_arrays.h"
@@ -50,6 +51,7 @@
void
cell_vertex_shader_queue_flush(struct draw_context *draw)
{
+#if 0
struct cell_context *const cell =
(struct cell_context *) draw->driver_private;
struct cell_command_vs *const vs = &cell_global.command[0].vs;
@@ -138,4 +140,7 @@ cell_vertex_shader_queue_flush(struct draw_context *draw)
draw->vs.post_nr = draw->vs.queue_nr;
draw->vs.queue_nr = 0;
+#else
+ assert(0);
+#endif
}
diff --git a/src/gallium/drivers/cell/spu/spu_exec.h b/src/gallium/drivers/cell/spu/spu_exec.h
index c68f78f59b6..86056799405 100644
--- a/src/gallium/drivers/cell/spu/spu_exec.h
+++ b/src/gallium/drivers/cell/spu/spu_exec.h
@@ -99,7 +99,7 @@ struct spu_exec_machine
* 1 address
*/
struct spu_exec_vector Temps[TGSI_EXEC_NUM_TEMPS
- + TGSI_EXEC_NUM_ADDRS + 1]
+ + TGSI_EXEC_NUM_TEMP_EXTRAS + 1]
ALIGN16_ATTRIB;
struct spu_exec_vector *Addrs;
diff --git a/src/gallium/drivers/cell/spu/spu_render.c b/src/gallium/drivers/cell/spu/spu_render.c
index 6df59abd36d..305dc988810 100644
--- a/src/gallium/drivers/cell/spu/spu_render.c
+++ b/src/gallium/drivers/cell/spu/spu_render.c
@@ -35,7 +35,7 @@
#include "spu_tri.h"
#include "spu_tile.h"
#include "cell/common.h"
-
+#include "util/u_memory.h"
/**
diff --git a/src/gallium/drivers/cell/spu/spu_tri.c b/src/gallium/drivers/cell/spu/spu_tri.c
index 8944ef171eb..2a4e0b423ca 100644
--- a/src/gallium/drivers/cell/spu/spu_tri.c
+++ b/src/gallium/drivers/cell/spu/spu_tri.c
@@ -32,6 +32,7 @@
#include <transpose_matrix4x4.h>
#include "pipe/p_compiler.h"
#include "pipe/p_format.h"
+#include "util/u_math.h"
#include "spu_colorpack.h"
#include "spu_main.h"
#include "spu_texture.h"
diff --git a/src/gallium/drivers/cell/spu/spu_util.c b/src/gallium/drivers/cell/spu/spu_util.c
index dbcf4b0eb93..b25ca4eafc0 100644
--- a/src/gallium/drivers/cell/spu/spu_util.c
+++ b/src/gallium/drivers/cell/spu/spu_util.c
@@ -1,4 +1,6 @@
+
#include "pipe/p_shader_tokens.h"
+#include "pipe/p_debug.h"
#include "tgsi/tgsi_parse.h"
//#include "tgsi_build.h"
#include "tgsi/tgsi_util.h"
diff --git a/src/gallium/drivers/cell/spu/spu_vertex_shader.c b/src/gallium/drivers/cell/spu/spu_vertex_shader.c
index a1e81975e65..f81d19fea1c 100644
--- a/src/gallium/drivers/cell/spu/spu_vertex_shader.c
+++ b/src/gallium/drivers/cell/spu/spu_vertex_shader.c
@@ -36,13 +36,35 @@
#include "pipe/p_state.h"
#include "pipe/p_shader_tokens.h"
-#include "spu_vertex_shader.h"
-#include "spu_exec.h"
+#include "util/u_math.h"
#include "draw/draw_private.h"
#include "draw/draw_context.h"
#include "cell/common.h"
+#include "spu_vertex_shader.h"
+#include "spu_exec.h"
#include "spu_main.h"
+
+#define MAX_VERTEX_SIZE ((2 + PIPE_MAX_SHADER_OUTPUTS) * 4 * sizeof(float))
+
+
+#define CLIP_RIGHT_BIT 0x01
+#define CLIP_LEFT_BIT 0x02
+#define CLIP_TOP_BIT 0x04
+#define CLIP_BOTTOM_BIT 0x08
+#define CLIP_FAR_BIT 0x10
+#define CLIP_NEAR_BIT 0x20
+
+
+static INLINE float
+dot4(const float *a, const float *b)
+{
+ return (a[0]*b[0] +
+ a[1]*b[1] +
+ a[2]*b[2] +
+ a[3]*b[3]);
+}
+
static INLINE unsigned
compute_clipmask(const float *clip, /*const*/ float plane[][4], unsigned nr)
{