Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | 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.                   _mesa_free_parameter_list(layout);
  142.                   return GL_FALSE;
  143.                }
  144.  
  145.                inst->SrcReg[i].Symbol->param_binding_begin = new_begin;
  146.                inst->SrcReg[i].Symbol->pass1_done = 1;
  147.             }
  148.  
  149.             /* Previously the Index was just the offset from the parameter
  150.              * array.  Now that the base of the parameter array is known, the
  151.              * index can be updated to its actual value.
  152.              */
  153.             inst->Base.SrcReg[i] = inst->SrcReg[i].Base;
  154.             inst->Base.SrcReg[i].Index +=
  155.                inst->SrcReg[i].Symbol->param_binding_begin;
  156.          }
  157.       }
  158.    }
  159.  
  160.    /* PASS 2:  Move any parameters that are not accessed indirectly from the
  161.     * original parameter list to the new parameter list.
  162.     */
  163.    for (inst = state->inst_head; inst != NULL; inst = inst->next) {
  164.       for (i = 0; i < 3; i++) {
  165.          const struct gl_program_parameter *p;
  166.          const int idx = inst->SrcReg[i].Base.Index;
  167.          unsigned swizzle = SWIZZLE_NOOP;
  168.  
  169.          /* All relative addressed operands were processed on the first
  170.           * pass.  Just skip them here.
  171.           */
  172.          if (inst->SrcReg[i].Base.RelAddr) {
  173.             continue;
  174.          }
  175.  
  176.          if ((inst->SrcReg[i].Base.File <= PROGRAM_OUTPUT)
  177.              || (inst->SrcReg[i].Base.File >= PROGRAM_WRITE_ONLY)) {
  178.             continue;
  179.          }
  180.  
  181.          inst->Base.SrcReg[i] = inst->SrcReg[i].Base;
  182.          p = & state->prog->Parameters->Parameters[idx];
  183.  
  184.          switch (p->Type) {
  185.          case PROGRAM_CONSTANT: {
  186.             const gl_constant_value *const v =
  187.                state->prog->Parameters->ParameterValues[idx];
  188.  
  189.             inst->Base.SrcReg[i].Index =
  190.                _mesa_add_unnamed_constant(layout, v, p->Size, & swizzle);
  191.  
  192.             inst->Base.SrcReg[i].Swizzle =
  193.                _mesa_combine_swizzles(swizzle, inst->Base.SrcReg[i].Swizzle);
  194.             break;
  195.          }
  196.  
  197.          case PROGRAM_STATE_VAR:
  198.             inst->Base.SrcReg[i].Index =
  199.                _mesa_add_state_reference(layout, p->StateIndexes);
  200.             break;
  201.  
  202.          default:
  203.             break;
  204.          }
  205.  
  206.          inst->SrcReg[i].Base.File = p->Type;
  207.          inst->Base.SrcReg[i].File = p->Type;
  208.       }
  209.    }
  210.  
  211.    layout->StateFlags = state->prog->Parameters->StateFlags;
  212.    _mesa_free_parameter_list(state->prog->Parameters);
  213.    state->prog->Parameters = layout;
  214.  
  215.    return GL_TRUE;
  216. }
  217.