mesa/src
Alyssa Rosenzweig 6b22a02f90 asahi,agx: Implement buffer textures with gnarly NIR
Implement buffer textures in full generality.  There are a few issues here:

* OpenGL requires buffer textures support a minimum size of 65536 elements,
  however 1D textures in AGX are (at most) 8192 elements.

* OpenGL 4.0 (and OpenGL ES) require buffer textures to support the "RGB32"
  texture formats. These are 3 packed channels of 32-bits each. In general,
  non-power-of-two texel sizes are problematic. AGX does not support any such
  formats and we rely on the GL frontend to lower to a padded format (RGBX) if
  necessary. Such a lowering cannot work for buffer textures, however, so we
  need to find a way to implement RGB32 buffer textures.

We solve these issues in the follow way:

* Use 2D texture descriptors for buffer textures, with a large fixed
  power-of-two size along one axis. Then large texel indices may be accessed at
  a small vec2 texel coordinate, and since the fixed dimension is a
  power-of-two, that vector may be recovered by simply shifting and masking.
  This effectively avoids size restriction. We do need to clamp texel indices to
  the buffer size to avoid faulting on OOB reads, since we may read past the end
  of the buffer (if the app binds a non-page-aligned offset into the buffer).

* Use a general purpose memory load for RGB32 buffer textures. Lower the texture
  load instruction to a memory load from the buffer and some address arithmetic.
  There's no format conversion needed for RGB32, other than maybe filling in a
  format-appropriate alpha, so this is straightforward. Again, we need to clamp
  the texel index for robustness with OOB reads.

Each of these solutions brings its own problem.

* Using 2D textures instead of 1D requires physically rounding up the buffer
  size when packing the descriptor, so we can no longer implement textureSize()
  by reading off the texture descriptor like normal.

* We don't know at compile-time whether a given texture load will read from an
  RGB32 buffer texture or not, so we need to emit code for both. In Vulkan, we
  can't key the shader to this property, either, since it's descriptor set state
  and not pipeline state.

And each of these problems in turn brings its own solution:

* The texture descriptor is linear, so the "compression buffer address" field is
  ignored by the hardware. We stash the real buffer size there so that
  textureSize becomes a load from the texture descriptor like usual, without
  requiring a sideband (which would complicate bindless textures).

* If we determine a texture descriptor contains RGB32 data, then it will never
  be interpreted by the hardware and hence does not need to be a valid texture
  descriptor. So, we extend the hardware's format enum to contain a
  software-defined RGB32 format enum. Then, when lowering texture buffer loads,
  we either read it as a typed RGB32 memory load or as a texture load depending
  on the value of the format field in the texture descriptor.

All of this is accomplished with a big NIR pass generating a pile of strange
looking code. But it should be good enough in practice for this silly feature.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21672>
2023-03-11 02:26:31 +00:00
..
amd radv: set RADEON_FLAG_GTT_WC for external mem on vram 2023-03-09 22:21:09 +00:00
android_stub util/log: improve logger_android 2023-02-22 17:55:40 +00:00
asahi asahi,agx: Implement buffer textures with gnarly NIR 2023-03-11 02:26:31 +00:00
broadcom v3dv: split out broadcom_shader_stage_to_gl() calls to improve readability 2023-03-10 10:38:43 +00:00
c11 c11: Remove _MTX_INITIALIZER_NP for windows 2022-11-09 04:38:28 +00:00
compiler nir/lower_int64: Optionally lower ufind_msb using uadd_sat 2023-03-10 15:27:17 +00:00
drm-shim drm-shim: Use hide_drm_device_path() to hide other drm devices 2022-12-30 15:51:11 -08:00
egl egl/wayland: Fix destruction of event queue with proxies still attached. 2023-03-02 18:32:02 +00:00
etnaviv ci/etnaviv: Drop the dEQP-GLES2.functional.uniform_api.random.94 xfail. 2023-03-07 21:03:33 +00:00
freedreno ci/fdno: Add a618 Vulkan flakes 2023-03-09 14:47:57 +00:00
gallium asahi,agx: Implement buffer textures with gnarly NIR 2023-03-11 02:26:31 +00:00
gbm gbm: drop unnecessary vulkan dependency 2023-02-23 18:31:22 +00:00
getopt
glx meson: inline gtest_test_protocol now that it's always 'gtest' 2023-03-10 07:20:29 +00:00
gtest
imagination pvr: Advertise STORAGE_IMAGE_BIT for B10G11R11_UFLOAT_PACK32 2023-03-02 16:33:53 +00:00
imgui
intel ci: Fix release build use for performance jobs 2023-03-10 21:40:23 +00:00
loader loader: Use libdrm shim 2023-03-05 16:31:51 +00:00
mapi meson: inline gtest_test_protocol now that it's always 'gtest' 2023-03-10 07:20:29 +00:00
mesa meson: inline gtest_test_protocol now that it's always 'gtest' 2023-03-10 07:20:29 +00:00
microsoft meson: inline gtest_test_protocol now that it's always 'gtest' 2023-03-10 07:20:29 +00:00
nouveau nir: add assertions that loops don't have a Continue Construct 2023-02-21 10:41:11 +00:00
panfrost meson: inline gtest_test_protocol now that it's always 'gtest' 2023-03-10 07:20:29 +00:00
tool tool/pps: Fix 32-bit build issue with format string 2023-01-18 19:27:41 +00:00
util meson: inline gtest_test_protocol now that it's always 'gtest' 2023-03-10 07:20:29 +00:00
virtio Revert "Revert "ci: disable mesa-swrast runner jobs"" 2023-03-10 12:37:56 +00:00
vulkan vulkan/wsi: fix crash in failed swapchain creation for wayland 2023-03-08 17:33:00 +00:00
meson.build hgl: remove 2023-02-18 00:44:43 +00:00