From fa1556516f502fa8909d2f31106a4f02874576ab Mon Sep 17 00:00:00 2001 From: s-ol Date: Sat, 22 Jun 2024 20:52:02 +0200 Subject: [PATCH] display: use GLFW when ::isLaptop is set (not just on mac) --- virtual-programs/display.folk | 73 +++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 30 deletions(-) diff --git a/virtual-programs/display.folk b/virtual-programs/display.folk index 1b4dbbd4..758fd614 100644 --- a/virtual-programs/display.folk +++ b/virtual-programs/display.folk @@ -4,10 +4,11 @@ # to run pixel shaders with image and numerical parameters (so you # can draw images, shapes, etc from Display.) +set ::isLaptop 1 set makeGpu { set macos [expr {$tcl_platform(os) eq "Darwin"}] - if {!$macos} { + if {!$::isLaptop} { foreach renderFile [glob -nocomplain "/dev/dri/render*"] { if {![file readable $renderFile]} { puts stderr "Gpu: Warning: $renderFile is not readable by current user; Vulkan device may not appear. @@ -70,6 +71,8 @@ Try doing `sudo adduser folk render`." dc include if {$macos} { dc cflags -I/opt/homebrew/include -L/opt/homebrew/lib + } + if {$::isLaptop} { dc include dc cflags -lglfw } @@ -112,7 +115,7 @@ Try doing `sudo adduser folk render`." } dc proc init {int displayIdx} void [csubst { $[vktry volkInitialize()] - $[if {$macos} { expr {"glfwInit();"} }] + $[if {$::isLaptop} { expr {"glfwInit();"} }] // Set up VkInstance instance: { @@ -125,22 +128,30 @@ Try doing `sudo adduser folk render`." createInfo.enabledLayerCount = sizeof(validationLayers)/sizeof(validationLayers[0]); createInfo.ppEnabledLayerNames = validationLayers; - const char* enabledExtensions[] = $[expr { $macos ? {{ - VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, - VK_KHR_SURFACE_EXTENSION_NAME, - "VK_EXT_metal_surface", + uint32_t enabledExtensionCount = 1; + const char* enabledExtensions[10] = { VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, - }} : {{ - // 2 extensions for non-X11/Wayland display - VK_KHR_SURFACE_EXTENSION_NAME, - VK_KHR_DISPLAY_EXTENSION_NAME, - VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, - }} }]; - createInfo.enabledExtensionCount = sizeof(enabledExtensions)/sizeof(enabledExtensions[0]); - createInfo.ppEnabledExtensionNames = enabledExtensions; + }; + $[if {$macos} { expr {{ + enabledExtensions[enabledExtensionCount++] = VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME; createInfo.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR; }} }] + $[if {$::isLaptop} { expr {{ + uint32_t extCount; + const char** extensions = glfwGetRequiredInstanceExtensions(&extCount); + + while (extCount > 0) { + enabledExtensions[enabledExtensionCount++] = extensions[--extCount]; + } + }} } else { expr {{ + enabledExtensions[enabledExtensionCount++] = VK_KHR_SURFACE_EXTENSION_NAME; + enabledExtensions[enabledExtensionCount++] = VK_KHR_DISPLAY_EXTENSION_NAME; + }} }] + + createInfo.ppEnabledExtensionNames = enabledExtensions; + createInfo.enabledExtensionCount = enabledExtensionCount; + VkResult res = vkCreateInstance(&createInfo, NULL, &instance); if (res != VK_SUCCESS) { fprintf(stderr, "Failed vkCreateInstance: %s (%d)\n", @@ -202,14 +213,13 @@ Try doing `sudo adduser folk render`." VkPhysicalDeviceFeatures deviceFeatures = {0}; - const char *deviceExtensions[] = $[expr { $macos ? {{ + const char *deviceExtensions[] = { VK_KHR_SWAPCHAIN_EXTENSION_NAME, + VK_KHR_MAINTENANCE3_EXTENSION_NAME, + $[expr { $macos ? { "VK_KHR_portability_subset", - VK_KHR_MAINTENANCE3_EXTENSION_NAME - }} : {{ - VK_KHR_SWAPCHAIN_EXTENSION_NAME, - VK_KHR_MAINTENANCE3_EXTENSION_NAME - }} }]; + } : {} }] + }; VkDeviceCreateInfo createInfo = {0}; createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; @@ -236,14 +246,14 @@ Try doing `sudo adduser folk render`." // Get drawing surface. VkSurfaceKHR surface; - $[expr { $macos ? { + $[expr { $::isLaptop ? [csubst { GLFWwindow* window; glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); - window = glfwCreateWindow(640, 480, "Window Title", NULL, NULL); + window = glfwCreateWindow($WIDTH, $HEIGHT, "Window Title", NULL, NULL); if (glfwCreateWindowSurface(instance, window, NULL, &surface) != VK_SUCCESS) { fprintf(stderr, "Gpu: Failed to create GLFW window surface\n"); exit(1); } - } : [csubst { + }] : [csubst { // TODO: support multiple displays, pick best display mode uint32_t displayCount; @@ -291,7 +301,7 @@ Try doing `sudo adduser folk render`." if (capabilities.currentExtent.width != UINT32_MAX) { extent = capabilities.currentExtent; } else { - $[expr { $macos ? { + $[expr { $::isLaptop ? { glfwGetFramebufferSize(window, (int*) &extent.width, (int*) &extent.height); if (capabilities.minImageExtent.width > extent.width) { extent.width = capabilities.minImageExtent.width; } if (capabilities.maxImageExtent.width < extent.width) { extent.width = capabilities.maxImageExtent.width; } @@ -808,12 +818,12 @@ Try doing `sudo adduser folk render`." presentInfo.pImageIndices = &imageIndex; presentInfo.pResults = NULL; - vkQueuePresentKHR(presentQueue, &presentInfo); + $[vktry {vkQueuePresentKHR(presentQueue, &presentInfo)}] } } dc proc poll {} void { - $[expr { $macos ? { glfwPollEvents(); } : {} }] + $[expr { $::isLaptop ? { glfwPollEvents(); } : {} }] } # Construct a reusable GLSL function that can be linked into and @@ -1554,7 +1564,7 @@ Try doing `sudo adduser folk render`." source "lib/colors.tcl" proc Start-display-process {code} { - if {$::tcl_platform(os) eq "Darwin"} { + if {$::isLaptop} { # On macOS, you must talk to the GPU on the main thread, so we # don't Start a subprocess here. We trampoline this code into # a claim so we can run the rest of display.folk before @@ -1574,6 +1584,7 @@ proc Start-display-process {code} { Start-display-process { puts "Display pid: [pid]" set macos [expr {$::tcl_platform(os) eq "Darwin"}] + set ::isLaptop 1 source "virtual-programs/images.folk" namespace eval Gpu $makeGpu @@ -1646,7 +1657,9 @@ Start-display-process { while true { set ::displayList [dict create] ;# Keys are layer numbers; values are lists of commands Step - if {$macos} { update } + if {$::isLaptop} { + update + } foreach match [Statements::findMatches {/wisher/ wishes the GPU draws pipeline /name/ with /...options/}] { try { @@ -1682,7 +1695,7 @@ Start-display-process { } Gpu::drawEnd }] - if {$macos} { Gpu::poll } + if {$::isLaptop} { Gpu::poll } Commit { Claim the display time is "render $renderTime us ($::stepTime)" } } @@ -1700,7 +1713,7 @@ namespace eval ::Display { variable WIDTH variable HEIGHT variable LAYER 0 - if {$::tcl_platform(os) eq "Darwin"} { + if {$::isLaptop} { set WIDTH [* 640 2]; set HEIGHT [* 480 2] } else { regexp {mode "(\d+)x(\d+)(?:-\d+)?"} [exec fbset] -> WIDTH HEIGHT