Commit ad62c016 authored by hybrid's avatar hybrid

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

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
parent e96027cb
...@@ -32,7 +32,7 @@ CD3D9Driver::CD3D9Driver(const core::dimension2d<s32>& screenSize, HWND window, ...@@ -32,7 +32,7 @@ CD3D9Driver::CD3D9Driver(const core::dimension2d<s32>& screenSize, HWND window,
D3DLibrary(0), pID3D(0), pID3DDevice(0), PrevRenderTarget(0), D3DLibrary(0), pID3D(0), pID3DDevice(0), PrevRenderTarget(0),
WindowId(0), SceneSourceRect(0), WindowId(0), SceneSourceRect(0),
LastVertexType((video::E_VERTEX_TYPE)-1), MaxTextureUnits(0), MaxUserClipPlanes(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) Fullscreen(fullscreen), DriverWasReset(true)
{ {
#ifdef _DEBUG #ifdef _DEBUG
...@@ -454,6 +454,21 @@ bool CD3D9Driver::initDriver(const core::dimension2d<s32>& screenSize, ...@@ -454,6 +454,21 @@ bool CD3D9Driver::initDriver(const core::dimension2d<s32>& screenSize,
pID3DDevice->GetDepthStencilSurface(&(DepthBuffers[0]->Surface)); pID3DDevice->GetDepthStencilSurface(&(DepthBuffers[0]->Surface));
DepthBuffers[0]->Size=ScreenSize; 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. // so far so good.
return true; return true;
} }
...@@ -2301,22 +2316,40 @@ bool CD3D9Driver::reset() ...@@ -2301,22 +2316,40 @@ bool CD3D9Driver::reset()
tex->Release(); tex->Release();
} }
} }
for (i=0; i<DepthBuffers.size(); ++i)
if(DepthBuffers[0]->Surface) {
DepthBuffers[0]->Surface->Release(); if(DepthBuffers[i]->Surface)
DepthBuffers[i]->Surface->Release();
}
DriverWasReset=true; DriverWasReset=true;
HRESULT hr = pID3DDevice->Reset(&present); 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) for (i=0; i<Textures.size(); ++i)
{ {
if (Textures[i].Surface->isRenderTarget()) if (Textures[i].Surface->isRenderTarget())
((CD3D9Texture*)(Textures[i].Surface))->createRenderTarget(); ((CD3D9Texture*)(Textures[i].Surface))->createRenderTarget();
} }
pID3DDevice->GetDepthStencilSurface(&(DepthBuffers[0]->Surface));
if (FAILED(hr)) if (FAILED(hr))
{ {
if (hr == D3DERR_DEVICELOST) if (hr == D3DERR_DEVICELOST)
...@@ -2620,6 +2653,20 @@ IImage* CD3D9Driver::createScreenShot() ...@@ -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 // returns the current size of the screen or rendertarget
const core::dimension2d<s32>& CD3D9Driver::getCurrentRenderTargetSize() const const core::dimension2d<s32>& CD3D9Driver::getCurrentRenderTargetSize() const
{ {
...@@ -2657,6 +2704,44 @@ void CD3D9Driver::enableClipPlane(u32 index, bool enable) ...@@ -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) void CD3D9Driver::checkDepthBuffer(ITexture* tex)
{ {
if (!tex) if (!tex)
......
...@@ -236,6 +236,20 @@ namespace video ...@@ -236,6 +236,20 @@ namespace video
// removes the depth struct from the DepthSurface array // removes the depth struct from the DepthSurface array
void removeDepthSurface(SDepthSurface* depth); 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: private:
//! enumeration for rendering modes such as 2d and 3d for minizing the switching of renderStates. //! enumeration for rendering modes such as 2d and 3d for minizing the switching of renderStates.
...@@ -348,6 +362,9 @@ namespace video ...@@ -348,6 +362,9 @@ namespace video
u32 MaxUserClipPlanes; u32 MaxUserClipPlanes;
f32 MaxLightDistance; f32 MaxLightDistance;
s32 LastSetLight; s32 LastSetLight;
ECOLOR_FORMAT ColorFormat;
D3DFORMAT D3DColorFormat;
bool DeviceLost; bool DeviceLost;
bool Fullscreen; bool Fullscreen;
bool DriverWasReset; bool DriverWasReset;
...@@ -359,5 +376,5 @@ namespace video ...@@ -359,5 +376,5 @@ namespace video
#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ #endif // _IRR_COMPILE_WITH_DIRECT3D_9_
#endif // __C_VIDEO_DIRECTX_8_H_INCLUDED__ #endif // __C_VIDEO_DIRECTX_9_H_INCLUDED__
...@@ -124,29 +124,10 @@ void CD3D9Texture::createRenderTarget() ...@@ -124,29 +124,10 @@ void CD3D9Texture::createRenderTarget()
os::Printer::log("RenderTarget size has to be a power of two", ELL_INFORMATION); os::Printer::log("RenderTarget size has to be a power of two", ELL_INFORMATION);
} }
// get backbuffer format to create the render target in the // get irrlicht format from backbuffer
// same format ColorFormat = Driver->getColorFormat();
D3DFORMAT d3dformat = Driver->getD3DColorFormat();
IDirect3DSurface9* bb; setPitch(d3dformat);
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;
}
// create texture // create texture
HRESULT hr; HRESULT hr;
...@@ -156,14 +137,11 @@ void CD3D9Texture::createRenderTarget() ...@@ -156,14 +137,11 @@ void CD3D9Texture::createRenderTarget()
TextureSize.Height, TextureSize.Height,
1, // mip map level count, we don't want mipmaps here 1, // mip map level count, we don't want mipmaps here
D3DUSAGE_RENDERTARGET, D3DUSAGE_RENDERTARGET,
d3DFormat, d3dformat,
D3DPOOL_DEFAULT, D3DPOOL_DEFAULT,
&Texture, &Texture,
NULL); NULL);
// get irrlicht format from D3D format
ColorFormat = getColorFormatFromD3DFormat(d3DFormat);
if (FAILED(hr)) if (FAILED(hr))
{ {
if (D3DERR_INVALIDCALL == hr) if (D3DERR_INVALIDCALL == hr)
...@@ -269,7 +247,7 @@ bool CD3D9Texture::createMipMaps(u32 level) ...@@ -269,7 +247,7 @@ bool CD3D9Texture::createMipMaps(u32 level)
upperSurface->Release(); upperSurface->Release();
lowerSurface->Release(); lowerSurface->Release();
if (!result || (upperDesc.Width < 3 && upperDesc.Height < 3)) if (!result || (upperDesc.Width <= 3 && upperDesc.Height <= 3))
return result; // stop generating levels return result; // stop generating levels
// generate next level // generate next level
...@@ -366,53 +344,12 @@ bool CD3D9Texture::createTexture(u32 flags, IImage * image) ...@@ -366,53 +344,12 @@ bool CD3D9Texture::createTexture(u32 flags, IImage * image)
0, format, D3DPOOL_MANAGED, &Texture, NULL); 0, format, D3DPOOL_MANAGED, &Texture, NULL);
} }
ColorFormat = getColorFormatFromD3DFormat(format); ColorFormat = Driver->getColorFormatFromD3DFormat(format);
setPitch(format);
return (SUCCEEDED(hr)); 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 //! copies the image to the texture
bool CD3D9Texture::copyTexture(IImage * image) bool CD3D9Texture::copyTexture(IImage * image)
{ {
...@@ -683,6 +620,7 @@ bool CD3D9Texture::isRenderTarget() const ...@@ -683,6 +620,7 @@ bool CD3D9Texture::isRenderTarget() const
return IsRenderTarget; return IsRenderTarget;
} }
//! Returns pointer to the render target surface //! Returns pointer to the render target surface
IDirect3DSurface9* CD3D9Texture::getRenderTargetSurface() IDirect3DSurface9* CD3D9Texture::getRenderTargetSurface()
{ {
...@@ -700,6 +638,31 @@ 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 video
} // end namespace irr } // end namespace irr
......
...@@ -88,12 +88,6 @@ private: ...@@ -88,12 +88,6 @@ private:
//! copies the image to the texture //! copies the image to the texture
bool copyTexture(IImage * image); 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. //! Helper function for mipmap generation.
bool createMipMaps(u32 level=1); bool createMipMaps(u32 level=1);
...@@ -105,6 +99,9 @@ private: ...@@ -105,6 +99,9 @@ private:
void copy32BitMipMap(char* src, char* tgt, void copy32BitMipMap(char* src, char* tgt,
s32 width, s32 height, s32 pitchsrc, s32 pitchtgt) const; s32 width, s32 height, s32 pitchsrc, s32 pitchtgt) const;
//! set Pitch based on the d3d format
void setPitch(D3DFORMAT d3dformat);
IDirect3DDevice9* Device; IDirect3DDevice9* Device;
IDirect3DTexture9* Texture; IDirect3DTexture9* Texture;
IDirect3DSurface9* RTTSurface; IDirect3DSurface9* RTTSurface;
......
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