}
/* Mark constant buffers as being read */
- for (unsigned i = 0; i < ETNA_MAX_CONST_BUF; i++) {
- resource_read(ctx, ctx->constant_buffer[PIPE_SHADER_VERTEX][i].buffer);
- resource_read(ctx, ctx->constant_buffer[PIPE_SHADER_FRAGMENT][i].buffer);
- }
+ foreach_bit(i, ctx->constant_buffer[PIPE_SHADER_VERTEX].enabled_mask)
+ resource_read(ctx, ctx->constant_buffer[PIPE_SHADER_VERTEX].cb[i].buffer);
+
+ foreach_bit(i, ctx->constant_buffer[PIPE_SHADER_FRAGMENT].enabled_mask)
+ resource_read(ctx, ctx->constant_buffer[PIPE_SHADER_FRAGMENT].cb[i].buffer);
/* Mark VBOs as being read */
foreach_bit(i, ctx->vertex_buffer.enabled_mask) {
void *mapped;
};
+struct etna_constbuf_state {
+ struct pipe_constant_buffer cb[ETNA_MAX_CONST_BUF];
+ uint32_t enabled_mask;
+};
+
struct etna_vertexbuf_state {
struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS];
struct compiled_set_vertex_buffer cvb[PIPE_MAX_ATTRIBS];
uint32_t active_sampler_views;
uint32_t dirty_sampler_views;
struct pipe_sampler_view *sampler_view[PIPE_MAX_SAMPLERS];
- struct pipe_constant_buffer constant_buffer[PIPE_SHADER_TYPES][ETNA_MAX_CONST_BUF];
+ struct etna_constbuf_state constant_buffer[PIPE_SHADER_TYPES];
struct etna_vertexbuf_state vertex_buffer;
struct etna_index_buffer index_buffer;
struct etna_shader_state shader;
if (do_uniform_flush)
etna_set_state(stream, VIVS_VS_UNIFORM_CACHE, VIVS_VS_UNIFORM_CACHE_FLUSH);
- etna_uniforms_write(ctx, ctx->shader.vs, ctx->constant_buffer[PIPE_SHADER_VERTEX]);
+ etna_uniforms_write(ctx, ctx->shader.vs, ctx->constant_buffer[PIPE_SHADER_VERTEX].cb);
if (do_uniform_flush)
etna_set_state(stream, VIVS_VS_UNIFORM_CACHE, VIVS_VS_UNIFORM_CACHE_FLUSH | VIVS_VS_UNIFORM_CACHE_PS);
- etna_uniforms_write(ctx, ctx->shader.fs, ctx->constant_buffer[PIPE_SHADER_FRAGMENT]);
+ etna_uniforms_write(ctx, ctx->shader.fs, ctx->constant_buffer[PIPE_SHADER_FRAGMENT].cb);
if (ctx->specs.halti >= 5) {
/* HALTI5 needs to be prompted to pre-fetch shaders */
etna_set_state(stream, VIVS_VS_UNIFORM_CACHE, VIVS_VS_UNIFORM_CACHE_FLUSH);
if (dirty & (uniform_dirty_bits | ctx->shader.vs->uniforms_dirty_bits))
- etna_uniforms_write(ctx, ctx->shader.vs, ctx->constant_buffer[PIPE_SHADER_VERTEX]);
+ etna_uniforms_write(ctx, ctx->shader.vs, ctx->constant_buffer[PIPE_SHADER_VERTEX].cb);
/* ideally this cache would only be flushed if there are PS uniform changes */
if (do_uniform_flush)
etna_set_state(stream, VIVS_VS_UNIFORM_CACHE, VIVS_VS_UNIFORM_CACHE_FLUSH | VIVS_VS_UNIFORM_CACHE_PS);
if (dirty & (uniform_dirty_bits | ctx->shader.fs->uniforms_dirty_bits))
- etna_uniforms_write(ctx, ctx->shader.fs, ctx->constant_buffer[PIPE_SHADER_FRAGMENT]);
+ etna_uniforms_write(ctx, ctx->shader.fs, ctx->constant_buffer[PIPE_SHADER_FRAGMENT].cb);
}
/**** End of state update ****/
#undef EMIT_STATE
const struct pipe_constant_buffer *cb)
{
struct etna_context *ctx = etna_context(pctx);
+ struct etna_constbuf_state *so = &ctx->constant_buffer[shader];
assert(index < ETNA_MAX_CONST_BUF);
- util_copy_constant_buffer(&ctx->constant_buffer[shader][index], cb);
+ util_copy_constant_buffer(&so->cb[index], cb);
/* Note that the state tracker can unbind constant buffers by
* passing NULL here. */
- if (unlikely(!cb || (!cb->buffer && !cb->user_buffer)))
+ if (unlikely(!cb || (!cb->buffer && !cb->user_buffer))) {
+ so->enabled_mask &= ~(1 << index);
return;
+ }
assert(index != 0 || cb->user_buffer != NULL);
if (!cb->buffer) {
- struct pipe_constant_buffer *cb = &ctx->constant_buffer[shader][index];
+ struct pipe_constant_buffer *cb = &so->cb[index];
u_upload_data(pctx->const_uploader, 0, cb->buffer_size, 16, cb->user_buffer, &cb->buffer_offset, &cb->buffer);
}
+ so->enabled_mask |= 1 << index;
ctx->dirty |= ETNA_DIRTY_CONSTBUF;
}