Commit Graph

69 Commits

Author SHA1 Message Date
Elias Naur cc2edbaa51 gpu: introduce render passes
Modern GPU API such as Metal and Vulkan use explicit render passes
and command buffers for recording rendering commands. They don't have
global state; each render pass starts with a clean set of bound
textures, pipeline etc.

Change our GPU abstraction to better match newer API and modify our two
renderers to explicitly describe their render passes.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-20 15:13:00 +02:00
Elias Naur 9e6ed3cb96 gpu/internal/rendertest: clean up headless context immediately
GPU contexts can hold on to a significant amount of resources. Clean
them up immediately instead of at test cleanup.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-20 15:13:00 +02:00
Elias Naur f842178ac7 gpu/internal/metal: don't copy padding during images transfers
Don't copy the padding when stride is larger than the width. Applies to
Texture.Upload and Framebuffer.ReadPixels.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-20 15:13:00 +02:00
Elias Naur da1c4a60e0 gpu/internal/rendertest: only dump images when -saveimages is set
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-20 15:13:00 +02:00
Elias Naur f896a72ea1 app,gpu/internal/opengl: move glFlush to macOS context present
A previous change[0] moved all OpenGL function calls to the internal
opengl package, so that Gio can use desktop OpenGL and OpenGL ES (ANGLE)
in the same program without confusing the function pointers.

However the change also moved the glFlush that constitutes a buffer
swap, or present, on macOS. Other platforms don't need the flush, so
this change moves it back to macOS-specific code, in glContext.Present
where it belongs. It also uses dlopen and dlsym to avoid symbol
confusion between Apple's OpenGL framework and ANGLE's libGLESv2.dylib.

The motivation is that we're getting rid of the desktop OpenGL backend
on macOS in favor of Metal, and so should reduce the number of global
special-cases catering to that platform.

[0] https://gioui.org/commit/476d2269a

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-15 21:12:29 +02:00
Elias Naur bde046de54 gpu/internal/opengl: avoid PACK/UNPACK_ROW_LENGTH on WebGL 1
Fixes gio#259

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-05 13:58:19 +02:00
Elias Naur 1362acb85a gpu/internal/d3d11,internal/d3d11: add DirectCompute support
This change implements support for compute programs in the Direct3D 11
driver. The compute renderer doesn't work for me yet; my NVIDIA GTX 970
and Intel GPUs both display corrupted output and hangs.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-28 16:13:06 +02:00
Elias Naur e841288b88 gpu/internal/d3d11: introduce newBuffer for common buffer creation
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-28 13:32:35 +01:00
Elias Naur d724f61d06 gpu/internal/d3d11: fix partial uploads in Buffer.Upload
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-28 12:38:00 +01:00
Elias Naur 32a4885c00 gpu/internal: fix AccessBits to be a bitset and support read+write
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-28 10:41:00 +02:00
Elias Naur 7f6e376424 gpu,gpu/internal: support variable strides in ReadPixels
It saves a roundtrip to scratch memory when the CPU fallback renderer
downloads rendered materials.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-27 12:59:01 +02:00
Elias Naur b9ede6d735 gpu/internal/opengl,internal/gl: avoid glBufferSubData after glBufferData
On my Fedora Intel GPU, issuing a glBufferSubData immediately after a
glBufferData with no data may leave the buffer cleared.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-25 14:29:09 +02:00
Elias Naur 7acc031ccf gpu/internal/metal: merge buffer address and size calls
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-23 17:56:57 +02:00
Elias Naur b47653b808 gpu/internal/metal: don't double-buffer staging memory
One staging buffer is enough because BeginFrame waits for the completion
of the staging operatoins from the previous frame.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-23 17:48:59 +02:00
Elias Naur 43a7030f6e gpu/internal/metal: use optimal CPU cache mode for staging buffers
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-22 17:46:28 +02:00
Elias Naur 0d009bd534 gpu/internal/d3d11: remove unused method
Invalidate is no longer part of the driver contract.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-22 09:34:17 +02:00
Elias Naur 6ee8a1cb7c gpu/internal/opengl: avoid crash when uniform buffers are not supported
Found by Dan Kortschak.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-21 16:06:45 +02:00
Elias Naur c9970cb8e3 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 <mail@eliasnaur.com>
2021-08-21 11:16:28 +02:00
Elias Naur 3b2992c37e gpu,app/internal/wm: add Metal port
The OpenGL (ES) implementations on Apple platforms are deprecated and
don't support GPU compute programs. This change adds support for the
replacement, the Metal GPU API.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-21 08:31:46 +02:00
Elias Naur a7f08eedf3 gpu,gpu/internal: split shader storage usage into read and write
Metal has texture write usage flags for read and write.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-21 08:31:46 +02:00
Elias Naur 07fdc1a2de gpu,gpu/internal: drop implied transformation from BlitFramebuffer
The Metal (and presumably the D3D11) backend doesn't support transformed
framebuffer blits. The only caller doesn't need it either, so drop that
capability from the driver abstraction.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-21 08:31:46 +02:00
Elias Naur 58cc817e5f gpu,gpu/internal: move vertex buffer stride to pipeline state
Metal needs the vertex stride at pipeline creation.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-21 08:31:46 +02:00
Elias Naur 1af910959b gpu: fold buffer clearing into framebuffer bind
In Metal, clearing a framebuffer is most efficiently done during bind.
Modify our driver accordingly.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-21 08:31:46 +02:00
Elias Naur d38c78d7ac gpu,gpu/internal: move InputDesc back from gioui.org/shader module
It was moved to gioui.org/shader by mistake.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-21 08:31:46 +02:00
Elias Naur afaa31eca8 gpu: introduce pipeline abstraction
Modern API such as Metal and Vulkan want clients to compile expensive
state changes into pipeline objects. Change our GPU driver abstraction
to match, thereby paving the way for future drivers.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-21 08:31:46 +02:00
Elias Naur f475087296 gpu/internal/opengl: handle switch from non-sRGB output to sRGB output
The opengl example has a screenshot functionality that renders to a
non-sRGB texture, whereas window rendering is to a sRGB capable EGL
surface. The opengl driver detects the switch from an sRGB capable
output to a non-sRGB capable output, but not the switch back. This
change releases the emulation framebuffer on the switch back.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-19 10:25:05 +02:00
Elias Naur 8d8bc19c23 gpu/internal/opengl: remove "gpu" prefix from type names
Refactor only.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-16 15:47:23 +02:00
Elias Naur 6aee543234 all: switch to external shaders in the gioui.org/shaders module
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-08 13:47:41 +01:00
Elias Naur 18b4442393 all: remove Z buffer support
It is no longer needed by any rendering backend.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-08 13:47:37 +01:00
Elias Naur 7d84e419c9 gpu,gpu/headless,app/internal/wm: add explicit RenderTarget API
Both the OpenGL and the Direct3D API are stateful and gpu.GPU renders to
the render target current when Frame is called.

Modern GPU API such as Metal don't have a concept of a current render
target, and the target even changes each frame.

Add RenderTarget and add an explicit target argument to GPU.Frame as
well as the underlying driver.Device.BeginFrame.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-08 13:45:23 +01:00
Elias Naur d8f8740574 gpu/internal/opengl: use the linear colorspace when EXT_sRGB is missing
The SRGBFBO emulates a framebuffer in the sRGB colorspace. However, some
low-end devices may not have EXT_sRGB support to store framebuffer content in
sRGB.

This change handles missing EXT_sRGB support by falling back to the linear RGB colorspace.
Falling back loses color precision but is better than failing.

Updates gio#49
Updates gio#154
Updates gio#97
Updates gio#36
Updates gio#172

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-07-29 08:37:59 +02:00
Elias Naur 68fa64dfd5 gpu/internal/opengl: detect sRGB triple in terms of srgbaTripleFor
Refactor in preparation for relaxing sRGB format requirements.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-07-29 08:37:59 +02:00
Elias Naur 970fadf852 gpu/internal/driver: introduce and use FeatureSRGB
No functional changes; a follow-up will implement graceful fallback in
the compute renderer.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-07-29 08:37:59 +02:00
Elias Naur b3a8c24334 gpu/internal/driver: rename TextureFormatSRGB to TextureFormatSRGBA
The format implies an alpha channel; name it accordingly.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-07-29 08:37:18 +02:00
Elias Naur f14c151883 gpu,gpu/internal: generate hashes of compute programs
The CPU fallback for the compute renderer is contained in a separate
module for space reasons, but the CPU binaries must exactly match the
compute programs. However, there is no way to express that constraint
in go.mod.

This change generates hashes of every compute program so that a
following change can verify the CPU binaries match the programs.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-07-27 14:34:18 +02:00
Elias Naur 60a47e7de5 gpu/internal,internal/gl: add support for strided texture uploads
The CPU fallback of the compute renderer needs to upload subtextures
from a larger image.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-07-27 14:34:18 +02:00
Elias Naur abfbeb87cc gpu/internal/d3d11: stub BlitFramebuffer for D3D11
The compute renderer doesn't run on Windows yet, but the d3d11 backend needs
the method to satisfy the driver interface.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-07-27 14:34:18 +02:00
Elias Naur 75c9736708 op/paint: skip zero images
Updates gio#235

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-06-16 12:01:42 +02:00
Elias Naur 9b5e9ae607 gpu/internal/opengl: restore BeginFrame state in EndFrame
To ease the integration with foreign OpenGL contexts, carefully save the
context state before rendering a frame and restore it afterwards. Gio
rendering can then be mixed with OpenGL code that expects exclusive
control over context state.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-06-11 21:02:18 +02:00
Elias Naur 476d2269a6 gpu/internal/opengl,app/internal/wm: generalize desktop OpenGL support
This changes moves the macOS specific setup for desktop OpenGL to the
portable opengl package. The opengl package already takes care of the
desktop OpenGL setup for sRGB framebuffers, and by moving the code we
avoid calling the wrong OpenGL functions in case both OpenGL.framework
and ANGLE libGLESv2.dylib is linked into the program.

Remove the interface casting expressions for gl.Functions; it wasn't
worth the trouble to keep updated.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-06-01 18:26:11 +02:00
Elias Naur 03ee75fd72 gpu/internal/opengl: support sRGB emulation for desktop OpenGL
Desktop OpenGL implements a GL_FRAMEBUFFER_SRGB setting; query that instead
of the frambuffer color encoding.

With this change it is no longer necessary to enable FRAMEBUFFER_SRGB
in the macOS setup; remove it.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-05-18 14:26:45 +01:00
Elias Naur b622412ac6 gpu: support forced OpenGL ES mode, for ANGLE on macOS
macOS is the only platform where desktop OpenGL is used. To support
foreign ANGLE contexts add a setting to override Gio's selection of
OpenGL implementation.

The bulk of this change is making all function pointers per-context
instead of global, and loading the OpenGL library dynamically. As a side
effect we're closer to Gio tolerating a platform without any OpenGL
implementation. For example, Apple has deprecated OpenGL and OpenGL ES
on its platforms and may remove them in the future.

Note that as a side-effect of this change, Gio needs Go 1.16 or newer to
run on iOS.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-05-18 14:26:45 +01:00
Elias Naur 39775f555a gp/internal/opengl: support sRGB emulation for embedded content
Programs such as gio-example/glfw rely on Gio drawing blending with
the framebuffer background. This change makes it so when sRGB emulation
is active.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-05-16 18:17:00 +02:00
Elias Naur 566b4b166b gpu/internal/opengl: remove unused type alias
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-05-16 11:18:42 +02:00
Elias Naur 21c319ace5 gpu/internal/opengl,internal: move sRGB emulation to OpenGL driver
There is only one driver but several backends (EGL, WebGL).

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-05-16 10:44:45 +02:00
Elias Naur 2c07b2dc0e headless: clear background to transparent, not white
The clear background is the most useful, and the old behaviour can
be achieved by filling the entire viewport with a white paint.ColorOp.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-05-03 11:31:45 +02:00
Elias Naur 3b69b5ed05 gpu/internal/opengl: fix package name
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-04-18 17:16:03 +02:00
Elias Naur 9bf4e559bc gpu/internal/opengl: use uniform blocks on macOS
The reflected uniform names are for the shader versions that don't use uniform
buffer objects. For UBO shaders, the names won't resolve.

This change adds a panic when shader uniforms are not found, and fixes

Fixes gio#216

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-04-17 11:10:33 +02:00
Elias Naur c19ce8e1d7 gpu/internal/convertshaders: don't require GL_ARB_shading_language_420pack
It's not supported on macOS.

Updates gio#216

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-04-17 11:10:20 +02:00
Elias Naur e9a020f774 gpu/internal/convertshaders: build compute shaders in HLSL cs_5_0 profile
The recent changes to the compute shaders have fixed all errors
previously reported by fxc. Switch from dxc to fxc to target shader
model 5.0, supported by Direct3D 11.

Because we know dxc must be available, always build compute shaders even
though the result is not yet used.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-04-12 12:49:49 +02:00