Quake II RTX doxygen  1.0 dev
bloom.c
Go to the documentation of this file.
1 /*
2 Copyright (C) 2019, NVIDIA CORPORATION. All rights reserved.
3 
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18 
19 #include "vkpt.h"
20 #include "system/system.h"
21 
22 enum {
25 
27 };
28 
29 static VkPipeline pipelines[BLOOM_NUM_PIPELINES];
30 static VkPipelineLayout pipeline_layout_blur;
31 static VkPipelineLayout pipeline_layout_composite;
32 
34  float pixstep_x;
35  float pixstep_y;
39  int pass;
40 };
41 
44 
45 cvar_t *cvar_bloom_enable = NULL;
46 cvar_t *cvar_bloom_debug = NULL;
47 cvar_t *cvar_bloom_sigma = NULL;
48 cvar_t *cvar_bloom_intensity = NULL;
49 cvar_t *cvar_bloom_sigma_water = NULL;
51 
52 static float bloom_intensity;
53 static float bloom_sigma;
54 static float under_water_animation;
55 
57 {
58  float sigma_pixels = bloom_sigma * qvk.extent_render.height;
59 
60  float effective_sigma = sigma_pixels * 0.25f;
61  effective_sigma = min(effective_sigma, 100.f);
62  effective_sigma = max(effective_sigma, 1.f);
63 
66  push_constants_hblur.argument_scale = -1.f / (2.0 * effective_sigma * effective_sigma);
67  push_constants_hblur.normalization_scale = 1.f / (sqrtf(2 * M_PI) * effective_sigma);
68  push_constants_hblur.num_samples = roundf(effective_sigma * 4.f);
70 
75 }
77 {
81 }
82 
83 static float mix(float a, float b, float s)
84 {
85  return a * (1.f - s) + b * s;
86 }
87 
88 void vkpt_bloom_update(QVKUniformBuffer_t * ubo, float frame_time, qboolean under_water, qboolean menu_mode)
89 {
90  if (under_water)
91  {
92  under_water_animation = min(1.f, under_water_animation + frame_time * 3.f);
95  }
96  else
97  {
98  under_water_animation = max(0.f, under_water_animation - frame_time * 3.f);
101  }
102 
103  static int menu_start_ms = -1;
104 
105  if (menu_mode)
106  {
107  if (menu_start_ms < 0)
108  menu_start_ms = Sys_Milliseconds();
109  int current_ms = Sys_Milliseconds();
110 
111  float phase = max(0.f, min(1.f, (float)(current_ms - menu_start_ms) / 150.f));
112  phase = powf(phase, 0.25f);
113 
114  bloom_sigma = phase * 0.03f;
115 
116  ubo->bloom_intensity = 1.f;
117  }
118  else
119  {
120  menu_start_ms = -1;
121 
122  ubo->bloom_intensity = bloom_intensity;
123  }
124 }
125 
126 VkResult
128 {
129  cvar_bloom_enable = Cvar_Get("bloom_enable", "1", 0);
130  cvar_bloom_debug = Cvar_Get("bloom_debug", "0", 0);
131  cvar_bloom_sigma = Cvar_Get("bloom_sigma", "0.037", 0); // relative to screen height
132  cvar_bloom_intensity = Cvar_Get("bloom_intensity", "0.002", 0);
133  cvar_bloom_sigma_water = Cvar_Get("bloom_sigma_water", "0.037", 0);
134  cvar_bloom_intensity_water = Cvar_Get("bloom_intensity_water", "0.2", 0);
135 
136  VkDescriptorSetLayout desc_set_layouts[] = {
139  };
140 
141  VkPushConstantRange push_constant_range = {
142  .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
143  .offset = 0,
144  .size = sizeof(push_constants_hblur)
145  };
146 
148  .setLayoutCount = LENGTH(desc_set_layouts),
149  .pSetLayouts = desc_set_layouts,
150  .pushConstantRangeCount = 1,
151  .pPushConstantRanges = &push_constant_range
152  );
154 
156  .setLayoutCount = LENGTH(desc_set_layouts),
157  .pSetLayouts = desc_set_layouts,
158  );
160 
161  return VK_SUCCESS;
162 }
163 
164 VkResult
166 {
167  vkDestroyPipelineLayout(qvk.device, pipeline_layout_blur, NULL);
168  pipeline_layout_blur = NULL;
169  vkDestroyPipelineLayout(qvk.device, pipeline_layout_composite, NULL);
171 
172  return VK_SUCCESS;
173 }
174 
175 VkResult
177 {
178  VkComputePipelineCreateInfo pipeline_info[BLOOM_NUM_PIPELINES] = {
179  [BLUR] = {
180  .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
181  .stage = SHADER_STAGE(QVK_MOD_BLOOM_BLUR_COMP, VK_SHADER_STAGE_COMPUTE_BIT),
182  .layout = pipeline_layout_blur,
183  },
184  [COMPOSITE] = {
185  .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
186  .stage = SHADER_STAGE(QVK_MOD_BLOOM_COMPOSITE_COMP, VK_SHADER_STAGE_COMPUTE_BIT),
187  .layout = pipeline_layout_composite,
188  }
189  };
190 
191  _VK(vkCreateComputePipelines(qvk.device, 0, LENGTH(pipeline_info), pipeline_info, 0, pipelines));
192  return VK_SUCCESS;
193 }
194 
195 VkResult
197 {
198  for(int i = 0; i < BLOOM_NUM_PIPELINES; i++)
199  vkDestroyPipeline(qvk.device, pipelines[i], NULL);
200 
201  return VK_SUCCESS;
202 }
203 
204 
205 #define BARRIER_COMPUTE(cmd_buf, img) \
206  do { \
207  VkImageSubresourceRange subresource_range = { \
208  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, \
209  .baseMipLevel = 0, \
210  .levelCount = 1, \
211  .baseArrayLayer = 0, \
212  .layerCount = 1 \
213  }; \
214  IMAGE_BARRIER(cmd_buf, \
215  .image = img, \
216  .subresourceRange = subresource_range, \
217  .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, \
218  .dstAccessMask = VK_ACCESS_SHADER_READ_BIT, \
219  .oldLayout = VK_IMAGE_LAYOUT_GENERAL, \
220  .newLayout = VK_IMAGE_LAYOUT_GENERAL, \
221  ); \
222  } while(0)
223 
224 #define BARRIER_TO_COPY_DEST(cmd_buf, img) \
225  do { \
226  VkImageSubresourceRange subresource_range = { \
227  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, \
228  .baseMipLevel = 0, \
229  .levelCount = 1, \
230  .baseArrayLayer = 0, \
231  .layerCount = 1 \
232  }; \
233  IMAGE_BARRIER(cmd_buf, \
234  .image = img, \
235  .subresourceRange = subresource_range, \
236  .srcAccessMask = 0, \
237  .dstAccessMask = 0, \
238  .oldLayout = VK_IMAGE_LAYOUT_GENERAL, \
239  .newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, \
240  ); \
241  } while(0)
242 
243 #define BARRIER_FROM_COPY_DEST(cmd_buf, img) \
244  do { \
245  VkImageSubresourceRange subresource_range = { \
246  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, \
247  .baseMipLevel = 0, \
248  .levelCount = 1, \
249  .baseArrayLayer = 0, \
250  .layerCount = 1 \
251  }; \
252  IMAGE_BARRIER(cmd_buf, \
253  .image = img, \
254  .subresourceRange = subresource_range, \
255  .srcAccessMask = 0, \
256  .dstAccessMask = VK_ACCESS_SHADER_READ_BIT, \
257  .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, \
258  .newLayout = VK_IMAGE_LAYOUT_GENERAL, \
259  ); \
260  } while(0)
261 
262 #define BARRIER_TO_COPY_SRC(cmd_buf, img) \
263  do { \
264  VkImageSubresourceRange subresource_range = { \
265  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, \
266  .baseMipLevel = 0, \
267  .levelCount = 1, \
268  .baseArrayLayer = 0, \
269  .layerCount = 1 \
270  }; \
271  IMAGE_BARRIER(cmd_buf, \
272  .image = img, \
273  .subresourceRange = subresource_range, \
274  .srcAccessMask = 0, \
275  .dstAccessMask = 0, \
276  .oldLayout = VK_IMAGE_LAYOUT_GENERAL, \
277  .newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, \
278  ); \
279  } while(0)
280 
281 #define BARRIER_FROM_COPY_SRC(cmd_buf, img) \
282  do { \
283  VkImageSubresourceRange subresource_range = { \
284  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, \
285  .baseMipLevel = 0, \
286  .levelCount = 1, \
287  .baseArrayLayer = 0, \
288  .layerCount = 1 \
289  }; \
290  IMAGE_BARRIER(cmd_buf, \
291  .image = img, \
292  .subresourceRange = subresource_range, \
293  .srcAccessMask = 0, \
294  .dstAccessMask = VK_ACCESS_SHADER_READ_BIT, \
295  .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, \
296  .newLayout = VK_IMAGE_LAYOUT_GENERAL, \
297  ); \
298  } while(0)
299 
300 VkResult
301 vkpt_bloom_record_cmd_buffer(VkCommandBuffer cmd_buf)
302 {
304 
305  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_TAA_OUTPUT]);
306 
307  // downscale TAA_OUTPUT -> BLOOM_DOWNSCALE_MIP_1 -> BLOOM_VBLUR
308  {
309  VkImageSubresourceLayers subresource = {
310  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
311  .mipLevel = 0,
312  .baseArrayLayer = 0,
313  .layerCount = 1
314  };
315 
316  VkOffset3D offset_UL = {
317  .x = 0,
318  .y = 0,
319  .z = 0
320  };
321 
322  VkOffset3D offset_LR_mip_0 = {
323  .x = qvk.extent_screen_images.width,
324  .y = qvk.extent_screen_images.height,
325  .z = 1
326  };
327 
328  VkOffset3D offset_LR_mip_1 = {
329  .x = qvk.extent_screen_images.width / 2,
330  .y = qvk.extent_screen_images.height / 2,
331  .z = 1
332  };
333 
334  VkOffset3D offset_LR_mip_2 = {
335  .x = qvk.extent_screen_images.width / 4,
336  .y = qvk.extent_screen_images.height / 4,
337  .z = 1
338  };
339 
340  VkImageBlit blit_mip_0_to_1 = {
341  .srcSubresource = subresource,
342  .srcOffsets[0] = offset_UL,
343  .srcOffsets[1] = offset_LR_mip_0,
344  .dstSubresource = subresource,
345  .dstOffsets[0] = offset_UL,
346  .dstOffsets[1] = offset_LR_mip_1,
347  };
348 
349  VkImageBlit blit_mip_1_to_2 = {
350  .srcSubresource = subresource,
351  .srcOffsets[0] = offset_UL,
352  .srcOffsets[1] = offset_LR_mip_1,
353  .dstSubresource = subresource,
354  .dstOffsets[0] = offset_UL,
355  .dstOffsets[1] = offset_LR_mip_2,
356  };
357 
358  BARRIER_TO_COPY_SRC(cmd_buf, qvk.images[VKPT_IMG_TAA_OUTPUT]);
359  BARRIER_TO_COPY_DEST(cmd_buf, qvk.images[VKPT_IMG_BLOOM_DOWNSCALE_MIP_1]);
360 
361  vkCmdBlitImage(cmd_buf,
362  qvk.images[VKPT_IMG_TAA_OUTPUT], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
363  qvk.images[VKPT_IMG_BLOOM_DOWNSCALE_MIP_1], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
364  1, &blit_mip_0_to_1, VK_FILTER_LINEAR);
365 
366  BARRIER_FROM_COPY_SRC(cmd_buf, qvk.images[VKPT_IMG_TAA_OUTPUT]);
367  BARRIER_FROM_COPY_DEST(cmd_buf, qvk.images[VKPT_IMG_BLOOM_DOWNSCALE_MIP_1]);
368 
369  BARRIER_TO_COPY_SRC(cmd_buf, qvk.images[VKPT_IMG_BLOOM_DOWNSCALE_MIP_1]);
370  BARRIER_TO_COPY_DEST(cmd_buf, qvk.images[VKPT_IMG_BLOOM_VBLUR]);
371 
372  vkCmdBlitImage(cmd_buf,
373  qvk.images[VKPT_IMG_BLOOM_DOWNSCALE_MIP_1], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
374  qvk.images[VKPT_IMG_BLOOM_VBLUR], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
375  1, &blit_mip_1_to_2, VK_FILTER_LINEAR);
376 
377  BARRIER_FROM_COPY_SRC(cmd_buf, qvk.images[VKPT_IMG_BLOOM_DOWNSCALE_MIP_1]);
378  BARRIER_FROM_COPY_DEST(cmd_buf, qvk.images[VKPT_IMG_BLOOM_VBLUR]);
379  }
380 
381  VkDescriptorSet desc_sets[] = {
385  };
386 
387  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_BLOOM_VBLUR]);
388  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_BLOOM_HBLUR]);
389 
390  // apply horizontal blur from BLOOM_VBLUR -> BLOOM_HBLUR
391  vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE, pipelines[BLUR]);
392  vkCmdBindDescriptorSets(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE,
393  pipeline_layout_blur, 0, LENGTH(desc_sets), desc_sets, 0, 0);
394 
395  vkCmdPushConstants(cmd_buf, pipeline_layout_blur, VK_SHADER_STAGE_COMPUTE_BIT,
397  vkCmdDispatch(cmd_buf,
398  (qvk.extent_render.width / 4 + 15) / 16,
399  (qvk.extent_render.height / 4 + 15) / 16,
400  1);
401 
402  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_BLOOM_HBLUR]);
403 
404  // vertical blur from BLOOM_HBLUR -> BLOOM_VBLUR
405  vkCmdPushConstants(cmd_buf, pipeline_layout_blur, VK_SHADER_STAGE_COMPUTE_BIT,
407  vkCmdDispatch(cmd_buf,
408  (qvk.extent_render.width / 4 + 15) / 16,
409  (qvk.extent_render.height / 4 + 15) / 16,
410  1);
411 
412  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_BLOOM_VBLUR]);
413 
414  if (cvar_bloom_debug->integer)
415  {
416  VkImageSubresourceLayers subresource = {
417  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
418  .mipLevel = 0,
419  .baseArrayLayer = 0,
420  .layerCount = 1
421  };
422 
423  VkOffset3D offset_UL = {
424  .x = 0,
425  .y = 0,
426  .z = 0
427  };
428 
429  VkOffset3D offset_LR_input = {
430  .x = IMG_WIDTH,
431  .y = IMG_HEIGHT,
432  .z = 1
433  };
434 
435  VkImageBlit blit_region = {
436  .srcSubresource = subresource,
437  .srcOffsets[0] = offset_UL,
438  .dstSubresource = subresource,
439  .dstOffsets[0] = offset_UL,
440  .dstOffsets[1] = offset_LR_input,
441  };
442 
443  BARRIER_TO_COPY_DEST(cmd_buf, qvk.images[VKPT_IMG_TAA_OUTPUT]);
444 
445  int vis_img;
446  switch(cvar_bloom_debug->integer)
447  {
448  case 1:
449  vis_img = VKPT_IMG_BLOOM_DOWNSCALE_MIP_1;
450  blit_region.srcOffsets[1].x = IMG_WIDTH / 2;
451  blit_region.srcOffsets[1].y = IMG_HEIGHT / 2;
452  break;
453 
454  case 2:
455  vis_img = VKPT_IMG_BLOOM_HBLUR;
456  blit_region.srcOffsets[1].x = IMG_WIDTH / 4;
457  blit_region.srcOffsets[1].y = IMG_HEIGHT / 4;
458  break;
459 
460  default:
461  vis_img = VKPT_IMG_BLOOM_VBLUR;
462  blit_region.srcOffsets[1].x = IMG_WIDTH / 4;
463  blit_region.srcOffsets[1].y = IMG_HEIGHT / 4;
464  break;
465  }
466 
467  vkCmdBlitImage(cmd_buf,
468  qvk.images[vis_img], VK_IMAGE_LAYOUT_GENERAL,
469  qvk.images[VKPT_IMG_TAA_OUTPUT], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
470  1, &blit_region, VK_FILTER_LINEAR);
471 
472  BARRIER_FROM_COPY_DEST(cmd_buf, qvk.images[VKPT_IMG_TAA_OUTPUT]);
473  } else {
474  // composite bloom into TAA_OUTPUT
475  vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE, pipelines[COMPOSITE]);
476  vkCmdBindDescriptorSets(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE,
477  pipeline_layout_composite, 0, LENGTH(desc_sets), desc_sets, 0, 0);
478  vkCmdDispatch(cmd_buf,
479  (qvk.extent_render.width + 15) / 16,
480  (qvk.extent_render.height + 15) / 16,
481  1);
482  }
483 
484  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_BLOOM_VBLUR]);
485  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_TAA_OUTPUT]);
486 
487 
488  return VK_SUCCESS;
489 }
QVK_s::desc_set_ubo
VkDescriptorSet desc_set_ubo
Definition: vkpt.h:226
cvar_bloom_sigma_water
cvar_t * cvar_bloom_sigma_water
Definition: bloom.c:49
QVKUniformBuffer_s
Definition: global_ubo.h:247
CREATE_PIPELINE_LAYOUT
#define CREATE_PIPELINE_LAYOUT(dev, layout,...)
Definition: vk_util.h:82
bloom_blur_push_constants::argument_scale
float argument_scale
Definition: bloom.c:36
BARRIER_FROM_COPY_DEST
#define BARRIER_FROM_COPY_DEST(cmd_buf, img)
Definition: bloom.c:243
QVK_s::device
VkDevice device
Definition: vkpt.h:172
pipeline_layout_blur
static VkPipelineLayout pipeline_layout_blur
Definition: bloom.c:30
Cvar_Get
cvar_t * Cvar_Get(const char *var_name, const char *var_value, int flags)
Definition: cvar.c:257
BLUR
@ BLUR
Definition: bloom.c:23
vkpt.h
push_constants_hblur
static struct bloom_blur_push_constants push_constants_hblur
Definition: bloom.c:42
BARRIER_COMPUTE
#define BARRIER_COMPUTE(cmd_buf, img)
Definition: bloom.c:205
bloom_blur_push_constants
Definition: bloom.c:33
cvar_bloom_intensity
cvar_t * cvar_bloom_intensity
Definition: bloom.c:48
bloom_intensity
static float bloom_intensity
Definition: bloom.c:52
Sys_Milliseconds
unsigned Sys_Milliseconds(void)
Definition: system.c:644
under_water_animation
static float under_water_animation
Definition: bloom.c:54
vkpt_bloom_initialize
VkResult vkpt_bloom_initialize()
Definition: bloom.c:127
_VK
#define _VK(...)
Definition: vkpt.h:65
bloom_blur_push_constants::num_samples
int num_samples
Definition: bloom.c:38
QVK_s::extent_screen_images
VkExtent2D extent_screen_images
Definition: vkpt.h:183
QVK_s::desc_set_vertex_buffer
VkDescriptorSet desc_set_vertex_buffer
Definition: vkpt.h:241
mix
static float mix(float a, float b, float s)
Definition: bloom.c:83
vkpt_bloom_create_pipelines
VkResult vkpt_bloom_create_pipelines()
Definition: bloom.c:176
BLOOM_NUM_PIPELINES
@ BLOOM_NUM_PIPELINES
Definition: bloom.c:26
cvar_bloom_intensity_water
cvar_t * cvar_bloom_intensity_water
Definition: bloom.c:50
IMG_WIDTH
#define IMG_WIDTH
Definition: global_textures.h:25
bloom_blur_push_constants::pixstep_x
float pixstep_x
Definition: bloom.c:34
QVK_s::images
VkImage images[NUM_VKPT_IMAGES]
Definition: vkpt.h:231
IMG_HEIGHT
#define IMG_HEIGHT
Definition: global_textures.h:26
BARRIER_TO_COPY_SRC
#define BARRIER_TO_COPY_SRC(cmd_buf, img)
Definition: bloom.c:262
LENGTH
#define LENGTH(a)
Definition: tent.c:228
bloom_blur_push_constants::pass
int pass
Definition: bloom.c:39
bloom_sigma
static float bloom_sigma
Definition: bloom.c:53
cvar_bloom_debug
cvar_t * cvar_bloom_debug
Definition: bloom.c:46
pipelines
static VkPipeline pipelines[BLOOM_NUM_PIPELINES]
Definition: bloom.c:29
push_constants_vblur
static struct bloom_blur_push_constants push_constants_vblur
Definition: bloom.c:43
qvk
QVK_t qvk
Definition: main.c:377
SHADER_STAGE
#define SHADER_STAGE(_module, _stage)
Definition: vkpt.h:116
vkpt_bloom_record_cmd_buffer
VkResult vkpt_bloom_record_cmd_buffer(VkCommandBuffer cmd_buf)
Definition: bloom.c:301
COMPOSITE
@ COMPOSITE
Definition: bloom.c:24
QVK_s::extent_render
VkExtent2D extent_render
Definition: vkpt.h:184
BARRIER_FROM_COPY_SRC
#define BARRIER_FROM_COPY_SRC(cmd_buf, img)
Definition: bloom.c:281
vkpt_bloom_destroy_pipelines
VkResult vkpt_bloom_destroy_pipelines()
Definition: bloom.c:196
cvar_bloom_sigma
cvar_t * cvar_bloom_sigma
Definition: bloom.c:47
bloom_blur_push_constants::pixstep_y
float pixstep_y
Definition: bloom.c:35
pipeline_layout_composite
static VkPipelineLayout pipeline_layout_composite
Definition: bloom.c:31
cvar_bloom_enable
cvar_t * cvar_bloom_enable
Definition: bloom.c:45
bloom_blur_push_constants::normalization_scale
float normalization_scale
Definition: bloom.c:37
ATTACH_LABEL_VARIABLE
#define ATTACH_LABEL_VARIABLE(a, type)
Definition: vk_util.h:137
QVK_s::desc_set_layout_textures
VkDescriptorSetLayout desc_set_layout_textures
Definition: vkpt.h:228
QVK_s::desc_set_layout_ubo
VkDescriptorSetLayout desc_set_layout_ubo
Definition: vkpt.h:225
vkpt_bloom_update
void vkpt_bloom_update(QVKUniformBuffer_t *ubo, float frame_time, qboolean under_water, qboolean menu_mode)
Definition: bloom.c:88
vkpt_bloom_destroy
VkResult vkpt_bloom_destroy()
Definition: bloom.c:165
compute_push_constants
static void compute_push_constants()
Definition: bloom.c:56
qvk_get_current_desc_set_textures
VkDescriptorSet qvk_get_current_desc_set_textures()
Definition: main.c:1847
BARRIER_TO_COPY_DEST
#define BARRIER_TO_COPY_DEST(cmd_buf, img)
Definition: bloom.c:224
QVK_s::desc_set_layout_vertex_buffer
VkDescriptorSetLayout desc_set_layout_vertex_buffer
Definition: vkpt.h:240
vkpt_bloom_reset
void vkpt_bloom_reset()
Definition: bloom.c:76