This commit is contained in:
Hane 2024-11-04 20:49:24 +01:00
commit 302e7aa753

View file

@ -13,6 +13,10 @@
#include <vector>
#include <vulkan/vulkan.h>
#include <glm/glm.hpp>
#include <glm/ext/matrix_clip_space.hpp>
#include <glm/ext/matrix_transform.hpp>
#include <Windows.h>
#include <winuser.h>
#include <wingdi.h>
@ -148,7 +152,7 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n
exit(-2);
}
/* Enumerating physical devices */
/* Enumerating physical devices and registering memory and general properties for later use*/
uint32_t gpuCount = 0; //U_ASSERT_ONLY
std::vector<VkPhysicalDevice> gpus;
result = vkEnumeratePhysicalDevices(inst, &gpuCount, NULL);
@ -157,6 +161,17 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n
result = vkEnumeratePhysicalDevices(inst, &gpuCount, gpus.data());
assert(!result && gpuCount >= 1);
VkPhysicalDeviceMemoryProperties memoryProperties;
VkPhysicalDeviceProperties gpuProperties;
vkGetPhysicalDeviceMemoryProperties(gpus[0], &memoryProperties);
vkGetPhysicalDeviceProperties(gpus[0], &gpuProperties);
/* query device extensions for enabled layers */
/*
* for (auto &layer_props : info.instance_layer_properties) {
* init_device_extension_properties(info, layer_props);
* }
*/
//Surface setup (requires Instance SURFACEs)
VkSurfaceKHR surface;
#ifdef _WIN32
@ -180,8 +195,6 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n
assert(result == VK_SUCCESS);
/* Creating logical device(with SWAPCHAIN extension) + queues (todo insspect all gpus, not assume 1st) */
VkDeviceQueueCreateInfo queueInfo = {};
uint32_t queueFamilyCount = 0;
@ -201,18 +214,6 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n
}
//Look for graphics & present support in queue families. Also store graphics queue family to create queue
/*
* bool found = false; //U_ASSERT_ONLY
* for (unsigned int i = 0; i < queueFamilyCount; i++) {
* if (queueProperties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
* queuequeueFamilyIndex = i;
* found = true;
* break;
* }
* }
* assert(found);
*/
uint32_t graphicsQueueFamilyIndex = UINT32_MAX;
uint32_t presentQueueFamilyIndex = UINT32_MAX;
for (uint32_t i = 0; i < queueFamilyCount; ++i) {
@ -248,6 +249,7 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n
queueInfo.queueCount = 1;
queueInfo.pQueuePriorities = queuePriorities;
//Creating logical device
std::vector<const char*> deviceExtensionNames;
deviceExtensionNames.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
VkDeviceCreateInfo deviceInfo = {};
@ -309,7 +311,6 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n
free(surfFormats);
//Surface capabilities and present modes
uint32_t presentModeCount;
result = vkGetPhysicalDeviceSurfacePresentModesKHR(gpus[0], surface, &presentModeCount, NULL);
assert(result == VK_SUCCESS); //free?
@ -375,6 +376,7 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n
}
}
//Finally, creating the swapchain
VkSwapchainKHR swapchain;
VkSwapchainCreateInfoKHR swapchainCreateInfo = {};
swapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
@ -408,7 +410,8 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n
result = vkCreateSwapchainKHR(device, &swapchainCreateInfo, NULL, &swapchain);
assert(result == VK_SUCCESS);
//After creating it, retrieve all images (=buffers)
uint32_t swapchainImageCount;
result = vkGetSwapchainImagesKHR(device, swapchain, &swapchainImageCount, NULL);
assert(result == VK_SUCCESS);
@ -418,6 +421,7 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n
result = vkGetSwapchainImagesKHR(device, swapchain, &swapchainImageCount, swapchainImages);
assert(result == VK_SUCCESS);
//Said images need config, provided via ImageView
typedef struct _swap_chain_buffers {
VkImage image;
VkImageView view;
@ -451,8 +455,88 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n
result = vkCreateImageView(device, &color_image_view, NULL, &buffers[i].view);
assert(result == VK_SUCCESS);
}
/* Setting up uniform buffer & camera values through it */
glm::mat4 Projection = glm::perspective(glm::radians(45.0f), 1.0f, 0.1f, 100.0f);
glm::mat4 View = glm::lookAt(glm::vec3(-5, 3, -10), // Camera is at (-5,3,-10), in World Space
glm::vec3(0, 0, 0), // and looks at the origin
glm::vec3(0, -1, 0) // Head is up (set to 0,-1,0 to look upside-down)
);
glm::mat4 Model = glm::mat4(1.0f);
// Vulkan clip space has inverted Y and half Z.
// clang-format off
glm::mat4 Clip = glm::mat4(1.0f, 0.0f, 0.0f, 0.0f,
0.0f,-1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
0.0f, 0.0f, 0.5f, 1.0f);
// clang-format on
glm::mat4 MVP = Clip * Projection * View * Model;
//Creating uniform buffer
struct {
VkBuffer buf;
VkDeviceMemory mem;
VkDescriptorBufferInfo descriptorBufferInfo;
} uniformData;
VkBufferCreateInfo uniformBufferInfo = {};
uniformBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
uniformBufferInfo.pNext = NULL;
uniformBufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
uniformBufferInfo.size = sizeof(MVP);
uniformBufferInfo.queueFamilyIndexCount = 0;
uniformBufferInfo.pQueueFamilyIndices = NULL;
uniformBufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
uniformBufferInfo.flags = 0;
result = vkCreateBuffer(device, &uniformBufferInfo, NULL, &uniformData.buf);
assert(result == VK_SUCCESS);
VkMemoryRequirements memoryRequirements;
vkGetBufferMemoryRequirements(device, uniformData.buf, &memoryRequirements);
VkMemoryAllocateInfo memoryAllocInfo = {};
memoryAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
memoryAllocInfo.pNext = NULL;
memoryAllocInfo.memoryTypeIndex = 0;
memoryAllocInfo.allocationSize = memoryRequirements.size;
uint32_t memoryTypeIndex = 0;
VkFlags requirements = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
// Search memtypes to find first index with those properties
for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; i++) {
if ((memoryRequirements.memoryTypeBits & 1) == 1) {
// Type is available, does it match user properties?
if ((memoryProperties.memoryTypes[i].propertyFlags & requirements) == requirements) {
memoryAllocInfo.memoryTypeIndex = i;
}
}
memoryRequirements.memoryTypeBits >>= 1;
}
// No memory types matched, return failure
assert(memoryTypeIndex && "No mappable, coherent memory");
result = vkAllocateMemory(device, &memoryAllocInfo, NULL, &(uniformData.mem));
assert(result == VK_SUCCESS);
uint8_t* pData; //VK_WHOLE_SIZE
result = vkMapMemory(device, uniformData.mem, 0, memoryRequirements.size, 0, (void **)&pData);
assert(result == VK_SUCCESS);
memcpy(pData, &MVP, sizeof(MVP));
vkUnmapMemory(device, uniformData.mem);
result = vkBindBufferMemory(device, uniformData.buf, uniformData.mem, 0);
assert(result == VK_SUCCESS);
uniformData.descriptorBufferInfo.buffer = uniformData.buf;
uniformData.descriptorBufferInfo.offset = 0;
uniformData.descriptorBufferInfo.range = sizeof(MVP);
//Window show and event loop
@ -464,6 +548,8 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n
DispatchMessage(&msg);
}
vkDestroyBuffer(device, uniformData.buf, NULL);
vkFreeMemory(device, uniformData.mem, NULL);
VkCommandBuffer cmdBufs[1] = {cmd};
vkFreeCommandBuffers(device, cmdPool, 1, cmdBufs);
vkDestroyCommandPool(device, cmdPool, NULL);