1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-02-19 23:29:05 +00:00

Adds first_scan to LineMetadata.

Also reorders `Line` fields to match `Scan` fields, just for visual consistency.
This commit is contained in:
Thomas Harte 2020-08-16 08:59:37 -04:00
parent 512c0079a9
commit 940e9e037e
5 changed files with 23 additions and 12 deletions

View File

@ -5113,6 +5113,7 @@
); );
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_OPTIMIZATION_LEVEL = 2; GCC_OPTIMIZATION_LEVEL = 2;
GCC_PREPROCESSOR_DEFINITIONS = NDEBUG;
MACOSX_DEPLOYMENT_TARGET = 10.10; MACOSX_DEPLOYMENT_TARGET = 10.10;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
}; };

View File

@ -142,6 +142,8 @@ using BufferingScanTarget = Outputs::Display::BufferingScanTarget;
_frameBufferRenderPass.colorAttachments[0].texture = _frameBuffer; _frameBufferRenderPass.colorAttachments[0].texture = _frameBuffer;
_frameBufferRenderPass.colorAttachments[0].loadAction = MTLLoadActionLoad; _frameBufferRenderPass.colorAttachments[0].loadAction = MTLLoadActionLoad;
_frameBufferRenderPass.colorAttachments[0].storeAction = MTLStoreActionStore; _frameBufferRenderPass.colorAttachments[0].storeAction = MTLStoreActionStore;
// TODO: old framebuffer should be resized onto the new one.
} }
} }

View File

@ -45,12 +45,12 @@ struct Scan {
struct Line { struct Line {
struct EndPoint { struct EndPoint {
uint16_t position[2]; uint16_t position[2];
uint16_t cyclesSinceRetrace;
uint16_t compositeAngle; uint16_t compositeAngle;
uint16_t cyclesSinceRetrace;
} endPoints[2]; } endPoints[2];
uint16_t line;
uint8_t compositeAmplitude; uint8_t compositeAmplitude;
uint16_t line;
}; };
// MARK: - Intermediate structs. // MARK: - Intermediate structs.

View File

@ -131,19 +131,19 @@ Outputs::Display::ScanTarget::Scan *BufferingScanTarget::begin_scan() {
return nullptr; 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); const auto read_pointers = read_pointers_.load(std::memory_order::memory_order_relaxed);
// Advance the pointer. // 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. // 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; allocation_has_failed_ = true;
vended_scan_ = nullptr; vended_scan_ = nullptr;
return nullptr; return nullptr;
} }
write_pointers_.scan_buffer = next_write_pointer; write_pointers_.scan = next_write_pointer;
++provided_scans_; ++provided_scans_;
// Fill in extra OpenGL-specific details. // Fill in extra OpenGL-specific details.
@ -211,12 +211,18 @@ void BufferingScanTarget::announce(Event event, bool is_visible, const Outputs::
} else { } else {
// Commit the most recent line only if any scans fell on it and all allocation was successful. // Commit the most recent line only if any scans fell on it and all allocation was successful.
if(!allocation_has_failed_ && provided_scans_) { if(!allocation_has_failed_ && provided_scans_) {
const auto submit_pointers = submit_pointers_.load(std::memory_order::memory_order_relaxed);
// Store metadata. // Store metadata.
LineMetadata &metadata = line_metadata_buffer_[size_t(write_pointers_.line)]; LineMetadata &metadata = line_metadata_buffer_[size_t(write_pointers_.line)];
metadata.is_first_in_frame = is_first_in_frame_; metadata.is_first_in_frame = is_first_in_frame_;
metadata.previous_frame_was_complete = previous_frame_was_complete_; metadata.previous_frame_was_complete = previous_frame_was_complete_;
metadata.first_scan = submit_pointers.scan;
is_first_in_frame_ = false; is_first_in_frame_ = false;
// Sanity check.
assert(((metadata.first_scan + provided_scans_) % scan_buffer_size_) == write_pointers_.scan);
// Store actual line data. // Store actual line data.
Line &active_line = line_buffer_[size_t(write_pointers_.line)]; Line &active_line = line_buffer_[size_t(write_pointers_.line)];
active_line.end_points[1].x = location.x; 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.start.line = read_ahead_pointers.line;
area.end.line = submit_pointers.line; area.end.line = submit_pointers.line;
area.start.scan = read_ahead_pointers.scan_buffer; area.start.scan = read_ahead_pointers.scan;
area.end.scan = submit_pointers.scan_buffer; area.end.scan = submit_pointers.scan;
area.start.write_area_x = TextureAddressGetX(read_ahead_pointers.write_area); area.start.write_area_x = TextureAddressGetX(read_ahead_pointers.write_area);
area.start.write_area_y = TextureAddressGetY(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) { void BufferingScanTarget::complete_output_area(const OutputArea &area) {
PointerSet new_read_pointers; PointerSet new_read_pointers;
new_read_pointers.line = uint16_t(area.end.line); 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); 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); read_pointers_.store(new_read_pointers, std::memory_order::memory_order_relaxed);
} }

View File

@ -70,12 +70,12 @@ class BufferingScanTarget: public Outputs::Display::ScanTarget {
struct Line { struct Line {
struct EndPoint { struct EndPoint {
uint16_t x, y; uint16_t x, y;
uint16_t cycles_since_end_of_horizontal_retrace;
int16_t composite_angle; int16_t composite_angle;
uint16_t cycles_since_end_of_horizontal_retrace;
} end_points[2]; } end_points[2];
uint16_t line;
uint8_t composite_amplitude; uint8_t composite_amplitude;
uint16_t line;
}; };
/// Provides additional metadata about lines; this is separate because it's unlikely to be of /// 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 /// from a frame if performance problems mean that the emulated machine is running
/// more quickly than complete frames can be generated. /// more quickly than complete frames can be generated.
bool previous_frame_was_complete; 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. /// 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; int32_t write_area = 1;
// Points into the scan buffer. // Points into the scan buffer.
uint16_t scan_buffer = 0; uint16_t scan = 0;
// Points into the line buffer. // Points into the line buffer.
uint16_t line = 0; uint16_t line = 0;