From 2d893a60b4675359285737be173dfa632269cab3 Mon Sep 17 00:00:00 2001 From: MooglyGuy Date: Mon, 26 Dec 2022 04:40:43 +0100 Subject: [PATCH] -bgfx: Adjusted per-pass blending handling - fixes MT07586 and MT07587. (#10747) [Ryan Holtz] --- bgfx/effects/gui_multiply.json | 4 +- bgfx/effects/misc/blit.json | 8 +- bgfx/effects/misc/blit_alpha.json | 121 +++++++++++++++++++ bgfx/effects/screen_multiply.json | 4 +- src/osd/modules/render/bgfx/blendreader.cpp | 11 +- src/osd/modules/render/bgfx/chain.cpp | 7 +- src/osd/modules/render/bgfx/chainmanager.cpp | 38 +++++- src/osd/modules/render/bgfx/chainmanager.h | 2 + src/osd/modules/render/bgfx/effect.cpp | 3 +- src/osd/modules/render/bgfx/effect.h | 2 +- src/osd/modules/render/bgfxutil.cpp | 2 +- 11 files changed, 177 insertions(+), 25 deletions(-) create mode 100644 bgfx/effects/misc/blit_alpha.json diff --git a/bgfx/effects/gui_multiply.json b/bgfx/effects/gui_multiply.json index 15ac24c91a9..9bd4decdcc8 100644 --- a/bgfx/effects/gui_multiply.json +++ b/bgfx/effects/gui_multiply.json @@ -10,9 +10,7 @@ "blend": { "equation": "add", "srcColor": "dstcolor", - "dstColor": "0", - "srcAlpha": "dstalpha", - "dstAlpha": "0" + "dstColor": "0" }, "depth": { "function": "always" diff --git a/bgfx/effects/misc/blit.json b/bgfx/effects/misc/blit.json index a5e5c544336..85dcba27635 100644 --- a/bgfx/effects/misc/blit.json +++ b/bgfx/effects/misc/blit.json @@ -21,10 +21,10 @@ // 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" + "srcColor": "1", + "dstColor": "0", + "srcAlpha": "1", + "dstAlpha": "0" }, // depth (required): The depth state for this effect. diff --git a/bgfx/effects/misc/blit_alpha.json b/bgfx/effects/misc/blit_alpha.json new file mode 100644 index 00000000000..c8d86a79cff --- /dev/null +++ b/bgfx/effects/misc/blit_alpha.json @@ -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 ] + } + ] +} diff --git a/bgfx/effects/screen_multiply.json b/bgfx/effects/screen_multiply.json index 93bfb90c358..5cd216f11b3 100644 --- a/bgfx/effects/screen_multiply.json +++ b/bgfx/effects/screen_multiply.json @@ -11,9 +11,7 @@ "blend": { "equation": "add", "srcColor": "dstcolor", - "dstColor": "0", - "srcAlpha": "dstalpha", - "dstAlpha": "0" + "dstColor": "0" }, "depth": { "function": "always" diff --git a/src/osd/modules/render/bgfx/blendreader.cpp b/src/osd/modules/render/bgfx/blendreader.cpp index 9e7ddb17ce3..53cd57a9f4a 100644 --- a/src/osd/modules/render/bgfx/blendreader.cpp +++ b/src/osd/modules/render/bgfx/blendreader.cpp @@ -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 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 srcalpha = get_enum_from_value(value, "srcAlpha", BGFX_STATE_BLEND_ONE, FUNCTION_NAMES, FUNCTION_COUNT); - 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); + if (value.HasMember("srcAlpha") && value.HasMember("dstAlpha")) + { + uint64_t srcalpha = get_enum_from_value(value, "srcAlpha", BGFX_STATE_BLEND_ONE, FUNCTION_NAMES, FUNCTION_COUNT); + 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); } diff --git a/src/osd/modules/render/bgfx/chain.cpp b/src/osd/modules/render/bgfx/chain.cpp index b677569a67f..ee32e12f28d 100644 --- a/src/osd/modules/render/bgfx/chain.cpp +++ b/src/osd/modules/render/bgfx/chain.cpp @@ -108,11 +108,12 @@ void bgfx_chain::process(chain_manager::screen_prim &prim, int view, int screen, } 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++; } } diff --git a/src/osd/modules/render/bgfx/chainmanager.cpp b/src/osd/modules/render/bgfx/chainmanager.cpp index 2ae3d9a3daf..719bc61de90 100644 --- a/src/osd/modules/render/bgfx/chainmanager.cpp +++ b/src/osd/modules/render/bgfx/chainmanager.cpp @@ -65,6 +65,7 @@ chain_manager::chain_manager(running_machine& machine, osd_options& options, tex , m_window_index(window_index) , m_slider_notifier(slider_notifier) , m_screen_count(0) + , m_default_chain_index(-1) { m_converters.clear(); 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"); } +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() { 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()); 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(); } @@ -112,8 +137,7 @@ void chain_manager::destroy_unloaded_chains() { delete m_screen_chains[i]; m_screen_chains[i] = nullptr; - m_chain_names[i] = ""; - m_current_chain[i] = CHAIN_NONE; + get_default_chain_info(m_chain_names[i], m_current_chain[i]); 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); - 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(); } @@ -381,8 +405,12 @@ void chain_manager::update_screen_count(uint32_t screen_count) while (m_screen_chains.size() < m_screen_count) { 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 diff --git a/src/osd/modules/render/bgfx/chainmanager.h b/src/osd/modules/render/bgfx/chainmanager.h index 59a65dc59cf..29f06ddaa8d 100644 --- a/src/osd/modules/render/bgfx/chainmanager.h +++ b/src/osd/modules/render/bgfx/chainmanager.h @@ -102,6 +102,7 @@ private: void init_texture_converters(); + void get_default_chain_info(std::string &out_chain_name, int32_t &out_chain_index); void refresh_available_chains(); void destroy_unloaded_chains(); void find_available_chains(std::string root, std::string path); @@ -125,6 +126,7 @@ private: uint32_t m_window_index; slider_dirty_notifier& m_slider_notifier; uint32_t m_screen_count; + int32_t m_default_chain_index; std::vector m_available_chains; std::vector m_screen_chains; std::vector m_chain_names; diff --git a/src/osd/modules/render/bgfx/effect.cpp b/src/osd/modules/render/bgfx/effect.cpp index c5ea8555dce..5891bfe0789 100644 --- a/src/osd/modules/render/bgfx/effect.cpp +++ b/src/osd/modules/render/bgfx/effect.cpp @@ -47,7 +47,8 @@ void bgfx_effect::submit(int view, uint64_t blend) { (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); } diff --git a/src/osd/modules/render/bgfx/effect.h b/src/osd/modules/render/bgfx/effect.h index ca1be77c73d..6bceaedffd5 100644 --- a/src/osd/modules/render/bgfx/effect.h +++ b/src/osd/modules/render/bgfx/effect.h @@ -25,7 +25,7 @@ public: bgfx_effect(uint64_t state, bgfx::ShaderHandle vertex_shader, bgfx::ShaderHandle fragment_shader, std::vector uniforms); ~bgfx_effect(); - void submit(int view, uint64_t blend = 0L); + void submit(int view, uint64_t blend = ~0ULL); bgfx_uniform *uniform(std::string name); bool is_valid() { return m_program_handle.idx != bgfx::kInvalidHandle; } diff --git a/src/osd/modules/render/bgfxutil.cpp b/src/osd/modules/render/bgfxutil.cpp index e864cb98fb4..9381f2fb04e 100644 --- a/src/osd/modules/render/bgfxutil.cpp +++ b/src/osd/modules/render/bgfxutil.cpp @@ -96,7 +96,7 @@ uint64_t bgfx_util::get_blend_state(uint32_t blend) case BLENDMODE_ALPHA: return BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA); 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: return BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_ONE); default: