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