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, &region);
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