1
0
mirror of https://github.com/Yours3lf/rpi-vk-driver.git synced 2025-02-22 19:54:18 +01:00

vsync now seems to work

This commit is contained in:
yours3lf 2020-06-04 21:33:49 +01:00
parent 2f8484e65d
commit ee1d6b44b7
2 changed files with 69 additions and 81 deletions

View File

@ -5,6 +5,8 @@
#include <stdatomic.h> #include <stdatomic.h>
#include <unistd.h> #include <unistd.h>
#include <pthread.h> #include <pthread.h>
#include <semaphore.h>
atomic_int saved_state_guard = 0; atomic_int saved_state_guard = 0;
typedef struct vsyncData typedef struct vsyncData
@ -22,7 +24,7 @@ static pthread_t flipQueueThread = 0;
static Fifo flipQueueFifo; static Fifo flipQueueFifo;
static vsyncData dataMem[FLIP_FIFO_SIZE]; static vsyncData dataMem[FLIP_FIFO_SIZE];
static FifoElem fifoMem[FLIP_FIFO_SIZE]; static FifoElem fifoMem[FLIP_FIFO_SIZE];
static atomic_int flip_queue_guard = 0; static sem_t flipQueueSem;
static void* flipQueueThreadFunction(void* vargp) static void* flipQueueThreadFunction(void* vargp)
{ {
@ -36,10 +38,8 @@ static void* flipQueueThreadFunction(void* vargp)
uint64_t seqno = 0; uint64_t seqno = 0;
sem_wait(&flipQueueSem);
{ {
while(flip_queue_guard);
flip_queue_guard = 1;
vsyncData* d = fifoGetLast(&flipQueueFifo); vsyncData* d = fifoGetLast(&flipQueueFifo);
if(d) if(d)
{ {
@ -47,9 +47,8 @@ static void* flipQueueThreadFunction(void* vargp)
} }
run = refCount; run = refCount;
flip_queue_guard = 0;
} }
sem_post(&flipQueueSem);
if(seqno) if(seqno)
{ {
@ -58,25 +57,23 @@ static void* flipQueueThreadFunction(void* vargp)
if(ret > 0) if(ret > 0)
{ {
while(flip_queue_guard); sem_wait(&flipQueueSem);
flip_queue_guard = 1;
vsyncData* d = fifoGetLast(&flipQueueFifo);
fprintf(stderr, "seqno finished, flipping %llu image %p\n", d->seqno, d->i);
d->seqno = 0; //done!
flip_queue_guard = 0;
if(d->i->presentMode == VK_PRESENT_MODE_FIFO_KHR)
{ {
drmModePageFlip(threadFD, d->s->crtc->crtc_id, d->i->fb, DRM_MODE_PAGE_FLIP_EVENT, d); vsyncData* d = fifoGetLast(&flipQueueFifo);
}
else if(d->i->presentMode == VK_PRESENT_MODE_IMMEDIATE_KHR) d->seqno = 0; //done!
{
drmModePageFlip(threadFD, d->s->crtc->crtc_id, d->i->fb, DRM_MODE_PAGE_FLIP_ASYNC, 0); if(d->i->presentMode == VK_PRESENT_MODE_FIFO_KHR)
{
d->flipPending = 1;
drmModePageFlip(threadFD, d->s->crtc->crtc_id, d->i->fb, DRM_MODE_PAGE_FLIP_EVENT, d);
}
else if(d->i->presentMode == VK_PRESENT_MODE_IMMEDIATE_KHR)
{
drmModePageFlip(threadFD, d->s->crtc->crtc_id, d->i->fb, DRM_MODE_PAGE_FLIP_ASYNC, 0);
}
} }
sem_post(&flipQueueSem);
} }
} }
} }
@ -247,19 +244,16 @@ void modeset_create_surface_for_mode(int fd, uint32_t display, uint32_t mode, mo
{ {
// modeset_debug_print(fd); // modeset_debug_print(fd);
while(flip_queue_guard);
flip_queue_guard = 1;
if(!refCount) if(!refCount)
{ {
flipQueueFifo = createFifo(dataMem, fifoMem, FLIP_FIFO_SIZE, sizeof(vsyncData)); flipQueueFifo = createFifo(dataMem, fifoMem, FLIP_FIFO_SIZE, sizeof(vsyncData));
pthread_create(&flipQueueThread, 0, flipQueueThreadFunction, &fd); pthread_create(&flipQueueThread, 0, flipQueueThreadFunction, &fd);
sem_init(&flipQueueSem, 0, 0);
sem_post(&flipQueueSem);
} }
refCount++; refCount++;
flip_queue_guard = 0;
surface->savedState = 0; surface->savedState = 0;
drmModeResPtr resPtr = drmModeGetResources(fd); drmModeResPtr resPtr = drmModeGetResources(fd);
@ -353,17 +347,16 @@ static void modeset_page_flip_event(int fd, unsigned int frame,
{ {
if(data) if(data)
{ {
while(flip_queue_guard); sem_wait(&flipQueueSem);
flip_queue_guard = 1;
if(data)
{ {
vsyncData* d = data; if(data)
{
vsyncData* d = data;
d->flipPending = 0; d->flipPending = 0;
}
} }
sem_post(&flipQueueSem);
flip_queue_guard = 0;
} }
} }
@ -371,8 +364,7 @@ void modeset_acquire_image(int fd, _image** buf, modeset_display_surface** surfa
{ {
uint32_t pending = 1, gpuprocessing = 1; uint32_t pending = 1, gpuprocessing = 1;
while(flip_queue_guard); sem_wait(&flipQueueSem);
flip_queue_guard = 1;
vsyncData* last = fifoGetLast(&flipQueueFifo); vsyncData* last = fifoGetLast(&flipQueueFifo);
@ -387,49 +379,48 @@ void modeset_acquire_image(int fd, _image** buf, modeset_display_surface** surfa
*buf = 0; *buf = 0;
*surface = 0; *surface = 0;
flip_queue_guard = 0; sem_post(&flipQueueSem);
return; return;
} }
flip_queue_guard = 0; sem_post(&flipQueueSem);
while(pending || gpuprocessing) while(pending || gpuprocessing)
{ {
drmEventContext ev; if(pending)
memset(&ev, 0, sizeof(ev)); {
ev.version = 2; drmEventContext ev;
ev.page_flip_handler = modeset_page_flip_event; memset(&ev, 0, sizeof(ev));
drmHandleEvent(fd, &ev); ev.version = 2;
ev.page_flip_handler = modeset_page_flip_event;
drmHandleEvent(fd, &ev);
}
while(flip_queue_guard); sem_wait(&flipQueueSem);
flip_queue_guard = 1; {
vsyncData* d = fifoGetLast(&flipQueueFifo);
vsyncData* d = fifoGetLast(&flipQueueFifo); //a frame must be in flight
//so fifo must contain something
assert(d);
//a frame must be in flight pending = d->flipPending;
//so fifo must contain something gpuprocessing = d->seqno > 0;
assert(d); }
sem_post(&flipQueueSem);
pending = d->flipPending;
gpuprocessing = d->seqno > 0;
flip_queue_guard = 0;
} }
vsyncData d; sem_wait(&flipQueueSem);
{
vsyncData d;
while(flip_queue_guard); fifoRemove(&flipQueueFifo, &d);
flip_queue_guard = 1;
fifoRemove(&flipQueueFifo, &d); *buf = d.i;
*surface = d.s;
fprintf(stderr, "remove image flipped %p\n", d.i); }
sem_post(&flipQueueSem);
flip_queue_guard = 0;
*buf = d.i;
*surface = d.s;
} }
void modeset_present(int fd, _image *buf, modeset_display_surface* surface, uint64_t seqno) void modeset_present(int fd, _image *buf, modeset_display_surface* surface, uint64_t seqno)
@ -483,15 +474,12 @@ void modeset_present(int fd, _image *buf, modeset_display_surface* surface, uint
while(!added) while(!added)
{ {
while(flip_queue_guard); sem_wait(&flipQueueSem);
flip_queue_guard = 1; {
//try to add request to queue
//try to add request to queue added = fifoAdd(&flipQueueFifo, &d);
added = fifoAdd(&flipQueueFifo, &d); }
sem_post(&flipQueueSem);
fprintf(stderr, "present added seqno %llu image %p\n", seqno, buf);
flip_queue_guard = 0;
} }
//modeset_debug_print(fd); //modeset_debug_print(fd);

View File

@ -498,16 +498,17 @@ VKAPI_ATTR VkResult VKAPI_CALL RPIFUNC(vkAcquireNextImageKHR)(
} }
} }
uint32_t candidateIdx = (sc->backbufferIdx + 1) % sc->numImages;
for(uint32_t c = 0; c < sc->numImages; ++c) for(uint32_t c = 0; c < sc->numImages; ++c)
{ {
if(!sc->inFlight[c]) if(!sc->inFlight[candidateIdx])
{ {
sc->backbufferIdx = c; sc->backbufferIdx = candidateIdx;
break; break;
} }
}
fprintf(stderr, "acquire backbufferIdx %u\n", sc->backbufferIdx); candidateIdx = (sc->backbufferIdx + 1) % sc->numImages;
}
*pImageIndex = sc->backbufferIdx; //return back buffer index *pImageIndex = sc->backbufferIdx; //return back buffer index
@ -564,7 +565,6 @@ VKAPI_ATTR VkResult VKAPI_CALL RPIFUNC(vkQueuePresentKHR)(
_swapchain* s = pPresentInfo->pSwapchains[c]; _swapchain* s = pPresentInfo->pSwapchains[c];
modeset_present(controlFd, &s->images[pPresentInfo->pImageIndices[c]], s->surface, queue->lastEmitSeqno); modeset_present(controlFd, &s->images[pPresentInfo->pImageIndices[c]], s->surface, queue->lastEmitSeqno);
s->inFlight[pPresentInfo->pImageIndices[c]] = 1; s->inFlight[pPresentInfo->pImageIndices[c]] = 1;
fprintf(stderr, "present backbufferIdx %u image %p\n", pPresentInfo->pImageIndices[c], &s->images[pPresentInfo->pImageIndices[c]]);
} }
PROFILEEND(RPIFUNC(vkQueuePresentKHR)); PROFILEEND(RPIFUNC(vkQueuePresentKHR));