mirror of
https://github.com/Yours3lf/rpi-vk-driver.git
synced 2025-01-30 22:52:14 +01:00
added surface creator extension
This commit is contained in:
parent
c28f79e87a
commit
1e73f44f50
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
CMakeLists.txt.user
|
||||
build-debug
|
293
driver/driver.c
293
driver/driver.c
@ -15,6 +15,9 @@
|
||||
#include <drm/vc4_drm.h>
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
#include "vkExt.h"
|
||||
|
||||
#include "modeset.h"
|
||||
|
||||
#ifndef min
|
||||
#define min(a, b) (a < b ? a : b)
|
||||
@ -56,8 +59,39 @@ typedef struct VkPhysicalDevice_T
|
||||
int dummy;
|
||||
} _physicalDevice;
|
||||
|
||||
typedef struct VkDevice_T
|
||||
{
|
||||
int dummy;
|
||||
} _device;
|
||||
|
||||
typedef struct VkQueue_T
|
||||
{
|
||||
int familyIndex;
|
||||
} _queue;
|
||||
|
||||
VkQueueFamilyProperties _queueFamilyProperties[] =
|
||||
{
|
||||
{
|
||||
//TODO maybe sparse textures later?
|
||||
.queueFlags = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT,
|
||||
.queueCount = 1,
|
||||
.timestampValidBits = 32, //TODO dunno, 32 for now
|
||||
.minImageTransferGranularity = {1, 1, 1}
|
||||
}
|
||||
};
|
||||
const int numQueueFamilies = sizeof(_queueFamilyProperties)/sizeof(VkQueueFamilyProperties);
|
||||
|
||||
_queue _queuesByFamily[][1] =
|
||||
{
|
||||
{
|
||||
{
|
||||
.familyIndex = 0
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#vkCreateInstance
|
||||
* https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#vkCreateInstance
|
||||
* There is no global state in Vulkan and all per-application state is stored in a VkInstance object. Creating a VkInstance object initializes the Vulkan library
|
||||
* vkCreateInstance verifies that the requested layers exist. If not, vkCreateInstance will return VK_ERROR_LAYER_NOT_PRESENT. Next vkCreateInstance verifies that
|
||||
* the requested extensions are supported (e.g. in the implementation or in any enabled instance layer) and if any requested extension is not supported,
|
||||
@ -70,6 +104,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(
|
||||
VkInstance* pInstance)
|
||||
{
|
||||
*pInstance = malloc(sizeof(_instance));
|
||||
assert(pInstance);
|
||||
|
||||
//TODO: allocator is ignored for now
|
||||
assert(pAllocator == 0);
|
||||
@ -79,12 +114,14 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(
|
||||
|
||||
//TODO: need to check here that the requested
|
||||
//extensions are supported
|
||||
//eg.
|
||||
//VK_KHR_surface
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#devsandqueues-physical-device-enumeration
|
||||
* https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#devsandqueues-physical-device-enumeration
|
||||
* If pPhysicalDevices is NULL, then the number of physical devices available is returned in pPhysicalDeviceCount. Otherwise, pPhysicalDeviceCount must point to a
|
||||
* variable set by the user to the number of elements in the pPhysicalDevices array, and on return the variable is overwritten with the number of handles actually
|
||||
* written to pPhysicalDevices. If pPhysicalDeviceCount is less than the number of physical devices available, at most pPhysicalDeviceCount structures will be written.
|
||||
@ -96,6 +133,8 @@ VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(
|
||||
uint32_t* pPhysicalDeviceCount,
|
||||
VkPhysicalDevice* pPhysicalDevices)
|
||||
{
|
||||
assert(instance);
|
||||
|
||||
//TODO is there a way to check if there's a gpu (and it's the rPi)?
|
||||
int gpuExists = access( "/dev/dri/card0", F_OK ) != -1;
|
||||
|
||||
@ -114,7 +153,9 @@ VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(
|
||||
|
||||
for(int c = 0; c < elementsWritten; ++c)
|
||||
{
|
||||
//TODO no allocator, we probably shouldn't allocate
|
||||
pPhysicalDevices[c] = malloc(sizeof(_physicalDevice));
|
||||
assert(pPhysicalDevices[c]);
|
||||
}
|
||||
|
||||
*pPhysicalDeviceCount = elementsWritten;
|
||||
@ -130,15 +171,191 @@ VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(
|
||||
}
|
||||
|
||||
/*
|
||||
* https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#vkGetPhysicalDeviceQueueFamilyProperties
|
||||
*
|
||||
* https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#vkGetPhysicalDeviceQueueFamilyProperties
|
||||
* If pQueueFamilyProperties is NULL, then the number of queue families available is returned in pQueueFamilyPropertyCount.
|
||||
* Otherwise, pQueueFamilyPropertyCount must point to a variable set by the user to the number of elements in the pQueueFamilyProperties array,
|
||||
* and on return the variable is overwritten with the number of structures actually written to pQueueFamilyProperties. If pQueueFamilyPropertyCount
|
||||
* is less than the number of queue families available, at most pQueueFamilyPropertyCount structures will be written.
|
||||
*/
|
||||
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
uint32_t* pQueueFamilyPropertyCount,
|
||||
VkQueueFamilyProperties* pQueueFamilyProperties)
|
||||
{
|
||||
assert(physicalDevice);
|
||||
assert(pQueueFamilyPropertyCount);
|
||||
|
||||
if(!pQueueFamilyProperties)
|
||||
{
|
||||
*pQueueFamilyPropertyCount = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
int arraySize = *pQueueFamilyPropertyCount;
|
||||
int elementsWritten = min(numQueueFamilies, arraySize);
|
||||
|
||||
for(int c = 0; c < elementsWritten; ++c)
|
||||
{
|
||||
pQueueFamilyProperties[c] = _queueFamilyProperties[c];
|
||||
}
|
||||
|
||||
*pQueueFamilyPropertyCount = elementsWritten;
|
||||
}
|
||||
|
||||
/*
|
||||
* https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#vkGetPhysicalDeviceSurfaceSupportKHR
|
||||
* does this queue family support presentation to this surface?
|
||||
*/
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupportKHR(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
uint32_t queueFamilyIndex,
|
||||
VkSurfaceKHR surface,
|
||||
VkBool32* pSupported)
|
||||
{
|
||||
assert(pSupported);
|
||||
assert(surface);
|
||||
assert(physicalDevice);
|
||||
|
||||
assert(queueFamilyIndex < numQueueFamilies);
|
||||
|
||||
*pSupported = VK_TRUE; //TODO suuure for now, but we should verify if queue supports presenting to surface
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of our RPI specific "extension"
|
||||
*/
|
||||
VkResult vkCreateRpiSurfaceKHR(
|
||||
VkInstance instance,
|
||||
const VkRpiSurfaceCreateInfoKHR* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkSurfaceKHR* pSurface)
|
||||
{
|
||||
assert(pSurface);
|
||||
//TODO: allocator is ignored for now
|
||||
assert(pAllocator == 0);
|
||||
|
||||
int ret = modeset_open("/dev/dri/card0"); assert(!ret);
|
||||
*pSurface = (VkSurfaceKHR)modeset_create();
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#vkDestroySurfaceKHR
|
||||
* Destroying a VkSurfaceKHR merely severs the connection between Vulkan and the native surface,
|
||||
* and does not imply destroying the native surface, closing a window, or similar behavior
|
||||
* (but we'll do so anyways...)
|
||||
*/
|
||||
VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR(
|
||||
VkInstance instance,
|
||||
VkSurfaceKHR surface,
|
||||
const VkAllocationCallbacks* pAllocator)
|
||||
{
|
||||
assert(instance);
|
||||
assert(surface);
|
||||
|
||||
//TODO: allocator is ignored for now
|
||||
assert(pAllocator == 0);
|
||||
|
||||
modeset_destroy((modeset_dev*)surface);
|
||||
modeset_close();
|
||||
}
|
||||
|
||||
/*
|
||||
* https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#vkCreateDevice
|
||||
* vkCreateDevice verifies that extensions and features requested in the ppEnabledExtensionNames and pEnabledFeatures
|
||||
* members of pCreateInfo, respectively, are supported by the implementation. If any requested extension is not supported,
|
||||
* vkCreateDevice must return VK_ERROR_EXTENSION_NOT_PRESENT. If any requested feature is not supported, vkCreateDevice must return
|
||||
* VK_ERROR_FEATURE_NOT_PRESENT. Support for extensions can be checked before creating a device by querying vkEnumerateDeviceExtensionProperties
|
||||
* After verifying and enabling the extensions the VkDevice object is created and returned to the application.
|
||||
* If a requested extension is only supported by a layer, both the layer and the extension need to be specified at vkCreateInstance
|
||||
* time for the creation to succeed. Multiple logical devices can be created from the same physical device. Logical device creation may
|
||||
* fail due to lack of device-specific resources (in addition to the other errors). If that occurs, vkCreateDevice will return VK_ERROR_TOO_MANY_OBJECTS.
|
||||
*/
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
const VkDeviceCreateInfo* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkDevice* pDevice)
|
||||
{
|
||||
assert(physicalDevice);
|
||||
assert(pDevice);
|
||||
|
||||
//TODO verify extensions, features
|
||||
|
||||
//TODO: allocator is ignored for now
|
||||
assert(pAllocator == 0);
|
||||
|
||||
*pDevice = malloc(sizeof(_device));
|
||||
if(!pDevice)
|
||||
{
|
||||
return VK_ERROR_TOO_MANY_OBJECTS;
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#vkGetDeviceQueue
|
||||
* vkGetDeviceQueue must only be used to get queues that were created with the flags parameter of VkDeviceQueueCreateInfo set to zero.
|
||||
* To get queues that were created with a non-zero flags parameter use vkGetDeviceQueue2.
|
||||
*/
|
||||
VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue(
|
||||
VkDevice device,
|
||||
uint32_t queueFamilyIndex,
|
||||
uint32_t queueIndex,
|
||||
VkQueue* pQueue)
|
||||
{
|
||||
assert(device);
|
||||
assert(pQueue);
|
||||
|
||||
assert(queueFamilyIndex < numQueueFamilies);
|
||||
assert(queueIndex < _queueFamilyProperties[queueFamilyIndex].queueCount);
|
||||
|
||||
*pQueue = &_queuesByFamily[queueFamilyIndex][queueIndex];
|
||||
}
|
||||
|
||||
/*
|
||||
* https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#vkCreateSemaphore
|
||||
* Semaphores are a synchronization primitive that can be used to insert a dependency between batches submitted to queues.
|
||||
* Semaphores have two states - signaled and unsignaled. The state of a semaphore can be signaled after execution of a batch of commands is completed.
|
||||
* A batch can wait for a semaphore to become signaled before it begins execution, and the semaphore is also unsignaled before the batch begins execution.
|
||||
* As with most objects in Vulkan, semaphores are an interface to internal data which is typically opaque to applications.
|
||||
* This internal data is referred to as a semaphore’s payload. However, in order to enable communication with agents outside of the current device,
|
||||
* it is necessary to be able to export that payload to a commonly understood format, and subsequently import from that format as well.
|
||||
* The internal data of a semaphore may include a reference to any resources and pending work associated with signal or unsignal operations performed on that semaphore object.
|
||||
* Mechanisms to import and export that internal data to and from semaphores are provided below.
|
||||
* These mechanisms indirectly enable applications to share semaphore state between two or more semaphores and other synchronization primitives across process and API boundaries.
|
||||
* When created, the semaphore is in the unsignaled state.
|
||||
*/
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkCreateSemaphore(
|
||||
VkDevice device,
|
||||
const VkSemaphoreCreateInfo* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkSemaphore* pSemaphore)
|
||||
{
|
||||
assert(device);
|
||||
assert(pSemaphore);
|
||||
|
||||
//TODO: allocator is ignored for now
|
||||
assert(pAllocator == 0);
|
||||
|
||||
//we'll probably just use an IOCTL to wait for a GPU sequence number to complete.
|
||||
*pSemaphore = -1;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#vkGetPhysicalDeviceSurfaceCapabilitiesKHR
|
||||
*/
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
VkSurfaceKHR surface,
|
||||
VkSurfaceCapabilitiesKHR* pSurfaceCapabilities)
|
||||
{
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkDeviceWaitIdle(
|
||||
@ -187,14 +404,6 @@ VKAPI_ATTR void VKAPI_CALL vkDestroyDevice(
|
||||
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR(
|
||||
VkInstance instance,
|
||||
VkSurfaceKHR surface,
|
||||
const VkAllocationCallbacks* pAllocator)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(
|
||||
VkInstance instance,
|
||||
const VkAllocationCallbacks* pAllocator)
|
||||
@ -320,63 +529,3 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormatsKHR(
|
||||
{
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
VkSurfaceKHR surface,
|
||||
VkSurfaceCapabilitiesKHR* pSurfaceCapabilities)
|
||||
{
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkCreateSemaphore(
|
||||
VkDevice device,
|
||||
const VkSemaphoreCreateInfo* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkSemaphore* pSemaphore)
|
||||
{
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue2(
|
||||
VkDevice device,
|
||||
const VkDeviceQueueInfo2* pQueueInfo,
|
||||
VkQueue* pQueue)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
const VkDeviceCreateInfo* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkDevice* pDevice)
|
||||
{
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupportKHR(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
uint32_t queueFamilyIndex,
|
||||
VkSurfaceKHR surface,
|
||||
VkBool32* pSupported)
|
||||
{
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue(
|
||||
VkDevice device,
|
||||
uint32_t queueFamilyIndex,
|
||||
uint32_t queueIndex,
|
||||
VkQueue* pQueue)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -69,11 +69,10 @@ struct modeset_dev {
|
||||
drmModeCrtc *saved_crtc;
|
||||
};
|
||||
|
||||
static struct modeset_dev *modeset_list = NULL;
|
||||
//static struct modeset_dev *modeset_list = NULL;
|
||||
|
||||
static int fd = -1;
|
||||
|
||||
static int modeset_prepare();
|
||||
static int modeset_find_crtc(drmModeRes *res, drmModeConnector *conn,
|
||||
struct modeset_dev *dev);
|
||||
static int modeset_create_fb(struct modeset_buf *buf);
|
||||
@ -124,15 +123,12 @@ int modeset_open(const char *node)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return modeset_prepare();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* modeset_prepare() stays the same.
|
||||
*/
|
||||
|
||||
static int modeset_prepare()
|
||||
modeset_dev* modeset_create()
|
||||
{
|
||||
modeset_dev* ret_dev = 0;
|
||||
drmModeRes *res;
|
||||
drmModeConnector *conn;
|
||||
struct modeset_dev *dev;
|
||||
@ -142,7 +138,7 @@ static int modeset_prepare()
|
||||
res = drmModeGetResources(fd);
|
||||
if (!res) {
|
||||
printf("cannot retrieve DRM resources (%d): %m\n", errno);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// iterate all connectors
|
||||
@ -173,8 +169,8 @@ static int modeset_prepare()
|
||||
|
||||
// free connector data and link device into global list
|
||||
drmModeFreeConnector(conn);
|
||||
dev->next = modeset_list;
|
||||
modeset_list = dev;
|
||||
dev->next = ret_dev;
|
||||
ret_dev = dev;
|
||||
}
|
||||
|
||||
// free resources again
|
||||
@ -182,7 +178,7 @@ static int modeset_prepare()
|
||||
|
||||
struct modeset_dev *iter;
|
||||
struct modeset_buf *buf;
|
||||
for (iter = modeset_list; iter; iter = iter->next) {
|
||||
for (iter = ret_dev; iter; iter = iter->next) {
|
||||
iter->saved_crtc = drmModeGetCrtc(fd, iter->crtc);
|
||||
buf = &iter->bufs[iter->front_buf];
|
||||
ret = drmModeSetCrtc(fd, iter->crtc, buf->fb, 0, 0,
|
||||
@ -191,7 +187,8 @@ static int modeset_prepare()
|
||||
printf("cannot set CRTC for connector %u (%d): %m\n",
|
||||
iter->conn, errno);
|
||||
}
|
||||
return 0;
|
||||
|
||||
return ret_dev;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -263,7 +260,7 @@ static int modeset_setup_dev(drmModeRes *res, drmModeConnector *conn,
|
||||
*/
|
||||
|
||||
static int modeset_find_crtc(drmModeRes *res, drmModeConnector *conn,
|
||||
struct modeset_dev *dev)
|
||||
modeset_dev *dev)
|
||||
{
|
||||
drmModeEncoder *enc;
|
||||
unsigned int i, j;
|
||||
@ -279,7 +276,7 @@ static int modeset_find_crtc(drmModeRes *res, drmModeConnector *conn,
|
||||
if (enc) {
|
||||
if (enc->crtc_id) {
|
||||
crtc = enc->crtc_id;
|
||||
for (iter = modeset_list; iter; iter = iter->next) {
|
||||
for (iter = dev; iter; iter = iter->next) {
|
||||
if (iter->crtc == crtc) {
|
||||
crtc = -1;
|
||||
break;
|
||||
@ -316,7 +313,7 @@ static int modeset_find_crtc(drmModeRes *res, drmModeConnector *conn,
|
||||
|
||||
// check that no other device already uses this CRTC
|
||||
crtc = res->crtcs[j];
|
||||
for (iter = modeset_list; iter; iter = iter->next) {
|
||||
for (iter = dev; iter; iter = iter->next) {
|
||||
if (iter->crtc == crtc) {
|
||||
crtc = -1;
|
||||
break;
|
||||
@ -476,13 +473,13 @@ static void modeset_destroy_fb(struct modeset_buf *buf)
|
||||
* vertical-sync.
|
||||
*/
|
||||
|
||||
void modeset_swapbuffer()
|
||||
void modeset_swapbuffer(modeset_dev* dev)
|
||||
{
|
||||
struct modeset_dev *iter;
|
||||
struct modeset_buf *buf;
|
||||
int ret;
|
||||
|
||||
for (iter = modeset_list; iter; iter = iter->next) {
|
||||
for (iter = dev; iter; iter = iter->next) {
|
||||
buf = &iter->bufs[iter->front_buf ^ 1];
|
||||
|
||||
ret = drmModeSetCrtc(fd, iter->crtc, buf->fb, 0, 0,
|
||||
@ -500,14 +497,14 @@ void modeset_swapbuffer()
|
||||
* modeset_destroy_fb() instead of accessing the framebuffers directly.
|
||||
*/
|
||||
|
||||
void modeset_cleanup()
|
||||
void modeset_destroy(modeset_dev* dev)
|
||||
{
|
||||
struct modeset_dev *iter;
|
||||
|
||||
while (modeset_list) {
|
||||
while (dev) {
|
||||
// remove from global list
|
||||
iter = modeset_list;
|
||||
modeset_list = iter->next;
|
||||
iter = dev;
|
||||
dev = iter->next;
|
||||
|
||||
// restore saved CRTC configuration
|
||||
drmModeSetCrtc(fd,
|
||||
@ -527,7 +524,10 @@ void modeset_cleanup()
|
||||
// free allocated memory
|
||||
free(iter);
|
||||
}
|
||||
}
|
||||
|
||||
void modeset_close()
|
||||
{
|
||||
close(fd);
|
||||
}
|
||||
|
||||
|
@ -17,9 +17,13 @@ extern "C" {
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
|
||||
int modeset_open(const char *node);
|
||||
void modeset_swapbuffer();
|
||||
void modeset_cleanup();
|
||||
typedef struct modeset_dev modeset_dev;
|
||||
|
||||
int modeset_open(const char* node);
|
||||
modeset_dev* modeset_create();
|
||||
void modeset_swapbuffer(modeset_dev* dev);
|
||||
void modeset_destroy(modeset_dev* dev);
|
||||
void modeset_close();
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
|
32
driver/vkExt.h
Normal file
32
driver/vkExt.h
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//we need something like the other platforms to create surfaces on the RPI
|
||||
//so I created this little "extension"
|
||||
//full spec in this file ;)
|
||||
|
||||
typedef enum VkRpiSurfaceCreateFlagsKHR {
|
||||
//reserved
|
||||
VK_RPI_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
|
||||
} VkRpiSurfaceCreateFlagsKHR;
|
||||
|
||||
typedef struct VkRpiSurfaceCreateInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkRpiSurfaceCreateFlagsKHR flags;
|
||||
//maybe include some other stuff dunno
|
||||
} VkRpiSurfaceCreateInfoKHR;
|
||||
|
||||
VkResult vkCreateRpiSurfaceKHR(
|
||||
VkInstance instance,
|
||||
const VkRpiSurfaceCreateInfoKHR* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkSurfaceKHR* pSurface);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#include "driver/modeset.h"
|
||||
#include "driver/vkExt.h"
|
||||
|
||||
//#define GLFW_INCLUDE_VULKAN
|
||||
//#define VK_USE_PLATFORM_WIN32_KHR
|
||||
@ -165,12 +165,12 @@ void createInstance() {
|
||||
}
|
||||
|
||||
void createWindowSurface() {
|
||||
//if (glfwCreateWindowSurface(instance, window, NULL, &windowSurface) != VK_SUCCESS) {
|
||||
// std::cerr << "failed to create window surface!" << std::endl;
|
||||
// assert(0);
|
||||
//}
|
||||
if (vkCreateRpiSurfaceKHR(instance, 0, 0, &windowSurface) != VK_SUCCESS) {
|
||||
std::cerr << "failed to create window surface!" << std::endl;
|
||||
assert(0);
|
||||
}
|
||||
|
||||
//std::cout << "created window surface" << std::endl;
|
||||
std::cout << "created window surface" << std::endl;
|
||||
}
|
||||
|
||||
void findPhysicalDevice() {
|
||||
@ -670,17 +670,16 @@ int main() {
|
||||
|
||||
//window = glfwCreateWindow(640, 480, "The 630 line cornflower blue window", nullptr, nullptr);
|
||||
|
||||
int ret = 0;
|
||||
ret = modeset_open("/dev/dri/card0"); assert(!ret);
|
||||
modeset_swapbuffer();
|
||||
//TODO create surface
|
||||
//swapbuffer
|
||||
|
||||
// Use Vulkan
|
||||
setupVulkan();
|
||||
|
||||
mainLoop();
|
||||
|
||||
//TODO destroy surface
|
||||
cleanup();
|
||||
modeset_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user