From 9f1db21f287e76a9b36e0b240929aed4f59483e5 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 1 Nov 2017 14:30:13 +1000 Subject: [PATCH] st/mesa: start adding support for hw atomics atom. (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This adds a new atom that calls the new driver API to bind buffers containing hw atomics. v2: fixup bindings for sparse buffers. (mareko/nha) don't bind buffer atomics when hw atomics are enabled. use NewAtomicBuffer (mareko) Tested-By: Gert Wollny Reviewed-by: Marek Olšák Signed-off-by: Dave Airlie --- src/mesa/state_tracker/st_atom_atomicbuf.c | 38 ++++++++++++++++++-- src/mesa/state_tracker/st_atom_list.h | 2 ++ src/mesa/state_tracker/st_cb_bufferobjects.c | 2 +- src/mesa/state_tracker/st_context.c | 9 ++++- src/mesa/state_tracker/st_context.h | 1 + 5 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/mesa/state_tracker/st_atom_atomicbuf.c b/src/mesa/state_tracker/st_atom_atomicbuf.c index ee5944fe9b4..d01c227acdd 100644 --- a/src/mesa/state_tracker/st_atom_atomicbuf.c +++ b/src/mesa/state_tracker/st_atom_atomicbuf.c @@ -46,7 +46,7 @@ st_bind_atomics(struct st_context *st, struct gl_program *prog, { unsigned i; - if (!prog || !st->pipe->set_shader_buffers) + if (!prog || !st->pipe->set_shader_buffers || st->has_hw_atomics) return; for (i = 0; i < prog->sh.data->NumAtomicBuffers; i++) { @@ -63,7 +63,7 @@ st_bind_atomics(struct st_context *st, struct gl_program *prog, sb.buffer_offset = binding->Offset; sb.buffer_size = st_obj->buffer->width0 - binding->Offset; - /* AutomaticSize is FALSE if the buffer was set with BindBufferRange. + /* AutomaticSize is FALSE if the buffer was set with BindBufferRange. * Take the minimum just to be sure. */ if (!binding->AutomaticSize) @@ -128,3 +128,37 @@ st_bind_cs_atomics(struct st_context *st) st_bind_atomics(st, prog, PIPE_SHADER_COMPUTE); } + +void +st_bind_hw_atomic_buffers(struct st_context *st) +{ + struct pipe_shader_buffer buffers[PIPE_MAX_HW_ATOMIC_BUFFERS]; + int i; + + if (!st->has_hw_atomics) + return; + + for (i = 0; i < st->ctx->Const.MaxAtomicBufferBindings; i++) { + struct gl_buffer_binding *binding = &st->ctx->AtomicBufferBindings[i]; + struct st_buffer_object *st_obj = st_buffer_object(binding->BufferObject); + struct pipe_shader_buffer *sb = &buffers[i]; + + if (st_obj && st_obj->buffer) { + sb->buffer = st_obj->buffer; + sb->buffer_offset = binding->Offset; + sb->buffer_size = st_obj->buffer->width0 - binding->Offset; + + /* AutomaticSize is FALSE if the buffer was set with BindBufferRange. + * Take the minimum just to be sure. + */ + if (!binding->AutomaticSize) + sb->buffer_size = MIN2(sb->buffer_size, (unsigned) binding->Size); + } else { + sb->buffer = NULL; + sb->buffer_offset = 0; + sb->buffer_size = 0; + } + } + + st->pipe->set_hw_atomic_buffers(st->pipe, 0, st->ctx->Const.MaxAtomicBufferBindings, buffers); +} diff --git a/src/mesa/state_tracker/st_atom_list.h b/src/mesa/state_tracker/st_atom_list.h index b76854e8b60..8f50a72d00f 100644 --- a/src/mesa/state_tracker/st_atom_list.h +++ b/src/mesa/state_tracker/st_atom_list.h @@ -66,6 +66,8 @@ ST_STATE(ST_NEW_GS_SSBOS, st_bind_gs_ssbos) ST_STATE(ST_NEW_PIXEL_TRANSFER, st_update_pixel_transfer) ST_STATE(ST_NEW_TESS_STATE, st_update_tess) +ST_STATE(ST_NEW_HW_ATOMICS, st_bind_hw_atomic_buffers) + /* this must be done after the vertex program update */ ST_STATE(ST_NEW_VERTEX_ARRAYS, st_update_array) diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c index 86ebfc674b5..a9104a90095 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -348,7 +348,7 @@ bufferobj_data(struct gl_context *ctx, if (st_obj->Base.UsageHistory & USAGE_TEXTURE_BUFFER) ctx->NewDriverState |= ST_NEW_SAMPLER_VIEWS | ST_NEW_IMAGE_UNITS; if (st_obj->Base.UsageHistory & USAGE_ATOMIC_COUNTER_BUFFER) - ctx->NewDriverState |= ST_NEW_ATOMIC_BUFFER; + ctx->NewDriverState |= ctx->DriverFlags.NewAtomicBuffer; return GL_TRUE; } diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 5d8dd8b97ef..e82090b7e45 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -405,6 +405,10 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe, st->has_multi_draw_indirect = screen->get_param(screen, PIPE_CAP_MULTI_DRAW_INDIRECT); + st->has_hw_atomics = + screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT, + PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS) ? true : false; + /* GL limits and extensions */ st_init_limits(pipe->screen, &ctx->Const, &ctx->Extensions); st_init_extensions(pipe->screen, &ctx->Const, @@ -497,7 +501,10 @@ static void st_init_driver_flags(struct st_context *st) /* Shader resources */ f->NewTextureBuffer = ST_NEW_SAMPLER_VIEWS; - f->NewAtomicBuffer = ST_NEW_ATOMIC_BUFFER; + if (st->has_hw_atomics) + f->NewAtomicBuffer = ST_NEW_HW_ATOMICS; + else + f->NewAtomicBuffer = ST_NEW_ATOMIC_BUFFER; f->NewShaderStorageBuffer = ST_NEW_STORAGE_BUFFER; f->NewImageUnits = ST_NEW_IMAGE_UNITS; diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index ced915ec1b9..9f33eed8f36 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -129,6 +129,7 @@ struct st_context boolean invalidate_on_gl_viewport; boolean draw_needs_minmax_index; boolean vertex_array_out_of_memory; + boolean has_hw_atomics; /* Some state is contained in constant objects. * Other state is just parameter values. -- 2.30.2