Get nv10_swtcl.c working enough for glxgears on NV40.
authorBen Skeggs <darktama@iinet.net.au>
Sat, 16 Dec 2006 12:32:11 +0000 (12:32 +0000)
committerBen Skeggs <darktama@iinet.net.au>
Sat, 16 Dec 2006 12:32:11 +0000 (12:32 +0000)
src/mesa/drivers/dri/nouveau/nouveau_context.c
src/mesa/drivers/dri/nouveau/nouveau_context.h
src/mesa/drivers/dri/nouveau/nouveau_shader.c
src/mesa/drivers/dri/nouveau/nouveau_shader.h
src/mesa/drivers/dri/nouveau/nv10_swtcl.c

index 1e25062c1dbffd784f25c5e76a02fa8d04b87638..22c1f5887427a20986b3c8f93719835f8b9d6285 100644 (file)
@@ -187,11 +187,9 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual,
        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 );
index 211d4e0a6d3ab72631d94cd8fa230c8de2334667..d7730bd79649d83df2ed2d81f4e6b59bed6f59f5 100644 (file)
@@ -144,6 +144,7 @@ typedef struct nouveau_context {
        nvsFunc FPfunc;
        nouveauShader *current_fragprog;
        nouveauShader *current_vertprog;
+       nouveauShader *passthrough_vp;
 
        nouveauScreenRec *screen;
        drm_nouveau_sarea_t *sarea;
index e3082ebc69beffc3ee6c404e3b2be1789aa833d8..9a09f43d5819fd8a41b78b2304d61e9c93e054ff 100644 (file)
@@ -37,6 +37,7 @@
 
 #include "program.h"
 #include "tnl/tnl.h"
+#include "shader/arbprogparse.h"
 
 #include "nouveau_context.h"
 #include "nouveau_shader.h"
@@ -161,6 +162,63 @@ nvsUpdateShader(GLcontext *ctx, nouveauShader *nvs)
    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)
 {
@@ -184,6 +242,11 @@ 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;
@@ -446,7 +509,7 @@ nvsDumpReg(nvsInstruction * inst, nvsRegister * reg)
       printf(")");
 }
 
-void
+static void
 nvsDumpInstruction(nvsInstruction * inst, int slot, int lvl)
 {
    struct _opcode_info *opr = &ops[inst->op];
index dce2e23f46e7d1f4f60a81d347f1c651499c3ce6..652775e6c239fc7f699413a5f05bbef4af144d11 100644 (file)
@@ -349,6 +349,9 @@ nvsSwizzle(nvsRegister reg, nvsSwzComp x, nvsSwzComp y,
 
 extern GLboolean nvsUpdateShader(GLcontext *ctx, nouveauShader *nvs);
 extern void nvsDisasmHWShader(nvsPtr);
+extern void nvsDumpFragmentList(nvsFragmentList *f, int lvl);
+extern nouveauShader *nvsBuildTextShader(GLcontext *ctx, GLenum target,
+                                        const char *text);
 
 extern void NV20VPInitShaderFuncs(nvsFunc *);
 extern void NV30VPInitShaderFuncs(nvsFunc *);
index 07b3e666df1560f3a069cc6c4d3d3c6900a80465..37d9f001d1246b1fc8bcea718e74f7fae5252f8d 100644 (file)
@@ -366,6 +366,15 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa)
        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);
 
@@ -425,10 +434,11 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa)
                        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);
 
        /* 
@@ -467,6 +477,8 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa)
                        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++)
                {
@@ -496,6 +508,19 @@ static void nv10ChooseVertexState( GLcontext *ctx )
                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);
+       }
 }