From 4e720d57b258110a0b29255aab50196c9eac5fe9 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 1 Feb 2018 07:53:52 -0500 Subject: [PATCH] With debugging hooks still on display, makes first attempt at dynamic analysis. --- .../Implementation/MultiCRTMachine.cpp | 12 +++++++++- .../Implementation/MultiCRTMachine.hpp | 10 ++++++++ .../Dynamic/MultiMachine/MultiMachine.cpp | 24 ++++++++++++++++++- .../Dynamic/MultiMachine/MultiMachine.hpp | 4 +++- Machines/CRTMachine.hpp | 4 ++++ Machines/MSX/Cartridges/ASCII16kb.hpp | 6 ++++- Machines/MSX/Cartridges/ASCII8kb.hpp | 6 ++++- Machines/MSX/Cartridges/Konami.hpp | 5 +++- Machines/MSX/Cartridges/KonamiWithSCC.hpp | 4 ++++ Machines/MSX/MSX.cpp | 11 ++++++++- Machines/MSX/ROMSlotHandler.hpp | 3 +++ Outputs/CRT/CRT.hpp | 3 +-- Outputs/CRT/Internals/CRTOpenGL.cpp | 7 ++++++ Outputs/CRT/Internals/TextureBuilder.cpp | 18 ++++++++------ Outputs/CRT/Internals/TextureBuilder.hpp | 6 ++++- Outputs/CRT/Internals/TextureTarget.cpp | 4 ++-- 16 files changed, 108 insertions(+), 19 deletions(-) diff --git a/Analyser/Dynamic/MultiMachine/Implementation/MultiCRTMachine.cpp b/Analyser/Dynamic/MultiMachine/Implementation/MultiCRTMachine.cpp index 3aeabe886..d83b937e6 100644 --- a/Analyser/Dynamic/MultiMachine/Implementation/MultiCRTMachine.cpp +++ b/Analyser/Dynamic/MultiMachine/Implementation/MultiCRTMachine.cpp @@ -14,6 +14,12 @@ MultiCRTMachine::MultiCRTMachine(const std::vectorcrt_machine(); +// if(crt_machine) crt_machine->setup_output(aspect_ratio); +// reverse_iterator++; +// } for(const auto &machine: machines_) { CRTMachine::Machine *crt_machine = machine->crt_machine(); if(crt_machine) crt_machine->setup_output(aspect_ratio); @@ -43,7 +49,7 @@ void MultiCRTMachine::run_for(const Cycles cycles) { if(crt_machine) crt_machine->run_for(cycles); } - // TODO: announce an opportunity potentially to reorder the list of machines. + if(delegate_) delegate_->multi_crt_did_run_machines(); } double MultiCRTMachine::get_clock_rate() { @@ -57,6 +63,10 @@ bool MultiCRTMachine::get_clock_is_unlimited() { return crt_machine ? crt_machine->get_clock_is_unlimited() : false; } +void MultiCRTMachine::did_change_machine_order() { + // TODO +} + void MultiCRTMachine::set_delegate(::CRTMachine::Machine::Delegate *delegate) { // TODO } diff --git a/Analyser/Dynamic/MultiMachine/Implementation/MultiCRTMachine.hpp b/Analyser/Dynamic/MultiMachine/Implementation/MultiCRTMachine.hpp index 662db277c..a667ef9ff 100644 --- a/Analyser/Dynamic/MultiMachine/Implementation/MultiCRTMachine.hpp +++ b/Analyser/Dynamic/MultiMachine/Implementation/MultiCRTMachine.hpp @@ -34,8 +34,18 @@ struct MultiCRTMachine: public ::CRTMachine::Machine, public ::CRTMachine::Machi void machine_did_change_clock_rate(Machine *machine) override; void machine_did_change_clock_is_unlimited(Machine *machine) override; + void did_change_machine_order(); + + struct Delegate { + virtual void multi_crt_did_run_machines() = 0; + }; + void set_delegate(Delegate *delegate) { + delegate_ = delegate; + } + private: const std::vector> &machines_; + Delegate *delegate_ = nullptr; }; } diff --git a/Analyser/Dynamic/MultiMachine/MultiMachine.cpp b/Analyser/Dynamic/MultiMachine/MultiMachine.cpp index d668c66a9..380347e98 100644 --- a/Analyser/Dynamic/MultiMachine/MultiMachine.cpp +++ b/Analyser/Dynamic/MultiMachine/MultiMachine.cpp @@ -13,7 +13,9 @@ using namespace Analyser::Dynamic; MultiMachine::MultiMachine(std::vector> &&machines) : machines_(std::move(machines)), configuration_target_(machines_), - crt_machine_(machines_) {} + crt_machine_(machines_) { + crt_machine_.set_delegate(this); +} ConfigurationTarget::Machine *MultiMachine::configuration_target() { return &configuration_target_; @@ -38,3 +40,23 @@ Configurable::Device *MultiMachine::configurable_device() { Utility::TypeRecipient *MultiMachine::type_recipient() { return nullptr; } + +void MultiMachine::multi_crt_did_run_machines() { + DynamicMachine *front = machines_.front().get(); +// for(const auto &machine: machines_) { +// CRTMachine::Machine *crt = machine->crt_machine(); +// printf("%0.2f ", crt->get_confidence()); +// crt->print_type(); +// printf("; "); +// } +// printf("\n"); + std::stable_sort(machines_.begin(), machines_.end(), [] (const auto &lhs, const auto &rhs){ + CRTMachine::Machine *lhs_crt = lhs->crt_machine(); + CRTMachine::Machine *rhs_crt = rhs->crt_machine(); + return lhs_crt->get_confidence() > rhs_crt->get_confidence(); + }); + + if(machines_.front().get() != front) { + crt_machine_.did_change_machine_order(); + } +} diff --git a/Analyser/Dynamic/MultiMachine/MultiMachine.hpp b/Analyser/Dynamic/MultiMachine/MultiMachine.hpp index 759e9452a..bcf3d10ed 100644 --- a/Analyser/Dynamic/MultiMachine/MultiMachine.hpp +++ b/Analyser/Dynamic/MultiMachine/MultiMachine.hpp @@ -32,7 +32,7 @@ namespace Dynamic { If confidence for any machine becomes disproportionately low compared to the others in the set, that machine is removed from the array. */ -class MultiMachine: public ::Machine::DynamicMachine { +class MultiMachine: public ::Machine::DynamicMachine, public MultiCRTMachine::Delegate { public: MultiMachine(std::vector> &&machines); @@ -43,6 +43,8 @@ class MultiMachine: public ::Machine::DynamicMachine { Configurable::Device *configurable_device() override; Utility::TypeRecipient *type_recipient() override; + void multi_crt_did_run_machines() override; + private: std::vector> machines_; diff --git a/Machines/CRTMachine.hpp b/Machines/CRTMachine.hpp index 538bb29cd..67c4286bb 100644 --- a/Machines/CRTMachine.hpp +++ b/Machines/CRTMachine.hpp @@ -44,6 +44,10 @@ class Machine: public ROMMachine::Machine { /// Runs the machine for @c cycles. virtual void run_for(const Cycles cycles) = 0; + /// @returns The confidence that this machine is running content it understands. + virtual float get_confidence() { return 0.5f; } + virtual void print_type() {} + // TODO: sever the clock-rate stuff. virtual double get_clock_rate() { return clock_rate_; diff --git a/Machines/MSX/Cartridges/ASCII16kb.hpp b/Machines/MSX/Cartridges/ASCII16kb.hpp index 644a9f69e..73b4ac16f 100644 --- a/Machines/MSX/Cartridges/ASCII16kb.hpp +++ b/Machines/MSX/Cartridges/ASCII16kb.hpp @@ -19,7 +19,7 @@ class ASCII16kbROMSlotHandler: public ROMSlotHandler { ASCII16kbROMSlotHandler(MSX::MemoryMap &map, int slot) : map_(map), slot_(slot) {} - void write(uint16_t address, uint8_t value) { + void write(uint16_t address, uint8_t value) override { switch(address >> 11) { default: confidence_counter_.add_miss(); @@ -35,6 +35,10 @@ class ASCII16kbROMSlotHandler: public ROMSlotHandler { } } + virtual void print_type() override { + printf("A16"); + } + private: MSX::MemoryMap &map_; int slot_; diff --git a/Machines/MSX/Cartridges/ASCII8kb.hpp b/Machines/MSX/Cartridges/ASCII8kb.hpp index 8230ded1d..76016e9ff 100644 --- a/Machines/MSX/Cartridges/ASCII8kb.hpp +++ b/Machines/MSX/Cartridges/ASCII8kb.hpp @@ -19,7 +19,7 @@ class ASCII8kbROMSlotHandler: public ROMSlotHandler { ASCII8kbROMSlotHandler(MSX::MemoryMap &map, int slot) : map_(map), slot_(slot) {} - void write(uint16_t address, uint8_t value) { + void write(uint16_t address, uint8_t value) override { switch(address >> 11) { default: confidence_counter_.add_miss(); @@ -43,6 +43,10 @@ class ASCII8kbROMSlotHandler: public ROMSlotHandler { } } + virtual void print_type() override { + printf("A8"); + } + private: MSX::MemoryMap &map_; int slot_; diff --git a/Machines/MSX/Cartridges/Konami.hpp b/Machines/MSX/Cartridges/Konami.hpp index a4d7fb594..aa8be8c4c 100644 --- a/Machines/MSX/Cartridges/Konami.hpp +++ b/Machines/MSX/Cartridges/Konami.hpp @@ -19,7 +19,7 @@ class KonamiROMSlotHandler: public ROMSlotHandler { KonamiROMSlotHandler(MSX::MemoryMap &map, int slot) : map_(map), slot_(slot) {} - void write(uint16_t address, uint8_t value) { + void write(uint16_t address, uint8_t value) override { switch(address >> 13) { default: confidence_counter_.add_miss(); @@ -39,6 +39,9 @@ class KonamiROMSlotHandler: public ROMSlotHandler { } } + virtual void print_type() override { + printf("K"); + } private: MSX::MemoryMap &map_; int slot_; diff --git a/Machines/MSX/Cartridges/KonamiWithSCC.hpp b/Machines/MSX/Cartridges/KonamiWithSCC.hpp index 7ecdfd2af..caf74c085 100644 --- a/Machines/MSX/Cartridges/KonamiWithSCC.hpp +++ b/Machines/MSX/Cartridges/KonamiWithSCC.hpp @@ -67,6 +67,10 @@ class KonamiWithSCCROMSlotHandler: public ROMSlotHandler { return 0xff; } + virtual void print_type() override { + printf("KSCC"); + } + private: MSX::MemoryMap &map_; int slot_; diff --git a/Machines/MSX/MSX.cpp b/Machines/MSX/MSX.cpp index 2d550408b..f8d5ee544 100644 --- a/Machines/MSX/MSX.cpp +++ b/Machines/MSX/MSX.cpp @@ -155,9 +155,18 @@ class ConcreteMachine: void run_for(const Cycles cycles) override { z80_.run_for(cycles); + } + float get_confidence() override { if(memory_slots_[1].handler) { - printf("%0.2f\n", memory_slots_[1].handler->get_confidence()); + return memory_slots_[1].handler->get_confidence(); + } + return 0.5f; + } + + void print_type() override { + if(memory_slots_[1].handler) { + memory_slots_[1].handler->print_type(); } } diff --git a/Machines/MSX/ROMSlotHandler.hpp b/Machines/MSX/ROMSlotHandler.hpp index cf742daa8..2ae628785 100644 --- a/Machines/MSX/ROMSlotHandler.hpp +++ b/Machines/MSX/ROMSlotHandler.hpp @@ -69,6 +69,9 @@ class ROMSlotHandler { return confidence_counter_.get_confidence(); } + virtual void print_type() { + } + protected: Analyser::Dynamic::ConfidenceCounter confidence_counter_; }; diff --git a/Outputs/CRT/CRT.hpp b/Outputs/CRT/CRT.hpp index 374cfcb91..521f1833b 100644 --- a/Outputs/CRT/CRT.hpp +++ b/Outputs/CRT/CRT.hpp @@ -232,8 +232,7 @@ class CRT { inline void draw_frame(unsigned int output_width, unsigned int output_height, bool only_if_dirty) { { std::lock_guard function_guard(function_mutex_); - for(std::function function : enqueued_openGL_functions_) - { + for(std::function function : enqueued_openGL_functions_) { function(); } enqueued_openGL_functions_.clear(); diff --git a/Outputs/CRT/Internals/CRTOpenGL.cpp b/Outputs/CRT/Internals/CRTOpenGL.cpp index a95a15cb9..9bd1b7184 100644 --- a/Outputs/CRT/Internals/CRTOpenGL.cpp +++ b/Outputs/CRT/Internals/CRTOpenGL.cpp @@ -107,6 +107,12 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out glDeleteSync(fence_); } + // make sure everything is bound + composite_texture_->bind_texture(); + separated_texture_->bind_texture(); + filtered_texture_->bind_texture(); + if(work_texture_) work_texture_->bind_texture(); + // make sure there's a target to draw to if(!framebuffer_ || static_cast(framebuffer_->get_height()) != output_height || static_cast(framebuffer_->get_width()) != output_width) { std::unique_ptr new_framebuffer(new OpenGL::TextureTarget((GLsizei)output_width, (GLsizei)output_height, pixel_accumulation_texture_unit, GL_LINEAR)); @@ -131,6 +137,7 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out // upload new source pixels, if any glActiveTexture(source_data_texture_unit); + texture_builder.bind(); texture_builder.submit(); // buffer usage restart from 0 for the next time around diff --git a/Outputs/CRT/Internals/TextureBuilder.cpp b/Outputs/CRT/Internals/TextureBuilder.cpp index 5a61fa10c..df005f5d2 100644 --- a/Outputs/CRT/Internals/TextureBuilder.cpp +++ b/Outputs/CRT/Internals/TextureBuilder.cpp @@ -52,16 +52,11 @@ struct DefaultBookender: public TextureBuilder::Bookender { } TextureBuilder::TextureBuilder(std::size_t bytes_per_pixel, GLenum texture_unit) : - bytes_per_pixel_(bytes_per_pixel) { + bytes_per_pixel_(bytes_per_pixel), texture_unit_(texture_unit) { image_.resize(bytes_per_pixel * InputBufferBuilderWidth * InputBufferBuilderHeight); glGenTextures(1, &texture_name_); - glActiveTexture(texture_unit); - glBindTexture(GL_TEXTURE_2D, texture_name_); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + bind(); glTexImage2D(GL_TEXTURE_2D, 0, internalFormatForDepth(bytes_per_pixel), InputBufferBuilderWidth, InputBufferBuilderHeight, 0, formatForDepth(bytes_per_pixel), GL_UNSIGNED_BYTE, nullptr); set_bookender(nullptr); @@ -71,6 +66,15 @@ TextureBuilder::~TextureBuilder() { glDeleteTextures(1, &texture_name_); } +void TextureBuilder::bind() { + glActiveTexture(texture_unit_); + glBindTexture(GL_TEXTURE_2D, texture_name_); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); +} + inline uint8_t *TextureBuilder::pointer_to_location(uint16_t x, uint16_t y) { return &image_[((y * InputBufferBuilderWidth) + x) * bytes_per_pixel_]; } diff --git a/Outputs/CRT/Internals/TextureBuilder.hpp b/Outputs/CRT/Internals/TextureBuilder.hpp index 50917a69e..11e3ff4fe 100644 --- a/Outputs/CRT/Internals/TextureBuilder.hpp +++ b/Outputs/CRT/Internals/TextureBuilder.hpp @@ -114,9 +114,13 @@ class TextureBuilder { /// Supply nullptr to engage the default bookender. void set_bookender(std::unique_ptr bookender); + /// Binds this texture to the unit supplied at instantiation. + void bind(); + private: - // the buffer size + // the buffer size and target unit std::size_t bytes_per_pixel_; + GLenum texture_unit_; // the buffer std::vector image_; diff --git a/Outputs/CRT/Internals/TextureTarget.cpp b/Outputs/CRT/Internals/TextureTarget.cpp index 5742249bf..3dee17c6b 100644 --- a/Outputs/CRT/Internals/TextureTarget.cpp +++ b/Outputs/CRT/Internals/TextureTarget.cpp @@ -26,8 +26,7 @@ TextureTarget::TextureTarget(GLsizei width, GLsizei height, GLenum texture_unit, while(expanded_height_ < height) expanded_height_ <<= 1; glGenTextures(1, &texture_); - glActiveTexture(texture_unit); - glBindTexture(GL_TEXTURE_2D, texture_); + bind_texture(); std::vector blank_buffer(static_cast(expanded_width_ * expanded_height_ * 4), 0); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, static_cast(expanded_width_), static_cast(expanded_height_), 0, GL_RGBA, GL_UNSIGNED_BYTE, blank_buffer.data()); @@ -53,6 +52,7 @@ void TextureTarget::bind_framebuffer() { } void TextureTarget::bind_texture() { + glActiveTexture(texture_unit_); glBindTexture(GL_TEXTURE_2D, texture_); }