-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
I've noticed some odd bugs when accessing data packets sent via batch
buffers from the PPE to SPE. Every now and then one of the pointers
sent would be NULL or similar, low value. I tracked this down to
unaligned accesses. If 64-bit values aren't aligned, reads return garbage.
I managed to work around this by making the opcode field 64-bits and
ensuring that each batch is 64-bit aligned. This seems to also
eliminate the need for the dummy fields in cell_command_render.
Patch attached.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)
iD8DBQFHp6j9X1gOwKyEAw8RAgADAJ4rCcKUSbACY6lm1Zgg0jYC88adrwCghxm6
P0Hu90vLqA7+1t4JDP2DjbE=
=S3pb
-----END PGP SIGNATURE-----
diff --git a/configs/linux-cell b/configs/linux-cell
index 3d87449..fac854a 100644
--- a/configs/linux-cell
+++ b/configs/linux-cell
@@ -6,17 +6,17 @@ CONFIG_NAME = linux-cell
# Compiler and flags
-CC = ppu32-gcc
-CXX = ppu32-g++
+CC = ccache ppu32-gcc
+CXX = ccache ppu32-g++
HOST_CC = gcc
-OPT_FLAGS = -g
+OPT_FLAGS = -g -O2
# Cell SDK location
-SDK = /opt/ibm/cell-sdk/prototype/sysroot/usr
+SDK = /opt/cell/sysroot/opt/cell/sdk/usr
-CFLAGS = $(OPT_FLAGS) -Wall -Winline -fPIC -m32 -mabi=altivec -maltivec -I. -I$(SDK)/include -DGALLIUM_CELL
+CFLAGS = $(OPT_FLAGS) -Wall -Winline -fPIC -m32 -mabi=altivec -maltivec -I. -I/opt/powerpc/usr/include -I$(SDK)/include -DGALLIUM_CELL
CXXFLAGS = $(CFLAGS)
@@ -27,6 +27,11 @@ SRC_DIRS = mesa glu glut/glx
MKDEP_OPTIONS = -fdepend -Y
+EXTRA_LIB_PATH = -L/opt/powerpc/usr/lib
+APP_LIB_DEPS = $(EXTRA_LIB_PATH) -Wl,-rpath-link,/opt/powerpc/usr/lib \
+ -Wl,-rpath-link,$(SDK)/lib \
+ -Wl,-rpath-link,/opt/cell/toolchain/lib/gcc/ppu/4.1.1/32/ \
+ -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) -lm
GL_LIB_DEPS = $(EXTRA_LIB_PATH) -lX11 -lXext -lm -lpthread \
-L$(SDK)/lib -m32 -Wl,-m,elf32ppc -R$(SDK)/lib -lspe2
@@ -34,9 +39,12 @@ GL_LIB_DEPS = $(EXTRA_LIB_PATH) -lX11 -lXext -lm -lpthread \
### SPU stuff
-SPU_CC = spu-gcc
+SPU_CC = ccache spu-gcc
-SPU_CFLAGS = $(OPT_FLAGS) -W -Wall -Winline -Wmissing-prototypes -Wno-main -I. -I $(SDK)/spu/include -include spu_intrinsics.h -I $(TOP)/src/mesa/
+SPU_CFLAGS = $(OPT_FLAGS) -W -Wall -Winline -Wmissing-prototypes -Wno-main \
+ -I. -I $(SDK)/spu/include -include spu_intrinsics.h \
+ -I $(TOP)/src/mesa/ \
+ -DSPU_MAIN_PARAM_LONG_LONG
SPU_LFLAGS = -L$(SDK)/spu/lib -Wl,-N -lmisc
@@ -45,3 +53,5 @@ SPU_AR_FLAGS = -qcs
SPU_EMBED = ppu32-embedspu
SPU_EMBED_FLAGS = -m32
+
+PROGRAM_DIRS = demos glsl xdemos trivial vpglsl
diff --git a/src/mesa/pipe/cell/common.h b/src/mesa/pipe/cell/common.h
index 7e193f3..ec65e83 100644
--- a/src/mesa/pipe/cell/common.h
+++ b/src/mesa/pipe/cell/common.h
@@ -57,6 +57,9 @@
/** round up value to next multiple of 4 */
#define ROUNDUP4(k) (((k) + 0x3) & ~0x3)
+/** round up value to next multiple of 8 */
+#define ROUNDUP8(k) (((k) + 0x7) & ~0x7)
+
/** round up value to next multiple of 16 */
#define ROUNDUP16(k) (((k) + 0xf) & ~0xf)
@@ -101,7 +104,7 @@
*/
struct cell_command_framebuffer
{
- uint opcode;
+ uint64_t opcode;
int width, height;
void *color_start, *depth_start;
enum pipe_format color_format, depth_format;
@@ -113,7 +116,7 @@ struct cell_command_framebuffer
*/
struct cell_command_clear_surface
{
- uint opcode;
+ uint64_t opcode;
uint surface; /**< Temporary: 0=color, 1=Z */
uint value;
};
@@ -124,8 +127,7 @@ struct cell_command_clear_surface
*/
struct cell_array_info
{
- uint opcode;
- uint base; /**< Base address of the 0th element. */
+ uint64_t base; /**< Base address of the 0th element. */
uint attr; /**< Attribute that this state if for. */
uint pitch; /**< Byte pitch from one entry to the next. */
uint format; /**< Pipe format of each entry. */
@@ -149,7 +151,7 @@ struct cell_shader_info
#define SPU_VERTS_PER_BATCH 64
struct cell_command_vs
{
- uint opcode; /**< CELL_CMD_VS_EXECUTE */
+ uint64_t opcode; /**< CELL_CMD_VS_EXECUTE */
struct cell_shader_info shader;
unsigned num_elts;
unsigned elts[SPU_VERTS_PER_BATCH];
@@ -162,7 +164,7 @@ struct cell_command_vs
struct cell_command_render
{
- uint opcode; /**< CELL_CMD_RENDER */
+ uint64_t opcode; /**< CELL_CMD_RENDER */
uint prim_type; /**< PIPE_PRIM_x */
uint num_verts;
uint vertex_size; /**< bytes per vertex */
@@ -178,7 +180,7 @@ struct cell_command_render
struct cell_command_release_verts
{
- int opcode; /**< CELL_CMD_RELEASE_VERTS */
+ uint64_t opcode; /**< CELL_CMD_RELEASE_VERTS */
uint vertex_buf; /**< in [0, CELL_NUM_BUFFERS-1] */
};
diff --git a/src/mesa/pipe/cell/ppu/cell_batch.c b/src/mesa/pipe/cell/ppu/cell_batch.c
index 2d032fc..2fb4971 100644
--- a/src/mesa/pipe/cell/ppu/cell_batch.c
+++ b/src/mesa/pipe/cell/ppu/cell_batch.c
@@ -136,7 +136,7 @@ cell_batch_append(struct cell_context *cell, const void *data, uint bytes)
{
uint size;
- ASSERT(bytes % 4 == 0);
+ ASSERT(bytes % 8 == 0);
ASSERT(bytes <= CELL_BUFFER_SIZE);
ASSERT(cell->cur_batch >= 0);
@@ -171,7 +171,7 @@ cell_batch_alloc(struct cell_context *cell, uint bytes)
void *pos;
uint size;
- ASSERT(bytes % 4 == 0);
+ ASSERT(bytes % 8 == 0);
ASSERT(bytes <= CELL_BUFFER_SIZE);
assert(cell->cur_batch >= 0);
diff --git a/src/mesa/pipe/cell/ppu/cell_flush.c b/src/mesa/pipe/cell/ppu/cell_flush.c
index cf4e676..f62bc46 100644
--- a/src/mesa/pipe/cell/ppu/cell_flush.c
+++ b/src/mesa/pipe/cell/ppu/cell_flush.c
@@ -59,7 +59,7 @@ cell_flush_int(struct pipe_context *pipe, unsigned flags)
flushing = TRUE;
if (flags & PIPE_FLUSH_WAIT) {
- uint *cmd = (uint *) cell_batch_alloc(cell, sizeof(uint));
+ uint64_t *cmd = (uint64_t *) cell_batch_alloc(cell, sizeof(uint64_t));
*cmd = CELL_CMD_FINISH;
}
diff --git a/src/mesa/pipe/cell/ppu/cell_state_emit.c b/src/mesa/pipe/cell/ppu/cell_state_emit.c
index 7021844..1cbee4d 100644
--- a/src/mesa/pipe/cell/ppu/cell_state_emit.c
+++ b/src/mesa/pipe/cell/ppu/cell_state_emit.c
@@ -37,7 +37,8 @@ static void
emit_state_cmd(struct cell_context *cell, uint cmd,
const void *state, uint state_size)
{
- uint *dst = (uint *) cell_batch_alloc(cell, sizeof(uint) + state_size);
+ uint64_t *dst = (uint64_t *)
+ cell_batch_alloc(cell, ROUNDUP8(sizeof(uint64_t) + state_size));
*dst = cmd;
memcpy(dst + 1, state, state_size);
}
diff --git a/src/mesa/pipe/cell/ppu/cell_vbuf.c b/src/mesa/pipe/cell/ppu/cell_vbuf.c
index e63b34c..04b32f2 100644
--- a/src/mesa/pipe/cell/ppu/cell_vbuf.c
+++ b/src/mesa/pipe/cell/ppu/cell_vbuf.c
@@ -197,7 +197,7 @@ cell_vbuf_draw(struct vbuf_render *vbr,
/* build/insert batch RENDER command */
{
- const uint index_bytes = ROUNDUP4(nr_indices * 2);
+ const uint index_bytes = ROUNDUP8(nr_indices * 2);
const uint vertex_bytes = nr_vertices * 4 * cell->vertex_info.size;
const uint batch_size = sizeof(struct cell_command_render)
diff --git a/src/mesa/pipe/cell/ppu/cell_vertex_shader.c b/src/mesa/pipe/cell/ppu/cell_vertex_shader.c
index aef329a..80dd500 100644
--- a/src/mesa/pipe/cell/ppu/cell_vertex_shader.c
+++ b/src/mesa/pipe/cell/ppu/cell_vertex_shader.c
@@ -52,8 +52,8 @@ cell_vertex_shader_queue_flush(struct draw_context *draw)
struct cell_context *const cell =
(struct cell_context *) draw->driver_private;
struct cell_command_vs *const vs = &cell_global.command[0].vs;
- unsigned *batch;
- struct cell_array_info array_info;
+ uint64_t *batch;
+ struct cell_array_info *array_info;
unsigned i, j;
assert(draw->vs.queue_nr != 0);
@@ -63,17 +63,19 @@ cell_vertex_shader_queue_flush(struct draw_context *draw)
draw_update_vertex_fetch(draw);
for (i = 0; i < draw->vertex_fetch.nr_attrs; i++) {
- array_info.opcode = CELL_CMD_STATE_VS_ARRAY_INFO;
- assert(draw->vertex_fetch.src_ptr[i] != NULL);
- array_info.base = (uintptr_t) draw->vertex_fetch.src_ptr[i];
- array_info.attr = i;
- array_info.pitch = draw->vertex_fetch.pitch[i];
- array_info.format = draw->vertex_element[i].src_format;
+ batch = cell_batch_alloc(cell, sizeof(batch[0]) + sizeof(*array_info));
+
+ batch[0] = CELL_CMD_STATE_VS_ARRAY_INFO;
- cell_batch_append(cell, & array_info, sizeof(array_info));
+ array_info = (struct cell_array_info *) &batch[1];
+ assert(draw->vertex_fetch.src_ptr[i] != NULL);
+ array_info->base = (uintptr_t) draw->vertex_fetch.src_ptr[i];
+ array_info->attr = i;
+ array_info->pitch = draw->vertex_fetch.pitch[i];
+ array_info->format = draw->vertex_element[i].src_format;
}
- batch = cell_batch_alloc(cell, sizeof(unsigned)
+ batch = cell_batch_alloc(cell, sizeof(batch[0])
+ sizeof(struct pipe_viewport_state));
batch[0] = CELL_CMD_STATE_VIEWPORT;
(void) memcpy(&batch[1], &draw->viewport,
diff --git a/src/mesa/pipe/cell/spu/spu_colorpack.h b/src/mesa/pipe/cell/spu/spu_colorpack.h
index 9977a6e..e11fa85 100644
--- a/src/mesa/pipe/cell/spu/spu_colorpack.h
+++ b/src/mesa/pipe/cell/spu/spu_colorpack.h
@@ -31,7 +31,14 @@
#define SPU_COLORPACK_H
-#include <vec_literal.h>
+//#include <vec_literal.h>
+#define VEC_LITERAL(type, \
+ v0, v1, v2, v3, v4, v5, v6, v7, \
+ v8, v9, va, vb, vc, vd, ve, vf) \
+ (type) { v0, v1, v2, v3, v4, v5, v6, v7, \
+ v8, v9, va, vb, vc, vd, ve, vf }
+
+
#include <spu_intrinsics.h>
diff --git a/src/mesa/pipe/cell/spu/spu_main.c b/src/mesa/pipe/cell/spu/spu_main.c
index ba4d180..8b5227d 100644
--- a/src/mesa/pipe/cell/spu/spu_main.c
+++ b/src/mesa/pipe/cell/spu/spu_main.c
@@ -31,7 +31,11 @@
#include <stdio.h>
#include <libmisc.h>
-#include <vec_literal.h>
+//#include <vec_literal.h>
+#define VEC_LITERAL(type, v0, v1, v2, v3, v4, v5, v6, v7, \
+ v8, v9, va, vb, vc, vd, ve, vf) \
+ (type) { v0, v1, v2, v3, v4, v5, v6, v7, \
+ v8, v9, va, vb, vc, vd, ve, vf }
#include "spu_main.h"
#include "spu_render.h"
@@ -315,8 +319,8 @@ cmd_batch(uint opcode)
{
const uint buf = (opcode >> 8) & 0xff;
uint size = (opcode >> 16);
- uint buffer[CELL_BUFFER_SIZE / 4] ALIGN16_ATTRIB;
- const uint usize = size / sizeof(uint);
+ uint64_t buffer[CELL_BUFFER_SIZE / 8] ALIGN16_ATTRIB;
+ const unsigned usize = size / sizeof(buffer[0]);
uint pos;
if (Debug)
@@ -351,7 +355,7 @@ cmd_batch(uint opcode)
struct cell_command_framebuffer *fb
= (struct cell_command_framebuffer *) &buffer[pos];
cmd_state_framebuffer(fb);
- pos += sizeof(*fb) / 4;
+ pos += sizeof(*fb) / 8;
}
break;
case CELL_CMD_CLEAR_SURFACE:
@@ -359,7 +363,7 @@ cmd_batch(uint opcode)
struct cell_command_clear_surface *clr
= (struct cell_command_clear_surface *) &buffer[pos];
cmd_clear_surface(clr);
- pos += sizeof(*clr) / 4;
+ pos += sizeof(*clr) / 8;
}
break;
case CELL_CMD_RENDER:
@@ -368,7 +372,7 @@ cmd_batch(uint opcode)
= (struct cell_command_render *) &buffer[pos];
uint pos_incr;
cmd_render(render, &pos_incr);
- pos += sizeof(*render) / 4 + pos_incr;
+ pos += sizeof(*render) / 8 + ((pos_incr + 1) / 2);
}
break;
case CELL_CMD_RELEASE_VERTS:
@@ -376,8 +380,7 @@ cmd_batch(uint opcode)
struct cell_command_release_verts *release
= (struct cell_command_release_verts *) &buffer[pos];
cmd_release_verts(release);
- ASSERT(sizeof(*release) == 8);
- pos += sizeof(*release) / 4;
+ pos += sizeof(*release) / 8;
}
break;
case CELL_CMD_FINISH:
@@ -387,31 +390,31 @@ cmd_batch(uint opcode)
case CELL_CMD_STATE_DEPTH_STENCIL:
cmd_state_depth_stencil((struct pipe_depth_stencil_alpha_state *)
&buffer[pos+1]);
- pos += (1 + sizeof(struct pipe_depth_stencil_alpha_state) / 4);
+ pos += (1 + ROUNDUP8(sizeof(struct pipe_depth_stencil_alpha_state)) / 8);
break;
case CELL_CMD_STATE_SAMPLER:
cmd_state_sampler((struct pipe_sampler_state *) &buffer[pos+1]);
- pos += (1 + sizeof(struct pipe_sampler_state) / 4);
+ pos += (1 + ROUNDUP8(sizeof(struct pipe_sampler_state)) / 8);
break;
case CELL_CMD_STATE_TEXTURE:
cmd_state_texture((struct cell_command_texture *) &buffer[pos+1]);
- pos += (1 + sizeof(struct cell_command_texture) / 4);
+ pos += (1 + ROUNDUP8(sizeof(struct cell_command_texture)) / 8);
break;
case CELL_CMD_STATE_VERTEX_INFO:
cmd_state_vertex_info((struct vertex_info *) &buffer[pos+1]);
- pos += (1 + sizeof(struct vertex_info) / 4);
+ pos += (1 + ROUNDUP8(sizeof(struct vertex_info)) / 8);
break;
case CELL_CMD_STATE_VIEWPORT:
(void) memcpy(& draw.viewport, &buffer[pos+1],
sizeof(struct pipe_viewport_state));
- pos += (1 + sizeof(struct pipe_viewport_state) / 4);
+ pos += (1 + ROUNDUP8(sizeof(struct pipe_viewport_state)) / 8);
break;
case CELL_CMD_STATE_VS_ARRAY_INFO:
- cmd_state_vs_array_info((struct cell_array_info *) &buffer[pos]);
- pos += (sizeof(struct cell_array_info) / 4);
+ cmd_state_vs_array_info((struct cell_array_info *) &buffer[pos+1]);
+ pos += (1 + ROUNDUP8(sizeof(struct cell_array_info)) / 8);
break;
default:
- printf("SPU %u: bad opcode: 0x%x\n", spu.init.id, buffer[pos]);
+ printf("SPU %u: bad opcode: 0x%llx\n", spu.init.id, buffer[pos]);
ASSERT(0);
break;
}
diff --git a/src/mesa/pipe/cell/spu/spu_vertex_fetch.c b/src/mesa/pipe/cell/spu/spu_vertex_fetch.c
index 9734677..cfa449e 100644
--- a/src/mesa/pipe/cell/spu/spu_vertex_fetch.c
+++ b/src/mesa/pipe/cell/spu/spu_vertex_fetch.c
@@ -386,9 +386,8 @@ static void generic_vertex_fetch(struct spu_vs_context *draw,
/* loop over vertex attributes (vertex shader inputs)
*/
for (attr = 0; attr < nr_attrs; attr++) {
-
- const unsigned pitch = draw->vertex_fetch.pitch[attr];
- const ubyte *src = draw->vertex_fetch.src_ptr[attr];
+ const unsigned pitch = draw->vertex_fetch.pitch[attr];
+ const uint64_t src = draw->vertex_fetch.src_ptr[attr];
const spu_fetch_func fetch = draw->vertex_fetch.fetch[attr];
unsigned i;
qword p[4];
@@ -402,7 +401,7 @@ static void generic_vertex_fetch(struct spu_vs_context *draw,
*/
for (i = 0; i < count; i++) {
uint8_t buffer[32] ALIGN16_ATTRIB;
- const unsigned long addr = src + (elts[i] * pitch);
+ const uint64_t addr = src + (elts[i] * pitch);
const unsigned size = ((addr & 0x0f) == 0) ? 16 : 32;
#if DRAW_DBG
diff --git a/src/mesa/pipe/cell/spu/spu_vertex_shader.h b/src/mesa/pipe/cell/spu/spu_vertex_shader.h
index 4558839..2435b7d 100644
--- a/src/mesa/pipe/cell/spu/spu_vertex_shader.h
+++ b/src/mesa/pipe/cell/spu/spu_vertex_shader.h
@@ -16,7 +16,7 @@ struct spu_vs_context {
struct pipe_viewport_state viewport;
struct {
- const ubyte *src_ptr[PIPE_ATTRIB_MAX];
+ uint64_t src_ptr[PIPE_ATTRIB_MAX];
unsigned pitch[PIPE_ATTRIB_MAX];
enum pipe_format format[PIPE_ATTRIB_MAX];
unsigned nr_attrs;
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Mesa3d-dev mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev