Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added missing functions for compatibility with Vulkan #273

Merged
merged 13 commits into from
Apr 19, 2020
74 changes: 72 additions & 2 deletions v3.3/glfw/vulkan.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,27 @@
package glfw

//#define GLFW_INCLUDE_NONE
//#include "glfw/include/GLFW/glfw3.h"
/*
#include "glfw/include/GLFW/glfw3.h"
#include "glfw/src/internal.h"

GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* procname);

// Helper function for doing raw pointer arithmetic
static inline const char* getArrayIndex(const char** array, unsigned int index) {
return array[index];
}

void* getVulkanProcAddr() {
return glfwGetInstanceProcAddress;
}
*/
import "C"
import (
"errors"
"reflect"
"unsafe"
)

// VulkanSupported reports whether the Vulkan loader has been found. This check is performed by Init.
//
Expand All @@ -13,3 +32,54 @@ import "C"
func VulkanSupported() bool {
return glfwbool(C.glfwVulkanSupported())
}

// GetVulkanGetInstanceProcAddress returns the function pointer used to find Vulkan core or
// extension functions. The return value of this function can be passed to the Vulkan library.
//
// Note that this function does not work the same way as the glfwGetInstanceProcAddress.
func GetVulkanGetInstanceProcAddress() unsafe.Pointer {
return C.getVulkanProcAddr()
}

// GetRequiredInstanceExtensions returns a slice of Vulkan instance extension names required
// by GLFW for creating Vulkan surfaces for GLFW windows. If successful, the list will always
// contain VK_KHR_surface, so if you don't require any additional extensions you can pass this list
// directly to the VkInstanceCreateInfo struct.
//
// If Vulkan is not available on the machine, this function returns nil. Call
// VulkanSupported to check whether Vulkan is available.
//
// If Vulkan is available but no set of extensions allowing window surface creation was found, this
// function returns nil. You may still use Vulkan for off-screen rendering and compute work.
func (window *Window) GetRequiredInstanceExtensions() []string {
var count C.uint32_t
strarr := C.glfwGetRequiredInstanceExtensions(&count)
if count == 0 {
return nil
}

extensions := make([]string, count)
for i := uint(0); i < uint(count); i++ {
extensions[i] = C.GoString(C.getArrayIndex(strarr, C.uint(i)))
}
return extensions
}

// CreateWindowSurface creates a Vulkan surface for this window.
func (window *Window) CreateWindowSurface(instance interface{}, allocCallbacks unsafe.Pointer) (surface uintptr, err error) {
if instance == nil {
return 0, errors.New("vulkan: instance is nil")
}
val := reflect.ValueOf(instance)
if val.Kind() != reflect.Ptr {
return 0, errors.New("vulkan: instance is not a VkInstance (expected kind Ptr, got " + val.Kind().String() + ")")
}
var vulkanSurface C.VkSurfaceKHR
ret := C.glfwCreateWindowSurface(
(C.VkInstance)(unsafe.Pointer(reflect.ValueOf(instance).Pointer())), window.data,
(*C.VkAllocationCallbacks)(allocCallbacks), (*C.VkSurfaceKHR)(unsafe.Pointer(&vulkanSurface)))
if ret != C.VK_SUCCESS {
return 0, errors.New("vulkan: error creating window surface")
pwaller marked this conversation as resolved.
Show resolved Hide resolved
}
return uintptr(unsafe.Pointer(&vulkanSurface)), nil
}