Starting Out
Signed-off-by: Robear Selwans <robear.selwans@outlook.com>
This commit is contained in:
249
main.c
Normal file
249
main.c
Normal file
@@ -0,0 +1,249 @@
|
||||
#include <evk/evk.h>
|
||||
#include <ev_numeric.h>
|
||||
#include <ev_helpers.h>
|
||||
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
evstring PROJECT_NAME = evstr("evk");
|
||||
|
||||
float vertexPositions[] = {
|
||||
0.f,-.5f,
|
||||
.5f, .5f,
|
||||
-.5f, .5f
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
u32 width = 1024;
|
||||
u32 height = 1024;
|
||||
|
||||
evkInstance instance = evkCreateInstance((evkInstanceCreateInfo){
|
||||
.applicationInfo = EV_DEFAULT(evkApplicationInfo),
|
||||
.layers = svec_init(evstring, {
|
||||
evstr("VK_LAYER_KHRONOS_validation"),
|
||||
}),
|
||||
.extensions = svec_init(evstring, {
|
||||
evstr("VK_KHR_surface"),
|
||||
evstr("VK_KHR_win32_surface"),
|
||||
}),
|
||||
});
|
||||
|
||||
if(instance.vk == EV_INVALID(VkInstance))
|
||||
{
|
||||
puts("Instance creation failed.");
|
||||
goto InstanceCreationFailed;
|
||||
}
|
||||
puts("Instance was created successfully.");
|
||||
|
||||
evkDevice device = evkCreateDevice((evkDeviceCreateInfo) {
|
||||
.instance = instance,
|
||||
.physicalDeviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU,
|
||||
.queueRequirements = svec_init(evkDeviceQueueRequirement, {
|
||||
{ VK_QUEUE_GRAPHICS_BIT, 1 },
|
||||
{ VK_QUEUE_COMPUTE_BIT , 1 },
|
||||
}),
|
||||
.deviceExtensions = svec_init(evstring, {
|
||||
evstr("VK_KHR_swapchain"),
|
||||
evstr("VK_KHR_dynamic_rendering"),
|
||||
evstr("VK_KHR_depth_stencil_resolve"),
|
||||
evstr("VK_KHR_create_renderpass2"),
|
||||
evstr("VK_KHR_synchronization2"),
|
||||
evstr("VK_KHR_buffer_device_address"),
|
||||
evstr("VK_EXT_descriptor_indexing"),
|
||||
}),
|
||||
});
|
||||
|
||||
if(device.vk == EV_INVALID(VkDevice))
|
||||
{
|
||||
puts("Couldn't create a VkDevice");
|
||||
goto DeviceCreationFailed;
|
||||
}
|
||||
puts("Logical Device created successfully.");
|
||||
VkQueue graphicsQueue;
|
||||
vkGetDeviceQueue(device.vk, device.queueFamilies[VK_QUEUE_GRAPHICS_BIT].familyIndex, 0, &graphicsQueue);
|
||||
|
||||
if (!glfwInit())
|
||||
{
|
||||
puts("GLFW Initialization failed.");
|
||||
goto GLFWInitFailed;
|
||||
}
|
||||
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
GLFWwindow* window = glfwCreateWindow(1024,1024, "evk", NULL, NULL);
|
||||
if(!window)
|
||||
{
|
||||
puts("Window Creation Failed.");
|
||||
goto WindowCreationFailed;
|
||||
}
|
||||
|
||||
VkSurfaceKHR surface;
|
||||
VkResult err = glfwCreateWindowSurface(instance.vk, window, NULL, &surface);
|
||||
if (err)
|
||||
{
|
||||
goto VKSurfaceCreationFailed;
|
||||
puts("Surface creation failed.");
|
||||
}
|
||||
|
||||
evkSwapChain swapChain = evkCreateSwapChain((evkSwapChainCreateInfo){
|
||||
.device = device,
|
||||
.surface = surface,
|
||||
.width = width,
|
||||
.height = height,
|
||||
.imageCount = 3,
|
||||
});
|
||||
|
||||
evkCommandPool commandPool = evkCreateCommandPool((evkCommandPoolCreateInfo) {
|
||||
.device = device,
|
||||
.queueFlags = VK_QUEUE_GRAPHICS_BIT,
|
||||
.poolFlags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT
|
||||
});
|
||||
|
||||
vec(VkCommandBuffer) commandBuffers = evkAllocateCommandBuffers(device, commandPool, vec_len(&swapChain.images), true);
|
||||
|
||||
evkShaderCompiler compiler = evkCreateShaderCompiler();
|
||||
|
||||
evkShader vertShader = evkInitShaderFromFile(device, compiler, "shaders/tri.vert");
|
||||
evkShader fragShader = evkInitShaderFromFile(device, compiler, "shaders/tri.frag");
|
||||
|
||||
evkDestroyShaderCompiler(compiler);
|
||||
|
||||
evkColorAttachment colorAttachment0 = {
|
||||
swapChain.surfaceFormat.format,
|
||||
EV_DEFAULT(VkPipelineColorBlendAttachmentState)
|
||||
};
|
||||
|
||||
evkPipelineCreateInfo pipelineCreateInfo = EV_DEFAULT(evkPipelineCreateInfo,
|
||||
dynamicStates = svec_init(VkDynamicState, {
|
||||
VK_DYNAMIC_STATE_VIEWPORT,
|
||||
VK_DYNAMIC_STATE_SCISSOR,
|
||||
}),
|
||||
shaderStages = svec_init(evkShader, {
|
||||
vertShader,
|
||||
fragShader,
|
||||
}),
|
||||
colorAttachments = svec_init(evkColorAttachment, {
|
||||
colorAttachment0,
|
||||
}),
|
||||
viewportCountOverride = 1,
|
||||
);
|
||||
|
||||
VkViewport viewport = EV_DEFAULT(VkViewport, width=width, height=height);
|
||||
VkRect2D scissor = EV_DEFAULT(VkRect2D,extent.width=width, extent.height=height);
|
||||
|
||||
evkPipeline graphicsPipeline = evkCreatePipeline(device, pipelineCreateInfo);
|
||||
|
||||
VkFence drawFence = evkCreateFence(device, false);
|
||||
VkSemaphore imageAcquiredSemaphore = evkCreateSemaphore(device);
|
||||
VkSemaphore drawFinishedSemaphore = evkCreateSemaphore(device);
|
||||
|
||||
while(!glfwWindowShouldClose(window))
|
||||
{
|
||||
u32 imageIdx;
|
||||
vkAcquireNextImageKHR(device.vk, swapChain.vk, UInt64.MAX, imageAcquiredSemaphore, VK_NULL_HANDLE, &imageIdx);
|
||||
|
||||
VkCommandBuffer cmdbuf = commandBuffers[imageIdx];
|
||||
|
||||
VkRenderingAttachmentInfoKHR colorAttachment = EV_DEFAULT(VkRenderingAttachmentInfoKHR,
|
||||
imageView = swapChain.imageViews[imageIdx].vk,
|
||||
loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
storeOp= VK_ATTACHMENT_STORE_OP_STORE,
|
||||
);
|
||||
|
||||
VkRenderingInfo renderingInfo = EV_DEFAULT(VkRenderingInfo,
|
||||
renderArea.extent = ((VkExtent2D){width, height}),
|
||||
pColorAttachments = &colorAttachment,
|
||||
colorAttachmentCount = 1,
|
||||
);
|
||||
|
||||
evkBeginPrimaryCommandBuffer(cmdbuf);
|
||||
|
||||
vkCmdSetScissor(cmdbuf, 0, 1, &scissor);
|
||||
vkCmdSetViewport(cmdbuf, 0, 1, &viewport);
|
||||
|
||||
vkCmdBeginRenderingKHR(cmdbuf, &renderingInfo);
|
||||
|
||||
vkCmdBindPipeline(cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.vk);
|
||||
vkCmdDraw(cmdbuf, 3, 1, 0, 0);
|
||||
|
||||
vkCmdEndRenderingKHR(cmdbuf);
|
||||
|
||||
VkImageMemoryBarrier imageMemoryBarrier = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.image = swapChain.images[imageIdx].vk,
|
||||
.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
||||
.subresourceRange = {
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.layerCount = 1,
|
||||
.levelCount = 1,
|
||||
},
|
||||
};
|
||||
|
||||
vkCmdPipelineBarrier(cmdbuf, 0, 0, 0, 0, NULL, 0, NULL, 1, &imageMemoryBarrier);
|
||||
|
||||
evkEndCommandBuffer(cmdbuf);
|
||||
|
||||
VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
|
||||
|
||||
VkSubmitInfo submitInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||
.pCommandBuffers = &cmdbuf,
|
||||
.commandBufferCount = 1,
|
||||
.waitSemaphoreCount = 1,
|
||||
.pWaitSemaphores = &imageAcquiredSemaphore,
|
||||
.pWaitDstStageMask = waitStages,
|
||||
.signalSemaphoreCount = 1,
|
||||
.pSignalSemaphores = &drawFinishedSemaphore,
|
||||
};
|
||||
|
||||
vkQueueSubmit(graphicsQueue, 1, &submitInfo, drawFence);
|
||||
vkWaitForFences(device.vk, 1, &drawFence, VK_TRUE, UInt64.MAX);
|
||||
vkResetFences(device.vk, 1, &drawFence);
|
||||
|
||||
VkPresentInfoKHR presentInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
|
||||
.waitSemaphoreCount = 1,
|
||||
.pWaitSemaphores = &drawFinishedSemaphore,
|
||||
.swapchainCount = 1,
|
||||
.pSwapchains = &swapChain.vk,
|
||||
.pImageIndices = &imageIdx,
|
||||
};
|
||||
vkQueuePresentKHR(graphicsQueue, &presentInfo);
|
||||
|
||||
vkResetCommandBuffer(cmdbuf,VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
|
||||
|
||||
// Main Loop
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
vkQueueWaitIdle(graphicsQueue);
|
||||
|
||||
vkDestroyFence(device.vk, drawFence, NULL);
|
||||
vkDestroySemaphore(device.vk, imageAcquiredSemaphore, NULL);
|
||||
vkDestroySemaphore(device.vk, drawFinishedSemaphore, NULL);
|
||||
|
||||
evkDestroyPipeline(graphicsPipeline);
|
||||
|
||||
evkDestroyShader(device, vertShader);
|
||||
evkDestroyShader(device, fragShader);
|
||||
|
||||
vkFreeCommandBuffers(device.vk, commandPool.vk, vec_len(&commandBuffers), commandBuffers);
|
||||
evkDestroyCommandPool(device, commandPool);
|
||||
|
||||
evkDestroySwapChain(device, swapChain);
|
||||
|
||||
SwapchainCreationFailed:
|
||||
vkDestroySurfaceKHR(instance.vk, swapChain.surface, NULL);
|
||||
|
||||
VKSurfaceCreationFailed:
|
||||
WindowCreationFailed:
|
||||
glfwTerminate();
|
||||
|
||||
GLFWInitFailed:
|
||||
evkDestroyDevice(device);
|
||||
|
||||
DeviceCreationFailed:
|
||||
evkDestroyInstance(instance);
|
||||
InstanceCreationFailed:
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user