github.com/Seikaijyu/gio@v0.0.1/gpu/internal/driver/driver.go (about)

     1  // SPDX-License-Identifier: Unlicense OR MIT
     2  
     3  package driver
     4  
     5  import (
     6  	"errors"
     7  	"image"
     8  	"time"
     9  
    10  	"gioui.org/shader"
    11  	"github.com/Seikaijyu/gio/internal/f32color"
    12  )
    13  
    14  // Device represents the abstraction of underlying GPU
    15  // APIs such as OpenGL, Direct3D useful for rendering Gio
    16  // operations.
    17  type Device interface {
    18  	BeginFrame(target RenderTarget, clear bool, viewport image.Point) Texture
    19  	EndFrame()
    20  	Caps() Caps
    21  	NewTimer() Timer
    22  	// IsContinuousTime reports whether all timer measurements
    23  	// are valid at the point of call.
    24  	IsTimeContinuous() bool
    25  	NewTexture(format TextureFormat, width, height int, minFilter, magFilter TextureFilter, bindings BufferBinding) (Texture, error)
    26  	NewImmutableBuffer(typ BufferBinding, data []byte) (Buffer, error)
    27  	NewBuffer(typ BufferBinding, size int) (Buffer, error)
    28  	NewComputeProgram(shader shader.Sources) (Program, error)
    29  	NewVertexShader(src shader.Sources) (VertexShader, error)
    30  	NewFragmentShader(src shader.Sources) (FragmentShader, error)
    31  	NewPipeline(desc PipelineDesc) (Pipeline, error)
    32  
    33  	Viewport(x, y, width, height int)
    34  	DrawArrays(off, count int)
    35  	DrawElements(off, count int)
    36  
    37  	BeginRenderPass(t Texture, desc LoadDesc)
    38  	EndRenderPass()
    39  	PrepareTexture(t Texture)
    40  	BindProgram(p Program)
    41  	BindPipeline(p Pipeline)
    42  	BindTexture(unit int, t Texture)
    43  	BindVertexBuffer(b Buffer, offset int)
    44  	BindIndexBuffer(b Buffer)
    45  	BindImageTexture(unit int, texture Texture)
    46  	BindUniforms(buf Buffer)
    47  	BindStorageBuffer(binding int, buf Buffer)
    48  
    49  	BeginCompute()
    50  	EndCompute()
    51  	CopyTexture(dst Texture, dstOrigin image.Point, src Texture, srcRect image.Rectangle)
    52  	DispatchCompute(x, y, z int)
    53  
    54  	Release()
    55  }
    56  
    57  var ErrDeviceLost = errors.New("GPU device lost")
    58  
    59  type LoadDesc struct {
    60  	Action     LoadAction
    61  	ClearColor f32color.RGBA
    62  }
    63  
    64  type Pipeline interface {
    65  	Release()
    66  }
    67  
    68  type PipelineDesc struct {
    69  	VertexShader   VertexShader
    70  	FragmentShader FragmentShader
    71  	VertexLayout   VertexLayout
    72  	BlendDesc      BlendDesc
    73  	PixelFormat    TextureFormat
    74  	Topology       Topology
    75  }
    76  
    77  type VertexLayout struct {
    78  	Inputs []InputDesc
    79  	Stride int
    80  }
    81  
    82  // InputDesc describes a vertex attribute as laid out in a Buffer.
    83  type InputDesc struct {
    84  	Type shader.DataType
    85  	Size int
    86  
    87  	Offset int
    88  }
    89  
    90  type BlendDesc struct {
    91  	Enable               bool
    92  	SrcFactor, DstFactor BlendFactor
    93  }
    94  
    95  type BlendFactor uint8
    96  
    97  type Topology uint8
    98  
    99  type TextureFilter uint8
   100  type TextureFormat uint8
   101  
   102  type BufferBinding uint8
   103  
   104  type LoadAction uint8
   105  
   106  type Features uint
   107  
   108  type Caps struct {
   109  	// BottomLeftOrigin is true if the driver has the origin in the lower left
   110  	// corner. The OpenGL driver returns true.
   111  	BottomLeftOrigin bool
   112  	Features         Features
   113  	MaxTextureSize   int
   114  }
   115  
   116  type VertexShader interface {
   117  	Release()
   118  }
   119  
   120  type FragmentShader interface {
   121  	Release()
   122  }
   123  
   124  type Program interface {
   125  	Release()
   126  }
   127  
   128  type Buffer interface {
   129  	Release()
   130  	Upload(data []byte)
   131  	Download(data []byte) error
   132  }
   133  
   134  type Timer interface {
   135  	Begin()
   136  	End()
   137  	Duration() (time.Duration, bool)
   138  	Release()
   139  }
   140  
   141  type Texture interface {
   142  	RenderTarget
   143  	Upload(offset, size image.Point, pixels []byte, stride int)
   144  	ReadPixels(src image.Rectangle, pixels []byte, stride int) error
   145  	Release()
   146  }
   147  
   148  const (
   149  	BufferBindingIndices BufferBinding = 1 << iota
   150  	BufferBindingVertices
   151  	BufferBindingUniforms
   152  	BufferBindingTexture
   153  	BufferBindingFramebuffer
   154  	BufferBindingShaderStorageRead
   155  	BufferBindingShaderStorageWrite
   156  )
   157  
   158  const (
   159  	TextureFormatSRGBA TextureFormat = iota
   160  	TextureFormatFloat
   161  	TextureFormatRGBA8
   162  	// TextureFormatOutput denotes the format used by the output framebuffer.
   163  	TextureFormatOutput
   164  )
   165  
   166  const (
   167  	FilterNearest TextureFilter = iota
   168  	FilterLinear
   169  	FilterLinearMipmapLinear
   170  )
   171  
   172  const (
   173  	FeatureTimers Features = 1 << iota
   174  	FeatureFloatRenderTargets
   175  	FeatureCompute
   176  	FeatureSRGB
   177  )
   178  
   179  const (
   180  	TopologyTriangleStrip Topology = iota
   181  	TopologyTriangles
   182  )
   183  
   184  const (
   185  	BlendFactorOne BlendFactor = iota
   186  	BlendFactorOneMinusSrcAlpha
   187  	BlendFactorZero
   188  	BlendFactorDstColor
   189  )
   190  
   191  const (
   192  	LoadActionKeep LoadAction = iota
   193  	LoadActionClear
   194  	LoadActionInvalidate
   195  )
   196  
   197  var ErrContentLost = errors.New("buffer content lost")
   198  
   199  func (f Features) Has(feats Features) bool {
   200  	return f&feats == feats
   201  }
   202  
   203  func DownloadImage(d Device, t Texture, img *image.RGBA) error {
   204  	r := img.Bounds()
   205  	if err := t.ReadPixels(r, img.Pix, img.Stride); err != nil {
   206  		return err
   207  	}
   208  	if d.Caps().BottomLeftOrigin {
   209  		// OpenGL origin is in the lower-left corner. Flip the image to
   210  		// match.
   211  		flipImageY(r.Dx()*4, r.Dy(), img.Pix)
   212  	}
   213  	return nil
   214  }
   215  
   216  func flipImageY(stride, height int, pixels []byte) {
   217  	// Flip image in y-direction. OpenGL's origin is in the lower
   218  	// left corner.
   219  	row := make([]uint8, stride)
   220  	for y := 0; y < height/2; y++ {
   221  		y1 := height - y - 1
   222  		dest := y1 * stride
   223  		src := y * stride
   224  		copy(row, pixels[dest:])
   225  		copy(pixels[dest:], pixels[src:src+len(row)])
   226  		copy(pixels[src:], row)
   227  	}
   228  }
   229  
   230  func UploadImage(t Texture, offset image.Point, img *image.RGBA) {
   231  	var pixels []byte
   232  	size := img.Bounds().Size()
   233  	min := img.Rect.Min
   234  	start := img.PixOffset(min.X, min.Y)
   235  	end := img.PixOffset(min.X+size.X, min.Y+size.Y-1)
   236  	pixels = img.Pix[start:end]
   237  	t.Upload(offset, size, pixels, img.Stride)
   238  }