wined3d: Add multisampling support.
This commit is contained in:
parent
727eef4e4f
commit
628e4eece3
|
@ -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);
|
||||
|
|
|
@ -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; 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;
|
||||
}
|
||||
}
|
||||
else if(glDesc->Flags & 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; 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++;
|
||||
}
|
||||
|
|
|
@ -686,6 +686,7 @@ typedef struct WineD3D_PixelFormat
|
|||
BOOL pbufferDrawable;
|
||||
BOOL doubleBuffer;
|
||||
int auxBuffers;
|
||||
int numSamples;
|
||||
} WineD3D_PixelFormat;
|
||||
|
||||
/* The adapter structure */
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue