/* * gcc -lvulkan vertex-input-64bit.c -o vertex-input-64bit */ #include #include #include #include #include #define VK_USE_PLATFORM_XCB_KHR #include #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*x)) static const char * const instance_extensions[] = { VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_XCB_SURFACE_EXTENSION_NAME, }; static const char * const device_extensions[] = { VK_KHR_SWAPCHAIN_EXTENSION_NAME, }; static VkInstance create_instance(void) { VkApplicationInfo application_info; VkInstanceCreateInfo instance_info; VkInstance instance; VkResult vr; application_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; application_info.pNext = NULL; application_info.pApplicationName = "vk-dump-shader"; application_info.applicationVersion = 0; application_info.pEngineName = NULL; application_info.engineVersion = 0; application_info.apiVersion = VK_API_VERSION_1_0; instance_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; instance_info.pNext = NULL; instance_info.flags = 0; instance_info.pApplicationInfo = &application_info; instance_info.enabledLayerCount = 0; instance_info.ppEnabledLayerNames = NULL; instance_info.enabledExtensionCount = ARRAY_SIZE(instance_extensions); instance_info.ppEnabledExtensionNames = instance_extensions; if ((vr = vkCreateInstance(&instance_info, NULL, &instance))) { fprintf(stderr, "Failed to create Vulkan instance, vr %d.\n", vr); return VK_NULL_HANDLE; } return instance; } static VkPhysicalDevice select_physical_device(VkInstance instance) { VkPhysicalDevice *physical_devices, selected_device; uint32_t count; unsigned int i; VkResult vr; count = 0; if ((vr = vkEnumeratePhysicalDevices(instance, &count, NULL)) < 0) { fprintf(stderr, "Failed to enumerate physical devices, vr %d.\n", vr); return VK_NULL_HANDLE; } if (!count) { fprintf(stderr, "No physical device available.\n"); return VK_NULL_HANDLE; } if (!(physical_devices = calloc(count, sizeof(*physical_devices)))) return VK_NULL_HANDLE; if ((vr = vkEnumeratePhysicalDevices(instance, &count, physical_devices)) < 0) { fprintf(stderr, "Failed to enumerate physical devices, vr %d.\n", vr); free(physical_devices); return VK_NULL_HANDLE; } selected_device = physical_devices[0]; free(physical_devices); return selected_device; } static VkDevice create_device(VkInstance instance, VkPhysicalDevice physical_device) { VkQueueFamilyProperties *queue_properties; VkPhysicalDeviceFeatures device_features; VkDeviceQueueCreateInfo *queue_info; VkDeviceCreateInfo device_info; uint32_t queue_family_count; VkDevice device; unsigned int i; VkResult vr; vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count, NULL); if (!(queue_properties = calloc(queue_family_count, sizeof(*queue_properties)))) return VK_NULL_HANDLE; vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count, queue_properties); if (!(queue_info = calloc(queue_family_count, sizeof(*queue_info)))) { free(queue_properties); return VK_NULL_HANDLE; } for (i = 0; i < queue_family_count; ++i) { static float priorities[] = {1.0f}; queue_info[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; queue_info[i].pNext = NULL; queue_info[i].flags = 0; queue_info[i].queueFamilyIndex = i; queue_info[i].queueCount = 1; queue_info[i].pQueuePriorities = priorities; } free(queue_properties); vkGetPhysicalDeviceFeatures(physical_device, &device_features); device_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; device_info.pNext = NULL; device_info.flags = 0; device_info.queueCreateInfoCount = queue_family_count; device_info.pQueueCreateInfos = queue_info; device_info.enabledLayerCount = 0; device_info.ppEnabledLayerNames = NULL; device_info.enabledExtensionCount = ARRAY_SIZE(device_extensions); device_info.ppEnabledExtensionNames = device_extensions; device_info.pEnabledFeatures = &device_features; vr = vkCreateDevice(physical_device, &device_info, NULL, &device); free(queue_info); if (vr < 0) { fprintf(stderr, "Failed to create Vulkan device, vr %d.\n", vr); return VK_NULL_HANDLE; } return device; } static VkShaderModule create_shader_module(VkDevice device, size_t size, const void *code) { VkShaderModuleCreateInfo create_info; VkShaderModule module; VkResult vr; memset(&create_info, 0, sizeof(create_info)); create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; create_info.codeSize = size; create_info.pCode = code; if ((vr = vkCreateShaderModule(device, &create_info, NULL, &module)) < 0) { fprintf(stderr, "Failed to create shader module, vr %d.\n", vr); return VK_NULL_HANDLE; } return module; } static VkPipeline create_graphics_pipeline(VkDevice device, VkPipelineLayout layout, VkShaderModule vs, VkShaderModule fs, VkRenderPass render_pass) { VkPipelineRasterizationStateCreateInfo rasterization_state; VkPipelineMultisampleStateCreateInfo multisample_state; VkPipelineInputAssemblyStateCreateInfo input_assembly; VkPipelineColorBlendAttachmentState blend_attachment; VkPipelineShaderStageCreateInfo stage_create_info[2]; VkVertexInputAttributeDescription input_attribs[4]; VkVertexInputBindingDescription input_bindings[1]; VkPipelineVertexInputStateCreateInfo vertex_input; VkPipelineViewportStateCreateInfo viewport_state; VkPipelineColorBlendStateCreateInfo blend_state; VkGraphicsPipelineCreateInfo create_info; VkViewport viewports[1]; VkRect2D scissors[1]; VkPipeline pipeline; VkResult vr; memset(stage_create_info, 0, sizeof(stage_create_info)); stage_create_info[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; stage_create_info[0].stage = VK_SHADER_STAGE_VERTEX_BIT; stage_create_info[0].module = vs; stage_create_info[0].pName = "main"; stage_create_info[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; stage_create_info[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; stage_create_info[1].module = fs; stage_create_info[1].pName = "main"; memset(input_bindings, 0, sizeof(input_bindings)); memset(input_attribs, 0, sizeof(input_attribs)); input_attribs[0].location = 0; input_attribs[0].offset = 0; input_attribs[0].format = VK_FORMAT_R64G64B64A64_SFLOAT; input_attribs[1].location = 2; input_attribs[1].offset = 32; input_attribs[1].format = VK_FORMAT_R64G64B64A64_SFLOAT; input_attribs[2].location = 4; input_attribs[2].offset = 64; input_attribs[2].format = VK_FORMAT_R64G64B64A64_SFLOAT; input_attribs[3].location = 6; input_attribs[3].offset = 96; input_attribs[3].format = VK_FORMAT_R64G64B64A64_SFLOAT; memset(&vertex_input, 0, sizeof(vertex_input)); vertex_input.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; vertex_input.vertexBindingDescriptionCount = ARRAY_SIZE(input_bindings); vertex_input.pVertexBindingDescriptions = input_bindings; vertex_input.vertexAttributeDescriptionCount = ARRAY_SIZE(input_attribs); vertex_input.pVertexAttributeDescriptions = input_attribs; memset(&input_assembly, 0, sizeof(input_assembly)); input_assembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; input_assembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; viewports[0].x = 0.0f; viewports[0].y = 0.0f; viewports[0].width = 32.0f; viewports[0].height = 32.0f; viewports[0].minDepth = 0.0f; viewports[0].maxDepth = 1.0f; scissors[0].offset.x = 0; scissors[0].offset.y = 0; scissors[0].extent.width = 32; scissors[0].extent.height = 32; memset(&viewport_state, 0, sizeof(viewport_state)); viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; viewport_state.viewportCount = 1; viewport_state.pViewports = viewports; viewport_state.scissorCount = 1; viewport_state.pScissors = scissors; memset(&rasterization_state, 0, sizeof(rasterization_state)); rasterization_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; rasterization_state.polygonMode = VK_POLYGON_MODE_FILL; rasterization_state.cullMode = VK_CULL_MODE_NONE; rasterization_state.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; rasterization_state.lineWidth = 1.0f; memset(&multisample_state, 0, sizeof(multisample_state)); multisample_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; multisample_state.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; memset(&blend_attachment, 0, sizeof(blend_attachment)); blend_attachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; memset(&blend_state, 0, sizeof(blend_state)); blend_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; blend_state.attachmentCount = 1; blend_state.pAttachments = &blend_attachment; memset(&create_info, 0, sizeof(create_info)); create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; create_info.stageCount = 2; create_info.pStages = stage_create_info; create_info.pVertexInputState = &vertex_input; create_info.pInputAssemblyState = &input_assembly; create_info.pViewportState = &viewport_state; create_info.pRasterizationState = &rasterization_state; create_info.pMultisampleState = &multisample_state; create_info.pColorBlendState = &blend_state; create_info.layout = layout; create_info.renderPass = render_pass; create_info.basePipelineIndex = -1; if ((vr = vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &create_info, NULL, &pipeline)) < 0) { fprintf(stderr, "Failed to create pipeline, vr %d.\n", vr); return VK_NULL_HANDLE; } return pipeline; } static VkRenderPass create_render_pass(VkDevice device) { VkAttachmentReference attachment_ref; VkAttachmentDescription attachment; VkRenderPassCreateInfo pass_info; VkSubpassDescription subpass; VkRenderPass render_pass; VkResult vr; memset(&attachment, 0, sizeof(attachment)); attachment.format = VK_FORMAT_R32G32B32A32_SFLOAT; attachment.samples = VK_SAMPLE_COUNT_1_BIT; attachment.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; attachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; attachment_ref.attachment = 0; attachment_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; memset(&subpass, 0, sizeof(subpass)); subpass.flags = 0; subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; subpass.colorAttachmentCount = 1; subpass.pColorAttachments = &attachment_ref; memset(&pass_info, 0, sizeof(pass_info)); pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; pass_info.attachmentCount = 1; pass_info.pAttachments = &attachment; pass_info.subpassCount = 1; pass_info.pSubpasses = &subpass; if ((vr = vkCreateRenderPass(device, &pass_info, NULL, &render_pass)) < 0) { fprintf(stderr, "Failed to create render pass, vr %d.\n", vr); return VK_NULL_HANDLE; } return render_pass; } static VkDescriptorSetLayout create_descriptor_set_layout(VkDevice device) { VkDescriptorSetLayoutCreateInfo create_info; VkDescriptorSetLayoutBinding bindings[2]; VkDescriptorSetLayout layout; unsigned int i; VkResult vr; create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; create_info.pNext = NULL; create_info.flags = 0; create_info.bindingCount = ARRAY_SIZE(bindings); create_info.pBindings = bindings; for (i = 0; i < ARRAY_SIZE(bindings); ++i) { bindings[i].binding = i; bindings[i].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; bindings[i].descriptorCount = 1; bindings[i].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; bindings[i].pImmutableSamplers = NULL; } if ((vr = vkCreateDescriptorSetLayout(device, &create_info, NULL, &layout) < 0)) { fprintf(stderr, "Failed to create descriptor set, vr %d.\n", vr); return VK_NULL_HANDLE; } return layout; } static VkDescriptorPool create_descriptor_pool(VkDevice device) { VkDescriptorPoolCreateInfo create_info; VkDescriptorPoolSize pool_sizes[2]; VkDescriptorPool pool; VkResult vr; create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; create_info.pNext = NULL; create_info.flags = 0; create_info.maxSets = 32; create_info.poolSizeCount = ARRAY_SIZE(pool_sizes); create_info.pPoolSizes = pool_sizes; pool_sizes[0].type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; pool_sizes[0].descriptorCount = 32; pool_sizes[1].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; pool_sizes[1].descriptorCount = 32; if ((vr = vkCreateDescriptorPool(device, &create_info, NULL, &pool)) < 0) { fprintf(stderr, "Failed to create descriptor pool, vr %d.\n", vr); return VK_NULL_HANDLE; } return pool; } static VkDescriptorSet allocate_descriptor_set(VkDevice device, VkDescriptorPool pool, VkDescriptorSetLayout set_layout) { VkDescriptorSetAllocateInfo allocate_info; VkDescriptorSet set; VkResult vr; allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; allocate_info.pNext = NULL; allocate_info.descriptorPool = pool; allocate_info.descriptorSetCount = 1; allocate_info.pSetLayouts = &set_layout; if ((vr = vkAllocateDescriptorSets(device, &allocate_info, &set)) < 0) { fprintf(stderr, "Failed to allocate descriptor set, vr %d.\n", vr); return VK_NULL_HANDLE; } return set; } static VkPipelineLayout create_pipeline_layout(VkDevice device, VkDescriptorSetLayout set_layout) { VkPipelineLayoutCreateInfo create_info; VkPipelineLayout layout; VkResult vr; memset(&create_info, 0, sizeof(create_info)); create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; if (set_layout) { create_info.setLayoutCount = 1; create_info.pSetLayouts = &set_layout; } if ((vr = vkCreatePipelineLayout(device, &create_info, NULL, &layout)) < 0) { fprintf(stderr, "Failed to create pipeline layout, vr %d.\n", vr); return VK_NULL_HANDLE; } return layout; } static VkCommandPool create_command_pool(VkDevice device, uint32_t queue_index) { VkCommandPoolCreateInfo create_info; VkCommandPool pool; VkResult vr; create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; create_info.pNext = NULL; create_info.flags = 0; create_info.queueFamilyIndex = queue_index; if ((vr = vkCreateCommandPool(device, &create_info, NULL, &pool)) < 0) { fprintf(stderr, "Failed to create command pool, vr %d.\n", vr); return VK_NULL_HANDLE; } return pool; } static VkCommandBuffer allocate_command_buffer(VkDevice device, VkCommandPool pool) { VkCommandBufferAllocateInfo allocate_info; VkCommandBuffer command_buffer; VkResult vr; allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; allocate_info.pNext = NULL; allocate_info.commandPool = pool; allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; allocate_info.commandBufferCount = 1; if ((vr = vkAllocateCommandBuffers(device, &allocate_info, &command_buffer)) < 0) { fprintf(stderr, "Failed to allocate command buffer, vr %d.\n", vr); return VK_NULL_HANDLE; } return command_buffer; } static void begin_command_buffer(VkCommandBuffer command_buffer) { VkCommandBufferBeginInfo begin_info; VkResult vr; begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; begin_info.pNext = NULL; begin_info.flags = 0; begin_info.pInheritanceInfo = NULL; if ((vr = vkBeginCommandBuffer(command_buffer, &begin_info)) < 0) { fprintf(stderr, "Failed to begin command buffer, vr %d.\n", vr); } assert(vr == VK_SUCCESS); } static void end_command_buffer(VkCommandBuffer command_buffer) { VkResult vr; if ((vr = vkEndCommandBuffer(command_buffer)) < 0) { fprintf(stderr, "Failed to end command buffer, vr %d.\n", vr); } assert(vr == VK_SUCCESS); } static void submit_commands(VkDevice device, VkQueue queue, VkCommandBuffer command_buffer, bool wait) { VkFenceCreateInfo create_info; VkSubmitInfo submit_info; VkFence fence; VkResult vr; fence = VK_NULL_HANDLE; if (wait) { create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; create_info.pNext = NULL; create_info.flags = 0; if ((vr = vkCreateFence(device, &create_info, NULL, &fence)) < 0) { fprintf(stderr, "Failed to create fence, vr %d.\n", vr); return; } } memset(&submit_info, 0, sizeof(submit_info)); submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submit_info.pNext = NULL; submit_info.commandBufferCount = 1; submit_info.pCommandBuffers = &command_buffer; if ((vr = vkQueueSubmit(queue, 1, &submit_info, fence) < 0)) { fprintf(stderr, "Failed to submit commands, vr %d.\n", vr); vkDestroyFence(device, fence, NULL); return; } if ((vr = vkWaitForFences(device, 1, &fence, VK_FALSE, ~0u)) < 0) { fprintf(stderr, "Failed to wait for fences, vr %d.\n", vr); return; } vkDestroyFence(device, fence, NULL); } static VkBuffer create_buffer(VkDevice device, VkDeviceSize size, VkBufferUsageFlags usage) { VkBufferCreateInfo buffer_info; VkBuffer buffer; VkResult vr; buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; buffer_info.pNext = NULL; buffer_info.flags = 0; buffer_info.size = size; buffer_info.usage = usage; buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; buffer_info.queueFamilyIndexCount = 0; buffer_info.pQueueFamilyIndices = 0; if ((vr = vkCreateBuffer(device, &buffer_info, NULL, &buffer)) < 0) { fprintf(stderr, "Failed to create Vulkan buffer, vr %d.\n", vr); return VK_NULL_HANDLE; } return buffer; } static unsigned int select_memory_type(VkDevice device, VkPhysicalDevice physical_device, uint32_t memory_type_mask, VkMemoryPropertyFlags required_flags) { VkPhysicalDeviceMemoryProperties memory_info; unsigned int i; vkGetPhysicalDeviceMemoryProperties(physical_device, &memory_info); for (i = 0; i < memory_info.memoryTypeCount; ++i) { if (!(memory_type_mask & (1u << i))) continue; if ((memory_info.memoryTypes[i].propertyFlags & required_flags) == required_flags) return i; } return ~0u; } static VkDeviceMemory allocate_device_memory(VkDevice device, VkPhysicalDevice physical_device, const VkMemoryRequirements *memory_requirements, VkMemoryPropertyFlags memory_flags) { VkMemoryAllocateInfo allocate_info; VkDeviceMemory vk_memory; VkResult vr; allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; allocate_info.pNext = NULL; allocate_info.allocationSize = memory_requirements->size; allocate_info.memoryTypeIndex = select_memory_type(device, physical_device, memory_requirements->memoryTypeBits, memory_flags); if (allocate_info.memoryTypeIndex == ~0u) { fprintf(stderr, "Failed to find suitable memory type (allowed types %#x).\n", memory_requirements->memoryTypeBits); return VK_NULL_HANDLE; } if ((vr = vkAllocateMemory(device, &allocate_info, NULL, &vk_memory)) < 0) { fprintf(stderr, "Failed to allocate device memory, vr %d.\n", vr); return VK_NULL_HANDLE; } return vk_memory; } static VkDeviceMemory allocate_buffer_memory(VkDevice device, VkPhysicalDevice physical_device, VkBuffer buffer, VkMemoryPropertyFlags memory_flags) { VkMemoryRequirements memory_requirements; VkDeviceMemory memory; VkResult vr; vkGetBufferMemoryRequirements(device, buffer, &memory_requirements); memory = allocate_device_memory(device, physical_device, &memory_requirements, memory_flags); assert(memory != VK_NULL_HANDLE); if ((vr = vkBindBufferMemory(device, buffer, memory, 0)) < 0) { fprintf(stderr, "Failed to bind memory, vr %d.\n", vr); vkFreeMemory(device, memory, NULL); return VK_NULL_HANDLE; } return memory; } static VkBufferView create_buffer_view(VkDevice device, VkBuffer buffer, VkFormat format) { VkBufferViewCreateInfo create_info; VkBufferView buffer_view; VkResult vr; create_info.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO; create_info.pNext = NULL; create_info.flags = 0; create_info.buffer = buffer; create_info.format = format; create_info.offset = 0; create_info.range = VK_WHOLE_SIZE; if ((vr = vkCreateBufferView(device, &create_info, NULL, &buffer_view)) < 0) { fprintf(stderr, "Failed to create buffer view, vr %d.\n", vr); return VK_NULL_HANDLE; } return buffer_view; } static VkImage create_image(VkDevice device, VkFormat format, unsigned int width, unsigned int height, VkImageUsageFlags usage) { VkImageCreateInfo image_info; VkImage image; VkResult vr; image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; image_info.pNext = NULL; image_info.flags = 0; image_info.imageType = VK_IMAGE_TYPE_2D; image_info.format = format; image_info.extent.width = width; image_info.extent.height = height; image_info.extent.depth = 1; image_info.arrayLayers = 1; image_info.mipLevels = 1; image_info.samples = VK_SAMPLE_COUNT_1_BIT; image_info.tiling = VK_IMAGE_TILING_OPTIMAL; image_info.usage = usage; image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; image_info.queueFamilyIndexCount = 0; image_info.pQueueFamilyIndices = NULL; image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; if ((vr = vkCreateImage(device, &image_info, NULL, &image)) < 0) { fprintf(stderr, "Failed to create Vulkan image, vr %d.\n", vr); return VK_NULL_HANDLE; } return image; } static VkDeviceMemory allocate_image_memory(VkDevice device, VkPhysicalDevice physical_device, VkImage image, VkMemoryPropertyFlags memory_flags) { VkMemoryRequirements memory_requirements; VkDeviceMemory memory; VkResult vr; vkGetImageMemoryRequirements(device, image, &memory_requirements); memory = allocate_device_memory(device, physical_device, &memory_requirements, memory_flags); assert(memory != VK_NULL_HANDLE); if ((vr = vkBindImageMemory(device, image, memory, 0)) < 0) { fprintf(stderr, "Failed to bind memory, vr %d.\n", vr); vkFreeMemory(device, memory, NULL); return VK_NULL_HANDLE; } return memory; } static VkImageView create_image_view(VkDevice device, VkImage image, VkFormat format) { VkImageViewCreateInfo create_info; VkImageView image_view; VkResult vr; create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; create_info.pNext = NULL; create_info.flags = 0; create_info.image = image; create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; create_info.format = format; create_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; create_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; create_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; create_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; create_info.subresourceRange.baseMipLevel = 0; create_info.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS; create_info.subresourceRange.baseArrayLayer = 0; create_info.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; if ((vr = vkCreateImageView(device, &create_info, NULL, &image_view)) < 0) { fprintf(stderr, "Failed to create image view, vr %d.\n", vr); return VK_NULL_HANDLE; } return image_view; } static VkFramebuffer create_framebuffer(VkDevice device, VkRenderPass render_pass, VkImageView image_view, unsigned int width, unsigned int height) { VkFramebufferCreateInfo create_info; VkFramebuffer framebuffer; VkResult vr; create_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; create_info.pNext = NULL; create_info.flags = 0; create_info.renderPass = render_pass; create_info.attachmentCount = 1; create_info.pAttachments = &image_view; create_info.width = width; create_info.height = height; create_info.layers = 1; if ((vr = vkCreateFramebuffer(device, &create_info, NULL, &framebuffer)) < 0) { fprintf(stderr, "Failed to create framebuffer, vr %d.\n", vr); return VK_NULL_HANDLE; } return framebuffer; } static void cmd_buffer_barrier(VkCommandBuffer command_buffer, VkBuffer buffer, VkPipelineStageFlags src_stage_mask, VkPipelineStageFlags dst_stage_mask, VkAccessFlags src_access_mask, VkAccessFlags dst_access_mask) { VkBufferMemoryBarrier buffer_barrier; buffer_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; buffer_barrier.pNext = NULL; buffer_barrier.srcAccessMask = src_access_mask; buffer_barrier.dstAccessMask = dst_access_mask; buffer_barrier.srcQueueFamilyIndex = 0; buffer_barrier.dstQueueFamilyIndex = 0; buffer_barrier.buffer = buffer; buffer_barrier.offset = 0; buffer_barrier.size = VK_WHOLE_SIZE; vkCmdPipelineBarrier(command_buffer, src_stage_mask, dst_stage_mask, 0, 0, NULL, 1, &buffer_barrier, 0, NULL); } static void cmd_image_barrier(VkCommandBuffer command_buffer, VkImage image, VkPipelineStageFlags src_stage_mask, VkPipelineStageFlags dst_stage_mask, VkAccessFlags src_access_mask, VkAccessFlags dst_access_mask, VkImageLayout old_layout, VkImageLayout new_layout) { VkImageMemoryBarrier image_barrier; image_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; image_barrier.pNext = NULL; image_barrier.srcAccessMask = src_access_mask; image_barrier.dstAccessMask = dst_access_mask; image_barrier.oldLayout = old_layout; image_barrier.newLayout = new_layout; image_barrier.srcQueueFamilyIndex = 0; image_barrier.dstQueueFamilyIndex = 0; image_barrier.image = image; image_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; image_barrier.subresourceRange.baseMipLevel = 0; image_barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS; image_barrier.subresourceRange.baseArrayLayer = 0; image_barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; vkCmdPipelineBarrier(command_buffer, src_stage_mask, dst_stage_mask, 0, 0, NULL, 0, NULL, 1, &image_barrier); } static void cmd_copy_buffer(VkCommandBuffer command_buffer, VkBuffer src_buffer, VkBuffer dst_buffer, VkDeviceSize src_offset, VkDeviceSize dst_offset, VkDeviceSize size) { VkBufferCopy region; region.srcOffset = src_offset; region.dstOffset = dst_offset; region.size = size; vkCmdCopyBuffer(command_buffer, src_buffer, dst_buffer, 1, ®ion); } static void cmd_copy_image_to_buffer(VkCommandBuffer command_buffer, VkImage src_image, VkImageLayout image_layout, VkBuffer dst_buffer, unsigned int width, unsigned int height) { VkBufferImageCopy region; region.bufferOffset = 0; region.bufferRowLength = 0; region.bufferImageHeight = 0; region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; region.imageSubresource.mipLevel = 0; region.imageSubresource.baseArrayLayer = 0; region.imageSubresource.layerCount = 1; region.imageOffset.x = 0; region.imageOffset.y = 0; region.imageOffset.z = 0; region.imageExtent.width = width; region.imageExtent.height = height; region.imageExtent.depth = 0; vkCmdCopyImageToBuffer(command_buffer, src_image, image_layout, dst_buffer, 1, ®ion); } static void cmd_clear_color_attachment(VkCommandBuffer command_buffer, unsigned int index, unsigned int width, unsigned int height, float r, float g, float b, float a) { VkClearAttachment attachment; VkClearRect rect; attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; attachment.colorAttachment = index; attachment.clearValue.color.float32[0] = r; attachment.clearValue.color.float32[1] = g; attachment.clearValue.color.float32[2] = b; attachment.clearValue.color.float32[3] = a; rect.rect.offset.x = 0; rect.rect.offset.y = 0; rect.rect.extent.width = width; rect.rect.extent.height = height; rect.baseArrayLayer = 0; rect.layerCount = 1; vkCmdClearAttachments(command_buffer, 1, &attachment, 1, &rect); } static void cmd_begin_render_pass(VkCommandBuffer command_buffer, VkRenderPass render_pass, VkFramebuffer framebuffer, unsigned int width, unsigned int height) { struct VkRenderPassBeginInfo begin_desc; begin_desc.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; begin_desc.pNext = NULL; begin_desc.renderPass = render_pass; begin_desc.framebuffer = framebuffer; begin_desc.renderArea.offset.x = 0; begin_desc.renderArea.offset.y = 0; begin_desc.renderArea.extent.width = width; begin_desc.renderArea.extent.height = height; begin_desc.clearValueCount = 0; begin_desc.pClearValues = NULL; vkCmdBeginRenderPass(command_buffer, &begin_desc, VK_SUBPASS_CONTENTS_INLINE); } static void *map_memory(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size) { VkResult vr; void *ptr; if ((vr = vkMapMemory(device, memory, offset, size, 0, &ptr)) < 0) { fprintf(stderr, "Failed to map memory, vr %d.\n", vr); return NULL; } return ptr; } static uint32_t vs_code[] = { #if 0 #version 450 layout(location=0) in dmat4 x; void main() { gl_Position = vec4(x[0][0]); } #endif 0x07230203, 0x00010000, 0x00080007, 0x0000001d, 0x00000000, 0x00020011, 0x00000001, 0x00020011, 0x0000000a, 0x0006000b, 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000001, 0x0007000f, 0x00000000, 0x00000004, 0x6e69616d, 0x00000000, 0x0000000d, 0x00000014, 0x00030003, 0x00000002, 0x000001c2, 0x00040005, 0x00000004, 0x6e69616d, 0x00000000, 0x00060005, 0x0000000b, 0x505f6c67, 0x65567265, 0x78657472, 0x00000000, 0x00060006, 0x0000000b, 0x00000000, 0x505f6c67, 0x7469736f, 0x006e6f69, 0x00070006, 0x0000000b, 0x00000001, 0x505f6c67, 0x746e696f, 0x657a6953, 0x00000000, 0x00070006, 0x0000000b, 0x00000002, 0x435f6c67, 0x4470696c, 0x61747369, 0x0065636e, 0x00070006, 0x0000000b, 0x00000003, 0x435f6c67, 0x446c6c75, 0x61747369, 0x0065636e, 0x00030005, 0x0000000d, 0x00000000, 0x00030005, 0x00000014, 0x00000078, 0x00050048, 0x0000000b, 0x00000000, 0x0000000b, 0x00000000, 0x00050048, 0x0000000b, 0x00000001, 0x0000000b, 0x00000001, 0x00050048, 0x0000000b, 0x00000002, 0x0000000b, 0x00000003, 0x00050048, 0x0000000b, 0x00000003, 0x0000000b, 0x00000004, 0x00030047, 0x0000000b, 0x00000002, 0x00040047, 0x00000014, 0x0000001e, 0x00000000, 0x00020013, 0x00000002, 0x00030021, 0x00000003, 0x00000002, 0x00030016, 0x00000006, 0x00000020, 0x00040017, 0x00000007, 0x00000006, 0x00000004, 0x00040015, 0x00000008, 0x00000020, 0x00000000, 0x0004002b, 0x00000008, 0x00000009, 0x00000001, 0x0004001c, 0x0000000a, 0x00000006, 0x00000009, 0x0006001e, 0x0000000b, 0x00000007, 0x00000006, 0x0000000a, 0x0000000a, 0x00040020, 0x0000000c, 0x00000003, 0x0000000b, 0x0004003b, 0x0000000c, 0x0000000d, 0x00000003, 0x00040015, 0x0000000e, 0x00000020, 0x00000001, 0x0004002b, 0x0000000e, 0x0000000f, 0x00000000, 0x00030016, 0x00000010, 0x00000040, 0x00040017, 0x00000011, 0x00000010, 0x00000004, 0x00040018, 0x00000012, 0x00000011, 0x00000004, 0x00040020, 0x00000013, 0x00000001, 0x00000012, 0x0004003b, 0x00000013, 0x00000014, 0x00000001, 0x0004002b, 0x00000008, 0x00000015, 0x00000000, 0x00040020, 0x00000016, 0x00000001, 0x00000010, 0x00040020, 0x0000001b, 0x00000003, 0x00000007, 0x00050036, 0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x000200f8, 0x00000005, 0x00060041, 0x00000016, 0x00000017, 0x00000014, 0x0000000f, 0x00000015, 0x0004003d, 0x00000010, 0x00000018, 0x00000017, 0x00040073, 0x00000006, 0x00000019, 0x00000018, 0x00070050, 0x00000007, 0x0000001a, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00050041, 0x0000001b, 0x0000001c, 0x0000000d, 0x0000000f, 0x0003003e, 0x0000001c, 0x0000001a, 0x000100fd, 0x00010038, }; static uint32_t fs_code[] = { #if 0 ; SPIR-V ; Version: 1.0 ; Generator: Khronos; 0 ; Bound: 85 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %3 "main" %41 OpDecorate %_arr_v4float_uint_1 ArrayStride 16 OpDecorate %_struct_37 Block OpMemberDecorate %_struct_37 0 Offset 0 OpDecorate %39 DescriptorSet 0 OpDecorate %39 Binding 0 OpDecorate %41 Location 0 %void = OpTypeVoid %2 = OpTypeFunction %void %float = OpTypeFloat 32 %v4float = OpTypeVector %float 4 %float_0x1_36pn141 = OpConstant %float 0x1.36p-141 %float_0x1pn148 = OpConstant %float 0x1p-148 %float_76 = OpConstant %float 76 %float_0 = OpConstant %float 0 %11 = OpConstantComposite %v4float %float_0x1_36pn141 %float_0x1pn148 %float_76 %float_0 %float_0x1_bcpn143 = OpConstant %float 0x1.bcp-143 %float_0x1_cpn147 = OpConstant %float 0x1.cp-147 %float_83_5 = OpConstant %float 83.5 %15 = OpConstantComposite %v4float %float_0x1_bcpn143 %float_0x1_cpn147 %float_83_5 %float_0 %float_0x1_a8pn142 = OpConstant %float 0x1.a8p-142 %float_0x1p_128 = OpConstant %float 0x1p+128 %float_0_5 = OpConstant %float 0.5 %19 = OpConstantComposite %v4float %float_0x1_a8pn142 %float_0x1p_128 %float_0_5 %float_0 %float_n0x1_fffbfep_128 = OpConstant %float -0x1.fffbfep+128 %float_n0x1p_128 = OpConstant %float -0x1p+128 %float_0_75 = OpConstant %float 0.75 %23 = OpConstantComposite %v4float %float_n0x1_fffbfep_128 %float_n0x1p_128 %float_0_75 %float_0 %float_n0x1_fffd84p_128 = OpConstant %float -0x1.fffd84p+128 %float_0x1_8p_128 = OpConstant %float 0x1.8p+128 %float_n0_5 = OpConstant %float -0.5 %27 = OpConstantComposite %v4float %float_n0x1_fffd84p_128 %float_0x1_8p_128 %float_n0_5 %float_0 %28 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 %uint = OpTypeInt 32 0 %uint_6 = OpConstant %uint 6 %_arr_v4float_uint_6 = OpTypeArray %v4float %uint_6 %32 = OpConstantComposite %_arr_v4float_uint_6 %11 %15 %19 %23 %27 %28 %_ptr_Private__arr_v4float_uint_6 = OpTypePointer Private %_arr_v4float_uint_6 %34 = OpVariable %_ptr_Private__arr_v4float_uint_6 Private %32 %uint_1 = OpConstant %uint 1 %_arr_v4float_uint_1 = OpTypeArray %v4float %uint_1 %_struct_37 = OpTypeStruct %_arr_v4float_uint_1 %_ptr_Uniform__struct_37 = OpTypePointer Uniform %_struct_37 %39 = OpVariable %_ptr_Uniform__struct_37 Uniform %_ptr_Output_v4float = OpTypePointer Output %v4float %41 = OpVariable %_ptr_Output_v4float Output %_ptr_Function_v4float = OpTypePointer Function %v4float %float_1 = OpConstant %float 1 %_ptr_Output_float = OpTypePointer Output %float %uint_3 = OpConstant %uint 3 %uint_0 = OpConstant %uint 0 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float %_ptr_Uniform_float = OpTypePointer Uniform %float %_ptr_Function_float = OpTypePointer Function %float %int = OpTypeInt 32 1 %_ptr_Private_v4float = OpTypePointer Private %v4float %_ptr_Private_float = OpTypePointer Private %float %uint_2 = OpConstant %uint 2 %3 = OpFunction %void None %2 %4 = OpLabel %47 = OpInBoundsAccessChain %_ptr_Output_float %41 %uint_3 OpStore %47 %float_1 %50 = OpAccessChain %_ptr_Uniform_v4float %39 %uint_0 %uint_0 %52 = OpInBoundsAccessChain %_ptr_Uniform_float %50 %uint_0 %53 = OpLoad %float %52 %59 = OpBitcast %int %53 %61 = OpAccessChain %_ptr_Private_v4float %34 %59 %63 = OpInBoundsAccessChain %_ptr_Private_float %61 %uint_1 %64 = OpLoad %float %63 %65 = OpBitcast %uint %64 %66 = OpConvertUToF %float %65 %67 = OpInBoundsAccessChain %_ptr_Output_float %41 %uint_1 OpStore %67 %66 %70 = OpBitcast %int %53 %71 = OpAccessChain %_ptr_Private_v4float %34 %70 %72 = OpInBoundsAccessChain %_ptr_Private_float %71 %uint_0 %73 = OpLoad %float %72 %74 = OpBitcast %int %73 %75 = OpConvertSToF %float %74 %76 = OpInBoundsAccessChain %_ptr_Output_float %41 %uint_0 OpStore %76 %75 %79 = OpBitcast %int %53 %80 = OpAccessChain %_ptr_Private_v4float %34 %79 %82 = OpInBoundsAccessChain %_ptr_Private_float %80 %uint_2 %83 = OpLoad %float %82 %84 = OpInBoundsAccessChain %_ptr_Output_float %41 %uint_2 OpStore %84 %83 OpReturn OpFunctionEnd #endif 0x07230203, 0x00010000, 0x00000000, 0x00000055, 0x00000000, 0x00020011, 0x00000001, 0x0003000e, 0x00000000, 0x00000001, 0x0006000f, 0x00000004, 0x00000003, 0x6e69616d, 0x00000000, 0x00000029, 0x00040047, 0x00000024, 0x00000006, 0x00000010, 0x00030047, 0x00000025, 0x00000002, 0x00050048, 0x00000025, 0x00000000, 0x00000023, 0x00000000, 0x00040047, 0x00000027, 0x00000022, 0x00000000, 0x00040047, 0x00000027, 0x00000021, 0x00000000, 0x00040047, 0x00000029, 0x0000001e, 0x00000000, 0x00020013, 0x00000001, 0x00030021, 0x00000002, 0x00000001, 0x00030016, 0x00000005, 0x00000020, 0x00040017, 0x00000006, 0x00000005, 0x00000004, 0x0004002b, 0x00000005, 0x00000007, 0x00000136, 0x0004002b, 0x00000005, 0x00000008, 0x00000002, 0x0004002b, 0x00000005, 0x00000009, 0x42980000, 0x0004002b, 0x00000005, 0x0000000a, 0x00000000, 0x0007002c, 0x00000006, 0x0000000b, 0x00000007, 0x00000008, 0x00000009, 0x0000000a, 0x0004002b, 0x00000005, 0x0000000c, 0x0000006f, 0x0004002b, 0x00000005, 0x0000000d, 0x00000007, 0x0004002b, 0x00000005, 0x0000000e, 0x42a70000, 0x0007002c, 0x00000006, 0x0000000f, 0x0000000c, 0x0000000d, 0x0000000e, 0x0000000a, 0x0004002b, 0x00000005, 0x00000010, 0x000000d4, 0x0004002b, 0x00000005, 0x00000011, 0x7f800000, 0x0004002b, 0x00000005, 0x00000012, 0x3f000000, 0x0007002c, 0x00000006, 0x00000013, 0x00000010, 0x00000011, 0x00000012, 0x0000000a, 0x0004002b, 0x00000005, 0x00000014, 0xfffffdff, 0x0004002b, 0x00000005, 0x00000015, 0xff800000, 0x0004002b, 0x00000005, 0x00000016, 0x3f400000, 0x0007002c, 0x00000006, 0x00000017, 0x00000014, 0x00000015, 0x00000016, 0x0000000a, 0x0004002b, 0x00000005, 0x00000018, 0xfffffec2, 0x0004002b, 0x00000005, 0x00000019, 0x7fc00000, 0x0004002b, 0x00000005, 0x0000001a, 0xbf000000, 0x0007002c, 0x00000006, 0x0000001b, 0x00000018, 0x00000019, 0x0000001a, 0x0000000a, 0x0007002c, 0x00000006, 0x0000001c, 0x0000000a, 0x0000000a, 0x0000000a, 0x0000000a, 0x00040015, 0x0000001d, 0x00000020, 0x00000000, 0x0004002b, 0x0000001d, 0x0000001e, 0x00000006, 0x0004001c, 0x0000001f, 0x00000006, 0x0000001e, 0x0009002c, 0x0000001f, 0x00000020, 0x0000000b, 0x0000000f, 0x00000013, 0x00000017, 0x0000001b, 0x0000001c, 0x00040020, 0x00000021, 0x00000006, 0x0000001f, 0x0005003b, 0x00000021, 0x00000022, 0x00000006, 0x00000020, 0x0004002b, 0x0000001d, 0x00000023, 0x00000001, 0x0004001c, 0x00000024, 0x00000006, 0x00000023, 0x0003001e, 0x00000025, 0x00000024, 0x00040020, 0x00000026, 0x00000002, 0x00000025, 0x0004003b, 0x00000026, 0x00000027, 0x00000002, 0x00040020, 0x00000028, 0x00000003, 0x00000006, 0x0004003b, 0x00000028, 0x00000029, 0x00000003, 0x00040020, 0x0000002a, 0x00000007, 0x00000006, 0x0004002b, 0x00000005, 0x0000002c, 0x3f800000, 0x00040020, 0x0000002d, 0x00000003, 0x00000005, 0x0004002b, 0x0000001d, 0x0000002e, 0x00000003, 0x0004002b, 0x0000001d, 0x00000030, 0x00000000, 0x00040020, 0x00000031, 0x00000002, 0x00000006, 0x00040020, 0x00000033, 0x00000002, 0x00000005, 0x00040020, 0x00000036, 0x00000007, 0x00000005, 0x00040015, 0x0000003a, 0x00000020, 0x00000001, 0x00040020, 0x0000003c, 0x00000006, 0x00000006, 0x00040020, 0x0000003e, 0x00000006, 0x00000005, 0x0004002b, 0x0000001d, 0x00000051, 0x00000002, 0x00050036, 0x00000001, 0x00000003, 0x00000000, 0x00000002, 0x000200f8, 0x00000004, 0x00050042, 0x0000002d, 0x0000002f, 0x00000029, 0x0000002e, 0x0003003e, 0x0000002f, 0x0000002c, 0x00060041, 0x00000031, 0x00000032, 0x00000027, 0x00000030, 0x00000030, 0x00050042, 0x00000033, 0x00000034, 0x00000032, 0x00000030, 0x0004003d, 0x00000005, 0x00000035, 0x00000034, 0x0004007c, 0x0000003a, 0x0000003b, 0x00000035, 0x00050041, 0x0000003c, 0x0000003d, 0x00000022, 0x0000003b, 0x00050042, 0x0000003e, 0x0000003f, 0x0000003d, 0x00000023, 0x0004003d, 0x00000005, 0x00000040, 0x0000003f, 0x0004007c, 0x0000001d, 0x00000041, 0x00000040, 0x00040070, 0x00000005, 0x00000042, 0x00000041, 0x00050042, 0x0000002d, 0x00000043, 0x00000029, 0x00000023, 0x0003003e, 0x00000043, 0x00000042, 0x0004007c, 0x0000003a, 0x00000046, 0x00000035, 0x00050041, 0x0000003c, 0x00000047, 0x00000022, 0x00000046, 0x00050042, 0x0000003e, 0x00000048, 0x00000047, 0x00000030, 0x0004003d, 0x00000005, 0x00000049, 0x00000048, 0x0004007c, 0x0000003a, 0x0000004a, 0x00000049, 0x0004006f, 0x00000005, 0x0000004b, 0x0000004a, 0x00050042, 0x0000002d, 0x0000004c, 0x00000029, 0x00000030, 0x0003003e, 0x0000004c, 0x0000004b, 0x0004007c, 0x0000003a, 0x0000004f, 0x00000035, 0x00050041, 0x0000003c, 0x00000050, 0x00000022, 0x0000004f, 0x00050042, 0x0000003e, 0x00000052, 0x00000050, 0x00000051, 0x0004003d, 0x00000005, 0x00000053, 0x00000052, 0x00050042, 0x0000002d, 0x00000054, 0x00000029, 0x00000051, 0x0003003e, 0x00000054, 0x00000053, 0x000100fd, 0x00010038, }; static uint32_t check_uint32(uint32_t value, uint32_t expected_value) { if (value != expected_value) printf("Got value %u, expected %u.\n", value, expected_value); } int main(void) { VkPhysicalDevice physical_device; VkDescriptorSetLayout set_layout; VkRenderPass render_pass; VkPipelineLayout layout; VkShaderModule vs, fs; VkInstance instance; VkPipeline pipeline; VkDescriptorSet set; unsigned int x, y; VkDevice device; VkQueue queue; instance = create_instance(); assert(instance != VK_NULL_HANDLE); physical_device = select_physical_device(instance); assert(physical_device != VK_NULL_HANDLE); device = create_device(instance, physical_device); assert(device != VK_NULL_HANDLE); vs = create_shader_module(device, sizeof(vs_code), &vs_code); assert(vs != VK_NULL_HANDLE); fs = create_shader_module(device, sizeof(fs_code), &fs_code); assert(vs != VK_NULL_HANDLE); set_layout = create_descriptor_set_layout(device); assert(set_layout != VK_NULL_HANDLE); layout = create_pipeline_layout(device, set_layout); assert(layout != VK_NULL_HANDLE); render_pass = create_render_pass(device); assert(render_pass != VK_NULL_HANDLE); pipeline = create_graphics_pipeline(device, layout, vs, fs, render_pass); assert(pipeline != VK_NULL_HANDLE); vkDestroyShaderModule(device, vs, NULL); vkDestroyShaderModule(device, fs, NULL); vkDestroyPipeline(device, pipeline, NULL); vkDestroyRenderPass(device, render_pass, NULL); vkDestroyPipelineLayout(device, layout, NULL); vkDestroyDescriptorSetLayout(device, set_layout, NULL); vkDestroyDevice(device, NULL); vkDestroyInstance(instance, NULL); return 0; }