4cdd89182ad21da9445b0034a82e82cda3835cd1
[mesa.git] / src / gallium / aux / tgsi / util / tgsi_util.c
1 #include "pipe/p_debug.h"
2 #include "pipe/p_util.h"
3 #include "pipe/p_shader_tokens.h"
4 #include "tgsi_parse.h"
5 #include "tgsi_build.h"
6 #include "tgsi_util.h"
7
8 union pointer_hack
9 {
10 void *pointer;
11 unsigned long long uint64;
12 };
13
14 void *
15 tgsi_align_128bit(
16 void *unaligned )
17 {
18 union pointer_hack ph;
19
20 ph.uint64 = 0;
21 ph.pointer = unaligned;
22 ph.uint64 = (ph.uint64 + 15) & ~15;
23 return ph.pointer;
24 }
25
26 unsigned
27 tgsi_util_get_src_register_swizzle(
28 const struct tgsi_src_register *reg,
29 unsigned component )
30 {
31 switch( component ) {
32 case 0:
33 return reg->SwizzleX;
34 case 1:
35 return reg->SwizzleY;
36 case 2:
37 return reg->SwizzleZ;
38 case 3:
39 return reg->SwizzleW;
40 default:
41 assert( 0 );
42 }
43 return 0;
44 }
45
46 unsigned
47 tgsi_util_get_src_register_extswizzle(
48 const struct tgsi_src_register_ext_swz *reg,
49 unsigned component )
50 {
51 switch( component ) {
52 case 0:
53 return reg->ExtSwizzleX;
54 case 1:
55 return reg->ExtSwizzleY;
56 case 2:
57 return reg->ExtSwizzleZ;
58 case 3:
59 return reg->ExtSwizzleW;
60 default:
61 assert( 0 );
62 }
63 return 0;
64 }
65
66 unsigned
67 tgsi_util_get_full_src_register_extswizzle(
68 const struct tgsi_full_src_register *reg,
69 unsigned component )
70 {
71 unsigned swizzle;
72
73 /*
74 * First, calculate the extended swizzle for a given channel. This will give
75 * us either a channel index into the simple swizzle or a constant 1 or 0.
76 */
77 swizzle = tgsi_util_get_src_register_extswizzle(
78 &reg->SrcRegisterExtSwz,
79 component );
80
81 assert (TGSI_SWIZZLE_X == TGSI_EXTSWIZZLE_X);
82 assert (TGSI_SWIZZLE_Y == TGSI_EXTSWIZZLE_Y);
83 assert (TGSI_SWIZZLE_Z == TGSI_EXTSWIZZLE_Z);
84 assert (TGSI_SWIZZLE_W == TGSI_EXTSWIZZLE_W);
85 assert (TGSI_EXTSWIZZLE_ZERO > TGSI_SWIZZLE_W);
86 assert (TGSI_EXTSWIZZLE_ONE > TGSI_SWIZZLE_W);
87
88 /*
89 * Second, calculate the simple swizzle for the unswizzled channel index.
90 * Leave the constants intact, they are not affected by the simple swizzle.
91 */
92 if( swizzle <= TGSI_SWIZZLE_W ) {
93 swizzle = tgsi_util_get_src_register_swizzle(
94 &reg->SrcRegister,
95 component );
96 }
97
98 return swizzle;
99 }
100
101 void
102 tgsi_util_set_src_register_swizzle(
103 struct tgsi_src_register *reg,
104 unsigned swizzle,
105 unsigned component )
106 {
107 switch( component ) {
108 case 0:
109 reg->SwizzleX = swizzle;
110 break;
111 case 1:
112 reg->SwizzleY = swizzle;
113 break;
114 case 2:
115 reg->SwizzleZ = swizzle;
116 break;
117 case 3:
118 reg->SwizzleW = swizzle;
119 break;
120 default:
121 assert( 0 );
122 }
123 }
124
125 void
126 tgsi_util_set_src_register_extswizzle(
127 struct tgsi_src_register_ext_swz *reg,
128 unsigned swizzle,
129 unsigned component )
130 {
131 switch( component ) {
132 case 0:
133 reg->ExtSwizzleX = swizzle;
134 break;
135 case 1:
136 reg->ExtSwizzleY = swizzle;
137 break;
138 case 2:
139 reg->ExtSwizzleZ = swizzle;
140 break;
141 case 3:
142 reg->ExtSwizzleW = swizzle;
143 break;
144 default:
145 assert( 0 );
146 }
147 }
148
149 unsigned
150 tgsi_util_get_src_register_extnegate(
151 const struct tgsi_src_register_ext_swz *reg,
152 unsigned component )
153 {
154 switch( component ) {
155 case 0:
156 return reg->NegateX;
157 case 1:
158 return reg->NegateY;
159 case 2:
160 return reg->NegateZ;
161 case 3:
162 return reg->NegateW;
163 default:
164 assert( 0 );
165 }
166 return 0;
167 }
168
169 void
170 tgsi_util_set_src_register_extnegate(
171 struct tgsi_src_register_ext_swz *reg,
172 unsigned negate,
173 unsigned component )
174 {
175 switch( component ) {
176 case 0:
177 reg->NegateX = negate;
178 break;
179 case 1:
180 reg->NegateY = negate;
181 break;
182 case 2:
183 reg->NegateZ = negate;
184 break;
185 case 3:
186 reg->NegateW = negate;
187 break;
188 default:
189 assert( 0 );
190 }
191 }
192
193 unsigned
194 tgsi_util_get_full_src_register_sign_mode(
195 const struct tgsi_full_src_register *reg,
196 unsigned component )
197 {
198 unsigned sign_mode;
199
200 if( reg->SrcRegisterExtMod.Absolute ) {
201 /* Consider only the post-abs negation. */
202
203 if( reg->SrcRegisterExtMod.Negate ) {
204 sign_mode = TGSI_UTIL_SIGN_SET;
205 }
206 else {
207 sign_mode = TGSI_UTIL_SIGN_CLEAR;
208 }
209 }
210 else {
211 /* Accumulate the three negations. */
212
213 unsigned negate;
214
215 negate = reg->SrcRegister.Negate;
216 if( tgsi_util_get_src_register_extnegate( &reg->SrcRegisterExtSwz, component ) ) {
217 negate = !negate;
218 }
219 if( reg->SrcRegisterExtMod.Negate ) {
220 negate = !negate;
221 }
222
223 if( negate ) {
224 sign_mode = TGSI_UTIL_SIGN_TOGGLE;
225 }
226 else {
227 sign_mode = TGSI_UTIL_SIGN_KEEP;
228 }
229 }
230
231 return sign_mode;
232 }
233
234 void
235 tgsi_util_set_full_src_register_sign_mode(
236 struct tgsi_full_src_register *reg,
237 unsigned sign_mode )
238 {
239 reg->SrcRegisterExtSwz.NegateX = 0;
240 reg->SrcRegisterExtSwz.NegateY = 0;
241 reg->SrcRegisterExtSwz.NegateZ = 0;
242 reg->SrcRegisterExtSwz.NegateW = 0;
243
244 switch (sign_mode)
245 {
246 case TGSI_UTIL_SIGN_CLEAR:
247 reg->SrcRegister.Negate = 0;
248 reg->SrcRegisterExtMod.Absolute = 1;
249 reg->SrcRegisterExtMod.Negate = 0;
250 break;
251
252 case TGSI_UTIL_SIGN_SET:
253 reg->SrcRegister.Negate = 0;
254 reg->SrcRegisterExtMod.Absolute = 1;
255 reg->SrcRegisterExtMod.Negate = 1;
256 break;
257
258 case TGSI_UTIL_SIGN_TOGGLE:
259 reg->SrcRegister.Negate = 1;
260 reg->SrcRegisterExtMod.Absolute = 0;
261 reg->SrcRegisterExtMod.Negate = 0;
262 break;
263
264 case TGSI_UTIL_SIGN_KEEP:
265 reg->SrcRegister.Negate = 0;
266 reg->SrcRegisterExtMod.Absolute = 0;
267 reg->SrcRegisterExtMod.Negate = 0;
268 break;
269
270 default:
271 assert( 0 );
272 }
273 }
274