Quake II RTX doxygen  1.0 dev
vertex_buffer.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 #include "shader/vertex_buffer.h"
23 #include "material.h"
24 
25 #include <assert.h>
26 #include <stdio.h>
27 #include "precomputed_sky.h"
28 
29 
30 static VkDescriptorPool desc_pool_vertex_buffer;
31 static VkPipeline pipeline_instance_geometry;
32 static VkPipeline pipeline_animate_materials;
33 static VkPipelineLayout pipeline_layout_instance_geometry;
34 
35 VkResult
37 {
38  vkWaitForFences(qvk.device, 1, &qvk.fence_vertex_sync, VK_TRUE, ~((uint64_t)0));
39  vkResetFences(qvk.device, 1, &qvk.fence_vertex_sync);
40 
41  VkCommandBuffer cmd_buf = vkpt_begin_command_buffer(&qvk.cmd_buffers_graphics);
42 
43  VkBufferCopy copyRegion = {
44  .size = sizeof(VertexBuffer),
45  };
46  vkCmdCopyBuffer(cmd_buf, qvk.buf_vertex_staging.buffer, qvk.buf_vertex.buffer, 1, &copyRegion);
47 
48  BUFFER_BARRIER(cmd_buf,
49  .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
50  .dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV,
51  .buffer = qvk.buf_vertex.buffer,
52  .offset = 0,
53  .size = VK_WHOLE_SIZE,
54  );
55 
56  if (qvk.buf_light_stats[0].buffer)
57  {
58  vkCmdFillBuffer(cmd_buf, qvk.buf_light_stats[0].buffer, 0, qvk.buf_light_stats[0].size, 0);
59  vkCmdFillBuffer(cmd_buf, qvk.buf_light_stats[1].buffer, 0, qvk.buf_light_stats[1].size, 0);
60  vkCmdFillBuffer(cmd_buf, qvk.buf_light_stats[2].buffer, 0, qvk.buf_light_stats[2].size, 0);
61  }
62 
63  vkpt_submit_command_buffer(cmd_buf, qvk.queue_graphics, (1 << qvk.device_count) - 1, 0, NULL, NULL, NULL, 0, NULL, NULL, qvk.fence_vertex_sync);
64 
65  return VK_SUCCESS;
66 }
67 
68 VkResult
69 vkpt_light_buffer_upload_staging(VkCommandBuffer cmd_buf)
70 {
72 
73  assert(!staging->is_mapped);
74 
75  VkBufferCopy copyRegion = {
76  .size = sizeof(LightBuffer),
77  };
78  vkCmdCopyBuffer(cmd_buf, staging->buffer, qvk.buf_light.buffer, 1, &copyRegion);
79 
80  int buffer_idx = qvk.frame_counter % 3;
81  if (qvk.buf_light_stats[buffer_idx].buffer)
82  {
83  vkCmdFillBuffer(cmd_buf, qvk.buf_light_stats[buffer_idx].buffer, 0, qvk.buf_light_stats[buffer_idx].size, 0);
84  }
85 
86  return VK_SUCCESS;
87 }
88 
89 VkResult
91 {
92  assert(bsp_mesh);
94  assert(vbo);
95 
96  int num_vertices = bsp_mesh->num_vertices;
97  if (num_vertices > MAX_VERT_BSP)
98  {
99  assert(!"Vertex buffer overflow");
100  num_vertices = MAX_VERT_BSP;
101  }
102 
103  memcpy(vbo->positions_bsp, bsp_mesh->positions, num_vertices * sizeof(float) * 3 );
104  memcpy(vbo->tex_coords_bsp, bsp_mesh->tex_coords,num_vertices * sizeof(float) * 2 );
105  memcpy(vbo->tangents_bsp, bsp_mesh->tangents, num_vertices * sizeof(float));
106  memcpy(vbo->materials_bsp, bsp_mesh->materials, num_vertices * sizeof(uint32_t) / 3);
107  memcpy(vbo->clusters_bsp, bsp_mesh->clusters, num_vertices * sizeof(uint32_t) / 3);
108  memcpy(vbo->texel_density_bsp, bsp_mesh->texel_density, num_vertices * sizeof(float) / 3);
109 
110  int num_clusters = bsp_mesh->num_clusters;
111  if (num_clusters > MAX_LIGHT_LISTS)
112  {
113  assert(!"Visibility buffer overflow");
114  num_clusters = MAX_LIGHT_LISTS;
115  }
116 
117  memcpy(vbo->sky_visibility, bsp_mesh->sky_visibility, (num_clusters + 7) / 8);
118 
120  vbo = NULL;
121 
122  return VK_SUCCESS;
123 }
124 
125 static int local_light_counts[MAX_MAP_LEAFS];
126 static int cluster_light_counts[MAX_MAP_LEAFS];
127 static int light_list_tails[MAX_MAP_LEAFS];
128 static int max_cluster_model_lights[MAX_MAP_LEAFS];
129 static int max_model_lights;
130 
132 {
134  max_model_lights = 0;
135 }
136 
137 void
138 inject_model_lights(bsp_mesh_t* bsp_mesh, bsp_t* bsp, int num_model_lights, light_poly_t* transformed_model_lights, int model_light_offset, uint32_t* dst_list_offsets, uint32_t* dst_lists)
139 {
140  memset(local_light_counts, 0, bsp_mesh->num_clusters * sizeof(int));
141  memset(cluster_light_counts, 0, bsp_mesh->num_clusters * sizeof(int));
142 
143  // Count the number of model lights per cluster
144 
145  for (int nlight = 0; nlight < num_model_lights; nlight++)
146  {
147  local_light_counts[transformed_model_lights[nlight].cluster]++;
148  }
149 
150  // Count the number of model lights visible from each cluster, using the PVS
151 
152  for (int c = 0; c < bsp_mesh->num_clusters; c++)
153  {
154  if (local_light_counts[c])
155  {
156  const char* mask = BSP_GetPvs(bsp, c);
157 
158  for (int j = 0; j < bsp->visrowsize; j++) {
159  if (mask[j]) {
160  for (int k = 0; k < 8; ++k) {
161  if (mask[j] & (1 << k))
163  }
164  }
165  }
166  }
167  }
168 
169  // Update the max light counts per cluster
170 
171  for (int c = 0; c < bsp_mesh->num_clusters; c++)
172  {
174  }
175 
176  // Copy the static light lists, and make room in these lists to inject the model lights
177 
178  int tail = 0;
179  for (int c = 0; c < bsp_mesh->num_clusters; c++)
180  {
181  int original_size = bsp_mesh->cluster_light_offsets[c + 1] - bsp_mesh->cluster_light_offsets[c];
182 
183  dst_list_offsets[c] = tail;
184  memcpy(dst_lists + tail, bsp_mesh->cluster_lights + bsp_mesh->cluster_light_offsets[c], sizeof(uint32_t) * original_size);
185  tail += original_size;
186  if (max_cluster_model_lights[c] > 0) {
187  memset(dst_lists + tail, 0xff, sizeof(uint32_t) * max_cluster_model_lights[c]);
188  }
189  light_list_tails[c] = tail;
190  tail += max_cluster_model_lights[c];
191  }
192  dst_list_offsets[bsp_mesh->num_clusters] = tail;
193 
194  // Write the model light indices into the light lists
195 
196  for (int nlight = 0; nlight < num_model_lights; nlight++)
197  {
198  const char* mask = BSP_GetPvs(bsp, transformed_model_lights[nlight].cluster);
199 
200  for (int j = 0; j < bsp->visrowsize; j++) {
201  if (mask[j]) {
202  for (int k = 0; k < 8; ++k) {
203  if (mask[j] & (1 << k))
204  {
205  int other_cluster = j * 8 + k;
206  dst_lists[light_list_tails[other_cluster]++] = model_light_offset + nlight;
207  }
208  }
209  }
210  }
211  }
212 }
213 
214 static inline void
215 copy_light(const light_poly_t* light, float* vblight, const float* sky_radiance)
216 {
217  float style_scale = 1.f;
218  float prev_style = 1.f;
219  if (light->style != 0 && vkpt_refdef.fd->lightstyles)
220  {
221  style_scale = vkpt_refdef.fd->lightstyles[light->style].white;
222  style_scale = max(0, min(1, style_scale));
223 
224  prev_style = vkpt_refdef.prev_lightstyles[light->style].white;
225  prev_style = max(0, min(1, prev_style));
226  }
227 
228  float mat_scale = light->material ? light->material->emissive_scale : 1.f;
229 
230  VectorCopy(light->positions + 0, vblight + 0);
231  VectorCopy(light->positions + 3, vblight + 4);
232  VectorCopy(light->positions + 6, vblight + 8);
233 
234  if (light->color[0] < 0.f)
235  {
236  vblight[3] = -sky_radiance[0] * 0.5f;
237  vblight[7] = -sky_radiance[1] * 0.5f;
238  vblight[11] = -sky_radiance[2] * 0.5f;
239  }
240  else
241  {
242  vblight[3] = light->color[0] * mat_scale;
243  vblight[7] = light->color[1] * mat_scale;
244  vblight[11] = light->color[2] * mat_scale;
245  }
246 
247  vblight[12] = style_scale;
248  vblight[13] = prev_style;
249  vblight[14] = 0.f;
250  vblight[15] = 0.f;
251 }
252 
253 /*
254  Float -> Half converter function, adapted from
255  https://stackoverflow.com/questions/1659440/32-bit-to-16-bit-floating-point-conversion
256 */
257 
258 typedef union
259 {
260  float f;
261  int32_t si;
262  uint32_t ui;
263 } Bits;
264 
265 static uint16_t floatToHalf(float value)
266 {
267  static int const shift = 13;
268  static int const shiftSign = 16;
269 
270  static int32_t const infN = 0x7F800000; // flt32 infinity
271  static int32_t const maxN = 0x477FE000; // max flt16 normal as a flt32
272  static int32_t const minN = 0x38800000; // min flt16 normal as a flt32
273  static int32_t const signN = 0x80000000; // flt32 sign bit
274 
275  static int32_t const infC = 0x3FC00;
276  static int32_t const nanN = 0x7F802000; // minimum flt16 nan as a flt32
277  static int32_t const maxC = 0x23BFF;
278  static int32_t const minC = 0x1C400;
279  static int32_t const signC = 0x8000; // flt16 sign bit
280 
281  static int32_t const mulN = 0x52000000; // (1 << 23) / minN
282  static int32_t const mulC = 0x33800000; // minN / (1 << (23 - shift))
283 
284  static int32_t const subC = 0x003FF; // max flt32 subnormal down shifted
285  static int32_t const norC = 0x00400; // min flt32 normal down shifted
286 
287  static int32_t const maxD = 0x1C000;
288  static int32_t const minD = 0x1C000;
289 
290  Bits v, s;
291  v.f = value;
292  uint32_t sign = v.si & signN;
293  v.si ^= sign;
294  sign >>= shiftSign; // logical shift
295  s.si = mulN;
296  s.si = s.f * v.f; // correct subnormals
297  v.si ^= (s.si ^ v.si) & -(minN > v.si);
298  v.si ^= (infN ^ v.si) & -((infN > v.si) & (v.si > maxN));
299  v.si ^= (nanN ^ v.si) & -((nanN > v.si) & (v.si > infN));
300  v.ui >>= shift; // logical shift
301  v.si ^= ((v.si - maxD) ^ v.si) & -(v.si > maxC);
302  v.si ^= ((v.si - minD) ^ v.si) & -(v.si > subC);
303  return v.ui | sign;
304 }
305 
307 extern char cluster_debug_mask[VIS_MAX_BYTES];
308 
309 VkResult
310 vkpt_light_buffer_upload_to_staging(qboolean render_world, bsp_mesh_t *bsp_mesh, bsp_t* bsp, int num_model_lights, light_poly_t* transformed_model_lights, const float* sky_radiance)
311 {
312  assert(bsp_mesh);
313 
315 
316  LightBuffer *lbo = (LightBuffer *)buffer_map(staging);
317  assert(lbo);
318 
319  if (render_world)
320  {
321  assert(bsp_mesh->num_clusters + 1 < MAX_LIGHT_LISTS);
322  assert(bsp_mesh->num_cluster_lights < MAX_LIGHT_LIST_NODES);
324  assert(bsp_mesh->num_light_polys + num_model_lights < MAX_LIGHT_POLYS);
325 
326  int model_light_offset = bsp_mesh->num_light_polys;
328 
329  if(max_model_lights > 0)
330  {
331  // If any of the BSP models contain lights, inject these lights right into the visibility lists.
332  // The shader doesn't know that these lights are dynamic.
333 
334  inject_model_lights(bsp_mesh, bsp, num_model_lights, transformed_model_lights, model_light_offset, lbo->light_list_offsets, lbo->light_list_lights);
335  }
336  else
337  {
338  memcpy(lbo->light_list_offsets, bsp_mesh->cluster_light_offsets, (bsp_mesh->num_clusters + 1) * sizeof(uint32_t));
339  memcpy(lbo->light_list_lights, bsp_mesh->cluster_lights, bsp_mesh->num_cluster_lights * sizeof(uint32_t));
340  }
341 
342  for (int nlight = 0; nlight < bsp_mesh->num_light_polys; nlight++)
343  {
344  light_poly_t* light = bsp_mesh->light_polys + nlight;
345  float* vblight = lbo->light_polys + nlight * (LIGHT_POLY_VEC4S * 4);
346  copy_light(light, vblight, sky_radiance);
347  }
348 
349  for (int nlight = 0; nlight < num_model_lights; nlight++)
350  {
351  light_poly_t* light = transformed_model_lights + nlight;
352  float* vblight = lbo->light_polys + (nlight + model_light_offset) * (LIGHT_POLY_VEC4S * 4);
353  copy_light(light, vblight, sky_radiance);
354  }
355  }
356  else
357  {
358  lbo->light_list_offsets[0] = 0;
359  lbo->light_list_offsets[1] = 0;
360  }
361 
362  /* effects.c declares this - hence the assert below:
363  typedef struct clightstyle_s {
364  ...
365  float map[MAX_QPATH];
366  } clightstyle_t;
367  */
368 
369  assert(MAX_LIGHT_STYLES == MAX_QPATH);
370  for (int nstyle = 0; nstyle < MAX_LIGHT_STYLES; nstyle++)
371  {
372  float style_scale = 1.f;
373  if (vkpt_refdef.fd->lightstyles)
374  {
375  style_scale = vkpt_refdef.fd->lightstyles[nstyle].white;
376  style_scale = max(0, min(1, style_scale));
377  }
378  lbo->light_styles[nstyle] = style_scale;
379  }
380 
381  // materials
382  int nmaterials = MAT_GetNumPBRMaterials();
383  pbr_material_t const * materials = MAT_GetPBRMaterialsTable();
384 
385  for (int nmat = 0; nmat < nmaterials; nmat++)
386  {
387  pbr_material_t const * material = materials + nmat;
388  uint32_t* mat_data = lbo->material_table + nmat * 4;
389  memset(mat_data, 0, sizeof(uint32_t) * 4);
390 
391  if (material->image_diffuse) mat_data[0] |= (material->image_diffuse - r_images);
392  if (material->image_normals) mat_data[0] |= (material->image_normals - r_images) << 16;
393  if (material->image_emissive) mat_data[1] |= (material->image_emissive - r_images);
394  mat_data[1] |= (material->num_frames & 0x000f) << 28;
395  mat_data[1] |= (material->next_frame & 0x0fff) << 16;
396 
397  mat_data[2] = floatToHalf(material->bump_scale);
398  mat_data[2] |= floatToHalf(material->rough_override) << 16;
399  mat_data[3] = floatToHalf(material->specular_scale);
400  mat_data[3] |= floatToHalf(material->emissive_scale) << 16;
401  }
402 
403  memcpy(lbo->cluster_debug_mask, cluster_debug_mask, MAX_LIGHT_LISTS / 8);
404 
405  buffer_unmap(staging);
406  lbo = NULL;
407 
408  return VK_SUCCESS;
409 }
410 
411 VkResult
413 {
415  assert(vbo);
416 
417  int idx_offset = 0;
418  int vertex_offset = 0;
419  for(int i = 0; i < MAX_MODELS; i++) {
420  if(!r_models[i].meshes) {
421  continue;
422  }
423 
424  for (int nmesh = 0; nmesh < r_models[i].nummeshes; nmesh++)
425  {
426  maliasmesh_t *m = r_models[i].meshes + nmesh;
427 
428  m->idx_offset = idx_offset;
429  m->vertex_offset = vertex_offset;
430 
431  assert(r_models[i].numframes > 0);
432 
433  int num_verts = r_models[i].numframes * m->numverts;
434  assert(num_verts > 0);
435 #if 0
436  for (int j = 0; j < num_verts; j++)
437  Com_Printf("%f %f %f\n",
438  m->positions[j][0],
439  m->positions[j][1],
440  m->positions[j][2]);
441 
442  for (int j = 0; j < m->numtris; j++)
443  Com_Printf("%d %d %d\n",
444  m->indices[j * 3 + 0],
445  m->indices[j * 3 + 1],
446  m->indices[j * 3 + 2]);
447 #endif
448 
449 #if 0
450  char buf[1024];
451  snprintf(buf, sizeof buf, "model_%04d.obj", i);
452  FILE *f = fopen(buf, "wb+");
453  assert(f);
454  for (int j = 0; j < m->numverts; j++) {
455  fprintf(f, "v %f %f %f\n",
456  m->positions[j][0],
457  m->positions[j][1],
458  m->positions[j][2]);
459  }
460  for (int j = 0; j < m->numindices / 3; j++) {
461  fprintf(f, "f %d %d %d\n",
462  m->indices[j * 3 + 0] + 1,
463  m->indices[j * 3 + 1] + 1,
464  m->indices[j * 3 + 2] + 1);
465  }
466  fclose(f);
467 #endif
468 
469  memcpy(vbo->positions_model + vertex_offset * 3, m->positions, sizeof(float) * 3 * num_verts);
470  memcpy(vbo->normals_model + vertex_offset * 3, m->normals, sizeof(float) * 3 * num_verts);
471  memcpy(vbo->tex_coords_model + vertex_offset * 2, m->tex_coords, sizeof(float) * 2 * num_verts);
472  memcpy(vbo->tangents_model + vertex_offset * 4, m->tangents, sizeof(float) * 4 * num_verts);
473  memcpy(vbo->idx_model + idx_offset, m->indices, sizeof(uint32_t) * m->numindices);
474 
475  vertex_offset += num_verts;
476  idx_offset += m->numtris * 3;
477 
478  assert(vertex_offset < MAX_VERT_MODEL);
479  assert(idx_offset < MAX_IDX_MODEL);
480  }
481  }
482 
484  vbo = NULL;
485 
486  // Com_Printf("uploaded %d vert, %d idx\n", vertex_offset, idx_offset);
487 
488  return VK_SUCCESS;
489 }
490 
491 VkResult
493 {
494  VkDescriptorSetLayoutBinding vbo_layout_bindings[] = {
495  {
496  .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
497  .descriptorCount = 1,
498  .binding = VERTEX_BUFFER_BINDING_IDX,
499  .stageFlags = VK_SHADER_STAGE_ALL,
500  },
501  {
502  .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
503  .descriptorCount = 1,
504  .binding = LIGHT_BUFFER_BINDING_IDX,
505  .stageFlags = VK_SHADER_STAGE_ALL,
506  },
507  {
508  .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
509  .descriptorCount = 1,
510  .binding = READBACK_BUFFER_BINDING_IDX,
511  .stageFlags = VK_SHADER_STAGE_ALL,
512  },
513  {
514  .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
515  .descriptorCount = 1,
517  .stageFlags = VK_SHADER_STAGE_ALL,
518  },
519  {
520  .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
521  .descriptorCount = 1,
522  .binding = SUN_COLOR_BUFFER_BINDING_IDX,
523  .stageFlags = VK_SHADER_STAGE_ALL,
524  },
525  {
526  .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
527  .descriptorCount = 1,
528  .binding = SUN_COLOR_UBO_BINDING_IDX,
529  .stageFlags = VK_SHADER_STAGE_ALL,
530  },
531  {
532  .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
533  .descriptorCount = 3,
535  .stageFlags = VK_SHADER_STAGE_ALL,
536  }
537  };
538 
539  VkDescriptorSetLayoutCreateInfo layout_info = {
540  .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
541  .bindingCount = LENGTH(vbo_layout_bindings),
542  .pBindings = vbo_layout_bindings,
543  };
544 
545  _VK(vkCreateDescriptorSetLayout(qvk.device, &layout_info, NULL, &qvk.desc_set_layout_vertex_buffer));
546 
547  // Com_Printf("allocating %.02f MB of memory for vertex buffer\n", (double) sizeof(VertexBuffer) / (1024.0 * 1024.0));
549  VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
550  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
551 
552  // Com_Printf("allocating %.02f MB of memory for staging vertex buffer\n", (double) sizeof(VertexBuffer) / (1024.0 * 1024.0));
554  VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
555  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
556 
558  VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
559  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
560 
561  for (int frame = 0; frame < MAX_FRAMES_IN_FLIGHT; frame++)
562  {
564  VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
565  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
566  }
567 
569  VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
570  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
571 
573  VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
574  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
575 
577  VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
578  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
579 
580  for (int frame = 0; frame < MAX_FRAMES_IN_FLIGHT; frame++)
581  {
583  VK_BUFFER_USAGE_TRANSFER_DST_BIT,
584  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
585  }
586 
587  VkDescriptorPoolSize pool_size = {
588  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
589  .descriptorCount = LENGTH(vbo_layout_bindings),
590  };
591 
592  VkDescriptorPoolCreateInfo pool_info = {
593  .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
594  .poolSizeCount = 1,
595  .pPoolSizes = &pool_size,
596  .maxSets = 1,
597  };
598 
599  _VK(vkCreateDescriptorPool(qvk.device, &pool_info, NULL, &desc_pool_vertex_buffer));
600 
601  VkDescriptorSetAllocateInfo descriptor_set_alloc_info = {
602  .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
603  .descriptorPool = desc_pool_vertex_buffer,
604  .descriptorSetCount = 1,
605  .pSetLayouts = &qvk.desc_set_layout_vertex_buffer,
606  };
607 
608  _VK(vkAllocateDescriptorSets(qvk.device, &descriptor_set_alloc_info, &qvk.desc_set_vertex_buffer));
609 
610  VkDescriptorBufferInfo buf_info = {
611  .buffer = qvk.buf_vertex.buffer,
612  .offset = 0,
613  .range = sizeof(VertexBuffer),
614  };
615 
616  VkWriteDescriptorSet output_buf_write = {
617  .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
618  .dstSet = qvk.desc_set_vertex_buffer,
619  .dstBinding = 0,
620  .dstArrayElement = 0,
621  .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
622  .descriptorCount = 1,
623  .pBufferInfo = &buf_info,
624  };
625 
626  vkUpdateDescriptorSets(qvk.device, 1, &output_buf_write, 0, NULL);
627 
628  output_buf_write.dstBinding = 1;
629  buf_info.buffer = qvk.buf_light.buffer;
630  buf_info.range = sizeof(LightBuffer);
631  vkUpdateDescriptorSets(qvk.device, 1, &output_buf_write, 0, NULL);
632 
633  output_buf_write.dstBinding = 2;
634  buf_info.buffer = qvk.buf_readback.buffer;
635  buf_info.range = sizeof(ReadbackBuffer);
636  vkUpdateDescriptorSets(qvk.device, 1, &output_buf_write, 0, NULL);
637 
638  output_buf_write.dstBinding = 3;
639  buf_info.buffer = qvk.buf_tonemap.buffer;
640  buf_info.range = sizeof(ToneMappingBuffer);
641  vkUpdateDescriptorSets(qvk.device, 1, &output_buf_write, 0, NULL);
642 
643  output_buf_write.dstBinding = 4;
644  buf_info.buffer = qvk.buf_sun_color.buffer;
645  buf_info.range = sizeof(SunColorBuffer);
646  vkUpdateDescriptorSets(qvk.device, 1, &output_buf_write, 0, NULL);
647 
648  output_buf_write.dstBinding = 5;
649  output_buf_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
650  buf_info.buffer = qvk.buf_sun_color.buffer;
651  buf_info.range = sizeof(SunColorBuffer);
652  vkUpdateDescriptorSets(qvk.device, 1, &output_buf_write, 0, NULL);
653 
654 
655  return VK_SUCCESS;
656 }
657 
658 VkResult
660 {
662  void* mapped = buffer_map(buffer);
663 
664  if (mapped == NULL)
665  return VK_ERROR_MEMORY_MAP_FAILED;
666 
667  memcpy(dst, mapped, sizeof(ReadbackBuffer));
668 
669  buffer_unmap(buffer);
670 
671  return VK_SUCCESS;
672 }
673 
674 VkResult
676 {
677  vkDestroyDescriptorPool(qvk.device, desc_pool_vertex_buffer, NULL);
678  vkDestroyDescriptorSetLayout(qvk.device, qvk.desc_set_layout_vertex_buffer, NULL);
679  desc_pool_vertex_buffer = VK_NULL_HANDLE;
680  qvk.desc_set_layout_vertex_buffer = VK_NULL_HANDLE;
681 
684 
687  for (int frame = 0; frame < MAX_FRAMES_IN_FLIGHT; frame++)
688  {
691  }
692 
695 
696  return VK_SUCCESS;
697 }
698 
700 {
702 
703  // Light statistics: 2 uints (shadowed, unshadowed) per light per surface orientation (6) per cluster.
704  uint32_t num_stats = bsp_mesh->num_clusters * bsp_mesh->num_light_polys * 6 * 2;
705 
706  // Handle rare cases when the map has zero lights
707  if (num_stats == 0)
708  num_stats = 1;
709 
710  for (int frame = 0; frame < NUM_LIGHT_STATS_BUFFERS; frame++)
711  {
712  buffer_create(qvk.buf_light_stats + frame, sizeof(uint32_t) * num_stats,
713  VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
714  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
715  }
716 
717  assert(NUM_LIGHT_STATS_BUFFERS == 3);
718 
719  VkDescriptorBufferInfo light_stats_buf_info[] = { {
720  .buffer = qvk.buf_light_stats[0].buffer,
721  .offset = 0,
722  .range = qvk.buf_light_stats[0].size,
723  }, {
724  .buffer = qvk.buf_light_stats[1].buffer,
725  .offset = 0,
726  .range = qvk.buf_light_stats[1].size,
727  }, {
728  .buffer = qvk.buf_light_stats[2].buffer,
729  .offset = 0,
730  .range = qvk.buf_light_stats[2].size,
731  } };
732 
733  VkWriteDescriptorSet output_buf_write = {
734  .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
735  .dstSet = qvk.desc_set_vertex_buffer,
736  .dstBinding = 6,
737  .dstArrayElement = 0,
738  .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
739  .descriptorCount = LENGTH(light_stats_buf_info),
740  .pBufferInfo = light_stats_buf_info,
741  };
742 
743  vkUpdateDescriptorSets(qvk.device, 1, &output_buf_write, 0, NULL);
744 
745  return VK_SUCCESS;
746 }
747 
749 {
750  for (int frame = 0; frame < NUM_LIGHT_STATS_BUFFERS; frame++)
751  {
753  }
754 
755  return VK_SUCCESS;
756 }
757 
758 VkResult
760 {
764 
765  assert(qvk.desc_set_layout_ubo);
767 
768  VkDescriptorSetLayout desc_set_layouts[] = {
770  };
771 
773  .setLayoutCount = LENGTH(desc_set_layouts),
774  .pSetLayouts = desc_set_layouts,
775  );
776 
777  VkComputePipelineCreateInfo compute_pipeline_info[] = {
778  {
779  .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
780  .stage = SHADER_STAGE(QVK_MOD_INSTANCE_GEOMETRY_COMP, VK_SHADER_STAGE_COMPUTE_BIT),
782  },
783  {
784  .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
785  .stage = SHADER_STAGE(QVK_MOD_ANIMATE_MATERIALS_COMP, VK_SHADER_STAGE_COMPUTE_BIT),
787  },
788  };
789 
790  VkPipeline pipelines[2];
791  _VK(vkCreateComputePipelines(qvk.device, 0, LENGTH(compute_pipeline_info), compute_pipeline_info, 0, pipelines));
792 
795 
796  return VK_SUCCESS;
797 }
798 
799 VkResult
801 {
805 
806  vkDestroyPipeline(qvk.device, pipeline_instance_geometry, NULL);
807  vkDestroyPipeline(qvk.device, pipeline_animate_materials, NULL);
808  vkDestroyPipelineLayout(qvk.device, pipeline_layout_instance_geometry, NULL);
809 
810  pipeline_instance_geometry = VK_NULL_HANDLE;
811  pipeline_animate_materials = VK_NULL_HANDLE;
812  pipeline_layout_instance_geometry = VK_NULL_HANDLE;
813 
814  return VK_SUCCESS;
815 }
816 
817 VkResult
818 vkpt_vertex_buffer_create_instance(VkCommandBuffer cmd_buf, uint32_t num_instances, qboolean update_world_animations)
819 {
820  VkDescriptorSet desc_sets[] = {
823  };
824  vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_instance_geometry);
825  vkCmdBindDescriptorSets(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE,
826  pipeline_layout_instance_geometry, 0, LENGTH(desc_sets), desc_sets, 0, 0);
827 
828  vkCmdDispatch(cmd_buf, num_instances, 1, 1);
829 
830  if (update_world_animations)
831  {
832  vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_animate_materials);
833 
835  vkCmdDispatch(cmd_buf, num_groups, 1, 1);
836  }
837 
838  VkBufferMemoryBarrier barrier = {
839  .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
840  .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
841  .dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
842  .buffer = qvk.buf_vertex.buffer,
843  .size = qvk.buf_vertex.size,
844  .srcQueueFamilyIndex = qvk.queue_idx_graphics,
845  .dstQueueFamilyIndex = qvk.queue_idx_graphics
846  };
847 
848  vkCmdPipelineBarrier(
849  cmd_buf,
850  VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
851  VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
852  0,
853  0, NULL,
854  1, &barrier,
855  0, NULL);
856 
857  return VK_SUCCESS;
858 }
859 
860 // vim: shiftwidth=4 noexpandtab tabstop=4 cindent
QVK_s::desc_set_ubo
VkDescriptorSet desc_set_ubo
Definition: vkpt.h:226
MAX_LIGHT_LIST_NODES
#define MAX_LIGHT_LIST_NODES
Definition: vertex_buffer.h:33
BUFFER_BARRIER
#define BUFFER_BARRIER(cmd_buf,...)
Definition: vk_util.h:68
bsp_mesh_s::num_clusters
int num_clusters
Definition: vkpt.h:366
MAT_GetNumPBRMaterials
int MAT_GetNumPBRMaterials()
Definition: material.c:144
vkpt_readback
VkResult vkpt_readback(ReadbackBuffer *dst)
Definition: vertex_buffer.c:659
SUN_COLOR_UBO_BINDING_IDX
#define SUN_COLOR_UBO_BINDING_IDX
Definition: vertex_buffer.h:50
maliasmesh_s
Definition: gl.h:232
light_poly_s
Definition: vkpt.h:315
CREATE_PIPELINE_LAYOUT
#define CREATE_PIPELINE_LAYOUT(dev, layout,...)
Definition: vk_util.h:82
QVK_s::frame_counter
uint64_t frame_counter
Definition: vkpt.h:212
SUN_COLOR_BUFFER_BINDING_IDX
#define SUN_COLOR_BUFFER_BINDING_IDX
Definition: vertex_buffer.h:49
READBACK_BUFFER_BINDING_IDX
#define READBACK_BUFFER_BINDING_IDX
Definition: vertex_buffer.h:47
max_model_lights
static int max_model_lights
Definition: vertex_buffer.c:129
MAX_VERT_MODEL
#define MAX_VERT_MODEL
Definition: vertex_buffer.h:25
MAX_FRAMES_IN_FLIGHT
#define MAX_FRAMES_IN_FLIGHT
Definition: vkpt.h:140
bsp_mesh_s::sky_visibility
char sky_visibility[VIS_MAX_BYTES]
Definition: vkpt.h:384
vkpt_light_stats_create
VkResult vkpt_light_stats_create(bsp_mesh_t *bsp_mesh)
Definition: vertex_buffer.c:699
precomputed_sky.h
vkpt_vertex_buffer_create_pipelines
VkResult vkpt_vertex_buffer_create_pipelines()
Definition: vertex_buffer.c:759
pbr_material_s::next_frame
int next_frame
Definition: material.h:45
vkpt_vertex_buffer_create
VkResult vkpt_vertex_buffer_create()
Definition: vertex_buffer.c:492
vkpt_vertex_buffer_destroy_pipelines
VkResult vkpt_vertex_buffer_destroy_pipelines()
Definition: vertex_buffer.c:800
QVK_s::buf_tonemap
BufferResource_t buf_tonemap
Definition: vkpt.h:252
bsp_mesh_s::clusters
int * clusters
Definition: vkpt.h:367
vertex_buffer.h
QVK_s::device
VkDevice device
Definition: vkpt.h:172
pbr_material_s::image_normals
image_t * image_normals
Definition: material.h:36
local_light_counts
static int local_light_counts[MAX_MAP_LEAFS]
Definition: vertex_buffer.c:125
Bits::f
float f
Definition: vertex_buffer.c:260
bsp_mesh_s::texel_density
float * texel_density
Definition: vkpt.h:362
bsp_mesh_s
Definition: vkpt.h:343
pbr_material_s::image_emissive
image_t * image_emissive
Definition: material.h:37
pipeline_layout_instance_geometry
static VkPipelineLayout pipeline_layout_instance_geometry
Definition: vertex_buffer.c:33
light_poly_s::color
vec3_t color
Definition: vkpt.h:318
QVK_s::buf_vertex
BufferResource_t buf_vertex
Definition: vkpt.h:243
cluster_debug_mask
char cluster_debug_mask[VIS_MAX_BYTES]
Definition: main.c:83
light_poly_s::material
struct pbr_material_s * material
Definition: vkpt.h:319
buffer_unmap
void buffer_unmap(BufferResource_t *buf)
Definition: vk_util.c:159
bsp_mesh_s::tex_coords
float * tex_coords
Definition: vkpt.h:359
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
LIGHT_POLY_VEC4S
#define LIGHT_POLY_VEC4S
Definition: vertex_buffer.h:36
VERTEX_BUFFER_BINDING_IDX
#define VERTEX_BUFFER_BINDING_IDX
Definition: vertex_buffer.h:45
buffer_destroy
VkResult buffer_destroy(BufferResource_t *buf)
Definition: vk_util.c:132
QVK_s::fence_vertex_sync
VkFence fence_vertex_sync
Definition: vkpt.h:207
light_list_tails
static int light_list_tails[MAX_MAP_LEAFS]
Definition: vertex_buffer.c:127
bsp_mesh_s::num_cluster_lights
int num_cluster_lights
Definition: vkpt.h:369
MAX_IDX_MODEL
#define MAX_IDX_MODEL
Definition: vertex_buffer.h:26
desc_pool_vertex_buffer
static VkDescriptorPool desc_pool_vertex_buffer
Definition: vertex_buffer.c:30
bsp_mesh_s::tangents
float * tangents
Definition: vkpt.h:359
vkpt_light_buffer_upload_staging
VkResult vkpt_light_buffer_upload_staging(VkCommandBuffer cmd_buf)
Definition: vertex_buffer.c:69
TONE_MAPPING_BUFFER_BINDING_IDX
#define TONE_MAPPING_BUFFER_BINDING_IDX
Definition: vertex_buffer.h:48
QVK_s::cmd_buffers_graphics
cmd_buf_group_t cmd_buffers_graphics
Definition: vkpt.h:193
bsp_mesh_s::num_vertices
int num_vertices
Definition: vkpt.h:364
pbr_material_s::specular_scale
float specular_scale
Definition: material.h:40
LIGHT_BUFFER_BINDING_IDX
#define LIGHT_BUFFER_BINDING_IDX
Definition: vertex_buffer.h:46
LightBuffer
struct LightBuffer LightBuffer
Definition: vertex_buffer.h:160
pipeline_instance_geometry
static VkPipeline pipeline_instance_geometry
Definition: vertex_buffer.c:31
vkpt_refdef_s::fd
refdef_t * fd
Definition: vkpt.h:396
cluster_light_counts
static int cluster_light_counts[MAX_MAP_LEAFS]
Definition: vertex_buffer.c:126
_VK
#define _VK(...)
Definition: vkpt.h:65
vkpt_refdef_s::bsp_mesh_world
bsp_mesh_t bsp_mesh_world
Definition: vkpt.h:406
vkpt_light_buffer_reset_counts
void vkpt_light_buffer_reset_counts()
Definition: vertex_buffer.c:131
bsp_mesh_s::cluster_lights
int * cluster_lights
Definition: vkpt.h:371
pbr_material_s::emissive_scale
float emissive_scale
Definition: material.h:41
bsp_mesh_s::cluster_light_offsets
int * cluster_light_offsets
Definition: vkpt.h:370
pbr_material_s::bump_scale
float bump_scale
Definition: material.h:38
QVK_s::queue_idx_graphics
int32_t queue_idx_graphics
Definition: vkpt.h:176
QVK_s::desc_set_vertex_buffer
VkDescriptorSet desc_set_vertex_buffer
Definition: vkpt.h:241
pbr_material_s::num_frames
int num_frames
Definition: material.h:44
material.h
vkpt_refdef_s::prev_lightstyles
lightstyle_t prev_lightstyles[MAX_LIGHTSTYLES]
Definition: vkpt.h:409
ToneMappingBuffer
Definition: vertex_buffer.h:116
pbr_material_s
Definition: material.h:33
vkpt_light_buffer_upload_to_staging
VkResult vkpt_light_buffer_upload_to_staging(qboolean render_world, bsp_mesh_t *bsp_mesh, bsp_t *bsp, int num_model_lights, light_poly_t *transformed_model_lights, const float *sky_radiance)
Definition: vertex_buffer.c:310
ToneMappingBuffer
struct ToneMappingBuffer ToneMappingBuffer
Definition: vertex_buffer.h:162
QVK_s::buf_sun_color
BufferResource_t buf_sun_color
Definition: vkpt.h:253
MAX_VERT_BSP
#define MAX_VERT_BSP
Definition: vertex_buffer.h:23
BufferResource_s::buffer
VkBuffer buffer
Definition: vk_util.h:34
m
static struct mdfour * m
Definition: mdfour.c:32
pipeline_animate_materials
static VkPipeline pipeline_animate_materials
Definition: vertex_buffer.c:32
bsp_mesh_s::materials
uint32_t * materials
Definition: vkpt.h:361
r_images
image_t r_images[MAX_RIMAGES]
Definition: images.c:651
max_cluster_model_lights
static int max_cluster_model_lights[MAX_MAP_LEAFS]
Definition: vertex_buffer.c:128
MAX_LIGHT_LISTS
#define MAX_LIGHT_LISTS
Definition: vertex_buffer.h:32
vkpt_refdef
vkpt_refdef_t vkpt_refdef
Definition: main.c:372
light_poly_s::style
int style
Definition: vkpt.h:321
ReadbackBuffer
Definition: vertex_buffer.h:134
Bits::ui
uint32_t ui
Definition: vertex_buffer.c:262
pipelines
VkPipeline pipelines[2]
Definition: god_rays.c:28
LENGTH
#define LENGTH(a)
Definition: tent.c:228
pbr_material_s::image_diffuse
image_t * image_diffuse
Definition: material.h:35
MAT_GetPBRMaterialsTable
const pbr_material_t * MAT_GetPBRMaterialsTable()
Definition: material.c:139
NUM_LIGHT_STATS_BUFFERS
#define NUM_LIGHT_STATS_BUFFERS
Definition: constants.h:44
vkpt_vertex_buffer_upload_bsp_mesh_to_staging
VkResult vkpt_vertex_buffer_upload_bsp_mesh_to_staging(bsp_mesh_t *bsp_mesh)
Definition: vertex_buffer.c:90
VertexBuffer
struct VertexBuffer VertexBuffer
Definition: vertex_buffer.h:159
MAX_LIGHT_POLYS
#define MAX_LIGHT_POLYS
Definition: vertex_buffer.h:35
vkpt_vertex_buffer_create_instance
VkResult vkpt_vertex_buffer_create_instance(VkCommandBuffer cmd_buf, uint32_t num_instances, qboolean update_world_animations)
Definition: vertex_buffer.c:818
LIGHT_STATS_BUFFER_BINDING_IDX
#define LIGHT_STATS_BUFFER_BINDING_IDX
Definition: vertex_buffer.h:51
MAX_PBR_MATERIALS
#define MAX_PBR_MATERIALS
Definition: material.h:25
qvk
QVK_t qvk
Definition: main.c:377
Bits
Definition: vertex_buffer.c:258
QVK_s::buf_light
BufferResource_t buf_light
Definition: vkpt.h:245
bsp_mesh_s::world_transparent_count
uint32_t world_transparent_count
Definition: vkpt.h:351
inject_model_lights
void inject_model_lights(bsp_mesh_t *bsp_mesh, bsp_t *bsp, int num_model_lights, light_poly_t *transformed_model_lights, int model_light_offset, uint32_t *dst_list_offsets, uint32_t *dst_lists)
Definition: vertex_buffer.c:138
c
statCounters_t c
Definition: main.c:30
num_model_lights
static int num_model_lights
Definition: main.c:1266
bsp_mesh_s::light_polys
light_poly_t * light_polys
Definition: vkpt.h:375
ReadbackBuffer
struct ReadbackBuffer ReadbackBuffer
Definition: vertex_buffer.h:161
SHADER_STAGE
#define SHADER_STAGE(_module, _stage)
Definition: vkpt.h:116
bsp_mesh_s::num_light_polys
int num_light_polys
Definition: vkpt.h:373
BufferResource_s::is_mapped
int is_mapped
Definition: vk_util.h:37
SunColorBuffer
struct SunColorBuffer SunColorBuffer
Definition: vertex_buffer.h:163
BufferResource_s
Definition: vk_util.h:33
bsp_mesh_s::positions
float * positions
Definition: vkpt.h:359
QVK_s::buf_light_staging
BufferResource_t buf_light_staging[MAX_FRAMES_IN_FLIGHT]
Definition: vkpt.h:246
LightBuffer
Definition: vertex_buffer.h:106
VertexBuffer
Definition: vertex_buffer.h:96
buffer_create
VkResult buffer_create(BufferResource_t *buf, VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags mem_properties)
Definition: vk_util.c:57
vkpt_vertex_buffer_upload_staging
VkResult vkpt_vertex_buffer_upload_staging()
Definition: vertex_buffer.c:36
bsp_mesh_s::world_idx_count
uint32_t world_idx_count
Definition: vkpt.h:344
copy_light
static void copy_light(const light_poly_t *light, float *vblight, const float *sky_radiance)
Definition: vertex_buffer.c:215
vkpt_vertex_buffer_upload_models_to_staging
VkResult vkpt_vertex_buffer_upload_models_to_staging()
Definition: vertex_buffer.c:412
vkpt_begin_command_buffer
VkCommandBuffer vkpt_begin_command_buffer(cmd_buf_group_t *group)
Definition: main.c:3301
MAX_LIGHT_STYLES
#define MAX_LIGHT_STYLES
Definition: constants.h:105
QVK_s::buf_light_stats
BufferResource_t buf_light_stats[NUM_LIGHT_STATS_BUFFERS]
Definition: vkpt.h:247
floatToHalf
static uint16_t floatToHalf(float value)
Definition: vertex_buffer.c:265
QVK_s::desc_set_layout_ubo
VkDescriptorSetLayout desc_set_layout_ubo
Definition: vkpt.h:225
QVK_s::buf_readback_staging
BufferResource_t buf_readback_staging[MAX_FRAMES_IN_FLIGHT]
Definition: vkpt.h:250
pbr_material_s::rough_override
float rough_override
Definition: material.h:39
BSP_GetPvs
char * BSP_GetPvs(bsp_t *bsp, int cluster)
Definition: bsp.c:974
buffer_map
void * buffer_map(BufferResource_t *buf)
Definition: vk_util.c:147
SunColorBuffer
Definition: vertex_buffer.h:144
BufferResource_s::size
size_t size
Definition: vk_util.h:36
vkpt_vertex_buffer_destroy
VkResult vkpt_vertex_buffer_destroy()
Definition: vertex_buffer.c:675
vkpt_refdef_s
Definition: vkpt.h:393
vkpt_submit_command_buffer
void vkpt_submit_command_buffer(VkCommandBuffer cmd_buf, VkQueue queue, uint32_t execute_device_mask, int wait_semaphore_count, VkSemaphore *wait_semaphores, VkPipelineStageFlags *wait_stages, uint32_t *wait_device_indices, int signal_semaphore_count, VkSemaphore *signal_semaphores, uint32_t *signal_device_indices, VkFence fence)
Definition: main.c:3411
vkpt_light_stats_destroy
VkResult vkpt_light_stats_destroy()
Definition: vertex_buffer.c:748
light_poly_s::cluster
int cluster
Definition: vkpt.h:320
QVK_s::buf_vertex_staging
BufferResource_t buf_vertex_staging
Definition: vkpt.h:244
QVK_s::queue_graphics
VkQueue queue_graphics
Definition: vkpt.h:173
QVK_s::device_count
int device_count
Definition: vkpt.h:167
light_poly_s::positions
float positions[9]
Definition: vkpt.h:316
QVK_s::desc_set_layout_vertex_buffer
VkDescriptorSetLayout desc_set_layout_vertex_buffer
Definition: vkpt.h:240
Bits::si
int32_t si
Definition: vertex_buffer.c:261
r_models
model_t r_models[MAX_RMODELS]
Definition: models.c:39