1bf215546Sopenharmony_ci#ifndef __NV30_SHADER_H__
2bf215546Sopenharmony_ci#define __NV30_SHADER_H__
3bf215546Sopenharmony_ci
4bf215546Sopenharmony_ci/* Vertex programs instruction set
5bf215546Sopenharmony_ci *
6bf215546Sopenharmony_ci * 128bit opcodes, split into 4 32-bit ones for ease of use.
7bf215546Sopenharmony_ci *
8bf215546Sopenharmony_ci * Non-native instructions
9bf215546Sopenharmony_ci *   ABS - MOV + NV40_VP_INST0_DEST_ABS
10bf215546Sopenharmony_ci *   POW - EX2 + MUL + LG2
11bf215546Sopenharmony_ci *   SUB - ADD, second source negated
12bf215546Sopenharmony_ci *   SWZ - MOV
13bf215546Sopenharmony_ci *
14bf215546Sopenharmony_ci * Register access
15bf215546Sopenharmony_ci *   - Only one INPUT can be accessed per-instruction (move extras into TEMPs)
16bf215546Sopenharmony_ci *   - Only one CONST can be accessed per-instruction (move extras into TEMPs)
17bf215546Sopenharmony_ci *
18bf215546Sopenharmony_ci * Relative Addressing
19bf215546Sopenharmony_ci *   According to the value returned for
20bf215546Sopenharmony_ci *   MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB
21bf215546Sopenharmony_ci *
22bf215546Sopenharmony_ci *   there are only two address registers available.  The destination in the
23bf215546Sopenharmony_ci *   ARL instruction is set to TEMP <n> (The temp isn't actually written).
24bf215546Sopenharmony_ci *
25bf215546Sopenharmony_ci *   When using vanilla ARB_v_p, the proprietary driver will squish both the
26bf215546Sopenharmony_ci *   available ADDRESS regs into the first hardware reg in the X and Y
27bf215546Sopenharmony_ci *   components.
28bf215546Sopenharmony_ci *
29bf215546Sopenharmony_ci *   To use an address reg as an index into consts, the CONST_SRC is set to
30bf215546Sopenharmony_ci *   (const_base + offset) and INDEX_CONST is set.
31bf215546Sopenharmony_ci *
32bf215546Sopenharmony_ci *   To access the second address reg use ADDR_REG_SELECT_1. A particular
33bf215546Sopenharmony_ci *   component of the address regs is selected with ADDR_SWZ.
34bf215546Sopenharmony_ci *
35bf215546Sopenharmony_ci *   Only one address register can be accessed per instruction.
36bf215546Sopenharmony_ci *
37bf215546Sopenharmony_ci * Conditional execution (see NV_vertex_program{2,3} for details) Conditional
38bf215546Sopenharmony_ci * execution of an instruction is enabled by setting COND_TEST_ENABLE, and
39bf215546Sopenharmony_ci * selecting the condition which will allow the test to pass with
40bf215546Sopenharmony_ci * COND_{FL,LT,...}.  It is possible to swizzle the values in the condition
41bf215546Sopenharmony_ci * register, which allows for testing against an individual component.
42bf215546Sopenharmony_ci *
43bf215546Sopenharmony_ci * Branching:
44bf215546Sopenharmony_ci *
45bf215546Sopenharmony_ci *   The BRA/CAL instructions seem to follow a slightly different opcode
46bf215546Sopenharmony_ci *   layout.  The destination instruction ID (IADDR) overlaps a source field.
47bf215546Sopenharmony_ci *   Instruction ID's seem to be numbered based on the UPLOAD_FROM_ID FIFO
48bf215546Sopenharmony_ci *   command, and is incremented automatically on each UPLOAD_INST FIFO
49bf215546Sopenharmony_ci *   command.
50bf215546Sopenharmony_ci *
51bf215546Sopenharmony_ci *   Conditional branching is achieved by using the condition tests described
52bf215546Sopenharmony_ci *   above.  There doesn't appear to be dedicated looping instructions, but
53bf215546Sopenharmony_ci *   this can be done using a temp reg + conditional branching.
54bf215546Sopenharmony_ci *
55bf215546Sopenharmony_ci *   Subroutines may be uploaded before the main program itself, but the first
56bf215546Sopenharmony_ci *   executed instruction is determined by the PROGRAM_START_ID FIFO command.
57bf215546Sopenharmony_ci *
58bf215546Sopenharmony_ci */
59bf215546Sopenharmony_ci
60bf215546Sopenharmony_ci/* DWORD 0 */
61bf215546Sopenharmony_ci
62bf215546Sopenharmony_ci/* guess that this is the same as nv40 */
63bf215546Sopenharmony_ci#define NV30_VP_INST_INDEX_INPUT                                        (1 << 27)
64bf215546Sopenharmony_ci
65bf215546Sopenharmony_ci#define NV30_VP_INST_ADDR_REG_SELECT_1        (1 << 24)
66bf215546Sopenharmony_ci#define NV30_VP_INST_SRC2_ABS           (1 << 23) /* guess */
67bf215546Sopenharmony_ci#define NV30_VP_INST_SRC1_ABS           (1 << 22) /* guess */
68bf215546Sopenharmony_ci#define NV30_VP_INST_SRC0_ABS           (1 << 21) /* guess */
69bf215546Sopenharmony_ci#define NV30_VP_INST_VEC_RESULT         (1 << 20)
70bf215546Sopenharmony_ci#define NV30_VP_INST_DEST_TEMP_ID_SHIFT        16
71bf215546Sopenharmony_ci#define NV30_VP_INST_DEST_TEMP_ID_MASK        (0x0F << 16)
72bf215546Sopenharmony_ci#define NV30_VP_INST_COND_UPDATE_ENABLE        (1<<15)
73bf215546Sopenharmony_ci#define NV30_VP_INST_VEC_DEST_TEMP_MASK      (0x1F << 16)
74bf215546Sopenharmony_ci#define NV30_VP_INST_COND_TEST_ENABLE        (1<<14)
75bf215546Sopenharmony_ci#define NV30_VP_INST_COND_SHIFT          11
76bf215546Sopenharmony_ci#define NV30_VP_INST_COND_MASK          (0x07 << 11)
77bf215546Sopenharmony_ci#define NV30_VP_INST_COND_SWZ_X_SHIFT        9
78bf215546Sopenharmony_ci#define NV30_VP_INST_COND_SWZ_X_MASK        (0x03 <<  9)
79bf215546Sopenharmony_ci#define NV30_VP_INST_COND_SWZ_Y_SHIFT        7
80bf215546Sopenharmony_ci#define NV30_VP_INST_COND_SWZ_Y_MASK        (0x03 <<  7)
81bf215546Sopenharmony_ci#define NV30_VP_INST_COND_SWZ_Z_SHIFT        5
82bf215546Sopenharmony_ci#define NV30_VP_INST_COND_SWZ_Z_MASK        (0x03 <<  5)
83bf215546Sopenharmony_ci#define NV30_VP_INST_COND_SWZ_W_SHIFT        3
84bf215546Sopenharmony_ci#define NV30_VP_INST_COND_SWZ_W_MASK        (0x03 <<  3)
85bf215546Sopenharmony_ci#define NV30_VP_INST_COND_SWZ_ALL_SHIFT        3
86bf215546Sopenharmony_ci#define NV30_VP_INST_COND_SWZ_ALL_MASK        (0xFF <<  3)
87bf215546Sopenharmony_ci#define NV30_VP_INST_ADDR_SWZ_SHIFT        1
88bf215546Sopenharmony_ci#define NV30_VP_INST_ADDR_SWZ_MASK        (0x03 <<  1)
89bf215546Sopenharmony_ci#define NV30_VP_INST_SCA_OPCODEH_SHIFT        0
90bf215546Sopenharmony_ci#define NV30_VP_INST_SCA_OPCODEH_MASK        (0x01 <<  0)
91bf215546Sopenharmony_ci
92bf215546Sopenharmony_ci/* DWORD 1 */
93bf215546Sopenharmony_ci#define NV30_VP_INST_SCA_OPCODEL_SHIFT        28
94bf215546Sopenharmony_ci#define NV30_VP_INST_SCA_OPCODEL_MASK        (0x0F << 28)
95bf215546Sopenharmony_ci#define NV30_VP_INST_VEC_OPCODE_SHIFT        23
96bf215546Sopenharmony_ci#define NV30_VP_INST_VEC_OPCODE_MASK        (0x1F << 23)
97bf215546Sopenharmony_ci#define NV30_VP_INST_CONST_SRC_SHIFT        14
98bf215546Sopenharmony_ci#define NV30_VP_INST_CONST_SRC_MASK        (0xFF << 14)
99bf215546Sopenharmony_ci#define NV30_VP_INST_INPUT_SRC_SHIFT        9    /*NV20*/
100bf215546Sopenharmony_ci#define NV30_VP_INST_INPUT_SRC_MASK        (0x0F <<  9)  /*NV20*/
101bf215546Sopenharmony_ci#define NV30_VP_INST_SRC0H_SHIFT        0    /*NV20*/
102bf215546Sopenharmony_ci#define NV30_VP_INST_SRC0H_MASK          (0x1FF << 0)  /*NV20*/
103bf215546Sopenharmony_ci
104bf215546Sopenharmony_ci/* Please note: the IADDR fields overlap other fields because they are used
105bf215546Sopenharmony_ci * only for branch instructions.  See Branching: label above
106bf215546Sopenharmony_ci *
107bf215546Sopenharmony_ci * DWORD 2
108bf215546Sopenharmony_ci */
109bf215546Sopenharmony_ci#define NV30_VP_INST_SRC0L_SHIFT        26    /*NV20*/
110bf215546Sopenharmony_ci#define NV30_VP_INST_SRC0L_MASK         (0x3F  <<26)  /* NV30_VP_SRC0_LOW_MASK << 26 */
111bf215546Sopenharmony_ci#define NV30_VP_INST_SRC1_SHIFT         11    /*NV20*/
112bf215546Sopenharmony_ci#define NV30_VP_INST_SRC1_MASK          (0x7FFF<<11)  /*NV20*/
113bf215546Sopenharmony_ci#define NV30_VP_INST_SRC2H_SHIFT        0    /*NV20*/
114bf215546Sopenharmony_ci#define NV30_VP_INST_SRC2H_MASK          (0x7FF << 0)  /* NV30_VP_SRC2_HIGH_MASK >> 4*/
115bf215546Sopenharmony_ci#define NV30_VP_INST_IADDR_SHIFT        2
116bf215546Sopenharmony_ci#define NV30_VP_INST_IADDR_MASK          (0x1FF <<  2)   /* NV30_VP_SRC2_LOW_MASK << 28 */
117bf215546Sopenharmony_ci
118bf215546Sopenharmony_ci/* DWORD 3 */
119bf215546Sopenharmony_ci#define NV30_VP_INST_SRC2L_SHIFT        28    /*NV20*/
120bf215546Sopenharmony_ci#define NV30_VP_INST_SRC2L_MASK          (0x0F  <<28)  /*NV20*/
121bf215546Sopenharmony_ci#define NV30_VP_INST_STEMP_WRITEMASK_SHIFT      24
122bf215546Sopenharmony_ci#define NV30_VP_INST_STEMP_WRITEMASK_MASK      (0x0F << 24)
123bf215546Sopenharmony_ci#define NV30_VP_INST_VTEMP_WRITEMASK_SHIFT      20
124bf215546Sopenharmony_ci#define NV30_VP_INST_VTEMP_WRITEMASK_MASK      (0x0F << 20)
125bf215546Sopenharmony_ci#define NV30_VP_INST_SDEST_WRITEMASK_SHIFT      16
126bf215546Sopenharmony_ci#define NV30_VP_INST_SDEST_WRITEMASK_MASK      (0x0F << 16)
127bf215546Sopenharmony_ci#define NV30_VP_INST_VDEST_WRITEMASK_SHIFT      12    /*NV20*/
128bf215546Sopenharmony_ci#define NV30_VP_INST_VDEST_WRITEMASK_MASK      (0x0F << 12)  /*NV20*/
129bf215546Sopenharmony_ci#define NV30_VP_INST_DEST_SHIFT        2
130bf215546Sopenharmony_ci#define NV30_VP_INST_DEST_MASK        (0x1F <<  2)
131bf215546Sopenharmony_ci#  define NV30_VP_INST_DEST_POS  0
132bf215546Sopenharmony_ci#  define NV30_VP_INST_DEST_BFC0  1
133bf215546Sopenharmony_ci#  define NV30_VP_INST_DEST_BFC1  2
134bf215546Sopenharmony_ci#  define NV30_VP_INST_DEST_COL0  3
135bf215546Sopenharmony_ci#  define NV30_VP_INST_DEST_COL1  4
136bf215546Sopenharmony_ci#  define NV30_VP_INST_DEST_FOGC  5
137bf215546Sopenharmony_ci#  define NV30_VP_INST_DEST_PSZ   6
138bf215546Sopenharmony_ci#  define NV30_VP_INST_DEST_TC(n)  (8+(n))
139bf215546Sopenharmony_ci#  define NV30_VP_INST_DEST_CLP(n) (17 + (n))
140bf215546Sopenharmony_ci
141bf215546Sopenharmony_ci/* guess that this is the same as nv40 */
142bf215546Sopenharmony_ci#define NV30_VP_INST_INDEX_CONST                                        (1 << 1)
143bf215546Sopenharmony_ci
144bf215546Sopenharmony_ci/* Useful to split the source selection regs into their pieces */
145bf215546Sopenharmony_ci#define NV30_VP_SRC0_HIGH_SHIFT                                                6
146bf215546Sopenharmony_ci#define NV30_VP_SRC0_HIGH_MASK                                        0x00007FC0
147bf215546Sopenharmony_ci#define NV30_VP_SRC0_LOW_MASK                                         0x0000003F
148bf215546Sopenharmony_ci#define NV30_VP_SRC2_HIGH_SHIFT                                                4
149bf215546Sopenharmony_ci#define NV30_VP_SRC2_HIGH_MASK                                        0x00007FF0
150bf215546Sopenharmony_ci#define NV30_VP_SRC2_LOW_MASK                                         0x0000000F
151bf215546Sopenharmony_ci
152bf215546Sopenharmony_ci
153bf215546Sopenharmony_ci/* Source-register definition - matches NV20 exactly */
154bf215546Sopenharmony_ci#define NV30_VP_SRC_NEGATE          (1<<14)
155bf215546Sopenharmony_ci#define NV30_VP_SRC_SWZ_X_SHIFT        12
156bf215546Sopenharmony_ci#define NV30_VP_SRC_REG_SWZ_X_MASK        (0x03  <<12)
157bf215546Sopenharmony_ci#define NV30_VP_SRC_SWZ_Y_SHIFT        10
158bf215546Sopenharmony_ci#define NV30_VP_SRC_REG_SWZ_Y_MASK        (0x03  <<10)
159bf215546Sopenharmony_ci#define NV30_VP_SRC_SWZ_Z_SHIFT        8
160bf215546Sopenharmony_ci#define NV30_VP_SRC_REG_SWZ_Z_MASK        (0x03  << 8)
161bf215546Sopenharmony_ci#define NV30_VP_SRC_SWZ_W_SHIFT        6
162bf215546Sopenharmony_ci#define NV30_VP_SRC_REG_SWZ_W_MASK        (0x03  << 6)
163bf215546Sopenharmony_ci#define NV30_VP_SRC_REG_SWZ_ALL_SHIFT        6
164bf215546Sopenharmony_ci#define NV30_VP_SRC_REG_SWZ_ALL_MASK        (0xFF  << 6)
165bf215546Sopenharmony_ci#define NV30_VP_SRC_TEMP_SRC_SHIFT        2
166bf215546Sopenharmony_ci#define NV30_VP_SRC_REG_TEMP_ID_MASK        (0x0F  << 0)
167bf215546Sopenharmony_ci#define NV30_VP_SRC_REG_TYPE_SHIFT        0
168bf215546Sopenharmony_ci#define NV30_VP_SRC_REG_TYPE_MASK        (0x03  << 0)
169bf215546Sopenharmony_ci#define NV30_VP_SRC_REG_TYPE_TEMP  1
170bf215546Sopenharmony_ci#define NV30_VP_SRC_REG_TYPE_INPUT  2
171bf215546Sopenharmony_ci#define NV30_VP_SRC_REG_TYPE_CONST  3 /* guess */
172bf215546Sopenharmony_ci
173bf215546Sopenharmony_ci#include "nv30/nvfx_shader.h"
174bf215546Sopenharmony_ci
175bf215546Sopenharmony_ci#endif
176