summaryrefslogtreecommitdiff
path: root/src/mesa/pipe/cell/ppu
diff options
context:
space:
mode:
authorBrian <brian.paul@tungstengraphics.com>2008-01-28 17:23:44 -0700
committerBrian <brian.paul@tungstengraphics.com>2008-01-28 18:18:46 -0700
commit425f270fcbfdbfce98adaf9da4b8eb7360f34447 (patch)
treeaeb424c4598456849ca32ac2b2ae90874edff9f7 /src/mesa/pipe/cell/ppu
parentc2372cc7481bf3985a6a3126952ab9d5dab4bf77 (diff)
Cell: basic texture mapping
Texture images are tiled in PPU code. SPUs use a texture cache for getting texels from textures. This is very rough code, but demos/texcyl.c works.
Diffstat (limited to 'src/mesa/pipe/cell/ppu')
-rw-r--r--src/mesa/pipe/cell/ppu/cell_context.h5
-rw-r--r--src/mesa/pipe/cell/ppu/cell_state_emit.c12
-rw-r--r--src/mesa/pipe/cell/ppu/cell_state_sampler.c10
-rw-r--r--src/mesa/pipe/cell/ppu/cell_texture.c87
-rw-r--r--src/mesa/pipe/cell/ppu/cell_texture.h6
5 files changed, 115 insertions, 5 deletions
diff --git a/src/mesa/pipe/cell/ppu/cell_context.h b/src/mesa/pipe/cell/ppu/cell_context.h
index de65fb5e9a..7d234f3e45 100644
--- a/src/mesa/pipe/cell/ppu/cell_context.h
+++ b/src/mesa/pipe/cell/ppu/cell_context.h
@@ -76,7 +76,7 @@ struct cell_context
struct pipe_framebuffer_state framebuffer;
struct pipe_poly_stipple poly_stipple;
struct pipe_scissor_state scissor;
- struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
+ struct cell_texture *texture[PIPE_MAX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX];
struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX];
@@ -84,6 +84,9 @@ struct cell_context
ubyte *cbuf_map[PIPE_MAX_COLOR_BUFS];
ubyte *zsbuf_map;
+ struct pipe_surface *tex_surf;
+ uint *tex_map;
+
uint dirty;
/** The primitive drawing context */
diff --git a/src/mesa/pipe/cell/ppu/cell_state_emit.c b/src/mesa/pipe/cell/ppu/cell_state_emit.c
index 6776ec88c7..391ff454ac 100644
--- a/src/mesa/pipe/cell/ppu/cell_state_emit.c
+++ b/src/mesa/pipe/cell/ppu/cell_state_emit.c
@@ -30,7 +30,7 @@
#include "cell_state.h"
#include "cell_state_emit.h"
#include "cell_batch.h"
-
+#include "cell_texture.h"
static void
@@ -72,6 +72,16 @@ cell_emit_state(struct cell_context *cell)
cell->sampler[0], sizeof(struct pipe_sampler_state));
}
+ if (cell->dirty & CELL_NEW_TEXTURE) {
+ struct cell_command_texture texture;
+ texture.start = cell->texture[0]->tiled_data;
+ texture.width = cell->texture[0]->base.width[0];
+ texture.height = cell->texture[0]->base.height[0];
+
+ emit_state_cmd(cell, CELL_CMD_STATE_TEXTURE,
+ &texture, sizeof(struct cell_command_texture));
+ }
+
if (cell->dirty & CELL_NEW_VERTEX_INFO) {
emit_state_cmd(cell, CELL_CMD_STATE_VERTEX_INFO,
&cell->vertex_info, sizeof(struct vertex_info));
diff --git a/src/mesa/pipe/cell/ppu/cell_state_sampler.c b/src/mesa/pipe/cell/ppu/cell_state_sampler.c
index ae1eeb4620..317f7603bb 100644
--- a/src/mesa/pipe/cell/ppu/cell_state_sampler.c
+++ b/src/mesa/pipe/cell/ppu/cell_state_sampler.c
@@ -30,12 +30,10 @@
*/
#include "pipe/p_util.h"
+#include "pipe/draw/draw_context.h"
#include "cell_context.h"
#include "cell_state.h"
-#if 0
#include "cell_texture.h"
-#include "cell_tile_cache.h"
-#endif
void *
@@ -53,6 +51,8 @@ cell_bind_sampler_state(struct pipe_context *pipe,
{
struct cell_context *cell = cell_context(pipe);
+ draw_flush(cell->draw);
+
assert(unit < PIPE_MAX_SAMPLERS);
cell->sampler[unit] = (struct pipe_sampler_state *)sampler;
@@ -76,7 +76,11 @@ cell_set_sampler_texture(struct pipe_context *pipe,
{
struct cell_context *cell = cell_context(pipe);
+ draw_flush(cell->draw);
+
cell->texture[sampler] = texture;
+ cell_update_texture_mapping(cell);
+
cell->dirty |= CELL_NEW_TEXTURE;
}
diff --git a/src/mesa/pipe/cell/ppu/cell_texture.c b/src/mesa/pipe/cell/ppu/cell_texture.c
index 0a8190d983..acbe4c79f0 100644
--- a/src/mesa/pipe/cell/ppu/cell_texture.c
+++ b/src/mesa/pipe/cell/ppu/cell_texture.c
@@ -163,3 +163,90 @@ cell_get_tex_surface(struct pipe_context *pipe,
}
return ps;
}
+
+
+
+static void
+tile_copy_data(uint w, uint h, uint tile_size, uint *dst, const uint *src)
+{
+ const uint tile_size2 = tile_size * tile_size;
+ const uint h_t = h / tile_size, w_t = w / tile_size;
+
+ uint it, jt; /* tile counters */
+ uint i, j; /* intra-tile counters */
+
+ for (it = 0; it < h_t; it++) {
+ for (jt = 0; jt < w_t; jt++) {
+ /* fill in tile (i, j) */
+ uint *tdst = dst + (it * w_t + jt) * tile_size2;
+ for (i = 0; i < tile_size; i++) {
+ for (j = 0; j < tile_size; j++) {
+ const uint srci = it * tile_size + i;
+ const uint srcj = jt * tile_size + j;
+ *tdst++ = src[srci * h + srcj];
+ }
+ }
+ }
+ }
+}
+
+
+
+/**
+ * Convert linear texture image data to tiled format for SPU usage.
+ */
+static void
+cell_tile_texture(struct cell_context *cell,
+ struct cell_texture *texture)
+{
+ uint face = 0, level = 0, zslice = 0;
+ struct pipe_surface *surf;
+ const uint w = texture->base.width[0], h = texture->base.height[0];
+ const uint *src;
+
+ /* temporary restrictions: */
+ assert(w >= TILE_SIZE);
+ assert(h >= TILE_SIZE);
+ assert(w % TILE_SIZE == 0);
+ assert(h % TILE_SIZE == 0);
+
+ surf = cell_get_tex_surface(&cell->pipe, &texture->base, face, level, zslice);
+ ASSERT(surf);
+
+ src = (const uint *) pipe_surface_map(surf);
+
+ if (texture->tiled_data) {
+ align_free(texture->tiled_data);
+ }
+ texture->tiled_data = align_malloc(w * h * 4, 16);
+
+ tile_copy_data(w, h, TILE_SIZE, texture->tiled_data, src);
+
+ pipe_surface_unmap(surf);
+
+ pipe_surface_reference(&surf, NULL);
+}
+
+
+
+void
+cell_update_texture_mapping(struct cell_context *cell)
+{
+ uint face = 0, level = 0, zslice = 0;
+
+ cell_tile_texture(cell, cell->texture[0]);
+#if 0
+ if (cell->tex_surf && cell->tex_map) {
+ pipe_surface_unmap(cell->tex_surf);
+ cell->tex_map = NULL;
+ }
+
+ /* XXX free old surface */
+
+ cell->tex_surf = cell_get_tex_surface(&cell->pipe,
+ &cell->texture[0]->base,
+ face, level, zslice);
+
+ cell->tex_map = pipe_surface_map(cell->tex_surf);
+#endif
+}
diff --git a/src/mesa/pipe/cell/ppu/cell_texture.h b/src/mesa/pipe/cell/ppu/cell_texture.h
index ef5808c086..bd434c8776 100644
--- a/src/mesa/pipe/cell/ppu/cell_texture.h
+++ b/src/mesa/pipe/cell/ppu/cell_texture.h
@@ -46,6 +46,8 @@ struct cell_texture
*/
struct pipe_buffer *buffer;
unsigned long buffer_size;
+
+ void *tiled_data; /* XXX this may be temporary */ /*ALIGN16*/
};
@@ -70,4 +72,8 @@ cell_get_tex_surface(struct pipe_context *pipe,
unsigned face, unsigned level, unsigned zslice);
+extern void
+cell_update_texture_mapping(struct cell_context *cell);
+
+
#endif /* CELL_TEXTURE */