#include #include "glheader.h" #include "macros.h" #include "nouveau_context.h" #include "nouveau_fifo.h" #include "nouveau_reg.h" #include "nouveau_drm.h" #include "nouveau_shader.h" #include "nouveau_object.h" #include "nouveau_msg.h" #include "nouveau_bufferobj.h" #include "nv30_shader.h" unsigned int NVFP_TX_AOP_COUNT = 64; struct _op_xlat NVFP_TX_AOP[64]; /******************************************************************************* * Support routines */ static void NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); nvsCardPriv *priv = &nvs->card_priv; uint32_t offset; if (!nvs->program_buffer) nvs->program_buffer = ctx->Driver.NewBufferObject(ctx, 0, GL_ARRAY_BUFFER_ARB); /* Should use STATIC_DRAW_ARB if shader doesn't use changable params */ nouveau_bo_init_storage(ctx, NOUVEAU_BO_VRAM_OK, nvs->program_size * sizeof(uint32_t), (const GLvoid *)nvs->program, GL_DYNAMIC_DRAW_ARB, nvs->program_buffer); offset = nouveau_bo_gpu_ref(ctx, nvs->program_buffer); /* Not using state cache here, updated programs at the same address don't * seem to take effect unless the ACTIVE_PROGRAM method is called again. * HW caches the program somewhere? */ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM, 1); OUT_RING (offset | 1); if (nmesa->screen->card->type == NV_30) { BEGIN_RING_SIZE(NvSub3D, 0x1d60 /*NV30_TCL_PRIMITIVE_3D_FP_CONTROL*/, 1); OUT_RING ((priv->NV30FP.uses_kil << 7)); BEGIN_RING_SIZE(NvSub3D, 0x1450, 1); OUT_RING (priv->NV30FP.num_regs << 16); } else { BEGIN_RING_SIZE(NvSub3D, 0x1d60 /*NV30_TCL_PRIMITIVE_3D_FP_CONTROL*/, 1); OUT_RING ((priv->NV30FP.uses_kil << 7) | (priv->NV30FP.num_regs << 24)); } } static void NV30FPUpdateConst(GLcontext *ctx, nouveauShader *nvs, int id) { uint32_t *new = nvs->params[id].source_val ? (uint32_t*)nvs->params[id].source_val : (uint32_t*)nvs->params[id].val; uint32_t *current; int i; for (i=0; iparams[id].hw_index_cnt; i++) { current = nvs->program + nvs->params[id].hw_index[i]; COPY_4V(current, new); } nvs->on_hardware = 0; } /******************************************************************************* * Assembly helpers */ static struct _op_xlat * NV30FPGetOPTXFromSOP(nvsOpcode op, int *id) { int i; for (i=0; iGetOPTXFromSOP(op, NULL)) return 1; return 0; } static void NV30FPSetOpcode(nvsFunc *shader, unsigned int opcode, int slot) { if (opcode == NV30_FP_OP_OPCODE_KIL) shader->card_priv->NV30FP.uses_kil = GL_TRUE; shader->inst[0] &= ~NV30_FP_OP_OPCODE_MASK; shader->inst[0] |= (opcode << NV30_FP_OP_OPCODE_SHIFT); } static void NV30FPSetCCUpdate(nvsFunc *shader) { shader->inst[0] |= NV30_FP_OP_COND_WRITE_ENABLE; } static void NV30FPSetCondition(nvsFunc *shader, int on, nvsCond cond, int reg, nvsSwzComp *swz) { nvsSwzComp default_swz[4] = { NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W }; unsigned int hwcond; /* cond masking is always enabled */ if (!on) { cond = NVS_COND_TR; reg = 0; swz = default_swz; } switch (cond) { case NVS_COND_TR: hwcond = NV30_FP_OP_COND_TR; break; case NVS_COND_FL: hwcond = NV30_FP_OP_COND_FL; break; case NVS_COND_LT: hwcond = NV30_FP_OP_COND_LT; break; case NVS_COND_GT: hwcond = NV30_FP_OP_COND_GT; break; case NVS_COND_LE: hwcond = NV30_FP_OP_COND_LE; break; case NVS_COND_GE: hwcond = NV30_FP_OP_COND_GE; break; case NVS_COND_EQ: hwcond = NV30_FP_OP_COND_EQ; break; case NVS_COND_NE: hwcond = NV30_FP_OP_COND_NE; break; default: WARN_ONCE("unknown fp condmask=%d\n", cond); hwcond = NV30_FP_OP_COND_TR; break; } shader->inst[1] &= ~NV30_FP_OP_COND_MASK; shader->inst[1] |= (hwcond << NV30_FP_OP_COND_SHIFT); shader->inst[1] &= ~NV30_FP_OP_COND_SWZ_ALL_MASK; shader->inst[1] |= (swz[NVS_SWZ_X] << NV30_FP_OP_COND_SWZ_X_SHIFT); shader->inst[1] |= (swz[NVS_SWZ_Y] << NV30_FP_OP_COND_SWZ_Y_SHIFT); shader->inst[1] |= (swz[NVS_SWZ_Z] << NV30_FP_OP_COND_SWZ_Z_SHIFT); shader->inst[1] |= (swz[NVS_SWZ_W] << NV30_FP_OP_COND_SWZ_W_SHIFT); } static void NV30FPSetHighReg(nvsFunc *shader, int id) { if (shader->card_priv->NV30FP.num_regs < (id+1)) { if (id == 0) id = 1; /* necessary? */ shader->card_priv->NV30FP.num_regs = (id+1); } } static void NV30FPSetResult(nvsFunc *shader, nvsRegister *reg, unsigned int mask, int slot) { unsigned int hwreg; if (mask & SMASK_X) shader->inst[0] |= NV30_FP_OP_OUT_X; if (mask & SMASK_Y) shader->inst[0] |= NV30_FP_OP_OUT_Y; if (mask & SMASK_Z) shader->inst[0] |= NV30_FP_OP_OUT_Z; if (mask & SMASK_W) shader->inst[0] |= NV30_FP_OP_OUT_W; if (reg->file == NVS_FILE_RESULT) { hwreg = 0; /* FIXME: this is only fragment.color */ /* This is *not* correct, I have no idea what it is either */ shader->inst[0] |= NV30_FP_OP_UNK0_7; } else { shader->inst[0] &= ~NV30_FP_OP_UNK0_7; hwreg = reg->index; } NV30FPSetHighReg(shader, hwreg); shader->inst[0] &= ~NV30_FP_OP_OUT_REG_SHIFT; shader->inst[0] |= (hwreg << NV30_FP_OP_OUT_REG_SHIFT); } static void NV30FPSetSource(nvsFunc *shader, nvsRegister *reg, int pos) { unsigned int hwsrc = 0; switch (reg->file) { case NVS_FILE_TEMP: hwsrc |= (NV30_FP_REG_TYPE_TEMP << NV30_FP_REG_TYPE_SHIFT); hwsrc |= (reg->index << NV30_FP_REG_SRC_SHIFT); NV30FPSetHighReg(shader, reg->index); break; case NVS_FILE_ATTRIB: { unsigned int hwin; switch (reg->index) { case NVS_FR_POSITION : hwin = NV30_FP_OP_INPUT_SRC_POSITION; break; case NVS_FR_COL0 : hwin = NV30_FP_OP_INPUT_SRC_COL0; break; case NVS_FR_COL1 : hwin = NV30_FP_OP_INPUT_SRC_COL1; break; case NVS_FR_FOGCOORD : hwin = NV30_FP_OP_INPUT_SRC_FOGC; break; case NVS_FR_TEXCOORD0: hwin = NV30_FP_OP_INPUT_SRC_TC(0); break; case NVS_FR_TEXCOORD1: hwin = NV30_FP_OP_INPUT_SRC_TC(1); break; case NVS_FR_TEXCOORD2: hwin = NV30_FP_OP_INPUT_SRC_TC(2); break; case NVS_FR_TEXCOORD3: hwin = NV30_FP_OP_INPUT_SRC_TC(3); break; case NVS_FR_TEXCOORD4: hwin = NV30_FP_OP_INPUT_SRC_TC(4); break; case NVS_FR_TEXCOORD5: hwin = NV30_FP_OP_INPUT_SRC_TC(5); break; case NVS_FR_TEXCOORD6: hwin = NV30_FP_OP_INPUT_SRC_TC(6); break; case NVS_FR_TEXCOORD7: hwin = NV30_FP_OP_INPUT_SRC_TC(7); break; default: WARN_ONCE("unknown fp input %d\n", reg->index); hwin = NV30_FP_OP_INPUT_SRC_COL0; break; } shader->inst[0] &= ~NV30_FP_OP_INPUT_SRC_MASK; shader->inst[0] |= (hwin << NV30_FP_OP_INPUT_SRC_SHIFT); hwsrc |= (hwin << NV30_FP_REG_SRC_SHIFT); } hwsrc |= (NV30_FP_REG_TYPE_INPUT << NV30_FP_REG_TYPE_SHIFT); break; case NVS_FILE_CONST: /* consts are inlined after the inst */ hwsrc |= (NV30_FP_REG_TYPE_CONST << NV30_FP_REG_TYPE_SHIFT); break; default: assert(0); break; } if (reg->negate) hwsrc |= NV30_FP_REG_NEGATE; if (reg->abs) shader->inst[1] |= (1 << (29+pos)); hwsrc |= (reg->swizzle[NVS_SWZ_X] << NV30_FP_REG_SWZ_X_SHIFT); hwsrc |= (reg->swizzle[NVS_SWZ_Y] << NV30_FP_REG_SWZ_Y_SHIFT); hwsrc |= (reg->swizzle[NVS_SWZ_Z] << NV30_FP_REG_SWZ_Z_SHIFT); hwsrc |= (reg->swizzle[NVS_SWZ_W] << NV30_FP_REG_SWZ_W_SHIFT); shader->inst[pos+1] &= ~NV30_FP_REG_ALL_MASK; shader->inst[pos+1] |= hwsrc; } static void NV30FPSetTexImageUnit(nvsFunc *shader, int unit) { shader->inst[0] &= ~NV30_FP_OP_TEX_UNIT_SHIFT; shader->inst[0] |= (unit << NV30_FP_OP_TEX_UNIT_SHIFT); } static void NV30FPSetSaturate(nvsFunc *shader) { shader->inst[0] |= NV30_FP_OP_OUT_SAT; } static void NV30FPInitInstruction(nvsFunc *shader) { unsigned int hwsrc; shader->inst[0] = 0; hwsrc = (NV30_FP_REG_TYPE_INPUT << NV30_FP_REG_TYPE_SHIFT) | (NVS_SWZ_X << NV30_FP_REG_SWZ_X_SHIFT) | (NVS_SWZ_Y << NV30_FP_REG_SWZ_Y_SHIFT) | (NVS_SWZ_Z << NV30_FP_REG_SWZ_Z_SHIFT) | (NVS_SWZ_W << NV30_FP_REG_SWZ_W_SHIFT); shader->inst[1] = hwsrc; shader->inst[2] = hwsrc; shader->inst[3] = hwsrc; } static void NV30FPSetLastInst(nvsFunc *shader) { shader->inst[0] |= 1; } /******************************************************************************* * Disassembly helpers */ static struct _op_xlat * NV30FPGetOPTXRec(nvsFunc * shader, int merged) { int op; op = shader->GetOpcodeHW(shader, 0); if (op > NVFP_TX_AOP_COUNT) return NULL; if (NVFP_TX_AOP[op].SOP == NVS_OP_UNKNOWN) return NULL; return &NVFP_TX_AOP[op]; } static int NV30FPHasMergedInst(nvsFunc * shader) { return 0; } static int NV30FPIsLastInst(nvsFunc * shader) { return ((shader->inst[0] & NV30_FP_OP_PROGRAM_END) ? 1 : 0); } static int NV30FPGetOffsetNext(nvsFunc * shader) { int i; for (i = 0; i < 3; i++) if (shader->GetSourceFile(shader, 0, i) == NVS_FILE_CONST) return 8; return 4; } static nvsOpcode NV30FPGetOpcode(nvsFunc * shader, int merged) { struct _op_xlat *opr; opr = shader->GetOPTXRec(shader, merged); if (!opr) return NVS_OP_UNKNOWN; return opr->SOP; } static unsigned int NV30FPGetOpcodeHW(nvsFunc * shader, int slot) { int op; op = (shader->inst[0] & NV30_FP_OP_OPCODE_MASK) >> NV30_FP_OP_OPCODE_SHIFT; return op; } static nvsRegFile NV30FPGetDestFile(nvsFunc * shader, int merged) { /* Result regs overlap temporary regs */ return NVS_FILE_TEMP; } static unsigned int NV30FPGetDestID(nvsFunc * shader, int merged) { int id; switch (shader->GetDestFile(shader, merged)) { case NVS_FILE_TEMP: id = ((shader->inst[0] & NV30_FP_OP_OUT_REG_MASK) >> NV30_FP_OP_OUT_REG_SHIFT); return id; default: return -1; } } static unsigned int NV30FPGetDestMask(nvsFunc * shader, int merged) { unsigned int mask = 0; if (shader->inst[0] & NV30_FP_OP_OUT_X) mask |= SMASK_X; if (shader->inst[0] & NV30_FP_OP_OUT_Y) mask |= SMASK_Y; if (shader->inst[0] & NV30_FP_OP_OUT_Z) mask |= SMASK_Z; if (shader->inst[0] & NV30_FP_OP_OUT_W) mask |= SMASK_W; return mask; } static unsigned int NV30FPGetSourceHW(nvsFunc * shader, int merged, int pos) { struct _op_xlat *opr; opr = shader->GetOPTXRec(shader, merged); if (!opr || opr->srcpos[pos] == -1) return -1; return shader->inst[opr->srcpos[pos] + 1]; } static nvsRegFile NV30FPGetSourceFile(nvsFunc * shader, int merged, int pos) { unsigned int src; struct _op_xlat *opr; int file; opr = shader->GetOPTXRec(shader, merged); if (!opr || opr->srcpos[pos] == -1) return NVS_FILE_UNKNOWN; switch (opr->srcpos[pos]) { case SPOS_ADDRESS: return NVS_FILE_ADDRESS; default: src = shader->GetSourceHW(shader, merged, pos); file = (src & NV30_FP_REG_TYPE_MASK) >> NV30_FP_REG_TYPE_SHIFT; switch (file) { case NV30_FP_REG_TYPE_TEMP : return NVS_FILE_TEMP; case NV30_FP_REG_TYPE_INPUT: return NVS_FILE_ATTRIB; case NV30_FP_REG_TYPE_CONST: return NVS_FILE_CONST; default: return NVS_FILE_UNKNOWN; } } } static int NV30FPGetSourceID(nvsFunc * shader, int merged, int pos) { switch (shader->GetSourceFile(shader, merged, pos)) { case NVS_FILE_ATTRIB: switch ((shader->inst[0] & NV30_FP_OP_INPUT_SRC_MASK) >> NV30_FP_OP_INPUT_SRC_SHIFT) { case NV30_FP_OP_INPUT_SRC_POSITION: return NVS_FR_POSITION; case NV30_FP_OP_INPUT_SRC_COL0 : return NVS_FR_COL0; case NV30_FP_OP_INPUT_SRC_COL1 : return NVS_FR_COL1; case NV30_FP_OP_INPUT_SRC_FOGC : return NVS_FR_FOGCOORD; case NV30_FP_OP_INPUT_SRC_TC(0) : return NVS_FR_TEXCOORD0; case NV30_FP_OP_INPUT_SRC_TC(1) : return NVS_FR_TEXCOORD1; case NV30_FP_OP_INPUT_SRC_TC(2) : return NVS_FR_TEXCOORD2; case NV30_FP_OP_INPUT_SRC_TC(3) : return NVS_FR_TEXCOORD3; case NV30_FP_OP_INPUT_SRC_TC(4) : return NVS_FR_TEXCOORD4; case NV30_FP_OP_INPUT_SRC_TC(5) : return NVS_FR_TEXCOORD5; case NV30_FP_OP_INPUT_SRC_TC(6) : return NVS_FR_TEXCOORD6; case NV30_FP_OP_INPUT_SRC_TC(7) : return NVS_FR_TEXCOORD7; default: return -1; } break; case NVS_FILE_TEMP: { unsigned int src; src = shader->GetSourceHW(shader, merged, pos); return ((src & NV30_FP_REG_SRC_MASK) >> NV30_FP_REG_SRC_SHIFT); } case NVS_FILE_CONST: /* inlined into fragprog */ default: return -1; } } static int NV30FPGetTexImageUnit(nvsFunc *shader) { return ((shader->inst[0] & NV30_FP_OP_TEX_UNIT_MASK) >> NV30_FP_OP_TEX_UNIT_SHIFT); } static int NV30FPGetSourceNegate(nvsFunc * shader, int merged, int pos) { unsigned int src; src = shader->GetSourceHW(shader, merged, pos); if (src == -1) return -1; return ((src & NV30_FP_REG_NEGATE) ? 1 : 0); } static int NV30FPGetSourceAbs(nvsFunc * shader, int merged, int pos) { struct _op_xlat *opr; static unsigned int abspos[3] = { NV30_FP_OP_OUT_ABS, (1 << 30), /* guess */ (1 << 31) /* guess */ }; opr = shader->GetOPTXRec(shader, merged); if (!opr || opr->srcpos[pos] == -1) return -1; return ((shader->inst[1] & abspos[opr->srcpos[pos]]) ? 1 : 0); } nvsSwzComp NV30FP_TX_SWIZZLE[4] = {NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W }; static void NV30FPTXSwizzle(int hwswz, nvsSwzComp *swz) { swz[NVS_SWZ_W] = NV30FP_TX_SWIZZLE[(hwswz & 0xC0) >> 6]; swz[NVS_SWZ_Z] = NV30FP_TX_SWIZZLE[(hwswz & 0x30) >> 4]; swz[NVS_SWZ_Y] = NV30FP_TX_SWIZZLE[(hwswz & 0x0C) >> 2]; swz[NVS_SWZ_X] = NV30FP_TX_SWIZZLE[(hwswz & 0x03) >> 0]; } static void NV30FPGetSourceSwizzle(nvsFunc * shader, int merged, int pos, nvsSwzComp *swz) { unsigned int src; int swzbits; src = shader->GetSourceHW(shader, merged, pos); swzbits = (src & NV30_FP_REG_SWZ_ALL_MASK) >> NV30_FP_REG_SWZ_ALL_SHIFT; NV30FPTXSwizzle(swzbits, swz); } static int NV30FPGetSourceIndexed(nvsFunc * shader, int merged, int pos) { switch (shader->GetSourceFile(shader, merged, pos)) { case NVS_FILE_ATTRIB: return ((shader->inst[3] & NV30_FP_OP_INDEX_INPUT) ? 1 : 0); default: return 0; } } static void NV30FPGetSourceConstVal(nvsFunc * shader, int merged, int pos, float *val) { val[0] = *(float *) &(shader->inst[4]); val[1] = *(float *) &(shader->inst[5]); val[2] = *(float *) &(shader->inst[6]); val[3] = *(float *) &(shader->inst[7]); } static int NV30FPGetSourceScale(nvsFunc * shader, int merged, int pos) { /*FIXME: is this per-source, only for a specific source, or all sources??*/ return (1 << ((shader->inst[2] & NV30_FP_OP_SRC_SCALE_MASK) >> NV30_FP_OP_SRC_SCALE_SHIFT)); } static int NV30FPGetAddressRegID(nvsFunc * shader) { return 0; } static nvsSwzComp NV30FPGetAddressRegSwizzle(nvsFunc * shader) { return NVS_SWZ_X; } static int NV30FPSupportsConditional(nvsFunc * shader) { /*FIXME: Is this true of all ops? */ return 1; } static int NV30FPGetConditionUpdate(nvsFunc * shader) { return ((shader->inst[0] & NV30_FP_OP_COND_WRITE_ENABLE) ? 1 : 0); } static int NV30FPGetConditionTest(nvsFunc * shader) { /*FIXME: always? */ return 1; } static nvsCond NV30FPGetCondition(nvsFunc * shader) { int cond; cond = ((shader->inst[1] & NV30_FP_OP_COND_MASK) >> NV30_FP_OP_COND_SHIFT); switch (cond) { case NV30_FP_OP_COND_FL: return NVS_COND_FL; case NV30_FP_OP_COND_LT: return NVS_COND_LT; case NV30_FP_OP_COND_EQ: return NVS_COND_EQ; case NV30_FP_OP_COND_LE: return NVS_COND_LE; case NV30_FP_OP_COND_GT: return NVS_COND_GT; case NV30_FP_OP_COND_NE: return NVS_COND_NE; case NV30_FP_OP_COND_GE: return NVS_COND_GE; case NV30_FP_OP_COND_TR: return NVS_COND_TR; default: return NVS_COND_UNKNOWN; } } static void NV30FPGetCondRegSwizzle(nvsFunc * shader, nvsSwzComp *swz) { int swzbits; swzbits = (shader->inst[1] & NV30_FP_OP_COND_SWZ_ALL_MASK) >> NV30_FP_OP_COND_SWZ_ALL_SHIFT; NV30FPTXSwizzle(swzbits, swz); } static int NV30FPGetCondRegID(nvsFunc * shader) { return 0; } static nvsPrecision NV30FPGetPrecision(nvsFunc * shader) { int p; p = (shader->inst[0] & NV30_FP_OP_PRECISION_MASK) >> NV30_FP_OP_PRECISION_SHIFT; switch (p) { case NV30_FP_PRECISION_FP32: return NVS_PREC_FLOAT32; case NV30_FP_PRECISION_FP16: return NVS_PREC_FLOAT16; case NV30_FP_PRECISION_FX12: return NVS_PREC_FIXED12; default: return NVS_PREC_UNKNOWN; } } static int NV30FPGetSaturate(nvsFunc * shader) { return ((shader->inst[0] & NV30_FP_OP_OUT_SAT) ? 1 : 0); } /******************************************************************************* * Init */ void NV30FPInitShaderFuncs(nvsFunc * shader) { /* These are probably bogus, I made them up... */ shader->MaxInst = 1024; shader->MaxAttrib = 16; shader->MaxTemp = 32; shader->MaxAddress = 1; shader->MaxConst = 256; shader->caps = SCAP_SRC_ABS; MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MOV, NVS_OP_MOV, 0, -1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MUL, NVS_OP_MUL, 0, 1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_ADD, NVS_OP_ADD, 0, 1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MAD, NVS_OP_MAD, 0, 1, 2); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DP3, NVS_OP_DP3, 0, 1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DP4, NVS_OP_DP4, 0, 1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DST, NVS_OP_DST, 0, 1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MIN, NVS_OP_MIN, 0, 1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MAX, NVS_OP_MAX, 0, 1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SLT, NVS_OP_SLT, 0, 1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SGE, NVS_OP_SGE, 0, 1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_FRC, NVS_OP_FRC, 0, -1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_FLR, NVS_OP_FLR, 0, -1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_TEX, NVS_OP_TEX, 0, -1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_TXD, NVS_OP_TXD, 0, 1, 2); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_TXP, NVS_OP_TXP, 0, -1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_TXB, NVS_OP_TXB, 0, -1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SEQ, NVS_OP_SEQ, 0, 1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SGT, NVS_OP_SGT, 0, 1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SLE, NVS_OP_SLE, 0, 1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SNE, NVS_OP_SNE, 0, 1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_RCP, NVS_OP_RCP, 0, -1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_LG2, NVS_OP_LG2, 0, -1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_EX2, NVS_OP_EX2, 0, -1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_COS, NVS_OP_COS, 0, -1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SIN, NVS_OP_SIN, 0, -1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_NOP, NVS_OP_NOP, -1, -1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DDX, NVS_OP_DDX, 0, -1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DDY, NVS_OP_DDY, 0, -1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_KIL, NVS_OP_KIL, -1, -1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_PK4B, NVS_OP_PK4B, 0, -1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_UP4B, NVS_OP_UP4B, 0, -1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_PK2H, NVS_OP_PK2H, 0, -1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_UP2H, NVS_OP_UP2H, 0, -1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_PK4UB, NVS_OP_PK4UB, 0, -1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_UP4UB, NVS_OP_UP4UB, 0, -1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_PK2US, NVS_OP_PK2US, 0, -1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_UP2US, NVS_OP_UP2US, 0, -1, -1); /*FIXME: Haven't confirmed the source positions for the below opcodes */ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_LIT, NVS_OP_LIT, 0, -1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_LRP, NVS_OP_LRP, 0, 1, 2); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_POW, NVS_OP_POW, 0, 1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_RSQ, NVS_OP_RSQ, 0, -1, -1); MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_RFL, NVS_OP_RFL, 0, 1, -1); shader->GetOPTXRec = NV30FPGetOPTXRec; shader->GetOPTXFromSOP = NV30FPGetOPTXFromSOP; shader->UploadToHW = NV30FPUploadToHW; shader->UpdateConst = NV30FPUpdateConst; shader->InitInstruction = NV30FPInitInstruction; shader->SupportsOpcode = NV30FPSupportsOpcode; shader->SetOpcode = NV30FPSetOpcode; shader->SetCCUpdate = NV30FPSetCCUpdate; shader->SetCondition = NV30FPSetCondition; shader->SetResult = NV30FPSetResult; shader->SetSource = NV30FPSetSource; shader->SetTexImageUnit = NV30FPSetTexImageUnit; shader->SetSaturate = NV30FPSetSaturate; shader->SetLastInst = NV30FPSetLastInst; shader->HasMergedInst = NV30FPHasMergedInst; shader->IsLastInst = NV30FPIsLastInst; shader->GetOffsetNext = NV30FPGetOffsetNext; shader->GetOpcode = NV30FPGetOpcode; shader->GetOpcodeHW = NV30FPGetOpcodeHW; shader->GetDestFile = NV30FPGetDestFile; shader->GetDestID = NV30FPGetDestID; shader->GetDestMask = NV30FPGetDestMask; shader->GetSourceHW = NV30FPGetSourceHW; shader->GetSourceFile = NV30FPGetSourceFile; shader->GetSourceID = NV30FPGetSourceID; shader->GetTexImageUnit = NV30FPGetTexImageUnit; shader->GetSourceNegate = NV30FPGetSourceNegate; shader->GetSourceAbs = NV30FPGetSourceAbs; shader->GetSourceSwizzle = NV30FPGetSourceSwizzle; shader->GetSourceIndexed = NV30FPGetSourceIndexed; shader->GetSourceConstVal = NV30FPGetSourceConstVal; shader->GetSourceScale = NV30FPGetSourceScale; shader->GetRelAddressRegID = NV30FPGetAddressRegID; shader->GetRelAddressSwizzle = NV30FPGetAddressRegSwizzle; shader->GetPrecision = NV30FPGetPrecision; shader->GetSaturate = NV30FPGetSaturate; shader->SupportsConditional = NV30FPSupportsConditional; shader->GetConditionUpdate = NV30FPGetConditionUpdate; shader->GetConditionTest = NV30FPGetConditionTest; shader->GetCondition = NV30FPGetCondition; shader->GetCondRegSwizzle = NV30FPGetCondRegSwizzle; shader->GetCondRegID = NV30FPGetCondRegID; }