From 3a13de082ef24922aab67ebe9cc2966c188e1b64 Mon Sep 17 00:00:00 2001
From: foreman
Date: Tue, 19 Jun 2018 14:06:00 -0400
Subject: [PATCH] P4 to Git Change 1570202 by gandryey@gera-w8 on 2018/06/19
13:58:38
SWDEV-155436 - Write dispatch dimensions to COMPUTE registers for OpenCL support for RGP
- Add the dispatch dimensions to the RGP trace
Affected files ...
... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palgpuopen.cpp#2 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palgpuopen.hpp#2 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palvirtual.cpp#111 edit
... //depot/stg/opencl/drivers/opencl/runtime/utils/flags.hpp#290 edit
[ROCm/clr commit: 64fd3e50a0c6f01674411d2b78d7b1a6fcd3184e]
---
.../rocclr/runtime/device/pal/palgpuopen.cpp | 75 +++++--
.../rocclr/runtime/device/pal/palgpuopen.hpp | 198 ++++++++++++++++--
.../rocclr/runtime/device/pal/palvirtual.cpp | 23 +-
projects/clr/rocclr/runtime/utils/flags.hpp | 2 +-
4 files changed, 258 insertions(+), 40 deletions(-)
diff --git a/projects/clr/rocclr/runtime/device/pal/palgpuopen.cpp b/projects/clr/rocclr/runtime/device/pal/palgpuopen.cpp
index 8d5b89da99..5129d8e1f8 100644
--- a/projects/clr/rocclr/runtime/device/pal/palgpuopen.cpp
+++ b/projects/clr/rocclr/runtime/device/pal/palgpuopen.cpp
@@ -227,7 +227,7 @@ Pal::Result RgpCaptureMgr::CheckForTraceResults()
// Check if trace results are ready
if (trace_.gpa_session_->IsReady() && // GPA session is ready
- (trace_.trace_begin_queue_->isDone(&trace_.end_event_))) // "Trace end" cmdbuf has retired
+ (trace_.begin_queue_->isDone(&trace_.end_event_))) // "Trace end" cmdbuf has retired
{
bool success = false;
@@ -267,7 +267,7 @@ 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)
+void RgpCaptureMgr::PreDispatch(VirtualGPU* pQueue, size_t x, size_t y, size_t z)
{
// Wait for the driver to be resumed in case it's been paused.
WaitForDriverResume();
@@ -309,7 +309,7 @@ void RgpCaptureMgr::PreDispatch(VirtualGPU* pQueue)
else if (trace_.status_ == TraceStatus::WaitingForSqtt) {
Pal::Result result = Pal::Result::Success;
- if (trace_.trace_begin_queue_->isDone(&trace_.end_sqtt_event_)) {
+ if (trace_.begin_queue_->isDone(&trace_.end_sqtt_event_)) {
result = EndRGPTrace(pQueue);
} else {
// todo: There is a wait inside the trace end for now
@@ -333,6 +333,12 @@ void RgpCaptureMgr::PreDispatch(VirtualGPU* pQueue)
FinishRGPTrace(true);
}
}
+
+ if (trace_.status_ == TraceStatus::Running) {
+ // Write disaptch marker
+ WriteEventWithDimsMarker(RgpSqttMarkerEventType::CmdDispatch,
+ static_cast(x), static_cast(y), static_cast(z));
+ }
}
global_disp_count_++;
@@ -381,8 +387,8 @@ Pal::Result RgpCaptureMgr::PrepareRGPTrace(VirtualGPU* pQueue)
if (result == Pal::Result::Success) {
// Remember which queue started the trace
- trace_.trace_prepare_queue_ = pQueue;
- trace_.trace_begin_queue_ = nullptr;
+ trace_.prepare_queue_ = pQueue;
+ trace_.begin_queue_ = nullptr;
trace_.status_ = TraceStatus::Preparing;
} else {
@@ -415,7 +421,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_.trace_prepare_queue_ != pQueue) {
+ if (trace_.prepare_queue_ != pQueue) {
result = Pal::Result::ErrorIncompatibleQueue;
}
}
@@ -445,8 +451,8 @@ Pal::Result RgpCaptureMgr::BeginRGPTrace(VirtualGPU* pQueue)
// Make the trace active and remember which queue started it
if (result == Pal::Result::Success) {
- trace_.status_ = TraceStatus::Running;
- trace_.trace_begin_queue_ = pQueue;
+ trace_.status_ = TraceStatus::Running;
+ trace_.begin_queue_ = pQueue;
}
return result;
@@ -464,7 +470,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_.trace_begin_queue_) {
+ if (pQueue != trace_.begin_queue_) {
result = Pal::Result::ErrorIncompatibleQueue;
}
@@ -536,7 +542,7 @@ Pal::Result RgpCaptureMgr::EndRGPTrace(VirtualGPU* pQueue)
// It frees any dependent resources.
void RgpCaptureMgr::FinishRGPTrace(bool aborted)
{
- if (trace_.trace_prepare_queue_ == nullptr) {
+ if (trace_.prepare_queue_ == nullptr) {
return;
}
@@ -556,8 +562,8 @@ void RgpCaptureMgr::FinishRGPTrace(bool aborted)
trace_.sqtt_disp_count_ = 0;
trace_.gpa_sample_id_ = 0;
trace_.status_ = TraceStatus::Idle;
- trace_.trace_prepare_queue_ = nullptr;
- trace_.trace_begin_queue_ = nullptr;
+ trace_.prepare_queue_ = nullptr;
+ trace_.begin_queue_ = nullptr;
}
// ================================================================================================
@@ -620,4 +626,49 @@ void RgpCaptureMgr::PreDeviceDestroy()
}
}
+// ================================================================================================
+// Sets up an Event marker's basic data.
+RgpSqttMarkerEvent RgpCaptureMgr::BuildEventMarker(RgpSqttMarkerEventType api_type)
+{
+ RgpSqttMarkerEvent marker = {};
+
+ marker.identifier = RgpSqttMarkerIdentifierEvent;
+ marker.apiType = static_cast(api_type);
+ marker.cmdID = trace_.current_event_id_++;
+ marker.cbID = trace_.begin_queue_->queue(MainEngine).cmdBufId();
+
+ return marker;
+}
+
+// ================================================================================================
+void RgpCaptureMgr::WriteMarker(const void* data, size_t data_size) const
+{
+ assert((data_size % sizeof(uint32_t)) == 0);
+ assert((data_size / sizeof(uint32_t)) > 0);
+
+ trace_.begin_queue_->queue(MainEngine).iCmd()->CmdInsertRgpTraceMarker(
+ static_cast(data_size / sizeof(uint32_t)), data);
+}
+
+// =====================================================================================================================
+// Inserts an RGP pre-dispatch marker
+void RgpCaptureMgr::WriteEventWithDimsMarker(
+ RgpSqttMarkerEventType apiType,
+ uint32_t x,
+ uint32_t y,
+ uint32_t z)
+{
+ assert(apiType != RgpSqttMarkerEventType::Invalid);
+
+ RgpSqttMarkerEventWithDims eventWithDims = {};
+
+ eventWithDims.event = BuildEventMarker(apiType);
+ eventWithDims.event.hasThreadDims = 1;
+ eventWithDims.threadX = x;
+ eventWithDims.threadY = y;
+ eventWithDims.threadZ = z;
+
+ WriteMarker(&eventWithDims, sizeof(eventWithDims));
+}
+
}; // namespace vk
diff --git a/projects/clr/rocclr/runtime/device/pal/palgpuopen.hpp b/projects/clr/rocclr/runtime/device/pal/palgpuopen.hpp
index 0b3889763f..b0c17ee2c2 100644
--- a/projects/clr/rocclr/runtime/device/pal/palgpuopen.hpp
+++ b/projects/clr/rocclr/runtime/device/pal/palgpuopen.hpp
@@ -74,15 +74,177 @@ class Settings;
class Device;
class VirtualGPU;
+// ================================================================================================
+// RgpSqttMarkerIdentifier - Identifiers for RGP SQ thread-tracing markers (Table 1)
+enum RgpSqttMarkerIdentifier : uint32_t
+{
+ RgpSqttMarkerIdentifierEvent = 0x0,
+ RgpSqttMarkerIdentifierCbStart = 0x1,
+ RgpSqttMarkerIdentifierCbEnd = 0x2,
+ RgpSqttMarkerIdentifierBarrierStart = 0x3,
+ RgpSqttMarkerIdentifierBarrierEnd = 0x4,
+ RgpSqttMarkerIdentifierUserEvent = 0x5,
+ RgpSqttMarkerIdentifierGeneralApi = 0x6,
+ RgpSqttMarkerIdentifierSync = 0x7,
+ RgpSqttMarkerIdentifierPresent = 0x8,
+ RgpSqttMarkerIdentifierLayoutTransition = 0x9,
+ RgpSqttMarkerIdentifierRenderPass = 0xA,
+ RgpSqttMarkerIdentifierReserved2 = 0xB,
+ RgpSqttMarkerIdentifierReserved3 = 0xC,
+ RgpSqttMarkerIdentifierReserved4 = 0xD,
+ RgpSqttMarkerIdentifierReserved5 = 0xE,
+ RgpSqttMarkerIdentifierReserved6 = 0xF
+};
+
+// ================================================================================================
+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
+ Invalid = 0xffffffff
+};
+
+// ================================================================================================
+// RgpSqttMarkerEvent - "Event (Per-draw/dispatch)" RGP SQ thread-tracing marker.
+// These are generated ahead of draws or dispatches for commands that trigger generation of waves
+// i.e. draws/dispatches (Table 4).
+struct RgpSqttMarkerEvent
+{
+ union
+ {
+ struct
+ {
+ uint32_t identifier : 4; // Identifier for this marker
+ uint32_t extDwords : 3; // Number of extra dwords following this marker
+ uint32_t apiType : 24; // The API type for this command
+ uint32_t hasThreadDims : 1; // Whether thread dimensions are included
+ };
+
+ uint32_t dword01; // The first dword
+ };
+
+ union
+ {
+ // Some information about the vertex/instance/draw register indices. These values are not
+ // always valid because they are not available for one reason or another:
+ //
+ // - If vertex offset index or instance offset index are not (together) valid, they are both
+ // equal to 0
+ // - If draw index is not valid, it is equal to the vertex offset index
+ struct
+ {
+ uint32_t cbID : 20; // Command buffer ID for this marker
+ uint32_t vertexOffsetRegIdx : 4; // SPI userdata register index for the first vertex offset
+ uint32_t instanceOffsetRegIdx : 4; // SPI userdata register index for the first instance offset
+ uint32_t drawIndexRegIdx : 4; // SPI userdata register index for the draw index (multi draw indirect)
+ };
+ uint32_t dword02; // The second dword
+ };
+
+ union
+ {
+ uint32_t cmdID; // Command index within the command buffer
+ uint32_t dword03; // The third dword
+ };
+};
+
+// ================================================================================================
+// RgpSqttMarkerEventWithDims - Per-dispatch specific marker where workgroup dims are included
+struct RgpSqttMarkerEventWithDims
+{
+ RgpSqttMarkerEvent event; // Per-draw/dispatch marker. API type should be Dispatch, threadDim = 1
+ uint32_t threadX; // Work group count in X
+ uint32_t threadY; // Work group count in Y
+ uint32_t threadZ; // Work group count in Z
+};
+
+// ================================================================================================
+// RgpSqttMarkerBarrierStart - "Barrier Start" RGP SQTT instrumentation marker (Table 5)
+struct RgpSqttMarkerBarrierStart
+{
+ union
+ {
+ struct
+ {
+ uint32_t identifier : 4; // Identifier for this marker
+ uint32_t extDwords : 3; // Number of extra dwords following this marker
+ uint32_t cbId : 20; // Command buffer ID within queue
+ uint32_t reserved : 5; // Reserved
+ };
+
+ uint32_t dword01; // The first dword
+ };
+
+ union
+ {
+ struct
+ {
+ uint32_t driverReason : 31;
+ uint32_t internal: 1;
+ };
+
+ uint32_t dword02; // The second dword
+ };
+};
+
+// ================================================================================================
+// RgpSqttMarkerBarrierEnd - "Barrier End" RGP SQTT instrumentation marker (Table 6)
+struct RgpSqttMarkerBarrierEnd
+{
+ union
+ {
+ struct
+ {
+ uint32_t identifier : 4; // Identifier for this marker
+ uint32_t extDwords : 3; // Number of extra dwords following this marker
+ uint32_t cbId : 20; // Command buffer ID within queue
+ uint32_t waitOnEopTs : 1; // Issued EOP_TS VGT event followed by a WAIT_REG_MEM for that timestamp
+ // to be written. Quintessential full pipeline stall.
+ uint32_t vsPartialFlush : 1; // Stall at ME waiting for all prior VS waves to complete.
+ uint32_t psPartialFlush : 1; // Stall at ME waiting for all prior PS waves to complete.
+ uint32_t csPartialFlush : 1; // Stall at ME waiting for all prior CS waves to complete.
+ uint32_t pfpSyncMe : 1; // Stall PFP until ME is at same point in command stream.
+ };
+
+ uint32_t dword01; // The first dword
+ };
+
+ union
+ {
+ struct
+ {
+ uint32_t syncCpDma : 1; // Issue dummy CP-DMA command to confirm all prior CP-DMAs have completed.
+ uint32_t invalTcp : 1; // Invalidate the L1 vector caches.
+ uint32_t invalSqI : 1; // Invalidate the SQ instruction caches
+ uint32_t invalSqK : 1; // Invalidate the SQ constant caches (i.e. L1 scalar caches)
+ uint32_t flushTcc : 1; // Flush L2
+ uint32_t invalTcc : 1; // Invalidate L2
+ uint32_t flushCb : 1; // Flush CB caches (including DCC, cmask, fmask)
+ uint32_t invalCb : 1; // Invalidate CB caches (including DCC, cmask, fmask)
+ uint32_t flushDb : 1; // Flush DB caches (including htile)
+ uint32_t invalDb : 1; // Invalidate DB caches (including htile)
+ uint32_t numLayoutTransitions : 16; // Number of layout transitions following this packet
+ uint32_t reserved : 6; // Reserved for future expansion. Always 0
+ };
+
+ uint32_t dword02; // The second dword
+ };
+};
+
// RGP SQTT Instrumentation Specification version (API-independent)
constexpr uint32_t RgpSqttInstrumentationSpecVersion = 1;
// RGP SQTT Instrumentation Specification version for Vulkan-specific tables
constexpr uint32_t RgpSqttInstrumentationApiVersion = 0;
-// =====================================================================================================================
-// This class provides functionality to interact with the GPU Open Developer Mode message passing service and the rest
-// of the driver.
+// ================================================================================================
+// This class provides functionality to interact with the GPU Open Developer Mode message passing
+// service and the rest of the driver.
class RgpCaptureMgr
{
public:
@@ -92,7 +254,7 @@ public:
void Finalize();
- void PreDispatch(VirtualGPU* pQueue);
+ void PreDispatch(VirtualGPU* pQueue, size_t x, size_t y, size_t z);
void PostDispatch(VirtualGPU* pQueue);
void WaitForDriverResume();
@@ -117,21 +279,22 @@ private:
// All per-device state to support RGP tracing
struct TraceState
{
- TraceStatus status_; // Current trace status (idle, running, etc.)
+ 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
+ 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* trace_prepare_queue_; // The queue that triggered the full start of a trace
- VirtualGPU* trace_begin_queue_; // The queue that triggered starting SQTT
+ VirtualGPU* prepare_queue_; // The queue that triggered the full start of a trace
+ 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
+ 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
+ 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
};
RgpCaptureMgr(Pal::IPlatform* platform, const Device& device);
@@ -144,6 +307,9 @@ private:
void DestroyRGPTracing();
Pal::Result CheckForTraceResults();
static bool GpuSupportsTracing(const Pal::DeviceProperties& props, const Settings& settings);
+ RgpSqttMarkerEvent BuildEventMarker(RgpSqttMarkerEventType api_type);
+ void WriteMarker(const void* data, size_t data_size) const;
+ void WriteEventWithDimsMarker(RgpSqttMarkerEventType apiType, uint32_t x, uint32_t y, uint32_t z);
const Device& device_;
DevDriver::DevDriverServer* dev_driver_server_;
@@ -160,7 +326,7 @@ private:
PAL_DISALLOW_COPY_AND_ASSIGN(RgpCaptureMgr);
};
-// =====================================================================================================================
+// ================================================================================================
// Returns true if queue operations are currently being timed by RGP traces.
inline bool RgpCaptureMgr::IsQueueTimingActive() const
{
diff --git a/projects/clr/rocclr/runtime/device/pal/palvirtual.cpp b/projects/clr/rocclr/runtime/device/pal/palvirtual.cpp
index feff0b95ca..bcffd0c374 100644
--- a/projects/clr/rocclr/runtime/device/pal/palvirtual.cpp
+++ b/projects/clr/rocclr/runtime/device/pal/palvirtual.cpp
@@ -2094,9 +2094,20 @@ bool VirtualGPU::submitKernelInternal(const amd::NDRangeContainer& sizes, const
const_address parameters, bool nativeMem,
amd::Event* enqueueEvent)
{
+ size_t newOffset[3] = { 0, 0, 0 };
+ size_t newGlobalSize[3] = { 0, 0, 0 };
+
+ int dim = -1;
+ int iteration = 1;
+ size_t globalStep = 0;
+ for (uint i = 0; i < sizes.dimensions(); i++) {
+ newGlobalSize[i] = sizes.global()[i];
+ newOffset[i] = sizes.offset()[i];
+ }
+
// If RGP capturing is enabled, then start SQTT trace
if (rgpCaptureEna()) {
- dev().rgpCaptureMgr()->PreDispatch(this);
+ dev().rgpCaptureMgr()->PreDispatch(this, newGlobalSize[0], newGlobalSize[1], newGlobalSize[2]);
}
// Get the HSA kernel object
@@ -2135,16 +2146,6 @@ bool VirtualGPU::submitKernelInternal(const amd::NDRangeContainer& sizes, const
}
}
- size_t newOffset[3] = {0, 0, 0};
- size_t newGlobalSize[3] = {0, 0, 0};
-
- int dim = -1;
- int iteration = 1;
- size_t globalStep = 0;
- for (uint i = 0; i < sizes.dimensions(); i++) {
- newGlobalSize[i] = sizes.global()[i];
- newOffset[i] = sizes.offset()[i];
- }
// Check if it is blit kernel. If it is, then check if split is needed.
if (hsaKernel.isInternalKernel()) {
// Calculate new group size for each submission
diff --git a/projects/clr/rocclr/runtime/utils/flags.hpp b/projects/clr/rocclr/runtime/utils/flags.hpp
index 138cc81f63..9c3afe475f 100644
--- a/projects/clr/rocclr/runtime/utils/flags.hpp
+++ b/projects/clr/rocclr/runtime/utils/flags.hpp
@@ -197,7 +197,7 @@ release(bool, GPU_VEGA10_ONLY, VEGA10_ONLY, \
"1 = Report vega10 only on OCL/ROCR") \
release_on_stg(bool, PAL_DISABLE_SDMA, false, \
"1 = Disable SDMA for PAL") \
-release_on_stg(uint, PAL_RGP_DISP_COUNT, 10, \
+release(uint, PAL_RGP_DISP_COUNT, 10, \
"The number of dispatches for RGP capture with SQTT") \
release(bool, GPU_FORCE_WAVE_SIZE_32, false, \
"Forces WaveSize32 compilation in SC") \