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
Этот коммит содержится в:
@@ -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<Device*>(pPrivateData);
|
||||
const auto& barrier = *static_cast<const Pal::Developer::BarrierData*>(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;
|
||||
}
|
||||
|
||||
@@ -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&);
|
||||
|
||||
|
||||
@@ -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<uint32_t>(x), static_cast<uint32_t>(y), static_cast<uint32_t>(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<uint32_t>(name[charIdx]);
|
||||
user_event_->stringData[charIdx / 4] |= (c << (8 * (charIdx % 4)));
|
||||
user_event_->stringLength = static_cast<uint32_t>(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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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<const HSAILKernel&>(*(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!");
|
||||
|
||||
Ссылка в новой задаче
Block a user