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:
parent
c12aaea747
commit
4e720d57b2
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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_;
|
||||||
|
|
||||||
|
@ -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_;
|
||||||
|
@ -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_;
|
||||||
|
@ -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_;
|
||||||
|
@ -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_;
|
||||||
|
@ -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_;
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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_;
|
||||||
};
|
};
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
|
@ -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_];
|
||||||
}
|
}
|
||||||
|
@ -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_;
|
||||||
|
@ -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_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user