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,
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)
......
......@@ -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__
......@@ -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
......
......@@ -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;
......
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