summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/svga/svga_tgsi_emit.h
blob: 357d772e7a6c7a4402229ecbb0e169bfc803617b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
/**********************************************************
 * Copyright 2008-2009 VMware, Inc.  All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 **********************************************************/

#ifndef SVGA_TGSI_EMIT_H
#define SVGA_TGSI_EMIT_H

#include "tgsi/tgsi_scan.h"
#include "svga_hw_reg.h"
#include "svga_shader.h"
#include "svga_tgsi.h"
#include "svga3d_shaderdefs.h"

struct src_register
{
   SVGA3dShaderSrcToken base;
   SVGA3dShaderSrcToken indirect;
};


struct svga_arl_consts
{
   int number;
   int idx;
   int swizzle;
   int arl_num;
};


/**
 * This is the context/state used during TGSI->SVGA shader translation.
 */
struct svga_shader_emitter
{
   unsigned size;
   char *buf;
   char *ptr;

   struct svga_compile_key key;
   struct tgsi_shader_info info;
   int unit;

   int imm_start;

   int nr_hw_float_const;
   int nr_hw_int_const;
   int nr_hw_temp;

   int insn_offset;

   int internal_temp_count;
   int internal_imm_count;

   int internal_color_idx[2]; /* diffuse, specular */
   int internal_color_count;

   boolean emitted_vface;
   boolean emit_frontface;
   int internal_frontface_idx;

   int ps30_input_count;
   int vs30_output_count;

   int dynamic_branching_level;

   unsigned num_output_writes;
   boolean constant_color_output;

   boolean in_main_func;

   boolean created_common_immediate;
   int common_immediate_idx[2];

   boolean created_loop_const;
   int loop_const_idx;

   unsigned inverted_texcoords;  /**< bitmask of which texcoords are flipped */
   struct src_register ps_true_texcoord[PIPE_MAX_ATTRIBS];
   struct src_register ps_inverted_texcoord[PIPE_MAX_ATTRIBS];
   unsigned ps_inverted_texcoord_input[PIPE_MAX_ATTRIBS];

   unsigned label[32];
   unsigned nr_labels;

   /** input/output register mappings, indexed by register number */
   struct src_register input_map[PIPE_MAX_ATTRIBS];
   SVGA3dShaderDestToken output_map[PIPE_MAX_ATTRIBS];

   boolean ps_reads_pos;
   boolean emitted_depth_fog;
   struct src_register ps_true_pos;
   struct src_register ps_depth_pos;
   SVGA3dShaderDestToken ps_temp_pos;

   /* shared input for depth and fog */
   struct src_register ps_depth_fog;

   struct src_register imm_0055;
   SVGA3dShaderDestToken temp_pos;
   SVGA3dShaderDestToken true_pos;
   SVGA3dShaderDestToken depth_pos;

   /* shared output for depth and fog */
   SVGA3dShaderDestToken vs_depth_fog;

   /* PS output colors (indexed by color semantic index) */
   SVGA3dShaderDestToken temp_color_output[PIPE_MAX_COLOR_BUFS];
   SVGA3dShaderDestToken true_color_output[PIPE_MAX_COLOR_BUFS];

   SVGA3dShaderDestToken temp_psiz;
   SVGA3dShaderDestToken true_psiz;

   struct svga_arl_consts arl_consts[12];
   int num_arl_consts;
   int current_arl;

   unsigned pstipple_sampler_unit;

   int num_samplers;
   uint8_t sampler_target[PIPE_MAX_SAMPLERS];
};


boolean
svga_shader_emit_dword(struct svga_shader_emitter *emit, unsigned dword);

boolean
svga_shader_emit_dwords(struct svga_shader_emitter *emit,
                        const unsigned *dwords, unsigned nr);

boolean
svga_shader_emit_opcode(struct svga_shader_emitter *emit,
                        unsigned opcode);

boolean
svga_shader_emit_instructions(struct svga_shader_emitter *emit,
                              const struct tgsi_token *tokens);

boolean
svga_shader_emit_samplers_decl(struct svga_shader_emitter *emit);

boolean
svga_translate_decl_sm30(struct svga_shader_emitter *emit,
                         const struct tgsi_full_declaration *decl);


#define TRANSLATE_SWIZZLE(x,y,z,w)  ((x) | ((y) << 2) | ((z) << 4) | ((w) << 6))
#define SWIZZLE_XYZW  \
 TRANSLATE_SWIZZLE(TGSI_SWIZZLE_X,TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Z,TGSI_SWIZZLE_W)
#define SWIZZLE_XXXX  \
 TRANSLATE_SWIZZLE(TGSI_SWIZZLE_X,TGSI_SWIZZLE_X,TGSI_SWIZZLE_X,TGSI_SWIZZLE_X)
#define SWIZZLE_YYYY  \
 TRANSLATE_SWIZZLE(TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Y)
#define SWIZZLE_ZZZZ  \
 TRANSLATE_SWIZZLE(TGSI_SWIZZLE_Z,TGSI_SWIZZLE_Z,TGSI_SWIZZLE_Z,TGSI_SWIZZLE_Z)
#define SWIZZLE_WWWW  \
 TRANSLATE_SWIZZLE(TGSI_SWIZZLE_W,TGSI_SWIZZLE_W,TGSI_SWIZZLE_W,TGSI_SWIZZLE_W)


/** Emit the given SVGA3dShaderInstToken opcode */
static inline boolean
emit_instruction(struct svga_shader_emitter *emit,
                 SVGA3dShaderInstToken opcode)
{
   return svga_shader_emit_opcode(emit, opcode.value);
}


/** Generate a SVGA3dShaderInstToken for the given SVGA3D shader opcode */
static inline SVGA3dShaderInstToken
inst_token(SVGA3dShaderOpCodeType opcode)
{
   SVGA3dShaderInstToken inst;

   inst.value = 0;
   inst.op = opcode;

   return inst;
}


/**
 * Generate a SVGA3dShaderInstToken for the given SVGA3D shader opcode
 * with the predication flag set.
 */
static inline SVGA3dShaderInstToken
inst_token_predicated(SVGA3dShaderOpCodeType opcode)
{
   SVGA3dShaderInstToken inst;

   inst.value = 0;
   inst.op = opcode;
   inst.predicated = 1;

   return inst;
}


/**
 * Generate a SVGA3dShaderInstToken for a SETP instruction (set predicate)
 * using the given comparison operator (one of SVGA3DOPCOMP_xx).
 */
static inline SVGA3dShaderInstToken
inst_token_setp(SVGA3dShaderOpCodeCompFnType operator)
{
   SVGA3dShaderInstToken inst;

   inst.value = 0;
   inst.op = SVGA3DOP_SETP;
   inst.control = operator;

   return inst;
}


/**
 * Create an instance of a SVGA3dShaderDestToken.
 * Note that this function is used to create tokens for output registers,
 * temp registers AND constants (see emit_def_const()).
 */
static inline SVGA3dShaderDestToken
dst_register(SVGA3dShaderRegType file, int number)
{
   SVGA3dShaderDestToken dest;

   /* check values against bitfield sizes */
   assert(number < (1 << 11));
   assert(file <= SVGA3DREG_PREDICATE);

   dest.value = 0;
   dest.num = number;
   dest.type_upper = file >> 3;
   dest.relAddr = 0;
   dest.reserved1 = 0;
   dest.mask = 0xf;
   dest.dstMod = 0;
   dest.shfScale = 0;
   dest.type_lower = file & 0x7;
   dest.reserved0 = 1;          /* is_reg */

   return dest;
}


/**
 * Apply a writemask to the given SVGA3dShaderDestToken, returning a
 * new SVGA3dShaderDestToken.
 */
static inline SVGA3dShaderDestToken
writemask(SVGA3dShaderDestToken dest, unsigned mask)
{
   assert(dest.mask & mask);
   dest.mask &= mask;
   return dest;
}


/** Create a SVGA3dShaderSrcToken given a register file and number */
static inline SVGA3dShaderSrcToken
src_token(SVGA3dShaderRegType file, int number)
{
   SVGA3dShaderSrcToken src;

   /* check values against bitfield sizes */
   assert(number < (1 << 11));
   assert(file <= SVGA3DREG_PREDICATE);

   src.value = 0;
   src.num = number;
   src.type_upper = file >> 3;
   src.relAddr = 0;
   src.reserved1 = 0;
   src.swizzle = SWIZZLE_XYZW;
   src.srcMod = 0;
   src.type_lower = file & 0x7;
   src.reserved0 = 1;           /* is_reg */

   return src;
}


/** Create a src_register given a register file and register number */
static inline struct src_register
src_register(SVGA3dShaderRegType file, int number)
{
   struct src_register src;

   src.base = src_token(file, number);
   src.indirect.value = 0;

   return src;
}

/** Translate src_register into SVGA3dShaderDestToken */
static inline SVGA3dShaderDestToken
dst(struct src_register src)
{
   return dst_register(SVGA3dShaderGetRegType(src.base.value), src.base.num);
}


/** Translate SVGA3dShaderDestToken to a src_register */
static inline struct src_register
src(SVGA3dShaderDestToken dst)
{
   return src_register(SVGA3dShaderGetRegType(dst.value), dst.num);
}

#endif