Quake II RTX doxygen  1.0 dev
vk_util.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 "vk_util.h"
22 #include "vkpt.h"
23 
24 #include <assert.h>
25 
26 char * sgets(char * str, int num, char const ** input)
27 {
28  char const *next = *input;
29  int numread = 0;
30  while (numread + 1 < num && *next) {
31  int isnewline = (*next == '\n');
32  *str++ = *next++;
33  numread++;
34  if (isnewline)
35  break;
36  }
37  if (numread == 0)
38  return NULL; // "eof"
39  *str = '\0';
40  *input = next;
41  return str;
42 }
43 
44 uint32_t
45 get_memory_type(uint32_t mem_req_type_bits, VkMemoryPropertyFlags mem_prop)
46 {
47  for(uint32_t i = 0; i < VK_MAX_MEMORY_TYPES; i++) {
48  if(mem_req_type_bits & (1 << i)) {
49  if((qvk.mem_properties.memoryTypes[i].propertyFlags & mem_prop) == mem_prop)
50  return i;
51  }
52  }
53  return 0;
54 }
55 
56 VkResult
58  BufferResource_t *buf,
59  VkDeviceSize size,
60  VkBufferUsageFlags usage,
61  VkMemoryPropertyFlags mem_properties)
62 {
63  assert(size > 0);
64  assert(buf);
65  VkResult result = VK_SUCCESS;
66 
67  VkBufferCreateInfo buf_create_info = {
68  .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
69  .size = size,
70  .usage = usage,
71  .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
72  .queueFamilyIndexCount = 0,
73  .pQueueFamilyIndices = NULL
74  };
75 
76  buf->size = size;
77  buf->is_mapped = 0;
78 
79  result = vkCreateBuffer(qvk.device, &buf_create_info, NULL, &buf->buffer);
80  if(result != VK_SUCCESS) {
81  goto fail_buffer;
82  }
83  assert(buf->buffer != VK_NULL_HANDLE);
84 
85  VkMemoryRequirements mem_reqs;
86  vkGetBufferMemoryRequirements(qvk.device, buf->buffer, &mem_reqs);
87 
88  VkMemoryAllocateInfo mem_alloc_info = {
89  .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
90  .allocationSize = mem_reqs.size,
91  .memoryTypeIndex = get_memory_type(mem_reqs.memoryTypeBits, mem_properties)
92  };
93 
94 #ifdef VKPT_DEVICE_GROUPS
95  VkMemoryAllocateFlagsInfoKHR mem_alloc_flags = {
96  .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO_KHR,
97  .flags = VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT_KHR,
98  .deviceMask = (1 << qvk.device_count) - 1
99  };
100 
101  if (qvk.device_count > 1 && !(mem_properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) {
102  mem_alloc_info.pNext = &mem_alloc_flags;
103  }
104 #endif
105 
106  result = vkAllocateMemory(qvk.device, &mem_alloc_info, NULL, &buf->memory);
107  if(result != VK_SUCCESS) {
108  goto fail_mem_alloc;
109  }
110 
111  assert(buf->memory != VK_NULL_HANDLE);
112 
113  result = vkBindBufferMemory(qvk.device, buf->buffer, buf->memory, 0);
114  if(result != VK_SUCCESS) {
115  goto fail_bind_buf_memory;
116  }
117 
118  return VK_SUCCESS;
119 
120 fail_bind_buf_memory:
121  vkFreeMemory(qvk.device, buf->memory, NULL);
122 fail_mem_alloc:
123  vkDestroyBuffer(qvk.device, buf->buffer, NULL);
124 fail_buffer:
125  buf->buffer = VK_NULL_HANDLE;
126  buf->memory = VK_NULL_HANDLE;
127  buf->size = 0;
128  return result;
129 }
130 
131 VkResult
133 {
134  assert(!buf->is_mapped);
135  if(buf->memory != VK_NULL_HANDLE)
136  vkFreeMemory(qvk.device, buf->memory, NULL);
137  if(buf->buffer != VK_NULL_HANDLE)
138  vkDestroyBuffer(qvk.device, buf->buffer, NULL);
139  buf->buffer = VK_NULL_HANDLE;
140  buf->memory = VK_NULL_HANDLE;
141  buf->size = 0;
142 
143  return VK_SUCCESS;
144 }
145 
146 void *
148 {
149  assert(!buf->is_mapped);
150  buf->is_mapped = 1;
151  void *ret = NULL;
152  assert(buf->memory != VK_NULL_HANDLE);
153  assert(buf->size > 0);
154  _VK(vkMapMemory(qvk.device, buf->memory, 0 /*offset*/, buf->size, 0 /*flags*/, &ret));
155  return ret;
156 }
157 
158 void
160 {
161  assert(buf->is_mapped);
162  buf->is_mapped = 0;
163  vkUnmapMemory(qvk.device, buf->memory);
164 }
165 
166 const char *
167 qvk_format_to_string(VkFormat format)
168 {
169  switch(format) {
170  case 0: return "UNDEFINED";
171  case 1: return "R4G4_UNORM_PACK8";
172  case 2: return "R4G4B4A4_UNORM_PACK16";
173  case 3: return "B4G4R4A4_UNORM_PACK16";
174  case 4: return "R5G6B5_UNORM_PACK16";
175  case 5: return "B5G6R5_UNORM_PACK16";
176  case 6: return "R5G5B5A1_UNORM_PACK16";
177  case 7: return "B5G5R5A1_UNORM_PACK16";
178  case 8: return "A1R5G5B5_UNORM_PACK16";
179  case 9: return "R8_UNORM";
180  case 10: return "R8_SNORM";
181  case 11: return "R8_USCALED";
182  case 12: return "R8_SSCALED";
183  case 13: return "R8_UINT";
184  case 14: return "R8_SINT";
185  case 15: return "R8_SRGB";
186  case 16: return "R8G8_UNORM";
187  case 17: return "R8G8_SNORM";
188  case 18: return "R8G8_USCALED";
189  case 19: return "R8G8_SSCALED";
190  case 20: return "R8G8_UINT";
191  case 21: return "R8G8_SINT";
192  case 22: return "R8G8_SRGB";
193  case 23: return "R8G8B8_UNORM";
194  case 24: return "R8G8B8_SNORM";
195  case 25: return "R8G8B8_USCALED";
196  case 26: return "R8G8B8_SSCALED";
197  case 27: return "R8G8B8_UINT";
198  case 28: return "R8G8B8_SINT";
199  case 29: return "R8G8B8_SRGB";
200  case 30: return "B8G8R8_UNORM";
201  case 31: return "B8G8R8_SNORM";
202  case 32: return "B8G8R8_USCALED";
203  case 33: return "B8G8R8_SSCALED";
204  case 34: return "B8G8R8_UINT";
205  case 35: return "B8G8R8_SINT";
206  case 36: return "B8G8R8_SRGB";
207  case 37: return "R8G8B8A8_UNORM";
208  case 38: return "R8G8B8A8_SNORM";
209  case 39: return "R8G8B8A8_USCALED";
210  case 40: return "R8G8B8A8_SSCALED";
211  case 41: return "R8G8B8A8_UINT";
212  case 42: return "R8G8B8A8_SINT";
213  case 43: return "R8G8B8A8_SRGB";
214  case 44: return "B8G8R8A8_UNORM";
215  case 45: return "B8G8R8A8_SNORM";
216  case 46: return "B8G8R8A8_USCALED";
217  case 47: return "B8G8R8A8_SSCALED";
218  case 48: return "B8G8R8A8_UINT";
219  case 49: return "B8G8R8A8_SINT";
220  case 50: return "B8G8R8A8_SRGB";
221  case 51: return "A8B8G8R8_UNORM_PACK32";
222  case 52: return "A8B8G8R8_SNORM_PACK32";
223  case 53: return "A8B8G8R8_USCALED_PACK32";
224  case 54: return "A8B8G8R8_SSCALED_PACK32";
225  case 55: return "A8B8G8R8_UINT_PACK32";
226  case 56: return "A8B8G8R8_SINT_PACK32";
227  case 57: return "A8B8G8R8_SRGB_PACK32";
228  case 58: return "A2R10G10B10_UNORM_PACK32";
229  case 59: return "A2R10G10B10_SNORM_PACK32";
230  case 60: return "A2R10G10B10_USCALED_PACK32";
231  case 61: return "A2R10G10B10_SSCALED_PACK32";
232  case 62: return "A2R10G10B10_UINT_PACK32";
233  case 63: return "A2R10G10B10_SINT_PACK32";
234  case 64: return "A2B10G10R10_UNORM_PACK32";
235  case 65: return "A2B10G10R10_SNORM_PACK32";
236  case 66: return "A2B10G10R10_USCALED_PACK32";
237  case 67: return "A2B10G10R10_SSCALED_PACK32";
238  case 68: return "A2B10G10R10_UINT_PACK32";
239  case 69: return "A2B10G10R10_SINT_PACK32";
240  case 70: return "R16_UNORM";
241  case 71: return "R16_SNORM";
242  case 72: return "R16_USCALED";
243  case 73: return "R16_SSCALED";
244  case 74: return "R16_UINT";
245  case 75: return "R16_SINT";
246  case 76: return "R16_SFLOAT";
247  case 77: return "R16G16_UNORM";
248  case 78: return "R16G16_SNORM";
249  case 79: return "R16G16_USCALED";
250  case 80: return "R16G16_SSCALED";
251  case 81: return "R16G16_UINT";
252  case 82: return "R16G16_SINT";
253  case 83: return "R16G16_SFLOAT";
254  case 84: return "R16G16B16_UNORM";
255  case 85: return "R16G16B16_SNORM";
256  case 86: return "R16G16B16_USCALED";
257  case 87: return "R16G16B16_SSCALED";
258  case 88: return "R16G16B16_UINT";
259  case 89: return "R16G16B16_SINT";
260  case 90: return "R16G16B16_SFLOAT";
261  case 91: return "R16G16B16A16_UNORM";
262  case 92: return "R16G16B16A16_SNORM";
263  case 93: return "R16G16B16A16_USCALED";
264  case 94: return "R16G16B16A16_SSCALED";
265  case 95: return "R16G16B16A16_UINT";
266  case 96: return "R16G16B16A16_SINT";
267  case 97: return "R16G16B16A16_SFLOAT";
268  case 98: return "R32_UINT";
269  case 99: return "R32_SINT";
270  case 100: return "R32_SFLOAT";
271  case 101: return "R32G32_UINT";
272  case 102: return "R32G32_SINT";
273  case 103: return "R32G32_SFLOAT";
274  case 104: return "R32G32B32_UINT";
275  case 105: return "R32G32B32_SINT";
276  case 106: return "R32G32B32_SFLOAT";
277  case 107: return "R32G32B32A32_UINT";
278  case 108: return "R32G32B32A32_SINT";
279  case 109: return "R32G32B32A32_SFLOAT";
280  case 110: return "R64_UINT";
281  case 111: return "R64_SINT";
282  case 112: return "R64_SFLOAT";
283  case 113: return "R64G64_UINT";
284  case 114: return "R64G64_SINT";
285  case 115: return "R64G64_SFLOAT";
286  case 116: return "R64G64B64_UINT";
287  case 117: return "R64G64B64_SINT";
288  case 118: return "R64G64B64_SFLOAT";
289  case 119: return "R64G64B64A64_UINT";
290  case 120: return "R64G64B64A64_SINT";
291  case 121: return "R64G64B64A64_SFLOAT";
292  case 122: return "B10G11R11_UFLOAT_PACK32";
293  case 123: return "E5B9G9R9_UFLOAT_PACK32";
294  case 124: return "D16_UNORM";
295  case 125: return "X8_D24_UNORM_PACK32";
296  case 126: return "D32_SFLOAT";
297  case 127: return "S8_UINT";
298  case 128: return "D16_UNORM_S8_UINT";
299  case 129: return "D24_UNORM_S8_UINT";
300  case 130: return "D32_SFLOAT_S8_UINT";
301  case 131: return "BC1_RGB_UNORM_BLOCK";
302  case 132: return "BC1_RGB_SRGB_BLOCK";
303  case 133: return "BC1_RGBA_UNORM_BLOCK";
304  case 134: return "BC1_RGBA_SRGB_BLOCK";
305  case 135: return "BC2_UNORM_BLOCK";
306  case 136: return "BC2_SRGB_BLOCK";
307  case 137: return "BC3_UNORM_BLOCK";
308  case 138: return "BC3_SRGB_BLOCK";
309  case 139: return "BC4_UNORM_BLOCK";
310  case 140: return "BC4_SNORM_BLOCK";
311  case 141: return "BC5_UNORM_BLOCK";
312  case 142: return "BC5_SNORM_BLOCK";
313  case 143: return "BC6H_UFLOAT_BLOCK";
314  case 144: return "BC6H_SFLOAT_BLOCK";
315  case 145: return "BC7_UNORM_BLOCK";
316  case 146: return "BC7_SRGB_BLOCK";
317  case 147: return "ETC2_R8G8B8_UNORM_BLOCK";
318  case 148: return "ETC2_R8G8B8_SRGB_BLOCK";
319  case 149: return "ETC2_R8G8B8A1_UNORM_BLOCK";
320  case 150: return "ETC2_R8G8B8A1_SRGB_BLOCK";
321  case 151: return "ETC2_R8G8B8A8_UNORM_BLOCK";
322  case 152: return "ETC2_R8G8B8A8_SRGB_BLOCK";
323  case 153: return "EAC_R11_UNORM_BLOCK";
324  case 154: return "EAC_R11_SNORM_BLOCK";
325  case 155: return "EAC_R11G11_UNORM_BLOCK";
326  case 156: return "EAC_R11G11_SNORM_BLOCK";
327  case 157: return "ASTC_4x4_UNORM_BLOCK";
328  case 158: return "ASTC_4x4_SRGB_BLOCK";
329  case 159: return "ASTC_5x4_UNORM_BLOCK";
330  case 160: return "ASTC_5x4_SRGB_BLOCK";
331  case 161: return "ASTC_5x5_UNORM_BLOCK";
332  case 162: return "ASTC_5x5_SRGB_BLOCK";
333  case 163: return "ASTC_6x5_UNORM_BLOCK";
334  case 164: return "ASTC_6x5_SRGB_BLOCK";
335  case 165: return "ASTC_6x6_UNORM_BLOCK";
336  case 166: return "ASTC_6x6_SRGB_BLOCK";
337  case 167: return "ASTC_8x5_UNORM_BLOCK";
338  case 168: return "ASTC_8x5_SRGB_BLOCK";
339  case 169: return "ASTC_8x6_UNORM_BLOCK";
340  case 170: return "ASTC_8x6_SRGB_BLOCK";
341  case 171: return "ASTC_8x8_UNORM_BLOCK";
342  case 172: return "ASTC_8x8_SRGB_BLOCK";
343  case 173: return "ASTC_10x5_UNORM_BLOCK";
344  case 174: return "ASTC_10x5_SRGB_BLOCK";
345  case 175: return "ASTC_10x6_UNORM_BLOCK";
346  case 176: return "ASTC_10x6_SRGB_BLOCK";
347  case 177: return "ASTC_10x8_UNORM_BLOCK";
348  case 178: return "ASTC_10x8_SRGB_BLOCK";
349  case 179: return "ASTC_10x10_UNORM_BLOCK";
350  case 180: return "ASTC_10x10_SRGB_BLOCK";
351  case 181: return "ASTC_12x10_UNORM_BLOCK";
352  case 182: return "ASTC_12x10_SRGB_BLOCK";
353  case 183: return "ASTC_12x12_UNORM_BLOCK";
354  case 184: return "ASTC_12x12_SRGB_BLOCK";
355  case 1000156000: return "G8B8G8R8_422_UNORM";
356  case 1000156001: return "B8G8R8G8_422_UNORM";
357  case 1000156002: return "G8_B8_R8_3PLANE_420_UNORM";
358  case 1000156003: return "G8_B8R8_2PLANE_420_UNORM";
359  case 1000156004: return "G8_B8_R8_3PLANE_422_UNORM";
360  case 1000156005: return "G8_B8R8_2PLANE_422_UNORM";
361  case 1000156006: return "G8_B8_R8_3PLANE_444_UNORM";
362  case 1000156007: return "R10X6_UNORM_PACK16";
363  case 1000156008: return "R10X6G10X6_UNORM_2PACK16";
364  case 1000156009: return "R10X6G10X6B10X6A10X6_UNORM_4PACK16";
365  case 1000156010: return "G10X6B10X6G10X6R10X6_422_UNORM_4PACK16";
366  case 1000156011: return "B10X6G10X6R10X6G10X6_422_UNORM_4PACK16";
367  case 1000156012: return "G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16";
368  case 1000156013: return "G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16";
369  case 1000156014: return "G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16";
370  case 1000156015: return "G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16";
371  case 1000156016: return "G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16";
372  case 1000156017: return "R12X4_UNORM_PACK16";
373  case 1000156018: return "R12X4G12X4_UNORM_2PACK16";
374  case 1000156019: return "R12X4G12X4B12X4A12X4_UNORM_4PACK16";
375  case 1000156020: return "G12X4B12X4G12X4R12X4_422_UNORM_4PACK16";
376  case 1000156021: return "B12X4G12X4R12X4G12X4_422_UNORM_4PACK16";
377  case 1000156022: return "G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16";
378  case 1000156023: return "G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16";
379  case 1000156024: return "G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16";
380  case 1000156025: return "G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16";
381  case 1000156026: return "G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16";
382  case 1000156027: return "G16B16G16R16_422_UNORM";
383  case 1000156028: return "B16G16R16G16_422_UNORM";
384  case 1000156029: return "G16_B16_R16_3PLANE_420_UNORM";
385  case 1000156030: return "G16_B16R16_2PLANE_420_UNORM";
386  case 1000156031: return "G16_B16_R16_3PLANE_422_UNORM";
387  case 1000156032: return "G16_B16R16_2PLANE_422_UNORM";
388  case 1000156033: return "G16_B16_R16_3PLANE_444_UNORM";
389  case 1000054000: return "PVRTC1_2BPP_UNORM_BLOCK_IMG";
390  case 1000054001: return "PVRTC1_4BPP_UNORM_BLOCK_IMG";
391  case 1000054002: return "PVRTC2_2BPP_UNORM_BLOCK_IMG";
392  case 1000054003: return "PVRTC2_4BPP_UNORM_BLOCK_IMG";
393  case 1000054004: return "PVRTC1_2BPP_SRGB_BLOCK_IMG";
394  case 1000054005: return "PVRTC1_4BPP_SRGB_BLOCK_IMG";
395  case 1000054006: return "PVRTC2_2BPP_SRGB_BLOCK_IMG";
396  case 1000054007: return "PVRTC2_4BPP_SRGB_BLOCK_IMG";
397  default: break;
398  }
399  return "";
400 }
401 
402 VkResult allocate_gpu_memory(VkMemoryRequirements mem_req, VkDeviceMemory* pMemory)
403 {
404  VkMemoryAllocateInfo mem_alloc_info = {
405  .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
406  .allocationSize = mem_req.size,
407  .memoryTypeIndex = get_memory_type(mem_req.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
408  };
409 
410 #ifdef VKPT_DEVICE_GROUPS
411  VkMemoryAllocateFlagsInfoKHR mem_alloc_flags = {
412  .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO_KHR,
413  .flags = VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT_KHR,
414  .deviceMask = (1 << qvk.device_count) - 1
415  };
416 
417  if (qvk.device_count > 1) {
418  mem_alloc_info.pNext = &mem_alloc_flags;
419  }
420 #endif
421 
422  return vkAllocateMemory(qvk.device, &mem_alloc_info, NULL, pMemory);
423 
424 }
425 
426 void set_current_gpu(VkCommandBuffer cmd_buf, int gpu_index)
427 {
428 #ifdef VKPT_DEVICE_GROUPS
429  if (qvk.device_count > 1)
430  {
431  if(gpu_index == ALL_GPUS)
432  qvkCmdSetDeviceMaskKHR(cmd_buf, (1 << qvk.device_count) - 1);
433  else
434  qvkCmdSetDeviceMaskKHR(cmd_buf, 1 << gpu_index);
435  }
436 #endif
437 }
438 
439 const char *qvk_result_to_string(VkResult result)
440 {
441  switch ((int)result)
442  {
443  case VK_SUCCESS:
444  return "VK_SUCCESS";
445  case VK_NOT_READY:
446  return "VK_NOT_READY";
447  case VK_TIMEOUT:
448  return "VK_TIMEOUT";
449  case VK_EVENT_SET:
450  return "VK_EVENT_SET";
451  case VK_EVENT_RESET:
452  return "VK_EVENT_RESET";
453  case VK_INCOMPLETE:
454  return "VK_INCOMPLETE";
455  case VK_ERROR_OUT_OF_HOST_MEMORY:
456  return "VK_ERROR_OUT_OF_HOST_MEMORY";
457  case VK_ERROR_OUT_OF_DEVICE_MEMORY:
458  return "VK_ERROR_OUT_OF_DEVICE_MEMORY";
459  case VK_ERROR_INITIALIZATION_FAILED:
460  return "VK_ERROR_INITIALIZATION_FAILED";
461  case VK_ERROR_DEVICE_LOST:
462  return "VK_ERROR_DEVICE_LOST";
463  case VK_ERROR_MEMORY_MAP_FAILED:
464  return "VK_ERROR_MEMORY_MAP_FAILED";
465  case VK_ERROR_LAYER_NOT_PRESENT:
466  return "VK_ERROR_LAYER_NOT_PRESENT";
467  case VK_ERROR_EXTENSION_NOT_PRESENT:
468  return "VK_ERROR_EXTENSION_NOT_PRESENT";
469  case VK_ERROR_FEATURE_NOT_PRESENT:
470  return "VK_ERROR_FEATURE_NOT_PRESENT";
471  case VK_ERROR_INCOMPATIBLE_DRIVER:
472  return "VK_ERROR_INCOMPATIBLE_DRIVER";
473  case VK_ERROR_TOO_MANY_OBJECTS:
474  return "VK_ERROR_TOO_MANY_OBJECTS";
475  case VK_ERROR_FORMAT_NOT_SUPPORTED:
476  return "VK_ERROR_FORMAT_NOT_SUPPORTED";
477  case VK_ERROR_FRAGMENTED_POOL:
478  return "VK_ERROR_FRAGMENTED_POOL";
479  case VK_ERROR_OUT_OF_POOL_MEMORY:
480  return "VK_ERROR_OUT_OF_POOL_MEMORY";
481  case VK_ERROR_INVALID_EXTERNAL_HANDLE:
482  return "VK_ERROR_INVALID_EXTERNAL_HANDLE";
483  case VK_ERROR_SURFACE_LOST_KHR:
484  return "VK_ERROR_SURFACE_LOST_KHR";
485  case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
486  return "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR";
487  case VK_SUBOPTIMAL_KHR:
488  return "VK_SUBOPTIMAL_KHR";
489  case VK_ERROR_OUT_OF_DATE_KHR:
490  return "VK_ERROR_OUT_OF_DATE_KHR";
491  case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
492  return "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR";
493  case VK_ERROR_VALIDATION_FAILED_EXT:
494  return "VK_ERROR_VALIDATION_FAILED_EXT";
495  case VK_ERROR_INVALID_SHADER_NV:
496  return "VK_ERROR_INVALID_SHADER_NV";
497  case VK_ERROR_FRAGMENTATION_EXT:
498  return "VK_ERROR_FRAGMENTATION_EXT";
499  case VK_ERROR_NOT_PERMITTED_EXT:
500  return "VK_ERROR_NOT_PERMITTED_EXT";
501  }
502 
503  static char buffer[16];
504  Q_snprintf(buffer, sizeof(buffer), "(%d)", (int)result);
505  return buffer;
506 }
507 
508 #ifdef VKPT_IMAGE_DUMPS
509 float convert_half_to_float(uint16_t Value)
510 {
511  uint32_t Mantissa = (uint32_t)(Value & 0x03FF);
512 
513  uint32_t Exponent = (Value & 0x7C00);
514  if (Exponent == 0x7C00) // INF/NAN
515  {
516  Exponent = (uint32_t)0x8f;
517  }
518  else if (Exponent != 0) // The value is normalized
519  {
520  Exponent = (uint32_t)((Value >> 10) & 0x1F);
521  }
522  else if (Mantissa != 0) // The value is denormalized
523  {
524  // Normalize the value in the resulting float
525  Exponent = 1;
526 
527  do
528  {
529  Exponent--;
530  Mantissa <<= 1;
531  } while ((Mantissa & 0x0400) == 0);
532 
533  Mantissa &= 0x03FF;
534  }
535  else // The value is zero
536  {
537  Exponent = (uint32_t)-112;
538  }
539 
540  uint32_t Result = ((Value & 0x8000) << 16) | // Sign
541  ((Exponent + 112) << 23) | // Exponent
542  (Mantissa << 13); // Mantissa
543 
544  float* res = (float*)(&Result);
545  return res[0];
546 }
547 
548 void save_to_pfm_file(char* prefix, uint64_t frame_counter, uint64_t width, uint64_t height, char* data, uint64_t rowPitch, int32_t type)
549 {
550  if (frame_counter == 0) return;
551 
552  char fileName[128];
553  sprintf(fileName, "%s_%04llu.pfm", prefix, frame_counter);
554 
555  FILE* file = fopen(fileName, "wb");
556  if (file)
557  {
558  {
559  char* buf = "PF\n";
560  fwrite(buf, 1, strlen(buf), file);
561  }
562  {
563  char resolutionData[256];
564  sprintf(resolutionData, "%llu %llu\n", width, height);
565  fwrite(resolutionData, 1, strlen(resolutionData), file);
566  }
567  {
568  char* buf = "-1.0\n";
569  fwrite(buf, 1, strlen(buf), file);
570  }
571 
572  size_t pixelDataSize = width * height * 3 * sizeof(float);
573  float* pixelData = malloc(pixelDataSize);
574  memset(pixelData, 0, pixelDataSize);
575 
576  if (type == 0) // input
577  {
578  for (size_t y = 0; y < height; ++y)
579  {
580  float* rowData = pixelData + (height - y - 1) * width * 3;
581  for (size_t x = 0; x < width; ++x)
582  {
583  uint16_t* row = (uint16_t*)(data + y * rowPitch + x * 8);
584  rowData[x * 3 + 0] = convert_half_to_float(row[0]);
585  rowData[x * 3 + 1] = convert_half_to_float(row[1]);
586  rowData[x * 3 + 2] = convert_half_to_float(row[2]);
587  }
588  }
589  }
590  else if (type == 1) // motion
591  {
592  float scaleX = qvk.extent_render.width * 0.5f;
593  float scaleY = qvk.extent_render.height * 0.5f;
594 
595  for (size_t y = 0; y < height; ++y)
596  {
597  float* rowData = pixelData + y * width * 3;
598  for (size_t x = 0; x < width; ++x)
599  {
600  uint16_t* row = (uint16_t*)(data + y * rowPitch + x * 8);
601  rowData[x * 3 + 0] = convert_half_to_float(row[0]) * scaleX;
602  rowData[x * 3 + 1] = convert_half_to_float(row[1]) * scaleY;
603  rowData[x * 3 + 2] = 0.0f;
604  }
605  }
606  }
607  else if (type == 2) // reference
608  {
609  for (size_t y = 0; y < height; ++y)
610  {
611  float* rowData = pixelData + y * width * 3;
612  for (size_t x = 0; x < width; ++x)
613  {
614  float* row = (float*)(data + y * rowPitch + x * 16);
615  rowData[x * 3 + 0] = row[0];
616  rowData[x * 3 + 1] = row[1];
617  rowData[x * 3 + 2] = row[2];
618  }
619  }
620  }
621 
622  fwrite(pixelData, 1, pixelDataSize, file);
623 
624  free(pixelData);
625  fclose(file);
626 
627  Com_Printf("wrote image data to %s", fileName);
628  }
629 }
630 #endif
height
static int height
Definition: physical_sky.c:39
Q_snprintf
size_t Q_snprintf(char *dest, size_t size, const char *fmt,...)
Definition: shared.c:846
allocate_gpu_memory
VkResult allocate_gpu_memory(VkMemoryRequirements mem_req, VkDeviceMemory *pMemory)
Definition: vk_util.c:402
QVK_s::device
VkDevice device
Definition: vkpt.h:172
input
static in_state_t input
Definition: input.c:71
buffer_unmap
void buffer_unmap(BufferResource_t *buf)
Definition: vk_util.c:159
vkpt.h
buffer_destroy
VkResult buffer_destroy(BufferResource_t *buf)
Definition: vk_util.c:132
width
static int width
Definition: physical_sky.c:38
QVK_s::mem_properties
VkPhysicalDeviceMemoryProperties mem_properties
Definition: vkpt.h:164
get_memory_type
uint32_t get_memory_type(uint32_t mem_req_type_bits, VkMemoryPropertyFlags mem_prop)
Definition: vk_util.c:45
_VK
#define _VK(...)
Definition: vkpt.h:65
BufferResource_s::buffer
VkBuffer buffer
Definition: vk_util.h:34
qvk_format_to_string
const char * qvk_format_to_string(VkFormat format)
Definition: vk_util.c:167
set_current_gpu
void set_current_gpu(VkCommandBuffer cmd_buf, int gpu_index)
Definition: vk_util.c:426
qvk
QVK_t qvk
Definition: main.c:377
sgets
char * sgets(char *str, int num, char const **input)
Definition: vk_util.c:26
ALL_GPUS
#define ALL_GPUS
Definition: vkpt.h:535
vk_util.h
QVK_s::extent_render
VkExtent2D extent_render
Definition: vkpt.h:184
BufferResource_s::is_mapped
int is_mapped
Definition: vk_util.h:37
BufferResource_s
Definition: vk_util.h:33
buffer_create
VkResult buffer_create(BufferResource_t *buf, VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags mem_properties)
Definition: vk_util.c:57
buffer_map
void * buffer_map(BufferResource_t *buf)
Definition: vk_util.c:147
BufferResource_s::size
size_t size
Definition: vk_util.h:36
qvk_result_to_string
const char * qvk_result_to_string(VkResult result)
Definition: vk_util.c:439
QVK_s::device_count
int device_count
Definition: vkpt.h:167
BufferResource_s::memory
VkDeviceMemory memory
Definition: vk_util.h:35