diff --git a/gpu/src/GrDrawTarget.cpp b/gpu/src/GrDrawTarget.cpp
index 82f94a3..7ea9ff2 100644
--- a/gpu/src/GrDrawTarget.cpp
+++ b/gpu/src/GrDrawTarget.cpp
@@ -18,93 +18,265 @@
 #include "GrDrawTarget.h"
 #include "GrGpuVertex.h"
 
-#define VERTEX_LAYOUT_ASSERTS \
-    GrAssert(!(vertexLayout & kTextFormat_VertexLayoutBit) ||           \
-             vertexLayout == kTextFormat_VertexLayoutBit);              \
-    GrAssert(!(vertexLayout & kSeparateTexCoord_VertexLayoutBit) ||     \
-             !(vertexLayout & kPositionAsTexCoord_VertexLayoutBit));
+// recursive helper for creating mask with all the tex coord bits set for
+// one stage
+template <int N>
+static int stage_mask_recur(int stage) {
+    return GrDrawTarget::StageTexCoordVertexLayoutBit(stage, N) | 
+           stage_mask_recur<N+1>(stage);
+}
+template<>
+static int stage_mask_recur<GrDrawTarget::kNumStages>(int) { return 0; }
 
-size_t GrDrawTarget::VertexSize(GrVertexLayout vertexLayout) {
-    VERTEX_LAYOUT_ASSERTS
-    if ((vertexLayout & kTextFormat_VertexLayoutBit)) {
-        return 2 * sizeof(GrGpuTextVertex);
-    } else {
-        size_t size = sizeof(GrPoint);
-        if (vertexLayout & kSeparateTexCoord_VertexLayoutBit) {
-            size += sizeof(GrPoint);
-        }
-        if (vertexLayout & kColor_VertexLayoutBit) {
-            size += sizeof(GrColor);
-        }
-        return size;
-    }
+// mask of all tex coord indices for one stage
+static int stage_tex_coord_mask(int stage) {
+    return stage_mask_recur<0>(stage);
 }
 
-int GrDrawTarget::VertexTexCoordOffset(GrVertexLayout vertexLayout) {
-    VERTEX_LAYOUT_ASSERTS
-    if ((vertexLayout & kTextFormat_VertexLayoutBit)) {
-        return sizeof(GrGpuTextVertex);
-    } else if (vertexLayout & kSeparateTexCoord_VertexLayoutBit) {
-        return sizeof(GrPoint);
-    } else if (vertexLayout & kPositionAsTexCoord_VertexLayoutBit) {
+// mask of all bits relevant to one stage
+static int stage_mask(int stage) {
+    return stage_tex_coord_mask(stage) | 
+           GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(stage);
+}
+
+// recursive helper for creating mask of with all bits set relevant to one
+// texture coordinate index
+template <int N>
+static int tex_coord_mask_recur(int texCoordIdx) {
+    return GrDrawTarget::StageTexCoordVertexLayoutBit(N, texCoordIdx) | 
+           tex_coord_mask_recur<N+1>(texCoordIdx);
+}
+template<>
+static int tex_coord_mask_recur<GrDrawTarget::kMaxTexCoords>(int) { return 0; }
+
+// mask of all bits relevant to one texture coordinate index
+static int tex_coord_idx_mask(int texCoordIdx) {
+    return tex_coord_mask_recur<0>(texCoordIdx);
+}
+
+bool check_layout(GrVertexLayout layout) {
+    // can only have 1 or 0 bits set for each stage.
+    for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
+        int stageBits = layout & stage_mask(s);
+        if (stageBits && !GrIsPow2(stageBits)) {
+            return false;
+        }
+    }
+    return true;
+}
+
+size_t GrDrawTarget::VertexSize(GrVertexLayout vertexLayout) {
+    GrAssert(check_layout(vertexLayout));
+    
+    size_t vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 
+                        sizeof(GrGpuTextVertex) :
+                        sizeof(GrPoint);
+
+    size_t size = vecSize; // position
+    for (int t = 0; t < kMaxTexCoords; ++t) {
+        if (tex_coord_idx_mask(t) & vertexLayout) {
+            size += vecSize;
+        }
+    }
+    if (vertexLayout & kColor_VertexLayoutBit) {
+        size += sizeof(GrColor);
+    }
+    return size;
+}
+
+int GrDrawTarget::VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout) {
+    GrAssert(check_layout(vertexLayout));
+    if (StagePosAsTexCoordVertexLayoutBit(stage) & vertexLayout) {
         return 0;
     }
+    int tcIdx = VertexTexCoordsForStage(stage, vertexLayout);
+    if (tcIdx >= 0) {
+        
+        int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 
+                                    sizeof(GrGpuTextVertex) :
+                                    sizeof(GrPoint);
+        int offset = vecSize; // position
+        // figure out how many tex coordinates are present and precede this one.
+        for (int t = 0; t < tcIdx; ++t) {
+            if (tex_coord_idx_mask(t) & vertexLayout) {
+                offset += vecSize;
+            }
+        }
+        return offset;
+    }
+
     return -1;
 }
 
 int  GrDrawTarget::VertexColorOffset(GrVertexLayout vertexLayout) {
-    VERTEX_LAYOUT_ASSERTS
+    GrAssert(check_layout(vertexLayout));
+    
     if (vertexLayout & kColor_VertexLayoutBit) {
-        if (vertexLayout & kSeparateTexCoord_VertexLayoutBit) {
-            return 2 * sizeof(GrPoint);
-        } else {
-            return sizeof(GrPoint);
+        int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 
+                                    sizeof(GrGpuTextVertex) :
+                                    sizeof(GrPoint);
+        int offset = vecSize; // position
+        // figure out how many tex coordinates are present and precede this one.
+        for (int t = 0; t < kMaxTexCoords; ++t) {
+            if (tex_coord_idx_mask(t) & vertexLayout) {
+                offset += vecSize;
+            }
         }
+        return offset;
     }
     return -1;
 }
 
-int GrDrawTarget::VertexSizeAndOffsets(GrVertexLayout vertexLayout,
-                                       int* texCoordOffset,
-                                       int* colorOffset) {
-    VERTEX_LAYOUT_ASSERTS
-
-    GrAssert(NULL != texCoordOffset);
+int GrDrawTarget::VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
+                                             int texCoordOffsetsByIdx[kMaxTexCoords],
+                                             int* colorOffset) {
+    GrAssert(check_layout(vertexLayout));
+    
+    GrAssert(NULL != texCoordOffsetsByIdx);
     GrAssert(NULL != colorOffset);
 
-    if ((vertexLayout & kTextFormat_VertexLayoutBit)) {
-        *texCoordOffset = sizeof(GrGpuTextVertex);
-        *colorOffset = 0;
-        return 2 * sizeof(GrGpuTextVertex);
-    } else {
-        size_t size = sizeof(GrPoint);
-        if (vertexLayout & kSeparateTexCoord_VertexLayoutBit) {
-            *texCoordOffset = sizeof(GrPoint);
-            size += sizeof(GrPoint);
-        } else if (vertexLayout & kPositionAsTexCoord_VertexLayoutBit) {
-            *texCoordOffset = 0;
+    int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 
+                                                    sizeof(GrGpuTextVertex) :
+                                                    sizeof(GrPoint);
+    int size = vecSize; // position
+    
+    for (int t = 0; t < kMaxTexCoords; ++t) {
+        if (tex_coord_idx_mask(t) & vertexLayout) {
+            texCoordOffsetsByIdx[t] = size;
+            size += vecSize;
         } else {
-            *texCoordOffset = -1;
+            texCoordOffsetsByIdx[t] = -1;
         }
-        if (vertexLayout & kColor_VertexLayoutBit) {
-            *colorOffset = size;
-            size += sizeof(GrColor);
-        } else {
-            *colorOffset = -1;
-        }
-        return size;
     }
+    if (kColor_VertexLayoutBit & vertexLayout) {
+        *colorOffset = size;
+        size += sizeof(GrColor);
+    } else {
+        *colorOffset = -1;
+    }
+    return size;
 }
 
-bool GrDrawTarget::VertexHasTexCoords(GrVertexLayout vertexLayout) {
-    return !!(vertexLayout & (kSeparateTexCoord_VertexLayoutBit   |
-                              kPositionAsTexCoord_VertexLayoutBit |
-                              kTextFormat_VertexLayoutBit));
+int GrDrawTarget::VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
+                                              int texCoordOffsetsByStage[kNumStages],
+                                              int* colorOffset) {
+    GrAssert(check_layout(vertexLayout));
+
+    GrAssert(NULL != texCoordOffsetsByStage);
+    GrAssert(NULL != colorOffset);
+    
+    int texCoordOffsetsByIdx[kMaxTexCoords];
+    int size = VertexSizeAndOffsetsByIdx(vertexLayout, 
+                                         texCoordOffsetsByIdx, 
+                                         colorOffset);
+    for (int s = 0; s < kNumStages; ++s) {
+        int tcIdx;
+        if (StagePosAsTexCoordVertexLayoutBit(s) & vertexLayout) {
+            texCoordOffsetsByStage[s] = 0;
+        } else if ((tcIdx = VertexTexCoordsForStage(s, vertexLayout)) >= 0) {
+            texCoordOffsetsByStage[s] = texCoordOffsetsByIdx[tcIdx];
+        } else {
+            texCoordOffsetsByStage[s] = -1;
+        }
+    }
+    return size;    
+}
+
+bool GrDrawTarget::VertexUsesStage(int stage, GrVertexLayout vertexLayout) {
+    GrAssert(stage < kNumStages);
+    GrAssert(check_layout(vertexLayout));
+    return !!(stage_mask(stage) & vertexLayout);
+}
+
+bool GrDrawTarget::VertexUsesTexCoordIdx(int coordIndex, 
+                                         GrVertexLayout vertexLayout) {
+    GrAssert(coordIndex < kMaxTexCoords);     
+    GrAssert(check_layout(vertexLayout));
+    return !!(tex_coord_idx_mask(coordIndex) & vertexLayout);
+}
+
+int GrDrawTarget::VertexTexCoordsForStage(int stage, GrVertexLayout vertexLayout) {
+    GrAssert(stage < kNumStages);
+    GrAssert(check_layout(vertexLayout));
+    int bit = vertexLayout & stage_tex_coord_mask(stage);
+    if (bit) {
+        // figure out which set of texture coordates is used
+        // bits are ordered T0S0, T0S1, T0S2, ..., T1S0, T1S1, ...
+        // and start at bit 0.
+        GR_STATIC_ASSERT(sizeof(GrVertexLayout) <= sizeof(uint32_t));
+        return (32 - Gr_clz(bit) - 1) / kNumStages;
+    }
+    return -1;
+}
+
+void GrDrawTarget::VertexLayoutUnitTest() {
+    // not necessarily exhaustive
+    static bool run;
+    if (!run) {
+        run = true;
+        for (int s = 0; s < kNumStages; ++s) {
+
+            GrAssert(!VertexUsesStage(s, 0));
+            GrAssert(-1 == VertexStageCoordOffset(s, 0));
+            GrVertexLayout stageMask = 0;
+            for (int t = 0; t < kMaxTexCoords; ++t) {
+                stageMask |= StageTexCoordVertexLayoutBit(s,t);
+            }
+            GrAssert(1 == kMaxTexCoords || !check_layout(stageMask));            
+            GrAssert(stage_tex_coord_mask(s) == stageMask);
+            stageMask |= StagePosAsTexCoordVertexLayoutBit(s);
+            GrAssert(stage_mask(s) == stageMask);
+            GrAssert(!check_layout(stageMask));
+        }
+        for (int t = 0; t < kMaxTexCoords; ++t) {
+            GrVertexLayout tcMask = 0;
+            GrAssert(!VertexUsesTexCoordIdx(t, 0));
+            for (int s = 0; s < kNumStages; ++s) {
+                tcMask |= StageTexCoordVertexLayoutBit(s,t);
+                GrAssert(VertexUsesStage(s, tcMask));
+                GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
+                GrAssert(VertexUsesTexCoordIdx(t, tcMask));
+                GrAssert(2*sizeof(GrPoint) == VertexSize(tcMask));
+                GrAssert(t == VertexTexCoordsForStage(s, tcMask));
+                for (int s2 = s + 1; s2 < kNumStages; ++s2) {
+                    GrAssert(-1 == VertexStageCoordOffset(s2, tcMask));
+                    GrAssert(!VertexUsesStage(s2, tcMask));
+                    GrAssert(-1 == VertexTexCoordsForStage(s2, tcMask));
+                    
+                    GrVertexLayout posAsTex = tcMask | StagePosAsTexCoordVertexLayoutBit(s2);
+                    GrAssert(0 == VertexStageCoordOffset(s2, posAsTex));
+                    GrAssert(VertexUsesStage(s2, posAsTex));
+                    GrAssert(2*sizeof(GrPoint) == VertexSize(posAsTex));
+                    GrAssert(-1 == VertexTexCoordsForStage(s2, posAsTex));
+                }
+                GrVertexLayout withColor = tcMask | kColor_VertexLayoutBit;
+                GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColor));
+                GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColor));
+            }
+            GrAssert(tex_coord_idx_mask(t) == tcMask);
+            GrAssert(check_layout(tcMask));
+            
+            int stageOffsets[kNumStages];
+            int colorOffset;
+            int size;
+            size = VertexSizeAndOffsetsByStage(tcMask, stageOffsets, &colorOffset);
+            GrAssert(2*sizeof(GrPoint) == size);
+            GrAssert(-1 == colorOffset);
+            for (int s = 0; s < kNumStages; ++s) {
+                GrAssert(VertexUsesStage(s, tcMask));
+                GrAssert(sizeof(GrPoint) == stageOffsets[s]);
+                GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
+            }
+        }
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 GrDrawTarget::GrDrawTarget() {
+#if GR_DEBUG
+    VertexLayoutUnitTest();
+#endif
     fReservedGeometry.fLocked = false;
 #if GR_DEBUG
     fReservedGeometry.fVertexCount  = ~0;
@@ -123,12 +295,14 @@
     return fClip;
 }
 
-void GrDrawTarget::setTexture(GrTexture* tex) {
-    fCurrDrawState.fTexture = tex;
+void GrDrawTarget::setTexture(int stage, GrTexture* tex) {
+    GrAssert(stage >= 0 && stage < kNumStages);
+    fCurrDrawState.fTextures[stage] = tex;
 }
 
-GrTexture* GrDrawTarget::currentTexture() const {
-    return fCurrDrawState.fTexture;
+GrTexture* GrDrawTarget::currentTexture(int stage) const {
+    GrAssert(stage >= 0 && stage < kNumStages);
+    return fCurrDrawState.fTextures[stage];
 }
 
 void GrDrawTarget::setRenderTarget(GrRenderTarget* target) {
@@ -139,21 +313,25 @@
     return fCurrDrawState.fRenderTarget;
 }
 
-void GrDrawTarget::concatViewMatrix(const GrMatrix& matrix) {
-    GrMatrix mv;
-    mv.setConcat(fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode], matrix);
-    this->loadMatrix(mv, kModelView_MatrixMode);
+void GrDrawTarget::setViewMatrix(const GrMatrix& m) {
+    fCurrDrawState.fViewMatrix = m;
 }
 
+void GrDrawTarget::concatViewMatrix(const GrMatrix& matrix) {
+    fCurrDrawState.fViewMatrix.preConcat(matrix);
+}
+
+// Can't this just return a const&
 void GrDrawTarget::getViewMatrix(GrMatrix* matrix) const {
-    *matrix = fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode];
+    *matrix = fCurrDrawState.fViewMatrix;
 }
 
 bool GrDrawTarget::getViewInverse(GrMatrix* matrix) const {
-    // Can we cache this somewhere?
+    // Mike:  Can we cache this somewhere? 
+    // Brian: Sure, do we use it often?
 
     GrMatrix inverse;
-    if (fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode].invert(&inverse)) {
+    if (fCurrDrawState.fViewMatrix.invert(&inverse)) {
         if (matrix) {
             *matrix = inverse;
         }
@@ -162,8 +340,14 @@
     return false;
 }
 
-void GrDrawTarget::setSamplerState(const GrSamplerState& state) {
-    fCurrDrawState.fSamplerState = state;
+void GrDrawTarget::setSamplerState(int stage, const GrSamplerState& state) {
+    GrAssert(stage >= 0 && stage < kNumStages);
+    fCurrDrawState.fSamplerStates[stage] = state;
+}
+
+void GrDrawTarget::setTextureMatrix(int stage, const GrMatrix& m) {
+    GrAssert(stage >= 0 && stage < kNumStages);
+    fCurrDrawState.fTextureMatrices[stage] = m;
 }
 
 void GrDrawTarget::setStencilPass(StencilPass pass) {
@@ -182,10 +366,6 @@
     fCurrDrawState.fFlagBits &= ~(bits);
 }
 
-void GrDrawTarget::loadMatrix(const GrMatrix& matrix, MatrixMode m) {
-    fCurrDrawState.fMatrixModeCache[m] = matrix;
-}
-
 void GrDrawTarget::setPointSize(float size) {
     fCurrDrawState.fPointSize = size;
 }
