summaryrefslogtreecommitdiffstats
path: root/video/out/gpu/video.c
Commit message (Collapse)AuthorAgeFilesLines
* vo_gpu: split --linear-scaling into two separate optionsNiklas Haas2018-10-191-12/+23
| | | | | | | | | | | | | | | | | | Since linear downscaling makes sense to handle independently from linear/sigmoid upscaling, we split this option up. Now, linear-downscaling is its own option that only controls linearization when downscaling and nothing more. Likewise, linear-upscaling / sigmoid-upscaling are two mutually exclusive options (the latter overriding the former) that apply only to upscaling and no longer implicitly enable linear light downscaling as well. The old behavior was very confusing, as evidenced by issues such as #6213. The current behavior should make much more sense, and only minimally breaks backwards compatibility (since using linear-scaling directly was very uncommon - most users got this for free as part of gpu-hq and relied only on that). Closes #6213.
* vo_gpu: avoid overwriting compute shader block sizesNiklas Haas2018-08-261-4/+10
| | | | | | | | | | When using multiple compute shaders as part of the same pass, there can be a conflict in the block sizes. In the problematic case, the HDR detection shader can collide with the polar sampling shader. In this case, the solution is clear - the passes that can handle any size should "give in" and not overwrite the block sizes. Fixes #6083.
* gpu: prefer 16bit floating point FBO formats to 16bit integer onesJan Ekström2018-07-081-1/+1
| | | | | | According to earlier discussions, this can improve visual quality. This only changes the preferred order of the formats, not the formats themselves.
* vo_gpu/video: disable compute shaders if an FBO format was not availableJan Ekström2018-05-011-0/+5
| | | | | This is actually more generic and better than just lazily plastering peak calculation together with dumb mode.
* vo_gpu/video: add improved logging when a user-specified FBO failsJan Ekström2018-05-011-2/+13
| | | | | I don't know if we can just return from this function, so for now just adding this piece of logging.
* gpu/video: make HDR peak computing work without work group countNiklas Haas2018-04-291-4/+5
| | | | | | | | | | Define a hard-coded value for gl_NumWorkGroups if it is not available. This adds an additional requirement of needing a shader recompile for all window size changes. This was considered a worthwhile compromise as currently f.ex. d3d11 completely lacked any peak computation - this is a major quality of life upgrade.
* gpu/video: improve HDR peak computation feature check loggingJan Ekström2018-04-291-1/+4
| | | | | Now that the feature depends on multiple features, log all of their states in the message.
* video: remove internal stereo_out flagwm42018-04-291-2/+2
| | | | | | Also rename stereo3d to stereo_in. The only real change is that the vo_gpu OSD code now uses the actual stereo 3D mode, instead of the --video-steroe-mode value. (Why does this vo_gpu code even exist?)
* vo_gpu: move some extra code for screenshot to video.cwm42018-04-201-5/+14
| | | | | This also happens to fix some UB on the error path (target being declared after the first "goto done;").
* vo_gpu: fix anamorphic video screenshots (second try)wm42018-03-161-3/+4
| | | | | | | | | | | | | | This passed the display size as source size to the renderer, which is of course nonsense. I don't know what I was doing in 569383bc54. Yet another fix for those damn anamorphic videos. As a somewhat redundant/cosmetic change, use image_params instead of real_image_params in the code above. They should have the same, dimensions (but possibly different formats when doing hw decdoing), and mixing them is confusing. p->image_params wins because it's shorter. Actually fixes #5619.
* vo_gpu: fix anamorphic screenshotswm42018-03-151-2/+2
| | | | | | | | | | | We took the storage size instead of the display size for "unscaled" screenshots. Even if it's called "unscaled", it's still supposed to scale to compensate for aspect ratio. (How many commits fixing anamorphic screenshots in various situations are there?) Fixes #5619.
* vo_gpu: error out if there were rendering errors when taking screenshotwm42018-03-031-1/+5
|
* vo_gpu: fix taking screenshots of rotated videoswm42018-03-031-0/+3
| | | | Good old 90° rotation logic messing everything up.
* vo_gpu: introduce --target-peakNiklas Haas2018-02-201-4/+7
| | | | | | | | | | | | | This solves a number of problems simultaneously: 1. When outputting HLG, this allows tuning the OOTF based on the display characteristics. 2. When outputting PQ or other HDR curves, this allows soft-limiting the output brightness using the tone mapping algorithm. 3. When outputting SDR, this allows HDR-in-SDR style output, by controlling the output brightness directly. Closes #5521
* vo_gpu: simplify and correct color scale handlingNiklas Haas2018-02-201-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | | The primary need for this change is the fact that the OOTF was incorrectly scaled, due to the fact that the application of the OOTF can itself change the required normalization peak. (Plus, an oversight in pass_inverse_ootf meant we forgot to normalize at the end of it) The linearize/delinearize functions still normalize the scale since it's used in a number of places throughout gpu/video.c, but the color management function now converts to absolute scale right away, instead of in an awkward way inside the tone mapping branch. The OOTF functions now work in absolute scale only. In addition, minor changes have been made to the way normalization is handled for tone mapping - we now divide out the dst_peak *after* peak detection, in order to make the scale of the peak detection buffer consistent even if the dst_peak were to (hypothetically) change mid-stream. In theory, we could also do this for desaturation, but doing the desaturation before tone mapping has the advantage of preserving much more brightness than the other way around - and even mid-stream changes are not that drastic here. Finally, some preparation work has been done for allowing the user to customize the `dst.sig_peak` in the future.
* vo_gpu: use a variable for the RA_CAP_FRAGCOORD flagJames Ross-Gowan2018-02-131-4/+3
| | | | | This is just a cosmetic change. Now the RA_CAP_FRAGCOORD check looks like all the others.
* vo_gpu: check for HDR peak detection in dumb mode tooJames Ross-Gowan2018-02-131-7/+8
| | | | | | | | Similar spirit to edb4970ca8b9. check_gl_features() has a confusing early-return. This also adds compute_hdr_peak to the list of options that is copied to the dumb-mode options struct, since it seems to make a difference. Otherwise it would be impossible to disable HDR peak detection in dumb mode.
* vo_gpu: make screenshots use the GL rendererwm42018-02-111-1/+79
| | | | | | | | | | | | | | | | | | | | | | | | | | Using the GL renderer for color conversion will make sure screenshots will use the same conversion as normal video rendering. It can do this for all types of screenshots. The logic when to write 16 bit PNGs changes. To approximate the old behavior, we decide by looking whether the source video format has more than 8 bits per component. We apply this logic even for window screenshots. Also, 16 bit PNGs now always include an unused alpha channel. The reason is that FFmpeg has RGB48 and RGBA64 formats, but no RGB064. RGB48 is 3 bytes and usually not supported by GPUs for rendering, so we have to use RGBA64, which forces an alpha channel. Will break for users who use --target-trc and similar options. I considered creating a new gl_video context, but it could double GPU memory use, so I didn't. This uses FBOs instead of glGetTexImage(), because that increases the chance it could work on GLES (e.g. ANGLE). Untested. No support for the Vulkan and D3D11 backends yet. Fixes #5498. Also fixes #5240, because the code for reading back is not used with the new code path.
* vo_gpu: add internal ability to skip osd/subs for renderingwm42018-02-111-14/+30
| | | | Needed for the following commit.
* vo_gpu: use blit() only if target ra_tex supports itwm42018-02-111-2/+3
| | | | | Even if RA_CAP_BLIT is set, this might just not be enabled for the target ra_tex.
* vo_gpu: correctly infer HDR peak detection supportNiklas Haas2018-02-111-1/+4
| | | | | | The re-ordering of commits e3d93fd and 0870859 ended up swallowing the change which made the HDR tone mapping algorithm actually check for RA_CAP_NUM_GROUPS support.
* vo_gpu: refactor HDR peak detection algorithmNiklas Haas2018-02-111-9/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The major changes are as follows: 1. Use `uint32_t` instead of `unsigned int` for the SSBO size calculation. This doesn't really matter, since a too-big buffer will still work just fine, but since `uint` is a 32-bit integer by definition this is the correct way to do it. 2. Pre-divide the frame_sum by the num_wg immediately at the end of a frame. This change was made to prevent overflow. At 4K screen size, this code is currently already very at risk of overflow, especially once I started playing with longer averaging sizes. Pre-dividing this out makes it just about fit into 32-bit even for worst-case PQ content. (It's technically also faster and easier this way, so I should have done it to begin with). Rename `frame_sum` to `frame_avg` to clearly signal the change in semantics. 3. Implement a scene transition detection algorithm. This basically compares the current frame's average brightness against the (averaged) value of the past frames. If it exceeds a threshold, which I experimentally configured, we reset the peak detection SSBO's state immediately - so that it just contains the current frame. This prevents annoying "eye adaptation"-like effects on scene transitions. 4. As a result of the previous change, we can now use a much larger buffer size by default, which results in a more stable and less flickery result. I experimented with values between 20 and 256 and settled on the new value of 64. (I also switched to a power-of-2 array size, because I like powers of two)
* vo_gpu: port HDR tone mapping algorithm from libplaceboNiklas Haas2018-02-051-19/+28
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | The current peak detection algorithm was very bugged (which contributed to the excessive cross-frame flicker without long normalization) and also didn't take into account the frame average brightness level. The new algorithm both takes into account frame average brightness (in addition to peak brightness), and also computes the values in a more stable/correct way. (The old path was basically undefined behavior) In addition to improving the algorithm, we also switch to hable tone mapping by default, and try to enable peak computation automatically whever possible (compute shaders + SSBOs supported). We also make the desaturation milder, after extensive testing during libplacebo development. I also had to compensate a bit for the representational differences between mpv and libplacebo (libplacebo treats 1.0 as the reference peak, but mpv treats it as the nominal peak), but it shouldn't have caused any problems. This is still not quite the same as libplacebo, since libplacebo also allows tagging the desired scene average brightness on the output, and it also supports reading the scene average brightness from static metadata (MaxFALL) where available. But those changes are a bit more involved. It's possible we could also read this from metadata in the future, but we have problems communicating with AVFrames as it is and I don't want to touch the mpv colorimetry structs for the time being.
* vo_gpu: check for RA_CAP_FRAGCOORD in dumb mode tooJames Ross-Gowan2018-01-301-13/+14
| | | | | | | The RA_CAP_FRAGCOORD checks apply to dumb mode as well, but they were after the check for dumb mode, which returns early, so they never ran. Fixes #5436
* video: fix crash with vdpau when reinitializing renderingwm42018-01-271-3/+3
| | | | | | | | | | Using vdpau will allocate additional textures for the reinterleaving step, which uninit_rendering() will free. This is a problem because the hwdec image remains mapped when reinitializing, so the reinterleaving textures are turned into dangling pointers. Fix this by freeing the reinterleave textures on full uninit instead. Fixes #5447.
* video: change some remaining vo_opengl mentions to vo_gpuAkemi2018-01-201-1/+1
|
* vo_gpu: skip DR for unsupported image formatswm42018-01-181-0/+3
| | | | | | | | | | | | | | DR (direct rendering) works by having the decoder decode into the GPU staging buffers, instead of copying the video data on texture upload. We did this even for formats unsupported by the GPU or the renderer. This "worked" because the staging memory is untyped, and the video frame was converted by libswscale to a supported format, and then uploaded with a copy using the normal non-DR texture upload path. Even though it "works", we don't gain anything from using the staging buffers for decoding, since we can't use them for upload anyway. Also, staging memory might be potentially limited (what really happens is up to the driver). It's easy to avoid, so just skip it in these cases.
* vo_gpu: fix broken 10 bit via integer textures playbackwm42018-01-171-3/+3
| | | | | | | | | | | The check_gl_features(p) call here checks whether dumb mode can be used. It uses the field use_integer_conversion, which is set _after_ the call in the same function. Move check_gl_features() to the end of the function, when use_integer_conversion is finally set. Fixes that it tried to use bilinear filtering with integer textures. The bug disabled the code that is supposed to convert it to non-integer textures.
* vo_gpu: attempt re-using the FBO format for p->output_texNiklas Haas2017-12-251-1/+7
| | | | | | | | | This allows RAs with support for non-opaque FBO formats to use a more appropriate FBO format for the output tex, possibly enabling a more efficient blit operation. This requires distinguishing between real formats (which can be used to create textures) and fake formats (e.g. ra_gl's FBO hack).
* vo_gpu: aggressively prefer async computeNiklas Haas2017-12-251-0/+5
| | | | | | | | | | On AMD devices, we only get one graphics pipe but several compute pipes which can (in theory) run independently. As such, we should prefer compute shaders over fragment shaders in scenarios where we expect them to be better for parallelism. This is amusingly trivial to do, and actually improves performance even in a single-queue scenario.
* vo_gpu: invalidate fbotex before drawingNiklas Haas2017-12-251-7/+7
| | | | | Don't discard the OSD or pass_draw_to_screen passes though. Could be faster on some hardware.
* msg: reinterpret a bunch of message levelsNiklas Haas2017-12-151-21/+13
| | | | | | | | | | | | | | | | | | | | | | I've decided that MP_TRACE means “noisy spam per frame”, whereas MP_DBG just means “more verbose debugging messages than MSGL_V”. Basically, MSGL_DBG shouldn't create spam per frame like it currently does, and MSGL_V should make sense to the end-user and provide mostly additional informational output. MP_DBG is basically what I want to make the new default for --log-file, so the cut-off point for MP_DBG is if we probably want to know if for debugging purposes but the user most likely doesn't care about on the terminal. Also, the debug callbacks for libass and ffmpeg got bumped in their verbosity levels slightly, because being external components they're a bit less relevant to mpv debugging, and a bit too over-eager in what they consider to be relevant information. I exclusively used the "try it on my machine and remove messages from MSGL_* until it does what I want it to" approach of refactoring, so YMMV.
* video: remove code duplication by calling a hwdec loader helperwm42017-12-111-2/+1
| | | | | Make gl_video_load_hwdecs() call gl_video_load_hwdecs_all() when all HW decoders should be loaded.
* video: properly initialize and set hwdec_interopwm42017-12-111-0/+2
| | | | Don't reset --gpu-hwdec-interop if vo_gpu uses dumb mode.
* vo_gpu: make it possible to load multiple hwdec interop driverswm42017-12-011-21/+82
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Make the VO<->decoder interface capable of supporting multiple hwdec APIs at once. The main gain is that this simplifies autoprobing a lot. Before this change, it could happen that the VO loaded the "wrong" hwdec API, and the decoder was stuck with the choice (breaking hw decoding). With the change applied, the VO simply loads all available APIs, so autoprobing trickery is left entirely to the decoder. In the past, we were quite careful about not accidentally loading the wrong interop drivers. This was in part to make sure autoprobing works, but also because libva had this obnoxious bug of dumping garbage to stderr when using the API. libva was fixed, so this is not a problem anymore. The --opengl-hwdec-interop option is changed in various ways (again...), and renamed to --gpu-hwdec-interop. It does not have much use anymore, other than debugging. It's notable that the order in the hwdec interop array ra_hwdec_drivers[] still matters if multiple drivers support the same image formats, so the option can explicitly force one, if that should ever be necessary, or more likely, for debugging. One example are the ra_hwdec_d3d11egl and ra_hwdec_d3d11eglrgb drivers, which both support d3d11 input. vo_gpu now always loads the interop lazily by default, but when it does, it loads them all. vo_opengl_cb now always loads them when the GL context handle is initialized. I don't expect that this causes any problems. It's now possible to do things like changing between vdpau and nvdec decoding at runtime. This is also preparation for cleaning up vd_lavc.c hwdec autoprobing. It's another reason why hwdec_devices_request_all() does not take a hwdec type anymore.
* vo_gpu: never pass flipped images to ra or ra backendswm42017-11-101-2/+7
| | | | | | | | | | | | | | | | | | | 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.
* vo_gpu: d3d11: add RA caps for ra_d3d11James Ross-Gowan2017-11-071-1/+15
| | | | | | | | | | | | | | | | 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.
* vo_gpu: don't re-render hwdec frames when repeating frameswm42017-11-031-19/+11
| | | | | | | | | | | | | 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 761eeacf5407cab07. 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.
* vo_gpu: change --tone-mapping-desaturate algorithmNiklas Haas2017-10-251-1/+1
| | | | | | | | | | | | | | | 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.
* video: fix alpha handlingwm42017-10-191-2/+4
| | | | | | | | | Regression since ec6e8a31e092a1d. 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.
* vo_gpu: add rgba16hf to the list of FBO formatsJames Ross-Gowan2017-10-181-1/+2
| | | | | | | 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.
* vo_gpu: fix video sometimes not being rerendered on equalizer changewm42017-10-171-1/+9
| | | | | | | | | | | | | | 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.
* vo_gpu: enable 3DLUTs in dumb modeNiklas Haas2017-09-301-1/+3
| | | | | | 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.
* vo_gpu: fix --opengl-gamma redirectNiklas Haas2017-09-281-1/+1
| | | | | It still pointed at --gpu-gamma, but we decided on --gamma-factor instead.
* vo_gpu: set the correct number of vertex attribsNiklas Haas2017-09-281-2/+2
| | | | | | | 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.
* vo_gpu: make the vertex attribs dynamicNiklas Haas2017-09-281-53/+71
| | | | | | | | | | | | | | | | 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.
* vo_gpu: kill some static arraysNiklas Haas2017-09-281-81/+69
| | | | | This gets rid of the hard-coded limits on the number of hooks, textures and hook points.
* vo_gpu: attempt to avoid UBOs for dynamic variablesNiklas Haas2017-09-261-0/+5