1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-26 09:29:45 +00:00

With debugging hooks still on display, makes first attempt at dynamic analysis.

This commit is contained in:
Thomas Harte 2018-02-01 07:53:52 -05:00
parent c12aaea747
commit 4e720d57b2
16 changed files with 108 additions and 19 deletions

View File

@ -14,6 +14,12 @@ MultiCRTMachine::MultiCRTMachine(const std::vector<std::unique_ptr<::Machine::Dy
machines_(machines) {} machines_(machines) {}
void MultiCRTMachine::setup_output(float aspect_ratio) { void MultiCRTMachine::setup_output(float aspect_ratio) {
// auto reverse_iterator = machines_.rbegin();
// while(reverse_iterator != machines_.rend()) {
// CRTMachine::Machine *crt_machine = (*reverse_iterator)->crt_machine();
// if(crt_machine) crt_machine->setup_output(aspect_ratio);
// reverse_iterator++;
// }
for(const auto &machine: machines_) { for(const auto &machine: machines_) {
CRTMachine::Machine *crt_machine = machine->crt_machine(); CRTMachine::Machine *crt_machine = machine->crt_machine();
if(crt_machine) crt_machine->setup_output(aspect_ratio); 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); 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() { 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; 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) { void MultiCRTMachine::set_delegate(::CRTMachine::Machine::Delegate *delegate) {
// TODO // TODO
} }

View File

@ -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_rate(Machine *machine) override;
void machine_did_change_clock_is_unlimited(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: private:
const std::vector<std::unique_ptr<::Machine::DynamicMachine>> &machines_; const std::vector<std::unique_ptr<::Machine::DynamicMachine>> &machines_;
Delegate *delegate_ = nullptr;
}; };
} }

View File

@ -13,7 +13,9 @@ using namespace Analyser::Dynamic;
MultiMachine::MultiMachine(std::vector<std::unique_ptr<DynamicMachine>> &&machines) : MultiMachine::MultiMachine(std::vector<std::unique_ptr<DynamicMachine>> &&machines) :
machines_(std::move(machines)), machines_(std::move(machines)),
configuration_target_(machines_), configuration_target_(machines_),
crt_machine_(machines_) {} crt_machine_(machines_) {
crt_machine_.set_delegate(this);
}
ConfigurationTarget::Machine *MultiMachine::configuration_target() { ConfigurationTarget::Machine *MultiMachine::configuration_target() {
return &configuration_target_; return &configuration_target_;
@ -38,3 +40,23 @@ Configurable::Device *MultiMachine::configurable_device() {
Utility::TypeRecipient *MultiMachine::type_recipient() { Utility::TypeRecipient *MultiMachine::type_recipient() {
return nullptr; 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();
}
}

View File

@ -32,7 +32,7 @@ namespace Dynamic {
If confidence for any machine becomes disproportionately low compared to If confidence for any machine becomes disproportionately low compared to
the others in the set, that machine is removed from the array. 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: public:
MultiMachine(std::vector<std::unique_ptr<DynamicMachine>> &&machines); MultiMachine(std::vector<std::unique_ptr<DynamicMachine>> &&machines);
@ -43,6 +43,8 @@ class MultiMachine: public ::Machine::DynamicMachine {
Configurable::Device *configurable_device() override; Configurable::Device *configurable_device() override;
Utility::TypeRecipient *type_recipient() override; Utility::TypeRecipient *type_recipient() override;
void multi_crt_did_run_machines() override;
private: private:
std::vector<std::unique_ptr<DynamicMachine>> machines_; std::vector<std::unique_ptr<DynamicMachine>> machines_;

View File

@ -44,6 +44,10 @@ class Machine: public ROMMachine::Machine {
/// Runs the machine for @c cycles. /// Runs the machine for @c cycles.
virtual void run_for(const Cycles cycles) = 0; 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. // TODO: sever the clock-rate stuff.
virtual double get_clock_rate() { virtual double get_clock_rate() {
return clock_rate_; return clock_rate_;

View File

@ -19,7 +19,7 @@ class ASCII16kbROMSlotHandler: public ROMSlotHandler {
ASCII16kbROMSlotHandler(MSX::MemoryMap &map, int slot) : ASCII16kbROMSlotHandler(MSX::MemoryMap &map, int slot) :
map_(map), slot_(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) { switch(address >> 11) {
default: default:
confidence_counter_.add_miss(); confidence_counter_.add_miss();
@ -35,6 +35,10 @@ class ASCII16kbROMSlotHandler: public ROMSlotHandler {
} }
} }
virtual void print_type() override {
printf("A16");
}
private: private:
MSX::MemoryMap &map_; MSX::MemoryMap &map_;
int slot_; int slot_;

View File

@ -19,7 +19,7 @@ class ASCII8kbROMSlotHandler: public ROMSlotHandler {
ASCII8kbROMSlotHandler(MSX::MemoryMap &map, int slot) : ASCII8kbROMSlotHandler(MSX::MemoryMap &map, int slot) :
map_(map), slot_(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) { switch(address >> 11) {
default: default:
confidence_counter_.add_miss(); confidence_counter_.add_miss();
@ -43,6 +43,10 @@ class ASCII8kbROMSlotHandler: public ROMSlotHandler {
} }
} }
virtual void print_type() override {
printf("A8");
}
private: private:
MSX::MemoryMap &map_; MSX::MemoryMap &map_;
int slot_; int slot_;

View File

@ -19,7 +19,7 @@ class KonamiROMSlotHandler: public ROMSlotHandler {
KonamiROMSlotHandler(MSX::MemoryMap &map, int slot) : KonamiROMSlotHandler(MSX::MemoryMap &map, int slot) :
map_(map), slot_(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) { switch(address >> 13) {
default: default:
confidence_counter_.add_miss(); confidence_counter_.add_miss();
@ -39,6 +39,9 @@ class KonamiROMSlotHandler: public ROMSlotHandler {
} }
} }
virtual void print_type() override {
printf("K");
}
private: private:
MSX::MemoryMap &map_; MSX::MemoryMap &map_;
int slot_; int slot_;

View File

@ -67,6 +67,10 @@ class KonamiWithSCCROMSlotHandler: public ROMSlotHandler {
return 0xff; return 0xff;
} }
virtual void print_type() override {
printf("KSCC");
}
private: private:
MSX::MemoryMap &map_; MSX::MemoryMap &map_;
int slot_; int slot_;

View File

@ -155,9 +155,18 @@ class ConcreteMachine:
void run_for(const Cycles cycles) override { void run_for(const Cycles cycles) override {
z80_.run_for(cycles); z80_.run_for(cycles);
}
float get_confidence() override {
if(memory_slots_[1].handler) { 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();
} }
} }

View File

@ -69,6 +69,9 @@ class ROMSlotHandler {
return confidence_counter_.get_confidence(); return confidence_counter_.get_confidence();
} }
virtual void print_type() {
}
protected: protected:
Analyser::Dynamic::ConfidenceCounter confidence_counter_; Analyser::Dynamic::ConfidenceCounter confidence_counter_;
}; };

View File

@ -232,8 +232,7 @@ class CRT {
inline void draw_frame(unsigned int output_width, unsigned int output_height, bool only_if_dirty) { inline void draw_frame(unsigned int output_width, unsigned int output_height, bool only_if_dirty) {
{ {
std::lock_guard<std::mutex> function_guard(function_mutex_); std::lock_guard<std::mutex> function_guard(function_mutex_);
for(std::function<void(void)> function : enqueued_openGL_functions_) for(std::function<void(void)> function : enqueued_openGL_functions_) {
{
function(); function();
} }
enqueued_openGL_functions_.clear(); enqueued_openGL_functions_.clear();

View File

@ -107,6 +107,12 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
glDeleteSync(fence_); 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 // make sure there's a target to draw to
if(!framebuffer_ || static_cast<unsigned int>(framebuffer_->get_height()) != output_height || static_cast<unsigned int>(framebuffer_->get_width()) != output_width) { if(!framebuffer_ || static_cast<unsigned int>(framebuffer_->get_height()) != output_height || static_cast<unsigned int>(framebuffer_->get_width()) != output_width) {
std::unique_ptr<OpenGL::TextureTarget> new_framebuffer(new OpenGL::TextureTarget((GLsizei)output_width, (GLsizei)output_height, pixel_accumulation_texture_unit, GL_LINEAR)); std::unique_ptr<OpenGL::TextureTarget> 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 // upload new source pixels, if any
glActiveTexture(source_data_texture_unit); glActiveTexture(source_data_texture_unit);
texture_builder.bind();
texture_builder.submit(); texture_builder.submit();
// buffer usage restart from 0 for the next time around // buffer usage restart from 0 for the next time around

View File

@ -52,16 +52,11 @@ struct DefaultBookender: public TextureBuilder::Bookender {
} }
TextureBuilder::TextureBuilder(std::size_t bytes_per_pixel, GLenum texture_unit) : 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); image_.resize(bytes_per_pixel * InputBufferBuilderWidth * InputBufferBuilderHeight);
glGenTextures(1, &texture_name_); glGenTextures(1, &texture_name_);
glActiveTexture(texture_unit); bind();
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);
glTexImage2D(GL_TEXTURE_2D, 0, internalFormatForDepth(bytes_per_pixel), InputBufferBuilderWidth, InputBufferBuilderHeight, 0, formatForDepth(bytes_per_pixel), GL_UNSIGNED_BYTE, nullptr); glTexImage2D(GL_TEXTURE_2D, 0, internalFormatForDepth(bytes_per_pixel), InputBufferBuilderWidth, InputBufferBuilderHeight, 0, formatForDepth(bytes_per_pixel), GL_UNSIGNED_BYTE, nullptr);
set_bookender(nullptr); set_bookender(nullptr);
@ -71,6 +66,15 @@ TextureBuilder::~TextureBuilder() {
glDeleteTextures(1, &texture_name_); 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) { inline uint8_t *TextureBuilder::pointer_to_location(uint16_t x, uint16_t y) {
return &image_[((y * InputBufferBuilderWidth) + x) * bytes_per_pixel_]; return &image_[((y * InputBufferBuilderWidth) + x) * bytes_per_pixel_];
} }

View File

@ -114,9 +114,13 @@ class TextureBuilder {
/// Supply nullptr to engage the default bookender. /// Supply nullptr to engage the default bookender.
void set_bookender(std::unique_ptr<Bookender> bookender); void set_bookender(std::unique_ptr<Bookender> bookender);
/// Binds this texture to the unit supplied at instantiation.
void bind();
private: private:
// the buffer size // the buffer size and target unit
std::size_t bytes_per_pixel_; std::size_t bytes_per_pixel_;
GLenum texture_unit_;
// the buffer // the buffer
std::vector<uint8_t> image_; std::vector<uint8_t> image_;

View File

@ -26,8 +26,7 @@ TextureTarget::TextureTarget(GLsizei width, GLsizei height, GLenum texture_unit,
while(expanded_height_ < height) expanded_height_ <<= 1; while(expanded_height_ < height) expanded_height_ <<= 1;
glGenTextures(1, &texture_); glGenTextures(1, &texture_);
glActiveTexture(texture_unit); bind_texture();
glBindTexture(GL_TEXTURE_2D, texture_);
std::vector<uint8_t> blank_buffer(static_cast<size_t>(expanded_width_ * expanded_height_ * 4), 0); std::vector<uint8_t> blank_buffer(static_cast<size_t>(expanded_width_ * expanded_height_ * 4), 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, static_cast<GLsizei>(expanded_width_), static_cast<GLsizei>(expanded_height_), 0, GL_RGBA, GL_UNSIGNED_BYTE, blank_buffer.data()); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, static_cast<GLsizei>(expanded_width_), static_cast<GLsizei>(expanded_height_), 0, GL_RGBA, GL_UNSIGNED_BYTE, blank_buffer.data());
@ -53,6 +52,7 @@ void TextureTarget::bind_framebuffer() {
} }
void TextureTarget::bind_texture() { void TextureTarget::bind_texture() {
glActiveTexture(texture_unit_);
glBindTexture(GL_TEXTURE_2D, texture_); glBindTexture(GL_TEXTURE_2D, texture_);
} }