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