summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Ross-Gowan <rossymiles@gmail.com>2016-07-11 22:23:00 +1000
committerJames Ross-Gowan <rossymiles@gmail.com>2016-07-12 20:26:41 +1000
commit43e811cb4ba57758281b8f21c5a09a965e3a2f5d (patch)
treec6698be4594aa30c64f11f3bcaa7b8e5c8e1cda7
parent2d44dfaba9d5fe47c35ab6b5d552a25f02bd0bd5 (diff)
downloadmpv-43e811cb4ba57758281b8f21c5a09a965e3a2f5d.tar.bz2
mpv-43e811cb4ba57758281b8f21c5a09a965e3a2f5d.tar.xz
vo_opengl: angle: use WARP if there are no hw adapters
This should get mpv working on Windows 7 machines without hardware accelerated graphics adapters. It already worked on Windows 8 and up because those systems would silently fall back to WARP if there was no graphics hardware installed. The normal MPGL_CAP_SW flag is not set, so unlike other opengl backends, this will choose a software adapter even if opengl:sw is not specified. The reason for this is, unlike on Linux, where vo_xv and vo_x11 can be used, mpv on Windows does not have any VO to fall back on when hardware acceleration isn't available, so if software adapters are rejected, the user won't see any video output when using the default settings. WARP seems to perform quite well, so it should be used in this case.
-rw-r--r--video/out/opengl/context_angle.c47
1 files changed, 45 insertions, 2 deletions
diff --git a/video/out/opengl/context_angle.c b/video/out/opengl/context_angle.c
index 39ef3c6b5e..ebc803fdb1 100644
--- a/video/out/opengl/context_angle.c
+++ b/video/out/opengl/context_angle.c
@@ -15,6 +15,7 @@
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <initguid.h>
#include <windows.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
@@ -33,11 +34,15 @@
#define EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE 0x0002
#endif
+// Windows 8 enum value, not present in mingw-w64 headers
+#define DXGI_ADAPTER_FLAG_SOFTWARE (2)
+
struct priv {
EGLDisplay egl_display;
EGLContext egl_context;
EGLSurface egl_surface;
bool use_es2;
+ bool sw_adapter_msg_shown;
PFNEGLPOSTSUBBUFFERNVPROC eglPostSubBufferNV;
};
@@ -104,6 +109,15 @@ static bool create_context_egl(MPGLContext *ctx, EGLConfig config, int version)
return true;
}
+static void show_sw_adapter_msg(struct MPGLContext *ctx)
+{
+ struct priv *p = ctx->priv;
+ if (p->sw_adapter_msg_shown)
+ return;
+ MP_WARN(ctx->vo, "Using a software adapter\n");
+ p->sw_adapter_msg_shown = true;
+}
+
static void d3d_init(struct MPGLContext *ctx)
{
HRESULT hr;
@@ -111,6 +125,7 @@ static void d3d_init(struct MPGLContext *ctx)
struct vo *vo = ctx->vo;
IDXGIDevice *dxgi_dev = NULL;
IDXGIAdapter *dxgi_adapter = NULL;
+ IDXGIAdapter1 *dxgi_adapter1 = NULL;
IDXGIFactory *dxgi_factory = NULL;
PFNEGLQUERYDISPLAYATTRIBEXTPROC eglQueryDisplayAttribEXT =
@@ -147,6 +162,25 @@ static void d3d_init(struct MPGLContext *ctx)
goto done;
}
+ // Windows 8 can choose a software adapter even if mpv didn't ask for
+ // one. If this is the case, show a warning message.
+ hr = IDXGIAdapter_QueryInterface(dxgi_adapter, &IID_IDXGIAdapter1,
+ (void**)&dxgi_adapter1);
+ if (SUCCEEDED(hr)) {
+ DXGI_ADAPTER_DESC1 desc;
+ hr = IDXGIAdapter1_GetDesc1(dxgi_adapter1, &desc);
+ if (SUCCEEDED(hr)) {
+ if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
+ show_sw_adapter_msg(ctx);
+
+ // If the primary display adapter is a software adapter, the
+ // DXGI_ADAPTER_FLAG_SOFTWARE won't be set, but the device IDs
+ // should still match the Microsoft Basic Render Driver
+ if (desc.VendorId == 0x1414 && desc.DeviceId == 0x8c)
+ show_sw_adapter_msg(ctx);
+ }
+ }
+
hr = IDXGIAdapter_GetParent(dxgi_adapter, &IID_IDXGIFactory,
(void**)&dxgi_factory);
if (FAILED(hr)) {
@@ -168,6 +202,8 @@ done:
IDXGIDevice_Release(dxgi_dev);
if (dxgi_adapter)
IDXGIAdapter_Release(dxgi_adapter);
+ if (dxgi_adapter1)
+ IDXGIAdapter1_Release(dxgi_adapter1);
if (dxgi_factory)
IDXGIFactory_Release(dxgi_factory);
}
@@ -204,13 +240,17 @@ static int angle_init(struct MPGLContext *ctx, int flags)
}
EGLint d3d_types[] = {EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
- EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE};
+ EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE,
+ EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE};
+ EGLint d3d_dev_types[] = {EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE,
+ EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE,
+ EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE};
for (int i = 0; i < MP_ARRAY_SIZE(d3d_types); i++) {
EGLint display_attributes[] = {
EGL_PLATFORM_ANGLE_TYPE_ANGLE,
d3d_types[i],
EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE,
- EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE,
+ d3d_dev_types[i],
EGL_NONE,
};
@@ -223,6 +263,9 @@ static int angle_init(struct MPGLContext *ctx, int flags)
p->egl_display = EGL_NO_DISPLAY;
continue;
}
+
+ if (d3d_dev_types[i] == EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE)
+ show_sw_adapter_msg(ctx);
break;
}
if (p->egl_display == EGL_NO_DISPLAY) {