[Mesa-dev] [PATCH 09/12] sso: implement BindProgramPipeline
Gregory Hainaut
gregory.hainaut at gmail.com
Fri May 3 10:44:13 PDT 2013
Test become green in piglit:
The updated ext_transform_feedback-api-errors:useprogstage_noactive useprogstage_active bind_pipeline
arb_separate_shader_object-GetProgramPipelineiv
arb_separate_shader_object-IsProgramPipeline
For the moment I reuse Driver.UseProgram but I guess it will be better to create
a UseProgramStages functions. Opinion is welcome
V2: formatting & rename
---
src/mesa/main/pipelineobj.c | 60 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/src/mesa/main/pipelineobj.c b/src/mesa/main/pipelineobj.c
index 3cdca63..2d18192 100644
--- a/src/mesa/main/pipelineobj.c
+++ b/src/mesa/main/pipelineobj.c
@@ -35,6 +35,10 @@
* DeletePipelineObject
* 2/ We probably need a UseProgramStages driver function. It would avoir to
* dirty all stages
+ * 3/ Maybe create a bind pipeline driver function to notify that all
+ * program was updated. Currently I call UseProgram with NULL because there isn't
+ * a single program
+ * 4/ When vertices need to be flushed (FLUSH_VERTICES)
*/
#include "main/glheader.h"
@@ -382,6 +386,62 @@ _mesa_ActiveShaderProgram(GLuint pipeline, GLuint program)
void GLAPIENTRY
_mesa_BindProgramPipeline(GLuint pipeline)
{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_pipeline_object *newObj = NULL;
+
+ if (ctx->_Shader->Name == pipeline)
+ return; /* rebinding the same pipeline object- no change */
+
+ /*
+ * An INVALID_OPERATION error is generated :
+ * by BindProgramPipeline if the current transform feedback object is active
+ * and not paused;
+ */
+ if (_mesa_is_xfb_active_and_unpaused(ctx)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBindProgramPipeline(transform feedback active)");
+ return;
+ }
+
+ /*
+ * Get pointer to new pipeline object (newObj)
+ */
+ if (pipeline) {
+ /* non-default pipeline object */
+ newObj = lookup_pipeline_object(ctx, pipeline);
+ if (!newObj) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glBindProgramPipeline(non-gen name)");
+ return;
+ }
+
+ /* Object is created by any Pipeline call but glGenProgramPipelines,
+ * glIsProgramPipeline and GetProgramPipelineInfoLog
+ */
+ newObj->EverBound = GL_TRUE;
+ }
+
+ /* First bind the Pipeline to pipeline binding point */
+ _mesa_reference_pipeline_object(ctx, &ctx->Pipeline.Current, newObj);
+
+ /* Spec say:
+ * if any program is bound to the context, the current pipeline object is
+ * ignored.
+ */
+ if (&ctx->Shader != ctx->_Shader) {
+ if (pipeline) {
+ /* Bound the pipeline to the current program and
+ * restore the pipeline state
+ */
+ _mesa_reference_pipeline_object(ctx, &ctx->_Shader, newObj);
+ } else {
+ /* Unbind the pipeline */
+ _mesa_reference_pipeline_object(ctx, &ctx->_Shader, ctx->Pipeline.Default);
+ }
+ FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
+ /* FIXME */
+ if (ctx->Driver.UseProgram)
+ ctx->Driver.UseProgram(ctx, NULL);
+ }
}
/**
--
1.7.10.4
More information about the mesa-dev
mailing list