diff --git a/video/out/gpu/ra.h b/video/out/gpu/ra.h index 85e293d84b..b38eba7a82 100644 --- a/video/out/gpu/ra.h +++ b/video/out/gpu/ra.h @@ -80,6 +80,7 @@ enum { RA_CAP_FRAGCOORD = 1 << 10, // supports reading from gl_FragCoord RA_CAP_PARALLEL_COMPUTE = 1 << 11, // supports parallel compute shaders RA_CAP_NUM_GROUPS = 1 << 12, // supports gl_NumWorkGroups + RA_CAP_SLOW_DR = 1 << 13, // direct rendering is assumed to be slow }; enum ra_ctype { diff --git a/video/out/gpu/video.c b/video/out/gpu/video.c index c04f5c57a4..c35372d69e 100644 --- a/video/out/gpu/video.c +++ b/video/out/gpu/video.c @@ -4290,6 +4290,13 @@ static void gl_video_dr_free_buffer(void *opaque, uint8_t *data) struct mp_image *gl_video_get_image(struct gl_video *p, int imgfmt, int w, int h, int stride_align, int flags) { + if (flags & VO_DR_FLAG_HOST_CACHED) { + if (p->ra->caps & RA_CAP_SLOW_DR) { + MP_VERBOSE(p, "DR path suspected slow/uncached, disabling.."); + return NULL; + } + } + if (!gl_video_check_format(p, imgfmt)) return NULL; diff --git a/video/out/opengl/common.c b/video/out/opengl/common.c index cf680e9c4c..ee2650867c 100644 --- a/video/out/opengl/common.c +++ b/video/out/opengl/common.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +48,18 @@ static bool is_software_gl(GL *gl) strcmp(renderer, "Apple Software Renderer") == 0; } +// This guesses whether our DR path is fast or slow +static bool is_fast_dr(GL *gl) +{ + const char *vendor = gl->GetString(GL_VENDOR); + if (!vendor) + return false; + + return strcasecmp(vendor, "AMD") == 0 || + strcasecmp(vendor, "NVIDIA Corporation") == 0 || + strcasecmp(vendor, "ATI Technologies Inc.") == 0; // AMD on Windows +} + static void GLAPIENTRY dummy_glBindFramebuffer(GLenum target, GLuint framebuffer) { assert(framebuffer == 0); @@ -650,6 +663,9 @@ void mpgl_load_functions2(GL *gl, void *(*get_fn)(void *ctx, const char *n), mp_verbose(log, "Detected suspected software renderer.\n"); } + if (!is_fast_dr(gl)) + gl->mpgl_caps |= MPGL_CAP_SLOW_DR; + // GL_ARB_compute_shader & GL_ARB_shader_image_load_store if (gl->DispatchCompute && gl->BindImageTexture) gl->mpgl_caps |= MPGL_CAP_COMPUTE_SHADER; diff --git a/video/out/opengl/common.h b/video/out/opengl/common.h index a9e67d9756..35535322ad 100644 --- a/video/out/opengl/common.h +++ b/video/out/opengl/common.h @@ -59,6 +59,7 @@ enum { MPGL_CAP_COMPUTE_SHADER = (1 << 23), // GL_ARB_compute_shader & GL_ARB_shader_image_load_store MPGL_CAP_NESTED_ARRAY = (1 << 24), // GL_ARB_arrays_of_arrays + MPGL_CAP_SLOW_DR = (1 << 29), // direct rendering is assumed to be slow MPGL_CAP_SW = (1 << 30), // indirect or sw renderer }; diff --git a/video/out/opengl/ra_gl.c b/video/out/opengl/ra_gl.c index 03207e1c4a..f535f1f13d 100644 --- a/video/out/opengl/ra_gl.c +++ b/video/out/opengl/ra_gl.c @@ -103,6 +103,7 @@ static int ra_init_gl(struct ra *ra, GL *gl) {RA_CAP_COMPUTE, MPGL_CAP_COMPUTE_SHADER}, {RA_CAP_NUM_GROUPS, MPGL_CAP_COMPUTE_SHADER}, {RA_CAP_NESTED_ARRAY, MPGL_CAP_NESTED_ARRAY}, + {RA_CAP_SLOW_DR, MPGL_CAP_SLOW_DR}, }; for (int i = 0; i < MP_ARRAY_SIZE(caps_map); i++) { diff --git a/video/out/placebo/ra_pl.c b/video/out/placebo/ra_pl.c index dd24e1dadf..3493e79d97 100644 --- a/video/out/placebo/ra_pl.c +++ b/video/out/placebo/ra_pl.c @@ -52,6 +52,10 @@ struct ra *ra_create_pl(pl_gpu gpu, struct mp_log *log) if (gpu->limits.max_variables) ra->caps |= RA_CAP_GLOBAL_UNIFORM; #endif +#if PL_API_VER >= 234 + if (!gpu->limits.host_cached) + ra->caps |= RA_CAP_SLOW_DR; +#endif if (gpu->limits.max_tex_1d_dim) ra->caps |= RA_CAP_TEX_1D;