| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // This test is intended to be run manually from within biscotti_guest. |
| |
| #include "magma.h" |
| |
| #include <dlfcn.h> |
| #include <errno.h> |
| #include <fcntl.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <unistd.h> |
| #include <vulkan/vulkan.h> |
| |
| #define CHECK(x) \ |
| do { \ |
| if (!(x)) { \ |
| printf("Check Failed (%s): \"%s\"\n", #x, strerror(errno)); \ |
| exit(EXIT_FAILURE); \ |
| } \ |
| } while (0) |
| |
| // TODO(MA-520): this should be part of vm initialization, not a magma API |
| extern bool magma_write_driver_to_filesystem(int32_t file_descriptor); |
| |
| PFN_vkVoidFunction get_vkCreateInstance(void* driver) |
| { |
| // This method emulates a small part of the initialization logic in the Vulkan loader. |
| |
| static const char* vulkan_main_entrypoint = "vk_icdGetInstanceProcAddr"; |
| printf("dlsym for Address of Symbol %s\n", vulkan_main_entrypoint); |
| PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = |
| (PFN_vkGetInstanceProcAddr)dlsym(driver, vulkan_main_entrypoint); |
| CHECK(vkGetInstanceProcAddr != nullptr); |
| printf("Address Acquired\n"); |
| |
| static const char* vulkan_instance_entrypoint = "vkCreateInstance"; |
| printf("vkGetInstanceProcAddr for Address of Entrypoint %s\n", vulkan_instance_entrypoint); |
| PFN_vkVoidFunction addr_vkCreateInstance = |
| vkGetInstanceProcAddr(nullptr, vulkan_instance_entrypoint); |
| CHECK(addr_vkCreateInstance != nullptr); |
| printf("Address Acquired\n"); |
| |
| return addr_vkCreateInstance; |
| } |
| |
| int main(int argc, char* argv[]) |
| { |
| static const char* device_path = "/dev/wl0"; |
| printf("Open Device %s\n", device_path); |
| int fd = open(device_path, O_NONBLOCK); |
| CHECK(fd != -1); |
| printf("Device Opened\n"); |
| |
| uint64_t device_id = 0; |
| printf("Query Device ID 0x%08X\n", MAGMA_QUERY_DEVICE_ID); |
| magma_status_t status = magma_query(fd, MAGMA_QUERY_DEVICE_ID, &device_id); |
| CHECK(status == MAGMA_STATUS_OK); |
| printf("Device ID: 0x%016lX\n", device_id); |
| |
| magma_connection_t connection{}; |
| printf("Create Connection\n"); |
| status = magma_create_connection(fd, &connection); |
| CHECK(status == MAGMA_STATUS_OK); |
| CHECK(connection != nullptr); |
| printf("Connection Created\n"); |
| |
| printf("Release Connection\n"); |
| magma_release_connection(connection); |
| printf("Connection Released\n"); |
| |
| printf("Write Driver to FS\n"); |
| bool ok = magma_write_driver_to_filesystem(fd); |
| CHECK(ok); |
| printf("Driver Written to FS\n"); |
| |
| static const char* driver_path = "/libvulkan_magma.so"; |
| printf("Load Driver %s\n", driver_path); |
| void* driver = dlopen(driver_path, RTLD_NOW); |
| CHECK(driver != nullptr); |
| printf("Driver Loaded\n"); |
| |
| PFN_vkCreateInstance vkCreateInstance = (PFN_vkCreateInstance)get_vkCreateInstance(driver); |
| |
| printf("Creating Vulkan Instance\n"); |
| VkApplicationInfo application_info{}; |
| application_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; |
| application_info.pApplicationName = "magma_test"; |
| application_info.applicationVersion = VK_MAKE_VERSION(1, 0, 0); |
| application_info.pEngineName = "no-engine"; |
| application_info.engineVersion = VK_MAKE_VERSION(1, 0, 0); |
| application_info.apiVersion = VK_API_VERSION_1_0; |
| VkInstanceCreateInfo instance_create_info{}; |
| instance_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; |
| instance_create_info.pApplicationInfo = &application_info; |
| VkInstance instance{}; |
| VkResult result = vkCreateInstance(&instance_create_info, nullptr, &instance); |
| CHECK(result == VK_SUCCESS); |
| printf("Vulkan Instance Created\n"); |
| |
| return 0; |
| } |