chore(v2): vendor dependencies for offline/China builds
go mod vendor pins onnxruntime_go v1.12.1, Gio and the rest into v2/vendor so go run/build work without hitting proxy.golang.org (blocked/slow in China). Verified: CGO_ENABLED=1 go build -mod=vendor ./internal/spike and GOOS=windows go build -mod=vendor ./internal/ui both pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+218
@@ -0,0 +1,218 @@
|
||||
// SPDX-License-Identifier: Unlicense OR MIT
|
||||
|
||||
//go:build (linux || freebsd) && !novulkan
|
||||
// +build linux freebsd
|
||||
// +build !novulkan
|
||||
|
||||
package app
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"unsafe"
|
||||
|
||||
"gioui.org/gpu"
|
||||
"gioui.org/internal/vk"
|
||||
)
|
||||
|
||||
type vkContext struct {
|
||||
physDev vk.PhysicalDevice
|
||||
inst vk.Instance
|
||||
dev vk.Device
|
||||
queueFam int
|
||||
queue vk.Queue
|
||||
acquireSem vk.Semaphore
|
||||
presentSem vk.Semaphore
|
||||
fence vk.Fence
|
||||
|
||||
swchain vk.Swapchain
|
||||
imgs []vk.Image
|
||||
views []vk.ImageView
|
||||
fbos []vk.Framebuffer
|
||||
format vk.Format
|
||||
presentIdx int
|
||||
}
|
||||
|
||||
func newVulkanContext(inst vk.Instance, surf vk.Surface) (*vkContext, error) {
|
||||
physDev, qFam, err := vk.ChoosePhysicalDevice(inst, surf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dev, err := vk.CreateDeviceAndQueue(physDev, qFam, "VK_KHR_swapchain")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
acquireSem, err := vk.CreateSemaphore(dev)
|
||||
if err != nil {
|
||||
vk.DestroyDevice(dev)
|
||||
return nil, err
|
||||
}
|
||||
presentSem, err := vk.CreateSemaphore(dev)
|
||||
if err != nil {
|
||||
vk.DestroySemaphore(dev, acquireSem)
|
||||
vk.DestroyDevice(dev)
|
||||
return nil, err
|
||||
}
|
||||
fence, err := vk.CreateFence(dev, vk.FENCE_CREATE_SIGNALED_BIT)
|
||||
if err != nil {
|
||||
vk.DestroySemaphore(dev, presentSem)
|
||||
vk.DestroySemaphore(dev, acquireSem)
|
||||
vk.DestroyDevice(dev)
|
||||
return nil, err
|
||||
}
|
||||
c := &vkContext{
|
||||
physDev: physDev,
|
||||
inst: inst,
|
||||
dev: dev,
|
||||
queueFam: qFam,
|
||||
queue: vk.GetDeviceQueue(dev, qFam, 0),
|
||||
acquireSem: acquireSem,
|
||||
presentSem: presentSem,
|
||||
fence: fence,
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (c *vkContext) RenderTarget() (gpu.RenderTarget, error) {
|
||||
vk.WaitForFences(c.dev, c.fence)
|
||||
vk.ResetFences(c.dev, c.fence)
|
||||
|
||||
imgIdx, err := vk.AcquireNextImage(c.dev, c.swchain, c.acquireSem, 0)
|
||||
if err := mapSurfaceErr(err); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.presentIdx = imgIdx
|
||||
return gpu.VulkanRenderTarget{
|
||||
WaitSem: uint64(c.acquireSem),
|
||||
SignalSem: uint64(c.presentSem),
|
||||
Fence: uint64(c.fence),
|
||||
Framebuffer: uint64(c.fbos[imgIdx]),
|
||||
Image: uint64(c.imgs[imgIdx]),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *vkContext) api() gpu.API {
|
||||
return gpu.Vulkan{
|
||||
PhysDevice: unsafe.Pointer(c.physDev),
|
||||
Device: unsafe.Pointer(c.dev),
|
||||
Format: int(c.format),
|
||||
QueueFamily: c.queueFam,
|
||||
QueueIndex: 0,
|
||||
}
|
||||
}
|
||||
|
||||
func mapErr(err error) error {
|
||||
var vkErr vk.Error
|
||||
if errors.As(err, &vkErr) && vkErr == vk.ERROR_DEVICE_LOST {
|
||||
return gpu.ErrDeviceLost
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func mapSurfaceErr(err error) error {
|
||||
var vkErr vk.Error
|
||||
if !errors.As(err, &vkErr) {
|
||||
return err
|
||||
}
|
||||
switch {
|
||||
case vkErr == vk.SUBOPTIMAL_KHR:
|
||||
// Android reports VK_SUBOPTIMAL_KHR when presenting to a rotated
|
||||
// swapchain (preTransform != currentTransform). However, we don't
|
||||
// support transforming the output ourselves, so we'll live with it.
|
||||
return nil
|
||||
case vkErr == vk.ERROR_OUT_OF_DATE_KHR:
|
||||
return errOutOfDate
|
||||
case vkErr == vk.ERROR_SURFACE_LOST_KHR:
|
||||
// Treating a lost surface as a lost device isn't accurate, but
|
||||
// probably not worth optimizing.
|
||||
return gpu.ErrDeviceLost
|
||||
}
|
||||
return mapErr(err)
|
||||
}
|
||||
|
||||
func (c *vkContext) release() {
|
||||
vk.DeviceWaitIdle(c.dev)
|
||||
|
||||
c.destroySwapchain()
|
||||
vk.DestroyFence(c.dev, c.fence)
|
||||
vk.DestroySemaphore(c.dev, c.acquireSem)
|
||||
vk.DestroySemaphore(c.dev, c.presentSem)
|
||||
vk.DestroyDevice(c.dev)
|
||||
*c = vkContext{}
|
||||
}
|
||||
|
||||
func (c *vkContext) present() error {
|
||||
return mapSurfaceErr(vk.PresentQueue(c.queue, c.swchain, c.presentSem, c.presentIdx))
|
||||
}
|
||||
|
||||
func (c *vkContext) destroyImageViews() {
|
||||
for _, f := range c.fbos {
|
||||
vk.DestroyFramebuffer(c.dev, f)
|
||||
}
|
||||
c.fbos = nil
|
||||
for _, view := range c.views {
|
||||
vk.DestroyImageView(c.dev, view)
|
||||
}
|
||||
c.views = nil
|
||||
}
|
||||
|
||||
func (c *vkContext) destroySwapchain() {
|
||||
vk.DeviceWaitIdle(c.dev)
|
||||
|
||||
c.destroyImageViews()
|
||||
if c.swchain != 0 {
|
||||
vk.DestroySwapchain(c.dev, c.swchain)
|
||||
c.swchain = 0
|
||||
}
|
||||
}
|
||||
|
||||
func (c *vkContext) refresh(surf vk.Surface, width, height int) error {
|
||||
vk.DeviceWaitIdle(c.dev)
|
||||
|
||||
c.destroyImageViews()
|
||||
// Check whether size is valid. That's needed on X11, where ConfigureNotify
|
||||
// is not always synchronized with the window extent.
|
||||
caps, err := vk.GetPhysicalDeviceSurfaceCapabilities(c.physDev, surf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
minExt, maxExt := vk.SurfaceCapabilitiesMinExtent(caps), vk.SurfaceCapabilitiesMaxExtent(caps)
|
||||
if width < minExt.X || maxExt.X < width || height < minExt.Y || maxExt.Y < height {
|
||||
return errOutOfDate
|
||||
}
|
||||
swchain, imgs, format, err := vk.CreateSwapchain(c.physDev, c.dev, surf, width, height, c.swchain)
|
||||
if c.swchain != 0 {
|
||||
vk.DestroySwapchain(c.dev, c.swchain)
|
||||
c.swchain = 0
|
||||
}
|
||||
if err := mapSurfaceErr(err); err != nil {
|
||||
return err
|
||||
}
|
||||
c.swchain = swchain
|
||||
c.imgs = imgs
|
||||
c.format = format
|
||||
pass, err := vk.CreateRenderPass(
|
||||
c.dev,
|
||||
format,
|
||||
vk.ATTACHMENT_LOAD_OP_CLEAR,
|
||||
vk.IMAGE_LAYOUT_UNDEFINED,
|
||||
vk.IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
||||
nil,
|
||||
)
|
||||
if err := mapErr(err); err != nil {
|
||||
return err
|
||||
}
|
||||
defer vk.DestroyRenderPass(c.dev, pass)
|
||||
for _, img := range imgs {
|
||||
view, err := vk.CreateImageView(c.dev, img, format)
|
||||
if err := mapErr(err); err != nil {
|
||||
return err
|
||||
}
|
||||
c.views = append(c.views, view)
|
||||
fbo, err := vk.CreateFramebuffer(c.dev, pass, view, width, height)
|
||||
if err := mapErr(err); err != nil {
|
||||
return err
|
||||
}
|
||||
c.fbos = append(c.fbos, fbo)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user