vulkan.go 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. package glfw
  2. /*
  3. #include "glfw/src/internal.h"
  4. GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
  5. GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* procname);
  6. // Helper function for doing raw pointer arithmetic
  7. static inline const char* getArrayIndex(const char** array, unsigned int index) {
  8. return array[index];
  9. }
  10. void* getVulkanProcAddr() {
  11. return glfwGetInstanceProcAddress;
  12. }
  13. */
  14. import "C"
  15. import (
  16. "errors"
  17. "fmt"
  18. "reflect"
  19. "unsafe"
  20. )
  21. // VulkanSupported reports whether the Vulkan loader has been found. This check is performed by Init.
  22. //
  23. // The availability of a Vulkan loader does not by itself guarantee that window surface creation or
  24. // even device creation is possible. Call GetRequiredInstanceExtensions to check whether the
  25. // extensions necessary for Vulkan surface creation are available and GetPhysicalDevicePresentationSupport
  26. // to check whether a queue family of a physical device supports image presentation.
  27. func VulkanSupported() bool {
  28. return glfwbool(C.glfwVulkanSupported())
  29. }
  30. // GetVulkanGetInstanceProcAddress returns the function pointer used to find Vulkan core or
  31. // extension functions. The return value of this function can be passed to the Vulkan library.
  32. //
  33. // Note that this function does not work the same way as the glfwGetInstanceProcAddress.
  34. func GetVulkanGetInstanceProcAddress() unsafe.Pointer {
  35. return C.getVulkanProcAddr()
  36. }
  37. // GetRequiredInstanceExtensions returns a slice of Vulkan instance extension names required
  38. // by GLFW for creating Vulkan surfaces for GLFW windows. If successful, the list will always
  39. // contain VK_KHR_surface, so if you don't require any additional extensions you can pass this list
  40. // directly to the VkInstanceCreateInfo struct.
  41. //
  42. // If Vulkan is not available on the machine, this function returns nil. Call
  43. // VulkanSupported to check whether Vulkan is available.
  44. //
  45. // If Vulkan is available but no set of extensions allowing window surface creation was found, this
  46. // function returns nil. You may still use Vulkan for off-screen rendering and compute work.
  47. func (window *Window) GetRequiredInstanceExtensions() []string {
  48. var count C.uint32_t
  49. strarr := C.glfwGetRequiredInstanceExtensions(&count)
  50. if count == 0 {
  51. return nil
  52. }
  53. extensions := make([]string, count)
  54. for i := uint(0); i < uint(count); i++ {
  55. extensions[i] = C.GoString(C.getArrayIndex(strarr, C.uint(i)))
  56. }
  57. return extensions
  58. }
  59. // CreateWindowSurface creates a Vulkan surface for this window.
  60. func (window *Window) CreateWindowSurface(instance interface{}, allocCallbacks unsafe.Pointer) (surface uintptr, err error) {
  61. if instance == nil {
  62. return 0, errors.New("vulkan: instance is nil")
  63. }
  64. val := reflect.ValueOf(instance)
  65. if val.Kind() != reflect.Ptr {
  66. return 0, fmt.Errorf("vulkan: instance is not a VkInstance (expected kind Ptr, got %s)", val.Kind())
  67. }
  68. var vulkanSurface C.VkSurfaceKHR
  69. ret := C.glfwCreateWindowSurface(
  70. (C.VkInstance)(unsafe.Pointer(reflect.ValueOf(instance).Pointer())), window.data,
  71. (*C.VkAllocationCallbacks)(allocCallbacks), (*C.VkSurfaceKHR)(unsafe.Pointer(&vulkanSurface)))
  72. if ret != C.VK_SUCCESS {
  73. return 0, fmt.Errorf("vulkan: error creating window surface: %d", ret)
  74. }
  75. return uintptr(unsafe.Pointer(&vulkanSurface)), nil
  76. }