package instance //#cgo LDFLAGS: -LF:/Coding/GoModule/cgo -lvulkan import "C" 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" ) type T interface { EnumeratePhysicalDevices() []core1_0.PhysicalDevice Destroy() Init() error DrawFrame() error Ptr() core1_0.Instance WaitIdle() (common.VkResult, error) } type FLoaderCreate func() *core.VulkanLoader type FInstance struct { 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 renderPass core1_0.RenderPass pipelineLayout core1_0.PipelineLayout graphicsPipeline core1_0.Pipeline commandPool core1_0.CommandPool commandBuffers []core1_0.CommandBuffer imageAvailableSemaphore []core1_0.Semaphore renderFinishedSemaphore []core1_0.Semaphore inFlightFence []core1_0.Fence imagesInFlight []core1_0.Fence currentFrame int } func New(appName string, win *window.FSDLWindow, LoaderCreate FLoaderCreate) T { loader := LoaderCreate() instanceOptions := &core1_0.InstanceCreateInfo{ APIVersion: common.APIVersion(common.CreateVersion(1, 1, 0)), ApplicationName: appName, ApplicationVersion: common.CreateVersion(0, 1, 0), EngineName: engineName, EngineVersion: common.CreateVersion(0, 2, 1), } 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, loader: loader, win: win, } } func (e *FInstance) Ptr() core1_0.Instance { return e.ptr } func (e *FInstance) Destroy() { e.ptr.Destroy(nil) e.ptr = nil } func (e *FInstance) EnumeratePhysicalDevices() []core1_0.PhysicalDevice { r, _, err := e.ptr.EnumeratePhysicalDevices() if err != nil { panic(err) } return r } func (e *FInstance) WaitIdle() (common.VkResult, error) { return e.device.WaitIdle() } func (e *FInstance) DrawFrame() error { fences := []core1_0.Fence{e.inFlightFence[e.currentFrame]} _, err := e.device.WaitForFences(true, common.NoTimeout, fences) if err != nil { return err } imageIndex, _, err := e.swapchain.AcquireNextImage(common.NoTimeout, e.imageAvailableSemaphore[e.currentFrame], nil) if err != nil { return err } if e.imagesInFlight[imageIndex] != nil { _, err := e.device.WaitForFences(true, common.NoTimeout, []core1_0.Fence{e.imagesInFlight[imageIndex]}) if err != nil { return err } } e.imagesInFlight[imageIndex] = e.inFlightFence[e.currentFrame] _, err = e.device.ResetFences(fences) if err != nil { return err } _, err = e.graphicsQueue.Submit(e.inFlightFence[e.currentFrame], []core1_0.SubmitInfo{ { WaitSemaphores: []core1_0.Semaphore{e.imageAvailableSemaphore[e.currentFrame]}, WaitDstStageMask: []core1_0.PipelineStageFlags{core1_0.PipelineStageColorAttachmentOutput}, CommandBuffers: []core1_0.CommandBuffer{e.commandBuffers[imageIndex]}, SignalSemaphores: []core1_0.Semaphore{e.renderFinishedSemaphore[e.currentFrame]}, }, }) if err != nil { return err } _, err = e.swapchainExtension.QueuePresent(e.presentQueue, khr_swapchain.PresentInfo{ WaitSemaphores: []core1_0.Semaphore{e.renderFinishedSemaphore[e.currentFrame]}, Swapchains: []khr_swapchain.Swapchain{e.swapchain}, ImageIndices: []int{imageIndex}, }) if err != nil { return err } e.currentFrame = (e.currentFrame + 1) % MaxFramesInFlight return nil }