[PATCH 3/5] wined3d: Simplify context_choose_pixel_format().
Henri Verbeet
hverbeet at codeweavers.com
Tue Nov 8 13:48:57 CST 2011
Simply rank the formats instead of doing multiple passes over the list.
---
dlls/wined3d/context.c | 150 +++++++++++++---------------------------
dlls/wined3d/directx.c | 20 -----
dlls/wined3d/wined3d_private.h | 1 -
3 files changed, 49 insertions(+), 122 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 31a604c..355dccf 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -1124,33 +1124,9 @@ static int context_choose_pixel_format(const struct wined3d_device *device, HDC
BOOL auxBuffers, BOOL findCompatible)
{
int iPixelFormat=0;
- unsigned int matchtry;
BYTE redBits, greenBits, blueBits, alphaBits, colorBits;
BYTE depthBits=0, stencilBits=0;
-
- 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 current_value;
unsigned int cfg_count = device->adapter->cfg_count;
unsigned int i;
@@ -1167,84 +1143,56 @@ static int context_choose_pixel_format(const struct wined3d_device *device, HDC
getDepthStencilBits(ds_format, &depthBits, &stencilBits);
- for (matchtry = 0; matchtry < (sizeof(matches) / sizeof(*matches)) && !iPixelFormat; ++matchtry)
- {
- for (i = 0; i < cfg_count; ++i)
- {
- const struct wined3d_pixel_format *cfg = &device->adapter->cfgs[i];
- BOOL exactDepthMatch = TRUE;
-
- /* For now only accept RGBA formats. Perhaps some day we will
- * allow floating point formats for pbuffers. */
- if(cfg->iPixelType != WGL_TYPE_RGBA_ARB)
- continue;
-
- /* In window mode we need a window drawable format and double buffering. */
- if(!(cfg->windowDrawable && cfg->doubleBuffer))
- continue;
-
- /* We like to have aux buffers in backbuffer mode */
- if(auxBuffers && !cfg->auxBuffers && matches[matchtry].require_aux)
- continue;
-
- if(matches[matchtry].exact_color) {
- if(cfg->redSize != redBits)
- continue;
- if(cfg->greenSize != greenBits)
- continue;
- if(cfg->blueSize != blueBits)
- continue;
- } else {
- if(cfg->redSize < redBits)
- continue;
- if(cfg->greenSize < greenBits)
- continue;
- if(cfg->blueSize < blueBits)
- 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)
- continue;
-
- /* When we have passed all the checks then we have found a format which matches our
- * requirements. Note that we only check for a limit number of capabilities right now,
- * so there can easily be a dozen of pixel formats which appear to be the 'same' but
- * can still differ in things like multisampling, stereo, SRGB and other flags.
- */
-
- /* Exit the loop as we have found a format :) */
- if(exactDepthMatch) {
- iPixelFormat = cfg->iPixelFormat;
- break;
- } 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;
- }
+ current_value = 0;
+ for (i = 0; i < cfg_count; ++i)
+ {
+ const struct wined3d_pixel_format *cfg = &device->adapter->cfgs[i];
+ unsigned int value;
+
+ /* For now only accept RGBA formats. Perhaps some day we will
+ * allow floating point formats for pbuffers. */
+ if (cfg->iPixelType != WGL_TYPE_RGBA_ARB)
+ continue;
+ /* In window mode we need a window drawable format and double buffering. */
+ if (!(cfg->windowDrawable && cfg->doubleBuffer))
+ continue;
+ if (cfg->redSize < redBits)
+ continue;
+ if (cfg->greenSize < greenBits)
+ continue;
+ if (cfg->blueSize < blueBits)
+ continue;
+ if (cfg->alphaSize < alphaBits)
+ continue;
+ if (cfg->depthSize < depthBits)
+ continue;
+ if (stencilBits && cfg->stencilSize != stencilBits)
+ continue;
+ /* Check multisampling support. */
+ if (cfg->numSamples)
+ continue;
+
+ value = 1;
+ /* 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)
+ 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;
+
+ if (value > current_value)
+ {
+ iPixelFormat = cfg->iPixelFormat;
+ current_value = value;
}
}
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 44fd88d..ad79276 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -5260,7 +5260,6 @@ static BOOL InitAdapters(struct wined3d *wined3d)
struct wined3d_pixel_format *cfgs;
int iPixelFormat;
int res;
- int i;
DISPLAY_DEVICEW DisplayDevice;
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);
select_shader_mode(&adapter->gl_info, &ps_selected_mode, &vs_selected_mode);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 48a302a..ef09e26 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1527,7 +1527,6 @@ struct wined3d_adapter
WCHAR DeviceName[CCHDEVICENAME]; /* DeviceName for use with e.g. ChangeDisplaySettings */
unsigned int cfg_count;
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 UsedTextureRam;
LUID luid;
--
1.7.3.4
More information about the wine-patches
mailing list