Skip to content

Fix a couple issues found by ASan/UBSan in the Metal backend#1844

Open
fabioarnold wants to merge 4 commits intocemu-project:mainfrom
fabioarnold:fabio/metal-glitches
Open

Fix a couple issues found by ASan/UBSan in the Metal backend#1844
fabioarnold wants to merge 4 commits intocemu-project:mainfrom
fabioarnold:fabio/metal-glitches

Conversation

@fabioarnold
Copy link
Copy Markdown

@fabioarnold fabioarnold commented Mar 21, 2026

Applied after #1842 attempts to fix graphical glitches I encountered while playing Twilight Princess HD due to memory corruption.

  • Fixes a debug assertion failure by initializing pointers in MetalPipelineCache to 0.
  • Fixes an out of bounds memory write in MetalRenderer() by using the correct bound.
  • Fixes a nullptr use in LatteTextureViewMtl destructor

Another issue I couldn't test but was discovered by Claude:

The old code tried to convert a triangle fan into a triangle strip because Metal doesn't support fans. It's in LatteIndices_unpackTriangleFanAndConvert:

	// TODO: check this
	for (sint32 i = 0; i < count; i++)
	{
	    uint32 i0;
		if (i % 2 == 0)
		    i0 = i / 2;
        else
            i0 = count - 1 - i / 2;
        T idx = src[i0];
        dst[0] = idx;
	}

It's clever, trying to connect indices from both ends. However, it doesn't work in the case of a non-convex polygon like a star. You can convert to a triangle strip matching the topology of the original fan. But every other triangle needs to be degenerate. It's a bit more complicated and uses 2 indices per triangle.

In this change I implemented it the easy way and used a triangle list instead with 3 indices per triangle.

`m_uniformBufferOffsets` is sized to `METAL_GENERAL_SHADER_TYPE_TOTAL`
Otherwise `cemu_assert_debug(s_cache == nullptr);` fails in MetalPipelineCache.cpp: 294
std::map::operator[] inserts a default-constructed (null) value when
the key is absent. In GetSwizzledView, m_fallbackViewCache[key] would
insert a null entry, but if a free slot existed in m_viewCache the
texture was stored there instead, leaving the null entry in
m_fallbackViewCache. The destructor then iterated the map and called
->release() on that null pointer.
@fabioarnold fabioarnold force-pushed the fabio/metal-glitches branch from 13caea1 to 5554699 Compare March 29, 2026 14:54
@fabioarnold fabioarnold marked this pull request as ready for review March 29, 2026 14:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant