mirror of
https://github.com/Yours3lf/rpi-vk-driver.git
synced 2024-12-02 14:24:14 +01:00
383 lines
12 KiB
C
383 lines
12 KiB
C
|
#include <stdio.h>
|
||
|
#include <assert.h>
|
||
|
#include <string.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <fcntl.h>
|
||
|
#include <unistd.h>
|
||
|
#include <assert.h>
|
||
|
#include <stdint.h>
|
||
|
#include <sys/mman.h>
|
||
|
#include <sys/ioctl.h>
|
||
|
#include <sys/types.h>
|
||
|
#include <sys/stat.h>
|
||
|
#include <fcntl.h>
|
||
|
|
||
|
#include <drm/vc4_drm.h>
|
||
|
|
||
|
#include <vulkan/vulkan.h>
|
||
|
|
||
|
#ifndef min
|
||
|
#define min(a, b) (a < b ? a : b)
|
||
|
#endif
|
||
|
|
||
|
#ifndef max
|
||
|
#define max(a, b) (a > b ? a : b)
|
||
|
#endif
|
||
|
|
||
|
#define DRM_IOCTL_FILE_NAME "/dev/"DRM_NAME
|
||
|
|
||
|
static int fd = -1;
|
||
|
|
||
|
int openIoctl()
|
||
|
{
|
||
|
fd = open(DRM_IOCTL_FILE_NAME, O_RDWR);
|
||
|
if (fd < 0) {
|
||
|
printf("Can't open device file: %s\n", DRM_IOCTL_FILE_NAME);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void closeIoctl(int fd)
|
||
|
{
|
||
|
close(fd);
|
||
|
}
|
||
|
|
||
|
typedef struct VkInstance_T
|
||
|
{
|
||
|
//supposedly this should contain all the enabled layers?
|
||
|
int dummy;
|
||
|
} _instance;
|
||
|
|
||
|
typedef struct VkPhysicalDevice_T
|
||
|
{
|
||
|
//hardware id?
|
||
|
int dummy;
|
||
|
} _physicalDevice;
|
||
|
|
||
|
/*
|
||
|
* https://www.khronos.org/registry/vulkan/specs/1.0/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,
|
||
|
* vkCreateInstance must return VK_ERROR_EXTENSION_NOT_PRESENT. After verifying and enabling the instance layers and extensions the VkInstance object is
|
||
|
* created and returned to the application.
|
||
|
*/
|
||
|
VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(
|
||
|
const VkInstanceCreateInfo* pCreateInfo,
|
||
|
const VkAllocationCallbacks* pAllocator,
|
||
|
VkInstance* pInstance)
|
||
|
{
|
||
|
*pInstance = malloc(sizeof(_instance));
|
||
|
|
||
|
//TODO: allocator is ignored for now
|
||
|
assert(pAllocator == 0);
|
||
|
|
||
|
//TODO: possibly we need to load layers here
|
||
|
//and store them in pInstance
|
||
|
|
||
|
//TODO: need to check here that the requested
|
||
|
//extensions are supported
|
||
|
|
||
|
return VK_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* https://www.khronos.org/registry/vulkan/specs/1.0/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.
|
||
|
* If pPhysicalDeviceCount is smaller than the number of physical devices available, VK_INCOMPLETE will be returned instead of VK_SUCCESS, to indicate that not all the
|
||
|
* available physical devices were returned.
|
||
|
*/
|
||
|
VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(
|
||
|
VkInstance instance,
|
||
|
uint32_t* pPhysicalDeviceCount,
|
||
|
VkPhysicalDevice* pPhysicalDevices)
|
||
|
{
|
||
|
//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;
|
||
|
|
||
|
int numGPUs = gpuExists;
|
||
|
|
||
|
assert(pPhysicalDeviceCount);
|
||
|
|
||
|
if(!pPhysicalDevices)
|
||
|
{
|
||
|
*pPhysicalDeviceCount = numGPUs;
|
||
|
return VK_SUCCESS;
|
||
|
}
|
||
|
|
||
|
int arraySize = *pPhysicalDeviceCount;
|
||
|
int elementsWritten = min(numGPUs, arraySize);
|
||
|
|
||
|
for(int c = 0; c < elementsWritten; ++c)
|
||
|
{
|
||
|
pPhysicalDevices[c] = malloc(sizeof(_physicalDevice));
|
||
|
}
|
||
|
|
||
|
*pPhysicalDeviceCount = elementsWritten;
|
||
|
|
||
|
if(elementsWritten < arraySize)
|
||
|
{
|
||
|
return VK_INCOMPLETE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return VK_SUCCESS;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#vkGetPhysicalDeviceQueueFamilyProperties
|
||
|
*
|
||
|
*/
|
||
|
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties(
|
||
|
VkPhysicalDevice physicalDevice,
|
||
|
uint32_t* pQueueFamilyPropertyCount,
|
||
|
VkQueueFamilyProperties* pQueueFamilyProperties)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
VKAPI_ATTR VkResult VKAPI_CALL vkDeviceWaitIdle(
|
||
|
VkDevice device)
|
||
|
{
|
||
|
return VK_SUCCESS;
|
||
|
}
|
||
|
|
||
|
VKAPI_ATTR void VKAPI_CALL vkFreeCommandBuffers(
|
||
|
VkDevice device,
|
||
|
VkCommandPool commandPool,
|
||
|
uint32_t commandBufferCount,
|
||
|
const VkCommandBuffer* pCommandBuffers)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
VKAPI_ATTR void VKAPI_CALL vkDestroyCommandPool(
|
||
|
VkDevice device,
|
||
|
VkCommandPool commandPool,
|
||
|
const VkAllocationCallbacks* pAllocator)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
VKAPI_ATTR void VKAPI_CALL vkDestroySemaphore(
|
||
|
VkDevice device,
|
||
|
VkSemaphore semaphore,
|
||
|
const VkAllocationCallbacks* pAllocator)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
VKAPI_ATTR void VKAPI_CALL vkDestroySwapchainKHR(
|
||
|
VkDevice device,
|
||
|
VkSwapchainKHR swapchain,
|
||
|
const VkAllocationCallbacks* pAllocator)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
VKAPI_ATTR void VKAPI_CALL vkDestroyDevice(
|
||
|
VkDevice device,
|
||
|
const VkAllocationCallbacks* pAllocator)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR(
|
||
|
VkInstance instance,
|
||
|
VkSurfaceKHR surface,
|
||
|
const VkAllocationCallbacks* pAllocator)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(
|
||
|
VkInstance instance,
|
||
|
const VkAllocationCallbacks* pAllocator)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR(
|
||
|
VkQueue queue,
|
||
|
const VkPresentInfoKHR* pPresentInfo)
|
||
|
{
|
||
|
return VK_SUCCESS;
|
||
|
}
|
||
|
|
||
|
VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit(
|
||
|
VkQueue queue,
|
||
|
uint32_t submitCount,
|
||
|
const VkSubmitInfo* pSubmits,
|
||
|
VkFence fence)
|
||
|
{
|
||
|
return VK_SUCCESS;
|
||
|
}
|
||
|
|
||
|
VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImageKHR(
|
||
|
VkDevice device,
|
||
|
VkSwapchainKHR swapchain,
|
||
|
uint64_t timeout,
|
||
|
VkSemaphore semaphore,
|
||
|
VkFence fence,
|
||
|
uint32_t* pImageIndex)
|
||
|
{
|
||
|
return VK_SUCCESS;
|
||
|
}
|
||
|
|
||
|
VKAPI_ATTR VkResult VKAPI_CALL vkEndCommandBuffer(
|
||
|
VkCommandBuffer commandBuffer)
|
||
|
{
|
||
|
return VK_SUCCESS;
|
||
|
}
|
||
|
|
||
|
VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier(
|
||
|
VkCommandBuffer commandBuffer,
|
||
|
VkPipelineStageFlags srcStageMask,
|
||
|
VkPipelineStageFlags dstStageMask,
|
||
|
VkDependencyFlags dependencyFlags,
|
||
|
uint32_t memoryBarrierCount,
|
||
|
const VkMemoryBarrier* pMemoryBarriers,
|
||
|
uint32_t bufferMemoryBarrierCount,
|
||
|
const VkBufferMemoryBarrier* pBufferMemoryBarriers,
|
||
|
uint32_t imageMemoryBarrierCount,
|
||
|
const VkImageMemoryBarrier* pImageMemoryBarriers)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
VKAPI_ATTR void VKAPI_CALL vkCmdClearColorImage(
|
||
|
VkCommandBuffer commandBuffer,
|
||
|
VkImage image,
|
||
|
VkImageLayout imageLayout,
|
||
|
const VkClearColorValue* pColor,
|
||
|
uint32_t rangeCount,
|
||
|
const VkImageSubresourceRange* pRanges)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
VKAPI_ATTR VkResult VKAPI_CALL vkBeginCommandBuffer(
|
||
|
VkCommandBuffer commandBuffer,
|
||
|
const VkCommandBufferBeginInfo* pBeginInfo)
|
||
|
{
|
||
|
return VK_SUCCESS;
|
||
|
}
|
||
|
|
||
|
VKAPI_ATTR VkResult VKAPI_CALL vkAllocateCommandBuffers(
|
||
|
VkDevice device,
|
||
|
const VkCommandBufferAllocateInfo* pAllocateInfo,
|
||
|
VkCommandBuffer* pCommandBuffers)
|
||
|
{
|
||
|
return VK_SUCCESS;
|
||
|
}
|
||
|
|
||
|
VKAPI_ATTR VkResult VKAPI_CALL vkCreateCommandPool(
|
||
|
VkDevice device,
|
||
|
const VkCommandPoolCreateInfo* pCreateInfo,
|
||
|
const VkAllocationCallbacks* pAllocator,
|
||
|
VkCommandPool* pCommandPool)
|
||
|
{
|
||
|
return VK_SUCCESS;
|
||
|
}
|
||
|
|
||
|
VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainImagesKHR(
|
||
|
VkDevice device,
|
||
|
VkSwapchainKHR swapchain,
|
||
|
uint32_t* pSwapchainImageCount,
|
||
|
VkImage* pSwapchainImages)
|
||
|
{
|
||
|
return VK_SUCCESS;
|
||
|
}
|
||
|
|
||
|
VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR(
|
||
|
VkDevice device,
|
||
|
const VkSwapchainCreateInfoKHR* pCreateInfo,
|
||
|
const VkAllocationCallbacks* pAllocator,
|
||
|
VkSwapchainKHR* pSwapchain)
|
||
|
{
|
||
|
return VK_SUCCESS;
|
||
|
}
|
||
|
|
||
|
VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModesKHR(
|
||
|
VkPhysicalDevice physicalDevice,
|
||
|
VkSurfaceKHR surface,
|
||
|
uint32_t* pPresentModeCount,
|
||
|
VkPresentModeKHR* pPresentModes)
|
||
|
{
|
||
|
return VK_SUCCESS;
|
||
|
}
|
||
|
|
||
|
VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormatsKHR(
|
||
|
VkPhysicalDevice physicalDevice,
|
||
|
VkSurfaceKHR surface,
|
||
|
uint32_t* pSurfaceFormatCount,
|
||
|
VkSurfaceFormatKHR* pSurfaceFormats)
|
||
|
{
|
||
|
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)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|