CopyFramebufferToMemory always returned true, even when glReadPixels
failed, and then copied out whatever the readback buffer held from before.
Depth was labeled D24_S8 while GL reads it as float, and the conversion
ignored the source format, so only a D32F destination came out right.
Record the format and the result of each read, convert from that, and
return it. That also fixes the image readback reusing the aspect of an
earlier framebuffer readback.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The repack loop used the texture height instead of the row, and the pack
row length was the rect's right edge while glGetTexImage writes whole rows.
Only reachable from the texture debugger.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The app now always uses the Metal view controller with Vulkan (MoltenVK),
for both the App Store and sideload builds. The GL view controller is gone,
and Common/GPU/OpenGL (except GLFeatures, used by the shader generators) and
GPU/GLES are no longer compiled for it. PPSSPP_API_ANY_GL is now off for
all of iOS except the libretro core, which still uses GLES.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
It needs GL 4.3 or GLES 3.1. On Apple's GL 4.1 every depth texture bind (Cars
Race-O-Rama's depal from depth, for one) raised GL_INVALID_ENUM, which then
showed up at whatever checked glGetError next. Without the mode a
depth-stencil texture samples depth, so nothing else changes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
glBlitFramebuffer obeys the scissor test, which stays enabled between render
passes with the last pass's rectangle. Resizing a framebuffer after drawing to
a small one copied only that corner, so FF Type-0's battle screen turned into
the red overlay. Disable it around the blit and restore it.
Also fixes Assassin's Creed Bloodlines, Split/Second, Super Stardust's bloom
and MotorStorm.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The texture and fragment test caches dropped their GLRTexture objects on
DeviceLost without queueing them for deletion, leaking them on every
Android background/resume. The deleter already skips the GL calls when
the context is gone.
- GLRenderManager::ThreadEnd cleared unsubmitted init and render steps
without freeing the data they own. Run them through the dry run instead,
which now also frees stereo matrices and shader code.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
DrawEngineGLES already knows that every index it generates is below the
decoded/transformed vertex count, but only passed the count to
glDrawElements. Drivers that need the vertex range before vertex
shading, like Mesa's Panfrost, then scan the index data on the CPU for
every draw, and their min/max caches can't help since the index push
buffer is rewritten every frame.
Only used for single-instance draws on desktop GL or GLES3, and only
when the caller provides the range, so other DrawIndexed callers are
unchanged.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
imgui 1.92 hands the backend a list of dirty rectangles when its font atlas
grows, but thin3d could only replace a whole mip level, so every new glyph
re-uploaded the entire atlas.
Adds DrawContext::UpdateTextureRegions, taking a batch of regions so each
backend can submit them together:
- Vulkan: packs the regions into the push pool and issues a single
vkCmdCopyBufferToImage from the init command buffer, transitioning only
the level being written.
- OpenGL: new TEXTURE_SUBIMAGE init step. The existing sub-image path is a
render command needing an active render pass and a texture slot, which
doesn't fit here. Rows are packed caller-side since GLES2 lacks
GL_UNPACK_ROW_LENGTH.
- D3D11: UpdateSubresource with a box, no staging texture needed.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
TextureCacheGLES passed a hardcoded 0.0f instead of key.aniso, so the
Anisotropic Filtering setting did nothing at all on the OpenGL backend, even
though GPU_USE_ANISOTROPY was advertised and D3D11/Vulkan both honor it. Looks
like it was left behind by the 2017 render manager refactor.
The queue runner now clamps to the device maximum it already queried into
maxAnisotropyLevel_ (until now unused), and only touches the parameter when the
extension is actually supported - the anisotropy branch there has been dead
since every caller passed 0.0f, so this is the first time it runs.
0.0f keeps its meaning of "don't care" for the CLUT/fragment-test/thin3d
callers; the texture cache now passes 1.0f when the setting is off, so turning
it off takes effect on already-uploaded textures instead of only new ones.
TexCache: Never use anisotropic filtering for CLUT8-indexed textures
What gets sampled for those is palette indices, depalettized by the shader
afterwards - averaging indices across an anisotropic footprint produces garbage
colors. Affects all backends, not just the GL one that just started honoring
key.aniso.
TexCache: Clear key.aniso wherever filtering is forced to nearest
It was only cleared in the two places inside the AUTO_MAX_QUALITY branch, so the
TEX_FILTER_AUTO path (pixel-mapped textures, the ugly color test heuristic), the
FORCE_NEAREST setting and the replacement-texture override could all end up
requesting nearest filtering with anisotropy still on.
Doing it in the switch that applies forceFiltering covers every path, so it
can't drift apart again.
GLES: Only record the applied anisotropy, and log skipped draws
The queue runner updated tex->anisotropy even when it skipped the call because
the value was 0.0f ("don't care") - harmless while nothing ever set anisotropy,
but now it would make the tracked state disagree with GL, so a later request for
the value it thinks is set would be wrongly skipped.
Also log when a draw is skipped for a missing vertex shader. The failure is
cached per shader ID, so without it geometry silently disappears for the rest of
the session after the one-shot OSD message.
Integrates the GLProfiler into GLQueueRunner to provide GPU timestamp
profiling for OpenGL render passes, similar to the Vulkan backend.
Profiled operations:
- RenderPass (with tag name for identification)
- Copy operations
- Blit operations
- Readback operations
- ReadbackImage operations
The profiler is initialized in CreateDeviceObjects() and shutdown in
DestroyDeviceObjects(). Timing results are logged each frame when the
GPU profile debug overlay is enabled.
Signed-off-by: Chris Healy <cphealy@gmail.com>
* Rename LogType to Log
* Explicitly use the Log:: enum when logging. Allows for autocomplete when editing.
* Mac/ARM64 buildfix
* Do the same with the hle result log macros
* Rename the log names to mixed case while at it.
* iOS buildfix
* Qt buildfix attempt, ARM32 buildfix
Turns out the VR work bloated it a bit, which can't be good.
Think it's fine to allocate these view matrices on the heap to get them
out of the way, there won't be that crazy many per frame usually.
[how]
1. use comment instead of unnecessary logic comparison
2. remove some useless code
3. move some implemention code from header to source
4. some more assert