Fix device reset in combination with large RTTs. All DepthBuffers need to be released and recreated...

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@1799 dfc29bdd-3216-0410-991c-e03cc46cb475
master
hybrid 2008-11-21 14:36:57 +00:00
parent e96027cbec
commit ad62c01608
4 changed files with 146 additions and 84 deletions

View File

@ -32,7 +32,7 @@ CD3D9Driver::CD3D9Driver(const core::dimension2d<s32>& screenSize, HWND window,
D3DLibrary(0), pID3D(0), pID3DDevice(0), PrevRenderTarget(0),
WindowId(0), SceneSourceRect(0),
LastVertexType((video::E_VERTEX_TYPE)-1), MaxTextureUnits(0), MaxUserClipPlanes(0),
MaxLightDistance(sqrtf(FLT_MAX)), LastSetLight(-1), DeviceLost(false),
MaxLightDistance(sqrtf(FLT_MAX)), LastSetLight(-1), ColorFormat(ECF_A8R8G8B8), DeviceLost(false),
Fullscreen(fullscreen), DriverWasReset(true)
{
#ifdef _DEBUG
@ -454,6 +454,21 @@ bool CD3D9Driver::initDriver(const core::dimension2d<s32>& screenSize,
pID3DDevice->GetDepthStencilSurface(&(DepthBuffers[0]->Surface));
DepthBuffers[0]->Size=ScreenSize;
D3DColorFormat = D3DFMT_A8R8G8B8;
IDirect3DSurface9* bb=0;
if (SUCCEEDED(pID3DDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &bb)))
{
D3DSURFACE_DESC desc;
bb->GetDesc(&desc);
D3DColorFormat = desc.Format;
if (D3DColorFormat == D3DFMT_X8R8G8B8)
D3DColorFormat = D3DFMT_A8R8G8B8;
bb->Release();
}
ColorFormat = getColorFormatFromD3DFormat(D3DColorFormat);
// so far so good.
return true;
}
@ -2301,22 +2316,40 @@ bool CD3D9Driver::reset()
tex->Release();
}
}
if(DepthBuffers[0]->Surface)
DepthBuffers[0]->Surface->Release();
for (i=0; i<DepthBuffers.size(); ++i)
{
if(DepthBuffers[i]->Surface)
DepthBuffers[i]->Surface->Release();
}
DriverWasReset=true;
HRESULT hr = pID3DDevice->Reset(&present);
// restore screen depthbuffer
pID3DDevice->GetDepthStencilSurface(&(DepthBuffers[0]->Surface));
D3DSURFACE_DESC desc;
DepthBuffers[0]->Surface->GetDesc(&desc);
// restore other depth buffers
for (i=1; i<DepthBuffers.size(); ++i)
{
HRESULT hr=pID3DDevice->CreateDepthStencilSurface(DepthBuffers[i]->Size.Width,
DepthBuffers[i]->Size.Height,
desc.Format,
desc.MultiSampleType,
desc.MultiSampleQuality,
TRUE,
&(DepthBuffers[i]->Surface),
NULL);
}
// restore RTTs
for (i=0; i<Textures.size(); ++i)
{
if (Textures[i].Surface->isRenderTarget())
((CD3D9Texture*)(Textures[i].Surface))->createRenderTarget();
}
pID3DDevice->GetDepthStencilSurface(&(DepthBuffers[0]->Surface));
if (FAILED(hr))
{
if (hr == D3DERR_DEVICELOST)
@ -2620,6 +2653,20 @@ IImage* CD3D9Driver::createScreenShot()
}
//! returns color format
ECOLOR_FORMAT CD3D9Driver::getColorFormat() const
{
return ColorFormat;
}
//! returns color format
D3DFORMAT CD3D9Driver::getD3DColorFormat() const
{
return D3DColorFormat;
}
// returns the current size of the screen or rendertarget
const core::dimension2d<s32>& CD3D9Driver::getCurrentRenderTargetSize() const
{
@ -2657,6 +2704,44 @@ void CD3D9Driver::enableClipPlane(u32 index, bool enable)
}
D3DFORMAT CD3D9Driver::getD3DFormatFromColorFormat(ECOLOR_FORMAT format) const
{
switch(format)
{
case ECF_A1R5G5B5:
return D3DFMT_A1R5G5B5;
case ECF_R5G6B5:
return D3DFMT_R5G6B5;
case ECF_R8G8B8:
return D3DFMT_R8G8B8;
case ECF_A8R8G8B8:
return D3DFMT_A8R8G8B8;
}
return D3DFMT_UNKNOWN;
}
ECOLOR_FORMAT CD3D9Driver::getColorFormatFromD3DFormat(D3DFORMAT format) const
{
switch(format)
{
case D3DFMT_X1R5G5B5:
case D3DFMT_A1R5G5B5:
return ECF_A1R5G5B5;
case D3DFMT_A8B8G8R8:
case D3DFMT_A8R8G8B8:
case D3DFMT_X8R8G8B8:
return ECF_A8R8G8B8;
case D3DFMT_R5G6B5:
return ECF_R5G6B5;
case D3DFMT_R8G8B8:
return ECF_R8G8B8;
default:
return (ECOLOR_FORMAT)0;
};
}
void CD3D9Driver::checkDepthBuffer(ITexture* tex)
{
if (!tex)

View File

@ -236,6 +236,20 @@ namespace video
// removes the depth struct from the DepthSurface array
void removeDepthSurface(SDepthSurface* depth);
//! Get the current color format of the color buffer
/** \return Color format of the color buffer. */
virtual ECOLOR_FORMAT getColorFormat() const;
//! Get the current color format of the color buffer
/** \return Color format of the color buffer as D3D color value. */
D3DFORMAT getD3DColorFormat() const;
//! Get D3D color format from Irrlicht color format.
D3DFORMAT getD3DFormatFromColorFormat(ECOLOR_FORMAT format) const;
//! Get Irrlicht color format from D3D color format.
ECOLOR_FORMAT getColorFormatFromD3DFormat(D3DFORMAT format) const;
private:
//! enumeration for rendering modes such as 2d and 3d for minizing the switching of renderStates.
@ -348,6 +362,9 @@ namespace video
u32 MaxUserClipPlanes;
f32 MaxLightDistance;
s32 LastSetLight;
ECOLOR_FORMAT ColorFormat;
D3DFORMAT D3DColorFormat;
bool DeviceLost;
bool Fullscreen;
bool DriverWasReset;
@ -359,5 +376,5 @@ namespace video
#endif // _IRR_COMPILE_WITH_DIRECT3D_9_
#endif // __C_VIDEO_DIRECTX_8_H_INCLUDED__
#endif // __C_VIDEO_DIRECTX_9_H_INCLUDED__

View File

@ -124,29 +124,10 @@ void CD3D9Texture::createRenderTarget()
os::Printer::log("RenderTarget size has to be a power of two", ELL_INFORMATION);
}
// get backbuffer format to create the render target in the
// same format
IDirect3DSurface9* bb;
D3DFORMAT d3DFormat = D3DFMT_A8R8G8B8;
if (!FAILED(Device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &bb)))
{
D3DSURFACE_DESC desc;
bb->GetDesc(&desc);
d3DFormat = desc.Format;
if (d3DFormat == D3DFMT_X8R8G8B8)
d3DFormat = D3DFMT_A8R8G8B8;
bb->Release();
}
else
{
os::Printer::log("Could not create RenderTarget texture", "could not get BackBuffer.",
ELL_WARNING);
return;
}
// get irrlicht format from backbuffer
ColorFormat = Driver->getColorFormat();
D3DFORMAT d3dformat = Driver->getD3DColorFormat();
setPitch(d3dformat);
// create texture
HRESULT hr;
@ -156,14 +137,11 @@ void CD3D9Texture::createRenderTarget()
TextureSize.Height,
1, // mip map level count, we don't want mipmaps here
D3DUSAGE_RENDERTARGET,
d3DFormat,
d3dformat,
D3DPOOL_DEFAULT,
&Texture,
NULL);
// get irrlicht format from D3D format
ColorFormat = getColorFormatFromD3DFormat(d3DFormat);
if (FAILED(hr))
{
if (D3DERR_INVALIDCALL == hr)
@ -269,7 +247,7 @@ bool CD3D9Texture::createMipMaps(u32 level)
upperSurface->Release();
lowerSurface->Release();
if (!result || (upperDesc.Width < 3 && upperDesc.Height < 3))
if (!result || (upperDesc.Width <= 3 && upperDesc.Height <= 3))
return result; // stop generating levels
// generate next level
@ -366,53 +344,12 @@ bool CD3D9Texture::createTexture(u32 flags, IImage * image)
0, format, D3DPOOL_MANAGED, &Texture, NULL);
}
ColorFormat = getColorFormatFromD3DFormat(format);
ColorFormat = Driver->getColorFormatFromD3DFormat(format);
setPitch(format);
return (SUCCEEDED(hr));
}
D3DFORMAT CD3D9Texture::getD3DFormatFromColorFormat(ECOLOR_FORMAT format) const
{
switch(format)
{
case ECF_A1R5G5B5:
return D3DFMT_A1R5G5B5;
case ECF_R5G6B5:
return D3DFMT_R5G6B5;
case ECF_R8G8B8:
return D3DFMT_R8G8B8;
case ECF_A8R8G8B8:
return D3DFMT_A8R8G8B8;
}
return D3DFMT_UNKNOWN;
}
ECOLOR_FORMAT CD3D9Texture::getColorFormatFromD3DFormat(D3DFORMAT format)
{
switch(format)
{
case D3DFMT_X1R5G5B5:
case D3DFMT_A1R5G5B5:
Pitch = TextureSize.Width * 2;
return ECF_A1R5G5B5;
case D3DFMT_A8B8G8R8:
case D3DFMT_A8R8G8B8:
case D3DFMT_X8R8G8B8:
Pitch = TextureSize.Width * 4;
return ECF_A8R8G8B8;
case D3DFMT_R5G6B5:
Pitch = TextureSize.Width * 2;
return ECF_R5G6B5;
case D3DFMT_R8G8B8:
Pitch = TextureSize.Width * 3;
return ECF_R8G8B8;
default:
return (ECOLOR_FORMAT)0;
};
}
//! copies the image to the texture
bool CD3D9Texture::copyTexture(IImage * image)
{
@ -683,6 +620,7 @@ bool CD3D9Texture::isRenderTarget() const
return IsRenderTarget;
}
//! Returns pointer to the render target surface
IDirect3DSurface9* CD3D9Texture::getRenderTargetSurface()
{
@ -700,6 +638,31 @@ IDirect3DSurface9* CD3D9Texture::getRenderTargetSurface()
}
void CD3D9Texture::setPitch(D3DFORMAT d3dformat)
{
switch(d3dformat)
{
case D3DFMT_X1R5G5B5:
case D3DFMT_A1R5G5B5:
Pitch = TextureSize.Width * 2;
break;
case D3DFMT_A8B8G8R8:
case D3DFMT_A8R8G8B8:
case D3DFMT_X8R8G8B8:
Pitch = TextureSize.Width * 4;
break;
case D3DFMT_R5G6B5:
Pitch = TextureSize.Width * 2;
break;
case D3DFMT_R8G8B8:
Pitch = TextureSize.Width * 3;
break;
default:
Pitch = 0;
};
}
} // end namespace video
} // end namespace irr

View File

@ -88,12 +88,6 @@ private:
//! copies the image to the texture
bool copyTexture(IImage * image);
//! Get D3D color format from Irrlicht color format.
D3DFORMAT getD3DFormatFromColorFormat(ECOLOR_FORMAT format) const;
//! Get Irrlicht color format from D3D color format.
ECOLOR_FORMAT getColorFormatFromD3DFormat(D3DFORMAT format);
//! Helper function for mipmap generation.
bool createMipMaps(u32 level=1);
@ -105,6 +99,9 @@ private:
void copy32BitMipMap(char* src, char* tgt,
s32 width, s32 height, s32 pitchsrc, s32 pitchtgt) const;
//! set Pitch based on the d3d format
void setPitch(D3DFORMAT d3dformat);
IDirect3DDevice9* Device;
IDirect3DTexture9* Texture;
IDirect3DSurface9* RTTSurface;