Created
April 17, 2021 20:48
-
-
Save untodesu/5d1bf5f18e390da4a485ec09fe3bf8a3 to your computer and use it in GitHub Desktop.
fckn vulkan
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <glad/vulkan.h> | |
#include <GLFW/glfw3.h> | |
#include <stddef.h> | |
#include <stdio.h> | |
#include <stdint.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include "tri_v.h" | |
#include "tri_f.h" | |
// Note #1: | |
// All the Vulkan-related code should be | |
// eventually moved from this to a more suitable | |
// place where it can be also abstracted so the | |
// OpenGL (both 4.6 and 3.2) compatibility can be | |
// achieved. For now since I'm learning about how | |
// Vulkan works, shit's about to live here for a while. | |
// Note #2: | |
// There will be a bunch of my own comments about | |
// how Vulkan differs from OpenGL from the perspective | |
// of a huge modern OpenGL nerd that wants to learn Vulkan. | |
// So the first difference is function loading process: | |
// we need to call the loader three (holy shit!) times. | |
// So the process of initialization is: | |
// 1. Load a basic set of functions: LoadVulkan(null, GetInstanceProcAddress, null) | |
// 2. Create a new Vulkan instance | |
// 3. Load some more functions: LoadVulkan(null, GetInstanceProcAddress, instance) | |
// 4. Choose a GPU (physical device) to use | |
// 5. Load the remaining functions: LoadVulkan(gpu, GetInstanceProcAddress, instance) | |
// 6. Create a new logical device | |
// This seems like a bad idea | |
typedef _Bool boolean; | |
enum { false, true }; | |
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) | |
struct r_queuefamily_s { | |
boolean valid; | |
uint32_t index; | |
}; | |
struct r_vkstate_s { | |
VkInstance instance; | |
VkPhysicalDevice gpu; | |
VkPhysicalDeviceFeatures gpu_features; | |
VkPhysicalDeviceProperties gpu_properties; | |
struct r_queuefamily_s gpu_graphics_qf; | |
struct r_queuefamily_s gpu_present_qf; | |
VkDevice device; | |
VkQueue graphics; | |
VkQueue present; | |
VkSurfaceKHR surface; | |
VkSurfaceCapabilitiesKHR surface_caps; | |
VkSurfaceFormatKHR swapchain_format; | |
VkPresentModeKHR swapchain_present_mode; | |
VkExtent2D swapchain_extent; | |
VkSwapchainKHR swapchain; | |
uint32_t num_swapchain_images; | |
VkImage *swapchain_images; | |
VkImageView *swapchain_image_views; | |
VkFramebuffer *swapchain_framebuffers; | |
VkCommandBuffer *command_buffers; | |
}; | |
static struct r_vkstate_s r_state; | |
static boolean R_CreateInstance(void) | |
{ | |
uint32_t num_instance_extensions; | |
const char **instance_extensions = glfwGetRequiredInstanceExtensions(&num_instance_extensions); | |
VkApplicationInfo app_info = { 0 }; | |
app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; | |
app_info.pApplicationName = "Test App"; | |
app_info.applicationVersion = VK_MAKE_VERSION(0, 0, 0); | |
app_info.pEngineName = "Wynn"; | |
app_info.engineVersion = VK_MAKE_VERSION(0, 0, 0); | |
app_info.apiVersion = VK_API_VERSION_1_0; | |
VkInstanceCreateInfo instance_info = { 0 }; | |
instance_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; | |
instance_info.pApplicationInfo = &app_info; | |
instance_info.ppEnabledExtensionNames = instance_extensions; | |
instance_info.enabledExtensionCount = num_instance_extensions; | |
instance_info.enabledLayerCount = 0; | |
return vkCreateInstance(&instance_info, NULL, &r_state.instance) == VK_SUCCESS; | |
} | |
static boolean R_ChooseGPU(void) | |
{ | |
r_state.gpu = VK_NULL_HANDLE; | |
uint32_t num_gpus; | |
vkEnumeratePhysicalDevices(r_state.instance, &num_gpus, NULL); | |
unsigned int *gpu_ratings = malloc(sizeof(unsigned int) * num_gpus); | |
VkPhysicalDevice *gpus = malloc(sizeof(VkPhysicalDevice) * num_gpus); | |
vkEnumeratePhysicalDevices(r_state.instance, &num_gpus, gpus); | |
uint32_t max_index = 0; | |
unsigned int max_rating = 0; | |
for(uint32_t i = 0; i < num_gpus; i++) { | |
VkPhysicalDeviceFeatures features; | |
vkGetPhysicalDeviceFeatures(gpus[i], &features); | |
VkPhysicalDeviceProperties properties; | |
vkGetPhysicalDeviceProperties(gpus[i], &properties); | |
gpu_ratings[i] = 0; | |
if(properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) | |
gpu_ratings[i] += 1000; | |
gpu_ratings[i] += properties.limits.maxImageDimension2D; | |
if(gpu_ratings[i] > max_rating) { | |
max_rating = gpu_ratings[i]; | |
max_index = i; | |
} | |
} | |
if(max_rating > 0) { | |
uint32_t num_queue_families; | |
vkGetPhysicalDeviceQueueFamilyProperties(gpus[max_index], &num_queue_families, NULL); | |
VkQueueFamilyProperties *queue_families = malloc(sizeof(VkQueueFamilyProperties) * num_queue_families); | |
vkGetPhysicalDeviceQueueFamilyProperties(gpus[max_index], &num_queue_families, queue_families); | |
for(uint32_t i = 0; i < num_queue_families; i++) { | |
if(!r_state.gpu_graphics_qf.valid && queue_families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { | |
r_state.gpu_graphics_qf.valid = true; | |
r_state.gpu_graphics_qf.index = i; | |
} | |
if(!r_state.gpu_present_qf.valid && glfwGetPhysicalDevicePresentationSupport(r_state.instance, gpus[max_index], i)) { | |
r_state.gpu_present_qf.valid = true; | |
r_state.gpu_present_qf.index = i; | |
} | |
} | |
free(queue_families); | |
// todo: R_QueuesComplete | |
if(r_state.gpu_graphics_qf.valid && r_state.gpu_present_qf.valid) { | |
r_state.gpu = gpus[max_index]; | |
vkGetPhysicalDeviceFeatures(r_state.gpu, &r_state.gpu_features); | |
vkGetPhysicalDeviceProperties(r_state.gpu, &r_state.gpu_properties); | |
printf("R_ChooseGPU: choosing %s\n", r_state.gpu_properties.deviceName); | |
printf("R_ChooseGPU: gpu rating: %u\n", max_rating); | |
} | |
} | |
free(gpus); | |
free(gpu_ratings); | |
return r_state.gpu != VK_NULL_HANDLE; | |
} | |
static boolean R_CreateDevice(void) | |
{ | |
const float queue_priority = 1.0f; | |
VkDeviceQueueCreateInfo queue_infos[] = { | |
{ | |
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, | |
.queueFamilyIndex = r_state.gpu_graphics_qf.index, | |
.queueCount = 1, | |
.pQueuePriorities = &queue_priority, | |
}, | |
{ | |
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, | |
.queueFamilyIndex = r_state.gpu_present_qf.index, | |
.queueCount = 1, | |
.pQueuePriorities = &queue_priority, | |
}, | |
}; | |
const char *device_extensions[] = { | |
VK_KHR_SWAPCHAIN_EXTENSION_NAME | |
}; | |
VkDeviceCreateInfo device_info = { 0 }; | |
device_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; | |
device_info.pQueueCreateInfos = queue_infos; | |
device_info.queueCreateInfoCount = ARRAY_SIZE(queue_infos); | |
device_info.pEnabledFeatures = &r_state.gpu_features; | |
device_info.ppEnabledExtensionNames = device_extensions; | |
device_info.enabledExtensionCount = ARRAY_SIZE(device_extensions); | |
device_info.enabledLayerCount = 0; | |
return vkCreateDevice(r_state.gpu, &device_info, NULL, &r_state.device) == VK_SUCCESS; | |
} | |
static boolean R_CreateSwapchain(GLFWwindow *window) | |
{ | |
uint32_t num_formats; | |
vkGetPhysicalDeviceSurfaceFormatsKHR(r_state.gpu, r_state.surface, &num_formats, NULL); | |
if(!num_formats) { | |
printf("R_CreateSwapchain: surface has no formats"); | |
return false; | |
} | |
VkSurfaceFormatKHR *formats = malloc(sizeof(VkSurfaceFormatKHR) * num_formats); | |
vkGetPhysicalDeviceSurfaceFormatsKHR(r_state.gpu, r_state.surface, &num_formats, formats); | |
boolean has_best_format = false; | |
for(uint32_t i = 0; i < num_formats; i++) { | |
if(formats[i].format == VK_FORMAT_B8G8R8A8_SRGB && formats[i].colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) { | |
r_state.swapchain_format = formats[i]; | |
has_best_format = true; | |
} | |
} | |
if(!has_best_format) { | |
printf("R_CreateSwapchain: can't find the best surface format, defaulting to 0\n"); | |
r_state.swapchain_format = formats[0]; | |
} | |
free(formats); | |
uint32_t num_present_modes; | |
vkGetPhysicalDeviceSurfacePresentModesKHR(r_state.gpu, r_state.surface, &num_present_modes, NULL); | |
if(!num_present_modes) { | |
printf("R_CreateSwapchain: surface has no present modes\n"); | |
return false; | |
} | |
VkPresentModeKHR *present_modes = malloc(sizeof(VkPresentModeKHR) * num_present_modes); | |
vkGetPhysicalDeviceSurfacePresentModesKHR(r_state.gpu, r_state.surface, &num_present_modes, present_modes); | |
boolean has_best_present_mode = false; | |
for(uint32_t i = 0; i < num_present_modes; i++) { | |
if(present_modes[i] == VK_PRESENT_MODE_MAILBOX_KHR) { | |
r_state.swapchain_present_mode = present_modes[i]; | |
has_best_present_mode = true; | |
} | |
} | |
if(!has_best_present_mode) { | |
printf("R_CreateSwapchain: can't find the best surface present mode, defaulting to VK_PRESENT_MODE_FIFO_KHR\n"); | |
r_state.swapchain_present_mode = VK_PRESENT_MODE_FIFO_KHR; | |
} | |
free(present_modes); | |
if(r_state.surface_caps.currentExtent.width != UINT32_MAX) { | |
printf("R_CreateSwapchain: using current surface extent\n"); | |
r_state.swapchain_extent = r_state.surface_caps.currentExtent; | |
} | |
else { | |
int width, height; | |
glfwGetFramebufferSize(window, &width, &height); | |
r_state.swapchain_extent.width = width; | |
r_state.swapchain_extent.height = height; | |
// clamp the width | |
if(r_state.swapchain_extent.width > r_state.surface_caps.maxImageExtent.width) | |
r_state.swapchain_extent.width = r_state.surface_caps.maxImageExtent.width; | |
if(r_state.swapchain_extent.width < r_state.surface_caps.minImageExtent.width) | |
r_state.swapchain_extent.width = r_state.surface_caps.minImageExtent.width; | |
// clamp the height | |
if(r_state.swapchain_extent.height > r_state.surface_caps.maxImageExtent.height) | |
r_state.swapchain_extent.height = r_state.surface_caps.maxImageExtent.height; | |
if(r_state.swapchain_extent.height < r_state.surface_caps.minImageExtent.height) | |
r_state.swapchain_extent.height = r_state.surface_caps.minImageExtent.height; | |
} | |
uint32_t num_images = r_state.surface_caps.minImageCount + 1; | |
if(num_images > r_state.surface_caps.maxImageCount) | |
num_images = r_state.surface_caps.maxImageCount; | |
VkSwapchainCreateInfoKHR swapchain_info = { 0 }; | |
swapchain_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; | |
swapchain_info.surface = r_state.surface; | |
swapchain_info.minImageCount = num_images; | |
swapchain_info.imageFormat = r_state.swapchain_format.format; | |
swapchain_info.imageColorSpace = r_state.swapchain_format.colorSpace; | |
swapchain_info.imageExtent = r_state.swapchain_extent; | |
swapchain_info.imageArrayLayers = 1; | |
swapchain_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; | |
swapchain_info.preTransform = r_state.surface_caps.currentTransform; | |
swapchain_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; | |
swapchain_info.presentMode = r_state.swapchain_present_mode; | |
swapchain_info.clipped = VK_TRUE; | |
swapchain_info.oldSwapchain = VK_NULL_HANDLE; | |
uint32_t indices[] = { | |
r_state.gpu_graphics_qf.index, | |
r_state.gpu_present_qf.index | |
}; | |
if(r_state.gpu_graphics_qf.index != r_state.gpu_present_qf.index) { | |
swapchain_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT; | |
swapchain_info.queueFamilyIndexCount = ARRAY_SIZE(indices); | |
swapchain_info.pQueueFamilyIndices = indices; | |
} | |
else { | |
swapchain_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; | |
swapchain_info.queueFamilyIndexCount = 0; | |
} | |
return vkCreateSwapchainKHR(r_state.device, &swapchain_info, NULL, &r_state.swapchain) == VK_SUCCESS; | |
} | |
static boolean R_GetSwapchainImages(void) | |
{ | |
vkGetSwapchainImagesKHR(r_state.device, r_state.swapchain, &r_state.num_swapchain_images, NULL); | |
r_state.swapchain_images = malloc(sizeof(VkImage) * r_state.num_swapchain_images); | |
vkGetSwapchainImagesKHR(r_state.device, r_state.swapchain, &r_state.num_swapchain_images, r_state.swapchain_images); | |
r_state.swapchain_image_views = malloc(sizeof(VkImageView) * r_state.num_swapchain_images); | |
for(uint32_t i = 0; i < r_state.num_swapchain_images; i++) { | |
VkImageViewCreateInfo view_info = { 0 }; | |
view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; | |
view_info.image = r_state.swapchain_images[i]; | |
view_info.viewType = VK_IMAGE_VIEW_TYPE_2D; | |
view_info.format = r_state.swapchain_format.format; | |
view_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; | |
view_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; | |
view_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; | |
view_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; | |
view_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; | |
view_info.subresourceRange.baseMipLevel = 0; | |
view_info.subresourceRange.levelCount = 1; | |
view_info.subresourceRange.baseArrayLayer = 0; | |
view_info.subresourceRange.layerCount = 1; | |
if(vkCreateImageView(r_state.device, &view_info, NULL, &r_state.swapchain_image_views[i]) != VK_SUCCESS) | |
return false; | |
} | |
return true; | |
} | |
static boolean R_Init(GLFWwindow *window) | |
{ | |
if(!gladLoadVulkanUserPtr(NULL, glfwGetInstanceProcAddress, NULL)) { | |
printf("R_Init: failed to load Vulkan functions (1)\n"); | |
return false; | |
} | |
if(!R_CreateInstance()) { | |
printf("R_Init: failed to create a Vulkan instance\n"); | |
return false; | |
} | |
if(!gladLoadVulkanUserPtr(NULL, glfwGetInstanceProcAddress, r_state.instance)) { | |
printf("R_Init: failed to load Vulkan functions (2)\n"); | |
return false; | |
} | |
if(!R_ChooseGPU()) { | |
printf("R_Init: failed to choose a suitable GPU\n"); | |
return false; | |
} | |
if(!gladLoadVulkanUserPtr(r_state.gpu, glfwGetInstanceProcAddress, r_state.instance)) { | |
printf("R_Init: failed to load Vulkan functions (3)\n"); | |
return false; | |
} | |
if(!R_CreateDevice()) { | |
printf("R_Init: failed to create a Vulkan device\n"); | |
return false; | |
} | |
vkGetDeviceQueue(r_state.device, r_state.gpu_graphics_qf.index, 0, &r_state.graphics); | |
vkGetDeviceQueue(r_state.device, r_state.gpu_present_qf.index, 0, &r_state.present); | |
if(glfwCreateWindowSurface(r_state.instance, window, NULL, &r_state.surface) != VK_SUCCESS) { | |
printf("R_Init: failed to create a window surface\n"); | |
return false; | |
} | |
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(r_state.gpu, r_state.surface, &r_state.surface_caps); | |
if(!R_CreateSwapchain(window)) { | |
printf("R_Init: failed to create a swapchain\n"); | |
return false; | |
} | |
if(!R_GetSwapchainImages()) { | |
printf("R_Init: failed to get swapchain images\n"); | |
return false; | |
} | |
return true; | |
} | |
static void R_Shutdown(void) | |
{ | |
for(uint32_t i = 0; i < r_state.num_swapchain_images; i++) | |
vkDestroyImageView(r_state.device, r_state.swapchain_image_views[i], NULL); | |
free(r_state.swapchain_image_views); | |
free(r_state.swapchain_images); | |
vkDestroySwapchainKHR(r_state.device, r_state.swapchain, NULL); | |
vkDestroySurfaceKHR(r_state.instance, r_state.surface, NULL); | |
vkDestroyDevice(r_state.device, NULL); | |
vkDestroyInstance(r_state.instance, NULL); | |
} | |
static boolean R_CreateShaderModule(const void *data, size_t size, VkShaderModule *out) | |
{ | |
VkShaderModuleCreateInfo module_info = { 0 }; | |
module_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; | |
module_info.codeSize = size; | |
module_info.pCode = data; | |
return vkCreateShaderModule(r_state.device, &module_info, NULL, out) == VK_SUCCESS; | |
} | |
static boolean R_CreateRenderPass(VkRenderPass *out) | |
{ | |
VkAttachmentDescription color = { 0 }; | |
color.format = r_state.swapchain_format.format; | |
color.samples = VK_SAMPLE_COUNT_1_BIT; | |
color.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; | |
color.storeOp = VK_ATTACHMENT_STORE_OP_STORE; | |
color.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; | |
color.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; | |
color.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; | |
color.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; | |
VkAttachmentReference color_ref = { 0 }; | |
color_ref.attachment = 0; | |
color_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; | |
VkSubpassDependency dependency = { 0 }; | |
dependency.srcSubpass = VK_SUBPASS_EXTERNAL; | |
dependency.dstSubpass = 0; | |
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; | |
dependency.srcAccessMask = 0; | |
VkSubpassDescription subpass = { 0 }; | |
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; | |
subpass.colorAttachmentCount = 1; | |
subpass.pColorAttachments = &color_ref; | |
VkRenderPassCreateInfo pass_info = { 0 }; | |
pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; | |
pass_info.attachmentCount = 1; | |
pass_info.pAttachments = &color; | |
pass_info.subpassCount = 1; | |
pass_info.pSubpasses = &subpass; | |
pass_info.dependencyCount = 1; | |
pass_info.pDependencies = &dependency; | |
return vkCreateRenderPass(r_state.device, &pass_info, NULL, out) == VK_SUCCESS; | |
} | |
static void GLFW_ErrorCallback(int code, const char *message) | |
{ | |
printf("glfw error %d: %s\n", code, message); | |
} | |
int main(void) | |
{ | |
glfwSetErrorCallback(GLFW_ErrorCallback); | |
if(!glfwInit()) | |
return 1; | |
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); | |
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); | |
GLFWwindow *window = glfwCreateWindow(800, 600, "", NULL, NULL); | |
if(!window) { | |
glfwTerminate(); | |
return 1; | |
} | |
if(!R_Init(window)) { | |
glfwTerminate(); | |
return 1; | |
} | |
VkShaderModule vert; | |
if(!R_CreateShaderModule(tri_vspv, tri_vspv_len, &vert)) { | |
R_Shutdown(); | |
glfwTerminate(); | |
return 2; | |
} | |
VkShaderModule frag; | |
if(!R_CreateShaderModule(tri_fspv, tri_fspv_len, &frag)) { | |
R_Shutdown(); | |
glfwTerminate(); | |
return 2; | |
} | |
VkPipelineShaderStageCreateInfo stages[] = { | |
{ | |
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, | |
.stage = VK_SHADER_STAGE_VERTEX_BIT, | |
.module = vert, | |
.pName = "main", | |
}, | |
{ | |
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, | |
.stage = VK_SHADER_STAGE_FRAGMENT_BIT, | |
.module = frag, | |
.pName = "main", | |
} | |
}; | |
VkRenderPass pass; | |
if(!R_CreateRenderPass(&pass)) { | |
R_Shutdown(); | |
glfwTerminate(); | |
return 3; | |
} | |
VkPipelineVertexInputStateCreateInfo vertex_info = { 0 }; | |
vertex_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; | |
vertex_info.vertexBindingDescriptionCount = 0; | |
vertex_info.vertexAttributeDescriptionCount = 0; | |
VkPipelineInputAssemblyStateCreateInfo input_info = { 0 }; | |
input_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; | |
input_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; | |
input_info.primitiveRestartEnable = VK_FALSE; | |
VkViewport viewport = { | |
.x = 0.0f, | |
.y = 0.0f, | |
.width = r_state.swapchain_extent.width, | |
.height = r_state.swapchain_extent.height, | |
.minDepth = 0.0f, | |
.maxDepth = 1.0f | |
}; | |
VkRect2D scissor = { | |
.offset = { 0, 0 }, | |
.extent = r_state.swapchain_extent | |
}; | |
VkPipelineViewportStateCreateInfo viewport_info = { 0 }; | |
viewport_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; | |
viewport_info.viewportCount = 1; | |
viewport_info.pViewports = &viewport; | |
viewport_info.scissorCount = 1; | |
viewport_info.pScissors = &scissor; | |
VkPipelineRasterizationStateCreateInfo rasterizer_info = { 0 }; | |
rasterizer_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; | |
rasterizer_info.depthClampEnable = VK_FALSE; | |
rasterizer_info.rasterizerDiscardEnable = VK_FALSE; | |
rasterizer_info.polygonMode = VK_POLYGON_MODE_FILL; | |
rasterizer_info.cullMode = VK_CULL_MODE_BACK_BIT; | |
rasterizer_info.frontFace = VK_FRONT_FACE_CLOCKWISE; | |
rasterizer_info.depthBiasEnable = VK_FALSE; | |
VkPipelineMultisampleStateCreateInfo msaa_info = { 0 }; | |
msaa_info.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; | |
msaa_info.sampleShadingEnable = VK_FALSE; | |
msaa_info.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; | |
VkPipelineColorBlendAttachmentState blend_attachment = { 0 }; | |
blend_attachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; | |
blend_attachment.blendEnable = VK_FALSE; | |
VkPipelineColorBlendStateCreateInfo color_blend = { 0 }; | |
color_blend.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; | |
color_blend.logicOpEnable = VK_FALSE; | |
color_blend.logicOp = VK_LOGIC_OP_COPY; | |
color_blend.attachmentCount = 1; | |
color_blend.pAttachments = &blend_attachment; | |
color_blend.blendConstants[0] = 0.0f; | |
color_blend.blendConstants[1] = 0.0f; | |
color_blend.blendConstants[2] = 0.0f; | |
color_blend.blendConstants[3] = 0.0f; | |
VkPipelineLayout pipeline_layout; | |
VkPipelineLayoutCreateInfo layout_info = { 0 }; | |
layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; | |
vkCreatePipelineLayout(r_state.device, &layout_info, NULL, &pipeline_layout); | |
VkGraphicsPipelineCreateInfo pipeline_info = { 0 }; | |
pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; | |
pipeline_info.stageCount = 2; | |
pipeline_info.pStages = stages; | |
pipeline_info.pVertexInputState = &vertex_info; | |
pipeline_info.pInputAssemblyState = &input_info; | |
pipeline_info.pViewportState = &viewport_info; | |
pipeline_info.pRasterizationState = &rasterizer_info; | |
pipeline_info.pMultisampleState = &msaa_info; | |
pipeline_info.pColorBlendState = &color_blend; | |
pipeline_info.layout = pipeline_layout; | |
pipeline_info.renderPass = pass; | |
pipeline_info.subpass = 0; | |
VkPipeline pipeline; | |
if(vkCreateGraphicsPipelines(r_state.device, VK_NULL_HANDLE, 1, &pipeline_info, NULL, &pipeline) != VK_SUCCESS) { | |
printf("failed to create pipeline\n"); | |
R_Shutdown(); | |
glfwTerminate(); | |
return 4; | |
} | |
r_state.swapchain_framebuffers = malloc(sizeof(VkFramebuffer) * r_state.num_swapchain_images); | |
for(uint32_t i = 0; i < r_state.num_swapchain_images; i++) { | |
VkFramebufferCreateInfo framebuffer_info = { 0 }; | |
framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; | |
framebuffer_info.renderPass = pass; | |
framebuffer_info.attachmentCount = 1; | |
framebuffer_info.pAttachments = &r_state.swapchain_image_views[i]; | |
framebuffer_info.width = r_state.swapchain_extent.width; | |
framebuffer_info.height = r_state.swapchain_extent.height; | |
framebuffer_info.layers = 1; | |
if(vkCreateFramebuffer(r_state.device, &framebuffer_info, NULL, &r_state.swapchain_framebuffers[i]) != VK_SUCCESS) { | |
printf("failed to create framebuffer\n"); | |
R_Shutdown(); | |
glfwTerminate(); | |
return 1; | |
} | |
} | |
VkCommandPool pool; | |
VkCommandPoolCreateInfo pool_info = { 0 }; | |
pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; | |
pool_info.queueFamilyIndex = r_state.gpu_graphics_qf.index; | |
pool_info.flags = 0; | |
if(vkCreateCommandPool(r_state.device, &pool_info, NULL, &pool) != VK_SUCCESS) { | |
printf("failed to create command pool\n"); | |
R_Shutdown(); | |
glfwTerminate(); | |
return 1; | |
} | |
r_state.command_buffers = malloc(sizeof(VkCommandBuffer) * r_state.num_swapchain_images); | |
VkCommandBufferAllocateInfo cb_info = { 0 }; | |
cb_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; | |
cb_info.commandPool = pool; | |
cb_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; | |
cb_info.commandBufferCount = r_state.num_swapchain_images; | |
if(vkAllocateCommandBuffers(r_state.device, &cb_info, r_state.command_buffers) != VK_SUCCESS) { | |
printf("failed to allocate command buffers\n"); | |
R_Shutdown(); | |
glfwTerminate(); | |
return 1; | |
} | |
VkSemaphore ia_se; | |
VkSemaphore rf_se; | |
VkSemaphoreCreateInfo se_info = { 0 }; | |
se_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; | |
if(vkCreateSemaphore(r_state.device, &se_info, NULL, &ia_se) != VK_SUCCESS) { | |
printf("failed to create semaphore\n"); | |
R_Shutdown(); | |
glfwTerminate(); | |
return 1; | |
} | |
if(vkCreateSemaphore(r_state.device, &se_info, NULL, &rf_se) != VK_SUCCESS) { | |
printf("failed to create semaphore\n"); | |
R_Shutdown(); | |
glfwTerminate(); | |
return 1; | |
} | |
while(!glfwWindowShouldClose(window)) { | |
for(uint32_t i = 0; i < r_state.num_swapchain_images; i++) { | |
VkCommandBufferBeginInfo begin_info = { 0 }; | |
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; | |
if(vkBeginCommandBuffer(r_state.command_buffers[i], &begin_info) != VK_SUCCESS) { | |
printf("failed to begin command buffer\n"); | |
R_Shutdown(); | |
glfwTerminate(); | |
return 1; | |
} | |
VkClearValue clear = { 0.0f, 0.0f, 0.0f, 1.0f }; | |
VkRenderPassBeginInfo pass_info = { 0 }; | |
pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; | |
pass_info.renderPass = pass; | |
pass_info.framebuffer = r_state.swapchain_framebuffers[i]; | |
pass_info.renderArea.offset.x = 0; | |
pass_info.renderArea.offset.y = 0; | |
pass_info.renderArea.extent = r_state.swapchain_extent; | |
pass_info.clearValueCount = 1; | |
pass_info.pClearValues = &clear; | |
vkCmdBeginRenderPass(r_state.command_buffers[i], &pass_info, VK_SUBPASS_CONTENTS_INLINE); | |
vkCmdBindPipeline(r_state.command_buffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); | |
vkCmdDraw(r_state.command_buffers[i], 3, 1, 0, 0); | |
vkCmdEndRenderPass(r_state.command_buffers[i]); | |
if(vkEndCommandBuffer(r_state.command_buffers[i]) != VK_SUCCESS) { | |
printf("failed to end command buffer\n"); | |
R_Shutdown(); | |
glfwTerminate(); | |
return 1; | |
} | |
} | |
uint32_t index; | |
vkAcquireNextImageKHR(r_state.device, r_state.swapchain, UINT64_MAX, ia_se, VK_NULL_HANDLE, &index); | |
VkPipelineStageFlags ws[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; | |
VkSubmitInfo si = { 0 }; | |
si.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; | |
si.waitSemaphoreCount = 1; | |
si.pWaitSemaphores = &ia_se; | |
si.pWaitDstStageMask = ws; | |
si.commandBufferCount = 1; | |
si.pCommandBuffers = &r_state.command_buffers[index]; | |
si.signalSemaphoreCount = 1; | |
si.pSignalSemaphores = &rf_se; | |
if(vkQueueSubmit(r_state.graphics, 1, &si, VK_NULL_HANDLE) != VK_SUCCESS) { | |
printf("failed to submit\n"); | |
R_Shutdown(); | |
glfwTerminate(); | |
return 1; | |
} | |
VkPresentInfoKHR present_info = { 0 }; | |
present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; | |
present_info.waitSemaphoreCount = 1; | |
present_info.pWaitSemaphores = &rf_se; | |
present_info.swapchainCount = 1; | |
present_info.pSwapchains = &r_state.swapchain; | |
present_info.pImageIndices = &index; | |
vkQueuePresentKHR(r_state.graphics, &present_info); | |
glfwPollEvents(); | |
} | |
vkDestroySemaphore(r_state.device, rf_se, NULL); | |
vkDestroySemaphore(r_state.device, ia_se, NULL); | |
vkDestroyCommandPool(r_state.device, pool, NULL); | |
for(uint32_t i = 0; i , r_state.num_swapchain_images; i++) | |
vkDestroyFramebuffer(r_state.device, r_state.swapchain_framebuffers[i], NULL); | |
free(r_state.swapchain_framebuffers); | |
vkDestroyPipeline(r_state.device, pipeline, NULL); | |
vkDestroyPipelineLayout(r_state.device, pipeline_layout, NULL); | |
vkDestroyShaderModule(r_state.device, vert, NULL); | |
vkDestroyShaderModule(r_state.device, frag, NULL); | |
R_Shutdown(); | |
glfwDestroyWindow(window); | |
glfwTerminate(); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#version 450 | |
layout(location = 0) in vec3 col; | |
layout(location = 0) out vec4 fc; | |
void main(void) | |
{ | |
fc = vec4(col, 1.0); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#version 450 | |
vec2 positions[3] = vec2[]( | |
vec2(-0.5, -0.5), | |
vec2( 0.0, 0.5), | |
vec2( 0.5, -0.5) | |
); | |
vec3 colors[3] = vec3[]( | |
vec3(1.0, 0.0, 0.0), | |
vec3(0.0, 1.0, 0.0), | |
vec3(0.0, 0.0, 1.0) | |
); | |
layout(location = 0) out vec3 col; | |
void main(void) | |
{ | |
col = colors[gl_VertexIndex]; | |
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
unsigned char tri_fspv[] = { | |
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x0d, 0x00, | |
0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, | |
0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, | |
0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, | |
0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, | |
0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, | |
0x09, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00, | |
0x04, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, | |
0x02, 0x00, 0x00, 0x00, 0xc2, 0x01, 0x00, 0x00, 0x04, 0x00, 0x0a, 0x00, | |
0x47, 0x4c, 0x5f, 0x47, 0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x5f, 0x63, 0x70, | |
0x70, 0x5f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x5f, 0x6c, 0x69, 0x6e, 0x65, | |
0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, | |
0x04, 0x00, 0x08, 0x00, 0x47, 0x4c, 0x5f, 0x47, 0x4f, 0x4f, 0x47, 0x4c, | |
0x45, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x64, 0x69, | |
0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00, 0x05, 0x00, 0x04, 0x00, | |
0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, | |
0x05, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x66, 0x63, 0x00, 0x00, | |
0x05, 0x00, 0x03, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6c, 0x00, | |
0x47, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, | |
0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, | |
0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, | |
0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, | |
0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, | |
0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, | |
0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, | |
0x3b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, | |
0x03, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, | |
0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, | |
0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, | |
0x3b, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, | |
0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, | |
0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x36, 0x00, 0x05, 0x00, | |
0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x03, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, | |
0x3d, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, | |
0x0c, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, | |
0x0f, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, | |
0x0d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, | |
0x06, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, | |
0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, | |
0x12, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, | |
0x11, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, | |
0x09, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, | |
0x38, 0x00, 0x01, 0x00 | |
}; | |
unsigned int tri_fspv_len = 556; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
unsigned char tri_vspv[] = { | |
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x0d, 0x00, | |
0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, | |
0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, | |
0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, | |
0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, | |
0x1e, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, | |
0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc2, 0x01, 0x00, 0x00, | |
0x04, 0x00, 0x0a, 0x00, 0x47, 0x4c, 0x5f, 0x47, 0x4f, 0x4f, 0x47, 0x4c, | |
0x45, 0x5f, 0x63, 0x70, 0x70, 0x5f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x5f, | |
0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, | |
0x76, 0x65, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x47, 0x4c, 0x5f, 0x47, | |
0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, | |
0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00, | |
0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, | |
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x00, 0x00, | |
0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x00, 0x00, 0x00, | |
0x05, 0x00, 0x04, 0x00, 0x17, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6c, 0x6f, | |
0x72, 0x73, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x1e, 0x00, 0x00, 0x00, | |
0x63, 0x6f, 0x6c, 0x00, 0x05, 0x00, 0x06, 0x00, 0x21, 0x00, 0x00, 0x00, | |
0x67, 0x6c, 0x5f, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x49, 0x6e, 0x64, | |
0x65, 0x78, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x29, 0x00, 0x00, 0x00, | |
0x67, 0x6c, 0x5f, 0x50, 0x65, 0x72, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, | |
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x29, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, | |
0x69, 0x6f, 0x6e, 0x00, 0x06, 0x00, 0x07, 0x00, 0x29, 0x00, 0x00, 0x00, | |
0x01, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x69, 0x6e, 0x74, | |
0x53, 0x69, 0x7a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x07, 0x00, | |
0x29, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x43, | |
0x6c, 0x69, 0x70, 0x44, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x00, | |
0x06, 0x00, 0x07, 0x00, 0x29, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, | |
0x67, 0x6c, 0x5f, 0x43, 0x75, 0x6c, 0x6c, 0x44, 0x69, 0x73, 0x74, 0x61, | |
0x6e, 0x63, 0x65, 0x00, 0x05, 0x00, 0x03, 0x00, 0x2b, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x1e, 0x00, 0x00, 0x00, | |
0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, | |
0x21, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, | |
0x48, 0x00, 0x05, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, | |
0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, | |
0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x29, 0x00, 0x00, 0x00, | |
0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, | |
0x48, 0x00, 0x05, 0x00, 0x29, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, | |
0x0b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, | |
0x29, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, | |
0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, | |
0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, | |
0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, | |
0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, | |
0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x2b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, | |
0x03, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, | |
0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, | |
0x0b, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, | |
0x3b, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, | |
0x06, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, | |
0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0x2c, 0x00, 0x05, 0x00, | |
0x07, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, | |
0x0d, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, | |
0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, | |
0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, | |
0x2c, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, | |
0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x05, 0x00, | |
0x07, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, | |
0x0d, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x06, 0x00, 0x0a, 0x00, 0x00, 0x00, | |
0x13, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, | |
0x12, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, | |
0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, | |
0x15, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, | |
0x20, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, | |
0x15, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, | |
0x17, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, | |
0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, | |
0x2c, 0x00, 0x06, 0x00, 0x14, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, | |
0x18, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, | |
0x2c, 0x00, 0x06, 0x00, 0x14, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, | |
0x0f, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, | |
0x2c, 0x00, 0x06, 0x00, 0x14, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, | |
0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, | |
0x2c, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, | |
0x19, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, | |
0x20, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, | |
0x14, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, | |
0x1e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, | |
0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, | |
0x20, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, | |
0x1f, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, | |
0x21, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, | |
0x23, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, | |
0x17, 0x00, 0x04, 0x00, 0x26, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, | |
0x04, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, | |
0x27, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, | |
0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, | |
0x1e, 0x00, 0x06, 0x00, 0x29, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, | |
0x06, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, | |
0x20, 0x00, 0x04, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, | |
0x29, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x2a, 0x00, 0x00, 0x00, | |
0x2b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, | |
0x1f, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x20, 0x00, 0x04, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, | |
0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x34, 0x00, 0x00, 0x00, | |
0x03, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, | |
0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x03, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, | |
0x3e, 0x00, 0x03, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, | |
0x3e, 0x00, 0x03, 0x00, 0x17, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, | |
0x3d, 0x00, 0x04, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, | |
0x21, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x23, 0x00, 0x00, 0x00, | |
0x24, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, | |
0x3d, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, | |
0x24, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x1e, 0x00, 0x00, 0x00, | |
0x25, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x1f, 0x00, 0x00, 0x00, | |
0x2d, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, | |
0x2e, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, | |
0x2d, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, | |
0x30, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, | |
0x06, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, | |
0x32, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, | |
0x50, 0x00, 0x07, 0x00, 0x26, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, | |
0x31, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, | |
0x18, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x34, 0x00, 0x00, 0x00, | |
0x35, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, | |
0x3e, 0x00, 0x03, 0x00, 0x35, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, | |
0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00 | |
}; | |
unsigned int tri_vspv_len = 1496; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment