From c0323a5677dcd87ddde75364bd310d33a38b212e Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 27 Oct 2012 12:20:52 +0200 Subject: [PATCH] Use Rarch state tracker. --- gfx/d3d9/config_file.hpp | 24 ++++++++ gfx/d3d9/d3d9.cpp | 115 +++++++++++++++++++++++++++++++++++--- gfx/d3d9/render_chain.cpp | 23 ++++---- gfx/d3d9/render_chain.hpp | 12 ++-- 4 files changed, 148 insertions(+), 26 deletions(-) diff --git a/gfx/d3d9/config_file.hpp b/gfx/d3d9/config_file.hpp index 5765fb00eb..749d564dd8 100644 --- a/gfx/d3d9/config_file.hpp +++ b/gfx/d3d9/config_file.hpp @@ -61,6 +61,30 @@ class ConfigFile return false; } + bool get(const std::string& key, unsigned& out) + { + if (!conf) return false; + unsigned val; + if (config_get_uint(conf, key.c_str(), &val)) + { + out = val; + return true; + } + return false; + } + + bool get_hex(const std::string& key, unsigned& out) + { + if (!conf) return false; + unsigned val; + if (config_get_hex(conf, key.c_str(), &val)) + { + out = val; + return true; + } + return false; + } + bool get(const std::string& key, char& out) { if (!conf) return false; diff --git a/gfx/d3d9/d3d9.cpp b/gfx/d3d9/d3d9.cpp index 34a50f6d6d..6f6154fa24 100644 --- a/gfx/d3d9/d3d9.cpp +++ b/gfx/d3d9/d3d9.cpp @@ -17,9 +17,7 @@ // It is written in C++11 (should be compat with MSVC 2010). // Might get rewritten in C99 if I have lots of time to burn. // -// TODO: Integrate state tracker again. // TODO: Multi-monitor. -// TODO: Window resize? #include "d3d9.hpp" #include "render_chain.hpp" @@ -509,15 +507,113 @@ void D3DVideo::init_imports(ConfigFile &conf, const std::string &basedir) std::vector list = tokenize(imports); - std::string path; - if (!conf.get("import_script", path)) - throw std::runtime_error("Didn't find import_script!"); + state_tracker_info tracker_info = {0}; + std::vector uniforms; + for (auto &elem : list) + { + state_tracker_uniform_info info; + std::memset(&info, 0, sizeof(info)); + std::string semantic, wram, input_slot, mask, equal; + + state_tracker_type tracker_type; + state_ram_type ram_type = RARCH_STATE_NONE; + + conf.get(elem + "_semantic", semantic); + if (semantic == "capture") + tracker_type = RARCH_STATE_CAPTURE; + else if (semantic == "transition") + tracker_type = RARCH_STATE_TRANSITION; + else if (semantic == "transition_count") + tracker_type = RARCH_STATE_TRANSITION_COUNT; + else if (semantic == "capture_previous") + tracker_type = RARCH_STATE_CAPTURE_PREV; + else if (semantic == "transition_previous") + tracker_type = RARCH_STATE_TRANSITION_PREV; +#ifdef HAVE_PYTHON + else if (semantic == "python") + tracker_type = RARCH_STATE_PYTHON; +#endif + else + throw std::logic_error("Invalid semantic."); + + unsigned addr = 0; +#ifdef HAVE_PYTHON + if (tracker_type != RARCH_STATE_PYTHON) +#endif + { + unsigned input_slot = 0; + if (conf.get_hex(elem + "_input_slot", input_slot)) + { + switch (input_slot) + { + case 1: + ram_type = RARCH_STATE_INPUT_SLOT1; + break; + + case 2: + ram_type = RARCH_STATE_INPUT_SLOT2; + break; + + default: + throw std::logic_error("Invalid input slot for import."); + } + } + else if (conf.get_hex(elem + "_wram", addr)) + ram_type = RARCH_STATE_WRAM; + else + throw std::logic_error("No address assigned to semantic."); + } + + unsigned memtype; + switch (ram_type) + { + case RARCH_STATE_WRAM: + memtype = RETRO_MEMORY_SYSTEM_RAM; + break; + + default: + memtype = -1u; + } + + if ((memtype != -1u) && (addr >= pretro_get_memory_size(memtype))) + throw std::logic_error("Semantic address out of bounds."); + + unsigned bitmask = 0, bitequal = 0; + conf.get_hex(elem + "_mask", bitmask); + conf.get_hex(elem + "_equal", bitequal); + + strlcpy(info.id, elem.c_str(), sizeof(info.id)); + info.addr = addr; + info.type = tracker_type; + info.ram_type = ram_type; + info.mask = bitmask; + info.equal = bitequal; + + uniforms.push_back(info); + } + + tracker_info.wram = (uint8_t*)pretro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM); + tracker_info.info = uniforms.data(); + tracker_info.info_elem = uniforms.size(); + + std::string py_path; std::string py_class; - if (!conf.get("import_script_class", py_class)) - throw std::runtime_error("Didn't find import_script_class!"); +#ifdef HAVE_PYTHON + conf.get("import_script", py_path); + conf.get("import_script_class", py_class); + tracker_info.script_is_file = true; +#endif - chain->add_state_tracker(basedir + path, py_class, list); + state_tracker_t *state_tracker = state_tracker_init(&tracker_info); + if (!state_tracker) + throw std::runtime_error("Failed to initialize state tracker."); + + std::shared_ptr tracker(state_tracker, [](state_tracker_t *tracker) { + state_tracker_free(tracker); + }); + + chain->add_state_tracker(tracker); } void D3DVideo::init_luts(ConfigFile &conf, const std::string &basedir) @@ -560,8 +656,11 @@ void D3DVideo::init_chain_multipass(const video_info_t &info) size_t pos = basedir.rfind('/'); if (pos == std::string::npos) pos = basedir.rfind('\\'); + if (pos != std::string::npos) basedir.replace(basedir.begin() + pos + 1, basedir.end(), ""); + else + basedir = "./"; bool use_extra_pass = false; bool use_first_pass_only = false; diff --git a/gfx/d3d9/render_chain.cpp b/gfx/d3d9/render_chain.cpp index 03653a51aa..56cb908d7e 100644 --- a/gfx/d3d9/render_chain.cpp +++ b/gfx/d3d9/render_chain.cpp @@ -165,12 +165,9 @@ void RenderChain::add_lut(const std::string &id, luts.push_back(info); } -void RenderChain::add_state_tracker(const std::string &program, - const std::string &py_class, - const std::vector &uniforms) +void RenderChain::add_state_tracker(std::shared_ptr tracker) { - //tracker = std::unique_ptr(new StateTracker( - // program, py_class, uniforms, video_info)); + this->tracker = tracker; } void RenderChain::start_render() @@ -578,7 +575,7 @@ void RenderChain::render_pass(Pass &pass, unsigned pass_index) bind_prev(pass); bind_pass(pass, pass_index); bind_luts(pass); - bind_tracker(pass); + bind_tracker(pass, pass_index); dev->Clear(0, 0, D3DCLEAR_TARGET, 0, 1, 0); if (SUCCEEDED(dev->BeginScene())) @@ -1022,18 +1019,18 @@ void RenderChain::init_fvf(Pass &pass) throw std::runtime_error("Failed to set up FVF!"); } -void RenderChain::bind_tracker(Pass &pass) +void RenderChain::bind_tracker(Pass &pass, unsigned pass_index) { -#if 0 if (!tracker) return; - auto res = tracker->get_uniforms(frame_count); - for (unsigned i = 0; i < res.size(); i++) + if (pass_index == 1) + uniform_cnt = state_get_uniform(tracker.get(), uniform_info, MAX_VARIABLES, frame_count); + + for (unsigned i = 0; i < uniform_cnt; i++) { - set_cg_param(pass.fPrg, res[i].first.c_str(), res[i].second); - set_cg_param(pass.vPrg, res[i].first.c_str(), res[i].second); + set_cg_param(pass.fPrg, uniform_info[i].id, uniform_info[i].value); + set_cg_param(pass.vPrg, uniform_info[i].id, uniform_info[i].value); } -#endif } diff --git a/gfx/d3d9/render_chain.hpp b/gfx/d3d9/render_chain.hpp index 448ce444b3..9a3055bb98 100644 --- a/gfx/d3d9/render_chain.hpp +++ b/gfx/d3d9/render_chain.hpp @@ -17,6 +17,7 @@ #define RENDER_CHAIN_HPP__ #include "d3d9.hpp" +#include "../state_tracker.h" #include #include #include @@ -56,9 +57,7 @@ class RenderChain void add_pass(const LinkInfo &info); void add_lut(const std::string &id, const std::string &path, bool smooth); - void add_state_tracker(const std::string &program, - const std::string &py_class, - const std::vector &uniforms); + void add_state_tracker(std::shared_ptr tracker); bool render(const void *data, unsigned width, unsigned height, unsigned pitch, unsigned rotation); @@ -79,7 +78,10 @@ class RenderChain const video_info_t &video_info; - //std::unique_ptr tracker; +#define MAX_VARIABLES 64 + std::shared_ptr tracker; + struct state_tracker_uniform uniform_info[MAX_VARIABLES]; + unsigned uniform_cnt; enum { Textures = 8, TexturesMask = Textures - 1 }; struct @@ -150,7 +152,7 @@ class RenderChain void bind_orig(Pass &pass); void bind_prev(Pass &pass); void bind_pass(Pass &pass, unsigned pass_index); - void bind_tracker(Pass &pass); + void bind_tracker(Pass &pass, unsigned pass_index); void unbind_all(); void init_fvf(Pass &pass);