1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-23 21:29:11 +00:00

Merge pull request #409 from TomHarte/BitShader

Switches ZX80/81 video bit unpacking to the GPU.
This commit is contained in:
Thomas Harte 2018-04-08 10:35:43 -04:00 committed by GitHub
commit 28947bb3c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -10,15 +10,29 @@
using namespace ZX8081; using namespace ZX8081;
namespace {
/*!
The number of bytes of PCM data to allocate at once; if/when more are required,
the class will simply allocate another batch.
*/
const std::size_t StandardAllocationSize = 40;
/// The amount of time a byte takes to output.
const std::size_t HalfCyclesPerByte = 8;
}
Video::Video() : Video::Video() :
crt_(new Outputs::CRT::CRT(207 * 2, 1, Outputs::CRT::DisplayType::PAL50, 1)) { crt_(new Outputs::CRT::CRT(207 * 2, 1, Outputs::CRT::DisplayType::PAL50, 1)) {
// Set a composite sampling function that assumes 8bpp input grayscale. // Set a composite sampling function that assumes 1bpp input.
// TODO: lessen this to 1bpp.
crt_->set_composite_sampling_function( crt_->set_composite_sampling_function(
"float composite_sample(usampler2D sampler, vec2 coordinate, vec2 icoordinate, float phase, float amplitude)" "float composite_sample(usampler2D sampler, vec2 coordinate, vec2 icoordinate, float phase, float amplitude)"
"{" "{"
"return float(texture(texID, coordinate).r) / 255.0;" "uint texValue = texture(sampler, coordinate).r;"
"texValue <<= int(icoordinate.x * 8) & 7;"
"return float(texValue & 128u);"
"}"); "}");
// Show only the centre 80% of the TV frame. // Show only the centre 80% of the TV frame.
@ -45,10 +59,10 @@ void Video::flush(bool next_sync) {
if(line_data_) { if(line_data_) {
// If there is output data queued, output it either if it's being interrupted by // If there is output data queued, output it either if it's being interrupted by
// sync, or if we're past its end anyway. Otherwise let it be. // sync, or if we're past its end anyway. Otherwise let it be.
unsigned int data_length = static_cast<unsigned int>(line_data_pointer_ - line_data_); unsigned int data_length = static_cast<unsigned int>(line_data_pointer_ - line_data_) * HalfCyclesPerByte;
if(data_length < cycles_since_update_ || next_sync) { if(data_length < cycles_since_update_ || next_sync) {
unsigned int output_length = std::min(data_length, cycles_since_update_); unsigned int output_length = std::min(data_length, cycles_since_update_);
crt_->output_data(output_length, 1); crt_->output_data(output_length, HalfCyclesPerByte);
line_data_pointer_ = line_data_ = nullptr; line_data_pointer_ = line_data_ = nullptr;
cycles_since_update_ -= output_length; cycles_since_update_ -= output_length;
} else return; } else return;
@ -79,25 +93,21 @@ void Video::output_byte(uint8_t byte) {
// Grab a buffer if one isn't already available. // Grab a buffer if one isn't already available.
if(!line_data_) { if(!line_data_) {
line_data_pointer_ = line_data_ = crt_->allocate_write_area(320); line_data_pointer_ = line_data_ = crt_->allocate_write_area(StandardAllocationSize);
} }
// If a buffer was obtained, serialise the new pixels. // If a buffer was obtained, serialise the new pixels.
if(line_data_) { if(line_data_) {
// If the buffer is full, output it now and obtain a new one // If the buffer is full, output it now and obtain a new one
if(line_data_pointer_ - line_data_ == 320) { if(line_data_pointer_ - line_data_ == StandardAllocationSize) {
crt_->output_data(320, 1); crt_->output_data(StandardAllocationSize, HalfCyclesPerByte);
cycles_since_update_ -= 320; cycles_since_update_ -= StandardAllocationSize * HalfCyclesPerByte;
line_data_pointer_ = line_data_ = crt_->allocate_write_area(320); line_data_pointer_ = line_data_ = crt_->allocate_write_area(StandardAllocationSize);
if(!line_data_) return; if(!line_data_) return;
} }
uint8_t mask = 0x80; line_data_pointer_[0] = byte;
for(int c = 0; c < 8; c++) { line_data_pointer_ ++;
line_data_pointer_[c] = (byte & mask) ? 0xff : 0x00;
mask >>= 1;
}
line_data_pointer_ += 8;
} }
} }