1 /**************************************************************************
3 * Copyright 2013-2014 RAD Game Tools and Valve Software
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 **************************************************************************/
26 // File: vogl_trace_stream_types.h
27 #ifndef VOGL_TRACE_STREAM_TYPES_H
28 #define VOGL_TRACE_STREAM_TYPES_H
29 #include "vogl_miniz.h"
31 #define VOGL_TRACE_FILE_VERSION 0x0106
32 #define VOGL_TRACE_FILE_MINIMUM_COMPATIBLE_VERSION 0x0106
34 #define VOGL_TRACE_LINK_PROGRAM_UNIFORM_DESC_KEY_OFS 0xF0000
37 enum vogl_trace_stream_packet_types_t
40 cTSPTGLEntrypoint = 3,
45 struct vogl_trace_stream_packet_base
49 cTracePacketPrefix = 0xD1C71602
52 uint32 m_size; // total size, including extra data, needed to get to next packet_base
53 uint32 m_crc; // CRC32 of all packet data following this member
57 cMinimumPossibleRnd = 1
59 uint16 m_rnd; // a random number, cannot be 0, must immediately follow m_crc!
61 uint64_t m_packet_begin_rdtsc;
62 uint64_t m_gl_begin_rdtsc;
63 uint64_t m_gl_end_rdtsc;
64 uint64_t m_packet_end_rdtsc;
66 uint8 m_type; // trace_packet_types_t
67 uint16 m_inv_rnd; // not of m_rnd, for verification (and to purpusely increase the packet entropy - this is only for devel)
69 inline void init(uint8 type, uint32 size)
71 memset(this, 0, sizeof(*this));
73 m_prefix = cTracePacketPrefix;
76 m_rnd = cMinimumPossibleRnd;
79 // Sets the rnd field using g_thread_safe_random
80 inline void init_rnd()
82 uint32 rnd16 = static_cast<uint16>(g_thread_safe_random.urand32());
83 m_rnd = static_cast<uint16>(math::maximum<uint>(vogl_trace_stream_packet_base::cMinimumPossibleRnd, rnd16));
87 // Assumes the *entire* packet is sequential in memory (i.e. m_size bytes starting at this)
88 inline void finalize()
92 VOGL_ASSERT(m_size >= sizeof(vogl_trace_stream_packet_base));
94 m_crc = (uint32)mz_crc32(MZ_CRC32_INIT, reinterpret_cast<const uint8 *>(this) + (uint32)VOGL_OFFSETOF(vogl_trace_stream_packet_base, m_rnd), m_size - (uint32)VOGL_OFFSETOF(vogl_trace_stream_packet_base, m_rnd));
97 inline bool basic_validation() const
99 if (m_prefix != cTracePacketPrefix)
102 if (m_type >= cTSPTTotalTypes)
105 if (m_size < sizeof(vogl_trace_stream_packet_base))
108 VOGL_ASSUME(sizeof(m_rnd) == sizeof(uint16));
109 uint inv_rnd = (~m_rnd) & 0xFFFFU;
111 if ((m_rnd < static_cast<uint>(cMinimumPossibleRnd)) || (inv_rnd != static_cast<uint>(m_inv_rnd)))
117 // Assumes the *entire* packet is sequential in memory (i.e. m_size bytes starting at this)
118 inline bool check_crc(uint actual_buf_size) const
120 if (m_size < sizeof(vogl_trace_stream_packet_base))
123 if (m_size > actual_buf_size)
126 uint32 check_crc = (uint32)mz_crc32(MZ_CRC32_INIT, reinterpret_cast<const uint8 *>(this) + (uint32)VOGL_OFFSETOF(vogl_trace_stream_packet_base, m_rnd), m_size - (uint32)VOGL_OFFSETOF(vogl_trace_stream_packet_base, m_rnd));
127 if (check_crc != m_crc)
133 // Assumes the *entire* packet is sequential in memory (i.e. m_size bytes starting at this)
134 inline bool full_validation(uint actual_buf_size) const
136 if (!basic_validation())
139 return check_crc(actual_buf_size);
143 struct vogl_trace_stream_start_of_file_packet
147 cSOFTracePacketPrefix = 0xD1C71601
150 uint64_t m_size; // The size of this packet (NOT including the archive data)
151 uint32 m_crc; // CRC32 of all packet data following this member
153 uint16 m_version; // must immediately follow m_crc!
154 uint8 m_pointer_sizes;
161 uint32 m_uuid[cUUIDSize];
163 uint64_t m_first_packet_offset;
165 // File offset and size of all ZIP archive data immediately following this packet, or 0 if there is no archive data.
166 uint64_t m_archive_offset;
167 uint64_t m_archive_size;
171 memset(this, 0, sizeof(*this));
172 m_size = sizeof(*this);
173 m_pointer_sizes = sizeof(void *);
174 m_version = VOGL_TRACE_FILE_VERSION;
177 uint32 compute_crc() const
179 return (uint32)mz_crc32(MZ_CRC32_INIT, reinterpret_cast<const uint8 *>(this) + (uint32)VOGL_OFFSETOF(vogl_trace_stream_start_of_file_packet, m_version), sizeof(*this) - (uint32)VOGL_OFFSETOF(vogl_trace_stream_start_of_file_packet, m_version));
182 inline void finalize()
184 m_prefix = cSOFTracePacketPrefix;
185 m_crc = compute_crc();
188 inline bool basic_validation() const
190 if (m_prefix != cSOFTracePacketPrefix)
193 if (m_size != sizeof(vogl_trace_stream_start_of_file_packet))
196 if (m_version < VOGL_TRACE_FILE_MINIMUM_COMPATIBLE_VERSION)
202 inline bool check_crc(uint actual_buf_size) const
204 if (m_size != sizeof(vogl_trace_stream_start_of_file_packet))
206 if (actual_buf_size < sizeof(vogl_trace_stream_start_of_file_packet))
209 uint32 check_crc = compute_crc();
210 if (check_crc != m_crc)
216 inline bool full_validation(uint actual_buf_size) const
218 if (!basic_validation())
220 return check_crc(actual_buf_size);
224 #define VOGL_RETURN_PARAM_INDEX 255
226 // GL entrypoint packets contain a fixed size struct vogl_trace_gl_entrypoint_packet, immediately
227 // followed by three variable sized data blobs:
229 // struct vogl_trace_gl_entrypoint_packet contains the base data in vogl_trace_stream_packet_base (total
230 // size of packet, crc of entire packet, various RDTSC's), and stuff like the entrypoint ID/context
231 // handle/kernel thread ID/call counter/etc.
233 // Immediately following this struct are up to three variable length blobs of data: The parameter
234 // data, any referenced client memory data, and an optional name value map.
235 struct vogl_trace_gl_entrypoint_packet : vogl_trace_stream_packet_base
237 uint16 m_entrypoint_id;
239 uint64_t m_context_handle;
240 uint64_t m_call_counter;
241 uint64_t m_thread_id;
244 uint32 m_client_memory_size;
246 uint32 m_backtrace_hash_index;
248 // The code that handles serialization is written assuming most packets will *not* use a name value map.
249 // Maps are intended to be rare events that are only included on expensive GL/GLX calls.
250 uint32 m_name_value_map_size;
254 vogl_trace_stream_packet_base::init(cTSPTGLEntrypoint, sizeof(*this));
259 enum vogl_internal_trace_command_rad_cmd_types_t
261 cITCRDemarcation = 0,
262 cITCRKeyValueMap = 1,
266 // TODO: Is this the best location for this?
267 struct vogl_backtrace_addrs
274 uintptr_t m_addrs[cMaxAddrs];
278 utils::zero_object(*this);
281 uint64_t get_hash() const
283 return vogl::calc_crc64(vogl::CRC64_INIT, reinterpret_cast<const uint8 *>(this), sizeof(uint32) + sizeof(m_addrs[0]) * m_num_addrs);
286 bool operator==(const vogl_backtrace_addrs &rhs) const
288 if (m_num_addrs != rhs.m_num_addrs)
290 return memcmp(m_addrs, rhs.m_addrs, m_num_addrs * sizeof(m_addrs[0])) == 0;
293 bool operator!=(const vogl_backtrace_addrs &rhs) const
295 return !(*this == rhs);
298 bool operator<(const vogl_backtrace_addrs &rhs) const
300 if (m_num_addrs < rhs.m_num_addrs)
302 else if (m_num_addrs == rhs.m_num_addrs)
304 for (uint i = 0; i < m_num_addrs; i++)
306 if (m_addrs[i] < rhs.m_addrs[i])
308 else if (m_addrs[i] > rhs.m_addrs[i])
318 return fast_hash(this, sizeof(uint32) + (m_num_addrs * sizeof(m_addrs[0])));
322 typedef vogl::hash_map<vogl_backtrace_addrs, uint64_t, intrusive_hasher<vogl_backtrace_addrs> > vogl_backtrace_hashmap;
324 #define VOGL_TRACE_ARCHIVE_FRAME_FILE_OFFSETS_FILENAME "frame_file_offsets"
326 #define VOGL_TRACE_ARCHIVE_COMPILER_INFO_FILENAME "compiler_info.json"
327 #define VOGL_TRACE_ARCHIVE_MACHINE_INFO_FILENAME "machine_info.json"
328 #define VOGL_TRACE_ARCHIVE_BACKTRACE_MAP_SYMS_FILENAME "backtrace_map_syms.json"
329 #define VOGL_TRACE_ARCHIVE_BACKTRACE_MAP_ADDRS_FILENAME "backtrace_map_addrs.json"
331 #endif // VOGL_TRACE_STREAM_TYPES_H