kiba-engine
texture.c
1 #include <kiba/gpu/texture.h>
2 
3 #include <kiba/gpu/vulkan/allocator.h>
4 #include <kiba/gpu/vulkan/conv.h>
5 #include <kiba/gpu/vulkan/device.h>
6 #include <kiba/gpu/vulkan/util.h>
7 
8 b8 gpu_backend_texture_create(struct gpu_backend_texture *texture,
9  struct gpu_backend_device device,
10  struct gpu_texture_descriptor desc) {
11  VkExtent3D image_extent = {
12  .width = (u32) desc.size.width,
13  .height = (u32) desc.size.height,
14  .depth = 1,
15  };
16  if (desc.dimension == GPU_TEXTURE_DIMENSION_D3) {
17  image_extent.depth = (u32) desc.size.depth;
18  }
19  VkImageCreateInfo image_info = {
20  .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
21  .imageType = vk_convert_texture_dimension(desc.dimension),
22  .extent = image_extent,
23  .mipLevels = (u32) desc.mip_level_count,
24  .arrayLayers = 1,
25  .format = vk_convert_texture_format(desc.format),
26  .tiling = VK_IMAGE_TILING_OPTIMAL,
27  .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
28  .usage = vk_convert_texture_use(gpu_convert_texture_usage_to_use(desc.usage, desc.format)),
29  .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
30  .samples = vk_convert_sample_count(desc.sample_count),
31  .flags = 0, // TODO view_formats and cube textures would set flags
32  };
33  if (desc.dimension == GPU_TEXTURE_DIMENSION_D2) {
34  image_info.arrayLayers = (u32) desc.size.layers;
35  }
36  VK_CALL_B8(vkCreateImage(device.logical, &image_info, &vk_alloc.vulkan_callbacks, &texture->raw));
37 
38  VkMemoryRequirements memory_requirements;
39  vkGetImageMemoryRequirements(device.logical, texture->raw, &memory_requirements);
40 
41  if (!vk_device_allocate_memory(device,
42  &texture->memory,
43  memory_requirements,
44  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) {
45  KB_ERROR("could not allocate memory for image");
46  return false;
47  }
48  VK_CALL_B8(vkBindImageMemory(device.logical, texture->raw, texture->memory, 0));
49  vk_device_set_object_name(device.logical, VK_OBJECT_TYPE_IMAGE, texture->raw, desc.label);
50  return true;
51 }
52 
53 void gpu_backend_texture_destroy(struct gpu_backend_texture *texture, struct gpu_backend_device device) {
54  vkDestroyImage(device.logical, texture->raw, &vk_alloc.vulkan_callbacks);
55  vkFreeMemory(device.logical, texture->memory, &vk_alloc.vulkan_callbacks);
56 }
57 
58 b8 gpu_backend_texture_view_create(struct gpu_backend_texture_view *view,
59  struct gpu_backend_device device,
60  struct gpu_backend_texture texture,
61  struct gpu_texture_view_descriptor desc) {
62  VkImageSubresourceRange subresource_range = {
63  .aspectMask = vk_convert_texture_format_aspect(gpu_format_aspect_from_format(desc.format)),
64  .baseMipLevel = (u32) desc.base_mip_level,
65  .levelCount = desc.mip_level_count == 0 ? VK_REMAINING_MIP_LEVELS : (u32) desc.mip_level_count,
66  .baseArrayLayer = (u32) desc.base_array_layer,
67  .layerCount = desc.array_layer_count == 0 ? VK_REMAINING_ARRAY_LAYERS : (u32) desc.array_layer_count,
68  };
69  VkImageViewCreateInfo view_info = {
70  .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
71  .image = texture.raw,
72  .viewType = vk_convert_texture_view_dimension(desc.dimension),
73  .format = vk_convert_texture_format(desc.format),
74  .subresourceRange = subresource_range,
75  };
76  VK_CALL_B8(vkCreateImageView(device.logical, &view_info, &vk_alloc.vulkan_callbacks, &view->raw));
77  vk_device_set_object_name(device.logical, VK_OBJECT_TYPE_IMAGE_VIEW, view->raw, desc.label);
78  return true;
79 }
80 
81 void gpu_backend_texture_view_destroy(struct gpu_backend_texture_view *view, struct gpu_backend_device device) {
82  if (view->raw != VK_NULL_HANDLE) {
83  vkDestroyImageView(device.logical, view->raw, &vk_alloc.vulkan_callbacks);
84  view->raw = VK_NULL_HANDLE;
85  } else {
86  KB_WARN("tried to destroy uninitialized texture view");
87  }
88 }
#define KB_WARN(...)
Log entry with warn log level.
Definition: log.h:161
#define KB_ERROR(...)
Log entry with error log level.
Definition: log.h:142