Commit Graph

54 Commits

Author SHA1 Message Date
wm4 c7596d3c8b vd_lavc: prefer nvdec over vdpau with --hwdec=auto
nvdec aka cuvid aka cuda should work much better than vdpau, and support
newer codecs (such as vp9), and more advanced surface formats (like 10
bit).

This requires moving the d3d hwaccels in the autoprobe order, since on
Windows, d3d decoding should be preferred over nvidia proprietary stuff.

Users of older drivers will need to force --hwdec=vdpau, since it could
happen that the vo_gpu cuda hwdec interop loads (so the vdpau interop is
not loaded), but the hwdec itself doesn't work.

I expect this does not break AMD (which still needs vdpau for vo_gpu
interop, until libva is fixed so it can fully support AMD).
2017-11-30 21:54:13 +01:00
wm4 c437267518 vo_gpu: remove hwdec_vaglx interop
This has stopped being useful a long time ago, and it's the only GPL
source file in the vo_gpu source directories. Recently it wasn't even
loaded at all, unless you forced loading it.
2017-11-30 04:19:12 +01:00
James Ross-Gowan b9c742df10 vo_gpu: d3d11_helpers: don't try BGRA_SUPPORT
The D3D11_CREATE_DEVICE_BGRA_SUPPORT flag doesn't enable support for
BGRA textures. BGRA textures will be supported whether or not the flag
is passed. The flag just fails device creation if they are not supported
as an API convenience for programs that need BGRA textures, such as
programs that use D2D or D3D9 interop. We can handle devices without
BGRA support fine, so don't bother with the flag.
2017-11-19 21:37:57 +11:00
wm4 4a6b04bdb9 vo_gpu: never pass flipped images to ra or ra backends
Seems like the last refactor to this code broke playing flipped images,
at least with --opengl-pbo --gpu-api=opengl.

Flipping is rather a shitmess. The main problem is that OpenGL does not
support flipped uploading. The original vo_gl implementation considered
it important to handle the flipped case efficiently, so instead of
uploading the image line by line backwards, it uploaded it flipped, and
then flipped it in the renderer (basically the upload path ignored the
flipping). The ra code and backends probably have an insane and
inconsistent mix of semantics, so fix this by never passing it flipped
images in the first place.

In the future, the backends should probably support flipped images
directly.

Fixes #5097.
2017-11-10 10:06:33 +01:00
James Ross-Gowan 4b014b3a81 vo_gpu: move d3d11_screenshot to shared code
This can be used by the ANGLE backend and ra_d3d11.
2017-11-07 20:27:13 +11:00
James Ross-Gowan 9b2dae79b1 vo_gpu: d3d11: add RA caps for ra_d3d11
ra_d3d11 uses the SPIR-V compiler to translate GLSL to SPIR-V, which is
then translated to HLSL. This means it always exposes the same GLSL
version that the SPIR-V compiler supports (4.50 for shaderc/glslang.)

Despite claiming to support GLSL 4.50, some features that are tied to
the GLSL version in OpenGL are not supported by ra_d3d11 when targeting
legacy Direct3D feature levels.

This includes two features that mpv relies on:
- Reading from gl_FragCoord in the fragment shader (requires FL 10_0)
- textureGather from any texture component (requires FL 11_0)

These features have been exposed as new RA caps.
2017-11-07 20:27:13 +11:00
James Ross-Gowan 68eac1a1e7 vo_gpu: d3d11: initial implementation
This is a new RA/vo_gpu backend that uses Direct3D 11. The GLSL
generated by vo_gpu is cross-compiled to HLSL with SPIRV-Cross.

What works:

- All of mpv's internal shaders should work, including compute shaders.

- Some external shaders have been tested and work, including RAVU and
  adaptive-sharpen.

- Non-dumb mode works, even on very old hardware. Most features work at
  feature level 9_3 and all features work at feature level 10_0. Some
  features also work at feature level 9_1 and 9_2, but without high-bit-
  depth FBOs, it's not very useful. (Hardware this old is probably not
  fast enough for advanced features anyway.)

  Note: This is more compatible than ANGLE, which requires 9_3 to work
  at all (GLES 2.0,) and 10_1 for non-dumb-mode (GLES 3.0.)

- Hardware decoding with D3D11VA, including decoding of 10-bit formats
  without truncation to 8-bit.

What doesn't work / can be improved:

- PBO upload and direct rendering does not work yet. Direct rendering
  requires persistent-mapped PBOs because the decoder needs to be able
  to read data from images that have already been decoded and uploaded.
  Unfortunately, it seems like persistent-mapped PBOs are fundamentally
  incompatible with D3D11, which requires all resources to use driver-
  managed memory and requires memory to be unmapped (and hence pointers
  to be invalidated) when a resource is used in a draw or copy
  operation.

  However it might be possible to use D3D11's limited multithreading
  capabilities to emulate some features of PBOs, like asynchronous
  texture uploading.

- The blit() and clear() operations don't have equivalents in the D3D11
  API that handle all cases, so in most cases, they have to be emulated
  with a shader. This is currently done inside ra_d3d11, but ideally it
  would be done in generic code, so it can take advantage of mpv's
  shader generation utilities.

- SPIRV-Cross is used through a NIH C-compatible wrapper library, since
  it does not expose a C interface itself.

  The library is available here: https://github.com/rossy/crossc

- The D3D11 context could be made to support more modern DXGI features
  in future. For example, it should be possible to add support for
  high-bit-depth and HDR output with DXGI 1.5/1.6.
2017-11-07 20:27:13 +11:00
James Ross-Gowan 8020a62953 vo_gpu: export the GLSL format qualifier for ra_format
Backported from @haasn's change to libplacebo, except in the current RA,
there's nothing to indicate an ra_format can be bound as a storage
image, so there's no way to force all of these formats to have a
glsl_format. Instead, the layout qualifier will be removed if
glsl_format is NULL.

This is needed for the upcoming ra_d3d11 backend. In Direct3D 11, while
loading float values from unorm images often works as expected, it's
technically undefined behaviour, and in Windows 10, it will cause the
debug layer to spam the log with error messages. Also, apparently in
GLSL, the format name must match the image's format exactly (but in
Direct3D, it just has to have the same component type.)
2017-11-07 20:27:13 +11:00
James Ross-Gowan 41dff03f8d vo_gpu: add namespace query mechanism
Backported from @haasn's change to libplacebo. More flexible than the
previous "shared || non-shared" distinction. The extra flexibility is
needed for Direct3D 11, but it also doesn't hurt code-wise.
2017-11-07 20:27:13 +11:00
wm4 5261d1b099 vo_gpu: don't re-render hwdec frames when repeating frames
Repeating frames (for display-sync) is not supposed to render the entire
frame again. When using hardware decoding, it unfortunately did: the
renderer uses the frame ID to check whether the frame data changed, and
unmapping the hwdec frame clears it.

Essentially reverts commit 761eeacf54. Back then I probably
thought it would be a good idea to release the hwdec image quickly in
order to return it to the decoder, but they're referenced anyway.

This should increase the performance and reduce GPU work.
2017-11-03 15:11:56 +01:00
wm4 2abf20b2b2 vo_gpu: fix mobius tone mapping compatibility to GLSL 120
Normally such code is didsabled by have_mglsl==false in
check_gl_features(), but apparently not this one.

Just fix it. Seems also more readable.

Fixes #5069.
2017-11-03 11:53:17 +01:00
wm4 1c46bd5e50 vo_gpu: remove a redundant ifdef 2017-10-30 18:35:33 +01:00
wm4 b7ce3ac445 vd_lavc: remove need for duplicated cuda GL interop backend
This is just a dumb consequence of HWDEC_ types somehow being part of
both decoder and VO. Obviously, the VO should only care about supporting
specific hardware surface types or providing specific device types, but
until they are separated, stupid unintuitive mismatches will occur.
2017-10-30 18:31:20 +01:00
wm4 6b745769b1 vd_lavc: add support for nvdec hwaccel
See manpage additions.

(In ffmpeg-mpv and Libav, this is still called "cuvid". Libav won't work
yet, because it has no frame params support yet, but this could get
fixed soon.)
2017-10-28 19:59:08 +02:00
Niklas Haas 4701c5ba4f vo_gpu: fix ra_tex_upload_pbo for 2D textures
params->rc was ignored in the calculation for the buffer size. I fucking
hate this stupid ra_tex_upload signature where *rc is randomly relevant
or not.
2017-10-27 16:56:23 +02:00
wm4 d6f33e0b0d vo_gpu: osd: simplify some code
Coverity complains about this, but it's probably a false positive.
Anyway, rewrite it in a slightly more readable way. Now it's more
obvious that it is correct.
2017-10-27 14:19:57 +02:00
Niklas Haas c2d4fd0ef4 vo_gpu: change --tone-mapping-desaturate algorithm
Comparing mpv's implementation against the ACES ODR reference samples
and algorithms, it seems like they're happy desaturating highlights
_way_ more aggressively than mpv currently does. And indeed, looking at
some example clips like The Redwoods (which is actually well-mastered),
the current desaturation produces unnatural-looking brightness fringes
where the sky meets the treeline.

Adjust the algorithm to make it apply to a much larger, more gradual
brightness region; and change the interpretation of the parameter. As a
bonus, the new parameter is actually sanely scaled (higher values = more
desaturation). Also, make it scale based on the signal level instead of
the luminance, to avoid under-desaturating bright blues.
2017-10-25 17:24:27 +02:00
Lionel CHAZALLON cfcee4cfe7 Add DRM_PRIME Format Handling and Display for RockChip MPP decoders
This commit allows to use the AV_PIX_FMT_DRM_PRIME newly introduced
format in ffmpeg that allows decoders to provide an AVDRMFrameDescriptor
struct.

That struct holds dmabuf fds and information allowing zerocopy rendering
using KMS / DRM Atomic.

This has been tested on RockChip ROCK64 device.
2017-10-23 21:07:24 +02:00
wm4 d3c022779a video: fix alpha handling
Regression since ec6e8a31e0. Removal of the explicit else case
always applies the conversion to premultiplied alpha in the else branch.
We want to scale with multiplied alpha, but we don't want to multiply
with alpha again on top of it.

Fixes #4983, hopefully.
2017-10-19 19:01:33 +02:00
James Ross-Gowan d9e3bad500 vo_gpu: add rgba16hf to the list of FBO formats
This should be functionally identical to rgba16f, since the formats only
differ in their representation on the CPU, but it could be useful for RA
backends that don't expose rgba16f, like Vulkan. It's definitely useful
for the WIP D3D11 backend.
2017-10-18 23:55:13 +11:00
wm4 c90f76d322 vo_gpu: fix video sometimes not being rerendered on equalizer change
With video paused, changing the brightness controls (or similar) would
sometimes not rerender the video frame. So the OSD would redraw, but the
video wouldn't change. This is caused by output caching, and a redraw
request is free to return the cached frame. Change it such to invalidate
the cached frame if any of the options or the equalizer change.

In theory, gl_video_reset_surfaces() could be called if the equalizer
changes - this would apparently force interpolatzion to redraw all
frames. But this looks kind of crappy when changing the equalizer during
playback. It'll "eventually" use the correct settings anyway, and when
paused interpolation is off.
2017-10-17 09:07:35 +02:00
wm4 7cfae5adce vo_gpu: semi-fix --gpu-context/--gpu-api options and help output
This was confusing at best. Change it to output the actual choices.
(Seems like in the end it's always me who has to clean up other people's
bullshit.)

Context names were not unique - but they should be, so fix it. The whole
point of the original --opengl-backend option was to side-step the
tricky auto-detection, so you know exactly what you get. The goal of
this commit is to make --gpu-context work the same way. Fix the
non-unique names by appending "vk" to the names.

Keep in mind that this was not suitable for slecting the "UI" backend
anyway, since "x11" would force GLX, whereas people on not-NVIDIA
actually want "x11egl". Users trying to use --gpu-context=x11 to force
the X11 backend would always end up with GLX, which would at least break
VAAPI hardware decoding for them. Basically the idea that this option
could select the "UI" type is completely broken - it selects an
implementation, which implies a UI. Selecting the UI type This would
require a separate mechanism. (Although in theory this separate
mechanism could be part of the --gpu-context option - in any case,
someone would have to implement it.)

To achieve help output that can actually be understood, just duplicate
the code. Most of that code is duplicated anyway, and trying to share
just the list code with the result of making the output unreadable
doesn't make too much sense. If we wanted to save code/effort, we could
just remove the help output altogether.

--gpu-api has non-unique entries, and it would be nice to group them
(e.g. list all OpenGL capable contexts with "opengl"), but C makes this
simple idea too much of a pain, so don't do it.

Also remove a stray tab from the android entry on the manpage.
2017-10-16 10:57:51 +02:00
Tobias Jakobi 47b1390b80 vo_gpu: mali-fbdev: fix build error
Apparantly the context was renamed.
2017-10-13 17:10:52 +02:00
James Ross-Gowan b3178eb59e vo_gpu: shaderc: include debug info when --gpu-debug is set
This adds symbol information to the generated SPIR-V, which shows up in
the SPIR-V assembly dump. It's also useful for potential RA backends
that use SPIRV-Cross, since the symbol information is used in the
generated shader source.
2017-10-11 12:22:21 +11:00
Aman Gupta 502d074a31 vo_gpu: android: fix gpu context 2017-10-09 21:49:01 +02:00
Niklas Haas eb69e73eb4 vo_gpu: enable 3DLUTs in dumb mode
Unless FBOs are unsupported, this works. In particular, it's required to
get ICC profiles working in voluntary dumb mode. So instead of
blanket-disabling it, only disable it in the !have_fbo false case.
2017-09-30 19:03:34 +02:00
Niklas Haas 22311a767d vo_gpu: force layout std430 for PCs
Seems to be fixed upstream in the nvidia driver, so it's probably a good
idea to 1. force the layout and 2. remove the warning, as it now
actually works. Users with older drivers would run into errors, but they
can still use shaderc as a replacement. (And it's not like the old
status quo was any better)
2017-09-29 00:41:50 +02:00
Niklas Haas 07fa5c8a8f vo_gpu: fix --opengl-gamma redirect
It still pointed at --gpu-gamma, but we decided on --gamma-factor
instead.
2017-09-28 17:21:56 +02:00
Niklas Haas 791b9c4024 vo_gpu: set the correct number of vertex attribs
This was always set to the length of the VAO, but it should have been
set to the number of vertex attribs actually in use for this frame. No
idea how that managed to survive the test framework on nvidia/linux, but
ANGLE caught it.
2017-09-28 12:50:45 +02:00
James Ross-Gowan a65abe2447 vo_gpu: vulkan: add support for Windows 2017-09-28 10:02:22 +10:00
Niklas Haas 67fd5882b8
vo_gpu: make the vertex attribs dynamic
This has several advantages:

1. no more redundant texcoords when we don't need them
2. no more arbitrary limit on how many textures we can bind
3. (that extends to user shaders as well)
4. no more arbitrary limits on tscale radius

To realize this, the VAO was moved from a hacky stateful approach
(gl_sc_set_vertex_attribs) - which always bothered me since it was
required for compute shaders as well even though they ignored it - to be
a proper parameter of gl_sc_dispatch_draw, and internally plumbed into
gl_sc_generate, which will make a (properly mangled) deep copy into
params.vertex_attribs.
2017-09-28 01:54:38 +02:00
Niklas Haas 002a0ce232 vo_gpu: kill some static arrays
This gets rid of the hard-coded limits on the number of hooks, textures
and hook points.
2017-09-28 01:54:33 +02:00
Niklas Haas e569050fe4
vo_gpu: fix memleak in spirv.c 2017-09-26 17:32:36 +02:00
Niklas Haas a4e951e80c
vo_gpu: explicitly label storage image formats
This is apparently required to get storage images working on
windows/vulkan, and probably good practice either way. Not entirely sure
if it's the best idea to be always storing the value as 32-bit float,
but it should hardly matter in practice (since we're only writing one
sample per thread).

(Leaving them implicit requires the shaderStorageImageWriteWithoutFormat
feature to be enabled, which the windows nvidia vulkan driver doesn't
support, at least not for a GTX 670)
2017-09-26 17:25:46 +02:00
Niklas Haas 47af509e1f vo_gpu: attempt to avoid UBOs for dynamic variables
This makes the radeon driver shut up about frequently updating
STATIC_DRAW UBOs (--opengl-debug), and also reduces the amount of
synchronization necessary for vulkan uniform buffers.

Also add some extra debugging/tracing code paths. I went with a
flags-based approach in case we ever want to extend this.
2017-09-26 17:25:35 +02:00
Niklas Haas ca85a153b4 vo_gpu: vulkan: add support for push constants
Can in theory avoid updating the uniform buffer every frame
2017-09-26 17:25:35 +02:00
Rostislav Pehlivanov ed345ffc2f vo_gpu: vulkan: add support for wayland 2017-09-26 17:25:35 +02:00
Niklas Haas 258487370f vo_gpu: vulkan: generalize SPIR-V compiler
In addition to the built-in nvidia compiler, we now also support a
backend based on libshaderc. shaderc is sort of like glslang except it
has a C API and is available as a dynamic library.

The generated SPIR-V is now cached alongside the VkPipeline in the
cached_program. We use a special cache header to ensure validity of this
cache before passing it blindly to the vulkan implementation, since
passing invalid SPIR-V can cause all sorts of nasty things. It's also
designed to self-invalidate if the compiler gets better, by offering a
catch-all `int compiler_version` that implementations can use as a cache
invalidation marker.
2017-09-26 17:25:35 +02:00
Niklas Haas 91f23c7067 vo_gpu: vulkan: initial implementation
This time based on ra/vo_gpu. 2017 is the year of the vulkan desktop!

Current problems / limitations / improvement opportunities:

1. The swapchain/flipping code violates the vulkan spec, by assuming
   that the presentation queue will be bounded (in cases where rendering
   is significantly faster than vsync). But apparently, there's simply
   no better way to do this right now, to the point where even the
   stupid cube.c examples from LunarG etc. do it wrong.
   (cf. https://github.com/KhronosGroup/Vulkan-Docs/issues/370)

2. The memory allocator could be improved. (This is a universal
   constant)

3. Could explore using push descriptors instead of descriptor sets,
   especially since we expect to switch descriptors semi-often for some
   passes (like interpolation). Probably won't make a difference, but
   the synchronization overhead might be a factor. Who knows.

4. Parallelism across frames / async transfer is not well-defined, we
   either need to use a better semaphore / command buffer strategy or a
   resource pooling layer to safely handle cross-frame parallelism.
   (That said, I gave resource pooling a try and was not happy with the
   result at all - so I'm still exploring the semaphore strategy)

5. We aggressively use pipeline barriers where events would offer a much
   more fine-grained synchronization mechanism. As a result of this, we
   might be suffering from GPU bubbles due to too-short dependencies on
   objects. (That said, I'm also exploring the use of semaphores as a an
   ordering tactic which would allow cross-frame time slicing in theory)

Some minor changes to the vo_gpu and infrastructure, but nothing
consequential.

NOTE: For safety, all use of asynchronous commands / multiple command
pools is currently disabled completely. There are some left-over relics
of this in the code (e.g. the distinction between dev_poll and
pool_poll), but that is kept in place mostly because this will be
re-extended in the future (vulkan rev 2).

The queue count is also currently capped to 1, because of the lack of
cross-frame semaphores means we need the implicit synchronization from
the same-queue semantics to guarantee a correct result.
2017-09-26 17:25:35 +02:00
Niklas Haas 89cdccfa6c vo_gpu: fix possible segfault on shader miscompile
Iterations after the first time will fail to realize that the pass was
never created. This function's logic and control flow is so annoying...
2017-09-23 16:36:58 +02:00
Niklas Haas b0ba193b66 vo_gpu: handle texture initialization errors gracefully
Tested by making the ra_tex_resize function always fail (apart from the
initial FBO check). This required a few changes:

1. reset shaders on failed dispatch
2. reset cleanup binds on failed dispatch
3. fall back to initializing the struct image to 1x1 on failure
4. handle output_fbo_valid gracefully
2017-09-23 09:58:27 +02:00
Niklas Haas f3ec494613 vo_gpu: reduce the --alpha=blend-tiles checkerboard intensity
This was sort of grating by default and made it really hard to actually
read e.g. text on top of a transparent background. I decided to approach
the problem from both directions, making the whites darker and the grays
lighter. This brings it closer to the dynamic range of e.g. the
wikipedia transparent svg preview.
2017-09-22 21:14:27 +02:00
Niklas Haas e3288c4597 vo_gpu: simplify compute shader coordinate calculation
Since the removal of FBOTEX_FUZZY, this can be made slightly simpler.
2017-09-22 17:22:53 +02:00
Niklas Haas 62ddc85d17 vo_gpu: simplify structs / names
Due to the plethora of historical baggage from different eras getting
confusing, I decided to simplify and unify the struct organization and
naming scheme.

Structs that got renamed:

1. fbodst     -> ra_fbo  (and moved to gpu/context.h)
2. fbotex     -> removed (redundant after 2af2fa7a)
3. fbosurface -> surface
4. img_tex    -> image

In addition to these structs being renamed, all of the names have been
made consistent. The new scheme is as follows:

struct image img;
struct ra_tex *tex;
struct ra_fbo fbo;

This also affects derived names, e.g. indirect_fbo -> indirect_tex.
Notably also, finish_pass_fbo -> finish_pass_tex and finish_pass_direct
-> finish_pass_fbo.

The new equivalent of fbotex_change() is called ra_tex_resize().

This commit (should) contain no logic changes, just renaming a bunch of
crap.
2017-09-22 16:58:55 +02:00
Niklas Haas 2af2fa7a27 vo_gpu: kill off FBOTEX_FUZZY
I've observed the garbage pixels in more scenarios. They also were never
really needed to begin with, originally being a discovered work-around
for bug that we fixed since then anyway. Doesn't really seem to even
help resizing, since the OpenGL drivers are all smart enough to pool
resources internally anyway.

Fixes #1814
2017-09-22 16:33:25 +02:00
wm4 fba927de41 options: properly handle deprecated options with CLI actions
We want e.g. --opengl-shaders-append=foo to resolve to the new option,
all while printing an option name. --opengl-shader is a similar case.
These options are special, because they apply "actions" on actual
options by specifying a suffix. So the alias/deprecation handling has to
be part of resolving the actual option from prefix and suffix.
2017-09-22 11:31:03 +02:00
wm4 baffe6bcbc vo_gpu: fix autoprobing message 2017-09-22 05:37:54 +02:00
Niklas Haas b940691784 vo_gpu: drop the RA_CAP_NESTED_ARRAY req from EWA compute
Almost as fast as the old code, but more general. Notably, glslang
doesn't support nested arrays.

(cf. https://github.com/KhronosGroup/glslang/issues/1057)

Also much cleaner code-wise, so I think I'll keep it even if glslang
implements array_of_arrays.
2017-09-21 15:15:59 +02:00
Niklas Haas 28b2fa4b7e vo_gpu: fix possible segfault in shader_cache.c
If shader compilation fails in an unexpected way, it can end up calling
renderpass_run on an invalid pass, since current_shader is never cleared.
2017-09-21 15:15:15 +02:00
Niklas Haas db0fb3c48b
vo_gpu: fix gamma scale
This never really made sense since the BT.1886 changes. It should get
*brighter* for bright rooms, not darker for dark rooms. Picked some new
values that seemed reasonable-ish.
2017-09-21 15:01:26 +02:00