1b8e80941Smrg/* Author(s):
2b8e80941Smrg *   Connor Abbott
3b8e80941Smrg *   Alyssa Rosenzweig
4b8e80941Smrg *
5b8e80941Smrg * Copyright (c) 2013 Connor Abbott (connor@abbott.cx)
6b8e80941Smrg * Copyright (c) 2018 Alyssa Rosenzweig (alyssa@rosenzweig.io)
7b8e80941Smrg *
8b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a copy
9b8e80941Smrg * of this software and associated documentation files (the "Software"), to deal
10b8e80941Smrg * in the Software without restriction, including without limitation the rights
11b8e80941Smrg * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12b8e80941Smrg * copies of the Software, and to permit persons to whom the Software is
13b8e80941Smrg * furnished to do so, subject to the following conditions:
14b8e80941Smrg *
15b8e80941Smrg * The above copyright notice and this permission notice shall be included in
16b8e80941Smrg * all copies or substantial portions of the Software.
17b8e80941Smrg *
18b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21b8e80941Smrg * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23b8e80941Smrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24b8e80941Smrg * THE SOFTWARE.
25b8e80941Smrg */
26b8e80941Smrg
27b8e80941Smrg#ifndef __midgard_h__
28b8e80941Smrg#define __midgard_h__
29b8e80941Smrg
30b8e80941Smrg#include <stdint.h>
31b8e80941Smrg#include <stdbool.h>
32b8e80941Smrg
33b8e80941Smrg#define MIDGARD_DBG_MSGS		0x0001
34b8e80941Smrg#define MIDGARD_DBG_SHADERS		0x0002
35b8e80941Smrg
36b8e80941Smrgextern int midgard_debug;
37b8e80941Smrg
38b8e80941Smrgtypedef enum {
39b8e80941Smrg        midgard_word_type_alu,
40b8e80941Smrg        midgard_word_type_load_store,
41b8e80941Smrg        midgard_word_type_texture,
42b8e80941Smrg        midgard_word_type_unknown
43b8e80941Smrg} midgard_word_type;
44b8e80941Smrg
45b8e80941Smrgtypedef enum {
46b8e80941Smrg        midgard_alu_vmul,
47b8e80941Smrg        midgard_alu_sadd,
48b8e80941Smrg        midgard_alu_smul,
49b8e80941Smrg        midgard_alu_vadd,
50b8e80941Smrg        midgard_alu_lut
51b8e80941Smrg} midgard_alu;
52b8e80941Smrg
53b8e80941Smrg/*
54b8e80941Smrg * ALU words
55b8e80941Smrg */
56b8e80941Smrg
57b8e80941Smrgtypedef enum {
58b8e80941Smrg        midgard_alu_op_fadd       = 0x10,
59b8e80941Smrg        midgard_alu_op_fmul       = 0x14,
60b8e80941Smrg
61b8e80941Smrg        midgard_alu_op_fmin       = 0x28,
62b8e80941Smrg        midgard_alu_op_fmax       = 0x2C,
63b8e80941Smrg
64b8e80941Smrg        midgard_alu_op_fmov       = 0x30,
65b8e80941Smrg        midgard_alu_op_froundeven = 0x34,
66b8e80941Smrg        midgard_alu_op_ftrunc     = 0x35,
67b8e80941Smrg        midgard_alu_op_ffloor     = 0x36,
68b8e80941Smrg        midgard_alu_op_fceil      = 0x37,
69b8e80941Smrg        midgard_alu_op_ffma       = 0x38,
70b8e80941Smrg        midgard_alu_op_fdot3      = 0x3C,
71b8e80941Smrg        midgard_alu_op_fdot3r     = 0x3D,
72b8e80941Smrg        midgard_alu_op_fdot4      = 0x3E,
73b8e80941Smrg        midgard_alu_op_freduce    = 0x3F,
74b8e80941Smrg
75b8e80941Smrg        midgard_alu_op_iadd       = 0x40,
76b8e80941Smrg        midgard_alu_op_ishladd    = 0x41,
77b8e80941Smrg        midgard_alu_op_isub       = 0x46,
78b8e80941Smrg
79b8e80941Smrg        midgard_alu_op_imul       = 0x58,
80b8e80941Smrg
81b8e80941Smrg        midgard_alu_op_imin       = 0x60,
82b8e80941Smrg        midgard_alu_op_umin       = 0x61,
83b8e80941Smrg        midgard_alu_op_imax       = 0x62,
84b8e80941Smrg        midgard_alu_op_umax       = 0x63,
85b8e80941Smrg        midgard_alu_op_iasr       = 0x68,
86b8e80941Smrg        midgard_alu_op_ilsr       = 0x69,
87b8e80941Smrg        midgard_alu_op_ishl       = 0x6E,
88b8e80941Smrg
89b8e80941Smrg        midgard_alu_op_iand       = 0x70,
90b8e80941Smrg        midgard_alu_op_ior        = 0x71,
91b8e80941Smrg        midgard_alu_op_inand      = 0x72, /* ~(a & b), for inot let a = b */
92b8e80941Smrg        midgard_alu_op_inor       = 0x73, /* ~(a | b) */
93b8e80941Smrg        midgard_alu_op_iandnot    = 0x74, /* (a & ~b), used for not/b2f */
94b8e80941Smrg        midgard_alu_op_iornot     = 0x75, /* (a | ~b) */
95b8e80941Smrg        midgard_alu_op_ixor       = 0x76,
96b8e80941Smrg        midgard_alu_op_inxor      = 0x77, /* ~(a & b) */
97b8e80941Smrg        midgard_alu_op_iclz       = 0x78, /* Number of zeroes on left */
98b8e80941Smrg        midgard_alu_op_ibitcount8 = 0x7A, /* Counts bits in 8-bit increments */
99b8e80941Smrg        midgard_alu_op_imov       = 0x7B,
100b8e80941Smrg        midgard_alu_op_iabs       = 0x7C,
101b8e80941Smrg
102b8e80941Smrg        midgard_alu_op_feq        = 0x80,
103b8e80941Smrg        midgard_alu_op_fne        = 0x81,
104b8e80941Smrg        midgard_alu_op_flt        = 0x82,
105b8e80941Smrg        midgard_alu_op_fle        = 0x83,
106b8e80941Smrg        midgard_alu_op_fball_eq   = 0x88,
107b8e80941Smrg        midgard_alu_op_bball_eq   = 0x89,
108b8e80941Smrg        midgard_alu_op_fball_lt   = 0x8A, /* all(lessThan(.., ..)) */
109b8e80941Smrg        midgard_alu_op_fball_lte  = 0x8B, /* all(lessThanEqual(.., ..)) */
110b8e80941Smrg
111b8e80941Smrg        midgard_alu_op_bbany_neq  = 0x90, /* used for bvec4(1) */
112b8e80941Smrg        midgard_alu_op_fbany_neq  = 0x91, /* bvec4(0) also */
113b8e80941Smrg        midgard_alu_op_fbany_lt   = 0x92, /* any(lessThan(.., ..)) */
114b8e80941Smrg        midgard_alu_op_fbany_lte  = 0x93, /* any(lessThanEqual(.., ..)) */
115b8e80941Smrg        midgard_alu_op_f2i        = 0x99,
116b8e80941Smrg        midgard_alu_op_f2u8       = 0x9C,
117b8e80941Smrg        midgard_alu_op_f2u        = 0x9D,
118b8e80941Smrg
119b8e80941Smrg        midgard_alu_op_ieq        = 0xA0,
120b8e80941Smrg        midgard_alu_op_ine        = 0xA1,
121b8e80941Smrg        midgard_alu_op_ult        = 0xA2,
122b8e80941Smrg        midgard_alu_op_ule        = 0xA3,
123b8e80941Smrg        midgard_alu_op_ilt        = 0xA4,
124b8e80941Smrg        midgard_alu_op_ile        = 0xA5,
125b8e80941Smrg        midgard_alu_op_iball_eq   = 0xA8,
126b8e80941Smrg        midgard_alu_op_iball_neq  = 0xA9,
127b8e80941Smrg        midgard_alu_op_uball_lt   = 0xAA,
128b8e80941Smrg        midgard_alu_op_uball_lte  = 0xAB,
129b8e80941Smrg        midgard_alu_op_iball_lt   = 0xAC,
130b8e80941Smrg        midgard_alu_op_iball_lte  = 0xAD,
131b8e80941Smrg
132b8e80941Smrg        midgard_alu_op_ibany_eq   = 0xB0,
133b8e80941Smrg        midgard_alu_op_ibany_neq  = 0xB1,
134b8e80941Smrg        midgard_alu_op_ubany_lt   = 0xB2,
135b8e80941Smrg        midgard_alu_op_ubany_lte  = 0xB3,
136b8e80941Smrg        midgard_alu_op_ibany_lt   = 0xB4, /* any(lessThan(.., ..)) */
137b8e80941Smrg        midgard_alu_op_ibany_lte  = 0xB5, /* any(lessThanEqual(.., ..)) */
138b8e80941Smrg        midgard_alu_op_i2f        = 0xB8,
139b8e80941Smrg        midgard_alu_op_u2f        = 0xBC,
140b8e80941Smrg
141b8e80941Smrg        midgard_alu_op_icsel      = 0xC1,
142b8e80941Smrg        midgard_alu_op_fcsel_i    = 0xC4,
143b8e80941Smrg        midgard_alu_op_fcsel      = 0xC5,
144b8e80941Smrg        midgard_alu_op_fround     = 0xC6,
145b8e80941Smrg
146b8e80941Smrg        midgard_alu_op_fatan_pt2  = 0xE8,
147b8e80941Smrg        midgard_alu_op_fpow_pt1   = 0xEC,
148b8e80941Smrg
149b8e80941Smrg        midgard_alu_op_frcp       = 0xF0,
150b8e80941Smrg        midgard_alu_op_frsqrt     = 0xF2,
151b8e80941Smrg        midgard_alu_op_fsqrt      = 0xF3,
152b8e80941Smrg        midgard_alu_op_fexp2      = 0xF4,
153b8e80941Smrg        midgard_alu_op_flog2      = 0xF5,
154b8e80941Smrg        midgard_alu_op_fsin       = 0xF6,
155b8e80941Smrg        midgard_alu_op_fcos       = 0xF7,
156b8e80941Smrg        midgard_alu_op_fatan2_pt1 = 0xF9,
157b8e80941Smrg} midgard_alu_op;
158b8e80941Smrg
159b8e80941Smrgtypedef enum {
160b8e80941Smrg        midgard_outmod_none = 0,
161b8e80941Smrg        midgard_outmod_pos  = 1,
162b8e80941Smrg        midgard_outmod_int  = 2,
163b8e80941Smrg        midgard_outmod_sat  = 3
164b8e80941Smrg} midgard_outmod;
165b8e80941Smrg
166b8e80941Smrgtypedef enum {
167b8e80941Smrg        midgard_reg_mode_8 = 0,
168b8e80941Smrg        midgard_reg_mode_16 = 1,
169b8e80941Smrg        midgard_reg_mode_32 = 2,
170b8e80941Smrg        midgard_reg_mode_64 = 3 /* TODO: verify */
171b8e80941Smrg} midgard_reg_mode;
172b8e80941Smrg
173b8e80941Smrgtypedef enum {
174b8e80941Smrg        midgard_dest_override_lower = 0,
175b8e80941Smrg        midgard_dest_override_upper = 1,
176b8e80941Smrg        midgard_dest_override_none = 2
177b8e80941Smrg} midgard_dest_override;
178b8e80941Smrg
179b8e80941Smrgtypedef enum {
180b8e80941Smrg        midgard_int_sign_extend = 0,
181b8e80941Smrg        midgard_int_zero_extend = 1,
182b8e80941Smrg        midgard_int_normal = 2,
183b8e80941Smrg        midgard_int_reserved = 3
184b8e80941Smrg} midgard_int_mod;
185b8e80941Smrg
186b8e80941Smrg#define MIDGARD_FLOAT_MOD_ABS (1 << 0)
187b8e80941Smrg#define MIDGARD_FLOAT_MOD_NEG (1 << 1)
188b8e80941Smrg
189b8e80941Smrgtypedef struct
190b8e80941Smrg__attribute__((__packed__))
191b8e80941Smrg{
192b8e80941Smrg        /* Either midgard_int_mod or from midgard_float_mod_*, depending on the
193b8e80941Smrg         * type of op */
194b8e80941Smrg        unsigned mod : 2;
195b8e80941Smrg
196b8e80941Smrg        /* replicate lower half if dest = half, or low/high half selection if
197b8e80941Smrg         * dest = full
198b8e80941Smrg         */
199b8e80941Smrg        bool rep_low     : 1;
200b8e80941Smrg        bool rep_high    : 1; /* unused if dest = full */
201b8e80941Smrg        bool half        : 1; /* only matters if dest = full */
202b8e80941Smrg        unsigned swizzle : 8;
203b8e80941Smrg}
204b8e80941Smrgmidgard_vector_alu_src;
205b8e80941Smrg
206b8e80941Smrgtypedef struct
207b8e80941Smrg__attribute__((__packed__))
208b8e80941Smrg{
209b8e80941Smrg        midgard_alu_op op               :  8;
210b8e80941Smrg        midgard_reg_mode reg_mode   :  2;
211b8e80941Smrg        unsigned src1 : 13;
212b8e80941Smrg        unsigned src2 : 13;
213b8e80941Smrg        midgard_dest_override dest_override : 2;
214b8e80941Smrg        midgard_outmod outmod               : 2;
215b8e80941Smrg        unsigned mask                           : 8;
216b8e80941Smrg}
217b8e80941Smrgmidgard_vector_alu;
218b8e80941Smrg
219b8e80941Smrgtypedef struct
220b8e80941Smrg__attribute__((__packed__))
221b8e80941Smrg{
222b8e80941Smrg        bool abs           : 1;
223b8e80941Smrg        bool negate        : 1;
224b8e80941Smrg        bool full          : 1; /* 0 = half, 1 = full */
225b8e80941Smrg        unsigned component : 3;
226b8e80941Smrg}
227b8e80941Smrgmidgard_scalar_alu_src;
228b8e80941Smrg
229b8e80941Smrgtypedef struct
230b8e80941Smrg__attribute__((__packed__))
231b8e80941Smrg{
232b8e80941Smrg        midgard_alu_op op         :  8;
233b8e80941Smrg        unsigned src1             :  6;
234b8e80941Smrg        unsigned src2             : 11;
235b8e80941Smrg        unsigned unknown          :  1;
236b8e80941Smrg        midgard_outmod outmod :  2;
237b8e80941Smrg        bool output_full          :  1;
238b8e80941Smrg        unsigned output_component :  3;
239b8e80941Smrg}
240b8e80941Smrgmidgard_scalar_alu;
241b8e80941Smrg
242b8e80941Smrgtypedef struct
243b8e80941Smrg__attribute__((__packed__))
244b8e80941Smrg{
245b8e80941Smrg        unsigned src1_reg : 5;
246b8e80941Smrg        unsigned src2_reg : 5;
247b8e80941Smrg        unsigned out_reg  : 5;
248b8e80941Smrg        bool src2_imm     : 1;
249b8e80941Smrg}
250b8e80941Smrgmidgard_reg_info;
251b8e80941Smrg
252b8e80941Smrg/* In addition to conditional branches and jumps (unconditional branches),
253b8e80941Smrg * Midgard implements a bit of fixed function functionality used in fragment
254b8e80941Smrg * shaders via specially crafted branches. These have special branch opcodes,
255b8e80941Smrg * which perform a fixed-function operation and/or use the results of a
256b8e80941Smrg * fixed-function operation as the branch condition.  */
257b8e80941Smrg
258b8e80941Smrgtypedef enum {
259b8e80941Smrg        /* Regular branches */
260b8e80941Smrg        midgard_jmp_writeout_op_branch_uncond = 1,
261b8e80941Smrg        midgard_jmp_writeout_op_branch_cond = 2,
262b8e80941Smrg
263b8e80941Smrg        /* In a fragment shader, execute a discard_if instruction, with the
264b8e80941Smrg         * corresponding condition code. Terminates the shader, so generally
265b8e80941Smrg         * set the branch target to out of the shader */
266b8e80941Smrg        midgard_jmp_writeout_op_discard = 4,
267b8e80941Smrg
268b8e80941Smrg        /* Branch if the tilebuffer is not yet ready. At the beginning of a
269b8e80941Smrg         * fragment shader that reads from the tile buffer, for instance via
270b8e80941Smrg         * ARM_shader_framebuffer_fetch or EXT_pixel_local_storage, this branch
271b8e80941Smrg         * operation should be used as a loop. An instruction like
272b8e80941Smrg         * "br.tilebuffer.always -1" does the trick, corresponding to
273b8e80941Smrg         * "while(!is_tilebuffer_ready) */
274b8e80941Smrg        midgard_jmp_writeout_op_tilebuffer_pending = 6,
275b8e80941Smrg
276b8e80941Smrg        /* In a fragment shader, try to write out the value pushed to r0 to the
277b8e80941Smrg         * tilebuffer, subject to unknown state in r1.z and r1.w. If this
278b8e80941Smrg         * succeeds, the shader terminates. If it fails, it branches to the
279b8e80941Smrg         * specified branch target. Generally, this should be used in a loop to
280b8e80941Smrg         * itself, acting as "do { write(r0); } while(!write_successful);" */
281b8e80941Smrg        midgard_jmp_writeout_op_writeout = 7,
282b8e80941Smrg} midgard_jmp_writeout_op;
283b8e80941Smrg
284b8e80941Smrgtypedef enum {
285b8e80941Smrg        midgard_condition_write0 = 0,
286b8e80941Smrg
287b8e80941Smrg        /* These condition codes denote a conditional branch on FALSE and on
288b8e80941Smrg         * TRUE respectively */
289b8e80941Smrg        midgard_condition_false = 1,
290b8e80941Smrg        midgard_condition_true = 2,
291b8e80941Smrg
292b8e80941Smrg        /* This condition code always branches. For a pure branch, the
293b8e80941Smrg         * unconditional branch coding should be used instead, but for
294b8e80941Smrg         * fixed-function branch opcodes, this is still useful */
295b8e80941Smrg        midgard_condition_always = 3,
296b8e80941Smrg} midgard_condition;
297b8e80941Smrg
298b8e80941Smrgtypedef struct
299b8e80941Smrg__attribute__((__packed__))
300b8e80941Smrg{
301b8e80941Smrg        midgard_jmp_writeout_op op : 3; /* == branch_uncond */
302b8e80941Smrg        unsigned dest_tag : 4; /* tag of branch destination */
303b8e80941Smrg        unsigned unknown : 2;
304b8e80941Smrg        int offset : 7;
305b8e80941Smrg}
306b8e80941Smrgmidgard_branch_uncond;
307b8e80941Smrg
308b8e80941Smrgtypedef struct
309b8e80941Smrg__attribute__((__packed__))
310b8e80941Smrg{
311b8e80941Smrg        midgard_jmp_writeout_op op : 3; /* == branch_cond */
312b8e80941Smrg        unsigned dest_tag : 4; /* tag of branch destination */
313b8e80941Smrg        int offset : 7;
314b8e80941Smrg        midgard_condition cond : 2;
315b8e80941Smrg}
316b8e80941Smrgmidgard_branch_cond;
317b8e80941Smrg
318b8e80941Smrgtypedef struct
319b8e80941Smrg__attribute__((__packed__))
320b8e80941Smrg{
321b8e80941Smrg        midgard_jmp_writeout_op op : 3; /* == branch_cond */
322b8e80941Smrg        unsigned dest_tag : 4; /* tag of branch destination */
323b8e80941Smrg        unsigned unknown : 2;
324b8e80941Smrg        signed offset : 23;
325b8e80941Smrg        unsigned cond : 16;
326b8e80941Smrg}
327b8e80941Smrgmidgard_branch_extended;
328b8e80941Smrg
329b8e80941Smrgtypedef struct
330b8e80941Smrg__attribute__((__packed__))
331b8e80941Smrg{
332b8e80941Smrg        midgard_jmp_writeout_op op : 3; /* == writeout */
333b8e80941Smrg        unsigned unknown : 13;
334b8e80941Smrg}
335b8e80941Smrgmidgard_writeout;
336b8e80941Smrg
337b8e80941Smrg/*
338b8e80941Smrg * Load/store words
339b8e80941Smrg */
340b8e80941Smrg
341b8e80941Smrgtypedef enum {
342b8e80941Smrg        midgard_op_ld_st_noop   = 0x03,
343b8e80941Smrg
344b8e80941Smrg        /* Unclear why this is on the L/S unit, but (with an address of 0,
345b8e80941Smrg         * appropriate swizzle, magic constant 0x24, and xy mask?) moves fp32 cube
346b8e80941Smrg         * map coordinates in r27 to its cube map texture coordinate
347b8e80941Smrg         * destination (e.g r29). 0x4 magic for loading from fp16 instead */
348b8e80941Smrg
349b8e80941Smrg        midgard_op_store_cubemap_coords = 0x0E,
350b8e80941Smrg
351b8e80941Smrg        midgard_op_load_attr_16 = 0x95,
352b8e80941Smrg        midgard_op_load_attr_32 = 0x94,
353b8e80941Smrg        midgard_op_load_vary_16 = 0x99,
354b8e80941Smrg        midgard_op_load_vary_32 = 0x98,
355b8e80941Smrg        midgard_op_load_color_buffer_16 = 0x9D,
356b8e80941Smrg        midgard_op_load_color_buffer_8 = 0xBA,
357b8e80941Smrg        midgard_op_load_uniform_16 = 0xAC,
358b8e80941Smrg        midgard_op_load_uniform_32 = 0xB0,
359b8e80941Smrg        midgard_op_store_vary_16 = 0xD5,
360b8e80941Smrg        midgard_op_store_vary_32 = 0xD4
361b8e80941Smrg} midgard_load_store_op;
362b8e80941Smrg
363b8e80941Smrgtypedef enum {
364b8e80941Smrg        midgard_interp_centroid = 1,
365b8e80941Smrg        midgard_interp_default = 2
366b8e80941Smrg} midgard_interpolation;
367b8e80941Smrg
368b8e80941Smrgtypedef struct
369b8e80941Smrg__attribute__((__packed__))
370b8e80941Smrg{
371b8e80941Smrg        unsigned zero1 : 4; /* Always zero */
372b8e80941Smrg
373b8e80941Smrg        /* Varying qualifiers, zero if not a varying */
374b8e80941Smrg        unsigned flat    : 1;
375b8e80941Smrg        unsigned is_varying : 1; /* Always one for varying, but maybe something else? */
376b8e80941Smrg        midgard_interpolation interpolation : 2;
377b8e80941Smrg
378b8e80941Smrg        unsigned zero2 : 2; /* Always zero */
379b8e80941Smrg}
380b8e80941Smrgmidgard_varying_parameter;
381b8e80941Smrg
382b8e80941Smrgtypedef struct
383b8e80941Smrg__attribute__((__packed__))
384b8e80941Smrg{
385b8e80941Smrg        midgard_load_store_op op : 8;
386b8e80941Smrg        unsigned reg     : 5;
387b8e80941Smrg        unsigned mask    : 4;
388b8e80941Smrg        unsigned swizzle : 8;
389b8e80941Smrg        unsigned unknown : 16;
390b8e80941Smrg
391b8e80941Smrg        unsigned varying_parameters : 10;
392b8e80941Smrg
393b8e80941Smrg        unsigned address : 9;
394b8e80941Smrg}
395b8e80941Smrgmidgard_load_store_word;
396b8e80941Smrg
397b8e80941Smrgtypedef struct
398b8e80941Smrg__attribute__((__packed__))
399b8e80941Smrg{
400b8e80941Smrg        unsigned type      : 4;
401b8e80941Smrg        unsigned next_type : 4;
402b8e80941Smrg        uint64_t word1     : 60;
403b8e80941Smrg        uint64_t word2     : 60;
404b8e80941Smrg}
405b8e80941Smrgmidgard_load_store;
406b8e80941Smrg
407b8e80941Smrg/* Texture pipeline results are in r28-r29 */
408b8e80941Smrg#define REG_TEX_BASE 28
409b8e80941Smrg
410b8e80941Smrg/* Texture opcodes... maybe? */
411b8e80941Smrg#define TEXTURE_OP_NORMAL 0x11
412b8e80941Smrg#define TEXTURE_OP_TEXEL_FETCH 0x14
413b8e80941Smrg
414b8e80941Smrg/* Texture format types, found in format */
415b8e80941Smrg#define TEXTURE_CUBE 0x00
416b8e80941Smrg#define TEXTURE_2D 0x02
417b8e80941Smrg#define TEXTURE_3D 0x03
418b8e80941Smrg
419b8e80941Smrgtypedef struct
420b8e80941Smrg__attribute__((__packed__))
421b8e80941Smrg{
422b8e80941Smrg        unsigned type      : 4;
423b8e80941Smrg        unsigned next_type : 4;
424b8e80941Smrg
425b8e80941Smrg        unsigned op  : 6;
426b8e80941Smrg        unsigned shadow    : 1;
427b8e80941Smrg        unsigned unknown3  : 1;
428b8e80941Smrg
429b8e80941Smrg        /* A little obscure, but last is set for the last texture operation in
430b8e80941Smrg         * a shader. cont appears to just be last's opposite (?). Yeah, I know,
431b8e80941Smrg         * kind of funky.. BiOpen thinks it could do with memory hinting, or
432b8e80941Smrg         * tile locking? */
433b8e80941Smrg
434b8e80941Smrg        unsigned cont  : 1;
435b8e80941Smrg        unsigned last  : 1;
436b8e80941Smrg
437b8e80941Smrg        unsigned format    : 5;
438b8e80941Smrg        unsigned has_offset : 1;
439b8e80941Smrg
440b8e80941Smrg        /* Like in Bifrost */
441b8e80941Smrg        unsigned filter  : 1;
442b8e80941Smrg
443b8e80941Smrg        unsigned in_reg_select : 1;
444b8e80941Smrg        unsigned in_reg_upper  : 1;
445b8e80941Smrg
446b8e80941Smrg        unsigned in_reg_swizzle_left : 2;
447b8e80941Smrg        unsigned in_reg_swizzle_right : 2;
448b8e80941Smrg
449b8e80941Smrg        unsigned unknown1 : 2;
450b8e80941Smrg
451b8e80941Smrg        unsigned unknown8  : 4;
452b8e80941Smrg
453b8e80941Smrg        unsigned out_full  : 1;
454b8e80941Smrg
455b8e80941Smrg        /* Always 1 afaict... */
456b8e80941Smrg        unsigned unknown7  : 2;
457b8e80941Smrg
458b8e80941Smrg        unsigned out_reg_select : 1;
459b8e80941Smrg        unsigned out_upper : 1;
460b8e80941Smrg
461b8e80941Smrg        unsigned mask : 4;
462b8e80941Smrg
463b8e80941Smrg        unsigned unknown2  : 2;
464b8e80941Smrg
465b8e80941Smrg        unsigned swizzle  : 8;
466b8e80941Smrg        unsigned unknown4  : 8;
467b8e80941Smrg
468b8e80941Smrg        unsigned unknownA  : 4;
469b8e80941Smrg
470b8e80941Smrg        unsigned offset_unknown1  : 1;
471b8e80941Smrg        unsigned offset_reg_select : 1;
472b8e80941Smrg        unsigned offset_reg_upper : 1;
473b8e80941Smrg        unsigned offset_unknown4  : 1;
474b8e80941Smrg        unsigned offset_unknown5  : 1;
475b8e80941Smrg        unsigned offset_unknown6  : 1;
476b8e80941Smrg        unsigned offset_unknown7  : 1;
477b8e80941Smrg        unsigned offset_unknown8  : 1;
478b8e80941Smrg        unsigned offset_unknown9  : 1;
479b8e80941Smrg
480b8e80941Smrg        unsigned unknownB  : 3;
481b8e80941Smrg
482b8e80941Smrg        /* Texture bias or LOD, depending on whether it is executed in a
483b8e80941Smrg         * fragment/vertex shader respectively. Compute as int(2^8 * biasf).
484b8e80941Smrg         *
485b8e80941Smrg         * For texel fetch, this is the LOD as is. */
486b8e80941Smrg        unsigned bias  : 8;
487b8e80941Smrg
488b8e80941Smrg        unsigned unknown9  : 8;
489b8e80941Smrg
490b8e80941Smrg        unsigned texture_handle : 16;
491b8e80941Smrg        unsigned sampler_handle : 16;
492b8e80941Smrg}
493b8e80941Smrgmidgard_texture_word;
494b8e80941Smrg
495b8e80941Smrgstatic char *load_store_opcode_names[256] = {
496b8e80941Smrg        [midgard_op_store_cubemap_coords] = "st_cubemap_coords",
497b8e80941Smrg        [midgard_op_load_attr_16] = "ld_attr_16",
498b8e80941Smrg        [midgard_op_load_attr_32] = "ld_attr_32",
499b8e80941Smrg        [midgard_op_load_vary_16] = "ld_vary_16",
500b8e80941Smrg        [midgard_op_load_vary_32] = "ld_vary_32",
501b8e80941Smrg        [midgard_op_load_uniform_16] = "ld_uniform_16",
502b8e80941Smrg        [midgard_op_load_uniform_32] = "ld_uniform_32",
503b8e80941Smrg        [midgard_op_load_color_buffer_8] = "ld_color_buffer_8",
504b8e80941Smrg        [midgard_op_load_color_buffer_16] = "ld_color_buffer_16",
505b8e80941Smrg        [midgard_op_store_vary_16] = "st_vary_16",
506b8e80941Smrg        [midgard_op_store_vary_32] = "st_vary_32"
507b8e80941Smrg};
508b8e80941Smrg
509b8e80941Smrg#endif
510