if (!nvs->program_tree)
nvs->program_tree = &sub->header;
else
- pass0_append_fragment(nvs->program_tree, &sub->header, 0);
+ pass0_append_fragment(nvs->program_tree,
+ &sub->header, 0);
}
return sub;
static void
pass0_make_reg(nouveauShader *nvs, nvsRegister *reg,
- nvsRegFile file, unsigned int index)
+ nvsRegFile file, unsigned int index)
{
- struct pass0_rec *rec = nvs->pass_rec;
-
- /* defaults */
- *reg = nvr_unused;
- /* -1 == quick-and-dirty temp alloc */
- if (file == NVS_FILE_TEMP && index == -1) {
- index = rec->next_temp++;
- assert(index < NVS_MAX_TEMPS);
- }
- reg->file = file;
- reg->index = index;
+ struct pass0_rec *rec = nvs->pass_rec;
+
+ /* defaults */
+ *reg = nvr_unused;
+ /* -1 == quick-and-dirty temp alloc */
+ if (file == NVS_FILE_TEMP && index == -1) {
+ index = rec->next_temp++;
+ assert(index < NVS_MAX_TEMPS);
+ }
+ reg->file = file;
+ reg->index = index;
}
static void
pass0_make_swizzle(nvsSwzComp *swz, unsigned int mesa)
{
- int i;
+ int i;
- for (i=0;i<4;i++)
- swz[i] = _tx_mesa_swizzle[GET_SWZ(mesa, i)];
+ for (i=0;i<4;i++)
+ swz[i] = _tx_mesa_swizzle[GET_SWZ(mesa, i)];
}
static nvsOpcode
pass0_make_opcode(enum prog_opcode op)
{
- if (op > MAX_OPCODE)
- return NVS_OP_UNKNOWN;
- return _tx_mesa_opcode[op];
+ if (op > MAX_OPCODE)
+ return NVS_OP_UNKNOWN;
+ return _tx_mesa_opcode[op];
}
static nvsCond
pass0_make_condmask(GLuint mesa)
{
- if (mesa > COND_FL)
- return NVS_COND_UNKNOWN;
- return _tx_mesa_condmask[mesa];
+ if (mesa > COND_FL)
+ return NVS_COND_UNKNOWN;
+ return _tx_mesa_condmask[mesa];
}
static unsigned int
pass0_make_mask(GLuint mesa_mask)
{
- unsigned int mask = 0;
+ unsigned int mask = 0;
- if (mesa_mask & WRITEMASK_X) mask |= SMASK_X;
- if (mesa_mask & WRITEMASK_Y) mask |= SMASK_Y;
- if (mesa_mask & WRITEMASK_Z) mask |= SMASK_Z;
- if (mesa_mask & WRITEMASK_W) mask |= SMASK_W;
+ if (mesa_mask & WRITEMASK_X) mask |= SMASK_X;
+ if (mesa_mask & WRITEMASK_Y) mask |= SMASK_Y;
+ if (mesa_mask & WRITEMASK_Z) mask |= SMASK_Z;
+ if (mesa_mask & WRITEMASK_W) mask |= SMASK_W;
- return mask;
+ return mask;
}
static nvsTexTarget
pass0_make_tex_target(GLuint mesa)
{
- switch (mesa) {
- case TEXTURE_1D_INDEX: return NVS_TEX_TARGET_1D;
- case TEXTURE_2D_INDEX: return NVS_TEX_TARGET_2D;
- case TEXTURE_3D_INDEX: return NVS_TEX_TARGET_3D;
- case TEXTURE_CUBE_INDEX: return NVS_TEX_TARGET_CUBE;
- case TEXTURE_RECT_INDEX: return NVS_TEX_TARGET_RECT;
- default:
- return NVS_TEX_TARGET_UNKNOWN;
- }
+ switch (mesa) {
+ case TEXTURE_1D_INDEX: return NVS_TEX_TARGET_1D;
+ case TEXTURE_2D_INDEX: return NVS_TEX_TARGET_2D;
+ case TEXTURE_3D_INDEX: return NVS_TEX_TARGET_3D;
+ case TEXTURE_CUBE_INDEX: return NVS_TEX_TARGET_CUBE;
+ case TEXTURE_RECT_INDEX: return NVS_TEX_TARGET_RECT;
+ default:
+ return NVS_TEX_TARGET_UNKNOWN;
+ }
}
static void
pass0_make_dst_reg(nvsPtr nvs, nvsRegister *reg,
struct prog_dst_register *dst)
{
- struct gl_program *mesa = (struct gl_program*)&nvs->mesa.vp;
- nvsFixedReg sfr;
-
- switch (dst->File) {
- case PROGRAM_OUTPUT:
- if (mesa->Target == GL_VERTEX_PROGRAM_ARB) {
- sfr = (dst->Index < VERT_RESULT_MAX) ?
- _tx_mesa_vp_dst_reg[dst->Index] : NVS_FR_UNKNOWN;
- } else {
- sfr = (dst->Index < FRAG_RESULT_MAX) ?
- _tx_mesa_fp_dst_reg[dst->Index] : NVS_FR_UNKNOWN;
- }
- pass0_make_reg(nvs, reg, NVS_FILE_RESULT, sfr);
- break;
- case PROGRAM_TEMPORARY:
- pass0_make_reg(nvs, reg, NVS_FILE_TEMP, dst->Index);
- break;
- case PROGRAM_ADDRESS:
- pass0_make_reg(nvs, reg, NVS_FILE_ADDRESS, dst->Index);
- break;
- default:
- fprintf(stderr, "Unknown dest file %d\n", dst->File);
- assert(0);
- }
+ struct gl_program *mesa = (struct gl_program*)&nvs->mesa.vp;
+ nvsFixedReg sfr;
+
+ switch (dst->File) {
+ case PROGRAM_OUTPUT:
+ if (mesa->Target == GL_VERTEX_PROGRAM_ARB) {
+ sfr = (dst->Index < VERT_RESULT_MAX) ?
+ _tx_mesa_vp_dst_reg[dst->Index] :
+ NVS_FR_UNKNOWN;
+ } else {
+ sfr = (dst->Index < FRAG_RESULT_MAX) ?
+ _tx_mesa_fp_dst_reg[dst->Index] :
+ NVS_FR_UNKNOWN;
+ }
+ pass0_make_reg(nvs, reg, NVS_FILE_RESULT, sfr);
+ break;
+ case PROGRAM_TEMPORARY:
+ pass0_make_reg(nvs, reg, NVS_FILE_TEMP, dst->Index);
+ break;
+ case PROGRAM_ADDRESS:
+ pass0_make_reg(nvs, reg, NVS_FILE_ADDRESS, dst->Index);
+ break;
+ default:
+ fprintf(stderr, "Unknown dest file %d\n", dst->File);
+ assert(0);
+ }
}
static void
pass0_make_src_reg(nvsPtr nvs, nvsRegister *reg, struct prog_src_register *src)
{
- struct gl_program *mesa = (struct gl_program *)&nvs->mesa.vp.Base;
- struct gl_program_parameter_list *p = mesa->Parameters;
-
- *reg = nvr_unused;
-
- switch (src->File) {
- case PROGRAM_INPUT:
- reg->file = NVS_FILE_ATTRIB;
- if (mesa->Target == GL_VERTEX_PROGRAM_ARB) {
- reg->index = (src->Index < VERT_ATTRIB_MAX) ?
- _tx_mesa_vp_src_reg[src->Index] : NVS_FR_UNKNOWN;
- } else {
- reg->index = (src->Index < FRAG_ATTRIB_MAX) ?
- _tx_mesa_fp_src_reg[src->Index] : NVS_FR_UNKNOWN;
- }
- break;
- /* All const types seem to get shoved into here, not really sure why */
- case PROGRAM_STATE_VAR:
- switch (p->Parameters[src->Index].Type) {
- case PROGRAM_NAMED_PARAM:
- case PROGRAM_CONSTANT:
- nvs->params[src->Index].source_val = NULL;
- COPY_4V(nvs->params[src->Index].val, p->ParameterValues[src->Index]);
- break;
- case PROGRAM_STATE_VAR:
- nvs->params[src->Index].source_val = p->ParameterValues[src->Index];
- break;
- default:
- fprintf(stderr, "Unknown parameter type %d\n",
- p->Parameters[src->Index].Type);
- assert(0);
- break;
- }
-
- if (src->RelAddr) {
- reg->indexed = 1;
- reg->addr_reg = 0;
- reg->addr_comp = NVS_SWZ_X;
- } else
- reg->indexed = 0;
- reg->file = NVS_FILE_CONST;
- reg->index = src->Index;
- break;
- case PROGRAM_TEMPORARY:
- reg->file = NVS_FILE_TEMP;
- reg->index = src->Index;
- break;
- default:
- fprintf(stderr, "Unknown source type %d\n", src->File);
- assert(0);
- }
-
- /* per-component negate handled elsewhere */
- reg->negate = src->NegateBase != 0;
- reg->abs = src->Abs;
- pass0_make_swizzle(reg->swizzle, src->Swizzle);
+ struct gl_program *mesa = (struct gl_program *)&nvs->mesa.vp.Base;
+ struct gl_program_parameter_list *p = mesa->Parameters;
+
+ *reg = nvr_unused;
+
+ switch (src->File) {
+ case PROGRAM_INPUT:
+ reg->file = NVS_FILE_ATTRIB;
+ if (mesa->Target == GL_VERTEX_PROGRAM_ARB) {
+ reg->index = (src->Index < VERT_ATTRIB_MAX) ?
+ _tx_mesa_vp_src_reg[src->Index] :
+ NVS_FR_UNKNOWN;
+ } else {
+ reg->index = (src->Index < FRAG_ATTRIB_MAX) ?
+ _tx_mesa_fp_src_reg[src->Index] :
+ NVS_FR_UNKNOWN;
+ }
+ break;
+ /* All const types seem to get shoved into here, not really sure why */
+ case PROGRAM_STATE_VAR:
+ switch (p->Parameters[src->Index].Type) {
+ case PROGRAM_NAMED_PARAM:
+ case PROGRAM_CONSTANT:
+ nvs->params[src->Index].source_val = NULL;
+ COPY_4V(nvs->params[src->Index].val,
+ p->ParameterValues[src->Index]);
+ break;
+ case PROGRAM_STATE_VAR:
+ nvs->params[src->Index].source_val =
+ p->ParameterValues[src->Index];
+ break;
+ default:
+ fprintf(stderr, "Unknown parameter type %d\n",
+ p->Parameters[src->Index].Type);
+ assert(0);
+ break;
+ }
+
+ if (src->RelAddr) {
+ reg->indexed = 1;
+ reg->addr_reg = 0;
+ reg->addr_comp = NVS_SWZ_X;
+ } else
+ reg->indexed = 0;
+ reg->file = NVS_FILE_CONST;
+ reg->index = src->Index;
+ break;
+ case PROGRAM_TEMPORARY:
+ reg->file = NVS_FILE_TEMP;
+ reg->index = src->Index;
+ break;
+ default:
+ fprintf(stderr, "Unknown source type %d\n", src->File);
+ assert(0);
+ }
+
+ /* per-component negate handled elsewhere */
+ reg->negate = src->NegateBase != 0;
+ reg->abs = src->Abs;
+ pass0_make_swizzle(reg->swizzle, src->Swizzle);
}
static nvsInstruction *
static void
pass0_fixup_swizzle(nvsPtr nvs, nvsFragmentHeader *parent, int fpos,
- struct prog_src_register *src,
+ struct prog_src_register *src,
unsigned int sm1,
unsigned int sm2)
{
- static const float sc[4] = { 1.0, 0.0, -1.0, 0.0 };
- struct pass0_rec *rec = nvs->pass_rec;
- int fixup_1, fixup_2;
- nvsRegister sr, dr = nvr_unused;
- nvsRegister sm1const, sm2const;
-
- if (!rec->swzconst_done) {
- struct gl_program *prog = &nvs->mesa.vp.Base;
- rec->swzconst_id = _mesa_add_unnamed_constant(prog->Parameters, sc, 4);
- rec->swzconst_done = 1;
- COPY_4V(nvs->params[rec->swzconst_id].val, sc);
- }
-
- fixup_1 = (sm1 != MAKE_SWIZZLE4(0,0,0,0) && sm2 != MAKE_SWIZZLE4(2,2,2,2));
- fixup_2 = (sm2 != MAKE_SWIZZLE4(2,2,2,2));
-
- if (src->File != PROGRAM_TEMPORARY && src->File != PROGRAM_INPUT) {
- /* We can't use more than one const in an instruction, so move the const
- * into a temp, and swizzle from there.
- *TODO: should just emit the swizzled const, instead of swizzling it
- * in the shader.. would need to reswizzle any state params when they
- * change however..
- */
- pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1);
- pass0_make_src_reg(nvs, &sr, src);
- pass0_emit(nvs, parent, fpos, NVS_OP_MOV, dr, SMASK_ALL, 0, sr, nvr_unused, nvr_unused);
- pass0_make_reg(nvs, &sr, NVS_FILE_TEMP, dr.index);
- } else {
- if (fixup_1)
- src->NegateBase = 0;
- pass0_make_src_reg(nvs, &sr, src);
- pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1);
- }
-
- pass0_make_reg(nvs, &sm1const, NVS_FILE_CONST, rec->swzconst_id);
- pass0_make_swizzle(sm1const.swizzle, sm1);
- if (fixup_1 && fixup_2) {
- /* Any combination with SWIZZLE_ONE */
- pass0_make_reg(nvs, &sm2const, NVS_FILE_CONST, rec->swzconst_id);
- pass0_make_swizzle(sm2const.swizzle, sm2);
- pass0_emit(nvs, parent, fpos, NVS_OP_MAD, dr, SMASK_ALL, 0, sr, sm1const, sm2const);
- } else {
- /* SWIZZLE_ZERO || arbitrary negate */
- pass0_emit(nvs, parent, fpos, NVS_OP_MUL, dr, SMASK_ALL, 0, sr, sm1const, nvr_unused);
- }
-
- src->File = PROGRAM_TEMPORARY;
- src->Index = dr.index;
- src->Swizzle = SWIZZLE_NOOP;
+ static const float sc[4] = { 1.0, 0.0, -1.0, 0.0 };
+ struct pass0_rec *rec = nvs->pass_rec;
+ int fixup_1, fixup_2;
+ nvsRegister sr, dr = nvr_unused;
+ nvsRegister sm1const, sm2const;
+
+ if (!rec->swzconst_done) {
+ struct gl_program *prog = &nvs->mesa.vp.Base;
+ rec->swzconst_id = _mesa_add_unnamed_constant(prog->Parameters,
+ sc, 4);
+ rec->swzconst_done = 1;
+ COPY_4V(nvs->params[rec->swzconst_id].val, sc);
+ }
+
+ fixup_1 = (sm1 != MAKE_SWIZZLE4(0,0,0,0) &&
+ sm2 != MAKE_SWIZZLE4(2,2,2,2));
+ fixup_2 = (sm2 != MAKE_SWIZZLE4(2,2,2,2));
+
+ if (src->File != PROGRAM_TEMPORARY && src->File != PROGRAM_INPUT) {
+ /* We can't use more than one const in an instruction,
+ * so move the const into a temp, and swizzle from there.
+ *
+ * TODO: should just emit the swizzled const, instead of
+ * swizzling it in the shader.. would need to reswizzle
+ * any state params when they change however..
+ */
+ pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1);
+ pass0_make_src_reg(nvs, &sr, src);
+ pass0_emit(nvs, parent, fpos, NVS_OP_MOV,
+ dr, SMASK_ALL, 0, sr, nvr_unused, nvr_unused);
+ pass0_make_reg(nvs, &sr, NVS_FILE_TEMP, dr.index);
+ } else {
+ if (fixup_1)
+ src->NegateBase = 0;
+ pass0_make_src_reg(nvs, &sr, src);
+ pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1);
+ }
+
+ pass0_make_reg(nvs, &sm1const, NVS_FILE_CONST, rec->swzconst_id);
+ pass0_make_swizzle(sm1const.swizzle, sm1);
+ if (fixup_1 && fixup_2) {
+ /* Any combination with SWIZZLE_ONE */
+ pass0_make_reg(nvs, &sm2const,
+ NVS_FILE_CONST, rec->swzconst_id);
+ pass0_make_swizzle(sm2const.swizzle, sm2);
+ pass0_emit(nvs, parent, fpos, NVS_OP_MAD,
+ dr, SMASK_ALL, 0, sr, sm1const, sm2const);
+ } else {
+ /* SWIZZLE_ZERO || arbitrary negate */
+ pass0_emit(nvs, parent, fpos, NVS_OP_MUL,
+ dr, SMASK_ALL, 0, sr, sm1const, nvr_unused);
+ }
+
+ src->File = PROGRAM_TEMPORARY;
+ src->Index = dr.index;
+ src->Swizzle = SWIZZLE_NOOP;
}
#define SET_SWZ(fs, cp, c) fs = (fs & ~(0x7<<(cp*3))) | (c<<(cp*3))
pass0_check_sources(nvsPtr nvs, nvsFragmentHeader *parent, int fpos,
struct prog_instruction *inst)
{
- unsigned int insrc = -1, constsrc = -1;
- int i;
-
- for (i=0;i<_mesa_num_inst_src_regs(inst->Opcode);i++) {
- struct prog_src_register *src = &inst->SrcReg[i];
- unsigned int sm_1 = 0, sm_2 = 0;
- nvsRegister sr, dr;
- int do_mov = 0, c;
-
- /* Build up swizzle masks as if we were going to use
- * "MAD new, src, const1, const2" to support arbitrary negation
- * and SWIZZLE_ZERO/SWIZZLE_ONE.
- */
- for (c=0;c<4;c++) {
- if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ZERO) {
- SET_SWZ(sm_1, c, SWIZZLE_Y); /* 0.0 */
- SET_SWZ(sm_2, c, SWIZZLE_Y);
- SET_SWZ(src->Swizzle, c, SWIZZLE_X);
- } else if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ONE) {
- SET_SWZ(sm_1, c, SWIZZLE_Y);
- if (src->NegateBase & (1<<c))
- SET_SWZ(sm_2, c, SWIZZLE_Z); /* -1.0 */
- else
- SET_SWZ(sm_2, c, SWIZZLE_X); /* 1.0 */
- SET_SWZ(src->Swizzle, c, SWIZZLE_X);
- } else {
- if (src->NegateBase & (1<<c))
- SET_SWZ(sm_1, c, SWIZZLE_Z); /* -[xyzw] */
- else
- SET_SWZ(sm_1, c, SWIZZLE_X); /* [xyzw] */
- SET_SWZ(sm_2, c, SWIZZLE_Y);
- }
- }
- /* Unless we're multiplying by 1.0 or -1.0 on all components, and we're
- * adding nothing to any component we have to emulate the swizzle.
- */
- if ((sm_1 != MAKE_SWIZZLE4(0,0,0,0) && sm_1 != MAKE_SWIZZLE4(2,2,2,2)) ||
- sm_2 != MAKE_SWIZZLE4(1,1,1,1)) {
- pass0_fixup_swizzle(nvs, parent, fpos, src, sm_1, sm_2);
- /* The source is definitely in a temp now, so don't bother checking
- * for multiple ATTRIB/CONST regs.
- */
- continue;
- }
-
- /* HW can't use more than one ATTRIB or PARAM in a single instruction */
- switch (src->File) {
- case PROGRAM_INPUT:
- if (insrc != -1 && insrc != src->Index)
- do_mov = 1;
- else insrc = src->Index;
- break;
- case PROGRAM_STATE_VAR:
- if (constsrc != -1 && constsrc != src->Index)
- do_mov = 1;
- else constsrc = src->Index;
- break;
- default:
- break;
- }
-
- /* Emit any extra ATTRIB/CONST to a temp, and modify the Mesa instruction
- * to point at the temp.
- */
- if (do_mov) {
- pass0_make_src_reg(nvs, &sr, src);
- pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1);
- pass0_emit(nvs, parent, fpos, NVS_OP_MOV, dr, SMASK_ALL, 0,
- sr, nvr_unused, nvr_unused);
-
- src->File = PROGRAM_TEMPORARY;
- src->Index = dr.index;
- src->Swizzle= SWIZZLE_NOOP;
- }
- }
+ unsigned int insrc = -1, constsrc = -1;
+ int i;
+
+ for (i=0;i<_mesa_num_inst_src_regs(inst->Opcode);i++) {
+ struct prog_src_register *src = &inst->SrcReg[i];
+ unsigned int sm_1 = 0, sm_2 = 0;
+ nvsRegister sr, dr;
+ int do_mov = 0, c;
+
+ /* Build up swizzle masks as if we were going to use
+ * "MAD new, src, const1, const2" to support arbitrary negation
+ * and SWIZZLE_ZERO/SWIZZLE_ONE.
+ */
+ for (c=0;c<4;c++) {
+ if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ZERO) {
+ SET_SWZ(sm_1, c, SWIZZLE_Y); /* 0.0 */
+ SET_SWZ(sm_2, c, SWIZZLE_Y);
+ SET_SWZ(src->Swizzle, c, SWIZZLE_X);
+ } else if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ONE) {
+ SET_SWZ(sm_1, c, SWIZZLE_Y);
+ if (src->NegateBase & (1<<c))
+ SET_SWZ(sm_2, c, SWIZZLE_Z); /* -1.0 */
+ else
+ SET_SWZ(sm_2, c, SWIZZLE_X); /* 1.0 */
+ SET_SWZ(src->Swizzle, c, SWIZZLE_X);
+ } else {
+ if (src->NegateBase & (1<<c))
+ SET_SWZ(sm_1, c, SWIZZLE_Z); /* -[xyzw] */
+ else
+ SET_SWZ(sm_1, c, SWIZZLE_X); /*[xyzw]*/
+ SET_SWZ(sm_2, c, SWIZZLE_Y);
+ }
+ }
+
+ /* Unless we're multiplying by 1.0 or -1.0 on all components,
+ * and we're adding nothing to any component we have to
+ * emulate the swizzle.
+ */
+ if ((sm_1 != MAKE_SWIZZLE4(0,0,0,0) &&
+ sm_1 != MAKE_SWIZZLE4(2,2,2,2)) ||
+ sm_2 != MAKE_SWIZZLE4(1,1,1,1)) {
+ pass0_fixup_swizzle(nvs, parent, fpos, src, sm_1, sm_2);
+ /* The source is definitely in a temp now, so don't
+ * bother checking for multiple ATTRIB/CONST regs.
+ */
+ continue;
+ }
+
+ /* HW can't use more than one ATTRIB or PARAM in a single
+ * instruction */
+ switch (src->File) {
+ case PROGRAM_INPUT:
+ if (insrc != -1 && insrc != src->Index)
+ do_mov = 1;
+ else insrc = src->Index;
+ break;
+ case PROGRAM_STATE_VAR:
+ if (constsrc != -1 && constsrc != src->Index)
+ do_mov = 1;
+ else constsrc = src->Index;
+ break;
+ default:
+ break;
+ }
+
+ /* Emit any extra ATTRIB/CONST to a temp, and modify the Mesa
+ * instruction to point at the temp.
+ */
+ if (do_mov) {
+ pass0_make_src_reg(nvs, &sr, src);
+ pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1);
+ pass0_emit(nvs, parent, fpos, NVS_OP_MOV,
+ dr, SMASK_ALL, 0,
+ sr, nvr_unused, nvr_unused);
+
+ src->File = PROGRAM_TEMPORARY;
+ src->Index = dr.index;
+ src->Swizzle= SWIZZLE_NOOP;
+ }
+ }
}
static GLboolean
nvsFragmentHeader *parent, int fpos,
struct prog_instruction *inst)
{
- nvsFunc *shader = nvs->func;
- nvsRegister src[3], dest, temp;
- nvsInstruction *nvsinst;
- struct pass0_rec *rec = nvs->pass_rec;
- unsigned int mask = pass0_make_mask(inst->DstReg.WriteMask);
- int i, sat;
-
- sat = (inst->SaturateMode == SATURATE_ZERO_ONE);
-
- /* Build all the "real" regs for the instruction */
- for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++)
- pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]);
- if (inst->Opcode != OPCODE_KIL)
- pass0_make_dst_reg(nvs, &dest, &inst->DstReg);
-
- switch (inst->Opcode) {
- case OPCODE_ABS:
- if (shader->caps & SCAP_SRC_ABS)
- pass0_emit(nvs, parent, fpos, NVS_OP_MOV, dest, mask, sat,
- nvsAbs(src[0]), nvr_unused, nvr_unused);
- else
- pass0_emit(nvs, parent, fpos, NVS_OP_MAX, dest, mask, sat,
- src[0], nvsNegate(src[0]), nvr_unused);
- break;
- case OPCODE_KIL:
- /* This is only in ARB shaders, so we don't have to worry
- * about clobbering a CC reg as they aren't supported anyway.
- */
- /* MOVC0 temp, src */
- pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
- nvsinst = pass0_emit(nvs, parent, fpos, NVS_OP_MOV, temp, SMASK_ALL, 0,
- src[0], nvr_unused, nvr_unused);
- nvsinst->cond_update = 1;
- nvsinst->cond_reg = 0;
- /* KIL_NV (LT0.xyzw) temp */
- nvsinst = pass0_emit(nvs, parent, fpos, NVS_OP_KIL, nvr_unused, 0, 0,
- nvr_unused, nvr_unused, nvr_unused);
- nvsinst->cond = COND_LT;
- nvsinst->cond_reg = 0;
- nvsinst->cond_test = 1;
- pass0_make_swizzle(nvsinst->cond_swizzle, MAKE_SWIZZLE4(0,1,2,3));
- break;
- case OPCODE_LIT:
- break;
- case OPCODE_LRP:
- pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
- pass0_emit(nvs, parent, fpos, NVS_OP_MAD, temp, mask, 0,
- nvsNegate(src[0]), src[2], src[2]);
- pass0_emit(nvs, parent, fpos, NVS_OP_MAD, dest, mask, sat,
- src[0], src[1], temp);
- break;
- case OPCODE_POW:
- if (shader->SupportsOpcode(shader, NVS_OP_LG2) &&
- shader->SupportsOpcode(shader, NVS_OP_EX2)) {
- pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
- /* LG2 temp.x, src0.c */
- pass0_emit(nvs, parent, fpos, NVS_OP_LG2, temp, SMASK_X, 0,
- nvsSwizzle(src[0], X, X, X, X),
- nvr_unused,
- nvr_unused);
- /* MUL temp.x, temp.x, src1.c */
- pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_X, 0,
- nvsSwizzle(temp, X, X, X, X),
- nvsSwizzle(src[1], X, X, X, X),
- nvr_unused);
- /* EX2 dest, temp.x */
- pass0_emit(nvs, parent, fpos, NVS_OP_EX2, dest, mask, sat,
- nvsSwizzle(temp, X, X, X, X),
- nvr_unused,
- nvr_unused);
- } else {
- /* can we use EXP/LOG instead of EX2/LG2?? */
- fprintf(stderr, "Implement POW for NV20 vtxprog!\n");
- return GL_FALSE;
- }
- break;
- case OPCODE_RSQ:
- if (rec->const_half.file != NVS_FILE_CONST) {
- GLfloat const_half[4] = { 0.5, 0.0, 0.0, 0.0 };
- pass0_make_reg(nvs, &rec->const_half, NVS_FILE_CONST,
- _mesa_add_unnamed_constant(nvs->mesa.vp.Base.Parameters,
- const_half, 4));
- COPY_4V(nvs->params[rec->const_half.index].val, const_half);
- }
- pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
- pass0_emit(nvs, parent, fpos, NVS_OP_LG2, temp, SMASK_X, 0,
- nvsAbs(nvsSwizzle(src[0], X, X, X, X)),
- nvr_unused,
- nvr_unused);
- pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_X, 0,
- nvsSwizzle(temp, X, X, X, X),
- nvsNegate(rec->const_half),
- nvr_unused);
- pass0_emit(nvs, parent, fpos, NVS_OP_EX2, dest, mask, sat,
- nvsSwizzle(temp, X, X, X, X),
- nvr_unused,
- nvr_unused);
- break;
- case OPCODE_SCS:
- if (mask & SMASK_X)
- pass0_emit(nvs, parent, fpos, NVS_OP_COS, dest, SMASK_X, sat,
- nvsSwizzle(src[0], X, X, X, X),
- nvr_unused,
- nvr_unused);
- if (mask & SMASK_Y)
- pass0_emit(nvs, parent, fpos, NVS_OP_SIN, dest, SMASK_Y, sat,
- nvsSwizzle(src[0], X, X, X, X),
- nvr_unused,
- nvr_unused);
- break;
- case OPCODE_SUB:
- pass0_emit(nvs, parent, fpos, NVS_OP_ADD, dest, mask, sat,
- src[0], nvsNegate(src[1]), nvr_unused);
- break;
- case OPCODE_XPD:
- pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
- pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_ALL, 0,
- nvsSwizzle(src[0], Z, X, Y, Y),
- nvsSwizzle(src[1], Y, Z, X, X),
- nvr_unused);
- pass0_emit(nvs, parent, fpos, NVS_OP_MAD, dest, (mask & ~SMASK_W), sat,
- nvsSwizzle(src[0], Y, Z, X, X),
- nvsSwizzle(src[1], Z, X, Y, Y),
- nvsNegate(temp));
- break;
- default:
- fprintf(stderr, "hw doesn't support opcode \"%s\", and no emulation found\n",
- _mesa_opcode_string(inst->Opcode));
- return GL_FALSE;
- }
-
- return GL_TRUE;
+ nvsFunc *shader = nvs->func;
+ nvsRegister src[3], dest, temp;
+ nvsInstruction *nvsinst;
+ struct pass0_rec *rec = nvs->pass_rec;
+ unsigned int mask = pass0_make_mask(inst->DstReg.WriteMask);
+ int i, sat;
+
+ sat = (inst->SaturateMode == SATURATE_ZERO_ONE);
+
+ /* Build all the "real" regs for the instruction */
+ for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++)
+ pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]);
+ if (inst->Opcode != OPCODE_KIL)
+ pass0_make_dst_reg(nvs, &dest, &inst->DstReg);
+
+ switch (inst->Opcode) {
+ case OPCODE_ABS:
+ if (shader->caps & SCAP_SRC_ABS)
+ pass0_emit(nvs, parent, fpos, NVS_OP_MOV,
+ dest, mask, sat,
+ nvsAbs(src[0]), nvr_unused, nvr_unused);
+ else
+ pass0_emit(nvs, parent, fpos, NVS_OP_MAX,
+ dest, mask, sat,
+ src[0], nvsNegate(src[0]), nvr_unused);
+ break;
+ case OPCODE_KIL:
+ /* This is only in ARB shaders, so we don't have to worry
+ * about clobbering a CC reg as they aren't supported anyway.
+ */
+ /* MOVC0 temp, src */
+ pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
+ nvsinst = pass0_emit(nvs, parent, fpos, NVS_OP_MOV,
+ temp, SMASK_ALL, 0,
+ src[0], nvr_unused, nvr_unused);
+ nvsinst->cond_update = 1;
+ nvsinst->cond_reg = 0;
+ /* KIL_NV (LT0.xyzw) temp */
+ nvsinst = pass0_emit(nvs, parent, fpos, NVS_OP_KIL,
+ nvr_unused, 0, 0,
+ nvr_unused, nvr_unused, nvr_unused);
+ nvsinst->cond = COND_LT;
+ nvsinst->cond_reg = 0;
+ nvsinst->cond_test = 1;
+ pass0_make_swizzle(nvsinst->cond_swizzle,
+ MAKE_SWIZZLE4(0,1,2,3));
+ break;
+ case OPCODE_LRP:
+ pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
+ pass0_emit(nvs, parent, fpos, NVS_OP_MAD, temp, mask, 0,
+ nvsNegate(src[0]), src[2], src[2]);
+ pass0_emit(nvs, parent, fpos, NVS_OP_MAD, dest, mask, sat,
+ src[0], src[1], temp);
+ break;
+ case OPCODE_POW:
+ if (shader->SupportsOpcode(shader, NVS_OP_LG2) &&
+ shader->SupportsOpcode(shader, NVS_OP_EX2)) {
+ pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
+ /* LG2 temp.x, src0.c */
+ pass0_emit(nvs, parent, fpos, NVS_OP_LG2,
+ temp, SMASK_X, 0,
+ nvsSwizzle(src[0], X, X, X, X),
+ nvr_unused,
+ nvr_unused);
+ /* MUL temp.x, temp.x, src1.c */
+ pass0_emit(nvs, parent, fpos, NVS_OP_MUL,
+ temp, SMASK_X, 0,
+ nvsSwizzle(temp, X, X, X, X),
+ nvsSwizzle(src[1], X, X, X, X),
+ nvr_unused);
+ /* EX2 dest, temp.x */
+ pass0_emit(nvs, parent, fpos, NVS_OP_EX2,
+ dest, mask, sat,
+ nvsSwizzle(temp, X, X, X, X),
+ nvr_unused,
+ nvr_unused);
+ } else {
+ /* can we use EXP/LOG instead of EX2/LG2?? */
+ fprintf(stderr, "Implement POW for NV20 vtxprog!\n");
+ return GL_FALSE;
+ }
+ break;
+ case OPCODE_RSQ:
+ if (rec->const_half.file != NVS_FILE_CONST) {
+ GLfloat const_half[4] = { 0.5, 0.0, 0.0, 0.0 };
+ pass0_make_reg(nvs, &rec->const_half, NVS_FILE_CONST,
+ _mesa_add_unnamed_constant(
+ nvs->mesa.vp.Base.Parameters,
+ const_half, 4));
+ COPY_4V(nvs->params[rec->const_half.index].val,
+ const_half);
+ }
+ pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
+ pass0_emit(nvs, parent, fpos, NVS_OP_LG2, temp, SMASK_X, 0,
+ nvsAbs(nvsSwizzle(src[0], X, X, X, X)),
+ nvr_unused,
+ nvr_unused);
+ pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_X, 0,
+ nvsSwizzle(temp, X, X, X, X),
+ nvsNegate(rec->const_half),
+ nvr_unused);
+ pass0_emit(nvs, parent, fpos, NVS_OP_EX2, dest, mask, sat,
+ nvsSwizzle(temp, X, X, X, X),
+ nvr_unused,
+ nvr_unused);
+ break;
+ case OPCODE_SCS:
+ if (mask & SMASK_X)
+ pass0_emit(nvs, parent, fpos, NVS_OP_COS,
+ dest, SMASK_X, sat,
+ nvsSwizzle(src[0], X, X, X, X),
+ nvr_unused,
+ nvr_unused);
+ if (mask & SMASK_Y)
+ pass0_emit(nvs, parent, fpos, NVS_OP_SIN,
+ dest, SMASK_Y, sat,
+ nvsSwizzle(src[0], X, X, X, X),
+ nvr_unused,
+ nvr_unused);
+ break;
+ case OPCODE_SUB:
+ pass0_emit(nvs, parent, fpos, NVS_OP_ADD, dest, mask, sat,
+ src[0], nvsNegate(src[1]), nvr_unused);
+ break;
+ case OPCODE_XPD:
+ pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
+ pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_ALL, 0,
+ nvsSwizzle(src[0], Z, X, Y, Y),
+ nvsSwizzle(src[1], Y, Z, X, X),
+ nvr_unused);
+ pass0_emit(nvs, parent, fpos, NVS_OP_MAD,
+ dest, (mask & ~SMASK_W), sat,
+ nvsSwizzle(src[0], Y, Z, X, X),
+ nvsSwizzle(src[1], Z, X, Y, Y),
+ nvsNegate(temp));
+ break;
+ default:
+ WARN_ONCE("hw doesn't support opcode \"%s\","
+ "and no emulation found\n",
+ _mesa_opcode_string(inst->Opcode));
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
}
static GLboolean
#include "nouveau_msg.h"
struct pass2_rec {
- /* Map nvsRegister temp ID onto hw temp ID */
- unsigned int temps[NVS_MAX_TEMPS];
- /* Track free hw registers */
- unsigned int hw_temps[NVS_MAX_TEMPS];
+ /* Map nvsRegister temp ID onto hw temp ID */
+ unsigned int temps[NVS_MAX_TEMPS];
+ /* Track free hw registers */
+ unsigned int hw_temps[NVS_MAX_TEMPS];
};
static int
pass2_alloc_hw_temp(nvsPtr nvs)
{
- struct pass2_rec *rec = nvs->pass_rec;
- int i;
-
- for (i=0; i<nvs->func->MaxTemp; i++) {
- /* This is a *horrible* hack.. R0 is both temp0 and result.color
- * in NV30/40 fragprogs, we can use R0 as a temp before result is
- * written however..
- */
- if (nvs->mesa.vp.Base.Target == GL_FRAGMENT_PROGRAM_ARB && i==0)
- continue;
-
- if (rec->hw_temps[i] == 0) {
- rec->hw_temps[i] = 1;
- return i;
- }
- }
- return -1;
+ struct pass2_rec *rec = nvs->pass_rec;
+ int i;
+
+ for (i=0; i<nvs->func->MaxTemp; i++) {
+ /* This is a *horrible* hack.. R0 is both temp0 and result.color
+ * in NV30/40 fragprogs, we can use R0 as a temp before result
+ * is written however..
+ */
+ if (nvs->mesa.vp.Base.Target == GL_FRAGMENT_PROGRAM_ARB && i==0)
+ continue;
+ if (rec->hw_temps[i] == 0) {
+ rec->hw_temps[i] = 1;
+ return i;
+ }
+ }
+
+ return -1;
}
static nvsRegister
pass2_mangle_reg(nvsPtr nvs, nvsInstruction *inst, nvsRegister reg)
{
- struct pass2_rec *rec = nvs->pass_rec;
+ struct pass2_rec *rec = nvs->pass_rec;
- if (reg.file == NVS_FILE_TEMP) {
- if (rec->temps[reg.index] == -1)
- rec->temps[reg.index] = pass2_alloc_hw_temp(nvs);
- reg.index = rec->temps[reg.index];
- }
+ if (reg.file == NVS_FILE_TEMP) {
+ if (rec->temps[reg.index] == -1)
+ rec->temps[reg.index] = pass2_alloc_hw_temp(nvs);
+ reg.index = rec->temps[reg.index];
+ }
- return reg;
+ return reg;
}
static void
pass2_add_instruction(nvsPtr nvs, nvsInstruction *inst,
- struct _op_xlat *op, int slot)
+ struct _op_xlat *op, int slot)
{
- nvsSwzComp default_swz[4] = { NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W };
- nvsFunc *shader = nvs->func;
- nvsRegister reg;
- int i;
-
- shader->SetOpcode(shader, op->NV, slot);
- if (inst->saturate ) shader->SetSaturate(shader);
- if (inst->cond_update) shader->SetCCUpdate(shader);
- if (inst->cond_test ) shader->SetCondition(shader, 1, inst->cond,
- inst->cond_reg,
- inst->cond_swizzle);
- else shader->SetCondition(shader, 0, NVS_COND_TR,
- 0,
- default_swz);
- switch (inst->op) {
- case NVS_OP_TEX:
- case NVS_OP_TXB:
- case NVS_OP_TXL:
- case NVS_OP_TXP:
- case NVS_OP_TXD:
- shader->SetTexImageUnit(shader, inst->tex_unit);
- break;
- default:
- break;
- }
-
- for (i = 0; i < 3; i++) {
- if (op->srcpos[i] != -1) {
- reg = pass2_mangle_reg(nvs, inst, inst->src[i]);
- if (reg.file == NVS_FILE_ATTRIB)
- nvs->inputs_read |= (1 << reg.index);
- shader->SetSource(shader, ®, op->srcpos[i]);
- if (reg.file == NVS_FILE_CONST && shader->GetSourceConstVal) {
- int idx_slot = nvs->params[reg.index].hw_index_cnt++;
- nvs->params[reg.index].hw_index = realloc(
- nvs->params[reg.index].hw_index, sizeof(int) * idx_slot+1);
- nvs->params[reg.index].hw_index[idx_slot] = nvs->program_current + 4;
- }
- }
- }
-
- reg = pass2_mangle_reg(nvs, inst, inst->dest);
- if (reg.file == NVS_FILE_RESULT)
- nvs->outputs_written |= (1 << reg.index);
- shader->SetResult(shader, ®, inst->mask, slot);
+ nvsSwzComp default_swz[4] = { NVS_SWZ_X, NVS_SWZ_Y,
+ NVS_SWZ_Z, NVS_SWZ_W };
+ nvsFunc *shader = nvs->func;
+ nvsRegister reg;
+ int i;
+
+ shader->SetOpcode(shader, op->NV, slot);
+ if (inst->saturate ) shader->SetSaturate(shader);
+ if (inst->cond_update ) shader->SetCCUpdate(shader);
+ if (inst->cond_test ) shader->SetCondition(shader, 1, inst->cond,
+ inst->cond_reg,
+ inst->cond_swizzle);
+ else shader->SetCondition(shader, 0, NVS_COND_TR,
+ 0,
+ default_swz);
+ switch (inst->op) {
+ case NVS_OP_TEX:
+ case NVS_OP_TXB:
+ case NVS_OP_TXL:
+ case NVS_OP_TXP:
+ case NVS_OP_TXD:
+ shader->SetTexImageUnit(shader, inst->tex_unit);
+ break;
+ default:
+ break;
+ }
+
+ for (i = 0; i < 3; i++) {
+ if (op->srcpos[i] != -1) {
+ reg = pass2_mangle_reg(nvs, inst, inst->src[i]);
+
+ if (reg.file == NVS_FILE_ATTRIB)
+ nvs->inputs_read |= (1 << reg.index);
+ shader->SetSource(shader, ®, op->srcpos[i]);
+
+ if (reg.file == NVS_FILE_CONST &&
+ shader->GetSourceConstVal) {
+ int idx_slot =
+ nvs->params[reg.index].hw_index_cnt++;
+ nvs->params[reg.index].hw_index = realloc(
+ nvs->params[reg.index].hw_index,
+ sizeof(int) * idx_slot+1);
+ nvs->params[reg.index].hw_index[idx_slot] =
+ nvs->program_current + 4;
+ }
+ }
+ }
+
+ reg = pass2_mangle_reg(nvs, inst, inst->dest);
+ if (reg.file == NVS_FILE_RESULT)
+ nvs->outputs_written |= (1 << reg.index);
+ shader->SetResult(shader, ®, inst->mask, slot);
}
static int
pass2_assemble_instruction(nvsPtr nvs, nvsInstruction *inst, int last)
{
- nvsFunc *shader = nvs->func;
- struct _op_xlat *op;
- unsigned int hw_inst[8];
- int slot;
- int instsz;
- int i;
-
- shader->inst = hw_inst;
-
- /* Assemble this instruction */
- if (!(op = shader->GetOPTXFromSOP(inst->op, &slot)))
- return 0;
- shader->InitInstruction(shader);
- pass2_add_instruction(nvs, inst, op, slot);
- if (last)
- shader->SetLastInst(shader);
-
- instsz = shader->GetOffsetNext(nvs->func);
- if (nvs->program_size + instsz >= nvs->program_alloc_size) {
- nvs->program_alloc_size *= 2;
- nvs->program = realloc(nvs->program,
- nvs->program_alloc_size * sizeof(uint32_t));
- }
-
- for (i=0; i<instsz; i++)
- nvs->program[nvs->program_current++] = hw_inst[i];
- nvs->program_size = nvs->program_current;
- return 1;
+ nvsFunc *shader = nvs->func;
+ struct _op_xlat *op;
+ unsigned int hw_inst[8];
+ int slot;
+ int instsz;
+ int i;
+
+ shader->inst = hw_inst;
+
+ /* Assemble this instruction */
+ if (!(op = shader->GetOPTXFromSOP(inst->op, &slot)))
+ return 0;
+ shader->InitInstruction(shader);
+ pass2_add_instruction(nvs, inst, op, slot);
+ if (last)
+ shader->SetLastInst(shader);
+
+ instsz = shader->GetOffsetNext(nvs->func);
+ if (nvs->program_size + instsz >= nvs->program_alloc_size) {
+ nvs->program_alloc_size *= 2;
+ nvs->program = realloc(nvs->program,
+ nvs->program_alloc_size *
+ sizeof(uint32_t));
+ }
+
+ for (i=0; i<instsz; i++)
+ nvs->program[nvs->program_current++] = hw_inst[i];
+ nvs->program_size = nvs->program_current;
+ return 1;
}
static GLboolean
GLboolean
nouveau_shader_pass2(nvsPtr nvs)
{
- struct pass2_rec *rec;
- int i;
-
- rec = calloc(1, sizeof(struct pass2_rec));
- for (i=0; i<NVS_MAX_TEMPS; i++)
- rec->temps[i] = -1;
- nvs->pass_rec = rec;
-
- /* Start off with allocating 4 uint32_t's for each inst, will be grown
- * if necessary..
- */
- nvs->program_alloc_size = nvs->mesa.vp.Base.NumInstructions * 4;
- nvs->program = calloc(nvs->program_alloc_size, sizeof(uint32_t));
- nvs->program_size = 0;
- nvs->program_current = 0;
-
- if (!pass2_translate(nvs, ((nvsSubroutine*)nvs->program_tree)->insn_head)) {
- free(nvs->program);
- nvs->program = NULL;
- return GL_FALSE;
- }
-
- /* Shrink allocated memory to only what we need */
- nvs->program = realloc(nvs->program, nvs->program_size * sizeof(uint32_t));
- nvs->program_alloc_size = nvs->program_size;
-
- nvs->translated = 1;
- nvs->on_hardware = 0;
-
- if (NOUVEAU_DEBUG & DEBUG_SHADERS) {
- fflush(stdout); fflush(stderr);
- fprintf(stderr, "----------------MESA PROGRAM target=%s, id=0x%x\n",
- _mesa_lookup_enum_by_nr(nvs->mesa.vp.Base.Target),
- nvs->mesa.vp.Base.Id);
- fflush(stdout); fflush(stderr);
- _mesa_print_program(&nvs->mesa.vp.Base);
- fflush(stdout); fflush(stderr);
- fprintf(stderr, "^^^^^^^^^^^^^^^^MESA PROGRAM\n");
- fflush(stdout); fflush(stderr);
- fprintf(stderr, "----------------NV PROGRAM\n");
- fflush(stdout); fflush(stderr);
- nvsDisasmHWShader(nvs);
- fflush(stdout); fflush(stderr);
- fprintf(stderr, "^^^^^^^^^^^^^^^^NV PROGRAM\n");
- fflush(stdout); fflush(stderr);
- }
-
- return GL_TRUE;
+ struct pass2_rec *rec;
+ int i;
+
+ rec = calloc(1, sizeof(struct pass2_rec));
+ for (i=0; i<NVS_MAX_TEMPS; i++)
+ rec->temps[i] = -1;
+ nvs->pass_rec = rec;
+
+ /* Start off with allocating 4 uint32_t's for each inst, will be grown
+ * if necessary..
+ */
+ nvs->program_alloc_size = nvs->mesa.vp.Base.NumInstructions * 4;
+ nvs->program = calloc(nvs->program_alloc_size, sizeof(uint32_t));
+ nvs->program_size = 0;
+ nvs->program_current = 0;
+
+ if (!pass2_translate(nvs,
+ ((nvsSubroutine*)nvs->program_tree)->insn_head)) {
+ free(nvs->program);
+ nvs->program = NULL;
+ return GL_FALSE;
+ }
+
+ /* Shrink allocated memory to only what we need */
+ nvs->program = realloc(nvs->program,
+ nvs->program_size * sizeof(uint32_t));
+ nvs->program_alloc_size = nvs->program_size;
+
+ nvs->translated = 1;
+ nvs->on_hardware = 0;
+
+ if (NOUVEAU_DEBUG & DEBUG_SHADERS) {
+ fflush(stdout); fflush(stderr);
+ fprintf(stderr, "-----------MESA PROGRAM target=%s, id=0x%x\n",
+ _mesa_lookup_enum_by_nr(
+ nvs->mesa.vp.Base.Target),
+ nvs->mesa.vp.Base.Id);
+ fflush(stdout); fflush(stderr);
+ _mesa_print_program(&nvs->mesa.vp.Base);
+ fflush(stdout); fflush(stderr);
+ fprintf(stderr, "^^^^^^^^^^^^^^^^MESA PROGRAM\n");
+ fflush(stdout); fflush(stderr);
+ fprintf(stderr, "----------------NV PROGRAM\n");
+ fflush(stdout); fflush(stderr);
+ nvsDisasmHWShader(nvs);
+ fflush(stdout); fflush(stderr);
+ fprintf(stderr, "^^^^^^^^^^^^^^^^NV PROGRAM\n");
+ fflush(stdout); fflush(stderr);
+ }
+
+ return GL_TRUE;
}