vo_direct3d: disable shaders if unavailable

Apparently, extremely crappy graphics drivers don't allow you to use
shaders. Simply disable use of shaders if this happens, and use the
"old" method instead.

One unexpectedly tricky thing is that you need a d3d_device to create
a shader, which in turn requires a window, so the initialization order
changes.

Conflicts:
	video/out/vo_direct3d.c
This commit is contained in:
wm4 2015-01-21 20:56:34 +01:00 committed by Diogo Franco (Kovensky)
parent 155ecb2c14
commit 7af2cb08e2
1 changed files with 24 additions and 23 deletions

View File

@ -152,7 +152,6 @@ typedef struct d3d_priv {
struct texplane planes[3];
IDirect3DPixelShader9 *pixel_shader;
const BYTE *pixel_shader_data;
D3DFORMAT movie_src_fmt; /**< Movie colorspace format (depends on
the movie's codec) */
@ -237,6 +236,7 @@ static void flip_page(struct vo *vo);
static mp_image_t *get_screenshot(d3d_priv *priv);
static mp_image_t *get_window_screenshot(d3d_priv *priv);
static void draw_osd(struct vo *vo);
static bool change_d3d_backbuffer(d3d_priv *priv);
static void d3d_matrix_identity(D3DMATRIX *m)
{
@ -439,10 +439,6 @@ static void d3d_destroy_video_objects(d3d_priv *priv)
for (int n = 0; n < priv->plane_count; n++) {
d3dtex_release(priv, &priv->planes[n].texture);
}
if (priv->pixel_shader)
IDirect3DPixelShader9_Release(priv->pixel_shader);
priv->pixel_shader = NULL;
}
/** @brief Destroy D3D Offscreen and Backbuffer surfaces.
@ -504,17 +500,6 @@ static bool d3d_configure_video_objects(d3d_priv *priv)
if (need_clear)
d3d_clear_video_textures(priv);
if (priv->pixel_shader_data) {
if (!priv->pixel_shader &&
FAILED(IDirect3DDevice9_CreatePixelShader(priv->d3d_device,
(DWORD *)priv->pixel_shader_data, &priv->pixel_shader)))
{
MP_ERR(priv, "Failed to create "
"YUV conversion pixel shader.\n");
return false;
}
}
} else {
if (!priv->d3d_surface &&
@ -658,6 +643,9 @@ static bool init_d3d(d3d_priv *priv)
if (priv->opt_force_power_of_2)
priv->device_caps_power2_only = 1;
if (!change_d3d_backbuffer(priv))
return false;
MP_VERBOSE(priv, "device_caps_power2_only %d, device_caps_square_only %d\n"
"device_texture_sys %d\n"
"max_texture_width %d, max_texture_height %d\n",
@ -693,7 +681,9 @@ static void fill_d3d_presentparams(d3d_priv *priv,
// Create a new backbuffer. Create or Reset the D3D device.
static bool change_d3d_backbuffer(d3d_priv *priv)
{
D3DPRESENT_PARAMETERS present_params;
if (priv->pixel_shader)
IDirect3DPixelShader9_Release(priv->pixel_shader);
priv->pixel_shader = NULL;
int window_w = priv->vo->dwidth;
int window_h = priv->vo->dheight;
@ -713,6 +703,7 @@ static bool change_d3d_backbuffer(d3d_priv *priv)
/* The grown backbuffer dimensions are ready and fill_d3d_presentparams
* will use them, so we can reset the device.
*/
D3DPRESENT_PARAMETERS present_params;
fill_d3d_presentparams(priv, &present_params);
if (!priv->d3d_device) {
@ -737,6 +728,14 @@ static bool change_d3d_backbuffer(d3d_priv *priv)
present_params.BackBufferWidth, present_params.BackBufferHeight,
window_w, window_h);
if (FAILED(IDirect3DDevice9_CreatePixelShader(priv->d3d_device,
(DWORD *)d3d_shader_yuv, &priv->pixel_shader)))
{
priv->pixel_shader = NULL;
if (!priv->opt_disable_shaders)
MP_WARN(priv, "Shader could not be created - disabling shaders.\n");
}
return 1;
}
@ -828,6 +827,10 @@ static void uninit_d3d(d3d_priv *priv)
destroy_d3d_surfaces(priv);
if (priv->pixel_shader)
IDirect3DPixelShader9_Release(priv->pixel_shader);
priv->pixel_shader = NULL;
if (priv->d3d_device)
IDirect3DDevice9_Release(priv->d3d_device);
priv->d3d_device = NULL;
@ -1032,7 +1035,7 @@ static bool init_rendering_mode(d3d_priv *priv, uint32_t fmt, bool initialize)
if (priv->opt_disable_textures)
texture_d3dfmt = 0;
if (priv->opt_disable_shaders)
if (priv->opt_disable_shaders || !priv->pixel_shader)
shader_d3dfmt = 0;
if (priv->opt_disable_stretchrect)
blit_d3dfmt = 0;
@ -1052,7 +1055,6 @@ static bool init_rendering_mode(d3d_priv *priv, uint32_t fmt, bool initialize)
priv->use_shaders = false;
priv->use_textures = false;
priv->movie_src_fmt = 0;
priv->pixel_shader_data = NULL;
priv->plane_count = 0;
priv->image_format = fmt;
@ -1093,7 +1095,6 @@ static bool init_rendering_mode(d3d_priv *priv, uint32_t fmt, bool initialize)
if (n > 0)
planes[n].clearval = get_chroma_clear_val(desc.plane_bits);
}
priv->pixel_shader_data = d3d_shader_yuv;
}
for (n = 0; n < priv->plane_count; n++) {
@ -1190,9 +1191,6 @@ static int preinit(struct vo *vo)
goto err_out;
}
if (!init_d3d(priv))
goto err_out;
/* w32_common framework call. Configures window on the screen, gets
* fullscreen dimensions and does other useful stuff.
*/
@ -1201,6 +1199,9 @@ static int preinit(struct vo *vo)
goto err_out;
}
if (!init_d3d(priv))
goto err_out;
return 0;
err_out: