vulkan init
This commit is contained in:
		
							parent
							
								
									2296cda4b5
								
							
						
					
					
						commit
						a2e3ae5c55
					
				| @ -23,6 +23,10 @@ func main() { | ||||
| 	} | ||||
| 	vulkan := instance.New("test", win, window.CreateLoaderFromSDL) | ||||
| 	vulkan.EnumeratePhysicalDevices() | ||||
| 	err = vulkan.Init() | ||||
| 	if err != nil { | ||||
| 		zlog.Infof("err", err) | ||||
| 	} | ||||
| 	for i := 1; i < 100; i++ { | ||||
| 		w.Tick() | ||||
| 	} | ||||
|  | ||||
| @ -1,17 +1,6 @@ | ||||
| package instance | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/vkngwrapper/extensions/v2/ext_debug_utils" | ||||
| 	"github.com/vkngwrapper/extensions/v2/khr_get_physical_device_properties2" | ||||
| 	"github.com/vkngwrapper/extensions/v2/khr_surface" | ||||
| ) | ||||
| import "github.com/vkngwrapper/extensions/v2/khr_swapchain" | ||||
| 
 | ||||
| var validationLayers = []string{"VK_LAYER_KHRONOS_validation"} | ||||
| var extensions = []string{ | ||||
| 	khr_surface.ExtensionName, | ||||
| 	ext_debug_utils.ExtensionName, | ||||
| 	khr_get_physical_device_properties2.ExtensionName, | ||||
| 
 | ||||
| 	"VK_EXT_debug_report", | ||||
| 	"VK_EXT_metal_surface", | ||||
| } | ||||
| var deviceExtensions = []string{khr_swapchain.ExtensionName} | ||||
|  | ||||
| @ -7,26 +7,37 @@ import ( | ||||
| 	"github.com/vkngwrapper/core/v2" | ||||
| 	"github.com/vkngwrapper/core/v2/common" | ||||
| 	"github.com/vkngwrapper/core/v2/core1_0" | ||||
| 	"github.com/vkngwrapper/extensions/v2/khr_surface" | ||||
| 	"github.com/vkngwrapper/extensions/v2/khr_swapchain" | ||||
| 	"zworld/engine/window" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	engineName = "goworld" | ||||
| 	layers     = []string{ | ||||
| 		"VK_LAYER_KHRONOS_validation", | ||||
| 		//"VK_LAYER_LUNARG_api_dump",
 | ||||
| 	} | ||||
| ) | ||||
| 
 | ||||
| type T interface { | ||||
| 	EnumeratePhysicalDevices() []core1_0.PhysicalDevice | ||||
| 	Destroy() | ||||
| 	Init() error | ||||
| 	Ptr() core1_0.Instance | ||||
| } | ||||
| type FLoaderCreate func() *core.VulkanLoader | ||||
| type FInstance struct { | ||||
| 	loader *core.VulkanLoader | ||||
| 	ptr    core1_0.Instance | ||||
| 	loader  *core.VulkanLoader | ||||
| 	win     *window.FSDLWindow | ||||
| 	ptr     core1_0.Instance | ||||
| 	surface khr_surface.Surface | ||||
| 
 | ||||
| 	physicalDevice core1_0.PhysicalDevice | ||||
| 	device         core1_0.Device | ||||
| 
 | ||||
| 	graphicsQueue core1_0.Queue | ||||
| 	presentQueue  core1_0.Queue | ||||
| 
 | ||||
| 	swapchainExtension    khr_swapchain.Extension | ||||
| 	swapchain             khr_swapchain.Swapchain | ||||
| 	swapchainImages       []core1_0.Image | ||||
| 	swapchainImageFormat  core1_0.Format | ||||
| 	swapchainExtent       core1_0.Extent2D | ||||
| 	swapchainImageViews   []core1_0.ImageView | ||||
| 	swapchainFramebuffers []core1_0.Framebuffer | ||||
| } | ||||
| 
 | ||||
| func New(appName string, win *window.FSDLWindow, LoaderCreate FLoaderCreate) T { | ||||
| @ -35,30 +46,39 @@ func New(appName string, win *window.FSDLWindow, LoaderCreate FLoaderCreate) T { | ||||
| 		APIVersion:         common.APIVersion(common.CreateVersion(1, 1, 0)), | ||||
| 		ApplicationName:    appName, | ||||
| 		ApplicationVersion: common.CreateVersion(0, 1, 0), | ||||
| 		EngineName:         "goworld", | ||||
| 		EngineName:         engineName, | ||||
| 		EngineVersion:      common.CreateVersion(0, 2, 1), | ||||
| 	} | ||||
| 	help.getCreateInstanceExtension(instanceOptions, loader, win) | ||||
| 	err := help.getCreateInstanceExtension(instanceOptions, loader, win) | ||||
| 	if err != nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 	err = help.getCreateInstanceLayer(instanceOptions, loader, win) | ||||
| 	if err != nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 	handle, _, err := loader.CreateInstance(nil, *instanceOptions) | ||||
| 	if err != nil { | ||||
| 		panic(err) | ||||
| 	} | ||||
| 	return &FInstance{ | ||||
| 		ptr: handle, | ||||
| 		ptr:    handle, | ||||
| 		loader: loader, | ||||
| 		win:    win, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (i *FInstance) Ptr() core1_0.Instance { | ||||
| 	return i.ptr | ||||
| func (e *FInstance) Ptr() core1_0.Instance { | ||||
| 	return e.ptr | ||||
| } | ||||
| 
 | ||||
| func (i *FInstance) Destroy() { | ||||
| 	i.ptr.Destroy(nil) | ||||
| 	i.ptr = nil | ||||
| func (e *FInstance) Destroy() { | ||||
| 	e.ptr.Destroy(nil) | ||||
| 	e.ptr = nil | ||||
| } | ||||
| 
 | ||||
| func (i *FInstance) EnumeratePhysicalDevices() []core1_0.PhysicalDevice { | ||||
| 	r, _, err := i.ptr.EnumeratePhysicalDevices() | ||||
| func (e *FInstance) EnumeratePhysicalDevices() []core1_0.PhysicalDevice { | ||||
| 	r, _, err := e.ptr.EnumeratePhysicalDevices() | ||||
| 	if err != nil { | ||||
| 		panic(err) | ||||
| 	} | ||||
|  | ||||
							
								
								
									
										200
									
								
								engine/render/vulkan/instance/instance_init.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										200
									
								
								engine/render/vulkan/instance/instance_init.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,200 @@ | ||||
| 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 | ||||
| } | ||||
| @ -2,4 +2,7 @@ package instance | ||||
| 
 | ||||
| const enableValidationLayers = true | ||||
| 
 | ||||
| var help FVulkanHelp | ||||
| var ( | ||||
| 	help       FVulkanHelp | ||||
| 	engineName = "goworld" | ||||
| ) | ||||
|  | ||||
| @ -5,10 +5,27 @@ import ( | ||||
| 	"github.com/vkngwrapper/core/v2/core1_0" | ||||
| 	"github.com/vkngwrapper/extensions/v2/ext_debug_utils" | ||||
| 	"github.com/vkngwrapper/extensions/v2/khr_portability_enumeration" | ||||
| 	"github.com/vkngwrapper/extensions/v2/khr_surface" | ||||
| 	"zworld/engine/window" | ||||
| ) | ||||
| 
 | ||||
| type FVulkanHelp struct{} | ||||
| type FVulkanHelp struct { | ||||
| 	vulkan *FInstance | ||||
| } | ||||
| type QueueFamilyIndices struct { | ||||
| 	GraphicsFamily *int | ||||
| 	PresentFamily  *int | ||||
| } | ||||
| 
 | ||||
| func (i *QueueFamilyIndices) IsComplete() bool { | ||||
| 	return i.GraphicsFamily != nil && i.PresentFamily != nil | ||||
| } | ||||
| 
 | ||||
| type SwapChainSupportDetails struct { | ||||
| 	Capabilities *khr_surface.SurfaceCapabilities | ||||
| 	Formats      []khr_surface.SurfaceFormat | ||||
| 	PresentModes []khr_surface.PresentMode | ||||
| } | ||||
| 
 | ||||
| func (h *FVulkanHelp) getCreateInstanceExtension(instanceOptions *core1_0.InstanceCreateInfo, loader *core.VulkanLoader, win *window.FSDLWindow) error { | ||||
| 	// Add extensions
 | ||||
| @ -56,3 +73,130 @@ func (h *FVulkanHelp) getCreateInstanceLayer(instanceOptions *core1_0.InstanceCr | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (h *FVulkanHelp) findQueueFamilies(device core1_0.PhysicalDevice) (QueueFamilyIndices, error) { | ||||
| 	indices := QueueFamilyIndices{} | ||||
| 	e := h.vulkan | ||||
| 	queueFamilies := device.QueueFamilyProperties() | ||||
| 
 | ||||
| 	for queueFamilyIdx, queueFamily := range queueFamilies { | ||||
| 		if (queueFamily.QueueFlags & core1_0.QueueGraphics) != 0 { | ||||
| 			indices.GraphicsFamily = new(int) | ||||
| 			*indices.GraphicsFamily = queueFamilyIdx | ||||
| 		} | ||||
| 
 | ||||
| 		supported, _, err := e.surface.PhysicalDeviceSurfaceSupport(device, queueFamilyIdx) | ||||
| 		if err != nil { | ||||
| 			return indices, err | ||||
| 		} | ||||
| 
 | ||||
| 		if supported { | ||||
| 			indices.PresentFamily = new(int) | ||||
| 			*indices.PresentFamily = queueFamilyIdx | ||||
| 		} | ||||
| 
 | ||||
| 		if indices.IsComplete() { | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return indices, nil | ||||
| } | ||||
| func (h *FVulkanHelp) checkDeviceExtensionSupport(device core1_0.PhysicalDevice) bool { | ||||
| 	extensions, _, err := device.EnumerateDeviceExtensionProperties() | ||||
| 	if err != nil { | ||||
| 		return false | ||||
| 	} | ||||
| 
 | ||||
| 	for _, extension := range deviceExtensions { | ||||
| 		_, hasExtension := extensions[extension] | ||||
| 		if !hasExtension { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return true | ||||
| } | ||||
| func (h *FVulkanHelp) querySwapChainSupport(device core1_0.PhysicalDevice) (SwapChainSupportDetails, error) { | ||||
| 	e := h.vulkan | ||||
| 	var details SwapChainSupportDetails | ||||
| 	var err error | ||||
| 
 | ||||
| 	details.Capabilities, _, err = e.surface.PhysicalDeviceSurfaceCapabilities(device) | ||||
| 	if err != nil { | ||||
| 		return details, err | ||||
| 	} | ||||
| 
 | ||||
| 	details.Formats, _, err = e.surface.PhysicalDeviceSurfaceFormats(device) | ||||
| 	if err != nil { | ||||
| 		return details, err | ||||
| 	} | ||||
| 
 | ||||
| 	details.PresentModes, _, err = e.surface.PhysicalDeviceSurfacePresentModes(device) | ||||
| 	return details, err | ||||
| } | ||||
| func (h *FVulkanHelp) isDeviceSuitable(device core1_0.PhysicalDevice) bool { | ||||
| 	indices, err := h.findQueueFamilies(device) | ||||
| 	if err != nil { | ||||
| 		return false | ||||
| 	} | ||||
| 
 | ||||
| 	extensionsSupported := h.checkDeviceExtensionSupport(device) | ||||
| 
 | ||||
| 	var swapChainAdequate bool | ||||
| 	if extensionsSupported { | ||||
| 		swapChainSupport, err := h.querySwapChainSupport(device) | ||||
| 		if err != nil { | ||||
| 			return false | ||||
| 		} | ||||
| 
 | ||||
| 		swapChainAdequate = len(swapChainSupport.Formats) > 0 && len(swapChainSupport.PresentModes) > 0 | ||||
| 	} | ||||
| 
 | ||||
| 	return indices.IsComplete() && extensionsSupported && swapChainAdequate | ||||
| } | ||||
| 
 | ||||
| func (h *FVulkanHelp) chooseSwapSurfaceFormat(availableFormats []khr_surface.SurfaceFormat) khr_surface.SurfaceFormat { | ||||
| 	for _, format := range availableFormats { | ||||
| 		if format.Format == core1_0.FormatB8G8R8A8SRGB && format.ColorSpace == khr_surface.ColorSpaceSRGBNonlinear { | ||||
| 			return format | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return availableFormats[0] | ||||
| } | ||||
| 
 | ||||
| func (h *FVulkanHelp) chooseSwapPresentMode(availablePresentModes []khr_surface.PresentMode) khr_surface.PresentMode { | ||||
| 	for _, presentMode := range availablePresentModes { | ||||
| 		if presentMode == khr_surface.PresentModeMailbox { | ||||
| 			return presentMode | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return khr_surface.PresentModeFIFO | ||||
| } | ||||
| 
 | ||||
| func (h *FVulkanHelp) chooseSwapExtent(capabilities *khr_surface.SurfaceCapabilities) core1_0.Extent2D { | ||||
| 	if capabilities.CurrentExtent.Width != -1 { | ||||
| 		return capabilities.CurrentExtent | ||||
| 	} | ||||
| 	e := h.vulkan | ||||
| 	widthInt, heightInt := e.win.GetInstance().VulkanGetDrawableSize() | ||||
| 	width := int(widthInt) | ||||
| 	height := int(heightInt) | ||||
| 
 | ||||
| 	if width < capabilities.MinImageExtent.Width { | ||||
| 		width = capabilities.MinImageExtent.Width | ||||
| 	} | ||||
| 	if width > capabilities.MaxImageExtent.Width { | ||||
| 		width = capabilities.MaxImageExtent.Width | ||||
| 	} | ||||
| 	if height < capabilities.MinImageExtent.Height { | ||||
| 		height = capabilities.MinImageExtent.Height | ||||
| 	} | ||||
| 	if height > capabilities.MaxImageExtent.Height { | ||||
| 		height = capabilities.MaxImageExtent.Height | ||||
| 	} | ||||
| 
 | ||||
| 	return core1_0.Extent2D{Width: width, Height: height} | ||||
| } | ||||
|  | ||||
							
								
								
									
										1
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								go.mod
									
									
									
									
									
								
							| @ -27,6 +27,7 @@ require ( | ||||
| 	github.com/kjk/flex v0.0.0-20171203210503-ed34d6b6a425 // indirect | ||||
| 	github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect | ||||
| 	github.com/pkg/errors v0.9.1 // indirect | ||||
| 	github.com/vkngwrapper/integrations/sdl2/v2 v2.1.0 // indirect | ||||
| 	go.uber.org/multierr v1.10.0 // indirect | ||||
| 	golang.org/x/net v0.19.0 // indirect | ||||
| 	golang.org/x/sys v0.15.0 // indirect | ||||
|  | ||||
							
								
								
									
										2
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.sum
									
									
									
									
									
								
							| @ -47,6 +47,8 @@ github.com/vkngwrapper/core/v2 v2.2.1 h1:8xw2tuIXAeyNQj4mnDA7BHO6T6f7ba08UbJZB7U | ||||
| github.com/vkngwrapper/core/v2 v2.2.1/go.mod h1:EWABLJZGHa8nyeO4Bh9eR/V862HAz+Fvk5DitkOvYF4= | ||||
| github.com/vkngwrapper/extensions/v2 v2.2.0 h1:2ZP+Nom2EbefqgR2EPherJRS836wSWPoXeOLvV7aUuY= | ||||
| github.com/vkngwrapper/extensions/v2 v2.2.0/go.mod h1:55exjYwTUyQVNS/zhrC/Or/c2CA4Q9Cj/88Tu9EqlJ0= | ||||
| github.com/vkngwrapper/integrations/sdl2/v2 v2.1.0 h1:7XZItFXzMeg6NDsvTXLQz65QD93t+rUuLwXbHbXsmmc= | ||||
| github.com/vkngwrapper/integrations/sdl2/v2 v2.1.0/go.mod h1:Qwh+0jymwQHlXQQgVYB77m6O49ShV37nR75RBJ/oRvI= | ||||
| go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= | ||||
| go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= | ||||
| go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user