nmesa->current_primitive = -1;
nouveauShaderInitFuncs(ctx);
- /* Install Mesa's fixed-function shader support */
- if (nmesa->screen->card->type >= NV_40) {
- ctx->_MaintainTnlProgram = GL_TRUE;
+ /* Install Mesa's fixed-function texenv shader support */
+ if (nmesa->screen->card->type >= NV_40)
ctx->_MaintainTexEnvProgram = GL_TRUE;
- }
/* Initialize the swrast */
_swrast_CreateContext( ctx );
#include "program.h"
#include "tnl/tnl.h"
+#include "shader/arbprogparse.h"
#include "nouveau_context.h"
#include "nouveau_shader.h"
return GL_TRUE;
}
+nouveauShader *
+nvsBuildTextShader(GLcontext *ctx, GLenum target, const char *text)
+{
+ nouveauShader *nvs;
+
+ nvs = CALLOC_STRUCT(_nouveauShader);
+ if (!nvs)
+ return NULL;
+
+ if (target == GL_VERTEX_PROGRAM_ARB) {
+ _mesa_init_vertex_program(ctx, &nvs->mesa.vp, GL_VERTEX_PROGRAM_ARB, 0);
+ _mesa_parse_arb_vertex_program(ctx,
+ GL_VERTEX_PROGRAM_ARB,
+ text,
+ strlen(text),
+ &nvs->mesa.vp);
+ } else if (target == GL_FRAGMENT_PROGRAM_ARB) {
+ _mesa_init_fragment_program(ctx, &nvs->mesa.fp, GL_VERTEX_PROGRAM_ARB, 0);
+ _mesa_parse_arb_fragment_program(ctx,
+ GL_FRAGMENT_PROGRAM_ARB,
+ text,
+ strlen(text),
+ &nvs->mesa.fp);
+ }
+
+ nouveau_shader_pass0_arb(ctx, nvs);
+ nouveau_shader_pass1(nvs);
+ nouveau_shader_pass2(nvs);
+
+ return nvs;
+}
+
+static void
+nvsBuildPassthroughVP(GLcontext *ctx)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ const char *vp_text =
+ "!!ARBvp1.0\n"
+ "OPTION ARB_position_invariant;"
+ ""
+ "MOV result.color, vertex.color;\n"
+ "MOV result.texcoord[0], vertex.texcoord[0];\n"
+ "MOV result.texcoord[1], vertex.texcoord[1];\n"
+ "MOV result.texcoord[2], vertex.texcoord[2];\n"
+ "MOV result.texcoord[3], vertex.texcoord[3];\n"
+ "MOV result.texcoord[4], vertex.texcoord[4];\n"
+ "MOV result.texcoord[5], vertex.texcoord[5];\n"
+ "MOV result.texcoord[6], vertex.texcoord[6];\n"
+ "MOV result.texcoord[7], vertex.texcoord[7];\n"
+ "END";
+
+ nmesa->passthrough_vp = nvsBuildTextShader(ctx,
+ GL_VERTEX_PROGRAM_ARB,
+ vp_text);
+}
+
void
nouveauShaderInitFuncs(GLcontext * ctx)
{
return;
}
+ /* Build a vertex program that simply passes through all attribs.
+ * Needed to do swtcl on nv40
+ */
+ nvsBuildPassthroughVP(ctx);
+
ctx->Const.VertexProgram.MaxNativeInstructions = nmesa->VPfunc.MaxInst;
ctx->Const.VertexProgram.MaxNativeAluInstructions = nmesa->VPfunc.MaxInst;
ctx->Const.VertexProgram.MaxNativeTexInstructions = nmesa->VPfunc.MaxInst;
printf(")");
}
-void
+static void
nvsDumpInstruction(nvsInstruction * inst, int slot, int lvl)
{
struct _opcode_info *opr = &ops[inst->op];
int i;
int slots=0;
int total_size=0;
+ /* t_vertex_generic dereferences a NULL pointer if we
+ * pass NULL as the vp transform...
+ */
+ const GLfloat ident_vp[16] = {
+ 1.0, 0.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0, 0.0,
+ 0.0, 0.0, 1.0, 0.0,
+ 0.0, 0.0, 0.0, 1.0
+ };
RENDERINPUTS_COPY(index, nmesa->render_inputs_bitset);
total_size+=attr_size[i];
}
}
+
nmesa->vertex_size=_tnl_install_attrs( ctx,
nmesa->vertex_attrs,
nmesa->vertex_attr_count,
- NULL, 0 );
+ ident_vp, 0 );
assert(nmesa->vertex_size==total_size*4);
/*
OUT_RING_CACHE(NV_VERTEX_ATTRIBUTE_TYPE_FLOAT|(size*0x10));
}
} else {
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DO_VERTICES, 1);
+ OUT_RING(0);
BEGIN_RING_CACHE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR0_POS,slots);
for(i=0;i<slots;i++)
{
RENDERINPUTS_COPY(nmesa->render_inputs_bitset, index);
nv10OutputVertexFormat(nmesa);
}
+
+ if (nmesa->screen->card->type >= NV_40) {
+ /* Ensure passthrough shader is being used, and mvp matrix
+ * is up to date
+ */
+ nvsUpdateShader(ctx, nmesa->passthrough_vp);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_IN_REG, 2);
+ OUT_RING_CACHE (0xff09); /*IN : POS, COL, TC0-7 */
+ OUT_RING_CACHE (0x3fc001); /*OUT: COL, TC0-7, POS implied */
+
+ /* Update texenv shader / user fragprog */
+ nvsUpdateShader(ctx, (nouveauShader*)ctx->FragmentProgram._Current);
+ }
}