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, ¶ms)) { 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); } }
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(); } }
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); }