From 940e9e037e3e7fc44c66e626326a2cc772c93d96 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 16 Aug 2020 08:59:37 -0400 Subject: [PATCH] Adds `first_scan` to LineMetadata. Also reorders `Line` fields to match `Scan` fields, just for visual consistency. --- .../Clock Signal.xcodeproj/project.pbxproj | 1 + .../Clock Signal/ScanTarget/CSScanTarget.mm | 2 ++ .../Clock Signal/ScanTarget/ScanTarget.metal | 4 ++-- Outputs/ScanTargets/BufferingScanTarget.cpp | 20 ++++++++++++------- Outputs/ScanTargets/BufferingScanTarget.hpp | 8 +++++--- 5 files changed, 23 insertions(+), 12 deletions(-) diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index deeab7a7a..c4c11eb2c 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -5113,6 +5113,7 @@ ); GCC_C_LANGUAGE_STANDARD = gnu11; GCC_OPTIMIZATION_LEVEL = 2; + GCC_PREPROCESSOR_DEFINITIONS = NDEBUG; MACOSX_DEPLOYMENT_TARGET = 10.10; PRODUCT_NAME = "$(TARGET_NAME)"; }; diff --git a/OSBindings/Mac/Clock Signal/ScanTarget/CSScanTarget.mm b/OSBindings/Mac/Clock Signal/ScanTarget/CSScanTarget.mm index f6c14ed1d..b95aab15c 100644 --- a/OSBindings/Mac/Clock Signal/ScanTarget/CSScanTarget.mm +++ b/OSBindings/Mac/Clock Signal/ScanTarget/CSScanTarget.mm @@ -142,6 +142,8 @@ using BufferingScanTarget = Outputs::Display::BufferingScanTarget; _frameBufferRenderPass.colorAttachments[0].texture = _frameBuffer; _frameBufferRenderPass.colorAttachments[0].loadAction = MTLLoadActionLoad; _frameBufferRenderPass.colorAttachments[0].storeAction = MTLStoreActionStore; + + // TODO: old framebuffer should be resized onto the new one. } } diff --git a/OSBindings/Mac/Clock Signal/ScanTarget/ScanTarget.metal b/OSBindings/Mac/Clock Signal/ScanTarget/ScanTarget.metal index 5c0081e3f..1fb85a801 100644 --- a/OSBindings/Mac/Clock Signal/ScanTarget/ScanTarget.metal +++ b/OSBindings/Mac/Clock Signal/ScanTarget/ScanTarget.metal @@ -45,12 +45,12 @@ struct Scan { struct Line { struct EndPoint { uint16_t position[2]; - uint16_t cyclesSinceRetrace; uint16_t compositeAngle; + uint16_t cyclesSinceRetrace; } endPoints[2]; - uint16_t line; uint8_t compositeAmplitude; + uint16_t line; }; // MARK: - Intermediate structs. diff --git a/Outputs/ScanTargets/BufferingScanTarget.cpp b/Outputs/ScanTargets/BufferingScanTarget.cpp index b89fcdbdf..cc8b0ecf9 100644 --- a/Outputs/ScanTargets/BufferingScanTarget.cpp +++ b/Outputs/ScanTargets/BufferingScanTarget.cpp @@ -131,19 +131,19 @@ Outputs::Display::ScanTarget::Scan *BufferingScanTarget::begin_scan() { return nullptr; } - const auto result = &scan_buffer_[write_pointers_.scan_buffer]; + const auto result = &scan_buffer_[write_pointers_.scan]; const auto read_pointers = read_pointers_.load(std::memory_order::memory_order_relaxed); // Advance the pointer. - const auto next_write_pointer = decltype(write_pointers_.scan_buffer)((write_pointers_.scan_buffer + 1) % scan_buffer_size_); + const auto next_write_pointer = decltype(write_pointers_.scan)((write_pointers_.scan + 1) % scan_buffer_size_); // Check whether that's too many. - if(next_write_pointer == read_pointers.scan_buffer) { + if(next_write_pointer == read_pointers.scan) { allocation_has_failed_ = true; vended_scan_ = nullptr; return nullptr; } - write_pointers_.scan_buffer = next_write_pointer; + write_pointers_.scan = next_write_pointer; ++provided_scans_; // Fill in extra OpenGL-specific details. @@ -211,12 +211,18 @@ void BufferingScanTarget::announce(Event event, bool is_visible, const Outputs:: } else { // Commit the most recent line only if any scans fell on it and all allocation was successful. if(!allocation_has_failed_ && provided_scans_) { + const auto submit_pointers = submit_pointers_.load(std::memory_order::memory_order_relaxed); + // Store metadata. LineMetadata &metadata = line_metadata_buffer_[size_t(write_pointers_.line)]; metadata.is_first_in_frame = is_first_in_frame_; metadata.previous_frame_was_complete = previous_frame_was_complete_; + metadata.first_scan = submit_pointers.scan; is_first_in_frame_ = false; + // Sanity check. + assert(((metadata.first_scan + provided_scans_) % scan_buffer_size_) == write_pointers_.scan); + // Store actual line data. Line &active_line = line_buffer_[size_t(write_pointers_.line)]; active_line.end_points[1].x = location.x; @@ -296,8 +302,8 @@ BufferingScanTarget::OutputArea BufferingScanTarget::get_output_area() { area.start.line = read_ahead_pointers.line; area.end.line = submit_pointers.line; - area.start.scan = read_ahead_pointers.scan_buffer; - area.end.scan = submit_pointers.scan_buffer; + area.start.scan = read_ahead_pointers.scan; + area.end.scan = submit_pointers.scan; area.start.write_area_x = TextureAddressGetX(read_ahead_pointers.write_area); area.start.write_area_y = TextureAddressGetY(read_ahead_pointers.write_area); @@ -313,7 +319,7 @@ BufferingScanTarget::OutputArea BufferingScanTarget::get_output_area() { void BufferingScanTarget::complete_output_area(const OutputArea &area) { PointerSet new_read_pointers; new_read_pointers.line = uint16_t(area.end.line); - new_read_pointers.scan_buffer = uint16_t(area.end.scan); + new_read_pointers.scan = uint16_t(area.end.scan); new_read_pointers.write_area = TextureAddress(area.end.write_area_x, area.end.write_area_y); read_pointers_.store(new_read_pointers, std::memory_order::memory_order_relaxed); } diff --git a/Outputs/ScanTargets/BufferingScanTarget.hpp b/Outputs/ScanTargets/BufferingScanTarget.hpp index 07ea61da3..5c9b6f3cb 100644 --- a/Outputs/ScanTargets/BufferingScanTarget.hpp +++ b/Outputs/ScanTargets/BufferingScanTarget.hpp @@ -70,12 +70,12 @@ class BufferingScanTarget: public Outputs::Display::ScanTarget { struct Line { struct EndPoint { uint16_t x, y; - uint16_t cycles_since_end_of_horizontal_retrace; int16_t composite_angle; + uint16_t cycles_since_end_of_horizontal_retrace; } end_points[2]; - uint16_t line; uint8_t composite_amplitude; + uint16_t line; }; /// Provides additional metadata about lines; this is separate because it's unlikely to be of @@ -88,6 +88,8 @@ class BufferingScanTarget: public Outputs::Display::ScanTarget { /// from a frame if performance problems mean that the emulated machine is running /// more quickly than complete frames can be generated. bool previous_frame_was_complete; + /// The index of the first scan that will appear on this line. + size_t first_scan; }; /// Sets the area of memory to use as a scan buffer. @@ -205,7 +207,7 @@ class BufferingScanTarget: public Outputs::Display::ScanTarget { int32_t write_area = 1; // Points into the scan buffer. - uint16_t scan_buffer = 0; + uint16_t scan = 0; // Points into the line buffer. uint16_t line = 0;