Quake II RTX doxygen  1.0 dev
profiler.c
Go to the documentation of this file.
1 /*
2 Copyright (C) 2018 Christoph Schied
3 Copyright (C) 2019, NVIDIA CORPORATION. All rights reserved.
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 
20 #include "vkpt.h"
21 
22 static VkQueryPool query_pool;
24 
25 extern cvar_t *cvar_pt_reflect_refract;
26 
28 
29 VkResult
31 {
32  VkQueryPoolCreateInfo query_pool_info = {
33  .sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,
34  .queryType = VK_QUERY_TYPE_TIMESTAMP,
35  .queryCount = MAX_FRAMES_IN_FLIGHT * NUM_PROFILER_ENTRIES * 2,
36  };
37  vkCreateQueryPool(qvk.device, &query_pool_info, NULL, &query_pool);
38  return VK_SUCCESS;
39 }
40 
41 VkResult
43 {
44  vkDestroyQueryPool(qvk.device, query_pool, NULL);
45  return VK_SUCCESS;
46 }
47 
48 VkResult
49 vkpt_profiler_query(VkCommandBuffer cmd_buf, int idx, VKPTProfilerAction action)
50 {
51  idx = idx * 2 + action + qvk.current_frame_index * NUM_PROFILER_QUERIES_PER_FRAME;
52 
53  set_current_gpu(cmd_buf, 0);
54 
55  vkCmdWriteTimestamp(cmd_buf, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
56  query_pool, idx);
57 
58  set_current_gpu(cmd_buf, ALL_GPUS);
59 
60  profiler_queries_used[idx] = qtrue;
61 
62  return VK_SUCCESS;
63 }
64 
65 VkResult
66 vkpt_profiler_next_frame(VkCommandBuffer cmd_buf)
67 {
68  qboolean any_queries_used = qfalse;
69 
70  for (int idx = 0; idx < NUM_PROFILER_QUERIES_PER_FRAME; idx++)
71  {
73  {
74  any_queries_used = qtrue;
75  break;
76  }
77  }
78 
79  if (any_queries_used)
80  {
81  VkResult result = vkGetQueryPoolResults(qvk.device, query_pool,
84  sizeof(query_pool_results),
86  sizeof(query_pool_results[0]),
87  VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT);
88 
89  if (result != VK_SUCCESS && result != VK_NOT_READY)
90  {
91  Com_EPrintf("Failed call to vkGetQueryPoolResults, error code = %d\n", result);
92  any_queries_used = qfalse;
93  }
94  }
95 
96  if (any_queries_used)
97  {
98  for (int idx = 0; idx < NUM_PROFILER_QUERIES_PER_FRAME; idx++)
99  {
101  query_pool_results[idx] = 0;
102  }
103  }
104  else
105  {
106  memset(query_pool_results, 0, sizeof(query_pool_results));
107  }
108 
109  vkCmdResetQueryPool(cmd_buf, query_pool,
112 
114 
115  return VK_SUCCESS;
116 }
117 
118 static void
119 draw_query(int x, int y, qhandle_t font, const char *enum_name, int idx)
120 {
121  char buf[256];
122  int i;
123  for(i = 0; i < LENGTH(buf) - 1 && enum_name[i]; i++)
124  buf[i] = enum_name[i] == '_' ? ' ' : tolower(enum_name[i]);
125  buf[i] = 0;
126 
127  R_DrawString(x, y, 0, 128, buf, font);
128  double ms = vkpt_get_profiler_result(idx);
129  snprintf(buf, sizeof buf, "%8.2f ms", ms);
130  R_DrawString(x + 256, y, 0, 128, buf, font);
131 }
132 
133 void
134 draw_profiler(int enable_asvgf)
135 {
136  int x = 500;
137  int y = 100;
138 
139  qhandle_t font;
140  font = R_RegisterFont("conchars");
141  if(!font)
142  return;
143 
144 #define PROFILER_DO(name, indent) \
145  draw_query(x, y, font, #name + 9, name); y += 10;
146 
147  PROFILER_DO(PROFILER_FRAME_TIME, 0);
148  PROFILER_DO(PROFILER_INSTANCE_GEOMETRY, 1);
149  PROFILER_DO(PROFILER_BVH_UPDATE, 1);
150  PROFILER_DO(PROFILER_UPDATE_ENVIRONMENT, 1);
151  PROFILER_DO(PROFILER_SHADOW_MAP, 1);
152  PROFILER_DO(PROFILER_ASVGF_GRADIENT_SAMPLES, 1);
153  PROFILER_DO(PROFILER_ASVGF_DO_GRADIENT_SAMPLES, 2);
154  PROFILER_DO(PROFILER_PRIMARY_RAYS, 1);
155  if (cvar_pt_reflect_refract->integer > 0) { PROFILER_DO(PROFILER_REFLECT_REFRACT_1, 1); }
156  if (cvar_pt_reflect_refract->integer > 1) { PROFILER_DO(PROFILER_REFLECT_REFRACT_2, 1); }
157  PROFILER_DO(PROFILER_DIRECT_LIGHTING, 1);
158  PROFILER_DO(PROFILER_INDIRECT_LIGHTING, 1);
159  PROFILER_DO(PROFILER_GOD_RAYS, 1);
160  PROFILER_DO(PROFILER_GOD_RAYS_REFLECT_REFRACT, 1);
161  PROFILER_DO(PROFILER_GOD_RAYS_FILTER, 1);
162  if (enable_asvgf)
163  {
164  PROFILER_DO(PROFILER_ASVGF_FULL, 1);
165  PROFILER_DO(PROFILER_ASVGF_RECONSTRUCT_GRADIENT, 2);
166  PROFILER_DO(PROFILER_ASVGF_TEMPORAL, 2);
167  PROFILER_DO(PROFILER_ASVGF_ATROUS, 2);
168  PROFILER_DO(PROFILER_ASVGF_TAA, 2);
169  }
170  else
171  {
172  PROFILER_DO(PROFILER_COMPOSITING, 1);
173  }
174  if (qvk.device_count > 1) {
175  PROFILER_DO(PROFILER_MGPU_TRANSFERS, 1);
176  }
177  PROFILER_DO(PROFILER_INTERLEAVE, 1);
178  PROFILER_DO(PROFILER_BLOOM, 1);
179  PROFILER_DO(PROFILER_TONE_MAPPING, 2);
180 #undef PROFILER_DO
181 }
182 
184 {
185  double ms = (double)(query_pool_results[idx * 2 + 1] - query_pool_results[idx * 2 + 0]) * 1e-6;
186  return ms;
187 }
draw_profiler
void draw_profiler(int enable_asvgf)
Definition: profiler.c:134
VKPTProfilerAction
VKPTProfilerAction
Definition: vkpt.h:468
MAX_FRAMES_IN_FLIGHT
#define MAX_FRAMES_IN_FLIGHT
Definition: vkpt.h:140
QVK_s::device
VkDevice device
Definition: vkpt.h:172
vkpt_profiler_next_frame
VkResult vkpt_profiler_next_frame(VkCommandBuffer cmd_buf)
Definition: profiler.c:66
QVK_s::current_frame_index
uint32_t current_frame_index
Definition: vkpt.h:219
vkpt.h
NUM_PROFILER_QUERIES_PER_FRAME
#define NUM_PROFILER_QUERIES_PER_FRAME
Definition: vkpt.h:466
PROFILER_DO
#define PROFILER_DO(name, indent)
profiler_queries_used
static qboolean profiler_queries_used[NUM_PROFILER_QUERIES_PER_FRAME *2]
Definition: profiler.c:27
vkpt_profiler_destroy
VkResult vkpt_profiler_destroy()
Definition: profiler.c:42
vkpt_get_profiler_result
double vkpt_get_profiler_result(int idx)
Definition: profiler.c:183
R_DrawString
int(* R_DrawString)(int x, int y, int flags, size_t maxChars, const char *string, qhandle_t font)
Definition: refresh.c:417
set_current_gpu
void set_current_gpu(VkCommandBuffer cmd_buf, int gpu_index)
Definition: vk_util.c:426
draw_query
static void draw_query(int x, int y, qhandle_t font, const char *enum_name, int idx)
Definition: profiler.c:119
LENGTH
#define LENGTH(a)
Definition: tent.c:228
NUM_PROFILER_ENTRIES
@ NUM_PROFILER_ENTRIES
Definition: vkpt.h:463
cvar_pt_reflect_refract
cvar_t * cvar_pt_reflect_refract
qvk
QVK_t qvk
Definition: main.c:377
ALL_GPUS
#define ALL_GPUS
Definition: vkpt.h:535
vkpt_profiler_initialize
VkResult vkpt_profiler_initialize()
Definition: profiler.c:30
query_pool_results
static uint64_t query_pool_results[NUM_PROFILER_QUERIES_PER_FRAME+1]
Definition: profiler.c:23
query_pool
static VkQueryPool query_pool
Definition: profiler.c:22
vkpt_profiler_query
VkResult vkpt_profiler_query(VkCommandBuffer cmd_buf, int idx, VKPTProfilerAction action)
Definition: profiler.c:49
QVK_s::device_count
int device_count
Definition: vkpt.h:167