mirror of
https://github.com/Kugelschieber/vk-experiments.git
synced 2026-01-18 06:40:27 +00:00
Vulkan device and graphics queue.
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"github.com/go-gl/glfw/v3.3/glfw"
|
"github.com/go-gl/glfw/v3.3/glfw"
|
||||||
vk "github.com/vulkan-go/vulkan"
|
vk "github.com/vulkan-go/vulkan"
|
||||||
"log"
|
"log"
|
||||||
@@ -9,6 +10,9 @@ import (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
vkInstance vk.Instance
|
vkInstance vk.Instance
|
||||||
|
vkPhysicalDevice vk.PhysicalDevice
|
||||||
|
vkDevice vk.Device
|
||||||
|
vkQueue vk.Queue
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -36,24 +40,114 @@ func createWindow(title string, width, height int) (*glfw.Window, error) {
|
|||||||
return window, nil
|
return window, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func initVk() error {
|
func destroyWindow(window *glfw.Window) {
|
||||||
|
window.Destroy()
|
||||||
|
glfw.Terminate()
|
||||||
|
}
|
||||||
|
|
||||||
|
func initVk(window *glfw.Window) error {
|
||||||
vk.SetGetInstanceProcAddr(glfw.GetVulkanGetInstanceProcAddress())
|
vk.SetGetInstanceProcAddr(glfw.GetVulkanGetInstanceProcAddress())
|
||||||
|
|
||||||
if err := vk.Init(); err != nil {
|
if err := vk.Init(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create Vulkan instance
|
||||||
|
extensions := window.GetRequiredInstanceExtensions()
|
||||||
|
result := vk.CreateInstance(&vk.InstanceCreateInfo{
|
||||||
|
SType: vk.StructureTypeInstanceCreateInfo,
|
||||||
|
PApplicationInfo: &vk.ApplicationInfo{
|
||||||
|
SType: vk.StructureTypeApplicationInfo,
|
||||||
|
PApplicationName: "01 Simple Sprite",
|
||||||
|
ApiVersion: vk.ApiVersion11,
|
||||||
|
},
|
||||||
|
EnabledExtensionCount: uint32(len(extensions)),
|
||||||
|
PpEnabledExtensionNames: extensions,
|
||||||
|
}, nil, &vkInstance)
|
||||||
|
|
||||||
|
if result != vk.Success {
|
||||||
|
return errors.New("error creating Vulkan instance")
|
||||||
|
}
|
||||||
|
|
||||||
|
// select the first device with Vulkan support
|
||||||
|
var deviceCount uint32
|
||||||
|
|
||||||
|
if result := vk.EnumeratePhysicalDevices(vkInstance, &deviceCount, nil); result != vk.Success {
|
||||||
|
return errors.New("error counting Vulkan devices")
|
||||||
|
}
|
||||||
|
|
||||||
|
if deviceCount == 0 {
|
||||||
|
return errors.New("no device with Vulkan support found")
|
||||||
|
}
|
||||||
|
|
||||||
|
var devices []vk.PhysicalDevice
|
||||||
|
|
||||||
|
if result := vk.EnumeratePhysicalDevices(vkInstance, &deviceCount, devices); result != vk.Success {
|
||||||
|
return errors.New("error listing Vulkan devices")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, d := range devices {
|
||||||
|
//var properties []vk.DisplayProperties
|
||||||
|
//vk.GetPhysicalDeviceDisplayProperties(d, nil, properties)
|
||||||
|
vkPhysicalDevice = d
|
||||||
|
break // TODO check suitability
|
||||||
|
}
|
||||||
|
|
||||||
|
if vkPhysicalDevice == nil {
|
||||||
|
return errors.New("no suitable Vulkan device found")
|
||||||
|
}
|
||||||
|
|
||||||
|
// find a graphics queue
|
||||||
|
var queueCount uint32
|
||||||
|
var queueProperties []vk.QueueFamilyProperties
|
||||||
|
vk.GetPhysicalDeviceQueueFamilyProperties(vkPhysicalDevice, &queueCount, nil)
|
||||||
|
vk.GetPhysicalDeviceQueueFamilyProperties(vkPhysicalDevice, &queueCount, queueProperties)
|
||||||
|
var queueIndex uint32
|
||||||
|
queueFound := false
|
||||||
|
|
||||||
|
for i, q := range queueProperties {
|
||||||
|
if vk.QueueFlagBits(q.QueueFlags)&vk.QueueGraphicsBit == 1 {
|
||||||
|
queueIndex = uint32(i)
|
||||||
|
queueFound = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !queueFound {
|
||||||
|
return errors.New("no Vulkan graphics bit queue found")
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a logical device and get queue
|
||||||
|
queues := []vk.DeviceQueueCreateInfo{
|
||||||
|
{
|
||||||
|
SType: vk.StructureTypeDeviceQueueCreateInfo,
|
||||||
|
QueueFamilyIndex: queueIndex,
|
||||||
|
QueueCount: 1,
|
||||||
|
PQueuePriorities: []float32{1},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
result = vk.CreateDevice(vkPhysicalDevice, &vk.DeviceCreateInfo{
|
||||||
|
SType: vk.StructureTypeDeviceCreateInfo,
|
||||||
|
QueueCreateInfoCount: 1,
|
||||||
|
PQueueCreateInfos: queues,
|
||||||
|
}, nil, &vkDevice)
|
||||||
|
|
||||||
|
if result != vk.Success {
|
||||||
|
return errors.New("error creating logical Vulkan device")
|
||||||
|
}
|
||||||
|
|
||||||
|
vk.GetDeviceQueue(vkDevice, queueIndex, 0, &vkQueue)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func load() {
|
func cleanupVk() {
|
||||||
vk.CreateInstance(&vk.InstanceCreateInfo{
|
vk.DestroyDevice(vkDevice, nil)
|
||||||
EnabledLayerCount: 0,
|
vk.DestroyInstance(vkInstance, nil)
|
||||||
}, nil, &vkInstance)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func cleanup() {
|
func load() {
|
||||||
vk.DestroyInstance(vkInstance, nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func loop(window *glfw.Window) {
|
func loop(window *glfw.Window) {
|
||||||
@@ -71,13 +165,13 @@ func main() {
|
|||||||
log.Fatalf("error creating window: %s", err)
|
log.Fatalf("error creating window: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer glfw.Terminate()
|
defer destroyWindow(window)
|
||||||
|
|
||||||
if err := initVk(); err != nil {
|
if err := initVk(window); err != nil {
|
||||||
log.Fatalf("error initializing Vulkan: %s", err)
|
log.Fatalf("error initializing Vulkan: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defer cleanupVk()
|
||||||
load()
|
load()
|
||||||
defer cleanup()
|
|
||||||
loop(window)
|
loop(window)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user