1 #include <kiba/renderer/vulkan/texture.h>
3 #define STB_IMAGE_IMPLEMENTATION
4 #pragma GCC diagnostic push
5 #pragma GCC diagnostic ignored "-Wsign-conversion"
6 #pragma GCC diagnostic ignored "-Wconversion"
8 #pragma GCC diagnostic pop
9 #undef STB_IMAGE_IMPLEMENTATION
12 #include <kiba/renderer/vulkan/buffer.h>
13 #include <kiba/renderer/vulkan/image.h>
16 VkPhysicalDeviceProperties properties;
17 vkGetPhysicalDeviceProperties(context->device.physical, &properties);
18 VkSamplerCreateInfo sampler_info = {
19 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
20 .magFilter = VK_FILTER_LINEAR,
21 .minFilter = VK_FILTER_LINEAR,
22 .addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT,
23 .addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT,
24 .addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT,
25 .anisotropyEnable = VK_TRUE,
26 .maxAnisotropy = properties.limits.maxSamplerAnisotropy,
27 .borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK,
28 .unnormalizedCoordinates = VK_FALSE,
29 .compareEnable = VK_FALSE,
30 .compareOp = VK_COMPARE_OP_ALWAYS,
31 .mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR,
36 VK_CALL_B8(vkCreateSampler(context->device.logical,
38 &context->alloc.vulkan_callbacks,
39 &context->texture.sampler));
43 static void vulkan_texture_sampler_destroy(
vulkan_context *context) {
44 vkDestroySampler(context->device.logical, context->texture.sampler, &context->alloc.vulkan_callbacks);
48 const int image_mode = STBI_rgb_alpha;
49 const VkDeviceSize pixel_size = 4;
51 int width, height, channels;
53 stbi_uc *pixels = stbi_load(
"assets/textures/viking_room.png", &width, &height, &channels, image_mode);
56 KB_ERROR(
"failed to load texture data");
60 VkDeviceSize image_size = (u64) (width * height) * pixel_size;
62 if (!vulkan_buffer_create(context,
64 VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
65 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
67 KB_ERROR(
"could not create staging buffer for texture");
71 VK_CALL_B8(vkMapMemory(context->device.logical, staging_buffer.memory, 0, image_size, 0, &staging_buffer.mapped));
72 memory_copy(staging_buffer.mapped, pixels, (usize) image_size);
74 vkUnmapMemory(context->device.logical, staging_buffer.memory);
75 stbi_image_free(pixels);
77 if (!vulkan_image_create(
81 VK_FORMAT_R8G8B8A8_SRGB,
82 VK_IMAGE_TILING_OPTIMAL,
83 VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
84 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
85 &context->texture.image)) {
86 KB_ERROR(
"failed to create vulkan_image");
89 if (!vulkan_image_transition_layout(context,
90 &context->texture.image,
91 VK_FORMAT_R8G8B8A8_SRGB,
92 VK_IMAGE_LAYOUT_UNDEFINED,
93 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)) {
94 KB_ERROR(
"failed to transition vulkan_image layout for copying");
97 if (!vulkan_image_copy_from_buffer(context, &staging_buffer, &context->texture.image, (u32) width, (u32) height)) {
98 KB_ERROR(
"failed to copy image data from buffer to vulkan_image");
101 if (!vulkan_image_transition_layout(context,
102 &context->texture.image,
103 VK_FORMAT_R8G8B8A8_SRGB,
104 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
105 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)) {
106 KB_ERROR(
"failed to transition vulkan_image layout for rendering");
109 vulkan_buffer_destroy(context, &staging_buffer);
111 if (!vulkan_image_view_create(context,
112 context->texture.image.image,
113 VK_FORMAT_R8G8B8A8_SRGB,
114 VK_IMAGE_ASPECT_COLOR_BIT,
115 &context->texture.view)) {
116 KB_ERROR(
"failed to create image view for texture");
120 return vulkan_texture_sampler_create(context);
124 vulkan_texture_sampler_destroy(context);
125 vulkan_image_view_destroy(context, &context->texture.view);
126 vulkan_image_destroy(context, &context->texture.image);
void * memory_copy(void *dst, const void *src, usize size)
Copy memory.
Lightweight layer between platform and other engine components to enable tracing/monitoring.
#define KB_ERROR(...)
Log entry with error log level.