midgard.h 8.13 KB
Newer Older
1 2
/* Author(s):
 *   Connor Abbott
3
 *   Alyssa Rosenzweig
4 5
 *
 * Copyright (c) 2013 Connor Abbott (connor@abbott.cx)
6
 * Copyright (c) 2018 Alyssa Rosenzweig (alyssa@rosenzweig.io)
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
 *
 * 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.
 */

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
27 28
#ifndef __midgard_h__
#define __midgard_h__
29 30 31 32 33 34

#include <stdint.h>
#include <stdbool.h>

typedef enum
{
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
35 36 37 38 39
	midgard_word_type_alu,
	midgard_word_type_load_store,
	midgard_word_type_texture,
	midgard_word_type_unknown
} midgard_word_type_e;
40

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
41
extern midgard_word_type_e midgard_word_type[];
42 43

 //size in quadwords, i.e. multiples of 128 bits
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
44
extern unsigned midgard_word_size[];
45 46 47

typedef enum
{
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
48 49 50 51 52 53
	midgard_alu_vmul,
	midgard_alu_sadd,
	midgard_alu_smul,
	midgard_alu_vadd,
	midgard_alu_lut
} midgard_alu_e;
54 55 56 57 58 59 60

/*
 * ALU words
 */

typedef enum
{
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
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
	midgard_alu_op_fadd       = 0x10,
	midgard_alu_op_fmul       = 0x14,
	midgard_alu_op_fmin       = 0x28,
	midgard_alu_op_fmax       = 0x2C,
	midgard_alu_op_fmov       = 0x30,
	midgard_alu_op_ffloor     = 0x36,
	midgard_alu_op_fceil      = 0x37,
	midgard_alu_op_fdot3      = 0x3C,
	midgard_alu_op_fdot3r     = 0x3D,
	midgard_alu_op_fdot4      = 0x3E,
	midgard_alu_op_freduce    = 0x3F,
	midgard_alu_op_iadd       = 0x40,
	midgard_alu_op_isub       = 0x46,
	midgard_alu_op_imul       = 0x58,
	midgard_alu_op_imov       = 0x7B,
	midgard_alu_op_feq        = 0x80,
	midgard_alu_op_fne        = 0x81,
	midgard_alu_op_flt        = 0x82,
	midgard_alu_op_fle        = 0x83,
	midgard_alu_op_f2i        = 0x99,
	midgard_alu_op_ieq        = 0xA0,
	midgard_alu_op_ine        = 0xA1,
	midgard_alu_op_ilt        = 0xA4,
	midgard_alu_op_ile        = 0xA5,
	midgard_alu_op_ball       = 0xA9,
	midgard_alu_op_bany       = 0xB1,
	midgard_alu_op_i2f        = 0xB8,
	midgard_alu_op_csel       = 0xC5,
	midgard_alu_op_fatan_pt2  = 0xE8,
	midgard_alu_op_frcp       = 0xF0,
	midgard_alu_op_frsqrt     = 0xF2,
	midgard_alu_op_fsqrt      = 0xF3,
	midgard_alu_op_fexp2      = 0xF4,
	midgard_alu_op_flog2      = 0xF5,
	midgard_alu_op_fsin       = 0xF6,
	midgard_alu_op_fcos       = 0xF7,
	midgard_alu_op_fatan2_pt1 = 0xF9,
} midgard_alu_op_e;
99 100 101

typedef enum
{
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
102 103 104 105 106
	midgard_outmod_none = 0,
	midgard_outmod_pos  = 1,
	midgard_outmod_int  = 2,
	midgard_outmod_sat  = 3
} midgard_outmod_e;
107 108 109

typedef enum
{
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
110 111 112
	midgard_reg_mode_half = 1,
	midgard_reg_mode_full = 2
} midgard_reg_mode_e;
113 114 115

typedef enum
{
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
116 117 118 119
	midgard_dest_override_lower = 0,
	midgard_dest_override_upper = 1,
	midgard_dest_override_none = 2
} midgard_dest_override_e;
120 121 122 123 124 125

typedef struct
__attribute__((__packed__))
{
	bool abs         : 1;
	bool negate      : 1;
Lyude Paul's avatar
Lyude Paul committed
126

127 128 129 130 131 132 133
	/* replicate lower half if dest = half, or low/high half selection if
	 * dest = full
	 */
	bool rep_low     : 1;
	bool rep_high    : 1; /* unused if dest = full */
	bool half        : 1; /* only matters if dest = full */
	unsigned swizzle : 8;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
134
} midgard_vector_alu_src_t;
135 136 137 138

typedef struct
__attribute__((__packed__))
{
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
139 140
	midgard_alu_op_e op               :  8;
	midgard_reg_mode_e reg_mode   :  2;
141 142
	unsigned src1 : 13;
	unsigned src2 : 13;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
143 144
	midgard_dest_override_e dest_override : 2;
	midgard_outmod_e outmod               : 2;
145
	unsigned mask                           : 8;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
146
} midgard_vector_alu_t;
147 148 149 150 151 152 153 154

typedef struct
__attribute__((__packed__))
{
	bool abs           : 1;
	bool negate        : 1;
	bool full          : 1; /* 0 = half, 1 = full */
	unsigned component : 3;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
155
} midgard_scalar_alu_src_t;
156 157 158 159

typedef struct
__attribute__((__packed__))
{
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
160
	midgard_alu_op_e op         :  8;
161 162 163
	unsigned src1             :  6;
	unsigned src2             : 11;
	unsigned unknown          :  1;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
164
	midgard_outmod_e outmod :  2;
165 166
	bool output_full          :  1;
	unsigned output_component :  3;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
167
} midgard_scalar_alu_t;
168 169 170 171 172 173 174 175

typedef struct
__attribute__((__packed__))
{
	unsigned src1_reg : 5;
	unsigned src2_reg : 5;
	unsigned out_reg  : 5;
	bool src2_imm     : 1;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
176
} midgard_reg_info_t;
177 178 179

typedef enum
{
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
180 181 182 183 184
	midgard_jmp_writeout_op_branch_uncond = 1,
	midgard_jmp_writeout_op_branch_cond = 2,
	midgard_jmp_writeout_op_discard = 4,
	midgard_jmp_writeout_op_writeout = 7,
} midgard_jmp_writeout_op_e;
185 186 187 188

typedef struct
__attribute__((__packed__))
{
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
189
	midgard_jmp_writeout_op_e op : 3; /* == branch_uncond */
190 191 192
	unsigned dest_tag : 4; /* tag of branch destination */
	unsigned unknown : 2;
	int offset : 7;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
193
} midgard_branch_uncond_t;
194 195 196 197

typedef struct
__attribute__((__packed__))
{
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
198
	midgard_jmp_writeout_op_e op : 3; /* == branch_cond */
199 200 201
	unsigned dest_tag : 4; /* tag of branch destination */
	int offset : 7;
	unsigned cond : 2;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
202
} midgard_branch_cond_t;
203 204 205 206

typedef struct
__attribute__((__packed__))
{
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
207
	midgard_jmp_writeout_op_e op : 3; /* == writeout */
208
	unsigned unknown : 13;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
209
} midgard_writeout_t;
210 211 212 213 214 215 216

/*
 * Load/store words
 */

typedef enum
{
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
217 218 219 220 221 222 223 224 225 226
	midgard_op_ld_st_noop   = 0x03,
	midgard_op_load_attr_16 = 0x95,
	midgard_op_load_attr_32 = 0x94,
	midgard_op_load_vary_16 = 0x99,
	midgard_op_load_vary_32 = 0x98,
	midgard_op_load_uniform_16 = 0xAC,
	midgard_op_load_uniform_32 = 0xB0,
	midgard_op_store_vary_16 = 0xD5,
	midgard_op_store_vary_32 = 0xD4
} midgard_load_store_op_e;
227 228 229 230

typedef struct
__attribute__((__packed__))
{
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
231
	midgard_load_store_op_e op : 8;
232 233 234 235 236
	unsigned reg     : 5;
	unsigned mask    : 4;
	unsigned swizzle : 8;
	unsigned unknown : 26;
	unsigned address : 9;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
237
} midgard_load_store_word_t;
238 239 240 241 242 243 244 245

typedef struct
__attribute__((__packed__))
{
	unsigned type      : 4;
	unsigned next_type : 4;
	uint64_t word1     : 60;
	uint64_t word2     : 60;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
246
} midgard_load_store_t;
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
/* Texture pipeline results are in r28-r29 */
#define REG_TEX_BASE 28

/* Texture opcodes... maybe? */
#define TEXTURE_OP_NORMAL 0x11
#define TEXTURE_OP_TEXEL_FETCH 0x14

/* Texture format types, found in format */
#define TEXTURE_2D 0x02
#define TEXTURE_3D 0x03

typedef struct
__attribute__((__packed__))
{
	unsigned type      : 4;
	unsigned next_type : 4;

	unsigned op  : 6;
	unsigned shadow    : 1;
	unsigned unknown3  : 1;

	/* A little obscure, but last is set for the last texture operation in
	 * a shader. cont appears to just be last's opposite (?). Yeah, I know,
	 * kind of funky.. BiOpen thinks it could do with memory hinting, or
	 * tile locking? */

	unsigned cont  : 1;
	unsigned last  : 1;

	unsigned format    : 5;
	unsigned has_offset : 1;

	/* Like in Bifrost */
	unsigned filter  : 1;

	unsigned in_reg_select : 1;
	unsigned in_reg_upper  : 1;
	unsigned unknown1  : 1;
	unsigned in_reg_full : 1;

	unsigned in_reg_swizzle_right : 2;
	unsigned in_reg_swizzle_left : 2;

	unsigned unknown8  : 4;

	unsigned out_full  : 1;

	/* Always 1 afaict... */
	unsigned unknown7  : 2;

	unsigned out_reg_select : 1;
	unsigned out_upper : 1;

	unsigned mask : 4;

	unsigned unknown2  : 2;

	unsigned swizzle  : 8;
	unsigned unknown4  : 8;

	unsigned unknownA  : 4;

	unsigned offset_unknown1  : 1;
	unsigned offset_reg_select : 1;
	unsigned offset_reg_upper : 1;
	unsigned offset_unknown4  : 1;
	unsigned offset_unknown5  : 1;
	unsigned offset_unknown6  : 1;
	unsigned offset_unknown7  : 1;
	unsigned offset_unknown8  : 1;
	unsigned offset_unknown9  : 1;

	unsigned unknownB  : 3;
Lyude Paul's avatar
Lyude Paul committed
321

322 323 324 325 326 327 328 329 330 331
	/* Texture bias or LOD, depending on whether it is executed in a
	 * fragment/vertex shader respectively. Compute as int(2^8 * biasf).
	 *
	 * For texel fetch, this is the LOD as is. */
	unsigned bias  : 8;

	unsigned unknown9  : 8;

	unsigned texture_handle : 16;
	unsigned sampler_handle : 16;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
332
} midgard_texture_word_t;
333 334

#endif