Ejemplo n.º 1
0
void
HdDirtyList::_UpdateIDs(SdfPathVector* ids, HdDirtyBits mask)
{
    HD_TRACE_FUNCTION();
    HD_PERF_COUNTER_INCR(HdPerfTokens->dirtyListsRebuilt);

    
    const SdfPathVector &paths        = _renderIndex.GetRprimIds();
    const SdfPathVector &includePaths = _collection.GetRootPaths();
    const SdfPathVector &excludePaths = _collection.GetExcludePaths();

    _FilterParam filterParam = {_collection, _renderIndex, mask};

    HdPrimGather gather;

    gather.PredicatedFilter(paths,
                  includePaths,
                  excludePaths,
                  _DirtyListFilterPredicate,
                  &filterParam,
                  ids);
}
Ejemplo n.º 2
0
void
HdBufferArray::RemoveUnusedRanges()
{
    // Local copy, because we don't want to perform atomic ops
    size_t numRanges = _rangeCount;
    size_t idx = 0;
    while (idx < numRanges) {
        if (_rangeList[idx].expired()) {
            // Order of range objects doesn't matter so use range at end to fill gap.
            _rangeList[idx] = _rangeList[numRanges - 1];
            _rangeList[numRanges - 1].reset();
            --numRanges;

            HD_PERF_COUNTER_INCR(_garbageCollectionPerfToken);
            // Don't increament idx as we need to check the value we just moved into the slot.
        } else {
            ++idx;
        }
    }

    // Now update atomic copy with new size.
    _rangeCount = numRanges;
}
HdBasisCurvesTopology::HdBasisCurvesTopology(const TfToken &curveType,
                                             const TfToken &curveBasis,
                                             const TfToken &curveWrap,
                                             const VtIntArray &curveVertexCounts,
                                             const VtIntArray &curveIndices)
  : HdTopology()
  , _curveType(curveType)
  , _curveBasis(curveBasis)
  , _curveWrap(curveWrap)
  , _curveVertexCounts(curveVertexCounts)
  , _curveIndices(curveIndices)
{
    if (_curveType != HdTokens->linear && _curveType != HdTokens->cubic){
        TF_WARN("Curve type must be 'linear' or 'cubic'.  Got: '%s'", _curveType.GetText());
        _curveType = HdTokens->linear;
        _curveBasis = TfToken();
    }
    if (curveBasis == HdTokens->linear && curveType == HdTokens->cubic){
        TF_WARN("Basis 'linear' passed in to 'cubic' curveType.  Converting 'curveType' to 'linear'.");
        _curveType = HdTokens->linear;
        _curveBasis = TfToken();
    }
    HD_PERF_COUNTER_INCR(HdPerfTokens->basisCurvesTopology);
}
Ejemplo n.º 4
0
    TF_FOR_ALL(drawItemIt, _drawItemInstances) {
        if(not (*drawItemIt)->IsVisible()) {
            continue;
        }

        HdDrawItem const * drawItem = (*drawItemIt)->GetDrawItem();

        ++numItemsDrawn;
        if (TfDebug::IsEnabled(HD_DRAWITEM_DRAWN)) {
            std::stringstream ss;
            ss << *drawItem;
            TF_DEBUG(HD_DRAWITEM_DRAWN).Msg("DRAW: \n%s\n", 
                    ss.str().c_str());
        }

        //
        // index buffer data
        //
        HdBufferArrayRangeSharedPtr const & indexBar =
            drawItem->GetTopologyRange();
        if (indexBar and (not indexBar->IsAggregatedWith(indexBarCurrent))) {
            binder.UnbindBufferArray(indexBarCurrent);
            binder.BindBufferArray(indexBar);
            indexBarCurrent = indexBar;
        }

        //
        // per-face buffer data (fetched through ElementID in primitiveParam)
        //
        HdBufferArrayRangeSharedPtr const & elementBar =
            drawItem->GetElementPrimVarRange();
        if (elementBar and (not elementBar->IsAggregatedWith(elementBarCurrent))) {
            binder.UnbindBufferArray(elementBarCurrent);
            binder.BindBufferArray(elementBar);
            elementBarCurrent = elementBar;
        }

        //
        // vertex attrib buffer data
        //
        HdBufferArrayRangeSharedPtr const & vertexBar =
            drawItem->GetVertexPrimVarRange();

        if (vertexBar and (not vertexBar->IsAggregatedWith(vertexBarCurrent))) {
            binder.UnbindBufferArray(vertexBarCurrent);
            binder.BindBufferArray(vertexBar);
            vertexBarCurrent = vertexBar;
        }

        //
        // constant (uniform) buffer data
        //
        HdBufferArrayRangeSharedPtr const & constantBar =
            drawItem->GetConstantPrimVarRange();
        if (constantBar and (not constantBar->IsAggregatedWith(constantBarCurrent))) {
            binder.UnbindConstantBuffer(constantBarCurrent);
            binder.BindConstantBuffer(constantBar);
            constantBarCurrent = constantBar;
        }

        //
        // facevarying buffer data
        //
        HdBufferArrayRangeSharedPtr const & fvarBar =
            drawItem->GetFaceVaryingPrimVarRange();
        if (fvarBar and (not fvarBar->IsAggregatedWith(fvarBarCurrent))) {
            binder.UnbindBufferArray(fvarBarCurrent);
            binder.BindBufferArray(fvarBar);
            fvarBarCurrent = fvarBar;
        }

        //
        // instance buffer data
        //
        int instancerNumLevels = drawItem->GetInstancePrimVarNumLevels();
        int instanceIndexWidth = instancerNumLevels + 1;
        for (int i = 0; i < instancerNumLevels; ++i) {
            HdBufferArrayRangeSharedPtr const & instanceBar =
                drawItem->GetInstancePrimVarRange(i);
            if (instanceBar) {
                if (static_cast<size_t>(i) >= instanceBarCurrents.size()) {
                    instanceBarCurrents.push_back(instanceBar);
                    binder.BindInstanceBufferArray(instanceBar, i);
                } else if (not instanceBar->IsAggregatedWith(
                               instanceBarCurrents[i])) {
                    binder.UnbindInstanceBufferArray(instanceBarCurrents[i], i);
                    binder.BindInstanceBufferArray(instanceBar, i);
                    instanceBarCurrents[i] = instanceBar;
                }
            }
        }

        //
        // instance index indirection buffer
        //
        HdBufferArrayRangeSharedPtr const & instanceIndexBar =
            drawItem->GetInstanceIndexRange();
        if (instanceIndexBar and (not instanceIndexBar->IsAggregatedWith(instanceIndexBarCurrent))) {
            binder.UnbindBufferArray(instanceIndexBarCurrent);
            binder.BindBufferArray(instanceIndexBar);
            instanceIndexBarCurrent = instanceIndexBar;
        }

        //
        // shader buffer
        //
        HdBufferArrayRangeSharedPtr const & shaderBar =
            renderPassState->GetOverrideShader()
                ? HdBufferArrayRangeSharedPtr()
                : drawItem->GetSurfaceShader()->GetShaderData();
        // shaderBar isn't needed when the surfaceShader is overriden
        if (shaderBar and (not shaderBar->IsAggregatedWith(shaderBarCurrent))) {
            if (shaderBarCurrent) {
                binder.UnbindBuffer(HdTokens->surfaceShaderParams,
                                    shaderBarCurrent->GetResource());
            }
            binder.BindBuffer(HdTokens->surfaceShaderParams,
                              shaderBar->GetResource());
            shaderBarCurrent = shaderBar;
        }

        //
        // shader textures
        //
        if (not hasOverrideShader) {
            drawItem->GetSurfaceShader()->BindResources(binder, programId);
        }

        /*
          Drawing coord is a unified cursor which locates a subset of
          aggregated buffer in GPU. The primary role of drawing coord is
          to provide a way to access buffers from glsl shader code.

          We have some aggregated buffers of different granularities.
          They are associated to class/variability specifiers in GL/prman spec.
          ( see http://renderman.pixar.com/view/Appnote22 )

          |   | drawing coord |  hd buffer   |     OpenGL     |     PRMan      |
          ----------------------------------------------------------------------
          | 0 | ModelDC       |  (reserved)  |    uniform     |    constant    |
          | 1 | ConstantDC    |  constantBar |    uniform     |    constant    |
          | 2 | ElementDC     |  elementBar  |       (*)      |    uniform     |
          | 3 | PrimitiveDC   |  indexBar    | gl_PrimitiveID |       (*)      |
          | 4 | FVarDC        |  fvarBar     | gl_PrimitiveID |    facevarying |
          | 5 | InstanceIndex |  inst-idxBar | (gl_InstanceID)|      n/a       |
          | 7 | ShaderDC      |  shaderBar   |    uniform     |                |
          | 8 | InstanceDC[0] |  instanceBar | (gl_InstanceID)|    constant    |
          | 9 | InstanceDC[1] |  instanceBar | (gl_InstanceID)|    constant    |
          |...| ...           |  instanceBar | (gl_InstanceID)|    constant    |
          ----------------------------------------------------------------------
          | - | VertexBase    |  vertexBar   |  gl_VertexID   | vertex/varying |

          We put these offsets into 3 variables,
           - ivec4 drawingCoord0  (ModelDC - PrimitiveDC)
           - ivec3 drawingCoord1  (FVarDC - ShaderDC)
           - int[] drawingCoordI  (InstanceDC)
          so that the shaders can access any of these aggregated data.

          (*) primitiveParam buffer can be used to reinterpret GL-primitive
              ID back to element ID.

         */

        int vertexOffset = 0;
        int vertexCount = 0;
        if (vertexBar) {
            vertexOffset = vertexBar->GetOffset();
            vertexCount = vertexBar->GetNumElements();
        }

        //
        // Get parameters from our buffer range objects to
        // allow drawing to access the correct elements from
        // aggregated buffers.
        //
        int numIndicesPerPrimitive = geometricShader->GetPrimitiveIndexSize();
        int indexCount = indexBar ? indexBar->GetNumElements() * numIndicesPerPrimitive : 0;
        int firstIndex = indexBar ? indexBar->GetOffset() * numIndicesPerPrimitive : 0;
        int baseVertex = vertexOffset;
        int instanceCount = instanceIndexBar
            ? instanceIndexBar->GetNumElements()/instanceIndexWidth : 1;

        // if delegate fails to get vertex primvars, it could be empty.
        // skip the drawitem to prevent drawing uninitialized vertices.
        if (vertexCount == 0) continue;

        // update standalone uniforms
        int drawingCoord0[4] = {
            0, // reserved for modelBar
            constantBar ? constantBar->GetIndex()  : 0,
            elementBar  ? elementBar->GetOffset()  : 0,
            indexBar    ? indexBar->GetOffset()    : 0
        };
        int drawingCoord1[3] = {
            fvarBar          ? fvarBar->GetOffset()          : 0,
            instanceIndexBar ? instanceIndexBar->GetOffset() : 0,
            shaderBar        ? shaderBar->GetIndex()         : 0
        };
        binder.BindUniformi(HdTokens->drawingCoord0, 4, drawingCoord0);
        binder.BindUniformi(HdTokens->drawingCoord1, 3, drawingCoord1);

        // instance coordinates
        std::vector<int> instanceDrawingCoords(instancerNumLevels);
        for (int i = 0; i < instancerNumLevels; ++i) {
            instanceDrawingCoords[i] = instanceBarCurrents[i]
                ? instanceBarCurrents[i]->GetOffset() : 0;
        }
        if (instancerNumLevels > 0) {
            binder.BindUniformArrayi(HdTokens->drawingCoordI,
                                     instancerNumLevels, &instanceDrawingCoords[0]);
        }

        if (indexCount > 0 and indexBar) {
            glDrawElementsInstancedBaseVertex(
                geometricShader->GetPrimitiveMode(),
                indexCount,
                GL_UNSIGNED_INT, // GL_INT is invalid: indexBar->GetResource(HdTokens->indices)->GetGLDataType(),
                (void *)(firstIndex * sizeof(GLuint)),
                instanceCount,
                baseVertex);
        } else if (vertexCount > 0) {
            glDrawArraysInstanced(
                geometricShader->GetPrimitiveMode(),
                baseVertex,
                vertexCount,
                instanceCount);
        }

        if (not hasOverrideShader) {
            drawItem->GetSurfaceShader()->UnbindResources(binder, programId);
        }

        HD_PERF_COUNTER_INCR(HdPerfTokens->drawCalls);
    }
Ejemplo n.º 5
0
void
HdRenderPass::_PrepareCommandBuffer(
    HdRenderPassStateSharedPtr const &renderPassState)
{
    HD_TRACE_FUNCTION();
    // ------------------------------------------------------------------- #
    // SCHEDULE PREPARATION
    // ------------------------------------------------------------------- #
    // We know what must be drawn and that the stream needs to be updated, 
    // so iterate over each prim, cull it and schedule it to be drawn.

    HdChangeTracker& tracker = _renderIndex->GetChangeTracker();
    HdRenderContextCaps const &caps = HdRenderContextCaps::GetInstance();

    const int
       collectionVersion = tracker.GetCollectionVersion(_collection.GetName());

    const int shaderBindingsVersion = tracker.GetShaderBindingsVersion();

    const bool 
       skipCulling = TfDebug::IsEnabled(HD_DISABLE_FRUSTUM_CULLING) ||
           (caps.multiDrawIndirectEnabled
               && Hd_IndirectDrawBatch::IsEnabledGPUFrustumCulling());

    const bool 
       cameraChanged = true,
       extentsChanged = true,
       collectionChanged = _collectionChanged 
                           || (_collectionVersion != collectionVersion);

    const bool cullingStateJustChanged = 
                                    skipCulling != _lastCullingDisabledState;
    _lastCullingDisabledState = skipCulling;

    bool freezeCulling = TfDebug::IsEnabled(HD_FREEZE_CULL_FRUSTUM);

    // Bypass freezeCulling if  collection has changed
    // Need to add extents in here as well, once they are
    // hooked up to detect proper change.
    if(collectionChanged || cullingStateJustChanged) {
        freezeCulling = false;
    }

    // Now either the collection is dirty or culling needs to be applied.
    if (collectionChanged) {
        HD_PERF_COUNTER_INCR(HdPerfTokens->collectionsRefreshed);
        TF_DEBUG(HD_COLLECTION_CHANGED).Msg("CollectionChanged: %s "
                                            "version: %d -> %d\n", 
                                             _collection.GetName().GetText(),
                                             _collectionVersion,
                                             collectionVersion);

        HdRenderIndex::HdDrawItemView items = 
                                       _renderIndex->GetDrawItems(_collection);

        // This loop will extract the tags and bucket the geometry in 
        // the different command buffers.
        size_t itemCount = 0;
        _cmdBuffers.clear();
        for (HdRenderIndex::HdDrawItemView::iterator it = items.begin();
                                                    it != items.end(); it++ ) {
            _cmdBuffers[it->first].SwapDrawItems(&it->second, 
                                                 shaderBindingsVersion);
            itemCount += _cmdBuffers[it->first].GetTotalSize();
        }

        _collectionVersion = collectionVersion;
        _collectionChanged = false;
        HD_PERF_COUNTER_SET(HdTokens->totalItemCount, itemCount);
    } else {
        // validate command buffer to not include expired drawItems,
        // which could be produced by migrating BARs at the new repr creation.
        for (_HdCommandBufferMap::iterator it  = _cmdBuffers.begin(); 
                                           it != _cmdBuffers.end(); it++) {
            it->second.RebuildDrawBatchesIfNeeded(shaderBindingsVersion);
        }
    }

    if(skipCulling) {
        // Since culling state is stored across renders,
        // we need to update all items visible state
        for (_HdCommandBufferMap::iterator it = _cmdBuffers.begin(); 
                                           it != _cmdBuffers.end(); it++) {
            it->second.SyncDrawItemVisibility(tracker.GetVisibilityChangeCount());
        }

        TF_DEBUG(HD_DRAWITEMS_CULLED).Msg("CULLED: skipped\n");
    }
    else {
        // XXX: this process should be moved to Hd_DrawBatch::PrepareDraw
        //      to be consistent with GPU culling.
        if((!freezeCulling)
            && (collectionChanged || cameraChanged || extentsChanged)) {
            // Re-cull the command buffer. 
            for (_HdCommandBufferMap::iterator it  = _cmdBuffers.begin(); 
                                               it != _cmdBuffers.end(); it++) {
                it->second.FrustumCull(renderPassState->GetCullMatrix());
            }
        }

        for (_HdCommandBufferMap::iterator it  = _cmdBuffers.begin(); 
                                           it != _cmdBuffers.end(); it++) {
            TF_DEBUG(HD_DRAWITEMS_CULLED).Msg("CULLED: %zu drawItems\n", 
                                                 it->second.GetCulledSize());
        }
    }
}