void
OsdD3D11DrawContext::_AppendPatchArray(
    unsigned int *indexBuffer, int *indexBase,
    unsigned int *levelBuffer, int *levelBase,
    FarPatchTables::PTable const & ptable, int patchSize,
    FarPatchTables::PtexCoordinateTable const & ptexTable,
    FarPatchTables::FVarDataTable const & fvarTable, int fvarDataWidth,
    OsdPatchDescriptor const & desc,
    int gregoryQuadOffsetBase)
{
    if (ptable.IsEmpty()) {
        return;
    }

    OsdPatchArray array;
    array.desc = desc;
    array.patchSize = patchSize;
    array.firstIndex = *indexBase;
    array.numIndices = ptable.GetSize();
    array.levelBase = *levelBase;
    array.gregoryQuadOffsetBase = gregoryQuadOffsetBase;

    int numSubPatches = 1;
    if (desc.type == OpenSubdiv::kTransitionRegular or
            desc.type == OpenSubdiv::kTransitionBoundary or
            desc.type == OpenSubdiv::kTransitionCorner) {
        int subPatchCounts[] = { 3, 4, 4, 4, 2 };
        numSubPatches = subPatchCounts[desc.pattern];
    }

    for (int subpatch = 0; subpatch < numSubPatches; ++subpatch) {
        array.desc.subpatch = subpatch;
        patchArrays.push_back(array);
    }

    memcpy(indexBuffer + array.firstIndex,
           ptable[0], array.numIndices * sizeof(unsigned int));
    *indexBase += array.numIndices;

    std::vector<unsigned int> levels;
    levels.reserve(ptable.GetSize());
    for (int i = 0; i < (int) ptable.GetMarkers().size()-1; ++i) {
        int numPrims = ptable.GetNumElements(i)/array.patchSize;
        for (int j = 0; j < numPrims; ++j) {
            levels.push_back(i);
        }
    }

    memcpy(levelBuffer + array.levelBase,
           &levels[0], levels.size() * sizeof(unsigned int));
    *levelBase += (int)levels.size();
}
void
OsdGLDrawContext::_AppendPatchArray(
        int *indexBase, int *levelBase,
        FarPatchTables::PTable const & ptable, int patchSize,
        FarPatchTables::PtexCoordinateTable const & ptexTable,
        FarPatchTables::FVarDataTable const & fvarTable, int fvarDataWidth,
        OsdPatchDescriptor const & desc, int gregoryQuadOffsetBase)
{
    if (ptable.IsEmpty()) {
        return;
    } 

    OsdPatchArray array;
    array.desc = desc;
    array.patchSize = patchSize;
    array.firstIndex = *indexBase;
    array.numIndices = ptable.GetSize();
    array.levelBase = *levelBase;
    array.gregoryQuadOffsetBase = gregoryQuadOffsetBase;

    int numSubPatches = 1;
    if (desc.type == OpenSubdiv::kTransitionRegular or
        desc.type == OpenSubdiv::kTransitionBoundary or
        desc.type == OpenSubdiv::kTransitionCorner) {
        int subPatchCounts[] = { 3, 4, 4, 4, 2 };
        numSubPatches = subPatchCounts[desc.pattern];
    }

    for (int subpatch = 0; subpatch < numSubPatches; ++subpatch) {
        array.desc.subpatch = subpatch;
        patchArrays.push_back(array);
    }

    glBufferSubData(GL_ELEMENT_ARRAY_BUFFER,
        array.firstIndex * sizeof(unsigned int),
        array.numIndices * sizeof(unsigned int),
        ptable[0]);
    *indexBase += array.numIndices;

    std::vector<unsigned char> levels;
    levels.reserve(ptable.GetSize());
    for (int i = 0; i < (int) ptable.GetMarkers().size()-1; ++i) {
        int numPrims = ptable.GetNumElements(i)/array.patchSize;
        for (int j = 0; j < numPrims; ++j) {
            levels.push_back(i);
        }
    }

#if defined(GL_ARB_texture_buffer_object) || defined(GL_VERSION_3_1)
    glBufferSubData(GL_TEXTURE_BUFFER,
                    array.levelBase * sizeof(unsigned char),
                    levels.size() * sizeof(unsigned char),
                    &levels[0]);
    *levelBase += (int)levels.size();
#endif

    if (ptexCoordinateTextureBuffer) {
#if defined(GL_ARB_texture_buffer_object) || defined(GL_VERSION_3_1)
        assert(ptexTable.size()/2 == levels.size());

        // populate ptex coordinates
        glBufferSubData(GL_ARRAY_BUFFER,
                        array.levelBase * sizeof(int) * 2,
                        (int)ptexTable.size() * sizeof(int),
                        &ptexTable[0]);
#endif
    }

    if (fvarDataTextureBuffer) {
#if defined(GL_ARB_texture_buffer_object) || defined(GL_VERSION_3_1)
        assert(fvarTable.size()/(fvarDataWidth*4) == levels.size());

        // populate fvar data
        glBufferSubData(GL_UNIFORM_BUFFER,
                        array.levelBase * sizeof(float) * fvarDataWidth*4,
                        (int)fvarTable.size() * sizeof(float),
                        &fvarTable[0]);
#endif
    }
}