Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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/hash.h"
  35. #include "main/macros.h"
  36. #include "program.h"
  37. #include "prog_cache.h"
  38. #include "prog_parameter.h"
  39. #include "prog_instruction.h"
  40. #include "util/ralloc.h"
  41.  
  42.  
  43. /**
  44.  * A pointer to this dummy program is put into the hash table when
  45.  * glGenPrograms is called.
  46.  */
  47. struct gl_program _mesa_DummyProgram;
  48.  
  49.  
  50. /**
  51.  * Init context's vertex/fragment program state
  52.  */
  53. void
  54. _mesa_init_program(struct gl_context *ctx)
  55. {
  56.    /*
  57.     * If this assertion fails, we need to increase the field
  58.     * size for register indexes (see INST_INDEX_BITS).
  59.     */
  60.    assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents / 4
  61.           <= (1 << INST_INDEX_BITS));
  62.    assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents / 4
  63.           <= (1 << INST_INDEX_BITS));
  64.  
  65.    assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxTemps <= (1 << INST_INDEX_BITS));
  66.    assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxLocalParams <= (1 << INST_INDEX_BITS));
  67.    assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTemps <= (1 << INST_INDEX_BITS));
  68.    assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxLocalParams <= (1 << INST_INDEX_BITS));
  69.  
  70.    assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents <= 4 * MAX_UNIFORMS);
  71.    assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents <= 4 * MAX_UNIFORMS);
  72.  
  73.    assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxAddressOffset <= (1 << INST_INDEX_BITS));
  74.    assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxAddressOffset <= (1 << INST_INDEX_BITS));
  75.  
  76.    /* If this fails, increase prog_instruction::TexSrcUnit size */
  77.    STATIC_ASSERT(MAX_TEXTURE_UNITS <= (1 << 5));
  78.  
  79.    /* If this fails, increase prog_instruction::TexSrcTarget size */
  80.    STATIC_ASSERT(NUM_TEXTURE_TARGETS <= (1 << 4));
  81.  
  82.    ctx->Program.ErrorPos = -1;
  83.    ctx->Program.ErrorString = strdup("");
  84.  
  85.    ctx->VertexProgram.Enabled = GL_FALSE;
  86.    ctx->VertexProgram.PointSizeEnabled =
  87.       (ctx->API == API_OPENGLES2) ? GL_TRUE : GL_FALSE;
  88.    ctx->VertexProgram.TwoSideEnabled = GL_FALSE;
  89.    _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
  90.                             ctx->Shared->DefaultVertexProgram);
  91.    assert(ctx->VertexProgram.Current);
  92.    ctx->VertexProgram.Cache = _mesa_new_program_cache();
  93.  
  94.    ctx->FragmentProgram.Enabled = GL_FALSE;
  95.    _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
  96.                             ctx->Shared->DefaultFragmentProgram);
  97.    assert(ctx->FragmentProgram.Current);
  98.    ctx->FragmentProgram.Cache = _mesa_new_program_cache();
  99.  
  100.    ctx->GeometryProgram.Enabled = GL_FALSE;
  101.    /* right now by default we don't have a geometry program */
  102.    _mesa_reference_geomprog(ctx, &ctx->GeometryProgram.Current,
  103.                             NULL);
  104.  
  105.    _mesa_reference_compprog(ctx, &ctx->ComputeProgram.Current, NULL);
  106.  
  107.    /* XXX probably move this stuff */
  108.    ctx->ATIFragmentShader.Enabled = GL_FALSE;
  109.    ctx->ATIFragmentShader.Current = ctx->Shared->DefaultFragmentShader;
  110.    assert(ctx->ATIFragmentShader.Current);
  111.    ctx->ATIFragmentShader.Current->RefCount++;
  112. }
  113.  
  114.  
  115. /**
  116.  * Free a context's vertex/fragment program state
  117.  */
  118. void
  119. _mesa_free_program_data(struct gl_context *ctx)
  120. {
  121.    _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL);
  122.    _mesa_delete_program_cache(ctx, ctx->VertexProgram.Cache);
  123.    _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
  124.    _mesa_delete_shader_cache(ctx, ctx->FragmentProgram.Cache);
  125.    _mesa_reference_geomprog(ctx, &ctx->GeometryProgram.Current, NULL);
  126.    _mesa_reference_compprog(ctx, &ctx->ComputeProgram.Current, NULL);
  127.  
  128.    /* XXX probably move this stuff */
  129.    if (ctx->ATIFragmentShader.Current) {
  130.       ctx->ATIFragmentShader.Current->RefCount--;
  131.       if (ctx->ATIFragmentShader.Current->RefCount <= 0) {
  132.          free(ctx->ATIFragmentShader.Current);
  133.       }
  134.    }
  135.  
  136.    free((void *) ctx->Program.ErrorString);
  137. }
  138.  
  139.  
  140. /**
  141.  * Update the default program objects in the given context to reference those
  142.  * specified in the shared state and release those referencing the old
  143.  * shared state.
  144.  */
  145. void
  146. _mesa_update_default_objects_program(struct gl_context *ctx)
  147. {
  148.    _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
  149.                             ctx->Shared->DefaultVertexProgram);
  150.    assert(ctx->VertexProgram.Current);
  151.  
  152.    _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
  153.                             ctx->Shared->DefaultFragmentProgram);
  154.    assert(ctx->FragmentProgram.Current);
  155.  
  156.    _mesa_reference_geomprog(ctx, &ctx->GeometryProgram.Current,
  157.                       ctx->Shared->DefaultGeometryProgram);
  158.  
  159.    /* XXX probably move this stuff */
  160.    if (ctx->ATIFragmentShader.Current) {
  161.       ctx->ATIFragmentShader.Current->RefCount--;
  162.       if (ctx->ATIFragmentShader.Current->RefCount <= 0) {
  163.          free(ctx->ATIFragmentShader.Current);
  164.       }
  165.    }
  166.    ctx->ATIFragmentShader.Current = (struct ati_fragment_shader *) ctx->Shared->DefaultFragmentShader;
  167.    assert(ctx->ATIFragmentShader.Current);
  168.    ctx->ATIFragmentShader.Current->RefCount++;
  169. }
  170.  
  171.  
  172. /**
  173.  * Set the vertex/fragment program error state (position and error string).
  174.  * This is generally called from within the parsers.
  175.  */
  176. void
  177. _mesa_set_program_error(struct gl_context *ctx, GLint pos, const char *string)
  178. {
  179.    ctx->Program.ErrorPos = pos;
  180.    free((void *) ctx->Program.ErrorString);
  181.    if (!string)
  182.       string = "";
  183.    ctx->Program.ErrorString = strdup(string);
  184. }
  185.  
  186.  
  187. /**
  188.  * Find the line number and column for 'pos' within 'string'.
  189.  * Return a copy of the line which contains 'pos'.  Free the line with
  190.  * free().
  191.  * \param string  the program string
  192.  * \param pos     the position within the string
  193.  * \param line    returns the line number corresponding to 'pos'.
  194.  * \param col     returns the column number corresponding to 'pos'.
  195.  * \return copy of the line containing 'pos'.
  196.  */
  197. const GLubyte *
  198. _mesa_find_line_column(const GLubyte *string, const GLubyte *pos,
  199.                        GLint *line, GLint *col)
  200. {
  201.    const GLubyte *lineStart = string;
  202.    const GLubyte *p = string;
  203.    GLubyte *s;
  204.    int len;
  205.  
  206.    *line = 1;
  207.  
  208.    while (p != pos) {
  209.       if (*p == (GLubyte) '\n') {
  210.          (*line)++;
  211.          lineStart = p + 1;
  212.       }
  213.       p++;
  214.    }
  215.  
  216.    *col = (pos - lineStart) + 1;
  217.  
  218.    /* return copy of this line */
  219.    while (*p != 0 && *p != '\n')
  220.       p++;
  221.    len = p - lineStart;
  222.    s = malloc(len + 1);
  223.    memcpy(s, lineStart, len);
  224.    s[len] = 0;
  225.  
  226.    return s;
  227. }
  228.  
  229.  
  230. /**
  231.  * Initialize a new gl_program object.
  232.  */
  233. static void
  234. init_program_struct(struct gl_program *prog, GLenum target, GLuint id)
  235. {
  236.    GLuint i;
  237.  
  238.    assert(prog);
  239.  
  240.    memset(prog, 0, sizeof(*prog));
  241.    prog->Id = id;
  242.    prog->Target = target;
  243.    prog->RefCount = 1;
  244.    prog->Format = GL_PROGRAM_FORMAT_ASCII_ARB;
  245.  
  246.    /* default mapping from samplers to texture units */
  247.    for (i = 0; i < MAX_SAMPLERS; i++)
  248.       prog->SamplerUnits[i] = i;
  249. }
  250.  
  251.  
  252. /**
  253.  * Initialize a new fragment program object.
  254.  */
  255. struct gl_program *
  256. _mesa_init_fragment_program(struct gl_context *ctx,
  257.                             struct gl_fragment_program *prog,
  258.                             GLenum target, GLuint id)
  259. {
  260.    if (prog) {
  261.       init_program_struct(&prog->Base, target, id);
  262.       return &prog->Base;
  263.    }
  264.    return NULL;
  265. }
  266.  
  267.  
  268. /**
  269.  * Initialize a new vertex program object.
  270.  */
  271. struct gl_program *
  272. _mesa_init_vertex_program(struct gl_context *ctx,
  273.                           struct gl_vertex_program *prog,
  274.                           GLenum target, GLuint id)
  275. {
  276.    if (prog) {
  277.       init_program_struct(&prog->Base, target, id);
  278.       return &prog->Base;
  279.    }
  280.    return NULL;
  281. }
  282.  
  283.  
  284. /**
  285.  * Initialize a new compute program object.
  286.  */
  287. struct gl_program *
  288. _mesa_init_compute_program(struct gl_context *ctx,
  289.                            struct gl_compute_program *prog,
  290.                            GLenum target, GLuint id)
  291. {
  292.    if (prog) {
  293.       init_program_struct(&prog->Base, target, id);
  294.       return &prog->Base;
  295.    }
  296.    return NULL;
  297. }
  298.  
  299.  
  300. /**
  301.  * Initialize a new geometry program object.
  302.  */
  303. struct gl_program *
  304. _mesa_init_geometry_program(struct gl_context *ctx,
  305.                             struct gl_geometry_program *prog,
  306.                             GLenum target, GLuint id)
  307. {
  308.    if (prog) {
  309.       init_program_struct(&prog->Base, target, id);
  310.       return &prog->Base;
  311.    }
  312.    return NULL;
  313. }
  314.  
  315.  
  316. /**
  317.  * Allocate and initialize a new fragment/vertex program object but
  318.  * don't put it into the program hash table.  Called via
  319.  * ctx->Driver.NewProgram.  May be overridden (ie. replaced) by a
  320.  * device driver function to implement OO deriviation with additional
  321.  * types not understood by this function.
  322.  *
  323.  * \param ctx  context
  324.  * \param id   program id/number
  325.  * \param target  program target/type
  326.  * \return  pointer to new program object
  327.  */
  328. struct gl_program *
  329. _mesa_new_program(struct gl_context *ctx, GLenum target, GLuint id)
  330. {
  331.    struct gl_program *prog;
  332.    switch (target) {
  333.    case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */
  334.       prog = _mesa_init_vertex_program(ctx, CALLOC_STRUCT(gl_vertex_program),
  335.                                        target, id );
  336.       break;
  337.    case GL_FRAGMENT_PROGRAM_NV:
  338.    case GL_FRAGMENT_PROGRAM_ARB:
  339.       prog =_mesa_init_fragment_program(ctx,
  340.                                          CALLOC_STRUCT(gl_fragment_program),
  341.                                          target, id );
  342.       break;
  343.    case MESA_GEOMETRY_PROGRAM:
  344.       prog = _mesa_init_geometry_program(ctx,
  345.                                          CALLOC_STRUCT(gl_geometry_program),
  346.                                          target, id);
  347.       break;
  348.    case GL_COMPUTE_PROGRAM_NV:
  349.       prog = _mesa_init_compute_program(ctx,
  350.                                         CALLOC_STRUCT(gl_compute_program),
  351.                                         target, id);
  352.       break;
  353.    default:
  354.       _mesa_problem(ctx, "bad target in _mesa_new_program");
  355.       prog = NULL;
  356.    }
  357.    return prog;
  358. }
  359.  
  360.  
  361. /**
  362.  * Delete a program and remove it from the hash table, ignoring the
  363.  * reference count.
  364.  * Called via ctx->Driver.DeleteProgram.  May be wrapped (OO deriviation)
  365.  * by a device driver function.
  366.  */
  367. void
  368. _mesa_delete_program(struct gl_context *ctx, struct gl_program *prog)
  369. {
  370.    (void) ctx;
  371.    assert(prog);
  372.    assert(prog->RefCount==0);
  373.  
  374.    if (prog == &_mesa_DummyProgram)
  375.       return;
  376.  
  377.    free(prog->String);
  378.    free(prog->LocalParams);
  379.  
  380.    if (prog->Instructions) {
  381.       _mesa_free_instructions(prog->Instructions, prog->NumInstructions);
  382.    }
  383.    if (prog->Parameters) {
  384.       _mesa_free_parameter_list(prog->Parameters);
  385.    }
  386.  
  387.    if (prog->nir) {
  388.       ralloc_free(prog->nir);
  389.    }
  390.  
  391.    free(prog);
  392. }
  393.  
  394.  
  395. /**
  396.  * Return the gl_program object for a given ID.
  397.  * Basically just a wrapper for _mesa_HashLookup() to avoid a lot of
  398.  * casts elsewhere.
  399.  */
  400. struct gl_program *
  401. _mesa_lookup_program(struct gl_context *ctx, GLuint id)
  402. {
  403.    if (id)
  404.       return (struct gl_program *) _mesa_HashLookup(ctx->Shared->Programs, id);
  405.    else
  406.       return NULL;
  407. }
  408.  
  409.  
  410. /**
  411.  * Reference counting for vertex/fragment programs
  412.  * This is normally only called from the _mesa_reference_program() macro
  413.  * when there's a real pointer change.
  414.  */
  415. void
  416. _mesa_reference_program_(struct gl_context *ctx,
  417.                          struct gl_program **ptr,
  418.                          struct gl_program *prog)
  419. {
  420. #ifndef NDEBUG
  421.    assert(ptr);
  422.    if (*ptr && prog) {
  423.       /* sanity check */
  424.       if ((*ptr)->Target == GL_VERTEX_PROGRAM_ARB)
  425.          assert(prog->Target == GL_VERTEX_PROGRAM_ARB);
  426.       else if ((*ptr)->Target == GL_FRAGMENT_PROGRAM_ARB)
  427.          assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB ||
  428.                 prog->Target == GL_FRAGMENT_PROGRAM_NV);
  429.       else if ((*ptr)->Target == MESA_GEOMETRY_PROGRAM)
  430.          assert(prog->Target == MESA_GEOMETRY_PROGRAM);
  431.    }
  432. #endif
  433.  
  434.    if (*ptr) {
  435.       GLboolean deleteFlag;
  436.  
  437.       /*mtx_lock(&(*ptr)->Mutex);*/
  438. #if 0
  439.       printf("Program %p ID=%u Target=%s  Refcount-- to %d\n",
  440.              *ptr, (*ptr)->Id,
  441.              ((*ptr)->Target == GL_VERTEX_PROGRAM_ARB ? "VP" :
  442.               ((*ptr)->Target == MESA_GEOMETRY_PROGRAM ? "GP" : "FP")),
  443.              (*ptr)->RefCount - 1);
  444. #endif
  445.       assert((*ptr)->RefCount > 0);
  446.       (*ptr)->RefCount--;
  447.  
  448.       deleteFlag = ((*ptr)->RefCount == 0);
  449.       /*mtx_lock(&(*ptr)->Mutex);*/
  450.  
  451.       if (deleteFlag) {
  452.          assert(ctx);
  453.          ctx->Driver.DeleteProgram(ctx, *ptr);
  454.       }
  455.  
  456.       *ptr = NULL;
  457.    }
  458.  
  459.    assert(!*ptr);
  460.    if (prog) {
  461.       /*mtx_lock(&prog->Mutex);*/
  462.       prog->RefCount++;
  463. #if 0
  464.       printf("Program %p ID=%u Target=%s  Refcount++ to %d\n",
  465.              prog, prog->Id,
  466.              (prog->Target == GL_VERTEX_PROGRAM_ARB ? "VP" :
  467.               (prog->Target == MESA_GEOMETRY_PROGRAM ? "GP" : "FP")),
  468.              prog->RefCount);
  469. #endif
  470.       /*mtx_unlock(&prog->Mutex);*/
  471.    }
  472.  
  473.    *ptr = prog;
  474. }
  475.  
  476.  
  477. /**
  478.  * Return a copy of a program.
  479.  * XXX Problem here if the program object is actually OO-derivation
  480.  * made by a device driver.
  481.  */
  482. struct gl_program *
  483. _mesa_clone_program(struct gl_context *ctx, const struct gl_program *prog)
  484. {
  485.    struct gl_program *clone;
  486.  
  487.    clone = ctx->Driver.NewProgram(ctx, prog->Target, prog->Id);
  488.    if (!clone)
  489.       return NULL;
  490.  
  491.    assert(clone->Target == prog->Target);
  492.    assert(clone->RefCount == 1);
  493.  
  494.    clone->String = (GLubyte *) strdup((char *) prog->String);
  495.    clone->Format = prog->Format;
  496.    clone->Instructions = _mesa_alloc_instructions(prog->NumInstructions);
  497.    if (!clone->Instructions) {
  498.       _mesa_reference_program(ctx, &clone, NULL);
  499.       return NULL;
  500.    }
  501.    _mesa_copy_instructions(clone->Instructions, prog->Instructions,
  502.                            prog->NumInstructions);
  503.    clone->InputsRead = prog->InputsRead;
  504.    clone->OutputsWritten = prog->OutputsWritten;
  505.    clone->SamplersUsed = prog->SamplersUsed;
  506.    clone->ShadowSamplers = prog->ShadowSamplers;
  507.    memcpy(clone->TexturesUsed, prog->TexturesUsed, sizeof(prog->TexturesUsed));
  508.  
  509.    if (prog->Parameters)
  510.       clone->Parameters = _mesa_clone_parameter_list(prog->Parameters);
  511.    if (prog->LocalParams) {
  512.       clone->LocalParams = malloc(MAX_PROGRAM_LOCAL_PARAMS *
  513.                                   sizeof(float[4]));
  514.       if (!clone->LocalParams) {
  515.          _mesa_reference_program(ctx, &clone, NULL);
  516.          return NULL;
  517.       }
  518.       memcpy(clone->LocalParams, prog->LocalParams,
  519.              MAX_PROGRAM_LOCAL_PARAMS * sizeof(float[4]));
  520.    }
  521.    clone->IndirectRegisterFiles = prog->IndirectRegisterFiles;
  522.    clone->NumInstructions = prog->NumInstructions;
  523.    clone->NumTemporaries = prog->NumTemporaries;
  524.    clone->NumParameters = prog->NumParameters;
  525.    clone->NumAttributes = prog->NumAttributes;
  526.    clone->NumAddressRegs = prog->NumAddressRegs;
  527.    clone->NumNativeInstructions = prog->NumNativeInstructions;
  528.    clone->NumNativeTemporaries = prog->NumNativeTemporaries;
  529.    clone->NumNativeParameters = prog->NumNativeParameters;
  530.    clone->NumNativeAttributes = prog->NumNativeAttributes;
  531.    clone->NumNativeAddressRegs = prog->NumNativeAddressRegs;
  532.    clone->NumAluInstructions = prog->NumAluInstructions;
  533.    clone->NumTexInstructions = prog->NumTexInstructions;
  534.    clone->NumTexIndirections = prog->NumTexIndirections;
  535.    clone->NumNativeAluInstructions = prog->NumNativeAluInstructions;
  536.    clone->NumNativeTexInstructions = prog->NumNativeTexInstructions;
  537.    clone->NumNativeTexIndirections = prog->NumNativeTexIndirections;
  538.  
  539.    switch (prog->Target) {
  540.    case GL_VERTEX_PROGRAM_ARB:
  541.       {
  542.          const struct gl_vertex_program *vp = gl_vertex_program_const(prog);
  543.          struct gl_vertex_program *vpc = gl_vertex_program(clone);
  544.          vpc->IsPositionInvariant = vp->IsPositionInvariant;
  545.       }
  546.       break;
  547.    case GL_FRAGMENT_PROGRAM_ARB:
  548.       {
  549.          const struct gl_fragment_program *fp = gl_fragment_program_const(prog);
  550.          struct gl_fragment_program *fpc = gl_fragment_program(clone);
  551.          fpc->UsesKill = fp->UsesKill;
  552.          fpc->UsesDFdy = fp->UsesDFdy;
  553.          fpc->OriginUpperLeft = fp->OriginUpperLeft;
  554.          fpc->PixelCenterInteger = fp->PixelCenterInteger;
  555.       }
  556.       break;
  557.    case MESA_GEOMETRY_PROGRAM:
  558.       {
  559.          const struct gl_geometry_program *gp = gl_geometry_program_const(prog);
  560.          struct gl_geometry_program *gpc = gl_geometry_program(clone);
  561.          gpc->VerticesOut = gp->VerticesOut;
  562.          gpc->InputType = gp->InputType;
  563.          gpc->Invocations = gp->Invocations;
  564.          gpc->OutputType = gp->OutputType;
  565.          gpc->UsesEndPrimitive = gp->UsesEndPrimitive;
  566.          gpc->UsesStreams = gp->UsesStreams;
  567.       }
  568.       break;
  569.    default:
  570.       _mesa_problem(NULL, "Unexpected target in _mesa_clone_program");
  571.    }
  572.  
  573.    return clone;
  574. }
  575.  
  576.  
  577. /**
  578.  * Insert 'count' NOP instructions at 'start' in the given program.
  579.  * Adjust branch targets accordingly.
  580.  */
  581. GLboolean
  582. _mesa_insert_instructions(struct gl_program *prog, GLuint start, GLuint count)
  583. {
  584.    const GLuint origLen = prog->NumInstructions;
  585.    const GLuint newLen = origLen + count;
  586.    struct prog_instruction *newInst;
  587.    GLuint i;
  588.  
  589.    /* adjust branches */
  590.    for (i = 0; i < prog->NumInstructions; i++) {
  591.       struct prog_instruction *inst = prog->Instructions + i;
  592.       if (inst->BranchTarget > 0) {
  593.          if ((GLuint)inst->BranchTarget >= start) {
  594.             inst->BranchTarget += count;
  595.          }
  596.       }
  597.    }
  598.  
  599.    /* Alloc storage for new instructions */
  600.    newInst = _mesa_alloc_instructions(newLen);
  601.    if (!newInst) {
  602.       return GL_FALSE;
  603.    }
  604.  
  605.    /* Copy 'start' instructions into new instruction buffer */
  606.    _mesa_copy_instructions(newInst, prog->Instructions, start);
  607.  
  608.    /* init the new instructions */
  609.    _mesa_init_instructions(newInst + start, count);
  610.  
  611.    /* Copy the remaining/tail instructions to new inst buffer */
  612.    _mesa_copy_instructions(newInst + start + count,
  613.                            prog->Instructions + start,
  614.                            origLen - start);
  615.  
  616.    /* free old instructions */
  617.    _mesa_free_instructions(prog->Instructions, origLen);
  618.  
  619.    /* install new instructions */
  620.    prog->Instructions = newInst;
  621.    prog->NumInstructions = newLen;
  622.  
  623.    return GL_TRUE;
  624. }
  625.  
  626. /**
  627.  * Delete 'count' instructions at 'start' in the given program.
  628.  * Adjust branch targets accordingly.
  629.  */
  630. GLboolean
  631. _mesa_delete_instructions(struct gl_program *prog, GLuint start, GLuint count)
  632. {
  633.    const GLuint origLen = prog->NumInstructions;
  634.    const GLuint newLen = origLen - count;
  635.    struct prog_instruction *newInst;
  636.    GLuint i;
  637.  
  638.    /* adjust branches */
  639.    for (i = 0; i < prog->NumInstructions; i++) {
  640.       struct prog_instruction *inst = prog->Instructions + i;
  641.       if (inst->BranchTarget > 0) {
  642.          if (inst->BranchTarget > (GLint) start) {
  643.             inst->BranchTarget -= count;
  644.          }
  645.       }
  646.    }
  647.  
  648.    /* Alloc storage for new instructions */
  649.    newInst = _mesa_alloc_instructions(newLen);
  650.    if (!newInst) {
  651.       return GL_FALSE;
  652.    }
  653.  
  654.    /* Copy 'start' instructions into new instruction buffer */
  655.    _mesa_copy_instructions(newInst, prog->Instructions, start);
  656.  
  657.    /* Copy the remaining/tail instructions to new inst buffer */
  658.    _mesa_copy_instructions(newInst + start,
  659.                            prog->Instructions + start + count,
  660.                            newLen - start);
  661.  
  662.    /* free old instructions */
  663.    _mesa_free_instructions(prog->Instructions, origLen);
  664.  
  665.    /* install new instructions */
  666.    prog->Instructions = newInst;
  667.    prog->NumInstructions = newLen;
  668.  
  669.    return GL_TRUE;
  670. }
  671.  
  672.  
  673. /**
  674.  * Search instructions for registers that match (oldFile, oldIndex),
  675.  * replacing them with (newFile, newIndex).
  676.  */
  677. static void
  678. replace_registers(struct prog_instruction *inst, GLuint numInst,
  679.                   GLuint oldFile, GLuint oldIndex,
  680.                   GLuint newFile, GLuint newIndex)
  681. {
  682.    GLuint i, j;
  683.    for (i = 0; i < numInst; i++) {
  684.       /* src regs */
  685.       for (j = 0; j < _mesa_num_inst_src_regs(inst[i].Opcode); j++) {
  686.          if (inst[i].SrcReg[j].File == oldFile &&
  687.              inst[i].SrcReg[j].Index == oldIndex) {
  688.             inst[i].SrcReg[j].File = newFile;
  689.             inst[i].SrcReg[j].Index = newIndex;
  690.          }
  691.       }
  692.       /* dst reg */
  693.       if (inst[i].DstReg.File == oldFile && inst[i].DstReg.Index == oldIndex) {
  694.          inst[i].DstReg.File = newFile;
  695.          inst[i].DstReg.Index = newIndex;
  696.       }
  697.    }
  698. }
  699.  
  700.  
  701. /**
  702.  * Search instructions for references to program parameters.  When found,
  703.  * increment the parameter index by 'offset'.
  704.  * Used when combining programs.
  705.  */
  706. static void
  707. adjust_param_indexes(struct prog_instruction *inst, GLuint numInst,
  708.                      GLuint offset)
  709. {
  710.    GLuint i, j;
  711.    for (i = 0; i < numInst; i++) {
  712.       for (j = 0; j < _mesa_num_inst_src_regs(inst[i].Opcode); j++) {
  713.          GLuint f = inst[i].SrcReg[j].File;
  714.          if (f == PROGRAM_CONSTANT ||
  715.              f == PROGRAM_UNIFORM ||
  716.              f == PROGRAM_STATE_VAR) {
  717.             inst[i].SrcReg[j].Index += offset;
  718.          }
  719.       }
  720.    }
  721. }
  722.  
  723.  
  724. /**
  725.  * Combine two programs into one.  Fix instructions so the outputs of
  726.  * the first program go to the inputs of the second program.
  727.  */
  728. struct gl_program *
  729. _mesa_combine_programs(struct gl_context *ctx,
  730.                        const struct gl_program *progA,
  731.                        const struct gl_program *progB)
  732. {
  733.    struct prog_instruction *newInst;
  734.    struct gl_program *newProg;
  735.    const GLuint lenA = progA->NumInstructions - 1; /* omit END instr */
  736.    const GLuint lenB = progB->NumInstructions;
  737.    const GLuint numParamsA = _mesa_num_parameters(progA->Parameters);
  738.    const GLuint newLength = lenA + lenB;
  739.    GLboolean usedTemps[MAX_PROGRAM_TEMPS];
  740.    GLuint firstTemp = 0;
  741.    GLbitfield64 inputsB;
  742.    GLuint i;
  743.  
  744.    assert(progA->Target == progB->Target);
  745.  
  746.    newInst = _mesa_alloc_instructions(newLength);
  747.    if (!newInst)
  748.       return GL_FALSE;
  749.  
  750.    _mesa_copy_instructions(newInst, progA->Instructions, lenA);
  751.    _mesa_copy_instructions(newInst + lenA, progB->Instructions, lenB);
  752.  
  753.    /* adjust branch / instruction addresses for B's instructions */
  754.    for (i = 0; i < lenB; i++) {
  755.       newInst[lenA + i].BranchTarget += lenA;
  756.    }
  757.  
  758.    newProg = ctx->Driver.NewProgram(ctx, progA->Target, 0);
  759.    newProg->Instructions = newInst;
  760.    newProg->NumInstructions = newLength;
  761.  
  762.    /* find used temp regs (we may need new temps below) */
  763.    _mesa_find_used_registers(newProg, PROGRAM_TEMPORARY,
  764.                              usedTemps, MAX_PROGRAM_TEMPS);
  765.  
  766.    if (newProg->Target == GL_FRAGMENT_PROGRAM_ARB) {
  767.       const struct gl_fragment_program *fprogA, *fprogB;
  768.       struct gl_fragment_program *newFprog;
  769.       GLbitfield64 progB_inputsRead = progB->InputsRead;
  770.       GLint progB_colorFile, progB_colorIndex;
  771.  
  772.       fprogA = gl_fragment_program_const(progA);
  773.       fprogB = gl_fragment_program_const(progB);
  774.       newFprog = gl_fragment_program(newProg);
  775.  
  776.       newFprog->UsesKill = fprogA->UsesKill || fprogB->UsesKill;
  777.       newFprog->UsesDFdy = fprogA->UsesDFdy || fprogB->UsesDFdy;
  778.  
  779.       /* We'll do a search and replace for instances
  780.        * of progB_colorFile/progB_colorIndex below...
  781.        */
  782.       progB_colorFile = PROGRAM_INPUT;
  783.       progB_colorIndex = VARYING_SLOT_COL0;
  784.  
  785.       /*
  786.        * The fragment program may get color from a state var rather than
  787.        * a fragment input (vertex output) if it's constant.
  788.        * See the texenvprogram.c code.
  789.        * So, search the program's parameter list now to see if the program
  790.        * gets color from a state var instead of a conventional fragment
  791.        * input register.
  792.        */
  793.       for (i = 0; i < progB->Parameters->NumParameters; i++) {
  794.          struct gl_program_parameter *p = &progB->Parameters->Parameters[i];
  795.          if (p->Type == PROGRAM_STATE_VAR &&
  796.              p->StateIndexes[0] == STATE_INTERNAL &&
  797.              p->StateIndexes[1] == STATE_CURRENT_ATTRIB &&
  798.              (int) p->StateIndexes[2] == (int) VERT_ATTRIB_COLOR0) {
  799.             progB_inputsRead |= VARYING_BIT_COL0;
  800.             progB_colorFile = PROGRAM_STATE_VAR;
  801.             progB_colorIndex = i;
  802.             break;
  803.          }
  804.       }
  805.  
  806.       /* Connect color outputs of fprogA to color inputs of fprogB, via a
  807.        * new temporary register.
  808.        */
  809.       if ((progA->OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_COLOR)) &&
  810.           (progB_inputsRead & VARYING_BIT_COL0)) {
  811.          GLint tempReg = _mesa_find_free_register(usedTemps, MAX_PROGRAM_TEMPS,
  812.                                                   firstTemp);
  813.          if (tempReg < 0) {
  814.             _mesa_problem(ctx, "No free temp regs found in "
  815.                           "_mesa_combine_programs(), using 31");
  816.             tempReg = 31;
  817.          }
  818.          firstTemp = tempReg + 1;
  819.  
  820.          /* replace writes to result.color[0] with tempReg */
  821.          replace_registers(newInst, lenA,
  822.                            PROGRAM_OUTPUT, FRAG_RESULT_COLOR,
  823.                            PROGRAM_TEMPORARY, tempReg);
  824.          /* replace reads from the input color with tempReg */
  825.          replace_registers(newInst + lenA, lenB,
  826.                            progB_colorFile, progB_colorIndex, /* search for */
  827.                            PROGRAM_TEMPORARY, tempReg  /* replace with */ );
  828.       }
  829.  
  830.       /* compute combined program's InputsRead */
  831.       inputsB = progB_inputsRead;
  832.       if (progA->OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_COLOR)) {
  833.          inputsB &= ~(1 << VARYING_SLOT_COL0);
  834.       }
  835.       newProg->InputsRead = progA->InputsRead | inputsB;
  836.       newProg->OutputsWritten = progB->OutputsWritten;
  837.       newProg->SamplersUsed = progA->SamplersUsed | progB->SamplersUsed;
  838.    }
  839.    else {
  840.       /* vertex program */
  841.       assert(0);      /* XXX todo */
  842.    }
  843.  
  844.    /*
  845.     * Merge parameters (uniforms, constants, etc)
  846.     */
  847.    newProg->Parameters = _mesa_combine_parameter_lists(progA->Parameters,
  848.                                                        progB->Parameters);
  849.  
  850.    adjust_param_indexes(newInst + lenA, lenB, numParamsA);
  851.  
  852.  
  853.    return newProg;
  854. }
  855.  
  856.  
  857. /**
  858.  * Populate the 'used' array with flags indicating which registers (TEMPs,
  859.  * INPUTs, OUTPUTs, etc, are used by the given program.
  860.  * \param file  type of register to scan for
  861.  * \param used  returns true/false flags for in use / free
  862.  * \param usedSize  size of the 'used' array
  863.  */
  864. void
  865. _mesa_find_used_registers(const struct gl_program *prog,
  866.                           gl_register_file file,
  867.                           GLboolean used[], GLuint usedSize)
  868. {
  869.    GLuint i, j;
  870.  
  871.    memset(used, 0, usedSize);
  872.  
  873.    for (i = 0; i < prog->NumInstructions; i++) {
  874.       const struct prog_instruction *inst = prog->Instructions + i;
  875.       const GLuint n = _mesa_num_inst_src_regs(inst->Opcode);
  876.  
  877.       if (inst->DstReg.File == file) {
  878.          assert(inst->DstReg.Index < usedSize);
  879.          if(inst->DstReg.Index < usedSize)
  880.             used[inst->DstReg.Index] = GL_TRUE;
  881.       }
  882.  
  883.       for (j = 0; j < n; j++) {
  884.          if (inst->SrcReg[j].File == file) {
  885.             assert(inst->SrcReg[j].Index < (GLint) usedSize);
  886.             if (inst->SrcReg[j].Index < (GLint) usedSize)
  887.                used[inst->SrcReg[j].Index] = GL_TRUE;
  888.          }
  889.       }
  890.    }
  891. }
  892.  
  893.  
  894. /**
  895.  * Scan the given 'used' register flag array for the first entry
  896.  * that's >= firstReg.
  897.  * \param used  vector of flags indicating registers in use (as returned
  898.  *              by _mesa_find_used_registers())
  899.  * \param usedSize  size of the 'used' array
  900.  * \param firstReg  first register to start searching at
  901.  * \return index of unused register, or -1 if none.
  902.  */
  903. GLint
  904. _mesa_find_free_register(const GLboolean used[],
  905.                          GLuint usedSize, GLuint firstReg)
  906. {
  907.    GLuint i;
  908.  
  909.    assert(firstReg < usedSize);
  910.  
  911.    for (i = firstReg; i < usedSize; i++)
  912.       if (!used[i])
  913.          return i;
  914.  
  915.    return -1;
  916. }
  917.  
  918.  
  919.  
  920. /**
  921.  * Check if the given register index is valid (doesn't exceed implementation-
  922.  * dependent limits).
  923.  * \return GL_TRUE if OK, GL_FALSE if bad index
  924.  */
  925. GLboolean
  926. _mesa_valid_register_index(const struct gl_context *ctx,
  927.                            gl_shader_stage shaderType,
  928.                            gl_register_file file, GLint index)
  929. {
  930.    const struct gl_program_constants *c;
  931.  
  932.    assert(0 <= shaderType && shaderType < MESA_SHADER_STAGES);
  933.    c = &ctx->Const.Program[shaderType];
  934.  
  935.    switch (file) {
  936.    case PROGRAM_UNDEFINED:
  937.       return GL_TRUE;  /* XXX or maybe false? */
  938.  
  939.    case PROGRAM_TEMPORARY:
  940.       return index >= 0 && index < (GLint) c->MaxTemps;
  941.  
  942.    case PROGRAM_UNIFORM:
  943.    case PROGRAM_STATE_VAR:
  944.       /* aka constant buffer */
  945.       return index >= 0 && index < (GLint) c->MaxUniformComponents / 4;
  946.  
  947.    case PROGRAM_CONSTANT:
  948.       /* constant buffer w/ possible relative negative addressing */
  949.       return (index > (int) c->MaxUniformComponents / -4 &&
  950.               index < (int) c->MaxUniformComponents / 4);
  951.  
  952.    case PROGRAM_INPUT:
  953.       if (index < 0)
  954.          return GL_FALSE;
  955.  
  956.       switch (shaderType) {
  957.       case MESA_SHADER_VERTEX:
  958.          return index < VERT_ATTRIB_GENERIC0 + (GLint) c->MaxAttribs;
  959.       case MESA_SHADER_FRAGMENT:
  960.          return index < VARYING_SLOT_VAR0 + (GLint) ctx->Const.MaxVarying;
  961.       case MESA_SHADER_GEOMETRY:
  962.          return index < VARYING_SLOT_VAR0 + (GLint) ctx->Const.MaxVarying;
  963.       default:
  964.          return GL_FALSE;
  965.       }
  966.  
  967.    case PROGRAM_OUTPUT:
  968.       if (index < 0)
  969.          return GL_FALSE;
  970.  
  971.       switch (shaderType) {
  972.       case MESA_SHADER_VERTEX:
  973.          return index < VARYING_SLOT_VAR0 + (GLint) ctx->Const.MaxVarying;
  974.       case MESA_SHADER_FRAGMENT:
  975.          return index < FRAG_RESULT_DATA0 + (GLint) ctx->Const.MaxDrawBuffers;
  976.       case MESA_SHADER_GEOMETRY:
  977.          return index < VARYING_SLOT_VAR0 + (GLint) ctx->Const.MaxVarying;
  978.       default:
  979.          return GL_FALSE;
  980.       }
  981.  
  982.    case PROGRAM_ADDRESS:
  983.       return index >= 0 && index < (GLint) c->MaxAddressRegs;
  984.  
  985.    default:
  986.       _mesa_problem(ctx,
  987.                     "unexpected register file in _mesa_valid_register_index()");
  988.       return GL_FALSE;
  989.    }
  990. }
  991.  
  992.  
  993.  
  994. /**
  995.  * "Post-process" a GPU program.  This is intended to be used for debugging.
  996.  * Example actions include no-op'ing instructions or changing instruction
  997.  * behaviour.
  998.  */
  999. void
  1000. _mesa_postprocess_program(struct gl_context *ctx, struct gl_program *prog)
  1001. {
  1002.    static const GLfloat white[4] = { 0.5, 0.5, 0.5, 0.5 };
  1003.    GLuint i;
  1004.    GLuint whiteSwizzle;
  1005.    GLint whiteIndex = _mesa_add_unnamed_constant(prog->Parameters,
  1006.                                                  (gl_constant_value *) white,
  1007.                                                  4, &whiteSwizzle);
  1008.  
  1009.    (void) whiteIndex;
  1010.  
  1011.    for (i = 0; i < prog->NumInstructions; i++) {
  1012.       struct prog_instruction *inst = prog->Instructions + i;
  1013.       const GLuint n = _mesa_num_inst_src_regs(inst->Opcode);
  1014.  
  1015.       (void) n;
  1016.  
  1017.       if (_mesa_is_tex_instruction(inst->Opcode)) {
  1018. #if 0
  1019.          /* replace TEX/TXP/TXB with MOV */
  1020.          inst->Opcode = OPCODE_MOV;
  1021.          inst->DstReg.WriteMask = WRITEMASK_XYZW;
  1022.          inst->SrcReg[0].Swizzle = SWIZZLE_XYZW;
  1023.          inst->SrcReg[0].Negate = NEGATE_NONE;
  1024. #endif
  1025.  
  1026. #if 0
  1027.          /* disable shadow texture mode */
  1028.          inst->TexShadow = 0;
  1029. #endif
  1030.       }
  1031.  
  1032.       if (inst->Opcode == OPCODE_TXP) {
  1033. #if 0
  1034.          inst->Opcode = OPCODE_MOV;
  1035.          inst->DstReg.WriteMask = WRITEMASK_XYZW;
  1036.          inst->SrcReg[0].File = PROGRAM_CONSTANT;
  1037.          inst->SrcReg[0].Index = whiteIndex;
  1038.          inst->SrcReg[0].Swizzle = SWIZZLE_XYZW;
  1039.          inst->SrcReg[0].Negate = NEGATE_NONE;
  1040. #endif
  1041. #if 0
  1042.          inst->TexShadow = 0;
  1043. #endif
  1044. #if 0
  1045.          inst->Opcode = OPCODE_TEX;
  1046.          inst->TexShadow = 0;
  1047. #endif
  1048.       }
  1049.  
  1050.    }
  1051. }
  1052.  
  1053. /* Gets the minimum number of shader invocations per fragment.
  1054.  * This function is useful to determine if we need to do per
  1055.  * sample shading or per fragment shading.
  1056.  */
  1057. GLint
  1058. _mesa_get_min_invocations_per_fragment(struct gl_context *ctx,
  1059.                                        const struct gl_fragment_program *prog,
  1060.                                        bool ignore_sample_qualifier)
  1061. {
  1062.    /* From ARB_sample_shading specification:
  1063.     * "Using gl_SampleID in a fragment shader causes the entire shader
  1064.     *  to be evaluated per-sample."
  1065.     *
  1066.     * "Using gl_SamplePosition in a fragment shader causes the entire
  1067.     *  shader to be evaluated per-sample."
  1068.     *
  1069.     * "If MULTISAMPLE or SAMPLE_SHADING_ARB is disabled, sample shading
  1070.     *  has no effect."
  1071.     */
  1072.    if (ctx->Multisample.Enabled) {
  1073.       /* The ARB_gpu_shader5 specification says:
  1074.        *
  1075.        * "Use of the "sample" qualifier on a fragment shader input
  1076.        *  forces per-sample shading"
  1077.        */
  1078.       if (prog->IsSample && !ignore_sample_qualifier)
  1079.          return MAX2(ctx->DrawBuffer->Visual.samples, 1);
  1080.  
  1081.       if (prog->Base.SystemValuesRead & (SYSTEM_BIT_SAMPLE_ID |
  1082.                                          SYSTEM_BIT_SAMPLE_POS))
  1083.          return MAX2(ctx->DrawBuffer->Visual.samples, 1);
  1084.       else if (ctx->Multisample.SampleShading)
  1085.          return MAX2(ceil(ctx->Multisample.MinSampleShadingValue *
  1086.                           ctx->DrawBuffer->Visual.samples), 1);
  1087.       else
  1088.          return 1;
  1089.    }
  1090.    return 1;
  1091. }
  1092.