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: 64fd3e50a0]
このコミットが含まれているのは:
@@ -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<uint32_t>(x), static_cast<uint32_t>(y), static_cast<uint32_t>(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<uint32_t>(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<uint32_t>(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
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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") \
|
||||
|
||||
新しいイシューから参照
ユーザーをブロックする