pipelineobj.c revision 01e04c3f
1/* 2 * Mesa 3-D graphics library 3 * 4 * Copyright © 2013 Gregory Hainaut <gregory.hainaut@gmail.com> 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the next 14 * paragraph) shall be included in all copies or substantial portions of the 15 * Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 23 * IN THE SOFTWARE. 24 */ 25 26/** 27 * \file pipelineobj.c 28 * \author Hainaut Gregory <gregory.hainaut@gmail.com> 29 * 30 * Implementation of pipeline object related API functions. Based on 31 * GL_ARB_separate_shader_objects extension. 32 */ 33 34#include <stdbool.h> 35#include "main/glheader.h" 36#include "main/context.h" 37#include "main/enums.h" 38#include "main/hash.h" 39#include "main/mtypes.h" 40#include "main/pipelineobj.h" 41#include "main/shaderapi.h" 42#include "main/shaderobj.h" 43#include "main/state.h" 44#include "main/transformfeedback.h" 45#include "main/uniforms.h" 46#include "compiler/glsl/glsl_parser_extras.h" 47#include "compiler/glsl/ir_uniform.h" 48#include "program/program.h" 49#include "program/prog_parameter.h" 50#include "util/ralloc.h" 51 52/** 53 * Delete a pipeline object. 54 */ 55void 56_mesa_delete_pipeline_object(struct gl_context *ctx, 57 struct gl_pipeline_object *obj) 58{ 59 unsigned i; 60 61 for (i = 0; i < MESA_SHADER_STAGES; i++) { 62 _mesa_reference_program(ctx, &obj->CurrentProgram[i], NULL); 63 _mesa_reference_shader_program(ctx, &obj->ReferencedPrograms[i], NULL); 64 } 65 66 _mesa_reference_shader_program(ctx, &obj->ActiveProgram, NULL); 67 free(obj->Label); 68 ralloc_free(obj); 69} 70 71/** 72 * Allocate and initialize a new pipeline object. 73 */ 74static struct gl_pipeline_object * 75_mesa_new_pipeline_object(struct gl_context *ctx, GLuint name) 76{ 77 struct gl_pipeline_object *obj = rzalloc(NULL, struct gl_pipeline_object); 78 if (obj) { 79 obj->Name = name; 80 obj->RefCount = 1; 81 obj->Flags = _mesa_get_shader_flags(); 82 obj->InfoLog = NULL; 83 } 84 85 return obj; 86} 87 88/** 89 * Initialize pipeline object state for given context. 90 */ 91void 92_mesa_init_pipeline(struct gl_context *ctx) 93{ 94 ctx->Pipeline.Objects = _mesa_NewHashTable(); 95 96 ctx->Pipeline.Current = NULL; 97 98 /* Install a default Pipeline */ 99 ctx->Pipeline.Default = _mesa_new_pipeline_object(ctx, 0); 100 _mesa_reference_pipeline_object(ctx, &ctx->_Shader, ctx->Pipeline.Default); 101} 102 103 104/** 105 * Callback for deleting a pipeline object. Called by _mesa_HashDeleteAll(). 106 */ 107static void 108delete_pipelineobj_cb(UNUSED GLuint id, void *data, void *userData) 109{ 110 struct gl_pipeline_object *obj = (struct gl_pipeline_object *) data; 111 struct gl_context *ctx = (struct gl_context *) userData; 112 _mesa_delete_pipeline_object(ctx, obj); 113} 114 115 116/** 117 * Free pipeline state for given context. 118 */ 119void 120_mesa_free_pipeline_data(struct gl_context *ctx) 121{ 122 _mesa_reference_pipeline_object(ctx, &ctx->_Shader, NULL); 123 124 _mesa_HashDeleteAll(ctx->Pipeline.Objects, delete_pipelineobj_cb, ctx); 125 _mesa_DeleteHashTable(ctx->Pipeline.Objects); 126 127 _mesa_delete_pipeline_object(ctx, ctx->Pipeline.Default); 128} 129 130/** 131 * Look up the pipeline object for the given ID. 132 * 133 * \returns 134 * Either a pointer to the pipeline object with the specified ID or \c NULL for 135 * a non-existent ID. The spec defines ID 0 as being technically 136 * non-existent. 137 */ 138struct gl_pipeline_object * 139_mesa_lookup_pipeline_object(struct gl_context *ctx, GLuint id) 140{ 141 if (id == 0) 142 return NULL; 143 else 144 return (struct gl_pipeline_object *) 145 _mesa_HashLookupLocked(ctx->Pipeline.Objects, id); 146} 147 148/** 149 * Add the given pipeline object to the pipeline object pool. 150 */ 151static void 152save_pipeline_object(struct gl_context *ctx, struct gl_pipeline_object *obj) 153{ 154 if (obj->Name > 0) { 155 _mesa_HashInsertLocked(ctx->Pipeline.Objects, obj->Name, obj); 156 } 157} 158 159/** 160 * Remove the given pipeline object from the pipeline object pool. 161 * Do not deallocate the pipeline object though. 162 */ 163static void 164remove_pipeline_object(struct gl_context *ctx, struct gl_pipeline_object *obj) 165{ 166 if (obj->Name > 0) { 167 _mesa_HashRemoveLocked(ctx->Pipeline.Objects, obj->Name); 168 } 169} 170 171/** 172 * Set ptr to obj w/ reference counting. 173 * Note: this should only be called from the _mesa_reference_pipeline_object() 174 * inline function. 175 */ 176void 177_mesa_reference_pipeline_object_(struct gl_context *ctx, 178 struct gl_pipeline_object **ptr, 179 struct gl_pipeline_object *obj) 180{ 181 assert(*ptr != obj); 182 183 if (*ptr) { 184 /* Unreference the old pipeline object */ 185 struct gl_pipeline_object *oldObj = *ptr; 186 187 assert(oldObj->RefCount > 0); 188 oldObj->RefCount--; 189 190 if (oldObj->RefCount == 0) { 191 _mesa_delete_pipeline_object(ctx, oldObj); 192 } 193 194 *ptr = NULL; 195 } 196 assert(!*ptr); 197 198 if (obj) { 199 /* reference new pipeline object */ 200 assert(obj->RefCount > 0); 201 202 obj->RefCount++; 203 *ptr = obj; 204 } 205} 206 207static void 208use_program_stage(struct gl_context *ctx, GLenum type, 209 struct gl_shader_program *shProg, 210 struct gl_pipeline_object *pipe) { 211 gl_shader_stage stage = _mesa_shader_enum_to_shader_stage(type); 212 struct gl_program *prog = NULL; 213 if (shProg && shProg->_LinkedShaders[stage]) 214 prog = shProg->_LinkedShaders[stage]->Program; 215 216 _mesa_use_program(ctx, stage, shProg, prog, pipe); 217} 218 219static void 220use_program_stages(struct gl_context *ctx, struct gl_shader_program *shProg, 221 GLbitfield stages, struct gl_pipeline_object *pipe) { 222 223 /* Enable individual stages from the program as requested by the 224 * application. If there is no shader for a requested stage in the 225 * program, _mesa_use_shader_program will enable fixed-function processing 226 * as dictated by the spec. 227 * 228 * Section 2.11.4 (Program Pipeline Objects) of the OpenGL 4.1 spec 229 * says: 230 * 231 * "If UseProgramStages is called with program set to zero or with a 232 * program object that contains no executable code for the given 233 * stages, it is as if the pipeline object has no programmable stage 234 * configured for the indicated shader stages." 235 */ 236 if ((stages & GL_VERTEX_SHADER_BIT) != 0) 237 use_program_stage(ctx, GL_VERTEX_SHADER, shProg, pipe); 238 239 if ((stages & GL_FRAGMENT_SHADER_BIT) != 0) 240 use_program_stage(ctx, GL_FRAGMENT_SHADER, shProg, pipe); 241 242 if ((stages & GL_GEOMETRY_SHADER_BIT) != 0) 243 use_program_stage(ctx, GL_GEOMETRY_SHADER, shProg, pipe); 244 245 if ((stages & GL_TESS_CONTROL_SHADER_BIT) != 0) 246 use_program_stage(ctx, GL_TESS_CONTROL_SHADER, shProg, pipe); 247 248 if ((stages & GL_TESS_EVALUATION_SHADER_BIT) != 0) 249 use_program_stage(ctx, GL_TESS_EVALUATION_SHADER, shProg, pipe); 250 251 if ((stages & GL_COMPUTE_SHADER_BIT) != 0) 252 use_program_stage(ctx, GL_COMPUTE_SHADER, shProg, pipe); 253 254 pipe->Validated = false; 255} 256 257void GLAPIENTRY 258_mesa_UseProgramStages_no_error(GLuint pipeline, GLbitfield stages, 259 GLuint prog) 260{ 261 GET_CURRENT_CONTEXT(ctx); 262 263 struct gl_pipeline_object *pipe = 264 _mesa_lookup_pipeline_object(ctx, pipeline); 265 struct gl_shader_program *shProg = NULL; 266 267 if (prog) 268 shProg = _mesa_lookup_shader_program(ctx, prog); 269 270 /* Object is created by any Pipeline call but glGenProgramPipelines, 271 * glIsProgramPipeline and GetProgramPipelineInfoLog 272 */ 273 pipe->EverBound = GL_TRUE; 274 275 use_program_stages(ctx, shProg, stages, pipe); 276} 277 278/** 279 * Bound program to severals stages of the pipeline 280 */ 281void GLAPIENTRY 282_mesa_UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program) 283{ 284 GET_CURRENT_CONTEXT(ctx); 285 286 struct gl_pipeline_object *pipe = _mesa_lookup_pipeline_object(ctx, pipeline); 287 struct gl_shader_program *shProg = NULL; 288 GLbitfield any_valid_stages; 289 290 if (MESA_VERBOSE & VERBOSE_API) 291 _mesa_debug(ctx, "glUseProgramStages(%u, 0x%x, %u)\n", 292 pipeline, stages, program); 293 294 if (!pipe) { 295 _mesa_error(ctx, GL_INVALID_OPERATION, "glUseProgramStages(pipeline)"); 296 return; 297 } 298 299 /* Object is created by any Pipeline call but glGenProgramPipelines, 300 * glIsProgramPipeline and GetProgramPipelineInfoLog 301 */ 302 pipe->EverBound = GL_TRUE; 303 304 /* Section 2.11.4 (Program Pipeline Objects) of the OpenGL 4.1 spec says: 305 * 306 * "If stages is not the special value ALL_SHADER_BITS, and has a bit 307 * set that is not recognized, the error INVALID_VALUE is generated." 308 */ 309 any_valid_stages = GL_VERTEX_SHADER_BIT | GL_FRAGMENT_SHADER_BIT; 310 if (_mesa_has_geometry_shaders(ctx)) 311 any_valid_stages |= GL_GEOMETRY_SHADER_BIT; 312 if (_mesa_has_tessellation(ctx)) 313 any_valid_stages |= GL_TESS_CONTROL_SHADER_BIT | 314 GL_TESS_EVALUATION_SHADER_BIT; 315 if (_mesa_has_compute_shaders(ctx)) 316 any_valid_stages |= GL_COMPUTE_SHADER_BIT; 317 318 if (stages != GL_ALL_SHADER_BITS && (stages & ~any_valid_stages) != 0) { 319 _mesa_error(ctx, GL_INVALID_VALUE, "glUseProgramStages(Stages)"); 320 return; 321 } 322 323 /* Section 2.17.2 (Transform Feedback Primitive Capture) of the OpenGL 4.1 324 * spec says: 325 * 326 * "The error INVALID_OPERATION is generated: 327 * 328 * ... 329 * 330 * - by UseProgramStages if the program pipeline object it refers 331 * to is current and the current transform feedback object is 332 * active and not paused; 333 */ 334 if (ctx->_Shader == pipe) { 335 if (_mesa_is_xfb_active_and_unpaused(ctx)) { 336 _mesa_error(ctx, GL_INVALID_OPERATION, 337 "glUseProgramStages(transform feedback active)"); 338 return; 339 } 340 } 341 342 if (program) { 343 shProg = _mesa_lookup_shader_program_err(ctx, program, 344 "glUseProgramStages"); 345 if (shProg == NULL) 346 return; 347 348 /* Section 2.11.4 (Program Pipeline Objects) of the OpenGL 4.1 spec 349 * says: 350 * 351 * "If the program object named by program was linked without the 352 * PROGRAM_SEPARABLE parameter set, or was not linked successfully, 353 * the error INVALID_OPERATION is generated and the corresponding 354 * shader stages in the pipeline program pipeline object are not 355 * modified." 356 */ 357 if (!shProg->data->LinkStatus) { 358 _mesa_error(ctx, GL_INVALID_OPERATION, 359 "glUseProgramStages(program not linked)"); 360 return; 361 } 362 363 if (!shProg->SeparateShader) { 364 _mesa_error(ctx, GL_INVALID_OPERATION, 365 "glUseProgramStages(program wasn't linked with the " 366 "PROGRAM_SEPARABLE flag)"); 367 return; 368 } 369 } 370 371 use_program_stages(ctx, shProg, stages, pipe); 372} 373 374static ALWAYS_INLINE void 375active_shader_program(struct gl_context *ctx, GLuint pipeline, GLuint program, 376 bool no_error) 377{ 378 struct gl_shader_program *shProg = NULL; 379 struct gl_pipeline_object *pipe = _mesa_lookup_pipeline_object(ctx, pipeline); 380 381 if (program) { 382 if (no_error) { 383 shProg = _mesa_lookup_shader_program(ctx, program); 384 } else { 385 shProg = _mesa_lookup_shader_program_err(ctx, program, 386 "glActiveShaderProgram(program)"); 387 if (shProg == NULL) 388 return; 389 } 390 } 391 392 if (!no_error && !pipe) { 393 _mesa_error(ctx, GL_INVALID_OPERATION, "glActiveShaderProgram(pipeline)"); 394 return; 395 } 396 397 /* Object is created by any Pipeline call but glGenProgramPipelines, 398 * glIsProgramPipeline and GetProgramPipelineInfoLog 399 */ 400 pipe->EverBound = GL_TRUE; 401 402 if (!no_error && shProg != NULL && !shProg->data->LinkStatus) { 403 _mesa_error(ctx, GL_INVALID_OPERATION, 404 "glActiveShaderProgram(program %u not linked)", shProg->Name); 405 return; 406 } 407 408 _mesa_reference_shader_program(ctx, &pipe->ActiveProgram, shProg); 409} 410 411void GLAPIENTRY 412_mesa_ActiveShaderProgram_no_error(GLuint pipeline, GLuint program) 413{ 414 GET_CURRENT_CONTEXT(ctx); 415 active_shader_program(ctx, pipeline, program, true); 416} 417 418/** 419 * Use the named shader program for subsequent glUniform calls (if pipeline 420 * bound) 421 */ 422void GLAPIENTRY 423_mesa_ActiveShaderProgram(GLuint pipeline, GLuint program) 424{ 425 GET_CURRENT_CONTEXT(ctx); 426 427 if (MESA_VERBOSE & VERBOSE_API) 428 _mesa_debug(ctx, "glActiveShaderProgram(%u, %u)\n", pipeline, program); 429 430 active_shader_program(ctx, pipeline, program, false); 431} 432 433static ALWAYS_INLINE void 434bind_program_pipeline(struct gl_context *ctx, GLuint pipeline, bool no_error) 435{ 436 struct gl_pipeline_object *newObj = NULL; 437 438 if (MESA_VERBOSE & VERBOSE_API) 439 _mesa_debug(ctx, "glBindProgramPipeline(%u)\n", pipeline); 440 441 /* Rebinding the same pipeline object: no change. 442 */ 443 if (ctx->_Shader->Name == pipeline) 444 return; 445 446 /* Section 2.17.2 (Transform Feedback Primitive Capture) of the OpenGL 4.1 447 * spec says: 448 * 449 * "The error INVALID_OPERATION is generated: 450 * 451 * ... 452 * 453 * - by BindProgramPipeline if the current transform feedback 454 * object is active and not paused; 455 */ 456 if (!no_error && _mesa_is_xfb_active_and_unpaused(ctx)) { 457 _mesa_error(ctx, GL_INVALID_OPERATION, 458 "glBindProgramPipeline(transform feedback active)"); 459 return; 460 } 461 462 /* Get pointer to new pipeline object (newObj) 463 */ 464 if (pipeline) { 465 /* non-default pipeline object */ 466 newObj = _mesa_lookup_pipeline_object(ctx, pipeline); 467 if (!no_error && !newObj) { 468 _mesa_error(ctx, GL_INVALID_OPERATION, 469 "glBindProgramPipeline(non-gen name)"); 470 return; 471 } 472 473 /* Object is created by any Pipeline call but glGenProgramPipelines, 474 * glIsProgramPipeline and GetProgramPipelineInfoLog 475 */ 476 newObj->EverBound = GL_TRUE; 477 } 478 479 _mesa_bind_pipeline(ctx, newObj); 480} 481 482void GLAPIENTRY 483_mesa_BindProgramPipeline_no_error(GLuint pipeline) 484{ 485 GET_CURRENT_CONTEXT(ctx); 486 bind_program_pipeline(ctx, pipeline, true); 487} 488 489/** 490 * Make program of the pipeline current 491 */ 492void GLAPIENTRY 493_mesa_BindProgramPipeline(GLuint pipeline) 494{ 495 GET_CURRENT_CONTEXT(ctx); 496 bind_program_pipeline(ctx, pipeline, false); 497} 498 499void 500_mesa_bind_pipeline(struct gl_context *ctx, 501 struct gl_pipeline_object *pipe) 502{ 503 int i; 504 /* First bind the Pipeline to pipeline binding point */ 505 _mesa_reference_pipeline_object(ctx, &ctx->Pipeline.Current, pipe); 506 507 /* Section 2.11.3 (Program Objects) of the OpenGL 4.1 spec says: 508 * 509 * "If there is a current program object established by UseProgram, 510 * that program is considered current for all stages. Otherwise, if 511 * there is a bound program pipeline object (see section 2.11.4), the 512 * program bound to the appropriate stage of the pipeline object is 513 * considered current." 514 */ 515 if (&ctx->Shader != ctx->_Shader) { 516 FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); 517 518 if (pipe != NULL) { 519 /* Bound the pipeline to the current program and 520 * restore the pipeline state 521 */ 522 _mesa_reference_pipeline_object(ctx, &ctx->_Shader, pipe); 523 } else { 524 /* Unbind the pipeline */ 525 _mesa_reference_pipeline_object(ctx, &ctx->_Shader, 526 ctx->Pipeline.Default); 527 } 528 529 for (i = 0; i < MESA_SHADER_STAGES; i++) { 530 struct gl_program *prog = ctx->_Shader->CurrentProgram[i]; 531 if (prog) { 532 _mesa_program_init_subroutine_defaults(ctx, prog); 533 } 534 } 535 536 _mesa_update_vertex_processing_mode(ctx); 537 } 538} 539 540/** 541 * Delete a set of pipeline objects. 542 * 543 * \param n Number of pipeline objects to delete. 544 * \param ids pipeline of \c n pipeline object IDs. 545 */ 546void GLAPIENTRY 547_mesa_DeleteProgramPipelines(GLsizei n, const GLuint *pipelines) 548{ 549 GET_CURRENT_CONTEXT(ctx); 550 GLsizei i; 551 552 if (MESA_VERBOSE & VERBOSE_API) 553 _mesa_debug(ctx, "glDeleteProgramPipelines(%d, %p)\n", n, pipelines); 554 555 if (n < 0) { 556 _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteProgramPipelines(n<0)"); 557 return; 558 } 559 560 for (i = 0; i < n; i++) { 561 struct gl_pipeline_object *obj = 562 _mesa_lookup_pipeline_object(ctx, pipelines[i]); 563 564 if (obj) { 565 assert(obj->Name == pipelines[i]); 566 567 /* If the pipeline object is currently bound, the spec says "If an 568 * object that is currently bound is deleted, the binding for that 569 * object reverts to zero and no program pipeline object becomes 570 * current." 571 */ 572 if (obj == ctx->Pipeline.Current) { 573 _mesa_BindProgramPipeline(0); 574 } 575 576 /* The ID is immediately freed for re-use */ 577 remove_pipeline_object(ctx, obj); 578 579 /* Unreference the pipeline object. 580 * If refcount hits zero, the object will be deleted. 581 */ 582 _mesa_reference_pipeline_object(ctx, &obj, NULL); 583 } 584 } 585} 586 587/** 588 * Generate a set of unique pipeline object IDs and store them in \c pipelines. 589 * \param n Number of IDs to generate. 590 * \param pipelines pipeline of \c n locations to store the IDs. 591 */ 592static void 593create_program_pipelines(struct gl_context *ctx, GLsizei n, GLuint *pipelines, 594 bool dsa) 595{ 596 const char *func = dsa ? "glCreateProgramPipelines" : "glGenProgramPipelines"; 597 GLuint first; 598 GLint i; 599 600 if (!pipelines) 601 return; 602 603 first = _mesa_HashFindFreeKeyBlock(ctx->Pipeline.Objects, n); 604 605 for (i = 0; i < n; i++) { 606 struct gl_pipeline_object *obj; 607 GLuint name = first + i; 608 609 obj = _mesa_new_pipeline_object(ctx, name); 610 if (!obj) { 611 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func); 612 return; 613 } 614 615 if (dsa) { 616 /* make dsa-allocated objects behave like program objects */ 617 obj->EverBound = GL_TRUE; 618 } 619 620 save_pipeline_object(ctx, obj); 621 pipelines[i] = first + i; 622 } 623} 624 625static void 626create_program_pipelines_err(struct gl_context *ctx, GLsizei n, 627 GLuint *pipelines, bool dsa) 628{ 629 const char *func = dsa ? "glCreateProgramPipelines" : "glGenProgramPipelines"; 630 631 if (n < 0) { 632 _mesa_error(ctx, GL_INVALID_VALUE, "%s (n < 0)", func); 633 return; 634 } 635 636 create_program_pipelines(ctx, n, pipelines, dsa); 637} 638 639void GLAPIENTRY 640_mesa_GenProgramPipelines_no_error(GLsizei n, GLuint *pipelines) 641{ 642 GET_CURRENT_CONTEXT(ctx); 643 create_program_pipelines(ctx, n, pipelines, false); 644} 645 646void GLAPIENTRY 647_mesa_GenProgramPipelines(GLsizei n, GLuint *pipelines) 648{ 649 GET_CURRENT_CONTEXT(ctx); 650 651 if (MESA_VERBOSE & VERBOSE_API) 652 _mesa_debug(ctx, "glGenProgramPipelines(%d, %p)\n", n, pipelines); 653 654 create_program_pipelines_err(ctx, n, pipelines, false); 655} 656 657void GLAPIENTRY 658_mesa_CreateProgramPipelines_no_error(GLsizei n, GLuint *pipelines) 659{ 660 GET_CURRENT_CONTEXT(ctx); 661 create_program_pipelines(ctx, n, pipelines, true); 662} 663 664void GLAPIENTRY 665_mesa_CreateProgramPipelines(GLsizei n, GLuint *pipelines) 666{ 667 GET_CURRENT_CONTEXT(ctx); 668 669 if (MESA_VERBOSE & VERBOSE_API) 670 _mesa_debug(ctx, "glCreateProgramPipelines(%d, %p)\n", n, pipelines); 671 672 create_program_pipelines_err(ctx, n, pipelines, true); 673} 674 675/** 676 * Determine if ID is the name of an pipeline object. 677 * 678 * \param id ID of the potential pipeline object. 679 * \return \c GL_TRUE if \c id is the name of a pipeline object, 680 * \c GL_FALSE otherwise. 681 */ 682GLboolean GLAPIENTRY 683_mesa_IsProgramPipeline(GLuint pipeline) 684{ 685 GET_CURRENT_CONTEXT(ctx); 686 687 if (MESA_VERBOSE & VERBOSE_API) 688 _mesa_debug(ctx, "glIsProgramPipeline(%u)\n", pipeline); 689 690 struct gl_pipeline_object *obj = _mesa_lookup_pipeline_object(ctx, pipeline); 691 if (obj == NULL) 692 return GL_FALSE; 693 694 return obj->EverBound; 695} 696 697/** 698 * glGetProgramPipelineiv() - get pipeline shader state. 699 */ 700void GLAPIENTRY 701_mesa_GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params) 702{ 703 GET_CURRENT_CONTEXT(ctx); 704 struct gl_pipeline_object *pipe = _mesa_lookup_pipeline_object(ctx, pipeline); 705 706 if (MESA_VERBOSE & VERBOSE_API) 707 _mesa_debug(ctx, "glGetProgramPipelineiv(%u, %d, %p)\n", 708 pipeline, pname, params); 709 710 /* Are geometry shaders available in this context? 711 */ 712 const bool has_gs = _mesa_has_geometry_shaders(ctx); 713 const bool has_tess = _mesa_has_tessellation(ctx); 714 715 if (!pipe) { 716 _mesa_error(ctx, GL_INVALID_OPERATION, 717 "glGetProgramPipelineiv(pipeline)"); 718 return; 719 } 720 721 /* Object is created by any Pipeline call but glGenProgramPipelines, 722 * glIsProgramPipeline and GetProgramPipelineInfoLog 723 */ 724 pipe->EverBound = GL_TRUE; 725 726 switch (pname) { 727 case GL_ACTIVE_PROGRAM: 728 *params = pipe->ActiveProgram ? pipe->ActiveProgram->Name : 0; 729 return; 730 case GL_INFO_LOG_LENGTH: 731 *params = (pipe->InfoLog && pipe->InfoLog[0] != '\0') ? 732 strlen(pipe->InfoLog) + 1 : 0; 733 return; 734 case GL_VALIDATE_STATUS: 735 *params = pipe->Validated; 736 return; 737 case GL_VERTEX_SHADER: 738 *params = pipe->CurrentProgram[MESA_SHADER_VERTEX] 739 ? pipe->CurrentProgram[MESA_SHADER_VERTEX]->Id : 0; 740 return; 741 case GL_TESS_EVALUATION_SHADER: 742 if (!has_tess) 743 break; 744 *params = pipe->CurrentProgram[MESA_SHADER_TESS_EVAL] 745 ? pipe->CurrentProgram[MESA_SHADER_TESS_EVAL]->Id : 0; 746 return; 747 case GL_TESS_CONTROL_SHADER: 748 if (!has_tess) 749 break; 750 *params = pipe->CurrentProgram[MESA_SHADER_TESS_CTRL] 751 ? pipe->CurrentProgram[MESA_SHADER_TESS_CTRL]->Id : 0; 752 return; 753 case GL_GEOMETRY_SHADER: 754 if (!has_gs) 755 break; 756 *params = pipe->CurrentProgram[MESA_SHADER_GEOMETRY] 757 ? pipe->CurrentProgram[MESA_SHADER_GEOMETRY]->Id : 0; 758 return; 759 case GL_FRAGMENT_SHADER: 760 *params = pipe->CurrentProgram[MESA_SHADER_FRAGMENT] 761 ? pipe->CurrentProgram[MESA_SHADER_FRAGMENT]->Id : 0; 762 return; 763 case GL_COMPUTE_SHADER: 764 if (!_mesa_has_compute_shaders(ctx)) 765 break; 766 *params = pipe->CurrentProgram[MESA_SHADER_COMPUTE] 767 ? pipe->CurrentProgram[MESA_SHADER_COMPUTE]->Id : 0; 768 return; 769 default: 770 break; 771 } 772 773 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramPipelineiv(pname=%s)", 774 _mesa_enum_to_string(pname)); 775} 776 777/** 778 * Determines whether every stage in a linked program is active in the 779 * specified pipeline. 780 */ 781static bool 782program_stages_all_active(struct gl_pipeline_object *pipe, 783 const struct gl_program *prog) 784{ 785 bool status = true; 786 787 if (!prog) 788 return true; 789 790 unsigned mask = prog->sh.data->linked_stages; 791 while (mask) { 792 const int i = u_bit_scan(&mask); 793 if (pipe->CurrentProgram[i]) { 794 if (prog->Id != pipe->CurrentProgram[i]->Id) { 795 status = false; 796 } 797 } else { 798 status = false; 799 } 800 } 801 802 if (!status) { 803 pipe->InfoLog = ralloc_asprintf(pipe, 804 "Program %d is not active for all " 805 "shaders that was linked", 806 prog->Id); 807 } 808 809 return status; 810} 811 812static bool 813program_stages_interleaved_illegally(const struct gl_pipeline_object *pipe) 814{ 815 unsigned prev_linked_stages = 0; 816 817 /* Look for programs bound to stages: A -> B -> A, with any intervening 818 * sequence of unrelated programs or empty stages. 819 */ 820 for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 821 struct gl_program *cur = pipe->CurrentProgram[i]; 822 823 /* Empty stages anywhere in the pipe are OK. Also we can be confident 824 * that if the linked_stages mask matches we are looking at the same 825 * linked program because a previous validation call to 826 * program_stages_all_active() will have already failed if two different 827 * programs with the sames stages linked are not active for all linked 828 * stages. 829 */ 830 if (!cur || cur->sh.data->linked_stages == prev_linked_stages) 831 continue; 832 833 if (prev_linked_stages) { 834 /* We've seen an A -> B transition; look at the rest of the pipe 835 * to see if we ever see A again. 836 */ 837 if (prev_linked_stages >> (i + 1)) 838 return true; 839 } 840 841 prev_linked_stages = cur->sh.data->linked_stages; 842 } 843 844 return false; 845} 846 847extern GLboolean 848_mesa_validate_program_pipeline(struct gl_context* ctx, 849 struct gl_pipeline_object *pipe) 850{ 851 unsigned i; 852 bool program_empty = true; 853 854 pipe->Validated = GL_FALSE; 855 856 /* Release and reset the info log. 857 */ 858 if (pipe->InfoLog != NULL) 859 ralloc_free(pipe->InfoLog); 860 861 pipe->InfoLog = NULL; 862 863 /* Section 2.11.11 (Shader Execution), subheading "Validation," of the 864 * OpenGL 4.1 spec says: 865 * 866 * "[INVALID_OPERATION] is generated by any command that transfers 867 * vertices to the GL if: 868 * 869 * - A program object is active for at least one, but not all of 870 * the shader stages that were present when the program was 871 * linked." 872 * 873 * For each possible program stage, verify that the program bound to that 874 * stage has all of its stages active. In other words, if the program 875 * bound to the vertex stage also has a fragment shader, the fragment 876 * shader must also be bound to the fragment stage. 877 */ 878 for (i = 0; i < MESA_SHADER_STAGES; i++) { 879 if (!program_stages_all_active(pipe, pipe->CurrentProgram[i])) { 880 return GL_FALSE; 881 } 882 } 883 884 /* Section 2.11.11 (Shader Execution), subheading "Validation," of the 885 * OpenGL 4.1 spec says: 886 * 887 * "[INVALID_OPERATION] is generated by any command that transfers 888 * vertices to the GL if: 889 * 890 * ... 891 * 892 * - One program object is active for at least two shader stages 893 * and a second program is active for a shader stage between two 894 * stages for which the first program was active." 895 */ 896 if (program_stages_interleaved_illegally(pipe)) { 897 pipe->InfoLog = 898 ralloc_strdup(pipe, 899 "Program is active for multiple shader stages with an " 900 "intervening stage provided by another program"); 901 return GL_FALSE; 902 } 903 904 /* Section 2.11.11 (Shader Execution), subheading "Validation," of the 905 * OpenGL 4.1 spec says: 906 * 907 * "[INVALID_OPERATION] is generated by any command that transfers 908 * vertices to the GL if: 909 * 910 * ... 911 * 912 * - There is an active program for tessellation control, 913 * tessellation evaluation, or geometry stages with corresponding 914 * executable shader, but there is no active program with 915 * executable vertex shader." 916 */ 917 if (!pipe->CurrentProgram[MESA_SHADER_VERTEX] 918 && (pipe->CurrentProgram[MESA_SHADER_GEOMETRY] || 919 pipe->CurrentProgram[MESA_SHADER_TESS_CTRL] || 920 pipe->CurrentProgram[MESA_SHADER_TESS_EVAL])) { 921 pipe->InfoLog = ralloc_strdup(pipe, "Program lacks a vertex shader"); 922 return GL_FALSE; 923 } 924 925 /* Section 2.11.11 (Shader Execution), subheading "Validation," of the 926 * OpenGL 4.1 spec says: 927 * 928 * "[INVALID_OPERATION] is generated by any command that transfers 929 * vertices to the GL if: 930 * 931 * ... 932 * 933 * - There is no current program object specified by UseProgram, 934 * there is a current program pipeline object, and the current 935 * program for any shader stage has been relinked since being 936 * applied to the pipeline object via UseProgramStages with the 937 * PROGRAM_SEPARABLE parameter set to FALSE. 938 */ 939 for (i = 0; i < MESA_SHADER_STAGES; i++) { 940 if (pipe->CurrentProgram[i] && 941 !pipe->CurrentProgram[i]->info.separate_shader) { 942 pipe->InfoLog = ralloc_asprintf(pipe, 943 "Program %d was relinked without " 944 "PROGRAM_SEPARABLE state", 945 pipe->CurrentProgram[i]->Id); 946 return GL_FALSE; 947 } 948 } 949 950 /* Section 11.1.3.11 (Validation) of the OpenGL 4.5 spec says: 951 * 952 * "An INVALID_OPERATION error is generated by any command that trans- 953 * fers vertices to the GL or launches compute work if the current set 954 * of active program objects cannot be executed, for reasons including: 955 * 956 * ... 957 * 958 * - There is no current program object specified by UseProgram, 959 * there is a current program pipeline object, and that object is 960 * empty (no executable code is installed for any stage). 961 */ 962 for (i = 0; i < MESA_SHADER_STAGES; i++) { 963 if (pipe->CurrentProgram[i]) { 964 program_empty = false; 965 break; 966 } 967 } 968 969 if (program_empty) { 970 return GL_FALSE; 971 } 972 973 /* Section 2.11.11 (Shader Execution), subheading "Validation," of the 974 * OpenGL 4.1 spec says: 975 * 976 * "[INVALID_OPERATION] is generated by any command that transfers 977 * vertices to the GL if: 978 * 979 * ... 980 * 981 * - Any two active samplers in the current program object are of 982 * different types, but refer to the same texture image unit. 983 * 984 * - The number of active samplers in the program exceeds the 985 * maximum number of texture image units allowed." 986 */ 987 if (!_mesa_sampler_uniforms_pipeline_are_valid(pipe)) 988 return GL_FALSE; 989 990 /* Validate inputs against outputs, this cannot be done during linking 991 * since programs have been linked separately from each other. 992 * 993 * Section 11.1.3.11 (Validation) of the OpenGL 4.5 Core Profile spec says: 994 * 995 * "Separable program objects may have validation failures that cannot be 996 * detected without the complete program pipeline. Mismatched interfaces, 997 * improper usage of program objects together, and the same 998 * state-dependent failures can result in validation errors for such 999 * program objects." 1000 * 1001 * OpenGL ES 3.1 specification has the same text. 1002 * 1003 * Section 11.1.3.11 (Validation) of the OpenGL ES spec also says: 1004 * 1005 * An INVALID_OPERATION error is generated by any command that transfers 1006 * vertices to the GL or launches compute work if the current set of 1007 * active program objects cannot be executed, for reasons including: 1008 * 1009 * * The current program pipeline object contains a shader interface 1010 * that doesn't have an exact match (see section 7.4.1) 1011 * 1012 * Based on this, only perform the most-strict checking on ES or when the 1013 * application has created a debug context. 1014 */ 1015 if ((_mesa_is_gles(ctx) || (ctx->Const.ContextFlags & GL_CONTEXT_FLAG_DEBUG_BIT)) && 1016 !_mesa_validate_pipeline_io(pipe)) { 1017 if (_mesa_is_gles(ctx)) 1018 return GL_FALSE; 1019 1020 static GLuint msg_id = 0; 1021 1022 _mesa_gl_debug(ctx, &msg_id, 1023 MESA_DEBUG_SOURCE_API, 1024 MESA_DEBUG_TYPE_PORTABILITY, 1025 MESA_DEBUG_SEVERITY_MEDIUM, 1026 "glValidateProgramPipeline: pipeline %u does not meet " 1027 "strict OpenGL ES 3.1 requirements and may not be " 1028 "portable across desktop hardware\n", 1029 pipe->Name); 1030 } 1031 1032 pipe->Validated = GL_TRUE; 1033 return GL_TRUE; 1034} 1035 1036/** 1037 * Check compatibility of pipeline's program 1038 */ 1039void GLAPIENTRY 1040_mesa_ValidateProgramPipeline(GLuint pipeline) 1041{ 1042 GET_CURRENT_CONTEXT(ctx); 1043 1044 if (MESA_VERBOSE & VERBOSE_API) 1045 _mesa_debug(ctx, "glValidateProgramPipeline(%u)\n", pipeline); 1046 1047 struct gl_pipeline_object *pipe = _mesa_lookup_pipeline_object(ctx, pipeline); 1048 1049 if (!pipe) { 1050 _mesa_error(ctx, GL_INVALID_OPERATION, 1051 "glValidateProgramPipeline(pipeline)"); 1052 return; 1053 } 1054 1055 _mesa_validate_program_pipeline(ctx, pipe); 1056} 1057 1058void GLAPIENTRY 1059_mesa_GetProgramPipelineInfoLog(GLuint pipeline, GLsizei bufSize, 1060 GLsizei *length, GLchar *infoLog) 1061{ 1062 GET_CURRENT_CONTEXT(ctx); 1063 1064 if (MESA_VERBOSE & VERBOSE_API) 1065 _mesa_debug(ctx, "glGetProgramPipelineInfoLog(%u, %d, %p, %p)\n", 1066 pipeline, bufSize, length, infoLog); 1067 1068 struct gl_pipeline_object *pipe = _mesa_lookup_pipeline_object(ctx, pipeline); 1069 1070 if (!pipe) { 1071 _mesa_error(ctx, GL_INVALID_VALUE, 1072 "glGetProgramPipelineInfoLog(pipeline)"); 1073 return; 1074 } 1075 1076 if (bufSize < 0) { 1077 _mesa_error(ctx, GL_INVALID_VALUE, 1078 "glGetProgramPipelineInfoLog(bufSize)"); 1079 return; 1080 } 1081 1082 _mesa_copy_string(infoLog, bufSize, length, pipe->InfoLog); 1083} 1084