diff --git a/driver/command.c b/driver/command.c index c93446d..fbb746d 100644 --- a/driver/command.c +++ b/driver/command.c @@ -6,10 +6,7 @@ #include "declarations.h" -#include - -static uint64_t lastFinishedSeqno = 0; -static atomic_int lastSeqnoGuard = 0; +#include #define VC4_HW_2116_COUNT 0x1ef0 @@ -667,14 +664,12 @@ VKAPI_ATTR VkResult VKAPI_CALL RPIFUNC(vkQueueSubmit)( assert(submitCl.bo_handle_count > 0); - //TODO - while(lastSeqnoGuard); + sem_wait(queue->seqnoSem); { - lastSeqnoGuard = 1; //submit ioctl - vc4_cl_submit(controlFd, &submitCl, &queue->lastEmitSeqno, &lastFinishedSeqno); - lastSeqnoGuard = 0; + vc4_cl_submit(controlFd, &submitCl, &queue->lastEmitSeqno, &queue->lastFinishedSeqno); } + sem_post(queue->seqnoSem); //see if it's a sync bug //uint64_t timeout = WAIT_TIMEOUT_INFINITE; diff --git a/driver/common.h b/driver/common.h index edf80f1..e85b481 100644 --- a/driver/common.h +++ b/driver/common.h @@ -61,7 +61,9 @@ typedef struct VkQueue_T { VK_LOADER_DATA loaderData; uint64_t lastEmitSeqno; + uint64_t lastFinishedSeqno; _device* dev; + struct sem_t* seqnoSem; } _queue; typedef struct VkCommandPool_T diff --git a/driver/device.c b/driver/device.c index 3622bea..c1392e2 100644 --- a/driver/device.c +++ b/driver/device.c @@ -349,9 +349,16 @@ VKAPI_ATTR VkResult VKAPI_CALL RPIFUNC(vkCreateDevice)( for(int d = 0; d < pCreateInfo->pQueueCreateInfos[c].queueCount; ++d) { - (*pDevice)->queues[pCreateInfo->pQueueCreateInfos[c].queueFamilyIndex][d].lastEmitSeqno = 0; - (*pDevice)->queues[pCreateInfo->pQueueCreateInfos[c].queueFamilyIndex][d].dev = *pDevice; - set_loader_magic_value(&(*pDevice)->queues[pCreateInfo->pQueueCreateInfos[c].queueFamilyIndex][d].loaderData); + _queue* q = &(*pDevice)->queues[pCreateInfo->pQueueCreateInfos[c].queueFamilyIndex][d]; + q->lastEmitSeqno = 0; + q->lastFinishedSeqno = 0; + q->dev = *pDevice; + + q->seqnoSem = ALLOCATE(sizeof(sem_t), 1, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + sem_init(q->seqnoSem, 0, 0); + sem_post(q->seqnoSem); + + set_loader_magic_value(&q->loaderData); } (*pDevice)->numQueues[pCreateInfo->pQueueCreateInfos[c].queueFamilyIndex] = pCreateInfo->pQueueCreateInfos[c].queueCount; @@ -427,6 +434,7 @@ VKAPI_ATTR void VKAPI_CALL RPIFUNC(vkDestroyDevice)( { for(int d = 0; d < dev->numQueues[c]; ++d) { + FREE(dev->queues[d]->seqnoSem); FREE(dev->queues[d]); } } diff --git a/driver/modeset.c b/driver/modeset.c index 86f2040..5e7f3ee 100644 --- a/driver/modeset.c +++ b/driver/modeset.c @@ -2,13 +2,10 @@ #include "fifo.h" -#include #include #include #include -atomic_int saved_state_guard = 0; - typedef struct vsyncData { _image* i; @@ -26,6 +23,8 @@ static vsyncData dataMem[FLIP_FIFO_SIZE]; static FifoElem fifoMem[FLIP_FIFO_SIZE]; static sem_t flipQueueSem; +static sem_t savedStateSem; + static void* flipQueueThreadFunction(void* vargp) { uint32_t run = 1; @@ -250,6 +249,9 @@ void modeset_create_surface_for_mode(int fd, uint32_t display, uint32_t mode, mo pthread_create(&flipQueueThread, 0, flipQueueThreadFunction, &fd); sem_init(&flipQueueSem, 0, 0); sem_post(&flipQueueSem); + + sem_init(&savedStateSem, 0, 0); + sem_post(&savedStateSem); } refCount++; @@ -427,31 +429,30 @@ void modeset_present(int fd, _image *buf, modeset_display_surface* surface, uint { if(!surface->savedState) { - while(saved_state_guard); - saved_state_guard = 1; - - for(uint32_t c = 0; c < 32; ++c) + sem_wait(&savedStateSem); { - if(!modeset_saved_states[c].used) + for(uint32_t c = 0; c < 32; ++c) { - drmModeConnectorPtr tmpConnPtr = drmModeGetConnector(fd, surface->connector->connector_id); - drmModeCrtcPtr tmpCrtcPtr = drmModeGetCrtc(fd, surface->crtc->crtc_id); - modeset_saved_states[c].used = 1; - modeset_saved_states[c].conn = tmpConnPtr; - modeset_saved_states[c].crtc = tmpCrtcPtr; - surface->savedState = c; - break; + if(!modeset_saved_states[c].used) + { + drmModeConnectorPtr tmpConnPtr = drmModeGetConnector(fd, surface->connector->connector_id); + drmModeCrtcPtr tmpCrtcPtr = drmModeGetCrtc(fd, surface->crtc->crtc_id); + modeset_saved_states[c].used = 1; + modeset_saved_states[c].conn = tmpConnPtr; + modeset_saved_states[c].crtc = tmpCrtcPtr; + surface->savedState = c; + break; + } + } + + int ret = drmModeSetCrtc(fd, surface->crtc->crtc_id, buf->fb, 0, 0, &surface->connector->connector_id, 1, &surface->connector->modes[surface->modeID]); + if(ret) + { + fprintf(stderr, "cannot set CRTC for connector %u: %m\n", + surface->connector->connector_id, errno); } } - - int ret = drmModeSetCrtc(fd, surface->crtc->crtc_id, buf->fb, 0, 0, &surface->connector->connector_id, 1, &surface->connector->modes[surface->modeID]); - if(ret) - { - fprintf(stderr, "cannot set CRTC for connector %u: %m\n", - surface->connector->connector_id, errno); - } - - saved_state_guard = 0; + sem_post(&savedStateSem); } //TODO presenting needs to happen *after* the gpu is done with rendering to an image @@ -497,22 +498,21 @@ void modeset_destroy_surface(int fd, modeset_display_surface *surface) &modeset_saved_states[surface->savedState].crtc->mode); { - while(saved_state_guard); - saved_state_guard = 1; - refCount--; - drmModeFreeConnector(modeset_saved_states[surface->savedState].conn); - drmModeFreeCrtc(modeset_saved_states[surface->savedState].crtc); - modeset_saved_states[surface->savedState].used = 0; + sem_wait(&savedStateSem); + { + drmModeFreeConnector(modeset_saved_states[surface->savedState].conn); + drmModeFreeCrtc(modeset_saved_states[surface->savedState].crtc); + modeset_saved_states[surface->savedState].used = 0; + } + sem_post(&savedStateSem); if(!refCount) { destroyFifo(&flipQueueFifo); pthread_join(flipQueueThread, 0); } - - saved_state_guard = 0; } drmModeFreeConnector(surface->connector); diff --git a/driver/profiler.c b/driver/profiler.c index 6e4ba95..3bbc0da 100644 --- a/driver/profiler.c +++ b/driver/profiler.c @@ -9,10 +9,10 @@ extern "C" { #include #include -#include +#include static profiler* globalProfiler = 0; -static atomic_int globalProfilerGuard = 0; +static sem_t globalProfilerSem; #define SKIPPED_FRAMES 100 @@ -20,16 +20,12 @@ void initProfiler() { if(!globalProfiler) { - while(globalProfilerGuard); - { - globalProfilerGuard = 1; + sem_init(&globalProfilerSem, 0, 0); + sem_post(&globalProfilerSem); - globalProfiler = (profiler*)malloc(sizeof(profiler)); - globalProfiler->funcDatabase = createMap(malloc(sizeof(mapElem) * MAX_FUNCTIONS), MAX_FUNCTIONS); - globalProfiler->frameCounter = 0; - - globalProfilerGuard = 0; - } + globalProfiler = (profiler*)malloc(sizeof(profiler)); + globalProfiler->funcDatabase = createMap(malloc(sizeof(mapElem) * MAX_FUNCTIONS), MAX_FUNCTIONS); + globalProfiler->frameCounter = 0; } } @@ -37,10 +33,8 @@ void startMeasure(void* func, const char* funcName) { initProfiler(); - while(globalProfilerGuard); + sem_wait(&globalProfilerSem); { - globalProfilerGuard = 1; - assert(globalProfiler); assert(func); assert(funcName); @@ -61,9 +55,8 @@ void startMeasure(void* func, const char* funcName) assert(!data->inProgress); data->inProgress = 1; clock_gettime(CLOCK_REALTIME, &data->start); - - globalProfilerGuard = 0; } + sem_post(&globalProfilerSem); } void endMeasure(void* func) @@ -71,10 +64,8 @@ void endMeasure(void* func) struct timespec end; clock_gettime(CLOCK_REALTIME, &end); - while(globalProfilerGuard); + sem_wait(&globalProfilerSem); { - globalProfilerGuard = 1; - assert(globalProfiler); assert(func); @@ -94,23 +85,19 @@ void endMeasure(void* func) data->timeSpent += (end.tv_sec - data->start.tv_sec) * 0.001 + (end.tv_nsec - data->start.tv_nsec) / MILLION; } } - - globalProfilerGuard = 0; } + sem_post(&globalProfilerSem); } void endFrame() { if(!globalProfiler) return; - while(globalProfilerGuard); + sem_wait(&globalProfilerSem); { - globalProfilerGuard = 1; - globalProfiler->frameCounter++; - - globalProfilerGuard = 0; } + sem_post(&globalProfilerSem); } double getTimeSpent(void* func) diff --git a/test/mipmapping/mipmapping.cpp b/test/mipmapping/mipmapping.cpp index 2f4fa9d..800772f 100644 --- a/test/mipmapping/mipmapping.cpp +++ b/test/mipmapping/mipmapping.cpp @@ -163,13 +163,24 @@ void cleanup() { vkDestroyRenderPass(device, renderPass, 0); - //vkDestroyShaderModule(device, shaderModule, 0); + vkDestroyShaderModule(device, sampleShaderModule, 0); - //vkDestroyPipeline(device, pipeline, 0); + vkDestroyPipeline(device, samplePipeline, 0); // Note: implicitly destroys images (in fact, we're not allowed to do that explicitly) vkDestroySwapchainKHR(device, swapChain, nullptr); + vkDestroyBuffer(device, triangleVertexBuffer, 0); + vkFreeMemory(device, triangleVertexBufferMemory, 0); + + vkDestroyDescriptorPool(device, descriptorPool, 0); + vkDestroyDescriptorSetLayout(device, sampleDsl, 0); + vkDestroyPipelineLayout(device, samplePipelineLayout, 0); + + vkDestroyImageView(device, textureView, 0); + vkDestroyImage(device, textureImage, 0); + vkDestroySampler(device, textureSampler, 0); + vkDestroyDevice(device, nullptr); vkDestroySurfaceKHR(instance, windowSurface, nullptr);