Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright © 2009 Intel Corporation
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8.  * and/or sell copies of the Software, and to permit persons to whom the
  9.  * Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  21.  * DEALINGS IN THE SOFTWARE.
  22.  */
  23.  
  24. /**
  25.  * \file prog_parameter_layout.c
  26.  * \brief Helper functions to layout storage for program parameters
  27.  *
  28.  * \author Ian Romanick <ian.d.romanick@intel.com>
  29.  */
  30.  
  31. #include "main/compiler.h"
  32. #include "main/mtypes.h"
  33. #include "prog_parameter.h"
  34. #include "prog_parameter_layout.h"
  35. #include "prog_instruction.h"
  36. #include "program_parser.h"
  37.  
  38. unsigned
  39. _mesa_combine_swizzles(unsigned base, unsigned applied)
  40. {
  41.    unsigned swiz = 0;
  42.    unsigned i;
  43.  
  44.    for (i = 0; i < 4; i++) {
  45.       const unsigned s = GET_SWZ(applied, i);
  46.  
  47.       swiz |= ((s <= SWIZZLE_W) ? GET_SWZ(base, s) : s) << (i * 3);
  48.    }
  49.  
  50.    return swiz;
  51. }
  52.  
  53.  
  54. /**
  55.  * Copy indirect access array from one parameter list to another
  56.  *
  57.  * \param src   Parameter array copied from
  58.  * \param dst   Parameter array copied to
  59.  * \param first Index of first element in \c src to copy
  60.  * \param count Number of elements to copy
  61.  *
  62.  * \return
  63.  * The location in \c dst of the first element copied from \c src on
  64.  * success.  -1 on failure.
  65.  *
  66.  * \warning
  67.  * This function assumes that there is already enough space available in
  68.  * \c dst to hold all of the elements that will be copied over.
  69.  */
  70. static int
  71. copy_indirect_accessed_array(struct gl_program_parameter_list *src,
  72.                              struct gl_program_parameter_list *dst,
  73.                              unsigned first, unsigned count)
  74. {
  75.    const int base = dst->NumParameters;
  76.    unsigned i, j;
  77.  
  78.    for (i = first; i < (first + count); i++) {
  79.       struct gl_program_parameter *curr = & src->Parameters[i];
  80.  
  81.       if (curr->Type == PROGRAM_CONSTANT) {
  82.          j = dst->NumParameters;
  83.       } else {
  84.          for (j = 0; j < dst->NumParameters; j++) {
  85.             if (memcmp(dst->Parameters[j].StateIndexes, curr->StateIndexes,
  86.                        sizeof(curr->StateIndexes)) == 0) {
  87.                return -1;
  88.             }
  89.          }
  90.       }
  91.  
  92.       assert(j == dst->NumParameters);
  93.  
  94.       /* copy src parameter [i] to dest parameter [j] */
  95.       memcpy(& dst->Parameters[j], curr,
  96.              sizeof(dst->Parameters[j]));
  97.       memcpy(dst->ParameterValues[j], src->ParameterValues[i],
  98.              sizeof(GLfloat) * 4);
  99.  
  100.       /* Pointer to the string name was copied.  Null-out src param name
  101.        * to prevent double free later.
  102.        */
  103.       curr->Name = NULL;
  104.  
  105.       dst->NumParameters++;
  106.    }
  107.  
  108.    return base;
  109. }
  110.  
  111.  
  112. /**
  113.  * XXX description???
  114.  * \return GL_TRUE for success, GL_FALSE for failure
  115.  */
  116. GLboolean
  117. _mesa_layout_parameters(struct asm_parser_state *state)
  118. {
  119.    struct gl_program_parameter_list *layout;
  120.    struct asm_instruction *inst;
  121.    unsigned i;
  122.  
  123.    layout =
  124.       _mesa_new_parameter_list_sized(state->prog->Parameters->NumParameters);
  125.  
  126.    /* PASS 1:  Move any parameters that are accessed indirectly from the
  127.     * original parameter list to the new parameter list.
  128.     */
  129.    for (inst = state->inst_head; inst != NULL; inst = inst->next) {
  130.       for (i = 0; i < 3; i++) {
  131.          if (inst->SrcReg[i].Base.RelAddr) {
  132.             /* Only attempt to add the to the new parameter list once.
  133.              */
  134.             if (!inst->SrcReg[i].Symbol->pass1_done) {
  135.                const int new_begin =
  136.                   copy_indirect_accessed_array(state->prog->Parameters, layout,
  137.                       inst->SrcReg[i].Symbol->param_binding_begin,
  138.                       inst->SrcReg[i].Symbol->param_binding_length);
  139.  
  140.                if (new_begin < 0) {
  141.                   return GL_FALSE;
  142.                }
  143.  
  144.                inst->SrcReg[i].Symbol->param_binding_begin = new_begin;
  145.                inst->SrcReg[i].Symbol->pass1_done = 1;
  146.             }
  147.  
  148.             /* Previously the Index was just the offset from the parameter
  149.              * array.  Now that the base of the parameter array is known, the
  150.              * index can be updated to its actual value.
  151.              */
  152.             inst->Base.SrcReg[i] = inst->SrcReg[i].Base;
  153.             inst->Base.SrcReg[i].Index +=
  154.                inst->SrcReg[i].Symbol->param_binding_begin;
  155.          }
  156.       }
  157.    }
  158.  
  159.    /* PASS 2:  Move any parameters that are not accessed indirectly from the
  160.     * original parameter list to the new parameter list.
  161.     */
  162.    for (inst = state->inst_head; inst != NULL; inst = inst->next) {
  163.       for (i = 0; i < 3; i++) {
  164.          const struct gl_program_parameter *p;
  165.          const int idx = inst->SrcReg[i].Base.Index;
  166.          unsigned swizzle = SWIZZLE_NOOP;
  167.  
  168.          /* All relative addressed operands were processed on the first
  169.           * pass.  Just skip them here.
  170.           */
  171.          if (inst->SrcReg[i].Base.RelAddr) {
  172.             continue;
  173.          }
  174.  
  175.          if ((inst->SrcReg[i].Base.File <= PROGRAM_VARYING )
  176.              || (inst->SrcReg[i].Base.File >= PROGRAM_WRITE_ONLY)) {
  177.             continue;
  178.          }
  179.  
  180.          inst->Base.SrcReg[i] = inst->SrcReg[i].Base;
  181.          p = & state->prog->Parameters->Parameters[idx];
  182.  
  183.          switch (p->Type) {
  184.          case PROGRAM_CONSTANT: {
  185.             const float *const v =
  186.                state->prog->Parameters->ParameterValues[idx];
  187.  
  188.             inst->Base.SrcReg[i].Index =
  189.                _mesa_add_unnamed_constant(layout, v, p->Size, & swizzle);
  190.  
  191.             inst->Base.SrcReg[i].Swizzle =
  192.                _mesa_combine_swizzles(swizzle, inst->Base.SrcReg[i].Swizzle);
  193.             break;
  194.          }
  195.  
  196.          case PROGRAM_STATE_VAR:
  197.             inst->Base.SrcReg[i].Index =
  198.                _mesa_add_state_reference(layout, p->StateIndexes);
  199.             break;
  200.  
  201.          default:
  202.             break;
  203.          }
  204.  
  205.          inst->SrcReg[i].Base.File = p->Type;
  206.          inst->Base.SrcReg[i].File = p->Type;
  207.       }
  208.    }
  209.  
  210.    _mesa_free_parameter_list(state->prog->Parameters);
  211.    state->prog->Parameters = layout;
  212.  
  213.    return GL_TRUE;
  214. }
  215.