PixelShaderGen: For custom textures and scaled EFB copies, use correct texel to pixel mapping when sampling textures
(D3D9 only)
This is basically the same as revision e58692653a
, just for scaled textures and with a LOT more work...
This commit is contained in:
parent
d068686a7f
commit
9adc119e3c
|
@ -24,7 +24,7 @@
|
||||||
// Increment this every time you change shader generation code.
|
// Increment this every time you change shader generation code.
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
LINEAR_DISKCACHE_VER = 6970
|
LINEAR_DISKCACHE_VER = 6971
|
||||||
};
|
};
|
||||||
|
|
||||||
// On disk format:
|
// On disk format:
|
||||||
|
|
|
@ -560,6 +560,7 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
|
||||||
WRITE(p, "uniform float4 "I_KCOLORS"[4] : register(c%d);\n", C_KCOLORS);
|
WRITE(p, "uniform float4 "I_KCOLORS"[4] : register(c%d);\n", C_KCOLORS);
|
||||||
WRITE(p, "uniform float4 "I_ALPHA"[1] : register(c%d);\n", C_ALPHA);
|
WRITE(p, "uniform float4 "I_ALPHA"[1] : register(c%d);\n", C_ALPHA);
|
||||||
WRITE(p, "uniform float4 "I_TEXDIMS"[8] : register(c%d);\n", C_TEXDIMS);
|
WRITE(p, "uniform float4 "I_TEXDIMS"[8] : register(c%d);\n", C_TEXDIMS);
|
||||||
|
WRITE(p, "uniform float4 "I_VTEXSCALE"[8] : register(c%d);\n", C_VTEXSCALE);
|
||||||
WRITE(p, "uniform float4 "I_ZBIAS"[2] : register(c%d);\n", C_ZBIAS);
|
WRITE(p, "uniform float4 "I_ZBIAS"[2] : register(c%d);\n", C_ZBIAS);
|
||||||
WRITE(p, "uniform float4 "I_INDTEXSCALE"[2] : register(c%d);\n", C_INDTEXSCALE);
|
WRITE(p, "uniform float4 "I_INDTEXSCALE"[2] : register(c%d);\n", C_INDTEXSCALE);
|
||||||
WRITE(p, "uniform float4 "I_INDTEXMTX"[6] : register(c%d);\n", C_INDTEXMTX);
|
WRITE(p, "uniform float4 "I_INDTEXMTX"[6] : register(c%d);\n", C_INDTEXMTX);
|
||||||
|
@ -1102,9 +1103,9 @@ void SampleTexture(char *&p, const char *destination, const char *texcoords, con
|
||||||
WRITE(p, "%s=Tex%d.Sample(samp%d, %s.xy * "I_TEXDIMS"[%d].xy).%s;\n", destination, texmap,texmap, texcoords, texmap, texswap);
|
WRITE(p, "%s=Tex%d.Sample(samp%d, %s.xy * "I_TEXDIMS"[%d].xy).%s;\n", destination, texmap,texmap, texcoords, texmap, texswap);
|
||||||
else if (ApiType & API_D3D9)
|
else if (ApiType & API_D3D9)
|
||||||
{
|
{
|
||||||
// D3D9 uses different pixel to texel mapping, so we need to offset our base address by half a pixel.
|
// D3D9 uses different pixel to texel mapping, so we need to offset our sampling address by half a pixel (assuming native and virtual texture dimensions match each other, otherwise some math is involved).
|
||||||
// Read the MSDN article "Directly Mapping Texels to Pixels (Direct3D 9)" for further info.
|
// Read the MSDN article "Directly Mapping Texels to Pixels (Direct3D 9)" for further info.
|
||||||
WRITE(p, "%s=tex2D(samp%d, (%s.xy + float2(0.5f,0.5f)) * "I_TEXDIMS"[%d].xy).%s;\n", destination, texmap, texcoords, texmap, texswap);
|
WRITE(p, "%s=tex2D(samp%d, (%s.xy + 0.5f*"I_VTEXSCALE"[%d].%s) * "I_TEXDIMS"[%d].xy).%s;\n", destination, texmap, texcoords, texmap/2, (texmap&1)?"zw":"xy", texmap, texswap);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
WRITE(p, "%s=tex2D(samp%d, %s.xy * "I_TEXDIMS"[%d].xy).%s;\n", destination, texmap, texcoords, texmap, texswap);
|
WRITE(p, "%s=tex2D(samp%d, %s.xy * "I_TEXDIMS"[%d].xy).%s;\n", destination, texmap, texcoords, texmap, texswap);
|
||||||
|
|
|
@ -24,26 +24,27 @@
|
||||||
#define I_KCOLORS "k"
|
#define I_KCOLORS "k"
|
||||||
#define I_ALPHA "alphaRef"
|
#define I_ALPHA "alphaRef"
|
||||||
#define I_TEXDIMS "texdim"
|
#define I_TEXDIMS "texdim"
|
||||||
|
#define I_VTEXSCALE "vtexscale"
|
||||||
#define I_ZBIAS "czbias"
|
#define I_ZBIAS "czbias"
|
||||||
#define I_INDTEXSCALE "cindscale"
|
#define I_INDTEXSCALE "cindscale"
|
||||||
#define I_INDTEXMTX "cindmtx"
|
#define I_INDTEXMTX "cindmtx"
|
||||||
#define I_FOG "cfog"
|
#define I_FOG "cfog"
|
||||||
#define I_PLIGHTS "cLights"
|
#define I_PLIGHTS "cLights"
|
||||||
#define I_PMATERIALS "cmtrl"
|
#define I_PMATERIALS "cmtrl"
|
||||||
|
|
||||||
#define C_COLORMATRIX 0 // 0
|
#define C_COLORMATRIX 0 // 0
|
||||||
#define C_COLORS 0 // 0
|
#define C_COLORS 0 // 0
|
||||||
#define C_KCOLORS (C_COLORS + 4) // 4
|
#define C_KCOLORS (C_COLORS + 4) // 4
|
||||||
#define C_ALPHA (C_KCOLORS + 4) // 8
|
#define C_ALPHA (C_KCOLORS + 4) // 8
|
||||||
#define C_TEXDIMS (C_ALPHA + 1) // 9
|
#define C_TEXDIMS (C_ALPHA + 1) // 9
|
||||||
#define C_ZBIAS (C_TEXDIMS + 8) //17
|
#define C_VTEXSCALE (C_TEXDIMS + 8) //17 - virtual texture scaling factor (e.g. custom textures, scaled EFB copies)
|
||||||
#define C_INDTEXSCALE (C_ZBIAS + 2) //19
|
#define C_ZBIAS (C_VTEXSCALE + 4) //21
|
||||||
#define C_INDTEXMTX (C_INDTEXSCALE + 2) //21
|
#define C_INDTEXSCALE (C_ZBIAS + 2) //23
|
||||||
#define C_FOG (C_INDTEXMTX + 6) //27
|
#define C_INDTEXMTX (C_INDTEXSCALE + 2) //25
|
||||||
|
#define C_FOG (C_INDTEXMTX + 6) //31
|
||||||
#define C_PLIGHTS (C_FOG + 3)
|
#define C_PLIGHTS (C_FOG + 3) //34
|
||||||
#define C_PMATERIALS (C_PLIGHTS + 40)
|
#define C_PMATERIALS (C_PLIGHTS + 40) //74
|
||||||
#define C_PENVCONST_END (C_PMATERIALS + 4)
|
#define C_PENVCONST_END (C_PMATERIALS + 4) //78
|
||||||
#define PIXELSHADERUID_MAX_VALUES 70
|
#define PIXELSHADERUID_MAX_VALUES 70
|
||||||
#define PIXELSHADERUID_MAX_VALUES_SAFE 120
|
#define PIXELSHADERUID_MAX_VALUES_SAFE 120
|
||||||
|
|
||||||
|
|
|
@ -36,9 +36,11 @@ static bool s_bFogRangeAdjustChanged;
|
||||||
static int nLightsChanged[2]; // min,max
|
static int nLightsChanged[2]; // min,max
|
||||||
static float lastRGBAfull[2][4][4];
|
static float lastRGBAfull[2][4][4];
|
||||||
static u8 s_nTexDimsChanged;
|
static u8 s_nTexDimsChanged;
|
||||||
|
static u8 s_nVirtualTexScalesChanged;
|
||||||
static u8 s_nIndTexScaleChanged;
|
static u8 s_nIndTexScaleChanged;
|
||||||
static u32 lastAlpha;
|
static u32 lastAlpha;
|
||||||
static u32 lastTexDims[8]; // width | height << 16 | wrap_s << 28 | wrap_t << 30
|
static u32 lastTexDims[8]; // width | height << 16 | wrap_s << 28 | wrap_t << 30
|
||||||
|
static float lastVirtualTexScales[16]; // even fields: width ratio; odd fields: height ratio
|
||||||
static u32 lastZBias;
|
static u32 lastZBias;
|
||||||
static int nMaterialsChanged;
|
static int nMaterialsChanged;
|
||||||
|
|
||||||
|
@ -61,6 +63,7 @@ void PixelShaderManager::Init()
|
||||||
{
|
{
|
||||||
lastAlpha = 0;
|
lastAlpha = 0;
|
||||||
memset(lastTexDims, 0, sizeof(lastTexDims));
|
memset(lastTexDims, 0, sizeof(lastTexDims));
|
||||||
|
memset(lastVirtualTexScales, 0, sizeof(lastVirtualTexScales));
|
||||||
lastZBias = 0;
|
lastZBias = 0;
|
||||||
memset(lastRGBAfull, 0, sizeof(lastRGBAfull));
|
memset(lastRGBAfull, 0, sizeof(lastRGBAfull));
|
||||||
Dirty();
|
Dirty();
|
||||||
|
@ -70,6 +73,7 @@ void PixelShaderManager::Dirty()
|
||||||
{
|
{
|
||||||
s_nColorsChanged[0] = s_nColorsChanged[1] = 15;
|
s_nColorsChanged[0] = s_nColorsChanged[1] = 15;
|
||||||
s_nTexDimsChanged = 0xFF;
|
s_nTexDimsChanged = 0xFF;
|
||||||
|
s_nVirtualTexScalesChanged = 0xFF;
|
||||||
s_nIndTexScaleChanged = 0xFF;
|
s_nIndTexScaleChanged = 0xFF;
|
||||||
s_nIndTexMtxChanged = 15;
|
s_nIndTexMtxChanged = 15;
|
||||||
s_bAlphaChanged = s_bZBiasChanged = s_bZTextureTypeChanged = s_bDepthRangeChanged = true;
|
s_bAlphaChanged = s_bZBiasChanged = s_bZTextureTypeChanged = s_bDepthRangeChanged = true;
|
||||||
|
@ -83,7 +87,7 @@ void PixelShaderManager::Shutdown()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PixelShaderManager::SetConstants()
|
void PixelShaderManager::SetConstants(API_TYPE api_type)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 2; ++i)
|
for (int i = 0; i < 2; ++i)
|
||||||
{
|
{
|
||||||
|
@ -109,6 +113,16 @@ void PixelShaderManager::SetConstants()
|
||||||
s_nTexDimsChanged = 0;
|
s_nTexDimsChanged = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((api_type & API_D3D9) && s_nVirtualTexScalesChanged)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 8; i += 2)
|
||||||
|
{
|
||||||
|
if (s_nVirtualTexScalesChanged & (3<<i))
|
||||||
|
SetPSVirtualTexScalePair(i/2);
|
||||||
|
}
|
||||||
|
s_nVirtualTexScalesChanged = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (s_bAlphaChanged)
|
if (s_bAlphaChanged)
|
||||||
{
|
{
|
||||||
SetPSConstant4f(C_ALPHA, (lastAlpha&0xff)/255.0f, ((lastAlpha>>8)&0xff)/255.0f, 0, ((lastAlpha>>16)&0xff)/255.0f);
|
SetPSConstant4f(C_ALPHA, (lastAlpha&0xff)/255.0f, ((lastAlpha>>8)&0xff)/255.0f, 0, ((lastAlpha>>16)&0xff)/255.0f);
|
||||||
|
@ -338,6 +352,13 @@ void PixelShaderManager::SetPSTextureDims(int texid)
|
||||||
SetPSConstant4fv(C_TEXDIMS + texid, fdims);
|
SetPSConstant4fv(C_TEXDIMS + texid, fdims);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PixelShaderManager::SetPSVirtualTexScalePair(int texpairid)
|
||||||
|
{
|
||||||
|
PRIM_LOG("vtexscale%d: %f %f %f %f\n", texpairid, lastVirtualTexScales[texpairid*4], lastVirtualTexScales[texpairid*4+1],
|
||||||
|
lastVirtualTexScales[texpairid*4+2], lastVirtualTexScales[texpairid*4+3]);
|
||||||
|
SetPSConstant4fv(C_VTEXSCALE + texpairid, &lastVirtualTexScales[texpairid*4]);
|
||||||
|
}
|
||||||
|
|
||||||
// This one is high in profiles (0.5%). TODO: Move conversion out, only store the raw color value
|
// This one is high in profiles (0.5%). TODO: Move conversion out, only store the raw color value
|
||||||
// and update it when the shader constant is set, only.
|
// and update it when the shader constant is set, only.
|
||||||
void PixelShaderManager::SetColorChanged(int type, int num, bool high)
|
void PixelShaderManager::SetColorChanged(int type, int num, bool high)
|
||||||
|
@ -376,14 +397,25 @@ void PixelShaderManager::SetDestAlpha(const ConstantAlpha& alpha)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PixelShaderManager::SetTexDims(int texmapid, u32 width, u32 height, u32 wraps, u32 wrapt)
|
void PixelShaderManager::SetTexDims(int texmapid, u32 width, u32 height, u32 virtual_width, u32 virtual_height, u32 wraps, u32 wrapt, API_TYPE api_type)
|
||||||
{
|
{
|
||||||
u32 wh = width | (height << 16) | (wraps << 28) | (wrapt << 30);
|
u32 wh = width | (height << 16) | (wraps << 28) | (wrapt << 30);
|
||||||
if (lastTexDims[texmapid] != wh)
|
|
||||||
|
bool refresh = lastTexDims[texmapid] != wh;
|
||||||
|
if (api_type & API_D3D9)
|
||||||
{
|
{
|
||||||
lastTexDims[texmapid] = wh;
|
refresh |= (lastVirtualTexScales[texmapid*2] != (float)width / (float)virtual_width);
|
||||||
|
refresh |= (lastVirtualTexScales[texmapid*2+1] != (float)height / (float)virtual_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (refresh)
|
||||||
|
{
|
||||||
|
lastTexDims[texmapid] = wh;
|
||||||
|
lastVirtualTexScales[texmapid*2] = (float)width / (float)virtual_width;
|
||||||
|
lastVirtualTexScales[texmapid*2+1] = (float)height / (float)virtual_height;
|
||||||
s_nTexDimsChanged |= 1 << texmapid;
|
s_nTexDimsChanged |= 1 << texmapid;
|
||||||
}
|
s_nVirtualTexScalesChanged |= 1 << texmapid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PixelShaderManager::SetZTextureBias(u32 bias)
|
void PixelShaderManager::SetZTextureBias(u32 bias)
|
||||||
|
|
|
@ -26,18 +26,20 @@
|
||||||
class PixelShaderManager
|
class PixelShaderManager
|
||||||
{
|
{
|
||||||
static void SetPSTextureDims(int texid);
|
static void SetPSTextureDims(int texid);
|
||||||
|
static void SetPSVirtualTexScalePair(int texpairid);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void Init();
|
static void Init();
|
||||||
static void Dirty();
|
static void Dirty();
|
||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
|
|
||||||
static void SetConstants(); // sets pixel shader constants
|
static void SetConstants(API_TYPE api_type); // sets pixel shader constants
|
||||||
|
|
||||||
// constant management, should be called after memory is committed
|
// constant management, should be called after memory is committed
|
||||||
static void SetColorChanged(int type, int index, bool high);
|
static void SetColorChanged(int type, int index, bool high);
|
||||||
static void SetAlpha(const AlphaFunc& alpha);
|
static void SetAlpha(const AlphaFunc& alpha);
|
||||||
static void SetDestAlpha(const ConstantAlpha& alpha);
|
static void SetDestAlpha(const ConstantAlpha& alpha);
|
||||||
static void SetTexDims(int texmapid, u32 width, u32 height, u32 wraps, u32 wrapt);
|
static void SetTexDims(int texmapid, u32 width, u32 height, u32 virtual_width, u32 virtual_height, u32 wraps, u32 wrapt, API_TYPE api_type);
|
||||||
static void SetZTextureBias(u32 bias);
|
static void SetZTextureBias(u32 bias);
|
||||||
static void SetViewportChanged();
|
static void SetViewportChanged();
|
||||||
static void SetIndMatrixChanged(int matrixidx);
|
static void SetIndMatrixChanged(int matrixidx);
|
||||||
|
|
|
@ -234,7 +234,7 @@ void VertexManager::vFlush()
|
||||||
if (tentry)
|
if (tentry)
|
||||||
{
|
{
|
||||||
// 0s are probably for no manual wrapping needed.
|
// 0s are probably for no manual wrapping needed.
|
||||||
PixelShaderManager::SetTexDims(i, tentry->native_width, tentry->native_height, 0, 0);
|
PixelShaderManager::SetTexDims(i, tentry->native_width, tentry->native_height, tentry->virtual_width, tentry->virtual_height, 0, 0, API_D3D11);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ERROR_LOG(VIDEO, "error loading texture");
|
ERROR_LOG(VIDEO, "error loading texture");
|
||||||
|
@ -243,7 +243,7 @@ void VertexManager::vFlush()
|
||||||
|
|
||||||
// set global constants
|
// set global constants
|
||||||
VertexShaderManager::SetConstants();
|
VertexShaderManager::SetConstants();
|
||||||
PixelShaderManager::SetConstants();
|
PixelShaderManager::SetConstants(API_D3D11);
|
||||||
|
|
||||||
bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate &&
|
bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate &&
|
||||||
bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24;
|
bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24;
|
||||||
|
|
|
@ -143,7 +143,7 @@ void VertexManager::vFlush()
|
||||||
if (tentry)
|
if (tentry)
|
||||||
{
|
{
|
||||||
// 0s are probably for no manual wrapping needed.
|
// 0s are probably for no manual wrapping needed.
|
||||||
PixelShaderManager::SetTexDims(i, tentry->native_width, tentry->native_height, 0, 0);
|
PixelShaderManager::SetTexDims(i, tentry->native_width, tentry->native_height, tentry->virtual_width, tentry->virtual_height, 0, 0, API_D3D9);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ERROR_LOG(VIDEO, "error loading texture");
|
ERROR_LOG(VIDEO, "error loading texture");
|
||||||
|
@ -152,7 +152,7 @@ void VertexManager::vFlush()
|
||||||
|
|
||||||
// set global constants
|
// set global constants
|
||||||
VertexShaderManager::SetConstants();
|
VertexShaderManager::SetConstants();
|
||||||
PixelShaderManager::SetConstants();
|
PixelShaderManager::SetConstants(API_D3D9);
|
||||||
|
|
||||||
if (!PixelShaderCache::SetShader(DSTALPHA_NONE,g_nativeVertexFmt->m_components))
|
if (!PixelShaderCache::SetShader(DSTALPHA_NONE,g_nativeVertexFmt->m_components))
|
||||||
{
|
{
|
||||||
|
|
|
@ -161,7 +161,7 @@ void VertexManager::vFlush()
|
||||||
if (tentry)
|
if (tentry)
|
||||||
{
|
{
|
||||||
// 0s are probably for no manual wrapping needed.
|
// 0s are probably for no manual wrapping needed.
|
||||||
PixelShaderManager::SetTexDims(i, tentry->native_width, tentry->native_height, 0, 0);
|
PixelShaderManager::SetTexDims(i, tentry->native_width, tentry->native_height, tentry->virtual_width, tentry->virtual_height, 0, 0, API_OPENGL);
|
||||||
|
|
||||||
if (g_ActiveConfig.iLog & CONF_SAVETEXTURES)
|
if (g_ActiveConfig.iLog & CONF_SAVETEXTURES)
|
||||||
{
|
{
|
||||||
|
@ -179,7 +179,7 @@ void VertexManager::vFlush()
|
||||||
|
|
||||||
// set global constants
|
// set global constants
|
||||||
VertexShaderManager::SetConstants();
|
VertexShaderManager::SetConstants();
|
||||||
PixelShaderManager::SetConstants();
|
PixelShaderManager::SetConstants(API_OPENGL);
|
||||||
|
|
||||||
bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate
|
bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate
|
||||||
&& bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24;
|
&& bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24;
|
||||||
|
|
Loading…
Reference in New Issue