From c9970cb8e3aa1b26b981b85c3a185c03bc614820 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Sat, 21 Aug 2021 11:11:38 +0200 Subject: [PATCH] gpu,gpu/internal,internal/gl: replace BlitFramebuffer with CopyTexture OpenGL ES 2.0 doesn't support glBlitFramebuffer, but does support glCopyTexSubImage2D. Fortunately, we don't need the extra features of glBlitFramebuffer anyway. Signed-off-by: Elias Naur --- gpu/compute.go | 4 ++-- gpu/internal/d3d11/d3d11_windows.go | 2 +- gpu/internal/driver/driver.go | 2 +- gpu/internal/metal/metal_darwin.go | 4 ++-- gpu/internal/opengl/opengl.go | 17 +++++++++-------- internal/gl/gl_js.go | 6 +++--- internal/gl/gl_unix.go | 10 ++++++++++ internal/gl/gl_windows.go | 7 ++++--- 8 files changed, 32 insertions(+), 20 deletions(-) diff --git a/gpu/compute.go b/gpu/compute.go index 570229bd..0d8582db 100644 --- a/gpu/compute.go +++ b/gpu/compute.go @@ -692,10 +692,10 @@ func (g *compute) compactLayers() error { continue } src := l.place.atlas.fbo - dst := atlas.fbo + dst := atlas.image sz := l.rect.Size() sr := image.Rectangle{Min: l.place.pos, Max: l.place.pos.Add(sz)} - g.ctx.BlitFramebuffer(dst, src, sr, l.newPlace.pos) + g.ctx.CopyTexture(dst, l.newPlace.pos, src, sr) l.place.atlas.layers-- layers[i].place = l.newPlace } diff --git a/gpu/internal/d3d11/d3d11_windows.go b/gpu/internal/d3d11/d3d11_windows.go index 3339b40a..11810a7e 100644 --- a/gpu/internal/d3d11/d3d11_windows.go +++ b/gpu/internal/d3d11/d3d11_windows.go @@ -165,7 +165,7 @@ func (b *Backend) BeginFrame(target driver.RenderTarget, clear bool, viewport im return &Framebuffer{ctx: b.ctx, dev: b.dev, renderTarget: renderTarget, foreign: true} } -func (b *Backend) BlitFramebuffer(dst, src driver.Framebuffer, srect image.Rectangle, dorigin image.Point) { +func (b *Backend) CopyTexture(dst driver.Texture, dstOrigin image.Point, src driver.Framebuffer, srcRect image.Rectangle) { panic("not implemented") } diff --git a/gpu/internal/driver/driver.go b/gpu/internal/driver/driver.go index f272e66b..51ecf0f8 100644 --- a/gpu/internal/driver/driver.go +++ b/gpu/internal/driver/driver.go @@ -45,7 +45,7 @@ type Device interface { BindFragmentUniforms(buf Buffer) BindStorageBuffer(binding int, buf Buffer) - BlitFramebuffer(dst, src Framebuffer, srcRect image.Rectangle, dstOrigin image.Point) + CopyTexture(dst Texture, dstOrigin image.Point, src Framebuffer, srcRect image.Rectangle) MemoryBarrier() DispatchCompute(x, y, z int) diff --git a/gpu/internal/metal/metal_darwin.go b/gpu/internal/metal/metal_darwin.go index 38b17730..808031fb 100644 --- a/gpu/internal/metal/metal_darwin.go +++ b/gpu/internal/metal/metal_darwin.go @@ -524,9 +524,9 @@ func (b *Backend) startBlit() C.CFTypeRef { return b.blitEnc } -func (b *Backend) BlitFramebuffer(dst, src driver.Framebuffer, srect image.Rectangle, dorig image.Point) { +func (b *Backend) CopyTexture(dst driver.Texture, dorig image.Point, src driver.Framebuffer, srect image.Rectangle) { enc := b.startBlit() - dstTex := dst.(*Framebuffer).texture + dstTex := dst.(*Texture).texture srcTex := src.(*Framebuffer).texture ssz := srect.Size() C.blitEncCopyFromTexture( diff --git a/gpu/internal/opengl/opengl.go b/gpu/internal/opengl/opengl.go index 788c1e1d..9c391f46 100644 --- a/gpu/internal/opengl/opengl.go +++ b/gpu/internal/opengl/opengl.go @@ -1166,15 +1166,16 @@ func (b *Backend) BindIndexBuffer(buf driver.Buffer) { b.glstate.bindBuffer(b.funcs, gl.ELEMENT_ARRAY_BUFFER, gbuf.obj) } -func (b *Backend) BlitFramebuffer(dst, src driver.Framebuffer, srect image.Rectangle, dorig image.Point) { - b.glstate.bindFramebuffer(b.funcs, gl.DRAW_FRAMEBUFFER, dst.(*framebuffer).obj) +func (b *Backend) CopyTexture(dst driver.Texture, dstOrigin image.Point, src driver.Framebuffer, srcRect image.Rectangle) { + const unit = 0 + oldTex := b.glstate.texUnits.binds[unit] + defer func() { + b.glstate.bindTexture(b.funcs, unit, oldTex) + }() + b.glstate.bindTexture(b.funcs, unit, dst.(*texture).obj) b.glstate.bindFramebuffer(b.funcs, gl.READ_FRAMEBUFFER, src.(*framebuffer).obj) - drect := image.Rectangle{Min: dorig, Max: dorig.Add(srect.Size())} - b.funcs.BlitFramebuffer( - srect.Min.X, srect.Min.Y, srect.Max.X, srect.Max.Y, - drect.Min.X, drect.Min.Y, drect.Max.X, drect.Max.Y, - gl.COLOR_BUFFER_BIT, - gl.NEAREST) + sz := srcRect.Size() + b.funcs.CopyTexSubImage2D(gl.TEXTURE_2D, 0, dstOrigin.X, dstOrigin.Y, srcRect.Min.X, srcRect.Min.Y, sz.X, sz.Y) } func (f *framebuffer) ReadPixels(src image.Rectangle, pixels []byte) error { diff --git a/internal/gl/gl_js.go b/internal/gl/gl_js.go index f071be9d..7c2314d3 100644 --- a/internal/gl/gl_js.go +++ b/internal/gl/gl_js.go @@ -104,9 +104,6 @@ func (f *Functions) BlendEquation(mode Enum) { func (f *Functions) BlendFuncSeparate(srcRGB, dstRGB, srcA, dstA Enum) { f.Ctx.Call("blendFunc", int(srcRGB), int(dstRGB), int(srcA), int(dstA)) } -func (f *Functions) BlitFramebuffer(sx0, sy0, sx1, sy1, dx0, dy0, dx1, dy1 int, mask Enum, filter Enum) { - panic("not implemented") -} func (f *Functions) BufferData(target Enum, size int, usage Enum) { f.Ctx.Call("bufferData", int(target), size, int(usage)) } @@ -128,6 +125,9 @@ func (f *Functions) ClearDepthf(d float32) { func (f *Functions) CompileShader(s Shader) { f.Ctx.Call("compileShader", js.Value(s)) } +func (f *Functions) CopyTexSubImage2D(target Enum, level, xoffset, yoffset, x, y, width, height int) { + f.Ctx.Call("copyTexSubImage2D", int(target), level, xoffset, yoffset, x, y, width, height) +} func (f *Functions) CreateBuffer() Buffer { return Buffer(f.Ctx.Call("createBuffer")) } diff --git a/internal/gl/gl_unix.go b/internal/gl/gl_unix.go index bbef5213..4dd2c144 100644 --- a/internal/gl/gl_unix.go +++ b/internal/gl/gl_unix.go @@ -51,6 +51,7 @@ typedef struct { void (*glClearColor)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); void (*glClearDepthf)(GLfloat d); void (*glCompileShader)(GLuint shader); + void (*glCopyTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); GLuint (*glCreateProgram)(void); GLuint (*glCreateShader)(GLenum type); void (*glDeleteBuffers)(GLsizei n, const GLuint *buffers); @@ -199,6 +200,10 @@ static void glCompileShader(glFunctions *f, GLuint shader) { f->glCompileShader(shader); } +static void glCopyTexSubImage2D(glFunctions *f, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { + f->glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); +} + static GLuint glCreateProgram(glFunctions *f) { return f->glCreateProgram(); } @@ -606,6 +611,7 @@ func (f *Functions) load(forceES bool) error { f.f.glClearColor = must("glClearColor") f.f.glClearDepthf = must("glClearDepthf") f.f.glCompileShader = must("glCompileShader") + f.f.glCopyTexSubImage2D = must("glCopyTexSubImage2D") f.f.glCreateProgram = must("glCreateProgram") f.f.glCreateShader = must("glCreateShader") f.f.glDeleteBuffers = must("glDeleteBuffers") @@ -808,6 +814,10 @@ func (f *Functions) CompileShader(s Shader) { C.glCompileShader(&f.f, C.GLuint(s.V)) } +func (f *Functions) CopyTexSubImage2D(target Enum, level, xoffset, yoffset, x, y, width, height int) { + C.glCopyTexSubImage2D(&f.f, C.GLenum(target), C.GLint(level), C.GLint(xoffset), C.GLint(yoffset), C.GLint(x), C.GLint(y), C.GLsizei(width), C.GLsizei(height)) +} + func (f *Functions) CreateBuffer() Buffer { C.glGenBuffers(&f.f, 1, &f.uints[0]) return Buffer{uint(f.uints[0])} diff --git a/internal/gl/gl_windows.go b/internal/gl/gl_windows.go index 518f6081..c92a44fb 100644 --- a/internal/gl/gl_windows.go +++ b/internal/gl/gl_windows.go @@ -34,6 +34,7 @@ var ( _glDeleteQueries = LibGLESv2.NewProc("glDeleteQueries") _glDeleteVertexArrays = LibGLESv2.NewProc("glDeleteVertexArrays") _glCompileShader = LibGLESv2.NewProc("glCompileShader") + _glCopyTexSubImage2D = LibGLESv2.NewProc("glCopyTexSubImage2D") _glGenBuffers = LibGLESv2.NewProc("glGenBuffers") _glGenFramebuffers = LibGLESv2.NewProc("glGenFramebuffers") _glGenVertexArrays = LibGLESv2.NewProc("glGenVertexArrays") @@ -158,9 +159,6 @@ func (c *Functions) BlendEquation(mode Enum) { func (c *Functions) BlendFuncSeparate(srcRGB, dstRGB, srcA, dstA Enum) { syscall.Syscall6(_glBlendFuncSeparate.Addr(), 4, uintptr(srcRGB), uintptr(dstRGB), uintptr(srcA), uintptr(dstA), 0, 0) } -func (f *Functions) BlitFramebuffer(sx0, sy0, sx1, sy1, dx0, dy0, dx1, dy1 int, mask Enum, filter Enum) { - panic("not implemented") -} func (c *Functions) BufferData(target Enum, size int, usage Enum) { syscall.Syscall6(_glBufferData.Addr(), 4, uintptr(target), uintptr(size), 0, uintptr(usage), 0, 0) } @@ -187,6 +185,9 @@ func (c *Functions) ClearDepthf(d float32) { func (c *Functions) CompileShader(s Shader) { syscall.Syscall(_glCompileShader.Addr(), 1, uintptr(s.V), 0, 0) } +func (f *Functions) CopyTexSubImage2D(target Enum, level, xoffset, yoffset, x, y, width, height int) { + syscall.Syscall9(_glCopyTexSubImage2D.Addr(), 8, uintptr(target), uintptr(level), uintptr(xoffset), uintptr(yoffset), uintptr(x), uintptr(y), uintptr(width), uintptr(height), 0) +} func (c *Functions) CreateBuffer() Buffer { var buf uintptr syscall.Syscall(_glGenBuffers.Addr(), 2, 1, uintptr(unsafe.Pointer(&buf)), 0)