diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index dbb7f3fb659..32373b4884b 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -2180,6 +2180,23 @@ static void shader_arb_get_caps(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_info } } +static BOOL shader_arb_conv_supported(WINED3DFORMAT fmt) { + TRACE("Checking shader format support for format %s:", debug_d3dformat(fmt)); + switch(fmt) { + case WINED3DFMT_V8U8: + case WINED3DFMT_V16U16: + case WINED3DFMT_X8L8V8U8: + case WINED3DFMT_L6V5U5: + case WINED3DFMT_Q8W8V8U8: + case WINED3DFMT_ATI2N: + TRACE("[OK]\n"); + return TRUE; + default: + TRACE("[FAILED\n"); + return FALSE; + } +} + const shader_backend_t arb_program_shader_backend = { shader_arb_select, shader_arb_select_depth_blt, @@ -2194,6 +2211,7 @@ const shader_backend_t arb_program_shader_backend = { shader_arb_generate_pshader, shader_arb_generate_vshader, shader_arb_get_caps, + shader_arb_conv_supported, }; /* ARB_fragment_program fixed function pipeline replacement definitions */ @@ -2961,5 +2979,6 @@ const struct fragment_pipeline arbfp_fragment_pipeline = { arbfp_get_caps, arbfp_alloc, arbfp_free, + shader_arb_conv_supported, arbfp_fragmentstate_template }; diff --git a/dlls/wined3d/ati_fragment_shader.c b/dlls/wined3d/ati_fragment_shader.c index 54b05b144c1..d6c133cfe29 100644 --- a/dlls/wined3d/ati_fragment_shader.c +++ b/dlls/wined3d/ati_fragment_shader.c @@ -1063,10 +1063,24 @@ static void atifs_free(IWineD3DDevice *iface) { } #undef GLINFO_LOCATION +static BOOL atifs_conv_supported(WINED3DFORMAT fmt) { + TRACE("Checking shader format support for format %s:", debug_d3dformat(fmt)); + switch(fmt) { + case WINED3DFMT_V8U8: + case WINED3DFMT_V16U16: + TRACE("[OK]\n"); + return TRUE; + default: + TRACE("[FAILED\n"); + return FALSE; + } +} + const struct fragment_pipeline atifs_fragment_pipeline = { atifs_enable, atifs_get_caps, atifs_alloc, atifs_free, + atifs_conv_supported, atifs_fragmentstate_template }; diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c index 7b52510c587..82187fc1a11 100644 --- a/dlls/wined3d/baseshader.c +++ b/dlls/wined3d/baseshader.c @@ -1113,8 +1113,23 @@ static void shader_none_get_caps(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_inf pCaps->PixelShaderVersion = 0; pCaps->PixelShader1xMaxValue = 0.0; } - #undef GLINFO_LOCATION +static BOOL shader_none_conv_supported(WINED3DFORMAT fmt) { + TRACE("Checking shader format support for format %s", debug_d3dformat(fmt)); + switch(fmt) { + /* Faked to make some apps happy. */ + case WINED3DFMT_V8U8: + case WINED3DFMT_V16U16: + case WINED3DFMT_L6V5U5: + case WINED3DFMT_X8L8V8U8: + case WINED3DFMT_Q8W8V8U8: + TRACE("[OK]\n"); + return TRUE; + default: + TRACE("[FAILED]\n"); + return FALSE; + } +} const shader_backend_t none_shader_backend = { shader_none_select, @@ -1130,6 +1145,7 @@ const shader_backend_t none_shader_backend = { shader_none_generate_pshader, shader_none_generate_vshader, shader_none_get_caps, + shader_none_conv_supported }; /* ******************************************* diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index b5eb4069674..f0cca692140 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -149,6 +149,9 @@ static int numAdapters = 0; static struct WineD3DAdapter Adapters[1]; static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DFORMAT AdapterFormat, DWORD Usage, WINED3DRESOURCETYPE RType, WINED3DFORMAT CheckFormat); +static const struct fragment_pipeline *select_fragment_implementation(UINT Adapter, WINED3DDEVTYPE DeviceType); +static const shader_backend_t *select_shader_backend(UINT Adapter, WINED3DDEVTYPE DeviceType); +static const struct blit_shader *select_blit_implementation(UINT Adapter, WINED3DDEVTYPE DeviceType); /* lookup tables */ int minLookup[MAX_LOOKUPS]; @@ -1960,46 +1963,40 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceType(IWineD3D *iface, UINT Adapter #define GLINFO_LOCATION Adapters[Adapter].gl_info /* Check if we support bumpmapping for a format */ -static BOOL CheckBumpMapCapability(UINT Adapter, WINED3DFORMAT CheckFormat) +static BOOL CheckBumpMapCapability(UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DFORMAT CheckFormat) { - /* TODO: Check this in the fixed function pipeline backend */ - if(GL_SUPPORT(NV_REGISTER_COMBINERS) && GL_SUPPORT(NV_TEXTURE_SHADER2)) { - switch (CheckFormat) { - case WINED3DFMT_V8U8: + const struct fragment_pipeline *fp; + const GlPixelFormatDesc *glDesc; + + switch(CheckFormat) { + case WINED3DFMT_V8U8: + case WINED3DFMT_V16U16: + case WINED3DFMT_L6V5U5: + case WINED3DFMT_X8L8V8U8: + case WINED3DFMT_Q8W8V8U8: + getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &glDesc); + if(glDesc->conversion_group == WINED3DFMT_UNKNOWN) { + /* We have a GL extension giving native support */ TRACE_(d3d_caps)("[OK]\n"); return TRUE; - /* TODO: Other bump map formats */ - default: - TRACE_(d3d_caps)("[FAILED]\n"); - return FALSE; - } - } - if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP) || GL_SUPPORT(ATI_FRAGMENT_SHADER)) { - switch (CheckFormat) { - case WINED3DFMT_V8U8: + } + + /* No native support: Ask the fixed function pipeline implementation if it + * can deal with the conversion + */ + fp = select_fragment_implementation(Adapter, DeviceType); + if(fp->conv_supported(CheckFormat)) { TRACE_(d3d_caps)("[OK]\n"); return TRUE; - default: + } else { TRACE_(d3d_caps)("[FAILED]\n"); return FALSE; - } + } + + default: + TRACE_(d3d_caps)("[FAILED]\n"); + return FALSE; } - if(GL_SUPPORT(ARB_FRAGMENT_PROGRAM)) { - switch (CheckFormat) { - case WINED3DFMT_V8U8: - case WINED3DFMT_V16U16: - case WINED3DFMT_L6V5U5: - case WINED3DFMT_X8L8V8U8: - case WINED3DFMT_Q8W8V8U8: - TRACE_(d3d_caps)("[OK]\n"); - return TRUE; - default: - TRACE_(d3d_caps)("[FAILED]\n"); - return FALSE; - } - } - TRACE_(d3d_caps)("[FAILED]\n"); - return FALSE; } /* Check if the given DisplayFormat + DepthStencilFormat combination is valid for the Adapter */ @@ -2186,8 +2183,12 @@ static BOOL CheckWrapAndMipCapability(UINT Adapter, WINED3DFORMAT CheckFormat) { } /* Check if a texture format is supported on the given adapter */ -static BOOL CheckTextureCapability(UINT Adapter, WINED3DFORMAT CheckFormat) +static BOOL CheckTextureCapability(UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DFORMAT CheckFormat) { + const shader_backend_t *shader_backend; + const struct fragment_pipeline *fp; + const GlPixelFormatDesc *glDesc; + switch (CheckFormat) { /***** @@ -2247,53 +2248,33 @@ static BOOL CheckTextureCapability(UINT Adapter, WINED3DFORMAT CheckFormat) /***** * Not supported everywhere(depends on GL_ATI_envmap_bumpmap or - * GL_NV_texture_shader), but advertized to make apps happy. - * Enable some because games often fail when they are not available - * and are still playable even without bump mapping + * GL_NV_texture_shader). Emulated by shaders */ case WINED3DFMT_V8U8: - if(GL_SUPPORT(NV_TEXTURE_SHADER) || GL_SUPPORT(ATI_ENVMAP_BUMPMAP) || - GL_SUPPORT(ATI_FRAGMENT_SHADER)) { - return TRUE; - } - if(GL_SUPPORT(ARB_FRAGMENT_SHADER) || GL_SUPPORT(ARB_FRAGMENT_PROGRAM)) { - /* Shader emulated */ - return TRUE; - } - TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n"); - return FALSE; - case WINED3DFMT_X8L8V8U8: case WINED3DFMT_L6V5U5: - if(GL_SUPPORT(ARB_FRAGMENT_SHADER) || GL_SUPPORT(ARB_FRAGMENT_PROGRAM)) { - /* Shader emulated */ - return TRUE; - } - WARN_(d3d_caps)("[FAILED]\n"); - return FALSE; - case WINED3DFMT_Q8W8V8U8: case WINED3DFMT_V16U16: - if(GL_SUPPORT(NV_TEXTURE_SHADER)) { - WARN_(d3d_caps)("[Not supported, but pretended to do]\n"); - return TRUE; - } - if(GL_SUPPORT(ARB_FRAGMENT_SHADER) || GL_SUPPORT(ARB_FRAGMENT_PROGRAM)) { - /* Shader emulated */ - return TRUE; - } - TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n"); - return FALSE; - - /* Those are not advertized by the nvidia windows driver, and not - * supported natively by GL_NV_texture_shader or GL_ATI_envmap_bumpmap. - * WINED3DFMT_A2W10V10U10 could be loaded into shaders using the unsigned - * ARGB format if needed - */ case WINED3DFMT_W11V11U10: case WINED3DFMT_A2W10V10U10: - WARN_(d3d_caps)("[FAILED]\n"); - return FALSE; + getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &glDesc); + if(glDesc->conversion_group == WINED3DFMT_UNKNOWN) { + /* We have a GL extension giving native support */ + TRACE_(d3d_caps)("[OK]\n"); + return TRUE; + } + + /* No native support: Ask the fixed function pipeline implementation if it + * can deal with the conversion + */ + shader_backend = select_shader_backend(Adapter, DeviceType); + if(shader_backend->shader_conv_supported(CheckFormat)) { + TRACE_(d3d_caps)("[OK]\n"); + return TRUE; + } else { + TRACE_(d3d_caps)("[FAILED]\n"); + return FALSE; + } case WINED3DFMT_DXT1: case WINED3DFMT_DXT2: @@ -2394,6 +2375,14 @@ static BOOL CheckTextureCapability(UINT Adapter, WINED3DFORMAT CheckFormat) /* Vendor specific formats */ case WINED3DFMT_ATI2N: if(GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC) || GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC)) { + shader_backend = select_shader_backend(Adapter, DeviceType); + fp = select_fragment_implementation(Adapter, DeviceType); + if(shader_backend->shader_conv_supported(CheckFormat) && + fp->conv_supported(CheckFormat)) { + TRACE_(d3d_caps)("[OK]\n"); + return TRUE; + } + TRACE_(d3d_caps)("[OK]\n"); return TRUE; } @@ -2410,12 +2399,21 @@ static BOOL CheckTextureCapability(UINT Adapter, WINED3DFORMAT CheckFormat) return FALSE; } -static BOOL CheckSurfaceCapability(UINT Adapter, WINED3DFORMAT AdapterFormat, WINED3DFORMAT CheckFormat) { +static BOOL CheckSurfaceCapability(UINT Adapter, WINED3DFORMAT AdapterFormat, WINED3DDEVTYPE DeviceType, WINED3DFORMAT CheckFormat) { + const struct blit_shader *blitter; + /* All format that are supported for textures are supported for surfaces as well */ - if(CheckTextureCapability(Adapter, CheckFormat)) return TRUE; + if(CheckTextureCapability(Adapter, DeviceType, CheckFormat)) return TRUE; /* All depth stencil formats are supported on surfaces */ if(CheckDepthStencilCapability(Adapter, AdapterFormat, CheckFormat)) return TRUE; + /* If opengl can't process the format natively, the blitter may be able to convert it */ + blitter = select_blit_implementation(Adapter, DeviceType); + if(blitter->conv_supported(CheckFormat)) { + TRACE_(d3d_caps)("[OK]\n"); + return TRUE; + } + /* Reject other formats */ TRACE_(d3d_caps)("[FAILED]\n"); return FALSE; @@ -2474,7 +2472,7 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapt */ if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) { /* Check if the texture format is around */ - if(CheckTextureCapability(Adapter, CheckFormat)) { + if(CheckTextureCapability(Adapter, DeviceType, CheckFormat)) { if(Usage & WINED3DUSAGE_AUTOGENMIPMAP) { /* Check for automatic mipmap generation support */ if(GL_SUPPORT(SGIS_GENERATE_MIPMAP)) { @@ -2576,7 +2574,7 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapt * - D3DUSAGE_RENDERTARGET */ - if(CheckSurfaceCapability(Adapter, AdapterFormat, CheckFormat)) { + if(CheckSurfaceCapability(Adapter, AdapterFormat, DeviceType, CheckFormat)) { if(Usage & WINED3DUSAGE_DEPTHSTENCIL) { if(CheckDepthStencilCapability(Adapter, AdapterFormat, CheckFormat)) { UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL; @@ -2623,7 +2621,7 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapt */ /* Check if the texture format is around */ - if(CheckTextureCapability(Adapter, CheckFormat)) { + if(CheckTextureCapability(Adapter, DeviceType, CheckFormat)) { if(Usage & WINED3DUSAGE_AUTOGENMIPMAP) { /* Check for automatic mipmap generation support */ if(GL_SUPPORT(SGIS_GENERATE_MIPMAP)) { @@ -2663,7 +2661,7 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapt /* Check QUERY_LEGACYBUMPMAP support */ if(Usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP) { - if(CheckBumpMapCapability(Adapter, CheckFormat)) { + if(CheckBumpMapCapability(Adapter, DeviceType, CheckFormat)) { UsageCaps |= WINED3DUSAGE_QUERY_LEGACYBUMPMAP; } else { TRACE_(d3d_caps)("[FAILED] - No legacy bumpmap support\n"); @@ -2746,7 +2744,7 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapt /* Check volume texture and volume usage caps */ if(GL_SUPPORT(EXT_TEXTURE3D)) { - if(CheckTextureCapability(Adapter, CheckFormat) == FALSE) { + if(CheckTextureCapability(Adapter, DeviceType, CheckFormat) == FALSE) { TRACE_(d3d_caps)("[FAILED] - Format not supported\n"); return WINED3DERR_NOTAVAILABLE; } diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 925a07ca57f..63d95fd9b30 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -3731,6 +3731,23 @@ static void shader_glsl_get_caps(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_inf TRACE_(d3d_caps)("Hardware pixel shader version %d.%d enabled (GLSL)\n", (pCaps->PixelShaderVersion >> 8) & 0xff, pCaps->PixelShaderVersion & 0xff); } +static BOOL shader_glsl_conv_supported(WINED3DFORMAT fmt) { + TRACE("Checking shader format support for format %s:", debug_d3dformat(fmt)); + switch(fmt) { + case WINED3DFMT_V8U8: + case WINED3DFMT_V16U16: + case WINED3DFMT_X8L8V8U8: + case WINED3DFMT_L6V5U5: + case WINED3DFMT_Q8W8V8U8: + case WINED3DFMT_ATI2N: + TRACE("[OK]\n"); + return TRUE; + default: + TRACE("[FAILED\n"); + return FALSE; + } +} + const shader_backend_t glsl_shader_backend = { shader_glsl_select, shader_glsl_select_depth_blt, @@ -3745,4 +3762,5 @@ const shader_backend_t glsl_shader_backend = { shader_glsl_generate_pshader, shader_glsl_generate_vshader, shader_glsl_get_caps, + shader_glsl_conv_supported, }; diff --git a/dlls/wined3d/nvidia_texture_shader.c b/dlls/wined3d/nvidia_texture_shader.c index e2176785553..aea99607454 100644 --- a/dlls/wined3d/nvidia_texture_shader.c +++ b/dlls/wined3d/nvidia_texture_shader.c @@ -673,6 +673,11 @@ static void nvrc_fragment_free(IWineD3DDevice *iface) {} * register combiners extension(Pre-GF3). */ +static BOOL nvts_conv_supported(WINED3DFORMAT fmt) { + TRACE("Checking shader format support for format %s: [FAILED]", debug_d3dformat(fmt)); + return FALSE; +} + const struct StateEntryTemplate nvrc_fragmentstate_template[] = { { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), nvrc_colorop }, 0 }, { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), nvrc_colorop }, 0 }, @@ -805,6 +810,7 @@ const struct fragment_pipeline nvts_fragment_pipeline = { nvrc_fragment_get_caps, nvrc_fragment_alloc, nvrc_fragment_free, + nvts_conv_supported, nvrc_fragmentstate_template }; @@ -813,5 +819,6 @@ const struct fragment_pipeline nvrc_fragment_pipeline = { nvrc_fragment_get_caps, nvrc_fragment_alloc, nvrc_fragment_free, + nvts_conv_supported, nvrc_fragmentstate_template }; diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index dd81378ff5f..84be28bedf7 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -5620,12 +5620,17 @@ static void ffp_fragment_get_caps(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_in static HRESULT ffp_fragment_alloc(IWineD3DDevice *iface) { return WINED3D_OK; } static void ffp_fragment_free(IWineD3DDevice *iface) {} +static BOOL ffp_conv_supported(WINED3DFORMAT fmt) { + TRACE("Checking shader format support for format %s: [FAILED]", debug_d3dformat(fmt)); + return FALSE; +} const struct fragment_pipeline ffp_fragment_pipeline = { ffp_enable, ffp_fragment_get_caps, ffp_fragment_alloc, ffp_fragment_free, + ffp_conv_supported, ffp_fragmentstate_template }; diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 197ff168e69..9a50e84fe46 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -4648,9 +4648,15 @@ static void ffp_blit_unset(IWineD3DDevice *iface) { } } +static BOOL ffp_blit_conv_supported(WINED3DFORMAT fmt) { + TRACE("Checking blit format support for format %s: [FAILED]\n", debug_d3dformat(fmt)); + return FALSE; +} + const struct blit_shader ffp_blit = { ffp_blit_alloc, ffp_blit_free, ffp_blit_set, - ffp_blit_unset + ffp_blit_unset, + ffp_blit_conv_supported }; diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index cf8c3cd81a2..6f3a447c911 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -413,6 +413,21 @@ BOOL initPixelFormats(WineD3D_GL_Info *gl_info) gl_info->gl_formats[dst].conversion_group= WINED3DFMT_ATI2N; } + if(!GL_SUPPORT(APPLE_YCBCR_422)) { + dst = getFmtIdx(WINED3DFMT_YUY2); + gl_info->gl_formats[dst].glInternal = GL_LUMINANCE_ALPHA; + gl_info->gl_formats[dst].glGammaInternal = GL_LUMINANCE_ALPHA; /* not srgb */ + gl_info->gl_formats[dst].glFormat = GL_LUMINANCE_ALPHA; + gl_info->gl_formats[dst].glType = GL_UNSIGNED_BYTE; + gl_info->gl_formats[dst].conversion_group = WINED3DFMT_YUY2; + + dst = getFmtIdx(WINED3DFMT_UYVY); + gl_info->gl_formats[dst].glInternal = GL_LUMINANCE_ALPHA; + gl_info->gl_formats[dst].glGammaInternal = GL_LUMINANCE_ALPHA; /* not srgb */ + gl_info->gl_formats[dst].glFormat = GL_LUMINANCE_ALPHA; + gl_info->gl_formats[dst].glType = GL_UNSIGNED_BYTE; + gl_info->gl_formats[dst].conversion_group = WINED3DFMT_UYVY; + } return TRUE; } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 70bac96019d..0b8cca6e04f 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -247,6 +247,7 @@ typedef struct { void (*shader_generate_pshader)(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer); void (*shader_generate_vshader)(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer); void (*shader_get_caps)(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_info, struct shader_caps *caps); + BOOL (*shader_conv_supported)(WINED3DFORMAT conv); } shader_backend_t; extern const shader_backend_t atifs_shader_backend; @@ -556,6 +557,7 @@ struct fragment_pipeline { void (*get_caps)(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_info, struct fragment_caps *caps); HRESULT (*alloc_private)(IWineD3DDevice *iface); void (*free_private)(IWineD3DDevice *iface); + BOOL (*conv_supported)(WINED3DFORMAT conv); const struct StateEntryTemplate *states; }; @@ -581,6 +583,7 @@ struct blit_shader { void (*free_private)(IWineD3DDevice *iface); HRESULT (*set_shader)(IWineD3DDevice *iface, WINED3DFORMAT fmt, GLenum textype, UINT width, UINT height); void (*unset_shader)(IWineD3DDevice *iface); + BOOL (*conv_supported)(WINED3DFORMAT conv); }; extern const struct blit_shader ffp_blit;