diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/glsl/link_varyings.cpp | 11 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/gen6_sol.c | 2 | ||||
-rw-r--r-- | src/mesa/main/mtypes.h | 6 | ||||
-rw-r--r-- | src/mesa/main/transformfeedback.c | 36 | ||||
-rw-r--r-- | src/mesa/main/transformfeedback.h | 2 |
5 files changed, 33 insertions, 24 deletions
diff --git a/src/compiler/glsl/link_varyings.cpp b/src/compiler/glsl/link_varyings.cpp index 8aefb7e201d..cb0c8baf8aa 100644 --- a/src/compiler/glsl/link_varyings.cpp +++ b/src/compiler/glsl/link_varyings.cpp @@ -872,6 +872,11 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog, unsigned num_tfeedback_decls, tfeedback_decl *tfeedback_decls, bool has_xfb_qualifiers) { + /* Make sure MaxTransformFeedbackBuffers is less than 32 so the bitmask for + * tracking the number of buffers doesn't overflow. + */ + assert(ctx->Const.MaxTransformFeedbackBuffers < 32); + bool separate_attribs_mode = prog->TransformFeedback.BufferMode == GL_SEPARATE_ATTRIBS; @@ -904,6 +909,7 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog, num_outputs); unsigned num_buffers = 0; + unsigned buffers = 0; if (!has_xfb_qualifiers && separate_attribs_mode) { /* GL_SEPARATE_ATTRIBS */ @@ -913,6 +919,7 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog, has_xfb_qualifiers)) return false; + buffers |= 1 << num_buffers; num_buffers++; } } @@ -949,6 +956,7 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog, } else { buffer = num_buffers; } + buffers |= 1 << num_buffers; if (!tfeedback_decls[i].store(ctx, prog, &prog->LinkedTransformFeedback, @@ -956,12 +964,11 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog, has_xfb_qualifiers)) return false; } - num_buffers++; } assert(prog->LinkedTransformFeedback.NumOutputs == num_outputs); - prog->LinkedTransformFeedback.NumBuffers = num_buffers; + prog->LinkedTransformFeedback.ActiveBuffers = buffers; return true; } diff --git a/src/mesa/drivers/dri/i965/gen6_sol.c b/src/mesa/drivers/dri/i965/gen6_sol.c index 2f6eadffd2e..08d4e1b52ca 100644 --- a/src/mesa/drivers/dri/i965/gen6_sol.c +++ b/src/mesa/drivers/dri/i965/gen6_sol.c @@ -256,7 +256,7 @@ brw_begin_transform_feedback(struct gl_context *ctx, GLenum mode, * overflowing any of the buffers currently being used for feedback. */ unsigned max_index - = _mesa_compute_max_transform_feedback_vertices(xfb_obj, + = _mesa_compute_max_transform_feedback_vertices(ctx, xfb_obj, linked_xfb_info); /* Initialize the SVBI 0 register to zero and set the maximum index. */ diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index ae0c8a84dda..02e60626b4a 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1649,10 +1649,8 @@ struct gl_transform_feedback_info { unsigned NumOutputs; - /** - * Number of transform feedback buffers in use by this program. - */ - unsigned NumBuffers; + /* Bitmask of active buffer indices. */ + unsigned ActiveBuffers; struct gl_transform_feedback_output *Outputs; diff --git a/src/mesa/main/transformfeedback.c b/src/mesa/main/transformfeedback.c index f73a89f6c0f..39ba3dcd7c0 100644 --- a/src/mesa/main/transformfeedback.c +++ b/src/mesa/main/transformfeedback.c @@ -347,23 +347,25 @@ compute_transform_feedback_buffer_sizes( * enabled transform feedback buffers without overflowing any of them. */ unsigned -_mesa_compute_max_transform_feedback_vertices( +_mesa_compute_max_transform_feedback_vertices(struct gl_context *ctx, const struct gl_transform_feedback_object *obj, const struct gl_transform_feedback_info *info) { unsigned max_index = 0xffffffff; unsigned i; - for (i = 0; i < info->NumBuffers; ++i) { - unsigned stride = info->BufferStride[i]; - unsigned max_for_this_buffer; + for (i = 0; i < ctx->Const.MaxTransformFeedbackBuffers; i++) { + if ((info->ActiveBuffers >> i) & 1) { + unsigned stride = info->BufferStride[i]; + unsigned max_for_this_buffer; - /* Skip any inactive buffers, which have a stride of 0. */ - if (stride == 0) - continue; + /* Skip any inactive buffers, which have a stride of 0. */ + if (stride == 0) + continue; - max_for_this_buffer = obj->Size[i] / (4 * stride); - max_index = MIN2(max_index, max_for_this_buffer); + max_for_this_buffer = obj->Size[i] / (4 * stride); + max_index = MIN2(max_index, max_for_this_buffer); + } } return max_index; @@ -445,12 +447,14 @@ _mesa_BeginTransformFeedback(GLenum mode) return; } - for (i = 0; i < info->NumBuffers; ++i) { - if (obj->BufferNames[i] == 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glBeginTransformFeedback(binding point %d does not have " - "a buffer object bound)", i); - return; + for (i = 0; i < ctx->Const.MaxTransformFeedbackBuffers; i++) { + if ((info->ActiveBuffers >> i) & 1) { + if (obj->BufferNames[i] == 0) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glBeginTransformFeedback(binding point %d does not " + "have a buffer object bound)", i); + return; + } } } @@ -470,7 +474,7 @@ _mesa_BeginTransformFeedback(GLenum mode) * feedback. */ unsigned max_vertices - = _mesa_compute_max_transform_feedback_vertices(obj, info); + = _mesa_compute_max_transform_feedback_vertices(ctx, obj, info); obj->GlesRemainingPrims = max_vertices / vertices_per_prim; } diff --git a/src/mesa/main/transformfeedback.h b/src/mesa/main/transformfeedback.h index eb274ad6540..c83f917a532 100644 --- a/src/mesa/main/transformfeedback.h +++ b/src/mesa/main/transformfeedback.h @@ -50,7 +50,7 @@ extern void _mesa_init_transform_feedback_functions(struct dd_function_table *driver); extern unsigned -_mesa_compute_max_transform_feedback_vertices( +_mesa_compute_max_transform_feedback_vertices( struct gl_context *ctx, const struct gl_transform_feedback_object *obj, const struct gl_transform_feedback_info *info); |