1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-02 20:30:00 +00:00

Introduces buffer alignment when writing to textures.

To avoid cross-boundary writes and hopefully to eke out a little better performance.
This commit is contained in:
Thomas Harte 2017-10-17 22:09:48 -04:00
parent edbc60a3fb
commit ce78d9d12c
5 changed files with 13 additions and 10 deletions

View File

@ -207,7 +207,7 @@ class CRTCBusHandler {
// collect some more pixels if output is ongoing
if(!is_sync && state.display_enable) {
if(!pixel_data_) {
pixel_pointer_ = pixel_data_ = crt_->allocate_write_area(320);
pixel_pointer_ = pixel_data_ = crt_->allocate_write_area(320, 8);
}
if(pixel_pointer_) {
// the CPC shuffles output lines as:

View File

@ -106,7 +106,7 @@ void VideoOutput::output_pixels(unsigned int number_of_cycles) {
if(!initial_output_target_ || divider != current_output_divider_) {
if(current_output_target_) crt_->output_data((unsigned int)((current_output_target_ - initial_output_target_) * current_output_divider_), current_output_divider_);
current_output_divider_ = divider;
initial_output_target_ = current_output_target_ = crt_->allocate_write_area(640 / current_output_divider_);
initial_output_target_ = current_output_target_ = crt_->allocate_write_area(640 / current_output_divider_, 4);
}
#define get_pixel() \

View File

@ -221,9 +221,9 @@ class CRT {
@param required_length The number of samples to allocate.
@returns A pointer to the allocated area if room is available; @c nullptr otherwise.
*/
inline uint8_t *allocate_write_area(size_t required_length) {
inline uint8_t *allocate_write_area(size_t required_length, size_t required_alignment = 1) {
std::unique_lock<std::mutex> output_lock = openGL_output_builder_.get_output_lock();
return openGL_output_builder_.texture_builder.allocate_write_area(required_length);
return openGL_output_builder_.texture_builder.allocate_write_area(required_length, required_alignment);
}
/*! Causes appropriate OpenGL or OpenGL ES calls to be issued in order to draw the current CRT state.

View File

@ -60,7 +60,7 @@ inline uint8_t *TextureBuilder::pointer_to_location(uint16_t x, uint16_t y) {
return &image_[((y * InputBufferBuilderWidth) + x) * bytes_per_pixel_];
}
uint8_t *TextureBuilder::allocate_write_area(size_t required_length) {
uint8_t *TextureBuilder::allocate_write_area(size_t required_length, size_t required_alignment) {
// Keep a flag to indicate whether the buffer was full at allocate_write_area; if it was then
// don't return anything now, and decline to act upon follow-up methods. is_full_ may be reset
// by asynchronous calls to submit. was_full_ will not be touched by it.
@ -69,8 +69,10 @@ uint8_t *TextureBuilder::allocate_write_area(size_t required_length) {
// If there's not enough space on this line, move to the next. If the next is where the current
// submission group started, trigger is/was_full_ and return nothing.
if(write_areas_start_x_ + required_length + 2 > InputBufferBuilderWidth) {
size_t alignment_offset = (required_alignment - ((write_areas_start_x_ + 1) % required_alignment)) % required_alignment;
if(write_areas_start_x_ + required_length + 2 + alignment_offset > InputBufferBuilderWidth) {
write_areas_start_x_ = 0;
alignment_offset = (required_alignment - 1) % required_alignment;
write_areas_start_y_ = (write_areas_start_y_ + 1) % InputBufferBuilderHeight;
if(write_areas_start_y_ == first_unsubmitted_y_) {
@ -80,7 +82,7 @@ uint8_t *TextureBuilder::allocate_write_area(size_t required_length) {
}
// Queue up the latest write area.
write_area_.x = write_areas_start_x_ + 1;
write_area_.x = write_areas_start_x_ + 1 + static_cast<uint16_t>(alignment_offset);
write_area_.y = write_areas_start_y_;
write_area_.length = (uint16_t)required_length;

View File

@ -66,10 +66,11 @@ class TextureBuilder {
TextureBuilder(size_t bytes_per_pixel, GLenum texture_unit);
virtual ~TextureBuilder();
/// Finds the first available space of at least @c required_length pixels in size. Calls must be paired off
/// with calls to @c reduce_previous_allocation_to.
/// Finds the first available space of at least @c required_length pixels in size which is suitably aligned
/// for writing of @c required_alignment number of pixels at a time.
/// Calls must be paired off with calls to @c reduce_previous_allocation_to.
/// @returns a pointer to the allocated space if any was available; @c nullptr otherwise.
uint8_t *allocate_write_area(size_t required_length);
uint8_t *allocate_write_area(size_t required_length, size_t required_alignment = 1);
/// Announces that the owner is finished with the region created by the most recent @c allocate_write_area
/// and indicates that its actual final size was @c actual_length.