aboutsummaryrefslogtreecommitdiffhomepage
path: root/video
diff options
context:
space:
mode:
authorGravatar James Ross-Gowan <rossymiles@gmail.com>2016-07-11 22:23:00 +1000
committerGravatar James Ross-Gowan <rossymiles@gmail.com>2016-07-12 20:26:41 +1000
commit43e811cb4ba57758281b8f21c5a09a965e3a2f5d (patch)
treec6698be4594aa30c64f11f3bcaa7b8e5c8e1cda7 /video
parent2d44dfaba9d5fe47c35ab6b5d552a25f02bd0bd5 (diff)
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.
Diffstat (limited to 'video')
-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) {