extern GLboolean _mesa_validate_program_pipeline(struct gl_context* ctx, struct gl_pipeline_object *pipe, GLboolean IsBound) { unsigned i; pipe->Validated = GL_FALSE; /* Release and reset the info log. */ if (pipe->InfoLog != NULL) ralloc_free(pipe->InfoLog); pipe->InfoLog = NULL; /* Section 2.11.11 (Shader Execution), subheading "Validation," of the * OpenGL 4.1 spec says: * * "[INVALID_OPERATION] is generated by any command that transfers * vertices to the GL if: * * - A program object is active for at least one, but not all of * the shader stages that were present when the program was * linked." * * For each possible program stage, verify that the program bound to that * stage has all of its stages active. In other words, if the program * bound to the vertex stage also has a fragment shader, the fragment * shader must also be bound to the fragment stage. */ for (i = 0; i < MESA_SHADER_STAGES; i++) { if (!program_stages_all_active(pipe, pipe->CurrentProgram[i])) { goto err; } } /* Section 2.11.11 (Shader Execution), subheading "Validation," of the * OpenGL 4.1 spec says: * * "[INVALID_OPERATION] is generated by any command that transfers * vertices to the GL if: * * ... * * - One program object is active for at least two shader stages * and a second program is active for a shader stage between two * stages for which the first program was active." */ if (program_stages_interleaved_illegally(pipe)) { pipe->InfoLog = ralloc_strdup(pipe, "Program is active for multiple shader stages with an " "intervening stage provided by another program"); goto err; } /* Section 2.11.11 (Shader Execution), subheading "Validation," of the * OpenGL 4.1 spec says: * * "[INVALID_OPERATION] is generated by any command that transfers * vertices to the GL if: * * ... * * - There is an active program for tessellation control, * tessellation evaluation, or geometry stages with corresponding * executable shader, but there is no active program with * executable vertex shader." */ if (!pipe->CurrentProgram[MESA_SHADER_VERTEX] && (pipe->CurrentProgram[MESA_SHADER_GEOMETRY] || pipe->CurrentProgram[MESA_SHADER_TESS_CTRL] || pipe->CurrentProgram[MESA_SHADER_TESS_EVAL])) { pipe->InfoLog = ralloc_strdup(pipe, "Program lacks a vertex shader"); goto err; } /* Section 2.11.11 (Shader Execution), subheading "Validation," of the * OpenGL 4.1 spec says: * * "[INVALID_OPERATION] is generated by any command that transfers * vertices to the GL if: * * ... * * - There is no current program object specified by UseProgram, * there is a current program pipeline object, and the current * program for any shader stage has been relinked since being * applied to the pipeline object via UseProgramStages with the * PROGRAM_SEPARABLE parameter set to FALSE. */ for (i = 0; i < MESA_SHADER_STAGES; i++) { if (pipe->CurrentProgram[i] && !pipe->CurrentProgram[i]->SeparateShader) { pipe->InfoLog = ralloc_asprintf(pipe, "Program %d was relinked without " "PROGRAM_SEPARABLE state", pipe->CurrentProgram[i]->Name); goto err; } } /* Section 2.11.11 (Shader Execution), subheading "Validation," of the * OpenGL 4.1 spec says: * * "[INVALID_OPERATION] is generated by any command that transfers * vertices to the GL if: * * ... * * - Any two active samplers in the current program object are of * different types, but refer to the same texture image unit. * * - The number of active samplers in the program exceeds the * maximum number of texture image units allowed." */ if (!_mesa_sampler_uniforms_pipeline_are_valid(pipe)) goto err; pipe->Validated = GL_TRUE; return GL_TRUE; err: if (IsBound) _mesa_error(ctx, GL_INVALID_OPERATION, "glValidateProgramPipeline failed to validate the pipeline"); return GL_FALSE; }
extern GLboolean _mesa_validate_program_pipeline(struct gl_context* ctx, struct gl_pipeline_object *pipe, GLboolean IsBound) { unsigned i; bool program_empty = true; pipe->Validated = GL_FALSE; /* Release and reset the info log. */ if (pipe->InfoLog != NULL) ralloc_free(pipe->InfoLog); pipe->InfoLog = NULL; /* Section 2.11.11 (Shader Execution), subheading "Validation," of the * OpenGL 4.1 spec says: * * "[INVALID_OPERATION] is generated by any command that transfers * vertices to the GL if: * * - A program object is active for at least one, but not all of * the shader stages that were present when the program was * linked." * * For each possible program stage, verify that the program bound to that * stage has all of its stages active. In other words, if the program * bound to the vertex stage also has a fragment shader, the fragment * shader must also be bound to the fragment stage. */ for (i = 0; i < MESA_SHADER_STAGES; i++) { if (!program_stages_all_active(pipe, pipe->CurrentProgram[i])) { goto err; } } /* Section 2.11.11 (Shader Execution), subheading "Validation," of the * OpenGL 4.1 spec says: * * "[INVALID_OPERATION] is generated by any command that transfers * vertices to the GL if: * * ... * * - One program object is active for at least two shader stages * and a second program is active for a shader stage between two * stages for which the first program was active." */ if (program_stages_interleaved_illegally(pipe)) { pipe->InfoLog = ralloc_strdup(pipe, "Program is active for multiple shader stages with an " "intervening stage provided by another program"); goto err; } /* Section 2.11.11 (Shader Execution), subheading "Validation," of the * OpenGL 4.1 spec says: * * "[INVALID_OPERATION] is generated by any command that transfers * vertices to the GL if: * * ... * * - There is an active program for tessellation control, * tessellation evaluation, or geometry stages with corresponding * executable shader, but there is no active program with * executable vertex shader." */ if (!pipe->CurrentProgram[MESA_SHADER_VERTEX] && (pipe->CurrentProgram[MESA_SHADER_GEOMETRY] || pipe->CurrentProgram[MESA_SHADER_TESS_CTRL] || pipe->CurrentProgram[MESA_SHADER_TESS_EVAL])) { pipe->InfoLog = ralloc_strdup(pipe, "Program lacks a vertex shader"); goto err; } /* Section 2.11.11 (Shader Execution), subheading "Validation," of the * OpenGL 4.1 spec says: * * "[INVALID_OPERATION] is generated by any command that transfers * vertices to the GL if: * * ... * * - There is no current program object specified by UseProgram, * there is a current program pipeline object, and the current * program for any shader stage has been relinked since being * applied to the pipeline object via UseProgramStages with the * PROGRAM_SEPARABLE parameter set to FALSE. */ for (i = 0; i < MESA_SHADER_STAGES; i++) { if (pipe->CurrentProgram[i] && !pipe->CurrentProgram[i]->SeparateShader) { pipe->InfoLog = ralloc_asprintf(pipe, "Program %d was relinked without " "PROGRAM_SEPARABLE state", pipe->CurrentProgram[i]->Name); goto err; } } /* Section 11.1.3.11 (Validation) of the OpenGL 4.5 spec says: * * "An INVALID_OPERATION error is generated by any command that trans- * fers vertices to the GL or launches compute work if the current set * of active program objects cannot be executed, for reasons including: * * ... * * - There is no current program object specified by UseProgram, * there is a current program pipeline object, and that object is * empty (no executable code is installed for any stage). */ for (i = 0; i < MESA_SHADER_STAGES; i++) { if (pipe->CurrentProgram[i]) { program_empty = false; break; } } if (program_empty) { goto err; } /* Section 2.11.11 (Shader Execution), subheading "Validation," of the * OpenGL 4.1 spec says: * * "[INVALID_OPERATION] is generated by any command that transfers * vertices to the GL if: * * ... * * - Any two active samplers in the current program object are of * different types, but refer to the same texture image unit. * * - The number of active samplers in the program exceeds the * maximum number of texture image units allowed." */ if (!_mesa_sampler_uniforms_pipeline_are_valid(pipe)) goto err; /* Validate inputs against outputs, this cannot be done during linking * since programs have been linked separately from each other. * * From OpenGL 4.5 Core spec: * "Separable program objects may have validation failures that cannot be * detected without the complete program pipeline. Mismatched interfaces, * improper usage of program objects together, and the same * state-dependent failures can result in validation errors for such * program objects." * * OpenGL ES 3.1 specification has the same text. */ if (!_mesa_validate_pipeline_io(pipe)) goto err; pipe->Validated = GL_TRUE; return GL_TRUE; err: if (IsBound) _mesa_error(ctx, GL_INVALID_OPERATION, "glValidateProgramPipeline failed to validate the pipeline"); return GL_FALSE; }