Quake II RTX doxygen  1.0 dev
path_tracer.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 "shared/shared.h"
21 #include "vkpt.h"
22 #include "vk_util.h"
23 #include "shader/vertex_buffer.h"
24 #include "../../client/client.h"
25 
26 #include <assert.h>
27 
28 #define RAY_GEN_ACCEL_STRUCTURE_BINDING_IDX 0
29 #define RAY_GEN_PARTICLE_COLOR_BUFFER_BINDING_IDX 1
30 #define RAY_GEN_BEAM_COLOR_BUFFER_BINDING_IDX 2
31 #define RAY_GEN_SPRITE_INFO_BUFFER_BINDING_IDX 3
32 
33 #define SIZE_SCRATCH_BUFFER (1 << 24)
34 
35 #define INSTANCE_MAX_NUM 12
36 
37 static VkPhysicalDeviceRayTracingPropertiesNV rt_properties = {
38  .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_NV,
39  .pNext = NULL,
40  .maxRecursionDepth = 0, /* updated during init */
41  .shaderGroupHandleSize = 0
42 };
43 
44 typedef struct accel_bottom_match_info_s {
45  VkGeometryFlagsNV flags;
46  uint32_t vertexCount;
47  uint32_t indexCount;
49 
50 typedef struct accel_top_match_info_s {
51  uint32_t instanceCount;
53 
55 static size_t scratch_buf_ptr = 0;
57 static VkAccelerationStructureNV accel_static;
58 static VkAccelerationStructureNV accel_transparent;
59 static VkAccelerationStructureNV accel_sky;
60 static VkAccelerationStructureNV accel_custom_sky;
62 static int sky_primitive_offset = 0;
69 static int explosions_present = 0;
70 static VkAccelerationStructureNV accel_dynamic [MAX_FRAMES_IN_FLIGHT];
72 static VkAccelerationStructureNV accel_transparent_models[MAX_FRAMES_IN_FLIGHT];
74 static VkAccelerationStructureNV accel_viewer_models[MAX_FRAMES_IN_FLIGHT];
76 static VkAccelerationStructureNV accel_viewer_weapon[MAX_FRAMES_IN_FLIGHT];
78 static VkAccelerationStructureNV accel_explosions[MAX_FRAMES_IN_FLIGHT];
80 static VkAccelerationStructureNV accel_top [MAX_FRAMES_IN_FLIGHT];
82 static VkDeviceMemory mem_accel_static;
83 static VkDeviceMemory mem_accel_transparent;
84 static VkDeviceMemory mem_accel_sky;
85 static VkDeviceMemory mem_accel_custom_sky;
86 static VkDeviceMemory mem_accel_top[MAX_FRAMES_IN_FLIGHT];
87 static VkDeviceMemory mem_accel_dynamic[MAX_FRAMES_IN_FLIGHT];
92 
94 
95 static VkDescriptorPool rt_descriptor_pool;
96 static VkDescriptorSet rt_descriptor_set[MAX_FRAMES_IN_FLIGHT];
97 static VkDescriptorSetLayout rt_descriptor_set_layout;
98 static VkPipelineLayout rt_pipeline_layout;
99 static VkPipeline rt_pipeline;
100 
102 cvar_t* cvar_pt_enable_beams = NULL;
103 cvar_t* cvar_pt_enable_sprites = NULL;
104 
105 extern cvar_t *cvar_pt_caustics;
106 extern cvar_t *cvar_pt_reflect_refract;
107 
108 
109 typedef struct QvkGeometryInstance_s {
110  float transform[12];
111  uint32_t instance_id : 24;
112  uint32_t mask : 8;
113  uint32_t instance_offset : 24;
114  uint32_t flags : 8;
117 
118 #define MEM_BARRIER_BUILD_ACCEL(cmd_buf, ...) \
119  do { \
120  VkMemoryBarrier mem_barrier = { \
121  .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, \
122  .srcAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NV \
123  | VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV, \
124  .dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV, \
125  __VA_ARGS__ \
126  }; \
127  \
128  vkCmdPipelineBarrier(cmd_buf, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV, \
129  VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_NV, 0, 1, \
130  &mem_barrier, 0, 0, 0, 0); \
131  } while(0)
132 
133 VkResult
135 {
136  VkPhysicalDeviceProperties2 dev_props2 = {
137  .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
138  .pNext = &rt_properties,
139  };
140 
141  vkGetPhysicalDeviceProperties2(qvk.physical_device, &dev_props2);
142 
143  Com_Printf("Maximum recursion depth: %d\n", rt_properties.maxRecursionDepth);
144  Com_Printf("Shader group handle size: %d\n", rt_properties.shaderGroupHandleSize);
145 
146  buffer_create(&buf_accel_scratch, SIZE_SCRATCH_BUFFER, VK_BUFFER_USAGE_RAY_TRACING_BIT_NV,
147  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
148 
149  for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
150  buffer_create(buf_instances + i, INSTANCE_MAX_NUM * sizeof(QvkGeometryInstance_t), VK_BUFFER_USAGE_RAY_TRACING_BIT_NV,
151  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
152  }
153 
154  /* create descriptor set layout */
155  VkDescriptorSetLayoutBinding bindings[] = {
156  {
158  .descriptorType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV,
159  .descriptorCount = 1,
160  .stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_NV,
161  },
162  {
164  .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
165  .descriptorCount = 1,
166  .stageFlags = VK_SHADER_STAGE_ANY_HIT_BIT_NV,
167  },
168  {
170  .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
171  .descriptorCount = 1,
172  .stageFlags = VK_SHADER_STAGE_ANY_HIT_BIT_NV,
173  },
174  {
176  .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
177  .descriptorCount = 1,
178  .stageFlags = VK_SHADER_STAGE_ANY_HIT_BIT_NV,
179  },
180  };
181 
182  VkDescriptorSetLayoutCreateInfo layout_info = {
183  .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
184  .bindingCount = LENGTH(bindings),
185  .pBindings = bindings
186  };
187  _VK(vkCreateDescriptorSetLayout(qvk.device, &layout_info, NULL, &rt_descriptor_set_layout));
188  ATTACH_LABEL_VARIABLE(rt_descriptor_set_layout, DESCRIPTOR_SET_LAYOUT);
189 
190 
191  VkDescriptorSetLayout desc_set_layouts[] = {
196  };
197 
198  /* create pipeline */
199  VkPushConstantRange push_constant_range = {
200  .stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_NV,
201  .offset = 0,
202  .size = sizeof(int) * 2,
203  };
204 
205  VkPipelineLayoutCreateInfo pipeline_layout_create_info = {
206  .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
207  .setLayoutCount = LENGTH(desc_set_layouts),
208  .pSetLayouts = desc_set_layouts,
209  .pushConstantRangeCount = 1,
210  .pPushConstantRanges = &push_constant_range,
211  };
212 
213  _VK(vkCreatePipelineLayout(qvk.device, &pipeline_layout_create_info, NULL, &rt_pipeline_layout));
214  ATTACH_LABEL_VARIABLE(rt_pipeline_layout, PIPELINE_LAYOUT);
215 
216  VkDescriptorPoolSize pool_sizes[] = {
217  { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, MAX_FRAMES_IN_FLIGHT },
218  { VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV, MAX_FRAMES_IN_FLIGHT }
219  };
220 
221  VkDescriptorPoolCreateInfo pool_create_info = {
222  .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
223  .maxSets = MAX_FRAMES_IN_FLIGHT,
224  .poolSizeCount = LENGTH(pool_sizes),
225  .pPoolSizes = pool_sizes
226  };
227 
228  _VK(vkCreateDescriptorPool(qvk.device, &pool_create_info, NULL, &rt_descriptor_pool));
229  ATTACH_LABEL_VARIABLE(rt_descriptor_pool, DESCRIPTOR_POOL);
230 
231  VkDescriptorSetAllocateInfo descriptor_set_alloc_info = {
232  .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
233  .descriptorPool = rt_descriptor_pool,
234  .descriptorSetCount = 1,
235  .pSetLayouts = &rt_descriptor_set_layout,
236  };
237 
238  for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
239  _VK(vkAllocateDescriptorSets(qvk.device, &descriptor_set_alloc_info, rt_descriptor_set + i));
240  ATTACH_LABEL_VARIABLE(rt_descriptor_set[i], DESCRIPTOR_SET);
241  }
242 
243  cvar_pt_enable_particles = Cvar_Get("pt_enable_particles", "1", 0);
244  cvar_pt_enable_beams = Cvar_Get("pt_enable_beams", "1", 0);
245  cvar_pt_enable_sprites= Cvar_Get("pt_enable_sprites", "1", 0);
246 
247  return VK_SUCCESS;
248 }
249 
250 VkResult
252 {
253  /* update descriptor set bindings */
254  VkWriteDescriptorSetAccelerationStructureNV desc_accel_struct_info = {
255  .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_NV,
256  .accelerationStructureCount = 1,
257  .pAccelerationStructures = accel_top + idx
258  };
259 
263 
264  VkWriteDescriptorSet writes[] = {
265  {
266  .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
267  .pNext = &desc_accel_struct_info,
268  .dstSet = rt_descriptor_set[idx],
270  .descriptorCount = 1,
271  .descriptorType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV
272  },
273  {
274  .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
275  .dstSet = rt_descriptor_set[idx],
277  .descriptorCount = 1,
278  .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
279  .pTexelBufferView = &particle_color_buffer_view
280  },
281  {
282  .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
283  .dstSet = rt_descriptor_set[idx],
285  .descriptorCount = 1,
286  .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
287  .pTexelBufferView = &beam_color_buffer_view
288  },
289  {
290  .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
291  .dstSet = rt_descriptor_set[idx],
293  .descriptorCount = 1,
294  .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
295  .pTexelBufferView = &sprite_info_buffer_view
296  },
297  };
298 
299  vkUpdateDescriptorSets(qvk.device, LENGTH(writes), writes, 0, NULL);
300 
301  return VK_SUCCESS;
302 }
303 
304 
305 static size_t
306 get_scratch_buffer_size(VkAccelerationStructureNV ac)
307 {
308  VkAccelerationStructureMemoryRequirementsInfoNV mem_req_info = {
309  .sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV,
310  .accelerationStructure = ac,
311  .type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV
312  };
313 
314  VkMemoryRequirements2 mem_req = { 0 };
315  mem_req.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
316  qvkGetAccelerationStructureMemoryRequirementsNV(qvk.device, &mem_req_info, &mem_req);
317 
318  return mem_req.memoryRequirements.size;
319 }
320 
321 static inline VkGeometryNV
322 get_geometry(VkBuffer buffer, size_t offset, uint32_t num_vertices)
323 {
324  size_t size_per_vertex = sizeof(float) * 3;
325  VkGeometryNV geometry = {
326  .sType = VK_STRUCTURE_TYPE_GEOMETRY_NV,
327  .geometry = {
328  .triangles = {
329  .sType = VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV,
330  .vertexData = buffer,
331  .vertexOffset = offset,
332  .vertexCount = num_vertices,
333  .vertexStride = size_per_vertex,
334  .vertexFormat = VK_FORMAT_R32G32B32_SFLOAT,
335  .indexType = VK_INDEX_TYPE_NONE_NV,
336  .indexCount = num_vertices, /* idiotic, doesn't work without */
337  },
338  .aabbs = { .sType = VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV }
339  }
340  };
341  return geometry;
342 }
343 
344 VkResult
346 {
347  if(mem_accel_static) {
348  vkFreeMemory(qvk.device, mem_accel_static, NULL);
349  mem_accel_static = VK_NULL_HANDLE;
350  }
351  if (mem_accel_transparent) {
352  vkFreeMemory(qvk.device, mem_accel_transparent, NULL);
353  mem_accel_transparent = VK_NULL_HANDLE;
354  }
355  if (mem_accel_sky) {
356  vkFreeMemory(qvk.device, mem_accel_sky, NULL);
357  mem_accel_sky = VK_NULL_HANDLE;
358  }
359  if (mem_accel_custom_sky) {
360  vkFreeMemory(qvk.device, mem_accel_custom_sky, NULL);
361  mem_accel_custom_sky = VK_NULL_HANDLE;
362  }
363  if(accel_static) {
364  qvkDestroyAccelerationStructureNV(qvk.device, accel_static, NULL);
365  accel_static = VK_NULL_HANDLE;
366  }
367  if (accel_transparent) {
368  qvkDestroyAccelerationStructureNV(qvk.device, accel_transparent, NULL);
369  accel_transparent = VK_NULL_HANDLE;
370  }
371  if (accel_sky) {
372  qvkDestroyAccelerationStructureNV(qvk.device, accel_sky, NULL);
373  accel_sky = VK_NULL_HANDLE;
374  }
375  if (accel_custom_sky) {
376  qvkDestroyAccelerationStructureNV(qvk.device, accel_custom_sky, NULL);
377  accel_custom_sky = VK_NULL_HANDLE;
378  }
379  return VK_SUCCESS;
380 }
381 
382 VkResult
384 {
385  if(mem_accel_dynamic[idx]) {
386  vkFreeMemory(qvk.device, mem_accel_dynamic[idx], NULL);
387  mem_accel_dynamic[idx] = VK_NULL_HANDLE;
388  }
389  if(accel_dynamic[idx]) {
390  qvkDestroyAccelerationStructureNV(qvk.device, accel_dynamic[idx], NULL);
391  accel_dynamic[idx] = VK_NULL_HANDLE;
392  }
393  return VK_SUCCESS;
394 }
395 
396 VkResult
398 {
399  if (mem_accel_transparent_models[idx]) {
400  vkFreeMemory(qvk.device, mem_accel_transparent_models[idx], NULL);
401  mem_accel_transparent_models[idx] = VK_NULL_HANDLE;
402  }
403  if (accel_transparent_models[idx]) {
404  qvkDestroyAccelerationStructureNV(qvk.device, accel_transparent_models[idx], NULL);
405  accel_transparent_models[idx] = VK_NULL_HANDLE;
406  }
407  return VK_SUCCESS;
408 }
409 
410 VkResult
412 {
413  if(mem_accel_viewer_models[idx]) {
414  vkFreeMemory(qvk.device, mem_accel_viewer_models[idx], NULL);
415  mem_accel_viewer_models[idx] = VK_NULL_HANDLE;
416  }
417  if(accel_viewer_models[idx]) {
418  qvkDestroyAccelerationStructureNV(qvk.device, accel_viewer_models[idx], NULL);
419  accel_viewer_models[idx] = VK_NULL_HANDLE;
420  }
421  return VK_SUCCESS;
422 }
423 
424 VkResult
426 {
427  if(mem_accel_viewer_weapon[idx]) {
428  vkFreeMemory(qvk.device, mem_accel_viewer_weapon[idx], NULL);
429  mem_accel_viewer_weapon[idx] = VK_NULL_HANDLE;
430  }
431  if(accel_viewer_weapon[idx]) {
432  qvkDestroyAccelerationStructureNV(qvk.device, accel_viewer_weapon[idx], NULL);
433  accel_viewer_weapon[idx] = VK_NULL_HANDLE;
434  }
435  return VK_SUCCESS;
436 }
437 
438 VkResult
440 {
441  if (mem_accel_explosions[idx]) {
442  vkFreeMemory(qvk.device, mem_accel_explosions[idx], NULL);
443  mem_accel_explosions[idx] = VK_NULL_HANDLE;
444  }
445  if (accel_explosions[idx]) {
446  qvkDestroyAccelerationStructureNV(qvk.device, accel_explosions[idx], NULL);
447  accel_explosions[idx] = VK_NULL_HANDLE;
448  }
449  return VK_SUCCESS;
450 }
451 
453  VkGeometryNV *geometry) {
454  return match->flags == geometry->flags &&
455  match->vertexCount >= geometry->geometry.triangles.vertexCount &&
456  match->indexCount >= geometry->geometry.triangles.indexCount;
457 }
458 
459 // How much to bloat the dynamic geometry allocations
460 // to try to avoid later allocations.
461 #define DYNAMIC_GEOMETRY_BLOAT_FACTOR 2
462 
463 static VkResult
465  VkBuffer vertex_buffer,
466  size_t buffer_offset,
467  int num_vertices,
468  VkAccelerationStructureNV *accel,
470  VkDeviceMemory *mem_accel,
471  VkCommandBuffer cmd_buf,
472  int fast_build
473  )
474 {
475  assert(accel);
476  assert(mem_accel);
477 
478  VkGeometryNV geometry = get_geometry(vertex_buffer, buffer_offset, num_vertices);
479 
480  int doFree = 0;
481  int doAlloc = 0;
482 
483  if (!match || !accel_matches(match, &geometry) || *accel == VK_NULL_HANDLE) {
484  doAlloc = 1;
485  doFree = (*accel != VK_NULL_HANDLE);
486  }
487 
488  if (doFree) {
489  if (*mem_accel) {
490  vkFreeMemory(qvk.device, *mem_accel, NULL);
491  *mem_accel = VK_NULL_HANDLE;
492  }
493  if (*accel) {
494  qvkDestroyAccelerationStructureNV(qvk.device, *accel, NULL);
495  *accel = VK_NULL_HANDLE;
496  }
497  }
498 
499  if (doAlloc) {
500  VkGeometryNV allocGeometry = geometry;
501 
502  // Only dynamic geometries have match info
503  if (match) {
504  allocGeometry.geometry.triangles.indexCount *= DYNAMIC_GEOMETRY_BLOAT_FACTOR;
505  allocGeometry.geometry.triangles.vertexCount *= DYNAMIC_GEOMETRY_BLOAT_FACTOR;
506  }
507 
508  VkAccelerationStructureCreateInfoNV accel_create_info = {
509  .sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV,
510  .info = {
511  .sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV,
512  .instanceCount = 0,
513  .geometryCount = 1,
514  .pGeometries = &allocGeometry,
515  .type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV,
516  .flags = fast_build ? VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_NV : VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_NV
517  }
518  };
519 
520  qvkCreateAccelerationStructureNV(qvk.device, &accel_create_info, NULL, accel);
521 
522  VkAccelerationStructureMemoryRequirementsInfoNV mem_req_info = {
523  .sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV,
524  .accelerationStructure = *accel,
525  .type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV
526  };
527  VkMemoryRequirements2 mem_req = { 0 };
528  mem_req.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
529  qvkGetAccelerationStructureMemoryRequirementsNV(qvk.device, &mem_req_info, &mem_req);
530 
531  _VK(allocate_gpu_memory(mem_req.memoryRequirements, mem_accel));
532 
533  VkBindAccelerationStructureMemoryInfoNV bind_info = {
534  .sType = VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NV,
535  .accelerationStructure = *accel,
536  .memory = *mem_accel,
537  };
538 
539  _VK(qvkBindAccelerationStructureMemoryNV(qvk.device, 1, &bind_info));
540 
541  if (match) {
542  match->flags = allocGeometry.flags;
543  match->vertexCount = allocGeometry.geometry.triangles.vertexCount;
544  match->indexCount = allocGeometry.geometry.triangles.indexCount;
545  }
546  }
547 
548  size_t scratch_buf_size = get_scratch_buffer_size(*accel);
549  assert(scratch_buf_ptr + scratch_buf_size < SIZE_SCRATCH_BUFFER);
550 
551  VkAccelerationStructureInfoNV as_info = {
552  .sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV,
553  .type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV,
554  .geometryCount = 1,
555  .pGeometries = &geometry,
556  .flags = fast_build ? VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_NV : VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_NV
557  };
558 
559  qvkCmdBuildAccelerationStructureNV(cmd_buf, &as_info,
560  VK_NULL_HANDLE, /* instance buffer */
561  0 /* instance offset */,
562  VK_FALSE, /* update */
563  *accel,
564  VK_NULL_HANDLE, /* source acceleration structure ?? */
567 
568  scratch_buf_ptr += scratch_buf_size;
569 
570  return VK_SUCCESS;
571 }
572 
573 VkResult
575  VkBuffer vertex_buffer,
576  size_t buffer_offset,
577  int num_vertices,
578  int num_vertices_transparent,
579  int num_vertices_sky,
580  int num_vertices_custom_sky
581  )
582 {
583  VkCommandBuffer cmd_buf = vkpt_begin_command_buffer(&qvk.cmd_buffers_graphics);
584 
585  scratch_buf_ptr = 0;
586 
587  VkResult ret = vkpt_pt_create_accel_bottom(
589  buffer_offset,
590  num_vertices,
591  &accel_static,
592  NULL,
594  cmd_buf,
595  VK_FALSE);
596 
597  MEM_BARRIER_BUILD_ACCEL(cmd_buf);
598  scratch_buf_ptr = 0;
599 
602  buffer_offset + num_vertices * sizeof(float) * 3,
603  num_vertices_transparent,
605  NULL,
607  cmd_buf,
608  VK_FALSE);
609 
610  MEM_BARRIER_BUILD_ACCEL(cmd_buf);
611  scratch_buf_ptr = 0;
612 
615  buffer_offset + (num_vertices + num_vertices_transparent) * sizeof(float) * 3,
616  num_vertices_sky,
617  &accel_sky,
618  NULL,
619  &mem_accel_sky,
620  cmd_buf,
621  VK_FALSE);
622 
623  MEM_BARRIER_BUILD_ACCEL(cmd_buf);
624  scratch_buf_ptr = 0;
625 
628  buffer_offset + (num_vertices + num_vertices_transparent + num_vertices_sky) * sizeof(float) * 3,
629  num_vertices_custom_sky,
631  NULL,
633  cmd_buf,
634  VK_FALSE);
635 
636  MEM_BARRIER_BUILD_ACCEL(cmd_buf);
637  scratch_buf_ptr = 0;
638 
639  transparent_primitive_offset = num_vertices / 3;
640  sky_primitive_offset = transparent_primitive_offset + num_vertices_transparent / 3;
641  custom_sky_primitive_offset = sky_primitive_offset + num_vertices_sky / 3;
642 
645 
646  return ret;
647 }
648 
649 static VkResult
651  VkCommandBuffer cmd_buf,
652  int idx,
653  VkBuffer vertex_buffer,
654  size_t buffer_offset,
655  int num_vertices
656  )
657 {
660  buffer_offset,
661  num_vertices,
662  accel_dynamic + idx,
663  accel_dynamic_match + idx,
664  mem_accel_dynamic + idx,
665  cmd_buf,
666  VK_TRUE);
667 }
668 
669 static VkResult
671  VkCommandBuffer cmd_buf,
672  int idx,
673  VkBuffer vertex_buffer,
674  size_t buffer_offset,
675  int num_vertices,
676  int vertex_offset
677  )
678 {
679  transparent_model_primitive_offset = vertex_offset / 3;
680 
681  if (num_vertices > 0)
682  {
683  transparent_models_present = VK_TRUE;
684 
687  buffer_offset + vertex_offset * 3 * sizeof(float),
688  num_vertices,
692  cmd_buf,
693  VK_TRUE);
694  }
695  else
696  {
697  transparent_models_present = VK_FALSE;
698  return VK_SUCCESS;
699  }
700 }
701 
702 static VkResult
704  VkCommandBuffer cmd_buf,
705  int idx,
706  VkBuffer vertex_buffer,
707  size_t buffer_offset,
708  int num_vertices,
709  int vertex_offset
710  )
711 {
712  viewer_model_primitive_offset = vertex_offset / 3;
713 
716  buffer_offset + vertex_offset * 3 * sizeof(float),
717  num_vertices,
718  accel_viewer_models + idx,
721  cmd_buf,
722  VK_TRUE);
723 }
724 
725 static VkResult
727  VkCommandBuffer cmd_buf,
728  int idx,
729  VkBuffer vertex_buffer,
730  size_t buffer_offset,
731  int num_vertices,
732  int vertex_offset
733  )
734 {
735  viewer_weapon_primitive_offset = vertex_offset / 3;
736 
739  buffer_offset + vertex_offset * 3 * sizeof(float),
740  num_vertices,
741  accel_viewer_weapon + idx,
744  cmd_buf,
745  VK_TRUE);
746 }
747 
748 static VkResult
750  VkCommandBuffer cmd_buf,
751  int idx,
752  VkBuffer vertex_buffer,
753  size_t buffer_offset,
754  int num_vertices,
755  int vertex_offset
756 )
757 {
758  if (num_vertices > 0)
759  {
760  explosions_primitive_offset = vertex_offset / 3;
761  explosions_present = VK_TRUE;
762 
765  buffer_offset + vertex_offset * 3 * sizeof(float),
766  num_vertices,
767  accel_explosions + idx,
769  mem_accel_explosions + idx,
770  cmd_buf,
771  VK_TRUE);
772  }
773  else
774  {
775  explosions_present = VK_FALSE;
776  return VK_SUCCESS;
777  }
778 }
779 
780 VkResult
782  VkCommandBuffer cmd_buf,
783  int idx,
784  VkBuffer vertex_buffer,
785  const EntityUploadInfo* upload_info)
786 {
787  scratch_buf_ptr = 0;
788 
790  offsetof(VertexBuffer, positions_instanced), upload_info->dynamic_vertex_num);
791 
793  offsetof(VertexBuffer, positions_instanced), upload_info->transparent_model_vertex_num,
794  upload_info->transparent_model_vertex_offset);
795 
797  offsetof(VertexBuffer, positions_instanced), upload_info->viewer_model_vertex_num,
798  upload_info->viewer_model_vertex_offset);
799 
801  offsetof(VertexBuffer, positions_instanced), upload_info->viewer_weapon_vertex_num,
802  upload_info->viewer_weapon_vertex_offset);
803 
805  offsetof(VertexBuffer, positions_instanced), upload_info->explosions_vertex_num,
806  upload_info->explosions_vertex_offset);
807 
808  MEM_BARRIER_BUILD_ACCEL(cmd_buf);
809  scratch_buf_ptr = 0;
810 
811  return VK_SUCCESS;
812 }
813 
814 void
816 {
817  if(accel_top[idx]) {
818  qvkDestroyAccelerationStructureNV(qvk.device, accel_top[idx], NULL);
819  accel_top[idx] = VK_NULL_HANDLE;
821  }
822  if(mem_accel_top[idx]) {
823  vkFreeMemory(qvk.device, mem_accel_top[idx], NULL);
824  mem_accel_top[idx] = VK_NULL_HANDLE;
825  }
826 }
827 
828 static void
829 append_blas(QvkGeometryInstance_t *instances, int *num_instances, VkAccelerationStructureNV blas, int instance_id, int mask, int flags, int sbt_offset)
830 {
831  QvkGeometryInstance_t instance = {
832  .transform = {
833  1.0f, 0.0f, 0.0f, 0.0f,
834  0.0f, 1.0f, 0.0f, 0.0f,
835  0.0f, 0.0f, 1.0f, 0.0f,
836  },
837  .instance_id = instance_id,
838  .mask = mask,
839  .instance_offset = sbt_offset,
840  .flags = flags,
841  .acceleration_structure_handle = 1337, // will be overwritten
842  };
843 
844  _VK(qvkGetAccelerationStructureHandleNV(qvk.device, blas, sizeof(uint64_t), &instance.acceleration_structure_handle));
845 
846  assert(*num_instances < INSTANCE_MAX_NUM);
847  memcpy(instances + *num_instances, &instance, sizeof(instance));
848  ++*num_instances;
849 }
850 
851 VkResult
852 vkpt_pt_create_toplevel(VkCommandBuffer cmd_buf, int idx, qboolean include_world, qboolean weapon_left_handed)
853 {
855  int num_instances = 0;
856 
857  if (include_world)
858  {
859  append_blas(instances, &num_instances, accel_static, 0, AS_FLAG_OPAQUE, 0, 0);
861  append_blas(instances, &num_instances, accel_sky, AS_INSTANCE_FLAG_SKY | sky_primitive_offset, AS_FLAG_SKY, 0, 0);
863  }
864  append_blas(instances, &num_instances, accel_dynamic[idx], AS_INSTANCE_FLAG_DYNAMIC, AS_FLAG_OPAQUE, 0, 0);
865 
867  {
869  }
870 
872  {
873  append_blas(instances, &num_instances, accel_viewer_models[idx], AS_INSTANCE_FLAG_DYNAMIC | viewer_model_primitive_offset, AS_FLAG_VIEWER_MODELS, VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV, 0);
874  append_blas(instances, &num_instances, accel_viewer_weapon[idx], AS_INSTANCE_FLAG_DYNAMIC | viewer_weapon_primitive_offset, AS_FLAG_VIEWER_WEAPON, weapon_left_handed ? VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_NV : 0, 0);
875  }
876 
879 
880  if (cvar_pt_enable_particles->integer != 0 && particle_num > 0)
881  {
882  append_blas(instances, &num_instances, get_transparency_particle_blas(), 0, AS_FLAG_PARTICLES, VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV, 1);
883  }
884 
885  if (cvar_pt_enable_beams->integer != 0 && beam_num > 0)
886  {
887  append_blas(instances, &num_instances, get_transparency_beam_blas(), 0, AS_FLAG_PARTICLES, VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV, 2);
888  }
889 
890  if (cvar_pt_enable_sprites->integer != 0 && sprite_num > 0)
891  {
892  append_blas(instances, &num_instances, get_transparency_sprite_blas(), 0, AS_FLAG_EXPLOSIONS, VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV, 4);
893  }
894 
896  {
898  }
899 
900  void *instance_data = buffer_map(buf_instances + idx);
901  memcpy(instance_data, &instances, sizeof(QvkGeometryInstance_t) * num_instances);
902 
904  instance_data = NULL;
905 
906  VkAccelerationStructureCreateInfoNV accel_create_info = {
907  .sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV,
908  .info = {
909  .sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV,
910  .instanceCount = num_instances,
911  .geometryCount = 0,
912  .pGeometries = NULL,
913  .type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV
914  }
915  };
916 
917  if (accel_top_match[idx].instanceCount < accel_create_info.info.instanceCount) {
919 
920  qvkCreateAccelerationStructureNV(qvk.device, &accel_create_info, NULL, accel_top + idx);
921 
922  /* XXX: do allocation only once with safety margin */
923  VkAccelerationStructureMemoryRequirementsInfoNV mem_req_info = {
924  .sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV,
925  .accelerationStructure = accel_top[idx],
926  .type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV
927  };
928  VkMemoryRequirements2 mem_req = { 0 };
929  mem_req.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
930  qvkGetAccelerationStructureMemoryRequirementsNV(qvk.device, &mem_req_info, &mem_req);
931 
932  _VK(allocate_gpu_memory(mem_req.memoryRequirements, mem_accel_top + idx));
933 
934  VkBindAccelerationStructureMemoryInfoNV bind_info = {
935  .sType = VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NV,
936  .accelerationStructure = accel_top[idx],
937  .memory = mem_accel_top[idx],
938  };
939 
940  _VK(qvkBindAccelerationStructureMemoryNV(qvk.device, 1, &bind_info));
941 
943 
944  accel_top_match[idx].instanceCount = accel_create_info.info.instanceCount;
945  }
946 
947  VkAccelerationStructureInfoNV as_info = {
948  .sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV,
949  .type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV,
950  .geometryCount = 0,
951  .pGeometries = NULL,
952  .instanceCount = num_instances,
953  };
954 
955  qvkCmdBuildAccelerationStructureNV(
956  cmd_buf,
957  &as_info,
958  buf_instances[idx].buffer, /* instance buffer */
959  0 /* instance offset */,
960  VK_FALSE, /* update */
961  accel_top[idx],
962  VK_NULL_HANDLE, /* source acceleration structure ?? */
964  0 /* scratch offset */);
965 
966  MEM_BARRIER_BUILD_ACCEL(cmd_buf); /* probably not needed here but doesn't matter */
967 
968  return VK_SUCCESS;
969 }
970 
971 #define BARRIER_COMPUTE(cmd_buf, img) \
972  do { \
973  VkImageSubresourceRange subresource_range = { \
974  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, \
975  .baseMipLevel = 0, \
976  .levelCount = 1, \
977  .baseArrayLayer = 0, \
978  .layerCount = 1 \
979  }; \
980  IMAGE_BARRIER(cmd_buf, \
981  .image = img, \
982  .subresourceRange = subresource_range, \
983  .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, \
984  .dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT, \
985  .oldLayout = VK_IMAGE_LAYOUT_GENERAL, \
986  .newLayout = VK_IMAGE_LAYOUT_GENERAL, \
987  ); \
988  } while(0)
989 
990 static void setup_rt_pipeline(VkCommandBuffer cmd_buf)
991 {
992  vkCmdBindDescriptorSets(cmd_buf, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV,
994 
995  vkCmdBindDescriptorSets(cmd_buf, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV,
996  rt_pipeline_layout, 1, 1, &qvk.desc_set_ubo, 0, 0);
997 
998  VkDescriptorSet desc_set_textures = qvk_get_current_desc_set_textures();
999  vkCmdBindDescriptorSets(cmd_buf, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV,
1000  rt_pipeline_layout, 2, 1, &desc_set_textures, 0, 0);
1001 
1002  vkCmdBindDescriptorSets(cmd_buf, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV,
1004 
1005  vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, rt_pipeline);
1006 }
1007 
1008 VkResult
1009 vkpt_pt_trace_primary_rays(VkCommandBuffer cmd_buf)
1010 {
1011  int frame_idx = qvk.frame_counter & 1;
1012 
1013  BUFFER_BARRIER(cmd_buf,
1014  .srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
1015  .dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
1016  .buffer = qvk.buf_readback.buffer,
1017  .offset = 0,
1018  .size = VK_WHOLE_SIZE,
1019  );
1020 
1021  setup_rt_pipeline(cmd_buf);
1022 
1023  BEGIN_PERF_MARKER(cmd_buf, PROFILER_PRIMARY_RAYS);
1024 
1025  for(int i = 0; i < qvk.device_count; i++)
1026  {
1027  set_current_gpu(cmd_buf, i);
1028 
1029  int idx = qvk.device_count == 1 ? -1 : i;
1030  vkCmdPushConstants(cmd_buf, rt_pipeline_layout, VK_SHADER_STAGE_RAYGEN_BIT_NV, 0, sizeof(int), &idx);
1031 
1032  qvkCmdTraceRaysNV(cmd_buf,
1034  buf_shader_binding_table.buffer, 0, rt_properties.shaderGroupHandleSize,
1035  buf_shader_binding_table.buffer, 0, rt_properties.shaderGroupHandleSize,
1036  VK_NULL_HANDLE, 0, 0,
1037  qvk.extent_render.width / 2, qvk.extent_render.height, qvk.device_count == 1 ? 2 : 1);
1038  }
1039 
1040  set_current_gpu(cmd_buf, ALL_GPUS);
1041 
1042  END_PERF_MARKER(cmd_buf, PROFILER_PRIMARY_RAYS);
1043 
1044  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_VISBUF]);
1045  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_TRANSPARENT]);
1046  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_TEX_GRADIENTS]);
1047  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_MOTION]);
1048  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_SHADING_POSITION]);
1049  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_VIEW_DIRECTION]);
1050  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_THROUGHPUT]);
1051  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_BOUNCE_THROUGHPUT]);
1052  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_GODRAYS_THROUGHPUT_DIST]);
1053  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_ALBEDO]);
1054  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_METALLIC]);
1055  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_CLUSTER]);
1056  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_VIEW_DEPTH_A + frame_idx]);
1057  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_NORMAL_A + frame_idx]);
1058 
1059  return VK_SUCCESS;
1060 }
1061 
1062 VkResult
1063 vkpt_pt_trace_reflections(VkCommandBuffer cmd_buf, int bounce)
1064 {
1065  int frame_idx = qvk.frame_counter & 1;
1066 
1067  setup_rt_pipeline(cmd_buf);
1068 
1069  for (int i = 0; i < qvk.device_count; i++)
1070  {
1071  set_current_gpu(cmd_buf, i);
1072 
1073  int idx = qvk.device_count == 1 ? -1 : i;
1074  vkCmdPushConstants(cmd_buf, rt_pipeline_layout, VK_SHADER_STAGE_RAYGEN_BIT_NV, 0, sizeof(int), &idx);
1075  vkCmdPushConstants(cmd_buf, rt_pipeline_layout, VK_SHADER_STAGE_RAYGEN_BIT_NV, sizeof(int), sizeof(int), &bounce);
1076 
1077  int shader = (bounce == 0) ? SBT_RGEN_REFLECT_REFRACT1 : SBT_RGEN_REFLECT_REFRACT2;
1078 
1079  qvkCmdTraceRaysNV(cmd_buf,
1080  buf_shader_binding_table.buffer, shader * rt_properties.shaderGroupHandleSize,
1081  buf_shader_binding_table.buffer, 0, rt_properties.shaderGroupHandleSize,
1082  buf_shader_binding_table.buffer, 0, rt_properties.shaderGroupHandleSize,
1083  VK_NULL_HANDLE, 0, 0,
1084  qvk.extent_render.width / 2, qvk.extent_render.height, qvk.device_count == 1 ? 2 : 1);
1085  }
1086 
1087  set_current_gpu(cmd_buf, ALL_GPUS);
1088 
1089  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_TRANSPARENT]);
1090  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_MOTION]);
1091  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_SHADING_POSITION]);
1092  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_VIEW_DIRECTION]);
1093  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_THROUGHPUT]);
1094  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_GODRAYS_THROUGHPUT_DIST]);
1095  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_ALBEDO]);
1096  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_METALLIC]);
1097  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_CLUSTER]);
1098  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_VIEW_DEPTH_A + frame_idx]);
1099  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_NORMAL_A + frame_idx]);
1100 
1101  return VK_SUCCESS;
1102 }
1103 
1104 VkResult
1105 vkpt_pt_trace_lighting(VkCommandBuffer cmd_buf, float num_bounce_rays)
1106 {
1107  int frame_idx = qvk.frame_counter & 1;
1108 
1109  setup_rt_pipeline(cmd_buf);
1110 
1111  BEGIN_PERF_MARKER(cmd_buf, PROFILER_DIRECT_LIGHTING);
1112 
1113  for (int i = 0; i < qvk.device_count; i++)
1114  {
1115  set_current_gpu(cmd_buf, i);
1116 
1117  int idx = qvk.device_count == 1 ? -1 : i;
1118  vkCmdPushConstants(cmd_buf, rt_pipeline_layout, VK_SHADER_STAGE_RAYGEN_BIT_NV, 0, sizeof(int), &idx);
1119 
1120  int rgen_index = SBT_RGEN_DIRECT_LIGHTING;
1121  if (cvar_pt_caustics->value != 0)
1122  rgen_index = SBT_RGEN_DIRECT_LIGHTING_CAUSTICS;
1123 
1124  qvkCmdTraceRaysNV(cmd_buf,
1125  buf_shader_binding_table.buffer, rgen_index * rt_properties.shaderGroupHandleSize,
1126  buf_shader_binding_table.buffer, 0, rt_properties.shaderGroupHandleSize,
1127  buf_shader_binding_table.buffer, 0, rt_properties.shaderGroupHandleSize,
1128  VK_NULL_HANDLE, 0, 0,
1129  qvk.extent_render.width / 2, qvk.extent_render.height, qvk.device_count == 1 ? 2 : 1);
1130  }
1131 
1132  set_current_gpu(cmd_buf, ALL_GPUS);
1133 
1134  END_PERF_MARKER(cmd_buf, PROFILER_DIRECT_LIGHTING);
1135 
1136  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_COLOR_LF_SH]);
1137  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_COLOR_LF_COCG]);
1138  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_COLOR_HF]);
1139  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_COLOR_SPEC]);
1140 
1141  BUFFER_BARRIER(cmd_buf,
1142  .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
1143  .dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
1144  .buffer = qvk.buf_readback.buffer,
1145  .offset = 0,
1146  .size = VK_WHOLE_SIZE,
1147  );
1148 
1149  BEGIN_PERF_MARKER(cmd_buf, PROFILER_INDIRECT_LIGHTING);
1150 
1151  if (num_bounce_rays > 0)
1152  {
1153  for (int i = 0; i < qvk.device_count; i++)
1154  {
1155  set_current_gpu(cmd_buf, i);
1156 
1157  int idx = qvk.device_count == 1 ? -1 : i;
1158  vkCmdPushConstants(cmd_buf, rt_pipeline_layout, VK_SHADER_STAGE_RAYGEN_BIT_NV, 0, sizeof(idx), &idx);
1159 
1160  for (int bounce_ray = 0; bounce_ray < (int)ceilf(num_bounce_rays); bounce_ray++)
1161  {
1162  int height;
1163  if (num_bounce_rays == 0.5f)
1164  height = qvk.extent_render.height / 2;
1165  else
1166  height = qvk.extent_render.height;
1167 
1168  int rgen_index = (bounce_ray == 0)
1171 
1172  qvkCmdTraceRaysNV(cmd_buf,
1173  buf_shader_binding_table.buffer, rgen_index * rt_properties.shaderGroupHandleSize,
1174  buf_shader_binding_table.buffer, 0, rt_properties.shaderGroupHandleSize,
1175  buf_shader_binding_table.buffer, 0, rt_properties.shaderGroupHandleSize,
1176  VK_NULL_HANDLE, 0, 0,
1177  qvk.extent_render.width / 2, height, qvk.device_count == 1 ? 2 : 1);
1178 
1179  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_COLOR_LF_SH]);
1180  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_COLOR_LF_COCG]);
1181  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_COLOR_HF]);
1182  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_COLOR_SPEC]);
1183  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_BOUNCE_THROUGHPUT]);
1184  }
1185  }
1186  }
1187 
1188  END_PERF_MARKER(cmd_buf, PROFILER_INDIRECT_LIGHTING);
1189 
1190  set_current_gpu(cmd_buf, ALL_GPUS);
1191 
1192  return VK_SUCCESS;
1193 }
1194 
1195 VkResult
1197 {
1198  for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
1206  }
1209  vkDestroyDescriptorSetLayout(qvk.device, rt_descriptor_set_layout, NULL);
1210  vkDestroyPipelineLayout(qvk.device, rt_pipeline_layout, NULL);
1211  vkDestroyDescriptorPool(qvk.device, rt_descriptor_pool, NULL);
1212  return VK_SUCCESS;
1213 }
1214 
1215 VkResult
1217 {
1218  VkSpecializationMapEntry specEntry = {
1219  .constantID = 0,
1220  .offset = 0,
1221  .size = sizeof(uint32_t),
1222  };
1223 
1224  uint32_t numbers[2] = { 0, 1 };
1225 
1226  VkSpecializationInfo specInfo[2] = {
1227  {
1228  .mapEntryCount = 1,
1229  .pMapEntries = &specEntry,
1230  .dataSize = sizeof(uint32_t),
1231  .pData = &numbers[0],
1232  },
1233  {
1234  .mapEntryCount = 1,
1235  .pMapEntries = &specEntry,
1236  .dataSize = sizeof(uint32_t),
1237  .pData = &numbers[1],
1238  }
1239  };
1240 
1241  VkPipelineShaderStageCreateInfo shader_stages[] = {
1242  SHADER_STAGE(QVK_MOD_PRIMARY_RAYS_RGEN, VK_SHADER_STAGE_RAYGEN_BIT_NV),
1243  SHADER_STAGE_SPEC(QVK_MOD_REFLECT_REFRACT_RGEN, VK_SHADER_STAGE_RAYGEN_BIT_NV, &specInfo[0]),
1244  SHADER_STAGE_SPEC(QVK_MOD_REFLECT_REFRACT_RGEN, VK_SHADER_STAGE_RAYGEN_BIT_NV, &specInfo[1]),
1245  SHADER_STAGE_SPEC(QVK_MOD_DIRECT_LIGHTING_RGEN, VK_SHADER_STAGE_RAYGEN_BIT_NV, &specInfo[0]),
1246  SHADER_STAGE_SPEC(QVK_MOD_DIRECT_LIGHTING_RGEN, VK_SHADER_STAGE_RAYGEN_BIT_NV, &specInfo[1]),
1247  SHADER_STAGE_SPEC(QVK_MOD_INDIRECT_LIGHTING_RGEN, VK_SHADER_STAGE_RAYGEN_BIT_NV, &specInfo[0]),
1248  SHADER_STAGE_SPEC(QVK_MOD_INDIRECT_LIGHTING_RGEN, VK_SHADER_STAGE_RAYGEN_BIT_NV, &specInfo[1]),
1249  SHADER_STAGE(QVK_MOD_PATH_TRACER_RMISS, VK_SHADER_STAGE_MISS_BIT_NV),
1250  SHADER_STAGE(QVK_MOD_PATH_TRACER_SHADOW_RMISS, VK_SHADER_STAGE_MISS_BIT_NV),
1251  SHADER_STAGE(QVK_MOD_PATH_TRACER_RCHIT, VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV),
1252  SHADER_STAGE(QVK_MOD_PATH_TRACER_PARTICLE_RAHIT, VK_SHADER_STAGE_ANY_HIT_BIT_NV),
1253  SHADER_STAGE(QVK_MOD_PATH_TRACER_BEAM_RAHIT, VK_SHADER_STAGE_ANY_HIT_BIT_NV),
1254  SHADER_STAGE(QVK_MOD_PATH_TRACER_EXPLOSION_RAHIT, VK_SHADER_STAGE_ANY_HIT_BIT_NV),
1255  SHADER_STAGE(QVK_MOD_PATH_TRACER_SPRITE_RAHIT, VK_SHADER_STAGE_ANY_HIT_BIT_NV),
1256  };
1257 
1258  VkRayTracingShaderGroupCreateInfoNV rt_shader_group_info[] = {
1259  [SBT_RGEN_PRIMARY_RAYS] = {
1260  .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV,
1261  .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV,
1262  .generalShader = 0,
1263  .closestHitShader = VK_SHADER_UNUSED_NV,
1264  .anyHitShader = VK_SHADER_UNUSED_NV,
1265  .intersectionShader = VK_SHADER_UNUSED_NV
1266  },
1268  .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV,
1269  .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV,
1270  .generalShader = 1,
1271  .closestHitShader = VK_SHADER_UNUSED_NV,
1272  .anyHitShader = VK_SHADER_UNUSED_NV,
1273  .intersectionShader = VK_SHADER_UNUSED_NV
1274  },
1276  .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV,
1277  .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV,
1278  .generalShader = 2,
1279  .closestHitShader = VK_SHADER_UNUSED_NV,
1280  .anyHitShader = VK_SHADER_UNUSED_NV,
1281  .intersectionShader = VK_SHADER_UNUSED_NV
1282  },
1284  .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV,
1285  .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV,
1286  .generalShader = 3,
1287  .closestHitShader = VK_SHADER_UNUSED_NV,
1288  .anyHitShader = VK_SHADER_UNUSED_NV,
1289  .intersectionShader = VK_SHADER_UNUSED_NV
1290  },
1292  .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV,
1293  .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV,
1294  .generalShader = 4,
1295  .closestHitShader = VK_SHADER_UNUSED_NV,
1296  .anyHitShader = VK_SHADER_UNUSED_NV,
1297  .intersectionShader = VK_SHADER_UNUSED_NV
1298  },
1300  .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV,
1301  .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV,
1302  .generalShader = 5,
1303  .closestHitShader = VK_SHADER_UNUSED_NV,
1304  .anyHitShader = VK_SHADER_UNUSED_NV,
1305  .intersectionShader = VK_SHADER_UNUSED_NV
1306  },
1308  .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV,
1309  .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV,
1310  .generalShader = 6,
1311  .closestHitShader = VK_SHADER_UNUSED_NV,
1312  .anyHitShader = VK_SHADER_UNUSED_NV,
1313  .intersectionShader = VK_SHADER_UNUSED_NV
1314  },
1315  [SBT_RMISS_PATH_TRACER] = {
1316  .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV,
1317  .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV,
1318  .generalShader = 7,
1319  .closestHitShader = VK_SHADER_UNUSED_NV,
1320  .anyHitShader = VK_SHADER_UNUSED_NV,
1321  .intersectionShader = VK_SHADER_UNUSED_NV
1322  },
1323  [SBT_RMISS_SHADOW] = {
1324  .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV,
1325  .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV,
1326  .generalShader = 8,
1327  .closestHitShader = VK_SHADER_UNUSED_NV,
1328  .anyHitShader = VK_SHADER_UNUSED_NV,
1329  .intersectionShader = VK_SHADER_UNUSED_NV
1330  },
1331  [SBT_RCHIT_OPAQUE] = {
1332  .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV,
1333  .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_NV,
1334  .generalShader = VK_SHADER_UNUSED_NV,
1335  .closestHitShader = 9,
1336  .anyHitShader = VK_SHADER_UNUSED_NV,
1337  .intersectionShader = VK_SHADER_UNUSED_NV
1338  },
1339  [SBT_RAHIT_PARTICLE] = {
1340  .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV,
1341  .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_NV,
1342  .generalShader = VK_SHADER_UNUSED_NV,
1343  .closestHitShader = VK_SHADER_UNUSED_NV,
1344  .anyHitShader = 10,
1345  .intersectionShader = VK_SHADER_UNUSED_NV
1346  },
1347  [SBT_RAHIT_BEAM] = {
1348  .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV,
1349  .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_NV,
1350  .generalShader = VK_SHADER_UNUSED_NV,
1351  .closestHitShader = VK_SHADER_UNUSED_NV,
1352  .anyHitShader = 11,
1353  .intersectionShader = VK_SHADER_UNUSED_NV
1354  },
1355  [SBT_RAHIT_EXPLOSION] = {
1356  .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV,
1357  .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_NV,
1358  .generalShader = VK_SHADER_UNUSED_NV,
1359  .closestHitShader = VK_SHADER_UNUSED_NV,
1360  .anyHitShader = 12,
1361  .intersectionShader = VK_SHADER_UNUSED_NV
1362  },
1363  [SBT_RAHIT_SPRITE] = {
1364  .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV,
1365  .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_NV,
1366  .generalShader = VK_SHADER_UNUSED_NV,
1367  .closestHitShader = VK_SHADER_UNUSED_NV,
1368  .anyHitShader = 13,
1369  .intersectionShader = VK_SHADER_UNUSED_NV
1370  },
1371  [SBT_RCHIT_EMPTY] = {
1372  .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV,
1373  .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_NV,
1374  .generalShader = VK_SHADER_UNUSED_NV,
1375  .closestHitShader = VK_SHADER_UNUSED_NV,
1376  .anyHitShader = VK_SHADER_UNUSED_NV,
1377  .intersectionShader = VK_SHADER_UNUSED_NV
1378  },
1379  };
1380 
1381  VkRayTracingPipelineCreateInfoNV rt_pipeline_info = {
1382  .sType = VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_NV,
1383  .stageCount = LENGTH(shader_stages),
1384  .pStages = shader_stages,
1385  .groupCount = LENGTH(rt_shader_group_info),
1386  .pGroups = rt_shader_group_info,
1387  .layout = rt_pipeline_layout,
1388  .maxRecursionDepth = 1,
1389  };
1390 
1391  _VK(qvkCreateRayTracingPipelinesNV(qvk.device, NULL, 1, &rt_pipeline_info, NULL, &rt_pipeline ));
1392 
1393  uint32_t num_groups = LENGTH(rt_shader_group_info);
1394  uint32_t shader_binding_table_size = rt_properties.shaderGroupHandleSize * num_groups;
1395 
1396  /* pt */
1397  _VK(buffer_create(&buf_shader_binding_table, shader_binding_table_size,
1398  VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT));
1399 
1400  void *shader_binding_table = buffer_map(&buf_shader_binding_table);
1401  _VK(qvkGetRayTracingShaderGroupHandlesNV(qvk.device, rt_pipeline, 0, num_groups,
1402  shader_binding_table_size, shader_binding_table));
1404  shader_binding_table = NULL;
1405 
1406  return VK_SUCCESS;
1407 }
1408 
1409 VkResult
1411 {
1413  vkDestroyPipeline(qvk.device, rt_pipeline, NULL);
1414 
1415  return VK_SUCCESS;
1416 }
QVK_s::desc_set_ubo
VkDescriptorSet desc_set_ubo
Definition: vkpt.h:226
QvkGeometryInstance_s::transform
float transform[12]
Definition: path_tracer.c:110
BUFFER_BARRIER
#define BUFFER_BARRIER(cmd_buf,...)
Definition: vk_util.h:68
accel_dynamic
static VkAccelerationStructureNV accel_dynamic[MAX_FRAMES_IN_FLIGHT]
Definition: path_tracer.c:70
mem_accel_top
static VkDeviceMemory mem_accel_top[MAX_FRAMES_IN_FLIGHT]
Definition: path_tracer.c:86
vkpt_pt_create_viewer_models
static VkResult vkpt_pt_create_viewer_models(VkCommandBuffer cmd_buf, int idx, VkBuffer vertex_buffer, size_t buffer_offset, int num_vertices, int vertex_offset)
Definition: path_tracer.c:703
accel_viewer_models
static VkAccelerationStructureNV accel_viewer_models[MAX_FRAMES_IN_FLIGHT]
Definition: path_tracer.c:74
accel_explosions_match
static accel_bottom_match_info_t accel_explosions_match[MAX_FRAMES_IN_FLIGHT]
Definition: path_tracer.c:79
QVK_s::frame_counter
uint64_t frame_counter
Definition: vkpt.h:212
SBT_RGEN_PRIMARY_RAYS
#define SBT_RGEN_PRIMARY_RAYS
Definition: constants.h:121
vkpt_pt_destroy_explosions
VkResult vkpt_pt_destroy_explosions(int idx)
Definition: path_tracer.c:439
SBT_RGEN_DIRECT_LIGHTING_CAUSTICS
#define SBT_RGEN_DIRECT_LIGHTING_CAUSTICS
Definition: constants.h:125
MAX_FRAMES_IN_FLIGHT
#define MAX_FRAMES_IN_FLIGHT
Definition: vkpt.h:140
height
static int height
Definition: physical_sky.c:39
get_transparency_beam_blas
VkAccelerationStructureNV get_transparency_beam_blas()
Definition: transparency.c:231
buf_shader_binding_table
static BufferResource_t buf_shader_binding_table
Definition: path_tracer.c:93
vkpt_pt_destroy_pipelines
VkResult vkpt_pt_destroy_pipelines()
Definition: path_tracer.c:1410
sprite_info_buffer_view
VkBufferView sprite_info_buffer_view
Definition: transparency.c:74
allocate_gpu_memory
VkResult allocate_gpu_memory(VkMemoryRequirements mem_req, VkDeviceMemory *pMemory)
Definition: vk_util.c:402
viewer_model_primitive_offset
static int viewer_model_primitive_offset
Definition: path_tracer.c:66
SHADER_STAGE_SPEC
#define SHADER_STAGE_SPEC(_module, _stage, _spec)
Definition: vkpt.h:124
vertex_buffer.h
EntityUploadInfo::viewer_model_vertex_num
uint32_t viewer_model_vertex_num
Definition: vkpt.h:481
get_scratch_buffer_size
static size_t get_scratch_buffer_size(VkAccelerationStructureNV ac)
Definition: path_tracer.c:306
QVK_s::device
VkDevice device
Definition: vkpt.h:172
rt_descriptor_pool
static VkDescriptorPool rt_descriptor_pool
Definition: path_tracer.c:95
RAY_GEN_BEAM_COLOR_BUFFER_BINDING_IDX
#define RAY_GEN_BEAM_COLOR_BUFFER_BINDING_IDX
Definition: path_tracer.c:30
vkpt_pt_destroy_viewer_models
VkResult vkpt_pt_destroy_viewer_models(int idx)
Definition: path_tracer.c:411
ac
static ac_locals_t ac
Definition: ac.c:128
EntityUploadInfo::dynamic_vertex_num
uint32_t dynamic_vertex_num
Definition: vkpt.h:477
accel_top_match
static accel_top_match_info_t accel_top_match[MAX_FRAMES_IN_FLIGHT]
Definition: path_tracer.c:81
get_transparency_sprite_blas
VkAccelerationStructureNV get_transparency_sprite_blas()
Definition: transparency.c:236
Cvar_Get
cvar_t * Cvar_Get(const char *var_name, const char *var_value, int flags)
Definition: cvar.c:257
rt_pipeline_layout
static VkPipelineLayout rt_pipeline_layout
Definition: path_tracer.c:98
QvkGeometryInstance_s
Definition: path_tracer.c:109
QVK_s::buf_vertex
BufferResource_t buf_vertex
Definition: vkpt.h:243
BARRIER_COMPUTE
#define BARRIER_COMPUTE(cmd_buf, img)
Definition: path_tracer.c:971
accel_top_match_info_t
struct accel_top_match_info_s accel_top_match_info_t
accel_static
static VkAccelerationStructureNV accel_static
Definition: path_tracer.c:57
buffer_unmap
void buffer_unmap(BufferResource_t *buf)
Definition: vk_util.c:159
QVK_s::current_frame_index
uint32_t current_frame_index
Definition: vkpt.h:219
vkpt.h
QVK_s::buf_readback
BufferResource_t buf_readback
Definition: vkpt.h:249
AS_FLAG_VIEWER_MODELS
#define AS_FLAG_VIEWER_MODELS
Definition: constants.h:110
get_transparency_counts
void get_transparency_counts(int *particle_num, int *beam_num, int *sprite_num)
Definition: transparency.c:256
AS_FLAG_SKY
#define AS_FLAG_SKY
Definition: constants.h:113
vkpt_pt_create_accel_bottom
static VkResult vkpt_pt_create_accel_bottom(VkBuffer vertex_buffer, size_t buffer_offset, int num_vertices, VkAccelerationStructureNV *accel, accel_bottom_match_info_t *match, VkDeviceMemory *mem_accel, VkCommandBuffer cmd_buf, int fast_build)
Definition: path_tracer.c:464
vkpt_pt_create_transparent_models
static VkResult vkpt_pt_create_transparent_models(VkCommandBuffer cmd_buf, int idx, VkBuffer vertex_buffer, size_t buffer_offset, int num_vertices, int vertex_offset)
Definition: path_tracer.c:670
get_transparency_sprite_info_buffer_view
VkBufferView get_transparency_sprite_info_buffer_view()
Definition: transparency.c:251
buffer_destroy
VkResult buffer_destroy(BufferResource_t *buf)
Definition: vk_util.c:132
accel_explosions
static VkAccelerationStructureNV accel_explosions[MAX_FRAMES_IN_FLIGHT]
Definition: path_tracer.c:78
SBT_RMISS_SHADOW
#define SBT_RMISS_SHADOW
Definition: constants.h:129
QvkGeometryInstance_s::instance_id
uint32_t instance_id
Definition: path_tracer.c:111
AS_INSTANCE_FLAG_DYNAMIC
#define AS_INSTANCE_FLAG_DYNAMIC
Definition: constants.h:117
vkpt_pt_destroy_viewer_weapon
VkResult vkpt_pt_destroy_viewer_weapon(int idx)
Definition: path_tracer.c:425
vkpt_pt_trace_reflections
VkResult vkpt_pt_trace_reflections(VkCommandBuffer cmd_buf, int bounce)
Definition: path_tracer.c:1063
mem_accel_transparent
static VkDeviceMemory mem_accel_transparent
Definition: path_tracer.c:83
accel_custom_sky
static VkAccelerationStructureNV accel_custom_sky
Definition: path_tracer.c:60
accel_dynamic_match
static accel_bottom_match_info_t accel_dynamic_match[MAX_FRAMES_IN_FLIGHT]
Definition: path_tracer.c:71
buf_instances
static BufferResource_t buf_instances[MAX_FRAMES_IN_FLIGHT]
Definition: path_tracer.c:56
QVK_s::cmd_buffers_graphics
cmd_buf_group_t cmd_buffers_graphics
Definition: vkpt.h:193
mem_accel_dynamic
static VkDeviceMemory mem_accel_dynamic[MAX_FRAMES_IN_FLIGHT]
Definition: path_tracer.c:87
QvkGeometryInstance_t
struct QvkGeometryInstance_s QvkGeometryInstance_t
QVK_s::physical_device
VkPhysicalDevice physical_device
Definition: vkpt.h:163
accel_viewer_weapon_match
static accel_bottom_match_info_t accel_viewer_weapon_match[MAX_FRAMES_IN_FLIGHT]
Definition: path_tracer.c:77
END_PERF_MARKER
#define END_PERF_MARKER(command_buffer, name)
Definition: vkpt.h:743
vkpt_pt_create_pipelines
VkResult vkpt_pt_create_pipelines()
Definition: path_tracer.c:1216
beam_color_buffer_view
VkBufferView beam_color_buffer_view
Definition: transparency.c:73
vkpt_pt_update_descripter_set_bindings
VkResult vkpt_pt_update_descripter_set_bindings(int idx)
Definition: path_tracer.c:251
custom_sky_primitive_offset
static int custom_sky_primitive_offset
Definition: path_tracer.c:63
accel_top
static VkAccelerationStructureNV accel_top[MAX_FRAMES_IN_FLIGHT]
Definition: path_tracer.c:80
cvar_pt_enable_beams
cvar_t * cvar_pt_enable_beams
Definition: path_tracer.c:102
explosions_primitive_offset
static int explosions_primitive_offset
Definition: path_tracer.c:68
accel_bottom_match_info_s
Definition: path_tracer.c:44
AS_FLAG_PARTICLES
#define AS_FLAG_PARTICLES
Definition: constants.h:109
cvar_pt_reflect_refract
cvar_t * cvar_pt_reflect_refract
_VK
#define _VK(...)
Definition: vkpt.h:65
vkpt_pt_create_toplevel
VkResult vkpt_pt_create_toplevel(VkCommandBuffer cmd_buf, int idx, qboolean include_world, qboolean weapon_left_handed)
Definition: path_tracer.c:852
vkpt_pt_create_viewer_weapon
static VkResult vkpt_pt_create_viewer_weapon(VkCommandBuffer cmd_buf, int idx, VkBuffer vertex_buffer, size_t buffer_offset, int num_vertices, int vertex_offset)
Definition: path_tracer.c:726
SBT_RAHIT_SPRITE
#define SBT_RAHIT_SPRITE
Definition: constants.h:134
explosions_present
static int explosions_present
Definition: path_tracer.c:69
QVK_s::desc_set_vertex_buffer
VkDescriptorSet desc_set_vertex_buffer
Definition: vkpt.h:241
SBT_RCHIT_EMPTY
#define SBT_RCHIT_EMPTY
Definition: constants.h:135
AS_FLAG_CUSTOM_SKY
#define AS_FLAG_CUSTOM_SKY
Definition: constants.h:114
cl_player_model
cvar_t * cl_player_model
Definition: main.c:47
RAY_GEN_PARTICLE_COLOR_BUFFER_BINDING_IDX
#define RAY_GEN_PARTICLE_COLOR_BUFFER_BINDING_IDX
Definition: path_tracer.c:29
SBT_RAHIT_PARTICLE
#define SBT_RAHIT_PARTICLE
Definition: constants.h:131
QvkGeometryInstance_s::acceleration_structure_handle
uint64_t acceleration_structure_handle
Definition: path_tracer.c:115
SBT_RGEN_REFLECT_REFRACT1
#define SBT_RGEN_REFLECT_REFRACT1
Definition: constants.h:122
BufferResource_s::buffer
VkBuffer buffer
Definition: vk_util.h:34
vkpt_pt_create_explosions
static VkResult vkpt_pt_create_explosions(VkCommandBuffer cmd_buf, int idx, VkBuffer vertex_buffer, size_t buffer_offset, int num_vertices, int vertex_offset)
Definition: path_tracer.c:749
accel_viewer_models_match
static accel_bottom_match_info_t accel_viewer_models_match[MAX_FRAMES_IN_FLIGHT]
Definition: path_tracer.c:75
CL_PLAYER_MODEL_FIRST_PERSON
#define CL_PLAYER_MODEL_FIRST_PERSON
Definition: client.h:555
buf_accel_scratch
static BufferResource_t buf_accel_scratch
Definition: path_tracer.c:54
get_transparency_beam_color_buffer_view
VkBufferView get_transparency_beam_color_buffer_view()
Definition: transparency.c:246
accel_viewer_weapon
static VkAccelerationStructureNV accel_viewer_weapon[MAX_FRAMES_IN_FLIGHT]
Definition: path_tracer.c:76
accel_bottom_match_info_s::flags
VkGeometryFlagsNV flags
Definition: path_tracer.c:45
mem_accel_static
static VkDeviceMemory mem_accel_static
Definition: path_tracer.c:82
viewer_weapon_primitive_offset
static int viewer_weapon_primitive_offset
Definition: path_tracer.c:67
transparent_models_present
static int transparent_models_present
Definition: path_tracer.c:65
QVK_s::images
VkImage images[NUM_VKPT_IMAGES]
Definition: vkpt.h:231
setup_rt_pipeline
static void setup_rt_pipeline(VkCommandBuffer cmd_buf)
Definition: path_tracer.c:990
set_current_gpu
void set_current_gpu(VkCommandBuffer cmd_buf, int gpu_index)
Definition: vk_util.c:426
mem_accel_transparent_models
static VkDeviceMemory mem_accel_transparent_models[MAX_FRAMES_IN_FLIGHT]
Definition: path_tracer.c:88
MEM_BARRIER_BUILD_ACCEL
#define MEM_BARRIER_BUILD_ACCEL(cmd_buf,...)
Definition: path_tracer.c:118
AS_INSTANCE_FLAG_SKY
#define AS_INSTANCE_FLAG_SKY
Definition: constants.h:118
beam_num
unsigned int beam_num
Definition: transparency.c:51
vkpt_wait_idle
void vkpt_wait_idle(VkQueue queue, cmd_buf_group_t *group)
Definition: main.c:3405
accel_top_match_info_s
Definition: path_tracer.c:50
LENGTH
#define LENGTH(a)
Definition: tent.c:228
sprite_num
unsigned int sprite_num
Definition: transparency.c:52
DYNAMIC_GEOMETRY_BLOAT_FACTOR
#define DYNAMIC_GEOMETRY_BLOAT_FACTOR
Definition: path_tracer.c:461
BEGIN_PERF_MARKER
#define BEGIN_PERF_MARKER(command_buffer, name)
Definition: vkpt.h:742
SBT_RAHIT_BEAM
#define SBT_RAHIT_BEAM
Definition: constants.h:132
AS_FLAG_OPAQUE
#define AS_FLAG_OPAQUE
Definition: constants.h:107
QvkGeometryInstance_s::mask
uint32_t mask
Definition: path_tracer.c:112
QvkGeometryInstance_s::instance_offset
uint32_t instance_offset
Definition: path_tracer.c:113
vkpt_pt_create_all_dynamic
VkResult vkpt_pt_create_all_dynamic(VkCommandBuffer cmd_buf, int idx, VkBuffer vertex_buffer, const EntityUploadInfo *upload_info)
Definition: path_tracer.c:781
vertex_buffer
VkBuffer vertex_buffer
Definition: transparency.c:64
SBT_RGEN_INDIRECT_LIGHTING_FIRST
#define SBT_RGEN_INDIRECT_LIGHTING_FIRST
Definition: constants.h:126
vkpt_pt_trace_lighting
VkResult vkpt_pt_trace_lighting(VkCommandBuffer cmd_buf, float num_bounce_rays)
Definition: path_tracer.c:1105
transparent_model_primitive_offset
static int transparent_model_primitive_offset
Definition: path_tracer.c:64
accel_bottom_match_info_s::vertexCount
uint32_t vertexCount
Definition: path_tracer.c:46
AS_FLAG_VIEWER_WEAPON
#define AS_FLAG_VIEWER_WEAPON
Definition: constants.h:111
vkpt_pt_destroy_toplevel
void vkpt_pt_destroy_toplevel(int idx)
Definition: path_tracer.c:815
cvar_pt_caustics
cvar_t * cvar_pt_caustics
Definition: main.c:52
sky_primitive_offset
static int sky_primitive_offset
Definition: path_tracer.c:62
SBT_RMISS_PATH_TRACER
#define SBT_RMISS_PATH_TRACER
Definition: constants.h:128
qvk
QVK_t qvk
Definition: main.c:377
particle_num
unsigned int particle_num
Definition: transparency.c:50
vkpt_pt_init
VkResult vkpt_pt_init()
Definition: path_tracer.c:134
mem_accel_viewer_models
static VkDeviceMemory mem_accel_viewer_models[MAX_FRAMES_IN_FLIGHT]
Definition: path_tracer.c:89
mem_accel_viewer_weapon
static VkDeviceMemory mem_accel_viewer_weapon[MAX_FRAMES_IN_FLIGHT]
Definition: path_tracer.c:90
vkpt_submit_command_buffer_simple
void vkpt_submit_command_buffer_simple(VkCommandBuffer cmd_buf, VkQueue queue, qboolean all_gpus)
Definition: main.c:3473
ALL_GPUS
#define ALL_GPUS
Definition: vkpt.h:535
INSTANCE_MAX_NUM
#define INSTANCE_MAX_NUM
Definition: path_tracer.c:35
cvar_pt_enable_particles
cvar_t * cvar_pt_enable_particles
Definition: path_tracer.c:101
mem_accel_sky
static VkDeviceMemory mem_accel_sky
Definition: path_tracer.c:84
vk_util.h
vkpt_pt_destroy_static
VkResult vkpt_pt_destroy_static()
Definition: path_tracer.c:345
accel_bottom_match_info_t
struct accel_bottom_match_info_s accel_bottom_match_info_t
SHADER_STAGE
#define SHADER_STAGE(_module, _stage)
Definition: vkpt.h:116
accel_transparent
static VkAccelerationStructureNV accel_transparent
Definition: path_tracer.c:58
SBT_RCHIT_OPAQUE
#define SBT_RCHIT_OPAQUE
Definition: constants.h:130
rt_properties
static VkPhysicalDeviceRayTracingPropertiesNV rt_properties
Definition: path_tracer.c:37
SIZE_SCRATCH_BUFFER
#define SIZE_SCRATCH_BUFFER
Definition: path_tracer.c:33
QVK_s::extent_render
VkExtent2D extent_render
Definition: vkpt.h:184
get_transparency_particle_color_buffer_view
VkBufferView get_transparency_particle_color_buffer_view()
Definition: transparency.c:241
BufferResource_s
Definition: vk_util.h:33
rt_descriptor_set
static VkDescriptorSet rt_descriptor_set[MAX_FRAMES_IN_FLIGHT]
Definition: path_tracer.c:96
EntityUploadInfo
Definition: vkpt.h:473
accel_transparent_models
static VkAccelerationStructureNV accel_transparent_models[MAX_FRAMES_IN_FLIGHT]
Definition: path_tracer.c:72
accel_sky
static VkAccelerationStructureNV accel_sky
Definition: path_tracer.c:59
EntityUploadInfo::explosions_vertex_offset
uint32_t explosions_vertex_offset
Definition: vkpt.h:484
vkpt_pt_create_static
VkResult vkpt_pt_create_static(VkBuffer vertex_buffer, size_t buffer_offset, int num_vertices, int num_vertices_transparent, int num_vertices_sky, int num_vertices_custom_sky)
Definition: path_tracer.c:574
EntityUploadInfo::explosions_vertex_num
uint32_t explosions_vertex_num
Definition: vkpt.h:485
accel_bottom_match_info_s::indexCount
uint32_t indexCount
Definition: path_tracer.c:47
EntityUploadInfo::transparent_model_vertex_num
uint32_t transparent_model_vertex_num
Definition: vkpt.h:479
particle_color_buffer_view
VkBufferView particle_color_buffer_view
Definition: transparency.c:72
rt_descriptor_set_layout
static VkDescriptorSetLayout rt_descriptor_set_layout
Definition: path_tracer.c:97
rt_pipeline
static VkPipeline rt_pipeline
Definition: path_tracer.c:99
VertexBuffer
Definition: vertex_buffer.h:96
vkpt_pt_create_dynamic
static VkResult vkpt_pt_create_dynamic(VkCommandBuffer cmd_buf, int idx, VkBuffer vertex_buffer, size_t buffer_offset, int num_vertices)
Definition: path_tracer.c:650
buffer_create
VkResult buffer_create(BufferResource_t *buf, VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags mem_properties)
Definition: vk_util.c:57
SBT_RGEN_DIRECT_LIGHTING
#define SBT_RGEN_DIRECT_LIGHTING
Definition: constants.h:124
cvar_pt_enable_sprites
cvar_t * cvar_pt_enable_sprites
Definition: path_tracer.c:103
EntityUploadInfo::viewer_weapon_vertex_num
uint32_t viewer_weapon_vertex_num
Definition: vkpt.h:483
SBT_RGEN_REFLECT_REFRACT2
#define SBT_RGEN_REFLECT_REFRACT2
Definition: constants.h:123
vkpt_pt_trace_primary_rays
VkResult vkpt_pt_trace_primary_rays(VkCommandBuffer cmd_buf)
Definition: path_tracer.c:1009
QvkGeometryInstance_s::flags
uint32_t flags
Definition: path_tracer.c:114
ATTACH_LABEL_VARIABLE
#define ATTACH_LABEL_VARIABLE(a, type)
Definition: vk_util.h:137
accel_top_match_info_s::instanceCount
uint32_t instanceCount
Definition: path_tracer.c:51
vkpt_begin_command_buffer
VkCommandBuffer vkpt_begin_command_buffer(cmd_buf_group_t *group)
Definition: main.c:3301
QVK_s::desc_set_layout_textures
VkDescriptorSetLayout desc_set_layout_textures
Definition: vkpt.h:228
accel_matches
static int accel_matches(accel_bottom_match_info_t *match, VkGeometryNV *geometry)
Definition: path_tracer.c:452
QVK_s::desc_set_layout_ubo
VkDescriptorSetLayout desc_set_layout_ubo
Definition: vkpt.h:225
RAY_GEN_ACCEL_STRUCTURE_BINDING_IDX
#define RAY_GEN_ACCEL_STRUCTURE_BINDING_IDX
Definition: path_tracer.c:28
vkpt_pt_destroy_dynamic
VkResult vkpt_pt_destroy_dynamic(int idx)
Definition: path_tracer.c:383
transparent_primitive_offset
static int transparent_primitive_offset
Definition: path_tracer.c:61
RAY_GEN_SPRITE_INFO_BUFFER_BINDING_IDX
#define RAY_GEN_SPRITE_INFO_BUFFER_BINDING_IDX
Definition: path_tracer.c:31
buffer_map
void * buffer_map(BufferResource_t *buf)
Definition: vk_util.c:147
get_transparency_particle_blas
VkAccelerationStructureNV get_transparency_particle_blas()
Definition: transparency.c:226
int
CONST PIXELFORMATDESCRIPTOR int
Definition: wgl.c:26
AS_FLAG_TRANSPARENT
#define AS_FLAG_TRANSPARENT
Definition: constants.h:108
EntityUploadInfo::viewer_model_vertex_offset
uint32_t viewer_model_vertex_offset
Definition: vkpt.h:480
SBT_RAHIT_EXPLOSION
#define SBT_RAHIT_EXPLOSION
Definition: constants.h:133
mem_accel_explosions
static VkDeviceMemory mem_accel_explosions[MAX_FRAMES_IN_FLIGHT]
Definition: path_tracer.c:91
vkpt_pt_destroy
VkResult vkpt_pt_destroy()
Definition: path_tracer.c:1196
vkpt_pt_destroy_transparent_models
VkResult vkpt_pt_destroy_transparent_models(int idx)
Definition: path_tracer.c:397
append_blas
static void append_blas(QvkGeometryInstance_t *instances, int *num_instances, VkAccelerationStructureNV blas, int instance_id, int mask, int flags, int sbt_offset)
Definition: path_tracer.c:829
qvk_get_current_desc_set_textures
VkDescriptorSet qvk_get_current_desc_set_textures()
Definition: main.c:1847
AS_FLAG_EXPLOSIONS
#define AS_FLAG_EXPLOSIONS
Definition: constants.h:112
mem_accel_custom_sky
static VkDeviceMemory mem_accel_custom_sky
Definition: path_tracer.c:85
EntityUploadInfo::transparent_model_vertex_offset
uint32_t transparent_model_vertex_offset
Definition: vkpt.h:478
SBT_RGEN_INDIRECT_LIGHTING_SECOND
#define SBT_RGEN_INDIRECT_LIGHTING_SECOND
Definition: constants.h:127
QVK_s::queue_graphics
VkQueue queue_graphics
Definition: vkpt.h:173
QVK_s::device_count
int device_count
Definition: vkpt.h:167
scratch_buf_ptr
static size_t scratch_buf_ptr
Definition: path_tracer.c:55
get_geometry
static VkGeometryNV get_geometry(VkBuffer buffer, size_t offset, uint32_t num_vertices)
Definition: path_tracer.c:322
QVK_s::desc_set_layout_vertex_buffer
VkDescriptorSetLayout desc_set_layout_vertex_buffer
Definition: vkpt.h:240
accel_transparent_models_match
static accel_bottom_match_info_t accel_transparent_models_match[MAX_FRAMES_IN_FLIGHT]
Definition: path_tracer.c:73
EntityUploadInfo::viewer_weapon_vertex_offset
uint32_t viewer_weapon_vertex_offset
Definition: vkpt.h:482