// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. // Don't include this file directly - use pix3.h #pragma once #ifndef _PixEvents_H_ #define _PixEvents_H_ #ifndef _PIX3_H_ # error Do not include this file directly - use pix3.h #endif #include "PIXEventsCommon.h" #if _MSC_VER < 1800 # error This version of pix3.h is only supported on Visual Studio 2013 or higher #elif _MSC_VER < 1900 # ifndef constexpr // Visual Studio 2013 doesn't support constexpr # define constexpr # define PIX3__DEFINED_CONSTEXPR # endif #endif // Xbox does not support CPU events for retail scenarios #if defined(USE_PIX) || !defined(PIX_XBOX) #define PIX_CONTEXT_EMIT_CPU_EVENTS #endif namespace PIXEventsDetail { inline void PIXCopyEventArguments(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit) { // nothing UNREFERENCED_PARAMETER(destination); UNREFERENCED_PARAMETER(limit); } template void PIXCopyEventArguments(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, ARG const& arg, ARGS const&... args) { PIXCopyEventArgument(destination, limit, arg); PIXCopyEventArguments(destination, limit, args...); } template void PIXCopyStringArguments(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, ARG const& arg, ARGS const&... args) { PIXCopyStringArgument(destination, limit, arg); PIXCopyEventArguments(destination, limit, args...); } template void PIXCopyStringArgumentsWithContext(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, void* context, ARG const& arg, ARGS const&... args) { #ifdef PIX_XBOX UNREFERENCED_PARAMETER(context); PIXCopyStringArgument(destination, limit, arg); PIXCopyEventArguments(destination, limit, args...); #else PIXCopyEventArgument(destination, limit, context); PIXCopyStringArgument(destination, limit, arg); PIXCopyEventArguments(destination, limit, args...); #endif } inline UINT8 PIXGetEventSize(const UINT64* end, const UINT64* start) { const UINT64 actualEventSize = end - start; return static_cast(actualEventSize > PIXEventsSizeMax ? PIXEventsSizeMax : actualEventSize); } template inline UINT8 PIXEncodeStringIsAnsi() { return PIX_EVENT_METADATA_NONE; } template<> inline UINT8 PIXEncodeStringIsAnsi() { return PIX_EVENT_METADATA_STRING_IS_ANSI; } template<> inline UINT8 PIXEncodeStringIsAnsi() { return PIX_EVENT_METADATA_STRING_IS_ANSI; } template __declspec(noinline) void PIXBeginEventAllocate(PIXEventsThreadInfo* threadInfo, UINT64 color, STR formatString, ARGS... args) { UINT64 time = PIXEventsReplaceBlock(threadInfo, false); if (!time) return; UINT64* destination = threadInfo->destination; UINT64* limit = threadInfo->biasedLimit; if (destination >= limit) return; limit += PIXEventsSafeFastCopySpaceQwords; UINT64* eventDestination = destination++; *destination++ = color; PIXCopyStringArguments(destination, limit, formatString, args...); *destination = PIXEventsBlockEndMarker; const UINT8 eventSize = PIXGetEventSize(destination, threadInfo->destination); const UINT8 eventMetadata = PIX_EVENT_METADATA_HAS_COLOR | PIXEncodeStringIsAnsi(); *eventDestination = PIXEncodeEventInfo(time, PIXEvent_BeginEvent, eventSize, eventMetadata); threadInfo->destination = destination; } template void PIXBeginEvent(UINT64 color, STR formatString, ARGS... args) { PIXEventsThreadInfo* threadInfo = PIXGetThreadInfo(); UINT64* limit = threadInfo->biasedLimit; if (limit != nullptr) { UINT64* destination = threadInfo->destination; if (destination < limit) { limit += PIXEventsSafeFastCopySpaceQwords; UINT64 time = PIXGetTimestampCounter(); UINT64* eventDestination = destination++; *destination++ = color; PIXCopyStringArguments(destination, limit, formatString, args...); *destination = PIXEventsBlockEndMarker; const UINT8 eventSize = PIXGetEventSize(destination, threadInfo->destination); const UINT8 eventMetadata = PIX_EVENT_METADATA_HAS_COLOR | PIXEncodeStringIsAnsi(); *eventDestination = PIXEncodeEventInfo(time, PIXEvent_BeginEvent, eventSize, eventMetadata); threadInfo->destination = destination; } else { PIXBeginEventAllocate(threadInfo, color, formatString, args...); } } } template __declspec(noinline) void PIXBeginEventAllocate(PIXEventsThreadInfo* threadInfo, UINT8 color, STR formatString, ARGS... args) { UINT64 time = PIXEventsReplaceBlock(threadInfo, false); if (!time) return; UINT64* destination = threadInfo->destination; UINT64* limit = threadInfo->biasedLimit; if (destination >= limit) return; limit += PIXEventsSafeFastCopySpaceQwords; UINT64* eventDestination = destination++; PIXCopyStringArguments(destination, limit, formatString, args...); *destination = PIXEventsBlockEndMarker; const UINT8 eventSize = PIXGetEventSize(destination, threadInfo->destination); const UINT8 eventMetadata = PIXEncodeStringIsAnsi() | PIXEncodeIndexColor(color); *eventDestination = PIXEncodeEventInfo(time, PIXEvent_BeginEvent, eventSize, eventMetadata); threadInfo->destination = destination; } template void PIXBeginEvent(UINT8 color, STR formatString, ARGS... args) { PIXEventsThreadInfo* threadInfo = PIXGetThreadInfo(); UINT64* limit = threadInfo->biasedLimit; if (limit != nullptr) { UINT64* destination = threadInfo->destination; if (destination < limit) { limit += PIXEventsSafeFastCopySpaceQwords; UINT64 time = PIXGetTimestampCounter(); UINT64* eventDestination = destination++; PIXCopyStringArguments(destination, limit, formatString, args...); *destination = PIXEventsBlockEndMarker; const UINT8 eventSize = PIXGetEventSize(destination, threadInfo->destination); const UINT8 eventMetadata = PIXEncodeStringIsAnsi() | PIXEncodeIndexColor(color); *eventDestination = PIXEncodeEventInfo(time, PIXEvent_BeginEvent, eventSize, eventMetadata); threadInfo->destination = destination; } else { PIXBeginEventAllocate(threadInfo, color, formatString, args...); } } } template __declspec(noinline) void PIXSetMarkerAllocate(PIXEventsThreadInfo* threadInfo, UINT64 color, STR formatString, ARGS... args) { UINT64 time = PIXEventsReplaceBlock(threadInfo, false); if (!time) return; UINT64* destination = threadInfo->destination; UINT64* limit = threadInfo->biasedLimit; if (destination >= limit) return; limit += PIXEventsSafeFastCopySpaceQwords; UINT64* eventDestination = destination++; *destination++ = color; PIXCopyStringArguments(destination, limit, formatString, args...); *destination = PIXEventsBlockEndMarker; const UINT8 eventSize = PIXGetEventSize(destination, threadInfo->destination); const UINT8 eventMetadata = PIXEncodeStringIsAnsi() | PIX_EVENT_METADATA_HAS_COLOR; *eventDestination = PIXEncodeEventInfo(time, PIXEvent_SetMarker, eventSize, eventMetadata); threadInfo->destination = destination; } template void PIXSetMarker(UINT64 color, STR formatString, ARGS... args) { PIXEventsThreadInfo* threadInfo = PIXGetThreadInfo(); UINT64* limit = threadInfo->biasedLimit; if (limit != nullptr) { UINT64* destination = threadInfo->destination; if (destination < limit) { limit += PIXEventsSafeFastCopySpaceQwords; UINT64 time = PIXGetTimestampCounter(); UINT64* eventDestination = destination++; *destination++ = color; PIXCopyStringArguments(destination, limit, formatString, args...); *destination = PIXEventsBlockEndMarker; const UINT8 eventSize = PIXGetEventSize(destination, threadInfo->destination); const UINT8 eventMetadata = PIXEncodeStringIsAnsi() | PIX_EVENT_METADATA_HAS_COLOR; *eventDestination = PIXEncodeEventInfo(time, PIXEvent_SetMarker, eventSize, eventMetadata); threadInfo->destination = destination; } else { PIXSetMarkerAllocate(threadInfo, color, formatString, args...); } } } template __declspec(noinline) void PIXSetMarkerAllocate(PIXEventsThreadInfo* threadInfo, UINT8 color, STR formatString, ARGS... args) { UINT64 time = PIXEventsReplaceBlock(threadInfo, false); if (!time) return; UINT64* destination = threadInfo->destination; UINT64* limit = threadInfo->biasedLimit; if (destination >= limit) return; limit += PIXEventsSafeFastCopySpaceQwords; UINT64* eventDestination = destination++; PIXCopyStringArguments(destination, limit, formatString, args...); *destination = PIXEventsBlockEndMarker; const UINT8 eventSize = PIXGetEventSize(destination, threadInfo->destination); const UINT8 eventMetadata = PIXEncodeStringIsAnsi() | PIXEncodeIndexColor(color); *eventDestination = PIXEncodeEventInfo(time, PIXEvent_SetMarker, eventSize, eventMetadata); threadInfo->destination = destination; } template void PIXSetMarker(UINT8 color, STR formatString, ARGS... args) { PIXEventsThreadInfo* threadInfo = PIXGetThreadInfo(); UINT64* limit = threadInfo->biasedLimit; if (limit != nullptr) { UINT64* destination = threadInfo->destination; if (destination < limit) { limit += PIXEventsSafeFastCopySpaceQwords; UINT64 time = PIXGetTimestampCounter(); UINT64* eventDestination = destination++; PIXCopyStringArguments(destination, limit, formatString, args...); *destination = PIXEventsBlockEndMarker; const UINT8 eventSize = PIXGetEventSize(destination, threadInfo->destination); const UINT8 eventMetadata = PIXEncodeStringIsAnsi() | PIXEncodeIndexColor(color); *eventDestination = PIXEncodeEventInfo(time, PIXEvent_SetMarker, eventSize, eventMetadata); threadInfo->destination = destination; } else { PIXSetMarkerAllocate(threadInfo, color, formatString, args...); } } } template __declspec(noinline) void PIXBeginEventOnContextCpuAllocate(UINT64*& eventDestination, UINT8& eventSize, PIXEventsThreadInfo* threadInfo, void* context, UINT64 color, STR formatString, ARGS... args) { UINT64 time = PIXEventsReplaceBlock(threadInfo, false); if (!time) { eventDestination = nullptr; return; } UINT64* destination = threadInfo->destination; UINT64* limit = threadInfo->biasedLimit; if (destination >= limit) { eventDestination = nullptr; return; } limit += PIXEventsSafeFastCopySpaceQwords; eventDestination = destination++; *destination++ = color; PIXCopyStringArgumentsWithContext(destination, limit, context, formatString, args...); *destination = PIXEventsBlockEndMarker; eventSize = PIXGetEventSize(destination, threadInfo->destination); const UINT8 eventMetadata = PIX_EVENT_METADATA_ON_CONTEXT | PIXEncodeStringIsAnsi() | PIX_EVENT_METADATA_HAS_COLOR; *eventDestination = PIXEncodeEventInfo(time, PIXEvent_BeginEvent, eventSize, eventMetadata); threadInfo->destination = destination; } template void PIXBeginEventOnContextCpu(UINT64*& eventDestination, UINT8& eventSize, void* context, UINT64 color, STR formatString, ARGS... args) { PIXEventsThreadInfo* threadInfo = PIXGetThreadInfo(); UINT64* limit = threadInfo->biasedLimit; if (limit == nullptr) { eventDestination = nullptr; return; } UINT64* destination = threadInfo->destination; if (destination < limit) { limit += PIXEventsSafeFastCopySpaceQwords; UINT64 time = PIXGetTimestampCounter(); eventDestination = destination++; *destination++ = color; PIXCopyStringArgumentsWithContext(destination, limit, context, formatString, args...); *destination = PIXEventsBlockEndMarker; eventSize = PIXGetEventSize(destination, threadInfo->destination); const UINT8 eventMetadata = PIX_EVENT_METADATA_ON_CONTEXT | PIXEncodeStringIsAnsi() | PIX_EVENT_METADATA_HAS_COLOR; *eventDestination = PIXEncodeEventInfo(time, PIXEvent_BeginEvent, eventSize, eventMetadata); threadInfo->destination = destination; } else { PIXBeginEventOnContextCpuAllocate(eventDestination, eventSize, threadInfo, context, color, formatString, args...); } } template void PIXBeginEvent(CONTEXT* context, UINT64 color, STR formatString, ARGS... args) { UINT64* destination = nullptr; UINT8 eventSize = 0u; #ifdef PIX_CONTEXT_EMIT_CPU_EVENTS PIXBeginEventOnContextCpu(destination, eventSize, context, color, formatString, args...); #endif #ifdef PIX_USE_GPU_MARKERS_V2 if (destination != nullptr) { PIXInsertTimingMarkerOnContextForBeginEvent(context, PIXEvent_BeginEvent, static_cast(destination), eventSize * sizeof(UINT64)); } else #endif { UINT64 buffer[PIXEventsGraphicsRecordSpaceQwords]; #ifdef PIX_USE_GPU_MARKERS_V2 destination = buffer; UINT64* limit = buffer + PIXEventsGraphicsRecordSpaceQwords - PIXEventsReservedTailSpaceQwords; UINT64* eventDestination = destination++; *destination++ = color; PIXCopyStringArgumentsWithContext(destination, limit, context, formatString, args...); *destination = 0ull; eventSize = static_cast(destination - buffer); const UINT8 eventMetadata = PIX_EVENT_METADATA_ON_CONTEXT | PIXEncodeStringIsAnsi() | PIX_EVENT_METADATA_HAS_COLOR; *eventDestination = PIXEncodeEventInfo(0, PIXEvent_BeginEvent, eventSize, eventMetadata); PIXInsertGPUMarkerOnContextForBeginEvent(context, PIXEvent_BeginEvent, static_cast(buffer), static_cast(reinterpret_cast(destination) - reinterpret_cast(buffer))); #else destination = PixEventsLegacy::EncodeBeginEventForContext(buffer, color, formatString, args...); PIXBeginGPUEventOnContext(context, static_cast(buffer), static_cast(reinterpret_cast(destination) - reinterpret_cast(buffer))); #endif } } template __declspec(noinline) void PIXBeginEventOnContextCpuAllocate(UINT64*& eventDestination, UINT8& eventSize, PIXEventsThreadInfo* threadInfo, void* context, UINT8 color, STR formatString, ARGS... args) { UINT64 time = PIXEventsReplaceBlock(threadInfo, false); if (!time) { eventDestination = nullptr; return; } UINT64* destination = threadInfo->destination; UINT64* limit = threadInfo->biasedLimit; if (destination >= limit) { eventDestination = nullptr; return; } limit += PIXEventsSafeFastCopySpaceQwords; eventDestination = destination++; PIXCopyStringArgumentsWithContext(destination, limit, context, formatString, args...); *destination = PIXEventsBlockEndMarker; eventSize = PIXGetEventSize(destination, threadInfo->destination); const UINT8 eventMetadata = PIX_EVENT_METADATA_ON_CONTEXT | PIXEncodeStringIsAnsi() | PIXEncodeIndexColor(color); *eventDestination = PIXEncodeEventInfo(time, PIXEvent_BeginEvent, eventSize, eventMetadata); threadInfo->destination = destination; } template void PIXBeginEventOnContextCpu(UINT64*& eventDestination, UINT8& eventSize, void* context, UINT8 color, STR formatString, ARGS... args) { PIXEventsThreadInfo* threadInfo = PIXGetThreadInfo(); UINT64* limit = threadInfo->biasedLimit; if (limit == nullptr) { eventDestination = nullptr; return; } UINT64* destination = threadInfo->destination; if (destination < limit) { limit += PIXEventsSafeFastCopySpaceQwords; UINT64 time = PIXGetTimestampCounter(); eventDestination = destination++; PIXCopyStringArgumentsWithContext(destination, limit, context, formatString, args...); *destination = PIXEventsBlockEndMarker; eventSize = PIXGetEventSize(destination, threadInfo->destination); const UINT8 eventMetadata = PIX_EVENT_METADATA_ON_CONTEXT | PIXEncodeStringIsAnsi() | PIXEncodeIndexColor(color); *eventDestination = PIXEncodeEventInfo(time, PIXEvent_BeginEvent, eventSize, eventMetadata); threadInfo->destination = destination; } else { PIXBeginEventOnContextCpuAllocate(eventDestination, eventSize, threadInfo, context, color, formatString, args...); } } template void PIXBeginEvent(CONTEXT* context, UINT8 color, STR formatString, ARGS... args) { UINT64* destination = nullptr; UINT8 eventSize = 0u; #ifdef PIX_CONTEXT_EMIT_CPU_EVENTS PIXBeginEventOnContextCpu(destination, eventSize, context, color, formatString, args...); #endif #ifdef PIX_USE_GPU_MARKERS_V2 if (destination != nullptr) { PIXInsertTimingMarkerOnContextForBeginEvent(context, PIXEvent_BeginEvent, static_cast(destination), eventSize * sizeof(UINT64)); } else #endif { UINT64 buffer[PIXEventsGraphicsRecordSpaceQwords]; #ifdef PIX_USE_GPU_MARKERS_V2 destination = buffer; UINT64* limit = buffer + PIXEventsGraphicsRecordSpaceQwords - PIXEventsReservedTailSpaceQwords; UINT64* eventDestination = destination++; PIXCopyStringArgumentsWithContext(destination, limit, context, formatString, args...); *destination = 0ull; eventSize = static_cast(destination - buffer); const UINT8 eventMetadata = PIX_EVENT_METADATA_ON_CONTEXT | PIXEncodeStringIsAnsi() | PIXEncodeIndexColor(color); *eventDestination = PIXEncodeEventInfo(0, PIXEvent_BeginEvent, eventSize, eventMetadata); PIXInsertGPUMarkerOnContextForBeginEvent(context, PIXEvent_BeginEvent, static_cast(buffer), static_cast(reinterpret_cast(destination) - reinterpret_cast(buffer))); #else destination = PixEventsLegacy::EncodeBeginEventForContext(buffer, color, formatString, args...); PIXBeginGPUEventOnContext(context, static_cast(buffer), static_cast(reinterpret_cast(destination) - reinterpret_cast(buffer))); #endif } } template __declspec(noinline) void PIXSetMarkerOnContextCpuAllocate(UINT64*& eventDestination, UINT8& eventSize, PIXEventsThreadInfo* threadInfo, void* context, UINT64 color, STR formatString, ARGS... args) { UINT64 time = PIXEventsReplaceBlock(threadInfo, false); if (!time) { eventDestination = nullptr; return; } UINT64* destination = threadInfo->destination; UINT64* limit = threadInfo->biasedLimit; if (destination >= limit) { eventDestination = nullptr; return; } limit += PIXEventsSafeFastCopySpaceQwords; eventDestination = destination++; *destination++ = color; PIXCopyStringArgumentsWithContext(destination, limit, context, formatString, args...); *destination = PIXEventsBlockEndMarker; eventSize = PIXGetEventSize(destination, threadInfo->destination); const UINT8 eventMetadata = PIX_EVENT_METADATA_ON_CONTEXT | PIXEncodeStringIsAnsi() | PIX_EVENT_METADATA_HAS_COLOR; *eventDestination = PIXEncodeEventInfo(time, PIXEvent_SetMarker, eventSize, eventMetadata); threadInfo->destination = destination; } template void PIXSetMarkerOnContextCpu(UINT64*& eventDestination, UINT8& eventSize, void* context, UINT64 color, STR formatString, ARGS... args) { PIXEventsThreadInfo* threadInfo = PIXGetThreadInfo(); UINT64* limit = threadInfo->biasedLimit; if (limit == nullptr) { eventDestination = nullptr; return; } UINT64* destination = threadInfo->destination; if (destination < limit) { limit += PIXEventsSafeFastCopySpaceQwords; UINT64 time = PIXGetTimestampCounter(); eventDestination = destination++; *destination++ = color; PIXCopyStringArgumentsWithContext(destination, limit, context, formatString, args...); *destination = PIXEventsBlockEndMarker; eventSize = PIXGetEventSize(destination, threadInfo->destination); const UINT8 eventMetadata = PIX_EVENT_METADATA_ON_CONTEXT | PIXEncodeStringIsAnsi() | PIX_EVENT_METADATA_HAS_COLOR; *eventDestination = PIXEncodeEventInfo(time, PIXEvent_SetMarker, eventSize, eventMetadata); threadInfo->destination = destination; } else { PIXSetMarkerOnContextCpuAllocate(eventDestination, eventSize, threadInfo, context, color, formatString, args...); } } template void PIXSetMarker(CONTEXT* context, UINT64 color, STR formatString, ARGS... args) { UINT64* destination = nullptr; UINT8 eventSize = 0u; #ifdef PIX_CONTEXT_EMIT_CPU_EVENTS PIXSetMarkerOnContextCpu(destination, eventSize, context, color, formatString, args...); #endif #ifdef PIX_USE_GPU_MARKERS_V2 if (destination != nullptr) { PIXInsertTimingMarkerOnContextForSetMarker(context, PIXEvent_SetMarker, static_cast(destination), eventSize * sizeof(UINT64)); } else #endif { UINT64 buffer[PIXEventsGraphicsRecordSpaceQwords]; #ifdef PIX_USE_GPU_MARKERS_V2 destination = buffer; UINT64* limit = buffer + PIXEventsGraphicsRecordSpaceQwords - PIXEventsReservedTailSpaceQwords; UINT64* eventDestination = destination++; *destination++ = color; PIXCopyStringArgumentsWithContext(destination, limit, context, formatString, args...); *destination = 0ull; eventSize = static_cast(destination - buffer); const UINT8 eventMetadata = PIX_EVENT_METADATA_ON_CONTEXT | PIXEncodeStringIsAnsi() | PIX_EVENT_METADATA_HAS_COLOR; *eventDestination = PIXEncodeEventInfo(0, PIXEvent_SetMarker, eventSize, eventMetadata); PIXInsertGPUMarkerOnContextForSetMarker(context, PIXEvent_SetMarker, static_cast(buffer), static_cast(reinterpret_cast(destination) - reinterpret_cast(buffer))); #else destination = PixEventsLegacy::EncodeSetMarkerForContext(buffer, color, formatString, args...); PIXSetGPUMarkerOnContext(context, static_cast(buffer), static_cast(reinterpret_cast(destination) - reinterpret_cast(buffer))); #endif } } template __declspec(noinline) void PIXSetMarkerOnContextCpuAllocate(UINT64*& eventDestination, UINT8& eventSize, PIXEventsThreadInfo* threadInfo, void* context, UINT8 color, STR formatString, ARGS... args) { UINT64 time = PIXEventsReplaceBlock(threadInfo, false); if (!time) { eventDestination = nullptr; return; } UINT64* destination = threadInfo->destination; UINT64* limit = threadInfo->biasedLimit; if (destination >= limit) { eventDestination = nullptr; return; } limit += PIXEventsSafeFastCopySpaceQwords; eventDestination = destination++; PIXCopyStringArgumentsWithContext(destination, limit, context, formatString, args...); *destination = PIXEventsBlockEndMarker; eventSize = PIXGetEventSize(destination, threadInfo->destination); const UINT8 eventMetadata = PIX_EVENT_METADATA_ON_CONTEXT | PIXEncodeStringIsAnsi() | PIXEncodeIndexColor(color); *eventDestination = PIXEncodeEventInfo(time, PIXEvent_SetMarker, eventSize, eventMetadata); threadInfo->destination = destination; } template void PIXSetMarkerOnContextCpu(UINT64*& eventDestination, UINT8& eventSize, void* context, UINT8 color, STR formatString, ARGS... args) { PIXEventsThreadInfo* threadInfo = PIXGetThreadInfo(); UINT64* limit = threadInfo->biasedLimit; if (limit == nullptr) { eventDestination = nullptr; return; } UINT64* destination = threadInfo->destination; if (destination < limit) { limit += PIXEventsSafeFastCopySpaceQwords; UINT64 time = PIXGetTimestampCounter(); eventDestination = destination++; PIXCopyStringArgumentsWithContext(destination, limit, context, formatString, args...); *destination = PIXEventsBlockEndMarker; eventSize = PIXGetEventSize(destination, threadInfo->destination); const UINT8 eventMetadata = PIX_EVENT_METADATA_ON_CONTEXT | PIXEncodeStringIsAnsi() | PIXEncodeIndexColor(color); *eventDestination = PIXEncodeEventInfo(time, PIXEvent_SetMarker, eventSize, eventMetadata); threadInfo->destination = destination; } else { PIXSetMarkerOnContextCpuAllocate(eventDestination, eventSize, threadInfo, context, color, formatString, args...); } } template void PIXSetMarker(CONTEXT* context, UINT8 color, STR formatString, ARGS... args) { UINT64* destination = nullptr; UINT8 eventSize = 0u; #ifdef PIX_CONTEXT_EMIT_CPU_EVENTS PIXSetMarkerOnContextCpu(destination, eventSize, context, color, formatString, args...); #endif #ifdef PIX_USE_GPU_MARKERS_V2 if (destination != nullptr) { PIXInsertTimingMarkerOnContextForSetMarker(context, PIXEvent_SetMarker, static_cast(destination), eventSize * sizeof(UINT64)); } else #endif { UINT64 buffer[PIXEventsGraphicsRecordSpaceQwords]; #ifdef PIX_USE_GPU_MARKERS_V2 destination = buffer; UINT64* limit = buffer + PIXEventsGraphicsRecordSpaceQwords - PIXEventsReservedTailSpaceQwords; UINT64* eventDestination = destination++; PIXCopyStringArgumentsWithContext(destination, limit, context, formatString, args...); *destination = 0ull; eventSize = static_cast(destination - buffer); const UINT8 eventMetadata = PIX_EVENT_METADATA_ON_CONTEXT | PIXEncodeStringIsAnsi() | PIXEncodeIndexColor(color); *eventDestination = PIXEncodeEventInfo(0, PIXEvent_SetMarker, eventSize, eventMetadata); PIXInsertGPUMarkerOnContextForSetMarker(context, PIXEvent_SetMarker, static_cast(buffer), static_cast(reinterpret_cast(destination) - reinterpret_cast(buffer))); #else destination = PixEventsLegacy::EncodeSetMarkerForContext(buffer, color, formatString, args...); PIXSetGPUMarkerOnContext(context, static_cast(buffer), static_cast(reinterpret_cast(destination) - reinterpret_cast(buffer))); #endif } } __declspec(noinline) inline void PIXEndEventAllocate(PIXEventsThreadInfo* threadInfo) { UINT64 time = PIXEventsReplaceBlock(threadInfo, true); if (!time) return; UINT64* destination = threadInfo->destination; UINT64* limit = threadInfo->biasedLimit; if (destination >= limit) return; limit += PIXEventsSafeFastCopySpaceQwords; const UINT8 eventSize = 1; const UINT8 eventMetadata = PIX_EVENT_METADATA_NONE; *destination++ = PIXEncodeEventInfo(time, PIXEvent_EndEvent, eventSize, eventMetadata); *destination = PIXEventsBlockEndMarker; threadInfo->destination = destination; } inline void PIXEndEvent() { PIXEventsThreadInfo* threadInfo = PIXGetThreadInfo(); UINT64* limit = threadInfo->biasedLimit; if (limit != nullptr) { UINT64* destination = threadInfo->destination; if (destination < limit) { limit += PIXEventsSafeFastCopySpaceQwords; UINT64 time = PIXGetTimestampCounter(); const UINT8 eventSize = 1; const UINT8 eventMetadata = PIX_EVENT_METADATA_NONE; *destination++ = PIXEncodeEventInfo(time, PIXEvent_EndEvent, eventSize, eventMetadata); *destination = PIXEventsBlockEndMarker; threadInfo->destination = destination; } else { PIXEndEventAllocate(threadInfo); } } } __declspec(noinline) inline UINT64* PIXEndEventOnContextCpuAllocate(PIXEventsThreadInfo* threadInfo, void* context) { UINT64 time = PIXEventsReplaceBlock(threadInfo, true); if (!time) return nullptr; UINT64* destination = threadInfo->destination; UINT64* limit = threadInfo->biasedLimit; if (destination >= limit) return nullptr; limit += PIXEventsSafeFastCopySpaceQwords; UINT64* eventDestination = destination++; #ifdef PIX_XBOX UNREFERENCED_PARAMETER(context); #else PIXCopyEventArgument(destination, limit, context); #endif * destination = PIXEventsBlockEndMarker; const UINT8 eventSize = PIXGetEventSize(destination, threadInfo->destination); const UINT8 eventMetadata = PIX_EVENT_METADATA_ON_CONTEXT; *eventDestination = PIXEncodeEventInfo(time, PIXEvent_EndEvent, eventSize, eventMetadata); threadInfo->destination = destination; return eventDestination; } inline UINT64* PIXEndEventOnContextCpu(void* context) { PIXEventsThreadInfo* threadInfo = PIXGetThreadInfo(); UINT64* limit = threadInfo->biasedLimit; if (limit != nullptr) { UINT64* destination = threadInfo->destination; if (destination < limit) { limit += PIXEventsSafeFastCopySpaceQwords; UINT64 time = PIXGetTimestampCounter(); UINT64* eventDestination = destination++; #ifndef PIX_XBOX PIXCopyEventArgument(destination, limit, context); #endif * destination = PIXEventsBlockEndMarker; const UINT8 eventSize = PIXGetEventSize(destination, threadInfo->destination); const UINT8 eventMetadata = PIX_EVENT_METADATA_ON_CONTEXT; *eventDestination = PIXEncodeEventInfo(time, PIXEvent_EndEvent, eventSize, eventMetadata); threadInfo->destination = destination; return eventDestination; } else { return PIXEndEventOnContextCpuAllocate(threadInfo, context); } } return nullptr; } template void PIXEndEvent(CONTEXT* context) { UINT64* destination = nullptr; #ifdef PIX_CONTEXT_EMIT_CPU_EVENTS destination = PIXEndEventOnContextCpu(context); #endif #ifdef PIX_USE_GPU_MARKERS_V2 if (destination != nullptr) { PIXInsertTimingMarkerOnContextForEndEvent(context, PIXEvent_EndEvent); } else #endif { #ifdef PIX_USE_GPU_MARKERS_V2 UINT64 buffer[PIXEventsGraphicsRecordSpaceQwords]; destination = buffer; UINT64* eventDestination = destination++; const UINT8 eventSize = static_cast(destination - buffer); const UINT8 eventMetadata = PIX_EVENT_METADATA_NONE; *eventDestination = PIXEncodeEventInfo(0, PIXEvent_EndEvent, eventSize, eventMetadata); PIXInsertGPUMarkerOnContextForEndEvent(context, PIXEvent_EndEvent, static_cast(buffer), static_cast(reinterpret_cast(destination) - reinterpret_cast(buffer))); #else PIXEndGPUEventOnContext(context); #endif } } } #if defined(USE_PIX) template void PIXBeginEvent(UINT64 color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(color, formatString, args...); } template void PIXBeginEvent(UINT64 color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(color, formatString, args...); } template void PIXBeginEvent(UINT32 color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(static_cast(color), formatString, args...); } template void PIXBeginEvent(UINT32 color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(static_cast(color), formatString, args...); } template void PIXBeginEvent(INT32 color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(static_cast(color), formatString, args...); } template void PIXBeginEvent(INT32 color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(static_cast(color), formatString, args...); } template void PIXBeginEvent(DWORD color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(static_cast(color), formatString, args...); } template void PIXBeginEvent(DWORD color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(static_cast(color), formatString, args...); } template void PIXBeginEvent(UINT8 color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(color, formatString, args...); } template void PIXBeginEvent(UINT8 color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(color, formatString, args...); } template void PIXSetMarker(UINT64 color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(color, formatString, args...); } template void PIXSetMarker(UINT64 color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(color, formatString, args...); } template void PIXSetMarker(UINT32 color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(static_cast(color), formatString, args...); } template void PIXSetMarker(UINT32 color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(static_cast(color), formatString, args...); } template void PIXSetMarker(INT32 color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(static_cast(color), formatString, args...); } template void PIXSetMarker(INT32 color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(static_cast(color), formatString, args...); } template void PIXSetMarker(DWORD color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(static_cast(color), formatString, args...); } template void PIXSetMarker(DWORD color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(static_cast(color), formatString, args...); } template void PIXSetMarker(UINT8 color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(color, formatString, args...); } template void PIXSetMarker(UINT8 color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(color, formatString, args...); } template void PIXBeginEvent(CONTEXT* context, UINT64 color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(context, color, formatString, args...); } template void PIXBeginEvent(CONTEXT* context, UINT64 color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(context, color, formatString, args...); } template void PIXBeginEvent(CONTEXT* context, UINT32 color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(context, static_cast(color), formatString, args...); } template void PIXBeginEvent(CONTEXT* context, UINT32 color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(context, static_cast(color), formatString, args...); } template void PIXBeginEvent(CONTEXT* context, INT32 color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(context, static_cast(color), formatString, args...); } template void PIXBeginEvent(CONTEXT* context, INT32 color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(context, static_cast(color), formatString, args...); } template void PIXBeginEvent(CONTEXT* context, DWORD color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(context, static_cast(color), formatString, args...); } template void PIXBeginEvent(CONTEXT* context, DWORD color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(context, static_cast(color), formatString, args...); } template void PIXBeginEvent(CONTEXT* context, UINT8 color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(context, color, formatString, args...); } template void PIXBeginEvent(CONTEXT* context, UINT8 color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(context, color, formatString, args...); } template void PIXSetMarker(CONTEXT* context, UINT64 color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(context, color, formatString, args...); } template void PIXSetMarker(CONTEXT* context, UINT64 color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(context, color, formatString, args...); } template void PIXSetMarker(CONTEXT* context, UINT32 color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(context, static_cast(color), formatString, args...); } template void PIXSetMarker(CONTEXT* context, UINT32 color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(context, static_cast(color), formatString, args...); } template void PIXSetMarker(CONTEXT* context, INT32 color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(context, static_cast(color), formatString, args...); } template void PIXSetMarker(CONTEXT* context, INT32 color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(context, static_cast(color), formatString, args...); } template void PIXSetMarker(CONTEXT* context, DWORD color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(context, static_cast(color), formatString, args...); } template void PIXSetMarker(CONTEXT* context, DWORD color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(context, static_cast(color), formatString, args...); } template void PIXSetMarker(CONTEXT* context, UINT8 color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(context, color, formatString, args...); } template void PIXSetMarker(CONTEXT* context, UINT8 color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(context, color, formatString, args...); } inline void PIXEndEvent() { PIXEventsDetail::PIXEndEvent(); } template void PIXEndEvent(CONTEXT* context) { PIXEventsDetail::PIXEndEvent(context); } #else // USE_PIX_RETAIL inline void PIXBeginEvent(UINT64, _In_ PCSTR, ...) {} inline void PIXBeginEvent(UINT64, _In_ PCWSTR, ...) {} inline void PIXBeginEvent(void*, UINT64, _In_ PCSTR, ...) {} inline void PIXBeginEvent(void*, UINT64, _In_ PCWSTR, ...) {} inline void PIXEndEvent() {} inline void PIXEndEvent(void*) {} inline void PIXSetMarker(UINT64, _In_ PCSTR, ...) {} inline void PIXSetMarker(UINT64, _In_ PCWSTR, ...) {} inline void PIXSetMarker(void*, UINT64, _In_ PCSTR, ...) {} inline void PIXSetMarker(void*, UINT64, _In_ PCWSTR, ...) {} #endif // USE_PIX template void PIXBeginRetailEvent(CONTEXT* context, UINT64 color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(context, color, formatString, args...); } template void PIXBeginRetailEvent(CONTEXT* context, UINT64 color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(context, color, formatString, args...); } template void PIXBeginRetailEvent(CONTEXT* context, UINT32 color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(context, static_cast(color), formatString, args...); } template void PIXBeginRetailEvent(CONTEXT* context, UINT32 color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(context, static_cast(color), formatString, args...); } template void PIXBeginRetailEvent(CONTEXT* context, INT32 color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(context, static_cast(color), formatString, args...); } template void PIXBeginRetailEvent(CONTEXT* context, INT32 color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(context, static_cast(color), formatString, args...); } template void PIXBeginRetailEvent(CONTEXT* context, DWORD color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(context, static_cast(color), formatString, args...); } template void PIXBeginRetailEvent(CONTEXT* context, DWORD color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(context, static_cast(color), formatString, args...); } template void PIXBeginRetailEvent(CONTEXT* context, UINT8 color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(context, color, formatString, args...); } template void PIXBeginRetailEvent(CONTEXT* context, UINT8 color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXBeginEvent(context, color, formatString, args...); } template void PIXSetRetailMarker(CONTEXT* context, UINT64 color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(context, color, formatString, args...); } template void PIXSetRetailMarker(CONTEXT* context, UINT64 color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(context, color, formatString, args...); } template void PIXSetRetailMarker(CONTEXT* context, UINT32 color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(context, static_cast(color), formatString, args...); } template void PIXSetRetailMarker(CONTEXT* context, UINT32 color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(context, static_cast(color), formatString, args...); } template void PIXSetRetailMarker(CONTEXT* context, INT32 color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(context, static_cast(color), formatString, args...); } template void PIXSetRetailMarker(CONTEXT* context, INT32 color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(context, static_cast(color), formatString, args...); } template void PIXSetRetailMarker(CONTEXT* context, DWORD color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(context, static_cast(color), formatString, args...); } template void PIXSetRetailMarker(CONTEXT* context, DWORD color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(context, static_cast(color), formatString, args...); } template void PIXSetRetailMarker(CONTEXT* context, UINT8 color, PCWSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(context, color, formatString, args...); } template void PIXSetRetailMarker(CONTEXT* context, UINT8 color, PCSTR formatString, ARGS... args) { PIXEventsDetail::PIXSetMarker(context, color, formatString, args...); } template void PIXEndRetailEvent(CONTEXT* context) { PIXEventsDetail::PIXEndEvent(context); } template class PIXScopedEventObject { CONTEXT* m_context; public: template PIXScopedEventObject(CONTEXT* context, UINT64 color, PCWSTR formatString, ARGS... args) : m_context(context) { PIXBeginEvent(m_context, color, formatString, args...); } template PIXScopedEventObject(CONTEXT* context, UINT64 color, PCSTR formatString, ARGS... args) : m_context(context) { PIXBeginEvent(m_context, color, formatString, args...); } template PIXScopedEventObject(CONTEXT* context, UINT32 color, PCWSTR formatString, ARGS... args) : m_context(context) { PIXBeginEvent(m_context, color, formatString, args...); } template PIXScopedEventObject(CONTEXT* context, UINT32 color, PCSTR formatString, ARGS... args) : m_context(context) { PIXBeginEvent(m_context, color, formatString, args...); } template PIXScopedEventObject(CONTEXT* context, INT32 color, PCWSTR formatString, ARGS... args) : m_context(context) { PIXBeginEvent(m_context, color, formatString, args...); } template PIXScopedEventObject(CONTEXT* context, INT32 color, PCSTR formatString, ARGS... args) : m_context(context) { PIXBeginEvent(m_context, color, formatString, args...); } template PIXScopedEventObject(CONTEXT* context, DWORD color, PCWSTR formatString, ARGS... args) : m_context(context) { PIXBeginEvent(m_context, color, formatString, args...); } template PIXScopedEventObject(CONTEXT* context, DWORD color, PCSTR formatString, ARGS... args) : m_context(context) { PIXBeginEvent(m_context, color, formatString, args...); } template PIXScopedEventObject(CONTEXT* context, UINT8 color, PCWSTR formatString, ARGS... args) : m_context(context) { PIXBeginEvent(m_context, color, formatString, args...); } template PIXScopedEventObject(CONTEXT* context, UINT8 color, PCSTR formatString, ARGS... args) : m_context(context) { PIXBeginEvent(m_context, color, formatString, args...); } ~PIXScopedEventObject() { PIXEndEvent(m_context); } }; template class PIXScopedRetailEventObject { CONTEXT* m_context; public: template PIXScopedRetailEventObject(CONTEXT* context, UINT64 color, PCWSTR formatString, ARGS... args) : m_context(context) { PIXBeginRetailEvent(m_context, color, formatString, args...); } template PIXScopedRetailEventObject(CONTEXT* context, UINT64 color, PCSTR formatString, ARGS... args) : m_context(context) { PIXBeginRetailEvent(m_context, color, formatString, args...); } template PIXScopedRetailEventObject(CONTEXT* context, UINT32 color, PCWSTR formatString, ARGS... args) : m_context(context) { PIXBeginRetailEvent(m_context, color, formatString, args...); } template PIXScopedRetailEventObject(CONTEXT* context, UINT32 color, PCSTR formatString, ARGS... args) : m_context(context) { PIXBeginRetailEvent(m_context, color, formatString, args...); } template PIXScopedRetailEventObject(CONTEXT* context, INT32 color, PCWSTR formatString, ARGS... args) : m_context(context) { PIXBeginRetailEvent(m_context, color, formatString, args...); } template PIXScopedRetailEventObject(CONTEXT* context, INT32 color, PCSTR formatString, ARGS... args) : m_context(context) { PIXBeginRetailEvent(m_context, color, formatString, args...); } template PIXScopedRetailEventObject(CONTEXT* context, DWORD color, PCWSTR formatString, ARGS... args) : m_context(context) { PIXBeginRetailEvent(m_context, color, formatString, args...); } template PIXScopedRetailEventObject(CONTEXT* context, DWORD color, PCSTR formatString, ARGS... args) : m_context(context) { PIXBeginRetailEvent(m_context, color, formatString, args...); } template PIXScopedRetailEventObject(CONTEXT* context, UINT8 color, PCWSTR formatString, ARGS... args) : m_context(context) { PIXBeginRetailEvent(m_context, color, formatString, args...); } template PIXScopedRetailEventObject(CONTEXT* context, UINT8 color, PCSTR formatString, ARGS... args) : m_context(context) { PIXBeginRetailEvent(m_context, color, formatString, args...); } ~PIXScopedRetailEventObject() { PIXEndRetailEvent(m_context); } }; template<> class PIXScopedEventObject { public: template PIXScopedEventObject(UINT64 color, PCWSTR formatString, ARGS... args) { PIXBeginEvent(color, formatString, args...); } template PIXScopedEventObject(UINT64 color, PCSTR formatString, ARGS... args) { PIXBeginEvent(color, formatString, args...); } template PIXScopedEventObject(UINT32 color, PCWSTR formatString, ARGS... args) { PIXBeginEvent(color, formatString, args...); } template PIXScopedEventObject(UINT32 color, PCSTR formatString, ARGS... args) { PIXBeginEvent(color, formatString, args...); } template PIXScopedEventObject(INT32 color, PCWSTR formatString, ARGS... args) { PIXBeginEvent(color, formatString, args...); } template PIXScopedEventObject(INT32 color, PCSTR formatString, ARGS... args) { PIXBeginEvent(color, formatString, args...); } template PIXScopedEventObject(DWORD color, PCWSTR formatString, ARGS... args) { PIXBeginEvent(color, formatString, args...); } template PIXScopedEventObject(DWORD color, PCSTR formatString, ARGS... args) { PIXBeginEvent(color, formatString, args...); } template PIXScopedEventObject(UINT8 color, PCWSTR formatString, ARGS... args) { PIXBeginEvent(color, formatString, args...); } template PIXScopedEventObject(UINT8 color, PCSTR formatString, ARGS... args) { PIXBeginEvent(color, formatString, args...); } ~PIXScopedEventObject() { PIXEndEvent(); } }; #define PIXConcatenate(a, b) a ## b #define PIXGetScopedEventVariableName(a, b) PIXConcatenate(a, b) #define PIXScopedEvent(context, ...) PIXScopedEventObject::Type> PIXGetScopedEventVariableName(pixEvent, __LINE__)(context, __VA_ARGS__) #ifdef PIX3__DEFINED_CONSTEXPR #undef constexpr #undef PIX3__DEFINED_CONSTEXPR #endif #endif // _PIXEvents_H__