From d8d13d44293a58b58d51c3a8e91e3ea76c6d6feb Mon Sep 17 00:00:00 2001 From: aap Date: Sat, 25 Apr 2020 12:16:04 +0200 Subject: [PATCH] added GS alpha test emulation --- src/d3d/d3d9render.cpp | 26 ++++++++++++++++++++------ src/d3d/d3ddevice.cpp | 20 ++++++++++++++++++++ src/rwrender.h | 7 ++++++- 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/d3d/d3d9render.cpp b/src/d3d/d3d9render.cpp index abfb378..494cc92 100644 --- a/src/d3d/d3d9render.cpp +++ b/src/d3d/d3d9render.cpp @@ -23,7 +23,7 @@ void defaultRenderCB_Shader(Atomic *atomic, InstanceDataHeader *header) {} #else void -drawInst(d3d9::InstanceDataHeader *header, d3d9::InstanceData *inst) +drawInst_simple(d3d9::InstanceDataHeader *header, d3d9::InstanceData *inst) { d3d::flushCache(); d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)header->primType, inst->baseIndex, @@ -36,27 +36,41 @@ void drawInst_GSemu(d3d9::InstanceDataHeader *header, InstanceData *inst) { uint32 hasAlpha; - int alphafunc; + int alphafunc, alpharef, gsalpharef; int zwrite; d3d::getRenderState(D3DRS_ALPHABLENDENABLE, &hasAlpha); if(hasAlpha){ zwrite = rw::GetRenderState(rw::ZWRITEENABLE); alphafunc = rw::GetRenderState(rw::ALPHATESTFUNC); if(zwrite){ + alpharef = rw::GetRenderState(rw::ALPHATESTREF); + gsalpharef = rw::GetRenderState(rw::GSALPHATESTREF); + SetRenderState(rw::ALPHATESTFUNC, rw::ALPHAGREATEREQUAL); - drawInst(header, inst); + SetRenderState(rw::ALPHATESTREF, gsalpharef); + drawInst_simple(header, inst); SetRenderState(rw::ALPHATESTFUNC, rw::ALPHALESS); SetRenderState(rw::ZWRITEENABLE, 0); - drawInst(header, inst); + drawInst_simple(header, inst); SetRenderState(rw::ZWRITEENABLE, 1); SetRenderState(rw::ALPHATESTFUNC, alphafunc); + SetRenderState(rw::ALPHATESTREF, alpharef); }else{ SetRenderState(rw::ALPHATESTFUNC, rw::ALPHAALWAYS); - drawInst(header, inst); + drawInst_simple(header, inst); SetRenderState(rw::ALPHATESTFUNC, alphafunc); } }else - drawInst(header, inst); + drawInst_simple(header, inst); +} + +void +drawInst(d3d9::InstanceDataHeader *header, d3d9::InstanceData *inst) +{ + if(rw::GetRenderState(rw::GSALPHATEST)) + drawInst_GSemu(header, inst); + else + drawInst_simple(header, inst); } void diff --git a/src/d3d/d3ddevice.cpp b/src/d3d/d3ddevice.cpp index 99ff50e..a16370c 100644 --- a/src/d3d/d3ddevice.cpp +++ b/src/d3d/d3ddevice.cpp @@ -79,6 +79,11 @@ struct RwStateCache { uint32 cullmode; uint32 alphafunc; uint32 alpharef; + + // emulation of PS2 GS + bool32 gsalpha; + uint32 gsalpharef; + RwRasterStateCache texstage[MAXNUMSTAGES]; }; static RwStateCache rwStateCache; @@ -548,6 +553,12 @@ setRwRenderState(int32 state, void *pvalue) setRenderState(D3DRS_ALPHAREF, rwStateCache.alpharef); } break; + case GSALPHATEST: + rwStateCache.gsalpha = value; + break; + case GSALPHATESTREF: + rwStateCache.gsalpharef = value; + break; } } @@ -605,6 +616,12 @@ getRwRenderState(int32 state) case ALPHATESTREF: val = rwStateCache.alpharef; break; + case GSALPHATEST: + val = rwStateCache.gsalpha; + break; + case GSALPHATESTREF: + val = rwStateCache.gsalpharef; + break; default: val = 0; } @@ -1326,6 +1343,9 @@ initD3D(void) d3ddevice->SetRenderState(D3DRS_ALPHAREF, 10); rwStateCache.alpharef = 10; + rwStateCache.gsalpha = 0; + rwStateCache.gsalpharef = 128; + d3ddevice->SetRenderState(D3DRS_FOGENABLE, FALSE); rwStateCache.fogenable = 0; d3ddevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_LINEAR); diff --git a/src/rwrender.h b/src/rwrender.h index 2a19f38..33f094c 100644 --- a/src/rwrender.h +++ b/src/rwrender.h @@ -24,7 +24,12 @@ enum RenderState // platform specific or opaque? ALPHATESTFUNC, - ALPHATESTREF + ALPHATESTREF, + + // emulation of PS2 GS alpha test + // in the mode where it still writes color but nor depth + GSALPHATEST, + GSALPHATESTREF }; enum AlphaTestFunc