Subversion Repositories Kolibri OS

Rev

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

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2010 Luca Barbieri
  4.  *
  5.  * Permission is hereby granted, free of charge, to any person obtaining
  6.  * a copy of this software and associated documentation files (the
  7.  * "Software"), to deal in the Software without restriction, including
  8.  * without limitation the rights to use, copy, modify, merge, publish,
  9.  * distribute, sublicense, and/or sell copies of the Software, and to
  10.  * permit persons to whom the Software is furnished to do so, subject to
  11.  * the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice (including the
  14.  * next paragraph) shall be included in all copies or substantial
  15.  * portions of the Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18.  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  20.  * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
  21.  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  22.  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  23.  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24.  *
  25.  **************************************************************************/
  26.  
  27. #include "util/u_debug.h"
  28. #include "pipe/p_shader_tokens.h"
  29. #include "tgsi/tgsi_parse.h"
  30. #include "tgsi/tgsi_scan.h"
  31. #include "util/u_linkage.h"
  32.  
  33. /* we must only record the registers that are actually used, not just declared */
  34. static INLINE boolean
  35. util_semantic_set_test_and_set(struct util_semantic_set *set, unsigned value)
  36. {
  37.    unsigned mask = 1 << (value % (sizeof(long) * 8));
  38.    unsigned long *p = &set->masks[value / (sizeof(long) * 8)];
  39.    unsigned long v = *p & mask;
  40.    *p |= mask;
  41.    return !!v;
  42. }
  43.  
  44. unsigned
  45. util_semantic_set_from_program_file(struct util_semantic_set *set, const struct tgsi_token *tokens, enum tgsi_file_type file)
  46. {
  47.    struct tgsi_shader_info info;
  48.    struct tgsi_parse_context parse;
  49.    unsigned count = 0;
  50.    ubyte *semantic_name;
  51.    ubyte *semantic_index;
  52.  
  53.    tgsi_scan_shader(tokens, &info);
  54.  
  55.    if(file == TGSI_FILE_INPUT)
  56.    {
  57.       semantic_name = info.input_semantic_name;
  58.       semantic_index = info.input_semantic_index;
  59.    }
  60.    else if(file == TGSI_FILE_OUTPUT)
  61.    {
  62.       semantic_name = info.output_semantic_name;
  63.       semantic_index = info.output_semantic_index;
  64.    }
  65.    else
  66.    {
  67.       assert(0);
  68.       semantic_name = NULL;
  69.       semantic_index = NULL;
  70.    }
  71.  
  72.    tgsi_parse_init(&parse, tokens);
  73.  
  74.    memset(set->masks, 0, sizeof(set->masks));
  75.    while(!tgsi_parse_end_of_tokens(&parse))
  76.    {
  77.       tgsi_parse_token(&parse);
  78.  
  79.       if(parse.FullToken.Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION)
  80.       {
  81.          const struct tgsi_full_instruction *finst = &parse.FullToken.FullInstruction;
  82.          unsigned i;
  83.          for(i = 0; i < finst->Instruction.NumDstRegs; ++i)
  84.          {
  85.             if(finst->Dst[i].Register.File == file)
  86.             {
  87.                unsigned idx = finst->Dst[i].Register.Index;
  88.                if(semantic_name[idx] == TGSI_SEMANTIC_GENERIC)
  89.                {
  90.                   if(!util_semantic_set_test_and_set(set, semantic_index[idx]))
  91.                      ++count;
  92.                }
  93.             }
  94.          }
  95.  
  96.          for(i = 0; i < finst->Instruction.NumSrcRegs; ++i)
  97.          {
  98.             if(finst->Src[i].Register.File == file)
  99.             {
  100.                unsigned idx = finst->Src[i].Register.Index;
  101.                if(semantic_name[idx] == TGSI_SEMANTIC_GENERIC)
  102.                {
  103.                   if(!util_semantic_set_test_and_set(set, semantic_index[idx]))
  104.                      ++count;
  105.                }
  106.             }
  107.          }
  108.       }
  109.    }
  110.    tgsi_parse_free(&parse);
  111.  
  112.    return count;
  113. }
  114.  
  115. #define UTIL_SEMANTIC_SET_FOR_EACH(i, set) for(i = 0; i < 256; ++i) if(set->masks[i / (sizeof(long) * 8)] & (1 << (i % (sizeof(long) * 8))))
  116.  
  117. void
  118. util_semantic_layout_from_set(unsigned char *layout, const struct util_semantic_set *set, unsigned efficient_slots, unsigned num_slots)
  119. {
  120.    int first = -1;
  121.    int last = -1;
  122.    unsigned i;
  123.  
  124.    memset(layout, 0xff, num_slots);
  125.  
  126.    UTIL_SEMANTIC_SET_FOR_EACH(i, set)
  127.    {
  128.       if(first < 0)
  129.          first = i;
  130.       last = i;
  131.    }
  132.  
  133.    if (last < (int) efficient_slots)
  134.    {
  135.       UTIL_SEMANTIC_SET_FOR_EACH(i, set)
  136.          layout[i] = i;
  137.    }
  138.    else if ((last - first) < (int) efficient_slots)
  139.    {
  140.       UTIL_SEMANTIC_SET_FOR_EACH(i, set)
  141.          layout[i - first] = i;
  142.    }
  143.    else
  144.    {
  145.       unsigned idx = 0;
  146.       UTIL_SEMANTIC_SET_FOR_EACH(i, set)
  147.          layout[idx++] = i;
  148.    }
  149. }
  150.