images (kinda) working again
the image example shows :3 but it errors a lot and shit
This commit is contained in:
parent
1dbb93543e
commit
114c8a0c5d
21 changed files with 694 additions and 105 deletions
4
Makefile
4
Makefile
|
@ -4,8 +4,8 @@ CC = clang
|
|||
CFLAGS = -std=c23 -Wall -Wextra -Wpedantic
|
||||
CFLAGS += -Werror -Wfloat-equal -Wshadow
|
||||
CFLAGS += -fPIC -fstrict-aliasing
|
||||
CFLAGS += $(shell pkg-config --cflags glfw3 vulkan)
|
||||
LDFLAGS = $(shell pkg-config --libs glfw3 vulkan)
|
||||
CFLAGS += $(shell pkg-config --cflags glfw3 stb vulkan)
|
||||
LDFLAGS = $(shell pkg-config --libs glfw3 stb vulkan)
|
||||
|
||||
ifdef DEBUG
|
||||
CFLAGS += -DDEBUG -g
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
gnumake,
|
||||
pkg-config,
|
||||
shaderc,
|
||||
stb,
|
||||
vulkan-headers,
|
||||
vulkan-loader,
|
||||
vulkan-validation-layers,
|
||||
|
@ -20,6 +21,7 @@ in stdenv.mkDerivation {
|
|||
|
||||
buildInputs = [
|
||||
glfw
|
||||
stb
|
||||
vulkan-headers
|
||||
vulkan-loader
|
||||
vulkan-validation-layers
|
||||
|
|
BIN
examples/:3.png
Normal file
BIN
examples/:3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
15
examples/image.c
Normal file
15
examples/image.c
Normal file
|
@ -0,0 +1,15 @@
|
|||
// Copyright (jacekpoz 2024). Licensed under the EUPL-1.2 or later.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <ptk.h>
|
||||
|
||||
int main(void) {
|
||||
if (!ptk_init(800, 600, "image", (PtkVersion){ .major = 0, .minor = 1, .patch = 0 })) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return ptk_run(/*PTK_BOX(*/
|
||||
// ptk_image("examples/papiezWasap.png", (PtkPos){ .x = 200.0f, .y = 200.0f }, (PtkSize){ .w = 128.0f, .h = 128.0f }),
|
||||
ptk_image("examples/:3.png", (PtkPos){ .x = 200.0f, .y = 400.0f }, (PtkSize){ .w = 128.0f, .h = 128.0f })
|
||||
/*)*/);
|
||||
}
|
|
@ -25,6 +25,7 @@ typedef enum {
|
|||
PTK_COMPONENT_TYPE_RECT = 2,
|
||||
PTK_COMPONENT_TYPE_ELLIPSE = 3,
|
||||
PTK_COMPONENT_TYPE_CLICKABLE = 4,
|
||||
PTK_COMPONENT_TYPE_IMAGE = 5,
|
||||
} PtkComponentType;
|
||||
|
||||
const char *ptk_component_type_to_str(PtkComponentType type);
|
||||
|
@ -66,6 +67,12 @@ PTK_COMPONENT_DEFINE(PtkClickable,
|
|||
MouseButtonCallback on_press;
|
||||
);
|
||||
|
||||
PTK_COMPONENT_DEFINE(PtkImage,
|
||||
const char *path;
|
||||
PtkPos top_left;
|
||||
PtkSize size;
|
||||
);
|
||||
|
||||
PtkHandle ptk_box(const size_t child_count, PtkHandle *children);
|
||||
PtkHandle ptk_triangle(const PtkPos vertices[3], const PtkRGB color);
|
||||
PtkHandle ptk_rect(const PtkPos top_left, const PtkSize size, const PtkRGB color);
|
||||
|
@ -73,6 +80,7 @@ PtkHandle ptk_square(const PtkPos top_left, const float size, const PtkRGB color
|
|||
PtkHandle ptk_ellipse(const PtkPos center, const PtkSize radii, const PtkRGB color);
|
||||
PtkHandle ptk_circle(const PtkPos center, const float radius, const PtkRGB color);
|
||||
PtkHandle ptk_clickable(PtkHandle hitbox, const MouseButtonCallback on_press);
|
||||
PtkHandle ptk_image(const char *path, const PtkPos top_left, const PtkSize size);
|
||||
|
||||
#define PTK_BOX(...) ptk_box(sizeof((PtkHandle []){ __VA_ARGS__ }) / sizeof(PtkHandle), (PtkHandle []) { __VA_ARGS__ })
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#version 450
|
||||
|
||||
layout(constant_id = 0) const int PTK_COMPONENT_TYPE_ELLIPSE = 0;
|
||||
layout(constant_id = 1) const int PTK_COMPONENT_TYPE_IMAGE = 0;
|
||||
|
||||
layout(location = 0) in vec3 fragColor;
|
||||
layout(location = 1) flat in int shapeType;
|
||||
|
@ -10,11 +11,17 @@ layout(location = 2) in vec2 uv;
|
|||
|
||||
layout(location = 0) out vec4 outColor;
|
||||
|
||||
layout(binding = 1) uniform sampler2D textureSampler;
|
||||
|
||||
void main() {
|
||||
if (shapeType == PTK_COMPONENT_TYPE_ELLIPSE) {
|
||||
if (length(uv - vec2(0.5)) > 0.5) {
|
||||
discard;
|
||||
}
|
||||
outColor = vec4(fragColor, 1.0);
|
||||
} else if (shapeType == PTK_COMPONENT_TYPE_IMAGE) {
|
||||
outColor = texture(textureSampler, uv);
|
||||
} else {
|
||||
outColor = vec4(fragColor, 1.0);
|
||||
}
|
||||
outColor = vec4(fragColor, 1.0);
|
||||
}
|
||||
|
|
|
@ -118,6 +118,7 @@ const char *ptk_component_type_to_str(PtkComponentType type) {
|
|||
case PTK_COMPONENT_TYPE_RECT: res = "rect"; break;
|
||||
case PTK_COMPONENT_TYPE_ELLIPSE: res = "ellipse"; break;
|
||||
case PTK_COMPONENT_TYPE_CLICKABLE: res = "clickable"; break;
|
||||
case PTK_COMPONENT_TYPE_IMAGE: res = "image"; break;
|
||||
default: res = "unknown"; break;
|
||||
}
|
||||
return res;
|
||||
|
@ -159,6 +160,10 @@ PtkHandle ptk_clickable(PtkHandle hitbox, const MouseButtonCallback on_press) {
|
|||
return clickable_component(get_component_id(), hitbox, on_press);
|
||||
}
|
||||
|
||||
PtkHandle ptk_image(const char *path, const PtkPos top_left, const PtkSize size) {
|
||||
return image_component(get_component_id(), path, top_left, size);
|
||||
}
|
||||
|
||||
int ptk_run(PtkHandle root) {
|
||||
vk_init_components(root);
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "ptk_vk/components.h"
|
||||
#include "ptk_vk/descriptors.h"
|
||||
#include "ptk_vk/device.h"
|
||||
#include "ptk_vk/image.h"
|
||||
#include "ptk_vk/init.h"
|
||||
#include "ptk_vk/instance.h"
|
||||
#include "ptk_vk/physical_device.h"
|
||||
|
@ -174,6 +175,21 @@ bool vk_init(GLFWwindow *window, const size_t width, const size_t height, const
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!vk_create_texture_image("examples/:3.png")) {
|
||||
PTK_ERR("failed creating texture image");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!vk_create_texture_image_view()) {
|
||||
PTK_ERR("failed creating texture image view");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!vk_create_texture_sampler()) {
|
||||
PTK_ERR("failed creating texture sampler");
|
||||
return false;
|
||||
}
|
||||
|
||||
const VkDeviceSize buffer_size = 65536;
|
||||
|
||||
PTK_OPTION(BufferStuff) vertex_buffer_stuff_opt = vk_create_buffer(
|
||||
|
|
|
@ -3,15 +3,14 @@
|
|||
#include "ptk_vk/buffer.h"
|
||||
|
||||
#include "ptk_vk/command_pool.h"
|
||||
#include "ptk_vk/device.h"
|
||||
#include "ptk_vk/physical_device.h"
|
||||
#include "ptk_vk/utils.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
PTK_OPTION(uint32_t) find_memory_type(VkPhysicalDevice physical_dev, const uint32_t type_filter, const VkMemoryPropertyFlags props) {
|
||||
PTK_OPTION(uint32_t) vk_find_memory_type(const uint32_t type_filter, const VkMemoryPropertyFlags props) {
|
||||
VkPhysicalDeviceMemoryProperties mem_props;
|
||||
vkGetPhysicalDeviceMemoryProperties(physical_dev, &mem_props);
|
||||
vkGetPhysicalDeviceMemoryProperties(g_physical_dev, &mem_props);
|
||||
|
||||
for (uint32_t i = 0; i < mem_props.memoryTypeCount; ++i) {
|
||||
if (type_filter & (1 << i) && (mem_props.memoryTypes[i].propertyFlags & props) == props) {
|
||||
|
@ -46,7 +45,7 @@ PTK_OPTION(BufferStuff) vk_create_buffer(const VkDeviceSize size, const VkBuffer
|
|||
VkMemoryRequirements mem_reqs;
|
||||
vkGetBufferMemoryRequirements(g_dev, ret.buffer, &mem_reqs);
|
||||
|
||||
const PTK_OPTION(uint32_t) memory_type = find_memory_type(g_physical_dev, mem_reqs.memoryTypeBits, props);
|
||||
const PTK_OPTION(uint32_t) memory_type = vk_find_memory_type(mem_reqs.memoryTypeBits, props);
|
||||
|
||||
if (!memory_type.exists) {
|
||||
PTK_ERR("failed to find suitable memory type");
|
||||
|
@ -73,30 +72,14 @@ PTK_OPTION(BufferStuff) vk_create_buffer(const VkDeviceSize size, const VkBuffer
|
|||
}
|
||||
|
||||
bool copy_buffer(const VkBuffer src, const VkBuffer dst, const VkDeviceSize size) {
|
||||
VkCommandBuffer command_buffer;
|
||||
PTK_OPTION(VkCommandBuffer) command_buffer_opt = vk_begin_single_time_commands();
|
||||
|
||||
VK_TRY(false,
|
||||
vkAllocateCommandBuffers(
|
||||
g_dev,
|
||||
&(VkCommandBufferAllocateInfo){
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
|
||||
.pNext = NULL,
|
||||
.commandPool = g_command_pool,
|
||||
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
|
||||
.commandBufferCount = 1,
|
||||
},
|
||||
&command_buffer
|
||||
)
|
||||
);
|
||||
if (!command_buffer_opt.exists) {
|
||||
PTK_ERR("failed to create command buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
VK_TRY(false,
|
||||
vkBeginCommandBuffer(command_buffer, &(VkCommandBufferBeginInfo){
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||
.pNext = NULL,
|
||||
.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
|
||||
.pInheritanceInfo = NULL,
|
||||
})
|
||||
);
|
||||
VkCommandBuffer command_buffer = command_buffer_opt.value;
|
||||
|
||||
vkCmdCopyBuffer(command_buffer, src, dst, 1, &(VkBufferCopy){
|
||||
.srcOffset = 0,
|
||||
|
@ -104,30 +87,10 @@ bool copy_buffer(const VkBuffer src, const VkBuffer dst, const VkDeviceSize size
|
|||
.size = size,
|
||||
});
|
||||
|
||||
VK_TRY(false,
|
||||
vkEndCommandBuffer(command_buffer)
|
||||
);
|
||||
|
||||
vkQueueSubmit(
|
||||
g_graphics_queue,
|
||||
1,
|
||||
&(VkSubmitInfo){
|
||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||
.pNext = NULL,
|
||||
.waitSemaphoreCount = 0,
|
||||
.pWaitSemaphores = NULL,
|
||||
.pWaitDstStageMask = NULL,
|
||||
.commandBufferCount = 1,
|
||||
.pCommandBuffers = &command_buffer,
|
||||
.signalSemaphoreCount = 0,
|
||||
.pSignalSemaphores = NULL,
|
||||
},
|
||||
VK_NULL_HANDLE
|
||||
);
|
||||
|
||||
vkQueueWaitIdle(g_graphics_queue);
|
||||
|
||||
vkFreeCommandBuffers(g_dev, g_command_pool, 1, &command_buffer);
|
||||
if (!vk_end_single_time_commands(command_buffer)) {
|
||||
PTK_ERR("failed to end command buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -3,10 +3,14 @@
|
|||
#ifndef PTK_PTK_VK_BUFFER_H_
|
||||
#define PTK_PTK_VK_BUFFER_H_
|
||||
|
||||
#include "ptk_vk/device.h"
|
||||
|
||||
#include "ptk_option.h"
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
PTK_OPTION(uint32_t) vk_find_memory_type(const uint32_t type_filter, const VkMemoryPropertyFlags props);
|
||||
|
||||
typedef struct {
|
||||
VkBuffer buffer;
|
||||
VkDeviceMemory buffer_memory;
|
||||
|
|
|
@ -5,6 +5,67 @@
|
|||
#include "ptk_vk/device.h"
|
||||
#include "ptk_vk/utils.h"
|
||||
|
||||
PTK_OPTION(VkCommandBuffer) vk_begin_single_time_commands(void) {
|
||||
VkCommandBuffer command_buffer;
|
||||
|
||||
VK_TRY(PTK_OPTION_NONE(VkCommandBuffer),
|
||||
vkAllocateCommandBuffers(
|
||||
g_dev,
|
||||
&(VkCommandBufferAllocateInfo){
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
|
||||
.pNext = NULL,
|
||||
.commandPool = g_command_pool,
|
||||
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
|
||||
.commandBufferCount = 1,
|
||||
},
|
||||
&command_buffer
|
||||
)
|
||||
);
|
||||
|
||||
VK_TRY(PTK_OPTION_NONE(VkCommandBuffer),
|
||||
vkBeginCommandBuffer(
|
||||
command_buffer,
|
||||
&(VkCommandBufferBeginInfo){
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||
.pNext = NULL,
|
||||
.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
|
||||
.pInheritanceInfo = NULL,
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
return PTK_OPTION_SOME(VkCommandBuffer, command_buffer);
|
||||
}
|
||||
|
||||
bool vk_end_single_time_commands(VkCommandBuffer command_buffer) {
|
||||
VK_TRY(false, vkEndCommandBuffer(command_buffer));
|
||||
|
||||
VK_TRY(false,
|
||||
vkQueueSubmit(
|
||||
g_graphics_queue,
|
||||
1,
|
||||
&(VkSubmitInfo){
|
||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||
.pNext = NULL,
|
||||
.waitSemaphoreCount = 0,
|
||||
.pWaitSemaphores = NULL,
|
||||
.pWaitDstStageMask = NULL,
|
||||
.commandBufferCount = 1,
|
||||
.pCommandBuffers = &command_buffer,
|
||||
.signalSemaphoreCount = 0,
|
||||
.pSignalSemaphores = NULL,
|
||||
},
|
||||
VK_NULL_HANDLE
|
||||
);
|
||||
);
|
||||
|
||||
VK_TRY(false, vkQueueWaitIdle(g_graphics_queue));
|
||||
|
||||
vkFreeCommandBuffers(g_dev, g_command_pool, 1, &command_buffer);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
VkCommandPool g_command_pool;
|
||||
|
||||
bool vk_create_command_pool(void) {
|
||||
|
|
|
@ -3,8 +3,16 @@
|
|||
#ifndef PTK_PTK_VK_COMMAND_POOL_H_
|
||||
#define PTK_PTK_VK_COMMAND_POOL_H_
|
||||
|
||||
#include "ptk_option.h"
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
PTK_OPTION_DEFINE(VkCommandBuffer);
|
||||
|
||||
PTK_OPTION(VkCommandBuffer) vk_begin_single_time_commands(void);
|
||||
|
||||
bool vk_end_single_time_commands(VkCommandBuffer command_buffer);
|
||||
|
||||
extern VkCommandPool g_command_pool;
|
||||
|
||||
bool vk_create_command_pool(void);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (jacekpoz 2024). Licensed under the EUPL-1.2 or later.
|
||||
|
||||
#include "ptk_vk/components.h"
|
||||
#include "ptk_vk/image.h"
|
||||
#include "ptk_vk/init.h"
|
||||
|
||||
#include "ptk.h"
|
||||
|
@ -113,6 +114,19 @@ PtkHandle clickable_component(const uint64_t id, PtkHandle hitbox, const MouseBu
|
|||
return (PtkHandle)ret;
|
||||
}
|
||||
|
||||
PtkHandle image_component(const uint64_t id, const char *path, const PtkPos top_left, const PtkSize size) {
|
||||
PtkImage *ret = malloc(sizeof(PtkImage));
|
||||
*ret = (PtkImage){
|
||||
.id = id,
|
||||
.type = PTK_COMPONENT_TYPE_IMAGE,
|
||||
.path = path,
|
||||
.top_left = top_left,
|
||||
.size = size,
|
||||
};
|
||||
|
||||
return (PtkHandle)ret;
|
||||
}
|
||||
|
||||
void triangle(const PtkTriangle *triangle) {
|
||||
PTK_LIST_SET(Vertices, m_vertices_cache, triangle->id, PTK_LIST_NEW(Vertex, 3));
|
||||
PTK_LIST_SET(Indices, m_indices_cache, triangle->id, PTK_LIST_NEW(uint32_t, 3));
|
||||
|
@ -224,7 +238,20 @@ void ellipse(const PtkEllipse *ellipse) {
|
|||
rect(r);
|
||||
}
|
||||
|
||||
void image(const PtkImage *image) {
|
||||
vk_create_texture_image(image->path);
|
||||
|
||||
PtkRect *r = (PtkRect *)rect_component(image->id, image->top_left, image->size, (PtkRGB){ .r = 0.0f, .g = 0.0f, .b = 0.0f });
|
||||
r->type = image->type;
|
||||
|
||||
rect(r);
|
||||
}
|
||||
|
||||
void component(PtkHandle c) {
|
||||
if (c == PTK_NULL_HANDLE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_update.data[c->id]) {
|
||||
Vertices vcache = m_vertices_cache.data[c->id];
|
||||
Indices icache = m_indices_cache.data[c->id];
|
||||
|
@ -245,6 +272,9 @@ void component(PtkHandle c) {
|
|||
case PTK_COMPONENT_TYPE_ELLIPSE: {
|
||||
ellipse((PtkEllipse *)c);
|
||||
} break;
|
||||
case PTK_COMPONENT_TYPE_IMAGE: {
|
||||
image((PtkImage *)c);
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
@ -255,6 +285,10 @@ void component(PtkHandle c) {
|
|||
}
|
||||
|
||||
void init_component(PtkHandle c) {
|
||||
if (c == PTK_NULL_HANDLE) {
|
||||
return;
|
||||
}
|
||||
|
||||
PTK_LIST_SET(bool, m_update, c->id, true);
|
||||
PTK_LIST_FOR_EACH(PtkHandle, c->children, child, {
|
||||
init_component(child);
|
||||
|
@ -323,6 +357,8 @@ bool intersects(const PtkHandle component, const PtkPos point) {
|
|||
return ellipse_intersects(*(PtkEllipse *)component, point);
|
||||
case PTK_COMPONENT_TYPE_CLICKABLE:
|
||||
return intersects(component->children.data[0], point);
|
||||
case PTK_COMPONENT_TYPE_IMAGE:
|
||||
return rect_intersects(*(PtkRect *)rect_component(component->id, ((PtkImage *)component)->top_left, ((PtkImage *)component)->size, (PtkRGB){ .r = 0.0f, .g = 0.0f, .b = 0.0f }), point);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ PtkHandle square_component(const uint64_t id, const PtkPos top_left, const float
|
|||
PtkHandle ellipse_component(const uint64_t id, const PtkPos center, const PtkSize radii, const PtkRGB color);
|
||||
PtkHandle circle_component(const uint64_t id, const PtkPos center, const float radius, const PtkRGB color);
|
||||
PtkHandle clickable_component(const uint64_t id, PtkHandle hitbox, const MouseButtonCallback on_press);
|
||||
PtkHandle image_component(const uint64_t id, const char *path, const PtkPos top_left, const PtkSize size);
|
||||
|
||||
void vk_init_components(PtkHandle root);
|
||||
|
||||
|
|
|
@ -3,15 +3,37 @@
|
|||
#include "ptk_vk/descriptors.h"
|
||||
|
||||
#include "ptk_vk/device.h"
|
||||
#include "ptk_vk/image.h"
|
||||
#include "ptk_vk/sync_objects.h"
|
||||
#include "ptk_vk/uniform_buffers.h"
|
||||
#include "ptk_vk/utils.h"
|
||||
|
||||
#include "ptk_array.h"
|
||||
|
||||
VkDescriptorSetLayout g_descriptor_set_layout;
|
||||
VkDescriptorPool g_descriptor_pool;
|
||||
PTK_LIST(VkDescriptorSet) g_descriptor_sets;
|
||||
|
||||
PTK_ARRAY_DEFINE(VkDescriptorSetLayoutBinding);
|
||||
|
||||
bool vk_create_descriptor_set_layout(void) {
|
||||
PTK_ARRAY(VkDescriptorSetLayoutBinding) bindings = PTK_ARRAY_NEW(VkDescriptorSetLayoutBinding, {
|
||||
(VkDescriptorSetLayoutBinding){
|
||||
.binding = 0,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
|
||||
.pImmutableSamplers = NULL,
|
||||
},
|
||||
(VkDescriptorSetLayoutBinding){
|
||||
.binding = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
.pImmutableSamplers = NULL,
|
||||
},
|
||||
});
|
||||
|
||||
VK_TRY(false,
|
||||
vkCreateDescriptorSetLayout(
|
||||
g_dev,
|
||||
|
@ -19,14 +41,8 @@ bool vk_create_descriptor_set_layout(void) {
|
|||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||
.pNext = NULL,
|
||||
.flags = 0,
|
||||
.bindingCount = 1,
|
||||
.pBindings = &(VkDescriptorSetLayoutBinding){
|
||||
.binding = 0,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
|
||||
.pImmutableSamplers = NULL,
|
||||
},
|
||||
.bindingCount = bindings.size,
|
||||
.pBindings = bindings.data,
|
||||
},
|
||||
NULL,
|
||||
&g_descriptor_set_layout
|
||||
|
@ -36,7 +52,20 @@ bool vk_create_descriptor_set_layout(void) {
|
|||
return true;
|
||||
}
|
||||
|
||||
PTK_ARRAY_DEFINE(VkDescriptorPoolSize);
|
||||
|
||||
bool vk_create_descriptor_pool(void) {
|
||||
PTK_ARRAY(VkDescriptorPoolSize) pool_sizes = PTK_ARRAY_NEW(VkDescriptorPoolSize, {
|
||||
(VkDescriptorPoolSize){
|
||||
.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
.descriptorCount = g_max_frames_in_flight,
|
||||
},
|
||||
(VkDescriptorPoolSize){
|
||||
.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
.descriptorCount = g_max_frames_in_flight,
|
||||
},
|
||||
});
|
||||
|
||||
VK_TRY(false,
|
||||
vkCreateDescriptorPool(
|
||||
g_dev,
|
||||
|
@ -45,11 +74,8 @@ bool vk_create_descriptor_pool(void) {
|
|||
.pNext = NULL,
|
||||
.flags = 0,
|
||||
.maxSets = g_max_frames_in_flight,
|
||||
.poolSizeCount = 1,
|
||||
.pPoolSizes = &(VkDescriptorPoolSize){
|
||||
.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
.descriptorCount = g_max_frames_in_flight,
|
||||
},
|
||||
.poolSizeCount = pool_sizes.size,
|
||||
.pPoolSizes = pool_sizes.data,
|
||||
},
|
||||
NULL,
|
||||
&g_descriptor_pool
|
||||
|
@ -60,6 +86,7 @@ bool vk_create_descriptor_pool(void) {
|
|||
}
|
||||
|
||||
PTK_LIST_DEFINE(VkDescriptorSetLayout);
|
||||
PTK_ARRAY_DEFINE(VkWriteDescriptorSet);
|
||||
|
||||
bool vk_create_descriptor_sets(void) {
|
||||
PTK_LIST(VkDescriptorSetLayout) layouts = PTK_LIST_NEW(VkDescriptorSetLayout, g_max_frames_in_flight);
|
||||
|
@ -84,10 +111,8 @@ bool vk_create_descriptor_sets(void) {
|
|||
);
|
||||
|
||||
for (size_t i = 0; i < g_max_frames_in_flight; ++i) {
|
||||
vkUpdateDescriptorSets(
|
||||
g_dev,
|
||||
1,
|
||||
&(VkWriteDescriptorSet){
|
||||
PTK_ARRAY(VkWriteDescriptorSet) descriptor_writes = PTK_ARRAY_NEW(VkWriteDescriptorSet, {
|
||||
(VkWriteDescriptorSet){
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.pNext = NULL,
|
||||
.dstSet = g_descriptor_sets.data[i],
|
||||
|
@ -103,6 +128,28 @@ bool vk_create_descriptor_sets(void) {
|
|||
},
|
||||
.pTexelBufferView = NULL,
|
||||
},
|
||||
(VkWriteDescriptorSet){
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.pNext = NULL,
|
||||
.dstSet = g_descriptor_sets.data[i],
|
||||
.dstBinding = 1,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
.pImageInfo = &(VkDescriptorImageInfo){
|
||||
.sampler = g_texture_sampler,
|
||||
.imageView = g_texture_image_view,
|
||||
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
},
|
||||
.pBufferInfo = NULL,
|
||||
.pTexelBufferView = NULL,
|
||||
},
|
||||
});
|
||||
|
||||
vkUpdateDescriptorSets(
|
||||
g_dev,
|
||||
descriptor_writes.size,
|
||||
descriptor_writes.data,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
|
|
|
@ -88,7 +88,10 @@ static bool is_device_suitable(const VkPhysicalDevice physical_dev, const VkSurf
|
|||
|
||||
PTK_LIST_FREE(queue_families);
|
||||
|
||||
return indices_found && extensions_supported && swapchain_adequate;
|
||||
VkPhysicalDeviceFeatures supported_features;
|
||||
vkGetPhysicalDeviceFeatures(physical_dev, &supported_features);
|
||||
|
||||
return indices_found && extensions_supported && swapchain_adequate && supported_features.samplerAnisotropy;
|
||||
}
|
||||
|
||||
bool vk_create_logical_dev(void) {
|
||||
|
|
385
src/ptk_vk/image.c
Normal file
385
src/ptk_vk/image.c
Normal file
|
@ -0,0 +1,385 @@
|
|||
#include "ptk_vk/image.h"
|
||||
|
||||
#include "ptk_vk/buffer.h"
|
||||
#include "ptk_vk/command_pool.h"
|
||||
#include "ptk_vk/device.h"
|
||||
#include "ptk_vk/physical_device.h"
|
||||
#include "ptk_vk/utils.h"
|
||||
|
||||
#include "ptk_log.h"
|
||||
#include "ptk_option.h"
|
||||
|
||||
#include "vulkan/vulkan_core.h"
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <stb_image.h>
|
||||
|
||||
VkImage g_texture_image;
|
||||
VkDeviceMemory g_texture_image_memory;
|
||||
|
||||
VkImageView g_texture_image_view;
|
||||
|
||||
VkSampler g_texture_sampler;
|
||||
|
||||
bool create_image(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags props, VkImage *image, VkDeviceMemory *image_memory) {
|
||||
VK_TRY(false,
|
||||
vkCreateImage(
|
||||
g_dev,
|
||||
&(VkImageCreateInfo){
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
||||
.pNext = NULL,
|
||||
.flags = 0,
|
||||
.imageType = VK_IMAGE_TYPE_2D,
|
||||
.format = format,
|
||||
.extent = (VkExtent3D){
|
||||
.width = width,
|
||||
.height = height,
|
||||
.depth = 1,
|
||||
},
|
||||
.mipLevels = 1,
|
||||
.arrayLayers = 1,
|
||||
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||
.tiling = tiling,
|
||||
.usage = usage,
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
.queueFamilyIndexCount = 0,
|
||||
.pQueueFamilyIndices = NULL,
|
||||
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
},
|
||||
NULL,
|
||||
image
|
||||
)
|
||||
);
|
||||
|
||||
VkMemoryRequirements mem_reqs;
|
||||
vkGetImageMemoryRequirements(g_dev, *image, &mem_reqs);
|
||||
|
||||
PTK_OPTION(uint32_t) mem_type = vk_find_memory_type(mem_reqs.memoryTypeBits, props);
|
||||
|
||||
if (!mem_type.exists) {
|
||||
PTK_ERR("failed to find suitable memory type");
|
||||
return false;
|
||||
}
|
||||
|
||||
VK_TRY(false,
|
||||
vkAllocateMemory(
|
||||
g_dev,
|
||||
&(VkMemoryAllocateInfo){
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
||||
.pNext = NULL,
|
||||
.allocationSize = mem_reqs.size,
|
||||
.memoryTypeIndex = mem_type.value,
|
||||
},
|
||||
NULL,
|
||||
image_memory
|
||||
)
|
||||
);
|
||||
|
||||
VK_TRY(false,
|
||||
vkBindImageMemory(
|
||||
g_dev,
|
||||
*image,
|
||||
*image_memory,
|
||||
0
|
||||
)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool transition_image_layout(VkImage image, VkFormat format, VkImageLayout old_layout, VkImageLayout new_layout) {
|
||||
(void)format;
|
||||
PTK_OPTION(VkCommandBuffer) command_buffer_opt = vk_begin_single_time_commands();
|
||||
|
||||
if (!command_buffer_opt.exists) {
|
||||
PTK_ERR("failed to create command buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
VkCommandBuffer command_buffer = command_buffer_opt.value;
|
||||
|
||||
VkAccessFlags source_access_mask;
|
||||
VkAccessFlags destination_access_mask;
|
||||
VkPipelineStageFlags source_stage;
|
||||
VkPipelineStageFlags destination_stage;
|
||||
|
||||
if (
|
||||
old_layout == VK_IMAGE_LAYOUT_UNDEFINED
|
||||
&& new_layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
|
||||
) {
|
||||
source_access_mask = 0;
|
||||
destination_access_mask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
|
||||
source_stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
||||
destination_stage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
} else if (
|
||||
old_layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
|
||||
&& new_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
|
||||
) {
|
||||
source_access_mask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
destination_access_mask = VK_ACCESS_SHADER_READ_BIT;
|
||||
|
||||
source_stage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
destination_stage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||
} else {
|
||||
PTK_ERR("unsupported layer transition");
|
||||
return false;
|
||||
}
|
||||
|
||||
vkCmdPipelineBarrier(
|
||||
command_buffer,
|
||||
source_stage,
|
||||
destination_stage,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
1,
|
||||
&(VkImageMemoryBarrier){
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.pNext = NULL,
|
||||
.srcAccessMask = source_access_mask,
|
||||
.dstAccessMask = destination_access_mask,
|
||||
.oldLayout = old_layout,
|
||||
.newLayout = new_layout,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.image = image,
|
||||
.subresourceRange = (VkImageSubresourceRange){
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (!vk_end_single_time_commands(command_buffer)) {
|
||||
PTK_ERR("failed to end command buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool copy_buffer_to_image(VkBuffer buffer, VkImage image, uint32_t width, uint32_t height) {
|
||||
PTK_OPTION(VkCommandBuffer) command_buffer_opt = vk_begin_single_time_commands();
|
||||
|
||||
if (!command_buffer_opt.exists) {
|
||||
PTK_ERR("failed to create command buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
VkCommandBuffer command_buffer = command_buffer_opt.value;
|
||||
|
||||
vkCmdCopyBufferToImage(
|
||||
command_buffer,
|
||||
buffer,
|
||||
image,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
1,
|
||||
&(VkBufferImageCopy){
|
||||
.bufferOffset = 0,
|
||||
.bufferRowLength = 0,
|
||||
.bufferImageHeight = 0,
|
||||
.imageSubresource = (VkImageSubresourceLayers){
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.mipLevel = 0,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
},
|
||||
.imageOffset = (VkOffset3D){
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.z = 0,
|
||||
},
|
||||
.imageExtent = (VkExtent3D){
|
||||
.width = width,
|
||||
.height = height,
|
||||
.depth = 1,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (!vk_end_single_time_commands(command_buffer)) {
|
||||
PTK_ERR("failed to end command buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool vk_create_texture_image(const char *path) {
|
||||
int texture_width;
|
||||
int texture_height;
|
||||
int texture_channels;
|
||||
|
||||
stbi_uc *pixels = stbi_load(path, &texture_width, &texture_height, &texture_channels, STBI_rgb_alpha);
|
||||
VkDeviceSize image_size = texture_width * texture_height * 4;
|
||||
|
||||
if (pixels == NULL) {
|
||||
PTK_ERR("failed to load image at %s", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
PTK_OPTION(BufferStuff) staging_buffer_stuff_opt = vk_create_buffer(
|
||||
image_size,
|
||||
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
|
||||
);
|
||||
|
||||
if (!staging_buffer_stuff_opt.exists) {
|
||||
PTK_ERR("failed creating staging image buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
VkBuffer staging_buffer = staging_buffer_stuff_opt.value.buffer;
|
||||
VkDeviceMemory staging_buffer_memory = staging_buffer_stuff_opt.value.buffer_memory;
|
||||
|
||||
void *data;
|
||||
vkMapMemory(g_dev, staging_buffer_memory, 0, image_size, 0, &data);
|
||||
memcpy(data, pixels, image_size);
|
||||
vkUnmapMemory(g_dev, staging_buffer_memory);
|
||||
|
||||
stbi_image_free(pixels);
|
||||
|
||||
if (
|
||||
!create_image(
|
||||
texture_width,
|
||||
texture_height,
|
||||
VK_FORMAT_R8G8B8A8_SRGB,
|
||||
VK_IMAGE_TILING_OPTIMAL,
|
||||
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
&g_texture_image,
|
||||
&g_texture_image_memory
|
||||
)
|
||||
) {
|
||||
PTK_ERR("failed creating image");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
!transition_image_layout(
|
||||
g_texture_image,
|
||||
VK_FORMAT_R8G8B8A8_SRGB,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
|
||||
)
|
||||
) {
|
||||
PTK_ERR("failed transitioning image layout to optimal");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!copy_buffer_to_image(staging_buffer, g_texture_image, texture_width, texture_height)) {
|
||||
PTK_ERR("failed copying buffer to image");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
!transition_image_layout(
|
||||
g_texture_image,
|
||||
VK_FORMAT_R8G8B8A8_SRGB,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
|
||||
)
|
||||
) {
|
||||
PTK_ERR("failed transitioning image layout to shader optimal");
|
||||
return false;
|
||||
}
|
||||
|
||||
vkDestroyBuffer(g_dev, staging_buffer, NULL);
|
||||
vkFreeMemory(g_dev, staging_buffer_memory, NULL);
|
||||
|
||||
if (!vk_create_texture_image_view()) {
|
||||
PTK_ERR("failed creating texture image view");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
PTK_OPTION(VkImageView) vk_create_image_view(VkImage image, VkFormat format) {
|
||||
VkImageView ret;
|
||||
|
||||
VK_TRY(PTK_OPTION_NONE(VkImageView),
|
||||
vkCreateImageView(
|
||||
g_dev,
|
||||
&(VkImageViewCreateInfo){
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||
.pNext = NULL,
|
||||
.flags = 0,
|
||||
.image = image,
|
||||
.viewType = VK_IMAGE_VIEW_TYPE_2D,
|
||||
.format = format,
|
||||
.components = (VkComponentMapping){
|
||||
.r = VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
.g = VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
.b = VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
.a = VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
},
|
||||
.subresourceRange = (VkImageSubresourceRange){
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
},
|
||||
},
|
||||
NULL,
|
||||
&ret
|
||||
)
|
||||
);
|
||||
|
||||
return PTK_OPTION_SOME(VkImageView, ret);
|
||||
}
|
||||
|
||||
bool vk_create_texture_image_view(void) {
|
||||
PTK_OPTION(VkImageView) image_view_opt = vk_create_image_view(g_texture_image, VK_FORMAT_R8G8B8A8_SRGB);
|
||||
|
||||
if (!image_view_opt.exists) {
|
||||
PTK_ERR("failed to create texture image view");
|
||||
return false;
|
||||
}
|
||||
|
||||
g_texture_image_view = image_view_opt.value;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool vk_create_texture_sampler(void) {
|
||||
VkPhysicalDeviceProperties props;
|
||||
vkGetPhysicalDeviceProperties(g_physical_dev, &props);
|
||||
|
||||
VK_TRY(false,
|
||||
vkCreateSampler(
|
||||
g_dev,
|
||||
&(VkSamplerCreateInfo){
|
||||
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
||||
.pNext = NULL,
|
||||
.flags = 0,
|
||||
.magFilter = VK_FILTER_LINEAR,
|
||||
.minFilter = VK_FILTER_LINEAR,
|
||||
.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR,
|
||||
.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
||||
.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
||||
.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
||||
.mipLodBias = 0.0f,
|
||||
.anisotropyEnable = VK_FALSE,
|
||||
.maxAnisotropy = props.limits.maxSamplerAnisotropy,
|
||||
.compareEnable = VK_FALSE,
|
||||
.compareOp = VK_COMPARE_OP_ALWAYS,
|
||||
.minLod = 0.0f,
|
||||
.maxLod = 0.0f,
|
||||
.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK,
|
||||
.unnormalizedCoordinates = VK_FALSE,
|
||||
},
|
||||
NULL,
|
||||
&g_texture_sampler
|
||||
)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
25
src/ptk_vk/image.h
Normal file
25
src/ptk_vk/image.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
#ifndef PTK_PTK_VK_IMAGE_H_
|
||||
#define PTK_PTK_VK_IMAGE_H_
|
||||
|
||||
#include "ptk_option.h"
|
||||
|
||||
#include "vulkan/vulkan_core.h"
|
||||
|
||||
extern VkImage g_texture_image;
|
||||
extern VkDeviceMemory g_texture_image_memory;
|
||||
|
||||
extern VkImageView g_texture_image_view;
|
||||
|
||||
extern VkSampler g_texture_sampler;
|
||||
|
||||
bool vk_create_texture_image(const char *path);
|
||||
|
||||
PTK_OPTION_DEFINE(VkImageView);
|
||||
|
||||
PTK_OPTION(VkImageView) vk_create_image_view(VkImage image, VkFormat format);
|
||||
|
||||
bool vk_create_texture_image_view(void);
|
||||
|
||||
bool vk_create_texture_sampler(void);
|
||||
|
||||
#endif // PTK_PTK_VK_IMAGE_H_
|
|
@ -8,6 +8,7 @@
|
|||
#include "ptk_vk/components.h"
|
||||
#include "ptk_vk/descriptors.h"
|
||||
#include "ptk_vk/device.h"
|
||||
#include "ptk_vk/image.h"
|
||||
#include "ptk_vk/instance.h"
|
||||
#include "ptk_vk/pipeline.h"
|
||||
#include "ptk_vk/render_pass.h"
|
||||
|
@ -55,6 +56,12 @@ bool vk_transfer_vertex_data(void) {
|
|||
void vk_cleanup(void) {
|
||||
vk_cleanup_swapchain();
|
||||
|
||||
vkDestroySampler(g_dev, g_texture_sampler, NULL);
|
||||
vkDestroyImageView(g_dev, g_texture_image_view, NULL);
|
||||
|
||||
vkDestroyImage(g_dev, g_texture_image, NULL);
|
||||
vkFreeMemory(g_dev, g_texture_image_memory, NULL);
|
||||
|
||||
vkDestroyPipeline(g_dev, g_pipeline, NULL);
|
||||
vkDestroyPipelineLayout(g_dev, g_pipeline_layout, NULL);
|
||||
|
||||
|
|
|
@ -115,6 +115,8 @@ PTK_OPTION(VkShaderModule) create_shader_module(VkDevice dev, const PTK_STRING c
|
|||
return PTK_OPTION_SOME(VkShaderModule, shader_module);
|
||||
}
|
||||
|
||||
PTK_ARRAY_DEFINE(VkSpecializationMapEntry);
|
||||
|
||||
bool vk_create_pipeline(void) {
|
||||
const PTK_STRING vert_shader_code = read_spv("target/shaders/shader.vert.spv");
|
||||
const PTK_STRING frag_shader_code = read_spv("target/shaders/shader.frag.spv");
|
||||
|
@ -133,15 +135,27 @@ bool vk_create_pipeline(void) {
|
|||
return false;
|
||||
}
|
||||
|
||||
const VkSpecializationInfo spec_info = {
|
||||
.mapEntryCount = 1,
|
||||
.pMapEntries = &(VkSpecializationMapEntry){
|
||||
PTK_ARRAY(VkSpecializationMapEntry) map_entries = PTK_ARRAY_NEW(VkSpecializationMapEntry, {
|
||||
(VkSpecializationMapEntry){
|
||||
.constantID = 0,
|
||||
.offset = 0,
|
||||
.size = sizeof(int),
|
||||
},
|
||||
.dataSize = sizeof(int),
|
||||
.pData = &(int){PTK_COMPONENT_TYPE_ELLIPSE},
|
||||
(VkSpecializationMapEntry){
|
||||
.constantID = 1,
|
||||
.offset = sizeof(int),
|
||||
.size = sizeof(int),
|
||||
},
|
||||
});
|
||||
|
||||
const VkSpecializationInfo spec_info = {
|
||||
.mapEntryCount = map_entries.size,
|
||||
.pMapEntries = map_entries.data,
|
||||
.dataSize = sizeof(int) * map_entries.size,
|
||||
.pData = (int []){
|
||||
PTK_COMPONENT_TYPE_ELLIPSE,
|
||||
PTK_COMPONENT_TYPE_IMAGE,
|
||||
},
|
||||
};
|
||||
|
||||
const VkPipelineShaderStageCreateInfo shader_stages[] = {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "ptk_vk/backend.h"
|
||||
#include "ptk_vk/device.h"
|
||||
#include "ptk_vk/image.h"
|
||||
#include "ptk_vk/physical_device.h"
|
||||
#include "ptk_vk/render_pass.h"
|
||||
#include "ptk_vk/utils.h"
|
||||
|
@ -183,35 +184,16 @@ bool vk_create_image_views(void) {
|
|||
m_swapchain_image_views = PTK_LIST_NEW(VkImageView, m_swapchain_images.size);
|
||||
|
||||
PTK_LIST_FOR_EACH_E(VkImage, m_swapchain_images, i, swapchain_image, {
|
||||
VK_TRY(false,
|
||||
vkCreateImageView(
|
||||
g_dev,
|
||||
&(VkImageViewCreateInfo){
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||
.pNext = NULL,
|
||||
.flags = 0,
|
||||
.image = swapchain_image,
|
||||
.viewType = VK_IMAGE_VIEW_TYPE_2D,
|
||||
.format = g_swapchain_image_format,
|
||||
.components = (VkComponentMapping){
|
||||
.r = VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
.g = VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
.b = VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
.a = VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
},
|
||||
.subresourceRange = (VkImageSubresourceRange){
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
},
|
||||
},
|
||||
NULL,
|
||||
&m_swapchain_image_views.data[i]
|
||||
)
|
||||
);
|
||||
m_swapchain_image_views.size += 1;
|
||||
PTK_OPTION(VkImageView) image_view_opt = vk_create_image_view(swapchain_image, g_swapchain_image_format);
|
||||
|
||||
if (!image_view_opt.exists) {
|
||||
PTK_ERR("failed to create swapchain image view #%d", i);
|
||||
return false;
|
||||
}
|
||||
|
||||
VkImageView image_view = image_view_opt.value;
|
||||
|
||||
PTK_LIST_ADD(VkImageView, m_swapchain_image_views, image_view);
|
||||
})
|
||||
|
||||
return true;
|
||||
|
|
Loading…
Reference in a new issue