nouveau: shader backend branching support for all cards that support it.
authorBen Skeggs <darktama@iinet.net.au>
Sat, 20 Jan 2007 22:13:27 +0000 (09:13 +1100)
committerBen Skeggs <darktama@iinet.net.au>
Sat, 20 Jan 2007 22:13:27 +0000 (09:13 +1100)
src/mesa/drivers/dri/nouveau/nouveau_shader.h
src/mesa/drivers/dri/nouveau/nv30_vertprog.c
src/mesa/drivers/dri/nouveau/nv40_fragprog.c
src/mesa/drivers/dri/nouveau/nv40_vertprog.c

index 08cb781..dfa53ca 100644 (file)
@@ -275,6 +275,11 @@ struct _nvsFunc {
    void                (*SetSaturate)          (nvsFunc *);
    void                (*SetLastInst)          (nvsFunc *);
 
+   void                (*SetBranchTarget)      (nvsFunc *, int addr);
+   void                (*SetBranchElse)        (nvsFunc *, int addr);
+   void                (*SetBranchEnd)         (nvsFunc *, int addr);
+   void                (*SetLoopParams)        (nvsFunc *, int cnt, int init, int inc);
+
    int         (*HasMergedInst)        (nvsFunc *);
    int         (*IsLastInst)           (nvsFunc *);
    int         (*GetOffsetNext)        (nvsFunc *);
index 6ba8e35..0b7678f 100644 (file)
@@ -48,6 +48,12 @@ NV30VPUpdateConst(GLcontext *ctx, nouveauShader *nvs, int id)
 /*****************************************************************************
  * Assembly routines
  */
+static void
+NV30VPSetBranchTarget(nvsFunc *shader, int addr)
+{
+       shader->inst[2] &= ~NV30_VP_INST_IADDR_MASK;
+       shader->inst[2] |= (addr << NV30_VP_INST_IADDR_SHIFT);
+}
 
 /*****************************************************************************
  * Disassembly routines
@@ -349,5 +355,6 @@ NV30VPInitShaderFuncs(nvsFunc * shader)
    shader->GetCondRegID                = NV30VPGetCondRegID;
 
    shader->GetBranch           = NV30VPGetBranch;
+   shader->SetBranchTarget     = NV30VPSetBranchTarget;
 }
 
index 3d58d6b..8bca6ae 100644 (file)
@@ -5,6 +5,47 @@
 unsigned int NVFP_TX_BOP_COUNT = 5;
 struct _op_xlat NVFP_TX_BOP[64];
 
+
+/*****************************************************************************
+ * Assembly routines
+ *     - These extend the NV30 routines, which are almost identical.  NV40
+ *       just has branching hacked into the instruction set.
+ */
+static void
+NV40FPSetBranchTarget(nvsFunc *shader, int addr)
+{
+       shader->inst[2] &= ~NV40_FP_OP_IADDR_MASK;
+       shader->inst[2] |= (addr << NV40_FP_OP_IADDR_SHIFT);
+}
+
+static void
+NV40FPSetBranchElse(nvsFunc *shader, int addr)
+{
+       shader->inst[2] &= ~NV40_FP_OP_ELSE_ID_MASK;
+       shader->inst[2] |= (addr << NV40_FP_OP_ELSE_ID_SHIFT);
+}
+
+static void
+NV40FPSetBranchEnd(nvsFunc *shader, int addr)
+{
+       shader->inst[3] &= ~NV40_FP_OP_END_ID_MASK;
+       shader->inst[3] |= (addr << NV40_FP_OP_END_ID_SHIFT);
+}
+
+static void
+NV40FPSetLoopParams(nvsFunc *shader, int count, int initial, int increment)
+{
+       shader->inst[2] &= ~(NV40_FP_OP_LOOP_COUNT_MASK |
+                            NV40_FP_OP_LOOP_INDEX_MASK |
+                            NV40_FP_OP_LOOP_INCR_MASK);
+       shader->inst[2] |= ((count     << NV40_FP_OP_LOOP_COUNT_SHIFT) |
+                           (initial   << NV40_FP_OP_LOOP_INDEX_SHIFT) |
+                           (increment << NV40_FP_OP_LOOP_INCR_SHIFT));
+}
+
+/*****************************************************************************
+ * Disassembly routines
+ */
 static struct _op_xlat *
 NV40FPGetOPTXRec(nvsFunc * shader, int merged)
 {
@@ -149,4 +190,8 @@ NV40FPInitShaderFuncs(nvsFunc * shader)
    shader->GetLoopCount                = NV40FPGetLoopCount;
    shader->GetLoopInitial      = NV40FPGetLoopInitial;
    shader->GetLoopIncrement    = NV40FPGetLoopIncrement;
+   shader->SetBranchTarget     = NV40FPSetBranchTarget;
+   shader->SetBranchElse       = NV40FPSetBranchElse;
+   shader->SetBranchEnd                = NV40FPSetBranchEnd;
+   shader->SetLoopParams       = NV40FPSetLoopParams;
 }
index 0493e18..1ba1cfd 100644 (file)
@@ -228,6 +228,15 @@ NV40VPSetSource(nvsFunc *shader, nvsRegister * src, int pos)
 }
 
 static void
+NV40VPSetBranchTarget(nvsFunc *shader, int addr)
+{
+       shader->inst[2] &= ~NV40_VP_INST_IADDRH_MASK;
+       shader->inst[2] |= ((addr & 0xf8) >> 3) << NV40_VP_INST_IADDRH_SHIFT;
+       shader->inst[3] &= ~NV40_VP_INST_IADDRL_MASK;
+       shader->inst[3] |= ((addr & 0x07) << NV40_VP_INST_IADDRL_SHIFT);
+}
+
+static void
 NV40VPInitInstruction(nvsFunc *shader)
 {
    unsigned int hwsrc = 0;
@@ -657,6 +666,7 @@ NV40VPInitShaderFuncs(nvsFunc * shader)
    shader->SetResult           = NV40VPSetResult;
    shader->SetSource           = NV40VPSetSource;
    shader->SetLastInst         = NV40VPSetLastInst;
+   shader->SetBranchTarget     = NV40VPSetBranchTarget;
 
    shader->HasMergedInst       = NV40VPHasMergedInst;
    shader->GetOpcodeHW         = NV40VPGetOpcodeHW;