github.com/cybriq/giocore@v0.0.7-0.20210703034601-cfb9cb5f3900/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  
    11  // Device represents the abstraction of underlying GPU
    12  // APIs such as OpenGL, Direct3D useful for rendering Gio
    13  // operations.
    14  type Device interface {
    15  	BeginFrame(clear bool, viewport image.Point) Framebuffer
    16  	EndFrame()
    17  	Caps() Caps
    18  	NewTimer() Timer
    19  	// IsContinuousTime reports whether all timer measurements
    20  	// are valid at the point of call.
    21  	IsTimeContinuous() bool
    22  	NewTexture(format TextureFormat, width, height int, minFilter, magFilter TextureFilter, bindings BufferBinding) (Texture, error)
    23  	NewFramebuffer(tex Texture, depthBits int) (Framebuffer, error)
    24  	NewImmutableBuffer(typ BufferBinding, data []byte) (Buffer, error)
    25  	NewBuffer(typ BufferBinding, size int) (Buffer, error)
    26  	NewComputeProgram(shader ShaderSources) (Program, error)
    27  	NewProgram(vertexShader, fragmentShader ShaderSources) (Program, error)
    28  	NewInputLayout(vertexShader ShaderSources, layout []InputDesc) (InputLayout, error)
    29  
    30  	DepthFunc(f DepthFunc)
    31  	ClearDepth(d float32)
    32  	Clear(r, g, b, a float32)
    33  	Viewport(x, y, width, height int)
    34  	DrawArrays(mode DrawMode, off, count int)
    35  	DrawElements(mode DrawMode, off, count int)
    36  	SetBlend(enable bool)
    37  	SetDepthTest(enable bool)
    38  	DepthMask(mask bool)
    39  	BlendFunc(sfactor, dfactor BlendFactor)
    40  
    41  	BindInputLayout(i InputLayout)
    42  	BindProgram(p Program)
    43  	BindFramebuffer(f Framebuffer)
    44  	BindTexture(unit int, t Texture)
    45  	BindVertexBuffer(b Buffer, stride, offset int)
    46  	BindIndexBuffer(b Buffer)
    47  	BindImageTexture(unit int, texture Texture, access AccessBits, format TextureFormat)
    48  
    49  	MemoryBarrier()
    50  	DispatchCompute(x, y, z int)
    51  
    52  	Release()
    53  }
    54  
    55  type ShaderSources struct {
    56  	Name      string
    57  	GLSL100ES string
    58  	GLSL300ES string
    59  	GLSL310ES string
    60  	GLSL130   string
    61  	GLSL150   string
    62  	HLSL      string
    63  	Uniforms  UniformsReflection
    64  	Inputs    []InputLocation
    65  	Textures  []TextureBinding
    66  }
    67  
    68  type UniformsReflection struct {
    69  	Blocks    []UniformBlock
    70  	Locations []UniformLocation
    71  	Size      int
    72  }
    73  
    74  type TextureBinding struct {
    75  	Name    string
    76  	Binding int
    77  }
    78  
    79  type UniformBlock struct {
    80  	Name    string
    81  	Binding int
    82  }
    83  
    84  type UniformLocation struct {
    85  	Name   string
    86  	Type   DataType
    87  	Size   int
    88  	Offset int
    89  }
    90  
    91  type InputLocation struct {
    92  	// For GLSL.
    93  	Name     string
    94  	Location int
    95  	// For HLSL.
    96  	Semantic      string
    97  	SemanticIndex int
    98  
    99  	Type DataType
   100  	Size int
   101  }
   102  
   103  // InputDesc describes a vertex attribute as laid out in a Buffer.
   104  type InputDesc struct {
   105  	Type DataType
   106  	Size int
   107  
   108  	Offset int
   109  }
   110  
   111  // InputLayout is the driver specific representation of the mapping
   112  // between Buffers and shader attributes.
   113  type InputLayout interface {
   114  	Release()
   115  }
   116  
   117  type AccessBits uint8
   118  
   119  type BlendFactor uint8
   120  
   121  type DrawMode uint8
   122  
   123  type TextureFilter uint8
   124  type TextureFormat uint8
   125  
   126  type BufferBinding uint8
   127  
   128  type DataType uint8
   129  
   130  type DepthFunc uint8
   131  
   132  type Features uint
   133  
   134  type Caps struct {
   135  	// BottomLeftOrigin is true if the driver has the origin in the lower left
   136  	// corner. The OpenGL driver returns true.
   137  	BottomLeftOrigin bool
   138  	Features         Features
   139  	MaxTextureSize   int
   140  }
   141  
   142  type Program interface {
   143  	Release()
   144  	SetStorageBuffer(binding int, buf Buffer)
   145  	SetVertexUniforms(buf Buffer)
   146  	SetFragmentUniforms(buf Buffer)
   147  }
   148  
   149  type Buffer interface {
   150  	Release()
   151  	Upload(data []byte)
   152  	Download(data []byte) error
   153  }
   154  
   155  type Framebuffer interface {
   156  	Invalidate()
   157  	Release()
   158  	ReadPixels(src image.Rectangle, pixels []byte) error
   159  }
   160  
   161  type Timer interface {
   162  	Begin()
   163  	End()
   164  	Duration() (time.Duration, bool)
   165  	Release()
   166  }
   167  
   168  type Texture interface {
   169  	Upload(offset, size image.Point, pixels []byte)
   170  	Release()
   171  }
   172  
   173  const (
   174  	DepthFuncGreater DepthFunc = iota
   175  	DepthFuncGreaterEqual
   176  )
   177  
   178  const (
   179  	DataTypeFloat DataType = iota
   180  	DataTypeInt
   181  	DataTypeShort
   182  )
   183  
   184  const (
   185  	BufferBindingIndices BufferBinding = 1 << iota
   186  	BufferBindingVertices
   187  	BufferBindingUniforms
   188  	BufferBindingTexture
   189  	BufferBindingFramebuffer
   190  	BufferBindingShaderStorage
   191  )
   192  
   193  const (
   194  	TextureFormatSRGB TextureFormat = iota
   195  	TextureFormatFloat
   196  	TextureFormatRGBA8
   197  )
   198  
   199  const (
   200  	AccessRead AccessBits = 1 + iota
   201  	AccessWrite
   202  )
   203  
   204  const (
   205  	FilterNearest TextureFilter = iota
   206  	FilterLinear
   207  )
   208  
   209  const (
   210  	FeatureTimers Features = 1 << iota
   211  	FeatureFloatRenderTargets
   212  	FeatureCompute
   213  )
   214  
   215  const (
   216  	DrawModeTriangleStrip DrawMode = iota
   217  	DrawModeTriangles
   218  )
   219  
   220  const (
   221  	BlendFactorOne BlendFactor = iota
   222  	BlendFactorOneMinusSrcAlpha
   223  	BlendFactorZero
   224  	BlendFactorDstColor
   225  )
   226  
   227  var ErrContentLost = errors.New("buffer content lost")
   228  
   229  func (f Features) Has(feats Features) bool {
   230  	return f&feats == feats
   231  }
   232  
   233  func DownloadImage(d Device, f Framebuffer, r image.Rectangle) (*image.RGBA, error) {
   234  	img := image.NewRGBA(r)
   235  	if err := f.ReadPixels(r, img.Pix); err != nil {
   236  		return nil, err
   237  	}
   238  	if d.Caps().BottomLeftOrigin {
   239  		// OpenGL origin is in the lower-left corner. Flip the image to
   240  		// match.
   241  		flipImageY(r.Dx()*4, r.Dy(), img.Pix)
   242  	}
   243  	return img, nil
   244  }
   245  
   246  func flipImageY(stride, height int, pixels []byte) {
   247  	// Flip image in y-direction. OpenGL's origin is in the lower
   248  	// left corner.
   249  	row := make([]uint8, stride)
   250  	for y := 0; y < height/2; y++ {
   251  		y1 := height - y - 1
   252  		dest := y1 * stride
   253  		src := y * stride
   254  		copy(row, pixels[dest:])
   255  		copy(pixels[dest:], pixels[src:src+len(row)])
   256  		copy(pixels[src:], row)
   257  	}
   258  }
   259  
   260  func UploadImage(t Texture, offset image.Point, img *image.RGBA) {
   261  	var pixels []byte
   262  	size := img.Bounds().Size()
   263  	if img.Stride != size.X*4 {
   264  		panic("unsupported stride")
   265  	}
   266  	start := img.PixOffset(0, 0)
   267  	end := img.PixOffset(size.X, size.Y-1)
   268  	pixels = img.Pix[start:end]
   269  	t.Upload(offset, size, pixels)
   270  }