On 2015-06-03 00:01:07, Iago Toral Quiroga wrote: > --- > src/mesa/main/bufferobj.c | 142 > ++++++++++++++++++++++++++++++++++++++++++++++ > src/mesa/main/mtypes.h | 7 +++ > 2 files changed, 149 insertions(+) > > diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c > index 0e762df..c8b29a7 100644 > --- a/src/mesa/main/bufferobj.c > +++ b/src/mesa/main/bufferobj.c > @@ -3034,6 +3034,33 @@ set_ubo_binding(struct gl_context *ctx, > } > > /** > + * Binds a buffer object to a shader storage buffer binding point. > + * > + * The caller is responsible for flushing vertices and updating > + * NewDriverState. > + */ > +static void > +set_ssbo_binding(struct gl_context *ctx, > + struct gl_shader_storage_buffer_binding *binding, > + struct gl_buffer_object *bufObj, > + GLintptr offset, > + GLsizeiptr size, > + GLboolean autoSize) > +{ > + _mesa_reference_buffer_object(ctx, &binding->BufferObject, bufObj); > + > + binding->Offset = offset; > + binding->Size = size; > + binding->AutomaticSize = autoSize; > + > + /* If this is a real buffer object, mark it has having been used > + * at some point as a SSBO. > + */ > + if (size >= 0) > + bufObj->UsageHistory |= USAGE_SHADER_STORAGE_BUFFER; > +} > + > +/** > * Binds a buffer object to a uniform buffer binding point. > * > * Unlike set_ubo_binding(), this function also flushes vertices > @@ -3254,6 +3281,35 @@ error_check_bind_uniform_buffers(struct gl_context > *ctx, > return true; > } > > +static bool > +error_check_bind_shader_storage_buffers(struct gl_context *ctx, > + GLuint first, GLsizei count, > + const char *caller) > +{ > + if (!ctx->Extensions.ARB_shader_storage_buffer_object) { > + _mesa_error(ctx, GL_INVALID_ENUM, > + "%s(target=GL_SHADER_STORAGE_BUFFER)", caller); > + return false; > + } > + > + /* The ARB_multi_bind_spec says: > + * > + * "An INVALID_OPERATION error is generated if <first> + <count> is > + * greater than the number of target-specific indexed binding points, > + * as described in section 6.7.1." > + */ > + if (first + count > ctx->Const.MaxShaderStorageBufferBindings) { > + _mesa_error(ctx, GL_INVALID_OPERATION, > + "%s(first=%u + count=%d > the value of " > + "GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS=%u)", > + caller, first, count, > + ctx->Const.MaxShaderStorageBufferBindings); > + return false; > + } > + > + return true; > +} > + > /** > * Unbind all uniform buffers in the range > * <first> through <first>+<count>-1 > @@ -3269,6 +3325,22 @@ unbind_uniform_buffers(struct gl_context *ctx, GLuint > first, GLsizei count) > bufObj, -1, -1, GL_TRUE); > } > > +/** > + * Unbind all shader storage buffers in the range > + * <first> through <first>+<count>-1 > + */ > +static void > +unbind_shader_storage_buffers(struct gl_context *ctx, GLuint first, > + GLsizei count) > +{ > + struct gl_buffer_object *bufObj = ctx->Shared->NullBufferObj; > + GLint i; > + > + for (i = 0; i < count; i++) > + set_ssbo_binding(ctx, &ctx->ShaderStorageBufferBindings[first + i], > + bufObj, -1, -1, GL_TRUE); > +} > + > static void > bind_uniform_buffers_base(struct gl_context *ctx, GLuint first, GLsizei > count, > const GLuint *buffers) > @@ -3336,6 +3408,73 @@ bind_uniform_buffers_base(struct gl_context *ctx, > GLuint first, GLsizei count, > } > > static void > +bind_shader_storage_buffers_base(struct gl_context *ctx, GLuint first, > + GLsizei count,const GLuint *buffers)
space before const Reviewed-by: Jordan Justen <jordan.l.jus...@intel.com> > +{ > + GLint i; > + > + if (!error_check_bind_shader_storage_buffers(ctx, first, count, > + "glBindBuffersBase")) > + return; > + > + /* Assume that at least one binding will be changed */ > + FLUSH_VERTICES(ctx, 0); > + ctx->NewDriverState |= ctx->DriverFlags.NewShaderStorageBuffer; > + > + if (!buffers) { > + /* The ARB_multi_bind spec says: > + * > + * "If <buffers> is NULL, all bindings from <first> through > + * <first>+<count>-1 are reset to their unbound (zero) state." > + */ > + unbind_shader_storage_buffers(ctx, first, count); > + return; > + } > + > + /* Note that the error semantics for multi-bind commands differ from > + * those of other GL commands. > + * > + * The Issues section in the ARB_multi_bind spec says: > + * > + * "(11) Typically, OpenGL specifies that if an error is generated by a > + * command, that command has no effect. This is somewhat > + * unfortunate for multi-bind commands, because it would require > a > + * first pass to scan the entire list of bound objects for errors > + * and then a second pass to actually perform the bindings. > + * Should we have different error semantics? > + * > + * RESOLVED: Yes. In this specification, when the parameters for > + * one of the <count> binding points are invalid, that binding point > + * is not updated and an error will be generated. However, other > + * binding points in the same command will be updated if their > + * parameters are valid and no other error occurs." > + */ > + > + _mesa_begin_bufferobj_lookups(ctx); > + > + for (i = 0; i < count; i++) { > + struct gl_shader_storage_buffer_binding *binding = > + &ctx->ShaderStorageBufferBindings[first + i]; > + struct gl_buffer_object *bufObj; > + > + if (binding->BufferObject && binding->BufferObject->Name == buffers[i]) > + bufObj = binding->BufferObject; > + else > + bufObj = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, i, > + "glBindBuffersBase"); > + > + if (bufObj) { > + if (bufObj == ctx->Shared->NullBufferObj) > + set_ssbo_binding(ctx, binding, bufObj, -1, -1, GL_TRUE); > + else > + set_ssbo_binding(ctx, binding, bufObj, 0, 0, GL_TRUE); > + } > + } > + > + _mesa_end_bufferobj_lookups(ctx); > +} > + > +static void > bind_uniform_buffers_range(struct gl_context *ctx, GLuint first, GLsizei > count, > const GLuint *buffers, > const GLintptr *offsets, const GLsizeiptr *sizes) > @@ -4043,6 +4182,9 @@ _mesa_BindBuffersBase(GLenum target, GLuint first, > GLsizei count, > case GL_UNIFORM_BUFFER: > bind_uniform_buffers_base(ctx, first, count, buffers); > return; > + case GL_SHADER_STORAGE_BUFFER: > + bind_shader_storage_buffers_base(ctx, first, count, buffers); > + return; > case GL_ATOMIC_COUNTER_BUFFER: > bind_atomic_buffers_base(ctx, first, count, buffers); > return; > diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h > index 64a8a4c..f5a1e97 100644 > --- a/src/mesa/main/mtypes.h > +++ b/src/mesa/main/mtypes.h > @@ -1461,6 +1461,7 @@ typedef enum { > USAGE_UNIFORM_BUFFER = 0x1, > USAGE_TEXTURE_BUFFER = 0x2, > USAGE_ATOMIC_COUNTER_BUFFER = 0x4, > + USAGE_SHADER_STORAGE_BUFFER = 0x8, > } gl_buffer_usage; > > > @@ -4000,6 +4001,12 @@ struct gl_driver_flags > */ > uint64_t NewUniformBuffer; > > + /** > + * gl_context::ShaderStorageBufferBindings > + * gl_shader_program::ShaderStorageBlocks > + */ > + uint64_t NewShaderStorageBuffer; > + > uint64_t NewTextureBuffer; > > /** > -- > 1.9.1 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev