quick backup - everything is going to be changed on vulkan side.
authorEleni Maria Stea <estea@igalia.com>
Mon, 2 Oct 2017 15:52:26 +0000 (18:52 +0300)
committerEleni Maria Stea <estea@igalia.com>
Mon, 2 Oct 2017 15:52:26 +0000 (18:52 +0300)
external/gph-math
external/libimago
src/main.cc
src/opengl/opengl.cc
src/opengl/opengl.h
src/opengl/texture-gl.h
src/vulkan/vk.cc
src/vulkan/vk.h

index 54ac4cb..9f7489b 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 54ac4cbc3b08744e570a53e7f1a8ba862ea87b80
+Subproject commit 9f7489b288f64a5a8e95a0d2ce67594e7fed950b
index 2228b92..6d5b91d 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 2228b925b87ee5458bd59611c11fc98c051446cc
+Subproject commit 6d5b91de61e8710324852a356d1b7704fc22596c
index 69721c1..6b1050b 100644 (file)
@@ -1,4 +1,5 @@
 #include <GL/glew.h>
+#include <GLFW/glfw3.h>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -80,7 +81,7 @@ int main(int argc, char **argv)
 {
        Gfx_API api;
 
-       for(int i=0; i<argc; ++i) {
+       for(int i=1; i<argc; i++) {
                if(strcmp(argv[i], "-opengl") == 0) {
                        api = GFX_GL;
                        printf("Backend: OpenGL.\n");
@@ -100,6 +101,9 @@ int main(int argc, char **argv)
                return 1;
        }
 
+       //TODO
+       return 0;
+
        glfwSetKeyCallback(win, clbk_key);
        glfwSetCursorPosCallback(win, clbk_motion);
        glfwSetMouseButtonCallback(win, clbk_mouse);
@@ -116,7 +120,6 @@ int main(int argc, char **argv)
        }
 
        cleanup();
-       // atexit(cleanup);
        return 0;
 }
 
index 844b3ac..9b220ab 100644 (file)
@@ -1,4 +1,5 @@
 #include <GL/glew.h>
+#include <GLFW/glfw3.h>
 #include <stdio.h>
 
 #include "gfxapi.h"
index 1a9a86f..7b4d11d 100644 (file)
@@ -1,11 +1,7 @@
 #ifndef OPENGL_H_
 #define OPENGL_H_
 
-#include <GLFW/glfw3.h>
-
 bool init_opengl();
 void cleanup_opengl();
-GLFWwindow *create_opengl_window();
 
-void clear_gl();
-#endif // OPENGL_H_
+#endif // OPENGL_H_
\ No newline at end of file
index 0b495ed..748b4e7 100644 (file)
@@ -6,7 +6,7 @@
 class TextureGL : public Texture {
 private:
        unsigned int tex;
-       GLenum target;
+       unsigned int target;
        
        virtual void update() override;
 public:
index 24941b5..105caba 100644 (file)
-#include "vulkan/vk.h"
-extern GLFWwindow win;
+#define GLFW_INCLUDE_VULKAN
+#include <GLFW/glfw3.h>
+
+#include <alloca.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <string>
+#include <vector>
+
+#include "gfxapi.h"
+
+/* global variables */
+extern GLFWwindow *win;
+extern int win_w;
+extern int win_h;
+
+/* static variables */
+static std::vector<std::string> enabled_extension_names;
+static VkInstance inst;
+static VkDevice device;
+static VkPhysicalDevice pdev;
+static VkSurfaceKHR surface;
+static uint32_t device_mem_idx;
+static uint32_t num_queues;
+static uint32_t qfamily_idx;
+
+static const char *print_vulkan_error(VkResult error);
+static const char *dev_type_str(VkPhysicalDeviceType type);
+static const char *heap_flags_str(VkMemoryHeapFlags flags);
+static const char *memtype_flags_str(VkMemoryPropertyFlags flags);
+static const char *queue_flags_str(VkQueueFlags flags);
+
+/* static fumctions */
+static bool create_instance();
+static bool create_device();
 
 bool init_vulkan()
 {
+       if(!glfwInit()) {
+               fprintf(stderr, "Failed to initialize GLFW.\n");
+               return false;
+       }
+
+       if(!glfwVulkanSupported()) {
+               fprintf(stderr, "No Vulkan support on the device.\n");
+               return false;
+       }
+
+       if(!create_instance()) {
+               fprintf(stderr, "Failed to enable validation.\n");
+               return false;
+       }
+
+       if(!glfwGetPhysicalDevicePresentationSupport(inst, pdev, qfamily_idx)) {
+               fprintf(stderr, "Presentation support not found.\n");
+               return false;
+       }
+
+       glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
+       if(!(win = glfwCreateWindow(win_w, win_h, "vkcow", 0, 0))) {
+               fprintf(stderr, "Failed to create window.\n");
+               return false;
+       }
+
+       if(VkResult err = glfwCreateWindowSurface(inst, win, 0, &surface)) {
+               fprintf(stderr, "Failed to create KHR surface: %s\n", print_vulkan_error(err));
+               return false;
+       }
+
        return true;
 }
 
 void cleanup_vulkan()
 {
+       //TODOs according to the book:
+       // 1- make sure all threads have been terminated (when I add threads)
+       // 2- destroy objects in *reverse* order
+
+       vkDestroySurfaceKHR(inst, surface, 0);
+
+       if(vkDeviceWaitIdle(device) == VK_SUCCESS) {
+               vkDestroyDevice(device, 0);
+               vkDestroyInstance(inst, 0);
+       }
+}
+
+static bool create_instance()
+{
+       /* enable layers */
+       uint32_t layer_count = 0;
+       std::vector<const char *> enabled_layers;
+
+       if(vkEnumerateInstanceLayerProperties(&layer_count, 0) != VK_SUCCESS) {
+               fprintf(stderr, "Failed to query layer properties.\n");
+               return false;
+       }
+
+       if(layer_count > 0) {
+               VkLayerProperties *layers = (VkLayerProperties *)alloca(layer_count * sizeof *layers);
+               vkEnumerateInstanceLayerProperties(&layer_count, layers);
+               for(uint32_t i=0; i<layer_count; i++) {
+                       if(strcmp(layers[i].layerName, "VK_LAYER_LUNARG_standard_validation")) {
+                               enabled_layers.push_back(layers[i].layerName);
+                       }
+               }
+       }
+
+       /* enable extensions */
+       uint32_t extensions_count = 0;
+       std::vector<const char *> enabled_extensions;
+
+       if(vkEnumerateInstanceExtensionProperties(0, &extensions_count, 0) != VK_SUCCESS) {
+               fprintf(stderr, "Failed to enumerate instance extension properties\n");
+               return false;
+       }
+
+       if(extensions_count > 0) {
+               VkExtensionProperties *extensions = (VkExtensionProperties *)alloca(extensions_count * sizeof *extensions);
+               vkEnumerateInstanceExtensionProperties(0, &extensions_count, extensions);
+
+               for(uint32_t i=0; i<extensions_count; i++) {
+                       printf("Extension %u: %s %u.\n", i, extensions[i].extensionName, extensions[i].specVersion);
+                       //enable all the available extensions
+                       enabled_extensions.push_back(extensions[i].extensionName);
+                       enabled_extension_names.push_back(std::string(extensions[i].extensionName));
+               }
+       }
+
+       /* create instance */
+       VkInstanceCreateInfo create_info;
+       memset(&create_info, 0, sizeof create_info);
+       create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
+
+       if(!enabled_layers.empty()) {
+               create_info.enabledLayerCount = enabled_layers.size();
+               create_info.ppEnabledLayerNames = enabled_layers.data();
+       }
+
+       if(!enabled_extensions.empty()) {
+               create_info.enabledExtensionCount = enabled_extensions.size();
+               create_info.ppEnabledExtensionNames = enabled_extensions.data();
+       }
+
+       if(vkCreateInstance(&create_info, 0, &inst) != VK_SUCCESS) {
+               fprintf(stderr, "Failed to create instance.\n");
+               return false;
+       }
+
+       if(!create_device())
+               return false;
+
+       return true;
+}
+
+static bool create_device()
+{
+       int qfam_idx = -1;
+       int pdev_idx = -1;
+
+       uint32_t dev_count;
+       if(vkEnumeratePhysicalDevices(inst, &dev_count, 0) != VK_SUCCESS) {
+               fprintf(stderr, "Failed to enumerate physical devices.\n");
+               return false;
+       }
+       printf("%u devices found.\n", (unsigned int)dev_count);
+
+       VkPhysicalDevice *phys_dev = (VkPhysicalDevice *)alloca(dev_count * sizeof *phys_dev);
+       vkEnumeratePhysicalDevices(inst, &dev_count, phys_dev);
+       VkPhysicalDeviceMemoryProperties memprop;
+
+       for(uint32_t i=0; i<dev_count; i++) {
+               VkPhysicalDeviceProperties dev_props;
+               vkGetPhysicalDeviceProperties(phys_dev[i], &dev_props);
+
+               //memory heaps:
+               vkGetPhysicalDeviceMemoryProperties(phys_dev[i], &memprop);
+               printf("\tNumber of heaps: %u\n", memprop.memoryHeapCount);
+               for(uint32_t j=0; j<memprop.memoryHeapCount; j++) {
+                       printf("\t\tHeap %u size: %lu\n", j, (unsigned long)memprop.memoryHeaps[j].size);
+                       printf("\t\tHeap %u flags: %s\n", j, heap_flags_str(memprop.memoryHeaps[j].flags));
+               }
+               //memory types
+               printf("\tMemory types: %u\n", memprop.memoryTypeCount);
+               for(uint32_t j=0; j<memprop.memoryTypeCount; j++) {
+                       printf("\t\tType %u heap index: %u\n", j, memprop.memoryTypes[j].heapIndex);
+                       printf("\t\tType %u flags: %s\n", j, memtype_flags_str(memprop.memoryTypes[j].propertyFlags));
+               }
+
+               //supported features
+               VkPhysicalDeviceFeatures features;
+               vkGetPhysicalDeviceFeatures(phys_dev[i], &features);
+
+               //queue families
+               uint32_t qfam_count;
+               vkGetPhysicalDeviceQueueFamilyProperties(phys_dev[i], &qfam_count, 0);
+               printf("\tQueue Families: %u\n", qfam_count);
+               VkQueueFamilyProperties *qfam_props = new VkQueueFamilyProperties[qfam_count];
+               vkGetPhysicalDeviceQueueFamilyProperties(phys_dev[i], &qfam_count, qfam_props);
+               for(uint32_t j=0; j<qfam_count; j++) {
+                       printf("\t\tFamily %u flags: %s\n", j, queue_flags_str(qfam_props[j].queueFlags));
+                       printf("\t\tFamily %u number of queues: %u\n", j, qfam_props[j].queueCount);
+
+                       if((qfam_props[j].queueFlags & VK_QUEUE_GRAPHICS_BIT) && (pdev_idx == -1)) {
+                               pdev_idx = i;
+                               qfam_idx = j;
+                               num_queues = qfam_props[j].queueCount;
+                       }
+               }
+               delete [] qfam_props;
+       }
+
+       if(pdev_idx == -1) {
+               fprintf(stderr, "No suitable devices found.\n");
+               return false;
+       }
+
+       pdev = *(phys_dev + pdev_idx);
+       qfamily_idx = qfam_idx;
+
+       /*      uint32_t layer_count;
+               if(vkEnumerateDeviceLayerProperties(pdev, &layer_count, 0) != VK_SUCCESS) {
+                       fprintf(stderr, "Failed to enumerate device layers.\n");
+                       return false;
+               }
+               if(layer_count > 0) {
+                       VkLayerProperties *layers = (VkLayerProperties*)alloca(layer_count * sizeof *layers);
+                       vkEnumerateDeviceLayerProperties(pdev, &layer_count, layers);
+                       printf("%u layers found.\n", layer_count);
+                       for(uint32_t i=0; i<layer_count; i++) {
+                               printf("Layer %u: %s (%u, %u)\n", i, layers[i].layerName,
+                                               layers[i].specVersion, layers[i].implementationVersion);
+                               printf("\tDesc: %s\n", layers[i].description);
+                       }
+               }
+       */
+       VkDeviceCreateInfo dev_info;
+       memset(&dev_info, 0, sizeof dev_info);
+       dev_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
+
+       VkDeviceQueueCreateInfo dev_qinfo;
+       memset(&dev_qinfo, 0, sizeof dev_qinfo);
+       dev_qinfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+       dev_qinfo.queueFamilyIndex = qfam_idx;
+       dev_qinfo.queueCount = 1;
+
+       dev_info.queueCreateInfoCount = 1;
+       dev_info.pQueueCreateInfos = &dev_qinfo;
+
+       if(vkCreateDevice(pdev, &dev_info, 0, &device) != VK_SUCCESS) {
+               fprintf(stderr, "Failed to create logical device.\n");
+               return false;
+       }
+
+       vkGetPhysicalDeviceMemoryProperties(pdev, &memprop);
+       for(uint32_t j=0; j<memprop.memoryTypeCount; j++) {
+               if(memprop.memoryTypes[j].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
+                       device_mem_idx = j;
+                       printf("Selected device memory index: %u\n", device_mem_idx);
+                       break;
+               }
+       }
+
+       return true;
+}
+
+static const char *print_vulkan_error(VkResult error)
+{
+       std::string errmsg;
+       switch(error) {
+       case VK_SUCCESS:
+               errmsg = std::string("VK_SUCCESS");
+               break;
+       case VK_NOT_READY:
+               errmsg = std::string("VK_NOT_READY");
+               break;
+       case VK_TIMEOUT:
+               errmsg = std::string("VK_TIMEOUT");
+               break;
+       case VK_EVENT_SET:
+               errmsg = std::string("VK_EVENT_SET");
+               break;
+       case VK_EVENT_RESET:
+               errmsg = std::string("VK_EVENT_RESET");
+               break;
+       case VK_INCOMPLETE:
+               errmsg = std::string("VK_EVENT");
+               break;
+       case VK_ERROR_OUT_OF_HOST_MEMORY:
+               errmsg = std::string("VK_ERROR_OUT_OF_HOST_MEMORY");
+               break;
+       case VK_ERROR_OUT_OF_DEVICE_MEMORY:
+               errmsg = std::string("VK_ERROR_OUT_OF_DEVICE_MEMORY");
+               break;
+       case VK_ERROR_INITIALIZATION_FAILED:
+               errmsg = std::string("VK_ERROR_INITIALIZATION_FAILED");
+               break;
+       case VK_ERROR_DEVICE_LOST:
+               errmsg = std::string("VK_ERROR_DEVICE_LOST");
+               break;
+       case VK_ERROR_MEMORY_MAP_FAILED:
+               errmsg = std::string("VK_ERROR_MEMORY_MAP_FAILED");
+               break;
+       case VK_ERROR_LAYER_NOT_PRESENT:
+               errmsg = std::string("VK_ERROR_LAYER_NOT_PRESENT");
+               break;
+       case VK_ERROR_EXTENSION_NOT_PRESENT:
+               errmsg = std::string("VK_ERROR_EXTENSION_NOT_PRESENT");
+               break;
+       case VK_ERROR_FEATURE_NOT_PRESENT:
+               errmsg = std::string("VK_ERROR_FEATURE_NOT_PRESENT");
+               break;
+       case VK_ERROR_INCOMPATIBLE_DRIVER:
+               errmsg = std::string("VK_ERROR_INCOMPATIBLE_DRIVER");
+               break;
+       case VK_ERROR_TOO_MANY_OBJECTS:
+               errmsg = std::string("VK_ERROR_TOO_MANY_OBJECTS");
+               break;
+       case VK_ERROR_FORMAT_NOT_SUPPORTED:
+               errmsg = std::string("VK_ERROR_FORMAT_NOT_SUPPORTED");
+               break;
+       case VK_ERROR_FRAGMENTED_POOL:
+               errmsg = std::string("VK_ERROR_FRAGMENTED_POOL");
+               break;
+       default:
+               errmsg = std::string("UNKNOWN");
+               break;
+       }
+
+       return errmsg.c_str();
+}
+
+static const char *dev_type_str(VkPhysicalDeviceType type)
+{
+       switch(type) {
+       case VK_PHYSICAL_DEVICE_TYPE_OTHER:
+               return "other";
+       case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
+               return "integrated GPU";
+       case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
+               return "discrete GPU";
+       case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
+               return "virtual GPU";
+       case VK_PHYSICAL_DEVICE_TYPE_CPU:
+               return "CPU";
+       default:
+               break;
+       }
+       return "unknown";
+}
+
+static const char *heap_flags_str(VkMemoryHeapFlags flags)
+{
+       static std::string str;
+       str.clear();
+       if(flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) {
+               str += "device-local ";
+       }
+       if(!str.empty())
+               str.pop_back();
+       return str.c_str();
 }
 
-GLFWwindow *create_vulkan_window()
+static const char *memtype_flags_str(VkMemoryPropertyFlags flags)
 {
-       return 0;
+       static std::string str;
+       str.clear();
+       if(flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
+               str += "device-local ";
+       }
+       if(flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
+               str += "host-visible ";
+       }
+       if(flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) {
+               str += "host-coherent ";
+       }
+       if(flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) {
+               str += "host-cached ";
+       }
+       if(flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) {
+               str += "lazily-allocated ";
+       }
+       if(!str.empty())
+               str.pop_back();
+       return str.c_str();
 }
 
-void clbk_clear_vk()
+static const char *queue_flags_str(VkQueueFlags flags)
 {
+       static std::string str;
+       str.clear();
+       if(flags & VK_QUEUE_GRAPHICS_BIT)
+               str += "graphics ";
+       if(flags & VK_QUEUE_COMPUTE_BIT)
+               str += "compute ";
+       if(flags & VK_QUEUE_TRANSFER_BIT)
+               str += "transfer ";
+       if(flags & VK_QUEUE_SPARSE_BINDING_BIT)
+               str += "sparse-binding ";
+       if(!str.empty())
+               str.pop_back();
+       return str.c_str();
 }
\ No newline at end of file
index b391a52..5e62b41 100644 (file)
@@ -1,12 +1,9 @@
 #ifndef VK_H_
 #define VK_H_
 
-#define GLFW_INCLUDE_VULKAN
-#include <GLFW/glfw3.h>
+#include <vulkan/vulkan.h>
 
 bool init_vulkan();
 void cleanup_vulkan();
-GLFWwindow *create_vulkan_window();
 
-void clbk_clear_vk();
-#endif // VK_H_
+#endif // VK_H_
\ No newline at end of file