Compare commits

...

50 commits

Author SHA1 Message Date
Jakly d27ceec6fe
Merge 1670c806f1 into 10798c3464 2024-05-06 20:31:06 +00:00
Jaklyy 1670c806f1 add note
make sure we dont forget that this is still implemented wrong.
2024-05-06 16:31:00 -04:00
Jaklyy ea95460816 AAAAAAA 2024-04-26 21:58:05 -04:00
Jaklyy 44e333af48 attempt to optimize
that caused a wayyyy bigger hit than it had any right to, jeez
2024-04-26 21:38:33 -04:00
Jaklyy d4a02306bc implement the "color interp bug" for compressed textures 2024-04-26 19:54:34 -04:00
Jaklyy e04644b3d2 Merge remote-tracking branch 'upstream/master' into depth-test-equals-swapped 2024-04-26 19:43:48 -04:00
Jaklyy ba451574ee minor corrections 2024-04-24 22:26:33 -04:00
Jaklyy 0d3ca9fde1 re-add optimizations
turned out to be a 10% performance hit under certain circumstances.
yeeesh.
maybe some day this fix'll return.
some day...
2024-04-17 21:34:12 -04:00
Jaklyy a70887b553 hw uses two flags to determine which buffer to clear
fixes a couple minor bugs with misused shadow polys
2024-04-14 11:38:19 -04:00
Jaklyy 4819602492 the (way more complicated) fix that isn't ultra slow 2024-04-13 20:27:47 -04:00
Jaklyy ee5fcf8edb Revert "fix for stencil buffer persistence"
This reverts commit 04a2713e0b.
2024-04-13 19:29:48 -04:00
Jaklyy 04a2713e0b fix for stencil buffer persistence 2024-04-13 11:16:38 -04:00
Jaklyy d2a1f9715a edge related edge-case is if front/back facing flags are the same 2024-04-11 20:24:53 -04:00
Jaklyy 17ba3d1da0 implement edge marking edge case 2024-03-18 17:52:11 -04:00
Jaklyy 420e91426a const 2024-03-16 12:26:02 -04:00
Jaklyy dbc6b76287 forgot to add raster rev to reset/savestate funcs 2024-03-15 17:19:09 -04:00
Jaklyy b7825b303f translucent pixels of textures also fill edges
also verify that thingy
2024-03-14 18:43:36 -04:00
Jaklyy 8a95377406 cleanup 2024-03-14 12:45:58 -04:00
Jaklyy 6acefec43c shadow, shadow mask, and decals count as translucent based on texture format 2024-03-14 12:37:45 -04:00
Jaklyy 4648cd2219 opaque shadows check opaque poly id 2024-03-14 12:35:49 -04:00
Jaklyy 07b3321b25 verified the fog flag 2024-03-14 10:46:57 -04:00
Jaklyy d25229d495 opaque shadows only update color buffer 2024-03-13 11:37:57 -04:00
Jaklyy 0d0b6534f4 Merge branch 'too-many-fixes' into depth-test-equals-swapped 2024-03-13 09:39:30 -04:00
Jaklyy a47c473738 undo making wireframes have texture alpha
this is why we always fact check
2024-03-12 22:08:19 -04:00
Jaklyy f400e43d7f clarify some details 2024-03-12 16:40:18 -04:00
Jaklyy 599d7eedbc lazy fix to translucent pixels always needing to update depth buffer
required for proper emulation of shadow mask jank
2024-03-12 16:29:51 -04:00
Jaklyy c393d594a2 simplify some checks, fix post dt handling for shadows
should be mathematically impossible for the top pixel to pass the depth test and the bottom fail
...as long as there isn't a <= dt for shadow polys--
2024-03-12 14:00:28 -04:00
Jaklyy eaa4443c24 nvm translucent shadows do update the attr buffer
also shadow masks dont need to pass attrs to the depth test
2024-03-12 10:26:16 -04:00
Jaklyy ba91493ffd remove some optimizations so we can emulate a useless shadow mask quirk
this hurts me physically
2024-03-12 09:40:06 -04:00
Jaklyy c8fcdcdffd cleanup and a correction 2024-03-11 19:22:53 -04:00
Jaklyy 7ab97038a9 Revert "probably correct?"
This reverts commit fa7c4db7bd.
2024-03-11 19:06:16 -04:00
Jaklyy 61682582c5 doh 2024-03-11 17:22:30 -04:00
Jaklyy bd2e65668a fix a bug i introduced, also wireframes do support texture alpha 2024-03-11 17:13:54 -04:00
Jaklyy 514d48fea9 Merge branch 'shadow-polygon-fixes' into depth-test-jank 2024-03-11 17:08:23 -04:00
Jaklyy 1a1dbdf85f bug only applies to opaque shadow masks
weird
2024-03-11 11:46:47 -04:00
Jaklyy fa7c4db7bd probably correct? 2024-03-11 08:13:33 -04:00
Jaklyy 11b0ad2d7f oops 2024-03-11 07:30:42 -04:00
Jaklyy f71f60dc4c oop 2024-03-11 07:06:08 -04:00
Jaklyy e68009f583 fix <= depth test for translucent polygons 2024-03-10 23:07:34 -04:00
Jaklyy ff5e823df2 misc fixes
1. shadow and transparent polygons don't have edge flags
2. shadow and shadow mask polygons dont have a <= depth test
2024-03-10 17:18:23 -04:00
Jaklyy 80240d16e5 nevermind it doesn't apply to them 2024-03-10 16:00:16 -04:00
Jaklyy 601c27af0c apply to shadow masks
this *should* be right?
hard to test though...
2024-03-10 15:59:49 -04:00
Jaklyy ffa6c50883 misc fixes
1. stencil buffer is only cleared when starting a mask polygon, *after* rendering a shadow polygon.
2. shadow polygons always(?) push pixels down.
3. Transparent shadows dont(?) write to the attr buffer
4. opaque shadows dont write to the attr(?) buff or depth buffer
2024-03-10 14:32:55 -04:00
Jaklyy fe683c1250 start raster scfg bit; add stencil buffer to reset
also fix a small issue that prevented compiling
2024-03-09 19:05:45 -05:00
Jaklyy a03aec13c1 alpha is ignored when "rasterizing" shadow masks 2024-03-09 13:34:55 -05:00
Jaklyy cf0c697065 merge slope and edge flags
+misc cleanup
2024-03-09 10:36:06 -05:00
Jaklyy 0ed21a68c7 misc cleanup, fix a bug 2024-03-08 13:36:57 -05:00
Jaklyy 1699dbec34 basic implementation 2024-03-07 19:23:39 -05:00
Jaklyy 3890dd0165 front facing flag behavior is also inverted
also dont forget about shadow mask polygons!
2024-03-06 12:14:56 -05:00
Jaklyy cc9baf0bc1 backfacing flag is inverted for swapped polygons 2024-03-06 11:46:40 -05:00
8 changed files with 547 additions and 268 deletions

View file

@ -3173,4 +3173,9 @@ void DSi::ARM7IOWrite32(u32 addr, u32 val)
return NDS::ARM7IOWrite32(addr, val);
}
bool DSi::GetSCFGRasterBit() const
{
return SCFG_EXT[0] & (1<<2);
}
}

View file

@ -129,6 +129,8 @@ public:
void ARM7IOWrite16(u32 addr, u16 val) override;
void ARM7IOWrite32(u32 addr, u32 val) override;
bool GetSCFGRasterBit() const override;
public:
DSi(DSiArgs&& args) noexcept;
~DSi() noexcept override;

View file

@ -182,6 +182,8 @@ void GPU3D::ResetRenderingState() noexcept
RenderClearAttr1 = 0x3F000000;
RenderClearAttr2 = 0x00007FFF;
RenderRasterRev = false; // CHECKME: when should this be reset?
}
void GPU3D::Reset() noexcept
@ -354,6 +356,8 @@ void GPU3D::DoSavestate(Savestate* file) noexcept
file->Var32(&RenderClearAttr1);
file->Var32(&RenderClearAttr2);
file->Bool32(&RenderRasterRev);
file->Var16(&RenderXPos);
@ -553,6 +557,7 @@ void GPU3D::DoSavestate(Savestate* file) noexcept
file->Var32(&TexParam);
file->Var32(&TexPalette);
RenderFrameIdentical = false;
ForceRerender = false;
if (softRenderer && softRenderer->IsThreaded())
{
softRenderer->EnableRenderThread();
@ -1216,7 +1221,7 @@ void GPU3D::SubmitPolygon() noexcept
u32 texfmt = (TexParam >> 26) & 0x7;
u32 polyalpha = (CurPolygonAttr >> 16) & 0x1F;
poly->Translucent = ((texfmt == 1 || texfmt == 6) && !(CurPolygonAttr & 0x10)) || (polyalpha > 0 && polyalpha < 31);
poly->Translucent = (texfmt == 1 || texfmt == 6) || (polyalpha > 0 && polyalpha < 31);
poly->IsShadowMask = ((CurPolygonAttr & 0x3F000030) == 0x00000030);
poly->IsShadow = ((CurPolygonAttr & 0x30) == 0x30) && !poly->IsShadowMask;
@ -2459,18 +2464,30 @@ void GPU3D::VBlank() noexcept
RenderNumPolygons = NumPolygons;
RenderFrameIdentical = false;
ForceRerender = 0;
}
else
{
RenderFrameIdentical = RenderDispCnt == DispCnt
&& RenderAlphaRef == AlphaRef
&& RenderClearAttr1 == ClearAttr1
&& RenderClearAttr2 == ClearAttr2
&& RenderFogColor == FogColor
&& RenderFogOffset == FogOffset * 0x200
&& memcmp(RenderEdgeTable, EdgeTable, 8*2) == 0
&& memcmp(RenderFogDensityTable + 1, FogDensityTable, 32) == 0
&& memcmp(RenderToonTable, ToonTable, 32*2) == 0;
if (ForceRerender == true)
{
RenderFrameIdentical = false;
ForceRerender = false;
DontRerenderLoop = true;
}
else
{
RenderFrameIdentical = RenderDispCnt == DispCnt
&& RenderAlphaRef == AlphaRef
&& RenderClearAttr1 == ClearAttr1
&& RenderClearAttr2 == ClearAttr2
&& RenderFogColor == FogColor
&& RenderFogOffset == FogOffset * 0x200
&& memcmp(RenderEdgeTable, EdgeTable, 8*2) == 0
&& memcmp(RenderFogDensityTable + 1, FogDensityTable, 32) == 0
&& memcmp(RenderToonTable, ToonTable, 32*2) == 0
&& RenderRasterRev == NDS.GetSCFGRasterBit();
}
}
RenderDispCnt = DispCnt;
@ -2488,6 +2505,9 @@ void GPU3D::VBlank() noexcept
RenderClearAttr1 = ClearAttr1;
RenderClearAttr2 = ClearAttr2;
// NOTE: this is not latched. it updates the *moment* you set it. it does not cancel the current scanline. it just causes pain and suffering.
// in less dramatic terms: annoying to emulate properly, so we're just gonna pretend it's latched for now, ok?
RenderRasterRev = NDS.GetSCFGRasterBit();
}
if (FlushRequest)

View file

@ -271,6 +271,8 @@ public:
u32 RenderClearAttr1 = 0;
u32 RenderClearAttr2 = 0;
bool RenderRasterRev = false;
bool RenderFrameIdentical = false; // not part of the hardware state, don't serialize
bool AbortFrame = false;
@ -323,6 +325,10 @@ public:
std::array<Polygon*,2048> RenderPolygonRAM {};
u32 RenderNumPolygons = 0;
// used to fix stencil buffer's frame-to-frame persistence not working properly under extreme misuse of shadow masks/shadows
bool ForceRerender = false;
bool DontRerenderLoop = false;
u32 FlushRequest = 0;
u32 FlushAttributes = 0;
u32 ScrolledLine[256]; // not part of the hardware state, don't serialize

File diff suppressed because it is too large Load diff

View file

@ -26,6 +26,18 @@
namespace melonDS
{
enum EdgeFlags
{
EF_None = (0),
EF_AnyEdge = (0xF),
EF_TopXMajor = (1<<0),
EF_BotXMajor = (1<<1),
EF_LYMajor = (1<<2),
EF_RYMajor = (1<<3),
};
class SoftRenderer : public Renderer3D
{
public:
@ -455,19 +467,20 @@ private:
};
RendererPolygon PolygonList[2048];
void TextureLookup(const GPU& gpu, u32 texparam, u32 texpal, s16 s, s16 t, u16* color, u8* alpha) const;
template <bool colorcorrect> inline void ColorConv(const u16 color, u8* r, u8* g, u8* b) const;
void TextureLookup(const GPU& gpu, u32 texparam, u32 texpal, s16 s, s16 t, u8* tr, u8* tg, u8* tb, u8* alpha) const;
u32 RenderPixel(const GPU& gpu, const Polygon* polygon, u8 vr, u8 vg, u8 vb, s16 s, s16 t) const;
void PlotTranslucentPixel(const GPU3D& gpu3d, u32 pixeladdr, u32 color, u32 z, u32 polyattr, u32 shadow);
void SetupPolygonLeftEdge(RendererPolygon* rp, s32 y) const;
void SetupPolygonRightEdge(RendererPolygon* rp, s32 y) const;
void SetupPolygon(RendererPolygon* rp, Polygon* polygon) const;
void RenderShadowMaskScanline(const GPU3D& gpu3d, RendererPolygon* rp, s32 y);
void RenderPolygonScanline(const GPU& gpu, RendererPolygon* rp, s32 y);
void RenderScanline(const GPU& gpu, s32 y, int npolys);
void RenderPolygonScanline(GPU& gpu, RendererPolygon* rp, s32 y);
void RenderScanline(GPU& gpu, s32 y, int npolys);
u32 CalculateFogDensity(const GPU3D& gpu3d, u32 pixeladdr) const;
void ScanlineFinalPass(const GPU3D& gpu3d, s32 y);
void ClearBuffers(const GPU& gpu);
void RenderPolygons(const GPU& gpu, bool threaded, Polygon** polygons, int npolys);
void RenderPolygons(GPU& gpu, bool threaded, Polygon** polygons, int npolys);
void RenderThreadFunc(GPU& gpu);
@ -487,7 +500,7 @@ private:
u32 AttrBuffer[BufferSize * 2];
// attribute buffer:
// bit0-3: edge flags (left/right/top/bottom)
// bit0-3: edge flags (top xmajor/bottom xmajor/left ymajor/right ymajor)
// bit4: backfacing flag
// bit8-12: antialiasing alpha
// bit15: fog enable
@ -496,7 +509,8 @@ private:
// bit24-29: polygon ID for opaque pixels
u8 StencilBuffer[256*2];
bool PrevIsShadowMask;
bool ShadowRendered[2];
bool StencilCleared;
bool Enabled;

View file

@ -4334,4 +4334,9 @@ void NDS::ARM7IOWrite32(u32 addr, u32 val)
Log(LogLevel::Debug, "unknown ARM7 IO write32 %08X %08X %08X\n", addr, val, ARM7.R[15]);
}
bool NDS::GetSCFGRasterBit() const
{
return false;
}
}

View file

@ -471,6 +471,8 @@ public: // TODO: Encapsulate the rest of these members
void SetJITArgs(std::optional<JITArgs> args) noexcept {}
#endif
virtual bool GetSCFGRasterBit() const;
private:
void InitTimings();
u32 SchedListMask;