wined3d: Simplify context_choose_pixel_format().
Simply rank the formats instead of doing multiple passes over the list.
This commit is contained in:
parent
0ba5f7dd98
commit
81ae0cea7c
|
@ -1124,33 +1124,9 @@ static int context_choose_pixel_format(const struct wined3d_device *device, HDC
|
||||||
BOOL auxBuffers, BOOL findCompatible)
|
BOOL auxBuffers, BOOL findCompatible)
|
||||||
{
|
{
|
||||||
int iPixelFormat=0;
|
int iPixelFormat=0;
|
||||||
unsigned int matchtry;
|
|
||||||
BYTE redBits, greenBits, blueBits, alphaBits, colorBits;
|
BYTE redBits, greenBits, blueBits, alphaBits, colorBits;
|
||||||
BYTE depthBits=0, stencilBits=0;
|
BYTE depthBits=0, stencilBits=0;
|
||||||
|
unsigned int current_value;
|
||||||
static const struct
|
|
||||||
{
|
|
||||||
BOOL require_aux;
|
|
||||||
BOOL exact_alpha;
|
|
||||||
BOOL exact_color;
|
|
||||||
}
|
|
||||||
matches[] =
|
|
||||||
{
|
|
||||||
/* First, try without alpha match buffers. MacOS supports aux buffers only
|
|
||||||
* on A8R8G8B8, and we prefer better offscreen rendering over an alpha match.
|
|
||||||
* Then try without aux buffers - this is the most common cause for not
|
|
||||||
* finding a pixel format. Also some drivers(the open source ones)
|
|
||||||
* only offer 32 bit ARB pixel formats. First try without an exact alpha
|
|
||||||
* match, then try without an exact alpha and color match.
|
|
||||||
*/
|
|
||||||
{ TRUE, TRUE, TRUE },
|
|
||||||
{ TRUE, FALSE, TRUE },
|
|
||||||
{ FALSE, TRUE, TRUE },
|
|
||||||
{ FALSE, FALSE, TRUE },
|
|
||||||
{ TRUE, FALSE, FALSE },
|
|
||||||
{ FALSE, FALSE, FALSE },
|
|
||||||
};
|
|
||||||
|
|
||||||
unsigned int cfg_count = device->adapter->cfg_count;
|
unsigned int cfg_count = device->adapter->cfg_count;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
@ -1167,84 +1143,56 @@ static int context_choose_pixel_format(const struct wined3d_device *device, HDC
|
||||||
|
|
||||||
getDepthStencilBits(ds_format, &depthBits, &stencilBits);
|
getDepthStencilBits(ds_format, &depthBits, &stencilBits);
|
||||||
|
|
||||||
for (matchtry = 0; matchtry < (sizeof(matches) / sizeof(*matches)) && !iPixelFormat; ++matchtry)
|
current_value = 0;
|
||||||
{
|
|
||||||
for (i = 0; i < cfg_count; ++i)
|
for (i = 0; i < cfg_count; ++i)
|
||||||
{
|
{
|
||||||
const struct wined3d_pixel_format *cfg = &device->adapter->cfgs[i];
|
const struct wined3d_pixel_format *cfg = &device->adapter->cfgs[i];
|
||||||
BOOL exactDepthMatch = TRUE;
|
unsigned int value;
|
||||||
|
|
||||||
/* For now only accept RGBA formats. Perhaps some day we will
|
/* For now only accept RGBA formats. Perhaps some day we will
|
||||||
* allow floating point formats for pbuffers. */
|
* allow floating point formats for pbuffers. */
|
||||||
if(cfg->iPixelType != WGL_TYPE_RGBA_ARB)
|
if (cfg->iPixelType != WGL_TYPE_RGBA_ARB)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* In window mode we need a window drawable format and double buffering. */
|
/* In window mode we need a window drawable format and double buffering. */
|
||||||
if(!(cfg->windowDrawable && cfg->doubleBuffer))
|
if (!(cfg->windowDrawable && cfg->doubleBuffer))
|
||||||
continue;
|
continue;
|
||||||
|
if (cfg->redSize < redBits)
|
||||||
/* We like to have aux buffers in backbuffer mode */
|
|
||||||
if(auxBuffers && !cfg->auxBuffers && matches[matchtry].require_aux)
|
|
||||||
continue;
|
continue;
|
||||||
|
if (cfg->greenSize < greenBits)
|
||||||
if(matches[matchtry].exact_color) {
|
|
||||||
if(cfg->redSize != redBits)
|
|
||||||
continue;
|
continue;
|
||||||
if(cfg->greenSize != greenBits)
|
if (cfg->blueSize < blueBits)
|
||||||
continue;
|
continue;
|
||||||
if(cfg->blueSize != blueBits)
|
if (cfg->alphaSize < alphaBits)
|
||||||
continue;
|
continue;
|
||||||
} else {
|
if (cfg->depthSize < depthBits)
|
||||||
if(cfg->redSize < redBits)
|
|
||||||
continue;
|
continue;
|
||||||
if(cfg->greenSize < greenBits)
|
if (stencilBits && cfg->stencilSize != stencilBits)
|
||||||
continue;
|
continue;
|
||||||
if(cfg->blueSize < blueBits)
|
/* Check multisampling support. */
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(matches[matchtry].exact_alpha) {
|
|
||||||
if(cfg->alphaSize != alphaBits)
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
if(cfg->alphaSize < alphaBits)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We try to locate a format which matches our requirements exactly. In case of
|
|
||||||
* depth it is no problem to emulate 16-bit using e.g. 24-bit, so accept that. */
|
|
||||||
if(cfg->depthSize < depthBits)
|
|
||||||
continue;
|
|
||||||
else if(cfg->depthSize > depthBits)
|
|
||||||
exactDepthMatch = FALSE;
|
|
||||||
|
|
||||||
/* In all cases make sure the number of stencil bits matches our requirements
|
|
||||||
* even when we don't need stencil because it could affect performance EXCEPT
|
|
||||||
* on cards which don't offer depth formats without stencil like the i915 drivers
|
|
||||||
* on Linux. */
|
|
||||||
if (stencilBits != cfg->stencilSize
|
|
||||||
&& !(device->adapter->brokenStencil && stencilBits <= cfg->stencilSize))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Check multisampling support */
|
|
||||||
if (cfg->numSamples)
|
if (cfg->numSamples)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* When we have passed all the checks then we have found a format which matches our
|
value = 1;
|
||||||
* requirements. Note that we only check for a limit number of capabilities right now,
|
/* We try to locate a format which matches our requirements exactly. In case of
|
||||||
* so there can easily be a dozen of pixel formats which appear to be the 'same' but
|
* depth it is no problem to emulate 16-bit using e.g. 24-bit, so accept that. */
|
||||||
* can still differ in things like multisampling, stereo, SRGB and other flags.
|
if (cfg->depthSize == depthBits)
|
||||||
*/
|
value += 1;
|
||||||
|
if (cfg->stencilSize == stencilBits)
|
||||||
|
value += 2;
|
||||||
|
if (cfg->alphaSize == alphaBits)
|
||||||
|
value += 4;
|
||||||
|
/* We like to have aux buffers in backbuffer mode */
|
||||||
|
if (auxBuffers && cfg->auxBuffers)
|
||||||
|
value += 8;
|
||||||
|
if (cfg->redSize == redBits
|
||||||
|
&& cfg->greenSize == greenBits
|
||||||
|
&& cfg->blueSize == blueBits)
|
||||||
|
value += 16;
|
||||||
|
|
||||||
/* Exit the loop as we have found a format :) */
|
if (value > current_value)
|
||||||
if(exactDepthMatch) {
|
{
|
||||||
iPixelFormat = cfg->iPixelFormat;
|
iPixelFormat = cfg->iPixelFormat;
|
||||||
break;
|
current_value = value;
|
||||||
} else if(!iPixelFormat) {
|
|
||||||
/* In the end we might end up with a format which doesn't exactly match our depth
|
|
||||||
* requirements. Accept the first format we found because formats with higher iPixelFormat
|
|
||||||
* values tend to have more extended capabilities (e.g. multisampling) which we don't need. */
|
|
||||||
iPixelFormat = cfg->iPixelFormat;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5260,7 +5260,6 @@ static BOOL InitAdapters(struct wined3d *wined3d)
|
||||||
struct wined3d_pixel_format *cfgs;
|
struct wined3d_pixel_format *cfgs;
|
||||||
int iPixelFormat;
|
int iPixelFormat;
|
||||||
int res;
|
int res;
|
||||||
int i;
|
|
||||||
DISPLAY_DEVICEW DisplayDevice;
|
DISPLAY_DEVICEW DisplayDevice;
|
||||||
HDC hdc;
|
HDC hdc;
|
||||||
|
|
||||||
|
@ -5439,25 +5438,6 @@ static BOOL InitAdapters(struct wined3d *wined3d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* D16, D24X8 and D24S8 are common depth / depth+stencil formats. All drivers support them though this doesn't
|
|
||||||
* mean that the format is offered in hardware. For instance Geforce8 cards don't have offer D16 in hardware
|
|
||||||
* but just fake it using D24(X8?) which is fine. D3D also allows that.
|
|
||||||
* Some display drivers (i915 on Linux) only report mixed depth+stencil formats like D24S8. MSDN clearly mentions
|
|
||||||
* that only on lockable formats (e.g. D16_locked) the bit order is guaranteed and that on other formats the
|
|
||||||
* driver is allowed to consume more bits EXCEPT for stencil bits.
|
|
||||||
*
|
|
||||||
* Mark an adapter with this broken stencil behavior.
|
|
||||||
*/
|
|
||||||
adapter->brokenStencil = TRUE;
|
|
||||||
for (i = 0, cfgs = adapter->cfgs; i < adapter->cfg_count; ++i)
|
|
||||||
{
|
|
||||||
/* Nearly all drivers offer depth formats without stencil, only on i915 this if-statement won't be entered. */
|
|
||||||
if(cfgs[i].depthSize && !cfgs[i].stencilSize) {
|
|
||||||
adapter->brokenStencil = FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
|
WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
|
||||||
|
|
||||||
select_shader_mode(&adapter->gl_info, &ps_selected_mode, &vs_selected_mode);
|
select_shader_mode(&adapter->gl_info, &ps_selected_mode, &vs_selected_mode);
|
||||||
|
|
|
@ -1527,7 +1527,6 @@ struct wined3d_adapter
|
||||||
WCHAR DeviceName[CCHDEVICENAME]; /* DeviceName for use with e.g. ChangeDisplaySettings */
|
WCHAR DeviceName[CCHDEVICENAME]; /* DeviceName for use with e.g. ChangeDisplaySettings */
|
||||||
unsigned int cfg_count;
|
unsigned int cfg_count;
|
||||||
struct wined3d_pixel_format *cfgs;
|
struct wined3d_pixel_format *cfgs;
|
||||||
BOOL brokenStencil; /* Set on cards which only offer mixed depth+stencil */
|
|
||||||
unsigned int TextureRam; /* Amount of texture memory both video ram + AGP/TurboCache/HyperMemory/.. */
|
unsigned int TextureRam; /* Amount of texture memory both video ram + AGP/TurboCache/HyperMemory/.. */
|
||||||
unsigned int UsedTextureRam;
|
unsigned int UsedTextureRam;
|
||||||
LUID luid;
|
LUID luid;
|
||||||
|
|
Loading…
Reference in New Issue