diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index d80ef0660f1..c91153c41ae 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 29f451ceabe..74d409d6e94 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; - } - *pQualityLevels = 1; /* Guess at a value! */ - } + /* 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; iFlags & WINED3DFMT_FLAG_RENDERTARGET) { + short redSize, greenSize, blueSize, alphaSize, colorBits; + int i, nCfgs; + WineD3D_PixelFormat *cfgs; + + 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; iauxBuffers = 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 73570fa0a25..17a8fb09b33 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 */ diff --git a/include/wine/wined3d_gl.h b/include/wine/wined3d_gl.h index 2467a73d2f7..9bd5a44743b 100644 --- a/include/wine/wined3d_gl.h +++ b/include/wine/wined3d_gl.h @@ -3682,6 +3682,11 @@ typedef enum _GL_SupportedExt { /* WGL_ARB_extensions_string */ typedef const char * (WINAPI * WINED3D_PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); +/* WGL_ARB_multisample */ +#ifndef WGL_ARB_multisample +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 +#endif /* WGL_ARB_pixel_format */ #ifndef WGL_ARB_pixel_format #define WGL_ARB_pixel_format 1