github.com/utopiagio/gio@v0.0.8/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 "github.com/utopiagio/gio/internal/f32color" 11 "gioui.org/shader" 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 }