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:
parent
512c0079a9
commit
940e9e037e
@ -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)";
|
||||||
};
|
};
|
||||||
|
@ -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.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user