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_generic = 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, FILE *fp); 359 360 #endif 361