From 18c74f00aff1b190d85e898fbf5af9e5147067e5 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Mon, 13 May 2019 12:44:47 +0200 Subject: [PATCH] ui/app/internal/gpu: check floating point FBO support Some devices don't support floating point FBOs even though they support OpenGL ES 3. Check support by creating a FBO and fail early if no support is found. Signed-off-by: Elias Naur --- ui/app/internal/gpu/context.go | 50 ++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/ui/app/internal/gpu/context.go b/ui/app/internal/gpu/context.go index de6964d4..2156d2a8 100644 --- a/ui/app/internal/gpu/context.go +++ b/ui/app/internal/gpu/context.go @@ -40,7 +40,7 @@ func newContext(glctx gl.Context) (*context, error) { if err != nil { return nil, err } - floatTriple, err := floatTripleFor(ver, exts) + floatTriple, err := floatTripleFor(ctx, ver, exts) if err != nil { return nil, err } @@ -57,6 +57,41 @@ func newContext(glctx gl.Context) (*context, error) { return ctx, nil } +// floatTripleFor determines the best texture triple for floating point FBOs. +func floatTripleFor(ctx *context, ver [2]int, exts []string) (textureTriple, error) { + var triples []textureTriple + if ver[0] >= 3 { + triples = append(triples, textureTriple{gl.R16F, gl.Enum(gl.RED), gl.Enum(gl.HALF_FLOAT)}) + } + if hasExtension(exts, "GL_OES_texture_half_float") || hasExtension(exts, "EXT_color_buffer_half_float") { + triples = append(triples, textureTriple{gl.RGBA, gl.Enum(gl.RGBA), gl.Enum(gl.HALF_FLOAT_OES)}) + } + if hasExtension(exts, "GL_OES_texture_float") || hasExtension(exts, "GL_EXT_color_buffer_float") { + triples = append(triples, textureTriple{gl.RGBA, gl.Enum(gl.RGBA), gl.Enum(gl.FLOAT)}) + } + tex := ctx.CreateTexture() + defer ctx.DeleteTexture(tex) + ctx.BindTexture(gl.TEXTURE_2D, tex) + ctx.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE) + ctx.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) + ctx.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST) + ctx.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST) + fbo := ctx.CreateFramebuffer() + defer ctx.DeleteFramebuffer(fbo) + defFBO := gl.Framebuffer(ctx.GetBinding(gl.FRAMEBUFFER_BINDING)) + ctx.BindFramebuffer(gl.FRAMEBUFFER, fbo) + defer ctx.BindFramebuffer(gl.FRAMEBUFFER, defFBO) + for _, tt := range triples { + const size = 256 + ctx.TexImage2D(gl.TEXTURE_2D, 0, tt.internalFormat, size, size, tt.format, tt.typ, nil) + ctx.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0) + if st := ctx.CheckFramebufferStatus(gl.FRAMEBUFFER); st == gl.FRAMEBUFFER_COMPLETE { + return tt, nil + } + } + return textureTriple{}, errors.New("floating point fbos not supported") +} + func srgbaTripleFor(ver [2]int, exts []string) (textureTriple, error) { switch { case ver[0] >= 3: @@ -77,19 +112,6 @@ func alphaTripleFor(ver [2]int) textureTriple { return textureTriple{intf, f, gl.UNSIGNED_BYTE} } -func floatTripleFor(ver [2]int, exts []string) (textureTriple, error) { - switch { - case ver[0] >= 3: - return textureTriple{gl.R16F, gl.Enum(gl.RED), gl.Enum(gl.HALF_FLOAT)}, nil - case hasExtension(exts, "GL_OES_texture_half_float") || hasExtension(exts, "EXT_color_buffer_half_float"): - return textureTriple{gl.RGBA, gl.Enum(gl.RGBA), gl.Enum(gl.HALF_FLOAT_OES)}, nil - case hasExtension(exts, "GL_OES_texture_float") || hasExtension(exts, "GL_EXT_color_buffer_float"): - return textureTriple{gl.RGBA, gl.Enum(gl.RGBA), gl.Enum(gl.FLOAT)}, nil - default: - return textureTriple{}, errors.New("floating point texture not supported") - } -} - func hasExtension(exts []string, ext string) bool { for _, e := range exts { if ext == e {