/* global variables */
+VkPipeline *vkgraphics_pipeline;
+VkFramebuffer *vkfbufs;
+VkRenderPass vkrpass;
VkSwapchainKHR vkswapchain;
VkImage *vkswapchain_images;
+VkImageView *vkswapchain_views;
+int vknum_swapchain_images;
int vknext_swapchain_image;
VkSurfaceKHR vksurface;
VkInstance vkinst;
vkext_count = 0;
vkEnumerateInstanceExtensionProperties(0, &vkext_count, 0);
if(vkext_count) {
- if(!(vkext = (VkExtensionProperties *)malloc(vkext_count * sizeof *vkext))) {
- perror("failed to allocate instance extension list");
- return false;
- }
+ vkext = new VkExtensionProperties[vkext_count];
vkEnumerateInstanceExtensionProperties(0, &vkext_count, vkext);
printf("instance extensions:\n");
vkdevext_count = 0;
vkEnumerateDeviceExtensionProperties(phys_devices[sel_dev], 0, &vkdevext_count, 0);
if(vkdevext_count) {
- if(!(vkdevext = (VkExtensionProperties *)malloc(vkdevext_count * sizeof *vkdevext))) {
- perror("failed to allocate device extension list");
- return false;
- }
+ vkdevext = new VkExtensionProperties[vkdevext_count];
vkEnumerateDeviceExtensionProperties(phys_devices[sel_dev], 0, &vkdevext_count, vkdevext);
printf("selected device extensions:\n");
fprintf(stderr, "failed to enumerate vulkan physical devices\n");
return false;
}
- phys_devices = (VkPhysicalDevice *)malloc(num_devices * sizeof *phys_devices);
+ phys_devices = new VkPhysicalDevice[num_devices];
if(vkEnumeratePhysicalDevices(vkinst, &num_devices, phys_devices) != 0) {
fprintf(stderr, "failed to enumerate vulkan physical devices\n");
return false;
if(qprop_count <= 0) {
continue;
}
- qprop = (VkQueueFamilyProperties *)malloc(qprop_count * sizeof *qprop);
+ qprop = new VkQueueFamilyProperties[qprop_count];
vkGetPhysicalDeviceQueueFamilyProperties(phys_devices[i], &qprop_count, qprop);
for(unsigned int j=0; j<qprop_count; j++) {
sel_qfamily = j;
}
}
- free(qprop);
+ delete [] qprop;
}
if(sel_dev < 0 || sel_qfamily < 0) {
vkinst = 0;
}
- free(phys_devices);
+ delete [] phys_devices;
phys_devices = 0;
}
if(vkGetSwapchainImagesKHR(vkdev, sc, &nimg, 0) != 0) {
return 0;
}
- if(!(images = (VkImage *)malloc(nimg * sizeof *images))) {
- return 0;
- }
+ images = new VkImage[nimg];
vkGetSwapchainImagesKHR(vkdev, sc, &nimg, images);
if(count) *count = (int)nimg;
return images;
}
+VkImageView *vku_create_image_views(VkImage *images, int count)
+{
+ VkImageView *iviews;
+
+ iviews = new VkImageView[count];
+ for(int i=0; i<count; i++) {
+ VkImageViewCreateInfo inf;
+ memset(&inf, 0, sizeof inf);
+
+ inf.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+ inf.image = images[i];
+ inf.viewType = VK_IMAGE_VIEW_TYPE_2D;
+ inf.format = VK_FORMAT_B8G8R8A8_UNORM; //TODO
+ inf.components.r = inf.components.g = inf.components.b =
+ inf.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
+ inf.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+ inf.subresourceRange.levelCount = 1;
+ inf.subresourceRange.layerCount = 1;
+
+ if(vkCreateImageView(vkdev, &inf, 0, iviews) != 0) {
+ fprintf(stderr, "Failed to create image views.\n");
+ delete iviews;
+ return 0;
+ }
+ }
+
+ return iviews;
+}
+
int vku_get_next_image(VkSwapchainKHR sc)
{
uint32_t next;
vkQueuePresentKHR(vkq, &inf);
}
+bool vku_create_renderpass()
+{
+ VkAttachmentDescription attachments[2];
+ memset(&attachments, 0, 2 * sizeof *attachments);
+
+ /* color */
+ attachments[0].format = VK_FORMAT_B8G8R8A8_UNORM;
+ attachments[0].samples = VK_SAMPLE_COUNT_1_BIT;
+ attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+ attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
+ attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ attachments[0].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+ attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+
+ /* depth */
+ attachments[1].format = VK_FORMAT_D32_SFLOAT_S8_UINT; //TODO
+ attachments[1].samples = VK_SAMPLE_COUNT_1_BIT;
+ attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+ attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ attachments[1].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+ attachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+
+ VkAttachmentReference color_ref;
+ color_ref.attachment = 0;
+ color_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+
+ VkAttachmentReference depth_ref;
+ depth_ref.attachment = 1;
+ depth_ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+
+ VkSubpassDescription subpass_desc;
+ memset(&subpass_desc, 0, sizeof subpass_desc);
+
+ subpass_desc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
+ subpass_desc.colorAttachmentCount = 1;
+ subpass_desc.pColorAttachments = &color_ref;
+ subpass_desc.pDepthStencilAttachment = &depth_ref;
+
+ VkRenderPassCreateInfo inf;
+ memset(&inf, 0, sizeof inf);
+
+ inf.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+ inf.attachmentCount = 2;
+ inf.pAttachments = attachments;
+ inf.subpassCount = 1;
+ inf.pSubpasses = &subpass_desc;
+
+ if(vkCreateRenderPass(vkdev, &inf, 0, &vkrpass) != VK_SUCCESS) {
+ return false;
+ }
+
+ return true;
+}
+
+bool vku_create_framebuffers(VkImageView *image_views, int count, int w, int h)
+{
+ delete vkfbufs;
+ vkfbufs = new VkFramebuffer[count];
+
+ VkFramebufferCreateInfo inf;
+ memset(&inf, 0, sizeof inf);
+
+ inf.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
+ inf.renderPass = vkrpass;
+ inf.attachmentCount = count;
+ inf.pAttachments = image_views;
+ inf.width = w;
+ inf.height = h;
+ inf.layers = 1;
+
+ for(int i=0; i<count; i++) {
+ if(vkCreateFramebuffer(vkdev, &inf, 0, &vkfbufs[i]) != VK_SUCCESS) {
+ fprintf(stderr, "Failed to create framebuffer for image view: %d\n", i);
+ delete vkfbufs;
+ return false;
+ }
+ }
+ return true;
+}
+
struct vku_buffer *vku_create_buffer(int sz, unsigned int usage)
{
struct vku_buffer *buf;
VkBufferCreateInfo binfo;
- if(!(buf = (vku_buffer *)malloc(sizeof *buf))) {
- perror("failed to allocate vk_buffer structure");
- return 0;
- }
+ buf = new vku_buffer;
memset(&binfo, 0, sizeof binfo);
binfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
{
if(buf) {
vkDestroyBuffer(vkdev, buf->buf, 0);
- free(buf);
+ delete buf;
}
}
return errmsg.c_str();
}
+bool vku_create_graphics_pipeline(VkPipelineLayout *layout)
+{
+ VkGraphicsPipelineCreateInfo inf;
+ memset(&inf, 0, sizeof inf);
+
+ inf.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
+ inf.layout = *layout;
+ inf.renderPass = vkrpass;
+
+ /* states */
+
+ /* how primitives are assembled */
+ VkPipelineInputAssemblyStateCreateInfo ias;
+ memset(&ias, 0, sizeof ias);
+ ias.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
+ ias.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
+
+ /* rasterisation */
+ VkPipelineRasterizationStateCreateInfo rsi;
+ memset(&rsi, 0, sizeof rsi);
+ rsi.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
+ rsi.polygonMode = VK_POLYGON_MODE_FILL;
+ rsi.cullMode = VK_CULL_MODE_BACK_BIT;
+ rsi.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
+ rsi.lineWidth = 1.0f;
+
+ /* blend factors */
+ VkPipelineColorBlendAttachmentState bas[1];
+ memset(&bas[0], 0, sizeof bas[0]);
+
+ VkPipelineColorBlendStateCreateInfo cbs;
+ memset(&cbs, 0, sizeof cbs);
+ cbs.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
+ cbs.attachmentCount = 1;
+ cbs.pAttachments = bas;
+
+ /* number of viewport and scissors in this pipeline */
+ VkPipelineViewportStateCreateInfo vs;
+ memset(&vs, 0, sizeof vs);
+ vs.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
+ vs.viewportCount = 1;
+ vs.scissorCount = 1;
+
+ /* dynamic states: that can be changed later */
+ std::vector<VkDynamicState> ds_enabled;
+ ds_enabled.push_back(VK_DYNAMIC_STATE_VIEWPORT);
+ //ds_enabled.push_back(VK_DYNAMIC_STATE_SCISSOR);
+ VkPipelineDynamicStateCreateInfo ds;
+ ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
+ ds.pDynamicStates = ds_enabled.data();
+ ds.dynamicStateCount = static_cast<uint32_t>(ds_enabled.size());
+
+ /* depth tests */
+ VkPipelineDepthStencilStateCreateInfo dsi;
+ memset(&dsi, 0, sizeof dsi);
+ dsi.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
+ dsi.depthTestEnable = VK_TRUE;
+ dsi.depthWriteEnable = VK_TRUE;
+ dsi.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
+ dsi.back.failOp = VK_STENCIL_OP_KEEP;
+ dsi.back.passOp = VK_STENCIL_OP_KEEP;
+ dsi.back.compareOp = VK_COMPARE_OP_ALWAYS;
+ dsi.front = dsi.back;
+
+ /* multisampling - must be set even if not used */
+ VkPipelineMultisampleStateCreateInfo msi;
+ memset(&msi, 0, sizeof msi);
+ msi.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
+ msi.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
+
+ //TODO in progress
+ return true;
+}
+
static const char *get_device_name_str(VkPhysicalDeviceType type)
{
switch(type) {