Updated PIX headers to 1.0.240308001.

https://www.nuget.org/packages/WinPixEventRuntime
This commit is contained in:
Branimir Karadžić
2025-10-22 14:36:32 -07:00
parent a569829d50
commit e15154513c
8 changed files with 3047 additions and 10990 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,41 +1,84 @@
/*==========================================================================;
*
* Copyright (C) Microsoft Corporation. All Rights Reserved.
*
* File: PIXEventsCommon.h
* Content: PIX include file
* Don't include this file directly - use pix3.h
*
****************************************************************************/
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// Don't include this file directly - use pix3.h
#pragma once
#ifndef _PIXEventsCommon_H_
#define _PIXEventsCommon_H_
#if defined(_AMD64_) || defined(_X86_)
#include <emmintrin.h>
#endif // _AMD64_ || _X86_
//
// The PIXBeginEvent and PIXSetMarker functions have an optimized path for
// copying strings that work by copying 128-bit or 64-bits at a time. In some
// circumstances this may result in PIX logging the remaining memory after the
// null terminator.
//
// By default this optimization is enabled unless Address Sanitizer is enabled,
// since this optimization can trigger a global-buffer-overflow when copying
// string literals.
//
// The PIX_ENABLE_BLOCK_ARGUMENT_COPY controls whether or not this optimization
// is enabled. Applications may also explicitly set this macro to 0 to disable
// the optimization if necessary.
//
enum PIXEventType
// Check for Address Sanitizer on either Clang or MSVC
#if defined(__has_feature)
#if __has_feature(address_sanitizer)
#define PIX_ASAN_ENABLED
#endif
#elif defined(__SANITIZE_ADDRESS__)
#define PIX_ASAN_ENABLED
#endif
#if defined(PIX_ENABLE_BLOCK_ARGUMENT_COPY)
// Previously set values override everything
# define PIX_ENABLE_BLOCK_ARGUMENT_COPY_SET 0
#elif defined(PIX_ASAN_ENABLED)
// Disable block argument copy when address sanitizer is enabled
#define PIX_ENABLE_BLOCK_ARGUMENT_COPY 0
#define PIX_ENABLE_BLOCK_ARGUMENT_COPY_SET 1
#endif
#if !defined(PIX_ENABLE_BLOCK_ARGUMENT_COPY)
// Default to enabled.
#define PIX_ENABLE_BLOCK_ARGUMENT_COPY 1
#define PIX_ENABLE_BLOCK_ARGUMENT_COPY_SET 1
#endif
struct PIXEventsBlockInfo;
struct PIXEventsThreadInfo
{
PIXEvent_EndEvent = 0x000,
PIXEvent_BeginEvent_VarArgs = 0x001,
PIXEvent_BeginEvent_NoArgs = 0x002,
PIXEvent_SetMarker_VarArgs = 0x007,
PIXEvent_SetMarker_NoArgs = 0x008,
PIXEventsBlockInfo* block;
UINT64* biasedLimit;
UINT64* destination;
};
PIXEvent_EndEvent_OnContext = 0x010,
PIXEvent_BeginEvent_OnContext_VarArgs = 0x011,
PIXEvent_BeginEvent_OnContext_NoArgs = 0x012,
PIXEvent_SetMarker_OnContext_VarArgs = 0x017,
PIXEvent_SetMarker_OnContext_NoArgs = 0x018,
//extern "C" UINT64 WINAPI PIXEventsReplaceBlock(PIXEventsThreadInfo * threadInfo, bool getEarliestTime) noexcept;
#define PIX_EVENT_METADATA_NONE 0x0
#define PIX_EVENT_METADATA_ON_CONTEXT 0x1
#define PIX_EVENT_METADATA_STRING_IS_ANSI 0x2
#define PIX_EVENT_METADATA_HAS_COLOR 0xF0
#ifndef PIX_GAMING_XBOX
#include "PIXEventsLegacy.h"
#endif
enum PIXEventType : UINT8
{
PIXEvent_EndEvent = 0x00,
PIXEvent_BeginEvent = 0x01,
PIXEvent_SetMarker = 0x02,
};
static const UINT64 PIXEventsReservedRecordSpaceQwords = 64;
//this is used to make sure SSE string copy always will end 16-byte write in the current block
//this way only a check if destination < limit can be performed, instead of destination < limit - 1
//since both these are UINT64* and SSE writes in 16 byte chunks, 8 bytes are kept in reserve
//so even if SSE overwrites 8 extra bytes, those will still belong to the correct block
//so even if SSE overwrites 8-15 extra bytes, those will still belong to the correct block
//on next iteration check destination will be greater than limit
//this is used as well for fixed size UMD events and PIXEndEvent since these require less space
//than other variable length user events and do not need big reserved space
@@ -46,20 +89,43 @@ static const UINT64 PIXEventsGraphicsRecordSpaceQwords = 64;
//Bits 7-19 (13 bits)
static const UINT64 PIXEventsBlockEndMarker = 0x00000000000FFF80;
//Bits 10-19 (10 bits)
static const UINT64 PIXEventsTypeReadMask = 0x00000000000FFC00;
static const UINT64 PIXEventsTypeWriteMask = 0x00000000000003FF;
static const UINT64 PIXEventsTypeBitShift = 10;
//Bits 20-63 (44 bits)
static const UINT64 PIXEventsTimestampReadMask = 0xFFFFFFFFFFF00000;
// V2 events
// Bits 00..06 (7 bits) - Size in QWORDS
static const UINT64 PIXEventsSizeWriteMask = 0x000000000000007F;
static const UINT64 PIXEventsSizeBitShift = 0;
static const UINT64 PIXEventsSizeReadMask = PIXEventsSizeWriteMask << PIXEventsSizeBitShift;
static const UINT64 PIXEventsSizeMax = (1ull << 7) - 1ull;
// Bits 07..11 (5 bits) - Event Type
static const UINT64 PIXEventsTypeWriteMask = 0x000000000000001F;
static const UINT64 PIXEventsTypeBitShift = 7;
static const UINT64 PIXEventsTypeReadMask = PIXEventsTypeWriteMask << PIXEventsTypeBitShift;
// Bits 12..19 (8 bits) - Event Specific Metadata
static const UINT64 PIXEventsMetadataWriteMask = 0x00000000000000FF;
static const UINT64 PIXEventsMetadataBitShift = 12;
static const UINT64 PIXEventsMetadataReadMask = PIXEventsMetadataWriteMask << PIXEventsMetadataBitShift;
// Buts 20..63 (44 bits) - Timestamp
static const UINT64 PIXEventsTimestampWriteMask = 0x00000FFFFFFFFFFF;
static const UINT64 PIXEventsTimestampBitShift = 20;
static const UINT64 PIXEventsTimestampReadMask = PIXEventsTimestampWriteMask << PIXEventsTimestampBitShift;
inline UINT64 PIXEncodeEventInfo(UINT64 timestamp, PIXEventType eventType)
inline UINT64 PIXEncodeEventInfo(UINT64 timestamp, PIXEventType eventType, UINT8 eventSize, UINT8 eventMetadata)
{
return ((timestamp & PIXEventsTimestampWriteMask) << PIXEventsTimestampBitShift) |
(((UINT64)eventType & PIXEventsTypeWriteMask) << PIXEventsTypeBitShift);
return
((timestamp & PIXEventsTimestampWriteMask) << PIXEventsTimestampBitShift) |
(((UINT64)eventType & PIXEventsTypeWriteMask) << PIXEventsTypeBitShift) |
(((UINT64)eventMetadata & PIXEventsMetadataWriteMask) << PIXEventsMetadataBitShift) |
(((UINT64)eventSize & PIXEventsSizeWriteMask) << PIXEventsSizeBitShift);
}
inline UINT8 PIXEncodeIndexColor(UINT8 color)
{
// There are 8 index colors, indexed 0 (default) to 7
return (color & 0x7) << 4;
}
//Bits 60-63 (4)
@@ -82,12 +148,13 @@ static const UINT64 PIXEventsStringIsShortcutWriteMask = 0x0000000000000001;
static const UINT64 PIXEventsStringIsShortcutReadMask = 0x0020000000000000;
static const UINT64 PIXEventsStringIsShortcutBitShift = 53;
inline UINT64 PIXEncodeStringInfo(UINT64 alignment, UINT64 copyChunkSize, BOOL isANSI, BOOL isShortcut)
inline void PIXEncodeStringInfo(UINT64*& destination, BOOL isANSI)
{
return ((alignment & PIXEventsStringAlignmentWriteMask) << PIXEventsStringAlignmentBitShift) |
((copyChunkSize & PIXEventsStringCopyChunkSizeWriteMask) << PIXEventsStringCopyChunkSizeBitShift) |
(((UINT64)isANSI & PIXEventsStringIsANSIWriteMask) << PIXEventsStringIsANSIBitShift) |
(((UINT64)isShortcut & PIXEventsStringIsShortcutWriteMask) << PIXEventsStringIsShortcutBitShift);
const UINT64 encodedStringInfo =
((sizeof(UINT64) & PIXEventsStringCopyChunkSizeWriteMask) << PIXEventsStringCopyChunkSizeBitShift) |
(((UINT64)isANSI & PIXEventsStringIsANSIWriteMask) << PIXEventsStringIsANSIBitShift);
*destination++ = encodedStringInfo;
}
template<UINT alignment, class T>
@@ -96,16 +163,62 @@ inline bool PIXIsPointerAligned(T* pointer)
return !(((UINT64)pointer) & (alignment - 1));
}
// Generic template version slower because of the additional clear write
template<class T>
inline void PIXCopyEventArgument(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, T argument)
{
if (destination < limit)
{
*destination = 0ull;
*((T*)destination) = argument;
++destination;
}
}
// int32 specialization to avoid slower double memory writes
template<>
inline void PIXCopyEventArgument<INT32>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, INT32 argument)
{
if (destination < limit)
{
*reinterpret_cast<INT64*>(destination) = static_cast<INT64>(argument);
++destination;
}
}
// unsigned int32 specialization to avoid slower double memory writes
template<>
inline void PIXCopyEventArgument<UINT32>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, UINT32 argument)
{
if (destination < limit)
{
*destination = static_cast<UINT64>(argument);
++destination;
}
}
// int64 specialization to avoid slower double memory writes
template<>
inline void PIXCopyEventArgument<INT64>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, INT64 argument)
{
if (destination < limit)
{
*reinterpret_cast<INT64*>(destination) = argument;
++destination;
}
}
// unsigned int64 specialization to avoid slower double memory writes
template<>
inline void PIXCopyEventArgument<UINT64>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, UINT64 argument)
{
if (destination < limit)
{
*destination = argument;
++destination;
}
}
//floats must be cast to double during writing the data to be properly printed later when reading the data
//this is needed because when float is passed to varargs function it's cast to double
template<>
@@ -113,7 +226,7 @@ inline void PIXCopyEventArgument<float>(_Out_writes_to_ptr_(limit) UINT64*& dest
{
if (destination < limit)
{
*((double*)destination) = (double)(argument);
*reinterpret_cast<double*>(destination) = static_cast<double>(argument);
++destination;
}
}
@@ -125,19 +238,19 @@ inline void PIXCopyEventArgument<char>(_Out_writes_to_ptr_(limit) UINT64*& desti
{
if (destination < limit)
{
*((INT64*)destination) = (INT64)(argument);
*reinterpret_cast<INT64*>(destination) = static_cast<INT64>(argument);
++destination;
}
}
//unsigned char has to be cast to a longer unsigned integer type
//UINT8 has to be cast to a longer unsigned integer type
//this is due to printf not ignoring correctly the upper bits of unsigned long long for a char format specifier
template<>
inline void PIXCopyEventArgument<unsigned char>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, unsigned char argument)
inline void PIXCopyEventArgument<UINT8>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, UINT8 argument)
{
if (destination < limit)
{
*destination = (UINT64)(argument);
*destination = static_cast<UINT64>(argument);
++destination;
}
}
@@ -149,66 +262,65 @@ inline void PIXCopyEventArgument<bool>(_Out_writes_to_ptr_(limit) UINT64*& desti
{
if (destination < limit)
{
*destination = (UINT64)(argument);
*destination = static_cast<UINT64>(argument);
++destination;
}
}
inline void PIXCopyEventArgumentSlowest(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PCSTR argument)
inline void PIXCopyEventStringArgumentSlow(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PCSTR argument)
{
*destination++ = PIXEncodeStringInfo(0, 8, TRUE, FALSE);
while (destination < limit)
{
UINT64 c = argument[0];
UINT64 c = static_cast<UINT8>(argument[0]);
if (!c)
{
*destination++ = 0;
return;
}
UINT64 x = c;
c = argument[1];
c = static_cast<UINT8>(argument[1]);
if (!c)
{
*destination++ = x;
return;
}
x |= c << 8;
c = argument[2];
c = static_cast<UINT8>(argument[2]);
if (!c)
{
*destination++ = x;
return;
}
x |= c << 16;
c = argument[3];
c = static_cast<UINT8>(argument[3]);
if (!c)
{
*destination++ = x;
return;
}
x |= c << 24;
c = argument[4];
c = static_cast<UINT8>(argument[4]);
if (!c)
{
*destination++ = x;
return;
}
x |= c << 32;
c = argument[5];
c = static_cast<UINT8>(argument[5]);
if (!c)
{
*destination++ = x;
return;
}
x |= c << 40;
c = argument[6];
c = static_cast<UINT8>(argument[6]);
if (!c)
{
*destination++ = x;
return;
}
x |= c << 48;
c = argument[7];
c = static_cast<UINT8>(argument[7]);
if (!c)
{
*destination++ = x;
@@ -220,35 +332,42 @@ inline void PIXCopyEventArgumentSlowest(_Out_writes_to_ptr_(limit) UINT64*& dest
}
}
template<bool>
inline void PIXCopyEventArgumentSlow(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PCSTR argument)
{
if (PIXIsPointerAligned<8>(argument))
PIXEncodeStringInfo(destination, TRUE);
PIXCopyEventStringArgumentSlow(destination, limit, argument);
}
template<>
inline void PIXCopyEventArgumentSlow<false>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PCSTR argument)
{
*destination++ = PIXEncodeStringInfo(0, 8, TRUE, FALSE);
PIXCopyEventStringArgumentSlow(destination, limit, argument);
}
#if (defined(_M_X64) || defined(_M_IX86)) && PIX_ENABLE_BLOCK_ARGUMENT_COPY
inline void PIXCopyEventStringArgumentFast(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PCSTR argument)
{
constexpr UINT64 mask1 = 0x0101010101010101ULL;
constexpr UINT64 mask2 = 0x8080808080808080ULL;
UINT64* source = (UINT64*)argument;
while (destination < limit)
{
UINT64 qword = *source++;
*destination++ = qword;
//check if any of the characters is a terminating zero
if (!((qword & 0xFF00000000000000) &&
(qword & 0xFF000000000000) &&
(qword & 0xFF0000000000) &&
(qword & 0xFF00000000) &&
(qword & 0xFF000000) &&
(qword & 0xFF0000) &&
(qword & 0xFF00) &&
(qword & 0xFF)))
UINT64 isTerminated = (qword - mask1) & (~qword & mask2);
if (isTerminated)
{
break;
}
}
}
else
{
PIXCopyEventArgumentSlowest(destination, limit, argument);
}
}
#endif
template<>
inline void PIXCopyEventArgument<PCSTR>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PCSTR argument)
@@ -257,44 +376,16 @@ inline void PIXCopyEventArgument<PCSTR>(_Out_writes_to_ptr_(limit) UINT64*& dest
{
if (argument != nullptr)
{
#if defined(_AMD64_) || defined(_X86_)
if (PIXIsPointerAligned<16>(argument))
#if (defined(_M_X64) || defined(_M_IX86)) && PIX_ENABLE_BLOCK_ARGUMENT_COPY
if (PIXIsPointerAligned<8>(argument))
{
*destination++ = PIXEncodeStringInfo(0, 16, TRUE, FALSE);
__m128i zero = _mm_setzero_si128();
if (PIXIsPointerAligned<16>(destination))
{
while (destination < limit)
{
__m128i mem = _mm_load_si128((__m128i*)argument);
_mm_store_si128((__m128i*)destination, mem);
//check if any of the characters is a terminating zero
__m128i res = _mm_cmpeq_epi8(mem, zero);
destination += 2;
if (_mm_movemask_epi8(res))
break;
argument += 16;
}
PIXEncodeStringInfo(destination, TRUE);
PIXCopyEventStringArgumentFast(destination, limit, argument);
}
else
#endif // (defined(_M_X64) || defined(_M_IX86)) && PIX_ENABLE_BLOCK_ARGUMENT_COPY
{
while (destination < limit)
{
__m128i mem = _mm_load_si128((__m128i*)argument);
_mm_storeu_si128((__m128i*)destination, mem);
//check if any of the characters is a terminating zero
__m128i res = _mm_cmpeq_epi8(mem, zero);
destination += 2;
if (_mm_movemask_epi8(res))
break;
argument += 16;
}
}
}
else
#endif // _AMD64_ || _X86_
{
PIXCopyEventArgumentSlow(destination, limit, argument);
PIXCopyEventArgumentSlow<true>(destination, limit, argument);
}
}
else
@@ -304,39 +395,64 @@ inline void PIXCopyEventArgument<PCSTR>(_Out_writes_to_ptr_(limit) UINT64*& dest
}
}
inline void PIXCopyStringArgument(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PCSTR argument)
{
if (argument != nullptr)
{
#if (defined(_M_X64) || defined(_M_IX86)) && PIX_ENABLE_BLOCK_ARGUMENT_COPY
if (PIXIsPointerAligned<8>(argument))
{
PIXCopyEventStringArgumentFast(destination, limit, argument);
}
else
#endif // (defined(_M_X64) || defined(_M_IX86)) && PIX_ENABLE_BLOCK_ARGUMENT_COPY
{
PIXCopyEventArgumentSlow<false>(destination, limit, argument);
}
}
else
{
*destination++ = 0ull;
}
}
template<>
inline void PIXCopyEventArgument<PSTR>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PSTR argument)
{
PIXCopyEventArgument(destination, limit, (PCSTR)argument);
}
inline void PIXCopyEventArgumentSlowest(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PCWSTR argument)
inline void PIXCopyStringArgument(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PSTR argument)
{
PIXCopyStringArgument(destination, limit, (PCSTR)argument);
}
inline void PIXCopyEventStringArgumentSlow(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PCWSTR argument)
{
*destination++ = PIXEncodeStringInfo(0, 8, FALSE, FALSE);
while (destination < limit)
{
UINT64 c = argument[0];
UINT64 c = static_cast<UINT16>(argument[0]);
if (!c)
{
*destination++ = 0;
return;
}
UINT64 x = c;
c = argument[1];
c = static_cast<UINT16>(argument[1]);
if (!c)
{
*destination++ = x;
return;
}
x |= c << 16;
c = argument[2];
c = static_cast<UINT16>(argument[2]);
if (!c)
{
*destination++ = x;
return;
}
x |= c << 32;
c = argument[3];
c = static_cast<UINT16>(argument[3]);
if (!c)
{
*destination++ = x;
@@ -348,11 +464,22 @@ inline void PIXCopyEventArgumentSlowest(_Out_writes_to_ptr_(limit) UINT64*& dest
}
}
template<bool>
inline void PIXCopyEventArgumentSlow(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PCWSTR argument)
{
if (PIXIsPointerAligned<8>(argument))
PIXEncodeStringInfo(destination, FALSE);
PIXCopyEventStringArgumentSlow(destination, limit, argument);
}
template<>
inline void PIXCopyEventArgumentSlow<false>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PCWSTR argument)
{
PIXCopyEventStringArgumentSlow(destination, limit, argument);
}
#if (defined(_M_X64) || defined(_M_IX86)) && PIX_ENABLE_BLOCK_ARGUMENT_COPY
inline void PIXCopyEventStringArgumentFast(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PCWSTR argument)
{
*destination++ = PIXEncodeStringInfo(0, 8, FALSE, FALSE);
UINT64* source = (UINT64*)argument;
while (destination < limit)
{
@@ -369,11 +496,7 @@ inline void PIXCopyEventArgumentSlow(_Out_writes_to_ptr_(limit) UINT64*& destina
}
}
}
else
{
PIXCopyEventArgumentSlowest(destination, limit, argument);
}
}
#endif
template<>
inline void PIXCopyEventArgument<PCWSTR>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PCWSTR argument)
@@ -382,44 +505,16 @@ inline void PIXCopyEventArgument<PCWSTR>(_Out_writes_to_ptr_(limit) UINT64*& des
{
if (argument != nullptr)
{
#if defined(_AMD64_) || defined(_X86_)
if (PIXIsPointerAligned<16>(argument))
#if (defined(_M_X64) || defined(_M_IX86)) && PIX_ENABLE_BLOCK_ARGUMENT_COPY
if (PIXIsPointerAligned<8>(argument))
{
*destination++ = PIXEncodeStringInfo(0, 16, FALSE, FALSE);
__m128i zero = _mm_setzero_si128();
if (PIXIsPointerAligned<16>(destination))
{
while (destination < limit)
{
__m128i mem = _mm_load_si128((__m128i*)argument);
_mm_store_si128((__m128i*)destination, mem);
//check if any of the characters is a terminating zero
__m128i res = _mm_cmpeq_epi16(mem, zero);
destination += 2;
if (_mm_movemask_epi8(res))
break;
argument += 8;
}
PIXEncodeStringInfo(destination, FALSE);
PIXCopyEventStringArgumentFast(destination, limit, argument);
}
else
#endif // (defined(_M_X64) || defined(_M_IX86)) && PIX_ENABLE_BLOCK_ARGUMENT_COPY
{
while (destination < limit)
{
__m128i mem = _mm_load_si128((__m128i*)argument);
_mm_storeu_si128((__m128i*)destination, mem);
//check if any of the characters is a terminating zero
__m128i res = _mm_cmpeq_epi16(mem, zero);
destination += 2;
if (_mm_movemask_epi8(res))
break;
argument += 8;
}
}
}
else
#endif // _AMD64_ || _X86_
{
PIXCopyEventArgumentSlow(destination, limit, argument);
PIXCopyEventArgumentSlow<true>(destination, limit, argument);
}
}
else
@@ -429,44 +524,71 @@ inline void PIXCopyEventArgument<PCWSTR>(_Out_writes_to_ptr_(limit) UINT64*& des
}
}
inline void PIXCopyStringArgument(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PCWSTR argument)
{
if (argument != nullptr)
{
#if (defined(_M_X64) || defined(_M_IX86)) && PIX_ENABLE_BLOCK_ARGUMENT_COPY
if (PIXIsPointerAligned<8>(argument))
{
PIXCopyEventStringArgumentFast(destination, limit, argument);
}
else
#endif // (defined(_M_X64) || defined(_M_IX86)) && PIX_ENABLE_BLOCK_ARGUMENT_COPY
{
PIXCopyEventArgumentSlow<false>(destination, limit, argument);
}
}
else
{
*destination++ = 0ull;
}
}
template<>
inline void PIXCopyEventArgument<PWSTR>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PWSTR argument)
{
PIXCopyEventArgument(destination, limit, (PCWSTR)argument);
};
#if defined(__d3d12_x_h__) || defined(__d3d12_h__)
inline void PIXCopyStringArgument(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PWSTR argument)
{
PIXCopyStringArgument(destination, limit, (PCWSTR)argument);
};
inline void PIXSetMarkerOnContext(_In_ ID3D12GraphicsCommandList* commandList, _In_reads_bytes_(size) void* data, UINT size)
#if defined(__d3d12_x_h__) || defined(__d3d12_xs_h__) || defined(__d3d12_h__)
inline void PIXSetGPUMarkerOnContext(_In_ ID3D12GraphicsCommandList* commandList, _In_reads_bytes_(size) void* data, UINT size)
{
commandList->SetMarker(D3D12_EVENT_METADATA, data, size);
}
inline void PIXSetMarkerOnContext(_In_ ID3D12CommandQueue* commandQueue, _In_reads_bytes_(size) void* data, UINT size)
inline void PIXSetGPUMarkerOnContext(_In_ ID3D12CommandQueue* commandQueue, _In_reads_bytes_(size) void* data, UINT size)
{
commandQueue->SetMarker(D3D12_EVENT_METADATA, data, size);
}
inline void PIXBeginEventOnContext(_In_ ID3D12GraphicsCommandList* commandList, _In_reads_bytes_(size) void* data, UINT size)
inline void PIXBeginGPUEventOnContext(_In_ ID3D12GraphicsCommandList* commandList, _In_reads_bytes_(size) void* data, UINT size)
{
commandList->BeginEvent(D3D12_EVENT_METADATA, data, size);
}
inline void PIXBeginEventOnContext(_In_ ID3D12CommandQueue* commandQueue, _In_reads_bytes_(size) void* data, UINT size)
inline void PIXBeginGPUEventOnContext(_In_ ID3D12CommandQueue* commandQueue, _In_reads_bytes_(size) void* data, UINT size)
{
commandQueue->BeginEvent(D3D12_EVENT_METADATA, data, size);
}
inline void PIXEndEventOnContext(_In_ ID3D12GraphicsCommandList* commandList)
inline void PIXEndGPUEventOnContext(_In_ ID3D12GraphicsCommandList* commandList)
{
commandList->EndEvent();
}
inline void PIXEndEventOnContext(_In_ ID3D12CommandQueue* commandQueue)
inline void PIXEndGPUEventOnContext(_In_ ID3D12CommandQueue* commandQueue)
{
commandQueue->EndEvent();
}
#endif //__d3d12_x_h__
#endif //__d3d12_h__
template<class T> struct PIXInferScopedEventType { typedef T Type; };
template<class T> struct PIXInferScopedEventType<const T> { typedef T Type; };
@@ -480,4 +602,9 @@ template<> struct PIXInferScopedEventType<UINT> { typedef void Type; };
template<> struct PIXInferScopedEventType<const UINT> { typedef void Type; };
template<> struct PIXInferScopedEventType<INT> { typedef void Type; };
template<> struct PIXInferScopedEventType<const INT> { typedef void Type; };
template<> struct PIXInferScopedEventType<UINT8> { typedef void Type; };
template<> struct PIXInferScopedEventType<const UINT8> { typedef void Type; };
template<> struct PIXInferScopedEventType<INT8> { typedef void Type; };
template<> struct PIXInferScopedEventType<const INT8> { typedef void Type; };
#endif //_PIXEventsCommon_H_

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,565 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// Don't include this file directly - use pix3.h
// This file encodes PIX events in the legacy PIX event format.
#ifndef _PIXEventsLegacy_H_
#define _PIXEventsLegacy_H_
#include <cstdint>
#if defined(_M_X64) || defined(_M_IX86)
#include <emmintrin.h>
#endif
namespace PixEventsLegacy
{
enum PIXEventType
{
PIXEvent_EndEvent = 0x000,
PIXEvent_BeginEvent_VarArgs = 0x001,
PIXEvent_BeginEvent_NoArgs = 0x002,
PIXEvent_SetMarker_VarArgs = 0x007,
PIXEvent_SetMarker_NoArgs = 0x008,
PIXEvent_EndEvent_OnContext = 0x010,
PIXEvent_BeginEvent_OnContext_VarArgs = 0x011,
PIXEvent_BeginEvent_OnContext_NoArgs = 0x012,
PIXEvent_SetMarker_OnContext_VarArgs = 0x017,
PIXEvent_SetMarker_OnContext_NoArgs = 0x018,
};
static const UINT64 PIXEventsReservedRecordSpaceQwords = 64;
static const UINT64 PIXEventsReservedTailSpaceQwords = 2;
static const UINT64 PIXEventsSafeFastCopySpaceQwords = PIXEventsReservedRecordSpaceQwords - PIXEventsReservedTailSpaceQwords;
static const UINT64 PIXEventsGraphicsRecordSpaceQwords = 64;
//Bits 7-19 (13 bits)
static const UINT64 PIXEventsBlockEndMarker = 0x00000000000FFF80;
//Bits 10-19 (10 bits)
static const UINT64 PIXEventsTypeReadMask = 0x00000000000FFC00;
static const UINT64 PIXEventsTypeWriteMask = 0x00000000000003FF;
static const UINT64 PIXEventsTypeBitShift = 10;
//Bits 20-63 (44 bits)
static const UINT64 PIXEventsTimestampReadMask = 0xFFFFFFFFFFF00000;
static const UINT64 PIXEventsTimestampWriteMask = 0x00000FFFFFFFFFFF;
static const UINT64 PIXEventsTimestampBitShift = 20;
inline UINT64 PIXEncodeEventInfo(UINT64 timestamp, PIXEventType eventType)
{
return ((timestamp & PIXEventsTimestampWriteMask) << PIXEventsTimestampBitShift) |
(((UINT64)eventType & PIXEventsTypeWriteMask) << PIXEventsTypeBitShift);
}
//Bits 60-63 (4)
static const UINT64 PIXEventsStringAlignmentWriteMask = 0x000000000000000F;
static const UINT64 PIXEventsStringAlignmentReadMask = 0xF000000000000000;
static const UINT64 PIXEventsStringAlignmentBitShift = 60;
//Bits 55-59 (5)
static const UINT64 PIXEventsStringCopyChunkSizeWriteMask = 0x000000000000001F;
static const UINT64 PIXEventsStringCopyChunkSizeReadMask = 0x0F80000000000000;
static const UINT64 PIXEventsStringCopyChunkSizeBitShift = 55;
//Bit 54
static const UINT64 PIXEventsStringIsANSIWriteMask = 0x0000000000000001;
static const UINT64 PIXEventsStringIsANSIReadMask = 0x0040000000000000;
static const UINT64 PIXEventsStringIsANSIBitShift = 54;
//Bit 53
static const UINT64 PIXEventsStringIsShortcutWriteMask = 0x0000000000000001;
static const UINT64 PIXEventsStringIsShortcutReadMask = 0x0020000000000000;
static const UINT64 PIXEventsStringIsShortcutBitShift = 53;
inline UINT64 PIXEncodeStringInfo(UINT64 alignment, UINT64 copyChunkSize, BOOL isANSI, BOOL isShortcut)
{
return ((alignment & PIXEventsStringAlignmentWriteMask) << PIXEventsStringAlignmentBitShift) |
((copyChunkSize & PIXEventsStringCopyChunkSizeWriteMask) << PIXEventsStringCopyChunkSizeBitShift) |
(((UINT64)isANSI & PIXEventsStringIsANSIWriteMask) << PIXEventsStringIsANSIBitShift) |
(((UINT64)isShortcut & PIXEventsStringIsShortcutWriteMask) << PIXEventsStringIsShortcutBitShift);
}
template<UINT alignment, class T>
inline bool PIXIsPointerAligned(T* pointer)
{
return !(((UINT64)pointer) & (alignment - 1));
}
// Generic template version slower because of the additional clear write
template<class T>
inline void PIXCopyEventArgument(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, T argument)
{
if (destination < limit)
{
*destination = 0ull;
*((T*)destination) = argument;
++destination;
}
}
// int32 specialization to avoid slower double memory writes
template<>
inline void PIXCopyEventArgument<INT32>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, INT32 argument)
{
if (destination < limit)
{
*reinterpret_cast<INT64*>(destination) = static_cast<INT64>(argument);
++destination;
}
}
// unsigned int32 specialization to avoid slower double memory writes
template<>
inline void PIXCopyEventArgument<UINT32>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, UINT32 argument)
{
if (destination < limit)
{
*destination = static_cast<UINT64>(argument);
++destination;
}
}
// int64 specialization to avoid slower double memory writes
template<>
inline void PIXCopyEventArgument<INT64>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, INT64 argument)
{
if (destination < limit)
{
*reinterpret_cast<INT64*>(destination) = argument;
++destination;
}
}
// unsigned int64 specialization to avoid slower double memory writes
template<>
inline void PIXCopyEventArgument<UINT64>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, UINT64 argument)
{
if (destination < limit)
{
*destination = argument;
++destination;
}
}
//floats must be cast to double during writing the data to be properly printed later when reading the data
//this is needed because when float is passed to varargs function it's cast to double
template<>
inline void PIXCopyEventArgument<float>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, float argument)
{
if (destination < limit)
{
*reinterpret_cast<double*>(destination) = static_cast<double>(argument);
++destination;
}
}
//char has to be cast to a longer signed integer type
//this is due to printf not ignoring correctly the upper bits of unsigned long long for a char format specifier
template<>
inline void PIXCopyEventArgument<char>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, char argument)
{
if (destination < limit)
{
*reinterpret_cast<INT64*>(destination) = static_cast<INT64>(argument);
++destination;
}
}
//unsigned char has to be cast to a longer unsigned integer type
//this is due to printf not ignoring correctly the upper bits of unsigned long long for a char format specifier
template<>
inline void PIXCopyEventArgument<unsigned char>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, unsigned char argument)
{
if (destination < limit)
{
*destination = static_cast<UINT64>(argument);
++destination;
}
}
//bool has to be cast to an integer since it's not explicitly supported by string format routines
//there's no format specifier for bool type, but it should work with integer format specifiers
template<>
inline void PIXCopyEventArgument<bool>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, bool argument)
{
if (destination < limit)
{
*destination = static_cast<UINT64>(argument);
++destination;
}
}
inline void PIXCopyEventArgumentSlowest(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PCSTR argument)
{
*destination++ = PIXEncodeStringInfo(0, 8, TRUE, FALSE);
while (destination < limit)
{
UINT64 c = static_cast<uint8_t>(argument[0]);
if (!c)
{
*destination++ = 0;
return;
}
UINT64 x = c;
c = static_cast<uint8_t>(argument[1]);
if (!c)
{
*destination++ = x;
return;
}
x |= c << 8;
c = static_cast<uint8_t>(argument[2]);
if (!c)
{
*destination++ = x;
return;
}
x |= c << 16;
c = static_cast<uint8_t>(argument[3]);
if (!c)
{
*destination++ = x;
return;
}
x |= c << 24;
c = static_cast<uint8_t>(argument[4]);
if (!c)
{
*destination++ = x;
return;
}
x |= c << 32;
c = static_cast<uint8_t>(argument[5]);
if (!c)
{
*destination++ = x;
return;
}
x |= c << 40;
c = static_cast<uint8_t>(argument[6]);
if (!c)
{
*destination++ = x;
return;
}
x |= c << 48;
c = static_cast<uint8_t>(argument[7]);
if (!c)
{
*destination++ = x;
return;
}
x |= c << 56;
*destination++ = x;
argument += 8;
}
}
inline void PIXCopyEventArgumentSlow(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PCSTR argument)
{
#if PIX_ENABLE_BLOCK_ARGUMENT_COPY
if (PIXIsPointerAligned<8>(argument))
{
*destination++ = PIXEncodeStringInfo(0, 8, TRUE, FALSE);
UINT64* source = (UINT64*)argument;
while (destination < limit)
{
UINT64 qword = *source++;
*destination++ = qword;
//check if any of the characters is a terminating zero
if (!((qword & 0xFF00000000000000) &&
(qword & 0xFF000000000000) &&
(qword & 0xFF0000000000) &&
(qword & 0xFF00000000) &&
(qword & 0xFF000000) &&
(qword & 0xFF0000) &&
(qword & 0xFF00) &&
(qword & 0xFF)))
{
break;
}
}
}
else
#endif // PIX_ENABLE_BLOCK_ARGUMENT_COPY
{
PIXCopyEventArgumentSlowest(destination, limit, argument);
}
}
template<>
inline void PIXCopyEventArgument<PCSTR>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PCSTR argument)
{
if (destination < limit)
{
if (argument != nullptr)
{
#if (defined(_M_X64) || defined(_M_IX86)) && PIX_ENABLE_BLOCK_ARGUMENT_COPY
if (PIXIsPointerAligned<16>(argument))
{
*destination++ = PIXEncodeStringInfo(0, 16, TRUE, FALSE);
__m128i zero = _mm_setzero_si128();
if (PIXIsPointerAligned<16>(destination))
{
while (destination < limit)
{
__m128i mem = _mm_load_si128((__m128i*)argument);
_mm_store_si128((__m128i*)destination, mem);
//check if any of the characters is a terminating zero
__m128i res = _mm_cmpeq_epi8(mem, zero);
destination += 2;
if (_mm_movemask_epi8(res))
break;
argument += 16;
}
}
else
{
while (destination < limit)
{
__m128i mem = _mm_load_si128((__m128i*)argument);
_mm_storeu_si128((__m128i*)destination, mem);
//check if any of the characters is a terminating zero
__m128i res = _mm_cmpeq_epi8(mem, zero);
destination += 2;
if (_mm_movemask_epi8(res))
break;
argument += 16;
}
}
}
else
#endif // (defined(_M_X64) || defined(_M_IX86)) && PIX_ENABLE_BLOCK_ARGUMENT_COPY
{
PIXCopyEventArgumentSlow(destination, limit, argument);
}
}
else
{
*destination++ = 0ull;
}
}
}
template<>
inline void PIXCopyEventArgument<PSTR>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PSTR argument)
{
PIXCopyEventArgument(destination, limit, (PCSTR)argument);
}
inline void PIXCopyEventArgumentSlowest(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PCWSTR argument)
{
*destination++ = PIXEncodeStringInfo(0, 8, FALSE, FALSE);
while (destination < limit)
{
UINT64 c = static_cast<uint16_t>(argument[0]);
if (!c)
{
*destination++ = 0;
return;
}
UINT64 x = c;
c = static_cast<uint16_t>(argument[1]);
if (!c)
{
*destination++ = x;
return;
}
x |= c << 16;
c = static_cast<uint16_t>(argument[2]);
if (!c)
{
*destination++ = x;
return;
}
x |= c << 32;
c = static_cast<uint16_t>(argument[3]);
if (!c)
{
*destination++ = x;
return;
}
x |= c << 48;
*destination++ = x;
argument += 4;
}
}
inline void PIXCopyEventArgumentSlow(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PCWSTR argument)
{
#if PIX_ENABLE_BLOCK_ARGUMENT_COPY
if (PIXIsPointerAligned<8>(argument))
{
*destination++ = PIXEncodeStringInfo(0, 8, FALSE, FALSE);
UINT64* source = (UINT64*)argument;
while (destination < limit)
{
UINT64 qword = *source++;
*destination++ = qword;
//check if any of the characters is a terminating zero
//TODO: check if reversed condition is faster
if (!((qword & 0xFFFF000000000000) &&
(qword & 0xFFFF00000000) &&
(qword & 0xFFFF0000) &&
(qword & 0xFFFF)))
{
break;
}
}
}
else
#endif // PIX_ENABLE_BLOCK_ARGUMENT_COPY
{
PIXCopyEventArgumentSlowest(destination, limit, argument);
}
}
template<>
inline void PIXCopyEventArgument<PCWSTR>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PCWSTR argument)
{
if (destination < limit)
{
if (argument != nullptr)
{
#if (defined(_M_X64) || defined(_M_IX86)) && PIX_ENABLE_BLOCK_ARGUMENT_COPY
if (PIXIsPointerAligned<16>(argument))
{
*destination++ = PIXEncodeStringInfo(0, 16, FALSE, FALSE);
__m128i zero = _mm_setzero_si128();
if (PIXIsPointerAligned<16>(destination))
{
while (destination < limit)
{
__m128i mem = _mm_load_si128((__m128i*)argument);
_mm_store_si128((__m128i*)destination, mem);
//check if any of the characters is a terminating zero
__m128i res = _mm_cmpeq_epi16(mem, zero);
destination += 2;
if (_mm_movemask_epi8(res))
break;
argument += 8;
}
}
else
{
while (destination < limit)
{
__m128i mem = _mm_load_si128((__m128i*)argument);
_mm_storeu_si128((__m128i*)destination, mem);
//check if any of the characters is a terminating zero
__m128i res = _mm_cmpeq_epi16(mem, zero);
destination += 2;
if (_mm_movemask_epi8(res))
break;
argument += 8;
}
}
}
else
#endif // (defined(_M_X64) || defined(_M_IX86)) && PIX_ENABLE_BLOCK_ARGUMENT_COPY
{
PIXCopyEventArgumentSlow(destination, limit, argument);
}
}
else
{
*destination++ = 0ull;
}
}
}
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... 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; }
static constexpr PIXEventType End() { return PIXEvent_EndEvent; }
// 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; }
static constexpr PIXEventType GpuEndOnContext() { return PIXEvent_EndEvent_OnContext; }
#else
static constexpr PIXEventType GpuBeginOnContext() { return PIXEvent_BeginEvent_VarArgs; }
static constexpr PIXEventType GpuSetMarkerOnContext() { return PIXEvent_SetMarker_VarArgs; }
static constexpr PIXEventType GpuEndOnContext() { return PIXEvent_EndEvent; }
#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; }
static constexpr PIXEventType End() { return PIXEvent_EndEvent; }
#ifdef PIX_XBOX
static constexpr PIXEventType GpuBeginOnContext() { return PIXEvent_BeginEvent_OnContext_NoArgs; }
static constexpr PIXEventType GpuSetMarkerOnContext() { return PIXEvent_SetMarker_OnContext_NoArgs; }
static constexpr PIXEventType GpuEndOnContext() { return PIXEvent_EndEvent_OnContext; }
#else
static constexpr PIXEventType GpuBeginOnContext() { return PIXEvent_BeginEvent_NoArgs; }
static constexpr PIXEventType GpuSetMarkerOnContext() { return PIXEvent_SetMarker_NoArgs; }
static constexpr PIXEventType GpuEndOnContext() { return PIXEvent_EndEvent; }
#endif
};
template<size_t size, typename STR, typename... ARGS>
UINT64* EncodeBeginEventForContext(UINT64 (&buffer)[size], UINT64 color, STR formatString, ARGS... args)
{
UINT64* destination = buffer;
UINT64* limit = buffer + PIXEventsGraphicsRecordSpaceQwords - PIXEventsReservedTailSpaceQwords;
*destination++ = PIXEncodeEventInfo(0, PIXEventTypeInferer<ARGS...>::GpuBeginOnContext());
*destination++ = color;
PIXCopyEventArguments(destination, limit, formatString, args...);
*destination = 0ull;
return destination;
}
template<size_t size, typename STR, typename... ARGS>
UINT64* EncodeSetMarkerForContext(UINT64 (&buffer)[size], UINT64 color, STR formatString, ARGS... args)
{
UINT64* destination = buffer;
UINT64* limit = buffer + PIXEventsGraphicsRecordSpaceQwords - PIXEventsReservedTailSpaceQwords;
*destination++ = PIXEncodeEventInfo(0, PIXEventTypeInferer<ARGS...>::GpuSetMarkerOnContext());
*destination++ = color;
PIXCopyEventArguments(destination, limit, formatString, args...);
*destination = 0ull;
return destination;
}
}
#endif //_PIXEventsLegacy_H_

View File

@@ -1,11 +1,6 @@
/*==========================================================================;
*
* Copyright (C) Microsoft Corporation. All Rights Reserved.
*
* File: pix3.h
* Content: PIX include file
*
****************************************************************************/
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#pragma once
#ifndef _PIX3_H_
@@ -14,26 +9,26 @@
#include <sal.h>
#ifndef __cplusplus
#error "Only C++ files can include pix.h. C is not supported."
#error "Only C++ files can include pix3.h. C is not supported."
#endif
#if defined(XBOX) || defined(_XBOX_ONE) || defined(_DURANGO)
#include "pix3_xbox.h"
#else
#include "pix3_win.h"
#if !defined(USE_PIX_SUPPORTED_ARCHITECTURE)
#if defined(_M_X64) || defined(USE_PIX_ON_ALL_ARCHITECTURES) || defined(_M_ARM64)
#define USE_PIX_SUPPORTED_ARCHITECTURE
#endif
#endif
//
// The PIX event/marker APIs compile to nothing on retail builds and on x86 builds
//
#if (!defined(USE_PIX)) && ((defined(_DEBUG) || DBG || (defined(PROFILE) && !defined(FASTCAP)) || defined(PROFILE_BUILD)) && !defined(i386) && defined(_AMD64_) && !defined(_PREFAST_))
#if !defined(USE_PIX)
#if defined(USE_PIX_SUPPORTED_ARCHITECTURE) && (defined(_DEBUG) || DBG || defined(PROFILE) || defined(PROFILE_BUILD)) && !defined(_PREFAST_)
#define USE_PIX
#endif
#if defined(USE_PIX) && !defined(_AMD64_) && !defined(USE_PIX_ON_ALL_ARCHITECTURES)
#pragma message("Warning: Pix markers are only supported on AMD64")
#endif
#if defined(USE_PIX) && !defined(USE_PIX_SUPPORTED_ARCHITECTURE)
#pragma message("Warning: Pix markers are only supported on AMD64 and ARM64")
#endif
// These flags are used by both PIXBeginCapture and PIXGetCaptureState
#define PIX_CAPTURE_TIMING (1 << 0)
#define PIX_CAPTURE_GPU (1 << 1)
@@ -44,49 +39,122 @@
#define PIX_CAPTURE_SYSTEM_MONITOR_COUNTERS (1 << 6)
#define PIX_CAPTURE_VIDEO (1 << 7)
#define PIX_CAPTURE_AUDIO (1 << 8)
#define PIX_CAPTURE_GPU_TRACE (1 << 9)
#define PIX_CAPTURE_RESERVED (1 << 15)
typedef union PIXCaptureParameters
union PIXCaptureParameters
{
enum PIXCaptureStorage
{
Memory = 0,
MemoryCircular = 1, // Xbox only
FileCircular = 2, // PC only
};
struct GpuCaptureParameters
{
PVOID reserved;
PCWSTR FileName;
} GpuCaptureParameters;
struct TimingCaptureParameters
{
PCWSTR FileName;
UINT32 MaximumToolingMemorySizeMb;
PIXCaptureStorage CaptureStorage;
BOOL CaptureGpuTiming;
BOOL CaptureCallstacks;
PWSTR FileName;
BOOL CaptureCpuSamples;
UINT32 CpuSamplesPerSecond;
BOOL CaptureFileIO;
BOOL CaptureVirtualAllocEvents;
BOOL CaptureHeapAllocEvents;
BOOL CaptureXMemEvents; // Xbox only
BOOL CapturePixMemEvents;
BOOL CapturePageFaultEvents;
BOOL CaptureVideoFrames; // Xbox only
} TimingCaptureParameters;
} PIXCaptureParameters, *PPIXCaptureParameters;
struct GpuTraceParameters // Xbox Series and newer only
{
PWSTR FileName;
UINT32 MaximumToolingMemorySizeMb;
BOOL CaptureGpuOccupancy;
} GpuTraceParameters;
};
#if defined (USE_PIX) && (defined(_AMD64_) || defined(USE_PIX_ON_ALL_ARCHITECTURES))
typedef PIXCaptureParameters* PPIXCaptureParameters;
#if defined(XBOX) || defined(_XBOX_ONE) || defined(_DURANGO) || defined(_GAMING_XBOX) || defined(_GAMING_XBOX_SCARLETT)
#include "pix3_xbox.h"
#else
#include "pix3_win.h"
#endif
#if defined(XBOX) || defined(_XBOX_ONE) || defined(_DURANGO) || defined(_GAMING_XBOX) || defined(_GAMING_XBOX_SCARLETT)
#define PIX_XBOX
#if defined(_GAMING_XBOX) || defined(_GAMING_XBOX_SCARLETT)
#define PIX_GAMING_XBOX
#endif
#endif
#if !defined(PIX_USE_GPU_MARKERS_V2)
#ifdef PIX_GAMING_XBOX
#define PIX_USE_GPU_MARKERS_V2
#endif
#endif
#if defined(USE_PIX_SUPPORTED_ARCHITECTURE) && (defined(USE_PIX) || defined(USE_PIX_RETAIL))
#define PIX_EVENTS_ARE_TURNED_ON
#include "PIXEventsCommon.h"
#include "PIXEventsGenerated.h"
#include "PIXEvents.h"
#ifdef USE_PIX
// Starts a programmatically controlled capture.
// captureFlags uses the PIX_CAPTURE_* family of flags to specify the type of capture to take
extern "C" HRESULT WINAPI PIXBeginCapture(DWORD captureFlags, _In_opt_ const PPIXCaptureParameters captureParameters);
extern "C" HRESULT WINAPI PIXBeginCapture2(DWORD captureFlags, _In_opt_ const PPIXCaptureParameters captureParameters);
inline HRESULT PIXBeginCapture(DWORD captureFlags, _In_opt_ const PPIXCaptureParameters captureParameters) { return PIXBeginCapture2(captureFlags, captureParameters); }
// Stops a programmatically controlled capture
// If discard == TRUE, the captured data is discarded
// If discard == FALSE, the captured data is saved
// discard parameter is not supported on Windows
extern "C" HRESULT WINAPI PIXEndCapture(BOOL discard);
extern "C" DWORD WINAPI PIXGetCaptureState();
extern "C" void WINAPI PIXReportCounter(_In_ PCWSTR name, float value);
#else
#endif // USE_PIX
#endif // (USE_PIX_SUPPORTED_ARCHITECTURE) && (USE_PIX || USE_PIX_RETAIL)
#if !defined(USE_PIX_SUPPORTED_ARCHITECTURE) || !defined(USE_PIX)
// Eliminate these APIs when not using PIX
inline HRESULT PIXBeginCapture2(DWORD, _In_opt_ const PIXCaptureParameters*) { return S_OK; }
inline HRESULT PIXBeginCapture(DWORD, _In_opt_ const PIXCaptureParameters*) { return S_OK; }
inline HRESULT PIXEndCapture(BOOL) { return S_OK; }
inline HRESULT PIXGpuCaptureNextFrames(PCWSTR, UINT32) { return S_OK; }
inline HRESULT PIXSetTargetWindow(HWND) { return S_OK; }
inline HRESULT PIXForceD3D11On12() { return S_OK; }
inline HRESULT WINAPI PIXSetHUDOptions(PIXHUDOptions) { return S_OK; }
inline bool WINAPI PIXIsAttachedForGpuCapture() { return false; }
inline HINSTANCE WINAPI PIXOpenCaptureInUI(PCWSTR) { return 0; }
inline HMODULE PIXLoadLatestWinPixGpuCapturerLibrary() { return nullptr; }
inline HMODULE PIXLoadLatestWinPixTimingCapturerLibrary() { return nullptr; }
inline DWORD PIXGetCaptureState() { return 0; }
inline void PIXReportCounter(_In_ PCWSTR, float) {}
inline void PIXNotifyWakeFromFenceSignal(_In_ HANDLE) {}
#if !defined(USE_PIX_RETAIL)
inline void PIXBeginEvent(UINT64, _In_ PCSTR, ...) {}
inline void PIXBeginEvent(UINT64, _In_ PCWSTR, ...) {}
@@ -98,19 +166,30 @@ 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, ...) {}
inline void PIXBeginRetailEvent(void*, UINT64, _In_ PCSTR, ...) {}
inline void PIXBeginRetailEvent(void*, UINT64, _In_ PCWSTR, ...) {}
inline void PIXEndRetailEvent(void*) {}
inline void PIXSetRetailMarker(void*, UINT64, _In_ PCSTR, ...) {}
inline void PIXSetRetailMarker(void*, UINT64, _In_ PCWSTR, ...) {}
inline void PIXScopedEvent(UINT64, _In_ PCSTR, ...) {}
inline void PIXScopedEvent(UINT64, _In_ PCWSTR, ...) {}
inline void PIXScopedEvent(void*, UINT64, _In_ PCSTR, ...) {}
inline void PIXScopedEvent(void*, UINT64, _In_ PCWSTR, ...) {}
#endif // USE_PIX
#endif // !USE_PIX_RETAIL
// don't show warnings about expressions with no effect
#pragma warning(disable:4548)
#pragma warning(disable:4555)
#endif // !USE_PIX_SUPPORTED_ARCHITECTURE || !USE_PIX
// Use these functions to specify colors to pass as metadata to a PIX event/marker API.
// Use PIX_COLOR() to specify a particular color for an event.
// Or, use PIX_COLOR_INDEX() to specify a set of unique event categories, and let PIX choose
// the colors to represent each category.
inline UINT PIX_COLOR(BYTE r, BYTE g, BYTE b) { return 0xff000000 | (r << 16) | (g << 8) | b; }
inline UINT PIX_COLOR_INDEX(BYTE i) { return i; }
const UINT PIX_COLOR_DEFAULT = PIX_COLOR_INDEX(0);
inline UINT32 PIX_COLOR(UINT8 r, UINT8 g, UINT8 b) { return 0xff000000u | ((UINT32)r << 16) | ((UINT32)g << 8) | (UINT32)b; }
inline UINT8 PIX_COLOR_INDEX(UINT8 i) { return i; }
const UINT8 PIX_COLOR_DEFAULT = PIX_COLOR_INDEX(0);
#endif // _PIX3_H_

View File

@@ -1,53 +1,509 @@
/*==========================================================================;
*
* Copyright (C) Microsoft Corporation. All Rights Reserved.
*
* File: PIX3_win.h
* Content: PIX include file
* Don't include this file directly - use pix3.h
*
****************************************************************************/
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// Don't include this file directly - use pix3.h
#pragma once
#ifndef _PIX3_H_
#error "Don't include this file directly - use pix3.h"
#error Don't include this file directly - use pix3.h
#endif
#ifndef _PIX3_WIN_H_
#define _PIX3_WIN_H_
struct PIXEventsBlockInfo
{
};
// PIXEventsThreadInfo is defined in PIXEventsCommon.h
struct PIXEventsThreadInfo;
struct PIXEventsThreadInfo
{
PIXEventsBlockInfo* block;
UINT64* biasedLimit;
UINT64* destination;
UINT64* limit;
UINT64 id;
};
//extern "C" PIXEventsThreadInfo* WINAPI PIXGetThreadInfo() noexcept;
//
//#if defined(USE_PIX) && defined(USE_PIX_SUPPORTED_ARCHITECTURE)
//// Notifies PIX that an event handle was set as a result of a D3D12 fence being signaled.
//// The event specified must have the same handle value as the handle
//// used in ID3D12Fence::SetEventOnCompletion.
//extern "C" void WINAPI PIXNotifyWakeFromFenceSignal(_In_ HANDLE event);
//
//// Notifies PIX that a block of memory was allocated
//extern "C" void WINAPI PIXRecordMemoryAllocationEvent(USHORT allocatorId, void* baseAddress, size_t size, UINT64 metadata);
//
//// Notifies PIX that a block of memory was freed
//extern "C" void WINAPI PIXRecordMemoryFreeEvent(USHORT allocatorId, void* baseAddress, size_t size, UINT64 metadata);
//
//#else
//
//// Eliminate these APIs when not using PIX
//inline void PIXRecordMemoryAllocationEvent(USHORT, void*, size_t, UINT64) {}
//inline void PIXRecordMemoryFreeEvent(USHORT, void*, size_t, UINT64) {}
//
//#endif
// The following defines denote the different metadata values that have been used
// by tools to denote how to parse pix marker event data. The first two values
// are legacy values.
// The following WINPIX_EVENT_* defines denote the different metadata values that have
// been used by tools to denote how to parse pix marker event data. The first two values
// are legacy values used by pix.h in the Windows SDK.
#define WINPIX_EVENT_UNICODE_VERSION 0
#define WINPIX_EVENT_ANSI_VERSION 1
#define WINPIX_EVENT_PIX3BLOB_VERSION 2
// These values denote PIX marker event data that was created by the WinPixEventRuntime.
// In early 2023 we revised the PIX marker format and defined a new version number.
#define WINPIX_EVENT_PIX3BLOB_VERSION 2
#define WINPIX_EVENT_PIX3BLOB_V2 6345127 // A number that other applications are unlikely to have used before
// For backcompat reasons, the WinPixEventRuntime uses the older PIX3BLOB format when it passes data
// into the D3D12 runtime. It will be updated to use the V2 format in the future.
#define D3D12_EVENT_METADATA WINPIX_EVENT_PIX3BLOB_VERSION
__forceinline UINT64 PIXGetTimestampCounter()
{
LARGE_INTEGER time = {};
QueryPerformanceCounter(&time);
return time.QuadPart;
return static_cast<UINT64>(time.QuadPart);
}
#define PIXSetCPUMarkerOnContext(context, metadata, ...) MakeCPUSetMarkerForContext(metadata, context, __VA_ARGS__)
#define PIXBeginCPUEventOnContext(context, metadata, ...) MakeCPUBeginEventForContext(metadata, context, __VA_ARGS__)
#define PIXEndCPUEventOnContext(context) MakeCPUEndEventForContext(context)
enum PIXHUDOptions
{
PIX_HUD_SHOW_ON_ALL_WINDOWS = 0x1,
PIX_HUD_SHOW_ON_TARGET_WINDOW_ONLY = 0x2,
PIX_HUD_SHOW_ON_NO_WINDOWS = 0x4
};
DEFINE_ENUM_FLAG_OPERATORS(PIXHUDOptions);
#if defined(USE_PIX_SUPPORTED_ARCHITECTURE) && defined(USE_PIX)
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES)
#include <shlobj.h>
#include <strsafe.h>
#include <knownfolders.h>
#include <shellapi.h>
#define PIXERRORCHECK(value) do { \
if (FAILED(value)) \
return nullptr; \
} while(0)
namespace PixImpl
{
#ifndef PIX3_WIN_UNIT_TEST
__forceinline BOOL GetModuleHandleExW(
DWORD dwFlags,
LPCWSTR lpModuleName,
HMODULE* phModule)
{
return ::GetModuleHandleExW(dwFlags, lpModuleName, phModule);
}
__forceinline HRESULT SHGetKnownFolderPath(
REFKNOWNFOLDERID rfid,
DWORD dwFlags,
HANDLE hToken,
PWSTR* ppszPath)
{
return ::SHGetKnownFolderPath(rfid, dwFlags, hToken, ppszPath);
}
__forceinline void CoTaskMemFree(LPVOID pv)
{
return ::CoTaskMemFree(pv);
}
__forceinline HANDLE FindFirstFileW(
LPCWSTR lpFileName,
LPWIN32_FIND_DATAW lpFindFileData)
{
return ::FindFirstFileW(lpFileName, lpFindFileData);
}
__forceinline DWORD GetFileAttributesW(LPCWSTR lpFileName)
{
return ::GetFileAttributesW(lpFileName);
}
__forceinline BOOL FindNextFileW(
HANDLE hFindFile,
LPWIN32_FIND_DATAW lpFindFileData)
{
return ::FindNextFileW(hFindFile, lpFindFileData);
}
__forceinline BOOL FindClose(HANDLE hFindFile)
{
return ::FindClose(hFindFile);
}
__forceinline HMODULE LoadLibraryExW(LPCWSTR lpLibFileName, DWORD flags)
{
return ::LoadLibraryExW(lpLibFileName, NULL, flags);
}
#endif // !PIX3_WIN_UNIT_TESTS
__forceinline void * GetGpuCaptureFunctionPtr(LPCSTR fnName) noexcept
{
HMODULE module = GetModuleHandleW(L"WinPixGpuCapturer.dll");
if (module == NULL)
{
return nullptr;
}
auto fn = (void*)GetProcAddress(module, fnName);
if (fn == nullptr)
{
return nullptr;
}
return fn;
}
__forceinline void* GetTimingCaptureFunctionPtr(LPCSTR fnName) noexcept
{
HMODULE module = GetModuleHandleW(L"WinPixTimingCapturer.dll");
if (module == NULL)
{
return nullptr;
}
auto fn = (void*)GetProcAddress(module, fnName);
if (fn == nullptr)
{
return nullptr;
}
return fn;
}
__forceinline HMODULE PIXLoadLatestCapturerLibrary(wchar_t const* capturerDllName, DWORD flags)
{
HMODULE libHandle{};
if (PixImpl::GetModuleHandleExW(0, capturerDllName, &libHandle))
{
return libHandle;
}
LPWSTR programFilesPath = nullptr;
if (FAILED(PixImpl::SHGetKnownFolderPath(FOLDERID_ProgramFiles, KF_FLAG_DEFAULT, NULL, &programFilesPath)))
{
PixImpl::CoTaskMemFree(programFilesPath);
return nullptr;
}
wchar_t pixSearchPath[MAX_PATH];
if (FAILED(StringCchCopyW(pixSearchPath, MAX_PATH, programFilesPath)))
{
PixImpl::CoTaskMemFree(programFilesPath);
return nullptr;
}
PixImpl::CoTaskMemFree(programFilesPath);
PIXERRORCHECK(StringCchCatW(pixSearchPath, MAX_PATH, L"\\Microsoft PIX\\*"));
WIN32_FIND_DATAW findData;
bool foundPixInstallation = false;
wchar_t newestVersionFound[MAX_PATH];
wchar_t output[MAX_PATH];
wchar_t possibleOutput[MAX_PATH];
HANDLE hFind = PixImpl::FindFirstFileW(pixSearchPath, &findData);
if (hFind != INVALID_HANDLE_VALUE)
{
do
{
if (((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) &&
(findData.cFileName[0] != '.'))
{
if (!foundPixInstallation || wcscmp(newestVersionFound, findData.cFileName) <= 0)
{
// length - 1 to get rid of the wildcard character in the search path
PIXERRORCHECK(StringCchCopyNW(possibleOutput, MAX_PATH, pixSearchPath, wcslen(pixSearchPath) - 1));
PIXERRORCHECK(StringCchCatW(possibleOutput, MAX_PATH, findData.cFileName));
PIXERRORCHECK(StringCchCatW(possibleOutput, MAX_PATH, L"\\"));
PIXERRORCHECK(StringCchCatW(possibleOutput, MAX_PATH, capturerDllName));
DWORD result = PixImpl::GetFileAttributesW(possibleOutput);
if (result != INVALID_FILE_ATTRIBUTES && !(result & FILE_ATTRIBUTE_DIRECTORY))
{
foundPixInstallation = true;
PIXERRORCHECK(StringCchCopyW(newestVersionFound, _countof(newestVersionFound), findData.cFileName));
PIXERRORCHECK(StringCchCopyW(output, _countof(possibleOutput), possibleOutput));
}
}
}
} while (PixImpl::FindNextFileW(hFind, &findData) != 0);
}
PixImpl::FindClose(hFind);
if (!foundPixInstallation)
{
SetLastError(ERROR_FILE_NOT_FOUND);
return nullptr;
}
return PixImpl::LoadLibraryExW(output, flags);
}
}
#undef PIXERRORCHECK
__forceinline HMODULE PIXLoadLatestWinPixGpuCapturerLibrary()
{
return PixImpl::PIXLoadLatestCapturerLibrary(
L"WinPixGpuCapturer.dll",
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
}
__forceinline HMODULE PIXLoadLatestWinPixTimingCapturerLibrary()
{
return PixImpl::PIXLoadLatestCapturerLibrary(
L"WinPixTimingCapturer.dll",
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
}
__forceinline HRESULT WINAPI PIXSetTargetWindow(HWND hwnd)
{
typedef void(WINAPI* SetGlobalTargetWindowFn)(HWND);
auto fn = (SetGlobalTargetWindowFn)PixImpl::GetGpuCaptureFunctionPtr("SetGlobalTargetWindow");
if (fn == nullptr)
{
return HRESULT_FROM_WIN32(GetLastError());
}
fn(hwnd);
return S_OK;
}
__forceinline HRESULT WINAPI PIXGpuCaptureNextFrames(PCWSTR fileName, UINT32 numFrames)
{
typedef HRESULT(WINAPI* CaptureNextFrameFn)(PCWSTR, UINT32);
auto fn = (CaptureNextFrameFn)PixImpl::GetGpuCaptureFunctionPtr("CaptureNextFrame");
if (fn == nullptr)
{
return HRESULT_FROM_WIN32(GetLastError());
}
return fn(fileName, numFrames);
}
extern "C" __forceinline HRESULT WINAPI PIXBeginCapture2(DWORD captureFlags, _In_opt_ const PPIXCaptureParameters captureParameters)
{
if (captureFlags == PIX_CAPTURE_GPU)
{
typedef HRESULT(WINAPI* BeginProgrammaticGpuCaptureFn)(const PPIXCaptureParameters);
auto fn = (BeginProgrammaticGpuCaptureFn)PixImpl::GetGpuCaptureFunctionPtr("BeginProgrammaticGpuCapture");
if (fn == nullptr)
{
return HRESULT_FROM_WIN32(GetLastError());
}
return fn(captureParameters);
}
else if (captureFlags == PIX_CAPTURE_TIMING)
{
typedef HRESULT(WINAPI* BeginProgrammaticTimingCaptureFn)(void const*, UINT64);
auto fn = (BeginProgrammaticTimingCaptureFn)PixImpl::GetTimingCaptureFunctionPtr("BeginProgrammaticTimingCapture");
if (fn == nullptr)
{
return HRESULT_FROM_WIN32(GetLastError());
}
return fn(&captureParameters->TimingCaptureParameters, sizeof(captureParameters->TimingCaptureParameters));
}
else
{
return E_NOTIMPL;
}
}
extern "C" __forceinline HRESULT WINAPI PIXEndCapture(BOOL discard)
{
// We can't tell if the user wants to end a GPU Capture or a Timing Capture.
// The user shouldn't have both WinPixGpuCapturer and WinPixTimingCapturer loaded in the process though,
// so we can just look for one of them and call it.
typedef HRESULT(WINAPI* EndProgrammaticGpuCaptureFn)(void);
auto gpuFn = (EndProgrammaticGpuCaptureFn)PixImpl::GetGpuCaptureFunctionPtr("EndProgrammaticGpuCapture");
if (gpuFn != NULL)
{
return gpuFn();
}
typedef HRESULT(WINAPI* EndProgrammaticTimingCaptureFn)(BOOL);
auto timingFn = (EndProgrammaticTimingCaptureFn)PixImpl::GetTimingCaptureFunctionPtr("EndProgrammaticTimingCapture");
if (timingFn != NULL)
{
return timingFn(discard);
}
return HRESULT_FROM_WIN32(GetLastError());
}
__forceinline HRESULT WINAPI PIXForceD3D11On12()
{
typedef HRESULT (WINAPI* ForceD3D11On12Fn)(void);
auto fn = (ForceD3D11On12Fn)PixImpl::GetGpuCaptureFunctionPtr("ForceD3D11On12");
if (fn == NULL)
{
return HRESULT_FROM_WIN32(GetLastError());
}
return fn();
}
__forceinline HRESULT WINAPI PIXSetHUDOptions(PIXHUDOptions hudOptions)
{
typedef HRESULT(WINAPI* SetHUDOptionsFn)(PIXHUDOptions);
auto fn = (SetHUDOptionsFn)PixImpl::GetGpuCaptureFunctionPtr("SetHUDOptions");
if (fn == NULL)
{
return HRESULT_FROM_WIN32(GetLastError());
}
return fn(hudOptions);
}
__forceinline bool WINAPI PIXIsAttachedForGpuCapture()
{
typedef bool(WINAPI* GetIsAttachedToPixFn)(void);
auto fn = (GetIsAttachedToPixFn)PixImpl::GetGpuCaptureFunctionPtr("GetIsAttachedToPix");
if (fn == NULL)
{
OutputDebugStringW(L"WinPixEventRuntime error: Mismatched header/dll. Please ensure that pix3.h and WinPixGpuCapturer.dll match");
return false;
}
return fn();
}
__forceinline HINSTANCE WINAPI PIXOpenCaptureInUI(PCWSTR fileName)
{
return ShellExecuteW(0, 0, fileName, 0, 0, SW_SHOW);
}
#else
__forceinline HMODULE PIXLoadLatestWinPixGpuCapturerLibrary()
{
return nullptr;
}
__forceinline HMODULE PIXLoadLatestWinPixTimingCapturerLibrary()
{
return nullptr;
}
__forceinline HRESULT WINAPI PIXSetTargetWindow(HWND)
{
return E_NOTIMPL;
}
__forceinline HRESULT WINAPI PIXGpuCaptureNextFrames(PCWSTR, UINT32)
{
return E_NOTIMPL;
}
extern "C" __forceinline HRESULT WINAPI PIXBeginCapture2(DWORD, _In_opt_ const PPIXCaptureParameters)
{
return E_NOTIMPL;
}
extern "C" __forceinline HRESULT WINAPI PIXEndCapture(BOOL)
{
return E_NOTIMPL;
}
__forceinline HRESULT WINAPI PIXForceD3D11On12()
{
return E_NOTIMPL;
}
__forceinline HRESULT WINAPI PIXSetHUDOptions(PIXHUDOptions)
{
return E_NOTIMPL;
}
__forceinline bool WINAPI PIXIsAttachedForGpuCapture()
{
return false;
}
__forceinline HINSTANCE WINAPI PIXOpenCaptureInUI(PCWSTR)
{
return 0;
}
#endif // WINAPI_PARTITION
#endif // USE_PIX_SUPPORTED_ARCHITECTURE || USE_PIX
#if defined(__d3d12_h__)
inline void PIXInsertTimingMarkerOnContextForBeginEvent(_In_ ID3D12GraphicsCommandList* commandList, UINT8 eventType, _In_reads_bytes_(size) void* data, UINT size)
{
UNREFERENCED_PARAMETER(eventType);
commandList->BeginEvent(WINPIX_EVENT_PIX3BLOB_V2, data, size);
}
inline void PIXInsertTimingMarkerOnContextForBeginEvent(_In_ ID3D12CommandQueue* commandQueue, UINT8 eventType, _In_reads_bytes_(size) void* data, UINT size)
{
UNREFERENCED_PARAMETER(eventType);
commandQueue->BeginEvent(WINPIX_EVENT_PIX3BLOB_V2, data, size);
}
inline void PIXInsertTimingMarkerOnContextForSetMarker(_In_ ID3D12GraphicsCommandList* commandList, UINT8 eventType, _In_reads_bytes_(size) void* data, UINT size)
{
UNREFERENCED_PARAMETER(eventType);
commandList->SetMarker(WINPIX_EVENT_PIX3BLOB_V2, data, size);
}
inline void PIXInsertTimingMarkerOnContextForSetMarker(_In_ ID3D12CommandQueue* commandQueue, UINT8 eventType, _In_reads_bytes_(size) void* data, UINT size)
{
UNREFERENCED_PARAMETER(eventType);
commandQueue->SetMarker(WINPIX_EVENT_PIX3BLOB_V2, data, size);
}
inline void PIXInsertTimingMarkerOnContextForEndEvent(_In_ ID3D12GraphicsCommandList* commandList, UINT8 eventType)
{
UNREFERENCED_PARAMETER(eventType);
commandList->EndEvent();
}
inline void PIXInsertTimingMarkerOnContextForEndEvent(_In_ ID3D12CommandQueue* commandQueue, UINT8 eventType)
{
UNREFERENCED_PARAMETER(eventType);
commandQueue->EndEvent();
}
inline void PIXInsertGPUMarkerOnContextForBeginEvent(_In_ ID3D12GraphicsCommandList* commandList, UINT8 eventType, _In_reads_bytes_(size) void* data, UINT size)
{
UNREFERENCED_PARAMETER(eventType);
commandList->BeginEvent(WINPIX_EVENT_PIX3BLOB_V2, data, size);
}
inline void PIXInsertGPUMarkerOnContextForBeginEvent(_In_ ID3D12CommandQueue* commandQueue, UINT8 eventType, _In_reads_bytes_(size) void* data, UINT size)
{
UNREFERENCED_PARAMETER(eventType);
commandQueue->BeginEvent(WINPIX_EVENT_PIX3BLOB_V2, data, size);
}
inline void PIXInsertGPUMarkerOnContextForSetMarker(_In_ ID3D12GraphicsCommandList* commandList, UINT8 eventType, _In_reads_bytes_(size) void* data, UINT size)
{
UNREFERENCED_PARAMETER(eventType);
commandList->SetMarker(WINPIX_EVENT_PIX3BLOB_V2, data, size);
}
inline void PIXInsertGPUMarkerOnContextForSetMarker(_In_ ID3D12CommandQueue* commandQueue, UINT8 eventType, _In_reads_bytes_(size) void* data, UINT size)
{
UNREFERENCED_PARAMETER(eventType);
commandQueue->SetMarker(WINPIX_EVENT_PIX3BLOB_V2, data, size);
}
inline void PIXInsertGPUMarkerOnContextForEndEvent(_In_ ID3D12GraphicsCommandList* commandList, UINT8, void*, UINT)
{
commandList->EndEvent();
}
inline void PIXInsertGPUMarkerOnContextForEndEvent(_In_ ID3D12CommandQueue* commandQueue, UINT8, void*, UINT)
{
commandQueue->EndEvent();
}
#endif
#endif //_PIX3_WIN_H_

View File

@@ -665,9 +665,9 @@ namespace bgfx { namespace d3d12
return &s_pixEventsThreadInfo;
}
uint64_t WINAPI stubPIXEventsReplaceBlock(bool _getEarliestTime)
uint64_t WINAPI stubPIXEventsReplaceBlock(PIXEventsThreadInfo* _threadInfo, bool _getEarliestTime)
{
BX_UNUSED(_getEarliestTime);
BX_UNUSED(_threadInfo, _getEarliestTime);
return 0;
}
#endif // BGFX_CONFIG_DEBUG_ANNOTATION && (BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT)

View File

@@ -50,7 +50,7 @@ extern "C++" {
#if BGFX_CONFIG_DEBUG_ANNOTATION && !BX_PLATFORM_LINUX
# if BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT
typedef struct PIXEventsThreadInfo* (WINAPI* PFN_PIX_GET_THREAD_INFO)();
typedef uint64_t (WINAPI* PFN_PIX_EVENTS_REPLACE_BLOCK)(bool _getEarliestTime);
typedef uint64_t (WINAPI* PFN_PIX_EVENTS_REPLACE_BLOCK)(PIXEventsThreadInfo* _threadInfo, bool _getEarliestTime);
extern PFN_PIX_GET_THREAD_INFO bgfx_PIXGetThreadInfo;
extern PFN_PIX_EVENTS_REPLACE_BLOCK bgfx_PIXEventsReplaceBlock;
@@ -59,7 +59,7 @@ extern PFN_PIX_EVENTS_REPLACE_BLOCK bgfx_PIXEventsReplaceBlock;
# define PIXEventsReplaceBlock bgfx_PIXEventsReplaceBlock
# else
extern "C" struct PIXEventsThreadInfo* WINAPI bgfx_PIXGetThreadInfo();
extern "C" uint64_t WINAPI bgfx_PIXEventsReplaceBlock(bool _getEarliestTime);
extern "C" uint64_t WINAPI bgfx_PIXEventsReplaceBlock(PIXEventsThreadInfo* _threadInfo, bool _getEarliestTime);
# endif // BX_PLATFORM_WINDOWS
# include <pix3.h>