Commit f289ee8d by apatrick@chromium.org

Allocate D3D queries from a pool for the Display.

This is a workaround for an Intel bug. The crash looks like this: 0x5f816c53 [d3d9.dll + 0x00036c53] CQuery::~CQuery() 0x5f816bec [d3d9.dll + 0x00036bec] CQuery::`vector deleting destructor'(unsigned int) 0x5f7e8129 [d3d9.dll + 0x00008129] CBaseObject::~CBaseObject() 0x5f9e19c7 [libglesv2.dll + 0x000319c7] gl::Fence::`vector deleting destructor'(unsigned int) 0x5f9de78e [libglesv2.dll - context.cpp:975] gl::Context::deleteFence(unsigned int) 0x5f9e1491 [libglesv2.dll - context.cpp:198] gl::Context::~Context() 0x5f9e182f [libglesv2.dll - context.cpp:3936] glDestroyContext 0x717654ec [libegl.dll - display.cpp:749] egl::Display::destroyContext(gl::Context *) 0x7176a3da [libegl.dll - libegl.cpp:907] eglDestroyContext 0x64fbaf33 [chrome.dll - gl_context_egl.cc:75] gfx::GLContextEGL::Destroy() The vendor ID is always 8086 (Intel). Not an XP issue - it's happening on Win 7. With this change, D3D queries are only released when the display is destroyed or reset or if a very high number of D3D queries have been allocated. Tested by stepping exercising the NV_fence entry points in a debugger. Review URL: http://codereview.appspot.com/5534065 git-svn-id: https://angleproject.googlecode.com/svn/trunk@941 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent a5ddde91
...@@ -33,6 +33,13 @@ ...@@ -33,6 +33,13 @@
PFNEGLPOSTSUBBUFFERNVPROC eglPostSubBufferNV; PFNEGLPOSTSUBBUFFERNVPROC eglPostSubBufferNV;
PFNGLDELETEFENCESNVPROC glDeleteFencesNV;
PFNGLGENFENCESNVPROC glGenFencesNV;
PFNGLGETFENCEIVNVPROC glGetFenceivNV;
PFNGLISFENCENVPROC glIsFenceNV;
PFNGLFINISHFENCENVPROC glFinishFenceNV;
PFNGLSETFENCENVPROC glSetFenceNV;
PFNGLTESTFENCENVPROC glTestFenceNV;
/// ///
// CreateEGLContext() // CreateEGLContext()
...@@ -68,6 +75,14 @@ EGLBoolean CreateEGLContext ( EGLNativeWindowType hWnd, EGLDisplay* eglDisplay, ...@@ -68,6 +75,14 @@ EGLBoolean CreateEGLContext ( EGLNativeWindowType hWnd, EGLDisplay* eglDisplay,
// Bind to extensions // Bind to extensions
eglPostSubBufferNV = (PFNEGLPOSTSUBBUFFERNVPROC) eglGetProcAddress("eglPostSubBufferNV"); eglPostSubBufferNV = (PFNEGLPOSTSUBBUFFERNVPROC) eglGetProcAddress("eglPostSubBufferNV");
glDeleteFencesNV = (PFNGLDELETEFENCESNVPROC) eglGetProcAddress("glDeleteFencesNV");
glGenFencesNV = (PFNGLGENFENCESNVPROC) eglGetProcAddress("glGenFencesNV");
glGetFenceivNV = (PFNGLGETFENCEIVNVPROC) eglGetProcAddress("glGetFenceivNV");
glIsFenceNV = (PFNGLISFENCENVPROC) eglGetProcAddress("glIsFenceNV");
glFinishFenceNV = (PFNGLFINISHFENCENVPROC) eglGetProcAddress("glFinishFenceNV");
glSetFenceNV = (PFNGLSETFENCENVPROC) eglGetProcAddress("glSetFenceNV");
glTestFenceNV = (PFNGLTESTFENCENVPROC) eglGetProcAddress("glTestFenceNV");
// Get configs // Get configs
if ( !eglGetConfigs(display, NULL, 0, &numConfigs) ) if ( !eglGetConfigs(display, NULL, 0, &numConfigs) )
{ {
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
// Includes // Includes
// //
#include <GLES2/gl2.h> #include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <EGL/egl.h> #include <EGL/egl.h>
#include <EGL/eglext.h> #include <EGL/eglext.h>
...@@ -95,6 +96,13 @@ typedef struct ...@@ -95,6 +96,13 @@ typedef struct
extern PFNEGLPOSTSUBBUFFERNVPROC eglPostSubBufferNV; extern PFNEGLPOSTSUBBUFFERNVPROC eglPostSubBufferNV;
extern PFNGLDELETEFENCESNVPROC glDeleteFencesNV;
extern PFNGLGENFENCESNVPROC glGenFencesNV;
extern PFNGLGETFENCEIVNVPROC glGetFenceivNV;
extern PFNGLISFENCENVPROC glIsFenceNV;
extern PFNGLFINISHFENCENVPROC glFinishFenceNV;
extern PFNGLSETFENCENVPROC glSetFenceNV;
extern PFNGLTESTFENCENVPROC glTestFenceNV;
/// ///
// Public Functions // Public Functions
......
#define MAJOR_VERSION 1 #define MAJOR_VERSION 1
#define MINOR_VERSION 0 #define MINOR_VERSION 0
#define BUILD_VERSION 0 #define BUILD_VERSION 0
#define BUILD_REVISION 940 #define BUILD_REVISION 941
#define STRINGIFY(x) #x #define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x) #define MACRO_STRINGIFY(x) STRINGIFY(x)
......
...@@ -76,7 +76,6 @@ Display::Display(EGLNativeDisplayType displayId, HDC deviceContext, bool softwar ...@@ -76,7 +76,6 @@ Display::Display(EGLNativeDisplayType displayId, HDC deviceContext, bool softwar
mDevice = NULL; mDevice = NULL;
mDeviceEx = NULL; mDeviceEx = NULL;
mDeviceWindow = NULL; mDeviceWindow = NULL;
mEventQuery = NULL;
mAdapter = D3DADAPTER_DEFAULT; mAdapter = D3DADAPTER_DEFAULT;
...@@ -304,10 +303,10 @@ void Display::terminate() ...@@ -304,10 +303,10 @@ void Display::terminate()
destroyContext(*mContextSet.begin()); destroyContext(*mContextSet.begin());
} }
if (mEventQuery) while (!mEventQueryPool.empty())
{ {
mEventQuery->Release(); mEventQueryPool.back()->Release();
mEventQuery = NULL; mEventQueryPool.pop_back();
} }
if (mDevice) if (mDevice)
...@@ -469,12 +468,6 @@ void Display::initializeDevice() ...@@ -469,12 +468,6 @@ void Display::initializeDevice()
mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE); mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
mDevice->SetRenderState(D3DRS_LASTPIXEL, FALSE); mDevice->SetRenderState(D3DRS_LASTPIXEL, FALSE);
// Leave mEventQuery null if CreateQuery fails. This will prevent sync from
// working correctly but otherwise mEventQuery is expected to be null when
// queries are not supported.
ASSERT(!mEventQuery);
mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &mEventQuery);
mSceneStarted = false; mSceneStarted = false;
} }
...@@ -737,10 +730,10 @@ bool Display::restoreLostDevice() ...@@ -737,10 +730,10 @@ bool Display::restoreLostDevice()
(*surface)->release(); (*surface)->release();
} }
if (mEventQuery) while (!mEventQueryPool.empty())
{ {
mEventQuery->Release(); mEventQueryPool.back()->Release();
mEventQuery = NULL; mEventQueryPool.pop_back();
} }
if (!resetDevice()) if (!resetDevice())
...@@ -892,17 +885,18 @@ void Display::sync(bool block) ...@@ -892,17 +885,18 @@ void Display::sync(bool block)
{ {
HRESULT result; HRESULT result;
if (!mEventQuery) IDirect3DQuery9* query = allocateEventQuery();
if (!query)
{ {
return; return;
} }
result = mEventQuery->Issue(D3DISSUE_END); result = query->Issue(D3DISSUE_END);
ASSERT(SUCCEEDED(result)); ASSERT(SUCCEEDED(result));
do do
{ {
result = mEventQuery->GetData(NULL, 0, D3DGETDATA_FLUSH); result = query->GetData(NULL, 0, D3DGETDATA_FLUSH);
if(block && result == S_FALSE) if(block && result == S_FALSE)
{ {
...@@ -919,9 +913,41 @@ void Display::sync(bool block) ...@@ -919,9 +913,41 @@ void Display::sync(bool block)
} }
while(block && result == S_FALSE); while(block && result == S_FALSE);
if (isDeviceLostError(result)) freeEventQuery(query);
if (isDeviceLostError(result))
{
notifyDeviceLost();
}
}
IDirect3DQuery9* Display::allocateEventQuery()
{
IDirect3DQuery9 *query = NULL;
if (mEventQueryPool.empty())
{
HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &query);
ASSERT(SUCCEEDED(result));
}
else
{
query = mEventQueryPool.back();
mEventQueryPool.pop_back();
}
return query;
}
void Display::freeEventQuery(IDirect3DQuery9* query)
{
if (mEventQueryPool.size() > 1000)
{
query->Release();
}
else
{ {
notifyDeviceLost(); mEventQueryPool.push_back(query);
} }
} }
...@@ -1068,14 +1094,16 @@ D3DPOOL Display::getTexturePool(bool renderable) const ...@@ -1068,14 +1094,16 @@ D3DPOOL Display::getTexturePool(bool renderable) const
bool Display::getEventQuerySupport() bool Display::getEventQuerySupport()
{ {
IDirect3DQuery9 *query; IDirect3DQuery9 *query = allocateEventQuery();
HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &query); if (query)
if (SUCCEEDED(result))
{ {
query->Release(); freeEventQuery(query);
return true;
}
else
{
return false;
} }
return result != D3DERR_NOTAVAILABLE;
} }
D3DPRESENT_PARAMETERS Display::getDefaultPresentParameters() D3DPRESENT_PARAMETERS Display::getDefaultPresentParameters()
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <d3d9.h> #include <d3d9.h>
#include <set> #include <set>
#include <vector>
#include "libGLESv2/Context.h" #include "libGLESv2/Context.h"
...@@ -64,6 +65,8 @@ class Display ...@@ -64,6 +65,8 @@ class Display
virtual bool testDeviceLost(); virtual bool testDeviceLost();
virtual bool testDeviceResettable(); virtual bool testDeviceResettable();
virtual void sync(bool block); virtual void sync(bool block);
virtual IDirect3DQuery9* allocateEventQuery();
virtual void freeEventQuery(IDirect3DQuery9* query);
virtual void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray); virtual void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray);
virtual bool getDXT1TextureSupport(); virtual bool getDXT1TextureSupport();
virtual bool getDXT3TextureSupport(); virtual bool getDXT3TextureSupport();
...@@ -104,7 +107,9 @@ class Display ...@@ -104,7 +107,9 @@ class Display
IDirect3D9Ex *mD3d9Ex; // Might be null if D3D9Ex is not supported. IDirect3D9Ex *mD3d9Ex; // Might be null if D3D9Ex is not supported.
IDirect3DDevice9 *mDevice; IDirect3DDevice9 *mDevice;
IDirect3DDevice9Ex *mDeviceEx; // Might be null if D3D9Ex is not supported. IDirect3DDevice9Ex *mDeviceEx; // Might be null if D3D9Ex is not supported.
IDirect3DQuery9 *mEventQuery;
// A pool of event queries that are currently unused.
std::vector<IDirect3DQuery9*> mEventQueryPool;
D3DCAPS9 mDeviceCaps; D3DCAPS9 mDeviceCaps;
D3DADAPTER_IDENTIFIER9 mAdapterIdentifier; D3DADAPTER_IDENTIFIER9 mAdapterIdentifier;
......
...@@ -24,8 +24,7 @@ Fence::~Fence() ...@@ -24,8 +24,7 @@ Fence::~Fence()
{ {
if (mQuery != NULL) if (mQuery != NULL)
{ {
mQuery->Release(); getDisplay()->freeEventQuery(mQuery);
mQuery = NULL;
} }
} }
...@@ -38,15 +37,13 @@ GLboolean Fence::isFence() ...@@ -38,15 +37,13 @@ GLboolean Fence::isFence()
void Fence::setFence(GLenum condition) void Fence::setFence(GLenum condition)
{ {
if (mQuery != NULL) if (!mQuery)
{
mQuery->Release();
mQuery = NULL;
}
if (FAILED(getDevice()->CreateQuery(D3DQUERYTYPE_EVENT, &mQuery)))
{ {
return error(GL_OUT_OF_MEMORY); mQuery = getDisplay()->allocateEventQuery();
if (!mQuery)
{
return error(GL_OUT_OF_MEMORY);
}
} }
HRESULT result = mQuery->Issue(D3DISSUE_END); HRESULT result = mQuery->Issue(D3DISSUE_END);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment