summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Hainaut <gregory.hainaut@gmail.com>2013-06-28 17:59:55 -0700
committerIan Romanick <ian.d.romanick@intel.com>2014-03-25 10:25:25 -0700
commit78578b759943cb198d34eedc00b3408c1599f6ec (patch)
treef08e18dfde08ce81b001600c8f3b0cbaed4367e5
parent4caa9db71ce05dc2cc86177ca42655c2011fbe4a (diff)
mesa/sso: Implement _mesa_UseProgramStages
Now arb_separate_shader_object-GetProgramPipelineiv should pass. V3 (idr): * Change spec references to core OpenGL versions instead of issues in the extension spec. * Split out from previous uber patch. v4 (idr): Use _mesa_has_geometry_shaders in _mesa_UseProgramStages to detect availability of geometry shaders. v5 (idr): Whitespace cleanup, use _mesa_lookup_shader_program_err instead of open-coding it again, and update some comments at the end of _mesa_UseProgramStages. All suggested by Eric. Reviewed-by: Ian Romanick <ian.d.romanick@intel.com> Reviewed-by: Eric Anholt <eric@anholt.net>
-rw-r--r--src/mesa/main/pipelineobj.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/src/mesa/main/pipelineobj.c b/src/mesa/main/pipelineobj.c
index 849c7818d1f..b639e9bc913 100644
--- a/src/mesa/main/pipelineobj.c
+++ b/src/mesa/main/pipelineobj.c
@@ -222,6 +222,108 @@ _mesa_reference_pipeline_object_(struct gl_context *ctx,
void GLAPIENTRY
_mesa_UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
{
+ GET_CURRENT_CONTEXT(ctx);
+
+ struct gl_pipeline_object *pipe = lookup_pipeline_object(ctx, pipeline);
+ struct gl_shader_program *shProg = NULL;
+
+ if (!pipe) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glUseProgramStages(pipeline)");
+ return;
+ }
+
+ /* Object is created by any Pipeline call but glGenProgramPipelines,
+ * glIsProgramPipeline and GetProgramPipelineInfoLog
+ */
+ pipe->EverBound = GL_TRUE;
+
+ /* Section 2.11.4 (Program Pipeline Objects) of the OpenGL 4.1 spec says:
+ *
+ * "If stages is not the special value ALL_SHADER_BITS, and has a bit
+ * set that is not recognized, the error INVALID_VALUE is generated."
+ *
+ * NOT YET SUPPORTED:
+ * GL_TESS_CONTROL_SHADER_BIT
+ * GL_TESS_EVALUATION_SHADER_BIT
+ */
+ GLbitfield any_valid_stages = GL_VERTEX_SHADER_BIT | GL_FRAGMENT_SHADER_BIT;
+ if (_mesa_has_geometry_shaders(ctx))
+ any_valid_stages |= GL_GEOMETRY_SHADER_BIT;
+
+ if (stages != GL_ALL_SHADER_BITS && (stages & ~any_valid_stages) != 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glUseProgramStages(Stages)");
+ return;
+ }
+
+ /* Section 2.17.2 (Transform Feedback Primitive Capture) of the OpenGL 4.1
+ * spec says:
+ *
+ * "The error INVALID_OPERATION is generated:
+ *
+ * ...
+ *
+ * - by UseProgramStages if the program pipeline object it refers
+ * to is current and the current transform feedback object is
+ * active and not paused;
+ */
+ if (ctx->_Shader == pipe) {
+ if (_mesa_is_xfb_active_and_unpaused(ctx)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glUseProgramStages(transform feedback active)");
+ return;
+ }
+ }
+
+ if (program) {
+ shProg = _mesa_lookup_shader_program_err(ctx, program,
+ "glUseProgramStages");
+ if (shProg == NULL)
+ return;
+
+ /* Section 2.11.4 (Program Pipeline Objects) of the OpenGL 4.1 spec
+ * says:
+ *
+ * "If the program object named by program was linked without the
+ * PROGRAM_SEPARABLE parameter set, or was not linked successfully,
+ * the error INVALID_OPERATION is generated and the corresponding
+ * shader stages in the pipeline program pipeline object are not
+ * modified."
+ */
+ if (!shProg->LinkStatus) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glUseProgramStages(program not linked)");
+ return;
+ }
+
+ if (!shProg->SeparateShader) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glUseProgramStages(program wasn't linked with the "
+ "PROGRAM_SEPARABLE flag)");
+ return;
+ }
+ }
+
+ /* Enable individual stages from the program as requested by the
+ * application. If there is no shader for a requested stage in the
+ * program, _mesa_use_shader_program will enable fixed-function processing
+ * as dictated by the spec.
+ *
+ * Section 2.11.4 (Program Pipeline Objects) of the OpenGL 4.1 spec
+ * says:
+ *
+ * "If UseProgramStages is called with program set to zero or with a
+ * program object that contains no executable code for the given
+ * stages, it is as if the pipeline object has no programmable stage
+ * configured for the indicated shader stages."
+ */
+ if ((stages & GL_VERTEX_SHADER_BIT) != 0)
+ _mesa_use_shader_program(ctx, GL_VERTEX_SHADER, shProg, pipe);
+
+ if ((stages & GL_FRAGMENT_SHADER_BIT) != 0)
+ _mesa_use_shader_program(ctx, GL_FRAGMENT_SHADER, shProg, pipe);
+
+ if ((stages & GL_GEOMETRY_SHADER_BIT) != 0)
+ _mesa_use_shader_program(ctx, GL_GEOMETRY_SHADER, shProg, pipe);
}
/**