mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 00:00:11 +01:00
cell: more work for multi-texture support
This commit is contained in:
parent
5553a3b675
commit
e6c981f22c
6 changed files with 90 additions and 57 deletions
|
|
@ -36,6 +36,7 @@
|
|||
#include "pipe/p_compiler.h"
|
||||
#include "pipe/p_util.h"
|
||||
#include "pipe/p_format.h"
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
|
||||
/** The standard assert macro doesn't seem to work reliably */
|
||||
|
|
@ -228,12 +229,20 @@ struct cell_command_release_verts
|
|||
};
|
||||
|
||||
|
||||
struct cell_command_sampler
|
||||
{
|
||||
uint64_t opcode; /**< CELL_CMD_STATE_SAMPLER */
|
||||
uint unit;
|
||||
struct pipe_sampler_state state;
|
||||
};
|
||||
|
||||
|
||||
struct cell_command_texture
|
||||
{
|
||||
struct {
|
||||
void *start; /**< Address in main memory */
|
||||
ushort width, height;
|
||||
} texture[CELL_MAX_SAMPLERS];
|
||||
uint64_t opcode; /**< CELL_CMD_STATE_TEXTURE */
|
||||
uint unit;
|
||||
void *start; /**< Address in main memory */
|
||||
ushort width, height;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -121,25 +121,36 @@ cell_emit_state(struct cell_context *cell)
|
|||
}
|
||||
|
||||
if (cell->dirty & CELL_NEW_SAMPLER) {
|
||||
if (cell->sampler[0]) {
|
||||
emit_state_cmd(cell, CELL_CMD_STATE_SAMPLER,
|
||||
cell->sampler[0], sizeof(struct pipe_sampler_state));
|
||||
uint i;
|
||||
for (i = 0; i < CELL_MAX_SAMPLERS; i++) {
|
||||
if (cell->sampler[i]) {
|
||||
struct cell_command_sampler *sampler
|
||||
= cell_batch_alloc(cell, sizeof(*sampler));
|
||||
sampler->opcode = CELL_CMD_STATE_SAMPLER;
|
||||
sampler->unit = i;
|
||||
sampler->state = *cell->sampler[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cell->dirty & CELL_NEW_TEXTURE) {
|
||||
struct cell_command_texture texture;
|
||||
uint i;
|
||||
memset(&texture, 0, sizeof(texture));
|
||||
for (i = 0;i < CELL_MAX_SAMPLERS; i++) {
|
||||
struct cell_command_texture *texture
|
||||
= cell_batch_alloc(cell, sizeof(*texture));
|
||||
texture->opcode = CELL_CMD_STATE_TEXTURE;
|
||||
texture->unit = i;
|
||||
if (cell->texture[i]) {
|
||||
texture.texture[i].start = cell->texture[i]->tiled_data;
|
||||
texture.texture[i].width = cell->texture[i]->base.width[0];
|
||||
texture.texture[i].height = cell->texture[i]->base.height[0];
|
||||
texture->start = cell->texture[i]->tiled_data;
|
||||
texture->width = cell->texture[i]->base.width[0];
|
||||
texture->height = cell->texture[i]->base.height[0];
|
||||
}
|
||||
else {
|
||||
texture->start = NULL;
|
||||
texture->width = 1;
|
||||
texture->height = 1;
|
||||
}
|
||||
}
|
||||
emit_state_cmd(cell, CELL_CMD_STATE_TEXTURE,
|
||||
&texture, sizeof(struct cell_command_texture));
|
||||
}
|
||||
|
||||
if (cell->dirty & CELL_NEW_VERTEX_INFO) {
|
||||
|
|
|
|||
|
|
@ -312,13 +312,13 @@ cmd_state_depth_stencil(const struct cell_command_depth_stencil_alpha_test *stat
|
|||
|
||||
|
||||
static void
|
||||
cmd_state_sampler(const struct pipe_sampler_state *state)
|
||||
cmd_state_sampler(const struct cell_command_sampler *sampler)
|
||||
{
|
||||
if (Debug)
|
||||
printf("SPU %u: SAMPLER\n",
|
||||
spu.init.id);
|
||||
printf("SPU %u: SAMPLER [%u]\n",
|
||||
spu.init.id, sampler->unit);
|
||||
|
||||
memcpy(&spu.sampler[0], state, sizeof(*state));
|
||||
spu.sampler[sampler->unit] = sampler->state;
|
||||
if (spu.sampler[0].min_img_filter == PIPE_TEX_FILTER_LINEAR)
|
||||
spu.sample_texture = sample_texture_bilinear;
|
||||
else
|
||||
|
|
@ -329,26 +329,25 @@ cmd_state_sampler(const struct pipe_sampler_state *state)
|
|||
static void
|
||||
cmd_state_texture(const struct cell_command_texture *texture)
|
||||
{
|
||||
uint i;
|
||||
const uint unit = texture->unit;
|
||||
const uint width = texture->width;
|
||||
const uint height = texture->height;
|
||||
|
||||
if (1||Debug) {
|
||||
printf("SPU %u: TEXTURE\n", spu.init.id);
|
||||
for (i = 0; i < CELL_MAX_SAMPLERS; i++) {
|
||||
printf(" %d: at %p size %u x %u\n", i, texture->texture[i].start,
|
||||
texture->texture[i].width, texture->texture[i].height);
|
||||
}
|
||||
if (Debug) {
|
||||
printf("SPU %u: TEXTURE [%u] at %p size %u x %u\n", spu.init.id,
|
||||
texture->unit, texture->start,
|
||||
texture->width, texture->height);
|
||||
}
|
||||
|
||||
memcpy(&spu.texture, texture, sizeof(*texture));
|
||||
for (i = 0; i < CELL_MAX_SAMPLERS; i++) {
|
||||
const uint width = texture->texture[i].width;
|
||||
const uint height = texture->texture[i].height;
|
||||
spu.tex_size[i] = (vector float) { width, height, 0.0, 0.0};
|
||||
spu.tex_size_mask[i] = (vector unsigned int)
|
||||
spu.texture[unit].start = texture->start;
|
||||
spu.texture[unit].width = width;
|
||||
spu.texture[unit].height = height;
|
||||
|
||||
spu.texture[unit].tex_size = (vector float) { width, height, 0.0, 0.0};
|
||||
spu.texture[unit].tex_size_mask = (vector unsigned int)
|
||||
{ width - 1, height - 1, 0, 0 };
|
||||
spu.tex_size_x_mask[i] = spu_splats(width - 1);
|
||||
spu.tex_size_y_mask[i] = spu_splats(height - 1);
|
||||
}
|
||||
spu.texture[unit].tex_size_x_mask = spu_splats(width - 1);
|
||||
spu.texture[unit].tex_size_y_mask = spu_splats(height - 1);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -480,12 +479,20 @@ cmd_batch(uint opcode)
|
|||
pos += (1 + ROUNDUP8(sizeof(struct cell_command_depth_stencil_alpha_test)) / 8);
|
||||
break;
|
||||
case CELL_CMD_STATE_SAMPLER:
|
||||
cmd_state_sampler((struct pipe_sampler_state *) &buffer[pos+1]);
|
||||
pos += (1 + ROUNDUP8(sizeof(struct pipe_sampler_state)) / 8);
|
||||
{
|
||||
struct cell_command_sampler *sampler
|
||||
= (struct cell_command_sampler *) &buffer[pos];
|
||||
cmd_state_sampler(sampler);
|
||||
pos += sizeof(*sampler) / 8;
|
||||
}
|
||||
break;
|
||||
case CELL_CMD_STATE_TEXTURE:
|
||||
cmd_state_texture((struct cell_command_texture *) &buffer[pos+1]);
|
||||
pos += (1 + ROUNDUP8(sizeof(struct cell_command_texture)) / 8);
|
||||
{
|
||||
struct cell_command_texture *texture
|
||||
= (struct cell_command_texture *) &buffer[pos];
|
||||
cmd_state_texture(texture);
|
||||
pos += sizeof(*texture) / 8;
|
||||
}
|
||||
break;
|
||||
case CELL_CMD_STATE_VERTEX_INFO:
|
||||
cmd_state_vertex_info((struct vertex_info *) &buffer[pos+1]);
|
||||
|
|
|
|||
|
|
@ -100,6 +100,17 @@ struct spu_framebuffer {
|
|||
} ALIGN16_ATTRIB;
|
||||
|
||||
|
||||
struct spu_texture
|
||||
{
|
||||
void *start;
|
||||
uint width, height;
|
||||
vector float tex_size;
|
||||
vector unsigned int tex_size_mask; /**< == int(size - 1) */
|
||||
vector unsigned int tex_size_x_mask; /**< == int(size - 1) */
|
||||
vector unsigned int tex_size_y_mask; /**< == int(size - 1) */
|
||||
} ALIGN16_ATTRIB;
|
||||
|
||||
|
||||
/**
|
||||
* All SPU global/context state will be in singleton object of this type:
|
||||
*/
|
||||
|
|
@ -119,7 +130,7 @@ struct spu_global
|
|||
logicop_func logicop;
|
||||
|
||||
struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS];
|
||||
struct cell_command_texture texture;
|
||||
struct spu_texture texture[PIPE_MAX_SAMPLERS];
|
||||
|
||||
struct vertex_info vertex_info;
|
||||
|
||||
|
|
@ -141,11 +152,6 @@ struct spu_global
|
|||
/** for converting RGBA to PIPE_FORMAT_x colors */
|
||||
vector unsigned char color_shuffle;
|
||||
|
||||
vector float tex_size[CELL_MAX_SAMPLERS];
|
||||
vector unsigned int tex_size_mask[CELL_MAX_SAMPLERS]; /**< == int(size - 1) */
|
||||
vector unsigned int tex_size_x_mask[CELL_MAX_SAMPLERS]; /**< == int(size - 1) */
|
||||
vector unsigned int tex_size_y_mask[CELL_MAX_SAMPLERS]; /**< == int(size - 1) */
|
||||
|
||||
vector float (*sample_texture)(vector float texcoord);
|
||||
|
||||
} ALIGN16_ATTRIB;
|
||||
|
|
|
|||
|
|
@ -41,10 +41,10 @@ void
|
|||
invalidate_tex_cache(void)
|
||||
{
|
||||
uint unit = 0;
|
||||
uint bytes = 4 * spu.texture.texture[unit].width
|
||||
* spu.texture.texture[unit].height;
|
||||
uint bytes = 4 * spu.texture[unit].width
|
||||
* spu.texture[unit].height;
|
||||
|
||||
spu_dcache_mark_dirty((unsigned) spu.texture.texture[unit].start, bytes);
|
||||
spu_dcache_mark_dirty((unsigned) spu.texture[unit].start, bytes);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -55,14 +55,14 @@ get_texel(vec_uint4 coordinate)
|
|||
vec_uint4 tmp;
|
||||
unsigned x = spu_extract(coordinate, 0);
|
||||
unsigned y = spu_extract(coordinate, 1);
|
||||
const unsigned tiles_per_row = spu.texture.texture[unit].width / TILE_SIZE;
|
||||
const unsigned tiles_per_row = spu.texture[unit].width / TILE_SIZE;
|
||||
unsigned tile_offset = sizeof(tile_t) * ((y / TILE_SIZE * tiles_per_row)
|
||||
+ (x / TILE_SIZE));
|
||||
unsigned texel_offset = 4 * (((y % TILE_SIZE) * TILE_SIZE)
|
||||
+ (x % TILE_SIZE));
|
||||
|
||||
spu_dcache_fetch_unaligned((qword *) & tmp,
|
||||
spu.texture.texture[unit].start + tile_offset + texel_offset,
|
||||
spu.texture[unit].start + tile_offset + texel_offset,
|
||||
4);
|
||||
return spu_extract(tmp, 0);
|
||||
}
|
||||
|
|
@ -72,13 +72,13 @@ static void
|
|||
get_four_texels(vec_uint4 x, vec_uint4 y, vec_uint4 *texels)
|
||||
{
|
||||
const uint unit = 0;
|
||||
const unsigned texture_ea = (uintptr_t) spu.texture.texture[unit].start;
|
||||
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);
|
||||
const qword offset_x = si_andi((qword) x, 0x1f);
|
||||
const qword offset_y = si_andi((qword) y, 0x1f);
|
||||
|
||||
const qword tiles_per_row = (qword) spu_splats(spu.texture.texture[unit].width / TILE_SIZE);
|
||||
const qword tiles_per_row = (qword) spu_splats(spu.texture[unit].width / TILE_SIZE);
|
||||
const qword tile_size = (qword) spu_splats(sizeof(tile_t));
|
||||
|
||||
qword tile_offset = si_mpya((qword) tile_y, tiles_per_row, (qword) tile_x);
|
||||
|
|
@ -107,9 +107,9 @@ vector float
|
|||
sample_texture_nearest(vector float texcoord)
|
||||
{
|
||||
const uint unit = 0;
|
||||
vector float tc = spu_mul(texcoord, spu.tex_size[unit]);
|
||||
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.tex_size_mask[unit]); /* mask (GL_REPEAT) */
|
||||
itc = spu_and(itc, spu.texture[unit].tex_size_mask); /* mask (GL_REPEAT) */
|
||||
uint texel = get_texel(itc);
|
||||
return spu_unpack_A8R8G8B8(texel);
|
||||
}
|
||||
|
|
@ -122,7 +122,7 @@ sample_texture_bilinear(vector float texcoord)
|
|||
static const vec_uint4 offset_x = {0, 0, 1, 1};
|
||||
static const vec_uint4 offset_y = {0, 1, 0, 1};
|
||||
|
||||
vector float tc = spu_mul(texcoord, spu.tex_size[unit]);
|
||||
vector float tc = spu_mul(texcoord, spu.texture[unit].tex_size);
|
||||
tc = spu_add(tc, spu_splats(-0.5f)); /* half texel bias */
|
||||
|
||||
/* integer texcoords S,T: */
|
||||
|
|
@ -136,8 +136,8 @@ sample_texture_bilinear(vector float texcoord)
|
|||
x = spu_add(x, offset_x);
|
||||
y = spu_add(y, offset_y);
|
||||
|
||||
x = spu_and(x, spu.tex_size_x_mask[unit]);
|
||||
y = spu_and(y, spu.tex_size_y_mask[unit]);
|
||||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -309,7 +309,7 @@ emit_quad( int x, int y, mask_t mask )
|
|||
|
||||
spu.cur_ctile_status = TILE_STATUS_DIRTY;
|
||||
|
||||
if (spu.texture.texture[0].start) {
|
||||
if (spu.texture[0].start) {
|
||||
/* texture mapping */
|
||||
vector float texcoords[4];
|
||||
eval_coeff(2, (float) x, (float) y, texcoords);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue