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