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)
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:
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
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.
27 #ifndef LIMA_IR_PP_CODEGEN_H
28 #define LIMA_IR_PP_CODEGEN_H
35 typedef union __attribute__((__packed__
)) {
36 struct __attribute__((__packed__
)) {
41 unsigned next_count
: 6;
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
;
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
;
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;
86 ppir_codegen_vec4_reg dest
: 4;
88 unsigned unknown_3
: 2; /* = 00 */
90 struct __attribute__((__packed__
)) {
91 unsigned perspective
: 2;
92 unsigned source_type
: 2; /* = 01 */
93 unsigned unknown_0
: 2; /* = 00 */
95 unsigned unknown_1
: 3;
96 ppir_codegen_vec4_reg source
: 4;
100 ppir_codegen_vec4_reg dest
: 4;
102 unsigned unknown_2
: 2; /* = 00 */
104 } ppir_codegen_field_varying
;
107 ppir_codegen_sampler_type_2d
= 0x00,
108 ppir_codegen_sampler_type_cube
= 0x1F,
109 } ppir_codegen_sampler_type
;
111 typedef struct __attribute__((__packed__
)) {
112 unsigned lod_bias
: 6;
113 unsigned index_offset
: 6;
114 unsigned unknown_0
: 6; /* = 000000 */
115 bool lod_bias_en
: 1;
116 unsigned unknown_1
: 5; /* = 00000 */
117 ppir_codegen_sampler_type type
: 5;
120 unsigned unknown_2
: 20; /* = 0011 1001 0000 0000 0001 */
121 } ppir_codegen_field_sampler
;
124 ppir_codegen_uniform_src_uniform
= 0,
125 ppir_codegen_uniform_src_temporary
= 3,
126 } ppir_codegen_uniform_src
;
128 typedef struct __attribute__((__packed__
)) {
129 ppir_codegen_uniform_src source
: 2;
130 unsigned unknown_0
: 8; /* = 00 0000 00 */
131 unsigned alignment
: 2; /* 00: float, 01: vec2, 10: vec4 */
132 unsigned unknown_1
: 6; /* = 00 0000 */
133 unsigned offset_reg
: 6;
136 } ppir_codegen_field_uniform
;
141 ppir_codegen_vec4_mul_op_not
= 0x08, /* Logical Not */
142 ppir_codegen_vec4_mul_op_and
= 0x09, /* Logical AND */
143 ppir_codegen_vec4_mul_op_or
= 0x0A, /* Logical OR */
144 ppir_codegen_vec4_mul_op_xor
= 0x0B, /* Logical XOR */
145 ppir_codegen_vec4_mul_op_ne
= 0x0C, /* Not Equal */
146 ppir_codegen_vec4_mul_op_gt
= 0x0D, /* Great Than */
147 ppir_codegen_vec4_mul_op_ge
= 0x0E, /* Great than or Equal */
148 ppir_codegen_vec4_mul_op_eq
= 0x0F, /* Equal */
149 ppir_codegen_vec4_mul_op_min
= 0x10, /* Minimum */
150 ppir_codegen_vec4_mul_op_max
= 0x11, /* Maximum */
151 ppir_codegen_vec4_mul_op_mov
= 0x1F, /* Passthrough, result = arg1 */
152 } ppir_codegen_vec4_mul_op
;
155 ppir_codegen_outmod_none
= 0,
156 ppir_codegen_outmod_clamp_fraction
= 1,
157 ppir_codegen_outmod_clamp_positive
= 2,
158 ppir_codegen_outmod_round
= 3,
159 } ppir_codegen_outmod
;
161 typedef struct __attribute__((__packed__
)) {
162 ppir_codegen_vec4_reg arg0_source
: 4;
163 unsigned arg0_swizzle
: 8;
164 bool arg0_absolute
: 1;
165 bool arg0_negate
: 1;
166 ppir_codegen_vec4_reg arg1_source
: 4;
167 unsigned arg1_swizzle
: 8;
168 bool arg1_absolute
: 1;
169 bool arg1_negate
: 1;
172 ppir_codegen_outmod dest_modifier
: 2;
173 ppir_codegen_vec4_mul_op op
: 5;
174 } ppir_codegen_field_vec4_mul
;
177 ppir_codegen_vec4_acc_op_add
= 0x00,
178 ppir_codegen_vec4_acc_op_fract
= 0x04, /* Fract? */
179 ppir_codegen_vec4_acc_op_ne
= 0x08, /* Not Equal */
180 ppir_codegen_vec4_acc_op_gt
= 0x09, /* Great-Than */
181 ppir_codegen_vec4_acc_op_ge
= 0x0A, /* Great-than or Equal */
182 ppir_codegen_vec4_acc_op_eq
= 0x0B, /* Equal */
183 ppir_codegen_vec4_acc_op_floor
= 0x0C,
184 ppir_codegen_vec4_acc_op_ceil
= 0x0D,
185 ppir_codegen_vec4_acc_op_min
= 0x0E,
186 ppir_codegen_vec4_acc_op_max
= 0x0F,
187 ppir_codegen_vec4_acc_op_sum3
= 0x10, /* dest.xyzw = (arg0.x + arg0.y + arg0.z) */
188 ppir_codegen_vec4_acc_op_sum4
= 0x11, /* dest.xyzw = (arg0.x + arg0.y + arg0.z + arg0.w) */
189 ppir_codegen_vec4_acc_op_dFdx
= 0x14,
190 ppir_codegen_vec4_acc_op_dFdy
= 0x15,
191 ppir_codegen_vec4_acc_op_sel
= 0x17, /* result = (^fmul ? arg0 : arg1) */
192 ppir_codegen_vec4_acc_op_mov
= 0x1F, /* Passthrough, result = arg0 */
193 } ppir_codegen_vec4_acc_op
;
195 typedef struct __attribute__((__packed__
)) {
196 ppir_codegen_vec4_reg arg0_source
: 4;
197 unsigned arg0_swizzle
: 8;
198 bool arg0_absolute
: 1;
199 bool arg0_negate
: 1;
200 ppir_codegen_vec4_reg arg1_source
: 4;
201 unsigned arg1_swizzle
: 8;
202 bool arg1_absolute
: 1;
203 bool arg1_negate
: 1;
206 ppir_codegen_outmod dest_modifier
: 2;
207 ppir_codegen_vec4_acc_op op
: 5;
208 bool mul_in
: 1; /* whether to get arg0 from multiply unit below */
209 } ppir_codegen_field_vec4_acc
;
211 /* Float (Scalar) Pipe */
214 ppir_codegen_float_mul_op_not
= 0x08, /* Logical Not */
215 ppir_codegen_float_mul_op_and
= 0x09, /* Logical AND */
216 ppir_codegen_float_mul_op_or
= 0x0A, /* Logical OR */
217 ppir_codegen_float_mul_op_xor
= 0x0B, /* Logical XOR */
218 ppir_codegen_float_mul_op_ne
= 0x0C, /* Not Equal */
219 ppir_codegen_float_mul_op_gt
= 0x0D, /* Great Than */
220 ppir_codegen_float_mul_op_ge
= 0x0E, /* great than or Equal */
221 ppir_codegen_float_mul_op_eq
= 0x0F, /* Equal */
222 ppir_codegen_float_mul_op_min
= 0x10, /* Minimum */
223 ppir_codegen_float_mul_op_max
= 0x11, /* Maximum */
224 ppir_codegen_float_mul_op_mov
= 0x1F, /* Passthrough, result = arg1 */
225 } ppir_codegen_float_mul_op
;
227 typedef struct __attribute__((__packed__
)) {
228 unsigned arg0_source
: 6;
229 bool arg0_absolute
: 1;
230 bool arg0_negate
: 1;
231 unsigned arg1_source
: 6;
232 bool arg1_absolute
: 1;
233 bool arg1_negate
: 1;
235 bool output_en
: 1; /* Set to 0 when outputting directly to float_acc below. */
236 ppir_codegen_outmod dest_modifier
: 2;
237 ppir_codegen_float_mul_op op
: 5;
238 } ppir_codegen_field_float_mul
;
241 ppir_codegen_float_acc_op_add
= 0x00,
242 ppir_codegen_float_acc_op_fract
= 0x04,
243 ppir_codegen_float_acc_op_ne
= 0x08, /* Not Equal */
244 ppir_codegen_float_acc_op_gt
= 0x09, /* Great-Than */
245 ppir_codegen_float_acc_op_ge
= 0x0A, /* Great-than or Equal */
246 ppir_codegen_float_acc_op_eq
= 0x0B, /* Equal */
247 ppir_codegen_float_acc_op_floor
= 0x0C,
248 ppir_codegen_float_acc_op_ceil
= 0x0D,
249 ppir_codegen_float_acc_op_min
= 0x0E,
250 ppir_codegen_float_acc_op_max
= 0x0F,
251 ppir_codegen_float_acc_op_dFdx
= 0x14,
252 ppir_codegen_float_acc_op_dFdy
= 0x15,
253 ppir_codegen_float_acc_op_sel
= 0x17, /* result = (^fmul ? arg0 : arg1) */
254 ppir_codegen_float_acc_op_mov
= 0x1F, /* Passthrough, result = arg1 */
255 } ppir_codegen_float_acc_op
;
257 typedef struct __attribute__((__packed__
)) {
258 unsigned arg0_source
: 6;
259 bool arg0_absolute
: 1;
260 bool arg0_negate
: 1;
261 unsigned arg1_source
: 6;
262 bool arg1_absolute
: 1;
263 bool arg1_negate
: 1;
265 bool output_en
: 1; /* Always true */
266 ppir_codegen_outmod dest_modifier
: 2;
267 ppir_codegen_float_acc_op op
: 5;
268 bool mul_in
: 1; /* Get arg1 from float_mul above. */
269 } ppir_codegen_field_float_acc
;
271 /* Temporary Write / Framebuffer Read */
273 typedef union __attribute__((__packed__
)) {
274 struct __attribute__((__packed__
)) {
275 unsigned dest
: 2; /* = 11 */
276 unsigned unknown_0
: 2; /* = 00 */
278 unsigned alignment
: 2; /* 0: float, 1:vec2, 2: vec4 */
279 unsigned unknown_1
: 6; /* = 00 0000 */
280 unsigned offset_reg
: 6;
284 struct __attribute__((__packed__
)) {
285 bool source
: 1; /* 0 = fb_depth, 1 = fb_color */
286 unsigned unknown_0
: 5; /* = 00 111 */
288 unsigned unknown_1
: 31; /* = 0 0000 ... 10 */
290 } ppir_codegen_field_temp_write
;
292 /* Result combiner */
295 ppir_codegen_combine_scalar_op_rcp
= 0, /* Reciprocal */
296 ppir_codegen_combine_scalar_op_mov
= 1, /* No Operation */
297 ppir_codegen_combine_scalar_op_sqrt
= 2, /* Square-Root */
298 ppir_codegen_combine_scalar_op_rsqrt
= 3, /* Inverse Square-Root */
299 ppir_codegen_combine_scalar_op_exp2
= 4, /* Binary Exponent */
300 ppir_codegen_combine_scalar_op_log2
= 5, /* Binary Logarithm */
301 ppir_codegen_combine_scalar_op_sin
= 6, /* Sine (Scaled LUT) */
302 ppir_codegen_combine_scalar_op_cos
= 7, /* Cosine (Scaled LUT) */
303 ppir_codegen_combine_scalar_op_atan
= 8, /* Arc Tangent Part 1 */
304 ppir_codegen_combine_scalar_op_atan2
= 9, /* Arc Tangent 2 Part 1 */
305 } ppir_codegen_combine_scalar_op
;
307 typedef union __attribute__((__packed__
)) {
308 struct __attribute__((__packed__
)) {
311 ppir_codegen_combine_scalar_op op
: 4;
312 bool arg1_absolute
: 1;
313 bool arg1_negate
: 1;
314 unsigned arg1_src
: 6;
315 bool arg0_absolute
: 1;
316 bool arg0_negate
: 1;
317 unsigned arg0_src
: 6;
318 ppir_codegen_outmod dest_modifier
: 2;
321 struct __attribute__((__packed__
)) {
324 unsigned arg1_swizzle
: 8;
325 unsigned arg1_source
: 4;
326 unsigned padding_0
: 8;
330 } ppir_codegen_field_combine
;
332 /* Branch/Control Flow */
334 #define PPIR_CODEGEN_DISCARD_WORD0 0x007F0003
335 #define PPIR_CODEGEN_DISCARD_WORD1 0x00000000
336 #define PPIR_CODEGEN_DISCARD_WORD2 0x000
338 typedef union __attribute__((__packed__
)) {
339 struct __attribute__((__packed__
)) {
340 unsigned unknown_0
: 4; /* = 0000 */
341 unsigned arg1_source
: 6;
342 unsigned arg0_source
: 6;
346 unsigned unknown_1
: 22; /* = 0 0000 0000 0000 0000 0000 0 */
348 unsigned unknown_2
: 5; /* = 0 0011 */
350 struct __attribute__((__packed__
)) {
355 } ppir_codegen_field_branch
;
357 void ppir_disassemble_instr(uint32_t *instr
, unsigned offset
);