Files
pcsx2/plugins/GSdx/GSTextureFX9.cpp
T
Akash 3c9ca799a6 Remove anisotropic filtering checkbox value.
Removes the checkbox of Anisotropic filtering from the GSDX plugin settings, the checkbox was usually used to enable & disable the AF which is not necessary since there is an option in the drop down list for disabling AF.
the internal function value of "AnisotropicFiltering" has been replaced with "MaxAnisotropy" for detection.
the detection uses the function getconfig("MaxAnisotropy", value)  where value 0 means disabled and value is the default value when no value is set in the INI file.
2015-08-21 09:45:00 +05:30

342 lines
8.9 KiB
C++

/*
* Copyright (C) 2007-2009 Gabest
* http://www.gabest.org
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "stdafx.h"
#include "GSDevice9.h"
#include "resource.h"
#include "GSTables.h"
GSTexture* GSDevice9::CreateMskFix(uint32 size, uint32 msk, uint32 fix)
{
GSTexture* t = NULL;
uint32 hash = (size << 20) | (msk << 10) | fix;
hash_map<uint32, GSTexture*>::iterator i = m_mskfix.find(hash);
if(i != m_mskfix.end())
{
t = i->second;
}
else
{
t = CreateTexture(size, 1, D3DFMT_R32F);
if(t)
{
GSTexture::GSMap m;
if(t->Map(m))
{
for(uint32 i = 0; i < size; i++)
{
((float*)m.bits)[i] = (float)((i & msk) | fix) / size;
}
t->Unmap();
}
m_mskfix[hash] = t;
}
}
return t;
}
void GSDevice9::SetupVS(VSSelector sel, const VSConstantBuffer* cb)
{
hash_map<uint32, GSVertexShader9>::const_iterator i = m_vs.find(sel);
if(i == m_vs.end())
{
string str[5];
str[0] = format("%d", sel.bppz);
str[1] = format("%d", sel.tme);
str[2] = format("%d", sel.fst);
str[3] = format("%d", sel.logz);
str[4] = format("%d", sel.rtcopy);
D3DXMACRO macro[] =
{
{"VS_BPPZ", str[0].c_str()},
{"VS_TME", str[1].c_str()},
{"VS_FST", str[2].c_str()},
{"VS_LOGZ", str[3].c_str()},
{"VS_RTCOPY", str[4].c_str()},
{NULL, NULL},
};
static const D3DVERTEXELEMENT9 layout[] =
{
{0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
{0, 8, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
{0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
{0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
D3DDECL_END()
};
GSVertexShader9 vs;
CompileShader(IDR_TFX_FX, "vs_main", macro, &vs.vs, layout, countof(layout), &vs.il);
m_vs[sel] = vs;
i = m_vs.find(sel);
}
VSSetShader(i->second.vs, (const float*)cb, sizeof(*cb) / sizeof(GSVector4));
IASetInputLayout(i->second.il);
}
void GSDevice9::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel)
{
if(cb->WH.z > 0 && cb->WH.w > 0 && (sel.wms == 3 || sel.wmt == 3))
{
GSVector4i size(cb->WH);
if(sel.wms == 3)
{
if(GSTexture* t = CreateMskFix(size.z, cb->MskFix.x, cb->MskFix.z))
{
m_dev->SetTexture(3, *(GSTexture9*)t);
}
}
if(sel.wmt == 3)
{
if(GSTexture* t = CreateMskFix(size.w, cb->MskFix.y, cb->MskFix.w))
{
m_dev->SetTexture(4, *(GSTexture9*)t);
}
}
}
hash_map<uint32, CComPtr<IDirect3DPixelShader9> >::const_iterator i = m_ps.find(sel);
if(i == m_ps.end())
{
string str[17];
str[0] = format("%d", sel.fst);
str[1] = format("%d", sel.wms);
str[2] = format("%d", sel.wmt);
str[3] = format("%d", sel.fmt);
str[4] = format("%d", sel.aem);
str[5] = format("%d", sel.tfx);
str[6] = format("%d", sel.tcc);
str[7] = format("%d", sel.atst);
str[8] = format("%d", sel.fog);
str[9] = format("%d", sel.clr1);
str[10] = format("%d", sel.rt);
str[11] = format("%d", sel.ltf);
str[12] = format("%d", sel.colclip);
str[13] = format("%d", sel.date);
str[14] = format("%d", sel.spritehack);
str[15] = format("%d", sel.tcoffsethack);
str[16] = format("%d", sel.point_sampler);
D3DXMACRO macro[] =
{
{"PS_FST", str[0].c_str()},
{"PS_WMS", str[1].c_str()},
{"PS_WMT", str[2].c_str()},
{"PS_FMT", str[3].c_str()},
{"PS_AEM", str[4].c_str()},
{"PS_TFX", str[5].c_str()},
{"PS_TCC", str[6].c_str()},
{"PS_ATST", str[7].c_str()},
{"PS_FOG", str[8].c_str()},
{"PS_CLR1", str[9].c_str()},
{"PS_RT", str[10].c_str()},
{"PS_LTF", str[11].c_str()},
{"PS_COLCLIP", str[12].c_str()},
{"PS_DATE", str[13].c_str()},
{"PS_SPRITEHACK", str[14].c_str()},
{"PS_TCOFFSETHACK", str[15].c_str()},
{"PS_POINT_SAMPLER", str[16].c_str()},
{NULL, NULL},
};
CComPtr<IDirect3DPixelShader9> ps;
CompileShader(IDR_TFX_FX, "ps_main", macro, &ps);
m_ps[sel] = ps;
i = m_ps.find(sel);
}
PSSetShader(i->second, (const float*)cb, sizeof(*cb) / sizeof(GSVector4));
Direct3DSamplerState9* ss = NULL;
if(sel.tfx != 4)
{
if(!(sel.fmt < 3 && sel.wms < 3 && sel.wmt < 3))
{
ssel.ltf = 0;
}
hash_map<uint32, Direct3DSamplerState9* >::const_iterator i = m_ps_ss.find(ssel);
if(i != m_ps_ss.end())
{
ss = i->second;
}
else
{
ss = new Direct3DSamplerState9();
memset(ss, 0, sizeof(*ss));
ss->Anisotropic[0] = theApp.GetConfig("MaxAnisotropy", 0) && !theApp.GetConfig("paltex", 0) ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR;
ss->Anisotropic[1] = theApp.GetConfig("MaxAnisotropy", 0) && !theApp.GetConfig("paltex", 0) ? D3DTEXF_ANISOTROPIC : D3DTEXF_POINT;
ss->FilterMin[0] = ssel.ltf ? ss->Anisotropic[0] : D3DTEXF_POINT;
ss->FilterMag[0] = ssel.ltf ? ss->Anisotropic[0] : D3DTEXF_POINT;
ss->FilterMip[0] = ssel.ltf ? ss->Anisotropic[0] : D3DTEXF_POINT;
ss->FilterMin[1] = ss->Anisotropic[1];
ss->FilterMag[1] = ss->Anisotropic[1];
ss->FilterMip[1] = ss->Anisotropic[1];
ss->AddressU = ssel.tau ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP;
ss->AddressV = ssel.tav ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP;
ss->MaxAnisotropy = theApp.GetConfig("MaxAnisotropy", 0);
ss->MaxLOD = ULONG_MAX;
m_ps_ss[ssel] = ss;
}
}
PSSetSamplerState(ss);
}
void GSDevice9::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix)
{
Direct3DDepthStencilState9* dss = NULL;
hash_map<uint32, Direct3DDepthStencilState9*>::const_iterator i = m_om_dss.find(dssel);
if(i == m_om_dss.end())
{
dss = new Direct3DDepthStencilState9();
memset(dss, 0, sizeof(*dss));
if(dssel.date || dssel.fba)
{
dss->StencilEnable = true;
dss->StencilReadMask = 1;
dss->StencilWriteMask = dssel.alpha_stencil ? 3 : 2;
dss->StencilFunc = dssel.date ? D3DCMP_EQUAL : D3DCMP_ALWAYS;
dss->StencilPassOp = dssel.alpha_stencil ? D3DSTENCILOP_ZERO : dssel.fba ? D3DSTENCILOP_REPLACE : D3DSTENCILOP_KEEP;
dss->StencilFailOp = dssel.fba && !dssel.alpha_stencil ? D3DSTENCILOP_ZERO : D3DSTENCILOP_KEEP;
dss->StencilDepthFailOp = D3DSTENCILOP_KEEP;
dss->StencilRef = 3;
}
if(dssel.ztst != ZTST_ALWAYS || dssel.zwe)
{
static const D3DCMPFUNC ztst[] =
{
D3DCMP_NEVER,
D3DCMP_ALWAYS,
D3DCMP_GREATEREQUAL,
D3DCMP_GREATER
};
dss->DepthEnable = true;
dss->DepthWriteMask = dssel.zwe;
dss->DepthFunc = ztst[dssel.ztst];
}
m_om_dss[dssel] = dss;
i = m_om_dss.find(dssel);
}
OMSetDepthStencilState(i->second);
hash_map<uint32, Direct3DBlendState9*>::const_iterator j = m_om_bs.find(bsel);
if(j == m_om_bs.end())
{
Direct3DBlendState9* bs = new Direct3DBlendState9();
memset(bs, 0, sizeof(*bs));
bs->BlendEnable = bsel.abe;
if(bsel.abe)
{
int i = ((bsel.a * 3 + bsel.b) * 3 + bsel.c) * 3 + bsel.d;
bs->BlendOp = (D3DBLENDOP)m_blendMapD3D9[i].op;
bs->SrcBlend = (D3DBLEND)m_blendMapD3D9[i].src;
bs->DestBlend = (D3DBLEND)m_blendMapD3D9[i].dst;
bs->BlendOpAlpha = D3DBLENDOP_ADD;
bs->SrcBlendAlpha = D3DBLEND_ONE;
bs->DestBlendAlpha = D3DBLEND_ZERO;
// Not very good but I don't wanna write another 81 row table
if(bsel.negative)
{
if(bs->BlendOp == D3DBLENDOP_ADD)
{
bs->BlendOp = D3DBLENDOP_REVSUBTRACT;
}
else if(bs->BlendOp == D3DBLENDOP_REVSUBTRACT)
{
bs->BlendOp = D3DBLENDOP_ADD;
}
else
; // god knows, best just not to mess with it for now
}
if(m_blendMapD3D9[i].bogus == 1)
{
(bsel.a == 0 ? bs->SrcBlend : bs->DestBlend) = D3DBLEND_ONE;
const string afixstr = format("%d >> 7", afix);
const char *col[3] = {"Cs", "Cd", "0"};
const char *alpha[3] = {"As", "Ad", afixstr.c_str()};
printf("Impossible blend for D3D: (%s - %s) * %s + %s\n", col[bsel.a], col[bsel.b], alpha[bsel.c], col[bsel.d]);
}
}
// this is not a typo; dx9 uses BGRA rather than the gs native RGBA, unlike dx10
if(bsel.wr) bs->RenderTargetWriteMask |= D3DCOLORWRITEENABLE_BLUE;
if(bsel.wg) bs->RenderTargetWriteMask |= D3DCOLORWRITEENABLE_GREEN;
if(bsel.wb) bs->RenderTargetWriteMask |= D3DCOLORWRITEENABLE_RED;
if(bsel.wa) bs->RenderTargetWriteMask |= D3DCOLORWRITEENABLE_ALPHA;
m_om_bs[bsel] = bs;
j = m_om_bs.find(bsel);
}
OMSetBlendState(j->second, afix >= 0x80 ? 0xffffff : 0x020202 * afix);
}