-bgfx: Adjusted per-pass blending handling - fixes MT07586 and MT07587. (#10747) [Ryan Holtz]

This commit is contained in:
MooglyGuy 2022-12-26 04:40:43 +01:00 committed by GitHub
parent aede45e42e
commit 2d893a60b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 177 additions and 25 deletions

View File

@ -10,9 +10,7 @@
"blend": { "blend": {
"equation": "add", "equation": "add",
"srcColor": "dstcolor", "srcColor": "dstcolor",
"dstColor": "0", "dstColor": "0"
"srcAlpha": "dstalpha",
"dstAlpha": "0"
}, },
"depth": { "depth": {
"function": "always" "function": "always"

View File

@ -21,10 +21,10 @@
// defaults (dstColor, dstAlpha): "0" // defaults (dstColor, dstAlpha): "0"
// //
// "zero", "one", "invsrccolor", "invdstcolor", "invsrcalpha", and "invdstalpha" are provided as aliases for "0", "1", "1-srccolor", "1-dstcolor", "1-srcalpha", and "1-dstalpha" // "zero", "one", "invsrccolor", "invdstcolor", "invsrcalpha", and "invdstalpha" are provided as aliases for "0", "1", "1-srccolor", "1-dstcolor", "1-srcalpha", and "1-dstalpha"
"srcColor": "srcalpha", "srcColor": "1",
"dstColor": "1-srcalpha", "dstColor": "0",
"srcAlpha": "srcalpha", "srcAlpha": "1",
"dstAlpha": "1-srcalpha" "dstAlpha": "0"
}, },
// depth (required): The depth state for this effect. // depth (required): The depth state for this effect.

View File

@ -0,0 +1,121 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
//============================================================
//
// blit_alpha.json: A simple texture-to-target copy.
//
//============================================================
{
// blend (required): The blend state for this effect.
"blend": {
// equation (optional): What equation to perform on the source and destination blend values.
// values: "add", "sub", "revSub", "min", "max"
// default: "add"
//
// "subtract" and "revSubtract" are provided as aliases for "sub" and "revSub"
"equation": "add",
// blend function parameters (optional): What factors to use in the blend function when calculating the final pixel.
// values: "0", "1", "srccolor", "1-srccolor", "dstcolor", "1-dstcolor", "srcalpha", "1-srcalpha", "dstalpha", "1-dstalpha"
// defaults (srcColor, srcAlpha): "1"
// defaults (dstColor, dstAlpha): "0"
//
// "zero", "one", "invsrccolor", "invdstcolor", "invsrcalpha", and "invdstalpha" are provided as aliases for "0", "1", "1-srccolor", "1-dstcolor", "1-srcalpha", and "1-dstalpha"
"srcColor": "srcalpha",
"dstColor": "1-srcalpha",
"srcAlpha": "srcalpha",
"dstAlpha": "1-srcalpha"
},
// depth (required): The depth state for this effect.
"depth": {
// function (optional): The depth function to use when drawing.
// values: "never", "less", "equal", "lequal", "greater", "notequal", "gequal", "always"
// default: "always"
"function": "always",
// writeenable (optional): Whether to store Z-buffer data.
// values: true, false
// default: false
"writeenable": false
},
// cull (required): The cull mode for this effect.
"cull": {
// mode (optional): What winding, if any, to cull.
// values: "none", "cw", "ccw"
// default: "ccw"
//
// "clockwise" and "counterclockwise" are provided as aliases for "cw" and "ccw"
"mode": "none"
},
// write (required): Write enable for color and alpha channels.
"write": {
// rgb (optional): Whether to store color data when drawing.
// values: true, false
// default: false
"rgb": true,
// alpha (optional): Whether to store alpha data when drawing.
// values: true, false
// default: false
"alpha": true
},
// vertex (required): The vertex shader to use when drawing.
// value: A string containing the path and name of a shader file to use, minus the extension.
"vertex": "chains/misc/vs_blit",
// pixel/fragment (required): The pixel or fragment shader to use when drawing.
// value: A string containing the path and name of a shader file to use, minus the extension.
"fragment": "chains/misc/fs_blit",
// uniforms (required): The list of uniforms for this effect. Can be empty, but must exist.
"uniforms": [
{
// name (required): The name of the uniform, as used in either the vertex or pixel/fragment shader.
// value: A string containing the name of the uniform as described above.
//
// NOTE: Some names correspond to special values that will be automatically filled by the BGFX
// code if they are used by the shader. These names are:
// "u_screen_dims"
// The dimensions of the first texture input if present, otherwise the dimensions of the output window.
// Valid values: xy
// "u_inv_screen_dims"
// The reciprocal of u_screen_dims.
// Valid values: xy
// "u_source_dims"
// The size, in pixels, of the screen texture incoming to the chain.
// Valid values: xy
// "u_rotation_type"
// This screen's rotation type. 0 if ROT0, 1 if ROT90, 2 if ROT180, 3 of ROT270.
// Valid values: x
// "u_swap_xy"
// Whether this screen is swapped on the X and Y axes. 1 if true, 0 if false.
// Valid values: x
// "u_quad_dims"
// The dimensions, in pixels, occupied by this one screen primitive itself in the output window.
// Valid values: xy
// "u_tex_sizeN"
// The dimensions, in pixels, of the texture in input pair N. Starts at 0.
// valid values: xy
"name": "s_tex",
// type (required): The type of the uniform.
// values: "int", "vec4", "mat3", "mat4"
//
// Note: "int" should only be used for samplers.
"type": "int",
// values (required): The array of numbers with which to initialize the uniform.
// value: A JSON array containin the correct amount of numbers to initialize a uniform of the
// above-specified type. The following size rules should be followed:
// "int": 1 float
// "vec4": 4 floats
// "mat3": 9 floats
// "mat4": 16 floats
"values": [ 1.0 ]
}
]
}

View File

@ -11,9 +11,7 @@
"blend": { "blend": {
"equation": "add", "equation": "add",
"srcColor": "dstcolor", "srcColor": "dstcolor",
"dstColor": "0", "dstColor": "0"
"srcAlpha": "dstalpha",
"dstAlpha": "0"
}, },
"depth": { "depth": {
"function": "always" "function": "always"

View File

@ -44,8 +44,11 @@ uint64_t blend_reader::read_from_value(const Value& value)
uint64_t equation = get_enum_from_value(value, "equation", BGFX_STATE_BLEND_EQUATION_ADD, EQUATION_NAMES, EQUATION_COUNT); uint64_t equation = get_enum_from_value(value, "equation", BGFX_STATE_BLEND_EQUATION_ADD, EQUATION_NAMES, EQUATION_COUNT);
uint64_t srccolor = get_enum_from_value(value, "srcColor", BGFX_STATE_BLEND_ONE, FUNCTION_NAMES, FUNCTION_COUNT); uint64_t srccolor = get_enum_from_value(value, "srcColor", BGFX_STATE_BLEND_ONE, FUNCTION_NAMES, FUNCTION_COUNT);
uint64_t dstcolor = get_enum_from_value(value, "dstColor", BGFX_STATE_BLEND_ZERO, FUNCTION_NAMES, FUNCTION_COUNT); uint64_t dstcolor = get_enum_from_value(value, "dstColor", BGFX_STATE_BLEND_ZERO, FUNCTION_NAMES, FUNCTION_COUNT);
uint64_t srcalpha = get_enum_from_value(value, "srcAlpha", BGFX_STATE_BLEND_ONE, FUNCTION_NAMES, FUNCTION_COUNT); if (value.HasMember("srcAlpha") && value.HasMember("dstAlpha"))
uint64_t dstalpha = get_enum_from_value(value, "dstAlpha", BGFX_STATE_BLEND_ZERO, FUNCTION_NAMES, FUNCTION_COUNT); {
uint64_t srcalpha = get_enum_from_value(value, "srcAlpha", BGFX_STATE_BLEND_ONE, FUNCTION_NAMES, FUNCTION_COUNT);
return BGFX_STATE_BLEND_EQUATION(equation) | BGFX_STATE_BLEND_FUNC_SEPARATE(srccolor, dstcolor, srcalpha, dstalpha); uint64_t dstalpha = get_enum_from_value(value, "dstAlpha", BGFX_STATE_BLEND_ZERO, FUNCTION_NAMES, FUNCTION_COUNT);
return BGFX_STATE_BLEND_EQUATION(equation) | BGFX_STATE_BLEND_FUNC_SEPARATE(srccolor, dstcolor, srcalpha, dstalpha);
}
return BGFX_STATE_BLEND_EQUATION(equation) | BGFX_STATE_BLEND_FUNC(srccolor, dstcolor);
} }

View File

@ -108,11 +108,12 @@ void bgfx_chain::process(chain_manager::screen_prim &prim, int view, int screen,
} }
int current_view = view; int current_view = view;
for (bgfx_chain_entry* entry : m_entries) for (size_t i = 0; i < m_entries.size(); i++)
{ {
if (!entry->skip()) if (!m_entries[i]->skip())
{ {
entry->submit(current_view, prim, textures, screen_count, screen_width, screen_height, screen_scale_x, screen_scale_y, screen_offset_x, screen_offset_y, rotation_type, swap_xy, blend, screen); m_entries[i]->submit(current_view, prim, textures, screen_count, screen_width, screen_height, screen_scale_x, screen_scale_y, screen_offset_x, screen_offset_y,
rotation_type, swap_xy, i == (m_entries.size() - 1) ? blend : ~0ULL, screen);
current_view++; current_view++;
} }
} }

View File

@ -65,6 +65,7 @@ chain_manager::chain_manager(running_machine& machine, osd_options& options, tex
, m_window_index(window_index) , m_window_index(window_index)
, m_slider_notifier(slider_notifier) , m_slider_notifier(slider_notifier)
, m_screen_count(0) , m_screen_count(0)
, m_default_chain_index(-1)
{ {
m_converters.clear(); m_converters.clear();
refresh_available_chains(); refresh_available_chains();
@ -87,6 +88,20 @@ void chain_manager::init_texture_converters()
m_adjuster = m_effects.get_or_load_effect(m_options, "misc/bcg_adjust"); m_adjuster = m_effects.get_or_load_effect(m_options, "misc/bcg_adjust");
} }
void chain_manager::get_default_chain_info(std::string &out_chain_name, int32_t &out_chain_index)
{
if (m_default_chain_index == -1)
{
out_chain_index = CHAIN_NONE;
out_chain_name = "";
return;
}
out_chain_index = m_default_chain_index;
out_chain_name = "default";
return;
}
void chain_manager::refresh_available_chains() void chain_manager::refresh_available_chains()
{ {
m_available_chains.clear(); m_available_chains.clear();
@ -94,6 +109,16 @@ void chain_manager::refresh_available_chains()
const std::string chains_path = util::string_format("%s" PATH_SEPARATOR "chains", m_options.bgfx_path()); const std::string chains_path = util::string_format("%s" PATH_SEPARATOR "chains", m_options.bgfx_path());
find_available_chains(chains_path, ""); find_available_chains(chains_path, "");
if (m_default_chain_index == -1)
{
for (size_t i = 0; i < m_available_chains.size(); i++)
{
if (m_available_chains[i].m_name == "default")
{
m_default_chain_index = int32_t(i);
}
}
}
destroy_unloaded_chains(); destroy_unloaded_chains();
} }
@ -112,8 +137,7 @@ void chain_manager::destroy_unloaded_chains()
{ {
delete m_screen_chains[i]; delete m_screen_chains[i];
m_screen_chains[i] = nullptr; m_screen_chains[i] = nullptr;
m_chain_names[i] = ""; get_default_chain_info(m_chain_names[i], m_current_chain[i]);
m_current_chain[i] = CHAIN_NONE;
break; break;
} }
} }
@ -332,7 +356,7 @@ void chain_manager::process_screen_quad(uint32_t view, uint32_t screen, screen_p
} }
bgfx_chain* chain = screen_chain(screen); bgfx_chain* chain = screen_chain(screen);
chain->process(prim, view, screen, m_textures, window, bgfx_util::get_blend_state(PRIMFLAG_GET_BLENDMODE(prim.m_flags))); chain->process(prim, view, screen, m_textures, window);
view += chain->applicable_passes(); view += chain->applicable_passes();
} }
@ -381,8 +405,12 @@ void chain_manager::update_screen_count(uint32_t screen_count)
while (m_screen_chains.size() < m_screen_count) while (m_screen_chains.size() < m_screen_count)
{ {
m_screen_chains.push_back(nullptr); m_screen_chains.push_back(nullptr);
m_chain_names.push_back("");
m_current_chain.push_back(CHAIN_NONE); int32_t chain_index = CHAIN_NONE;
std::string chain_name = "";
get_default_chain_info(chain_name, chain_index);
m_chain_names.push_back(chain_name);
m_current_chain.push_back(chain_index);
} }
// Ensure we have a screen chain selection slider per screen // Ensure we have a screen chain selection slider per screen

View File

@ -102,6 +102,7 @@ private:
void init_texture_converters(); void init_texture_converters();
void get_default_chain_info(std::string &out_chain_name, int32_t &out_chain_index);
void refresh_available_chains(); void refresh_available_chains();
void destroy_unloaded_chains(); void destroy_unloaded_chains();
void find_available_chains(std::string root, std::string path); void find_available_chains(std::string root, std::string path);
@ -125,6 +126,7 @@ private:
uint32_t m_window_index; uint32_t m_window_index;
slider_dirty_notifier& m_slider_notifier; slider_dirty_notifier& m_slider_notifier;
uint32_t m_screen_count; uint32_t m_screen_count;
int32_t m_default_chain_index;
std::vector<chain_desc> m_available_chains; std::vector<chain_desc> m_available_chains;
std::vector<bgfx_chain*> m_screen_chains; std::vector<bgfx_chain*> m_screen_chains;
std::vector<std::string> m_chain_names; std::vector<std::string> m_chain_names;

View File

@ -47,7 +47,8 @@ void bgfx_effect::submit(int view, uint64_t blend)
{ {
(uniform_pair.second)->upload(); (uniform_pair.second)->upload();
} }
bgfx::setState(m_state | blend); const uint64_t final_blend = (blend != ~0ULL) ? ((m_state & ~BGFX_STATE_BLEND_MASK) | blend) : m_state;
bgfx::setState(final_blend);
bgfx::submit(view, m_program_handle); bgfx::submit(view, m_program_handle);
} }

View File

@ -25,7 +25,7 @@ public:
bgfx_effect(uint64_t state, bgfx::ShaderHandle vertex_shader, bgfx::ShaderHandle fragment_shader, std::vector<bgfx_uniform*> uniforms); bgfx_effect(uint64_t state, bgfx::ShaderHandle vertex_shader, bgfx::ShaderHandle fragment_shader, std::vector<bgfx_uniform*> uniforms);
~bgfx_effect(); ~bgfx_effect();
void submit(int view, uint64_t blend = 0L); void submit(int view, uint64_t blend = ~0ULL);
bgfx_uniform *uniform(std::string name); bgfx_uniform *uniform(std::string name);
bool is_valid() { return m_program_handle.idx != bgfx::kInvalidHandle; } bool is_valid() { return m_program_handle.idx != bgfx::kInvalidHandle; }

View File

@ -96,7 +96,7 @@ uint64_t bgfx_util::get_blend_state(uint32_t blend)
case BLENDMODE_ALPHA: case BLENDMODE_ALPHA:
return BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA); return BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA);
case BLENDMODE_RGB_MULTIPLY: case BLENDMODE_RGB_MULTIPLY:
return BGFX_STATE_BLEND_FUNC_SEPARATE(BGFX_STATE_BLEND_DST_COLOR, BGFX_STATE_BLEND_ZERO, BGFX_STATE_BLEND_DST_ALPHA, BGFX_STATE_BLEND_ZERO); return BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_DST_COLOR, BGFX_STATE_BLEND_ZERO);
case BLENDMODE_ADD: case BLENDMODE_ADD:
return BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_ONE); return BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_ONE);
default: default: