summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am17
-rw-r--r--src/vulkan-helpers.h57
-rw-r--r--src/vulkan-renderer.c222
3 files changed, 296 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am
index 62719c95..689132aa 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -215,6 +215,23 @@ gl_renderer_la_SOURCES = \
shared/helpers.h
endif
+if ENABLE_VULKAN
+module_LTLIBRARIES += vulkan-renderer.la
+vulkan_renderer_la_LDFLAGS = -module -avoid-version
+vulkan_renderer_la_LIBADD = $(COMPOSITOR_LIBS) -lvulkan
+vulkan_renderer_la_CFLAGS = \
+ $(COMPOSITOR_CFLAGS) \
+ $(VULKAN_RENDERER_CFLAGS) \
+ $(AM_CFLAGS)
+vulkan_renderer_la_SOURCES = \
+ src/vulkan-helpers.h \
+ src/vulkan-renderer.h \
+ src/vulkan-renderer.c \
+ src/vertex-clipping.c \
+ src/vertex-clipping.h \
+ shared/helpers.h
+endif
+
if ENABLE_X11_COMPOSITOR
module_LTLIBRARIES += x11-backend.la
x11_backend_la_LDFLAGS = -module -avoid-version
diff --git a/src/vulkan-helpers.h b/src/vulkan-helpers.h
new file mode 100644
index 00000000..749d68af
--- /dev/null
+++ b/src/vulkan-helpers.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __VULKAN_HELPERS_H__
+#define __VULKAN_HELPERS_H__
+
+#include <string.h>
+
+#define __VK_HELP_STRUCT_NAME(StructName, STRUCT_NAME) \
+static const VkStructureType __vulkan_helpers_##StructName##_type = \
+ VK_STRUCTURE_TYPE_##STRUCT_NAME;
+
+__VK_HELP_STRUCT_NAME(ApplicationInfo, APPLICATION_INFO);
+__VK_HELP_STRUCT_NAME(DeviceCreateInfo, DEVICE_CREATE_INFO);
+__VK_HELP_STRUCT_NAME(MemoryAllocInfo, MEMORY_ALLOC_INFO);
+__VK_HELP_STRUCT_NAME(ImageViewCreateInfo, IMAGE_VIEW_CREATE_INFO);
+
+__VK_HELP_STRUCT_NAME(InstanceCreateInfo, INSTANCE_CREATE_INFO);
+
+__VK_HELP_STRUCT_NAME(SurfaceDescriptionWindowWSI, SURFACE_DESCRIPTION_WINDOW_WSI);
+
+#define VK_STRUCT_DECL(StructName, name) \
+Vk##StructName name = { __vulkan_helpers_##StructName##_type, NULL }
+
+#define VK_STRUCT(StructName, name, ...) \
+ Vk##StructName name; \
+ do { \
+ Vk##StructName s; \
+ memset(&s, 0, sizeof(s)); \
+ s.sType = __vulkan_helpers_##StructName##_type; \
+ __VA_ARGS__; \
+ name = s; \
+ } while (0)
+
+#endif /* __VULKAN_HELPERS_H__ */
diff --git a/src/vulkan-renderer.c b/src/vulkan-renderer.c
new file mode 100644
index 00000000..e0a9b03c
--- /dev/null
+++ b/src/vulkan-renderer.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define VK_PROTOTYPES
+
+#include <vulkan/vulkan.h>
+#include <vulkan/vk_wsi_swapchain.h>
+#include <vulkan/vk_wsi_device_swapchain.h>
+
+#include "shared/helpers.h"
+#include "vulkan-renderer.h"
+#include "vulkan-helpers.h"
+
+struct vk_renderer {
+ VkInstance instance;
+ VkPhysicalDevice physical_device;
+ VkDevice device;
+ VkQueue queue;
+
+ PFN_vkGetPhysicalDeviceSurfaceSupportWSI get_pd_surface_support;
+};
+
+static int
+vk_renderer_output_create(struct weston_output *output,
+ VkSurfaceDescriptionWindowWSI *window,
+ VkFormat *formats, const int n_formats)
+{ return -1; /* TODO */ }
+
+static void
+vk_renderer_output_destroy(struct weston_output *output)
+{ /* TODO */ }
+
+static void
+vk_renderer_output_set_border(struct weston_output *output,
+ enum vk_renderer_border_side side,
+ int32_t width, int32_t height,
+ int32_t tex_width, unsigned char *data)
+{ /* TODO */ }
+
+/* Chooses a physical device and queue family that should work */
+static int
+vk_renderer_choose_physical_device(struct vk_renderer *r,
+ VkPlatformWSI platform,
+ void *native_platform_handle,
+ VkPhysicalDevice *physical_device,
+ uint32_t *queue_family)
+{
+ VkResult result;
+ uint32_t i, j, pd_count, queue_count;
+ VkPhysicalDevice *pdevs;
+ VkPhysicalDeviceQueueProperties *queue_props;
+ VkBool32 supported;
+
+ result = vkEnumeratePhysicalDevices(r->instance, &pd_count, NULL);
+ if (result != VK_SUCCESS || pd_count == 0)
+ return -1;
+
+ pdevs = malloc(pd_count * sizeof(*pdevs));
+ if (pdevs == NULL)
+ return -1;
+
+ result = vkEnumeratePhysicalDevices(r->instance, &pd_count, pdevs);
+ if (result != VK_SUCCESS)
+ goto fail;
+
+ VK_STRUCT(SurfaceDescriptionWindowWSI, wsi_window,
+ s.platform = platform,
+ s.pPlatformHandle = native_platform_handle,
+ s.pPlatformWindow = NULL /* XXX: This shouldn't be needed? */
+ );
+
+ /* Grab the first physical device that claims to have the WSI
+ * support that we need.
+ */
+ for (i = 0; i < pd_count; i++) {
+ result = vkGetPhysicalDeviceQueueCount(pdevs[i], &queue_count);
+ if (result != VK_SUCCESS)
+ goto fail;
+
+ queue_props = malloc(queue_count * sizeof(*queue_props));
+
+ result = vkGetPhysicalDeviceQueueProperties(pdevs[i],
+ queue_count,
+ queue_props);
+ if (result != VK_SUCCESS) {
+ free(queue_props);
+ goto fail;
+ }
+
+ for (j = 0; j < queue_count; j++) {
+ if (!(queue_props[j].queueFlags & VK_QUEUE_GRAPHICS_BIT))
+ continue;
+
+ result = r->get_pd_surface_support(pdevs[i], j,
+ (void *)&wsi_window,
+ &supported);
+ if (supported) {
+ /* We've found a physical device and queue
+ * family that works. Let's go ahead and
+ * use that one.
+ */
+ *physical_device = pdevs[i];
+ *queue_family = j;
+ free(pdevs);
+ return 0;
+ }
+ }
+ }
+
+fail:
+ free(pdevs);
+ return -1;
+}
+
+const char *instance_extensions[] = {
+ "VK_WSI_swapchain",
+};
+
+const char *device_extensions[] = {
+ "VK_WSI_device_swapchain",
+};
+
+static int
+vk_renderer_create(struct weston_compositor *ec, VkPlatformWSI platform,
+ void *native_platform_handle)
+{
+ struct vk_renderer *r;
+ VkResult result;
+ uint32_t queue_family;
+
+ r = zalloc(sizeof *r);
+ if (r == NULL)
+ return -1;
+
+ VK_STRUCT(ApplicationInfo, app_info,
+ s.pAppName = "org.freedesktop.wayland.weston",
+ s.appVersion = 1,
+ s.pEngineName = "org.freedesktop.wayland.weston",
+ s.engineVersion = 1,
+ s.apiVersion = VK_MAKE_VERSION(0, 138, 2)
+ );
+
+ VK_STRUCT(InstanceCreateInfo, ic_info,
+ s.pAppInfo = &app_info,
+ s.pAllocCb = NULL, /* Use driver default */
+ s.extensionCount = ARRAY_LENGTH(instance_extensions),
+ s.ppEnabledExtensionNames = instance_extensions
+ );
+
+ result = vkCreateInstance(&ic_info, &r->instance);
+ if (result != VK_SUCCESS)
+ goto fail_alloc;
+
+ r->get_pd_surface_support = (PFN_vkGetPhysicalDeviceSurfaceSupportWSI)
+ vkGetInstanceProcAddr(r->instance,
+ "vkGetPhysicalDeviceSurfaceSupportWSI");
+
+ if (vk_renderer_choose_physical_device(r, platform,
+ native_platform_handle,
+ &r->physical_device,
+ &queue_family) < 0) {
+ goto fail_instance;
+ }
+
+ VkDeviceQueueCreateInfo queue_info = {
+ queue_family,
+ 1 /* queue count */
+ };
+
+ VK_STRUCT(DeviceCreateInfo, dev_info,
+ s.queueRecordCount = 1,
+ s.pRequestedQueues = &queue_info,
+ s.extensionCount = ARRAY_LENGTH(device_extensions),
+ s.ppEnabledExtensionNames = device_extensions
+ );
+
+ result = vkCreateDevice(r->physical_device, &dev_info, &r->device);
+ if (result != VK_SUCCESS)
+ goto fail_instance;
+
+ result = vkGetDeviceQueue(r->device, queue_family, 0, &r->queue);
+ if (result != VK_SUCCESS)
+ goto fail_device;
+
+fail_device:
+ vkDestroyDevice(r->device);
+fail_instance:
+ vkDestroyInstance(r->instance);
+fail_alloc:
+ free(r);
+
+ return -1;
+}
+
+WL_EXPORT struct vulkan_renderer_interface vulkan_renderer_interface = {
+ .create = vk_renderer_create,
+ .output_create = vk_renderer_output_create,
+ .output_destroy = vk_renderer_output_destroy,
+ .output_set_border = vk_renderer_output_set_border,
+};