Quake II RTX doxygen  1.0 dev
asvgf.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 enum {
33  TAA,
37 };
38 
40 static VkPipelineLayout pipeline_layout_atrous;
41 static VkPipelineLayout pipeline_layout_general;
42 static VkPipelineLayout pipeline_layout_taa;
43 
44 VkResult
46 {
47  VkDescriptorSetLayout desc_set_layouts[] = {
50  };
51 
52  VkPushConstantRange push_constant_range_atrous = {
53  .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
54  .offset = 0,
55  .size = sizeof(uint32_t)
56  };
57 
59  .setLayoutCount = LENGTH(desc_set_layouts),
60  .pSetLayouts = desc_set_layouts,
61  .pushConstantRangeCount = 1,
62  .pPushConstantRanges = &push_constant_range_atrous
63  );
65 
67  .setLayoutCount = LENGTH(desc_set_layouts),
68  .pSetLayouts = desc_set_layouts,
69  );
71 
73  .setLayoutCount = LENGTH(desc_set_layouts),
74  .pSetLayouts = desc_set_layouts,
75  );
77  return VK_SUCCESS;
78 }
79 
80 VkResult
82 {
83  vkDestroyPipelineLayout(qvk.device, pipeline_layout_atrous, NULL);
84  vkDestroyPipelineLayout(qvk.device, pipeline_layout_general, NULL);
85  vkDestroyPipelineLayout(qvk.device, pipeline_layout_taa, NULL);
86 
87  return VK_SUCCESS;
88 }
89 
90 VkResult
92 {
93  VkSpecializationMapEntry specEntries[] = {
94  { .constantID = 0, .offset = 0, .size = sizeof(uint32_t) }
95  };
96 
97  uint32_t spec_data[] = {
98  0,
99  1,
100  2,
101  3
102  };
103 
104  VkSpecializationInfo specInfo[] = {
105  { .mapEntryCount = 1, .pMapEntries = specEntries, .dataSize = sizeof(uint32_t), .pData = &spec_data[0] },
106  { .mapEntryCount = 1, .pMapEntries = specEntries, .dataSize = sizeof(uint32_t), .pData = &spec_data[1] },
107  { .mapEntryCount = 1, .pMapEntries = specEntries, .dataSize = sizeof(uint32_t), .pData = &spec_data[2] },
108  { .mapEntryCount = 1, .pMapEntries = specEntries, .dataSize = sizeof(uint32_t), .pData = &spec_data[3] },
109  };
110 
111  VkComputePipelineCreateInfo pipeline_info[ASVGF_NUM_PIPELINES] = {
112  [SEED_RNG] = {
113  .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
114  .stage = SHADER_STAGE(QVK_MOD_ASVGF_SEED_RNG_COMP, VK_SHADER_STAGE_COMPUTE_BIT),
115  .layout = pipeline_layout_atrous,
116  },
117  [FWD_PROJECT] = {
118  .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
119  .stage = SHADER_STAGE(QVK_MOD_ASVGF_FWD_PROJECT_COMP, VK_SHADER_STAGE_COMPUTE_BIT),
120  .layout = pipeline_layout_general,
121  },
122  [GRADIENT_IMAGE] = {
123  .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
124  .stage = SHADER_STAGE(QVK_MOD_ASVGF_GRADIENT_IMG_COMP, VK_SHADER_STAGE_COMPUTE_BIT),
125  .layout = pipeline_layout_general,
126  },
127  [GRADIENT_ATROUS] = {
128  .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
129  .stage = SHADER_STAGE(QVK_MOD_ASVGF_GRADIENT_ATROUS_COMP, VK_SHADER_STAGE_COMPUTE_BIT),
130  .layout = pipeline_layout_atrous,
131  },
132  [TEMPORAL] = {
133  .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
134  .stage = SHADER_STAGE(QVK_MOD_ASVGF_TEMPORAL_COMP, VK_SHADER_STAGE_COMPUTE_BIT),
135  .layout = pipeline_layout_general,
136  },
137  [ATROUS_LF] = {
138  .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
139  .stage = SHADER_STAGE(QVK_MOD_ASVGF_LF_COMP, VK_SHADER_STAGE_COMPUTE_BIT),
140  .layout = pipeline_layout_atrous,
141  },
142  [ATROUS_ITER_0] = {
143  .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
144  .stage = SHADER_STAGE_SPEC(QVK_MOD_ASVGF_ATROUS_COMP, VK_SHADER_STAGE_COMPUTE_BIT, &specInfo[0]),
145  .layout = pipeline_layout_atrous,
146  },
147  [ATROUS_ITER_1] = {
148  .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
149  .stage = SHADER_STAGE_SPEC(QVK_MOD_ASVGF_ATROUS_COMP, VK_SHADER_STAGE_COMPUTE_BIT, &specInfo[1]),
150  .layout = pipeline_layout_atrous,
151  },
152  [ATROUS_ITER_2] = {
153  .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
154  .stage = SHADER_STAGE_SPEC(QVK_MOD_ASVGF_ATROUS_COMP, VK_SHADER_STAGE_COMPUTE_BIT, &specInfo[2]),
155  .layout = pipeline_layout_atrous,
156  },
157  [ATROUS_ITER_3] = {
158  .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
159  .stage = SHADER_STAGE_SPEC(QVK_MOD_ASVGF_ATROUS_COMP, VK_SHADER_STAGE_COMPUTE_BIT, &specInfo[3]),
160  .layout = pipeline_layout_atrous,
161  },
163  .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
164  .stage = SHADER_STAGE(QVK_MOD_CHECKERBOARD_INTERLEAVE_COMP, VK_SHADER_STAGE_COMPUTE_BIT),
165  .layout = pipeline_layout_general,
166  },
167  [TAA] = {
168  .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
169  .stage = SHADER_STAGE(QVK_MOD_ASVGF_TAA_COMP, VK_SHADER_STAGE_COMPUTE_BIT),
170  .layout = pipeline_layout_general,
171  },
172  [COMPOSITING] = {
173  .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
174  .stage = SHADER_STAGE(QVK_MOD_COMPOSITING_COMP, VK_SHADER_STAGE_COMPUTE_BIT),
175  .layout = pipeline_layout_general,
176  },
177  };
178 
179  _VK(vkCreateComputePipelines(qvk.device, 0, LENGTH(pipeline_info), pipeline_info, 0, pipeline_asvgf));
180 
181  return VK_SUCCESS;
182 }
183 
184 VkResult
186 {
187  for(int i = 0; i < ASVGF_NUM_PIPELINES; i++)
188  vkDestroyPipeline(qvk.device, pipeline_asvgf[i], NULL);
189  return VK_SUCCESS;
190 }
191 
192 #define BARRIER_COMPUTE(cmd_buf, img) \
193  do { \
194  VkImageSubresourceRange subresource_range = { \
195  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, \
196  .baseMipLevel = 0, \
197  .levelCount = 1, \
198  .baseArrayLayer = 0, \
199  .layerCount = 1 \
200  }; \
201  IMAGE_BARRIER(cmd_buf, \
202  .image = img, \
203  .subresourceRange = subresource_range, \
204  .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, \
205  .dstAccessMask = VK_ACCESS_SHADER_READ_BIT, \
206  .oldLayout = VK_IMAGE_LAYOUT_GENERAL, \
207  .newLayout = VK_IMAGE_LAYOUT_GENERAL, \
208  ); \
209  } while(0)
210 
211 #define BARRIER_TO_CLEAR(cmd_buf, img) \
212  do { \
213  VkImageSubresourceRange subresource_range = { \
214  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, \
215  .baseMipLevel = 0, \
216  .levelCount = 1, \
217  .baseArrayLayer = 0, \
218  .layerCount = 1 \
219  }; \
220  IMAGE_BARRIER(cmd_buf, \
221  .image = img, \
222  .subresourceRange = subresource_range, \
223  .srcAccessMask = 0, \
224  .dstAccessMask = 0, \
225  .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, \
226  .newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, \
227  ); \
228  } while(0)
229 
230 #define BARRIER_FROM_CLEAR(cmd_buf, img) \
231  do { \
232  VkImageSubresourceRange subresource_range = { \
233  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, \
234  .baseMipLevel = 0, \
235  .levelCount = 1, \
236  .baseArrayLayer = 0, \
237  .layerCount = 1 \
238  }; \
239  IMAGE_BARRIER(cmd_buf, \
240  .image = img, \
241  .subresourceRange = subresource_range, \
242  .srcAccessMask = 0, \
243  .dstAccessMask = VK_ACCESS_SHADER_READ_BIT, \
244  .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, \
245  .newLayout = VK_IMAGE_LAYOUT_GENERAL, \
246  ); \
247  } while(0)
248 
249 
250 VkResult
251 vkpt_asvgf_create_gradient_samples(VkCommandBuffer cmd_buf, uint32_t frame_num, int do_gradient_samples)
252 {
253  VkDescriptorSet desc_sets[] = {
257  };
258  VkClearColorValue clear_grd_smpl_pos = {
259  .uint32 = { 0, 0, 0, 0 }
260  };
261 
262  VkImageSubresourceRange subresource_range = {
263  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
264  .baseMipLevel = 0,
265  .levelCount = 1,
266  .baseArrayLayer = 0,
267  .layerCount = 1
268  };
269 
270  int current_sample_pos_image = VKPT_IMG_ASVGF_GRAD_SMPL_POS_A + (qvk.frame_counter & 1);
271 
272  BARRIER_TO_CLEAR(cmd_buf, qvk.images[current_sample_pos_image]);
273  vkCmdClearColorImage(cmd_buf, qvk.images[current_sample_pos_image],
274  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_grd_smpl_pos, 1, &subresource_range);
275  BARRIER_FROM_CLEAR(cmd_buf, qvk.images[current_sample_pos_image]);
276 
277  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_RNG_SEED_A + (qvk.frame_counter & 1)]);
278 
279  for(uint32_t gpu = 0; gpu < qvk.device_count; gpu++)
280  {
281  set_current_gpu(cmd_buf, gpu);
282 
283  uint32_t push_constants[1] = {
284  gpu
285  };
286 
287  vkCmdPushConstants(cmd_buf, pipeline_layout_atrous,
288  VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(push_constants), push_constants);
289 
290  vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_asvgf[SEED_RNG]);
291  vkCmdBindDescriptorSets(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE,
292  pipeline_layout_general, 0, LENGTH(desc_sets), desc_sets, 0, 0);
293  vkCmdDispatch(cmd_buf,
294  (qvk.gpu_slice_width + 15) / 16,
295  (qvk.extent_render.height + 15) / 16,
296  1);
297  }
298 
299  set_current_gpu(cmd_buf, ALL_GPUS);
300 
301  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_RNG_SEED_A + (qvk.frame_counter & 1)]);
302 
303  if (do_gradient_samples)
304  {
305  BEGIN_PERF_MARKER(cmd_buf, PROFILER_ASVGF_DO_GRADIENT_SAMPLES);
306 
307  vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_asvgf[FWD_PROJECT]);
308  vkCmdBindDescriptorSets(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE,
309  pipeline_layout_general, 0, LENGTH(desc_sets), desc_sets, 0, 0);
310  vkCmdDispatch(cmd_buf,
311  (qvk.gpu_slice_width_prev / GRAD_DWN + 15) / 16,
312  (qvk.extent_render_prev.height / GRAD_DWN + 15) / 16,
313  1);
314 
315  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_RNG_SEED_A + (qvk.frame_counter & 1)]);
316  BARRIER_COMPUTE(cmd_buf, qvk.images[current_sample_pos_image]);
317 
318  END_PERF_MARKER(cmd_buf, PROFILER_ASVGF_DO_GRADIENT_SAMPLES);
319  }
320 
321  return VK_SUCCESS;
322 }
323 
324 VkResult
325 vkpt_asvgf_filter(VkCommandBuffer cmd_buf, qboolean enable_lf)
326 {
327  VkDescriptorSet desc_sets[] = {
331  };
332  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_COLOR_LF_SH]);
333  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_COLOR_LF_COCG]);
334  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_COLOR_HF]);
335  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_COLOR_SPEC]);
336 
337  BEGIN_PERF_MARKER(cmd_buf, PROFILER_ASVGF_RECONSTRUCT_GRADIENT);
338 
339  /* create gradient image */
340  vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_asvgf[GRADIENT_IMAGE]);
341  vkCmdBindDescriptorSets(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE,
342  pipeline_layout_atrous, 0, LENGTH(desc_sets), desc_sets, 0, 0);
343  vkCmdDispatch(cmd_buf,
344  (qvk.gpu_slice_width / GRAD_DWN + 15) / 16,
345  (qvk.extent_render.height / GRAD_DWN + 15) / 16,
346  1);
347 
348  // XXX BARRIERS!!!
349  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_GRAD_LF_PING]);
350  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_GRAD_HF_SPEC_PING]);
351 
352  //vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_asvgf[GRADIENT_ATROUS]);
353  vkCmdBindDescriptorSets(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE,
354  pipeline_layout_atrous, 0, LENGTH(desc_sets), desc_sets, 0, 0);
355 
356  /* reconstruct gradient image */
357  const int num_atrous_iterations_gradient = 7;
358  for(int i = 0; i < num_atrous_iterations_gradient; i++) {
359  uint32_t push_constants[1] = {
360  i
361  };
362 
363  vkCmdPushConstants(cmd_buf, pipeline_layout_atrous,
364  VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(push_constants), push_constants);
365 
366  vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_asvgf[GRADIENT_ATROUS]);
367 
368  vkCmdDispatch(cmd_buf,
369  (qvk.gpu_slice_width / GRAD_DWN + 15) / 16,
370  (qvk.extent_render.height / GRAD_DWN + 15) / 16,
371  1);
372  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_GRAD_LF_PING + !(i & 1)]);
373  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_GRAD_HF_SPEC_PING + !(i & 1)]);
374 
375  }
376 
377  END_PERF_MARKER(cmd_buf, PROFILER_ASVGF_RECONSTRUCT_GRADIENT);
378  BEGIN_PERF_MARKER(cmd_buf, PROFILER_ASVGF_TEMPORAL);
379 
380  /* temporal accumulation / filtering */
381  vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_asvgf[TEMPORAL]);
382  vkCmdBindDescriptorSets(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE,
383  pipeline_layout_atrous, 0, LENGTH(desc_sets), desc_sets, 0, 0);
384  vkCmdDispatch(cmd_buf,
385  (qvk.gpu_slice_width + 14) / 15,
386  (qvk.extent_render.height + 14) / 15,
387  1);
388 
389 
390  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_ATROUS_PING_LF_SH]);
391  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_ATROUS_PING_LF_COCG]);
392  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_ATROUS_PING_HF]);
393  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_ATROUS_PING_MOMENTS]);
394  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_FILTERED_SPEC_A + (qvk.frame_counter & 1)]);
395  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_HIST_MOMENTS_HF_A]);
396  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_HIST_MOMENTS_HF_B]);
397 
398  END_PERF_MARKER(cmd_buf, PROFILER_ASVGF_TEMPORAL);
399  BEGIN_PERF_MARKER(cmd_buf, PROFILER_ASVGF_ATROUS);
400 
401  //vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_asvgf[ATROUS]);
402  vkCmdBindDescriptorSets(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE,
403  pipeline_layout_atrous, 0, LENGTH(desc_sets), desc_sets, 0, 0);
404 
405  /* spatial reconstruction filtering */
406  const int num_atrous_iterations = 4;
407  for(int i = 0; i < num_atrous_iterations; i++)
408  {
409  if (enable_lf)
410  {
411  uint32_t push_constants[1] = {
412  i
413  };
414 
415  vkCmdPushConstants(cmd_buf, pipeline_layout_atrous,
416  VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(push_constants), push_constants);
417 
418  vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_asvgf[ATROUS_LF]);
419 
420  vkCmdDispatch(cmd_buf,
421  (qvk.gpu_slice_width / GRAD_DWN + 15) / 16,
422  (qvk.extent_render.height / GRAD_DWN + 15) / 16,
423  1);
424 
425  if (i == num_atrous_iterations - 1)
426  {
427  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_ATROUS_PING_LF_SH]);
428  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_ATROUS_PING_LF_COCG]);
429  }
430  }
431 
432  int specialization = ATROUS_ITER_0 + i;
433 
434  vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_asvgf[specialization]);
435  vkCmdDispatch(cmd_buf,
436  (qvk.gpu_slice_width + 15) / 16,
437  (qvk.extent_render.height + 15) / 16,
438  1);
439 
440  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_ATROUS_PING_LF_SH]);
441  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_ATROUS_PING_LF_COCG]);
442  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_ATROUS_PING_HF]);
443  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_ATROUS_PING_MOMENTS]);
444  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_ATROUS_PONG_LF_SH]);
445  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_ATROUS_PONG_LF_COCG]);
446  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_ATROUS_PONG_HF]);
447  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_ATROUS_PONG_MOMENTS]);
448  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_HIST_COLOR_HF]);
449  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_ATROUS_PING_LF_SH + !(i & 1)]);
450  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_ATROUS_PING_LF_COCG + !(i & 1)]);
451  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_COLOR]);
452  }
453 
454  END_PERF_MARKER(cmd_buf, PROFILER_ASVGF_ATROUS);
455 
456  return VK_SUCCESS;
457 }
458 
459 VkResult
460 vkpt_compositing(VkCommandBuffer cmd_buf)
461 {
462  VkDescriptorSet desc_sets[] = {
466  };
467  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_COLOR_LF_SH]);
468  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_COLOR_LF_COCG]);
469  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_COLOR_HF]);
470  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_PT_COLOR_SPEC]);
471 
472  BEGIN_PERF_MARKER(cmd_buf, PROFILER_COMPOSITING);
473 
474  /* create gradient image */
475  vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_asvgf[COMPOSITING]);
476  vkCmdBindDescriptorSets(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE,
477  pipeline_layout_general, 0, LENGTH(desc_sets), desc_sets, 0, 0);
478 
479  vkCmdDispatch(cmd_buf,
480  (qvk.gpu_slice_width + 15) / 16,
481  (qvk.extent_render.height + 15) / 16,
482  1);
483 
484  END_PERF_MARKER(cmd_buf, PROFILER_COMPOSITING);
485 
486  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_COLOR]);
487 
488  return VK_SUCCESS;
489 }
490 
491 VkResult
492 vkpt_interleave(VkCommandBuffer cmd_buf)
493 {
494  VkDescriptorSet desc_sets[] = {
498  };
499 
500 #ifdef VKPT_DEVICE_GROUPS
501  if (qvk.device_count > 1) {
502  BEGIN_PERF_MARKER(cmd_buf, PROFILER_MGPU_TRANSFERS);
503 
504  // create full interleaved motion and color buffers on GPU 0
505  VkOffset2D offset_left = { 0, 0 };
506  VkOffset2D offset_right = { qvk.extent_render.width / 2, 0 };
507  VkExtent2D extent = { qvk.extent_render.width / 2, qvk.extent_render.height };
508 
509  vkpt_mgpu_image_copy(cmd_buf,
510  VKPT_IMG_PT_MOTION,
511  VKPT_IMG_PT_MOTION,
512  1,
513  0,
514  offset_left,
515  offset_right,
516  extent);
517 
518  vkpt_mgpu_image_copy(cmd_buf,
519  VKPT_IMG_ASVGF_COLOR,
520  VKPT_IMG_ASVGF_COLOR,
521  1,
522  0,
523  offset_left,
524  offset_right,
525  extent);
526 
527  vkpt_mgpu_global_barrier(cmd_buf);
528 
529  END_PERF_MARKER(cmd_buf, PROFILER_MGPU_TRANSFERS);
530  }
531 #endif
532 
533  BEGIN_PERF_MARKER(cmd_buf, PROFILER_INTERLEAVE);
534 
535  vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_asvgf[CHECKERBOARD_INTERLEAVE]);
536  vkCmdBindDescriptorSets(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE,
537  pipeline_layout_general, 0, LENGTH(desc_sets), desc_sets, 0, 0);
538 
539  set_current_gpu(cmd_buf, 0);
540 
541  // dispatch using the image dimensions, not render dimensions - to clear the unused area with black color
542  vkCmdDispatch(cmd_buf,
543  (qvk.extent_screen_images.width + 15) / 16,
544  (qvk.extent_screen_images.height + 15) / 16,
545  1);
546 
547  END_PERF_MARKER(cmd_buf, PROFILER_INTERLEAVE);
548 
549  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_FLAT_COLOR]);
550  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_FLAT_MOTION]);
551 
552  return VK_SUCCESS;
553 }
554 
555 VkResult vkpt_taa(VkCommandBuffer cmd_buf)
556 {
557  VkDescriptorSet desc_sets[] = {
561  };
562 
563  BEGIN_PERF_MARKER(cmd_buf, PROFILER_ASVGF_TAA);
564 
565  vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_asvgf[TAA]);
566  vkCmdBindDescriptorSets(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE,
567  pipeline_layout_taa, 0, LENGTH(desc_sets), desc_sets, 0, 0);
568 
569  VkExtent2D dispatch_size = qvk.extent_render;
570 
571  if(dispatch_size.width < qvk.extent_screen_images.width)
572  dispatch_size.width += 8;
573 
574  if (dispatch_size.height < qvk.extent_screen_images.height)
575  dispatch_size.height += 8;
576 
577  vkCmdDispatch(cmd_buf,
578  (dispatch_size.width + 15) / 16,
579  (dispatch_size.height + 15) / 16,
580  1);
581  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_TAA_A]);
582  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_TAA_B]);
583  BARRIER_COMPUTE(cmd_buf, qvk.images[VKPT_IMG_ASVGF_TAA_B]);
584 
585  END_PERF_MARKER(cmd_buf, PROFILER_ASVGF_TAA);
586 
587  return VK_SUCCESS;
588 }
QVK_s::desc_set_ubo
VkDescriptorSet desc_set_ubo
Definition: vkpt.h:226
TAA
@ TAA
Definition: asvgf.c:33
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
pipeline_layout_atrous
static VkPipelineLayout pipeline_layout_atrous
Definition: asvgf.c:40
vkpt_taa
VkResult vkpt_taa(VkCommandBuffer cmd_buf)
Definition: asvgf.c:555
SHADER_STAGE_SPEC
#define SHADER_STAGE_SPEC(_module, _stage, _spec)
Definition: vkpt.h:124
pipeline_asvgf
static VkPipeline pipeline_asvgf[ASVGF_NUM_PIPELINES]
Definition: asvgf.c:39
QVK_s::device
VkDevice device
Definition: vkpt.h:172
vkpt_asvgf_destroy
VkResult vkpt_asvgf_destroy()
Definition: asvgf.c:81
ATROUS_ITER_0
@ ATROUS_ITER_0
Definition: asvgf.c:29
vkpt.h
QVK_s::gpu_slice_width
uint32_t gpu_slice_width
Definition: vkpt.h:187
vkpt_asvgf_create_pipelines
VkResult vkpt_asvgf_create_pipelines()
Definition: asvgf.c:91
COMPOSITING
@ COMPOSITING
Definition: asvgf.c:35
pipeline_layout_general
static VkPipelineLayout pipeline_layout_general
Definition: asvgf.c:41
TEMPORAL
@ TEMPORAL
Definition: asvgf.c:27
ATROUS_ITER_1
@ ATROUS_ITER_1
Definition: asvgf.c:30
END_PERF_MARKER
#define END_PERF_MARKER(command_buffer, name)
Definition: vkpt.h:743
vkpt_compositing
VkResult vkpt_compositing(VkCommandBuffer cmd_buf)
Definition: asvgf.c:460
vkpt_asvgf_initialize
VkResult vkpt_asvgf_initialize()
Definition: asvgf.c:45
_VK
#define _VK(...)
Definition: vkpt.h:65
BARRIER_COMPUTE
#define BARRIER_COMPUTE(cmd_buf, img)
Definition: asvgf.c:192
pipeline_layout_taa
static VkPipelineLayout pipeline_layout_taa
Definition: asvgf.c:42
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
ATROUS_ITER_3
@ ATROUS_ITER_3
Definition: asvgf.c:32
ATROUS_ITER_2
@ ATROUS_ITER_2
Definition: asvgf.c:31
vkpt_asvgf_destroy_pipelines
VkResult vkpt_asvgf_destroy_pipelines()
Definition: asvgf.c:185
FWD_PROJECT
@ FWD_PROJECT
Definition: asvgf.c:24
push_constants
push_constants
Definition: path_tracer.h:129
GRADIENT_ATROUS
@ GRADIENT_ATROUS
Definition: asvgf.c:26
QVK_s::images
VkImage images[NUM_VKPT_IMAGES]
Definition: vkpt.h:231
set_current_gpu
void set_current_gpu(VkCommandBuffer cmd_buf, int gpu_index)
Definition: vk_util.c:426
LENGTH
#define LENGTH(a)
Definition: tent.c:228
BEGIN_PERF_MARKER
#define BEGIN_PERF_MARKER(command_buffer, name)
Definition: vkpt.h:742
vkpt_interleave
VkResult vkpt_interleave(VkCommandBuffer cmd_buf)
Definition: asvgf.c:492
CHECKERBOARD_INTERLEAVE
@ CHECKERBOARD_INTERLEAVE
Definition: asvgf.c:34
qvk
QVK_t qvk
Definition: main.c:377
vkpt_asvgf_create_gradient_samples
VkResult vkpt_asvgf_create_gradient_samples(VkCommandBuffer cmd_buf, uint32_t frame_num, int do_gradient_samples)
Definition: asvgf.c:251
QVK_s::gpu_slice_width_prev
uint32_t gpu_slice_width_prev
Definition: vkpt.h:188
GRADIENT_IMAGE
@ GRADIENT_IMAGE
Definition: asvgf.c:25
ALL_GPUS
#define ALL_GPUS
Definition: vkpt.h:535
SHADER_STAGE
#define SHADER_STAGE(_module, _stage)
Definition: vkpt.h:116
BARRIER_FROM_CLEAR
#define BARRIER_FROM_CLEAR(cmd_buf, img)
Definition: asvgf.c:230
QVK_s::extent_render
VkExtent2D extent_render
Definition: vkpt.h:184
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_asvgf_filter
VkResult vkpt_asvgf_filter(VkCommandBuffer cmd_buf, qboolean enable_lf)
Definition: asvgf.c:325
BARRIER_TO_CLEAR
#define BARRIER_TO_CLEAR(cmd_buf, img)
Definition: asvgf.c:211
ATROUS_LF
@ ATROUS_LF
Definition: asvgf.c:28
SEED_RNG
@ SEED_RNG
Definition: asvgf.c:23
QVK_s::extent_render_prev
VkExtent2D extent_render_prev
Definition: vkpt.h:185
qvk_get_current_desc_set_textures
VkDescriptorSet qvk_get_current_desc_set_textures()
Definition: main.c:1847
QVK_s::device_count
int device_count
Definition: vkpt.h:167
ASVGF_NUM_PIPELINES
@ ASVGF_NUM_PIPELINES
Definition: asvgf.c:36
QVK_s::desc_set_layout_vertex_buffer
VkDescriptorSetLayout desc_set_layout_vertex_buffer
Definition: vkpt.h:240
GRAD_DWN
#define GRAD_DWN
Definition: constants.h:22