summaryrefslogtreecommitdiffstats
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
* radv/ac: add initial pre-pass for shader info gatheringDave Airlie2017-04-196-9/+116
| | | | | | | | | | | | There is some radv specific info we need to gather from shaders before we get into converting nir->llvm, so we can make better decisions especially around user sgpr allocation. This is just an initial placeholder to gather if sample positions are required in the frag shader. Reviewed-by: Bas Nieuwenhuizen <[email protected]> Signed-off-by: Dave Airlie <[email protected]>
* freedreno: refactor dirty state handlingRob Clark2017-04-1819-101/+119
| | | | | | | | In particular, move per-shader-stage info out to a seperate array of enum's indexed by shader stage. This will make it easier to add more shader stages as well as new per-stage state (like SSBOs). Signed-off-by: Rob Clark <[email protected]>
* freedreno: move clear path dirty state hack to a2xx backendRob Clark2017-04-182-9/+9
| | | | | | | | | a3xx/a4xx use the generic u_blitter path, which will make state dirty bits be set appropriately thanks to the automagic of generic code setting generic state in the driver. And a5xx has a blit/dma engine (actually, two) so it doesn't need these extra dirty bits set. Signed-off-by: Rob Clark <[email protected]>
* freedreno/ir3: split out per-stage emit_consts fxnsRob Clark2017-04-185-21/+41
| | | | | | | | | This makes it easier to deal with adding additional stages which have their own driver-params. The duplicated code this introduces can be refactored out after a later patch moves to per-shader-stage dirty flags. Signed-off-by: Rob Clark <[email protected]>
* freedreno: add helper to mark all state cleanRob Clark2017-04-189-52/+34
| | | | | | | | Note that this involves juggling around a bit when we emit and clear texture state. So split out from the patch that adds the helper to set all state dirty. Signed-off-by: Rob Clark <[email protected]>
* freedreno: add helper to mark all state dirtyRob Clark2017-04-184-6/+13
| | | | | | This will simplify things when we break out per-shader-stage dirty bits. Signed-off-by: Rob Clark <[email protected]>
* freedreno: move a2xx specific hack out of coreRob Clark2017-04-182-10/+20
| | | | Signed-off-by: Rob Clark <[email protected]>
* freedreno: make texture state an arrayRob Clark2017-04-1810-39/+45
| | | | | | | | Make this an array indexed by shader stage, as is done elsewhere for other per-shader-stage state. This will simplify things as more shader stages are eventually added. Signed-off-by: Rob Clark <[email protected]>
* freedreno/ir3: refactor out helpers for comparing shader keysRob Clark2017-04-184-79/+63
| | | | | | | | | | | | Each of the ir3 users has *basically* the same logic for comparing the previous and current shader key, to see which, if any, shader state needs to be marked dirty due to shader variant change. The difference between gen's was just that some lowering flags never get set on certain generations. But it doesn't really hurt to include the extra checks (because both keys would have false). Signed-off-by: Rob Clark <[email protected]>
* util/queue: don't hang at exitRob Clark2017-04-181-1/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | So atexit() is horrible and 4aea8fe7 is probably not a good idea. But add an extra layer of duct-tape to the problem. Otherwise we hit a situation where app using an atexit() handler that runs later than ours doesn't hang when trying to tear down a context. (gdb) bt #0 util_queue_killall_and_wait (queue=queue@entry=0x52bc80) at ../../../src/util/u_queue.c:264 #1 0x0000007fb6c380c0 in atexit_handler () at ../../../src/util/u_queue.c:51 #2 0x0000007fb7730e2c in __run_exit_handlers () from /lib64/libc.so.6 #3 0x0000007fb7730e5c in exit () from /lib64/libc.so.6 #4 0x0000007fb7ce17dc in piglit_report_result (result=PIGLIT_PASS) at /home/robclark/src/piglit/tests/util/piglit-util.c:267 #5 0x0000007fb7ef99f8 in process_next_event (x11_fw=0x432c20) at /home/robclark/src/piglit/tests/util/piglit-framework-gl/piglit_x11_framework.c:139 #6 0x0000007fb7ef9a90 in enter_event_loop (winsys_fw=0x432c20) at /home/robclark/src/piglit/tests/util/piglit-framework-gl/piglit_x11_framework.c:153 #7 0x0000007fb7ef8e50 in run_test (gl_fw=0x432c20, argc=1, argv=0x7ffffff588) at /home/robclark/src/piglit/tests/util/piglit-framework-gl/piglit_winsys_framework.c:88 #8 0x0000007fb7edb890 in piglit_gl_test_run (argc=1, argv=0x7ffffff588, config=0x7ffffff400) at /home/robclark/src/piglit/tests/util/piglit-framework-gl.c:203 #9 0x0000000000401224 in main (argc=1, argv=0x7ffffff588) at /home/robclark/src/piglit/tests/bugs/drawbuffer-modes.c:46 (gdb) c Continuing. [Thread 0x7fb67580c0 (LWP 3471) exited] ^C Thread 1 "drawbuffer-mode" received signal SIGINT, Interrupt. 0x0000007fb72dda34 in pthread_cond_wait@@GLIBC_2.17 () from /lib64/libpthread.so.0 (gdb) bt #0 0x0000007fb72dda34 in pthread_cond_wait@@GLIBC_2.17 () from /lib64/libpthread.so.0 #1 0x0000007fb6c38304 in cnd_wait (mtx=0x5bdc90, cond=0x5bdcc0) at ../../../include/c11/threads_posix.h:159 #2 util_queue_fence_wait (fence=0x5bdc90) at ../../../src/util/u_queue.c:106 #3 0x0000007fb6daac70 in fd_batch_sync (batch=0x5bdc70) at ../../../../../src/gallium/drivers/freedreno/freedreno_batch.c:233 #4 batch_reset (batch=batch@entry=0x5bdc70) at ../../../../../src/gallium/drivers/freedreno/freedreno_batch.c:183 #5 0x0000007fb6daa5e0 in batch_flush (batch=0x5bdc70) at ../../../../../src/gallium/drivers/freedreno/freedreno_batch.c:290 #6 fd_batch_flush (batch=0x5bdc70, sync=<optimized out>) at ../../../../../src/gallium/drivers/freedreno/freedreno_batch.c:308 #7 0x0000007fb6daba2c in fd_bc_flush (cache=0x461220, ctx=0x52b920) at ../../../../../src/gallium/drivers/freedreno/freedreno_batch_cache.c:141 #8 0x0000007fb6dac954 in fd_context_flush (pctx=0x52b920, fence=0x0, flags=<optimized out>) at ../../../../../src/gallium/drivers/freedreno/freedreno_context.c:54 #9 0x0000007fb6b43294 in st_glFlush (ctx=<optimized out>) at ../../../src/mesa/state_tracker/st_cb_flush.c:121 #10 0x0000007fb69a84e8 in _mesa_make_current (newCtx=newCtx@entry=0x0, drawBuffer=drawBuffer@entry=0x0, readBuffer=readBuffer@entry=0x0) at ../../../src/mesa/main/context.c:1654 #11 0x0000007fb6b7ca58 in st_api_make_current (stapi=<optimized out>, stctxi=0x0, stdrawi=0x0, streadi=0x0) at ../../../src/mesa/state_tracker/st_manager.c:827 #12 0x0000007fb6cc87e8 in dri_unbind_context (cPriv=<optimized out>) at ../../../../../src/gallium/state_trackers/dri/dri_context.c:217 #13 0x0000007fb6cc80b0 in driUnbindContext (pcp=0x5271e0) at ../../../../../../src/mesa/drivers/dri/common/dri_util.c:591 #14 0x0000007fb7d1da08 in MakeContextCurrent (dpy=0x433380, draw=0, read=0, gc_user=0x0) at ../../../src/glx/glxcurrent.c:214 #15 0x0000007fb7a8d5e0 in glx_platform_make_current () from /lib64/libwaffle-1.so.0 #16 0x0000007fb7a894e4 in waffle_make_current () from /lib64/libwaffle-1.so.0 #17 0x0000007fb7ef8c60 in piglit_wfl_framework_teardown (wfl_fw=0x432c20) at /home/robclark/src/piglit/tests/util/piglit-framework-gl/piglit_wfl_framework.c:628 #18 0x0000007fb7ef939c in piglit_winsys_framework_teardown (winsys_fw=0x432c20) at /home/robclark/src/piglit/tests/util/piglit-framework-gl/piglit_winsys_framework.c:238 #19 0x0000007fb7ef9c30 in destroy (gl_fw=0x432c20) at /home/robclark/src/piglit/tests/util/piglit-framework-gl/piglit_x11_framework.c:212 #20 0x0000007fb7edb7c4 in destroy () at /home/robclark/src/piglit/tests/util/piglit-framework-gl.c:184 #21 0x0000007fb7730e2c in __run_exit_handlers () from /lib64/libc.so.6 #22 0x0000007fb7730e5c in exit () from /lib64/libc.so.6 #23 0x0000007fb7ce17dc in piglit_report_result (result=PIGLIT_PASS) at /home/robclark/src/piglit/tests/util/piglit-util.c:267 #24 0x0000007fb7ef99f8 in process_next_event (x11_fw=0x432c20) at /home/robclark/src/piglit/tests/util/piglit-framework-gl/piglit_x11_framework.c:139 #25 0x0000007fb7ef9a90 in enter_event_loop (winsys_fw=0x432c20) at /home/robclark/src/piglit/tests/util/piglit-framework-gl/piglit_x11_framework.c:153 #26 0x0000007fb7ef8e50 in run_test (gl_fw=0x432c20, argc=1, argv=0x7ffffff588) at /home/robclark/src/piglit/tests/util/piglit-framework-gl/piglit_winsys_framework.c:88 #27 0x0000007fb7edb890 in piglit_gl_test_run (argc=1, argv=0x7ffffff588, config=0x7ffffff400) at /home/robclark/src/piglit/tests/util/piglit-framework-gl.c:203 #28 0x0000000000401224 in main (argc=1, argv=0x7ffffff588) at /home/robclark/src/piglit/tests/bugs/drawbuffer-modes.c:46 (gdb) r Fixes: 4aea8fe7 ("gallium/u_queue: fix random crashes when the app calls exit()") Signed-off-by: Rob Clark <[email protected]> Reviewed-by: Nicolai Hähnle <[email protected]>
* vc4: Enable V3D 2.6.Eric Anholt2017-04-181-1/+1
| | | | | This version of the chip is present on the Cygnus-based 911360 enterprise phone platform. It appears to be completely backwards compatible.
* st/mesa: add st_convert_sampler()Samuel Pitoiset2017-04-182-12/+36
| | | | | | | | | Similar to st_convert_image(), will be useful for bindless. While we are at it, rename convert_sampler() to convert_sampler_from_unit() and make 'st' a const argument. Signed-off-by: Samuel Pitoiset <[email protected]> Reviewed-by: Nicolai Hähnle <[email protected]>
* mesa/glthread: add async support to ARB_viewport_array functionsBartosz Tomczyk2017-04-181-5/+5
| | | | | | | v2: fix attribute name, it is count_scale not scale_count Tested-by: Dieter Nützel <[email protected]> Reviewed-by: Nicolai Hähnle <[email protected]>
* mesa: rename _mesa_add_renderbuffer* functionsTimothy Arceri2017-04-1811-62/+60
| | | | | | | These names make it easier to understand what is going on in regards to references. Reviewed-by: Brian Paul <[email protected]>
* anv/cmd_buffer: Disable CCS on BDW input attachmentsNanley Chery2017-04-172-30/+13
| | | | | | | | | | | | | | | | | The description under RENDER_SURFACE_STATE::RedClearColor says, For Sampling Engine Multisampled Surfaces and Render Targets: Specifies the clear value for the red channel. For Other Surfaces: This field is ignored. This means that the sampler on BDW doesn't support CCS. Cc: Samuel Iglesias Gonsálvez <[email protected]> Cc: Jordan Justen <[email protected]> Cc: <[email protected]> Reviewed-by: Jason Ekstrand <[email protected]> Signed-off-by: Nanley Chery <[email protected]>
* anv: blorp: flush memory after copyLionel Landwerlin2017-04-171-2/+2
| | | | | | Signed-off-by: Lionel Landwerlin <[email protected]> Reviewed-by: Jason Ekstrand <[email protected]> Cc: "13.0 17.0" <[email protected]>
* radv: enable timestampComputeAndGraphicsGrazvydas Ignotas2017-04-171-1/+1
| | | | | | | | | | | | Commit bfee9866 "radv: Use RELEASE_MEM packet for MEC timestamp query." added WriteTimestamp handling for compute queues but forgot to flip the flag. Tested with DOOM (by me) and CTS (by Bas), but without verification that these tests actually use timestamps on compute queues. Signed-off-by: Grazvydas Ignotas <[email protected]> Reviewed-by: Bas Nieuwenhuizen <[email protected]>
* freedreno: fix crash if ctx torn down with no renderingRob Clark2017-04-171-1/+1
| | | | | | | | In this case, ctx->flush_queue would not have been initialized. Fixes: 0b613c20 ("freedreno: enable draw/batch reordering by default") Cc: "17.1" <[email protected]> Signed-off-by: Rob Clark <[email protected]>
* freedreno/ir3: add 'high' register classRob Clark2017-04-173-67/+131
| | | | | | | | For compute shaders, we need to be able to allocate some "high" registers (r48.x to r55.w). (Possibly these are global to all threads in a warp?) Add a new register class to handle this. Signed-off-by: Rob Clark <[email protected]>
* freedreno: extract helper for stage->sb for a4xx+Rob Clark2017-04-175-28/+29
| | | | Signed-off-by: Rob Clark <[email protected]>
* freedreno/{a4xx,a5xx}: switch to CP_LOAD_STATE4Rob Clark2017-04-175-127/+124
| | | | | | | The layout of CP_LOAD_STATE packet is slightly different on a4xx+. Switch to the a4xx+ specific CP_LOAD_STATE4 to get the correct encoding. Signed-off-by: Rob Clark <[email protected]>
* freedreno: update generated headersRob Clark2017-04-178-213/+794
| | | | Signed-off-by: Rob Clark <[email protected]>
* EGL: Implement the libglvnd interface for EGL (v3)Kyle Brenneman2017-04-1715-28/+3493
| | | | | | | | | | | | | | | | | | | | | | | | The new interface mostly just sits on top of the existing library. The only change to the existing EGL code is to split the client extension string into platform extensions and everything else. On non-glvnd builds, eglQueryString will just concatenate the two strings. The EGL dispatch stubs are all generated. The script is based on the one used to generate entrypoints in libglvnd itself. v2: [Kyle] - Rebased against master. - Reworked the EGL makefile to use separate libraries - Made the EGL code generation scripts work with Python 2 and 3. - Change gen_egl_dispatch.py to use argparse for the command line arguments. - Assorted formatting and style cleanup in the Python scripts. v3: [Emil Velikov] - Rebase - Remove separate glvnd glx/egl configure toggles Signed-off-by: Emil Velikov <[email protected]>
* android: add marshal_generated c and h files to generated sourcesTapani Pälli2017-04-171-1/+3
| | | | | | | Fixes: efd63e2 ("mesa: Connect the generated GL command marshalling code to the build.") Signed-off-by: Tapani Pälli <[email protected]> Reviewed-by: Plamena Manolova <[email protected]> Reviewed-by: Emil Velikov <[email protected]>
* winsys/amdgpu: init buffer_indices_hashlist with memset()Samuel Pitoiset2017-04-171-8/+2
| | | | | Signed-off-by: Samuel Pitoiset <[email protected]> Reviewed-by: Marek Olšák <[email protected]>
* winsys/amdgpu: simplify amdgpu_cs_add_buffer() a bitSamuel Pitoiset2017-04-171-4/+3
| | | | | Signed-off-by: Samuel Pitoiset <[email protected]> Reviewed-by: Marek Olšák <[email protected]>
* i965/drm: Delete NULL check in brw_bo_unmap().Kenneth Graunke2017-04-161-3/+0
| | | | | | | | | | | | | | I accidentally moved the bo->bufmgr dereference above the NULL check when cleaning up this code. While passing NULL to free() is a common pattern...passing NULL to unmap seems pretty bad. You really ought to know whether you have a buffer or not. We don't want to paper over bugs like that. So, just drop the NULL check altogether. CID: 1405006 Reviewed-by: Chris Wilson <[email protected]>
* intel/decoder: Fix is_header_field starting condition.Kenneth Graunke2017-04-161-1/+1
| | | | | | | | | | | Starting positions >= 32 are not part of the header, rather than >. Caught by Coverity, which found that "bits <<= field->start" may shift by 32, which has undefined behavior. CID: 1404968 Reviewed-by: Lionel Landwerlin <[email protected]>
* i965/drm: Remove dead return in brw_bo_busy()Kenneth Graunke2017-04-161-3/+1
| | | | | | | | If ret is 0, we return. If ret is not 0, we return. This is dead. CID: 1405013 (Structurally dead code (UNREACHABLE)) Reviewed-by: Topi Pohjolainen <[email protected]>
* android: amd/addrlib: trivial fix for gfx9 supportMauro Rossi2017-04-171-0/+2
| | | | | | | | | | | | Fixes the following build error: external/mesa/src/amd/addrlib/gfx9/gfx9addrlib.cpp:36:10: fatal error: 'gfx9_gb_reg.h' file not found ^ 1 error generated. Fixes: 7f160ef "amd/addrlib: import gfx9 support" Reviewed-by: Nicolai Hähnle <[email protected]> Reviewed-by: Edward O'Callaghan <[email protected]>
* nir: Add GLSL_TYPE_[U]INT64 to some switch statementsJason Ekstrand2017-04-162-0/+4
| | | | | Reviewed-by: Alejandro Piñeiro <[email protected]> Reviewed-by: Lionel Landwerlin <[email protected]>
* gallium/radeon: always flush asynchronously and wait after begin_new_csMarek Olšák2017-04-172-4/+11
| | | | | | | | | | This hides the overhead of everything in the driver after the CS flush and before returning from pipe_context::flush. Only microbenchmarks will benefit. +2% FPS for glxgears. Reviewed-by: Nicolai Hähnle <[email protected]>
* radeonsi: remove local variable 'mod' from si_compile_tgsi_shaderMarek Olšák2017-04-171-5/+2
| | | | Reviewed-by: Nicolai Hähnle <[email protected]>
* radeonsi: add si_shader_selector::vs_needs_prologMarek Olšák2017-04-173-7/+10
| | | | | | cleanup Reviewed-by: Nicolai Hähnle <[email protected]>
* radeonsi: don't set VGT_GS_MODE as part of the GS stateMarek Olšák2017-04-171-2/+0
| | | | | | The VS state sets it. Reviewed-by: Nicolai Hähnle <[email protected]>
* radeonsi: don't allow user indices with indirect drawsMarek Olšák2017-04-171-4/+4
| | | | | | | Not possible with GL and it will make future gallium rework easier. (also it's something I wouldn't like to support) Reviewed-by: Nicolai Hähnle <[email protected]>
* radeonsi: merge two if (indirect) statementsMarek Olšák2017-04-171-27/+25
| | | | Reviewed-by: Nicolai Hähnle <[email protected]>
* radeonsi: don't mark non-dirty textures with CMASK as compressedMarek Olšák2017-04-171-2/+3
| | | | | | | because the compression is skipped with non-dirty textures. Reviewed-by: Samuel Pitoiset <[email protected]> Reviewed-by: Nicolai Hähnle <[email protected]>
* glsl: don't run the GLSL pre-processor when we are skipping compilationTimothy Arceri2017-04-152-9/+20
| | | | | | | | | | | | | | | | | | | | This moves the hashing of shader source for the cache lookup to before the preprocessor. In our experience, shaders are unlikely to hash the same after preprocessing if they didn't hash the same before, so we can skip preprocessing for cache hits. Improves Deus Ex start-up times with a warm cache from ~30 seconds to ~22 seconds. Also fixes the leaking of state. V2: fix indentation v3: add the value of MESA_EXTENSION_OVERRIDE to the hash of the shader. Tested-by (v2): Grazvydas Ignotas <[email protected]> Tested-by: Dieter Nützel <[email protected]> Reviewed-by: Eric Anholt <[email protected]>
* glsl: delay optimisations on individual shaders when cache is availableTimothy Arceri2017-04-154-78/+96
| | | | | | | | | | | | | | | | | | | | | | Due to a max limit of 65,536 entries on the index table that we use to decide if we can skip compiling individual shaders, it is very likely we will have collisions. To avoid doing too much work when the linked program may be in the cache this patch delays calling the optimisations until link time. Improves cold cache start-up times on Deus Ex by ~20 seconds. When deleting the cache index to simulate a worst case scenario of collisions in the index, warm cache start-up time improves by ~45 seconds. V2: fix indentation, make sure to call optimisations on cache fallback, make sure optimisations get called for XFB. Tested-by: Grazvydas Ignotas <[email protected]> Tested-by: Dieter Nützel <[email protected]> Reviewed-by: Nicolai Hähnle <[email protected]>
* anv: Add the pci_id into the shader cache UUIDJason Ekstrand2017-04-141-5/+15
| | | | | | | | | | This prevents a user from using a cache created on one hardware generation on a different one. Of course, with Intel hardware, this requires moving their drive from one machine to another but it's still possible and we should prevent it. Reviewed-by: Chad Versace <[email protected]> Cc: [email protected]
* etnaviv: native fence fd supportPhilipp Zabel2017-04-156-6/+82
| | | | | | | | | | This adds native fence fd support to etnaviv, similarly to commit 0b98e84e9ba0 ("freedreno: native fence fd"), enabled for kernel driver version 1.1 or later. Signed-off-by: Philipp Zabel <[email protected]> Reviewed-By: Wladimir J. van der Laan <[email protected]> Reviewed-by: Christian Gmeiner <[email protected]>
* i965: enable OpenGL 4.2 in IvybridgeJuan A. Suarez Romero2017-04-142-2/+2
| | | | | Reviewed-by: Andreas Boll <[email protected]> Reviewed-by: Francisco Jerez <[email protected]>
* i965: enable ARB_shader_precision in gen7+Samuel Iglesias Gonsálvez2017-04-141-1/+1
| | | | | Reviewed-by: Andreas Boll <[email protected]> Reviewed-by: Francisco Jerez <[email protected]>
* i965: enable ARB_vertex_attrib_64bit for gen7+Juan A. Suarez Romero2017-04-141-1/+1
| | | | | Reviewed-by: Andreas Boll <[email protected]> Reviewed-by: Francisco Jerez <[email protected]>
* swr: Fix swr osmesa buildGeorge Kyriazis2017-04-141-1/+1
| | | | | | Use GALLIUM_SWR to standardize Reviewed-by: Emil Velikov <[email protected]>
* etnaviv: SINGLE_BUFFER support on GC3000Wladimir J. van der Laan2017-04-158-28/+63
| | | | | | | | | | | | | | | | | | | | This patch adds support for the SINGLE_BUFFER feature on GC3000 GPUs, which allows rendering to a single buffer using multiple pixel pipes. This feature is always used when it is available, which means that multi-tiled formats are no longer being used in that case, and all buffers will be normal (super)tiled. This mimics the behavior of the blob on GC3000. - Because the same format can be used to render to and texture from, this avoids an extra resolve pass when rendering to texture. - i.MX6qp includes a PRE which can scan-out directly from tiled formats, avoiding untiling overhead. Signed-off-by: Wladimir J. van der Laan <[email protected]> Reviewed-by: Christian Gmeiner <[email protected]>
* etnaviv: Update includes from rnndbWladimir J. van der Laan2017-04-155-20/+91
| | | | | | | | | Update to etna_viv commit 8486a97. austriancoder: changed patch to include isa redefinition fix. Signed-off-by: Wladimir J. van der Laan <[email protected]> Reviewed-by: Christian Gmeiner <[email protected]>
* etnaviv: Add chipMinorFeatures4 and 5Wladimir J. van der Laan2017-04-152-1/+15
| | | | | | | | Request chipMinorFeatures bitfields 4 and 5 from the drm driver. Signed-off-by: Wladimir J. van der Laan <[email protected]> Reviewed-by: Christian Gmeiner <[email protected]>
* etnaviv: resolve tile status when flushing resourcePhilipp Zabel2017-04-152-0/+11
| | | | | | | | | | | | | | | | When passing render buffers from EGL clients to a wayland compositor, the resource tile status must be resolved because otherwise the tile status is lost in the transfer and cleared parts of the buffer will contain old contents. The same applies when sampling directly from a renderable resource. lst: Add seqno tracking, to skip flush when not needed. Fixes: aadcb5e94b35 ("etnaviv: enable TS, but disable autodisable") Signed-off-by: Philipp Zabel <[email protected]> Signed-off-by: Lucas Stach <[email protected]> Reviewed-by: Christian Gmeiner <[email protected]>