201 lines
5.3 KiB
Go
201 lines
5.3 KiB
Go
|
|
package instance
|
||
|
|
|
||
|
|
import (
|
||
|
|
"github.com/pkg/errors"
|
||
|
|
"github.com/vkngwrapper/core/v2/core1_0"
|
||
|
|
"github.com/vkngwrapper/extensions/v2/khr_portability_subset"
|
||
|
|
"github.com/vkngwrapper/extensions/v2/khr_surface"
|
||
|
|
"github.com/vkngwrapper/extensions/v2/khr_swapchain"
|
||
|
|
vkng_sdl2 "github.com/vkngwrapper/integrations/sdl2/v2"
|
||
|
|
)
|
||
|
|
|
||
|
|
func (e *FInstance) createSurface() error {
|
||
|
|
surfaceLoader := khr_surface.CreateExtensionFromInstance(e.ptr)
|
||
|
|
|
||
|
|
surface, err := vkng_sdl2.CreateSurface(e.ptr, surfaceLoader, e.win.GetInstance())
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
e.surface = surface
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
func (e *FInstance) pickPhysicalDevice() error {
|
||
|
|
physicalDevices, _, err := e.ptr.EnumeratePhysicalDevices()
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
for _, device := range physicalDevices {
|
||
|
|
if help.isDeviceSuitable(device) {
|
||
|
|
e.physicalDevice = device
|
||
|
|
break
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if e.physicalDevice == nil {
|
||
|
|
return errors.New("failed to find a suitable GPU!")
|
||
|
|
}
|
||
|
|
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
func (e *FInstance) createLogicalDevice() error {
|
||
|
|
indices, err := help.findQueueFamilies(e.physicalDevice)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
uniqueQueueFamilies := []int{*indices.GraphicsFamily}
|
||
|
|
if uniqueQueueFamilies[0] != *indices.PresentFamily {
|
||
|
|
uniqueQueueFamilies = append(uniqueQueueFamilies, *indices.PresentFamily)
|
||
|
|
}
|
||
|
|
|
||
|
|
var queueFamilyOptions []core1_0.DeviceQueueCreateInfo
|
||
|
|
queuePriority := float32(1.0)
|
||
|
|
for _, queueFamily := range uniqueQueueFamilies {
|
||
|
|
queueFamilyOptions = append(queueFamilyOptions, core1_0.DeviceQueueCreateInfo{
|
||
|
|
QueueFamilyIndex: queueFamily,
|
||
|
|
QueuePriorities: []float32{queuePriority},
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
var extensionNames []string
|
||
|
|
extensionNames = append(extensionNames, deviceExtensions...)
|
||
|
|
|
||
|
|
// Makes this example compatible with vulkan portability, necessary to run on mobile & mac
|
||
|
|
extensions, _, err := e.physicalDevice.EnumerateDeviceExtensionProperties()
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
_, supported := extensions[khr_portability_subset.ExtensionName]
|
||
|
|
if supported {
|
||
|
|
extensionNames = append(extensionNames, khr_portability_subset.ExtensionName)
|
||
|
|
}
|
||
|
|
|
||
|
|
e.device, _, err = e.physicalDevice.CreateDevice(nil, core1_0.DeviceCreateInfo{
|
||
|
|
QueueCreateInfos: queueFamilyOptions,
|
||
|
|
EnabledFeatures: &core1_0.PhysicalDeviceFeatures{},
|
||
|
|
EnabledExtensionNames: extensionNames,
|
||
|
|
})
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
e.graphicsQueue = e.device.GetQueue(*indices.GraphicsFamily, 0)
|
||
|
|
e.presentQueue = e.device.GetQueue(*indices.PresentFamily, 0)
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (e *FInstance) createSwapchain() error {
|
||
|
|
e.swapchainExtension = khr_swapchain.CreateExtensionFromDevice(e.device)
|
||
|
|
|
||
|
|
swapchainSupport, err := help.querySwapChainSupport(e.physicalDevice)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
surfaceFormat := help.chooseSwapSurfaceFormat(swapchainSupport.Formats)
|
||
|
|
presentMode := help.chooseSwapPresentMode(swapchainSupport.PresentModes)
|
||
|
|
extent := help.chooseSwapExtent(swapchainSupport.Capabilities)
|
||
|
|
|
||
|
|
imageCount := swapchainSupport.Capabilities.MinImageCount + 1
|
||
|
|
if swapchainSupport.Capabilities.MaxImageCount > 0 && swapchainSupport.Capabilities.MaxImageCount < imageCount {
|
||
|
|
imageCount = swapchainSupport.Capabilities.MaxImageCount
|
||
|
|
}
|
||
|
|
|
||
|
|
sharingMode := core1_0.SharingModeExclusive
|
||
|
|
var queueFamilyIndices []int
|
||
|
|
|
||
|
|
indices, err := help.findQueueFamilies(e.physicalDevice)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
if *indices.GraphicsFamily != *indices.PresentFamily {
|
||
|
|
sharingMode = core1_0.SharingModeConcurrent
|
||
|
|
queueFamilyIndices = append(queueFamilyIndices, *indices.GraphicsFamily, *indices.PresentFamily)
|
||
|
|
}
|
||
|
|
|
||
|
|
swapchain, _, err := e.swapchainExtension.CreateSwapchain(e.device, nil, khr_swapchain.SwapchainCreateInfo{
|
||
|
|
Surface: e.surface,
|
||
|
|
|
||
|
|
MinImageCount: imageCount,
|
||
|
|
ImageFormat: surfaceFormat.Format,
|
||
|
|
ImageColorSpace: surfaceFormat.ColorSpace,
|
||
|
|
ImageExtent: extent,
|
||
|
|
ImageArrayLayers: 1,
|
||
|
|
ImageUsage: core1_0.ImageUsageColorAttachment,
|
||
|
|
|
||
|
|
ImageSharingMode: sharingMode,
|
||
|
|
QueueFamilyIndices: queueFamilyIndices,
|
||
|
|
|
||
|
|
PreTransform: swapchainSupport.Capabilities.CurrentTransform,
|
||
|
|
CompositeAlpha: khr_surface.CompositeAlphaOpaque,
|
||
|
|
PresentMode: presentMode,
|
||
|
|
Clipped: true,
|
||
|
|
})
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
e.swapchainExtent = extent
|
||
|
|
e.swapchain = swapchain
|
||
|
|
e.swapchainImageFormat = surfaceFormat.Format
|
||
|
|
|
||
|
|
images, _, err := swapchain.SwapchainImages()
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
e.swapchainImages = images
|
||
|
|
|
||
|
|
var imageViews []core1_0.ImageView
|
||
|
|
for _, image := range images {
|
||
|
|
view, _, err := e.device.CreateImageView(nil, core1_0.ImageViewCreateInfo{
|
||
|
|
ViewType: core1_0.ImageViewType2D,
|
||
|
|
Image: image,
|
||
|
|
Format: surfaceFormat.Format,
|
||
|
|
Components: core1_0.ComponentMapping{
|
||
|
|
R: core1_0.ComponentSwizzleIdentity,
|
||
|
|
G: core1_0.ComponentSwizzleIdentity,
|
||
|
|
B: core1_0.ComponentSwizzleIdentity,
|
||
|
|
A: core1_0.ComponentSwizzleIdentity,
|
||
|
|
},
|
||
|
|
SubresourceRange: core1_0.ImageSubresourceRange{
|
||
|
|
AspectMask: core1_0.ImageAspectColor,
|
||
|
|
BaseMipLevel: 0,
|
||
|
|
LevelCount: 1,
|
||
|
|
BaseArrayLayer: 0,
|
||
|
|
LayerCount: 1,
|
||
|
|
},
|
||
|
|
})
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
imageViews = append(imageViews, view)
|
||
|
|
}
|
||
|
|
e.swapchainImageViews = imageViews
|
||
|
|
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
func (e *FInstance) Init() error {
|
||
|
|
help.vulkan = e
|
||
|
|
err := e.createSurface()
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
err = e.pickPhysicalDevice()
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
err = e.createLogicalDevice()
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
err = e.createSwapchain()
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
return nil
|
||
|
|
}
|