diff options
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/state_tracker/st_atom_atomicbuf.c | 38 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_atom_list.h | 2 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_bufferobjects.c | 2 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_context.c | 9 | ||||
-rw-r--r-- | 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. |