On 12/12/2013 02:49 AM, Pi Tabred wrote:
On 12.12.2013 01:39, Brian Paul wrote:On 12/11/2013 02:55 PM, Pi Tabred wrote:- _mesa_buffer_clear_subdata: default callback for dd function table - _mesa_ClearBufferData: API function - _mesa_ClearBufferSubData: API function - buffer_object_format_good: helper function, check if the internalformat, format and type parameter are legal - buffer_object_convert_clear: helper function, convert the supplied data to the desired internalformat and clear the buffer by calling the callback for dd_function_table::ClearbufferSubData --- src/mesa/main/bufferobj.c | 250 ++++++++++++++++++++++++++++++++++++++++++++++ src/mesa/main/bufferobj.h | 4 + 2 files changed, 254 insertions(+) diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c index 0e5b705..72515ef 100644 --- a/src/mesa/main/bufferobj.c +++ b/src/mesa/main/bufferobj.c @@ -41,6 +41,9 @@ #include "fbobject.h" #include "mtypes.h" #include "texobj.h" +#include "teximage.h" +#include "glformats.h" +#include "texstore.h" #include "transformfeedback.h" #include "dispatch.h" @@ -283,6 +286,120 @@ buffer_object_subdata_range_good(struct gl_context * ctx, GLenum target, /** + * Tests the format and type parameters and sets the GL error code for + * \c glClearBufferData and \c glClearBufferSubData. + * + * \param ctx GL context. + * \param target Buffer object target on which to operate. + * \param offset Offset of the first byte of the subdata range. + * \param size Size, in bytes, of the subdata range. + * \param mappedRange If true, checks if an overlapping range is mapped. + * If false, checks if buffer is mapped. + * \param errorNoBuffer Error code if no buffer is bound to target. + * \param caller Name of calling function for recording errors. + * \return A pointer to the buffer object bound to \c target in the + * specified context or \c NULL if any of the parameter or state + * conditions are invalid.But the code below returns a gl_format, not a pointer.sorry about that, to much copy-paste.+ * + * \sa glBufferSubDataARB, glGetBufferSubDataARB, glClearBufferSubData + */ +static gl_format +buffer_object_format_good(struct gl_context *ctx, + const struct gl_buffer_object *obj, + GLenum internalformat, GLenum format, GLenum type, + const char* caller)Let's rename this function to something like "validate_buffer_clear_format".sure, I just tried to be in line with the naming of the buffer_object_subdata_range_good function+{ + gl_format internalFormatMesa;I think mesaFormat would be more concise.+ GLenum errorFormatType; + + internalFormatMesa = _mesa_validate_texbuffer_format(ctx, internalformat); + if (internalFormatMesa == MESA_FORMAT_NONE) { + _mesa_error(ctx, GL_INVALID_ENUM, + "%s(invalid internalformat)", caller); + return MESA_FORMAT_NONE; + } + + /* NOTE: not mentioned in ARB_clear_buffer_object but according to + * EXT_texture_integer there is no conversion between integer and + * non-integer formats + */ + if (_mesa_is_enum_format_signed_int(format) != + _mesa_is_format_integer_color(internalFormatMesa)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(integer vs non-integer)", caller); + return MESA_FORMAT_NONE; + } + + if (!_mesa_is_color_format(format)) { + _mesa_error(ctx, GL_INVALID_ENUM, + "%s(format is not a color format)", caller); + return MESA_FORMAT_NONE; + } + + errorFormatType = _mesa_error_check_format_and_type(ctx, format, + type); + if (errorFormatType != GL_NO_ERROR) { + _mesa_error(ctx, GL_INVALID_ENUM, + "%s(invalid format or type)", caller); + return MESA_FORMAT_NONE; + } + + return internalFormatMesa; +} + + +/** + * Converts the supplied data to the internalformat and clears the desired + * range. + * + * \param ctx GL context. + * \param offset Offset of the to be cleared range. + * \param size Size of the to be cleared range. + * \param internalformat Format to which the data is converted. + * \param sizeOfFormat Size of the internalformat in bytes. + * \param format Format of the supplied data. + * \param type Type of the supplied data. + * \param data Data which is used to clear the buffer. + * \param bufObj To be cleared buffer. + * \return A pointer to the buffer object bound to \c target in the + * specified context or \c NULL if any of the parameter or state + * conditions are invalid. + * + * \sa glClearBufferData, glClearBufferSubData + */ +static void +buffer_object_convert_clear(struct gl_context *ctx, + GLintptr offset, GLsizeiptr size, + gl_format internalformat, + unsigned int sizeOfFormat, + GLenum format, GLenum type, const GLvoid* data, + struct gl_buffer_object *bufObj) +{ + GLenum internalformatBase; + GLubyte* src; + + if (data == NULL) { + ctx->Driver.ClearBufferSubData(ctx, 0, bufObj->Size, + NULL, 0, bufObj); + return; + } + + internalformatBase = _mesa_get_format_base_format(internalformat); + + src = (GLubyte*) malloc(sizeOfFormat); + assert(src); + GLboolean success = _mesa_texstore(ctx, 1, internalformatBase, + internalformat, 0, &src, 1, 1, 1, + format, type, data, &ctx->Unpack); + assert(success); + + ctx->Driver.ClearBufferSubData(ctx, offset, size, + src, sizeOfFormat, bufObj); + free(src); +}I think this function should just convert the user's clear value to the internal representation. Then have the callers do the ctx->Driver.ClearBufferSubData() call. And since sizeOfFormat will always be <=16 bytes, we could just use a GLubyte clearValue[16] buffer instead of malloc'ing the buffer.I considered the second point but I thought that maybe there will be a GL_RGAB32D (double) format soon and then it will stop working, as opposed to this solution which is independent of new formats.
I should have suggested GLubyte[MAX_PIXEL_BYTES]; MAX_PIXEL_BYTES is defined in formats.h and will get bumped up when needed.
PS: sorry about all the little mistakes, I thought I found all in the second version.
No problem. Thanks for your persistence! -Brian _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev