From 7bb3d411553845c027f6e249bb4af7904ee7b85c Mon Sep 17 00:00:00 2001
From: foreman
Date: Wed, 27 Jun 2018 18:32:23 -0400
Subject: [PATCH] P4 to Git Change 1573623 by gandryey@gera-w8 on 2018/06/27
18:23:10
SWDEV-155433 - Add OpenCL API type for RGP files generated from OpenCL
- Add API type events to the SQTT
Affected files ...
... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paldevice.cpp#93 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paldevice.hpp#30 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palgpuopen.cpp#3 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palgpuopen.hpp#3 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palvirtual.cpp#112 edit
---
rocclr/runtime/device/pal/paldevice.cpp | 30 ++++
rocclr/runtime/device/pal/paldevice.hpp | 6 +
rocclr/runtime/device/pal/palgpuopen.cpp | 217 ++++++++++++++++++-----
rocclr/runtime/device/pal/palgpuopen.hpp | 77 ++++++--
rocclr/runtime/device/pal/palvirtual.cpp | 13 +-
5 files changed, 277 insertions(+), 66 deletions(-)
diff --git a/rocclr/runtime/device/pal/paldevice.cpp b/rocclr/runtime/device/pal/paldevice.cpp
index 0e9a895877..5a9e528321 100644
--- a/rocclr/runtime/device/pal/paldevice.cpp
+++ b/rocclr/runtime/device/pal/paldevice.cpp
@@ -942,6 +942,33 @@ bool Device::create(Pal::IDevice* device) {
return true;
}
+// =====================================================================================================================
+// Master function that handles developer callbacks from PAL.
+void PAL_STDCALL Device::PalDeveloperCallback(
+ void* pPrivateData,
+ const Pal::uint32 deviceIndex,
+ Pal::Developer::CallbackType type,
+ void* pCbData) {
+ Device* device = static_cast(pPrivateData);
+ const auto& barrier = *static_cast(pCbData);
+
+ switch (type) {
+ case Pal::Developer::CallbackType::BarrierBegin:
+ device->rgpCaptureMgr()->WriteBarrierStartMarker(barrier);
+ break;
+ case Pal::Developer::CallbackType::BarrierEnd:
+ device->rgpCaptureMgr()->WriteBarrierEndMarker(barrier);
+ break;
+ case Pal::Developer::CallbackType::ImageBarrier:
+ assert(false);
+ break;
+ case Pal::Developer::CallbackType::DrawDispatch:
+ break;
+ default:
+ break;
+ }
+}
+
bool Device::initializeHeapResources() {
amd::ScopedLock k(lockForInitHeap_);
if (!heapInitComplete_) {
@@ -999,6 +1026,9 @@ bool Device::initializeHeapResources() {
// Create RGP capture manager
rgpCaptureMgr_ = RgpCaptureMgr::Create(platform_, *this);
+ if (nullptr != rgpCaptureMgr_) {
+ Pal::IPlatform::InstallDeveloperCb(iPlat(), &Device::PalDeveloperCallback, this);
+ }
}
return true;
}
diff --git a/rocclr/runtime/device/pal/paldevice.hpp b/rocclr/runtime/device/pal/paldevice.hpp
index e5a441562f..1b5e1b3b59 100644
--- a/rocclr/runtime/device/pal/paldevice.hpp
+++ b/rocclr/runtime/device/pal/paldevice.hpp
@@ -526,6 +526,12 @@ class Device : public NullDevice {
}
private:
+ static void PAL_STDCALL PalDeveloperCallback(
+ void* pPrivateData,
+ const Pal::uint32 deviceIndex,
+ Pal::Developer::CallbackType type,
+ void* pCbData);
+
//! Disable copy constructor
Device(const Device&);
diff --git a/rocclr/runtime/device/pal/palgpuopen.cpp b/rocclr/runtime/device/pal/palgpuopen.cpp
index 5129d8e1f8..8614ccc90c 100644
--- a/rocclr/runtime/device/pal/palgpuopen.cpp
+++ b/rocclr/runtime/device/pal/palgpuopen.cpp
@@ -13,6 +13,9 @@
#include "device/pal/palgpuopen.hpp"
#include "device/pal/paldevice.hpp"
#include "device/pal/palvirtual.hpp"
+#include "device/pal/palprogram.hpp"
+#include "device/pal/palkernel.hpp"
+#include "device/pal/palblit.hpp"
// PAL headers
#include "palCmdAllocator.h"
@@ -39,6 +42,7 @@ RgpCaptureMgr::RgpCaptureMgr(Pal::IPlatform* platform, const Device& device)
num_prep_disp_(0),
trace_gpu_mem_limit_(0),
global_disp_count_(1), // Must start from 1 according to RGP spec
+ user_event_(nullptr),
trace_enabled_(false),
inst_tracing_enabled_(false)
{
@@ -122,6 +126,10 @@ bool RgpCaptureMgr::Init(Pal::IPlatform* platform)
bool hasDebugVmid = true;
if (result) {
+ user_event_ = new RgpSqttMarkerUserEventWithString;
+ if (nullptr == user_event_) {
+ result = false;
+ }
//result = InitTraceQueueResources(trace_, &hasDebugVmid);
}
@@ -192,7 +200,7 @@ void RgpCaptureMgr::WaitForDriverResume()
// ================================================================================================
// Called before a swap chain presents. This signals a frame-end boundary and
// is used to coordinate RGP trace start/stop.
-void RgpCaptureMgr::PostDispatch(VirtualGPU* pQueue)
+void RgpCaptureMgr::PostDispatch(VirtualGPU* gpu)
{
if (rgp_server_->TracesEnabled()) {
// If there's currently a trace running, submit the trace-end command buffer
@@ -200,15 +208,16 @@ void RgpCaptureMgr::PostDispatch(VirtualGPU* pQueue)
amd::ScopedLock traceLock(&trace_mutex_);
trace_.sqtt_disp_count_++;
if (trace_.sqtt_disp_count_ >= device_.settings().rgpSqttDispCount_) {
- if (EndRGPHardwareTrace(pQueue) != Pal::Result::Success) {
- FinishRGPTrace(true);
+ trace_.sqtt_disp_count_ = 0;
+ if (EndRGPHardwareTrace(gpu) != Pal::Result::Success) {
+ FinishRGPTrace(gpu, true);
}
}
}
if (IsQueueTimingActive()) {
// Call TimedQueuePresent() to insert commands that collect GPU timestamp.
- Pal::IQueue* pPalQueue = pQueue->queue(MainEngine).iQueue_;
+ Pal::IQueue* pPalQueue = gpu->queue(MainEngine).iQueue_;
// Currently nothing in the PresentInfo struct is used for inserting a timed present marker.
GpuUtil::TimedQueuePresentInfo timedPresentInfo = {};
@@ -267,7 +276,8 @@ Pal::Result RgpCaptureMgr::CheckForTraceResults()
// ================================================================================================
// Called after a swap chain presents. This signals a (next) frame-begin boundary and is
// used to coordinate RGP trace start/stop.
-void RgpCaptureMgr::PreDispatch(VirtualGPU* pQueue, size_t x, size_t y, size_t z)
+void RgpCaptureMgr::PreDispatch(VirtualGPU* gpu, const HSAILKernel& kernel,
+ size_t x, size_t y, size_t z)
{
// Wait for the driver to be resumed in case it's been paused.
WaitForDriverResume();
@@ -278,13 +288,13 @@ void RgpCaptureMgr::PreDispatch(VirtualGPU* pQueue, size_t x, size_t y, size_t z
// Check if there's an RGP trace request pending and we're idle
if ((trace_.status_ == TraceStatus::Idle) && rgp_server_->IsTracePending()) {
// Attempt to start preparing for a trace
- if (PrepareRGPTrace(pQueue) == Pal::Result::Success) {
- // Attempt to start the trace immediately if we do not need to prepare
- if (num_prep_disp_ == 0) {
- if (BeginRGPTrace(pQueue) != Pal::Result::Success) {
- FinishRGPTrace(true);
- }
+ if (PrepareRGPTrace(gpu) == Pal::Result::Success) {
+ // Attempt to start the trace immediately if we do not need to prepare
+ if (num_prep_disp_ == 0) {
+ if (BeginRGPTrace(gpu) != Pal::Result::Success) {
+ FinishRGPTrace(gpu, true);
}
+ }
}
}
else if (trace_.status_ == TraceStatus::Preparing) {
@@ -297,11 +307,11 @@ void RgpCaptureMgr::PreDispatch(VirtualGPU* pQueue, size_t x, size_t y, size_t z
// Start the SQTT trace if we've waited a sufficient number of preparation frames
if (trace_.prepared_disp_count_ >= num_prep_disp_) {
- Pal::Result result = BeginRGPTrace(pQueue);
+ Pal::Result result = BeginRGPTrace(gpu);
- if (result != Pal::Result::Success) {
- FinishRGPTrace(true);
- }
+ if (result != Pal::Result::Success) {
+ FinishRGPTrace(gpu, true);
+ }
}
}
// Check if we're ending a trace waiting for SQTT to turn off.
@@ -310,14 +320,14 @@ void RgpCaptureMgr::PreDispatch(VirtualGPU* pQueue, size_t x, size_t y, size_t z
Pal::Result result = Pal::Result::Success;
if (trace_.begin_queue_->isDone(&trace_.end_sqtt_event_)) {
- result = EndRGPTrace(pQueue);
+ result = EndRGPTrace(gpu);
} else {
// todo: There is a wait inside the trace end for now
- result = EndRGPTrace(pQueue);
+ result = EndRGPTrace(gpu);
}
if (result != Pal::Result::Success) {
- FinishRGPTrace(true);
+ FinishRGPTrace(gpu, true);
}
}
// Check if we're waiting for final trace results.
@@ -326,17 +336,36 @@ void RgpCaptureMgr::PreDispatch(VirtualGPU* pQueue, size_t x, size_t y, size_t z
// Results ready: finish trace
if (result == Pal::Result::Success) {
- FinishRGPTrace(false);
+ FinishRGPTrace(gpu, false);
}
// Error while computing results: abort trace
else if (result != Pal::Result::NotReady) {
- FinishRGPTrace(true);
+ FinishRGPTrace(gpu, true);
}
}
if (trace_.status_ == TraceStatus::Running) {
+ RgpSqttMarkerEventType apiEvent = RgpSqttMarkerEventType::CmdNDRangeKernel;
+ if (kernel.prog().isInternal()) {
+ constexpr RgpSqttMarkerEventType ApiEvents[KernelBlitManager::BlitTotal] = {
+ RgpSqttMarkerEventType::CmdCopyImage, RgpSqttMarkerEventType::CmdCopyImage,
+ RgpSqttMarkerEventType::CmdCopyImageToBuffer,
+ RgpSqttMarkerEventType::CmdCopyBufferToImage,
+ RgpSqttMarkerEventType::CmdCopyBuffer, RgpSqttMarkerEventType::CmdCopyBuffer,
+ RgpSqttMarkerEventType::CmdCopyBuffer, RgpSqttMarkerEventType::CmdCopyBuffer,
+ RgpSqttMarkerEventType::CmdFillBuffer, RgpSqttMarkerEventType::CmdFillImage,
+ RgpSqttMarkerEventType::CmdScheduler
+ };
+ for (uint i = 0; i < KernelBlitManager::BlitTotal; ++i) {
+ if (kernel.name().compare(BlitName[i]) == 0) {
+ apiEvent = ApiEvents[i];
+ break;
+ }
+ }
+ }
+ WriteUserEventMarker(RgpSqttMarkerUserEventObjectName, kernel.name());
// Write disaptch marker
- WriteEventWithDimsMarker(RgpSqttMarkerEventType::CmdDispatch,
+ WriteEventWithDimsMarker(apiEvent,
static_cast(x), static_cast(y), static_cast(z));
}
}
@@ -349,7 +378,7 @@ void RgpCaptureMgr::PreDispatch(VirtualGPU* pQueue, size_t x, size_t y, size_t z
// lead-up time during which timing samples are accumulated to synchronize CPU and GPU clock domains.
//
// This function transitions from the Idle state to the Preparing state.
-Pal::Result RgpCaptureMgr::PrepareRGPTrace(VirtualGPU* pQueue)
+Pal::Result RgpCaptureMgr::PrepareRGPTrace(VirtualGPU* gpu)
{
assert(trace_.status_ == TraceStatus::Idle);
@@ -387,7 +416,7 @@ Pal::Result RgpCaptureMgr::PrepareRGPTrace(VirtualGPU* pQueue)
if (result == Pal::Result::Success) {
// Remember which queue started the trace
- trace_.prepare_queue_ = pQueue;
+ trace_.prepare_queue_ = gpu;
trace_.begin_queue_ = nullptr;
trace_.status_ = TraceStatus::Preparing;
@@ -409,7 +438,7 @@ Pal::Result RgpCaptureMgr::PrepareRGPTrace(VirtualGPU* pQueue)
// the "begin trace" information command buffer.
//
// This function transitions from the Preparing state to the Running state.
-Pal::Result RgpCaptureMgr::BeginRGPTrace(VirtualGPU* pQueue)
+Pal::Result RgpCaptureMgr::BeginRGPTrace(VirtualGPU* gpu)
{
assert(trace_.status_ == TraceStatus::Preparing);
assert(trace_enabled_);
@@ -421,7 +450,7 @@ Pal::Result RgpCaptureMgr::BeginRGPTrace(VirtualGPU* pQueue)
if (result == Pal::Result::Success) {
// Only allow trace to start if the queue family at prep-time matches the queue
// family at begin time because the command buffer engine type must match
- if (trace_.prepare_queue_ != pQueue) {
+ if (trace_.prepare_queue_ != gpu) {
result = Pal::Result::ErrorIncompatibleQueue;
}
}
@@ -436,23 +465,23 @@ Pal::Result RgpCaptureMgr::BeginRGPTrace(VirtualGPU* pQueue)
sampleConfig.sqtt.flags.supressInstructionTokens = (inst_tracing_enabled_ == false);
// Fill GPU commands
- pQueue->eventBegin(MainEngine);
+ gpu->eventBegin(MainEngine);
trace_.gpa_sample_id_ = trace_.gpa_session_->BeginSample(
- pQueue->queue(MainEngine).iCmd(), sampleConfig);
- pQueue->eventEnd(MainEngine, trace_.begin_sqtt_event_);
+ gpu->queue(MainEngine).iCmd(), sampleConfig);
+ gpu->eventEnd(MainEngine, trace_.begin_sqtt_event_);
}
// Submit the trace-begin command buffer
if (result == Pal::Result::Success) {
static constexpr bool NeedFlush = true;
// Update the global GPU event
- pQueue->setGpuEvent(trace_.begin_sqtt_event_, NeedFlush);
+ gpu->setGpuEvent(trace_.begin_sqtt_event_, NeedFlush);
}
// Make the trace active and remember which queue started it
if (result == Pal::Result::Success) {
trace_.status_ = TraceStatus::Running;
- trace_.begin_queue_ = pQueue;
+ trace_.begin_queue_ = gpu;
}
return result;
@@ -462,7 +491,7 @@ Pal::Result RgpCaptureMgr::BeginRGPTrace(VirtualGPU* pQueue)
// This function submits the command buffer to stop SQTT tracing. Full tracing still continues.
//
// This function transitions from the Running state to the WaitingForSqtt state.
-Pal::Result RgpCaptureMgr::EndRGPHardwareTrace(VirtualGPU* pQueue)
+Pal::Result RgpCaptureMgr::EndRGPHardwareTrace(VirtualGPU* gpu)
{
assert(trace_.status_ == TraceStatus::Running);
@@ -470,7 +499,7 @@ Pal::Result RgpCaptureMgr::EndRGPHardwareTrace(VirtualGPU* pQueue)
// Only allow SQTT trace to start and end on the same queue because it's critical that these are
// in the same order
- if (pQueue != trace_.begin_queue_) {
+ if (gpu != trace_.begin_queue_) {
result = Pal::Result::ErrorIncompatibleQueue;
}
@@ -480,20 +509,20 @@ Pal::Result RgpCaptureMgr::EndRGPHardwareTrace(VirtualGPU* pQueue)
assert(trace_.gpa_session_ != nullptr);
// Write CB commands to finish the SQTT
- pQueue->eventBegin(MainEngine);
- trace_.gpa_session_->EndSample(pQueue->queue(MainEngine).iCmd(), trace_.gpa_sample_id_);
- pQueue->eventEnd(MainEngine, trace_.end_sqtt_event_);
+ gpu->eventBegin(MainEngine);
+ trace_.gpa_session_->EndSample(gpu->queue(MainEngine).iCmd(), trace_.gpa_sample_id_);
+ gpu->eventEnd(MainEngine, trace_.end_sqtt_event_);
static constexpr bool NeedFlush = true;
// Update the global GPU event
- pQueue->setGpuEvent(trace_.end_sqtt_event_, NeedFlush);
+ gpu->setGpuEvent(trace_.end_sqtt_event_, NeedFlush);
trace_.status_ = TraceStatus::WaitingForSqtt;
// Execute a device wait idle
if (device_.settings().rgpSqttWaitIdle_) {
// Make sure the trace is done. Note: required for SDMA data write back
- pQueue->waitForEvent(&trace_.end_sqtt_event_);
+ gpu->waitForEvent(&trace_.end_sqtt_event_);
}
}
@@ -504,7 +533,7 @@ Pal::Result RgpCaptureMgr::EndRGPHardwareTrace(VirtualGPU* pQueue)
// This function ends a running RGP trace.
//
// This function transitions from the WaitingForSqtt state to WaitingForResults state.
-Pal::Result RgpCaptureMgr::EndRGPTrace(VirtualGPU* pQueue)
+Pal::Result RgpCaptureMgr::EndRGPTrace(VirtualGPU* gpu)
{
assert(trace_.status_ == TraceStatus::WaitingForSqtt);
@@ -515,22 +544,22 @@ Pal::Result RgpCaptureMgr::EndRGPTrace(VirtualGPU* pQueue)
if (result == Pal::Result::Success) {
assert(trace_.gpa_session_ != nullptr);
// Initiate SDMA copy
- pQueue->eventBegin(SdmaEngine);
- result = trace_.gpa_session_->End(pQueue->queue(SdmaEngine).iCmd());
- pQueue->eventEnd(SdmaEngine, trace_.end_event_);
+ gpu->eventBegin(SdmaEngine);
+ result = trace_.gpa_session_->End(gpu->queue(SdmaEngine).iCmd());
+ gpu->eventEnd(SdmaEngine, trace_.end_event_);
}
// Submit the trace-end command buffer
if (result == Pal::Result::Success) {
static constexpr bool NeedFlush = true;
// Update the global GPU event
- pQueue->setGpuEvent(trace_.end_event_, NeedFlush);
+ gpu->setGpuEvent(trace_.end_event_, NeedFlush);
trace_.status_ = TraceStatus::WaitingForResults;
if (device_.settings().rgpSqttWaitIdle_) {
// Make sure the transfer is done
- pQueue->waitForEvent(&trace_.end_event_);
+ gpu->waitForEvent(&trace_.end_event_);
}
}
@@ -540,12 +569,18 @@ Pal::Result RgpCaptureMgr::EndRGPTrace(VirtualGPU* pQueue)
// ================================================================================================
// This function resets and possibly cancels a currently active (between begin/end) RGP trace.
// It frees any dependent resources.
-void RgpCaptureMgr::FinishRGPTrace(bool aborted)
+void RgpCaptureMgr::FinishRGPTrace(VirtualGPU* gpu, bool aborted)
{
if (trace_.prepare_queue_ == nullptr) {
return;
}
+ // Finish the trace if the queue was destroyed before
+ // OCL reached the number of captured dispatches
+ if ((trace_.sqtt_disp_count_ != 0) && (gpu != nullptr)) {
+ EndRGPHardwareTrace(gpu);
+ }
+
// Inform RGP protocol that we're done with the trace, either by aborting it or finishing normally
if (aborted) {
rgp_server_->AbortTrace();
@@ -571,9 +606,11 @@ void RgpCaptureMgr::FinishRGPTrace(bool aborted)
void RgpCaptureMgr::DestroyRGPTracing()
{
if (trace_.status_ != TraceStatus::Idle) {
- FinishRGPTrace(true);
+ FinishRGPTrace(nullptr, true);
}
+ delete user_event_;
+
// Destroy the GPA session
if (trace_.gpa_session_ != nullptr) {
//Util::Destructor(trace_.gpa_session_);
@@ -628,7 +665,7 @@ void RgpCaptureMgr::PreDeviceDestroy()
// ================================================================================================
// Sets up an Event marker's basic data.
-RgpSqttMarkerEvent RgpCaptureMgr::BuildEventMarker(RgpSqttMarkerEventType api_type)
+RgpSqttMarkerEvent RgpCaptureMgr::BuildEventMarker(RgpSqttMarkerEventType api_type) const
{
RgpSqttMarkerEvent marker = {};
@@ -656,7 +693,7 @@ void RgpCaptureMgr::WriteEventWithDimsMarker(
RgpSqttMarkerEventType apiType,
uint32_t x,
uint32_t y,
- uint32_t z)
+ uint32_t z) const
{
assert(apiType != RgpSqttMarkerEventType::Invalid);
@@ -671,4 +708,90 @@ void RgpCaptureMgr::WriteEventWithDimsMarker(
WriteMarker(&eventWithDims, sizeof(eventWithDims));
}
+// =====================================================================================================================
+void RgpCaptureMgr::WriteBarrierStartMarker(const Pal::Developer::BarrierData& data) const
+{
+ if (rgp_server_->TracesEnabled() && (trace_.status_ == TraceStatus::Running)) {
+ amd::ScopedLock traceLock(&trace_mutex_);
+ RgpSqttMarkerBarrierStart marker = {};
+
+ marker.identifier = RgpSqttMarkerIdentifierBarrierStart;
+ marker.cbId = trace_.begin_queue_->queue(MainEngine).cmdBufId();
+ marker.dword02 = 0xFFFFFFFF; //data.reason;
+ marker.internal = true;
+
+ WriteMarker(&marker, sizeof(marker));
+ }
+}
+
+// =====================================================================================================================
+void RgpCaptureMgr::WriteBarrierEndMarker(const Pal::Developer::BarrierData& data) const
+{
+ if (rgp_server_->TracesEnabled() && (trace_.status_ == TraceStatus::Running)) {
+ amd::ScopedLock traceLock(&trace_mutex_);
+ // Copy the operations part and include the same data from previous markers
+ // within the same barrier sequence to create a full picture of all cache
+ // syncs and pipeline stalls.
+ auto operations = data.operations;
+
+ operations.pipelineStalls.u16All |= 0;
+ operations.caches.u16All |= 0;
+
+ RgpSqttMarkerBarrierEnd marker = {};
+
+ marker.identifier = RgpSqttMarkerIdentifierBarrierEnd;
+ marker.cbId = trace_.begin_queue_->queue(MainEngine).cmdBufId();
+
+ marker.waitOnEopTs = operations.pipelineStalls.waitOnEopTsBottomOfPipe;
+ marker.vsPartialFlush = operations.pipelineStalls.vsPartialFlush;
+ marker.psPartialFlush = operations.pipelineStalls.psPartialFlush;
+ marker.csPartialFlush = operations.pipelineStalls.csPartialFlush;
+ marker.pfpSyncMe = operations.pipelineStalls.pfpSyncMe;
+ marker.syncCpDma = operations.pipelineStalls.syncCpDma;
+ marker.invalTcp = operations.caches.invalTcp;
+ marker.invalSqI = operations.caches.invalSqI$;
+ marker.invalSqK = operations.caches.invalSqK$;
+ marker.flushTcc = operations.caches.flushTcc;
+ marker.invalTcc = operations.caches.invalTcc;
+ marker.flushCb = operations.caches.flushCb;
+ marker.invalCb = operations.caches.invalCb;
+ marker.flushDb = operations.caches.flushDb;
+ marker.invalDb = operations.caches.invalDb;
+
+ marker.numLayoutTransitions = 0;
+
+ WriteMarker(&marker, sizeof(marker));
+ }
+}
+
+// =====================================================================================================================
+// Inserts a user event string marker
+void RgpCaptureMgr::WriteUserEventMarker(RgpSqttMarkerUserEventType eventType, const std::string& name) const
+{
+ memset(user_event_, 0, sizeof(RgpSqttMarkerUserEventWithString));
+
+ user_event_->header.identifier = RgpSqttMarkerIdentifierUserEvent;
+ user_event_->header.dataType = eventType;
+
+ size_t markerSize = sizeof(user_event_->header);
+
+ if ((eventType != RgpSqttMarkerUserEventPop)) {
+ size_t strLength = std::min(name.size(), RgpSqttMaxUserEventStringLengthInDwords * sizeof(uint32_t));
+ for (uint32_t charIdx = 0; charIdx < strLength; ++charIdx) {
+ uint32_t c = static_cast(name[charIdx]);
+ user_event_->stringData[charIdx / 4] |= (c << (8 * (charIdx % 4)));
+ user_event_->stringLength = static_cast(strLength);
+ }
+
+ // Every data type other than Pop includes a string length
+ markerSize += sizeof(uint32_t);
+
+ // Include string length (padded up to the nearest dword)
+ markerSize += sizeof(uint32_t) * ((strLength + sizeof(uint32_t) - 1) / sizeof(uint32_t));
+ }
+
+ WriteMarker(user_event_, markerSize);
+}
+
+
}; // namespace vk
diff --git a/rocclr/runtime/device/pal/palgpuopen.hpp b/rocclr/runtime/device/pal/palgpuopen.hpp
index b0c17ee2c2..42ba2f0a22 100644
--- a/rocclr/runtime/device/pal/palgpuopen.hpp
+++ b/rocclr/runtime/device/pal/palgpuopen.hpp
@@ -73,6 +73,7 @@ namespace pal
class Settings;
class Device;
class VirtualGPU;
+class HSAILKernel;
// ================================================================================================
// RgpSqttMarkerIdentifier - Identifiers for RGP SQ thread-tracing markers (Table 1)
@@ -99,13 +100,16 @@ enum RgpSqttMarkerIdentifier : uint32_t
// ================================================================================================
enum class RgpSqttMarkerEventType : uint32_t
{
- CmdDispatch = 6, // CmdDispatch
- CmdCopyBuffer = 8, // CmdCopyBuffer
- CmdCopyImage = 9, // CmdCopyImage
- CmdCopyBufferToImage = 11, // CmdCopyBufferToImage
- CmdCopyImageToBuffer = 12, // CmdCopyImageToBuffer
- CmdPipelineBarrier = 20, // CmdPipelineBarrier
- InternalUnknown = 26, // Uknown operaiton
+ CmdNDRangeKernel = 0,
+ CmdScheduler = 1,
+ CmdCopyBuffer = 2,
+ CmdCopyImageToBuffer = 3,
+ CmdCopyBufferToImage = 4,
+ CmdFillBuffer = 5,
+ CmdCopyImage = 6,
+ CmdFillImage = 7,
+ CmdPipelineBarrier = 8,
+ InternalUnknown = 26,
Invalid = 0xffffffff
};
@@ -242,6 +246,47 @@ constexpr uint32_t RgpSqttInstrumentationSpecVersion = 1;
// RGP SQTT Instrumentation Specification version for Vulkan-specific tables
constexpr uint32_t RgpSqttInstrumentationApiVersion = 0;
+// RgpSqttMarkeUserEventDataType - Data types used in RGP SQ thread-tracing markers for an user event
+enum RgpSqttMarkerUserEventType : uint32_t
+{
+ RgpSqttMarkerUserEventTrigger = 0x0,
+ RgpSqttMarkerUserEventPop = 0x1,
+ RgpSqttMarkerUserEventPush = 0x2,
+ RgpSqttMarkerUserEventObjectName = 0x3,
+ RgpSqttMarkerUserEventReserved1 = 0x4,
+ RgpSqttMarkerUserEventReserved2 = 0x5,
+ RgpSqttMarkerUserEventReserved3 = 0x6,
+ RgpSqttMarkerUserEventReserved4 = 0x7,
+};
+
+// RgpSqttMarkerUserEvent - RGP SQ thread-tracing marker for an user event.
+union RgpSqttMarkerUserEvent
+{
+ struct
+ {
+ uint32_t identifier : 4; // Identifier for this marker
+ uint32_t extDwords : 8; // Number of extra dwords following this marker
+ uint32_t dataType : 8; // The type for this marker
+ uint32_t reserved : 12; // reserved
+ };
+
+ uint32_t dword01; // The first dword
+};
+
+constexpr uint32_t RgpSqttMarkerUserEventWordCount = 1;
+
+// The max lengths of frame marker strings
+static constexpr size_t RgpSqttMaxUserEventStringLengthInDwords = 1024;
+
+// RgpSqttMarkerUserEvent - RGP SQ thread-tracing marker for an user event with a string (push and trigger data types)
+struct RgpSqttMarkerUserEventWithString
+{
+ RgpSqttMarkerUserEvent header;
+
+ uint32_t stringLength; // Length of the string (in characters)
+ uint32_t stringData[RgpSqttMaxUserEventStringLengthInDwords]; // String data in UTF-8 format
+};
+
// ================================================================================================
// This class provides functionality to interact with the GPU Open Developer Mode message passing
// service and the rest of the driver.
@@ -254,16 +299,20 @@ public:
void Finalize();
- void PreDispatch(VirtualGPU* pQueue, size_t x, size_t y, size_t z);
+ void PreDispatch(VirtualGPU* pQueue, const HSAILKernel& kernel, size_t x, size_t y, size_t z);
void PostDispatch(VirtualGPU* pQueue);
+
void WaitForDriverResume();
void PostDeviceCreate();
void PreDeviceDestroy();
- void FinishRGPTrace(bool aborted);
+ void FinishRGPTrace(VirtualGPU* gpu, bool aborted);
bool IsQueueTimingActive() const;
+ void WriteBarrierStartMarker(const Pal::Developer::BarrierData& data) const;
+ void WriteBarrierEndMarker(const Pal::Developer::BarrierData& data) const;
+
private:
// Steps that an RGP trace goes through
enum class TraceStatus
@@ -294,7 +343,7 @@ private:
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
- uint32_t current_event_id_; // Current event ID
+ mutable uint32_t current_event_id_; // Current event ID
};
RgpCaptureMgr(Pal::IPlatform* platform, const Device& device);
@@ -307,18 +356,20 @@ private:
void DestroyRGPTracing();
Pal::Result CheckForTraceResults();
static bool GpuSupportsTracing(const Pal::DeviceProperties& props, const Settings& settings);
- RgpSqttMarkerEvent BuildEventMarker(RgpSqttMarkerEventType api_type);
+ RgpSqttMarkerEvent BuildEventMarker(RgpSqttMarkerEventType api_type) const;
void WriteMarker(const void* data, size_t data_size) const;
- void WriteEventWithDimsMarker(RgpSqttMarkerEventType apiType, uint32_t x, uint32_t y, uint32_t z);
+ void WriteEventWithDimsMarker(RgpSqttMarkerEventType apiType, uint32_t x, uint32_t y, uint32_t z) const;
+ void WriteUserEventMarker(RgpSqttMarkerUserEventType eventType, const std::string& name) const;
const Device& device_;
DevDriver::DevDriverServer* dev_driver_server_;
DevDriver::RGPProtocol::RGPServer* rgp_server_;
- amd::Monitor trace_mutex_;
+ mutable amd::Monitor trace_mutex_;
TraceState trace_;
uint32_t num_prep_disp_;
uint32_t trace_gpu_mem_limit_;
uint32_t global_disp_count_;
+ RgpSqttMarkerUserEventWithString* user_event_;
bool trace_enabled_; // True if tracing is currently enabled (master flag)
bool inst_tracing_enabled_; // Enable instruction-level SQTT tokens
diff --git a/rocclr/runtime/device/pal/palvirtual.cpp b/rocclr/runtime/device/pal/palvirtual.cpp
index bcffd0c374..7192bb74c3 100644
--- a/rocclr/runtime/device/pal/palvirtual.cpp
+++ b/rocclr/runtime/device/pal/palvirtual.cpp
@@ -920,7 +920,7 @@ bool VirtualGPU::allocHsaQueueMem() {
VirtualGPU::~VirtualGPU() {
// Destroy RGP trace
if (rgpCaptureEna()) {
- dev().rgpCaptureMgr()->FinishRGPTrace(true);
+ dev().rgpCaptureMgr()->FinishRGPTrace(this, true);
}
// Not safe to remove a queue. So lock the device
@@ -2105,14 +2105,15 @@ bool VirtualGPU::submitKernelInternal(const amd::NDRangeContainer& sizes, const
newOffset[i] = sizes.offset()[i];
}
- // If RGP capturing is enabled, then start SQTT trace
- if (rgpCaptureEna()) {
- dev().rgpCaptureMgr()->PreDispatch(this, newGlobalSize[0], newGlobalSize[1], newGlobalSize[2]);
- }
-
// Get the HSA kernel object
const HSAILKernel& hsaKernel = static_cast(*(kernel.getDeviceKernel(dev())));
+ // If RGP capturing is enabled, then start SQTT trace
+ if (rgpCaptureEna()) {
+ dev().rgpCaptureMgr()->PreDispatch(this, hsaKernel,
+ newGlobalSize[0], newGlobalSize[1], newGlobalSize[2]);
+ }
+
bool printfEnabled = (hsaKernel.printfInfo().size() > 0) ? true : false;
if (printfEnabled && !printfDbgHSA().init(*this, printfEnabled)) {
LogError("Printf debug buffer initialization failed!");