a lot of people don't get convinced by my "Pseudo-antialiasing " effect and is true is not near the quality of the true effect so :)

true antialiasing using supersampling:
3 modes implemented:
2x = is a one and a half samples supersampled buffer with a linear texture fetch, this produce a similar result of a 2x MSAA
4x = four samples with a aligned texture fetch in the center of the 4 samples, this produce a little best effect that the first mode.
8x = is a four samples with a  rotated grid fetching producing a nicer (really nicer in some cases) antialiasing.
please test an let me know if you like this :)
i remember to everyone that supersampling is expensive so don't complain in speed drops :)

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5006 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Rodolfo Osvaldo Bogado 2010-02-03 22:19:00 +00:00
parent d89c5dddcd
commit 090d7ec534
6 changed files with 106 additions and 163 deletions

View File

@ -385,40 +385,6 @@ void drawShadedTexQuad(IDirect3DTexture9 *texture,
RestoreShaders();
}
void drawFSAATexQuad(IDirect3DTexture9 *texture,
IDirect3DTexture9 *Depthtexture,
const RECT *rSource,
int SourceWidth,
int SourceHeight,
IDirect3DPixelShader9 *PShader,
IDirect3DVertexShader9 *Vshader,
int Intensity,
float DepthRange)
{
float sw = 1.0f /(float) SourceWidth;
float sh = 1.0f /(float) SourceHeight;
float u1=((float)rSource->left + 0.5f) * sw;
float u2=((float)rSource->right + 0.5f) * sw;
float v1=((float)rSource->top + 0.5f) * sh;
float v2=((float)rSource->bottom + 0.5f) * sh;
float FinalIntensity = 4.0f / pow(10.0,Intensity);
struct Q2DVertex { float x,y,z,rhw;float u,v,w,h,dr1,dr2; } coords[4] = {
{-1.0f, 1.0f, 0.0f,1.0f,u1, v1, sw, sh,FinalIntensity,DepthRange},
{ 1.0f, 1.0f, 0.0f,1.0f,u2, v1, sw, sh,FinalIntensity,DepthRange},
{ 1.0f,-1.0f, 0.0f,1.0f,u2, v2, sw, sh,FinalIntensity,DepthRange},
{-1.0f,-1.0f, 0.0f,1.0f,u1, v2, sw, sh,FinalIntensity,DepthRange}
};
dev->SetVertexShader(Vshader);
dev->SetPixelShader(PShader);
D3D::SetTexture(0, texture);
D3D::SetTexture(1, Depthtexture);
dev->SetFVF(D3DFVF_XYZW | D3DFVF_TEX3);
dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(Q2DVertex));
RestoreShaders();
}
void drawClearQuad(u32 Color,float z,IDirect3DPixelShader9 *PShader,IDirect3DVertexShader9 *Vshader)
{
struct Q2DVertex { float x,y,z,rhw;u32 color;} coords[4] = {

View File

@ -64,15 +64,6 @@ namespace D3D
int SourceHeight,
IDirect3DPixelShader9 *PShader,
IDirect3DVertexShader9 *Vshader);
void drawFSAATexQuad(IDirect3DTexture9 *texture,
IDirect3DTexture9 *Depthtexture,
const RECT *rSource,
int SourceWidth,
int SourceHeight,
IDirect3DPixelShader9 *PShader,
IDirect3DVertexShader9 *Vshader,
int Intensity,
float DepthRange);
void drawClearQuad(u32 Color,float z,IDirect3DPixelShader9 *PShader,IDirect3DVertexShader9 *Vshader);
void SaveRenderStates();
void RestoreRenderStates();

View File

@ -126,7 +126,7 @@ void PixelShaderCache::Init()
char pprog[2048];
sprintf(pprog, "void main(\n"
"out float4 ocol0 : COLOR0,\n"
"in float4 incol0 : COLOR0){\n"
" in float4 incol0 : COLOR0){\n"
"ocol0 = incol0;\n"
"}\n");
s_ClearProgram = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog));
@ -143,7 +143,7 @@ void PixelShaderCache::Init()
"uniform float4 cColMatrix[5] : register(c%d);\n"
"void main(\n"
"out float4 ocol0 : COLOR0,\n"
"in float4 uv0 : TEXCOORD0){\n"
" in float4 uv0 : TEXCOORD0){\n"
"float4 texcol = tex2D(samp0,uv0.xy);\n"
"ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n"
"}\n",C_COLORMATRIX);
@ -153,7 +153,7 @@ void PixelShaderCache::Init()
"uniform float4 cColMatrix[5] : register(c%d);\n"
"void main(\n"
"out float4 ocol0 : COLOR0,\n"
"in float4 uv0 : TEXCOORD0){\n"
" in float4 uv0 : TEXCOORD0){\n"
"float4 texcol = tex2D(samp0,uv0.xy);\n"
"float4 EncodedDepth = frac((texcol.r * (16777215.0f/16777216.0f)) * float4(1.0f,255.0f,255.0f*255.0f,255.0f*255.0f*255.0f));\n"
"texcol = float4((EncodedDepth.rgb * (16777216.0f/16777215.0f)),1.0f);\n"
@ -165,27 +165,11 @@ void PixelShaderCache::Init()
"uniform sampler samp1 : register(s1);\n"
"void main(\n"
"out float4 ocol0 : COLOR0,\n"
"in float4 incol0 : COLOR0,\n"
"in float4 uv0 : TEXCOORD0,\n"
"in float4 uv1 : TEXCOORD1,\n"
"in float4 uv2 : TEXCOORD2,\n"
"in float4 uv3 : TEXCOORD3,\n"
"in float4 uv4 : TEXCOORD4,\n"
"in float2 uv5 : TEXCOORD5,\n"
"in float2 uv6 : TEXCOORD6,\n"
"in float2 uv7 : TEXCOORD7){\n"
"float3 P1 = float3(tex2D(samp1,uv0.xy).x,tex2D(samp1,uv1.xy).x,tex2D(samp1,uv2.xy).x);\n"
"float3 P2 = float3(tex2D(samp1,uv3.xy).x,tex2D(samp1,uv4.xy).x,tex2D(samp1,uv5).x);\n"
"float3 P3 = float3(P1.z,tex2D(samp1,uv6).x,P2.z);\n"
"float3 P4 = float3(P1.x,tex2D(samp1,uv7).r,P2.x);\n"
"float3 P5 = float3(1.0f,2.0f,1.0f);\n"
"float3 T = float3(dot(P3,P5) - dot(P4,P5),dot(P1,P5) - dot(P2,P5),0.0f);\n"
"if (dot(T,T) > incol0.x)\n"
"{\n"
"ocol0 = (tex2D(samp0,uv0.wz) + tex2D(samp0,uv1.wz) + tex2D(samp0,uv2.wz) + tex2D(samp0,uv3.wz))*0.25f;// + tex2D(samp0,uv4.xy) + tex2D(samp0,uv5) + tex2D(samp0,uv6) + tex2D(samp0,uv7) + tex2D(samp0,uv4.wz)) / 9.0f;\n"
"} else {\n"
"ocol0 = tex2D(samp0,uv4.wz);\n"
"}\n"
"in float2 uv0 : TEXCOORD0,\n"
"in float2 uv1 : TEXCOORD1,\n"
"in float2 uv2 : TEXCOORD2,\n"
"in float2 uv3 : TEXCOORD3){\n"
"ocol0 = (tex2D(samp0,uv0) + tex2D(samp0,uv1) + tex2D(samp0,uv2) + tex2D(samp0,uv3))*0.25f;\n"
"}\n");
s_FSAAProgram = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog));
@ -194,28 +178,12 @@ void PixelShaderCache::Init()
"uniform float4 cColMatrix[5] : register(c%d);\n"
"void main(\n"
"out float4 ocol0 : COLOR0,\n"
"in float4 incol0 : COLOR0,\n"
"in float4 uv0 : TEXCOORD0,\n"
"in float4 uv1 : TEXCOORD1,\n"
"in float4 uv2 : TEXCOORD2,\n"
"in float4 uv3 : TEXCOORD3,\n"
"in float4 uv4 : TEXCOORD4,\n"
"in float2 uv5 : TEXCOORD5,\n"
"in float2 uv6 : TEXCOORD6,\n"
"in float2 uv7 : TEXCOORD7){\n"
"float3 P1 = float3(tex2D(samp1,uv0.xy).x,tex2D(samp1,uv1.xy).x,tex2D(samp1,uv2.xy).x);\n"
"float3 P2 = float3(tex2D(samp1,uv3.xy).x,tex2D(samp1,uv4.xy).x,tex2D(samp1,uv5).x);\n"
"float3 P3 = float3(P1.z,tex2D(samp1,uv6).x,P2.z);\n"
"float3 P4 = float3(P1.x,tex2D(samp1,uv7).r,P2.x);\n"
"float3 P5 = float3(1.0f,2.0f,1.0f);\n"
"float3 T = float3(dot(P3,P5) - dot(P4,P5),dot(P1,P5) - dot(P2,P5),0.0f);\n"
"in float2 uv0 : TEXCOORD0,\n"
"in float2 uv1 : TEXCOORD1,\n"
"in float2 uv2 : TEXCOORD2,\n"
"in float2 uv3 : TEXCOORD3){\n"
"float4 texcol = float4(0.0f,0.0f,0.0f,0.0f);\n"
"if (dot(T,T) > incol0.x)\n"
"{\n"
"texcol = (tex2D(samp0,uv0.wz) + tex2D(samp0,uv1.wz) + tex2D(samp0,uv2.wz) + tex2D(samp0,uv3.wz))*0.25f;// + tex2D(samp0,uv4.xy) + tex2D(samp0,uv5) + tex2D(samp0,uv6) + tex2D(samp0,uv7) + tex2D(samp0,uv4.wz)) / 9.0f;\n"
"} else {\n"
"texcol = tex2D(samp0,uv4.wz);\n"
"}\n"
"texcol = (tex2D(samp0,uv0) + tex2D(samp0,uv1) + tex2D(samp0,uv2) + tex2D(samp0,uv3))*0.25f;\n"
"ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n"
"}\n",C_COLORMATRIX);
s_FSAAColorMatrixProgram = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog));

View File

@ -62,8 +62,6 @@ static int s_backbuffer_height;
static float xScale;
static float yScale;
static bool AUTO_ADJUST_RENDERTARGET_SIZE = false;
static int s_recordWidth;
static int s_recordHeight;
@ -71,6 +69,8 @@ static bool s_LastFrameDumped;
static bool s_AVIDumping;
static u32 s_blendMode;
static u32 s_LastAA;
char st[32768];
@ -281,13 +281,26 @@ bool Renderer::Init()
// TODO: Grab target width from configured resolution?
s_target_width = s_backbuffer_width;
s_target_height = s_backbuffer_height * ((float)EFB_HEIGHT / 480.0f);
s_LastAA = g_ActiveConfig.iMultisampleMode % 2;
switch (s_LastAA)
{
case 1:
s_target_width = (s_target_width * 3) / 2;
s_target_height = (s_target_height *3) / 2;
break;
case 2:
s_target_width *= 2;
s_target_height *= 2;
break;
default:
break;
};
xScale = (float)s_target_width / (float)EFB_WIDTH;
yScale = (float)s_target_height / (float)EFB_HEIGHT;
s_Fulltarget_width = s_target_width;
s_Fulltarget_height = s_target_height;
//apply automatic resizing only is not an ati card, ati can handle large viewports :)
AUTO_ADJUST_RENDERTARGET_SIZE = true;//!D3D::IsATIDevice();
s_LastFrameDumped = false;
s_AVIDumping = false;
@ -565,13 +578,9 @@ static void EFBTextureToD3DBackBuffer(const EFBRectangle& sourceRc)
D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
D3D::ChangeSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
if(g_ActiveConfig.iMultisampleMode != 0 )
if(g_ActiveConfig.iMultisampleMode > 2 )
{
D3D::ChangeSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_POINT);
D3D::ChangeSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
D3D::drawFSAATexQuad(read_texture,FBManager::GetEFBDepthTexture(efbRect),&sourcerect,Renderer::GetFullTargetWidth(),Renderer::GetFullTargetHeight(),PixelShaderCache::GetFSAAProgram(),VertexShaderCache::GetFSAAVertexShader(),g_ActiveConfig.iMultisampleMode,xfregs.rawViewport[2]);
D3D::RefreshSamplerState(1, D3DSAMP_MINFILTER);
D3D::RefreshSamplerState(1, D3DSAMP_MAGFILTER);
D3D::drawShadedTexQuad(read_texture,&sourcerect,Renderer::GetFullTargetWidth(),Renderer::GetFullTargetHeight(),PixelShaderCache::GetFSAAProgram(),VertexShaderCache::GetFSAAVertexShader());
}
else
{
@ -987,40 +996,37 @@ void UpdateViewport()
Y += Height;
Height *= -1;
}
if(AUTO_ADJUST_RENDERTARGET_SIZE)
bool sizeChanged = false;
if(X < 0)
{
bool sizeChanged = false;
if(X < 0)
{
s_Fulltarget_width -= 2 * X;
X = 0;
sizeChanged=true;
}
if(Y < 0)
{
s_Fulltarget_height -= 2 * Y;
Y = 0;
sizeChanged=true;
}
if(X + Width > s_Fulltarget_width)
{
s_Fulltarget_width += (X + Width - s_Fulltarget_width) * 2;
sizeChanged=true;
}
if(Y + Height > s_Fulltarget_height)
{
s_Fulltarget_height += (Y + Height - s_Fulltarget_height) * 2;
sizeChanged=true;
}
if(sizeChanged)
{
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface());
FBManager::Destroy();
FBManager::Create();
D3D::dev->SetRenderTarget(0, FBManager::GetEFBColorRTSurface());
D3D::dev->SetDepthStencilSurface(FBManager::GetEFBDepthRTSurface());
}
s_Fulltarget_width -= 2 * X;
X = 0;
sizeChanged=true;
}
if(Y < 0)
{
s_Fulltarget_height -= 2 * Y;
Y = 0;
sizeChanged=true;
}
if(X + Width > s_Fulltarget_width)
{
s_Fulltarget_width += (X + Width - s_Fulltarget_width) * 2;
sizeChanged=true;
}
if(Y + Height > s_Fulltarget_height)
{
s_Fulltarget_height += (Y + Height - s_Fulltarget_height) * 2;
sizeChanged=true;
}
if(sizeChanged)
{
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface());
FBManager::Destroy();
FBManager::Create();
D3D::dev->SetRenderTarget(0, FBManager::GetEFBColorRTSurface());
D3D::dev->SetDepthStencilSurface(FBManager::GetEFBDepthRTSurface());
}
vp.X = X;
vp.Y = Y;
@ -1126,6 +1132,37 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight)
CheckForResize();
u32 newAA = g_ActiveConfig.iMultisampleMode % 2;
if(newAA != s_LastAA)
{
s_target_width = s_backbuffer_width;
s_target_height = s_backbuffer_height * ((float)EFB_HEIGHT / 480.0f);
s_LastAA = newAA;
switch (s_LastAA)
{
case 1:
s_target_width = (s_target_width * 3) / 2;
s_target_height = (s_target_height *3) / 2;
break;
case 2:
s_target_width *= 2;
s_target_height *= 2;
break;
default:
break;
};
xScale = (float)s_target_width / (float)EFB_WIDTH;
yScale = (float)s_target_height / (float)EFB_HEIGHT;
s_Fulltarget_width = s_target_width;
s_Fulltarget_height = s_target_height;
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface());
FBManager::Destroy();
FBManager::Create();
D3D::dev->SetRenderTarget(0, FBManager::GetEFBColorRTSurface());
D3D::dev->SetDepthStencilSurface(FBManager::GetEFBDepthRTSurface());
}
// ---------------------------------------------------------------------
// Count FPS.
// -------------

View File

@ -525,22 +525,14 @@ have_texture:
D3DFORMAT bformat = FBManager::GetEFBDepthRTSurfaceFormat();
if(!bFromZBuffer && g_ActiveConfig.iMultisampleMode != 0)
if(!bFromZBuffer && g_ActiveConfig.iMultisampleMode > 2)
{
D3D::ChangeSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_POINT);
D3D::ChangeSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
D3D::drawFSAATexQuad(
read_texture,
FBManager::GetEFBDepthTexture(source_rect),
D3D::drawShadedTexQuad(read_texture,
&sourcerect,
Renderer::GetFullTargetWidth() ,
Renderer::GetFullTargetHeight(),
PixelShaderCache::GetFSAAColorMatrixProgram(),
VertexShaderCache::GetFSAAVertexShader(),
g_ActiveConfig.iMultisampleMode,1.0f);
D3D::RefreshSamplerState(1, D3DSAMP_MINFILTER);
D3D::RefreshSamplerState(1, D3DSAMP_MAGFILTER);
D3D::SetTexture(1,NULL);
VertexShaderCache::GetFSAAVertexShader());
}
else
{

View File

@ -175,29 +175,18 @@ void VertexShaderCache::Init()
sprintf(vFSAAProg, "struct VSOUTPUT\n"
"{\n"
"float4 vPosition : POSITION;\n"
"float4 vColor0 : COLOR0;\n"
"float4 vTexCoord : TEXCOORD0;\n"
"float4 vTexCoord1 : TEXCOORD1;\n"
"float4 vTexCoord2 : TEXCOORD2;\n"
"float4 vTexCoord3 : TEXCOORD3;\n"
"float4 vTexCoord4 : TEXCOORD4;\n"
"float2 vTexCoord5 : TEXCOORD5;\n"
"float2 vTexCoord6 : TEXCOORD6;\n"
"float2 vTexCoord7 : TEXCOORD7;\n"
"float2 vTexCoord : TEXCOORD0;\n"
"float2 vTexCoord1 : TEXCOORD1;\n"
"float2 vTexCoord2 : TEXCOORD2;\n"
"float2 vTexCoord3 : TEXCOORD3;\n"
"};\n"
"void main( out VSOUTPUT OUT,in float4 inPosition : POSITION,in float2 inTEX0 : TEXCOORD0,in float2 inTEX1 : TEXCOORD1,in float2 inTEX2 : TEXCOORD2)\n"
"void main( out VSOUTPUT OUT,in float4 inPosition : POSITION,in float2 inTEX0 : TEXCOORD0,in float2 inTEX1 : TEXCOORD1)\n"
"{\n"
"OUT.vPosition = inPosition;\n"
"OUT.vColor0 = float4(inTEX2.x / inTEX2.y,0.0f,0.0f,0.0f);\n"
"OUT.vTexCoord = inTEX0.xyyx + (float4(-1.0f,-1.0f,-0.45f,-0.45f) * inTEX1.xyyx);\n"
"OUT.vTexCoord1 = inTEX0.xyyx + (float4( 0.0f,-1.0f,-0.45f, 0.45f) * inTEX1.xyyx);\n"
"OUT.vTexCoord2 = inTEX0.xyyx + (float4( 1.0f,-1.0f, 0.45f,-0.45f) * inTEX1.xyyx);\n"
"OUT.vTexCoord3 = inTEX0.xyyx + (float4(-1.0f, 1.0f, 0.45f, 0.45f) * inTEX1.xyyx);\n"
"OUT.vTexCoord4 = inTEX0.xyyx + (float4( 0.0f, 1.0f, 0.0f, 0.0f) * inTEX1.xyyx);\n"
"OUT.vTexCoord5 = inTEX0 + (float2( 1.0f, 1.0f) * inTEX1);\n"
"OUT.vTexCoord6 = inTEX0 + (float2( 1.0f, 0.0f) * inTEX1);\n"
"OUT.vTexCoord7 = inTEX0 + (float2(-1.0f, 0.0f) * inTEX1);\n"
"OUT.vTexCoord = inTEX0 + (float2(-0.1830127f,-0.6830127f) * inTEX1);\n"
"OUT.vTexCoord1 = inTEX0 + (float2(-0.6830127f, 0.1830127f) * inTEX1);\n"
"OUT.vTexCoord2 = inTEX0 + (float2( 0.6830127f,-0.1830127f) * inTEX1);\n"
"OUT.vTexCoord3 = inTEX0 + (float2( 0.1830127f, 0.6830127f) * inTEX1);\n"
"}\n");
FSAAVertexShader = D3D::CompileAndCreateVertexShader(vFSAAProg, (int)strlen(vFSAAProg));