Skip to content

Commit

Permalink
wip: some stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
recp committed Oct 8, 2023
1 parent 867d203 commit 50648e8
Show file tree
Hide file tree
Showing 7 changed files with 308 additions and 25 deletions.
11 changes: 6 additions & 5 deletions include/gpu/api/surface.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@ extern "C" {
struct GPUApi;

typedef struct GPUApiSurface {
GPUSurface *(*createSurface)(struct GPUApi * __restrict api,
struct GPUInstance * __restrict inst,
void * __restrict nativeHandle,
GPUSurfaceType type,
float scale);
GPUSurface *(*createSurface)(struct GPUApi * __restrict api,
struct GPUInstance * __restrict inst,
struct GPUPhysicalDevice * __restrict phyDevice,
void * __restrict nativeHandle,
GPUSurfaceType type,
float scale);
} GPUApiSurface;

#ifdef __cplusplus
Expand Down
9 changes: 5 additions & 4 deletions include/gpu/surface.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ typedef struct GPUSurface {

GPU_EXPORT
GPUSurface*
GPUCreateSurface(GPUInstance * __restrict inst,
void * __restrict nativeHandle,
GPUSurfaceType type,
float scale);
GPUCreateSurface(GPUInstance * __restrict inst,
GPUPhysicalDevice * __restrict phyDevice,
void * __restrict nativeHandle,
GPUSurfaceType type,
float scale);

#endif /* gpu_surface */
11 changes: 6 additions & 5 deletions src/api/surface.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@

GPU_EXPORT
GPUSurface*
GPUCreateSurface(GPUInstance * __restrict inst,
void * __restrict nativeHandle,
GPUSurfaceType type,
float scale) {
GPUCreateSurface(GPUInstance * __restrict inst,
GPUPhysicalDevice * __restrict phyDevice,
void * __restrict nativeHandle,
GPUSurfaceType type,
float scale) {
GPUApi *api;

if (!(api = gpuActiveGPUApi()))
return NULL;

return api->surface.createSurface(api, inst, nativeHandle, type, scale);
return api->surface.createSurface(api, inst, phyDevice, nativeHandle, type, scale);
}
11 changes: 6 additions & 5 deletions src/backend/mt/impl/surface.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@
#include "../common.h"

GPUSurface*
mt_createSurface(struct GPUApi * __restrict api,
struct GPUInstance * __restrict inst,
void * __restrict nativeHandle,
GPUSurfaceType type,
float scale) {
mt_createSurface(GPUApi * __restrict api,
GPUInstance * __restrict inst,
GPUPhysicalDevice * __restrict phyDevice,
void * __restrict nativeHandle,
GPUSurfaceType type,
float scale) {
GPUSurface *surface;

return NULL;
Expand Down
29 changes: 29 additions & 0 deletions src/backend/vk/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,4 +166,33 @@ typedef struct GPUPhysicalDeviceVk {
VkPhysicalDeviceFeatures physDevFeatures;
} GPUPhysicalDeviceVk;


typedef enum GPUQueueFlagBits {
GPU_QUEUE_GRAPHICS_BIT = 0x00000001,
GPU_QUEUE_COMPUTE_BIT = 0x00000002,
GPU_QUEUE_TRANSFER_BIT = 0x00000004,
GPU_QUEUE_SPARSE_BINDING_BIT = 0x00000008,
GPU_QUEUE_PROTECTED_BIT = 0x00000010,

/* TODO: */
GPU_QUEUE_VIDEO_DECODE_BIT_KHR = 0x00000020,
GPU_QUEUE_VIDEO_ENCODE_BIT_KHR = 0x00000040,
GPU_QUEUE_OPTICAL_FLOW_BIT_NV = 0x00000100,
} GPUQueueFlagBits;

typedef struct GPUCommandQueueCreateInfo {
GPUQueueFlagBits flags;
uint32_t count;
} GPUCommandQueueCreateInfo;

typedef struct GPUDeviceVk {
VkDevice device;
GPUCommandQueueCreateInfo *createCI;
GPUCommandQueue *createdQueues;
} GPUDeviceVk;

typedef struct GPUSurfaceVk {
VkSurfaceKHR surface;
} GPUSurfaceVk;

#endif /* vk_common_h */
97 changes: 97 additions & 0 deletions src/backend/vk/impl/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,103 @@ vk_getAvailablePhysicalDevicesBy(GPUApi * __restrict api,
return phyDevice;
}

GPU_HIDE
GPUDevice*
vk_createDevice(GPUApi * __restrict api,
GPUInstance * __restrict inst,
GPUPhysicalDevice * __restrict phyDevice,
GPUCommandQueueCreateInfo queueCI[],
uint32_t nQueueCI) {
GPUDevice *device;
GPUDeviceVk *deviceVk;
GPUPhysicalDeviceVk *phyDeviceVk;
GPUInstanceVk *instVk;
VkResult U_ASSERT_ONLY err;
float queue_priorities[1] = {0.0};
VkDeviceQueueCreateInfo queues[nQueueCI];
uint32_t i;

// vk_createDevice(api, inst, phyDevice, (GPUCommandQueueCreateInfo[]){
// [0] = {
// .flags = GPU_QUEUE_GRAPHICS_BIT,
// .count = 0
// }
// }, 2);

phyDeviceVk = phyDevice->priv;
instVk = inst->_priv;
deviceVk = calloc(1, sizeof(*deviceVk));

// Search for a graphics and a present queue in the array of queue
// families, try to find one that supports both
uint32_t graphicsQueueFamilyIndex = UINT32_MAX;
uint32_t presentQueueFamilyIndex = UINT32_MAX;

for (i = 0; i < phyDeviceVk->queueFamilyCount; i++) {
if ((phyDeviceVk->queueFamilyProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0) {
if (graphicsQueueFamilyIndex == UINT32_MAX) {
graphicsQueueFamilyIndex = i;
}

// if (supportsPresent[i] == VK_TRUE) {
// graphicsQueueFamilyIndex = i;
// presentQueueFamilyIndex = i;
// break;
// }
}
}

// if (presentQueueFamilyIndex == UINT32_MAX) {
// // If didn't find a queue that supports both graphics and present, then
// // find a separate present queue.
// for (uint32_t i = 0; i < phyDeviceVk->queueFamilyCount; ++i) {
// if (supportsPresent[i] == VK_TRUE) {
// presentQueueFamilyIndex = i;
// break;
// }
// }
// }

// queues[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
// queues[0].pNext = NULL;
// queues[0].queueFamilyIndex = demo->graphics_queue_family_index;
// queues[0].queueCount = 1;
// queues[0].pQueuePriorities = queue_priorities;
// queues[0].flags = 0;
//
// VkDeviceCreateInfo createInfoCI = {
// .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
// .pNext = NULL,
// .queueCreateInfoCount = 1,
// .pQueueCreateInfos = queues,
// .enabledLayerCount = 0,
// .ppEnabledLayerNames = NULL,
// .enabledExtensionCount = instVk->nEnabledExtensions,
// .ppEnabledExtensionNames = (const char *const *)instVk->extensionNames,
// .pEnabledFeatures = NULL, // If specific features are required, pass them in here
// };
//
// if (demo->separate_present_queue) {
// queues[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
// queues[1].pNext = NULL;
// queues[1].queueFamilyIndex = demo->present_queue_family_index;
// queues[1].queueCount = 1;
// queues[1].pQueuePriorities = queue_priorities;
// queues[1].flags = 0;
// createInfoCI.queueCreateInfoCount = 2;
// }
//
// err = vkCreateDevice(phyDeviceVk->phyDevice, &createInfoCI, NULL, &deviceVk->device);
// assert(!err);
//
// device = calloc(1, sizeof(*device));
// device->priv = NULL;
//
// /* TODO: select-phy device auto */

return device;
}

GPU_HIDE
void
vk_initDevice(GPUApiDevice* apiDevice) {
Expand Down
165 changes: 159 additions & 6 deletions src/backend/vk/impl/surface.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,172 @@

#include "../common.h"

/* TODO: cube.c, improve it if needed */
#if defined(VK_USE_PLATFORM_DISPLAY_KHR)
GPU_HIDE
static
VkResult
vk_createDisplaySurface(GPUInstanceVk * __restrict inst,
GPUPhysicalDeviceVk * __restrict phyDevice,
GPUSurfaceVk * __restrict surface) {
VkDisplayPlanePropertiesKHR *plane_props;
VkDisplayPropertiesKHR display_props;
VkDisplayKHR display;
VkDisplayModePropertiesKHR mode_props;
VkBool32 found_plane = VK_FALSE;
VkExtent2D image_extent;
VkDisplaySurfaceCreateInfoKHR surfaceCI;
VkResult U_ASSERT_ONLY err;
uint32_t display_count, mode_count, plane_count, plane_index;

// Get the first display
display_count = 1;
err = vkGetPhysicalDeviceDisplayPropertiesKHR(phyDevice->phyDevice,
&display_count,
&display_props);
assert(!err || (err == VK_INCOMPLETE));

display = display_props.display;

// Get the first mode of the display
err = vkGetDisplayModePropertiesKHR(phyDevice->phyDevice, display, &mode_count, NULL);
assert(!err);

if (mode_count == 0) {
printf("Cannot find any mode for the display!\n");
fflush(stdout);
exit(1);
}

mode_count = 1;
err = vkGetDisplayModePropertiesKHR(phyDevice->phyDevice, display, &mode_count, &mode_props);
assert(!err || (err == VK_INCOMPLETE));

// Get the list of planes
err = vkGetPhysicalDeviceDisplayPlanePropertiesKHR(phyDevice->phyDevice, &plane_count, NULL);
assert(!err);

if (plane_count == 0) {
printf("Cannot find any plane!\n");
fflush(stdout);
exit(1);
}

plane_props = malloc(sizeof(VkDisplayPlanePropertiesKHR) * plane_count);
assert(plane_props);

err = vkGetPhysicalDeviceDisplayPlanePropertiesKHR(phyDevice->phyDevice,
&plane_count,
plane_props);
assert(!err);

// Find a plane compatible with the display
for (plane_index = 0; plane_index < plane_count; plane_index++) {
uint32_t supported_count;
VkDisplayKHR *supported_displays;

// Disqualify planes that are bound to a different display
if ((plane_props[plane_index].currentDisplay != VK_NULL_HANDLE)
&& (plane_props[plane_index].currentDisplay != display)) {
continue;
}

err = vkGetDisplayPlaneSupportedDisplaysKHR(phyDevice->phyDevice,
plane_index,
&supported_count,
NULL);
assert(!err);

if (supported_count == 0) {
continue;
}

supported_displays = malloc(sizeof(VkDisplayKHR) * supported_count);
assert(supported_displays);

err = vkGetDisplayPlaneSupportedDisplaysKHR(phyDevice->phyDevice,
plane_index,
&supported_count,
supported_displays);
assert(!err);

for (uint32_t i = 0; i < supported_count; i++) {
if (supported_displays[i] == display) {
found_plane = VK_TRUE;
break;
}
}

free(supported_displays);

if (found_plane) {
break;
}
}

if (!found_plane) {
printf("Cannot find a plane compatible with the display!\n");
fflush(stdout);
exit(1);
}

free(plane_props);

VkDisplayPlaneCapabilitiesKHR planeCaps;
vkGetDisplayPlaneCapabilitiesKHR(phyDevice->phyDevice,
mode_props.displayMode,
plane_index,
&planeCaps);
// Find a supported alpha mode
VkDisplayPlaneAlphaFlagBitsKHR alphaMode = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR;
VkDisplayPlaneAlphaFlagBitsKHR alphaModes[4] = {
VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR,
VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR,
VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR,
VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR,
};

for (uint32_t i = 0; i < sizeof(alphaModes); i++) {
if (planeCaps.supportedAlpha & alphaModes[i]) {
alphaMode = alphaModes[i];
break;
}
}

image_extent.width = mode_props.parameters.visibleRegion.width;
image_extent.height = mode_props.parameters.visibleRegion.height;

surfaceCI.sType = VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR;
surfaceCI.pNext = NULL;
surfaceCI.flags = 0;
surfaceCI.displayMode = mode_props.displayMode;
surfaceCI.planeIndex = plane_index;
surfaceCI.planeStackIndex = plane_props[plane_index].currentStackIndex;
surfaceCI.transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
surfaceCI.alphaMode = alphaMode;
surfaceCI.globalAlpha = 1.0f;
surfaceCI.imageExtent = image_extent;

return vkCreateDisplayPlaneSurfaceKHR(inst->inst, &surfaceCI, NULL, &surface->surface);
}
#endif

GPU_HIDE
GPUSurface*
vk_createSurface(struct GPUApi * __restrict api,
struct GPUInstance * __restrict inst,
void * __restrict nativeHandle,
GPUSurfaceType type,
float scale) {
vk_createSurface(GPUApi * __restrict api,
GPUInstance * __restrict inst,
GPUPhysicalDevice * __restrict phyDevice,
void * __restrict nativeHandle,
GPUSurfaceType type,
float scale) {
GPUInstanceVk *instVk;
GPUPhysicalDeviceVk *phyDeviceVk;
GPUSurface *gpuSurface;
GPUSurfaceVk *surface;
VkResult U_ASSERT_ONLY err;

instVk = inst->_priv;
phyDeviceVk = phyDevice->priv;
gpuSurface = calloc(1, sizeof(*gpuSurface));
gpuSurface->type = type;
gpuSurface->scale = scale;
Expand Down Expand Up @@ -91,7 +244,7 @@ vk_createSurface(struct GPUApi * __restrict api,

err = vkCreateDirectFBSurfaceEXT(instVk->inst, &createInfo, NULL, &surface->surface);
#elif defined(VK_USE_PLATFORM_DISPLAY_KHR)
err = demo_create_display_surface(demo);
err = vk_createDisplaySurface(instVk, phyDeviceVk, surface->surface);
#elif defined(VK_USE_PLATFORM_METAL_EXT)
VkMetalSurfaceCreateInfoEXT createInfo = {0};
createInfo.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT;
Expand Down

0 comments on commit 50648e8

Please sign in to comment.