Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3770 Serge 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
}