main: Added entry point for glTransformFeedbackBufferBase
v2: Review from Laura Ekstrand - give more helpful error messages - factor the lookup code for the xfb and objBuf - replace some already-existing tabs with spaces - add comments to explain the cases where xfb == 0 or buffer == 0 - fix the condition for binding the transform buffer or not v3: Review from Laura Ekstrand - rename _mesa_lookup_bufferobj_err to _mesa_lookup_transform_feedback_bufferobj_err and make it static to avoid a future conflict - make _mesa_lookup_transform_feedback_object_err static v4: Review from Laura Ekstrand - add the pdf page number when quoting the spec - rename some of the symbols to follow the public/private conventions v5: Review from Laura Ekstrand - properly rename some of the symbols to follow the public/private conventions - fix some alignments - add quotes around a spec citation - add back a newline I accidentally deleted - add spaces around the ternary operator usages Signed-off-by: Martin Peres <martin.peres@linux.intel.com> Reviewed-by: Laura Ekstrand <laura@jlekstrand.net>
This commit is contained in:
parent
c86cb2da25
commit
a5d165afed
|
@ -14,6 +14,12 @@
|
|||
<param name="ids" type="GLuint *" />
|
||||
</function>
|
||||
|
||||
<function name="TransformFeedbackBufferBase" offset="assign">
|
||||
<param name="xfb" type="GLuint" />
|
||||
<param name="index" type="GLuint" />
|
||||
<param name="buffer" type="GLuint" />
|
||||
</function>
|
||||
|
||||
<!-- Buffer object functions -->
|
||||
|
||||
<function name="CreateBuffers" offset="assign">
|
||||
|
|
|
@ -3885,8 +3885,9 @@ _mesa_BindBufferRange(GLenum target, GLuint index,
|
|||
|
||||
switch (target) {
|
||||
case GL_TRANSFORM_FEEDBACK_BUFFER:
|
||||
_mesa_bind_buffer_range_transform_feedback(ctx, index, bufObj,
|
||||
offset, size);
|
||||
_mesa_bind_buffer_range_transform_feedback(ctx,
|
||||
ctx->TransformFeedback.CurrentObject,
|
||||
index, bufObj, offset, size);
|
||||
return;
|
||||
case GL_UNIFORM_BUFFER:
|
||||
bind_buffer_range_uniform_buffer(ctx, index, bufObj, offset, size);
|
||||
|
@ -3950,7 +3951,9 @@ _mesa_BindBufferBase(GLenum target, GLuint index, GLuint buffer)
|
|||
|
||||
switch (target) {
|
||||
case GL_TRANSFORM_FEEDBACK_BUFFER:
|
||||
_mesa_bind_buffer_base_transform_feedback(ctx, index, bufObj);
|
||||
_mesa_bind_buffer_base_transform_feedback(ctx,
|
||||
ctx->TransformFeedback.CurrentObject,
|
||||
index, bufObj, false);
|
||||
return;
|
||||
case GL_UNIFORM_BUFFER:
|
||||
bind_buffer_base_uniform_buffer(ctx, index, bufObj);
|
||||
|
|
|
@ -923,6 +923,7 @@ const struct function gl_core_functions_possible[] = {
|
|||
|
||||
/* GL_ARB_direct_state_access */
|
||||
{ "glCreateTransformFeedbacks", 45, -1 },
|
||||
{ "glTransformFeedbackBufferBase", 45, -1 },
|
||||
{ "glCreateBuffers", 45, -1 },
|
||||
{ "glNamedBufferStorage", 45, -1 },
|
||||
{ "glNamedBufferData", 45, -1 },
|
||||
|
|
|
@ -514,22 +514,24 @@ _mesa_EndTransformFeedback(void)
|
|||
* Helper used by BindBufferRange() and BindBufferBase().
|
||||
*/
|
||||
static void
|
||||
bind_buffer_range(struct gl_context *ctx, GLuint index,
|
||||
bind_buffer_range(struct gl_context *ctx,
|
||||
struct gl_transform_feedback_object *obj,
|
||||
GLuint index,
|
||||
struct gl_buffer_object *bufObj,
|
||||
GLintptr offset, GLsizeiptr size)
|
||||
GLintptr offset, GLsizeiptr size,
|
||||
bool dsa)
|
||||
{
|
||||
struct gl_transform_feedback_object *obj =
|
||||
ctx->TransformFeedback.CurrentObject;
|
||||
|
||||
/* Note: no need to FLUSH_VERTICES or flag NewTransformFeedback, because
|
||||
* transform feedback buffers can't be changed while transform feedback is
|
||||
* active.
|
||||
*/
|
||||
|
||||
/* The general binding point */
|
||||
_mesa_reference_buffer_object(ctx,
|
||||
&ctx->TransformFeedback.CurrentBuffer,
|
||||
bufObj);
|
||||
if (!dsa) {
|
||||
/* The general binding point */
|
||||
_mesa_reference_buffer_object(ctx,
|
||||
&ctx->TransformFeedback.CurrentBuffer,
|
||||
bufObj);
|
||||
}
|
||||
|
||||
/* The per-attribute binding point */
|
||||
_mesa_set_transform_feedback_binding(ctx, obj, index, bufObj, offset, size);
|
||||
|
@ -543,15 +545,12 @@ bind_buffer_range(struct gl_context *ctx, GLuint index,
|
|||
*/
|
||||
void
|
||||
_mesa_bind_buffer_range_transform_feedback(struct gl_context *ctx,
|
||||
GLuint index,
|
||||
struct gl_buffer_object *bufObj,
|
||||
GLintptr offset,
|
||||
GLsizeiptr size)
|
||||
struct gl_transform_feedback_object *obj,
|
||||
GLuint index,
|
||||
struct gl_buffer_object *bufObj,
|
||||
GLintptr offset,
|
||||
GLsizeiptr size)
|
||||
{
|
||||
struct gl_transform_feedback_object *obj;
|
||||
|
||||
obj = ctx->TransformFeedback.CurrentObject;
|
||||
|
||||
if (obj->Active) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"glBindBufferRange(transform feedback active)");
|
||||
|
@ -559,13 +558,15 @@ _mesa_bind_buffer_range_transform_feedback(struct gl_context *ctx,
|
|||
}
|
||||
|
||||
if (index >= ctx->Const.MaxTransformFeedbackBuffers) {
|
||||
_mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(index=%d)", index);
|
||||
_mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(index=%d "
|
||||
"out of bounds)", index);
|
||||
return;
|
||||
}
|
||||
|
||||
if (size & 0x3) {
|
||||
/* must a multiple of four */
|
||||
_mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(size=%d)", (int) size);
|
||||
_mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(size=%d)",
|
||||
(int) size);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -576,38 +577,109 @@ _mesa_bind_buffer_range_transform_feedback(struct gl_context *ctx,
|
|||
return;
|
||||
}
|
||||
|
||||
bind_buffer_range(ctx, index, bufObj, offset, size);
|
||||
bind_buffer_range(ctx, obj, index, bufObj, offset, size, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specify a buffer object to receive transform feedback results.
|
||||
* As above, but start at offset = 0.
|
||||
* Called from the glBindBufferBase() function.
|
||||
* Called from the glBindBufferBase() and glTransformFeedbackBufferBase()
|
||||
* functions.
|
||||
*/
|
||||
void
|
||||
_mesa_bind_buffer_base_transform_feedback(struct gl_context *ctx,
|
||||
GLuint index,
|
||||
struct gl_buffer_object *bufObj)
|
||||
struct gl_transform_feedback_object *obj,
|
||||
GLuint index,
|
||||
struct gl_buffer_object *bufObj,
|
||||
bool dsa)
|
||||
{
|
||||
struct gl_transform_feedback_object *obj;
|
||||
|
||||
obj = ctx->TransformFeedback.CurrentObject;
|
||||
|
||||
if (obj->Active) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"glBindBufferBase(transform feedback active)");
|
||||
"%s(transform feedback active)",
|
||||
dsa ? "glTransformFeedbackBufferBase" : "glBindBufferBase");
|
||||
return;
|
||||
}
|
||||
|
||||
if (index >= ctx->Const.MaxTransformFeedbackBuffers) {
|
||||
_mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferBase(index=%d)", index);
|
||||
_mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%d out of bounds)",
|
||||
dsa ? "glTransformFeedbackBufferBase" : "glBindBufferBase",
|
||||
index);
|
||||
return;
|
||||
}
|
||||
|
||||
bind_buffer_range(ctx, index, bufObj, 0, 0);
|
||||
bind_buffer_range(ctx, obj, index, bufObj, 0, 0, dsa);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper around lookup_transform_feedback_object that throws
|
||||
* GL_INVALID_OPERATION if id is not in the hash table. After calling
|
||||
* _mesa_error, it returns NULL.
|
||||
*/
|
||||
static struct gl_transform_feedback_object *
|
||||
lookup_transform_feedback_object_err(struct gl_context *ctx,
|
||||
GLuint xfb, const char* func)
|
||||
{
|
||||
struct gl_transform_feedback_object *obj;
|
||||
|
||||
obj = _mesa_lookup_transform_feedback_object(ctx, xfb);
|
||||
if (!obj) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"%s(xfb=%u: non-generated object name)", func, xfb);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper around _mesa_lookup_bufferobj that throws GL_INVALID_VALUE if id
|
||||
* is not in the hash table. Specialised version for the
|
||||
* transform-feedback-related functions. After calling _mesa_error, it
|
||||
* returns NULL.
|
||||
*/
|
||||
static struct gl_buffer_object *
|
||||
lookup_transform_feedback_bufferobj_err(struct gl_context *ctx,
|
||||
GLuint buffer, const char* func)
|
||||
{
|
||||
struct gl_buffer_object *bufObj;
|
||||
|
||||
/* OpenGL 4.5 core profile, 13.2, pdf page 444: buffer must be zero or the
|
||||
* name of an existing buffer object.
|
||||
*/
|
||||
if (buffer == 0) {
|
||||
bufObj = ctx->Shared->NullBufferObj;
|
||||
} else {
|
||||
bufObj = _mesa_lookup_bufferobj(ctx, buffer);
|
||||
if (!bufObj) {
|
||||
_mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid buffer=%u)", func,
|
||||
buffer);
|
||||
}
|
||||
}
|
||||
|
||||
return bufObj;
|
||||
}
|
||||
|
||||
void GLAPIENTRY
|
||||
_mesa_TransformFeedbackBufferBase(GLuint xfb, GLuint index, GLuint buffer)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
struct gl_transform_feedback_object *obj;
|
||||
struct gl_buffer_object *bufObj;
|
||||
|
||||
obj = lookup_transform_feedback_object_err(ctx, xfb,
|
||||
"glTransformFeedbackBufferBase");
|
||||
if(!obj) {
|
||||
return;
|
||||
}
|
||||
|
||||
bufObj = lookup_transform_feedback_bufferobj_err(ctx, buffer,
|
||||
"glTransformFeedbackBufferBase");
|
||||
if(!bufObj) {
|
||||
return;
|
||||
}
|
||||
|
||||
_mesa_bind_buffer_base_transform_feedback(ctx, obj, index, bufObj, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a buffer object to receive transform feedback results, plus the
|
||||
|
@ -660,7 +732,7 @@ _mesa_BindBufferOffsetEXT(GLenum target, GLuint index, GLuint buffer,
|
|||
return;
|
||||
}
|
||||
|
||||
bind_buffer_range(ctx, index, bufObj, offset, 0);
|
||||
bind_buffer_range(ctx, obj, index, bufObj, offset, 0, false);
|
||||
}
|
||||
|
||||
|
||||
|
@ -817,6 +889,10 @@ _mesa_GetTransformFeedbackVarying(GLuint program, GLuint index,
|
|||
struct gl_transform_feedback_object *
|
||||
_mesa_lookup_transform_feedback_object(struct gl_context *ctx, GLuint name)
|
||||
{
|
||||
/* OpenGL 4.5 core profile, 13.2 pdf page 444: "xfb must be zero, indicating
|
||||
* the default transform feedback object, or the name of an existing
|
||||
* transform feedback object."
|
||||
*/
|
||||
if (name == 0) {
|
||||
return ctx->TransformFeedback.DefaultObject;
|
||||
}
|
||||
|
|
|
@ -65,6 +65,7 @@ _mesa_EndTransformFeedback(void);
|
|||
|
||||
extern void
|
||||
_mesa_bind_buffer_range_transform_feedback(struct gl_context *ctx,
|
||||
struct gl_transform_feedback_object *obj,
|
||||
GLuint index,
|
||||
struct gl_buffer_object *bufObj,
|
||||
GLintptr offset,
|
||||
|
@ -72,8 +73,10 @@ _mesa_bind_buffer_range_transform_feedback(struct gl_context *ctx,
|
|||
|
||||
extern void
|
||||
_mesa_bind_buffer_base_transform_feedback(struct gl_context *ctx,
|
||||
struct gl_transform_feedback_object *obj,
|
||||
GLuint index,
|
||||
struct gl_buffer_object *bufObj);
|
||||
struct gl_buffer_object *bufObj,
|
||||
bool dsa);
|
||||
|
||||
extern void GLAPIENTRY
|
||||
_mesa_BindBufferOffsetEXT(GLenum target, GLuint index, GLuint buffer,
|
||||
|
@ -144,4 +147,9 @@ _mesa_set_transform_feedback_binding(struct gl_context *ctx,
|
|||
tfObj->RequestedSize[index] = size;
|
||||
}
|
||||
|
||||
/*** GL_ARB_direct_state_access ***/
|
||||
|
||||
extern void GLAPIENTRY
|
||||
_mesa_TransformFeedbackBufferBase(GLuint xfb, GLuint index, GLuint buffer);
|
||||
|
||||
#endif /* TRANSFORM_FEEDBACK_H */
|
||||
|
|
Loading…
Reference in New Issue