216 lines
12 KiB
C
216 lines
12 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#define VK_NO_PROTOTYPES
|
|
#include <vulkan/vulkan_core.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <dlfcn.h>
|
|
|
|
#ifndef LIBVK
|
|
#define LIBVK "vulkan"
|
|
#endif
|
|
|
|
#define VOLK_IMPLEMENTATION
|
|
#include <volk.h>
|
|
|
|
#define KVF_IMPLEMENTATION
|
|
#define KVF_ENABLE_VALIDATION_LAYERS
|
|
#define KVF_NO_KHR
|
|
#include <kvf.h>
|
|
|
|
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
|
#include <stb_image_write.h>
|
|
|
|
static const uint32_t vertex_shader[] = {
|
|
0x07230203,0x00010000,0x000d000b,0x00000036,0x00000000,0x00020011,0x00000001,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,
|
|
0x00000000,0x0003000e,0x00000000,0x00000001,0x0008000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x00000022,0x00000026,0x00000031,
|
|
0x00030003,0x00000002,0x000001c2,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,
|
|
0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d,
|
|
0x00000000,0x00050005,0x0000000c,0x69736f70,0x6e6f6974,0x00000073,0x00040005,0x00000017,0x6f6c6f63,0x00007372,0x00060005,0x00000020,
|
|
0x505f6c67,0x65567265,0x78657472,0x00000000,0x00060006,0x00000020,0x00000000,0x505f6c67,0x7469736f,0x006e6f69,0x00070006,0x00000020,
|
|
0x00000001,0x505f6c67,0x746e696f,0x657a6953,0x00000000,0x00070006,0x00000020,0x00000002,0x435f6c67,0x4470696c,0x61747369,0x0065636e,
|
|
0x00070006,0x00000020,0x00000003,0x435f6c67,0x446c6c75,0x61747369,0x0065636e,0x00030005,0x00000022,0x00000000,0x00060005,0x00000026,
|
|
0x565f6c67,0x65747265,0x646e4978,0x00007865,0x00050005,0x00000031,0x67617266,0x6f6c6f43,0x00000072,0x00050048,0x00000020,0x00000000,
|
|
0x0000000b,0x00000000,0x00050048,0x00000020,0x00000001,0x0000000b,0x00000001,0x00050048,0x00000020,0x00000002,0x0000000b,0x00000003,
|
|
0x00050048,0x00000020,0x00000003,0x0000000b,0x00000004,0x00030047,0x00000020,0x00000002,0x00040047,0x00000026,0x0000000b,0x0000002a,
|
|
0x00040047,0x00000031,0x0000001e,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,
|
|
0x00040017,0x00000007,0x00000006,0x00000002,0x00040015,0x00000008,0x00000020,0x00000000,0x0004002b,0x00000008,0x00000009,0x00000003,
|
|
0x0004001c,0x0000000a,0x00000007,0x00000009,0x00040020,0x0000000b,0x00000006,0x0000000a,0x0004003b,0x0000000b,0x0000000c,0x00000006,
|
|
0x0004002b,0x00000006,0x0000000d,0x00000000,0x0004002b,0x00000006,0x0000000e,0xbf000000,0x0005002c,0x00000007,0x0000000f,0x0000000d,
|
|
0x0000000e,0x0004002b,0x00000006,0x00000010,0x3f000000,0x0005002c,0x00000007,0x00000011,0x00000010,0x00000010,0x0005002c,0x00000007,
|
|
0x00000012,0x0000000e,0x00000010,0x0006002c,0x0000000a,0x00000013,0x0000000f,0x00000011,0x00000012,0x00040017,0x00000014,0x00000006,
|
|
0x00000003,0x0004001c,0x00000015,0x00000014,0x00000009,0x00040020,0x00000016,0x00000006,0x00000015,0x0004003b,0x00000016,0x00000017,
|
|
0x00000006,0x0004002b,0x00000006,0x00000018,0x3f800000,0x0006002c,0x00000014,0x00000019,0x00000018,0x0000000d,0x0000000d,0x0006002c,
|
|
0x00000014,0x0000001a,0x0000000d,0x00000018,0x0000000d,0x0006002c,0x00000014,0x0000001b,0x0000000d,0x0000000d,0x00000018,0x0006002c,
|
|
0x00000015,0x0000001c,0x00000019,0x0000001a,0x0000001b,0x00040017,0x0000001d,0x00000006,0x00000004,0x0004002b,0x00000008,0x0000001e,
|
|
0x00000001,0x0004001c,0x0000001f,0x00000006,0x0000001e,0x0006001e,0x00000020,0x0000001d,0x00000006,0x0000001f,0x0000001f,0x00040020,
|
|
0x00000021,0x00000003,0x00000020,0x0004003b,0x00000021,0x00000022,0x00000003,0x00040015,0x00000023,0x00000020,0x00000001,0x0004002b,
|
|
0x00000023,0x00000024,0x00000000,0x00040020,0x00000025,0x00000001,0x00000023,0x0004003b,0x00000025,0x00000026,0x00000001,0x00040020,
|
|
0x00000028,0x00000006,0x00000007,0x00040020,0x0000002e,0x00000003,0x0000001d,0x00040020,0x00000030,0x00000003,0x00000014,0x0004003b,
|
|
0x00000030,0x00000031,0x00000003,0x00040020,0x00000033,0x00000006,0x00000014,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,
|
|
0x000200f8,0x00000005,0x0003003e,0x0000000c,0x00000013,0x0003003e,0x00000017,0x0000001c,0x0004003d,0x00000023,0x00000027,0x00000026,
|
|
0x00050041,0x00000028,0x00000029,0x0000000c,0x00000027,0x0004003d,0x00000007,0x0000002a,0x00000029,0x00050051,0x00000006,0x0000002b,
|
|
0x0000002a,0x00000000,0x00050051,0x00000006,0x0000002c,0x0000002a,0x00000001,0x00070050,0x0000001d,0x0000002d,0x0000002b,0x0000002c,
|
|
0x0000000d,0x00000018,0x00050041,0x0000002e,0x0000002f,0x00000022,0x00000024,0x0003003e,0x0000002f,0x0000002d,0x0004003d,0x00000023,
|
|
0x00000032,0x00000026,0x00050041,0x00000033,0x00000034,0x00000017,0x00000032,0x0004003d,0x00000014,0x00000035,0x00000034,0x0003003e,
|
|
0x00000031,0x00000035,0x000100fd,0x00010038
|
|
};
|
|
|
|
static const uint32_t fragment_shader[] = {
|
|
0x07230203,0x00010000,0x000d000b,0x00000013,0x00000000,0x00020011,0x00000001,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,
|
|
0x00000000,0x0003000e,0x00000000,0x00000001,0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000009,0x0000000c,0x00030010,
|
|
0x00000004,0x00000007,0x00030003,0x00000002,0x000001c2,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,
|
|
0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,
|
|
0x00000004,0x6e69616d,0x00000000,0x00050005,0x00000009,0x4374756f,0x726f6c6f,0x00000000,0x00050005,0x0000000c,0x67617266,0x6f6c6f43,
|
|
0x00000072,0x00040047,0x00000009,0x0000001e,0x00000000,0x00040047,0x0000000c,0x0000001e,0x00000000,0x00020013,0x00000002,0x00030021,
|
|
0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000004,0x00040020,0x00000008,0x00000003,
|
|
0x00000007,0x0004003b,0x00000008,0x00000009,0x00000003,0x00040017,0x0000000a,0x00000006,0x00000003,0x00040020,0x0000000b,0x00000001,
|
|
0x0000000a,0x0004003b,0x0000000b,0x0000000c,0x00000001,0x0004002b,0x00000006,0x0000000e,0x3f800000,0x00050036,0x00000002,0x00000004,
|
|
0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x0000000a,0x0000000d,0x0000000c,0x00050051,0x00000006,0x0000000f,0x0000000d,
|
|
0x00000000,0x00050051,0x00000006,0x00000010,0x0000000d,0x00000001,0x00050051,0x00000006,0x00000011,0x0000000d,0x00000002,0x00070050,
|
|
0x00000007,0x00000012,0x0000000f,0x00000010,0x00000011,0x0000000e,0x0003003e,0x00000009,0x00000012,0x000100fd,0x00010038
|
|
};
|
|
|
|
VkDeviceMemory CreateAndBindMemoryToBuffer(VkPhysicalDevice physical_device, VkDevice device, VkBuffer buffer, VkMemoryPropertyFlags props)
|
|
{
|
|
VkMemoryRequirements requirements;
|
|
vkGetBufferMemoryRequirements(device, buffer, &requirements);
|
|
|
|
VkMemoryAllocateInfo alloc_info = {0};
|
|
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
|
alloc_info.allocationSize = requirements.size;
|
|
alloc_info.memoryTypeIndex = kvfFindMemoryType(physical_device, requirements.memoryTypeBits, props);
|
|
|
|
VkDeviceMemory memory;
|
|
kvfCheckVk(vkAllocateMemory(device, &alloc_info, NULL, &memory));
|
|
kvfCheckVk(vkBindBufferMemory(device, buffer, memory, 0));
|
|
return memory;
|
|
}
|
|
|
|
VkDeviceMemory CreateAndBindMemoryToImage(VkPhysicalDevice physical_device, VkDevice device, VkImage image, VkMemoryPropertyFlags props)
|
|
{
|
|
VkMemoryRequirements requirements;
|
|
vkGetImageMemoryRequirements(device, image, &requirements);
|
|
|
|
VkMemoryAllocateInfo alloc_info = {0};
|
|
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
|
alloc_info.allocationSize = requirements.size;
|
|
alloc_info.memoryTypeIndex = kvfFindMemoryType(physical_device, requirements.memoryTypeBits, props);
|
|
|
|
VkDeviceMemory memory;
|
|
kvfCheckVk(vkAllocateMemory(device, &alloc_info, NULL, &memory));
|
|
kvfCheckVk(vkBindImageMemory(device, image, memory, 0));
|
|
return memory;
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
volkInitialize();
|
|
|
|
void* lib = dlopen("./zig-out/lib/lib" LIBVK ".so", RTLD_NOW | RTLD_LOCAL);
|
|
if(!lib)
|
|
{
|
|
fprintf(stderr, "Could not open driver lib: %s\n", dlerror());
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
puts("openned ./zig-out/lib/lib" LIBVK ".so");
|
|
|
|
VkDirectDriverLoadingInfoLUNARG direct_loading_info = {};
|
|
direct_loading_info.sType = VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_INFO_LUNARG;
|
|
direct_loading_info.pfnGetInstanceProcAddr = (PFN_vkGetInstanceProcAddrLUNARG)(dlsym(lib, "vk_icdGetInstanceProcAddr"));
|
|
|
|
VkDirectDriverLoadingListLUNARG direct_driver_list = {};
|
|
direct_driver_list.sType = VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_LIST_LUNARG;
|
|
direct_driver_list.mode = VK_DIRECT_DRIVER_LOADING_MODE_EXCLUSIVE_LUNARG;
|
|
direct_driver_list.driverCount = 1;
|
|
direct_driver_list.pDrivers = &direct_loading_info;
|
|
|
|
const char* extensions[] = { VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME };
|
|
|
|
VkInstance instance = kvfCreateInstanceNext(extensions, 1, &direct_driver_list);
|
|
volkLoadInstance(instance);
|
|
|
|
VkPhysicalDevice physical_device = kvfPickGoodPhysicalDevice(instance, VK_NULL_HANDLE, NULL, 0);
|
|
VkDevice device = kvfCreateDevice(physical_device, NULL, 0, NULL);
|
|
volkLoadDevice(device);
|
|
|
|
VkImage image = kvfCreateImage(device, 600, 400, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TILING_LINEAR, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, KVF_IMAGE_COLOR);
|
|
VkDeviceMemory memory = CreateAndBindMemoryToImage(physical_device, device, image, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
|
|
VkImageView image_view = kvfCreateImageView(device, image, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT, 1);
|
|
|
|
VkAttachmentDescription attachment = kvfBuildAttachmentDescription(KVF_IMAGE_COLOR, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true, VK_SAMPLE_COUNT_1_BIT);
|
|
VkRenderPass renderpass = kvfCreateRenderPass(device, &attachment, 1, VK_PIPELINE_BIND_POINT_GRAPHICS);
|
|
|
|
VkFramebuffer framebuffer = kvfCreateFramebuffer(device, renderpass, &image_view, 1, (VkExtent2D){ .width = 600, .height = 400 });
|
|
|
|
VkShaderModule vertex_shader_module = kvfCreateShaderModule(device, (uint32_t*)vertex_shader, sizeof(vertex_shader) / sizeof(uint32_t));
|
|
VkShaderModule fragment_shader_module = kvfCreateShaderModule(device, (uint32_t*)fragment_shader, sizeof(fragment_shader) / sizeof(uint32_t));
|
|
|
|
VkPipelineLayout pipeline_layout = kvfCreatePipelineLayout(device, NULL, 0, NULL, 0);
|
|
|
|
KvfGraphicsPipelineBuilder* builder = kvfCreateGPipelineBuilder();
|
|
kvfGPipelineBuilderSetInputTopology(builder, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
|
|
kvfGPipelineBuilderSetPolygonMode(builder, VK_POLYGON_MODE_FILL, 1.0f);
|
|
kvfGPipelineBuilderSetCullMode(builder, VK_CULL_MODE_NONE, VK_FRONT_FACE_CLOCKWISE);
|
|
kvfGPipelineBuilderSetMultisampling(builder, VK_SAMPLE_COUNT_1_BIT);
|
|
kvfGPipelineBuilderAddShaderStage(builder, VK_SHADER_STAGE_VERTEX_BIT, vertex_shader_module, "main");
|
|
kvfGPipelineBuilderAddShaderStage(builder, VK_SHADER_STAGE_FRAGMENT_BIT, fragment_shader_module, "main");
|
|
kvfGPipelineBuilderDisableDepthTest(builder);
|
|
kvfGPipelineBuilderDisableBlending(builder);
|
|
|
|
VkPipeline pipeline = kvfCreateGraphicsPipeline(device, VK_NULL_HANDLE, pipeline_layout, builder, renderpass);
|
|
|
|
kvfDestroyGPipelineBuilder(builder);
|
|
kvfDestroyShaderModule(device, vertex_shader_module);
|
|
kvfDestroyShaderModule(device, fragment_shader_module);
|
|
|
|
VkCommandBuffer cmd = kvfCreateCommandBuffer(device);
|
|
|
|
kvfCheckVk(vkResetCommandBuffer(cmd, 0));
|
|
|
|
kvfBeginCommandBuffer(cmd, 0);
|
|
{
|
|
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
|
VkClearValue clear_color = {{{0.0f, 0.0f, 0.0f, 1.0f}}};
|
|
kvfBeginRenderPass(renderpass, cmd, framebuffer, (VkExtent2D){ .width = 600, .height = 400 }, &clear_color, 1);
|
|
VkViewport viewport = { 0 };
|
|
viewport.width = 600;
|
|
viewport.height = 400;
|
|
viewport.maxDepth = 1.0f;
|
|
vkCmdSetViewport(cmd, 0, 1, &viewport);
|
|
VkRect2D scissor = { 0 };
|
|
scissor.extent = (VkExtent2D){ .width = 600, .height = 400 };
|
|
vkCmdSetScissor(cmd, 0, 1, &scissor);
|
|
vkCmdDraw(cmd, 3, 1, 0, 0);
|
|
vkCmdEndRenderPass(cmd);
|
|
}
|
|
kvfEndCommandBuffer(cmd);
|
|
|
|
VkPipelineStageFlags wait_stages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
|
|
kvfSubmitCommandBuffer(device, cmd, KVF_GRAPHICS_QUEUE, VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, wait_stages);
|
|
vkDeviceWaitIdle(device);
|
|
|
|
void* map = NULL;
|
|
kvfCheckVk(vkMapMemory(device, memory, 0, VK_WHOLE_SIZE, 0, &map));
|
|
if(!stbi_write_png("res.png", 256, 256, 4, map, 256 * 4))
|
|
fprintf(stderr, "Failed to write result image to file\n");
|
|
vkUnmapMemory(device, memory);
|
|
|
|
vkDeviceWaitIdle(device);
|
|
kvfDestroyPipelineLayout(device, pipeline_layout);
|
|
kvfDestroyPipeline(device, pipeline);
|
|
kvfDestroyRenderPass(device, renderpass);
|
|
kvfDestroyImageView(device, image_view);
|
|
kvfDestroyImage(device, image);
|
|
vkFreeMemory(device, memory, NULL);
|
|
kvfDestroyFramebuffer(device, framebuffer);
|
|
|
|
kvfDestroyDevice(device);
|
|
kvfDestroyInstance(instance);
|
|
|
|
dlclose(lib);
|
|
return 0;
|
|
}
|