Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,7 @@ class W3DSmudgeManager : public SmudgeManager
ShareBufferClass<unsigned int> *m_RGBABuffer; ///< array of particle color and alpha
ShareBufferClass<float> *m_sizeBuffer; ///< array of particle sizes

#ifdef USE_COPY_RECTS
TextureClass *m_backgroundTexture;
#endif
DX8IndexBufferClass *m_indexBuffer;
Int m_backBufferWidth;
Int m_backBufferHeight;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,13 +173,12 @@ Int ScreenDefaultFilter::init()

Bool ScreenDefaultFilter::preRender(Bool &skipRender, CustomScenePassModes &scenePassMode)
{
//Right now this filter is only used for smudges, so don't bother if none are present.
if (TheSmudgeManager)
{ if (((W3DSmudgeManager *)TheSmudgeManager)->getSmudgeCountLastFrame() == 0)
return FALSE;
}
W3DShaderManager::startRenderToTexture();
return true;
// TheSuperHackers @bugfix Disable RTT redirection for the default filter.
// When MSAA is forced by Nvidia driver profile, the D3D8 API reports MultiSampleType=NONE
// and SetRenderTarget returns S_OK, but the depth buffer is actually multisampled internally.
// Rendering to a non-MSAA texture with this hidden-MSAA depth buffer corrupts depth testing,
// producing a black screen. The smudge system has its own Copy path that works without RTT.
return FALSE;
}

Bool ScreenDefaultFilter::postRender(FilterModes mode, Coord2D &scrollDelta,Bool &doExtraRender)
Expand Down Expand Up @@ -2605,8 +2604,18 @@ void W3DShaderManager::init()
HRESULT hr=DX8Wrapper::_Get_D3D_Device8()->GetRenderTarget(&m_oldRenderSurface);

m_oldRenderSurface->GetDesc(&desc);

hr=DX8Wrapper::_Get_D3D_Device8()->CreateTexture(desc.Width,desc.Height,1,D3DUSAGE_RENDERTARGET,desc.Format,D3DPOOL_DEFAULT,&m_renderTexture);

// TheSuperHackers @bugfix Redirecting rendering to a non-multisampled texture
// while using a multisampled depth buffer is an API violation in DX8.
if (desc.MultiSampleType == D3DMULTISAMPLE_NONE)
{
hr=DX8Wrapper::_Get_D3D_Device8()->CreateTexture(desc.Width,desc.Height,1,D3DUSAGE_RENDERTARGET,desc.Format,D3DPOOL_DEFAULT,&m_renderTexture);
}
else
{
// Force failure path to avoid MSAA mismatch
hr = E_FAIL;
}

if (hr != S_OK)
{
Expand Down Expand Up @@ -2831,9 +2840,20 @@ void W3DShaderManager::startRenderToTexture()

if (m_renderingToTexture || m_newRenderSurface==nullptr || m_oldDepthSurface==nullptr) return;
HRESULT hr = DX8Wrapper::_Get_D3D_Device8()->SetRenderTarget(m_newRenderSurface,m_oldDepthSurface);
DEBUG_ASSERTCRASH(hr==S_OK, ("Set target failed unexpectedly."));

// TheSuperHackers @bugfix If SetRenderTarget fails (e.g. due to MSAA forced by driver
// profile causing a depth buffer mismatch that D3DSURFACE_DESC doesn't report), permanently
// disable RTT to prevent repeated failures and accidental backbuffer clears.
if (hr != S_OK)
{
// Permanently disable RTT
if (m_newRenderSurface) { m_newRenderSurface->Release(); m_newRenderSurface = nullptr; }
if (m_renderTexture) { m_renderTexture->Release(); m_renderTexture = nullptr; }
if (m_oldRenderSurface) { m_oldRenderSurface->Release(); m_oldRenderSurface = nullptr; }
if (m_oldDepthSurface) { m_oldDepthSurface->Release(); m_oldDepthSurface = nullptr; }
Comment on lines +2850 to +2853
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Multiple statements on same line as if condition prevents setting individual breakpoints

Suggested change
if (m_newRenderSurface) { m_newRenderSurface->Release(); m_newRenderSurface = nullptr; }
if (m_renderTexture) { m_renderTexture->Release(); m_renderTexture = nullptr; }
if (m_oldRenderSurface) { m_oldRenderSurface->Release(); m_oldRenderSurface = nullptr; }
if (m_oldDepthSurface) { m_oldDepthSurface->Release(); m_oldDepthSurface = nullptr; }
if (m_newRenderSurface)
{
m_newRenderSurface->Release();
m_newRenderSurface = nullptr;
}
if (m_renderTexture)
{
m_renderTexture->Release();
m_renderTexture = nullptr;
}
if (m_oldRenderSurface)
{
m_oldRenderSurface->Release();
m_oldRenderSurface = nullptr;
}
if (m_oldDepthSurface)
{
m_oldDepthSurface->Release();
m_oldDepthSurface = nullptr;
}

Context Used: Rule from dashboard - Always place if/else/for/while statement bodies on separate lines from the condition to allow precis... (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DShaderManager.cpp
Line: 2850-2853

Comment:
Multiple statements on same line as `if` condition prevents setting individual breakpoints

```suggestion
		if (m_newRenderSurface)
		{
			m_newRenderSurface->Release();
			m_newRenderSurface = nullptr;
		}
		if (m_renderTexture)
		{
			m_renderTexture->Release();
			m_renderTexture = nullptr;
		}
		if (m_oldRenderSurface)
		{
			m_oldRenderSurface->Release();
			m_oldRenderSurface = nullptr;
		}
		if (m_oldDepthSurface)
		{
			m_oldDepthSurface->Release();
			m_oldDepthSurface = nullptr;
		}
```

**Context Used:** Rule from `dashboard` - Always place if/else/for/while statement bodies on separate lines from the condition to allow precis... ([source](https://app.greptile.com/review/custom-context?memory=16b9b669-b823-49be-ba5b-2bd30ff3ba6d))

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

return;
}

m_renderingToTexture = true;
if (TheGlobalData->m_showSoftWaterEdge)
{ //Soft water edges use frame buffer destination alpha so we must clear it to a known value.
Expand Down
67 changes: 30 additions & 37 deletions Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DSmudge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,7 @@ void W3DSmudgeManager::reset ()

void W3DSmudgeManager::ReleaseResources()
{
#ifdef USE_COPY_RECTS
REF_PTR_RELEASE(m_backgroundTexture);
#endif
REF_PTR_RELEASE(m_indexBuffer);
}

Expand All @@ -85,9 +83,12 @@ void W3DSmudgeManager::ReAcquireResources()
surface->Get_Description(surface_desc);
REF_PTR_RELEASE(surface);

#ifdef USE_COPY_RECTS
m_backgroundTexture = MSGNEW("TextureClass") TextureClass(TheTacticalView->getWidth(),TheTacticalView->getHeight(),surface_desc.Format,MIP_LEVELS_1,TextureClass::POOL_DEFAULT, true);
#endif
// TheSuperHackers @bugfix Use backbuffer dimensions instead of tactical view dimensions.
// With forced MSAA, SurfaceClass::Copy uses CopyRects with NULL rects for whole-surface resolve.
// This requires the destination surface to match the source surface dimensions exactly.
// Using TheTacticalView dimensions caused a size mismatch, forcing a fallback to
// D3DXLoadSurfaceFromSurface which cannot read from MSAA surfaces.
m_backgroundTexture = MSGNEW("TextureClass") TextureClass(surface_desc.Width,surface_desc.Height,surface_desc.Format,MIP_LEVELS_1,TextureClass::POOL_DEFAULT, true);

m_backBufferWidth = surface_desc.Width;
m_backBufferHeight = surface_desc.Height;
Expand Down Expand Up @@ -207,15 +208,20 @@ Bool W3DSmudgeManager::testHardwareSupport()
{ //we have not done the test yet.

IDirect3DTexture8 *backTexture=W3DShaderManager::getRenderTexture();
if (!backTexture)
{ //do trivial test first to see if render target exists.
if (!backTexture || !W3DShaderManager::isRenderingToTexture())
{
// TheSuperHackers @bugfix When RTT is disabled globally (e.g. due to forced MSAA),
// if the Copy path is still available, accept that as hardware support.
if (m_backgroundTexture)
{
m_hardwareSupportStatus = SMUDGE_SUPPORT_YES;
return TRUE;
}

m_hardwareSupportStatus = SMUDGE_SUPPORT_NO;
return FALSE;
}

if (!W3DShaderManager::isRenderingToTexture())
return FALSE; //can't do the test unless we're rendering to texture.

VertexMaterialClass *vmat=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE);
DX8Wrapper::Set_Material(vmat);
REF_PTR_RELEASE(vmat); //no need to keep a reference since it's a preset.
Expand Down Expand Up @@ -306,6 +312,12 @@ void W3DSmudgeManager::render(RenderInfoClass &rinfo)
if (!testHardwareSupport())
return;

SurfaceClass *backBuffer = DX8Wrapper::_Get_DX8_Back_Buffer();
if (!backBuffer) return;

SurfaceClass::SurfaceDescription surface_desc;
backBuffer->Get_Description(surface_desc);

CameraClass &camera=rinfo.Camera;
Vector3 vsVert;
Vector4 ssVert;
Expand All @@ -327,22 +339,13 @@ void W3DSmudgeManager::render(RenderInfoClass &rinfo)
camera.Get_View_Matrix(&view);
camera.Get_Projection_Matrix(&proj);

SurfaceClass::SurfaceDescription surface_desc;
#ifdef USE_COPY_RECTS
SurfaceClass *background=m_backgroundTexture->Get_Surface_Level();
background->Get_Description(surface_desc);
#else
D3DSURFACE_DESC D3DDesc;
SurfaceClass *background=m_backgroundTexture ? m_backgroundTexture->Get_Surface_Level() : nullptr;

IDirect3DTexture8 *backTexture=W3DShaderManager::getRenderTexture();
if (!backTexture || !W3DShaderManager::isRenderingToTexture())
return; //this card doesn't support render targets.

backTexture->GetLevelDesc(0,&D3DDesc);

surface_desc.Width = D3DDesc.Width;
surface_desc.Height = D3DDesc.Height;
#endif
if (!background)
{
REF_PTR_RELEASE(backBuffer);
return;
}

Real texClampX = (Real)TheTacticalView->getWidth()/(Real)surface_desc.Width;
Real texClampY = (Real)TheTacticalView->getHeight()/(Real)surface_desc.Height;
Expand Down Expand Up @@ -421,23 +424,16 @@ void W3DSmudgeManager::render(RenderInfoClass &rinfo)

if (!count)
{
#ifdef USE_COPY_RECTS
REF_PTR_RELEASE(background);
#endif
REF_PTR_RELEASE(backBuffer);
return; //nothing to render.
}

#ifdef USE_COPY_RECTS
SurfaceClass *backBuffer=DX8Wrapper::_Get_DX8_Back_Buffer();

backBuffer->Get_Description(surface_desc);

//Copy the area of backbuffer occupied by smudges into an alternate buffer.
background->Copy(0,0,0,0,surface_desc.Width,surface_desc.Height,backBuffer);

REF_PTR_RELEASE(background);
REF_PTR_RELEASE(backBuffer);
#endif

Matrix4x4 identity(true);
DX8Wrapper::Set_Transform(D3DTS_WORLD,identity);
Expand All @@ -447,18 +443,15 @@ void W3DSmudgeManager::render(RenderInfoClass &rinfo)
//DX8Wrapper::Set_Shader(ShaderClass::_PresetOpaqueSpriteShader);

DX8Wrapper::Set_Shader(ShaderClass::_PresetAlphaShader);
#ifdef USE_COPY_RECTS

DX8Wrapper::Set_Texture(0,m_backgroundTexture);
#else
DX8Wrapper::Set_DX8_Texture(0,backTexture);
//Need these states in case texture is non-power-of-2
DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSW, D3DTADDRESS_CLAMP);
DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_MIPFILTER, D3DTEXF_NONE);
#endif
VertexMaterialClass *vmat=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE);
DX8Wrapper::Set_Material(vmat);
REF_PTR_RELEASE(vmat);
Expand Down
Loading