195 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			195 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								package main
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import (
							 | 
						||
| 
								 | 
							
									"github.com/pkg/errors"
							 | 
						||
| 
								 | 
							
									"github.com/veandco/go-sdl2/sdl"
							 | 
						||
| 
								 | 
							
									"github.com/vkngwrapper/core/v2"
							 | 
						||
| 
								 | 
							
									"github.com/vkngwrapper/core/v2/common"
							 | 
						||
| 
								 | 
							
									"github.com/vkngwrapper/core/v2/core1_0"
							 | 
						||
| 
								 | 
							
									"github.com/vkngwrapper/extensions/v2/ext_debug_utils"
							 | 
						||
| 
								 | 
							
									"github.com/vkngwrapper/extensions/v2/khr_portability_enumeration"
							 | 
						||
| 
								 | 
							
									"log"
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var validationLayers = []string{"VK_LAYER_KHRONOS_validation"}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const enableValidationLayers = true
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								type HelloTriangleApplication struct {
							 | 
						||
| 
								 | 
							
									window *sdl.Window
							 | 
						||
| 
								 | 
							
									loader core.Loader
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									instance       core1_0.Instance
							 | 
						||
| 
								 | 
							
									debugMessenger ext_debug_utils.DebugUtilsMessenger
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (app *HelloTriangleApplication) Run() error {
							 | 
						||
| 
								 | 
							
									err := app.initWindow()
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									err = app.initVulkan()
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									defer app.cleanup()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return app.mainLoop()
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (app *HelloTriangleApplication) initWindow() error {
							 | 
						||
| 
								 | 
							
									if err := sdl.Init(sdl.INIT_VIDEO); err != nil {
							 | 
						||
| 
								 | 
							
										return err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									window, err := sdl.CreateWindow("Vulkan", sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, 800, 600, sdl.WINDOW_SHOWN|sdl.WINDOW_VULKAN)
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									app.window = window
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									app.loader, err = core.CreateSystemLoader()
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return nil
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (app *HelloTriangleApplication) initVulkan() error {
							 | 
						||
| 
								 | 
							
									err := app.createInstance()
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return app.setupDebugMessenger()
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (app *HelloTriangleApplication) mainLoop() error {
							 | 
						||
| 
								 | 
							
								appLoop:
							 | 
						||
| 
								 | 
							
									for true {
							 | 
						||
| 
								 | 
							
										for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
							 | 
						||
| 
								 | 
							
											switch event.(type) {
							 | 
						||
| 
								 | 
							
											case *sdl.QuitEvent:
							 | 
						||
| 
								 | 
							
												break appLoop
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return nil
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (app *HelloTriangleApplication) cleanup() {
							 | 
						||
| 
								 | 
							
									if app.debugMessenger != nil {
							 | 
						||
| 
								 | 
							
										app.debugMessenger.Destroy(nil)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if app.instance != nil {
							 | 
						||
| 
								 | 
							
										app.instance.Destroy(nil)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if app.window != nil {
							 | 
						||
| 
								 | 
							
										app.window.Destroy()
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									sdl.Quit()
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (app *HelloTriangleApplication) createInstance() error {
							 | 
						||
| 
								 | 
							
									instanceOptions := core1_0.InstanceCreateInfo{
							 | 
						||
| 
								 | 
							
										ApplicationName:    "Hello Triangle",
							 | 
						||
| 
								 | 
							
										ApplicationVersion: common.CreateVersion(1, 0, 0),
							 | 
						||
| 
								 | 
							
										EngineName:         "No Engine",
							 | 
						||
| 
								 | 
							
										EngineVersion:      common.CreateVersion(1, 0, 0),
							 | 
						||
| 
								 | 
							
										APIVersion:         common.Vulkan1_2,
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Add extensions
							 | 
						||
| 
								 | 
							
									sdlExtensions := app.window.VulkanGetInstanceExtensions()
							 | 
						||
| 
								 | 
							
									extensions, _, err := app.loader.AvailableExtensions()
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for _, ext := range sdlExtensions {
							 | 
						||
| 
								 | 
							
										_, hasExt := extensions[ext]
							 | 
						||
| 
								 | 
							
										if !hasExt {
							 | 
						||
| 
								 | 
							
											return errors.Errorf("createinstance: cannot initialize sdl: missing extension %s", ext)
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										instanceOptions.EnabledExtensionNames = append(instanceOptions.EnabledExtensionNames, ext)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if enableValidationLayers {
							 | 
						||
| 
								 | 
							
										instanceOptions.EnabledExtensionNames = append(instanceOptions.EnabledExtensionNames, ext_debug_utils.ExtensionName)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									_, enumerationSupported := extensions[khr_portability_enumeration.ExtensionName]
							 | 
						||
| 
								 | 
							
									if enumerationSupported {
							 | 
						||
| 
								 | 
							
										instanceOptions.EnabledExtensionNames = append(instanceOptions.EnabledExtensionNames, khr_portability_enumeration.ExtensionName)
							 | 
						||
| 
								 | 
							
										instanceOptions.Flags |= khr_portability_enumeration.InstanceCreateEnumeratePortability
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Add layers
							 | 
						||
| 
								 | 
							
									layers, _, err := app.loader.AvailableLayers()
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if enableValidationLayers {
							 | 
						||
| 
								 | 
							
										for _, layer := range validationLayers {
							 | 
						||
| 
								 | 
							
											_, hasValidation := layers[layer]
							 | 
						||
| 
								 | 
							
											if !hasValidation {
							 | 
						||
| 
								 | 
							
												return errors.Errorf("createInstance: cannot add validation- layer %s not available- install LunarG Vulkan SDK", layer)
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											instanceOptions.EnabledLayerNames = append(instanceOptions.EnabledLayerNames, layer)
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// Add debug messenger
							 | 
						||
| 
								 | 
							
										instanceOptions.Next = app.debugMessengerOptions()
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									app.instance, _, err = app.loader.CreateInstance(nil, instanceOptions)
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return nil
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (app *HelloTriangleApplication) debugMessengerOptions() ext_debug_utils.DebugUtilsMessengerCreateInfo {
							 | 
						||
| 
								 | 
							
									return ext_debug_utils.DebugUtilsMessengerCreateInfo{
							 | 
						||
| 
								 | 
							
										MessageSeverity: ext_debug_utils.SeverityError | ext_debug_utils.SeverityWarning,
							 | 
						||
| 
								 | 
							
										MessageType:     ext_debug_utils.TypeGeneral | ext_debug_utils.TypeValidation | ext_debug_utils.TypePerformance,
							 | 
						||
| 
								 | 
							
										UserCallback:    app.logDebug,
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (app *HelloTriangleApplication) setupDebugMessenger() error {
							 | 
						||
| 
								 | 
							
									if !enableValidationLayers {
							 | 
						||
| 
								 | 
							
										return nil
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var err error
							 | 
						||
| 
								 | 
							
									debugLoader := ext_debug_utils.CreateExtensionFromInstance(app.instance)
							 | 
						||
| 
								 | 
							
									app.debugMessenger, _, err = debugLoader.CreateDebugUtilsMessenger(app.instance, nil, app.debugMessengerOptions())
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return nil
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (app *HelloTriangleApplication) logDebug(msgType ext_debug_utils.DebugUtilsMessageTypeFlags, severity ext_debug_utils.DebugUtilsMessageSeverityFlags, data *ext_debug_utils.DebugUtilsMessengerCallbackData) bool {
							 | 
						||
| 
								 | 
							
									log.Printf("[%s %s] - %s", severity, msgType, data.Message)
							 | 
						||
| 
								 | 
							
									return false
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func main() {
							 | 
						||
| 
								 | 
							
									app := &HelloTriangleApplication{}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									err := app.Run()
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										log.Fatalf("%+v\n", err)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 |