Skip to content

Commit 377ea66

Browse files
committed
Simplify function W3DSmudgeManager::testHardwareSupport to what chat has suggested trying
1 parent bdb6551 commit 377ea66

File tree

2 files changed

+52
-187
lines changed

2 files changed

+52
-187
lines changed

Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DSmudge.cpp

Lines changed: 51 additions & 187 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ void W3DSmudgeManager::init(void)
5757
{
5858
SmudgeManager::init();
5959
ReAcquireResources();
60+
testHardwareSupport();
6061
}
6162

6263
void W3DSmudgeManager::reset (void)
@@ -133,210 +134,73 @@ void W3DSmudgeManager::ReAcquireResources(void)
133134
}
134135
}
135136

136-
/*Copies a portion of the current render target into a specified buffer*/
137-
Int copyRect(unsigned char *buf, Int bufSize, Int oX, Int oY, Int width, Int height)
137+
Bool W3DSmudgeManager::testHardwareSupport(void)
138138
{
139-
IDirect3DSurface8 *surface=NULL; ///<previous render target
140-
IDirect3DSurface8 *tempSurface=NULL;
141-
Int result = 0;
142-
143-
LPDIRECT3DDEVICE8 m_pDev=DX8Wrapper::_Get_D3D_Device8();
144-
145-
if (!m_pDev)
146-
goto error;
147-
148-
m_pDev->GetRenderTarget(&surface);
149-
150-
if (!surface)
151-
goto error;
152-
153-
D3DSURFACE_DESC desc;
154-
surface->GetDesc(&desc);
155-
156-
RECT srcRect;
157-
srcRect.left=oX;
158-
srcRect.top=oY;
159-
srcRect.right=oX+width;
160-
srcRect.bottom=oY+height;
161-
DEBUG_ASSERTCRASH(srcRect.left >= 0, ("copyRect - Invalid size"));
162-
DEBUG_ASSERTCRASH(srcRect.top >= 0, ("copyRect - Invalid size"));
163-
DEBUG_ASSERTCRASH(srcRect.right < (LONG)desc.Width, ("copyRect - Invalid size"));
164-
DEBUG_ASSERTCRASH(srcRect.bottom < (LONG)desc.Height, ("copyRect - Invalid size"));
165-
166-
POINT dstPoint;
167-
dstPoint.x=0;
168-
dstPoint.y=0;
169-
170-
HRESULT hr;
171-
hr=m_pDev->CreateImageSurface(width, height, desc.Format, &tempSurface);
172-
173-
if (hr != S_OK)
174-
goto error;
175-
176-
hr=m_pDev->CopyRects(surface,&srcRect,1,tempSurface,&dstPoint);
177-
178-
if (hr != S_OK)
179-
goto error;
180-
181-
D3DLOCKED_RECT lrect;
182-
183-
hr=tempSurface->LockRect(&lrect,NULL,D3DLOCK_READONLY);
184-
185-
if (hr != S_OK)
186-
goto error;
187-
188-
tempSurface->GetDesc(&desc);
189-
UnsignedInt bytesPerPixel;
190-
bytesPerPixel = DX8Wrapper::Bytes_Per_Pixel(desc.Format);
191-
192-
if (bytesPerPixel == 0)
193-
goto error;
194-
195-
Int rowSize;
196-
Int totalSize;
197-
rowSize = width * bytesPerPixel;
198-
totalSize = height * rowSize;
199-
200-
if (totalSize > bufSize)
201-
totalSize = bufSize;
202-
203-
UnsignedByte* dst;
204-
UnsignedByte* src;
205-
Int rowCount;
206-
Int row;
207-
dst = buf;
208-
src = (UnsignedByte*)lrect.pBits;
209-
rowCount = totalSize / rowSize;
210-
211-
for (row = 0; row < rowCount; ++row)
139+
// Return cached result if already checked
140+
if (m_hardwareSupportStatus != SMUDGE_SUPPORT_UNKNOWN)
212141
{
213-
memcpy(dst, src, rowSize);
214-
dst += rowSize;
215-
src += lrect.Pitch;
142+
return m_hardwareSupportStatus == SMUDGE_SUPPORT_YES;
216143
}
217144

218-
result = totalSize;
219-
tempSurface->UnlockRect();
220-
221-
error:
222-
if (surface)
223-
surface->Release();
224-
if (tempSurface)
225-
tempSurface->Release();
226-
227-
return result;
228-
}
229-
230-
#define UNIQUE_COLOR (0x12345678)
231-
#define BLOCK_SIZE (8)
232-
233-
Bool W3DSmudgeManager::testHardwareSupport(void)
234-
{
235-
if (m_hardwareSupportStatus == SMUDGE_SUPPORT_UNKNOWN)
236-
{ //we have not done the test yet.
237-
238-
IDirect3DTexture8 *backTexture=W3DShaderManager::getRenderTexture();
239-
if (!backTexture)
240-
{ //do trivial test first to see if render target exists.
241-
m_hardwareSupportStatus = SMUDGE_SUPPORT_NO;
242-
return FALSE;
243-
}
244-
245-
if (!W3DShaderManager::isRenderingToTexture())
246-
return FALSE; //can't do the test unless we're rendering to texture.
247-
248-
VertexMaterialClass *vmat=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE);
249-
DX8Wrapper::Set_Material(vmat);
250-
REF_PTR_RELEASE(vmat); //no need to keep a reference since it's a preset.
251-
252-
ShaderClass shader=ShaderClass::_PresetOpaqueShader;
253-
shader.Set_Depth_Compare(ShaderClass::PASS_ALWAYS);
254-
shader.Set_Depth_Mask(ShaderClass::DEPTH_WRITE_DISABLE);
255-
DX8Wrapper::Set_Shader(shader);
256-
DX8Wrapper::Set_Texture(0,NULL);
257-
DX8Wrapper::Apply_Render_State_Changes(); //force update of view and projection matrices
258-
259-
struct _TRANS_LIT_TEX_VERTEX {
260-
Vector4 p;
261-
DWORD color; // diffuse color
262-
float u;
263-
float v;
264-
} v[4];
265-
266-
//bottom right
267-
v[0].p = Vector4( BLOCK_SIZE-0.5f, BLOCK_SIZE-0.5f, 0.0f, 1.0f );
268-
v[0].u = BLOCK_SIZE/(Real)TheDisplay->getWidth();
269-
v[0].v = BLOCK_SIZE/(Real)TheDisplay->getHeight();
270-
//top right
271-
v[1].p = Vector4( BLOCK_SIZE-0.5f, 0-0.5f, 0.0f, 1.0f );
272-
v[1].u = BLOCK_SIZE/(Real)TheDisplay->getWidth();
273-
v[1].v = 0;
274-
//bottom left
275-
v[2].p = Vector4( 0-0.5f, BLOCK_SIZE-0.5f, 0.0f, 1.0f );
276-
v[2].u = 0;
277-
v[2].v = BLOCK_SIZE/(Real)TheDisplay->getHeight();
278-
//top left
279-
v[3].p = Vector4( 0-0.5f, 0-0.5f, 0.0f, 1.0f );
280-
v[3].u = 0;
281-
v[3].v = 0;
282-
283-
v[0].color = UNIQUE_COLOR;
284-
v[1].color = UNIQUE_COLOR;
285-
v[2].color = UNIQUE_COLOR;
286-
v[3].color = UNIQUE_COLOR;
287-
288-
LPDIRECT3DDEVICE8 pDev=DX8Wrapper::_Get_D3D_Device8();
289-
290-
//draw polygons like this is very inefficient but for only 2 triangles, it's
291-
//not worth bothering with index/vertex buffers.
292-
pDev->SetVertexShader(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
293-
294-
pDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v, sizeof(_TRANS_LIT_TEX_VERTEX));
295-
296-
DWORD refData[BLOCK_SIZE*BLOCK_SIZE];
297-
memset(refData,0,sizeof(refData));
298-
Int bufSize=copyRect((unsigned char *)refData,sizeof(refData),0,0,BLOCK_SIZE,BLOCK_SIZE); //copy area we just rendered using solid color
299-
if (!bufSize)
300-
{
301-
m_hardwareSupportStatus = SMUDGE_SUPPORT_NO;
302-
return FALSE;
303-
}
304-
305-
DX8Wrapper::Set_DX8_Texture(0,backTexture);
145+
LPDIRECT3DDEVICE8 d3d8Device = DX8Wrapper::_Get_D3D_Device8();
146+
LPDIRECT3D8 d3d8Interface = DX8Wrapper::_Get_D3D8();
147+
if (!d3d8Device || !d3d8Interface)
148+
{
149+
m_hardwareSupportStatus = SMUDGE_SUPPORT_NO;
150+
return false;
151+
}
306152

307-
DWORD testData[BLOCK_SIZE*BLOCK_SIZE];
308-
memset(testData,0xff,sizeof(testData));
153+
D3DCAPS8 caps;
154+
d3d8Device->GetDeviceCaps(&caps);
309155

310-
v[0].color = 0xffffffff;
311-
v[1].color = 0xffffffff;
312-
v[2].color = 0xffffffff;
313-
v[3].color = 0xffffffff;
156+
// DX8 requires dynamic textures to efficiently update smudge texture
157+
if (!(caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES))
158+
{
159+
m_hardwareSupportStatus = SMUDGE_SUPPORT_NO;
160+
return false;
161+
}
314162

315-
pDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v, sizeof(_TRANS_LIT_TEX_VERTEX));
316-
bufSize=copyRect((unsigned char *)testData,sizeof(testData),0,0,BLOCK_SIZE,BLOCK_SIZE);
163+
IDirect3DTexture8 *backTexture = W3DShaderManager::getRenderTexture();
164+
if (!backTexture)
165+
{
166+
m_hardwareSupportStatus = SMUDGE_SUPPORT_NO;
167+
return FALSE;
168+
}
317169

318-
if (!bufSize)
319-
{
320-
m_hardwareSupportStatus = SMUDGE_SUPPORT_NO;
321-
return FALSE;
322-
}
170+
IDirect3DSurface8* surface;
171+
if (FAILED(backTexture->GetSurfaceLevel(0, &surface)))
172+
{
173+
m_hardwareSupportStatus = SMUDGE_SUPPORT_NO;
174+
return false;
175+
}
323176

324-
//compare the 2 buffers to see if they match.
325-
if (memcmp(testData,refData,bufSize) == 0)
326-
{
327-
m_hardwareSupportStatus = SMUDGE_SUPPORT_YES;
328-
return TRUE;
329-
}
177+
D3DSURFACE_DESC desc;
178+
surface->GetDesc(&desc);
179+
surface->Release();
180+
181+
// Check if the device supports render-to-texture for this format
182+
HRESULT hr = d3d8Interface->CheckDeviceFormat(
183+
D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
184+
DX8Wrapper::_Get_D3D_Back_Buffer_Format(),
185+
D3DUSAGE_RENDERTARGET,
186+
D3DRTYPE_TEXTURE,
187+
desc.Format
188+
);
189+
190+
if (hr != D3D_OK)
191+
{
330192
m_hardwareSupportStatus = SMUDGE_SUPPORT_NO;
193+
return false;
331194
}
332195

333-
return (SMUDGE_SUPPORT_YES == m_hardwareSupportStatus);
196+
m_hardwareSupportStatus = SMUDGE_SUPPORT_YES;
197+
return true;
334198
}
335199

336200
void W3DSmudgeManager::render(RenderInfoClass &rinfo)
337201
{
338202
//Verify that the card supports the effect.
339-
if (!testHardwareSupport())
203+
if (m_hardwareSupportStatus == SMUDGE_SUPPORT_NO)
340204
return;
341205

342206
CameraClass &camera=rinfo.Camera;

GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,7 @@ class DX8Wrapper
527527
static IDirect3D8* _Get_D3D8() { return D3DInterface; }
528528
/// Returns the display format - added by TR for video playback - not part of W3D
529529
static WW3DFormat getBackBufferFormat( void );
530+
static D3DFORMAT _Get_D3D_Back_Buffer_Format() { return DisplayFormat; }
530531
static bool Reset_Device(bool reload_assets=true);
531532

532533
static const DX8Caps* Get_Current_Caps() { WWASSERT(CurrentCaps); return CurrentCaps; }

0 commit comments

Comments
 (0)