diff --git a/bgfx/chains/test.json b/bgfx/chains/test.json index e05cee4df3e..ddd12df8ff7 100644 --- a/bgfx/chains/test.json +++ b/bgfx/chains/test.json @@ -1,7 +1,7 @@ { "name": "Test Shader Chain", "author": "Ryan Holtz", "sliders": [ - { "type": "int_enum", "name": "adjustments", "text": "Enable Adjustments", "default": 0, "max": 1, "min": 0, "step": 1, "scale": 1.0, "format": "%s", "screen": "any", "strings": [ "On", "Off" ] }, + { "type": "int_enum", "name": "adjustments", "text": "Enable Adjustments", "default": 0, "max": 1, "min": 0, "step": 1, "scale": 1.0, "format": "%s", "screen": "any", "strings": [ "Off", "On" ] }, { "type": "float", "name": "ratio_amount", "text": "Ratio Amount", "default": 0, "max": 100, "min": 0, "step": 1, "scale": 0.01, "format": "%1.2f", "screen": "any" }, { "type": "color", "name": "red_ratios", "text": "Color Matrix, Red from ", "default": [ 200, 0, 0 ], "max": [ 400, 400, 400 ], "min": [ 0, 0, 0 ], "step": 1, "scale": 0.005, "format": "%2.3f", "screen": "any" }, { "type": "color", "name": "grn_ratios", "text": "Color Matrix, Green from ", "default": [ 0, 200, 0 ], "max": [ 400, 400, 400 ], "min": [ 0, 0, 0 ], "step": 1, "scale": 0.005, "format": "%2.3f", "screen": "any" }, @@ -21,15 +21,16 @@ }, { "name": "previous", "mode": "native", - "prescale": 1 + "prescale": 1, + "doublebuffer": true } ], "passes": [ { "effect": "ratios", "name": "Matrix Pass", - "disable_conditions": [ - { "type": "slider", "name": "adjustments", "value": 0 }, - { "type": "slider", "name": "ratio_amount", "value": 0.0 } + "disablewhen": [ + { "type": "slider", "condition": "equal", "name": "adjustments", "value": 0 }, + { "type": "slider", "condition": "equal", "name": "ratio_amount", "value": 0 } ], "uniforms": [ { "uniform": "u_ratio_amount", "slider": "ratio_amount" }, @@ -42,10 +43,21 @@ ], "output": "native" }, + { "effect": "blit", + "name": "Matrix Skip", + "disablewhen": [ + { "type": "slider", "condition": "equal", "name": "adjustments", "value": 0 }, + { "type": "slider", "condition": "notequal", "name": "ratio_amount", "value": 0 } + ], + "input": [ + { "sampler": "s_tex", "texture": "screen" } + ], + "output": "native" + }, { "effect": "tint", "name": "Tint Pass", - "disable_conditions": [ - { "type": "slider", "name": "adjustments", "value": 0 } + "disablewhen": [ + { "type": "slider", "condition": "equal", "name": "adjustments", "value": 0 } ], "uniforms": [ { "uniform": "u_tint", "slider": "tint" }, @@ -58,9 +70,9 @@ }, { "effect": "phosphor", "name": "Phosphor Decay", - "disable_conditions": [ - { "type": "slider", "name": "adjustments", "value": false }, - { "type": "slider", "name": "phosphor", "value": [ 0, 0, 0 ] } + "disablewhen": [ + { "type": "slider", "condition": "equal", "name": "adjustments", "value": 0 }, + { "type": "slider", "condition": "equal", "name": "phosphor", "value": [ 0, 0, 0 ] } ], "uniforms": [ { "uniform": "u_passthrough", "value": [ 0 ] }, @@ -74,9 +86,9 @@ }, { "effect": "phosphor", "name": "Phosphor Store", - "disable_conditions": [ - { "type": "slider", "name": "adjustments", "value": false }, - { "type": "slider", "name": "phosphor", "value": [ 0, 0, 0 ] } + "disablewhen": [ + { "type": "slider", "condition": "equal", "name": "adjustments", "value": 0 }, + { "type": "slider", "condition": "equal", "name": "phosphor", "value": [ 0, 0, 0 ] } ], "uniforms": [ { "uniform": "u_passthrough", "value": [ 1 ] }, @@ -89,11 +101,15 @@ "output": "previous" }, { "effect": "blit", - "name": "Final Blit", - "input": [ - { "sampler": "s_tex", "texture": "native" } + "name": "Total Skip", + "disablewhen": [ + { "type": "slider", "condition": "notequal", "name": "adjustments", "value": 0 } ], - "output": "backbuffer" + "input": [ + { "sampler": "s_tex", "texture": "screen" } + ], + "output": "native" } - ] + ], + "output": "native" } \ No newline at end of file diff --git a/bgfx/effects/screen_opaque.json b/bgfx/effects/screen_opaque.json index e3ac55387c3..f03f1943404 100644 --- a/bgfx/effects/screen_opaque.json +++ b/bgfx/effects/screen_opaque.json @@ -17,7 +17,6 @@ "vertex": "vs_screen", "fragment": "fs_screen", "uniforms": [ - { "name": "s_tex", "type": "int", "values": [ 1.0 ] }, - { "name": "u_tint", "type": "vec4", "values": [ 1.0, 1.0, 1.0, 1.0 ] } + { "name": "s_tex", "type": "int", "values": [ 1.0 ] } ] } \ No newline at end of file diff --git a/scripts/src/osd/modules.lua b/scripts/src/osd/modules.lua index d8cc99966c1..85d8468be90 100644 --- a/scripts/src/osd/modules.lua +++ b/scripts/src/osd/modules.lua @@ -140,6 +140,8 @@ function osdmodulesbuild() MAME_DIR .. "src/osd/modules/render/bgfx/slideruniform.cpp", MAME_DIR .. "src/osd/modules/render/bgfx/slideruniformreader.cpp", MAME_DIR .. "src/osd/modules/render/bgfx/statereader.cpp", + MAME_DIR .. "src/osd/modules/render/bgfx/suppressor.cpp", + MAME_DIR .. "src/osd/modules/render/bgfx/suppressorreader.cpp", MAME_DIR .. "src/osd/modules/render/bgfx/target.cpp", MAME_DIR .. "src/osd/modules/render/bgfx/targetmanager.cpp", MAME_DIR .. "src/osd/modules/render/bgfx/texture.cpp", diff --git a/shaders/dx11/fs_screen.bin b/shaders/dx11/fs_screen.bin index 802d22a89ff..80d85fb1107 100644 Binary files a/shaders/dx11/fs_screen.bin and b/shaders/dx11/fs_screen.bin differ diff --git a/shaders/dx9/fs_screen.bin b/shaders/dx9/fs_screen.bin index cd32f845f00..ee2b018cae8 100644 Binary files a/shaders/dx9/fs_screen.bin and b/shaders/dx9/fs_screen.bin differ diff --git a/shaders/gles/fs_screen.bin b/shaders/gles/fs_screen.bin index e61cd98570a..22e2f0c23d0 100644 Binary files a/shaders/gles/fs_screen.bin and b/shaders/gles/fs_screen.bin differ diff --git a/shaders/glsl/fs_screen.bin b/shaders/glsl/fs_screen.bin index 2dd75acfc5e..db0fe2b487b 100644 Binary files a/shaders/glsl/fs_screen.bin and b/shaders/glsl/fs_screen.bin differ diff --git a/shaders/metal/fs_screen.bin b/shaders/metal/fs_screen.bin index c0c34d2553f..6a3da392480 100644 Binary files a/shaders/metal/fs_screen.bin and b/shaders/metal/fs_screen.bin differ diff --git a/src/osd/modules/render/bgfx/chain.cpp b/src/osd/modules/render/bgfx/chain.cpp index a0fbdc56686..4534dbbf9f9 100644 --- a/src/osd/modules/render/bgfx/chain.cpp +++ b/src/osd/modules/render/bgfx/chain.cpp @@ -10,19 +10,19 @@ #include "slider.h" #include "parameter.h" -#include "chainentry.h" #include "entryuniform.h" #include "texturemanager.h" #include "vertex.h" #include "chain.h" -bgfx_chain::bgfx_chain(std::string name, std::string author, std::vector sliders, std::vector params, std::vector entries) +bgfx_chain::bgfx_chain(std::string name, std::string author, std::vector sliders, std::vector params, std::vector entries, std::string output) : m_name(name) , m_author(author) , m_sliders(sliders) , m_params(params) , m_entries(entries) + , m_output(output) { for (bgfx_slider* slider : m_sliders) { @@ -48,17 +48,27 @@ bgfx_chain::~bgfx_chain() void bgfx_chain::process(render_primitive* prim, int view, texture_manager& textures, uint16_t screen_width, uint16_t screen_height, uint64_t blend) { + int current_view = view; for (int index = 0; index < m_entries.size(); index++) { - if (index == (m_entries.size() - 1)) + if (!m_entries[index]->skip()) { - view = 0; + m_entries[index]->submit(prim, current_view, textures, screen_width, screen_height, blend); + current_view++; } - else - { - view = 1 + index; - } - - m_entries[index]->submit(prim, view, textures, screen_width, screen_height, blend); } } + +uint32_t bgfx_chain::applicable_passes() +{ + int applicable_passes = 0; + for (int index = 0; index < m_entries.size(); index++) + { + if (!m_entries[index]->skip()) + { + applicable_passes++; + } + } + + return applicable_passes; +} \ No newline at end of file diff --git a/src/osd/modules/render/bgfx/chain.h b/src/osd/modules/render/bgfx/chain.h index 6993a56ea10..aa5187e3a74 100644 --- a/src/osd/modules/render/bgfx/chain.h +++ b/src/osd/modules/render/bgfx/chain.h @@ -15,28 +15,34 @@ #include #include +#include "chainentry.h" + class render_primitive; class bgfx_slider; class bgfx_parameter; -class bgfx_chain_entry; class texture_manager; class bgfx_chain { public: - bgfx_chain(std::string name, std::string author, std::vector sliders, std::vector params, std::vector entries); + bgfx_chain(std::string name, std::string author, std::vector sliders, std::vector params, std::vector entries, std::string output); ~bgfx_chain(); void process(render_primitive* prim, int view, texture_manager& textures, uint16_t screen_width, uint16_t screen_height, uint64_t blend = 0L); + + // Getters std::vector& sliders() { return m_sliders; } + std::string output() const { return m_output; } + uint32_t applicable_passes(); private: - std::string m_name; - std::string m_author; - std::vector m_sliders; - std::vector m_params; - std::vector m_entries; + std::string m_name; + std::string m_author; + std::vector m_sliders; + std::vector m_params; + std::vector m_entries; std::map m_slider_map; + std::string m_output; }; #endif // __DRAWBGFX_CHAIN__ diff --git a/src/osd/modules/render/bgfx/chainentry.cpp b/src/osd/modules/render/bgfx/chainentry.cpp index ea25897f294..3a9d4248691 100644 --- a/src/osd/modules/render/bgfx/chainentry.cpp +++ b/src/osd/modules/render/bgfx/chainentry.cpp @@ -22,20 +22,16 @@ #include "entryuniform.h" #include "texturemanager.h" #include "vertex.h" +#include "suppressor.h" -bgfx_chain_entry::bgfx_chain_entry(std::string name, bgfx_effect* effect, std::vector& inputs, std::vector uniforms, bgfx_target* output) +bgfx_chain_entry::bgfx_chain_entry(std::string name, bgfx_effect* effect, std::vector suppressors, std::vector inputs, std::vector uniforms, bgfx_target* output) : m_name(name) , m_effect(effect) + , m_inputs(inputs) + , m_suppressors(suppressors) , m_output(output) + , m_uniforms(uniforms) { - for (bgfx_input_pair input : inputs) - { - m_inputs.push_back(input); - } - for (bgfx_entry_uniform* uniform : uniforms) - { - m_uniforms.push_back(uniform); - } } bgfx_chain_entry::~bgfx_chain_entry() @@ -53,7 +49,8 @@ void bgfx_chain_entry::submit(render_primitive* prim, int view, texture_manager& setup_view(view, screen_width, screen_height); - for (bgfx_input_pair input : m_inputs) { + for (bgfx_input_pair input : m_inputs) + { input.bind(m_effect, textures); } @@ -89,23 +86,24 @@ void bgfx_chain_entry::setup_view(int view, uint16_t screen_width, uint16_t scre bgfx::setViewFrameBuffer(view, handle); bgfx::setViewRect(view, 0, 0, width, height); - { - float viewMat[16]; - bx::mtxIdentity(viewMat); + float viewMat[16]; + bx::mtxIdentity(viewMat); - float projMat[16]; - bx::mtxOrtho(projMat, 0.0f, width, height, 0.0f, 0.0f, 100.0f); - bgfx::setViewTransform(view, viewMat, projMat); - } + float projMat[16]; + bx::mtxOrtho(projMat, 0.0f, width, height, 0.0f, 0.0f, 100.0f); + bgfx::setViewTransform(view, viewMat, projMat); bgfx::setViewClear(view, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x000000ff, 1.0f, 0); } void bgfx_chain_entry::put_screen_buffer(render_primitive* prim, bgfx::TransientVertexBuffer* buffer) { - if (bgfx::checkAvailTransientVertexBuffer(6, ScreenVertex::ms_decl)) { + if (bgfx::checkAvailTransientVertexBuffer(6, ScreenVertex::ms_decl)) + { bgfx::allocTransientVertexBuffer(buffer, 6, ScreenVertex::ms_decl); - } else { + } + else + { return; } @@ -152,4 +150,22 @@ void bgfx_chain_entry::put_screen_buffer(render_primitive* prim, bgfx::Transient vertex[5].m_rgba = 0xffffffff; vertex[5].m_u = prim->texcoords.tl.u; vertex[5].m_v = prim->texcoords.tl.v; +} + +bool bgfx_chain_entry::skip() +{ + if (m_suppressors.size() == 0) + { + return false; + } + + for (bgfx_suppressor* suppressor : m_suppressors) + { + if (suppressor->suppress()) + { + return true; + } + } + + return false; } \ No newline at end of file diff --git a/src/osd/modules/render/bgfx/chainentry.h b/src/osd/modules/render/bgfx/chainentry.h index a6ab71aae35..f9ed1aa6358 100644 --- a/src/osd/modules/render/bgfx/chainentry.h +++ b/src/osd/modules/render/bgfx/chainentry.h @@ -25,18 +25,21 @@ class render_primitive; class bgfx_effect; class bgfx_target; class bgfx_entry_uniform; +class bgfx_suppressor; class texture_manager; class bgfx_chain_entry { public: - bgfx_chain_entry(std::string name, bgfx_effect* effect, std::vector& inputs, std::vector uniforms, bgfx_target* output); + bgfx_chain_entry(std::string name, bgfx_effect* effect, std::vector suppressors, std::vector inputs, std::vector uniforms, bgfx_target* output); ~bgfx_chain_entry(); void submit(render_primitive* prim, int view, texture_manager& textures, uint16_t screen_width, uint16_t screen_height, uint64_t blend); // Getters std::string name() const { return m_name; } + bgfx_target* target() const { return m_output; } + bool skip(); private: void setup_view(int view, uint16_t screen_width, uint16_t screen_height); @@ -44,7 +47,8 @@ private: std::string m_name; bgfx_effect* m_effect; - std::vector m_inputs; + std::vector m_suppressors; + std::vector m_inputs; std::vector m_uniforms; bgfx_target* m_output; }; diff --git a/src/osd/modules/render/bgfx/chainentryreader.cpp b/src/osd/modules/render/bgfx/chainentryreader.cpp index 4bb3b1737f2..1f856ec2d8c 100644 --- a/src/osd/modules/render/bgfx/chainentryreader.cpp +++ b/src/osd/modules/render/bgfx/chainentryreader.cpp @@ -16,10 +16,12 @@ #include "targetmanager.h" #include "effectmanager.h" #include "chainentry.h" -#include "entryuniform.h" #include "slider.h" #include "inputpair.h" +#include "entryuniform.h" #include "entryuniformreader.h" +#include "suppressor.h" +#include "suppressorreader.h" bgfx_chain_entry* chain_entry_reader::read_from_value(const Value& value, texture_manager& textures, target_manager& targets, effect_manager& effects, std::map& sliders) { @@ -30,6 +32,7 @@ bgfx_chain_entry* chain_entry_reader::read_from_value(const Value& value, textur std::vector inputs; if (value.HasMember("input")) { + assert(value["input"].IsArray()); const Value& input_array = value["input"]; for (UINT32 i = 0; i < input_array.Size(); i++) { @@ -42,6 +45,7 @@ bgfx_chain_entry* chain_entry_reader::read_from_value(const Value& value, textur std::vector uniforms; if (value.HasMember("uniforms")) { + assert(value["uniforms"].IsArray()); const Value& uniform_array = value["uniforms"]; for (UINT32 i = 0; i < uniform_array.Size(); i++) { @@ -49,14 +53,25 @@ bgfx_chain_entry* chain_entry_reader::read_from_value(const Value& value, textur } } + std::vector suppressors; + if (value.HasMember("disablewhen")) + { + assert(value["disablewhen"].IsArray()); + const Value& suppressor_array = value["disablewhen"]; + for (UINT32 i = 0; i < suppressor_array.Size(); i++) + { + suppressors.push_back(suppressor_reader::read_from_value(suppressor_array[i], sliders)); + } + } + std::string output_name = value["output"].GetString(); if (output_name != std::string("backbuffer")) { - return new bgfx_chain_entry(value["name"].GetString(), effect, inputs, uniforms, targets.target(output_name)); + return new bgfx_chain_entry(value["name"].GetString(), effect, suppressors, inputs, uniforms, targets.target(output_name)); } else { - return new bgfx_chain_entry(value["name"].GetString(), effect, inputs, uniforms, nullptr); + return new bgfx_chain_entry(value["name"].GetString(), effect, suppressors, inputs, uniforms, nullptr); } } diff --git a/src/osd/modules/render/bgfx/chainmanager.cpp b/src/osd/modules/render/bgfx/chainmanager.cpp index 769c429845d..09383ae08ad 100644 --- a/src/osd/modules/render/bgfx/chainmanager.cpp +++ b/src/osd/modules/render/bgfx/chainmanager.cpp @@ -42,7 +42,8 @@ bgfx_chain* chain_manager::chain(std::string name, running_machine& machine) return load_chain(name, machine); } -bgfx_chain* chain_manager::load_chain(std::string name, running_machine& machine) { +bgfx_chain* chain_manager::load_chain(std::string name, running_machine& machine) +{ std::string path = "bgfx/chains/" + name + ".json"; bx::CrtFileReader reader; diff --git a/src/osd/modules/render/bgfx/chainreader.cpp b/src/osd/modules/render/bgfx/chainreader.cpp index 19e476ccb03..00eb77eaa59 100644 --- a/src/osd/modules/render/bgfx/chainreader.cpp +++ b/src/osd/modules/render/bgfx/chainreader.cpp @@ -71,6 +71,7 @@ bgfx_chain* chain_reader::read_from_value(const Value& value, running_machine& m if (value.HasMember("targets")) { const Value& target_array = value["targets"]; + // TODO: Move into its own reader for (UINT32 i = 0; i < target_array.Size(); i++) { assert(target_array[i].HasMember("name")); @@ -115,14 +116,18 @@ bgfx_chain* chain_reader::read_from_value(const Value& value, running_machine& m // Parse chain entries std::vector entries; - if (value.HasMember("passes")) { + if (value.HasMember("passes")) + { const Value& entry_array = value["passes"]; - for (UINT32 i = 0; i < entry_array.Size(); i++) { + for (UINT32 i = 0; i < entry_array.Size(); i++) + { entries.push_back(chain_entry_reader::read_from_value(entry_array[i], textures, targets, effects, slider_map)); } } - return new bgfx_chain(name, author, sliders, parameters, entries); + std::string output = value["output"].GetString(); + + return new bgfx_chain(name, author, sliders, parameters, entries, output); } void chain_reader::validate_parameters(const Value& value) @@ -132,4 +137,7 @@ void chain_reader::validate_parameters(const Value& value) assert(value.HasMember("author")); assert(value["author"].IsString()); assert(value.HasMember("passes")); + assert(value["passes"].IsArray()); + assert(value.HasMember("output")); + assert(value["output"].IsString()); } diff --git a/src/osd/modules/render/bgfx/effect.h b/src/osd/modules/render/bgfx/effect.h index b44b6a8fb72..80fd6fc454f 100644 --- a/src/osd/modules/render/bgfx/effect.h +++ b/src/osd/modules/render/bgfx/effect.h @@ -2,7 +2,7 @@ // copyright-holders:Ryan Holtz //============================================================ // -// vertex.h - BGFX screen vertex data +// effect.cpp - BGFX shader material to be applied to a mesh // //============================================================ diff --git a/src/osd/modules/render/bgfx/effectmanager.cpp b/src/osd/modules/render/bgfx/effectmanager.cpp index c7410406f13..ed10e600a42 100644 --- a/src/osd/modules/render/bgfx/effectmanager.cpp +++ b/src/osd/modules/render/bgfx/effectmanager.cpp @@ -44,7 +44,8 @@ bgfx_effect* effect_manager::effect(std::string name) return load_effect(name); } -bgfx_effect* effect_manager::load_effect(std::string name) { +bgfx_effect* effect_manager::load_effect(std::string name) +{ std::string path = "bgfx/effects/" + name + ".json"; bx::CrtFileReader reader; diff --git a/src/osd/modules/render/bgfx/fs_screen.sc b/src/osd/modules/render/bgfx/fs_screen.sc index 59c2916039e..0d3539f2be8 100644 --- a/src/osd/modules/render/bgfx/fs_screen.sc +++ b/src/osd/modules/render/bgfx/fs_screen.sc @@ -7,10 +7,7 @@ $input v_color0, v_texcoord0 SAMPLER2D(s_tex, 0); -uniform vec4 u_tint; - void main() { - vec4 texel = texture2D(s_tex, v_texcoord0); - gl_FragColor = texel * v_color0 * u_tint; + gl_FragColor = texture2D(s_tex, v_texcoord0) * v_color0; } diff --git a/src/osd/modules/render/bgfx/shadermanager.cpp b/src/osd/modules/render/bgfx/shadermanager.cpp index 93a7205b93c..9a277a2aeae 100644 --- a/src/osd/modules/render/bgfx/shadermanager.cpp +++ b/src/osd/modules/render/bgfx/shadermanager.cpp @@ -39,29 +39,30 @@ bgfx::ShaderHandle shader_manager::shader(std::string name) return load_shader(name); } -bgfx::ShaderHandle shader_manager::load_shader(std::string name) { +bgfx::ShaderHandle shader_manager::load_shader(std::string name) +{ std::string shader_path = "shaders/dx9/"; switch (bgfx::getRendererType()) { - case bgfx::RendererType::Direct3D11: - case bgfx::RendererType::Direct3D12: - shader_path = "shaders/dx11/"; - break; + case bgfx::RendererType::Direct3D11: + case bgfx::RendererType::Direct3D12: + shader_path = "shaders/dx11/"; + break; - case bgfx::RendererType::OpenGL: - shader_path = "shaders/glsl/"; - break; + case bgfx::RendererType::OpenGL: + shader_path = "shaders/glsl/"; + break; - case bgfx::RendererType::Metal: - shader_path = "shaders/metal/"; - break; + case bgfx::RendererType::Metal: + shader_path = "shaders/metal/"; + break; - case bgfx::RendererType::OpenGLES: - shader_path = "shaders/gles/"; - break; + case bgfx::RendererType::OpenGLES: + shader_path = "shaders/gles/"; + break; - default: - break; + default: + break; } bgfx::ShaderHandle handle = bgfx::createShader(load_mem(shader_path + name + ".bin")); @@ -71,7 +72,8 @@ bgfx::ShaderHandle shader_manager::load_shader(std::string name) { return handle; } -const bgfx::Memory* shader_manager::load_mem(std::string name) { +const bgfx::Memory* shader_manager::load_mem(std::string name) +{ bx::CrtFileReader reader; bx::open(&reader, name.c_str()); diff --git a/src/osd/modules/render/bgfx/slider.cpp b/src/osd/modules/render/bgfx/slider.cpp index 4fac9bd4849..b5dbdfe80ef 100644 --- a/src/osd/modules/render/bgfx/slider.cpp +++ b/src/osd/modules/render/bgfx/slider.cpp @@ -43,8 +43,10 @@ bgfx_slider::~bgfx_slider() { } -static INT32 update_trampoline(running_machine &machine, void *arg, std::string *str, INT32 newval) { - if (arg != nullptr) { +static INT32 update_trampoline(running_machine &machine, void *arg, std::string *str, INT32 newval) +{ + if (arg != nullptr) + { return reinterpret_cast(arg)->update(str, newval); } return 0; @@ -64,20 +66,23 @@ slider_state* bgfx_slider::create_core_slider(running_machine& machine) state->hidden = false; state->id = 0; // fixme strcpy(state->description, m_description.c_str()); - + return state; } int32_t bgfx_slider::update(std::string *str, int32_t newval) { - switch (m_type) { + switch (m_type) + { case SLIDER_INT_ENUM: { INT32 *val_ptr = reinterpret_cast(&m_value); - if (newval != SLIDER_NOCHANGE) { + if (newval != SLIDER_NOCHANGE) + { *val_ptr = newval; } - if (str != nullptr) { + if (str != nullptr) + { *str = string_format(m_format, m_strings[*val_ptr]); } return *val_ptr; @@ -86,10 +91,12 @@ int32_t bgfx_slider::update(std::string *str, int32_t newval) case SLIDER_INT: { int *val_ptr = reinterpret_cast(&m_value); - if (newval != SLIDER_NOCHANGE) { + if (newval != SLIDER_NOCHANGE) + { *val_ptr = newval; } - if (str != nullptr) { + if (str != nullptr) + { *str = string_format(m_format, *val_ptr); } return *val_ptr; @@ -102,7 +109,8 @@ int32_t bgfx_slider::update(std::string *str, int32_t newval) { *val_ptr = float(newval) * m_scale; } - if (str != nullptr) { + if (str != nullptr) + { *str = string_format(m_format, *val_ptr); } return int32_t(floor(*val_ptr / m_scale + 0.5f)); @@ -110,3 +118,20 @@ int32_t bgfx_slider::update(std::string *str, int32_t newval) } return 0; } + +size_t bgfx_slider::get_size_for_type(slider_type type) +{ + switch(type) + { + case SLIDER_INT_ENUM: + case SLIDER_FLOAT: + case SLIDER_INT: + return sizeof(float); + case SLIDER_COLOR: + return sizeof(float) * 3; + case SLIDER_VEC2: + return sizeof(float) * 2; + default: + return 0; + } +} diff --git a/src/osd/modules/render/bgfx/slider.h b/src/osd/modules/render/bgfx/slider.h index d88bb8ffde0..62929bd5fe1 100644 --- a/src/osd/modules/render/bgfx/slider.h +++ b/src/osd/modules/render/bgfx/slider.h @@ -54,6 +54,9 @@ public: int32_t value() const { return m_value; } float uniform_value() const { return *(reinterpret_cast(&m_value)); } slider_state* core_slider() const { return m_slider_state; } + size_t size() const { return get_size_for_type(m_type); } + + static size_t get_size_for_type(slider_type type); protected: slider_state* create_core_slider(running_machine &machine); diff --git a/src/osd/modules/render/bgfx/statereader.cpp b/src/osd/modules/render/bgfx/statereader.cpp index 6c0f707ae31..0f5c0a2f88c 100644 --- a/src/osd/modules/render/bgfx/statereader.cpp +++ b/src/osd/modules/render/bgfx/statereader.cpp @@ -46,8 +46,10 @@ void state_reader::validate_float_parameter(const Value& value, std::string type } } -void state_reader::validate_int_parameter(const Value& value, std::string typeName, std::string name) { - if (value.HasMember(name.c_str())) { +void state_reader::validate_int_parameter(const Value& value, std::string typeName, std::string name) +{ + if (value.HasMember(name.c_str())) + { assert(value[name.c_str()].IsInt()); } } @@ -77,8 +79,10 @@ bool state_reader::get_bool(const Value& value, const std::string name, const bo return default_value; } -int state_reader::get_int(const Value& value, const std::string name, const int default_value) { - if (value.HasMember(name.c_str())) { +int state_reader::get_int(const Value& value, const std::string name, const int default_value) +{ + if (value.HasMember(name.c_str())) + { return int(floor(value[name.c_str()].GetDouble() + 0.5)); } return default_value; diff --git a/src/osd/modules/render/bgfx/suppressor.cpp b/src/osd/modules/render/bgfx/suppressor.cpp new file mode 100644 index 00000000000..eec0efb6440 --- /dev/null +++ b/src/osd/modules/render/bgfx/suppressor.cpp @@ -0,0 +1,56 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +//============================================================ +// +// suppressor.h - Conditionally suppress a bgfx chain entry +// from being processed. +// +//============================================================ + +#include "suppressor.h" + +#include "slider.h" + +bgfx_suppressor::bgfx_suppressor(std::vector sliders, uint32_t condition, void* value) + : m_sliders(sliders) + , m_condition(condition) + , m_value(nullptr) +{ + uint32_t size = sliders[0]->size(); + m_value = new uint8_t[size]; + memcpy(m_value, value, size); +} + +bgfx_suppressor::~bgfx_suppressor() +{ + delete [] m_value; +} + +bool bgfx_suppressor::suppress() +{ + int32_t count = 1; + if (m_sliders[0]->type() == bgfx_slider::slider_type::SLIDER_VEC2) + { + count = 2; + } + else if (m_sliders[0]->type() == bgfx_slider::slider_type::SLIDER_COLOR) + { + count = 3; + } + + int32_t current_values[3]; + for (int32_t index = 0; index < count; index++) + { + current_values[index] = m_sliders[index]->value(); + } + + switch (m_condition) + { + case CONDITION_NOTEQUAL: + return memcmp(m_value, current_values, m_sliders[0]->size()) != 0; + case CONDITION_EQUAL: + return memcmp(m_value, current_values, m_sliders[0]->size()) == 0; + default: + return false; + } +} diff --git a/src/osd/modules/render/bgfx/suppressor.h b/src/osd/modules/render/bgfx/suppressor.h new file mode 100644 index 00000000000..a371ed4e9fa --- /dev/null +++ b/src/osd/modules/render/bgfx/suppressor.h @@ -0,0 +1,41 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +//============================================================ +// +// suppressor.h - Conditionally suppress a bgfx chain entry +// from being processed. +// +//============================================================ + +#pragma once + +#ifndef __DRAWBGFX_SUPPRESSOR__ +#define __DRAWBGFX_SUPPRESSOR__ + +#include + +class bgfx_slider; + +class bgfx_suppressor +{ +public: + enum condition_type + { + CONDITION_EQUAL, + CONDITION_NOTEQUAL, + + CONDITION_COUNT + }; + + bgfx_suppressor(std::vector sliders, uint32_t condition, void* value); + ~bgfx_suppressor(); + + bool suppress(); + +private: + std::vector m_sliders; + uint32_t m_condition; + void* m_value; +}; + +#endif // __DRAWBGFX_SUPPRESSOR__ diff --git a/src/osd/modules/render/bgfx/suppressorreader.cpp b/src/osd/modules/render/bgfx/suppressorreader.cpp new file mode 100644 index 00000000000..daa3a55c7c6 --- /dev/null +++ b/src/osd/modules/render/bgfx/suppressorreader.cpp @@ -0,0 +1,89 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +//============================================================ +// +// suppressorreader.cpp - Reads pass-skipping conditions +// +//============================================================ + +#include + +#include "suppressorreader.h" + +#include "suppressor.h" +#include "slider.h" + +const suppressor_reader::string_to_enum suppressor_reader::CONDITION_NAMES[suppressor_reader::CONDITION_COUNT] = { + { "equal", bgfx_suppressor::condition_type::CONDITION_EQUAL }, + { "notequal", bgfx_suppressor::condition_type::CONDITION_NOTEQUAL } +}; + +bgfx_suppressor* suppressor_reader::read_from_value(const Value& value, std::map& sliders) +{ + validate_parameters(value); + + std::string name = value["name"].GetString(); + uint32_t condition = uint32_t(get_enum_from_value(value, "condition", bgfx_suppressor::condition_type::CONDITION_EQUAL, CONDITION_NAMES, CONDITION_COUNT)); + + std::vector check_sliders; + check_sliders.push_back(sliders[name + "0"]); + + int slider_count; + switch (check_sliders[0]->type()) + { + case bgfx_slider::slider_type::SLIDER_FLOAT: + case bgfx_slider::slider_type::SLIDER_INT: + case bgfx_slider::slider_type::SLIDER_INT_ENUM: + slider_count = 1; + break; + case bgfx_slider::slider_type::SLIDER_VEC2: + slider_count = 2; + break; + case bgfx_slider::slider_type::SLIDER_COLOR: + slider_count = 3; + break; + default: + slider_count = 0; + break; + } + + int values[4]; + if (slider_count > 1) + { + get_values(value, "value", values, slider_count); + for (int index = 0; index < slider_count; index++) + { + std::string desc; + char full_name[1024]; // arbitrary + snprintf(full_name, 1024, "%s%d", name.c_str(), index); + check_sliders.push_back(sliders[std::string(full_name)]); + } + } + else + { + values[0] = get_int(value, "value", 0); + } + + return new bgfx_suppressor(check_sliders, condition, values); +} + +void suppressor_reader::validate_parameters(const Value& value) +{ + assert(value.HasMember("name")); + assert(value["name"].IsString()); + assert(value.HasMember("value")); + assert(value["value"].IsNumber() || value["value"].IsArray()); +} + +void suppressor_reader::get_values(const Value& value, std::string name, int* values, const int count) +{ + const char* name_str = name.c_str(); + assert(value.HasMember(name_str)); + assert(value[name_str].IsArray()); + + const Value& value_array = value[name_str]; + for (UINT32 i = 0; i < value_array.Size() && i < count; i++) + { + values[i] = value_array[i].GetInt(); + } +} diff --git a/src/osd/modules/render/bgfx/suppressorreader.h b/src/osd/modules/render/bgfx/suppressorreader.h new file mode 100644 index 00000000000..ea0e86304b0 --- /dev/null +++ b/src/osd/modules/render/bgfx/suppressorreader.h @@ -0,0 +1,36 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +//============================================================ +// +// suppressorreader.h - Reads pass-skipping conditions +// +//============================================================ + +#pragma once + +#ifndef __DRAWBGFX_SUPPRESSOR_READER__ +#define __DRAWBGFX_SUPPRESSOR_READER__ + +#include "statereader.h" + +#include +#include + +class bgfx_suppressor; +class bgfx_slider; + +class suppressor_reader : public state_reader +{ +public: + static bgfx_suppressor* read_from_value(const Value& value, std::map& sliders); + +private: + static void get_values(const Value& value, std::string name, int* values, const int count); + + static void validate_parameters(const Value& value); + + static const int CONDITION_COUNT = 2; + static const string_to_enum CONDITION_NAMES[CONDITION_COUNT]; +}; + +#endif // __DRAWBGFX_SUPPRESSOR_READER__ diff --git a/src/osd/modules/render/bgfx/uniformreader.cpp b/src/osd/modules/render/bgfx/uniformreader.cpp index 141bc657121..8c60113d364 100644 --- a/src/osd/modules/render/bgfx/uniformreader.cpp +++ b/src/osd/modules/render/bgfx/uniformreader.cpp @@ -41,7 +41,8 @@ bgfx_uniform* uniform_reader::read_from_value(const Value& value) data[index] = (float)value_array[index].GetDouble(); } - for (; index < type_size / 4; index++) { + for (; index < type_size / 4; index++) + { data[index] = 0.0f; } diff --git a/src/osd/modules/render/bgfx/vertex.h b/src/osd/modules/render/bgfx/vertex.h index 2e0eb9e01dc..30c38400f93 100644 --- a/src/osd/modules/render/bgfx/vertex.h +++ b/src/osd/modules/render/bgfx/vertex.h @@ -13,7 +13,8 @@ #include -struct ScreenVertex { +struct ScreenVertex +{ float m_x; float m_y; float m_z; @@ -21,7 +22,8 @@ struct ScreenVertex { float m_u; float m_v; - static void init() { + static void init() + { ms_decl.begin() .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float) .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true) diff --git a/src/osd/modules/render/drawbgfx.cpp b/src/osd/modules/render/drawbgfx.cpp index 70aa92e508b..6b64a239317 100644 --- a/src/osd/modules/render/drawbgfx.cpp +++ b/src/osd/modules/render/drawbgfx.cpp @@ -304,10 +304,11 @@ void renderer_bgfx::put_packed_quad(render_primitive *prim, UINT32 hash, ScreenV vertex[5].m_v = v[0]; } -void renderer_bgfx::render_screen_quad(int view, render_primitive* prim) +void renderer_bgfx::process_screen_quad(int view, render_primitive* prim) { uint32_t texture_flags = BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP; - if (video_config.filter == 0) { + if (video_config.filter == 0) + { texture_flags |= BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIP_POINT; } @@ -327,6 +328,68 @@ void renderer_bgfx::render_screen_quad(int view, render_primitive* prim) delete texture; } +void renderer_bgfx::render_post_screen_quad(int view, render_primitive* prim) +{ + bgfx::TransientVertexBuffer buffer; + if (bgfx::checkAvailTransientVertexBuffer(6, ScreenVertex::ms_decl)) + { + bgfx::allocTransientVertexBuffer(&buffer, 6, ScreenVertex::ms_decl); + } + else + { + return; + } + + ScreenVertex* vertex = reinterpret_cast(buffer.data); + + vertex[0].m_x = prim->bounds.x0; + vertex[0].m_y = prim->bounds.y0; + vertex[0].m_z = 0; + vertex[0].m_rgba = 0xffffffff; + vertex[0].m_u = prim->texcoords.tl.u; + vertex[0].m_v = prim->texcoords.tl.v; + + vertex[1].m_x = prim->bounds.x1; + vertex[1].m_y = prim->bounds.y0; + vertex[1].m_z = 0; + vertex[1].m_rgba = 0xffffffff; + vertex[1].m_u = prim->texcoords.tr.u; + vertex[1].m_v = prim->texcoords.tr.v; + + vertex[2].m_x = prim->bounds.x1; + vertex[2].m_y = prim->bounds.y1; + vertex[2].m_z = 0; + vertex[2].m_rgba = 0xffffffff; + vertex[2].m_u = prim->texcoords.br.u; + vertex[2].m_v = prim->texcoords.br.v; + + vertex[3].m_x = prim->bounds.x1; + vertex[3].m_y = prim->bounds.y1; + vertex[3].m_z = 0; + vertex[3].m_rgba = 0xffffffff; + vertex[3].m_u = prim->texcoords.br.u; + vertex[3].m_v = prim->texcoords.br.v; + + vertex[4].m_x = prim->bounds.x0; + vertex[4].m_y = prim->bounds.y1; + vertex[4].m_z = 0; + vertex[4].m_rgba = 0xffffffff; + vertex[4].m_u = prim->texcoords.bl.u; + vertex[4].m_v = prim->texcoords.bl.v; + + vertex[5].m_x = prim->bounds.x0; + vertex[5].m_y = prim->bounds.y0; + vertex[5].m_z = 0; + vertex[5].m_rgba = 0xffffffff; + vertex[5].m_u = prim->texcoords.tl.u; + vertex[5].m_v = prim->texcoords.tl.v; + + UINT32 blend = PRIMFLAG_GET_BLENDMODE(prim->flags); + bgfx::setVertexBuffer(&buffer); + bgfx::setTexture(0, m_screen_effect[blend]->uniform("s_tex")->handle(), m_targets->target(m_screen_chain->output())->texture()); + m_screen_effect[blend]->submit(view); +} + void renderer_bgfx::render_textured_quad(int view, render_primitive* prim, bgfx::TransientVertexBuffer* buffer) { ScreenVertex* vertex = reinterpret_cast(buffer->data); @@ -787,52 +850,89 @@ const bgfx::Memory* renderer_bgfx::mame_texture_data_to_bgfx_texture_data(UINT32 return mem; } +int renderer_bgfx::handle_screen_chains() +{ + int index = window().m_index; + + window().m_primlist->acquire_lock(); + + int view = 0; + + // process + render_primitive *prim = window().m_primlist->first(); + while (prim != nullptr) + { + if (PRIMFLAG_GET_SCREENTEX(prim->flags)) + { + process_screen_quad(view, prim); + const int applicable_passes = m_screen_chain->applicable_passes(); + bgfx::setViewFrameBuffer(applicable_passes, BGFX_INVALID_HANDLE); + window().m_primlist->release_lock(); + return applicable_passes * (window().m_index + 1); + } + prim = prim->next(); + } + + window().m_primlist->release_lock(); + + return 0; +} + int renderer_bgfx::draw(int update) { - int index = window().m_index; - // Set view 0 default viewport. + int post_view_index = handle_screen_chains(); + int window_index = window().m_index; + int view_index = window_index; + int first_view_index = 0; + if (post_view_index > 0) + { + view_index = post_view_index; + first_view_index = m_screen_chain->applicable_passes(); + } + + // Set view 0 default viewport. osd_dim wdim = window().get_size(); - m_width[index] = wdim.width(); - m_height[index] = wdim.height(); - if (index == 0) + m_width[window_index] = wdim.width(); + m_height[window_index] = wdim.height(); + if (view_index == first_view_index) { - if ((m_dimensions != osd_dim(m_width[index], m_height[index]))) + if ((m_dimensions != osd_dim(m_width[window_index], m_height[window_index]))) { - bgfx::reset(m_width[index], m_height[index], video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE); - m_dimensions = osd_dim(m_width[index], m_height[index]); + bgfx::reset(m_width[window_index], m_height[window_index], video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE); + m_dimensions = osd_dim(m_width[window_index], m_height[window_index]); } } else { - if ((m_dimensions != osd_dim(m_width[index], m_height[index]))) + if ((m_dimensions != osd_dim(m_width[window_index], m_height[window_index]))) { bgfx::reset(window().m_main->get_size().width(), window().m_main->get_size().height(), video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE); delete m_framebuffer; #ifdef OSD_WINDOWS - m_framebuffer = m_targets->create_backbuffer(window().m_hwnd, m_width[index], m_height[index]); + m_framebuffer = m_targets->create_backbuffer(window().m_hwnd, m_width[window_index], m_height[window_index]); #else m_framebuffer = m_targets->create_backbuffer(sdlNativeWindowHandle(window().sdl_window()), m_width[index], m_height[index]); #endif - bgfx::setViewFrameBuffer(index, m_framebuffer->target()); - m_dimensions = osd_dim(m_width[index], m_height[index]); - bgfx::setViewClear(index + bgfx::setViewFrameBuffer(view_index, m_framebuffer->target()); + m_dimensions = osd_dim(m_width[window_index], m_height[window_index]); + bgfx::setViewClear(view_index , BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH , 0x000000ff , 1.0f , 0 ); - bgfx::touch(index); + bgfx::touch(view_index); bgfx::frame(); return 0; } } - if (index != 0) + if (view_index != first_view_index) { - bgfx::setViewFrameBuffer(index, m_framebuffer->target()); + bgfx::setViewFrameBuffer(view_index, m_framebuffer->target()); } - bgfx::setViewSeq(index, true); - bgfx::setViewRect(index, 0, 0, m_width[index], m_height[index]); + bgfx::setViewSeq(view_index, true); + bgfx::setViewRect(view_index, 0, 0, m_width[window_index], m_height[window_index]); // Setup view transform. { @@ -841,13 +941,13 @@ int renderer_bgfx::draw(int update) float left = 0.0f; float top = 0.0f; - float right = m_width[index]; - float bottom = m_height[index]; + float right = m_width[window_index]; + float bottom = m_height[window_index]; float proj[16]; bx::mtxOrtho(proj, left, right, bottom, top, 0.0f, 100.0f); - bgfx::setViewTransform(index, view, proj); + bgfx::setViewTransform(view_index, view, proj); } - bgfx::setViewClear(index + bgfx::setViewClear(view_index , BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH , 0x000000ff , 1.0f @@ -867,13 +967,13 @@ int renderer_bgfx::draw(int update) bgfx::TransientVertexBuffer buffer; allocate_buffer(prim, blend, &buffer); - buffer_status status = buffer_primitives(index, atlas_valid, &prim, &buffer); + buffer_status status = buffer_primitives(view_index, atlas_valid, &prim, &buffer); if (status != BUFFER_EMPTY) { bgfx::setVertexBuffer(&buffer); bgfx::setTexture(0, m_gui_effect[blend]->uniform("s_tex")->handle(), m_texture_cache->texture()); - m_gui_effect[blend]->submit(index); + m_gui_effect[blend]->submit(view_index); } if (status != BUFFER_DONE && status != BUFFER_PRE_FLUSH) @@ -886,11 +986,14 @@ int renderer_bgfx::draw(int update) // This dummy draw call is here to make sure that view 0 is cleared // if no other draw calls are submitted to view 0. - bgfx::touch(index); + bgfx::touch(view_index); // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. - if (index==0) bgfx::frame(); + if (view_index == first_view_index) + { + bgfx::frame(); + } return 0; } @@ -928,7 +1031,8 @@ renderer_bgfx::buffer_status renderer_bgfx::buffer_primitives(int view, bool atl #if USE_NEW_SHADERS if (PRIMFLAG_GET_SCREENTEX((*prim)->flags)) { - render_screen_quad(view, *prim); + //render_screen_quad(view, *prim); + render_post_screen_quad(view, *prim); } else { diff --git a/src/osd/modules/render/drawbgfx.h b/src/osd/modules/render/drawbgfx.h index 814f073b05c..c64c189688a 100644 --- a/src/osd/modules/render/drawbgfx.h +++ b/src/osd/modules/render/drawbgfx.h @@ -55,6 +55,8 @@ public: } private: + int handle_screen_chains(); + void allocate_buffer(render_primitive *prim, UINT32 blend, bgfx::TransientVertexBuffer *buffer); enum buffer_status { @@ -65,8 +67,9 @@ private: }; buffer_status buffer_primitives(int view, bool atlas_valid, render_primitive** prim, bgfx::TransientVertexBuffer* buffer); - void render_screen_quad(int view, render_primitive* prim); + void process_screen_quad(int view, render_primitive* prim); void render_textured_quad(int view, render_primitive* prim, bgfx::TransientVertexBuffer* buffer); + void render_post_screen_quad(int view, render_primitive* prim); void put_packed_quad(render_primitive *prim, UINT32 hash, ScreenVertex* vertex); void put_polygon(const float* coords, UINT32 num_coords, float r, UINT32 rgba, ScreenVertex* vertex);