1 /*
2 Copyright (C) 1996-2001 Id Software, Inc.
3 Copyright (C) 2002-2009 John Fitzgibbons and others
4 Copyright (C) 2007-2008 Kristian Duske
5 Copyright (C) 2010-2014 QuakeSpasm developers
6 Copyright (C) 2016 Axel Gneiting
7
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
17 See the GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
23 */
24 // r_misc.c
25
26 #include "quakedef.h"
27 #include <float.h>
28
29 #if defined(SDL_FRAMEWORK) || defined(NO_SDL_CONFIG)
30 #include <SDL2/SDL.h>
31 #else
32 #include "SDL.h"
33 #endif
34
35 cvar_t r_lodbias = {"r_lodbias", "1", CVAR_ARCHIVE};
36
37 //johnfitz -- new cvars
38 extern cvar_t r_clearcolor;
39 extern cvar_t r_fastclear;
40 extern cvar_t r_flatlightstyles;
41 extern cvar_t gl_fullbrights;
42 extern cvar_t gl_farclip;
43 extern cvar_t r_waterquality;
44 extern cvar_t r_waterwarp;
45 extern cvar_t r_waterwarpcompute;
46 extern cvar_t r_oldskyleaf;
47 extern cvar_t r_drawworld;
48 extern cvar_t r_showtris;
49 extern cvar_t r_showbboxes;
50 extern cvar_t r_lerpmodels;
51 extern cvar_t r_lerpmove;
52 extern cvar_t r_nolerp_list;
53 //johnfitz
54 extern cvar_t gl_zfix; // QuakeSpasm z-fighting fix
55
56 #if defined(USE_SIMD)
57 extern cvar_t r_simd;
58 #endif
59 extern gltexture_t *playertextures[MAX_SCOREBOARD]; //johnfitz
60
61 vulkanglobals_t vulkan_globals;
62
63 int num_vulkan_tex_allocations = 0;
64 int num_vulkan_bmodel_allocations = 0;
65 int num_vulkan_mesh_allocations = 0;
66 int num_vulkan_misc_allocations = 0;
67 int num_vulkan_dynbuf_allocations = 0;
68 int num_vulkan_combined_image_samplers = 0;
69 int num_vulkan_ubos_dynamic = 0;
70 int num_vulkan_input_attachments = 0;
71 int num_vulkan_storage_images = 0;
72 size_t total_device_vulkan_allocation_size = 0;
73 size_t total_host_vulkan_allocation_size = 0;
74
75 qboolean use_simd;
76
77 /*
78 ================
79 Staging
80 ================
81 */
82 #define NUM_STAGING_BUFFERS 2
83
84 typedef struct
85 {
86 VkBuffer buffer;
87 VkCommandBuffer command_buffer;
88 VkFence fence;
89 int current_offset;
90 qboolean submitted;
91 unsigned char * data;
92 } stagingbuffer_t;
93
94 static VkCommandPool staging_command_pool;
95 static vulkan_memory_t staging_memory;
96 static stagingbuffer_t staging_buffers[NUM_STAGING_BUFFERS];
97 static int current_staging_buffer = 0;
98
99 /*
100 ================
101 Dynamic vertex/index & uniform buffer
102 ================
103 */
104 #define INITIAL_DYNAMIC_VERTEX_BUFFER_SIZE_KB 256
105 #define INITIAL_DYNAMIC_INDEX_BUFFER_SIZE_KB 1024
106 #define INITIAL_DYNAMIC_UNIFORM_BUFFER_SIZE_KB 256
107 #define NUM_DYNAMIC_BUFFERS 2
108 #define GARBAGE_FRAME_COUNT 3
109 #define MAX_UNIFORM_ALLOC 2048
110
111 typedef struct
112 {
113 VkBuffer buffer;
114 uint32_t current_offset;
115 unsigned char * data;
116 } dynbuffer_t;
117
118 static uint32_t current_dyn_vertex_buffer_size = INITIAL_DYNAMIC_VERTEX_BUFFER_SIZE_KB * 1024;
119 static uint32_t current_dyn_index_buffer_size = INITIAL_DYNAMIC_INDEX_BUFFER_SIZE_KB * 1024;
120 static uint32_t current_dyn_uniform_buffer_size = INITIAL_DYNAMIC_UNIFORM_BUFFER_SIZE_KB * 1024;
121 static vulkan_memory_t dyn_vertex_buffer_memory;
122 static vulkan_memory_t dyn_index_buffer_memory;
123 static vulkan_memory_t dyn_uniform_buffer_memory;
124 static dynbuffer_t dyn_vertex_buffers[NUM_DYNAMIC_BUFFERS];
125 static dynbuffer_t dyn_index_buffers[NUM_DYNAMIC_BUFFERS];
126 static dynbuffer_t dyn_uniform_buffers[NUM_DYNAMIC_BUFFERS];
127 static int current_dyn_buffer_index = 0;
128 static VkDescriptorSet ubo_descriptor_sets[2];
129
130 static int current_garbage_index = 0;
131 static int num_device_memory_garbage[GARBAGE_FRAME_COUNT];
132 static int num_buffer_garbage[GARBAGE_FRAME_COUNT];
133 static int num_desc_set_garbage[GARBAGE_FRAME_COUNT];
134 static vulkan_memory_t * device_memory_garbage[GARBAGE_FRAME_COUNT];
135 static VkDescriptorSet * descriptor_set_garbage[GARBAGE_FRAME_COUNT];
136 static VkBuffer * buffer_garbage[GARBAGE_FRAME_COUNT];
137
138 void R_VulkanMemStats_f (void);
139
140 /*
141 ================
142 GL_MemoryTypeFromProperties
143 ================
144 */
GL_MemoryTypeFromProperties(uint32_t type_bits,VkFlags requirements_mask,VkFlags preferred_mask)145 int GL_MemoryTypeFromProperties(uint32_t type_bits, VkFlags requirements_mask, VkFlags preferred_mask)
146 {
147 uint32_t current_type_bits = type_bits;
148 uint32_t i;
149
150 for (i = 0; i < VK_MAX_MEMORY_TYPES; i++)
151 {
152 if ((current_type_bits & 1) == 1)
153 {
154 if ((vulkan_globals.memory_properties.memoryTypes[i].propertyFlags & (requirements_mask | preferred_mask)) == (requirements_mask | preferred_mask))
155 return i;
156 }
157 current_type_bits >>= 1;
158 }
159
160 current_type_bits = type_bits;
161 for (i = 0; i < VK_MAX_MEMORY_TYPES; i++)
162 {
163 if ((current_type_bits & 1) == 1)
164 {
165 if ((vulkan_globals.memory_properties.memoryTypes[i].propertyFlags & requirements_mask) == requirements_mask)
166 return i;
167 }
168 current_type_bits >>= 1;
169 }
170
171 Sys_Error("Could not find memory type");
172 return 0;
173 }
174
175 /*
176 ====================
177 GL_Fullbrights_f -- johnfitz
178 ====================
179 */
GL_Fullbrights_f(cvar_t * var)180 static void GL_Fullbrights_f (cvar_t *var)
181 {
182 TexMgr_ReloadNobrightImages ();
183 }
184
185 /*
186 ====================
187 SetClearColor
188 ====================
189 */
SetClearColor()190 static void SetClearColor()
191 {
192 byte *rgb;
193 int s;
194
195 if (r_fastclear.value != 0.0f)
196 {
197 // Set to black so fast clear works properly on modern GPUs
198 vulkan_globals.color_clear_value.color.float32[0] = 0.0f;
199 vulkan_globals.color_clear_value.color.float32[1] = 0.0f;
200 vulkan_globals.color_clear_value.color.float32[2] = 0.0f;
201 vulkan_globals.color_clear_value.color.float32[3] = 0.0f;
202 }
203 else
204 {
205 s = (int)r_clearcolor.value & 0xFF;
206 rgb = (byte*)(d_8to24table + s);
207 vulkan_globals.color_clear_value.color.float32[0] = rgb[0]/255.0f;
208 vulkan_globals.color_clear_value.color.float32[1] = rgb[1]/255.0f;
209 vulkan_globals.color_clear_value.color.float32[2] = rgb[2]/255.0f;
210 vulkan_globals.color_clear_value.color.float32[3] = 0.0f;
211 }
212 }
213
214 /*
215 ====================
216 R_SetClearColor_f -- johnfitz
217 ====================
218 */
R_SetClearColor_f(cvar_t * var)219 static void R_SetClearColor_f (cvar_t *var)
220 {
221 if (r_fastclear.value != 0.0f)
222 Con_Warning("Black clear color forced by r_fastclear\n");
223
224 SetClearColor();
225 }
226
227 /*
228 ====================
229 R_SetFastClear_f -- johnfitz
230 ====================
231 */
R_SetFastClear_f(cvar_t * var)232 static void R_SetFastClear_f (cvar_t *var)
233 {
234 SetClearColor();
235 }
236
237 /*
238 ===============
239 R_Model_ExtraFlags_List_f -- johnfitz -- called when r_nolerp_list cvar changes
240 ===============
241 */
R_Model_ExtraFlags_List_f(cvar_t * var)242 static void R_Model_ExtraFlags_List_f (cvar_t *var)
243 {
244 int i;
245 for (i=0; i < MAX_MODELS; i++)
246 Mod_SetExtraFlags (cl.model_precache[i]);
247 }
248
249 /*
250 ====================
251 R_SetWateralpha_f -- ericw
252 ====================
253 */
R_SetWateralpha_f(cvar_t * var)254 static void R_SetWateralpha_f (cvar_t *var)
255 {
256 if (cls.signon == SIGNONS && cl.worldmodel && !(cl.worldmodel->contentstransparent&SURF_DRAWWATER) && var->value < 1)
257 Con_Warning("Map does not appear to be water-vised\n");
258 map_wateralpha = var->value;
259 map_fallbackalpha = var->value;
260 }
261
262 #if defined(USE_SIMD)
263 /*
264 ====================
265 R_SIMD_f
266 ====================
267 */
R_SIMD_f(cvar_t * var)268 static void R_SIMD_f (cvar_t *var)
269 {
270 #if defined(USE_SSE2)
271 use_simd = SDL_HasSSE() && SDL_HasSSE2() && (var->value != 0.0f);
272 #else
273 #error not implemented
274 #endif
275 }
276 #endif
277
278 /*
279 ====================
280 R_SetLavaalpha_f -- ericw
281 ====================
282 */
R_SetLavaalpha_f(cvar_t * var)283 static void R_SetLavaalpha_f (cvar_t *var)
284 {
285 if (cls.signon == SIGNONS && cl.worldmodel && !(cl.worldmodel->contentstransparent&SURF_DRAWLAVA) && var->value && var->value < 1)
286 Con_Warning("Map does not appear to be lava-vised\n");
287 map_lavaalpha = var->value;
288 }
289
290 /*
291 ====================
292 R_SetTelealpha_f -- ericw
293 ====================
294 */
R_SetTelealpha_f(cvar_t * var)295 static void R_SetTelealpha_f (cvar_t *var)
296 {
297 if (cls.signon == SIGNONS && cl.worldmodel && !(cl.worldmodel->contentstransparent&SURF_DRAWTELE) && var->value && var->value < 1)
298 Con_Warning("Map does not appear to be tele-vised\n");
299 map_telealpha = var->value;
300 }
301
302 /*
303 ====================
304 R_SetSlimealpha_f -- ericw
305 ====================
306 */
R_SetSlimealpha_f(cvar_t * var)307 static void R_SetSlimealpha_f (cvar_t *var)
308 {
309 if (cls.signon == SIGNONS && cl.worldmodel && !(cl.worldmodel->contentstransparent&SURF_DRAWSLIME) && var->value && var->value < 1)
310 Con_Warning("Map does not appear to be slime-vised\n");
311 map_slimealpha = var->value;
312 }
313
314 /*
315 ====================
316 GL_WaterAlphaForSurfface -- ericw
317 ====================
318 */
GL_WaterAlphaForSurface(msurface_t * fa)319 float GL_WaterAlphaForSurface (msurface_t *fa)
320 {
321 if (fa->flags & SURF_DRAWLAVA)
322 return map_lavaalpha > 0 ? map_lavaalpha : map_fallbackalpha;
323 else if (fa->flags & SURF_DRAWTELE)
324 return map_telealpha > 0 ? map_telealpha : map_fallbackalpha;
325 else if (fa->flags & SURF_DRAWSLIME)
326 return map_slimealpha > 0 ? map_slimealpha : map_fallbackalpha;
327 else
328 return map_wateralpha;
329 }
330
331 /*
332 ===============
333 R_CreateStagingBuffers
334 ===============
335 */
R_CreateStagingBuffers()336 static void R_CreateStagingBuffers()
337 {
338 int i;
339 VkResult err;
340
341 VkBufferCreateInfo buffer_create_info;
342 memset(&buffer_create_info, 0, sizeof(buffer_create_info));
343 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
344 buffer_create_info.size = vulkan_globals.staging_buffer_size;
345 buffer_create_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
346
347 for (i = 0; i < NUM_STAGING_BUFFERS; ++i)
348 {
349 staging_buffers[i].current_offset = 0;
350 staging_buffers[i].submitted = false;
351
352 err = vkCreateBuffer(vulkan_globals.device, &buffer_create_info, NULL, &staging_buffers[i].buffer);
353 if (err != VK_SUCCESS)
354 Sys_Error("vkCreateBuffer failed");
355
356 GL_SetObjectName((uint64_t)staging_buffers[i].buffer, VK_OBJECT_TYPE_BUFFER, "Staging Buffer");
357 }
358
359 VkMemoryRequirements memory_requirements;
360 vkGetBufferMemoryRequirements(vulkan_globals.device, staging_buffers[0].buffer, &memory_requirements);
361
362 const int align_mod = memory_requirements.size % memory_requirements.alignment;
363 const int aligned_size = ((memory_requirements.size % memory_requirements.alignment) == 0)
364 ? memory_requirements.size
365 : (memory_requirements.size + memory_requirements.alignment - align_mod);
366
367 VkMemoryAllocateInfo memory_allocate_info;
368 memset(&memory_allocate_info, 0, sizeof(memory_allocate_info));
369 memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
370 memory_allocate_info.allocationSize = NUM_STAGING_BUFFERS * aligned_size;
371 memory_allocate_info.memoryTypeIndex = GL_MemoryTypeFromProperties(memory_requirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_CACHED_BIT);
372
373 num_vulkan_misc_allocations += 1;
374 R_AllocateVulkanMemory(&staging_memory, &memory_allocate_info, VULKAN_MEMORY_TYPE_HOST);
375 GL_SetObjectName((uint64_t)staging_memory.handle, VK_OBJECT_TYPE_DEVICE_MEMORY, "Staging Buffers");
376
377 for (i = 0; i < NUM_STAGING_BUFFERS; ++i)
378 {
379 err = vkBindBufferMemory(vulkan_globals.device, staging_buffers[i].buffer, staging_memory.handle, i * aligned_size);
380 if (err != VK_SUCCESS)
381 Sys_Error("vkBindBufferMemory failed");
382 }
383
384 void * data;
385 err = vkMapMemory(vulkan_globals.device, staging_memory.handle, 0, NUM_STAGING_BUFFERS * aligned_size, 0, &data);
386 if (err != VK_SUCCESS)
387 Sys_Error("vkMapMemory failed");
388
389 for (i = 0; i < NUM_STAGING_BUFFERS; ++i)
390 staging_buffers[i].data = (unsigned char *)data + (i * aligned_size);
391 }
392
393 /*
394 ===============
395 R_DestroyStagingBuffers
396 ===============
397 */
R_DestroyStagingBuffers()398 static void R_DestroyStagingBuffers()
399 {
400 int i;
401
402 vkUnmapMemory(vulkan_globals.device, staging_memory.handle);
403 R_FreeVulkanMemory(&staging_memory);
404 for (i = 0; i < NUM_STAGING_BUFFERS; ++i) {
405 vkDestroyBuffer(vulkan_globals.device, staging_buffers[i].buffer, NULL);
406 }
407 }
408
409 /*
410 ===============
411 R_InitStagingBuffers
412 ===============
413 */
R_InitStagingBuffers()414 void R_InitStagingBuffers()
415 {
416 int i;
417 VkResult err;
418
419 Con_Printf("Initializing staging\n");
420
421 R_CreateStagingBuffers();
422
423 VkCommandPoolCreateInfo command_pool_create_info;
424 memset(&command_pool_create_info, 0, sizeof(command_pool_create_info));
425 command_pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
426 command_pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
427 command_pool_create_info.queueFamilyIndex = vulkan_globals.gfx_queue_family_index;
428
429 err = vkCreateCommandPool(vulkan_globals.device, &command_pool_create_info, NULL, &staging_command_pool);
430 if (err != VK_SUCCESS)
431 Sys_Error("vkCreateCommandPool failed");
432
433 VkCommandBufferAllocateInfo command_buffer_allocate_info;
434 memset(&command_buffer_allocate_info, 0, sizeof(command_buffer_allocate_info));
435 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
436 command_buffer_allocate_info.commandPool = staging_command_pool;
437 command_buffer_allocate_info.commandBufferCount = NUM_STAGING_BUFFERS;
438
439 VkCommandBuffer command_buffers[NUM_STAGING_BUFFERS];
440 err = vkAllocateCommandBuffers(vulkan_globals.device, &command_buffer_allocate_info, command_buffers);
441 if (err != VK_SUCCESS)
442 Sys_Error("vkAllocateCommandBuffers failed");
443
444 VkFenceCreateInfo fence_create_info;
445 memset(&fence_create_info, 0, sizeof(fence_create_info));
446 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
447
448 VkCommandBufferBeginInfo command_buffer_begin_info;
449 memset(&command_buffer_begin_info, 0, sizeof(command_buffer_begin_info));
450 command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
451 command_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
452
453 for (i = 0; i < NUM_STAGING_BUFFERS; ++i)
454 {
455 err = vkCreateFence(vulkan_globals.device, &fence_create_info, NULL, &staging_buffers[i].fence);
456 if (err != VK_SUCCESS)
457 Sys_Error("vkCreateFence failed");
458
459 staging_buffers[i].command_buffer = command_buffers[i];
460
461 err = vkBeginCommandBuffer(staging_buffers[i].command_buffer, &command_buffer_begin_info);
462 if (err != VK_SUCCESS)
463 Sys_Error("vkBeginCommandBuffer failed");
464 }
465 }
466
467 /*
468 ===============
469 R_SubmitStagingBuffer
470 ===============
471 */
R_SubmitStagingBuffer(int index)472 static void R_SubmitStagingBuffer(int index)
473 {
474 VkMemoryBarrier memory_barrier;
475 memset(&memory_barrier, 0, sizeof(memory_barrier));
476 memory_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
477 memory_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
478 memory_barrier.dstAccessMask = VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
479 vkCmdPipelineBarrier(staging_buffers[index].command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, 1, &memory_barrier, 0, NULL, 0, NULL);
480
481 vkEndCommandBuffer(staging_buffers[index].command_buffer);
482
483 VkMappedMemoryRange range;
484 memset(&range, 0, sizeof(range));
485 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
486 range.memory = staging_memory.handle;
487 range.size = VK_WHOLE_SIZE;
488 vkFlushMappedMemoryRanges(vulkan_globals.device, 1, &range);
489
490 VkSubmitInfo submit_info;
491 memset(&submit_info, 0, sizeof(submit_info));
492 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
493 submit_info.commandBufferCount = 1;
494 submit_info.pCommandBuffers = &staging_buffers[index].command_buffer;
495
496 vkQueueSubmit(vulkan_globals.queue, 1, &submit_info, staging_buffers[index].fence);
497
498 staging_buffers[index].submitted = true;
499 current_staging_buffer = (current_staging_buffer + 1) % NUM_STAGING_BUFFERS;
500 }
501
502 /*
503 ===============
504 R_SubmitStagingBuffers
505 ===============
506 */
R_SubmitStagingBuffers()507 void R_SubmitStagingBuffers()
508 {
509 int i;
510 for (i = 0; i<NUM_STAGING_BUFFERS; ++i)
511 {
512 if (!staging_buffers[i].submitted && staging_buffers[i].current_offset > 0)
513 R_SubmitStagingBuffer(i);
514 }
515 }
516
517 /*
518 ===============
519 R_FlushStagingBuffer
520 ===============
521 */
R_FlushStagingBuffer(stagingbuffer_t * staging_buffer)522 static void R_FlushStagingBuffer(stagingbuffer_t * staging_buffer)
523 {
524 VkResult err;
525
526 if (!staging_buffer->submitted)
527 return;
528
529 err = vkWaitForFences(vulkan_globals.device, 1, &staging_buffer->fence, VK_TRUE, UINT64_MAX);
530 if (err != VK_SUCCESS)
531 Sys_Error("vkWaitForFences failed");
532
533 err = vkResetFences(vulkan_globals.device, 1, &staging_buffer->fence);
534 if (err != VK_SUCCESS)
535 Sys_Error("vkResetFences failed");
536
537 staging_buffer->current_offset = 0;
538 staging_buffer->submitted = false;
539
540 VkCommandBufferBeginInfo command_buffer_begin_info;
541 memset(&command_buffer_begin_info, 0, sizeof(command_buffer_begin_info));
542 command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
543 command_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
544
545 err = vkBeginCommandBuffer(staging_buffer->command_buffer, &command_buffer_begin_info);
546 if (err != VK_SUCCESS)
547 Sys_Error("vkBeginCommandBuffer failed");
548 }
549
550 /*
551 ===============
552 R_StagingAllocate
553 ===============
554 */
R_StagingAllocate(int size,int alignment,VkCommandBuffer * command_buffer,VkBuffer * buffer,int * buffer_offset)555 byte * R_StagingAllocate(int size, int alignment, VkCommandBuffer * command_buffer, VkBuffer * buffer, int * buffer_offset)
556 {
557 vulkan_globals.device_idle = false;
558
559 if (size > vulkan_globals.staging_buffer_size)
560 {
561 R_SubmitStagingBuffers();
562
563 for (int i = 0; i < NUM_STAGING_BUFFERS; ++i)
564 R_FlushStagingBuffer(&staging_buffers[i]);
565
566 vulkan_globals.staging_buffer_size = size;
567
568 R_DestroyStagingBuffers();
569 R_CreateStagingBuffers();
570 }
571
572 stagingbuffer_t * staging_buffer = &staging_buffers[current_staging_buffer];
573 const int align_mod = staging_buffer->current_offset % alignment;
574 staging_buffer->current_offset = ((staging_buffer->current_offset % alignment) == 0)
575 ? staging_buffer->current_offset
576 : (staging_buffer->current_offset + alignment - align_mod);
577
578 if ((staging_buffer->current_offset + size) >= vulkan_globals.staging_buffer_size && !staging_buffer->submitted)
579 R_SubmitStagingBuffer(current_staging_buffer);
580
581 staging_buffer = &staging_buffers[current_staging_buffer];
582 R_FlushStagingBuffer(staging_buffer);
583
584 if (command_buffer)
585 *command_buffer = staging_buffer->command_buffer;
586 if (buffer)
587 *buffer = staging_buffer->buffer;
588 if (buffer_offset)
589 *buffer_offset = staging_buffer->current_offset;
590
591 unsigned char *data = staging_buffer->data + staging_buffer->current_offset;
592 staging_buffer->current_offset += size;
593
594 return data;
595 }
596
597 /*
598 ===============
599 R_InitDynamicVertexBuffers
600 ===============
601 */
R_InitDynamicVertexBuffers()602 static void R_InitDynamicVertexBuffers()
603 {
604 int i;
605
606 Sys_Printf("Reallocating dynamic VBs (%u KB)\n", current_dyn_vertex_buffer_size / 1024);
607
608 VkResult err;
609
610 VkBufferCreateInfo buffer_create_info;
611 memset(&buffer_create_info, 0, sizeof(buffer_create_info));
612 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
613 buffer_create_info.size = current_dyn_vertex_buffer_size;
614 buffer_create_info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
615
616 for (i = 0; i < NUM_DYNAMIC_BUFFERS; ++i)
617 {
618 dyn_vertex_buffers[i].current_offset = 0;
619
620 err = vkCreateBuffer(vulkan_globals.device, &buffer_create_info, NULL, &dyn_vertex_buffers[i].buffer);
621 if (err != VK_SUCCESS)
622 Sys_Error("vkCreateBuffer failed");
623
624 GL_SetObjectName((uint64_t)dyn_vertex_buffers[i].buffer, VK_OBJECT_TYPE_BUFFER, "Dynamic Vertex Buffer");
625 }
626
627 VkMemoryRequirements memory_requirements;
628 vkGetBufferMemoryRequirements(vulkan_globals.device, dyn_vertex_buffers[0].buffer, &memory_requirements);
629
630 const int align_mod = memory_requirements.size % memory_requirements.alignment;
631 const int aligned_size = ((memory_requirements.size % memory_requirements.alignment) == 0)
632 ? memory_requirements.size
633 : (memory_requirements.size + memory_requirements.alignment - align_mod);
634
635 VkMemoryAllocateInfo memory_allocate_info;
636 memset(&memory_allocate_info, 0, sizeof(memory_allocate_info));
637 memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
638 memory_allocate_info.allocationSize = NUM_DYNAMIC_BUFFERS * aligned_size;
639 memory_allocate_info.memoryTypeIndex = GL_MemoryTypeFromProperties(memory_requirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_CACHED_BIT);
640
641 num_vulkan_dynbuf_allocations += 1;
642 R_AllocateVulkanMemory(&dyn_vertex_buffer_memory, &memory_allocate_info, VULKAN_MEMORY_TYPE_HOST);
643 GL_SetObjectName((uint64_t)dyn_vertex_buffer_memory.handle, VK_OBJECT_TYPE_DEVICE_MEMORY, "Dynamic Vertex Buffers");
644
645 for (i = 0; i < NUM_DYNAMIC_BUFFERS; ++i)
646 {
647 err = vkBindBufferMemory(vulkan_globals.device, dyn_vertex_buffers[i].buffer, dyn_vertex_buffer_memory.handle, i * aligned_size);
648 if (err != VK_SUCCESS)
649 Sys_Error("vkBindBufferMemory failed");
650 }
651
652 void * data;
653 err = vkMapMemory(vulkan_globals.device, dyn_vertex_buffer_memory.handle, 0, NUM_DYNAMIC_BUFFERS * aligned_size, 0, &data);
654 if (err != VK_SUCCESS)
655 Sys_Error("vkMapMemory failed");
656
657 for (i = 0; i < NUM_DYNAMIC_BUFFERS; ++i)
658 dyn_vertex_buffers[i].data = (unsigned char *)data + (i * aligned_size);
659 }
660
661 /*
662 ===============
663 R_InitDynamicIndexBuffers
664 ===============
665 */
R_InitDynamicIndexBuffers()666 static void R_InitDynamicIndexBuffers()
667 {
668 int i;
669
670 Sys_Printf("Reallocating dynamic IBs (%u KB)\n", current_dyn_index_buffer_size / 1024);
671
672 VkResult err;
673
674 VkBufferCreateInfo buffer_create_info;
675 memset(&buffer_create_info, 0, sizeof(buffer_create_info));
676 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
677 buffer_create_info.size = current_dyn_index_buffer_size;
678 buffer_create_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
679
680 for (i = 0; i < NUM_DYNAMIC_BUFFERS; ++i)
681 {
682 dyn_index_buffers[i].current_offset = 0;
683
684 err = vkCreateBuffer(vulkan_globals.device, &buffer_create_info, NULL, &dyn_index_buffers[i].buffer);
685 if (err != VK_SUCCESS)
686 Sys_Error("vkCreateBuffer failed");
687
688 GL_SetObjectName((uint64_t)dyn_index_buffers[i].buffer, VK_OBJECT_TYPE_BUFFER, "Dynamic Index Buffer");
689 }
690
691 VkMemoryRequirements memory_requirements;
692 vkGetBufferMemoryRequirements(vulkan_globals.device, dyn_index_buffers[0].buffer, &memory_requirements);
693
694 const int align_mod = memory_requirements.size % memory_requirements.alignment;
695 const int aligned_size = ((memory_requirements.size % memory_requirements.alignment) == 0)
696 ? memory_requirements.size
697 : (memory_requirements.size + memory_requirements.alignment - align_mod);
698
699 VkMemoryAllocateInfo memory_allocate_info;
700 memset(&memory_allocate_info, 0, sizeof(memory_allocate_info));
701 memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
702 memory_allocate_info.allocationSize = NUM_DYNAMIC_BUFFERS * aligned_size;
703 memory_allocate_info.memoryTypeIndex = GL_MemoryTypeFromProperties(memory_requirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_CACHED_BIT);
704
705 num_vulkan_dynbuf_allocations += 1;
706 R_AllocateVulkanMemory(&dyn_index_buffer_memory, &memory_allocate_info, VULKAN_MEMORY_TYPE_HOST);
707 GL_SetObjectName((uint64_t)dyn_index_buffer_memory.handle, VK_OBJECT_TYPE_DEVICE_MEMORY, "Dynamic Index Buffers");
708
709 for (i = 0; i < NUM_DYNAMIC_BUFFERS; ++i)
710 {
711 err = vkBindBufferMemory(vulkan_globals.device, dyn_index_buffers[i].buffer, dyn_index_buffer_memory.handle, i * aligned_size);
712 if (err != VK_SUCCESS)
713 Sys_Error("vkBindBufferMemory failed");
714 }
715
716 void * data;
717 err = vkMapMemory(vulkan_globals.device, dyn_index_buffer_memory.handle, 0, NUM_DYNAMIC_BUFFERS * aligned_size, 0, &data);
718 if (err != VK_SUCCESS)
719 Sys_Error("vkMapMemory failed");
720
721 for (i = 0; i < NUM_DYNAMIC_BUFFERS; ++i)
722 dyn_index_buffers[i].data = (unsigned char *)data + (i * aligned_size);
723 }
724
725 /*
726 ===============
727 R_InitDynamicUniformBuffers
728 ===============
729 */
R_InitDynamicUniformBuffers()730 static void R_InitDynamicUniformBuffers()
731 {
732 int i;
733
734 Sys_Printf("Reallocating dynamic UBs (%u KB)\n", current_dyn_uniform_buffer_size / 1024);
735
736 VkResult err;
737
738 VkBufferCreateInfo buffer_create_info;
739 memset(&buffer_create_info, 0, sizeof(buffer_create_info));
740 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
741 buffer_create_info.size = current_dyn_uniform_buffer_size;
742 buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
743
744 for (i = 0; i < NUM_DYNAMIC_BUFFERS; ++i)
745 {
746 dyn_uniform_buffers[i].current_offset = 0;
747
748 err = vkCreateBuffer(vulkan_globals.device, &buffer_create_info, NULL, &dyn_uniform_buffers[i].buffer);
749 if (err != VK_SUCCESS)
750 Sys_Error("vkCreateBuffer failed");
751
752 GL_SetObjectName((uint64_t)dyn_uniform_buffers[i].buffer, VK_OBJECT_TYPE_BUFFER, "Dynamic Uniform Buffer");
753 }
754
755 VkMemoryRequirements memory_requirements;
756 vkGetBufferMemoryRequirements(vulkan_globals.device, dyn_uniform_buffers[0].buffer, &memory_requirements);
757
758 const int align_mod = memory_requirements.size % memory_requirements.alignment;
759 const int aligned_size = ((memory_requirements.size % memory_requirements.alignment) == 0)
760 ? memory_requirements.size
761 : (memory_requirements.size + memory_requirements.alignment - align_mod);
762
763 VkMemoryAllocateInfo memory_allocate_info;
764 memset(&memory_allocate_info, 0, sizeof(memory_allocate_info));
765 memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
766 memory_allocate_info.allocationSize = NUM_DYNAMIC_BUFFERS * aligned_size;
767 memory_allocate_info.memoryTypeIndex = GL_MemoryTypeFromProperties(memory_requirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_CACHED_BIT);
768
769 num_vulkan_dynbuf_allocations += 1;
770 R_AllocateVulkanMemory(&dyn_uniform_buffer_memory, &memory_allocate_info, VULKAN_MEMORY_TYPE_HOST);
771 GL_SetObjectName((uint64_t)dyn_uniform_buffer_memory.handle, VK_OBJECT_TYPE_DEVICE_MEMORY, "Dynamic Uniform Buffers");
772
773 for (i = 0; i < NUM_DYNAMIC_BUFFERS; ++i)
774 {
775 err = vkBindBufferMemory(vulkan_globals.device, dyn_uniform_buffers[i].buffer, dyn_uniform_buffer_memory.handle, i * aligned_size);
776 if (err != VK_SUCCESS)
777 Sys_Error("vkBindBufferMemory failed");
778 }
779
780 void * data;
781 err = vkMapMemory(vulkan_globals.device, dyn_uniform_buffer_memory.handle, 0, NUM_DYNAMIC_BUFFERS * aligned_size, 0, &data);
782 if (err != VK_SUCCESS)
783 Sys_Error("vkMapMemory failed");
784
785 for (i = 0; i < NUM_DYNAMIC_BUFFERS; ++i)
786 dyn_uniform_buffers[i].data = (unsigned char *)data + (i * aligned_size);
787
788 VkDescriptorSetAllocateInfo descriptor_set_allocate_info;
789 memset(&descriptor_set_allocate_info, 0, sizeof(descriptor_set_allocate_info));
790 descriptor_set_allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
791 descriptor_set_allocate_info.descriptorPool = vulkan_globals.descriptor_pool;
792 descriptor_set_allocate_info.descriptorSetCount = 1;
793 descriptor_set_allocate_info.pSetLayouts = &vulkan_globals.ubo_set_layout.handle;
794
795 ubo_descriptor_sets[0] = R_AllocateDescriptorSet(&vulkan_globals.ubo_set_layout);
796 ubo_descriptor_sets[1] = R_AllocateDescriptorSet(&vulkan_globals.ubo_set_layout);
797
798 VkDescriptorBufferInfo buffer_info;
799 memset(&buffer_info, 0, sizeof(buffer_info));
800 buffer_info.offset = 0;
801 buffer_info.range = MAX_UNIFORM_ALLOC;
802
803 VkWriteDescriptorSet ubo_write;
804 memset(&ubo_write, 0, sizeof(ubo_write));
805 ubo_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
806 ubo_write.dstBinding = 0;
807 ubo_write.dstArrayElement = 0;
808 ubo_write.descriptorCount = 1;
809 ubo_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
810 ubo_write.pBufferInfo = &buffer_info;
811
812 for (i = 0; i < NUM_DYNAMIC_BUFFERS; ++i)
813 {
814 buffer_info.buffer = dyn_uniform_buffers[i].buffer;
815 ubo_write.dstSet = ubo_descriptor_sets[i];
816 vkUpdateDescriptorSets(vulkan_globals.device, 1, &ubo_write, 0, NULL);
817 }
818 }
819
820 /*
821 ===============
822 R_InitFanIndexBuffer
823 ===============
824 */
R_InitFanIndexBuffer()825 static void R_InitFanIndexBuffer()
826 {
827 VkResult err;
828 VkDeviceMemory memory;
829 const int bufferSize = sizeof(uint16_t) * FAN_INDEX_BUFFER_SIZE;
830
831 VkBufferCreateInfo buffer_create_info;
832 memset(&buffer_create_info, 0, sizeof(buffer_create_info));
833 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
834 buffer_create_info.size = bufferSize;
835 buffer_create_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
836
837 err = vkCreateBuffer(vulkan_globals.device, &buffer_create_info, NULL, &vulkan_globals.fan_index_buffer);
838 if (err != VK_SUCCESS)
839 Sys_Error("vkCreateBuffer failed");
840
841 GL_SetObjectName((uint64_t)vulkan_globals.fan_index_buffer, VK_OBJECT_TYPE_BUFFER, "Quad Index Buffer");
842
843 VkMemoryRequirements memory_requirements;
844 vkGetBufferMemoryRequirements(vulkan_globals.device, vulkan_globals.fan_index_buffer, &memory_requirements);
845
846 VkMemoryAllocateInfo memory_allocate_info;
847 memset(&memory_allocate_info, 0, sizeof(memory_allocate_info));
848 memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
849 memory_allocate_info.allocationSize = memory_requirements.size;
850 memory_allocate_info.memoryTypeIndex = GL_MemoryTypeFromProperties(memory_requirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0);
851
852 num_vulkan_dynbuf_allocations += 1;
853 total_device_vulkan_allocation_size += memory_requirements.size;
854 err = vkAllocateMemory(vulkan_globals.device, &memory_allocate_info, NULL, &memory);
855 if (err != VK_SUCCESS)
856 Sys_Error("vkAllocateMemory failed");
857
858 err = vkBindBufferMemory(vulkan_globals.device, vulkan_globals.fan_index_buffer, memory, 0);
859 if (err != VK_SUCCESS)
860 Sys_Error("vkBindBufferMemory failed");
861
862 {
863 VkBuffer staging_buffer;
864 VkCommandBuffer command_buffer;
865 int staging_offset;
866 int current_index = 0;
867 int i;
868 uint16_t * staging_mem = (uint16_t*)R_StagingAllocate(bufferSize, 1, &command_buffer, &staging_buffer, &staging_offset);
869
870 for (i = 0; i < FAN_INDEX_BUFFER_SIZE / 3; ++i)
871 {
872 staging_mem[current_index++] = 0;
873 staging_mem[current_index++] = 1 + i;
874 staging_mem[current_index++] = 2 + i;
875 }
876
877 VkBufferCopy region;
878 region.srcOffset = staging_offset;
879 region.dstOffset = 0;
880 region.size = bufferSize;
881 vkCmdCopyBuffer(command_buffer, staging_buffer, vulkan_globals.fan_index_buffer, 1, ®ion);
882 }
883 }
884
885 /*
886 ===============
887 R_SwapDynamicBuffers
888 ===============
889 */
R_SwapDynamicBuffers()890 void R_SwapDynamicBuffers()
891 {
892 current_dyn_buffer_index = (current_dyn_buffer_index + 1) % NUM_DYNAMIC_BUFFERS;
893 dyn_vertex_buffers[current_dyn_buffer_index].current_offset = 0;
894 dyn_index_buffers[current_dyn_buffer_index].current_offset = 0;
895 dyn_uniform_buffers[current_dyn_buffer_index].current_offset = 0;
896 }
897
898 /*
899 ===============
900 R_FlushDynamicBuffers
901 ===============
902 */
R_FlushDynamicBuffers()903 void R_FlushDynamicBuffers()
904 {
905 VkMappedMemoryRange ranges[3];
906 memset(&ranges, 0, sizeof(ranges));
907 ranges[0].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
908 ranges[0].memory = dyn_vertex_buffer_memory.handle;
909 ranges[0].size = VK_WHOLE_SIZE;
910 ranges[1].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
911 ranges[1].memory = dyn_index_buffer_memory.handle;
912 ranges[1].size = VK_WHOLE_SIZE;
913 ranges[2].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
914 ranges[2].memory = dyn_uniform_buffer_memory.handle;
915 ranges[2].size = VK_WHOLE_SIZE;
916 vkFlushMappedMemoryRanges(vulkan_globals.device, 3, ranges);
917 }
918
919 /*
920 ===============
921 R_AddDynamicBufferGarbage
922 ===============
923 */
R_AddDynamicBufferGarbage(vulkan_memory_t device_memory,dynbuffer_t * buffers,VkDescriptorSet * descriptor_sets)924 static void R_AddDynamicBufferGarbage(vulkan_memory_t device_memory, dynbuffer_t * buffers, VkDescriptorSet * descriptor_sets)
925 {
926 {
927 int * num_garbage = &num_device_memory_garbage[current_garbage_index];
928 int old_num_memory_garbage = *num_garbage;
929 *num_garbage += 1;
930 if (device_memory_garbage[current_garbage_index] == NULL)
931 device_memory_garbage[current_garbage_index] = malloc(sizeof(vulkan_memory_t) * (*num_garbage));
932 else
933 device_memory_garbage[current_garbage_index] = realloc(device_memory_garbage[current_garbage_index], sizeof(vulkan_memory_t) * (*num_garbage));
934 device_memory_garbage[current_garbage_index][old_num_memory_garbage] = device_memory;
935 }
936
937 {
938 int * num_garbage = &num_buffer_garbage[current_garbage_index];
939 int old_num_buffer_garbage = *num_garbage;
940 *num_garbage += NUM_DYNAMIC_BUFFERS;
941 if (buffer_garbage[current_garbage_index] == NULL)
942 buffer_garbage[current_garbage_index] = malloc(sizeof(VkBuffer) * (*num_garbage));
943 else
944 buffer_garbage[current_garbage_index] = realloc(buffer_garbage[current_garbage_index], sizeof(VkBuffer) * (*num_garbage));
945 for (int i = 0; i < NUM_DYNAMIC_BUFFERS; ++i)
946 buffer_garbage[current_garbage_index][old_num_buffer_garbage + i] = buffers[i].buffer;
947 }
948
949 if (descriptor_sets)
950 {
951 int * num_garbage = &num_desc_set_garbage[current_garbage_index];
952 int old_num_desc_set_garbage = *num_garbage;
953 *num_garbage += 2;
954 if (descriptor_set_garbage[current_garbage_index] == NULL)
955 descriptor_set_garbage[current_garbage_index] = malloc(sizeof(VkDescriptorSet) * (*num_garbage));
956 else
957 descriptor_set_garbage[current_garbage_index] = realloc(descriptor_set_garbage[current_garbage_index], sizeof(VkDescriptorSet) * (*num_garbage));
958 for (int i = 0; i < 2; ++i)
959 descriptor_set_garbage[current_garbage_index][old_num_desc_set_garbage + i] = descriptor_sets[i];
960 }
961 }
962
963 /*
964 ===============
965 R_CollectDynamicBufferGarbage
966 ===============
967 */
R_CollectDynamicBufferGarbage()968 void R_CollectDynamicBufferGarbage()
969 {
970 current_garbage_index = (current_garbage_index + 1) % GARBAGE_FRAME_COUNT;
971 const int collect_garbage_index = (current_garbage_index + 1) % GARBAGE_FRAME_COUNT;
972
973 if (num_desc_set_garbage[collect_garbage_index] > 0) {
974 for (int i = 0; i < num_desc_set_garbage[collect_garbage_index]; ++i)
975 R_FreeDescriptorSet(descriptor_set_garbage[collect_garbage_index][i], &vulkan_globals.ubo_set_layout);
976 free(descriptor_set_garbage[collect_garbage_index]);
977 descriptor_set_garbage[collect_garbage_index] = NULL;
978 num_desc_set_garbage[collect_garbage_index] = 0;
979 }
980
981 if (num_buffer_garbage[collect_garbage_index] > 0) {
982 for (int i = 0; i < num_buffer_garbage[collect_garbage_index]; ++i)
983 vkDestroyBuffer(vulkan_globals.device, buffer_garbage[collect_garbage_index][i], NULL);
984 free(buffer_garbage[collect_garbage_index]);
985 buffer_garbage[collect_garbage_index] = NULL;
986 num_buffer_garbage[collect_garbage_index] = 0;
987 }
988
989 if (num_device_memory_garbage[collect_garbage_index] > 0) {
990 for (int i = 0; i < num_device_memory_garbage[collect_garbage_index]; ++i)
991 R_FreeVulkanMemory(&device_memory_garbage[collect_garbage_index][i]);
992 free(device_memory_garbage[collect_garbage_index]);
993 device_memory_garbage[collect_garbage_index] = NULL;
994 num_device_memory_garbage[collect_garbage_index] = 0;
995 }
996 }
997
998 /*
999 ===============
1000 R_VertexAllocate
1001 ===============
1002 */
R_VertexAllocate(int size,VkBuffer * buffer,VkDeviceSize * buffer_offset)1003 byte * R_VertexAllocate(int size, VkBuffer * buffer, VkDeviceSize * buffer_offset)
1004 {
1005 dynbuffer_t *dyn_vb = &dyn_vertex_buffers[current_dyn_buffer_index];
1006
1007 if ((dyn_vb->current_offset + size) > current_dyn_vertex_buffer_size)
1008 {
1009 R_AddDynamicBufferGarbage(dyn_vertex_buffer_memory, dyn_vertex_buffers, NULL);
1010 current_dyn_vertex_buffer_size = q_max(current_dyn_vertex_buffer_size * 2, (uint32_t)Q_nextPow2(size));
1011 vkUnmapMemory(vulkan_globals.device, dyn_vertex_buffer_memory.handle);
1012 R_InitDynamicVertexBuffers();
1013 }
1014
1015 *buffer = dyn_vb->buffer;
1016 *buffer_offset = dyn_vb->current_offset;
1017
1018 unsigned char *data = dyn_vb->data + dyn_vb->current_offset;
1019 dyn_vb->current_offset += size;
1020
1021 return data;
1022 }
1023
1024 /*
1025 ===============
1026 R_IndexAllocate
1027 ===============
1028 */
R_IndexAllocate(int size,VkBuffer * buffer,VkDeviceSize * buffer_offset)1029 byte * R_IndexAllocate(int size, VkBuffer * buffer, VkDeviceSize * buffer_offset)
1030 {
1031 // Align to 4 bytes because we allocate both uint16 and uint32
1032 // index buffers and alignment must match index size
1033 const int align_mod = size % 4;
1034 const int aligned_size = ((size % 4) == 0) ? size : (size + 4 - align_mod);
1035
1036 dynbuffer_t *dyn_ib = &dyn_index_buffers[current_dyn_buffer_index];
1037
1038 if ((dyn_ib->current_offset + aligned_size) > current_dyn_index_buffer_size)
1039 {
1040 R_AddDynamicBufferGarbage(dyn_index_buffer_memory, dyn_index_buffers, NULL);
1041 current_dyn_index_buffer_size = q_max(current_dyn_index_buffer_size * 2, (uint32_t)Q_nextPow2(size));
1042 vkUnmapMemory(vulkan_globals.device, dyn_index_buffer_memory.handle);
1043 R_InitDynamicIndexBuffers();
1044 }
1045
1046 *buffer = dyn_ib->buffer;
1047 *buffer_offset = dyn_ib->current_offset;
1048
1049 unsigned char *data = dyn_ib->data + dyn_ib->current_offset;
1050 dyn_ib->current_offset += aligned_size;
1051
1052 return data;
1053 }
1054
1055 /*
1056 ===============
1057 R_UniformAllocate
1058
1059 UBO offsets need to be 256 byte aligned on NVIDIA hardware
1060 This is also the maximum required alignment by the Vulkan spec
1061 ===============
1062 */
R_UniformAllocate(int size,VkBuffer * buffer,uint32_t * buffer_offset,VkDescriptorSet * descriptor_set)1063 byte * R_UniformAllocate(int size, VkBuffer * buffer, uint32_t * buffer_offset, VkDescriptorSet * descriptor_set)
1064 {
1065 if (size > MAX_UNIFORM_ALLOC)
1066 Sys_Error("Increase MAX_UNIFORM_ALLOC");
1067
1068 const int align_mod = size % 256;
1069 const int aligned_size = ((size % 256) == 0) ? size : (size + 256 - align_mod);
1070
1071 dynbuffer_t *dyn_ub = &dyn_uniform_buffers[current_dyn_buffer_index];
1072
1073 if ((dyn_ub->current_offset + MAX_UNIFORM_ALLOC) > current_dyn_uniform_buffer_size)
1074 {
1075 R_AddDynamicBufferGarbage(dyn_uniform_buffer_memory, dyn_uniform_buffers, ubo_descriptor_sets);
1076 current_dyn_uniform_buffer_size = q_max(current_dyn_uniform_buffer_size * 2, (uint32_t)Q_nextPow2(size));
1077 vkUnmapMemory(vulkan_globals.device, dyn_uniform_buffer_memory.handle);
1078 R_InitDynamicUniformBuffers();
1079 }
1080
1081 *buffer = dyn_ub->buffer;
1082 *buffer_offset = dyn_ub->current_offset;
1083
1084 unsigned char *data = dyn_ub->data + dyn_ub->current_offset;
1085 dyn_ub->current_offset += aligned_size;
1086
1087 *descriptor_set = ubo_descriptor_sets[current_dyn_buffer_index];
1088
1089 return data;
1090 }
1091
1092 /*
1093 ===============
1094 R_InitGPUBuffers
1095 ===============
1096 */
R_InitGPUBuffers()1097 void R_InitGPUBuffers()
1098 {
1099 R_InitDynamicVertexBuffers();
1100 R_InitDynamicIndexBuffers();
1101 R_InitDynamicUniformBuffers();
1102 R_InitFanIndexBuffer();
1103 }
1104
1105 /*
1106 ===============
1107 R_CreateDescriptorSetLayouts
1108 ===============
1109 */
R_CreateDescriptorSetLayouts()1110 void R_CreateDescriptorSetLayouts()
1111 {
1112 Sys_Printf("Creating descriptor set layouts\n");
1113
1114 VkResult err;
1115
1116 VkDescriptorSetLayoutBinding single_texture_layout_binding;
1117 memset(&single_texture_layout_binding, 0, sizeof(single_texture_layout_binding));
1118 single_texture_layout_binding.binding = 0;
1119 single_texture_layout_binding.descriptorCount = 1;
1120 single_texture_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
1121 single_texture_layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT;
1122
1123 VkDescriptorSetLayoutCreateInfo descriptor_set_layout_create_info;
1124 memset(&descriptor_set_layout_create_info, 0, sizeof(descriptor_set_layout_create_info));
1125 descriptor_set_layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
1126 descriptor_set_layout_create_info.bindingCount = 1;
1127 descriptor_set_layout_create_info.pBindings = &single_texture_layout_binding;
1128
1129 memset(&vulkan_globals.single_texture_set_layout, 0, sizeof(vulkan_globals.single_texture_set_layout));
1130 vulkan_globals.single_texture_set_layout.num_combined_image_samplers = 1;
1131
1132 err = vkCreateDescriptorSetLayout(vulkan_globals.device, &descriptor_set_layout_create_info, NULL, &vulkan_globals.single_texture_set_layout.handle);
1133 if (err != VK_SUCCESS)
1134 Sys_Error("vkCreateDescriptorSetLayout failed");
1135
1136 VkDescriptorSetLayoutBinding ubo_sampler_layout_bindings;
1137 memset(&ubo_sampler_layout_bindings, 0, sizeof(ubo_sampler_layout_bindings));
1138 ubo_sampler_layout_bindings.binding = 0;
1139 ubo_sampler_layout_bindings.descriptorCount = 1;
1140 ubo_sampler_layout_bindings.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
1141 ubo_sampler_layout_bindings.stageFlags = VK_SHADER_STAGE_ALL_GRAPHICS;
1142
1143 descriptor_set_layout_create_info.bindingCount = 1;
1144 descriptor_set_layout_create_info.pBindings = &ubo_sampler_layout_bindings;
1145
1146 memset(&vulkan_globals.ubo_set_layout, 0, sizeof(vulkan_globals.ubo_set_layout));
1147 vulkan_globals.ubo_set_layout.num_ubos_dynamic = 1;
1148
1149 err = vkCreateDescriptorSetLayout(vulkan_globals.device, &descriptor_set_layout_create_info, NULL, &vulkan_globals.ubo_set_layout.handle);
1150 if (err != VK_SUCCESS)
1151 Sys_Error("vkCreateDescriptorSetLayout failed");
1152
1153 VkDescriptorSetLayoutBinding input_attachment_layout_bindings;
1154 memset(&input_attachment_layout_bindings, 0, sizeof(input_attachment_layout_bindings));
1155 input_attachment_layout_bindings.binding = 0;
1156 input_attachment_layout_bindings.descriptorCount = 1;
1157 input_attachment_layout_bindings.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
1158 input_attachment_layout_bindings.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
1159
1160 descriptor_set_layout_create_info.bindingCount = 1;
1161 descriptor_set_layout_create_info.pBindings = &input_attachment_layout_bindings;
1162
1163 memset(&vulkan_globals.input_attachment_set_layout, 0, sizeof(vulkan_globals.input_attachment_set_layout));
1164 vulkan_globals.input_attachment_set_layout.num_input_attachments = 1;
1165
1166 err = vkCreateDescriptorSetLayout(vulkan_globals.device, &descriptor_set_layout_create_info, NULL, &vulkan_globals.input_attachment_set_layout.handle);
1167 if (err != VK_SUCCESS)
1168 Sys_Error("vkCreateDescriptorSetLayout failed");
1169
1170 VkDescriptorSetLayoutBinding screen_warp_layout_bindings[2];
1171 memset(&screen_warp_layout_bindings, 0, sizeof(screen_warp_layout_bindings));
1172 screen_warp_layout_bindings[0].binding = 0;
1173 screen_warp_layout_bindings[0].descriptorCount = 1;
1174 screen_warp_layout_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
1175 screen_warp_layout_bindings[0].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
1176 screen_warp_layout_bindings[1].binding = 1;
1177 screen_warp_layout_bindings[1].descriptorCount = 1;
1178 screen_warp_layout_bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
1179 screen_warp_layout_bindings[1].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
1180
1181 descriptor_set_layout_create_info.bindingCount = 2;
1182 descriptor_set_layout_create_info.pBindings = screen_warp_layout_bindings;
1183
1184 memset(&vulkan_globals.screen_warp_set_layout, 0, sizeof(vulkan_globals.screen_warp_set_layout));
1185 vulkan_globals.screen_warp_set_layout.num_combined_image_samplers = 1;
1186 vulkan_globals.screen_warp_set_layout.num_storage_images = 1;
1187
1188 err = vkCreateDescriptorSetLayout(vulkan_globals.device, &descriptor_set_layout_create_info, NULL, &vulkan_globals.screen_warp_set_layout.handle);
1189 if (err != VK_SUCCESS)
1190 Sys_Error("vkCreateDescriptorSetLayout failed");
1191
1192 VkDescriptorSetLayoutBinding single_texture_cs_write_layout_binding;
1193 memset(&single_texture_cs_write_layout_binding, 0, sizeof(single_texture_cs_write_layout_binding));
1194 single_texture_cs_write_layout_binding.binding = 0;
1195 single_texture_cs_write_layout_binding.descriptorCount = 1;
1196 single_texture_cs_write_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
1197 single_texture_cs_write_layout_binding.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
1198
1199 descriptor_set_layout_create_info.bindingCount = 1;
1200 descriptor_set_layout_create_info.pBindings = &single_texture_cs_write_layout_binding;
1201
1202 memset(&vulkan_globals.single_texture_cs_write_set_layout, 0, sizeof(vulkan_globals.single_texture_cs_write_set_layout));
1203 vulkan_globals.single_texture_cs_write_set_layout.num_storage_images = 1;
1204
1205 err = vkCreateDescriptorSetLayout(vulkan_globals.device, &descriptor_set_layout_create_info, NULL, &vulkan_globals.single_texture_cs_write_set_layout.handle);
1206 if (err != VK_SUCCESS)
1207 Sys_Error("vkCreateDescriptorSetLayout failed");
1208 }
1209
1210 /*
1211 ===============
1212 R_CreateDescriptorPool
1213 ===============
1214 */
R_CreateDescriptorPool()1215 void R_CreateDescriptorPool()
1216 {
1217 VkDescriptorPoolSize pool_sizes[4];
1218 pool_sizes[0].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
1219 pool_sizes[0].descriptorCount = MAX_GLTEXTURES + 1;
1220 pool_sizes[1].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
1221 pool_sizes[1].descriptorCount = 16;
1222 pool_sizes[2].type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
1223 pool_sizes[2].descriptorCount = 2;
1224 pool_sizes[3].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
1225 pool_sizes[3].descriptorCount = MAX_GLTEXTURES;
1226
1227 VkDescriptorPoolCreateInfo descriptor_pool_create_info;
1228 memset(&descriptor_pool_create_info, 0, sizeof(descriptor_pool_create_info));
1229 descriptor_pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
1230 descriptor_pool_create_info.maxSets = MAX_GLTEXTURES + 32;
1231 descriptor_pool_create_info.poolSizeCount = 4;
1232 descriptor_pool_create_info.pPoolSizes = pool_sizes;
1233 descriptor_pool_create_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
1234
1235 vkCreateDescriptorPool(vulkan_globals.device, &descriptor_pool_create_info, NULL, &vulkan_globals.descriptor_pool);
1236 }
1237
1238 /*
1239 ===============
1240 R_CreatePipelineLayouts
1241 ===============
1242 */
R_CreatePipelineLayouts()1243 void R_CreatePipelineLayouts()
1244 {
1245 Sys_Printf("Creating pipeline layouts\n");
1246
1247 VkResult err;
1248
1249 // Basic
1250 VkDescriptorSetLayout basic_descriptor_set_layouts[1] = { vulkan_globals.single_texture_set_layout.handle };
1251
1252 VkPushConstantRange push_constant_range;
1253 memset(&push_constant_range, 0, sizeof(push_constant_range));
1254 push_constant_range.offset = 0;
1255 push_constant_range.size = 21 * sizeof(float);
1256 push_constant_range.stageFlags = VK_SHADER_STAGE_ALL_GRAPHICS;
1257
1258 VkPipelineLayoutCreateInfo pipeline_layout_create_info;
1259 memset(&pipeline_layout_create_info, 0, sizeof(pipeline_layout_create_info));
1260 pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
1261 pipeline_layout_create_info.setLayoutCount = 1;
1262 pipeline_layout_create_info.pSetLayouts = basic_descriptor_set_layouts;
1263 pipeline_layout_create_info.pushConstantRangeCount = 1;
1264 pipeline_layout_create_info.pPushConstantRanges = &push_constant_range;
1265
1266 err = vkCreatePipelineLayout(vulkan_globals.device, &pipeline_layout_create_info, NULL, &vulkan_globals.basic_pipeline_layout.handle);
1267 if (err != VK_SUCCESS)
1268 Sys_Error("vkCreatePipelineLayout failed");
1269 GL_SetObjectName((uint64_t)vulkan_globals.basic_pipeline_layout.handle, VK_OBJECT_TYPE_PIPELINE_LAYOUT, "basic_pipeline_layout");
1270 vulkan_globals.basic_pipeline_layout.push_constant_range = push_constant_range;
1271
1272 // World
1273 VkDescriptorSetLayout world_descriptor_set_layouts[3] = {
1274 vulkan_globals.single_texture_set_layout.handle,
1275 vulkan_globals.single_texture_set_layout.handle,
1276 vulkan_globals.single_texture_set_layout.handle
1277 };
1278
1279 pipeline_layout_create_info.setLayoutCount = 3;
1280 pipeline_layout_create_info.pSetLayouts = world_descriptor_set_layouts;
1281
1282 err = vkCreatePipelineLayout(vulkan_globals.device, &pipeline_layout_create_info, NULL, &vulkan_globals.world_pipeline_layout.handle);
1283 if (err != VK_SUCCESS)
1284 Sys_Error("vkCreatePipelineLayout failed");
1285 GL_SetObjectName((uint64_t)vulkan_globals.world_pipeline_layout.handle, VK_OBJECT_TYPE_PIPELINE_LAYOUT, "world_pipeline_layout");
1286 vulkan_globals.world_pipeline_layout.push_constant_range = push_constant_range;
1287
1288 // Alias
1289 VkDescriptorSetLayout alias_descriptor_set_layouts[3] = {
1290 vulkan_globals.single_texture_set_layout.handle,
1291 vulkan_globals.single_texture_set_layout.handle,
1292 vulkan_globals.ubo_set_layout.handle
1293 };
1294
1295 pipeline_layout_create_info.setLayoutCount = 3;
1296 pipeline_layout_create_info.pSetLayouts = alias_descriptor_set_layouts;
1297
1298 err = vkCreatePipelineLayout(vulkan_globals.device, &pipeline_layout_create_info, NULL, &vulkan_globals.alias_pipeline.layout.handle);
1299 if (err != VK_SUCCESS)
1300 Sys_Error("vkCreatePipelineLayout failed");
1301 GL_SetObjectName((uint64_t)vulkan_globals.alias_pipeline.layout.handle, VK_OBJECT_TYPE_PIPELINE_LAYOUT, "alias_pipeline_layout");
1302 vulkan_globals.alias_pipeline.layout.push_constant_range = push_constant_range;
1303
1304 // Sky
1305 VkDescriptorSetLayout sky_layer_descriptor_set_layouts[2] = {
1306 vulkan_globals.single_texture_set_layout.handle,
1307 vulkan_globals.single_texture_set_layout.handle,
1308 };
1309
1310 pipeline_layout_create_info.setLayoutCount = 2;
1311 pipeline_layout_create_info.pSetLayouts = sky_layer_descriptor_set_layouts;
1312
1313 err = vkCreatePipelineLayout(vulkan_globals.device, &pipeline_layout_create_info, NULL, &vulkan_globals.sky_layer_pipeline.layout.handle);
1314 if (err != VK_SUCCESS)
1315 Sys_Error("vkCreatePipelineLayout failed");
1316 GL_SetObjectName((uint64_t)vulkan_globals.sky_layer_pipeline.layout.handle, VK_OBJECT_TYPE_PIPELINE_LAYOUT, "sky_layer_pipeline_layout");
1317 vulkan_globals.sky_layer_pipeline.layout.push_constant_range = push_constant_range;
1318
1319 // Postprocess
1320 VkDescriptorSetLayout postprocess_descriptor_set_layouts[1] = {
1321 vulkan_globals.input_attachment_set_layout.handle,
1322 };
1323
1324 memset(&push_constant_range, 0, sizeof(push_constant_range));
1325 push_constant_range.offset = 0;
1326 push_constant_range.size = 2 * sizeof(float);
1327 push_constant_range.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
1328
1329 pipeline_layout_create_info.setLayoutCount = 1;
1330 pipeline_layout_create_info.pSetLayouts = postprocess_descriptor_set_layouts;
1331 pipeline_layout_create_info.pushConstantRangeCount = 1;
1332 pipeline_layout_create_info.pPushConstantRanges = &push_constant_range;
1333
1334 err = vkCreatePipelineLayout(vulkan_globals.device, &pipeline_layout_create_info, NULL, &vulkan_globals.postprocess_pipeline.layout.handle);
1335 if (err != VK_SUCCESS)
1336 Sys_Error("vkCreatePipelineLayout failed");
1337 GL_SetObjectName((uint64_t)vulkan_globals.postprocess_pipeline.layout.handle, VK_OBJECT_TYPE_PIPELINE_LAYOUT, "postprocess_pipeline_layout");
1338 vulkan_globals.postprocess_pipeline.layout.push_constant_range = push_constant_range;
1339
1340 // Screen warp
1341 VkDescriptorSetLayout screen_warp_descriptor_set_layouts[1] = {
1342 vulkan_globals.screen_warp_set_layout.handle,
1343 };
1344
1345 memset(&push_constant_range, 0, sizeof(push_constant_range));
1346 push_constant_range.offset = 0;
1347 push_constant_range.size = 3 * sizeof(uint32_t) + 4 * sizeof(float);
1348 push_constant_range.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
1349
1350 pipeline_layout_create_info.setLayoutCount = 1;
1351 pipeline_layout_create_info.pSetLayouts = screen_warp_descriptor_set_layouts;
1352 pipeline_layout_create_info.pushConstantRangeCount = 1;
1353 pipeline_layout_create_info.pPushConstantRanges = &push_constant_range;
1354
1355 err = vkCreatePipelineLayout(vulkan_globals.device, &pipeline_layout_create_info, NULL, &vulkan_globals.screen_effects_pipeline.layout.handle);
1356 if (err != VK_SUCCESS)
1357 Sys_Error("vkCreatePipelineLayout failed");
1358 GL_SetObjectName((uint64_t)vulkan_globals.screen_effects_pipeline.layout.handle, VK_OBJECT_TYPE_PIPELINE_LAYOUT, "screen_effects_pipeline_layout");
1359 vulkan_globals.screen_effects_pipeline.layout.push_constant_range = push_constant_range;
1360
1361 vulkan_globals.screen_effects_scale_pipeline.layout.handle = vulkan_globals.screen_effects_pipeline.layout.handle;
1362 vulkan_globals.screen_effects_scale_pipeline.layout.push_constant_range = push_constant_range;
1363 vulkan_globals.screen_effects_scale_sops_pipeline.layout.handle = vulkan_globals.screen_effects_pipeline.layout.handle;
1364 vulkan_globals.screen_effects_scale_sops_pipeline.layout.push_constant_range = push_constant_range;
1365
1366 // Texture warp
1367 VkDescriptorSetLayout tex_warp_descriptor_set_layouts[2] = {
1368 vulkan_globals.single_texture_set_layout.handle,
1369 vulkan_globals.single_texture_cs_write_set_layout.handle,
1370 };
1371
1372 memset(&push_constant_range, 0, sizeof(push_constant_range));
1373 push_constant_range.offset = 0;
1374 push_constant_range.size = 1 * sizeof(float);
1375 push_constant_range.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
1376
1377 pipeline_layout_create_info.setLayoutCount = 2;
1378 pipeline_layout_create_info.pSetLayouts = tex_warp_descriptor_set_layouts;
1379 pipeline_layout_create_info.pushConstantRangeCount = 1;
1380 pipeline_layout_create_info.pPushConstantRanges = &push_constant_range;
1381
1382 err = vkCreatePipelineLayout(vulkan_globals.device, &pipeline_layout_create_info, NULL, &vulkan_globals.cs_tex_warp_pipeline.layout.handle);
1383 if (err != VK_SUCCESS)
1384 Sys_Error("vkCreatePipelineLayout failed");
1385 GL_SetObjectName((uint64_t)vulkan_globals.cs_tex_warp_pipeline.layout.handle, VK_OBJECT_TYPE_PIPELINE_LAYOUT, "cs_tex_warp_pipeline_layout");
1386 vulkan_globals.cs_tex_warp_pipeline.layout.push_constant_range = push_constant_range;
1387
1388 // Show triangles
1389 pipeline_layout_create_info.setLayoutCount = 0;
1390 pipeline_layout_create_info.pushConstantRangeCount = 0;
1391
1392 err = vkCreatePipelineLayout(vulkan_globals.device, &pipeline_layout_create_info, NULL, &vulkan_globals.showtris_pipeline.layout.handle);
1393 if (err != VK_SUCCESS)
1394 Sys_Error("vkCreatePipelineLayout failed");
1395 GL_SetObjectName((uint64_t)vulkan_globals.showtris_pipeline.layout.handle, VK_OBJECT_TYPE_PIPELINE_LAYOUT, "showtris_pipeline_layout");
1396 vulkan_globals.showtris_pipeline.layout.push_constant_range = push_constant_range;
1397 }
1398
1399 /*
1400 ===============
1401 R_InitSamplers
1402 ===============
1403 */
R_InitSamplers()1404 void R_InitSamplers()
1405 {
1406 GL_WaitForDeviceIdle();
1407 Sys_Printf("Initializing samplers\n");
1408
1409 VkResult err;
1410
1411 if (vulkan_globals.point_sampler == VK_NULL_HANDLE)
1412 {
1413 VkSamplerCreateInfo sampler_create_info;
1414 memset(&sampler_create_info, 0, sizeof(sampler_create_info));
1415 sampler_create_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
1416 sampler_create_info.magFilter = VK_FILTER_NEAREST;
1417 sampler_create_info.minFilter = VK_FILTER_NEAREST;
1418 sampler_create_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
1419 sampler_create_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
1420 sampler_create_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
1421 sampler_create_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
1422 sampler_create_info.mipLodBias = 0.0f;
1423 sampler_create_info.maxAnisotropy = 1.0f;
1424 sampler_create_info.minLod = 0;
1425 sampler_create_info.maxLod = FLT_MAX;
1426
1427 err = vkCreateSampler(vulkan_globals.device, &sampler_create_info, NULL, &vulkan_globals.point_sampler);
1428 if (err != VK_SUCCESS)
1429 Sys_Error("vkCreateSampler failed");
1430
1431 GL_SetObjectName((uint64_t)vulkan_globals.point_sampler, VK_OBJECT_TYPE_SAMPLER, "point");
1432
1433 sampler_create_info.anisotropyEnable = VK_TRUE;
1434 sampler_create_info.maxAnisotropy = vulkan_globals.device_properties.limits.maxSamplerAnisotropy;
1435 err = vkCreateSampler(vulkan_globals.device, &sampler_create_info, NULL, &vulkan_globals.point_aniso_sampler);
1436 if (err != VK_SUCCESS)
1437 Sys_Error("vkCreateSampler failed");
1438
1439 GL_SetObjectName((uint64_t)vulkan_globals.point_aniso_sampler, VK_OBJECT_TYPE_SAMPLER, "point_aniso");
1440
1441 sampler_create_info.magFilter = VK_FILTER_LINEAR;
1442 sampler_create_info.minFilter = VK_FILTER_LINEAR;
1443 sampler_create_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
1444 sampler_create_info.anisotropyEnable = VK_FALSE;
1445 sampler_create_info.maxAnisotropy = 1.0f;
1446
1447 err = vkCreateSampler(vulkan_globals.device, &sampler_create_info, NULL, &vulkan_globals.linear_sampler);
1448 if (err != VK_SUCCESS)
1449 Sys_Error("vkCreateSampler failed");
1450
1451 GL_SetObjectName((uint64_t)vulkan_globals.linear_sampler, VK_OBJECT_TYPE_SAMPLER, "linear");
1452
1453 sampler_create_info.anisotropyEnable = VK_TRUE;
1454 sampler_create_info.maxAnisotropy = vulkan_globals.device_properties.limits.maxSamplerAnisotropy;
1455 err = vkCreateSampler(vulkan_globals.device, &sampler_create_info, NULL, &vulkan_globals.linear_aniso_sampler);
1456 if (err != VK_SUCCESS)
1457 Sys_Error("vkCreateSampler failed");
1458
1459 GL_SetObjectName((uint64_t)vulkan_globals.linear_aniso_sampler, VK_OBJECT_TYPE_SAMPLER, "linear_aniso");
1460 }
1461
1462 if (vulkan_globals.point_sampler_lod_bias != VK_NULL_HANDLE)
1463 {
1464 vkDestroySampler(vulkan_globals.device, vulkan_globals.point_sampler_lod_bias, NULL);
1465 vkDestroySampler(vulkan_globals.device, vulkan_globals.point_aniso_sampler_lod_bias, NULL);
1466 vkDestroySampler(vulkan_globals.device, vulkan_globals.linear_sampler_lod_bias, NULL);
1467 vkDestroySampler(vulkan_globals.device, vulkan_globals.linear_aniso_sampler_lod_bias, NULL);
1468 }
1469
1470 {
1471 float lod_bias = 0.0f;
1472 if (r_lodbias.value)
1473 {
1474 if (vulkan_globals.supersampling)
1475 {
1476 switch (vulkan_globals.sample_count)
1477 {
1478 case VK_SAMPLE_COUNT_2_BIT:
1479 lod_bias -= 0.5f;
1480 break;
1481 case VK_SAMPLE_COUNT_4_BIT:
1482 lod_bias -= 1.0f;
1483 break;
1484 case VK_SAMPLE_COUNT_8_BIT:
1485 lod_bias -= 1.5f;
1486 break;
1487 case VK_SAMPLE_COUNT_16_BIT:
1488 lod_bias -= 2.0f;
1489 break;
1490 default: /* silences gcc's -Wswitch */
1491 break;
1492 }
1493 }
1494
1495 if (r_scale.value >= 2)
1496 lod_bias -= 1.0f;
1497 if (r_scale.value >= 4)
1498 lod_bias -= 2.0f;
1499 if (r_scale.value >= 8)
1500 lod_bias -= 4.0f;
1501 }
1502
1503 Sys_Printf("Texture lod bias: %f\n", lod_bias);
1504
1505 VkSamplerCreateInfo sampler_create_info;
1506 memset(&sampler_create_info, 0, sizeof(sampler_create_info));
1507 sampler_create_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
1508 sampler_create_info.magFilter = VK_FILTER_NEAREST;
1509 sampler_create_info.minFilter = VK_FILTER_NEAREST;
1510 sampler_create_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
1511 sampler_create_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
1512 sampler_create_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
1513 sampler_create_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
1514 sampler_create_info.mipLodBias = lod_bias;
1515 sampler_create_info.maxAnisotropy = 1.0f;
1516 sampler_create_info.minLod = 0;
1517 sampler_create_info.maxLod = FLT_MAX;
1518
1519 err = vkCreateSampler(vulkan_globals.device, &sampler_create_info, NULL, &vulkan_globals.point_sampler_lod_bias);
1520 if (err != VK_SUCCESS)
1521 Sys_Error("vkCreateSampler failed");
1522
1523 GL_SetObjectName((uint64_t)vulkan_globals.point_sampler_lod_bias, VK_OBJECT_TYPE_SAMPLER, "point_lod_bias");
1524
1525 sampler_create_info.anisotropyEnable = VK_TRUE;
1526 sampler_create_info.maxAnisotropy = vulkan_globals.device_properties.limits.maxSamplerAnisotropy;
1527 err = vkCreateSampler(vulkan_globals.device, &sampler_create_info, NULL, &vulkan_globals.point_aniso_sampler_lod_bias);
1528 if (err != VK_SUCCESS)
1529 Sys_Error("vkCreateSampler failed");
1530
1531 GL_SetObjectName((uint64_t)vulkan_globals.point_aniso_sampler_lod_bias, VK_OBJECT_TYPE_SAMPLER, "point_aniso_lod_bias");
1532
1533 sampler_create_info.magFilter = VK_FILTER_LINEAR;
1534 sampler_create_info.minFilter = VK_FILTER_LINEAR;
1535 sampler_create_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
1536 sampler_create_info.anisotropyEnable = VK_FALSE;
1537 sampler_create_info.maxAnisotropy = 1.0f;
1538
1539 err = vkCreateSampler(vulkan_globals.device, &sampler_create_info, NULL, &vulkan_globals.linear_sampler_lod_bias);
1540 if (err != VK_SUCCESS)
1541 Sys_Error("vkCreateSampler failed");
1542
1543 GL_SetObjectName((uint64_t)vulkan_globals.linear_sampler_lod_bias, VK_OBJECT_TYPE_SAMPLER, "linear_lod_bias");
1544
1545 sampler_create_info.anisotropyEnable = VK_TRUE;
1546 sampler_create_info.maxAnisotropy = vulkan_globals.device_properties.limits.maxSamplerAnisotropy;
1547 err = vkCreateSampler(vulkan_globals.device, &sampler_create_info, NULL, &vulkan_globals.linear_aniso_sampler_lod_bias);
1548 if (err != VK_SUCCESS)
1549 Sys_Error("vkCreateSampler failed");
1550
1551 GL_SetObjectName((uint64_t)vulkan_globals.linear_aniso_sampler_lod_bias, VK_OBJECT_TYPE_SAMPLER, "linear_aniso_lod_bias");
1552 }
1553
1554 TexMgr_UpdateTextureDescriptorSets();
1555 }
1556
1557 /*
1558 ===============
1559 R_CreateShaderModule
1560 ===============
1561 */
R_CreateShaderModule(byte * code,int size,const char * name)1562 static VkShaderModule R_CreateShaderModule(byte *code, int size, const char * name)
1563 {
1564 VkShaderModuleCreateInfo module_create_info;
1565 memset(&module_create_info, 0, sizeof(module_create_info));
1566 module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
1567 module_create_info.pNext = NULL;
1568 module_create_info.codeSize = size;
1569 module_create_info.pCode = (uint32_t *)code;
1570
1571 VkShaderModule module;
1572 VkResult err = vkCreateShaderModule(vulkan_globals.device, &module_create_info, NULL, &module);
1573 if (err != VK_SUCCESS)
1574 Sys_Error("vkCreateShaderModule failed");
1575
1576 GL_SetObjectName((uint64_t)module, VK_OBJECT_TYPE_SHADER_MODULE, name);
1577
1578 return module;
1579 }
1580
1581 #define CREATE_SHADER_MODULE(name) VkShaderModule name##_module = R_CreateShaderModule(name##_spv, name##_spv_size, #name)
1582 #define CREATE_SHADER_MODULE_COND(name, cond) VkShaderModule name##_module = cond ? R_CreateShaderModule(name##_spv, name##_spv_size, #name) : VK_NULL_HANDLE
1583
1584 /*
1585 ===============
1586 R_CreatePipelines
1587 ===============
1588 */
R_CreatePipelines()1589 void R_CreatePipelines()
1590 {
1591 int render_pass;
1592 int alpha_blend, alpha_test, fullbright_enabled;
1593 VkResult err;
1594
1595 Sys_Printf("Creating pipelines\n");
1596
1597 CREATE_SHADER_MODULE(basic_vert);
1598 CREATE_SHADER_MODULE(basic_frag);
1599 CREATE_SHADER_MODULE(basic_alphatest_frag);
1600 CREATE_SHADER_MODULE(basic_notex_frag);
1601 CREATE_SHADER_MODULE(world_vert);
1602 CREATE_SHADER_MODULE(world_frag);
1603 CREATE_SHADER_MODULE(alias_vert);
1604 CREATE_SHADER_MODULE(alias_frag);
1605 CREATE_SHADER_MODULE(alias_alphatest_frag);
1606 CREATE_SHADER_MODULE(sky_layer_vert);
1607 CREATE_SHADER_MODULE(sky_layer_frag);
1608 CREATE_SHADER_MODULE(sky_box_frag);
1609 CREATE_SHADER_MODULE(postprocess_vert);
1610 CREATE_SHADER_MODULE(postprocess_frag);
1611 CREATE_SHADER_MODULE(screen_effects_8bit_comp);
1612 CREATE_SHADER_MODULE(screen_effects_8bit_scale_comp);
1613 CREATE_SHADER_MODULE_COND(screen_effects_8bit_scale_sops_comp, vulkan_globals.screen_effects_sops);
1614 CREATE_SHADER_MODULE(screen_effects_10bit_comp);
1615 CREATE_SHADER_MODULE(screen_effects_10bit_scale_comp);
1616 CREATE_SHADER_MODULE_COND(screen_effects_10bit_scale_sops_comp, vulkan_globals.screen_effects_sops);
1617 CREATE_SHADER_MODULE(cs_tex_warp_comp);
1618 CREATE_SHADER_MODULE(showtris_vert);
1619 CREATE_SHADER_MODULE(showtris_frag);
1620
1621 VkPipelineDynamicStateCreateInfo dynamic_state_create_info;
1622 memset(&dynamic_state_create_info, 0, sizeof(dynamic_state_create_info));
1623 dynamic_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
1624 VkDynamicState dynamic_states[3];
1625 dynamic_state_create_info.pDynamicStates = dynamic_states;
1626
1627 VkPipelineShaderStageCreateInfo shader_stages[2];
1628 memset(&shader_stages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
1629
1630 shader_stages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
1631 shader_stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
1632 shader_stages[0].module = basic_vert_module;
1633 shader_stages[0].pName = "main";
1634
1635 shader_stages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
1636 shader_stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
1637 shader_stages[1].module = basic_alphatest_frag_module;
1638 shader_stages[1].pName = "main";
1639
1640 VkVertexInputAttributeDescription basic_vertex_input_attribute_descriptions[3];
1641 basic_vertex_input_attribute_descriptions[0].binding = 0;
1642 basic_vertex_input_attribute_descriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT;
1643 basic_vertex_input_attribute_descriptions[0].location = 0;
1644 basic_vertex_input_attribute_descriptions[0].offset = 0;
1645 basic_vertex_input_attribute_descriptions[1].binding = 0;
1646 basic_vertex_input_attribute_descriptions[1].format = VK_FORMAT_R32G32_SFLOAT;
1647 basic_vertex_input_attribute_descriptions[1].location = 1;
1648 basic_vertex_input_attribute_descriptions[1].offset = 12;
1649 basic_vertex_input_attribute_descriptions[2].binding = 0;
1650 basic_vertex_input_attribute_descriptions[2].format = VK_FORMAT_R8G8B8A8_UNORM;
1651 basic_vertex_input_attribute_descriptions[2].location = 2;
1652 basic_vertex_input_attribute_descriptions[2].offset = 20;
1653
1654 VkVertexInputBindingDescription basic_vertex_binding_description;
1655 basic_vertex_binding_description.binding = 0;
1656 basic_vertex_binding_description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
1657 basic_vertex_binding_description.stride = 24;
1658
1659 VkPipelineVertexInputStateCreateInfo vertex_input_state_create_info;
1660 memset(&vertex_input_state_create_info, 0, sizeof(vertex_input_state_create_info));
1661 vertex_input_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
1662 vertex_input_state_create_info.vertexAttributeDescriptionCount = 3;
1663 vertex_input_state_create_info.pVertexAttributeDescriptions = basic_vertex_input_attribute_descriptions;
1664 vertex_input_state_create_info.vertexBindingDescriptionCount = 1;
1665 vertex_input_state_create_info.pVertexBindingDescriptions = &basic_vertex_binding_description;
1666
1667 VkPipelineInputAssemblyStateCreateInfo input_assembly_state_create_info;
1668 memset(&input_assembly_state_create_info, 0, sizeof(input_assembly_state_create_info));
1669 input_assembly_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
1670 input_assembly_state_create_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
1671
1672 VkPipelineViewportStateCreateInfo viewport_state_create_info;
1673 memset(&viewport_state_create_info, 0, sizeof(viewport_state_create_info));
1674 viewport_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
1675 viewport_state_create_info.viewportCount = 1;
1676 dynamic_states[dynamic_state_create_info.dynamicStateCount++] = VK_DYNAMIC_STATE_VIEWPORT;
1677 viewport_state_create_info.scissorCount = 1;
1678 dynamic_states[dynamic_state_create_info.dynamicStateCount++] = VK_DYNAMIC_STATE_SCISSOR;
1679
1680 VkPipelineRasterizationStateCreateInfo rasterization_state_create_info;
1681 memset(&rasterization_state_create_info, 0, sizeof(rasterization_state_create_info));
1682 rasterization_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
1683 rasterization_state_create_info.polygonMode = VK_POLYGON_MODE_FILL;
1684 rasterization_state_create_info.cullMode = VK_CULL_MODE_NONE;
1685 rasterization_state_create_info.frontFace = VK_FRONT_FACE_CLOCKWISE;
1686 rasterization_state_create_info.depthClampEnable = VK_FALSE;
1687 rasterization_state_create_info.rasterizerDiscardEnable = VK_FALSE;
1688 rasterization_state_create_info.depthBiasEnable = VK_FALSE;
1689 rasterization_state_create_info.lineWidth = 1.0f;
1690
1691 VkPipelineMultisampleStateCreateInfo multisample_state_create_info;
1692 memset(&multisample_state_create_info, 0, sizeof(multisample_state_create_info));
1693 multisample_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
1694 multisample_state_create_info.rasterizationSamples = vulkan_globals.sample_count;
1695 if (vulkan_globals.supersampling)
1696 {
1697 multisample_state_create_info.sampleShadingEnable = VK_TRUE;
1698 multisample_state_create_info.minSampleShading = 1.0f;
1699 }
1700
1701 VkPipelineDepthStencilStateCreateInfo depth_stencil_state_create_info;
1702 memset(&depth_stencil_state_create_info, 0, sizeof(depth_stencil_state_create_info));
1703 depth_stencil_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
1704 depth_stencil_state_create_info.depthTestEnable = VK_FALSE;
1705 depth_stencil_state_create_info.depthWriteEnable = VK_FALSE;
1706 depth_stencil_state_create_info.depthCompareOp = VK_COMPARE_OP_GREATER_OR_EQUAL;
1707 depth_stencil_state_create_info.depthBoundsTestEnable = VK_FALSE;
1708 depth_stencil_state_create_info.back.failOp = VK_STENCIL_OP_KEEP;
1709 depth_stencil_state_create_info.back.passOp = VK_STENCIL_OP_KEEP;
1710 depth_stencil_state_create_info.back.compareOp = VK_COMPARE_OP_ALWAYS;
1711 depth_stencil_state_create_info.stencilTestEnable = VK_FALSE;
1712 depth_stencil_state_create_info.front = depth_stencil_state_create_info.back;
1713
1714 VkPipelineColorBlendStateCreateInfo color_blend_state_create_info;
1715 VkPipelineColorBlendAttachmentState blend_attachment_state;
1716 memset(&color_blend_state_create_info, 0, sizeof(color_blend_state_create_info));
1717 color_blend_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
1718 memset(&blend_attachment_state, 0, sizeof(blend_attachment_state));
1719 blend_attachment_state.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
1720 blend_attachment_state.blendEnable = VK_FALSE;
1721 color_blend_state_create_info.attachmentCount = 1;
1722 color_blend_state_create_info.pAttachments = &blend_attachment_state;
1723
1724 VkGraphicsPipelineCreateInfo pipeline_create_info;
1725 memset(&pipeline_create_info, 0, sizeof(pipeline_create_info));
1726 pipeline_create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
1727 pipeline_create_info.stageCount = 2;
1728 pipeline_create_info.pStages = shader_stages;
1729 pipeline_create_info.pVertexInputState = &vertex_input_state_create_info;
1730 pipeline_create_info.pInputAssemblyState = &input_assembly_state_create_info;
1731 pipeline_create_info.pViewportState = &viewport_state_create_info;
1732 pipeline_create_info.pRasterizationState = &rasterization_state_create_info;
1733 pipeline_create_info.pMultisampleState = &multisample_state_create_info;
1734 pipeline_create_info.pDepthStencilState = &depth_stencil_state_create_info;
1735 pipeline_create_info.pColorBlendState = &color_blend_state_create_info;
1736 pipeline_create_info.pDynamicState = &dynamic_state_create_info;
1737 pipeline_create_info.layout = vulkan_globals.basic_pipeline_layout.handle;
1738 pipeline_create_info.renderPass = vulkan_globals.main_render_pass;
1739
1740 //================
1741 // Basic pipelines
1742 //================
1743 input_assembly_state_create_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
1744
1745 depth_stencil_state_create_info.depthTestEnable = VK_TRUE;
1746 depth_stencil_state_create_info.depthWriteEnable = VK_TRUE;
1747 for (render_pass = 0; render_pass < 2; ++render_pass)
1748 {
1749 pipeline_create_info.renderPass = (render_pass == 0) ? vulkan_globals.main_render_pass : vulkan_globals.ui_render_pass;
1750 multisample_state_create_info.rasterizationSamples = (render_pass == 0) ? vulkan_globals.sample_count : VK_SAMPLE_COUNT_1_BIT;
1751
1752 assert(vulkan_globals.basic_alphatest_pipeline[render_pass].handle == VK_NULL_HANDLE);
1753 err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.basic_alphatest_pipeline[render_pass].handle);
1754 if (err != VK_SUCCESS)
1755 Sys_Error("vkCreateGraphicsPipelines failed");
1756 vulkan_globals.basic_alphatest_pipeline[render_pass].layout = vulkan_globals.basic_pipeline_layout;
1757 GL_SetObjectName((uint64_t)vulkan_globals.basic_alphatest_pipeline[render_pass].handle, VK_OBJECT_TYPE_PIPELINE, "basic_alphatest");
1758 }
1759
1760 shader_stages[1].module = basic_notex_frag_module;
1761
1762 blend_attachment_state.blendEnable = VK_TRUE;
1763 blend_attachment_state.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
1764 blend_attachment_state.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
1765 blend_attachment_state.colorBlendOp = VK_BLEND_OP_ADD;
1766 blend_attachment_state.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
1767 blend_attachment_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
1768 blend_attachment_state.alphaBlendOp = VK_BLEND_OP_ADD;
1769
1770 depth_stencil_state_create_info.depthTestEnable = VK_FALSE;
1771 depth_stencil_state_create_info.depthWriteEnable = VK_FALSE;
1772
1773 for (render_pass = 0; render_pass < 2; ++render_pass)
1774 {
1775 pipeline_create_info.renderPass = (render_pass == 0) ? vulkan_globals.main_render_pass : vulkan_globals.ui_render_pass;
1776 multisample_state_create_info.rasterizationSamples = (render_pass == 0) ? vulkan_globals.sample_count : VK_SAMPLE_COUNT_1_BIT;
1777
1778 assert(vulkan_globals.basic_notex_blend_pipeline[render_pass].handle == VK_NULL_HANDLE);
1779 err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.basic_notex_blend_pipeline[render_pass].handle);
1780 if (err != VK_SUCCESS)
1781 Sys_Error("vkCreateGraphicsPipelines failed");
1782 vulkan_globals.basic_notex_blend_pipeline[render_pass].layout = vulkan_globals.basic_pipeline_layout;
1783 GL_SetObjectName((uint64_t)vulkan_globals.basic_notex_blend_pipeline[render_pass].handle, VK_OBJECT_TYPE_PIPELINE, "basic_notex_blend");
1784 }
1785
1786 pipeline_create_info.renderPass = vulkan_globals.main_render_pass;
1787 pipeline_create_info.subpass = 0;
1788 multisample_state_create_info.rasterizationSamples = vulkan_globals.sample_count;
1789
1790 assert(vulkan_globals.basic_poly_blend_pipeline.handle == VK_NULL_HANDLE);
1791 err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.basic_poly_blend_pipeline.handle);
1792 if (err != VK_SUCCESS)
1793 Sys_Error("vkCreateGraphicsPipelines failed");
1794 vulkan_globals.basic_poly_blend_pipeline.layout = vulkan_globals.basic_pipeline_layout;
1795 GL_SetObjectName((uint64_t)vulkan_globals.basic_poly_blend_pipeline.handle, VK_OBJECT_TYPE_PIPELINE, "basic_poly_blend");
1796
1797 shader_stages[1].module = basic_frag_module;
1798
1799 for (render_pass = 0; render_pass < 2; ++render_pass)
1800 {
1801 pipeline_create_info.renderPass = (render_pass == 0) ? vulkan_globals.main_render_pass : vulkan_globals.ui_render_pass;
1802 multisample_state_create_info.rasterizationSamples = (render_pass == 0) ? vulkan_globals.sample_count : VK_SAMPLE_COUNT_1_BIT;
1803
1804 assert(vulkan_globals.basic_blend_pipeline[render_pass].handle == VK_NULL_HANDLE);
1805 err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.basic_blend_pipeline[render_pass].handle);
1806 if (err != VK_SUCCESS)
1807 Sys_Error("vkCreateGraphicsPipelines failed");
1808 vulkan_globals.basic_blend_pipeline[render_pass].layout = vulkan_globals.basic_pipeline_layout;
1809
1810 GL_SetObjectName((uint64_t)vulkan_globals.basic_blend_pipeline[render_pass].handle, VK_OBJECT_TYPE_PIPELINE, "basic_blend");
1811 }
1812
1813 multisample_state_create_info.rasterizationSamples = vulkan_globals.sample_count;
1814
1815 //================
1816 // Warp
1817 //================
1818 multisample_state_create_info.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
1819
1820 input_assembly_state_create_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
1821
1822 blend_attachment_state.blendEnable = VK_FALSE;
1823
1824 shader_stages[0].module = basic_vert_module;
1825 shader_stages[1].module = basic_frag_module;
1826
1827 pipeline_create_info.renderPass = vulkan_globals.warp_render_pass;
1828
1829 assert(vulkan_globals.raster_tex_warp_pipeline.handle == VK_NULL_HANDLE);
1830 err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.raster_tex_warp_pipeline.handle);
1831 if (err != VK_SUCCESS)
1832 Sys_Error("vkCreateGraphicsPipelines failed");
1833 vulkan_globals.raster_tex_warp_pipeline.layout = vulkan_globals.basic_pipeline_layout;
1834 GL_SetObjectName((uint64_t)vulkan_globals.raster_tex_warp_pipeline.handle, VK_OBJECT_TYPE_PIPELINE, "warp");
1835
1836 //================
1837 // Particles
1838 //================
1839 multisample_state_create_info.rasterizationSamples = vulkan_globals.sample_count;
1840
1841 input_assembly_state_create_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
1842
1843 depth_stencil_state_create_info.depthTestEnable = VK_TRUE;
1844 depth_stencil_state_create_info.depthWriteEnable = VK_FALSE;
1845
1846 pipeline_create_info.renderPass = vulkan_globals.main_render_pass;
1847
1848 blend_attachment_state.blendEnable = VK_TRUE;
1849
1850 assert(vulkan_globals.particle_pipeline.handle == VK_NULL_HANDLE);
1851 err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.particle_pipeline.handle);
1852 if (err != VK_SUCCESS)
1853 Sys_Error("vkCreateGraphicsPipelines failed");
1854 vulkan_globals.particle_pipeline.layout = vulkan_globals.basic_pipeline_layout;
1855 GL_SetObjectName((uint64_t)vulkan_globals.particle_pipeline.handle, VK_OBJECT_TYPE_PIPELINE, "particles");
1856
1857 #ifdef PSET_SCRIPT
1858 //================
1859 // FTE particles
1860 //================
1861 static const VkBlendFactor source_blend_factors[8] =
1862 {
1863 VK_BLEND_FACTOR_SRC_ALPHA, //BM_BLEND
1864 VK_BLEND_FACTOR_SRC_COLOR, //BM_BLENDCOLOUR
1865 VK_BLEND_FACTOR_SRC_ALPHA, //BM_ADDA
1866 VK_BLEND_FACTOR_SRC_COLOR, //BM_ADDC
1867 VK_BLEND_FACTOR_SRC_ALPHA, //BM_SUBTRACT
1868 VK_BLEND_FACTOR_ZERO, //BM_INVMODA
1869 VK_BLEND_FACTOR_ZERO, //BM_INVMODC
1870 VK_BLEND_FACTOR_ONE //BM_PREMUL
1871 };
1872 static const VkBlendFactor dest_blend_factors[8] =
1873 {
1874 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, //BM_BLEND
1875 VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, //BM_BLENDCOLOUR
1876 VK_BLEND_FACTOR_ONE, //BM_ADDA
1877 VK_BLEND_FACTOR_ONE, //BM_ADDC
1878 VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, //BM_SUBTRACT
1879 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, //BM_INVMODA
1880 VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, //BM_INVMODC
1881 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA //BM_PREMUL
1882 };
1883
1884 static const char* fte_particle_pipeline_names[16] =
1885 {
1886 "fte_particles_blend_tris",
1887 "fte_particles_blend_color_tris",
1888 "fte_particles_add_color_tris",
1889 "fte_particles_add_alpha_tris",
1890 "fte_particles_subtract_tris",
1891 "fte_particles_inv_modulate_alpha_tris",
1892 "fte_particles_inv_modulate_color_tris",
1893 "fte_particles_premultiplied_tris",
1894 "fte_particles_blend_lines",
1895 "fte_particles_blend_color_lines",
1896 "fte_particles_add_color_lines",
1897 "fte_particles_add_alpha_lines",
1898 "fte_particles_subtract_lines",
1899 "fte_particles_inv_modulate_alpha_lines",
1900 "fte_particles_inv_modulate_color_lines",
1901 "fte_particles_premultiplied_lines"
1902 };
1903
1904 rasterization_state_create_info.cullMode = VK_CULL_MODE_NONE;
1905 rasterization_state_create_info.depthBiasEnable = VK_TRUE;
1906 rasterization_state_create_info.depthBiasConstantFactor = OFFSET_DECAL;
1907 rasterization_state_create_info.depthBiasSlopeFactor = 1.0f;
1908
1909 for (int i = 0; i < 8; ++i)
1910 {
1911 input_assembly_state_create_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
1912 rasterization_state_create_info.polygonMode = VK_POLYGON_MODE_FILL;
1913 blend_attachment_state.srcColorBlendFactor = source_blend_factors[i];
1914 blend_attachment_state.dstColorBlendFactor = dest_blend_factors[i];
1915 blend_attachment_state.colorBlendOp = VK_BLEND_OP_ADD;
1916 blend_attachment_state.srcAlphaBlendFactor = source_blend_factors[i];
1917 blend_attachment_state.dstAlphaBlendFactor = source_blend_factors[i];
1918
1919 assert(vulkan_globals.fte_particle_pipelines[i].handle == VK_NULL_HANDLE);
1920 err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.fte_particle_pipelines[i].handle);
1921 if (err != VK_SUCCESS)
1922 Sys_Error("vkCreateGraphicsPipelines failed");
1923 vulkan_globals.fte_particle_pipelines[i].layout = vulkan_globals.basic_pipeline_layout;
1924 GL_SetObjectName((uint64_t)vulkan_globals.fte_particle_pipelines[i].handle, VK_OBJECT_TYPE_PIPELINE, fte_particle_pipeline_names[i]);
1925
1926 if (vulkan_globals.non_solid_fill)
1927 {
1928 input_assembly_state_create_info.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
1929 rasterization_state_create_info.polygonMode = VK_POLYGON_MODE_LINE;
1930
1931 assert(vulkan_globals.fte_particle_pipelines[i + 8].handle == VK_NULL_HANDLE);
1932 err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.fte_particle_pipelines[i + 8].handle);
1933 if (err != VK_SUCCESS)
1934 Sys_Error("vkCreateGraphicsPipelines failed");
1935 vulkan_globals.fte_particle_pipelines[i + 8].layout = vulkan_globals.basic_pipeline_layout;
1936 GL_SetObjectName((uint64_t)vulkan_globals.fte_particle_pipelines[i + 8].handle, VK_OBJECT_TYPE_PIPELINE, fte_particle_pipeline_names[i + 8]);
1937 }
1938 }
1939 #endif
1940
1941 //================
1942 // Water
1943 //================
1944 input_assembly_state_create_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
1945 depth_stencil_state_create_info.depthTestEnable = VK_TRUE;
1946 depth_stencil_state_create_info.depthWriteEnable = VK_TRUE;
1947 depth_stencil_state_create_info.depthCompareOp = VK_COMPARE_OP_GREATER_OR_EQUAL;
1948 rasterization_state_create_info.polygonMode = VK_POLYGON_MODE_FILL;
1949 blend_attachment_state.blendEnable = VK_FALSE;
1950 blend_attachment_state.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
1951 blend_attachment_state.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
1952 blend_attachment_state.colorBlendOp = VK_BLEND_OP_ADD;
1953 blend_attachment_state.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
1954 blend_attachment_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
1955 blend_attachment_state.alphaBlendOp = VK_BLEND_OP_ADD;
1956 rasterization_state_create_info.depthBiasEnable = VK_FALSE;
1957
1958 assert(vulkan_globals.water_pipeline.handle == VK_NULL_HANDLE);
1959 err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.water_pipeline.handle);
1960 if (err != VK_SUCCESS)
1961 Sys_Error("vkCreateGraphicsPipelines failed");
1962 vulkan_globals.water_pipeline.layout = vulkan_globals.basic_pipeline_layout;
1963
1964 GL_SetObjectName((uint64_t)vulkan_globals.water_pipeline.handle, VK_OBJECT_TYPE_PIPELINE, "water");
1965
1966 depth_stencil_state_create_info.depthWriteEnable = VK_FALSE;
1967 blend_attachment_state.blendEnable = VK_TRUE;
1968
1969 assert(vulkan_globals.water_blend_pipeline.handle == VK_NULL_HANDLE);
1970 err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.water_blend_pipeline.handle);
1971 if (err != VK_SUCCESS)
1972 Sys_Error("vkCreateGraphicsPipelines failed");
1973 vulkan_globals.water_blend_pipeline.layout = vulkan_globals.basic_pipeline_layout;
1974 GL_SetObjectName((uint64_t)vulkan_globals.water_blend_pipeline.handle, VK_OBJECT_TYPE_PIPELINE, "water_blend");
1975
1976 //================
1977 // Sprites
1978 //================
1979 shader_stages[1].module = basic_alphatest_frag_module;
1980 blend_attachment_state.blendEnable = VK_FALSE;
1981 depth_stencil_state_create_info.depthTestEnable = VK_TRUE;
1982 depth_stencil_state_create_info.depthWriteEnable = VK_TRUE;
1983
1984 dynamic_states[dynamic_state_create_info.dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_BIAS;
1985
1986 assert(vulkan_globals.sprite_pipeline.handle == VK_NULL_HANDLE);
1987 err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.sprite_pipeline.handle);
1988 if (err != VK_SUCCESS)
1989 Sys_Error("vkCreateGraphicsPipelines failed");
1990 vulkan_globals.sprite_pipeline.layout = vulkan_globals.basic_pipeline_layout;
1991 GL_SetObjectName((uint64_t)vulkan_globals.sprite_pipeline.handle, VK_OBJECT_TYPE_PIPELINE, "sprite");
1992
1993 dynamic_state_create_info.dynamicStateCount--;
1994
1995 //================
1996 // Sky
1997 //================
1998 pipeline_create_info.renderPass = vulkan_globals.main_render_pass;
1999
2000 pipeline_create_info.stageCount = 1;
2001 shader_stages[1].module = VK_NULL_HANDLE;
2002
2003 depth_stencil_state_create_info.depthTestEnable = VK_TRUE;
2004 depth_stencil_state_create_info.depthWriteEnable = VK_TRUE;
2005 depth_stencil_state_create_info.depthCompareOp = VK_COMPARE_OP_GREATER_OR_EQUAL;
2006 depth_stencil_state_create_info.stencilTestEnable = VK_TRUE;
2007 depth_stencil_state_create_info.front.compareOp = VK_COMPARE_OP_ALWAYS;
2008 depth_stencil_state_create_info.front.failOp = VK_STENCIL_OP_KEEP;
2009 depth_stencil_state_create_info.front.depthFailOp = VK_STENCIL_OP_KEEP;
2010 depth_stencil_state_create_info.front.passOp = VK_STENCIL_OP_REPLACE;
2011 depth_stencil_state_create_info.front.compareMask = 0xFF;
2012 depth_stencil_state_create_info.front.writeMask = 0xFF;
2013 depth_stencil_state_create_info.front.reference = 0x1;
2014
2015 blend_attachment_state.colorWriteMask = 0; // We only want to write stencil
2016
2017 assert(vulkan_globals.sky_stencil_pipeline.handle == VK_NULL_HANDLE);
2018 err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.sky_stencil_pipeline.handle);
2019 if (err != VK_SUCCESS)
2020 Sys_Error("vkCreateGraphicsPipelines failed");
2021 vulkan_globals.sky_stencil_pipeline.layout = vulkan_globals.basic_pipeline_layout;
2022 GL_SetObjectName((uint64_t)vulkan_globals.sky_stencil_pipeline.handle, VK_OBJECT_TYPE_PIPELINE, "sky_stencil");
2023
2024 depth_stencil_state_create_info.stencilTestEnable = VK_FALSE;
2025 blend_attachment_state.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
2026 pipeline_create_info.stageCount = 2;
2027
2028 shader_stages[1].module = basic_notex_frag_module;
2029
2030 assert(vulkan_globals.sky_color_pipeline.handle == VK_NULL_HANDLE);
2031 err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.sky_color_pipeline.handle);
2032 if (err != VK_SUCCESS)
2033 Sys_Error("vkCreateGraphicsPipelines failed");
2034 vulkan_globals.sky_color_pipeline.layout = vulkan_globals.basic_pipeline_layout;
2035 GL_SetObjectName((uint64_t)vulkan_globals.sky_color_pipeline.handle, VK_OBJECT_TYPE_PIPELINE, "sky_color");
2036
2037 depth_stencil_state_create_info.depthTestEnable = VK_FALSE;
2038 depth_stencil_state_create_info.depthWriteEnable = VK_FALSE;
2039 depth_stencil_state_create_info.stencilTestEnable = VK_TRUE;
2040 depth_stencil_state_create_info.front.compareOp = VK_COMPARE_OP_EQUAL;
2041 depth_stencil_state_create_info.front.failOp = VK_STENCIL_OP_KEEP;
2042 depth_stencil_state_create_info.front.depthFailOp = VK_STENCIL_OP_KEEP;
2043 depth_stencil_state_create_info.front.passOp = VK_STENCIL_OP_KEEP;
2044 depth_stencil_state_create_info.front.compareMask = 0xFF;
2045 depth_stencil_state_create_info.front.writeMask = 0x0;
2046 depth_stencil_state_create_info.front.reference = 0x1;
2047 shader_stages[1].module = sky_box_frag_module;
2048
2049 assert(vulkan_globals.sky_box_pipeline.handle == VK_NULL_HANDLE);
2050 err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.sky_box_pipeline.handle);
2051 if (err != VK_SUCCESS)
2052 Sys_Error("vkCreateGraphicsPipelines failed");
2053 GL_SetObjectName((uint64_t)vulkan_globals.sky_box_pipeline.handle, VK_OBJECT_TYPE_PIPELINE, "sky_box");
2054
2055 vulkan_globals.sky_box_pipeline.layout = vulkan_globals.basic_pipeline_layout;
2056
2057 VkVertexInputAttributeDescription sky_layer_vertex_input_attribute_descriptions[4];
2058 sky_layer_vertex_input_attribute_descriptions[0].binding = 0;
2059 sky_layer_vertex_input_attribute_descriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT;
2060 sky_layer_vertex_input_attribute_descriptions[0].location = 0;
2061 sky_layer_vertex_input_attribute_descriptions[0].offset = 0;
2062 sky_layer_vertex_input_attribute_descriptions[1].binding = 0;
2063 sky_layer_vertex_input_attribute_descriptions[1].format = VK_FORMAT_R32G32_SFLOAT;
2064 sky_layer_vertex_input_attribute_descriptions[1].location = 1;
2065 sky_layer_vertex_input_attribute_descriptions[1].offset = 12;
2066 sky_layer_vertex_input_attribute_descriptions[2].binding = 0;
2067 sky_layer_vertex_input_attribute_descriptions[2].format = VK_FORMAT_R32G32_SFLOAT;
2068 sky_layer_vertex_input_attribute_descriptions[2].location = 2;
2069 sky_layer_vertex_input_attribute_descriptions[2].offset = 20;
2070 sky_layer_vertex_input_attribute_descriptions[3].binding = 0;
2071 sky_layer_vertex_input_attribute_descriptions[3].format = VK_FORMAT_R8G8B8A8_UNORM;
2072 sky_layer_vertex_input_attribute_descriptions[3].location = 3;
2073 sky_layer_vertex_input_attribute_descriptions[3].offset = 28;
2074
2075 VkVertexInputBindingDescription sky_layer_vertex_binding_description;
2076 sky_layer_vertex_binding_description.binding = 0;
2077 sky_layer_vertex_binding_description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2078 sky_layer_vertex_binding_description.stride = 32;
2079
2080 vertex_input_state_create_info.vertexAttributeDescriptionCount = 4;
2081 vertex_input_state_create_info.pVertexAttributeDescriptions = sky_layer_vertex_input_attribute_descriptions;
2082 vertex_input_state_create_info.vertexBindingDescriptionCount = 1;
2083 vertex_input_state_create_info.pVertexBindingDescriptions = &sky_layer_vertex_binding_description;
2084
2085 shader_stages[0].module = sky_layer_vert_module;
2086 shader_stages[1].module = sky_layer_frag_module;
2087 blend_attachment_state.blendEnable = VK_FALSE;
2088
2089 pipeline_create_info.layout = vulkan_globals.sky_layer_pipeline.layout.handle;
2090
2091 assert(vulkan_globals.sky_layer_pipeline.handle == VK_NULL_HANDLE);
2092 err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.sky_layer_pipeline.handle);
2093 if (err != VK_SUCCESS)
2094 Sys_Error("vkCreateGraphicsPipelines failed");
2095 GL_SetObjectName((uint64_t)vulkan_globals.sky_layer_pipeline.handle, VK_OBJECT_TYPE_PIPELINE, "sky_layer");
2096
2097 depth_stencil_state_create_info.stencilTestEnable = VK_FALSE;
2098
2099 //================
2100 // Show triangles
2101 //================
2102 if (vulkan_globals.non_solid_fill)
2103 {
2104 rasterization_state_create_info.cullMode = VK_CULL_MODE_NONE;
2105 rasterization_state_create_info.polygonMode = VK_POLYGON_MODE_LINE;
2106 depth_stencil_state_create_info.depthTestEnable = VK_FALSE;
2107 depth_stencil_state_create_info.depthWriteEnable = VK_FALSE;
2108 input_assembly_state_create_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
2109
2110 VkVertexInputAttributeDescription showtris_vertex_input_attribute_descriptions;
2111 showtris_vertex_input_attribute_descriptions.binding = 0;
2112 showtris_vertex_input_attribute_descriptions.format = VK_FORMAT_R32G32B32_SFLOAT;
2113 showtris_vertex_input_attribute_descriptions.location = 0;
2114 showtris_vertex_input_attribute_descriptions.offset = 0;
2115
2116 VkVertexInputBindingDescription showtris_vertex_binding_description;
2117 showtris_vertex_binding_description.binding = 0;
2118 showtris_vertex_binding_description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2119 showtris_vertex_binding_description.stride = 24;
2120
2121 vertex_input_state_create_info.vertexAttributeDescriptionCount = 1;
2122 vertex_input_state_create_info.pVertexAttributeDescriptions = &showtris_vertex_input_attribute_descriptions;
2123 vertex_input_state_create_info.vertexBindingDescriptionCount = 1;
2124 vertex_input_state_create_info.pVertexBindingDescriptions = &showtris_vertex_binding_description;
2125
2126 shader_stages[0].module = showtris_vert_module;
2127 shader_stages[1].module = showtris_frag_module;
2128
2129 pipeline_create_info.layout = vulkan_globals.basic_pipeline_layout.handle;
2130
2131 assert(vulkan_globals.showtris_pipeline.handle == VK_NULL_HANDLE);
2132 err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.showtris_pipeline.handle);
2133 if (err != VK_SUCCESS)
2134 Sys_Error("vkCreateGraphicsPipelines failed");
2135 vulkan_globals.showtris_pipeline.layout = vulkan_globals.basic_pipeline_layout;
2136 GL_SetObjectName((uint64_t)vulkan_globals.showtris_pipeline.handle, VK_OBJECT_TYPE_PIPELINE, "showtris");
2137
2138 depth_stencil_state_create_info.depthTestEnable = VK_TRUE;
2139 rasterization_state_create_info.depthBiasEnable = VK_TRUE;
2140 rasterization_state_create_info.depthBiasConstantFactor = 500.0f;
2141 rasterization_state_create_info.depthBiasSlopeFactor = 0.0f;
2142
2143 assert(vulkan_globals.showtris_depth_test_pipeline.handle == VK_NULL_HANDLE);
2144 err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.showtris_depth_test_pipeline.handle);
2145 if (err != VK_SUCCESS)
2146 Sys_Error("vkCreateGraphicsPipelines failed");
2147 vulkan_globals.showtris_depth_test_pipeline.layout = vulkan_globals.basic_pipeline_layout;
2148
2149 GL_SetObjectName((uint64_t)vulkan_globals.showtris_depth_test_pipeline.handle, VK_OBJECT_TYPE_PIPELINE, "showtris_depth_test");
2150
2151 depth_stencil_state_create_info.depthTestEnable = VK_FALSE;
2152 rasterization_state_create_info.depthBiasEnable = VK_FALSE;
2153 input_assembly_state_create_info.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
2154 assert(vulkan_globals.showbboxes_pipeline.handle == VK_NULL_HANDLE);
2155 err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.showbboxes_pipeline.handle);
2156 if (err != VK_SUCCESS)
2157 Sys_Error("vkCreateGraphicsPipelines failed");
2158 vulkan_globals.showbboxes_pipeline.layout = vulkan_globals.basic_pipeline_layout;
2159
2160 GL_SetObjectName((uint64_t)vulkan_globals.showbboxes_pipeline.handle, VK_OBJECT_TYPE_PIPELINE, "showbboxes");
2161 }
2162
2163 //================
2164 // World pipelines
2165 //================
2166 rasterization_state_create_info.cullMode = VK_CULL_MODE_BACK_BIT;
2167 rasterization_state_create_info.polygonMode = VK_POLYGON_MODE_FILL;
2168 depth_stencil_state_create_info.depthTestEnable = VK_TRUE;
2169 depth_stencil_state_create_info.depthWriteEnable = VK_TRUE;
2170 rasterization_state_create_info.depthBiasEnable = VK_TRUE;
2171 input_assembly_state_create_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
2172 dynamic_states[dynamic_state_create_info.dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_BIAS;
2173
2174 VkVertexInputAttributeDescription world_vertex_input_attribute_descriptions[3];
2175 world_vertex_input_attribute_descriptions[0].binding = 0;
2176 world_vertex_input_attribute_descriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT;
2177 world_vertex_input_attribute_descriptions[0].location = 0;
2178 world_vertex_input_attribute_descriptions[0].offset = 0;
2179 world_vertex_input_attribute_descriptions[1].binding = 0;
2180 world_vertex_input_attribute_descriptions[1].format = VK_FORMAT_R32G32_SFLOAT;
2181 world_vertex_input_attribute_descriptions[1].location = 1;
2182 world_vertex_input_attribute_descriptions[1].offset = 12;
2183 world_vertex_input_attribute_descriptions[2].binding = 0;
2184 world_vertex_input_attribute_descriptions[2].format = VK_FORMAT_R32G32_SFLOAT;
2185 world_vertex_input_attribute_descriptions[2].location = 2;
2186 world_vertex_input_attribute_descriptions[2].offset = 20;
2187
2188 VkVertexInputBindingDescription world_vertex_binding_description;
2189 world_vertex_binding_description.binding = 0;
2190 world_vertex_binding_description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2191 world_vertex_binding_description.stride = 28;
2192
2193 vertex_input_state_create_info.vertexAttributeDescriptionCount = 3;
2194 vertex_input_state_create_info.pVertexAttributeDescriptions = world_vertex_input_attribute_descriptions;
2195 vertex_input_state_create_info.vertexBindingDescriptionCount = 1;
2196 vertex_input_state_create_info.pVertexBindingDescriptions = &world_vertex_binding_description;
2197
2198 VkSpecializationMapEntry specialization_entries[3];
2199 specialization_entries[0].constantID = 0;
2200 specialization_entries[0].offset = 0;
2201 specialization_entries[0].size = 4;
2202 specialization_entries[1].constantID = 1;
2203 specialization_entries[1].offset = 4;
2204 specialization_entries[1].size = 4;
2205 specialization_entries[2].constantID = 2;
2206 specialization_entries[2].offset = 8;
2207 specialization_entries[2].size = 4;
2208
2209 uint32_t specialization_data[3];
2210 specialization_data[0] = 0;
2211 specialization_data[1] = 0;
2212 specialization_data[2] = 0;
2213
2214 VkSpecializationInfo specialization_info;
2215 specialization_info.mapEntryCount = 3;
2216 specialization_info.pMapEntries = specialization_entries;
2217 specialization_info.dataSize = 12;
2218 specialization_info.pData = specialization_data;
2219
2220 pipeline_create_info.layout = vulkan_globals.world_pipeline_layout.handle;
2221
2222 shader_stages[0].module = world_vert_module;
2223 shader_stages[1].module = world_frag_module;
2224 shader_stages[1].pSpecializationInfo = &specialization_info;
2225
2226 for (alpha_blend = 0; alpha_blend < 2; ++alpha_blend) {
2227 for (alpha_test = 0; alpha_test < 2; ++alpha_test) {
2228 for (fullbright_enabled = 0; fullbright_enabled < 2; ++fullbright_enabled) {
2229 int pipeline_index = fullbright_enabled + (alpha_test * 2) + (alpha_blend * 4);
2230
2231 specialization_data[0] = fullbright_enabled;
2232 specialization_data[1] = alpha_test;
2233 specialization_data[2] = alpha_blend;
2234
2235 blend_attachment_state.blendEnable = alpha_blend ? VK_TRUE : VK_FALSE;
2236 depth_stencil_state_create_info.depthWriteEnable = alpha_blend ? VK_FALSE : VK_TRUE;
2237 if ( pipeline_index > 0 ) {
2238 pipeline_create_info.flags = VK_PIPELINE_CREATE_DERIVATIVE_BIT;
2239 pipeline_create_info.basePipelineHandle = vulkan_globals.world_pipelines[0].handle;
2240 pipeline_create_info.basePipelineIndex = -1;
2241 } else {
2242 pipeline_create_info.flags = VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT;
2243 }
2244
2245 assert(vulkan_globals.world_pipelines[pipeline_index].handle == VK_NULL_HANDLE);
2246 err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.world_pipelines[pipeline_index].handle);
2247 if (err != VK_SUCCESS)
2248 Sys_Error("vkCreateGraphicsPipelines failed");
2249 GL_SetObjectName((uint64_t)vulkan_globals.world_pipelines[pipeline_index].handle, VK_OBJECT_TYPE_PIPELINE, va("world %d", pipeline_index));
2250 vulkan_globals.world_pipelines[pipeline_index].layout = vulkan_globals.world_pipeline_layout;
2251 }
2252 }
2253 }
2254
2255 depth_stencil_state_create_info.depthTestEnable = VK_TRUE;
2256 depth_stencil_state_create_info.depthWriteEnable = VK_TRUE;
2257 rasterization_state_create_info.depthBiasEnable = VK_FALSE;
2258 dynamic_state_create_info.dynamicStateCount--;
2259 pipeline_create_info.flags = 0;
2260 blend_attachment_state.blendEnable = VK_FALSE;
2261 shader_stages[1].pSpecializationInfo = NULL;
2262
2263 //================
2264 // Alias pipeline
2265 //================
2266 VkVertexInputAttributeDescription alias_vertex_input_attribute_descriptions[5];
2267 alias_vertex_input_attribute_descriptions[0].binding = 0;
2268 alias_vertex_input_attribute_descriptions[0].format = VK_FORMAT_R32G32_SFLOAT;
2269 alias_vertex_input_attribute_descriptions[0].location = 0;
2270 alias_vertex_input_attribute_descriptions[0].offset = 0;
2271 alias_vertex_input_attribute_descriptions[1].binding = 1;
2272 alias_vertex_input_attribute_descriptions[1].format = VK_FORMAT_R8G8B8A8_UNORM;
2273 alias_vertex_input_attribute_descriptions[1].location = 1;
2274 alias_vertex_input_attribute_descriptions[1].offset = 0;
2275 alias_vertex_input_attribute_descriptions[2].binding = 1;
2276 alias_vertex_input_attribute_descriptions[2].format = VK_FORMAT_R8G8B8A8_SNORM;
2277 alias_vertex_input_attribute_descriptions[2].location = 2;
2278 alias_vertex_input_attribute_descriptions[2].offset = 4;
2279 alias_vertex_input_attribute_descriptions[3].binding = 2;
2280 alias_vertex_input_attribute_descriptions[3].format = VK_FORMAT_R8G8B8A8_UNORM;
2281 alias_vertex_input_attribute_descriptions[3].location = 3;
2282 alias_vertex_input_attribute_descriptions[3].offset = 0;
2283 alias_vertex_input_attribute_descriptions[4].binding = 2;
2284 alias_vertex_input_attribute_descriptions[4].format = VK_FORMAT_R8G8B8A8_SNORM;
2285 alias_vertex_input_attribute_descriptions[4].location = 4;
2286 alias_vertex_input_attribute_descriptions[4].offset = 4;
2287
2288 VkVertexInputBindingDescription alias_vertex_binding_descriptions[3];
2289 alias_vertex_binding_descriptions[0].binding = 0;
2290 alias_vertex_binding_descriptions[0].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2291 alias_vertex_binding_descriptions[0].stride = 8;
2292 alias_vertex_binding_descriptions[1].binding = 1;
2293 alias_vertex_binding_descriptions[1].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2294 alias_vertex_binding_descriptions[1].stride = 8;
2295 alias_vertex_binding_descriptions[2].binding = 2;
2296 alias_vertex_binding_descriptions[2].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2297 alias_vertex_binding_descriptions[2].stride = 8;
2298
2299 vertex_input_state_create_info.vertexAttributeDescriptionCount = 5;
2300 vertex_input_state_create_info.pVertexAttributeDescriptions = alias_vertex_input_attribute_descriptions;
2301 vertex_input_state_create_info.vertexBindingDescriptionCount = 3;
2302 vertex_input_state_create_info.pVertexBindingDescriptions = alias_vertex_binding_descriptions;
2303
2304 shader_stages[0].module = alias_vert_module;
2305 shader_stages[1].module = alias_frag_module;
2306
2307 pipeline_create_info.layout = vulkan_globals.alias_pipeline.layout.handle;
2308
2309 assert(vulkan_globals.alias_pipeline.handle == VK_NULL_HANDLE);
2310 err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.alias_pipeline.handle);
2311 if (err != VK_SUCCESS)
2312 Sys_Error("vkCreateGraphicsPipelines failed");
2313 GL_SetObjectName((uint64_t)vulkan_globals.alias_pipeline.handle, VK_OBJECT_TYPE_PIPELINE, "alias");
2314
2315 shader_stages[1].module = alias_alphatest_frag_module;
2316
2317 assert(vulkan_globals.alias_alphatest_pipeline.handle == VK_NULL_HANDLE);
2318 err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.alias_alphatest_pipeline.handle);
2319 if (err != VK_SUCCESS)
2320 Sys_Error("vkCreateGraphicsPipelines failed");
2321 GL_SetObjectName((uint64_t)vulkan_globals.alias_alphatest_pipeline.handle, VK_OBJECT_TYPE_PIPELINE, "alias_alphatest");
2322 vulkan_globals.alias_alphatest_pipeline.layout = vulkan_globals.alias_pipeline.layout;
2323
2324 depth_stencil_state_create_info.depthWriteEnable = VK_FALSE;
2325 blend_attachment_state.blendEnable = VK_TRUE;
2326 shader_stages[1].module = alias_frag_module;
2327
2328 assert(vulkan_globals.alias_blend_pipeline.handle == VK_NULL_HANDLE);
2329 err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.alias_blend_pipeline.handle);
2330 if (err != VK_SUCCESS)
2331 Sys_Error("vkCreateGraphicsPipelines failed");
2332 GL_SetObjectName((uint64_t)vulkan_globals.alias_blend_pipeline.handle, VK_OBJECT_TYPE_PIPELINE, "alias_blend");
2333 vulkan_globals.alias_blend_pipeline.layout = vulkan_globals.alias_pipeline.layout;
2334
2335 shader_stages[1].module = alias_alphatest_frag_module;
2336
2337 assert(vulkan_globals.alias_alphatest_blend_pipeline.handle == VK_NULL_HANDLE);
2338 err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.alias_alphatest_blend_pipeline.handle);
2339 if (err != VK_SUCCESS)
2340 Sys_Error("vkCreateGraphicsPipelines failed");
2341 GL_SetObjectName((uint64_t)vulkan_globals.alias_alphatest_blend_pipeline.handle, VK_OBJECT_TYPE_PIPELINE, "alias_alphatest_blend");
2342 vulkan_globals.alias_alphatest_blend_pipeline.layout = vulkan_globals.alias_pipeline.layout;
2343
2344 if (vulkan_globals.non_solid_fill)
2345 {
2346 rasterization_state_create_info.cullMode = VK_CULL_MODE_NONE;
2347 rasterization_state_create_info.polygonMode = VK_POLYGON_MODE_LINE;
2348 depth_stencil_state_create_info.depthTestEnable = VK_FALSE;
2349 depth_stencil_state_create_info.depthWriteEnable = VK_FALSE;
2350 blend_attachment_state.blendEnable = VK_FALSE;
2351 input_assembly_state_create_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
2352
2353 shader_stages[0].module = alias_vert_module;
2354 shader_stages[1].module = showtris_frag_module;
2355
2356 pipeline_create_info.layout = vulkan_globals.alias_pipeline.layout.handle;
2357
2358 assert(vulkan_globals.alias_showtris_pipeline.handle == VK_NULL_HANDLE);
2359 err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.alias_showtris_pipeline.handle);
2360 if (err != VK_SUCCESS)
2361 Sys_Error("vkCreateGraphicsPipelines failed");
2362 GL_SetObjectName((uint64_t)vulkan_globals.alias_showtris_pipeline.handle, VK_OBJECT_TYPE_PIPELINE, "alias_showtris");
2363 vulkan_globals.alias_showtris_pipeline.layout = vulkan_globals.alias_pipeline.layout;
2364
2365 depth_stencil_state_create_info.depthTestEnable = VK_TRUE;
2366 rasterization_state_create_info.depthBiasEnable = VK_TRUE;
2367 rasterization_state_create_info.depthBiasConstantFactor = 500.0f;
2368 rasterization_state_create_info.depthBiasSlopeFactor = 0.0f;
2369
2370 assert(vulkan_globals.alias_showtris_depth_test_pipeline.handle == VK_NULL_HANDLE);
2371 err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.alias_showtris_depth_test_pipeline.handle);
2372 if (err != VK_SUCCESS)
2373 Sys_Error("vkCreateGraphicsPipelines failed");
2374 GL_SetObjectName((uint64_t)vulkan_globals.alias_showtris_depth_test_pipeline.handle, VK_OBJECT_TYPE_PIPELINE, "alias_showtris_depth_test");
2375 vulkan_globals.alias_showtris_depth_test_pipeline.layout = vulkan_globals.alias_pipeline.layout;
2376 }
2377
2378 //================
2379 // Postprocess pipeline
2380 //================
2381 multisample_state_create_info.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
2382 rasterization_state_create_info.polygonMode = VK_POLYGON_MODE_FILL;
2383 rasterization_state_create_info.cullMode = VK_CULL_MODE_NONE;
2384 rasterization_state_create_info.depthBiasEnable = VK_FALSE;
2385 depth_stencil_state_create_info.depthTestEnable = VK_TRUE;
2386 depth_stencil_state_create_info.depthWriteEnable = VK_TRUE;
2387 blend_attachment_state.blendEnable = VK_FALSE;
2388
2389 vertex_input_state_create_info.vertexAttributeDescriptionCount = 0;
2390 vertex_input_state_create_info.pVertexAttributeDescriptions = NULL;
2391 vertex_input_state_create_info.vertexBindingDescriptionCount = 0;
2392 vertex_input_state_create_info.pVertexBindingDescriptions = NULL;
2393
2394 shader_stages[0].module = postprocess_vert_module;
2395 shader_stages[1].module = postprocess_frag_module;
2396 pipeline_create_info.renderPass = vulkan_globals.ui_render_pass;
2397 pipeline_create_info.layout = vulkan_globals.postprocess_pipeline.layout.handle;
2398 pipeline_create_info.subpass = 1;
2399
2400 assert(vulkan_globals.postprocess_pipeline.handle == VK_NULL_HANDLE);
2401 err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.postprocess_pipeline.handle);
2402 if (err != VK_SUCCESS)
2403 Sys_Error("vkCreateGraphicsPipelines failed");
2404 GL_SetObjectName((uint64_t)vulkan_globals.postprocess_pipeline.handle, VK_OBJECT_TYPE_PIPELINE, "postprocess");
2405
2406 //================
2407 // Screen Effects
2408 //================
2409 VkPipelineShaderStageCreateInfo compute_shader_stage;
2410 memset(&compute_shader_stage, 0, sizeof(compute_shader_stage));
2411 compute_shader_stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
2412 compute_shader_stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
2413 compute_shader_stage.module = (vulkan_globals.color_format == VK_FORMAT_A2B10G10R10_UNORM_PACK32) ? screen_effects_10bit_comp_module : screen_effects_8bit_comp_module;
2414 compute_shader_stage.pName = "main";
2415
2416 VkComputePipelineCreateInfo compute_pipeline_create_info;
2417 memset(&compute_pipeline_create_info, 0, sizeof(compute_pipeline_create_info));
2418 compute_pipeline_create_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
2419 compute_pipeline_create_info.stage = compute_shader_stage;
2420 compute_pipeline_create_info.layout = vulkan_globals.screen_effects_pipeline.layout.handle;
2421
2422 assert(vulkan_globals.screen_effects_pipeline.handle == VK_NULL_HANDLE);
2423 err = vkCreateComputePipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &compute_pipeline_create_info, NULL, &vulkan_globals.screen_effects_pipeline.handle);
2424 if (err != VK_SUCCESS)
2425 Sys_Error("vkCreateComputePipelines failed");
2426 GL_SetObjectName((uint64_t)vulkan_globals.screen_effects_pipeline.handle, VK_OBJECT_TYPE_PIPELINE, "screen_effects");
2427
2428 compute_shader_stage.module = (vulkan_globals.color_format == VK_FORMAT_A2B10G10R10_UNORM_PACK32) ? screen_effects_10bit_scale_comp_module : screen_effects_8bit_scale_comp_module;
2429 compute_pipeline_create_info.stage = compute_shader_stage;
2430 assert(vulkan_globals.screen_effects_scale_pipeline.handle == VK_NULL_HANDLE);
2431 err = vkCreateComputePipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &compute_pipeline_create_info, NULL, &vulkan_globals.screen_effects_scale_pipeline.handle);
2432 if (err != VK_SUCCESS)
2433 Sys_Error("vkCreateComputePipelines failed");
2434 GL_SetObjectName((uint64_t)vulkan_globals.screen_effects_scale_pipeline.handle, VK_OBJECT_TYPE_PIPELINE, "screen_effects_scale");
2435
2436 #if defined(VK_EXT_subgroup_size_control)
2437 if (vulkan_globals.screen_effects_sops)
2438 {
2439 compute_shader_stage.module = (vulkan_globals.color_format == VK_FORMAT_A2B10G10R10_UNORM_PACK32) ? screen_effects_10bit_scale_sops_comp_module : screen_effects_8bit_scale_sops_comp_module;
2440 compute_shader_stage.flags = VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT | VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT;
2441 compute_pipeline_create_info.stage = compute_shader_stage;
2442 assert(vulkan_globals.screen_effects_scale_sops_pipeline.handle == VK_NULL_HANDLE);
2443 err = vkCreateComputePipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &compute_pipeline_create_info, NULL, &vulkan_globals.screen_effects_scale_sops_pipeline.handle);
2444 if (err != VK_SUCCESS)
2445 Sys_Error("vkCreateComputePipelines failed");
2446 GL_SetObjectName((uint64_t)vulkan_globals.screen_effects_scale_sops_pipeline.handle, VK_OBJECT_TYPE_PIPELINE, "screen_effects_scale_sops");
2447 compute_shader_stage.flags = 0;
2448 }
2449 #endif
2450
2451 //================
2452 // Texture Warp
2453 //================
2454 memset(&compute_shader_stage, 0, sizeof(compute_shader_stage));
2455 compute_shader_stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
2456 compute_shader_stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
2457 compute_shader_stage.module = cs_tex_warp_comp_module;
2458 compute_shader_stage.pName = "main";
2459
2460 memset(&compute_pipeline_create_info, 0, sizeof(compute_pipeline_create_info));
2461 compute_pipeline_create_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
2462 compute_pipeline_create_info.stage = compute_shader_stage;
2463 compute_pipeline_create_info.layout = vulkan_globals.cs_tex_warp_pipeline.layout.handle;
2464
2465 assert(vulkan_globals.cs_tex_warp_pipeline.handle == VK_NULL_HANDLE);
2466 err = vkCreateComputePipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &compute_pipeline_create_info, NULL, &vulkan_globals.cs_tex_warp_pipeline.handle);
2467 if (err != VK_SUCCESS)
2468 Sys_Error("vkCreateComputePipelines failed");
2469 GL_SetObjectName((uint64_t)vulkan_globals.cs_tex_warp_pipeline.handle, VK_OBJECT_TYPE_PIPELINE, "cs_tex_warp");
2470
2471 vkDestroyShaderModule(vulkan_globals.device, showtris_frag_module, NULL);
2472 vkDestroyShaderModule(vulkan_globals.device, showtris_vert_module, NULL);
2473 vkDestroyShaderModule(vulkan_globals.device, cs_tex_warp_comp_module, NULL);
2474 vkDestroyShaderModule(vulkan_globals.device, screen_effects_8bit_comp_module, NULL);
2475 vkDestroyShaderModule(vulkan_globals.device, screen_effects_8bit_scale_comp_module, NULL);
2476 if (screen_effects_8bit_scale_sops_comp_module != VK_NULL_HANDLE)
2477 vkDestroyShaderModule(vulkan_globals.device, screen_effects_8bit_scale_sops_comp_module, NULL);
2478 vkDestroyShaderModule(vulkan_globals.device, screen_effects_10bit_comp_module, NULL);
2479 vkDestroyShaderModule(vulkan_globals.device, screen_effects_10bit_scale_comp_module, NULL);
2480 if (screen_effects_10bit_scale_sops_comp_module != VK_NULL_HANDLE)
2481 vkDestroyShaderModule(vulkan_globals.device, screen_effects_10bit_scale_sops_comp_module, NULL);
2482 vkDestroyShaderModule(vulkan_globals.device, postprocess_frag_module, NULL);
2483 vkDestroyShaderModule(vulkan_globals.device, postprocess_vert_module, NULL);
2484 vkDestroyShaderModule(vulkan_globals.device, sky_layer_frag_module, NULL);
2485 vkDestroyShaderModule(vulkan_globals.device, sky_layer_vert_module, NULL);
2486 vkDestroyShaderModule(vulkan_globals.device, alias_frag_module, NULL);
2487 vkDestroyShaderModule(vulkan_globals.device, alias_alphatest_frag_module, NULL);
2488 vkDestroyShaderModule(vulkan_globals.device, alias_vert_module, NULL);
2489 vkDestroyShaderModule(vulkan_globals.device, world_frag_module, NULL);
2490 vkDestroyShaderModule(vulkan_globals.device, world_vert_module, NULL);
2491 vkDestroyShaderModule(vulkan_globals.device, basic_notex_frag_module, NULL);
2492 vkDestroyShaderModule(vulkan_globals.device, basic_alphatest_frag_module, NULL);
2493 vkDestroyShaderModule(vulkan_globals.device, basic_frag_module, NULL);
2494 vkDestroyShaderModule(vulkan_globals.device, basic_vert_module, NULL);
2495 }
2496
2497 /*
2498 ===============
2499 R_DestroyPipelines
2500 ===============
2501 */
R_DestroyPipelines(void)2502 void R_DestroyPipelines(void)
2503 {
2504 int i;
2505 for (i = 0; i < 2; ++i)
2506 {
2507 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.basic_alphatest_pipeline[i].handle, NULL);
2508 vulkan_globals.basic_alphatest_pipeline[i].handle = VK_NULL_HANDLE;
2509 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.basic_blend_pipeline[i].handle, NULL);
2510 vulkan_globals.basic_blend_pipeline[i].handle = VK_NULL_HANDLE;
2511 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.basic_notex_blend_pipeline[i].handle, NULL);
2512 vulkan_globals.basic_notex_blend_pipeline[i].handle = VK_NULL_HANDLE;
2513 }
2514 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.basic_poly_blend_pipeline.handle, NULL);
2515 vulkan_globals.basic_poly_blend_pipeline.handle = VK_NULL_HANDLE;
2516 for (i = 0; i < WORLD_PIPELINE_COUNT; ++i) {
2517 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.world_pipelines[i].handle, NULL);
2518 vulkan_globals.world_pipelines[i].handle = VK_NULL_HANDLE;
2519 }
2520 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.water_pipeline.handle, NULL);
2521 vulkan_globals.water_pipeline.handle = VK_NULL_HANDLE;
2522 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.water_blend_pipeline.handle, NULL);
2523 vulkan_globals.water_blend_pipeline.handle = VK_NULL_HANDLE;
2524 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.raster_tex_warp_pipeline.handle, NULL);
2525 vulkan_globals.raster_tex_warp_pipeline.handle = VK_NULL_HANDLE;
2526 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.particle_pipeline.handle, NULL);
2527 vulkan_globals.particle_pipeline.handle = VK_NULL_HANDLE;
2528 #ifdef PSET_SCRIPT
2529 for (i = 0; i < 8; ++i)
2530 {
2531 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.fte_particle_pipelines[i].handle, NULL);
2532 vulkan_globals.fte_particle_pipelines[i].handle = VK_NULL_HANDLE;
2533 if (vulkan_globals.non_solid_fill)
2534 {
2535 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.fte_particle_pipelines[i + 8].handle, NULL);
2536 vulkan_globals.fte_particle_pipelines[i + 8].handle = VK_NULL_HANDLE;
2537 }
2538 }
2539 #endif
2540 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.sprite_pipeline.handle, NULL);
2541 vulkan_globals.sprite_pipeline.handle = VK_NULL_HANDLE;
2542 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.sky_stencil_pipeline.handle, NULL);
2543 vulkan_globals.sky_stencil_pipeline.handle = VK_NULL_HANDLE;
2544 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.sky_color_pipeline.handle, NULL);
2545 vulkan_globals.sky_color_pipeline.handle = VK_NULL_HANDLE;
2546 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.sky_box_pipeline.handle, NULL);
2547 vulkan_globals.sky_box_pipeline.handle = VK_NULL_HANDLE;
2548 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.sky_layer_pipeline.handle, NULL);
2549 vulkan_globals.sky_layer_pipeline.handle = VK_NULL_HANDLE;
2550 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.alias_pipeline.handle, NULL);
2551 vulkan_globals.alias_pipeline.handle = VK_NULL_HANDLE;
2552 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.alias_alphatest_pipeline.handle, NULL);
2553 vulkan_globals.alias_alphatest_pipeline.handle = VK_NULL_HANDLE;
2554 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.alias_alphatest_blend_pipeline.handle, NULL);
2555 vulkan_globals.alias_alphatest_blend_pipeline.handle = VK_NULL_HANDLE;
2556 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.alias_blend_pipeline.handle, NULL);
2557 vulkan_globals.alias_blend_pipeline.handle = VK_NULL_HANDLE;
2558 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.postprocess_pipeline.handle, NULL);
2559 vulkan_globals.postprocess_pipeline.handle = VK_NULL_HANDLE;
2560 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.screen_effects_pipeline.handle, NULL);
2561 vulkan_globals.screen_effects_pipeline.handle = VK_NULL_HANDLE;
2562 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.screen_effects_scale_pipeline.handle, NULL);
2563 vulkan_globals.screen_effects_scale_pipeline.handle = VK_NULL_HANDLE;
2564 if (vulkan_globals.screen_effects_scale_sops_pipeline.handle != VK_NULL_HANDLE)
2565 {
2566 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.screen_effects_scale_sops_pipeline.handle, NULL);
2567 vulkan_globals.screen_effects_scale_sops_pipeline.handle = VK_NULL_HANDLE;
2568 }
2569 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.cs_tex_warp_pipeline.handle, NULL);
2570 vulkan_globals.cs_tex_warp_pipeline.handle = VK_NULL_HANDLE;
2571 if (vulkan_globals.showtris_pipeline.handle != VK_NULL_HANDLE)
2572 {
2573 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.showtris_pipeline.handle, NULL);
2574 vulkan_globals.showtris_pipeline.handle = VK_NULL_HANDLE;
2575 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.showtris_depth_test_pipeline.handle, NULL);
2576 vulkan_globals.showtris_depth_test_pipeline.handle = VK_NULL_HANDLE;
2577 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.showbboxes_pipeline.handle, NULL);
2578 vulkan_globals.showbboxes_pipeline.handle = VK_NULL_HANDLE;
2579 }
2580 if (vulkan_globals.alias_showtris_pipeline.handle != VK_NULL_HANDLE)
2581 {
2582 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.alias_showtris_pipeline.handle, NULL);
2583 vulkan_globals.alias_showtris_pipeline.handle = VK_NULL_HANDLE;
2584 vkDestroyPipeline(vulkan_globals.device, vulkan_globals.alias_showtris_depth_test_pipeline.handle, NULL);
2585 vulkan_globals.alias_showtris_depth_test_pipeline.handle = VK_NULL_HANDLE;
2586 }
2587 }
2588
2589 /*
2590 ===================
2591 R_ScaleChanged_f
2592 ===================
2593 */
R_ScaleChanged_f(cvar_t * var)2594 static void R_ScaleChanged_f(cvar_t *var)
2595 {
2596 R_InitSamplers();
2597 }
2598
2599 /*
2600 ===============
2601 R_Init
2602 ===============
2603 */
R_Init(void)2604 void R_Init (void)
2605 {
2606 Cmd_AddCommand ("timerefresh", R_TimeRefresh_f);
2607 Cmd_AddCommand ("pointfile", R_ReadPointFile_f);
2608 Cmd_AddCommand ("vkmemstats", R_VulkanMemStats_f);
2609
2610 Cvar_RegisterVariable (&r_fullbright);
2611 Cvar_RegisterVariable (&r_lightmap);
2612 Cvar_RegisterVariable (&r_drawentities);
2613 Cvar_RegisterVariable (&r_drawviewmodel);
2614 Cvar_RegisterVariable (&r_wateralpha);
2615 Cvar_SetCallback (&r_wateralpha, R_SetWateralpha_f);
2616 Cvar_RegisterVariable (&r_dynamic);
2617 Cvar_RegisterVariable (&r_novis);
2618 #if defined(USE_SIMD)
2619 Cvar_RegisterVariable (&r_simd);
2620 Cvar_SetCallback (&r_simd, R_SIMD_f);
2621 R_SIMD_f(&r_simd);
2622 #endif
2623 Cvar_RegisterVariable (&r_speeds);
2624 Cvar_RegisterVariable (&r_pos);
2625 Cvar_RegisterVariable (&gl_polyblend);
2626 Cvar_RegisterVariable (&gl_nocolors);
2627
2628 //johnfitz -- new cvars
2629 Cvar_RegisterVariable (&r_clearcolor);
2630 Cvar_SetCallback (&r_clearcolor, R_SetClearColor_f);
2631 Cvar_RegisterVariable (&r_fastclear);
2632 Cvar_SetCallback (&r_fastclear, R_SetFastClear_f);
2633 Cvar_RegisterVariable (&r_waterquality);
2634 Cvar_RegisterVariable (&r_waterwarp);
2635 Cvar_RegisterVariable (&r_waterwarpcompute);
2636 Cvar_RegisterVariable (&r_flatlightstyles);
2637 Cvar_RegisterVariable (&r_oldskyleaf);
2638 Cvar_RegisterVariable (&r_drawworld);
2639 Cvar_RegisterVariable (&r_showtris);
2640 Cvar_RegisterVariable (&r_showbboxes);
2641 Cvar_RegisterVariable (&gl_farclip);
2642 Cvar_RegisterVariable (&gl_fullbrights);
2643 Cvar_SetCallback (&gl_fullbrights, GL_Fullbrights_f);
2644 Cvar_RegisterVariable (&r_lerpmodels);
2645 Cvar_RegisterVariable (&r_lerpmove);
2646 Cvar_RegisterVariable (&r_nolerp_list);
2647 Cvar_SetCallback (&r_nolerp_list, R_Model_ExtraFlags_List_f);
2648 //johnfitz
2649
2650 Cvar_RegisterVariable (&gl_zfix); // QuakeSpasm z-fighting fix
2651 Cvar_RegisterVariable (&r_lavaalpha);
2652 Cvar_RegisterVariable (&r_telealpha);
2653 Cvar_RegisterVariable (&r_slimealpha);
2654 Cvar_RegisterVariable (&r_scale);
2655 Cvar_RegisterVariable (&r_lodbias);
2656 Cvar_SetCallback (&r_scale, R_ScaleChanged_f);
2657 Cvar_SetCallback (&r_lodbias, R_ScaleChanged_f);
2658 Cvar_SetCallback (&r_lavaalpha, R_SetLavaalpha_f);
2659 Cvar_SetCallback (&r_telealpha, R_SetTelealpha_f);
2660 Cvar_SetCallback (&r_slimealpha, R_SetSlimealpha_f);
2661
2662 R_InitParticles ();
2663 #ifdef PSET_SCRIPT
2664 PScript_InitParticles();
2665 #endif
2666 SetClearColor(); //johnfitz
2667
2668 Sky_Init (); //johnfitz
2669 Fog_Init (); //johnfitz
2670 }
2671
2672 /*
2673 ===============
2674 R_AllocateDescriptorSet
2675 ===============
2676 */
R_AllocateDescriptorSet(vulkan_desc_set_layout_t * layout)2677 VkDescriptorSet R_AllocateDescriptorSet(vulkan_desc_set_layout_t * layout)
2678 {
2679 VkDescriptorSetAllocateInfo descriptor_set_allocate_info;
2680 memset(&descriptor_set_allocate_info, 0, sizeof(descriptor_set_allocate_info));
2681 descriptor_set_allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
2682 descriptor_set_allocate_info.descriptorPool = vulkan_globals.descriptor_pool;
2683 descriptor_set_allocate_info.descriptorSetCount = 1;
2684 descriptor_set_allocate_info.pSetLayouts = &layout->handle;
2685
2686 VkDescriptorSet handle;
2687 vkAllocateDescriptorSets(vulkan_globals.device, &descriptor_set_allocate_info, &handle);
2688
2689 num_vulkan_combined_image_samplers += layout->num_combined_image_samplers;
2690 num_vulkan_ubos_dynamic += layout->num_ubos_dynamic;
2691 num_vulkan_input_attachments += layout->num_input_attachments;
2692 num_vulkan_storage_images += layout->num_storage_images;
2693
2694 return handle;
2695 }
2696
2697 /*
2698 ===============
2699 R_FreeDescriptorSet
2700 ===============
2701 */
2702
R_FreeDescriptorSet(VkDescriptorSet desc_set,vulkan_desc_set_layout_t * layout)2703 void R_FreeDescriptorSet(VkDescriptorSet desc_set, vulkan_desc_set_layout_t * layout)
2704 {
2705 vkFreeDescriptorSets(vulkan_globals.device, vulkan_globals.descriptor_pool, 1, &desc_set);
2706
2707 num_vulkan_combined_image_samplers -= layout->num_combined_image_samplers;
2708 num_vulkan_ubos_dynamic -= layout->num_ubos_dynamic;
2709 num_vulkan_input_attachments -= layout->num_input_attachments;
2710 num_vulkan_storage_images -= layout->num_storage_images;
2711 }
2712
2713 /*
2714 ===============
2715 R_TranslatePlayerSkin -- johnfitz -- rewritten. also, only handles new colors, not new skins
2716 ===============
2717 */
R_TranslatePlayerSkin(int playernum)2718 void R_TranslatePlayerSkin (int playernum)
2719 {
2720 int top, bottom;
2721
2722 top = (cl.scores[playernum].colors & 0xf0)>>4;
2723 bottom = cl.scores[playernum].colors &15;
2724
2725 //FIXME: if gl_nocolors is on, then turned off, the textures may be out of sync with the scoreboard colors.
2726 if (!gl_nocolors.value)
2727 if (playertextures[playernum])
2728 TexMgr_ReloadImage (playertextures[playernum], top, bottom);
2729 }
2730
2731 /*
2732 ===============
2733 R_TranslateNewPlayerSkin -- johnfitz -- split off of TranslatePlayerSkin -- this is called when
2734 the skin or model actually changes, instead of just new colors
2735 added bug fix from bengt jardup
2736 ===============
2737 */
R_TranslateNewPlayerSkin(int playernum)2738 void R_TranslateNewPlayerSkin (int playernum)
2739 {
2740 char name[64];
2741 byte *pixels;
2742 aliashdr_t *paliashdr;
2743 int skinnum;
2744
2745 //get correct texture pixels
2746 currententity = &cl.entities[1+playernum];
2747
2748 if (!currententity->model || currententity->model->type != mod_alias)
2749 return;
2750
2751 paliashdr = (aliashdr_t *)Mod_Extradata (currententity->model);
2752
2753 skinnum = currententity->skinnum;
2754
2755 //TODO: move these tests to the place where skinnum gets received from the server
2756 if (skinnum < 0 || skinnum >= paliashdr->numskins)
2757 {
2758 Con_DPrintf("(%d): Invalid player skin #%d\n", playernum, skinnum);
2759 skinnum = 0;
2760 }
2761
2762 pixels = (byte *)paliashdr + paliashdr->texels[skinnum]; // This is not a persistent place!
2763
2764 //upload new image
2765 q_snprintf(name, sizeof(name), "player_%i", playernum);
2766 playertextures[playernum] = TexMgr_LoadImage (currententity->model, name, paliashdr->skinwidth, paliashdr->skinheight,
2767 SRC_INDEXED, pixels, paliashdr->gltextures[skinnum][0]->source_file, paliashdr->gltextures[skinnum][0]->source_offset, TEXPREF_PAD | TEXPREF_OVERWRITE);
2768
2769 //now recolor it
2770 R_TranslatePlayerSkin (playernum);
2771 }
2772
2773 /*
2774 ===============
2775 R_NewGame -- johnfitz -- handle a game switch
2776 ===============
2777 */
R_NewGame(void)2778 void R_NewGame (void)
2779 {
2780 int i;
2781
2782 //clear playertexture pointers (the textures themselves were freed by texmgr_newgame)
2783 for (i=0; i<MAX_SCOREBOARD; i++)
2784 playertextures[i] = NULL;
2785 }
2786
2787 /*
2788 =============
2789 R_ParseWorldspawn
2790
2791 called at map load
2792 =============
2793 */
R_ParseWorldspawn(void)2794 static void R_ParseWorldspawn (void)
2795 {
2796 char key[128], value[4096];
2797 const char *data;
2798
2799 map_fallbackalpha = r_wateralpha.value;
2800 map_wateralpha = (cl.worldmodel->contentstransparent&SURF_DRAWWATER)?r_wateralpha.value:1;
2801 map_lavaalpha = (cl.worldmodel->contentstransparent&SURF_DRAWLAVA)?r_lavaalpha.value:1;
2802 map_telealpha = (cl.worldmodel->contentstransparent&SURF_DRAWTELE)?r_telealpha.value:1;
2803 map_slimealpha = (cl.worldmodel->contentstransparent&SURF_DRAWSLIME)?r_slimealpha.value:1;
2804
2805 data = COM_Parse(cl.worldmodel->entities);
2806 if (!data)
2807 return; // error
2808 if (com_token[0] != '{')
2809 return; // error
2810 while (1)
2811 {
2812 data = COM_Parse(data);
2813 if (!data)
2814 return; // error
2815 if (com_token[0] == '}')
2816 break; // end of worldspawn
2817 if (com_token[0] == '_')
2818 q_strlcpy(key, com_token + 1, sizeof(key));
2819 else
2820 q_strlcpy(key, com_token, sizeof(key));
2821 while (key[0] && key[strlen(key)-1] == ' ') // remove trailing spaces
2822 key[strlen(key)-1] = 0;
2823 data = COM_Parse(data);
2824 if (!data)
2825 return; // error
2826 q_strlcpy(value, com_token, sizeof(value));
2827
2828 if (!strcmp("wateralpha", key))
2829 map_wateralpha = atof(value);
2830
2831 if (!strcmp("lavaalpha", key))
2832 map_lavaalpha = atof(value);
2833
2834 if (!strcmp("telealpha", key))
2835 map_telealpha = atof(value);
2836
2837 if (!strcmp("slimealpha", key))
2838 map_slimealpha = atof(value);
2839 }
2840 }
2841
2842
2843 /*
2844 ===============
2845 R_NewMap
2846 ===============
2847 */
R_NewMap(void)2848 void R_NewMap (void)
2849 {
2850 int i;
2851
2852 for (i=0 ; i<256 ; i++)
2853 d_lightstylevalue[i] = 264; // normal light value
2854
2855 // clear out efrags in case the level hasn't been reloaded
2856 // FIXME: is this one short?
2857 for (i=0 ; i<cl.worldmodel->numleafs ; i++)
2858 cl.worldmodel->leafs[i].efrags = NULL;
2859
2860 r_viewleaf = NULL;
2861 R_ClearParticles ();
2862 #ifdef PSET_SCRIPT
2863 PScript_ClearParticles();
2864 #endif
2865 GL_DeleteBModelVertexBuffer();
2866
2867 GL_BuildLightmaps ();
2868 GL_BuildBModelVertexBuffer ();
2869 //ericw -- no longer load alias models into a VBO here, it's done in Mod_LoadAliasModel
2870
2871 r_framecount = 0; //johnfitz -- paranoid?
2872 r_visframecount = 0; //johnfitz -- paranoid?
2873
2874 Sky_NewMap (); //johnfitz -- skybox in worldspawn
2875 Fog_NewMap (); //johnfitz -- global fog in worldspawn
2876 R_ParseWorldspawn (); //ericw -- wateralpha, lavaalpha, telealpha, slimealpha in worldspawn
2877 }
2878
2879 /*
2880 ====================
2881 R_TimeRefresh_f
2882
2883 For program optimization
2884 ====================
2885 */
R_TimeRefresh_f(void)2886 void R_TimeRefresh_f (void)
2887 {
2888 int i;
2889 float start, stop, time;
2890
2891 if (cls.state != ca_connected)
2892 {
2893 Con_Printf("Not connected to a server\n");
2894 return;
2895 }
2896
2897 start = Sys_DoubleTime ();
2898 for (i = 0; i < 128; i++)
2899 {
2900 GL_BeginRendering(&glx, &gly, &glwidth, &glheight);
2901 r_refdef.viewangles[1] = i/128.0*360.0;
2902 R_RenderView ();
2903 GL_EndRendering (false);
2904 }
2905
2906 //glFinish ();
2907 stop = Sys_DoubleTime ();
2908 time = stop-start;
2909 Con_Printf ("%f seconds (%f fps)\n", time, 128/time);
2910 }
2911
R_AllocateVulkanMemory(vulkan_memory_t * memory,VkMemoryAllocateInfo * memory_allocate_info,vulkan_memory_type_t type)2912 void R_AllocateVulkanMemory(vulkan_memory_t * memory, VkMemoryAllocateInfo * memory_allocate_info, vulkan_memory_type_t type)
2913 {
2914 VkResult err = vkAllocateMemory(vulkan_globals.device, memory_allocate_info, NULL, &memory->handle);
2915 if (err != VK_SUCCESS)
2916 Sys_Error("vkAllocateMemory failed");
2917 memory->type = type;
2918 memory->size = memory_allocate_info->allocationSize;
2919 if (memory->type == VULKAN_MEMORY_TYPE_DEVICE)
2920 total_device_vulkan_allocation_size += memory->size;
2921 else if (memory->type == VULKAN_MEMORY_TYPE_HOST)
2922 total_host_vulkan_allocation_size += memory->size;
2923 }
2924
R_FreeVulkanMemory(vulkan_memory_t * memory)2925 void R_FreeVulkanMemory(vulkan_memory_t * memory)
2926 {
2927 if (memory->type == VULKAN_MEMORY_TYPE_DEVICE)
2928 total_device_vulkan_allocation_size -= memory->size;
2929 else if (memory->type == VULKAN_MEMORY_TYPE_HOST)
2930 total_host_vulkan_allocation_size -= memory->size;
2931 vkFreeMemory(vulkan_globals.device, memory->handle, NULL);
2932 memory->handle = VK_NULL_HANDLE;
2933 memory->size = 0;
2934 }
2935
2936 /*
2937 ====================
2938 R_VulkanMemStats_f
2939 ====================
2940 */
R_VulkanMemStats_f(void)2941 void R_VulkanMemStats_f(void)
2942 {
2943 Con_Printf("Vulkan allocations:\n");
2944 Con_Printf(" Tex: %d\n", num_vulkan_tex_allocations);
2945 Con_Printf(" BModel: %d\n", num_vulkan_bmodel_allocations);
2946 Con_Printf(" Mesh: %d\n", num_vulkan_mesh_allocations);
2947 Con_Printf(" Misc: %d\n", num_vulkan_misc_allocations);
2948 Con_Printf(" DynBuf: %d\n", num_vulkan_dynbuf_allocations);
2949 Con_Printf("Descriptors:\n");
2950 Con_Printf(" Combined image samplers: %d\n", num_vulkan_combined_image_samplers );
2951 Con_Printf(" Dynamic UBOs: %d\n", num_vulkan_ubos_dynamic );
2952 Con_Printf(" Input attachments: %d\n", num_vulkan_input_attachments );
2953 Con_Printf(" Storage images: %d\n", num_vulkan_storage_images );
2954 Con_Printf("Device %" SDL_PRIu64 " MiB total\n", (uint64_t)total_device_vulkan_allocation_size / 1024 / 1024);
2955 Con_Printf("Host %" SDL_PRIu64 " MiB total\n", (uint64_t)total_host_vulkan_allocation_size / 1024 / 1024);
2956 }
2957