cell: more efficient state emit for textures/samplers
This commit is contained in:
@@ -121,6 +121,8 @@ struct cell_context
|
||||
uint *tex_map;
|
||||
|
||||
uint dirty;
|
||||
uint dirty_textures; /* bitmask of texture units */
|
||||
uint dirty_samplers; /* bitmask of sampler units */
|
||||
|
||||
/** Cache of code generated for per-fragment ops */
|
||||
struct keymap *fragment_ops_cache;
|
||||
|
||||
@@ -212,17 +212,24 @@ cell_bind_sampler_states(struct pipe_context *pipe,
|
||||
unsigned num, void **samplers)
|
||||
{
|
||||
struct cell_context *cell = cell_context(pipe);
|
||||
uint i, changed = 0x0;
|
||||
|
||||
assert(num <= CELL_MAX_SAMPLERS);
|
||||
|
||||
draw_flush(cell->draw);
|
||||
|
||||
memcpy(cell->sampler, samplers, num * sizeof(void *));
|
||||
memset(&cell->sampler[num], 0, (CELL_MAX_SAMPLERS - num) *
|
||||
sizeof(void *));
|
||||
cell->num_samplers = num;
|
||||
for (i = 0; i < CELL_MAX_SAMPLERS; i++) {
|
||||
struct pipe_sampler_state *new_samp = i < num ? samplers[i] : NULL;
|
||||
if (cell->sampler[i] != new_samp) {
|
||||
cell->sampler[i] = new_samp;
|
||||
changed |= (1 << i);
|
||||
}
|
||||
}
|
||||
|
||||
cell->dirty |= CELL_NEW_SAMPLER;
|
||||
if (changed) {
|
||||
cell->dirty |= CELL_NEW_SAMPLER;
|
||||
cell->dirty_samplers |= changed;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -240,25 +247,23 @@ cell_set_sampler_textures(struct pipe_context *pipe,
|
||||
unsigned num, struct pipe_texture **texture)
|
||||
{
|
||||
struct cell_context *cell = cell_context(pipe);
|
||||
uint i;
|
||||
uint i, changed = 0x0;
|
||||
|
||||
assert(num <= CELL_MAX_SAMPLERS);
|
||||
|
||||
/* Check for no-op */
|
||||
if (num == cell->num_textures &&
|
||||
!memcmp(cell->texture, texture, num * sizeof(struct pipe_texture *)))
|
||||
return;
|
||||
|
||||
draw_flush(cell->draw);
|
||||
|
||||
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);
|
||||
struct pipe_texture *new_tex = i < num ? texture[i] : NULL;
|
||||
if ((struct pipe_texture *) cell->texture[i] != new_tex) {
|
||||
pipe_texture_reference((struct pipe_texture **) &cell->texture[i],
|
||||
new_tex);
|
||||
changed |= (1 << i);
|
||||
}
|
||||
}
|
||||
cell->num_textures = num;
|
||||
|
||||
cell->dirty |= CELL_NEW_TEXTURE;
|
||||
if (changed) {
|
||||
cell->dirty |= CELL_NEW_TEXTURE;
|
||||
cell->dirty_textures |= changed;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -201,44 +201,50 @@ cell_emit_state(struct cell_context *cell)
|
||||
if (cell->dirty & CELL_NEW_SAMPLER) {
|
||||
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_samplers & (1 << 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];
|
||||
}
|
||||
}
|
||||
}
|
||||
cell->dirty_samplers = 0x0;
|
||||
}
|
||||
|
||||
if (cell->dirty & CELL_NEW_TEXTURE) {
|
||||
uint i;
|
||||
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]) {
|
||||
uint level;
|
||||
for (level = 0; level < CELL_MAX_TEXTURE_LEVELS; level++) {
|
||||
texture->start[level] = cell->texture[i]->tiled_data[level];
|
||||
texture->width[level] = cell->texture[i]->base.width[level];
|
||||
texture->height[level] = cell->texture[i]->base.height[level];
|
||||
texture->depth[level] = cell->texture[i]->base.depth[level];
|
||||
if (cell->dirty_textures & (1 << 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]) {
|
||||
uint level;
|
||||
for (level = 0; level < CELL_MAX_TEXTURE_LEVELS; level++) {
|
||||
texture->start[level] = cell->texture[i]->tiled_data[level];
|
||||
texture->width[level] = cell->texture[i]->base.width[level];
|
||||
texture->height[level] = cell->texture[i]->base.height[level];
|
||||
texture->depth[level] = cell->texture[i]->base.depth[level];
|
||||
}
|
||||
texture->target = cell->texture[i]->base.target;
|
||||
}
|
||||
texture->target = cell->texture[i]->base.target;
|
||||
}
|
||||
else {
|
||||
uint level;
|
||||
for (level = 0; level < CELL_MAX_TEXTURE_LEVELS; level++) {
|
||||
texture->start[level] = NULL;
|
||||
texture->width[level] = 0;
|
||||
texture->height[level] = 0;
|
||||
texture->depth[level] = 0;
|
||||
else {
|
||||
uint level;
|
||||
for (level = 0; level < CELL_MAX_TEXTURE_LEVELS; level++) {
|
||||
texture->start[level] = NULL;
|
||||
texture->width[level] = 0;
|
||||
texture->height[level] = 0;
|
||||
texture->depth[level] = 0;
|
||||
}
|
||||
texture->target = 0;
|
||||
}
|
||||
texture->target = 0;
|
||||
}
|
||||
}
|
||||
cell->dirty_textures = 0x0;
|
||||
}
|
||||
|
||||
if (cell->dirty & CELL_NEW_VERTEX_INFO) {
|
||||
|
||||
Reference in New Issue
Block a user