The handling of infinite fog coordinates in #660 does not exactly
match HW behavior for all bias and multiplier values. Further testing
indicates that the handling of the infinite value appears to override
all combinations of FOG_PARAM bias/multipliers, rather than keeping
the bias. This change emulates this behavior and also fixes NaN
handling, which similarly seems to be fog-mode dependent.
Fixes#2474Fixes#2412Fixes#2200Fixes#632
Mesa OpenGL radeonsi driver has a bug where triangles in triangle strips
emitted from geometry shader may have provoking vertices not corresponding
to either first or last vertex convention when GL_FIRST_VERTEX_CONVENTION
is used.
This commit changes geometry shader such that it always emits separate
triangles and line segments and it doesn't matter what vertex OpenGL or
Vulkan implementation chooses as provoking.
This adds redundant computation to the simple geometry shader for winding
testing based on the assumption that Nvidia GeForce compiler has a bug
which may incorrectly detect a simple geometry shader as a passthrough
shader.
Test OpenGL/Vulkan geometry shader triangle, strip and fan vertex ordering
during backend initialization. OpenGL/Vulkan does not guarantee absolute
vertex order for geometry shader input triangles. The test results are
used to reorder input triangle vertices into the first vertex convention
order so that correct provoking vertex can be chosen for flat shading.
Also, this removes use of the Vulkan provoking vertex extension. The
default first vertex convention is now used when emitting line strips
in geometry shader. (It would of course be possible to always emit only
separate line segments and then the convention wouldn't matter at all.)
Xbox draws lines in polygon mode without trying to avoid overlaps, e.g.
internal edge lines are drawn twice for triangle strips and fans. This is
evidenced by using additive blending and also stencil adds. This commit
removes the gl_PrimitiveIDIn==0 checks which were there to avoid drawing
lines twice.
This commit also implements flat shading first/last provoking vertex
handling. This fixes triangle strip and fan flat shading in
nxdk_pgraph_tests shade model tests.
1. Use barycentric coordinates to interpolate depth values. Linux, Mesa
and AMD Radeon RX 6600 with Vulkan driver currently has quite poor
interpolation precision, which results in artifacts in at least Chronicles
of Riddick. Intel integrated UHD 770 has much better precision, for
example. This commit handles depth interpolation manually. Also note that
the previous w-buffer interpolation used gl_FragCoord.w which can't produce
all w-values, e.g. 1.0f/16777046.0f equals 1.0f/16777047.0f with 32-bit
floats. This also uses depth value differences in interpolation which has
the desired property that a triangle with the same z-value on all vertices
will result in exactly that same z-value when interpolated. At least the
game Shenmue II sky rendering relies on this.
2. Computes polygon depth bias slope for both z-buffering and w-buffering.
These are computed by taking the max and abs of partial derivatives of
either of the functions z=z(x,y) or w=w(x,y), where x,y,z,w are
screen-space coordinates. This matches Xbox hardware for z-buffering where
the partial derivatives are constants over any fixed triangle. However,
for w-buffering the partial derivatives vary over any fixed triangle, but
Xbox appears to compute just a single depth slope at the first visible
pixel (where "first" means something like first in top-left order) and uses
that over the whole triangle. This commit computes the slope per-pixel.
The way to compute the partial derivatives is by using the chain-rule, e.g.
dw/dx = -w^2 * d(1/w)/dx. This is useful since 1/w is linear in
screen-space and therefore d(1/w)/dx is constant over any fixed triangle.
But, as mentioned, finding out the w-value for the first visible pixel
of a triangle is difficult in OpenGL/Vulkan and is not done here. Instead
we calculate depth slope per-pixel.
This fixes nxdk_pgraph_tests W_param tests a bit more. Note that the
geometry shader approach in Xemu for polygon line mode doesn't currently
implement face culling. It could be improved by using the built-in
gl_FrontFacing variable in the geometry shader.
Meson 1.9.0 provides mixed linking of Rust and C objects. As a side effect,
this also allows adding dependencies with "sources: ..." files to Rust crates
that use structured_sources().
It can also clean up up the meson.build files for Rust noticeably, but due
to an issue with doctests (see https://github.com/mesonbuild/meson/pull/14973)
that will have to wait for 1.9.1.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Link: https://lore.kernel.org/r/20250908105005.2119297-3-pbonzini@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
xemu: Update minimum Meson requirement to 1.8.4 to facilitate building on
macOS with Clang 17.
Fixes#2442
Discards the alpha value passed to the color key register, matching tested
hardware behavior.
Fixes#2421
Tests: c64f5af5f7/src/tests/pvideo_tests.cpp (L761)
Note: PVIDEO tests do not produce artifacts so they must be compared manually
against HW. I have verified that they are identical for the subset of surface
formats supported by xemu.