pipelineobj.c revision b9abf16e
1af69d88dSmrg/* 2af69d88dSmrg * Mesa 3-D graphics library 3af69d88dSmrg * 4af69d88dSmrg * Copyright © 2013 Gregory Hainaut <gregory.hainaut@gmail.com> 5af69d88dSmrg * 6af69d88dSmrg * Permission is hereby granted, free of charge, to any person obtaining a 7af69d88dSmrg * copy of this software and associated documentation files (the "Software"), 8af69d88dSmrg * to deal in the Software without restriction, including without limitation 9af69d88dSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10af69d88dSmrg * and/or sell copies of the Software, and to permit persons to whom the 11af69d88dSmrg * Software is furnished to do so, subject to the following conditions: 12af69d88dSmrg * 13af69d88dSmrg * The above copyright notice and this permission notice (including the next 14af69d88dSmrg * paragraph) shall be included in all copies or substantial portions of the 15af69d88dSmrg * Software. 16af69d88dSmrg * 17af69d88dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18af69d88dSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19af69d88dSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21af69d88dSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22af69d88dSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 23af69d88dSmrg * IN THE SOFTWARE. 24af69d88dSmrg */ 25af69d88dSmrg 26af69d88dSmrg/** 27af69d88dSmrg * \file pipelineobj.c 28af69d88dSmrg * \author Hainaut Gregory <gregory.hainaut@gmail.com> 29af69d88dSmrg * 30af69d88dSmrg * Implementation of pipeline object related API functions. Based on 31af69d88dSmrg * GL_ARB_separate_shader_objects extension. 32af69d88dSmrg */ 33af69d88dSmrg 3401e04c3fSmrg#include <stdbool.h> 35af69d88dSmrg#include "main/glheader.h" 36af69d88dSmrg#include "main/context.h" 37af69d88dSmrg#include "main/enums.h" 38af69d88dSmrg#include "main/hash.h" 39af69d88dSmrg#include "main/mtypes.h" 40af69d88dSmrg#include "main/pipelineobj.h" 41af69d88dSmrg#include "main/shaderapi.h" 42af69d88dSmrg#include "main/shaderobj.h" 4301e04c3fSmrg#include "main/state.h" 44af69d88dSmrg#include "main/transformfeedback.h" 45af69d88dSmrg#include "main/uniforms.h" 4601e04c3fSmrg#include "compiler/glsl/glsl_parser_extras.h" 4701e04c3fSmrg#include "compiler/glsl/ir_uniform.h" 48af69d88dSmrg#include "program/program.h" 49af69d88dSmrg#include "program/prog_parameter.h" 50af69d88dSmrg#include "util/ralloc.h" 51af69d88dSmrg 52af69d88dSmrg/** 53af69d88dSmrg * Delete a pipeline object. 54af69d88dSmrg */ 55af69d88dSmrgvoid 56af69d88dSmrg_mesa_delete_pipeline_object(struct gl_context *ctx, 57af69d88dSmrg struct gl_pipeline_object *obj) 58af69d88dSmrg{ 59af69d88dSmrg unsigned i; 60af69d88dSmrg 6101e04c3fSmrg for (i = 0; i < MESA_SHADER_STAGES; i++) { 6201e04c3fSmrg _mesa_reference_program(ctx, &obj->CurrentProgram[i], NULL); 6301e04c3fSmrg _mesa_reference_shader_program(ctx, &obj->ReferencedPrograms[i], NULL); 6401e04c3fSmrg } 65af69d88dSmrg 66af69d88dSmrg _mesa_reference_shader_program(ctx, &obj->ActiveProgram, NULL); 6701e04c3fSmrg free(obj->Label); 68af69d88dSmrg ralloc_free(obj); 69af69d88dSmrg} 70af69d88dSmrg 71af69d88dSmrg/** 72af69d88dSmrg * Allocate and initialize a new pipeline object. 73af69d88dSmrg */ 74af69d88dSmrgstatic struct gl_pipeline_object * 75af69d88dSmrg_mesa_new_pipeline_object(struct gl_context *ctx, GLuint name) 76af69d88dSmrg{ 77af69d88dSmrg struct gl_pipeline_object *obj = rzalloc(NULL, struct gl_pipeline_object); 78af69d88dSmrg if (obj) { 79af69d88dSmrg obj->Name = name; 80af69d88dSmrg obj->RefCount = 1; 81af69d88dSmrg obj->Flags = _mesa_get_shader_flags(); 82af69d88dSmrg obj->InfoLog = NULL; 83af69d88dSmrg } 84af69d88dSmrg 85af69d88dSmrg return obj; 86af69d88dSmrg} 87af69d88dSmrg 88af69d88dSmrg/** 89af69d88dSmrg * Initialize pipeline object state for given context. 90af69d88dSmrg */ 91af69d88dSmrgvoid 92af69d88dSmrg_mesa_init_pipeline(struct gl_context *ctx) 93af69d88dSmrg{ 94af69d88dSmrg ctx->Pipeline.Objects = _mesa_NewHashTable(); 95af69d88dSmrg 96af69d88dSmrg ctx->Pipeline.Current = NULL; 97af69d88dSmrg 98af69d88dSmrg /* Install a default Pipeline */ 99af69d88dSmrg ctx->Pipeline.Default = _mesa_new_pipeline_object(ctx, 0); 100af69d88dSmrg _mesa_reference_pipeline_object(ctx, &ctx->_Shader, ctx->Pipeline.Default); 101af69d88dSmrg} 102af69d88dSmrg 103af69d88dSmrg 104af69d88dSmrg/** 105af69d88dSmrg * Callback for deleting a pipeline object. Called by _mesa_HashDeleteAll(). 106af69d88dSmrg */ 107af69d88dSmrgstatic void 10801e04c3fSmrgdelete_pipelineobj_cb(UNUSED GLuint id, void *data, void *userData) 109af69d88dSmrg{ 110af69d88dSmrg struct gl_pipeline_object *obj = (struct gl_pipeline_object *) data; 111af69d88dSmrg struct gl_context *ctx = (struct gl_context *) userData; 112af69d88dSmrg _mesa_delete_pipeline_object(ctx, obj); 113af69d88dSmrg} 114af69d88dSmrg 115af69d88dSmrg 116af69d88dSmrg/** 117af69d88dSmrg * Free pipeline state for given context. 118af69d88dSmrg */ 119af69d88dSmrgvoid 120af69d88dSmrg_mesa_free_pipeline_data(struct gl_context *ctx) 121af69d88dSmrg{ 122af69d88dSmrg _mesa_reference_pipeline_object(ctx, &ctx->_Shader, NULL); 123af69d88dSmrg 124af69d88dSmrg _mesa_HashDeleteAll(ctx->Pipeline.Objects, delete_pipelineobj_cb, ctx); 125af69d88dSmrg _mesa_DeleteHashTable(ctx->Pipeline.Objects); 126af69d88dSmrg 127af69d88dSmrg _mesa_delete_pipeline_object(ctx, ctx->Pipeline.Default); 128af69d88dSmrg} 129af69d88dSmrg 130af69d88dSmrg/** 131af69d88dSmrg * Look up the pipeline object for the given ID. 132af69d88dSmrg * 133af69d88dSmrg * \returns 134af69d88dSmrg * Either a pointer to the pipeline object with the specified ID or \c NULL for 135af69d88dSmrg * a non-existent ID. The spec defines ID 0 as being technically 136af69d88dSmrg * non-existent. 137af69d88dSmrg */ 13801e04c3fSmrgstruct gl_pipeline_object * 13901e04c3fSmrg_mesa_lookup_pipeline_object(struct gl_context *ctx, GLuint id) 140af69d88dSmrg{ 141af69d88dSmrg if (id == 0) 142af69d88dSmrg return NULL; 143af69d88dSmrg else 144af69d88dSmrg return (struct gl_pipeline_object *) 14501e04c3fSmrg _mesa_HashLookupLocked(ctx->Pipeline.Objects, id); 146af69d88dSmrg} 147af69d88dSmrg 148af69d88dSmrg/** 149af69d88dSmrg * Add the given pipeline object to the pipeline object pool. 150af69d88dSmrg */ 151af69d88dSmrgstatic void 152af69d88dSmrgsave_pipeline_object(struct gl_context *ctx, struct gl_pipeline_object *obj) 153af69d88dSmrg{ 154af69d88dSmrg if (obj->Name > 0) { 15501e04c3fSmrg _mesa_HashInsertLocked(ctx->Pipeline.Objects, obj->Name, obj); 156af69d88dSmrg } 157af69d88dSmrg} 158af69d88dSmrg 159af69d88dSmrg/** 160af69d88dSmrg * Remove the given pipeline object from the pipeline object pool. 161af69d88dSmrg * Do not deallocate the pipeline object though. 162af69d88dSmrg */ 163af69d88dSmrgstatic void 164af69d88dSmrgremove_pipeline_object(struct gl_context *ctx, struct gl_pipeline_object *obj) 165af69d88dSmrg{ 166af69d88dSmrg if (obj->Name > 0) { 16701e04c3fSmrg _mesa_HashRemoveLocked(ctx->Pipeline.Objects, obj->Name); 168af69d88dSmrg } 169af69d88dSmrg} 170af69d88dSmrg 171af69d88dSmrg/** 172af69d88dSmrg * Set ptr to obj w/ reference counting. 173af69d88dSmrg * Note: this should only be called from the _mesa_reference_pipeline_object() 174af69d88dSmrg * inline function. 175af69d88dSmrg */ 176af69d88dSmrgvoid 177af69d88dSmrg_mesa_reference_pipeline_object_(struct gl_context *ctx, 178af69d88dSmrg struct gl_pipeline_object **ptr, 179af69d88dSmrg struct gl_pipeline_object *obj) 180af69d88dSmrg{ 181af69d88dSmrg assert(*ptr != obj); 182af69d88dSmrg 183af69d88dSmrg if (*ptr) { 184af69d88dSmrg /* Unreference the old pipeline object */ 185af69d88dSmrg struct gl_pipeline_object *oldObj = *ptr; 186af69d88dSmrg 18701e04c3fSmrg assert(oldObj->RefCount > 0); 188af69d88dSmrg oldObj->RefCount--; 189af69d88dSmrg 19001e04c3fSmrg if (oldObj->RefCount == 0) { 191af69d88dSmrg _mesa_delete_pipeline_object(ctx, oldObj); 192af69d88dSmrg } 193af69d88dSmrg 194af69d88dSmrg *ptr = NULL; 195af69d88dSmrg } 19601e04c3fSmrg assert(!*ptr); 197af69d88dSmrg 198af69d88dSmrg if (obj) { 199af69d88dSmrg /* reference new pipeline object */ 20001e04c3fSmrg assert(obj->RefCount > 0); 20101e04c3fSmrg 20201e04c3fSmrg obj->RefCount++; 20301e04c3fSmrg *ptr = obj; 204af69d88dSmrg } 205af69d88dSmrg} 206af69d88dSmrg 20701e04c3fSmrgstatic void 20801e04c3fSmrguse_program_stage(struct gl_context *ctx, GLenum type, 20901e04c3fSmrg struct gl_shader_program *shProg, 21001e04c3fSmrg struct gl_pipeline_object *pipe) { 21101e04c3fSmrg gl_shader_stage stage = _mesa_shader_enum_to_shader_stage(type); 21201e04c3fSmrg struct gl_program *prog = NULL; 21301e04c3fSmrg if (shProg && shProg->_LinkedShaders[stage]) 21401e04c3fSmrg prog = shProg->_LinkedShaders[stage]->Program; 21501e04c3fSmrg 21601e04c3fSmrg _mesa_use_program(ctx, stage, shProg, prog, pipe); 21701e04c3fSmrg} 21801e04c3fSmrg 21901e04c3fSmrgstatic void 22001e04c3fSmrguse_program_stages(struct gl_context *ctx, struct gl_shader_program *shProg, 22101e04c3fSmrg GLbitfield stages, struct gl_pipeline_object *pipe) { 22201e04c3fSmrg 22301e04c3fSmrg /* Enable individual stages from the program as requested by the 22401e04c3fSmrg * application. If there is no shader for a requested stage in the 22501e04c3fSmrg * program, _mesa_use_shader_program will enable fixed-function processing 22601e04c3fSmrg * as dictated by the spec. 22701e04c3fSmrg * 22801e04c3fSmrg * Section 2.11.4 (Program Pipeline Objects) of the OpenGL 4.1 spec 22901e04c3fSmrg * says: 23001e04c3fSmrg * 23101e04c3fSmrg * "If UseProgramStages is called with program set to zero or with a 23201e04c3fSmrg * program object that contains no executable code for the given 23301e04c3fSmrg * stages, it is as if the pipeline object has no programmable stage 23401e04c3fSmrg * configured for the indicated shader stages." 23501e04c3fSmrg */ 23601e04c3fSmrg if ((stages & GL_VERTEX_SHADER_BIT) != 0) 23701e04c3fSmrg use_program_stage(ctx, GL_VERTEX_SHADER, shProg, pipe); 23801e04c3fSmrg 23901e04c3fSmrg if ((stages & GL_FRAGMENT_SHADER_BIT) != 0) 24001e04c3fSmrg use_program_stage(ctx, GL_FRAGMENT_SHADER, shProg, pipe); 24101e04c3fSmrg 24201e04c3fSmrg if ((stages & GL_GEOMETRY_SHADER_BIT) != 0) 24301e04c3fSmrg use_program_stage(ctx, GL_GEOMETRY_SHADER, shProg, pipe); 24401e04c3fSmrg 24501e04c3fSmrg if ((stages & GL_TESS_CONTROL_SHADER_BIT) != 0) 24601e04c3fSmrg use_program_stage(ctx, GL_TESS_CONTROL_SHADER, shProg, pipe); 24701e04c3fSmrg 24801e04c3fSmrg if ((stages & GL_TESS_EVALUATION_SHADER_BIT) != 0) 24901e04c3fSmrg use_program_stage(ctx, GL_TESS_EVALUATION_SHADER, shProg, pipe); 25001e04c3fSmrg 25101e04c3fSmrg if ((stages & GL_COMPUTE_SHADER_BIT) != 0) 25201e04c3fSmrg use_program_stage(ctx, GL_COMPUTE_SHADER, shProg, pipe); 25301e04c3fSmrg 25401e04c3fSmrg pipe->Validated = false; 25501e04c3fSmrg} 25601e04c3fSmrg 25701e04c3fSmrgvoid GLAPIENTRY 25801e04c3fSmrg_mesa_UseProgramStages_no_error(GLuint pipeline, GLbitfield stages, 25901e04c3fSmrg GLuint prog) 26001e04c3fSmrg{ 26101e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 26201e04c3fSmrg 26301e04c3fSmrg struct gl_pipeline_object *pipe = 26401e04c3fSmrg _mesa_lookup_pipeline_object(ctx, pipeline); 26501e04c3fSmrg struct gl_shader_program *shProg = NULL; 26601e04c3fSmrg 26701e04c3fSmrg if (prog) 26801e04c3fSmrg shProg = _mesa_lookup_shader_program(ctx, prog); 26901e04c3fSmrg 27001e04c3fSmrg /* Object is created by any Pipeline call but glGenProgramPipelines, 27101e04c3fSmrg * glIsProgramPipeline and GetProgramPipelineInfoLog 27201e04c3fSmrg */ 27301e04c3fSmrg pipe->EverBound = GL_TRUE; 27401e04c3fSmrg 27501e04c3fSmrg use_program_stages(ctx, shProg, stages, pipe); 27601e04c3fSmrg} 27701e04c3fSmrg 278af69d88dSmrg/** 279af69d88dSmrg * Bound program to severals stages of the pipeline 280af69d88dSmrg */ 281af69d88dSmrgvoid GLAPIENTRY 282af69d88dSmrg_mesa_UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program) 283af69d88dSmrg{ 284af69d88dSmrg GET_CURRENT_CONTEXT(ctx); 285af69d88dSmrg 28601e04c3fSmrg struct gl_pipeline_object *pipe = _mesa_lookup_pipeline_object(ctx, pipeline); 287af69d88dSmrg struct gl_shader_program *shProg = NULL; 288af69d88dSmrg GLbitfield any_valid_stages; 289af69d88dSmrg 29001e04c3fSmrg if (MESA_VERBOSE & VERBOSE_API) 29101e04c3fSmrg _mesa_debug(ctx, "glUseProgramStages(%u, 0x%x, %u)\n", 29201e04c3fSmrg pipeline, stages, program); 29301e04c3fSmrg 294af69d88dSmrg if (!pipe) { 295af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, "glUseProgramStages(pipeline)"); 296af69d88dSmrg return; 297af69d88dSmrg } 298af69d88dSmrg 299af69d88dSmrg /* Object is created by any Pipeline call but glGenProgramPipelines, 300af69d88dSmrg * glIsProgramPipeline and GetProgramPipelineInfoLog 301af69d88dSmrg */ 302af69d88dSmrg pipe->EverBound = GL_TRUE; 303af69d88dSmrg 304af69d88dSmrg /* Section 2.11.4 (Program Pipeline Objects) of the OpenGL 4.1 spec says: 305af69d88dSmrg * 306af69d88dSmrg * "If stages is not the special value ALL_SHADER_BITS, and has a bit 307af69d88dSmrg * set that is not recognized, the error INVALID_VALUE is generated." 308af69d88dSmrg */ 309af69d88dSmrg any_valid_stages = GL_VERTEX_SHADER_BIT | GL_FRAGMENT_SHADER_BIT; 310af69d88dSmrg if (_mesa_has_geometry_shaders(ctx)) 311af69d88dSmrg any_valid_stages |= GL_GEOMETRY_SHADER_BIT; 31201e04c3fSmrg if (_mesa_has_tessellation(ctx)) 31301e04c3fSmrg any_valid_stages |= GL_TESS_CONTROL_SHADER_BIT | 31401e04c3fSmrg GL_TESS_EVALUATION_SHADER_BIT; 31501e04c3fSmrg if (_mesa_has_compute_shaders(ctx)) 31601e04c3fSmrg any_valid_stages |= GL_COMPUTE_SHADER_BIT; 317af69d88dSmrg 318af69d88dSmrg if (stages != GL_ALL_SHADER_BITS && (stages & ~any_valid_stages) != 0) { 319af69d88dSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glUseProgramStages(Stages)"); 320af69d88dSmrg return; 321af69d88dSmrg } 322af69d88dSmrg 323af69d88dSmrg /* Section 2.17.2 (Transform Feedback Primitive Capture) of the OpenGL 4.1 324af69d88dSmrg * spec says: 325af69d88dSmrg * 326af69d88dSmrg * "The error INVALID_OPERATION is generated: 327af69d88dSmrg * 328af69d88dSmrg * ... 329af69d88dSmrg * 330af69d88dSmrg * - by UseProgramStages if the program pipeline object it refers 331af69d88dSmrg * to is current and the current transform feedback object is 332af69d88dSmrg * active and not paused; 333af69d88dSmrg */ 334af69d88dSmrg if (ctx->_Shader == pipe) { 335af69d88dSmrg if (_mesa_is_xfb_active_and_unpaused(ctx)) { 336af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 337af69d88dSmrg "glUseProgramStages(transform feedback active)"); 338af69d88dSmrg return; 339af69d88dSmrg } 340af69d88dSmrg } 341af69d88dSmrg 342af69d88dSmrg if (program) { 343af69d88dSmrg shProg = _mesa_lookup_shader_program_err(ctx, program, 344af69d88dSmrg "glUseProgramStages"); 345af69d88dSmrg if (shProg == NULL) 346af69d88dSmrg return; 347af69d88dSmrg 348af69d88dSmrg /* Section 2.11.4 (Program Pipeline Objects) of the OpenGL 4.1 spec 349af69d88dSmrg * says: 350af69d88dSmrg * 351af69d88dSmrg * "If the program object named by program was linked without the 352af69d88dSmrg * PROGRAM_SEPARABLE parameter set, or was not linked successfully, 353af69d88dSmrg * the error INVALID_OPERATION is generated and the corresponding 354af69d88dSmrg * shader stages in the pipeline program pipeline object are not 355af69d88dSmrg * modified." 356af69d88dSmrg */ 35701e04c3fSmrg if (!shProg->data->LinkStatus) { 358af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 359af69d88dSmrg "glUseProgramStages(program not linked)"); 360af69d88dSmrg return; 361af69d88dSmrg } 362af69d88dSmrg 363af69d88dSmrg if (!shProg->SeparateShader) { 364af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 365af69d88dSmrg "glUseProgramStages(program wasn't linked with the " 366af69d88dSmrg "PROGRAM_SEPARABLE flag)"); 367af69d88dSmrg return; 368af69d88dSmrg } 369af69d88dSmrg } 370af69d88dSmrg 37101e04c3fSmrg use_program_stages(ctx, shProg, stages, pipe); 372af69d88dSmrg} 373af69d88dSmrg 37401e04c3fSmrgstatic ALWAYS_INLINE void 37501e04c3fSmrgactive_shader_program(struct gl_context *ctx, GLuint pipeline, GLuint program, 37601e04c3fSmrg bool no_error) 377af69d88dSmrg{ 378af69d88dSmrg struct gl_shader_program *shProg = NULL; 37901e04c3fSmrg struct gl_pipeline_object *pipe = _mesa_lookup_pipeline_object(ctx, pipeline); 380af69d88dSmrg 38101e04c3fSmrg if (program) { 38201e04c3fSmrg if (no_error) { 38301e04c3fSmrg shProg = _mesa_lookup_shader_program(ctx, program); 38401e04c3fSmrg } else { 38501e04c3fSmrg shProg = _mesa_lookup_shader_program_err(ctx, program, 38601e04c3fSmrg "glActiveShaderProgram(program)"); 38701e04c3fSmrg if (shProg == NULL) 38801e04c3fSmrg return; 38901e04c3fSmrg } 390af69d88dSmrg } 391af69d88dSmrg 39201e04c3fSmrg if (!no_error && !pipe) { 393af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, "glActiveShaderProgram(pipeline)"); 394af69d88dSmrg return; 395af69d88dSmrg } 396af69d88dSmrg 397af69d88dSmrg /* Object is created by any Pipeline call but glGenProgramPipelines, 398af69d88dSmrg * glIsProgramPipeline and GetProgramPipelineInfoLog 399af69d88dSmrg */ 400af69d88dSmrg pipe->EverBound = GL_TRUE; 401af69d88dSmrg 40201e04c3fSmrg if (!no_error && shProg != NULL && !shProg->data->LinkStatus) { 403af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 404af69d88dSmrg "glActiveShaderProgram(program %u not linked)", shProg->Name); 405af69d88dSmrg return; 406af69d88dSmrg } 407af69d88dSmrg 408af69d88dSmrg _mesa_reference_shader_program(ctx, &pipe->ActiveProgram, shProg); 409af69d88dSmrg} 410af69d88dSmrg 41101e04c3fSmrgvoid GLAPIENTRY 41201e04c3fSmrg_mesa_ActiveShaderProgram_no_error(GLuint pipeline, GLuint program) 41301e04c3fSmrg{ 41401e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 41501e04c3fSmrg active_shader_program(ctx, pipeline, program, true); 41601e04c3fSmrg} 41701e04c3fSmrg 418af69d88dSmrg/** 41901e04c3fSmrg * Use the named shader program for subsequent glUniform calls (if pipeline 42001e04c3fSmrg * bound) 421af69d88dSmrg */ 422af69d88dSmrgvoid GLAPIENTRY 42301e04c3fSmrg_mesa_ActiveShaderProgram(GLuint pipeline, GLuint program) 424af69d88dSmrg{ 425af69d88dSmrg GET_CURRENT_CONTEXT(ctx); 42601e04c3fSmrg 42701e04c3fSmrg if (MESA_VERBOSE & VERBOSE_API) 42801e04c3fSmrg _mesa_debug(ctx, "glActiveShaderProgram(%u, %u)\n", pipeline, program); 42901e04c3fSmrg 43001e04c3fSmrg active_shader_program(ctx, pipeline, program, false); 43101e04c3fSmrg} 43201e04c3fSmrg 43301e04c3fSmrgstatic ALWAYS_INLINE void 43401e04c3fSmrgbind_program_pipeline(struct gl_context *ctx, GLuint pipeline, bool no_error) 43501e04c3fSmrg{ 436af69d88dSmrg struct gl_pipeline_object *newObj = NULL; 437af69d88dSmrg 43801e04c3fSmrg if (MESA_VERBOSE & VERBOSE_API) 43901e04c3fSmrg _mesa_debug(ctx, "glBindProgramPipeline(%u)\n", pipeline); 44001e04c3fSmrg 441af69d88dSmrg /* Rebinding the same pipeline object: no change. 442af69d88dSmrg */ 443af69d88dSmrg if (ctx->_Shader->Name == pipeline) 444af69d88dSmrg return; 445af69d88dSmrg 446af69d88dSmrg /* Section 2.17.2 (Transform Feedback Primitive Capture) of the OpenGL 4.1 447af69d88dSmrg * spec says: 448af69d88dSmrg * 449af69d88dSmrg * "The error INVALID_OPERATION is generated: 450af69d88dSmrg * 451af69d88dSmrg * ... 452af69d88dSmrg * 453af69d88dSmrg * - by BindProgramPipeline if the current transform feedback 454af69d88dSmrg * object is active and not paused; 455af69d88dSmrg */ 45601e04c3fSmrg if (!no_error && _mesa_is_xfb_active_and_unpaused(ctx)) { 457af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 458af69d88dSmrg "glBindProgramPipeline(transform feedback active)"); 459af69d88dSmrg return; 460af69d88dSmrg } 461af69d88dSmrg 462af69d88dSmrg /* Get pointer to new pipeline object (newObj) 463af69d88dSmrg */ 464af69d88dSmrg if (pipeline) { 465af69d88dSmrg /* non-default pipeline object */ 46601e04c3fSmrg newObj = _mesa_lookup_pipeline_object(ctx, pipeline); 46701e04c3fSmrg if (!no_error && !newObj) { 468af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 469af69d88dSmrg "glBindProgramPipeline(non-gen name)"); 470af69d88dSmrg return; 471af69d88dSmrg } 472af69d88dSmrg 473af69d88dSmrg /* Object is created by any Pipeline call but glGenProgramPipelines, 474af69d88dSmrg * glIsProgramPipeline and GetProgramPipelineInfoLog 475af69d88dSmrg */ 476af69d88dSmrg newObj->EverBound = GL_TRUE; 477af69d88dSmrg } 478af69d88dSmrg 479af69d88dSmrg _mesa_bind_pipeline(ctx, newObj); 480af69d88dSmrg} 481af69d88dSmrg 48201e04c3fSmrgvoid GLAPIENTRY 48301e04c3fSmrg_mesa_BindProgramPipeline_no_error(GLuint pipeline) 48401e04c3fSmrg{ 48501e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 48601e04c3fSmrg bind_program_pipeline(ctx, pipeline, true); 48701e04c3fSmrg} 48801e04c3fSmrg 48901e04c3fSmrg/** 49001e04c3fSmrg * Make program of the pipeline current 49101e04c3fSmrg */ 49201e04c3fSmrgvoid GLAPIENTRY 49301e04c3fSmrg_mesa_BindProgramPipeline(GLuint pipeline) 49401e04c3fSmrg{ 49501e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 49601e04c3fSmrg bind_program_pipeline(ctx, pipeline, false); 49701e04c3fSmrg} 49801e04c3fSmrg 499af69d88dSmrgvoid 500af69d88dSmrg_mesa_bind_pipeline(struct gl_context *ctx, 501af69d88dSmrg struct gl_pipeline_object *pipe) 502af69d88dSmrg{ 50301e04c3fSmrg int i; 504af69d88dSmrg /* First bind the Pipeline to pipeline binding point */ 505af69d88dSmrg _mesa_reference_pipeline_object(ctx, &ctx->Pipeline.Current, pipe); 506af69d88dSmrg 507af69d88dSmrg /* Section 2.11.3 (Program Objects) of the OpenGL 4.1 spec says: 508af69d88dSmrg * 509af69d88dSmrg * "If there is a current program object established by UseProgram, 510af69d88dSmrg * that program is considered current for all stages. Otherwise, if 511af69d88dSmrg * there is a bound program pipeline object (see section 2.11.4), the 512af69d88dSmrg * program bound to the appropriate stage of the pipeline object is 513af69d88dSmrg * considered current." 514af69d88dSmrg */ 515af69d88dSmrg if (&ctx->Shader != ctx->_Shader) { 51601e04c3fSmrg FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); 51701e04c3fSmrg 518af69d88dSmrg if (pipe != NULL) { 519af69d88dSmrg /* Bound the pipeline to the current program and 520af69d88dSmrg * restore the pipeline state 521af69d88dSmrg */ 522af69d88dSmrg _mesa_reference_pipeline_object(ctx, &ctx->_Shader, pipe); 523af69d88dSmrg } else { 524af69d88dSmrg /* Unbind the pipeline */ 525af69d88dSmrg _mesa_reference_pipeline_object(ctx, &ctx->_Shader, 526af69d88dSmrg ctx->Pipeline.Default); 527af69d88dSmrg } 528af69d88dSmrg 52901e04c3fSmrg for (i = 0; i < MESA_SHADER_STAGES; i++) { 53001e04c3fSmrg struct gl_program *prog = ctx->_Shader->CurrentProgram[i]; 53101e04c3fSmrg if (prog) { 53201e04c3fSmrg _mesa_program_init_subroutine_defaults(ctx, prog); 53301e04c3fSmrg } 53401e04c3fSmrg } 535af69d88dSmrg 53601e04c3fSmrg _mesa_update_vertex_processing_mode(ctx); 537af69d88dSmrg } 538af69d88dSmrg} 539af69d88dSmrg 540af69d88dSmrg/** 541af69d88dSmrg * Delete a set of pipeline objects. 542af69d88dSmrg * 543af69d88dSmrg * \param n Number of pipeline objects to delete. 544af69d88dSmrg * \param ids pipeline of \c n pipeline object IDs. 545af69d88dSmrg */ 546af69d88dSmrgvoid GLAPIENTRY 547af69d88dSmrg_mesa_DeleteProgramPipelines(GLsizei n, const GLuint *pipelines) 548af69d88dSmrg{ 549af69d88dSmrg GET_CURRENT_CONTEXT(ctx); 550af69d88dSmrg GLsizei i; 551af69d88dSmrg 55201e04c3fSmrg if (MESA_VERBOSE & VERBOSE_API) 55301e04c3fSmrg _mesa_debug(ctx, "glDeleteProgramPipelines(%d, %p)\n", n, pipelines); 55401e04c3fSmrg 555af69d88dSmrg if (n < 0) { 556af69d88dSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteProgramPipelines(n<0)"); 557af69d88dSmrg return; 558af69d88dSmrg } 559af69d88dSmrg 560af69d88dSmrg for (i = 0; i < n; i++) { 561af69d88dSmrg struct gl_pipeline_object *obj = 56201e04c3fSmrg _mesa_lookup_pipeline_object(ctx, pipelines[i]); 563af69d88dSmrg 564af69d88dSmrg if (obj) { 56501e04c3fSmrg assert(obj->Name == pipelines[i]); 566af69d88dSmrg 567af69d88dSmrg /* If the pipeline object is currently bound, the spec says "If an 568af69d88dSmrg * object that is currently bound is deleted, the binding for that 569af69d88dSmrg * object reverts to zero and no program pipeline object becomes 570af69d88dSmrg * current." 571af69d88dSmrg */ 572af69d88dSmrg if (obj == ctx->Pipeline.Current) { 573af69d88dSmrg _mesa_BindProgramPipeline(0); 574af69d88dSmrg } 575af69d88dSmrg 576af69d88dSmrg /* The ID is immediately freed for re-use */ 577af69d88dSmrg remove_pipeline_object(ctx, obj); 578af69d88dSmrg 579af69d88dSmrg /* Unreference the pipeline object. 580af69d88dSmrg * If refcount hits zero, the object will be deleted. 581af69d88dSmrg */ 582af69d88dSmrg _mesa_reference_pipeline_object(ctx, &obj, NULL); 583af69d88dSmrg } 584af69d88dSmrg } 585af69d88dSmrg} 586af69d88dSmrg 587af69d88dSmrg/** 588af69d88dSmrg * Generate a set of unique pipeline object IDs and store them in \c pipelines. 589af69d88dSmrg * \param n Number of IDs to generate. 590af69d88dSmrg * \param pipelines pipeline of \c n locations to store the IDs. 591af69d88dSmrg */ 59201e04c3fSmrgstatic void 59301e04c3fSmrgcreate_program_pipelines(struct gl_context *ctx, GLsizei n, GLuint *pipelines, 59401e04c3fSmrg bool dsa) 595af69d88dSmrg{ 59601e04c3fSmrg const char *func = dsa ? "glCreateProgramPipelines" : "glGenProgramPipelines"; 597af69d88dSmrg GLuint first; 598af69d88dSmrg GLint i; 599af69d88dSmrg 60001e04c3fSmrg if (!pipelines) 601af69d88dSmrg return; 602af69d88dSmrg 603af69d88dSmrg first = _mesa_HashFindFreeKeyBlock(ctx->Pipeline.Objects, n); 604af69d88dSmrg 605af69d88dSmrg for (i = 0; i < n; i++) { 606af69d88dSmrg struct gl_pipeline_object *obj; 607af69d88dSmrg GLuint name = first + i; 608af69d88dSmrg 609af69d88dSmrg obj = _mesa_new_pipeline_object(ctx, name); 610af69d88dSmrg if (!obj) { 61101e04c3fSmrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func); 612af69d88dSmrg return; 613af69d88dSmrg } 614af69d88dSmrg 61501e04c3fSmrg if (dsa) { 61601e04c3fSmrg /* make dsa-allocated objects behave like program objects */ 61701e04c3fSmrg obj->EverBound = GL_TRUE; 61801e04c3fSmrg } 61901e04c3fSmrg 620af69d88dSmrg save_pipeline_object(ctx, obj); 621af69d88dSmrg pipelines[i] = first + i; 622af69d88dSmrg } 62301e04c3fSmrg} 62401e04c3fSmrg 62501e04c3fSmrgstatic void 62601e04c3fSmrgcreate_program_pipelines_err(struct gl_context *ctx, GLsizei n, 62701e04c3fSmrg GLuint *pipelines, bool dsa) 62801e04c3fSmrg{ 62901e04c3fSmrg const char *func = dsa ? "glCreateProgramPipelines" : "glGenProgramPipelines"; 63001e04c3fSmrg 63101e04c3fSmrg if (n < 0) { 63201e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, "%s (n < 0)", func); 63301e04c3fSmrg return; 63401e04c3fSmrg } 635af69d88dSmrg 63601e04c3fSmrg create_program_pipelines(ctx, n, pipelines, dsa); 63701e04c3fSmrg} 63801e04c3fSmrg 63901e04c3fSmrgvoid GLAPIENTRY 64001e04c3fSmrg_mesa_GenProgramPipelines_no_error(GLsizei n, GLuint *pipelines) 64101e04c3fSmrg{ 64201e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 64301e04c3fSmrg create_program_pipelines(ctx, n, pipelines, false); 64401e04c3fSmrg} 64501e04c3fSmrg 64601e04c3fSmrgvoid GLAPIENTRY 64701e04c3fSmrg_mesa_GenProgramPipelines(GLsizei n, GLuint *pipelines) 64801e04c3fSmrg{ 64901e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 65001e04c3fSmrg 65101e04c3fSmrg if (MESA_VERBOSE & VERBOSE_API) 65201e04c3fSmrg _mesa_debug(ctx, "glGenProgramPipelines(%d, %p)\n", n, pipelines); 65301e04c3fSmrg 65401e04c3fSmrg create_program_pipelines_err(ctx, n, pipelines, false); 65501e04c3fSmrg} 65601e04c3fSmrg 65701e04c3fSmrgvoid GLAPIENTRY 65801e04c3fSmrg_mesa_CreateProgramPipelines_no_error(GLsizei n, GLuint *pipelines) 65901e04c3fSmrg{ 66001e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 66101e04c3fSmrg create_program_pipelines(ctx, n, pipelines, true); 66201e04c3fSmrg} 66301e04c3fSmrg 66401e04c3fSmrgvoid GLAPIENTRY 66501e04c3fSmrg_mesa_CreateProgramPipelines(GLsizei n, GLuint *pipelines) 66601e04c3fSmrg{ 66701e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 66801e04c3fSmrg 66901e04c3fSmrg if (MESA_VERBOSE & VERBOSE_API) 67001e04c3fSmrg _mesa_debug(ctx, "glCreateProgramPipelines(%d, %p)\n", n, pipelines); 67101e04c3fSmrg 67201e04c3fSmrg create_program_pipelines_err(ctx, n, pipelines, true); 673af69d88dSmrg} 674af69d88dSmrg 675af69d88dSmrg/** 676af69d88dSmrg * Determine if ID is the name of an pipeline object. 677af69d88dSmrg * 678af69d88dSmrg * \param id ID of the potential pipeline object. 679af69d88dSmrg * \return \c GL_TRUE if \c id is the name of a pipeline object, 680af69d88dSmrg * \c GL_FALSE otherwise. 681af69d88dSmrg */ 682af69d88dSmrgGLboolean GLAPIENTRY 683af69d88dSmrg_mesa_IsProgramPipeline(GLuint pipeline) 684af69d88dSmrg{ 685af69d88dSmrg GET_CURRENT_CONTEXT(ctx); 686af69d88dSmrg 68701e04c3fSmrg if (MESA_VERBOSE & VERBOSE_API) 68801e04c3fSmrg _mesa_debug(ctx, "glIsProgramPipeline(%u)\n", pipeline); 68901e04c3fSmrg 69001e04c3fSmrg struct gl_pipeline_object *obj = _mesa_lookup_pipeline_object(ctx, pipeline); 691af69d88dSmrg if (obj == NULL) 692af69d88dSmrg return GL_FALSE; 693af69d88dSmrg 694af69d88dSmrg return obj->EverBound; 695af69d88dSmrg} 696af69d88dSmrg 697af69d88dSmrg/** 698af69d88dSmrg * glGetProgramPipelineiv() - get pipeline shader state. 699af69d88dSmrg */ 700af69d88dSmrgvoid GLAPIENTRY 701af69d88dSmrg_mesa_GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params) 702af69d88dSmrg{ 703af69d88dSmrg GET_CURRENT_CONTEXT(ctx); 70401e04c3fSmrg struct gl_pipeline_object *pipe = _mesa_lookup_pipeline_object(ctx, pipeline); 70501e04c3fSmrg 70601e04c3fSmrg if (MESA_VERBOSE & VERBOSE_API) 70701e04c3fSmrg _mesa_debug(ctx, "glGetProgramPipelineiv(%u, %d, %p)\n", 70801e04c3fSmrg pipeline, pname, params); 709af69d88dSmrg 710af69d88dSmrg /* Are geometry shaders available in this context? 711af69d88dSmrg */ 712af69d88dSmrg const bool has_gs = _mesa_has_geometry_shaders(ctx); 71301e04c3fSmrg const bool has_tess = _mesa_has_tessellation(ctx); 714af69d88dSmrg 715af69d88dSmrg if (!pipe) { 716af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 717af69d88dSmrg "glGetProgramPipelineiv(pipeline)"); 718af69d88dSmrg return; 719af69d88dSmrg } 720af69d88dSmrg 721af69d88dSmrg /* Object is created by any Pipeline call but glGenProgramPipelines, 722af69d88dSmrg * glIsProgramPipeline and GetProgramPipelineInfoLog 723af69d88dSmrg */ 724af69d88dSmrg pipe->EverBound = GL_TRUE; 725af69d88dSmrg 726af69d88dSmrg switch (pname) { 727af69d88dSmrg case GL_ACTIVE_PROGRAM: 728af69d88dSmrg *params = pipe->ActiveProgram ? pipe->ActiveProgram->Name : 0; 729af69d88dSmrg return; 730af69d88dSmrg case GL_INFO_LOG_LENGTH: 73101e04c3fSmrg *params = (pipe->InfoLog && pipe->InfoLog[0] != '\0') ? 73201e04c3fSmrg strlen(pipe->InfoLog) + 1 : 0; 733af69d88dSmrg return; 734af69d88dSmrg case GL_VALIDATE_STATUS: 735af69d88dSmrg *params = pipe->Validated; 736af69d88dSmrg return; 737af69d88dSmrg case GL_VERTEX_SHADER: 738af69d88dSmrg *params = pipe->CurrentProgram[MESA_SHADER_VERTEX] 73901e04c3fSmrg ? pipe->CurrentProgram[MESA_SHADER_VERTEX]->Id : 0; 740af69d88dSmrg return; 741af69d88dSmrg case GL_TESS_EVALUATION_SHADER: 74201e04c3fSmrg if (!has_tess) 74301e04c3fSmrg break; 74401e04c3fSmrg *params = pipe->CurrentProgram[MESA_SHADER_TESS_EVAL] 74501e04c3fSmrg ? pipe->CurrentProgram[MESA_SHADER_TESS_EVAL]->Id : 0; 74601e04c3fSmrg return; 747af69d88dSmrg case GL_TESS_CONTROL_SHADER: 74801e04c3fSmrg if (!has_tess) 74901e04c3fSmrg break; 75001e04c3fSmrg *params = pipe->CurrentProgram[MESA_SHADER_TESS_CTRL] 75101e04c3fSmrg ? pipe->CurrentProgram[MESA_SHADER_TESS_CTRL]->Id : 0; 75201e04c3fSmrg return; 753af69d88dSmrg case GL_GEOMETRY_SHADER: 754af69d88dSmrg if (!has_gs) 755af69d88dSmrg break; 756af69d88dSmrg *params = pipe->CurrentProgram[MESA_SHADER_GEOMETRY] 75701e04c3fSmrg ? pipe->CurrentProgram[MESA_SHADER_GEOMETRY]->Id : 0; 758af69d88dSmrg return; 759af69d88dSmrg case GL_FRAGMENT_SHADER: 760af69d88dSmrg *params = pipe->CurrentProgram[MESA_SHADER_FRAGMENT] 76101e04c3fSmrg ? pipe->CurrentProgram[MESA_SHADER_FRAGMENT]->Id : 0; 76201e04c3fSmrg return; 76301e04c3fSmrg case GL_COMPUTE_SHADER: 76401e04c3fSmrg if (!_mesa_has_compute_shaders(ctx)) 76501e04c3fSmrg break; 76601e04c3fSmrg *params = pipe->CurrentProgram[MESA_SHADER_COMPUTE] 76701e04c3fSmrg ? pipe->CurrentProgram[MESA_SHADER_COMPUTE]->Id : 0; 768af69d88dSmrg return; 769af69d88dSmrg default: 770af69d88dSmrg break; 771af69d88dSmrg } 772af69d88dSmrg 773af69d88dSmrg _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramPipelineiv(pname=%s)", 77401e04c3fSmrg _mesa_enum_to_string(pname)); 775af69d88dSmrg} 776af69d88dSmrg 777af69d88dSmrg/** 778af69d88dSmrg * Determines whether every stage in a linked program is active in the 779af69d88dSmrg * specified pipeline. 780af69d88dSmrg */ 781af69d88dSmrgstatic bool 782af69d88dSmrgprogram_stages_all_active(struct gl_pipeline_object *pipe, 78301e04c3fSmrg const struct gl_program *prog) 784af69d88dSmrg{ 785af69d88dSmrg bool status = true; 786af69d88dSmrg 787af69d88dSmrg if (!prog) 788af69d88dSmrg return true; 789af69d88dSmrg 79001e04c3fSmrg unsigned mask = prog->sh.data->linked_stages; 79101e04c3fSmrg while (mask) { 79201e04c3fSmrg const int i = u_bit_scan(&mask); 79301e04c3fSmrg if (pipe->CurrentProgram[i]) { 79401e04c3fSmrg if (prog->Id != pipe->CurrentProgram[i]->Id) { 795af69d88dSmrg status = false; 796af69d88dSmrg } 79701e04c3fSmrg } else { 79801e04c3fSmrg status = false; 799af69d88dSmrg } 800af69d88dSmrg } 801af69d88dSmrg 802af69d88dSmrg if (!status) { 803af69d88dSmrg pipe->InfoLog = ralloc_asprintf(pipe, 804af69d88dSmrg "Program %d is not active for all " 805af69d88dSmrg "shaders that was linked", 80601e04c3fSmrg prog->Id); 807af69d88dSmrg } 808af69d88dSmrg 809af69d88dSmrg return status; 810af69d88dSmrg} 811af69d88dSmrg 81201e04c3fSmrgstatic bool 81301e04c3fSmrgprogram_stages_interleaved_illegally(const struct gl_pipeline_object *pipe) 81401e04c3fSmrg{ 81501e04c3fSmrg unsigned prev_linked_stages = 0; 81601e04c3fSmrg 81701e04c3fSmrg /* Look for programs bound to stages: A -> B -> A, with any intervening 81801e04c3fSmrg * sequence of unrelated programs or empty stages. 81901e04c3fSmrg */ 82001e04c3fSmrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 82101e04c3fSmrg struct gl_program *cur = pipe->CurrentProgram[i]; 82201e04c3fSmrg 82301e04c3fSmrg /* Empty stages anywhere in the pipe are OK. Also we can be confident 82401e04c3fSmrg * that if the linked_stages mask matches we are looking at the same 82501e04c3fSmrg * linked program because a previous validation call to 82601e04c3fSmrg * program_stages_all_active() will have already failed if two different 82701e04c3fSmrg * programs with the sames stages linked are not active for all linked 82801e04c3fSmrg * stages. 82901e04c3fSmrg */ 83001e04c3fSmrg if (!cur || cur->sh.data->linked_stages == prev_linked_stages) 83101e04c3fSmrg continue; 83201e04c3fSmrg 83301e04c3fSmrg if (prev_linked_stages) { 83401e04c3fSmrg /* We've seen an A -> B transition; look at the rest of the pipe 83501e04c3fSmrg * to see if we ever see A again. 83601e04c3fSmrg */ 83701e04c3fSmrg if (prev_linked_stages >> (i + 1)) 83801e04c3fSmrg return true; 83901e04c3fSmrg } 84001e04c3fSmrg 84101e04c3fSmrg prev_linked_stages = cur->sh.data->linked_stages; 84201e04c3fSmrg } 84301e04c3fSmrg 84401e04c3fSmrg return false; 84501e04c3fSmrg} 84601e04c3fSmrg 847af69d88dSmrgextern GLboolean 848af69d88dSmrg_mesa_validate_program_pipeline(struct gl_context* ctx, 84901e04c3fSmrg struct gl_pipeline_object *pipe) 850af69d88dSmrg{ 851af69d88dSmrg unsigned i; 85201e04c3fSmrg bool program_empty = true; 853af69d88dSmrg 854af69d88dSmrg pipe->Validated = GL_FALSE; 855af69d88dSmrg 856af69d88dSmrg /* Release and reset the info log. 857af69d88dSmrg */ 858af69d88dSmrg if (pipe->InfoLog != NULL) 859af69d88dSmrg ralloc_free(pipe->InfoLog); 860af69d88dSmrg 861af69d88dSmrg pipe->InfoLog = NULL; 862af69d88dSmrg 863af69d88dSmrg /* Section 2.11.11 (Shader Execution), subheading "Validation," of the 864af69d88dSmrg * OpenGL 4.1 spec says: 865af69d88dSmrg * 866af69d88dSmrg * "[INVALID_OPERATION] is generated by any command that transfers 867af69d88dSmrg * vertices to the GL if: 868af69d88dSmrg * 869af69d88dSmrg * - A program object is active for at least one, but not all of 870af69d88dSmrg * the shader stages that were present when the program was 871af69d88dSmrg * linked." 872af69d88dSmrg * 873af69d88dSmrg * For each possible program stage, verify that the program bound to that 874af69d88dSmrg * stage has all of its stages active. In other words, if the program 875af69d88dSmrg * bound to the vertex stage also has a fragment shader, the fragment 876af69d88dSmrg * shader must also be bound to the fragment stage. 877af69d88dSmrg */ 878af69d88dSmrg for (i = 0; i < MESA_SHADER_STAGES; i++) { 879af69d88dSmrg if (!program_stages_all_active(pipe, pipe->CurrentProgram[i])) { 88001e04c3fSmrg return GL_FALSE; 881af69d88dSmrg } 882af69d88dSmrg } 883af69d88dSmrg 884af69d88dSmrg /* Section 2.11.11 (Shader Execution), subheading "Validation," of the 885af69d88dSmrg * OpenGL 4.1 spec says: 886af69d88dSmrg * 887af69d88dSmrg * "[INVALID_OPERATION] is generated by any command that transfers 888af69d88dSmrg * vertices to the GL if: 889af69d88dSmrg * 890af69d88dSmrg * ... 891af69d88dSmrg * 892af69d88dSmrg * - One program object is active for at least two shader stages 893af69d88dSmrg * and a second program is active for a shader stage between two 894af69d88dSmrg * stages for which the first program was active." 895af69d88dSmrg */ 89601e04c3fSmrg if (program_stages_interleaved_illegally(pipe)) { 89701e04c3fSmrg pipe->InfoLog = 89801e04c3fSmrg ralloc_strdup(pipe, 89901e04c3fSmrg "Program is active for multiple shader stages with an " 90001e04c3fSmrg "intervening stage provided by another program"); 90101e04c3fSmrg return GL_FALSE; 902af69d88dSmrg } 903af69d88dSmrg 904af69d88dSmrg /* Section 2.11.11 (Shader Execution), subheading "Validation," of the 905af69d88dSmrg * OpenGL 4.1 spec says: 906af69d88dSmrg * 907af69d88dSmrg * "[INVALID_OPERATION] is generated by any command that transfers 908af69d88dSmrg * vertices to the GL if: 909af69d88dSmrg * 910af69d88dSmrg * ... 911af69d88dSmrg * 912af69d88dSmrg * - There is an active program for tessellation control, 913af69d88dSmrg * tessellation evaluation, or geometry stages with corresponding 914af69d88dSmrg * executable shader, but there is no active program with 915af69d88dSmrg * executable vertex shader." 916af69d88dSmrg */ 917af69d88dSmrg if (!pipe->CurrentProgram[MESA_SHADER_VERTEX] 91801e04c3fSmrg && (pipe->CurrentProgram[MESA_SHADER_GEOMETRY] || 91901e04c3fSmrg pipe->CurrentProgram[MESA_SHADER_TESS_CTRL] || 92001e04c3fSmrg pipe->CurrentProgram[MESA_SHADER_TESS_EVAL])) { 921af69d88dSmrg pipe->InfoLog = ralloc_strdup(pipe, "Program lacks a vertex shader"); 92201e04c3fSmrg return GL_FALSE; 923af69d88dSmrg } 924af69d88dSmrg 925af69d88dSmrg /* Section 2.11.11 (Shader Execution), subheading "Validation," of the 926af69d88dSmrg * OpenGL 4.1 spec says: 927af69d88dSmrg * 928af69d88dSmrg * "[INVALID_OPERATION] is generated by any command that transfers 929af69d88dSmrg * vertices to the GL if: 930af69d88dSmrg * 931af69d88dSmrg * ... 932af69d88dSmrg * 933af69d88dSmrg * - There is no current program object specified by UseProgram, 934af69d88dSmrg * there is a current program pipeline object, and the current 935af69d88dSmrg * program for any shader stage has been relinked since being 936af69d88dSmrg * applied to the pipeline object via UseProgramStages with the 937af69d88dSmrg * PROGRAM_SEPARABLE parameter set to FALSE. 938af69d88dSmrg */ 939af69d88dSmrg for (i = 0; i < MESA_SHADER_STAGES; i++) { 94001e04c3fSmrg if (pipe->CurrentProgram[i] && 94101e04c3fSmrg !pipe->CurrentProgram[i]->info.separate_shader) { 942af69d88dSmrg pipe->InfoLog = ralloc_asprintf(pipe, 943af69d88dSmrg "Program %d was relinked without " 944af69d88dSmrg "PROGRAM_SEPARABLE state", 94501e04c3fSmrg pipe->CurrentProgram[i]->Id); 94601e04c3fSmrg return GL_FALSE; 94701e04c3fSmrg } 94801e04c3fSmrg } 94901e04c3fSmrg 95001e04c3fSmrg /* Section 11.1.3.11 (Validation) of the OpenGL 4.5 spec says: 95101e04c3fSmrg * 95201e04c3fSmrg * "An INVALID_OPERATION error is generated by any command that trans- 95301e04c3fSmrg * fers vertices to the GL or launches compute work if the current set 95401e04c3fSmrg * of active program objects cannot be executed, for reasons including: 95501e04c3fSmrg * 95601e04c3fSmrg * ... 95701e04c3fSmrg * 95801e04c3fSmrg * - There is no current program object specified by UseProgram, 95901e04c3fSmrg * there is a current program pipeline object, and that object is 96001e04c3fSmrg * empty (no executable code is installed for any stage). 96101e04c3fSmrg */ 96201e04c3fSmrg for (i = 0; i < MESA_SHADER_STAGES; i++) { 96301e04c3fSmrg if (pipe->CurrentProgram[i]) { 96401e04c3fSmrg program_empty = false; 96501e04c3fSmrg break; 966af69d88dSmrg } 967af69d88dSmrg } 968af69d88dSmrg 96901e04c3fSmrg if (program_empty) { 97001e04c3fSmrg return GL_FALSE; 97101e04c3fSmrg } 97201e04c3fSmrg 973af69d88dSmrg /* Section 2.11.11 (Shader Execution), subheading "Validation," of the 974af69d88dSmrg * OpenGL 4.1 spec says: 975af69d88dSmrg * 976af69d88dSmrg * "[INVALID_OPERATION] is generated by any command that transfers 977af69d88dSmrg * vertices to the GL if: 978af69d88dSmrg * 979af69d88dSmrg * ... 980af69d88dSmrg * 981af69d88dSmrg * - Any two active samplers in the current program object are of 982af69d88dSmrg * different types, but refer to the same texture image unit. 983af69d88dSmrg * 984af69d88dSmrg * - The number of active samplers in the program exceeds the 985af69d88dSmrg * maximum number of texture image units allowed." 986af69d88dSmrg */ 987af69d88dSmrg if (!_mesa_sampler_uniforms_pipeline_are_valid(pipe)) 98801e04c3fSmrg return GL_FALSE; 98901e04c3fSmrg 99001e04c3fSmrg /* Validate inputs against outputs, this cannot be done during linking 99101e04c3fSmrg * since programs have been linked separately from each other. 99201e04c3fSmrg * 99301e04c3fSmrg * Section 11.1.3.11 (Validation) of the OpenGL 4.5 Core Profile spec says: 99401e04c3fSmrg * 99501e04c3fSmrg * "Separable program objects may have validation failures that cannot be 99601e04c3fSmrg * detected without the complete program pipeline. Mismatched interfaces, 99701e04c3fSmrg * improper usage of program objects together, and the same 99801e04c3fSmrg * state-dependent failures can result in validation errors for such 99901e04c3fSmrg * program objects." 100001e04c3fSmrg * 100101e04c3fSmrg * OpenGL ES 3.1 specification has the same text. 100201e04c3fSmrg * 100301e04c3fSmrg * Section 11.1.3.11 (Validation) of the OpenGL ES spec also says: 100401e04c3fSmrg * 100501e04c3fSmrg * An INVALID_OPERATION error is generated by any command that transfers 100601e04c3fSmrg * vertices to the GL or launches compute work if the current set of 100701e04c3fSmrg * active program objects cannot be executed, for reasons including: 100801e04c3fSmrg * 100901e04c3fSmrg * * The current program pipeline object contains a shader interface 101001e04c3fSmrg * that doesn't have an exact match (see section 7.4.1) 101101e04c3fSmrg * 101201e04c3fSmrg * Based on this, only perform the most-strict checking on ES or when the 101301e04c3fSmrg * application has created a debug context. 101401e04c3fSmrg */ 101501e04c3fSmrg if ((_mesa_is_gles(ctx) || (ctx->Const.ContextFlags & GL_CONTEXT_FLAG_DEBUG_BIT)) && 101601e04c3fSmrg !_mesa_validate_pipeline_io(pipe)) { 101701e04c3fSmrg if (_mesa_is_gles(ctx)) 101801e04c3fSmrg return GL_FALSE; 101901e04c3fSmrg 102001e04c3fSmrg static GLuint msg_id = 0; 102101e04c3fSmrg 1022b9abf16eSmaya _mesa_gl_debugf(ctx, &msg_id, 1023b9abf16eSmaya MESA_DEBUG_SOURCE_API, 1024b9abf16eSmaya MESA_DEBUG_TYPE_PORTABILITY, 1025b9abf16eSmaya MESA_DEBUG_SEVERITY_MEDIUM, 1026b9abf16eSmaya "glValidateProgramPipeline: pipeline %u does not meet " 1027b9abf16eSmaya "strict OpenGL ES 3.1 requirements and may not be " 1028b9abf16eSmaya "portable across desktop hardware\n", 1029b9abf16eSmaya pipe->Name); 103001e04c3fSmrg } 1031af69d88dSmrg 1032af69d88dSmrg pipe->Validated = GL_TRUE; 1033af69d88dSmrg return GL_TRUE; 1034af69d88dSmrg} 1035af69d88dSmrg 1036af69d88dSmrg/** 1037af69d88dSmrg * Check compatibility of pipeline's program 1038af69d88dSmrg */ 1039af69d88dSmrgvoid GLAPIENTRY 1040af69d88dSmrg_mesa_ValidateProgramPipeline(GLuint pipeline) 1041af69d88dSmrg{ 1042af69d88dSmrg GET_CURRENT_CONTEXT(ctx); 1043af69d88dSmrg 104401e04c3fSmrg if (MESA_VERBOSE & VERBOSE_API) 104501e04c3fSmrg _mesa_debug(ctx, "glValidateProgramPipeline(%u)\n", pipeline); 104601e04c3fSmrg 104701e04c3fSmrg struct gl_pipeline_object *pipe = _mesa_lookup_pipeline_object(ctx, pipeline); 1048af69d88dSmrg 1049af69d88dSmrg if (!pipe) { 1050af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 1051af69d88dSmrg "glValidateProgramPipeline(pipeline)"); 1052af69d88dSmrg return; 1053af69d88dSmrg } 1054af69d88dSmrg 105501e04c3fSmrg _mesa_validate_program_pipeline(ctx, pipe); 1056af69d88dSmrg} 1057af69d88dSmrg 1058af69d88dSmrgvoid GLAPIENTRY 1059af69d88dSmrg_mesa_GetProgramPipelineInfoLog(GLuint pipeline, GLsizei bufSize, 1060af69d88dSmrg GLsizei *length, GLchar *infoLog) 1061af69d88dSmrg{ 1062af69d88dSmrg GET_CURRENT_CONTEXT(ctx); 1063af69d88dSmrg 106401e04c3fSmrg if (MESA_VERBOSE & VERBOSE_API) 106501e04c3fSmrg _mesa_debug(ctx, "glGetProgramPipelineInfoLog(%u, %d, %p, %p)\n", 106601e04c3fSmrg pipeline, bufSize, length, infoLog); 106701e04c3fSmrg 106801e04c3fSmrg struct gl_pipeline_object *pipe = _mesa_lookup_pipeline_object(ctx, pipeline); 1069af69d88dSmrg 1070af69d88dSmrg if (!pipe) { 1071af69d88dSmrg _mesa_error(ctx, GL_INVALID_VALUE, 1072af69d88dSmrg "glGetProgramPipelineInfoLog(pipeline)"); 1073af69d88dSmrg return; 1074af69d88dSmrg } 1075af69d88dSmrg 1076af69d88dSmrg if (bufSize < 0) { 1077af69d88dSmrg _mesa_error(ctx, GL_INVALID_VALUE, 1078af69d88dSmrg "glGetProgramPipelineInfoLog(bufSize)"); 1079af69d88dSmrg return; 1080af69d88dSmrg } 1081af69d88dSmrg 108201e04c3fSmrg _mesa_copy_string(infoLog, bufSize, length, pipe->InfoLog); 1083af69d88dSmrg} 1084