1bf215546Sopenharmony_ci/**************************************************************************
2bf215546Sopenharmony_ci *
3bf215546Sopenharmony_ci * Copyright 2008 VMware, Inc.
4bf215546Sopenharmony_ci * All Rights Reserved.
5bf215546Sopenharmony_ci *
6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the
8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including
9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish,
10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to
11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to
12bf215546Sopenharmony_ci * the following conditions:
13bf215546Sopenharmony_ci *
14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the
15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions
16bf215546Sopenharmony_ci * of the Software.
17bf215546Sopenharmony_ci *
18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25bf215546Sopenharmony_ci *
26bf215546Sopenharmony_ci **************************************************************************/
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci#ifndef TGSI_TRANSFORM_H
29bf215546Sopenharmony_ci#define TGSI_TRANSFORM_H
30bf215546Sopenharmony_ci
31bf215546Sopenharmony_ci
32bf215546Sopenharmony_ci#include "pipe/p_defines.h"
33bf215546Sopenharmony_ci#include "pipe/p_shader_tokens.h"
34bf215546Sopenharmony_ci#include "tgsi/tgsi_parse.h"
35bf215546Sopenharmony_ci#include "tgsi/tgsi_build.h"
36bf215546Sopenharmony_ci
37bf215546Sopenharmony_ci
38bf215546Sopenharmony_ci
39bf215546Sopenharmony_ci/**
40bf215546Sopenharmony_ci * Subclass this to add caller-specific data
41bf215546Sopenharmony_ci */
42bf215546Sopenharmony_cistruct tgsi_transform_context
43bf215546Sopenharmony_ci{
44bf215546Sopenharmony_ci/**** PUBLIC ***/
45bf215546Sopenharmony_ci
46bf215546Sopenharmony_ci   /**
47bf215546Sopenharmony_ci    * User-defined callbacks invoked per instruction.
48bf215546Sopenharmony_ci    */
49bf215546Sopenharmony_ci   void (*transform_instruction)(struct tgsi_transform_context *ctx,
50bf215546Sopenharmony_ci                                 struct tgsi_full_instruction *inst);
51bf215546Sopenharmony_ci
52bf215546Sopenharmony_ci   void (*transform_declaration)(struct tgsi_transform_context *ctx,
53bf215546Sopenharmony_ci                                 struct tgsi_full_declaration *decl);
54bf215546Sopenharmony_ci
55bf215546Sopenharmony_ci   void (*transform_immediate)(struct tgsi_transform_context *ctx,
56bf215546Sopenharmony_ci                               struct tgsi_full_immediate *imm);
57bf215546Sopenharmony_ci   void (*transform_property)(struct tgsi_transform_context *ctx,
58bf215546Sopenharmony_ci                              struct tgsi_full_property *prop);
59bf215546Sopenharmony_ci
60bf215546Sopenharmony_ci   /**
61bf215546Sopenharmony_ci    * Called after last declaration, before first instruction.  This is
62bf215546Sopenharmony_ci    * where the user might insert new declarations and/or instructions.
63bf215546Sopenharmony_ci    */
64bf215546Sopenharmony_ci   void (*prolog)(struct tgsi_transform_context *ctx);
65bf215546Sopenharmony_ci
66bf215546Sopenharmony_ci   /**
67bf215546Sopenharmony_ci    * Called at end of input program to allow caller to append extra
68bf215546Sopenharmony_ci    * instructions.
69bf215546Sopenharmony_ci    */
70bf215546Sopenharmony_ci   void (*epilog)(struct tgsi_transform_context *ctx);
71bf215546Sopenharmony_ci
72bf215546Sopenharmony_ci   enum pipe_shader_type processor;
73bf215546Sopenharmony_ci
74bf215546Sopenharmony_ci/*** PRIVATE ***/
75bf215546Sopenharmony_ci
76bf215546Sopenharmony_ci   /**
77bf215546Sopenharmony_ci    * These are setup by tgsi_transform_shader() and cannot be overridden.
78bf215546Sopenharmony_ci    * Meant to be called from in the above user callback functions.
79bf215546Sopenharmony_ci    */
80bf215546Sopenharmony_ci   void (*emit_instruction)(struct tgsi_transform_context *ctx,
81bf215546Sopenharmony_ci                            const struct tgsi_full_instruction *inst);
82bf215546Sopenharmony_ci   void (*emit_declaration)(struct tgsi_transform_context *ctx,
83bf215546Sopenharmony_ci                            const struct tgsi_full_declaration *decl);
84bf215546Sopenharmony_ci   void (*emit_immediate)(struct tgsi_transform_context *ctx,
85bf215546Sopenharmony_ci                          const struct tgsi_full_immediate *imm);
86bf215546Sopenharmony_ci   void (*emit_property)(struct tgsi_transform_context *ctx,
87bf215546Sopenharmony_ci                         const struct tgsi_full_property *prop);
88bf215546Sopenharmony_ci
89bf215546Sopenharmony_ci   struct tgsi_header *header;
90bf215546Sopenharmony_ci   uint max_tokens_out;
91bf215546Sopenharmony_ci   struct tgsi_token *tokens_out;
92bf215546Sopenharmony_ci   uint ti;
93bf215546Sopenharmony_ci   bool fail;
94bf215546Sopenharmony_ci};
95bf215546Sopenharmony_ci
96bf215546Sopenharmony_ci
97bf215546Sopenharmony_ci/**
98bf215546Sopenharmony_ci * Helper for emitting temporary register declarations.
99bf215546Sopenharmony_ci */
100bf215546Sopenharmony_cistatic inline void
101bf215546Sopenharmony_citgsi_transform_temps_decl(struct tgsi_transform_context *ctx,
102bf215546Sopenharmony_ci                          unsigned firstIdx, unsigned lastIdx)
103bf215546Sopenharmony_ci{
104bf215546Sopenharmony_ci   struct tgsi_full_declaration decl;
105bf215546Sopenharmony_ci
106bf215546Sopenharmony_ci   decl = tgsi_default_full_declaration();
107bf215546Sopenharmony_ci   decl.Declaration.File = TGSI_FILE_TEMPORARY;
108bf215546Sopenharmony_ci   decl.Range.First = firstIdx;
109bf215546Sopenharmony_ci   decl.Range.Last = lastIdx;
110bf215546Sopenharmony_ci   ctx->emit_declaration(ctx, &decl);
111bf215546Sopenharmony_ci}
112bf215546Sopenharmony_ci
113bf215546Sopenharmony_cistatic inline void
114bf215546Sopenharmony_citgsi_transform_temp_decl(struct tgsi_transform_context *ctx,
115bf215546Sopenharmony_ci                         unsigned index)
116bf215546Sopenharmony_ci{
117bf215546Sopenharmony_ci   tgsi_transform_temps_decl(ctx, index, index);
118bf215546Sopenharmony_ci}
119bf215546Sopenharmony_ci
120bf215546Sopenharmony_cistatic inline void
121bf215546Sopenharmony_citgsi_transform_const_decl(struct tgsi_transform_context *ctx,
122bf215546Sopenharmony_ci                          unsigned firstIdx, unsigned lastIdx)
123bf215546Sopenharmony_ci{
124bf215546Sopenharmony_ci   struct tgsi_full_declaration decl;
125bf215546Sopenharmony_ci
126bf215546Sopenharmony_ci   decl = tgsi_default_full_declaration();
127bf215546Sopenharmony_ci   decl.Declaration.File = TGSI_FILE_CONSTANT;
128bf215546Sopenharmony_ci   decl.Range.First = firstIdx;
129bf215546Sopenharmony_ci   decl.Range.Last = lastIdx;
130bf215546Sopenharmony_ci   decl.Declaration.Dimension = 1;
131bf215546Sopenharmony_ci   /* Dim.Index2D is already 0 */
132bf215546Sopenharmony_ci   ctx->emit_declaration(ctx, &decl);
133bf215546Sopenharmony_ci}
134bf215546Sopenharmony_ci
135bf215546Sopenharmony_cistatic inline void
136bf215546Sopenharmony_citgsi_transform_input_decl(struct tgsi_transform_context *ctx,
137bf215546Sopenharmony_ci                          unsigned index,
138bf215546Sopenharmony_ci                          unsigned sem_name, unsigned sem_index,
139bf215546Sopenharmony_ci                          unsigned interp)
140bf215546Sopenharmony_ci{
141bf215546Sopenharmony_ci   struct tgsi_full_declaration decl;
142bf215546Sopenharmony_ci
143bf215546Sopenharmony_ci   decl = tgsi_default_full_declaration();
144bf215546Sopenharmony_ci   decl.Declaration.File = TGSI_FILE_INPUT;
145bf215546Sopenharmony_ci   decl.Declaration.Interpolate = 1;
146bf215546Sopenharmony_ci   decl.Declaration.Semantic = 1;
147bf215546Sopenharmony_ci   decl.Semantic.Name = sem_name;
148bf215546Sopenharmony_ci   decl.Semantic.Index = sem_index;
149bf215546Sopenharmony_ci   decl.Range.First =
150bf215546Sopenharmony_ci   decl.Range.Last = index;
151bf215546Sopenharmony_ci   decl.Interp.Interpolate = interp;
152bf215546Sopenharmony_ci
153bf215546Sopenharmony_ci   ctx->emit_declaration(ctx, &decl);
154bf215546Sopenharmony_ci}
155bf215546Sopenharmony_ci
156bf215546Sopenharmony_cistatic inline void
157bf215546Sopenharmony_citgsi_transform_output_decl(struct tgsi_transform_context *ctx,
158bf215546Sopenharmony_ci                          unsigned index,
159bf215546Sopenharmony_ci                          unsigned sem_name, unsigned sem_index,
160bf215546Sopenharmony_ci                          unsigned interp)
161bf215546Sopenharmony_ci{
162bf215546Sopenharmony_ci   struct tgsi_full_declaration decl;
163bf215546Sopenharmony_ci
164bf215546Sopenharmony_ci   decl = tgsi_default_full_declaration();
165bf215546Sopenharmony_ci   decl.Declaration.File = TGSI_FILE_OUTPUT;
166bf215546Sopenharmony_ci   decl.Declaration.Interpolate = 1;
167bf215546Sopenharmony_ci   decl.Declaration.Semantic = 1;
168bf215546Sopenharmony_ci   decl.Semantic.Name = sem_name;
169bf215546Sopenharmony_ci   decl.Semantic.Index = sem_index;
170bf215546Sopenharmony_ci   decl.Range.First =
171bf215546Sopenharmony_ci   decl.Range.Last = index;
172bf215546Sopenharmony_ci   decl.Interp.Interpolate = interp;
173bf215546Sopenharmony_ci
174bf215546Sopenharmony_ci   ctx->emit_declaration(ctx, &decl);
175bf215546Sopenharmony_ci}
176bf215546Sopenharmony_ci
177bf215546Sopenharmony_cistatic inline void
178bf215546Sopenharmony_citgsi_transform_sampler_decl(struct tgsi_transform_context *ctx,
179bf215546Sopenharmony_ci                            unsigned index)
180bf215546Sopenharmony_ci{
181bf215546Sopenharmony_ci   struct tgsi_full_declaration decl;
182bf215546Sopenharmony_ci
183bf215546Sopenharmony_ci   decl = tgsi_default_full_declaration();
184bf215546Sopenharmony_ci   decl.Declaration.File = TGSI_FILE_SAMPLER;
185bf215546Sopenharmony_ci   decl.Range.First =
186bf215546Sopenharmony_ci   decl.Range.Last = index;
187bf215546Sopenharmony_ci   ctx->emit_declaration(ctx, &decl);
188bf215546Sopenharmony_ci}
189bf215546Sopenharmony_ci
190bf215546Sopenharmony_cistatic inline void
191bf215546Sopenharmony_citgsi_transform_sampler_view_decl(struct tgsi_transform_context *ctx,
192bf215546Sopenharmony_ci                                 unsigned index,
193bf215546Sopenharmony_ci                                 unsigned target,
194bf215546Sopenharmony_ci                                 enum tgsi_return_type type)
195bf215546Sopenharmony_ci{
196bf215546Sopenharmony_ci   struct tgsi_full_declaration decl;
197bf215546Sopenharmony_ci
198bf215546Sopenharmony_ci   decl = tgsi_default_full_declaration();
199bf215546Sopenharmony_ci   decl.Declaration.File = TGSI_FILE_SAMPLER_VIEW;
200bf215546Sopenharmony_ci   decl.Declaration.UsageMask = TGSI_WRITEMASK_XYZW;
201bf215546Sopenharmony_ci   decl.Range.First =
202bf215546Sopenharmony_ci   decl.Range.Last = index;
203bf215546Sopenharmony_ci   decl.SamplerView.Resource = target;
204bf215546Sopenharmony_ci   decl.SamplerView.ReturnTypeX = type;
205bf215546Sopenharmony_ci   decl.SamplerView.ReturnTypeY = type;
206bf215546Sopenharmony_ci   decl.SamplerView.ReturnTypeZ = type;
207bf215546Sopenharmony_ci   decl.SamplerView.ReturnTypeW = type;
208bf215546Sopenharmony_ci
209bf215546Sopenharmony_ci   ctx->emit_declaration(ctx, &decl);
210bf215546Sopenharmony_ci}
211bf215546Sopenharmony_ci
212bf215546Sopenharmony_cistatic inline void
213bf215546Sopenharmony_citgsi_transform_immediate_decl(struct tgsi_transform_context *ctx,
214bf215546Sopenharmony_ci                              float x, float y, float z, float w)
215bf215546Sopenharmony_ci{
216bf215546Sopenharmony_ci   struct tgsi_full_immediate immed;
217bf215546Sopenharmony_ci   unsigned size = 4;
218bf215546Sopenharmony_ci
219bf215546Sopenharmony_ci   immed = tgsi_default_full_immediate();
220bf215546Sopenharmony_ci   immed.Immediate.NrTokens = 1 + size; /* one for the token itself */
221bf215546Sopenharmony_ci   immed.u[0].Float = x;
222bf215546Sopenharmony_ci   immed.u[1].Float = y;
223bf215546Sopenharmony_ci   immed.u[2].Float = z;
224bf215546Sopenharmony_ci   immed.u[3].Float = w;
225bf215546Sopenharmony_ci
226bf215546Sopenharmony_ci   ctx->emit_immediate(ctx, &immed);
227bf215546Sopenharmony_ci}
228bf215546Sopenharmony_ci
229bf215546Sopenharmony_cistatic inline void
230bf215546Sopenharmony_citgsi_transform_immediate_int_decl(struct tgsi_transform_context *ctx,
231bf215546Sopenharmony_ci                                  int x, int y, int z, int w)
232bf215546Sopenharmony_ci{
233bf215546Sopenharmony_ci   struct tgsi_full_immediate immed;
234bf215546Sopenharmony_ci   unsigned size = 4;
235bf215546Sopenharmony_ci
236bf215546Sopenharmony_ci   immed = tgsi_default_full_immediate();
237bf215546Sopenharmony_ci   immed.Immediate.DataType = TGSI_IMM_INT32;
238bf215546Sopenharmony_ci   immed.Immediate.NrTokens = 1 + size; /* one for the token itself */
239bf215546Sopenharmony_ci   immed.u[0].Int = x;
240bf215546Sopenharmony_ci   immed.u[1].Int = y;
241bf215546Sopenharmony_ci   immed.u[2].Int = z;
242bf215546Sopenharmony_ci   immed.u[3].Int = w;
243bf215546Sopenharmony_ci
244bf215546Sopenharmony_ci   ctx->emit_immediate(ctx, &immed);
245bf215546Sopenharmony_ci}
246bf215546Sopenharmony_ci
247bf215546Sopenharmony_cistatic inline void
248bf215546Sopenharmony_citgsi_transform_dst_reg(struct tgsi_full_dst_register *reg,
249bf215546Sopenharmony_ci                       unsigned file, unsigned index, unsigned writemask)
250bf215546Sopenharmony_ci{
251bf215546Sopenharmony_ci   reg->Register.File = file;
252bf215546Sopenharmony_ci   reg->Register.Index = index;
253bf215546Sopenharmony_ci   reg->Register.WriteMask = writemask;
254bf215546Sopenharmony_ci}
255bf215546Sopenharmony_ci
256bf215546Sopenharmony_cistatic inline void
257bf215546Sopenharmony_citgsi_transform_src_reg_xyzw(struct tgsi_full_src_register *reg,
258bf215546Sopenharmony_ci                            unsigned file, unsigned index)
259bf215546Sopenharmony_ci{
260bf215546Sopenharmony_ci   reg->Register.File = file;
261bf215546Sopenharmony_ci   reg->Register.Index = index;
262bf215546Sopenharmony_ci   if (file == TGSI_FILE_CONSTANT) {
263bf215546Sopenharmony_ci      reg->Register.Dimension = 1;
264bf215546Sopenharmony_ci      reg->Dimension.Index = 0;
265bf215546Sopenharmony_ci   }
266bf215546Sopenharmony_ci}
267bf215546Sopenharmony_ci
268bf215546Sopenharmony_cistatic inline void
269bf215546Sopenharmony_citgsi_transform_src_reg(struct tgsi_full_src_register *reg,
270bf215546Sopenharmony_ci                       unsigned file, unsigned index,
271bf215546Sopenharmony_ci                       unsigned swizzleX, unsigned swizzleY,
272bf215546Sopenharmony_ci                       unsigned swizzleZ, unsigned swizzleW)
273bf215546Sopenharmony_ci{
274bf215546Sopenharmony_ci   reg->Register.File = file;
275bf215546Sopenharmony_ci   reg->Register.Index = index;
276bf215546Sopenharmony_ci   if (file == TGSI_FILE_CONSTANT) {
277bf215546Sopenharmony_ci      reg->Register.Dimension = 1;
278bf215546Sopenharmony_ci      reg->Dimension.Index = 0;
279bf215546Sopenharmony_ci   }
280bf215546Sopenharmony_ci   reg->Register.SwizzleX = swizzleX;
281bf215546Sopenharmony_ci   reg->Register.SwizzleY = swizzleY;
282bf215546Sopenharmony_ci   reg->Register.SwizzleZ = swizzleZ;
283bf215546Sopenharmony_ci   reg->Register.SwizzleW = swizzleW;
284bf215546Sopenharmony_ci}
285bf215546Sopenharmony_ci
286bf215546Sopenharmony_ci/**
287bf215546Sopenharmony_ci * Helper for emitting 1-operand instructions.
288bf215546Sopenharmony_ci */
289bf215546Sopenharmony_cistatic inline void
290bf215546Sopenharmony_citgsi_transform_op1_inst(struct tgsi_transform_context *ctx,
291bf215546Sopenharmony_ci                        enum tgsi_opcode opcode,
292bf215546Sopenharmony_ci                        unsigned dst_file,
293bf215546Sopenharmony_ci                        unsigned dst_index,
294bf215546Sopenharmony_ci                        unsigned dst_writemask,
295bf215546Sopenharmony_ci                        unsigned src0_file,
296bf215546Sopenharmony_ci                        unsigned src0_index)
297bf215546Sopenharmony_ci{
298bf215546Sopenharmony_ci   struct tgsi_full_instruction inst;
299bf215546Sopenharmony_ci
300bf215546Sopenharmony_ci   inst = tgsi_default_full_instruction();
301bf215546Sopenharmony_ci   inst.Instruction.Opcode = opcode;
302bf215546Sopenharmony_ci   inst.Instruction.NumDstRegs = 1;
303bf215546Sopenharmony_ci   inst.Dst[0].Register.File = dst_file,
304bf215546Sopenharmony_ci   inst.Dst[0].Register.Index = dst_index;
305bf215546Sopenharmony_ci   inst.Dst[0].Register.WriteMask = dst_writemask;
306bf215546Sopenharmony_ci   inst.Instruction.NumSrcRegs = 1;
307bf215546Sopenharmony_ci   tgsi_transform_src_reg_xyzw(&inst.Src[0], src0_file, src0_index);
308bf215546Sopenharmony_ci
309bf215546Sopenharmony_ci   ctx->emit_instruction(ctx, &inst);
310bf215546Sopenharmony_ci}
311bf215546Sopenharmony_ci
312bf215546Sopenharmony_ci
313bf215546Sopenharmony_cistatic inline void
314bf215546Sopenharmony_citgsi_transform_op2_inst(struct tgsi_transform_context *ctx,
315bf215546Sopenharmony_ci                        enum tgsi_opcode opcode,
316bf215546Sopenharmony_ci                        unsigned dst_file,
317bf215546Sopenharmony_ci                        unsigned dst_index,
318bf215546Sopenharmony_ci                        unsigned dst_writemask,
319bf215546Sopenharmony_ci                        unsigned src0_file,
320bf215546Sopenharmony_ci                        unsigned src0_index,
321bf215546Sopenharmony_ci                        unsigned src1_file,
322bf215546Sopenharmony_ci                        unsigned src1_index,
323bf215546Sopenharmony_ci                        bool src1_negate)
324bf215546Sopenharmony_ci{
325bf215546Sopenharmony_ci   struct tgsi_full_instruction inst;
326bf215546Sopenharmony_ci
327bf215546Sopenharmony_ci   inst = tgsi_default_full_instruction();
328bf215546Sopenharmony_ci   inst.Instruction.Opcode = opcode;
329bf215546Sopenharmony_ci   inst.Instruction.NumDstRegs = 1;
330bf215546Sopenharmony_ci   inst.Dst[0].Register.File = dst_file,
331bf215546Sopenharmony_ci   inst.Dst[0].Register.Index = dst_index;
332bf215546Sopenharmony_ci   inst.Dst[0].Register.WriteMask = dst_writemask;
333bf215546Sopenharmony_ci   inst.Instruction.NumSrcRegs = 2;
334bf215546Sopenharmony_ci   tgsi_transform_src_reg_xyzw(&inst.Src[0], src0_file, src0_index);
335bf215546Sopenharmony_ci   tgsi_transform_src_reg_xyzw(&inst.Src[1], src1_file, src1_index);
336bf215546Sopenharmony_ci   inst.Src[1].Register.Negate = src1_negate;
337bf215546Sopenharmony_ci
338bf215546Sopenharmony_ci   ctx->emit_instruction(ctx, &inst);
339bf215546Sopenharmony_ci}
340bf215546Sopenharmony_ci
341bf215546Sopenharmony_ci
342bf215546Sopenharmony_cistatic inline void
343bf215546Sopenharmony_citgsi_transform_op3_inst(struct tgsi_transform_context *ctx,
344bf215546Sopenharmony_ci                        enum tgsi_opcode opcode,
345bf215546Sopenharmony_ci                        unsigned dst_file,
346bf215546Sopenharmony_ci                        unsigned dst_index,
347bf215546Sopenharmony_ci                        unsigned dst_writemask,
348bf215546Sopenharmony_ci                        unsigned src0_file,
349bf215546Sopenharmony_ci                        unsigned src0_index,
350bf215546Sopenharmony_ci                        unsigned src1_file,
351bf215546Sopenharmony_ci                        unsigned src1_index,
352bf215546Sopenharmony_ci                        unsigned src2_file,
353bf215546Sopenharmony_ci                        unsigned src2_index)
354bf215546Sopenharmony_ci{
355bf215546Sopenharmony_ci   struct tgsi_full_instruction inst;
356bf215546Sopenharmony_ci
357bf215546Sopenharmony_ci   inst = tgsi_default_full_instruction();
358bf215546Sopenharmony_ci   inst.Instruction.Opcode = opcode;
359bf215546Sopenharmony_ci   inst.Instruction.NumDstRegs = 1;
360bf215546Sopenharmony_ci   inst.Dst[0].Register.File = dst_file,
361bf215546Sopenharmony_ci   inst.Dst[0].Register.Index = dst_index;
362bf215546Sopenharmony_ci   inst.Dst[0].Register.WriteMask = dst_writemask;
363bf215546Sopenharmony_ci   inst.Instruction.NumSrcRegs = 3;
364bf215546Sopenharmony_ci   tgsi_transform_src_reg_xyzw(&inst.Src[0], src0_file, src0_index);
365bf215546Sopenharmony_ci   tgsi_transform_src_reg_xyzw(&inst.Src[1], src1_file, src1_index);
366bf215546Sopenharmony_ci   tgsi_transform_src_reg_xyzw(&inst.Src[2], src2_file, src2_index);
367bf215546Sopenharmony_ci
368bf215546Sopenharmony_ci   ctx->emit_instruction(ctx, &inst);
369bf215546Sopenharmony_ci}
370bf215546Sopenharmony_ci
371bf215546Sopenharmony_ci
372bf215546Sopenharmony_ci
373bf215546Sopenharmony_cistatic inline void
374bf215546Sopenharmony_citgsi_transform_op1_swz_inst(struct tgsi_transform_context *ctx,
375bf215546Sopenharmony_ci                            enum tgsi_opcode opcode,
376bf215546Sopenharmony_ci                            unsigned dst_file,
377bf215546Sopenharmony_ci                            unsigned dst_index,
378bf215546Sopenharmony_ci                            unsigned dst_writemask,
379bf215546Sopenharmony_ci                            unsigned src0_file,
380bf215546Sopenharmony_ci                            unsigned src0_index,
381bf215546Sopenharmony_ci                            unsigned src0_swizzle)
382bf215546Sopenharmony_ci{
383bf215546Sopenharmony_ci   struct tgsi_full_instruction inst;
384bf215546Sopenharmony_ci
385bf215546Sopenharmony_ci   inst = tgsi_default_full_instruction();
386bf215546Sopenharmony_ci   inst.Instruction.Opcode = opcode;
387bf215546Sopenharmony_ci   inst.Instruction.NumDstRegs = 1;
388bf215546Sopenharmony_ci   inst.Dst[0].Register.File = dst_file,
389bf215546Sopenharmony_ci   inst.Dst[0].Register.Index = dst_index;
390bf215546Sopenharmony_ci   inst.Dst[0].Register.WriteMask = dst_writemask;
391bf215546Sopenharmony_ci   inst.Instruction.NumSrcRegs = 1;
392bf215546Sopenharmony_ci   tgsi_transform_src_reg_xyzw(&inst.Src[0], src0_file, src0_index);
393bf215546Sopenharmony_ci   switch (dst_writemask) {
394bf215546Sopenharmony_ci   case TGSI_WRITEMASK_X:
395bf215546Sopenharmony_ci      inst.Src[0].Register.SwizzleX = src0_swizzle;
396bf215546Sopenharmony_ci      break;
397bf215546Sopenharmony_ci   case TGSI_WRITEMASK_Y:
398bf215546Sopenharmony_ci      inst.Src[0].Register.SwizzleY = src0_swizzle;
399bf215546Sopenharmony_ci      break;
400bf215546Sopenharmony_ci   case TGSI_WRITEMASK_Z:
401bf215546Sopenharmony_ci      inst.Src[0].Register.SwizzleZ = src0_swizzle;
402bf215546Sopenharmony_ci      break;
403bf215546Sopenharmony_ci   case TGSI_WRITEMASK_W:
404bf215546Sopenharmony_ci      inst.Src[0].Register.SwizzleW = src0_swizzle;
405bf215546Sopenharmony_ci      break;
406bf215546Sopenharmony_ci   default:
407bf215546Sopenharmony_ci      ; /* nothing */
408bf215546Sopenharmony_ci   }
409bf215546Sopenharmony_ci
410bf215546Sopenharmony_ci   ctx->emit_instruction(ctx, &inst);
411bf215546Sopenharmony_ci}
412bf215546Sopenharmony_ci
413bf215546Sopenharmony_ci
414bf215546Sopenharmony_cistatic inline void
415bf215546Sopenharmony_citgsi_transform_op2_swz_inst(struct tgsi_transform_context *ctx,
416bf215546Sopenharmony_ci                            enum tgsi_opcode opcode,
417bf215546Sopenharmony_ci                            unsigned dst_file,
418bf215546Sopenharmony_ci                            unsigned dst_index,
419bf215546Sopenharmony_ci                            unsigned dst_writemask,
420bf215546Sopenharmony_ci                            unsigned src0_file,
421bf215546Sopenharmony_ci                            unsigned src0_index,
422bf215546Sopenharmony_ci                            unsigned src0_swizzle,
423bf215546Sopenharmony_ci                            unsigned src1_file,
424bf215546Sopenharmony_ci                            unsigned src1_index,
425bf215546Sopenharmony_ci                            unsigned src1_swizzle,
426bf215546Sopenharmony_ci                            bool src1_negate)
427bf215546Sopenharmony_ci{
428bf215546Sopenharmony_ci   struct tgsi_full_instruction inst;
429bf215546Sopenharmony_ci
430bf215546Sopenharmony_ci   inst = tgsi_default_full_instruction();
431bf215546Sopenharmony_ci   inst.Instruction.Opcode = opcode;
432bf215546Sopenharmony_ci   inst.Instruction.NumDstRegs = 1;
433bf215546Sopenharmony_ci   inst.Dst[0].Register.File = dst_file,
434bf215546Sopenharmony_ci   inst.Dst[0].Register.Index = dst_index;
435bf215546Sopenharmony_ci   inst.Dst[0].Register.WriteMask = dst_writemask;
436bf215546Sopenharmony_ci   inst.Instruction.NumSrcRegs = 2;
437bf215546Sopenharmony_ci   tgsi_transform_src_reg_xyzw(&inst.Src[0], src0_file, src0_index);
438bf215546Sopenharmony_ci   tgsi_transform_src_reg_xyzw(&inst.Src[1], src1_file, src1_index);
439bf215546Sopenharmony_ci   inst.Src[1].Register.Negate = src1_negate;
440bf215546Sopenharmony_ci   switch (dst_writemask) {
441bf215546Sopenharmony_ci   case TGSI_WRITEMASK_X:
442bf215546Sopenharmony_ci      inst.Src[0].Register.SwizzleX = src0_swizzle;
443bf215546Sopenharmony_ci      inst.Src[1].Register.SwizzleX = src1_swizzle;
444bf215546Sopenharmony_ci      break;
445bf215546Sopenharmony_ci   case TGSI_WRITEMASK_Y:
446bf215546Sopenharmony_ci      inst.Src[0].Register.SwizzleY = src0_swizzle;
447bf215546Sopenharmony_ci      inst.Src[1].Register.SwizzleY = src1_swizzle;
448bf215546Sopenharmony_ci      break;
449bf215546Sopenharmony_ci   case TGSI_WRITEMASK_Z:
450bf215546Sopenharmony_ci      inst.Src[0].Register.SwizzleZ = src0_swizzle;
451bf215546Sopenharmony_ci      inst.Src[1].Register.SwizzleZ = src1_swizzle;
452bf215546Sopenharmony_ci      break;
453bf215546Sopenharmony_ci   case TGSI_WRITEMASK_W:
454bf215546Sopenharmony_ci      inst.Src[0].Register.SwizzleW = src0_swizzle;
455bf215546Sopenharmony_ci      inst.Src[1].Register.SwizzleW = src1_swizzle;
456bf215546Sopenharmony_ci      break;
457bf215546Sopenharmony_ci   default:
458bf215546Sopenharmony_ci      ; /* nothing */
459bf215546Sopenharmony_ci   }
460bf215546Sopenharmony_ci
461bf215546Sopenharmony_ci   ctx->emit_instruction(ctx, &inst);
462bf215546Sopenharmony_ci}
463bf215546Sopenharmony_ci
464bf215546Sopenharmony_ci
465bf215546Sopenharmony_cistatic inline void
466bf215546Sopenharmony_citgsi_transform_op3_swz_inst(struct tgsi_transform_context *ctx,
467bf215546Sopenharmony_ci                            enum tgsi_opcode opcode,
468bf215546Sopenharmony_ci                            unsigned dst_file,
469bf215546Sopenharmony_ci                            unsigned dst_index,
470bf215546Sopenharmony_ci                            unsigned dst_writemask,
471bf215546Sopenharmony_ci                            unsigned src0_file,
472bf215546Sopenharmony_ci                            unsigned src0_index,
473bf215546Sopenharmony_ci                            unsigned src0_swizzle,
474bf215546Sopenharmony_ci                            unsigned src0_negate,
475bf215546Sopenharmony_ci                            unsigned src1_file,
476bf215546Sopenharmony_ci                            unsigned src1_index,
477bf215546Sopenharmony_ci                            unsigned src1_swizzle,
478bf215546Sopenharmony_ci                            unsigned src2_file,
479bf215546Sopenharmony_ci                            unsigned src2_index,
480bf215546Sopenharmony_ci                            unsigned src2_swizzle)
481bf215546Sopenharmony_ci{
482bf215546Sopenharmony_ci   struct tgsi_full_instruction inst;
483bf215546Sopenharmony_ci
484bf215546Sopenharmony_ci   inst = tgsi_default_full_instruction();
485bf215546Sopenharmony_ci   inst.Instruction.Opcode = opcode;
486bf215546Sopenharmony_ci   inst.Instruction.NumDstRegs = 1;
487bf215546Sopenharmony_ci   inst.Dst[0].Register.File = dst_file,
488bf215546Sopenharmony_ci   inst.Dst[0].Register.Index = dst_index;
489bf215546Sopenharmony_ci   inst.Dst[0].Register.WriteMask = dst_writemask;
490bf215546Sopenharmony_ci   inst.Instruction.NumSrcRegs = 3;
491bf215546Sopenharmony_ci   tgsi_transform_src_reg_xyzw(&inst.Src[0], src0_file, src0_index);
492bf215546Sopenharmony_ci   inst.Src[0].Register.Negate = src0_negate;
493bf215546Sopenharmony_ci   tgsi_transform_src_reg_xyzw(&inst.Src[1], src1_file, src1_index);
494bf215546Sopenharmony_ci   tgsi_transform_src_reg_xyzw(&inst.Src[2], src2_file, src2_index);
495bf215546Sopenharmony_ci   switch (dst_writemask) {
496bf215546Sopenharmony_ci   case TGSI_WRITEMASK_X:
497bf215546Sopenharmony_ci      inst.Src[0].Register.SwizzleX = src0_swizzle;
498bf215546Sopenharmony_ci      inst.Src[1].Register.SwizzleX = src1_swizzle;
499bf215546Sopenharmony_ci      inst.Src[2].Register.SwizzleX = src2_swizzle;
500bf215546Sopenharmony_ci      break;
501bf215546Sopenharmony_ci   case TGSI_WRITEMASK_Y:
502bf215546Sopenharmony_ci      inst.Src[0].Register.SwizzleY = src0_swizzle;
503bf215546Sopenharmony_ci      inst.Src[1].Register.SwizzleY = src1_swizzle;
504bf215546Sopenharmony_ci      inst.Src[2].Register.SwizzleY = src2_swizzle;
505bf215546Sopenharmony_ci      break;
506bf215546Sopenharmony_ci   case TGSI_WRITEMASK_Z:
507bf215546Sopenharmony_ci      inst.Src[0].Register.SwizzleZ = src0_swizzle;
508bf215546Sopenharmony_ci      inst.Src[1].Register.SwizzleZ = src1_swizzle;
509bf215546Sopenharmony_ci      inst.Src[2].Register.SwizzleZ = src2_swizzle;
510bf215546Sopenharmony_ci      break;
511bf215546Sopenharmony_ci   case TGSI_WRITEMASK_W:
512bf215546Sopenharmony_ci      inst.Src[0].Register.SwizzleW = src0_swizzle;
513bf215546Sopenharmony_ci      inst.Src[1].Register.SwizzleW = src1_swizzle;
514bf215546Sopenharmony_ci      inst.Src[2].Register.SwizzleW = src2_swizzle;
515bf215546Sopenharmony_ci      break;
516bf215546Sopenharmony_ci   default:
517bf215546Sopenharmony_ci      ; /* nothing */
518bf215546Sopenharmony_ci   }
519bf215546Sopenharmony_ci
520bf215546Sopenharmony_ci   ctx->emit_instruction(ctx, &inst);
521bf215546Sopenharmony_ci}
522bf215546Sopenharmony_ci
523bf215546Sopenharmony_ci
524bf215546Sopenharmony_cistatic inline void
525bf215546Sopenharmony_citgsi_transform_kill_inst(struct tgsi_transform_context *ctx,
526bf215546Sopenharmony_ci                         unsigned src_file,
527bf215546Sopenharmony_ci                         unsigned src_index,
528bf215546Sopenharmony_ci                         unsigned src_swizzle,
529bf215546Sopenharmony_ci                         boolean negate)
530bf215546Sopenharmony_ci{
531bf215546Sopenharmony_ci   struct tgsi_full_instruction inst;
532bf215546Sopenharmony_ci
533bf215546Sopenharmony_ci   inst = tgsi_default_full_instruction();
534bf215546Sopenharmony_ci   inst.Instruction.Opcode = TGSI_OPCODE_KILL_IF;
535bf215546Sopenharmony_ci   inst.Instruction.NumDstRegs = 0;
536bf215546Sopenharmony_ci   inst.Instruction.NumSrcRegs = 1;
537bf215546Sopenharmony_ci   tgsi_transform_src_reg_xyzw(&inst.Src[0], src_file, src_index);
538bf215546Sopenharmony_ci   inst.Src[0].Register.SwizzleX =
539bf215546Sopenharmony_ci   inst.Src[0].Register.SwizzleY =
540bf215546Sopenharmony_ci   inst.Src[0].Register.SwizzleZ =
541bf215546Sopenharmony_ci   inst.Src[0].Register.SwizzleW = src_swizzle;
542bf215546Sopenharmony_ci   inst.Src[0].Register.Negate = negate;
543bf215546Sopenharmony_ci
544bf215546Sopenharmony_ci   ctx->emit_instruction(ctx, &inst);
545bf215546Sopenharmony_ci}
546bf215546Sopenharmony_ci
547bf215546Sopenharmony_ci
548bf215546Sopenharmony_cistatic inline void
549bf215546Sopenharmony_citgsi_transform_tex_inst(struct tgsi_transform_context *ctx,
550bf215546Sopenharmony_ci                        unsigned dst_file,
551bf215546Sopenharmony_ci                        unsigned dst_index,
552bf215546Sopenharmony_ci                        unsigned src_file,
553bf215546Sopenharmony_ci                        unsigned src_index,
554bf215546Sopenharmony_ci                        unsigned tex_target,
555bf215546Sopenharmony_ci                        unsigned sampler_index)
556bf215546Sopenharmony_ci{
557bf215546Sopenharmony_ci   struct tgsi_full_instruction inst;
558bf215546Sopenharmony_ci
559bf215546Sopenharmony_ci   assert(tex_target < TGSI_TEXTURE_COUNT);
560bf215546Sopenharmony_ci
561bf215546Sopenharmony_ci   inst = tgsi_default_full_instruction();
562bf215546Sopenharmony_ci   inst.Instruction.Opcode = TGSI_OPCODE_TEX;
563bf215546Sopenharmony_ci   inst.Instruction.NumDstRegs = 1;
564bf215546Sopenharmony_ci   inst.Dst[0].Register.File = dst_file;
565bf215546Sopenharmony_ci   inst.Dst[0].Register.Index = dst_index;
566bf215546Sopenharmony_ci   inst.Instruction.NumSrcRegs = 2;
567bf215546Sopenharmony_ci   inst.Instruction.Texture = TRUE;
568bf215546Sopenharmony_ci   inst.Texture.Texture = tex_target;
569bf215546Sopenharmony_ci   tgsi_transform_src_reg_xyzw(&inst.Src[0], src_file, src_index);
570bf215546Sopenharmony_ci   tgsi_transform_src_reg_xyzw(&inst.Src[1], TGSI_FILE_SAMPLER, sampler_index);
571bf215546Sopenharmony_ci
572bf215546Sopenharmony_ci   ctx->emit_instruction(ctx, &inst);
573bf215546Sopenharmony_ci}
574bf215546Sopenharmony_ci
575bf215546Sopenharmony_ci
576bf215546Sopenharmony_ciextern struct tgsi_token *
577bf215546Sopenharmony_citgsi_transform_shader(const struct tgsi_token *tokens_in,
578bf215546Sopenharmony_ci                      uint initial_tokens_len,
579bf215546Sopenharmony_ci                      struct tgsi_transform_context *ctx);
580bf215546Sopenharmony_ci
581bf215546Sopenharmony_ci
582bf215546Sopenharmony_ci#endif /* TGSI_TRANSFORM_H */
583