tgsi/transform: add support for SVIEW decls
[mesa.git] / src / gallium / auxiliary / tgsi / tgsi_transform.h
1 /**************************************************************************
2 *
3 * Copyright 2008 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 #ifndef TGSI_TRANSFORM_H
29 #define TGSI_TRANSFORM_H
30
31
32 #include "pipe/p_shader_tokens.h"
33 #include "tgsi/tgsi_parse.h"
34 #include "tgsi/tgsi_build.h"
35
36
37
38 /**
39 * Subclass this to add caller-specific data
40 */
41 struct tgsi_transform_context
42 {
43 /**** PUBLIC ***/
44
45 /**
46 * User-defined callbacks invoked per instruction.
47 */
48 void (*transform_instruction)(struct tgsi_transform_context *ctx,
49 struct tgsi_full_instruction *inst);
50
51 void (*transform_declaration)(struct tgsi_transform_context *ctx,
52 struct tgsi_full_declaration *decl);
53
54 void (*transform_immediate)(struct tgsi_transform_context *ctx,
55 struct tgsi_full_immediate *imm);
56 void (*transform_property)(struct tgsi_transform_context *ctx,
57 struct tgsi_full_property *prop);
58
59 /**
60 * Called after last declaration, before first instruction. This is
61 * where the user might insert new declarations and/or instructions.
62 */
63 void (*prolog)(struct tgsi_transform_context *ctx);
64
65 /**
66 * Called at end of input program to allow caller to append extra
67 * instructions. Return number of tokens emitted.
68 */
69 void (*epilog)(struct tgsi_transform_context *ctx);
70
71
72 /*** PRIVATE ***/
73
74 /**
75 * These are setup by tgsi_transform_shader() and cannot be overridden.
76 * Meant to be called from in the above user callback functions.
77 */
78 void (*emit_instruction)(struct tgsi_transform_context *ctx,
79 const struct tgsi_full_instruction *inst);
80 void (*emit_declaration)(struct tgsi_transform_context *ctx,
81 const struct tgsi_full_declaration *decl);
82 void (*emit_immediate)(struct tgsi_transform_context *ctx,
83 const struct tgsi_full_immediate *imm);
84 void (*emit_property)(struct tgsi_transform_context *ctx,
85 const struct tgsi_full_property *prop);
86
87 struct tgsi_header *header;
88 uint max_tokens_out;
89 struct tgsi_token *tokens_out;
90 uint ti;
91 };
92
93
94 /**
95 * Helper for emitting temporary register declarations.
96 */
97 static INLINE void
98 tgsi_transform_temp_decl(struct tgsi_transform_context *ctx,
99 unsigned index)
100 {
101 struct tgsi_full_declaration decl;
102
103 decl = tgsi_default_full_declaration();
104 decl.Declaration.File = TGSI_FILE_TEMPORARY;
105 decl.Range.First =
106 decl.Range.Last = index;
107 ctx->emit_declaration(ctx, &decl);
108 }
109
110
111 static INLINE void
112 tgsi_transform_input_decl(struct tgsi_transform_context *ctx,
113 unsigned index,
114 unsigned sem_name, unsigned sem_index,
115 unsigned interp)
116 {
117 struct tgsi_full_declaration decl;
118
119 decl = tgsi_default_full_declaration();
120 decl.Declaration.File = TGSI_FILE_INPUT;
121 decl.Declaration.Interpolate = 1;
122 decl.Declaration.Semantic = 1;
123 decl.Semantic.Name = sem_name;
124 decl.Semantic.Index = sem_index;
125 decl.Range.First =
126 decl.Range.Last = index;
127 decl.Interp.Interpolate = interp;
128
129 ctx->emit_declaration(ctx, &decl);
130 }
131
132
133 static INLINE void
134 tgsi_transform_sampler_decl(struct tgsi_transform_context *ctx,
135 unsigned index)
136 {
137 struct tgsi_full_declaration decl;
138
139 decl = tgsi_default_full_declaration();
140 decl.Declaration.File = TGSI_FILE_SAMPLER;
141 decl.Range.First =
142 decl.Range.Last = index;
143 ctx->emit_declaration(ctx, &decl);
144 }
145
146 static INLINE void
147 tgsi_transform_sampler_view_decl(struct tgsi_transform_context *ctx,
148 unsigned index,
149 unsigned target,
150 enum tgsi_return_type type)
151 {
152 struct tgsi_full_declaration decl;
153
154 decl = tgsi_default_full_declaration();
155 decl.Declaration.File = TGSI_FILE_SAMPLER_VIEW;
156 decl.Declaration.UsageMask = 0xf;
157 decl.Range.First =
158 decl.Range.Last = index;
159 decl.SamplerView.Resource = target;
160 decl.SamplerView.ReturnTypeX = type;
161 decl.SamplerView.ReturnTypeY = type;
162 decl.SamplerView.ReturnTypeZ = type;
163 decl.SamplerView.ReturnTypeW = type;
164
165 ctx->emit_declaration(ctx, &decl);
166 }
167
168 static INLINE void
169 tgsi_transform_immediate_decl(struct tgsi_transform_context *ctx,
170 float x, float y, float z, float w)
171 {
172 struct tgsi_full_immediate immed;
173 unsigned size = 4;
174
175 immed = tgsi_default_full_immediate();
176 immed.Immediate.NrTokens = 1 + size; /* one for the token itself */
177 immed.u[0].Float = x;
178 immed.u[1].Float = y;
179 immed.u[2].Float = z;
180 immed.u[3].Float = w;
181
182 ctx->emit_immediate(ctx, &immed);
183 }
184
185
186 /**
187 * Helper for emitting 1-operand instructions.
188 */
189 static INLINE void
190 tgsi_transform_op1_inst(struct tgsi_transform_context *ctx,
191 unsigned opcode,
192 unsigned dst_file,
193 unsigned dst_index,
194 unsigned dst_writemask,
195 unsigned src0_file,
196 unsigned src0_index)
197 {
198 struct tgsi_full_instruction inst;
199
200 inst = tgsi_default_full_instruction();
201 inst.Instruction.Opcode = opcode;
202 inst.Instruction.NumDstRegs = 1;
203 inst.Dst[0].Register.File = dst_file,
204 inst.Dst[0].Register.Index = dst_index;
205 inst.Dst[0].Register.WriteMask = dst_writemask;
206 inst.Instruction.NumSrcRegs = 1;
207 inst.Src[0].Register.File = src0_file;
208 inst.Src[0].Register.Index = src0_index;
209
210 ctx->emit_instruction(ctx, &inst);
211 }
212
213
214 static INLINE void
215 tgsi_transform_op2_inst(struct tgsi_transform_context *ctx,
216 unsigned opcode,
217 unsigned dst_file,
218 unsigned dst_index,
219 unsigned dst_writemask,
220 unsigned src0_file,
221 unsigned src0_index,
222 unsigned src1_file,
223 unsigned src1_index)
224 {
225 struct tgsi_full_instruction inst;
226
227 inst = tgsi_default_full_instruction();
228 inst.Instruction.Opcode = opcode;
229 inst.Instruction.NumDstRegs = 1;
230 inst.Dst[0].Register.File = dst_file,
231 inst.Dst[0].Register.Index = dst_index;
232 inst.Dst[0].Register.WriteMask = dst_writemask;
233 inst.Instruction.NumSrcRegs = 2;
234 inst.Src[0].Register.File = src0_file;
235 inst.Src[0].Register.Index = src0_index;
236 inst.Src[1].Register.File = src1_file;
237 inst.Src[1].Register.Index = src1_index;
238
239 ctx->emit_instruction(ctx, &inst);
240 }
241
242
243 static INLINE void
244 tgsi_transform_op1_swz_inst(struct tgsi_transform_context *ctx,
245 unsigned opcode,
246 unsigned dst_file,
247 unsigned dst_index,
248 unsigned dst_writemask,
249 unsigned src0_file,
250 unsigned src0_index,
251 unsigned src0_swizzle)
252 {
253 struct tgsi_full_instruction inst;
254
255 inst = tgsi_default_full_instruction();
256 inst.Instruction.Opcode = opcode;
257 inst.Instruction.NumDstRegs = 1;
258 inst.Dst[0].Register.File = dst_file,
259 inst.Dst[0].Register.Index = dst_index;
260 inst.Dst[0].Register.WriteMask = dst_writemask;
261 inst.Instruction.NumSrcRegs = 1;
262 inst.Src[0].Register.File = src0_file;
263 inst.Src[0].Register.Index = src0_index;
264 switch (dst_writemask) {
265 case TGSI_WRITEMASK_X:
266 inst.Src[0].Register.SwizzleX = src0_swizzle;
267 break;
268 case TGSI_WRITEMASK_Y:
269 inst.Src[0].Register.SwizzleY = src0_swizzle;
270 break;
271 case TGSI_WRITEMASK_Z:
272 inst.Src[0].Register.SwizzleZ = src0_swizzle;
273 break;
274 case TGSI_WRITEMASK_W:
275 inst.Src[0].Register.SwizzleW = src0_swizzle;
276 break;
277 default:
278 ; /* nothing */
279 }
280
281 ctx->emit_instruction(ctx, &inst);
282 }
283
284
285 static INLINE void
286 tgsi_transform_op2_swz_inst(struct tgsi_transform_context *ctx,
287 unsigned opcode,
288 unsigned dst_file,
289 unsigned dst_index,
290 unsigned dst_writemask,
291 unsigned src0_file,
292 unsigned src0_index,
293 unsigned src0_swizzle,
294 unsigned src1_file,
295 unsigned src1_index,
296 unsigned src1_swizzle)
297 {
298 struct tgsi_full_instruction inst;
299
300 inst = tgsi_default_full_instruction();
301 inst.Instruction.Opcode = opcode;
302 inst.Instruction.NumDstRegs = 1;
303 inst.Dst[0].Register.File = dst_file,
304 inst.Dst[0].Register.Index = dst_index;
305 inst.Dst[0].Register.WriteMask = dst_writemask;
306 inst.Instruction.NumSrcRegs = 2;
307 inst.Src[0].Register.File = src0_file;
308 inst.Src[0].Register.Index = src0_index;
309 inst.Src[1].Register.File = src1_file;
310 inst.Src[1].Register.Index = src1_index;
311 switch (dst_writemask) {
312 case TGSI_WRITEMASK_X:
313 inst.Src[0].Register.SwizzleX = src0_swizzle;
314 inst.Src[1].Register.SwizzleX = src1_swizzle;
315 break;
316 case TGSI_WRITEMASK_Y:
317 inst.Src[0].Register.SwizzleY = src0_swizzle;
318 inst.Src[1].Register.SwizzleY = src1_swizzle;
319 break;
320 case TGSI_WRITEMASK_Z:
321 inst.Src[0].Register.SwizzleZ = src0_swizzle;
322 inst.Src[1].Register.SwizzleZ = src1_swizzle;
323 break;
324 case TGSI_WRITEMASK_W:
325 inst.Src[0].Register.SwizzleW = src0_swizzle;
326 inst.Src[1].Register.SwizzleW = src1_swizzle;
327 break;
328 default:
329 ; /* nothing */
330 }
331
332 ctx->emit_instruction(ctx, &inst);
333 }
334
335
336 static INLINE void
337 tgsi_transform_op3_swz_inst(struct tgsi_transform_context *ctx,
338 unsigned opcode,
339 unsigned dst_file,
340 unsigned dst_index,
341 unsigned dst_writemask,
342 unsigned src0_file,
343 unsigned src0_index,
344 unsigned src0_swizzle,
345 unsigned src0_negate,
346 unsigned src1_file,
347 unsigned src1_index,
348 unsigned src1_swizzle,
349 unsigned src2_file,
350 unsigned src2_index,
351 unsigned src2_swizzle)
352 {
353 struct tgsi_full_instruction inst;
354
355 inst = tgsi_default_full_instruction();
356 inst.Instruction.Opcode = opcode;
357 inst.Instruction.NumDstRegs = 1;
358 inst.Dst[0].Register.File = dst_file,
359 inst.Dst[0].Register.Index = dst_index;
360 inst.Dst[0].Register.WriteMask = dst_writemask;
361 inst.Instruction.NumSrcRegs = 3;
362 inst.Src[0].Register.File = src0_file;
363 inst.Src[0].Register.Index = src0_index;
364 inst.Src[0].Register.Negate = src0_negate;
365 inst.Src[1].Register.File = src1_file;
366 inst.Src[1].Register.Index = src1_index;
367 inst.Src[2].Register.File = src2_file;
368 inst.Src[2].Register.Index = src2_index;
369 switch (dst_writemask) {
370 case TGSI_WRITEMASK_X:
371 inst.Src[0].Register.SwizzleX = src0_swizzle;
372 inst.Src[1].Register.SwizzleX = src1_swizzle;
373 inst.Src[2].Register.SwizzleX = src2_swizzle;
374 break;
375 case TGSI_WRITEMASK_Y:
376 inst.Src[0].Register.SwizzleY = src0_swizzle;
377 inst.Src[1].Register.SwizzleY = src1_swizzle;
378 inst.Src[2].Register.SwizzleY = src2_swizzle;
379 break;
380 case TGSI_WRITEMASK_Z:
381 inst.Src[0].Register.SwizzleZ = src0_swizzle;
382 inst.Src[1].Register.SwizzleZ = src1_swizzle;
383 inst.Src[2].Register.SwizzleZ = src2_swizzle;
384 break;
385 case TGSI_WRITEMASK_W:
386 inst.Src[0].Register.SwizzleW = src0_swizzle;
387 inst.Src[1].Register.SwizzleW = src1_swizzle;
388 inst.Src[2].Register.SwizzleW = src2_swizzle;
389 break;
390 default:
391 ; /* nothing */
392 }
393
394 ctx->emit_instruction(ctx, &inst);
395 }
396
397
398 static INLINE void
399 tgsi_transform_kill_inst(struct tgsi_transform_context *ctx,
400 unsigned src_file,
401 unsigned src_index,
402 unsigned src_swizzle)
403 {
404 struct tgsi_full_instruction inst;
405
406 inst = tgsi_default_full_instruction();
407 inst.Instruction.Opcode = TGSI_OPCODE_KILL_IF;
408 inst.Instruction.NumDstRegs = 0;
409 inst.Instruction.NumSrcRegs = 1;
410 inst.Src[0].Register.File = src_file;
411 inst.Src[0].Register.Index = src_index;
412 inst.Src[0].Register.SwizzleX =
413 inst.Src[0].Register.SwizzleY =
414 inst.Src[0].Register.SwizzleZ =
415 inst.Src[0].Register.SwizzleW = src_swizzle;
416 inst.Src[0].Register.Negate = 1;
417
418 ctx->emit_instruction(ctx, &inst);
419 }
420
421
422 static INLINE void
423 tgsi_transform_tex_2d_inst(struct tgsi_transform_context *ctx,
424 unsigned dst_file,
425 unsigned dst_index,
426 unsigned src_file,
427 unsigned src_index,
428 unsigned sampler_index)
429 {
430 struct tgsi_full_instruction inst;
431
432 inst = tgsi_default_full_instruction();
433 inst.Instruction.Opcode = TGSI_OPCODE_TEX;
434 inst.Instruction.NumDstRegs = 1;
435 inst.Dst[0].Register.File = dst_file;
436 inst.Dst[0].Register.Index = dst_index;
437 inst.Instruction.NumSrcRegs = 2;
438 inst.Instruction.Texture = TRUE;
439 inst.Texture.Texture = TGSI_TEXTURE_2D;
440 inst.Src[0].Register.File = src_file;
441 inst.Src[0].Register.Index = src_index;
442 inst.Src[1].Register.File = TGSI_FILE_SAMPLER;
443 inst.Src[1].Register.Index = sampler_index;
444
445 ctx->emit_instruction(ctx, &inst);
446 }
447
448
449 extern int
450 tgsi_transform_shader(const struct tgsi_token *tokens_in,
451 struct tgsi_token *tokens_out,
452 uint max_tokens_out,
453 struct tgsi_transform_context *ctx);
454
455
456 #endif /* TGSI_TRANSFORM_H */