SameBoy | Accurate GB/GBC emulator |
| download: https://git.y1.nz/archives/sameboy.tar.gz | |
| README | Files | Log | Refs | LICENSE |
commit a9c01d35fc0bb567a70040c3d5a2debd13891f4d parent 686a506e174dfdc761a45b5733438c163b6ba01a Author: Lior Halphon <LIJI32@gmail.com> Date: Sat, 13 Jan 2024 15:49:37 +0200 Fix a bug where the Metal renderer would sometimes flicker in the Cocoa/iOS frontends Diffstat:
| M | AppleCommon/GBViewBase.m | 4 | +++- |
| M | AppleCommon/GBViewMetal.m | 44 | +++++++++++++++++++++++++++++++++----------- |
| M | Cocoa/Document.xib | 2 | +- |
3 files changed, 37 insertions(+), 13 deletions(-)
diff --git a/AppleCommon/GBViewBase.m b/AppleCommon/GBViewBase.m @@ -5,6 +5,7 @@ uint32_t *_imageBuffers[3]; unsigned _currentBuffer; GB_frame_blending_mode_t _frameBlendingMode; + bool _oddFrame; } - (void)screenSizeChanged @@ -23,6 +24,7 @@ - (void)flip { _currentBuffer = (_currentBuffer + 1) % self.numberOfBuffers; + _oddFrame = GB_is_odd_frame(_gb); } - (unsigned) numberOfBuffers @@ -62,7 +64,7 @@ if (!_gb || GB_is_sgb(_gb)) { return GB_FRAME_BLENDING_MODE_SIMPLE; } - return GB_is_odd_frame(_gb)? GB_FRAME_BLENDING_MODE_ACCURATE_ODD : GB_FRAME_BLENDING_MODE_ACCURATE_EVEN; + return _oddFrame ? GB_FRAME_BLENDING_MODE_ACCURATE_ODD : GB_FRAME_BLENDING_MODE_ACCURATE_EVEN; } return _frameBlendingMode; } diff --git a/AppleCommon/GBViewMetal.m b/AppleCommon/GBViewMetal.m @@ -85,7 +85,7 @@ static const vector_float2 rect[] = #endif } -- (void) loadShader +- (void)loadShader { NSError *error = nil; NSString *shader_source = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"MasterShader" @@ -160,22 +160,44 @@ static const vector_float2 rect[] = {texture.width, texture.height, 1} // MTLSize }; - [texture replaceRegion:region - mipmapLevel:0 - withBytes:[self currentBuffer] - bytesPerRow:texture.width * 4]; - if ([self frameBlendingMode]) { - [previous_texture replaceRegion:region - mipmapLevel:0 - withBytes:[self previousBuffer] - bytesPerRow:texture.width * 4]; + GB_frame_blending_mode_t mode = [self frameBlendingMode]; + + switch (mode) { + case GB_FRAME_BLENDING_MODE_SIMPLE: + case GB_FRAME_BLENDING_MODE_ACCURATE_EVEN: + [previous_texture replaceRegion:region + mipmapLevel:0 + withBytes:[self previousBuffer] + bytesPerRow:texture.width * 4]; + case GB_FRAME_BLENDING_MODE_DISABLED: + [texture replaceRegion:region + mipmapLevel:0 + withBytes:[self currentBuffer] + bytesPerRow:texture.width * 4]; + break; + case GB_FRAME_BLENDING_MODE_ACCURATE_ODD: + /* + I don't understand GPUs. When rapidly changing `mode`, the shader might sometimes incorrectly + use the old value. I couldn't figure out how to fix it, so I just work around the issue by + avoiding rapid changes in `mode`. + */ + mode = GB_FRAME_BLENDING_MODE_ACCURATE_EVEN; + [previous_texture replaceRegion:region + mipmapLevel:0 + withBytes:[self currentBuffer] + bytesPerRow:texture.width * 4]; + [texture replaceRegion:region + mipmapLevel:0 + withBytes:[self previousBuffer] + bytesPerRow:texture.width * 4]; + break; } MTLRenderPassDescriptor *render_pass_descriptor = view.currentRenderPassDescriptor; id<MTLCommandBuffer> command_buffer = [command_queue commandBuffer]; if (render_pass_descriptor) { - *(GB_frame_blending_mode_t *)[frame_blending_mode_buffer contents] = [self frameBlendingMode]; + *(GB_frame_blending_mode_t *)[frame_blending_mode_buffer contents] = mode; *(vector_float2 *)[output_resolution_buffer contents] = output_resolution; id<MTLRenderCommandEncoder> render_encoder = diff --git a/Cocoa/Document.xib b/Cocoa/Document.xib @@ -703,7 +703,7 @@ </toolbarItem> <toolbarItem implicitItemIdentifier="NSToolbarSpaceItem" id="AoG-LH-J4b"/> <toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="Q0x-n5-Q2Y"/> - <toolbarItem implicitItemIdentifier="E8F74F8F-6DE2-4774-A690-F71D92CD932E" label="" paletteLabel="" tag="-1" title="wtf" sizingBehavior="auto" id="CJX-Ff-7iQ"> + <toolbarItem implicitItemIdentifier="E8F74F8F-6DE2-4774-A690-F71D92CD932E" label="" paletteLabel="" tag="-1" sizingBehavior="auto" id="CJX-Ff-7iQ"> <nil key="toolTip"/> <progressIndicator key="view" wantsLayer="YES" maxValue="100" displayedWhenStopped="NO" indeterminate="YES" controlSize="small" style="spinning" id="rrz-Uh-Nae"> <rect key="frame" x="0.0" y="14" width="16" height="16"/>
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.