mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-15 08:41:59 +00:00
- 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
|
@ -1,3 +1,11 @@
|
|||
October 7, 2009
|
||||
- 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.)
|
||||
|
||||
October 4, 2009 (Changes by Graf Zahl)
|
||||
- Deleted a_magewand.cpp because it only contained unused code.
|
||||
- Fixed: The conversation code tried to get the player's tag instead of the
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -336,9 +336,10 @@ private:
|
|||
void CreateBlockSurfaces();
|
||||
bool CreateFBTexture();
|
||||
bool CreatePaletteTexture();
|
||||
bool CreateGrayPaletteTexture();
|
||||
bool CreateGammaTexture();
|
||||
bool CreateVertexes();
|
||||
void UploadPalette();
|
||||
void UpdateGammaTexture(float igamma);
|
||||
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();
|
||||
|
@ -381,7 +382,7 @@ private:
|
|||
float Constant[3][4];
|
||||
D3DCOLOR CurBorderColor;
|
||||
IDirect3DPixelShader9 *CurPixelShader;
|
||||
IDirect3DTexture9 *Texture[2];
|
||||
IDirect3DTexture9 *Texture[5];
|
||||
|
||||
PalEntry SourcePalette[256];
|
||||
D3DCOLOR BorderColor;
|
||||
|
@ -415,6 +416,7 @@ private:
|
|||
IDirect3DTexture9 *FBTexture;
|
||||
IDirect3DTexture9 *TempRenderTexture;
|
||||
IDirect3DTexture9 *PaletteTexture;
|
||||
IDirect3DTexture9 *GammaTexture;
|
||||
IDirect3DTexture9 *ScreenshotTexture;
|
||||
IDirect3DSurface9 *ScreenshotSurface;
|
||||
|
||||
|
@ -429,6 +431,7 @@ private:
|
|||
enum { BATCH_None, BATCH_Quads, BATCH_Lines } BatchType;
|
||||
|
||||
IDirect3DPixelShader9 *Shaders[NUM_SHADERS];
|
||||
IDirect3DPixelShader9 *GammaShader;
|
||||
|
||||
IDirect3DSurface9 *BlockSurface[2];
|
||||
IDirect3DSurface9 *OldRenderTarget;
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
sampler2D Image : register(s0);
|
||||
sampler1D Palette : register(s1);
|
||||
#if PS14
|
||||
sampler1D Gamma1 : register(s2);
|
||||
sampler1D Gamma2 : register(s3);
|
||||
sampler1D Gamma3 : register(s4);
|
||||
#endif
|
||||
|
||||
float4 PaletteMod : register(c2);
|
||||
float4 Weights : register(c6); // RGB->Gray weighting { 77/256.0, 143/256.0, 37/256.0, 1 }
|
||||
|
@ -100,7 +105,19 @@ float4 InGameColormap(float2 tex_coord : TEXCOORD0, float4 color : COLOR0, float
|
|||
float4 GammaCorrection(float2 tex_coord : TEXCOORD0) : COLOR
|
||||
{
|
||||
float4 color = tex2D(Image, tex_coord);
|
||||
#if !PS14
|
||||
color.rgb = pow(color.rgb, Gamma.rgb);
|
||||
#else
|
||||
// On PS14 targets, we can only sample once from each sampler
|
||||
// per stage. Fortunately, we have 16 samplers to play with,
|
||||
// so we can just set three of them to the gamma texture and
|
||||
// use one for each component. Unfortunately, all these
|
||||
// texture lookups are probably not as efficient as the pow()
|
||||
// solution that later targets make possible.
|
||||
color.r = tex1D(Gamma1, color.r * Gamma.w).r;
|
||||
color.g = tex1D(Gamma2, color.g * Gamma.w).g;
|
||||
color.b = tex1D(Gamma3, color.b * Gamma.w).b;
|
||||
#endif
|
||||
return color;
|
||||
}
|
||||
|
||||
|
|
BIN
wadsrc/static/shaders/d3d/sm14/GammaCorrection.pso
Normal file
BIN
wadsrc/static/shaders/d3d/sm14/GammaCorrection.pso
Normal file
Binary file not shown.
|
@ -22,4 +22,4 @@ fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /EInGameColormap -DPALTEX=1 -DINVERT=1 -
|
|||
|
||||
fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /EBurnWipe /FoBurnWipe.pso
|
||||
|
||||
@rem PS1.4 does not support the pow instruction, so no windowed gamma correction for it.
|
||||
fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /EGammaCorrection /FoGammaCorrection.pso
|
||||
|
|
Loading…
Reference in a new issue