mirror of
https://github.com/holub/mame
synced 2025-04-25 17:56:43 +03:00
Fix housemnq crash, nw
This commit is contained in:
parent
124b4ab8a7
commit
c0a67e7310
@ -55,7 +55,7 @@ void bgfx_chain_entry::submit(int view, render_primitive* prim, texture_manager&
|
||||
|
||||
for (bgfx_input_pair input : m_inputs)
|
||||
{
|
||||
input.bind(m_effect, textures, screen);
|
||||
input.bind(m_effect, m_targets, textures, screen);
|
||||
}
|
||||
|
||||
bgfx::TransientVertexBuffer buffer;
|
||||
@ -74,11 +74,7 @@ void bgfx_chain_entry::submit(int view, render_primitive* prim, texture_manager&
|
||||
|
||||
m_effect->submit(view, blend);
|
||||
|
||||
std::string output_name = m_output;
|
||||
if (output_name == "output" || output_name == "previous")
|
||||
{
|
||||
output_name = output_name + std::to_string(screen);
|
||||
}
|
||||
std::string output_name = m_output + std::to_string(screen);
|
||||
if (m_targets.target(output_name) != nullptr)
|
||||
{
|
||||
m_targets.target(output_name)->page_flip();
|
||||
@ -158,11 +154,7 @@ bool bgfx_chain_entry::setup_view(int view, uint16_t screen_width, uint16_t scre
|
||||
bgfx::FrameBufferHandle handle = BGFX_INVALID_HANDLE;
|
||||
uint16_t width = screen_width;
|
||||
uint16_t height = screen_height;
|
||||
std::string output_name = m_output;
|
||||
if (output_name == "output" || output_name == "previous")
|
||||
{
|
||||
output_name = output_name + std::to_string(screen);
|
||||
}
|
||||
std::string output_name = m_output + std::to_string(screen);
|
||||
if (m_targets.target(output_name) != nullptr)
|
||||
{
|
||||
bgfx_target* output = m_targets.target(output_name);
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "effect.h"
|
||||
#include "uniform.h"
|
||||
#include "texturemanager.h"
|
||||
#include "targetmanager.h"
|
||||
|
||||
bgfx_input_pair::bgfx_input_pair(int index, std::string sampler, std::string texture)
|
||||
: m_index(index)
|
||||
@ -25,11 +26,11 @@ bgfx_input_pair::bgfx_input_pair(int index, std::string sampler, std::string tex
|
||||
{
|
||||
}
|
||||
|
||||
void bgfx_input_pair::bind(bgfx_effect *effect, texture_manager& textures, const int32_t screen) const
|
||||
void bgfx_input_pair::bind(bgfx_effect *effect, target_manager& targets, texture_manager& textures, const int32_t screen) const
|
||||
{
|
||||
assert(effect->uniform(m_sampler) != nullptr);
|
||||
std::string texture = m_texture;
|
||||
if (m_texture == "previous")
|
||||
if (targets.target(m_texture + std::to_string(screen)) != nullptr)
|
||||
{
|
||||
texture = m_texture + std::to_string(screen);
|
||||
}
|
||||
|
@ -18,13 +18,14 @@
|
||||
|
||||
class bgfx_effect;
|
||||
class texture_manager;
|
||||
class target_manager;
|
||||
|
||||
class bgfx_input_pair
|
||||
{
|
||||
public:
|
||||
bgfx_input_pair(int index, std::string sampler, std::string texture);
|
||||
|
||||
void bind(bgfx_effect *effect, texture_manager& textures, const int32_t screen) const;
|
||||
void bind(bgfx_effect *effect, target_manager& targets, texture_manager& textures, const int32_t screen) const;
|
||||
|
||||
// Getters
|
||||
std::string sampler() const { return m_sampler; }
|
||||
|
@ -6,9 +6,11 @@
|
||||
//
|
||||
//============================================================
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "target.h"
|
||||
|
||||
bgfx_target::bgfx_target(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t height, uint32_t prescale_x, uint32_t prescale_y, uint32_t style, bool double_buffer, bool filter, bool init, bool output)
|
||||
bgfx_target::bgfx_target(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t height, uint32_t prescale_x, uint32_t prescale_y, uint32_t style, int32_t index, bool double_buffer, bool filter, bool init, bool output)
|
||||
: m_name(name)
|
||||
, m_format(format)
|
||||
, m_targets(nullptr)
|
||||
@ -21,7 +23,8 @@ bgfx_target::bgfx_target(std::string name, bgfx::TextureFormat::Enum format, uin
|
||||
, m_style(style)
|
||||
, m_filter(filter)
|
||||
, m_output(output)
|
||||
, m_current_page(0)
|
||||
, m_index(index)
|
||||
, m_current_page(0)
|
||||
, m_initialized(false)
|
||||
, m_page_count(double_buffer ? 2 : 1)
|
||||
{
|
||||
@ -35,8 +38,10 @@ bgfx_target::bgfx_target(std::string name, bgfx::TextureFormat::Enum format, uin
|
||||
for (int page = 0; page < m_page_count; page++)
|
||||
{
|
||||
m_textures[page] = bgfx::createTexture2D(width * prescale_x, height * prescale_y, 1, format, wrap_mode | filter_mode | BGFX_TEXTURE_RT);
|
||||
assert(m_textures[page].idx != 0xffff);
|
||||
m_targets[page] = bgfx::createFrameBuffer(1, &m_textures[page], false);
|
||||
}
|
||||
assert(m_targets[page].idx != 0xffff);
|
||||
}
|
||||
|
||||
m_initialized = true;
|
||||
}
|
||||
@ -55,7 +60,8 @@ bgfx_target::bgfx_target(void *handle, uint16_t width, uint16_t height)
|
||||
, m_style(TARGET_STYLE_CUSTOM)
|
||||
, m_filter(false)
|
||||
, m_current_page(0)
|
||||
, m_initialized(true)
|
||||
, m_index(-1)
|
||||
, m_initialized(true)
|
||||
, m_page_count(0)
|
||||
{
|
||||
m_targets = new bgfx::FrameBufferHandle[1];
|
||||
@ -66,15 +72,18 @@ bgfx_target::bgfx_target(void *handle, uint16_t width, uint16_t height)
|
||||
|
||||
bgfx_target::~bgfx_target()
|
||||
{
|
||||
if (!m_initialized) return;
|
||||
if (!m_initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_page_count > 0)
|
||||
{
|
||||
for (int page = 0; page < m_page_count; page++)
|
||||
{
|
||||
bgfx::destroyFrameBuffer(m_targets[page]);
|
||||
bgfx::destroyTexture(m_textures[page]);
|
||||
}
|
||||
bgfx::destroyTexture(m_textures[page]);
|
||||
}
|
||||
delete [] m_textures;
|
||||
delete [] m_targets;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ enum
|
||||
class bgfx_target : public bgfx_texture_handle_provider
|
||||
{
|
||||
public:
|
||||
bgfx_target(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t height, uint32_t prescale_x, uint32_t prescale_y, uint32_t style, bool double_buffer, bool filter, bool init = true, bool output = false);
|
||||
bgfx_target(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t height, uint32_t prescale_x, uint32_t prescale_y, uint32_t style, int32_t index, bool double_buffer, bool filter, bool init = true, bool output = false);
|
||||
bgfx_target(void *handle, uint16_t width, uint16_t height);
|
||||
virtual ~bgfx_target();
|
||||
|
||||
@ -43,6 +43,7 @@ public:
|
||||
uint32_t prescale_x() const { return m_prescale_x; }
|
||||
uint32_t prescale_y() const { return m_prescale_y; }
|
||||
bool output() const { return m_output; }
|
||||
int32_t index() const { return m_index; }
|
||||
|
||||
// bgfx_texture_handle_provider
|
||||
virtual uint16_t width() const override { return m_width; }
|
||||
@ -67,6 +68,7 @@ private:
|
||||
uint32_t m_style;
|
||||
bool m_filter;
|
||||
bool m_output;
|
||||
int32_t m_index;
|
||||
|
||||
uint32_t m_current_page;
|
||||
|
||||
|
@ -19,18 +19,36 @@
|
||||
|
||||
#include "target.h"
|
||||
|
||||
const int32_t target_manager::MAX_SCREENS = 100;
|
||||
|
||||
target_manager::target_manager(osd_options& options, texture_manager& textures)
|
||||
: m_textures(textures)
|
||||
, m_options(options)
|
||||
, m_screen_count(0)
|
||||
{
|
||||
m_guest_width = new uint16_t[MAX_SCREENS];
|
||||
m_guest_height = new uint16_t[MAX_SCREENS];
|
||||
memset(m_guest_width, 0, sizeof(uint16_t) * MAX_SCREENS);
|
||||
memset(m_guest_height, 0, sizeof(uint16_t) * MAX_SCREENS);
|
||||
}
|
||||
|
||||
target_manager::~target_manager()
|
||||
{
|
||||
for (std::pair<std::string, bgfx_target*> target : m_targets)
|
||||
{
|
||||
delete target.second;
|
||||
if (target.second != nullptr)
|
||||
{
|
||||
delete target.second;
|
||||
}
|
||||
}
|
||||
m_targets.clear();
|
||||
delete [] m_guest_width;
|
||||
delete [] m_guest_height;
|
||||
}
|
||||
|
||||
bgfx_target* target_manager::create_target(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t height, uint32_t prescale_x, uint32_t prescale_y, uint32_t style, bool double_buffer, bool filter, bool output)
|
||||
{
|
||||
bgfx_target* target = new bgfx_target(name, format, width, height, prescale_x, prescale_y, style, double_buffer, filter, width > 0 && height > 0, output);
|
||||
bgfx_target* target = new bgfx_target(name, format, width, height, prescale_x, prescale_y, style, -1, double_buffer, filter, width > 0 && height > 0, output);
|
||||
m_targets[name] = target;
|
||||
|
||||
m_textures.add_provider(name, target);
|
||||
@ -55,62 +73,140 @@ bgfx_target* target_manager::target(std::string name)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void target_manager::update_guest_targets(uint16_t width, uint16_t height)
|
||||
void target_manager::update_guest_targets(int32_t screen, uint16_t width, uint16_t height)
|
||||
{
|
||||
if (width != m_guest_width || height != m_guest_height)
|
||||
if (screen < 0 || screen >= MAX_SCREENS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (width != m_guest_width[screen] || height != m_guest_height[screen])
|
||||
{
|
||||
m_guest_width = width;
|
||||
m_guest_height = height;
|
||||
|
||||
std::vector<bgfx_target*> to_resize;
|
||||
for (std::pair<std::string, bgfx_target*> target : m_targets)
|
||||
{
|
||||
if ((target.second)->style() == TARGET_STYLE_GUEST)
|
||||
{
|
||||
to_resize.push_back(target.second);
|
||||
}
|
||||
}
|
||||
|
||||
for (bgfx_target* target : to_resize)
|
||||
{
|
||||
std::string name = target->name();
|
||||
const bgfx::TextureFormat::Enum format = target->format();
|
||||
const bool double_buffered = target->double_buffered();
|
||||
const bool filter = target->filter();
|
||||
const uint32_t prescale_x = target->prescale_x();
|
||||
const uint32_t prescale_y = target->prescale_y();
|
||||
delete target;
|
||||
|
||||
m_targets[name] = new bgfx_target(name, format, m_guest_width, m_guest_height, prescale_x, prescale_y, TARGET_STYLE_GUEST, double_buffered, filter);
|
||||
m_textures.add_provider(name, m_targets[name]);
|
||||
}
|
||||
m_guest_width[screen] = width;
|
||||
m_guest_height[screen] = height;
|
||||
ensure_guest_targets();
|
||||
rebuild_guest_targets(screen);
|
||||
}
|
||||
}
|
||||
|
||||
void target_manager::update_window_count(uint32_t count)
|
||||
void target_manager::ensure_guest_targets()
|
||||
{
|
||||
if (count != m_window_count)
|
||||
// Build a list of all guest targets that end in 0 *or* don't end in a number
|
||||
std::vector<std::string> existing_names;
|
||||
for (std::pair<std::string, bgfx_target*> target_pair : m_targets)
|
||||
{
|
||||
m_window_count = count;
|
||||
rebuild_outputs();
|
||||
bgfx_target* target = target_pair.second;
|
||||
if (target == nullptr || target->style() != TARGET_STYLE_GUEST)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the last character is not a digit, add it to the list
|
||||
std::string name = target->name();
|
||||
char last_char = name[name.length() - 1];
|
||||
if ((last_char & 0xf0) != 0x30) {
|
||||
existing_names.push_back(name);
|
||||
}
|
||||
|
||||
// If the last character is a zero, and the stripped name isn't already in the list, strip it off and add it to the list
|
||||
if (last_char == 0x30)
|
||||
{
|
||||
std::string shortened_name = name.substr(0, name.length() - 1);
|
||||
bool exists = false;
|
||||
for (std::string other_name : existing_names)
|
||||
{
|
||||
if (other_name == shortened_name)
|
||||
{
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!exists)
|
||||
{
|
||||
existing_names.push_back(shortened_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (std::string name : existing_names)
|
||||
{
|
||||
create_nonexistent_targets(name);
|
||||
}
|
||||
}
|
||||
|
||||
void target_manager::rebuild_outputs()
|
||||
void target_manager::rebuild_guest_targets(int32_t screen)
|
||||
{
|
||||
for (uint32_t i = 0; i < m_window_count; i++)
|
||||
{
|
||||
rebuild_target("output" + std::to_string(i));
|
||||
rebuild_target("previous" + std::to_string(i));
|
||||
std::vector<bgfx_target*> to_resize;
|
||||
for (std::pair<std::string, bgfx_target*> target : m_targets) {
|
||||
bgfx_target* target_ptr = target.second;
|
||||
if (target_ptr == nullptr) {
|
||||
continue;
|
||||
}
|
||||
bool is_guest = target_ptr->style() == TARGET_STYLE_GUEST;
|
||||
bool is_desired_screen = target_ptr->index() == screen || target_ptr->index() == -1;
|
||||
std::string name = target_ptr->name();
|
||||
bool is_indexed = (name[name.length() - 1] & 0xf0) == 0x30;
|
||||
if (is_guest && is_desired_screen && is_indexed) {
|
||||
to_resize.push_back(target.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void target_manager::rebuild_target(std::string name)
|
||||
{
|
||||
bgfx_target* target = m_targets[name];
|
||||
if (target != nullptr) {
|
||||
for (bgfx_target* target : to_resize) {
|
||||
std::string name = target->name();
|
||||
const bgfx::TextureFormat::Enum format = target->format();
|
||||
const bool double_buffered = target->double_buffered();
|
||||
const bool filter = target->filter();
|
||||
const uint32_t prescale_x = target->prescale_x();
|
||||
const uint32_t prescale_y = target->prescale_y();
|
||||
delete target;
|
||||
|
||||
const uint16_t width = m_guest_width[screen];
|
||||
const uint16_t height = m_guest_height[screen];
|
||||
const bool init = width > 0 && height > 0;
|
||||
m_targets[name] = new bgfx_target(name, format, width, height, prescale_x, prescale_y, TARGET_STYLE_GUEST, screen, double_buffered, filter, init);
|
||||
m_textures.add_provider(name, m_targets[name]);
|
||||
}
|
||||
m_targets[name] = new bgfx_target(name, bgfx::TextureFormat::RGBA8, m_guest_width, m_guest_height, m_options.bgfx_prescale_x(), m_options.bgfx_prescale_y(), TARGET_STYLE_GUEST, true, true);
|
||||
m_textures.add_provider(name, m_targets[name]);
|
||||
}
|
||||
|
||||
void target_manager::update_screen_count(uint32_t count)
|
||||
{
|
||||
if (count != m_screen_count)
|
||||
{
|
||||
uint32_t old_count = m_screen_count;
|
||||
m_screen_count = count;
|
||||
if (m_screen_count > old_count)
|
||||
{
|
||||
create_nonexistent_targets("output");
|
||||
create_nonexistent_targets("previous");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void target_manager::create_nonexistent_targets(std::string name)
|
||||
{
|
||||
bool double_buffered = true;
|
||||
bool filter = true;
|
||||
if (m_targets[name + "0"] != nullptr)
|
||||
{
|
||||
double_buffered = m_targets[name + "0"]->double_buffered();
|
||||
filter = m_targets[name + "0"]->filter();
|
||||
}
|
||||
|
||||
for (uint32_t screen = 0; screen < m_screen_count; screen++)
|
||||
{
|
||||
create_guest_if_nonexistent(name, screen, double_buffered, filter);
|
||||
}
|
||||
}
|
||||
|
||||
bool target_manager::create_guest_if_nonexistent(std::string name, int32_t screen, bool double_buffered, bool filter)
|
||||
{
|
||||
std::string full_name = name + std::to_string(screen);
|
||||
if (m_targets[full_name] != nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool init = m_guest_width[screen] > 0 && m_guest_height[screen] > 0;
|
||||
m_targets[full_name] = new bgfx_target(full_name, bgfx::TextureFormat::RGBA8, m_guest_width[screen], m_guest_height[screen], m_options.bgfx_prescale_x(), m_options.bgfx_prescale_y(), TARGET_STYLE_GUEST, screen, double_buffered, filter, init);
|
||||
return true;
|
||||
}
|
@ -26,31 +26,36 @@ class osd_options;
|
||||
|
||||
class target_manager {
|
||||
public:
|
||||
target_manager(osd_options& options, texture_manager& textures) : m_textures(textures), m_options(options), m_guest_width(0), m_guest_height(0), m_window_count(0) { }
|
||||
target_manager(osd_options& options, texture_manager& textures);
|
||||
~target_manager();
|
||||
|
||||
bgfx_target* create_target(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t height, uint32_t prescale_x, uint32_t prescale_y, uint32_t style, bool double_buffer, bool filter, bool output);
|
||||
bgfx_target* create_backbuffer(void *handle, uint32_t width, uint32_t height);
|
||||
|
||||
void update_guest_targets(uint16_t width, uint16_t height);
|
||||
void update_window_count(uint32_t count);
|
||||
void update_guest_targets(int32_t screen, uint16_t width, uint16_t height);
|
||||
void update_screen_count(uint32_t count);
|
||||
|
||||
// Getters
|
||||
bgfx_target* target(std::string name);
|
||||
uint16_t guest_width() const { return m_guest_width; }
|
||||
uint16_t guest_height() const { return m_guest_height; }
|
||||
uint16_t guest_width(int32_t screen) const { return m_guest_width[screen]; }
|
||||
uint16_t guest_height(int32_t screen) const { return m_guest_height[screen]; }
|
||||
|
||||
private:
|
||||
void rebuild_guest_targets(int32_t screen);
|
||||
void rebuild_outputs();
|
||||
void rebuild_target(std::string name);
|
||||
void ensure_guest_targets();
|
||||
void create_nonexistent_targets(std::string name);
|
||||
bool create_guest_if_nonexistent(std::string name, int32_t screen, bool double_buffered, bool filter);
|
||||
|
||||
std::map<std::string, bgfx_target*> m_targets;
|
||||
texture_manager& m_textures;
|
||||
osd_options& m_options;
|
||||
|
||||
uint16_t m_guest_width;
|
||||
uint16_t m_guest_height;
|
||||
uint32_t m_window_count;
|
||||
uint16_t *m_guest_width;
|
||||
uint16_t *m_guest_height;
|
||||
uint32_t m_screen_count;
|
||||
|
||||
static const int32_t MAX_SCREENS;
|
||||
};
|
||||
|
||||
#endif // __DRAWBGFX_TARGET_MANAGER__
|
||||
|
@ -40,8 +40,6 @@ bool target_reader::read_from_value(const Value& value, std::string prefix, targ
|
||||
switch (mode)
|
||||
{
|
||||
case TARGET_STYLE_GUEST:
|
||||
width = targets.guest_width();
|
||||
height = targets.guest_height();
|
||||
break;
|
||||
case TARGET_STYLE_NATIVE:
|
||||
width = screen_width;
|
||||
|
@ -331,7 +331,7 @@ void renderer_bgfx::put_packed_quad(render_primitive *prim, UINT32 hash, ScreenV
|
||||
vertex[5].m_v = v[0];
|
||||
}
|
||||
|
||||
void renderer_bgfx::process_screen_quad(int view, render_primitive* prim)
|
||||
void renderer_bgfx::process_screen_quad(int screen, render_primitive* prim)
|
||||
{
|
||||
uint32_t texture_flags = BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP;
|
||||
if (video_config.filter == 0)
|
||||
@ -348,16 +348,9 @@ void renderer_bgfx::process_screen_quad(int view, render_primitive* prim)
|
||||
bgfx_texture *texture = new bgfx_texture("screen", bgfx::TextureFormat::RGBA8, tex_width, tex_height, mem);
|
||||
m_textures->add_provider("screen", texture);
|
||||
|
||||
int screens = 0;
|
||||
screen_device_iterator iter(window().machine().root_device());
|
||||
for (const screen_device *screen = iter.first(); screen != nullptr; screen = iter.next())
|
||||
{
|
||||
screens++;
|
||||
}
|
||||
m_targets->update_guest_targets(tex_width, tex_height);
|
||||
m_targets->update_window_count(screens);
|
||||
m_targets->update_guest_targets(screen, tex_width, tex_height);
|
||||
|
||||
m_screen_chain->process(prim, view, view / m_screen_chain->applicable_passes(), *m_textures, window(), get_blend_state(PRIMFLAG_GET_BLENDMODE(prim->flags)));
|
||||
m_screen_chain->process(prim, screen * m_screen_chain->applicable_passes(), screen, *m_textures, window(), get_blend_state(PRIMFLAG_GET_BLENDMODE(prim->flags)));
|
||||
|
||||
m_textures->add_provider("screen", nullptr);
|
||||
delete texture;
|
||||
@ -744,20 +737,27 @@ int renderer_bgfx::handle_screen_chains()
|
||||
// process
|
||||
render_primitive *prim = window().m_primlist->first();
|
||||
|
||||
int seen = 0;
|
||||
int screens = 0;
|
||||
screen_device_iterator iter(window().machine().root_device());
|
||||
for (const screen_device *screen = iter.first(); screen != nullptr; screen = iter.next()) {
|
||||
screens++;
|
||||
}
|
||||
m_targets->update_screen_count(screens);
|
||||
|
||||
int seen_screen_quads = 0;
|
||||
while (prim != nullptr)
|
||||
{
|
||||
if (PRIMFLAG_GET_SCREENTEX(prim->flags))
|
||||
{
|
||||
process_screen_quad(m_screen_chain->applicable_passes() * seen, prim);
|
||||
seen++;
|
||||
process_screen_quad(seen_screen_quads, prim);
|
||||
seen_screen_quads++;
|
||||
}
|
||||
prim = prim->next();
|
||||
}
|
||||
|
||||
window().m_primlist->release_lock();
|
||||
|
||||
uint32_t total_passes = seen * m_screen_chain->applicable_passes();
|
||||
uint32_t total_passes = seen_screen_quads * m_screen_chain->applicable_passes();
|
||||
bgfx::setViewFrameBuffer(total_passes, BGFX_INVALID_HANDLE);
|
||||
|
||||
return total_passes;
|
||||
|
Loading…
Reference in New Issue
Block a user