Quake II RTX doxygen  1.0 dev
textures.c File Reference
#include "vkpt.h"
#include "vk_util.h"
#include "refresh/images.h"
#include "device_memory_allocator.h"
#include <assert.h>
#include "../stb/stb_image.h"
#include "../stb/stb_image_resize.h"
#include "../stb/stb_image_write.h"

Go to the source code of this file.

Classes

struct  UnusedResources
 
struct  TextureSystem
 

Macros

#define MAX_RBUFFERS   16
 
#define DESTROY_LATENCY   MAX_FRAMES_IN_FLIGHT * 4
 
#define IMG_DO(_name, _binding, ...)
 
#define IMG_DO(_name, _binding, ...)
 
#define IMG_DO(_name, _binding, _vkformat, _glslformat, _w, _h)
 
#define IMG_DO(_name, _binding, ...)   ATTACH_LABEL_VARIABLE_NAME(qvk.images[VKPT_IMG_##_name], IMAGE, #_name);
 
#define IMG_DO(_name, _binding, ...)   ATTACH_LABEL_VARIABLE_NAME(qvk.images[VKPT_IMG_##_name], IMAGE, #_name);
 
#define IMG_DO(_name, _binding, _vkformat, _glslformat, _w, _h)
 
#define IMG_DO(_name, ...)   ATTACH_LABEL_VARIABLE_NAME(qvk.images_views[VKPT_IMG_##_name], IMAGE_VIEW, #_name);
 
#define IMG_DO(_name, ...)
 
#define IMG_DO(_name, ...)
 
#define IMG_DO(_name, _binding, ...)
 

Typedefs

typedef struct UnusedResources UnusedResources
 
typedef struct TextureSystem TextureSystem
 

Functions

void vkpt_textures_prefetch ()
 
static void textures_destroy_unused_set (uint32_t set_index)
 
void vkpt_textures_destroy_unused ()
 
VkResult vkpt_textures_upload_envmap (int w, int h, byte *data)
 
static VkResult load_blue_noise ()
 
static int get_num_miplevels (int w, int h)
 
static float decode_srgb (byte pix)
 
static byte encode_srgb (float x)
 
static float decode_linear (byte pix)
 
static byte encode_linear (float x)
 
void vkpt_extract_emissive_texture_info (image_t *image)
 
void vkpt_normalize_normal_map (image_t *image)
 
void IMG_Load_RTX (image_t *image, byte *pic)
 
void IMG_Unload_RTX (image_t *image)
 
void IMG_ReloadAll (void)
 
void create_invalid_texture ()
 
void destroy_invalid_texture ()
 
VkResult vkpt_textures_initialize ()
 
static void destroy_tex_images ()
 
VkResult vkpt_textures_destroy ()
 
VkResult vkpt_textures_end_registration ()
 
void vkpt_textures_update_descriptor_set ()
 
static VkResult create_readback_image (VkImage *image, VkDeviceMemory *memory, VkDeviceSize *memory_size, VkFormat format, uint32_t width, uint32_t height)
 
static void destroy_readback_image (VkImage *image, VkDeviceMemory *memory, VkDeviceSize *memory_size)
 
VkResult vkpt_create_images ()
 
VkResult vkpt_destroy_images ()
 

Variables

static TextureSystem texture_system = { 0 }
 
static VkImage tex_images [MAX_RIMAGES] = { 0 }
 
static VkImageView tex_image_views [MAX_RIMAGES] = { 0 }
 
static VkDeviceMemory mem_blue_noise
 
static VkDeviceMemory mem_envmap
 
static VkImage img_blue_noise
 
static VkImageView imv_blue_noise
 
static VkImage img_envmap
 
static VkImageView imv_envmap
 
static VkDescriptorPool desc_pool_textures
 
static VkImage tex_invalid_texture_image = VK_NULL_HANDLE
 
static VkImageView tex_invalid_texture_image_view = VK_NULL_HANDLE
 
static DeviceMemory tex_invalid_texture_image_memory = { 0 }
 
static VkDeviceMemory mem_images [NUM_VKPT_IMAGES]
 
static DeviceMemory tex_image_memory [MAX_RIMAGES] = { 0 }
 
static VkBindImageMemoryInfo tex_bind_image_info [MAX_RIMAGES] = { 0 }
 
static DeviceMemoryAllocatortex_device_memory_allocator = NULL
 
static int image_loading_dirty_flag = 0
 
static uint8_t descriptor_set_dirty_flags [MAX_FRAMES_IN_FLIGHT] = { 0 }
 

Macro Definition Documentation

◆ DESTROY_LATENCY

#define DESTROY_LATENCY   MAX_FRAMES_IN_FLIGHT * 4

Definition at line 44 of file textures.c.

◆ IMG_DO [1/10]

#define IMG_DO (   _name,
  _binding,
  _vkformat,
  _glslformat,
  _w,
  _h 
)
Value:
[VKPT_IMG_##_name] = { \
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, \
.imageType = VK_IMAGE_TYPE_2D, \
.format = VK_FORMAT_##_vkformat, \
.extent = { \
.width = _w, \
.height = _h, \
.depth = 1 \
}, \
.mipLevels = 1, \
.arrayLayers = 1, \
.samples = VK_SAMPLE_COUNT_1_BIT, \
.tiling = VK_IMAGE_TILING_OPTIMAL, \
.usage = VK_IMAGE_USAGE_STORAGE_BIT \
| VK_IMAGE_USAGE_TRANSFER_SRC_BIT \
| VK_IMAGE_USAGE_TRANSFER_DST_BIT \
| VK_IMAGE_USAGE_SAMPLED_BIT \
| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, \
.sharingMode = VK_SHARING_MODE_EXCLUSIVE, \
.queueFamilyIndexCount = qvk.queue_idx_graphics, \
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, \
},

◆ IMG_DO [2/10]

#define IMG_DO (   _name,
  _binding,
  _vkformat,
  _glslformat,
  _w,
  _h 
)
Value:
[VKPT_IMG_##_name] = { \
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, \
.viewType = VK_IMAGE_VIEW_TYPE_2D, \
.format = VK_FORMAT_##_vkformat, \
.image = qvk.images[VKPT_IMG_##_name], \
.subresourceRange = { \
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, \
.baseMipLevel = 0, \
.levelCount = 1, \
.baseArrayLayer = 0, \
.layerCount = 1 \
}, \
.components = { \
VK_COMPONENT_SWIZZLE_R, \
VK_COMPONENT_SWIZZLE_G, \
VK_COMPONENT_SWIZZLE_B, \
VK_COMPONENT_SWIZZLE_A \
}, \
},

◆ IMG_DO [3/10]

#define IMG_DO (   _name,
  _binding,
  ... 
)
Value:
{ \
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, \
.descriptorCount = 1, \
.binding = BINDING_OFFSET_IMAGES + _binding, \
.stageFlags = VK_SHADER_STAGE_ALL, \
},

◆ IMG_DO [4/10]

#define IMG_DO (   _name,
  _binding,
  ... 
)
Value:
{ \
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, \
.descriptorCount = 1, \
.binding = BINDING_OFFSET_TEXTURES + _binding, \
.stageFlags = VK_SHADER_STAGE_ALL, \
},

◆ IMG_DO [5/10]

#define IMG_DO (   _name,
  _binding,
  ... 
)    ATTACH_LABEL_VARIABLE_NAME(qvk.images[VKPT_IMG_##_name], IMAGE, #_name);

◆ IMG_DO [6/10]

#define IMG_DO (   _name,
  _binding,
  ... 
)    ATTACH_LABEL_VARIABLE_NAME(qvk.images[VKPT_IMG_##_name], IMAGE, #_name);

◆ IMG_DO [7/10]

#define IMG_DO (   _name,
  _binding,
  ... 
)
Value:
{ \
VkWriteDescriptorSet elem_image = { \
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, \
.dstBinding = BINDING_OFFSET_IMAGES + _binding, \
.dstArrayElement = 0, \
.descriptorCount = 1, \
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, \
.pImageInfo = desc_output_img_info + VKPT_IMG_##_name, \
}; \
VkWriteDescriptorSet elem_texture = { \
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, \
.dstBinding = BINDING_OFFSET_TEXTURES + _binding, \
.dstArrayElement = 0, \
.descriptorCount = 1, \
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, \
.pImageInfo = img_info + VKPT_IMG_##_name, \
}; \
output_img_write[VKPT_IMG_##_name] = elem_image; \
output_img_write[VKPT_IMG_##_name + NUM_VKPT_IMAGES] = elem_texture; \
}

◆ IMG_DO [8/10]

#define IMG_DO (   _name,
  ... 
)    ATTACH_LABEL_VARIABLE_NAME(qvk.images_views[VKPT_IMG_##_name], IMAGE_VIEW, #_name);

◆ IMG_DO [9/10]

#define IMG_DO (   _name,
  ... 
)
Value:
[VKPT_IMG_##_name] = { \
.sampler = VK_NULL_HANDLE, \
.imageView = qvk.images_views[VKPT_IMG_##_name], \
.imageLayout = VK_IMAGE_LAYOUT_GENERAL \
},

◆ IMG_DO [10/10]

#define IMG_DO (   _name,
  ... 
)
Value:
[VKPT_IMG_##_name] = { \
.imageLayout = VK_IMAGE_LAYOUT_GENERAL, \
.imageView = qvk.images_views[VKPT_IMG_##_name], \
.sampler = qvk.tex_sampler, \
},

◆ MAX_RBUFFERS

#define MAX_RBUFFERS   16

Definition at line 31 of file textures.c.

Typedef Documentation

◆ TextureSystem

typedef struct TextureSystem TextureSystem

◆ UnusedResources

Function Documentation

◆ create_invalid_texture()

void create_invalid_texture ( )

Definition at line 734 of file textures.c.

735 {
736  const VkImageCreateInfo image_create_info = {
737  .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
738  .imageType = VK_IMAGE_TYPE_2D,
739  .format = VK_FORMAT_R8G8B8A8_UNORM,
740  .extent = { 1, 1, 1 },
741  .mipLevels = 1,
742  .arrayLayers = 1,
743  .samples = VK_SAMPLE_COUNT_1_BIT,
744  .tiling = VK_IMAGE_TILING_OPTIMAL,
745  .usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
746  .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
747  .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED
748  };
749  _VK(vkCreateImage(qvk.device, &image_create_info, NULL, &tex_invalid_texture_image));
750 
751  VkMemoryRequirements memory_requirements;
752  vkGetImageMemoryRequirements(qvk.device, tex_invalid_texture_image, &memory_requirements);
753 
754  tex_invalid_texture_image_memory.alignment = memory_requirements.alignment;
755  tex_invalid_texture_image_memory.size = memory_requirements.size;
756  tex_invalid_texture_image_memory.memory_type = get_memory_type(memory_requirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
757 
759 
762 
763  const VkImageSubresourceRange subresource_range = {
764  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
765  .levelCount = 1,
766  .layerCount = 1
767  };
768 
769  const VkImageViewCreateInfo image_view_create_info = {
770  .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
771  .image = tex_invalid_texture_image,
772  .viewType = VK_IMAGE_VIEW_TYPE_2D,
773  .format = image_create_info.format,
774  .subresourceRange = subresource_range
775  };
776 
777  _VK(vkCreateImageView(qvk.device, &image_view_create_info, NULL, &tex_invalid_texture_image_view));
778 
779  VkCommandBuffer cmd_buf = vkpt_begin_command_buffer(&qvk.cmd_buffers_graphics);
780 
781  IMAGE_BARRIER(cmd_buf,
782  .image = tex_invalid_texture_image,
783  .subresourceRange = subresource_range,
784  .srcAccessMask = 0,
785  .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
786  .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
787  .newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
788  );
789 
790  const VkClearColorValue color = {
791  .float32[0] = 1.0f,
792  .float32[1] = 0.0f,
793  .float32[2] = 1.0f,
794  .float32[3] = 1.0f
795  };
796  const VkImageSubresourceRange range = subresource_range;
797  vkCmdClearColorImage(cmd_buf, tex_invalid_texture_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &color, 1, &range);
798 
799  IMAGE_BARRIER(cmd_buf,
800  .image = tex_invalid_texture_image,
801  .subresourceRange = subresource_range,
802  .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
803  .dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
804  .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
805  .newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
806  );
807 
809 
810  vkQueueWaitIdle(qvk.queue_graphics);
811 }

Referenced by vkpt_textures_initialize().

◆ create_readback_image()

static VkResult create_readback_image ( VkImage *  image,
VkDeviceMemory *  memory,
VkDeviceSize *  memory_size,
VkFormat  format,
uint32_t  width,
uint32_t  height 
)
static

Definition at line 1392 of file textures.c.

1393 {
1394  VkImageCreateInfo dump_image_info = {
1395  .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
1396  .imageType = VK_IMAGE_TYPE_2D,
1397  .format = format,
1398  .extent.width = width,
1399  .extent.height = height,
1400  .extent.depth = 1,
1401  .mipLevels = 1,
1402  .arrayLayers = 1,
1403  .samples = VK_SAMPLE_COUNT_1_BIT,
1404  .tiling = VK_IMAGE_TILING_LINEAR,
1405  .usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1406  .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
1407  .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
1408  };
1409 
1410  _VK(vkCreateImage(qvk.device, &dump_image_info, NULL, image));
1411 
1412  VkMemoryRequirements mem_req;
1413  vkGetImageMemoryRequirements(qvk.device, *image, &mem_req);
1414 
1415  VkMemoryAllocateInfo mem_alloc_info = {
1416  .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
1417  .allocationSize = mem_req.size,
1418  .memoryTypeIndex = get_memory_type(mem_req.memoryTypeBits,
1419  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT),
1420  };
1421 
1422  _VK(vkAllocateMemory(qvk.device, &mem_alloc_info, NULL, memory));
1423  _VK(vkBindImageMemory(qvk.device, *image, *memory, 0));
1424 
1425  *memory_size = mem_req.size;
1426 
1427  return VK_SUCCESS;
1428 }

Referenced by vkpt_create_images().

◆ decode_linear()

static float decode_linear ( byte  pix)
inlinestatic

Definition at line 519 of file textures.c.

520 {
521  return (float)pix / 255.f;
522 }

Referenced by vkpt_normalize_normal_map().

◆ decode_srgb()

static float decode_srgb ( byte  pix)
inlinestatic

Definition at line 497 of file textures.c.

498 {
499  float x = (float)pix / 255.f;
500 
501  if (x < 0.04045f)
502  return x / 12.92f;
503 
504  return powf((x + 0.055f) / 1.055f, 2.4f);
505 }

Referenced by vkpt_extract_emissive_texture_info().

◆ destroy_invalid_texture()

void destroy_invalid_texture ( )

Definition at line 813 of file textures.c.

Referenced by vkpt_textures_destroy().

◆ destroy_readback_image()

static void destroy_readback_image ( VkImage *  image,
VkDeviceMemory *  memory,
VkDeviceSize *  memory_size 
)
static

Definition at line 1431 of file textures.c.

1432 {
1433  vkDestroyImage(qvk.device, *image, NULL);
1434  *image = VK_NULL_HANDLE;
1435 
1436  vkFreeMemory(qvk.device, *memory, NULL);
1437  *memory = VK_NULL_HANDLE;
1438  *memory_size = 0;
1439 }

Referenced by vkpt_destroy_images().

◆ destroy_tex_images()

static void destroy_tex_images ( )
static

Definition at line 1024 of file textures.c.

1025 {
1026  for(int i = 0; i < MAX_RIMAGES; i++) {
1027  if(tex_image_views[i]) {
1028  vkDestroyImageView(qvk.device, tex_image_views[i], NULL);
1029  tex_image_views[i] = VK_NULL_HANDLE;
1030  }
1031  if(tex_images[i]) {
1032  vkDestroyImage(qvk.device, tex_images[i], NULL);
1033  tex_images[i] = VK_NULL_HANDLE;
1034 
1036  }
1037  }
1038 
1039  for(uint32_t i = 0; i < DESTROY_LATENCY; i++) {
1041  }
1042 }

Referenced by vkpt_textures_destroy().

◆ encode_linear()

static byte encode_linear ( float  x)
inlinestatic

Definition at line 524 of file textures.c.

525 {
526  x = max(0.f, min(1.f, x));
527 
528  return (byte)roundf(x * 255.f);
529 }

Referenced by vkpt_normalize_normal_map().

◆ encode_srgb()

static byte encode_srgb ( float  x)
inlinestatic

Definition at line 507 of file textures.c.

508 {
509  if (x <= 0.0031308f)
510  x *= 12.92f;
511  else
512  x = 1.055f * powf(x, 1.f / 2.4f) - 0.055f;
513 
514  x = max(0.f, min(1.f, x));
515 
516  return (byte)roundf(x * 255.f);
517 }

◆ get_num_miplevels()

static int get_num_miplevels ( int  w,
int  h 
)
static

Definition at line 485 of file textures.c.

486 {
487  return 1 + log2(MAX(w, h));
488 }

Referenced by vkpt_textures_end_registration().

◆ IMG_Load_RTX()

void IMG_Load_RTX ( image_t image,
byte *  pic 
)

Definition at line 632 of file textures.c.

633 {
634  image->pix_data = pic;
636 }

Referenced by R_RegisterFunctionsRTX().

◆ IMG_ReloadAll()

void IMG_ReloadAll ( void  )

Definition at line 665 of file textures.c.

666 {
667  int i, reloaded=0;
668  image_t * image;
669 
670  for (i = 1, image = r_images + 1; i < r_numImages; i++, image++)
671  {
672  if (!image->registration_sequence)
673  continue;
674 
675  if (image->type == IT_FONT || image->type == IT_PIC)
676  continue;
677 
678  // check if image has been updated since previous load
679 
680  char const * filepath = image->filepath[0] ? image->filepath : image->name;
681 
682  uint64_t last_modifed;
683  if (FS_LastModified(filepath, &last_modifed) != Q_ERR_SUCCESS)
684  {
685  //Com_EPrintf("Could not find '%s' (%s)\n", image->name, image->filepath);
686  continue;
687  }
688 
689  if (last_modifed <= image->last_modified)
690  continue; // skip if file has not been modified since last read
691 
692  // image has been modified : try loading in new_image
693  image_t new_image;
694  if (load_img(filepath, &new_image) == Q_ERR_SUCCESS)
695  {
696  Z_Free(image->pix_data);
697 
698  image->pix_data = new_image.pix_data;
699  image->width = new_image.width;
700  image->height = new_image.width;
701  image->upload_width = new_image.upload_width;
702  image->upload_height = new_image.upload_height;
703  image->processing_complete = qfalse;
704 
705  IMG_Load(image, new_image.pix_data);
706 
707  if (strstr(filepath, "_n."))
708  {
710  }
711 
712  image->last_modified = last_modifed; // reset time stamp because load_img doesn't
713 
714  // destroy Vk ressources to force vkpt_textures_end_registration
715  // to recreate them next time a frame is drawn
716  if (tex_image_views[i]) {
717  vkDestroyImageView(qvk.device, tex_image_views[i], NULL);
718  tex_image_views[i] = VK_NULL_HANDLE;
719  }
720  if (tex_images[i]) {
721  vkDestroyImage(qvk.device, tex_images[i], NULL);
722  tex_images[i] = VK_NULL_HANDLE;
724  }
725  ++reloaded;
726  Com_Printf("Reloaded '%s'\n", image->name);
727  }
728  //else
729  // Com_EPrintf("Skipped '%s'\n", image->name);
730  }
731  Com_Printf("Reloaded %d textures\n", reloaded);
732 }

Referenced by vkpt_reload_textures().

◆ IMG_Unload_RTX()

void IMG_Unload_RTX ( image_t image)

Definition at line 639 of file textures.c.

640 {
641  if(image->pix_data)
642  Z_Free(image->pix_data);
643  image->pix_data = NULL;
644 
645  const uint32_t index = image - r_images;
646 
647  if (tex_images[index])
648  {
649  const uint32_t frame_index = (qvk.frame_counter + MAX_FRAMES_IN_FLIGHT) % DESTROY_LATENCY;
650  UnusedResources* unused_resources = texture_system.unused_resources + frame_index;
651 
652  const uint32_t unused_index = unused_resources->image_num++;
653 
654  unused_resources->images[unused_index] = tex_images[index];
655  unused_resources->image_memory[unused_index] = tex_image_memory[index];
656  unused_resources->image_views[unused_index] = tex_image_views[index];
657 
658  tex_images[index] = VK_NULL_HANDLE;
659  tex_image_views[index] = VK_NULL_HANDLE;
660 
662  }
663 }

Referenced by R_RegisterFunctionsRTX().

◆ load_blue_noise()

static VkResult load_blue_noise ( )
static

Definition at line 308 of file textures.c.

309 {
310  const int num_images = NUM_BLUE_NOISE_TEX / 4;
311  const int res = BLUE_NOISE_RES;
312  size_t img_size = res * res;
313  size_t total_size = img_size * sizeof(uint16_t);
314 
315  BufferResource_t buf_img_upload;
316  buffer_create(&buf_img_upload, total_size * NUM_BLUE_NOISE_TEX, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
317  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
318 
319  uint16_t *bn_tex = (uint16_t *) buffer_map(&buf_img_upload);
320 
321  for(int i = 0; i < num_images; i++) {
322  int w, h, n;
323  char buf[1024];
324 
325  snprintf(buf, sizeof buf, "blue_noise/%d_%d/HDR_RGBA_%04d.png", res, res, i);
326 
327  byte* filedata = 0;
328  uint16_t *data = 0;
329  ssize_t filelen = FS_LoadFile(buf, &filedata);
330 
331  if (filedata) {
332  data = stbi_load_16_from_memory(filedata, filelen, &w, &h, &n, 4);
333  Z_Free(filedata);
334  }
335 
336  if(!data) {
337  Com_EPrintf("error loading blue noise tex %s\n", buf);
338  buffer_unmap(&buf_img_upload);
339  buffer_destroy(&buf_img_upload);
340  return VK_ERROR_INITIALIZATION_FAILED;
341  }
342 
343  /* loaded images are RGBA, want to upload as texture array though */
344  for(int k = 0; k < 4; k++) {
345  for(int j = 0; j < img_size; j++)
346  bn_tex[(i * 4 + k) * img_size + j] = data[j * 4 + k];
347  }
348 
349  stbi_image_free(data);
350  }
351  buffer_unmap(&buf_img_upload);
352  bn_tex = NULL;
353 
354  VkImageCreateInfo img_info = {
355  .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
356  .extent = {
357  .width = BLUE_NOISE_RES,
358  .height = BLUE_NOISE_RES,
359  .depth = 1,
360  },
361  .imageType = VK_IMAGE_TYPE_2D,
362  .format = VK_FORMAT_R16_UNORM,
363  .mipLevels = 1,
364  .arrayLayers = NUM_BLUE_NOISE_TEX,
365  .samples = VK_SAMPLE_COUNT_1_BIT,
366  .tiling = VK_IMAGE_TILING_OPTIMAL,
367  .usage = VK_IMAGE_USAGE_STORAGE_BIT
368  | VK_IMAGE_USAGE_TRANSFER_DST_BIT
369  | VK_IMAGE_USAGE_SAMPLED_BIT,
370  .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
371  .queueFamilyIndexCount = qvk.queue_idx_graphics,
372  .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
373  };
374 
375  _VK(vkCreateImage(qvk.device, &img_info, NULL, &img_blue_noise));
377 
378  VkMemoryRequirements mem_req;
379  vkGetImageMemoryRequirements(qvk.device, img_blue_noise, &mem_req);
380  assert(mem_req.size >= buf_img_upload.size);
381 
383 
384  _VK(vkBindImageMemory(qvk.device, img_blue_noise, mem_blue_noise, 0));
385 
386  VkImageViewCreateInfo img_view_info = {
387  .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
388  .viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY,
389  .format = VK_FORMAT_R16_UNORM,
390  .image = img_blue_noise,
391  .subresourceRange = {
392  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
393  .baseMipLevel = 0,
394  .levelCount = 1,
395  .baseArrayLayer = 0,
396  .layerCount = NUM_BLUE_NOISE_TEX,
397  },
398  .components = {
399  VK_COMPONENT_SWIZZLE_R,
400  VK_COMPONENT_SWIZZLE_R,
401  VK_COMPONENT_SWIZZLE_R,
402  VK_COMPONENT_SWIZZLE_R,
403  },
404  };
405  _VK(vkCreateImageView(qvk.device, &img_view_info, NULL, &imv_blue_noise));
407 
408  VkCommandBuffer cmd_buf = vkpt_begin_command_buffer(&qvk.cmd_buffers_graphics);
409 
410  for(int layer = 0; layer < NUM_BLUE_NOISE_TEX; layer++) {
411 
412  VkImageSubresourceRange subresource_range = {
413  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
414  .baseMipLevel = 0,
415  .levelCount = 1,
416  .baseArrayLayer = layer,
417  .layerCount = 1,
418  };
419 
420  IMAGE_BARRIER(cmd_buf,
421  .image = img_blue_noise,
422  .subresourceRange = subresource_range,
423  .srcAccessMask = 0,
424  .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
425  .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
426  .newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
427  );
428 
429  VkBufferImageCopy cpy_info = {
430  .bufferOffset = total_size * layer,
431  .imageSubresource = {
432  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
433  .mipLevel = 0,
434  .baseArrayLayer = layer,
435  .layerCount = 1,
436  },
437  .imageOffset = { 0, 0, 0 },
438  .imageExtent = { BLUE_NOISE_RES, BLUE_NOISE_RES, 1 }
439  };
440  vkCmdCopyBufferToImage(cmd_buf, buf_img_upload.buffer, img_blue_noise,
441  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cpy_info);
442 
443 
444  IMAGE_BARRIER(cmd_buf,
445  .image = img_blue_noise,
446  .subresourceRange = subresource_range,
447  .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
448  .dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
449  .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
450  .newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
451  );
452  }
453 
455 
456  VkDescriptorImageInfo desc_img_info = {
457  .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
458  .imageView = imv_blue_noise,
459  .sampler = qvk.tex_sampler,
460  };
461 
462  VkWriteDescriptorSet s = {
463  .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
464  .dstSet = qvk.desc_set_textures_even,
465  .dstBinding = BINDING_OFFSET_BLUE_NOISE,
466  .dstArrayElement = 0,
467  .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
468  .descriptorCount = 1,
469  .pImageInfo = &desc_img_info,
470  };
471 
472  vkUpdateDescriptorSets(qvk.device, 1, &s, 0, NULL);
473 
474  s.dstSet = qvk.desc_set_textures_odd;
475  vkUpdateDescriptorSets(qvk.device, 1, &s, 0, NULL);
476 
477  vkQueueWaitIdle(qvk.queue_graphics);
478 
479  buffer_destroy(&buf_img_upload);
480 
481  return VK_SUCCESS;
482 }

Referenced by vkpt_textures_initialize().

◆ textures_destroy_unused_set()

static void textures_destroy_unused_set ( uint32_t  set_index)
static

Definition at line 119 of file textures.c.

120 {
121  UnusedResources* unused_resources = texture_system.unused_resources + set_index;
122 
123  for (uint32_t i = 0; i < unused_resources->image_num; i++)
124  {
125  if (unused_resources->image_views[i] != VK_NULL_HANDLE)
126  vkDestroyImageView(qvk.device, unused_resources->image_views[i], NULL);
127 
128  if(unused_resources->images[i] != VK_NULL_HANDLE)
129  vkDestroyImage(qvk.device, unused_resources->images[i], NULL);
130 
131  if(unused_resources->image_memory[i].memory != VK_NULL_HANDLE)
133  }
134  unused_resources->image_num = 0;
135 
136  for (uint32_t i = 0; i < unused_resources->buffer_num; i++)
137  {
138  vkDestroyBuffer(qvk.device, unused_resources->buffers[i], NULL);
139  vkFreeMemory(qvk.device, unused_resources->buffer_memory[i], NULL);
140  }
141  unused_resources->buffer_num = 0;
142 }

Referenced by destroy_tex_images(), and vkpt_textures_destroy_unused().

◆ vkpt_create_images()

VkResult vkpt_create_images ( )

Definition at line 1442 of file textures.c.

1443 {
1444  VkImageCreateInfo images_create_info[NUM_VKPT_IMAGES] = {
1445 #define IMG_DO(_name, _binding, _vkformat, _glslformat, _w, _h) \
1446  [VKPT_IMG_##_name] = { \
1447  .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, \
1448  .imageType = VK_IMAGE_TYPE_2D, \
1449  .format = VK_FORMAT_##_vkformat, \
1450  .extent = { \
1451  .width = _w, \
1452  .height = _h, \
1453  .depth = 1 \
1454  }, \
1455  .mipLevels = 1, \
1456  .arrayLayers = 1, \
1457  .samples = VK_SAMPLE_COUNT_1_BIT, \
1458  .tiling = VK_IMAGE_TILING_OPTIMAL, \
1459  .usage = VK_IMAGE_USAGE_STORAGE_BIT \
1460  | VK_IMAGE_USAGE_TRANSFER_SRC_BIT \
1461  | VK_IMAGE_USAGE_TRANSFER_DST_BIT \
1462  | VK_IMAGE_USAGE_SAMPLED_BIT \
1463  | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, \
1464  .sharingMode = VK_SHARING_MODE_EXCLUSIVE, \
1465  .queueFamilyIndexCount = qvk.queue_idx_graphics, \
1466  .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, \
1467  },
1470 #undef IMG_DO
1471  };
1472 
1473 #ifdef VKPT_DEVICE_GROUPS
1474 #define IMG_DO(_name, _binding, _vkformat, _glslformat, _w, _h) \
1475  images_create_info[VKPT_IMG_##_name].flags |= \
1476  VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT;
1479 #undef IMG_DO
1480 #endif
1481 
1482  size_t total_size = 0;
1483 
1484  for(int i = 0; i < NUM_VKPT_IMAGES; i++)
1485  {
1486  _VK(vkCreateImage(qvk.device, images_create_info + i, NULL, qvk.images + i));
1487  ATTACH_LABEL_VARIABLE(qvk.images[i], IMAGE);
1488 
1489  VkMemoryRequirements mem_req;
1490  vkGetImageMemoryRequirements(qvk.device, qvk.images[i], &mem_req);
1491 
1492  total_size += align(mem_req.size, mem_req.alignment);
1493 
1494  _VK(allocate_gpu_memory(mem_req, &mem_images[i]));
1495 
1496  ATTACH_LABEL_VARIABLE(mem_images[i], DEVICE_MEMORY);
1497 
1498  _VK(vkBindImageMemory(qvk.device, qvk.images[i], mem_images[i], 0));
1499 
1500 #ifdef VKPT_DEVICE_GROUPS
1501  if (qvk.device_count > 1) {
1502  // create per-device local image bindings so we can copy back and forth
1503 
1504  // create copies of the same image object that will receive full per-GPU mappings
1505  for(int d = 0; d < qvk.device_count; d++)
1506  {
1507  _VK(vkCreateImage(qvk.device, images_create_info + i, NULL, &qvk.images_local[d][i]));
1508  ATTACH_LABEL_VARIABLE(qvk.images_local[d][i], IMAGE);
1509 
1510  uint32_t device_indices[VKPT_MAX_GPUS];
1511 
1512  for (int j = 0; j < VKPT_MAX_GPUS; j++)
1513  {
1514  // all GPUs attach to memory on one device for this image object
1515  device_indices[j] = (uint32_t)d;
1516  }
1517 
1518  // shut up lunarg
1519  {
1520  VkMemoryRequirements mem_req;
1521  vkGetImageMemoryRequirements(qvk.device, qvk.images_local[d][i], &mem_req);
1522  }
1523 
1524  VkBindImageMemoryDeviceGroupInfoKHR device_group_info = {
1525  .sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO_KHR,
1526  .pNext = NULL,
1527  .deviceIndexCount = qvk.device_count,
1528  .pDeviceIndices = device_indices,
1529  .splitInstanceBindRegionCount = 0,
1530  .pSplitInstanceBindRegions = NULL,
1531  };
1532 
1533  VkBindImageMemoryInfoKHR bind_info = {
1534  .sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR,
1535  .pNext = &device_group_info,
1536  .image = qvk.images_local[d][i],
1537  .memory = mem_images[i],
1538  .memoryOffset = 0,
1539  };
1540 
1541  _VK(qvkBindImageMemory2KHR(qvk.device, 1, &bind_info));
1542  }
1543  }
1544 #endif
1545  }
1546 
1547  Com_Printf("Screen-space image memory: %.2f MB\n", (float)total_size / 1048576.f);
1548 
1549  /* attach labels to images */
1550 #define IMG_DO(_name, _binding, ...) \
1551  ATTACH_LABEL_VARIABLE_NAME(qvk.images[VKPT_IMG_##_name], IMAGE, #_name);
1552  LIST_IMAGES
1554 #undef IMG_DO
1555  /* attach labels to images */
1556 #define IMG_DO(_name, _binding, ...) \
1557  ATTACH_LABEL_VARIABLE_NAME(qvk.images[VKPT_IMG_##_name], IMAGE, #_name);
1558  LIST_IMAGES
1560 #undef IMG_DO
1561 
1562 
1563 #define IMG_DO(_name, _binding, _vkformat, _glslformat, _w, _h) \
1564  [VKPT_IMG_##_name] = { \
1565  .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, \
1566  .viewType = VK_IMAGE_VIEW_TYPE_2D, \
1567  .format = VK_FORMAT_##_vkformat, \
1568  .image = qvk.images[VKPT_IMG_##_name], \
1569  .subresourceRange = { \
1570  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, \
1571  .baseMipLevel = 0, \
1572  .levelCount = 1, \
1573  .baseArrayLayer = 0, \
1574  .layerCount = 1 \
1575  }, \
1576  .components = { \
1577  VK_COMPONENT_SWIZZLE_R, \
1578  VK_COMPONENT_SWIZZLE_G, \
1579  VK_COMPONENT_SWIZZLE_B, \
1580  VK_COMPONENT_SWIZZLE_A \
1581  }, \
1582  },
1583 
1584  VkImageViewCreateInfo images_view_create_info[NUM_VKPT_IMAGES] = {
1585  LIST_IMAGES
1587  };
1588 #undef IMG_DO
1589 
1590 
1591  for(int i = 0; i < NUM_VKPT_IMAGES; i++) {
1592  _VK(vkCreateImageView(qvk.device, images_view_create_info + i, NULL, qvk.images_views + i));
1593 
1594 #ifdef VKPT_DEVICE_GROUPS
1595  if (qvk.device_count > 1) {
1596  for(int d = 0; d < qvk.device_count; d++) {
1597  VkImageViewCreateInfo info = images_view_create_info[i];
1598  info.image = qvk.images_local[d][i];
1599  _VK(vkCreateImageView(qvk.device, &info, NULL, &qvk.images_views_local[d][i]));
1600  }
1601  }
1602 #endif
1603  }
1604 
1605  /* attach labels to image views */
1606 #define IMG_DO(_name, ...) \
1607  ATTACH_LABEL_VARIABLE_NAME(qvk.images_views[VKPT_IMG_##_name], IMAGE_VIEW, #_name);
1608  LIST_IMAGES
1610 #undef IMG_DO
1611 
1612 #define IMG_DO(_name, ...) \
1613  [VKPT_IMG_##_name] = { \
1614  .sampler = VK_NULL_HANDLE, \
1615  .imageView = qvk.images_views[VKPT_IMG_##_name], \
1616  .imageLayout = VK_IMAGE_LAYOUT_GENERAL \
1617  },
1618  VkDescriptorImageInfo desc_output_img_info[] = {
1619  LIST_IMAGES
1621  };
1622 #undef IMG_DO
1623 
1624  VkDescriptorImageInfo img_info[] = {
1625 #define IMG_DO(_name, ...) \
1626  [VKPT_IMG_##_name] = { \
1627  .imageLayout = VK_IMAGE_LAYOUT_GENERAL, \
1628  .imageView = qvk.images_views[VKPT_IMG_##_name], \
1629  .sampler = qvk.tex_sampler, \
1630  },
1631 
1632  LIST_IMAGES
1634  };
1635 #undef IMG_DO
1636 
1637  for(int i = VKPT_IMG_BLOOM_HBLUR; i <= VKPT_IMG_BLOOM_VBLUR; i++) {
1638  img_info[i].sampler = qvk.tex_sampler_linear_clamp;
1639  }
1640 
1641  VkWriteDescriptorSet output_img_write[NUM_IMAGES * 2];
1642 
1643  for (int even_odd = 0; even_odd < 2; even_odd++)
1644  {
1645  /* create information to update descriptor sets */
1646 #define IMG_DO(_name, _binding, ...) { \
1647  VkWriteDescriptorSet elem_image = { \
1648  .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, \
1649  .dstSet = even_odd ? qvk.desc_set_textures_odd : qvk.desc_set_textures_even, \
1650  .dstBinding = BINDING_OFFSET_IMAGES + _binding, \
1651  .dstArrayElement = 0, \
1652  .descriptorCount = 1, \
1653  .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, \
1654  .pImageInfo = desc_output_img_info + VKPT_IMG_##_name, \
1655  }; \
1656  VkWriteDescriptorSet elem_texture = { \
1657  .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, \
1658  .dstSet = even_odd ? qvk.desc_set_textures_odd : qvk.desc_set_textures_even, \
1659  .dstBinding = BINDING_OFFSET_TEXTURES + _binding, \
1660  .dstArrayElement = 0, \
1661  .descriptorCount = 1, \
1662  .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, \
1663  .pImageInfo = img_info + VKPT_IMG_##_name, \
1664  }; \
1665  output_img_write[VKPT_IMG_##_name] = elem_image; \
1666  output_img_write[VKPT_IMG_##_name + NUM_VKPT_IMAGES] = elem_texture; \
1667  }
1668  LIST_IMAGES;
1669  if (even_odd)
1670  {
1672  }
1673  else
1674  {
1676  }
1677 #undef IMG_DO
1678 
1679  vkUpdateDescriptorSets(qvk.device, LENGTH(output_img_write), output_img_write, 0, NULL);
1680  }
1681 
1683 #ifdef VKPT_IMAGE_DUMPS
1684  create_readback_image(&qvk.dump_image, &qvk.dump_image_memory, &qvk.dump_image_memory_size, VK_FORMAT_R16G16B16A16_SFLOAT, qvk.extent_screen_images.width, qvk.extent_screen_images.height);
1685 #endif
1686 
1687  VkCommandBuffer cmd_buf = vkpt_begin_command_buffer(&qvk.cmd_buffers_graphics);
1688 
1689  VkImageSubresourceRange subresource_range = {
1690  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
1691  .baseMipLevel = 0,
1692  .levelCount = 1,
1693  .baseArrayLayer = 0,
1694  .layerCount = 1
1695  };
1696 
1697  for (int i = 0; i < NUM_VKPT_IMAGES; i++) {
1698  IMAGE_BARRIER(cmd_buf,
1699  .image = qvk.images[i],
1700  .subresourceRange = subresource_range,
1701  .srcAccessMask = 0,
1702  .dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
1703  .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
1704  .newLayout = VK_IMAGE_LAYOUT_GENERAL,
1705  );
1706 
1707 #ifdef VKPT_DEVICE_GROUPS
1708  if (qvk.device_count > 1) {
1709  for(int d = 0; d < qvk.device_count; d++)
1710  {
1711  set_current_gpu(cmd_buf, d);
1712 
1713  IMAGE_BARRIER(cmd_buf,
1714  .image = qvk.images_local[d][i],
1715  .subresourceRange = subresource_range,
1716  .srcAccessMask = 0,
1717  .dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
1718  .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
1719  .newLayout = VK_IMAGE_LAYOUT_GENERAL
1720  );
1721  }
1722 
1723  set_current_gpu(cmd_buf, ALL_GPUS);
1724  }
1725 #endif
1726 
1727  }
1728 
1729  IMAGE_BARRIER(cmd_buf,
1730  .image = qvk.screenshot_image,
1731  .subresourceRange = subresource_range,
1732  .srcAccessMask = 0,
1733  .dstAccessMask = VK_ACCESS_HOST_READ_BIT,
1734  .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
1735  .newLayout = VK_IMAGE_LAYOUT_GENERAL,
1736  );
1737 
1738 #ifdef VKPT_IMAGE_DUMPS
1739  IMAGE_BARRIER(cmd_buf,
1740  .image = qvk.dump_image,
1741  .subresourceRange = subresource_range,
1742  .srcAccessMask = 0,
1743  .dstAccessMask = VK_ACCESS_HOST_READ_BIT,
1744  .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
1745  .newLayout = VK_IMAGE_LAYOUT_GENERAL,
1746  );
1747 #endif
1748 
1750 
1751  vkQueueWaitIdle(qvk.queue_graphics);
1752 
1753  return VK_SUCCESS;
1754 }

◆ vkpt_destroy_images()

VkResult vkpt_destroy_images ( )

Definition at line 1757 of file textures.c.

1758 {
1759  for(int i = 0; i < NUM_VKPT_IMAGES; i++) {
1760  vkDestroyImageView(qvk.device, qvk.images_views[i], NULL);
1761  vkDestroyImage (qvk.device, qvk.images[i], NULL);
1762 
1763  qvk.images_views[i] = VK_NULL_HANDLE;
1764  qvk.images[i] = VK_NULL_HANDLE;
1765 
1766 #ifdef VKPT_DEVICE_GROUPS
1767  if (qvk.device_count > 1) {
1768  for (int d = 0; d < qvk.device_count; d++)
1769  {
1770  vkDestroyImageView(qvk.device, qvk.images_views_local[d][i], NULL);
1771  vkDestroyImage(qvk.device, qvk.images_local[d][i], NULL);
1772  qvk.images_views_local[d][i] = VK_NULL_HANDLE;
1773  qvk.images_local[d][i] = VK_NULL_HANDLE;
1774  }
1775  }
1776 #endif
1777 
1778  if (mem_images[i])
1779  {
1780  vkFreeMemory(qvk.device, mem_images[i], NULL);
1781  mem_images[i] = VK_NULL_HANDLE;
1782  }
1783  }
1784 
1786 #ifdef VKPT_IMAGE_DUMPS
1787  destroy_readback_image(&qvk.dump_image, &qvk.dump_image_memory, &qvk.dump_image_memory_size);
1788 #endif
1789 
1790  return VK_SUCCESS;
1791 }

◆ vkpt_extract_emissive_texture_info()

void vkpt_extract_emissive_texture_info ( image_t image)

Definition at line 532 of file textures.c.

533 {
534  int w = image->upload_width;
535  int h = image->upload_height;
536 
537  byte* current_pixel = image->pix_data;
538  vec3_t emissive_color;
539  VectorClear(emissive_color);
540 
541  int min_x = w;
542  int max_x = -1;
543  int min_y = h;
544  int max_y = -1;
545 
546  for (int y = 0; y < h; y++) {
547  for (int x = 0; x < w; x++) {
548  if(current_pixel[0] + current_pixel[1] + current_pixel[2] > 0)
549  {
550  vec3_t color;
551  color[0] = decode_srgb(current_pixel[0]);
552  color[1] = decode_srgb(current_pixel[1]);
553  color[2] = decode_srgb(current_pixel[2]);
554 
555  color[0] = max(0.f, color[0] + EMISSIVE_TRANSFORM_BIAS);
556  color[1] = max(0.f, color[1] + EMISSIVE_TRANSFORM_BIAS);
557  color[2] = max(0.f, color[2] + EMISSIVE_TRANSFORM_BIAS);
558 
559  VectorAdd(emissive_color, color, emissive_color);
560 
561  min_x = min(min_x, x);
562  min_y = min(min_y, y);
563  max_x = max(max_x, x);
564  max_y = max(max_y, y);
565  }
566 
567  current_pixel += 4;
568  }
569  }
570 
571  if (min_x <= max_x && min_y <= max_y)
572  {
573  float normalization = 1.f / (float)((max_x - min_x + 1) * (max_y - min_y + 1));
574  VectorScale(emissive_color, normalization, image->light_color);
575  }
576  else
577  {
578  VectorSet(image->light_color, 0.f, 0.f, 0.f);
579  }
580 
581  image->min_light_texcoord[0] = (float)min_x / (float)w;
582  image->min_light_texcoord[1] = (float)min_y / (float)h;
583  image->max_light_texcoord[0] = (float)(max_x + 1) / (float)w;
584  image->max_light_texcoord[1] = (float)(max_y + 1) / (float)h;
585 
586  image->entire_texture_emissive = (min_x == 0) && (min_y == 0) && (max_x == w - 1) && (max_y == h - 1);
587 
588  image->processing_complete = qtrue;
589 }

Referenced by bsp_mesh_register_textures().

◆ vkpt_normalize_normal_map()

void vkpt_normalize_normal_map ( image_t image)

Definition at line 592 of file textures.c.

593 {
594  int w = image->upload_width;
595  int h = image->upload_height;
596 
597  byte* current_pixel = image->pix_data;
598 
599  for (int y = 0; y < h; y++) {
600  for (int x = 0; x < w; x++)
601  {
602  vec3_t color;
603  color[0] = decode_linear(current_pixel[0]);
604  color[1] = decode_linear(current_pixel[1]);
605  color[2] = decode_linear(current_pixel[2]);
606 
607  color[0] = color[0] * 2.f - 1.f;
608  color[1] = color[1] * 2.f - 1.f;
609 
610  if (VectorNormalize(color) == 0.f)
611  {
612  color[0] = 0.f;
613  color[1] = 0.f;
614  color[2] = 1.f;
615  }
616 
617  color[0] = color[0] * 0.5f + 0.5f;
618  color[1] = color[1] * 0.5f + 0.5f;
619 
620  current_pixel[0] = encode_linear(color[0]);
621  current_pixel[1] = encode_linear(color[1]);
622  current_pixel[2] = encode_linear(color[2]);
623 
624  current_pixel += 4;
625  }
626  }
627 
628  image->processing_complete = qtrue;
629 }

Referenced by bsp_mesh_register_textures(), and IMG_ReloadAll().

◆ vkpt_textures_destroy()

VkResult vkpt_textures_destroy ( )

Definition at line 1045 of file textures.c.

1046 {
1048  vkDestroyDescriptorSetLayout(qvk.device, qvk.desc_set_layout_textures, NULL);
1049  vkDestroyDescriptorPool(qvk.device, desc_pool_textures, NULL);
1050 
1051  vkFreeMemory (qvk.device, mem_blue_noise, NULL);
1052  vkDestroyImage (qvk.device, img_blue_noise, NULL);
1053  vkDestroyImageView(qvk.device, imv_blue_noise, NULL);
1054  vkDestroySampler (qvk.device, qvk.tex_sampler, NULL);
1055  vkDestroySampler (qvk.device, qvk.tex_sampler_nearest, NULL);
1056  vkDestroySampler (qvk.device, qvk.tex_sampler_linear_clamp, NULL);
1057 
1058  if(imv_envmap != VK_NULL_HANDLE) {
1059  vkDestroyImageView(qvk.device, imv_envmap, NULL);
1060  imv_envmap = NULL;
1061  }
1062  if(img_envmap != VK_NULL_HANDLE) {
1063  vkDestroyImage(qvk.device, img_envmap, NULL);
1064  img_envmap = NULL;
1065  }
1066  if (mem_envmap != VK_NULL_HANDLE) {
1067  vkFreeMemory(qvk.device, mem_envmap, NULL);
1068  mem_envmap = VK_NULL_HANDLE;
1069  }
1070 
1074 
1075  LOG_FUNC();
1076  return VK_SUCCESS;
1077 }

◆ vkpt_textures_destroy_unused()

void vkpt_textures_destroy_unused ( )

Definition at line 144 of file textures.c.

Referenced by R_BeginFrame_RTX(), and R_Shutdown_RTX().

◆ vkpt_textures_end_registration()

VkResult vkpt_textures_end_registration ( )

Definition at line 1087 of file textures.c.

1088 {
1090  return VK_SUCCESS;
1092 
1093  VkImageCreateInfo img_info = {
1094  .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
1095  .extent = {
1096  .width = 1337,
1097  .height = 1337,
1098  .depth = 1
1099  },
1100  .imageType = VK_IMAGE_TYPE_2D,
1101  .format = VK_FORMAT_UNDEFINED,
1102  .mipLevels = 1,
1103  .arrayLayers = 1,
1104  .samples = VK_SAMPLE_COUNT_1_BIT,
1105  .tiling = VK_IMAGE_TILING_OPTIMAL,
1106  .usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT
1107  | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
1108  | VK_IMAGE_USAGE_SAMPLED_BIT,
1109  .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
1110  .queueFamilyIndexCount = qvk.queue_idx_graphics,
1111  .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
1112  };
1113 
1114  VkImageViewCreateInfo img_view_info = {
1115  .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1116  .viewType = VK_IMAGE_VIEW_TYPE_2D,
1117  .format = VK_FORMAT_UNDEFINED,
1118  .subresourceRange = {
1119  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
1120  .baseMipLevel = 0,
1121  .levelCount = 1,
1122  .baseArrayLayer = 0,
1123  .layerCount = 1
1124  },
1125  .components = {
1126  VK_COMPONENT_SWIZZLE_R,
1127  VK_COMPONENT_SWIZZLE_G,
1128  VK_COMPONENT_SWIZZLE_B,
1129  VK_COMPONENT_SWIZZLE_A
1130  },
1131  };
1132 
1133 #ifdef VKPT_DEVICE_GROUPS
1134  if (qvk.device_count > 1) {
1135  mem_alloc_flags_broadcast.deviceMask = (1 << qvk.device_count) - 1;
1136  }
1137 #endif
1138 
1139  uint32_t new_image_num = 0;
1140  size_t total_size = 0;
1141  for(int i = 0; i < MAX_RIMAGES; i++) {
1142  image_t *q_img = r_images + i;
1143 
1144  if (tex_images[i] != VK_NULL_HANDLE || !q_img->registration_sequence || q_img->pix_data == NULL)
1145  continue;
1146 
1147  img_info.extent.width = q_img->upload_width;
1148  img_info.extent.height = q_img->upload_height;
1149  img_info.mipLevels = get_num_miplevels(q_img->upload_width, q_img->upload_height);
1150  img_info.format = q_img->is_srgb ? VK_FORMAT_R8G8B8A8_SRGB : VK_FORMAT_R8G8B8A8_UNORM;
1151 
1152  _VK(vkCreateImage(qvk.device, &img_info, NULL, tex_images + i));
1153  ATTACH_LABEL_VARIABLE(tex_images[i], IMAGE);
1154 
1155  VkMemoryRequirements mem_req;
1156  vkGetImageMemoryRequirements(qvk.device, tex_images[i], &mem_req);
1157 
1158  assert(!(mem_req.alignment & (mem_req.alignment - 1)));
1159  total_size += mem_req.alignment - 1;
1160  total_size &= ~(mem_req.alignment - 1);
1161  total_size += mem_req.size;
1162 
1163  DeviceMemory* image_memory = tex_image_memory + i;
1164  image_memory->size = mem_req.size;
1165  image_memory->alignment = mem_req.alignment;
1166  image_memory->memory_type = get_memory_type(mem_req.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
1167 
1169 
1170  VkBindImageMemoryInfo* bind_info = tex_bind_image_info + new_image_num;
1171  bind_info->sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
1172  bind_info->image = tex_images[i];
1173  bind_info->memory = image_memory->memory;
1174  bind_info->memoryOffset = image_memory->memory_offset;
1175 
1176  new_image_num++;
1177  }
1178 
1179  if (new_image_num == 0)
1180  return VK_SUCCESS;
1181  vkBindImageMemory2(qvk.device, new_image_num, tex_bind_image_info);
1182 
1183  BufferResource_t buf_img_upload;
1184  buffer_create(&buf_img_upload, total_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
1185  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
1186 
1187  VkCommandBuffer cmd_buf = vkpt_begin_command_buffer(&qvk.cmd_buffers_graphics);
1188 
1189  char *staging_buffer = buffer_map(&buf_img_upload);
1190 
1191  size_t offset = 0;
1192  for(int i = 0; i < MAX_RIMAGES; i++) {
1193  image_t *q_img = r_images + i;
1194 
1195  if (tex_images[i] == VK_NULL_HANDLE || tex_image_views[i] != VK_NULL_HANDLE)
1196  continue;
1197 
1198  int num_mip_levels = get_num_miplevels(q_img->upload_width, q_img->upload_height);
1199 
1200  VkMemoryRequirements mem_req;
1201  vkGetImageMemoryRequirements(qvk.device, tex_images[i], &mem_req);
1202 
1203  assert(!(mem_req.alignment & (mem_req.alignment - 1)));
1204  offset += mem_req.alignment - 1;
1205  offset &= ~(mem_req.alignment - 1);
1206 
1207  uint32_t wd = q_img->upload_width;
1208  uint32_t ht = q_img->upload_height;
1209 
1210  VkImageSubresourceRange subresource_range = {
1211  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
1212  .baseMipLevel = 0,
1213  .levelCount = num_mip_levels,
1214  .baseArrayLayer = 0,
1215  .layerCount = 1
1216  };
1217 
1218  IMAGE_BARRIER(cmd_buf,
1219  .image = tex_images[i],
1220  .subresourceRange = subresource_range,
1221  .srcAccessMask = 0,
1222  .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
1223  .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
1224  .newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
1225  );
1226 
1227  {
1228  memcpy(staging_buffer + offset, q_img->pix_data, wd * ht * 4);
1229 
1230  VkBufferImageCopy cpy_info = {
1231  .bufferOffset = offset,
1232  .imageSubresource = {
1233  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
1234  .mipLevel = 0,
1235  .baseArrayLayer = 0,
1236  .layerCount = 1,
1237  },
1238  .imageOffset = { 0, 0, 0 },
1239  .imageExtent = { wd, ht, 1 }
1240  };
1241 
1242  vkCmdCopyBufferToImage(cmd_buf, buf_img_upload.buffer, tex_images[i],
1243  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cpy_info);
1244  }
1245 
1246  subresource_range.levelCount = 1;
1247 
1248  for (int mip = 1; mip < num_mip_levels; mip++)
1249  {
1250  subresource_range.baseMipLevel = mip - 1;
1251 
1252  IMAGE_BARRIER(cmd_buf,
1253  .image = tex_images[i],
1254  .subresourceRange = subresource_range,
1255  .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
1256  .dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
1257  .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1258  .newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1259  );
1260 
1261  int nwd = (wd > 1) ? (wd >> 1) : wd;
1262  int nht = (ht > 1) ? (ht >> 1) : ht;
1263 
1264  VkImageBlit region = {
1265  .srcSubresource = {
1266  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
1267  .mipLevel = mip - 1,
1268  .baseArrayLayer = 0,
1269  .layerCount = 1
1270  },
1271  .srcOffsets = {
1272  { 0, 0, 0 },
1273  { wd, ht, 1 } },
1274 
1275  .dstSubresource = {
1276  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
1277  .mipLevel = mip,
1278  .baseArrayLayer = 0,
1279  .layerCount = 1
1280  },
1281  .dstOffsets = {
1282  { 0, 0, 0 },
1283  { nwd, nht, 1 } }
1284  };
1285 
1286  vkCmdBlitImage(
1287  cmd_buf,
1288  tex_images[i], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1289  tex_images[i], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1290  1, &region,
1291  VK_FILTER_LINEAR);
1292 
1293  subresource_range.baseMipLevel = mip - 1;
1294 
1295  IMAGE_BARRIER(cmd_buf,
1296  .image = tex_images[i],
1297  .subresourceRange = subresource_range,
1298  .srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
1299  .dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
1300  .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1301  .newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
1302  );
1303 
1304  wd = nwd;
1305  ht = nht;
1306  }
1307 
1308  subresource_range.baseMipLevel = num_mip_levels - 1;
1309 
1310  IMAGE_BARRIER(cmd_buf,
1311  .image = tex_images[i],
1312  .subresourceRange = subresource_range,
1313  .srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
1314  .dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
1315  .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1316  .newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
1317  );
1318 
1319  img_view_info.image = tex_images[i];
1320  img_view_info.subresourceRange.levelCount = num_mip_levels;
1321  img_view_info.format = q_img->is_srgb ? VK_FORMAT_R8G8B8A8_SRGB : VK_FORMAT_R8G8B8A8_UNORM;
1322  _VK(vkCreateImageView(qvk.device, &img_view_info, NULL, tex_image_views + i));
1323  ATTACH_LABEL_VARIABLE(tex_image_views[i], IMAGE_VIEW);
1324 
1325  offset += mem_req.size;
1326  }
1327 
1328  buffer_unmap(&buf_img_upload);
1329  staging_buffer = NULL;
1330 
1332 
1333 
1334  const uint32_t destroy_frame_index = (qvk.frame_counter + MAX_FRAMES_IN_FLIGHT) % DESTROY_LATENCY;
1335  UnusedResources* unused_resources = texture_system.unused_resources + destroy_frame_index;
1336 
1337  const uint32_t unused_index = unused_resources->buffer_num++;
1338  unused_resources->buffers[unused_index] = buf_img_upload.buffer;
1339  unused_resources->buffer_memory[unused_index] = buf_img_upload.memory;
1340 
1342 
1343  return VK_SUCCESS;
1344 }

Referenced by R_BeginFrame_RTX().

◆ vkpt_textures_initialize()

VkResult vkpt_textures_initialize ( )

Definition at line 821 of file textures.c.

822 {
824  memset(&texture_system, 0, sizeof(texture_system));
825 
827 
829 
830  VkSamplerCreateInfo sampler_info = {
831  .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
832  .magFilter = VK_FILTER_LINEAR,
833  .minFilter = VK_FILTER_LINEAR,
834  .addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT,
835  .addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT,
836  .addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT,
837  .anisotropyEnable = VK_TRUE,
838  .maxAnisotropy = 16,
839  .borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK,
840  .unnormalizedCoordinates = VK_FALSE,
841  .mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR,
842  .minLod = 0.0f,
843  .maxLod = 128.0f,
844  };
845  _VK(vkCreateSampler(qvk.device, &sampler_info, NULL, &qvk.tex_sampler));
847  VkSamplerCreateInfo sampler_nearest_info = {
848  .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
849  .magFilter = VK_FILTER_NEAREST,
850  .minFilter = VK_FILTER_NEAREST,
851  .addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT,
852  .addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT,
853  .addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT,
854  .anisotropyEnable = VK_FALSE,
855  .maxAnisotropy = 16,
856  .borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK,
857  .unnormalizedCoordinates = VK_FALSE,
858  .mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST,
859  };
860  _VK(vkCreateSampler(qvk.device, &sampler_nearest_info, NULL, &qvk.tex_sampler_nearest));
862 
863  VkSamplerCreateInfo sampler_linear_clamp_info = {
864  .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
865  .magFilter = VK_FILTER_LINEAR,
866  .minFilter = VK_FILTER_LINEAR,
867  .addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
868  .addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
869  .addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
870  .anisotropyEnable = VK_FALSE,
871  .maxAnisotropy = 16,
872  .borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK,
873  .unnormalizedCoordinates = VK_FALSE,
874  .mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR,
875  };
876  _VK(vkCreateSampler(qvk.device, &sampler_linear_clamp_info, NULL, &qvk.tex_sampler_linear_clamp));
878 
879  VkDescriptorSetLayoutBinding layout_bindings[] = {
880  {
881  .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
882  .descriptorCount = MAX_RIMAGES,
883  .binding = 0,
884  .stageFlags = VK_SHADER_STAGE_ALL,
885  },
886 #define IMG_DO(_name, _binding, ...) \
887  { \
888  .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, \
889  .descriptorCount = 1, \
890  .binding = BINDING_OFFSET_IMAGES + _binding, \
891  .stageFlags = VK_SHADER_STAGE_ALL, \
892  },
895 #undef IMG_DO
896 #define IMG_DO(_name, _binding, ...) \
897  { \
898  .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, \
899  .descriptorCount = 1, \
900  .binding = BINDING_OFFSET_TEXTURES + _binding, \
901  .stageFlags = VK_SHADER_STAGE_ALL, \
902  },
905 #undef IMG_DO
906  {
907  .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
908  .descriptorCount = 1,
909  .binding = BINDING_OFFSET_BLUE_NOISE,
910  .stageFlags = VK_SHADER_STAGE_ALL,
911  },
912  {
913  .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
914  .descriptorCount = 1,
915  .binding = BINDING_OFFSET_ENVMAP,
916  .stageFlags = VK_SHADER_STAGE_ALL,
917  },
918  {
919  .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
920  .descriptorCount = 1,
921  .binding = BINDING_OFFSET_PHYSICAL_SKY,
922  .stageFlags = VK_SHADER_STAGE_ALL,
923  },
924  {
925  .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
926  .descriptorCount = 1,
928  .stageFlags = VK_SHADER_STAGE_ALL,
929  },
930  {
931  .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
932  .descriptorCount = 1,
934  .stageFlags = VK_SHADER_STAGE_ALL,
935  },
936  {
937  .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
938  .descriptorCount = 1,
940  .stageFlags = VK_SHADER_STAGE_ALL,
941  },
942  {
943  .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
944  .descriptorCount = 1,
946  .stageFlags = VK_SHADER_STAGE_ALL,
947  },
948  {
949  .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
950  .descriptorCount = 1,
951  .binding = BINDING_OFFSET_SKY_CLOUDS,
952  .stageFlags = VK_SHADER_STAGE_ALL,
953  },
954  {
955  .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
956  .descriptorCount = 1,
958  .stageFlags = VK_SHADER_STAGE_ALL,
959  },
960  {
961  .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
962  .descriptorCount = 1,
964  .stageFlags = VK_SHADER_STAGE_ALL,
965  },
966  {
967  .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
968  .descriptorCount = 1,
969  .binding = BINDING_OFFSET_TERRAIN_DEPTH,
970  .stageFlags = VK_SHADER_STAGE_ALL,
971  },
972  {
973  .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
974  .descriptorCount = 1,
976  .stageFlags = VK_SHADER_STAGE_ALL,
977  }
978  };
979 
980  VkDescriptorSetLayoutCreateInfo layout_info = {
981  .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
982  .bindingCount = LENGTH(layout_bindings),
983  .pBindings = layout_bindings,
984  };
985 
986  _VK(vkCreateDescriptorSetLayout(qvk.device, &layout_info, NULL, &qvk.desc_set_layout_textures));
987  ATTACH_LABEL_VARIABLE(qvk.desc_set_layout_textures, DESCRIPTOR_SET_LAYOUT);
988  VkDescriptorPoolSize pool_size = {
989  .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
990  .descriptorCount = MAX_RIMAGES + 2 * NUM_VKPT_IMAGES + 128,
991  };
992 
993  VkDescriptorPoolCreateInfo pool_info = {
994  .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
995  .poolSizeCount = 1,
996  .pPoolSizes = &pool_size,
997  .maxSets = 2,
998  };
999 
1000  _VK(vkCreateDescriptorPool(qvk.device, &pool_info, NULL, &desc_pool_textures));
1001  ATTACH_LABEL_VARIABLE(desc_pool_textures, DESCRIPTOR_POOL);
1002 
1003  VkDescriptorSetAllocateInfo descriptor_set_alloc_info = {
1004  .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1005  .descriptorPool = desc_pool_textures,
1006  .descriptorSetCount = 1,
1007  .pSetLayouts = &qvk.desc_set_layout_textures,
1008  };
1009 
1010  _VK(vkAllocateDescriptorSets(qvk.device, &descriptor_set_alloc_info, &qvk.desc_set_textures_even));
1011  _VK(vkAllocateDescriptorSets(qvk.device, &descriptor_set_alloc_info, &qvk.desc_set_textures_odd));
1012 
1015 
1016  if(load_blue_noise() != VK_SUCCESS)
1017  return VK_ERROR_INITIALIZATION_FAILED;
1018 
1019  LOG_FUNC();
1020  return VK_SUCCESS;
1021 }

◆ vkpt_textures_prefetch()

void vkpt_textures_prefetch ( )

Definition at line 75 of file textures.c.

76 {
77  byte* buffer = NULL;
78  ssize_t buffer_size = 0;
79  char const * filename = "prefetch.txt";
80  buffer_size = FS_LoadFile(filename, (void**)&buffer);
81  if (buffer == NULL)
82  {
83  Com_EPrintf("Can't load '%s'\n", filename);
84  return;
85  }
86 
87  char const * ptr = buffer;
88  char linebuf[MAX_QPATH];
89  while (sgets(linebuf, sizeof(linebuf), &ptr))
90  {
91  char* line = strtok(linebuf, " \t\r\n");
92  if (!line)
93  continue;
94 
95  image_t const * img1 = IMG_Find(line, IT_SKIN, IF_PERMANENT | IF_SRGB);
96 
97  char other_name[MAX_QPATH];
98 
99  // attempt loading a matching normal map
100  if (!Q_strlcpy(other_name, line, strlen(line) - 3))
101  continue;
102  Q_concat(other_name, sizeof(other_name), other_name, "_n.tga", NULL);
103  FS_NormalizePath(other_name, other_name);
104  image_t const * img2 = IMG_Find(other_name, IT_SKIN, IF_PERMANENT);
105  /* if (img2 != R_NOTEXTURE)
106  Com_Printf("Prefetched '%s' (%d)\n", other_name, (int)(img2 - r_images)); */
107 
108  // attempt loading a matching emissive map
109  if (!Q_strlcpy(other_name, line, strlen(line) - 3))
110  continue;
111  Q_concat(other_name, sizeof(other_name), other_name, "_light.tga", NULL);
112  FS_NormalizePath(other_name, other_name);
113  image_t const * img3 = IMG_Find(other_name, IT_SKIN, IF_PERMANENT | IF_SRGB);
114  }
115  // Com_Printf("Loaded '%s'\n", filename);
116  FS_FreeFile(buffer);
117 }

Referenced by vkpt_initialize_all().

◆ vkpt_textures_update_descriptor_set()

void vkpt_textures_update_descriptor_set ( )

Definition at line 1346 of file textures.c.

1347 {
1349  return;
1350 
1352 
1353  for(int i = 0; i < MAX_RIMAGES; i++) {
1354  image_t *q_img = r_images + i;
1355 
1356  VkImageView image_view = tex_image_views[i];
1357  if (image_view == VK_NULL_HANDLE)
1358  image_view = tex_invalid_texture_image_view;
1359 
1360  VkSampler sampler = qvk.tex_sampler;
1361  if (!strcmp(q_img->name, "pics/conchars.pcx") || !strcmp(q_img->name, "pics/ch1.pcx"))
1362  sampler = qvk.tex_sampler_nearest;
1363  else if (q_img->type == IT_SPRITE)
1364  sampler = qvk.tex_sampler_linear_clamp;
1365 
1366  VkDescriptorImageInfo img_info = {
1367  .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
1368  .imageView = image_view,
1369  .sampler = sampler,
1370  };
1371 
1372  if (i >= VKPT_IMG_BLOOM_HBLUR &&
1373  i <= VKPT_IMG_BLOOM_VBLUR) {
1374  img_info.sampler = qvk.tex_sampler_linear_clamp;
1375  }
1376 
1377  VkWriteDescriptorSet descriptor_set_write = {
1378  .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1381  .dstArrayElement = i,
1382  .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
1383  .descriptorCount = 1,
1384  .pImageInfo = &img_info,
1385  };
1386 
1387  vkUpdateDescriptorSets(qvk.device, 1, &descriptor_set_write, 0, NULL);
1388  }
1389 }

Referenced by R_BeginFrame_RTX().

◆ vkpt_textures_upload_envmap()

VkResult vkpt_textures_upload_envmap ( int  w,
int  h,
byte *  data 
)

Definition at line 150 of file textures.c.

151 {
152  vkDeviceWaitIdle(qvk.device);
153  if(imv_envmap != VK_NULL_HANDLE) {
154  vkDestroyImageView(qvk.device, imv_envmap, NULL);
155  imv_envmap = NULL;
156  }
157  if(img_envmap != VK_NULL_HANDLE) {
158  vkDestroyImage(qvk.device, img_envmap, NULL);
159  img_envmap = NULL;
160  }
161 
162  const int num_images = 6;
163  size_t img_size = w * h * 4;
164 
165  BufferResource_t buf_img_upload;
166  buffer_create(&buf_img_upload, img_size * num_images, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
167  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
168 
169  byte *envmap = (byte *) buffer_map(&buf_img_upload);
170  memcpy(envmap, data, img_size * num_images);
171  buffer_unmap(&buf_img_upload);
172  envmap = NULL;
173 
174  VkImageCreateInfo img_info = {
175  .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
176  .extent = {
177  .width = w,
178  .height = h,
179  .depth = 1,
180  },
181  .imageType = VK_IMAGE_TYPE_2D,
182  .format = VK_FORMAT_R8G8B8A8_UNORM,
183  .mipLevels = 1,
184  .arrayLayers = num_images,
185  .samples = VK_SAMPLE_COUNT_1_BIT,
186  .tiling = VK_IMAGE_TILING_OPTIMAL,
187  .usage = VK_IMAGE_USAGE_STORAGE_BIT
188  | VK_IMAGE_USAGE_TRANSFER_DST_BIT
189  | VK_IMAGE_USAGE_SAMPLED_BIT,
190  .flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT,
191  .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
192  .queueFamilyIndexCount = qvk.queue_idx_graphics,
193  .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
194  };
195 
196  _VK(vkCreateImage(qvk.device, &img_info, NULL, &img_envmap));
198 
199  VkMemoryRequirements mem_req;
200  vkGetImageMemoryRequirements(qvk.device, img_envmap, &mem_req);
201  assert(mem_req.size >= buf_img_upload.size);
202 
203  _VK(allocate_gpu_memory(mem_req, &mem_envmap));
204 
205  _VK(vkBindImageMemory(qvk.device, img_envmap, mem_envmap, 0));
206 
207  VkImageViewCreateInfo img_view_info = {
208  .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
209  .viewType = VK_IMAGE_VIEW_TYPE_CUBE,
210  .format = VK_FORMAT_R8G8B8A8_UNORM,
211  .image = img_envmap,
212  .subresourceRange = {
213  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
214  .baseMipLevel = 0,
215  .levelCount = 1,
216  .baseArrayLayer = 0,
217  .layerCount = num_images,
218  },
219  .components = {
220  VK_COMPONENT_SWIZZLE_R,
221  VK_COMPONENT_SWIZZLE_G,
222  VK_COMPONENT_SWIZZLE_B,
223  VK_COMPONENT_SWIZZLE_A,
224  },
225  };
226  _VK(vkCreateImageView(qvk.device, &img_view_info, NULL, &imv_envmap));
227  ATTACH_LABEL_VARIABLE(imv_envmap, IMAGE_VIEW);
228 
229  VkCommandBuffer cmd_buf = vkpt_begin_command_buffer(&qvk.cmd_buffers_graphics);
230 
231  for(int layer = 0; layer < num_images; layer++) {
232 
233  VkImageSubresourceRange subresource_range = {
234  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
235  .baseMipLevel = 0,
236  .levelCount = 1,
237  .baseArrayLayer = layer,
238  .layerCount = 1,
239  };
240 
241  IMAGE_BARRIER(cmd_buf,
242  .image = img_envmap,
243  .subresourceRange = subresource_range,
244  .srcAccessMask = 0,
245  .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
246  .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
247  .newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
248  );
249 
250  VkBufferImageCopy cpy_info = {
251  .bufferOffset = img_size * layer,
252  .imageSubresource = {
253  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
254  .mipLevel = 0,
255  .baseArrayLayer = layer,
256  .layerCount = 1,
257  },
258  .imageOffset = { 0, 0, 0 },
259  .imageExtent = { w, h, 1 }
260  };
261  vkCmdCopyBufferToImage(cmd_buf, buf_img_upload.buffer, img_envmap,
262  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cpy_info);
263 
264 
265  IMAGE_BARRIER(cmd_buf,
266  .image = img_envmap,
267  .subresourceRange = subresource_range,
268  .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
269  .dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
270  .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
271  .newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
272  );
273  }
274 
276 
277  {
278  VkDescriptorImageInfo desc_img_info = {
279  .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
280  .imageView = imv_envmap,
281  .sampler = qvk.tex_sampler,
282  };
283 
284  VkWriteDescriptorSet s = {
285  .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
286  .dstSet = qvk.desc_set_textures_even,
287  .dstBinding = BINDING_OFFSET_ENVMAP,
288  .dstArrayElement = 0,
289  .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
290  .descriptorCount = 1,
291  .pImageInfo = &desc_img_info,
292  };
293 
294  vkUpdateDescriptorSets(qvk.device, 1, &s, 0, NULL);
295 
296  s.dstSet = qvk.desc_set_textures_odd;
297  vkUpdateDescriptorSets(qvk.device, 1, &s, 0, NULL);
298  }
299 
300  vkQueueWaitIdle(qvk.queue_graphics);
301 
302  buffer_destroy(&buf_img_upload);
303 
304  return VK_SUCCESS;
305 }

Referenced by R_SetSky_RTX().

Variable Documentation

◆ desc_pool_textures

VkDescriptorPool desc_pool_textures
static

Definition at line 60 of file textures.c.

Referenced by vkpt_textures_destroy(), and vkpt_textures_initialize().

◆ descriptor_set_dirty_flags

uint8_t descriptor_set_dirty_flags[MAX_FRAMES_IN_FLIGHT] = { 0 }
static

◆ image_loading_dirty_flag

int image_loading_dirty_flag = 0
static

Definition at line 72 of file textures.c.

Referenced by IMG_Load_RTX(), and vkpt_textures_end_registration().

◆ img_blue_noise

VkImage img_blue_noise
static

Definition at line 56 of file textures.c.

Referenced by load_blue_noise(), and vkpt_textures_destroy().

◆ img_envmap

VkImage img_envmap
static

Definition at line 58 of file textures.c.

Referenced by vkpt_textures_destroy(), and vkpt_textures_upload_envmap().

◆ imv_blue_noise

VkImageView imv_blue_noise
static

Definition at line 57 of file textures.c.

Referenced by load_blue_noise(), and vkpt_textures_destroy().

◆ imv_envmap

VkImageView imv_envmap
static

Definition at line 59 of file textures.c.

Referenced by vkpt_textures_destroy(), and vkpt_textures_upload_envmap().

◆ mem_blue_noise

VkDeviceMemory mem_blue_noise
static

Definition at line 55 of file textures.c.

Referenced by load_blue_noise(), and vkpt_textures_destroy().

◆ mem_envmap

VkDeviceMemory mem_envmap
static

Definition at line 55 of file textures.c.

Referenced by vkpt_textures_destroy(), and vkpt_textures_upload_envmap().

◆ mem_images

VkDeviceMemory mem_images[NUM_VKPT_IMAGES]
static

Definition at line 66 of file textures.c.

Referenced by vkpt_create_images(), and vkpt_destroy_images().

◆ tex_bind_image_info

VkBindImageMemoryInfo tex_bind_image_info[MAX_RIMAGES] = { 0 }
static

Definition at line 69 of file textures.c.

Referenced by vkpt_textures_end_registration().

◆ tex_device_memory_allocator

◆ tex_image_memory

DeviceMemory tex_image_memory[MAX_RIMAGES] = { 0 }
static

◆ tex_image_views

VkImageView tex_image_views[MAX_RIMAGES] = { 0 }
static

◆ tex_images

VkImage tex_images[MAX_RIMAGES] = { 0 }
static

◆ tex_invalid_texture_image

VkImage tex_invalid_texture_image = VK_NULL_HANDLE
static

Definition at line 62 of file textures.c.

Referenced by create_invalid_texture(), and destroy_invalid_texture().

◆ tex_invalid_texture_image_memory

DeviceMemory tex_invalid_texture_image_memory = { 0 }
static

Definition at line 64 of file textures.c.

Referenced by create_invalid_texture(), and destroy_invalid_texture().

◆ tex_invalid_texture_image_view

VkImageView tex_invalid_texture_image_view = VK_NULL_HANDLE
static

◆ texture_system

TextureSystem texture_system = { 0 }
static
LIST_IMAGES_B_A
#define LIST_IMAGES_B_A
Definition: global_textures.h:101
mem_images
static VkDeviceMemory mem_images[NUM_VKPT_IMAGES]
Definition: textures.c:66
UnusedResources::image_num
uint32_t image_num
Definition: textures.c:38
LOG_FUNC
#define LOG_FUNC()
Definition: vkpt.h:54
QVK_s::frame_counter
uint64_t frame_counter
Definition: vkpt.h:212
decode_srgb
static float decode_srgb(byte pix)
Definition: textures.c:497
UnusedResources::buffers
VkBuffer buffers[MAX_RBUFFERS]
Definition: textures.c:39
MAX_FRAMES_IN_FLIGHT
#define MAX_FRAMES_IN_FLIGHT
Definition: vkpt.h:140
GLOBAL_TEXTURES_TEX_ARR_BINDING_IDX
#define GLOBAL_TEXTURES_TEX_ARR_BINDING_IDX
Definition: global_textures.h:124
height
static int height
Definition: physical_sky.c:39
allocate_gpu_memory
VkResult allocate_gpu_memory(VkMemoryRequirements mem_req, VkDeviceMemory *pMemory)
Definition: vk_util.c:402
image_t
struct image_s image_t
Definition: material.h:27
mem_blue_noise
static VkDeviceMemory mem_blue_noise
Definition: textures.c:55
destroy_invalid_texture
void destroy_invalid_texture()
Definition: textures.c:813
FS_LastModified
qerror_t FS_LastModified(char const *file, uint64_t *last_modified)
Definition: files.c:1310
QVK_s::device
VkDevice device
Definition: vkpt.h:172
BLUE_NOISE_RES
#define BLUE_NOISE_RES
Definition: constants.h:42
IMG_Load
void(* IMG_Load)(image_t *image, byte *pic)
Definition: refresh.c:431
texture_system
static TextureSystem texture_system
Definition: textures.c:51
align
static size_t align(size_t x, size_t alignment)
Definition: vk_util.h:143
BINDING_OFFSET_IMAGES
#define BINDING_OFFSET_IMAGES
Definition: global_textures.h:125
create_device_memory_allocator
DeviceMemoryAllocator * create_device_memory_allocator(VkDevice device)
Definition: device_memory_allocator.c:48
BINDING_OFFSET_SKY_CLOUDS
#define BINDING_OFFSET_SKY_CLOUDS
Definition: global_textures.h:134
allocate_device_memory
DMAResult allocate_device_memory(DeviceMemoryAllocator *allocator, DeviceMemory *device_memory)
Definition: device_memory_allocator.c:60
desc_pool_textures
static VkDescriptorPool desc_pool_textures
Definition: textures.c:60
get_num_miplevels
static int get_num_miplevels(int w, int h)
Definition: textures.c:485
buffer_unmap
void buffer_unmap(BufferResource_t *buf)
Definition: vk_util.c:159
MAX
#define MAX(a, b)
Definition: vkpt.h:50
tex_image_memory
static DeviceMemory tex_image_memory[MAX_RIMAGES]
Definition: textures.c:68
QVK_s::current_frame_index
uint32_t current_frame_index
Definition: vkpt.h:219
QVK_s::tex_sampler
VkSampler tex_sampler
Definition: vkpt.h:255
BINDING_OFFSET_BLUE_NOISE
#define BINDING_OFFSET_BLUE_NOISE
Definition: global_textures.h:127
buffer_destroy
VkResult buffer_destroy(BufferResource_t *buf)
Definition: vk_util.c:132
UnusedResources
Definition: textures.c:33
BINDING_OFFSET_TEXTURES
#define BINDING_OFFSET_TEXTURES
Definition: global_textures.h:126
TextureSystem::unused_resources
UnusedResources unused_resources[DESTROY_LATENCY]
Definition: textures.c:48
BINDING_OFFSET_TERRAIN_ALBEDO
#define BINDING_OFFSET_TERRAIN_ALBEDO
Definition: global_textures.h:135
destroy_readback_image
static void destroy_readback_image(VkImage *image, VkDeviceMemory *memory, VkDeviceSize *memory_size)
Definition: textures.c:1431
tex_device_memory_allocator
static DeviceMemoryAllocator * tex_device_memory_allocator
Definition: textures.c:70
QVK_s::cmd_buffers_graphics
cmd_buf_group_t cmd_buffers_graphics
Definition: vkpt.h:193
QVK_s::desc_set_textures_even
VkDescriptorSet desc_set_textures_even
Definition: vkpt.h:229
QVK_s::screenshot_image_memory
VkDeviceMemory screenshot_image_memory
Definition: vkpt.h:262
image_loading_dirty_flag
static int image_loading_dirty_flag
Definition: textures.c:72
width
static int width
Definition: physical_sky.c:38
free_device_memory
void free_device_memory(DeviceMemoryAllocator *allocator, const DeviceMemory *device_memory)
Definition: device_memory_allocator.c:100
img_envmap
static VkImage img_envmap
Definition: textures.c:58
get_memory_type
uint32_t get_memory_type(uint32_t mem_req_type_bits, VkMemoryPropertyFlags mem_prop)
Definition: vk_util.c:45
_VK
#define _VK(...)
Definition: vkpt.h:65
DeviceMemory::alignment
uint64_t alignment
Definition: device_memory_allocator.h:33
tex_invalid_texture_image_memory
static DeviceMemory tex_invalid_texture_image_memory
Definition: textures.c:64
BINDING_OFFSET_SKY_SCATTERING
#define BINDING_OFFSET_SKY_SCATTERING
Definition: global_textures.h:132
vkpt_normalize_normal_map
void vkpt_normalize_normal_map(image_t *image)
Definition: textures.c:592
tex_invalid_texture_image_view
static VkImageView tex_invalid_texture_image_view
Definition: textures.c:63
NUM_IMAGES
#define NUM_IMAGES
Definition: global_textures.h:121
DeviceMemory
Definition: device_memory_allocator.h:28
UnusedResources::image_views
VkImageView image_views[MAX_RIMAGES]
Definition: textures.c:36
QVK_s::queue_idx_graphics
int32_t queue_idx_graphics
Definition: vkpt.h:176
QVK_s::extent_screen_images
VkExtent2D extent_screen_images
Definition: vkpt.h:183
r_numImages
int r_numImages
Definition: images.c:652
LIST_IMAGES
#define LIST_IMAGES
Definition: global_textures.h:34
tex_bind_image_info
static VkBindImageMemoryInfo tex_bind_image_info[MAX_RIMAGES]
Definition: textures.c:69
Z_Free
void Z_Free(void *ptr)
Definition: zone.c:147
BufferResource_s::buffer
VkBuffer buffer
Definition: vk_util.h:34
descriptor_set_dirty_flags
static uint8_t descriptor_set_dirty_flags[MAX_FRAMES_IN_FLIGHT]
Definition: textures.c:73
r_images
image_t r_images[MAX_RIMAGES]
Definition: images.c:651
encode_linear
static byte encode_linear(float x)
Definition: textures.c:524
QVK_s::images
VkImage images[NUM_VKPT_IMAGES]
Definition: vkpt.h:231
UnusedResources::buffer_num
uint32_t buffer_num
Definition: textures.c:41
set_current_gpu
void set_current_gpu(VkCommandBuffer cmd_buf, int gpu_index)
Definition: vk_util.c:426
NUM_BLUE_NOISE_TEX
#define NUM_BLUE_NOISE_TEX
Definition: constants.h:41
QVK_s::screenshot_image
VkImage screenshot_image
Definition: vkpt.h:261
Q_strlcpy
size_t Q_strlcpy(char *dst, const char *src, size_t size)
Definition: shared.c:715
imv_blue_noise
static VkImageView imv_blue_noise
Definition: textures.c:57
LENGTH
#define LENGTH(a)
Definition: tent.c:228
VKPT_MAX_GPUS
#define VKPT_MAX_GPUS
Definition: vk_util.h:30
DeviceMemory::memory
VkDeviceMemory memory
Definition: device_memory_allocator.h:30
BINDING_OFFSET_SKY_IRRADIANCE
#define BINDING_OFFSET_SKY_IRRADIANCE
Definition: global_textures.h:133
DeviceMemory::memory_offset
uint64_t memory_offset
Definition: device_memory_allocator.h:31
UnusedResources::buffer_memory
VkDeviceMemory buffer_memory[MAX_RBUFFERS]
Definition: textures.c:40
BINDING_OFFSET_PHYSICAL_SKY_IMG
#define BINDING_OFFSET_PHYSICAL_SKY_IMG
Definition: global_textures.h:130
BINDING_OFFSET_TERRAIN_DEPTH
#define BINDING_OFFSET_TERRAIN_DEPTH
Definition: global_textures.h:137
mem_envmap
static VkDeviceMemory mem_envmap
Definition: textures.c:55
QVK_s::tex_sampler_linear_clamp
VkSampler tex_sampler_linear_clamp
Definition: vkpt.h:257
QVK_s::desc_set_textures_odd
VkDescriptorSet desc_set_textures_odd
Definition: vkpt.h:230
IMG_Find
image_t * IMG_Find(const char *name, imagetype_t type, imageflags_t flags)
Definition: images.c:1122
BINDING_OFFSET_PHYSICAL_SKY
#define BINDING_OFFSET_PHYSICAL_SKY
Definition: global_textures.h:129
qvk
QVK_t qvk
Definition: main.c:377
destroy_device_memory_allocator
void destroy_device_memory_allocator(DeviceMemoryAllocator *allocator)
Definition: device_memory_allocator.c:110
QVK_s::screenshot_image_memory_size
VkDeviceSize screenshot_image_memory_size
Definition: vkpt.h:263
BINDING_OFFSET_TERRAIN_NORMALS
#define BINDING_OFFSET_TERRAIN_NORMALS
Definition: global_textures.h:136
vkpt_submit_command_buffer_simple
void vkpt_submit_command_buffer_simple(VkCommandBuffer cmd_buf, VkQueue queue, qboolean all_gpus)
Definition: main.c:3473
EMISSIVE_TRANSFORM_BIAS
#define EMISSIVE_TRANSFORM_BIAS
Definition: constants.h:35
sgets
char * sgets(char *str, int num, char const **input)
Definition: vk_util.c:26
ALL_GPUS
#define ALL_GPUS
Definition: vkpt.h:535
imv_envmap
static VkImageView imv_envmap
Definition: textures.c:59
UnusedResources::image_memory
DeviceMemory image_memory[MAX_RIMAGES]
Definition: textures.c:37
BufferResource_s
Definition: vk_util.h:33
DeviceMemory::size
uint64_t size
Definition: device_memory_allocator.h:32
QVK_s::tex_sampler_nearest
VkSampler tex_sampler_nearest
Definition: vkpt.h:256
textures_destroy_unused_set
static void textures_destroy_unused_set(uint32_t set_index)
Definition: textures.c:119
QVK_s::extent_unscaled
VkExtent2D extent_unscaled
Definition: vkpt.h:186
img_blue_noise
static VkImage img_blue_noise
Definition: textures.c:56
NUM_VKPT_IMAGES
@ NUM_VKPT_IMAGES
Definition: global_textures.h:157
buffer_create
VkResult buffer_create(BufferResource_t *buf, VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags mem_properties)
Definition: vk_util.c:57
QVK_s::images_views
VkImageView images_views[NUM_VKPT_IMAGES]
Definition: vkpt.h:232
UnusedResources::images
VkImage images[MAX_RIMAGES]
Definition: textures.c:35
IMAGE_BARRIER
#define IMAGE_BARRIER(cmd_buf,...)
Definition: vk_util.h:55
color
static vec4_t color
Definition: mesh.c:33
ATTACH_LABEL_VARIABLE
#define ATTACH_LABEL_VARIABLE(a, type)
Definition: vk_util.h:137
vkpt_begin_command_buffer
VkCommandBuffer vkpt_begin_command_buffer(cmd_buf_group_t *group)
Definition: main.c:3301
create_readback_image
static VkResult create_readback_image(VkImage *image, VkDeviceMemory *memory, VkDeviceSize *memory_size, VkFormat format, uint32_t width, uint32_t height)
Definition: textures.c:1392
load_blue_noise
static VkResult load_blue_noise()
Definition: textures.c:308
QVK_s::desc_set_layout_textures
VkDescriptorSetLayout desc_set_layout_textures
Definition: vkpt.h:228
range
int range(edict_t *self, edict_t *other)
Definition: g_ai.c:245
Q_concat
size_t Q_concat(char *dest, size_t size,...)
Definition: shared.c:758
BINDING_OFFSET_ENVMAP
#define BINDING_OFFSET_ENVMAP
Definition: global_textures.h:128
tex_images
static VkImage tex_images[MAX_RIMAGES]
Definition: textures.c:53
buffer_map
void * buffer_map(BufferResource_t *buf)
Definition: vk_util.c:147
QVK_s::surf_format
VkSurfaceFormatKHR surf_format
Definition: vkpt.h:181
LIST_IMAGES_A_B
#define LIST_IMAGES_A_B
Definition: global_textures.h:81
BufferResource_s::size
size_t size
Definition: vk_util.h:36
tex_invalid_texture_image
static VkImage tex_invalid_texture_image
Definition: textures.c:62
decode_linear
static float decode_linear(byte pix)
Definition: textures.c:519
load_img
qerror_t load_img(const char *name, image_t *image)
Definition: images.c:927
tex_image_views
static VkImageView tex_image_views[MAX_RIMAGES]
Definition: textures.c:54
BINDING_OFFSET_TERRAIN_SHADOWMAP
#define BINDING_OFFSET_TERRAIN_SHADOWMAP
Definition: global_textures.h:138
DeviceMemory::memory_type
uint32_t memory_type
Definition: device_memory_allocator.h:34
destroy_tex_images
static void destroy_tex_images()
Definition: textures.c:1024
create_invalid_texture
void create_invalid_texture()
Definition: textures.c:734
DESTROY_LATENCY
#define DESTROY_LATENCY
Definition: textures.c:44
VectorNormalize
vec_t VectorNormalize(vec3_t v)
Definition: shared.c:55
FS_NormalizePath
size_t FS_NormalizePath(char *out, const char *in)
Definition: files.c:331
qvk_get_current_desc_set_textures
VkDescriptorSet qvk_get_current_desc_set_textures()
Definition: main.c:1847
QVK_s::queue_graphics
VkQueue queue_graphics
Definition: vkpt.h:173
QVK_s::device_count
int device_count
Definition: vkpt.h:167
BINDING_OFFSET_SKY_TRANSMITTANCE
#define BINDING_OFFSET_SKY_TRANSMITTANCE
Definition: global_textures.h:131
BufferResource_s::memory
VkDeviceMemory memory
Definition: vk_util.h:35