mirror of https://github.com/PCSX2/pcsx2.git
GSdx: Unscale Point and Line Direct3D11 port
Ports the "Unscale Point and Line" hack to the Direct3D11 Hardware renderer. And enables the "Unscale Point and Line" hack for Custom Resolutions with Direct3D11 and OpenGL.
This commit is contained in:
parent
117c249595
commit
557b672232
|
@ -30,13 +30,20 @@ GSDevice11::GSDevice11()
|
||||||
{
|
{
|
||||||
memset(&m_state, 0, sizeof(m_state));
|
memset(&m_state, 0, sizeof(m_state));
|
||||||
memset(&m_vs_cb_cache, 0, sizeof(m_vs_cb_cache));
|
memset(&m_vs_cb_cache, 0, sizeof(m_vs_cb_cache));
|
||||||
|
memset(&m_gs_cb_cache, 0, sizeof(m_gs_cb_cache));
|
||||||
memset(&m_ps_cb_cache, 0, sizeof(m_ps_cb_cache));
|
memset(&m_ps_cb_cache, 0, sizeof(m_ps_cb_cache));
|
||||||
|
|
||||||
FXAA_Compiled = false;
|
FXAA_Compiled = false;
|
||||||
ExShader_Compiled = false;
|
ExShader_Compiled = false;
|
||||||
|
|
||||||
m_state.topology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
|
m_state.topology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
|
||||||
m_state.bf = -1;
|
m_state.bf = -1;
|
||||||
|
|
||||||
|
if (theApp.GetConfigB("UserHacks")) {
|
||||||
|
UserHacks_unscale_pt_ln = theApp.GetConfigB("UserHacks_unscale_point_line");
|
||||||
|
} else {
|
||||||
|
UserHacks_unscale_pt_ln = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GSDevice11::~GSDevice11()
|
GSDevice11::~GSDevice11()
|
||||||
|
@ -699,7 +706,7 @@ void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture*
|
||||||
//sel.prim = 2; //Triangle Strip
|
//sel.prim = 2; //Triangle Strip
|
||||||
//SetupGS(sel);
|
//SetupGS(sel);
|
||||||
|
|
||||||
GSSetShader(NULL);
|
GSSetShader(NULL, NULL);
|
||||||
|
|
||||||
/*END OF HACK*/
|
/*END OF HACK*/
|
||||||
|
|
||||||
|
@ -895,7 +902,7 @@ void GSDevice11::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* vert
|
||||||
|
|
||||||
// gs
|
// gs
|
||||||
|
|
||||||
GSSetShader(NULL);
|
GSSetShader(NULL, NULL);
|
||||||
|
|
||||||
// ps
|
// ps
|
||||||
|
|
||||||
|
@ -1105,7 +1112,7 @@ void GSDevice11::VSSetShader(ID3D11VertexShader* vs, ID3D11Buffer* vs_cb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDevice11::GSSetShader(ID3D11GeometryShader* gs)
|
void GSDevice11::GSSetShader(ID3D11GeometryShader* gs, ID3D11Buffer* gs_cb)
|
||||||
{
|
{
|
||||||
if(m_state.gs != gs)
|
if(m_state.gs != gs)
|
||||||
{
|
{
|
||||||
|
@ -1113,6 +1120,13 @@ void GSDevice11::GSSetShader(ID3D11GeometryShader* gs)
|
||||||
|
|
||||||
m_ctx->GSSetShader(gs, NULL, 0);
|
m_ctx->GSSetShader(gs, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_state.gs_cb != gs_cb)
|
||||||
|
{
|
||||||
|
m_state.gs_cb = gs_cb;
|
||||||
|
|
||||||
|
m_ctx->GSSetConstantBuffers(0, 1, &gs_cb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDevice11::PSSetShaderResources(GSTexture* sr0, GSTexture* sr1)
|
void GSDevice11::PSSetShaderResources(GSTexture* sr0, GSTexture* sr1)
|
||||||
|
|
|
@ -57,6 +57,8 @@ class GSDevice11 : public GSDeviceDX
|
||||||
int spritehack;
|
int spritehack;
|
||||||
bool isNative;
|
bool isNative;
|
||||||
|
|
||||||
|
bool UserHacks_unscale_pt_ln;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
ID3D11Buffer* vb;
|
ID3D11Buffer* vb;
|
||||||
|
@ -67,6 +69,7 @@ class GSDevice11 : public GSDeviceDX
|
||||||
ID3D11VertexShader* vs;
|
ID3D11VertexShader* vs;
|
||||||
ID3D11Buffer* vs_cb;
|
ID3D11Buffer* vs_cb;
|
||||||
ID3D11GeometryShader* gs;
|
ID3D11GeometryShader* gs;
|
||||||
|
ID3D11Buffer* gs_cb;
|
||||||
ID3D11ShaderResourceView* ps_srv[16];
|
ID3D11ShaderResourceView* ps_srv[16];
|
||||||
ID3D11PixelShader* ps;
|
ID3D11PixelShader* ps;
|
||||||
ID3D11Buffer* ps_cb;
|
ID3D11Buffer* ps_cb;
|
||||||
|
@ -145,6 +148,7 @@ public: // TODO
|
||||||
hash_map<uint32, GSVertexShader11 > m_vs;
|
hash_map<uint32, GSVertexShader11 > m_vs;
|
||||||
CComPtr<ID3D11Buffer> m_vs_cb;
|
CComPtr<ID3D11Buffer> m_vs_cb;
|
||||||
hash_map<uint32, CComPtr<ID3D11GeometryShader> > m_gs;
|
hash_map<uint32, CComPtr<ID3D11GeometryShader> > m_gs;
|
||||||
|
CComPtr<ID3D11Buffer> m_gs_cb;
|
||||||
hash_map<uint64, CComPtr<ID3D11PixelShader> > m_ps;
|
hash_map<uint64, CComPtr<ID3D11PixelShader> > m_ps;
|
||||||
CComPtr<ID3D11Buffer> m_ps_cb;
|
CComPtr<ID3D11Buffer> m_ps_cb;
|
||||||
hash_map<uint32, CComPtr<ID3D11SamplerState> > m_ps_ss;
|
hash_map<uint32, CComPtr<ID3D11SamplerState> > m_ps_ss;
|
||||||
|
@ -154,6 +158,7 @@ public: // TODO
|
||||||
hash_map<uint32, CComPtr<ID3D11BlendState> > m_om_bs;
|
hash_map<uint32, CComPtr<ID3D11BlendState> > m_om_bs;
|
||||||
|
|
||||||
VSConstantBuffer m_vs_cb_cache;
|
VSConstantBuffer m_vs_cb_cache;
|
||||||
|
GSConstantBuffer m_gs_cb_cache;
|
||||||
PSConstantBuffer m_ps_cb_cache;
|
PSConstantBuffer m_ps_cb_cache;
|
||||||
|
|
||||||
bool CreateTextureFX();
|
bool CreateTextureFX();
|
||||||
|
@ -202,7 +207,7 @@ public:
|
||||||
void IASetInputLayout(ID3D11InputLayout* layout);
|
void IASetInputLayout(ID3D11InputLayout* layout);
|
||||||
void IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY topology);
|
void IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY topology);
|
||||||
void VSSetShader(ID3D11VertexShader* vs, ID3D11Buffer* vs_cb);
|
void VSSetShader(ID3D11VertexShader* vs, ID3D11Buffer* vs_cb);
|
||||||
void GSSetShader(ID3D11GeometryShader* gs);
|
void GSSetShader(ID3D11GeometryShader* gs, ID3D11Buffer* gs_cb = NULL);
|
||||||
void PSSetShaderResources(GSTexture* sr0, GSTexture* sr1);
|
void PSSetShaderResources(GSTexture* sr0, GSTexture* sr1);
|
||||||
void PSSetShaderResource(int i, GSTexture* sr);
|
void PSSetShaderResource(int i, GSTexture* sr);
|
||||||
void PSSetShaderResourceView(int i, ID3D11ShaderResourceView* srv);
|
void PSSetShaderResourceView(int i, ID3D11ShaderResourceView* srv);
|
||||||
|
@ -217,7 +222,7 @@ public:
|
||||||
void OMSetRenderTargets(const GSVector2i& rtsize, int count, ID3D11UnorderedAccessView** uav, uint32* counters, const GSVector4i* scissor = NULL);
|
void OMSetRenderTargets(const GSVector2i& rtsize, int count, ID3D11UnorderedAccessView** uav, uint32* counters, const GSVector4i* scissor = NULL);
|
||||||
|
|
||||||
void SetupVS(VSSelector sel, const VSConstantBuffer* cb);
|
void SetupVS(VSSelector sel, const VSConstantBuffer* cb);
|
||||||
void SetupGS(GSSelector sel);
|
void SetupGS(GSSelector sel, const GSConstantBuffer* cb);
|
||||||
void SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel);
|
void SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel);
|
||||||
void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix);
|
void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix);
|
||||||
|
|
||||||
|
|
|
@ -241,7 +241,7 @@ public:
|
||||||
void CompileShader(const char *source, size_t size, const char *filename, const string& entry, const D3D_SHADER_MACRO* macro, IDirect3DPixelShader9** ps);
|
void CompileShader(const char *source, size_t size, const char *filename, const string& entry, const D3D_SHADER_MACRO* macro, IDirect3DPixelShader9** ps);
|
||||||
|
|
||||||
void SetupVS(VSSelector sel, const VSConstantBuffer* cb);
|
void SetupVS(VSSelector sel, const VSConstantBuffer* cb);
|
||||||
void SetupGS(GSSelector sel) {}
|
void SetupGS(GSSelector sel, const GSConstantBuffer* cb) {}
|
||||||
void SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel);
|
void SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel);
|
||||||
void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix);
|
void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix);
|
||||||
|
|
||||||
|
|
|
@ -125,6 +125,21 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct alignas(32) GSConstantBuffer
|
||||||
|
{
|
||||||
|
GSVector2 PointSize;
|
||||||
|
|
||||||
|
struct GSConstantBuffer()
|
||||||
|
{
|
||||||
|
PointSize = GSVector2(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
__forceinline bool Update(const GSConstantBuffer* cb)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct GSSelector
|
struct GSSelector
|
||||||
{
|
{
|
||||||
union
|
union
|
||||||
|
@ -133,14 +148,19 @@ public:
|
||||||
{
|
{
|
||||||
uint32 iip:1;
|
uint32 iip:1;
|
||||||
uint32 prim:2;
|
uint32 prim:2;
|
||||||
|
uint32 point:1;
|
||||||
|
uint32 line:1;
|
||||||
|
|
||||||
|
uint32 _free:27;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32 key;
|
uint32 key;
|
||||||
};
|
};
|
||||||
|
|
||||||
operator uint32() {return key & 0x7;}
|
operator uint32() {return key;}
|
||||||
|
|
||||||
GSSelector() : key(0) {}
|
GSSelector() : key(0) {}
|
||||||
|
GSSelector(uint32 k) : key(k) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PSSelector
|
struct PSSelector
|
||||||
|
@ -286,7 +306,7 @@ public:
|
||||||
void GetFeatureLevel(D3D_FEATURE_LEVEL& level) const {level = m_shader.level;}
|
void GetFeatureLevel(D3D_FEATURE_LEVEL& level) const {level = m_shader.level;}
|
||||||
|
|
||||||
virtual void SetupVS(VSSelector sel, const VSConstantBuffer* cb) = 0;
|
virtual void SetupVS(VSSelector sel, const VSConstantBuffer* cb) = 0;
|
||||||
virtual void SetupGS(GSSelector sel) = 0;
|
virtual void SetupGS(GSSelector sel, const GSConstantBuffer* cb) = 0;
|
||||||
virtual void SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel) = 0;
|
virtual void SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel) = 0;
|
||||||
virtual void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix) = 0;
|
virtual void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix) = 0;
|
||||||
|
|
||||||
|
|
|
@ -52,48 +52,48 @@ GSRendererDX::~GSRendererDX()
|
||||||
|
|
||||||
void GSRendererDX::EmulateAtst(const int pass, const GSTextureCache::Source* tex)
|
void GSRendererDX::EmulateAtst(const int pass, const GSTextureCache::Source* tex)
|
||||||
{
|
{
|
||||||
static const uint32 inverted_atst[] = { ATST_ALWAYS, ATST_NEVER, ATST_GEQUAL, ATST_GREATER, ATST_NOTEQUAL, ATST_LESS, ATST_LEQUAL, ATST_EQUAL };
|
static const uint32 inverted_atst[] = {ATST_ALWAYS, ATST_NEVER, ATST_GEQUAL, ATST_GREATER, ATST_NOTEQUAL, ATST_LESS, ATST_LEQUAL, ATST_EQUAL};
|
||||||
int atst = (pass == 2) ? inverted_atst[m_context->TEST.ATST] : m_context->TEST.ATST;
|
int atst = (pass == 2) ? inverted_atst[m_context->TEST.ATST] : m_context->TEST.ATST;
|
||||||
|
|
||||||
if (!m_context->TEST.ATE) return;
|
if (!m_context->TEST.ATE) return;
|
||||||
|
|
||||||
switch (atst) {
|
switch (atst) {
|
||||||
case ATST_LESS:
|
case ATST_LESS:
|
||||||
if (tex && tex->m_spritehack_t) {
|
if (tex && tex->m_spritehack_t) {
|
||||||
m_ps_sel.atst = 0;
|
m_ps_sel.atst = 0;
|
||||||
}
|
} else {
|
||||||
else {
|
ps_cb.FogColor_AREF.a = (float)m_context->TEST.AREF - 0.1f;
|
||||||
ps_cb.FogColor_AREF.a = (float)m_context->TEST.AREF - 0.1f;
|
m_ps_sel.atst = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ATST_LEQUAL:
|
||||||
|
ps_cb.FogColor_AREF.a = (float)m_context->TEST.AREF - 0.1f + 1.0f;
|
||||||
m_ps_sel.atst = 1;
|
m_ps_sel.atst = 1;
|
||||||
}
|
break;
|
||||||
break;
|
case ATST_GEQUAL:
|
||||||
case ATST_LEQUAL:
|
// Maybe a -1 trick multiplication factor could be used to merge with ATST_LEQUAL case
|
||||||
ps_cb.FogColor_AREF.a = (float)m_context->TEST.AREF - 0.1f + 1.0f;
|
ps_cb.FogColor_AREF.a = (float)m_context->TEST.AREF - 0.1f;
|
||||||
m_ps_sel.atst = 1;
|
m_ps_sel.atst = 2;
|
||||||
break;
|
break;
|
||||||
case ATST_GEQUAL:
|
case ATST_GREATER:
|
||||||
// Maybe a -1 trick multiplication factor could be used to merge with ATST_LEQUAL case
|
// Maybe a -1 trick multiplication factor could be used to merge with ATST_LESS case
|
||||||
ps_cb.FogColor_AREF.a = (float)m_context->TEST.AREF - 0.1f;
|
ps_cb.FogColor_AREF.a = (float)m_context->TEST.AREF - 0.1f + 1.0f;
|
||||||
m_ps_sel.atst = 2;
|
m_ps_sel.atst = 2;
|
||||||
break;
|
break;
|
||||||
case ATST_GREATER:
|
case ATST_EQUAL:
|
||||||
// Maybe a -1 trick multiplication factor could be used to merge with ATST_LESS case
|
ps_cb.FogColor_AREF.a = (float)m_context->TEST.AREF;
|
||||||
ps_cb.FogColor_AREF.a = (float)m_context->TEST.AREF - 0.1f + 1.0f;
|
m_ps_sel.atst = 3;
|
||||||
m_ps_sel.atst = 2;
|
break;
|
||||||
break;
|
case ATST_NOTEQUAL:
|
||||||
case ATST_EQUAL:
|
ps_cb.FogColor_AREF.a = (float)m_context->TEST.AREF;
|
||||||
ps_cb.FogColor_AREF.a = (float)m_context->TEST.AREF;
|
m_ps_sel.atst = 4;
|
||||||
m_ps_sel.atst = 3;
|
break;
|
||||||
break;
|
|
||||||
case ATST_NOTEQUAL:
|
case ATST_NEVER: // Draw won't be done so no need to implement it in shader
|
||||||
ps_cb.FogColor_AREF.a = (float)m_context->TEST.AREF;
|
case ATST_ALWAYS:
|
||||||
m_ps_sel.atst = 4;
|
default:
|
||||||
break;
|
m_ps_sel.atst = 0;
|
||||||
case ATST_NEVER:
|
break;
|
||||||
case ATST_ALWAYS:
|
|
||||||
default:
|
|
||||||
m_ps_sel.atst = 0;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,10 +426,8 @@ void GSRendererDX::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sourc
|
||||||
|
|
||||||
// gs
|
// gs
|
||||||
|
|
||||||
GSDeviceDX::GSSelector gs_sel;
|
m_gs_sel.iip = PRIM->IIP;
|
||||||
|
m_gs_sel.prim = m_vt.m_primclass;
|
||||||
gs_sel.iip = PRIM->IIP;
|
|
||||||
gs_sel.prim = m_vt.m_primclass;
|
|
||||||
|
|
||||||
// ps
|
// ps
|
||||||
|
|
||||||
|
@ -629,11 +627,11 @@ void GSRendererDX::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sourc
|
||||||
|
|
||||||
uint8 afix = m_context->ALPHA.FIX;
|
uint8 afix = m_context->ALPHA.FIX;
|
||||||
|
|
||||||
SetupIA();
|
SetupIA(sx, sy);
|
||||||
|
|
||||||
dev->SetupOM(om_dssel, om_bsel, afix);
|
dev->SetupOM(om_dssel, om_bsel, afix);
|
||||||
dev->SetupVS(vs_sel, &vs_cb);
|
dev->SetupVS(vs_sel, &vs_cb);
|
||||||
dev->SetupGS(gs_sel);
|
dev->SetupGS(m_gs_sel, &gs_cb);
|
||||||
dev->SetupPS(m_ps_sel, &ps_cb, m_ps_ssel);
|
dev->SetupPS(m_ps_sel, &ps_cb, m_ps_ssel);
|
||||||
|
|
||||||
// draw
|
// draw
|
||||||
|
|
|
@ -38,7 +38,7 @@ protected:
|
||||||
void EmulateZbuffer();
|
void EmulateZbuffer();
|
||||||
void EmulateTextureSampler(const GSTextureCache::Source* tex);
|
void EmulateTextureSampler(const GSTextureCache::Source* tex);
|
||||||
virtual void DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex);
|
virtual void DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex);
|
||||||
virtual void SetupIA() = 0;
|
virtual void SetupIA(const float& sx, const float& sy) = 0;
|
||||||
virtual void UpdateFBA(GSTexture* rt) {}
|
virtual void UpdateFBA(GSTexture* rt) {}
|
||||||
|
|
||||||
unsigned int UserHacks_TCOffset;
|
unsigned int UserHacks_TCOffset;
|
||||||
|
@ -57,9 +57,11 @@ protected:
|
||||||
|
|
||||||
GSDeviceDX::PSSelector m_ps_sel;
|
GSDeviceDX::PSSelector m_ps_sel;
|
||||||
GSDeviceDX::PSSamplerSelector m_ps_ssel;
|
GSDeviceDX::PSSamplerSelector m_ps_ssel;
|
||||||
|
GSDeviceDX::GSSelector m_gs_sel;
|
||||||
|
|
||||||
GSDeviceDX::PSConstantBuffer ps_cb;
|
GSDeviceDX::PSConstantBuffer ps_cb;
|
||||||
GSDeviceDX::VSConstantBuffer vs_cb;
|
GSDeviceDX::VSConstantBuffer vs_cb;
|
||||||
|
GSDeviceDX::GSConstantBuffer gs_cb;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GSRendererDX(GSTextureCache* tc, const GSVector2& pixelcenter = GSVector2(0));
|
GSRendererDX(GSTextureCache* tc, const GSVector2& pixelcenter = GSVector2(0));
|
||||||
|
|
|
@ -27,6 +27,11 @@
|
||||||
GSRendererDX11::GSRendererDX11()
|
GSRendererDX11::GSRendererDX11()
|
||||||
: GSRendererDX(new GSTextureCache11(this), GSVector2(-0.5f))
|
: GSRendererDX(new GSTextureCache11(this), GSVector2(-0.5f))
|
||||||
{
|
{
|
||||||
|
if (theApp.GetConfigB("UserHacks")) {
|
||||||
|
UserHacks_unscale_pt_ln = theApp.GetConfigB("UserHacks_unscale_point_line");
|
||||||
|
} else {
|
||||||
|
UserHacks_unscale_pt_ln = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GSRendererDX11::CreateDevice(GSDevice* dev)
|
bool GSRendererDX11::CreateDevice(GSDevice* dev)
|
||||||
|
@ -37,10 +42,52 @@ bool GSRendererDX11::CreateDevice(GSDevice* dev)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSRendererDX11::SetupIA()
|
void GSRendererDX11::SetupIA(const float& sx, const float& sy)
|
||||||
{
|
{
|
||||||
GSDevice11* dev = (GSDevice11*)m_dev;
|
GSDevice11* dev = (GSDevice11*)m_dev;
|
||||||
|
|
||||||
|
D3D11_PRIMITIVE_TOPOLOGY t;
|
||||||
|
|
||||||
|
bool unscale_hack = UserHacks_unscale_pt_ln && (GetUpscaleMultiplier() != 1);
|
||||||
|
|
||||||
|
switch (m_vt.m_primclass)
|
||||||
|
{
|
||||||
|
case GS_POINT_CLASS:
|
||||||
|
if (unscale_hack) {
|
||||||
|
m_gs_sel.point = 1;
|
||||||
|
gs_cb.PointSize = GSVector2(16.0f * sx, 16.0f * sy);
|
||||||
|
}
|
||||||
|
|
||||||
|
t = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST;
|
||||||
|
break;
|
||||||
|
case GS_LINE_CLASS:
|
||||||
|
if (unscale_hack) {
|
||||||
|
m_gs_sel.line = 1;
|
||||||
|
gs_cb.PointSize = GSVector2(16.0f * sx, 16.0f * sy);
|
||||||
|
}
|
||||||
|
|
||||||
|
t = D3D11_PRIMITIVE_TOPOLOGY_LINELIST;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case GS_SPRITE_CLASS:
|
||||||
|
if (!m_vt.m_accurate_stq && m_vertex.next > 32) { // <=> 16 sprites (based on Shadow Hearts)
|
||||||
|
|
||||||
|
t = D3D11_PRIMITIVE_TOPOLOGY_LINELIST;
|
||||||
|
} else {
|
||||||
|
Lines2Sprites();
|
||||||
|
|
||||||
|
t = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GS_TRIANGLE_CLASS:
|
||||||
|
|
||||||
|
t = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
__assume(0);
|
||||||
|
}
|
||||||
|
|
||||||
void* ptr = NULL;
|
void* ptr = NULL;
|
||||||
|
|
||||||
if(dev->IAMapVertexBuffer(&ptr, sizeof(GSVertex), m_vertex.next))
|
if(dev->IAMapVertexBuffer(&ptr, sizeof(GSVertex), m_vertex.next))
|
||||||
|
@ -61,24 +108,5 @@ void GSRendererDX11::SetupIA()
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->IASetIndexBuffer(m_index.buff, m_index.tail);
|
dev->IASetIndexBuffer(m_index.buff, m_index.tail);
|
||||||
|
|
||||||
D3D11_PRIMITIVE_TOPOLOGY t;
|
|
||||||
|
|
||||||
switch(m_vt.m_primclass)
|
|
||||||
{
|
|
||||||
case GS_POINT_CLASS:
|
|
||||||
t = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST;
|
|
||||||
break;
|
|
||||||
case GS_LINE_CLASS:
|
|
||||||
case GS_SPRITE_CLASS:
|
|
||||||
t = D3D11_PRIMITIVE_TOPOLOGY_LINELIST;
|
|
||||||
break;
|
|
||||||
case GS_TRIANGLE_CLASS:
|
|
||||||
t = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
__assume(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
dev->IASetPrimitiveTopology(t);
|
dev->IASetPrimitiveTopology(t);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,10 @@
|
||||||
|
|
||||||
class GSRendererDX11 : public GSRendererDX
|
class GSRendererDX11 : public GSRendererDX
|
||||||
{
|
{
|
||||||
|
bool UserHacks_unscale_pt_ln;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void SetupIA();
|
void SetupIA(const float& sx, const float& sy);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GSRendererDX11();
|
GSRendererDX11();
|
||||||
|
|
|
@ -56,7 +56,7 @@ bool GSRendererDX9::CreateDevice(GSDevice* dev)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSRendererDX9::SetupIA()
|
void GSRendererDX9::SetupIA(const float& sx, const float& sy)
|
||||||
{
|
{
|
||||||
D3DPRIMITIVETYPE topology;
|
D3DPRIMITIVETYPE topology;
|
||||||
|
|
||||||
|
@ -106,62 +106,7 @@ void GSRendererDX9::SetupIA()
|
||||||
|
|
||||||
// each sprite converted to quad needs twice the space
|
// each sprite converted to quad needs twice the space
|
||||||
|
|
||||||
while(m_vertex.tail * 2 > m_vertex.maxcount)
|
Lines2Sprites();
|
||||||
{
|
|
||||||
GrowVertexBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
// assume vertices are tightly packed and sequentially indexed (it should be the case)
|
|
||||||
|
|
||||||
if(m_vertex.next >= 2)
|
|
||||||
{
|
|
||||||
size_t count = m_vertex.next;
|
|
||||||
|
|
||||||
int i = (int)count * 2 - 4;
|
|
||||||
GSVertex* s = &m_vertex.buff[count - 2];
|
|
||||||
GSVertex* q = &m_vertex.buff[count * 2 - 4];
|
|
||||||
uint32* RESTRICT index = &m_index.buff[count * 3 - 6];
|
|
||||||
|
|
||||||
for(; i >= 0; i -= 4, s -= 2, q -= 4, index -= 6)
|
|
||||||
{
|
|
||||||
GSVertex v0 = s[0];
|
|
||||||
GSVertex v1 = s[1];
|
|
||||||
|
|
||||||
v0.RGBAQ = v1.RGBAQ;
|
|
||||||
v0.XYZ.Z = v1.XYZ.Z;
|
|
||||||
v0.FOG = v1.FOG;
|
|
||||||
|
|
||||||
q[0] = v0;
|
|
||||||
q[3] = v1;
|
|
||||||
|
|
||||||
// swap x, s, u
|
|
||||||
|
|
||||||
uint16 x = v0.XYZ.X;
|
|
||||||
v0.XYZ.X = v1.XYZ.X;
|
|
||||||
v1.XYZ.X = x;
|
|
||||||
|
|
||||||
float s = v0.ST.S;
|
|
||||||
v0.ST.S = v1.ST.S;
|
|
||||||
v1.ST.S = s;
|
|
||||||
|
|
||||||
uint16 u = v0.U;
|
|
||||||
v0.U = v1.U;
|
|
||||||
v1.U = u;
|
|
||||||
|
|
||||||
q[1] = v0;
|
|
||||||
q[2] = v1;
|
|
||||||
|
|
||||||
index[0] = i + 0;
|
|
||||||
index[1] = i + 1;
|
|
||||||
index[2] = i + 2;
|
|
||||||
index[3] = i + 1;
|
|
||||||
index[4] = i + 2;
|
|
||||||
index[5] = i + 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_vertex.head = m_vertex.tail = m_vertex.next = count * 2;
|
|
||||||
m_index.tail = count * 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ protected:
|
||||||
Direct3DBlendState9 bs;
|
Direct3DBlendState9 bs;
|
||||||
} m_fba;
|
} m_fba;
|
||||||
|
|
||||||
void SetupIA();
|
void SetupIA(const float& sx, const float& sy);
|
||||||
void UpdateFBA(GSTexture* rt);
|
void UpdateFBA(GSTexture* rt);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -267,6 +267,83 @@ GSTexture* GSRendererHW::GetFeedbackOutput()
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GSRendererHW::Lines2Sprites()
|
||||||
|
{
|
||||||
|
ASSERT(m_vt.m_primclass == GS_SPRITE_CLASS);
|
||||||
|
|
||||||
|
// each sprite converted to quad needs twice the space
|
||||||
|
|
||||||
|
while (m_vertex.tail * 2 > m_vertex.maxcount)
|
||||||
|
{
|
||||||
|
GrowVertexBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
// assume vertices are tightly packed and sequentially indexed (it should be the case)
|
||||||
|
|
||||||
|
if (m_vertex.next >= 2)
|
||||||
|
{
|
||||||
|
size_t count = m_vertex.next;
|
||||||
|
|
||||||
|
int i = (int)count * 2 - 4;
|
||||||
|
GSVertex* s = &m_vertex.buff[count - 2];
|
||||||
|
GSVertex* q = &m_vertex.buff[count * 2 - 4];
|
||||||
|
uint32* RESTRICT index = &m_index.buff[count * 3 - 6];
|
||||||
|
|
||||||
|
for (; i >= 0; i -= 4, s -= 2, q -= 4, index -= 6)
|
||||||
|
{
|
||||||
|
GSVertex v0 = s[0];
|
||||||
|
GSVertex v1 = s[1];
|
||||||
|
|
||||||
|
v0.RGBAQ = v1.RGBAQ;
|
||||||
|
v0.XYZ.Z = v1.XYZ.Z;
|
||||||
|
v0.FOG = v1.FOG;
|
||||||
|
|
||||||
|
if (PRIM->TME && !PRIM->FST) {
|
||||||
|
GSVector4 st0 = GSVector4::loadl(&v0.ST.u64);
|
||||||
|
GSVector4 st1 = GSVector4::loadl(&v1.ST.u64);
|
||||||
|
GSVector4 Q = GSVector4(v1.RGBAQ.Q, v1.RGBAQ.Q, v1.RGBAQ.Q, v1.RGBAQ.Q);
|
||||||
|
GSVector4 st = st0.upld(st1) / Q;
|
||||||
|
|
||||||
|
GSVector4::storel(&v0.ST.u64, st);
|
||||||
|
GSVector4::storeh(&v1.ST.u64, st);
|
||||||
|
|
||||||
|
v0.RGBAQ.Q = 1.0f;
|
||||||
|
v1.RGBAQ.Q = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
q[0] = v0;
|
||||||
|
q[3] = v1;
|
||||||
|
|
||||||
|
// swap x, s, u
|
||||||
|
|
||||||
|
uint16 x = v0.XYZ.X;
|
||||||
|
v0.XYZ.X = v1.XYZ.X;
|
||||||
|
v1.XYZ.X = x;
|
||||||
|
|
||||||
|
float s = v0.ST.S;
|
||||||
|
v0.ST.S = v1.ST.S;
|
||||||
|
v1.ST.S = s;
|
||||||
|
|
||||||
|
uint16 u = v0.U;
|
||||||
|
v0.U = v1.U;
|
||||||
|
v1.U = u;
|
||||||
|
|
||||||
|
q[1] = v0;
|
||||||
|
q[2] = v1;
|
||||||
|
|
||||||
|
index[0] = i + 0;
|
||||||
|
index[1] = i + 1;
|
||||||
|
index[2] = i + 2;
|
||||||
|
index[3] = i + 1;
|
||||||
|
index[4] = i + 2;
|
||||||
|
index[5] = i + 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_vertex.head = m_vertex.tail = m_vertex.next = count * 2;
|
||||||
|
m_index.tail = count * 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GSVector4 GSRendererHW::RealignTargetTextureCoordinate(const GSTextureCache::Source* tex)
|
GSVector4 GSRendererHW::RealignTargetTextureCoordinate(const GSTextureCache::Source* tex)
|
||||||
{
|
{
|
||||||
if (m_userHacks_HPO <= 1 || GetUpscaleMultiplier() == 1) return GSVector4(0.0f);
|
if (m_userHacks_HPO <= 1 || GetUpscaleMultiplier() == 1) return GSVector4(0.0f);
|
||||||
|
|
|
@ -167,6 +167,7 @@ public:
|
||||||
GSVector2i GetCustomResolution();
|
GSVector2i GetCustomResolution();
|
||||||
void SetScaling();
|
void SetScaling();
|
||||||
GSVector4 RealignTargetTextureCoordinate(const GSTextureCache::Source* tex);
|
GSVector4 RealignTargetTextureCoordinate(const GSTextureCache::Source* tex);
|
||||||
|
void Lines2Sprites();
|
||||||
|
|
||||||
void Reset();
|
void Reset();
|
||||||
void VSync(int field);
|
void VSync(int field);
|
||||||
|
|
|
@ -61,83 +61,6 @@ bool GSRendererOGL::CreateDevice(GSDevice* dev)
|
||||||
return GSRenderer::CreateDevice(dev);
|
return GSRenderer::CreateDevice(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSRendererOGL::Lines2Sprites()
|
|
||||||
{
|
|
||||||
ASSERT(m_vt.m_primclass == GS_SPRITE_CLASS);
|
|
||||||
|
|
||||||
// each sprite converted to quad needs twice the space
|
|
||||||
|
|
||||||
while(m_vertex.tail * 2 > m_vertex.maxcount)
|
|
||||||
{
|
|
||||||
GrowVertexBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
// assume vertices are tightly packed and sequentially indexed (it should be the case)
|
|
||||||
|
|
||||||
if (m_vertex.next >= 2)
|
|
||||||
{
|
|
||||||
size_t count = m_vertex.next;
|
|
||||||
|
|
||||||
int i = (int)count * 2 - 4;
|
|
||||||
GSVertex* s = &m_vertex.buff[count - 2];
|
|
||||||
GSVertex* q = &m_vertex.buff[count * 2 - 4];
|
|
||||||
uint32* RESTRICT index = &m_index.buff[count * 3 - 6];
|
|
||||||
|
|
||||||
for(; i >= 0; i -= 4, s -= 2, q -= 4, index -= 6)
|
|
||||||
{
|
|
||||||
GSVertex v0 = s[0];
|
|
||||||
GSVertex v1 = s[1];
|
|
||||||
|
|
||||||
v0.RGBAQ = v1.RGBAQ;
|
|
||||||
v0.XYZ.Z = v1.XYZ.Z;
|
|
||||||
v0.FOG = v1.FOG;
|
|
||||||
|
|
||||||
if (PRIM->TME && !PRIM->FST) {
|
|
||||||
GSVector4 st0 = GSVector4::loadl(&v0.ST.u64);
|
|
||||||
GSVector4 st1 = GSVector4::loadl(&v1.ST.u64);
|
|
||||||
GSVector4 Q = GSVector4(v1.RGBAQ.Q, v1.RGBAQ.Q, v1.RGBAQ.Q, v1.RGBAQ.Q);
|
|
||||||
GSVector4 st = st0.upld(st1) / Q;
|
|
||||||
|
|
||||||
GSVector4::storel(&v0.ST.u64, st);
|
|
||||||
GSVector4::storeh(&v1.ST.u64, st);
|
|
||||||
|
|
||||||
v0.RGBAQ.Q = 1.0f;
|
|
||||||
v1.RGBAQ.Q = 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
q[0] = v0;
|
|
||||||
q[3] = v1;
|
|
||||||
|
|
||||||
// swap x, s, u
|
|
||||||
|
|
||||||
uint16 x = v0.XYZ.X;
|
|
||||||
v0.XYZ.X = v1.XYZ.X;
|
|
||||||
v1.XYZ.X = x;
|
|
||||||
|
|
||||||
float s = v0.ST.S;
|
|
||||||
v0.ST.S = v1.ST.S;
|
|
||||||
v1.ST.S = s;
|
|
||||||
|
|
||||||
uint16 u = v0.U;
|
|
||||||
v0.U = v1.U;
|
|
||||||
v1.U = u;
|
|
||||||
|
|
||||||
q[1] = v0;
|
|
||||||
q[2] = v1;
|
|
||||||
|
|
||||||
index[0] = i + 0;
|
|
||||||
index[1] = i + 1;
|
|
||||||
index[2] = i + 2;
|
|
||||||
index[3] = i + 1;
|
|
||||||
index[4] = i + 2;
|
|
||||||
index[5] = i + 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_vertex.head = m_vertex.tail = m_vertex.next = count * 2;
|
|
||||||
m_index.tail = count * 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GSRendererOGL::SetupIA(const float& sx, const float& sy)
|
void GSRendererOGL::SetupIA(const float& sx, const float& sy)
|
||||||
{
|
{
|
||||||
GL_PUSH("IA");
|
GL_PUSH("IA");
|
||||||
|
@ -151,7 +74,7 @@ void GSRendererOGL::SetupIA(const float& sx, const float& sy)
|
||||||
}
|
}
|
||||||
|
|
||||||
GLenum t = 0;
|
GLenum t = 0;
|
||||||
bool unscale_hack = UserHacks_unscale_pt_ln & (GetUpscaleMultiplier() > 1) & GLLoader::found_geometry_shader;
|
bool unscale_hack = UserHacks_unscale_pt_ln && (GetUpscaleMultiplier() != 1) && GLLoader::found_geometry_shader;
|
||||||
|
|
||||||
switch(m_vt.m_primclass)
|
switch(m_vt.m_primclass)
|
||||||
{
|
{
|
||||||
|
|
|
@ -75,7 +75,6 @@ class GSRendererOGL final : public GSRendererHW
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline void ResetStates();
|
inline void ResetStates();
|
||||||
inline void Lines2Sprites();
|
|
||||||
inline void SetupIA(const float& sx, const float& sy);
|
inline void SetupIA(const float& sx, const float& sy);
|
||||||
inline void EmulateTextureShuffleAndFbmask();
|
inline void EmulateTextureShuffleAndFbmask();
|
||||||
inline void EmulateChannelShuffle(GSTexture** rt, const GSTextureCache::Source* tex);
|
inline void EmulateChannelShuffle(GSTexture** rt, const GSTextureCache::Source* tex);
|
||||||
|
|
|
@ -720,9 +720,9 @@ void GSHacksDlg::OnInit()
|
||||||
EnableWindow(GetDlgItem(m_hWnd, IDC_TC_DEPTH), ogl);
|
EnableWindow(GetDlgItem(m_hWnd, IDC_TC_DEPTH), ogl);
|
||||||
EnableWindow(GetDlgItem(m_hWnd, IDC_TRI_FILTER), ogl);
|
EnableWindow(GetDlgItem(m_hWnd, IDC_TRI_FILTER), ogl);
|
||||||
EnableWindow(GetDlgItem(m_hWnd, IDC_TRI_FILTER_TEXT), ogl);
|
EnableWindow(GetDlgItem(m_hWnd, IDC_TRI_FILTER_TEXT), ogl);
|
||||||
EnableWindow(GetDlgItem(m_hWnd, IDC_UNSCALE_POINT_LINE), ogl && !native);
|
|
||||||
|
|
||||||
// Upscaling hacks:
|
// Upscaling hacks:
|
||||||
|
EnableWindow(GetDlgItem(m_hWnd, IDC_UNSCALE_POINT_LINE), !dx9 && !native);
|
||||||
EnableWindow(GetDlgItem(m_hWnd, IDC_SPRITEHACK), !native);
|
EnableWindow(GetDlgItem(m_hWnd, IDC_SPRITEHACK), !native);
|
||||||
EnableWindow(GetDlgItem(m_hWnd, IDC_WILDHACK), !native);
|
EnableWindow(GetDlgItem(m_hWnd, IDC_WILDHACK), !native);
|
||||||
EnableWindow(GetDlgItem(m_hWnd, IDC_ALIGN_SPRITE), !native);
|
EnableWindow(GetDlgItem(m_hWnd, IDC_ALIGN_SPRITE), !native);
|
||||||
|
|
|
@ -42,6 +42,16 @@ bool GSDevice11::CreateTextureFX()
|
||||||
|
|
||||||
memset(&bd, 0, sizeof(bd));
|
memset(&bd, 0, sizeof(bd));
|
||||||
|
|
||||||
|
bd.ByteWidth = sizeof(GSConstantBuffer);
|
||||||
|
bd.Usage = D3D11_USAGE_DEFAULT;
|
||||||
|
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||||
|
|
||||||
|
hr = m_dev->CreateBuffer(&bd, NULL, &m_gs_cb);
|
||||||
|
|
||||||
|
if (FAILED(hr)) return false;
|
||||||
|
|
||||||
|
memset(&bd, 0, sizeof(bd));
|
||||||
|
|
||||||
bd.ByteWidth = sizeof(PSConstantBuffer);
|
bd.ByteWidth = sizeof(PSConstantBuffer);
|
||||||
bd.Usage = D3D11_USAGE_DEFAULT;
|
bd.Usage = D3D11_USAGE_DEFAULT;
|
||||||
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||||
|
@ -78,6 +88,10 @@ bool GSDevice11::CreateTextureFX()
|
||||||
|
|
||||||
SetupVS(sel, &cb);
|
SetupVS(sel, &cb);
|
||||||
|
|
||||||
|
GSConstantBuffer gcb;
|
||||||
|
|
||||||
|
SetupGS(GSSelector(1), &gcb);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -139,11 +153,12 @@ void GSDevice11::SetupVS(VSSelector sel, const VSConstantBuffer* cb)
|
||||||
IASetInputLayout(i->second.il);
|
IASetInputLayout(i->second.il);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDevice11::SetupGS(GSSelector sel)
|
void GSDevice11::SetupGS(GSSelector sel, const GSConstantBuffer* cb)
|
||||||
{
|
{
|
||||||
CComPtr<ID3D11GeometryShader> gs;
|
CComPtr<ID3D11GeometryShader> gs;
|
||||||
|
|
||||||
if(sel.prim > 0 && (sel.iip == 0 || sel.prim == 3)) // geometry shader works in every case, but not needed
|
bool Unscale_GSShader = (sel.point == 1 || sel.line == 1) && UserHacks_unscale_pt_ln;
|
||||||
|
if((sel.prim > 0 && (sel.iip == 0 || sel.prim == 3)) || Unscale_GSShader) // geometry shader works in every case, but not needed
|
||||||
{
|
{
|
||||||
hash_map<uint32, CComPtr<ID3D11GeometryShader> >::const_iterator i = m_gs.find(sel);
|
hash_map<uint32, CComPtr<ID3D11GeometryShader> >::const_iterator i = m_gs.find(sel);
|
||||||
|
|
||||||
|
@ -153,15 +168,19 @@ void GSDevice11::SetupGS(GSSelector sel)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string str[2];
|
string str[4];
|
||||||
|
|
||||||
str[0] = format("%d", sel.iip);
|
str[0] = format("%d", sel.iip);
|
||||||
str[1] = format("%d", sel.prim);
|
str[1] = format("%d", sel.prim);
|
||||||
|
str[2] = format("%d", sel.point);
|
||||||
|
str[3] = format("%d", sel.line);
|
||||||
|
|
||||||
D3D_SHADER_MACRO macro[] =
|
D3D_SHADER_MACRO macro[] =
|
||||||
{
|
{
|
||||||
{"GS_IIP", str[0].c_str()},
|
{"GS_IIP", str[0].c_str()},
|
||||||
{"GS_PRIM", str[1].c_str()},
|
{"GS_PRIM", str[1].c_str()},
|
||||||
|
{"GS_POINT", str[2].c_str()},
|
||||||
|
{"GS_LINE", str[3].c_str()},
|
||||||
{NULL, NULL},
|
{NULL, NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -173,7 +192,15 @@ void GSDevice11::SetupGS(GSSelector sel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GSSetShader(gs);
|
|
||||||
|
if (m_gs_cb_cache.Update(cb))
|
||||||
|
{
|
||||||
|
ID3D11DeviceContext* ctx = m_ctx;
|
||||||
|
|
||||||
|
ctx->UpdateSubresource(m_gs_cb, 0, NULL, cb, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
GSSetShader(gs, m_gs_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDevice11::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel)
|
void GSDevice11::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel)
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#ifndef GS_IIP
|
#ifndef GS_IIP
|
||||||
#define GS_IIP 0
|
#define GS_IIP 0
|
||||||
#define GS_PRIM 3
|
#define GS_PRIM 3
|
||||||
|
#define GS_POINT 0
|
||||||
|
#define GS_LINE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef PS_FST
|
#ifndef PS_FST
|
||||||
|
@ -107,6 +109,11 @@ cbuffer cb1
|
||||||
float4 TC_OffsetHack;
|
float4 TC_OffsetHack;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
cbuffer cb2
|
||||||
|
{
|
||||||
|
float2 PointSize;
|
||||||
|
};
|
||||||
|
|
||||||
float4 sample_c(float2 uv)
|
float4 sample_c(float2 uv)
|
||||||
{
|
{
|
||||||
if (ATI_SUCKS && PS_POINT_SAMPLER)
|
if (ATI_SUCKS && PS_POINT_SAMPLER)
|
||||||
|
@ -630,7 +637,7 @@ VS_OUTPUT vs_main(VS_INPUT input)
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GS_PRIM == 0
|
#if GS_PRIM == 0 && GS_POINT == 0
|
||||||
|
|
||||||
[maxvertexcount(1)]
|
[maxvertexcount(1)]
|
||||||
void gs_main(point VS_OUTPUT input[1], inout PointStream<VS_OUTPUT> stream)
|
void gs_main(point VS_OUTPUT input[1], inout PointStream<VS_OUTPUT> stream)
|
||||||
|
@ -638,19 +645,104 @@ void gs_main(point VS_OUTPUT input[1], inout PointStream<VS_OUTPUT> stream)
|
||||||
stream.Append(input[0]);
|
stream.Append(input[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif GS_PRIM == 1
|
#elif GS_PRIM == 0 && GS_POINT == 1
|
||||||
|
|
||||||
|
[maxvertexcount(6)]
|
||||||
|
void gs_main(point VS_OUTPUT input[1], inout TriangleStream<VS_OUTPUT> stream)
|
||||||
|
{
|
||||||
|
// Transform a point to a NxN sprite
|
||||||
|
VS_OUTPUT Point = input[0];
|
||||||
|
|
||||||
|
// Get new position
|
||||||
|
float4 lt_p = input[0].p;
|
||||||
|
float4 rb_p = input[0].p + float4(PointSize.x, PointSize.y, 0.0f, 0.0f);
|
||||||
|
float4 lb_p = rb_p;
|
||||||
|
float4 rt_p = rb_p;
|
||||||
|
lb_p.x = lt_p.x;
|
||||||
|
rt_p.y = lt_p.y;
|
||||||
|
|
||||||
|
// Triangle 1
|
||||||
|
Point.p = lt_p;
|
||||||
|
stream.Append(Point);
|
||||||
|
|
||||||
|
Point.p = lb_p;
|
||||||
|
stream.Append(Point);
|
||||||
|
|
||||||
|
Point.p = rt_p;
|
||||||
|
stream.Append(Point);
|
||||||
|
|
||||||
|
// Triangle 2
|
||||||
|
Point.p = lb_p;
|
||||||
|
stream.Append(Point);
|
||||||
|
|
||||||
|
Point.p = rt_p;
|
||||||
|
stream.Append(Point);
|
||||||
|
|
||||||
|
Point.p = rb_p;
|
||||||
|
stream.Append(Point);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif GS_PRIM == 1 && GS_LINE == 0
|
||||||
|
|
||||||
[maxvertexcount(2)]
|
[maxvertexcount(2)]
|
||||||
void gs_main(line VS_OUTPUT input[2], inout LineStream<VS_OUTPUT> stream)
|
void gs_main(line VS_OUTPUT input[2], inout LineStream<VS_OUTPUT> stream)
|
||||||
{
|
{
|
||||||
#if GS_IIP == 0
|
#if GS_IIP == 0
|
||||||
input[0].c = input[1].c;
|
input[0].c = input[1].c;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
stream.Append(input[0]);
|
stream.Append(input[0]);
|
||||||
stream.Append(input[1]);
|
stream.Append(input[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#elif GS_PRIM == 1 && GS_LINE == 1
|
||||||
|
|
||||||
|
[maxvertexcount(6)]
|
||||||
|
void gs_main(line VS_OUTPUT input[2], inout TriangleStream<VS_OUTPUT> stream)
|
||||||
|
{
|
||||||
|
// Transform a line to a thick line-sprite
|
||||||
|
VS_OUTPUT left = input[0];
|
||||||
|
VS_OUTPUT right = input[1];
|
||||||
|
float2 lt_p = input[0].p.xy;
|
||||||
|
float2 rt_p = input[1].p.xy;
|
||||||
|
|
||||||
|
// Potentially there is faster math
|
||||||
|
float2 line_vector = normalize(rt_p.xy - lt_p.xy);
|
||||||
|
float2 line_normal = float2(line_vector.y, -line_vector.x);
|
||||||
|
float2 line_width = (line_normal * PointSize) / 2;
|
||||||
|
|
||||||
|
lt_p -= line_width;
|
||||||
|
rt_p -= line_width;
|
||||||
|
float2 lb_p = input[0].p.xy + line_width;
|
||||||
|
float2 rb_p = input[1].p.xy + line_width;
|
||||||
|
|
||||||
|
#if GS_IIP == 0
|
||||||
|
left.c = right.c;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Triangle 1
|
||||||
|
left.p.xy = lt_p;
|
||||||
|
stream.Append(left);
|
||||||
|
|
||||||
|
left.p.xy = lb_p;
|
||||||
|
stream.Append(left);
|
||||||
|
|
||||||
|
right.p.xy = rt_p;
|
||||||
|
stream.Append(right);
|
||||||
|
stream.RestartStrip();
|
||||||
|
|
||||||
|
// Triangle 2
|
||||||
|
left.p.xy = lb_p;
|
||||||
|
stream.Append(left);
|
||||||
|
|
||||||
|
right.p.xy = rt_p;
|
||||||
|
stream.Append(right);
|
||||||
|
|
||||||
|
right.p.xy = rb_p;
|
||||||
|
stream.Append(right);
|
||||||
|
stream.RestartStrip();
|
||||||
|
}
|
||||||
|
|
||||||
#elif GS_PRIM == 2
|
#elif GS_PRIM == 2
|
||||||
|
|
||||||
[maxvertexcount(3)]
|
[maxvertexcount(3)]
|
||||||
|
@ -671,27 +763,32 @@ void gs_main(triangle VS_OUTPUT input[3], inout TriangleStream<VS_OUTPUT> stream
|
||||||
[maxvertexcount(4)]
|
[maxvertexcount(4)]
|
||||||
void gs_main(line VS_OUTPUT input[2], inout TriangleStream<VS_OUTPUT> stream)
|
void gs_main(line VS_OUTPUT input[2], inout TriangleStream<VS_OUTPUT> stream)
|
||||||
{
|
{
|
||||||
input[0].p.z = input[1].p.z;
|
VS_OUTPUT lt = input[0];
|
||||||
input[0].t.zw = input[1].t.zw;
|
VS_OUTPUT rb = input[1];
|
||||||
|
|
||||||
|
// flat depth
|
||||||
|
lt.p.z = rb.p.z;
|
||||||
|
// flat fog and texture perspective
|
||||||
|
lt.t.zw = rb.t.zw;
|
||||||
|
|
||||||
|
// flat color
|
||||||
#if GS_IIP == 0
|
#if GS_IIP == 0
|
||||||
input[0].c = input[1].c;
|
lt.c = rb.c;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
VS_OUTPUT lb = input[1];
|
// Swap texture and position coordinate
|
||||||
|
VS_OUTPUT lb = rb;
|
||||||
|
lb.p.x = lt.p.x;
|
||||||
|
lb.t.x = lt.t.x;
|
||||||
|
|
||||||
lb.p.x = input[0].p.x;
|
VS_OUTPUT rt = rb;
|
||||||
lb.t.x = input[0].t.x;
|
rt.p.y = lt.p.y;
|
||||||
|
rt.t.y = lt.t.y;
|
||||||
|
|
||||||
VS_OUTPUT rt = input[1];
|
stream.Append(lt);
|
||||||
|
|
||||||
rt.p.y = input[0].p.y;
|
|
||||||
rt.t.y = input[0].t.y;
|
|
||||||
|
|
||||||
stream.Append(input[0]);
|
|
||||||
stream.Append(lb);
|
stream.Append(lb);
|
||||||
stream.Append(rt);
|
stream.Append(rt);
|
||||||
stream.Append(input[1]);
|
stream.Append(rb);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -101,6 +101,7 @@
|
||||||
#define IDC_MEMORY_WRAPPING 2122
|
#define IDC_MEMORY_WRAPPING 2122
|
||||||
#define IDC_TRI_FILTER 2123
|
#define IDC_TRI_FILTER 2123
|
||||||
#define IDC_TRI_FILTER_TEXT 2124
|
#define IDC_TRI_FILTER_TEXT 2124
|
||||||
|
#define IDC_UNSCALE_POINT_LINE 2125
|
||||||
// Shader:
|
// Shader:
|
||||||
#define IDC_SHADEBOOST 2140
|
#define IDC_SHADEBOOST 2140
|
||||||
#define IDC_FXAA 2141
|
#define IDC_FXAA 2141
|
||||||
|
|
Loading…
Reference in New Issue