summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/cell
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/cell')
-rw-r--r--src/gallium/drivers/cell/ppu/cell_pipe_state.c10
-rw-r--r--src/gallium/drivers/cell/ppu/cell_screen.c3
-rw-r--r--src/gallium/drivers/cell/ppu/cell_texture.c14
-rw-r--r--src/gallium/drivers/cell/spu/spu_dcache.c18
-rw-r--r--src/gallium/drivers/cell/spu/spu_dcache.h3
-rw-r--r--src/gallium/drivers/cell/spu/spu_main.c8
-rw-r--r--src/gallium/drivers/cell/spu/spu_main.h4
-rw-r--r--src/gallium/drivers/cell/spu/spu_texture.c16
-rw-r--r--src/gallium/drivers/cell/spu/spu_texture.h4
-rw-r--r--src/gallium/drivers/cell/spu/spu_tri.c34
10 files changed, 85 insertions, 29 deletions
diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c
index 52c3126050..67b87f16d7 100644
--- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c
+++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c
@@ -232,12 +232,12 @@ cell_bind_sampler_states(struct pipe_context *pipe,
{
struct cell_context *cell = cell_context(pipe);
- draw_flush(cell->draw);
+ assert(num <= CELL_MAX_SAMPLERS);
- assert(unit < PIPE_MAX_SAMPLERS);
+ draw_flush(cell->draw);
memcpy(cell->sampler, samplers, num * sizeof(void *));
- memset(&cell->sampler[num], 0, (PIPE_MAX_SAMPLERS - num) *
+ memset(&cell->sampler[num], 0, (CELL_MAX_SAMPLERS - num) *
sizeof(void *));
cell->num_samplers = num;
@@ -261,6 +261,8 @@ cell_set_sampler_textures(struct pipe_context *pipe,
struct cell_context *cell = cell_context(pipe);
uint i;
+ assert(num <= CELL_MAX_SAMPLERS);
+
/* Check for no-op */
if (num == cell->num_textures &&
!memcmp(cell->texture, texture, num * sizeof(struct pipe_texture *)))
@@ -268,7 +270,7 @@ cell_set_sampler_textures(struct pipe_context *pipe,
draw_flush(cell->draw);
- for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
+ for (i = 0; i < CELL_MAX_SAMPLERS; i++) {
struct pipe_texture *tex = i < num ? texture[i] : NULL;
pipe_texture_reference((struct pipe_texture **) &cell->texture[i], tex);
diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c
index 84b48bf4f1..5198b51441 100644
--- a/src/gallium/drivers/cell/ppu/cell_screen.c
+++ b/src/gallium/drivers/cell/ppu/cell_screen.c
@@ -31,6 +31,7 @@
#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
+#include "cell/common.h"
#include "cell_screen.h"
#include "cell_texture.h"
#include "cell_winsys.h"
@@ -55,7 +56,7 @@ cell_get_param(struct pipe_screen *screen, int param)
{
switch (param) {
case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
- return PIPE_MAX_SAMPLERS;
+ return CELL_MAX_SAMPLERS;
case PIPE_CAP_NPOT_TEXTURES:
return 0;
case PIPE_CAP_TWO_SIDED_STENCIL:
diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c
index 9c694e136d..07717da8f6 100644
--- a/src/gallium/drivers/cell/ppu/cell_texture.c
+++ b/src/gallium/drivers/cell/ppu/cell_texture.c
@@ -186,15 +186,17 @@ tile_copy_data(uint w, uint h, uint tile_size, uint *dst, const uint *src)
uint it, jt; /* tile counters */
uint i, j; /* intra-tile counters */
+ /* loop over dest tiles */
for (it = 0; it < h_t; it++) {
for (jt = 0; jt < w_t; jt++) {
- /* fill in tile (i, j) */
+ /* start of dest tile: */
uint *tdst = dst + (it * w_t + jt) * tile_size2;
+ /* loop over texels in the tile */
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];
+ *tdst++ = src[srci * w + srcj];
}
}
}
@@ -245,9 +247,13 @@ void
cell_update_texture_mapping(struct cell_context *cell)
{
uint face = 0, level = 0, zslice = 0;
+ uint i;
+
+ for (i = 0; i < CELL_MAX_SAMPLERS; i++) {
+ if (cell->texture[i])
+ cell_tile_texture(cell, cell->texture[i]);
+ }
- if (cell->texture[0])
- cell_tile_texture(cell, cell->texture[0]);
#if 0
if (cell->tex_surf && cell->tex_map) {
pipe_surface_unmap(cell->tex_surf);
diff --git a/src/gallium/drivers/cell/spu/spu_dcache.c b/src/gallium/drivers/cell/spu/spu_dcache.c
index a1701d80d1..167404cdc5 100644
--- a/src/gallium/drivers/cell/spu/spu_dcache.c
+++ b/src/gallium/drivers/cell/spu/spu_dcache.c
@@ -36,6 +36,7 @@
#define CACHE_SET_TAGID(set) (((set) & 0x03) + TAG_DCACHE0)
#define CACHE_LOG2NNWAY 2
#define CACHE_LOG2NSETS 6
+/*#define CACHE_STATS 1*/
#include <cache-api.h>
/* Yes folks, this is ugly.
@@ -123,3 +124,20 @@ spu_dcache_mark_dirty(unsigned ea, unsigned size)
? (entry & ~CACHELINE_VALID) : entry;
}
}
+
+
+/**
+ * Print cache utilization report
+ */
+void
+spu_dcache_report(void)
+{
+#ifdef CACHE_STATS
+ if (spu.init.id == 0) {
+ printf("SPU 0: Texture cache report:\n");
+ cache_pr_stats(data);
+ }
+#endif
+}
+
+
diff --git a/src/gallium/drivers/cell/spu/spu_dcache.h b/src/gallium/drivers/cell/spu/spu_dcache.h
index 7a06b8c25a..39a19eb31b 100644
--- a/src/gallium/drivers/cell/spu/spu_dcache.h
+++ b/src/gallium/drivers/cell/spu/spu_dcache.h
@@ -31,4 +31,7 @@ spu_dcache_fetch_unaligned(qword *dst, unsigned ea, unsigned size);
extern void
spu_dcache_mark_dirty(unsigned ea, unsigned size);
+extern void
+spu_dcache_report(void);
+
#endif /* SPU_DCACHE_H */
diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c
index 7f0473d198..1ab1c40379 100644
--- a/src/gallium/drivers/cell/spu/spu_main.c
+++ b/src/gallium/drivers/cell/spu/spu_main.c
@@ -319,10 +319,10 @@ cmd_state_sampler(const struct cell_command_sampler *sampler)
spu.init.id, sampler->unit);
spu.sampler[sampler->unit] = sampler->state;
- if (spu.sampler[0].min_img_filter == PIPE_TEX_FILTER_LINEAR)
- spu.sample_texture = sample_texture_bilinear;
+ if (spu.sampler[sampler->unit].min_img_filter == PIPE_TEX_FILTER_LINEAR)
+ spu.sample_texture[sampler->unit] = sample_texture_bilinear;
else
- spu.sample_texture = sample_texture_nearest;
+ spu.sample_texture[sampler->unit] = sample_texture_nearest;
}
@@ -629,6 +629,8 @@ main_loop(void)
if (Debug)
printf("SPU %u: Exit main loop\n", spu.init.id);
+
+ spu_dcache_report();
}
diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h
index 2bfad3535a..e9e39cbeab 100644
--- a/src/gallium/drivers/cell/spu/spu_main.h
+++ b/src/gallium/drivers/cell/spu/spu_main.h
@@ -85,6 +85,8 @@ typedef struct spu_blend_results (*logicop_func)(
qword frag_mask);
+typedef vector float (*sample_texture_func)(uint unit, vector float texcoord);
+
struct spu_framebuffer {
void *color_start; /**< addr of color surface in main memory */
void *depth_start; /**< addr of depth surface in main memory */
@@ -152,7 +154,7 @@ struct spu_global
/** for converting RGBA to PIPE_FORMAT_x colors */
vector unsigned char color_shuffle;
- vector float (*sample_texture)(vector float texcoord);
+ sample_texture_func sample_texture[CELL_MAX_SAMPLERS];
} ALIGN16_ATTRIB;
diff --git a/src/gallium/drivers/cell/spu/spu_texture.c b/src/gallium/drivers/cell/spu/spu_texture.c
index 4612501eb3..ceab246980 100644
--- a/src/gallium/drivers/cell/spu/spu_texture.c
+++ b/src/gallium/drivers/cell/spu/spu_texture.c
@@ -49,9 +49,8 @@ invalidate_tex_cache(void)
static uint
-get_texel(vec_uint4 coordinate)
+get_texel(uint unit, vec_uint4 coordinate)
{
- const uint unit = 0;
vec_uint4 tmp;
unsigned x = spu_extract(coordinate, 0);
unsigned y = spu_extract(coordinate, 1);
@@ -69,9 +68,8 @@ get_texel(vec_uint4 coordinate)
static void
-get_four_texels(vec_uint4 x, vec_uint4 y, vec_uint4 *texels)
+get_four_texels(uint unit, vec_uint4 x, vec_uint4 y, vec_uint4 *texels)
{
- const uint unit = 0;
const unsigned texture_ea = (uintptr_t) spu.texture[unit].start;
vec_uint4 tile_x = spu_rlmask(x, -5);
vec_uint4 tile_y = spu_rlmask(y, -5);
@@ -104,21 +102,19 @@ get_four_texels(vec_uint4 x, vec_uint4 y, vec_uint4 *texels)
* XXX this is extremely primitive for now.
*/
vector float
-sample_texture_nearest(vector float texcoord)
+sample_texture_nearest(uint unit, vector float texcoord)
{
- const uint unit = 0;
vector float tc = spu_mul(texcoord, spu.texture[unit].tex_size);
vector unsigned int itc = spu_convtu(tc, 0); /* convert to int */
itc = spu_and(itc, spu.texture[unit].tex_size_mask); /* mask (GL_REPEAT) */
- uint texel = get_texel(itc);
+ uint texel = get_texel(unit, itc);
return spu_unpack_A8R8G8B8(texel);
}
vector float
-sample_texture_bilinear(vector float texcoord)
+sample_texture_bilinear(uint unit, vector float texcoord)
{
- const uint unit = 0;
static const vec_uint4 offset_x = {0, 0, 1, 1};
static const vec_uint4 offset_y = {0, 1, 0, 1};
@@ -139,7 +135,7 @@ sample_texture_bilinear(vector float texcoord)
x = spu_and(x, spu.texture[unit].tex_size_x_mask);
y = spu_and(y, spu.texture[unit].tex_size_y_mask);
- get_four_texels(x, y, texels);
+ get_four_texels(unit, x, y, texels);
vector float texel00 = spu_unpack_A8R8G8B8(spu_extract(texels[0], 0));
vector float texel01 = spu_unpack_A8R8G8B8(spu_extract(texels[1], 0));
diff --git a/src/gallium/drivers/cell/spu/spu_texture.h b/src/gallium/drivers/cell/spu/spu_texture.h
index 95eb87080f..f7c9738be8 100644
--- a/src/gallium/drivers/cell/spu/spu_texture.h
+++ b/src/gallium/drivers/cell/spu/spu_texture.h
@@ -37,11 +37,11 @@ invalidate_tex_cache(void);
extern vector float
-sample_texture_nearest(vector float texcoord);
+sample_texture_nearest(uint unit, vector float texcoord);
extern vector float
-sample_texture_bilinear(vector float texcoord);
+sample_texture_bilinear(uint unit, vector float texcoord);
#endif /* SPU_TEXTURE_H */
diff --git a/src/gallium/drivers/cell/spu/spu_tri.c b/src/gallium/drivers/cell/spu/spu_tri.c
index 17e337bbdf..ab4ff8160a 100644
--- a/src/gallium/drivers/cell/spu/spu_tri.c
+++ b/src/gallium/drivers/cell/spu/spu_tri.c
@@ -311,17 +311,43 @@ emit_quad( int x, int y, mask_t mask )
if (spu.texture[0].start) {
/* texture mapping */
+ const uint unit = 0;
vector float texcoords[4];
eval_coeff(2, (float) x, (float) y, texcoords);
if (spu_extract(mask, 0))
- colors[0] = spu.sample_texture(texcoords[0]);
+ colors[0] = spu.sample_texture[unit](unit, texcoords[0]);
if (spu_extract(mask, 1))
- colors[1] = spu.sample_texture(texcoords[1]);
+ colors[1] = spu.sample_texture[unit](unit, texcoords[1]);
if (spu_extract(mask, 2))
- colors[2] = spu.sample_texture(texcoords[2]);
+ colors[2] = spu.sample_texture[unit](unit, texcoords[2]);
if (spu_extract(mask, 3))
- colors[3] = spu.sample_texture(texcoords[3]);
+ colors[3] = spu.sample_texture[unit](unit, texcoords[3]);
+
+
+ if (spu.texture[1].start) {
+ /* multi-texture mapping */
+ const uint unit = 1;
+ vector float colors1[4];
+
+ eval_coeff(2, (float) x, (float) y, texcoords);
+
+ if (spu_extract(mask, 0))
+ colors1[0] = spu.sample_texture[unit](unit, texcoords[0]);
+ if (spu_extract(mask, 1))
+ colors1[1] = spu.sample_texture[unit](unit, texcoords[1]);
+ if (spu_extract(mask, 2))
+ colors1[2] = spu.sample_texture[unit](unit, texcoords[2]);
+ if (spu_extract(mask, 3))
+ colors1[3] = spu.sample_texture[unit](unit, texcoords[3]);
+
+ /* hack: modulate first texture by second */
+ colors[0] = spu_mul(colors[0], colors1[0]);
+ colors[1] = spu_mul(colors[1], colors1[1]);
+ colors[2] = spu_mul(colors[2], colors1[2]);
+ colors[3] = spu_mul(colors[3], colors1[3]);
+ }
+
}
else {
/* simple shading */