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

rewriting modesetting so that direct to display is supported

This commit is contained in:
Unknown 2020-04-16 00:04:41 +01:00
parent db4d3d6507
commit a67cf48094
11 changed files with 307 additions and 281 deletions

View File

@ -515,6 +515,12 @@ typedef struct VkQueryPool_T
_query* queryPool;
} _queryPool;
typedef struct VkDisplayModeKHR_T
{
uint32_t connectorID;
uint32_t modeID;
} _displayMode;
uint32_t getFormatBpp(VkFormat f);
uint32_t packVec4IntoABGR8(const float rgba[4]);
void createImageBO(_image* i);

View File

@ -1020,6 +1020,24 @@ VKAPI_ATTR VkResult VKAPI_CALL rpi_vkAcquireProfilingLockKHR(
VKAPI_ATTR void VKAPI_CALL rpi_vkReleaseProfilingLockKHR(
VkDevice device);
VKAPI_ATTR VkResult VKAPI_CALL rpi_vkGetPhysicalDeviceDisplayPropertiesKHR(
VkPhysicalDevice physicalDevice,
uint32_t* pPropertyCount,
VkDisplayPropertiesKHR* pProperties);
VKAPI_ATTR VkResult VKAPI_CALL rpi_vkGetDisplayModePropertiesKHR(
VkPhysicalDevice physicalDevice,
VkDisplayKHR display,
uint32_t* pPropertyCount,
VkDisplayModePropertiesKHR* pProperties);
VKAPI_ATTR VkResult VKAPI_CALL rpi_vkCreateDisplayModeKHR(
VkPhysicalDevice physicalDevice,
VkDisplayKHR display,
const VkDisplayModeCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkDisplayModeKHR* pMode);
#ifdef __cplusplus
}
#endif

View File

@ -37,9 +37,6 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(VkInsta
{
void* ptr = 0;
if(!strcmp(pName, "vkCreateRpiSurfaceEXT"))
ptr = &rpi_vkCreateRpiSurfaceEXT;
if(!strcmp(pName, "vkCreateShaderModuleFromRpiAssemblyEXT"))
ptr = &rpi_vkCreateShaderModuleFromRpiAssemblyEXT;
@ -475,6 +472,10 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL rpi_vkGetInstanceProcAddr(
RETFUNC(vkAcquireProfilingLockKHR);
RETFUNC(vkReleaseProfilingLockKHR);
RETFUNC(vkGetPhysicalDeviceDisplayPropertiesKHR);
RETFUNC(vkGetDisplayModePropertiesKHR);
RETFUNC(vkCreateDisplayModeKHR);
return 0;
}

View File

@ -1,54 +1,5 @@
/*
* modeset - DRM Double-Buffered Modesetting Example
*
* Written 2012 by David Herrmann <dh.herrmann@googlemail.com>
* Dedicated to the Public Domain.
*/
/*
* DRM Modesetting Howto
* This document describes the DRM modesetting API. Before we can use the DRM
* API, we have to include xf86drm.h and xf86drmMode.h. Both are provided by
* libdrm which every major distribution ships by default. It has no other
* dependencies and is pretty small.
*
* Please ignore all forward-declarations of functions which are used later. I
* reordered the functions so you can read this document from top to bottom. If
* you reimplement it, you would probably reorder the functions to avoid all the
* nasty forward declarations.
*
* For easier reading, we ignore all memory-allocation errors of malloc() and
* friends here. However, we try to correctly handle all other kinds of errors
* that may occur.
*
* All functions and global variables are prefixed with "modeset_*" in this
* file. So it should be clear whether a function is a local helper or if it is
* provided by some external library.
*/
#include "modeset.h"
/*
* Previously, we used the modeset_dev objects to hold buffer informations, too.
* Technically, we could have split them but avoided this to make the
* example simpler.
* However, in this example we need 2 buffers. One back buffer and one front
* buffer. So we introduce a new structure modeset_buf which contains everything
* related to a single buffer. Each device now gets an array of two of these
* buffers.
* Each buffer consists of width, height, stride, size, handle, map and fb-id.
* They have the same meaning as before.
*
* Each device also gets a new integer field: front_buf. This field contains the
* index of the buffer that is currently used as front buffer / scanout buffer.
* In our example it can be 0 or 1. We flip it by using XOR:
* dev->front_buf ^= dev->front_buf
*
* Everything else stays the same.
*/
//static struct modeset_dev *modeset_list = NULL;
static int modeset_find_crtc(int fd, drmModeRes *res, drmModeConnector *conn,
struct modeset_dev *dev);
static int modeset_setup_dev(int fd, drmModeRes *res, drmModeConnector *conn,
@ -88,13 +39,6 @@ modeset_dev* modeset_create(int fd)
struct modeset_dev *dev;
int ret;
//we'll use a buffer created by the vc4 kernel module instead
/*uint64_t has_dumb;
if (drmGetCap(fd, DRM_CAP_DUMB_BUFFER, &has_dumb) < 0 || !has_dumb) {
printf("drm device does not support dumb buffers\n");
return 0;
}*/
// retrieve resources
res = drmModeGetResources(fd);
if (!res) {
@ -204,30 +148,6 @@ static int modeset_setup_dev(int fd, drmModeRes *res, drmModeConnector *conn,
}
/*static int modeset_create_swapchain(int fd, drmModeConnector *conn, struct modeset_dev *dev)
{
int ret;
// create framebuffer #1 for this CRTC
ret = modeset_create_fb(fd, &dev->bufs[0]);
if (ret) {
printf("cannot create framebuffer for connector %u\n",
conn->connector_id);
return ret;
}
// create framebuffer #2 for this CRTC
ret = modeset_create_fb(fd, &dev->bufs[1]);
if (ret) {
printf("cannot create framebuffer for connector %u\n",
conn->connector_id);
modeset_destroy_fb(fd, &dev->bufs[0]);
return ret;
}
return 0;
}*/
/*
* modeset_find_crtc() stays the same.
*/
@ -318,27 +238,8 @@ static int modeset_find_crtc(int fd, drmModeRes *res, drmModeConnector *conn,
int modeset_create_fb(int fd, _image *buf)
{
//struct drm_mode_create_dumb creq;
//struct drm_mode_destroy_dumb dreq;
//struct drm_mode_map_dumb mreq;
int ret;
//we'll use a buffer created by vc4 instead
// create dumb buffer
/*memset(&creq, 0, sizeof(creq));
creq.width = buf->width;
creq.height = buf->height;
creq.bpp = 32;
ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &creq);
if (ret < 0) {
printf("cannot create dumb buffer (%d): %m\n",
errno);
return -errno;
}
buf->stride = creq.pitch;
buf->size = creq.size;
buf->handle = creq.handle;*/
// create framebuffer object for the dumb-buffer
ret = drmModeAddFB(fd, buf->width, buf->height, 24, 32, buf->stride,
buf->boundMem->bo, &buf->fb);
@ -347,48 +248,9 @@ int modeset_create_fb(int fd, _image *buf)
errno);
ret = -errno;
//memset(&dreq, 0, sizeof(dreq));
//dreq.handle = buf->handle;
//drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
return ret;
}
/**
// prepare buffer for memory mapping
memset(&mreq, 0, sizeof(mreq));
mreq.handle = buf->handle;
ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &mreq);
if (ret) {
printf("cannot map dumb buffer (%d): %m\n",
errno);
ret = -errno;
drmModeRmFB(fd, buf->fb);
memset(&dreq, 0, sizeof(dreq));
dreq.handle = buf->handle;
drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
return ret;
}
// perform actual memory mapping
buf->map = mmap(0, buf->size, PROT_READ | PROT_WRITE, MAP_SHARED,
fd, mreq.offset);
if (buf->map == MAP_FAILED) {
printf("cannot mmap dumb buffer (%d): %m\n",
errno);
ret = -errno;
drmModeRmFB(fd, buf->fb);
memset(&dreq, 0, sizeof(dreq));
dreq.handle = buf->handle;
drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
return ret;
}
// clear the framebuffer to 0
memset(buf->map, 0, buf->size);
/**/
return 0;
}
@ -401,54 +263,10 @@ int modeset_create_fb(int fd, _image *buf)
void modeset_destroy_fb(int fd, _image* buf)
{
//struct drm_mode_destroy_dumb dreq;
// unmap buffer
//munmap(buf->map, buf->size);
// delete framebuffer
drmModeRmFB(fd, buf->fb);
// delete dumb buffer
/*memset(&dreq, 0, sizeof(dreq));
dreq.handle = buf->handle;
drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);*/
}
/*
* modeset_draw() is the place where things change. The render-logic is the same
* and we still draw a solid-color on the whole screen. However, we now have two
* buffers and need to flip between them.
*
* So before drawing into a framebuffer, we need to find the back-buffer.
* Remember, dev->font_buf is the index of the front buffer, so
* dev->front_buf ^ 1 is the index of the back buffer. We simply use
* dev->bufs[dev->front_buf ^ 1] to get the back-buffer and draw into it.
*
* After we finished drawing, we need to flip the buffers. We do this with the
* same call as we initially set the CRTC: drmModeSetCrtc(). However, we now
* pass the back-buffer as new framebuffer as we want to flip them.
* The only thing left to do is to change the dev->front_buf index to point to
* the new back-buffer (which was previously the front buffer).
* We then sleep for a short time period and start drawing again.
*
* If you run this example, you will notice that there is almost no flickering,
* anymore. The buffers are now swapped as a whole so each new frame shows
* always the whole new image. If you look carefully, you will notice that the
* modeset.c example showed many screen corruptions during redraw-cycles.
*
* However, this example is still not perfect. Imagine the display-controller is
* currently scanning out a new image and we call drmModeSetCrtc()
* simultaneously. It will then have the same effect as if we used a single
* buffer and we get some tearing. But, the chance that this happens is a lot
* less likely as with a single-buffer. This is because there is a long period
* between each frame called vertical-blank where the display-controller does
* not perform a scanout. If we swap the buffers in this period, we have the
* guarantee that there will be no tearing. See the modeset-vsync.c example if
* you want to know how you can guarantee that the swap takes place at a
* vertical-sync.
*/
void modeset_present_buffer(int fd, modeset_dev* dev, _image* buffer)
{
//TODO use index!!
@ -459,20 +277,15 @@ void modeset_present_buffer(int fd, modeset_dev* dev, _image* buffer)
}
struct modeset_dev *iter;
//struct modeset_buf *buf;
int ret;
for (iter = dev; iter; iter = iter->next)
{
//buf = &iter->bufs[iter->front_buf ^ 1];
ret = drmModeSetCrtc(fd, iter->crtc, buffer->fb, 0, 0,
&iter->conn, 1, &iter->mode);
if (ret)
fprintf(stderr, "cannot flip CRTC for connector %u (%d): %m\n",
iter->conn, errno);
//else
// iter->front_buf ^= 1;
}
}
@ -501,36 +314,109 @@ void modeset_destroy(int fd, modeset_dev* dev)
&iter->saved_crtc->mode);
drmModeFreeCrtc(iter->saved_crtc);
// destroy framebuffers
//modeset_destroy_fb(fd, &iter->bufs[1]);
//modeset_destroy_fb(fd, &iter->bufs[0]);
// free allocated memory
free(iter);
}
}
/*
* This was a very short extension to the basic modesetting example that shows
* how double-buffering is implemented. Double-buffering is the de-facto
* standard in any graphics application so any other example will be based on
* this. It is important to understand the ideas behind it as the code is pretty
* easy and short compared to modeset.c.
*
* Double-buffering doesn't solve all problems. Vsync'ed page-flips solve most
* of the problems that still occur, but has problems on it's own (see
* modeset-vsync.c for a discussion).
*
* If you want more code, I can recommend reading the source-code of:
* - plymouth (which uses dumb-buffers like this example; very easy to understand)
* - kmscon (which uses libuterm to do this)
* - wayland (very sophisticated DRM renderer; hard to understand fully as it
* uses more complicated techniques like DRM planes)
* - xserver (very hard to understand as it is split across many files/projects)
*
* Any feedback is welcome. Feel free to use this code freely for your own
* documentation or projects.
*
* - Hosted on http://github.com/dvdhrm/docs
* - Written by David Herrmann <dh.herrmann@googlemail.com>
*/
void modeset_enum_displays(int fd, uint32_t* numDisplays, modeset_display** displays)
{
drmModeResPtr resPtr = drmModeGetResources(fd);
uint32_t tmpNumDisplays = 0;
modeset_display tmpDisplays[16];
for(uint32_t c = 0; c < resPtr->count_connectors; ++c)
{
drmModeConnectorPtr connPtr = drmModeGetConnector(fd, resPtr->connectors[c]);
if(connPtr->connection != DRM_MODE_CONNECTED)
{
continue; //skip unused connector
}
if(!connPtr->count_modes)
{
continue; //skip connectors with no valid modes
}
memcpy(tmpDisplays[tmpNumDisplays].name, connPtr->modes[0].name, 32);
tmpDisplays[tmpNumDisplays].mmWidth = connPtr->mmWidth;
tmpDisplays[tmpNumDisplays].mmHeight = connPtr->mmHeight;
tmpDisplays[tmpNumDisplays].resWidth = connPtr->modes[0].hdisplay;
tmpDisplays[tmpNumDisplays].resHeight = connPtr->modes[0].vdisplay;
tmpDisplays[tmpNumDisplays].connectorID = connPtr->connector_id;
tmpNumDisplays++;
assert(tmpNumDisplays < 16);
drmModeFreeConnector(connPtr);
}
drmModeFreeResources(resPtr);
*numDisplays = tmpNumDisplays;
memcpy(*displays, tmpDisplays, tmpNumDisplays * sizeof(modeset_display));
}
void modeset_enum_modes_for_display(int fd, uint32_t display, uint32_t* numModes, modeset_display_mode** modes)
{
drmModeResPtr resPtr = drmModeGetResources(fd);
drmModeConnectorPtr connPtr = drmModeGetConnector(fd, display);
uint32_t tmpNumModes = 0;
modeset_display_mode tmpModes[1024];
for(uint32_t c = 0; c < connPtr->count_modes; ++c)
{
tmpModes[tmpNumModes].connectorID = display;
tmpModes[tmpNumModes].modeID = c;
tmpModes[tmpNumModes].refreshRate = connPtr->modes[c].vrefresh;
tmpModes[tmpNumModes].resWidth = connPtr->modes[c].hdisplay;
tmpModes[tmpNumModes].resHeight = connPtr->modes[c].vdisplay;
tmpNumModes++;
assert(tmpNumModes < 1024);
}
drmModeFreeConnector(connPtr);
drmModeFreeResources(resPtr);
*numModes = tmpNumModes;
memcpy(*modes, tmpModes, tmpNumModes * sizeof(modeset_display_mode));
}
void modeset_create_surface_for_mode(int fd, uint32_t display, uint32_t mode, modeset_display_surface* surface)
{
drmModeResPtr resPtr = drmModeGetResources(fd);
drmModeConnectorPtr connPtr = drmModeGetConnector(fd, display);
drmModeEncoderPtr encPtr = 0;
//if current encoder is valid, try to use that
if(connPtr->encoder_id)
{
encPtr = drmModeGetEncoder(fd, connPtr->encoder_id);
}
if(encPtr)
{
if(encPtr->crtc_id)
{
surface->connectorID = display;
surface->modeID = mode;
surface->encoderID = connPtr->encoder_id;
surface->crtcID = encPtr->crtc_id;
}
}
}

View File

@ -23,9 +23,6 @@ extern "C" {
typedef struct modeset_dev {
struct modeset_dev *next;
//unsigned int front_buf;
//struct modeset_buf bufs[2];
drmModeModeInfo mode;
uint32_t conn;
uint32_t crtc;
@ -35,6 +32,27 @@ typedef struct modeset_dev {
uint32_t handle;
} modeset_dev;
typedef struct modeset_display {
char name[32];
uint32_t mmWidth, mmHeight;
uint32_t resWidth, resHeight;
uint32_t connectorID;
} modeset_display;
typedef struct modeset_display_mode {
uint32_t connectorID;
uint32_t modeID;
uint32_t resWidth, resHeight;
uint32_t refreshRate;
} modeset_display_mode;
typedef struct modeset_display_surface {
uint32_t connectorID;
uint32_t modeID;
uint32_t encoderID;
uint32_t crtcID;
} modeset_display_mode;
modeset_dev* modeset_create(int fd);
void modeset_present_buffer(int fd, modeset_dev* dev, _image* buffer);
void modeset_destroy(int fd, modeset_dev* dev);
@ -42,6 +60,10 @@ int modeset_create_fb(int fd, _image *buf);
void modeset_destroy_fb(int fd, _image *buf);
int modeset_fb_for_dev(int fd, modeset_dev* dev, _image* buffer);
void modeset_enum_displays(int fd, uint32_t* numDisplays, modeset_display** displays);
void modeset_enum_modes_for_display(int fd, uint32_t display, uint32_t* numModes, modeset_display_mode** modes);
void modeset_create_surface_for_mode(int fd, uint32_t display, uint32_t mode, modeset_display_surface* surface);
#if defined (__cplusplus)
}
#endif

View File

@ -215,10 +215,6 @@ static VkExtensionProperties instanceExtensions[] =
.extensionName = "VK_KHR_display",
.specVersion = 21
},
{
.extensionName = "VK_EXT_direct_mode_display",
.specVersion = 1
},
{
.extensionName = "VK_EXT_debug_report",
.specVersion = 9
@ -226,12 +222,7 @@ static VkExtensionProperties instanceExtensions[] =
{
.extensionName = "VK_EXT_debug_utils",
.specVersion = 1
},
//TODO not an official extension, so can't expose it
//{
// .extensionName = "VK_KHR_rpi_surface",
// .specVersion = 1
//}
}
};
#define numInstanceExtensions (sizeof(instanceExtensions) / sizeof(VkExtensionProperties))

View File

@ -7,8 +7,6 @@
extern "C" {
#endif
typedef VkResult (*PFN_vkCreateRpiSurfaceEXT)(
VkPhysicalDevice physicalDevice);
typedef VkResult (*PFN_vkCreateShaderModuleFromRpiAssemblyEXT)(
VkPhysicalDevice physicalDevice);
@ -65,11 +63,6 @@ typedef struct LoaderTrampoline
*
*/
typedef enum VkRpiSurfaceCreateFlagsEXT {
//reserved
VK_RPI_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VkRpiSurfaceCreateFlagsEXT;
typedef enum VkRpiAssemblyMappingTypeEXT {
VK_RPI_ASSEMBLY_MAPPING_TYPE_DESCRIPTOR = 0,
@ -88,18 +81,6 @@ typedef struct VkRpiAssemblyMappingEXT {
VkShaderStageFlagBits shaderStage;
} VkRpiAssemblyMappingEXT;
//we need something like the other platforms to create surfaces on the RPI
//so I created this little "extension"
//full spec in this file ;)
typedef struct VkRpiSurfaceCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkRpiSurfaceCreateFlagsEXT flags; //reserved
const VkAllocationCallbacks* pAllocator;
VkSurfaceKHR* pSurface;
} VkRpiSurfaceCreateInfoEXT;
typedef struct VkRpiShaderModuleAssemblyCreateInfoEXT {
VkStructureType sType;
const void* pNext;

View File

@ -9,24 +9,6 @@
extern "C" {
#endif
/*
* Implementation of our RPI specific "extension"
*/
VkResult rpi_vkCreateRpiSurfaceEXT(VkPhysicalDevice physicalDevice)
{
assert(physicalDevice);
//TODO use allocator!
_physicalDevice* ptr = physicalDevice;
VkRpiSurfaceCreateInfoEXT* ci = ptr->customData;
VkSurfaceKHR surfRes = (VkSurfaceKHR)modeset_create(controlFd);
*ci->pSurface = surfRes;
return VK_SUCCESS;
}
//TODO collect shader performance data
//eg number of texture samples etc.
//TODO check if shader has flow control and make sure instance also has flow control

View File

@ -6,11 +6,6 @@
extern "C" {
#endif
//extension name something like: VK_KHR_rpi_surface
//extension that allows developers to create a surface to render to on Raspbian Stretch Lite
extern VkResult rpi_vkCreateRpiSurfaceEXT(
VkPhysicalDevice physicalDevice);
//extension that allows developers to submit QPU assembly directly and thus hand optimise code
extern VkResult rpi_vkCreateShaderModuleFromRpiAssemblyEXT(
VkPhysicalDevice physicalDevice);

View File

@ -9,13 +9,133 @@
extern "C" {
#endif
VKAPI_ATTR VkResult VKAPI_CALL rpi_vkGetPhysicalDeviceDisplayPropertiesKHR(
VkPhysicalDevice physicalDevice,
uint32_t* pPropertyCount,
VkDisplayPropertiesKHR* pProperties)
{
assert(physicalDevice);
assert(pPropertyCount);
uint32_t numDisplays;
modeset_display displays[16];
modeset_enum_displays(controlFd, &numDisplays, &displays);
if(!pProperties)
{
*pPropertyCount = numDisplays;
return VK_SUCCESS;
}
int arraySize = *pPropertyCount;
int elementsWritten = min(numDisplays, arraySize);
for(int c = 0; c < elementsWritten; ++c)
{
pProperties[c].display = displays[c].connectorID;
char* name = (char*)malloc(32);
memcpy(name, displays[c].name, 32);
pProperties[c].displayName = (const char*)name;
pProperties[c].physicalDimensions.width = displays[c].mmWidth;
pProperties[c].physicalDimensions.height = displays[c].mmHeight;
pProperties[c].physicalResolution.width = displays[c].resWidth;
pProperties[c].physicalResolution.height = displays[c].resHeight;
}
*pPropertyCount = elementsWritten;
if(arraySize < numDisplays)
{
return VK_INCOMPLETE;
}
return VK_SUCCESS;
}
VKAPI_ATTR VkResult VKAPI_CALL rpi_vkGetDisplayModePropertiesKHR(
VkPhysicalDevice physicalDevice,
VkDisplayKHR display,
uint32_t* pPropertyCount,
VkDisplayModePropertiesKHR* pProperties)
{
assert(physicalDevice);
assert(display);
assert(pPropertyCount);
uint32_t numModes;
modeset_display_mode modes[1024];
modeset_enum_modes_for_display(controlFd, display, &numModes, &modes);
if(!pProperties)
{
*pPropertyCount = numModes;
return VK_SUCCESS;
}
int arraySize = *pPropertyCount;
int elementsWritten = min(numModes, arraySize);
for(int c = 0; c < elementsWritten; ++c)
{
_displayMode mode = { modes[c].connectorID, modes[c].modeID };
memcpy(&pProperties[c].displayMode, &mode, sizeof(_displayMode));
pProperties[c].parameters.visibleRegion.width = modes[c].resWidth;
pProperties[c].parameters.visibleRegion.height = modes[c].resHeight;
pProperties[c].parameters.refreshRate = modes[c].refreshRate;
}
*pPropertyCount = elementsWritten;
if(arraySize < numModes)
{
return VK_INCOMPLETE;
}
return VK_SUCCESS;
}
VKAPI_ATTR VkResult VKAPI_CALL rpi_vkCreateDisplayModeKHR(
VkPhysicalDevice physicalDevice,
VkDisplayKHR display,
const VkDisplayModeCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkDisplayModeKHR* pMode)
{
assert(physicalDevice);
assert(display);
uint32_t numModes;
modeset_display_mode modes[1024];
modeset_enum_modes_for_display(controlFd, display, &numModes, &modes);
for(uint32_t c = 0; c < numModes; ++c)
{
if(modes[c].refreshRate == pCreateInfo->parameters.refreshRate &&
modes[c].resWidth == pCreateInfo->parameters.visibleRegion.width &&
modes[c].resHeight == pCreateInfo->parameters.visibleRegion.height)
{
_displayMode mode = { modes[c].connectorID, modes[c].modeID };
memcpy(pMode, &mode, sizeof(_displayMode));
}
}
}
VKAPI_ATTR VkResult VKAPI_CALL rpi_vkCreateDisplayPlaneSurfaceKHR(
VkInstance instance,
const VkDisplaySurfaceCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface)
{
fprintf(stderr, "vkCreateDisplayPlaneSurfaceKHR\n");
assert(instance);
assert(pSurface);
_displayMode mode = pCreateInfo->displayMode;
modeset_display_surface* surface = ALLOCATE(sizeof(modeset_display_surface), 1, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
modeset_create_surface_for_mode(controlFd, mode.connectorID, mode.modeID, surface);
*pSurface = surface;
}
/*
@ -31,12 +151,12 @@ VKAPI_ATTR void VKAPI_CALL rpi_vkDestroySurfaceKHR(
{
assert(instance);
//TODO use allocator
if(surface)
{
modeset_destroy(controlFd, (modeset_dev*)surface);
//modeset_destroy(controlFd, (modeset_dev*)surface);
}
FREE(surface);
}
/*

View File

@ -212,11 +212,11 @@ void createInstance() {
}
void createWindowSurface() {
PFN_vkCreateRpiSurfaceEXT vkCreateRpiSurfaceEXT = 0;
vkCreateRpiSurfaceEXT = (PFN_vkCreateRpiSurfaceEXT)vkGetInstanceProcAddr(instance, "vkCreateRpiSurfaceEXT");
windowSurface = 0;
/*PFN_vkCreateRpiSurfaceEXT vkCreateRpiSurfaceEXT = 0;
vkCreateRpiSurfaceEXT = (PFN_vkCreateRpiSurfaceEXT)vkGetInstanceProcAddr(instance, "vkCreateRpiSurfaceEXT");
LoaderTrampoline* trampoline = (LoaderTrampoline*)physicalDevice;
VkRpiPhysicalDevice* realPhysicalDevice = trampoline->loaderTerminator->physicalDevice;
@ -228,7 +228,31 @@ void createWindowSurface() {
if (vkCreateRpiSurfaceEXT(physicalDevice) != VK_SUCCESS) {
std::cerr << "failed to create window surface!" << std::endl;
assert(0);
}
}*/
uint32_t displayCount;
vkGetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, &displayCount, 0);
VkDisplayPropertiesKHR* displayProperties = (VkDisplayPropertiesKHR*)malloc(sizeof(VkDisplayPropertiesKHR)*displayCount);
vkGetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, &displayCount, displayProperties);
uint32_t propertyCount;
vkGetDisplayModePropertiesKHR(physicalDevice, displayProperties[0].display, &propertyCount, 0);
VkDisplayModePropertiesKHR* displayModeProperties = (VkDisplayModePropertiesKHR*)malloc(sizeof(VkDisplayModePropertiesKHR)*propertyCount);
vkGetDisplayModePropertiesKHR(physicalDevice, displayProperties[0].display, &propertyCount, displayModeProperties);
VkDisplayModeCreateInfoKHR dmci = {};
dmci.sType = VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR;
dmci.parameters = displayModeProperties[0].parameters;
VkDisplayModeKHR displayMode;
vkCreateDisplayModeKHR(physicalDevice, displayProperties[0].display, &dmci, 0, &displayMode);
VkDisplaySurfaceCreateInfoKHR dsci = {};
dsci.sType = VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR;
dsci.displayMode = displayMode;
dsci.transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
dsci.alphaMode = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR;
dsci.imageExtent = displayModeProperties[0].parameters.visibleRegion;
vkCreateDisplayPlaneSurfaceKHR(instance, &dsci, 0, &windowSurface);
std::cout << "created window surface" << std::endl;
}