Example #1
0
void
HdxShadowTask::_Sync(HdTaskContext* ctx)
{
    HD_TRACE_FUNCTION();
    HF_MALLOC_TAG_FUNCTION();

    // Extract the lighting context information from the task context
    GlfSimpleLightingContextRefPtr lightingContext;
    if (!_GetTaskContextData(ctx, HdxTokens->lightingContext, &lightingContext)) {
        return;
    }
    GlfSimpleShadowArrayRefPtr const shadows = lightingContext->GetShadows();

    _TaskDirtyState dirtyState;

    _GetTaskDirtyState(HdTokens->geometry, &dirtyState);


    // Check if the collection version has changed, if so, it means
    // that we should extract the new collections
    // from the lights in the render index, and then recreate the passes
    // required to render the shadow maps
    const bool collectionChanged = (_collectionVersion != dirtyState.collectionVersion);

    if ((dirtyState.bits & HdChangeTracker::DirtyParams) ||
        collectionChanged) {
        _collectionVersion = dirtyState.collectionVersion;

        // Extract the new shadow task params from exec
        HdxShadowTaskParams params;
        if (!_GetSceneDelegateValue(HdTokens->params, &params)) {
            return;
        }

        _depthBiasEnable = params.depthBiasEnable;
        _depthBiasConstantFactor = params.depthBiasConstantFactor;
        _depthBiasSlopeFactor = params.depthBiasSlopeFactor;
        _depthFunc = params.depthFunc;

        // XXX TODO: What to do about complexity?

        // We can now use the light information now
        // and create a pass for each
        _passes.clear();
        _renderPassStates.clear();

        HdSceneDelegate* delegate = GetDelegate();
        const HdRenderIndex &renderIndex = delegate->GetRenderIndex();
        
        // Extract the HD lights used to render the scene from the 
        // task context, we will use them to find out what
        // lights are dirty and if we need to update the
        // collection for shadows mapping
        
        // XXX: This is inefficient, need to be optimized
        SdfPathVector sprimPaths = renderIndex.GetSprimSubtree(
                                                   HdPrimTypeTokens->light,
                                                   SdfPath::AbsoluteRootPath());
        SdfPathVector lightPaths =
            HdxSimpleLightTask::ComputeIncludedLights(
                sprimPaths,
                params.lightIncludePaths,
                params.lightExcludePaths);
        
        HdxLightPtrConstVector lights;
        TF_FOR_ALL (it, lightPaths) {
             const HdxLight *light = static_cast<const HdxLight *>(
                                         renderIndex.GetSprim(
                                                 HdPrimTypeTokens->light, *it));

             if (light != nullptr) {
                lights.push_back(light);
            }
        }
        
        GlfSimpleLightVector const glfLights = lightingContext->GetLights();
        
        TF_VERIFY(lights.size() == glfLights.size());
        
        // Iterate through all lights and for those that have
        // shadows enabled we will extract the colection from 
        // the render index and create a pass that during execution
        // it will be used for generating each shadowmap
        for (size_t lightId = 0; lightId < glfLights.size(); lightId++) {
            
            if (!glfLights[lightId].HasShadow()) {
                continue;
            }
            
            // Extract the collection from the HD light
            VtValue vtShadowCollection =
                lights[lightId]->Get(HdxLightTokens->shadowCollection);
            const HdRprimCollection &col =
                vtShadowCollection.IsHolding<HdRprimCollection>() ?
                    vtShadowCollection.Get<HdRprimCollection>() : HdRprimCollection();

            // Creates a pass with the right geometry that will be
            // use during Execute phase to draw the maps
            HdRenderPassSharedPtr p = boost::make_shared<HdRenderPass>
                (&delegate->GetRenderIndex(), col);

            HdRenderPassShaderSharedPtr renderPassShadowShader
                (new HdRenderPassShader(HdxPackageRenderPassShadowShader()));
            HdRenderPassStateSharedPtr renderPassState
                (new HdRenderPassState(renderPassShadowShader));

            // Update the rest of the renderpass state parameters for this pass
            renderPassState->SetOverrideColor(params.overrideColor);
            renderPassState->SetWireframeColor(params.wireframeColor);
            renderPassState->SetLightingEnabled(false);
            
            // XXX : This can be removed when Hydra has support for 
            //       transparent objects.
            renderPassState->SetAlphaThreshold(1.0 /* params.alphaThreshold */);
            renderPassState->SetTessLevel(params.tessLevel);
            renderPassState->SetDrawingRange(params.drawingRange);
            renderPassState->SetCullStyle(params.cullStyle);
            
            _passes.push_back(p);
            _renderPassStates.push_back(renderPassState);
        }
    }
Example #2
0
void
HdxSelectionTask::_Sync(HdTaskContext* ctx)
{
    HD_TRACE_FUNCTION();

    SdfPath const& id = GetId();
    HdSceneDelegate* delegate = GetDelegate();
    HdRenderIndex& index = delegate->GetRenderIndex();
    HdChangeTracker& changeTracker = index.GetChangeTracker();
    HdDirtyBits bits = changeTracker.GetTaskDirtyBits(id);
    HdResourceRegistrySharedPtr const& resourceRegistry = 
        index.GetResourceRegistry();

    bool paramsChanged = bits & HdChangeTracker::DirtyParams;
    if (paramsChanged) {
        _GetSceneDelegateValue(HdTokens->params, &_params);
    }

    HdxSelectionTrackerSharedPtr sel;
    if (_GetTaskContextData(ctx, HdxTokens->selectionState, &sel)) {
        sel->Sync(&index);
    }

    if (sel && (paramsChanged || sel->GetVersion() != _lastVersion)) {

        _lastVersion = sel->GetVersion();
        VtIntArray offsets;
        VtIntArray values;
        
        _hasSelection = sel->GetSelectionOffsetBuffer(&index, &offsets);
        if (!_selOffsetBar) {

            HdBufferSpecVector offsetSpecs;
            offsetSpecs.emplace_back(HdxTokens->hdxSelectionBuffer,
                                     HdTupleType { HdTypeInt32, 1 });
            _selOffsetBar = resourceRegistry->AllocateSingleBufferArrayRange(
                                                /*role*/HdxTokens->selection,
                                                offsetSpecs);
        }

        if (!_selUniformBar) {
            HdBufferSpecVector uniformSpecs;
            uniformSpecs.emplace_back(HdxTokens->selColor,
                                      HdTupleType { HdTypeFloatVec4, 1 });
            uniformSpecs.emplace_back(HdxTokens->selLocateColor,
                                      HdTupleType { HdTypeFloatVec4, 1 });
            uniformSpecs.emplace_back(HdxTokens->selMaskColor,
                                      HdTupleType { HdTypeFloatVec4, 1 });
            _selUniformBar = resourceRegistry->AllocateUniformBufferArrayRange(
                                                /*role*/HdxTokens->selection,
                                                uniformSpecs);
        }

        //
        // Uniforms
        //
        HdBufferSourceSharedPtrVector uniformSources;
        uniformSources.push_back(HdBufferSourceSharedPtr(
                new HdVtBufferSource(HdxTokens->selColor,
                                     VtValue(_params.selectionColor))));
        uniformSources.push_back(HdBufferSourceSharedPtr(
                new HdVtBufferSource(HdxTokens->selLocateColor,
                                     VtValue(_params.locateColor))));
        uniformSources.push_back(HdBufferSourceSharedPtr(
                new HdVtBufferSource(HdxTokens->selMaskColor,
                                     VtValue(_params.maskColor))));
        resourceRegistry->AddSources(_selUniformBar, uniformSources);

        //
        // Offsets
        //
        HdBufferSourceSharedPtr offsetSource(
                new HdVtBufferSource(HdxTokens->hdxSelectionBuffer,
                                     VtValue(offsets)));
        resourceRegistry->AddSource(_selOffsetBar, offsetSource);
    }

    if (_params.enableSelection && _hasSelection) {
        (*ctx)[HdxTokens->selectionOffsets] = _selOffsetBar;
        (*ctx)[HdxTokens->selectionUniforms] = _selUniformBar;
    } else {
        (*ctx)[HdxTokens->selectionOffsets] = VtValue();
        (*ctx)[HdxTokens->selectionUniforms] = VtValue();
    }
}
Example #3
0
void
HdSurfaceShader::Sync()
{
    HD_TRACE_FUNCTION();
    HD_MALLOC_TAG_FUNCTION();
 
    // _delegate might be null in certain conditions including when
    // Hydra is using a fallback surface shader
    if (not _delegate) {
        return;  
    }

    SdfPath const& id = GetID();
    HdSceneDelegate* delegate = GetDelegate();
    HdResourceRegistry *resourceRegistry = &HdResourceRegistry::GetInstance();
    HdChangeTracker& changeTracker = 
                                delegate->GetRenderIndex().GetChangeTracker();
    HdChangeTracker::DirtyBits bits = changeTracker.GetShaderDirtyBits(id);

    if(bits & HdChangeTracker::DirtySurfaceShader) {
        _fragmentSource = delegate->GetSurfaceShaderSource(id);
        _geometrySource = delegate->GetDisplacementShaderSource(id);

        // XXX Forcing collections to be dirty to reload everything
        //     Something more efficient can be done here
        changeTracker.MarkAllCollectionsDirty();
    }

    if(bits & HdChangeTracker::DirtyParams) {
        HdBufferSourceVector sources;
        TextureDescriptorVector textures;
        _params = delegate->GetSurfaceShaderParams(id);
        TF_FOR_ALL(paramIt, _params) {
            if (paramIt->IsPrimvar()) {
                // skip -- maybe not necessary, but more memory efficient
                continue;
            } else if (paramIt->IsFallback()) {
                HdBufferSourceSharedPtr source(new HdVtBufferSource(
                                                   paramIt->GetName(),
                   delegate->GetSurfaceShaderParamValue(id, paramIt->GetName())));
                sources.push_back(source);
            } else if (paramIt->IsTexture()) {
                bool bindless = HdRenderContextCaps::GetInstance()
                                                        .bindlessTextureEnabled;
                // register bindless handle

                HdTextureResource::ID texID =
                    delegate->GetTextureResourceID(paramIt->GetConnection());

                HdTextureResourceSharedPtr texResource;
                {
                    HdInstance<HdTextureResource::ID, HdTextureResourceSharedPtr> texInstance;

                    std::unique_lock<std::mutex> regLock =
                        resourceRegistry->RegisterTextureResource(texID, &texInstance);

                    if (not TF_VERIFY(not texInstance.IsFirstInstance(), "%s",
                                      paramIt->GetConnection().GetText())) {
                        continue;
                    }

                    texResource = texInstance.GetValue();
                    if (not TF_VERIFY(texResource)) {
                        continue;
                    }
                }

                TextureDescriptor tex;
                tex.name = paramIt->GetName();

                if (texResource->IsPtex()) {
                    tex.type = TextureDescriptor::TEXTURE_PTEX_TEXEL;
                    tex.handle = bindless ? texResource->GetTexelsTextureHandle()
                                          : texResource->GetTexelsTextureId();
                    textures.push_back(tex);

                    if (bindless) {
                        HdBufferSourceSharedPtr source(new Hd_BindlessSamplerBufferSource(
                                                           tex.name,
                                                           GL_SAMPLER_2D_ARRAY,
                                                           tex.handle));
                        sources.push_back(source);
                    }

                    // layout

                    tex.name = TfToken(std::string(paramIt->GetName().GetText()) + "_layout");
                    tex.type = TextureDescriptor::TEXTURE_PTEX_LAYOUT;
                    tex.handle = bindless ? texResource->GetLayoutTextureHandle()
                                          : texResource->GetLayoutTextureId();
                    textures.push_back(tex);

                    if (bindless) {
                        HdBufferSourceSharedPtr source(new Hd_BindlessSamplerBufferSource(
                                                           tex.name,
                                                           GL_INT_SAMPLER_BUFFER,
                                                           tex.handle));
                        sources.push_back(source);
                    }

                } else {
                    tex.type = TextureDescriptor::TEXTURE_2D;
                    tex.handle = bindless ? texResource->GetTexelsTextureHandle()
                                          : texResource->GetTexelsTextureId();
                    tex.sampler =  texResource->GetTexelsSamplerId();
                    textures.push_back(tex);

                    if (bindless) {
                        HdBufferSourceSharedPtr source(new Hd_BindlessSamplerBufferSource(
                                                           tex.name,
                                                           GL_SAMPLER_2D,
                                                           tex.handle));
                        sources.push_back(source);
                    }
                }
            }
        }

        _textureDescriptors = textures;

        // return before allocation if it's empty.                                   
        if (sources.empty())                                                         
            return;

        // Allocate a new uniform buffer if not exists.
        if (not _paramArray) {
            // establish a buffer range
            HdBufferSpecVector bufferSpecs;
            TF_FOR_ALL(srcIt, sources) {
                (*srcIt)->AddBufferSpecs(&bufferSpecs);
            }