mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-01 07:35:40 +00:00
gpu: return and handle errors from Backend.New... methods
"handling" means panicing, but at least the panicing is moved up a layer, leaving future changes to do it properly in GPU. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+3
-3
@@ -18,11 +18,11 @@ type Backend interface {
|
||||
// IsContinuousTime reports whether all timer measurements
|
||||
// are valid at the point of call.
|
||||
IsTimeContinuous() bool
|
||||
NewTexture(format TextureFormat, width, height int, minFilter, magFilter TextureFilter, bindings BufferBinding) Texture
|
||||
NewTexture(format TextureFormat, width, height int, minFilter, magFilter TextureFilter, bindings BufferBinding) (Texture, error)
|
||||
DefaultFramebuffer() Framebuffer
|
||||
NewFramebuffer(tex Texture) (Framebuffer, error)
|
||||
NewImmutableBuffer(typ BufferBinding, data []byte) Buffer
|
||||
NewBuffer(typ BufferBinding, size int) Buffer
|
||||
NewImmutableBuffer(typ BufferBinding, data []byte) (Buffer, error)
|
||||
NewBuffer(typ BufferBinding, size int) (Buffer, error)
|
||||
NewProgram(vertexShader, fragmentShader ShaderSources) (Program, error)
|
||||
NewInputLayout(vertexShader ShaderSources, layout []InputDesc) (InputLayout, error)
|
||||
|
||||
|
||||
+35
-8
@@ -163,10 +163,15 @@ func (b *Backend) IsTimeContinuous() bool {
|
||||
}
|
||||
|
||||
func (b *Backend) NewFramebuffer(tex gpu.Texture) (gpu.Framebuffer, error) {
|
||||
glErr(b.funcs)
|
||||
gltex := tex.(*gpuTexture)
|
||||
fb := b.funcs.CreateFramebuffer()
|
||||
fbo := &gpuFramebuffer{funcs: b.funcs, obj: fb}
|
||||
fbo.Bind()
|
||||
if err := glErr(b.funcs); err != nil {
|
||||
fbo.Release()
|
||||
return nil, err
|
||||
}
|
||||
b.funcs.FramebufferTexture2D(FRAMEBUFFER, COLOR_ATTACHMENT0, TEXTURE_2D, gltex.obj, 0)
|
||||
if st := b.funcs.CheckFramebufferStatus(FRAMEBUFFER); st != FRAMEBUFFER_COMPLETE {
|
||||
fbo.Release()
|
||||
@@ -179,7 +184,8 @@ func (b *Backend) DefaultFramebuffer() gpu.Framebuffer {
|
||||
return b.defFBO
|
||||
}
|
||||
|
||||
func (b *Backend) NewTexture(format gpu.TextureFormat, width, height int, minFilter, magFilter gpu.TextureFilter, binding gpu.BufferBinding) gpu.Texture {
|
||||
func (b *Backend) NewTexture(format gpu.TextureFormat, width, height int, minFilter, magFilter gpu.TextureFilter, binding gpu.BufferBinding) (gpu.Texture, error) {
|
||||
glErr(b.funcs)
|
||||
tex := &gpuTexture{backend: b, obj: b.funcs.CreateTexture()}
|
||||
switch format {
|
||||
case gpu.TextureFormatFloat:
|
||||
@@ -187,7 +193,7 @@ func (b *Backend) NewTexture(format gpu.TextureFormat, width, height int, minFil
|
||||
case gpu.TextureFormatSRGB:
|
||||
tex.triple = b.srgbaTriple
|
||||
default:
|
||||
panic("unsupported texture format")
|
||||
return nil, errors.New("unsupported texture format")
|
||||
}
|
||||
tex.Bind(0)
|
||||
b.funcs.TexParameteri(TEXTURE_2D, TEXTURE_MAG_FILTER, toTexFilter(magFilter))
|
||||
@@ -195,30 +201,51 @@ func (b *Backend) NewTexture(format gpu.TextureFormat, width, height int, minFil
|
||||
b.funcs.TexParameteri(TEXTURE_2D, TEXTURE_WRAP_S, CLAMP_TO_EDGE)
|
||||
b.funcs.TexParameteri(TEXTURE_2D, TEXTURE_WRAP_T, CLAMP_TO_EDGE)
|
||||
b.funcs.TexImage2D(TEXTURE_2D, 0, tex.triple.internalFormat, width, height, tex.triple.format, tex.triple.typ, nil)
|
||||
return tex
|
||||
if err := glErr(b.funcs); err != nil {
|
||||
tex.Release()
|
||||
return nil, err
|
||||
}
|
||||
return tex, nil
|
||||
}
|
||||
|
||||
func (b *Backend) NewBuffer(typ gpu.BufferBinding, size int) gpu.Buffer {
|
||||
func (b *Backend) NewBuffer(typ gpu.BufferBinding, size int) (gpu.Buffer, error) {
|
||||
glErr(b.funcs)
|
||||
buf := &gpuBuffer{backend: b, typ: typ, size: size}
|
||||
if typ&gpu.BufferBindingUniforms != 0 {
|
||||
if typ != gpu.BufferBindingUniforms {
|
||||
panic("uniforms buffers cannot be bound as anything else")
|
||||
return nil, errors.New("uniforms buffers cannot be bound as anything else")
|
||||
}
|
||||
// GLES 2 doesn't support uniform buffers.
|
||||
buf.data = make([]byte, size)
|
||||
}
|
||||
if typ&^gpu.BufferBindingUniforms != 0 {
|
||||
buf.obj = b.funcs.CreateBuffer()
|
||||
if err := glErr(b.funcs); err != nil {
|
||||
buf.Release()
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return buf
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
func (b *Backend) NewImmutableBuffer(typ gpu.BufferBinding, data []byte) gpu.Buffer {
|
||||
func (b *Backend) NewImmutableBuffer(typ gpu.BufferBinding, data []byte) (gpu.Buffer, error) {
|
||||
glErr(b.funcs)
|
||||
obj := b.funcs.CreateBuffer()
|
||||
buf := &gpuBuffer{backend: b, obj: obj, typ: typ, size: len(data)}
|
||||
buf.Upload(data)
|
||||
buf.immutable = true
|
||||
return buf
|
||||
if err := glErr(b.funcs); err != nil {
|
||||
buf.Release()
|
||||
return nil, err
|
||||
}
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
func glErr(f Functions) error {
|
||||
if st := f.GetError(); st != NO_ERROR {
|
||||
return fmt.Errorf("glGetError: %#x", st)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Backend) bindTexture(unit int, t *gpuTexture) {
|
||||
|
||||
+14
-4
@@ -378,8 +378,12 @@ func (r *renderer) texHandle(t *texture) Texture {
|
||||
if t.tex != nil {
|
||||
return t.tex
|
||||
}
|
||||
t.tex = r.ctx.NewTexture(TextureFormatSRGB, t.src.Bounds().Dx(), t.src.Bounds().Dy(), FilterLinear, FilterLinear, BufferBindingTexture)
|
||||
t.tex.Upload(t.src)
|
||||
tex, err := r.ctx.NewTexture(TextureFormatSRGB, t.src.Bounds().Dx(), t.src.Bounds().Dy(), FilterLinear, FilterLinear, BufferBindingTexture)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
tex.Upload(t.src)
|
||||
t.tex = tex
|
||||
return t.tex
|
||||
}
|
||||
|
||||
@@ -406,7 +410,7 @@ func (r *renderer) release() {
|
||||
}
|
||||
|
||||
func newBlitter(ctx Backend) *blitter {
|
||||
quadVerts := ctx.NewImmutableBuffer(BufferBindingVertices,
|
||||
quadVerts, err := ctx.NewImmutableBuffer(BufferBindingVertices,
|
||||
gunsafe.BytesView([]float32{
|
||||
-1, +1, 0, 0,
|
||||
+1, +1, 1, 0,
|
||||
@@ -414,6 +418,9 @@ func newBlitter(ctx Backend) *blitter {
|
||||
+1, -1, 1, 1,
|
||||
}),
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
b := &blitter{
|
||||
ctx: ctx,
|
||||
quadVerts: quadVerts,
|
||||
@@ -913,7 +920,10 @@ func newUniformBuffer(b Backend, uniformBlock interface{}) *uniformBuffer {
|
||||
size := ref.Elem().Type().Size()
|
||||
// Map the uniforms structure as a byte slice.
|
||||
ptr := (*[1 << 30]byte)(unsafe.Pointer(ref.Pointer()))[:size:size]
|
||||
ubuf := b.NewBuffer(BufferBindingUniforms, len(ptr))
|
||||
ubuf, err := b.NewBuffer(BufferBindingUniforms, len(ptr))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &uniformBuffer{buf: ubuf, ptr: ptr}
|
||||
}
|
||||
|
||||
|
||||
+12
-5
@@ -150,7 +150,10 @@ func newStenciler(ctx Backend) *stenciler {
|
||||
indices[i*6+4] = i*4 + 1
|
||||
indices[i*6+5] = i*4 + 3
|
||||
}
|
||||
indexBuf := ctx.NewImmutableBuffer(BufferBindingIndices, gunsafe.BytesView(indices))
|
||||
indexBuf, err := ctx.NewImmutableBuffer(BufferBindingIndices, gunsafe.BytesView(indices))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
progLayout, err := ctx.NewInputLayout(shader_stencil_vert, []InputDesc{
|
||||
{Type: DataTypeShort, Size: 2, Offset: int(unsafe.Offsetof((*(*path.Vertex)(nil)).CornerX))},
|
||||
{Type: DataTypeFloat, Size: 1, Offset: int(unsafe.Offsetof((*(*path.Vertex)(nil)).MaxY))},
|
||||
@@ -208,13 +211,14 @@ func (s *fboSet) resize(ctx Backend, sizes []image.Point) {
|
||||
f.fbo.Release()
|
||||
f.tex.Release()
|
||||
}
|
||||
f.size = sz
|
||||
f.tex = ctx.NewTexture(TextureFormatFloat, sz.X, sz.Y, FilterNearest, FilterNearest,
|
||||
tex, err := ctx.NewTexture(TextureFormatFloat, sz.X, sz.Y, FilterNearest, FilterNearest,
|
||||
BufferBindingTexture|BufferBindingFramebuffer)
|
||||
fbo, err := ctx.NewFramebuffer(f.tex)
|
||||
fbo, err := ctx.NewFramebuffer(tex)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
f.size = sz
|
||||
f.tex = tex
|
||||
f.fbo = fbo
|
||||
}
|
||||
}
|
||||
@@ -259,7 +263,10 @@ func (c *coverer) release() {
|
||||
}
|
||||
|
||||
func buildPath(ctx Backend, p []byte) *pathData {
|
||||
buf := ctx.NewImmutableBuffer(BufferBindingVertices, p)
|
||||
buf, err := ctx.NewImmutableBuffer(BufferBindingVertices, p)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &pathData{
|
||||
ncurves: len(p) / path.VertStride,
|
||||
data: buf,
|
||||
|
||||
Reference in New Issue
Block a user