diff --git a/gpu/internal/opengl/opengl.go b/gpu/internal/opengl/opengl.go index 8d145cd7..cab30ee1 100644 --- a/gpu/internal/opengl/opengl.go +++ b/gpu/internal/opengl/opengl.go @@ -716,7 +716,7 @@ func (b *Backend) NewBuffer(typ driver.BufferBinding, size int) (driver.Buffer, } firstBinding := firstBufferType(typ) b.glstate.bindBuffer(b.funcs, firstBinding, buf.obj) - b.funcs.BufferData(firstBinding, size, gl.DYNAMIC_DRAW) + b.funcs.BufferData(firstBinding, size, gl.DYNAMIC_DRAW, nil) } return buf, nil } @@ -727,8 +727,7 @@ func (b *Backend) NewImmutableBuffer(typ driver.BufferBinding, data []byte) (dri buf := &buffer{backend: b, obj: obj, typ: typ, size: len(data), hasBuffer: true} firstBinding := firstBufferType(typ) b.glstate.bindBuffer(b.funcs, firstBinding, buf.obj) - b.funcs.BufferData(firstBinding, len(data), gl.STATIC_DRAW) - buf.Upload(data) + b.funcs.BufferData(firstBinding, len(data), gl.STATIC_DRAW, data) buf.immutable = true if err := glErr(b.funcs); err != nil { buf.Release() @@ -1090,9 +1089,10 @@ func (b *buffer) Upload(data []byte) { // the iOS GL implementation doesn't recognize when BufferSubData // clears the entire buffer. Tell it and avoid GPU stalls. // See also https://github.com/godotengine/godot/issues/23956. - b.backend.funcs.BufferData(firstBinding, b.size, gl.DYNAMIC_DRAW) + b.backend.funcs.BufferData(firstBinding, b.size, gl.DYNAMIC_DRAW, data) + } else { + b.backend.funcs.BufferSubData(firstBinding, 0, data) } - b.backend.funcs.BufferSubData(firstBinding, 0, data) } } diff --git a/gpu/internal/opengl/srgb.go b/gpu/internal/opengl/srgb.go index 1c5b528a..4871d946 100644 --- a/gpu/internal/opengl/srgb.go +++ b/gpu/internal/opengl/srgb.go @@ -72,8 +72,7 @@ func (s *SRGBFBO) Blit() { -1, -1, 0, 0, +1, -1, 1, 0, }) - s.c.BufferData(gl.ARRAY_BUFFER, len(coords), gl.STATIC_DRAW) - s.c.BufferSubData(gl.ARRAY_BUFFER, 0, coords) + s.c.BufferData(gl.ARRAY_BUFFER, len(coords), gl.STATIC_DRAW, coords) s.blitted = true } s.state.useProgram(s.c, s.prog) diff --git a/internal/gl/gl_js.go b/internal/gl/gl_js.go index 7c2314d3..a1c91d89 100644 --- a/internal/gl/gl_js.go +++ b/internal/gl/gl_js.go @@ -104,8 +104,15 @@ 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) BufferData(target Enum, size int, usage Enum) { - f.Ctx.Call("bufferData", int(target), size, int(usage)) +func (f *Functions) BufferData(target Enum, size int, usage Enum, data []byte) { + if data == nil { + f.Ctx.Call("bufferData", int(target), size, int(usage)) + } else { + if len(data) != size { + panic("size mismatch") + } + f.Ctx.Call("bufferData", int(target), f.byteArrayOf(data), int(usage)) + } } func (f *Functions) BufferSubData(target Enum, offset int, src []byte) { f.Ctx.Call("bufferSubData", int(target), offset, f.byteArrayOf(src)) diff --git a/internal/gl/gl_unix.go b/internal/gl/gl_unix.go index 4dd2c144..fc8c8013 100644 --- a/internal/gl/gl_unix.go +++ b/internal/gl/gl_unix.go @@ -782,8 +782,12 @@ func (f *Functions) BlitFramebuffer(sx0, sy0, sx1, sy1, dx0, dy0, dx1, dy1 int, ) } -func (f *Functions) BufferData(target Enum, size int, usage Enum) { - C.glBufferData(&f.f, C.GLenum(target), C.GLsizeiptr(size), nil, C.GLenum(usage)) +func (f *Functions) BufferData(target Enum, size int, usage Enum, data []byte) { + var p unsafe.Pointer + if len(data) > 0 { + p = unsafe.Pointer(&data[0]) + } + C.glBufferData(&f.f, C.GLenum(target), C.GLsizeiptr(size), p, C.GLenum(usage)) } func (f *Functions) BufferSubData(target Enum, offset int, src []byte) { diff --git a/internal/gl/gl_windows.go b/internal/gl/gl_windows.go index c92a44fb..99b16942 100644 --- a/internal/gl/gl_windows.go +++ b/internal/gl/gl_windows.go @@ -159,8 +159,12 @@ 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 (c *Functions) BufferData(target Enum, size int, usage Enum) { - syscall.Syscall6(_glBufferData.Addr(), 4, uintptr(target), uintptr(size), 0, uintptr(usage), 0, 0) +func (c *Functions) BufferData(target Enum, size int, usage Enum, data []byte) { + var p unsafe.Pointer + if len(data) > 0 { + p = unsafe.Pointer(&data[0]) + } + syscall.Syscall6(_glBufferData.Addr(), 4, uintptr(target), uintptr(size), uintptr(p), uintptr(usage), 0, 0) } func (f *Functions) BufferSubData(target Enum, offset int, src []byte) { if n := len(src); n > 0 {