mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 13:01:47 +00:00
- 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 it from system to video memory would be acceptable. Apparently I was wrong. In particular, updating the same surface several times probably has to synchronize between each one, making melt particularly slower than it needs to be. SVN r2012 (trunk)
This commit is contained in:
parent
f722b10294
commit
80034135ef
4 changed files with 181 additions and 91 deletions
|
@ -1,3 +1,11 @@
|
|||
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
|
||||
it from system to video memory would be acceptable. Apparently I was wrong.
|
||||
In particular, updating the same surface several times probably has to
|
||||
synchronize between each one, making melt particularly slower than it
|
||||
needs to be.
|
||||
|
||||
November 29, 2009 (Changes by Graf Zahl)
|
||||
- fixed: Line_SetBlocking and Line_SetTextureScale were not in the list
|
||||
of action specials used by DECORATE or MAPINFO.
|
||||
|
|
|
@ -162,30 +162,6 @@ public:
|
|||
int RoundedPaletteSize;
|
||||
};
|
||||
|
||||
// Flags for a buffered quad
|
||||
enum
|
||||
{
|
||||
BQF_GamePalette = 1,
|
||||
BQF_CustomPalette = 7,
|
||||
BQF_Paletted = 7,
|
||||
BQF_Bilinear = 8,
|
||||
BQF_WrapUV = 16,
|
||||
BQF_InvertSource = 32,
|
||||
BQF_DisableAlphaTest= 64,
|
||||
BQF_Desaturated = 128,
|
||||
};
|
||||
|
||||
// Shaders for a buffered quad
|
||||
enum
|
||||
{
|
||||
BQS_PalTex,
|
||||
BQS_Plain,
|
||||
BQS_RedToAlpha,
|
||||
BQS_ColorOnly,
|
||||
BQS_SpecialColormap,
|
||||
BQS_InGameColormap,
|
||||
};
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
@ -1709,12 +1685,14 @@ void D3DFB::ReleaseScreenshotBuffer()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
IDirect3DTexture9 *D3DFB::GetCurrentScreen()
|
||||
IDirect3DTexture9 *D3DFB::GetCurrentScreen(D3DPOOL pool)
|
||||
{
|
||||
IDirect3DTexture9 *tex;
|
||||
IDirect3DSurface9 *tsurf, *surf;
|
||||
D3DSURFACE_DESC desc;
|
||||
|
||||
assert(pool == D3DPOOL_SYSTEMMEM || pool == D3DPOOL_DEFAULT);
|
||||
|
||||
if (Windowed || PixelDoubling)
|
||||
{
|
||||
// The texture we read into must have the same pixel format as
|
||||
|
@ -1752,8 +1730,8 @@ IDirect3DTexture9 *D3DFB::GetCurrentScreen()
|
|||
desc.Format = D3DFMT_A8R8G8B8;
|
||||
}
|
||||
|
||||
if (FAILED(D3DDevice->CreateTexture(desc.Width, desc.Height, 1, 0,
|
||||
desc.Format, D3DPOOL_SYSTEMMEM, &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)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1790,6 +1768,39 @@ IDirect3DTexture9 *D3DFB::GetCurrentScreen()
|
|||
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;
|
||||
}
|
||||
surf->Release();
|
||||
return tex;
|
||||
}
|
||||
|
@ -1861,7 +1872,7 @@ void D3DFB::DrawPackedTextures(int packnum)
|
|||
quad->ShaderNum = BQS_Plain;
|
||||
}
|
||||
quad->Palette = NULL;
|
||||
quad->Texture = pack;
|
||||
quad->Texture = pack->Tex;
|
||||
|
||||
float x0 = float(x) - 0.5f;
|
||||
float y0 = float(y) - 0.5f;
|
||||
|
@ -3007,7 +3018,7 @@ void STACK_ARGS D3DFB::DrawTextureV (FTexture *img, double x, double y, uint32 t
|
|||
return;
|
||||
}
|
||||
|
||||
QuadExtra[QuadBatchPos].Texture = tex->Box->Owner;
|
||||
QuadExtra[QuadBatchPos].Texture = tex->Box->Owner->Tex;
|
||||
if (parms.bilinear)
|
||||
{
|
||||
QuadExtra[QuadBatchPos].Flags |= BQF_Bilinear;
|
||||
|
@ -3148,7 +3159,7 @@ void D3DFB::FlatFill(int left, int top, int right, int bottom, FTexture *src, bo
|
|||
quad->ShaderNum = BQS_Plain;
|
||||
}
|
||||
quad->Palette = NULL;
|
||||
quad->Texture = tex->Box->Owner;
|
||||
quad->Texture = tex->Box->Owner->Tex;
|
||||
|
||||
vert[0].x = x0;
|
||||
vert[0].y = y0;
|
||||
|
@ -3380,11 +3391,13 @@ void D3DFB::EndQuadBatch()
|
|||
{
|
||||
SetPaletteTexture(quad->Palette->Tex, quad->Palette->RoundedPaletteSize, quad->Palette->BorderColor);
|
||||
}
|
||||
#if 0
|
||||
// Set paletted bilinear filtering (IF IT WORKED RIGHT!)
|
||||
if ((quad->Flags & (BQF_Paletted | BQF_Bilinear)) == (BQF_Paletted | BQF_Bilinear))
|
||||
{
|
||||
SetPalTexBilinearConstants(quad->Texture);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set the alpha blending
|
||||
SetAlphaBlend(D3DBLENDOP(quad->BlendOp), D3DBLEND(quad->SrcBlend), D3DBLEND(quad->DestBlend));
|
||||
|
@ -3442,7 +3455,7 @@ void D3DFB::EndQuadBatch()
|
|||
// Set the texture
|
||||
if (quad->Texture != NULL)
|
||||
{
|
||||
SetTexture(0, quad->Texture->Tex);
|
||||
SetTexture(0, quad->Texture);
|
||||
}
|
||||
|
||||
// Draw the quad
|
||||
|
|
|
@ -159,7 +159,7 @@ bool D3DFB::WipeStartScreen(int type)
|
|||
return false;
|
||||
}
|
||||
|
||||
InitialWipeScreen = GetCurrentScreen();
|
||||
InitialWipeScreen = GetCurrentScreen(D3DPOOL_DEFAULT);
|
||||
|
||||
// Create another texture to copy the final wipe screen to so
|
||||
// we can still gamma correct the wipe. Since this is just for
|
||||
|
@ -338,6 +338,27 @@ D3DFB::Wiper::~Wiper()
|
|||
{
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: Wiper :: DrawScreen
|
||||
//
|
||||
// Draw either the initial or target screen completely to the screen.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void D3DFB::Wiper::DrawScreen(D3DFB *fb, IDirect3DTexture9 *tex,
|
||||
D3DBLENDOP blendop, D3DCOLOR color0, D3DCOLOR color1)
|
||||
{
|
||||
FBVERTEX verts[4];
|
||||
|
||||
fb->CalcFullscreenCoords(verts, false, false, color0, color1);
|
||||
fb->D3DDevice->SetFVF(D3DFVF_FBVERTEX);
|
||||
fb->SetTexture(0, tex);
|
||||
fb->SetAlphaBlend(blendop, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
|
||||
fb->SetPixelShader(fb->Shaders[SHADER_NormalColor]);
|
||||
fb->D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(FBVERTEX));
|
||||
}
|
||||
|
||||
// WIPE: CROSSFADE ---------------------------------------------------------
|
||||
|
||||
//==========================================================================
|
||||
|
@ -363,29 +384,12 @@ bool D3DFB::Wiper_Crossfade::Run(int ticks, D3DFB *fb)
|
|||
{
|
||||
Clock += ticks;
|
||||
|
||||
// Put the initial screen back to the buffer, presumably with DMA.
|
||||
IDirect3DSurface9 *source = NULL, *target = NULL;
|
||||
|
||||
if (SUCCEEDED(fb->InitialWipeScreen->GetSurfaceLevel(0, &source)) &&
|
||||
SUCCEEDED(fb->D3DDevice->GetRenderTarget(0, &target)))
|
||||
{
|
||||
fb->D3DDevice->UpdateSurface(source, NULL, target, NULL);
|
||||
target->Release();
|
||||
}
|
||||
if (source != NULL)
|
||||
{
|
||||
source->Release();
|
||||
}
|
||||
// Put the initial screen back to the buffer.
|
||||
DrawScreen(fb, fb->InitialWipeScreen);
|
||||
|
||||
// Draw the new screen on top of it.
|
||||
FBVERTEX verts[4];
|
||||
|
||||
fb->CalcFullscreenCoords(verts, false, false, D3DCOLOR_COLORVALUE(0,0,0,Clock / 32.f), D3DCOLOR_RGBA(255,255,255,0));
|
||||
fb->D3DDevice->SetFVF(D3DFVF_FBVERTEX);
|
||||
fb->SetTexture(0, fb->FinalWipeScreen);
|
||||
fb->SetAlphaBlend(D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
|
||||
fb->SetPixelShader(fb->Shaders[SHADER_NormalColor]);
|
||||
fb->D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(FBVERTEX));
|
||||
DrawScreen(fb, fb->FinalWipeScreen, D3DBLENDOP_ADD,
|
||||
D3DCOLOR_COLORVALUE(0,0,0,Clock / 32.f), D3DCOLOR_RGBA(255,255,255,0));
|
||||
|
||||
return Clock >= 32;
|
||||
}
|
||||
|
@ -422,28 +426,8 @@ D3DFB::Wiper_Melt::Wiper_Melt()
|
|||
|
||||
bool D3DFB::Wiper_Melt::Run(int ticks, D3DFB *fb)
|
||||
{
|
||||
IDirect3DSurface9 *source = NULL, *target;
|
||||
|
||||
if (FAILED(fb->InitialWipeScreen->GetSurfaceLevel(0, &source)) ||
|
||||
FAILED(fb->D3DDevice->GetRenderTarget(0, &target)))
|
||||
{
|
||||
// A fat lot of good we can do if we can't get these two surfaces.
|
||||
if (source != NULL)
|
||||
{
|
||||
source->Release();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Draw the new screen on the bottom.
|
||||
FBVERTEX verts[4];
|
||||
|
||||
fb->CalcFullscreenCoords(verts, false, false, 0, 0xFFFFFFFF);
|
||||
fb->D3DDevice->SetFVF(D3DFVF_FBVERTEX);
|
||||
fb->SetTexture(0, fb->FinalWipeScreen);
|
||||
fb->SetAlphaBlend(D3DBLENDOP(0));
|
||||
fb->SetPixelShader(fb->Shaders[SHADER_NormalColor]);
|
||||
fb->D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(FBVERTEX));
|
||||
DrawScreen(fb, fb->FinalWipeScreen);
|
||||
|
||||
int i, dy;
|
||||
int fbwidth = fb->Width;
|
||||
|
@ -481,13 +465,82 @@ bool D3DFB::Wiper_Melt::Run(int ticks, D3DFB *fb)
|
|||
dpt.y += fb->LBOffsetI;
|
||||
if (rect.bottom > rect.top)
|
||||
{
|
||||
fb->D3DDevice->UpdateSurface(source, &rect, target, &dpt);
|
||||
fb->CheckQuadBatch();
|
||||
|
||||
BufferedQuad *quad = &fb->QuadExtra[fb->QuadBatchPos];
|
||||
FBVERTEX *vert = &fb->VertexData[fb->VertexPos];
|
||||
WORD *index = &fb->IndexData[fb->IndexPos];
|
||||
|
||||
quad->Group1 = 0;
|
||||
quad->Flags = BQF_DisableAlphaTest;
|
||||
quad->ShaderNum = BQS_Plain;
|
||||
quad->Palette = NULL;
|
||||
quad->Texture = fb->InitialWipeScreen;
|
||||
|
||||
// Fill the vertex buffer.
|
||||
float u0 = rect.left / float(fb->FBWidth);
|
||||
float v0 = 0;
|
||||
float u1 = rect.right / float(fb->FBWidth);
|
||||
float v1 = (rect.bottom - rect.top) / float(fb->FBHeight);
|
||||
|
||||
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;
|
||||
|
||||
vert[0].x = x0;
|
||||
vert[0].y = y0;
|
||||
vert[0].z = 0;
|
||||
vert[0].rhw = 1;
|
||||
vert[0].color0 = 0;
|
||||
vert[0].color1 = 0xFFFFFFF;
|
||||
vert[0].tu = u0;
|
||||
vert[0].tv = v0;
|
||||
|
||||
vert[1].x = x1;
|
||||
vert[1].y = y0;
|
||||
vert[1].z = 0;
|
||||
vert[1].rhw = 1;
|
||||
vert[1].color0 = 0;
|
||||
vert[1].color1 = 0xFFFFFFF;
|
||||
vert[1].tu = u1;
|
||||
vert[1].tv = v0;
|
||||
|
||||
vert[2].x = x1;
|
||||
vert[2].y = y1;
|
||||
vert[2].z = 0;
|
||||
vert[2].rhw = 1;
|
||||
vert[2].color0 = 0;
|
||||
vert[2].color1 = 0xFFFFFFF;
|
||||
vert[2].tu = u1;
|
||||
vert[2].tv = v1;
|
||||
|
||||
vert[3].x = x0;
|
||||
vert[3].y = y1;
|
||||
vert[3].z = 0;
|
||||
vert[3].rhw = 1;
|
||||
vert[3].color0 = 0;
|
||||
vert[3].color1 = 0xFFFFFFF;
|
||||
vert[3].tu = u0;
|
||||
vert[3].tv = v1;
|
||||
|
||||
// Fill the vertex index buffer.
|
||||
index[0] = fb->VertexPos;
|
||||
index[1] = fb->VertexPos + 1;
|
||||
index[2] = fb->VertexPos + 2;
|
||||
index[3] = fb->VertexPos;
|
||||
index[4] = fb->VertexPos + 2;
|
||||
index[5] = fb->VertexPos + 3;
|
||||
|
||||
// Batch the quad.
|
||||
fb->QuadBatchPos++;
|
||||
fb->VertexPos += 4;
|
||||
fb->IndexPos += 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
target->Release();
|
||||
source->Release();
|
||||
fb->EndQuadBatch();
|
||||
return done;
|
||||
}
|
||||
|
||||
|
@ -561,18 +614,7 @@ bool D3DFB::Wiper_Burn::Run(int ticks, D3DFB *fb)
|
|||
}
|
||||
|
||||
// Put the initial screen back to the buffer.
|
||||
IDirect3DSurface9 *source = NULL, *target;
|
||||
|
||||
if (SUCCEEDED(fb->InitialWipeScreen->GetSurfaceLevel(0, &source)) &&
|
||||
SUCCEEDED(fb->D3DDevice->GetRenderTarget(0, &target)))
|
||||
{
|
||||
fb->D3DDevice->UpdateSurface(source, NULL, target, NULL);
|
||||
target->Release();
|
||||
}
|
||||
if (source != NULL)
|
||||
{
|
||||
source->Release();
|
||||
}
|
||||
DrawScreen(fb, fb->InitialWipeScreen);
|
||||
|
||||
// Burn the new screen on top of it.
|
||||
float top = fb->LBOffset - 0.5f;
|
||||
|
|
|
@ -289,7 +289,7 @@ private:
|
|||
DWORD Group1;
|
||||
};
|
||||
D3DPal *Palette;
|
||||
PackingTexture *Texture;
|
||||
IDirect3DTexture9 *Texture;
|
||||
};
|
||||
|
||||
enum
|
||||
|
@ -344,7 +344,7 @@ private:
|
|||
void FillPresentParameters (D3DPRESENT_PARAMETERS *pp, bool fullscreen, bool vsync);
|
||||
void CalcFullscreenCoords (FBVERTEX verts[4], bool viewarea_only, bool can_double, D3DCOLOR color0, D3DCOLOR color1) const;
|
||||
bool Reset();
|
||||
IDirect3DTexture9 *GetCurrentScreen();
|
||||
IDirect3DTexture9 *GetCurrentScreen(D3DPOOL pool=D3DPOOL_SYSTEMMEM);
|
||||
void ReleaseDefaultPoolItems();
|
||||
void KillNativePals();
|
||||
void KillNativeTexs();
|
||||
|
@ -444,6 +444,9 @@ private:
|
|||
public:
|
||||
virtual ~Wiper();
|
||||
virtual bool Run(int ticks, D3DFB *fb) = 0;
|
||||
|
||||
void DrawScreen(D3DFB *fb, IDirect3DTexture9 *tex,
|
||||
D3DBLENDOP blendop=D3DBLENDOP(0), D3DCOLOR color0=0, D3DCOLOR color1=0xFFFFFFF);
|
||||
};
|
||||
|
||||
class Wiper_Melt; friend class Wiper_Melt;
|
||||
|
@ -453,6 +456,30 @@ private:
|
|||
Wiper *ScreenWipe;
|
||||
};
|
||||
|
||||
// Flags for a buffered quad
|
||||
enum
|
||||
{
|
||||
BQF_GamePalette = 1,
|
||||
BQF_CustomPalette = 7,
|
||||
BQF_Paletted = 7,
|
||||
BQF_Bilinear = 8,
|
||||
BQF_WrapUV = 16,
|
||||
BQF_InvertSource = 32,
|
||||
BQF_DisableAlphaTest= 64,
|
||||
BQF_Desaturated = 128,
|
||||
};
|
||||
|
||||
// Shaders for a buffered quad
|
||||
enum
|
||||
{
|
||||
BQS_PalTex,
|
||||
BQS_Plain,
|
||||
BQS_RedToAlpha,
|
||||
BQS_ColorOnly,
|
||||
BQS_SpecialColormap,
|
||||
BQS_InGameColormap,
|
||||
};
|
||||
|
||||
#if 0
|
||||
#define STARTLOG do { if (!dbg) dbg = fopen ("k:/vid.log", "w"); } while(0)
|
||||
#define STOPLOG do { if (dbg) { fclose (dbg); dbg=NULL; } } while(0)
|
||||
|
|
Loading…
Reference in a new issue