- Since I am currently without a primary video card and stuck with this
Mobility Radeon 9000 (on a PCI card, no less!), I have decided to give the PS14 support some loving: D3D windowed gamma now works on these cards using a texture lookup for the gamma table. Sadly, this halves my framerate, so setting gamma to 1 will skip the gamma correction, as it was before, for full speed. (On my 8800 GT, the gamma correction was free.) SVN r1898 (trunk)
This commit is contained in:
parent
a6c387ecef
commit
da31d9f8a3
6 changed files with 119 additions and 17 deletions
|
|
@ -273,10 +273,12 @@ D3DFB::D3DFB (int width, int height, bool fullscreen)
|
|||
ScreenshotSurface = NULL;
|
||||
FinalWipeScreen = NULL;
|
||||
PaletteTexture = NULL;
|
||||
GammaTexture = NULL;
|
||||
for (int i = 0; i < NUM_SHADERS; ++i)
|
||||
{
|
||||
Shaders[i] = NULL;
|
||||
}
|
||||
GammaShader = NULL;
|
||||
BlockSurface[0] = NULL;
|
||||
BlockSurface[1] = NULL;
|
||||
FBFormat = D3DFMT_UNKNOWN;
|
||||
|
|
@ -416,12 +418,17 @@ void D3DFB::SetInitialState()
|
|||
CurPixelShader = NULL;
|
||||
memset(Constant, 0, sizeof(Constant));
|
||||
|
||||
Texture[0] = NULL;
|
||||
Texture[1] = NULL;
|
||||
D3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
D3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
D3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSU, SM14 ? D3DTADDRESS_BORDER : D3DTADDRESS_CLAMP);
|
||||
D3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSV, SM14 ? D3DTADDRESS_BORDER : D3DTADDRESS_CLAMP);
|
||||
for (int i = 0; i < countof(Texture); ++i)
|
||||
{
|
||||
Texture[i] = NULL;
|
||||
D3DDevice->SetSamplerState(i, D3DSAMP_ADDRESSU, (i == 1 && SM14) ? D3DTADDRESS_BORDER : D3DTADDRESS_CLAMP);
|
||||
D3DDevice->SetSamplerState(i, D3DSAMP_ADDRESSV, (i == 1 && SM14) ? D3DTADDRESS_BORDER : D3DTADDRESS_CLAMP);
|
||||
if (i > 1)
|
||||
{
|
||||
// Set linear filtering for the SM14 gamma texture.
|
||||
D3DDevice->SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
}
|
||||
}
|
||||
|
||||
NeedGammaUpdate = true;
|
||||
NeedPalUpdate = true;
|
||||
|
|
@ -534,6 +541,7 @@ bool D3DFB::CreateResources()
|
|||
{
|
||||
return false;
|
||||
}
|
||||
CreateGammaTexture();
|
||||
CreateBlockSurfaces();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -549,7 +557,7 @@ bool D3DFB::CreateResources()
|
|||
|
||||
bool D3DFB::LoadShaders()
|
||||
{
|
||||
static const char *const models[] = { "30/", "20/", "14/" };
|
||||
static const char models[][4] = { "30/", "20/", "14/" };
|
||||
FString shaderdir, shaderpath;
|
||||
int model, i, lump;
|
||||
|
||||
|
|
@ -568,7 +576,7 @@ bool D3DFB::LoadShaders()
|
|||
{
|
||||
FMemLump data = Wads.ReadLump(lump);
|
||||
if (FAILED(D3DDevice->CreatePixelShader((DWORD *)data.GetMem(), &Shaders[i])) &&
|
||||
i != SHADER_GammaCorrection && i != SHADER_BurnWipe)
|
||||
i < SHADER_BurnWipe)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
|
@ -607,6 +615,7 @@ void D3DFB::ReleaseResources ()
|
|||
{
|
||||
SAFE_RELEASE( Shaders[i] );
|
||||
}
|
||||
GammaShader = NULL;
|
||||
if (ScreenWipe != NULL)
|
||||
{
|
||||
delete ScreenWipe;
|
||||
|
|
@ -782,6 +791,19 @@ bool D3DFB::CreatePaletteTexture ()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool D3DFB::CreateGammaTexture ()
|
||||
{
|
||||
// If this fails, you just won't get gamma correction in a window
|
||||
// on SM14 cards.
|
||||
assert(GammaTexture == NULL);
|
||||
if (SM14)
|
||||
{
|
||||
return SUCCEEDED(D3DDevice->CreateTexture(256, 1, 1, 0, D3DFMT_A8R8G8B8,
|
||||
D3DPOOL_MANAGED, &GammaTexture, NULL));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool D3DFB::CreateVertexes ()
|
||||
{
|
||||
VertexPos = -1;
|
||||
|
|
@ -992,8 +1014,20 @@ void D3DFB::Update ()
|
|||
LOG("SetGammaRamp\n");
|
||||
D3DDevice->SetGammaRamp(0, D3DSGR_CALIBRATE, &ramp);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (igamma != 1)
|
||||
{
|
||||
UpdateGammaTexture(igamma);
|
||||
GammaShader = Shaders[SHADER_GammaCorrection];
|
||||
}
|
||||
else
|
||||
{
|
||||
GammaShader = NULL;
|
||||
}
|
||||
}
|
||||
psgamma[2] = psgamma[1] = psgamma[0] = igamma;
|
||||
psgamma[3] = 1;
|
||||
psgamma[3] = 0.5; // For SM14 version
|
||||
D3DDevice->SetPixelShaderConstantF(PSCONST_Gamma, psgamma, 1);
|
||||
}
|
||||
|
||||
|
|
@ -1105,7 +1139,7 @@ void D3DFB::Draw3DPart(bool copy3d)
|
|||
D3DDevice->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, vid_hwaalines);
|
||||
assert(OldRenderTarget == NULL);
|
||||
if (TempRenderTexture != NULL &&
|
||||
((Windowed && Shaders[SHADER_GammaCorrection] && TempRenderTexture != FinalWipeScreen) || GatheringWipeScreen || PixelDoubling))
|
||||
((Windowed && GammaShader && TempRenderTexture != FinalWipeScreen) || GatheringWipeScreen || PixelDoubling))
|
||||
{
|
||||
IDirect3DSurface9 *targetsurf;
|
||||
if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &targetsurf)))
|
||||
|
|
@ -1196,12 +1230,50 @@ void D3DFB::DoWindowedGamma()
|
|||
D3DDevice->SetRenderTarget(0, OldRenderTarget);
|
||||
D3DDevice->SetFVF(D3DFVF_FBVERTEX);
|
||||
SetTexture(0, TempRenderTexture);
|
||||
SetPixelShader(Shaders[(Windowed && Shaders[SHADER_GammaCorrection]) ? SHADER_GammaCorrection : SHADER_NormalColor]);
|
||||
SetPixelShader(Windowed && GammaShader ? GammaShader : Shaders[SHADER_NormalColor]);
|
||||
if (SM14 && Windowed && GammaShader)
|
||||
{
|
||||
SetTexture(2, GammaTexture);
|
||||
SetTexture(3, GammaTexture);
|
||||
SetTexture(4, GammaTexture);
|
||||
}
|
||||
SetAlphaBlend(D3DBLENDOP(0));
|
||||
EnableAlphaTest(FALSE);
|
||||
D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(FBVERTEX));
|
||||
OldRenderTarget->Release();
|
||||
OldRenderTarget = NULL;
|
||||
if (SM14 && Windowed && GammaShader)
|
||||
{
|
||||
// SetTexture(0, GammaTexture);
|
||||
// SetPixelShader(Shaders[SHADER_NormalColor]);
|
||||
// D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(FBVERTEX));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: UpdateGammaTexture
|
||||
//
|
||||
// Updates the gamma texture used by the PS14 shader. We only use the first
|
||||
// half of the texture so that we needn't worry about imprecision causing
|
||||
// it to grab from the border.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void D3DFB::UpdateGammaTexture(float igamma)
|
||||
{
|
||||
D3DLOCKED_RECT lockrect;
|
||||
|
||||
if (GammaTexture != NULL && SUCCEEDED(GammaTexture->LockRect(0, &lockrect, NULL, 0)))
|
||||
{
|
||||
BYTE *pix = (BYTE *)lockrect.pBits;
|
||||
for (int i = 0; i <= 128; ++i)
|
||||
{
|
||||
pix[i*4+2] = pix[i*4+1] = pix[i*4] = BYTE(255.f * powf(i / 128.f, igamma));
|
||||
pix[i*4+3] = 255;
|
||||
}
|
||||
GammaTexture->UnlockRect(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1221,6 +1293,9 @@ void D3DFB::UploadPalette ()
|
|||
// is similarly affected, which basically means that all Shader Model
|
||||
// 1.4 cards suffer from this problem, since they all use some variant
|
||||
// of the ATI R200.
|
||||
//
|
||||
// [Oh, gee. Looking over the old documentation, I guess this is
|
||||
// documented that PS 1.x cards don't have a lot of precision.]
|
||||
skipat = SM14 ? 256 - 8 : 256;
|
||||
|
||||
for (i = 0; i < skipat; ++i, pix += 4)
|
||||
|
|
@ -3395,6 +3470,7 @@ void D3DFB::SetPixelShader(IDirect3DPixelShader9 *shader)
|
|||
|
||||
void D3DFB::SetTexture(int tnum, IDirect3DTexture9 *texture)
|
||||
{
|
||||
assert(tnum >= 0 && tnum < countof(Texture));
|
||||
if (Texture[tnum] != texture)
|
||||
{
|
||||
Texture[tnum] = texture;
|
||||
|
|
@ -3402,8 +3478,6 @@ void D3DFB::SetTexture(int tnum, IDirect3DTexture9 *texture)
|
|||
}
|
||||
}
|
||||
|
||||
CVAR(Float, pal, 0.5f, 0)
|
||||
CVAR(Float, pc, 255.f, 0)
|
||||
void D3DFB::SetPaletteTexture(IDirect3DTexture9 *texture, int count, D3DCOLOR border_color)
|
||||
{
|
||||
if (SM14)
|
||||
|
|
@ -3430,7 +3504,7 @@ void D3DFB::SetPaletteTexture(IDirect3DTexture9 *texture, int count, D3DCOLOR bo
|
|||
// The constant register c2 is used to hold the multiplier in the
|
||||
// x part and the adder in the y part.
|
||||
float fcount = 1 / float(count);
|
||||
SetConstant(PSCONST_PaletteMod, pc * fcount, pal * fcount, 0, 0);
|
||||
SetConstant(PSCONST_PaletteMod, 255 * fcount, 0.5f * fcount, 0, 0);
|
||||
}
|
||||
SetTexture(1, texture);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue