vc4_qir.h revision 419fee92eef229314e28879a7b8a6a8dc3b4b549
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 <assert.h> 28#include <stdio.h> 29#include <stdlib.h> 30#include <stdbool.h> 31#include <stdint.h> 32#include <string.h> 33 34#include "util/macros.h" 35#include "compiler/nir/nir.h" 36#include "util/list.h" 37#include "util/u_math.h" 38 39#include "vc4_screen.h" 40#include "vc4_qpu_defines.h" 41#include "kernel/vc4_packet.h" 42#include "pipe/p_state.h" 43 44struct nir_builder; 45 46enum qfile { 47 QFILE_NULL, 48 QFILE_TEMP, 49 QFILE_VARY, 50 QFILE_UNIF, 51 QFILE_VPM, 52 QFILE_TLB_COLOR_WRITE, 53 QFILE_TLB_COLOR_WRITE_MS, 54 QFILE_TLB_Z_WRITE, 55 QFILE_TLB_STENCIL_SETUP, 56 57 /* Payload registers that aren't in the physical register file, so we 58 * can just use the corresponding qpu_reg at qpu_emit time. 59 */ 60 QFILE_FRAG_X, 61 QFILE_FRAG_Y, 62 QFILE_FRAG_REV_FLAG, 63 64 /** 65 * Stores an immediate value in the index field that can be turned 66 * into a small immediate field by qpu_encode_small_immediate(). 67 */ 68 QFILE_SMALL_IMM, 69}; 70 71struct qreg { 72 enum qfile file; 73 uint32_t index; 74 int pack; 75}; 76 77static inline struct qreg qir_reg(enum qfile file, uint32_t index) 78{ 79 return (struct qreg){file, index}; 80} 81 82enum qop { 83 QOP_UNDEF, 84 QOP_MOV, 85 QOP_FMOV, 86 QOP_MMOV, 87 QOP_FADD, 88 QOP_FSUB, 89 QOP_FMUL, 90 QOP_V8MULD, 91 QOP_V8MIN, 92 QOP_V8MAX, 93 QOP_V8ADDS, 94 QOP_V8SUBS, 95 QOP_MUL24, 96 QOP_FMIN, 97 QOP_FMAX, 98 QOP_FMINABS, 99 QOP_FMAXABS, 100 QOP_ADD, 101 QOP_SUB, 102 QOP_SHL, 103 QOP_SHR, 104 QOP_ASR, 105 QOP_MIN, 106 QOP_MAX, 107 QOP_AND, 108 QOP_OR, 109 QOP_XOR, 110 QOP_NOT, 111 112 QOP_FTOI, 113 QOP_ITOF, 114 QOP_RCP, 115 QOP_RSQ, 116 QOP_EXP2, 117 QOP_LOG2, 118 QOP_VW_SETUP, 119 QOP_VR_SETUP, 120 QOP_TLB_COLOR_READ, 121 QOP_MS_MASK, 122 QOP_VARY_ADD_C, 123 124 QOP_FRAG_Z, 125 QOP_FRAG_W, 126 127 /** Texture x coordinate parameter write */ 128 QOP_TEX_S, 129 /** Texture y coordinate parameter write */ 130 QOP_TEX_T, 131 /** Texture border color parameter or cube map z coordinate write */ 132 QOP_TEX_R, 133 /** Texture LOD bias parameter write */ 134 QOP_TEX_B, 135 136 /** 137 * Texture-unit 4-byte read with address provided direct in S 138 * cooordinate. 139 * 140 * The first operand is the offset from the start of the UBO, and the 141 * second is the uniform that has the UBO's base pointer. 142 */ 143 QOP_TEX_DIRECT, 144 145 /** 146 * Signal of texture read being necessary and then reading r4 into 147 * the destination 148 */ 149 QOP_TEX_RESULT, 150}; 151 152struct queued_qpu_inst { 153 struct list_head link; 154 uint64_t inst; 155}; 156 157struct qinst { 158 struct list_head link; 159 160 enum qop op; 161 struct qreg dst; 162 struct qreg *src; 163 bool sf; 164 uint8_t cond; 165}; 166 167enum qstage { 168 /** 169 * Coordinate shader, runs during binning, before the VS, and just 170 * outputs position. 171 */ 172 QSTAGE_COORD, 173 QSTAGE_VERT, 174 QSTAGE_FRAG, 175}; 176 177enum quniform_contents { 178 /** 179 * Indicates that a constant 32-bit value is copied from the program's 180 * uniform contents. 181 */ 182 QUNIFORM_CONSTANT, 183 /** 184 * Indicates that the program's uniform contents are used as an index 185 * into the GL uniform storage. 186 */ 187 QUNIFORM_UNIFORM, 188 189 /** @{ 190 * Scaling factors from clip coordinates to relative to the viewport 191 * center. 192 * 193 * This is used by the coordinate and vertex shaders to produce the 194 * 32-bit entry consisting of 2 16-bit fields with 12.4 signed fixed 195 * point offsets from the viewport ccenter. 196 */ 197 QUNIFORM_VIEWPORT_X_SCALE, 198 QUNIFORM_VIEWPORT_Y_SCALE, 199 /** @} */ 200 201 QUNIFORM_VIEWPORT_Z_OFFSET, 202 QUNIFORM_VIEWPORT_Z_SCALE, 203 204 QUNIFORM_USER_CLIP_PLANE, 205 206 /** 207 * A reference to a texture config parameter 0 uniform. 208 * 209 * This is a uniform implicitly loaded with a QPU_W_TMU* write, which 210 * defines texture type, miplevels, and such. It will be found as a 211 * parameter to the first QOP_TEX_[STRB] instruction in a sequence. 212 */ 213 QUNIFORM_TEXTURE_CONFIG_P0, 214 215 /** 216 * A reference to a texture config parameter 1 uniform. 217 * 218 * This is a uniform implicitly loaded with a QPU_W_TMU* write, which 219 * defines texture width, height, filters, and wrap modes. It will be 220 * found as a parameter to the second QOP_TEX_[STRB] instruction in a 221 * sequence. 222 */ 223 QUNIFORM_TEXTURE_CONFIG_P1, 224 225 /** A reference to a texture config parameter 2 cubemap stride uniform */ 226 QUNIFORM_TEXTURE_CONFIG_P2, 227 228 QUNIFORM_TEXTURE_MSAA_ADDR, 229 230 QUNIFORM_UBO_ADDR, 231 232 QUNIFORM_TEXRECT_SCALE_X, 233 QUNIFORM_TEXRECT_SCALE_Y, 234 235 QUNIFORM_TEXTURE_BORDER_COLOR, 236 237 QUNIFORM_BLEND_CONST_COLOR_X, 238 QUNIFORM_BLEND_CONST_COLOR_Y, 239 QUNIFORM_BLEND_CONST_COLOR_Z, 240 QUNIFORM_BLEND_CONST_COLOR_W, 241 QUNIFORM_BLEND_CONST_COLOR_RGBA, 242 QUNIFORM_BLEND_CONST_COLOR_AAAA, 243 244 QUNIFORM_STENCIL, 245 246 QUNIFORM_ALPHA_REF, 247 QUNIFORM_SAMPLE_MASK, 248}; 249 250struct vc4_varying_slot { 251 uint8_t slot; 252 uint8_t swizzle; 253}; 254 255struct vc4_compiler_ubo_range { 256 /** 257 * offset in bytes from the start of the ubo where this range is 258 * uploaded. 259 * 260 * Only set once used is set. 261 */ 262 uint32_t dst_offset; 263 264 /** 265 * offset in bytes from the start of the gallium uniforms where the 266 * data comes from. 267 */ 268 uint32_t src_offset; 269 270 /** size in bytes of this ubo range */ 271 uint32_t size; 272 273 /** 274 * Set if this range is used by the shader for indirect uniforms 275 * access. 276 */ 277 bool used; 278}; 279 280struct vc4_key { 281 struct vc4_uncompiled_shader *shader_state; 282 struct { 283 enum pipe_format format; 284 uint8_t swizzle[4]; 285 union { 286 struct { 287 unsigned compare_mode:1; 288 unsigned compare_func:3; 289 unsigned wrap_s:3; 290 unsigned wrap_t:3; 291 }; 292 struct { 293 uint16_t msaa_width, msaa_height; 294 }; 295 }; 296 } tex[VC4_MAX_TEXTURE_SAMPLERS]; 297 uint8_t ucp_enables; 298}; 299 300struct vc4_fs_key { 301 struct vc4_key base; 302 enum pipe_format color_format; 303 bool depth_enabled; 304 bool stencil_enabled; 305 bool stencil_twoside; 306 bool stencil_full_writemasks; 307 bool is_points; 308 bool is_lines; 309 bool alpha_test; 310 bool point_coord_upper_left; 311 bool light_twoside; 312 bool msaa; 313 bool sample_coverage; 314 bool sample_alpha_to_coverage; 315 bool sample_alpha_to_one; 316 uint8_t alpha_test_func; 317 uint8_t logicop_func; 318 uint32_t point_sprite_mask; 319 320 struct pipe_rt_blend_state blend; 321}; 322 323struct vc4_vs_key { 324 struct vc4_key base; 325 326 /** 327 * This is a proxy for the array of FS input semantics, which is 328 * larger than we would want to put in the key. 329 */ 330 uint64_t compiled_fs_id; 331 332 enum pipe_format attr_formats[8]; 333 bool is_coord; 334 bool per_vertex_point_size; 335}; 336 337struct vc4_compile { 338 struct vc4_context *vc4; 339 nir_shader *s; 340 nir_function_impl *impl; 341 struct exec_list *cf_node_list; 342 343 /** 344 * Mapping from nir_register * or nir_ssa_def * to array of struct 345 * qreg for the values. 346 */ 347 struct hash_table *def_ht; 348 349 /* For each temp, the instruction generating its value. */ 350 struct qinst **defs; 351 uint32_t defs_array_size; 352 353 /** 354 * Inputs to the shader, arranged by TGSI declaration order. 355 * 356 * Not all fragment shader QFILE_VARY reads are present in this array. 357 */ 358 struct qreg *inputs; 359 struct qreg *outputs; 360 bool msaa_per_sample_output; 361 struct qreg color_reads[VC4_MAX_SAMPLES]; 362 struct qreg sample_colors[VC4_MAX_SAMPLES]; 363 uint32_t inputs_array_size; 364 uint32_t outputs_array_size; 365 uint32_t uniforms_array_size; 366 367 struct vc4_compiler_ubo_range *ubo_ranges; 368 uint32_t ubo_ranges_array_size; 369 /** Number of uniform areas declared in ubo_ranges. */ 370 uint32_t num_uniform_ranges; 371 /** Number of uniform areas used for indirect addressed loads. */ 372 uint32_t num_ubo_ranges; 373 uint32_t next_ubo_dst_offset; 374 375 struct qreg line_x, point_x, point_y; 376 struct qreg discard; 377 struct qreg payload_FRAG_Z; 378 struct qreg payload_FRAG_W; 379 380 uint8_t vattr_sizes[8]; 381 382 /** 383 * Array of the VARYING_SLOT_* of all FS QFILE_VARY reads. 384 * 385 * This includes those that aren't part of the VPM varyings, like 386 * point/line coordinates. 387 */ 388 struct vc4_varying_slot *input_slots; 389 uint32_t num_input_slots; 390 uint32_t input_slots_array_size; 391 392 /** 393 * An entry per outputs[] in the VS indicating what the VARYING_SLOT_* 394 * of the output is. Used to emit from the VS in the order that the 395 * FS needs. 396 */ 397 struct vc4_varying_slot *output_slots; 398 399 struct pipe_shader_state *shader_state; 400 struct vc4_key *key; 401 struct vc4_fs_key *fs_key; 402 struct vc4_vs_key *vs_key; 403 404 uint32_t *uniform_data; 405 enum quniform_contents *uniform_contents; 406 uint32_t uniform_array_size; 407 uint32_t num_uniforms; 408 uint32_t num_outputs; 409 uint32_t num_texture_samples; 410 uint32_t output_position_index; 411 uint32_t output_color_index; 412 uint32_t output_point_size_index; 413 uint32_t output_sample_mask_index; 414 415 struct qreg undef; 416 enum qstage stage; 417 uint32_t num_temps; 418 struct list_head instructions; 419 420 struct list_head qpu_inst_list; 421 uint64_t *qpu_insts; 422 uint32_t qpu_inst_count; 423 uint32_t qpu_inst_size; 424 uint32_t num_inputs; 425 426 uint32_t program_id; 427 uint32_t variant_id; 428}; 429 430/* Special nir_load_input intrinsic index for loading the current TLB 431 * destination color. 432 */ 433#define VC4_NIR_TLB_COLOR_READ_INPUT 2000000000 434 435#define VC4_NIR_MS_MASK_OUTPUT 2000000000 436 437/* Special offset for nir_load_uniform values to get a QUNIFORM_* 438 * state-dependent value. 439 */ 440#define VC4_NIR_STATE_UNIFORM_OFFSET 1000000000 441 442struct vc4_compile *qir_compile_init(void); 443void qir_compile_destroy(struct vc4_compile *c); 444struct qinst *qir_inst(enum qop op, struct qreg dst, 445 struct qreg src0, struct qreg src1); 446struct qinst *qir_inst4(enum qop op, struct qreg dst, 447 struct qreg a, 448 struct qreg b, 449 struct qreg c, 450 struct qreg d); 451void qir_remove_instruction(struct vc4_compile *c, struct qinst *qinst); 452struct qreg qir_uniform(struct vc4_compile *c, 453 enum quniform_contents contents, 454 uint32_t data); 455void qir_schedule_instructions(struct vc4_compile *c); 456void qir_reorder_uniforms(struct vc4_compile *c); 457 458void qir_emit(struct vc4_compile *c, struct qinst *inst); 459static inline struct qinst * 460qir_emit_nodef(struct vc4_compile *c, struct qinst *inst) 461{ 462 list_addtail(&inst->link, &c->instructions); 463 return inst; 464} 465 466struct qreg qir_get_temp(struct vc4_compile *c); 467int qir_get_op_nsrc(enum qop qop); 468bool qir_reg_equals(struct qreg a, struct qreg b); 469bool qir_has_side_effects(struct vc4_compile *c, struct qinst *inst); 470bool qir_has_side_effect_reads(struct vc4_compile *c, struct qinst *inst); 471bool qir_is_mul(struct qinst *inst); 472bool qir_is_raw_mov(struct qinst *inst); 473bool qir_is_tex(struct qinst *inst); 474bool qir_is_float_input(struct qinst *inst); 475bool qir_depends_on_flags(struct qinst *inst); 476bool qir_writes_r4(struct qinst *inst); 477struct qreg qir_follow_movs(struct vc4_compile *c, struct qreg reg); 478 479void qir_dump(struct vc4_compile *c); 480void qir_dump_inst(struct vc4_compile *c, struct qinst *inst); 481const char *qir_get_stage_name(enum qstage stage); 482 483void qir_optimize(struct vc4_compile *c); 484bool qir_opt_algebraic(struct vc4_compile *c); 485bool qir_opt_constant_folding(struct vc4_compile *c); 486bool qir_opt_copy_propagation(struct vc4_compile *c); 487bool qir_opt_dead_code(struct vc4_compile *c); 488bool qir_opt_small_immediates(struct vc4_compile *c); 489bool qir_opt_vpm(struct vc4_compile *c); 490void vc4_nir_lower_blend(nir_shader *s, struct vc4_compile *c); 491void vc4_nir_lower_io(nir_shader *s, struct vc4_compile *c); 492nir_ssa_def *vc4_nir_get_state_uniform(struct nir_builder *b, 493 enum quniform_contents contents); 494nir_ssa_def *vc4_nir_get_swizzled_channel(struct nir_builder *b, 495 nir_ssa_def **srcs, int swiz); 496void vc4_nir_lower_txf_ms(nir_shader *s, struct vc4_compile *c); 497void qir_lower_uniforms(struct vc4_compile *c); 498 499uint32_t qpu_schedule_instructions(struct vc4_compile *c); 500 501void qir_SF(struct vc4_compile *c, struct qreg src); 502 503static inline struct qreg 504qir_uniform_ui(struct vc4_compile *c, uint32_t ui) 505{ 506 return qir_uniform(c, QUNIFORM_CONSTANT, ui); 507} 508 509static inline struct qreg 510qir_uniform_f(struct vc4_compile *c, float f) 511{ 512 return qir_uniform(c, QUNIFORM_CONSTANT, fui(f)); 513} 514 515#define QIR_ALU0(name) \ 516static inline struct qreg \ 517qir_##name(struct vc4_compile *c) \ 518{ \ 519 struct qreg t = qir_get_temp(c); \ 520 qir_emit(c, qir_inst(QOP_##name, t, c->undef, c->undef)); \ 521 return t; \ 522} 523 524#define QIR_ALU1(name) \ 525static inline struct qreg \ 526qir_##name(struct vc4_compile *c, struct qreg a) \ 527{ \ 528 struct qreg t = qir_get_temp(c); \ 529 qir_emit(c, qir_inst(QOP_##name, t, a, c->undef)); \ 530 return t; \ 531} \ 532static inline struct qinst * \ 533qir_##name##_dest(struct vc4_compile *c, struct qreg dest, \ 534 struct qreg a) \ 535{ \ 536 if (dest.file == QFILE_TEMP) \ 537 c->defs[dest.index] = NULL; \ 538 return qir_emit_nodef(c, qir_inst(QOP_##name, dest, a, \ 539 c->undef)); \ 540} 541 542#define QIR_ALU2(name) \ 543static inline struct qreg \ 544qir_##name(struct vc4_compile *c, struct qreg a, struct qreg b) \ 545{ \ 546 struct qreg t = qir_get_temp(c); \ 547 qir_emit(c, qir_inst(QOP_##name, t, a, b)); \ 548 return t; \ 549} \ 550static inline void \ 551qir_##name##_dest(struct vc4_compile *c, struct qreg dest, \ 552 struct qreg a, struct qreg b) \ 553{ \ 554 qir_emit_nodef(c, qir_inst(QOP_##name, dest, a, b)); \ 555} 556 557#define QIR_NODST_1(name) \ 558static inline struct qinst * \ 559qir_##name(struct vc4_compile *c, struct qreg a) \ 560{ \ 561 struct qinst *inst = qir_inst(QOP_##name, c->undef, \ 562 a, c->undef); \ 563 qir_emit(c, inst); \ 564 return inst; \ 565} 566 567#define QIR_NODST_2(name) \ 568static inline struct qinst * \ 569qir_##name(struct vc4_compile *c, struct qreg a, struct qreg b) \ 570{ \ 571 struct qinst *inst = qir_inst(QOP_##name, c->undef, \ 572 a, b); \ 573 qir_emit(c, inst); \ 574 return inst; \ 575} 576 577#define QIR_PACK(name) \ 578static inline struct qreg \ 579qir_##name(struct vc4_compile *c, struct qreg dest, struct qreg a) \ 580{ \ 581 qir_emit_nodef(c, qir_inst(QOP_##name, dest, a, c->undef)); \ 582 return dest; \ 583} 584 585#define QIR_PAYLOAD(name) \ 586static inline struct qreg \ 587qir_##name(struct vc4_compile *c) \ 588{ \ 589 struct qreg *payload = &c->payload_##name; \ 590 if (payload->file != QFILE_NULL) \ 591 return *payload; \ 592 *payload = qir_get_temp(c); \ 593 struct qinst *inst = qir_inst(QOP_##name, *payload, \ 594 c->undef, c->undef); \ 595 list_add(&inst->link, &c->instructions); \ 596 c->defs[payload->index] = inst; \ 597 return *payload; \ 598} 599 600QIR_ALU1(MOV) 601QIR_ALU1(FMOV) 602QIR_ALU1(MMOV) 603QIR_ALU2(FADD) 604QIR_ALU2(FSUB) 605QIR_ALU2(FMUL) 606QIR_ALU2(V8MULD) 607QIR_ALU2(V8MIN) 608QIR_ALU2(V8MAX) 609QIR_ALU2(V8ADDS) 610QIR_ALU2(V8SUBS) 611QIR_ALU2(MUL24) 612QIR_ALU2(FMIN) 613QIR_ALU2(FMAX) 614QIR_ALU2(FMINABS) 615QIR_ALU2(FMAXABS) 616QIR_ALU1(FTOI) 617QIR_ALU1(ITOF) 618 619QIR_ALU2(ADD) 620QIR_ALU2(SUB) 621QIR_ALU2(SHL) 622QIR_ALU2(SHR) 623QIR_ALU2(ASR) 624QIR_ALU2(MIN) 625QIR_ALU2(MAX) 626QIR_ALU2(AND) 627QIR_ALU2(OR) 628QIR_ALU2(XOR) 629QIR_ALU1(NOT) 630 631QIR_ALU1(RCP) 632QIR_ALU1(RSQ) 633QIR_ALU1(EXP2) 634QIR_ALU1(LOG2) 635QIR_ALU1(VARY_ADD_C) 636QIR_NODST_2(TEX_S) 637QIR_NODST_2(TEX_T) 638QIR_NODST_2(TEX_R) 639QIR_NODST_2(TEX_B) 640QIR_NODST_2(TEX_DIRECT) 641QIR_PAYLOAD(FRAG_Z) 642QIR_PAYLOAD(FRAG_W) 643QIR_ALU0(TEX_RESULT) 644QIR_ALU0(TLB_COLOR_READ) 645QIR_NODST_1(MS_MASK) 646 647static inline struct qreg 648qir_SEL(struct vc4_compile *c, uint8_t cond, struct qreg src0, struct qreg src1) 649{ 650 struct qreg t = qir_get_temp(c); 651 struct qinst *a = qir_MOV_dest(c, t, src0); 652 struct qinst *b = qir_MOV_dest(c, t, src1); 653 a->cond = cond; 654 b->cond = cond ^ 1; 655 return t; 656} 657 658static inline struct qreg 659qir_UNPACK_8_F(struct vc4_compile *c, struct qreg src, int i) 660{ 661 struct qreg t = qir_FMOV(c, src); 662 c->defs[t.index]->src[0].pack = QPU_UNPACK_8A + i; 663 return t; 664} 665 666static inline struct qreg 667qir_UNPACK_8_I(struct vc4_compile *c, struct qreg src, int i) 668{ 669 struct qreg t = qir_MOV(c, src); 670 c->defs[t.index]->src[0].pack = QPU_UNPACK_8A + i; 671 return t; 672} 673 674static inline struct qreg 675qir_UNPACK_16_F(struct vc4_compile *c, struct qreg src, int i) 676{ 677 struct qreg t = qir_FMOV(c, src); 678 c->defs[t.index]->src[0].pack = QPU_UNPACK_16A + i; 679 return t; 680} 681 682static inline struct qreg 683qir_UNPACK_16_I(struct vc4_compile *c, struct qreg src, int i) 684{ 685 struct qreg t = qir_MOV(c, src); 686 c->defs[t.index]->src[0].pack = QPU_UNPACK_16A + i; 687 return t; 688} 689 690static inline void 691qir_PACK_8_F(struct vc4_compile *c, struct qreg dest, struct qreg val, int chan) 692{ 693 assert(!dest.pack); 694 dest.pack = QPU_PACK_MUL_8A + chan; 695 qir_emit(c, qir_inst(QOP_MMOV, dest, val, c->undef)); 696 if (dest.file == QFILE_TEMP) 697 c->defs[dest.index] = NULL; 698} 699 700static inline struct qreg 701qir_PACK_8888_F(struct vc4_compile *c, struct qreg val) 702{ 703 struct qreg dest = qir_MMOV(c, val); 704 c->defs[dest.index]->dst.pack = QPU_PACK_MUL_8888; 705 return dest; 706} 707 708static inline struct qreg 709qir_POW(struct vc4_compile *c, struct qreg x, struct qreg y) 710{ 711 return qir_EXP2(c, qir_FMUL(c, 712 y, 713 qir_LOG2(c, x))); 714} 715 716static inline void 717qir_VPM_WRITE(struct vc4_compile *c, struct qreg val) 718{ 719 qir_MOV_dest(c, qir_reg(QFILE_VPM, 0), val); 720} 721 722#endif /* VC4_QIR_H */ 723