etnaviv: add etna_constbuf_state object

With this new state object we keep track of enabled pipe_constant_buffer
and only mark them as read when needed.

Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com>
Reviewed-by: Jonathan Marek <jonathan@marek.ca>
Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4088>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4088>
This commit is contained in:
Christian Gmeiner 2020-02-14 19:55:24 +01:00
parent 9f5802ad3e
commit 74e4cda64b
4 changed files with 22 additions and 12 deletions

View file

@ -288,10 +288,11 @@ etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
}
/* 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) {

View file

@ -73,6 +73,11 @@ struct etna_transfer {
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];
@ -164,7 +169,7 @@ struct etna_context {
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;

View file

@ -669,12 +669,12 @@ etna_emit_state(struct etna_context *ctx)
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 */
@ -688,14 +688,14 @@ etna_emit_state(struct etna_context *ctx)
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

View file

@ -82,23 +82,27 @@ etna_set_constant_buffer(struct pipe_context *pctx,
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;
}