Home | History | Annotate | Download | only in program
      1 /*
      2  * Mesa 3-D graphics library
      3  *
      4  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
      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 shall be included
     14  * in all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     22  * OTHER DEALINGS IN THE SOFTWARE.
     23  */
     24 
     25 /**
     26  * \file program.c
     27  * Vertex and fragment program support functions.
     28  * \author Brian Paul
     29  */
     30 
     31 
     32 #include "main/glheader.h"
     33 #include "main/context.h"
     34 #include "main/framebuffer.h"
     35 #include "main/hash.h"
     36 #include "main/macros.h"
     37 #include "main/shaderobj.h"
     38 #include "program.h"
     39 #include "prog_cache.h"
     40 #include "prog_parameter.h"
     41 #include "prog_instruction.h"
     42 #include "util/bitscan.h"
     43 #include "util/ralloc.h"
     44 #include "util/u_atomic.h"
     45 
     46 
     47 /**
     48  * A pointer to this dummy program is put into the hash table when
     49  * glGenPrograms is called.
     50  */
     51 struct gl_program _mesa_DummyProgram;
     52 
     53 
     54 /**
     55  * Init context's vertex/fragment program state
     56  */
     57 void
     58 _mesa_init_program(struct gl_context *ctx)
     59 {
     60    /*
     61     * If this assertion fails, we need to increase the field
     62     * size for register indexes (see INST_INDEX_BITS).
     63     */
     64    assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents / 4
     65           <= (1 << INST_INDEX_BITS));
     66    assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents / 4
     67           <= (1 << INST_INDEX_BITS));
     68 
     69    assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxTemps <= (1 << INST_INDEX_BITS));
     70    assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxLocalParams <= (1 << INST_INDEX_BITS));
     71    assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTemps <= (1 << INST_INDEX_BITS));
     72    assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxLocalParams <= (1 << INST_INDEX_BITS));
     73 
     74    assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents <= 4 * MAX_UNIFORMS);
     75    assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents <= 4 * MAX_UNIFORMS);
     76 
     77    assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxAddressOffset <= (1 << INST_INDEX_BITS));
     78    assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxAddressOffset <= (1 << INST_INDEX_BITS));
     79 
     80    /* If this fails, increase prog_instruction::TexSrcUnit size */
     81    STATIC_ASSERT(MAX_TEXTURE_UNITS <= (1 << 5));
     82 
     83    /* If this fails, increase prog_instruction::TexSrcTarget size */
     84    STATIC_ASSERT(NUM_TEXTURE_TARGETS <= (1 << 4));
     85 
     86    ctx->Program.ErrorPos = -1;
     87    ctx->Program.ErrorString = strdup("");
     88 
     89    ctx->VertexProgram.Enabled = GL_FALSE;
     90    ctx->VertexProgram.PointSizeEnabled =
     91       (ctx->API == API_OPENGLES2) ? GL_TRUE : GL_FALSE;
     92    ctx->VertexProgram.TwoSideEnabled = GL_FALSE;
     93    _mesa_reference_program(ctx, &ctx->VertexProgram.Current,
     94                            ctx->Shared->DefaultVertexProgram);
     95    assert(ctx->VertexProgram.Current);
     96    ctx->VertexProgram.Cache = _mesa_new_program_cache();
     97 
     98    ctx->FragmentProgram.Enabled = GL_FALSE;
     99    _mesa_reference_program(ctx, &ctx->FragmentProgram.Current,
    100                            ctx->Shared->DefaultFragmentProgram);
    101    assert(ctx->FragmentProgram.Current);
    102    ctx->FragmentProgram.Cache = _mesa_new_program_cache();
    103 
    104    /* XXX probably move this stuff */
    105    ctx->ATIFragmentShader.Enabled = GL_FALSE;
    106    ctx->ATIFragmentShader.Current = ctx->Shared->DefaultFragmentShader;
    107    assert(ctx->ATIFragmentShader.Current);
    108    ctx->ATIFragmentShader.Current->RefCount++;
    109 }
    110 
    111 
    112 /**
    113  * Free a context's vertex/fragment program state
    114  */
    115 void
    116 _mesa_free_program_data(struct gl_context *ctx)
    117 {
    118    _mesa_reference_program(ctx, &ctx->VertexProgram.Current, NULL);
    119    _mesa_delete_program_cache(ctx, ctx->VertexProgram.Cache);
    120    _mesa_reference_program(ctx, &ctx->FragmentProgram.Current, NULL);
    121    _mesa_delete_shader_cache(ctx, ctx->FragmentProgram.Cache);
    122 
    123    /* XXX probably move this stuff */
    124    if (ctx->ATIFragmentShader.Current) {
    125       ctx->ATIFragmentShader.Current->RefCount--;
    126       if (ctx->ATIFragmentShader.Current->RefCount <= 0) {
    127          free(ctx->ATIFragmentShader.Current);
    128       }
    129    }
    130 
    131    free((void *) ctx->Program.ErrorString);
    132 }
    133 
    134 
    135 /**
    136  * Update the default program objects in the given context to reference those
    137  * specified in the shared state and release those referencing the old
    138  * shared state.
    139  */
    140 void
    141 _mesa_update_default_objects_program(struct gl_context *ctx)
    142 {
    143    _mesa_reference_program(ctx, &ctx->VertexProgram.Current,
    144                            ctx->Shared->DefaultVertexProgram);
    145    assert(ctx->VertexProgram.Current);
    146 
    147    _mesa_reference_program(ctx, &ctx->FragmentProgram.Current,
    148                             ctx->Shared->DefaultFragmentProgram);
    149    assert(ctx->FragmentProgram.Current);
    150 
    151    /* XXX probably move this stuff */
    152    if (ctx->ATIFragmentShader.Current) {
    153       ctx->ATIFragmentShader.Current->RefCount--;
    154       if (ctx->ATIFragmentShader.Current->RefCount <= 0) {
    155          free(ctx->ATIFragmentShader.Current);
    156       }
    157    }
    158    ctx->ATIFragmentShader.Current = (struct ati_fragment_shader *) ctx->Shared->DefaultFragmentShader;
    159    assert(ctx->ATIFragmentShader.Current);
    160    ctx->ATIFragmentShader.Current->RefCount++;
    161 }
    162 
    163 
    164 /**
    165  * Set the vertex/fragment program error state (position and error string).
    166  * This is generally called from within the parsers.
    167  */
    168 void
    169 _mesa_set_program_error(struct gl_context *ctx, GLint pos, const char *string)
    170 {
    171    ctx->Program.ErrorPos = pos;
    172    free((void *) ctx->Program.ErrorString);
    173    if (!string)
    174       string = "";
    175    ctx->Program.ErrorString = strdup(string);
    176 }
    177 
    178 
    179 /**
    180  * Initialize a new gl_program object.
    181  */
    182 struct gl_program *
    183 _mesa_init_gl_program(struct gl_program *prog, GLenum target, GLuint id,
    184                       bool is_arb_asm)
    185 {
    186    if (!prog)
    187       return NULL;
    188 
    189    memset(prog, 0, sizeof(*prog));
    190    prog->Id = id;
    191    prog->Target = target;
    192    prog->RefCount = 1;
    193    prog->Format = GL_PROGRAM_FORMAT_ASCII_ARB;
    194    prog->info.stage = _mesa_program_enum_to_shader_stage(target);
    195    prog->is_arb_asm = is_arb_asm;
    196 
    197    /* Uniforms that lack an initializer in the shader code have an initial
    198     * value of zero.  This includes sampler uniforms.
    199     *
    200     * Page 24 (page 30 of the PDF) of the GLSL 1.20 spec says:
    201     *
    202     *     "The link time initial value is either the value of the variable's
    203     *     initializer, if present, or 0 if no initializer is present. Sampler
    204     *     types cannot have initializers."
    205     *
    206     * So we only initialise ARB assembly style programs.
    207     */
    208    if (is_arb_asm) {
    209       /* default mapping from samplers to texture units */
    210       for (unsigned i = 0; i < MAX_SAMPLERS; i++)
    211          prog->SamplerUnits[i] = i;
    212    }
    213 
    214    return prog;
    215 }
    216 
    217 
    218 /**
    219  * Allocate and initialize a new fragment/vertex program object but
    220  * don't put it into the program hash table.  Called via
    221  * ctx->Driver.NewProgram.  May be overridden (ie. replaced) by a
    222  * device driver function to implement OO deriviation with additional
    223  * types not understood by this function.
    224  *
    225  * \param ctx  context
    226  * \param id   program id/number
    227  * \param target  program target/type
    228  * \return  pointer to new program object
    229  */
    230 struct gl_program *
    231 _mesa_new_program(struct gl_context *ctx, GLenum target, GLuint id,
    232                   bool is_arb_asm)
    233 {
    234    switch (target) {
    235    case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */
    236    case GL_GEOMETRY_PROGRAM_NV:
    237    case GL_TESS_CONTROL_PROGRAM_NV:
    238    case GL_TESS_EVALUATION_PROGRAM_NV:
    239    case GL_FRAGMENT_PROGRAM_ARB:
    240    case GL_COMPUTE_PROGRAM_NV: {
    241       struct gl_program *prog = rzalloc(NULL, struct gl_program);
    242       return _mesa_init_gl_program(prog, target, id, is_arb_asm);
    243    }
    244    default:
    245       _mesa_problem(ctx, "bad target in _mesa_new_program");
    246       return NULL;
    247    }
    248 }
    249 
    250 
    251 /**
    252  * Delete a program and remove it from the hash table, ignoring the
    253  * reference count.
    254  * Called via ctx->Driver.DeleteProgram.  May be wrapped (OO deriviation)
    255  * by a device driver function.
    256  */
    257 void
    258 _mesa_delete_program(struct gl_context *ctx, struct gl_program *prog)
    259 {
    260    (void) ctx;
    261    assert(prog);
    262    assert(prog->RefCount==0);
    263 
    264    if (prog == &_mesa_DummyProgram)
    265       return;
    266 
    267    if (prog->Parameters) {
    268       _mesa_free_parameter_list(prog->Parameters);
    269    }
    270 
    271    if (prog->nir) {
    272       ralloc_free(prog->nir);
    273    }
    274 
    275    if (prog->sh.BindlessSamplers) {
    276       ralloc_free(prog->sh.BindlessSamplers);
    277    }
    278 
    279    if (prog->sh.BindlessImages) {
    280       ralloc_free(prog->sh.BindlessImages);
    281    }
    282 
    283    if (prog->driver_cache_blob) {
    284       ralloc_free(prog->driver_cache_blob);
    285    }
    286 
    287    ralloc_free(prog);
    288 }
    289 
    290 
    291 /**
    292  * Return the gl_program object for a given ID.
    293  * Basically just a wrapper for _mesa_HashLookup() to avoid a lot of
    294  * casts elsewhere.
    295  */
    296 struct gl_program *
    297 _mesa_lookup_program(struct gl_context *ctx, GLuint id)
    298 {
    299    if (id)
    300       return (struct gl_program *) _mesa_HashLookup(ctx->Shared->Programs, id);
    301    else
    302       return NULL;
    303 }
    304 
    305 
    306 /**
    307  * Reference counting for vertex/fragment programs
    308  * This is normally only called from the _mesa_reference_program() macro
    309  * when there's a real pointer change.
    310  */
    311 void
    312 _mesa_reference_program_(struct gl_context *ctx,
    313                          struct gl_program **ptr,
    314                          struct gl_program *prog)
    315 {
    316 #ifndef NDEBUG
    317    assert(ptr);
    318    if (*ptr && prog) {
    319       /* sanity check */
    320       if ((*ptr)->Target == GL_VERTEX_PROGRAM_ARB)
    321          assert(prog->Target == GL_VERTEX_PROGRAM_ARB);
    322       else if ((*ptr)->Target == GL_FRAGMENT_PROGRAM_ARB)
    323          assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB ||
    324                 prog->Target == GL_FRAGMENT_PROGRAM_NV);
    325       else if ((*ptr)->Target == GL_GEOMETRY_PROGRAM_NV)
    326          assert(prog->Target == GL_GEOMETRY_PROGRAM_NV);
    327    }
    328 #endif
    329 
    330    if (*ptr) {
    331       struct gl_program *oldProg = *ptr;
    332 
    333       assert(oldProg->RefCount > 0);
    334 
    335       if (p_atomic_dec_zero(&oldProg->RefCount)) {
    336          assert(ctx);
    337          _mesa_reference_shader_program_data(ctx, &oldProg->sh.data, NULL);
    338          ctx->Driver.DeleteProgram(ctx, oldProg);
    339       }
    340 
    341       *ptr = NULL;
    342    }
    343 
    344    assert(!*ptr);
    345    if (prog) {
    346       p_atomic_inc(&prog->RefCount);
    347    }
    348 
    349    *ptr = prog;
    350 }
    351 
    352 
    353 /**
    354  * Insert 'count' NOP instructions at 'start' in the given program.
    355  * Adjust branch targets accordingly.
    356  */
    357 GLboolean
    358 _mesa_insert_instructions(struct gl_program *prog, GLuint start, GLuint count)
    359 {
    360    const GLuint origLen = prog->arb.NumInstructions;
    361    const GLuint newLen = origLen + count;
    362    struct prog_instruction *newInst;
    363    GLuint i;
    364 
    365    /* adjust branches */
    366    for (i = 0; i < prog->arb.NumInstructions; i++) {
    367       struct prog_instruction *inst = prog->arb.Instructions + i;
    368       if (inst->BranchTarget > 0) {
    369          if ((GLuint)inst->BranchTarget >= start) {
    370             inst->BranchTarget += count;
    371          }
    372       }
    373    }
    374 
    375    /* Alloc storage for new instructions */
    376    newInst = rzalloc_array(prog, struct prog_instruction, newLen);
    377    if (!newInst) {
    378       return GL_FALSE;
    379    }
    380 
    381    /* Copy 'start' instructions into new instruction buffer */
    382    _mesa_copy_instructions(newInst, prog->arb.Instructions, start);
    383 
    384    /* init the new instructions */
    385    _mesa_init_instructions(newInst + start, count);
    386 
    387    /* Copy the remaining/tail instructions to new inst buffer */
    388    _mesa_copy_instructions(newInst + start + count,
    389                            prog->arb.Instructions + start,
    390                            origLen - start);
    391 
    392    /* free old instructions */
    393    ralloc_free(prog->arb.Instructions);
    394 
    395    /* install new instructions */
    396    prog->arb.Instructions = newInst;
    397    prog->arb.NumInstructions = newLen;
    398 
    399    return GL_TRUE;
    400 }
    401 
    402 /**
    403  * Delete 'count' instructions at 'start' in the given program.
    404  * Adjust branch targets accordingly.
    405  */
    406 GLboolean
    407 _mesa_delete_instructions(struct gl_program *prog, GLuint start, GLuint count,
    408                           void *mem_ctx)
    409 {
    410    const GLuint origLen = prog->arb.NumInstructions;
    411    const GLuint newLen = origLen - count;
    412    struct prog_instruction *newInst;
    413    GLuint i;
    414 
    415    /* adjust branches */
    416    for (i = 0; i < prog->arb.NumInstructions; i++) {
    417       struct prog_instruction *inst = prog->arb.Instructions + i;
    418       if (inst->BranchTarget > 0) {
    419          if (inst->BranchTarget > (GLint) start) {
    420             inst->BranchTarget -= count;
    421          }
    422       }
    423    }
    424 
    425    /* Alloc storage for new instructions */
    426    newInst = rzalloc_array(mem_ctx, struct prog_instruction, newLen);
    427    if (!newInst) {
    428       return GL_FALSE;
    429    }
    430 
    431    /* Copy 'start' instructions into new instruction buffer */
    432    _mesa_copy_instructions(newInst, prog->arb.Instructions, start);
    433 
    434    /* Copy the remaining/tail instructions to new inst buffer */
    435    _mesa_copy_instructions(newInst + start,
    436                            prog->arb.Instructions + start + count,
    437                            newLen - start);
    438 
    439    /* free old instructions */
    440    ralloc_free(prog->arb.Instructions);
    441 
    442    /* install new instructions */
    443    prog->arb.Instructions = newInst;
    444    prog->arb.NumInstructions = newLen;
    445 
    446    return GL_TRUE;
    447 }
    448 
    449 
    450 /**
    451  * Populate the 'used' array with flags indicating which registers (TEMPs,
    452  * INPUTs, OUTPUTs, etc, are used by the given program.
    453  * \param file  type of register to scan for
    454  * \param used  returns true/false flags for in use / free
    455  * \param usedSize  size of the 'used' array
    456  */
    457 void
    458 _mesa_find_used_registers(const struct gl_program *prog,
    459                           gl_register_file file,
    460                           GLboolean used[], GLuint usedSize)
    461 {
    462    GLuint i, j;
    463 
    464    memset(used, 0, usedSize);
    465 
    466    for (i = 0; i < prog->arb.NumInstructions; i++) {
    467       const struct prog_instruction *inst = prog->arb.Instructions + i;
    468       const GLuint n = _mesa_num_inst_src_regs(inst->Opcode);
    469 
    470       if (inst->DstReg.File == file) {
    471          assert(inst->DstReg.Index < usedSize);
    472          if(inst->DstReg.Index < usedSize)
    473             used[inst->DstReg.Index] = GL_TRUE;
    474       }
    475 
    476       for (j = 0; j < n; j++) {
    477          if (inst->SrcReg[j].File == file) {
    478             assert(inst->SrcReg[j].Index < (GLint) usedSize);
    479             if (inst->SrcReg[j].Index < (GLint) usedSize)
    480                used[inst->SrcReg[j].Index] = GL_TRUE;
    481          }
    482       }
    483    }
    484 }
    485 
    486 
    487 /**
    488  * Scan the given 'used' register flag array for the first entry
    489  * that's >= firstReg.
    490  * \param used  vector of flags indicating registers in use (as returned
    491  *              by _mesa_find_used_registers())
    492  * \param usedSize  size of the 'used' array
    493  * \param firstReg  first register to start searching at
    494  * \return index of unused register, or -1 if none.
    495  */
    496 GLint
    497 _mesa_find_free_register(const GLboolean used[],
    498                          GLuint usedSize, GLuint firstReg)
    499 {
    500    GLuint i;
    501 
    502    assert(firstReg < usedSize);
    503 
    504    for (i = firstReg; i < usedSize; i++)
    505       if (!used[i])
    506          return i;
    507 
    508    return -1;
    509 }
    510 
    511 
    512 /* Gets the minimum number of shader invocations per fragment.
    513  * This function is useful to determine if we need to do per
    514  * sample shading or per fragment shading.
    515  */
    516 GLint
    517 _mesa_get_min_invocations_per_fragment(struct gl_context *ctx,
    518                                        const struct gl_program *prog,
    519                                        bool ignore_sample_qualifier)
    520 {
    521    /* From ARB_sample_shading specification:
    522     * "Using gl_SampleID in a fragment shader causes the entire shader
    523     *  to be evaluated per-sample."
    524     *
    525     * "Using gl_SamplePosition in a fragment shader causes the entire
    526     *  shader to be evaluated per-sample."
    527     *
    528     * "If MULTISAMPLE or SAMPLE_SHADING_ARB is disabled, sample shading
    529     *  has no effect."
    530     */
    531    if (ctx->Multisample.Enabled) {
    532       /* The ARB_gpu_shader5 specification says:
    533        *
    534        * "Use of the "sample" qualifier on a fragment shader input
    535        *  forces per-sample shading"
    536        */
    537       if (prog->info.fs.uses_sample_qualifier && !ignore_sample_qualifier)
    538          return MAX2(_mesa_geometric_samples(ctx->DrawBuffer), 1);
    539 
    540       if (prog->info.system_values_read & (SYSTEM_BIT_SAMPLE_ID |
    541                                            SYSTEM_BIT_SAMPLE_POS))
    542          return MAX2(_mesa_geometric_samples(ctx->DrawBuffer), 1);
    543       else if (ctx->Multisample.SampleShading)
    544          return MAX2(ceil(ctx->Multisample.MinSampleShadingValue *
    545                           _mesa_geometric_samples(ctx->DrawBuffer)), 1);
    546       else
    547          return 1;
    548    }
    549    return 1;
    550 }
    551 
    552 
    553 GLbitfield
    554 gl_external_samplers(const struct gl_program *prog)
    555 {
    556    GLbitfield external_samplers = 0;
    557    GLbitfield mask = prog->SamplersUsed;
    558 
    559    while (mask) {
    560       int idx = u_bit_scan(&mask);
    561       if (prog->sh.SamplerTargets[idx] == TEXTURE_EXTERNAL_INDEX)
    562          external_samplers |= (1 << idx);
    563    }
    564 
    565    return external_samplers;
    566 }
    567