Path: blob/21.2-virgl/src/gallium/drivers/nouveau/nv30/nvfx_shader.h
4574 views
#ifndef __NVFX_SHADER_H__1#define __NVFX_SHADER_H__23#include <stdint.h>45#include "pipe/p_compiler.h"67#define NVFX_SWZ_IDENTITY ((3 << 6) | (2 << 4) | (1 << 2) | (0 << 0))89/* this will resolve to either the NV30 or the NV40 version10* depending on the current hardware */11/* unusual, but very fast and compact method */12#define NVFX_VP(c) ((NV30_VP_##c) + (vpc->is_nv4x & ((NV40_VP_##c) - (NV30_VP_##c))))1314#define NVFX_VP_INST_SLOT_VEC 015#define NVFX_VP_INST_SLOT_SCA 11617#define NVFX_VP_INST_IN_POS 0 /* These seem to match the bindings specified in */18#define NVFX_VP_INST_IN_WEIGHT 1 /* the ARB_v_p spec (2.14.3.1) */19#define NVFX_VP_INST_IN_NORMAL 220#define NVFX_VP_INST_IN_COL0 3 /* Should probably confirm them all though */21#define NVFX_VP_INST_IN_COL1 422#define NVFX_VP_INST_IN_FOGC 523#define NVFX_VP_INST_IN_TC0 824#define NVFX_VP_INST_IN_TC(n) (8+n)2526#define NVFX_VP_INST_SCA_OP_NOP 0x0027#define NVFX_VP_INST_SCA_OP_MOV 0x0128#define NVFX_VP_INST_SCA_OP_RCP 0x0229#define NVFX_VP_INST_SCA_OP_RCC 0x0330#define NVFX_VP_INST_SCA_OP_RSQ 0x0431#define NVFX_VP_INST_SCA_OP_EXP 0x0532#define NVFX_VP_INST_SCA_OP_LOG 0x0633#define NVFX_VP_INST_SCA_OP_LIT 0x0734#define NVFX_VP_INST_SCA_OP_BRA 0x0935#define NVFX_VP_INST_SCA_OP_CAL 0x0B36#define NVFX_VP_INST_SCA_OP_RET 0x0C37#define NVFX_VP_INST_SCA_OP_LG2 0x0D38#define NVFX_VP_INST_SCA_OP_EX2 0x0E39#define NVFX_VP_INST_SCA_OP_SIN 0x0F40#define NVFX_VP_INST_SCA_OP_COS 0x104142#define NV40_VP_INST_SCA_OP_PUSHA 0x1343#define NV40_VP_INST_SCA_OP_POPA 0x144445#define NVFX_VP_INST_VEC_OP_NOP 0x0046#define NVFX_VP_INST_VEC_OP_MOV 0x0147#define NVFX_VP_INST_VEC_OP_MUL 0x0248#define NVFX_VP_INST_VEC_OP_ADD 0x0349#define NVFX_VP_INST_VEC_OP_MAD 0x0450#define NVFX_VP_INST_VEC_OP_DP3 0x0551#define NVFX_VP_INST_VEC_OP_DPH 0x0652#define NVFX_VP_INST_VEC_OP_DP4 0x0753#define NVFX_VP_INST_VEC_OP_DST 0x0854#define NVFX_VP_INST_VEC_OP_MIN 0x0955#define NVFX_VP_INST_VEC_OP_MAX 0x0A56#define NVFX_VP_INST_VEC_OP_SLT 0x0B57#define NVFX_VP_INST_VEC_OP_SGE 0x0C58#define NVFX_VP_INST_VEC_OP_ARL 0x0D59#define NVFX_VP_INST_VEC_OP_FRC 0x0E60#define NVFX_VP_INST_VEC_OP_FLR 0x0F61#define NVFX_VP_INST_VEC_OP_SEQ 0x1062#define NVFX_VP_INST_VEC_OP_SFL 0x1163#define NVFX_VP_INST_VEC_OP_SGT 0x1264#define NVFX_VP_INST_VEC_OP_SLE 0x1365#define NVFX_VP_INST_VEC_OP_SNE 0x1466#define NVFX_VP_INST_VEC_OP_STR 0x1567#define NVFX_VP_INST_VEC_OP_SSG 0x1668#define NVFX_VP_INST_VEC_OP_ARR 0x1769#define NVFX_VP_INST_VEC_OP_ARA 0x187071#define NV40_VP_INST_VEC_OP_TXL 0x197273/* DWORD 3 */74#define NVFX_VP_INST_LAST (1 << 0)7576/*77* Each fragment program opcode appears to be comprised of 4 32-bit values.78*79* 0: OPDEST80* 0: program end81* 1-6: destination register82* 7: destination register is fp16?? (use for outputs)83* 8: set condition code84* 9: writemask x85* 10: writemask y86* 11: writemask z87* 12: writemask w88* 13-16: source attribute register number (e.g. COL0)89* 17-20: texture unit number90* 21: expand value on texture operation (x -> 2x - 1)91* 22-23: precision 0 = fp32, 1 = fp16, 2 = s1.10 fixed, 3 = s0.8 fixed (nv40-only))92* 24-29: opcode93* 30: no destination94* 31: saturate95* 1 - SRC096* 0-17: see common source fields97* 18: execute if condition code less98* 19: execute if condition code equal99* 20: execute if condition code greater100* 21-22: condition code swizzle x source component101* 23-24: condition code swizzle y source component102* 25-26: condition code swizzle z source component103* 27-28: condition code swizzle w source component104* 29: source 0 absolute105* 30: always 0 in renouveau tests106* 31: always 0 in renouveau tests107* 2 - SRC1108* 0-17: see common source fields109* 18: source 1 absolute110* 19-20: input precision 0 = fp32, 1 = fp16, 2 = s1.10 fixed, 3 = ???111* 21-27: always 0 in renouveau tests112* 28-30: scale (0 = 1x, 1 = 2x, 2 = 4x, 3 = 8x, 4 = ???, 5, = 1/2, 6 = 1/4, 7 = 1/8)113* 31: opcode is branch114* 3 - SRC2115* 0-17: see common source fields116* 18: source 2 absolute117* 19-29: address register displacement118* 30: use index register119* 31: disable perspective-correct interpolation?120*121* Common fields of 0, 1, 2 - SRC122* 0-1: source register type (0 = temp, 1 = input, 2 = immediate, 3 = ???)123* 2-7: source temp register index124* 8: source register is fp16??125* 9-10: source swizzle x source component126* 11-12: source swizzle y source component127* 13-14: source swizzle z source component128* 15-16: source swizzle w source component129* 17: negate130131* There appears to be no special difference between result regs and temp regs.132* result.color == R0.xyzw133* result.depth == R1.z134* When the fragprog contains instructions to write depth, NV30_TCL_PRIMITIVE_3D_UNK1D78=0135* otherwise it is set to 1.136*137* Constants are inserted directly after the instruction that uses them.138*139* It appears that it's not possible to use two input registers in one140* instruction as the input sourcing is done in the instruction dword141* and not the source selection dwords. As such instructions such as:142*143* ADD result.color, fragment.color, fragment.texcoord[0];144*145* must be split into two MOV's and then an ADD (nvidia does this) but146* I'm not sure why it's not just one MOV and then source the second input147* in the ADD instruction..148*149* Negation of the full source is done with NV30_FP_REG_NEGATE, arbitrary150* negation requires multiplication with a const.151*152* Arbitrary swizzling is supported with the exception of SWIZZLE_ZERO/SWIZZLE_ONE153* The temp/result regs appear to be initialised to (0.0, 0.0, 0.0, 0.0) as SWIZZLE_ZERO154* is implemented simply by not writing to the relevant components of the destination.155*156* Conditional execution157* TODO158*159* Non-native instructions:160* LIT161* LRP - MAD+MAD162* SUB - ADD, negate second source163* RSQ - LG2 + EX2164* POW - LG2 + MUL + EX2165*166* NV40 Looping167* Loops appear to be fairly expensive on NV40 at least, the proprietary168* driver goes to a lot of effort to avoid using the native looping169* instructions. If the total number of *executed* instructions between170* REP/ENDREP or LOOP/ENDLOOP is <=500, the driver will unroll the loop.171* The maximum loop count is 255.172*173*/174175//== Opcode / Destination selection ==176#define NVFX_FP_OP_PROGRAM_END (1 << 0)177#define NVFX_FP_OP_OUT_REG_SHIFT 1178#define NV30_FP_OP_OUT_REG_MASK (31 << 1) /* uncertain */179#define NV40_FP_OP_OUT_REG_MASK (63 << 1)180/* Needs to be set when writing outputs to get expected result.. */181#define NVFX_FP_OP_OUT_REG_HALF (1 << 7)182#define NVFX_FP_OP_COND_WRITE_ENABLE (1 << 8)183#define NVFX_FP_OP_OUTMASK_SHIFT 9184#define NVFX_FP_OP_OUTMASK_MASK (0xF << 9)185# define NVFX_FP_OP_OUT_X (1<<9)186# define NVFX_FP_OP_OUT_Y (1<<10)187# define NVFX_FP_OP_OUT_Z (1<<11)188# define NVFX_FP_OP_OUT_W (1<<12)189/* Uncertain about these, especially the input_src values.. it's possible that190* they can be dynamically changed.191*/192#define NVFX_FP_OP_INPUT_SRC_SHIFT 13193#define NVFX_FP_OP_INPUT_SRC_MASK (15 << 13)194# define NVFX_FP_OP_INPUT_SRC_POSITION 0x0195# define NVFX_FP_OP_INPUT_SRC_COL0 0x1196# define NVFX_FP_OP_INPUT_SRC_COL1 0x2197# define NVFX_FP_OP_INPUT_SRC_FOGC 0x3198# define NVFX_FP_OP_INPUT_SRC_TC0 0x4199# define NVFX_FP_OP_INPUT_SRC_TC(n) (0x4 + n)200# define NV40_FP_OP_INPUT_SRC_FACING 0xE201#define NVFX_FP_OP_TEX_UNIT_SHIFT 17202#define NVFX_FP_OP_TEX_UNIT_MASK (0xF << 17) /* guess */203#define NVFX_FP_OP_PRECISION_SHIFT 22204#define NVFX_FP_OP_PRECISION_MASK (3 << 22)205# define NVFX_FP_PRECISION_FP32 0206# define NVFX_FP_PRECISION_FP16 1207# define NVFX_FP_PRECISION_FX12 2208#define NVFX_FP_OP_OPCODE_SHIFT 24209#define NVFX_FP_OP_OPCODE_MASK (0x3F << 24)210/* NV30/NV40 fragment program opcodes */211#define NVFX_FP_OP_OPCODE_NOP 0x00212#define NVFX_FP_OP_OPCODE_MOV 0x01213#define NVFX_FP_OP_OPCODE_MUL 0x02214#define NVFX_FP_OP_OPCODE_ADD 0x03215#define NVFX_FP_OP_OPCODE_MAD 0x04216#define NVFX_FP_OP_OPCODE_DP3 0x05217#define NVFX_FP_OP_OPCODE_DP4 0x06218#define NVFX_FP_OP_OPCODE_DST 0x07219#define NVFX_FP_OP_OPCODE_MIN 0x08220#define NVFX_FP_OP_OPCODE_MAX 0x09221#define NVFX_FP_OP_OPCODE_SLT 0x0A222#define NVFX_FP_OP_OPCODE_SGE 0x0B223#define NVFX_FP_OP_OPCODE_SLE 0x0C224#define NVFX_FP_OP_OPCODE_SGT 0x0D225#define NVFX_FP_OP_OPCODE_SNE 0x0E226#define NVFX_FP_OP_OPCODE_SEQ 0x0F227#define NVFX_FP_OP_OPCODE_FRC 0x10228#define NVFX_FP_OP_OPCODE_FLR 0x11229#define NVFX_FP_OP_OPCODE_KIL 0x12230#define NVFX_FP_OP_OPCODE_PK4B 0x13231#define NVFX_FP_OP_OPCODE_UP4B 0x14232#define NVFX_FP_OP_OPCODE_DDX 0x15 /* can only write XY */233#define NVFX_FP_OP_OPCODE_DDY 0x16 /* can only write XY */234#define NVFX_FP_OP_OPCODE_TEX 0x17235#define NVFX_FP_OP_OPCODE_TXP 0x18236#define NVFX_FP_OP_OPCODE_TXD 0x19237#define NVFX_FP_OP_OPCODE_RCP 0x1A238#define NVFX_FP_OP_OPCODE_EX2 0x1C239#define NVFX_FP_OP_OPCODE_LG2 0x1D240#define NVFX_FP_OP_OPCODE_STR 0x20241#define NVFX_FP_OP_OPCODE_SFL 0x21242#define NVFX_FP_OP_OPCODE_COS 0x22243#define NVFX_FP_OP_OPCODE_SIN 0x23244#define NVFX_FP_OP_OPCODE_PK2H 0x24245#define NVFX_FP_OP_OPCODE_UP2H 0x25246#define NVFX_FP_OP_OPCODE_PK4UB 0x27247#define NVFX_FP_OP_OPCODE_UP4UB 0x28248#define NVFX_FP_OP_OPCODE_PK2US 0x29249#define NVFX_FP_OP_OPCODE_UP2US 0x2A250#define NVFX_FP_OP_OPCODE_DP2A 0x2E251#define NVFX_FP_OP_OPCODE_TXB 0x31252#define NVFX_FP_OP_OPCODE_DIV 0x3A253254/* NV30 only fragment program opcodes */255#define NVFX_FP_OP_OPCODE_RSQ_NV30 0x1B256#define NVFX_FP_OP_OPCODE_LIT_NV30 0x1E257#define NVFX_FP_OP_OPCODE_LRP_NV30 0x1F258#define NVFX_FP_OP_OPCODE_POW_NV30 0x26259#define NVFX_FP_OP_OPCODE_RFL_NV30 0x36260261/* NV40 only fragment program opcodes */262#define NVFX_FP_OP_OPCODE_TXL_NV40 0x2F263#define NVFX_FP_OP_OPCODE_LITEX2_NV40 0x3C264265/* The use of these instructions appears to be indicated by bit 31 of DWORD 2.*/266#define NV40_FP_OP_BRA_OPCODE_BRK 0x0267#define NV40_FP_OP_BRA_OPCODE_CAL 0x1268#define NV40_FP_OP_BRA_OPCODE_IF 0x2269#define NV40_FP_OP_BRA_OPCODE_LOOP 0x3270#define NV40_FP_OP_BRA_OPCODE_REP 0x4271#define NV40_FP_OP_BRA_OPCODE_RET 0x5272273#define NV40_FP_OP_OUT_NONE (1 << 30)274#define NVFX_FP_OP_OUT_SAT (1 << 31)275276/* high order bits of SRC0 */277#define NVFX_FP_OP_SRC0_ABS (1 << 29)278#define NVFX_FP_OP_COND_SWZ_W_SHIFT 27279#define NVFX_FP_OP_COND_SWZ_W_MASK (3 << 27)280#define NVFX_FP_OP_COND_SWZ_Z_SHIFT 25281#define NVFX_FP_OP_COND_SWZ_Z_MASK (3 << 25)282#define NVFX_FP_OP_COND_SWZ_Y_SHIFT 23283#define NVFX_FP_OP_COND_SWZ_Y_MASK (3 << 23)284#define NVFX_FP_OP_COND_SWZ_X_SHIFT 21285#define NVFX_FP_OP_COND_SWZ_X_MASK (3 << 21)286#define NVFX_FP_OP_COND_SWZ_ALL_SHIFT 21287#define NVFX_FP_OP_COND_SWZ_ALL_MASK (0xFF << 21)288#define NVFX_FP_OP_COND_SHIFT 18289#define NVFX_FP_OP_COND_MASK (0x07 << 18)290# define NVFX_FP_OP_COND_FL 0291# define NVFX_FP_OP_COND_LT 1292# define NVFX_FP_OP_COND_EQ 2293# define NVFX_FP_OP_COND_LE 3294# define NVFX_FP_OP_COND_GT 4295# define NVFX_FP_OP_COND_NE 5296# define NVFX_FP_OP_COND_GE 6297# define NVFX_FP_OP_COND_TR 7298299/* high order bits of SRC1 */300#define NV40_FP_OP_OPCODE_IS_BRANCH (1<<31)301#define NVFX_FP_OP_DST_SCALE_SHIFT 28302#define NVFX_FP_OP_DST_SCALE_MASK (3 << 28)303#define NVFX_FP_OP_DST_SCALE_1X 0304#define NVFX_FP_OP_DST_SCALE_2X 1305#define NVFX_FP_OP_DST_SCALE_4X 2306#define NVFX_FP_OP_DST_SCALE_8X 3307#define NVFX_FP_OP_DST_SCALE_INV_2X 5308#define NVFX_FP_OP_DST_SCALE_INV_4X 6309#define NVFX_FP_OP_DST_SCALE_INV_8X 7310#define NVFX_FP_OP_SRC1_ABS (1 << 18)311312/* SRC1 LOOP */313#define NV40_FP_OP_LOOP_INCR_SHIFT 19314#define NV40_FP_OP_LOOP_INCR_MASK (0xFF << 19)315#define NV40_FP_OP_LOOP_INDEX_SHIFT 10316#define NV40_FP_OP_LOOP_INDEX_MASK (0xFF << 10)317#define NV40_FP_OP_LOOP_COUNT_SHIFT 2318#define NV40_FP_OP_LOOP_COUNT_MASK (0xFF << 2)319320/* SRC1 IF: absolute offset in dwords */321#define NV40_FP_OP_ELSE_OFFSET_SHIFT 0322#define NV40_FP_OP_ELSE_OFFSET_MASK (0x7FFFFFFF << 0)323324/* SRC1 CAL */325#define NV40_FP_OP_SUB_OFFSET_SHIFT 0326#define NV40_FP_OP_SUB_OFFSET_MASK (0x7FFFFFFF << 0)327328/* SRC1 REP329* I have no idea why there are 3 count values here.. but they330* have always been filled with the same value in my tests so331* far..332*/333#define NV40_FP_OP_REP_COUNT1_SHIFT 2334#define NV40_FP_OP_REP_COUNT1_MASK (0xFF << 2)335#define NV40_FP_OP_REP_COUNT2_SHIFT 10336#define NV40_FP_OP_REP_COUNT2_MASK (0xFF << 10)337#define NV40_FP_OP_REP_COUNT3_SHIFT 19338#define NV40_FP_OP_REP_COUNT3_MASK (0xFF << 19)339340/* SRC2 REP/IF: absolute offset in dwords */341#define NV40_FP_OP_END_OFFSET_SHIFT 0342#define NV40_FP_OP_END_OFFSET_MASK (0x7FFFFFFF << 0)343344/* high order bits of SRC2 */345#define NVFX_FP_OP_INDEX_INPUT (1 << 30)346#define NV40_FP_OP_ADDR_INDEX_SHIFT 19347#define NV40_FP_OP_ADDR_INDEX_MASK (0xF << 19)348349//== Register selection ==350#define NVFX_FP_REG_TYPE_SHIFT 0351#define NVFX_FP_REG_TYPE_MASK (3 << 0)352# define NVFX_FP_REG_TYPE_TEMP 0353# define NVFX_FP_REG_TYPE_INPUT 1354# define NVFX_FP_REG_TYPE_CONST 2355#define NVFX_FP_REG_SRC_SHIFT 2356#define NV30_FP_REG_SRC_MASK (31 << 2)357#define NV40_FP_REG_SRC_MASK (63 << 2)358#define NVFX_FP_REG_SRC_HALF (1 << 8)359#define NVFX_FP_REG_SWZ_ALL_SHIFT 9360#define NVFX_FP_REG_SWZ_ALL_MASK (255 << 9)361#define NVFX_FP_REG_SWZ_X_SHIFT 9362#define NVFX_FP_REG_SWZ_X_MASK (3 << 9)363#define NVFX_FP_REG_SWZ_Y_SHIFT 11364#define NVFX_FP_REG_SWZ_Y_MASK (3 << 11)365#define NVFX_FP_REG_SWZ_Z_SHIFT 13366#define NVFX_FP_REG_SWZ_Z_MASK (3 << 13)367#define NVFX_FP_REG_SWZ_W_SHIFT 15368#define NVFX_FP_REG_SWZ_W_MASK (3 << 15)369# define NVFX_FP_SWIZZLE_X 0370# define NVFX_FP_SWIZZLE_Y 1371# define NVFX_FP_SWIZZLE_Z 2372# define NVFX_FP_SWIZZLE_W 3373#define NVFX_FP_REG_NEGATE (1 << 17)374375#define NVFXSR_NONE 0376#define NVFXSR_OUTPUT 1377#define NVFXSR_INPUT 2378#define NVFXSR_TEMP 3379#define NVFXSR_CONST 5380#define NVFXSR_IMM 6381382#define NVFX_COND_FL 0383#define NVFX_COND_LT 1384#define NVFX_COND_EQ 2385#define NVFX_COND_LE 3386#define NVFX_COND_GT 4387#define NVFX_COND_NE 5388#define NVFX_COND_GE 6389#define NVFX_COND_TR 7390391/* Yes, this are ordered differently... */392393#define NVFX_VP_MASK_X 8394#define NVFX_VP_MASK_Y 4395#define NVFX_VP_MASK_Z 2396#define NVFX_VP_MASK_W 1397#define NVFX_VP_MASK_ALL 0xf398399#define NVFX_FP_MASK_X 1400#define NVFX_FP_MASK_Y 2401#define NVFX_FP_MASK_Z 4402#define NVFX_FP_MASK_W 8403#define NVFX_FP_MASK_ALL 0xf404405#define NVFX_SWZ_X 0406#define NVFX_SWZ_Y 1407#define NVFX_SWZ_Z 2408#define NVFX_SWZ_W 3409410#define swz(s,x,y,z,w) nvfx_src_swz((s), NVFX_SWZ_##x, NVFX_SWZ_##y, NVFX_SWZ_##z, NVFX_SWZ_##w)411#define neg(s) nvfx_src_neg((s))412#define abs(s) nvfx_src_abs((s))413414struct nvfx_reg {415int8_t type;416int32_t index;417};418419struct nvfx_src {420struct nvfx_reg reg;421422uint8_t indirect : 1;423uint8_t indirect_reg : 1;424uint8_t indirect_swz : 2;425uint8_t negate : 1;426uint8_t abs : 1;427uint8_t swz[4];428};429430struct nvfx_insn431{432uint8_t op;433char scale;434int8_t unit;435uint8_t mask;436uint8_t cc_swz[4];437438uint8_t sat : 1;439uint8_t cc_update : 1;440uint8_t cc_update_reg : 1;441uint8_t cc_test : 3;442uint8_t cc_test_reg : 1;443444struct nvfx_reg dst;445struct nvfx_src src[3];446};447448static inline struct nvfx_insn449nvfx_insn(bool sat, unsigned op, int unit, struct nvfx_reg dst, unsigned mask, struct nvfx_src s0, struct nvfx_src s1, struct nvfx_src s2)450{451struct nvfx_insn insn = {452.op = op,453.scale = 0,454.unit = unit,455.sat = sat,456.mask = mask,457.cc_update = 0,458.cc_update_reg = 0,459.cc_test = NVFX_COND_TR,460.cc_test_reg = 0,461.cc_swz = { 0, 1, 2, 3 },462.dst = dst,463.src = {s0, s1, s2}464};465return insn;466}467468static inline struct nvfx_reg469nvfx_reg(int type, int index)470{471struct nvfx_reg temp = {472.type = type,473.index = index,474};475return temp;476}477478static inline struct nvfx_src479nvfx_src(struct nvfx_reg reg)480{481struct nvfx_src temp = {482.reg = reg,483.abs = 0,484.negate = 0,485.swz = { 0, 1, 2, 3 },486.indirect = 0,487};488return temp;489}490491static inline struct nvfx_src492nvfx_src_swz(struct nvfx_src src, int x, int y, int z, int w)493{494struct nvfx_src dst = src;495496dst.swz[NVFX_SWZ_X] = src.swz[x];497dst.swz[NVFX_SWZ_Y] = src.swz[y];498dst.swz[NVFX_SWZ_Z] = src.swz[z];499dst.swz[NVFX_SWZ_W] = src.swz[w];500return dst;501}502503static inline struct nvfx_src504nvfx_src_neg(struct nvfx_src src)505{506src.negate = !src.negate;507return src;508}509510static inline struct nvfx_src511nvfx_src_abs(struct nvfx_src src)512{513src.abs = 1;514return src;515}516517struct nvfx_relocation {518unsigned location;519unsigned target;520};521522struct nv30_fragprog;523struct nv30_vertprog;524525//XXX: needed to make it build, clean this up!526void527_nvfx_fragprog_translate(uint16_t oclass, struct nv30_fragprog *fp);528529bool530_nvfx_vertprog_translate(uint16_t oclass, struct nv30_vertprog *vp);531532#endif533534535