Huge cleanup of render target handling, nw

This commit is contained in:
therealmogminer@gmail.com 2016-03-25 16:19:55 +01:00
parent 956e57d26a
commit 93e5a03b89
75 changed files with 418 additions and 345 deletions

View File

@ -17,7 +17,7 @@
{ "effect": "blit",
"name": "Final Upscale",
"input": [
{ "sampler": "s_tex", "texture": "temp" }
{ "sampler": "s_tex", "target": "temp" }
],
"output": "output"
}

View File

@ -40,17 +40,18 @@
{ "type": "float", "name": "scanline_bright_offset", "text": "Scanline Brightness Offset", "default": 0, "max": 400, "min": 0, "step": 1, "scale": 0.01, "format": "%1.2f", "screen": "crt" },
{ "type": "float", "name": "scanline_jitter_amount", "text": "Scanline Jitter Amount", "default": 0, "max": 400, "min": 0, "step": 1, "scale": 0.01, "format": "%1.2f", "screen": "crt" },
{ "type": "float", "name": "scanline_height", "text": "Individual Scanline Scale", "default": 100, "max": 400, "min": 0, "step": 1, "scale": 0.01, "format": "%1.2f", "screen": "crt" },
{ "type": "float", "name": "scanline_variation", "text": "Scanline Variation", "default": 100, "max": 400, "min": 0, "step": 1, "scale": 0.01, "format": "%1.2f", "screen": "crt" },
{ "type": "float", "name": "shadow_alpha", "text": "Shadow Mask Amount", "default": 0, "max": 100, "min": 0, "step": 1, "scale": 0.01, "format": "%1.2f", "screen": "crt" },
{ "type": "vec2", "name": "shadow_uv_size", "text": "Shadow Mask UV Size ", "default": [ 250, 333 ], "max": [ 1000, 1000 ], "min": [ 0, 0 ], "step": 1, "scale": 0.001, "format": "%1.4f", "screen": "crt" },
{ "type": "vec2", "name": "shadow_uv_offset", "text": "Shadow Mask UV Offset ", "default": [ 0, 0 ], "max": [ 1000, 1000 ], "min": [ 0, 0 ], "step": 1, "scale": 0.001, "format": "%1.4f", "screen": "crt" },
{ "type": "int_enum", "name": "shadow_tile_mode", "text": "Shadow Mask Tile Mode", "default": 0, "max": 1, "min": 0, "step": 1, "scale": 1.0, "format": "%s", "screen": "crt", "strings": [ "Screen", "Source" ] },
{ "type": "float", "name": "humbar_alpha", "text": "Hum Bar Amount", "default": 5, "max": 100, "min": 0, "step": 1, "scale": 0.01, "format": "%1.2f", "screen": "crt" },
{ "type": "float", "name": "humbar_alpha", "text": "Hum Bar Amount", "default": 0, "max": 100, "min": 0, "step": 1, "scale": 0.01, "format": "%1.2f", "screen": "crt" },
{ "type": "float", "name": "humbar_hertz_rate", "text": "Hum Bar Frequency", "default": 100, "max": 10000, "min": 0, "step": 1, "scale": 0.00001, "format": "%1.7f", "screen": "crt" },
{ "type": "color", "name": "floor", "text": "Signal Floor, ", "default": [ 5, 5, 5 ], "max": [ 100, 100, 100 ], "min": [ 0, 0, 0 ], "step": 1, "scale": 0.01, "format": "%1.2f", "screen": "crt" },
{ "type": "color", "name": "power", "text": "Signal Exponent, ", "default": [ 80, 80, 80 ], "max": [ 400, 400, 400 ], "min": [ 0, 0, 0 ], "step": 1, "scale": 0.01, "format": "%1.2f", "screen": "crt" },
{ "type": "color", "name": "floor", "text": "Signal Floor, ", "default": [ 0, 0, 0 ], "max": [ 100, 100, 100 ], "min": [ 0, 0, 0 ], "step": 1, "scale": 0.01, "format": "%1.2f", "screen": "crt" },
{ "type": "color", "name": "power", "text": "Signal Exponent, ", "default": [ 100, 100, 100 ], "max": [ 400, 400, 400 ], "min": [ 0, 0, 0 ], "step": 1, "scale": 0.01, "format": "%1.2f", "screen": "crt" },
{ "type": "float", "name": "curvature", "text": "Screen Curvature Amount", "default": 25, "max": 200, "min": 0, "step": 1, "scale": 0.01, "format": "%1.2f", "screen": "crt" },
{ "type": "float", "name": "round_corner", "text": "Rounded Corner Amount", "default": 20, "max": 200, "min": 0, "step": 1, "scale": 0.01, "format": "%1.2f", "screen": "crt" },
{ "type": "float", "name": "round_corner", "text": "Rounded Corner Amount", "default": 15, "max": 200, "min": 0, "step": 1, "scale": 0.01, "format": "%1.2f", "screen": "crt" },
{ "type": "float", "name": "smooth_border", "text": "Smooth Border Amount", "default": 5, "max": 200, "min": 0, "step": 1, "scale": 0.01, "format": "%1.2f", "screen": "crt" },
{ "type": "float", "name": "vignetting", "text": "Vignetting Amount", "default": 20, "max": 200, "min": 0, "step": 1, "scale": 0.01, "format": "%1.2f", "screen": "crt" },
{ "type": "float", "name": "reflection", "text": "Reflection Amount", "default": 30, "max": 200, "min": 0, "step": 1, "scale": 0.01, "format": "%1.2f", "screen": "crt" }
@ -64,12 +65,11 @@
"name": "guest",
"mode": "guest",
"bilinear": false,
"prescale": false,
"doublebuffer": true
},
{ "name": "internal",
"mode": "guest",
"prescale": true,
"mode": "native",
"oversample": true,
"doublebuffer": true
}
],
@ -114,7 +114,7 @@
{ "uniform": "u_jitter_amount", "parameter": "jitter" }
],
"input": [
{ "sampler": "s_tex", "texture": "guest" }
{ "sampler": "s_tex", "target": "guest" }
],
"output": "guest"
},
@ -125,7 +125,7 @@
{ "type": "slider", "condition": "notequal", "combine": "and", "name": "ntsc", "value": 0 }
],
"input": [
{ "sampler": "s_tex", "texture": "screen" }
{ "sampler": "s_tex", "target": "screen" }
],
"output": "guest"
},
@ -143,14 +143,14 @@
{ "uniform": "u_saturation", "slider": "saturation" }
],
"input": [
{ "sampler": "s_tex", "texture": "guest" }
{ "sampler": "s_tex", "target": "guest" }
],
"output": "guest"
},
{ "effect": "blit",
{ "effect": "prescale",
"name": "Prescale",
"input": [
{ "sampler": "s_tex", "texture": "guest" }
{ "sampler": "s_tex", "target": "guest" }
],
"output": "internal"
},
@ -174,7 +174,7 @@
{ "uniform": "u_radial_converge_blue", "slider": "radial_converge_blue" }
],
"input": [
{ "sampler": "s_tex", "texture": "internal" }
{ "sampler": "s_tex", "target": "internal" }
],
"output": "internal"
},
@ -188,7 +188,7 @@
{ "uniform": "u_defocus", "slider": "defocus" }
],
"input": [
{ "sampler": "s_tex", "texture": "internal" }
{ "sampler": "s_tex", "target": "internal" }
],
"output": "internal"
},
@ -202,7 +202,7 @@
{ "uniform": "u_defocus", "slider": "defocus" }
],
"input": [
{ "sampler": "s_tex", "texture": "internal" }
{ "sampler": "s_tex", "target": "internal" }
],
"output": "internal"
},
@ -217,8 +217,8 @@
{ "uniform": "u_phosphor", "slider": "phosphor" }
],
"input": [
{ "sampler": "s_tex", "texture": "internal" },
{ "sampler": "s_prev", "texture": "previous" }
{ "sampler": "s_tex", "target": "internal" },
{ "sampler": "s_prev", "target": "previous" }
],
"output": "internal"
},
@ -233,8 +233,8 @@
{ "uniform": "u_phosphor", "slider": "phosphor" }
],
"input": [
{ "sampler": "s_tex", "texture": "internal" },
{ "sampler": "s_prev", "texture": "internal" }
{ "sampler": "s_tex", "target": "internal" },
{ "sampler": "s_prev", "target": "internal" }
],
"output": "previous"
},
@ -253,6 +253,8 @@
{ "uniform": "u_scanline_scale", "slider": "scanline_scale" },
{ "uniform": "u_scanline_bright_scale", "slider": "scanline_bright_scale" },
{ "uniform": "u_scanline_bright_offset", "slider": "scanline_bright_offset" },
{ "uniform": "u_scanline_height", "slider": "scanline_height" },
{ "uniform": "u_scanline_variation", "slider": "scanline_variation" },
{ "uniform": "u_shadow_alpha", "slider": "shadow_alpha" },
{ "uniform": "u_shadow_uv", "slider": "shadow_uv_size" },
{ "uniform": "u_shadow_uv_offset", "slider": "shadow_uv_offset" },
@ -266,8 +268,8 @@
{ "uniform": "u_time", "parameter": "time" }
],
"input": [
{ "sampler": "s_tex", "texture": "internal" },
{ "sampler": "s_shadow", "texture": "shadow" }
{ "sampler": "s_tex", "target": "internal" },
{ "sampler": "s_shadow", "option": "bgfx_shadow_mask" }
],
"output": "internal"
},
@ -289,14 +291,14 @@
{ "uniform": "u_reflection", "slider": "reflection" }
],
"input": [
{ "sampler": "s_tex", "texture": "internal" }
{ "sampler": "s_tex", "target": "internal" }
],
"output": "internal"
},
{ "effect": "blit",
"name": "Final Downscale",
"name": "Final Blit",
"input": [
{ "sampler": "s_tex", "texture": "internal" }
{ "sampler": "s_tex", "target": "internal" }
],
"output": "output"
}

View File

@ -17,7 +17,7 @@
{ "effect": "blit",
"name": "Final Upscale",
"input": [
{ "sampler": "s_tex", "texture": "temp" }
{ "sampler": "s_tex", "target": "temp" }
],
"output": "output"
}

View File

@ -18,12 +18,12 @@
"fragment": "fs_deconverge",
"uniforms": [
{ "name": "s_tex", "type": "int", "values": [ 1.0 ] },
{ "name": "u_tex_size0", "type": "vec4", "values": [ 256.0, 256.0, 0.0, 0.0 ] },
{ "name": "u_converge_red", "type": "vec4", "values": [ 0.5, 0.0, 0.0, 0.0 ] },
{ "name": "u_converge_green", "type": "vec4", "values": [ 0.0, 0.5, 0.0, 0.0 ] },
{ "name": "u_converge_blue", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_radial_converge_red", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_radial_converge_green", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_radial_converge_blue", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_source_dims", "type": "vec4", "values": [ 256.0, 256.0, 0.0, 0.0 ] }
{ "name": "u_radial_converge_blue", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] }
]
}

View File

@ -35,8 +35,9 @@
{ "name": "u_scanline_bright_scale", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_scanline_bright_offset", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_scanline_jitter", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_jitter_amount", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_scanline_height", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_scanline_variation", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_jitter_amount", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_back_color", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_shadow_tile_mode", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_shadow_alpha", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },

View File

@ -0,0 +1,24 @@
{
"blend": {
"equation": "add",
"srcColor": "1",
"dstColor": "0",
"srcAlpha": "1",
"dstAlpha": "0"
},
"depth": {
"function": "always"
},
"cull": { "mode": "none" },
"write": {
"rgb": "true",
"alpha": "true"
},
"vertex": "vs_prescale",
"fragment": "fs_prescale",
"uniforms": [
{ "name": "s_tex", "type": "int", "values": [ 1.0 ] },
{ "name": "u_source_dims", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] },
{ "name": "u_tex_size0", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }
]
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -144,8 +144,6 @@ const options_entry osd_options::s_option_entries[] =
{ OSDOPTION_BGFX_DEBUG, "0", OPTION_BOOLEAN, "enable BGFX debugging statistics" },
{ OSDOPTION_BGFX_SCREEN_CHAINS, "default", OPTION_STRING, "comma-delimited list of screen chain JSON names, colon-delimited per-window" },
{ OSDOPTION_BGFX_SHADOW_MASK, "shadow-mask.png", OPTION_STRING, "shadow mask texture name" },
{ OSDOPTION_BGFX_PRESCALE_X, "2", OPTION_INTEGER, "x prescale" },
{ OSDOPTION_BGFX_PRESCALE_Y, "2", OPTION_INTEGER, "y prescale" },
// End of list
{ nullptr }

View File

@ -80,8 +80,6 @@
#define OSDOPTION_BGFX_DEBUG "bgfx_debug"
#define OSDOPTION_BGFX_SCREEN_CHAINS "bgfx_screen_chains"
#define OSDOPTION_BGFX_SHADOW_MASK "bgfx_shadow_mask"
#define OSDOPTION_BGFX_PRESCALE_X "bgfx_prescale_x"
#define OSDOPTION_BGFX_PRESCALE_Y "bgfx_prescale_y"
//============================================================
// TYPE DEFINITIONS
@ -155,8 +153,6 @@ public:
const bool bgfx_debug() const { return bool_value(OSDOPTION_BGFX_DEBUG); }
const char *bgfx_screen_chains() const { return value(OSDOPTION_BGFX_SCREEN_CHAINS); }
const char *bgfx_shadow_mask() const { return value(OSDOPTION_BGFX_SHADOW_MASK); }
const uint32_t bgfx_prescale_x() const { return int_value(OSDOPTION_BGFX_PRESCALE_X); }
const uint32_t bgfx_prescale_y() const { return int_value(OSDOPTION_BGFX_PRESCALE_Y); }
private:
static const options_entry s_option_entries[];

View File

@ -0,0 +1,65 @@
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert, R. Belmont, Couriersud
//============================================================
//
// osdwindow.h - SDL window handling
//
//============================================================
#pragma once
#ifndef __OSDHELPER__
#define __OSDHELPER__
class osd_dim
{
public:
osd_dim(const int &w, const int &h)
: m_w(w), m_h(h)
{
}
int width() const { return m_w; }
int height() const { return m_h; }
bool operator!=(const osd_dim &other) { return (m_w != other.width()) || (m_h != other.height()); }
bool operator==(const osd_dim &other) { return (m_w == other.width()) && (m_h == other.height()); }
private:
int m_w;
int m_h;
};
class osd_rect
{
public:
osd_rect()
: m_x(0), m_y(0), m_d(0,0)
{
}
osd_rect(const int x, const int y, const int &w, const int &h)
: m_x(x), m_y(y), m_d(w,h)
{
}
osd_rect(const int x, const int y, const osd_dim &d)
: m_x(x), m_y(y), m_d(d)
{
}
int top() const { return m_y; }
int left() const { return m_x; }
int width() const { return m_d.width(); }
int height() const { return m_d.height(); }
osd_dim dim() const { return m_d; }
int bottom() const { return m_y + m_d.height(); }
int right() const { return m_x + m_d.width(); }
osd_rect move_by(int dx, int dy) const { return osd_rect(m_x + dx, m_y + dy, m_d); }
osd_rect resize(int w, int h) const { return osd_rect(m_x, m_y, w, h); }
private:
int m_x;
int m_y;
osd_dim m_d;
};
#endif // __OSDHELPER__

View File

@ -11,6 +11,7 @@
#include "emu.h"
#include "ui/ui.h"
#include "osdhelper.h"
#ifdef OSD_SDL
// standard SDL headers
@ -39,57 +40,6 @@ enum
VIDEO_MODE_COUNT
};
class osd_dim
{
public:
osd_dim(const int &w, const int &h)
: m_w(w), m_h(h)
{
}
int width() const { return m_w; }
int height() const { return m_h; }
bool operator!=(const osd_dim &other) { return (m_w != other.width()) || (m_h != other.height()); }
bool operator==(const osd_dim &other) { return (m_w == other.width()) && (m_h == other.height()); }
private:
int m_w;
int m_h;
};
class osd_rect
{
public:
osd_rect()
: m_x(0), m_y(0), m_d(0,0)
{
}
osd_rect(const int x, const int y, const int &w, const int &h)
: m_x(x), m_y(y), m_d(w,h)
{
}
osd_rect(const int x, const int y, const osd_dim &d)
: m_x(x), m_y(y), m_d(d)
{
}
int top() const { return m_y; }
int left() const { return m_x; }
int width() const { return m_d.width(); }
int height() const { return m_d.height(); }
osd_dim dim() const { return m_d; }
int bottom() const { return m_y + m_d.height(); }
int right() const { return m_x + m_d.width(); }
osd_rect move_by(int dx, int dy) const { return osd_rect(m_x + dx, m_y + dy, m_d); }
osd_rect resize(int w, int h) const { return osd_rect(m_x, m_y, w, h); }
private:
int m_x;
int m_y;
osd_dim m_d;
};
class osd_monitor_info
{
public:

View File

@ -52,8 +52,8 @@ bgfx_chain::~bgfx_chain()
void bgfx_chain::process(render_primitive* prim, int view, int screen, texture_manager& textures, osd_window& window, uint64_t blend)
{
int current_view = view;
uint16_t screen_width = window.get_size().width();
uint16_t screen_height = window.get_size().height();
uint16_t screen_width(floor((prim->bounds.x1 - prim->bounds.x0) + 0.5f));
uint16_t screen_height(floor((prim->bounds.y1 - prim->bounds.y0) + 0.5f));
uint32_t rotation_type = (window.target()->orientation() & ROT90) == ROT90 ?
1 : (window.target()->orientation() & ROT180) == ROT180 ?
2 : (window.target()->orientation() & ROT270) == ROT270 ?

View File

@ -74,10 +74,9 @@ void bgfx_chain_entry::submit(int view, render_primitive* prim, texture_manager&
m_effect->submit(view, blend);
std::string output_name = m_output + std::to_string(screen);
if (m_targets.target(output_name) != nullptr)
if (m_targets.target(screen, m_output) != nullptr)
{
m_targets.target(output_name)->page_flip();
m_targets.target(screen, m_output)->page_flip();
}
}
@ -87,11 +86,7 @@ void bgfx_chain_entry::setup_screensize_uniforms(texture_manager& textures, uint
float height = screen_height;
if (m_inputs.size() > 0)
{
std::string name = m_inputs[0].texture();
if (name == "previous")
{
name = name + std::to_string(screen);
}
std::string name = m_inputs[0].texture() + std::to_string(screen);
width = float(textures.provider(name)->width());
height = float(textures.provider(name)->height());
}
@ -165,17 +160,16 @@ 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 + std::to_string(screen);
if (m_targets.target(output_name) != nullptr)
if (m_targets.target(screen, m_output) != nullptr)
{
bgfx_target* output = m_targets.target(output_name);
bgfx_target* output = m_targets.target(screen, m_output);
if (output->width() == 0)
{
return false;
}
handle = output->target();
width = output->width() * output->prescale_x();
height = output->height() * output->prescale_y();
width = output->width();
height = output->height();
}
bgfx::setViewFrameBuffer(view, handle);

View File

@ -27,7 +27,7 @@
#include "suppressor.h"
#include "suppressorreader.h"
bgfx_chain_entry* chain_entry_reader::read_from_value(const Value& value, std::string prefix, osd_options& options, texture_manager& textures, target_manager& targets, effect_manager& effects, std::map<std::string, bgfx_slider*>& sliders, std::map<std::string, bgfx_parameter*>& params)
bgfx_chain_entry* chain_entry_reader::read_from_value(const Value& value, std::string prefix, osd_options& options, texture_manager& textures, target_manager& targets, effect_manager& effects, std::map<std::string, bgfx_slider*>& sliders, std::map<std::string, bgfx_parameter*>& params, uint32_t screen_index)
{
if (!validate_parameters(value, prefix))
{
@ -49,13 +49,50 @@ bgfx_chain_entry* chain_entry_reader::read_from_value(const Value& value, std::s
const Value& input_array = value["input"];
for (UINT32 i = 0; i < input_array.Size(); i++)
{
if (!READER_CHECK(input_array[i].HasMember("sampler"), (prefix + "input[" + std::to_string(i) + ": Must have string value 'sampler' (what sampler are we binding to?)\n").c_str())) return nullptr;
if (!READER_CHECK(input_array[i]["sampler"].IsString(), (prefix + "input[" + std::to_string(i) + ": Value 'sampler' must be a string\n").c_str())) return nullptr;
if (!READER_CHECK(input_array[i].HasMember("texture"), (prefix + "input[" + std::to_string(i) + ": Must have string value 'texture' (what texture are we using?)\n").c_str())) return nullptr;
if (!READER_CHECK(input_array[i]["texture"].IsString(), (prefix + "input[" + std::to_string(i) + ": Value 'texture' must be a string\n").c_str())) return nullptr;
std::string sampler = input_array[i]["sampler"].GetString();
std::string texture = input_array[i]["texture"].GetString();
inputs.push_back(bgfx_input_pair(i, sampler, texture));
const Value& input = input_array[i];
if (!READER_CHECK(input.HasMember("sampler"), (prefix + "input[" + std::to_string(i) + ": Must have string value 'sampler' (what sampler are we binding to?)\n").c_str())) return nullptr;
if (!READER_CHECK(input["sampler"].IsString(), (prefix + "input[" + std::to_string(i) + ": Value 'sampler' must be a string\n").c_str())) return nullptr;
bool has_texture = input.HasMember("texture");
bool has_target = input.HasMember("target");
bool has_option = input.HasMember("option");
if (!READER_CHECK(has_texture || has_target || has_option, (prefix + "input[" + std::to_string(i) + ": Must have string value 'target', 'texture' or 'option' (what source are we using?)\n").c_str())) return nullptr;
if (!READER_CHECK(!has_texture || input["texture"].IsString(), (prefix + "input[" + std::to_string(i) + ": Value 'texture' must be a string\n").c_str())) return nullptr;
if (!READER_CHECK(!has_target || input["target"].IsString(), (prefix + "input[" + std::to_string(i) + ": Value 'target' must be a string\n").c_str())) return nullptr;
if (!READER_CHECK(!has_option || input["option"].IsString(), (prefix + "input[" + std::to_string(i) + ": Value 'option' must be a string\n").c_str())) return nullptr;
std::string texture_name = "";
if (has_texture)
{
texture_name = input["texture"].GetString();
if (texture_name != "screen")
{
bgfx_texture* texture = textures.create_png_texture(options.art_path(), texture_name, texture_name, 0, screen_index);
if (texture == nullptr)
{
return nullptr;
}
}
}
else if (has_target)
{
texture_name = input["target"].GetString();
}
else if (has_option)
{
texture_name = input["option"].GetString();
bgfx_texture* texture = textures.create_png_texture(options.art_path(), options.value(texture_name.c_str()), texture_name, 0, screen_index);
if (texture == nullptr)
{
return nullptr;
}
}
else
{
return nullptr;
}
std::string sampler = input["sampler"].GetString();
inputs.push_back(bgfx_input_pair(i, sampler, texture_name));
}
}

View File

@ -26,7 +26,7 @@ class bgfx_parameter;
class chain_entry_reader : public state_reader
{
public:
static bgfx_chain_entry* read_from_value(const Value& value, std::string prefix, osd_options& options, texture_manager& textures, target_manager& targets, effect_manager& effects, std::map<std::string, bgfx_slider*>& sliders, std::map<std::string, bgfx_parameter*>& params);
static bgfx_chain_entry* read_from_value(const Value& value, std::string prefix, osd_options& options, texture_manager& textures, target_manager& targets, effect_manager& effects, std::map<std::string, bgfx_slider*>& sliders, std::map<std::string, bgfx_parameter*>& params, uint32_t screen_index);
private:
static bool validate_parameters(const Value& value, std::string prefix);

View File

@ -62,6 +62,8 @@ bgfx_chain* chain_manager::load_chain(std::string name, running_machine& machine
Document document;
document.Parse<0>(data);
delete [] data;
if (document.HasParseError())
{
std::string error(GetParseError_En(document.GetParseError()));
@ -70,7 +72,7 @@ bgfx_chain* chain_manager::load_chain(std::string name, running_machine& machine
return nullptr;
}
bgfx_chain* chain = chain_reader::read_from_value(document, name + ": ", m_options, machine, window_index, screen_index, m_textures, m_targets, m_effects, m_width, m_height);
bgfx_chain* chain = chain_reader::read_from_value(document, name + ": ", m_options, machine, window_index, screen_index, m_textures, m_targets, m_effects);
if (chain == nullptr)
{

View File

@ -27,13 +27,11 @@ class bgfx_chain;
class chain_manager {
public:
chain_manager(osd_options& options, texture_manager& textures, target_manager& targets, effect_manager& effects, uint32_t width, uint32_t height)
chain_manager(osd_options& options, texture_manager& textures, target_manager& targets, effect_manager& effects)
: m_options(options)
, m_textures(textures)
, m_targets(targets)
, m_effects(effects)
, m_width(width)
, m_height(height)
{
}
~chain_manager();
@ -48,8 +46,6 @@ private:
texture_manager& m_textures;
target_manager& m_targets;
effect_manager& m_effects;
uint32_t m_width;
uint32_t m_height;
std::vector<bgfx_chain*> m_chains;
};

View File

@ -24,7 +24,7 @@
#include "slider.h"
#include "parameter.h"
bgfx_chain* chain_reader::read_from_value(const Value& value, std::string prefix, osd_options& options, running_machine& machine, uint32_t window_index, uint32_t screen_index, texture_manager& textures, target_manager& targets, effect_manager& effects, uint32_t screen_width, uint32_t screen_height)
bgfx_chain* chain_reader::read_from_value(const Value& value, std::string prefix, osd_options& options, running_machine& machine, uint32_t window_index, uint32_t screen_index, texture_manager& textures, target_manager& targets, effect_manager& effects)
{
if (!validate_parameters(value, prefix))
{
@ -90,7 +90,7 @@ bgfx_chain* chain_reader::read_from_value(const Value& value, std::string prefix
// TODO: Move into its own reader
for (UINT32 i = 0; i < target_array.Size(); i++)
{
if (!target_reader::read_from_value(target_array[i], prefix + "targets[" + std::to_string(i) + "]: ", targets, options, screen_width, screen_height))
if (!target_reader::read_from_value(target_array[i], prefix + "targets[" + std::to_string(i) + "]: ", targets, options, screen_index))
{
return nullptr;
}
@ -104,7 +104,7 @@ bgfx_chain* chain_reader::read_from_value(const Value& value, std::string prefix
const Value& entry_array = value["passes"];
for (UINT32 i = 0; i < entry_array.Size(); i++)
{
bgfx_chain_entry* entry = chain_entry_reader::read_from_value(entry_array[i], prefix + "passes[" + std::to_string(i) + "]: ", options, textures, targets, effects, slider_map, param_map);
bgfx_chain_entry* entry = chain_entry_reader::read_from_value(entry_array[i], prefix + "passes[" + std::to_string(i) + "]: ", options, textures, targets, effects, slider_map, param_map, screen_index);
if (entry == nullptr)
{
return nullptr;

View File

@ -21,7 +21,7 @@ class effect_manager;
class chain_reader : public state_reader
{
public:
static bgfx_chain* read_from_value(const Value& value, std::string prefix, osd_options& options, running_machine& machine, uint32_t window_index, uint32_t screen_index, texture_manager& textures, target_manager& targets, effect_manager& effects, uint32_t screen_width, uint32_t screen_height);
static bgfx_chain* read_from_value(const Value& value, std::string prefix, osd_options& options, running_machine& machine, uint32_t window_index, uint32_t screen_index, texture_manager& textures, target_manager& targets, effect_manager& effects);
private:
static bool validate_parameters(const Value& value, std::string prefix);

View File

@ -10,6 +10,8 @@
#include "uniform.h"
#include "modules/osdmodule.h"
bgfx_effect::bgfx_effect(uint64_t state, bgfx::ShaderHandle vertex_shader, bgfx::ShaderHandle fragment_shader, std::vector<bgfx_uniform*> uniforms)
: m_state(state)
{
@ -17,6 +19,12 @@ bgfx_effect::bgfx_effect(uint64_t state, bgfx::ShaderHandle vertex_shader, bgfx:
for (int i = 0; i < uniforms.size(); i++)
{
if (m_uniforms[uniforms[i]->name()] != nullptr)
{
osd_printf_verbose("Uniform %s appears to be duplicated in one or more effects, please double-check the effect JSON files.\n", uniforms[i]->name().c_str());
delete uniforms[i];
continue;
}
m_uniforms[uniforms[i]->name()] = uniforms[i];
}
}

View File

@ -47,10 +47,11 @@ bgfx_effect* effect_manager::effect(std::string name)
bgfx_effect* effect_manager::load_effect(std::string name)
{
if (name.length() < 5 || (name.compare(name.length() - 5, 5, ".json") != 0)) {
name = name + ".json";
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 = std::string(m_options.bgfx_path()) + "/effects/" + name;
std::string path = std::string(m_options.bgfx_path()) + "/effects/" + full_name;
bx::CrtFileReader reader;
if (!bx::open(&reader, path.c_str()))
@ -69,6 +70,8 @@ bgfx_effect* effect_manager::load_effect(std::string name)
Document document;
document.Parse<0>(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());

View File

@ -24,6 +24,7 @@ uniform vec4 u_scanline_bright_scale;
uniform vec4 u_scanline_bright_offset;
uniform vec4 u_scanline_jitter;
uniform vec4 u_scanline_height;
uniform vec4 u_scanline_variation;
uniform vec4 u_back_color; // TODO: Unused in current implementation, mostly
uniform vec4 u_shadow_tile_mode; // 0 based on screen dimension, 1 based on source dimension
uniform vec4 u_shadow_alpha;
@ -65,14 +66,8 @@ vec2 GetAdjustedCoords(vec2 coord, vec2 center_offset)
void main()
{
vec2 ScreenTexelDims = vec2(1.0, 1.0) / u_screen_dims.xy;
vec2 SourceTexelDims = vec2(1.0, 1.0) / u_source_dims.xy;
vec2 SourceRes = u_source_dims.xy;
vec2 HalfSourceRect = vec2(0.5, 0.5);
vec2 ScreenCoord = v_texcoord0.xy;
vec2 BaseCoord = GetAdjustedCoords(v_texcoord0, HalfSourceRect);
vec2 BaseCoord = GetAdjustedCoords(v_texcoord0, vec2(0.5, 0.5));
// Color
vec4 BaseColor = texture2D(s_tex, BaseCoord);
@ -118,31 +113,37 @@ void main()
BaseColor.b = pow(BaseColor.b, u_power.b);
// Scanline Simulation (may not affect bloom)
if (u_prepare_bloom.x == 0.0)
{
//if (u_prepare_bloom.x == 0.0)
//{
// Scanline Simulation (may not affect vector screen)
if (u_prepare_vector.x == 0.0 && u_scanline_alpha.x > 0.0f)
{
//if (u_prepare_vector.x == 0.0 && u_scanline_alpha.x > 0.0f)
//{
float BrightnessOffset = (u_scanline_bright_offset.x * u_scanline_alpha.x);
float BrightnessScale = (u_scanline_bright_scale.x * u_scanline_alpha.x) + (1.0 - u_scanline_alpha.x);
float ColorBrightness = 0.299 * BaseColor.r + 0.587 * BaseColor.g + 0.114 * BaseColor.b;
float ScanCoord = v_texcoord0.y * u_source_dims.y * u_scanline_scale.x * 3.1415927;
float ScanCoordJitter = u_scanline_jitter.x * u_jitter_amount.x * 1.618034;
float ScanSine = sin(ScanCoord + ScanCoordJitter);
float ScanSineScaled = pow(ScanSine * ScanSine, 1.0);//u_scanline_height.x);
float ScanBrightness = (ScanSineScaled * u_scanline_bright_scale.x + 1.0 + u_scanline_bright_offset.x) * 0.5;
float ScanlineWide = u_scanline_height.x + u_scanline_variation.x * max(1.0, u_scanline_height.x) * (1.0 - ColorBrightness);
float ScanSineScaled = pow(ScanSine * ScanSine, ScanlineWide);
float ScanBrightness = ScanSineScaled * BrightnessScale + BrightnessOffset * BrightnessScale;
BaseColor.rgb *= mix(vec3(1.0, 1.0, 1.0), vec3(ScanBrightness, ScanBrightness, ScanBrightness), u_scanline_alpha.xxx);
}
//}
// Hum Bar Simulation (may not affect vector screen)
if (u_prepare_vector.x == 0.0 && u_humbar_alpha.x > 0.0f)
{
float HumTimeStep = fract(u_time.x * 0.001);
float HumBrightness = 1.0 - fract(BaseCoord.y + HumTimeStep) * u_humbar_alpha.x;
BaseColor.rgb *= HumBrightness;
}
}
//if (u_prepare_vector.x == 0.0 && u_humbar_alpha.x > 0.0f)
//{
//float HumTimeStep = fract(u_time.x * 0.001);
//float HumBrightness = 1.0 - fract(BaseCoord.y + HumTimeStep) * u_humbar_alpha.x;
//BaseColor.rgb *= HumBrightness;
//}
//}
vec4 Output = u_prepare_vector.x > 0.0 ? BaseColor * (v_color0 + vec4(1.0, 1.0, 1.0, 0.0)) : BaseColor * v_color0;
Output.a = 1.0;
//vec4 Output = u_prepare_vector.x > 0.0 ? BaseColor * (v_color0 + vec4(1.0, 1.0, 1.0, 0.0)) : BaseColor * v_color0;
//Output.a = 1.0;
gl_FragColor = Output;
gl_FragColor = vec4(BaseColor.rgb, 1.0);//Output;
}

View File

@ -0,0 +1,30 @@
$input v_color0, v_texcoord0
// license:BSD-3-Clause
// copyright-holders:Dario Manesku
#include "../../../../../3rdparty/bgfx/examples/common/common.sh"
// Samplers
SAMPLER2D(s_tex, 0);
uniform vec4 u_source_dims;
uniform vec4 u_tex_size0;
void main()
{
vec2 Scale = u_tex_size0.xy / u_source_dims.xy;
vec2 TexelDims = v_texcoord0.xy * u_source_dims.xy;
vec2 i = floor(TexelDims);
vec2 s = fract(TexelDims);
// Figure out where in the texel to sample to get the correct pre-scaled bilinear.
vec2 CenterDistance = s - 0.5;
vec2 RegionRange = 0.5 - 0.5 / Scale;
vec2 f = (CenterDistance - clamp(CenterDistance, -RegionRange, RegionRange)) * Scale + 0.5;
vec2 TexCoord = (i + f) / u_source_dims.xy;
gl_FragColor = texture2D(s_tex, TexCoord) * v_color0;
}

View File

@ -29,11 +29,7 @@ bgfx_input_pair::bgfx_input_pair(int index, std::string sampler, std::string tex
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 name = m_texture;
if (targets.target(m_texture + std::to_string(screen)) != nullptr)
{
name = m_texture + std::to_string(screen);
}
std::string name = m_texture + std::to_string(screen);
bgfx_texture_handle_provider* provider = textures.provider(name);
bgfx_uniform *tex_size = effect->uniform("u_tex_size" + std::to_string(m_index));

View File

@ -81,7 +81,7 @@ const bgfx::Memory* shader_manager::load_mem(std::string name)
bx::CrtFileReader reader;
bx::open(&reader, name.c_str());
uint32_t size = (uint32_t)bx::getSize(&reader);
uint32_t size(bx::getSize(&reader));
const bgfx::Memory* mem = bgfx::alloc(size + 1);
bx::read(&reader, mem->data, size);
bx::close(&reader);

View File

@ -10,26 +10,29 @@
#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, int32_t index, 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 style, bool double_buffer, bool filter, bool smooth, uint32_t screen)
: m_name(name)
, m_format(format)
, m_targets(nullptr)
, m_textures(nullptr)
, m_width(width)
, m_height(height)
, m_prescale_x(prescale_x)
, m_prescale_y(prescale_y)
, m_double_buffer(double_buffer)
, m_style(style)
, m_filter(filter)
, m_output(output)
, m_index(index)
, m_smooth(smooth)
, m_screen(screen)
, m_current_page(0)
, m_initialized(false)
, m_initialized(false)
, m_page_count(double_buffer ? 2 : 1)
{
if (init)
if (m_width > 0 && m_height > 0)
{
if (smooth)
{
m_width *= 2;
m_height *= 2;
}
uint32_t wrap_mode = BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP;
uint32_t filter_mode = filter ? (BGFX_TEXTURE_MIN_ANISOTROPIC | BGFX_TEXTURE_MAG_ANISOTROPIC) : (BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIP_POINT);
@ -37,7 +40,7 @@ bgfx_target::bgfx_target(std::string name, bgfx::TextureFormat::Enum format, uin
m_targets = new bgfx::FrameBufferHandle[m_page_count];
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);
m_textures[page] = bgfx::createTexture2D(m_width, m_height, 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);
@ -54,12 +57,11 @@ bgfx_target::bgfx_target(void *handle, uint16_t width, uint16_t height)
, m_textures(nullptr)
, m_width(width)
, m_height(height)
, m_prescale_x(1)
, m_prescale_y(1)
, m_double_buffer(false)
, m_style(TARGET_STYLE_CUSTOM)
, m_filter(false)
, m_index(-1)
, m_smooth(false)
, m_screen(-1)
, m_current_page(0)
, m_initialized(true)
, m_page_count(0)

View File

@ -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, int32_t index, 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 style, bool double_buffer, bool filter, bool smooth, uint32_t screen);
bgfx_target(void *handle, uint16_t width, uint16_t height);
virtual ~bgfx_target();
@ -39,11 +39,9 @@ public:
std::string name() const { return m_name; }
bool double_buffered() const { return m_double_buffer; }
uint32_t style() const { return m_style; }
bool filter() const { return m_filter; }
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; }
bool filter() const { return m_filter; }
bool smooth() const { return m_smooth; }
uint32_t screen_index() const { return m_screen; }
// bgfx_texture_handle_provider
virtual uint16_t width() const override { return m_width; }
@ -61,14 +59,12 @@ private:
uint16_t m_width;
uint16_t m_height;
uint32_t m_prescale_x;
uint32_t m_prescale_y;
bool m_double_buffer;
uint32_t m_style;
bool m_filter;
bool m_output;
int32_t m_index;
bool m_smooth;
int32_t m_screen;
uint32_t m_current_page;

View File

@ -26,32 +26,34 @@ target_manager::target_manager(osd_options& options, texture_manager& 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()
{
std::vector<bgfx_target*> to_delete;
for (std::pair<std::string, bgfx_target*> target : m_targets)
{
if (target.second != nullptr)
{
delete target.second;
to_delete.push_back(target.second);
}
}
m_targets.clear();
delete [] m_guest_width;
delete [] m_guest_height;
for (uint32_t i = 0; i < to_delete.size(); i++)
{
delete to_delete[i];
}
}
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_manager::create_target(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t height, uint32_t style, bool double_buffer, bool filter, bool smooth, uint32_t screen)
{
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;
bgfx_target* target = new bgfx_target(name, format, width, height, style, double_buffer, filter, smooth, screen);
m_targets[name + std::to_string(screen)] = target;
m_textures.add_provider(name + std::to_string(screen), target);
m_textures.add_provider(name, target);
return target;
}
@ -62,151 +64,102 @@ bgfx_target* target_manager::create_backbuffer(void *handle, uint32_t width, uin
return target;
}
bgfx_target* target_manager::target(std::string name)
bgfx_target* target_manager::target(uint32_t screen, std::string name)
{
std::map<std::string, bgfx_target*>::iterator iter = m_targets.find(name);
if (iter != m_targets.end())
std::string full_name = name + std::to_string(screen);
bgfx_target* target = m_targets[full_name];
if (target == nullptr)
{
return iter->second;
osd_printf_verbose("Warning: Attempting to retrieve a nonexistent target '%s' for screen %d\n", name.c_str(), screen);
}
return nullptr;
return target;
}
void target_manager::update_guest_targets(int32_t screen, uint16_t width, uint16_t height)
void target_manager::update_target_sizes(uint32_t screen, uint16_t width, uint16_t height, uint32_t style)
{
if (screen < 0 || screen >= MAX_SCREENS)
if (style == TARGET_STYLE_CUSTOM) return;
std::vector<osd_dim>& sizes = style == TARGET_STYLE_GUEST ? m_guest_dims : m_native_dims;
// Ensure that there's an entry to fill
while (sizes.size() <= screen)
{
sizes.push_back(osd_dim(0, 0));
}
if (width != sizes[screen].width() || height != sizes[screen].height())
{
return;
sizes[screen] = osd_dim(width, height);
rebuild_targets(screen, style);
}
if (width != m_guest_width[screen] || height != m_guest_height[screen])
{
m_guest_width[screen] = width;
m_guest_height[screen] = height;
ensure_guest_targets();
rebuild_guest_targets(screen);
}
}
void target_manager::ensure_guest_targets()
void target_manager::rebuild_targets(uint32_t screen, uint32_t style)
{
// Build a list of all guest targets that end in 0 *or* don't end in a number
std::vector<std::string> existing_names;
if (style == TARGET_STYLE_CUSTOM) return;
std::vector<bgfx_target*> to_resize;
for (std::pair<std::string, bgfx_target*> target_pair : m_targets)
{
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);
}
}
bgfx_target* target = target_pair.second;
if (target == nullptr || target->style() != style || target->screen_index() != screen)
{
continue;
}
to_resize.push_back(target);
}
for (std::string name : existing_names)
std::vector<osd_dim>& sizes = style == TARGET_STYLE_GUEST ? m_guest_dims : m_native_dims;
for (bgfx_target* target : to_resize)
{
create_nonexistent_targets(name);
}
}
void target_manager::rebuild_guest_targets(int32_t screen)
{
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);
}
}
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();
const bool smooth = target->smooth();
const uint16_t width(sizes[screen].width());
const uint16_t height(sizes[screen].height());
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]);
create_target(name, format, width, height, style, double_buffered, filter, smooth, screen);
}
}
void target_manager::update_screen_count(uint32_t count)
{
// Ensure that there's an entry to fill
while (count > m_native_dims.size())
{
m_native_dims.push_back(osd_dim(0, 0));
}
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");
for (uint32_t screen = old_count; screen < m_screen_count; screen++)
{
create_target_if_nonexistent(screen, "output", false, false, false, TARGET_STYLE_NATIVE);
create_target_if_nonexistent(screen, "previous", false, false, false, TARGET_STYLE_NATIVE);
}
}
}
}
void target_manager::create_nonexistent_targets(std::string name)
void target_manager::create_target_if_nonexistent(uint32_t screen, std::string name, bool double_buffered, bool filter, bool smooth, uint32_t style)
{
bool double_buffered = true;
bool filter = true;
if (m_targets[name + "0"] != nullptr)
if (style == TARGET_STYLE_CUSTOM) return;
if (m_targets[name + std::to_string(screen)] != nullptr)
{
double_buffered = m_targets[name + "0"]->double_buffered();
filter = m_targets[name + "0"]->filter();
return;
}
for (uint32_t screen = 0; screen < m_screen_count; screen++)
{
create_guest_if_nonexistent(name, screen, double_buffered, filter);
}
}
std::vector<osd_dim>& sizes = style == TARGET_STYLE_GUEST ? m_guest_dims : m_native_dims;
uint16_t width(sizes[screen].width());
uint16_t height(sizes[screen].height());
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;
create_target(name, bgfx::TextureFormat::RGBA8, width, height, style, double_buffered, filter, smooth, screen);
}

View File

@ -19,6 +19,8 @@
#include <bgfx/bgfx.h>
#include "modules/osdhelper.h"
#include "texturemanager.h"
class bgfx_target;
@ -29,30 +31,25 @@ public:
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_target(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t height, uint32_t style, bool double_buffer, bool filter, bool smooth, uint32_t screen);
bgfx_target* create_backbuffer(void *handle, uint32_t width, uint32_t height);
void update_guest_targets(int32_t screen, uint16_t width, uint16_t height);
void update_target_sizes(uint32_t screen, uint16_t width, uint16_t height, uint32_t style);
void update_screen_count(uint32_t count);
// Getters
bgfx_target* target(std::string name);
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]; }
bgfx_target* target(uint32_t screen, std::string name);
private:
void rebuild_guest_targets(int32_t screen);
void rebuild_outputs();
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);
void rebuild_targets(uint32_t screen, uint32_t style);
void create_target_if_nonexistent(uint32_t screen, std::string name, bool double_buffered, bool filter, bool smooth, uint32_t style);
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;
std::vector<osd_dim> m_guest_dims;
std::vector<osd_dim> m_native_dims;
uint32_t m_screen_count;
static const int32_t MAX_SCREENS;

View File

@ -21,7 +21,7 @@ const target_reader::string_to_enum target_reader::STYLE_NAMES[target_reader::ST
{ "custom", TARGET_STYLE_CUSTOM }
};
bool target_reader::read_from_value(const Value& value, std::string prefix, target_manager& targets, osd_options& options, uint32_t screen_width, uint32_t screen_height)
bool target_reader::read_from_value(const Value& value, std::string prefix, target_manager& targets, osd_options& options, uint32_t screen_index)
{
if (!validate_parameters(value, prefix))
{
@ -31,9 +31,8 @@ bool target_reader::read_from_value(const Value& value, std::string prefix, targ
std::string target_name = value["name"].GetString();
uint32_t mode = uint32_t(get_enum_from_value(value, "mode", TARGET_STYLE_NATIVE, STYLE_NAMES, STYLE_COUNT));
bool bilinear = get_bool(value, "bilinear", true);
bool double_buffer = get_bool(value, "doublebuffer", true);
bool prescale = get_bool(value, "prescale", false);
bool output = get_bool(value, "output", false);
bool double_buffer = get_bool(value, "doublebuffer", true);
bool smooth = get_bool(value, "oversample", false);
uint16_t width = 0;
uint16_t height = 0;
@ -42,8 +41,6 @@ bool target_reader::read_from_value(const Value& value, std::string prefix, targ
case TARGET_STYLE_GUEST:
break;
case TARGET_STYLE_NATIVE:
width = screen_width;
height = screen_height;
break;
case TARGET_STYLE_CUSTOM:
if (!READER_CHECK(value.HasMember("width"), (prefix + "Target '" + target_name + "': Must have numeric value 'width'\n").c_str())) return false;
@ -55,19 +52,7 @@ bool target_reader::read_from_value(const Value& value, std::string prefix, targ
break;
}
uint32_t prescale_x = 1;
uint32_t prescale_y = 1;
if (prescale)
{
prescale_x = options.bgfx_prescale_x();
prescale_y = options.bgfx_prescale_y();
}
if (!output)
{
targets.create_target(target_name, bgfx::TextureFormat::RGBA8, width, height, prescale_x, prescale_y, mode, double_buffer, bilinear, output);
}
targets.create_target(target_name, bgfx::TextureFormat::RGBA8, width, height, mode, double_buffer, bilinear, smooth, screen_index);
return true;
}
@ -79,7 +64,6 @@ bool target_reader::validate_parameters(const Value& value, std::string prefix)
if (!READER_CHECK(value["mode"].IsString(), (prefix + "Value 'mode' must be a string (what screens does this apply to?)\n").c_str())) return false;
if (!READER_CHECK(!value.HasMember("bilinear") || value["bilinear"].IsBool(), (prefix + "Value 'bilinear' must be a boolean\n").c_str())) return false;
if (!READER_CHECK(!value.HasMember("doublebuffer") || value["doublebuffer"].IsBool(), (prefix + "Value 'doublebuffer' must be a boolean\n").c_str())) return false;
if (!READER_CHECK(!value.HasMember("prescale") || value["prescale"].IsBool(), (prefix + "Value 'prescale' must be a boolean\n").c_str())) return false;
if (!READER_CHECK(!value.HasMember("output") || value["output"].IsBool(), (prefix + "Value 'output' must be a boolean\n").c_str())) return false;
if (!READER_CHECK(!value.HasMember("oversample") || value["oversample"].IsBool(), (prefix + "Value 'oversample' must be a boolean\n").c_str())) return false;
return true;
}

View File

@ -21,7 +21,7 @@ class osd_options;
class target_reader : public state_reader
{
public:
static bool read_from_value(const Value& value, std::string prefix, target_manager& targets, osd_options& options, uint32_t screen_width, uint32_t screen_height);
static bool read_from_value(const Value& value, std::string prefix, target_manager& targets, osd_options& options, uint32_t screen_index);
private:
static bool validate_parameters(const Value& value, std::string prefix);

View File

@ -50,12 +50,18 @@ bgfx_texture* texture_manager::create_texture(std::string name, bgfx::TextureFor
return texture;
}
bgfx_texture* texture_manager::create_png_texture(std::string path, std::string file_name, std::string texture_name, uint32_t flags)
bgfx_texture* texture_manager::create_png_texture(std::string path, std::string file_name, std::string texture_name, uint32_t flags, uint32_t screen)
{
bitmap_argb32 bitmap;
emu_file file(path.c_str(), OPEN_FLAG_READ);
render_load_png(bitmap, file, nullptr, file_name.c_str());
if (bitmap.width() == 0 || bitmap.height() == 0)
{
printf("Unable to load PNG '%s' from path '%s'\n", path.c_str(), file_name.c_str());
return nullptr;
}
uint8_t *texture_data = new uint8_t[bitmap.width() * bitmap.height() * 4];
uint32_t width = bitmap.width();
@ -66,6 +72,10 @@ bgfx_texture* texture_manager::create_png_texture(std::string path, std::string
copy_util::copyline_argb32(reinterpret_cast<UINT32 *>(texture_data) + y * width, reinterpret_cast<UINT32 *>(base) + y * rowpixels, width, nullptr);
}
if (screen >= 0)
{
texture_name += std::to_string(screen);
}
bgfx_texture* texture = create_texture(texture_name, bgfx::TextureFormat::RGBA8, width, height, texture_data, flags);
delete[] texture_data;

View File

@ -28,7 +28,7 @@ public:
~texture_manager();
bgfx_texture* create_texture(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t height, void* data = nullptr, uint32_t flags = BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP);
bgfx_texture* create_png_texture(std::string path, std::string file_name, std::string texture_name, uint32_t flags = BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP);
bgfx_texture* create_png_texture(std::string path, std::string file_name, std::string texture_name, uint32_t flags = BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP, uint32_t screen = -1);
void add_provider(std::string name, bgfx_texture_handle_provider* texture);
// Getters

View File

@ -7,7 +7,7 @@ $output v_color0, v_texcoord0, v_texcoord1, v_texcoord2
#include "../../../../../3rdparty/bgfx/examples/common/common.sh"
// Autos
uniform vec4 u_source_dims;
uniform vec4 u_tex_size0;
// User-supplied
uniform vec4 u_converge_red;
@ -23,9 +23,9 @@ void main()
vec2 half_value = vec2(0.5, 0.5);
v_texcoord0 = (a_texcoord0 - half_value) * (1.0 + u_radial_converge_red.xy ) + half_value + u_converge_red.xy * (vec2(1.0, 1.0) / u_source_dims.xy);
v_texcoord1 = (a_texcoord0 - half_value) * (1.0 + u_radial_converge_green.xy) + half_value + u_converge_green.xy * (vec2(1.0, 1.0) / u_source_dims.xy);
v_texcoord2 = (a_texcoord0 - half_value) * (1.0 + u_radial_converge_blue.xy ) + half_value + u_converge_blue.xy * (vec2(1.0, 1.0) / u_source_dims.xy);
v_texcoord0 = (a_texcoord0 - half_value) * (1.0 + u_radial_converge_red.xy ) + half_value + u_converge_red.xy * (vec2(1.0, 1.0) / u_tex_size0.xy);
v_texcoord1 = (a_texcoord0 - half_value) * (1.0 + u_radial_converge_green.xy) + half_value + u_converge_green.xy * (vec2(1.0, 1.0) / u_tex_size0.xy);
v_texcoord2 = (a_texcoord0 - half_value) * (1.0 + u_radial_converge_blue.xy ) + half_value + u_converge_blue.xy * (vec2(1.0, 1.0) / u_tex_size0.xy);
v_color0 = a_color0;
}

View File

@ -0,0 +1,14 @@
$input a_position, a_texcoord0, a_color0
$output v_texcoord0, v_color0
// license:BSD-3-Clause
// copyright-holders:Dario Manesku
#include "../../../../../3rdparty/bgfx/examples/common/common.sh"
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}

View File

@ -45,6 +45,7 @@
#include "bgfx/vertex.h"
#include "bgfx/uniform.h"
#include "bgfx/slider.h"
#include "bgfx/target.h"
//============================================================
// DEBUGGING
@ -190,16 +191,13 @@ int renderer_bgfx::create()
m_screen_effect[2] = m_effects->effect("screen_multiply");
m_screen_effect[3] = m_effects->effect("screen_add");
m_chains = new chain_manager(options, *m_textures, *m_targets, *m_effects, m_width[window().m_index], m_height[window().m_index]);
m_chains = new chain_manager(options, *m_textures, *m_targets, *m_effects);
parse_screen_chains(options.bgfx_screen_chains());
m_sliders_dirty = true;
uint32_t flags = BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP | BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIP_POINT;
m_texture_cache = m_textures->create_texture("#cache", bgfx::TextureFormat::RGBA8, CACHE_SIZE, CACHE_SIZE, nullptr, flags);
uint32_t shadow_flags = 0;//BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIP_POINT;
m_textures->create_png_texture(window().machine().options().art_path(), options.bgfx_shadow_mask(), "shadow", shadow_flags);
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));
@ -390,15 +388,16 @@ void renderer_bgfx::process_screen_quad(int screen, render_primitive* prim)
const bgfx::Memory* mem = mame_texture_data_to_bgfx_texture_data(prim->flags & PRIMFLAG_TEXFORMAT_MASK,
tex_width, tex_height, prim->texture.rowpixels, prim->texture.palette, prim->texture.base);
bgfx_texture *texture = new bgfx_texture("screen", bgfx::TextureFormat::RGBA8, tex_width, tex_height, mem);
m_textures->add_provider("screen", texture);
std::string full_name = "screen" + std::to_string(screen);
bgfx_texture *texture = new bgfx_texture(full_name, bgfx::TextureFormat::RGBA8, tex_width, tex_height, mem);
m_textures->add_provider(full_name, texture);
m_targets->update_guest_targets(screen, tex_width, tex_height);
m_targets->update_target_sizes(screen, tex_width, tex_height, TARGET_STYLE_GUEST);
screen_chain(screen)->process(prim, s_current_view, screen, *m_textures, window(), get_blend_state(PRIMFLAG_GET_BLENDMODE(prim->flags)));
s_current_view += screen_chain(screen)->applicable_passes();
m_textures->add_provider("screen", nullptr);
m_textures->add_provider(full_name, nullptr);
delete texture;
}
@ -477,7 +476,7 @@ void renderer_bgfx::render_post_screen_quad(int view, render_primitive* prim, bg
UINT32 blend = PRIMFLAG_GET_BLENDMODE(prim->flags);
bgfx::setVertexBuffer(buffer);
bgfx::setTexture(0, m_screen_effect[blend]->uniform("s_tex")->handle(), m_targets->target("output" + std::to_string(screen))->texture());
bgfx::setTexture(0, m_screen_effect[blend]->uniform("s_tex")->handle(), m_targets->target(screen, "output")->texture());
m_screen_effect[blend]->submit(view);
}
@ -792,17 +791,31 @@ int renderer_bgfx::handle_screen_chains()
}
prim = prim->next();
}
m_targets->update_screen_count(screens);
const uint32_t available_chains = m_screen_chains[window().m_index].size();
screens = screens >= available_chains ? available_chains: screens;
if (screens > 0)
{
m_targets->update_screen_count(screens);
}
// Process each screen as necessary
prim = window().m_primlist->first();
int seen_screen_quads = 0;
int screen_index = 0;
while (prim != nullptr)
{
if (PRIMFLAG_GET_SCREENTEX(prim->flags))
{
process_screen_quad(seen_screen_quads, prim);
seen_screen_quads++;
if (screen_index >= available_chains)
{
break;
}
uint16_t screen_width(floor((prim->bounds.x1 - prim->bounds.x0) + 0.5f));
uint16_t screen_height(floor((prim->bounds.y1 - prim->bounds.y0) + 0.5f));
m_targets->update_target_sizes(screen_index, screen_width, screen_height, TARGET_STYLE_NATIVE);
process_screen_quad(screen_index, prim);
screen_index++;
}
prim = prim->next();
}
@ -841,6 +854,7 @@ int renderer_bgfx::draw(int update)
osd_dim wdim = window().get_size();
m_width[window_index] = wdim.width();
m_height[window_index] = wdim.height();
if (window_index == 0)
{
if ((m_dimensions != osd_dim(m_width[window_index], m_height[window_index])))
@ -989,7 +1003,7 @@ renderer_bgfx::buffer_status renderer_bgfx::buffer_primitives(int view, bool atl
return BUFFER_PRE_FLUSH;
}
if (PRIMFLAG_GET_SCREENTEX((*prim)->flags) && m_screen_chains.size() > window().m_index && m_screen_chains[window().m_index].size() > 0)
if (PRIMFLAG_GET_SCREENTEX((*prim)->flags) && m_screen_chains.size() > window().m_index && screen < m_screen_chains[window().m_index].size())
{
render_post_screen_quad(view, *prim, buffer, screen);
return BUFFER_SCREEN;