The GE's blend terms are floor((2c+1)(2f+1)/1024), which truncates, while the
hardware multiplies by f/255 and rounds, so every pass of a fixed color blend
chain came out up to a level brighter. God Eater Burst's bloom is many such
passes and ended up far too bright.
For additive FIXA/FIXB blends that aren't just 0 and 0xFFFFFF, the shader
now computes the src term exactly and lowers it by 0.5 - (2B+1)/1024, and the
blend constant is the GE's dst factor (2B+1)/512, so the hardware's rounding
of the sum lands on the GE's floor (except where the src term would go below
zero). Blend constants are passed as floats to make that possible.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On the PSP the color and alpha/stencil write masks apply to clears like to
drawing (gpu/stencil/writemask, ppsspp-re geprobe exp254). Clear-mode draws
now take the same per-channel heuristic as other draws, and a clear with RGB
masked is drawn rather than done as a hardware clear.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
53aa2cc596 changed the first argument from "true" to stencilState_.writeMask,
but that slot is "bool enabled" - the writeMask argument stayed hardcoded to
0xFF, so the mask still never reached GL. The clear-mode call just above gets
the slots right.
Reachable because SoftwareTransformCommon refuses the fast clear path when the
stencil write mask is partial, so exactly those clears end up here.
Fixes#17451, while also keeping the Dante performance fix from #17032.
Of course, it's possible that something else could slow down now... But
hopefully not. This could also fix other problems.
Some drivers don't round depth the same way for a clear vs for drawing,
which can cause mismatches. We only do this if we see equals-style depth
comparison funcs used in drawing.
It took writing and debugging #15500 for me to understand what the issue with the old path was..
Much simpler alternative to #15500, or we could merge both but disable Split/Second
for this one. Needs some benchmarks I guess...
Should make support for depth texturing quite easy.
Unfortunately, this extension does not exist on OpenGL ES. There we'll
have to use ugly tricks with gl_FragDepth if we want this.