vc4_qir.h revision 24d998056275f4fab9bf3e98c962d91245ef1b7b
1/* 2 * Copyright © 2014 Broadcom 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24#ifndef VC4_QIR_H 25#define VC4_QIR_H 26 27#include <stdio.h> 28#include <stdlib.h> 29#include <stdbool.h> 30#include <stdint.h> 31#include <string.h> 32 33#include "util/u_simple_list.h" 34#include "tgsi/tgsi_parse.h" 35 36enum qfile { 37 QFILE_NULL, 38 QFILE_TEMP, 39 QFILE_VARY, 40 QFILE_UNIF, 41}; 42 43struct qreg { 44 enum qfile file; 45 uint32_t index; 46}; 47 48enum qop { 49 QOP_UNDEF, 50 QOP_MOV, 51 QOP_FADD, 52 QOP_FSUB, 53 QOP_FMUL, 54 QOP_MUL24, 55 QOP_FMIN, 56 QOP_FMAX, 57 QOP_FMINABS, 58 QOP_FMAXABS, 59 QOP_ADD, 60 QOP_SUB, 61 QOP_SHL, 62 QOP_SHR, 63 QOP_ASR, 64 QOP_MIN, 65 QOP_MAX, 66 QOP_AND, 67 QOP_OR, 68 QOP_XOR, 69 QOP_NOT, 70 71 /* Sets the flag register according to src. */ 72 QOP_SF, 73 74 /* Note: Orderings of these compares must be the same as in 75 * qpu_defines.h. Selects the src[0] if the ns flag bit is set, 76 * otherwise 0. */ 77 QOP_SEL_X_0_ZS, 78 QOP_SEL_X_0_ZC, 79 QOP_SEL_X_0_NS, 80 QOP_SEL_X_0_NC, 81 /* Selects the src[0] if the ns flag bit is set, otherwise src[1]. */ 82 QOP_SEL_X_Y_ZS, 83 QOP_SEL_X_Y_ZC, 84 QOP_SEL_X_Y_NS, 85 QOP_SEL_X_Y_NC, 86 87 QOP_FTOI, 88 QOP_ITOF, 89 QOP_RCP, 90 QOP_RSQ, 91 QOP_EXP2, 92 QOP_LOG2, 93 QOP_VW_SETUP, 94 QOP_VR_SETUP, 95 QOP_PACK_SCALED, 96 QOP_PACK_COLORS, 97 QOP_VPM_WRITE, 98 QOP_VPM_READ, 99 QOP_TLB_DISCARD_SETUP, 100 QOP_TLB_STENCIL_SETUP, 101 QOP_TLB_Z_WRITE, 102 QOP_TLB_COLOR_WRITE, 103 QOP_TLB_COLOR_READ, 104 QOP_VARY_ADD_C, 105 106 QOP_FRAG_X, 107 QOP_FRAG_Y, 108 QOP_FRAG_Z, 109 QOP_FRAG_W, 110 QOP_FRAG_REV_FLAG, 111 112 QOP_UNPACK_8A, 113 QOP_UNPACK_8B, 114 QOP_UNPACK_8C, 115 QOP_UNPACK_8D, 116 117 /** Texture x coordinate parameter write */ 118 QOP_TEX_S, 119 /** Texture y coordinate parameter write */ 120 QOP_TEX_T, 121 /** Texture border color parameter or cube map z coordinate write */ 122 QOP_TEX_R, 123 /** Texture LOD bias parameter write */ 124 QOP_TEX_B, 125 /** 126 * Signal of texture read being necessary and then reading r4 into 127 * the destination 128 */ 129 QOP_TEX_RESULT, 130 QOP_R4_UNPACK_A, 131 QOP_R4_UNPACK_B, 132 QOP_R4_UNPACK_C, 133 QOP_R4_UNPACK_D 134}; 135 136struct simple_node { 137 struct simple_node *next; 138 struct simple_node *prev; 139}; 140 141struct qinst { 142 struct simple_node link; 143 144 enum qop op; 145 struct qreg dst; 146 struct qreg *src; 147}; 148 149enum qstage { 150 /** 151 * Coordinate shader, runs during binning, before the VS, and just 152 * outputs position. 153 */ 154 QSTAGE_COORD, 155 QSTAGE_VERT, 156 QSTAGE_FRAG, 157}; 158 159enum quniform_contents { 160 /** 161 * Indicates that a constant 32-bit value is copied from the program's 162 * uniform contents. 163 */ 164 QUNIFORM_CONSTANT, 165 /** 166 * Indicates that the program's uniform contents are used as an index 167 * into the GL uniform storage. 168 */ 169 QUNIFORM_UNIFORM, 170 171 /** @{ 172 * Scaling factors from clip coordinates to relative to the viewport 173 * center. 174 * 175 * This is used by the coordinate and vertex shaders to produce the 176 * 32-bit entry consisting of 2 16-bit fields with 12.4 signed fixed 177 * point offsets from the viewport ccenter. 178 */ 179 QUNIFORM_VIEWPORT_X_SCALE, 180 QUNIFORM_VIEWPORT_Y_SCALE, 181 /** @} */ 182 183 QUNIFORM_VIEWPORT_Z_OFFSET, 184 QUNIFORM_VIEWPORT_Z_SCALE, 185 186 /** 187 * A reference to a texture config parameter 0 uniform. 188 * 189 * This is a uniform implicitly loaded with a QPU_W_TMU* write, which 190 * defines texture type, miplevels, and such. It will be found as a 191 * parameter to the first QOP_TEX_[STRB] instruction in a sequence. 192 */ 193 QUNIFORM_TEXTURE_CONFIG_P0, 194 195 /** 196 * A reference to a texture config parameter 1 uniform. 197 * 198 * This is a uniform implicitly loaded with a QPU_W_TMU* write, which 199 * defines texture width, height, filters, and wrap modes. It will be 200 * found as a parameter to the second QOP_TEX_[STRB] instruction in a 201 * sequence. 202 */ 203 QUNIFORM_TEXTURE_CONFIG_P1, 204 205 /** A reference to a texture config parameter 2 cubemap stride uniform */ 206 QUNIFORM_TEXTURE_CONFIG_P2, 207 208 QUNIFORM_TEXRECT_SCALE_X, 209 QUNIFORM_TEXRECT_SCALE_Y, 210 211 QUNIFORM_TEXTURE_BORDER_COLOR, 212 213 QUNIFORM_BLEND_CONST_COLOR, 214 QUNIFORM_STENCIL, 215 216 QUNIFORM_ALPHA_REF, 217}; 218 219struct vc4_compile { 220 struct tgsi_parse_context parser; 221 struct qreg *temps; 222 struct qreg *inputs; 223 struct qreg *outputs; 224 struct qreg *consts; 225 uint32_t temps_array_size; 226 uint32_t inputs_array_size; 227 uint32_t outputs_array_size; 228 uint32_t uniforms_array_size; 229 uint32_t consts_array_size; 230 uint32_t num_consts; 231 struct qreg line_x, point_x, point_y; 232 struct qreg discard; 233 234 struct pipe_shader_state *shader_state; 235 struct vc4_key *key; 236 struct vc4_fs_key *fs_key; 237 struct vc4_vs_key *vs_key; 238 239 uint32_t *uniform_data; 240 enum quniform_contents *uniform_contents; 241 uint32_t uniform_array_size; 242 uint32_t num_uniforms; 243 uint32_t num_outputs; 244 uint32_t num_texture_samples; 245 uint32_t output_position_index; 246 uint32_t output_color_index; 247 uint32_t output_point_size_index; 248 249 struct qreg undef; 250 enum qstage stage; 251 uint32_t num_temps; 252 struct simple_node instructions; 253 uint32_t immediates[1024]; 254 255 struct simple_node qpu_inst_list; 256 uint64_t *qpu_insts; 257 uint32_t qpu_inst_count; 258 uint32_t qpu_inst_size; 259 uint32_t num_inputs; 260 uint32_t color_inputs; 261}; 262 263struct vc4_compile *qir_compile_init(void); 264void qir_compile_destroy(struct vc4_compile *c); 265struct qinst *qir_inst(enum qop op, struct qreg dst, 266 struct qreg src0, struct qreg src1); 267struct qinst *qir_inst4(enum qop op, struct qreg dst, 268 struct qreg a, 269 struct qreg b, 270 struct qreg c, 271 struct qreg d); 272void qir_remove_instruction(struct qinst *qinst); 273void qir_reorder_uniforms(struct vc4_compile *c); 274void qir_emit(struct vc4_compile *c, struct qinst *inst); 275struct qreg qir_get_temp(struct vc4_compile *c); 276int qir_get_op_nsrc(enum qop qop); 277bool qir_reg_equals(struct qreg a, struct qreg b); 278bool qir_has_side_effects(struct qinst *inst); 279bool qir_depends_on_flags(struct qinst *inst); 280bool qir_writes_r4(struct qinst *inst); 281bool qir_reads_r4(struct qinst *inst); 282 283void qir_dump(struct vc4_compile *c); 284void qir_dump_inst(struct vc4_compile *c, struct qinst *inst); 285const char *qir_get_stage_name(enum qstage stage); 286 287void qir_optimize(struct vc4_compile *c); 288bool qir_opt_algebraic(struct vc4_compile *c); 289bool qir_opt_copy_propagation(struct vc4_compile *c); 290bool qir_opt_cse(struct vc4_compile *c); 291bool qir_opt_dead_code(struct vc4_compile *c); 292 293#define QIR_ALU0(name) \ 294static inline struct qreg \ 295qir_##name(struct vc4_compile *c) \ 296{ \ 297 struct qreg t = qir_get_temp(c); \ 298 qir_emit(c, qir_inst(QOP_##name, t, c->undef, c->undef)); \ 299 return t; \ 300} 301 302#define QIR_ALU1(name) \ 303static inline struct qreg \ 304qir_##name(struct vc4_compile *c, struct qreg a) \ 305{ \ 306 struct qreg t = qir_get_temp(c); \ 307 qir_emit(c, qir_inst(QOP_##name, t, a, c->undef)); \ 308 return t; \ 309} 310 311#define QIR_ALU2(name) \ 312static inline struct qreg \ 313qir_##name(struct vc4_compile *c, struct qreg a, struct qreg b) \ 314{ \ 315 struct qreg t = qir_get_temp(c); \ 316 qir_emit(c, qir_inst(QOP_##name, t, a, b)); \ 317 return t; \ 318} 319 320#define QIR_NODST_1(name) \ 321static inline void \ 322qir_##name(struct vc4_compile *c, struct qreg a) \ 323{ \ 324 qir_emit(c, qir_inst(QOP_##name, c->undef, a, c->undef)); \ 325} 326 327#define QIR_NODST_2(name) \ 328static inline void \ 329qir_##name(struct vc4_compile *c, struct qreg a, struct qreg b) \ 330{ \ 331 qir_emit(c, qir_inst(QOP_##name, c->undef, a, b)); \ 332} 333 334QIR_ALU1(MOV) 335QIR_ALU2(FADD) 336QIR_ALU2(FSUB) 337QIR_ALU2(FMUL) 338QIR_ALU2(MUL24) 339QIR_NODST_1(SF) 340QIR_ALU1(SEL_X_0_ZS) 341QIR_ALU1(SEL_X_0_ZC) 342QIR_ALU1(SEL_X_0_NS) 343QIR_ALU1(SEL_X_0_NC) 344QIR_ALU2(SEL_X_Y_ZS) 345QIR_ALU2(SEL_X_Y_ZC) 346QIR_ALU2(SEL_X_Y_NS) 347QIR_ALU2(SEL_X_Y_NC) 348QIR_ALU2(FMIN) 349QIR_ALU2(FMAX) 350QIR_ALU2(FMINABS) 351QIR_ALU2(FMAXABS) 352QIR_ALU1(FTOI) 353QIR_ALU1(ITOF) 354 355QIR_ALU2(ADD) 356QIR_ALU2(SUB) 357QIR_ALU2(SHL) 358QIR_ALU2(SHR) 359QIR_ALU2(ASR) 360QIR_ALU2(MIN) 361QIR_ALU2(MAX) 362QIR_ALU2(AND) 363QIR_ALU2(OR) 364QIR_ALU2(XOR) 365QIR_ALU1(NOT) 366 367QIR_ALU1(RCP) 368QIR_ALU1(RSQ) 369QIR_ALU1(EXP2) 370QIR_ALU1(LOG2) 371QIR_ALU2(PACK_SCALED) 372QIR_ALU1(VARY_ADD_C) 373QIR_NODST_1(VPM_WRITE) 374QIR_NODST_2(TEX_S) 375QIR_NODST_2(TEX_T) 376QIR_NODST_2(TEX_R) 377QIR_NODST_2(TEX_B) 378QIR_ALU0(FRAG_X) 379QIR_ALU0(FRAG_Y) 380QIR_ALU0(FRAG_Z) 381QIR_ALU0(FRAG_W) 382QIR_ALU0(FRAG_REV_FLAG) 383QIR_ALU0(TEX_RESULT) 384QIR_ALU0(TLB_COLOR_READ) 385QIR_NODST_1(TLB_Z_WRITE) 386QIR_NODST_1(TLB_DISCARD_SETUP) 387QIR_NODST_1(TLB_STENCIL_SETUP) 388 389static inline struct qreg 390qir_R4_UNPACK(struct vc4_compile *c, struct qreg r4, int i) 391{ 392 struct qreg t = qir_get_temp(c); 393 qir_emit(c, qir_inst(QOP_R4_UNPACK_A + i, t, r4, c->undef)); 394 return t; 395} 396 397static inline struct qreg 398qir_SEL_X_0_COND(struct vc4_compile *c, int i) 399{ 400 struct qreg t = qir_get_temp(c); 401 qir_emit(c, qir_inst(QOP_R4_UNPACK_A + i, t, c->undef, c->undef)); 402 return t; 403} 404 405static inline struct qreg 406qir_UNPACK_8(struct vc4_compile *c, struct qreg src, int i) 407{ 408 struct qreg t = qir_get_temp(c); 409 qir_emit(c, qir_inst(QOP_UNPACK_8A + i, t, src, c->undef)); 410 return t; 411} 412 413static inline struct qreg 414qir_POW(struct vc4_compile *c, struct qreg x, struct qreg y) 415{ 416 return qir_EXP2(c, qir_FMUL(c, 417 y, 418 qir_LOG2(c, x))); 419} 420 421#endif /* VC4_QIR_H */ 422