mirror of
https://github.com/Kugelschieber/vk-experiments.git
synced 2026-01-18 06:40:27 +00:00
Started adding swap chain and fixing bugs...
This commit is contained in:
@@ -12,7 +12,12 @@ var (
|
||||
vkInstance vk.Instance
|
||||
vkPhysicalDevice vk.PhysicalDevice
|
||||
vkDevice vk.Device
|
||||
vkQueue vk.Queue
|
||||
vkGraphicsQueue vk.Queue
|
||||
vkPresentQueue vk.Queue
|
||||
vkSurface vk.Surface
|
||||
vkSwapchain vk.Swapchain
|
||||
vkSwapchainImages []vk.Image
|
||||
vkSwapchainImageViews []vk.ImageView
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -24,6 +29,10 @@ func createWindow(title string, width, height int) (*glfw.Window, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !glfw.VulkanSupported() {
|
||||
return nil, errors.New("missing required Vulkan support")
|
||||
}
|
||||
|
||||
window, err := glfw.CreateWindow(width, height, title, nil, nil)
|
||||
|
||||
if err != nil {
|
||||
@@ -31,12 +40,6 @@ func createWindow(title string, width, height int) (*glfw.Window, error) {
|
||||
}
|
||||
|
||||
window.MakeContextCurrent()
|
||||
|
||||
for !window.ShouldClose() {
|
||||
window.SwapBuffers()
|
||||
glfw.PollEvents()
|
||||
}
|
||||
|
||||
return window, nil
|
||||
}
|
||||
|
||||
@@ -45,7 +48,8 @@ func destroyWindow(window *glfw.Window) {
|
||||
glfw.Terminate()
|
||||
}
|
||||
|
||||
func initVk(window *glfw.Window) error {
|
||||
func initVk(window *glfw.Window, width, height uint32) error {
|
||||
log.Println("Initializing Vulkan...")
|
||||
vk.SetGetInstanceProcAddr(glfw.GetVulkanGetInstanceProcAddress())
|
||||
|
||||
if err := vk.Init(); err != nil {
|
||||
@@ -69,6 +73,15 @@ func initVk(window *glfw.Window) error {
|
||||
return errors.New("error creating Vulkan instance")
|
||||
}
|
||||
|
||||
// create surface
|
||||
surface, err := window.CreateWindowSurface(vkInstance, nil)
|
||||
|
||||
if err != nil {
|
||||
return errors.New("error creating Vulkan surface")
|
||||
}
|
||||
|
||||
vkSurface = vk.SurfaceFromPointer(surface)
|
||||
|
||||
// select the first device with Vulkan support
|
||||
var deviceCount uint32
|
||||
|
||||
@@ -80,17 +93,16 @@ func initVk(window *glfw.Window) error {
|
||||
return errors.New("no device with Vulkan support found")
|
||||
}
|
||||
|
||||
var devices []vk.PhysicalDevice
|
||||
devices := make([]vk.PhysicalDevice, 1)
|
||||
|
||||
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)
|
||||
// TODO check suitability
|
||||
vkPhysicalDevice = d
|
||||
break // TODO check suitability
|
||||
break
|
||||
}
|
||||
|
||||
if vkPhysicalDevice == nil {
|
||||
@@ -99,29 +111,50 @@ func initVk(window *glfw.Window) error {
|
||||
|
||||
// find a graphics queue
|
||||
var queueCount uint32
|
||||
var queueProperties []vk.QueueFamilyProperties
|
||||
vk.GetPhysicalDeviceQueueFamilyProperties(vkPhysicalDevice, &queueCount, nil)
|
||||
queueProperties := make([]vk.QueueFamilyProperties, queueCount)
|
||||
vk.GetPhysicalDeviceQueueFamilyProperties(vkPhysicalDevice, &queueCount, queueProperties)
|
||||
var queueIndex uint32
|
||||
queueFound := false
|
||||
var graphicsQueueIndex, presentQueueIndex uint32
|
||||
foundGraphicsQueue, foundPresentQueue := false, false
|
||||
|
||||
for i, q := range queueProperties {
|
||||
if vk.QueueFlagBits(q.QueueFlags)&vk.QueueGraphicsBit == 1 {
|
||||
queueIndex = uint32(i)
|
||||
queueFound = true
|
||||
if !foundGraphicsQueue && vk.QueueFlagBits(q.QueueFlags)&vk.QueueGraphicsBit == 1 {
|
||||
graphicsQueueIndex = uint32(i)
|
||||
foundGraphicsQueue = true
|
||||
|
||||
if foundPresentQueue {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !queueFound {
|
||||
return errors.New("no Vulkan graphics bit queue found")
|
||||
if !foundPresentQueue {
|
||||
var presentSupport vk.Bool32
|
||||
vk.GetPhysicalDeviceSurfaceSupport(vkPhysicalDevice, uint32(i), vkSurface, &presentSupport)
|
||||
|
||||
if presentSupport == 1 {
|
||||
presentQueueIndex = uint32(i)
|
||||
foundPresentQueue = true
|
||||
|
||||
if foundGraphicsQueue {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create a logical device and get queue
|
||||
if !foundGraphicsQueue {
|
||||
return errors.New("no Vulkan graphics queue found")
|
||||
}
|
||||
|
||||
if !foundPresentQueue {
|
||||
return errors.New("no Vulkan present queue found")
|
||||
}
|
||||
|
||||
// create a logical device and queues
|
||||
queues := []vk.DeviceQueueCreateInfo{
|
||||
{
|
||||
SType: vk.StructureTypeDeviceQueueCreateInfo,
|
||||
QueueFamilyIndex: queueIndex,
|
||||
QueueFamilyIndex: graphicsQueueIndex,
|
||||
QueueCount: 1,
|
||||
PQueuePriorities: []float32{1},
|
||||
},
|
||||
@@ -131,17 +164,101 @@ func initVk(window *glfw.Window) error {
|
||||
SType: vk.StructureTypeDeviceCreateInfo,
|
||||
QueueCreateInfoCount: 1,
|
||||
PQueueCreateInfos: queues,
|
||||
EnabledExtensionCount: 1,
|
||||
PpEnabledExtensionNames: []string{
|
||||
vk.KhrDisplaySwapchainExtensionName,
|
||||
},
|
||||
}, nil, &vkDevice)
|
||||
|
||||
if result != vk.Success {
|
||||
return errors.New("error creating logical Vulkan device")
|
||||
}
|
||||
|
||||
vk.GetDeviceQueue(vkDevice, queueIndex, 0, &vkQueue)
|
||||
vk.GetDeviceQueue(vkDevice, graphicsQueueIndex, 0, &vkGraphicsQueue)
|
||||
vk.GetDeviceQueue(vkDevice, presentQueueIndex, 0, &vkPresentQueue)
|
||||
|
||||
// create swap chain (screen buffer) and get the images
|
||||
sharingMode := vk.SharingModeExclusive
|
||||
queueFamilyIndexCount := 0
|
||||
var queueFamilyIndices []uint32
|
||||
|
||||
if graphicsQueueIndex != presentQueueIndex {
|
||||
sharingMode = vk.SharingModeConcurrent
|
||||
queueFamilyIndexCount = 2
|
||||
queueFamilyIndices = []uint32{graphicsQueueIndex, presentQueueIndex}
|
||||
}
|
||||
|
||||
result = vk.CreateSwapchain(vkDevice, &vk.SwapchainCreateInfo{
|
||||
SType: vk.StructureTypeSwapchainCreateInfo,
|
||||
Surface: vkSurface,
|
||||
MinImageCount: uint32(3),
|
||||
ImageFormat: vk.FormatB8g8r8a8Uint,
|
||||
ImageColorSpace: vk.ColorspaceSrgbNonlinear,
|
||||
ImageExtent: vk.Extent2D{Width: width, Height: height},
|
||||
ImageArrayLayers: 1,
|
||||
ImageUsage: vk.ImageUsageFlags(vk.ImageUsageColorAttachmentBit),
|
||||
ImageSharingMode: sharingMode,
|
||||
QueueFamilyIndexCount: uint32(queueFamilyIndexCount),
|
||||
PQueueFamilyIndices: queueFamilyIndices,
|
||||
//PreTransform
|
||||
CompositeAlpha: vk.CompositeAlphaOpaqueBit,
|
||||
PresentMode: vk.PresentModeMailbox,
|
||||
Clipped: vk.True,
|
||||
OldSwapchain: vk.NullSwapchain,
|
||||
}, nil, &vkSwapchain)
|
||||
|
||||
if result != vk.Success {
|
||||
return errors.New("error creating Vulkan swap chain")
|
||||
}
|
||||
|
||||
var imgCount uint32
|
||||
vk.GetSwapchainImages(vkDevice, vkSwapchain, &imgCount, nil)
|
||||
result = vk.GetSwapchainImages(vkDevice, vkSwapchain, &imgCount, vkSwapchainImages)
|
||||
|
||||
if result != vk.Success {
|
||||
return errors.New("error getting Vulkan swap chain images")
|
||||
}
|
||||
|
||||
// create image views for the swap chain images
|
||||
vkSwapchainImageViews = make([]vk.ImageView, 0, imgCount)
|
||||
|
||||
for i, img := range vkSwapchainImages {
|
||||
result = vk.CreateImageView(vkDevice, &vk.ImageViewCreateInfo{
|
||||
SType: vk.StructureTypeImageViewCreateInfo,
|
||||
Image: img,
|
||||
ViewType: vk.ImageViewType2d,
|
||||
Format: vk.FormatB8g8r8a8Uint,
|
||||
Components: vk.ComponentMapping{
|
||||
R: vk.ComponentSwizzleR,
|
||||
G: vk.ComponentSwizzleG,
|
||||
B: vk.ComponentSwizzleB,
|
||||
A: vk.ComponentSwizzleA,
|
||||
},
|
||||
SubresourceRange: vk.ImageSubresourceRange{
|
||||
AspectMask: vk.ImageAspectFlags(vk.ImageAspectColorBit),
|
||||
BaseMipLevel: uint32(0),
|
||||
LevelCount: uint32(1),
|
||||
BaseArrayLayer: uint32(0),
|
||||
LayerCount: uint32(1),
|
||||
},
|
||||
}, nil, &vkSwapchainImageViews[i])
|
||||
|
||||
if result != vk.Success {
|
||||
return errors.New("error creating swap chain image view")
|
||||
}
|
||||
}
|
||||
|
||||
log.Println("Done initializing Vulkan...")
|
||||
return nil
|
||||
}
|
||||
|
||||
func cleanupVk() {
|
||||
for _, img := range vkSwapchainImageViews {
|
||||
vk.DestroyImageView(vkDevice, img, nil)
|
||||
}
|
||||
|
||||
vk.DestroySwapchain(vkDevice, vkSwapchain, nil)
|
||||
vk.DestroySurface(vkInstance, vkSurface, nil)
|
||||
vk.DestroyDevice(vkDevice, nil)
|
||||
vk.DestroyInstance(vkInstance, nil)
|
||||
}
|
||||
@@ -167,7 +284,7 @@ func main() {
|
||||
|
||||
defer destroyWindow(window)
|
||||
|
||||
if err := initVk(window); err != nil {
|
||||
if err := initVk(window, 640, 480); err != nil {
|
||||
log.Fatalf("error initializing Vulkan: %s", err)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user