diff --git a/driver/command.c b/driver/command.c index ae720c6..fa99580 100644 --- a/driver/command.c +++ b/driver/command.c @@ -325,7 +325,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit( //submit ioctl static uint64_t lastFinishedSeqno = 0; - vc4_cl_submit(controlFd, &cmdbuf->submitCl, &queue->lastEmitSeqno, &lastFinishedSeqno); + vc4_cl_submit(queue->dev->dev->instance->controlFd, &cmdbuf->submitCl, &queue->lastEmitSeqno, &lastFinishedSeqno); } for(int c = 0; c < pSubmits->commandBufferCount; ++c) diff --git a/driver/common.c b/driver/common.c index d3dbff6..c3fe4ab 100644 --- a/driver/common.c +++ b/driver/common.c @@ -909,9 +909,29 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineCache( VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr( VkDevice device, const char* pName) -{ +{ + if( + !strcmp("vkDestroyInstance", pName) || + !strcmp("vkEnumeratePhysicalDevices", pName) || + !strcmp("vkGetPhysicalDeviceFeatures", pName) || + !strcmp("vkGetPhysicalDeviceFormatProperties", pName) || + !strcmp("vkGetPhysicalDeviceImageFormatProperties", pName) || + !strcmp("vkGetPhysicalDeviceProperties", pName) || + !strcmp("vkGetPhysicalDeviceQueueFamilyProperties", pName) || + !strcmp("vkGetPhysicalDeviceMemoryProperties", pName) || + !strcmp("vkCreateDevice", pName) || + !strcmp("vkEnumerateDeviceExtensionProperties", pName) || + !strcmp("vkEnumerateDeviceLayerProperties", pName) || + !strcmp("vkGetPhysicalDeviceSparseImageFormatProperties", pName) + ) + { + return 0; + } + + //TODO - return vkGetInstanceProcAddr(0, pName); + _device* d = device; + return vkGetInstanceProcAddr(d->dev->instance, pName); } VKAPI_ATTR VkResult VKAPI_CALL vkCreateQueryPool( diff --git a/driver/common.h b/driver/common.h index caf9e17..3f716f8 100644 --- a/driver/common.h +++ b/driver/common.h @@ -34,15 +34,12 @@ #include "vkCaps.h" -typedef struct VkPhysicalDevice_T -{ - //hardware id? - int dummy; -} _physicalDevice; +typedef struct VkDevice_T _device; typedef struct VkQueue_T { uint64_t lastEmitSeqno; + _device* dev; } _queue; typedef struct VkCommandPool_T @@ -62,18 +59,29 @@ typedef enum commandBufferState CMDBUF_STATE_LAST } commandBufferState; +typedef struct VkInstance_T _instance; + +typedef struct VkPhysicalDevice_T +{ + //hardware id? + char* path; + _instance* instance; +} _physicalDevice; + typedef struct VkInstance_T { + _physicalDevice dev; //supposedly this should contain all the enabled layers? int enabledExtensions[numInstanceExtensions]; int numEnabledExtensions; - _physicalDevice dev; int chipVersion; int hasTiling; int hasControlFlow; int hasEtc1; int hasThreadedFs; int hasMadvise; + int controlFd; + //int renderFd; } _instance; typedef struct VkDevice_T diff --git a/driver/device.c b/driver/device.c index f71a66b..992b141 100644 --- a/driver/device.c +++ b/driver/device.c @@ -15,10 +15,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices( { 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; - - int numGPUs = gpuExists; + int numGPUs = 1; assert(pPhysicalDeviceCount); @@ -202,6 +199,31 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice( //TODO: allocator is ignored for now assert(pAllocator == 0); + //check for enabled extensions + for(int c = 0; c < pCreateInfo->enabledExtensionCount; ++c) + { + int findres = findDeviceExtension(pCreateInfo->ppEnabledExtensionNames[c]); + if(findres == -1) + { + return VK_ERROR_EXTENSION_NOT_PRESENT; + } + } + + //check for enabled features + VkBool32* requestedFeatures = pCreateInfo->pEnabledFeatures; + VkBool32* supportedFeatures = &_features; + + if(requestedFeatures) + { + for(int c = 0; c < numFeatures; ++c) + { + if(requestedFeatures[c] && !supportedFeatures[c]) + { + return VK_ERROR_FEATURE_NOT_PRESENT; + } + } + } + *pDevice = malloc(sizeof(_device)); if(!pDevice) { @@ -220,15 +242,8 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice( (*pDevice)->enabledExtensions[(*pDevice)->numEnabledExtensions] = findres; (*pDevice)->numEnabledExtensions++; } - else - { - return VK_ERROR_EXTENSION_NOT_PRESENT; - } } - VkBool32* requestedFeatures = pCreateInfo->pEnabledFeatures; - VkBool32* supportedFeatures = &_features; - if(requestedFeatures) { for(int c = 0; c < numFeatures; ++c) @@ -295,6 +310,7 @@ VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue( assert(queueIndex < device->numQueues[queueFamilyIndex]); *pQueue = &device->queues[queueFamilyIndex][queueIndex]; + (*pQueue)->dev = device; } /* diff --git a/driver/instance.c b/driver/instance.c index d96929d..d08e526 100644 --- a/driver/instance.c +++ b/driver/instance.c @@ -93,15 +93,22 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance( //TODO ignored for now //pCreateInfo->pApplicationInfo - int ret = openIoctl(); assert(!ret); + //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; assert(gpuExists); - (*pInstance)->chipVersion = vc4_get_chip_info(controlFd); - (*pInstance)->hasTiling = vc4_test_tiling(controlFd); + (*pInstance)->dev.path = "/dev/dri/card0"; + (*pInstance)->dev.instance = *pInstance; - (*pInstance)->hasControlFlow = vc4_has_feature(controlFd, DRM_VC4_PARAM_SUPPORTS_BRANCHES); - (*pInstance)->hasEtc1 = vc4_has_feature(controlFd, DRM_VC4_PARAM_SUPPORTS_ETC1); - (*pInstance)->hasThreadedFs = vc4_has_feature(controlFd, DRM_VC4_PARAM_SUPPORTS_THREADED_FS); - (*pInstance)->hasMadvise = vc4_has_feature(controlFd, DRM_VC4_PARAM_SUPPORTS_MADVISE); + int ret = openIoctl(); assert(ret != -1); + (*pInstance)->controlFd = ret; + + (*pInstance)->chipVersion = vc4_get_chip_info((*pInstance)->controlFd); + (*pInstance)->hasTiling = vc4_test_tiling((*pInstance)->controlFd); + + (*pInstance)->hasControlFlow = vc4_has_feature((*pInstance)->controlFd, DRM_VC4_PARAM_SUPPORTS_BRANCHES); + (*pInstance)->hasEtc1 = vc4_has_feature((*pInstance)->controlFd, DRM_VC4_PARAM_SUPPORTS_ETC1); + (*pInstance)->hasThreadedFs = vc4_has_feature((*pInstance)->controlFd, DRM_VC4_PARAM_SUPPORTS_THREADED_FS); + (*pInstance)->hasMadvise = vc4_has_feature((*pInstance)->controlFd, DRM_VC4_PARAM_SUPPORTS_MADVISE); return VK_SUCCESS; } diff --git a/driver/kernelInterface.c b/driver/kernelInterface.c index 0cca220..b926be4 100644 --- a/driver/kernelInterface.c +++ b/driver/kernelInterface.c @@ -1,30 +1,26 @@ #define _GNU_SOURCE #include "kernelInterface.h" -int controlFd = -1; -int renderFd = -1; - int openIoctl() { - controlFd = open(DRM_IOCTL_CTRL_DEV_FILE_NAME, O_RDWR | O_CLOEXEC); + int controlFd = open(DRM_IOCTL_CTRL_DEV_FILE_NAME, O_RDWR | O_CLOEXEC); if (controlFd < 0) { printf("Can't open device file: %s\n", DRM_IOCTL_CTRL_DEV_FILE_NAME); return -1; } - renderFd = open(DRM_IOCTL_RENDER_DEV_FILE_NAME, O_RDWR | O_CLOEXEC); + /*renderFd = open(DRM_IOCTL_RENDER_DEV_FILE_NAME, O_RDWR | O_CLOEXEC); if (renderFd < 0) { printf("Can't open device file: %s\n", DRM_IOCTL_RENDER_DEV_FILE_NAME); return -1; - } + }*/ - return 0; + return controlFd; } -void closeIoctl() +void closeIoctl(int fd) { - close(controlFd); - close(renderFd); + close(fd); } static uint32_t align(uint32_t num, uint32_t alignment) @@ -239,9 +235,11 @@ int vc4_seqno_wait(int fd, uint64_t* lastFinishedSeqno, uint64_t seqno, uint64_t { assert(fd); assert(lastFinishedSeqno); - assert(seqno); assert(timeout_ns); + if(!seqno) + return 1; + if (*lastFinishedSeqno >= seqno) return 1; diff --git a/driver/kernelInterface.h b/driver/kernelInterface.h index 160d3e8..1da80c4 100644 --- a/driver/kernelInterface.h +++ b/driver/kernelInterface.h @@ -34,9 +34,6 @@ extern "C" { #define WAIT_TIMEOUT_INFINITE 0xffffffffffffffffull #define ARM_PAGE_SIZE 4096 -extern int controlFd; -extern int renderFd; - int openIoctl(); void closeIoctl(); diff --git a/driver/memory.c b/driver/memory.c index a468d11..8ab720b 100644 --- a/driver/memory.c +++ b/driver/memory.c @@ -67,7 +67,7 @@ VkResult vkAllocateMemory(VkDevice device, const VkMemoryAllocateInfo* pAllocate assert(pAllocator == 0); //TODO - uint32_t bo = vc4_bo_alloc(controlFd, pAllocateInfo->allocationSize, "vkAllocateMemory"); + uint32_t bo = vc4_bo_alloc(device->dev->instance->controlFd, pAllocateInfo->allocationSize, "vkAllocateMemory"); if(!bo) { return VK_ERROR_OUT_OF_DEVICE_MEMORY; @@ -113,7 +113,7 @@ VkResult vkMapMemory(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset //TODO check ppdata alignment //TODO multiple instances? - void* ptr = vc4_bo_map(controlFd, ((_deviceMemory*)memory)->bo, offset, size); + void* ptr = vc4_bo_map(device->dev->instance->controlFd, ((_deviceMemory*)memory)->bo, offset, size); if(!ptr) { return VK_ERROR_MEMORY_MAP_FAILED; @@ -135,7 +135,7 @@ void vkUnmapMemory(VkDevice device, VkDeviceMemory memory) assert(device); assert(memory); - vc4_bo_unmap_unsynchronized(controlFd, ((_deviceMemory*)memory)->mappedPtr, ((_deviceMemory*)memory)->mappedSize); + vc4_bo_unmap_unsynchronized(device->dev->instance->controlFd, ((_deviceMemory*)memory)->mappedPtr, ((_deviceMemory*)memory)->mappedSize); } void vkFreeMemory(VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks* pAllocator) @@ -146,7 +146,7 @@ void vkFreeMemory(VkDevice device, VkDeviceMemory memory, const VkAllocationCall assert(pAllocator == 0); //TODO _deviceMemory* mem = memory; - vc4_bo_free(controlFd, mem->bo, mem->mappedPtr, mem->size); + vc4_bo_free(device->dev->instance->controlFd, mem->bo, mem->mappedPtr, mem->size); free(mem); } diff --git a/driver/shader.c b/driver/shader.c index f7e3e1e..69f2f23 100644 --- a/driver/shader.c +++ b/driver/shader.c @@ -24,7 +24,7 @@ VkResult vkCreateShaderModuleFromRpiAssemblyKHR(VkDevice device, VkRpiShaderModu if(pCreateInfo->byteStreamArray[c]) { uint32_t size = pCreateInfo->numBytesArray[c]; - shader->bos[c] = vc4_bo_alloc_shader(controlFd, pCreateInfo->byteStreamArray[c], &size); + shader->bos[c] = vc4_bo_alloc_shader(device->dev->instance->controlFd, pCreateInfo->byteStreamArray[c], &size); shader->sizes[c] = size; } else @@ -60,7 +60,7 @@ void vkDestroyShaderModule(VkDevice device, VkShaderModule shaderModule, const V { if(shader->bos[c]) { - vc4_bo_free(controlFd, shader->bos[c], 0, shader->sizes[c]); + vc4_bo_free(device->dev->instance->controlFd, shader->bos[c], 0, shader->sizes[c]); } } diff --git a/driver/sync.c b/driver/sync.c index ba1620d..2d257f8 100644 --- a/driver/sync.c +++ b/driver/sync.c @@ -247,7 +247,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkDeviceWaitIdle( { uint64_t lastFinishedSeqno; uint64_t timeout = WAIT_TIMEOUT_INFINITE; - vc4_seqno_wait(controlFd, &lastFinishedSeqno, device->queues[c][d].lastEmitSeqno, &timeout); + vc4_seqno_wait(device->dev->instance->controlFd, &lastFinishedSeqno, device->queues[c][d].lastEmitSeqno, &timeout); } } @@ -265,7 +265,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkQueueWaitIdle( _queue* q = queue; uint64_t lastFinishedSeqno; uint64_t timeout = WAIT_TIMEOUT_INFINITE; - vc4_seqno_wait(controlFd, &lastFinishedSeqno, q->lastEmitSeqno, &timeout); + vc4_seqno_wait(queue->dev->dev->instance->controlFd, &lastFinishedSeqno, q->lastEmitSeqno, &timeout); return VK_SUCCESS; } @@ -399,7 +399,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkWaitForFences( uint64_t lastFinishedSeqno = 0; if(!f->signaled) { - int ret = vc4_seqno_wait(controlFd, &lastFinishedSeqno, f->seqno, &timeout); + int ret = vc4_seqno_wait(device->dev->instance->controlFd, &lastFinishedSeqno, f->seqno, &timeout); if(ret < 0) { @@ -434,7 +434,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkWaitForFences( uint64_t lastFinishedSeqno = 0; if(!f->signaled) { - int ret = vc4_seqno_wait(controlFd, &lastFinishedSeqno, f->seqno, &timeout); + int ret = vc4_seqno_wait(device->dev->instance->controlFd, &lastFinishedSeqno, f->seqno, &timeout); if(ret < 0) { diff --git a/driver/wsi.c b/driver/wsi.c index f315c72..34ecbb2 100644 --- a/driver/wsi.c +++ b/driver/wsi.c @@ -18,7 +18,7 @@ VkResult vkCreateRpiSurfaceKHR( //TODO: allocator is ignored for now assert(pAllocator == 0); - *pSurface = (VkSurfaceKHR)modeset_create(controlFd); + *pSurface = (VkSurfaceKHR)modeset_create(instance->controlFd); return VK_SUCCESS; } @@ -40,7 +40,7 @@ VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR( //TODO: allocator is ignored for now assert(pAllocator == 0); - modeset_destroy(controlFd, (modeset_dev*)surface); + modeset_destroy(instance->controlFd, (modeset_dev*)surface); } /* @@ -254,14 +254,14 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR( //set tiling to T if size > 4KB if(s->images[c].tiling == VC4_TILING_FORMAT_T) { - int ret = vc4_bo_set_tiling(controlFd, s->images[c].boundMem->bo, DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED); assert(ret); + int ret = vc4_bo_set_tiling(device->dev->instance->controlFd, s->images[c].boundMem->bo, DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED); assert(ret); } else { - int ret = vc4_bo_set_tiling(controlFd, s->images[c].boundMem->bo, DRM_FORMAT_MOD_LINEAR); assert(ret); + int ret = vc4_bo_set_tiling(device->dev->instance->controlFd, s->images[c].boundMem->bo, DRM_FORMAT_MOD_LINEAR); assert(ret); } - int res = modeset_create_fb(controlFd, &s->images[c]); assert(res == 0); + int res = modeset_create_fb(device->dev->instance->controlFd, &s->images[c]); assert(res == 0); } //defer to first swapbuffer (or at least later, getting swapchain != presenting immediately) @@ -377,7 +377,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR( for(int c = 0; c < pPresentInfo->swapchainCount; ++c) { _swapchain* s = pPresentInfo->pSwapchains[c]; - modeset_present_buffer(controlFd, (modeset_dev*)s->surface, &s->images[s->backbufferIdx]); + modeset_present_buffer(queue->dev->dev->instance->controlFd, (modeset_dev*)s->surface, &s->images[s->backbufferIdx]); s->backbufferIdx = (s->backbufferIdx + 1) % s->numImages; } @@ -405,7 +405,7 @@ VKAPI_ATTR void VKAPI_CALL vkDestroySwapchainKHR( for(int c = 0; c < s->numImages; ++c) { vkFreeMemory(device, s->images[c].boundMem, 0); - modeset_destroy_fb(controlFd, &s->images[c]); + modeset_destroy_fb(device->dev->instance->controlFd, &s->images[c]); } free(s->images);