diff options
author | 2022-03-16 03:32:33 +0100 | |
---|---|---|
committer | 2022-03-15 22:32:33 -0400 | |
commit | 92ece92fedb15efa82a12901bc343b46a0f06905 (patch) | |
tree | dc16d467c041bb86470b409111d156ef803b73d3 | |
parent | 8d267ad2c7d3e757bf47d05ce816e060e37de401 (diff) |
Updated BGFX fixes; verified as working on Linux and Windows. (#9420)
* -bgfx: Improved stability when encountering missing files, and improved multi-window stability. [Ryan Holtz]
* -osd: Added video-init fallback functionality to other OSDs. [Ryan Holtz]
* -bgfx: Fixed issues from the previous batch of changes. [Ryan Holtz]
* -osdwindow: Remove no-longer-needed addition of post_create(). [Ryan Holtz]
-rw-r--r-- | src/osd/mac/window.cpp | 44 | ||||
-rw-r--r-- | src/osd/modules/render/bgfx/chainentryreader.cpp | 4 | ||||
-rw-r--r-- | src/osd/modules/render/bgfx/chainmanager.cpp | 8 | ||||
-rw-r--r-- | src/osd/modules/render/bgfx/effect.cpp | 1 | ||||
-rw-r--r-- | src/osd/modules/render/bgfx/effect.h | 3 | ||||
-rw-r--r-- | src/osd/modules/render/bgfx/effectmanager.cpp | 96 | ||||
-rw-r--r-- | src/osd/modules/render/bgfx/effectmanager.h | 8 | ||||
-rw-r--r-- | src/osd/modules/render/bgfx/effectreader.cpp | 129 | ||||
-rw-r--r-- | src/osd/modules/render/bgfx/effectreader.h | 9 | ||||
-rw-r--r-- | src/osd/modules/render/bgfx/shadermanager.cpp | 59 | ||||
-rw-r--r-- | src/osd/modules/render/bgfx/shadermanager.h | 9 | ||||
-rw-r--r-- | src/osd/modules/render/bgfx/texturemanager.cpp | 2 | ||||
-rw-r--r-- | src/osd/modules/render/bgfx/uniform.cpp | 12 | ||||
-rw-r--r-- | src/osd/modules/render/bgfx/uniform.h | 2 | ||||
-rw-r--r-- | src/osd/modules/render/bgfx/view.cpp | 7 | ||||
-rw-r--r-- | src/osd/modules/render/drawbgfx.cpp | 364 | ||||
-rw-r--r-- | src/osd/modules/render/drawbgfx.h | 9 | ||||
-rw-r--r-- | src/osd/sdl/window.cpp | 54 | ||||
-rw-r--r-- | src/osd/windows/window.cpp | 3 |
19 files changed, 528 insertions, 295 deletions
diff --git a/src/osd/mac/window.cpp b/src/osd/mac/window.cpp index 4a150e54a35..ea2adbb631f 100644 --- a/src/osd/mac/window.cpp +++ b/src/osd/mac/window.cpp @@ -69,17 +69,43 @@ bool mac_osd_interface::window_init() { osd_printf_verbose("Enter macwindow_init\n"); - // initialize the drawers - - switch (video_config.mode) - { - case VIDEO_MODE_BGFX: - renderer_bgfx::init(machine()); - break; - case VIDEO_MODE_OPENGL: - renderer_ogl::init(machine()); + // initialize the renderer + const int fallbacks[VIDEO_MODE_COUNT] = { + -1, // NONE -> no fallback + -1, // No GDI on macOS + VIDEO_MODE_OPENGL, // BGFX -> OpenGL + -1, // OpenGL -> no fallback + -1, // No SDL2ACCEL on macOS + -1, // No D3D on macOS + -1 // No SOFT on macOS + }; + + int current_mode = video_config.mode; + while (current_mode != VIDEO_MODE_NONE) + { + bool error = false; + switch(current_mode) + { + case VIDEO_MODE_BGFX: + error = renderer_bgfx::init(machine()); + break; + case VIDEO_MODE_OPENGL: + renderer_ogl::init(machine()); + break; + default: + fatalerror("Unknown video mode."); + break; + } + if (error) + { + current_mode = fallbacks[current_mode]; + } + else + { break; + } } + video_config.mode = current_mode; // set up the window list osd_printf_verbose("Leave macwindow_init\n"); diff --git a/src/osd/modules/render/bgfx/chainentryreader.cpp b/src/osd/modules/render/bgfx/chainentryreader.cpp index c179992c6b0..5ac97fd1d45 100644 --- a/src/osd/modules/render/bgfx/chainentryreader.cpp +++ b/src/osd/modules/render/bgfx/chainentryreader.cpp @@ -35,11 +35,11 @@ bgfx_chain_entry* chain_entry_reader::read_from_value(const Value& value, std::s { if (!validate_parameters(value, prefix)) { - printf("Failed validation\n"); + osd_printf_error("Chain entry failed validation.\n"); return nullptr; } - bgfx_effect* effect = chains.effects().effect(value["effect"].GetString()); + bgfx_effect* effect = chains.effects().get_or_load_effect(chains.options(), value["effect"].GetString()); if (effect == nullptr) { return nullptr; diff --git a/src/osd/modules/render/bgfx/chainmanager.cpp b/src/osd/modules/render/bgfx/chainmanager.cpp index 73128c12a0b..b0a239756c6 100644 --- a/src/osd/modules/render/bgfx/chainmanager.cpp +++ b/src/osd/modules/render/bgfx/chainmanager.cpp @@ -61,11 +61,11 @@ chain_manager::~chain_manager() void chain_manager::init_texture_converters() { m_converters.push_back(nullptr); - m_converters.push_back(m_effects.effect("misc/texconv_palette16")); - m_converters.push_back(m_effects.effect("misc/texconv_rgb32")); + m_converters.push_back(m_effects.get_or_load_effect(m_options, "misc/texconv_palette16")); + m_converters.push_back(m_effects.get_or_load_effect(m_options, "misc/texconv_rgb32")); m_converters.push_back(nullptr); - m_converters.push_back(m_effects.effect("misc/texconv_yuy16")); - m_adjuster = m_effects.effect("misc/bcg_adjust"); + m_converters.push_back(m_effects.get_or_load_effect(m_options, "misc/texconv_yuy16")); + m_adjuster = m_effects.get_or_load_effect(m_options, "misc/bcg_adjust"); } void chain_manager::refresh_available_chains() diff --git a/src/osd/modules/render/bgfx/effect.cpp b/src/osd/modules/render/bgfx/effect.cpp index 6707b5cfc43..06fddee66ad 100644 --- a/src/osd/modules/render/bgfx/effect.cpp +++ b/src/osd/modules/render/bgfx/effect.cpp @@ -25,6 +25,7 @@ bgfx_effect::bgfx_effect(uint64_t state, bgfx::ShaderHandle vertex_shader, bgfx: delete uniforms[i]; continue; } + uniforms[i]->create(); m_uniforms[uniforms[i]->name()] = uniforms[i]; } } diff --git a/src/osd/modules/render/bgfx/effect.h b/src/osd/modules/render/bgfx/effect.h index 02ef9fd4f54..ca1be77c73d 100644 --- a/src/osd/modules/render/bgfx/effect.h +++ b/src/osd/modules/render/bgfx/effect.h @@ -26,7 +26,8 @@ public: ~bgfx_effect(); void submit(int view, uint64_t blend = 0L); - bgfx_uniform* uniform(std::string name); + bgfx_uniform *uniform(std::string name); + bool is_valid() { return m_program_handle.idx != bgfx::kInvalidHandle; } private: uint64_t m_state; diff --git a/src/osd/modules/render/bgfx/effectmanager.cpp b/src/osd/modules/render/bgfx/effectmanager.cpp index 6462ae75f72..98bc9a72097 100644 --- a/src/osd/modules/render/bgfx/effectmanager.cpp +++ b/src/osd/modules/render/bgfx/effectmanager.cpp @@ -23,68 +23,79 @@ #include "effectreader.h" #include "effect.h" -using namespace rapidjson; - -effect_manager::~effect_manager() -{ - for (std::pair<std::string, bgfx_effect*> effect : m_effects) - { - delete effect.second; - } - m_effects.clear(); -} - -bgfx_effect* effect_manager::effect(std::string name) -{ - std::map<std::string, bgfx_effect*>::iterator iter = m_effects.find(name); - if (iter != m_effects.end()) - { - return iter->second; - } - - return load_effect(name); -} - -bgfx_effect* effect_manager::load_effect(std::string name) +static bool prepare_effect_document(std::string &name, osd_options &options, rapidjson::Document &document) { std::string full_name = name; - if (full_name.length() < 5 || (full_name.compare(full_name.length() - 5, 5, ".json") != 0)) { + if (full_name.length() < 5 || (full_name.compare(full_name.length() - 5, 5, ".json") != 0)) + { full_name = full_name + ".json"; } + std::string path; - osd_subst_env(path, util::string_format("%s" PATH_SEPARATOR "effects" PATH_SEPARATOR, m_options.bgfx_path())); + osd_subst_env(path, util::string_format("%s" PATH_SEPARATOR "effects" PATH_SEPARATOR, options.bgfx_path())); path += full_name; bx::FileReader reader; if (!bx::open(&reader, path.c_str())) { - printf("Unable to open effect file %s\n", path.c_str()); - return nullptr; + osd_printf_error("Unable to open effect file %s\n", path.c_str()); + return false; } int32_t size (bx::getSize(&reader)); - char* data = new char[size + 1]; bx::read(&reader, reinterpret_cast<void*>(data), size); bx::close(&reader); data[size] = 0; - Document document; - document.Parse<kParseCommentsFlag>(data); + document.Parse<rapidjson::kParseCommentsFlag>(data); delete [] data; - if (document.HasParseError()) { - std::string error(GetParseError_En(document.GetParseError())); - printf("Unable to parse effect %s. Errors returned:\n", path.c_str()); - printf("%s\n", error.c_str()); + if (document.HasParseError()) + { + std::string error(rapidjson::GetParseError_En(document.GetParseError())); + osd_printf_error("Unable to parse effect %s. Errors returned:\n", path.c_str()); + osd_printf_error("%s\n", error.c_str()); + return false; + } + + return true; +} + +effect_manager::~effect_manager() +{ + for (std::pair<std::string, bgfx_effect*> effect : m_effects) + { + delete effect.second; + } + m_effects.clear(); +} + +bgfx_effect* effect_manager::get_or_load_effect(osd_options &options, std::string name) +{ + std::map<std::string, bgfx_effect*>::iterator iter = m_effects.find(name); + if (iter != m_effects.end()) + { + return iter->second; + } + + return load_effect(options, name); +} + +bgfx_effect* effect_manager::load_effect(osd_options &options, std::string name) +{ + rapidjson::Document document; + if (!prepare_effect_document(name, options, document)) + { return nullptr; } - bgfx_effect* effect = effect_reader::read_from_value(document, "Effect '" + name + "': ", m_shaders); + bgfx_effect* effect = effect_reader::read_from_value(document, "Effect '" + name + "': ", options, m_shaders); - if (effect == nullptr) { - printf("Unable to load effect %s\n", path.c_str()); + if (effect == nullptr) + { + osd_printf_error("Unable to load effect %s\n", name.c_str()); return nullptr; } @@ -92,3 +103,14 @@ bgfx_effect* effect_manager::load_effect(std::string name) return effect; } + +bool effect_manager::validate_effect(osd_options &options, std::string name) +{ + rapidjson::Document document; + if (!prepare_effect_document(name, options, document)) + { + return false; + } + + return effect_reader::validate_value(document, "Effect '" + name + "': ", options); +} diff --git a/src/osd/modules/render/bgfx/effectmanager.h b/src/osd/modules/render/bgfx/effectmanager.h index 8125741c7ff..5d8bf3f5c93 100644 --- a/src/osd/modules/render/bgfx/effectmanager.h +++ b/src/osd/modules/render/bgfx/effectmanager.h @@ -25,16 +25,16 @@ class bgfx_effect; class effect_manager { public: - effect_manager(osd_options& options, shader_manager& shaders) : m_options(options), m_shaders(shaders) { } + effect_manager(shader_manager& shaders) : m_shaders(shaders) { } ~effect_manager(); // Getters - bgfx_effect* effect(std::string name); + bgfx_effect* get_or_load_effect(osd_options &options, std::string name); + static bool validate_effect(osd_options &options, std::string name); private: - bgfx_effect* load_effect(std::string name); + bgfx_effect* load_effect(osd_options& options, std::string name); - osd_options& m_options; shader_manager& m_shaders; std::map<std::string, bgfx_effect*> m_effects; }; diff --git a/src/osd/modules/render/bgfx/effectreader.cpp b/src/osd/modules/render/bgfx/effectreader.cpp index 3e51cb9d9dc..fd59b0bde44 100644 --- a/src/osd/modules/render/bgfx/effectreader.cpp +++ b/src/osd/modules/render/bgfx/effectreader.cpp @@ -23,13 +23,77 @@ #include "effectreader.h" -bgfx_effect* effect_reader::read_from_value(const Value& value, std::string prefix, shader_manager& shaders) +bgfx_effect *effect_reader::read_from_value(const Value& value, std::string prefix, osd_options &options, shader_manager& shaders) { - if (!validate_parameters(value, prefix)) + uint64_t flags = 0; + std::string vertex_name; + std::string fragment_name; + bgfx::ShaderHandle vertex_shader = BGFX_INVALID_HANDLE; + bgfx::ShaderHandle fragment_shader = BGFX_INVALID_HANDLE; + std::vector<bgfx_uniform *> uniforms; + + if (!get_base_effect_data(value, prefix, flags, vertex_name, fragment_name, uniforms)) + { + return nullptr; + } + + if (!get_shader_data(value, options, shaders, vertex_name, vertex_shader, fragment_name, fragment_shader)) { + clear_uniform_list(uniforms); return nullptr; } + bgfx_effect *effect = new bgfx_effect(flags, vertex_shader, fragment_shader, uniforms); + if (effect->is_valid()) + { + return effect; + } + + delete effect; + + return nullptr; +} + +bool effect_reader::validate_value(const Value& value, std::string prefix, osd_options &options) +{ + if (!validate_parameters(value, prefix)) + { + return false; + } + + uint64_t flags = 0; + std::string vertex_name; + std::string fragment_name; + std::vector<bgfx_uniform *> uniforms; + + if (!get_base_effect_data(value, prefix, flags, vertex_name, fragment_name, uniforms)) + { + return false; + } + + if (!shader_manager::is_shader_present(options, vertex_name)) + { + clear_uniform_list(uniforms); + return false; + } + + if (!shader_manager::is_shader_present(options, fragment_name)) + { + clear_uniform_list(uniforms); + return false; + } + + return true; +} + +bool effect_reader::get_base_effect_data(const Value& value, std::string &prefix, uint64_t &flags, std::string &vertex_name, std::string &fragment_name, + std::vector<bgfx_uniform *> &uniforms) +{ + if (!validate_parameters(value, prefix)) + { + return false; + } + uint64_t blend = 0; if (value.HasMember("blend")) { @@ -38,34 +102,21 @@ bgfx_effect* effect_reader::read_from_value(const Value& value, std::string pref uint64_t depth = depth_reader::read_from_value(value["depth"], prefix + "depth: "); uint64_t cull = cull_reader::read_from_value(value["cull"]); uint64_t write = write_reader::read_from_value(value["write"]); + flags = blend | depth | cull | write; - std::vector<bgfx_uniform*> uniforms; const Value& uniform_array = value["uniforms"]; for (uint32_t i = 0; i < uniform_array.Size(); i++) { - bgfx_uniform* uniform = uniform_reader::read_from_value(uniform_array[i], prefix + "uniforms[" + std::to_string(i) + "]: "); + bgfx_uniform *uniform = uniform_reader::read_from_value(uniform_array[i], prefix + "uniforms[" + std::to_string(i) + "]: "); if (uniform == nullptr) { - return nullptr; + return false; } uniforms.push_back(uniform); } - std::string vertex_name(value["vertex"].GetString()); - bgfx::ShaderHandle vertex_shader = shaders.shader(vertex_name); - if (vertex_shader.idx == 0xffff) - { - for (bgfx_uniform* uniform : uniforms) - { - if (uniform != nullptr) - { - delete uniform; - } - } - return nullptr; - } + vertex_name = value["vertex"].GetString(); - std::string fragment_name(""); if (value.HasMember("fragment")) { fragment_name = value["fragment"].GetString(); @@ -74,20 +125,38 @@ bgfx_effect* effect_reader::read_from_value(const Value& value, std::string pref { fragment_name = value["pixel"].GetString(); } - bgfx::ShaderHandle fragment_shader = shaders.shader(fragment_name); - if (fragment_shader.idx == 0xffff) + else { - for (bgfx_uniform* uniform : uniforms) - { - if (uniform != nullptr) - { - delete uniform; - } - } - return nullptr; + fragment_name = ""; } - return new bgfx_effect(blend | depth | cull | write, vertex_shader, fragment_shader, uniforms); + return true; +} + +bool effect_reader::get_shader_data(const Value& value, osd_options &options, shader_manager &shaders, std::string &vertex_name, bgfx::ShaderHandle &vertex_shader, + std::string &fragment_name, bgfx::ShaderHandle &fragment_shader) +{ + vertex_shader = shaders.load_shader(options, vertex_name); + if (vertex_shader.idx == bgfx::kInvalidHandle) + { + return false; + } + + fragment_shader = shaders.load_shader(options, fragment_name); + if (fragment_shader.idx == bgfx::kInvalidHandle) + { + return false; + } + + return true; +} + +void effect_reader::clear_uniform_list(std::vector<bgfx_uniform *> &uniforms) +{ + for (bgfx_uniform *uniform : uniforms) + { + delete uniform; + } } bool effect_reader::validate_parameters(const Value& value, std::string prefix) diff --git a/src/osd/modules/render/bgfx/effectreader.h b/src/osd/modules/render/bgfx/effectreader.h index 0bc1b334435..d632c7326c2 100644 --- a/src/osd/modules/render/bgfx/effectreader.h +++ b/src/osd/modules/render/bgfx/effectreader.h @@ -16,14 +16,21 @@ #include "statereader.h" class bgfx_effect; +class bgfx_uniform; class shader_manager; class effect_reader : public state_reader { public: - static bgfx_effect* read_from_value(const Value& value, std::string prefix, shader_manager& shaders); + static bgfx_effect *read_from_value(const Value& value, std::string prefix, osd_options &options, shader_manager& shaders); + static bool validate_value(const Value& value, std::string prefix, osd_options &options); private: + static bool get_base_effect_data(const Value& value, std::string &prefix, uint64_t &flags, std::string &vertex_name, std::string &fragment_name, + std::vector<bgfx_uniform *> &uniforms); + static bool get_shader_data(const Value& value, osd_options &options, shader_manager &shaders, std::string &vertex_name, bgfx::ShaderHandle &vertex_shader, + std::string &fragment_name, bgfx::ShaderHandle &fragment_shader); + static void clear_uniform_list(std::vector<bgfx_uniform *> &uniforms); static bool validate_parameters(const Value& value, std::string prefix); }; diff --git a/src/osd/modules/render/bgfx/shadermanager.cpp b/src/osd/modules/render/bgfx/shadermanager.cpp index 7583b58dec5..dd131e719a5 100644 --- a/src/osd/modules/render/bgfx/shadermanager.cpp +++ b/src/osd/modules/render/bgfx/shadermanager.cpp @@ -28,7 +28,7 @@ shader_manager::~shader_manager() m_shaders.clear(); } -bgfx::ShaderHandle shader_manager::shader(std::string name) +bgfx::ShaderHandle shader_manager::get_or_load_shader(osd_options &options, std::string name) { std::map<std::string, bgfx::ShaderHandle>::iterator iter = m_shaders.find(name); if (iter != m_shaders.end()) @@ -36,12 +36,49 @@ bgfx::ShaderHandle shader_manager::shader(std::string name) return iter->second; } - return load_shader(name); + bgfx::ShaderHandle handle = load_shader(options, name); + if (handle.idx != bgfx::kInvalidHandle) + { + m_shaders[name] = handle; + } + + return handle; +} + +bgfx::ShaderHandle shader_manager::load_shader(osd_options &options, std::string name) +{ + std::string shader_path = make_path_string(options, name); + const bgfx::Memory* mem = load_mem(shader_path + name + ".bin"); + if (mem != nullptr) + { + return bgfx::createShader(mem); + } + + return BGFX_INVALID_HANDLE; } -bgfx::ShaderHandle shader_manager::load_shader(std::string name) +bool shader_manager::is_shader_present(osd_options &options, std::string name) { - std::string shader_path(m_options.bgfx_path()); + std::string shader_path = make_path_string(options, name); + std::string file_name = shader_path + name + ".bin"; + bx::FileReader reader; + if (bx::open(&reader, file_name.c_str())) + { + uint32_t expected_size(bx::getSize(&reader)); + uint8_t *data = new uint8_t[expected_size]; + uint32_t read_size = (uint32_t)bx::read(&reader, data, expected_size); + delete [] data; + bx::close(&reader); + + return expected_size == read_size; + } + + return false; +} + +std::string shader_manager::make_path_string(osd_options &options, std::string name) +{ + std::string shader_path(options.bgfx_path()); shader_path += PATH_SEPARATOR "shaders" PATH_SEPARATOR; switch (bgfx::getRendererType()) { @@ -81,17 +118,7 @@ bgfx::ShaderHandle shader_manager::load_shader(std::string name) shader_path += PATH_SEPARATOR; osd_subst_env(shader_path, shader_path); - const bgfx::Memory* mem = load_mem(shader_path + name + ".bin"); - if (mem != nullptr) - { - bgfx::ShaderHandle handle = bgfx::createShader(mem); - - m_shaders[name] = handle; - - return handle; - } - - return BGFX_INVALID_HANDLE; + return shader_path; } const bgfx::Memory* shader_manager::load_mem(std::string name) @@ -109,7 +136,7 @@ const bgfx::Memory* shader_manager::load_mem(std::string name) } else { - printf("Unable to load shader %s\n", name.c_str()); + osd_printf_error("Unable to load shader %s\n", name.c_str()); } return nullptr; } diff --git a/src/osd/modules/render/bgfx/shadermanager.h b/src/osd/modules/render/bgfx/shadermanager.h index bee48dcea81..d58a669f22f 100644 --- a/src/osd/modules/render/bgfx/shadermanager.h +++ b/src/osd/modules/render/bgfx/shadermanager.h @@ -24,18 +24,19 @@ class shader_manager { public: - shader_manager(osd_options& options) : m_options(options) { } + shader_manager() { } ~shader_manager(); // Getters - bgfx::ShaderHandle shader(std::string name); + bgfx::ShaderHandle get_or_load_shader(osd_options &options, std::string name); + static bgfx::ShaderHandle load_shader(osd_options &options, std::string name); + static bool is_shader_present(osd_options &options, std::string name); private: - bgfx::ShaderHandle load_shader(std::string name); + static std::string make_path_string(osd_options &options, std::string name); static const bgfx::Memory* load_mem(std::string name); std::map<std::string, bgfx::ShaderHandle> m_shaders; - osd_options& m_options; }; #endif // __DRAWBGFX_SHADER_MANAGER__ diff --git a/src/osd/modules/render/bgfx/texturemanager.cpp b/src/osd/modules/render/bgfx/texturemanager.cpp index 25512c14e5d..af960707523 100644 --- a/src/osd/modules/render/bgfx/texturemanager.cpp +++ b/src/osd/modules/render/bgfx/texturemanager.cpp @@ -68,7 +68,7 @@ bgfx_texture* texture_manager::create_png_texture(std::string path, std::string if (bitmap.width() == 0 || bitmap.height() == 0) { - printf("Unable to load PNG '%s' from path '%s'\n", file_name.c_str(), path.c_str()); + osd_printf_error("Unable to load PNG '%s' from path '%s'\n", file_name.c_str(), path.c_str()); return nullptr; } diff --git a/src/osd/modules/render/bgfx/uniform.cpp b/src/osd/modules/render/bgfx/uniform.cpp index dc81475ad59..36f68b7a9c7 100644 --- a/src/osd/modules/render/bgfx/uniform.cpp +++ b/src/osd/modules/render/bgfx/uniform.cpp @@ -13,7 +13,7 @@ bgfx_uniform::bgfx_uniform(std::string name, bgfx::UniformType::Enum type) : m_name(name) , m_type(type) { - m_handle = bgfx::createUniform(m_name.c_str(), m_type); + m_handle = BGFX_INVALID_HANDLE; m_data_size = get_size_for_type(type); if (m_data_size > 0) { @@ -23,10 +23,18 @@ bgfx_uniform::bgfx_uniform(std::string name, bgfx::UniformType::Enum type) bgfx_uniform::~bgfx_uniform() { - bgfx::destroy(m_handle); + if (m_handle.idx != bgfx::kInvalidHandle) + { + bgfx::destroy(m_handle); + } delete [] m_data; } +void bgfx_uniform::create() +{ + m_handle = bgfx::createUniform(m_name.c_str(), m_type); +} + void bgfx_uniform::upload() { if (m_type != bgfx::UniformType::Sampler) diff --git a/src/osd/modules/render/bgfx/uniform.h b/src/osd/modules/render/bgfx/uniform.h index aa4c2cc097a..f7873f400a9 100644 --- a/src/osd/modules/render/bgfx/uniform.h +++ b/src/osd/modules/render/bgfx/uniform.h @@ -23,6 +23,8 @@ public: virtual void upload(); + void create(); + // Getters std::string name() { return m_name; } bgfx::UniformType::Enum type() const { return m_type; } diff --git a/src/osd/modules/render/bgfx/view.cpp b/src/osd/modules/render/bgfx/view.cpp index 4385500edb1..1e3b2a6000d 100644 --- a/src/osd/modules/render/bgfx/view.cpp +++ b/src/osd/modules/render/bgfx/view.cpp @@ -26,11 +26,14 @@ void bgfx_view::update() { } void bgfx_ortho_view::setup() { - if (m_window_index != 0) + if (m_window_index == 0) + { + bgfx::setViewFrameBuffer(m_index, BGFX_INVALID_HANDLE); + } + else { bgfx::setViewFrameBuffer(m_index, m_backbuffer->target()); } - bgfx::setViewRect(m_index, 0, 0, m_view_width, m_view_height); while ((m_index + 1) > m_seen_views.size()) diff --git a/src/osd/modules/render/drawbgfx.cpp b/src/osd/modules/render/drawbgfx.cpp index 29cb8deda00..7c509d0f441 100644 --- a/src/osd/modules/render/drawbgfx.cpp +++ b/src/osd/modules/render/drawbgfx.cpp @@ -75,8 +75,10 @@ char const *const renderer_bgfx::WINDOW_PREFIX = "Window 0, "; // STATICS //============================================================ -bool renderer_bgfx::s_window_set = false; uint32_t renderer_bgfx::s_current_view = 0; +bool renderer_bgfx::s_bgfx_library_initialized = false; +uint32_t renderer_bgfx::s_width[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +uint32_t renderer_bgfx::s_height[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; //============================================================ // renderer_bgfx - constructor @@ -134,31 +136,96 @@ renderer_bgfx::~renderer_bgfx() delete m_targets; } + + //============================================================ -// renderer_bgfx::create +// renderer_bgfx::init_bgfx_library +//============================================================ + +void renderer_bgfx::init_bgfx_library() +{ + std::string backend(m_options.bgfx_backend()); + + bgfx::Init init; + init.type = bgfx::RendererType::Count; + init.vendorId = BGFX_PCI_ID_NONE; + init.resolution.width = s_width[0]; + init.resolution.height = s_height[0]; + init.resolution.numBackBuffers = 1; + init.resolution.reset = BGFX_RESET_NONE; + init.platformData = m_platform_data; + if (backend == "auto") + { + } + else if (backend == "dx9" || backend == "d3d9") + { + init.type = bgfx::RendererType::Direct3D9; + } + else if (backend == "dx11" || backend == "d3d11") + { + init.type = bgfx::RendererType::Direct3D11; + } + else if (backend == "dx12" || backend == "d3d12") + { + init.type = bgfx::RendererType::Direct3D12; + } + else if (backend == "gles") + { + init.type = bgfx::RendererType::OpenGLES; + } + else if (backend == "glsl" || backend == "opengl") + { + init.type = bgfx::RendererType::OpenGL; + } + else if (backend == "vulkan") + { + init.type = bgfx::RendererType::Vulkan; + } + else if (backend == "metal") + { + init.type = bgfx::RendererType::Metal; + } + else + { + osd_printf_verbose("Unknown backend type '%s', going with auto-detection.\n", backend.c_str()); + } + + bgfx::init(init); + bgfx::reset(s_width[0], s_height[0], video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE); + // Enable debug text if requested. + bool bgfx_debug = m_options.bgfx_debug(); + bgfx::setDebug(bgfx_debug ? BGFX_DEBUG_STATS : BGFX_DEBUG_TEXT); + + ScreenVertex::init(); + + imguiCreate(); +} + + + +//============================================================ +// Utilities for setting up window handles //============================================================ #ifdef OSD_WINDOWS -inline void winSetHwnd(::HWND _window) +inline void winSetHwnd(bgfx::PlatformData &platform_data, ::HWND _window) { - bgfx::PlatformData pd; - pd.ndt = NULL; - pd.nwh = _window; - pd.context = NULL; - pd.backBuffer = NULL; - pd.backBufferDS = NULL; - bgfx::setPlatformData(pd); + platform_data.ndt = NULL; + platform_data.nwh = _window; + platform_data.context = NULL; + platform_data.backBuffer = NULL; + platform_data.backBufferDS = NULL; + bgfx::setPlatformData(platform_data); } #elif defined(OSD_MAC) -inline void macSetWindow(void *_window) +inline void macSetWindow(bgfx::PlatformData &platform_data, void *_window) { - bgfx::PlatformData pd; - pd.ndt = NULL; - pd.nwh = GetOSWindow(_window); - pd.context = NULL; - pd.backBuffer = NULL; - pd.backBufferDS = NULL; - bgfx::setPlatformData(pd); + platform_data.ndt = NULL; + platform_data.nwh = GetOSWindow(_window); + platform_data.context = NULL; + platform_data.backBuffer = NULL; + platform_data.backBufferDS = NULL; + bgfx::setPlatformData(platform_data); } #elif defined(OSD_SDL) static void* sdlNativeWindowHandle(SDL_Window* _window) @@ -181,7 +248,7 @@ static void* sdlNativeWindowHandle(SDL_Window* _window) # endif // BX_PLATFORM_ } -inline bool sdlSetWindow(SDL_Window* _window) +inline bool sdlSetWindow(bgfx::PlatformData &platform_data, SDL_Window* _window) { SDL_SysWMinfo wmi; SDL_VERSION(&wmi.version); @@ -190,117 +257,83 @@ inline bool sdlSetWindow(SDL_Window* _window) return false; } - bgfx::PlatformData pd; # if BX_PLATFORM_LINUX || BX_PLATFORM_BSD - pd.ndt = wmi.info.x11.display; - pd.nwh = (void*)(uintptr_t)wmi.info.x11.window; + platform_data.ndt = wmi.info.x11.display; + platform_data.nwh = (void*)(uintptr_t)wmi.info.x11.window; # elif BX_PLATFORM_OSX - pd.ndt = NULL; - pd.nwh = wmi.info.cocoa.window; + platform_data.ndt = NULL; + platform_data.nwh = wmi.info.cocoa.window; # elif BX_PLATFORM_WINDOWS - pd.ndt = NULL; - pd.nwh = wmi.info.win.window; + platform_data.ndt = NULL; + platform_data.nwh = wmi.info.win.window; # endif // BX_PLATFORM_ - pd.context = NULL; - pd.backBuffer = NULL; - pd.backBufferDS = NULL; - bgfx::setPlatformData(pd); + platform_data.context = NULL; + platform_data.backBuffer = NULL; + platform_data.backBufferDS = NULL; + bgfx::setPlatformData(platform_data); return true; } #endif + + +//============================================================ +// renderer_bgfx::create +//============================================================ + int renderer_bgfx::create() { - // create renderer std::shared_ptr<osd_window> win = assert_window(); osd_dim wdim = win->get_size(); - m_width[win->index()] = wdim.width(); - m_height[win->index()] = wdim.height(); + s_width[win->index()] = wdim.width(); + s_height[win->index()] = wdim.height(); + m_dimensions = wdim; + + if (s_bgfx_library_initialized) + { + exit(); + } + if (win->index() == 0) { - if (!s_window_set) - { - s_window_set = true; - ScreenVertex::init(); - } - else - { - bgfx::shutdown(); - bgfx::PlatformData blank_pd; - memset(&blank_pd, 0, sizeof(bgfx::PlatformData)); - bgfx::setPlatformData(blank_pd); - } #ifdef OSD_WINDOWS - winSetHwnd(std::static_pointer_cast<win_window_info>(win)->platform_window()); + winSetHwnd(m_platform_data, std::static_pointer_cast<win_window_info>(win)->platform_window()); #elif defined(OSD_MAC) - macSetWindow(std::static_pointer_cast<mac_window_info>(win)->platform_window()); + macSetWindow(m_platform_data, std::static_pointer_cast<mac_window_info>(win)->platform_window()); #else - sdlSetWindow(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window()); + sdlSetWindow(m_platform_data, std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window()); #endif - std::string backend(m_options.bgfx_backend()); - bgfx::Init init; - init.type = bgfx::RendererType::Count; - init.vendorId = BGFX_PCI_ID_NONE; - init.resolution.width = wdim.width(); - init.resolution.height = wdim.height(); - init.resolution.reset = BGFX_RESET_NONE; - if (backend == "auto") - { - } - else if (backend == "dx9" || backend == "d3d9") - { - init.type = bgfx::RendererType::Direct3D9; - } - else if (backend == "dx11" || backend == "d3d11") - { - init.type = bgfx::RendererType::Direct3D11; - } - else if (backend == "dx12" || backend == "d3d12") - { - init.type = bgfx::RendererType::Direct3D12; - } - else if (backend == "gles") - { - init.type = bgfx::RendererType::OpenGLES; - } - else if (backend == "glsl" || backend == "opengl") - { - init.type = bgfx::RendererType::OpenGL; - } - else if (backend == "vulkan") - { - init.type = bgfx::RendererType::Vulkan; - } - else if (backend == "metal") - { - init.type = bgfx::RendererType::Metal; - } - else - { - printf("Unknown backend type '%s', going with auto-detection\n", backend.c_str()); - } - bgfx::init(init); - bgfx::reset(m_width[win->index()], m_height[win->index()], video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE); - // Enable debug text. - bgfx::setDebug(m_options.bgfx_debug() ? BGFX_DEBUG_STATS : BGFX_DEBUG_TEXT); - m_dimensions = osd_dim(m_width[0], m_height[0]); + + init_bgfx_library(); } + // finish creating the renderer m_textures = new texture_manager(); m_targets = new target_manager(*m_textures); - m_shaders = new shader_manager(m_options); - m_effects = new effect_manager(m_options, *m_shaders); + m_shaders = new shader_manager(); + m_effects = new effect_manager(*m_shaders); + + // Create program from shaders. + m_gui_effect[0] = m_effects->get_or_load_effect(m_options, "gui_opaque"); + m_gui_effect[1] = m_effects->get_or_load_effect(m_options, "gui_blend"); + m_gui_effect[2] = m_effects->get_or_load_effect(m_options, "gui_multiply"); + m_gui_effect[3] = m_effects->get_or_load_effect(m_options, "gui_add"); + + m_screen_effect[0] = m_effects->get_or_load_effect(m_options, "screen_opaque"); + m_screen_effect[1] = m_effects->get_or_load_effect(m_options, "screen_blend"); + m_screen_effect[2] = m_effects->get_or_load_effect(m_options, "screen_multiply"); + m_screen_effect[3] = m_effects->get_or_load_effect(m_options, "screen_add"); if (win->index() != 0) { #ifdef OSD_WINDOWS - m_framebuffer = m_targets->create_backbuffer(std::static_pointer_cast<win_window_info>(win)->platform_window(), m_width[win->index()], m_height[win->index()]); + m_framebuffer = m_targets->create_backbuffer(std::static_pointer_cast<win_window_info>(win)->platform_window(), s_width[win->index()], s_height[win->index()]); #elif defined(OSD_MAC) - m_framebuffer = m_targets->create_backbuffer(GetOSWindow(std::static_pointer_cast<mac_window_info>(win)->platform_window()), m_width[win->index()], m_height[win->index()]); + m_framebuffer = m_targets->create_backbuffer(GetOSWindow(std::static_pointer_cast<mac_window_info>(win)->platform_window()), s_width[win->index()], s_height[win->index()]); #else - m_framebuffer = m_targets->create_backbuffer(sdlNativeWindowHandle(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window()), m_width[win->index()], m_height[win->index()]); + m_framebuffer = m_targets->create_backbuffer(sdlNativeWindowHandle(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window()), s_width[win->index()], s_height[win->index()]); #endif bgfx::touch(win->index()); @@ -309,23 +342,6 @@ int renderer_bgfx::create() } } - // Create program from shaders. - m_gui_effect[0] = m_effects->effect("gui_opaque"); - m_gui_effect[1] = m_effects->effect("gui_blend"); - m_gui_effect[2] = m_effects->effect("gui_multiply"); - m_gui_effect[3] = m_effects->effect("gui_add"); - - m_screen_effect[0] = m_effects->effect("screen_opaque"); - m_screen_effect[1] = m_effects->effect("screen_blend"); - m_screen_effect[2] = m_effects->effect("screen_multiply"); - m_screen_effect[3] = m_effects->effect("screen_add"); - - if ( m_gui_effect[0] == nullptr || m_gui_effect[1] == nullptr || m_gui_effect[2] == nullptr || m_gui_effect[3] == nullptr || - m_screen_effect[0] == nullptr || m_screen_effect[1] == nullptr || m_screen_effect[2] == nullptr || m_screen_effect[3] == nullptr) - { - fatalerror("BGFX: Unable to load required shaders. Please check and reinstall the %s folder\n", m_options.bgfx_path()); - } - m_chains = new chain_manager(win->machine(), m_options, *m_textures, *m_targets, *m_effects, win->index(), *this); m_sliders_dirty = true; @@ -335,11 +351,11 @@ int renderer_bgfx::create() memset(m_white, 0xff, sizeof(uint32_t) * 16 * 16); m_texinfo.push_back(rectangle_packer::packable_rectangle(WHITE_HASH, PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32), 16, 16, 16, nullptr, m_white)); - imguiCreate(); - return 0; } + + //============================================================ // renderer_bgfx::record //============================================================ @@ -355,9 +371,9 @@ void renderer_bgfx::record() if (m_avi_writer == nullptr) { - m_avi_writer = new avi_write(win->machine(), m_width[0], m_height[0]); - m_avi_data = new uint8_t[m_width[0] * m_height[0] * 4]; - m_avi_bitmap.allocate(m_width[0], m_height[0]); + m_avi_writer = new avi_write(win->machine(), s_width[0], s_height[0]); + m_avi_data = new uint8_t[s_width[0] * s_height[0] * 4]; + m_avi_bitmap.allocate(s_width[0], s_height[0]); } if (m_avi_writer->recording()) @@ -372,8 +388,8 @@ void renderer_bgfx::record() else { m_avi_writer->record(m_options.bgfx_avi_name()); - m_avi_target = m_targets->create_target("avibuffer", bgfx::TextureFormat::BGRA8, m_width[0], m_height[0], TARGET_STYLE_CUSTOM, false, true, 1, 0); - m_avi_texture = bgfx::createTexture2D(m_width[0], m_height[0], false, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_BLIT_DST | BGFX_TEXTURE_READ_BACK); + m_avi_target = m_targets->create_target("avibuffer", bgfx::TextureFormat::BGRA8, s_width[0], s_height[0], TARGET_STYLE_CUSTOM, false, true, 1, 0); + m_avi_texture = bgfx::createTexture2D(s_width[0], s_height[0], false, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_BLIT_DST | BGFX_TEXTURE_READ_BACK); if (m_avi_view == nullptr) { @@ -384,12 +400,32 @@ void renderer_bgfx::record() bool renderer_bgfx::init(running_machine &machine) { - const char *bgfx_path = downcast<osd_options &>(machine.options()).bgfx_path(); + osd_options &options = downcast<osd_options &>(machine.options()); + const char *bgfx_path = options.bgfx_path(); osd::directory::ptr directory = osd::directory::open(bgfx_path); if (directory == nullptr) { - osd_printf_verbose("Unable to find the %s folder. Please reinstall it to use the BGFX renderer\n", bgfx_path); + osd_printf_error("Unable to find the BGFX path %s, please install it or fix the bgfx_path setting to use the BGFX renderer.\n", bgfx_path); + return true; + } + + // Verify baseline shaders. + const bool gui_opaque_valid = effect_manager::validate_effect(options, "gui_opaque"); + const bool gui_blend_valid = effect_manager::validate_effect(options, "gui_blend"); + const bool gui_multiply_valid = effect_manager::validate_effect(options, "gui_multiply"); + const bool gui_add_valid = effect_manager::validate_effect(options, "gui_add"); + const bool all_gui_valid = gui_opaque_valid && gui_blend_valid && gui_multiply_valid && gui_add_valid; + + const bool screen_opaque_valid = effect_manager::validate_effect(options, "screen_opaque"); + const bool screen_blend_valid = effect_manager::validate_effect(options, "screen_blend"); + const bool screen_multiply_valid = effect_manager::validate_effect(options, "screen_multiply"); + const bool screen_add_valid = effect_manager::validate_effect(options, "screen_add"); + const bool all_screen_valid = screen_opaque_valid && screen_blend_valid && screen_multiply_valid && screen_add_valid; + + if (!all_gui_valid || !all_screen_valid) + { + osd_printf_error("BGFX: Unable to load required shaders. Please update the %s folder or adjust your bgfx_path setting.\n", options.bgfx_path()); return true; } @@ -399,9 +435,8 @@ bool renderer_bgfx::init(running_machine &machine) void renderer_bgfx::exit() { imguiDestroy(); - bgfx::shutdown(); - s_window_set = false; + s_bgfx_library_initialized = false; } //============================================================ @@ -524,15 +559,15 @@ void renderer_bgfx::render_avi_quad() m_avi_view->set_index(s_current_view); m_avi_view->setup(); - bgfx::setViewRect(s_current_view, 0, 0, m_width[0], m_height[0]); + bgfx::setViewRect(s_current_view, 0, 0, s_width[0], s_height[0]); bgfx::setViewClear(s_current_view, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x00000000, 1.0f, 0); bgfx::TransientVertexBuffer buffer; bgfx::allocTransientVertexBuffer(&buffer, 6, ScreenVertex::ms_decl); auto* vertices = reinterpret_cast<ScreenVertex*>(buffer.data); - float x[4] = { 0.0f, float(m_width[0]), 0.0f, float(m_width[0]) }; - float y[4] = { 0.0f, 0.0f, float(m_height[0]), float(m_height[0]) }; + float x[4] = { 0.0f, float(s_width[0]), 0.0f, float(s_width[0]) }; + float y[4] = { 0.0f, 0.0f, float(s_height[0]), float(s_height[0]) }; float u[4] = { 0.0f, 1.0f, 0.0f, 1.0f }; float v[4] = { 0.0f, 0.0f, 1.0f, 1.0f }; uint32_t rgba = 0xffffffff; @@ -824,8 +859,8 @@ int renderer_bgfx::draw(int update) } osd_dim wdim = win->get_size(); - m_width[window_index] = wdim.width(); - m_height[window_index] = wdim.height(); + s_width[window_index] = wdim.width(); + s_height[window_index] = wdim.height(); // Set view 0 default viewport. if (window_index == 0) @@ -837,17 +872,18 @@ int renderer_bgfx::draw(int update) uint32_t num_screens = m_chains->update_screen_textures(s_current_view, win->m_primlist->first(), *win.get()); win->m_primlist->release_lock(); - if (num_screens) - { - s_current_view += m_chains->process_screen_chains(s_current_view, *win.get()); - } - bool skip_frame = update_dimensions(); if (skip_frame) { return 0; } + if (num_screens) + { + uint32_t chain_view_count = m_chains->process_screen_chains(s_current_view, *win.get()); + s_current_view += chain_view_count; + } + if (s_current_view > m_max_view) { m_max_view = s_current_view; @@ -906,7 +942,7 @@ int renderer_bgfx::draw(int update) // This dummy draw call is here to make sure that view 0 is cleared // if no other draw calls are submitted to view 0. - bgfx::touch(s_current_view > 0 ? s_current_view - 1 : 0); + //bgfx::touch(s_current_view > 0 ? s_current_view - 1 : 0); // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. @@ -918,7 +954,10 @@ int renderer_bgfx::draw(int update) bgfx::touch(s_current_view); update_recording(); } + } + if (win->index() == osd_common_t::s_window_list.size() - 1) + { bgfx::frame(); } @@ -959,24 +998,16 @@ bool renderer_bgfx::update_dimensions() std::shared_ptr<osd_window> win = assert_window(); const uint32_t window_index = win->index(); - const uint32_t width = m_width[window_index]; - const uint32_t height = m_height[window_index]; + const uint32_t width = s_width[window_index]; + const uint32_t height = s_height[window_index]; - if (window_index == 0) - { - if ((m_dimensions != osd_dim(width, height))) - { - bgfx::reset(width, height, video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE); - m_dimensions = osd_dim(width, height); - } - } - else + if (m_dimensions != osd_dim(width, height)) { - if ((m_dimensions != osd_dim(width, height))) - { - bgfx::reset(win->main_window()->get_size().width(), win->main_window()->get_size().height(), video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE); - m_dimensions = osd_dim(width, height); + bgfx::reset(width, height, video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE); + m_dimensions = osd_dim(width, height); + if (win->index() != 0) + { delete m_framebuffer; #ifdef OSD_WINDOWS m_framebuffer = m_targets->create_backbuffer(std::static_pointer_cast<win_window_info>(win)->platform_window(), width, height); @@ -986,15 +1017,17 @@ bool renderer_bgfx::update_dimensions() m_framebuffer = m_targets->create_backbuffer(sdlNativeWindowHandle(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window()), width, height); #endif if (m_ortho_view) + { m_ortho_view->set_backbuffer(m_framebuffer); - + } bgfx::setViewFrameBuffer(s_current_view, m_framebuffer->target()); - bgfx::setViewClear(s_current_view, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x00000000, 1.0f, 0); - bgfx::setViewMode(s_current_view, bgfx::ViewMode::Sequential); - bgfx::touch(s_current_view); - bgfx::frame(); - return true; } + + bgfx::setViewClear(s_current_view, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x00000000, 1.0f, 0); + bgfx::setViewMode(s_current_view, bgfx::ViewMode::Sequential); + bgfx::touch(s_current_view); + bgfx::frame(); + return true; } return false; } @@ -1003,14 +1036,15 @@ void renderer_bgfx::setup_ortho_view() { if (!m_ortho_view) { - m_ortho_view = new bgfx_ortho_view(this, s_current_view, m_framebuffer, m_seen_views); + m_ortho_view = new bgfx_ortho_view(this, 0, m_framebuffer, m_seen_views); } - m_ortho_view->update(); - if (m_ortho_view->get_index() == UINT_MAX) { + if (m_ortho_view->get_index() == UINT_MAX) + { m_ortho_view->set_index(s_current_view); m_ortho_view->setup(); s_current_view++; } + m_ortho_view->update(); } renderer_bgfx::buffer_status renderer_bgfx::buffer_primitives(bool atlas_valid, render_primitive** prim, bgfx::TransientVertexBuffer* buffer, int32_t screen) @@ -1279,10 +1313,10 @@ void renderer_bgfx::set_sliders_dirty() } uint32_t renderer_bgfx::get_window_width(uint32_t index) const { - return m_width[index]; + return s_width[index]; } uint32_t renderer_bgfx::get_window_height(uint32_t index) const { - return m_height[index]; + return s_height[index]; } diff --git a/src/osd/modules/render/drawbgfx.h b/src/osd/modules/render/drawbgfx.h index e7e648c27d1..6cbf2631b9d 100644 --- a/src/osd/modules/render/drawbgfx.h +++ b/src/osd/modules/render/drawbgfx.h @@ -85,6 +85,8 @@ public: static char const *const WINDOW_PREFIX; private: + void init_bgfx_library(); + void vertex(ScreenVertex* vertex, float x, float y, float z, uint32_t rgba, float u, float v); void render_avi_quad(); void update_recording(); @@ -122,6 +124,7 @@ private: uint32_t get_texture_hash(render_primitive *prim); osd_options& m_options; + bgfx::PlatformData m_platform_data; bgfx_target *m_framebuffer; bgfx_texture *m_texture_cache; @@ -143,8 +146,6 @@ private: std::vector<rectangle_packer::packable_rectangle> m_texinfo; rectangle_packer m_packer; - uint32_t m_width[16]; - uint32_t m_height[16]; uint32_t m_white[16*16]; bgfx_view *m_ortho_view; uint32_t m_max_view; @@ -160,8 +161,10 @@ private: static const uint32_t PACKABLE_SIZE; static const uint32_t WHITE_HASH; - static bool s_window_set; static uint32_t s_current_view; + static bool s_bgfx_library_initialized; + static uint32_t s_width[16]; + static uint32_t s_height[16]; }; #endif // RENDER_BGFX diff --git a/src/osd/sdl/window.cpp b/src/osd/sdl/window.cpp index 17e10f575dd..12dbae4f6e9 100644 --- a/src/osd/sdl/window.cpp +++ b/src/osd/sdl/window.cpp @@ -92,25 +92,53 @@ bool sdl_osd_interface::window_init() { osd_printf_verbose("Enter sdlwindow_init\n"); - // initialize the drawers + // initialize the renderer + const int fallbacks[VIDEO_MODE_COUNT] = { + -1, // NONE -> no fallback + -1, // No GDI on Linux + VIDEO_MODE_OPENGL, // BGFX -> OpenGL +#if (USE_OPENGL) + VIDEO_MODE_SDL2ACCEL, // OpenGL -> SDL2Accel +#endif + -1, // SDL2ACCEL -> SOFT + -1, // No D3D on Linux + -1, // SOFT -> no fallback + }; - switch (video_config.mode) + int current_mode = video_config.mode; + while (current_mode != VIDEO_MODE_NONE) { - case VIDEO_MODE_BGFX: - renderer_bgfx::init(machine()); - break; + bool error = false; + switch(current_mode) + { + case VIDEO_MODE_BGFX: + renderer_bgfx::init(machine()); + break; #if (USE_OPENGL) - case VIDEO_MODE_OPENGL: - renderer_ogl::init(machine()); - break; + case VIDEO_MODE_OPENGL: + renderer_ogl::init(machine()); + break; #endif - case VIDEO_MODE_SDL2ACCEL: - renderer_sdl2::init(machine()); - break; - case VIDEO_MODE_SOFT: - renderer_sdl1::init(machine()); + case VIDEO_MODE_SDL2ACCEL: + renderer_sdl2::init(machine()); + break; + case VIDEO_MODE_SOFT: + renderer_sdl1::init(machine()); + break; + default: + fatalerror("Unknown video mode."); + break; + } + if (error) + { + current_mode = fallbacks[current_mode]; + } + else + { break; + } } + video_config.mode = current_mode; /* We may want to set a number of the hints SDL2 provides. * The code below will document which hints were set. diff --git a/src/osd/windows/window.cpp b/src/osd/windows/window.cpp index bcf89fc0267..f2c7b08db1a 100644 --- a/src/osd/windows/window.cpp +++ b/src/osd/windows/window.cpp @@ -130,6 +130,7 @@ bool windows_osd_interface::window_init() window_thread = GetCurrentThread(); window_threadid = main_threadid; + // initialize the renderer const int fallbacks[VIDEO_MODE_COUNT] = { -1, // NONE -> no fallback VIDEO_MODE_NONE, // GDI -> NONE @@ -151,7 +152,7 @@ bool windows_osd_interface::window_init() { bool error = false; switch(current_mode) - { + { case VIDEO_MODE_NONE: error = renderer_none::init(machine()); break; |