carb/profiler/IProfiler.h

File members: carb/profiler/IProfiler.h

// Copyright (c) 2018-2024, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
//

#pragma once

#include "../Interface.h"

#include <atomic>
#include <cstdint>

namespace carb
{

namespace profiler
{

constexpr uint64_t kCaptureMaskNone = 0;
constexpr uint64_t kCaptureMaskAll = (uint64_t)-1;
constexpr uint64_t kCaptureMaskDefault = uint64_t(1);
constexpr uint64_t kCaptureMaskProfiler = uint64_t(1) << 63;

using StaticStringType = size_t;

constexpr StaticStringType kInvalidStaticString = StaticStringType(0);

using ZoneId = size_t;

constexpr ZoneId kUnknownZoneId = 0;

constexpr ZoneId kNoZoneId = ZoneId(-1);

enum class FlowType : uint8_t
{
    Begin,
    End
};

enum class InstantType : uint8_t
{
    Thread,
    Process
};

using GpuContextId = uint8_t;

constexpr uint8_t kInvalidGpuContextId = (uint8_t)-1;

using LockableId = uint32_t;

constexpr uint32_t kInvalidLockableId = (uint32_t)-1;

enum class LockableOperationType : uint8_t
{
    BeforeLock,
    AfterLock,
    AfterUnlock,
    AfterSuccessfulTryLock,
    BeforeLockShared,
    AfterLockShared,
    AfterUnlockShared,
    AfterSuccessfulTryLockShared,
};

using MaskCallbackFn = void (*)(uint64_t);

struct IProfiler
{
    CARB_PLUGIN_INTERFACE("carb::profiler::IProfiler", 1, 4)

    void(CARB_ABI* startup)();

    void(CARB_ABI* shutdown)();

    uint64_t(CARB_ABI* setCaptureMask)(const uint64_t mask);

    uint64_t(CARB_ABI* getCaptureMask)();

    ZoneId(CARB_ABI* beginStatic)(
        const uint64_t mask, StaticStringType function, StaticStringType file, int line, StaticStringType nameFmt);

    ZoneId(CARB_ABI* beginDynamic)(
        const uint64_t mask, StaticStringType function, StaticStringType file, int line, const char* nameFmt, ...)
        CARB_PRINTF_FUNCTION(5, 6);

    void(CARB_ABI* end)(const uint64_t mask);

    void(CARB_ABI* frameStatic)(const uint64_t mask, StaticStringType nameFmt);
    void(CARB_ABI* frameDynamic)(const uint64_t mask, const char* nameFmt, ...) CARB_PRINTF_FUNCTION(2, 3);

    void(CARB_ABI* valueFloatStatic)(const uint64_t mask, float value, StaticStringType valueFmt);
    void(CARB_ABI* valueFloatDynamic)(const uint64_t mask, float value, const char* valueFmt, ...)
        CARB_PRINTF_FUNCTION(3, 4);

    void(CARB_ABI* valueIntStatic)(const uint64_t mask, int32_t value, StaticStringType valueFmt);
    void(CARB_ABI* valueIntDynamic)(const uint64_t mask, int32_t value, const char* valueFmt, ...)
        CARB_PRINTF_FUNCTION(3, 4);

    void(CARB_ABI* valueUIntStatic)(const uint64_t mask, uint32_t value, StaticStringType valueFmt);
    void(CARB_ABI* valueUIntDynamic)(const uint64_t mask, uint32_t value, const char* valueFmt, ...)
        CARB_PRINTF_FUNCTION(3, 4);

    void(CARB_ABI* nameThreadStatic)(uint64_t tidOrZero, StaticStringType threadName);
    void(CARB_ABI* nameThreadDynamic)(uint64_t tidOrZero, const char* threadName, ...) CARB_PRINTF_FUNCTION(2, 3);

    bool(CARB_ABI* supportsDynamicSourceLocations)();

    template <typename T>
    void valueStatic(uint64_t mask, T value, StaticStringType valueFmt);

    template <typename T, typename... Args>
    void valueDynamic(uint64_t mask, T value, const char* valueFmt, Args&&... args);

    StaticStringType(CARB_ABI* registerStaticString)(const char* string);

    void(CARB_ABI* allocNamedStatic)(const uint64_t mask, const void* ptr, uint64_t size, StaticStringType name);
    void(CARB_ABI* allocNamedDynamic)(const uint64_t mask, const void* ptr, uint64_t size, const char* nameFmt, ...)
        CARB_PRINTF_FUNCTION(4, 5);

    void(CARB_ABI* freeNamedStatic)(const uint64_t mask, const void* ptr, StaticStringType valueFmt);
    void(CARB_ABI* freeNamedDynamic)(const uint64_t mask, const void* ptr, const char* nameFmt, ...)
        CARB_PRINTF_FUNCTION(3, 4);

    void(CARB_ABI* allocStatic)(const uint64_t mask, const void* ptr, uint64_t size);

    void(CARB_ABI* freeStatic)(const uint64_t mask, const void* ptr);

    void(CARB_ABI* endEx)(const uint64_t mask, ZoneId zoneId);

    void(CARB_ABI* emitInstantStatic)(const uint64_t mask,
                                      StaticStringType function,
                                      StaticStringType file,
                                      int line,
                                      InstantType type,
                                      StaticStringType nameFmt);
    void(CARB_ABI* emitInstantDynamic)(const uint64_t mask,
                                       StaticStringType function,
                                       StaticStringType file,
                                       int line,
                                       InstantType type,
                                       const char* nameFmt,
                                       ...) CARB_PRINTF_FUNCTION(6, 7);

    void(CARB_ABI* emitFlowStatic)(const uint64_t mask,
                                   StaticStringType function,
                                   StaticStringType file,
                                   int line,
                                   FlowType type,
                                   uint64_t id,
                                   StaticStringType name);
    void(CARB_ABI* emitFlowDynamic)(const uint64_t mask,
                                    StaticStringType function,
                                    StaticStringType file,
                                    int line,
                                    FlowType type,
                                    uint64_t id,
                                    const char* name,
                                    ...) CARB_PRINTF_FUNCTION(7, 8);

    GpuContextId(CARB_ABI* createGpuContext)(const char* name,
                                             int64_t correlatedCpuTimestampNs,
                                             int64_t correlatedGpuTimestamp,
                                             float gpuTimestampPeriodNs,
                                             const char* graphicApi);

    void(CARB_ABI* destroyGpuContext)(GpuContextId contextId);

    bool(CARB_ABI* calibrateGpuContext)(GpuContextId contextId,
                                        int64_t correlatedCpuTimestampNs,
                                        int64_t previousCorrelatedCpuTimestampNs,
                                        int64_t correlatedGpuTimestamp);
    void(CARB_ABI* beginGpuQueryStatic)(const uint64_t mask,
                                        StaticStringType functionName,
                                        StaticStringType fileName,
                                        int line,
                                        GpuContextId contextId,
                                        uint32_t queryId,
                                        StaticStringType name);

    void(CARB_ABI* beginGpuQueryDynamic)(const uint64_t mask,
                                         StaticStringType functionName,
                                         StaticStringType fileName,
                                         int line,
                                         GpuContextId contextId,
                                         uint32_t queryId,
                                         const char* nameFmt,
                                         ...) CARB_PRINTF_FUNCTION(7, 8);

    void(CARB_ABI* endGpuQuery)(const uint64_t mask, GpuContextId contextId, uint32_t queryId);
    void(CARB_ABI* setGpuQueryValue)(const uint64_t mask, GpuContextId contextId, uint32_t queryId, int64_t gpuTimestamp);

    LockableId(CARB_ABI* createLockable)(const uint64_t mask,
                                         const char* name,
                                         const bool isSharedLock,
                                         StaticStringType functionName,
                                         StaticStringType fileName,
                                         int line);

    void(CARB_ABI* destroyLockable)(LockableId lockableId);

    void(CARB_ABI* lockableOperation)(LockableId lockableId, LockableOperationType operation);

    uint64_t(CARB_ABI* setMaskCallback)(MaskCallbackFn func, bool enabled);
};

#ifndef DOXYGEN_BUILD
namespace detail
{
template <typename T>
class ValueInvoker;

template <>
class ValueInvoker<float>
{
public:
    static void invokeStatic(IProfiler& profiler, uint64_t mask, float value, StaticStringType valueFmt)
    {
        profiler.valueFloatStatic(mask, value, valueFmt);
    }
    template <typename... Args>
    static void invokeDynamic(IProfiler& profiler, uint64_t mask, float value, const char* valueFmt, Args&&... args)
    {
        profiler.valueFloatDynamic(mask, value, valueFmt, std::forward<Args>(args)...);
    }
};

template <>
class ValueInvoker<int32_t>
{
public:
    static void invokeStatic(IProfiler& profiler, uint64_t mask, int32_t value, StaticStringType valueFmt)
    {
        profiler.valueIntStatic(mask, value, valueFmt);
    }
    template <typename... Args>
    static void invokeDynamic(IProfiler& profiler, uint64_t mask, int32_t value, const char* valueFmt, Args&&... args)
    {
        profiler.valueIntDynamic(mask, value, valueFmt, std::forward<Args>(args)...);
    }
};

template <>
class ValueInvoker<uint32_t>
{
public:
    static void invokeStatic(IProfiler& profiler, uint64_t mask, uint32_t value, StaticStringType valueFmt)
    {
        profiler.valueUIntStatic(mask, value, valueFmt);
    }
    template <typename... Args>
    static void invokeDynamic(IProfiler& profiler, uint64_t mask, uint32_t value, const char* valueFmt, Args&&... args)
    {
        profiler.valueUIntDynamic(mask, value, valueFmt, std::forward<Args>(args)...);
    }
};
} // namespace detail
#endif

template <typename T>
inline void IProfiler::valueStatic(uint64_t mask, T value, StaticStringType valueFmt)
{
    using ValueInvoker = typename detail::ValueInvoker<T>;
    ValueInvoker::invokeStatic(*this, mask, value, valueFmt);
}

template <typename T, typename... Args>
inline void IProfiler::valueDynamic(uint64_t mask, T value, const char* valueFmt, Args&&... args)
{
    using ValueInvoker = typename detail::ValueInvoker<T>;
    ValueInvoker::invokeDynamic(*this, mask, value, valueFmt, std::forward<Args>(args)...);
}

} // namespace profiler
} // namespace carb

CARB_WEAKLINK std::atomic<carb::profiler::IProfiler*> g_carbProfiler;

CARB_WEAKLINK std::atomic_uint64_t g_carbProfilerMask;