mirror of
				https://github.com/RetroDECK/Duckstation.git
				synced 2025-04-10 19:15:14 +00:00 
			
		
		
		
	
		
			
	
	
		
			662 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			662 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								// Copyright (c) Microsoft Corporation. All rights reserved.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*==========================================================================;
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 *  Copyright (C) Microsoft Corporation.  All Rights Reserved.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 *  File:       PIXEvents.h
							 | 
						||
| 
								 | 
							
								 *  Content:    PIX include file
							 | 
						||
| 
								 | 
							
								 *              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
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    template<typename... ARGS>
							 | 
						||
| 
								 | 
							
								    struct PIXEventTypeInferer
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        static constexpr PIXEventType Begin() { return PIXEvent_BeginEvent_VarArgs; }
							 | 
						||
| 
								 | 
							
								        static constexpr PIXEventType SetMarker() { return PIXEvent_SetMarker_VarArgs; }
							 | 
						||
| 
								 | 
							
								        static constexpr PIXEventType BeginOnContext() { return PIXEvent_BeginEvent_OnContext_VarArgs; }
							 | 
						||
| 
								 | 
							
								        static constexpr PIXEventType SetMarkerOnContext() { return PIXEvent_SetMarker_OnContext_VarArgs; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Xbox and Windows store different types of events for context events.
							 | 
						||
| 
								 | 
							
								        // On Xbox these include a context argument, while on Windows they do
							 | 
						||
| 
								 | 
							
								        // not. It is important not to change the event types used on the
							 | 
						||
| 
								 | 
							
								        // Windows version as there are OS components (eg debug layer & DRED)
							 | 
						||
| 
								 | 
							
								        // that decode event structs.
							 | 
						||
| 
								 | 
							
								#ifdef PIX_XBOX
							 | 
						||
| 
								 | 
							
								        static constexpr PIXEventType GpuBeginOnContext() { return PIXEvent_BeginEvent_OnContext_VarArgs; }
							 | 
						||
| 
								 | 
							
								        static constexpr PIXEventType GpuSetMarkerOnContext() { return PIXEvent_SetMarker_OnContext_VarArgs; }
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								        static constexpr PIXEventType GpuBeginOnContext() { return PIXEvent_BeginEvent_VarArgs; }
							 | 
						||
| 
								 | 
							
								        static constexpr PIXEventType GpuSetMarkerOnContext() { return PIXEvent_SetMarker_VarArgs; }
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<>
							 | 
						||
| 
								 | 
							
								    struct PIXEventTypeInferer<>
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        static constexpr PIXEventType Begin() { return PIXEvent_BeginEvent_NoArgs; }
							 | 
						||
| 
								 | 
							
								        static constexpr PIXEventType SetMarker() { return PIXEvent_SetMarker_NoArgs; }
							 | 
						||
| 
								 | 
							
								        static constexpr PIXEventType BeginOnContext() { return PIXEvent_BeginEvent_OnContext_NoArgs; }
							 | 
						||
| 
								 | 
							
								        static constexpr PIXEventType SetMarkerOnContext() { return PIXEvent_SetMarker_OnContext_NoArgs; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef PIX_XBOX
							 | 
						||
| 
								 | 
							
								        static constexpr PIXEventType GpuBeginOnContext() { return PIXEvent_BeginEvent_OnContext_NoArgs; }
							 | 
						||
| 
								 | 
							
								        static constexpr PIXEventType GpuSetMarkerOnContext() { return PIXEvent_SetMarker_OnContext_NoArgs; }
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								        static constexpr PIXEventType GpuBeginOnContext() { return PIXEvent_BeginEvent_NoArgs; }
							 | 
						||
| 
								 | 
							
								        static constexpr PIXEventType GpuSetMarkerOnContext() { return PIXEvent_SetMarker_NoArgs; }
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    inline void PIXCopyEventArguments(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        // nothing
							 | 
						||
| 
								 | 
							
								        UNREFERENCED_PARAMETER(destination);
							 | 
						||
| 
								 | 
							
								        UNREFERENCED_PARAMETER(limit);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<typename ARG, typename... ARGS>
							 | 
						||
| 
								 | 
							
								    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<typename STR, typename... ARGS>
							 | 
						||
| 
								 | 
							
								    __declspec(noinline) void PIXBeginEventAllocate(PIXEventsThreadInfo* threadInfo, UINT64 color, STR formatString, ARGS... args)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								#ifdef PIX_XBOX
							 | 
						||
| 
								 | 
							
								        UINT64 time = PIXEventsReplaceBlock(false);
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								        UINT64 time = PIXEventsReplaceBlock(threadInfo, false);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								        if (!time)
							 | 
						||
| 
								 | 
							
								            return;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        UINT64* destination = threadInfo->destination;
							 | 
						||
| 
								 | 
							
								        UINT64* limit = threadInfo->biasedLimit;
							 | 
						||
| 
								 | 
							
								        if (destination >= limit)
							 | 
						||
| 
								 | 
							
								            return;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        limit += PIXEventsSafeFastCopySpaceQwords;
							 | 
						||
| 
								 | 
							
								        *destination++ = PIXEncodeEventInfo(time, PIXEventTypeInferer<ARGS...>::Begin());
							 | 
						||
| 
								 | 
							
								        *destination++ = color;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        PIXCopyEventArguments(destination, limit, formatString, args...);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        *destination = PIXEventsBlockEndMarker;
							 | 
						||
| 
								 | 
							
								        threadInfo->destination = destination;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<typename STR, typename... ARGS>
							 | 
						||
| 
								 | 
							
								    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();
							 | 
						||
| 
								 | 
							
								                *destination++ = PIXEncodeEventInfo(time, PIXEventTypeInferer<ARGS...>::Begin());
							 | 
						||
| 
								 | 
							
								                *destination++ = color;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                PIXCopyEventArguments(destination, limit, formatString, args...);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                *destination = PIXEventsBlockEndMarker;
							 | 
						||
| 
								 | 
							
								                threadInfo->destination = destination;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                PIXBeginEventAllocate(threadInfo, color, formatString, args...);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<typename STR, typename... ARGS>
							 | 
						||
| 
								 | 
							
								    __declspec(noinline) void PIXSetMarkerAllocate(PIXEventsThreadInfo* threadInfo, UINT64 color, STR formatString, ARGS... args)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								#ifdef PIX_XBOX
							 | 
						||
| 
								 | 
							
								        UINT64 time = PIXEventsReplaceBlock(false);
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								        UINT64 time = PIXEventsReplaceBlock(threadInfo, false);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								        if (!time)
							 | 
						||
| 
								 | 
							
								            return;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        UINT64* destination = threadInfo->destination;
							 | 
						||
| 
								 | 
							
								        UINT64* limit = threadInfo->biasedLimit;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (destination >= limit)
							 | 
						||
| 
								 | 
							
								            return;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        limit += PIXEventsSafeFastCopySpaceQwords;
							 | 
						||
| 
								 | 
							
								        *destination++ = PIXEncodeEventInfo(time, PIXEventTypeInferer<ARGS...>::SetMarker());
							 | 
						||
| 
								 | 
							
								        *destination++ = color;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        PIXCopyEventArguments(destination, limit, formatString, args...);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        *destination = PIXEventsBlockEndMarker;
							 | 
						||
| 
								 | 
							
								        threadInfo->destination = destination;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<typename STR, typename... ARGS>
							 | 
						||
| 
								 | 
							
								    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();
							 | 
						||
| 
								 | 
							
								                *destination++ = PIXEncodeEventInfo(time, PIXEventTypeInferer<ARGS...>::SetMarker());
							 | 
						||
| 
								 | 
							
								                *destination++ = color;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                PIXCopyEventArguments(destination, limit, formatString, args...);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                *destination = PIXEventsBlockEndMarker;
							 | 
						||
| 
								 | 
							
								                threadInfo->destination = destination;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                PIXSetMarkerAllocate(threadInfo, color, formatString, args...);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<typename STR, typename... ARGS>
							 | 
						||
| 
								 | 
							
								    __declspec(noinline) void PIXBeginEventOnContextCpuAllocate(PIXEventsThreadInfo* threadInfo, void* context, UINT64 color, STR formatString, ARGS... args)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								#ifdef PIX_XBOX
							 | 
						||
| 
								 | 
							
								        UINT64 time = PIXEventsReplaceBlock(false);
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								        UINT64 time = PIXEventsReplaceBlock(threadInfo, false);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								        if (!time)
							 | 
						||
| 
								 | 
							
								            return;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        UINT64* destination = threadInfo->destination;
							 | 
						||
| 
								 | 
							
								        UINT64* limit = threadInfo->biasedLimit;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (destination >= limit)
							 | 
						||
| 
								 | 
							
								            return;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        limit += PIXEventsSafeFastCopySpaceQwords;
							 | 
						||
| 
								 | 
							
								        *destination++ = PIXEncodeEventInfo(time, PIXEventTypeInferer<ARGS...>::BeginOnContext());
							 | 
						||
| 
								 | 
							
								        *destination++ = color;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef PIX_XBOX
							 | 
						||
| 
								 | 
							
								        UNREFERENCED_PARAMETER(context);
							 | 
						||
| 
								 | 
							
								        PIXCopyEventArguments(destination, limit, formatString, args...);
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								        PIXCopyEventArguments(destination, limit, context, formatString, args...);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        *destination = PIXEventsBlockEndMarker;
							 | 
						||
| 
								 | 
							
								        threadInfo->destination = destination;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<typename STR, typename... ARGS>
							 | 
						||
| 
								 | 
							
								    void PIXBeginEventOnContextCpu(void* context, 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();
							 | 
						||
| 
								 | 
							
								                *destination++ = PIXEncodeEventInfo(time, PIXEventTypeInferer<ARGS...>::BeginOnContext());
							 | 
						||
| 
								 | 
							
								                *destination++ = color;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef PIX_XBOX
							 | 
						||
| 
								 | 
							
								                PIXCopyEventArguments(destination, limit, formatString, args...);
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								                PIXCopyEventArguments(destination, limit, context, formatString, args...);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                *destination = PIXEventsBlockEndMarker;
							 | 
						||
| 
								 | 
							
								                threadInfo->destination = destination;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                PIXBeginEventOnContextCpuAllocate(threadInfo, context, color, formatString, args...);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<typename CONTEXT, typename STR, typename... ARGS>
							 | 
						||
| 
								 | 
							
								    void PIXBeginEvent(CONTEXT* context, UINT64 color, STR formatString, ARGS... args)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								#ifdef PIX_CONTEXT_EMIT_CPU_EVENTS
							 | 
						||
| 
								 | 
							
								        PIXBeginEventOnContextCpu(context, color, formatString, args...);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // TODO: we've already encoded this once for the CPU event - figure out way to avoid doing it again
							 | 
						||
| 
								 | 
							
								        UINT64 buffer[PIXEventsGraphicsRecordSpaceQwords];
							 | 
						||
| 
								 | 
							
								        UINT64* destination = buffer;
							 | 
						||
| 
								 | 
							
								        UINT64* limit = buffer + PIXEventsGraphicsRecordSpaceQwords - PIXEventsReservedTailSpaceQwords;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        *destination++ = PIXEncodeEventInfo(0, PIXEventTypeInferer<ARGS...>::GpuBeginOnContext());
							 | 
						||
| 
								 | 
							
								        *destination++ = color;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        PIXCopyEventArguments(destination, limit, formatString, args...);
							 | 
						||
| 
								 | 
							
								        *destination = 0ull;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        PIXBeginGPUEventOnContext(context, static_cast<void*>(buffer), static_cast<UINT>(reinterpret_cast<BYTE*>(destination) - reinterpret_cast<BYTE*>(buffer)));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<typename STR, typename... ARGS>
							 | 
						||
| 
								 | 
							
								    __declspec(noinline) void PIXSetMarkerOnContextCpuAllocate(PIXEventsThreadInfo* threadInfo, void* context, UINT64 color, STR formatString, ARGS... args)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								#ifdef PIX_XBOX
							 | 
						||
| 
								 | 
							
								        UINT64 time = PIXEventsReplaceBlock(false);
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								        UINT64 time = PIXEventsReplaceBlock(threadInfo, false);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								        if (!time)
							 | 
						||
| 
								 | 
							
								            return;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        UINT64* destination = threadInfo->destination;
							 | 
						||
| 
								 | 
							
								        UINT64* limit = threadInfo->biasedLimit;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (destination >= limit)
							 | 
						||
| 
								 | 
							
								            return;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        limit += PIXEventsSafeFastCopySpaceQwords;
							 | 
						||
| 
								 | 
							
								        *destination++ = PIXEncodeEventInfo(time, PIXEventTypeInferer<ARGS...>::SetMarkerOnContext());
							 | 
						||
| 
								 | 
							
								        *destination++ = color;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef PIX_XBOX
							 | 
						||
| 
								 | 
							
								        UNREFERENCED_PARAMETER(context);
							 | 
						||
| 
								 | 
							
								        PIXCopyEventArguments(destination, limit, formatString, args...);
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								        PIXCopyEventArguments(destination, limit, context, formatString, args...);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        *destination = PIXEventsBlockEndMarker;
							 | 
						||
| 
								 | 
							
								        threadInfo->destination = destination;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<typename STR, typename... ARGS>
							 | 
						||
| 
								 | 
							
								    void PIXSetMarkerOnContextCpu(void* context, 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();
							 | 
						||
| 
								 | 
							
								                *destination++ = PIXEncodeEventInfo(time, PIXEventTypeInferer<ARGS...>::SetMarkerOnContext());
							 | 
						||
| 
								 | 
							
								                *destination++ = color;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef PIX_XBOX
							 | 
						||
| 
								 | 
							
								                PIXCopyEventArguments(destination, limit, formatString, args...);
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								                PIXCopyEventArguments(destination, limit, context, formatString, args...);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                *destination = PIXEventsBlockEndMarker;
							 | 
						||
| 
								 | 
							
								                threadInfo->destination = destination;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                PIXSetMarkerOnContextCpuAllocate(threadInfo, context, color, formatString, args...);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<typename CONTEXT, typename STR, typename... ARGS>
							 | 
						||
| 
								 | 
							
								    void PIXSetMarker(CONTEXT* context, UINT64 color, STR formatString, ARGS... args)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								#ifdef PIX_CONTEXT_EMIT_CPU_EVENTS
							 | 
						||
| 
								 | 
							
								        PIXSetMarkerOnContextCpu(context, color, formatString, args...);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        UINT64 buffer[PIXEventsGraphicsRecordSpaceQwords];
							 | 
						||
| 
								 | 
							
								        UINT64* destination = buffer;
							 | 
						||
| 
								 | 
							
								        UINT64* limit = buffer + PIXEventsGraphicsRecordSpaceQwords - PIXEventsReservedTailSpaceQwords;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        *destination++ = PIXEncodeEventInfo(0, PIXEventTypeInferer<ARGS...>::GpuSetMarkerOnContext());
							 | 
						||
| 
								 | 
							
								        *destination++ = color;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        PIXCopyEventArguments(destination, limit, formatString, args...);
							 | 
						||
| 
								 | 
							
								        *destination = 0ull;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        PIXSetGPUMarkerOnContext(context, static_cast<void*>(buffer), static_cast<UINT>(reinterpret_cast<BYTE*>(destination) - reinterpret_cast<BYTE*>(buffer)));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    __declspec(noinline) inline void PIXEndEventAllocate(PIXEventsThreadInfo* threadInfo)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								#ifdef PIX_XBOX
							 | 
						||
| 
								 | 
							
								        UINT64 time = PIXEventsReplaceBlock(true);
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								        UINT64 time = PIXEventsReplaceBlock(threadInfo, true);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								        if (!time)
							 | 
						||
| 
								 | 
							
								            return;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        UINT64* destination = threadInfo->destination;
							 | 
						||
| 
								 | 
							
								        UINT64* limit = threadInfo->biasedLimit;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (destination >= limit)
							 | 
						||
| 
								 | 
							
								            return;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        limit += PIXEventsSafeFastCopySpaceQwords;
							 | 
						||
| 
								 | 
							
								        *destination++ = PIXEncodeEventInfo(time, PIXEvent_EndEvent);
							 | 
						||
| 
								 | 
							
								        *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();
							 | 
						||
| 
								 | 
							
								                *destination++ = PIXEncodeEventInfo(time, PIXEvent_EndEvent);
							 | 
						||
| 
								 | 
							
								                *destination = PIXEventsBlockEndMarker;
							 | 
						||
| 
								 | 
							
								                threadInfo->destination = destination;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                PIXEndEventAllocate(threadInfo);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    __declspec(noinline) inline void PIXEndEventOnContextCpuAllocate(PIXEventsThreadInfo* threadInfo, void* context)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								#ifdef PIX_XBOX
							 | 
						||
| 
								 | 
							
								        UINT64 time = PIXEventsReplaceBlock(true);
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								        UINT64 time = PIXEventsReplaceBlock(threadInfo, true);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								        if (!time)
							 | 
						||
| 
								 | 
							
								            return;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        UINT64* destination = threadInfo->destination;
							 | 
						||
| 
								 | 
							
								        UINT64* limit = threadInfo->biasedLimit;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (destination >= limit)
							 | 
						||
| 
								 | 
							
								            return;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        limit += PIXEventsSafeFastCopySpaceQwords;
							 | 
						||
| 
								 | 
							
								        *destination++ = PIXEncodeEventInfo(time, PIXEvent_EndEvent_OnContext);
							 | 
						||
| 
								 | 
							
								#ifdef PIX_XBOX
							 | 
						||
| 
								 | 
							
								        UNREFERENCED_PARAMETER(context);
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								        PIXCopyEventArgument(destination, limit, context);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								        *destination = PIXEventsBlockEndMarker;
							 | 
						||
| 
								 | 
							
								        threadInfo->destination = destination;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    inline void 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();
							 | 
						||
| 
								 | 
							
								                *destination++ = PIXEncodeEventInfo(time, PIXEvent_EndEvent_OnContext);
							 | 
						||
| 
								 | 
							
								#ifndef PIX_XBOX
							 | 
						||
| 
								 | 
							
								                PIXCopyEventArgument(destination, limit, context);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								                *destination = PIXEventsBlockEndMarker;
							 | 
						||
| 
								 | 
							
								                threadInfo->destination = destination;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                PIXEndEventOnContextCpuAllocate(threadInfo, context);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<typename CONTEXT>
							 | 
						||
| 
								 | 
							
								    void PIXEndEvent(CONTEXT* context)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								#ifdef PIX_CONTEXT_EMIT_CPU_EVENTS
							 | 
						||
| 
								 | 
							
								        PIXEndEventOnContextCpu(context);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								        PIXEndGPUEventOnContext(context);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if defined(USE_PIX)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<typename... ARGS>
							 | 
						||
| 
								 | 
							
								void PIXBeginEvent(UINT64 color, PCWSTR formatString, ARGS... args)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    PIXEventsDetail::PIXBeginEvent(color, formatString, args...);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<typename... ARGS>
							 | 
						||
| 
								 | 
							
								void PIXBeginEvent(UINT64 color, PCSTR formatString, ARGS... args)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    PIXEventsDetail::PIXBeginEvent(color, formatString, args...);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<typename... ARGS>
							 | 
						||
| 
								 | 
							
								void PIXSetMarker(UINT64 color, PCWSTR formatString, ARGS... args)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    PIXEventsDetail::PIXSetMarker(color, formatString, args...);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<typename... ARGS>
							 | 
						||
| 
								 | 
							
								void PIXSetMarker(UINT64 color, PCSTR formatString, ARGS... args)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    PIXEventsDetail::PIXSetMarker(color, formatString, args...);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<typename CONTEXT, typename... ARGS>
							 | 
						||
| 
								 | 
							
								void PIXBeginEvent(CONTEXT* context, UINT64 color, PCWSTR formatString, ARGS... args)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    PIXEventsDetail::PIXBeginEvent(context, color, formatString, args...);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<typename CONTEXT, typename... ARGS>
							 | 
						||
| 
								 | 
							
								void PIXBeginEvent(CONTEXT* context, UINT64 color, PCSTR formatString, ARGS... args)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    PIXEventsDetail::PIXBeginEvent(context, color, formatString, args...);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<typename CONTEXT, typename... ARGS>
							 | 
						||
| 
								 | 
							
								void PIXSetMarker(CONTEXT* context, UINT64 color, PCWSTR formatString, ARGS... args)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    PIXEventsDetail::PIXSetMarker(context, color, formatString, args...);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<typename CONTEXT, typename... ARGS>
							 | 
						||
| 
								 | 
							
								void PIXSetMarker(CONTEXT* context, UINT64 color, PCSTR formatString, ARGS... args)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    PIXEventsDetail::PIXSetMarker(context, color, formatString, args...);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								inline void PIXEndEvent()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    PIXEventsDetail::PIXEndEvent();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<typename CONTEXT>
							 | 
						||
| 
								 | 
							
								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<typename CONTEXT, typename... ARGS>
							 | 
						||
| 
								 | 
							
								void PIXBeginRetailEvent(CONTEXT* context, UINT64 color, PCWSTR formatString, ARGS... args)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    PIXEventsDetail::PIXBeginEvent(context, color, formatString, args...);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<typename CONTEXT, typename... ARGS>
							 | 
						||
| 
								 | 
							
								void PIXBeginRetailEvent(CONTEXT* context, UINT64 color, PCSTR formatString, ARGS... args)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    PIXEventsDetail::PIXBeginEvent(context, color, formatString, args...);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<typename CONTEXT, typename... ARGS>
							 | 
						||
| 
								 | 
							
								void PIXSetRetailMarker(CONTEXT* context, UINT64 color, PCWSTR formatString, ARGS... args)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    PIXEventsDetail::PIXSetMarker(context, color, formatString, args...);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<typename CONTEXT, typename... ARGS>
							 | 
						||
| 
								 | 
							
								void PIXSetRetailMarker(CONTEXT* context, UINT64 color, PCSTR formatString, ARGS... args)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    PIXEventsDetail::PIXSetMarker(context, color, formatString, args...);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<typename CONTEXT>
							 | 
						||
| 
								 | 
							
								void PIXEndRetailEvent(CONTEXT* context)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    PIXEventsDetail::PIXEndEvent(context);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<typename CONTEXT>
							 | 
						||
| 
								 | 
							
								class PIXScopedEventObject
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    CONTEXT* m_context;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    template<typename... ARGS>
							 | 
						||
| 
								 | 
							
								    PIXScopedEventObject(CONTEXT* context, UINT64 color, PCWSTR formatString, ARGS... args)
							 | 
						||
| 
								 | 
							
								        : m_context(context)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        PIXBeginEvent(m_context, color, formatString, args...);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<typename... ARGS>
							 | 
						||
| 
								 | 
							
								    PIXScopedEventObject(CONTEXT* context, UINT64 color, PCSTR formatString, ARGS... args)
							 | 
						||
| 
								 | 
							
								        : m_context(context)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        PIXBeginEvent(m_context, color, formatString, args...);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ~PIXScopedEventObject()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        PIXEndEvent(m_context);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<typename CONTEXT>
							 | 
						||
| 
								 | 
							
								class PIXScopedRetailEventObject
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    CONTEXT* m_context;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    template<typename... ARGS>
							 | 
						||
| 
								 | 
							
								    PIXScopedRetailEventObject(CONTEXT* context, UINT64 color, PCWSTR formatString, ARGS... args)
							 | 
						||
| 
								 | 
							
								        : m_context(context)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        PIXBeginRetailEvent(m_context, color, formatString, args...);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<typename... ARGS>
							 | 
						||
| 
								 | 
							
								    PIXScopedRetailEventObject(CONTEXT* context, UINT64 color, PCSTR formatString, ARGS... args)
							 | 
						||
| 
								 | 
							
								        : m_context(context)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        PIXBeginRetailEvent(m_context, color, formatString, args...);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ~PIXScopedRetailEventObject()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        PIXEndRetailEvent(m_context);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<>
							 | 
						||
| 
								 | 
							
								class PIXScopedEventObject<void>
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    template<typename... ARGS>
							 | 
						||
| 
								 | 
							
								    PIXScopedEventObject(UINT64 color, PCWSTR formatString, ARGS... args)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        PIXBeginEvent(color, formatString, args...);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<typename... ARGS>
							 | 
						||
| 
								 | 
							
								    PIXScopedEventObject(UINT64 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<PIXInferScopedEventType<decltype(context)>::Type> PIXGetScopedEventVariableName(pixEvent, __LINE__)(context, __VA_ARGS__)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef PIX3__DEFINED_CONSTEXPR
							 | 
						||
| 
								 | 
							
								#undef constexpr
							 | 
						||
| 
								 | 
							
								#undef PIX3__DEFINED_CONSTEXPR
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif // _PIXEvents_H__
							 |