mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-01-31 05:40:44 +00:00
- Fixed: After the previous screenwipe changes, the melt type no longer worked
properly in letterboxed modes. - Added another surface to receive a copy of the top back buffer immediately before it is presented. This effectively produces a copy of the front buffer without the performance penalty of GetFrontBufferData, so fullscreen wipe preparation and screenshots are faster now. At lower resolutions, always copying the backbuffer does incur a slight FPS hit, but it's practically free at higher resolutions. SVN r2013 (trunk)
This commit is contained in:
parent
80034135ef
commit
d924575b1e
4 changed files with 82 additions and 99 deletions
|
@ -1,3 +1,11 @@
|
|||
December 1, 2009
|
||||
- Added another surface to receive a copy of the top back buffer immediately
|
||||
before it is presented. This effectively produces a copy of the front
|
||||
buffer without the performance penalty of GetFrontBufferData, so fullscreen
|
||||
wipe preparation and screenshots are faster now. At lower resolutions,
|
||||
always copying the backbuffer does incur a slight FPS hit, but it's
|
||||
practically free at higher resolutions.
|
||||
|
||||
November 30, 2009
|
||||
- The initial wipe screen is now kept in video memory. I had previously
|
||||
assumed that since the wipes only run at 35 FPS, the time spent DMA'ing
|
||||
|
|
|
@ -253,6 +253,7 @@ D3DFB::D3DFB (int width, int height, bool fullscreen)
|
|||
FinalWipeScreen = NULL;
|
||||
PaletteTexture = NULL;
|
||||
GammaTexture = NULL;
|
||||
FrontCopySurface = NULL;
|
||||
for (int i = 0; i < NUM_SHADERS; ++i)
|
||||
{
|
||||
Shaders[i] = NULL;
|
||||
|
@ -637,6 +638,7 @@ void D3DFB::ReleaseDefaultPoolItems()
|
|||
SAFE_RELEASE( IndexBuffer );
|
||||
SAFE_RELEASE( BlockSurface[0] );
|
||||
SAFE_RELEASE( BlockSurface[1] );
|
||||
SAFE_RELEASE( FrontCopySurface );
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -748,14 +750,14 @@ void D3DFB::KillNativeTexs()
|
|||
|
||||
bool D3DFB::CreateFBTexture ()
|
||||
{
|
||||
if (FAILED(D3DDevice->CreateTexture (Width, Height, 1, D3DUSAGE_DYNAMIC, D3DFMT_L8, D3DPOOL_DEFAULT, &FBTexture, NULL)))
|
||||
if (FAILED(D3DDevice->CreateTexture(Width, Height, 1, D3DUSAGE_DYNAMIC, D3DFMT_L8, D3DPOOL_DEFAULT, &FBTexture, NULL)))
|
||||
{
|
||||
int pow2width, pow2height, i;
|
||||
|
||||
for (i = 1; i < Width; i <<= 1) {} pow2width = i;
|
||||
for (i = 1; i < Height; i <<= 1) {} pow2height = i;
|
||||
|
||||
if (FAILED(D3DDevice->CreateTexture (pow2width, pow2height, 1, D3DUSAGE_DYNAMIC, D3DFMT_L8, D3DPOOL_DEFAULT, &FBTexture, NULL)))
|
||||
if (FAILED(D3DDevice->CreateTexture(pow2width, pow2height, 1, D3DUSAGE_DYNAMIC, D3DFMT_L8, D3DPOOL_DEFAULT, &FBTexture, NULL)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -770,7 +772,7 @@ bool D3DFB::CreateFBTexture ()
|
|||
FBWidth = Width;
|
||||
FBHeight = Height;
|
||||
}
|
||||
if (FAILED(D3DDevice->CreateTexture (FBWidth, FBHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &TempRenderTexture, NULL)))
|
||||
if (FAILED(D3DDevice->CreateTexture(FBWidth, FBHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &TempRenderTexture, NULL)))
|
||||
{
|
||||
TempRenderTexture = NULL;
|
||||
}
|
||||
|
@ -784,6 +786,10 @@ bool D3DFB::CreateFBTexture ()
|
|||
surf->Release();
|
||||
}
|
||||
}
|
||||
if (FAILED(D3DDevice->CreateRenderTarget(Width, Height, D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &FrontCopySurface, NULL)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1156,6 +1162,8 @@ void D3DFB::Flip()
|
|||
DoWindowedGamma();
|
||||
D3DDevice->EndScene();
|
||||
|
||||
CopyNextFrontBuffer();
|
||||
|
||||
// Attempt to counter input lag.
|
||||
if (d3d_antilag && BlockSurface[0] != NULL)
|
||||
{
|
||||
|
@ -1173,6 +1181,42 @@ void D3DFB::Flip()
|
|||
InScene = false;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: CopyNextFrontBuffer
|
||||
//
|
||||
// Duplicates the contents of the back buffer that will become the front
|
||||
// buffer upon Present into FrontCopySurface so that we can get the
|
||||
// contents of the display without wasting time in GetFrontBufferData().
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void D3DFB::CopyNextFrontBuffer()
|
||||
{
|
||||
IDirect3DSurface9 *backbuff;
|
||||
|
||||
if (Windowed || PixelDoubling)
|
||||
{
|
||||
// Windowed mode or pixel doubling: TempRenderTexture has what we want
|
||||
if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &backbuff)))
|
||||
{
|
||||
D3DDevice->StretchRect(backbuff, NULL, FrontCopySurface, NULL, D3DTEXF_NONE);
|
||||
backbuff->Release();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fullscreen, not pixel doubled: The back buffer has what we want,
|
||||
// but it might be letter boxed.
|
||||
if (SUCCEEDED(D3DDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuff)))
|
||||
{
|
||||
RECT srcrect = { 0, LBOffsetI, Width, LBOffsetI + Height };
|
||||
D3DDevice->StretchRect(backbuff, &srcrect, FrontCopySurface, NULL, D3DTEXF_NONE);
|
||||
backbuff->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: PaintToWindow
|
||||
|
@ -1688,50 +1732,25 @@ void D3DFB::ReleaseScreenshotBuffer()
|
|||
IDirect3DTexture9 *D3DFB::GetCurrentScreen(D3DPOOL pool)
|
||||
{
|
||||
IDirect3DTexture9 *tex;
|
||||
IDirect3DSurface9 *tsurf, *surf;
|
||||
IDirect3DSurface9 *surf;
|
||||
D3DSURFACE_DESC desc;
|
||||
HRESULT hr;
|
||||
|
||||
assert(pool == D3DPOOL_SYSTEMMEM || pool == D3DPOOL_DEFAULT);
|
||||
|
||||
if (Windowed || PixelDoubling)
|
||||
if (FAILED(FrontCopySurface->GetDesc(&desc)))
|
||||
{
|
||||
// The texture we read into must have the same pixel format as
|
||||
// the TempRenderTexture.
|
||||
if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &tsurf)))
|
||||
{
|
||||
if (FAILED(tsurf->GetDesc(&desc)))
|
||||
{
|
||||
tsurf->Release();
|
||||
return NULL;
|
||||
}
|
||||
tsurf->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
if (pool == D3DPOOL_SYSTEMMEM)
|
||||
{
|
||||
hr = D3DDevice->CreateTexture(desc.Width, desc.Height, 1, 0, desc.Format, D3DPOOL_SYSTEMMEM, &tex, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SUCCEEDED(D3DDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &tsurf)))
|
||||
{
|
||||
if (FAILED(tsurf->GetDesc(&desc)))
|
||||
{
|
||||
tsurf->Release();
|
||||
return NULL;
|
||||
}
|
||||
tsurf->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
// GetFrontBufferData works only with this format
|
||||
desc.Format = D3DFMT_A8R8G8B8;
|
||||
hr = D3DDevice->CreateTexture(FBWidth, FBHeight, 1, D3DUSAGE_RENDERTARGET, desc.Format, D3DPOOL_DEFAULT, &tex, NULL);
|
||||
}
|
||||
|
||||
// Read the image data into system memory.
|
||||
if (FAILED(D3DDevice->CreateTexture(desc.Width, desc.Height, 1, 0, desc.Format, D3DPOOL_SYSTEMMEM, &tex, NULL)))
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1740,68 +1759,23 @@ IDirect3DTexture9 *D3DFB::GetCurrentScreen(D3DPOOL pool)
|
|||
tex->Release();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!Windowed && !PixelDoubling)
|
||||
if (pool == D3DPOOL_SYSTEMMEM)
|
||||
{
|
||||
if (FAILED(D3DDevice->GetFrontBufferData(0, surf)))
|
||||
{
|
||||
surf->Release();
|
||||
tex->Release();
|
||||
return NULL;
|
||||
}
|
||||
// Video -> System memory : use GetRenderTargetData
|
||||
hr = D3DDevice->GetRenderTargetData(FrontCopySurface, surf);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &tsurf)))
|
||||
{
|
||||
if (FAILED(D3DDevice->GetRenderTargetData(tsurf, surf)))
|
||||
{
|
||||
tsurf->Release();
|
||||
tex->Release();
|
||||
return NULL;
|
||||
}
|
||||
tsurf->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
tex->Release();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// If the caller wants the screen in video memory, create a new texture, and copy back to that.
|
||||
if (pool == D3DPOOL_DEFAULT)
|
||||
{
|
||||
IDirect3DTexture9 *vtex;
|
||||
IDirect3DSurface9 *vsurf;
|
||||
|
||||
if (FAILED(D3DDevice->CreateTexture(FBWidth, FBHeight, 1, 0, desc.Format, D3DPOOL_DEFAULT, &vtex, NULL)))
|
||||
{
|
||||
surf->Release();
|
||||
tex->Release();
|
||||
return NULL;
|
||||
}
|
||||
if (FAILED(vtex->GetSurfaceLevel(0, &vsurf)))
|
||||
{
|
||||
vtex->Release();
|
||||
surf->Release();
|
||||
tex->Release();
|
||||
return NULL;
|
||||
}
|
||||
if (FAILED(D3DDevice->UpdateSurface(surf, NULL, vsurf, NULL)))
|
||||
{
|
||||
vsurf->Release();
|
||||
vtex->Release();
|
||||
surf->Release();
|
||||
tex->Release();
|
||||
return NULL;
|
||||
}
|
||||
surf->Release();
|
||||
tex->Release();
|
||||
surf = vsurf;
|
||||
tex = vtex;
|
||||
// Video -> Video memory : use StretchRect
|
||||
RECT destrect = { 0, 0, Width, Height };
|
||||
hr = D3DDevice->StretchRect(FrontCopySurface, NULL, surf, &destrect, D3DTEXF_POINT);
|
||||
}
|
||||
surf->Release();
|
||||
if (FAILED(hr))
|
||||
{
|
||||
tex->Release();
|
||||
return NULL;
|
||||
}
|
||||
return tex;
|
||||
}
|
||||
|
||||
|
|
|
@ -459,10 +459,9 @@ bool D3DFB::Wiper_Melt::Run(int ticks, D3DFB *fb)
|
|||
dpt.x = i * fbwidth / WIDTH;
|
||||
dpt.y = MAX(0, y[i] * fbheight / HEIGHT);
|
||||
rect.left = dpt.x;
|
||||
rect.top = fb->LBOffsetI;
|
||||
rect.top = 0;
|
||||
rect.right = (i + 1) * fbwidth / WIDTH;
|
||||
rect.bottom = fbheight - dpt.y + fb->LBOffsetI;
|
||||
dpt.y += fb->LBOffsetI;
|
||||
rect.bottom = fbheight - dpt.y;
|
||||
if (rect.bottom > rect.top)
|
||||
{
|
||||
fb->CheckQuadBatch();
|
||||
|
@ -485,8 +484,8 @@ bool D3DFB::Wiper_Melt::Run(int ticks, D3DFB *fb)
|
|||
|
||||
float x0 = float(rect.left) - 0.5f;
|
||||
float x1 = float(rect.right) - 0.5f;
|
||||
float y0 = float(dpt.y) - 0.5f;
|
||||
float y1 = float(fbheight) - 0.5f;
|
||||
float y0 = float(dpt.y + fb->LBOffsetI) - 0.5f;
|
||||
float y1 = float(fbheight + fb->LBOffsetI) - 0.5f;
|
||||
|
||||
vert[0].x = x0;
|
||||
vert[0].y = y0;
|
||||
|
|
|
@ -363,6 +363,7 @@ private:
|
|||
void BeginLineBatch();
|
||||
void EndLineBatch();
|
||||
void EndBatch();
|
||||
void CopyNextFrontBuffer();
|
||||
|
||||
D3DCAPS9 DeviceCaps;
|
||||
|
||||
|
@ -419,6 +420,7 @@ private:
|
|||
IDirect3DTexture9 *GammaTexture;
|
||||
IDirect3DTexture9 *ScreenshotTexture;
|
||||
IDirect3DSurface9 *ScreenshotSurface;
|
||||
IDirect3DSurface9 *FrontCopySurface;
|
||||
|
||||
IDirect3DVertexBuffer9 *VertexBuffer;
|
||||
FBVERTEX *VertexData;
|
||||
|
|
Loading…
Reference in a new issue