mirror of
https://github.com/holub/mame
synced 2025-04-19 23:12:11 +03:00
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]
This commit is contained in:
parent
8d267ad2c7
commit
92ece92fed
@ -69,17 +69,43 @@ bool mac_osd_interface::window_init()
|
||||
{
|
||||
osd_printf_verbose("Enter macwindow_init\n");
|
||||
|
||||
// initialize the drawers
|
||||
// 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
|
||||
};
|
||||
|
||||
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;
|
||||
case VIDEO_MODE_OPENGL:
|
||||
renderer_ogl::init(machine());
|
||||
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");
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -23,7 +23,45 @@
|
||||
#include "effectreader.h"
|
||||
#include "effect.h"
|
||||
|
||||
using namespace rapidjson;
|
||||
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))
|
||||
{
|
||||
full_name = full_name + ".json";
|
||||
}
|
||||
|
||||
std::string 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()))
|
||||
{
|
||||
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.Parse<rapidjson::kParseCommentsFlag>(data);
|
||||
|
||||
delete [] data;
|
||||
|
||||
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()
|
||||
{
|
||||
@ -34,7 +72,7 @@ effect_manager::~effect_manager()
|
||||
m_effects.clear();
|
||||
}
|
||||
|
||||
bgfx_effect* effect_manager::effect(std::string name)
|
||||
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())
|
||||
@ -42,49 +80,22 @@ bgfx_effect* effect_manager::effect(std::string name)
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
return load_effect(name);
|
||||
return load_effect(options, name);
|
||||
}
|
||||
|
||||
bgfx_effect* effect_manager::load_effect(std::string name)
|
||||
bgfx_effect* effect_manager::load_effect(osd_options &options, std::string name)
|
||||
{
|
||||
std::string full_name = name;
|
||||
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()));
|
||||
path += full_name;
|
||||
|
||||
bx::FileReader reader;
|
||||
if (!bx::open(&reader, path.c_str()))
|
||||
rapidjson::Document document;
|
||||
if (!prepare_effect_document(name, options, document))
|
||||
{
|
||||
printf("Unable to open effect file %s\n", path.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int32_t size (bx::getSize(&reader));
|
||||
bgfx_effect* effect = effect_reader::read_from_value(document, "Effect '" + name + "': ", options, m_shaders);
|
||||
|
||||
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);
|
||||
|
||||
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());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bgfx_effect* effect = effect_reader::read_from_value(document, "Effect '" + name + "': ", 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);
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -23,11 +23,75 @@
|
||||
|
||||
#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)
|
||||
{
|
||||
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 nullptr;
|
||||
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;
|
||||
@ -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)
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
@ -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(std::string name)
|
||||
bgfx::ShaderHandle shader_manager::load_shader(osd_options &options, std::string name)
|
||||
{
|
||||
std::string shader_path(m_options.bgfx_path());
|
||||
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;
|
||||
}
|
||||
|
||||
bool shader_manager::is_shader_present(osd_options &options, std::string name)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -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__
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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; }
|
||||
|
@ -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())
|
||||
|
@ -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();
|
||||
if (win->index() == 0)
|
||||
s_width[win->index()] = wdim.width();
|
||||
s_height[win->index()] = wdim.height();
|
||||
m_dimensions = wdim;
|
||||
|
||||
if (s_bgfx_library_initialized)
|
||||
{
|
||||
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());
|
||||
#elif defined(OSD_MAC)
|
||||
macSetWindow(std::static_pointer_cast<mac_window_info>(win)->platform_window());
|
||||
#else
|
||||
sdlSetWindow(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]);
|
||||
exit();
|
||||
}
|
||||
|
||||
if (win->index() == 0)
|
||||
{
|
||||
#ifdef OSD_WINDOWS
|
||||
winSetHwnd(m_platform_data, std::static_pointer_cast<win_window_info>(win)->platform_window());
|
||||
#elif defined(OSD_MAC)
|
||||
macSetWindow(m_platform_data, std::static_pointer_cast<mac_window_info>(win)->platform_window());
|
||||
#else
|
||||
sdlSetWindow(m_platform_data, std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window());
|
||||
#endif
|
||||
|
||||
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))
|
||||
{
|
||||
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)))
|
||||
{
|
||||
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];
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -92,25 +92,53 @@ bool sdl_osd_interface::window_init()
|
||||
{
|
||||
osd_printf_verbose("Enter sdlwindow_init\n");
|
||||
|
||||
// initialize the drawers
|
||||
|
||||
switch (video_config.mode)
|
||||
{
|
||||
case VIDEO_MODE_BGFX:
|
||||
renderer_bgfx::init(machine());
|
||||
break;
|
||||
// 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)
|
||||
case VIDEO_MODE_OPENGL:
|
||||
renderer_ogl::init(machine());
|
||||
break;
|
||||
VIDEO_MODE_SDL2ACCEL, // OpenGL -> SDL2Accel
|
||||
#endif
|
||||
case VIDEO_MODE_SDL2ACCEL:
|
||||
renderer_sdl2::init(machine());
|
||||
break;
|
||||
case VIDEO_MODE_SOFT:
|
||||
renderer_sdl1::init(machine());
|
||||
-1, // SDL2ACCEL -> SOFT
|
||||
-1, // No D3D on Linux
|
||||
-1, // SOFT -> no fallback
|
||||
};
|
||||
|
||||
int current_mode = video_config.mode;
|
||||
while (current_mode != VIDEO_MODE_NONE)
|
||||
{
|
||||
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;
|
||||
#endif
|
||||
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.
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user