1 /* 2 * Copyright (C) 2008 Nicolai Haehnle. 3 * 4 * All Rights Reserved. 5 * 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: 13 * 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. 17 * 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. 25 * 26 */ 27 28 #ifndef __RADEON_PROGRAM_H_ 29 #define __RADEON_PROGRAM_H_ 30 31 #include <stdint.h> 32 #include <string.h> 33 34 #include "radeon_opcodes.h" 35 #include "radeon_code.h" 36 #include "radeon_program_constants.h" 37 #include "radeon_program_pair.h" 38 39 struct radeon_compiler; 40 41 struct rc_src_register { 42 unsigned int File:4; 43 44 /** Negative values may be used for relative addressing. */ 45 signed int Index:(RC_REGISTER_INDEX_BITS+1); 46 unsigned int RelAddr:1; 47 48 unsigned int Swizzle:12; 49 50 /** Take the component-wise absolute value */ 51 unsigned int Abs:1; 52 53 /** Post-Abs negation. */ 54 unsigned int Negate:4; 55 }; 56 57 struct rc_dst_register { 58 unsigned int File:3; 59 unsigned int Index:RC_REGISTER_INDEX_BITS; 60 unsigned int WriteMask:4; 61 unsigned int Pred:2; 62 }; 63 64 struct rc_presub_instruction { 65 rc_presubtract_op Opcode; 66 struct rc_src_register SrcReg[2]; 67 }; 68 69 /** 70 * Instructions are maintained by the compiler in a doubly linked list 71 * of these structures. 72 * 73 * This instruction format is intended to be expanded for hardware-specific 74 * trickery. At different stages of compilation, a different set of 75 * instruction types may be valid. 76 */ 77 struct rc_sub_instruction { 78 struct rc_src_register SrcReg[3]; 79 struct rc_dst_register DstReg; 80 81 /** 82 * Opcode of this instruction, according to \ref rc_opcode enums. 83 */ 84 unsigned int Opcode:8; 85 86 /** 87 * Saturate each value of the result to the range [0,1] or [-1,1], 88 * according to \ref rc_saturate_mode enums. 89 */ 90 unsigned int SaturateMode:2; 91 92 /** 93 * Writing to the special register RC_SPECIAL_ALU_RESULT 94 */ 95 /*@{*/ 96 unsigned int WriteALUResult:2; 97 unsigned int ALUResultCompare:3; 98 /*@}*/ 99 100 /** 101 * \name Extra fields for TEX, TXB, TXD, TXL, TXP instructions. 102 */ 103 /*@{*/ 104 /** Source texture unit. */ 105 unsigned int TexSrcUnit:5; 106 107 /** Source texture target, one of the \ref rc_texture_target enums */ 108 unsigned int TexSrcTarget:3; 109 110 /** True if tex instruction should do shadow comparison */ 111 unsigned int TexShadow:1; 112 113 /**/ 114 unsigned int TexSemWait:1; 115 unsigned int TexSemAcquire:1; 116 117 /**R500 Only. How to swizzle the result of a TEX lookup*/ 118 unsigned int TexSwizzle:12; 119 /*@}*/ 120 121 /** This holds information about the presubtract operation used by 122 * this instruction. */ 123 struct rc_presub_instruction PreSub; 124 125 rc_omod_op Omod; 126 }; 127 128 typedef enum { 129 RC_INSTRUCTION_NORMAL = 0, 130 RC_INSTRUCTION_PAIR 131 } rc_instruction_type; 132 133 struct rc_instruction { 134 struct rc_instruction * Prev; 135 struct rc_instruction * Next; 136 137 rc_instruction_type Type; 138 union { 139 struct rc_sub_instruction I; 140 struct rc_pair_instruction P; 141 } U; 142 143 /** 144 * Warning: IPs are not stable. If you want to use them, 145 * you need to recompute them at the beginning of each pass 146 * using \ref rc_recompute_ips 147 */ 148 unsigned int IP; 149 }; 150 151 struct rc_program { 152 /** 153 * Instructions.Next points to the first instruction, 154 * Instructions.Prev points to the last instruction. 155 */ 156 struct rc_instruction Instructions; 157 158 /* Long term, we should probably remove InputsRead & OutputsWritten, 159 * since updating dependent state can be fragile, and they aren't 160 * actually used very often. */ 161 uint32_t InputsRead; 162 uint32_t OutputsWritten; 163 uint32_t ShadowSamplers; /**< Texture units used for shadow sampling. */ 164 165 struct rc_constant_list Constants; 166 }; 167 168 /** 169 * A transformation that can be passed to \ref rc_local_transform. 170 * 171 * The function will be called once for each instruction. 172 * It has to either emit the appropriate transformed code for the instruction 173 * and return true, or return false if it doesn't understand the 174 * instruction. 175 * 176 * The function gets passed the userData as last parameter. 177 */ 178 struct radeon_program_transformation { 179 int (*function)( 180 struct radeon_compiler*, 181 struct rc_instruction*, 182 void*); 183 void *userData; 184 }; 185 186 void rc_local_transform( 187 struct radeon_compiler *c, 188 void *user); 189 190 void rc_get_used_temporaries( 191 struct radeon_compiler * c, 192 unsigned char * used, 193 unsigned int used_length); 194 195 int rc_find_free_temporary_list( 196 struct radeon_compiler * c, 197 unsigned char * used, 198 unsigned int used_length, 199 unsigned int mask); 200 201 unsigned int rc_find_free_temporary(struct radeon_compiler * c); 202 203 struct rc_instruction *rc_alloc_instruction(struct radeon_compiler * c); 204 struct rc_instruction *rc_insert_new_instruction(struct radeon_compiler * c, struct rc_instruction * after); 205 void rc_insert_instruction(struct rc_instruction * after, struct rc_instruction * inst); 206 void rc_remove_instruction(struct rc_instruction * inst); 207 208 unsigned int rc_recompute_ips(struct radeon_compiler * c); 209 210 void rc_print_program(const struct rc_program *prog); 211 212 rc_swizzle rc_mask_to_swizzle(unsigned int mask); 213 #endif 214