diff options
author | Brian Paul <brian.paul@tungstengraphics.com> | 2008-10-16 16:51:23 -0600 |
---|---|---|
committer | Brian Paul <brian.paul@tungstengraphics.com> | 2008-10-17 14:14:23 -0600 |
commit | cb8ebc912430201683463822897f06d7d42795f2 (patch) | |
tree | a22da2cc8abc4eb477c2844888256e1f8d32f6ee | |
parent | fa7b8388066651c5cfafd4ce6461fc43c982d8c7 (diff) |
cell: more efficient state emit for textures/samplers
-rw-r--r-- | src/gallium/drivers/cell/ppu/cell_context.h | 2 | ||||
-rw-r--r-- | src/gallium/drivers/cell/ppu/cell_pipe_state.c | 41 | ||||
-rw-r--r-- | src/gallium/drivers/cell/ppu/cell_state_emit.c | 60 |
3 files changed, 58 insertions, 45 deletions
diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h index a592e728c8..ad1f4829a4 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.h +++ b/src/gallium/drivers/cell/ppu/cell_context.h @@ -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; diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index 2e3086c4fa..1615e0b356 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -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; + } } diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c index e6387382f2..effcd2a1e1 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_emit.c +++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c @@ -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) { |