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