#include <vulkan/vulkan.h>
#include
#include
#include
#include
const uint32_t WIDTH = 800;
const uint32_t HEIGHT = 600;
struct QueueFamilyIndices {
int graphicsFamily = -1;
int presentFamily = -1;
bool isComplete() {
return graphicsFamily >= 0 && presentFamily >= 0;
}
};
QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device, VkSurfaceKHR surface) {
QueueFamilyIndices indices;
uint32_t queueFamilyCount = 0;
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr);
std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data());
int i = 0;
for (const auto& queueFamily : queueFamilies) {
if (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
indices.graphicsFamily = i;
}
VkBool32 presentSupport = false;
vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport);
if (presentSupport) {
indices.presentFamily = i;
}
if (indices.isComplete()) {
break;
}
i++;
}
return indices;
}
bool checkDeviceExtensionSupport(VkPhysicalDevice device) {
uint32_t extensionCount;
vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr);
std::vector<VkExtensionProperties> availableExtensions(extensionCount);
vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, availableExtensions.data());
std::set<std::string> requiredExtensions = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME
};
for (const auto& extension : availableExtensions) {
requiredExtensions.erase(extension.extensionName);
}
return requiredExtensions.empty();
}
bool isDeviceSuitable(VkPhysicalDevice device, VkSurfaceKHR surface) {
QueueFamilyIndices indices = findQueueFamilies(device, surface);
bool extensionsSupported = checkDeviceExtensionSupport(device);
VkPhysicalDeviceFeatures supportedFeatures;
vkGetPhysicalDeviceFeatures(device, &supportedFeatures);
return indices.isComplete() && extensionsSupported && supportedFeatures.samplerAnisotropy;
}
void createBuffer(VkDevice device, VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer, VkDeviceMemory& bufferMemory) {
VkBufferCreateInfo bufferInfo = {};
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.size = size;
bufferInfo.usage = usage;
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
if (vkCreateBuffer(device, &bufferInfo, nullptr, &buffer)!= VK_SUCCESS) {
std::cerr << "Failed to create buffer!" << std::endl;
exit(1);
}
VkMemoryRequirements memRequirements;
vkGetBufferMemoryRequirements(device, buffer, &memRequirements);
VkMemoryAllocateInfo allocInfo = {};
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocInfo.allocationSize = memRequirements.size;
allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, properties, device);
if (vkAllocateMemory(device, &allocInfo, nullptr, &bufferMemory)!= VK_SUCCESS) {
std::cerr << "Failed to allocate buffer memory!" << std::endl;
exit(1);
}
vkBindBufferMemory(device, buffer, bufferMemory, 0);
}
uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties, VkPhysicalDevice device) {
VkPhysicalDeviceMemoryProperties memProperties;
vkGetPhysicalDeviceMemoryProperties(device, &memProperties);
for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) {
if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) {
return i;
}
}
std::cerr << "Failed to find suitable memory type!" << std::endl;
exit(1);
}
void createVertexBuffer(VkDevice device, std::vector vertices, VkBuffer& vertexBuffer, VkDeviceMemory& vertexBufferMemory) {
VkDeviceSize bufferSize = sizeof(vertices[0]) * vertices.size();
createBuffer(device, bufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, vertexBuffer, vertexBufferMemory);
void* data;
vkMapMemory(device, vertexBufferMemory, 0, bufferSize, 0, &data);
memcpy(data, vertices.data(), (size_t)bufferSize);
vkUnmapMemory(device, vertexBufferMemory);
}
struct UniformBufferObject {
alignas(16) glm::mat4 model;
alignas(16) glm::mat4 view;
alignas(16) glm::mat4 proj;
};
void createUniformBuffers(VkDevice device, VkPhysicalDevice physicalDevice, uint32_t swapChainImageCount, std::vector& uniformBuffers, std::vector& uniformBuffersMemory) {
VkDeviceSize bufferSize = sizeof(UniformBufferObject);
uniformBuffers.resize(swapChainImageCount);
uniformBuffersMemory.resize(swapChainImageCount);
for (size_t i = 0; i < swapChainImageCount; i++) {
createBuffer(device, bufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, uniformBuffers[i], uniformBuffersMemory[i]);
}
}
int main() {
VkInstance instance;
VkDebugUtilsMessengerEXT debugMessenger;
VkSurfaceKHR surface;
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
VkDevice device;
VkQueue graphicsQueue;
VkQueue presentQueue;
// 初始化 Vulkan
if (initVulkan(instance, debugMessenger, surface, physicalDevice, device, graphicsQueue, presentQueue)!= VK_SUCCESS) {
std::cerr << "Failed to initialize Vulkan!" << std::endl;
return -1;
}
// 顶点数据
std::vector<float> vertices = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
VkBuffer vertexBuffer;
VkDeviceMemory vertexBufferMemory;
createVertexBuffer(device, vertices, vertexBuffer, vertexBufferMemory);
// 清理资源
vkDestroyBuffer(device, vertexBuffer, nullptr);
vkFreeMemory(device, vertexBufferMemory, nullptr);
vkDestroyDevice(device, nullptr);
if (vkDestroySurfaceKHR(instance, surface, nullptr)!= VK_SUCCESS) {
std::cerr << "Failed to destroy surface!" << std::endl;
}
vkDestroyInstance(instance, nullptr);
return 0;
}