summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth Graunke <kenneth@whitecape.org>2013-05-27 11:27:18 -0700
committerKenneth Graunke <kenneth@whitecape.org>2013-10-31 11:04:37 -0700
commitded34f65ad6bd69a4af94945527de74761a866e6 (patch)
treedc4678ef360cad66092f00d5603b6787b923d5f3
parent684958d1e7415267e8276654390ea610eefaa95f (diff)
mesa: Add a new GetTransformFeedbackVertexCount() driver hook.
DrawTransformFeedback() needs to obtain the number of vertices written to a particular stream during the last Begin/EndTransformFeedback block. The new driver hook returns exactly that information. Gallium drivers already implement this by passing the transform feedback object to the drawing function, counting the number of vertices written on the GPU, and using draw indirect. This is efficient, but doesn't always work: If vertex data comes from user arrays, then the VBO module needs to know how many vertices to upload, so we need to synchronously count. Gallium drivers are currently broken in this case. It also doesn't work if primitive restart is done in software. For normal drawing, vbo_draw_arrays() performs software primitive restart, splitting the draw call in two. vbo_draw_transform_feedback() currently doesn't because it has no idea how many vertices need to be drawn. The new driver hook gives it that information, allowing us to reuse the existing vbo_draw_arrays() code to do everything right. On Intel hardware (at least Ivybridge), using the draw indirect approach is difficult since the hardware counts primitives, rather than vertices, which requires doing some simple math. So we always use this hook. Gallium drivers will likely want to use this hook in some cases, but want to use the existing draw indirect approach where possible. Hence, I've added a flag to allow drivers to opt-in to this call. v2: Make it possible to implement this hook but only use this path when necessary (suggested by Marek). Signed-off-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Marek Olšák <marek.olsak@amd.com>
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.c2
-rw-r--r--src/mesa/main/dd.h8
-rw-r--r--src/mesa/main/mtypes.h6
-rw-r--r--src/mesa/vbo/vbo_exec_array.c10
4 files changed, 26 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index 90d9be449c1..623273c260f 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -329,6 +329,8 @@ brw_initialize_context_constants(struct brw_context *brw)
ctx->Const.MaxTransformFeedbackSeparateComponents =
BRW_MAX_SOL_BINDINGS / BRW_MAX_SOL_BUFFERS;
+ ctx->Const.AlwaysUseGetTransformFeedbackVertexCount = true;
+
if (brw->gen == 6) {
ctx->Const.MaxSamples = 4;
ctx->Const.MaxColorTextureSamples = 4;
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index 50119219906..d7c43271355 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -843,6 +843,14 @@ struct dd_function_table {
struct gl_transform_feedback_object *obj);
/**
+ * Return the number of vertices written to a stream during the last
+ * Begin/EndTransformFeedback block.
+ */
+ GLsizei (*GetTransformFeedbackVertexCount)(struct gl_context *ctx,
+ struct gl_transform_feedback_object *obj,
+ GLuint stream);
+
+ /**
* \name GL_NV_texture_barrier interface
*/
void (*TextureBarrier)(struct gl_context *ctx);
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index a1a5eb4bf13..087bc372707 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -3156,6 +3156,12 @@ struct gl_constants
*/
GLboolean PrimitiveRestartInSoftware;
+ /**
+ * Always use the GetTransformFeedbackVertexCount() driver hook, rather
+ * than passing the transform feedback object to the drawing function.
+ */
+ GLboolean AlwaysUseGetTransformFeedbackVertexCount;
+
/** GL_ARB_map_buffer_alignment */
GLuint MinMapBufferAlignment;
diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c
index 1670409d48b..f25a9dec308 100644
--- a/src/mesa/vbo/vbo_exec_array.c
+++ b/src/mesa/vbo/vbo_exec_array.c
@@ -1464,6 +1464,16 @@ vbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode,
return;
}
+ if (ctx->Driver.GetTransformFeedbackVertexCount &&
+ (ctx->Const.AlwaysUseGetTransformFeedbackVertexCount ||
+ (ctx->Const.PrimitiveRestartInSoftware &&
+ ctx->Array._PrimitiveRestart) ||
+ !vbo_all_varyings_in_vbos(exec->array.inputs))) {
+ GLsizei n = ctx->Driver.GetTransformFeedbackVertexCount(ctx, obj, stream);
+ vbo_draw_arrays(ctx, mode, 0, n, numInstances, 0);
+ return;
+ }
+
vbo_bind_arrays(ctx);
/* init most fields to zero */