1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-28 08:29:34 +00:00

Makes an attempt to have the emulator fill the actual GPU buffers.

Not that they're drawn from correctly yet. I might first take a run at a new quick-path output route for emulated RGB displays, that just seeks to use the scans directly. No intermediate buffers. Besides probably being a good feature, it'll be a good way to ramp further up with Metal.
This commit is contained in:
Thomas Harte 2020-08-08 22:49:02 -04:00
parent bdcf266e45
commit df89a8771c
6 changed files with 60 additions and 12 deletions

View File

@ -1122,6 +1122,7 @@
4B4DC8271D2C2470003C5BF8 /* C1540.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = C1540.hpp; sourceTree = "<group>"; }; 4B4DC8271D2C2470003C5BF8 /* C1540.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = C1540.hpp; sourceTree = "<group>"; };
4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SerialBus.cpp; sourceTree = "<group>"; }; 4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SerialBus.cpp; sourceTree = "<group>"; };
4B4DC82A1D2C27A4003C5BF8 /* SerialBus.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SerialBus.hpp; sourceTree = "<group>"; }; 4B4DC82A1D2C27A4003C5BF8 /* SerialBus.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SerialBus.hpp; sourceTree = "<group>"; };
4B4F2B7024DF99D4000DA6B0 /* CSScanTarget+CppScanTarget.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CSScanTarget+CppScanTarget.h"; sourceTree = "<group>"; };
4B50AF7F242817F40099BBD7 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 4B50AF7F242817F40099BBD7 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
4B51F70920A521D700AFA2C1 /* Source.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Source.hpp; sourceTree = "<group>"; }; 4B51F70920A521D700AFA2C1 /* Source.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Source.hpp; sourceTree = "<group>"; };
4B51F70A20A521D700AFA2C1 /* Observer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Observer.hpp; sourceTree = "<group>"; }; 4B51F70A20A521D700AFA2C1 /* Observer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Observer.hpp; sourceTree = "<group>"; };
@ -2071,6 +2072,7 @@
4B228CDA24DA41880077EF25 /* ScanTarget.metal */, 4B228CDA24DA41880077EF25 /* ScanTarget.metal */,
4B228CD424D773B30077EF25 /* CSScanTarget.mm */, 4B228CD424D773B30077EF25 /* CSScanTarget.mm */,
4B228CD624D773CA0077EF25 /* CSScanTarget.h */, 4B228CD624D773CA0077EF25 /* CSScanTarget.h */,
4B4F2B7024DF99D4000DA6B0 /* CSScanTarget+CppScanTarget.h */,
); );
path = ScanTarget; path = ScanTarget;
sourceTree = "<group>"; sourceTree = "<group>";

View File

@ -11,7 +11,7 @@
#import "CSHighPrecisionTimer.h" #import "CSHighPrecisionTimer.h"
#include "CSROMFetcher.hpp" #include "CSROMFetcher.hpp"
#import "CSScanTarget.h" #import "CSScanTarget+CppScanTarget.h"
#include "MediaTarget.hpp" #include "MediaTarget.hpp"
#include "JoystickMachine.hpp" #include "JoystickMachine.hpp"
@ -353,14 +353,7 @@ struct ActivityObserver: public Activity::Observer {
- (void)setView:(CSScanTargetView *)view aspectRatio:(float)aspectRatio { - (void)setView:(CSScanTargetView *)view aspectRatio:(float)aspectRatio {
_view = view; _view = view;
_view.displayLinkDelegate = self; _view.displayLinkDelegate = self;
// [view performWithGLContext:^{ _machine->scan_producer()->set_scan_target(_view.scanTarget.scanTarget);
// [self setupOutputWithAspectRatio:aspectRatio];
// } flushDrawable:NO];
}
- (void)setupOutputWithAspectRatio:(float)aspectRatio {
// _scanTarget = std::make_unique<Outputs::Display::OpenGL::ScanTarget>();
// _machine->scan_producer()->set_scan_target(_scanTarget.get());
} }
- (void)updateViewForPixelSize:(CGSize)pixelSize { - (void)updateViewForPixelSize:(CGSize)pixelSize {

View File

@ -0,0 +1,16 @@
//
// CSScanTarget+C__ScanTarget.h
// Clock Signal
//
// Created by Thomas Harte on 08/08/2020.
// Copyright © 2020 Thomas Harte. All rights reserved.
//
#import "CSScanTarget.h"
#include "ScanTarget.hpp"
@interface CSScanTarget (CppScanTarget)
@property (nonatomic, readonly, nonnull) Outputs::Display::ScanTarget *scanTarget;
@end

View File

@ -20,9 +20,12 @@ struct Uniforms {
}; };
constexpr size_t NumBufferedScans = 2048; constexpr size_t NumBufferedScans = 2048;
constexpr size_t NumBufferedLines = 2048;
} }
using BufferingScanTarget = Outputs::Display::BufferingScanTarget;
@implementation CSScanTarget { @implementation CSScanTarget {
id<MTLCommandQueue> _commandQueue; id<MTLCommandQueue> _commandQueue;
@ -32,10 +35,17 @@ constexpr size_t NumBufferedScans = 2048;
// Buffers. // Buffers.
id<MTLBuffer> _uniformsBuffer; id<MTLBuffer> _uniformsBuffer;
id<MTLBuffer> _scansBuffer; id<MTLBuffer> _scansBuffer;
id<MTLBuffer> _linesBuffer;
id<MTLBuffer> _writeAreaBuffer;
// Current uniforms. // Current uniforms.
Uniforms _uniforms; Uniforms _uniforms;
// The scan target in C++-world terms and the non-GPU storage for it.
BufferingScanTarget _scanTarget;
BufferingScanTarget::LineMetadata _lineMetadataBuffer[NumBufferedLines];
} }
- (nonnull instancetype)initWithView:(nonnull MTKView *)view { - (nonnull instancetype)initWithView:(nonnull MTKView *)view {
@ -43,7 +53,7 @@ constexpr size_t NumBufferedScans = 2048;
if(self) { if(self) {
_commandQueue = [view.device newCommandQueue]; _commandQueue = [view.device newCommandQueue];
// Allocate space for uniforms. // Allocate space for uniforms and FOR TEST PURPOSES set some.
_uniformsBuffer = [view.device newBufferWithLength:16 options:MTLResourceCPUCacheModeWriteCombined]; _uniformsBuffer = [view.device newBufferWithLength:16 options:MTLResourceCPUCacheModeWriteCombined];
_uniforms.scale[0] = 1024; _uniforms.scale[0] = 1024;
_uniforms.scale[1] = 1024; _uniforms.scale[1] = 1024;
@ -51,10 +61,23 @@ constexpr size_t NumBufferedScans = 2048;
_uniforms.aspectRatioMultiplier = 1.0f; _uniforms.aspectRatioMultiplier = 1.0f;
[self setUniforms]; [self setUniforms];
// Allocate a large buffer for scans. // Allocate buffers for scans and lines and for the write area texture.
_scansBuffer = [view.device _scansBuffer = [view.device
newBufferWithLength:sizeof(Outputs::Display::BufferingScanTarget::Scan)*NumBufferedScans newBufferWithLength:sizeof(Outputs::Display::BufferingScanTarget::Scan)*NumBufferedScans
options:MTLResourceCPUCacheModeWriteCombined | MTLResourceStorageModeShared]; options:MTLResourceCPUCacheModeWriteCombined | MTLResourceStorageModeShared];
_linesBuffer = [view.device
newBufferWithLength:sizeof(Outputs::Display::BufferingScanTarget::Line)*NumBufferedLines
options:MTLResourceCPUCacheModeWriteCombined | MTLResourceStorageModeShared];
_writeAreaBuffer = [view.device
newBufferWithLength:BufferingScanTarget::WriteAreaWidth*BufferingScanTarget::WriteAreaHeight*4
options:MTLResourceCPUCacheModeWriteCombined | MTLResourceStorageModeShared];
// Install all that storage in the buffering scan target.
_scanTarget.set_write_area(reinterpret_cast<uint8_t *>(_writeAreaBuffer.contents));
_scanTarget.set_line_buffer(reinterpret_cast<BufferingScanTarget::Line *>(_linesBuffer.contents), _lineMetadataBuffer, NumBufferedLines);
_scanTarget.set_scan_buffer(reinterpret_cast<BufferingScanTarget::Scan *>(_scansBuffer.contents), NumBufferedScans);
// TEST ONLY: set some test data.
[self setTestScans]; [self setTestScans];
// Generate TEST pipeline. // Generate TEST pipeline.
@ -74,7 +97,7 @@ constexpr size_t NumBufferedScans = 2048;
} }
- (void)setTestScans { - (void)setTestScans {
Outputs::Display::BufferingScanTarget::Scan scans[2]; BufferingScanTarget::Scan scans[2];
scans[0].scan.end_points[0].x = 0; scans[0].scan.end_points[0].x = 0;
scans[0].scan.end_points[0].y = 0; scans[0].scan.end_points[0].y = 0;
scans[0].scan.end_points[1].x = 1024; scans[0].scan.end_points[1].x = 1024;
@ -129,4 +152,8 @@ constexpr size_t NumBufferedScans = 2048;
[commandBuffer commit]; [commandBuffer commit];
} }
- (Outputs::Display::ScanTarget *)scanTarget {
return &_scanTarget;
}
@end @end

View File

@ -11,6 +11,7 @@
#import <MetalKit/MetalKit.h> #import <MetalKit/MetalKit.h>
@class CSScanTargetView; @class CSScanTargetView;
@class CSScanTarget;
typedef NS_ENUM(NSInteger, CSScanTargetViewRedrawEvent) { typedef NS_ENUM(NSInteger, CSScanTargetViewRedrawEvent) {
/// Indicates that AppKit requested a redraw for some reason (mostly likely, the window is being resized). So, /// Indicates that AppKit requested a redraw for some reason (mostly likely, the window is being resized). So,
@ -179,4 +180,9 @@ typedef NS_ENUM(NSInteger, CSScanTargetViewRedrawEvent) {
*/ */
- (void)releaseMouse; - (void)releaseMouse;
/*!
@returns The CSScanTarget being used for this display.
*/
@property(nonatomic, readonly, nonnull) CSScanTarget *scanTarget;
@end @end

View File

@ -164,6 +164,10 @@ static CVReturn DisplayLinkCallback(__unused CVDisplayLinkRef displayLink, const
CVDisplayLinkRelease(_displayLink); CVDisplayLinkRelease(_displayLink);
} }
- (CSScanTarget *)scanTarget {
return _scanTarget;
}
- (CGSize)backingSize { - (CGSize)backingSize {
@synchronized(self) { @synchronized(self) {
return _backingSize; return _backingSize;