X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fpanfrost%2Fmidgard%2Fhelpers.h;h=1deac259151dfc1e656336147d4f8e9ee8ad93c6;hb=HEAD;hp=7a0a9d845e401cb8b5bf83513ea88e99f765808c;hpb=d168b08d621990cd1e47c7f3c13bb6e92195b52e;p=mesa.git diff --git a/src/panfrost/midgard/helpers.h b/src/panfrost/midgard/helpers.h index 7a0a9d845e4..1deac259151 100644 --- a/src/panfrost/midgard/helpers.h +++ b/src/panfrost/midgard/helpers.h @@ -23,28 +23,23 @@ #define __MDG_HELPERS_H #include "util/macros.h" +#include #include -#define OP_IS_STORE_VARY(op) (\ - op == midgard_op_st_vary_16 || \ - op == midgard_op_st_vary_32 || \ - op == midgard_op_st_vary_32u || \ - op == midgard_op_st_vary_32i \ - ) - -#define OP_IS_STORE_R26(op) (\ - OP_IS_STORE_VARY(op) || \ - op == midgard_op_st_char || \ - op == midgard_op_st_char2 || \ - op == midgard_op_st_char4 || \ - op == midgard_op_st_short4 || \ - op == midgard_op_st_int4 \ +#define OP_IS_LOAD_VARY_F(op) (\ + op == midgard_op_ld_vary_16 || \ + op == midgard_op_ld_vary_32 \ ) -#define OP_IS_STORE(op) (\ - OP_IS_STORE_VARY(op) || \ - op == midgard_op_st_cubemap_coords \ - ) +#define OP_IS_PROJECTION(op) ( \ + op == midgard_op_ldst_perspective_division_z || \ + op == midgard_op_ldst_perspective_division_w \ + ) + +#define OP_IS_VEC4_ONLY(op) ( \ + OP_IS_PROJECTION(op) || \ + op == midgard_op_ld_cubemap_coords \ + ) #define OP_IS_MOVE(op) ( \ op == midgard_alu_op_fmov || \ @@ -52,18 +47,37 @@ ) #define OP_IS_UBO_READ(op) ( \ - op == midgard_op_ld_uniform_32 || \ - op == midgard_op_ld_uniform_16 || \ - op == midgard_op_ld_uniform_32i \ + op == midgard_op_ld_ubo_char || \ + op == midgard_op_ld_ubo_char2 || \ + op == midgard_op_ld_ubo_char4 || \ + op == midgard_op_ld_ubo_short4 || \ + op == midgard_op_ld_ubo_int4 \ + ) + +#define OP_IS_CSEL_V(op) ( \ + op == midgard_alu_op_icsel_v || \ + op == midgard_alu_op_fcsel_v \ ) #define OP_IS_CSEL(op) ( \ + OP_IS_CSEL_V(op) || \ op == midgard_alu_op_icsel || \ - op == midgard_alu_op_icsel_v || \ - op == midgard_alu_op_fcsel_v || \ op == midgard_alu_op_fcsel \ ) +#define OP_IS_UNSIGNED_CMP(op) ( \ + op == midgard_alu_op_ult || \ + op == midgard_alu_op_ule \ + ) + +#define OP_IS_INTEGER_CMP(op) ( \ + op == midgard_alu_op_ieq || \ + op == midgard_alu_op_ine || \ + op == midgard_alu_op_ilt || \ + op == midgard_alu_op_ile || \ + OP_IS_UNSIGNED_CMP(op) \ + ) + /* ALU control words are single bit fields with a lot of space */ #define ALU_ENAB_VEC_MUL (1 << 17) @@ -101,6 +115,13 @@ /* Does the op convert types between int- and float- space (i2f/f2u/etc) */ #define OP_TYPE_CONVERT (1 << 4) +/* Is this opcode the first in a f2x (rte, rtz, rtn, rtp) sequence? If so, + * takes a roundmode argument in the IR. This has the semantic of rounding the + * source (it's all fused in), which is why it doesn't necessarily make sense + * for i2f (though folding there might be necessary for OpenCL reasons). Comes + * up in format conversion, i.e. f2u_rte */ +#define MIDGARD_ROUNDS (1 << 5) + /* Vector-independant shorthands for the above; these numbers are arbitrary and * not from the ISA. Convert to the above with unit_enum_to_midgard */ @@ -108,38 +129,7 @@ #define UNIT_ADD 1 #define UNIT_LUT 2 -/* 4-bit type tags */ - -#define TAG_TEXTURE_4_VTX 0x2 -#define TAG_TEXTURE_4 0x3 -#define TAG_LOAD_STORE_4 0x5 -#define TAG_ALU_4 0x8 -#define TAG_ALU_8 0x9 -#define TAG_ALU_12 0xA -#define TAG_ALU_16 0xB - -static inline int -quadword_size(int tag) -{ - switch (tag) { - case TAG_ALU_4: - case TAG_LOAD_STORE_4: - case TAG_TEXTURE_4: - case TAG_TEXTURE_4_VTX: - return 1; - case TAG_ALU_8: - return 2; - case TAG_ALU_12: - return 3; - case TAG_ALU_16: - return 4; - default: - unreachable("Unknown tag"); - } -} - -#define IS_ALU(tag) (tag == TAG_ALU_4 || tag == TAG_ALU_8 || \ - tag == TAG_ALU_12 || tag == TAG_ALU_16) +#define IS_ALU(tag) (tag >= TAG_ALU_4) /* Special register aliases */ @@ -148,56 +138,39 @@ quadword_size(int tag) /* Uniforms are begin at (REGISTER_UNIFORMS - uniform_count) */ #define REGISTER_UNIFORMS 24 +/* r24 and r25 are special registers that only exist during the pipeline, + * by using them when we don't care about the register we skip a roundtrip + * to the register file. */ #define REGISTER_UNUSED 24 #define REGISTER_CONSTANT 26 -#define REGISTER_VARYING_BASE 26 -#define REGISTER_OFFSET 27 +#define REGISTER_LDST_BASE 26 #define REGISTER_TEXTURE_BASE 28 #define REGISTER_SELECT 31 -/* SSA helper aliases to mimic the registers. UNUSED_0 encoded as an inline - * constant. UNUSED_1 encoded as REGISTER_UNUSED */ - -#define SSA_UNUSED_0 0 -#define SSA_UNUSED_1 -2 +/* SSA helper aliases to mimic the registers. */ #define SSA_FIXED_SHIFT 24 -#define SSA_FIXED_REGISTER(reg) ((1 + reg) << SSA_FIXED_SHIFT) -#define SSA_REG_FROM_FIXED(reg) ((reg >> SSA_FIXED_SHIFT) - 1) +#define SSA_FIXED_REGISTER(reg) (((1 + (reg)) << SSA_FIXED_SHIFT) | 1) +#define SSA_REG_FROM_FIXED(reg) ((((reg) & ~1) >> SSA_FIXED_SHIFT) - 1) #define SSA_FIXED_MINIMUM SSA_FIXED_REGISTER(0) -/* Swizzle support */ - -#define SWIZZLE(A, B, C, D) ((D << 6) | (C << 4) | (B << 2) | (A << 0)) -#define SWIZZLE_FROM_ARRAY(r) SWIZZLE(r[0], r[1], r[2], r[3]) #define COMPONENT_X 0x0 #define COMPONENT_Y 0x1 #define COMPONENT_Z 0x2 #define COMPONENT_W 0x3 -#define SWIZZLE_XXXX SWIZZLE(COMPONENT_X, COMPONENT_X, COMPONENT_X, COMPONENT_X) -#define SWIZZLE_XYXX SWIZZLE(COMPONENT_X, COMPONENT_Y, COMPONENT_X, COMPONENT_X) -#define SWIZZLE_XYZX SWIZZLE(COMPONENT_X, COMPONENT_Y, COMPONENT_Z, COMPONENT_X) -#define SWIZZLE_XYZW SWIZZLE(COMPONENT_X, COMPONENT_Y, COMPONENT_Z, COMPONENT_W) -#define SWIZZLE_XYXZ SWIZZLE(COMPONENT_X, COMPONENT_Y, COMPONENT_X, COMPONENT_Z) -#define SWIZZLE_XYZZ SWIZZLE(COMPONENT_X, COMPONENT_Y, COMPONENT_Z, COMPONENT_Z) -#define SWIZZLE_WWWW SWIZZLE(COMPONENT_W, COMPONENT_W, COMPONENT_W, COMPONENT_W) +#define SWIZZLE_IDENTITY { \ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, \ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, \ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, \ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } \ +} -static inline unsigned -swizzle_of(unsigned comp) -{ - switch (comp) { - case 1: - return SWIZZLE_XXXX; - case 2: - return SWIZZLE_XYXX; - case 3: - return SWIZZLE_XYZX; - case 4: - return SWIZZLE_XYZW; - default: - unreachable("Invalid component count"); - } +#define SWIZZLE_IDENTITY_4 { \ + { 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, \ + { 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, \ + { 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, \ + { 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, \ } static inline unsigned @@ -206,7 +179,6 @@ mask_of(unsigned nr_comp) return (1 << nr_comp) - 1; } - /* See ISA notes */ #define LDST_NOP (3) @@ -238,20 +210,53 @@ struct mir_op_props { unsigned props; }; +/* For load/store */ + +struct mir_ldst_op_props { + const char *name; + unsigned props; +}; + +struct mir_tag_props { + const char *name; + unsigned size; +}; + +/* Lower 2-bits are a midgard_reg_mode */ +#define GET_LDST_SIZE(c) (c & 3) + +/* Store (so the primary register is a source, not a destination */ +#define LDST_STORE (1 << 2) + +/* Mask has special meaning and should not be manipulated directly */ +#define LDST_SPECIAL_MASK (1 << 3) + +/* Non-store operation has side effects and should not be eliminated even if + * its mask is 0 */ +#define LDST_SIDE_FX (1 << 4) + +/* Computes an address according to indirects/zext/shift/etc */ +#define LDST_ADDRESS (1 << 5) + +/* Some fields such swizzle and address have special meanings */ +#define LDST_ATOMIC (1 << 6) + /* This file is common, so don't define the tables themselves. #include * midgard_op.h if you need that, or edit midgard_ops.c directly */ -/* Duplicate bits to convert a 4-bit writemask to duplicated 8-bit format, - * which is used for 32-bit vector units */ +/* Duplicate bits to convert a per-component to duplicated 8-bit format, + * which is used for vector units */ static inline unsigned -expand_writemask_32(unsigned mask) +expand_writemask(unsigned mask, unsigned log2_channels) { unsigned o = 0; + unsigned factor = 8 >> log2_channels; + unsigned expanded = (1 << factor) - 1; - for (int i = 0; i < 4; ++i) + for (unsigned i = 0; i < (1 << log2_channels); ++i) if (mask & (1 << i)) - o |= (3 << (2 * i)); + o |= (expanded << (factor * i)); return o; } @@ -274,33 +279,73 @@ vector_alu_from_unsigned(unsigned u) return s; } -/* Composes two swizzles */ -static inline unsigned -pan_compose_swizzle(unsigned left, unsigned right) +static inline void +mir_compose_swizzle(unsigned *left, unsigned *right, unsigned *final_out) { - unsigned out = 0; + unsigned out[16]; - for (unsigned c = 0; c < 4; ++c) { - unsigned s = (left >> (2*c)) & 0x3; - unsigned q = (right >> (2*s)) & 0x3; + for (unsigned c = 0; c < 16; ++c) + out[c] = right[left[c]]; - out |= (q << (2*c)); + memcpy(final_out, out, sizeof(out)); +} + +/* Checks for an xyzw.. swizzle, given a mask */ + +static inline bool +mir_is_simple_swizzle(unsigned *swizzle, unsigned mask) +{ + for (unsigned i = 0; i < 16; ++i) { + if (!(mask & (1 << i))) continue; + + if (swizzle[i] != i) + return false; } - return out; + return true; } -/* Applies a swizzle to an ALU source */ +/* Packs a load/store argument */ -static inline unsigned -vector_alu_apply_swizzle(unsigned src, unsigned swizzle) +static inline uint8_t +midgard_ldst_reg(unsigned reg, unsigned component, unsigned size) { - midgard_vector_alu_src s = - vector_alu_from_unsigned(src); + assert((reg == REGISTER_LDST_BASE) || (reg == REGISTER_LDST_BASE + 1)); + assert(size == 16 || size == 32 || size == 64); + + /* Shift so everything is in terms of 32-bit units */ + if (size == 64) { + assert(component < 2); + component <<= 1; + } else if (size == 16) { + assert((component & 1) == 0); + component >>= 1; + } - s.swizzle = pan_compose_swizzle(s.swizzle, swizzle); + midgard_ldst_register_select sel = { + .component = component, + .select = reg - 26 + }; - return vector_alu_srco_unsigned(s); + uint8_t packed; + memcpy(&packed, &sel, sizeof(packed)); + + return packed; +} + +static inline bool +midgard_is_branch_unit(unsigned unit) +{ + return (unit == ALU_ENAB_BRANCH) || (unit == ALU_ENAB_BR_COMPACT); } +/* Packs ALU mod argument */ +struct midgard_instruction; +unsigned mir_pack_mod(struct midgard_instruction *ins, unsigned i, bool scalar); + +void +mir_print_constant_component(FILE *fp, const midgard_constants *consts, + unsigned c, midgard_reg_mode reg_mode, bool half, + unsigned mod, midgard_alu_op op); + #endif