/* * Copyright (c) Advanced Micro Devices, Inc., or its affiliates. * * SPDX-License-Identifier: MIT */ #pragma once #include #include "device/pal/palcapturemgr.hpp" #include "platform/commandqueue.hpp" #include "device/blit.hpp" // PAL headers #include "palUtil.h" #include "palPlatform.h" #include "palCmdBuffer.h" #include "palCmdAllocator.h" #include "palQueue.h" #include "palFence.h" #include "palLinearAllocator.h" #include "palHashMap.h" #include "palQueue.h" #include "palUtil.h" namespace amd::pal { class Settings; class Device; class VirtualGPU; class Kernel; // ================================================================================================ enum class RgpSqqtBarrierReason : uint32_t { Invalid = 0, MemDependency = 0xC0000000, ProfilingControl = 0xC0000001, SignalSubmit = 0xC0000002, PostDeviceEnqueue = 0xC0000003, Unknown = 0xffffffff }; } // namespace amd::pal #ifdef PAL_GPUOPEN_OCL #include "protocols/rgpServer.h" // gpuopen headers #include "gpuopen.h" // gpuutil headers #include "gpuUtil/palGpaSession.h" // PAL forward declarations namespace Pal { class ICmdBuffer; class IFence; class IQueueSemaphore; struct PalPublicSettings; class IGPuMemory; } // namespace Pal // GPUOpen forward declarations namespace DevDriver { class DevDriverServer; class IMsgChannel; struct MessageBuffer; namespace DriverControlProtocol { enum struct DeviceClockMode : uint32_t; class HandlerServer; } // namespace DriverControlProtocol namespace SettingsProtocol { class HandlerServer; } } // namespace DevDriver namespace amd::pal { // ================================================================================================ // This class provides functionality to interact with the GPU Open Developer Mode message passing // service and the rest of the driver. class RgpCaptureMgr final : public ICaptureMgr { public: ~RgpCaptureMgr(); static RgpCaptureMgr* Create(Pal::IPlatform* platform, const Device& device); void PreDispatch(VirtualGPU* gpu, const pal::Kernel& kernel, size_t x, size_t y, size_t z) override; void PostDispatch(VirtualGPU* gpu) override; void FinishRGPTrace(VirtualGPU* gpu, bool aborted) override; void WriteBarrierStartMarker(const VirtualGPU* gpu, const Pal::Developer::BarrierData& data) const override; void WriteBarrierEndMarker(const VirtualGPU* gpu, const Pal::Developer::BarrierData& data) const override; bool RegisterTimedQueue(uint32_t queue_id, Pal::IQueue* iQueue, bool* debug_vmid) const override; Pal::Result TimedQueueSubmit(Pal::IQueue* queue, uint64_t cmdId, const Pal::SubmitInfo& submitInfo) const override; bool Update(Pal::IPlatform* platform) override; uint64_t AddElfBinary(const void* exe_binary, size_t exe_binary_size, const void* elf_binary, size_t elf_binary_size, Pal::IGpuMemory* pGpuMemory, size_t offset) override; private: // Steps that an RGP trace goes through enum class TraceStatus { Idle = 0, // No active trace and none requested Preparing, // A trace has been requested but is not active yet because we are // currently sampling timing information over some number of lead frames. Running, // SQTT and queue timing is currently active for all command buffer submits. WaitingForSqtt, WaitingForResults // Tracing is no longer active, but all results are not yet ready. }; // All per-device state to support RGP tracing struct TraceState { TraceStatus status_; // Current trace status (idle, running, etc.) GpuEvent begin_sqtt_event_; // Event that is signaled when a trace-end cmdbuf retires GpuEvent end_sqtt_event_; // Event that is signaled when a trace-end cmdbuf retires GpuEvent end_event_; // Event that is signaled when a trace-end cmdbuf retires VirtualGPU* begin_queue_; // The queue that triggered starting SQTT GpuUtil::GpaSession* gpa_session_; // GPA session helper object for building RGP data uint32_t gpa_sample_id_; // Sample ID associated with the current trace bool queue_timing_; // Queue timing is enabled uint32_t prepared_disp_count_; // Number of dispatches counted while preparing for a trace uint32_t sqtt_disp_count_; // Number of dispatches counted while SQTT tracing is active mutable uint32_t current_event_id_; // Current event ID }; RgpCaptureMgr(Pal::IPlatform* platform, const Device& device); bool Init(Pal::IPlatform* platform); void Finalize(); Pal::Result PrepareRGPTrace(VirtualGPU* pQueue); Pal::Result BeginRGPTrace(VirtualGPU* pQueue); Pal::Result EndRGPHardwareTrace(VirtualGPU* pQueue); Pal::Result EndRGPTrace(VirtualGPU* pQueue); void DestroyRGPTracing(); Pal::Result CheckForTraceResults(); static bool GpuSupportsTracing(const Pal::DeviceProperties& props, const Settings& settings); RgpSqttMarkerEvent BuildEventMarker(const VirtualGPU* gpu, RgpSqttMarkerEventType api_type) const; void WriteMarker(const VirtualGPU* gpu, const void* data, size_t data_size) const; void WriteEventWithDimsMarker(const VirtualGPU* gpu, RgpSqttMarkerEventType apiType, uint32_t x, uint32_t y, uint32_t z) const; void WriteUserEventMarker(const VirtualGPU* gpu, RgpSqttMarkerUserEventType eventType, const std::string& name) const; void WriteComputeBindMarker(const VirtualGPU* gpu, uint64_t api_hash) const; void WaitForDriverResume(); void PostDeviceCreate(); void PreDeviceDestroy(); bool IsQueueTimingActive() const; const Device& device_; DevDriver::DevDriverServer* dev_driver_server_; DevDriver::RGPProtocol::RGPServer* rgp_server_; mutable amd::Monitor trace_mutex_; TraceState trace_; RgpSqttMarkerUserEventWithString* user_event_; uint32_t num_prep_disp_; uint32_t max_sqtt_disp_; // Maximum number of the dispatches allowed in the trace uint32_t trace_gpu_mem_limit_; uint32_t global_disp_count_; uint32_t se_mask_; // Shader engine mask uint64_t perf_counter_mem_limit_; // Memory limit for perf counters uint32_t perf_counter_frequency_; // Counter sample frequency std::vector perf_counter_ids_; // List of perf counter ids union { struct { uint32_t trace_enabled_ : 1; // True if tracing is currently enabled (master flag) uint32_t inst_tracing_enabled_ : 1; // Enable instruction-level SQTT tokens uint32_t perf_counters_enabled_ : 1; // True if perf counters are enabled uint32_t static_vm_id_ : 1; // Static VM ID can be used for capture }; uint32_t value_; }; PAL_DISALLOW_DEFAULT_CTOR(RgpCaptureMgr); PAL_DISALLOW_COPY_AND_ASSIGN(RgpCaptureMgr); }; // ================================================================================================ // Returns true if queue operations are currently being timed by RGP traces. inline bool RgpCaptureMgr::IsQueueTimingActive() const { return (trace_.queue_timing_ && (trace_.status_ == TraceStatus::Running || trace_.status_ == TraceStatus::Preparing || trace_.status_ == TraceStatus::WaitingForSqtt)); } } // namespace amd::pal #else // PAL_GPUOPEN_OCL namespace amd::pal { class RgpCaptureMgr { public: static RgpCaptureMgr* Create(Pal::IPlatform* platform, const Device& device) { return nullptr; } Pal::Result TimedQueueSubmit(Pal::IQueue* queue, uint64_t cmdId, Pal::SubmitInfo& submitInfo) const { return Pal::Result::Success; } void PreDispatch(VirtualGPU* gpu, const pal::Kernel& kernel, size_t x, size_t y, size_t z) {} void PostDispatch(VirtualGPU* gpu) {} void FinishRGPTrace(VirtualGPU* gpu, bool aborted) {} bool RegisterTimedQueue(uint32_t queue_id, Pal::IQueue* iQueue, bool* debug_vmid) const { return true; } bool Update(Pal::IPlatform* platform) const { return true; } bool AddElfBinary(const void* exe_binary, size_t exe_binary_size, const void* elf_binary, size_t elf_binary_size, Pal::IGpuMemory* pGpuMemory, size_t offset) { return true; } }; } // namespace amd::pal #endif // PAL_GPUOPEN_OCL