Words at or past the size in the fetch constant read as 0 now instead of whatever sits in shared memory, matching real hardware.
Co-authored-by: Herman S. <429230+has207@users.noreply.github.com>
Guest sample 1 lives in host sample 3 when 2x-as-4x. This might have originally just been a typo or oversight.
Co-authored-by: Herman S. <429230+has207@users.noreply.github.com>
Mainly for NaN preservation. GS discards primitives by checking positions for NaN, mostly for vertex kill, and without the controls drivers might fold those checks away.
Co-authored-by: Herman S. <429230+has207@users.noreply.github.com>
Mips were always regenerated by blitting down from base, even when guest resolved real data into scaled memory.
The upload footprint is the guest mip reduced then scaled while the subresource is the base scaled then reduced, so the deepest mips of scaled textures can disagree by a row or column per axis. Compressed formats round up to the block and absorb it, uncompressed copies now clamp per axis so they never overrun the host image.
Matches D3D12 fix for the same problem.
Co-authored-by: Herman S. <429230+has207@users.noreply.github.com>
Exp 31 is a large finite value up to 131,008 on the guest, not Inf or NaN.
Packing used to clamp colors at 65504 and unpacking returned Inf for extended encodings.
Co-authored-by: Herman S. <429230+has207@users.noreply.github.com>
The domain shader reads the patch index from the hull shader output instead of gl_PrimitiveID, which bypassed the endian swap, offset, wrap and clamp already applied upstream.
The tessellator winds clockwise now. Clip space Y is not flipped on Vulkan, so counterclockwise winding inverted the facing and guest backface culling removed whole surfaces.
Co-authored-by: Herman S. <429230+has207@users.noreply.github.com>
This is a combination of three different Edge commits.
Guest page access is resolved with system page granularity so that anything deciding on protection now takes permissive access of every guest page a system page covers, which matters when the host is larger than the guest.
Access violations: Write faults on pages with no watch armed are only reported handled if guest mapping allows the write.
Invalidation of unwatched ranges when made writable or freed: Decommit, Release and Protect-to-writable (including write-combine) raise invalidation callbacks even with no watch armed.
Co-authored-by: Herman S. <429230+has207@users.noreply.github.com>
GetOrCreate reads entry->status while holding the global critical region,
but ResolveFunction published compile results by writing entry->function,
end_address and status directly, with no lock held. Nothing establishes a
happens-before edge between the two, so a thread that observes
STATUS_READY can still read a stale entry->function -- which it does
unlocked, right after GetOrCreate returns.
Benign on x86's TSO in practice; reachable on AArch64.
Add MarkReady/MarkFailed, which publish under that same lock, and route
Processor through them.
ThreadSanitizer against the real EntryTable: 2 data races before, 0 after.
The race is undefined behaviour by definition; no torn pointer was
actually observed in those runs.
Both of these have been around long enough to be probably prove safe and correct.
As a reminder, color resolves only take the full shader path if the destination number format matches EDRAM encoding && full 8_8_8_8_GAMMA resolves always decode PWL to linear before MSAA sample averaging.
Keeping decode_pwl_gamma bit for testing, but it's probably superfluous.
- Stub MicDeviceRequest
- Games:
- Rock Band 2 now exits game instead of being stuck on boot when mic set to false
- Guitar Hero World Tour now properly responds when you tell it mic is connected
Treat k_8 + LOW_BLUE as alpha selection. 5451080D uses this to resolve its opacity plane, and 4D530808 does the same for a fog lighting pass. Their blue channels are black, so treating LOW_BLUE as an R/B exchange drops data.
Informed by XGCopySurface decompilation, which combines source and inverse dest swizzle, plus notcing how L8 and A8 share the same texture format.
Fixed integer fetches are updated to look widths up through the guest swizzle, so every output channel is scaled by the width it came from.
Previously, host swizzle was being walked, and it was causing some 6 bit channels to be scaled as 5 bits and vice versa.
Co-authored-by: philtimmes <5494151+philtimmes@users.noreply.github.com>
For now, this adds a depth clamp override to both backends that's kept disabled by default.
494707EE needs this for its setup draws that feed its lighting passes. It could be that guest clipping / host near and flare Z planes aren't cleanly interchangeable at the edge of the clip volume.
The fetch constant carries independent signed exponent biases in [-16, 15] for the horizontal and vertical LOD gradients. Scale the H and V gradients by exp2(lod + bias_h) and exp2(lod + bias_v) respectively in the computed LOD sample path. getCompTexLOD keeps returning the raw queried LOD, treating the adjustment like the fetch-constant LOD bias, which is also not folded into it. Zero, the common case, is a no-op.
On the cube implicit-LOD path, where no explicit gradients exist to scale, the greater of the two biases is added to the LOD bias instead - exact when both are equal, erring towards a blurrier mip otherwise.
Co-Authored-By: Herman S. <429230+has207@users.noreply.github.com>
A non-zero value in bits 0:30 of the kill flag kills the vertex, tested on the integer bits rather than as a float comparison so denormal flushing can't affect the result, matching the DXBC translator. With PA_CL_CLIP_CNTL::vtx_kill_or, the position W is set to NaN, killing the whole primitive if any of its vertices requests the kill, with the "and" operator, a dedicated cull distance after the user clip plane cull distances is set to -1, culling the primitive only when all of its vertices request it.
Co-authored-by: Herman S. <429230+has207@users.noreply.github.com>
Explicit gradients of the direction reconstructed from the guest S/T/face coordinates pick the wrong mip on Vulkan, so sample cube fetches that use computed LOD without register gradients with implicit LOD and the accumulated LOD bias (fetch constant + register LOD + instruction bias) as the Bias image operand instead. This also makes tfetchCube consistent with getCompTexLOD, which already queries the implicit LOD. Register-gradient cube fetches keep explicit gradients in cube space, and other dimensions keep explicit gradients, matching the DXBC path. Gradient setup is skipped entirely on the implicit-LOD path.
Co-authored-by: Herman S. <429230+has207@users.noreply.github.com>
The check is moved after the anisotropy resolution (and the anisotropic override) so it sees, and can reset, the final filter state.
Co-authored-by: Herman S. <429230+has207@users.noreply.github.com>
Avoids a TRANSFER_WRITE -> TRANSFER_WRITE hazard identified by the Vulkan validation layer when a texture is reuploaded (after guest memory invalidation) without having been used for drawing in between, leaving it in the transfer destination usage with no layout transition to order the copies.
Co-authored-by: Herman S. <429230+has207@users.noreply.github.com>
545407D4's UI shader uses tfetch1D with a nonreplicated source swizzle and a 2D constant. The way we have it set up is causing the translators to sample with Y set to 0.
Handle this as 2D in the translators. Normal scalar tfetch1D untouched.