diff --git a/driver/fifo.c b/driver/fifo.c new file mode 100644 index 0000000..5cfd95e --- /dev/null +++ b/driver/fifo.c @@ -0,0 +1,112 @@ +#include "fifo.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +Fifo createFifo(void* dataMem, void* fifoElemMem, uint32_t maxElems, uint32_t dataSize) +{ + Fifo f; + f.first = 0; + f.last = 0; + f.dataSize = dataSize; + f.maxElems = maxElems; + f.dataBuf = createPoolAllocator(dataMem, dataSize, maxElems * dataSize); + f.fifoElemBuf = createPoolAllocator(fifoElemMem, sizeof(FifoElem), maxElems * sizeof(FifoElem)); + + return f; +} + +void destroyFifo(Fifo* f) +{ + assert(f); + f->first = 0; + f->last = 0; + destroyPoolAllocator(&f->dataBuf); + destroyPoolAllocator(&f->fifoElemBuf); +} + +uint32_t fifoAdd(Fifo* f, void* data) +{ + assert(f); + assert(data); + + void* dataPtr = poolAllocate(&f->dataBuf); + FifoElem* elemPtr = poolAllocate(&f->fifoElemBuf); + + memcpy(dataPtr, data, f->dataSize); + elemPtr->data = dataPtr; + + if(!dataPtr || !elemPtr) + { + return 0; + } + + if(!f->first) + { + elemPtr->prev = 0; + elemPtr->next = 0; + + f->first = elemPtr; + f->last = elemPtr; + } + else + { + FifoElem* tmpFirst = f->first; + + elemPtr->next = tmpFirst; + elemPtr->prev = 0; + tmpFirst->prev = elemPtr; + + f->first = elemPtr; + } + + return 1; +} + +void fifoRemove(Fifo* f, void* data) +{ + assert(f); + + if(f->last) + { + memcpy(data, f->last->data, f->dataSize); + + FifoElem* tmp = f->last; + + f->last = f->last->prev; + + if(f->last) + { + f->last->next = 0; + } + else + { + f->first = 0; + } + + poolFree(&f->dataBuf, tmp->data); + poolFree(&f->fifoElemBuf, tmp); + } +} + +void debugPrintFifo(Fifo* f) +{ + assert(f); + + fprintf(stderr, "fifo debug print\n"); + fprintf(stderr, "dataSize %u\n", f->dataSize); + fprintf(stderr, "maxElems %u\n", f->maxElems); + + FifoElem* ptr = f->first; + + while(ptr) + { + fprintf(stderr, "fifo elem %p prev %p next %p data %p\n", ptr, ptr->prev, ptr->next, ptr->data); + ptr = ptr->next; + } +} + +#if defined (__cplusplus) +} +#endif diff --git a/driver/fifo.h b/driver/fifo.h new file mode 100644 index 0000000..86f249b --- /dev/null +++ b/driver/fifo.h @@ -0,0 +1,38 @@ +#pragma once + +#if defined (__cplusplus) +extern "C" { +#endif + +#include "CustomAssert.h" + +#include "PoolAllocator.h" + +#include + +typedef struct FifoElem +{ + struct FifoElem* next; + struct FifoElem* prev; + void* data; +} FifoElem; + +typedef struct Fifo +{ + FifoElem* first; + FifoElem* last; + PoolAllocator dataBuf; + PoolAllocator fifoElemBuf; + uint32_t dataSize; + uint32_t maxElems; +} Fifo; + +Fifo createFifo(void* dataMem, void* fifoElemMem, uint32_t maxElems, uint32_t dataSize); +void destroyFifo(Fifo* f); +uint32_t fifoAdd(Fifo* f, void* data); +void fifoRemove(Fifo* f, void* data); +void debugPrintFifo(Fifo* f); + +#if defined (__cplusplus) +} +#endif diff --git a/driver/modeset.c b/driver/modeset.c index fa848c5..2e2eee2 100644 --- a/driver/modeset.c +++ b/driver/modeset.c @@ -257,8 +257,12 @@ typedef struct vsyncData { _image* i; modeset_display_surface* s; + uint32_t pending; } vsyncData; +static vsyncData flipQueue[2] = {}; +atomic_int flip_queue_guard = 0; + static void modeset_page_flip_event(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data) @@ -266,10 +270,34 @@ static void modeset_page_flip_event(int fd, unsigned int frame, if(data) { vsyncData* d = data; - //TODO image is now available for rendering + + while(flip_queue_guard); + flip_queue_guard = 1; + + flipQueue[0].pending = 0; + + flip_queue_guard = 0; } } +void modeset_acquire_image(int fd, _image* buf, modeset_display_surface* surface) +{ + while(flip_queue_guard); + flip_queue_guard = 1; + + //TODO + //try to find any image that's not pending + //call handle event until that happens + //then find a non-pending image + drmEventContext ev; + memset(&ev, 0, sizeof(ev)); + ev.version = 2; + ev.page_flip_handler = modeset_page_flip_event; + drmHandleEvent(fd, &ev); + + flip_queue_guard = 0; +} + void modeset_present(int fd, _image *buf, modeset_display_surface* surface) { if(!surface->savedState) @@ -312,7 +340,18 @@ void modeset_present(int fd, _image *buf, modeset_display_surface* surface) vsyncData d; d.i = buf; d.s = surface; - drmModePageFlip(fd, surface->crtc->crtc_id, buf->fb, DRM_MODE_PAGE_FLIP_EVENT, 0); + d.pending = 1; + + while(flipQueue[0].pending); + + while(flip_queue_guard); + flip_queue_guard = 1; + + flipQueue[0] = d; + drmModePageFlip(fd, surface->crtc->crtc_id, buf->fb, DRM_MODE_PAGE_FLIP_EVENT, &flipQueue[0]); + + flip_queue_guard = 0; + } //modeset_debug_print(fd); diff --git a/driver/modeset.h b/driver/modeset.h index 0f52a1e..d6eaa51 100644 --- a/driver/modeset.h +++ b/driver/modeset.h @@ -62,6 +62,7 @@ void modeset_create_surface_for_mode(int fd, uint32_t display, uint32_t mode, mo void modeset_create_fb_for_surface(int fd, _image* buf, modeset_display_surface* surface); void modeset_destroy_fb(int fd, _image* buf); void modeset_present(int fd, _image* buf, modeset_display_surface* surface); +void modeset_acquire_image(int fd, _image* buf, modeset_display_surface* surface); void modeset_destroy_surface(int fd, modeset_display_surface* surface); void modeset_debug_print(int fd); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 7ff44c7..b634c1f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -17,4 +17,5 @@ add_subdirectory(cubemapping) add_subdirectory(attribTest) add_subdirectory(clearTest) add_subdirectory(inputTest) -add_subdirectory(mintest) \ No newline at end of file +add_subdirectory(mintest) +add_subdirectory(FifoTest) \ No newline at end of file diff --git a/test/FifoTest/CMakeLists.txt b/test/FifoTest/CMakeLists.txt new file mode 100644 index 0000000..77ce8b1 --- /dev/null +++ b/test/FifoTest/CMakeLists.txt @@ -0,0 +1,11 @@ +file(GLOB testSrc + "*.h" + "*.cpp" +) + +add_executable(FifoTest ${testSrc}) +target_compile_options(FifoTest PRIVATE -Wall -std=c++11 + -march=${RPI_ARCH} -fPIC + ) + +target_link_libraries(FifoTest rpi-vk-driver) diff --git a/test/FifoTest/FifoTest.cpp b/test/FifoTest/FifoTest.cpp new file mode 100644 index 0000000..3a86513 --- /dev/null +++ b/test/FifoTest/FifoTest.cpp @@ -0,0 +1,34 @@ +#include +#include +#include +#include +#include "driver/CustomAssert.h" +#include "driver/fifo.h" + +int main() { + + uint32_t maxElems = 5; + void* dataBuf = malloc(sizeof(uint32_t) * maxElems); + void* elemBuf = malloc(sizeof(FifoElem) * maxElems); + Fifo f = createFifo(dataBuf, elemBuf, maxElems, sizeof(uint32_t)); + + debugPrintFifo(&f); + + for(uint32_t data = 1; data <= 5; ++data) + { + fifoAdd(&f, &data); + debugPrintFifo(&f); + } + + for(uint32_t c = 0; c < 5; ++c) + { + uint32_t data = 0; + fifoRemove(&f, &data); + debugPrintFifo(&f); + fprintf(stderr, "data %u\n", data); + } + + destroyFifo(&f); + + return 0; +}