2 * Copyright (C) 2008 Nicolai Haehnle.
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial
16 * portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 #ifndef __RADEON_PROGRAM_H_
29 #define __RADEON_PROGRAM_H_
34 #include "radeon_opcodes.h"
35 #include "radeon_code.h"
36 #include "radeon_program_constants.h"
38 struct radeon_compiler
;
40 struct rc_src_register
{
41 rc_register_file File
:3;
43 /** Negative values may be used for relative addressing. */
44 signed int Index
:(RC_REGISTER_INDEX_BITS
+1);
45 unsigned int RelAddr
:1;
47 unsigned int Swizzle
:12;
49 /** Take the component-wise absolute value */
52 /** Post-Abs negation. */
53 unsigned int Negate
:4;
56 struct rc_dst_register
{
57 rc_register_file File
:3;
59 /** Negative values may be used for relative addressing. */
60 signed int Index
:(RC_REGISTER_INDEX_BITS
+1);
61 unsigned int RelAddr
:1;
63 unsigned int WriteMask
:4;
67 * Instructions are maintained by the compiler in a doubly linked list
68 * of these structures.
70 * This instruction format is intended to be expanded for hardware-specific
71 * trickery. At different stages of compilation, a different set of
72 * instruction types may be valid.
74 struct rc_sub_instruction
{
75 struct rc_src_register SrcReg
[3];
76 struct rc_dst_register DstReg
;
79 * Opcode of this instruction, according to \ref rc_opcode enums.
84 * Saturate each value of the result to the range [0,1] or [-1,1],
85 * according to \ref rc_saturate_mode enums.
87 rc_saturate_mode SaturateMode
:2;
90 * \name Extra fields for TEX, TXB, TXD, TXL, TXP instructions.
93 /** Source texture unit. */
94 unsigned int TexSrcUnit
:5;
96 /** Source texture target, one of the \ref rc_texture_target enums */
97 rc_texture_target TexSrcTarget
:3;
99 /** True if tex instruction should do shadow comparison */
100 unsigned int TexShadow
:1;
104 struct rc_instruction
{
105 struct rc_instruction
* Prev
;
106 struct rc_instruction
* Next
;
108 struct rc_sub_instruction I
;
111 * Warning: IPs are not stable. If you want to use them,
112 * you need to recompute them at the beginning of each pass
113 * using \ref rc_recompute_ips
120 * Instructions.Next points to the first instruction,
121 * Instructions.Prev points to the last instruction.
123 struct rc_instruction Instructions
;
125 /* Long term, we should probably remove InputsRead & OutputsWritten,
126 * since updating dependent state can be fragile, and they aren't
127 * actually used very often. */
129 uint32_t OutputsWritten
;
130 uint32_t ShadowSamplers
; /**< Texture units used for shadow sampling. */
132 struct rc_constant_list Constants
;
136 OPCODE_REPL_ALPHA
= MAX_RC_OPCODE
/**< used in paired instructions */
140 static inline rc_swizzle
get_swz(unsigned int swz
, rc_swizzle idx
)
144 return GET_SWZ(swz
, idx
);
147 static inline unsigned int combine_swizzles4(unsigned int src
,
148 rc_swizzle swz_x
, rc_swizzle swz_y
, rc_swizzle swz_z
, rc_swizzle swz_w
)
150 unsigned int ret
= 0;
152 ret
|= get_swz(src
, swz_x
);
153 ret
|= get_swz(src
, swz_y
) << 3;
154 ret
|= get_swz(src
, swz_z
) << 6;
155 ret
|= get_swz(src
, swz_w
) << 9;
160 static inline unsigned int combine_swizzles(unsigned int src
, unsigned int swz
)
162 unsigned int ret
= 0;
164 ret
|= get_swz(src
, GET_SWZ(swz
, RC_SWIZZLE_X
));
165 ret
|= get_swz(src
, GET_SWZ(swz
, RC_SWIZZLE_Y
)) << 3;
166 ret
|= get_swz(src
, GET_SWZ(swz
, RC_SWIZZLE_Z
)) << 6;
167 ret
|= get_swz(src
, GET_SWZ(swz
, RC_SWIZZLE_W
)) << 9;
172 struct rc_src_register
lmul_swizzle(unsigned int swizzle
, struct rc_src_register srcreg
);
174 static inline void reset_srcreg(struct rc_src_register
* reg
)
176 memset(reg
, 0, sizeof(reg
));
177 reg
->Swizzle
= RC_SWIZZLE_XYZW
;
182 * A transformation that can be passed to \ref radeonLocalTransform.
184 * The function will be called once for each instruction.
185 * It has to either emit the appropriate transformed code for the instruction
186 * and return true, or return false if it doesn't understand the
189 * The function gets passed the userData as last parameter.
191 struct radeon_program_transformation
{
193 struct radeon_compiler
*,
194 struct rc_instruction
*,
199 void radeonLocalTransform(
200 struct radeon_compiler
*c
,
201 int num_transformations
,
202 struct radeon_program_transformation
* transformations
);
204 unsigned int rc_find_free_temporary(struct radeon_compiler
* c
);
206 struct rc_instruction
*rc_alloc_instruction(struct radeon_compiler
* c
);
207 struct rc_instruction
*rc_insert_new_instruction(struct radeon_compiler
* c
, struct rc_instruction
* after
);
208 void rc_remove_instruction(struct rc_instruction
* inst
);
210 unsigned int rc_recompute_ips(struct radeon_compiler
* c
);
212 void rc_print_program(const struct rc_program
*prog
);