2004-09-23 06:34:27 +02:00
/*
* IWineD3D implementation
*
* Copyright 2002 - 2004 Jason Edmeades
* Copyright 2003 - 2004 Raphael Junqueira
* Copyright 2004 Christian Costa
2005-06-23 13:05:24 +02:00
* Copyright 2005 Oliver Stieber
2004-09-23 06:34:27 +02:00
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library ; if not , write to the Free Software
2006-05-18 14:49:52 +02:00
* Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 , USA
2004-09-23 06:34:27 +02:00
*/
2004-09-28 04:12:12 +02:00
/* Compile time diagnostics: */
/* Uncomment this to force only a single display mode to be exposed: */
/*#define DEBUG_SINGLE_MODE*/
2004-09-23 06:34:27 +02:00
# include "config.h"
# include "wined3d_private.h"
WINE_DEFAULT_DEBUG_CHANNEL ( d3d ) ;
WINE_DECLARE_DEBUG_CHANNEL ( d3d_caps ) ;
2004-11-28 16:04:41 +01:00
# define GLINFO_LOCATION This->gl_info
2004-09-23 06:34:27 +02:00
2004-09-29 23:26:47 +02:00
/**********************************************************
* Utility functions follow
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* x11drv GDI escapes */
# define X11DRV_ESCAPE 6789
enum x11drv_escape_codes
{
X11DRV_GET_DISPLAY , /* get X11 display for a DC */
X11DRV_GET_DRAWABLE , /* get current drawable for a DC */
X11DRV_GET_FONT , /* get current X font for a DC */
} ;
/* retrieve the X display to use on a given DC */
inline static Display * get_display ( HDC hdc )
{
Display * display ;
enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY ;
if ( ! ExtEscape ( hdc , X11DRV_ESCAPE , sizeof ( escape ) , ( LPCSTR ) & escape ,
sizeof ( display ) , ( LPSTR ) & display ) ) display = NULL ;
return display ;
}
2005-08-03 13:00:28 +02:00
/* lookup tables */
int minLookup [ MAX_LOOKUPS ] ;
int maxLookup [ MAX_LOOKUPS ] ;
DWORD * stateLookup [ MAX_LOOKUPS ] ;
2006-04-06 19:02:16 +02:00
DWORD minMipLookup [ WINED3DTEXF_ANISOTROPIC + 1 ] [ WINED3DTEXF_LINEAR + 1 ] ;
2005-08-03 13:00:28 +02:00
2004-09-29 23:26:47 +02:00
/**
* Note : GL seems to trap if GetDeviceCaps is called before any HWND ' s created
2005-07-13 16:15:54 +02:00
* ie there is no GL Context - Get a default rendering context to enable the
* function query some info from GL
*/
2004-09-29 23:26:47 +02:00
static WineD3D_Context * WineD3D_CreateFakeGLContext ( void ) {
static WineD3D_Context ctx = { NULL , NULL , NULL , 0 , 0 } ;
WineD3D_Context * ret = NULL ;
if ( glXGetCurrentContext ( ) = = NULL ) {
BOOL gotContext = FALSE ;
BOOL created = FALSE ;
XVisualInfo template ;
HDC device_context ;
Visual * visual ;
BOOL failed = FALSE ;
int num ;
XWindowAttributes win_attr ;
2005-07-13 16:15:54 +02:00
2004-09-29 23:26:47 +02:00
TRACE_ ( d3d_caps ) ( " Creating Fake GL Context \n " ) ;
ctx . drawable = ( Drawable ) GetPropA ( GetDesktopWindow ( ) , " __wine_x11_whole_window " ) ;
/* Get the display */
device_context = GetDC ( 0 ) ;
ctx . display = get_display ( device_context ) ;
ReleaseDC ( 0 , device_context ) ;
2005-07-13 16:15:54 +02:00
2004-09-29 23:26:47 +02:00
/* Get the X visual */
ENTER_GL ( ) ;
if ( XGetWindowAttributes ( ctx . display , ctx . drawable , & win_attr ) ) {
visual = win_attr . visual ;
} else {
visual = DefaultVisual ( ctx . display , DefaultScreen ( ctx . display ) ) ;
}
template . visualid = XVisualIDFromVisual ( visual ) ;
ctx . visInfo = XGetVisualInfo ( ctx . display , VisualIDMask , & template , & num ) ;
if ( ctx . visInfo = = NULL ) {
LEAVE_GL ( ) ;
WARN_ ( d3d_caps ) ( " Error creating visual info for capabilities initialization \n " ) ;
failed = TRUE ;
}
2005-07-13 16:15:54 +02:00
2004-09-29 23:26:47 +02:00
/* Create a GL context */
if ( ! failed ) {
ctx . glCtx = glXCreateContext ( ctx . display , ctx . visInfo , NULL , GL_TRUE ) ;
2005-07-13 16:15:54 +02:00
2004-09-29 23:26:47 +02:00
if ( ctx . glCtx = = NULL ) {
LEAVE_GL ( ) ;
WARN_ ( d3d_caps ) ( " Error creating default context for capabilities initialization \n " ) ;
failed = TRUE ;
}
}
2005-07-13 16:15:54 +02:00
2004-09-29 23:26:47 +02:00
/* Make it the current GL context */
if ( ! failed & & glXMakeCurrent ( ctx . display , ctx . drawable , ctx . glCtx ) = = False ) {
glXDestroyContext ( ctx . display , ctx . glCtx ) ;
LEAVE_GL ( ) ;
WARN_ ( d3d_caps ) ( " Error setting default context as current for capabilities initialization \n " ) ;
2005-07-13 16:15:54 +02:00
failed = TRUE ;
2004-09-29 23:26:47 +02:00
}
2005-07-13 16:15:54 +02:00
2004-09-29 23:26:47 +02:00
/* It worked! Wow... */
if ( ! failed ) {
gotContext = TRUE ;
created = TRUE ;
ret = & ctx ;
} else {
ret = NULL ;
}
} else {
if ( ctx . ref > 0 ) ret = & ctx ;
}
if ( NULL ! = ret ) InterlockedIncrement ( & ret - > ref ) ;
return ret ;
}
static void WineD3D_ReleaseFakeGLContext ( WineD3D_Context * ctx ) {
/* If we created a dummy context, throw it away */
if ( NULL ! = ctx ) {
if ( 0 = = InterlockedDecrement ( & ctx - > ref ) ) {
glXMakeCurrent ( ctx - > display , None , NULL ) ;
glXDestroyContext ( ctx - > display , ctx - > glCtx ) ;
ctx - > display = NULL ;
ctx - > glCtx = NULL ;
LEAVE_GL ( ) ;
}
}
}
2005-03-02 14:44:58 +01:00
/**********************************************************
* IUnknown parts follows
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DImpl_QueryInterface ( IWineD3D * iface , REFIID riid , LPVOID * ppobj )
2005-03-02 14:44:58 +01:00
{
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2005-07-13 16:15:54 +02:00
2005-03-02 14:44:58 +01:00
TRACE ( " (%p)->(%s,%p) \n " , This , debugstr_guid ( riid ) , ppobj ) ;
2005-07-13 16:15:54 +02:00
if ( IsEqualGUID ( riid , & IID_IUnknown )
2006-02-06 11:32:41 +01:00
| | IsEqualGUID ( riid , & IID_IWineD3DBase )
2005-03-02 14:44:58 +01:00
| | IsEqualGUID ( riid , & IID_IWineD3DDevice ) ) {
IUnknown_AddRef ( iface ) ;
* ppobj = This ;
2006-04-25 23:59:12 +02:00
return S_OK ;
2005-03-02 14:44:58 +01:00
}
2006-04-25 23:59:12 +02:00
* ppobj = NULL ;
2005-03-02 14:44:58 +01:00
return E_NOINTERFACE ;
}
2006-06-10 13:15:32 +02:00
static ULONG WINAPI IWineD3DImpl_AddRef ( IWineD3D * iface ) {
2005-03-02 14:44:58 +01:00
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
ULONG refCount = InterlockedIncrement ( & This - > ref ) ;
TRACE ( " (%p) : AddRef increasing from %ld \n " , This , refCount - 1 ) ;
return refCount ;
}
2006-06-10 13:15:32 +02:00
static ULONG WINAPI IWineD3DImpl_Release ( IWineD3D * iface ) {
2005-03-02 14:44:58 +01:00
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
ULONG ref ;
TRACE ( " (%p) : Releasing from %ld \n " , This , This - > ref ) ;
ref = InterlockedDecrement ( & This - > ref ) ;
if ( ref = = 0 ) {
HeapFree ( GetProcessHeap ( ) , 0 , This ) ;
}
2005-07-13 16:15:54 +02:00
2005-03-02 14:44:58 +01:00
return ref ;
}
wined3d: Rework shader mode selection.
- currently half the shader selection code (GLSL vs ARB) is in
fillGLcaps. The parts that check for software shaders are in
GetDeviceCaps. That placement, will work, but is definitely not optimal.
FillGLcaps should detect support - it should not make decision as to
what's used, because that's not what the purpose of the function is.
GetDeviceCaps should report support as it has already been selected.
Instead, select shader mode in its own function, called in the
appropriate places.
- unifying pixel and vertex shaders into a single selection is a
mistake. A software vertex shader can be coupled with a hardware arb or
glsl pixel shader, or no shader at all. Split them back into two and add
a SHADER_NONE variant.
- drawprim is doing support checks for ARB_PROGRAM, and making shader
decisions based on that - that's wrong, support has already been
checked, and decided upon, and shaders can be implemented via software,
ARB_PROGRAm or GLSL, so that support check isn't valid.
- Store the shader selected mode into the shader itself. Different types
of shaders can be combined, so this is an improvement. In fact, storing
the mode into the settings globally is a mistake as well - it should be
done per device, since different cards have different capabilities.
2006-07-04 09:21:53 +02:00
/* Set the shader type for this device, depending on the given capabilities,
* the device type , and the user preferences in wined3d_settings */
static void select_shader_mode (
WineD3D_GL_Info * gl_info ,
WINED3DDEVTYPE DeviceType ,
int * ps_selected ,
int * vs_selected ) {
/* Give priority to user disable/emulation request.
* Then respect REF device for software .
* Then check capabilities for hardware , and fallback to software */
2006-07-19 06:06:07 +02:00
if ( wined3d_settings . vs_mode = = VS_NONE ) {
wined3d: Rework shader mode selection.
- currently half the shader selection code (GLSL vs ARB) is in
fillGLcaps. The parts that check for software shaders are in
GetDeviceCaps. That placement, will work, but is definitely not optimal.
FillGLcaps should detect support - it should not make decision as to
what's used, because that's not what the purpose of the function is.
GetDeviceCaps should report support as it has already been selected.
Instead, select shader mode in its own function, called in the
appropriate places.
- unifying pixel and vertex shaders into a single selection is a
mistake. A software vertex shader can be coupled with a hardware arb or
glsl pixel shader, or no shader at all. Split them back into two and add
a SHADER_NONE variant.
- drawprim is doing support checks for ARB_PROGRAM, and making shader
decisions based on that - that's wrong, support has already been
checked, and decided upon, and shaders can be implemented via software,
ARB_PROGRAm or GLSL, so that support check isn't valid.
- Store the shader selected mode into the shader itself. Different types
of shaders can be combined, so this is an improvement. In fact, storing
the mode into the settings globally is a mistake as well - it should be
done per device, since different cards have different capabilities.
2006-07-04 09:21:53 +02:00
* vs_selected = SHADER_NONE ;
2006-07-19 06:06:07 +02:00
} else if ( DeviceType = = WINED3DDEVTYPE_REF | | wined3d_settings . vs_mode = = VS_SW ) {
wined3d: Rework shader mode selection.
- currently half the shader selection code (GLSL vs ARB) is in
fillGLcaps. The parts that check for software shaders are in
GetDeviceCaps. That placement, will work, but is definitely not optimal.
FillGLcaps should detect support - it should not make decision as to
what's used, because that's not what the purpose of the function is.
GetDeviceCaps should report support as it has already been selected.
Instead, select shader mode in its own function, called in the
appropriate places.
- unifying pixel and vertex shaders into a single selection is a
mistake. A software vertex shader can be coupled with a hardware arb or
glsl pixel shader, or no shader at all. Split them back into two and add
a SHADER_NONE variant.
- drawprim is doing support checks for ARB_PROGRAM, and making shader
decisions based on that - that's wrong, support has already been
checked, and decided upon, and shaders can be implemented via software,
ARB_PROGRAm or GLSL, so that support check isn't valid.
- Store the shader selected mode into the shader itself. Different types
of shaders can be combined, so this is an improvement. In fact, storing
the mode into the settings globally is a mistake as well - it should be
done per device, since different cards have different capabilities.
2006-07-04 09:21:53 +02:00
* vs_selected = SHADER_SW ;
2006-07-30 23:28:10 +02:00
} else if ( gl_info - > supported [ ARB_VERTEX_SHADER ] & & wined3d_settings . glslRequested ) {
wined3d: Rework shader mode selection.
- currently half the shader selection code (GLSL vs ARB) is in
fillGLcaps. The parts that check for software shaders are in
GetDeviceCaps. That placement, will work, but is definitely not optimal.
FillGLcaps should detect support - it should not make decision as to
what's used, because that's not what the purpose of the function is.
GetDeviceCaps should report support as it has already been selected.
Instead, select shader mode in its own function, called in the
appropriate places.
- unifying pixel and vertex shaders into a single selection is a
mistake. A software vertex shader can be coupled with a hardware arb or
glsl pixel shader, or no shader at all. Split them back into two and add
a SHADER_NONE variant.
- drawprim is doing support checks for ARB_PROGRAM, and making shader
decisions based on that - that's wrong, support has already been
checked, and decided upon, and shaders can be implemented via software,
ARB_PROGRAm or GLSL, so that support check isn't valid.
- Store the shader selected mode into the shader itself. Different types
of shaders can be combined, so this is an improvement. In fact, storing
the mode into the settings globally is a mistake as well - it should be
done per device, since different cards have different capabilities.
2006-07-04 09:21:53 +02:00
* vs_selected = SHADER_GLSL ;
2006-07-19 06:06:07 +02:00
} else if ( gl_info - > supported [ ARB_VERTEX_PROGRAM ] ) {
wined3d: Rework shader mode selection.
- currently half the shader selection code (GLSL vs ARB) is in
fillGLcaps. The parts that check for software shaders are in
GetDeviceCaps. That placement, will work, but is definitely not optimal.
FillGLcaps should detect support - it should not make decision as to
what's used, because that's not what the purpose of the function is.
GetDeviceCaps should report support as it has already been selected.
Instead, select shader mode in its own function, called in the
appropriate places.
- unifying pixel and vertex shaders into a single selection is a
mistake. A software vertex shader can be coupled with a hardware arb or
glsl pixel shader, or no shader at all. Split them back into two and add
a SHADER_NONE variant.
- drawprim is doing support checks for ARB_PROGRAM, and making shader
decisions based on that - that's wrong, support has already been
checked, and decided upon, and shaders can be implemented via software,
ARB_PROGRAm or GLSL, so that support check isn't valid.
- Store the shader selected mode into the shader itself. Different types
of shaders can be combined, so this is an improvement. In fact, storing
the mode into the settings globally is a mistake as well - it should be
done per device, since different cards have different capabilities.
2006-07-04 09:21:53 +02:00
* vs_selected = SHADER_ARB ;
2006-07-19 06:06:07 +02:00
} else {
wined3d: Rework shader mode selection.
- currently half the shader selection code (GLSL vs ARB) is in
fillGLcaps. The parts that check for software shaders are in
GetDeviceCaps. That placement, will work, but is definitely not optimal.
FillGLcaps should detect support - it should not make decision as to
what's used, because that's not what the purpose of the function is.
GetDeviceCaps should report support as it has already been selected.
Instead, select shader mode in its own function, called in the
appropriate places.
- unifying pixel and vertex shaders into a single selection is a
mistake. A software vertex shader can be coupled with a hardware arb or
glsl pixel shader, or no shader at all. Split them back into two and add
a SHADER_NONE variant.
- drawprim is doing support checks for ARB_PROGRAM, and making shader
decisions based on that - that's wrong, support has already been
checked, and decided upon, and shaders can be implemented via software,
ARB_PROGRAm or GLSL, so that support check isn't valid.
- Store the shader selected mode into the shader itself. Different types
of shaders can be combined, so this is an improvement. In fact, storing
the mode into the settings globally is a mistake as well - it should be
done per device, since different cards have different capabilities.
2006-07-04 09:21:53 +02:00
* vs_selected = SHADER_SW ;
2006-07-19 06:06:07 +02:00
}
wined3d: Rework shader mode selection.
- currently half the shader selection code (GLSL vs ARB) is in
fillGLcaps. The parts that check for software shaders are in
GetDeviceCaps. That placement, will work, but is definitely not optimal.
FillGLcaps should detect support - it should not make decision as to
what's used, because that's not what the purpose of the function is.
GetDeviceCaps should report support as it has already been selected.
Instead, select shader mode in its own function, called in the
appropriate places.
- unifying pixel and vertex shaders into a single selection is a
mistake. A software vertex shader can be coupled with a hardware arb or
glsl pixel shader, or no shader at all. Split them back into two and add
a SHADER_NONE variant.
- drawprim is doing support checks for ARB_PROGRAM, and making shader
decisions based on that - that's wrong, support has already been
checked, and decided upon, and shaders can be implemented via software,
ARB_PROGRAm or GLSL, so that support check isn't valid.
- Store the shader selected mode into the shader itself. Different types
of shaders can be combined, so this is an improvement. In fact, storing
the mode into the settings globally is a mistake as well - it should be
done per device, since different cards have different capabilities.
2006-07-04 09:21:53 +02:00
/* Fallback to SHADER_NONE where software pixel shaders should be used */
2006-07-19 06:06:07 +02:00
if ( wined3d_settings . ps_mode = = PS_NONE ) {
wined3d: Rework shader mode selection.
- currently half the shader selection code (GLSL vs ARB) is in
fillGLcaps. The parts that check for software shaders are in
GetDeviceCaps. That placement, will work, but is definitely not optimal.
FillGLcaps should detect support - it should not make decision as to
what's used, because that's not what the purpose of the function is.
GetDeviceCaps should report support as it has already been selected.
Instead, select shader mode in its own function, called in the
appropriate places.
- unifying pixel and vertex shaders into a single selection is a
mistake. A software vertex shader can be coupled with a hardware arb or
glsl pixel shader, or no shader at all. Split them back into two and add
a SHADER_NONE variant.
- drawprim is doing support checks for ARB_PROGRAM, and making shader
decisions based on that - that's wrong, support has already been
checked, and decided upon, and shaders can be implemented via software,
ARB_PROGRAm or GLSL, so that support check isn't valid.
- Store the shader selected mode into the shader itself. Different types
of shaders can be combined, so this is an improvement. In fact, storing
the mode into the settings globally is a mistake as well - it should be
done per device, since different cards have different capabilities.
2006-07-04 09:21:53 +02:00
* ps_selected = SHADER_NONE ;
2006-07-19 06:06:07 +02:00
} else if ( DeviceType = = WINED3DDEVTYPE_REF ) {
wined3d: Rework shader mode selection.
- currently half the shader selection code (GLSL vs ARB) is in
fillGLcaps. The parts that check for software shaders are in
GetDeviceCaps. That placement, will work, but is definitely not optimal.
FillGLcaps should detect support - it should not make decision as to
what's used, because that's not what the purpose of the function is.
GetDeviceCaps should report support as it has already been selected.
Instead, select shader mode in its own function, called in the
appropriate places.
- unifying pixel and vertex shaders into a single selection is a
mistake. A software vertex shader can be coupled with a hardware arb or
glsl pixel shader, or no shader at all. Split them back into two and add
a SHADER_NONE variant.
- drawprim is doing support checks for ARB_PROGRAM, and making shader
decisions based on that - that's wrong, support has already been
checked, and decided upon, and shaders can be implemented via software,
ARB_PROGRAm or GLSL, so that support check isn't valid.
- Store the shader selected mode into the shader itself. Different types
of shaders can be combined, so this is an improvement. In fact, storing
the mode into the settings globally is a mistake as well - it should be
done per device, since different cards have different capabilities.
2006-07-04 09:21:53 +02:00
* ps_selected = SHADER_NONE ;
2006-07-30 23:28:10 +02:00
} else if ( gl_info - > supported [ ARB_FRAGMENT_SHADER ] & & wined3d_settings . glslRequested ) {
wined3d: Rework shader mode selection.
- currently half the shader selection code (GLSL vs ARB) is in
fillGLcaps. The parts that check for software shaders are in
GetDeviceCaps. That placement, will work, but is definitely not optimal.
FillGLcaps should detect support - it should not make decision as to
what's used, because that's not what the purpose of the function is.
GetDeviceCaps should report support as it has already been selected.
Instead, select shader mode in its own function, called in the
appropriate places.
- unifying pixel and vertex shaders into a single selection is a
mistake. A software vertex shader can be coupled with a hardware arb or
glsl pixel shader, or no shader at all. Split them back into two and add
a SHADER_NONE variant.
- drawprim is doing support checks for ARB_PROGRAM, and making shader
decisions based on that - that's wrong, support has already been
checked, and decided upon, and shaders can be implemented via software,
ARB_PROGRAm or GLSL, so that support check isn't valid.
- Store the shader selected mode into the shader itself. Different types
of shaders can be combined, so this is an improvement. In fact, storing
the mode into the settings globally is a mistake as well - it should be
done per device, since different cards have different capabilities.
2006-07-04 09:21:53 +02:00
* ps_selected = SHADER_GLSL ;
2006-07-19 06:06:07 +02:00
} else if ( gl_info - > supported [ ARB_FRAGMENT_PROGRAM ] ) {
wined3d: Rework shader mode selection.
- currently half the shader selection code (GLSL vs ARB) is in
fillGLcaps. The parts that check for software shaders are in
GetDeviceCaps. That placement, will work, but is definitely not optimal.
FillGLcaps should detect support - it should not make decision as to
what's used, because that's not what the purpose of the function is.
GetDeviceCaps should report support as it has already been selected.
Instead, select shader mode in its own function, called in the
appropriate places.
- unifying pixel and vertex shaders into a single selection is a
mistake. A software vertex shader can be coupled with a hardware arb or
glsl pixel shader, or no shader at all. Split them back into two and add
a SHADER_NONE variant.
- drawprim is doing support checks for ARB_PROGRAM, and making shader
decisions based on that - that's wrong, support has already been
checked, and decided upon, and shaders can be implemented via software,
ARB_PROGRAm or GLSL, so that support check isn't valid.
- Store the shader selected mode into the shader itself. Different types
of shaders can be combined, so this is an improvement. In fact, storing
the mode into the settings globally is a mistake as well - it should be
done per device, since different cards have different capabilities.
2006-07-04 09:21:53 +02:00
* ps_selected = SHADER_ARB ;
2006-07-19 06:06:07 +02:00
} else {
wined3d: Rework shader mode selection.
- currently half the shader selection code (GLSL vs ARB) is in
fillGLcaps. The parts that check for software shaders are in
GetDeviceCaps. That placement, will work, but is definitely not optimal.
FillGLcaps should detect support - it should not make decision as to
what's used, because that's not what the purpose of the function is.
GetDeviceCaps should report support as it has already been selected.
Instead, select shader mode in its own function, called in the
appropriate places.
- unifying pixel and vertex shaders into a single selection is a
mistake. A software vertex shader can be coupled with a hardware arb or
glsl pixel shader, or no shader at all. Split them back into two and add
a SHADER_NONE variant.
- drawprim is doing support checks for ARB_PROGRAM, and making shader
decisions based on that - that's wrong, support has already been
checked, and decided upon, and shaders can be implemented via software,
ARB_PROGRAm or GLSL, so that support check isn't valid.
- Store the shader selected mode into the shader itself. Different types
of shaders can be combined, so this is an improvement. In fact, storing
the mode into the settings globally is a mistake as well - it should be
done per device, since different cards have different capabilities.
2006-07-04 09:21:53 +02:00
* ps_selected = SHADER_NONE ;
2006-07-19 06:06:07 +02:00
}
wined3d: Rework shader mode selection.
- currently half the shader selection code (GLSL vs ARB) is in
fillGLcaps. The parts that check for software shaders are in
GetDeviceCaps. That placement, will work, but is definitely not optimal.
FillGLcaps should detect support - it should not make decision as to
what's used, because that's not what the purpose of the function is.
GetDeviceCaps should report support as it has already been selected.
Instead, select shader mode in its own function, called in the
appropriate places.
- unifying pixel and vertex shaders into a single selection is a
mistake. A software vertex shader can be coupled with a hardware arb or
glsl pixel shader, or no shader at all. Split them back into two and add
a SHADER_NONE variant.
- drawprim is doing support checks for ARB_PROGRAM, and making shader
decisions based on that - that's wrong, support has already been
checked, and decided upon, and shaders can be implemented via software,
ARB_PROGRAm or GLSL, so that support check isn't valid.
- Store the shader selected mode into the shader itself. Different types
of shaders can be combined, so this is an improvement. In fact, storing
the mode into the settings globally is a mistake as well - it should be
done per device, since different cards have different capabilities.
2006-07-04 09:21:53 +02:00
}
2006-07-23 21:08:27 +02:00
/** Select the number of report maximum shader constants based on the selected shader modes */
void select_shader_max_constants ( WineD3D_GL_Info * gl_info ) {
switch ( wined3d_settings . vs_selected_mode ) {
case SHADER_GLSL :
2006-07-28 10:14:14 +02:00
/* Subtract the other potential uniforms from the max available (bools, ints, and 1 row of projection matrix) */
gl_info - > max_vshader_constantsF = gl_info - > vs_glsl_constantsF - MAX_CONST_B - MAX_CONST_I - 1 ;
2006-07-23 21:08:27 +02:00
break ;
case SHADER_ARB :
2006-07-27 04:13:32 +02:00
/* We have to subtract any other PARAMs that we might use in our shader programs.
* ATI seems to count 2 implicit PARAMs when we use fog and NVIDIA counts 1 ,
* and we reference one row of the PROJECTION matrix which counts as 1 PARAM . */
gl_info - > max_vshader_constantsF = gl_info - > vs_arb_constantsF - 3 ;
2006-07-23 21:08:27 +02:00
break ;
case SHADER_SW :
gl_info - > max_vshader_constantsF = 96 ; /* TODO: Fixup software shaders */
break ;
default :
gl_info - > max_vshader_constantsF = 0 ;
break ;
}
switch ( wined3d_settings . ps_selected_mode ) {
case SHADER_GLSL :
/* Subtract the other potential uniforms from the max available (bools & ints) */
gl_info - > max_pshader_constantsF = gl_info - > ps_glsl_constantsF - MAX_CONST_B - MAX_CONST_I ;
break ;
case SHADER_ARB :
gl_info - > max_pshader_constantsF = gl_info - > ps_arb_constantsF ;
break ;
case SHADER_SW :
gl_info - > max_pshader_constantsF = 96 ; /* TODO: Fixup software shaders */
break ;
default :
gl_info - > max_pshader_constantsF = 0 ;
break ;
}
}
2005-03-02 14:44:58 +01:00
/**********************************************************
* IWineD3D parts follows
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-07-19 23:49:37 +02:00
BOOL IWineD3DImpl_FillGLCaps ( IWineD3D * iface , Display * display ) {
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
WineD3D_GL_Info * gl_info = & This - > gl_info ;
2004-09-29 23:26:47 +02:00
const char * GL_Extensions = NULL ;
const char * GLX_Extensions = NULL ;
const char * gl_string = NULL ;
const char * gl_string_cursor = NULL ;
GLint gl_max ;
2005-07-10 19:48:07 +02:00
GLfloat gl_float ;
2004-09-29 23:26:47 +02:00
Bool test = 0 ;
int major , minor ;
2005-07-10 19:48:07 +02:00
WineD3D_Context * fake_ctx = NULL ;
2005-08-03 13:00:28 +02:00
BOOL gotContext = FALSE ;
int i ;
2005-07-10 19:48:07 +02:00
/* Make sure that we've got a context */
if ( glXGetCurrentContext ( ) = = NULL ) {
/* TODO: CreateFakeGLContext should really take a display as a parameter */
fake_ctx = WineD3D_CreateFakeGLContext ( ) ;
if ( NULL ! = fake_ctx ) gotContext = TRUE ;
} else {
gotContext = TRUE ;
}
2004-09-29 23:26:47 +02:00
TRACE_ ( d3d_caps ) ( " (%p, %p) \n " , gl_info , display ) ;
2005-11-30 12:02:45 +01:00
gl_string = ( const char * ) glGetString ( GL_RENDERER ) ;
strcpy ( gl_info - > gl_renderer , gl_string ) ;
2004-09-29 23:26:47 +02:00
/* Fill in the GL info retrievable depending on the display */
if ( NULL ! = display ) {
test = glXQueryVersion ( display , & major , & minor ) ;
gl_info - > glx_version = ( ( major & 0x0000FFFF ) < < 16 ) | ( minor & 0x0000FFFF ) ;
} else {
2005-07-10 19:48:07 +02:00
FIXME ( " Display must not be NULL, use glXGetCurrentDisplay or getAdapterDisplay() \n " ) ;
2004-09-29 23:26:47 +02:00
}
2006-01-19 11:55:34 +01:00
gl_string = ( const char * ) glGetString ( GL_VENDOR ) ;
2005-07-10 19:48:07 +02:00
TRACE_ ( d3d_caps ) ( " Filling vendor string %s \n " , gl_string ) ;
if ( gl_string ! = NULL ) {
/* Fill in the GL vendor */
if ( strstr ( gl_string , " NVIDIA " ) ) {
gl_info - > gl_vendor = VENDOR_NVIDIA ;
} else if ( strstr ( gl_string , " ATI " ) ) {
gl_info - > gl_vendor = VENDOR_ATI ;
2005-11-30 12:02:45 +01:00
} else if ( strstr ( gl_string , " Intel(R) " ) | |
strstr ( gl_info - > gl_renderer , " Intel(R) " ) ) {
gl_info - > gl_vendor = VENDOR_INTEL ;
2005-11-10 12:04:59 +01:00
} else if ( strstr ( gl_string , " Mesa " ) ) {
gl_info - > gl_vendor = VENDOR_MESA ;
2005-07-10 19:48:07 +02:00
} else {
gl_info - > gl_vendor = VENDOR_WINE ;
}
2004-09-29 23:26:47 +02:00
} else {
gl_info - > gl_vendor = VENDOR_WINE ;
}
2005-07-10 19:48:07 +02:00
2004-09-29 23:26:47 +02:00
TRACE_ ( d3d_caps ) ( " found GL_VENDOR (%s)->(0x%04x) \n " , debugstr_a ( gl_string ) , gl_info - > gl_vendor ) ;
2005-07-10 19:48:07 +02:00
2004-09-29 23:26:47 +02:00
/* Parse the GL_VERSION field into major and minor information */
2005-08-11 12:57:47 +02:00
gl_string = ( const char * ) glGetString ( GL_VERSION ) ;
2005-07-10 19:48:07 +02:00
if ( gl_string ! = NULL ) {
switch ( gl_info - > gl_vendor ) {
case VENDOR_NVIDIA :
gl_string_cursor = strstr ( gl_string , " NVIDIA " ) ;
2006-01-19 12:39:37 +01:00
if ( ! gl_string_cursor ) {
ERR_ ( d3d_caps ) ( " Invalid nVidia version string: %s \n " , debugstr_a ( gl_string ) ) ;
break ;
}
2005-07-10 19:48:07 +02:00
gl_string_cursor = strstr ( gl_string_cursor , " " ) ;
2006-01-19 12:39:37 +01:00
if ( ! gl_string_cursor ) {
ERR_ ( d3d_caps ) ( " Invalid nVidia version string: %s \n " , debugstr_a ( gl_string ) ) ;
break ;
}
while ( * gl_string_cursor = = ' ' ) {
+ + gl_string_cursor ;
}
if ( ! * gl_string_cursor ) {
ERR_ ( d3d_caps ) ( " Invalid nVidia version string: %s \n " , debugstr_a ( gl_string ) ) ;
break ;
}
major = atoi ( gl_string_cursor ) ;
while ( * gl_string_cursor < = ' 9 ' & & * gl_string_cursor > = ' 0 ' ) {
2004-09-29 23:26:47 +02:00
+ + gl_string_cursor ;
2006-01-19 12:39:37 +01:00
}
2005-07-13 16:15:54 +02:00
2006-01-19 12:39:37 +01:00
if ( * gl_string_cursor + + ! = ' . ' ) {
ERR_ ( d3d_caps ) ( " Invalid nVidia version string: %s \n " , debugstr_a ( gl_string ) ) ;
break ;
2004-09-29 23:26:47 +02:00
}
2006-01-19 12:39:37 +01:00
minor = atoi ( gl_string_cursor ) ;
2006-02-11 12:16:29 +01:00
minor = major * 100 + minor ;
major = 10 ;
2006-01-19 12:39:37 +01:00
2005-07-10 19:48:07 +02:00
break ;
2005-07-13 16:15:54 +02:00
2005-07-10 19:48:07 +02:00
case VENDOR_ATI :
major = minor = 0 ;
gl_string_cursor = strchr ( gl_string , ' - ' ) ;
if ( gl_string_cursor ) {
int error = 0 ;
gl_string_cursor + + ;
2005-07-13 16:15:54 +02:00
2005-07-10 19:48:07 +02:00
/* Check if version number is of the form x.y.z */
if ( * gl_string_cursor > ' 9 ' & & * gl_string_cursor < ' 0 ' )
error = 1 ;
if ( ! error & & * ( gl_string_cursor + 2 ) > ' 9 ' & & * ( gl_string_cursor + 2 ) < ' 0 ' )
error = 1 ;
if ( ! error & & * ( gl_string_cursor + 4 ) > ' 9 ' & & * ( gl_string_cursor + 4 ) < ' 0 ' )
error = 1 ;
if ( ! error & & * ( gl_string_cursor + 1 ) ! = ' . ' & & * ( gl_string_cursor + 3 ) ! = ' . ' )
error = 1 ;
2005-07-13 16:15:54 +02:00
2005-07-10 19:48:07 +02:00
/* Mark version number as malformed */
if ( error )
gl_string_cursor = 0 ;
2004-09-29 23:26:47 +02:00
}
2005-07-13 16:15:54 +02:00
2005-07-10 19:48:07 +02:00
if ( ! gl_string_cursor )
WARN_ ( d3d_caps ) ( " malformed GL_VERSION (%s) \n " , debugstr_a ( gl_string ) ) ;
else {
major = * gl_string_cursor - ' 0 ' ;
minor = ( * ( gl_string_cursor + 2 ) - ' 0 ' ) * 256 + ( * ( gl_string_cursor + 4 ) - ' 0 ' ) ;
2005-07-13 16:15:54 +02:00
}
2005-07-10 19:48:07 +02:00
break ;
2005-07-13 16:15:54 +02:00
2005-11-30 12:02:45 +01:00
case VENDOR_INTEL :
2005-11-10 12:04:59 +01:00
case VENDOR_MESA :
gl_string_cursor = strstr ( gl_string , " Mesa " ) ;
gl_string_cursor = strstr ( gl_string_cursor , " " ) ;
while ( * gl_string_cursor & & ' ' = = * gl_string_cursor ) + + gl_string_cursor ;
if ( * gl_string_cursor ) {
char tmp [ 16 ] ;
int cursor = 0 ;
while ( * gl_string_cursor < = ' 9 ' & & * gl_string_cursor > = ' 0 ' ) {
tmp [ cursor + + ] = * gl_string_cursor ;
+ + gl_string_cursor ;
}
tmp [ cursor ] = 0 ;
major = atoi ( tmp ) ;
if ( * gl_string_cursor ! = ' . ' ) WARN_ ( d3d_caps ) ( " malformed GL_VERSION (%s) \n " , debugstr_a ( gl_string ) ) ;
+ + gl_string_cursor ;
cursor = 0 ;
while ( * gl_string_cursor < = ' 9 ' & & * gl_string_cursor > = ' 0 ' ) {
tmp [ cursor + + ] = * gl_string_cursor ;
+ + gl_string_cursor ;
}
tmp [ cursor ] = 0 ;
minor = atoi ( tmp ) ;
}
break ;
2005-07-10 19:48:07 +02:00
default :
major = 0 ;
minor = 9 ;
2004-09-29 23:26:47 +02:00
}
2005-07-10 19:48:07 +02:00
gl_info - > gl_driver_version = MAKEDWORD_VERSION ( major , minor ) ;
2006-02-11 12:16:29 +01:00
TRACE_ ( d3d_caps ) ( " found GL_VERSION (%s)->%i.%i->(0x%08lx) \n " , debugstr_a ( gl_string ) , major , minor , gl_info - > gl_driver_version ) ;
2005-07-13 16:15:54 +02:00
2005-07-10 19:48:07 +02:00
/* Fill in the renderer information */
2005-07-13 16:15:54 +02:00
2005-07-10 19:48:07 +02:00
switch ( gl_info - > gl_vendor ) {
case VENDOR_NVIDIA :
if ( strstr ( gl_info - > gl_renderer , " GeForce4 Ti " ) ) {
gl_info - > gl_card = CARD_NVIDIA_GEFORCE4_TI4600 ;
} else if ( strstr ( gl_info - > gl_renderer , " GeForceFX " ) ) {
gl_info - > gl_card = CARD_NVIDIA_GEFORCEFX_5900ULTRA ;
2005-11-30 19:45:45 +01:00
} else if ( strstr ( gl_info - > gl_renderer , " Quadro FX 3000 " ) ) {
gl_info - > gl_card = CARD_NVIDIA_QUADROFX_3000 ;
} else if ( strstr ( gl_info - > gl_renderer , " GeForce 6800 " ) ) {
gl_info - > gl_card = CARD_NVIDIA_GEFORCE_6800ULTRA ;
} else if ( strstr ( gl_info - > gl_renderer , " Quadro FX 4000 " ) ) {
gl_info - > gl_card = CARD_NVIDIA_QUADROFX_4000 ;
} else if ( strstr ( gl_info - > gl_renderer , " GeForce 7800 " ) ) {
gl_info - > gl_card = CARD_NVIDIA_GEFORCE_7800ULTRA ;
2005-07-10 19:48:07 +02:00
} else {
gl_info - > gl_card = CARD_NVIDIA_GEFORCE4_TI4600 ;
}
break ;
2005-07-13 16:15:54 +02:00
2005-07-10 19:48:07 +02:00
case VENDOR_ATI :
if ( strstr ( gl_info - > gl_renderer , " RADEON 9800 PRO " ) ) {
gl_info - > gl_card = CARD_ATI_RADEON_9800PRO ;
} else if ( strstr ( gl_info - > gl_renderer , " RADEON 9700 PRO " ) ) {
gl_info - > gl_card = CARD_ATI_RADEON_9700PRO ;
} else {
gl_info - > gl_card = CARD_ATI_RADEON_8500 ;
}
break ;
2005-07-13 16:15:54 +02:00
2005-11-30 12:02:45 +01:00
case VENDOR_INTEL :
if ( strstr ( gl_info - > gl_renderer , " 915GM " ) ) {
gl_info - > gl_card = CARD_INTEL_I915GM ;
} else if ( strstr ( gl_info - > gl_renderer , " 915G " ) ) {
gl_info - > gl_card = CARD_INTEL_I915G ;
} else if ( strstr ( gl_info - > gl_renderer , " 865G " ) ) {
gl_info - > gl_card = CARD_INTEL_I865G ;
} else if ( strstr ( gl_info - > gl_renderer , " 855G " ) ) {
gl_info - > gl_card = CARD_INTEL_I855G ;
} else if ( strstr ( gl_info - > gl_renderer , " 830G " ) ) {
gl_info - > gl_card = CARD_INTEL_I830G ;
} else {
gl_info - > gl_card = CARD_INTEL_I915G ;
}
break ;
2005-07-10 19:48:07 +02:00
default :
gl_info - > gl_card = CARD_WINE ;
break ;
2004-09-29 23:26:47 +02:00
}
2005-07-10 19:48:07 +02:00
} else {
FIXME ( " get version string returned null \n " ) ;
2004-09-29 23:26:47 +02:00
}
TRACE_ ( d3d_caps ) ( " found GL_RENDERER (%s)->(0x%04x) \n " , debugstr_a ( gl_info - > gl_renderer ) , gl_info - > gl_card ) ;
/*
* Initialize openGL extension related variables
* with Default values
*/
memset ( & gl_info - > supported , 0 , sizeof ( gl_info - > supported ) ) ;
2006-06-27 23:40:42 +02:00
gl_info - > max_textures = 1 ;
gl_info - > max_texture_stages = 1 ;
gl_info - > max_samplers = 1 ;
gl_info - > max_sampler_stages = 1 ;
2004-09-29 23:26:47 +02:00
gl_info - > ps_arb_version = PS_VERSION_NOT_SUPPORTED ;
gl_info - > vs_arb_version = VS_VERSION_NOT_SUPPORTED ;
gl_info - > vs_nv_version = VS_VERSION_NOT_SUPPORTED ;
gl_info - > vs_ati_version = VS_VERSION_NOT_SUPPORTED ;
2006-07-30 23:28:10 +02:00
gl_info - > vs_glsl_constantsF = 0 ;
gl_info - > ps_glsl_constantsF = 0 ;
gl_info - > vs_arb_constantsF = 0 ;
gl_info - > ps_arb_constantsF = 0 ;
2004-09-29 23:26:47 +02:00
/* Now work out what GL support this card really has */
2006-07-19 23:49:37 +02:00
# define USE_GL_FUNC(type, pfn) gl_info->pfn = (type) glXGetProcAddressARB( (const GLubyte *) #pfn);
2004-09-29 23:26:47 +02:00
GL_EXT_FUNCS_GEN ;
2006-07-19 23:49:37 +02:00
GLX_EXT_FUNCS_GEN ;
2004-09-29 23:26:47 +02:00
# undef USE_GL_FUNC
/* Retrieve opengl defaults */
glGetIntegerv ( GL_MAX_CLIP_PLANES , & gl_max ) ;
gl_info - > max_clipplanes = min ( D3DMAXUSERCLIPPLANES , gl_max ) ;
TRACE_ ( d3d_caps ) ( " ClipPlanes support - num Planes=%d \n " , gl_max ) ;
glGetIntegerv ( GL_MAX_LIGHTS , & gl_max ) ;
gl_info - > max_lights = gl_max ;
TRACE_ ( d3d_caps ) ( " Lights support - max lights=%d \n " , gl_max ) ;
2005-07-10 19:48:07 +02:00
glGetIntegerv ( GL_MAX_TEXTURE_SIZE , & gl_max ) ;
gl_info - > max_texture_size = gl_max ;
TRACE_ ( d3d_caps ) ( " Maximum texture size support - max texture size=%d \n " , gl_max ) ;
glGetFloatv ( GL_POINT_SIZE_RANGE , & gl_float ) ;
gl_info - > max_pointsize = gl_float ;
TRACE_ ( d3d_caps ) ( " Maximum point size support - max texture size=%f \n " , gl_float ) ;
2004-09-29 23:26:47 +02:00
/* Parse the gl supported features, in theory enabling parts of our code appropriately */
2005-08-11 12:57:47 +02:00
GL_Extensions = ( const char * ) glGetString ( GL_EXTENSIONS ) ;
2005-07-13 16:15:54 +02:00
TRACE_ ( d3d_caps ) ( " GL_Extensions reported: \n " ) ;
2004-09-29 23:26:47 +02:00
if ( NULL = = GL_Extensions ) {
2005-07-13 16:15:54 +02:00
ERR ( " GL_Extensions returns NULL \n " ) ;
2004-09-29 23:26:47 +02:00
} else {
while ( * GL_Extensions ! = 0x00 ) {
const char * Start = GL_Extensions ;
char ThisExtn [ 256 ] ;
memset ( ThisExtn , 0x00 , sizeof ( ThisExtn ) ) ;
while ( * GL_Extensions ! = ' ' & & * GL_Extensions ! = 0x00 ) {
GL_Extensions + + ;
}
memcpy ( ThisExtn , Start , ( GL_Extensions - Start ) ) ;
TRACE_ ( d3d_caps ) ( " - %s \n " , ThisExtn ) ;
/**
2005-07-13 16:15:54 +02:00
* ARB
2004-09-29 23:26:47 +02:00
*/
if ( strcmp ( ThisExtn , " GL_ARB_fragment_program " ) = = 0 ) {
gl_info - > ps_arb_version = PS_VERSION_11 ;
TRACE_ ( d3d_caps ) ( " FOUND: ARB Pixel Shader support - version=%02x \n " , gl_info - > ps_arb_version ) ;
gl_info - > supported [ ARB_FRAGMENT_PROGRAM ] = TRUE ;
2005-06-24 13:53:07 +02:00
glGetIntegerv ( GL_MAX_TEXTURE_IMAGE_UNITS_ARB , & gl_max ) ;
TRACE_ ( d3d_caps ) ( " FOUND: ARB Pixel Shader support - GL_MAX_TEXTURE_IMAGE_UNITS_ARB=%u \n " , gl_max ) ;
2005-07-10 19:48:07 +02:00
gl_info - > max_samplers = min ( MAX_SAMPLERS , gl_max ) ;
2006-07-19 23:49:37 +02:00
GL_EXTCALL ( glGetProgramivARB ( GL_FRAGMENT_PROGRAM_ARB , GL_MAX_PROGRAM_ENV_PARAMETERS_ARB , & gl_max ) ) ;
2006-07-19 06:06:07 +02:00
TRACE_ ( d3d_caps ) ( " FOUND: ARB Pixel Shader support - max float constants=%u \n " , gl_max ) ;
gl_info - > ps_arb_constantsF = gl_max ;
2006-07-30 23:28:10 +02:00
} else if ( strcmp ( ThisExtn , " GL_ARB_fragment_shader " ) = = 0 ) {
gl_info - > supported [ ARB_FRAGMENT_SHADER ] = TRUE ;
glGetIntegerv ( GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB , & gl_max ) ;
TRACE_ ( d3d_caps ) ( " FOUND: ARB_fragment_shader (GLSL) support - max float ps constants=%u \n " , gl_max ) ;
gl_info - > ps_glsl_constantsF = gl_max ;
2006-05-21 15:05:41 +02:00
} else if ( strcmp ( ThisExtn , " GL_ARB_imaging " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: ARB imaging support \n " ) ;
gl_info - > supported [ ARB_IMAGING ] = TRUE ;
2004-09-29 23:26:47 +02:00
} else if ( strcmp ( ThisExtn , " GL_ARB_multisample " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: ARB Multisample support \n " ) ;
gl_info - > supported [ ARB_MULTISAMPLE ] = TRUE ;
} else if ( strcmp ( ThisExtn , " GL_ARB_multitexture " ) = = 0 ) {
glGetIntegerv ( GL_MAX_TEXTURE_UNITS_ARB , & gl_max ) ;
TRACE_ ( d3d_caps ) ( " FOUND: ARB Multitexture support - GL_MAX_TEXTURE_UNITS_ARB=%u \n " , gl_max ) ;
gl_info - > supported [ ARB_MULTITEXTURE ] = TRUE ;
2005-07-10 19:48:07 +02:00
gl_info - > max_textures = min ( MAX_TEXTURES , gl_max ) ;
2006-06-27 23:40:42 +02:00
gl_info - > max_texture_stages = min ( MAX_TEXTURES , gl_max ) ;
2005-06-24 13:53:07 +02:00
gl_info - > max_samplers = max ( gl_info - > max_samplers , gl_max ) ;
2004-09-29 23:26:47 +02:00
} else if ( strcmp ( ThisExtn , " GL_ARB_texture_cube_map " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: ARB Texture Cube Map support \n " ) ;
gl_info - > supported [ ARB_TEXTURE_CUBE_MAP ] = TRUE ;
TRACE_ ( d3d_caps ) ( " IMPLIED: NVIDIA (NV) Texture Gen Reflection support \n " ) ;
gl_info - > supported [ NV_TEXGEN_REFLECTION ] = TRUE ;
} else if ( strcmp ( ThisExtn , " GL_ARB_texture_compression " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: ARB Texture Compression support \n " ) ;
gl_info - > supported [ ARB_TEXTURE_COMPRESSION ] = TRUE ;
} else if ( strcmp ( ThisExtn , " GL_ARB_texture_env_add " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: ARB Texture Env Add support \n " ) ;
gl_info - > supported [ ARB_TEXTURE_ENV_ADD ] = TRUE ;
} else if ( strcmp ( ThisExtn , " GL_ARB_texture_env_combine " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: ARB Texture Env combine support \n " ) ;
gl_info - > supported [ ARB_TEXTURE_ENV_COMBINE ] = TRUE ;
} else if ( strcmp ( ThisExtn , " GL_ARB_texture_env_dot3 " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: ARB Dot3 support \n " ) ;
gl_info - > supported [ ARB_TEXTURE_ENV_DOT3 ] = TRUE ;
} else if ( strcmp ( ThisExtn , " GL_ARB_texture_border_clamp " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: ARB Texture border clamp support \n " ) ;
gl_info - > supported [ ARB_TEXTURE_BORDER_CLAMP ] = TRUE ;
} else if ( strcmp ( ThisExtn , " GL_ARB_texture_mirrored_repeat " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: ARB Texture mirrored repeat support \n " ) ;
gl_info - > supported [ ARB_TEXTURE_MIRRORED_REPEAT ] = TRUE ;
2005-07-10 19:48:07 +02:00
} else if ( strcmp ( ThisExtn , " GLX_ARB_multisample " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: ARB multisample support \n " ) ;
gl_info - > supported [ ARB_MULTISAMPLE ] = TRUE ;
2005-11-10 12:04:59 +01:00
} else if ( strcmp ( ThisExtn , " GL_ARB_pixel_buffer_object " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: ARB Pixel Buffer support \n " ) ;
gl_info - > supported [ ARB_PIXEL_BUFFER_OBJECT ] = TRUE ;
2005-07-10 19:48:07 +02:00
} else if ( strcmp ( ThisExtn , " GL_ARB_point_sprite " ) = = 0 ) {
2005-11-10 12:04:59 +01:00
TRACE_ ( d3d_caps ) ( " FOUND: ARB point sprite support \n " ) ;
2005-07-10 19:48:07 +02:00
gl_info - > supported [ ARB_POINT_SPRITE ] = TRUE ;
2004-09-29 23:26:47 +02:00
} else if ( strstr ( ThisExtn , " GL_ARB_vertex_program " ) ) {
gl_info - > vs_arb_version = VS_VERSION_11 ;
TRACE_ ( d3d_caps ) ( " FOUND: ARB Vertex Shader support - version=%02x \n " , gl_info - > vs_arb_version ) ;
gl_info - > supported [ ARB_VERTEX_PROGRAM ] = TRUE ;
2006-07-19 23:49:37 +02:00
GL_EXTCALL ( glGetProgramivARB ( GL_VERTEX_PROGRAM_ARB , GL_MAX_PROGRAM_ENV_PARAMETERS_ARB , & gl_max ) ) ;
2006-07-19 06:06:07 +02:00
TRACE_ ( d3d_caps ) ( " FOUND: ARB Vertex Shader support - max float constants=%u \n " , gl_max ) ;
gl_info - > vs_arb_constantsF = gl_max ;
2006-07-30 23:28:10 +02:00
} else if ( strcmp ( ThisExtn , " GL_ARB_vertex_shader " ) = = 0 ) {
gl_info - > supported [ ARB_VERTEX_SHADER ] = TRUE ;
glGetIntegerv ( GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB , & gl_max ) ;
TRACE_ ( d3d_caps ) ( " FOUND: ARB_vertex_shader (GLSL) support - max float vs constants=%u \n " , gl_max ) ;
gl_info - > vs_glsl_constantsF = gl_max ;
2005-07-10 19:48:07 +02:00
} else if ( strcmp ( ThisExtn , " GL_ARB_vertex_blend " ) = = 0 ) {
glGetIntegerv ( GL_MAX_VERTEX_UNITS_ARB , & gl_max ) ;
TRACE_ ( d3d_caps ) ( " FOUND: ARB Vertex Blend support GL_MAX_VERTEX_UNITS_ARB %d \n " , gl_max ) ;
gl_info - > max_blends = gl_max ;
gl_info - > supported [ ARB_VERTEX_BLEND ] = TRUE ;
} else if ( strcmp ( ThisExtn , " GL_ARB_vertex_buffer_object " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: ARB Vertex Buffer support \n " ) ;
gl_info - > supported [ ARB_VERTEX_BUFFER_OBJECT ] = TRUE ;
2005-09-21 11:43:13 +02:00
} else if ( strcmp ( ThisExtn , " GL_ARB_occlusion_query " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: ARB Occlusion Query support \n " ) ;
gl_info - > supported [ ARB_OCCLUSION_QUERY ] = TRUE ;
2006-02-02 13:50:31 +01:00
} else if ( strcmp ( ThisExtn , " GL_ARB_point_parameters " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: ARB Point parameters support \n " ) ;
gl_info - > supported [ ARB_POINT_PARAMETERS ] = TRUE ;
2004-09-29 23:26:47 +02:00
/**
* EXT
*/
} else if ( strcmp ( ThisExtn , " GL_EXT_fog_coord " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: EXT Fog coord support \n " ) ;
gl_info - > supported [ EXT_FOG_COORD ] = TRUE ;
2005-11-10 12:04:59 +01:00
} else if ( strcmp ( ThisExtn , " GL_EXT_framebuffer_object " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: EXT Frame Buffer Object support \n " ) ;
gl_info - > supported [ EXT_FRAMEBUFFER_OBJECT ] = TRUE ;
2004-09-29 23:26:47 +02:00
} else if ( strcmp ( ThisExtn , " GL_EXT_paletted_texture " ) = = 0 ) { /* handle paletted texture extensions */
TRACE_ ( d3d_caps ) ( " FOUND: EXT Paletted texture support \n " ) ;
gl_info - > supported [ EXT_PALETTED_TEXTURE ] = TRUE ;
} else if ( strcmp ( ThisExtn , " GL_EXT_point_parameters " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: EXT Point parameters support \n " ) ;
gl_info - > supported [ EXT_POINT_PARAMETERS ] = TRUE ;
} else if ( strcmp ( ThisExtn , " GL_EXT_secondary_color " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: EXT Secondary coord support \n " ) ;
gl_info - > supported [ EXT_SECONDARY_COLOR ] = TRUE ;
2006-03-05 09:21:28 +01:00
} else if ( strcmp ( ThisExtn , " GL_EXT_stencil_two_side " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: EXT Stencil two side support \n " ) ;
gl_info - > supported [ EXT_STENCIL_TWO_SIDE ] = TRUE ;
2004-09-29 23:26:47 +02:00
} else if ( strcmp ( ThisExtn , " GL_EXT_stencil_wrap " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: EXT Stencil wrap support \n " ) ;
gl_info - > supported [ EXT_STENCIL_WRAP ] = TRUE ;
} else if ( strcmp ( ThisExtn , " GL_EXT_texture_compression_s3tc " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: EXT Texture S3TC compression support \n " ) ;
gl_info - > supported [ EXT_TEXTURE_COMPRESSION_S3TC ] = TRUE ;
} else if ( strcmp ( ThisExtn , " GL_EXT_texture_env_add " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: EXT Texture Env Add support \n " ) ;
gl_info - > supported [ EXT_TEXTURE_ENV_ADD ] = TRUE ;
} else if ( strcmp ( ThisExtn , " GL_EXT_texture_env_combine " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: EXT Texture Env combine support \n " ) ;
gl_info - > supported [ EXT_TEXTURE_ENV_COMBINE ] = TRUE ;
} else if ( strcmp ( ThisExtn , " GL_EXT_texture_env_dot3 " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: EXT Dot3 support \n " ) ;
gl_info - > supported [ EXT_TEXTURE_ENV_DOT3 ] = TRUE ;
} else if ( strcmp ( ThisExtn , " GL_EXT_texture_filter_anisotropic " ) = = 0 ) {
gl_info - > supported [ EXT_TEXTURE_FILTER_ANISOTROPIC ] = TRUE ;
2005-07-10 19:48:07 +02:00
glGetIntegerv ( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT , & gl_max ) ;
TRACE_ ( d3d_caps ) ( " FOUND: EXT Texture Anisotropic filter support. GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT %d \n " , gl_max ) ;
gl_info - > max_anisotropy = gl_max ;
2004-09-29 23:26:47 +02:00
} else if ( strcmp ( ThisExtn , " GL_EXT_texture_lod " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: EXT Texture LOD support \n " ) ;
gl_info - > supported [ EXT_TEXTURE_LOD ] = TRUE ;
} else if ( strcmp ( ThisExtn , " GL_EXT_texture_lod_bias " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: EXT Texture LOD bias support \n " ) ;
gl_info - > supported [ EXT_TEXTURE_LOD_BIAS ] = TRUE ;
} else if ( strcmp ( ThisExtn , " GL_EXT_vertex_weighting " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: EXT Vertex weighting support \n " ) ;
gl_info - > supported [ EXT_VERTEX_WEIGHTING ] = TRUE ;
/**
2005-07-13 16:15:54 +02:00
* NVIDIA
2004-09-29 23:26:47 +02:00
*/
} else if ( strstr ( ThisExtn , " GL_NV_fog_distance " ) ) {
TRACE_ ( d3d_caps ) ( " FOUND: NVIDIA (NV) Fog Distance support \n " ) ;
gl_info - > supported [ NV_FOG_DISTANCE ] = TRUE ;
} else if ( strstr ( ThisExtn , " GL_NV_fragment_program " ) ) {
gl_info - > ps_nv_version = PS_VERSION_11 ;
TRACE_ ( d3d_caps ) ( " FOUND: NVIDIA (NV) Pixel Shader support - version=%02x \n " , gl_info - > ps_nv_version ) ;
} else if ( strcmp ( ThisExtn , " GL_NV_register_combiners " ) = = 0 ) {
2006-06-27 23:44:26 +02:00
glGetIntegerv ( GL_MAX_GENERAL_COMBINERS_NV , & gl_max ) ;
gl_info - > max_texture_stages = min ( MAX_TEXTURES , gl_max ) ;
TRACE_ ( d3d_caps ) ( " FOUND: NVIDIA (NV) Register combiners (1) support - GL_MAX_GENERAL_COMBINERS_NV=%d \n " , gl_max ) ;
2004-09-29 23:26:47 +02:00
gl_info - > supported [ NV_REGISTER_COMBINERS ] = TRUE ;
} else if ( strcmp ( ThisExtn , " GL_NV_register_combiners2 " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: NVIDIA (NV) Register combiners (2) support \n " ) ;
gl_info - > supported [ NV_REGISTER_COMBINERS2 ] = TRUE ;
} else if ( strcmp ( ThisExtn , " GL_NV_texgen_reflection " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: NVIDIA (NV) Texture Gen Reflection support \n " ) ;
gl_info - > supported [ NV_TEXGEN_REFLECTION ] = TRUE ;
} else if ( strcmp ( ThisExtn , " GL_NV_texture_env_combine4 " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: NVIDIA (NV) Texture Env combine (4) support \n " ) ;
gl_info - > supported [ NV_TEXTURE_ENV_COMBINE4 ] = TRUE ;
} else if ( strcmp ( ThisExtn , " GL_NV_texture_shader " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: NVIDIA (NV) Texture Shader (1) support \n " ) ;
gl_info - > supported [ NV_TEXTURE_SHADER ] = TRUE ;
} else if ( strcmp ( ThisExtn , " GL_NV_texture_shader2 " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: NVIDIA (NV) Texture Shader (2) support \n " ) ;
gl_info - > supported [ NV_TEXTURE_SHADER2 ] = TRUE ;
} else if ( strcmp ( ThisExtn , " GL_NV_texture_shader3 " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: NVIDIA (NV) Texture Shader (3) support \n " ) ;
gl_info - > supported [ NV_TEXTURE_SHADER3 ] = TRUE ;
2005-09-21 11:43:13 +02:00
} else if ( strcmp ( ThisExtn , " GL_NV_occlusion_query " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: NVIDIA (NV) Occlusion Query (3) support \n " ) ;
gl_info - > supported [ NV_OCCLUSION_QUERY ] = TRUE ;
2004-09-29 23:26:47 +02:00
} else if ( strstr ( ThisExtn , " GL_NV_vertex_program " ) ) {
gl_info - > vs_nv_version = max ( gl_info - > vs_nv_version , ( 0 = = strcmp ( ThisExtn , " GL_NV_vertex_program1_1 " ) ) ? VS_VERSION_11 : VS_VERSION_10 ) ;
gl_info - > vs_nv_version = max ( gl_info - > vs_nv_version , ( 0 = = strcmp ( ThisExtn , " GL_NV_vertex_program2 " ) ) ? VS_VERSION_20 : VS_VERSION_10 ) ;
TRACE_ ( d3d_caps ) ( " FOUND: NVIDIA (NV) Vertex Shader support - version=%02x \n " , gl_info - > vs_nv_version ) ;
gl_info - > supported [ NV_VERTEX_PROGRAM ] = TRUE ;
/**
* ATI
*/
/** TODO */
2006-03-05 09:21:28 +01:00
} else if ( strcmp ( ThisExtn , " GL_ATI_separate_stencil " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: ATI Separate stencil support \n " ) ;
gl_info - > supported [ ATI_SEPARATE_STENCIL ] = TRUE ;
2004-09-29 23:26:47 +02:00
} else if ( strcmp ( ThisExtn , " GL_ATI_texture_env_combine3 " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: ATI Texture Env combine (3) support \n " ) ;
gl_info - > supported [ ATI_TEXTURE_ENV_COMBINE3 ] = TRUE ;
} else if ( strcmp ( ThisExtn , " GL_ATI_texture_mirror_once " ) = = 0 ) {
TRACE_ ( d3d_caps ) ( " FOUND: ATI Texture Mirror Once support \n " ) ;
gl_info - > supported [ ATI_TEXTURE_MIRROR_ONCE ] = TRUE ;
} else if ( strcmp ( ThisExtn , " GL_EXT_vertex_shader " ) = = 0 ) {
gl_info - > vs_ati_version = VS_VERSION_11 ;
TRACE_ ( d3d_caps ) ( " FOUND: ATI (EXT) Vertex Shader support - version=%02x \n " , gl_info - > vs_ati_version ) ;
gl_info - > supported [ EXT_VERTEX_SHADER ] = TRUE ;
}
if ( * GL_Extensions = = ' ' ) GL_Extensions + + ;
}
}
2006-07-30 23:28:10 +02:00
checkGLcall ( " extension detection \n " ) ;
2006-06-27 23:40:42 +02:00
gl_info - > max_sampler_stages = max ( gl_info - > max_samplers , gl_info - > max_texture_stages ) ;
2004-09-29 23:26:47 +02:00
2005-08-03 13:00:28 +02:00
/* Load all the lookup tables
TODO : It may be a good idea to make minLookup and maxLookup const and populate them in wined3d_private . h where they are declared */
minLookup [ WINELOOKUP_WARPPARAM ] = D3DTADDRESS_WRAP ;
maxLookup [ WINELOOKUP_WARPPARAM ] = D3DTADDRESS_MIRRORONCE ;
2006-04-06 19:02:16 +02:00
minLookup [ WINELOOKUP_MAGFILTER ] = WINED3DTEXF_NONE ;
maxLookup [ WINELOOKUP_MAGFILTER ] = WINED3DTEXF_ANISOTROPIC ;
2005-08-03 13:00:28 +02:00
for ( i = 0 ; i < MAX_LOOKUPS ; i + + ) {
2005-10-03 12:15:08 +02:00
stateLookup [ i ] = HeapAlloc ( GetProcessHeap ( ) , 0 , sizeof ( * stateLookup [ i ] ) * ( 1 + maxLookup [ i ] - minLookup [ i ] ) ) ;
2005-08-03 13:00:28 +02:00
}
stateLookup [ WINELOOKUP_WARPPARAM ] [ D3DTADDRESS_WRAP - minLookup [ WINELOOKUP_WARPPARAM ] ] = GL_REPEAT ;
stateLookup [ WINELOOKUP_WARPPARAM ] [ D3DTADDRESS_CLAMP - minLookup [ WINELOOKUP_WARPPARAM ] ] = GL_CLAMP_TO_EDGE ;
stateLookup [ WINELOOKUP_WARPPARAM ] [ D3DTADDRESS_BORDER - minLookup [ WINELOOKUP_WARPPARAM ] ] =
gl_info - > supported [ ARB_TEXTURE_BORDER_CLAMP ] ? GL_CLAMP_TO_BORDER_ARB : GL_REPEAT ;
stateLookup [ WINELOOKUP_WARPPARAM ] [ D3DTADDRESS_BORDER - minLookup [ WINELOOKUP_WARPPARAM ] ] =
gl_info - > supported [ ARB_TEXTURE_BORDER_CLAMP ] ? GL_CLAMP_TO_BORDER_ARB : GL_REPEAT ;
stateLookup [ WINELOOKUP_WARPPARAM ] [ D3DTADDRESS_MIRROR - minLookup [ WINELOOKUP_WARPPARAM ] ] =
gl_info - > supported [ ARB_TEXTURE_MIRRORED_REPEAT ] ? GL_MIRRORED_REPEAT_ARB : GL_REPEAT ;
stateLookup [ WINELOOKUP_WARPPARAM ] [ D3DTADDRESS_MIRRORONCE - minLookup [ WINELOOKUP_WARPPARAM ] ] =
gl_info - > supported [ ATI_TEXTURE_MIRROR_ONCE ] ? GL_MIRROR_CLAMP_TO_EDGE_ATI : GL_REPEAT ;
2006-04-06 19:02:16 +02:00
stateLookup [ WINELOOKUP_MAGFILTER ] [ WINED3DTEXF_NONE - minLookup [ WINELOOKUP_MAGFILTER ] ] = GL_NEAREST ;
stateLookup [ WINELOOKUP_MAGFILTER ] [ WINED3DTEXF_POINT - minLookup [ WINELOOKUP_MAGFILTER ] ] = GL_NEAREST ;
stateLookup [ WINELOOKUP_MAGFILTER ] [ WINED3DTEXF_LINEAR - minLookup [ WINELOOKUP_MAGFILTER ] ] = GL_LINEAR ;
stateLookup [ WINELOOKUP_MAGFILTER ] [ WINED3DTEXF_ANISOTROPIC - minLookup [ WINELOOKUP_MAGFILTER ] ] =
2005-08-03 13:00:28 +02:00
gl_info - > supported [ EXT_TEXTURE_FILTER_ANISOTROPIC ] ? GL_LINEAR : GL_NEAREST ;
2006-04-06 19:02:16 +02:00
minMipLookup [ WINED3DTEXF_NONE ] [ WINED3DTEXF_NONE ] = GL_LINEAR ;
minMipLookup [ WINED3DTEXF_NONE ] [ WINED3DTEXF_POINT ] = GL_LINEAR ;
minMipLookup [ WINED3DTEXF_NONE ] [ WINED3DTEXF_LINEAR ] = GL_LINEAR ;
minMipLookup [ WINED3DTEXF_POINT ] [ WINED3DTEXF_NONE ] = GL_NEAREST ;
minMipLookup [ WINED3DTEXF_POINT ] [ WINED3DTEXF_POINT ] = GL_NEAREST_MIPMAP_NEAREST ;
minMipLookup [ WINED3DTEXF_POINT ] [ WINED3DTEXF_LINEAR ] = GL_NEAREST_MIPMAP_LINEAR ;
minMipLookup [ WINED3DTEXF_LINEAR ] [ WINED3DTEXF_NONE ] = GL_LINEAR ;
minMipLookup [ WINED3DTEXF_LINEAR ] [ WINED3DTEXF_POINT ] = GL_LINEAR_MIPMAP_NEAREST ;
minMipLookup [ WINED3DTEXF_LINEAR ] [ WINED3DTEXF_LINEAR ] = GL_LINEAR_MIPMAP_LINEAR ;
minMipLookup [ WINED3DTEXF_ANISOTROPIC ] [ WINED3DTEXF_NONE ] = gl_info - > supported [ EXT_TEXTURE_FILTER_ANISOTROPIC ] ?
2005-08-03 13:00:28 +02:00
GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR ;
2006-04-06 19:02:16 +02:00
minMipLookup [ WINED3DTEXF_ANISOTROPIC ] [ WINED3DTEXF_POINT ] = gl_info - > supported [ EXT_TEXTURE_FILTER_ANISOTROPIC ] ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR ;
minMipLookup [ WINED3DTEXF_ANISOTROPIC ] [ WINED3DTEXF_LINEAR ] = gl_info - > supported [ EXT_TEXTURE_FILTER_ANISOTROPIC ] ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR ;
2005-08-03 13:00:28 +02:00
/* TODO: config lookups */
2004-09-29 23:26:47 +02:00
if ( display ! = NULL ) {
GLX_Extensions = glXQueryExtensionsString ( display , DefaultScreen ( display ) ) ;
2005-07-13 16:15:54 +02:00
TRACE_ ( d3d_caps ) ( " GLX_Extensions reported: \n " ) ;
2004-09-29 23:26:47 +02:00
if ( NULL = = GLX_Extensions ) {
2005-07-13 16:15:54 +02:00
ERR ( " GLX_Extensions returns NULL \n " ) ;
2004-09-29 23:26:47 +02:00
} else {
while ( * GLX_Extensions ! = 0x00 ) {
const char * Start = GLX_Extensions ;
char ThisExtn [ 256 ] ;
2005-07-13 16:15:54 +02:00
2004-09-29 23:26:47 +02:00
memset ( ThisExtn , 0x00 , sizeof ( ThisExtn ) ) ;
while ( * GLX_Extensions ! = ' ' & & * GLX_Extensions ! = 0x00 ) {
GLX_Extensions + + ;
}
memcpy ( ThisExtn , Start , ( GLX_Extensions - Start ) ) ;
TRACE_ ( d3d_caps ) ( " - %s \n " , ThisExtn ) ;
if ( * GLX_Extensions = = ' ' ) GLX_Extensions + + ;
}
}
}
2005-07-10 19:48:07 +02:00
/* If we created a dummy context, throw it away */
if ( NULL ! = fake_ctx ) WineD3D_ReleaseFakeGLContext ( fake_ctx ) ;
2004-09-29 23:26:47 +02:00
/* Only save the values obtained when a display is provided */
2005-07-10 19:48:07 +02:00
if ( fake_ctx = = NULL ) {
2004-09-29 23:26:47 +02:00
return TRUE ;
} else {
return FALSE ;
}
}
/**********************************************************
* IWineD3D implementation follows
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-06-10 13:15:32 +02:00
static UINT WINAPI IWineD3DImpl_GetAdapterCount ( IWineD3D * iface ) {
2004-09-23 06:34:27 +02:00
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
/* FIXME: Set to one for now to imply the display */
TRACE_ ( d3d_caps ) ( " (%p): Mostly stub, only returns primary display \n " , This ) ;
return 1 ;
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DImpl_RegisterSoftwareDevice ( IWineD3D * iface , void * pInitializeFunction ) {
2004-09-28 04:12:12 +02:00
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
FIXME ( " (%p)->(%p): stub \n " , This , pInitializeFunction ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-09-28 04:12:12 +02:00
}
2006-06-10 13:15:32 +02:00
static HMONITOR WINAPI IWineD3DImpl_GetAdapterMonitor ( IWineD3D * iface , UINT Adapter ) {
2004-09-28 04:12:12 +02:00
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
2006-07-11 04:32:47 +02:00
POINT pt = { - 1 , - 1 } ;
2004-09-28 04:12:12 +02:00
if ( Adapter > = IWineD3DImpl_GetAdapterCount ( iface ) ) {
return NULL ;
}
2006-07-11 04:32:47 +02:00
FIXME_ ( d3d_caps ) ( " (%p): returning the primary monitor for adapter %d \n " , This , Adapter ) ;
return MonitorFromPoint ( pt , MONITOR_DEFAULTTOPRIMARY ) ;
2004-09-28 04:12:12 +02:00
}
2005-07-13 16:15:54 +02:00
/* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes
2004-09-28 04:12:12 +02:00
of the same bpp but different resolutions */
/* Note: dx9 supplies a format. Calls from d3d8 supply D3DFMT_UNKNOWN */
2006-06-10 13:15:32 +02:00
static UINT WINAPI IWineD3DImpl_GetAdapterModeCount ( IWineD3D * iface , UINT Adapter , WINED3DFORMAT Format ) {
2004-09-28 04:12:12 +02:00
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
TRACE_ ( d3d_caps ) ( " (%p}->(Adapter: %d, Format: %s) \n " , This , Adapter , debug_d3dformat ( Format ) ) ;
if ( Adapter > = IWineD3D_GetAdapterCount ( iface ) ) {
return 0 ;
}
if ( Adapter = = 0 ) { /* Display */
int i = 0 ;
int j = 0 ;
# if !defined( DEBUG_SINGLE_MODE )
DEVMODEW DevModeW ;
/* Work out the current screen bpp */
HDC hdc = CreateDCA ( " DISPLAY " , NULL , NULL , NULL ) ;
int bpp = GetDeviceCaps ( hdc , BITSPIXEL ) ;
DeleteDC ( hdc ) ;
while ( EnumDisplaySettingsExW ( NULL , j , & DevModeW , 0 ) ) {
j + + ;
switch ( Format )
{
2005-07-13 16:15:54 +02:00
case D3DFMT_UNKNOWN :
i + + ;
2004-09-28 04:12:12 +02:00
break ;
2005-07-13 16:15:54 +02:00
case D3DFMT_X8R8G8B8 :
case D3DFMT_A8R8G8B8 :
if ( min ( DevModeW . dmBitsPerPel , bpp ) = = 32 ) i + + ;
if ( min ( DevModeW . dmBitsPerPel , bpp ) = = 24 ) i + + ;
2004-09-28 04:12:12 +02:00
break ;
case D3DFMT_X1R5G5B5 :
case D3DFMT_A1R5G5B5 :
case D3DFMT_R5G6B5 :
2005-07-13 16:15:54 +02:00
if ( min ( DevModeW . dmBitsPerPel , bpp ) = = 16 ) i + + ;
2004-09-28 04:12:12 +02:00
break ;
default :
/* Skip other modes as they do not match requested format */
break ;
}
}
# else
i = 1 ;
j = 1 ;
# endif
TRACE_ ( d3d_caps ) ( " (%p}->(Adapter: %d) => %d (out of %d) \n " , This , Adapter , i , j ) ;
return i ;
} else {
FIXME_ ( d3d_caps ) ( " Adapter not primary display \n " ) ;
}
return 0 ;
}
/* Note: dx9 supplies a format. Calls from d3d8 supply D3DFMT_UNKNOWN */
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DImpl_EnumAdapterModes ( IWineD3D * iface , UINT Adapter , WINED3DFORMAT Format , UINT Mode , WINED3DDISPLAYMODE * pMode ) {
2004-09-28 04:12:12 +02:00
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
TRACE_ ( d3d_caps ) ( " (%p}->(Adapter:%d, mode:%d, pMode:%p, format:%s) \n " , This , Adapter , Mode , pMode , debug_d3dformat ( Format ) ) ;
/* Validate the parameters as much as possible */
2005-07-13 16:15:54 +02:00
if ( NULL = = pMode | |
2004-09-28 04:12:12 +02:00
Adapter > = IWineD3DImpl_GetAdapterCount ( iface ) | |
Mode > = IWineD3DImpl_GetAdapterModeCount ( iface , Adapter , Format ) ) {
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2004-09-28 04:12:12 +02:00
}
if ( Adapter = = 0 ) { /* Display */
# if !defined( DEBUG_SINGLE_MODE )
DEVMODEW DevModeW ;
int ModeIdx = 0 ;
2005-07-13 16:15:54 +02:00
2004-09-28 04:12:12 +02:00
/* Work out the current screen bpp */
HDC hdc = CreateDCA ( " DISPLAY " , NULL , NULL , NULL ) ;
int bpp = GetDeviceCaps ( hdc , BITSPIXEL ) ;
DeleteDC ( hdc ) ;
/* If we are filtering to a specific format, then need to skip all unrelated
modes , but if mode is irrelevant , then we can use the index directly */
2005-07-13 16:15:54 +02:00
if ( Format = = D3DFMT_UNKNOWN )
2004-09-28 04:12:12 +02:00
{
ModeIdx = Mode ;
} else {
int i = 0 ;
int j = 0 ;
DEVMODEW DevModeWtmp ;
2005-01-09 17:33:01 +01:00
2005-07-30 21:11:38 +02:00
while ( i < ( Mode ) & & EnumDisplaySettingsExW ( NULL , j , & DevModeWtmp , 0 ) ) {
2004-09-28 04:12:12 +02:00
j + + ;
switch ( Format )
{
2005-07-13 16:15:54 +02:00
case D3DFMT_UNKNOWN :
i + + ;
2004-09-28 04:12:12 +02:00
break ;
2005-07-13 16:15:54 +02:00
case D3DFMT_X8R8G8B8 :
case D3DFMT_A8R8G8B8 :
if ( min ( DevModeWtmp . dmBitsPerPel , bpp ) = = 32 ) i + + ;
if ( min ( DevModeWtmp . dmBitsPerPel , bpp ) = = 24 ) i + + ;
2004-09-28 04:12:12 +02:00
break ;
case D3DFMT_X1R5G5B5 :
case D3DFMT_A1R5G5B5 :
case D3DFMT_R5G6B5 :
2005-07-13 16:15:54 +02:00
if ( min ( DevModeWtmp . dmBitsPerPel , bpp ) = = 16 ) i + + ;
2004-09-28 04:12:12 +02:00
break ;
default :
/* Skip other modes as they do not match requested format */
break ;
}
}
ModeIdx = j ;
}
/* Now get the display mode via the calculated index */
2005-07-13 16:15:54 +02:00
if ( EnumDisplaySettingsExW ( NULL , ModeIdx , & DevModeW , 0 ) )
2004-09-28 04:12:12 +02:00
{
pMode - > Width = DevModeW . dmPelsWidth ;
pMode - > Height = DevModeW . dmPelsHeight ;
bpp = min ( DevModeW . dmBitsPerPel , bpp ) ;
pMode - > RefreshRate = D3DADAPTER_DEFAULT ;
2005-09-19 17:25:07 +02:00
if ( DevModeW . dmFields & DM_DISPLAYFREQUENCY )
2004-09-28 04:12:12 +02:00
{
pMode - > RefreshRate = DevModeW . dmDisplayFrequency ;
}
if ( Format = = D3DFMT_UNKNOWN )
{
switch ( bpp ) {
case 8 : pMode - > Format = D3DFMT_R3G3B2 ; break ;
case 16 : pMode - > Format = D3DFMT_R5G6B5 ; break ;
2005-10-12 23:07:27 +02:00
case 24 : /* Robots and EVE Online need 24 and 32 bit as A8R8G8B8 to start */
case 32 : pMode - > Format = D3DFMT_A8R8G8B8 ; break ;
2004-09-28 04:12:12 +02:00
default : pMode - > Format = D3DFMT_UNKNOWN ;
}
} else {
pMode - > Format = Format ;
}
}
else
{
TRACE_ ( d3d_caps ) ( " Requested mode out of range %d \n " , Mode ) ;
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2004-09-28 04:12:12 +02:00
}
# else
/* Return one setting of the format requested */
2006-04-07 12:51:12 +02:00
if ( Mode > 0 ) return WINED3DERR_INVALIDCALL ;
2004-09-28 04:12:12 +02:00
pMode - > Width = 800 ;
pMode - > Height = 600 ;
pMode - > RefreshRate = D3DADAPTER_DEFAULT ;
2005-07-13 16:15:54 +02:00
pMode - > Format = ( Format = = D3DFMT_UNKNOWN ) ? D3DFMT_A8R8G8B8 : Format ;
2004-09-28 04:12:12 +02:00
bpp = 32 ;
# endif
2005-07-13 16:15:54 +02:00
TRACE_ ( d3d_caps ) ( " W %d H %d rr %d fmt (%x - %s) bpp %u \n " , pMode - > Width , pMode - > Height ,
2004-09-28 04:12:12 +02:00
pMode - > RefreshRate , pMode - > Format , debug_d3dformat ( pMode - > Format ) , bpp ) ;
} else {
FIXME_ ( d3d_caps ) ( " Adapter not primary display \n " ) ;
}
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-09-28 04:12:12 +02:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DImpl_GetAdapterDisplayMode ( IWineD3D * iface , UINT Adapter , WINED3DDISPLAYMODE * pMode ) {
2004-09-28 04:12:12 +02:00
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
TRACE_ ( d3d_caps ) ( " (%p}->(Adapter: %d, pMode: %p) \n " , This , Adapter , pMode ) ;
2005-07-13 16:15:54 +02:00
if ( NULL = = pMode | |
2004-09-28 04:12:12 +02:00
Adapter > = IWineD3D_GetAdapterCount ( iface ) ) {
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2004-09-28 04:12:12 +02:00
}
if ( Adapter = = 0 ) { /* Display */
int bpp = 0 ;
DEVMODEW DevModeW ;
EnumDisplaySettingsExW ( NULL , ( DWORD ) - 1 , & DevModeW , 0 ) ;
pMode - > Width = DevModeW . dmPelsWidth ;
pMode - > Height = DevModeW . dmPelsHeight ;
bpp = DevModeW . dmBitsPerPel ;
pMode - > RefreshRate = D3DADAPTER_DEFAULT ;
if ( DevModeW . dmFields & DM_DISPLAYFREQUENCY )
{
pMode - > RefreshRate = DevModeW . dmDisplayFrequency ;
}
switch ( bpp ) {
case 8 : pMode - > Format = D3DFMT_R3G3B2 ; break ;
case 16 : pMode - > Format = D3DFMT_R5G6B5 ; break ;
2005-07-13 21:38:39 +02:00
case 24 : pMode - > Format = D3DFMT_X8R8G8B8 ; break ; /* Robots needs 24bit to be X8R8G8B8 */
2005-10-12 23:07:27 +02:00
case 32 : pMode - > Format = D3DFMT_X8R8G8B8 ; break ; /* EVE online and the Fur demo need 32bit AdapterDisplatMode to return X8R8G8B8 */
2004-09-28 04:12:12 +02:00
default : pMode - > Format = D3DFMT_UNKNOWN ;
}
} else {
FIXME_ ( d3d_caps ) ( " Adapter not primary display \n " ) ;
}
TRACE_ ( d3d_caps ) ( " returning w:%d, h:%d, ref:%d, fmt:%s \n " , pMode - > Width ,
pMode - > Height , pMode - > RefreshRate , debug_d3dformat ( pMode - > Format ) ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-09-28 04:12:12 +02:00
}
2004-09-23 06:34:27 +02:00
2005-07-10 19:48:07 +02:00
static Display * WINAPI IWineD3DImpl_GetAdapterDisplay ( IWineD3D * iface , UINT Adapter ) {
Display * display ;
HDC device_context ;
/* only works with one adapter at the moment... */
/* Get the display */
device_context = GetDC ( 0 ) ;
display = get_display ( device_context ) ;
ReleaseDC ( 0 , device_context ) ;
return display ;
}
/* NOTE: due to structure differences between dx8 and dx9 D3DADAPTER_IDENTIFIER,
2004-09-29 23:26:47 +02:00
and fields being inserted in the middle , a new structure is used in place */
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DImpl_GetAdapterIdentifier ( IWineD3D * iface , UINT Adapter , DWORD Flags ,
2004-09-29 23:26:47 +02:00
WINED3DADAPTER_IDENTIFIER * pIdentifier ) {
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
TRACE_ ( d3d_caps ) ( " (%p}->(Adapter: %d, Flags: %lx, pId=%p) \n " , This , Adapter , Flags , pIdentifier ) ;
if ( Adapter > = IWineD3D_GetAdapterCount ( iface ) ) {
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2004-09-29 23:26:47 +02:00
}
if ( Adapter = = 0 ) { /* Display - only device supported for now */
2005-07-13 16:15:54 +02:00
2004-09-29 23:26:47 +02:00
BOOL isGLInfoValid = This - > isGLInfoValid ;
2005-07-13 16:15:54 +02:00
/* FillGLCaps updates gl_info, but we only want to store and
2004-09-29 23:26:47 +02:00
reuse the values once we have a context which is valid . Values from
a temporary context may differ from the final ones */
if ( isGLInfoValid = = FALSE ) {
2006-03-05 21:07:44 +01:00
WineD3D_Context * fake_ctx = NULL ;
if ( glXGetCurrentContext ( ) = = NULL ) fake_ctx = WineD3D_CreateFakeGLContext ( ) ;
2005-07-10 19:48:07 +02:00
/* If we don't know the device settings, go query them now */
2006-07-19 23:49:37 +02:00
isGLInfoValid = IWineD3DImpl_FillGLCaps ( iface , IWineD3DImpl_GetAdapterDisplay ( iface , Adapter ) ) ;
2006-03-05 21:07:44 +01:00
if ( fake_ctx ! = NULL ) WineD3D_ReleaseFakeGLContext ( fake_ctx ) ;
2004-09-29 23:26:47 +02:00
}
/* If it worked, return the information requested */
2004-12-09 15:07:59 +01:00
if ( isGLInfoValid ) {
2004-09-29 23:26:47 +02:00
TRACE_ ( d3d_caps ) ( " device/Vendor Name and Version detection using FillGLCaps \n " ) ;
strcpy ( pIdentifier - > Driver , " Display " ) ;
strcpy ( pIdentifier - > Description , " Direct3D HAL " ) ;
2004-10-05 20:15:29 +02:00
/* Note dx8 doesn't supply a DeviceName */
2004-09-29 23:26:47 +02:00
if ( NULL ! = pIdentifier - > DeviceName ) strcpy ( pIdentifier - > DeviceName , " \\ \\ . \\ DISPLAY " ) ; /* FIXME: May depend on desktop? */
2006-02-11 12:16:29 +01:00
/* Current Windows drivers have versions like 6.14.... (some older have an earlier version) */
pIdentifier - > DriverVersion - > u . HighPart = MAKEDWORD_VERSION ( 6 , 14 ) ;
2004-09-29 23:26:47 +02:00
pIdentifier - > DriverVersion - > u . LowPart = This - > gl_info . gl_driver_version ;
* ( pIdentifier - > VendorId ) = This - > gl_info . gl_vendor ;
* ( pIdentifier - > DeviceId ) = This - > gl_info . gl_card ;
* ( pIdentifier - > SubSysId ) = 0 ;
* ( pIdentifier - > Revision ) = 0 ;
} else {
/* If it failed, return dummy values from an NVidia driver */
WARN_ ( d3d_caps ) ( " Cannot get GLCaps for device/Vendor Name and Version detection using FillGLCaps, currently using NVIDIA identifiers \n " ) ;
strcpy ( pIdentifier - > Driver , " Display " ) ;
strcpy ( pIdentifier - > Description , " Direct3D HAL " ) ;
if ( NULL ! = pIdentifier - > DeviceName ) strcpy ( pIdentifier - > DeviceName , " \\ \\ . \\ DISPLAY " ) ; /* FIXME: May depend on desktop? */
2006-02-11 12:16:29 +01:00
/* Current Windows Nvidia drivers have versions like e.g. 6.14.10.5672 */
pIdentifier - > DriverVersion - > u . HighPart = MAKEDWORD_VERSION ( 6 , 14 ) ;
/* 71.74 is a current Linux Nvidia driver version */
pIdentifier - > DriverVersion - > u . LowPart = MAKEDWORD_VERSION ( 10 , ( 71 * 100 + 74 ) ) ;
2004-09-29 23:26:47 +02:00
* ( pIdentifier - > VendorId ) = VENDOR_NVIDIA ;
* ( pIdentifier - > DeviceId ) = CARD_NVIDIA_GEFORCE4_TI4600 ;
* ( pIdentifier - > SubSysId ) = 0 ;
* ( pIdentifier - > Revision ) = 0 ;
}
/*FIXME: memcpy(&pIdentifier->DeviceIdentifier, ??, sizeof(??GUID)); */
if ( Flags & D3DENUM_NO_WHQL_LEVEL ) {
* ( pIdentifier - > WHQLLevel ) = 0 ;
} else {
* ( pIdentifier - > WHQLLevel ) = 1 ;
}
} else {
FIXME_ ( d3d_caps ) ( " Adapter not primary display \n " ) ;
}
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-09-29 23:26:47 +02:00
}
2005-04-28 14:02:03 +02:00
static BOOL IWineD3DImpl_IsGLXFBConfigCompatibleWithRenderFmt ( WineD3D_Context * ctx , GLXFBConfig cfgs , WINED3DFORMAT Format ) {
2005-10-04 17:50:57 +02:00
#if 0 /* This code performs a strict test between the format and the current X11 buffer depth, which may give the best performance */
2005-04-28 14:02:03 +02:00
int gl_test ;
int rb , gb , bb , ab , type , buf_sz ;
gl_test = glXGetFBConfigAttrib ( ctx - > display , cfgs , GLX_RED_SIZE , & rb ) ;
gl_test = glXGetFBConfigAttrib ( ctx - > display , cfgs , GLX_GREEN_SIZE , & gb ) ;
gl_test = glXGetFBConfigAttrib ( ctx - > display , cfgs , GLX_BLUE_SIZE , & bb ) ;
gl_test = glXGetFBConfigAttrib ( ctx - > display , cfgs , GLX_ALPHA_SIZE , & ab ) ;
gl_test = glXGetFBConfigAttrib ( ctx - > display , cfgs , GLX_RENDER_TYPE , & type ) ;
gl_test = glXGetFBConfigAttrib ( ctx - > display , cfgs , GLX_BUFFER_SIZE , & buf_sz ) ;
switch ( Format ) {
2005-07-13 16:15:54 +02:00
case WINED3DFMT_X8R8G8B8 :
2005-04-28 14:02:03 +02:00
case WINED3DFMT_R8G8B8 :
if ( 8 = = rb & & 8 = = gb & & 8 = = bb ) return TRUE ;
break ;
case WINED3DFMT_A8R8G8B8 :
if ( 8 = = rb & & 8 = = gb & & 8 = = bb & & 8 = = ab ) return TRUE ;
break ;
2005-09-07 11:25:26 +02:00
case WINED3DFMT_A2R10G10B10 :
if ( 10 = = rb & & 10 = = gb & & 10 = = bb & & 2 = = ab ) return TRUE ;
break ;
2005-04-28 14:02:03 +02:00
case WINED3DFMT_X1R5G5B5 :
if ( 5 = = rb & & 5 = = gb & & 5 = = bb ) return TRUE ;
break ;
case WINED3DFMT_A1R5G5B5 :
if ( 5 = = rb & & 5 = = gb & & 5 = = bb & & 1 = = ab ) return TRUE ;
break ;
2005-12-31 13:13:34 +01:00
case WINED3DFMT_X4R4G4B4 :
if ( 16 = = buf_sz & & 4 = = rb & & 4 = = gb & & 4 = = bb ) return TRUE ;
break ;
2005-04-28 14:02:03 +02:00
case WINED3DFMT_R5G6B5 :
if ( 5 = = rb & & 6 = = gb & & 5 = = bb ) return TRUE ;
break ;
case WINED3DFMT_R3G3B2 :
if ( 3 = = rb & & 3 = = gb & & 2 = = bb ) return TRUE ;
break ;
case WINED3DFMT_A8P8 :
if ( type & GLX_COLOR_INDEX_BIT & & 8 = = buf_sz & & 8 = = ab ) return TRUE ;
break ;
case WINED3DFMT_P8 :
if ( type & GLX_COLOR_INDEX_BIT & & 8 = = buf_sz ) return TRUE ;
break ;
default :
ERR ( " unsupported format %s \n " , debug_d3dformat ( Format ) ) ;
break ;
}
return FALSE ;
2005-11-10 12:39:07 +01:00
# else /* Most of the time performance is less of an issue than compatibility, this code allows for most common opengl/d3d formats */
2005-10-04 17:50:57 +02:00
switch ( Format ) {
case WINED3DFMT_X8R8G8B8 :
case WINED3DFMT_R8G8B8 :
case WINED3DFMT_A8R8G8B8 :
case WINED3DFMT_A2R10G10B10 :
case WINED3DFMT_X1R5G5B5 :
case WINED3DFMT_A1R5G5B5 :
case WINED3DFMT_R5G6B5 :
case WINED3DFMT_R3G3B2 :
case WINED3DFMT_A8P8 :
case WINED3DFMT_P8 :
return TRUE ;
default :
ERR ( " unsupported format %s \n " , debug_d3dformat ( Format ) ) ;
break ;
}
return FALSE ;
# endif
2005-04-28 14:02:03 +02:00
}
static BOOL IWineD3DImpl_IsGLXFBConfigCompatibleWithDepthFmt ( WineD3D_Context * ctx , GLXFBConfig cfgs , WINED3DFORMAT Format ) {
2005-10-04 17:50:57 +02:00
#if 0 /* This code performs a strict test between the format and the current X11 buffer depth, which may give the best performance */
2005-04-28 14:02:03 +02:00
int gl_test ;
int db , sb ;
2005-07-13 16:15:54 +02:00
2005-04-28 14:02:03 +02:00
gl_test = glXGetFBConfigAttrib ( ctx - > display , cfgs , GLX_DEPTH_SIZE , & db ) ;
gl_test = glXGetFBConfigAttrib ( ctx - > display , cfgs , GLX_STENCIL_SIZE , & sb ) ;
switch ( Format ) {
case WINED3DFMT_D16 :
case WINED3DFMT_D16_LOCKABLE :
if ( 16 = = db ) return TRUE ;
break ;
case WINED3DFMT_D32 :
if ( 32 = = db ) return TRUE ;
break ;
case WINED3DFMT_D15S1 :
if ( 15 = = db ) return TRUE ;
break ;
case WINED3DFMT_D24S8 :
if ( 24 = = db & & 8 = = sb ) return TRUE ;
break ;
2005-09-07 11:25:26 +02:00
case WINED3DFMT_D24FS8 :
if ( 24 = = db & & 8 = = sb ) return TRUE ;
break ;
2005-04-28 14:02:03 +02:00
case WINED3DFMT_D24X8 :
if ( 24 = = db ) return TRUE ;
break ;
case WINED3DFMT_D24X4S4 :
if ( 24 = = db & & 4 = = sb ) return TRUE ;
break ;
case WINED3DFMT_D32F_LOCKABLE :
if ( 32 = = db ) return TRUE ;
break ;
default :
ERR ( " unsupported format %s \n " , debug_d3dformat ( Format ) ) ;
break ;
}
return FALSE ;
2005-11-10 12:39:07 +01:00
# else /* Most of the time performance is less of an issue than compatibility, this code allows for most common opengl/d3d formats */
2005-10-04 17:50:57 +02:00
switch ( Format ) {
case WINED3DFMT_D16 :
case WINED3DFMT_D16_LOCKABLE :
case WINED3DFMT_D32 :
case WINED3DFMT_D15S1 :
case WINED3DFMT_D24S8 :
case WINED3DFMT_D24FS8 :
case WINED3DFMT_D24X8 :
case WINED3DFMT_D24X4S4 :
case WINED3DFMT_D32F_LOCKABLE :
return TRUE ;
default :
ERR ( " unsupported format %s \n " , debug_d3dformat ( Format ) ) ;
break ;
}
return FALSE ;
# endif
2005-04-28 14:02:03 +02:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DImpl_CheckDepthStencilMatch ( IWineD3D * iface , UINT Adapter , WINED3DDEVTYPE DeviceType ,
2005-07-13 16:15:54 +02:00
WINED3DFORMAT AdapterFormat ,
WINED3DFORMAT RenderTargetFormat ,
WINED3DFORMAT DepthStencilFormat ) {
2004-10-05 04:14:06 +02:00
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
2006-04-07 12:51:12 +02:00
HRESULT hr = WINED3DERR_NOTAVAILABLE ;
2005-09-19 16:31:21 +02:00
WineD3D_Context * ctx = NULL ;
GLXFBConfig * cfgs = NULL ;
int nCfgs = 0 ;
int it ;
2005-07-13 16:15:54 +02:00
WARN_ ( d3d_caps ) ( " (%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), AdptFmt:(%x,%s), RendrTgtFmt:(%x,%s), DepthStencilFmt:(%x,%s)) \n " ,
This , Adapter ,
2004-10-05 04:14:06 +02:00
DeviceType , debug_d3ddevicetype ( DeviceType ) ,
AdapterFormat , debug_d3dformat ( AdapterFormat ) ,
2005-07-13 16:15:54 +02:00
RenderTargetFormat , debug_d3dformat ( RenderTargetFormat ) ,
2004-10-05 04:14:06 +02:00
DepthStencilFormat , debug_d3dformat ( DepthStencilFormat ) ) ;
if ( Adapter > = IWineD3D_GetAdapterCount ( iface ) ) {
2006-04-07 12:51:12 +02:00
TRACE ( " (%p) Failed: Atapter (%u) higher than supported adapters (%u) returning WINED3DERR_INVALIDCALL \n " , This , Adapter , IWineD3D_GetAdapterCount ( iface ) ) ;
return WINED3DERR_INVALIDCALL ;
2004-10-05 04:14:06 +02:00
}
2005-09-19 16:31:21 +02:00
/* TODO: use the real context if it's available */
ctx = WineD3D_CreateFakeGLContext ( ) ;
if ( NULL ! = ctx ) {
2005-07-13 16:15:54 +02:00
cfgs = glXGetFBConfigs ( ctx - > display , DefaultScreen ( ctx - > display ) , & nCfgs ) ;
2005-09-19 16:31:21 +02:00
} else {
TRACE_ ( d3d_caps ) ( " (%p) : Unable to create a fake context at this time (there may already be an active context) \n " , This ) ;
}
if ( NULL ! = cfgs ) {
2005-07-13 16:15:54 +02:00
for ( it = 0 ; it < nCfgs ; + + it ) {
if ( IWineD3DImpl_IsGLXFBConfigCompatibleWithRenderFmt ( ctx , cfgs [ it ] , RenderTargetFormat ) ) {
if ( IWineD3DImpl_IsGLXFBConfigCompatibleWithDepthFmt ( ctx , cfgs [ it ] , DepthStencilFormat ) ) {
2006-04-07 12:51:12 +02:00
hr = WINED3D_OK ;
2005-07-13 16:15:54 +02:00
break ;
}
}
}
XFree ( cfgs ) ;
2005-09-19 16:31:21 +02:00
cfgs = NULL ;
} else {
/* If there's a corrent context then we cannot create a fake one so pass everything */
2006-04-07 12:51:12 +02:00
hr = WINED3D_OK ;
2005-09-19 16:31:21 +02:00
}
2005-07-13 16:15:54 +02:00
2005-09-19 16:31:21 +02:00
if ( ctx ! = NULL )
2005-07-13 16:15:54 +02:00
WineD3D_ReleaseFakeGLContext ( ctx ) ;
2006-04-07 12:51:12 +02:00
if ( hr ! = WINED3D_OK )
2005-09-19 16:31:21 +02:00
TRACE_ ( d3d_caps ) ( " Failed to match stencil format to device \b " ) ;
2005-09-19 17:25:07 +02:00
TRACE_ ( d3d_caps ) ( " (%p) : Returning %lx \n " , This , hr ) ;
2005-09-19 16:31:21 +02:00
return hr ;
2004-10-05 04:14:06 +02:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DImpl_CheckDeviceMultiSampleType ( IWineD3D * iface , UINT Adapter , WINED3DDEVTYPE DeviceType ,
2005-07-13 16:15:54 +02:00
WINED3DFORMAT SurfaceFormat ,
2006-03-24 17:34:26 +01:00
BOOL Windowed , WINED3DMULTISAMPLE_TYPE MultiSampleType , DWORD * pQualityLevels ) {
2005-07-13 16:15:54 +02:00
2004-10-05 04:14:06 +02:00
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
2005-07-13 16:15:54 +02:00
TRACE_ ( d3d_caps ) ( " (%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), SurfFmt:(%x,%s), Win?%d, MultiSamp:%x, pQual:%p) \n " ,
This ,
Adapter ,
2004-10-05 04:14:06 +02:00
DeviceType , debug_d3ddevicetype ( DeviceType ) ,
SurfaceFormat , debug_d3dformat ( SurfaceFormat ) ,
2005-07-13 16:15:54 +02:00
Windowed ,
2004-10-05 04:14:06 +02:00
MultiSampleType ,
pQualityLevels ) ;
2005-07-13 16:15:54 +02:00
2004-10-05 04:14:06 +02:00
if ( Adapter > = IWineD3D_GetAdapterCount ( iface ) ) {
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2004-10-05 04:14:06 +02:00
}
if ( pQualityLevels ! = NULL ) {
2005-07-13 16:15:54 +02:00
static int s_single_shot = 0 ;
if ( ! s_single_shot ) {
FIXME ( " Quality levels unsupported at present \n " ) ;
s_single_shot = 1 ;
}
* pQualityLevels = 1 ; /* Guess at a value! */
2004-10-05 04:14:06 +02:00
}
2006-04-07 12:51:12 +02:00
if ( WINED3DMULTISAMPLE_NONE = = MultiSampleType ) return WINED3D_OK ;
return WINED3DERR_NOTAVAILABLE ;
2004-10-05 04:14:06 +02:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DImpl_CheckDeviceType ( IWineD3D * iface , UINT Adapter , WINED3DDEVTYPE CheckType ,
2005-07-13 16:15:54 +02:00
WINED3DFORMAT DisplayFormat , WINED3DFORMAT BackBufferFormat , BOOL Windowed ) {
2004-10-05 04:14:06 +02:00
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
2005-07-13 16:15:54 +02:00
TRACE_ ( d3d_caps ) ( " (%p)-> (STUB) (Adptr:%d, CheckType:(%x,%s), DispFmt:(%x,%s), BackBuf:(%x,%s), Win?%d): stub \n " ,
This ,
Adapter ,
2004-10-05 04:14:06 +02:00
CheckType , debug_d3ddevicetype ( CheckType ) ,
DisplayFormat , debug_d3dformat ( DisplayFormat ) ,
BackBufferFormat , debug_d3dformat ( BackBufferFormat ) ,
Windowed ) ;
if ( Adapter > = IWineD3D_GetAdapterCount ( iface ) ) {
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2004-10-05 04:14:06 +02:00
}
2005-04-28 14:02:03 +02:00
{
GLXFBConfig * cfgs = NULL ;
int nCfgs = 0 ;
int it ;
2006-04-07 12:51:12 +02:00
HRESULT hr = WINED3DERR_NOTAVAILABLE ;
2005-07-13 16:15:54 +02:00
2005-04-28 14:02:03 +02:00
WineD3D_Context * ctx = WineD3D_CreateFakeGLContext ( ) ;
if ( NULL ! = ctx ) {
2005-07-13 16:15:54 +02:00
cfgs = glXGetFBConfigs ( ctx - > display , DefaultScreen ( ctx - > display ) , & nCfgs ) ;
for ( it = 0 ; it < nCfgs ; + + it ) {
if ( IWineD3DImpl_IsGLXFBConfigCompatibleWithRenderFmt ( ctx , cfgs [ it ] , DisplayFormat ) ) {
2006-04-07 12:51:12 +02:00
hr = WINED3D_OK ;
2005-07-13 16:15:54 +02:00
break ;
}
}
XFree ( cfgs ) ;
WineD3D_ReleaseFakeGLContext ( ctx ) ;
return hr ;
2005-04-28 14:02:03 +02:00
}
2004-10-05 04:14:06 +02:00
}
2005-04-28 14:02:03 +02:00
2006-04-07 12:51:12 +02:00
return WINED3DERR_NOTAVAILABLE ;
2004-10-05 04:14:06 +02:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat ( IWineD3D * iface , UINT Adapter , WINED3DDEVTYPE DeviceType ,
2006-03-09 23:21:16 +01:00
WINED3DFORMAT AdapterFormat , DWORD Usage , WINED3DRESOURCETYPE RType , WINED3DFORMAT CheckFormat ) {
2004-10-05 04:14:06 +02:00
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
2006-07-28 21:33:20 +02:00
TRACE_ ( d3d_caps ) ( " (%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), AdptFmt:(%u,%s), Use:(%lu,%s,%s), ResTyp:(%x,%s), CheckFmt:(%u,%s)) " ,
2005-07-13 16:15:54 +02:00
This ,
Adapter ,
DeviceType , debug_d3ddevicetype ( DeviceType ) ,
AdapterFormat , debug_d3dformat ( AdapterFormat ) ,
2006-07-28 21:33:20 +02:00
Usage , debug_d3dusage ( Usage ) , debug_d3dusagequery ( Usage ) ,
2005-07-13 16:15:54 +02:00
RType , debug_d3dresourcetype ( RType ) ,
2004-10-05 04:14:06 +02:00
CheckFormat , debug_d3dformat ( CheckFormat ) ) ;
if ( Adapter > = IWineD3D_GetAdapterCount ( iface ) ) {
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2004-10-05 04:14:06 +02:00
}
2006-07-28 21:33:20 +02:00
/* TODO: Check support against more of the WINED3DUSAGE_QUERY_* constants
* See http : //msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/IDirect3D9__CheckDeviceFormat.asp
* and http : //msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/D3DUSAGE_QUERY.asp */
if ( Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE ) {
TRACE_ ( d3d_caps ) ( " [FAILED] \n " ) ;
return WINED3DERR_NOTAVAILABLE ; /* Enable when fully supported */
}
2006-07-22 01:58:19 +02:00
if ( Usage & WINED3DUSAGE_DEPTHSTENCIL ) {
switch ( CheckFormat ) {
case WINED3DFMT_D16_LOCKABLE :
case WINED3DFMT_D32 :
case WINED3DFMT_D15S1 :
case WINED3DFMT_D24S8 :
case WINED3DFMT_D24X8 :
case WINED3DFMT_D24X4S4 :
case WINED3DFMT_D16 :
case WINED3DFMT_L16 :
case WINED3DFMT_D32F_LOCKABLE :
case WINED3DFMT_D24FS8 :
TRACE_ ( d3d_caps ) ( " [OK] \n " ) ;
2006-07-28 21:33:20 +02:00
return WINED3D_OK ;
2006-07-22 01:58:19 +02:00
default :
TRACE_ ( d3d_caps ) ( " [FAILED] \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
} else if ( Usage & WINED3DUSAGE_RENDERTARGET ) {
switch ( CheckFormat ) {
case WINED3DFMT_R8G8B8 :
case WINED3DFMT_A8R8G8B8 :
case WINED3DFMT_X8R8G8B8 :
case WINED3DFMT_R5G6B5 :
case WINED3DFMT_X1R5G5B5 :
case WINED3DFMT_A1R5G5B5 :
case WINED3DFMT_A4R4G4B4 :
case WINED3DFMT_R3G3B2 :
case WINED3DFMT_X4R4G4B4 :
case WINED3DFMT_A8B8G8R8 :
case WINED3DFMT_X8B8G8R8 :
case WINED3DFMT_P8 :
TRACE_ ( d3d_caps ) ( " [OK] \n " ) ;
return WINED3D_OK ;
default :
TRACE_ ( d3d_caps ) ( " [FAILED] \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
}
2004-10-05 04:14:06 +02:00
if ( GL_SUPPORT ( EXT_TEXTURE_COMPRESSION_S3TC ) ) {
switch ( CheckFormat ) {
case D3DFMT_DXT1 :
2005-08-29 14:20:02 +02:00
case D3DFMT_DXT2 :
2004-10-05 04:14:06 +02:00
case D3DFMT_DXT3 :
2005-08-29 14:20:02 +02:00
case D3DFMT_DXT4 :
2004-10-05 04:14:06 +02:00
case D3DFMT_DXT5 :
TRACE_ ( d3d_caps ) ( " [OK] \n " ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-10-05 04:14:06 +02:00
default :
break ; /* Avoid compiler warnings */
}
}
2006-07-27 00:56:09 +02:00
/* This format is nothing special and it is supported perfectly.
* However , ati and nvidia driver on windows do not mark this format
* supported ( tested with the dxCapsViewer ) and pretending to
* support this format uncovers a bug in Battlefield 1942 ( fonts are missing )
* So do the same as Windows drivers and pretend not to support it on dx8 and 9
* Enable it on dx7 . It will need additional checking on dx10 when we support it .
*/
if ( This - > dxVersion > 7 & & CheckFormat = = WINED3DFMT_R8G8B8 ) {
TRACE_ ( d3d_caps ) ( " [FAILED] \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
2004-10-05 04:14:06 +02:00
switch ( CheckFormat ) {
2006-07-22 01:58:19 +02:00
/*****
* supported : RGB ( A ) formats
*/
2006-07-27 00:56:09 +02:00
case WINED3DFMT_R8G8B8 : /* Enable for dx7, blacklisted for 8 and 9 above */
2006-07-22 01:58:19 +02:00
case WINED3DFMT_A8R8G8B8 :
case WINED3DFMT_X8R8G8B8 :
case WINED3DFMT_R5G6B5 :
case WINED3DFMT_X1R5G5B5 :
case WINED3DFMT_A1R5G5B5 :
case WINED3DFMT_A4R4G4B4 :
case WINED3DFMT_R3G3B2 :
case WINED3DFMT_A8 :
case WINED3DFMT_A8R3G3B2 :
case WINED3DFMT_X4R4G4B4 :
case WINED3DFMT_A8B8G8R8 :
case WINED3DFMT_X8B8G8R8 :
case WINED3DFMT_A2R10G10B10 :
case WINED3DFMT_A2B10G10R10 :
TRACE_ ( d3d_caps ) ( " [OK] \n " ) ;
return WINED3D_OK ;
/*****
* supported : Palettized
*/
case WINED3DFMT_P8 :
TRACE_ ( d3d_caps ) ( " [OK] \n " ) ;
return WINED3D_OK ;
/*****
* Supported : ( Alpha ) - Luminance
*/
case WINED3DFMT_L8 :
case WINED3DFMT_A8L8 :
case WINED3DFMT_A4L4 :
TRACE_ ( d3d_caps ) ( " [OK] \n " ) ;
return WINED3D_OK ;
/*****
* Not supported for now : Bump mapping formats
* Enable some because games often fail when they are not available
* and are still playable even without bump mapping
*/
case WINED3DFMT_V8U8 :
case WINED3DFMT_V16U16 :
case WINED3DFMT_L6V5U5 :
case WINED3DFMT_X8L8V8U8 :
case WINED3DFMT_Q8W8V8U8 :
case WINED3DFMT_W11V11U10 :
case WINED3DFMT_A2W10V10U10 :
2006-07-25 21:10:01 +02:00
WARN_ ( d3d_caps ) ( " [Not supported, but pretended to do] \n " ) ;
return WINED3D_OK ;
2006-07-22 01:58:19 +02:00
/*****
* DXTN Formats : Handled above
* WINED3DFMT_DXT1
* WINED3DFMT_DXT2
* WINED3DFMT_DXT3
* WINED3DFMT_DXT4
* WINED3DFMT_DXT5
*/
/*****
* Odd formats - not supported
*/
case WINED3DFMT_VERTEXDATA :
case WINED3DFMT_INDEX16 :
case WINED3DFMT_INDEX32 :
case WINED3DFMT_Q16W16V16U16 :
TRACE_ ( d3d_caps ) ( " [FAILED] \n " ) ; /* Enable when implemented */
2006-07-28 21:33:20 +02:00
return WINED3DERR_NOTAVAILABLE ;
2006-07-22 01:58:19 +02:00
/*****
* Float formats : Not supported right now
*/
case WINED3DFMT_R16F :
case WINED3DFMT_G16R16F :
case WINED3DFMT_A16B16G16R16F :
case WINED3DFMT_R32F :
case WINED3DFMT_G32R32F :
case WINED3DFMT_A32B32G32R32F :
case WINED3DFMT_CxV8U8 :
TRACE_ ( d3d_caps ) ( " [FAILED] \n " ) ; /* Enable when implemented */
2006-07-28 21:33:20 +02:00
return WINED3DERR_NOTAVAILABLE ;
2006-07-22 01:58:19 +02:00
/* Not supported */
case WINED3DFMT_G16R16 :
case WINED3DFMT_A16B16G16R16 :
TRACE_ ( d3d_caps ) ( " [FAILED] \n " ) ; /* Enable when implemented */
2006-07-28 21:33:20 +02:00
return WINED3DERR_NOTAVAILABLE ;
2004-10-05 04:14:06 +02:00
2006-07-22 01:58:19 +02:00
default :
break ;
2004-10-05 04:14:06 +02:00
}
2006-07-22 01:58:19 +02:00
TRACE_ ( d3d_caps ) ( " [FAILED] \n " ) ;
2006-07-28 21:33:20 +02:00
return WINED3DERR_NOTAVAILABLE ;
2004-10-05 04:14:06 +02:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormatConversion ( IWineD3D * iface , UINT Adapter , WINED3DDEVTYPE DeviceType ,
2005-07-13 16:15:54 +02:00
WINED3DFORMAT SourceFormat , WINED3DFORMAT TargetFormat ) {
2004-10-05 04:14:06 +02:00
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
2006-07-11 00:57:29 +02:00
FIXME_ ( d3d_caps ) ( " (%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), SrcFmt:(%u,%s), TgtFmt:(%u,%s)) \n " ,
2005-07-13 16:15:54 +02:00
This ,
Adapter ,
DeviceType , debug_d3ddevicetype ( DeviceType ) ,
SourceFormat , debug_d3dformat ( SourceFormat ) ,
2004-10-05 04:14:06 +02:00
TargetFormat , debug_d3dformat ( TargetFormat ) ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-10-05 04:14:06 +02:00
}
2005-07-13 16:15:54 +02:00
/* Note: d3d8 passes in a pointer to a D3DCAPS8 structure, which is a true
subset of a D3DCAPS9 structure . However , it has to come via a void *
2004-10-06 02:05:29 +02:00
as the d3d8 interface cannot import the d3d9 header */
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps ( IWineD3D * iface , UINT Adapter , WINED3DDEVTYPE DeviceType , WINED3DCAPS * pCaps ) {
2004-10-06 02:05:29 +02:00
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
TRACE_ ( d3d_caps ) ( " (%p)->(Adptr:%d, DevType: %x, pCaps: %p) \n " , This , Adapter , DeviceType , pCaps ) ;
if ( Adapter > = IWineD3D_GetAdapterCount ( iface ) ) {
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2004-10-06 02:05:29 +02:00
}
wined3d: Rework shader mode selection.
- currently half the shader selection code (GLSL vs ARB) is in
fillGLcaps. The parts that check for software shaders are in
GetDeviceCaps. That placement, will work, but is definitely not optimal.
FillGLcaps should detect support - it should not make decision as to
what's used, because that's not what the purpose of the function is.
GetDeviceCaps should report support as it has already been selected.
Instead, select shader mode in its own function, called in the
appropriate places.
- unifying pixel and vertex shaders into a single selection is a
mistake. A software vertex shader can be coupled with a hardware arb or
glsl pixel shader, or no shader at all. Split them back into two and add
a SHADER_NONE variant.
- drawprim is doing support checks for ARB_PROGRAM, and making shader
decisions based on that - that's wrong, support has already been
checked, and decided upon, and shaders can be implemented via software,
ARB_PROGRAm or GLSL, so that support check isn't valid.
- Store the shader selected mode into the shader itself. Different types
of shaders can be combined, so this is an improvement. In fact, storing
the mode into the settings globally is a mistake as well - it should be
done per device, since different cards have different capabilities.
2006-07-04 09:21:53 +02:00
/* FIXME: both the gl_info and the shader_mode should be made per adapter */
2004-10-06 02:05:29 +02:00
/* If we don't know the device settings, go query them now */
if ( This - > isGLInfoValid = = FALSE ) {
2005-07-10 19:48:07 +02:00
/* use the desktop window to fill gl caps */
2006-07-19 23:49:37 +02:00
BOOL rc = IWineD3DImpl_FillGLCaps ( iface , IWineD3DImpl_GetAdapterDisplay ( iface , Adapter ) ) ;
2005-07-10 19:48:07 +02:00
/* We are running off a real context, save the values */
if ( rc ) This - > isGLInfoValid = TRUE ;
2004-10-06 02:05:29 +02:00
}
wined3d: Rework shader mode selection.
- currently half the shader selection code (GLSL vs ARB) is in
fillGLcaps. The parts that check for software shaders are in
GetDeviceCaps. That placement, will work, but is definitely not optimal.
FillGLcaps should detect support - it should not make decision as to
what's used, because that's not what the purpose of the function is.
GetDeviceCaps should report support as it has already been selected.
Instead, select shader mode in its own function, called in the
appropriate places.
- unifying pixel and vertex shaders into a single selection is a
mistake. A software vertex shader can be coupled with a hardware arb or
glsl pixel shader, or no shader at all. Split them back into two and add
a SHADER_NONE variant.
- drawprim is doing support checks for ARB_PROGRAM, and making shader
decisions based on that - that's wrong, support has already been
checked, and decided upon, and shaders can be implemented via software,
ARB_PROGRAm or GLSL, so that support check isn't valid.
- Store the shader selected mode into the shader itself. Different types
of shaders can be combined, so this is an improvement. In fact, storing
the mode into the settings globally is a mistake as well - it should be
done per device, since different cards have different capabilities.
2006-07-04 09:21:53 +02:00
select_shader_mode ( & This - > gl_info , DeviceType ,
& wined3d_settings . ps_selected_mode , & wined3d_settings . vs_selected_mode ) ;
2006-07-23 21:08:27 +02:00
select_shader_max_constants ( & This - > gl_info ) ;
2004-10-06 02:05:29 +02:00
/* ------------------------------------------------
The following fields apply to both d3d8 and d3d9
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-30 00:16:08 +02:00
* pCaps - > DeviceType = ( DeviceType = = WINED3DDEVTYPE_HAL ) ? WINED3DDEVTYPE_HAL : WINED3DDEVTYPE_REF ; /* Not quite true, but use h/w supported by opengl I suppose */
2005-06-22 20:30:29 +02:00
* pCaps - > AdapterOrdinal = Adapter ;
* pCaps - > Caps = 0 ;
* pCaps - > Caps2 = D3DCAPS2_CANRENDERWINDOWED ;
2006-03-06 23:05:02 +01:00
* pCaps - > Caps3 = WINED3DDEVCAPS_HWTRANSFORMANDLIGHT ;
2005-06-22 20:30:29 +02:00
* pCaps - > PresentationIntervals = D3DPRESENT_INTERVAL_IMMEDIATE ;
* pCaps - > CursorCaps = 0 ;
2006-05-18 23:25:19 +02:00
* pCaps - > DevCaps = WINED3DDEVCAPS_FLOATTLVERTEX |
WINED3DDEVCAPS_EXECUTESYSTEMMEMORY |
2006-05-18 22:59:33 +02:00
WINED3DDEVCAPS_TLVERTEXSYSTEMMEMORY |
WINED3DDEVCAPS_TLVERTEXVIDEOMEMORY |
WINED3DDEVCAPS_DRAWPRIMTLVERTEX |
2006-03-06 23:05:02 +01:00
WINED3DDEVCAPS_HWTRANSFORMANDLIGHT |
WINED3DDEVCAPS_EXECUTEVIDEOMEMORY |
WINED3DDEVCAPS_PUREDEVICE |
WINED3DDEVCAPS_HWRASTERIZATION |
2006-05-18 22:59:33 +02:00
WINED3DDEVCAPS_TEXTUREVIDEOMEMORY |
2006-05-18 23:25:19 +02:00
WINED3DDEVCAPS_TEXTURESYSTEMMEMORY |
WINED3DDEVCAPS_CANRENDERAFTERFLIP |
WINED3DDEVCAPS_DRAWPRIMITIVES2 |
WINED3DDEVCAPS_DRAWPRIMITIVES2EX ;
2005-06-22 20:30:29 +02:00
* pCaps - > PrimitiveMiscCaps = D3DPMISCCAPS_CULLCCW |
D3DPMISCCAPS_CULLCW |
D3DPMISCCAPS_COLORWRITEENABLE |
D3DPMISCCAPS_CLIPTLVERTS |
D3DPMISCCAPS_CLIPPLANESCALEDPOINTS |
D3DPMISCCAPS_MASKZ ;
2004-10-06 02:05:29 +02:00
/*NOT: D3DPMISCCAPS_TSSARGTEMP*/
2006-03-05 21:07:10 +01:00
* pCaps - > RasterCaps = WINED3DPRASTERCAPS_DITHER |
WINED3DPRASTERCAPS_PAT |
WINED3DPRASTERCAPS_WFOG |
WINED3DPRASTERCAPS_ZFOG |
WINED3DPRASTERCAPS_FOGVERTEX |
WINED3DPRASTERCAPS_FOGTABLE |
2006-05-18 23:25:19 +02:00
WINED3DPRASTERCAPS_FOGRANGE |
WINED3DPRASTERCAPS_STIPPLE |
WINED3DPRASTERCAPS_SUBPIXEL |
WINED3DPRASTERCAPS_ZTEST ;
2004-10-06 02:05:29 +02:00
if ( GL_SUPPORT ( EXT_TEXTURE_FILTER_ANISOTROPIC ) ) {
2006-03-05 21:07:10 +01:00
* pCaps - > RasterCaps | = WINED3DPRASTERCAPS_ANISOTROPY |
WINED3DPRASTERCAPS_ZBIAS |
WINED3DPRASTERCAPS_MIPMAPLODBIAS ;
2004-10-06 02:05:29 +02:00
}
/* FIXME Add:
2006-03-05 21:07:10 +01:00
WINED3DPRASTERCAPS_COLORPERSPECTIVE
WINED3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
WINED3DPRASTERCAPS_ANTIALIASEDGES
WINED3DPRASTERCAPS_ZBUFFERLESSHSR
WINED3DPRASTERCAPS_WBUFFER */
2004-10-06 02:05:29 +02:00
2005-06-22 20:30:29 +02:00
* pCaps - > ZCmpCaps = D3DPCMPCAPS_ALWAYS |
D3DPCMPCAPS_EQUAL |
D3DPCMPCAPS_GREATER |
D3DPCMPCAPS_GREATEREQUAL |
D3DPCMPCAPS_LESS |
D3DPCMPCAPS_LESSEQUAL |
D3DPCMPCAPS_NEVER |
D3DPCMPCAPS_NOTEQUAL ;
* pCaps - > SrcBlendCaps = 0xFFFFFFFF ; /*FIXME: Tidy up later */
* pCaps - > DestBlendCaps = 0xFFFFFFFF ; /*FIXME: Tidy up later */
* pCaps - > AlphaCmpCaps = 0xFFFFFFFF ; /*FIXME: Tidy up later */
2006-03-05 21:07:10 +01:00
* pCaps - > ShadeCaps = WINED3DPSHADECAPS_SPECULARGOURAUDRGB |
2006-05-18 23:25:19 +02:00
WINED3DPSHADECAPS_COLORGOURAUDRGB |
WINED3DPSHADECAPS_ALPHAFLATBLEND |
WINED3DPSHADECAPS_ALPHAGOURAUDBLEND |
WINED3DPSHADECAPS_COLORFLATRGB |
WINED3DPSHADECAPS_FOGFLAT |
WINED3DPSHADECAPS_FOGGOURAUD |
WINED3DPSHADECAPS_SPECULARFLATRGB ;
2005-06-22 20:30:29 +02:00
2006-03-05 21:07:10 +01:00
* pCaps - > TextureCaps = WINED3DPTEXTURECAPS_ALPHA |
WINED3DPTEXTURECAPS_ALPHAPALETTE |
2006-05-18 23:25:19 +02:00
WINED3DPTEXTURECAPS_BORDER |
2006-03-05 21:07:10 +01:00
WINED3DPTEXTURECAPS_VOLUMEMAP |
WINED3DPTEXTURECAPS_MIPMAP |
WINED3DPTEXTURECAPS_PROJECTED |
WINED3DPTEXTURECAPS_PERSPECTIVE |
2006-05-18 23:25:19 +02:00
WINED3DPTEXTURECAPS_VOLUMEMAP_POW2 |
WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL ;
2004-10-06 02:05:29 +02:00
if ( GL_SUPPORT ( ARB_TEXTURE_CUBE_MAP ) ) {
2006-03-05 21:07:10 +01:00
* pCaps - > TextureCaps | = WINED3DPTEXTURECAPS_CUBEMAP |
WINED3DPTEXTURECAPS_MIPCUBEMAP |
WINED3DPTEXTURECAPS_CUBEMAP_POW2 ;
2005-06-22 20:30:29 +02:00
2004-10-06 02:05:29 +02:00
}
2006-05-18 23:25:19 +02:00
* pCaps - > TextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR |
WINED3DPTFILTERCAPS_MAGFPOINT |
WINED3DPTFILTERCAPS_MINFLINEAR |
WINED3DPTFILTERCAPS_MINFPOINT |
WINED3DPTFILTERCAPS_MIPFLINEAR |
WINED3DPTFILTERCAPS_MIPFPOINT |
WINED3DPTFILTERCAPS_LINEAR |
WINED3DPTFILTERCAPS_LINEARMIPLINEAR |
WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
WINED3DPTFILTERCAPS_MIPLINEAR |
WINED3DPTFILTERCAPS_MIPNEAREST |
WINED3DPTFILTERCAPS_NEAREST ;
2004-10-06 02:05:29 +02:00
2005-06-22 20:30:29 +02:00
* pCaps - > CubeTextureFilterCaps = 0 ;
* pCaps - > VolumeTextureFilterCaps = 0 ;
2004-10-06 02:05:29 +02:00
2005-06-22 20:30:29 +02:00
* pCaps - > TextureAddressCaps = D3DPTADDRESSCAPS_BORDER |
D3DPTADDRESSCAPS_CLAMP |
D3DPTADDRESSCAPS_WRAP ;
2004-10-06 02:05:29 +02:00
if ( GL_SUPPORT ( ARB_TEXTURE_BORDER_CLAMP ) ) {
2005-06-22 20:30:29 +02:00
* pCaps - > TextureAddressCaps | = D3DPTADDRESSCAPS_BORDER ;
2004-10-06 02:05:29 +02:00
}
if ( GL_SUPPORT ( ARB_TEXTURE_MIRRORED_REPEAT ) ) {
2005-06-22 20:30:29 +02:00
* pCaps - > TextureAddressCaps | = D3DPTADDRESSCAPS_MIRROR ;
2004-10-06 02:05:29 +02:00
}
if ( GL_SUPPORT ( ATI_TEXTURE_MIRROR_ONCE ) ) {
2005-06-22 20:30:29 +02:00
* pCaps - > TextureAddressCaps | = D3DPTADDRESSCAPS_MIRRORONCE ;
2004-10-06 02:05:29 +02:00
}
2005-06-22 20:30:29 +02:00
* pCaps - > VolumeTextureAddressCaps = 0 ;
2004-10-06 02:05:29 +02:00
2005-06-22 20:30:29 +02:00
* pCaps - > LineCaps = D3DLINECAPS_TEXTURE |
D3DLINECAPS_ZTEST ;
/* FIXME: Add
2004-10-06 02:05:29 +02:00
D3DLINECAPS_BLEND
D3DLINECAPS_ALPHACMP
D3DLINECAPS_FOG */
2005-07-10 19:48:07 +02:00
* pCaps - > MaxTextureWidth = GL_LIMITS ( texture_size ) ;
* pCaps - > MaxTextureHeight = GL_LIMITS ( texture_size ) ;
2004-10-06 02:05:29 +02:00
2005-06-22 20:30:29 +02:00
* pCaps - > MaxVolumeExtent = 0 ;
2004-10-06 02:05:29 +02:00
2005-06-22 20:30:29 +02:00
* pCaps - > MaxTextureRepeat = 32768 ;
* pCaps - > MaxTextureAspectRatio = 32768 ;
* pCaps - > MaxVertexW = 1.0 ;
2004-10-06 02:05:29 +02:00
2005-06-22 20:30:29 +02:00
* pCaps - > GuardBandLeft = 0 ;
* pCaps - > GuardBandTop = 0 ;
* pCaps - > GuardBandRight = 0 ;
* pCaps - > GuardBandBottom = 0 ;
2004-10-06 02:05:29 +02:00
2005-06-22 20:30:29 +02:00
* pCaps - > ExtentsAdjust = 0 ;
2004-10-06 02:05:29 +02:00
2005-06-22 20:30:29 +02:00
* pCaps - > StencilCaps = D3DSTENCILCAPS_DECRSAT |
D3DSTENCILCAPS_INCRSAT |
D3DSTENCILCAPS_INVERT |
D3DSTENCILCAPS_KEEP |
D3DSTENCILCAPS_REPLACE |
D3DSTENCILCAPS_ZERO ;
2004-10-06 02:05:29 +02:00
if ( GL_SUPPORT ( EXT_STENCIL_WRAP ) ) {
2005-06-22 20:30:29 +02:00
* pCaps - > StencilCaps | = D3DSTENCILCAPS_DECR |
D3DSTENCILCAPS_INCR ;
2004-10-06 02:05:29 +02:00
}
2006-06-09 17:30:20 +02:00
if ( This - > dxVersion > 8 & &
( GL_SUPPORT ( EXT_STENCIL_TWO_SIDE ) | |
GL_SUPPORT ( ATI_SEPARATE_STENCIL ) ) ) {
* pCaps - > StencilCaps | = D3DSTENCILCAPS_TWOSIDED ;
}
2004-10-06 02:05:29 +02:00
2005-06-22 20:30:29 +02:00
* pCaps - > FVFCaps = D3DFVFCAPS_PSIZE | 0x0008 ; /* 8 texture coords */
* pCaps - > TextureOpCaps = D3DTEXOPCAPS_ADD |
D3DTEXOPCAPS_ADDSIGNED |
D3DTEXOPCAPS_ADDSIGNED2X |
D3DTEXOPCAPS_MODULATE |
D3DTEXOPCAPS_MODULATE2X |
D3DTEXOPCAPS_MODULATE4X |
D3DTEXOPCAPS_SELECTARG1 |
D3DTEXOPCAPS_SELECTARG2 |
D3DTEXOPCAPS_DISABLE ;
2004-10-06 02:05:29 +02:00
# if defined(GL_VERSION_1_3)
2005-06-22 20:30:29 +02:00
* pCaps - > TextureOpCaps | = D3DTEXOPCAPS_DOTPRODUCT3 |
D3DTEXOPCAPS_SUBTRACT ;
2004-10-06 02:05:29 +02:00
# endif
2005-06-22 20:30:29 +02:00
if ( GL_SUPPORT ( ARB_TEXTURE_ENV_COMBINE ) | |
GL_SUPPORT ( EXT_TEXTURE_ENV_COMBINE ) | |
GL_SUPPORT ( NV_TEXTURE_ENV_COMBINE4 ) ) {
* pCaps - > TextureOpCaps | = D3DTEXOPCAPS_BLENDDIFFUSEALPHA |
D3DTEXOPCAPS_BLENDTEXTUREALPHA |
D3DTEXOPCAPS_BLENDFACTORALPHA |
D3DTEXOPCAPS_BLENDCURRENTALPHA |
D3DTEXOPCAPS_LERP ;
2004-10-06 02:05:29 +02:00
}
if ( GL_SUPPORT ( NV_TEXTURE_ENV_COMBINE4 ) ) {
2005-06-22 20:30:29 +02:00
* pCaps - > TextureOpCaps | = D3DTEXOPCAPS_ADDSMOOTH |
D3DTEXOPCAPS_MULTIPLYADD |
D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR |
D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA |
D3DTEXOPCAPS_BLENDTEXTUREALPHAPM ;
2004-10-06 02:05:29 +02:00
}
2005-07-13 16:15:54 +02:00
2004-10-06 02:05:29 +02:00
#if 0
2005-07-10 19:48:07 +02:00
* pCaps - > TextureOpCaps | = D3DTEXOPCAPS_BUMPENVMAP ;
2005-07-13 16:15:54 +02:00
/* FIXME: Add
D3DTEXOPCAPS_BUMPENVMAPLUMINANCE
D3DTEXOPCAPS_PREMODULATE */
2004-10-06 02:05:29 +02:00
# endif
2006-06-27 23:40:42 +02:00
* pCaps - > MaxTextureBlendStages = GL_LIMITS ( texture_stages ) ;
2005-07-10 19:48:07 +02:00
* pCaps - > MaxSimultaneousTextures = GL_LIMITS ( textures ) ;
* pCaps - > MaxUserClipPlanes = GL_LIMITS ( clipplanes ) ;
* pCaps - > MaxActiveLights = GL_LIMITS ( lights ) ;
#if 0 /* TODO: Blends support in drawprim */
* pCaps - > MaxVertexBlendMatrices = GL_LIMITS ( blends ) ;
2005-06-22 20:30:29 +02:00
# else
2005-07-10 19:48:07 +02:00
* pCaps - > MaxVertexBlendMatrices = 0 ;
2005-06-22 20:30:29 +02:00
# endif
2005-07-10 19:48:07 +02:00
* pCaps - > MaxVertexBlendMatrixIndex = 1 ;
2004-10-06 02:05:29 +02:00
2005-07-10 19:48:07 +02:00
* pCaps - > MaxAnisotropy = GL_LIMITS ( anisotropy ) ;
* pCaps - > MaxPointSize = GL_LIMITS ( pointsize ) ;
2004-10-06 02:05:29 +02:00
2006-03-05 21:07:10 +01:00
* pCaps - > VertexProcessingCaps = WINED3DVTXPCAPS_DIRECTIONALLIGHTS |
WINED3DVTXPCAPS_MATERIALSOURCE7 |
WINED3DVTXPCAPS_POSITIONALLIGHTS |
2006-05-18 23:25:19 +02:00
WINED3DVTXPCAPS_LOCALVIEWER |
WINED3DVTXPCAPS_VERTEXFOG |
2006-03-05 21:07:10 +01:00
WINED3DVTXPCAPS_TEXGEN ;
2004-10-06 02:05:29 +02:00
/* FIXME: Add
D3DVTXPCAPS_TWEENING */
2005-06-22 20:30:29 +02:00
* pCaps - > MaxPrimitiveCount = 0xFFFFFFFF ;
* pCaps - > MaxVertexIndex = 0xFFFFFFFF ;
* pCaps - > MaxStreams = MAX_STREAMS ;
* pCaps - > MaxStreamStride = 1024 ;
2004-10-06 02:05:29 +02:00
wined3d: Rework shader mode selection.
- currently half the shader selection code (GLSL vs ARB) is in
fillGLcaps. The parts that check for software shaders are in
GetDeviceCaps. That placement, will work, but is definitely not optimal.
FillGLcaps should detect support - it should not make decision as to
what's used, because that's not what the purpose of the function is.
GetDeviceCaps should report support as it has already been selected.
Instead, select shader mode in its own function, called in the
appropriate places.
- unifying pixel and vertex shaders into a single selection is a
mistake. A software vertex shader can be coupled with a hardware arb or
glsl pixel shader, or no shader at all. Split them back into two and add
a SHADER_NONE variant.
- drawprim is doing support checks for ARB_PROGRAM, and making shader
decisions based on that - that's wrong, support has already been
checked, and decided upon, and shaders can be implemented via software,
ARB_PROGRAm or GLSL, so that support check isn't valid.
- Store the shader selected mode into the shader itself. Different types
of shaders can be combined, so this is an improvement. In fact, storing
the mode into the settings globally is a mistake as well - it should be
done per device, since different cards have different capabilities.
2006-07-04 09:21:53 +02:00
/* FIXME: the shader mode should be per adapter */
if ( wined3d_settings . vs_selected_mode = = SHADER_GLSL ) {
2006-05-18 03:24:08 +02:00
* pCaps - > VertexShaderVersion = D3DVS_VERSION ( 3 , 0 ) ;
wined3d: Rework shader mode selection.
- currently half the shader selection code (GLSL vs ARB) is in
fillGLcaps. The parts that check for software shaders are in
GetDeviceCaps. That placement, will work, but is definitely not optimal.
FillGLcaps should detect support - it should not make decision as to
what's used, because that's not what the purpose of the function is.
GetDeviceCaps should report support as it has already been selected.
Instead, select shader mode in its own function, called in the
appropriate places.
- unifying pixel and vertex shaders into a single selection is a
mistake. A software vertex shader can be coupled with a hardware arb or
glsl pixel shader, or no shader at all. Split them back into two and add
a SHADER_NONE variant.
- drawprim is doing support checks for ARB_PROGRAM, and making shader
decisions based on that - that's wrong, support has already been
checked, and decided upon, and shaders can be implemented via software,
ARB_PROGRAm or GLSL, so that support check isn't valid.
- Store the shader selected mode into the shader itself. Different types
of shaders can be combined, so this is an improvement. In fact, storing
the mode into the settings globally is a mistake as well - it should be
done per device, since different cards have different capabilities.
2006-07-04 09:21:53 +02:00
TRACE_ ( d3d_caps ) ( " Hardware vertex shader version 3.0 enabled (GLSL) \n " ) ;
} else if ( wined3d_settings . vs_selected_mode = = SHADER_ARB ) {
2006-05-08 22:39:04 +02:00
* pCaps - > VertexShaderVersion = D3DVS_VERSION ( 1 , 1 ) ;
wined3d: Rework shader mode selection.
- currently half the shader selection code (GLSL vs ARB) is in
fillGLcaps. The parts that check for software shaders are in
GetDeviceCaps. That placement, will work, but is definitely not optimal.
FillGLcaps should detect support - it should not make decision as to
what's used, because that's not what the purpose of the function is.
GetDeviceCaps should report support as it has already been selected.
Instead, select shader mode in its own function, called in the
appropriate places.
- unifying pixel and vertex shaders into a single selection is a
mistake. A software vertex shader can be coupled with a hardware arb or
glsl pixel shader, or no shader at all. Split them back into two and add
a SHADER_NONE variant.
- drawprim is doing support checks for ARB_PROGRAM, and making shader
decisions based on that - that's wrong, support has already been
checked, and decided upon, and shaders can be implemented via software,
ARB_PROGRAm or GLSL, so that support check isn't valid.
- Store the shader selected mode into the shader itself. Different types
of shaders can be combined, so this is an improvement. In fact, storing
the mode into the settings globally is a mistake as well - it should be
done per device, since different cards have different capabilities.
2006-07-04 09:21:53 +02:00
TRACE_ ( d3d_caps ) ( " Hardware vertex shader version 1.1 enabled (ARB_PROGRAM) \n " ) ;
} else if ( wined3d_settings . vs_selected_mode = = SHADER_SW ) {
* pCaps - > VertexShaderVersion = D3DVS_VERSION ( 3 , 0 ) ;
TRACE_ ( d3d_caps ) ( " Software vertex shader version 3.0 enabled \n " ) ;
2006-05-08 22:39:04 +02:00
} else {
* pCaps - > VertexShaderVersion = 0 ;
2006-05-18 19:21:00 +02:00
TRACE_ ( d3d_caps ) ( " Vertex shader functionality not available \n " ) ;
2006-05-08 22:39:04 +02:00
}
2005-06-22 20:30:29 +02:00
2006-07-19 06:06:07 +02:00
* pCaps - > MaxVertexShaderConst = GL_LIMITS ( vshader_constantsF ) ;
2004-10-06 02:05:29 +02:00
wined3d: Rework shader mode selection.
- currently half the shader selection code (GLSL vs ARB) is in
fillGLcaps. The parts that check for software shaders are in
GetDeviceCaps. That placement, will work, but is definitely not optimal.
FillGLcaps should detect support - it should not make decision as to
what's used, because that's not what the purpose of the function is.
GetDeviceCaps should report support as it has already been selected.
Instead, select shader mode in its own function, called in the
appropriate places.
- unifying pixel and vertex shaders into a single selection is a
mistake. A software vertex shader can be coupled with a hardware arb or
glsl pixel shader, or no shader at all. Split them back into two and add
a SHADER_NONE variant.
- drawprim is doing support checks for ARB_PROGRAM, and making shader
decisions based on that - that's wrong, support has already been
checked, and decided upon, and shaders can be implemented via software,
ARB_PROGRAm or GLSL, so that support check isn't valid.
- Store the shader selected mode into the shader itself. Different types
of shaders can be combined, so this is an improvement. In fact, storing
the mode into the settings globally is a mistake as well - it should be
done per device, since different cards have different capabilities.
2006-07-04 09:21:53 +02:00
/* FIXME: the shader ode should be per adapter */
if ( wined3d_settings . ps_selected_mode = = SHADER_GLSL ) {
2006-05-18 03:24:08 +02:00
* pCaps - > PixelShaderVersion = D3DPS_VERSION ( 3 , 0 ) ;
2006-06-15 17:38:04 +02:00
/* FIXME: The following line is card dependent. -1.0 to 1.0 is a safe default clamp range for now */
2006-05-08 22:39:04 +02:00
* pCaps - > PixelShader1xMaxValue = 1.0 ;
wined3d: Rework shader mode selection.
- currently half the shader selection code (GLSL vs ARB) is in
fillGLcaps. The parts that check for software shaders are in
GetDeviceCaps. That placement, will work, but is definitely not optimal.
FillGLcaps should detect support - it should not make decision as to
what's used, because that's not what the purpose of the function is.
GetDeviceCaps should report support as it has already been selected.
Instead, select shader mode in its own function, called in the
appropriate places.
- unifying pixel and vertex shaders into a single selection is a
mistake. A software vertex shader can be coupled with a hardware arb or
glsl pixel shader, or no shader at all. Split them back into two and add
a SHADER_NONE variant.
- drawprim is doing support checks for ARB_PROGRAM, and making shader
decisions based on that - that's wrong, support has already been
checked, and decided upon, and shaders can be implemented via software,
ARB_PROGRAm or GLSL, so that support check isn't valid.
- Store the shader selected mode into the shader itself. Different types
of shaders can be combined, so this is an improvement. In fact, storing
the mode into the settings globally is a mistake as well - it should be
done per device, since different cards have different capabilities.
2006-07-04 09:21:53 +02:00
TRACE_ ( d3d_caps ) ( " Hardware pixel shader version 3.0 enabled (GLSL) \n " ) ;
} else if ( wined3d_settings . ps_selected_mode = = SHADER_ARB ) {
2006-05-08 22:39:04 +02:00
* pCaps - > PixelShaderVersion = D3DPS_VERSION ( 1 , 4 ) ;
* pCaps - > PixelShader1xMaxValue = 1.0 ;
wined3d: Rework shader mode selection.
- currently half the shader selection code (GLSL vs ARB) is in
fillGLcaps. The parts that check for software shaders are in
GetDeviceCaps. That placement, will work, but is definitely not optimal.
FillGLcaps should detect support - it should not make decision as to
what's used, because that's not what the purpose of the function is.
GetDeviceCaps should report support as it has already been selected.
Instead, select shader mode in its own function, called in the
appropriate places.
- unifying pixel and vertex shaders into a single selection is a
mistake. A software vertex shader can be coupled with a hardware arb or
glsl pixel shader, or no shader at all. Split them back into two and add
a SHADER_NONE variant.
- drawprim is doing support checks for ARB_PROGRAM, and making shader
decisions based on that - that's wrong, support has already been
checked, and decided upon, and shaders can be implemented via software,
ARB_PROGRAm or GLSL, so that support check isn't valid.
- Store the shader selected mode into the shader itself. Different types
of shaders can be combined, so this is an improvement. In fact, storing
the mode into the settings globally is a mistake as well - it should be
done per device, since different cards have different capabilities.
2006-07-04 09:21:53 +02:00
TRACE_ ( d3d_caps ) ( " Hardware pixel shader version 1.4 enabled (ARB_PROGRAM) \n " ) ;
/* FIXME: Uncomment this when there is support for software Pixel Shader 3.0 and PS_SW is defined
} else if ( wined3d_settings . ps_selected_mode = SHADER_SW ) {
* pCaps - > PixelShaderVersion = D3DPS_VERSION ( 3 , 0 ) ;
2005-06-22 20:30:29 +02:00
* pCaps - > PixelShader1xMaxValue = 1.0 ;
wined3d: Rework shader mode selection.
- currently half the shader selection code (GLSL vs ARB) is in
fillGLcaps. The parts that check for software shaders are in
GetDeviceCaps. That placement, will work, but is definitely not optimal.
FillGLcaps should detect support - it should not make decision as to
what's used, because that's not what the purpose of the function is.
GetDeviceCaps should report support as it has already been selected.
Instead, select shader mode in its own function, called in the
appropriate places.
- unifying pixel and vertex shaders into a single selection is a
mistake. A software vertex shader can be coupled with a hardware arb or
glsl pixel shader, or no shader at all. Split them back into two and add
a SHADER_NONE variant.
- drawprim is doing support checks for ARB_PROGRAM, and making shader
decisions based on that - that's wrong, support has already been
checked, and decided upon, and shaders can be implemented via software,
ARB_PROGRAm or GLSL, so that support check isn't valid.
- Store the shader selected mode into the shader itself. Different types
of shaders can be combined, so this is an improvement. In fact, storing
the mode into the settings globally is a mistake as well - it should be
done per device, since different cards have different capabilities.
2006-07-04 09:21:53 +02:00
TRACE_ ( d3d_caps ) ( " Software pixel shader version 3.0 enabled \n " ) ; */
2004-10-06 02:05:29 +02:00
} else {
2005-07-13 16:15:54 +02:00
* pCaps - > PixelShaderVersion = 0 ;
2005-06-22 20:30:29 +02:00
* pCaps - > PixelShader1xMaxValue = 0.0 ;
2006-05-18 19:21:00 +02:00
TRACE_ ( d3d_caps ) ( " Pixel shader functionality not available \n " ) ;
2004-10-06 02:05:29 +02:00
}
/* ------------------------------------------------
The following fields apply to d3d9 only
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
if ( This - > dxVersion > 8 ) {
2005-07-13 16:15:54 +02:00
GLint max_buffers = 1 ;
2005-02-10 20:19:35 +01:00
FIXME ( " Caps support for directx9 is nonexistent at the moment! \n " ) ;
2005-06-22 20:30:29 +02:00
* pCaps - > DevCaps2 = 0 ;
/* TODO: D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES */
* pCaps - > MaxNpatchTessellationLevel = 0 ;
* pCaps - > MasterAdapterOrdinal = 0 ;
* pCaps - > AdapterOrdinalInGroup = 0 ;
* pCaps - > NumberOfAdaptersInGroup = 1 ;
* pCaps - > DeclTypes = 0 ;
#if 0 /*FIXME: Simultaneous render targets*/
GL_MAX_DRAW_BUFFERS_ATI 0x00008824
if ( GL_SUPPORT ( GL_MAX_DRAW_BUFFERS_ATI ) ) {
2005-07-13 16:15:54 +02:00
ENTER_GL ( ) ;
2005-06-22 20:30:29 +02:00
glEnable ( GL_MAX_DRAW_BUFFERS_ATI ) ;
glGetIntegerv ( GL_MAX_DRAW_BUFFERS_ATI , & max_buffers ) ;
glDisable ( GL_MAX_DRAW_BUFFERS_ATI ) ;
LEAVE_GL ( ) ;
}
# endif
* pCaps - > NumSimultaneousRTs = max_buffers ;
* pCaps - > StretchRectFilterCaps = 0 ;
* pCaps - > VS20Caps . Caps = 0 ;
* pCaps - > PS20Caps . Caps = 0 ;
* pCaps - > VertexTextureFilterCaps = 0 ;
* pCaps - > MaxVShaderInstructionsExecuted = 0 ;
* pCaps - > MaxPShaderInstructionsExecuted = 0 ;
* pCaps - > MaxVertexShader30InstructionSlots = 0 ;
* pCaps - > MaxPixelShader30InstructionSlots = 0 ;
2004-10-06 02:05:29 +02:00
}
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-10-06 02:05:29 +02:00
}
2005-06-22 20:30:29 +02:00
2004-10-07 06:22:21 +02:00
/* Note due to structure differences between dx8 and dx9 D3DPRESENT_PARAMETERS,
and fields being inserted in the middle , a new structure is used in place */
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DImpl_CreateDevice ( IWineD3D * iface , UINT Adapter , WINED3DDEVTYPE DeviceType , HWND hFocusWindow ,
2006-04-18 22:38:30 +02:00
DWORD BehaviourFlags , IWineD3DDevice * * ppReturnedDeviceInterface ,
IUnknown * parent ) {
2004-10-07 06:22:21 +02:00
2004-10-08 22:52:33 +02:00
IWineD3DDeviceImpl * object = NULL ;
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
2006-05-18 22:42:22 +02:00
HDC hDC ;
2006-07-19 06:06:07 +02:00
HRESULT temp_result ;
2004-10-08 22:52:33 +02:00
/* Validate the adapter number */
if ( Adapter > = IWineD3D_GetAdapterCount ( iface ) ) {
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2004-10-08 22:52:33 +02:00
}
2004-10-07 06:22:21 +02:00
/* Create a WineD3DDevice object */
2004-10-08 22:52:33 +02:00
object = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( IWineD3DDeviceImpl ) ) ;
* ppReturnedDeviceInterface = ( IWineD3DDevice * ) object ;
2005-11-10 13:14:56 +01:00
TRACE ( " Created WineD3DDevice object @ %p \n " , object ) ;
2004-10-08 22:52:33 +02:00
if ( NULL = = object ) {
2006-04-07 12:51:12 +02:00
return WINED3DERR_OUTOFVIDEOMEMORY ;
2004-10-08 22:52:33 +02:00
}
/* Set up initial COM information */
2004-10-07 06:22:21 +02:00
object - > lpVtbl = & IWineD3DDevice_Vtbl ;
object - > ref = 1 ;
2004-11-28 16:04:41 +01:00
object - > wineD3D = iface ;
IWineD3D_AddRef ( object - > wineD3D ) ;
2004-11-23 14:52:46 +01:00
object - > parent = parent ;
2005-07-13 16:15:54 +02:00
2005-09-21 12:55:03 +02:00
/* Set the state up as invalid until the device is fully created */
2006-04-07 12:51:12 +02:00
object - > state = WINED3DERR_DRIVERINTERNALERROR ;
2005-09-21 12:55:03 +02:00
2006-04-18 22:38:30 +02:00
TRACE ( " (%p)->(Adptr:%d, DevType: %x, FocusHwnd: %p, BehFlags: %lx, RetDevInt: %p) \n " , This , Adapter , DeviceType ,
hFocusWindow , BehaviourFlags , ppReturnedDeviceInterface ) ;
2004-10-08 22:52:33 +02:00
/* Save the creation parameters */
object - > createParms . AdapterOrdinal = Adapter ;
object - > createParms . DeviceType = DeviceType ;
object - > createParms . hFocusWindow = hFocusWindow ;
object - > createParms . BehaviorFlags = BehaviourFlags ;
/* Initialize other useful values */
object - > adapterNo = Adapter ;
object - > devType = DeviceType ;
2006-04-18 22:38:30 +02:00
TRACE ( " (%p) : Creating stateblock \n " , This ) ;
/* Creating the startup stateBlock - Note Special Case: 0 => Don't fill in yet! */
if ( WINED3D_OK ! = IWineD3DDevice_CreateStateBlock ( ( IWineD3DDevice * ) object ,
WINED3DSBT_INIT ,
( IWineD3DStateBlock * * ) & object - > stateBlock ,
NULL ) | | NULL = = object - > stateBlock ) { /* Note: No parent needed for initial internal stateblock */
WARN ( " Failed to create stateblock \n " ) ;
goto create_device_error ;
2004-10-08 22:52:33 +02:00
}
2006-04-18 22:38:30 +02:00
TRACE ( " (%p) : Created stateblock (%p) \n " , This , object - > stateBlock ) ;
object - > updateStateBlock = object - > stateBlock ;
IWineD3DStateBlock_AddRef ( ( IWineD3DStateBlock * ) object - > updateStateBlock ) ;
/* Setup surfaces for the backbuffer, frontbuffer and depthstencil buffer */
/* Setup some defaults for creating the implicit swapchain */
ENTER_GL ( ) ;
wined3d: Rework shader mode selection.
- currently half the shader selection code (GLSL vs ARB) is in
fillGLcaps. The parts that check for software shaders are in
GetDeviceCaps. That placement, will work, but is definitely not optimal.
FillGLcaps should detect support - it should not make decision as to
what's used, because that's not what the purpose of the function is.
GetDeviceCaps should report support as it has already been selected.
Instead, select shader mode in its own function, called in the
appropriate places.
- unifying pixel and vertex shaders into a single selection is a
mistake. A software vertex shader can be coupled with a hardware arb or
glsl pixel shader, or no shader at all. Split them back into two and add
a SHADER_NONE variant.
- drawprim is doing support checks for ARB_PROGRAM, and making shader
decisions based on that - that's wrong, support has already been
checked, and decided upon, and shaders can be implemented via software,
ARB_PROGRAm or GLSL, so that support check isn't valid.
- Store the shader selected mode into the shader itself. Different types
of shaders can be combined, so this is an improvement. In fact, storing
the mode into the settings globally is a mistake as well - it should be
done per device, since different cards have different capabilities.
2006-07-04 09:21:53 +02:00
/* FIXME: both of those should be made per adapter */
2006-07-19 23:49:37 +02:00
IWineD3DImpl_FillGLCaps ( iface , IWineD3DImpl_GetAdapterDisplay ( iface , Adapter ) ) ;
2006-04-18 22:38:30 +02:00
LEAVE_GL ( ) ;
wined3d: Rework shader mode selection.
- currently half the shader selection code (GLSL vs ARB) is in
fillGLcaps. The parts that check for software shaders are in
GetDeviceCaps. That placement, will work, but is definitely not optimal.
FillGLcaps should detect support - it should not make decision as to
what's used, because that's not what the purpose of the function is.
GetDeviceCaps should report support as it has already been selected.
Instead, select shader mode in its own function, called in the
appropriate places.
- unifying pixel and vertex shaders into a single selection is a
mistake. A software vertex shader can be coupled with a hardware arb or
glsl pixel shader, or no shader at all. Split them back into two and add
a SHADER_NONE variant.
- drawprim is doing support checks for ARB_PROGRAM, and making shader
decisions based on that - that's wrong, support has already been
checked, and decided upon, and shaders can be implemented via software,
ARB_PROGRAm or GLSL, so that support check isn't valid.
- Store the shader selected mode into the shader itself. Different types
of shaders can be combined, so this is an improvement. In fact, storing
the mode into the settings globally is a mistake as well - it should be
done per device, since different cards have different capabilities.
2006-07-04 09:21:53 +02:00
select_shader_mode ( & This - > gl_info , DeviceType ,
& wined3d_settings . ps_selected_mode , & wined3d_settings . vs_selected_mode ) ;
2006-07-23 21:08:27 +02:00
select_shader_max_constants ( & This - > gl_info ) ;
2004-10-08 22:52:33 +02:00
2006-07-19 06:06:07 +02:00
temp_result = allocate_shader_constants ( object - > updateStateBlock ) ;
if ( WINED3D_OK ! = temp_result )
return temp_result ;
2005-09-21 12:55:03 +02:00
/* set the state of the device to valid */
2006-04-07 12:51:12 +02:00
object - > state = WINED3D_OK ;
2005-09-21 12:55:03 +02:00
2006-05-18 22:42:22 +02:00
/* Get the initial screen setup for ddraw */
object - > ddraw_width = GetSystemMetrics ( SM_CXSCREEN ) ;
object - > ddraw_height = GetSystemMetrics ( SM_CYSCREEN ) ;
hDC = CreateDCA ( " DISPLAY " , NULL , NULL , NULL ) ;
object - > ddraw_format = pixelformat_for_depth ( GetDeviceCaps ( hDC , BITSPIXEL ) * GetDeviceCaps ( hDC , PLANES ) ) ;
DeleteDC ( hDC ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-07-26 20:49:30 +02:00
create_device_error :
2005-09-21 12:55:03 +02:00
/* Set the device state to error */
2006-04-07 12:51:12 +02:00
object - > state = WINED3DERR_DRIVERINTERNALERROR ;
2005-09-21 12:55:03 +02:00
2005-07-26 20:49:30 +02:00
if ( object - > updateStateBlock ! = NULL ) {
IWineD3DStateBlock_Release ( ( IWineD3DStateBlock * ) object - > updateStateBlock ) ;
object - > updateStateBlock = NULL ;
}
if ( object - > stateBlock ! = NULL ) {
IWineD3DStateBlock_Release ( ( IWineD3DStateBlock * ) object - > stateBlock ) ;
object - > stateBlock = NULL ;
}
if ( object - > renderTarget ! = NULL ) {
IWineD3DSurface_Release ( object - > renderTarget ) ;
object - > renderTarget = NULL ;
}
if ( object - > stencilBufferTarget ! = NULL ) {
IWineD3DSurface_Release ( object - > stencilBufferTarget ) ;
object - > stencilBufferTarget = NULL ;
}
if ( object - > stencilBufferTarget ! = NULL ) {
IWineD3DSurface_Release ( object - > stencilBufferTarget ) ;
object - > stencilBufferTarget = NULL ;
}
HeapFree ( GetProcessHeap ( ) , 0 , object ) ;
* ppReturnedDeviceInterface = NULL ;
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2005-07-26 20:49:30 +02:00
2004-10-07 06:22:21 +02:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DImpl_GetParent ( IWineD3D * iface , IUnknown * * pParent ) {
2004-11-23 14:52:46 +01:00
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
IUnknown_AddRef ( This - > parent ) ;
* pParent = This - > parent ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-11-23 14:52:46 +01:00
}
2004-09-29 23:26:47 +02:00
/**********************************************************
* IWineD3D VTbl follows
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-06-06 21:50:35 +02:00
const IWineD3DVtbl IWineD3D_Vtbl =
2004-09-23 06:34:27 +02:00
{
2005-07-13 16:15:54 +02:00
/* IUnknown */
2004-09-23 06:34:27 +02:00
IWineD3DImpl_QueryInterface ,
IWineD3DImpl_AddRef ,
IWineD3DImpl_Release ,
2005-07-13 16:15:54 +02:00
/* IWineD3D */
2004-11-23 14:52:46 +01:00
IWineD3DImpl_GetParent ,
2004-09-28 04:12:12 +02:00
IWineD3DImpl_GetAdapterCount ,
IWineD3DImpl_RegisterSoftwareDevice ,
IWineD3DImpl_GetAdapterMonitor ,
IWineD3DImpl_GetAdapterModeCount ,
IWineD3DImpl_EnumAdapterModes ,
2004-09-29 23:26:47 +02:00
IWineD3DImpl_GetAdapterDisplayMode ,
2004-10-05 04:14:06 +02:00
IWineD3DImpl_GetAdapterIdentifier ,
IWineD3DImpl_CheckDeviceMultiSampleType ,
IWineD3DImpl_CheckDepthStencilMatch ,
IWineD3DImpl_CheckDeviceType ,
2004-10-06 02:05:29 +02:00
IWineD3DImpl_CheckDeviceFormat ,
IWineD3DImpl_CheckDeviceFormatConversion ,
2004-10-07 06:22:21 +02:00
IWineD3DImpl_GetDeviceCaps ,
IWineD3DImpl_CreateDevice
2004-09-23 06:34:27 +02:00
} ;