lima/ppir: add lod-bias support
[mesa.git] / src / gallium / drivers / lima / ir / pp / codegen.h
1 /*
2 * Copyright (c) 2017 Lima Project
3 * Copyright (c) 2013 Ben Brewer (ben.brewer@codethink.co.uk)
4 * Copyright (c) 2013 Connor Abbott (connor@abbott.cx)
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sub license,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to 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 portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 *
25 */
26
27 #ifndef LIMA_IR_PP_CODEGEN_H
28 #define LIMA_IR_PP_CODEGEN_H
29
30 #include <stdint.h>
31 #include <stdbool.h>
32
33 /* Control */
34
35 typedef union __attribute__((__packed__)) {
36 struct __attribute__((__packed__)) {
37 unsigned count : 5;
38 bool stop : 1;
39 bool sync : 1;
40 unsigned fields : 12;
41 unsigned next_count : 6;
42 bool prefetch : 1;
43 unsigned unknown : 6;
44 };
45 uint32_t mask;
46 } ppir_codegen_ctrl;
47
48 typedef enum {
49 ppir_codegen_field_shift_varying = 0,
50 ppir_codegen_field_shift_sampler = 1,
51 ppir_codegen_field_shift_uniform = 2,
52 ppir_codegen_field_shift_vec4_mul = 3,
53 ppir_codegen_field_shift_float_mul = 4,
54 ppir_codegen_field_shift_vec4_acc = 5,
55 ppir_codegen_field_shift_float_acc = 6,
56 ppir_codegen_field_shift_combine = 7,
57 ppir_codegen_field_shift_temp_write = 8,
58 ppir_codegen_field_shift_branch = 9,
59 ppir_codegen_field_shift_vec4_const_0 = 10,
60 ppir_codegen_field_shift_vec4_const_1 = 11,
61 ppir_codegen_field_shift_count = 12,
62 } ppir_codegen_field_shift;
63
64 /* Data Inputs */
65
66 typedef enum {
67 ppir_codegen_vec4_reg_frag_color = 0,
68 ppir_codegen_vec4_reg_constant0 = 12,
69 ppir_codegen_vec4_reg_constant1 = 13,
70 ppir_codegen_vec4_reg_texture = 14,
71 ppir_codegen_vec4_reg_uniform = 15,
72 ppir_codegen_vec4_reg_discard = 15,
73 } ppir_codegen_vec4_reg;
74
75 typedef union __attribute__((__packed__)) {
76 struct __attribute__((__packed__)) {
77 unsigned perspective : 2;
78 unsigned source_type : 2;
79 unsigned unknown_0 : 1; /* = 0 */
80 unsigned alignment : 2;
81 unsigned unknown_1 : 3; /* = 00 0 */
82 unsigned offset_vector : 4;
83 unsigned unknown_2 : 2; /* = 00 */
84 unsigned offset_scalar : 2;
85 unsigned index : 6;
86 ppir_codegen_vec4_reg dest : 4;
87 unsigned mask : 4;
88 unsigned unknown_3 : 2; /* = 00 */
89 } imm;
90 struct __attribute__((__packed__)) {
91 unsigned perspective : 2;
92 unsigned source_type : 2; /* = 01 */
93 unsigned unknown_0 : 2; /* = 00 */
94 bool normalize : 1;
95 unsigned unknown_1 : 3;
96 ppir_codegen_vec4_reg source : 4;
97 bool negate : 1;
98 bool absolute : 1;
99 unsigned swizzle : 8;
100 ppir_codegen_vec4_reg dest : 4;
101 unsigned mask : 4;
102 unsigned unknown_2 : 2; /* = 00 */
103 } reg;
104 } ppir_codegen_field_varying;
105
106 typedef enum {
107 ppir_codegen_sampler_type_2d = 0x00,
108 ppir_codegen_sampler_type_cube = 0x1F,
109 } ppir_codegen_sampler_type;
110
111 typedef struct __attribute__((__packed__)) {
112 unsigned lod_bias : 6;
113 unsigned index_offset : 6;
114 unsigned unknown_0 : 5; /* = 00000 */
115 bool explicit_lod : 1;
116 bool lod_bias_en : 1;
117 unsigned unknown_1 : 5; /* = 00000 */
118 ppir_codegen_sampler_type type : 5;
119 bool offset_en : 1;
120 unsigned index : 12;
121 unsigned unknown_2 : 20; /* = 0011 1001 0000 0000 0001 */
122 } ppir_codegen_field_sampler;
123
124 typedef enum {
125 ppir_codegen_uniform_src_uniform = 0,
126 ppir_codegen_uniform_src_temporary = 3,
127 } ppir_codegen_uniform_src;
128
129 typedef struct __attribute__((__packed__)) {
130 ppir_codegen_uniform_src source : 2;
131 unsigned unknown_0 : 8; /* = 00 0000 00 */
132 unsigned alignment : 2; /* 00: float, 01: vec2, 10: vec4 */
133 unsigned unknown_1 : 6; /* = 00 0000 */
134 unsigned offset_reg : 6;
135 bool offset_en : 1;
136 unsigned index : 16;
137 } ppir_codegen_field_uniform;
138
139 /* Vector Pipe */
140
141 typedef enum {
142 ppir_codegen_vec4_mul_op_not = 0x08, /* Logical Not */
143 ppir_codegen_vec4_mul_op_and = 0x09, /* Logical AND */
144 ppir_codegen_vec4_mul_op_or = 0x0A, /* Logical OR */
145 ppir_codegen_vec4_mul_op_xor = 0x0B, /* Logical XOR */
146 ppir_codegen_vec4_mul_op_ne = 0x0C, /* Not Equal */
147 ppir_codegen_vec4_mul_op_gt = 0x0D, /* Great Than */
148 ppir_codegen_vec4_mul_op_ge = 0x0E, /* Great than or Equal */
149 ppir_codegen_vec4_mul_op_eq = 0x0F, /* Equal */
150 ppir_codegen_vec4_mul_op_min = 0x10, /* Minimum */
151 ppir_codegen_vec4_mul_op_max = 0x11, /* Maximum */
152 ppir_codegen_vec4_mul_op_mov = 0x1F, /* Passthrough, result = arg1 */
153 } ppir_codegen_vec4_mul_op;
154
155 typedef enum {
156 ppir_codegen_outmod_none = 0,
157 ppir_codegen_outmod_clamp_fraction = 1,
158 ppir_codegen_outmod_clamp_positive = 2,
159 ppir_codegen_outmod_round = 3,
160 } ppir_codegen_outmod;
161
162 typedef struct __attribute__((__packed__)) {
163 ppir_codegen_vec4_reg arg0_source : 4;
164 unsigned arg0_swizzle : 8;
165 bool arg0_absolute : 1;
166 bool arg0_negate : 1;
167 ppir_codegen_vec4_reg arg1_source : 4;
168 unsigned arg1_swizzle : 8;
169 bool arg1_absolute : 1;
170 bool arg1_negate : 1;
171 unsigned dest : 4;
172 unsigned mask : 4;
173 ppir_codegen_outmod dest_modifier : 2;
174 ppir_codegen_vec4_mul_op op : 5;
175 } ppir_codegen_field_vec4_mul;
176
177 typedef enum {
178 ppir_codegen_vec4_acc_op_add = 0x00,
179 ppir_codegen_vec4_acc_op_fract = 0x04, /* Fract? */
180 ppir_codegen_vec4_acc_op_ne = 0x08, /* Not Equal */
181 ppir_codegen_vec4_acc_op_gt = 0x09, /* Great-Than */
182 ppir_codegen_vec4_acc_op_ge = 0x0A, /* Great-than or Equal */
183 ppir_codegen_vec4_acc_op_eq = 0x0B, /* Equal */
184 ppir_codegen_vec4_acc_op_floor = 0x0C,
185 ppir_codegen_vec4_acc_op_ceil = 0x0D,
186 ppir_codegen_vec4_acc_op_min = 0x0E,
187 ppir_codegen_vec4_acc_op_max = 0x0F,
188 ppir_codegen_vec4_acc_op_sum3 = 0x10, /* dest.xyzw = (arg0.x + arg0.y + arg0.z) */
189 ppir_codegen_vec4_acc_op_sum4 = 0x11, /* dest.xyzw = (arg0.x + arg0.y + arg0.z + arg0.w) */
190 ppir_codegen_vec4_acc_op_dFdx = 0x14,
191 ppir_codegen_vec4_acc_op_dFdy = 0x15,
192 ppir_codegen_vec4_acc_op_sel = 0x17, /* result = (^fmul ? arg0 : arg1) */
193 ppir_codegen_vec4_acc_op_mov = 0x1F, /* Passthrough, result = arg0 */
194 } ppir_codegen_vec4_acc_op;
195
196 typedef struct __attribute__((__packed__)) {
197 ppir_codegen_vec4_reg arg0_source : 4;
198 unsigned arg0_swizzle : 8;
199 bool arg0_absolute : 1;
200 bool arg0_negate : 1;
201 ppir_codegen_vec4_reg arg1_source : 4;
202 unsigned arg1_swizzle : 8;
203 bool arg1_absolute : 1;
204 bool arg1_negate : 1;
205 unsigned dest : 4;
206 unsigned mask : 4;
207 ppir_codegen_outmod dest_modifier : 2;
208 ppir_codegen_vec4_acc_op op : 5;
209 bool mul_in : 1; /* whether to get arg0 from multiply unit below */
210 } ppir_codegen_field_vec4_acc;
211
212 /* Float (Scalar) Pipe */
213
214 typedef enum {
215 ppir_codegen_float_mul_op_not = 0x08, /* Logical Not */
216 ppir_codegen_float_mul_op_and = 0x09, /* Logical AND */
217 ppir_codegen_float_mul_op_or = 0x0A, /* Logical OR */
218 ppir_codegen_float_mul_op_xor = 0x0B, /* Logical XOR */
219 ppir_codegen_float_mul_op_ne = 0x0C, /* Not Equal */
220 ppir_codegen_float_mul_op_gt = 0x0D, /* Great Than */
221 ppir_codegen_float_mul_op_ge = 0x0E, /* great than or Equal */
222 ppir_codegen_float_mul_op_eq = 0x0F, /* Equal */
223 ppir_codegen_float_mul_op_min = 0x10, /* Minimum */
224 ppir_codegen_float_mul_op_max = 0x11, /* Maximum */
225 ppir_codegen_float_mul_op_mov = 0x1F, /* Passthrough, result = arg1 */
226 } ppir_codegen_float_mul_op;
227
228 typedef struct __attribute__((__packed__)) {
229 unsigned arg0_source : 6;
230 bool arg0_absolute : 1;
231 bool arg0_negate : 1;
232 unsigned arg1_source : 6;
233 bool arg1_absolute : 1;
234 bool arg1_negate : 1;
235 unsigned dest : 6;
236 bool output_en : 1; /* Set to 0 when outputting directly to float_acc below. */
237 ppir_codegen_outmod dest_modifier : 2;
238 ppir_codegen_float_mul_op op : 5;
239 } ppir_codegen_field_float_mul;
240
241 typedef enum {
242 ppir_codegen_float_acc_op_add = 0x00,
243 ppir_codegen_float_acc_op_fract = 0x04,
244 ppir_codegen_float_acc_op_ne = 0x08, /* Not Equal */
245 ppir_codegen_float_acc_op_gt = 0x09, /* Great-Than */
246 ppir_codegen_float_acc_op_ge = 0x0A, /* Great-than or Equal */
247 ppir_codegen_float_acc_op_eq = 0x0B, /* Equal */
248 ppir_codegen_float_acc_op_floor = 0x0C,
249 ppir_codegen_float_acc_op_ceil = 0x0D,
250 ppir_codegen_float_acc_op_min = 0x0E,
251 ppir_codegen_float_acc_op_max = 0x0F,
252 ppir_codegen_float_acc_op_dFdx = 0x14,
253 ppir_codegen_float_acc_op_dFdy = 0x15,
254 ppir_codegen_float_acc_op_sel = 0x17, /* result = (^fmul ? arg0 : arg1) */
255 ppir_codegen_float_acc_op_mov = 0x1F, /* Passthrough, result = arg1 */
256 } ppir_codegen_float_acc_op;
257
258 typedef struct __attribute__((__packed__)) {
259 unsigned arg0_source : 6;
260 bool arg0_absolute : 1;
261 bool arg0_negate : 1;
262 unsigned arg1_source : 6;
263 bool arg1_absolute : 1;
264 bool arg1_negate : 1;
265 unsigned dest : 6;
266 bool output_en : 1; /* Always true */
267 ppir_codegen_outmod dest_modifier : 2;
268 ppir_codegen_float_acc_op op : 5;
269 bool mul_in : 1; /* Get arg1 from float_mul above. */
270 } ppir_codegen_field_float_acc;
271
272 /* Temporary Write / Framebuffer Read */
273
274 typedef union __attribute__((__packed__)) {
275 struct __attribute__((__packed__)) {
276 unsigned dest : 2; /* = 11 */
277 unsigned unknown_0 : 2; /* = 00 */
278 unsigned source : 6;
279 unsigned alignment : 2; /* 0: float, 1:vec2, 2: vec4 */
280 unsigned unknown_1 : 6; /* = 00 0000 */
281 unsigned offset_reg : 6;
282 bool offset_en : 1;
283 unsigned index : 16;
284 } temp_write;
285 struct __attribute__((__packed__)) {
286 bool source : 1; /* 0 = fb_depth, 1 = fb_color */
287 unsigned unknown_0 : 5; /* = 00 111 */
288 unsigned dest : 4;
289 unsigned unknown_1 : 31; /* = 0 0000 ... 10 */
290 } fb_read;
291 } ppir_codegen_field_temp_write;
292
293 /* Result combiner */
294
295 typedef enum {
296 ppir_codegen_combine_scalar_op_rcp = 0, /* Reciprocal */
297 ppir_codegen_combine_scalar_op_mov = 1, /* No Operation */
298 ppir_codegen_combine_scalar_op_sqrt = 2, /* Square-Root */
299 ppir_codegen_combine_scalar_op_rsqrt = 3, /* Inverse Square-Root */
300 ppir_codegen_combine_scalar_op_exp2 = 4, /* Binary Exponent */
301 ppir_codegen_combine_scalar_op_log2 = 5, /* Binary Logarithm */
302 ppir_codegen_combine_scalar_op_sin = 6, /* Sine (Scaled LUT) */
303 ppir_codegen_combine_scalar_op_cos = 7, /* Cosine (Scaled LUT) */
304 ppir_codegen_combine_scalar_op_atan = 8, /* Arc Tangent Part 1 */
305 ppir_codegen_combine_scalar_op_atan2 = 9, /* Arc Tangent 2 Part 1 */
306 } ppir_codegen_combine_scalar_op;
307
308 typedef union __attribute__((__packed__)) {
309 struct __attribute__((__packed__)) {
310 bool dest_vec : 1;
311 bool arg1_en : 1;
312 ppir_codegen_combine_scalar_op op : 4;
313 bool arg1_absolute : 1;
314 bool arg1_negate : 1;
315 unsigned arg1_src : 6;
316 bool arg0_absolute : 1;
317 bool arg0_negate : 1;
318 unsigned arg0_src : 6;
319 ppir_codegen_outmod dest_modifier : 2;
320 unsigned dest : 6;
321 } scalar;
322 struct __attribute__((__packed__)) {
323 bool dest_vec : 1;
324 bool arg1_en : 1;
325 unsigned arg1_swizzle : 8;
326 unsigned arg1_source : 4;
327 unsigned padding_0 : 8;
328 unsigned mask : 4;
329 unsigned dest : 4;
330 } vector;
331 } ppir_codegen_field_combine;
332
333 /* Branch/Control Flow */
334
335 #define PPIR_CODEGEN_DISCARD_WORD0 0x007F0003
336 #define PPIR_CODEGEN_DISCARD_WORD1 0x00000000
337 #define PPIR_CODEGEN_DISCARD_WORD2 0x000
338
339 typedef union __attribute__((__packed__)) {
340 struct __attribute__((__packed__)) {
341 unsigned unknown_0 : 4; /* = 0000 */
342 unsigned arg1_source : 6;
343 unsigned arg0_source : 6;
344 bool cond_gt : 1;
345 bool cond_eq : 1;
346 bool cond_lt : 1;
347 unsigned unknown_1 : 22; /* = 0 0000 0000 0000 0000 0000 0 */
348 signed target : 27;
349 unsigned next_count : 5;
350 } branch;
351 struct __attribute__((__packed__)) {
352 unsigned word0 : 32;
353 unsigned word1 : 32;
354 unsigned word2 : 9;
355 } discard;
356 } ppir_codegen_field_branch;
357
358 void ppir_disassemble_instr(uint32_t *instr, unsigned offset);
359
360 #endif