| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- #include <png.h>
- #include <vulkan/vulkan.h>
-
- #include <iostream>
- #include <string>
- #include <vector>
-
- const uint32_t kWidth = 16;
- const uint32_t kHeight = 16;
-
- #define ERROR(message) \
- std::cerr << message << std::endl; \
- std::exit(EXIT_FAILURE)
-
- VkInstance CreateVkInstance() {
- VkApplicationInfo app_info = {};
- app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
- app_info.apiVersion = VK_API_VERSION_1_1;
-
- VkInstanceCreateInfo create_info = {};
- create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
- create_info.pApplicationInfo = &app_info;
- create_info.enabledExtensionCount = 0;
- create_info.ppEnabledExtensionNames = nullptr;
- create_info.enabledLayerCount = 0;
- create_info.ppEnabledLayerNames = nullptr;
-
- VkInstance instance;
- VkResult result = vkCreateInstance(&create_info, nullptr, &instance);
- if (result != VK_SUCCESS) {
- ERROR("Error creating VkInstance: " << result);
- }
- return instance;
- }
-
- VkPhysicalDevice ChooseVkPhysicalDevice(VkInstance instance) {
- uint32_t device_count = 0;
- VkResult result = vkEnumeratePhysicalDevices(instance, &device_count, nullptr);
- if (result != VK_SUCCESS) {
- ERROR("Error enumerating VkPhysicalDevices: " << result);
- }
- if (device_count == 0) {
- ERROR("No available VkPhysicalDevices");
- }
-
- std::vector<VkPhysicalDevice> devices(device_count);
- result = vkEnumeratePhysicalDevices(instance, &device_count, devices.data());
- if (result != VK_SUCCESS) {
- ERROR("Error fetching VkPhysicalDevices: " << result);
- }
-
- std::cout << "Found " << device_count << " device(s):" << std::endl;
- VkPhysicalDevice chosen_device = VK_NULL_HANDLE;
- for (VkPhysicalDevice device : devices) {
- VkPhysicalDeviceProperties device_props;
- vkGetPhysicalDeviceProperties(device, &device_props);
- std::cout << "\t- " << device_props.deviceName << " [V: " <<
- VK_VERSION_MAJOR(device_props.apiVersion) << "." <<
- VK_VERSION_MINOR(device_props.apiVersion) << "." <<
- VK_VERSION_PATCH(device_props.apiVersion) << "]" << std::endl;
- // Currently, any device with Vulkan API version 1.1 is fine.
- if (chosen_device == VK_NULL_HANDLE && device_props.apiVersion >= VK_API_VERSION_1_1) {
- chosen_device = device;
- }
- }
-
- if (chosen_device == VK_NULL_HANDLE) {
- ERROR("Unable to find suitable VkPhysicalDevice");
- }
- return chosen_device;
- }
-
- uint32_t ChooseDeviceQueueFamilyIndex(VkPhysicalDevice physical_device) {
- uint32_t props_count;
- vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &props_count, nullptr);
- std::vector<VkQueueFamilyProperties> props(props_count);
- vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &props_count, props.data());
-
- // Simply choose the first graphics queue.
- for (size_t i = 0; i < props_count; i++) {
- const VkQueueFamilyProperties& prop = props[i];
- if ((prop.queueFlags & VK_QUEUE_GRAPHICS_BIT) && prop.queueCount > 0) {
- return i;
- }
- }
-
- ERROR("Unable to find suitable queue family");
- }
-
- VkDevice CreateVkDevice(VkPhysicalDevice physical_device, uint32_t device_queue_family_index) {
- VkDeviceQueueCreateInfo queue_create_info = {};
- queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
- queue_create_info.queueFamilyIndex = device_queue_family_index;
- queue_create_info.queueCount = 1;
- float queue_priority = 1.0f;
- queue_create_info.pQueuePriorities = &queue_priority;
-
- VkDeviceCreateInfo device_create_info = {};
- device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
- device_create_info.queueCreateInfoCount = 1;
- device_create_info.pQueueCreateInfos = &queue_create_info;
- // Let's not use any device extensions for now.
- device_create_info.enabledExtensionCount = 0;
- device_create_info.ppEnabledExtensionNames = nullptr;
-
- VkDevice device;
- VkResult result = vkCreateDevice(physical_device, &device_create_info, nullptr, &device);
- if (result != VK_SUCCESS) {
- ERROR("Unable to create logical device");
- }
- return device;
- }
-
- int main() {
- VkInstance instance = CreateVkInstance();
- VkPhysicalDevice physical_device = ChooseVkPhysicalDevice(instance);
- uint32_t device_queue_family_index = ChooseDeviceQueueFamilyIndex(physical_device);
- VkDevice device = CreateVkDevice(physical_device, device_queue_family_index);
-
- // Example code for exporting a PNG.
- FILE *f = fopen("triangle.png", "wb");
-
- std::vector<uint8_t> pixels(kWidth * kHeight * 4);
- for (size_t i = 0; i < kHeight; i++) {
- for (size_t j = 0; j < kWidth; j++) {
- uint32_t base_index = (i * kWidth * 4) + (j * 4);
- pixels[base_index] = 255;
- pixels[base_index + 1] = 255;
- pixels[base_index + 2] = 0;
- pixels[base_index + 3] = 255;
- }
- }
-
- png_image image_info = {};
- image_info.version = PNG_IMAGE_VERSION;
- image_info.width = kWidth;
- image_info.height = kHeight;
- image_info.format = PNG_FORMAT_RGBA;
- if (png_image_write_to_stdio(&image_info, f, 0, pixels.data(), kWidth * 4, nullptr) == 0) {
- ERROR("Error writing PNG: " << image_info.message);
- }
-
- fclose(f);
-
- return EXIT_SUCCESS;
- }
|