summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/cell
diff options
context:
space:
mode:
authorBen Skeggs <skeggsb@gmail.com>2008-09-11 06:09:05 +1000
committerBen Skeggs <skeggsb@gmail.com>2008-09-11 06:09:05 +1000
commit7158203b081ad34c03382f07e0df748eae235e9b (patch)
treeee61efebbafb5464ec090c21b5e05533588789a1 /src/gallium/drivers/cell
parent02025148c28d03d644e3d66dde1a423fe21e1c44 (diff)
parenteb5b16d278e0f7ee0121049e43dfee1d52f2b0f7 (diff)
Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
Conflicts: configs/default
Diffstat (limited to 'src/gallium/drivers/cell')
-rw-r--r--src/gallium/drivers/cell/common.h5
-rw-r--r--src/gallium/drivers/cell/ppu/Makefile2
-rw-r--r--src/gallium/drivers/cell/ppu/cell_batch.c56
-rw-r--r--src/gallium/drivers/cell/ppu/cell_batch.h3
-rw-r--r--src/gallium/drivers/cell/ppu/cell_clear.c36
-rw-r--r--src/gallium/drivers/cell/ppu/cell_context.c46
-rw-r--r--src/gallium/drivers/cell/ppu/cell_context.h29
-rw-r--r--src/gallium/drivers/cell/ppu/cell_draw_arrays.c73
-rw-r--r--src/gallium/drivers/cell/ppu/cell_draw_arrays.h10
-rw-r--r--src/gallium/drivers/cell/ppu/cell_flush.c14
-rw-r--r--src/gallium/drivers/cell/ppu/cell_flush.h2
-rw-r--r--src/gallium/drivers/cell/ppu/cell_pipe_state.c31
-rw-r--r--src/gallium/drivers/cell/ppu/cell_render.c2
-rw-r--r--src/gallium/drivers/cell/ppu/cell_screen.c2
-rw-r--r--src/gallium/drivers/cell/ppu/cell_spu.c28
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state.h16
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_derived.c31
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_emit.c34
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_shader.c32
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_vertex.c12
-rw-r--r--src/gallium/drivers/cell/ppu/cell_surface.c99
-rw-r--r--src/gallium/drivers/cell/ppu/cell_texture.c143
-rw-r--r--src/gallium/drivers/cell/ppu/cell_texture.h1
-rw-r--r--src/gallium/drivers/cell/ppu/cell_vbuf.c13
-rw-r--r--src/gallium/drivers/cell/ppu/cell_vertex_fetch.c4
-rw-r--r--src/gallium/drivers/cell/ppu/cell_vertex_shader.c7
-rw-r--r--src/gallium/drivers/cell/ppu/cell_winsys.c2
-rw-r--r--src/gallium/drivers/cell/spu/Makefile2
-rw-r--r--src/gallium/drivers/cell/spu/spu_exec.c151
-rw-r--r--src/gallium/drivers/cell/spu/spu_exec.h2
-rw-r--r--src/gallium/drivers/cell/spu/spu_main.c138
-rw-r--r--src/gallium/drivers/cell/spu/spu_main.h8
-rw-r--r--src/gallium/drivers/cell/spu/spu_per_fragment_op.c4
-rw-r--r--src/gallium/drivers/cell/spu/spu_render.c2
-rw-r--r--src/gallium/drivers/cell/spu/spu_tile.c6
-rw-r--r--src/gallium/drivers/cell/spu/spu_tri.c2
-rw-r--r--src/gallium/drivers/cell/spu/spu_util.c24
-rw-r--r--src/gallium/drivers/cell/spu/spu_vertex_fetch.c3
-rw-r--r--src/gallium/drivers/cell/spu/spu_vertex_shader.c29
39 files changed, 690 insertions, 414 deletions
diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h
index f430e88b9c..c0ca201e1d 100644
--- a/src/gallium/drivers/cell/common.h
+++ b/src/gallium/drivers/cell/common.h
@@ -34,7 +34,6 @@
#define CELL_COMMON_H
#include "pipe/p_compiler.h"
-#include "pipe/p_util.h"
#include "pipe/p_format.h"
#include "pipe/p_state.h"
@@ -107,6 +106,9 @@
#define CELL_BUFFER_STATUS_USED 20
+#define CELL_DEBUG_CHECKER (1 << 0)
+#define CELL_DEBUG_SYNC (1 << 1)
+
/**
*/
@@ -264,6 +266,7 @@ struct cell_init_info
{
unsigned id;
unsigned num_spus;
+ unsigned debug_flags; /**< mask of CELL_DEBUG_x flags */
struct cell_command *cmd;
/** Buffers for command batches, vertex/index data */
diff --git a/src/gallium/drivers/cell/ppu/Makefile b/src/gallium/drivers/cell/ppu/Makefile
index 0389a9554c..25473e200c 100644
--- a/src/gallium/drivers/cell/ppu/Makefile
+++ b/src/gallium/drivers/cell/ppu/Makefile
@@ -5,7 +5,7 @@
TOP = ../../../../..
-include $(TOP)/configs/linux-cell
+include $(TOP)/configs/current
# This is the "top-level" cell PPU driver code, will get pulled into libGL.so
diff --git a/src/gallium/drivers/cell/ppu/cell_batch.c b/src/gallium/drivers/cell/ppu/cell_batch.c
index f45e5f25b6..16882c0129 100644
--- a/src/gallium/drivers/cell/ppu/cell_batch.c
+++ b/src/gallium/drivers/cell/ppu/cell_batch.c
@@ -32,6 +32,13 @@
+/**
+ * Search the buffer pool for an empty/free buffer and return its index.
+ * Buffers are used for storing vertex data, state and commands which
+ * will be sent to the SPUs.
+ * If no empty buffers are available, wait for one.
+ * \return buffer index in [0, CELL_NUM_BUFFERS-1]
+ */
uint
cell_get_empty_buffer(struct cell_context *cell)
{
@@ -74,6 +81,11 @@ cell_get_empty_buffer(struct cell_context *cell)
}
+/**
+ * Flush the current batch buffer to the SPUs.
+ * An empty buffer will be found and set as the new current batch buffer
+ * for subsequent commands/data.
+ */
void
cell_batch_flush(struct cell_context *cell)
{
@@ -93,11 +105,11 @@ cell_batch_flush(struct cell_context *cell)
/*
printf("cell_batch_dispatch: buf %u at %p, size %u\n",
- batch, &cell->batch_buffer[batch][0], size);
+ batch, &cell->buffer[batch][0], size);
*/
/*
- * Build "BATCH" command and sent to all SPUs.
+ * Build "BATCH" command and send to all SPUs.
*/
cmd_word = CELL_CMD_BATCH | (batch << 8) | (size << 16);
@@ -120,6 +132,9 @@ cell_batch_flush(struct cell_context *cell)
}
+/**
+ * Return the number of bytes free in the current batch buffer.
+ */
uint
cell_batch_free_space(const struct cell_context *cell)
{
@@ -129,7 +144,9 @@ cell_batch_free_space(const struct cell_context *cell)
/**
- * Append data to current batch.
+ * Append data to the current batch buffer.
+ * \param data address of block of bytes to append
+ * \param bytes size of block of bytes
*/
void
cell_batch_append(struct cell_context *cell, const void *data, uint bytes)
@@ -165,6 +182,10 @@ cell_batch_append(struct cell_context *cell, const void *data, uint bytes)
}
+/**
+ * Allocate space in the current batch buffer for 'bytes' space.
+ * \return address in batch buffer to put data
+ */
void *
cell_batch_alloc(struct cell_context *cell, uint bytes)
{
@@ -172,6 +193,10 @@ cell_batch_alloc(struct cell_context *cell, uint bytes)
}
+/**
+ * Same as \sa cell_batch_alloc, but return an address at a particular
+ * alignment.
+ */
void *
cell_batch_alloc_aligned(struct cell_context *cell, uint bytes,
uint alignment)
@@ -215,3 +240,28 @@ cell_batch_alloc_aligned(struct cell_context *cell, uint bytes,
return pos;
}
+
+
+/**
+ * One-time init of batch buffers.
+ */
+void
+cell_init_batch_buffers(struct cell_context *cell)
+{
+ uint spu, buf;
+
+ /* init command, vertex/index buffer info */
+ for (buf = 0; buf < CELL_NUM_BUFFERS; buf++) {
+ cell->buffer_size[buf] = 0;
+
+ /* init batch buffer status values,
+ * mark 0th buffer as used, rest as free.
+ */
+ for (spu = 0; spu < cell->num_spus; spu++) {
+ if (buf == 0)
+ cell->buffer_status[spu][buf][0] = CELL_BUFFER_STATUS_USED;
+ else
+ cell->buffer_status[spu][buf][0] = CELL_BUFFER_STATUS_FREE;
+ }
+ }
+}
diff --git a/src/gallium/drivers/cell/ppu/cell_batch.h b/src/gallium/drivers/cell/ppu/cell_batch.h
index a6eee0a8b1..f74dd60079 100644
--- a/src/gallium/drivers/cell/ppu/cell_batch.h
+++ b/src/gallium/drivers/cell/ppu/cell_batch.h
@@ -54,5 +54,8 @@ extern void *
cell_batch_alloc_aligned(struct cell_context *cell, uint bytes,
uint alignment);
+extern void
+cell_init_batch_buffers(struct cell_context *cell);
+
#endif /* CELL_BATCH_H */
diff --git a/src/gallium/drivers/cell/ppu/cell_clear.c b/src/gallium/drivers/cell/ppu/cell_clear.c
index 3ffe09add6..c9c0c721bb 100644
--- a/src/gallium/drivers/cell/ppu/cell_clear.c
+++ b/src/gallium/drivers/cell/ppu/cell_clear.c
@@ -34,7 +34,8 @@
#include <assert.h>
#include <stdint.h>
#include "pipe/p_inlines.h"
-#include "pipe/p_util.h"
+#include "util/u_memory.h"
+#include "util/u_pack_color.h"
#include "cell/common.h"
#include "cell_clear.h"
#include "cell_context.h"
@@ -44,10 +45,32 @@
#include "cell_state.h"
+/**
+ * Convert packed pixel from one format to another.
+ */
+static unsigned
+convert_color(enum pipe_format srcFormat, unsigned srcColor,
+ enum pipe_format dstFormat)
+{
+ ubyte r, g, b, a;
+ unsigned dstColor;
+
+ util_unpack_color_ub(srcFormat, &srcColor, &r, &g, &b, &a);
+ util_pack_color_ub(r, g, b, a, dstFormat, &dstColor);
+
+ return dstColor;
+}
+
+
+
+/**
+ * Called via pipe->clear()
+ */
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,16 +79,25 @@ 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) {
+ /* clear z/stencil buffer */
surfIndex = 1;
}
else {
+ /* clear color buffer */
surfIndex = 0;
+
+ if (ps->format != PIPE_FORMAT_A8R8G8B8_UNORM) {
+ clearValue = convert_color(PIPE_FORMAT_A8R8G8B8_UNORM, clearValue,
+ ps->format);
+ }
}
+ /* Build a CLEAR command and place it in the current batch buffer */
{
struct cell_command_clear_surface *clr
= (struct cell_command_clear_surface *)
diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c
index 12eb5aa254..71f1a3049d 100644
--- a/src/gallium/drivers/cell/ppu/cell_context.c
+++ b/src/gallium/drivers/cell/ppu/cell_context.c
@@ -35,7 +35,7 @@
#include "pipe/p_defines.h"
#include "pipe/p_format.h"
-#include "pipe/p_util.h"
+#include "util/u_memory.h"
#include "pipe/p_winsys.h"
#include "pipe/p_screen.h"
@@ -43,11 +43,11 @@
#include "draw/draw_private.h"
#include "cell/common.h"
+#include "cell_batch.h"
#include "cell_clear.h"
#include "cell_context.h"
#include "cell_draw_arrays.h"
#include "cell_flush.h"
-#include "cell_render.h"
#include "cell_state.h"
#include "cell_surface.h"
#include "cell_spu.h"
@@ -73,22 +73,32 @@ 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;
}
+#ifdef DEBUG
+static const struct debug_named_value cell_debug_flags[] = {
+ {"checker", CELL_DEBUG_CHECKER},/**< modulate tile clear color by SPU ID */
+ {"sync", CELL_DEBUG_SYNC}, /**< SPUs do synchronous DMA */
+ {NULL, 0}
+};
+#endif
+
+
struct pipe_context *
cell_create_context(struct pipe_screen *screen,
struct cell_winsys *cws)
{
struct cell_context *cell;
- uint spu, buf;
/* some fields need to be 16-byte aligned, so align the whole object */
cell = (struct cell_context*) align_malloc(sizeof(struct cell_context), 16);
@@ -102,13 +112,6 @@ cell_create_context(struct pipe_screen *screen,
cell->pipe.screen = screen;
cell->pipe.destroy = cell_destroy_context;
- /* state setters */
- cell->pipe.set_vertex_buffers = cell_set_vertex_buffers;
- cell->pipe.set_vertex_elements = cell_set_vertex_elements;
-
- cell->pipe.draw_arrays = cell_draw_arrays;
- cell->pipe.draw_elements = cell_draw_elements;
-
cell->pipe.clear = cell_clear_surface;
cell->pipe.flush = cell_flush;
@@ -118,20 +121,28 @@ cell_create_context(struct pipe_screen *screen,
cell->pipe.wait_query = cell_wait_query;
#endif
+ cell_init_draw_functions(cell);
cell_init_state_functions(cell);
cell_init_shader_functions(cell);
cell_init_surface_functions(cell);
cell_init_texture_functions(cell);
+ cell_init_vertex_functions(cell);
cell->draw = cell_draw_create(cell);
cell_init_vbuf(cell);
+
draw_set_rasterize_stage(cell->draw, cell->vbuf);
/* convert all points/lines to tris for the time being */
draw_wide_point_threshold(cell->draw, 0.0);
draw_wide_line_threshold(cell->draw, 0.0);
+ /* get env vars or read config file to get debug flags */
+ cell->debug_flags = debug_get_flags_option("CELL_DEBUG",
+ cell_debug_flags,
+ 0 );
+
/*
* SPU stuff
*/
@@ -142,20 +153,7 @@ cell_create_context(struct pipe_screen *screen,
cell_start_spus(cell);
- /* init command, vertex/index buffer info */
- for (buf = 0; buf < CELL_NUM_BUFFERS; buf++) {
- cell->buffer_size[buf] = 0;
-
- /* init batch buffer status values,
- * mark 0th buffer as used, rest as free.
- */
- for (spu = 0; spu < cell->num_spus; spu++) {
- if (buf == 0)
- cell->buffer_status[spu][buf][0] = CELL_BUFFER_STATUS_USED;
- else
- cell->buffer_status[spu][buf][0] = CELL_BUFFER_STATUS_FREE;
- }
- }
+ cell_init_batch_buffers(cell);
return &cell->pipe;
}
diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h
index f1d1ca89a9..8cec9f45b2 100644
--- a/src/gallium/drivers/cell/ppu/cell_context.h
+++ b/src/gallium/drivers/cell/ppu/cell_context.h
@@ -39,8 +39,13 @@
#include "rtasm/rtasm_ppc_spe.h"
#include "tgsi/tgsi_scan.h"
+
struct cell_vbuf_render;
+
+/**
+ * Cell vertex shader state, subclass of pipe_shader_state.
+ */
struct cell_vertex_shader_state
{
struct pipe_shader_state shader;
@@ -49,6 +54,9 @@ struct cell_vertex_shader_state
};
+/**
+ * Cell fragment shader state, subclass of pipe_shader_state.
+ */
struct cell_fragment_shader_state
{
struct pipe_shader_state shader;
@@ -57,7 +65,11 @@ struct cell_fragment_shader_state
};
-struct cell_blend_state {
+/**
+ * Cell blend state atom, subclass of pipe_blend_state.
+ */
+struct cell_blend_state
+{
struct pipe_blend_state base;
/**
@@ -67,17 +79,24 @@ struct cell_blend_state {
};
-struct cell_depth_stencil_alpha_state {
- struct pipe_depth_stencil_alpha_state base;
+/**
+ * Cell depth/stencil/alpha state atom, subclass of
+ * pipe_depth_stencil_alpha_state.
+ */
+struct cell_depth_stencil_alpha_state
+{
+ struct pipe_depth_stencil_alpha_state base;
/**
* Generated code to perform alpha, stencil, and depth testing on the SPE
*/
struct spe_function code;
-
};
+/**
+ * Per-context state, subclass of pipe_context.
+ */
struct cell_context
{
struct pipe_context pipe;
@@ -144,6 +163,8 @@ struct cell_context
struct spe_function attrib_fetch;
unsigned attrib_fetch_offsets[PIPE_MAX_ATTRIBS];
+
+ unsigned debug_flags;
};
diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
index 6e08cf6fe8..880d535320 100644
--- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
+++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
@@ -34,6 +34,7 @@
#include "pipe/p_defines.h"
#include "pipe/p_context.h"
#include "pipe/p_winsys.h"
+#include "pipe/p_inlines.h"
#include "cell_context.h"
#include "cell_draw_arrays.h"
@@ -59,7 +60,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
@@ -75,14 +77,6 @@ cell_unmap_constant_buffers(struct cell_context *sp)
}
-boolean
-cell_draw_arrays(struct pipe_context *pipe, unsigned mode,
- unsigned start, unsigned count)
-{
- return cell_draw_elements(pipe, NULL, 0, mode, start, count);
-}
-
-
/**
* Draw vertex arrays, with optional indexing.
@@ -91,11 +85,13 @@ 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)
+static 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)
{
struct cell_context *sp = cell_context(pipe);
struct draw_context *draw = sp->draw;
@@ -113,7 +109,7 @@ cell_draw_elements(struct pipe_context *pipe,
* Map vertex buffers
*/
for (i = 0; i < sp->num_vertex_buffers; i++) {
- void *buf = pipe->winsys->buffer_map(pipe->winsys,
+ void *buf = pipe_buffer_map(pipe->screen,
sp->vertex_buffer[i].buffer,
PIPE_BUFFER_USAGE_CPU_READ);
cell_flush_buffer_range(sp, buf, sp->vertex_buffer[i].buffer->size);
@@ -121,7 +117,7 @@ cell_draw_elements(struct pipe_context *pipe,
}
/* Map index buffer, if present */
if (indexBuffer) {
- void *mapped_indexes = pipe->winsys->buffer_map(pipe->winsys,
+ void *mapped_indexes = pipe_buffer_map(pipe->screen,
indexBuffer,
PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes);
@@ -140,11 +136,11 @@ cell_draw_elements(struct pipe_context *pipe,
*/
for (i = 0; i < sp->num_vertex_buffers; i++) {
draw_set_mapped_vertex_buffer(draw, i, NULL);
- pipe->winsys->buffer_unmap(pipe->winsys, sp->vertex_buffer[i].buffer);
+ pipe_buffer_unmap(pipe->screen, sp->vertex_buffer[i].buffer);
}
if (indexBuffer) {
draw_set_mapped_element_buffer(draw, 0, NULL);
- pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer);
+ pipe_buffer_unmap(pipe->screen, indexBuffer);
}
/* Note: leave drawing surfaces mapped */
@@ -152,3 +148,44 @@ cell_draw_elements(struct pipe_context *pipe,
return TRUE;
}
+
+
+static 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 );
+}
+
+
+static boolean
+cell_draw_arrays(struct pipe_context *pipe, unsigned mode,
+ unsigned start, unsigned count)
+{
+ return cell_draw_elements(pipe, NULL, 0, mode, start, count);
+}
+
+
+static void
+cell_set_edgeflags(struct pipe_context *pipe, const unsigned *edgeflags)
+{
+ struct cell_context *cell = cell_context(pipe);
+ draw_set_edgeflags(cell->draw, edgeflags);
+}
+
+
+
+void
+cell_init_draw_functions(struct cell_context *cell)
+{
+ 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;
+}
+
diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.h b/src/gallium/drivers/cell/ppu/cell_draw_arrays.h
index d5df4aa05f..148873aa67 100644
--- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.h
+++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.h
@@ -29,14 +29,8 @@
#define CELL_DRAW_ARRAYS_H
-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 void
+cell_init_draw_functions(struct cell_context *cell);
#endif /* CELL_DRAW_ARRAYS_H */
diff --git a/src/gallium/drivers/cell/ppu/cell_flush.c b/src/gallium/drivers/cell/ppu/cell_flush.c
index 3aaf3de668..6596b72010 100644
--- a/src/gallium/drivers/cell/ppu/cell_flush.c
+++ b/src/gallium/drivers/cell/ppu/cell_flush.c
@@ -34,6 +34,9 @@
#include "draw/draw_context.h"
+/**
+ * Called via pipe->flush()
+ */
void
cell_flush(struct pipe_context *pipe, unsigned flags,
struct pipe_fence_handle **fence)
@@ -50,16 +53,19 @@ cell_flush(struct pipe_context *pipe, unsigned flags,
flags |= CELL_FLUSH_WAIT;
draw_flush( cell->draw );
- cell_flush_int(pipe, flags);
+ cell_flush_int(cell, flags);
}
-/** internal flush */
+/**
+ * Cell internal flush function. Send the current batch buffer to all SPUs.
+ * If flags & CELL_FLUSH_WAIT, do not return until the SPUs are idle.
+ * \param flags bitmask of flags CELL_FLUSH_WAIT, or zero
+ */
void
-cell_flush_int(struct pipe_context *pipe, unsigned flags)
+cell_flush_int(struct cell_context *cell, unsigned flags)
{
static boolean flushing = FALSE; /* recursion catcher */
- struct cell_context *cell = cell_context(pipe);
uint i;
ASSERT(!flushing);
diff --git a/src/gallium/drivers/cell/ppu/cell_flush.h b/src/gallium/drivers/cell/ppu/cell_flush.h
index 8f0645c429..509ae6239a 100644
--- a/src/gallium/drivers/cell/ppu/cell_flush.h
+++ b/src/gallium/drivers/cell/ppu/cell_flush.h
@@ -36,7 +36,7 @@ cell_flush(struct pipe_context *pipe, unsigned flags,
struct pipe_fence_handle **fence);
extern void
-cell_flush_int(struct pipe_context *pipe, unsigned flags);
+cell_flush_int(struct cell_context *cell, unsigned flags);
extern void
cell_flush_buffer_range(struct cell_context *cell, void *ptr,
diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c
index 67b87f16d7..e04cf5f274 100644
--- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c
+++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c
@@ -30,10 +30,11 @@
* Brian Paul
*/
-#include "pipe/p_util.h"
+#include "util/u_memory.h"
#include "pipe/p_inlines.h"
#include "draw/draw_context.h"
#include "cell_context.h"
+#include "cell_flush.h"
#include "cell_state.h"
#include "cell_texture.h"
#include "cell_state_per_fragment.h"
@@ -130,8 +131,9 @@ cell_delete_depth_stencil_alpha_state(struct pipe_context *pipe, void *depth)
}
-static void cell_set_clip_state( struct pipe_context *pipe,
- const struct pipe_clip_state *clip )
+static void
+cell_set_clip_state(struct pipe_context *pipe,
+ const struct pipe_clip_state *clip)
{
struct cell_context *cell = cell_context(pipe);
@@ -294,6 +296,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++) {
@@ -308,15 +312,28 @@ cell_set_framebuffer_state(struct pipe_context *pipe,
cell->zsbuf_map = NULL;
}
- /* update my state */
- cell->framebuffer = *fb;
+ /* Finish any pending rendering to the current surface before
+ * installing a new surface!
+ */
+ cell_flush_int(cell, CELL_FLUSH_WAIT);
+
+ /* update my state
+ * (this is also where old surfaces will finally get freed)
+ */
+ cell->framebuffer.width = fb->width;
+ cell->framebuffer.height = fb->height;
+ cell->framebuffer.num_cbufs = fb->num_cbufs;
+ for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
+ pipe_surface_reference(&cell->framebuffer.cbufs[i], fb->cbufs[i]);
+ }
+ pipe_surface_reference(&cell->framebuffer.zsbuf, fb->zsbuf);
/* 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_render.c b/src/gallium/drivers/cell/ppu/cell_render.c
index b663b37622..dd25ae880e 100644
--- a/src/gallium/drivers/cell/ppu/cell_render.c
+++ b/src/gallium/drivers/cell/ppu/cell_render.c
@@ -33,7 +33,7 @@
#include "cell_context.h"
#include "cell_render.h"
#include "cell_spu.h"
-#include "pipe/p_util.h"
+#include "util/u_memory.h"
#include "draw/draw_private.h"
diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c
index 2bf441a0c5..139b3719b6 100644
--- a/src/gallium/drivers/cell/ppu/cell_screen.c
+++ b/src/gallium/drivers/cell/ppu/cell_screen.c
@@ -26,7 +26,7 @@
**************************************************************************/
-#include "pipe/p_util.h"
+#include "util/u_memory.h"
#include "pipe/p_winsys.h"
#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
diff --git a/src/gallium/drivers/cell/ppu/cell_spu.c b/src/gallium/drivers/cell/ppu/cell_spu.c
index 973c0b1aa1..9508227e29 100644
--- a/src/gallium/drivers/cell/ppu/cell_spu.c
+++ b/src/gallium/drivers/cell/ppu/cell_spu.c
@@ -26,6 +26,11 @@
**************************************************************************/
+/**
+ * Utility/wrappers for communicating with the SPUs.
+ */
+
+
#include <pthread.h>
#include "cell_spu.h"
@@ -40,6 +45,9 @@ helpful headers:
*/
+/**
+ * Cell/SPU info that's not per-context.
+ */
struct cell_global_info cell_global;
@@ -74,7 +82,11 @@ wait_mbox_message(spe_context_ptr_t ctx)
}
-static void *cell_thread_function(void *arg)
+/**
+ * Called by pthread_create() to spawn an SPU thread.
+ */
+static void *
+cell_thread_function(void *arg)
{
struct cell_init_info *init = (struct cell_init_info *) arg;
unsigned entry = SPE_DEFAULT_ENTRY;
@@ -92,7 +104,10 @@ static void *cell_thread_function(void *arg)
/**
- * Create the SPU threads
+ * Create the SPU threads. This is done once during driver initialization.
+ * This involves setting the the "init" message which is sent to each SPU.
+ * The init message specifies an SPU id, total number of SPUs, location
+ * and number of batch buffers, etc.
*/
void
cell_start_spus(struct cell_context *cell)
@@ -100,7 +115,6 @@ cell_start_spus(struct cell_context *cell)
static boolean one_time_init = FALSE;
uint i, j;
-
if (one_time_init) {
fprintf(stderr, "PPU: Multiple rendering contexts not yet supported "
"on Cell.\n");
@@ -120,6 +134,7 @@ cell_start_spus(struct cell_context *cell)
for (i = 0; i < cell->num_spus; i++) {
cell_global.inits[i].id = i;
cell_global.inits[i].num_spus = cell->num_spus;
+ cell_global.inits[i].debug_flags = cell->debug_flags;
cell_global.inits[i].cmd = &cell_global.command[i];
for (j = 0; j < CELL_NUM_BUFFERS; j++) {
cell_global.inits[i].buffers[j] = cell->buffer[j];
@@ -137,14 +152,17 @@ cell_start_spus(struct cell_context *cell)
exit(1);
}
- pthread_create(&cell_global.spe_threads[i], NULL, &cell_thread_function,
- &cell_global.inits[i]);
+ pthread_create(&cell_global.spe_threads[i], /* returned thread handle */
+ NULL, /* pthread attribs */
+ &cell_thread_function, /* start routine */
+ &cell_global.inits[i]); /* thread argument */
}
}
/**
* Tell all the SPUs to stop/exit.
+ * This is done when the driver's exiting / cleaning up.
*/
void
cell_spu_exit(struct cell_context *cell)
diff --git a/src/gallium/drivers/cell/ppu/cell_state.h b/src/gallium/drivers/cell/ppu/cell_state.h
index 82580ea35a..a7771a55a3 100644
--- a/src/gallium/drivers/cell/ppu/cell_state.h
+++ b/src/gallium/drivers/cell/ppu/cell_state.h
@@ -48,19 +48,17 @@
#define CELL_NEW_VERTEX_INFO 0x8000
-void cell_set_vertex_elements(struct pipe_context *,
- unsigned count,
- const struct pipe_vertex_element *);
+extern void
+cell_update_derived( struct cell_context *softpipe );
-void cell_set_vertex_buffers(struct pipe_context *,
- unsigned count,
- const struct pipe_vertex_buffer *);
-void cell_update_derived( struct cell_context *softpipe );
+extern void
+cell_init_shader_functions(struct cell_context *cell);
-void
-cell_init_shader_functions(struct cell_context *cell);
+extern void
+cell_init_vertex_functions(struct cell_context *cell);
+
#endif /* CELL_STATE_H */
diff --git a/src/gallium/drivers/cell/ppu/cell_state_derived.c b/src/gallium/drivers/cell/ppu/cell_state_derived.c
index 5480534ad9..efc4f78364 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_derived.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_derived.c
@@ -25,7 +25,7 @@
*
**************************************************************************/
-#include "pipe/p_util.h"
+#include "util/u_memory.h"
#include "pipe/p_shader_tokens.h"
#include "draw/draw_context.h"
#include "draw/draw_vertex.h"
@@ -35,21 +35,6 @@
#include "cell_state_emit.h"
-static int
-find_vs_output(const struct cell_vertex_shader_state *vs,
- uint semantic_name,
- uint semantic_index)
-{
- uint i;
- for (i = 0; i < vs->info.num_outputs; i++) {
- if (vs->info.output_semantic_name[i] == semantic_name &&
- vs->info.output_semantic_index[i] == semantic_index)
- return i;
- }
- return -1;
-}
-
-
/**
* Determine how to map vertex program outputs to fragment program inputs.
* Basically, this will be used when computing the triangle interpolation
@@ -58,7 +43,6 @@ find_vs_output(const struct cell_vertex_shader_state *vs,
static void
calculate_vertex_layout( struct cell_context *cell )
{
- const struct cell_vertex_shader_state *vs = cell->vs;
const struct cell_fragment_shader_state *fs = cell->fs;
const enum interp_mode colorInterp
= cell->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
@@ -82,7 +66,7 @@ calculate_vertex_layout( struct cell_context *cell )
vinfo->num_attribs = 0;
/* we always want to emit vertex pos */
- src = find_vs_output(vs, TGSI_SEMANTIC_POSITION, 0);
+ src = draw_find_vs_output(cell->draw, TGSI_SEMANTIC_POSITION, 0);
assert(src >= 0);
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src);
@@ -98,14 +82,14 @@ calculate_vertex_layout( struct cell_context *cell )
break;
case TGSI_SEMANTIC_COLOR:
- src = find_vs_output(vs, TGSI_SEMANTIC_COLOR,
- fs->info.input_semantic_index[i]);
+ src = draw_find_vs_output(cell->draw, TGSI_SEMANTIC_COLOR,
+ fs->info.input_semantic_index[i]);
assert(src >= 0);
draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
break;
case TGSI_SEMANTIC_FOG:
- src = find_vs_output(vs, TGSI_SEMANTIC_FOG, 0);
+ src = draw_find_vs_output(cell->draw, TGSI_SEMANTIC_FOG, 0);
#if 1
if (src < 0) /* XXX temp hack, try demos/fogcoord.c with this */
src = 0;
@@ -116,7 +100,7 @@ calculate_vertex_layout( struct cell_context *cell )
case TGSI_SEMANTIC_GENERIC:
/* this includes texcoords and varying vars */
- src = find_vs_output(vs, TGSI_SEMANTIC_GENERIC,
+ src = draw_find_vs_output(cell->draw, TGSI_SEMANTIC_GENERIC,
fs->info.input_semantic_index[i]);
assert(src >= 0);
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
@@ -163,6 +147,9 @@ compute_cliprect(struct cell_context *sp)
+/**
+ * Update derived state, send current state to SPUs prior to rendering.
+ */
void cell_update_derived( struct cell_context *cell )
{
if (cell->dirty & (CELL_NEW_RASTERIZER |
diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c
index 9cae67f091..f2feaa329a 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_emit.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c
@@ -25,7 +25,7 @@
*
**************************************************************************/
-#include "pipe/p_util.h"
+#include "util/u_memory.h"
#include "cell_context.h"
#include "cell_state.h"
#include "cell_state_emit.h"
@@ -47,7 +47,10 @@ emit_state_cmd(struct cell_context *cell, uint cmd,
}
-
+/**
+ * For state marked as 'dirty', construct a state-update command block
+ * and insert it into the current batch buffer.
+ */
void
cell_emit_state(struct cell_context *cell)
{
@@ -90,7 +93,8 @@ cell_emit_state(struct cell_context *cell)
blend.size = (char *) cell->blend->code.csr
- (char *) cell->blend->code.store;
blend.read_fb = TRUE;
- } else {
+ }
+ else {
blend.base = 0;
blend.size = 0;
blend.read_fb = FALSE;
@@ -101,7 +105,6 @@ cell_emit_state(struct cell_context *cell)
if (cell->dirty & CELL_NEW_DEPTH_STENCIL) {
struct cell_command_depth_stencil_alpha_test dsat;
-
if (cell->depth_stencil != NULL) {
dsat.base = (intptr_t) cell->depth_stencil->code.store;
@@ -109,15 +112,15 @@ cell_emit_state(struct cell_context *cell)
- (char *) cell->depth_stencil->code.store;
dsat.read_depth = TRUE;
dsat.read_stencil = FALSE;
- } else {
+ }
+ else {
dsat.base = 0;
dsat.size = 0;
dsat.read_depth = FALSE;
dsat.read_stencil = FALSE;
}
- emit_state_cmd(cell, CELL_CMD_STATE_DEPTH_STENCIL, &dsat,
- sizeof(dsat));
+ emit_state_cmd(cell, CELL_CMD_STATE_DEPTH_STENCIL, &dsat, sizeof(dsat));
}
if (cell->dirty & CELL_NEW_SAMPLER) {
@@ -162,15 +165,14 @@ 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));
+ 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 f5707f2bb8..97e44eeb1a 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_shader.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_shader.c
@@ -26,7 +26,7 @@
**************************************************************************/
#include "pipe/p_defines.h"
-#include "pipe/p_util.h"
+#include "util/u_memory.h"
#include "pipe/p_inlines.h"
#include "pipe/p_winsys.h"
#include "draw/draw_context.h"
@@ -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,11 +49,14 @@ 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;
}
-
+/**
+ * Create fragment shader state.
+ * Called via pipe->create_fs_state()
+ */
static void *
cell_create_fs_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
@@ -77,6 +80,9 @@ cell_create_fs_state(struct pipe_context *pipe,
}
+/**
+ * Called via pipe->bind_fs_state()
+ */
static void
cell_bind_fs_state(struct pipe_context *pipe, void *fs)
{
@@ -88,6 +94,9 @@ cell_bind_fs_state(struct pipe_context *pipe, void *fs)
}
+/**
+ * Called via pipe->delete_fs_state()
+ */
static void
cell_delete_fs_state(struct pipe_context *pipe, void *fs)
{
@@ -98,6 +107,10 @@ cell_delete_fs_state(struct pipe_context *pipe, void *fs)
}
+/**
+ * Create vertex shader state.
+ * Called via pipe->create_vs_state()
+ */
static void *
cell_create_vs_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
@@ -128,6 +141,9 @@ cell_create_vs_state(struct pipe_context *pipe,
}
+/**
+ * Called via pipe->bind_vs_state()
+ */
static void
cell_bind_vs_state(struct pipe_context *pipe, void *vs)
{
@@ -142,6 +158,9 @@ cell_bind_vs_state(struct pipe_context *pipe, void *vs)
}
+/**
+ * Called via pipe->delete_vs_state()
+ */
static void
cell_delete_vs_state(struct pipe_context *pipe, void *vs)
{
@@ -154,6 +173,9 @@ cell_delete_vs_state(struct pipe_context *pipe, void *vs)
}
+/**
+ * Called via pipe->set_constant_buffer()
+ */
static void
cell_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
@@ -166,7 +188,7 @@ cell_set_constant_buffer(struct pipe_context *pipe,
assert(index == 0);
/* note: reference counting */
- pipe_buffer_reference(ws,
+ winsys_buffer_reference(ws,
&cell->constants[shader].buffer,
buf->buffer);
cell->constants[shader].size = buf->size;
diff --git a/src/gallium/drivers/cell/ppu/cell_state_vertex.c b/src/gallium/drivers/cell/ppu/cell_state_vertex.c
index 114684c2a3..fbe55c8472 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_vertex.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_vertex.c
@@ -35,7 +35,7 @@
#include "draw/draw_context.h"
-void
+static void
cell_set_vertex_elements(struct pipe_context *pipe,
unsigned count,
const struct pipe_vertex_element *elements)
@@ -53,7 +53,7 @@ cell_set_vertex_elements(struct pipe_context *pipe,
}
-void
+static void
cell_set_vertex_buffers(struct pipe_context *pipe,
unsigned count,
const struct pipe_vertex_buffer *buffers)
@@ -69,3 +69,11 @@ cell_set_vertex_buffers(struct pipe_context *pipe,
draw_set_vertex_buffers(cell->draw, count, buffers);
}
+
+
+void
+cell_init_vertex_functions(struct cell_context *cell)
+{
+ cell->pipe.set_vertex_buffers = cell_set_vertex_buffers;
+ cell->pipe.set_vertex_elements = cell_set_vertex_elements;
+}
diff --git a/src/gallium/drivers/cell/ppu/cell_surface.c b/src/gallium/drivers/cell/ppu/cell_surface.c
index 5549eb496d..732c64082e 100644
--- a/src/gallium/drivers/cell/ppu/cell_surface.c
+++ b/src/gallium/drivers/cell/ppu/cell_surface.c
@@ -25,106 +25,13 @@
*
**************************************************************************/
-#include "pipe/p_defines.h"
-#include "pipe/p_util.h"
-#include "pipe/p_inlines.h"
-#include "pipe/p_winsys.h"
-#include "util/p_tile.h"
+#include "util/u_rect.h"
#include "cell_context.h"
-#include "cell_surface.h"
-
-
-static void
-cell_surface_copy(struct pipe_context *pipe,
- boolean do_flip,
- struct pipe_surface *dst,
- unsigned dstx, unsigned dsty,
- struct pipe_surface *src,
- unsigned srcx, unsigned srcy,
- unsigned width, unsigned height)
-{
- assert( dst->cpp == src->cpp );
-
- pipe_copy_rect(pipe_surface_map(dst),
- &dst->block,
- dst->stride,
- dstx, dsty,
- width, height,
- pipe_surface_map(src),
- do_flip ? -src->stride : src->stride,
- srcx, do_flip ? height - 1 - srcy : srcy);
-
- pipe_surface_unmap(src);
- pipe_surface_unmap(dst);
-}
-
-
-static void *
-get_pointer(struct pipe_surface *dst, void *dst_map, unsigned x, unsigned y)
-{
- return (char *)dst_map + y / dst->block.height * dst->stride + x / dst->block.width * dst->block.size;
-}
-
-
-#define UBYTE_TO_USHORT(B) ((B) | ((B) << 8))
-
-
-/**
- * Fill a rectangular sub-region. Need better logic about when to
- * push buffers into AGP - will currently do so whenever possible.
- */
-static void
-cell_surface_fill(struct pipe_context *pipe,
- struct pipe_surface *dst,
- unsigned dstx, unsigned dsty,
- unsigned width, unsigned height, unsigned value)
-{
- unsigned i, j;
- void *dst_map = pipe_surface_map(dst);
-
- assert(dst->stride > 0);
-
- switch (dst->block.size) {
- case 1:
- case 2:
- case 4:
- pipe_fill_rect(dst_map, &dst->block, dst->stride, dstx, dsty, width, height, value);
- break;
- case 8:
- {
- /* expand the 4-byte clear value to an 8-byte value */
- ushort *row = (ushort *) get_pointer(dst, dst_map, dstx, dsty);
- ushort val0 = UBYTE_TO_USHORT((value >> 0) & 0xff);
- ushort val1 = UBYTE_TO_USHORT((value >> 8) & 0xff);
- ushort val2 = UBYTE_TO_USHORT((value >> 16) & 0xff);
- ushort val3 = UBYTE_TO_USHORT((value >> 24) & 0xff);
- val0 = (val0 << 8) | val0;
- val1 = (val1 << 8) | val1;
- val2 = (val2 << 8) | val2;
- val3 = (val3 << 8) | val3;
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j++) {
- row[j*4+0] = val0;
- row[j*4+1] = val1;
- row[j*4+2] = val2;
- row[j*4+3] = val3;
- }
- row += dst->stride/2;
- }
- }
- break;
- default:
- assert(0);
- break;
- }
-
- pipe_surface_unmap( dst );
-}
void
cell_init_surface_functions(struct cell_context *cell)
{
- cell->pipe.surface_copy = cell_surface_copy;
- cell->pipe.surface_fill = cell_surface_fill;
+ cell->pipe.surface_copy = util_surface_copy;
+ cell->pipe.surface_fill = util_surface_fill;
}
diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c
index 533b64227d..b6590dfb86 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 "pipe/p_util.h"
#include "pipe/p_winsys.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
#include "cell_context.h"
#include "cell_state.h"
@@ -62,17 +63,30 @@ cell_texture_layout(struct cell_texture * spt)
spt->buffer_size = 0;
for ( level = 0 ; level <= pt->last_level ; level++ ) {
+ unsigned size;
+ unsigned w_tile, h_tile;
+
+ /* width, height, rounded up to tile size */
+ w_tile = align(width, TILE_SIZE);
+ h_tile = align(height, TILE_SIZE);
+
pt->width[level] = width;
pt->height[level] = height;
pt->depth[level] = depth;
- pt->nblocksx[level] = pf_get_nblocksx(&pt->block, width);
- pt->nblocksy[level] = pf_get_nblocksy(&pt->block, height);
+ pt->nblocksx[level] = pf_get_nblocksx(&pt->block, w_tile);
+ pt->nblocksy[level] = pf_get_nblocksy(&pt->block, h_tile);
+
+ 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;
+ size = pt->nblocksx[level] * pt->nblocksy[level] * pt->block.size;
+ if (pt->target == PIPE_TEXTURE_CUBE)
+ size *= 6;
+ else
+ size *= depth;
+
+ spt->buffer_size += size;
width = minify(width);
height = minify(height);
@@ -82,8 +96,8 @@ cell_texture_layout(struct cell_texture * spt)
static struct pipe_texture *
-cell_texture_create_screen(struct pipe_screen *screen,
- const struct pipe_texture *templat)
+cell_texture_create(struct pipe_screen *screen,
+ const struct pipe_texture *templat)
{
struct pipe_winsys *ws = screen->winsys;
struct cell_texture *spt = CALLOC_STRUCT(cell_texture);
@@ -110,8 +124,8 @@ cell_texture_create_screen(struct pipe_screen *screen,
static void
-cell_texture_release_screen(struct pipe_screen *screen,
- struct pipe_texture **pt)
+cell_texture_release(struct pipe_screen *screen,
+ struct pipe_texture **pt)
{
if (!*pt)
return;
@@ -127,7 +141,7 @@ cell_texture_release_screen(struct pipe_screen *screen,
DBG("%s deleting %p\n", __FUNCTION__, (void *) spt);
*/
- pipe_buffer_reference(screen->winsys, &spt->buffer, NULL);
+ pipe_buffer_reference(screen, &spt->buffer, NULL);
FREE(spt);
}
@@ -135,6 +149,7 @@ cell_texture_release_screen(struct pipe_screen *screen,
}
+#if 0
static void
cell_texture_update(struct pipe_context *pipe, struct pipe_texture *texture,
uint face, uint levelsMask)
@@ -142,12 +157,14 @@ cell_texture_update(struct pipe_context *pipe, struct pipe_texture *texture,
/* XXX TO DO: re-tile the texture data ... */
}
+#endif
static struct pipe_surface *
-cell_get_tex_surface_screen(struct pipe_screen *screen,
- struct pipe_texture *pt,
- unsigned face, unsigned level, unsigned zslice)
+cell_get_tex_surface(struct pipe_screen *screen,
+ struct pipe_texture *pt,
+ unsigned face, unsigned level, unsigned zslice,
+ unsigned usage)
{
struct pipe_winsys *ws = screen->winsys;
struct cell_texture *spt = cell_texture(pt);
@@ -157,7 +174,7 @@ cell_get_tex_surface_screen(struct pipe_screen *screen,
if (ps) {
assert(ps->refcount);
assert(ps->winsys);
- pipe_buffer_reference(ws, &ps->buffer, spt->buffer);
+ winsys_buffer_reference(ws, &ps->buffer, spt->buffer);
ps->format = pt->format;
ps->block = pt->block;
ps->width = pt->width[level];
@@ -166,12 +183,21 @@ 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) */
+
+ pipe_texture_reference(&ps->texture, pt);
+ ps->face = face;
+ ps->level = level;
+ ps->zslice = zslice;
if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) {
ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) *
ps->nblocksy *
ps->stride;
- } else {
+ }
+ else {
assert(face == 0);
assert(zslice == 0);
}
@@ -181,6 +207,11 @@ cell_get_tex_surface_screen(struct pipe_screen *screen,
+/**
+ * Copy tile data from linear layout to tiled layout.
+ * XXX this should be rolled into the future surface-creation code.
+ * XXX also need "untile" code...
+ */
static void
tile_copy_data(uint w, uint h, uint tile_size, uint *dst, const uint *src)
{
@@ -211,6 +242,7 @@ tile_copy_data(uint w, uint h, uint tile_size, uint *dst, const uint *src)
/**
* Convert linear texture image data to tiled format for SPU usage.
+ * XXX recast this in terms of pipe_surfaces (aka texture views).
*/
static void
cell_tile_texture(struct cell_context *cell,
@@ -228,10 +260,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 +279,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,16 +309,79 @@ cell_update_texture_mapping(struct cell_context *cell)
}
+static void
+cell_tex_surface_release(struct pipe_screen *screen,
+ struct pipe_surface **s)
+{
+ /* Effectively do the texture_update work here - if texture images
+ * needed post-processing to put them into hardware layout, this is
+ * where it would happen. For softpipe, nothing to do.
+ */
+ assert ((*s)->texture);
+ pipe_texture_reference(&(*s)->texture, NULL);
+
+ screen->winsys->surface_release(screen->winsys, s);
+}
+
+
+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 = pipe_buffer_map( screen, 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)
+{
+ pipe_buffer_unmap( screen, 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
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->texture_create = cell_texture_create;
+ screen->texture_release = cell_texture_release;
+
+ screen->get_tex_surface = cell_get_tex_surface;
+ screen->tex_surface_release = cell_tex_surface_release;
+
+ 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 fcee069d05..6d37e95ebc 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 3a181b585c..aa63435b93 100644
--- a/src/gallium/drivers/cell/ppu/cell_vbuf.c
+++ b/src/gallium/drivers/cell/ppu/cell_vbuf.c
@@ -26,6 +26,11 @@
**************************************************************************/
/**
+ * Vertex buffer code. The draw module transforms vertices to window
+ * coords, etc. and emits the vertices into buffer supplied by this module.
+ * When a vertex buffer is full, or we flush, we'll send the vertex data
+ * to the SPUs.
+ *
* Authors
* Brian Paul
*/
@@ -37,6 +42,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 */
@@ -112,7 +118,7 @@ cell_vbuf_release_vertices(struct vbuf_render *vbr, void *vertices,
}
cvbr->vertex_buf = ~0;
- cell_flush_int(&cell->pipe, 0x0);
+ cell_flush_int(cell, 0x0);
assert(vertices == cvbr->vertex_buffer);
cvbr->vertex_buffer = NULL;
@@ -120,12 +126,13 @@ cell_vbuf_release_vertices(struct vbuf_render *vbr, void *vertices,
-static void
+static boolean
cell_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim)
{
struct cell_vbuf_render *cvbr = cell_vbuf_render(vbr);
cvbr->prim = prim;
/*printf("cell_set_prim %u\n", prim);*/
+ return TRUE;
}
@@ -243,7 +250,7 @@ cell_vbuf_draw(struct vbuf_render *vbr,
#if 0
/* helpful for debug */
- cell_flush_int(&cell->pipe, CELL_FLUSH_WAIT);
+ cell_flush_int(cell, CELL_FLUSH_WAIT);
#endif
}
diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c b/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c
index 49d5443cde..2ece0250f6 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 f753960a0f..2b10c116fa 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;
@@ -133,9 +135,12 @@ cell_vertex_shader_queue_flush(struct draw_context *draw)
vs->num_elts = n;
send_mbox_message(cell_global.spe_contexts[0], CELL_CMD_VS_EXECUTE);
- cell_flush_int(& cell->pipe, CELL_FLUSH_WAIT);
+ cell_flush_int(cell, CELL_FLUSH_WAIT);
}
draw->vs.post_nr = draw->vs.queue_nr;
draw->vs.queue_nr = 0;
+#else
+ assert(0);
+#endif
}
diff --git a/src/gallium/drivers/cell/ppu/cell_winsys.c b/src/gallium/drivers/cell/ppu/cell_winsys.c
index ebabce3c8f..d570bbd2f9 100644
--- a/src/gallium/drivers/cell/ppu/cell_winsys.c
+++ b/src/gallium/drivers/cell/ppu/cell_winsys.c
@@ -26,7 +26,7 @@
**************************************************************************/
-#include "pipe/p_util.h"
+#include "util/u_memory.h"
#include "cell_winsys.h"
diff --git a/src/gallium/drivers/cell/spu/Makefile b/src/gallium/drivers/cell/spu/Makefile
index 8e83610790..d49abb2e82 100644
--- a/src/gallium/drivers/cell/spu/Makefile
+++ b/src/gallium/drivers/cell/spu/Makefile
@@ -5,7 +5,7 @@
TOP = ../../../../..
-include $(TOP)/configs/linux-cell
+include $(TOP)/configs/current
PROG = g3d
diff --git a/src/gallium/drivers/cell/spu/spu_exec.c b/src/gallium/drivers/cell/spu/spu_exec.c
index 42e5022f30..e27df2dfb3 100644
--- a/src/gallium/drivers/cell/spu/spu_exec.c
+++ b/src/gallium/drivers/cell/spu/spu_exec.c
@@ -63,7 +63,6 @@
#include "pipe/p_compiler.h"
#include "pipe/p_state.h"
-#include "pipe/p_util.h"
#include "pipe/p_shader_tokens.h"
#include "tgsi/tgsi_parse.h"
#include "tgsi/tgsi_util.h"
@@ -383,10 +382,10 @@ fetch_src_file_channel(
break;
case TGSI_FILE_IMMEDIATE:
- assert( index->i[0] < (int) mach->ImmLimit );
- assert( index->i[1] < (int) mach->ImmLimit );
- assert( index->i[2] < (int) mach->ImmLimit );
- assert( index->i[3] < (int) mach->ImmLimit );
+ ASSERT( index->i[0] < (int) mach->ImmLimit );
+ ASSERT( index->i[1] < (int) mach->ImmLimit );
+ ASSERT( index->i[2] < (int) mach->ImmLimit );
+ ASSERT( index->i[3] < (int) mach->ImmLimit );
chan->f[0] = mach->Imms[index->i[0]][swizzle];
chan->f[1] = mach->Imms[index->i[1]][swizzle];
@@ -410,7 +409,7 @@ fetch_src_file_channel(
break;
default:
- assert( 0 );
+ ASSERT( 0 );
}
break;
@@ -423,7 +422,7 @@ fetch_src_file_channel(
break;
default:
- assert( 0 );
+ ASSERT( 0 );
}
}
@@ -472,7 +471,7 @@ fetch_source(
index.q = si_shli(index.q, 12);
break;
default:
- assert( 0 );
+ ASSERT( 0 );
}
index.i[0] += reg->SrcRegisterDim.Index;
@@ -559,7 +558,7 @@ store_dest(
break;
default:
- assert( 0 );
+ ASSERT( 0 );
return;
}
@@ -583,11 +582,11 @@ store_dest(
break;
case TGSI_SAT_MINUS_PLUS_ONE:
- assert( 0 );
+ ASSERT( 0 );
break;
default:
- assert( 0 );
+ ASSERT( 0 );
}
}
@@ -770,7 +769,7 @@ exec_tex(struct spu_exec_machine *mach,
break;
default:
- assert (0);
+ ASSERT (0);
}
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
@@ -862,7 +861,7 @@ exec_declaration(struct spu_exec_machine *mach,
break;
default:
- assert( 0 );
+ ASSERT( 0 );
}
if( mask == TGSI_WRITEMASK_XYZW ) {
@@ -972,11 +971,11 @@ exec_instruction(
break;
case TGSI_OPCODE_EXP:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_LOG:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_MUL:
@@ -1152,24 +1151,24 @@ exec_instruction(
break;
case TGSI_OPCODE_CND:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_CND0:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_DOT2ADD:
/* TGSI_OPCODE_DP2A */
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_INDEX:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_NEGATE:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_FRAC:
@@ -1182,7 +1181,7 @@ exec_instruction(
break;
case TGSI_OPCODE_CLAMP:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_FLOOR:
@@ -1277,7 +1276,7 @@ exec_instruction(
break;
case TGSI_OPCODE_MULTIPLYMATRIX:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_ABS:
@@ -1291,7 +1290,7 @@ exec_instruction(
break;
case TGSI_OPCODE_RCC:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_DPH:
@@ -1354,23 +1353,23 @@ exec_instruction(
break;
case TGSI_OPCODE_PK2H:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_PK2US:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_PK4B:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_PK4UB:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_RFL:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_SEQ:
@@ -1385,7 +1384,7 @@ exec_instruction(
break;
case TGSI_OPCODE_SFL:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_SGT:
@@ -1430,7 +1429,7 @@ exec_instruction(
break;
case TGSI_OPCODE_STR:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_TEX:
@@ -1453,7 +1452,7 @@ exec_instruction(
/* src[1] = d[strq]/dx */
/* src[2] = d[strq]/dy */
/* src[3] = sampler unit */
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_TXL:
@@ -1471,35 +1470,35 @@ exec_instruction(
break;
case TGSI_OPCODE_UP2H:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_UP2US:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_UP4B:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_UP4UB:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_X2D:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_ARA:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_ARR:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_BRA:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_CAL:
@@ -1508,14 +1507,14 @@ exec_instruction(
/* do the call */
/* push the Cond, Loop, Cont stacks */
- assert(mach->CondStackTop < TGSI_EXEC_MAX_COND_NESTING);
+ ASSERT(mach->CondStackTop < TGSI_EXEC_MAX_COND_NESTING);
mach->CondStack[mach->CondStackTop++] = mach->CondMask;
- assert(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
+ ASSERT(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask;
- assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
+ ASSERT(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
mach->ContStack[mach->ContStackTop++] = mach->ContMask;
- assert(mach->FuncStackTop < TGSI_EXEC_MAX_CALL_NESTING);
+ ASSERT(mach->FuncStackTop < TGSI_EXEC_MAX_CALL_NESTING);
mach->FuncStack[mach->FuncStackTop++] = mach->FuncMask;
/* note that PC was already incremented above */
@@ -1539,13 +1538,13 @@ exec_instruction(
*pc = mach->CallStack[--mach->CallStackTop];
/* pop the Cond, Loop, Cont stacks */
- assert(mach->CondStackTop > 0);
+ ASSERT(mach->CondStackTop > 0);
mach->CondMask = mach->CondStack[--mach->CondStackTop];
- assert(mach->LoopStackTop > 0);
+ ASSERT(mach->LoopStackTop > 0);
mach->LoopMask = mach->LoopStack[--mach->LoopStackTop];
- assert(mach->ContStackTop > 0);
+ ASSERT(mach->ContStackTop > 0);
mach->ContMask = mach->ContStack[--mach->ContStackTop];
- assert(mach->FuncStackTop > 0);
+ ASSERT(mach->FuncStackTop > 0);
mach->FuncMask = mach->FuncStack[--mach->FuncStackTop];
UPDATE_EXEC_MASK(mach);
@@ -1553,7 +1552,7 @@ exec_instruction(
break;
case TGSI_OPCODE_SSG:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_CMP:
@@ -1593,11 +1592,11 @@ exec_instruction(
break;
case TGSI_OPCODE_NRM:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_DIV:
- assert( 0 );
+ ASSERT( 0 );
break;
case TGSI_OPCODE_DP2:
@@ -1616,7 +1615,7 @@ exec_instruction(
case TGSI_OPCODE_IF:
/* push CondMask */
- assert(mach->CondStackTop < TGSI_EXEC_MAX_COND_NESTING);
+ ASSERT(mach->CondStackTop < TGSI_EXEC_MAX_COND_NESTING);
mach->CondStack[mach->CondStackTop++] = mach->CondMask;
FETCH( &r[0], 0, CHAN_X );
/* update CondMask */
@@ -1640,7 +1639,7 @@ exec_instruction(
/* invert CondMask wrt previous mask */
{
uint prevMask;
- assert(mach->CondStackTop > 0);
+ ASSERT(mach->CondStackTop > 0);
prevMask = mach->CondStack[mach->CondStackTop - 1];
mach->CondMask = ~mach->CondMask & prevMask;
UPDATE_EXEC_MASK(mach);
@@ -1650,7 +1649,7 @@ exec_instruction(
case TGSI_OPCODE_ENDIF:
/* pop CondMask */
- assert(mach->CondStackTop > 0);
+ ASSERT(mach->CondStackTop > 0);
mach->CondMask = mach->CondStack[--mach->CondStackTop];
UPDATE_EXEC_MASK(mach);
break;
@@ -1661,19 +1660,19 @@ exec_instruction(
break;
case TGSI_OPCODE_REP:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_ENDREP:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_PUSHA:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_POPA:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_CEIL:
@@ -1747,7 +1746,7 @@ exec_instruction(
break;
case TGSI_OPCODE_MOD:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_XOR:
@@ -1760,15 +1759,15 @@ exec_instruction(
break;
case TGSI_OPCODE_SAD:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_TXF:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_TXQ:
- assert (0);
+ ASSERT (0);
break;
case TGSI_OPCODE_EMIT:
@@ -1785,9 +1784,9 @@ exec_instruction(
/* fall-through (for now) */
case TGSI_OPCODE_BGNLOOP2:
/* push LoopMask and ContMasks */
- assert(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
+ ASSERT(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask;
- assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
+ ASSERT(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
mach->ContStack[mach->ContStackTop++] = mach->ContMask;
break;
@@ -1795,7 +1794,7 @@ exec_instruction(
/* fall-through (for now at least) */
case TGSI_OPCODE_ENDLOOP2:
/* Restore ContMask, but don't pop */
- assert(mach->ContStackTop > 0);
+ ASSERT(mach->ContStackTop > 0);
mach->ContMask = mach->ContStack[mach->ContStackTop - 1];
if (mach->LoopMask) {
/* repeat loop: jump to instruction just past BGNLOOP */
@@ -1803,10 +1802,10 @@ exec_instruction(
}
else {
/* exit loop: pop LoopMask */
- assert(mach->LoopStackTop > 0);
+ ASSERT(mach->LoopStackTop > 0);
mach->LoopMask = mach->LoopStack[--mach->LoopStackTop];
/* pop ContMask */
- assert(mach->ContStackTop > 0);
+ ASSERT(mach->ContStackTop > 0);
mach->ContMask = mach->ContStack[--mach->ContStackTop];
}
UPDATE_EXEC_MASK(mach);
@@ -1835,26 +1834,26 @@ exec_instruction(
break;
case TGSI_OPCODE_NOISE1:
- assert( 0 );
+ ASSERT( 0 );
break;
case TGSI_OPCODE_NOISE2:
- assert( 0 );
+ ASSERT( 0 );
break;
case TGSI_OPCODE_NOISE3:
- assert( 0 );
+ ASSERT( 0 );
break;
case TGSI_OPCODE_NOISE4:
- assert( 0 );
+ ASSERT( 0 );
break;
case TGSI_OPCODE_NOP:
break;
default:
- assert( 0 );
+ ASSERT( 0 );
}
}
@@ -1875,11 +1874,11 @@ spu_exec_machine_run( struct spu_exec_machine *mach )
mach->FuncMask = 0xf;
mach->ExecMask = 0xf;
- mach->CondStackTop = 0; /* temporarily subvert this assertion */
- assert(mach->CondStackTop == 0);
- assert(mach->LoopStackTop == 0);
- assert(mach->ContStackTop == 0);
- assert(mach->CallStackTop == 0);
+ mach->CondStackTop = 0; /* temporarily subvert this ASSERTion */
+ ASSERT(mach->CondStackTop == 0);
+ ASSERT(mach->LoopStackTop == 0);
+ ASSERT(mach->ContStackTop == 0);
+ ASSERT(mach->CallStackTop == 0);
mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] = 0;
mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] = 0;
diff --git a/src/gallium/drivers/cell/spu/spu_exec.h b/src/gallium/drivers/cell/spu/spu_exec.h
index c68f78f59b..8605679940 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_main.c b/src/gallium/drivers/cell/spu/spu_main.c
index e04ffeb9b1..d223f32d94 100644
--- a/src/gallium/drivers/cell/spu/spu_main.c
+++ b/src/gallium/drivers/cell/spu/spu_main.c
@@ -55,6 +55,10 @@ struct spu_global spu;
struct spu_vs_context draw;
+
+/**
+ * Buffers containing dynamically generated SPU code:
+ */
static unsigned char attribute_fetch_code_buffer[136 * PIPE_MAX_ATTRIBS]
ALIGN16_ATTRIB;
@@ -136,54 +140,75 @@ really_clear_tiles(uint surfaceIndex)
static void
cmd_clear_surface(const struct cell_command_clear_surface *clear)
{
- const uint num_tiles = spu.fb.width_tiles * spu.fb.height_tiles;
- uint i;
-
if (Debug)
printf("SPU %u: CLEAR SURF %u to 0x%08x\n", spu.init.id,
clear->surface, clear->value);
-#define CLEAR_OPT 1
-#if CLEAR_OPT
- /* set all tile's status to CLEAR */
if (clear->surface == 0) {
- memset(spu.ctile_status, TILE_STATUS_CLEAR, sizeof(spu.ctile_status));
spu.fb.color_clear_value = clear->value;
+ if (spu.init.debug_flags & CELL_DEBUG_CHECKER) {
+ uint x = (spu.init.id << 4) | (spu.init.id << 12) |
+ (spu.init.id << 20) | (spu.init.id << 28);
+ spu.fb.color_clear_value ^= x;
+ }
}
else {
- memset(spu.ztile_status, TILE_STATUS_CLEAR, sizeof(spu.ztile_status));
spu.fb.depth_clear_value = clear->value;
}
- return;
-#endif
+#define CLEAR_OPT 1
+#if CLEAR_OPT
+
+ /* Simply set all tiles' status to CLEAR.
+ * When we actually begin rendering into a tile, we'll initialize it to
+ * the clear value. If any tiles go untouched during the frame,
+ * really_clear_tiles() will set them to the clear value.
+ */
if (clear->surface == 0) {
- spu.fb.color_clear_value = clear->value;
- clear_c_tile(&spu.ctile);
+ memset(spu.ctile_status, TILE_STATUS_CLEAR, sizeof(spu.ctile_status));
}
else {
- spu.fb.depth_clear_value = clear->value;
- clear_z_tile(&spu.ztile);
+ memset(spu.ztile_status, TILE_STATUS_CLEAR, sizeof(spu.ztile_status));
}
+#else
+
+ /*
+ * This path clears the whole framebuffer to the clear color right now.
+ */
+
/*
printf("SPU: %s num=%d w=%d h=%d\n",
__FUNCTION__, num_tiles, spu.fb.width_tiles, spu.fb.height_tiles);
*/
- for (i = spu.init.id; i < num_tiles; i += spu.init.num_spus) {
- uint tx = i % spu.fb.width_tiles;
- uint ty = i / spu.fb.width_tiles;
- if (clear->surface == 0)
- put_tile(tx, ty, &spu.ctile, TAG_SURFACE_CLEAR, 0);
- else
- put_tile(tx, ty, &spu.ztile, TAG_SURFACE_CLEAR, 1);
- /* XXX we don't want this here, but it fixes bad tile results */
+ /* init a single tile to the clear value */
+ if (clear->surface == 0) {
+ clear_c_tile(&spu.ctile);
+ }
+ else {
+ clear_z_tile(&spu.ztile);
}
-#if 0
- wait_on_mask(1 << TAG_SURFACE_CLEAR);
-#endif
+ /* walk over my tiles, writing the 'clear' tile's data */
+ {
+ const uint num_tiles = spu.fb.width_tiles * spu.fb.height_tiles;
+ uint i;
+ for (i = spu.init.id; i < num_tiles; i += spu.init.num_spus) {
+ uint tx = i % spu.fb.width_tiles;
+ uint ty = i / spu.fb.width_tiles;
+ if (clear->surface == 0)
+ put_tile(tx, ty, &spu.ctile, TAG_SURFACE_CLEAR, 0);
+ else
+ put_tile(tx, ty, &spu.ztile, TAG_SURFACE_CLEAR, 1);
+ }
+ }
+
+ if (spu.init.debug_flags & CELL_DEBUG_SYNC) {
+ wait_on_mask(1 << TAG_SURFACE_CLEAR);
+ }
+
+#endif /* CLEAR_OPT */
if (Debug)
printf("SPU %u: CLEAR SURF done\n", spu.init.id);
@@ -312,6 +337,21 @@ cmd_state_depth_stencil(const struct cell_command_depth_stencil_alpha_test *stat
static void
+cmd_state_logicop(const struct cell_command_logicop * code)
+{
+ mfc_get(logicop_code_buffer,
+ (unsigned int) code->base, /* src */
+ code->size,
+ TAG_BATCH_BUFFER,
+ 0, /* tid */
+ 0 /* rid */);
+ wait_on_mask(1 << TAG_BATCH_BUFFER);
+
+ spu.logicop = (logicop_func) logicop_code_buffer;
+}
+
+
+static void
cmd_state_sampler(const struct cell_command_sampler *sampler)
{
if (Debug)
@@ -381,6 +421,21 @@ cmd_state_vs_array_info(const struct cell_array_info *vs_info)
static void
+cmd_state_attrib_fetch(const struct cell_attribute_fetch_code *code)
+{
+ mfc_get(attribute_fetch_code_buffer,
+ (unsigned int) code->base, /* src */
+ code->size,
+ TAG_BATCH_BUFFER,
+ 0, /* tid */
+ 0 /* rid */);
+ wait_on_mask(1 << TAG_BATCH_BUFFER);
+
+ draw.vertex_fetch.code = attribute_fetch_code_buffer;
+}
+
+
+static void
cmd_finish(void)
{
if (Debug)
@@ -518,38 +573,15 @@ cmd_batch(uint opcode)
(struct cell_shader_info *) &buffer[pos+1]);
pos += (1 + ROUNDUP8(sizeof(struct cell_shader_info)) / 8);
break;
- case CELL_CMD_STATE_ATTRIB_FETCH: {
- struct cell_attribute_fetch_code *code =
- (struct cell_attribute_fetch_code *) &buffer[pos+1];
-
- mfc_get(attribute_fetch_code_buffer,
- (unsigned int) code->base, /* src */
- code->size,
- TAG_BATCH_BUFFER,
- 0, /* tid */
- 0 /* rid */);
- wait_on_mask(1 << TAG_BATCH_BUFFER);
-
- draw.vertex_fetch.code = attribute_fetch_code_buffer;
+ case CELL_CMD_STATE_ATTRIB_FETCH:
+ cmd_state_attrib_fetch((struct cell_attribute_fetch_code *)
+ &buffer[pos+1]);
pos += (1 + ROUNDUP8(sizeof(struct cell_attribute_fetch_code)) / 8);
break;
- }
- case CELL_CMD_STATE_LOGICOP: {
- struct cell_command_logicop *code =
- (struct cell_command_logicop *) &buffer[pos+1];
-
- mfc_get(logicop_code_buffer,
- (unsigned int) code->base, /* src */
- code->size,
- TAG_BATCH_BUFFER,
- 0, /* tid */
- 0 /* rid */);
- wait_on_mask(1 << TAG_BATCH_BUFFER);
-
- spu.logicop = (logicop_func) logicop_code_buffer;
+ case CELL_CMD_STATE_LOGICOP:
+ cmd_state_logicop((struct cell_command_logicop *) &buffer[pos+1]);
pos += (1 + ROUNDUP8(sizeof(struct cell_command_logicop)) / 8);
break;
- }
case CELL_CMD_FLUSH_BUFFER_RANGE: {
struct cell_buffer_range *br = (struct cell_buffer_range *)
&buffer[pos+1];
diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h
index e962e1426c..4879f8c9c8 100644
--- a/src/gallium/drivers/cell/spu/spu_main.h
+++ b/src/gallium/drivers/cell/spu/spu_main.h
@@ -124,13 +124,13 @@ struct spu_global
struct spu_framebuffer fb;
boolean read_depth;
boolean read_stencil;
- frag_test_func frag_test;
+ frag_test_func frag_test; /**< Current depth/stencil test code */
- boolean read_fb;
- blend_func blend;
+ boolean read_fb; /**< Does current blend mode require framebuffer read? */
+ blend_func blend; /**< Current blend code */
qword const_blend_color[4] ALIGN16_ATTRIB;
- logicop_func logicop;
+ logicop_func logicop; /**< Current logicop code **/
struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS];
struct spu_texture texture[PIPE_MAX_SAMPLERS];
diff --git a/src/gallium/drivers/cell/spu/spu_per_fragment_op.c b/src/gallium/drivers/cell/spu/spu_per_fragment_op.c
index b4cffeeb32..c0a729b3d2 100644
--- a/src/gallium/drivers/cell/spu/spu_per_fragment_op.c
+++ b/src/gallium/drivers/cell/spu/spu_per_fragment_op.c
@@ -95,7 +95,7 @@ read_ds_quad(tile_t *buffer, unsigned x, unsigned y,
default:
- assert(0);
+ ASSERT(0);
break;
}
}
@@ -153,7 +153,7 @@ write_ds_quad(tile_t *buffer, unsigned x, unsigned y,
default:
- assert(0);
+ ASSERT(0);
break;
}
}
diff --git a/src/gallium/drivers/cell/spu/spu_render.c b/src/gallium/drivers/cell/spu/spu_render.c
index 6df59abd36..305dc98881 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_tile.c b/src/gallium/drivers/cell/spu/spu_tile.c
index 12dc246328..216a33126b 100644
--- a/src/gallium/drivers/cell/spu/spu_tile.c
+++ b/src/gallium/drivers/cell/spu/spu_tile.c
@@ -31,6 +31,9 @@
#include "spu_main.h"
+/**
+ * Get tile of color or Z values from main memory, put into SPU memory.
+ */
void
get_tile(uint tx, uint ty, tile_t *tile, int tag, int zBuf)
{
@@ -56,6 +59,9 @@ get_tile(uint tx, uint ty, tile_t *tile, int tag, int zBuf)
}
+/**
+ * Move tile of color or Z values from SPU memory to main memory.
+ */
void
put_tile(uint tx, uint ty, const tile_t *tile, int tag, int zBuf)
{
diff --git a/src/gallium/drivers/cell/spu/spu_tri.c b/src/gallium/drivers/cell/spu/spu_tri.c
index ab4ff8160a..2a4e0b423c 100644
--- a/src/gallium/drivers/cell/spu/spu_tri.c
+++ b/src/gallium/drivers/cell/spu/spu_tri.c
@@ -32,7 +32,7 @@
#include <transpose_matrix4x4.h>
#include "pipe/p_compiler.h"
#include "pipe/p_format.h"
-#include "pipe/p_util.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 74ab2bbd1f..b8a0d4a265 100644
--- a/src/gallium/drivers/cell/spu/spu_util.c
+++ b/src/gallium/drivers/cell/spu/spu_util.c
@@ -1,5 +1,7 @@
-#include "pipe/p_util.h"
+
+#include "cell/common.h"
#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"
@@ -19,7 +21,7 @@ tgsi_util_get_src_register_swizzle(
case 3:
return reg->SwizzleW;
default:
- assert( 0 );
+ ASSERT( 0 );
}
return 0;
}
@@ -39,7 +41,7 @@ tgsi_util_get_src_register_extswizzle(
case 3:
return reg->ExtSwizzleW;
default:
- assert( 0 );
+ ASSERT( 0 );
}
return 0;
}
@@ -59,12 +61,12 @@ tgsi_util_get_full_src_register_extswizzle(
&reg->SrcRegisterExtSwz,
component );
- assert (TGSI_SWIZZLE_X == TGSI_EXTSWIZZLE_X);
- assert (TGSI_SWIZZLE_Y == TGSI_EXTSWIZZLE_Y);
- assert (TGSI_SWIZZLE_Z == TGSI_EXTSWIZZLE_Z);
- assert (TGSI_SWIZZLE_W == TGSI_EXTSWIZZLE_W);
- assert (TGSI_EXTSWIZZLE_ZERO > TGSI_SWIZZLE_W);
- assert (TGSI_EXTSWIZZLE_ONE > TGSI_SWIZZLE_W);
+ ASSERT (TGSI_SWIZZLE_X == TGSI_EXTSWIZZLE_X);
+ ASSERT (TGSI_SWIZZLE_Y == TGSI_EXTSWIZZLE_Y);
+ ASSERT (TGSI_SWIZZLE_Z == TGSI_EXTSWIZZLE_Z);
+ ASSERT (TGSI_SWIZZLE_W == TGSI_EXTSWIZZLE_W);
+ ASSERT (TGSI_EXTSWIZZLE_ZERO > TGSI_SWIZZLE_W);
+ ASSERT (TGSI_EXTSWIZZLE_ONE > TGSI_SWIZZLE_W);
/*
* Second, calculate the simple swizzle for the unswizzled channel index.
@@ -94,7 +96,7 @@ tgsi_util_get_src_register_extnegate(
case 3:
return reg->NegateW;
default:
- assert( 0 );
+ ASSERT( 0 );
}
return 0;
}
@@ -119,7 +121,7 @@ tgsi_util_set_src_register_extnegate(
reg->NegateW = negate;
break;
default:
- assert( 0 );
+ ASSERT( 0 );
}
}
diff --git a/src/gallium/drivers/cell/spu/spu_vertex_fetch.c b/src/gallium/drivers/cell/spu/spu_vertex_fetch.c
index 219fd90cc0..03375d84a5 100644
--- a/src/gallium/drivers/cell/spu/spu_vertex_fetch.c
+++ b/src/gallium/drivers/cell/spu/spu_vertex_fetch.c
@@ -32,7 +32,6 @@
* Ian Romanick <idr@us.ibm.com>
*/
-#include "pipe/p_util.h"
#include "pipe/p_state.h"
#include "pipe/p_shader_tokens.h"
#include "spu_exec.h"
@@ -93,7 +92,7 @@ static void generic_vertex_fetch(struct spu_vs_context *draw,
unsigned nr_attrs = draw->vertex_fetch.nr_attrs;
unsigned attr;
- assert(count <= 4);
+ ASSERT(count <= 4);
#if DRAW_DBG
printf("SPU: %s count = %u, nr_attrs = %u\n",
diff --git a/src/gallium/drivers/cell/spu/spu_vertex_shader.c b/src/gallium/drivers/cell/spu/spu_vertex_shader.c
index 3119a78c06..fbe5b34d39 100644
--- a/src/gallium/drivers/cell/spu/spu_vertex_shader.c
+++ b/src/gallium/drivers/cell/spu/spu_vertex_shader.c
@@ -34,16 +34,37 @@
#include <spu_mfcio.h>
-#include "pipe/p_util.h"
#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)
{
@@ -91,7 +112,7 @@ run_vertex_program(struct spu_vs_context *draw,
const float *scale = draw->viewport.scale;
const float *trans = draw->viewport.translate;
- assert(count <= 4);
+ ASSERT(count <= 4);
machine->Processor = TGSI_PROCESSOR_VERTEX;