[PATCH] Add D3D8/9 multisampling support. It works fine in D3D sdk samples.
Roderick Colenbrander
thunderbird2k at gmx.net
Mon Apr 28 16:44:21 CDT 2008
---
dlls/wined3d/context.c | 29 +++++++++----
dlls/wined3d/directx.c | 86 ++++++++++++++++++++++++++++++++++-----
dlls/wined3d/wined3d_private.h | 1 +
3 files changed, 96 insertions(+), 20 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index d80ef06..c91153c 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -111,7 +111,7 @@ static WineD3DContext *AddContextToArray(IWineD3DDeviceImpl *This, HWND win_hand
}
/* This function takes care of WineD3D pixel format selection. */
-static int WineD3D_ChoosePixelFormat(IWineD3DDeviceImpl *This, HDC hdc, WINED3DFORMAT ColorFormat, WINED3DFORMAT DepthStencilFormat, BOOL auxBuffers, BOOL pbuffer, BOOL findCompatible)
+static int WineD3D_ChoosePixelFormat(IWineD3DDeviceImpl *This, HDC hdc, WINED3DFORMAT ColorFormat, WINED3DFORMAT DepthStencilFormat, BOOL auxBuffers, int numSamples, BOOL pbuffer, BOOL findCompatible)
{
int iPixelFormat=0;
short redBits, greenBits, blueBits, alphaBits, colorBits;
@@ -173,6 +173,10 @@ static int WineD3D_ChoosePixelFormat(IWineD3DDeviceImpl *This, HDC hdc, WINED3DF
if(!(cfgs->stencilSize == stencilBits))
continue;
+ /* Check multisampling support */
+ if(cfgs->numSamples != 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
@@ -245,8 +249,6 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
TRACE("(%p): Creating a %s context for render target %p\n", This, create_pbuffer ? "offscreen" : "onscreen", target);
-#define PUSH1(att) attribs[nAttribs++] = (att);
-#define PUSH2(att,value) attribs[nAttribs++] = (att); attribs[nAttribs++] = (value);
if(create_pbuffer) {
HDC hdc_parent = GetDC(win_handle);
int iPixelFormat = 0;
@@ -255,13 +257,13 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
WINED3DFORMAT StencilBufferFormat = (NULL != StencilSurface) ? ((IWineD3DSurfaceImpl *) StencilSurface)->resource.format : 0;
/* Try to find a pixel format with pbuffer support. */
- iPixelFormat = WineD3D_ChoosePixelFormat(This, hdc_parent, target->resource.format, StencilBufferFormat, FALSE /* auxBuffers */, TRUE /* PBUFFER */, FALSE /* findCompatible */);
+ iPixelFormat = WineD3D_ChoosePixelFormat(This, hdc_parent, target->resource.format, StencilBufferFormat, FALSE /* auxBuffers */, 0 /* numSamples */, TRUE /* PBUFFER */, FALSE /* findCompatible */);
if(!iPixelFormat) {
TRACE("Trying to locate a compatible pixel format because an exact match failed.\n");
/* For some reason we weren't able to find a format, try to find something instead of crashing.
* A reason for failure could have been wglChoosePixelFormatARB strictness. */
- iPixelFormat = WineD3D_ChoosePixelFormat(This, hdc_parent, target->resource.format, StencilBufferFormat, FALSE /* auxBuffer */, TRUE /* PBUFFER */, TRUE /* findCompatible */);
+ iPixelFormat = WineD3D_ChoosePixelFormat(This, hdc_parent, target->resource.format, StencilBufferFormat, FALSE /* auxBuffer */, 0 /* numSamples */, TRUE /* PBUFFER */, TRUE /* findCompatible */);
}
/* This shouldn't happen as ChoosePixelFormat always returns something */
@@ -295,6 +297,7 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
WINED3DFORMAT ColorFormat = target->resource.format;
WINED3DFORMAT DepthStencilFormat = 0;
BOOL auxBuffers = FALSE;
+ int numSamples = 0;
hdc = GetDC(win_handle);
if(hdc == NULL) {
@@ -327,13 +330,23 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
DepthStencilFormat = pPresentParms->AutoDepthStencilFormat;
}
+ /* D3D only allows multisampling when SwapEffect is set to WINED3DSWAPEFFECT_DISCARD */
+ if(pPresentParms->MultiSampleType && (pPresentParms->SwapEffect == WINED3DSWAPEFFECT_DISCARD)) {
+ if(!GL_SUPPORT(ARB_MULTISAMPLE))
+ ERR("The program is requesting multisampling without support!\n");
+ else {
+ ERR("Requesting MultiSampleType=%d\n", pPresentParms->MultiSampleType);
+ numSamples = pPresentParms->MultiSampleType;
+ }
+ }
+
/* Try to find a pixel format which matches our requirements */
- iPixelFormat = WineD3D_ChoosePixelFormat(This, hdc, ColorFormat, DepthStencilFormat, auxBuffers, FALSE /* PBUFFER */, FALSE /* findCompatible */);
+ iPixelFormat = WineD3D_ChoosePixelFormat(This, hdc, ColorFormat, DepthStencilFormat, auxBuffers, numSamples, FALSE /* PBUFFER */, FALSE /* findCompatible */);
/* Try to locate a compatible format if we weren't able to find anything */
if(!iPixelFormat) {
TRACE("Trying to locate a compatible pixel format because an exact match failed.\n");
- iPixelFormat = WineD3D_ChoosePixelFormat(This, hdc, ColorFormat, DepthStencilFormat, auxBuffers, FALSE /* PBUFFER */, TRUE /* findCompatible */ );
+ iPixelFormat = WineD3D_ChoosePixelFormat(This, hdc, ColorFormat, DepthStencilFormat, auxBuffers, 0 /* numSamples */, FALSE /* PBUFFER */, TRUE /* findCompatible */ );
}
/* If we still don't have a pixel format, something is very wrong as ChoosePixelFormat barely fails */
@@ -370,8 +383,6 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
}
}
}
-#undef PUSH1
-#undef PUSH2
ctx = pwglCreateContext(hdc);
if(This->numContexts) pwglShareLists(This->contexts[0]->glCtx, ctx);
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 29f451c..5d770b1 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -1753,7 +1753,10 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceMultiSampleType(IWineD3D *iface, U
BOOL Windowed, WINED3DMULTISAMPLE_TYPE MultiSampleType, DWORD* pQualityLevels) {
IWineD3DImpl *This = (IWineD3DImpl *)iface;
- TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), SurfFmt:(%x,%s), Win?%d, MultiSamp:%x, pQual:%p)\n",
+ const GlPixelFormatDesc *glDesc;
+ const StaticPixelFormatDesc *desc;
+
+ TRACE_(d3d_caps)("(%p)-> (Adptr:%d, DevType:(%x,%s), SurfFmt:(%x,%s), Win?%d, MultiSamp:%x, pQual:%p)\n",
This,
Adapter,
DeviceType, debug_d3ddevicetype(DeviceType),
@@ -1766,17 +1769,66 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceMultiSampleType(IWineD3D *iface, U
return WINED3DERR_INVALIDCALL;
}
- /* TODO: Store in Adapter structure */
- if (pQualityLevels != NULL) {
- static int s_single_shot = 0;
- if (!s_single_shot) {
- FIXME("Quality levels unsupported at present\n");
- s_single_shot = 1;
+ /* TODO: handle Windowed, add more quality levels */
+
+ if (WINED3DMULTISAMPLE_NONE == MultiSampleType) return WINED3D_OK;
+
+ desc = getFormatDescEntry(SurfaceFormat, &Adapters[Adapter].gl_info, &glDesc);
+ if(!desc || !glDesc) {
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if(glDesc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) {
+ int i, nCfgs;
+ WineD3D_PixelFormat *cfgs;
+
+ cfgs = Adapters[Adapter].cfgs;
+ nCfgs = Adapters[Adapter].nCfgs;
+ for(i=0; i<nCfgs; i++) {
+ if(cfgs[i].numSamples != MultiSampleType)
+ continue;
+
+ if(!IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&cfgs[i], SurfaceFormat))
+ continue;
+
+ TRACE("Found iPixelFormat=%d to support MultiSampleType=%d for format %s\n", cfgs[i].iPixelFormat, MultiSampleType, debug_d3dformat(SurfaceFormat));
+
+ if(pQualityLevels)
+ *pQualityLevels = 1; /* Guess at a value! */
+ return WINED3D_OK;
}
- *pQualityLevels = 1; /* Guess at a value! */
}
+ else if(glDesc->Flags & WINED3DFMT_FLAG_RENDERTARGET) {
+ short redSize, greenSize, blueSize, alphaSize, colorBits;
+ int i, nCfgs;
+ WineD3D_PixelFormat *cfgs;
- if (WINED3DMULTISAMPLE_NONE == MultiSampleType) return WINED3D_OK;
+ if(!getColorBits(SurfaceFormat, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits)) {
+ ERR("Unable to color bits for format %#x, can't check multisampling capability!\n", SurfaceFormat);
+ return WINED3DERR_NOTAVAILABLE;
+ }
+
+ cfgs = Adapters[Adapter].cfgs;
+ nCfgs = Adapters[Adapter].nCfgs;
+ for(i=0; i<nCfgs; i++) {
+ if(cfgs[i].numSamples != MultiSampleType)
+ continue;
+ if(cfgs[i].redSize != redSize)
+ continue;
+ if(cfgs[i].greenSize != greenSize)
+ continue;
+ if(cfgs[i].blueSize != blueSize)
+ continue;
+ if(cfgs[i].alphaSize != alphaSize)
+ continue;
+
+ TRACE("Found iPixelFormat=%d to support MultiSampleType=%d for format %s\n", cfgs[i].iPixelFormat, MultiSampleType, debug_d3dformat(SurfaceFormat));
+
+ if(pQualityLevels)
+ *pQualityLevels = 1; /* Guess at a value! */
+ return WINED3D_OK;
+ }
+ }
return WINED3DERR_NOTAVAILABLE;
}
@@ -3876,8 +3928,7 @@ BOOL InitAdapters(void) {
cfgs->auxBuffers = values[9];
cfgs->pbufferDrawable = FALSE;
- /* Check for pbuffer support when it is around as wglGetPixelFormatAttribiv fails for unknown
-attributes. */
+ /* Check for pbuffer support when it is around as wglGetPixelFormatAttribiv fails for unknown attributes. */
if(GL_SUPPORT(WGL_ARB_PBUFFER)) {
int attrib = WGL_DRAW_TO_PBUFFER_ARB;
int value;
@@ -3885,6 +3936,19 @@ attributes. */
cfgs->pbufferDrawable = value;
}
+ cfgs->numSamples = 0;
+ /* Check multisample support */
+ if(GL_SUPPORT(ARB_MULTISAMPLE)) {
+ int attrib[2] = {WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB};
+ int value[2];
+ if(GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, 2, attrib, value))) {
+ /* value[0] = WGL_SAMPLE_BUFFERS_ARB which tells whether multisampling is supported.
+ * value[1] = number of multi sample buffers*/
+ if(value[0])
+ cfgs->numSamples = value[1];
+ }
+ }
+
TRACE("iPixelFormat=%d, iPixelType=%#x, RGBA=%d/%d/%d/%d, doubleBuffer=%d, depth=%d, stencil=%d, windowDrawable=%d, pbufferDrawable=%d\n", cfgs->iPixelFormat, cfgs->iPixelType, cfgs->doubleBuffer, cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize, cfgs->depthSize, cfgs->stencilSize, cfgs->windowDrawable, cfgs->pbufferDrawable);
cfgs++;
}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 73570fa..17a8fb0 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -686,6 +686,7 @@ typedef struct WineD3D_PixelFormat
BOOL pbufferDrawable;
BOOL doubleBuffer;
int auxBuffers;
+ int numSamples;
} WineD3D_PixelFormat;
/* The adapter structure */
--
1.5.3.4
--========GMX187151209411891758870--
More information about the wine-patches
mailing list