mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2025-01-31 04:20:34 +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)
|
October 4, 2009 (Changes by Graf Zahl)
|
||||||
- Deleted a_magewand.cpp because it only contained unused code.
|
- Deleted a_magewand.cpp because it only contained unused code.
|
||||||
- Fixed: The conversation code tried to get the player's tag instead of the
|
- 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;
|
ScreenshotSurface = NULL;
|
||||||
FinalWipeScreen = NULL;
|
FinalWipeScreen = NULL;
|
||||||
PaletteTexture = NULL;
|
PaletteTexture = NULL;
|
||||||
|
GammaTexture = NULL;
|
||||||
for (int i = 0; i < NUM_SHADERS; ++i)
|
for (int i = 0; i < NUM_SHADERS; ++i)
|
||||||
{
|
{
|
||||||
Shaders[i] = NULL;
|
Shaders[i] = NULL;
|
||||||
}
|
}
|
||||||
|
GammaShader = NULL;
|
||||||
BlockSurface[0] = NULL;
|
BlockSurface[0] = NULL;
|
||||||
BlockSurface[1] = NULL;
|
BlockSurface[1] = NULL;
|
||||||
FBFormat = D3DFMT_UNKNOWN;
|
FBFormat = D3DFMT_UNKNOWN;
|
||||||
|
@ -416,12 +418,17 @@ void D3DFB::SetInitialState()
|
||||||
CurPixelShader = NULL;
|
CurPixelShader = NULL;
|
||||||
memset(Constant, 0, sizeof(Constant));
|
memset(Constant, 0, sizeof(Constant));
|
||||||
|
|
||||||
Texture[0] = NULL;
|
for (int i = 0; i < countof(Texture); ++i)
|
||||||
Texture[1] = NULL;
|
{
|
||||||
D3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
Texture[i] = NULL;
|
||||||
D3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
D3DDevice->SetSamplerState(i, D3DSAMP_ADDRESSU, (i == 1 && SM14) ? D3DTADDRESS_BORDER : D3DTADDRESS_CLAMP);
|
||||||
D3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSU, SM14 ? D3DTADDRESS_BORDER : D3DTADDRESS_CLAMP);
|
D3DDevice->SetSamplerState(i, D3DSAMP_ADDRESSV, (i == 1 && SM14) ? D3DTADDRESS_BORDER : D3DTADDRESS_CLAMP);
|
||||||
D3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSV, 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;
|
NeedGammaUpdate = true;
|
||||||
NeedPalUpdate = true;
|
NeedPalUpdate = true;
|
||||||
|
@ -534,6 +541,7 @@ bool D3DFB::CreateResources()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
CreateGammaTexture();
|
||||||
CreateBlockSurfaces();
|
CreateBlockSurfaces();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -549,7 +557,7 @@ bool D3DFB::CreateResources()
|
||||||
|
|
||||||
bool D3DFB::LoadShaders()
|
bool D3DFB::LoadShaders()
|
||||||
{
|
{
|
||||||
static const char *const models[] = { "30/", "20/", "14/" };
|
static const char models[][4] = { "30/", "20/", "14/" };
|
||||||
FString shaderdir, shaderpath;
|
FString shaderdir, shaderpath;
|
||||||
int model, i, lump;
|
int model, i, lump;
|
||||||
|
|
||||||
|
@ -568,7 +576,7 @@ bool D3DFB::LoadShaders()
|
||||||
{
|
{
|
||||||
FMemLump data = Wads.ReadLump(lump);
|
FMemLump data = Wads.ReadLump(lump);
|
||||||
if (FAILED(D3DDevice->CreatePixelShader((DWORD *)data.GetMem(), &Shaders[i])) &&
|
if (FAILED(D3DDevice->CreatePixelShader((DWORD *)data.GetMem(), &Shaders[i])) &&
|
||||||
i != SHADER_GammaCorrection && i != SHADER_BurnWipe)
|
i < SHADER_BurnWipe)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -607,6 +615,7 @@ void D3DFB::ReleaseResources ()
|
||||||
{
|
{
|
||||||
SAFE_RELEASE( Shaders[i] );
|
SAFE_RELEASE( Shaders[i] );
|
||||||
}
|
}
|
||||||
|
GammaShader = NULL;
|
||||||
if (ScreenWipe != NULL)
|
if (ScreenWipe != NULL)
|
||||||
{
|
{
|
||||||
delete ScreenWipe;
|
delete ScreenWipe;
|
||||||
|
@ -782,6 +791,19 @@ bool D3DFB::CreatePaletteTexture ()
|
||||||
return true;
|
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 ()
|
bool D3DFB::CreateVertexes ()
|
||||||
{
|
{
|
||||||
VertexPos = -1;
|
VertexPos = -1;
|
||||||
|
@ -992,8 +1014,20 @@ void D3DFB::Update ()
|
||||||
LOG("SetGammaRamp\n");
|
LOG("SetGammaRamp\n");
|
||||||
D3DDevice->SetGammaRamp(0, D3DSGR_CALIBRATE, &ramp);
|
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[2] = psgamma[1] = psgamma[0] = igamma;
|
||||||
psgamma[3] = 1;
|
psgamma[3] = 0.5; // For SM14 version
|
||||||
D3DDevice->SetPixelShaderConstantF(PSCONST_Gamma, psgamma, 1);
|
D3DDevice->SetPixelShaderConstantF(PSCONST_Gamma, psgamma, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1105,7 +1139,7 @@ void D3DFB::Draw3DPart(bool copy3d)
|
||||||
D3DDevice->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, vid_hwaalines);
|
D3DDevice->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, vid_hwaalines);
|
||||||
assert(OldRenderTarget == NULL);
|
assert(OldRenderTarget == NULL);
|
||||||
if (TempRenderTexture != NULL &&
|
if (TempRenderTexture != NULL &&
|
||||||
((Windowed && Shaders[SHADER_GammaCorrection] && TempRenderTexture != FinalWipeScreen) || GatheringWipeScreen || PixelDoubling))
|
((Windowed && GammaShader && TempRenderTexture != FinalWipeScreen) || GatheringWipeScreen || PixelDoubling))
|
||||||
{
|
{
|
||||||
IDirect3DSurface9 *targetsurf;
|
IDirect3DSurface9 *targetsurf;
|
||||||
if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &targetsurf)))
|
if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &targetsurf)))
|
||||||
|
@ -1196,12 +1230,50 @@ void D3DFB::DoWindowedGamma()
|
||||||
D3DDevice->SetRenderTarget(0, OldRenderTarget);
|
D3DDevice->SetRenderTarget(0, OldRenderTarget);
|
||||||
D3DDevice->SetFVF(D3DFVF_FBVERTEX);
|
D3DDevice->SetFVF(D3DFVF_FBVERTEX);
|
||||||
SetTexture(0, TempRenderTexture);
|
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));
|
SetAlphaBlend(D3DBLENDOP(0));
|
||||||
EnableAlphaTest(FALSE);
|
EnableAlphaTest(FALSE);
|
||||||
D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(FBVERTEX));
|
D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(FBVERTEX));
|
||||||
OldRenderTarget->Release();
|
OldRenderTarget->Release();
|
||||||
OldRenderTarget = NULL;
|
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
|
// is similarly affected, which basically means that all Shader Model
|
||||||
// 1.4 cards suffer from this problem, since they all use some variant
|
// 1.4 cards suffer from this problem, since they all use some variant
|
||||||
// of the ATI R200.
|
// 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;
|
skipat = SM14 ? 256 - 8 : 256;
|
||||||
|
|
||||||
for (i = 0; i < skipat; ++i, pix += 4)
|
for (i = 0; i < skipat; ++i, pix += 4)
|
||||||
|
@ -3395,6 +3470,7 @@ void D3DFB::SetPixelShader(IDirect3DPixelShader9 *shader)
|
||||||
|
|
||||||
void D3DFB::SetTexture(int tnum, IDirect3DTexture9 *texture)
|
void D3DFB::SetTexture(int tnum, IDirect3DTexture9 *texture)
|
||||||
{
|
{
|
||||||
|
assert(tnum >= 0 && tnum < countof(Texture));
|
||||||
if (Texture[tnum] != texture)
|
if (Texture[tnum] != texture)
|
||||||
{
|
{
|
||||||
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)
|
void D3DFB::SetPaletteTexture(IDirect3DTexture9 *texture, int count, D3DCOLOR border_color)
|
||||||
{
|
{
|
||||||
if (SM14)
|
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
|
// The constant register c2 is used to hold the multiplier in the
|
||||||
// x part and the adder in the y part.
|
// x part and the adder in the y part.
|
||||||
float fcount = 1 / float(count);
|
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);
|
SetTexture(1, texture);
|
||||||
}
|
}
|
||||||
|
|
|
@ -336,9 +336,10 @@ private:
|
||||||
void CreateBlockSurfaces();
|
void CreateBlockSurfaces();
|
||||||
bool CreateFBTexture();
|
bool CreateFBTexture();
|
||||||
bool CreatePaletteTexture();
|
bool CreatePaletteTexture();
|
||||||
bool CreateGrayPaletteTexture();
|
bool CreateGammaTexture();
|
||||||
bool CreateVertexes();
|
bool CreateVertexes();
|
||||||
void UploadPalette();
|
void UploadPalette();
|
||||||
|
void UpdateGammaTexture(float igamma);
|
||||||
void FillPresentParameters (D3DPRESENT_PARAMETERS *pp, bool fullscreen, bool vsync);
|
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;
|
void CalcFullscreenCoords (FBVERTEX verts[4], bool viewarea_only, bool can_double, D3DCOLOR color0, D3DCOLOR color1) const;
|
||||||
bool Reset();
|
bool Reset();
|
||||||
|
@ -381,7 +382,7 @@ private:
|
||||||
float Constant[3][4];
|
float Constant[3][4];
|
||||||
D3DCOLOR CurBorderColor;
|
D3DCOLOR CurBorderColor;
|
||||||
IDirect3DPixelShader9 *CurPixelShader;
|
IDirect3DPixelShader9 *CurPixelShader;
|
||||||
IDirect3DTexture9 *Texture[2];
|
IDirect3DTexture9 *Texture[5];
|
||||||
|
|
||||||
PalEntry SourcePalette[256];
|
PalEntry SourcePalette[256];
|
||||||
D3DCOLOR BorderColor;
|
D3DCOLOR BorderColor;
|
||||||
|
@ -415,6 +416,7 @@ private:
|
||||||
IDirect3DTexture9 *FBTexture;
|
IDirect3DTexture9 *FBTexture;
|
||||||
IDirect3DTexture9 *TempRenderTexture;
|
IDirect3DTexture9 *TempRenderTexture;
|
||||||
IDirect3DTexture9 *PaletteTexture;
|
IDirect3DTexture9 *PaletteTexture;
|
||||||
|
IDirect3DTexture9 *GammaTexture;
|
||||||
IDirect3DTexture9 *ScreenshotTexture;
|
IDirect3DTexture9 *ScreenshotTexture;
|
||||||
IDirect3DSurface9 *ScreenshotSurface;
|
IDirect3DSurface9 *ScreenshotSurface;
|
||||||
|
|
||||||
|
@ -429,6 +431,7 @@ private:
|
||||||
enum { BATCH_None, BATCH_Quads, BATCH_Lines } BatchType;
|
enum { BATCH_None, BATCH_Quads, BATCH_Lines } BatchType;
|
||||||
|
|
||||||
IDirect3DPixelShader9 *Shaders[NUM_SHADERS];
|
IDirect3DPixelShader9 *Shaders[NUM_SHADERS];
|
||||||
|
IDirect3DPixelShader9 *GammaShader;
|
||||||
|
|
||||||
IDirect3DSurface9 *BlockSurface[2];
|
IDirect3DSurface9 *BlockSurface[2];
|
||||||
IDirect3DSurface9 *OldRenderTarget;
|
IDirect3DSurface9 *OldRenderTarget;
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
sampler2D Image : register(s0);
|
sampler2D Image : register(s0);
|
||||||
sampler1D Palette : register(s1);
|
sampler1D Palette : register(s1);
|
||||||
|
#if PS14
|
||||||
|
sampler1D Gamma1 : register(s2);
|
||||||
|
sampler1D Gamma2 : register(s3);
|
||||||
|
sampler1D Gamma3 : register(s4);
|
||||||
|
#endif
|
||||||
|
|
||||||
float4 PaletteMod : register(c2);
|
float4 PaletteMod : register(c2);
|
||||||
float4 Weights : register(c6); // RGB->Gray weighting { 77/256.0, 143/256.0, 37/256.0, 1 }
|
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 GammaCorrection(float2 tex_coord : TEXCOORD0) : COLOR
|
||||||
{
|
{
|
||||||
float4 color = tex2D(Image, tex_coord);
|
float4 color = tex2D(Image, tex_coord);
|
||||||
|
#if !PS14
|
||||||
color.rgb = pow(color.rgb, Gamma.rgb);
|
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;
|
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
|
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