Example #1
0
HdStGLSLProgramSharedPtr
HdStGLSLProgram::GetComputeProgram(
        TfToken const &shaderToken,
        HdStResourceRegistry *resourceRegistry)
{
    // Find the program from registry
    HdInstance<HdStGLSLProgram::ID, HdStGLSLProgramSharedPtr> programInstance;

    std::unique_lock<std::mutex> regLock = 
        resourceRegistry->RegisterGLSLProgram(
            HdStGLSLProgram::ComputeHash(shaderToken), &programInstance);

    if (programInstance.IsFirstInstance()) {
        // if not exists, create new one
        HdStGLSLProgramSharedPtr newProgram(
            new HdStGLSLProgram(HdTokens->computeShader));

        GlfGLSLFX glslfx(HdStPackageComputeShader());
        std::string version = "#version 430\n";
        if (!newProgram->CompileShader(
                GL_COMPUTE_SHADER, version + glslfx.GetSource(shaderToken))) {
            TF_CODING_ERROR("Fail to compile " + shaderToken.GetString());
            return HdStGLSLProgramSharedPtr();
        }
        if (!newProgram->Link()) {
            TF_CODING_ERROR("Fail to link " + shaderToken.GetString());
            return HdStGLSLProgramSharedPtr();
        }
        programInstance.SetValue(newProgram);
    }
    return programInstance.GetValue();
}
void
HdStExtComputation::Sync(HdSceneDelegate *sceneDelegate,
                         HdRenderParam   *renderParam,
                         HdDirtyBits     *dirtyBits)
{
    HD_TRACE_FUNCTION();
    HF_MALLOC_TAG_FUNCTION();
    TF_DEBUG(HD_EXT_COMPUTATION_UPDATED).Msg(
        "HdStExtComputation::Sync %s\n", GetId().GetText());

    HdExtComputation::_Sync(sceneDelegate, renderParam, dirtyBits);

    // We only commit GPU resources when directly executing a GPU computation
    // or when aggregating inputs for a downstream computation.
    if (GetGpuKernelSource().empty() && !IsInputAggregation()) {
        return;
    }

    HdRenderIndex &renderIndex = sceneDelegate->GetRenderIndex();
    HdStResourceRegistrySharedPtr const & resourceRegistry =
        boost::dynamic_pointer_cast<HdStResourceRegistry>(
                              renderIndex.GetResourceRegistry());

    HdBufferSourceVector inputs;
    for (TfToken const & inputName: GetSceneInputNames()) {
        VtValue inputValue = sceneDelegate->GetExtComputationInput(
                                                GetId(), inputName);
        size_t arraySize =
            inputValue.IsArrayValued() ? inputValue.GetArraySize() : 1;
        HdBufferSourceSharedPtr inputSource = HdBufferSourceSharedPtr(
                    new HdVtBufferSource(inputName, inputValue, arraySize));
        if (inputSource->IsValid()) {
            inputs.push_back(inputSource);
        } else {
            TF_WARN("Unsupported type %s for source %s in extComputation %s.",
                    inputValue.GetType().GetTypeName().c_str(),
                    inputName.GetText(), GetId().GetText());
        }
    }

    _inputRange.reset();
    if (!inputs.empty()) {
        if (_IsEnabledSharedExtComputationData() && IsInputAggregation()) {
            uint64_t inputId = _ComputeSharedComputationInputId(0, inputs);

            HdInstance<uint64_t, HdBufferArrayRangeSharedPtr> barInstance;
            std::unique_lock<std::mutex> regLog =
                resourceRegistry->RegisterExtComputationDataRange(inputId,
                                                                  &barInstance);

            if (barInstance.IsFirstInstance()) {
                // Allocate the first buffer range for this input key
                _inputRange = _AllocateComputationDataRange(inputs,
                                                            resourceRegistry);
                barInstance.SetValue(_inputRange);

                TF_DEBUG(HD_SHARED_EXT_COMPUTATION_DATA).Msg(
                    "Allocated shared ExtComputation buffer range: %s: %p\n",
                    GetId().GetText(), (void *)_inputRange.get());
            } else {
                // Share the existing buffer range for this input key
                _inputRange = barInstance.GetValue();

                TF_DEBUG(HD_SHARED_EXT_COMPUTATION_DATA).Msg(
                    "Reused shared ExtComputation buffer range: %s: %p\n",
                    GetId().GetText(), (void *)_inputRange.get());
            }

        } else {
            // We're not sharing, so go ahead and allocate new buffer range.
            _inputRange = _AllocateComputationDataRange(inputs,
                                                        resourceRegistry);
        }

        // Make sure that we also release any stale input range data
        renderIndex.GetChangeTracker().SetGarbageCollectionNeeded();
    }
}