summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/render
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/modules/render')
-rw-r--r--src/osd/modules/render/aviwrite.cpp6
-rw-r--r--src/osd/modules/render/aviwrite.h17
-rw-r--r--src/osd/modules/render/bgfx/blendreader.cpp11
-rw-r--r--src/osd/modules/render/bgfx/chain.cpp42
-rw-r--r--src/osd/modules/render/bgfx/chain.h17
-rw-r--r--src/osd/modules/render/bgfx/chainentry.cpp97
-rw-r--r--src/osd/modules/render/bgfx/chainentry.h14
-rw-r--r--src/osd/modules/render/bgfx/chainentryreader.cpp48
-rw-r--r--src/osd/modules/render/bgfx/chainentryreader.h12
-rw-r--r--src/osd/modules/render/bgfx/chainmanager.cpp463
-rw-r--r--src/osd/modules/render/bgfx/chainmanager.h97
-rw-r--r--src/osd/modules/render/bgfx/chainreader.cpp58
-rw-r--r--src/osd/modules/render/bgfx/chainreader.h15
-rw-r--r--src/osd/modules/render/bgfx/clearreader.cpp22
-rw-r--r--src/osd/modules/render/bgfx/clearreader.h14
-rw-r--r--src/osd/modules/render/bgfx/depthreader.cpp8
-rw-r--r--src/osd/modules/render/bgfx/depthreader.h10
-rw-r--r--src/osd/modules/render/bgfx/effect.cpp40
-rw-r--r--src/osd/modules/render/bgfx/effect.h23
-rw-r--r--src/osd/modules/render/bgfx/effectmanager.cpp74
-rw-r--r--src/osd/modules/render/bgfx/effectmanager.h29
-rw-r--r--src/osd/modules/render/bgfx/effectreader.cpp107
-rw-r--r--src/osd/modules/render/bgfx/effectreader.h24
-rw-r--r--src/osd/modules/render/bgfx/entryuniform.h12
-rw-r--r--src/osd/modules/render/bgfx/entryuniformreader.cpp12
-rw-r--r--src/osd/modules/render/bgfx/entryuniformreader.h14
-rw-r--r--src/osd/modules/render/bgfx/frameparameter.cpp8
-rw-r--r--src/osd/modules/render/bgfx/frameparameter.h16
-rw-r--r--src/osd/modules/render/bgfx/inputpair.cpp40
-rw-r--r--src/osd/modules/render/bgfx/parameter.h15
-rw-r--r--src/osd/modules/render/bgfx/paramreader.cpp32
-rw-r--r--src/osd/modules/render/bgfx/paramreader.h14
-rw-r--r--src/osd/modules/render/bgfx/paramuniform.h8
-rw-r--r--src/osd/modules/render/bgfx/paramuniformreader.cpp10
-rw-r--r--src/osd/modules/render/bgfx/paramuniformreader.h16
-rw-r--r--src/osd/modules/render/bgfx/shadermanager.cpp23
-rw-r--r--src/osd/modules/render/bgfx/shadermanager.h24
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/blurs/fs_smart-blur.sc32
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/blurs/vs_smart-blur.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/crt-geom_common.sc214
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom-deluxe.sc14
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom.sc120
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_gaussx.sc38
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_gaussy.sc38
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_lowpass.sc2
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_mipmap8.sc24
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_phosphor_apply.sc10
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_crt-geom.sc102
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_gaussx.sc16
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_gaussy.sc16
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_lowpass.sc72
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_mipmap8.sc11
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_phosphor_apply.sc11
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_phosphor_update.sc11
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt/vs_crt-caligari.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/default/vs_blit.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/eagle/fs_eagle.sc14
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/eagle/vs_eagle.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_defocus.sc2
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_distortion.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_scanline.sc27
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_chroma.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_color.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_deconverge.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_defocus.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_distortion.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_ntsc_decode.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_ntsc_encode.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_phosphor.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_post.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_prescale.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_scanline.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/hqx/fs_hq2x.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/hqx/fs_hq3x.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/hqx/fs_hq4x.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/hqx/vs_hq2x.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/hqx/vs_hq3x.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/hqx/vs_hq4x.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/lcd-grid/fs_lcd-grid.sc116
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/lcd-grid/fs_persistence.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/lcd-grid/vs_lcd-grid.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/lcd-grid/vs_persistence.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/misc/fs_deposterize-pass0.sc2
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/misc/fs_deposterize-pass1.sc2
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/misc/vs_blit.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/misc/vs_bob-and-ghost-deinterlace.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/misc/vs_deposterize-pass0.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/misc/vs_deposterize-pass1.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/misc/vs_lut.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/misc/vs_resize_blit.sc21
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/misc/vs_saturation.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/pillarbox_left_horizontal/vs_gaussian.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/pillarbox_left_horizontal/vs_offset_sat.sc9
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/pillarbox_left_vertical/vs_gaussian.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/pillarbox_left_vertical/vs_offset_sat.sc9
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/pillarbox_right_horizontal/vs_gaussian.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/pillarbox_right_horizontal/vs_offset_sat.sc9
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/pillarbox_right_vertical/vs_gaussian.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/pillarbox_right_vertical/vs_offset_sat.sc9
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/unfiltered/vs_blit.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/warp/vs_dilation-horizontal-fast.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_custom-jinc2-sharper.sc14
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-2xbr-3d-pass0.sc14
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_custom-jinc2-sharper.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-2xbr-3d-pass0.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-2xbr-3d-pass1.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-2xbr-3d-pass2.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass0.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass1.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass1f.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass2.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass3.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass3f.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-fast-pass0.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-fast-pass1.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-fast-pass2.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-pass0.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-pass1.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-pass2.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-pass3.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv1-noblend.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv2-3d.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv2-fast.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv2-noblend.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv2.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv3-noblend.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv3.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-sharp.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v2-gamma.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v2.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v4-gamma.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v4.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v4b.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v5-gamma.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-a-pass0.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-accuracy-pass0.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-accuracy-pass1.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-b-pass0.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-c-pass0.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-d-pass0.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-noblend-pass1.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-pass1.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv3-multipass/fs_xbr-lv3-pass0.sc2
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv3-multipass/vs_xbr-lv3-pass0.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv3-multipass/vs_xbr-lv3-pass1.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/fs_xbr-mlv4-pass4.sc2
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/vs_xbr-mlv4-pass1.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/vs_xbr-mlv4-pass2.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/vs_xbr-mlv4-pass3.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/vs_xbr-mlv4-pass4.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/vs_gui.sc5
-rw-r--r--src/osd/modules/render/bgfx/shaders/vs_screen.sc5
-rw-r--r--src/osd/modules/render/bgfx/slider.cpp6
-rw-r--r--src/osd/modules/render/bgfx/slider.h16
-rw-r--r--src/osd/modules/render/bgfx/sliderreader.cpp77
-rw-r--r--src/osd/modules/render/bgfx/sliderreader.h16
-rw-r--r--src/osd/modules/render/bgfx/slideruniform.cpp9
-rw-r--r--src/osd/modules/render/bgfx/slideruniform.h10
-rw-r--r--src/osd/modules/render/bgfx/slideruniformreader.cpp16
-rw-r--r--src/osd/modules/render/bgfx/slideruniformreader.h16
-rw-r--r--src/osd/modules/render/bgfx/statereader.cpp27
-rw-r--r--src/osd/modules/render/bgfx/statereader.h23
-rw-r--r--src/osd/modules/render/bgfx/suppressor.cpp6
-rw-r--r--src/osd/modules/render/bgfx/suppressor.h10
-rw-r--r--src/osd/modules/render/bgfx/suppressorreader.cpp23
-rw-r--r--src/osd/modules/render/bgfx/suppressorreader.h12
-rw-r--r--src/osd/modules/render/bgfx/target.cpp11
-rw-r--r--src/osd/modules/render/bgfx/target.h14
-rw-r--r--src/osd/modules/render/bgfx/targetmanager.cpp132
-rw-r--r--src/osd/modules/render/bgfx/targetmanager.h37
-rw-r--r--src/osd/modules/render/bgfx/targetreader.cpp60
-rw-r--r--src/osd/modules/render/bgfx/targetreader.h14
-rw-r--r--src/osd/modules/render/bgfx/texture.cpp9
-rw-r--r--src/osd/modules/render/bgfx/texture.h8
-rw-r--r--src/osd/modules/render/bgfx/texturehandleprovider.h11
-rw-r--r--src/osd/modules/render/bgfx/texturemanager.cpp141
-rw-r--r--src/osd/modules/render/bgfx/texturemanager.h37
-rw-r--r--src/osd/modules/render/bgfx/timeparameter.cpp6
-rw-r--r--src/osd/modules/render/bgfx/timeparameter.h15
-rw-r--r--src/osd/modules/render/bgfx/uniform.cpp6
-rw-r--r--src/osd/modules/render/bgfx/uniform.h12
-rw-r--r--src/osd/modules/render/bgfx/uniformreader.cpp32
-rw-r--r--src/osd/modules/render/bgfx/uniformreader.h16
-rw-r--r--src/osd/modules/render/bgfx/valueuniform.cpp10
-rw-r--r--src/osd/modules/render/bgfx/valueuniform.h10
-rw-r--r--src/osd/modules/render/bgfx/valueuniformreader.cpp8
-rw-r--r--src/osd/modules/render/bgfx/valueuniformreader.h15
-rw-r--r--src/osd/modules/render/bgfx/view.cpp4
-rw-r--r--src/osd/modules/render/bgfx/view.h6
-rw-r--r--src/osd/modules/render/bgfx/windowparameter.h16
-rw-r--r--src/osd/modules/render/bgfxutil.cpp34
-rw-r--r--src/osd/modules/render/bgfxutil.h3
-rw-r--r--src/osd/modules/render/binpacker.h36
-rw-r--r--src/osd/modules/render/blit13.ipp (renamed from src/osd/modules/render/blit13.h)0
-rw-r--r--src/osd/modules/render/d3d/d3dcomm.h103
-rw-r--r--src/osd/modules/render/d3d/d3dhlsl.cpp914
-rw-r--r--src/osd/modules/render/d3d/d3dhlsl.h102
-rw-r--r--src/osd/modules/render/draw13.cpp753
-rw-r--r--src/osd/modules/render/draw13.h216
-rw-r--r--src/osd/modules/render/drawbgfx.cpp997
-rw-r--r--src/osd/modules/render/drawbgfx.h87
-rw-r--r--src/osd/modules/render/drawd3d.cpp851
-rw-r--r--src/osd/modules/render/drawd3d.h57
-rw-r--r--src/osd/modules/render/drawgdi.cpp119
-rw-r--r--src/osd/modules/render/drawgdi.h55
-rw-r--r--src/osd/modules/render/drawnone.cpp79
-rw-r--r--src/osd/modules/render/drawnone.h33
-rw-r--r--src/osd/modules/render/drawogl.cpp1109
-rw-r--r--src/osd/modules/render/drawogl.h244
-rw-r--r--src/osd/modules/render/drawsdl.cpp337
-rw-r--r--src/osd/modules/render/drawsdl.h88
-rw-r--r--src/osd/modules/render/render_module.h38
-rw-r--r--src/osd/modules/render/sdlglcontext.h55
-rw-r--r--src/osd/modules/render/winglcontext.h201
215 files changed, 5860 insertions, 4402 deletions
diff --git a/src/osd/modules/render/aviwrite.cpp b/src/osd/modules/render/aviwrite.cpp
index 9148244111b..e86d8f99ba6 100644
--- a/src/osd/modules/render/aviwrite.cpp
+++ b/src/osd/modules/render/aviwrite.cpp
@@ -32,7 +32,7 @@ avi_write::~avi_write()
}
}
-void avi_write::record(const char *name)
+void avi_write::record(std::string_view name)
{
if (m_recording)
{
@@ -48,7 +48,7 @@ void avi_write::stop()
end_avi_recording();
}
-void avi_write::begin_avi_recording(const char *name)
+void avi_write::begin_avi_recording(std::string_view name)
{
// stop any existing recording
end_avi_recording();
@@ -81,7 +81,7 @@ void avi_write::begin_avi_recording(const char *name)
// create a new temporary movie file
emu_file tempfile(m_machine.options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- const std::error_condition filerr = (!name || !name[0] || !std::strcmp(name, OSDOPTVAL_AUTO))
+ const std::error_condition filerr = (name.empty() || name == OSDOPTVAL_AUTO)
? m_machine.video().open_next(tempfile, "avi")
: tempfile.open(name);
diff --git a/src/osd/modules/render/aviwrite.h b/src/osd/modules/render/aviwrite.h
index e59ce275168..a933dc2a3e6 100644
--- a/src/osd/modules/render/aviwrite.h
+++ b/src/osd/modules/render/aviwrite.h
@@ -6,13 +6,20 @@
//
//============================================================
+#ifndef MAME_RENDER_AVIWRITE_H
+#define MAME_RENDER_AVIWRITE_H
+
#pragma once
-#ifndef __RENDER_AVIWRITE__
-#define __RENDER_AVIWRITE__
+// emu
+#include "attotime.h"
+// lib/util
#include "aviio.h"
+#include <string_view>
+
+
class running_machine;
class avi_write
@@ -21,7 +28,7 @@ public:
avi_write(running_machine& machine, uint32_t width, uint32_t height);
~avi_write();
- void record(const char *name);
+ void record(std::string_view name);
void stop();
void audio_frame(const int16_t *buffer, int samples_this_frame);
void video_frame(bitmap_rgb32& snap);
@@ -30,7 +37,7 @@ public:
bool recording() const { return m_recording; }
private:
- void begin_avi_recording(const char *name);
+ void begin_avi_recording(std::string_view name);
void end_avi_recording();
running_machine& m_machine;
@@ -47,4 +54,4 @@ private:
attotime m_next_frame_time;
};
-#endif // __RENDER_AVIWRITE__
+#endif // MAME_RENDER_AVIWRITE_H
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..8d5adb0ec25 100644
--- a/src/osd/modules/render/bgfx/chain.cpp
+++ b/src/osd/modules/render/bgfx/chain.cpp
@@ -27,15 +27,24 @@
#include "clear.h"
#include "modules/osdwindow.h"
-bgfx_chain::bgfx_chain(std::string name, std::string author, bool transform, target_manager& targets, std::vector<bgfx_slider*> sliders, std::vector<bgfx_parameter*> params, std::vector<bgfx_chain_entry*> entries, std::vector<bgfx_target*> target_list, std::uint32_t screen_index)
- : m_name(name)
- , m_author(author)
+bgfx_chain::bgfx_chain(
+ std::string &&name,
+ std::string &&author,
+ bool transform,
+ target_manager& targets,
+ std::vector<bgfx_slider*> &&sliders,
+ std::vector<bgfx_parameter*> &&params,
+ std::vector<bgfx_chain_entry*> &&entries,
+ std::vector<bgfx_target*> &&target_list,
+ std::uint32_t screen_index)
+ : m_name(std::move(name))
+ , m_author(std::move(author))
, m_transform(transform)
, m_targets(targets)
- , m_sliders(sliders)
- , m_params(params)
- , m_entries(entries)
- , m_target_list(target_list)
+ , m_sliders(std::move(sliders))
+ , m_params(std::move(params))
+ , m_entries(std::move(entries))
+ , m_target_list(std::move(target_list))
, m_current_time(0)
, m_screen_index(screen_index)
, m_has_converter(false)
@@ -78,7 +87,7 @@ void bgfx_chain::repopulate_targets()
}
}
-void bgfx_chain::process(chain_manager::screen_prim &prim, int view, int screen, texture_manager& textures, osd_window& window, uint64_t blend)
+void bgfx_chain::process(chain_manager::screen_prim &prim, int view, int screen, texture_manager& textures, osd_window& window)
{
screen_device_enumerator screen_iterator(window.machine().root_device());
screen_device* screen_device = screen_iterator.byindex(screen);
@@ -108,11 +117,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, screen);
current_view++;
}
}
@@ -145,7 +155,7 @@ uint32_t bgfx_chain::applicable_passes()
return applicable_passes;
}
-void bgfx_chain::insert_effect(uint32_t index, bgfx_effect *effect, std::string name, std::string source, chain_manager &chains)
+void bgfx_chain::insert_effect(uint32_t index, bgfx_effect *effect, const bool apply_tint, std::string name, std::string source, chain_manager &chains)
{
auto *clear = new clear_state(BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH | BGFX_CLEAR_STENCIL, 0, 1.0f, 0);
std::vector<bgfx_suppressor*> suppressors;
@@ -164,11 +174,15 @@ void bgfx_chain::insert_effect(uint32_t index, bgfx_effect *effect, std::string
uniforms.push_back(new bgfx_value_uniform(new bgfx_uniform("u_tex_size1", bgfx::UniformType::Vec4), values, 4));
uniforms.push_back(new bgfx_value_uniform(new bgfx_uniform("u_inv_tex_size0", bgfx::UniformType::Vec4), values, 4));
uniforms.push_back(new bgfx_value_uniform(new bgfx_uniform("u_inv_tex_size1", bgfx::UniformType::Vec4), values, 4));
+ uniforms.push_back(new bgfx_value_uniform(new bgfx_uniform("u_tex_bounds0", bgfx::UniformType::Vec4), values, 4));
+ uniforms.push_back(new bgfx_value_uniform(new bgfx_uniform("u_tex_bounds1", bgfx::UniformType::Vec4), values, 4));
+ uniforms.push_back(new bgfx_value_uniform(new bgfx_uniform("u_inv_tex_bounds0", bgfx::UniformType::Vec4), values, 4));
+ uniforms.push_back(new bgfx_value_uniform(new bgfx_uniform("u_inv_tex_bounds1", bgfx::UniformType::Vec4), values, 4));
- m_entries.insert(m_entries.begin() + index, new bgfx_chain_entry(name, effect, clear, suppressors, inputs, uniforms, m_targets, "screen", false));
+ m_entries.insert(m_entries.begin() + index, new bgfx_chain_entry(name, effect, clear, suppressors, inputs, uniforms, m_targets, "screen", apply_tint));
const uint32_t screen_width = chains.targets().width(TARGET_STYLE_GUEST, m_screen_index);
const uint32_t screen_height = chains.targets().height(TARGET_STYLE_GUEST, m_screen_index);
m_targets.destroy_target("screen", m_screen_index);
- m_targets.create_target("screen", bgfx::TextureFormat::BGRA8, screen_width, screen_height, TARGET_STYLE_GUEST, true, false, 1, m_screen_index);
+ m_targets.create_target("screen", bgfx::TextureFormat::BGRA8, screen_width, screen_height, 1, 1, TARGET_STYLE_GUEST, true, false, 1, m_screen_index);
}
diff --git a/src/osd/modules/render/bgfx/chain.h b/src/osd/modules/render/bgfx/chain.h
index 5080532210c..5d84bb1ed0c 100644
--- a/src/osd/modules/render/bgfx/chain.h
+++ b/src/osd/modules/render/bgfx/chain.h
@@ -6,17 +6,17 @@
//
//============================================================
+#ifndef MAME_RENDER_BGFX_CHAIN_H
+#define MAME_RENDER_BGFX_CHAIN_H
+
#pragma once
-#ifndef __DRAWBGFX_CHAIN__
-#define __DRAWBGFX_CHAIN__
+#include "chainentry.h"
#include <string>
#include <vector>
#include <map>
-#include "chainentry.h"
-
class bgfx_slider;
class bgfx_parameter;
class texture_manager;
@@ -27,13 +27,14 @@ class osd_window;
class bgfx_chain
{
public:
- bgfx_chain(std::string name, std::string author, bool transform, target_manager& targets, std::vector<bgfx_slider*> sliders, std::vector<bgfx_parameter*> params, std::vector<bgfx_chain_entry*> entries, std::vector<bgfx_target*> target_list, uint32_t screen_index);
+ bgfx_chain(std::string &&name, std::string &&author, bool transform, target_manager& targets, std::vector<bgfx_slider*> &&sliders, std::vector<bgfx_parameter*> &&params, std::vector<bgfx_chain_entry*> &&entries, std::vector<bgfx_target*> &&target_list, uint32_t screen_index);
~bgfx_chain();
- void process(chain_manager::screen_prim &prim, int view, int screen, texture_manager& textures, osd_window &window, uint64_t blend = 0L);
+ void process(chain_manager::screen_prim &prim, int view, int screen, texture_manager& textures, osd_window &window);
void repopulate_targets();
// Getters
+ const std::string &name() const { return m_name; }
std::vector<bgfx_slider*>& sliders() { return m_sliders; }
std::vector<bgfx_chain_entry*>& entries() { return m_entries; }
uint32_t applicable_passes();
@@ -44,7 +45,7 @@ public:
// Setters
void set_has_converter(bool has_converter) { m_has_converter = has_converter; }
void set_has_adjuster(bool has_adjuster) { m_has_adjuster = has_adjuster; }
- void insert_effect(uint32_t index, bgfx_effect *effect, std::string name, std::string source, chain_manager &chains);
+ void insert_effect(uint32_t index, bgfx_effect *effect, const bool apply_tint, std::string name, std::string source, chain_manager &chains);
private:
std::string m_name;
@@ -63,4 +64,4 @@ private:
bool m_has_adjuster;
};
-#endif // __DRAWBGFX_CHAIN__
+#endif // MAME_RENDER_BGFX_CHAIN_H
diff --git a/src/osd/modules/render/bgfx/chainentry.cpp b/src/osd/modules/render/bgfx/chainentry.cpp
index 45c0b805882..c3f3ee3a8e3 100644
--- a/src/osd/modules/render/bgfx/chainentry.cpp
+++ b/src/osd/modules/render/bgfx/chainentry.cpp
@@ -30,7 +30,8 @@
#include "render.h"
-bgfx_chain_entry::bgfx_chain_entry(std::string name, bgfx_effect* effect, clear_state* clear, std::vector<bgfx_suppressor*> suppressors, std::vector<bgfx_input_pair*> inputs, std::vector<bgfx_entry_uniform*> uniforms, target_manager& targets, std::string output, bool apply_tint)
+bgfx_chain_entry::bgfx_chain_entry(std::string name, bgfx_effect* effect, clear_state* clear, std::vector<bgfx_suppressor*> suppressors, std::vector<bgfx_input_pair*> inputs,
+ std::vector<bgfx_entry_uniform*> uniforms, target_manager& targets, std::string output, bool apply_tint)
: m_name(name)
, m_effect(effect)
, m_clear(clear)
@@ -55,12 +56,18 @@ bgfx_chain_entry::~bgfx_chain_entry()
delete uniform;
}
m_uniforms.clear();
- delete m_clear;
+ if (m_clear)
+ {
+ delete m_clear;
+ }
}
-void bgfx_chain_entry::submit(int view, chain_manager::screen_prim &prim, texture_manager& textures, uint16_t screen_count, uint16_t screen_width, uint16_t screen_height, float screen_scale_x, float screen_scale_y, float screen_offset_x, float screen_offset_y, uint32_t rotation_type, bool swap_xy, uint64_t blend, int32_t screen)
+void bgfx_chain_entry::submit(int view, chain_manager::screen_prim &prim, texture_manager& textures, uint16_t screen_count, uint16_t screen_width, uint16_t screen_height,
+ float screen_scale_x, float screen_scale_y, float screen_offset_x, float screen_offset_y, uint32_t rotation_type, bool swap_xy, int32_t screen)
{
- if (!setup_view(textures, view, screen_width, screen_height, screen))
+ uint16_t view_width = screen_width;
+ uint16_t view_height = screen_height;
+ if (!setup_view(textures, view, screen_width, screen_height, screen, view_width, view_height))
{
return;
}
@@ -73,18 +80,19 @@ void bgfx_chain_entry::submit(int view, chain_manager::screen_prim &prim, textur
uint32_t tint = 0xffffffff;
if (m_apply_tint)
{
- const auto a = (uint8_t)std::round(prim.m_prim->color.a * 255);
- const auto r = (uint8_t)std::round(prim.m_prim->color.r * 255);
- const auto g = (uint8_t)std::round(prim.m_prim->color.g * 255);
- const auto b = (uint8_t)std::round(prim.m_prim->color.b * 255);
+ const uint8_t a = (uint8_t)std::round(prim.m_prim->color.a * 255);
+ const uint8_t r = (uint8_t)std::round(prim.m_prim->color.r * 255);
+ const uint8_t g = (uint8_t)std::round(prim.m_prim->color.g * 255);
+ const uint8_t b = (uint8_t)std::round(prim.m_prim->color.b * 255);
tint = (a << 24) | (b << 16) | (g << 8) | r;
}
bgfx::TransientVertexBuffer buffer;
- put_screen_buffer(prim.m_screen_width, prim.m_screen_height, tint, &buffer);
+ put_screen_buffer(view_width, view_height, tint, &buffer);
bgfx::setVertexBuffer(0, &buffer);
- setup_auto_uniforms(prim, textures, screen_count, screen_width, screen_height, screen_scale_x, screen_scale_y, screen_offset_x, screen_offset_y, rotation_type, swap_xy, screen);
+ setup_auto_uniforms(prim, textures, screen_count, view_width, view_height, screen_width, screen_height, screen_scale_x, screen_scale_y, screen_offset_x, screen_offset_y,
+ rotation_type, swap_xy, screen);
for (bgfx_entry_uniform* uniform : m_uniforms)
{
@@ -94,7 +102,7 @@ void bgfx_chain_entry::submit(int view, chain_manager::screen_prim &prim, textur
}
}
- m_effect->submit(view, blend);
+ m_effect->submit(view);
if (m_targets.target(screen, m_output) != nullptr)
{
@@ -102,6 +110,43 @@ void bgfx_chain_entry::submit(int view, chain_manager::screen_prim &prim, textur
}
}
+void bgfx_chain_entry::setup_auto_uniforms(chain_manager::screen_prim &prim, texture_manager& textures, uint16_t screen_count, uint16_t view_width, uint16_t view_height,
+ uint16_t screen_width, uint16_t screen_height, float screen_scale_x, float screen_scale_y, float screen_offset_x, float screen_offset_y,
+ uint32_t rotation_type, bool swap_xy, int32_t screen)
+{
+ setup_viewsize_uniforms(view_width, view_height);
+ setup_screensize_uniforms(textures, screen_width, screen_height, screen);
+ setup_screenscale_uniforms(screen_scale_x, screen_scale_y);
+ setup_screenoffset_uniforms(screen_offset_x, screen_offset_y);
+ setup_screencount_uniforms(screen_count);
+ setup_sourcesize_uniform(prim);
+ setup_targetsize_uniform(screen);
+ setup_targetscale_uniform(screen);
+ setup_rotationtype_uniform(rotation_type);
+ setup_swapxy_uniform(swap_xy);
+ setup_quaddims_uniform(prim);
+ setup_screenindex_uniform(screen);
+}
+
+void bgfx_chain_entry::setup_viewsize_uniforms(uint16_t view_width, uint16_t view_height)
+{
+ float width(view_width);
+ float height(view_height);
+ bgfx_uniform* view_dims = m_effect->uniform("u_view_dims");
+ if (view_dims != nullptr)
+ {
+ float values[2] = { width, height };
+ view_dims->set(values, sizeof(float) * 2);
+ }
+
+ bgfx_uniform* inv_view_dims = m_effect->uniform("u_inv_view_dims");
+ if (inv_view_dims != nullptr)
+ {
+ float values[2] = { -1.0f / width, 1.0f / height };
+ inv_view_dims->set(values, sizeof(float) * 2);
+ }
+}
+
void bgfx_chain_entry::setup_screensize_uniforms(texture_manager& textures, uint16_t screen_width, uint16_t screen_height, int32_t screen)
{
float width = screen_width;
@@ -235,22 +280,8 @@ void bgfx_chain_entry::setup_screenindex_uniform(int32_t screen) const
}
}
-void bgfx_chain_entry::setup_auto_uniforms(chain_manager::screen_prim &prim, texture_manager& textures, uint16_t screen_count, uint16_t screen_width, uint16_t screen_height, float screen_scale_x, float screen_scale_y, float screen_offset_x, float screen_offset_y, uint32_t rotation_type, bool swap_xy, int32_t screen)
-{
- setup_screensize_uniforms(textures, screen_width, screen_height, screen);
- setup_screenscale_uniforms(screen_scale_x, screen_scale_y);
- setup_screenoffset_uniforms(screen_offset_x, screen_offset_y);
- setup_screencount_uniforms(screen_count);
- setup_sourcesize_uniform(prim);
- setup_targetsize_uniform(screen);
- setup_targetscale_uniform(screen);
- setup_rotationtype_uniform(rotation_type);
- setup_swapxy_uniform(swap_xy);
- setup_quaddims_uniform(prim);
- setup_screenindex_uniform(screen);
-}
-
-bool bgfx_chain_entry::setup_view(texture_manager &textures, int view, uint16_t screen_width, uint16_t screen_height, int32_t screen) const
+bool bgfx_chain_entry::setup_view(texture_manager &textures, int view, uint16_t screen_width, uint16_t screen_height, int32_t screen,
+ uint16_t &out_view_width, uint16_t &out_view_height) const
{
bgfx::FrameBufferHandle handle = BGFX_INVALID_HANDLE;
uint16_t width = screen_width;
@@ -269,11 +300,13 @@ bool bgfx_chain_entry::setup_view(texture_manager &textures, int view, uint16_t
bgfx::setViewFrameBuffer(view, handle);
bgfx::setViewRect(view, 0, 0, width, height);
+ out_view_width = width;
+ out_view_height = height;
const bgfx::Caps* caps = bgfx::getCaps();
std::string name = m_inputs[0]->texture() + std::to_string(screen);
- const float right_ratio = (float)textures.provider(name)->width() / textures.provider(name)->rowpixels();
+ const float right_ratio = float(textures.provider(name)->width()) / textures.provider(name)->rowpixels();
float projMat[16];
bx::mtxOrtho(projMat, 0.0f, right_ratio, 1.0f, 0.0f, 0.0f, 100.0f, 0.0f, caps->homogeneousDepth);
@@ -307,14 +340,6 @@ void bgfx_chain_entry::put_screen_buffer(uint16_t screen_width, uint16_t screen_
v[0] = v[1] = 1;
v[2] = v[3] = 0;
}
- else if (renderer_type == bgfx::RendererType::Direct3D9)
- {
- for (int i = 0; i < 4; i++)
- {
- u[i] += 0.5f / screen_width;
- v[i] += 0.5f / screen_height;
- }
- }
vertex[0].m_x = x[0];
vertex[0].m_y = y[0];
diff --git a/src/osd/modules/render/bgfx/chainentry.h b/src/osd/modules/render/bgfx/chainentry.h
index 3fb1dd54ca6..a7504187879 100644
--- a/src/osd/modules/render/bgfx/chainentry.h
+++ b/src/osd/modules/render/bgfx/chainentry.h
@@ -34,10 +34,12 @@ class target_manager;
class bgfx_chain_entry
{
public:
- bgfx_chain_entry(std::string name, bgfx_effect* effect, clear_state* clear, std::vector<bgfx_suppressor*> suppressors, std::vector<bgfx_input_pair*> inputs, std::vector<bgfx_entry_uniform*> uniforms, target_manager& targets, std::string output, bool apply_tint);
+ bgfx_chain_entry(std::string name, bgfx_effect* effect, clear_state* clear, std::vector<bgfx_suppressor*> suppressors, std::vector<bgfx_input_pair*> inputs,
+ std::vector<bgfx_entry_uniform*> uniforms, target_manager& targets, std::string output, bool apply_tint);
~bgfx_chain_entry();
- void submit(int view, chain_manager::screen_prim &prim, texture_manager& textures, uint16_t screen_count, uint16_t screen_width, uint16_t screen_height, float screen_scale_x, float screen_scale_y, float screen_offset_x, float screen_offset_y, uint32_t rotation_type, bool swap_xy, uint64_t blend, int32_t screen);
+ void submit(int view, chain_manager::screen_prim &prim, texture_manager& textures, uint16_t screen_count, uint16_t screen_width, uint16_t screen_height,
+ float screen_scale_x, float screen_scale_y, float screen_offset_x, float screen_offset_y, uint32_t rotation_type, bool swap_xy, int32_t screen);
// Getters
std::string name() const { return m_name; }
@@ -45,7 +47,10 @@ public:
bool skip();
private:
- void setup_auto_uniforms(chain_manager::screen_prim &prim, texture_manager& textures, uint16_t screen_count, uint16_t screen_width, uint16_t screen_height, float screen_scale_x, float screen_scale_y, float screen_offset_x, float screen_offset_y, uint32_t rotation_type, bool swap_xy, int32_t screen);
+ void setup_auto_uniforms(chain_manager::screen_prim &prim, texture_manager& textures, uint16_t screen_count, uint16_t view_width, uint16_t view_height,
+ uint16_t screen_width, uint16_t screen_height, float screen_scale_x, float screen_scale_y, float screen_offset_x, float screen_offset_y,
+ uint32_t rotation_type, bool swap_xy, int32_t screen);
+ void setup_viewsize_uniforms(uint16_t view_width, uint16_t view_height);
void setup_screensize_uniforms(texture_manager& textures, uint16_t screen_width, uint16_t screen_height, int32_t screen);
void setup_screenscale_uniforms(float screen_scale_x, float screen_scale_y);
void setup_screenoffset_uniforms(float screen_offset_x, float screen_offset_y);
@@ -58,7 +63,8 @@ private:
void setup_quaddims_uniform(chain_manager::screen_prim &prim) const;
void setup_screenindex_uniform(int32_t screen) const;
- bool setup_view(texture_manager& textures, int view, uint16_t screen_width, uint16_t screen_height, int32_t screen) const;
+ bool setup_view(texture_manager& textures, int view, uint16_t screen_width, uint16_t screen_height, int32_t screen,
+ uint16_t &out_view_width, uint16_t &out_view_height) const;
void put_screen_buffer(uint16_t screen_width, uint16_t screen_height, uint32_t screen_tint, bgfx::TransientVertexBuffer* buffer) const;
std::string m_name;
diff --git a/src/osd/modules/render/bgfx/chainentryreader.cpp b/src/osd/modules/render/bgfx/chainentryreader.cpp
index c6b9953603f..ce58816e827 100644
--- a/src/osd/modules/render/bgfx/chainentryreader.cpp
+++ b/src/osd/modules/render/bgfx/chainentryreader.cpp
@@ -29,7 +29,13 @@
#include "clear.h"
#include "clearreader.h"
-bgfx_chain_entry* chain_entry_reader::read_from_value(const Value& value, std::string prefix, chain_manager& chains, std::map<std::string, bgfx_slider*>& sliders, std::map<std::string, bgfx_parameter*>& params, uint32_t screen_index)
+bgfx_chain_entry* chain_entry_reader::read_from_value(
+ const Value &value,
+ const std::string &prefix,
+ chain_manager &chains,
+ std::map<std::string, bgfx_slider*> &sliders,
+ std::map<std::string, bgfx_parameter*> &params,
+ uint32_t screen_index)
{
if (!validate_parameters(value, prefix))
{
@@ -52,18 +58,18 @@ bgfx_chain_entry* chain_entry_reader::read_from_value(const Value& value, std::s
for (uint32_t i = 0; i < input_array.Size(); i++)
{
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;
+ if (!READER_CHECK(input.HasMember("sampler"), "%sinput[%u]: Must have string value 'sampler' (what sampler are we binding to?)\n", prefix, i)) return nullptr;
+ if (!READER_CHECK(input["sampler"].IsString(), "%sinput[%u]: Value 'sampler' must be a string\n", prefix, i)) 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;
- if (!READER_CHECK(has_target || !input.HasMember("bilinear") || input["bilinear"].IsBool(), (prefix + "input[" + std::to_string(i) + ": Value 'bilinear' must be a boolean\n").c_str())) return nullptr;
- if (!READER_CHECK(has_target || !input.HasMember("clamp") || input["clamp"].IsBool(), (prefix + "input[" + std::to_string(i) + ": Value 'clamp' must be a boolean\n").c_str())) return nullptr;
- if (!READER_CHECK(has_texture || has_option || !input.HasMember("selection") || input["selection"].IsString(), (prefix + "input[" + std::to_string(i) + ": Value 'selection' must be a string\n").c_str())) return nullptr;
+ if (!READER_CHECK(has_texture || has_target || has_option, "%sinput[%u]: Must have string value 'target', 'texture' or 'option' (what source are we using?)\n", prefix, i)) return nullptr;
+ if (!READER_CHECK(!has_texture || input["texture"].IsString(), "%sinput[%u]: Value 'texture' must be a string\n", prefix, i)) return nullptr;
+ if (!READER_CHECK(!has_target || input["target"].IsString(), "%sinput[%u]: Value 'target' must be a string\n", prefix, i)) return nullptr;
+ if (!READER_CHECK(!has_option || input["option"].IsString(), "%sinput[%u]: Value 'option' must be a string\n", prefix, i)) return nullptr;
+ if (!READER_CHECK(has_target || !input.HasMember("bilinear") || input["bilinear"].IsBool(), "%sinput[%u]: Value 'bilinear' must be a boolean\n", prefix, i)) return nullptr;
+ if (!READER_CHECK(has_target || !input.HasMember("clamp") || input["clamp"].IsBool(), "%sinput[%u]: Value 'clamp' must be a boolean\n", prefix, i)) return nullptr;
+ if (!READER_CHECK(has_texture || has_option || !input.HasMember("selection") || input["selection"].IsString(), "%sinput[%u]: Value 'selection' must be a string\n", prefix, i)) return nullptr;
bool bilinear = get_bool(input, "bilinear", true);
bool clamp = get_bool(input, "clamp", false);
std::string selection = get_string(input, "selection", "");
@@ -223,17 +229,17 @@ bgfx_chain_entry* chain_entry_reader::read_from_value(const Value& value, std::s
return new bgfx_chain_entry(name, effect, clear, suppressors, inputs, uniforms, chains.targets(), output, applytint);
}
-bool chain_entry_reader::validate_parameters(const Value& value, std::string prefix)
+bool chain_entry_reader::validate_parameters(const Value& value, const std::string &prefix)
{
- if (!READER_CHECK(value.HasMember("effect"), (prefix + "Must have string value 'effect' (what effect does this entry use?)\n").c_str())) return false;
- if (!READER_CHECK(value["effect"].IsString(), (prefix + "Value 'effect' must be a string\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("name"), (prefix + "Must have string value 'effect' (what effect does this entry use?)\n").c_str())) return false;
- if (!READER_CHECK(value["name"].IsString(), (prefix + "Value 'name' must be a string\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("output"), (prefix + "Must have string value 'offset' (what target are we rendering to?)\n").c_str())) return false;
- if (!READER_CHECK(value["output"].IsString(), (prefix + "Value 'output' must be a string\n").c_str())) return false;
- if (!READER_CHECK(!value.HasMember("input") || value["input"].IsArray(), (prefix + "Value 'input' must be an array\n").c_str())) return false;
- if (!READER_CHECK(!value.HasMember("uniforms") || value["uniforms"].IsArray(), (prefix + "Value 'uniforms' must be an array\n").c_str())) return false;
- if (!READER_CHECK(!value.HasMember("disablewhen") || value["disablewhen"].IsArray(), (prefix + "Value 'disablewhen' must be an array\n").c_str())) return false;
- if (!READER_CHECK(!value.HasMember("applytint") || value["applytint"].IsBool(), (prefix + "Value 'applytint' must be a bool\n").c_str())) return false;
+ if (!READER_CHECK(value.HasMember("effect"), "%sMust have string value 'effect' (what effect does this entry use?)\n", prefix)) return false;
+ if (!READER_CHECK(value["effect"].IsString(), "%sValue 'effect' must be a string\n", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("name"), "%sMust have string value 'effect' (what effect does this entry use?)\n", prefix)) return false;
+ if (!READER_CHECK(value["name"].IsString(), "%sValue 'name' must be a string\n", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("output"), "%sMust have string value 'offset' (what target are we rendering to?)\n", prefix)) return false;
+ if (!READER_CHECK(value["output"].IsString(), "%sValue 'output' must be a string\n", prefix)) return false;
+ if (!READER_CHECK(!value.HasMember("input") || value["input"].IsArray(), "%sValue 'input' must be an array\n", prefix)) return false;
+ if (!READER_CHECK(!value.HasMember("uniforms") || value["uniforms"].IsArray(), "%sValue 'uniforms' must be an array\n", prefix)) return false;
+ if (!READER_CHECK(!value.HasMember("disablewhen") || value["disablewhen"].IsArray(), "%sValue 'disablewhen' must be an array\n", prefix)) return false;
+ if (!READER_CHECK(!value.HasMember("applytint") || value["applytint"].IsBool(), "%sValue 'applytint' must be a bool\n", prefix)) return false;
return true;
}
diff --git a/src/osd/modules/render/bgfx/chainentryreader.h b/src/osd/modules/render/bgfx/chainentryreader.h
index 0f604e9a71f..583e972732c 100644
--- a/src/osd/modules/render/bgfx/chainentryreader.h
+++ b/src/osd/modules/render/bgfx/chainentryreader.h
@@ -5,15 +5,15 @@
// chainentryreader.h - BGFX chain entry JSON reader
//
//============================================================
+#ifndef MAME_RENDER_BGFX_CHAINENTRYREADER_H
+#define MAME_RENDER_BGFX_CHAINENTRYREADER_H
#pragma once
-#ifndef __DRAWBGFX_CHAIN_ENTRY_READER__
-#define __DRAWBGFX_CHAIN_ENTRY_READER__
+#include "statereader.h"
#include <map>
-#include "statereader.h"
class bgfx_chain_entry;
class bgfx_slider;
@@ -23,10 +23,10 @@ class chain_manager;
class chain_entry_reader : public state_reader
{
public:
- static bgfx_chain_entry* read_from_value(const Value& value, std::string prefix, chain_manager& chains, std::map<std::string, bgfx_slider*>& sliders, std::map<std::string, bgfx_parameter*>& params, uint32_t screen_index);
+ static bgfx_chain_entry* read_from_value(const Value& value, const std::string &prefix, chain_manager& chains, 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);
+ static bool validate_parameters(const Value& value, const std::string &prefix);
};
-#endif // __DRAWBGFX_CHAIN_ENTRY_READER__
+#endif // MAME_RENDER_BGFX_CHAINENTRYREADER_H
diff --git a/src/osd/modules/render/bgfx/chainmanager.cpp b/src/osd/modules/render/bgfx/chainmanager.cpp
index c3b80e88d14..a15f2f1e584 100644
--- a/src/osd/modules/render/bgfx/chainmanager.cpp
+++ b/src/osd/modules/render/bgfx/chainmanager.cpp
@@ -26,45 +26,62 @@
#include "bgfxutil.h"
-#include "chainreader.h"
#include "chain.h"
-
-#include "texture.h"
-#include "target.h"
+#include "chainreader.h"
#include "slider.h"
+#include "target.h"
+#include "texture.h"
#include "sliderdirtynotifier.h"
+#include "util/path.h"
+#include "util/unicode.h"
+#include "util/xmlfile.h"
+
#include "osdcore.h"
#include "osdfile.h"
-using namespace rapidjson;
+#include <algorithm>
+#include <locale>
+
-const uint32_t chain_manager::CHAIN_NONE = 0;
+using namespace rapidjson;
chain_manager::screen_prim::screen_prim(render_primitive *prim)
{
m_prim = prim;
- m_screen_width = (uint16_t)floorf(prim->get_full_quad_width() + 0.5f);
- m_screen_height = (uint16_t)floorf(prim->get_full_quad_height() + 0.5f);
- m_quad_width = (uint16_t)floorf(prim->get_quad_width() + 0.5f);
- m_quad_height = (uint16_t)floorf(prim->get_quad_height() + 0.5f);
- m_tex_width = (float)prim->texture.width;
- m_tex_height = (float)prim->texture.height;
+ m_screen_width = uint16_t(floorf(prim->get_full_quad_width() + 0.5f));
+ m_screen_height = uint16_t(floorf(prim->get_full_quad_height() + 0.5f));
+ m_quad_width = uint16_t(floorf(prim->get_quad_width() + 0.5f));
+ m_quad_height = uint16_t(floorf(prim->get_quad_height() + 0.5f));
+ m_tex_width = prim->texture.width;
+ m_tex_height = prim->texture.height;
m_rowpixels = prim->texture.rowpixels;
m_palette_length = prim->texture.palette_length;
m_flags = prim->flags;
}
-chain_manager::chain_manager(running_machine& machine, osd_options& options, texture_manager& textures, target_manager& targets, effect_manager& effects, uint32_t window_index, slider_dirty_notifier& slider_notifier)
+chain_manager::chain_manager(
+ running_machine& machine,
+ const osd_options& options,
+ texture_manager& textures,
+ target_manager& targets,
+ effect_manager& effects,
+ uint32_t window_index,
+ slider_dirty_notifier& slider_notifier,
+ uint16_t user_prescale,
+ uint16_t max_prescale_size)
: m_machine(machine)
, m_options(options)
, m_textures(textures)
, m_targets(targets)
, m_effects(effects)
, m_window_index(window_index)
+ , m_user_prescale(user_prescale)
+ , m_max_prescale_size(max_prescale_size)
, m_slider_notifier(slider_notifier)
, m_screen_count(0)
+ , m_default_chain_index(-1)
{
m_converters.clear();
refresh_available_chains();
@@ -87,13 +104,55 @@ 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();
- m_available_chains.push_back(chain_desc("none", ""));
-
- const std::string chains_path = osd_subst_env(util::string_format("%s" PATH_SEPARATOR "chains", m_options.bgfx_path()));
- find_available_chains(chains_path, "");
+ m_available_chains.emplace_back("none", "");
+
+ find_available_chains(util::path_concat(m_options.bgfx_path(), "chains"), "");
+ std::collate<wchar_t> const &coll = std::use_facet<std::collate<wchar_t> >(std::locale());
+ std::sort(
+ m_available_chains.begin(),
+ m_available_chains.end(),
+ [&coll] (chain_desc const &x, chain_desc const &y) -> bool
+ {
+ if (x.m_name == "none")
+ return y.m_name != "none";
+ else if (y.m_name == "none")
+ return false;
+ else if (x.m_name == "default")
+ return y.m_name != "default";
+ else if (y.m_name == "default")
+ return false;
+ std::wstring const xstr = wstring_from_utf8(x.m_name);
+ std::wstring const ystr = wstring_from_utf8(y.m_name);
+ return coll.compare(xstr.data(), xstr.data() + xstr.size(), ystr.data(), ystr.data() + ystr.size()) < 0;
+ });
+
+ 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();
}
@@ -103,7 +162,7 @@ void chain_manager::destroy_unloaded_chains()
// O(shaders*available_chains), but we don't care because asset reloading happens rarely
for (int i = 0; i < m_chain_names.size(); i++)
{
- std::string name = m_chain_names[i];
+ const std::string &name = m_chain_names[i];
if (name.length() > 0)
{
for (chain_desc desc : m_available_chains)
@@ -112,8 +171,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;
}
}
@@ -121,56 +179,53 @@ void chain_manager::destroy_unloaded_chains()
}
}
-void chain_manager::find_available_chains(std::string root, std::string path)
+void chain_manager::find_available_chains(std::string_view root, std::string_view path)
{
- osd::directory::ptr directory = osd::directory::open(root + path);
- if (directory != nullptr)
+ osd::directory::ptr directory = osd::directory::open(path.empty() ? std::string(root) : util::path_concat(root, path));
+ if (directory)
{
- for (const osd::directory::entry *entry = directory->read(); entry != nullptr; entry = directory->read())
+ for (const osd::directory::entry *entry = directory->read(); entry; entry = directory->read())
{
if (entry->type == osd::directory::entry::entry_type::FILE)
{
- std::string name(entry->name);
- std::string extension(".json");
+ const std::string_view name(entry->name);
+ const std::string_view extension(".json");
// Does the name has at least one character in addition to ".json"?
if (name.length() > extension.length())
{
size_t start = name.length() - extension.length();
- std::string test_segment = name.substr(start, extension.length());
+ const std::string_view test_segment = name.substr(start, extension.length());
// Does it end in .json?
if (test_segment == extension)
{
- m_available_chains.push_back(chain_desc(name.substr(0, start), path));
+ m_available_chains.emplace_back(std::string(name.substr(0, start)), std::string(path));
}
}
}
else if (entry->type == osd::directory::entry::entry_type::DIR)
{
- std::string name = entry->name;
- if (!(name == "." || name == ".."))
+ const std::string_view name = entry->name;
+ if ((name != ".") && (name != ".."))
{
- std::string appended_path = path + "/" + name;
- if (path.length() == 0)
- {
- appended_path = name;
- }
- find_available_chains(root, path + "/" + name);
+ if (path.empty())
+ find_available_chains(root, name);
+ else
+ find_available_chains(root, util::path_concat(path, name));
}
}
}
}
}
-bgfx_chain* chain_manager::load_chain(std::string name, uint32_t screen_index)
+std::unique_ptr<bgfx_chain> chain_manager::load_chain(std::string name, uint32_t screen_index)
{
if (name.length() < 5 || (name.compare(name.length() - 5, 5, ".json") != 0))
{
- name = name + ".json";
+ name += ".json";
}
- std::string path = osd_subst_env(util::string_format("%s" PATH_SEPARATOR "chains" PATH_SEPARATOR, m_options.bgfx_path()));
- path += name;
+ const std::string path = util::path_concat(m_options.bgfx_path(), "chains", name);
bx::FileReader reader;
if (!bx::open(&reader, path.c_str()))
@@ -179,29 +234,35 @@ bgfx_chain* chain_manager::load_chain(std::string name, uint32_t screen_index)
return nullptr;
}
- int32_t size(bx::getSize(&reader));
+ const int32_t size(bx::getSize(&reader));
- char* data = new char[size + 1];
- bx::read(&reader, reinterpret_cast<void*>(data), size);
+ bx::ErrorAssert err;
+ std::unique_ptr<char []> data(new (std::nothrow) char [size + 1]);
+ if (!data)
+ {
+ osd_printf_error("Out of memory reading chain file %s\n", path);
+ bx::close(&reader);
+ return nullptr;
+ }
+
+ bx::read(&reader, reinterpret_cast<void*>(data.get()), size, &err);
bx::close(&reader);
data[size] = 0;
Document document;
- document.Parse<kParseCommentsFlag>(data);
-
- delete [] data;
+ document.Parse<kParseCommentsFlag>(data.get());
+ data.reset();
if (document.HasParseError())
{
std::string error(GetParseError_En(document.GetParseError()));
- osd_printf_warning("Unable to parse chain %s. Errors returned:\n", path);
- osd_printf_warning("%s\n", error);
+ osd_printf_warning("Unable to parse chain %s. Errors returned:\n%s\n", path, error);
return nullptr;
}
- bgfx_chain* chain = chain_reader::read_from_value(document, name + ": ", *this, screen_index);
+ std::unique_ptr<bgfx_chain> chain = chain_reader::read_from_value(document, name + ": ", *this, screen_index, m_user_prescale, m_max_prescale_size);
- if (chain == nullptr)
+ if (!chain)
{
osd_printf_warning("Unable to load chain %s, falling back to no post processing\n", path);
return nullptr;
@@ -210,17 +271,17 @@ bgfx_chain* chain_manager::load_chain(std::string name, uint32_t screen_index)
return chain;
}
-void chain_manager::parse_chain_selections(std::string chain_str)
+void chain_manager::parse_chain_selections(std::string_view chain_str)
{
- std::vector<std::string> chain_names = split_option_string(chain_str);
+ std::vector<std::string_view> chain_names = split_option_string(chain_str);
if (chain_names.empty())
chain_names.push_back("default");
- while (m_current_chain.size() != chain_names.size())
+ while (m_current_chain.size() < chain_names.size())
{
- m_screen_chains.push_back(nullptr);
- m_chain_names.push_back("");
+ m_screen_chains.emplace_back(nullptr);
+ m_chain_names.emplace_back();
m_current_chain.push_back(CHAIN_NONE);
}
@@ -230,9 +291,7 @@ void chain_manager::parse_chain_selections(std::string chain_str)
for (chain_index = 0; chain_index < m_available_chains.size(); chain_index++)
{
if (m_available_chains[chain_index].m_name == chain_names[index])
- {
break;
- }
}
if (chain_index < m_available_chains.size())
@@ -248,24 +307,35 @@ void chain_manager::parse_chain_selections(std::string chain_str)
}
}
-std::vector<std::string> chain_manager::split_option_string(std::string chain_str) const
+std::vector<std::string_view> chain_manager::split_option_string(std::string_view chain_str) const
{
- std::vector<std::string> chain_names;
+ std::vector<std::string_view> chain_names;
- uint32_t length = chain_str.length();
+ const uint32_t length = chain_str.length();
uint32_t win = 0;
uint32_t last_start = 0;
- for (uint32_t i = 0; i < length + 1; i++)
+ for (uint32_t i = 0; i <= length; i++)
{
- if (i == length || chain_str[i] == ',' || chain_str[i] == ':')
+ if (i == length || (chain_str[i] == ',') || (chain_str[i] == ':'))
{
- if (win == m_window_index)
+ if ((win == 0) || (win == m_window_index))
{
- chain_names.push_back(chain_str.substr(last_start, i - last_start));
+ // treat an empty string as equivalent to "default"
+ if (i > last_start)
+ chain_names.push_back(chain_str.substr(last_start, i - last_start));
+ else
+ chain_names.push_back("default");
}
+
last_start = i + 1;
- if (chain_str[i] == ':')
+ if ((i < length) && (chain_str[i] == ':'))
{
+ // no point walking the rest of the string if this was our window
+ if (win == m_window_index)
+ break;
+
+ // don't use first for all if more than one window is specified
+ chain_names.clear();
win++;
}
}
@@ -282,7 +352,7 @@ void chain_manager::load_chains()
{
chain_desc& desc = m_available_chains[m_current_chain[chain]];
m_chain_names[chain] = desc.m_name;
- m_screen_chains[chain] = load_chain(desc.m_path + "/" + desc.m_name, uint32_t(chain));
+ m_screen_chains[chain] = load_chain(util::path_concat(desc.m_path, desc.m_name), uint32_t(chain)).release();
}
}
}
@@ -319,7 +389,7 @@ bgfx_chain* chain_manager::screen_chain(uint32_t screen)
void chain_manager::process_screen_quad(uint32_t view, uint32_t screen, screen_prim &prim, osd_window& window)
{
- const bool any_targets_rebuilt = m_targets.update_target_sizes(screen, prim.m_tex_width, prim.m_tex_height, TARGET_STYLE_GUEST);
+ const bool any_targets_rebuilt = m_targets.update_target_sizes(screen, prim.m_tex_width, prim.m_tex_height, TARGET_STYLE_GUEST, m_user_prescale, m_max_prescale_size);
if (any_targets_rebuilt)
{
for (bgfx_chain* chain : m_screen_chains)
@@ -332,7 +402,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();
}
@@ -359,7 +429,7 @@ uint32_t chain_manager::count_screens(render_primitive* prim)
if (screen_count > 0)
{
update_screen_count(screen_count);
- m_targets.update_screen_count(screen_count);
+ m_targets.update_screen_count(screen_count, m_user_prescale, m_max_prescale_size);
}
if (screen_count < m_screen_prims.size())
@@ -381,8 +451,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.emplace_back(std::move(chain_name));
+ m_current_chain.push_back(chain_index);
}
// Ensure we have a screen chain selection slider per screen
@@ -395,11 +469,20 @@ void chain_manager::update_screen_count(uint32_t screen_count)
}
}
+void chain_manager::set_current_chain(uint32_t screen, int32_t chain_index)
+{
+ if (chain_index < m_available_chains.size() && screen < m_current_chain.size() && screen < m_chain_names.size())
+ {
+ m_current_chain[screen] = chain_index;
+ m_chain_names[screen] = m_available_chains[chain_index].m_name;
+ }
+}
+
int32_t chain_manager::slider_changed(int id, std::string *str, int32_t newval)
{
if (newval != SLIDER_NOCHANGE)
{
- m_current_chain[id] = newval;
+ set_current_chain(id, newval);
std::vector<std::vector<float>> settings = slider_settings();
reload_chains();
@@ -428,11 +511,11 @@ void chain_manager::create_selection_slider(uint32_t screen_index)
int32_t maxval = m_available_chains.size() - 1;
int32_t incval = 1;
- std::string description = "Window " + std::to_string(m_window_index) + ", Screen " + std::to_string(screen_index) + " Effect:";
-
using namespace std::placeholders;
- auto state = std::make_unique<slider_state>(std::move(description), minval, defval, maxval, incval,
- std::bind(&chain_manager::slider_changed, this, screen_index, _1, _2));
+ auto state = std::make_unique<slider_state>(
+ util::string_format("Window %1$u, Screen %2$u Effect", m_window_index, screen_index),
+ minval, defval, maxval, incval,
+ std::bind(&chain_manager::slider_changed, this, screen_index, _1, _2));
ui::menu_item item(ui::menu_item_type::SLIDER, state.get());
item.set_text(state->description);
@@ -457,23 +540,17 @@ uint32_t chain_manager::update_screen_textures(uint32_t view, render_primitive *
const uint32_t src_format = (prim.m_flags & PRIMFLAG_TEXFORMAT_MASK) >> PRIMFLAG_TEXFORMAT_SHIFT;
const bool needs_conversion = m_converters[src_format] != nullptr;
const bool needs_adjust = prim.m_prim->texture.palette != nullptr && src_format != TEXFORMAT_PALETTE16;
- std::string screen_index = std::to_string(screen);
- std::string source_name = "source" + screen_index;
- std::string screen_name = "screen" + screen_index;
- std::string palette_name = "palette" + screen_index;
- std::string full_name = (needs_conversion || needs_adjust) ? source_name : screen_name;
+ const std::string screen_index = std::to_string(screen);
+ const std::string source_name = "source" + screen_index;
+ const std::string screen_name = "screen" + screen_index;
+ const std::string palette_name = "palette" + screen_index;
+ const std::string &full_name = (needs_conversion || needs_adjust) ? source_name : screen_name;
if (texture && (texture->width() != tex_width || texture->height() != tex_height))
{
- m_textures.add_provider(full_name, nullptr);
- delete texture;
+ m_textures.remove_provider(full_name);
+ m_textures.remove_provider(palette_name);
texture = nullptr;
-
- if (palette)
- {
- m_textures.add_provider(palette_name, nullptr);
- delete palette;
- palette = nullptr;
- }
+ palette = nullptr;
}
bgfx::TextureFormat::Enum dst_format = bgfx::TextureFormat::BGRA8;
@@ -481,36 +558,38 @@ uint32_t chain_manager::update_screen_textures(uint32_t view, render_primitive *
int width_div_factor = 1;
int width_mul_factor = 1;
const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(dst_format, prim.m_flags & PRIMFLAG_TEXFORMAT_MASK,
- prim.m_rowpixels, tex_height, prim.m_prim->texture.palette, prim.m_prim->texture.base, pitch, width_div_factor, width_mul_factor);
+ prim.m_rowpixels, prim.m_prim->texture.width_margin, tex_height, prim.m_prim->texture.palette, prim.m_prim->texture.base, pitch, width_div_factor, width_mul_factor);
- if (texture == nullptr)
+ if (!texture)
{
uint32_t flags = BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT;
if (!PRIMFLAG_GET_TEXWRAP(prim.m_flags))
flags |= BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP;
- bgfx_texture *texture = new bgfx_texture(full_name, dst_format, tex_width, tex_height, mem, flags, pitch, prim.m_rowpixels, width_div_factor, width_mul_factor);
- m_textures.add_provider(full_name, texture);
+ auto newtex = std::make_unique<bgfx_texture>(full_name, dst_format, tex_width, prim.m_prim->texture.width_margin, tex_height, mem, flags, pitch, prim.m_rowpixels, width_div_factor, width_mul_factor);
+ texture = newtex.get();
+ m_textures.add_provider(full_name, std::move(newtex));
if (prim.m_prim->texture.palette)
{
- uint16_t palette_width = (uint16_t)std::min(prim.m_palette_length, 256U);
- uint16_t palette_height = (uint16_t)std::max((prim.m_palette_length + 255) / 256, 1U);
+ uint16_t palette_width = uint16_t(std::min(prim.m_palette_length, 256U));
+ uint16_t palette_height = uint16_t(std::max((prim.m_palette_length + 255) / 256, 1U));
m_palette_temp.resize(palette_width * palette_height * 4);
memcpy(&m_palette_temp[0], prim.m_prim->texture.palette, prim.m_palette_length * 4);
const bgfx::Memory *palmem = bgfx::copy(&m_palette_temp[0], palette_width * palette_height * 4);
- palette = new bgfx_texture(palette_name, bgfx::TextureFormat::BGRA8, palette_width, palette_height, palmem, BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP | BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT, palette_width * 4);
- m_textures.add_provider(palette_name, palette);
+ auto newpal = std::make_unique<bgfx_texture>(palette_name, bgfx::TextureFormat::BGRA8, palette_width, 0, palette_height, palmem, BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP | BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT, palette_width * 4);
+ palette = newpal.get();
+ m_textures.add_provider(palette_name, std::move(newpal));
}
while (screen >= m_screen_textures.size())
{
- m_screen_textures.push_back(nullptr);
+ m_screen_textures.emplace_back(nullptr);
}
m_screen_textures[screen] = texture;
while (screen >= m_screen_palettes.size())
{
- m_screen_palettes.push_back(nullptr);
+ m_screen_palettes.emplace_back(nullptr);
}
if (palette)
{
@@ -519,12 +598,12 @@ uint32_t chain_manager::update_screen_textures(uint32_t view, render_primitive *
}
else
{
- texture->update(mem, pitch);
+ texture->update(mem, pitch, prim.m_prim->texture.width_margin);
if (prim.m_prim->texture.palette)
{
- uint16_t palette_width = (uint16_t)std::min(prim.m_palette_length, 256U);
- uint16_t palette_height = (uint16_t)std::max((prim.m_palette_length + 255) / 256, 1U);
+ uint16_t palette_width = uint16_t(std::min(prim.m_palette_length, 256U));
+ uint16_t palette_height = uint16_t(std::max((prim.m_palette_length + 255) / 256, 1U));
const uint32_t palette_size = palette_width * palette_height * 4;
m_palette_temp.resize(palette_size);
memcpy(&m_palette_temp[0], prim.m_prim->texture.palette, prim.m_palette_length * 4);
@@ -536,26 +615,29 @@ uint32_t chain_manager::update_screen_textures(uint32_t view, render_primitive *
}
else
{
- palette = new bgfx_texture(palette_name, bgfx::TextureFormat::BGRA8, palette_width, palette_height, palmem, BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP | BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT, palette_width * 4);
- m_textures.add_provider(palette_name, palette);
+ auto newpal = std::make_unique<bgfx_texture>(palette_name, bgfx::TextureFormat::BGRA8, palette_width, 0, palette_height, palmem, BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP | BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT, palette_width * 4);
+ palette = newpal.get();
+ m_textures.add_provider(palette_name, std::move(newpal));
while (screen >= m_screen_palettes.size())
{
- m_screen_palettes.push_back(nullptr);
+ m_screen_palettes.emplace_back(nullptr);
}
m_screen_palettes[screen] = palette;
}
}
}
+ const bool has_tint = (prim.m_prim->color.a != 1.0f) || (prim.m_prim->color.r != 1.0f) || (prim.m_prim->color.g != 1.0f) || (prim.m_prim->color.b != 1.0f);
bgfx_chain* chain = screen_chain(screen);
if (chain && needs_adjust && !chain->has_adjuster())
{
- chain->insert_effect(chain->has_converter() ? 1 : 0, m_adjuster, "XXadjust", needs_conversion ? "screen" : "source", *this);
+ const bool apply_tint = !needs_conversion && has_tint;
+ chain->insert_effect(chain->has_converter() ? 1 : 0, m_adjuster, apply_tint, "XXadjust", needs_conversion ? "screen" : "source", *this);
chain->set_has_adjuster(true);
}
if (chain && needs_conversion && !chain->has_converter())
{
- chain->insert_effect(0, m_converters[src_format], "XXconvert", "source", *this);
+ chain->insert_effect(0, m_converters[src_format], has_tint, "XXconvert", "source", *this);
chain->set_has_converter(true);
}
}
@@ -583,7 +665,7 @@ uint32_t chain_manager::process_screen_chains(uint32_t view, osd_window& window)
std::swap(screen_width, screen_height);
}
- const bool any_targets_rebuilt = m_targets.update_target_sizes(screen_index, screen_width, screen_height, TARGET_STYLE_NATIVE);
+ const bool any_targets_rebuilt = m_targets.update_target_sizes(screen_index, screen_width, screen_height, TARGET_STYLE_NATIVE, m_user_prescale, m_max_prescale_size);
if (any_targets_rebuilt)
{
for (bgfx_chain* chain : m_screen_chains)
@@ -608,12 +690,12 @@ uint32_t chain_manager::process_screen_chains(uint32_t view, osd_window& window)
bool chain_manager::has_applicable_chain(uint32_t screen)
{
- return screen < m_screen_count && m_current_chain[screen] != CHAIN_NONE && m_screen_chains[screen] != nullptr;
+ return (screen < m_screen_count) && (m_current_chain[screen] != CHAIN_NONE) && m_screen_chains[screen];
}
bool chain_manager::needs_sliders()
{
- return m_screen_count > 0 && m_available_chains.size() > 1;
+ return (m_screen_count > 0) && (m_available_chains.size() > 1);
}
void chain_manager::restore_slider_settings(int32_t id, std::vector<std::vector<float>>& settings)
@@ -636,7 +718,7 @@ void chain_manager::restore_slider_settings(int32_t id, std::vector<std::vector<
continue;
}
- std::vector<bgfx_slider*> chain_sliders = chain->sliders();
+ const std::vector<bgfx_slider*> &chain_sliders = chain->sliders();
for (size_t slider = 0; slider < chain_sliders.size(); slider++)
{
chain_sliders[slider]->import(settings[index][slider]);
@@ -644,6 +726,151 @@ void chain_manager::restore_slider_settings(int32_t id, std::vector<std::vector<
}
}
+void chain_manager::load_config(util::xml::data_node const &windownode)
+{
+ // treat source INI files or more specific as higher priority than CFG
+ // FIXME: leaky abstraction - this depends on a front-end implementation detail
+ bool const persist = windownode.get_attribute_int("persist", 1) != 0;
+ bool const default_chains = (OPTION_PRIORITY_NORMAL + 5) > m_options.get_entry(OSDOPTION_BGFX_SCREEN_CHAINS)->priority();
+ bool const explicit_chains = !persist && !default_chains && *m_options.bgfx_screen_chains();
+
+ // if chains weren't explicitly specified, restore the chains from the config file
+ if (explicit_chains)
+ {
+ osd_printf_verbose(
+ "BGFX: Ignoring chain selection from window 0 configuration due to explicitly specified chains\n",
+ m_window_index);
+ }
+ else
+ {
+ bool changed = false;
+ util::xml::data_node const *screennode = windownode.get_child("screen");
+ while (screennode)
+ {
+ auto const index = screennode->get_attribute_int("index", -1);
+ if ((0 <= index) && (m_screen_count > index))
+ {
+ char const *const chainname = screennode->get_attribute_string("chain", nullptr);
+ if (chainname)
+ {
+ auto const found = std::find_if(
+ m_available_chains.begin(),
+ m_available_chains.end(),
+ [&chainname] (auto const &avail) { return avail.m_name == chainname; });
+ if (m_available_chains.end() != found)
+ {
+ auto const chainnum = found - m_available_chains.begin();
+ if (chainnum != m_current_chain[index])
+ {
+ m_current_chain[index] = chainnum;
+ changed = true;
+ }
+ }
+ }
+ }
+
+ screennode = screennode->get_next_sibling("screen");
+ }
+
+ if (changed)
+ reload_chains();
+ }
+
+ // now apply slider settings for screens with chains matching config
+ util::xml::data_node const *screennode = windownode.get_child("screen");
+ while (screennode)
+ {
+ auto const index = screennode->get_attribute_int("index", -1);
+ if ((0 <= index) && (m_screen_count > index) && (m_screen_chains.size() > index))
+ {
+ bgfx_chain *const chain = m_screen_chains[index];
+ char const *const chainname = screennode->get_attribute_string("chain", nullptr);
+ if (chain && chainname && (m_available_chains[m_current_chain[index]].m_name == chainname))
+ {
+ auto const &sliders = chain->sliders();
+
+ util::xml::data_node const *slidernode = screennode->get_child("slider");
+ while (slidernode)
+ {
+ char const *const slidername = slidernode->get_attribute_string("name", nullptr);
+ if (slidername)
+ {
+ auto const found = std::find_if(
+ sliders.begin(),
+ sliders.end(),
+ [&slidername] (auto const &slider) { return slider->name() == slidername; });
+ if (sliders.end() != found)
+ {
+ bgfx_slider &slider = **found;
+ switch (slider.type())
+ {
+ case bgfx_slider::SLIDER_INT_ENUM:
+ case bgfx_slider::SLIDER_INT:
+ {
+ slider_state const &core = *slider.core_slider();
+ int32_t const val = slidernode->get_attribute_int("value", core.defval);
+ slider.update(nullptr, std::clamp(val, core.minval, core.maxval));
+ }
+ break;
+ default:
+ {
+ float const val = slidernode->get_attribute_float("value", slider.default_value());
+ slider.import(std::clamp(val, slider.min_value(), slider.max_value()));
+ }
+ }
+ }
+ }
+
+ slidernode = slidernode->get_next_sibling("slider");
+ }
+ }
+ }
+ screennode = screennode->get_next_sibling("screen");
+ }
+}
+
+void chain_manager::save_config(util::xml::data_node &parentnode)
+{
+ if (!needs_sliders())
+ return;
+
+ util::xml::data_node *const windownode = parentnode.add_child("window", nullptr);
+ windownode->set_attribute_int("index", m_window_index);
+
+ for (size_t index = 0; index < m_screen_chains.size() && index < m_screen_count; index++)
+ {
+ bgfx_chain *const chain = m_screen_chains[index];
+ if (!chain)
+ continue;
+
+ util::xml::data_node *const screennode = windownode->add_child("screen", nullptr);
+ screennode->set_attribute_int("index", index);
+ screennode->set_attribute("chain", m_available_chains[m_current_chain[index]].m_name.c_str());
+
+ for (bgfx_slider *slider : chain->sliders())
+ {
+ auto const val = slider->update(nullptr, SLIDER_NOCHANGE);
+ if (val == slider->core_slider()->defval)
+ continue;
+
+ util::xml::data_node *const slidernode = screennode->add_child("slider", nullptr);
+ slidernode->set_attribute("name", slider->name().c_str());
+ switch (slider->type())
+ {
+ case bgfx_slider::SLIDER_INT_ENUM:
+ case bgfx_slider::SLIDER_INT:
+ slidernode->set_attribute_int("value", val);
+ break;
+ default:
+ slidernode->set_attribute_float("value", slider->value());
+ }
+ }
+ }
+
+ if (!windownode->get_first_child())
+ windownode->delete_node();
+}
+
std::vector<std::vector<float>> chain_manager::slider_settings()
{
std::vector<std::vector<float>> curr;
@@ -663,7 +890,7 @@ std::vector<std::vector<float>> chain_manager::slider_settings()
continue;
}
- std::vector<bgfx_slider*> chain_sliders = chain->sliders();
+ const std::vector<bgfx_slider*> &chain_sliders = chain->sliders();
for (bgfx_slider* slider : chain_sliders)
{
curr[index].push_back(slider->value());
@@ -692,24 +919,24 @@ std::vector<ui::menu_item> chain_manager::get_slider_list()
continue;
}
- std::vector<bgfx_chain_entry*> chain_entries = chain->entries();
+ const std::vector<bgfx_chain_entry*> &chain_entries = chain->entries();
for (bgfx_chain_entry* entry : chain_entries)
{
- std::vector<bgfx_input_pair*> entry_inputs = entry->inputs();
+ const std::vector<bgfx_input_pair*> &entry_inputs = entry->inputs();
for (bgfx_input_pair* input : entry_inputs)
{
std::vector<ui::menu_item> input_sliders = input->get_slider_list();
- for (ui::menu_item slider : input_sliders)
+ for (ui::menu_item &slider : input_sliders)
{
sliders.emplace_back(slider);
}
}
}
- std::vector<bgfx_slider*> chain_sliders = chain->sliders();
+ const std::vector<bgfx_slider*> &chain_sliders = chain->sliders();
for (bgfx_slider* slider : chain_sliders)
{
- slider_state* core_slider = slider->core_slider();
+ slider_state *const core_slider = slider->core_slider();
ui::menu_item item(ui::menu_item_type::SLIDER, core_slider);
item.set_text(core_slider->description);
diff --git a/src/osd/modules/render/bgfx/chainmanager.h b/src/osd/modules/render/bgfx/chainmanager.h
index 59a65dc59cf..0d489d0bd72 100644
--- a/src/osd/modules/render/bgfx/chainmanager.h
+++ b/src/osd/modules/render/bgfx/chainmanager.h
@@ -9,19 +9,24 @@
//
//============================================================
-#pragma once
+#ifndef MAME_RENDER_BGFX_CHAINMANAGER_H
+#define MAME_RENDER_BGFX_CHAINMANAGER_H
-#ifndef __DRAWBGFX_CHAIN_MANAGER__
-#define __DRAWBGFX_CHAIN_MANAGER__
+#pragma once
-#include "texturemanager.h"
-#include "targetmanager.h"
#include "effectmanager.h"
+#include "targetmanager.h"
+#include "texturemanager.h"
+
+#include "util/utilfwd.h"
#include <map>
#include <string>
+#include <string_view>
+#include <utility>
#include <vector>
+
class running_machine;
class osd_window;
struct slider_state;
@@ -33,23 +38,29 @@ namespace ui { class menu_item; }
class bgfx_chain;
class bgfx_slider;
-class chain_desc
+class chain_manager
{
public:
- chain_desc(std::string name, std::string path)
- : m_name(name)
- , m_path(path)
+ class screen_prim
{
- }
+ public:
+ screen_prim() = default;
+ screen_prim(render_primitive *prim);
- const std::string m_name;
- const std::string m_path;
-};
+ render_primitive *m_prim = nullptr;
+ uint16_t m_screen_width = 0;
+ uint16_t m_screen_height = 0;
+ uint16_t m_quad_width = 0;
+ uint16_t m_quad_height = 0;
+ float m_tex_width = 0.0f;
+ float m_tex_height = 0.0f;
+ int m_rowpixels = 0;
+ uint32_t m_palette_length = 0;
+ uint32_t m_flags = 0;
+ };
-class chain_manager
-{
-public:
- chain_manager(running_machine& machine, osd_options& options, texture_manager& textures, target_manager& targets, effect_manager& effects, uint32_t window_index, slider_dirty_notifier& slider_notifier);
+ chain_manager(running_machine& machine, const osd_options& options, texture_manager& textures, target_manager& targets, effect_manager& effects, uint32_t window_index,
+ slider_dirty_notifier& slider_notifier, uint16_t user_prescale, uint16_t max_prescale_size);
~chain_manager();
uint32_t update_screen_textures(uint32_t view, render_primitive *starting_prim, osd_window& window);
@@ -57,7 +68,7 @@ public:
// Getters
running_machine& machine() const { return m_machine; }
- osd_options& options() const { return m_options; }
+ const osd_options& options() const { return m_options; }
texture_manager& textures() const { return m_textures; }
target_manager& targets() const { return m_targets; }
effect_manager& effects() const { return m_effects; }
@@ -65,7 +76,7 @@ public:
uint32_t window_index() const { return m_window_index; }
uint32_t screen_count() const { return m_screen_count; }
bgfx_chain* screen_chain(uint32_t screen);
- bgfx_chain* load_chain(std::string name, uint32_t screen_index);
+ std::unique_ptr<bgfx_chain> load_chain(std::string name, uint32_t screen_index);
bool has_applicable_chain(uint32_t screen);
std::vector<ui::menu_item> get_slider_list();
std::vector<std::vector<float>> slider_settings();
@@ -73,43 +84,44 @@ public:
// Setters
void restore_slider_settings(int32_t id, std::vector<std::vector<float>>& settings);
- class screen_prim
+ void load_config(util::xml::data_node const &screennode);
+ void save_config(util::xml::data_node &parentnode);
+
+private:
+ class chain_desc
{
public:
- screen_prim() : m_prim(nullptr), m_screen_width(0), m_screen_height(0), m_quad_width(0), m_quad_height(0)
- , m_tex_width(0), m_tex_height(0), m_rowpixels(0), m_palette_length(0), m_flags(0)
+ chain_desc(const chain_desc &) = default;
+ chain_desc(chain_desc &&) = default;
+ chain_desc &operator=(const chain_desc &) = default;
+ chain_desc &operator=(chain_desc &&) = default;
+
+ chain_desc(std::string &&name, std::string &&path)
+ : m_name(std::move(name))
+ , m_path(std::move(path))
{
}
- screen_prim(render_primitive *prim);
-
- render_primitive *m_prim;
- uint16_t m_screen_width;
- uint16_t m_screen_height;
- uint16_t m_quad_width;
- uint16_t m_quad_height;
- float m_tex_width;
- float m_tex_height;
- int m_rowpixels;
- uint32_t m_palette_length;
- uint32_t m_flags;
+ std::string m_name;
+ std::string m_path;
};
-private:
void load_chains();
void destroy_chains();
void reload_chains();
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);
- void parse_chain_selections(std::string chain_str);
- std::vector<std::string> split_option_string(std::string chain_str) const;
+ void find_available_chains(std::string_view root, std::string_view path);
+ void parse_chain_selections(std::string_view chain_str);
+ std::vector<std::string_view> split_option_string(std::string_view chain_str) const;
void update_screen_count(uint32_t screen_count);
+ void set_current_chain(uint32_t screen, int32_t chain_index);
int32_t slider_changed(int id, std::string *str, int32_t newval);
void create_selection_slider(uint32_t screen_index);
bool needs_sliders();
@@ -118,13 +130,16 @@ private:
void process_screen_quad(uint32_t view, uint32_t screen, screen_prim &prim, osd_window& window);
running_machine& m_machine;
- osd_options& m_options;
+ const osd_options& m_options;
texture_manager& m_textures;
target_manager& m_targets;
effect_manager& m_effects;
uint32_t m_window_index;
+ uint16_t m_user_prescale;
+ uint16_t m_max_prescale_size;
slider_dirty_notifier& m_slider_notifier;
uint32_t m_screen_count;
+ int32_t m_default_chain_index;
std::vector<chain_desc> m_available_chains;
std::vector<bgfx_chain*> m_screen_chains;
std::vector<std::string> m_chain_names;
@@ -138,7 +153,7 @@ private:
std::vector<screen_prim> m_screen_prims;
std::vector<uint8_t> m_palette_temp;
- static const uint32_t CHAIN_NONE;
+ static inline constexpr uint32_t CHAIN_NONE = 0;
};
-#endif // __DRAWBGFX_CHAIN_MANAGER__
+#endif // MAME_RENDER_BGFX_CHAINMANAGER_H
diff --git a/src/osd/modules/render/bgfx/chainreader.cpp b/src/osd/modules/render/bgfx/chainreader.cpp
index 92e30df0b33..362baa42c82 100644
--- a/src/osd/modules/render/bgfx/chainreader.cpp
+++ b/src/osd/modules/render/bgfx/chainreader.cpp
@@ -8,21 +8,26 @@
#include "chainreader.h"
-#include <string>
-#include <vector>
-#include <map>
-
#include "chain.h"
+#include "chainentryreader.h"
#include "chainmanager.h"
-#include "sliderreader.h"
+#include "parameter.h"
#include "paramreader.h"
-#include "chainentryreader.h"
-#include "targetreader.h"
-#include "targetmanager.h"
#include "slider.h"
-#include "parameter.h"
+#include "sliderreader.h"
+#include "targetmanager.h"
+#include "targetreader.h"
+
+#include <vector>
+#include <map>
-bgfx_chain* chain_reader::read_from_value(const Value& value, std::string prefix, chain_manager& chains, uint32_t screen_index)
+std::unique_ptr<bgfx_chain> chain_reader::read_from_value(
+ const Value& value,
+ const std::string &prefix,
+ chain_manager& chains,
+ uint32_t screen_index,
+ uint16_t user_prescale,
+ uint16_t max_prescale_size)
{
if (!validate_parameters(value, prefix))
{
@@ -96,7 +101,7 @@ bgfx_chain* chain_reader::read_from_value(const Value& value, std::string prefix
// TODO: Move into its own reader
for (uint32_t i = 0; i < target_array.Size(); i++)
{
- bgfx_target* target = target_reader::read_from_value(target_array[i], prefix + "targets[" + std::to_string(i) + "]: ", chains, screen_index);
+ bgfx_target* target = target_reader::read_from_value(target_array[i], prefix + "targets[" + std::to_string(i) + "]: ", chains, screen_index, user_prescale, max_prescale_size);
if (target == nullptr)
{
return nullptr;
@@ -121,19 +126,28 @@ bgfx_chain* chain_reader::read_from_value(const Value& value, std::string prefix
}
}
- return new bgfx_chain(name, author, transform, chains.targets(), sliders, parameters, entries, target_list, screen_index);
+ return std::make_unique<bgfx_chain>(
+ std::move(name),
+ std::move(author),
+ transform,
+ chains.targets(),
+ std::move(sliders),
+ std::move(parameters),
+ std::move(entries),
+ std::move(target_list),
+ screen_index);
}
-bool chain_reader::validate_parameters(const Value& value, std::string prefix)
+bool chain_reader::validate_parameters(const Value& value, const std::string &prefix)
{
- if (!READER_CHECK(value.HasMember("name"), (prefix + "Must have string value 'name'\n").c_str())) return false;
- if (!READER_CHECK(value["name"].IsString(), (prefix + "Value 'name' must be a string\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("author"), (prefix + "Must have string value 'author'\n").c_str())) return false;
- if (!READER_CHECK(value["author"].IsString(), (prefix + "Value 'author' must be a string\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("passes"), (prefix + "Must have array value 'passes'\n").c_str())) return false;
- if (!READER_CHECK(value["passes"].IsArray(), (prefix + "Value 'passes' must be an array\n").c_str())) return false;
- if (!READER_CHECK(!value.HasMember("sliders") || value["sliders"].IsArray(), (prefix + "Value 'sliders' must be an array\n").c_str())) return false;
- if (!READER_CHECK(!value.HasMember("parameters") || value["parameters"].IsArray(), (prefix + "Value 'parameters' must be an array\n").c_str())) return false;
- if (!READER_CHECK(!value.HasMember("targets") || value["targets"].IsArray(), (prefix + "Value 'targets' must be an array\n").c_str())) return false;
+ if (!READER_CHECK(value.HasMember("name"), "%sMust have string value 'name'\n", prefix)) return false;
+ if (!READER_CHECK(value["name"].IsString(), "%sValue 'name' must be a string\n", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("author"), "%sMust have string value 'author'\n", prefix)) return false;
+ if (!READER_CHECK(value["author"].IsString(), "%sValue 'author' must be a string\n", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("passes"), "%sMust have array value 'passes'\n", prefix)) return false;
+ if (!READER_CHECK(value["passes"].IsArray(), "%sValue 'passes' must be an array\n", prefix)) return false;
+ if (!READER_CHECK(!value.HasMember("sliders") || value["sliders"].IsArray(), "%sValue 'sliders' must be an array\n", prefix)) return false;
+ if (!READER_CHECK(!value.HasMember("parameters") || value["parameters"].IsArray(), "%sValue 'parameters' must be an array\n", prefix)) return false;
+ if (!READER_CHECK(!value.HasMember("targets") || value["targets"].IsArray(), "%sValue 'targets' must be an array\n", prefix)) return false;
return true;
}
diff --git a/src/osd/modules/render/bgfx/chainreader.h b/src/osd/modules/render/bgfx/chainreader.h
index a2fa3ba28a5..6bbd2058501 100644
--- a/src/osd/modules/render/bgfx/chainreader.h
+++ b/src/osd/modules/render/bgfx/chainreader.h
@@ -6,23 +6,26 @@
//
//============================================================
-#pragma once
+#ifndef MAME_RENDER_BGFX_CHAINREADER_H
+#define MAME_RENDER_BGFX_CHAINREADER_H
-#ifndef __DRAWBGFX_CHAIN_READER__
-#define __DRAWBGFX_CHAIN_READER__
+#pragma once
#include "statereader.h"
+#include <memory>
+#include <string>
+
class bgfx_chain;
class chain_manager;
class chain_reader : public state_reader
{
public:
- static bgfx_chain* read_from_value(const Value& value, std::string prefix, chain_manager& chains, uint32_t screen_index);
+ static std::unique_ptr<bgfx_chain> read_from_value(const Value& value, const std::string &prefix, chain_manager& chains, uint32_t screen_index, uint16_t user_prescale, uint16_t max_prescale_size);
private:
- static bool validate_parameters(const Value& value, std::string prefix);
+ static bool validate_parameters(const Value& value, const std::string &prefix);
};
-#endif // __DRAWBGFX_CHAIN_READER__
+#endif // MAME_RENDER_BGFX_CHAINREADER_H
diff --git a/src/osd/modules/render/bgfx/clearreader.cpp b/src/osd/modules/render/bgfx/clearreader.cpp
index 948d96a7393..58c4d5f01aa 100644
--- a/src/osd/modules/render/bgfx/clearreader.cpp
+++ b/src/osd/modules/render/bgfx/clearreader.cpp
@@ -6,13 +6,15 @@
//
//============================================================
-#include <bgfx/bgfx.h>
-
#include "clearreader.h"
#include "clear.h"
-clear_state* clear_reader::read_from_value(const Value& value, std::string prefix)
+#include <bgfx/bgfx.h>
+
+#include <algorithm>
+
+clear_state* clear_reader::read_from_value(const Value& value, const std::string &prefix)
{
if (!validate_parameters(value, prefix))
{
@@ -29,10 +31,8 @@ clear_state* clear_reader::read_from_value(const Value& value, std::string prefi
const Value& colors = value["clearcolor"];
for (int i = 0; i < colors.Size(); i++)
{
- if (!READER_CHECK(colors[i].IsNumber(), (prefix + "clearcolor[" + std::to_string(i) + "] must be a numeric value\n").c_str())) return nullptr;
- auto val = int32_t(float(colors[i].GetDouble()) * 255.0f);
- if (val > 255) val = 255;
- if (val < 0) val = 0;
+ if (!READER_CHECK(colors[i].IsNumber(), "%sclearcolor[%d] must be a numeric value\n", prefix, i)) return nullptr;
+ auto val = std::clamp<int32_t>(float(colors[i].GetDouble()) * 255.0f, 0, 255);
clear_color |= val << (24 - (i * 3));
}
clear_flags |= BGFX_CLEAR_COLOR;
@@ -53,10 +53,10 @@ clear_state* clear_reader::read_from_value(const Value& value, std::string prefi
return new clear_state(clear_flags, clear_color, clear_depth, clear_stencil);
}
-bool clear_reader::validate_parameters(const Value& value, std::string prefix)
+bool clear_reader::validate_parameters(const Value& value, const std::string &prefix)
{
- if (!READER_CHECK(!value.HasMember("clearcolor") || (value["clearcolor"].IsArray() && value["clearcolor"].GetArray().Size() == 4), (prefix + "'clearcolor' must be an array of four numeric RGBA values representing the color to which to clear the color buffer\n").c_str())) return false;
- if (!READER_CHECK(!value.HasMember("cleardepth") || value["cleardepth"].IsNumber(), (prefix + "'cleardepth' must be a numeric value representing the depth to which to clear the depth buffer\n").c_str())) return false;
- if (!READER_CHECK(!value.HasMember("clearstencil") || value["clearstencil"].IsNumber(), (prefix + "'clearstencil' must be a numeric value representing the stencil value to which to clear the stencil buffer\n").c_str())) return false;
+ if (!READER_CHECK(!value.HasMember("clearcolor") || (value["clearcolor"].IsArray() && value["clearcolor"].GetArray().Size() == 4), "%s'clearcolor' must be an array of four numeric RGBA values representing the color to which to clear the color buffer\n", prefix)) return false;
+ if (!READER_CHECK(!value.HasMember("cleardepth") || value["cleardepth"].IsNumber(), "%s'cleardepth' must be a numeric value representing the depth to which to clear the depth buffer\n", prefix)) return false;
+ if (!READER_CHECK(!value.HasMember("clearstencil") || value["clearstencil"].IsNumber(), "%s'clearstencil' must be a numeric value representing the stencil value to which to clear the stencil buffer\n", prefix)) return false;
return true;
}
diff --git a/src/osd/modules/render/bgfx/clearreader.h b/src/osd/modules/render/bgfx/clearreader.h
index 80605ea35f3..1c2063e95de 100644
--- a/src/osd/modules/render/bgfx/clearreader.h
+++ b/src/osd/modules/render/bgfx/clearreader.h
@@ -6,26 +6,26 @@
//
//============================================================
+#ifndef MAME_RENDER_BGFX_CLEARREADER_H
+#define MAME_RENDER_BGFX_CLEARREADER_H
+
#pragma once
-#ifndef __DRAWBGFX_CLEAR_READER__
-#define __DRAWBGFX_CLEAR_READER__
+#include "statereader.h"
#include <string>
-#include "statereader.h"
-
class clear_state;
class clear_reader : public state_reader {
public:
- static clear_state* read_from_value(const Value& value, std::string prefix);
+ static clear_state* read_from_value(const Value& value, const std::string &prefix);
private:
- static bool validate_parameters(const Value& value, std::string prefix);
+ static bool validate_parameters(const Value& value, const std::string &prefix);
static const int FLAG_COUNT = 3;
static const string_to_enum FLAG_NAMES[FLAG_COUNT];
};
-#endif // __DRAWBGFX_CLEAR_READER__
+#endif // MAME_RENDER_BGFX_CLEARREADER_H
diff --git a/src/osd/modules/render/bgfx/depthreader.cpp b/src/osd/modules/render/bgfx/depthreader.cpp
index 97502d9028e..bcfc568b0da 100644
--- a/src/osd/modules/render/bgfx/depthreader.cpp
+++ b/src/osd/modules/render/bgfx/depthreader.cpp
@@ -6,10 +6,10 @@
//
//============================================================
-#include <bgfx/bgfx.h>
-
#include "depthreader.h"
+#include <bgfx/bgfx.h>
+
const depth_reader::string_to_enum depth_reader::FUNCTION_NAMES[depth_reader::FUNCTION_COUNT] = {
{ "never", BGFX_STATE_DEPTH_TEST_NEVER },
{ "less", BGFX_STATE_DEPTH_TEST_LESS },
@@ -21,12 +21,12 @@ const depth_reader::string_to_enum depth_reader::FUNCTION_NAMES[depth_reader::FU
{ "always", BGFX_STATE_DEPTH_TEST_ALWAYS }
};
-uint64_t depth_reader::read_from_value(const Value& value, std::string prefix)
+uint64_t depth_reader::read_from_value(const Value& value, const std::string &prefix)
{
uint64_t write_enable = 0;
if (value.HasMember("writeenable"))
{
- if (!READER_CHECK(value["writeenable"].IsBool(), (prefix + "Value 'writeenable' must be a boolean\n").c_str())) return 0;
+ if (!READER_CHECK(value["writeenable"].IsBool(), "%sValue 'writeenable' must be a boolean\n", prefix)) return 0;
write_enable = value["writeenable"].GetBool() ? BGFX_STATE_WRITE_Z : 0;
}
diff --git a/src/osd/modules/render/bgfx/depthreader.h b/src/osd/modules/render/bgfx/depthreader.h
index 9e2c99a0b29..0815732850f 100644
--- a/src/osd/modules/render/bgfx/depthreader.h
+++ b/src/osd/modules/render/bgfx/depthreader.h
@@ -6,10 +6,10 @@
//
//============================================================
-#pragma once
+#ifndef MAME_RENDER_BGFX_DEPTHREADER_H
+#define MAME_RENDER_BGFX_DEPTHREADER_H
-#ifndef __DRAWBGFX_DEPTH_READER__
-#define __DRAWBGFX_DEPTH_READER__
+#pragma once
#include <string>
@@ -17,11 +17,11 @@
class depth_reader : public state_reader {
public:
- static uint64_t read_from_value(const Value& value, std::string prefix);
+ static uint64_t read_from_value(const Value& value, const std::string &prefix);
private:
static const int FUNCTION_COUNT = 8;
static const string_to_enum FUNCTION_NAMES[FUNCTION_COUNT];
};
-#endif // __DRAWBGFX_DEPTH_READER__
+#endif // MAME_RENDER_BGFX_DEPTHREADER_H
diff --git a/src/osd/modules/render/bgfx/effect.cpp b/src/osd/modules/render/bgfx/effect.cpp
index c5ea8555dce..18b43cca9bf 100644
--- a/src/osd/modules/render/bgfx/effect.cpp
+++ b/src/osd/modules/render/bgfx/effect.cpp
@@ -13,46 +13,50 @@
#include "modules/osdmodule.h"
#include "osdcore.h"
-bgfx_effect::bgfx_effect(uint64_t state, bgfx::ShaderHandle vertex_shader, bgfx::ShaderHandle fragment_shader, std::vector<bgfx_uniform*> uniforms)
- : m_state(state)
+#include <utility>
+
+
+bgfx_effect::bgfx_effect(std::string &&name, uint64_t state, bgfx::ShaderHandle vertex_shader, bgfx::ShaderHandle fragment_shader, std::vector<std::unique_ptr<bgfx_uniform> > &uniforms)
+ : m_name(std::move(name))
+ , m_state(state)
{
m_program_handle = bgfx::createProgram(vertex_shader, fragment_shader, false);
- for (int i = 0; i < uniforms.size(); i++)
+ for (auto &uniform : uniforms)
{
- if (m_uniforms[uniforms[i]->name()] != nullptr)
+ const auto existing = m_uniforms.find(uniform->name());
+ if (existing != m_uniforms.end())
{
- 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());
- delete uniforms[i];
+ osd_printf_verbose("Uniform %s appears to be duplicated in one or more effects, please double-check the effect JSON files.\n", uniform->name());
+ uniform.reset();
continue;
}
- uniforms[i]->create();
- m_uniforms[uniforms[i]->name()] = uniforms[i];
+ uniform->create();
+ m_uniforms.emplace(uniform->name(), std::move(uniform));
}
}
bgfx_effect::~bgfx_effect()
{
- for (std::pair<std::string, bgfx_uniform*> uniform : m_uniforms)
- {
- delete uniform.second;
- }
m_uniforms.clear();
bgfx::destroy(m_program_handle);
}
void bgfx_effect::submit(int view, uint64_t blend)
{
- for (std::pair<std::string, bgfx_uniform*> uniform_pair : m_uniforms)
+ for (auto &[name, uniform] : m_uniforms)
{
- (uniform_pair.second)->upload();
+ uniform->upload();
}
- bgfx::setState(m_state | blend);
+
+ const uint64_t final_state = (blend != ~0ULL) ? ((m_state & ~BGFX_STATE_BLEND_MASK) | blend) : m_state;
+
+ bgfx::setState(final_state);
bgfx::submit(view, m_program_handle);
}
-bgfx_uniform* bgfx_effect::uniform(std::string name)
+bgfx_uniform* bgfx_effect::uniform(const std::string &name)
{
- auto iter = m_uniforms.find(name);
- return iter != m_uniforms.end() ? iter->second : nullptr;
+ const auto iter = m_uniforms.find(name);
+ return (iter != m_uniforms.end()) ? iter->second.get() : nullptr;
}
diff --git a/src/osd/modules/render/bgfx/effect.h b/src/osd/modules/render/bgfx/effect.h
index ca1be77c73d..07646e6302e 100644
--- a/src/osd/modules/render/bgfx/effect.h
+++ b/src/osd/modules/render/bgfx/effect.h
@@ -6,33 +6,36 @@
//
//============================================================
-#pragma once
+#ifndef MAME_RENDER_BGFX_EFFECT_H
+#define MAME_RENDER_BGFX_EFFECT_H
-#ifndef __DRAWBGFX_EFFECT__
-#define __DRAWBGFX_EFFECT__
+#pragma once
#include <bgfx/bgfx.h>
-#include <vector>
#include <map>
+#include <memory>
#include <string>
+#include <vector>
+
class bgfx_uniform;
class bgfx_effect
{
public:
- bgfx_effect(uint64_t state, bgfx::ShaderHandle vertex_shader, bgfx::ShaderHandle fragment_shader, std::vector<bgfx_uniform*> uniforms);
+ bgfx_effect(std::string &&name, uint64_t state, bgfx::ShaderHandle vertex_shader, bgfx::ShaderHandle fragment_shader, std::vector<std::unique_ptr<bgfx_uniform> > &uniforms);
~bgfx_effect();
- void submit(int view, uint64_t blend = 0L);
- bgfx_uniform *uniform(std::string name);
- bool is_valid() { return m_program_handle.idx != bgfx::kInvalidHandle; }
+ void submit(int view, uint64_t blend = ~0ULL);
+ bgfx_uniform *uniform(const std::string &name);
+ bool is_valid() const { return m_program_handle.idx != bgfx::kInvalidHandle; }
private:
+ std::string m_name;
uint64_t m_state;
bgfx::ProgramHandle m_program_handle;
- std::map<std::string, bgfx_uniform*> m_uniforms;
+ std::map<std::string, std::unique_ptr<bgfx_uniform> > m_uniforms;
};
-#endif // __DRAWBGFX_EFFECT__
+#endif // MAME_RENDER_BGFX_EFFECT_H
diff --git a/src/osd/modules/render/bgfx/effectmanager.cpp b/src/osd/modules/render/bgfx/effectmanager.cpp
index f57f56f708d..e5e5d1698f6 100644
--- a/src/osd/modules/render/bgfx/effectmanager.cpp
+++ b/src/osd/modules/render/bgfx/effectmanager.cpp
@@ -11,8 +11,11 @@
#include "effectmanager.h"
-#include "effectreader.h"
#include "effect.h"
+#include "effectreader.h"
+#include "shadermanager.h"
+
+#include "path.h"
#include "osdfile.h"
#include "modules/lib/osdobj_common.h"
@@ -25,66 +28,75 @@
#include <bgfx/bgfx.h>
-static bool prepare_effect_document(std::string &name, osd_options &options, rapidjson::Document &document)
+#include <utility>
+
+
+static bool prepare_effect_document(const std::string &name, const osd_options &options, rapidjson::Document &document)
{
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";
+ full_name += ".json";
}
- std::string path = osd_subst_env(util::string_format("%s" PATH_SEPARATOR "effects" PATH_SEPARATOR, options.bgfx_path()));
- path += full_name;
+ const std::string path = util::path_concat(options.bgfx_path(), "effects", full_name);
bx::FileReader reader;
if (!bx::open(&reader, path.c_str()))
{
- osd_printf_error("Unable to open effect file %s\n", path.c_str());
+ osd_printf_error("Unable to open effect file %s\n", path);
return false;
}
- int32_t size (bx::getSize(&reader));
- char* data = new char[size + 1];
- bx::read(&reader, reinterpret_cast<void*>(data), size);
+ const int32_t size = bx::getSize(&reader);
+ std::unique_ptr<char []> data(new (std::nothrow) char [size + 1]);
+ if (!data)
+ {
+ osd_printf_error("Out of memory reading effect file %s\n", path);
+ bx::close(&reader);
+ return false;
+ }
+
+ bx::ErrorAssert err;
+ bx::read(&reader, reinterpret_cast<void*>(data.get()), size, &err);
bx::close(&reader);
data[size] = 0;
- document.Parse<rapidjson::kParseCommentsFlag>(data);
-
- delete [] data;
+ document.Parse<rapidjson::kParseCommentsFlag>(data.get());
+ data.reset();
if (document.HasParseError())
{
std::string error(rapidjson::GetParseError_En(document.GetParseError()));
- osd_printf_error("Unable to parse effect %s. Errors returned:\n", path.c_str());
- osd_printf_error("%s\n", error.c_str());
+ osd_printf_error("Unable to parse effect %s. Errors returned:\n%s\n", path, error);
return false;
}
return true;
}
+
+// keep constructor and destructor out-of-line so the header works with forward declarations
+
+effect_manager::effect_manager(shader_manager& shaders) : m_shaders(shaders)
+{
+}
+
effect_manager::~effect_manager()
{
- for (std::pair<std::string, bgfx_effect*> effect : m_effects)
- {
- delete effect.second;
- }
- m_effects.clear();
+ // the map will automatically dispose of the effects
}
-bgfx_effect* effect_manager::get_or_load_effect(osd_options &options, std::string name)
+bgfx_effect* effect_manager::get_or_load_effect(const osd_options &options, const std::string &name)
{
- std::map<std::string, bgfx_effect*>::iterator iter = m_effects.find(name);
+ const auto iter = m_effects.find(name);
if (iter != m_effects.end())
- {
- return iter->second;
- }
+ return iter->second.get();
return load_effect(options, name);
}
-bgfx_effect* effect_manager::load_effect(osd_options &options, std::string name)
+bgfx_effect* effect_manager::load_effect(const osd_options &options, const std::string &name)
{
rapidjson::Document document;
if (!prepare_effect_document(name, options, document))
@@ -92,20 +104,18 @@ bgfx_effect* effect_manager::load_effect(osd_options &options, std::string name)
return nullptr;
}
- bgfx_effect* effect = effect_reader::read_from_value(document, "Effect '" + name + "': ", options, m_shaders);
+ std::unique_ptr<bgfx_effect> effect = effect_reader::read_from_value(name, document, "Effect '" + name + "': ", options, m_shaders);
- if (effect == nullptr)
+ if (!effect)
{
- osd_printf_error("Unable to load effect %s\n", name.c_str());
+ osd_printf_error("Unable to load effect %s\n", name);
return nullptr;
}
- m_effects[name] = effect;
-
- return effect;
+ return m_effects.emplace(name, std::move(effect)).first->second.get();
}
-bool effect_manager::validate_effect(osd_options &options, std::string name)
+bool effect_manager::validate_effect(const osd_options &options, const std::string &name)
{
rapidjson::Document document;
if (!prepare_effect_document(name, options, document))
diff --git a/src/osd/modules/render/bgfx/effectmanager.h b/src/osd/modules/render/bgfx/effectmanager.h
index 5d8bf3f5c93..697d468dc5c 100644
--- a/src/osd/modules/render/bgfx/effectmanager.h
+++ b/src/osd/modules/render/bgfx/effectmanager.h
@@ -9,34 +9,35 @@
//
//============================================================
-#pragma once
+#ifndef MAME_RENDER_BGFX_EFFECTMANAGER_H
+#define MAME_RENDER_BGFX_EFFECTMANAGER_H
-#ifndef __DRAWBGFX_EFFECT_MANAGER__
-#define __DRAWBGFX_EFFECT_MANAGER__
+#pragma once
#include <map>
+#include <memory>
#include <string>
-#include <bgfx/bgfx.h>
-
-#include "shadermanager.h"
class bgfx_effect;
+class osd_options;
+class shader_manager;
-class effect_manager {
+class effect_manager
+{
public:
- effect_manager(shader_manager& shaders) : m_shaders(shaders) { }
+ effect_manager(shader_manager& shaders);
~effect_manager();
// Getters
- bgfx_effect* get_or_load_effect(osd_options &options, std::string name);
- static bool validate_effect(osd_options &options, std::string name);
+ bgfx_effect* get_or_load_effect(const osd_options &options, const std::string &name);
+ static bool validate_effect(const osd_options &options, const std::string &name);
private:
- bgfx_effect* load_effect(osd_options& options, std::string name);
+ bgfx_effect* load_effect(const osd_options &options, const std::string &name);
- shader_manager& m_shaders;
- std::map<std::string, bgfx_effect*> m_effects;
+ shader_manager &m_shaders;
+ std::map<std::string, std::unique_ptr<bgfx_effect> > m_effects;
};
-#endif // __DRAWBGFX_EFFECT_MANAGER__
+#endif // MAME_RENDER_BGFX_EFFECTMANAGER_H
diff --git a/src/osd/modules/render/bgfx/effectreader.cpp b/src/osd/modules/render/bgfx/effectreader.cpp
index 36acee2f9ea..befdc598537 100644
--- a/src/osd/modules/render/bgfx/effectreader.cpp
+++ b/src/osd/modules/render/bgfx/effectreader.cpp
@@ -8,80 +8,79 @@
#include "effectreader.h"
-#include "effect.h"
#include "blendreader.h"
-#include "depthreader.h"
#include "cullreader.h"
-#include "writereader.h"
+#include "depthreader.h"
+#include "effect.h"
#include "shadermanager.h"
-#include "uniformreader.h"
#include "uniform.h"
+#include "uniformreader.h"
+#include "writereader.h"
-bgfx_effect *effect_reader::read_from_value(const Value& value, std::string prefix, osd_options &options, shader_manager& shaders)
+#include <utility>
+
+
+std::unique_ptr<bgfx_effect> effect_reader::read_from_value(
+ const std::string &name,
+ const Value &value,
+ const std::string &prefix,
+ const osd_options &options,
+ shader_manager &shaders)
{
uint64_t flags = 0;
std::string vertex_name;
std::string fragment_name;
- bgfx::ShaderHandle vertex_shader = BGFX_INVALID_HANDLE;
- bgfx::ShaderHandle fragment_shader = BGFX_INVALID_HANDLE;
- std::vector<bgfx_uniform *> uniforms;
+ std::vector<std::unique_ptr<bgfx_uniform> > uniforms;
if (!get_base_effect_data(value, prefix, flags, vertex_name, fragment_name, uniforms))
{
return nullptr;
}
+ bgfx::ShaderHandle vertex_shader = BGFX_INVALID_HANDLE;
+ bgfx::ShaderHandle fragment_shader = BGFX_INVALID_HANDLE;
+
if (!get_shader_data(value, options, shaders, vertex_name, vertex_shader, fragment_name, fragment_shader))
{
- clear_uniform_list(uniforms);
return nullptr;
}
- bgfx_effect *effect = new bgfx_effect(flags, vertex_shader, fragment_shader, uniforms);
- if (effect->is_valid())
- {
- return effect;
- }
-
- delete effect;
+ std::unique_ptr<bgfx_effect> effect(new bgfx_effect(std::string(name), flags, vertex_shader, fragment_shader, uniforms));
+ if (!effect->is_valid())
+ return nullptr;
- return nullptr;
+ return effect;
}
-bool effect_reader::validate_value(const Value& value, std::string prefix, osd_options &options)
+bool effect_reader::validate_value(const Value& value, const std::string &prefix, const osd_options &options)
{
if (!validate_parameters(value, prefix))
- {
return false;
- }
uint64_t flags = 0;
std::string vertex_name;
std::string fragment_name;
- std::vector<bgfx_uniform *> uniforms;
+ std::vector<std::unique_ptr<bgfx_uniform> > uniforms;
if (!get_base_effect_data(value, prefix, flags, vertex_name, fragment_name, uniforms))
- {
return false;
- }
if (!shader_manager::is_shader_present(options, vertex_name))
- {
- clear_uniform_list(uniforms);
return false;
- }
if (!shader_manager::is_shader_present(options, fragment_name))
- {
- clear_uniform_list(uniforms);
return false;
- }
return true;
}
-bool effect_reader::get_base_effect_data(const Value& value, std::string &prefix, uint64_t &flags, std::string &vertex_name, std::string &fragment_name,
- std::vector<bgfx_uniform *> &uniforms)
+bool effect_reader::get_base_effect_data(
+ const Value& value,
+ const std::string &prefix,
+ uint64_t &flags,
+ std::string &vertex_name,
+ std::string &fragment_name,
+ std::vector<std::unique_ptr<bgfx_uniform> > &uniforms)
{
if (!validate_parameters(value, prefix))
{
@@ -101,12 +100,12 @@ bool effect_reader::get_base_effect_data(const Value& value, std::string &prefix
const Value& uniform_array = value["uniforms"];
for (uint32_t i = 0; i < uniform_array.Size(); i++)
{
- bgfx_uniform *uniform = uniform_reader::read_from_value(uniform_array[i], prefix + "uniforms[" + std::to_string(i) + "]: ");
- if (uniform == nullptr)
+ auto uniform = uniform_reader::read_from_value(uniform_array[i], prefix + "uniforms[" + std::to_string(i) + "]: ");
+ if (!uniform)
{
return false;
}
- uniforms.push_back(uniform);
+ uniforms.emplace_back(std::move(uniform));
}
vertex_name = value["vertex"].GetString();
@@ -127,8 +126,14 @@ bool effect_reader::get_base_effect_data(const Value& value, std::string &prefix
return true;
}
-bool effect_reader::get_shader_data(const Value& value, osd_options &options, shader_manager &shaders, std::string &vertex_name, bgfx::ShaderHandle &vertex_shader,
- std::string &fragment_name, bgfx::ShaderHandle &fragment_shader)
+bool effect_reader::get_shader_data(
+ const Value &value,
+ const osd_options &options,
+ shader_manager &shaders,
+ std::string &vertex_name,
+ bgfx::ShaderHandle &vertex_shader,
+ std::string &fragment_name,
+ bgfx::ShaderHandle &fragment_shader)
{
vertex_shader = shaders.load_shader(options, vertex_name);
if (vertex_shader.idx == bgfx::kInvalidHandle)
@@ -145,25 +150,17 @@ bool effect_reader::get_shader_data(const Value& value, osd_options &options, sh
return true;
}
-void effect_reader::clear_uniform_list(std::vector<bgfx_uniform *> &uniforms)
-{
- for (bgfx_uniform *uniform : uniforms)
- {
- delete uniform;
- }
-}
-
-bool effect_reader::validate_parameters(const Value& value, std::string prefix)
+bool effect_reader::validate_parameters(const Value& value, const std::string &prefix)
{
- if (!READER_CHECK(value.HasMember("depth"), (prefix + "Must have object value 'depth' (what are our Z-buffer settings?)\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("cull"), (prefix + "Must have object value 'cull' (do we cull triangles based on winding?)\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("write"), (prefix + "Must have object value 'write' (what are our color buffer write settings?)\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("vertex"), (prefix + "Must have string value 'vertex' (what is our vertex shader?)\n").c_str())) return false;
- if (!READER_CHECK(value["vertex"].IsString(), (prefix + "Value 'vertex' must be a string\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("fragment") || value.HasMember("pixel"), (prefix + "Must have string value named 'fragment' or 'pixel' (what is our fragment/pixel shader?)\n").c_str())) return false;
- if (!READER_CHECK(!value.HasMember("fragment") || value["fragment"].IsString(), (prefix + "Value 'fragment' must be a string\n").c_str())) return false;
- if (!READER_CHECK(!value.HasMember("pixel") || value["pixel"].IsString(), (prefix + "Value 'pixel' must be a string\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("uniforms"), (prefix + "Must have array value 'uniforms' (what are our shader's parameters?)\n").c_str())) return false;
- if (!READER_CHECK(value["uniforms"].IsArray(), (prefix + "Value 'uniforms' must be an array\n").c_str())) return false;
+ if (!READER_CHECK(value.HasMember("depth"), "%sMust have object value 'depth' (what are our Z-buffer settings?)\n", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("cull"), "%sMust have object value 'cull' (do we cull triangles based on winding?)\n", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("write"), "%sMust have object value 'write' (what are our color buffer write settings?)\n", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("vertex"), "%sMust have string value 'vertex' (what is our vertex shader?)\n", prefix)) return false;
+ if (!READER_CHECK(value["vertex"].IsString(), "%sValue 'vertex' must be a string\n", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("fragment") || value.HasMember("pixel"), "%sMust have string value named 'fragment' or 'pixel' (what is our fragment/pixel shader?)\n", prefix)) return false;
+ if (!READER_CHECK(!value.HasMember("fragment") || value["fragment"].IsString(), "%sValue 'fragment' must be a string\n", prefix)) return false;
+ if (!READER_CHECK(!value.HasMember("pixel") || value["pixel"].IsString(), "%sValue 'pixel' must be a string\n", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("uniforms"), "%sMust have array value 'uniforms' (what are our shader's parameters?)\n", prefix)) return false;
+ if (!READER_CHECK(value["uniforms"].IsArray(), "%sValue 'uniforms' must be an array\n", prefix)) return false;
return true;
}
diff --git a/src/osd/modules/render/bgfx/effectreader.h b/src/osd/modules/render/bgfx/effectreader.h
index 095f06a56ea..db590e5eeb3 100644
--- a/src/osd/modules/render/bgfx/effectreader.h
+++ b/src/osd/modules/render/bgfx/effectreader.h
@@ -6,36 +6,38 @@
//
//============================================================
-#pragma once
+#ifndef MAME_RENDER_BGFX_EFFECTREADER_H
+#define MAME_RENDER_BGFX_EFFECTREADER_H
-#ifndef __DRAWBGFX_EFFECT_READER__
-#define __DRAWBGFX_EFFECT_READER__
+#pragma once
#include "statereader.h"
#include <bgfx/bgfx.h>
+#include <memory>
#include <string>
#include <vector>
+
class bgfx_effect;
class bgfx_uniform;
class osd_options;
class shader_manager;
+
class effect_reader : public state_reader
{
public:
- static bgfx_effect *read_from_value(const Value& value, std::string prefix, osd_options &options, shader_manager& shaders);
- static bool validate_value(const Value& value, std::string prefix, osd_options &options);
+ static std::unique_ptr<bgfx_effect> read_from_value(const std::string &name, const Value& value, const std::string &prefix, const osd_options &options, shader_manager& shaders);
+ static bool validate_value(const Value& value, const std::string &prefix, const osd_options &options);
private:
- static bool get_base_effect_data(const Value& value, std::string &prefix, uint64_t &flags, std::string &vertex_name, std::string &fragment_name,
- std::vector<bgfx_uniform *> &uniforms);
- static bool get_shader_data(const Value& value, osd_options &options, shader_manager &shaders, std::string &vertex_name, bgfx::ShaderHandle &vertex_shader,
+ static bool get_base_effect_data(const Value& value, const std::string &prefix, uint64_t &flags, std::string &vertex_name, std::string &fragment_name,
+ std::vector<std::unique_ptr<bgfx_uniform> > &uniforms);
+ static bool get_shader_data(const Value& value, const osd_options &options, shader_manager &shaders, std::string &vertex_name, bgfx::ShaderHandle &vertex_shader,
std::string &fragment_name, bgfx::ShaderHandle &fragment_shader);
- static void clear_uniform_list(std::vector<bgfx_uniform *> &uniforms);
- static bool validate_parameters(const Value& value, std::string prefix);
+ static bool validate_parameters(const Value& value, const std::string &prefix);
};
-#endif // __DRAWBGFX_EFFECT_READER__
+#endif // MAME_RENDER_BGFX_EFFECTREADER_H
diff --git a/src/osd/modules/render/bgfx/entryuniform.h b/src/osd/modules/render/bgfx/entryuniform.h
index 9c1462f360f..88ccc3e536d 100644
--- a/src/osd/modules/render/bgfx/entryuniform.h
+++ b/src/osd/modules/render/bgfx/entryuniform.h
@@ -9,15 +9,15 @@
//
//============================================================
+#ifndef MAME_RENDER_BGFX_ENTRYUNIFORM_H
+#define MAME_RENDER_BGFX_ENTRYUNIFORM_H
+
#pragma once
-#ifndef DRAWBGFX_ENTRY_UNIFORM
-#define DRAWBGFX_ENTRY_UNIFORM
+#include "uniform.h"
#include <bgfx/bgfx.h>
-#include "uniform.h"
-
class bgfx_entry_uniform
{
public:
@@ -25,10 +25,10 @@ public:
virtual ~bgfx_entry_uniform() { }
virtual void bind() = 0;
- std::string name() const { return m_uniform->name(); }
+ const std::string &name() const { return m_uniform->name(); }
protected:
bgfx_uniform* m_uniform;
};
-#endif // __DRAWBGFX_ENTRY_UNIFORM__
+#endif // MAME_RENDER_BGFX_ENTRYUNIFORM_H
diff --git a/src/osd/modules/render/bgfx/entryuniformreader.cpp b/src/osd/modules/render/bgfx/entryuniformreader.cpp
index 947f4c56e90..62c618f39a7 100644
--- a/src/osd/modules/render/bgfx/entryuniformreader.cpp
+++ b/src/osd/modules/render/bgfx/entryuniformreader.cpp
@@ -15,7 +15,7 @@
#include "paramuniformreader.h"
#include "uniform.h"
-bgfx_entry_uniform* entry_uniform_reader::read_from_value(const Value& value, std::string prefix, bgfx_effect* effect, std::map<std::string, bgfx_slider*>& sliders, std::map<std::string, bgfx_parameter*>& params)
+bgfx_entry_uniform* entry_uniform_reader::read_from_value(const Value& value, const std::string &prefix, bgfx_effect* effect, std::map<std::string, bgfx_slider*>& sliders, std::map<std::string, bgfx_parameter*>& params)
{
if (!validate_parameters(value, prefix))
{
@@ -25,7 +25,7 @@ bgfx_entry_uniform* entry_uniform_reader::read_from_value(const Value& value, st
std::string name = value["uniform"].GetString();
bgfx_uniform* uniform = effect->uniform(name);
- if (!READER_CHECK(uniform != nullptr, (prefix + "Uniform '" + name + " does not appear to exist\n").c_str()))
+ if (!READER_CHECK(uniform != nullptr, "%sUniform '%s' does not appear to exist\n", prefix, name))
{
return nullptr;
}
@@ -44,16 +44,16 @@ bgfx_entry_uniform* entry_uniform_reader::read_from_value(const Value& value, st
}
else
{
- READER_CHECK(false, (prefix + "Unrecognized uniform type for uniform binding " + name).c_str());
+ READER_CHECK(false, "%sUnrecognized uniform type for uniform binding %s", prefix, name);
}
return nullptr;
}
-bool entry_uniform_reader::validate_parameters(const Value& value, std::string prefix)
+bool entry_uniform_reader::validate_parameters(const Value& value, const std::string &prefix)
{
- if (!READER_CHECK(value.HasMember("uniform"), (prefix + "Must have string value 'uniform' (what uniform are we mapping?)\n").c_str())) return false;
- if (!READER_CHECK(value["uniform"].IsString(), (prefix + "Value 'effect' must be a string\n").c_str())) return false;
+ if (!READER_CHECK(value.HasMember("uniform"), "%sMust have string value 'uniform' (what uniform are we mapping?)\n", prefix)) return false;
+ if (!READER_CHECK(value["uniform"].IsString(), "%sValue 'effect' must be a string\n", prefix)) return false;
return true;
}
diff --git a/src/osd/modules/render/bgfx/entryuniformreader.h b/src/osd/modules/render/bgfx/entryuniformreader.h
index 73c66269a5e..c85a2647826 100644
--- a/src/osd/modules/render/bgfx/entryuniformreader.h
+++ b/src/osd/modules/render/bgfx/entryuniformreader.h
@@ -6,16 +6,16 @@
//
//============================================================
+#ifndef MAME_RENDER_BGFX_ENTRYUNIFORMREADER_H
+#define MAME_RENDER_BGFX_ENTRYUNIFORMREADER_H
+
#pragma once
-#ifndef __DRAWBGFX_ENTRY_UNIFORM_READER__
-#define __DRAWBGFX_ENTRY_UNIFORM_READER__
+#include "statereader.h"
#include <string>
#include <map>
-#include "statereader.h"
-
class bgfx_entry_uniform;
class bgfx_slider;
class bgfx_effect;
@@ -24,10 +24,10 @@ class bgfx_parameter;
class entry_uniform_reader : public state_reader
{
public:
- static bgfx_entry_uniform* read_from_value(const Value& value, std::string prefix, bgfx_effect* effect, std::map<std::string, bgfx_slider*>& sliders, std::map<std::string, bgfx_parameter*>& params);
+ static bgfx_entry_uniform* read_from_value(const Value& value, const std::string &prefix, bgfx_effect* effect, std::map<std::string, bgfx_slider*>& sliders, std::map<std::string, bgfx_parameter*>& params);
private:
- static bool validate_parameters(const Value& value, std::string prefix);
+ static bool validate_parameters(const Value& value, const std::string &prefix);
};
-#endif // __DRAWBGFX_ENTRY_UNIFORM_READER__
+#endif // MAME_RENDER_BGFX_ENTRYUNIFORMREADER_H
diff --git a/src/osd/modules/render/bgfx/frameparameter.cpp b/src/osd/modules/render/bgfx/frameparameter.cpp
index 841d4d0d2e5..6b16fe1d5fa 100644
--- a/src/osd/modules/render/bgfx/frameparameter.cpp
+++ b/src/osd/modules/render/bgfx/frameparameter.cpp
@@ -8,8 +8,10 @@
#include "frameparameter.h"
-bgfx_frame_parameter::bgfx_frame_parameter(std::string name, parameter_type type, uint32_t period)
- : bgfx_parameter(name, type)
+#include <utility>
+
+bgfx_frame_parameter::bgfx_frame_parameter(std::string &&name, parameter_type type, uint32_t period)
+ : bgfx_parameter(std::move(name), type)
, m_current_frame(0)
, m_period(period)
{
@@ -20,7 +22,7 @@ float bgfx_frame_parameter::value()
return float(m_current_frame);
}
-void bgfx_frame_parameter::tick(double /*delta*/)
+void bgfx_frame_parameter::tick(double delta)
{
m_current_frame++;
m_current_frame %= m_period;
diff --git a/src/osd/modules/render/bgfx/frameparameter.h b/src/osd/modules/render/bgfx/frameparameter.h
index e559d13c1d8..2a1e8f6094b 100644
--- a/src/osd/modules/render/bgfx/frameparameter.h
+++ b/src/osd/modules/render/bgfx/frameparameter.h
@@ -6,22 +6,20 @@
//
//============================================================
-#pragma once
+#ifndef MAME_RENDER_BGFX_FRAMEPARAMETER_H
+#define MAME_RENDER_BGFX_FRAMEPARAMETER_H
-#ifndef __DRAWBGFX_FRAME_PARAMETER__
-#define __DRAWBGFX_FRAME_PARAMETER__
+#pragma once
-#include <bgfx/bgfx.h>
+#include "parameter.h"
+#include <cstdint>
#include <string>
-#include "parameter.h"
-
class bgfx_frame_parameter : public bgfx_parameter
{
public:
- bgfx_frame_parameter(std::string name, parameter_type type, uint32_t period);
- virtual ~bgfx_frame_parameter() { }
+ bgfx_frame_parameter(std::string &&name, parameter_type type, uint32_t period);
virtual float value() override;
virtual void tick(double delta) override;
@@ -31,4 +29,4 @@ private:
uint32_t m_period;
};
-#endif // __DRAWBGFX_FRAME_PARAMETER__
+#endif // MAME_RENDER_BGFX_FRAMEPARAMETER_H
diff --git a/src/osd/modules/render/bgfx/inputpair.cpp b/src/osd/modules/render/bgfx/inputpair.cpp
index 5f1324c2581..154252db04f 100644
--- a/src/osd/modules/render/bgfx/inputpair.cpp
+++ b/src/osd/modules/render/bgfx/inputpair.cpp
@@ -11,15 +11,18 @@
#include "inputpair.h"
-#include "../frontend/mame/ui/slider.h"
-
-#include "texture.h"
-#include "target.h"
-#include "effect.h"
-#include "uniform.h"
#include "chainmanager.h"
+#include "effect.h"
#include "slider.h"
#include "sliderdirtynotifier.h"
+#include "target.h"
+#include "texture.h"
+#include "uniform.h"
+
+#include "../frontend/mame/ui/slider.h"
+
+#include "util/strformat.h"
+
bgfx_input_pair::bgfx_input_pair(int index, std::string sampler, std::string texture, std::vector<std::string> available_textures, std::string selection, chain_manager& chains, uint32_t screen_index)
: m_index(index)
@@ -53,20 +56,31 @@ void bgfx_input_pair::bind(bgfx_effect *effect, const int32_t screen) const
if (!provider)
return;
+ float rowpixels(provider->rowpixels());
+ float width_margin(provider->width_margin());
+ float height(provider->height());
+
bgfx_uniform *tex_size = effect->uniform("u_tex_size" + std::to_string(m_index));
if (tex_size && provider)
{
- float values[2] = { float(provider->rowpixels()), float(provider->height()) };
+ float values[2] = { rowpixels, height };
tex_size->set(values, sizeof(float) * 2);
}
bgfx_uniform *inv_tex_size = effect->uniform("u_inv_tex_size" + std::to_string(m_index));
if (inv_tex_size && provider)
{
- float values[2] = { 1.0f / float(provider->rowpixels()), 1.0f / float(provider->height()) };
+ float values[2] = { 1.0f / rowpixels, 1.0f / height };
inv_tex_size->set(values, sizeof(float) * 2);
}
+ bgfx_uniform *tex_bounds = effect->uniform("u_tex_bounds" + std::to_string(m_index));
+ if (tex_bounds && provider)
+ {
+ float values[4] = { width_margin / rowpixels, 0.0f, 1.0f + width_margin / rowpixels, 1.0f };
+ tex_bounds->set(values, sizeof(float) * 4);
+ }
+
bgfx::setTexture(m_index, effect->uniform(m_sampler)->handle(), chains().textures().handle(name));
}
@@ -109,11 +123,11 @@ void bgfx_input_pair::create_selection_slider(uint32_t screen_index)
int32_t maxval = m_available_textures.size() - 1;
int32_t incval = 1;
- std::string description = "Window " + std::to_string(chains().window_index()) + ", Screen " + std::to_string(screen_index) + " " + m_selection + ":";
-
using namespace std::placeholders;
- m_slider_state = std::make_unique<slider_state>(std::move(description), minval, defval, maxval, incval,
- std::bind(&bgfx_input_pair::texture_changed, this, screen_index, _1, _2));
+ m_slider_state = std::make_unique<slider_state>(
+ util::string_format("Window %1$u, Screen %1$u %3$s", chains().window_index(), screen_index, m_selection),
+ minval, defval, maxval, incval,
+ std::bind(&bgfx_input_pair::texture_changed, this, screen_index, _1, _2));
ui::menu_item item(ui::menu_item_type::SLIDER, m_slider_state.get());
item.set_text(m_slider_state->description);
@@ -130,9 +144,7 @@ std::vector<ui::menu_item> bgfx_input_pair::get_slider_list()
std::vector<ui::menu_item> sliders;
if (!needs_sliders())
- {
return sliders;
- }
sliders.push_back(m_selection_slider);
diff --git a/src/osd/modules/render/bgfx/parameter.h b/src/osd/modules/render/bgfx/parameter.h
index 2df18365a4c..baa2ff017ad 100644
--- a/src/osd/modules/render/bgfx/parameter.h
+++ b/src/osd/modules/render/bgfx/parameter.h
@@ -10,12 +10,13 @@
//
//============================================================
-#pragma once
+#ifndef MAME_RENDER_BGFX_PARAMETER_H
+#define MAME_RENDER_BGFX_PARAMETER_H
-#ifndef __DRAWBGFX_PARAMETER__
-#define __DRAWBGFX_PARAMETER__
+#pragma once
#include <string>
+#include <utility>
class bgfx_parameter
{
@@ -27,18 +28,18 @@ public:
PARAM_TIME
};
- bgfx_parameter(std::string name, parameter_type type) : m_name(name), m_type(type) { }
- virtual ~bgfx_parameter() { }
+ bgfx_parameter(std::string &&name, parameter_type type) : m_name(std::move(name)), m_type(type) { }
+ virtual ~bgfx_parameter() = default;
virtual void tick(double delta) = 0;
// Getters
virtual float value() = 0;
- std::string name() const { return m_name; }
+ const std::string &name() const { return m_name; }
protected:
std::string m_name;
parameter_type m_type;
};
-#endif // __DRAWBGFX_PARAMETER__
+#endif // MAME_RENDER_BGFX_PARAMETER_H
diff --git a/src/osd/modules/render/bgfx/paramreader.cpp b/src/osd/modules/render/bgfx/paramreader.cpp
index 1b14b2aa56a..0eeb5f22e84 100644
--- a/src/osd/modules/render/bgfx/paramreader.cpp
+++ b/src/osd/modules/render/bgfx/paramreader.cpp
@@ -6,15 +6,13 @@
//
//============================================================
-#include <string>
-
#include "paramreader.h"
-#include "parameter.h"
+#include "chainmanager.h"
#include "frameparameter.h"
-#include "windowparameter.h"
+#include "parameter.h"
#include "timeparameter.h"
-#include "chainmanager.h"
+#include "windowparameter.h"
const parameter_reader::string_to_enum parameter_reader::TYPE_NAMES[parameter_reader::TYPE_COUNT] = {
{ "frame", bgfx_parameter::parameter_type::PARAM_FRAME },
@@ -22,7 +20,7 @@ const parameter_reader::string_to_enum parameter_reader::TYPE_NAMES[parameter_re
{ "time", bgfx_parameter::parameter_type::PARAM_TIME }
};
-bgfx_parameter* parameter_reader::read_from_value(const Value& value, std::string prefix, chain_manager& chains)
+bgfx_parameter* parameter_reader::read_from_value(const Value& value, const std::string &prefix, chain_manager& chains)
{
if (!validate_parameters(value, prefix))
{
@@ -35,32 +33,32 @@ bgfx_parameter* parameter_reader::read_from_value(const Value& value, std::strin
if (type == bgfx_parameter::parameter_type::PARAM_FRAME)
{
uint32_t period = int(value["period"].GetDouble());
- return new bgfx_frame_parameter(name, type, period);
+ return new bgfx_frame_parameter(std::move(name), type, period);
}
else if (type == bgfx_parameter::parameter_type::PARAM_WINDOW)
{
- return new bgfx_window_parameter(name, type, chains.window_index());
+ return new bgfx_window_parameter(std::move(name), type, chains.window_index());
}
else if (type == bgfx_parameter::parameter_type::PARAM_TIME)
{
auto limit = float(value["limit"].GetDouble());
- return new bgfx_time_parameter(name, type, limit);
+ return new bgfx_time_parameter(std::move(name), type, limit);
}
else
{
- READER_CHECK(false, (prefix + "Unknown parameter type '" + std::string(value["type"].GetString()) + "'\n").c_str());
+ READER_CHECK(false, "%sUnknown parameter type '%s'\n", prefix, value["type"].GetString());
}
return nullptr;
}
-bool parameter_reader::validate_parameters(const Value& value, std::string prefix)
+bool parameter_reader::validate_parameters(const Value& value, const std::string &prefix)
{
- if (!READER_CHECK(value.HasMember("name"), (prefix + "Must have string value 'name'\n").c_str())) return false;
- if (!READER_CHECK(value["name"].IsString(), (prefix + "Value 'name' must be a string\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("type"), (prefix + "Must have string value 'type'\n").c_str())) return false;
- if (!READER_CHECK(value["type"].IsString(), (prefix + "Value 'type' must be a string\n").c_str())) return false;
- if (!READER_CHECK(!value.HasMember("period") || value["period"].IsNumber(), (prefix + "Value 'period' must be numeric\n").c_str())) return false;
- if (!READER_CHECK(!value.HasMember("limit") || value["limit"].IsNumber(), (prefix + "Value 'period' must be numeric\n").c_str())) return false;
+ if (!READER_CHECK(value.HasMember("name"), "%sMust have string value 'name'\n", prefix)) return false;
+ if (!READER_CHECK(value["name"].IsString(), "%sValue 'name' must be a string\n", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("type"), "%sMust have string value 'type'\n", prefix)) return false;
+ if (!READER_CHECK(value["type"].IsString(), "%sValue 'type' must be a string\n", prefix)) return false;
+ if (!READER_CHECK(!value.HasMember("period") || value["period"].IsNumber(), "%sValue 'period' must be numeric\n", prefix)) return false;
+ if (!READER_CHECK(!value.HasMember("limit") || value["limit"].IsNumber(), "%sValue 'period' must be numeric\n", prefix)) return false;
return true;
}
diff --git a/src/osd/modules/render/bgfx/paramreader.h b/src/osd/modules/render/bgfx/paramreader.h
index 013d6589cc3..bfd23b14a42 100644
--- a/src/osd/modules/render/bgfx/paramreader.h
+++ b/src/osd/modules/render/bgfx/paramreader.h
@@ -6,26 +6,28 @@
//
//============================================================
-#pragma once
+#ifndef MAME_RENDER_BGFX_PARAMREADER_H
+#define MAME_RENDER_BGFX_PARAMREADER_H
-#ifndef __DRAWBGFX_PARAM_READER__
-#define __DRAWBGFX_PARAM_READER__
+#pragma once
#include "statereader.h"
+#include <string>
+
class bgfx_parameter;
class chain_manager;
class parameter_reader : public state_reader
{
public:
- static bgfx_parameter* read_from_value(const Value& value, std::string prefix, chain_manager& chains);
+ static bgfx_parameter* read_from_value(const Value& value, const std::string &prefix, chain_manager& chains);
private:
- static bool validate_parameters(const Value& value, std::string prefix);
+ static bool validate_parameters(const Value& value, const std::string &prefix);
static const int TYPE_COUNT = 3;
static const string_to_enum TYPE_NAMES[TYPE_COUNT];
};
-#endif // __DRAWBGFX_PARAM_READER__
+#endif // MAME_RENDER_BGFX_PARAMREADER_H
diff --git a/src/osd/modules/render/bgfx/paramuniform.h b/src/osd/modules/render/bgfx/paramuniform.h
index b49fb2c7d61..5f5b69c96a6 100644
--- a/src/osd/modules/render/bgfx/paramuniform.h
+++ b/src/osd/modules/render/bgfx/paramuniform.h
@@ -6,10 +6,10 @@
//
//============================================================
-#pragma once
+#ifndef MAME_RENDER_BGFX_PARAMUNIFORM_H
+#define MAME_RENDER_BGFX_PARAMUNIFORM_H
-#ifndef __DRAWBGFX_PARAM_UNIFORM__
-#define __DRAWBGFX_PARAM_UNIFORM__
+#pragma once
#include "entryuniform.h"
@@ -26,4 +26,4 @@ private:
bgfx_parameter* m_param;
};
-#endif // __DRAWBGFX_PARAM_UNIFORM__
+#endif // MAME_RENDER_BGFX_PARAMUNIFORM_H
diff --git a/src/osd/modules/render/bgfx/paramuniformreader.cpp b/src/osd/modules/render/bgfx/paramuniformreader.cpp
index 2b613fc216c..8c5cd265195 100644
--- a/src/osd/modules/render/bgfx/paramuniformreader.cpp
+++ b/src/osd/modules/render/bgfx/paramuniformreader.cpp
@@ -9,10 +9,10 @@
#include "paramuniformreader.h"
#include "entryuniform.h"
-#include "paramuniform.h"
#include "parameter.h"
+#include "paramuniform.h"
-bgfx_entry_uniform* param_uniform_reader::read_from_value(const Value& value, std::string prefix, bgfx_uniform* uniform, std::map<std::string, bgfx_parameter*>& params)
+bgfx_entry_uniform* param_uniform_reader::read_from_value(const Value& value, const std::string &prefix, bgfx_uniform* uniform, std::map<std::string, bgfx_parameter*>& params)
{
if (!validate_parameters(value, prefix))
{
@@ -24,9 +24,9 @@ bgfx_entry_uniform* param_uniform_reader::read_from_value(const Value& value, st
return new bgfx_param_uniform(uniform, params[parameter]);
}
-bool param_uniform_reader::validate_parameters(const Value& value, std::string prefix)
+bool param_uniform_reader::validate_parameters(const Value& value, const std::string &prefix)
{
- if (!READER_CHECK(value.HasMember("parameter"), (prefix + "Must have string value 'parameter' (what parameter is being mapped?)\n").c_str())) return false;
- if (!READER_CHECK(value["parameter"].IsString(), (prefix + "Value 'parameter' must be a string\n").c_str())) return false;
+ if (!READER_CHECK(value.HasMember("parameter"), "%sMust have string value 'parameter' (what parameter is being mapped?)\n", prefix)) return false;
+ if (!READER_CHECK(value["parameter"].IsString(), "%sValue 'parameter' must be a string\n", prefix)) return false;
return true;
}
diff --git a/src/osd/modules/render/bgfx/paramuniformreader.h b/src/osd/modules/render/bgfx/paramuniformreader.h
index baf281b562b..b1ed2a87f69 100644
--- a/src/osd/modules/render/bgfx/paramuniformreader.h
+++ b/src/osd/modules/render/bgfx/paramuniformreader.h
@@ -6,15 +6,15 @@
//
//==================================================================
+#ifndef MAME_RENDER_BGFX_PARAMUNIFORMREADER_H
+#define MAME_RENDER_BGFX_PARAMUNIFORMREADER_H
+
#pragma once
-#ifndef __DRAWBGFX_PARAM_UNIFORM_READER__
-#define __DRAWBGFX_PARAM_UNIFORM_READER__
+#include "statereader.h"
-#include <string>
#include <map>
-
-#include "statereader.h"
+#include <string>
class bgfx_entry_uniform;
class bgfx_uniform;
@@ -23,10 +23,10 @@ class bgfx_parameter;
class param_uniform_reader : public state_reader
{
public:
- static bgfx_entry_uniform* read_from_value(const Value& value, std::string prefix, bgfx_uniform* uniform, std::map<std::string, bgfx_parameter*>& params);
+ static bgfx_entry_uniform* read_from_value(const Value& value, const std::string &prefix, bgfx_uniform* uniform, std::map<std::string, bgfx_parameter*>& params);
private:
- static bool validate_parameters(const Value& value, std::string prefix);
+ static bool validate_parameters(const Value& value, const std::string &prefix);
};
-#endif // __DRAWBGFX_PARAM_UNIFORM_READER__
+#endif // MAME_RENDER_BGFX_PARAMUNIFORMREADER_H
diff --git a/src/osd/modules/render/bgfx/shadermanager.cpp b/src/osd/modules/render/bgfx/shadermanager.cpp
index dd894426794..763a744e4aa 100644
--- a/src/osd/modules/render/bgfx/shadermanager.cpp
+++ b/src/osd/modules/render/bgfx/shadermanager.cpp
@@ -16,11 +16,10 @@
#include "osdfile.h"
#include "modules/lib/osdobj_common.h"
+#include <bx/file.h>
#include <bx/math.h>
#include <bx/readerwriter.h>
-#include <bx/file.h>
-#include <bgfx/bgfx.h>
shader_manager::~shader_manager()
{
@@ -31,7 +30,7 @@ shader_manager::~shader_manager()
m_shaders.clear();
}
-bgfx::ShaderHandle shader_manager::get_or_load_shader(osd_options &options, std::string name)
+bgfx::ShaderHandle shader_manager::get_or_load_shader(const osd_options &options, const std::string &name)
{
std::map<std::string, bgfx::ShaderHandle>::iterator iter = m_shaders.find(name);
if (iter != m_shaders.end())
@@ -48,7 +47,7 @@ bgfx::ShaderHandle shader_manager::get_or_load_shader(osd_options &options, std:
return handle;
}
-bgfx::ShaderHandle shader_manager::load_shader(osd_options &options, std::string name)
+bgfx::ShaderHandle shader_manager::load_shader(const osd_options &options, const std::string &name)
{
std::string shader_path = make_path_string(options, name);
const bgfx::Memory* mem = load_mem(shader_path + name + ".bin");
@@ -60,16 +59,17 @@ bgfx::ShaderHandle shader_manager::load_shader(osd_options &options, std::string
return BGFX_INVALID_HANDLE;
}
-bool shader_manager::is_shader_present(osd_options &options, std::string name)
+bool shader_manager::is_shader_present(const osd_options &options, const std::string &name)
{
std::string shader_path = make_path_string(options, name);
std::string file_name = shader_path + name + ".bin";
bx::FileReader reader;
+ bx::ErrorAssert err;
if (bx::open(&reader, file_name.c_str()))
{
uint32_t expected_size(bx::getSize(&reader));
uint8_t *data = new uint8_t[expected_size];
- uint32_t read_size = (uint32_t)bx::read(&reader, data, expected_size);
+ uint32_t read_size = (uint32_t)bx::read(&reader, data, expected_size, &err);
delete [] data;
bx::close(&reader);
@@ -79,7 +79,7 @@ bool shader_manager::is_shader_present(osd_options &options, std::string name)
return false;
}
-std::string shader_manager::make_path_string(osd_options &options, std::string name)
+std::string shader_manager::make_path_string(const osd_options &options, const std::string &name)
{
std::string shader_path(options.bgfx_path());
shader_path += PATH_SEPARATOR "shaders" PATH_SEPARATOR;
@@ -119,17 +119,18 @@ std::string shader_manager::make_path_string(osd_options &options, std::string n
fatalerror("Unknown BGFX renderer type %d", bgfx::getRendererType());
}
shader_path += PATH_SEPARATOR;
- return osd_subst_env(shader_path);
+ return shader_path;
}
-const bgfx::Memory* shader_manager::load_mem(std::string name)
+const bgfx::Memory* shader_manager::load_mem(const std::string &name)
{
bx::FileReader reader;
if (bx::open(&reader, name.c_str()))
{
+ bx::ErrorAssert err;
uint32_t size(bx::getSize(&reader));
const bgfx::Memory* mem = bgfx::alloc(size + 1);
- bx::read(&reader, mem->data, size);
+ bx::read(&reader, mem->data, size, &err);
bx::close(&reader);
mem->data[mem->size - 1] = '\0';
@@ -137,7 +138,7 @@ const bgfx::Memory* shader_manager::load_mem(std::string name)
}
else
{
- osd_printf_error("Unable to load shader %s\n", name.c_str());
+ osd_printf_error("Unable to load shader %s\n", name);
}
return nullptr;
}
diff --git a/src/osd/modules/render/bgfx/shadermanager.h b/src/osd/modules/render/bgfx/shadermanager.h
index 81fa4260f47..12ac739d35a 100644
--- a/src/osd/modules/render/bgfx/shadermanager.h
+++ b/src/osd/modules/render/bgfx/shadermanager.h
@@ -9,10 +9,10 @@
//
//============================================================
-#pragma once
+#ifndef MAME_RENDER_BGFX_SHADERMANAGER_H
+#define MAME_RENDER_BGFX_SHADERMANAGER_H
-#ifndef __DRAWBGFX_SHADER_MANAGER__
-#define __DRAWBGFX_SHADER_MANAGER__
+#pragma once
#include <bgfx/bgfx.h>
@@ -22,21 +22,23 @@
class osd_options;
-class shader_manager {
+
+class shader_manager
+{
public:
shader_manager() { }
~shader_manager();
// Getters
- bgfx::ShaderHandle get_or_load_shader(osd_options &options, std::string name);
- static bgfx::ShaderHandle load_shader(osd_options &options, std::string name);
- static bool is_shader_present(osd_options &options, std::string name);
+ bgfx::ShaderHandle get_or_load_shader(const osd_options &options, const std::string &name);
+ static bgfx::ShaderHandle load_shader(const osd_options &options, const std::string &name);
+ static bool is_shader_present(const osd_options &options, const std::string &name);
private:
- static std::string make_path_string(osd_options &options, std::string name);
- static const bgfx::Memory* load_mem(std::string name);
+ static std::string make_path_string(const osd_options &options, const std::string &name);
+ static const bgfx::Memory* load_mem(const std::string &name);
- std::map<std::string, bgfx::ShaderHandle> m_shaders;
+ std::map<std::string, bgfx::ShaderHandle> m_shaders;
};
-#endif // __DRAWBGFX_SHADER_MANAGER__
+#endif // MAME_RENDER_BGFX_SHADERMANAGER_H
diff --git a/src/osd/modules/render/bgfx/shaders/chains/blurs/fs_smart-blur.sc b/src/osd/modules/render/bgfx/shaders/chains/blurs/fs_smart-blur.sc
index 4c688c4d6f4..6ea70cb6aac 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/blurs/fs_smart-blur.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/blurs/fs_smart-blur.sc
@@ -39,26 +39,26 @@ uniform vec4 SB_THRESHOLD;
bool eq(vec3 c1, vec3 c2)
{
- vec3 df = abs(c1 - c2);
- return df.r < SB_THRESHOLD.r && df.g < SB_THRESHOLD.g && df.b < SB_THRESHOLD.b;
+ vec3 df = abs(c1 - c2);
+ return df.r < SB_THRESHOLD.r && df.g < SB_THRESHOLD.g && df.b < SB_THRESHOLD.b;
}
void main()
{
- vec3 A = texture2D(s_p, v_texcoord1.xw).xyz;
- vec3 B = texture2D(s_p, v_texcoord1.yw).xyz;
- vec3 C = texture2D(s_p, v_texcoord1.zw).xyz;
- vec3 D = texture2D(s_p, v_texcoord2.xw).xyz;
- vec3 E = texture2D(s_p, v_texcoord2.yw).xyz;
- vec3 F = texture2D(s_p, v_texcoord2.zw).xyz;
- vec3 G = texture2D(s_p, v_texcoord3.xw).xyz;
- vec3 H = texture2D(s_p, v_texcoord3.yw).xyz;
- vec3 I = texture2D(s_p, v_texcoord3.zw).xyz;
+ vec3 A = texture2D(s_p, v_texcoord1.xw).xyz;
+ vec3 B = texture2D(s_p, v_texcoord1.yw).xyz;
+ vec3 C = texture2D(s_p, v_texcoord1.zw).xyz;
+ vec3 D = texture2D(s_p, v_texcoord2.xw).xyz;
+ vec3 E = texture2D(s_p, v_texcoord2.yw).xyz;
+ vec3 F = texture2D(s_p, v_texcoord2.zw).xyz;
+ vec3 G = texture2D(s_p, v_texcoord3.xw).xyz;
+ vec3 H = texture2D(s_p, v_texcoord3.yw).xyz;
+ vec3 I = texture2D(s_p, v_texcoord3.zw).xyz;
- if (eq(E,F) && eq(E,H) && eq(E,I) && eq(E,B) && eq(E,C) && eq(E,A) && eq(E,D) && eq(E,G))
- {
- E = (A + B + C + D + E + F + G + H + I) / 9.0;
- }
+ if (eq(E,F) && eq(E,H) && eq(E,I) && eq(E,B) && eq(E,C) && eq(E,A) && eq(E,D) && eq(E,G))
+ {
+ E = (A + B + C + D + E + F + G + H + I) / 9.0;
+ }
- gl_FragColor = vec4(E, 1.0);
+ gl_FragColor = vec4(E, 1.0);
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/blurs/vs_smart-blur.sc b/src/osd/modules/render/bgfx/shaders/chains/blurs/vs_smart-blur.sc
index 1b967f894d4..40b0947da38 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/blurs/vs_smart-blur.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/blurs/vs_smart-blur.sc
@@ -32,10 +32,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_color0
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
vec2 ps = 1.0 / u_tex_size0.xy;
diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/crt-geom_common.sc b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/crt-geom_common.sc
index 6863a180ef6..9118e42d5c8 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/crt-geom_common.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/crt-geom_common.sc
@@ -13,12 +13,12 @@
vec4 TEX2D(vec2 c)
{
- vec2 underscan = step(0.0,c) * step(0.0,vec2_splat(1.0)-c);
- vec4 col = texture2D(mpass_texture, c) * vec4_splat(underscan.x*underscan.y);
+ vec2 underscan = step(0.0,c) * step(0.0,vec2_splat(1.0)-c);
+ vec4 col = texture2D(mpass_texture, c) * vec4_splat(underscan.x*underscan.y);
#ifdef LINEAR_PROCESSING
- col = pow(col, vec4_splat(CRTgamma.x));
+ col = pow(col, vec4_splat(CRTgamma.x));
#endif
- return col;
+ return col;
}
// Enable screen curvature.
@@ -48,43 +48,43 @@ uniform vec4 cornersmooth;
float intersect(vec2 xy , vec2 sinangle, vec2 cosangle)
{
- float A = dot(xy,xy)+d.x*d.x;
- float B = 2.0*(R.x*(dot(xy,sinangle)-d.x*cosangle.x*cosangle.y)-d.x*d.x);
- float C = d.x*d.x + 2.0*R.x*d.x*cosangle.x*cosangle.y;
- return (-B-sqrt(B*B-4.0*A*C))/(2.0*A);
+ float A = dot(xy,xy)+d.x*d.x;
+ float B = 2.0*(R.x*(dot(xy,sinangle)-d.x*cosangle.x*cosangle.y)-d.x*d.x);
+ float C = d.x*d.x + 2.0*R.x*d.x*cosangle.x*cosangle.y;
+ return (-B-sqrt(B*B-4.0*A*C))/(2.0*A);
}
vec2 bkwtrans(vec2 xy, vec2 sinangle, vec2 cosangle)
{
- float c = intersect(xy, sinangle, cosangle);
- vec2 pt = vec2_splat(c)*xy;
- pt -= vec2_splat(-R.x)*sinangle;
- pt /= vec2_splat(R.x);
- vec2 tang = sinangle/cosangle;
- vec2 poc = pt/cosangle;
- float A = dot(tang,tang)+1.0;
- float B = -2.0*dot(poc,tang);
- float C = dot(poc,poc)-1.0;
- float a = (-B+sqrt(B*B-4.0*A*C))/(2.0*A);
- vec2 uv = (pt-a*sinangle)/cosangle;
- float r = FIX(R.x*acos(a));
- return uv*r/sin(r/R.x);
+ float c = intersect(xy, sinangle, cosangle);
+ vec2 pt = vec2_splat(c)*xy;
+ pt -= vec2_splat(-R.x)*sinangle;
+ pt /= vec2_splat(R.x);
+ vec2 tang = sinangle/cosangle;
+ vec2 poc = pt/cosangle;
+ float A = dot(tang,tang)+1.0;
+ float B = -2.0*dot(poc,tang);
+ float C = dot(poc,poc)-1.0;
+ float a = (-B+sqrt(B*B-4.0*A*C))/(2.0*A);
+ vec2 uv = (pt-a*sinangle)/cosangle;
+ float r = FIX(R.x*acos(a));
+ return uv*r/sin(r/R.x);
}
vec2 transform(vec2 coord, vec3 stretch, vec2 sinangle, vec2 cosangle)
{
- coord = (coord-vec2_splat(0.5))*aspect.xy*stretch.z+stretch.xy;
- return (bkwtrans(coord, sinangle, cosangle)/overscan.xy/aspect.xy+vec2_splat(0.5));
+ coord = (coord-vec2_splat(0.5))*aspect.xy*stretch.z+stretch.xy;
+ return (bkwtrans(coord, sinangle, cosangle)/overscan.xy/aspect.xy+vec2_splat(0.5));
}
float corner(vec2 coord)
{
- coord = (coord - vec2_splat(0.5)) * overscan.xy + vec2_splat(0.5);
- coord = min(coord, vec2_splat(1.0)-coord) * aspect.xy;
- vec2 cdist = vec2_splat(cornersize.x);
- coord = (cdist - min(coord,cdist));
- float dist = sqrt(dot(coord,coord));
- return clamp((max(cdist.x,1e-3)-dist)*cornersmooth.x,0.0, 1.0);
+ coord = (coord - vec2_splat(0.5)) * overscan.xy + vec2_splat(0.5);
+ coord = min(coord, vec2_splat(1.0)-coord) * aspect.xy;
+ vec2 cdist = vec2_splat(cornersize.x);
+ coord = (cdist - min(coord,cdist));
+ float dist = sqrt(dot(coord,coord));
+ return clamp((max(cdist.x,1e-3)-dist)*cornersmooth.x,0.0, 1.0);
}
// Calculate the influence of a scanline on the current pixel.
@@ -95,109 +95,109 @@ float corner(vec2 coord)
// the current pixel.
vec4 scanlineWeights(float distance, vec4 color)
{
- // "wid" controls the width of the scanline beam, for each RGB channel
- // The "weights" lines basically specify the formula that gives
- // you the profile of the beam, i.e. the intensity as
- // a function of distance from the vertical center of the
- // scanline. In this case, it is gaussian if width=2, and
- // becomes nongaussian for larger widths. Ideally this should
- // be normalized so that the integral across the beam is
- // independent of its width. That is, for a narrower beam
- // "weights" should have a higher peak at the center of the
- // scanline than for a wider beam.
+ // "wid" controls the width of the scanline beam, for each RGB channel
+ // The "weights" lines basically specify the formula that gives
+ // you the profile of the beam, i.e. the intensity as
+ // a function of distance from the vertical center of the
+ // scanline. In this case, it is gaussian if width=2, and
+ // becomes nongaussian for larger widths. Ideally this should
+ // be normalized so that the integral across the beam is
+ // independent of its width. That is, for a narrower beam
+ // "weights" should have a higher peak at the center of the
+ // scanline than for a wider beam.
#ifdef USEGAUSSIAN
- vec4 wid = spot_size.x + spot_growth.x * pow(color, vec4_splat(spot_growth_power.x));
- vec4 weights = vec4(distance / wid);
- float maxwid = spot_size.x + spot_growth.x;
- float norm = maxwid / ( 1.0 + exp(-1.0/(maxwid*maxwid)) );
- return norm * exp(-weights * weights) / wid;
+ vec4 wid = spot_size.x + spot_growth.x * pow(color, vec4_splat(spot_growth_power.x));
+ vec4 weights = vec4(distance / wid);
+ float maxwid = spot_size.x + spot_growth.x;
+ float norm = maxwid / ( 1.0 + exp(-1.0/(maxwid*maxwid)) );
+ return norm * exp(-weights * weights) / wid;
#else
- vec4 wid = 2.0 + 2.0 * pow(color, vec4_splat(4.0));
- vec4 weights = vec4_splat(distance / 0.3);
- return 1.4 * exp(-pow(weights * inversesqrt(0.5 * wid), wid)) / (0.6 + 0.2 * wid);
+ vec4 wid = 2.0 + 2.0 * pow(color, vec4_splat(4.0));
+ vec4 weights = vec4_splat(distance / 0.3);
+ return 1.4 * exp(-pow(weights * inversesqrt(0.5 * wid), wid)) / (0.6 + 0.2 * wid);
#endif
}
vec4 cubic(vec4 x, float B, float C)
{
- // https://en.wikipedia.org/wiki/Mitchell%E2%80%93Netravali_filters
- vec2 a = x.yz; // components in [0,1]
- vec2 b = x.xw; // components in [1,2]
- vec2 a2 = a*a;
- vec2 b2 = b*b;
- a = (2.0-1.5*B-1.0*C)*a*a2 + (-3.0+2.0*B+C)*a2 + (1.0-(1.0/3.0)*B);
- b = ((-1.0/6.0)*B-C)*b*b2 + (B+5.0*C)*b2 + (-2.0*B-8.0*C)*b + ((4.0/3.0)*B+4.0*C);
- return vec4(b.x,a.x,a.y,b.y);
+ // https://en.wikipedia.org/wiki/Mitchell%E2%80%93Netravali_filters
+ vec2 a = x.yz; // components in [0,1]
+ vec2 b = x.xw; // components in [1,2]
+ vec2 a2 = a*a;
+ vec2 b2 = b*b;
+ a = (2.0-1.5*B-1.0*C)*a*a2 + (-3.0+2.0*B+C)*a2 + (1.0-(1.0/3.0)*B);
+ b = ((-1.0/6.0)*B-C)*b*b2 + (B+5.0*C)*b2 + (-2.0*B-8.0*C)*b + ((4.0/3.0)*B+4.0*C);
+ return vec4(b.x,a.x,a.y,b.y);
}
vec4 x_coeffs(vec4 x, float pos_x)
{
- if (u_interp.x < 0.5) { // box
- float wid = length(vec2(dFdx(pos_x),dFdy(pos_x)));
- float dx = clamp((0.5 + 0.5*wid - x.y)/wid, 0.0, 1.0);
- return vec4(0.0,dx,1.0-dx,0.0);
- } else if (u_interp.x < 1.5) { // linear
- return vec4(0.0, 1.0-x.y, 1.0-x.z, 0.0);
- } else if (u_interp.x < 2.5) { // Lanczos
- // Prevent division by zero.
- vec4 coeffs = FIX(PI * x);
- // Lanczos2 kernel.
- coeffs = 2.0 * sin(coeffs) * sin(coeffs / 2.0) / (coeffs * coeffs);
- // Normalize.
- coeffs /= dot(coeffs, vec4_splat(1.0));
- return coeffs;
- } else if (u_interp.x < 3.5) { // Catmull-Rom
- return cubic(x,0.0,0.5);
- } else if (u_interp.x < 4.5) { // Mitchell-Netravali
- return cubic(x,1.0/3.0,1.0/3.0);
- } else /*if (u_interp.x < 5.5)*/ { // B-spline
- return cubic(x,1.0,0.0);
- }
+ if (u_interp.x < 0.5) { // box
+ float wid = length(vec2(dFdx(pos_x),dFdy(pos_x)));
+ float dx = clamp((0.5 + 0.5*wid - x.y)/wid, 0.0, 1.0);
+ return vec4(0.0,dx,1.0-dx,0.0);
+ } else if (u_interp.x < 1.5) { // linear
+ return vec4(0.0, 1.0-x.y, 1.0-x.z, 0.0);
+ } else if (u_interp.x < 2.5) { // Lanczos
+ // Prevent division by zero.
+ vec4 coeffs = FIX(PI * x);
+ // Lanczos2 kernel.
+ coeffs = 2.0 * sin(coeffs) * sin(coeffs / 2.0) / (coeffs * coeffs);
+ // Normalize.
+ coeffs /= dot(coeffs, vec4_splat(1.0));
+ return coeffs;
+ } else if (u_interp.x < 3.5) { // Catmull-Rom
+ return cubic(x,0.0,0.5);
+ } else if (u_interp.x < 4.5) { // Mitchell-Netravali
+ return cubic(x,1.0/3.0,1.0/3.0);
+ } else /*if (u_interp.x < 5.5)*/ { // B-spline
+ return cubic(x,1.0,0.0);
+ }
}
vec4 sample_scanline(vec2 xy, vec4 coeffs, float onex)
{
- // Calculate the effective colour of the given
- // scanline at the horizontal location of the current pixel,
- // using the Lanczos coefficients.
- vec4 col = clamp(TEX2D(xy + vec2(-onex, 0.0))*coeffs.x +
- TEX2D(xy)*coeffs.y +
- TEX2D(xy +vec2(onex, 0.0))*coeffs.z +
- TEX2D(xy + vec2(2.0 * onex, 0.0))*coeffs.w , 0.0, 1.0);
- return col;
+ // Calculate the effective colour of the given
+ // scanline at the horizontal location of the current pixel,
+ // using the Lanczos coefficients.
+ vec4 col = clamp(TEX2D(xy + vec2(-onex, 0.0))*coeffs.x +
+ TEX2D(xy)*coeffs.y +
+ TEX2D(xy +vec2(onex, 0.0))*coeffs.z +
+ TEX2D(xy + vec2(2.0 * onex, 0.0))*coeffs.w , 0.0, 1.0);
+ return col;
}
vec3 apply_shadow_mask(vec2 coord, vec3 col)
{
- vec2 xy = coord * u_quad_dims.xy / u_tex_size1.xy;
- vec4 mask = texture2D(mask_texture, xy);
- // count of total bright pixels is encoded in the mask's alpha channel
- float nbright = 255.0 - 255.0*mask.a;
- // fraction of bright pixels in the mask
- float fbright = nbright / ( u_tex_size1.x * u_tex_size1.y );
- // average darkening factor of the mask
- float aperture_average = mix(1.0-aperture_strength.x*(1.0-aperture_brightboost.x), 1.0, fbright);
- // colour of dark mask pixels
- vec3 clow = vec3_splat(1.0-aperture_strength.x) * col + vec3_splat(aperture_strength.x*(aperture_brightboost.x)) * col * col;
- float ifbright = 1.0 / fbright;
- // colour of bright mask pixels
- vec3 chi = vec3_splat(ifbright*aperture_average) * col - vec3_splat(ifbright - 1.0) * clow;
- return mix(clow,chi,mask.rgb); // mask texture selects dark vs bright
+ vec2 xy = coord * u_quad_dims.xy / u_tex_size1.xy;
+ vec4 mask = texture2D(mask_texture, xy);
+ // count of total bright pixels is encoded in the mask's alpha channel
+ float nbright = 255.0 - 255.0*mask.a;
+ // fraction of bright pixels in the mask
+ float fbright = nbright / ( u_tex_size1.x * u_tex_size1.y );
+ // average darkening factor of the mask
+ float aperture_average = mix(1.0-aperture_strength.x*(1.0-aperture_brightboost.x), 1.0, fbright);
+ // colour of dark mask pixels
+ vec3 clow = vec3_splat(1.0-aperture_strength.x) * col + vec3_splat(aperture_strength.x*(aperture_brightboost.x)) * col * col;
+ float ifbright = 1.0 / fbright;
+ // colour of bright mask pixels
+ vec3 chi = vec3_splat(ifbright*aperture_average) * col - vec3_splat(ifbright - 1.0) * clow;
+ return mix(clow,chi,mask.rgb); // mask texture selects dark vs bright
}
vec3 linear_to_sRGB(vec3 col)
{
- // only applies the gamma ramp; does not adjust the primaries
- vec3 linear_ramp = vec3(lessThan(col, vec3_splat(0.0031308)));
- vec3 clin = col * vec3_splat(12.92);
- vec3 cpow = pow(col, vec3_splat(1.0/2.4)) * vec3_splat(1.055) - vec3_splat(0.055);
- return mix(cpow, clin, linear_ramp);
+ // only applies the gamma ramp; does not adjust the primaries
+ vec3 linear_ramp = vec3(lessThan(col, vec3_splat(0.0031308)));
+ vec3 clin = col * vec3_splat(12.92);
+ vec3 cpow = pow(col, vec3_splat(1.0/2.4)) * vec3_splat(1.055) - vec3_splat(0.055);
+ return mix(cpow, clin, linear_ramp);
}
vec3 linear_to_output(vec3 col)
{
- if (monitorsRGB.x > 0.5)
- return linear_to_sRGB(col);
- else
- return pow(col, vec3_splat(1.0 / monitorgamma.x));
+ if (monitorsRGB.x > 0.5)
+ return linear_to_sRGB(col);
+ else
+ return pow(col, vec3_splat(1.0 / monitorgamma.x));
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom-deluxe.sc b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom-deluxe.sc
index 72705bdcb83..5b8a633a642 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom-deluxe.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom-deluxe.sc
@@ -28,9 +28,9 @@ uniform vec4 rasterbloom;
uniform vec4 blurwidth;
-vec3 texblur(vec2 c)
+vec4 texblur(vec2 c)
{
- vec3 col = pow(texture2D(blur_texture,c).rgb, vec3_splat(CRTgamma.x));
+ vec4 col = pow(texture2D(blur_texture,c), vec4(vec3_splat(CRTgamma.x),1.0));
// taper the blur texture outside its border with a gaussian
float w = blurwidth.x / 320.0;
c = min(c, vec2_splat(1.0)-c) * aspect.xy * vec2_splat(1.0/w);
@@ -38,7 +38,7 @@ vec3 texblur(vec2 c)
// approximation of erf gives smooth step
// (convolution of gaussian with step)
c = (step(0.0,c)-vec2_splat(0.5)) * sqrt(vec2_splat(1.0)-e2c) * (vec2_splat(1.0) + vec2_splat(0.1749)*e2c) + vec2_splat(0.5);
- return col * vec3_splat( c.x * c.y );
+ return col * vec4_splat( c.x * c.y );
}
void main()
@@ -125,16 +125,16 @@ void main()
weights_prev=weights_prev+scanlineWeights(uv_ratio.y+1.0, col_prev)/3.0;
weights_next=weights_next+scanlineWeights(uv_ratio.y-1.0, col_next)/3.0;
#endif
- vec3 mul_res = (col * weights + col_prev * weights_prev + col_next * weights_next).rgb;
+ vec4 mul_res = col * weights + col_prev * weights_prev + col_next * weights_next;
// halation and corners
- vec3 blur = texblur(xy0);
+ vec4 blur = texblur(xy0);
// include factor of rbloom:
// (probably imperceptible) brightness reduction when raster grows
- mul_res = mix(mul_res, blur, halation.x) * vec3_splat(cval*rbloom);
+ mul_res = mix(mul_res, blur, halation.x) * vec4_splat(cval*rbloom);
// Shadow mask
- vec3 cout = apply_shadow_mask(v_texCoord.xy, mul_res);
+ vec3 cout = apply_shadow_mask(v_texCoord.xy, mul_res.rgb);
// Convert the image gamma for display on our output device.
cout = linear_to_output(cout);
diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom.sc b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom.sc
index c096ebca7e0..5226a9999cc 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom.sc
@@ -24,79 +24,79 @@ uniform vec4 u_quad_dims;
void main()
{
- // Here's a helpful diagram to keep in mind while trying to
- // understand the code:
- //
- // | | | | |
- // -------------------------------
- // | | | | |
- // | 01 | 11 | 21 | 31 | <-- current scanline
- // | | @ | | |
- // -------------------------------
- // | | | | |
- // | 02 | 12 | 22 | 32 | <-- next scanline
- // | | | | |
- // -------------------------------
- // | | | | |
- //
- // Each character-cell represents a pixel on the output
- // surface, "@" represents the current pixel (always somewhere
- // in the bottom half of the current scan-line, or the top-half
- // of the next scanline). The grid of lines represents the
- // edges of the texels of the underlying texture.
-
- // Texture coordinates of the texel containing the active pixel.
- vec2 xy;
- if (curvature.x > 0.5)
- xy = transform(v_texCoord, v_stretch, v_sinangle, v_cosangle);
- else
- xy = (v_texCoord-vec2_splat(0.5))/overscan.xy+vec2_splat(0.5);
- float cval = corner(xy);
-
- // Of all the pixels that are mapped onto the texel we are
- // currently rendering, which pixel are we currently rendering?
- vec2 ratio_scale = xy * u_tex_size0.xy - vec2_splat(0.5);
+ // Here's a helpful diagram to keep in mind while trying to
+ // understand the code:
+ //
+ // | | | | |
+ // -------------------------------
+ // | | | | |
+ // | 01 | 11 | 21 | 31 | <-- current scanline
+ // | | @ | | |
+ // -------------------------------
+ // | | | | |
+ // | 02 | 12 | 22 | 32 | <-- next scanline
+ // | | | | |
+ // -------------------------------
+ // | | | | |
+ //
+ // Each character-cell represents a pixel on the output
+ // surface, "@" represents the current pixel (always somewhere
+ // in the bottom half of the current scan-line, or the top-half
+ // of the next scanline). The grid of lines represents the
+ // edges of the texels of the underlying texture.
+
+ // Texture coordinates of the texel containing the active pixel.
+ vec2 xy;
+ if (curvature.x > 0.5)
+ xy = transform(v_texCoord, v_stretch, v_sinangle, v_cosangle);
+ else
+ xy = (v_texCoord-vec2_splat(0.5))/overscan.xy+vec2_splat(0.5);
+ float cval = corner(xy);
+
+ // Of all the pixels that are mapped onto the texel we are
+ // currently rendering, which pixel are we currently rendering?
+ vec2 ratio_scale = xy * u_tex_size0.xy - vec2_splat(0.5);
#ifdef OVERSAMPLE
- float filter = fwidth(ratio_scale.y);
+ float filter = fwidth(ratio_scale.y);
#endif
- vec2 uv_ratio = fract(ratio_scale);
+ vec2 uv_ratio = fract(ratio_scale);
- // Snap to the center of the underlying texel.
- xy = (floor(ratio_scale) + vec2_splat(0.5)) / u_tex_size0.xy;
+ // Snap to the center of the underlying texel.
+ xy = (floor(ratio_scale) + vec2_splat(0.5)) / u_tex_size0.xy;
- // Calculate scaling coefficients describing the effect
- // of various neighbour texels in a scanline on the current
- // pixel.
- vec4 coeffs = x_coeffs(vec4(1.0 + uv_ratio.x, uv_ratio.x, 1.0 - uv_ratio.x, 2.0 - uv_ratio.x), ratio_scale.x);
+ // Calculate scaling coefficients describing the effect
+ // of various neighbour texels in a scanline on the current
+ // pixel.
+ vec4 coeffs = x_coeffs(vec4(1.0 + uv_ratio.x, uv_ratio.x, 1.0 - uv_ratio.x, 2.0 - uv_ratio.x), ratio_scale.x);
- vec4 col = sample_scanline(xy, coeffs, v_one.x);
- vec4 col2 = sample_scanline(xy + vec2(0.0, v_one.y), coeffs, v_one.x);
+ vec4 col = sample_scanline(xy, coeffs, v_one.x);
+ vec4 col2 = sample_scanline(xy + vec2(0.0, v_one.y), coeffs, v_one.x);
#ifndef LINEAR_PROCESSING
- col = pow(col , vec4_splat(CRTgamma.x));
- col2 = pow(col2, vec4_splat(CRTgamma.x));
+ col = pow(col , vec4_splat(CRTgamma.x));
+ col2 = pow(col2, vec4_splat(CRTgamma.x));
#endif
- // Calculate the influence of the current and next scanlines on
- // the current pixel.
- vec4 weights = scanlineWeights(uv_ratio.y, col);
- vec4 weights2 = scanlineWeights(1.0 - uv_ratio.y, col2);
+ // Calculate the influence of the current and next scanlines on
+ // the current pixel.
+ vec4 weights = scanlineWeights(uv_ratio.y, col);
+ vec4 weights2 = scanlineWeights(1.0 - uv_ratio.y, col2);
#ifdef OVERSAMPLE
- uv_ratio.y =uv_ratio.y+1.0/3.0*filter;
- weights = (weights+scanlineWeights(uv_ratio.y, col))/3.0;
- weights2=(weights2+scanlineWeights(abs(1.0-uv_ratio.y), col2))/3.0;
- uv_ratio.y =uv_ratio.y-2.0/3.0*filter;
- weights=weights+scanlineWeights(abs(uv_ratio.y), col)/3.0;
- weights2=weights2+scanlineWeights(abs(1.0-uv_ratio.y), col2)/3.0;
+ uv_ratio.y =uv_ratio.y+1.0/3.0*filter;
+ weights = (weights+scanlineWeights(uv_ratio.y, col))/3.0;
+ weights2=(weights2+scanlineWeights(abs(1.0-uv_ratio.y), col2))/3.0;
+ uv_ratio.y =uv_ratio.y-2.0/3.0*filter;
+ weights=weights+scanlineWeights(abs(uv_ratio.y), col)/3.0;
+ weights2=weights2+scanlineWeights(abs(1.0-uv_ratio.y), col2)/3.0;
#endif
- vec3 mul_res = (col * weights + col2 * weights2).rgb * vec3_splat(cval);
+ vec4 mul_res = col * weights + col2 * weights2 * vec4_splat(cval);
- // Shadow mask
- vec3 cout = apply_shadow_mask(v_texCoord.xy, mul_res);
+ // Shadow mask
+ vec3 cout = apply_shadow_mask(v_texCoord.xy, mul_res.rgb);
- // Convert the image gamma for display on our output device.
- cout = linear_to_output(cout);
+ // Convert the image gamma for display on our output device.
+ cout = linear_to_output(cout);
- gl_FragColor = vec4(cout,1.0);
+ gl_FragColor = vec4(cout,mul_res.a);
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_gaussx.sc b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_gaussx.sc
index 74faf15a740..6290ae330eb 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_gaussx.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_gaussx.sc
@@ -6,33 +6,33 @@ uniform vec4 u_gamma;
uniform vec4 u_tex_size0;
SAMPLER2D(s_tex, 0);
-#define TEX2D(v) pow(texture2D(s_tex, v).rgb, vec3_splat(u_gamma.x))
+#define TEX2D(v) pow(texture2D(s_tex, v), vec4(vec3_splat(u_gamma.x), 1.0))
void main()
{
- vec3 sum = vec3_splat(0.0);
+ vec4 sum = vec4_splat(0.0);
float onex = 1.0/u_tex_size0.x;
- sum += TEX2D(v_texCoord + vec2(-8.0 * onex, 0.0)) * vec3_splat(v_coeffs2.w);
- sum += TEX2D(v_texCoord + vec2(-7.0 * onex, 0.0)) * vec3_splat(v_coeffs2.z);
- sum += TEX2D(v_texCoord + vec2(-6.0 * onex, 0.0)) * vec3_splat(v_coeffs2.y);
- sum += TEX2D(v_texCoord + vec2(-5.0 * onex, 0.0)) * vec3_splat(v_coeffs2.x);
- sum += TEX2D(v_texCoord + vec2(-4.0 * onex, 0.0)) * vec3_splat(v_coeffs.w);
- sum += TEX2D(v_texCoord + vec2(-3.0 * onex, 0.0)) * vec3_splat(v_coeffs.z);
- sum += TEX2D(v_texCoord + vec2(-2.0 * onex, 0.0)) * vec3_splat(v_coeffs.y);
- sum += TEX2D(v_texCoord + vec2(-1.0 * onex, 0.0)) * vec3_splat(v_coeffs.x);
+ sum += TEX2D(v_texCoord + vec2(-8.0 * onex, 0.0)) * vec4_splat(v_coeffs2.w);
+ sum += TEX2D(v_texCoord + vec2(-7.0 * onex, 0.0)) * vec4_splat(v_coeffs2.z);
+ sum += TEX2D(v_texCoord + vec2(-6.0 * onex, 0.0)) * vec4_splat(v_coeffs2.y);
+ sum += TEX2D(v_texCoord + vec2(-5.0 * onex, 0.0)) * vec4_splat(v_coeffs2.x);
+ sum += TEX2D(v_texCoord + vec2(-4.0 * onex, 0.0)) * vec4_splat(v_coeffs.w);
+ sum += TEX2D(v_texCoord + vec2(-3.0 * onex, 0.0)) * vec4_splat(v_coeffs.z);
+ sum += TEX2D(v_texCoord + vec2(-2.0 * onex, 0.0)) * vec4_splat(v_coeffs.y);
+ sum += TEX2D(v_texCoord + vec2(-1.0 * onex, 0.0)) * vec4_splat(v_coeffs.x);
sum += TEX2D(v_texCoord);
- sum += TEX2D(v_texCoord + vec2(+1.0 * onex, 0.0)) * vec3_splat(v_coeffs.x);
- sum += TEX2D(v_texCoord + vec2(+2.0 * onex, 0.0)) * vec3_splat(v_coeffs.y);
- sum += TEX2D(v_texCoord + vec2(+3.0 * onex, 0.0)) * vec3_splat(v_coeffs.z);
- sum += TEX2D(v_texCoord + vec2(+4.0 * onex, 0.0)) * vec3_splat(v_coeffs.w);
- sum += TEX2D(v_texCoord + vec2(+5.0 * onex, 0.0)) * vec3_splat(v_coeffs2.x);
- sum += TEX2D(v_texCoord + vec2(+6.0 * onex, 0.0)) * vec3_splat(v_coeffs2.y);
- sum += TEX2D(v_texCoord + vec2(+7.0 * onex, 0.0)) * vec3_splat(v_coeffs2.z);
- sum += TEX2D(v_texCoord + vec2(+8.0 * onex, 0.0)) * vec3_splat(v_coeffs2.w);
+ sum += TEX2D(v_texCoord + vec2(+1.0 * onex, 0.0)) * vec4_splat(v_coeffs.x);
+ sum += TEX2D(v_texCoord + vec2(+2.0 * onex, 0.0)) * vec4_splat(v_coeffs.y);
+ sum += TEX2D(v_texCoord + vec2(+3.0 * onex, 0.0)) * vec4_splat(v_coeffs.z);
+ sum += TEX2D(v_texCoord + vec2(+4.0 * onex, 0.0)) * vec4_splat(v_coeffs.w);
+ sum += TEX2D(v_texCoord + vec2(+5.0 * onex, 0.0)) * vec4_splat(v_coeffs2.x);
+ sum += TEX2D(v_texCoord + vec2(+6.0 * onex, 0.0)) * vec4_splat(v_coeffs2.y);
+ sum += TEX2D(v_texCoord + vec2(+7.0 * onex, 0.0)) * vec4_splat(v_coeffs2.z);
+ sum += TEX2D(v_texCoord + vec2(+8.0 * onex, 0.0)) * vec4_splat(v_coeffs2.w);
float norm = 1.0 / (1.0 + 2.0*(v_coeffs.x+v_coeffs.y+v_coeffs.z+v_coeffs.w
+v_coeffs2.x+v_coeffs2.y+v_coeffs2.z+v_coeffs2.w));
- gl_FragColor = vec4( pow(sum*vec3_splat(norm), vec3_splat(1.0/u_gamma.x)), 1.0 );
+ gl_FragColor = pow(sum*vec4_splat(norm), vec4(vec3_splat(1.0/u_gamma.x), 1.0));
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_gaussy.sc b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_gaussy.sc
index c4fa73cdcce..9f4eace6cbe 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_gaussy.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_gaussy.sc
@@ -6,33 +6,33 @@ uniform vec4 u_gamma;
uniform vec4 u_tex_size0;
SAMPLER2D(s_tex, 0);
-#define TEX2D(v) pow(texture2D(s_tex, v).rgb, vec3_splat(u_gamma.x))
+#define TEX2D(v) pow(texture2D(s_tex, v), vec4(vec3_splat(u_gamma.x), 1.0))
void main()
{
- vec3 sum = vec3_splat(0.0);
+ vec4 sum = vec4_splat(0.0);
float oney = 1.0/u_tex_size0.y;
- sum += TEX2D(v_texCoord + vec2(0.0, -8.0 * oney)) * vec3_splat(v_coeffs2.w);
- sum += TEX2D(v_texCoord + vec2(0.0, -7.0 * oney)) * vec3_splat(v_coeffs2.z);
- sum += TEX2D(v_texCoord + vec2(0.0, -6.0 * oney)) * vec3_splat(v_coeffs2.y);
- sum += TEX2D(v_texCoord + vec2(0.0, -5.0 * oney)) * vec3_splat(v_coeffs2.x);
- sum += TEX2D(v_texCoord + vec2(0.0, -4.0 * oney)) * vec3_splat(v_coeffs.w);
- sum += TEX2D(v_texCoord + vec2(0.0, -3.0 * oney)) * vec3_splat(v_coeffs.z);
- sum += TEX2D(v_texCoord + vec2(0.0, -2.0 * oney)) * vec3_splat(v_coeffs.y);
- sum += TEX2D(v_texCoord + vec2(0.0, -1.0 * oney)) * vec3_splat(v_coeffs.x);
+ sum += TEX2D(v_texCoord + vec2(0.0, -8.0 * oney)) * vec4_splat(v_coeffs2.w);
+ sum += TEX2D(v_texCoord + vec2(0.0, -7.0 * oney)) * vec4_splat(v_coeffs2.z);
+ sum += TEX2D(v_texCoord + vec2(0.0, -6.0 * oney)) * vec4_splat(v_coeffs2.y);
+ sum += TEX2D(v_texCoord + vec2(0.0, -5.0 * oney)) * vec4_splat(v_coeffs2.x);
+ sum += TEX2D(v_texCoord + vec2(0.0, -4.0 * oney)) * vec4_splat(v_coeffs.w);
+ sum += TEX2D(v_texCoord + vec2(0.0, -3.0 * oney)) * vec4_splat(v_coeffs.z);
+ sum += TEX2D(v_texCoord + vec2(0.0, -2.0 * oney)) * vec4_splat(v_coeffs.y);
+ sum += TEX2D(v_texCoord + vec2(0.0, -1.0 * oney)) * vec4_splat(v_coeffs.x);
sum += TEX2D(v_texCoord);
- sum += TEX2D(v_texCoord + vec2(0.0, +1.0 * oney)) * vec3_splat(v_coeffs.x);
- sum += TEX2D(v_texCoord + vec2(0.0, +2.0 * oney)) * vec3_splat(v_coeffs.y);
- sum += TEX2D(v_texCoord + vec2(0.0, +3.0 * oney)) * vec3_splat(v_coeffs.z);
- sum += TEX2D(v_texCoord + vec2(0.0, +4.0 * oney)) * vec3_splat(v_coeffs.w);
- sum += TEX2D(v_texCoord + vec2(0.0, +5.0 * oney)) * vec3_splat(v_coeffs2.x);
- sum += TEX2D(v_texCoord + vec2(0.0, +6.0 * oney)) * vec3_splat(v_coeffs2.y);
- sum += TEX2D(v_texCoord + vec2(0.0, +7.0 * oney)) * vec3_splat(v_coeffs2.z);
- sum += TEX2D(v_texCoord + vec2(0.0, +8.0 * oney)) * vec3_splat(v_coeffs2.w);
+ sum += TEX2D(v_texCoord + vec2(0.0, +1.0 * oney)) * vec4_splat(v_coeffs.x);
+ sum += TEX2D(v_texCoord + vec2(0.0, +2.0 * oney)) * vec4_splat(v_coeffs.y);
+ sum += TEX2D(v_texCoord + vec2(0.0, +3.0 * oney)) * vec4_splat(v_coeffs.z);
+ sum += TEX2D(v_texCoord + vec2(0.0, +4.0 * oney)) * vec4_splat(v_coeffs.w);
+ sum += TEX2D(v_texCoord + vec2(0.0, +5.0 * oney)) * vec4_splat(v_coeffs2.x);
+ sum += TEX2D(v_texCoord + vec2(0.0, +6.0 * oney)) * vec4_splat(v_coeffs2.y);
+ sum += TEX2D(v_texCoord + vec2(0.0, +7.0 * oney)) * vec4_splat(v_coeffs2.z);
+ sum += TEX2D(v_texCoord + vec2(0.0, +8.0 * oney)) * vec4_splat(v_coeffs2.w);
float norm = 1.0 / (1.0 + 2.0*(v_coeffs.x+v_coeffs.y+v_coeffs.z+v_coeffs.w
+v_coeffs2.x+v_coeffs2.y+v_coeffs2.z+v_coeffs2.w));
- gl_FragColor = vec4( pow(sum*vec3_splat(norm), vec3_splat(1.0/u_gamma.x)), 1.0 );
+ gl_FragColor = pow(sum*vec4_splat(norm), vec4(vec3_splat(1.0/u_gamma.x), 1.0));
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_lowpass.sc b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_lowpass.sc
index 2f48bbac321..37ab685957c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_lowpass.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_lowpass.sc
@@ -33,5 +33,5 @@ void main()
sum +=sample_screen(v_texCoord+vec2(-7.0*onex,0.0))*vec3_splat(v_lpcoeffs2.w);
sum +=sample_screen(v_texCoord+vec2( 7.0*onex,0.0))*vec3_splat(v_lpcoeffs2.w);
- gl_FragColor = vec4( sum, 1.0 );
+ gl_FragColor = vec4( sum, texture2D(s_screen, v_texCoord).a );
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_mipmap8.sc b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_mipmap8.sc
index 0f86bdbc7ba..2e0f8038053 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_mipmap8.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_mipmap8.sc
@@ -22,7 +22,7 @@ uniform vec4 u_smooth;
const vec2 v05 = vec2(0.5,0.5);
// pix has integer coordinates -> average four pixels using bilinear filtering
-vec3 sample_screen(vec2 pix)
+vec4 sample_screen(vec2 pix)
{
vec2 border = step(-0.5, u_tex_size0.xy - pix);
float weight = border.x * border.y;
@@ -34,12 +34,12 @@ vec3 sample_screen(vec2 pix)
border = clamp(u_tex_size0.xy-x,0.0,1.0);
weight *= border.x * border.y;
- vec3 tex = texture2D(s_screen, x / u_tex_size0.xy).rgb;
+ vec4 tex = texture2D(s_screen, x / u_tex_size0.xy);
- return tex * vec3_splat(weight);
+ return tex * vec4_splat(weight);
}
-vec3 sample_mipmap(vec2 pix, vec2 offset, vec2 size)
+vec4 sample_mipmap(vec2 pix, vec2 offset, vec2 size)
{
vec2 border = step(-0.5, size - pix) * step(-0.5, pix);
float weight = border.x * border.y;
@@ -51,9 +51,9 @@ vec3 sample_mipmap(vec2 pix, vec2 offset, vec2 size)
border = clamp(size-x,0.0,1.0);
weight *= border.x * border.y;
- vec3 tex = texture2D(s_mipmap, (x + offset) / u_tex_size0.xy).rgb;
+ vec4 tex = texture2D(s_mipmap, (x + offset) / u_tex_size0.xy);
- return tex * vec3_splat(weight);
+ return tex * vec4_splat(weight);
}
void main()
@@ -66,7 +66,7 @@ void main()
// sample 4x4 grid
// each sample uses bilinear filtering to average a 2x2 region
// overall reduction by 8x8
- vec3 tex = ( sample_screen(x + vec2(-3.0,-3.0))
+ vec4 tex = ( sample_screen(x + vec2(-3.0,-3.0))
+ sample_screen(x + vec2(-3.0,-1.0))
+ sample_screen(x + vec2(-3.0, 1.0))
+ sample_screen(x + vec2(-3.0, 3.0))
@@ -113,7 +113,7 @@ void main()
if (fc)
x = vec2(4.0,4.0);
- vec3 tex = ( sample_mipmap(x + vec2(-3.0,-3.0),offset0,newsize)
+ vec4 tex = ( sample_mipmap(x + vec2(-3.0,-3.0),offset0,newsize)
+ sample_mipmap(x + vec2(-3.0,-1.0),offset0,newsize)
+ sample_mipmap(x + vec2(-3.0, 1.0),offset0,newsize)
+ sample_mipmap(x + vec2(-3.0, 3.0),offset0,newsize)
@@ -133,16 +133,16 @@ void main()
if (fc) { // this sample yields average over the whole screen
// apply a compensation for the zeros included in the 8^n average
float f = fac*fac / (u_tex_size0.x * u_tex_size0.y);
- vec3 col = tex * vec3_splat(f);
+ vec4 col = tex * vec4_splat(f);
if (v_texCoord.y * u_tex_size1.y < ( offset0.y + u_tex_size1.y ) * 0.5) {
- gl_FragColor = vec4(col,1.0);
+ gl_FragColor = col;
} else {
// we are near (1,1): in this region include the temporal filter
vec4 old = texture2D(s_mipmap, v_texCoord.xy);
- gl_FragColor = vec4(mix(col,old.rgb,u_smooth.x),1.0);
+ gl_FragColor = mix(col,old,u_smooth.x);
}
} else {
- gl_FragColor = vec4(tex.rgb,1.0);
+ gl_FragColor = tex;
}
}
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_phosphor_apply.sc b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_phosphor_apply.sc
index c45fb8f883f..f7e116696cb 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_phosphor_apply.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_phosphor_apply.sc
@@ -28,15 +28,15 @@ void main()
vec4 screen = texture2D(s_screen, v_texCoord);
vec4 phosphor = texture2D(s_phosphor, v_texCoord);
- vec3 cscrn = pow(screen.rgb, vec3_splat(u_gamma.x));
- vec3 cphos = pow(phosphor.rgb, vec3_splat(u_gamma.x));
+ vec4 cscrn = pow(screen, vec4(vec3_splat(u_gamma.x), 1.0));
+ vec4 cphos = pow(phosphor, vec4(vec3_splat(u_gamma.x), 1.0));
// encode the upper 2 bits of the time elapsed in the lower 2 bits of b
float t = 255.0*phosphor.a + fract(phosphor.b*255.0/4.0)*1024.0;
- cphos *= vec3_splat( u_phosphor_amplitude.x * decay(t) );
+ cphos *= vec4_splat( u_phosphor_amplitude.x * decay(t) );
- vec3 col = pow(cscrn + cphos, vec3_splat(1.0/u_gamma.x));
+ vec4 col = pow(cscrn + cphos, vec4(vec3_splat(1.0/u_gamma.x), 1.0));
- gl_FragColor = vec4(col, 1.0);
+ gl_FragColor = col;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_crt-geom.sc b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_crt-geom.sc
index cc3ed09aa14..4f17f0d0ec3 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_crt-geom.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_crt-geom.sc
@@ -19,78 +19,82 @@ uniform vec4 R;
uniform vec4 angle;
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
uniform vec4 u_rotation_type;
#define FIX(c) max(abs(c), 1e-5)
float intersect(vec2 xy , vec2 sinangle, vec2 cosangle)
{
- float A = dot(xy,xy)+d.x*d.x;
- float B = 2.0*(R.x*(dot(xy,sinangle)-d.x*cosangle.x*cosangle.y)-d.x*d.x);
- float C = d.x*d.x + 2.0*R.x*d.x*cosangle.x*cosangle.y;
- return (-B-sqrt(B*B-4.0*A*C))/(2.0*A);
+ float A = dot(xy,xy)+d.x*d.x;
+ float B = 2.0*(R.x*(dot(xy,sinangle)-d.x*cosangle.x*cosangle.y)-d.x*d.x);
+ float C = d.x*d.x + 2.0*R.x*d.x*cosangle.x*cosangle.y;
+ return (-B-sqrt(B*B-4.0*A*C))/(2.0*A);
}
vec2 bkwtrans(vec2 xy, vec2 sinangle, vec2 cosangle)
{
- float c = intersect(xy, sinangle, cosangle);
- vec2 pt = vec2_splat(c)*xy;
- pt -= vec2_splat(-R.x)*sinangle;
- pt /= vec2_splat(R.x);
- vec2 tang = sinangle/cosangle;
- vec2 poc = pt/cosangle;
- float A = dot(tang,tang)+1.0;
- float B = -2.0*dot(poc,tang);
- float C = dot(poc,poc)-1.0;
- float a = (-B+sqrt(B*B-4.0*A*C))/(2.0*A);
- vec2 uv = (pt-a*sinangle)/cosangle;
- float r = FIX(R.x*acos(a));
- return uv*r/sin(r/R.x);
+ float c = intersect(xy, sinangle, cosangle);
+ vec2 pt = vec2_splat(c)*xy;
+ pt -= vec2_splat(-R.x)*sinangle;
+ pt /= vec2_splat(R.x);
+ vec2 tang = sinangle/cosangle;
+ vec2 poc = pt/cosangle;
+ float A = dot(tang,tang)+1.0;
+ float B = -2.0*dot(poc,tang);
+ float C = dot(poc,poc)-1.0;
+ float a = (-B+sqrt(B*B-4.0*A*C))/(2.0*A);
+ vec2 uv = (pt-a*sinangle)/cosangle;
+ float r = FIX(R.x*acos(a));
+ return uv*r/sin(r/R.x);
}
vec2 fwtrans(vec2 uv, vec2 sinangle, vec2 cosangle)
{
- float r = FIX(sqrt(dot(uv,uv)));
- uv *= sin(r/R.x)/r;
- float x = 1.0-cos(r/R.x);
- float D = d.x/R.x + x*cosangle.x*cosangle.y+dot(uv,sinangle);
- return d.x*(uv*cosangle-x*sinangle)/D;
+ float r = FIX(sqrt(dot(uv,uv)));
+ uv *= sin(r/R.x)/r;
+ float x = 1.0-cos(r/R.x);
+ float D = d.x/R.x + x*cosangle.x*cosangle.y+dot(uv,sinangle);
+ return d.x*(uv*cosangle-x*sinangle)/D;
}
vec3 maxscale(vec2 sinangle, vec2 cosangle)
{
- vec2 c = bkwtrans(-R.x * sinangle / (1.0 + R.x/d.x*cosangle.x*cosangle.y), sinangle, cosangle);
- vec2 a = vec2(0.5,0.5)*aspect.xy;
- vec2 lo = vec2(fwtrans(vec2(-a.x,c.y), sinangle, cosangle).x,
- fwtrans(vec2(c.x,-a.y), sinangle, cosangle).y)/aspect.xy;
- vec2 hi = vec2(fwtrans(vec2(+a.x,c.y), sinangle, cosangle).x,
- fwtrans(vec2(c.x,+a.y), sinangle, cosangle).y)/aspect.xy;
- return vec3((hi+lo)*aspect.xy*0.5,max(hi.x-lo.x,hi.y-lo.y));
+ vec2 c = bkwtrans(-R.x * sinangle / (1.0 + R.x/d.x*cosangle.x*cosangle.y), sinangle, cosangle);
+ vec2 a = vec2(0.5,0.5)*aspect.xy;
+ vec2 lo = vec2(fwtrans(vec2(-a.x,c.y), sinangle, cosangle).x,
+ fwtrans(vec2(c.x,-a.y), sinangle, cosangle).y)/aspect.xy;
+ vec2 hi = vec2(fwtrans(vec2(+a.x,c.y), sinangle, cosangle).x,
+ fwtrans(vec2(c.x,+a.y), sinangle, cosangle).y)/aspect.xy;
+ return vec3((hi+lo)*aspect.xy*0.5,max(hi.x-lo.x,hi.y-lo.y));
}
void main()
{
- // Do the standard vertex processing.
- gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
- v_texCoord = a_texcoord0;
+ // Do the standard vertex processing.
+ gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
+ v_texCoord = a_texcoord0;
- // Precalculate a bunch of useful values we'll need in the fragment
- // shader.
- vec2 ang;
- // if (u_rotation_type.x < 0.5)
- // ang = vec2(0.0,angle.x);
- // else if (u_rotation_type.x < 1.5)
- // ang = vec2(angle.x,0.0);
- // else if (u_rotation_type.x < 2.5)
- // ang = vec2(0.0,-angle.x);
- // else
- // ang = vec2(-angle.x,0.0);
- ang = angle.xy;
- v_sinangle = sin(ang);
- v_cosangle = cos(ang);
- v_stretch = maxscale(v_sinangle, v_cosangle);
+ // Precalculate a bunch of useful values we'll need in the fragment
+ // shader.
+ vec2 ang;
+ // if (u_rotation_type.x < 0.5)
+ // ang = vec2(0.0,angle.x);
+ // else if (u_rotation_type.x < 1.5)
+ // ang = vec2(angle.x,0.0);
+ // else if (u_rotation_type.x < 2.5)
+ // ang = vec2(0.0,-angle.x);
+ // else
+ // ang = vec2(-angle.x,0.0);
+ ang = angle.xy;
+ v_sinangle = sin(ang);
+ v_cosangle = cos(ang);
+ v_stretch = maxscale(v_sinangle, v_cosangle);
- // The size of one texel, in texture-coordinates.
- v_one = 1.0 / u_tex_size0.xy;
+ // The size of one texel, in texture-coordinates.
+ v_one = 1.0 / u_tex_size0.xy;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_gaussx.sc b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_gaussx.sc
index e9969187c94..a5fb1d22622 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_gaussx.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_gaussx.sc
@@ -4,16 +4,20 @@ $output v_texCoord, v_coeffs, v_coeffs2
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
uniform vec4 u_width;
uniform vec4 u_aspect;
void main()
{
- float wid = u_width.x*u_tex_size0.x/(320.*u_aspect.x);
- v_coeffs = exp(vec4(1.,4.,9.,16.)*vec4_splat(-1.0/wid/wid));
- v_coeffs2 = exp(vec4(25.,36.,49.,64.)*vec4_splat(-1.0/wid/wid));
+ float wid = u_width.x*u_tex_size0.x/(320.*u_aspect.x);
+ v_coeffs = exp(vec4(1.,4.,9.,16.)*vec4_splat(-1.0/wid/wid));
+ v_coeffs2 = exp(vec4(25.,36.,49.,64.)*vec4_splat(-1.0/wid/wid));
- // Do the standard vertex processing.
- gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
- v_texCoord = a_texcoord0;
+ // Do the standard vertex processing.
+ gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
+ v_texCoord = a_texcoord0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_gaussy.sc b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_gaussy.sc
index 0b7ff9b411f..93676cde1d5 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_gaussy.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_gaussy.sc
@@ -4,16 +4,20 @@ $output v_texCoord, v_coeffs, v_coeffs2
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
uniform vec4 u_width;
uniform vec4 u_aspect;
void main()
{
- float wid = u_width.x*u_tex_size0.y/(320.*u_aspect.y);
- v_coeffs = exp(vec4(1.,4.,9.,16.)*vec4_splat(-1.0/wid/wid));
- v_coeffs2 = exp(vec4(25.,36.,49.,64.)*vec4_splat(-1.0/wid/wid));
+ float wid = u_width.x*u_tex_size0.y/(320.*u_aspect.y);
+ v_coeffs = exp(vec4(1.,4.,9.,16.)*vec4_splat(-1.0/wid/wid));
+ v_coeffs2 = exp(vec4(25.,36.,49.,64.)*vec4_splat(-1.0/wid/wid));
- // Do the standard vertex processing.
- gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
- v_texCoord = a_texcoord0;
+ // Do the standard vertex processing.
+ gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
+ v_texCoord = a_texcoord0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_lowpass.sc b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_lowpass.sc
index 4d948a63a89..2ca983d41d7 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_lowpass.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_lowpass.sc
@@ -4,46 +4,50 @@ $output v_texCoord, v_lpcoeffs1, v_lpcoeffs2
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
uniform vec4 u_lowpass_cutoff;
uniform vec4 u_lowpass_width;
void main()
{
- // Do the standard vertex processing.
- gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
- v_texCoord = a_texcoord0;
+ // Do the standard vertex processing.
+ gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
+ v_texCoord = a_texcoord0;
- // interpret the cutoff and width as target resolutions in pixels per scanline
- // include factor of 1/2 because max frequency at given resolution is Nyquist
- float a = 0.5 * u_lowpass_cutoff.x / u_tex_size0.x;
- float b = 0.5 * u_lowpass_width.x / u_tex_size0.x;
- float w0 = (a-0.5*b);
- float w1 = (a+0.5*b);
+ // interpret the cutoff and width as target resolutions in pixels per scanline
+ // include factor of 1/2 because max frequency at given resolution is Nyquist
+ float a = 0.5 * u_lowpass_cutoff.x / u_tex_size0.x;
+ float b = 0.5 * u_lowpass_width.x / u_tex_size0.x;
+ float w0 = (a-0.5*b);
+ float w1 = (a+0.5*b);
- float two_pi = 6.283185307179586;
- vec3 n1 = vec3(1.0,2.0,3.0);
- vec4 n2 = vec4(4.0,5.0,6.0,7.0);
+ float two_pi = 6.283185307179586;
+ vec3 n1 = vec3(1.0,2.0,3.0);
+ vec4 n2 = vec4(4.0,5.0,6.0,7.0);
- // target frequency response:
- // 1 for w < w0
- // 0 for w > w1
- // linearly decreasing for w0 < w < w1
- // this will be approximated by including the lowest Fourier modes
- if (w0 > 0.5) { // no filtering
- v_lpcoeffs1 = vec4(1.0,0.0,0.0,0.0);
- v_lpcoeffs2 = vec4_splat(0.0);
- } else if (w1 > 0.5) { // don't reach zero
- // here the target has a nonzero response at the Nyquist frequency
- v_lpcoeffs1.x = w1 + w0 - (w1 - 0.5)*(w1 - 0.5)/(w1 - w0);
- v_lpcoeffs1.yzw = 2.0 / ( two_pi*two_pi*(w1-w0)*n1*n1 ) * ( cos(two_pi*w0*n1) - cos(two_pi*0.5*n1) );
- v_lpcoeffs2 = 2.0 / ( two_pi*two_pi*(w1-w0)*n2*n2 ) * ( cos(two_pi*w0*n2) - cos(two_pi*0.5*n2) );
- } else if (w1 == w0) { // sharp cutoff
- v_lpcoeffs1.x = 2.0 * w0;
- v_lpcoeffs1.yzw = 2.0 / ( two_pi * n1 ) * sin(two_pi*w0*n1);
- v_lpcoeffs2 = 2.0 / ( two_pi * n2 ) * sin(two_pi*w0*n2);
- } else {
- v_lpcoeffs1.x = w1 + w0;
- v_lpcoeffs1.yzw = 2.0 / ( two_pi*two_pi*(w1-w0)*n1*n1 ) * ( cos(two_pi*w0*n1) - cos(two_pi*w1*n1) );
- v_lpcoeffs2 = 2.0 / ( two_pi*two_pi*(w1-w0)*n2*n2 ) * ( cos(two_pi*w0*n2) - cos(two_pi*w1*n2) );
- }
+ // target frequency response:
+ // 1 for w < w0
+ // 0 for w > w1
+ // linearly decreasing for w0 < w < w1
+ // this will be approximated by including the lowest Fourier modes
+ if (w0 > 0.5) { // no filtering
+ v_lpcoeffs1 = vec4(1.0,0.0,0.0,0.0);
+ v_lpcoeffs2 = vec4_splat(0.0);
+ } else if (w1 > 0.5) { // don't reach zero
+ // here the target has a nonzero response at the Nyquist frequency
+ v_lpcoeffs1.x = w1 + w0 - (w1 - 0.5)*(w1 - 0.5)/(w1 - w0);
+ v_lpcoeffs1.yzw = 2.0 / ( two_pi*two_pi*(w1-w0)*n1*n1 ) * ( cos(two_pi*w0*n1) - cos(two_pi*0.5*n1) );
+ v_lpcoeffs2 = 2.0 / ( two_pi*two_pi*(w1-w0)*n2*n2 ) * ( cos(two_pi*w0*n2) - cos(two_pi*0.5*n2) );
+ } else if (w1 == w0) { // sharp cutoff
+ v_lpcoeffs1.x = 2.0 * w0;
+ v_lpcoeffs1.yzw = 2.0 / ( two_pi * n1 ) * sin(two_pi*w0*n1);
+ v_lpcoeffs2 = 2.0 / ( two_pi * n2 ) * sin(two_pi*w0*n2);
+ } else {
+ v_lpcoeffs1.x = w1 + w0;
+ v_lpcoeffs1.yzw = 2.0 / ( two_pi*two_pi*(w1-w0)*n1*n1 ) * ( cos(two_pi*w0*n1) - cos(two_pi*w1*n1) );
+ v_lpcoeffs2 = 2.0 / ( two_pi*two_pi*(w1-w0)*n2*n2 ) * ( cos(two_pi*w0*n2) - cos(two_pi*w1*n2) );
+ }
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_mipmap8.sc b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_mipmap8.sc
index bdd09148403..8424e153cdb 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_mipmap8.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_mipmap8.sc
@@ -3,9 +3,14 @@ $output v_texCoord
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
- // Do the standard vertex processing.
- gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
- v_texCoord = a_texcoord0;
+ // Do the standard vertex processing.
+ gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
+ v_texCoord = a_texcoord0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_phosphor_apply.sc b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_phosphor_apply.sc
index bdd09148403..8424e153cdb 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_phosphor_apply.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_phosphor_apply.sc
@@ -3,9 +3,14 @@ $output v_texCoord
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
- // Do the standard vertex processing.
- gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
- v_texCoord = a_texcoord0;
+ // Do the standard vertex processing.
+ gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
+ v_texCoord = a_texcoord0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_phosphor_update.sc b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_phosphor_update.sc
index bdd09148403..8424e153cdb 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_phosphor_update.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_phosphor_update.sc
@@ -3,9 +3,14 @@ $output v_texCoord
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
- // Do the standard vertex processing.
- gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
- v_texCoord = a_texcoord0;
+ // Do the standard vertex processing.
+ gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
+ v_texCoord = a_texcoord0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt/vs_crt-caligari.sc b/src/osd/modules/render/bgfx/shaders/chains/crt/vs_crt-caligari.sc
index 6dead210d9e..ce22c1e7200 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/crt/vs_crt-caligari.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt/vs_crt-caligari.sc
@@ -32,10 +32,14 @@ $output v_texcoord0, v_texcoord1, v_color0
// Autos
uniform vec4 u_source_size;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
onex = vec2(1.0 / u_source_size.x, 0.0);
diff --git a/src/osd/modules/render/bgfx/shaders/chains/default/vs_blit.sc b/src/osd/modules/render/bgfx/shaders/chains/default/vs_blit.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/default/vs_blit.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/default/vs_blit.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/eagle/fs_eagle.sc b/src/osd/modules/render/bgfx/shaders/chains/eagle/fs_eagle.sc
index 5219614c794..ca769f5dc07 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/eagle/fs_eagle.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/eagle/fs_eagle.sc
@@ -122,16 +122,16 @@ void main()
else
{
p01 = 0.5 * (C4 + C5);
- }
+ }
- if ((c8 == d2) || (c3 == c4))
- {
+ if ((c8 == d2) || (c3 == c4))
+ {
p10 = 0.25 * (3.0 * C4 + C7);
- }
- else
- {
+ }
+ else
+ {
p10 = 0.5 * (C7 + C8);
- }
+ }
}
else
{
diff --git a/src/osd/modules/render/bgfx/shaders/chains/eagle/vs_eagle.sc b/src/osd/modules/render/bgfx/shaders/chains/eagle/vs_eagle.sc
index 1ab076dfa73..095d5d562e0 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/eagle/vs_eagle.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/eagle/vs_eagle.sc
@@ -14,10 +14,14 @@ $output v_color0, texCoord, t1, t2, t3, t4, t5, t6, t7, t8
// Autos
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_color0 = a_color0;
vec2 ps = vec2(1.0, 1.0) / u_tex_size0.xy;
diff --git a/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_defocus.sc b/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_defocus.sc
index cfb7b487596..20820f0c0a3 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_defocus.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_defocus.sc
@@ -25,7 +25,7 @@ void main()
{
// previously this pass was applied two times with offsets of 0.25, 0.5, 0.75, 1.0
// now this pass is applied only once with offsets of 0.25, 0.55, 1.0, 1.6 to achieve the same appearance as before till a maximum defocus of 2.0
- // 0.075x² + 0.225x + 0.25
+ // 0.075x² + 0.225x + 0.25
const vec2 Coord1Offset = vec2(-1.60, 0.25);
const vec2 Coord2Offset = vec2(-1.00, -0.55);
const vec2 Coord3Offset = vec2(-0.55, 1.00);
diff --git a/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_distortion.sc b/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_distortion.sc
index 47201c0661d..ed4f6195944 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_distortion.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_distortion.sc
@@ -134,11 +134,11 @@ vec2 GetDistortedCoords(vec2 centerCoord, float amount, float amountCube)
float r2 = centerCoord.x * centerCoord.x + centerCoord.y * centerCoord.y;
float f = kcube == 0.0 ? 1.0 + r2 * k : 1.0 + r2 * (k + kcube * sqrt(r2));
- // fit screen bounds
+ // fit screen bounds
f /= 1.0 + amount * 0.25 + amountCube * 0.125;
// apply cubic distortion factor
- centerCoord *= f;
+ centerCoord *= f;
return centerCoord;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_scanline.sc b/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_scanline.sc
index 5942c75bab6..2126398062b 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_scanline.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_scanline.sc
@@ -37,34 +37,15 @@ SAMPLER2D(s_shadow, 1);
// Scanline Pixel Shader
//-----------------------------------------------------------------------------
-vec2 GetAdjustedCoords(vec2 coord)
-{
- // center coordinates
- coord -= 0.5;
-
- // apply screen scale
- coord *= u_screen_scale.xy;
-
- // un-center coordinates
- coord += 0.5;
-
- // apply screen offset
- coord += u_screen_offset.xy;
-
- return coord;
-}
-
void main()
{
- vec2 BaseCoord = GetAdjustedCoords(v_texcoord0);
-
// Color
- vec4 BaseColor = texture2D(s_tex, BaseCoord);
+ vec4 BaseColor = texture2D(s_tex, v_texcoord0);
// Clamp
- if (BaseCoord.x < 0.0 || BaseCoord.y < 0.0 || BaseCoord.x > 1.0 || BaseCoord.y > 1.0)
+ if (v_texcoord0.x < 0.0 || v_texcoord0.y < 0.0 || v_texcoord0.x > 1.0 || v_texcoord0.y > 1.0)
{
- gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
}
else
{
@@ -76,7 +57,7 @@ void main()
float ColorBrightness = 0.299 * BaseColor.r + 0.587 * BaseColor.g + 0.114 * BaseColor.b;
- float ScanCoord = BaseCoord.y;
+ float ScanCoord = v_texcoord0.y;
ScanCoord += u_swap_xy.x > 0.0
? u_quad_dims.x <= u_source_dims.x * 2.0
? 0.5 / u_quad_dims.x // uncenter scanlines if the quad is less than twice the size of the source
diff --git a/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_chroma.sc b/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_chroma.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_chroma.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_chroma.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_color.sc b/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_color.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_color.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_color.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_deconverge.sc b/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_deconverge.sc
index b77d85d1ea8..55c2f0e2e34 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_deconverge.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_deconverge.sc
@@ -8,6 +8,7 @@ $output v_color0, v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3
// Autos
uniform vec4 u_source_size;
+uniform vec4 u_inv_view_dims;
// User-supplied
uniform vec4 u_converge_red;
@@ -20,6 +21,9 @@ uniform vec4 u_radial_converge_blue;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
vec2 half_value = vec2(0.5, 0.5);
diff --git a/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_defocus.sc b/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_defocus.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_defocus.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_defocus.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_distortion.sc b/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_distortion.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_distortion.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_distortion.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_ntsc_decode.sc b/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_ntsc_decode.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_ntsc_decode.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_ntsc_decode.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_ntsc_encode.sc b/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_ntsc_encode.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_ntsc_encode.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_ntsc_encode.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_phosphor.sc b/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_phosphor.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_phosphor.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_phosphor.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_post.sc b/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_post.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_post.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_post.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_prescale.sc b/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_prescale.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_prescale.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_prescale.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_scanline.sc b/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_scanline.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_scanline.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/hlsl/vs_scanline.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/hqx/fs_hq2x.sc b/src/osd/modules/render/bgfx/shaders/chains/hqx/fs_hq2x.sc
index 479ed825a8b..3f6c2645ba4 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/hqx/fs_hq2x.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/hqx/fs_hq2x.sc
@@ -60,8 +60,8 @@ void main()
vec2 index;
index.x = dot(pattern[0], vec3( 1.0, 2.0, 4.0)) +
- dot(pattern[1], vec3( 8.0, 0.0, 16.0)) +
- dot(pattern[2], vec3(32.0, 64.0, 128.0));
+ dot(pattern[1], vec3( 8.0, 0.0, 16.0)) +
+ dot(pattern[2], vec3(32.0, 64.0, 128.0));
index.y = dot(cross, vec4(1.0, 2.0, 4.0, 8.0)) * SCALE * SCALE + dot(floor(fp * vec2(SCALE, SCALE)), vec2(1.0, SCALE));
vec2 step = vec2(1.0, 1.0) / vec2(256.0, 16.0 * (SCALE * SCALE));
diff --git a/src/osd/modules/render/bgfx/shaders/chains/hqx/fs_hq3x.sc b/src/osd/modules/render/bgfx/shaders/chains/hqx/fs_hq3x.sc
index 1d35cec01e6..1cb08a52da4 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/hqx/fs_hq3x.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/hqx/fs_hq3x.sc
@@ -60,8 +60,8 @@ void main()
vec2 index;
index.x = dot(pattern[0], vec3( 1.0, 2.0, 4.0)) +
- dot(pattern[1], vec3( 8.0, 0.0, 16.0)) +
- dot(pattern[2], vec3(32.0, 64.0, 128.0));
+ dot(pattern[1], vec3( 8.0, 0.0, 16.0)) +
+ dot(pattern[2], vec3(32.0, 64.0, 128.0));
index.y = dot(cross, vec4(1.0, 2.0, 4.0, 8.0)) * SCALE * SCALE + dot(floor(fp * vec2(SCALE, SCALE)), vec2(1.0, SCALE));
vec2 step = vec2(1.0, 1.0) / vec2(256.0, 16.0 * (SCALE * SCALE));
diff --git a/src/osd/modules/render/bgfx/shaders/chains/hqx/fs_hq4x.sc b/src/osd/modules/render/bgfx/shaders/chains/hqx/fs_hq4x.sc
index 6f25b0e9cc3..6e87d47dc0c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/hqx/fs_hq4x.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/hqx/fs_hq4x.sc
@@ -60,8 +60,8 @@ void main()
vec2 index;
index.x = dot(pattern[0], vec3( 1.0, 2.0, 4.0)) +
- dot(pattern[1], vec3( 8.0, 0.0, 16.0)) +
- dot(pattern[2], vec3(32.0, 64.0, 128.0));
+ dot(pattern[1], vec3( 8.0, 0.0, 16.0)) +
+ dot(pattern[2], vec3(32.0, 64.0, 128.0));
index.y = dot(cross, vec4(1.0, 2.0, 4.0, 8.0)) * SCALE * SCALE + dot(floor(fp * vec2(SCALE, SCALE)), vec2(1.0, SCALE));
vec2 step = vec2(1.0, 1.0) / vec2(256.0, 16.0 * (SCALE * SCALE));
diff --git a/src/osd/modules/render/bgfx/shaders/chains/hqx/vs_hq2x.sc b/src/osd/modules/render/bgfx/shaders/chains/hqx/vs_hq2x.sc
index dcff07b17f5..727f5763857 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/hqx/vs_hq2x.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/hqx/vs_hq2x.sc
@@ -8,10 +8,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_color0
// Autos
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_color0 = a_color0;
vec2 ps = vec2(1.0, 1.0) / u_tex_size0.xy;
diff --git a/src/osd/modules/render/bgfx/shaders/chains/hqx/vs_hq3x.sc b/src/osd/modules/render/bgfx/shaders/chains/hqx/vs_hq3x.sc
index dcff07b17f5..727f5763857 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/hqx/vs_hq3x.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/hqx/vs_hq3x.sc
@@ -8,10 +8,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_color0
// Autos
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_color0 = a_color0;
vec2 ps = vec2(1.0, 1.0) / u_tex_size0.xy;
diff --git a/src/osd/modules/render/bgfx/shaders/chains/hqx/vs_hq4x.sc b/src/osd/modules/render/bgfx/shaders/chains/hqx/vs_hq4x.sc
index dcff07b17f5..727f5763857 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/hqx/vs_hq4x.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/hqx/vs_hq4x.sc
@@ -8,10 +8,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_color0
// Autos
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_color0 = a_color0;
vec2 ps = vec2(1.0, 1.0) / u_tex_size0.xy;
diff --git a/src/osd/modules/render/bgfx/shaders/chains/lcd-grid/fs_lcd-grid.sc b/src/osd/modules/render/bgfx/shaders/chains/lcd-grid/fs_lcd-grid.sc
index 9ed2a47e801..801d1a2e9a4 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/lcd-grid/fs_lcd-grid.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/lcd-grid/fs_lcd-grid.sc
@@ -22,85 +22,85 @@ uniform vec4 u_subpixsize;
vec3 fetch_offset(vec2 coord, vec2 offset)
{
- vec2 x = coord + offset;
- vec3 col = texture2D(s_tex, x).rgb;
- vec3 col2 = pow(vec3_splat(u_gain.x) * col + vec3_splat(u_blacklevel.x), vec3_splat(u_LCDgamma.x)) + vec3_splat(u_ambient.x);
- // want zero for outside pixels
- vec4 b = step(0.0,vec4(x.x,x.y,1.0-x.x,1.0-x.y));
- return vec3_splat(b.x*b.y*b.z*b.w) * col2;
+ vec2 x = coord + offset;
+ vec3 col = texture2D(s_tex, x).rgb;
+ vec3 col2 = pow(vec3_splat(u_gain.x) * col + vec3_splat(u_blacklevel.x), vec3_splat(u_LCDgamma.x)) + vec3_splat(u_ambient.x);
+ // want zero for outside pixels
+ vec4 b = step(0.0,vec4(x.x,x.y,1.0-x.x,1.0-x.y));
+ return vec3_splat(b.x*b.y*b.z*b.w) * col2;
}
float intsmear_func(float z, float c1, float c2, float c3, float c4, float c5, float c6)
{
- float z2 = z*z;
- // both cases have c0=1
- return z * (1.0 + z2*(c1 + z2*(c2 + z2*(c3 + z2*(c4 + z2*(c5 + z2*c6))))));
+ float z2 = z*z;
+ // both cases have c0=1
+ return z * (1.0 + z2*(c1 + z2*(c2 + z2*(c3 + z2*(c4 + z2*(c5 + z2*c6))))));
}
float intsmear_fx(float z)
{
- // integral of (1 - x^2 - x^4 + x^6)^2
- return intsmear_func(z, -2.0/3.0, -1.0/5.0, 4.0/7.0, -1.0/9.0, -2.0/11.0, 1.0/13.0);
+ // integral of (1 - x^2 - x^4 + x^6)^2
+ return intsmear_func(z, -2.0/3.0, -1.0/5.0, 4.0/7.0, -1.0/9.0, -2.0/11.0, 1.0/13.0);
}
float intsmear_fy(float z)
{
- // integral of (1 - 2x^4 + x^6)^2
- return intsmear_func(z, 0.0, -4.0/5.0, 2.0/7.0, 4.0/9.0, -4.0/11.0, 1.0/13.0);
+ // integral of (1 - 2x^4 + x^6)^2
+ return intsmear_func(z, 0.0, -4.0/5.0, 2.0/7.0, 4.0/9.0, -4.0/11.0, 1.0/13.0);
}
float intsmear_x(float x, float dx, float d)
{
- float zl = clamp((x-dx*0.5)/d,-1.0,1.0);
- float zh = clamp((x+dx*0.5)/d,-1.0,1.0);
- return d * ( intsmear_fx(zh) - intsmear_fx(zl) )/dx;
+ float zl = clamp((x-dx*0.5)/d,-1.0,1.0);
+ float zh = clamp((x+dx*0.5)/d,-1.0,1.0);
+ return d * ( intsmear_fx(zh) - intsmear_fx(zl) )/dx;
}
float intsmear_y(float x, float dx, float d)
{
- float zl = clamp((x-dx*0.5)/d,-1.0,1.0);
- float zh = clamp((x+dx*0.5)/d,-1.0,1.0);
- return d * ( intsmear_fy(zh) - intsmear_fy(zl) )/dx;
+ float zl = clamp((x-dx*0.5)/d,-1.0,1.0);
+ float zh = clamp((x+dx*0.5)/d,-1.0,1.0);
+ return d * ( intsmear_fy(zh) - intsmear_fy(zl) )/dx;
}
void main()
{
- vec3 cr = pow(u_rsubpix.rgb, vec3_splat(u_monitorgamma.x));
- vec3 cg = pow(u_gsubpix.rgb, vec3_splat(u_monitorgamma.x));
- vec3 cb = pow(u_bsubpix.rgb, vec3_splat(u_monitorgamma.x));
-
- vec2 tl = v_texcoord0 * u_tex_size0.xy - vec2(0.5,0.5);
- vec2 tli = floor(tl);
- float subpix = fract(tl.x) * 3.0;
- float rsubpix = u_tex_size0.x / u_quad_dims.x * 3.0;
-
- vec3 lcol, rcol;
- lcol = vec3(intsmear_x(subpix+1.0, rsubpix, 3.0*u_subpixsize.x),
- intsmear_x(subpix , rsubpix, 3.0*u_subpixsize.x),
- intsmear_x(subpix-1.0, rsubpix, 3.0*u_subpixsize.x));
- rcol = vec3(intsmear_x(subpix-2.0, rsubpix, 3.0*u_subpixsize.x),
- intsmear_x(subpix-3.0, rsubpix, 3.0*u_subpixsize.x),
- intsmear_x(subpix-4.0, rsubpix, 3.0*u_subpixsize.x));
-
- if (u_BGR.x > 0.5) {
- lcol.rgb = lcol.bgr;
- rcol.rgb = rcol.bgr;
- }
-
- float tcol, bcol;
- subpix = fract(tl.y);
- rsubpix = u_tex_size0.y / u_quad_dims.y;
- tcol = intsmear_y(subpix ,rsubpix, u_subpixsize.y);
- bcol = intsmear_y(subpix-1.0,rsubpix, u_subpixsize.y);
-
- tl = (tli + vec2_splat(0.5)) / u_tex_size0.xy;
- vec2 one = vec2_splat(1.0) / u_tex_size0.xy;
-
- vec3 ul = fetch_offset(tl, vec2(0,0) ) * lcol * vec3_splat(tcol);
- vec3 br = fetch_offset(tl, one ) * rcol * vec3_splat(bcol);
- vec3 bl = fetch_offset(tl, vec2(0,one.y)) * lcol * vec3_splat(bcol);
- vec3 ur = fetch_offset(tl, vec2(one.x,0)) * rcol * vec3_splat(tcol);
-
- vec3 csum = ul + br + bl + ur;
- vec3 col = mul(mtxFromCols(u_rsubpix.rgb, u_gsubpix.rgb, u_bsubpix.rgb), csum);
- gl_FragColor = vec4(pow(col, vec3_splat(1.0/u_monitorgamma.x)), 1.0);
+ vec3 cr = pow(u_rsubpix.rgb, vec3_splat(u_monitorgamma.x));
+ vec3 cg = pow(u_gsubpix.rgb, vec3_splat(u_monitorgamma.x));
+ vec3 cb = pow(u_bsubpix.rgb, vec3_splat(u_monitorgamma.x));
+
+ vec2 tl = v_texcoord0 * u_tex_size0.xy - vec2(0.5,0.5);
+ vec2 tli = floor(tl);
+ float subpix = fract(tl.x) * 3.0;
+ float rsubpix = u_tex_size0.x / u_quad_dims.x * 3.0;
+
+ vec3 lcol, rcol;
+ lcol = vec3(intsmear_x(subpix+1.0, rsubpix, 3.0*u_subpixsize.x),
+ intsmear_x(subpix , rsubpix, 3.0*u_subpixsize.x),
+ intsmear_x(subpix-1.0, rsubpix, 3.0*u_subpixsize.x));
+ rcol = vec3(intsmear_x(subpix-2.0, rsubpix, 3.0*u_subpixsize.x),
+ intsmear_x(subpix-3.0, rsubpix, 3.0*u_subpixsize.x),
+ intsmear_x(subpix-4.0, rsubpix, 3.0*u_subpixsize.x));
+
+ if (u_BGR.x > 0.5) {
+ lcol.rgb = lcol.bgr;
+ rcol.rgb = rcol.bgr;
+ }
+
+ float tcol, bcol;
+ subpix = fract(tl.y);
+ rsubpix = u_tex_size0.y / u_quad_dims.y;
+ tcol = intsmear_y(subpix ,rsubpix, u_subpixsize.y);
+ bcol = intsmear_y(subpix-1.0,rsubpix, u_subpixsize.y);
+
+ tl = (tli + vec2_splat(0.5)) / u_tex_size0.xy;
+ vec2 one = vec2_splat(1.0) / u_tex_size0.xy;
+
+ vec3 ul = fetch_offset(tl, vec2(0,0) ) * lcol * vec3_splat(tcol);
+ vec3 br = fetch_offset(tl, one ) * rcol * vec3_splat(bcol);
+ vec3 bl = fetch_offset(tl, vec2(0,one.y)) * lcol * vec3_splat(bcol);
+ vec3 ur = fetch_offset(tl, vec2(one.x,0)) * rcol * vec3_splat(tcol);
+
+ vec3 csum = ul + br + bl + ur;
+ vec3 col = mul(mtxFromCols(u_rsubpix.rgb, u_gsubpix.rgb, u_bsubpix.rgb), csum);
+ gl_FragColor = vec4(pow(col, vec3_splat(1.0/u_monitorgamma.x)), 1.0);
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/lcd-grid/fs_persistence.sc b/src/osd/modules/render/bgfx/shaders/chains/lcd-grid/fs_persistence.sc
index 0187b8c90d2..4c9e998d3ec 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/lcd-grid/fs_persistence.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/lcd-grid/fs_persistence.sc
@@ -9,8 +9,8 @@ uniform vec4 u_persistence;
void main()
{
- vec4 screen = texture2D(s_screen , v_texcoord0);
- vec4 motionblur = texture2D(s_motionblur, v_texcoord0);
+ vec4 screen = texture2D(s_screen , v_texcoord0);
+ vec4 motionblur = texture2D(s_motionblur, v_texcoord0);
- gl_FragColor = mix(screen, motionblur, u_persistence.x);
+ gl_FragColor = mix(screen, motionblur, u_persistence.x);
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/lcd-grid/vs_lcd-grid.sc b/src/osd/modules/render/bgfx/shaders/chains/lcd-grid/vs_lcd-grid.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/lcd-grid/vs_lcd-grid.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/lcd-grid/vs_lcd-grid.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/lcd-grid/vs_persistence.sc b/src/osd/modules/render/bgfx/shaders/chains/lcd-grid/vs_persistence.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/lcd-grid/vs_persistence.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/lcd-grid/vs_persistence.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/misc/fs_deposterize-pass0.sc b/src/osd/modules/render/bgfx/shaders/chains/misc/fs_deposterize-pass0.sc
index 3e58af492c6..090485da1bc 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/misc/fs_deposterize-pass0.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/misc/fs_deposterize-pass0.sc
@@ -20,7 +20,7 @@ uniform vec4 DIFF_THRESH1;
vec3 df3(vec3 c1, vec3 c2)
{
- return abs(c1 - c2);
+ return abs(c1 - c2);
}
bvec3 le3(vec3 A, vec3 B, vec3 param)
diff --git a/src/osd/modules/render/bgfx/shaders/chains/misc/fs_deposterize-pass1.sc b/src/osd/modules/render/bgfx/shaders/chains/misc/fs_deposterize-pass1.sc
index 8fdd168a262..085f767358c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/misc/fs_deposterize-pass1.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/misc/fs_deposterize-pass1.sc
@@ -20,7 +20,7 @@ uniform vec4 DIFF_THRESH2;
vec3 df3(vec3 c1, vec3 c2)
{
- return abs(c1 - c2);
+ return abs(c1 - c2);
}
bvec3 le3(vec3 A, vec3 B, vec3 param)
diff --git a/src/osd/modules/render/bgfx/shaders/chains/misc/vs_blit.sc b/src/osd/modules/render/bgfx/shaders/chains/misc/vs_blit.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/misc/vs_blit.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/misc/vs_blit.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/misc/vs_bob-and-ghost-deinterlace.sc b/src/osd/modules/render/bgfx/shaders/chains/misc/vs_bob-and-ghost-deinterlace.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/misc/vs_bob-and-ghost-deinterlace.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/misc/vs_bob-and-ghost-deinterlace.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/misc/vs_deposterize-pass0.sc b/src/osd/modules/render/bgfx/shaders/chains/misc/vs_deposterize-pass0.sc
index f46bf23b063..1ed054f1b9a 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/misc/vs_deposterize-pass0.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/misc/vs_deposterize-pass0.sc
@@ -14,10 +14,14 @@ $output v_texcoord0, v_texcoord1, v_color0
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
vec2 ps = vec2(1.0 / u_tex_size0.xy);
float dx = ps.x;
diff --git a/src/osd/modules/render/bgfx/shaders/chains/misc/vs_deposterize-pass1.sc b/src/osd/modules/render/bgfx/shaders/chains/misc/vs_deposterize-pass1.sc
index 486edf97c5c..69a23cb477c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/misc/vs_deposterize-pass1.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/misc/vs_deposterize-pass1.sc
@@ -14,10 +14,14 @@ $output v_texcoord0, v_texcoord1, v_color0
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
vec2 ps = vec2(1.0 / u_tex_size0.xy);
float dx = ps.x;
diff --git a/src/osd/modules/render/bgfx/shaders/chains/misc/vs_lut.sc b/src/osd/modules/render/bgfx/shaders/chains/misc/vs_lut.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/misc/vs_lut.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/misc/vs_lut.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/misc/vs_resize_blit.sc b/src/osd/modules/render/bgfx/shaders/chains/misc/vs_resize_blit.sc
new file mode 100644
index 00000000000..0a9f2f178e1
--- /dev/null
+++ b/src/osd/modules/render/bgfx/shaders/chains/misc/vs_resize_blit.sc
@@ -0,0 +1,21 @@
+$input a_position, a_texcoord0, a_color0
+$output v_texcoord0, v_color0
+
+// license:BSD-3-Clause
+// copyright-holders:Dario Manesku
+
+#include "common.sh"
+
+uniform vec4 u_inv_view_dims;
+uniform vec4 u_tex_bounds0;
+
+void main()
+{
+ gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
+
+ v_texcoord0 = a_texcoord0 * (u_tex_bounds0.zw - u_tex_bounds0.xy) + u_tex_bounds0.xy;
+ v_color0 = a_color0;
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/misc/vs_saturation.sc b/src/osd/modules/render/bgfx/shaders/chains/misc/vs_saturation.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/misc/vs_saturation.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/misc/vs_saturation.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/pillarbox_left_horizontal/vs_gaussian.sc b/src/osd/modules/render/bgfx/shaders/chains/pillarbox_left_horizontal/vs_gaussian.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/pillarbox_left_horizontal/vs_gaussian.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/pillarbox_left_horizontal/vs_gaussian.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/pillarbox_left_horizontal/vs_offset_sat.sc b/src/osd/modules/render/bgfx/shaders/chains/pillarbox_left_horizontal/vs_offset_sat.sc
index f071beaaa26..77d392ad813 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/pillarbox_left_horizontal/vs_offset_sat.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/pillarbox_left_horizontal/vs_offset_sat.sc
@@ -9,9 +9,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
- gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+ gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0 * vec2(0.16666666 * 0.9, 1.0 * 0.8) + vec2(0.1, 0.1);
v_color0 = a_color0;
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/pillarbox_left_vertical/vs_gaussian.sc b/src/osd/modules/render/bgfx/shaders/chains/pillarbox_left_vertical/vs_gaussian.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/pillarbox_left_vertical/vs_gaussian.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/pillarbox_left_vertical/vs_gaussian.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/pillarbox_left_vertical/vs_offset_sat.sc b/src/osd/modules/render/bgfx/shaders/chains/pillarbox_left_vertical/vs_offset_sat.sc
index a9f6649c1e5..6d47076f992 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/pillarbox_left_vertical/vs_offset_sat.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/pillarbox_left_vertical/vs_offset_sat.sc
@@ -9,9 +9,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
- gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+ gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0 * vec2(1.0 * 0.8, 0.685185 * 0.9) + vec2(0.1, 0.1);
v_color0 = a_color0;
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/pillarbox_right_horizontal/vs_gaussian.sc b/src/osd/modules/render/bgfx/shaders/chains/pillarbox_right_horizontal/vs_gaussian.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/pillarbox_right_horizontal/vs_gaussian.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/pillarbox_right_horizontal/vs_gaussian.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/pillarbox_right_horizontal/vs_offset_sat.sc b/src/osd/modules/render/bgfx/shaders/chains/pillarbox_right_horizontal/vs_offset_sat.sc
index a473bc4123c..403b880b5ec 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/pillarbox_right_horizontal/vs_offset_sat.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/pillarbox_right_horizontal/vs_offset_sat.sc
@@ -9,9 +9,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
- gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+ gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0 * vec2(0.16666666 * 0.9, 1.0 * 0.8) + vec2(0.9 - 0.16666666 * 0.9, 0.1);
v_color0 = a_color0;
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/pillarbox_right_vertical/vs_gaussian.sc b/src/osd/modules/render/bgfx/shaders/chains/pillarbox_right_vertical/vs_gaussian.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/pillarbox_right_vertical/vs_gaussian.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/pillarbox_right_vertical/vs_gaussian.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/pillarbox_right_vertical/vs_offset_sat.sc b/src/osd/modules/render/bgfx/shaders/chains/pillarbox_right_vertical/vs_offset_sat.sc
index 8af6a293d8e..7121ae6651c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/pillarbox_right_vertical/vs_offset_sat.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/pillarbox_right_vertical/vs_offset_sat.sc
@@ -9,9 +9,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
- gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+ gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0 * vec2(1.0 * 0.8, 0.685185 * 0.9) + vec2(0.1, 0.9 - 0.685185 * 0.9);
v_color0 = a_color0;
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/unfiltered/vs_blit.sc b/src/osd/modules/render/bgfx/shaders/chains/unfiltered/vs_blit.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/unfiltered/vs_blit.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/unfiltered/vs_blit.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/warp/vs_dilation-horizontal-fast.sc b/src/osd/modules/render/bgfx/shaders/chains/warp/vs_dilation-horizontal-fast.sc
index 9433c8359be..52e0fc2ae90 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/warp/vs_dilation-horizontal-fast.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/warp/vs_dilation-horizontal-fast.sc
@@ -32,10 +32,14 @@ $output v_texcoord0, v_texcoord1, v_color0
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
vec2 ps = 1.0 / u_tex_size0.xy;
@@ -45,7 +49,7 @@ void main()
// D E F
// H
- v_texcoord1 = vec4(1.0 / u_tex_size0.xy, 0.0, 0.0); // F H
+ v_texcoord1 = vec4(1.0 / u_tex_size0.xy, 0.0, 0.0); // F H
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_custom-jinc2-sharper.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_custom-jinc2-sharper.sc
index fdf14bd393b..fd9a2d72f94 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_custom-jinc2-sharper.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_custom-jinc2-sharper.sc
@@ -18,11 +18,11 @@ uniform vec4 u_tex_size0;
SAMPLER2D(s_p, 0);
- /*
- This is an approximation of Jinc(x)*Jinc(x*r1/r2) for x < 2.5,
- where r1 and r2 are the first two zeros of jinc function.
- For a jinc 2-lobe best approximation, use A=0.5 and B=0.825.
- */
+/*
+ This is an approximation of Jinc(x)*Jinc(x*r1/r2) for x < 2.5,
+ where r1 and r2 are the first two zeros of jinc function.
+ For a jinc 2-lobe best approximation, use A=0.5 and B=0.825.
+*/
// A=0.5, B=0.825 is the best jinc approximation for x<2.5. if B=1.0, it's a lanczos filter.
// Increase A to get more blur. Decrease it to get a sharper picture.
@@ -47,12 +47,12 @@ float d(vec2 pt1, vec2 pt2)
vec4 min4(vec4 a, vec4 b, vec4 c, vec4 d)
{
- return min(a, min(b, min(c, d)));
+ return min(a, min(b, min(c, d)));
}
vec4 max4(vec4 a, vec4 b, vec4 c, vec4 d)
{
- return max(a, max(b, max(c, d)));
+ return max(a, max(b, max(c, d)));
}
vec4 resampler(vec4 x)
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-2xbr-3d-pass0.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-2xbr-3d-pass0.sc
index 9e5520740c2..fdb38420261 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-2xbr-3d-pass0.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-2xbr-3d-pass0.sc
@@ -95,23 +95,23 @@ float hv_wd(float i1, float i2, float i3, float i4, float e1, float e2, float e3
vec4 min4(vec4 a, vec4 b, vec4 c, vec4 d)
{
- return min(a, min(b, min(c, d)));
+ return min(a, min(b, min(c, d)));
}
vec4 max4(vec4 a, vec4 b, vec4 c, vec4 d)
{
- return max(a, max(b, max(c, d)));
+ return max(a, max(b, max(c, d)));
}
void main()
{
//Skip pixels on wrong grid
vec2 fraction = fract(v_texcoord0 * u_tex_size0.xy / XBR_RES);
- if (fraction.x < 0.5 || fraction.y < 0.5)
- {
- gl_FragColor = texture2D(s0, v_texcoord0);
- return;
- }
+ if (fraction.x < 0.5 || fraction.y < 0.5)
+ {
+ gl_FragColor = texture2D(s0, v_texcoord0);
+ return;
+ }
vec2 tex = (floor(v_texcoord0 * u_tex_size0.xy / XBR_RES) + vec2(0.5, 0.5)) * XBR_RES / u_tex_size0.xy;
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_custom-jinc2-sharper.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_custom-jinc2-sharper.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_custom-jinc2-sharper.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_custom-jinc2-sharper.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-2xbr-3d-pass0.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-2xbr-3d-pass0.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-2xbr-3d-pass0.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-2xbr-3d-pass0.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-2xbr-3d-pass1.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-2xbr-3d-pass1.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-2xbr-3d-pass1.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-2xbr-3d-pass1.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-2xbr-3d-pass2.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-2xbr-3d-pass2.sc
index 1c3ee6a8f23..335c9ef8b4c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-2xbr-3d-pass2.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-2xbr-3d-pass2.sc
@@ -33,10 +33,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_color
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
vec2 ps = 1.0 / u_tex_size0.xy;
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass0.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass0.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass0.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass0.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass1.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass1.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass1.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass1.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass1f.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass1f.sc
index c5bd41ee120..338cadbe4b7 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass1f.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass1f.sc
@@ -7,10 +7,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_color
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
vec2 ps = 1.0 / u_tex_size0.xy;
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass2.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass2.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass2.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass2.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass3.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass3.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass3.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass3.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass3f.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass3f.sc
index c5bd41ee120..338cadbe4b7 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass3f.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-4xbr-3d-pass3f.sc
@@ -7,10 +7,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_color
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
vec2 ps = 1.0 / u_tex_size0.xy;
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-fast-pass0.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-fast-pass0.sc
index 5827f1999b8..21e16b595e4 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-fast-pass0.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-fast-pass0.sc
@@ -32,9 +32,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-fast-pass1.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-fast-pass1.sc
index 60637684154..fc33723ec9d 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-fast-pass1.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-fast-pass1.sc
@@ -32,9 +32,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-fast-pass2.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-fast-pass2.sc
index 2cfe541e2b8..a8ec5539c0b 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-fast-pass2.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-fast-pass2.sc
@@ -32,9 +32,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-pass0.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-pass0.sc
index d10c9c24665..8352137204e 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-pass0.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-pass0.sc
@@ -33,10 +33,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_color
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
vec2 ps = 1.0 / u_tex_size0.xy;
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-pass1.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-pass1.sc
index 5827f1999b8..21e16b595e4 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-pass1.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-pass1.sc
@@ -32,9 +32,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-pass2.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-pass2.sc
index 9ae87c8a7ea..8f2d3277665 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-pass2.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-pass2.sc
@@ -33,10 +33,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_color
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
vec2 ps = 1.0 / u_tex_size0.xy;
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-pass3.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-pass3.sc
index 9ae87c8a7ea..8f2d3277665 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-pass3.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-pass3.sc
@@ -33,10 +33,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_color
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
vec2 ps = 1.0 / u_tex_size0.xy;
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv1-noblend.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv1-noblend.sc
index 3e97446a880..de23993d020 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv1-noblend.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv1-noblend.sc
@@ -7,10 +7,14 @@ $output v_texcoord0, v_texcoord1, v_color0
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
vec2 ps = 1.0 / u_tex_size0.xy;
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv2-3d.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv2-3d.sc
index a3bb4330f45..7992b9eee51 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv2-3d.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv2-3d.sc
@@ -9,10 +9,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
uniform vec4 XBR_RES;
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
vec2 ps = XBR_RES.xx / u_tex_size0.xy;
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv2-fast.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv2-fast.sc
index 38e92865308..48e9664b766 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv2-fast.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv2-fast.sc
@@ -7,10 +7,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_color0
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
// A1 B1 C1
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv2-noblend.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv2-noblend.sc
index cfc1a7cfc47..5bcf3e31f5a 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv2-noblend.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv2-noblend.sc
@@ -33,10 +33,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
// A1 B1 C1
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv2.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv2.sc
index ce6e411b75d..22e993426ed 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv2.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv2.sc
@@ -7,10 +7,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
vec2 ps = 1.0 / u_tex_size0.xy;
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv3-noblend.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv3-noblend.sc
index 114f1669ad1..5957004443c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv3-noblend.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv3-noblend.sc
@@ -33,10 +33,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
// A1 B1 C1
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv3.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv3.sc
index 3d72da14478..a5ee8cee547 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv3.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv3.sc
@@ -33,10 +33,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
// A1 B1 C1
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-sharp.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-sharp.sc
index c09b7b66d1c..35cc742cff1 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-sharp.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-sharp.sc
@@ -43,10 +43,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
vec2 ps = 1.0 / u_tex_size0.xy;
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v2-gamma.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v2-gamma.sc
index 2be09e52908..3a9b0e56b1c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v2-gamma.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v2-gamma.sc
@@ -43,10 +43,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
vec2 ps = 1.0 / u_tex_size0.xy;
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v2.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v2.sc
index 2ec42c6585d..c08e3988e24 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v2.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v2.sc
@@ -43,10 +43,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
vec2 ps = 1.0 / u_tex_size0.xy;
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v4-gamma.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v4-gamma.sc
index f40310aa1b9..8c2b0aec4cd 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v4-gamma.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v4-gamma.sc
@@ -43,10 +43,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
vec2 ps = 1.0 / u_tex_size0.xy;
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v4.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v4.sc
index e363aba2eb4..d7328857ffd 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v4.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v4.sc
@@ -43,10 +43,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
vec2 ps = 1.0 / u_tex_size0.xy;
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v4b.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v4b.sc
index 8f9c58be4c1..48ebe4f0a54 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v4b.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v4b.sc
@@ -43,10 +43,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
vec2 ps = 1.0 / u_tex_size0.xy;
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v5-gamma.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v5-gamma.sc
index f40310aa1b9..8c2b0aec4cd 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v5-gamma.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v5-gamma.sc
@@ -43,10 +43,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
vec2 ps = 1.0 / u_tex_size0.xy;
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid.sc
index c09b7b66d1c..35cc742cff1 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid.sc
@@ -43,10 +43,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
vec2 ps = 1.0 / u_tex_size0.xy;
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-a-pass0.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-a-pass0.sc
index 59ffb0a026a..15490257390 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-a-pass0.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-a-pass0.sc
@@ -34,10 +34,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
// A1 B1 C1
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-accuracy-pass0.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-accuracy-pass0.sc
index 5c20062823a..f63eb7b2391 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-accuracy-pass0.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-accuracy-pass0.sc
@@ -33,10 +33,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
// A1 B1 C1
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-accuracy-pass1.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-accuracy-pass1.sc
index fbb10ec9ea5..db8c513319b 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-accuracy-pass1.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-accuracy-pass1.sc
@@ -33,10 +33,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_color0
#include "common.sh"
uniform vec4 u_tex_size1;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
// A1 B1 C1
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-b-pass0.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-b-pass0.sc
index afdcf872331..0c317f16cc7 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-b-pass0.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-b-pass0.sc
@@ -34,10 +34,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
// A1 B1 C1
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-c-pass0.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-c-pass0.sc
index ba0da15a70d..fbcf72fd706 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-c-pass0.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-c-pass0.sc
@@ -34,10 +34,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
// A1 B1 C1
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-d-pass0.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-d-pass0.sc
index bfd5e4a6414..e75cc78ac8c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-d-pass0.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-d-pass0.sc
@@ -34,10 +34,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
// A1 B1 C1
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-noblend-pass1.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-noblend-pass1.sc
index b85cca1828d..56cebbd6540 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-noblend-pass1.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-noblend-pass1.sc
@@ -32,10 +32,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_color0
#include "common.sh"
uniform vec4 u_tex_size1;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
// A1 B1 C1
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-pass1.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-pass1.sc
index 11042eab09a..c35e62e81ac 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-pass1.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-pass1.sc
@@ -34,10 +34,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_color0
#include "common.sh"
uniform vec4 u_tex_size1;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
// A1 B1 C1
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv3-multipass/fs_xbr-lv3-pass0.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv3-multipass/fs_xbr-lv3-pass0.sc
index 4331c2353f6..229f2f93936 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv3-multipass/fs_xbr-lv3-pass0.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv3-multipass/fs_xbr-lv3-pass0.sc
@@ -120,7 +120,7 @@ vec4 weighted_distance(vec4 a, vec4 b, vec4 c, vec4 d, vec4 e, vec4 f, vec4 g, v
LEFT = UP = LEFT3 = UP3 = 0.0; \
PX0 = vec2(0.0, PX); \
LIN0 = vec4(0.0, 0.0, 0.0, 0.0); \
- } \
+ }
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv3-multipass/vs_xbr-lv3-pass0.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv3-multipass/vs_xbr-lv3-pass0.sc
index 80dd11d7ad9..8ae8f8df41c 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv3-multipass/vs_xbr-lv3-pass0.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv3-multipass/vs_xbr-lv3-pass0.sc
@@ -34,10 +34,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
// A1 B1 C1
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv3-multipass/vs_xbr-lv3-pass1.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv3-multipass/vs_xbr-lv3-pass1.sc
index 7932ba25f15..439005d2941 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv3-multipass/vs_xbr-lv3-pass1.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv3-multipass/vs_xbr-lv3-pass1.sc
@@ -32,10 +32,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_color0
uniform vec4 u_tex_size1;
uniform vec4 u_target_dims;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
// A3 B3 C3
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/fs_xbr-mlv4-pass4.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/fs_xbr-mlv4-pass4.sc
index c37c512a7f6..bdd9f5b31db 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/fs_xbr-mlv4-pass4.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/fs_xbr-mlv4-pass4.sc
@@ -110,7 +110,7 @@ vec3 color_mix(vec3 c, vec3 color, vec3 E)
ax.x = round(info); \
iq.x = dot(ax, bin) - 2.0; \
iq.y = dot(ay, bin) - 2.0; \
- PIXEL = texture2D(ORIG_texture, v_texcoord0 + iq.x * v_texcoord1.xy + iq.y * v_texcoord1.zw).xyz; \
+ PIXEL = texture2D(ORIG_texture, v_texcoord0 + iq.x * v_texcoord1.xy + iq.y * v_texcoord1.zw).xyz;
void main()
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/vs_xbr-mlv4-pass1.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/vs_xbr-mlv4-pass1.sc
index 1edfd8632ad..24f3b396cc2 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/vs_xbr-mlv4-pass1.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/vs_xbr-mlv4-pass1.sc
@@ -33,10 +33,14 @@ $output v_texcoord0, v_texcoord1, v_color0
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
// A3 B3 C3
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/vs_xbr-mlv4-pass2.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/vs_xbr-mlv4-pass2.sc
index 92cf6b60b87..1d67bb87ebe 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/vs_xbr-mlv4-pass2.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/vs_xbr-mlv4-pass2.sc
@@ -33,10 +33,14 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
#include "common.sh"
uniform vec4 u_tex_size0;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
// A1 B1 C1
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/vs_xbr-mlv4-pass3.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/vs_xbr-mlv4-pass3.sc
index a6926a41f8b..2c85859340b 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/vs_xbr-mlv4-pass3.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/vs_xbr-mlv4-pass3.sc
@@ -33,10 +33,14 @@ $output v_texcoord0, v_texcoord1, v_color0
#include "common.sh"
uniform vec4 u_tex_size1;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
// A3 B3 C3
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/vs_xbr-mlv4-pass4.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/vs_xbr-mlv4-pass4.sc
index 29fec2f1759..5e62a75a12e 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/vs_xbr-mlv4-pass4.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/vs_xbr-mlv4-pass4.sc
@@ -33,10 +33,14 @@ $output v_texcoord0, v_texcoord1, v_color0
#include "common.sh"
uniform vec4 u_tex_size1;
+uniform vec4 u_inv_view_dims;
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
// A3 B3 C3
diff --git a/src/osd/modules/render/bgfx/shaders/vs_gui.sc b/src/osd/modules/render/bgfx/shaders/vs_gui.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/vs_gui.sc
+++ b/src/osd/modules/render/bgfx/shaders/vs_gui.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/shaders/vs_screen.sc b/src/osd/modules/render/bgfx/shaders/vs_screen.sc
index 405ef8feb3b..df2b37f203c 100644
--- a/src/osd/modules/render/bgfx/shaders/vs_screen.sc
+++ b/src/osd/modules/render/bgfx/shaders/vs_screen.sc
@@ -6,9 +6,14 @@ $output v_texcoord0, v_color0
#include "common.sh"
+uniform vec4 u_inv_view_dims;
+
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
+ gl_Position.xy += u_inv_view_dims.xy * gl_Position.w;
+#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
diff --git a/src/osd/modules/render/bgfx/slider.cpp b/src/osd/modules/render/bgfx/slider.cpp
index 452c934fd37..dcd64c0c865 100644
--- a/src/osd/modules/render/bgfx/slider.cpp
+++ b/src/osd/modules/render/bgfx/slider.cpp
@@ -11,8 +11,10 @@
#include "strformat.h"
-bgfx_slider::bgfx_slider(running_machine &machine, std::string name, float min, float def, float max, float step, slider_type type, screen_type screen, std::string format, std::string description, std::vector<std::string>& strings)
- : m_name(name)
+#include <utility>
+
+bgfx_slider::bgfx_slider(running_machine &machine, std::string &&name, float min, float def, float max, float step, slider_type type, screen_type screen, std::string format, std::string description, std::vector<std::string>& strings)
+ : m_name(std::move(name))
, m_step(step)
, m_type(type)
, m_screen_type(screen)
diff --git a/src/osd/modules/render/bgfx/slider.h b/src/osd/modules/render/bgfx/slider.h
index d7815765c34..89a713da4b3 100644
--- a/src/osd/modules/render/bgfx/slider.h
+++ b/src/osd/modules/render/bgfx/slider.h
@@ -6,14 +6,15 @@
//
//============================================================
-#pragma once
+#ifndef MAME_RENDER_BGFX_SLIDER_H
+#define MAME_RENDER_BGFX_SLIDER_H
-#ifndef __DRAWBGFX_SLIDER__
-#define __DRAWBGFX_SLIDER__
+#pragma once
#include <bgfx/bgfx.h>
#include <cmath>
+#include <cstdint>
#include <memory>
#include <string>
#include <vector>
@@ -46,16 +47,19 @@ public:
SLIDER_SCREEN_TYPE_ANY = SLIDER_SCREEN_TYPE_RASTER | SLIDER_SCREEN_TYPE_VECTOR | SLIDER_SCREEN_TYPE_LCD
};
- bgfx_slider(running_machine& machine, std::string name, float min, float def, float max, float step, slider_type type, screen_type screen, std::string format, std::string description, std::vector<std::string>& strings);
+ bgfx_slider(running_machine& machine, std::string &&name, float min, float def, float max, float step, slider_type type, screen_type screen, std::string format, std::string description, std::vector<std::string>& strings);
virtual ~bgfx_slider();
int32_t update(std::string *str, int32_t newval);
// Getters
- std::string name() const { return m_name; }
+ const std::string &name() const { return m_name; }
slider_type type() const { return m_type; }
float value() const { return m_value; }
float uniform_value() const { return float(m_value); }
+ float min_value() const { return m_min; }
+ float default_value() const { return m_default; }
+ float max_value() const { return m_max; }
slider_state *core_slider() const { return m_slider_state.get(); }
size_t size() const { return get_size_for_type(m_type); }
static size_t get_size_for_type(slider_type type);
@@ -82,4 +86,4 @@ protected:
running_machine&m_machine;
};
-#endif // __DRAWBGFX_SLIDER__
+#endif // MAME_RENDER_BGFX_SLIDER_H
diff --git a/src/osd/modules/render/bgfx/sliderreader.cpp b/src/osd/modules/render/bgfx/sliderreader.cpp
index 208bc241559..96ff2511c96 100644
--- a/src/osd/modules/render/bgfx/sliderreader.cpp
+++ b/src/osd/modules/render/bgfx/sliderreader.cpp
@@ -33,7 +33,7 @@ const slider_reader::string_to_enum slider_reader::SCREEN_NAMES[slider_reader::S
{ "all", uint64_t(bgfx_slider::screen_type::SLIDER_SCREEN_TYPE_ANY) }
};
-std::vector<bgfx_slider*> slider_reader::read_from_value(const Value& value, std::string prefix, chain_manager& chains, uint32_t screen_index)
+std::vector<bgfx_slider*> slider_reader::read_from_value(const Value& value, const std::string &prefix, chain_manager& chains, uint32_t screen_index)
{
std::vector<bgfx_slider*> sliders;
@@ -55,7 +55,7 @@ std::vector<bgfx_slider*> slider_reader::read_from_value(const Value& value, std
const Value& string_array = value["strings"];
for (uint32_t i = 0; i < string_array.Size(); i++)
{
- if (!READER_CHECK(string_array[i].IsString(), (prefix + "Slider '" + name + "': strings[" + std::to_string(i) + "]: must be a string\n").c_str()))
+ if (!READER_CHECK(string_array[i].IsString(), "%sSlider '%s': strings[%u]: must be a string\n", prefix, name, i))
{
return sliders;
}
@@ -82,18 +82,22 @@ std::vector<bgfx_slider*> slider_reader::read_from_value(const Value& value, std
break;
}
- std::string prefixed_desc = "Window " + std::to_string(chains.window_index()) + ", Screen " + std::to_string(screen_index) + ", " + description;
+ std::string prefixed_desc = util::string_format("Window %1$u, Screen %2$u, %3$s", chains.window_index(), screen_index, description);
if (slider_count > 1)
{
+ if (!READER_CHECK(value["min"].IsArray(), "%1$sSlider '%2$s': value 'min' must be an array", prefix, name))
+ return sliders;
+ if (!READER_CHECK(value["default"].IsArray(), "%1$sSlider '%2$s': value 'default' must be an array", prefix, name))
+ return sliders;
+ if (!READER_CHECK(value["max"].IsArray(), "%1$sSlider '%2$s': value 'max' must be an array", prefix, name))
+ return sliders;
+
float min[3];
float defaults[3];
float max[3];
- if (!READER_CHECK(value["min"].IsArray(), (prefix + "Slider '" + name + "': value 'min' must be an array\n").c_str())) return sliders;
- if (!READER_CHECK(value["default"].IsArray(), (prefix + "Slider '" + name + "': value 'default' must be an array\n").c_str())) return sliders;
- if (!READER_CHECK(value["max"].IsArray(), (prefix + "Slider '" + name + "': value 'max' must be an array\n").c_str())) return sliders;
- get_values(value, prefix + "Slider '" + name + "': 'min': ", "min", min, slider_count);
- get_values(value, prefix + "Slider '" + name + "': 'default': ", "default", defaults, slider_count);
- get_values(value, prefix + "Slider '" + name + "': 'max': ", "max", max, slider_count);
+ get_values(value, util::string_format("%1$sSlider '%2$s': 'min': ", prefix, name), "min", min, slider_count);
+ get_values(value, util::string_format("%1$sSlider '%2$s': 'default': ", prefix, name), "default", defaults, slider_count);
+ get_values(value, util::string_format("%1$sSlider '%2$s': 'max': ", prefix, name), "max", max, slider_count);
for (int index = 0; index < slider_count; index++)
{
std::string desc;
@@ -113,51 +117,50 @@ std::vector<bgfx_slider*> slider_reader::read_from_value(const Value& value, std
desc = prefixed_desc + "Invalid";
break;
}
- sliders.push_back(new bgfx_slider(chains.machine(), full_name, min[index], defaults[index], max[index], step, type, screen_type, format, desc, strings));
+ sliders.push_back(new bgfx_slider(chains.machine(), std::move(full_name), min[index], defaults[index], max[index], step, type, screen_type, format, desc, strings));
}
}
else
{
- float min = get_float(value, "min", 0.0f);
- float def = get_float(value, "default", 0.0f);
- float max = get_float(value, "max", 1.0f);
+ const float min = get_float(value, "min", 0.0f);
+ const float def = get_float(value, "default", 0.0f);
+ const float max = get_float(value, "max", 1.0f);
sliders.push_back(new bgfx_slider(chains.machine(), name + "0", min, def, max, step, type, screen_type, format, prefixed_desc, strings));
}
return sliders;
}
-bool slider_reader::get_values(const Value& value, std::string prefix, std::string name, float* values, const int count)
+bool slider_reader::get_values(const Value& value, const std::string &prefix, const std::string &name, float* values, const int count)
{
- const char* name_str = name.c_str();
- const Value& value_array = value[name_str];
+ const Value& value_array = value[name.c_str()];
for (uint32_t i = 0; i < value_array.Size() && i < count; i++)
{
- if (!READER_CHECK(value_array[i].IsNumber(), (prefix + "Entry " + std::to_string(i) + " must be a number\n").c_str())) return false;
+ if (!READER_CHECK(value_array[i].IsNumber(), "%sEntry %u must be a number\n", prefix, i)) return false;
values[i] = value_array[i].GetFloat();
}
return true;
}
-bool slider_reader::validate_parameters(const Value& value, std::string prefix)
+bool slider_reader::validate_parameters(const Value& value, const std::string &prefix)
{
- if (!READER_CHECK(value.HasMember("name"), (prefix + "Must have string value 'name'\n").c_str())) return false;
- if (!READER_CHECK(value["name"].IsString(), (prefix + "Value 'name' must be a string\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("min"), (prefix + "Must have a number or array value 'min'\n").c_str())) return false;
- if (!READER_CHECK(value["min"].IsNumber() || value["min"].IsArray(), (prefix + "Value 'min' must be a number or an array the size of the corresponding slider type\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("default"), (prefix + "Must have a number or array value 'default'\n").c_str())) return false;
- if (!READER_CHECK(value["default"].IsNumber() || value["default"].IsArray(), (prefix + "Value 'default' must be a number or an array the size of the corresponding slider type\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("max"), (prefix + "Must have a number or array value 'max'\n").c_str())) return false;
- if (!READER_CHECK(value["max"].IsNumber() || value["max"].IsArray(), (prefix + "Value 'max' must be a number or an array the size of the corresponding slider type\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("step"), (prefix + "Must have a number value 'step'\n").c_str())) return false;
- if (!READER_CHECK(value["step"].IsNumber(), (prefix + "Value 'step' must be a number (how much does this slider increment by internally?)\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("type"), (prefix + "Must have string value 'type'\n").c_str())) return false;
- if (!READER_CHECK(value["type"].IsString(), (prefix + "Value 'type' must be a string (what type of slider is this? [int_enum, int, float])\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("screen"), (prefix + "Must have string value 'screen'\n").c_str())) return false;
- if (!READER_CHECK(value["screen"].IsString(), (prefix + "Value 'screen' must be a string (what type of output device does this slider apply to? [none, raster, vector, crt, lcd, non_vector, any])\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("format"), (prefix + "Must have string value 'format'\n").c_str())) return false;
- if (!READER_CHECK(value["format"].IsString(), (prefix + "Value 'scale' must be a string (how would we display it in a printf?)").c_str())) return false;
- if (!READER_CHECK(value.HasMember("text"), (prefix + "Must have string value 'text'\n").c_str())) return false;
- if (!READER_CHECK(value["text"].IsString(), (prefix + "Value 'text' must be a string (how would you explain it?)").c_str())) return false;
- if (!READER_CHECK(!value.HasMember("strings") || value["strings"].IsArray(), (prefix + "Value 'strings' must be an array\n").c_str())) return false;
+ if (!READER_CHECK(value.HasMember("name"), "%1$sMust have string value 'name'", prefix)) return false;
+ if (!READER_CHECK(value["name"].IsString(), "%1$sValue 'name' must be a string", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("min"), "%1$sMust have a number or array value 'min'", prefix)) return false;
+ if (!READER_CHECK(value["min"].IsNumber() || value["min"].IsArray(), "%1$sValue 'min' must be a number or an array the size of the corresponding slider type", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("default"), "%1$sMust have a number or array value 'default'", prefix)) return false;
+ if (!READER_CHECK(value["default"].IsNumber() || value["default"].IsArray(), "%1$sValue 'default' must be a number or an array the size of the corresponding slider type", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("max"), "%1$sMust have a number or array value 'max'", prefix)) return false;
+ if (!READER_CHECK(value["max"].IsNumber() || value["max"].IsArray(), "%1$sValue 'max' must be a number or an array the size of the corresponding slider type", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("step"), "%1$sMust have a number value 'step'", prefix)) return false;
+ if (!READER_CHECK(value["step"].IsNumber(), "%1$sValue 'step' must be a number (how much does this slider increment by internally?)", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("type"), "%1$sMust have string value 'type'", prefix)) return false;
+ if (!READER_CHECK(value["type"].IsString(), "%1$sValue 'type' must be a string (what type of slider is this? [int_enum, int, float])", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("screen"), "%1$sMust have string value 'screen'", prefix)) return false;
+ if (!READER_CHECK(value["screen"].IsString(), "%1$sValue 'screen' must be a string (what type of output device does this slider apply to? [none, raster, vector, crt, lcd, non_vector, any])", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("format"), "%1$sMust have string value 'format'", prefix)) return false;
+ if (!READER_CHECK(value["format"].IsString(), "%1$sValue 'scale' must be a string (how would we display it in a printf?)", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("text"), "%1$sMust have string value 'text'", prefix)) return false;
+ if (!READER_CHECK(value["text"].IsString(), "%1$sValue 'text' must be a string (how would you explain it?)", prefix)) return false;
+ if (!READER_CHECK(!value.HasMember("strings") || value["strings"].IsArray(), "%1$sValue 'strings' must be an array", prefix)) return false;
return true;
}
diff --git a/src/osd/modules/render/bgfx/sliderreader.h b/src/osd/modules/render/bgfx/sliderreader.h
index 95c6872e171..dc905472cc8 100644
--- a/src/osd/modules/render/bgfx/sliderreader.h
+++ b/src/osd/modules/render/bgfx/sliderreader.h
@@ -6,26 +6,26 @@
//
//============================================================
+#ifndef MAME_RENDER_BGFX_SLIDERREADER_H
+#define MAME_RENDER_BGFX_SLIDERREADER_H
+
#pragma once
-#ifndef __DRAWBGFX_SLIDER_READER__
-#define __DRAWBGFX_SLIDER_READER__
+#include "statereader.h"
#include <vector>
-#include "statereader.h"
-
class bgfx_slider;
class chain_manager;
class slider_reader : public state_reader
{
public:
- static std::vector<bgfx_slider*> read_from_value(const Value& value, std::string prefix, chain_manager& chains, uint32_t screen_index);
+ static std::vector<bgfx_slider*> read_from_value(const Value& value, const std::string &prefix, chain_manager& chains, uint32_t screen_index);
private:
- static bool get_values(const Value& value, std::string prefix, std::string name, float* values, const int count);
- static bool validate_parameters(const Value& value, std::string prefix);
+ static bool get_values(const Value& value, const std::string &prefix, const std::string &name, float* values, const int count);
+ static bool validate_parameters(const Value& value, const std::string &prefix);
static const int TYPE_COUNT = 5;
static const string_to_enum TYPE_NAMES[TYPE_COUNT];
@@ -33,4 +33,4 @@ private:
static const string_to_enum SCREEN_NAMES[SCREEN_COUNT];
};
-#endif // __DRAWBGFX_SLIDER_READER__
+#endif // MAME_RENDER_BGFX_SLIDERREADER_H
diff --git a/src/osd/modules/render/bgfx/slideruniform.cpp b/src/osd/modules/render/bgfx/slideruniform.cpp
index 7a63b1e6901..bc116f51ff1 100644
--- a/src/osd/modules/render/bgfx/slideruniform.cpp
+++ b/src/osd/modules/render/bgfx/slideruniform.cpp
@@ -13,13 +13,12 @@
#include "slider.h"
-bgfx_slider_uniform::bgfx_slider_uniform(bgfx_uniform* uniform, std::vector<bgfx_slider*> sliders)
+#include <utility>
+
+bgfx_slider_uniform::bgfx_slider_uniform(bgfx_uniform* uniform, std::vector<bgfx_slider*> &&sliders)
: bgfx_entry_uniform(uniform)
+ , m_sliders(std::move(sliders))
{
- for (bgfx_slider* slider : sliders)
- {
- m_sliders.push_back(slider);
- }
}
void bgfx_slider_uniform::bind()
diff --git a/src/osd/modules/render/bgfx/slideruniform.h b/src/osd/modules/render/bgfx/slideruniform.h
index a2fa990dd1f..a08d2fb503d 100644
--- a/src/osd/modules/render/bgfx/slideruniform.h
+++ b/src/osd/modules/render/bgfx/slideruniform.h
@@ -9,10 +9,10 @@
//
//============================================================
-#pragma once
+#ifndef MAME_RENDER_BGFX_SLIDERUNIFORM_H
+#define MAME_RENDER_BGFX_SLIDERUNIFORM_H
-#ifndef __DRAWBGFX_SLIDER_UNIFORM__
-#define __DRAWBGFX_SLIDER_UNIFORM__
+#pragma once
#include "entryuniform.h"
@@ -23,7 +23,7 @@ class bgfx_slider;
class bgfx_slider_uniform : public bgfx_entry_uniform
{
public:
- bgfx_slider_uniform(bgfx_uniform* uniform, std::vector<bgfx_slider*> sliders);
+ bgfx_slider_uniform(bgfx_uniform* uniform, std::vector<bgfx_slider*> &&sliders);
virtual void bind() override;
@@ -31,4 +31,4 @@ private:
std::vector<bgfx_slider*> m_sliders;
};
-#endif // __DRAWBGFX_SLIDER_UNIFORM__
+#endif // MAME_RENDER_BGFX_SLIDERUNIFORM_H
diff --git a/src/osd/modules/render/bgfx/slideruniformreader.cpp b/src/osd/modules/render/bgfx/slideruniformreader.cpp
index 314cff0b78b..3fdeb0b21e6 100644
--- a/src/osd/modules/render/bgfx/slideruniformreader.cpp
+++ b/src/osd/modules/render/bgfx/slideruniformreader.cpp
@@ -8,13 +8,13 @@
#include "slideruniformreader.h"
-#include <vector>
-
-#include "slideruniform.h"
#include "entryuniform.h"
#include "slider.h"
+#include "slideruniform.h"
+
+#include <vector>
-bgfx_entry_uniform* slider_uniform_reader::read_from_value(const Value& value, std::string prefix, bgfx_uniform* uniform, std::map<std::string, bgfx_slider*>& sliders)
+bgfx_entry_uniform* slider_uniform_reader::read_from_value(const Value& value, const std::string &prefix, bgfx_uniform* uniform, std::map<std::string, bgfx_slider*>& sliders)
{
if (!validate_parameters(value, prefix))
{
@@ -35,12 +35,12 @@ bgfx_entry_uniform* slider_uniform_reader::read_from_value(const Value& value, s
slider_list.push_back(sliders[name + "2"]);
}
- return new bgfx_slider_uniform(uniform, slider_list);
+ return new bgfx_slider_uniform(uniform, std::move(slider_list));
}
-bool slider_uniform_reader::validate_parameters(const Value& value, std::string prefix)
+bool slider_uniform_reader::validate_parameters(const Value& value, const std::string &prefix)
{
- if (!READER_CHECK(value.HasMember("slider"), (prefix + "Must have string value 'slider' (what slider are we getting the value of?)\n").c_str())) return false;
- if (!READER_CHECK(value["slider"].IsString(), (prefix + "Value 'slider' must be a string\n").c_str())) return false;
+ if (!READER_CHECK(value.HasMember("slider"), "%sMust have string value 'slider' (what slider are we getting the value of?)\n", prefix)) return false;
+ if (!READER_CHECK(value["slider"].IsString(), "%sValue 'slider' must be a string\n", prefix)) return false;
return true;
}
diff --git a/src/osd/modules/render/bgfx/slideruniformreader.h b/src/osd/modules/render/bgfx/slideruniformreader.h
index 0db387270b0..f39e7fc2fd8 100644
--- a/src/osd/modules/render/bgfx/slideruniformreader.h
+++ b/src/osd/modules/render/bgfx/slideruniformreader.h
@@ -6,27 +6,27 @@
//
//================================================================
+#ifndef MAME_RENDER_BGFX_SLIDERUNIFORMREADER_H
+#define MAME_RENDER_BGFX_SLIDERUNIFORMREADER_H
+
#pragma once
-#ifndef __DRAWBGFX_SLIDER_UNIFORM_READER__
-#define __DRAWBGFX_SLIDER_UNIFORM_READER__
+#include "entryuniform.h"
+#include "statereader.h"
#include <string>
#include <map>
-#include "entryuniform.h"
-#include "statereader.h"
-
class bgfx_uniform;
class bgfx_slider;
class slider_uniform_reader : public state_reader
{
public:
- static bgfx_entry_uniform* read_from_value(const Value& value, std::string prefix, bgfx_uniform* uniform, std::map<std::string, bgfx_slider*>& sliders);
+ static bgfx_entry_uniform* read_from_value(const Value& value, const std::string &prefix, bgfx_uniform* uniform, std::map<std::string, bgfx_slider*>& sliders);
private:
- static bool validate_parameters(const Value& value, std::string prefix);
+ static bool validate_parameters(const Value& value, const std::string &prefix);
};
-#endif // __DRAWBGFX_SLIDER_UNIFORM_READER__
+#endif // MAME_RENDER_BGFX_SLIDERUNIFORMREADER_H
diff --git a/src/osd/modules/render/bgfx/statereader.cpp b/src/osd/modules/render/bgfx/statereader.cpp
index acaeddd35b5..277e6815185 100644
--- a/src/osd/modules/render/bgfx/statereader.cpp
+++ b/src/osd/modules/render/bgfx/statereader.cpp
@@ -13,17 +13,20 @@
#include <cmath>
-bool state_reader::READER_CHECK(bool condition, const char* format, ...)
+
+bool state_reader::V_READER_CHECK(bool condition, const util::format_argument_pack<char> &args)
{
if (!condition)
- {
- va_list ap;
- va_start(ap, format);
- char buf[2048];
- vsnprintf(buf, 2048, format, ap);
- osd_printf_error("Error: %s\n", buf);
- va_end(ap);
- }
+ osd_printf_error("Error: %s\n", util::string_format(args));
+
+ return condition;
+}
+
+bool state_reader::V_READER_WARN(bool condition, const util::format_argument_pack<char> &args)
+{
+ if (!condition)
+ osd_printf_warning("Warning: %s\n", util::string_format(args));
+
return condition;
}
@@ -117,7 +120,7 @@ float state_reader::get_float(const Value& value, const std::string name, const
{
if (value.HasMember(name.c_str()))
{
- return (float)value[name.c_str()].GetDouble();
+ return float(value[name.c_str()].GetDouble());
}
return default_value;
}
@@ -128,7 +131,7 @@ void state_reader::get_float(const Value& value, const std::string name, float*
{
if (count == 1)
{
- *out = (float) value[name.c_str()].GetDouble();
+ *out = float(value[name.c_str()].GetDouble());
return;
}
else
@@ -146,7 +149,7 @@ void state_reader::get_vec_values(const Value& value_array, float* data, const u
{
for (unsigned int i = 0; i < count && i < value_array.Size(); i++)
{
- data[i] = (float) value_array[i].GetDouble();
+ data[i] = float(value_array[i].GetDouble());
}
}
diff --git a/src/osd/modules/render/bgfx/statereader.h b/src/osd/modules/render/bgfx/statereader.h
index 43596bf4e94..69a795d9f04 100644
--- a/src/osd/modules/render/bgfx/statereader.h
+++ b/src/osd/modules/render/bgfx/statereader.h
@@ -7,16 +7,19 @@
//
//================================================================
+#ifndef MAME_RENDER_BGFX_STATEREADER_H
+#define MAME_RENDER_BGFX_STATEREADER_H
+
#pragma once
-#ifndef DRAWBGFX_STATE_READER
-#define DRAWBGFX_STATE_READER
+#include "util/strformat.h"
#include <rapidjson/document.h>
#include <cstdint>
#include <string>
+
using namespace rapidjson;
class state_reader
@@ -44,10 +47,22 @@ protected:
static uint64_t get_param_from_string(std::string value, const string_to_enum* enums, const int count);
protected:
- static bool READER_CHECK(bool condition, const char* format, ...);
+ template <typename Format, typename... Params>
+ static bool READER_CHECK(bool condition, Format &&fmt, Params &&... args)
+ {
+ return V_READER_CHECK(condition, util::make_format_argument_pack(std::forward<Format>(fmt), std::forward<Params>(args)...));
+ }
+
+ template <typename Format, typename... Params>
+ static bool READER_WARN(bool condition, Format &&fmt, Params &&... args)
+ {
+ return V_READER_WARN(condition, util::make_format_argument_pack(std::forward<Format>(fmt), std::forward<Params>(args)...));
+ }
private:
+ static bool V_READER_CHECK(bool condition, const util::format_argument_pack<char> &args);
+ static bool V_READER_WARN(bool condition, const util::format_argument_pack<char> &args);
static void get_vec_values(const Value& value_array, float* data, const unsigned int count);
};
-#endif // DRAWBGFX_STATE_READER
+#endif // MAME_RENDER_BGFX_STATEREADER_H
diff --git a/src/osd/modules/render/bgfx/suppressor.cpp b/src/osd/modules/render/bgfx/suppressor.cpp
index 83dd403adf7..8ffb4be6d66 100644
--- a/src/osd/modules/render/bgfx/suppressor.cpp
+++ b/src/osd/modules/render/bgfx/suppressor.cpp
@@ -13,13 +13,13 @@
#include <cstring>
-bgfx_suppressor::bgfx_suppressor(std::vector<bgfx_slider*> sliders, uint32_t condition, combine_mode combine, void* value)
- : m_sliders(sliders)
+bgfx_suppressor::bgfx_suppressor(std::vector<bgfx_slider*> &&sliders, uint32_t condition, combine_mode combine, void* value)
+ : m_sliders(std::move(sliders))
, m_condition(condition)
, m_combine(combine)
, m_value(nullptr)
{
- uint32_t size = sliders[0]->size();
+ uint32_t size = m_sliders[0]->size();
m_value = new uint8_t[size];
memcpy(m_value, value, size);
}
diff --git a/src/osd/modules/render/bgfx/suppressor.h b/src/osd/modules/render/bgfx/suppressor.h
index 343a621b72d..00276fbb398 100644
--- a/src/osd/modules/render/bgfx/suppressor.h
+++ b/src/osd/modules/render/bgfx/suppressor.h
@@ -7,10 +7,10 @@
//
//============================================================
-#pragma once
+#ifndef MAME_RENDER_BGFX_SUPPRESSOR_H
+#define MAME_RENDER_BGFX_SUPPRESSOR_H
-#ifndef __DRAWBGFX_SUPPRESSOR__
-#define __DRAWBGFX_SUPPRESSOR__
+#pragma once
#include <bgfx/bgfx.h>
@@ -34,7 +34,7 @@ public:
COMBINE_OR
};
- bgfx_suppressor(std::vector<bgfx_slider*> sliders, uint32_t condition, combine_mode combine, void* value);
+ bgfx_suppressor(std::vector<bgfx_slider*> &&sliders, uint32_t condition, combine_mode combine, void* value);
~bgfx_suppressor();
// Getters
@@ -48,4 +48,4 @@ private:
uint8_t* m_value;
};
-#endif // __DRAWBGFX_SUPPRESSOR__
+#endif // MAME_RENDER_BGFX_SUPPRESSOR_H
diff --git a/src/osd/modules/render/bgfx/suppressorreader.cpp b/src/osd/modules/render/bgfx/suppressorreader.cpp
index d7eb2b21fb8..353b79ad9bf 100644
--- a/src/osd/modules/render/bgfx/suppressorreader.cpp
+++ b/src/osd/modules/render/bgfx/suppressorreader.cpp
@@ -21,7 +21,7 @@ const suppressor_reader::string_to_enum suppressor_reader::COMBINE_NAMES[suppres
{ "or", bgfx_suppressor::combine_mode::COMBINE_OR }
};
-bgfx_suppressor* suppressor_reader::read_from_value(const Value& value, std::string prefix, std::map<std::string, bgfx_slider*>& sliders)
+bgfx_suppressor* suppressor_reader::read_from_value(const Value& value, const std::string &prefix, std::map<std::string, bgfx_slider*>& sliders)
{
if (!validate_parameters(value, prefix))
{
@@ -58,7 +58,7 @@ bgfx_suppressor* suppressor_reader::read_from_value(const Value& value, std::str
if (slider_count > 1)
{
get_values(value, prefix, "value", values, slider_count);
- if (!READER_CHECK(slider_count == value["value"].GetArray().Size(), (prefix + "Expected " + std::to_string(slider_count) + " values, got " + std::to_string(value["value"].GetArray().Size()) + "\n").c_str())) return nullptr;
+ if (!READER_CHECK(slider_count == value["value"].GetArray().Size(), "%sExpected %d values, got %u\n", prefix, slider_count, value["value"].GetArray().Size())) return nullptr;
for (int index = 1; index < slider_count; index++)
{
check_sliders.push_back(sliders[name + std::to_string(index)]);
@@ -69,26 +69,25 @@ bgfx_suppressor* suppressor_reader::read_from_value(const Value& value, std::str
values[0] = get_int(value, "value", 0);
}
- return new bgfx_suppressor(check_sliders, condition, mode, values);
+ return new bgfx_suppressor(std::move(check_sliders), condition, mode, values);
}
-bool suppressor_reader::validate_parameters(const Value& value, std::string prefix)
+bool suppressor_reader::validate_parameters(const Value& value, const std::string &prefix)
{
- if (!READER_CHECK(value["type"].IsString(), (prefix + "Value 'type' must be a string\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("name"), (prefix + "Must have string value 'name'\n").c_str())) return false;
- if (!READER_CHECK(value["name"].IsString(), (prefix + "Value 'name' must be a string\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("value"), (prefix + "Must have numeric or array value 'value'\n").c_str())) return false;
- if (!READER_CHECK(value["value"].IsNumber() || value["value"].IsArray(), (prefix + "Value 'value' must be a number or array the size of the corresponding slider type\n").c_str())) return false;
+ if (!READER_CHECK(value["type"].IsString(), "%sValue 'type' must be a string\n", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("name"), "%sMust have string value 'name'\n", prefix)) return false;
+ if (!READER_CHECK(value["name"].IsString(), "%sValue 'name' must be a string\n", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("value"), "%sMust have numeric or array value 'value'\n", prefix)) return false;
+ if (!READER_CHECK(value["value"].IsNumber() || value["value"].IsArray(), "%sValue 'value' must be a number or array the size of the corresponding slider type\n", prefix)) return false;
return true;
}
bool suppressor_reader::get_values(const Value& value, std::string prefix, std::string name, int* values, const int count)
{
- const char* name_str = name.c_str();
- const Value& value_array = value[name_str];
+ const Value& value_array = value[name.c_str()];
for (uint32_t i = 0; i < value_array.Size() && i < count; i++)
{
- if (!READER_CHECK(value_array[i].IsInt(), (prefix + "value[" + std::to_string(i) + "] must be an integer\n").c_str())) return false;
+ if (!READER_CHECK(value_array[i].IsInt(), "%svalue[%u] must be an integer\n", prefix, i)) return false;
values[i] = value_array[i].GetInt();
}
return true;
diff --git a/src/osd/modules/render/bgfx/suppressorreader.h b/src/osd/modules/render/bgfx/suppressorreader.h
index cf7d641997c..23855134c51 100644
--- a/src/osd/modules/render/bgfx/suppressorreader.h
+++ b/src/osd/modules/render/bgfx/suppressorreader.h
@@ -6,10 +6,10 @@
//
//============================================================
-#pragma once
+#ifndef MAME_RENDER_BGFX_SUPPRESSORREADER_H
+#define MAME_RENDER_BGFX_SUPPRESSORREADER_H
-#ifndef __DRAWBGFX_SUPPRESSOR_READER__
-#define __DRAWBGFX_SUPPRESSOR_READER__
+#pragma once
#include "statereader.h"
@@ -22,11 +22,11 @@ class bgfx_slider;
class suppressor_reader : public state_reader
{
public:
- static bgfx_suppressor* read_from_value(const Value& value, std::string prefix, std::map<std::string, bgfx_slider*>& sliders);
+ static bgfx_suppressor* read_from_value(const Value& value, const std::string &prefix, std::map<std::string, bgfx_slider*>& sliders);
private:
static bool get_values(const Value& value, std::string prefix, std::string name, int* values, const int count);
- static bool validate_parameters(const Value& value, std::string prefix);
+ static bool validate_parameters(const Value& value, const std::string &prefix);
static const int CONDITION_COUNT = 2;
static const string_to_enum CONDITION_NAMES[CONDITION_COUNT];
@@ -34,4 +34,4 @@ private:
static const string_to_enum COMBINE_NAMES[COMBINE_COUNT];
};
-#endif // __DRAWBGFX_SUPPRESSOR_READER__
+#endif // MAME_RENDER_BGFX_SUPPRESSORREADER_H
diff --git a/src/osd/modules/render/bgfx/target.cpp b/src/osd/modules/render/bgfx/target.cpp
index f900f4f99fb..dd9169cb6cd 100644
--- a/src/osd/modules/render/bgfx/target.cpp
+++ b/src/osd/modules/render/bgfx/target.cpp
@@ -10,13 +10,16 @@
#include "target.h"
-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, uint16_t scale, uint32_t screen)
+bgfx_target::bgfx_target(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t height, uint16_t xprescale, uint16_t yprescale,
+ uint32_t style, bool double_buffer, bool filter, uint16_t scale, uint32_t screen)
: m_name(name)
, m_format(format)
, m_targets(nullptr)
, m_textures(nullptr)
, m_width(width)
, m_height(height)
+ , m_xprescale(xprescale)
+ , m_yprescale(yprescale)
, m_double_buffer(double_buffer)
, m_style(style)
, m_filter(filter)
@@ -39,10 +42,10 @@ 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(m_width, m_height, false, 1, format, wrap_mode | filter_mode | BGFX_TEXTURE_RT);
+ m_textures[page] = bgfx::createTexture2D(m_width * xprescale, m_height * yprescale, false, 1, format, wrap_mode | filter_mode | BGFX_TEXTURE_RT);
assert(m_textures[page].idx != 0xffff);
- m_textures[m_page_count + page] = bgfx::createTexture2D(m_width, m_height, false, 1, bgfx::TextureFormat::D32F, depth_flags | BGFX_TEXTURE_RT);
+ m_textures[m_page_count + page] = bgfx::createTexture2D(m_width * xprescale, m_height * yprescale, false, 1, bgfx::TextureFormat::D32F, depth_flags | BGFX_TEXTURE_RT);
assert(m_textures[m_page_count + page].idx != 0xffff);
bgfx::TextureHandle handles[2] = { m_textures[page], m_textures[m_page_count + page] };
@@ -62,6 +65,8 @@ bgfx_target::bgfx_target(void *handle, uint16_t width, uint16_t height)
, m_textures(nullptr)
, m_width(width)
, m_height(height)
+ , m_xprescale(1)
+ , m_yprescale(1)
, m_double_buffer(false)
, m_style(TARGET_STYLE_CUSTOM)
, m_filter(false)
diff --git a/src/osd/modules/render/bgfx/target.h b/src/osd/modules/render/bgfx/target.h
index c00fc669337..5b979373971 100644
--- a/src/osd/modules/render/bgfx/target.h
+++ b/src/osd/modules/render/bgfx/target.h
@@ -27,7 +27,8 @@ 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 style, bool double_buffer, bool filter, uint16_t scale, uint32_t screen);
+ bgfx_target(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t height, uint16_t xprescale, uint16_t yprescale,
+ uint32_t style, bool double_buffer, bool filter, uint16_t scale, uint32_t screen);
bgfx_target(void *handle, uint16_t width, uint16_t height);
virtual ~bgfx_target();
@@ -42,13 +43,16 @@ public:
bool filter() const { return m_filter; }
uint16_t scale() const { return m_scale; }
uint32_t screen_index() const { return m_screen; }
+ uint16_t raw_width() const { return m_width; }
+ uint16_t raw_height() const { return m_height; }
// bgfx_texture_handle_provider
virtual bgfx::TextureHandle texture() const override;
virtual bool is_target() const override { return true; }
- virtual uint16_t width() const override { return m_width; }
- virtual uint16_t height() const override { return m_height; }
- virtual uint16_t rowpixels() const override { return m_width; }
+ virtual uint16_t width() const override { return m_width * m_xprescale; }
+ virtual uint16_t width_margin() const override { return 0; }
+ virtual uint16_t height() const override { return m_height * m_yprescale; }
+ virtual uint16_t rowpixels() const override { return m_width * m_xprescale; }
virtual int width_div_factor() const override { return 1; }
virtual int width_mul_factor() const override { return 1; }
@@ -62,6 +66,8 @@ private:
uint16_t m_width;
uint16_t m_height;
+ uint16_t m_xprescale;
+ uint16_t m_yprescale;
bool m_double_buffer;
uint32_t m_style;
diff --git a/src/osd/modules/render/bgfx/targetmanager.cpp b/src/osd/modules/render/bgfx/targetmanager.cpp
index dfd5b2adbd1..eae09c48008 100644
--- a/src/osd/modules/render/bgfx/targetmanager.cpp
+++ b/src/osd/modules/render/bgfx/targetmanager.cpp
@@ -9,15 +9,15 @@
//
//============================================================
-#include <bgfx/bgfx.h>
+#include "targetmanager.h"
-#include <vector>
+#include "bgfxutil.h"
+#include "target.h"
#include "modules/lib/osdobj_common.h"
-#include "targetmanager.h"
+#include <utility>
-#include "target.h"
const int32_t target_manager::MAX_SCREENS = 100;
@@ -29,100 +29,106 @@ target_manager::target_manager(texture_manager& textures)
target_manager::~target_manager()
{
- std::vector<bgfx_target*> to_delete;
- for (std::pair<std::string, bgfx_target*> target : m_targets)
- {
- if (target.second != nullptr)
- {
- to_delete.push_back(target.second);
- }
- }
- m_targets.clear();
-
- for (uint32_t i = 0; i < to_delete.size(); i++)
- {
- delete to_delete[i];
- }
+ for (auto iter = m_targets.begin(); iter != m_targets.end(); iter = m_targets.erase(iter))
+ m_textures.remove_provider(iter->first);
}
-bgfx_target* target_manager::create_target(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t height, uint32_t style, bool double_buffer, bool filter, uint16_t scale, uint32_t screen)
+bgfx_target* target_manager::create_target(
+ std::string &&name,
+ bgfx::TextureFormat::Enum format,
+ uint16_t width,
+ uint16_t height,
+ uint16_t xprescale,
+ uint16_t yprescale,
+ uint32_t style,
+ bool double_buffer,
+ bool filter,
+ uint16_t scale,
+ uint32_t screen)
{
- std::string full_name = name + std::to_string(screen);
+ const std::string full_name = name + std::to_string(screen);
auto iter = m_targets.find(full_name);
if (iter != m_targets.end())
- destroy_target(name, screen);
+ {
+ iter->second.reset();
+ m_textures.remove_provider(full_name);
+ }
- bgfx_target *target = new bgfx_target(name, format, width, height, style, double_buffer, filter, scale, screen);
- m_targets[full_name] = target;
- m_textures.add_provider(full_name, target);
+ auto target = std::make_unique<bgfx_target>(std::move(name), format, width, height, xprescale, yprescale, style, double_buffer, filter, scale, screen);
+ if (iter != m_targets.end())
+ iter->second = std::move(target);
+ else
+ iter = m_targets.emplace(full_name, std::move(target)).first;
+ m_textures.add_provider(full_name, *iter->second);
- return target;
+ return iter->second.get();
}
-void target_manager::destroy_target(std::string name, uint32_t screen)
+void target_manager::destroy_target(const std::string &name, uint32_t screen)
{
- std::string full_name = (screen < 0) ? name : (name + std::to_string(screen));
- if (m_targets.find(full_name) != m_targets.end())
+ const std::string full_name = (screen < 0) ? name : (name + std::to_string(screen));
+ const auto found = m_targets.find(full_name);
+ if (found != m_targets.end())
{
- delete m_targets[full_name];
- m_targets.erase(full_name);
+ m_targets.erase(found);
m_textures.remove_provider(full_name);
}
}
bgfx_target* target_manager::create_backbuffer(void *handle, uint16_t width, uint16_t height)
{
- auto* target = new bgfx_target(handle, width, height);
- m_targets["backbuffer"] = target;
- return target;
+ auto target = std::make_unique<bgfx_target>(handle, width, height);
+ return (m_targets["backbuffer"] = std::move(target)).get();
}
-bgfx_target* target_manager::target(uint32_t screen, std::string name)
+bgfx_target* target_manager::target(uint32_t screen, const std::string &name)
{
- std::string full_name = name + std::to_string(screen);
- if (m_targets.find(full_name) == m_targets.end())
+ const std::string full_name = name + std::to_string(screen);
+ const auto found = m_targets.find(full_name);
+ if (found != m_targets.end())
+ {
+ return found->second.get();
+ }
+ else
{
osd_printf_verbose("Warning: Attempting to retrieve a nonexistent target '%s' for screen %d\n", name, screen);
+ return nullptr;
}
- return m_targets[full_name];
}
-bool target_manager::update_target_sizes(uint32_t screen, uint16_t width, uint16_t height, uint32_t style)
+bool target_manager::update_target_sizes(uint32_t screen, uint16_t width, uint16_t height, uint32_t style, uint16_t user_prescale, uint16_t max_prescale_size)
{
- if (style == TARGET_STYLE_CUSTOM) return false;
+ if (style == TARGET_STYLE_CUSTOM)
+ return false;
- std::vector<osd_dim>& sizes = style == TARGET_STYLE_GUEST ? m_guest_dims : m_native_dims;
+ 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.emplace_back(osd_dim(0, 0));
+ sizes.emplace_back(0, 0);
}
if (width != sizes[screen].width() || height != sizes[screen].height())
{
sizes[screen] = osd_dim(width, height);
- rebuild_targets(screen, style);
+ rebuild_targets(screen, style, user_prescale, max_prescale_size);
return true;
}
return false;
}
-void target_manager::rebuild_targets(uint32_t screen, uint32_t style)
+void target_manager::rebuild_targets(uint32_t screen, uint32_t style, uint16_t user_prescale, uint16_t max_prescale_size)
{
if (style == TARGET_STYLE_CUSTOM) return;
std::vector<bgfx_target*> to_resize;
- for (std::pair<std::string, bgfx_target*> target_pair : m_targets)
+ for (const auto &[name, target] : m_targets)
{
- bgfx_target* target = target_pair.second;
- if (target == nullptr || target->style() != style || target->screen_index() != screen)
- {
- continue;
- }
- to_resize.push_back(target);
+ if (target && (target->style() == style) && (target->screen_index() == screen))
+ to_resize.push_back(target.get());
}
std::vector<osd_dim>& sizes = style == TARGET_STYLE_GUEST ? m_guest_dims : m_native_dims;
@@ -135,13 +141,15 @@ void target_manager::rebuild_targets(uint32_t screen, uint32_t style)
const uint16_t scale = target->scale();
const uint16_t width(sizes[screen].width());
const uint16_t height(sizes[screen].height());
+ uint16_t xprescale = user_prescale;
+ uint16_t yprescale = user_prescale;
+ bgfx_util::find_prescale_factor(width, height, max_prescale_size, xprescale, yprescale);
- destroy_target(name, screen);
- create_target(name, format, width, height, style, double_buffered, filter, scale, screen);
+ create_target(std::move(name), format, width, height, xprescale, yprescale, style, double_buffered, filter, scale, screen);
}
}
-void target_manager::update_screen_count(uint32_t count)
+void target_manager::update_screen_count(uint32_t count, uint16_t user_prescale, uint16_t max_prescale_size)
{
// Ensure that there's an entry to fill
while (count > m_native_dims.size())
@@ -157,26 +165,26 @@ void target_manager::update_screen_count(uint32_t count)
{
for (uint32_t screen = old_count; screen < m_screen_count; screen++)
{
- create_target_if_nonexistent(screen, "output", false, false, TARGET_STYLE_NATIVE);
+ create_output_if_nonexistent(screen, user_prescale, max_prescale_size);
}
}
}
}
-void target_manager::create_target_if_nonexistent(uint32_t screen, std::string name, bool double_buffered, bool filter, uint32_t style)
+void target_manager::create_output_if_nonexistent(uint32_t screen, uint16_t user_prescale, uint16_t max_prescale_size)
{
- if (style == TARGET_STYLE_CUSTOM) return;
-
- if (m_targets.find(name + std::to_string(screen)) != m_targets.end())
+ if (m_targets.find("output" + std::to_string(screen)) != m_targets.end())
{
return;
}
- 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());
+ uint16_t width(m_native_dims[screen].width());
+ uint16_t height(m_native_dims[screen].height());
+ uint16_t xprescale = user_prescale;
+ uint16_t yprescale = user_prescale;
+ bgfx_util::find_prescale_factor(width, height, max_prescale_size, xprescale, yprescale);
- create_target(name, bgfx::TextureFormat::BGRA8, width, height, style, double_buffered, filter, 1, screen);
+ create_target("output", bgfx::TextureFormat::BGRA8, width, height, xprescale, yprescale, TARGET_STYLE_NATIVE, false, false, 1, screen);
}
uint16_t target_manager::width(uint32_t style, uint32_t screen)
diff --git a/src/osd/modules/render/bgfx/targetmanager.h b/src/osd/modules/render/bgfx/targetmanager.h
index fa44e2c1bd6..38bba4c5db5 100644
--- a/src/osd/modules/render/bgfx/targetmanager.h
+++ b/src/osd/modules/render/bgfx/targetmanager.h
@@ -9,44 +9,49 @@
//
//============================================================
+#ifndef MAME_RENDER_BGFX_TARGETMANAGER_H
+#define MAME_RENDER_BGFX_TARGETMANAGER_H
+
#pragma once
-#ifndef __DRAWBGFX_TARGET_MANAGER__
-#define __DRAWBGFX_TARGET_MANAGER__
+#include "texturemanager.h"
-#include <map>
-#include <string>
+#include "modules/osdhelper.h"
#include <bgfx/bgfx.h>
-#include "modules/osdhelper.h"
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
-#include "texturemanager.h"
class bgfx_target;
-class target_manager {
+class target_manager
+{
public:
target_manager(texture_manager& textures);
~target_manager();
- bgfx_target* create_target(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t height, uint32_t style, bool double_buffer, bool filter, uint16_t scale, uint32_t screen);
- void destroy_target(std::string name, uint32_t screen = -1);
+ bgfx_target* create_target(std::string &&name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t height, uint16_t xprescale, uint16_t yprescale,
+ uint32_t style, bool double_buffer, bool filter, uint16_t scale, uint32_t screen);
+ void destroy_target(const std::string &name, uint32_t screen = -1);
bgfx_target* create_backbuffer(void *handle, uint16_t width, uint16_t height);
- bool update_target_sizes(uint32_t screen, uint16_t width, uint16_t height, uint32_t style);
- void update_screen_count(uint32_t count);
+ bool update_target_sizes(uint32_t screen, uint16_t width, uint16_t height, uint32_t style, uint16_t user_prescale, uint16_t max_prescale_size);
+ void update_screen_count(uint32_t count, uint16_t user_prescale, uint16_t max_prescale_size);
// Getters
- bgfx_target* target(uint32_t screen, std::string name);
+ bgfx_target* target(uint32_t screen, const std::string &name);
uint16_t width(uint32_t style, uint32_t screen);
uint16_t height(uint32_t style, uint32_t screen);
private:
- 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, uint32_t style);
+ void rebuild_targets(uint32_t screen, uint32_t style, uint16_t user_prescale, uint16_t max_prescale_size);
+ void create_output_if_nonexistent(uint32_t screen, uint16_t user_prescale, uint16_t max_prescale_size);
- std::map<std::string, bgfx_target*> m_targets;
+ std::map<std::string, std::unique_ptr<bgfx_target> > m_targets;
texture_manager& m_textures;
std::vector<osd_dim> m_guest_dims;
@@ -56,4 +61,4 @@ private:
static const int32_t MAX_SCREENS;
};
-#endif // __DRAWBGFX_TARGET_MANAGER__
+#endif // MAME_RENDER_BGFX_TARGETMANAGER_H
diff --git a/src/osd/modules/render/bgfx/targetreader.cpp b/src/osd/modules/render/bgfx/targetreader.cpp
index e66a147d7ba..12386428822 100644
--- a/src/osd/modules/render/bgfx/targetreader.cpp
+++ b/src/osd/modules/render/bgfx/targetreader.cpp
@@ -8,11 +8,12 @@
#include "targetreader.h"
-#include <modules/lib/osdobj_common.h>
-
+#include "bgfxutil.h"
#include "chainmanager.h"
#include "target.h"
+#include "modules/lib/osdobj_common.h"
+
#include <cmath>
const target_reader::string_to_enum target_reader::STYLE_NAMES[target_reader::STYLE_COUNT] = {
@@ -21,7 +22,13 @@ const target_reader::string_to_enum target_reader::STYLE_NAMES[target_reader::ST
{ "custom", TARGET_STYLE_CUSTOM }
};
-bgfx_target* target_reader::read_from_value(const Value& value, std::string prefix, chain_manager& chains, uint32_t screen_index)
+bgfx_target* target_reader::read_from_value(
+ const Value& value,
+ const std::string &prefix,
+ chain_manager& chains,
+ uint32_t screen_index,
+ uint16_t user_prescale,
+ uint16_t max_prescale_size)
{
if (!validate_parameters(value, prefix))
{
@@ -37,40 +44,61 @@ bgfx_target* target_reader::read_from_value(const Value& value, std::string pref
{
scale = int(floor(value["scale"].GetDouble() + 0.5));
}
+ bool use_user_prescale = get_bool(value, "user_prescale", false);
uint16_t width = 0;
uint16_t height = 0;
+ uint16_t xprescale = 1;
+ uint16_t yprescale = 1;
switch (mode)
{
case TARGET_STYLE_GUEST:
+ {
width = chains.targets().width(TARGET_STYLE_GUEST, screen_index);
height = chains.targets().height(TARGET_STYLE_GUEST, screen_index);
+
+ if (use_user_prescale)
+ {
+ xprescale = user_prescale;
+ yprescale = user_prescale;
+ bgfx_util::find_prescale_factor(width, height, max_prescale_size, xprescale, yprescale);
+ }
break;
+ }
case TARGET_STYLE_NATIVE:
width = chains.targets().width(TARGET_STYLE_NATIVE, screen_index);
height = chains.targets().height(TARGET_STYLE_NATIVE, screen_index);
+
+ if (use_user_prescale)
+ {
+ xprescale = user_prescale;
+ yprescale = user_prescale;
+ bgfx_util::find_prescale_factor(width, height, max_prescale_size, xprescale, yprescale);
+ }
break;
case TARGET_STYLE_CUSTOM:
- if (!READER_CHECK(value.HasMember("width"), (prefix + "Target '" + target_name + "': Must have numeric value 'width'\n").c_str())) return nullptr;
- if (!READER_CHECK(value["width"].IsNumber(), (prefix + "Target '" + target_name + "': Value 'width' must be a number\n").c_str())) return nullptr;
- if (!READER_CHECK(value.HasMember("height"), (prefix + "Target '" + target_name + "': Must have numeric value 'height'\n").c_str())) return nullptr;
- if (!READER_CHECK(value["height"].IsNumber(), (prefix + "Target '" + target_name + "': Value 'height' must be a number\n").c_str())) return nullptr;
+ READER_WARN(!value.HasMember("user_prescale"), "%sTarget '%s': user_prescale parameter is not used for custom-type render targets.\n", prefix, target_name);
+ if (!READER_CHECK(value.HasMember("width"), "%sTarget '%s': Must have numeric value 'width'\n", prefix, target_name)) return nullptr;
+ if (!READER_CHECK(value["width"].IsNumber(), "%sTarget '%s': Value 'width' must be a number\n", prefix, target_name)) return nullptr;
+ if (!READER_CHECK(value.HasMember("height"), "%sTarget '%s': Must have numeric value 'height'\n", prefix, target_name)) return nullptr;
+ if (!READER_CHECK(value["height"].IsNumber(), "%sTarget '%s': Value 'height' must be a number\n", prefix, target_name)) return nullptr;
width = uint16_t(value["width"].GetDouble());
height = uint16_t(value["height"].GetDouble());
break;
}
- return chains.targets().create_target(target_name, bgfx::TextureFormat::BGRA8, width, height, mode, double_buffer, bilinear, scale, screen_index);
+ return chains.targets().create_target(std::move(target_name), bgfx::TextureFormat::BGRA8, width, height, xprescale, yprescale, mode, double_buffer, bilinear, scale, screen_index);
}
-bool target_reader::validate_parameters(const Value& value, std::string prefix)
+bool target_reader::validate_parameters(const Value& value, const std::string &prefix)
{
- if (!READER_CHECK(value.HasMember("name"), (prefix + "Must have string value 'name'\n").c_str())) return false;
- if (!READER_CHECK(value["name"].IsString(), (prefix + "Value 'name' must be a string\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("mode"), (prefix + "Must have string enum 'mode'\n").c_str())) return false;
- 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("scale") || value["scale"].IsNumber(), (prefix + "Value 'scale' must be a numeric value\n").c_str())) return false;
+ if (!READER_CHECK(value.HasMember("name"), "%sMust have string value 'name'\n", prefix)) return false;
+ if (!READER_CHECK(value["name"].IsString(), "%sValue 'name' must be a string\n", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("mode"), "%sMust have string enum 'mode'\n", prefix)) return false;
+ if (!READER_CHECK(value["mode"].IsString(), "%sValue 'mode' must be a string (what screens does this apply to?)\n", prefix)) return false;
+ if (!READER_CHECK(!value.HasMember("bilinear") || value["bilinear"].IsBool(), "%sValue 'bilinear' must be a boolean\n", prefix)) return false;
+ if (!READER_CHECK(!value.HasMember("doublebuffer") || value["doublebuffer"].IsBool(), "%sValue 'doublebuffer' must be a boolean\n", prefix)) return false;
+ if (!READER_CHECK(!value.HasMember("user_prescale") || value["user_prescale"].IsBool(), "%sValue 'user_prescale' must be a boolean\n", prefix)) return false;
+ if (!READER_CHECK(!value.HasMember("scale") || value["scale"].IsNumber(), "%sValue 'scale' must be a numeric value\n", prefix)) return false;
return true;
}
diff --git a/src/osd/modules/render/bgfx/targetreader.h b/src/osd/modules/render/bgfx/targetreader.h
index 7edf5e456fa..2db81311359 100644
--- a/src/osd/modules/render/bgfx/targetreader.h
+++ b/src/osd/modules/render/bgfx/targetreader.h
@@ -6,28 +6,28 @@
//
//============================================================
+#ifndef MAME_RENDER_BGFX_TARGETREADER_H
+#define MAME_RENDER_BGFX_TARGETREADER_H
+
#pragma once
-#ifndef __DRAWBGFX_TARGET_READER__
-#define __DRAWBGFX_TARGET_READER__
+#include "statereader.h"
#include <string>
-#include "statereader.h"
-
class bgfx_target;
class chain_manager;
class target_reader : public state_reader
{
public:
- static bgfx_target* read_from_value(const Value& value, std::string prefix, chain_manager& chains, uint32_t screen_index);
+ static bgfx_target* read_from_value(const Value& value, const std::string &prefix, chain_manager& chains, uint32_t screen_index, uint16_t user_prescale, uint16_t max_prescale_size);
private:
- static bool validate_parameters(const Value& value, std::string prefix);
+ static bool validate_parameters(const Value& value, const std::string &prefix);
static const int STYLE_COUNT = 3;
static const string_to_enum STYLE_NAMES[STYLE_COUNT];
};
-#endif // __DRAWBGFX_TARGET_READER__
+#endif // MAME_RENDER_BGFX_TARGETREADER_H
diff --git a/src/osd/modules/render/bgfx/texture.cpp b/src/osd/modules/render/bgfx/texture.cpp
index a504c625415..2ffa97c0b6f 100644
--- a/src/osd/modules/render/bgfx/texture.cpp
+++ b/src/osd/modules/render/bgfx/texture.cpp
@@ -10,10 +10,11 @@
#include "texture.h"
-bgfx_texture::bgfx_texture(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t height, uint32_t flags, void* data)
+bgfx_texture::bgfx_texture(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t width_margin, uint16_t height, uint32_t flags, void* data)
: m_name(name)
, m_format(format)
, m_width(width)
+ , m_width_margin(width_margin)
, m_height(height)
, m_rowpixels(width)
, m_width_div_factor(1)
@@ -35,10 +36,11 @@ bgfx_texture::bgfx_texture(std::string name, bgfx::TextureFormat::Enum format, u
}
}
-bgfx_texture::bgfx_texture(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t height, const bgfx::Memory* data, uint32_t flags, uint16_t pitch, uint16_t rowpixels, int width_div_factor, int width_mul_factor)
+bgfx_texture::bgfx_texture(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t width_margin, uint16_t height, const bgfx::Memory* data, uint32_t flags, uint16_t pitch, uint16_t rowpixels, int width_div_factor, int width_mul_factor)
: m_name(name)
, m_format(format)
, m_width(width)
+ , m_width_margin(width_margin)
, m_height(height)
, m_rowpixels(rowpixels ? rowpixels : width)
, m_width_div_factor(width_div_factor)
@@ -56,7 +58,8 @@ bgfx_texture::~bgfx_texture()
bgfx::destroy(m_texture);
}
-void bgfx_texture::update(const bgfx::Memory *data, uint16_t pitch)
+void bgfx_texture::update(const bgfx::Memory *data, uint16_t pitch, uint16_t width_margin)
{
+ m_width_margin = width_margin;
bgfx::updateTexture2D(m_texture, 0, 0, 0, 0, (m_rowpixels * m_width_mul_factor) / m_width_div_factor, m_height, data, pitch);
}
diff --git a/src/osd/modules/render/bgfx/texture.h b/src/osd/modules/render/bgfx/texture.h
index 75fedcd3129..ced0604dfcf 100644
--- a/src/osd/modules/render/bgfx/texture.h
+++ b/src/osd/modules/render/bgfx/texture.h
@@ -20,8 +20,8 @@
class bgfx_texture : public bgfx_texture_handle_provider
{
public:
- bgfx_texture(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t height, uint32_t flags, void* data);
- bgfx_texture(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t height, const bgfx::Memory* data, uint32_t flags = BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP, uint16_t pitch = UINT16_MAX, uint16_t rowpixels = 0, int width_div_factor = 1, int width_mul_factor = 1);
+ bgfx_texture(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t width_margin, uint16_t height, uint32_t flags, void* data);
+ bgfx_texture(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t width_margin, uint16_t height, const bgfx::Memory* data, uint32_t flags = BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP, uint16_t pitch = UINT16_MAX, uint16_t rowpixels = 0, int width_div_factor = 1, int width_mul_factor = 1);
virtual ~bgfx_texture();
// Getters
@@ -32,17 +32,19 @@ public:
virtual bgfx::TextureHandle texture() const override { return m_texture; }
virtual bool is_target() const override { return false; }
virtual uint16_t width() const override { return m_width; }
+ virtual uint16_t width_margin() const override { return m_width_margin; }
virtual uint16_t height() const override { return m_height; }
virtual uint16_t rowpixels() const override { return m_rowpixels; }
virtual int width_div_factor() const override { return m_width_div_factor; }
virtual int width_mul_factor() const override { return m_width_mul_factor; }
- void update(const bgfx::Memory *data, uint16_t pitch = UINT16_MAX);
+ void update(const bgfx::Memory *data, uint16_t pitch = UINT16_MAX, uint16_t width_margin = 0);
protected:
std::string m_name;
bgfx::TextureFormat::Enum m_format;
uint16_t m_width;
+ uint16_t m_width_margin;
uint16_t m_height;
uint16_t m_rowpixels;
int m_width_div_factor;
diff --git a/src/osd/modules/render/bgfx/texturehandleprovider.h b/src/osd/modules/render/bgfx/texturehandleprovider.h
index 14fb2fe892c..35e4e12dc43 100644
--- a/src/osd/modules/render/bgfx/texturehandleprovider.h
+++ b/src/osd/modules/render/bgfx/texturehandleprovider.h
@@ -7,26 +7,27 @@
//
//============================================================
-#pragma once
+#ifndef MAME_RENDER_BGFX_TEXTUREHANDLEPROVIDER_H
+#define MAME_RENDER_BGFX_TEXTUREHANDLEPROVIDER_H
-#ifndef __DRAWBGFX_TEXTURE_HANDLE_PROVIDER__
-#define __DRAWBGFX_TEXTURE_HANDLE_PROVIDER__
+#pragma once
#include <bgfx/bgfx.h>
class bgfx_texture_handle_provider
{
public:
- virtual ~bgfx_texture_handle_provider() { }
+ virtual ~bgfx_texture_handle_provider() = default;
// Getters
virtual bgfx::TextureHandle texture() const = 0;
virtual bool is_target() const = 0;
virtual uint16_t width() const = 0;
+ virtual uint16_t width_margin() const = 0;
virtual uint16_t height() const = 0;
virtual uint16_t rowpixels() const = 0;
virtual int width_div_factor() const = 0;
virtual int width_mul_factor() const = 0;
};
-#endif // __DRAWBGFX_TEXTURE_HANDLE_PROVIDER__
+#endif // MAME_RENDER_BGFX_TEXTUREHANDLEPROVIDER_H
diff --git a/src/osd/modules/render/bgfx/texturemanager.cpp b/src/osd/modules/render/bgfx/texturemanager.cpp
index 82225f87eb0..b9acd5748e8 100644
--- a/src/osd/modules/render/bgfx/texturemanager.cpp
+++ b/src/osd/modules/render/bgfx/texturemanager.cpp
@@ -11,23 +11,24 @@
#include "texturemanager.h"
-#include "texture.h"
#include "bgfxutil.h"
+#include "texture.h"
+
+#include "modules/render/copyutil.h"
+#include "osdcore.h"
+
#include "emucore.h"
#include "fileio.h"
#include "rendutil.h"
-#include "osdcore.h"
-#include "modules/render/copyutil.h"
+
+
+texture_manager::texture_manager()
+{
+ // out-of-line so header works with forward declarations
+}
texture_manager::~texture_manager()
{
- for (std::pair<std::string, bgfx_texture_handle_provider*> texture : m_textures)
- {
- if (texture.second != nullptr && !(texture.second)->is_target())
- {
- delete texture.second;
- }
- }
m_textures.clear();
for (std::pair<uint64_t, sequenced_handle> mame_texture : m_mame_textures)
@@ -37,27 +38,45 @@ texture_manager::~texture_manager()
m_mame_textures.clear();
}
-void texture_manager::add_provider(std::string name, bgfx_texture_handle_provider* provider)
+void texture_manager::add_provider(const std::string &name, std::unique_ptr<bgfx_texture_handle_provider> &&provider)
{
- auto iter = m_textures.find(name);
+ const auto iter = m_textures.find(name);
if (iter != m_textures.end())
- {
- iter->second = provider;
- }
+ iter->second = std::make_pair(provider.get(), std::move(provider));
else
- {
- m_textures[name] = provider;
- }
+ m_textures.emplace(name, std::make_pair(provider.get(), std::move(provider)));
}
-bgfx_texture* texture_manager::create_texture(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t height, void* data, uint32_t flags)
+void texture_manager::add_provider(const std::string &name, bgfx_texture_handle_provider &provider)
{
- auto* texture = new bgfx_texture(name, format, width, height, flags, data);
- m_textures[name] = texture;
- return texture;
+ const auto iter = m_textures.find(name);
+ if (iter != m_textures.end())
+ iter->second = std::make_pair(&provider, nullptr);
+ else
+ m_textures.emplace(name, std::make_pair(&provider, nullptr));
+}
+
+bgfx_texture* texture_manager::create_texture(
+ const std::string &name,
+ bgfx::TextureFormat::Enum format,
+ uint32_t width,
+ uint32_t width_margin,
+ uint32_t height,
+ void* data,
+ uint32_t flags)
+{
+ auto texture = std::make_unique<bgfx_texture>(name, format, width, width_margin, height, flags, data);
+ bgfx_texture &result = *texture;
+ m_textures[name] = std::make_pair(texture.get(), std::move(texture));
+ return &result;
}
-bgfx_texture* texture_manager::create_png_texture(std::string path, std::string file_name, std::string texture_name, uint32_t flags, uint32_t screen)
+bgfx_texture* texture_manager::create_png_texture(
+ const std::string &path,
+ const std::string &file_name,
+ std::string texture_name,
+ uint32_t flags,
+ uint32_t screen)
{
bitmap_argb32 bitmap;
emu_file file(path, OPEN_FLAG_READ);
@@ -69,40 +88,45 @@ bgfx_texture* texture_manager::create_png_texture(std::string path, std::string
if (bitmap.width() == 0 || bitmap.height() == 0)
{
- osd_printf_error("Unable to load PNG '%s' from path '%s'\n", file_name.c_str(), path.c_str());
+ osd_printf_error("Unable to load PNG '%s' from path '%s'\n", file_name, path);
return nullptr;
}
- auto *data = new uint8_t[bitmap.width() * bitmap.height() * 4];
- auto *data32 = reinterpret_cast<uint32_t *>(data);
-
const uint32_t width = bitmap.width();
const uint32_t height = bitmap.height();
+ auto data32 = std::make_unique<uint32_t []>(width * height);
+
const uint32_t rowpixels = bitmap.rowpixels();
auto* base = reinterpret_cast<uint32_t *>(bitmap.raw_pixptr(0));
for (int y = 0; y < height; y++)
{
- copy_util::copyline_argb32_to_bgra(data32 + y * width, base + y * rowpixels, width, nullptr);
+ copy_util::copyline_argb32_to_bgra(&data32[y * width], base + y * rowpixels, width, nullptr);
}
if (screen >= 0)
{
texture_name += std::to_string(screen);
}
- bgfx_texture* texture = create_texture(texture_name, bgfx::TextureFormat::BGRA8, width, height, data, flags);
-
- delete [] data;
-
- return texture;
+ return create_texture(texture_name, bgfx::TextureFormat::BGRA8, width, 0, height, data32.get(), flags);
}
-bgfx::TextureHandle texture_manager::create_or_update_mame_texture(uint32_t format, int width, int height
- , int rowpixels, const rgb_t *palette, void *base, uint32_t seqid, uint32_t flags, uint64_t key, uint64_t old_key)
+bgfx::TextureHandle texture_manager::create_or_update_mame_texture(
+ uint32_t format,
+ int width,
+ int width_margin,
+ int height,
+ int rowpixels,
+ const rgb_t *palette,
+ void *base,
+ uint32_t seqid,
+ uint32_t flags,
+ uint64_t key,
+ uint64_t old_key)
{
bgfx::TextureHandle handle = BGFX_INVALID_HANDLE;
if (old_key != ~0ULL)
{
- auto iter = m_mame_textures.find(old_key);
+ const auto iter = m_mame_textures.find(old_key);
if (iter != m_mame_textures.end())
{
handle = iter->second.handle;
@@ -126,8 +150,8 @@ bgfx::TextureHandle texture_manager::create_or_update_mame_texture(uint32_t form
uint16_t pitch = width;
int width_div_factor = 1;
int width_mul_factor = 1;
- const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(dst_format, format, rowpixels, height, palette, base, pitch, width_div_factor, width_mul_factor);
- bgfx::updateTexture2D(handle, 0, 0, 0, 0, (uint16_t)((rowpixels * width_mul_factor) / width_div_factor), (uint16_t)height, mem, pitch);
+ const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(dst_format, format, rowpixels, width_margin, height, palette, base, pitch, width_div_factor, width_mul_factor);
+ bgfx::updateTexture2D(handle, 0, 0, 0, 0, uint16_t((rowpixels * width_mul_factor) / width_div_factor), uint16_t(height), mem, pitch);
return handle;
}
}
@@ -156,8 +180,8 @@ bgfx::TextureHandle texture_manager::create_or_update_mame_texture(uint32_t form
uint16_t pitch = width;
int width_div_factor = 1;
int width_mul_factor = 1;
- const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(dst_format, format, rowpixels, height, palette, base, pitch, width_div_factor, width_mul_factor);
- bgfx::updateTexture2D(handle, 0, 0, 0, 0, (uint16_t)((rowpixels * width_mul_factor) / width_div_factor), (uint16_t)height, mem, pitch);
+ const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(dst_format, format, rowpixels, width_margin, height, palette, base, pitch, width_div_factor, width_mul_factor);
+ bgfx::updateTexture2D(handle, 0, 0, 0, 0, uint16_t((rowpixels * width_mul_factor) / width_div_factor), uint16_t(height), mem, pitch);
return handle;
}
}
@@ -169,47 +193,36 @@ bgfx::TextureHandle texture_manager::create_or_update_mame_texture(uint32_t form
uint16_t pitch = width;
int width_div_factor = 1;
int width_mul_factor = 1;
- const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(dst_format, format, rowpixels, height, palette, base, pitch, width_div_factor, width_mul_factor);
- const uint16_t adjusted_width = (uint16_t)((rowpixels * width_mul_factor) / width_div_factor);
+ const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(dst_format, format, rowpixels, width_margin, height, palette, base, pitch, width_div_factor, width_mul_factor);
+ const uint16_t adjusted_width = uint16_t((rowpixels * width_mul_factor) / width_div_factor);
handle = bgfx::createTexture2D(adjusted_width, height, false, 1, dst_format, flags, nullptr);
- bgfx::updateTexture2D(handle, 0, 0, 0, 0, adjusted_width, (uint16_t)height, mem, pitch);
+ bgfx::updateTexture2D(handle, 0, 0, 0, 0, adjusted_width, uint16_t(height), mem, pitch);
m_mame_textures[key] = { handle, seqid, width, height };
return handle;
}
-bgfx::TextureHandle texture_manager::handle(std::string name)
+bgfx::TextureHandle texture_manager::handle(const std::string &name)
{
bgfx::TextureHandle handle = BGFX_INVALID_HANDLE;
- auto iter = m_textures.find(name);
+ const auto iter = m_textures.find(name);
if (iter != m_textures.end())
- {
- handle = (iter->second)->texture();
- }
+ handle = iter->second.first->texture();
assert(handle.idx != bgfx::kInvalidHandle);
return handle;
}
-bgfx_texture_handle_provider* texture_manager::provider(std::string name)
+bgfx_texture_handle_provider* texture_manager::provider(const std::string &name)
{
- auto iter = m_textures.find(name);
+ const auto iter = m_textures.find(name);
if (iter != m_textures.end())
- {
- return iter->second;
- }
-
- return nullptr;
+ return iter->second.first;
+ else
+ return nullptr;
}
-void texture_manager::remove_provider(std::string name, bool delete_provider)
+void texture_manager::remove_provider(const std::string &name)
{
- if (provider(name) != nullptr)
- {
- if (delete_provider)
- {
- delete m_textures[name];
- }
- m_textures.erase(name);
- }
+ m_textures.erase(name);
}
diff --git a/src/osd/modules/render/bgfx/texturemanager.h b/src/osd/modules/render/bgfx/texturemanager.h
index db71f07c0fa..8ed5d410f75 100644
--- a/src/osd/modules/render/bgfx/texturemanager.h
+++ b/src/osd/modules/render/bgfx/texturemanager.h
@@ -9,40 +9,45 @@
//
//============================================================
-#pragma once
+#ifndef MAME_RENDER_BGFX_TEXTUREMANAGER_H
+#define MAME_RENDER_BGFX_TEXTUREMANAGER_H
-#ifndef DRAWBGFX_TEXTURE_MANAGER
-#define DRAWBGFX_TEXTURE_MANAGER
+#pragma once
#include "bitmap.h"
#include <cstdint>
#include <map>
+#include <memory>
#include <string>
+#include <utility>
#include <bgfx/bgfx.h>
+
class bgfx_texture_handle_provider;
class bgfx_texture;
-class texture_manager {
+class texture_manager
+{
public:
- texture_manager() { }
+ texture_manager();
~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_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP);
- bgfx_texture* create_png_texture(std::string path, std::string file_name, std::string texture_name, uint32_t flags = BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP, uint32_t screen = -1);
- void add_provider(std::string name, bgfx_texture_handle_provider* texture);
- void remove_provider(std::string name, bool delete_provider = false);
- bgfx::TextureHandle create_or_update_mame_texture(uint32_t format, int width, int height
- , int rowpixels, const rgb_t *palette, void *base, uint32_t seqid, uint32_t flags, uint64_t key, uint64_t old_key);
+ bgfx_texture* create_texture(const std::string &name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t width_margin, uint32_t height, void* data = nullptr, uint32_t flags = BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP);
+ bgfx_texture* create_png_texture(const std::string &path, const std::string &file_name, std::string texture_name, uint32_t flags = BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP, uint32_t screen = -1);
+ void add_provider(const std::string &name, std::unique_ptr<bgfx_texture_handle_provider> &&texture);
+ void add_provider(const std::string &name, bgfx_texture_handle_provider &texture);
+ void remove_provider(const std::string &name);
+ bgfx::TextureHandle create_or_update_mame_texture(uint32_t format, int width, int width_margin, int height,
+ int rowpixels, const rgb_t *palette, void *base, uint32_t seqid, uint32_t flags, uint64_t key, uint64_t old_key);
// Getters
- bgfx::TextureHandle handle(std::string name);
- bgfx_texture_handle_provider* provider(std::string name);
+ bgfx::TextureHandle handle(const std::string &name);
+ bgfx_texture_handle_provider* provider(const std::string &name);
private:
- bgfx_texture* create_texture(std::string name);
+ bgfx_texture* create_texture(const std::string &name);
struct sequenced_handle
{
@@ -52,8 +57,8 @@ private:
int height;
};
- std::map<std::string, bgfx_texture_handle_provider*> m_textures;
+ std::map<std::string, std::pair<bgfx_texture_handle_provider *, std::unique_ptr<bgfx_texture_handle_provider> > > m_textures;
std::map<uint64_t, sequenced_handle> m_mame_textures;
};
-#endif // DRAWBGFX_TEXTURE_MANAGER
+#endif // MAME_RENDER_BGFX_TEXTUREMANAGER_H
diff --git a/src/osd/modules/render/bgfx/timeparameter.cpp b/src/osd/modules/render/bgfx/timeparameter.cpp
index cbcd56c8e6e..bc01bb33b61 100644
--- a/src/osd/modules/render/bgfx/timeparameter.cpp
+++ b/src/osd/modules/render/bgfx/timeparameter.cpp
@@ -8,8 +8,10 @@
#include "timeparameter.h"
-bgfx_time_parameter::bgfx_time_parameter(std::string name, parameter_type type, double limit)
- : bgfx_parameter(name, type)
+#include <utility>
+
+bgfx_time_parameter::bgfx_time_parameter(std::string &&name, parameter_type type, double limit)
+ : bgfx_parameter(std::move(name), type)
, m_current_time(0)
, m_limit(limit)
{
diff --git a/src/osd/modules/render/bgfx/timeparameter.h b/src/osd/modules/render/bgfx/timeparameter.h
index ad01f8f7e60..ff7005041ff 100644
--- a/src/osd/modules/render/bgfx/timeparameter.h
+++ b/src/osd/modules/render/bgfx/timeparameter.h
@@ -6,22 +6,19 @@
//
//============================================================
-#pragma once
+#ifndef MAME_RENDER_BGFX_TIMEPARAMETER_H
+#define MAME_RENDER_BGFX_TIMEPARAMETER_H
-#ifndef __DRAWBGFX_TIME_PARAMETER__
-#define __DRAWBGFX_TIME_PARAMETER__
+#pragma once
-#include <bgfx/bgfx.h>
+#include "parameter.h"
#include <string>
-#include "parameter.h"
-
class bgfx_time_parameter : public bgfx_parameter
{
public:
- bgfx_time_parameter(std::string name, parameter_type type, double limit);
- virtual ~bgfx_time_parameter() { }
+ bgfx_time_parameter(std::string &&name, parameter_type type, double limit);
virtual float value() override;
virtual void tick(double delta) override;
@@ -31,4 +28,4 @@ private:
double m_limit;
};
-#endif // __DRAWBGFX_TIME_PARAMETER__
+#endif // MAME_RENDER_BGFX_TIMEPARAMETER_H
diff --git a/src/osd/modules/render/bgfx/uniform.cpp b/src/osd/modules/render/bgfx/uniform.cpp
index 36f68b7a9c7..238a6a4315d 100644
--- a/src/osd/modules/render/bgfx/uniform.cpp
+++ b/src/osd/modules/render/bgfx/uniform.cpp
@@ -7,10 +7,12 @@
//============================================================
#include "uniform.h"
+
#include <cstring>
+#include <utility>
-bgfx_uniform::bgfx_uniform(std::string name, bgfx::UniformType::Enum type)
- : m_name(name)
+bgfx_uniform::bgfx_uniform(std::string &&name, bgfx::UniformType::Enum type)
+ : m_name(std::move(name))
, m_type(type)
{
m_handle = BGFX_INVALID_HANDLE;
diff --git a/src/osd/modules/render/bgfx/uniform.h b/src/osd/modules/render/bgfx/uniform.h
index f7873f400a9..6a9999ca19f 100644
--- a/src/osd/modules/render/bgfx/uniform.h
+++ b/src/osd/modules/render/bgfx/uniform.h
@@ -6,10 +6,10 @@
//
//============================================================
-#pragma once
+#ifndef MAME_RENDER_BGFX_UNIFORM_H
+#define MAME_RENDER_BGFX_UNIFORM_H
-#ifndef __DRAWBGFX_UNIFORM__
-#define __DRAWBGFX_UNIFORM__
+#pragma once
#include <bgfx/bgfx.h>
@@ -18,7 +18,7 @@
class bgfx_uniform
{
public:
- bgfx_uniform(std::string name, bgfx::UniformType::Enum type);
+ bgfx_uniform(std::string &&name, bgfx::UniformType::Enum type);
virtual ~bgfx_uniform();
virtual void upload();
@@ -26,7 +26,7 @@ public:
void create();
// Getters
- std::string name() { return m_name; }
+ const std::string &name() { return m_name; }
bgfx::UniformType::Enum type() const { return m_type; }
bgfx::UniformHandle handle() const { return m_handle; }
@@ -47,4 +47,4 @@ protected:
size_t m_data_size;
};
-#endif // __DRAWBGFX_UNIFORM__
+#endif // MAME_RENDER_BGFX_UNIFORM_H
diff --git a/src/osd/modules/render/bgfx/uniformreader.cpp b/src/osd/modules/render/bgfx/uniformreader.cpp
index f2bf1114ec6..d1eab8098c7 100644
--- a/src/osd/modules/render/bgfx/uniformreader.cpp
+++ b/src/osd/modules/render/bgfx/uniformreader.cpp
@@ -10,6 +10,9 @@
#include "uniform.h"
+#include <cstdlib>
+
+
const uniform_reader::string_to_enum uniform_reader::TYPE_NAMES[uniform_reader::TYPE_COUNT] = {
{ "int", bgfx::UniformType::Sampler },
{ "vec4", bgfx::UniformType::Vec4 },
@@ -17,7 +20,7 @@ const uniform_reader::string_to_enum uniform_reader::TYPE_NAMES[uniform_reader::
{ "mat4", bgfx::UniformType::Mat4 }
};
-bgfx_uniform* uniform_reader::read_from_value(const Value& value, std::string prefix)
+std::unique_ptr<bgfx_uniform> uniform_reader::read_from_value(const Value& value, const std::string &prefix)
{
if (!validate_parameters(value, prefix))
{
@@ -31,33 +34,28 @@ bgfx_uniform* uniform_reader::read_from_value(const Value& value, std::string pr
const Value& value_array = value["values"];
const size_t array_size = value_array.Size() * sizeof(float);
- const size_t alloc_size = (type_size > array_size) ? type_size : array_size;
- auto* data = reinterpret_cast<float*>(new char[alloc_size]);
+ auto* data = reinterpret_cast<float*>(std::malloc(std::max(type_size, array_size)));
unsigned int index = 0;
for (; index < type_size / 4 && index < value_array.Size(); index++)
- {
- data[index] = (float)value_array[index].GetDouble();
- }
+ data[index] = float(value_array[index].GetDouble());
for (; index < type_size / 4; index++)
- {
data[index] = 0.0f;
- }
- auto* uniform = new bgfx_uniform(name, type);
- uniform->set((void*)data, type_size);
- delete [] data;
+ auto uniform = std::make_unique<bgfx_uniform>(name, type);
+ uniform->set(data, type_size);
+ std::free(data);
return uniform;
}
-bool uniform_reader::validate_parameters(const Value& value, std::string prefix)
+bool uniform_reader::validate_parameters(const Value& value, const std::string &prefix)
{
- if (!READER_CHECK(value.HasMember("name"), (prefix + "Must have string value 'name' (what is this uniform called in the shader code?)\n").c_str())) return false;
- if (!READER_CHECK(value["name"].IsString(), (prefix + "Value 'name' must be a string\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("type"), (prefix + "Must have string value 'type' [int, vec4, mat3, mat4]\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("values"), (prefix + "Must have array value 'values' (what are the uniform's default values?)\n").c_str())) return false;
- if (!READER_CHECK(value["values"].IsArray(), (prefix + "Value 'values' must be an array\n").c_str())) return false;
+ if (!READER_CHECK(value.HasMember("name"), "%sMust have string value 'name' (what is this uniform called in the shader code?)\n", prefix)) return false;
+ if (!READER_CHECK(value["name"].IsString(), "%sValue 'name' must be a string\n", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("type"), "%sMust have string value 'type' [int, vec4, mat3, mat4]\n", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("values"), "%sMust have array value 'values' (what are the uniform's default values?)\n", prefix)) return false;
+ if (!READER_CHECK(value["values"].IsArray(), "%sValue 'values' must be an array\n", prefix)) return false;
return true;
}
diff --git a/src/osd/modules/render/bgfx/uniformreader.h b/src/osd/modules/render/bgfx/uniformreader.h
index ce1b1e9ccbe..ebb3a485d63 100644
--- a/src/osd/modules/render/bgfx/uniformreader.h
+++ b/src/osd/modules/render/bgfx/uniformreader.h
@@ -6,27 +6,29 @@
//
//============================================================
+#ifndef MAME_RENDER_BGFX_UNIFORMREADER_H
+#define MAME_RENDER_BGFX_UNIFORMREADER_H
+
#pragma once
-#ifndef __DRAWBGFX_UNIFORM_READER__
-#define __DRAWBGFX_UNIFORM_READER__
+#include "statereader.h"
-#include <bgfx/bgfx.h>
+#include <memory>
+#include <string>
-#include "statereader.h"
class bgfx_uniform;
class uniform_reader : public state_reader
{
public:
- static bgfx_uniform* read_from_value(const Value& value, std::string prefix);
+ static std::unique_ptr<bgfx_uniform> read_from_value(const Value& value, const std::string &prefix);
private:
- static bool validate_parameters(const Value& value, std::string prefix);
+ static bool validate_parameters(const Value& value, const std::string &prefix);
static const int TYPE_COUNT = 4;
static const string_to_enum TYPE_NAMES[TYPE_COUNT];
};
-#endif // __DRAWBGFX_UNIFORM_READER__
+#endif // MAME_RENDER_BGFX_UNIFORMREADER_H
diff --git a/src/osd/modules/render/bgfx/valueuniform.cpp b/src/osd/modules/render/bgfx/valueuniform.cpp
index 8a018ac492a..e36ee3cbca8 100644
--- a/src/osd/modules/render/bgfx/valueuniform.cpp
+++ b/src/osd/modules/render/bgfx/valueuniform.cpp
@@ -10,13 +10,17 @@
//============================================================
#include "valueuniform.h"
-#include <cstring>
-bgfx_value_uniform::bgfx_value_uniform(bgfx_uniform* uniform, float* values, const int count)
+#include <algorithm>
+#include <cassert>
+
+
+bgfx_value_uniform::bgfx_value_uniform(bgfx_uniform* uniform, const float* values, const int count)
: bgfx_entry_uniform(uniform)
, m_count(count)
{
- memcpy(m_values, values, sizeof(float) * count);
+ assert(count <= std::size(m_values));
+ std::copy_n(values, count, m_values);
}
void bgfx_value_uniform::bind()
diff --git a/src/osd/modules/render/bgfx/valueuniform.h b/src/osd/modules/render/bgfx/valueuniform.h
index 40d207aa0bb..aa8139650a3 100644
--- a/src/osd/modules/render/bgfx/valueuniform.h
+++ b/src/osd/modules/render/bgfx/valueuniform.h
@@ -9,17 +9,17 @@
//
//============================================================
-#pragma once
+#ifndef MAME_RENDER_BGFX_VALUEUNIFORM_H
+#define MAME_RENDER_BGFX_VALUEUNIFORM_H
-#ifndef __DRAWBGFX_VALUE_UNIFORM__
-#define __DRAWBGFX_VALUE_UNIFORM__
+#pragma once
#include "entryuniform.h"
class bgfx_value_uniform : public bgfx_entry_uniform
{
public:
- bgfx_value_uniform(bgfx_uniform* uniform, float* values, const int count);
+ bgfx_value_uniform(bgfx_uniform* uniform, const float* values, const int count);
virtual void bind() override;
@@ -28,4 +28,4 @@ private:
const int m_count;
};
-#endif // __DRAWBGFX_VALUE_UNIFORM__
+#endif // MAME_RENDER_BGFX_VALUEUNIFORM_H
diff --git a/src/osd/modules/render/bgfx/valueuniformreader.cpp b/src/osd/modules/render/bgfx/valueuniformreader.cpp
index e71f1c86329..137a6d24719 100644
--- a/src/osd/modules/render/bgfx/valueuniformreader.cpp
+++ b/src/osd/modules/render/bgfx/valueuniformreader.cpp
@@ -11,7 +11,7 @@
#include "entryuniform.h"
#include "valueuniform.h"
-bgfx_entry_uniform* value_uniform_reader::read_from_value(const Value& value, std::string prefix, bgfx_uniform* uniform)
+bgfx_entry_uniform* value_uniform_reader::read_from_value(const Value& value, const std::string &prefix, bgfx_uniform* uniform)
{
if (!validate_parameters(value, prefix))
{
@@ -36,9 +36,9 @@ bgfx_entry_uniform* value_uniform_reader::read_from_value(const Value& value, st
return new bgfx_value_uniform(uniform, values, count);
}
-bool value_uniform_reader::validate_parameters(const Value& value, std::string prefix)
+bool value_uniform_reader::validate_parameters(const Value& value, const std::string &prefix)
{
- if (!READER_CHECK(value.HasMember("value"), (prefix + "Must have string value 'value' (what value is being assigned?)\n").c_str())) return false;
- if (!READER_CHECK(value["value"].IsArray() || value["value"].IsNumber(), (prefix + "Value 'value' must be numeric or an array\n").c_str())) return false;
+ if (!READER_CHECK(value.HasMember("value"), "%sMust have string value 'value' (what value is being assigned?)\n", prefix)) return false;
+ if (!READER_CHECK(value["value"].IsArray() || value["value"].IsNumber(), "%sValue 'value' must be numeric or an array\n", prefix)) return false;
return true;
}
diff --git a/src/osd/modules/render/bgfx/valueuniformreader.h b/src/osd/modules/render/bgfx/valueuniformreader.h
index 0b6fead1cca..ea544266a84 100644
--- a/src/osd/modules/render/bgfx/valueuniformreader.h
+++ b/src/osd/modules/render/bgfx/valueuniformreader.h
@@ -6,15 +6,14 @@
//
//================================================================
+#ifndef MAME_RENDER_BGFX_VALUEUNIFORMREADER_H
+#define MAME_RENDER_BGFX_VALUEUNIFORMREADER_H
+
#pragma once
-#ifndef __DRAWBGFX_VALUE_UNIFORM_READER__
-#define __DRAWBGFX_VALUE_UNIFORM_READER__
+#include "statereader.h"
#include <string>
-#include <map>
-
-#include "statereader.h"
class bgfx_entry_uniform;
class bgfx_uniform;
@@ -22,10 +21,10 @@ class bgfx_uniform;
class value_uniform_reader : public state_reader
{
public:
- static bgfx_entry_uniform* read_from_value(const Value& value, std::string prefix, bgfx_uniform* uniform);
+ static bgfx_entry_uniform* read_from_value(const Value& value, const std::string &prefix, bgfx_uniform* uniform);
private:
- static bool validate_parameters(const Value& value, std::string prefix);
+ static bool validate_parameters(const Value& value, const std::string &prefix);
};
-#endif // __DRAWBGFX_VALUE_UNIFORM_READER__
+#endif // MAME_RENDER_BGFX_VALUEUNIFORMREADER_H
diff --git a/src/osd/modules/render/bgfx/view.cpp b/src/osd/modules/render/bgfx/view.cpp
index 6935e19bca7..3a731fc71f8 100644
--- a/src/osd/modules/render/bgfx/view.cpp
+++ b/src/osd/modules/render/bgfx/view.cpp
@@ -13,9 +13,7 @@
#include "target.h"
void bgfx_view::update() {
- std::shared_ptr<osd_window> win = m_renderer->assert_window();
-
- const uint32_t window_index = win->index();
+ const uint32_t window_index = m_renderer->window().index();
const uint32_t width = m_renderer->get_window_width(window_index);
const uint32_t height = m_renderer->get_window_height(window_index);
diff --git a/src/osd/modules/render/bgfx/view.h b/src/osd/modules/render/bgfx/view.h
index a1793f89d0b..b257eb12ea4 100644
--- a/src/osd/modules/render/bgfx/view.h
+++ b/src/osd/modules/render/bgfx/view.h
@@ -4,12 +4,14 @@
#pragma once
#include "window.h"
+
#include <climits>
class renderer_bgfx;
class bgfx_target;
-class bgfx_view {
+class bgfx_view
+{
public:
bgfx_view(renderer_bgfx *renderer, uint32_t index, bgfx_target *backbuffer, std::vector<uint32_t> &seen_views)
: m_renderer(renderer)
@@ -21,7 +23,7 @@ public:
, m_view_height(0)
, m_z_near(0.0f)
, m_z_far(100.0f)
- , m_clear_color(0)
+ , m_clear_color(0x000000ff)
, m_clear_depth(1.0f)
, m_clear_stencil(0)
, m_do_clear_color(true)
diff --git a/src/osd/modules/render/bgfx/windowparameter.h b/src/osd/modules/render/bgfx/windowparameter.h
index 0ba4224de40..45df9060c71 100644
--- a/src/osd/modules/render/bgfx/windowparameter.h
+++ b/src/osd/modules/render/bgfx/windowparameter.h
@@ -6,22 +6,20 @@
//
//============================================================
-#pragma once
+#ifndef MAME_RENDER_BGFX_WINDOWPARAMETER_H
+#define MAME_RENDER_BGFX_WINDOWPARAMETER_H
-#ifndef __DRAWBGFX_WINDOW_PARAMETER__
-#define __DRAWBGFX_WINDOW_PARAMETER__
+#pragma once
-#include <bgfx/bgfx.h>
+#include "parameter.h"
#include <string>
-
-#include "parameter.h"
+#include <utility>
class bgfx_window_parameter : public bgfx_parameter
{
public:
- bgfx_window_parameter(std::string name, parameter_type type, uint32_t index) : bgfx_parameter(name, type), m_index(index) { }
- virtual ~bgfx_window_parameter() { }
+ bgfx_window_parameter(std::string &&name, parameter_type type, uint32_t index) : bgfx_parameter(std::move(name), type), m_index(index) { }
virtual float value() override { return float(m_index); }
virtual void tick(double delta) override { }
@@ -30,4 +28,4 @@ private:
uint32_t m_index;
};
-#endif // __DRAWBGFX_WINDOW_PARAMETER__
+#endif // MAME_RENDER_BGFX_WINDOWPARAMETER_H
diff --git a/src/osd/modules/render/bgfxutil.cpp b/src/osd/modules/render/bgfxutil.cpp
index e864cb98fb4..3d555bb60ad 100644
--- a/src/osd/modules/render/bgfxutil.cpp
+++ b/src/osd/modules/render/bgfxutil.cpp
@@ -14,10 +14,11 @@
#include "render.h"
-const bgfx::Memory* bgfx_util::mame_texture_data_to_bgfx_texture_data(bgfx::TextureFormat::Enum &dst_format, uint32_t src_format, int rowpixels, int height, const rgb_t *palette, void *base, uint16_t &out_pitch, int &width_div_factor, int &width_mul_factor)
+const bgfx::Memory* bgfx_util::mame_texture_data_to_bgfx_texture_data(bgfx::TextureFormat::Enum &dst_format, uint32_t src_format, int rowpixels, int width_margin, int height, const rgb_t *palette, void *base, uint16_t &out_pitch, int &width_div_factor, int &width_mul_factor)
{
bgfx::TextureInfo info;
const bgfx::Memory *data = nullptr;
+ uint8_t *adjusted_base = (uint8_t *)base;
switch (src_format)
{
@@ -28,7 +29,11 @@ const bgfx::Memory* bgfx_util::mame_texture_data_to_bgfx_texture_data(bgfx::Text
out_pitch = rowpixels * 2;
bgfx::calcTextureSize(info, rowpixels / width_div_factor, height, 1, false, false, 1, dst_format);
- data = bgfx::copy(base, info.storageSize);
+ if (width_margin)
+ {
+ adjusted_base -= width_margin * 2;
+ }
+ data = bgfx::copy(adjusted_base, info.storageSize);
break;
case PRIMFLAG_TEXFORMAT(TEXFORMAT_PALETTE16):
dst_format = bgfx::TextureFormat::R8;
@@ -37,7 +42,11 @@ const bgfx::Memory* bgfx_util::mame_texture_data_to_bgfx_texture_data(bgfx::Text
out_pitch = rowpixels * 2;
bgfx::calcTextureSize(info, rowpixels * width_mul_factor, height, 1, false, false, 1, dst_format);
- data = bgfx::copy(base, info.storageSize);
+ if (width_margin)
+ {
+ adjusted_base -= width_margin * 2;
+ }
+ data = bgfx::copy(adjusted_base, info.storageSize);
break;
case PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32):
case PRIMFLAG_TEXFORMAT(TEXFORMAT_RGB32):
@@ -47,7 +56,11 @@ const bgfx::Memory* bgfx_util::mame_texture_data_to_bgfx_texture_data(bgfx::Text
out_pitch = rowpixels * 4;
bgfx::calcTextureSize(info, rowpixels, height, 1, false, false, 1, dst_format);
- data = bgfx::copy(base, info.storageSize);
+ if (width_margin)
+ {
+ adjusted_base -= width_margin * 4;
+ }
+ data = bgfx::copy(adjusted_base, info.storageSize);
break;
}
@@ -96,6 +109,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_INV_SRC_COLOR, BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_ZERO);
return BGFX_STATE_BLEND_FUNC_SEPARATE(BGFX_STATE_BLEND_DST_COLOR, BGFX_STATE_BLEND_ZERO, BGFX_STATE_BLEND_DST_ALPHA, BGFX_STATE_BLEND_ZERO);
case BLENDMODE_ADD:
return BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_ONE);
@@ -104,3 +118,15 @@ uint64_t bgfx_util::get_blend_state(uint32_t blend)
}
return 0L;
}
+
+void bgfx_util::find_prescale_factor(uint16_t width, uint16_t height, uint16_t max_prescale_size, uint16_t &xprescale, uint16_t &yprescale)
+{
+ while (xprescale > 1 && width * xprescale > max_prescale_size)
+ {
+ xprescale--;
+ }
+ while (yprescale > 1 && height * yprescale > max_prescale_size)
+ {
+ yprescale--;
+ }
+}
diff --git a/src/osd/modules/render/bgfxutil.h b/src/osd/modules/render/bgfxutil.h
index db07e7fba77..aa108a6fb3b 100644
--- a/src/osd/modules/render/bgfxutil.h
+++ b/src/osd/modules/render/bgfxutil.h
@@ -15,9 +15,10 @@
class bgfx_util
{
public:
- static const bgfx::Memory* mame_texture_data_to_bgfx_texture_data(bgfx::TextureFormat::Enum &dst_format, uint32_t format, int rowpixels, int height, const rgb_t *palette, void *base, uint16_t &out_pitch, int &width_div_factor, int &width_mul_factor);
+ static const bgfx::Memory* mame_texture_data_to_bgfx_texture_data(bgfx::TextureFormat::Enum &dst_format, uint32_t format, int rowpixels, int width_margin, int height, const rgb_t *palette, void *base, uint16_t &out_pitch, int &width_div_factor, int &width_mul_factor);
static const bgfx::Memory* mame_texture_data_to_bgra32(uint32_t src_format, int width, int height, int rowpixels, const rgb_t *palette, void *base);
static uint64_t get_blend_state(uint32_t blend);
+ static void find_prescale_factor(uint16_t width, uint16_t height, uint16_t max_prescale_size, uint16_t &xprescale, uint16_t &yprescale);
};
#endif // RENDER_BGFX_UTIL
diff --git a/src/osd/modules/render/binpacker.h b/src/osd/modules/render/binpacker.h
index 1fb84596eec..52efe4abb85 100644
--- a/src/osd/modules/render/binpacker.h
+++ b/src/osd/modules/render/binpacker.h
@@ -29,7 +29,7 @@ public:
class packable_rectangle
{
public:
- packable_rectangle() : m_hash(0), m_width(-1), m_height(-1) { }
+ packable_rectangle() = default;
packable_rectangle(uint32_t hash, uint32_t format, int width, int height, int rowpixels, const rgb_t *palette, void *base)
: m_hash(hash)
, m_format(format)
@@ -50,19 +50,19 @@ public:
void* base() const { return m_base; }
private:
- uint32_t m_hash;
- uint32_t m_format;
- int m_width;
- int m_height;
- int m_rowpixels;
- const rgb_t* m_palette;
- void* m_base;
+ uint32_t m_hash = 0;
+ uint32_t m_format = 0;
+ int m_width = -1;
+ int m_height = -1;
+ int m_rowpixels = 0;
+ const rgb_t* m_palette = nullptr;
+ void* m_base = nullptr;
};
class packed_rectangle
{
public:
- packed_rectangle() : m_hash(0), m_format(0), m_width(-1), m_height(-1), m_x(-1), m_y(-1), m_rowpixels(0), m_palette(nullptr), m_base(nullptr) { }
+ packed_rectangle() = default;
packed_rectangle(const packed_rectangle& rect)
: m_hash(rect.m_hash)
, m_format(rect.m_format)
@@ -99,15 +99,15 @@ public:
void* base() const { return m_base; }
private:
- uint32_t m_hash;
- uint32_t m_format;
- int m_width;
- int m_height;
- int m_x;
- int m_y;
- int m_rowpixels;
- const rgb_t* m_palette;
- void* m_base;
+ uint32_t m_hash = 0;
+ uint32_t m_format = 0;
+ int m_width = -1;
+ int m_height = -1;
+ int m_x = -1;
+ int m_y = -1;
+ int m_rowpixels = 0;
+ const rgb_t* m_palette = nullptr;
+ void* m_base = nullptr;
};
bool pack(const std::vector<packable_rectangle>& rects, std::vector<std::vector<packed_rectangle>>& packs, int pack_size);
diff --git a/src/osd/modules/render/blit13.h b/src/osd/modules/render/blit13.ipp
index 1ac485bab8d..1ac485bab8d 100644
--- a/src/osd/modules/render/blit13.h
+++ b/src/osd/modules/render/blit13.ipp
diff --git a/src/osd/modules/render/d3d/d3dcomm.h b/src/osd/modules/render/d3d/d3dcomm.h
index c7dc58c6340..846d9dac791 100644
--- a/src/osd/modules/render/d3d/d3dcomm.h
+++ b/src/osd/modules/render/d3d/d3dcomm.h
@@ -6,8 +6,22 @@
//
//============================================================
-#ifndef __WIN_D3DCOMM__
-#define __WIN_D3DCOMM__
+#ifndef MAME_RENDER_D3D_D3DCOMM_H
+#define MAME_RENDER_D3D_D3DCOMM_H
+
+#pragma once
+
+// lib/util
+#include "bitmap.h"
+
+#include <windows.h>
+#include <d3d9.h>
+#include <wrl/client.h>
+
+#include <cstring>
+#include <memory>
+#include <vector>
+
//============================================================
// CONSTANTS
@@ -60,10 +74,7 @@ public:
class d3d_texture_manager
{
public:
- d3d_texture_manager(): m_renderer(nullptr), m_yuv_format(), m_texture_caps(0), m_texture_max_aspect(0), m_texture_max_width(0), m_texture_max_height(0), m_default_texture(nullptr)
- { }
-
- d3d_texture_manager(renderer_d3d9 *d3d);
+ d3d_texture_manager(renderer_d3d9 &d3d, IDirect3D9 *d3dobj);
void update_textures();
@@ -82,12 +93,12 @@ public:
texture_info * get_default_texture() const { return m_default_texture; }
- renderer_d3d9 * get_d3d() const { return m_renderer; }
+ renderer_d3d9 & get_d3d() const { return m_renderer; }
- std::vector<std::unique_ptr<texture_info>> m_texture_list; // list of active textures
+ std::vector<std::unique_ptr<texture_info> > m_texture_list; // list of active textures
private:
- renderer_d3d9 * m_renderer;
+ renderer_d3d9 & m_renderer;
D3DFORMAT m_yuv_format; // format to use for YUV textures
DWORD m_texture_caps; // textureCaps field
@@ -104,7 +115,7 @@ private:
class texture_info
{
public:
- texture_info(d3d_texture_manager *manager, const render_texinfo *texsource, int prescale, uint32_t flags);
+ texture_info(d3d_texture_manager &manager, const render_texinfo *texsource, int prescale, uint32_t flags);
~texture_info();
render_texinfo & get_texinfo() { return m_texinfo; }
@@ -125,15 +136,16 @@ public:
int get_cur_frame() const { return m_cur_frame; }
- IDirect3DTexture9 * get_tex() const { return m_d3dtex; }
- IDirect3DSurface9 * get_surface() const { return m_d3dsurface; }
- IDirect3DTexture9 * get_finaltex() const { return m_d3dfinaltex; }
+ IDirect3DTexture9 * get_finaltex() const { return m_d3dfinaltex.Get(); }
vec2f & get_uvstart() { return m_start; }
vec2f & get_uvstop() { return m_stop; }
vec2f & get_rawdims() { return m_rawdims; }
private:
+ using IDirect3DTexture9Ptr = Microsoft::WRL::ComPtr<IDirect3DTexture9>;
+ using IDirect3DSurface9Ptr = Microsoft::WRL::ComPtr<IDirect3DSurface9>;
+
void prescale();
void compute_size(int texwidth, int texheight);
void compute_size_subroutine(int texwidth, int texheight, int* p_width, int* p_height);
@@ -145,23 +157,23 @@ private:
inline void copyline_yuy16_to_uyvy(uint16_t *dst, const uint16_t *src, int width, const rgb_t *palette);
inline void copyline_yuy16_to_argb(uint32_t *dst, const uint16_t *src, int width, const rgb_t *palette);
- d3d_texture_manager * m_texture_manager; // texture manager pointer
+ d3d_texture_manager & m_texture_manager; // texture manager pointer
- renderer_d3d9 * m_renderer; // renderer pointer
+ renderer_d3d9 & m_renderer; // renderer pointer
- uint32_t m_hash; // hash value for the texture
- uint32_t m_flags; // rendering flags
+ const uint32_t m_hash; // hash value for the texture
+ const uint32_t m_flags; // rendering flags
render_texinfo m_texinfo; // copy of the texture info
+ const int m_type; // what type of texture are we?
vec2f m_start; // beggining UV coordinates
vec2f m_stop; // ending UV coordinates
vec2f m_rawdims; // raw dims of the texture
- int m_type; // what type of texture are we?
int m_xprescale, m_yprescale; // X/Y prescale factor
int m_xborderpix, m_yborderpix; // X/Y border pixels
int m_cur_frame; // what is our current frame?
- IDirect3DTexture9 * m_d3dtex; // Direct3D texture pointer
- IDirect3DSurface9 * m_d3dsurface; // Direct3D offscreen plain surface pointer
- IDirect3DTexture9 * m_d3dfinaltex; // Direct3D final (post-scaled) texture
+ IDirect3DTexture9Ptr m_d3dtex; // Direct3D texture pointer
+ IDirect3DSurface9Ptr m_d3dsurface; // Direct3D offscreen plain surface pointer
+ IDirect3DTexture9Ptr m_d3dfinaltex; // Direct3D final (post-scaled) texture
};
/* poly_info holds information about a single polygon/d3d primitive */
@@ -170,7 +182,7 @@ class poly_info
public:
void init(D3DPRIMITIVETYPE type, uint32_t count, uint32_t numverts,
uint32_t flags, texture_info *texture, uint32_t modmode,
- float prim_width, float prim_height)
+ float prim_width, float prim_height, uint32_t tint)
{
m_type = type;
m_count = count;
@@ -180,6 +192,7 @@ public:
m_modmode = modmode;
m_prim_width = prim_width;
m_prim_height = prim_height;
+ m_tint = tint;
}
D3DPRIMITIVETYPE type() const { return m_type; }
@@ -193,6 +206,8 @@ public:
float prim_width() const { return m_prim_width; }
float prim_height() const { return m_prim_height; }
+ DWORD tint() const { return m_tint; }
+
private:
D3DPRIMITIVETYPE m_type; // type of primitive
uint32_t m_count; // total number of primitives
@@ -204,6 +219,8 @@ private:
float m_prim_width; // used by quads
float m_prim_height; // used by quads
+
+ uint32_t m_tint; // color tint for primitive
};
/* vertex describes a single vertex */
@@ -222,24 +239,14 @@ class d3d_render_target
{
public:
// construction/destruction
- d3d_render_target(): target_width(0), target_height(0), width(0), height(0), screen_index(0), bloom_count(0)
+ d3d_render_target()
+ : target_width(0)
+ , target_height(0)
+ , width(0)
+ , height(0)
+ , screen_index(0)
+ , bloom_count(0)
{
- for (int index = 0; index < MAX_BLOOM_COUNT; index++)
- {
- bloom_texture[index] = nullptr;
- bloom_surface[index] = nullptr;
- }
-
- for (int index = 0; index < 2; index++)
- {
- source_texture[index] = nullptr;
- source_surface[index] = nullptr;
- target_texture[index] = nullptr;
- target_surface[index] = nullptr;
- }
-
- cache_texture = nullptr;
- cache_surface = nullptr;
}
~d3d_render_target();
@@ -257,20 +264,20 @@ public:
int screen_index;
- IDirect3DSurface9 *target_surface[2];
- IDirect3DTexture9 *target_texture[2];
- IDirect3DSurface9 *source_surface[2];
- IDirect3DTexture9 *source_texture[2];
+ Microsoft::WRL::ComPtr<IDirect3DSurface9> target_surface[2];
+ Microsoft::WRL::ComPtr<IDirect3DTexture9> target_texture[2];
+ Microsoft::WRL::ComPtr<IDirect3DSurface9> source_surface[2];
+ Microsoft::WRL::ComPtr<IDirect3DTexture9> source_texture[2];
- IDirect3DSurface9 *cache_surface;
- IDirect3DTexture9 *cache_texture;
+ Microsoft::WRL::ComPtr<IDirect3DSurface9> cache_surface;
+ Microsoft::WRL::ComPtr<IDirect3DTexture9> cache_texture;
- IDirect3DSurface9 *bloom_surface[MAX_BLOOM_COUNT];
- IDirect3DTexture9 *bloom_texture[MAX_BLOOM_COUNT];
+ Microsoft::WRL::ComPtr<IDirect3DSurface9> bloom_surface[MAX_BLOOM_COUNT];
+ Microsoft::WRL::ComPtr<IDirect3DTexture9> bloom_texture[MAX_BLOOM_COUNT];
float bloom_dims[MAX_BLOOM_COUNT][2];
int bloom_count;
};
-#endif
+#endif // MAME_RENDER_D3D_D3DCOMM_H
diff --git a/src/osd/modules/render/d3d/d3dhlsl.cpp b/src/osd/modules/render/d3d/d3dhlsl.cpp
index 22a6b5af508..c0753f314f7 100644
--- a/src/osd/modules/render/d3d/d3dhlsl.cpp
+++ b/src/osd/modules/render/d3d/d3dhlsl.cpp
@@ -8,15 +8,18 @@
// MAME headers
#include "emu.h"
+
#include "drivenum.h"
+#include "emuopts.h"
+#include "fileio.h"
+#include "main.h"
#include "render.h"
#include "rendlay.h"
#include "rendutil.h"
-#include "emuopts.h"
-#include "fileio.h"
+#include "screen.h"
+
#include "aviio.h"
#include "png.h"
-#include "screen.h"
// MAMEOS headers
#include "winmain.h"
@@ -50,8 +53,6 @@ class movie_recorder
public:
movie_recorder(running_machine& machine, renderer_d3d9 *d3d, int width, int height)
: m_initialized(false), m_d3d(d3d), m_width(width), m_height(height)
- , m_sys_texture(nullptr), m_sys_surface(nullptr)
- , m_vid_texture(nullptr), m_vid_surface(nullptr)
{
HRESULT result;
@@ -82,17 +83,6 @@ public:
~movie_recorder()
{
- if (m_sys_texture != nullptr)
- m_sys_texture->Release();
-
- if (m_sys_surface != nullptr)
- m_sys_surface->Release();
-
- if (m_vid_texture != nullptr)
- m_vid_texture->Release();
-
- if (m_vid_surface != nullptr)
- m_vid_surface->Release();
}
void record(const char *name)
@@ -109,7 +99,7 @@ public:
return;
// copy the frame from video memory, where it is not accessible, to system memory
- HRESULT result = m_d3d->get_device()->GetRenderTargetData(m_vid_surface, m_sys_surface);
+ HRESULT result = m_d3d->get_device()->GetRenderTargetData(m_vid_surface.Get(), m_sys_surface.Get());
if (FAILED(result))
return;
@@ -144,7 +134,7 @@ public:
m_avi_writer->audio_frame(buffer, samples_this_frame);
}
- IDirect3DSurface9 * target_surface() { return m_vid_surface; }
+ IDirect3DSurface9 * target_surface() { return m_vid_surface.Get(); }
private:
bool m_initialized;
@@ -156,10 +146,10 @@ private:
bitmap_rgb32 m_frame;
int m_width;
int m_height;
- IDirect3DTexture9 * m_sys_texture; // texture in system memory
- IDirect3DSurface9 * m_sys_surface; // surface in system memory
- IDirect3DTexture9 * m_vid_texture; // texture in video memory
- IDirect3DSurface9 * m_vid_surface; // surface in video memory
+ Microsoft::WRL::ComPtr<IDirect3DTexture9> m_sys_texture; // texture in system memory
+ Microsoft::WRL::ComPtr<IDirect3DSurface9> m_sys_surface; // surface in system memory
+ Microsoft::WRL::ComPtr<IDirect3DTexture9> m_vid_texture; // texture in video memory
+ Microsoft::WRL::ComPtr<IDirect3DSurface9> m_vid_surface; // surface in video memory
};
@@ -168,51 +158,32 @@ private:
//============================================================
shaders::shaders() :
- d3dintf(nullptr),
machine(nullptr),
d3d(nullptr),
post_fx_enable(false),
oversampling_enable(false),
num_screens(0),
- curr_screen(0),
+ num_targets(0),
+ curr_target(0),
acc_t(0),
delta_t(0),
shadow_texture(nullptr),
lut_texture(nullptr),
ui_lut_texture(nullptr),
options(nullptr),
- black_surface(nullptr),
- black_texture(nullptr),
recording_movie(false),
render_snap(false),
- snap_copy_target(nullptr),
- snap_copy_texture(nullptr),
- snap_target(nullptr),
- snap_texture(nullptr),
snap_width(0),
snap_height(0),
initialized(false),
- backbuffer(nullptr),
curr_effect(nullptr),
- default_effect(nullptr),
- prescale_effect(nullptr),
- post_effect(nullptr),
- distortion_effect(nullptr),
- scanline_effect(nullptr),
- focus_effect(nullptr),
- phosphor_effect(nullptr),
- deconverge_effect(nullptr),
- color_effect(nullptr),
- ntsc_effect(nullptr),
- bloom_effect(nullptr),
- downsample_effect(nullptr),
- vector_effect(nullptr),
- chroma_effect(nullptr),
+ diffuse_texture(nullptr),
curr_texture(nullptr),
curr_render_target(nullptr),
curr_poly(nullptr),
d3dx_create_effect_from_file_ptr(nullptr)
{
+ std::fill(std::begin(target_to_screen), std::end(target_to_screen), 0);
}
@@ -222,12 +193,7 @@ shaders::shaders() :
shaders::~shaders()
{
- for (slider* slider : internal_sliders)
- {
- delete slider;
- }
-
- if (options != nullptr)
+ if (options && (&last_options != options))
{
delete options;
options = nullptr;
@@ -244,11 +210,9 @@ void shaders::save_snapshot()
if (!enabled())
return;
- auto win = d3d->assert_window();
-
int width = snap_width;
int height = snap_height;
- if (win->swap_xy())
+ if (d3d->window().swap_xy())
{
std::swap(width, height);
}
@@ -289,8 +253,7 @@ void shaders::record_movie()
return;
}
- auto win = d3d->assert_window();
- osd_dim wdim = win->get_size();
+ osd_dim wdim = d3d->window().get_size();
recorder = std::make_unique<movie_recorder>(*machine, d3d, wdim.width(), wdim.height());
recorder->record(downcast<windows_options &>(machine->options()).d3d_hlsl_write());
@@ -323,11 +286,9 @@ void shaders::render_snapshot(IDirect3DSurface9 *surface)
if (!enabled())
return;
- auto win = d3d->assert_window();
-
int width = snap_width;
int height = snap_height;
- if (win->swap_xy())
+ if (d3d->window().swap_xy())
{
std::swap(width, height);
}
@@ -337,7 +298,7 @@ void shaders::render_snapshot(IDirect3DSurface9 *surface)
return;
// copy the texture
- HRESULT result = d3d->get_device()->GetRenderTargetData(surface, snap_copy_target);
+ HRESULT result = d3d->get_device()->GetRenderTargetData(surface, snap_copy_target.Get());
if (FAILED(result))
return;
@@ -378,29 +339,10 @@ void shaders::render_snapshot(IDirect3DSurface9 *surface)
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during texture UnlockRect call\n", result);
- if (snap_texture != nullptr)
- {
- snap_texture->Release();
- snap_texture = nullptr;
- }
-
- if (snap_target != nullptr)
- {
- snap_target->Release();
- snap_target = nullptr;
- }
-
- if (snap_copy_texture != nullptr)
- {
- snap_copy_texture->Release();
- snap_copy_texture = nullptr;
- }
-
- if (snap_copy_target != nullptr)
- {
- snap_copy_target->Release();
- snap_copy_target = nullptr;
- }
+ snap_texture.Reset();
+ snap_target.Reset();
+ snap_copy_texture.Reset();
+ snap_copy_target.Reset();
}
@@ -440,25 +382,33 @@ void shaders::set_texture(texture_info *texture)
return;
}
- // set initial texture to use
- texture_info *default_texture = d3d->get_default_texture();
- default_effect->set_texture("Diffuse", (texture == nullptr) ? default_texture->get_finaltex() : texture->get_finaltex());
- if (options->yiq_enable)
+ if (texture)
{
- ntsc_effect->set_texture("Diffuse", (texture == nullptr) ? default_texture->get_finaltex() : texture->get_finaltex());
+ diffuse_texture = texture;
}
else
{
- color_effect->set_texture("Diffuse", (texture == nullptr) ? default_texture->get_finaltex() : texture->get_finaltex());
+ diffuse_texture = d3d->get_default_texture();
}
}
//============================================================
+// shaders::set_filter - indicates if screens should be
+// filtered on upscaling
+//============================================================
+
+void shaders::set_filter(bool filter_screens)
+{
+ this->filter_screens = filter_screens;
+}
+
+
+//============================================================
// shaders::init
//============================================================
-bool shaders::init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *renderer)
+bool shaders::init(IDirect3D9 *d3dobj, running_machine *machine, renderer_d3d9 *renderer)
{
osd_printf_verbose("Direct3D: Initialize HLSL\n");
@@ -490,14 +440,10 @@ bool shaders::init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *r
return false;
}
- d3dintf->post_fx_available = true;
-
- this->d3dintf = d3dintf;
+ this->d3dobj = d3dobj;
this->machine = machine;
this->d3d = renderer;
- enumerate_screens();
-
auto &winoptions = downcast<windows_options &>(machine->options());
post_fx_enable = winoptions.d3d_hlsl_enable();
@@ -505,19 +451,18 @@ bool shaders::init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *r
snap_width = winoptions.d3d_snap_width();
snap_height = winoptions.d3d_snap_height();
- this->options = new hlsl_options;
- this->options->params_init = false;
-
- // copy last options if initialized
if (last_options.params_init)
{
+ // copy last options if initialized
osd_printf_verbose("Direct3D: First restore options\n");
options = &last_options;
}
-
- // read options if not initialized
- if (!options->params_init)
+ else
{
+ // read options if not initialized
+ options = new hlsl_options;
+ options->params_init = false;
+
strncpy(options->shadow_mask_texture, winoptions.screen_shadow_mask_texture(), sizeof(options->shadow_mask_texture));
options->shadow_mask_tile_mode = winoptions.screen_shadow_mask_tile_mode();
options->shadow_mask_alpha = winoptions.screen_shadow_mask_alpha();
@@ -599,6 +544,7 @@ bool shaders::init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *r
osd_printf_verbose("Direct3D: First store options\n");
last_options = *options;
+ delete options;
options = &last_options;
}
@@ -613,11 +559,70 @@ bool shaders::init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *r
//============================================================
+// shaders::begin_frame
+//
+// Enumerates the total number of screen textures present.
+//
+// Additionally, ensures the presence of necessary post-
+// processing geometry.
+//
+//============================================================
+
+void shaders::begin_frame(render_primitive_list *primlist)
+{
+ init_fsfx_quad();
+
+ std::fill(std::begin(target_to_screen), std::end(target_to_screen), 0);
+ std::fill(std::begin(targets_per_screen), std::end(targets_per_screen), 0);
+ EQUIVALENT_ARRAY(target_to_screen, render_container *) containers;
+
+ // Maximum potential runtime O(max_num_targets^2)
+ num_targets = 0;
+ num_screens = 0;
+ curr_target = 0;
+ for (render_primitive &prim : *primlist)
+ {
+ if (PRIMFLAG_GET_SCREENTEX(prim.flags))
+ {
+ int screen_index = 0;
+ for (; screen_index < num_screens && containers[screen_index] != prim.container; screen_index++);
+ containers[screen_index] = prim.container;
+ target_to_screen[num_targets] = screen_index;
+ targets_per_screen[screen_index]++;
+ if (screen_index >= num_screens)
+ num_screens++;
+ num_targets++;
+ }
+ }
+
+ diffuse_texture = d3d->get_default_texture();
+}
+
+
+//============================================================
+// shaders::end_frame
+//
+// Closes out any still-active effects at the end of
+// rendering.
+//
+//============================================================
+
+void shaders::end_frame()
+{
+ if (curr_effect->is_active())
+ {
+ curr_effect->end();
+ }
+}
+
+
+//============================================================
// shaders::init_fsfx_quad
//
// Called always at the start of each frame so that the two
// triangles used for the post-processing effects are always
-// at the beginning of the vertex buffer
+// at the beginning of the vertex buffer.
+//
//============================================================
void shaders::init_fsfx_quad()
@@ -714,7 +719,7 @@ int shaders::create_resources()
return 1;
}
black_texture->GetSurfaceLevel(0, &black_surface);
- result = d3d->get_device()->SetRenderTarget(0, black_surface);
+ result = d3d->get_device()->SetRenderTarget(0, black_surface.Get());
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call\n", result);
@@ -722,7 +727,7 @@ int shaders::create_resources()
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device clear call\n", result);
- result = d3d->get_device()->SetRenderTarget(0, backbuffer);
+ result = d3d->get_device()->SetRenderTarget(0, backbuffer.Get());
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call\n", result);
@@ -747,7 +752,7 @@ int shaders::create_resources()
texture.seqid = 0;
// now create it (no prescale, no wrap)
- auto tex = std::make_unique<texture_info>(d3d->get_texture_manager(), &texture, 1, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32));
+ auto tex = std::make_unique<texture_info>(*d3d->get_texture_manager(), &texture, 1, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32));
shadow_texture = tex.get();
d3d->get_texture_manager()->m_texture_list.push_back(std::move(tex));
}
@@ -770,7 +775,7 @@ int shaders::create_resources()
texture.seqid = 0;
// now create it (no prescale, no wrap)
- auto tex = std::make_unique<texture_info>(d3d->get_texture_manager(), &texture, 1, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32));
+ auto tex = std::make_unique<texture_info>(*d3d->get_texture_manager(), &texture, 1, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32));
lut_texture = tex.get();
d3d->get_texture_manager()->m_texture_list.push_back(std::move(tex));
}
@@ -793,74 +798,66 @@ int shaders::create_resources()
texture.seqid = 0;
// now create it (no prescale, no wrap)
- auto tex = std::make_unique<texture_info>(d3d->get_texture_manager(), &texture, 1, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32));
+ auto tex = std::make_unique<texture_info>(*d3d->get_texture_manager(), &texture, 1, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32));
ui_lut_texture = tex.get();
d3d->get_texture_manager()->m_texture_list.push_back(std::move(tex));
}
const char *fx_dir = downcast<windows_options &>(machine->options()).screen_post_fx_dir();
- default_effect = new effect(this, d3d->get_device(), "primary.fx", fx_dir);
- post_effect = new effect(this, d3d->get_device(), "post.fx", fx_dir);
- distortion_effect = new effect(this, d3d->get_device(), "distortion.fx", fx_dir);
- prescale_effect = new effect(this, d3d->get_device(), "prescale.fx", fx_dir);
- phosphor_effect = new effect(this, d3d->get_device(), "phosphor.fx", fx_dir);
- focus_effect = new effect(this, d3d->get_device(), "focus.fx", fx_dir);
- scanline_effect = new effect(this, d3d->get_device(), "scanline.fx", fx_dir);
- deconverge_effect = new effect(this, d3d->get_device(), "deconverge.fx", fx_dir);
- color_effect = new effect(this, d3d->get_device(), "color.fx", fx_dir);
- ntsc_effect = new effect(this, d3d->get_device(), "ntsc.fx", fx_dir);
- bloom_effect = new effect(this, d3d->get_device(), "bloom.fx", fx_dir);
- downsample_effect = new effect(this, d3d->get_device(), "downsample.fx", fx_dir);
- vector_effect = new effect(this, d3d->get_device(), "vector.fx", fx_dir);
- chroma_effect = new effect(this, d3d->get_device(), "chroma.fx", fx_dir);
-
- if (!default_effect->is_valid() ||
- !post_effect->is_valid() ||
- !distortion_effect->is_valid() ||
- !prescale_effect->is_valid() ||
- !phosphor_effect->is_valid() ||
- !focus_effect->is_valid() ||
- !scanline_effect->is_valid() ||
- !deconverge_effect->is_valid() ||
- !color_effect->is_valid() ||
- !ntsc_effect->is_valid() ||
- !bloom_effect->is_valid() ||
- !downsample_effect->is_valid() ||
- !vector_effect->is_valid() ||
- !chroma_effect->is_valid())
- {
- return 1;
- }
-
- std::array<effect*, 15> effects = {
- default_effect,
- post_effect,
- distortion_effect,
- prescale_effect,
- phosphor_effect,
- focus_effect,
- scanline_effect,
- deconverge_effect,
- color_effect,
- ntsc_effect,
- color_effect,
- bloom_effect,
- downsample_effect,
- vector_effect,
- chroma_effect
- };
-
- for (int i = 0; i < effects.size(); i++)
- {
- effects[i]->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS);
- effects[i]->add_uniform("TargetDims", uniform::UT_VEC2, uniform::CU_TARGET_DIMS);
- effects[i]->add_uniform("TargetScale", uniform::UT_FLOAT, uniform::CU_TARGET_SCALE);
- effects[i]->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
- effects[i]->add_uniform("ScreenCount", uniform::UT_INT, uniform::CU_SCREEN_COUNT);
- effects[i]->add_uniform("QuadDims", uniform::UT_VEC2, uniform::CU_QUAD_DIMS);
- effects[i]->add_uniform("SwapXY", uniform::UT_BOOL, uniform::CU_SWAP_XY);
- effects[i]->add_uniform("VectorScreen", uniform::UT_BOOL, uniform::CU_VECTOR_SCREEN);
+ default_effect = std::make_unique<effect>(this, d3d->get_device(), "primary.fx", fx_dir);
+ ui_effect = std::make_unique<effect>(this, d3d->get_device(), "primary.fx", fx_dir);
+ ui_wrap_effect = std::make_unique<effect>(this, d3d->get_device(), "primary.fx", fx_dir);
+ vector_buffer_effect = std::make_unique<effect>(this, d3d->get_device(), "primary.fx", fx_dir);
+ post_effect = std::make_unique<effect>(this, d3d->get_device(), "post.fx", fx_dir);
+ distortion_effect = std::make_unique<effect>(this, d3d->get_device(), "distortion.fx", fx_dir);
+ prescale_effect = std::make_unique<effect>(this, d3d->get_device(), "prescale.fx", fx_dir);
+ prescale_point_effect = std::make_unique<effect>(this, d3d->get_device(), "prescale.fx", fx_dir);
+ phosphor_effect = std::make_unique<effect>(this, d3d->get_device(), "phosphor.fx", fx_dir);
+ focus_effect = std::make_unique<effect>(this, d3d->get_device(), "focus.fx", fx_dir);
+ scanline_effect = std::make_unique<effect>(this, d3d->get_device(), "scanline.fx", fx_dir);
+ deconverge_effect = std::make_unique<effect>(this, d3d->get_device(), "deconverge.fx", fx_dir);
+ color_effect = std::make_unique<effect>(this, d3d->get_device(), "color.fx", fx_dir);
+ ntsc_effect = std::make_unique<effect>(this, d3d->get_device(), "ntsc.fx", fx_dir);
+ bloom_effect = std::make_unique<effect>(this, d3d->get_device(), "bloom.fx", fx_dir);
+ downsample_effect = std::make_unique<effect>(this, d3d->get_device(), "downsample.fx", fx_dir);
+ vector_effect = std::make_unique<effect>(this, d3d->get_device(), "vector.fx", fx_dir);
+ chroma_effect = std::make_unique<effect>(this, d3d->get_device(), "chroma.fx", fx_dir);
+
+ std::array<effect*, 18> effects = {
+ default_effect.get(),
+ ui_effect.get(),
+ ui_wrap_effect.get(),
+ vector_buffer_effect.get(),
+ post_effect.get(),
+ distortion_effect.get(),
+ prescale_effect.get(),
+ prescale_point_effect.get(),
+ phosphor_effect.get(),
+ focus_effect.get(),
+ scanline_effect.get(),
+ deconverge_effect.get(),
+ color_effect.get(),
+ ntsc_effect.get(),
+ bloom_effect.get(),
+ downsample_effect.get(),
+ vector_effect.get(),
+ chroma_effect.get() };
+
+ for (effect *eff : effects)
+ {
+ if (!eff->is_valid())
+ return 1;
+ }
+
+ for (effect *eff : effects)
+ {
+ eff->add_uniform("TargetDims", uniform::UT_VEC2, uniform::CU_TARGET_DIMS);
+ eff->add_uniform("TargetScale", uniform::UT_FLOAT, uniform::CU_TARGET_SCALE);
+ eff->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
+ eff->add_uniform("ScreenCount", uniform::UT_INT, uniform::CU_SCREEN_COUNT);
+ eff->add_uniform("SwapXY", uniform::UT_BOOL, uniform::CU_SWAP_XY);
+ eff->add_uniform("VectorScreen", uniform::UT_BOOL, uniform::CU_VECTOR_SCREEN);
}
ntsc_effect->add_uniform("CCValue", uniform::UT_FLOAT, uniform::CU_NTSC_CCFREQ);
@@ -873,6 +870,7 @@ int shaders::create_resources()
ntsc_effect->add_uniform("IFreqResponse", uniform::UT_FLOAT, uniform::CU_NTSC_IFREQ);
ntsc_effect->add_uniform("QFreqResponse", uniform::UT_FLOAT, uniform::CU_NTSC_QFREQ);
ntsc_effect->add_uniform("ScanTime", uniform::UT_FLOAT, uniform::CU_NTSC_HTIME);
+ ntsc_effect->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS);
color_effect->add_uniform("RedRatios", uniform::UT_VEC3, uniform::CU_COLOR_RED_RATIOS);
color_effect->add_uniform("GrnRatios", uniform::UT_VEC3, uniform::CU_COLOR_GRN_RATIOS);
@@ -880,6 +878,8 @@ int shaders::create_resources()
color_effect->add_uniform("Offset", uniform::UT_VEC3, uniform::CU_COLOR_OFFSET);
color_effect->add_uniform("Scale", uniform::UT_VEC3, uniform::CU_COLOR_SCALE);
color_effect->add_uniform("Saturation", uniform::UT_FLOAT, uniform::CU_COLOR_SATURATION);
+ color_effect->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS);
+ color_effect->add_uniform("LutEnable", uniform::UT_BOOL, uniform::CU_LUT_ENABLE);
deconverge_effect->add_uniform("ConvergeX", uniform::UT_VEC3, uniform::CU_CONVERGE_LINEAR_X);
deconverge_effect->add_uniform("ConvergeY", uniform::UT_VEC3, uniform::CU_CONVERGE_LINEAR_Y);
@@ -892,6 +892,8 @@ int shaders::create_resources()
scanline_effect->add_uniform("ScanlineVariation", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_VARIATION);
scanline_effect->add_uniform("ScanlineBrightScale", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_BRIGHT_SCALE);
scanline_effect->add_uniform("ScanlineBrightOffset", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_BRIGHT_OFFSET);
+ scanline_effect->add_uniform("QuadDims", uniform::UT_VEC2, uniform::CU_QUAD_DIMS);
+ scanline_effect->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS);
focus_effect->add_uniform("Defocus", uniform::UT_VEC2, uniform::CU_FOCUS_SIZE);
@@ -904,9 +906,15 @@ int shaders::create_resources()
post_effect->add_uniform("Floor", uniform::UT_VEC3, uniform::CU_POST_FLOOR);
post_effect->add_uniform("ChomaMode", uniform::UT_INT, uniform::CU_CHROMA_MODE);
post_effect->add_uniform("ConversionGain", uniform::UT_VEC3, uniform::CU_CHROMA_CONVERSION_GAIN);
+ post_effect->add_uniform("QuadDims", uniform::UT_VEC2, uniform::CU_QUAD_DIMS);
+ post_effect->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS);
phosphor_effect->add_uniform("Phosphor", uniform::UT_VEC3, uniform::CU_PHOSPHOR_LIFE);
+ bloom_effect->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS);
+
+ downsample_effect->add_uniform("QuadDims", uniform::UT_VEC2, uniform::CU_QUAD_DIMS);
+
chroma_effect->add_uniform("YGain", uniform::UT_VEC3, uniform::CU_CHROMA_Y_GAIN);
chroma_effect->add_uniform("ChromaA", uniform::UT_VEC2, uniform::CU_CHROMA_A);
chroma_effect->add_uniform("ChromaB", uniform::UT_VEC2, uniform::CU_CHROMA_B);
@@ -919,9 +927,19 @@ int shaders::create_resources()
distortion_effect->add_uniform("RoundCornerAmount", uniform::UT_FLOAT, uniform::CU_POST_ROUND_CORNER);
distortion_effect->add_uniform("SmoothBorderAmount", uniform::UT_FLOAT, uniform::CU_POST_SMOOTH_BORDER);
distortion_effect->add_uniform("ReflectionAmount", uniform::UT_FLOAT, uniform::CU_POST_REFLECTION);
+ distortion_effect->add_uniform("QuadDims", uniform::UT_VEC2, uniform::CU_QUAD_DIMS);
+
+ prescale_effect->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS);
+
+ prescale_point_effect->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS);
- default_effect->add_uniform("LutEnable", uniform::UT_BOOL, uniform::CU_LUT_ENABLE);
- default_effect->add_uniform("UiLutEnable", uniform::UT_BOOL, uniform::CU_UI_LUT_ENABLE);
+ ui_effect->add_uniform("LutEnable", uniform::UT_BOOL, uniform::CU_LUT_ENABLE);
+ ui_effect->add_uniform("UiLutEnable", uniform::UT_BOOL, uniform::CU_UI_LUT_ENABLE);
+
+ ui_wrap_effect->add_uniform("LutEnable", uniform::UT_BOOL, uniform::CU_LUT_ENABLE);
+ ui_wrap_effect->add_uniform("UiLutEnable", uniform::UT_BOOL, uniform::CU_UI_LUT_ENABLE);
+
+ vector_buffer_effect->add_uniform("LutEnable", uniform::UT_BOOL, uniform::CU_LUT_ENABLE);
return 0;
}
@@ -933,24 +951,24 @@ int shaders::create_resources()
void shaders::begin_draw()
{
- double t;
-
if (!enabled())
- {
return;
- }
- curr_screen = 0;
- curr_effect = default_effect;
+ curr_target = 0;
+
// Update for delta_time
- t = machine->time().as_double();
+ const double t = machine->time().as_double();
delta_t = t - acc_t;
acc_t = t;
default_effect->set_technique("ScreenTechnique");
+ ui_effect->set_technique("UiTechnique");
+ ui_wrap_effect->set_technique("UiWrapTechnique");
+ vector_buffer_effect->set_technique("VectorBufferTechnique");
post_effect->set_technique("DefaultTechnique");
distortion_effect->set_technique("DefaultTechnique");
prescale_effect->set_technique("DefaultTechnique");
+ prescale_point_effect->set_technique("PointTechnique");
phosphor_effect->set_technique("DefaultTechnique");
focus_effect->set_technique("DefaultTechnique");
scanline_effect->set_technique("DefaultTechnique");
@@ -963,11 +981,31 @@ void shaders::begin_draw()
vector_effect->set_technique("DefaultTechnique");
chroma_effect->set_technique("DefaultTechnique");
- HRESULT result = d3d->get_device()->SetRenderTarget(0, backbuffer);
+ HRESULT result = d3d->get_device()->SetRenderTarget(0, backbuffer.Get());
if (FAILED(result))
{
osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call\n", result);
}
+
+ set_curr_effect(default_effect.get());
+}
+
+
+//============================================================
+// shaders::set_curr_effect
+//============================================================
+
+void shaders::set_curr_effect(effect *curr_effect)
+{
+ if (this->curr_effect == curr_effect)
+ {
+ return;
+ }
+ if (this->curr_effect && this->curr_effect->is_active())
+ {
+ this->curr_effect->end();
+ }
+ this->curr_effect = curr_effect;
}
@@ -994,7 +1032,7 @@ void shaders::blit(
if (clear_dst)
{
- result = d3d->get_device()->Clear(0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_ARGB(1,0,0,0), 0, 0);
+ result = d3d->get_device()->Clear(0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0xff,0,0,0), 0, 0);
if (FAILED(result))
{
osd_printf_verbose("Direct3D: Error %08lX during device clear call\n", result);
@@ -1002,24 +1040,17 @@ void shaders::blit(
}
}
- UINT num_passes = 0;
- curr_effect->begin(&num_passes, 0);
-
- for (UINT pass = 0; pass < num_passes; pass++)
+ if (!curr_effect->is_active())
{
- curr_effect->begin_pass(pass);
-
- // add the primitives
- result = d3d->get_device()->DrawPrimitive(prim_type, prim_index, prim_count);
- if (FAILED(result))
- {
- osd_printf_verbose("Direct3D: Error %08lX during device DrawPrimitive call\n", result);
- }
-
- curr_effect->end_pass();
+ curr_effect->begin(0);
}
- curr_effect->end();
+ // add the primitives
+ result = d3d->get_device()->DrawPrimitive(prim_type, prim_index, prim_count);
+ if (FAILED(result))
+ {
+ osd_printf_verbose("Direct3D: Error %08lX during device DrawPrimitive call\n", result);
+ }
}
//============================================================
@@ -1056,14 +1087,15 @@ int shaders::ntsc_pass(d3d_render_target *rt, int source_index, poly_info *poly,
// initial "Diffuse" texture is set in shaders::set_texture()
- curr_effect = ntsc_effect;
+ set_curr_effect(ntsc_effect.get());
+ curr_effect->set_texture("Diffuse", diffuse_texture->get_finaltex());
curr_effect->update_uniforms();
curr_effect->set_float("SignalOffset", signal_offset);
next_index = rt->next_index(next_index);
- blit(rt->source_surface[next_index], false, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->source_surface[next_index].Get(), false, D3DPT_TRIANGLELIST, 0, 2);
- color_effect->set_texture("Diffuse", rt->source_texture[next_index]);
+ color_effect->set_texture("Diffuse", rt->source_texture[next_index].Get());
return next_index;
}
@@ -1112,13 +1144,23 @@ int shaders::color_convolution_pass(d3d_render_target *rt, int source_index, pol
{
int next_index = source_index;
- curr_effect = color_effect;
- curr_effect->update_uniforms();
+ set_curr_effect(color_effect.get());
- // initial "Diffuse" texture is set in shaders::set_texture() or the result of shaders::ntsc_pass()
+ // initial "Diffuse" texture is set in shaders::ntsc_pass() if NTSC processing is enabled
+ if (!options->yiq_enable)
+ {
+ curr_effect->set_texture("Diffuse", diffuse_texture->get_finaltex());
+ }
+
+ curr_effect->update_uniforms();
+ uint32_t tint = (uint32_t)poly->tint();
+ float prim_tint[3] = { ((tint >> 16) & 0xff) / 255.0f, ((tint >> 8) & 0xff) / 255.0f, (tint & 0xff) / 255.0f };
+ curr_effect->set_vector("PrimTint", 3, prim_tint);
+ curr_effect->set_texture("LutTexture", !lut_texture ? nullptr : lut_texture->get_finaltex());
+ curr_effect->set_bool("UiLutEnable", false);
next_index = rt->next_index(next_index);
- blit(rt->source_surface[next_index], false, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->source_surface[next_index].Get(), false, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1127,12 +1169,12 @@ int shaders::prescale_pass(d3d_render_target *rt, int source_index, poly_info *p
{
int next_index = source_index;
- curr_effect = prescale_effect;
+ set_curr_effect(filter_screens ? prescale_effect.get() : prescale_point_effect.get());
curr_effect->update_uniforms();
- curr_effect->set_texture("Diffuse", rt->source_texture[next_index]);
+ curr_effect->set_texture("Diffuse", rt->source_texture[next_index].Get());
next_index = rt->next_index(next_index);
- blit(rt->target_surface[next_index], false, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->target_surface[next_index].Get(), false, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1150,12 +1192,12 @@ int shaders::deconverge_pass(d3d_render_target *rt, int source_index, poly_info
return next_index;
}
- curr_effect = deconverge_effect;
+ set_curr_effect(deconverge_effect.get());
curr_effect->update_uniforms();
- curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
+ curr_effect->set_texture("Diffuse", rt->target_texture[next_index].Get());
next_index = rt->next_index(next_index);
- blit(rt->target_surface[next_index], false, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->target_surface[next_index].Get(), false, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1165,12 +1207,11 @@ int shaders::scanline_pass(d3d_render_target *rt, int source_index, poly_info *p
int next_index = source_index;
// skip scanline if alpha is 0
- if (options->scanline_alpha == 0.0f)
- return next_index;
+ //if (options->scanline_alpha == 0.0f)
+ //return next_index;
- auto win = d3d->assert_window();
screen_device_enumerator screen_iterator(machine->root_device());
- screen_device *screen = screen_iterator.byindex(curr_screen);
+ screen_device *screen = screen_iterator.byindex(target_to_screen[curr_target]);
render_container &screen_container = screen->container();
float xscale = 1.0f / screen_container.xscale();
float yscale = 1.0f / screen_container.yscale();
@@ -1179,16 +1220,16 @@ int shaders::scanline_pass(d3d_render_target *rt, int source_index, poly_info *p
float screen_scale[] = { xscale, yscale };
float screen_offset[] = { xoffset, yoffset };
- curr_effect = scanline_effect;
+ set_curr_effect(scanline_effect.get());
curr_effect->update_uniforms();
- curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
+ curr_effect->set_texture("Diffuse", rt->target_texture[next_index].Get());
curr_effect->set_vector("ScreenScale", 2, screen_scale);
curr_effect->set_vector("ScreenOffset", 2, screen_offset);
curr_effect->set_float("ScanlineOffset",
curr_texture->get_cur_frame() == 0 ?
0.0f : options->scanline_jitter);
next_index = rt->next_index(next_index);
- blit(rt->target_surface[next_index], false, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->target_surface[next_index].Get(), false, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1202,12 +1243,12 @@ int shaders::defocus_pass(d3d_render_target *rt, int source_index, poly_info *po
return next_index;
}
- curr_effect = focus_effect;
+ set_curr_effect(focus_effect.get());
curr_effect->update_uniforms();
- curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
+ curr_effect->set_texture("Diffuse", rt->target_texture[next_index].Get());
next_index = rt->next_index(next_index);
- blit(rt->target_surface[next_index], false, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->target_surface[next_index].Get(), false, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1223,23 +1264,23 @@ int shaders::phosphor_pass(d3d_render_target *rt, int source_index, poly_info *p
}
// Shader needs time between last update
- curr_effect = phosphor_effect;
+ set_curr_effect(phosphor_effect.get());
curr_effect->update_uniforms();
- curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
- curr_effect->set_texture("LastPass", rt->cache_texture);
+ curr_effect->set_texture("Diffuse", rt->target_texture[next_index].Get());
+ curr_effect->set_texture("LastPass", rt->cache_texture.Get());
curr_effect->set_bool("Passthrough", false);
curr_effect->set_float("DeltaTime", delta_time());
next_index = rt->next_index(next_index);
- blit(rt->target_surface[next_index], false, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->target_surface[next_index].Get(), false, D3DPT_TRIANGLELIST, 0, 2);
// Pass along our phosphor'd screen
curr_effect->update_uniforms();
- curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
- curr_effect->set_texture("LastPass", rt->target_texture[next_index]);
+ curr_effect->set_texture("Diffuse", rt->target_texture[next_index].Get());
+ curr_effect->set_texture("LastPass", rt->target_texture[next_index].Get());
curr_effect->set_bool("Passthrough", true);
- blit(rt->cache_surface, false, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->cache_surface.Get(), false, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1248,10 +1289,8 @@ int shaders::post_pass(d3d_render_target *rt, int source_index, poly_info *poly,
{
int next_index = source_index;
- auto win = d3d->assert_window();
-
screen_device_enumerator screen_iterator(machine->root_device());
- screen_device *screen = screen_iterator.byindex(curr_screen);
+ screen_device *screen = screen_iterator.byindex(target_to_screen[curr_target]);
render_container &screen_container = screen->container();
float xscale = 1.0f / screen_container.xscale();
@@ -1270,11 +1309,11 @@ int shaders::post_pass(d3d_render_target *rt, int source_index, poly_info *poly,
float(back_color_rgb.g()) / 255.0f,
float(back_color_rgb.b()) / 255.0f };
- curr_effect = post_effect;
+ set_curr_effect(post_effect.get());
curr_effect->update_uniforms();
- curr_effect->set_texture("ShadowTexture", shadow_texture == nullptr ? nullptr : shadow_texture->get_finaltex());
+ curr_effect->set_texture("ShadowTexture", !shadow_texture ? nullptr : shadow_texture->get_finaltex());
curr_effect->set_int("ShadowTileMode", options->shadow_mask_tile_mode);
- curr_effect->set_texture("DiffuseTexture", rt->target_texture[next_index]);
+ curr_effect->set_texture("DiffuseTexture", rt->target_texture[next_index].Get());
curr_effect->set_vector("BackColor", 3, back_color);
curr_effect->set_vector("ScreenScale", 2, screen_scale);
curr_effect->set_vector("ScreenOffset", 2, screen_offset);
@@ -1283,7 +1322,7 @@ int shaders::post_pass(d3d_render_target *rt, int source_index, poly_info *poly,
curr_effect->set_bool("PrepareBloom", prepare_bloom);
next_index = rt->next_index(next_index);
- blit(prepare_bloom ? rt->source_surface[next_index] : rt->target_surface[next_index], false, D3DPT_TRIANGLELIST, 0, 2);
+ blit(prepare_bloom ? rt->source_surface[next_index].Get() : rt->target_surface[next_index].Get(), false, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1292,11 +1331,11 @@ int shaders::chroma_pass(d3d_render_target *rt, int source_index, poly_info *pol
{
int next_index = source_index;
- curr_effect = chroma_effect;
+ set_curr_effect(chroma_effect.get());
curr_effect->update_uniforms();
- curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
+ curr_effect->set_texture("Diffuse", rt->target_texture[next_index].Get());
next_index = rt->next_index(next_index);
- blit(rt->target_surface[next_index], false, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->target_surface[next_index].Get(), false, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1310,18 +1349,19 @@ int shaders::downsample_pass(d3d_render_target *rt, int source_index, poly_info
return next_index;
}
- curr_effect = downsample_effect;
- curr_effect->update_uniforms();
+ set_curr_effect(downsample_effect.get());
for (int bloom_index = 0; bloom_index < rt->bloom_count; bloom_index++)
{
+ curr_effect->update_uniforms();
curr_effect->set_vector("TargetDims", 2, rt->bloom_dims[bloom_index]);
curr_effect->set_texture("DiffuseTexture",
bloom_index == 0
- ? rt->source_texture[next_index]
- : rt->bloom_texture[bloom_index - 1]);
+ ? rt->source_texture[next_index].Get()
+ : rt->bloom_texture[bloom_index - 1].Get());
- blit(rt->bloom_surface[bloom_index], false, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->bloom_surface[bloom_index].Get(), false, D3DPT_TRIANGLELIST, 0, 2);
+ downsample_effect->end();
}
return next_index;
@@ -1337,7 +1377,7 @@ int shaders::bloom_pass(d3d_render_target *rt, int source_index, poly_info *poly
return next_index;
}
- curr_effect = bloom_effect;
+ set_curr_effect(bloom_effect.get());
curr_effect->update_uniforms();
curr_effect->set_float("Level0Weight", options->bloom_level0_weight);
@@ -1354,22 +1394,22 @@ int shaders::bloom_pass(d3d_render_target *rt, int source_index, poly_info *poly
curr_effect->set_float("BloomScale", options->bloom_scale);
curr_effect->set_vector("BloomOverdrive", 3, options->bloom_overdrive);
- curr_effect->set_texture("DiffuseTexture", rt->target_texture[next_index]);
+ curr_effect->set_texture("DiffuseTexture", rt->target_texture[next_index].Get());
char name[14] = "BloomTexture*";
for (int index = 1; index < rt->bloom_count; index++)
{
name[12] = 'A' + index - 1;
- curr_effect->set_texture(name, rt->bloom_texture[index - 1]);
+ curr_effect->set_texture(name, rt->bloom_texture[index - 1].Get());
}
for (int index = rt->bloom_count; index < MAX_BLOOM_COUNT; index++)
{
name[12] = 'A' + index - 1;
- curr_effect->set_texture(name, black_texture);
+ curr_effect->set_texture(name, black_texture.Get());
}
next_index = rt->next_index(next_index);
- blit(rt->target_surface[next_index], false, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->target_surface[next_index].Get(), false, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1390,12 +1430,12 @@ int shaders::distortion_pass(d3d_render_target *rt, int source_index, poly_info
return next_index;
}
- curr_effect = distortion_effect;
+ set_curr_effect(distortion_effect.get());
curr_effect->update_uniforms();
- curr_effect->set_texture("DiffuseTexture", rt->target_texture[next_index]);
+ curr_effect->set_texture("DiffuseTexture", rt->target_texture[next_index].Get());
next_index = rt->next_index(next_index);
- blit(rt->target_surface[next_index], false, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->target_surface[next_index].Get(), false, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1404,14 +1444,14 @@ int shaders::vector_pass(d3d_render_target *rt, int source_index, poly_info *pol
{
int next_index = source_index;
- curr_effect = vector_effect;
+ set_curr_effect(vector_effect.get());
curr_effect->update_uniforms();
curr_effect->set_float("LengthRatio", options->vector_length_ratio);
curr_effect->set_float("LengthScale", options->vector_length_scale);
curr_effect->set_float("BeamSmooth", options->vector_beam_smooth);
// we need to clear the vector render target here
- blit(rt->target_surface[next_index], true, poly->type(), vertnum, poly->count());
+ blit(rt->target_surface[next_index].Get(), true, poly->type(), vertnum, poly->count());
return next_index;
}
@@ -1420,17 +1460,17 @@ int shaders::vector_buffer_pass(d3d_render_target *rt, int source_index, poly_in
{
int next_index = source_index;
- curr_effect = default_effect;
+ set_curr_effect(vector_buffer_effect.get());
+ curr_effect->set_texture("Diffuse", diffuse_texture->get_finaltex());
curr_effect->update_uniforms();
- curr_effect->set_technique("VectorBufferTechnique");
-
- curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
- curr_effect->set_texture("LutTexture", lut_texture == nullptr ? nullptr : lut_texture->get_finaltex());
+ curr_effect->set_texture("Diffuse", rt->target_texture[next_index].Get());
+ curr_effect->set_texture("LutTexture", !lut_texture ? nullptr : lut_texture->get_finaltex());
+ curr_effect->set_bool("UiLutEnable", false);
// we need to clear the vector render target here
next_index = rt->next_index(next_index);
- blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->target_surface[next_index].Get(), true, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1441,14 +1481,16 @@ int shaders::screen_pass(d3d_render_target *rt, int source_index, poly_info *pol
d3d->set_blendmode(PRIMFLAG_GET_BLENDMODE(poly->flags()));
- curr_effect = default_effect;
+ set_curr_effect(default_effect.get());
+ curr_effect->set_texture("Diffuse", diffuse_texture->get_finaltex());
curr_effect->update_uniforms();
- curr_effect->set_technique("ScreenTechnique");
- curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
- curr_effect->set_texture("LutTexture", lut_texture == nullptr ? nullptr : lut_texture->get_finaltex());
+ curr_effect->set_texture("Diffuse", rt->target_texture[next_index].Get());
+ curr_effect->set_texture("LutTexture", nullptr);
+ curr_effect->set_bool("LutEnable", false);
+ curr_effect->set_bool("UiLutEnable", false);
- blit(backbuffer, false, poly->type(), vertnum, poly->count());
+ blit(backbuffer.Get(), false, poly->type(), vertnum, poly->count());
if (recording_movie)
{
@@ -1460,9 +1502,9 @@ int shaders::screen_pass(d3d_render_target *rt, int source_index, poly_info *pol
if (render_snap)
{
// we need to clear the snap render target here
- blit(snap_target, true, poly->type(), vertnum, poly->count());
+ blit(snap_target.Get(), true, poly->type(), vertnum, poly->count());
- render_snapshot(snap_target);
+ render_snapshot(snap_target.Get());
render_snap = false;
}
@@ -1474,11 +1516,11 @@ void shaders::ui_pass(poly_info *poly, int vertnum)
{
d3d->set_blendmode(PRIMFLAG_GET_BLENDMODE(poly->flags()));
- curr_effect = default_effect;
+ set_curr_effect(PRIMFLAG_GET_TEXWRAP(poly->flags()) ? ui_wrap_effect.get() : ui_effect.get());
+ curr_effect->set_texture("Diffuse", diffuse_texture->get_finaltex());
curr_effect->update_uniforms();
- curr_effect->set_technique("UiTechnique");
- curr_effect->set_texture("LutTexture", lut_texture == nullptr ? nullptr : ui_lut_texture->get_finaltex());
+ curr_effect->set_texture("LutTexture", !lut_texture ? nullptr : ui_lut_texture->get_finaltex());
blit(nullptr, false, poly->type(), vertnum, poly->count());
}
@@ -1498,8 +1540,6 @@ void shaders::render_quad(poly_info *poly, int vertnum)
curr_texture = poly->texture();
curr_poly = poly;
- auto win = d3d->assert_window();
-
if (PRIMFLAG_GET_SCREENTEX(poly->flags()))
{
if (curr_texture == nullptr)
@@ -1508,9 +1548,9 @@ void shaders::render_quad(poly_info *poly, int vertnum)
return;
}
- curr_screen = curr_screen < num_screens ? curr_screen : 0;
+ curr_target = curr_target < num_targets ? curr_target : 0;
- curr_render_target = find_render_target(curr_texture->get_width(), curr_texture->get_height(), curr_screen);
+ curr_render_target = find_render_target(curr_texture->get_width(), curr_texture->get_height(), curr_target);
d3d_render_target *rt = curr_render_target;
if (rt == nullptr)
@@ -1530,12 +1570,16 @@ void shaders::render_quad(poly_info *poly, int vertnum)
//next_index = phosphor_pass(rt, next_index, poly, vertnum);
// create bloom textures
- int old_index = next_index;
- next_index = post_pass(rt, next_index, poly, vertnum, true);
- next_index = downsample_pass(rt, next_index, poly, vertnum);
+ bool bloom_enabled = (options->bloom_scale > 0.0f);
+ if (bloom_enabled)
+ {
+ int old_index = next_index;
+ next_index = post_pass(rt, next_index, poly, vertnum, true);
+ next_index = downsample_pass(rt, next_index, poly, vertnum);
+ next_index = old_index;
+ }
- // apply bloom textures
- next_index = old_index;
+ // apply bloom textures (if enabled) and other post effects
next_index = post_pass(rt, next_index, poly, vertnum, false);
next_index = bloom_pass(rt, next_index, poly, vertnum);
next_index = phosphor_pass(rt, next_index, poly, vertnum);
@@ -1551,19 +1595,19 @@ void shaders::render_quad(poly_info *poly, int vertnum)
curr_texture->increment_frame_count();
curr_texture->mask_frame_count(options->yiq_phase_count);
- curr_screen++;
+ curr_target++;
}
else if (PRIMFLAG_GET_VECTOR(poly->flags()))
{
- curr_screen = curr_screen < num_screens ? curr_screen : 0;
+ curr_target = curr_target < num_targets ? curr_target : 0;
int source_width = int(poly->prim_width() + 0.5f);
int source_height = int(poly->prim_height() + 0.5f);
- if (win->swap_xy())
+ if (d3d->window().swap_xy())
{
std::swap(source_width, source_height);
}
- curr_render_target = find_render_target(source_width, source_height, curr_screen);
+ curr_render_target = find_render_target(source_width, source_height, curr_target);
d3d_render_target *rt = curr_render_target;
if (rt == nullptr)
@@ -1576,25 +1620,25 @@ void shaders::render_quad(poly_info *poly, int vertnum)
next_index = vector_pass(rt, next_index, poly, vertnum);
- HRESULT result = d3d->get_device()->SetRenderTarget(0, backbuffer);
+ HRESULT result = d3d->get_device()->SetRenderTarget(0, backbuffer.Get());
if (FAILED(result))
{
osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call\n", result);
}
- curr_screen++;
+ curr_target++;
}
else if (PRIMFLAG_GET_VECTORBUF(poly->flags()))
{
- curr_screen = curr_screen < num_screens ? curr_screen : 0;
+ curr_target = curr_target < num_targets ? curr_target : 0;
int source_width = int(poly->prim_width() + 0.5f);
int source_height = int(poly->prim_height() + 0.5f);
- if (win->swap_xy())
+ if (d3d->window().swap_xy())
{
std::swap(source_width, source_height);
}
- curr_render_target = find_render_target(source_width, source_height, curr_screen);
+ curr_render_target = find_render_target(source_width, source_height, curr_target);
d3d_render_target *rt = curr_render_target;
if (rt == nullptr)
@@ -1629,7 +1673,7 @@ void shaders::render_quad(poly_info *poly, int vertnum)
next_index = screen_pass(rt, next_index, poly, vertnum);
d3d->set_wrap(PRIMFLAG_GET_TEXWRAP(curr_texture->get_flags()) ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP);
- curr_screen++;
+ curr_target++;
}
else
{
@@ -1655,7 +1699,7 @@ void shaders::end_draw()
return;
}
- backbuffer->Release();
+ backbuffer->Release(); // TODO: where's the matching AddRef that requires this explicit Release?
}
@@ -1670,8 +1714,6 @@ d3d_render_target* shaders::get_texture_target(render_primitive *prim, int width
return nullptr;
}
- auto win = d3d->assert_window();
-
int source_width = width;
int source_height = height;
int source_screen = screen;
@@ -1679,7 +1721,7 @@ d3d_render_target* shaders::get_texture_target(render_primitive *prim, int width
int target_height = int(prim->get_full_quad_height() + 0.5f);
target_width *= oversampling_enable ? 2 : 1;
target_height *= oversampling_enable ? 2 : 1;
- if (win->swap_xy())
+ if (d3d->window().swap_xy())
{
std::swap(target_width, target_height);
}
@@ -1710,8 +1752,6 @@ d3d_render_target* shaders::get_vector_target(render_primitive *prim, int screen
return nullptr;
}
- auto win = d3d->assert_window();
-
int source_width = int(prim->get_quad_width() + 0.5f);
int source_height = int(prim->get_quad_height() + 0.5f);
int source_screen = screen;
@@ -1719,7 +1759,7 @@ d3d_render_target* shaders::get_vector_target(render_primitive *prim, int screen
int target_height = int(prim->get_full_quad_height() + 0.5f);
target_width *= oversampling_enable ? 2 : 1;
target_height *= oversampling_enable ? 2 : 1;
- if (win->swap_xy())
+ if (d3d->window().swap_xy())
{
std::swap(source_width, source_height);
std::swap(target_width, target_height);
@@ -1751,8 +1791,6 @@ bool shaders::create_vector_target(render_primitive *prim, int screen)
return false;
}
- auto win = d3d->assert_window();
-
int source_width = int(prim->get_quad_width() + 0.5f);
int source_height = int(prim->get_quad_height() + 0.5f);
int source_screen = screen;
@@ -1760,7 +1798,7 @@ bool shaders::create_vector_target(render_primitive *prim, int screen)
int target_height = int(prim->get_full_quad_height() + 0.5f);
target_width *= oversampling_enable ? 2 : 1;
target_height *= oversampling_enable ? 2 : 1;
- if (win->swap_xy())
+ if (d3d->window().swap_xy())
{
std::swap(source_width, source_height);
std::swap(target_width, target_height);
@@ -1796,16 +1834,6 @@ bool shaders::add_render_target(renderer_d3d9* d3d, render_primitive *prim, int
//============================================================
-// shaders::enumerate_screens
-//============================================================
-void shaders::enumerate_screens()
-{
- screen_device_enumerator iter(machine->root_device());
- num_screens = iter.count();
-}
-
-
-//============================================================
// shaders::create_texture_target
//============================================================
@@ -1816,8 +1844,6 @@ bool shaders::create_texture_target(render_primitive *prim, int width, int heigh
return false;
}
- auto win = d3d->assert_window();
-
int source_width = width;
int source_height = height;
int source_screen = screen;
@@ -1825,7 +1851,7 @@ bool shaders::create_texture_target(render_primitive *prim, int width, int heigh
int target_height = int(prim->get_full_quad_height() + 0.5f);
target_width *= oversampling_enable ? 2 : 1;
target_height *= oversampling_enable ? 2 : 1;
- if (win->swap_xy())
+ if (d3d->window().swap_xy())
{
// source texture is already swapped
std::swap(target_width, target_height);
@@ -1863,93 +1889,29 @@ void shaders::delete_resources()
m_render_target_list.clear();
- if (downsample_effect != nullptr)
- {
- delete downsample_effect;
- downsample_effect = nullptr;
- }
- if (bloom_effect != nullptr)
- {
- delete bloom_effect;
- bloom_effect = nullptr;
- }
- if (vector_effect != nullptr)
- {
- delete vector_effect;
- vector_effect = nullptr;
- }
- if (default_effect != nullptr)
- {
- delete default_effect;
- default_effect = nullptr;
- }
- if (post_effect != nullptr)
- {
- delete post_effect;
- post_effect = nullptr;
- }
- if (distortion_effect != nullptr)
- {
- delete distortion_effect;
- distortion_effect = nullptr;
- }
- if (prescale_effect != nullptr)
- {
- delete prescale_effect;
- prescale_effect = nullptr;
- }
- if (phosphor_effect != nullptr)
- {
- delete phosphor_effect;
- phosphor_effect = nullptr;
- }
- if (focus_effect != nullptr)
- {
- delete focus_effect;
- focus_effect = nullptr;
- }
- if (scanline_effect != nullptr)
- {
- delete scanline_effect;
- scanline_effect = nullptr;
- }
- if (deconverge_effect != nullptr)
- {
- delete deconverge_effect;
- deconverge_effect = nullptr;
- }
- if (color_effect != nullptr)
- {
- delete color_effect;
- color_effect = nullptr;
- }
- if (ntsc_effect != nullptr)
- {
- delete ntsc_effect;
- ntsc_effect = nullptr;
- }
- if (chroma_effect != nullptr)
- {
- delete chroma_effect;
- chroma_effect = nullptr;
- }
-
- if (backbuffer != nullptr)
- {
- backbuffer->Release();
- backbuffer = nullptr;
- }
-
- if (black_surface != nullptr)
- {
- black_surface->Release();
- black_surface = nullptr;
- }
- if (black_texture != nullptr)
- {
- black_texture->Release();
- black_texture = nullptr;
- }
+ downsample_effect.reset();
+ bloom_effect.reset();
+ vector_effect.reset();
+ default_effect.reset();
+ ui_effect.reset();
+ ui_wrap_effect.reset();
+ vector_buffer_effect.reset();
+ post_effect.reset();
+ distortion_effect.reset();
+ prescale_effect.reset();
+ prescale_point_effect.reset();
+ phosphor_effect.reset();
+ focus_effect.reset();
+ scanline_effect.reset();
+ deconverge_effect.reset();
+ color_effect.reset();
+ ntsc_effect.reset();
+ chroma_effect.reset();
+
+ backbuffer.Reset();
+
+ black_surface.Reset();
+ black_texture.Reset();
shadow_bitmap.reset();
lut_bitmap.reset();
@@ -2060,7 +2022,7 @@ int32_t slider::update(std::string *str, int32_t newval)
return 0;
}
-char shaders::last_system_name[16];
+char shaders::last_system_name[MAX_DRIVER_NAME_CHARS + 1];
hlsl_options shaders::last_options = { false };
@@ -2215,13 +2177,13 @@ slider_desc shaders::s_sliders[] =
{ "NTSC Frame Jitter Offset", 0, 0, 100, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_NTSC_JITTER, 0.01f, "%1.2f", {} },
{ "NTSC A Value", -100, 50, 100, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_NTSC_A_VALUE, 0.01f, "%1.2f", {} },
{ "NTSC B Value", -100, 50, 100, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_NTSC_B_VALUE, 0.01f, "%1.2f", {} },
- { "NTSC Incoming Phase Pixel Clock Scale",-300, 100, 300, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_NTSC_P_VALUE, 0.01f, "%1.2f", {} },
- { "NTSC Outgoing Phase Offset", -300, 0, 300, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_NTSC_O_VALUE, 0.01f, "%1.2f", {} },
- { "NTSC Color Carrier (Hz)", 0, 35795, 60000, 5, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_NTSC_CC_VALUE, 0.001f, "%1.4f", {} },
- { "NTSC Color Notch Filter Width", 0, 100, 600, 5, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_NTSC_N_VALUE, 0.01f, "%1.4f", {} },
- { "NTSC Y Signal Bandwidth (Hz)", 0, 600, 600, 5, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_NTSC_Y_VALUE, 0.01f, "%1.4f", {} },
- { "NTSC I Signal Bandwidth (Hz)", 0, 120, 600, 5, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_NTSC_I_VALUE, 0.01f, "%1.4f", {} },
- { "NTSC Q Signal Bandwidth (Hz)", 0, 60, 600, 5, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_NTSC_Q_VALUE, 0.01f, "%1.4f", {} },
+ { "NTSC Incoming Phase Pixel Clock Scale",-300,100, 300, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_NTSC_P_VALUE, 0.01f, "%1.2f", {} },
+ { "NTSC Outgoing Phase Offset (radians)",-314, 0, 314, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_NTSC_O_VALUE, 0.01f, "%1.2f", {} },
+ { "NTSC Color Carrier (MHz)", 0, 31500,6*8800, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_NTSC_CC_VALUE, 1/8800.f, "%1.5f", {} },
+ { "NTSC Color Notch Filter Width (MHz)",0, 100, 600, 5, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_NTSC_N_VALUE, 0.01f, "%1.2f", {} },
+ { "NTSC Y Signal Bandwidth (MHz)", 0, 600, 2100, 5, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_NTSC_Y_VALUE, 0.01f, "%1.2f", {} },
+ { "NTSC I Signal Bandwidth (MHz)", 0, 120, 2100, 5, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_NTSC_I_VALUE, 0.01f, "%1.2f", {} },
+ { "NTSC Q Signal Bandwidth (MHz)", 0, 60, 2100, 5, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_NTSC_Q_VALUE, 0.01f, "%1.2f", {} },
{ "NTSC Scanline Duration (uSec)", 0, 5260, 10000, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_NTSC_SCAN_TIME, 0.01f, "%1.2f", {} },
{ "3D LUT (Screen)", 0, 0, 1, 1, SLIDER_INT_ENUM, SLIDER_SCREEN_TYPE_ANY, SLIDER_LUT_ENABLE, 0, "%s", { "Off", "On" } },
{ nullptr, 0, 0, 0, 0, 0, 0, -1, 0, nullptr, {} }
@@ -2313,10 +2275,6 @@ void shaders::init_slider_list()
m_sliders.clear();
m_core_sliders.clear();
- for (slider* slider : internal_sliders)
- {
- delete slider;
- }
internal_sliders.clear();
const screen_device *first_screen = screen_device_enumerator(machine->root_device()).first();
@@ -2349,28 +2307,27 @@ void shaders::init_slider_list()
for (int j = 0; j < count; j++)
{
- auto* slider_arg = new slider(desc, get_slider_option(desc->id, j), &options->params_dirty);
- internal_sliders.push_back(slider_arg);
+ slider &slider_arg = *internal_sliders.emplace_back(std::make_unique<slider>(desc, get_slider_option(desc->id, j), &options->params_dirty));
std::string name = desc->name;
switch (desc->slider_type)
{
case SLIDER_VEC2:
{
- std::string names[2] = { " X", " Y" };
- name = name + names[j];
+ char const *const names[2] = { " X", " Y" };
+ name += names[j];
break;
}
case SLIDER_COLOR:
{
- std::string names[3] = { " Red", " Green", " Blue" };
- name = name + names[j];
+ char const *const names[3] = { " Red", " Green", " Blue" };
+ name += names[j];
break;
}
default:
break;
}
- std::unique_ptr<slider_state> core_slider = slider_alloc(std::move(name), desc->minval, desc->defval, desc->maxval, desc->step, slider_arg);
+ std::unique_ptr<slider_state> core_slider = slider_alloc(std::move(name), desc->minval, desc->defval, desc->maxval, desc->step, &slider_arg);
ui::menu_item item(ui::menu_item_type::SLIDER, core_slider.get());
item.set_text(core_slider->description);
@@ -2405,8 +2362,7 @@ void uniform::update()
hlsl_options *options = shadersys->options;
renderer_d3d9 *d3d = shadersys->d3d;
- auto win = d3d->assert_window();
- const screen_device *first_screen = screen_device_enumerator(win->machine().root_device()).first();
+ const screen_device *first_screen = screen_device_enumerator(d3d->window().machine().root_device()).first();
bool vector_screen =
first_screen != nullptr &&
@@ -2422,7 +2378,7 @@ void uniform::update()
}
case CU_SCREEN_COUNT:
{
- int screen_count = win->target()->current_view().visible_screen_count();
+ int screen_count = d3d->window().target()->current_view().visible_screen_count();
m_shader->set_int("ScreenCount", screen_count);
break;
}
@@ -2485,7 +2441,7 @@ void uniform::update()
case CU_SWAP_XY:
{
- m_shader->set_bool("SwapXY", win->swap_xy());
+ m_shader->set_bool("SwapXY", d3d->window().swap_xy());
break;
}
case CU_VECTOR_SCREEN:
@@ -2609,7 +2565,7 @@ void uniform::update()
m_shader->set_float("SmoothBorderAmount", options->smooth_border);
break;
case CU_POST_SHADOW_ALPHA:
- m_shader->set_float("ShadowAlpha", shadersys->shadow_texture == nullptr ? 0.0f : options->shadow_mask_alpha);
+ m_shader->set_float("ShadowAlpha", !shadersys->shadow_texture ? 0.0f : options->shadow_mask_alpha);
break;
case CU_POST_SHADOW_COUNT:
{
@@ -2684,12 +2640,14 @@ void uniform::update()
//============================================================
effect::effect(shaders *shadersys, IDirect3DDevice9 *dev, const char *name, const char *path)
+ : m_effect(nullptr)
+ , m_shaders(shadersys)
+ , m_num_passes(0)
+ , m_valid(false)
+ , m_active(false)
{
LPD3DXBUFFER buffer_errors = nullptr;
- m_shaders = shadersys;
- m_valid = false;
-
char name_cstr[1024];
sprintf(name_cstr, "%s\\%s", path, name);
auto effect_name = osd::text::to_tstring(name_cstr);
@@ -2716,6 +2674,12 @@ effect::effect(shaders *shadersys, IDirect3DDevice9 *dev, const char *name, cons
effect::~effect()
{
m_effect->Release();
+
+ m_vecs.clear();
+ m_floats.clear();
+ m_ints.clear();
+ m_bools.clear();
+ m_textures.clear();
}
void effect::add_uniform(const char *name, uniform::uniform_type type, int id)
@@ -2729,24 +2693,19 @@ void effect::update_uniforms()
(*uniform).update();
}
-void effect::begin(UINT *passes, DWORD flags)
+void effect::begin(DWORD flags)
{
- m_effect->Begin(passes, flags);
+ m_active = true;
+ m_num_passes = 0;
+ m_effect->Begin(&m_num_passes, flags);
+ m_effect->BeginPass(0);
}
void effect::end()
{
- m_effect->End();
-}
-
-void effect::begin_pass(UINT pass)
-{
- m_effect->BeginPass(pass);
-}
-
-void effect::end_pass()
-{
+ m_active = false;
m_effect->EndPass();
+ m_effect->End();
}
void effect::set_technique(const char *name)
@@ -2756,48 +2715,97 @@ void effect::set_technique(const char *name)
void effect::set_vector(D3DXHANDLE param, int count, float *vector)
{
- static D3DXVECTOR4 out_vector;
- if (count > 0)
- {
- out_vector.x = vector[0];
- }
- if (count > 1)
- {
- out_vector.y = vector[1];
- }
- if (count > 2)
+ count = std::min(count, 4);
+
+ auto iter = m_vecs.find(param);
+ if (iter != m_vecs.end())
{
- out_vector.z = vector[2];
+ D3DXVECTOR4 &data = iter->second;
+ if (!memcmp((float *)data, vector, sizeof(float) * count))
+ {
+ return;
+ }
+ memcpy(data, vector, sizeof(float) * count);
+ m_effect->SetVector(param, &iter->second);
}
- if (count > 3)
+ else
{
- out_vector.w = vector[3];
+ D3DXVECTOR4 vec;
+ memcpy((float *)vec, vector, sizeof(float) * count);
+ m_effect->SetVector(param, &vec);
+ m_vecs[param] = vec;
}
- m_effect->SetVector(param, &out_vector);
}
void effect::set_float(D3DXHANDLE param, float value)
{
+ auto iter = m_floats.find(param);
+ if (iter != m_floats.end())
+ {
+ if (iter->second == value)
+ {
+ return;
+ }
+ iter->second = value;
+ }
+ else
+ {
+ m_floats[param] = value;
+ }
m_effect->SetFloat(param, value);
}
void effect::set_int(D3DXHANDLE param, int value)
{
+ auto iter = m_ints.find(param);
+ if (iter != m_ints.end())
+ {
+ if (iter->second == value)
+ {
+ return;
+ }
+ iter->second = value;
+ }
+ else
+ {
+ m_ints[param] = value;
+ }
m_effect->SetInt(param, value);
}
void effect::set_bool(D3DXHANDLE param, bool value)
{
+ auto iter = m_bools.find(param);
+ if (iter != m_bools.end())
+ {
+ if (iter->second == value)
+ {
+ return;
+ }
+ iter->second = value;
+ }
+ else
+ {
+ m_bools[param] = value;
+ }
m_effect->SetBool(param, value);
}
-void effect::set_matrix(D3DXHANDLE param, D3DXMATRIX *matrix)
-{
- m_effect->SetMatrix(param, matrix);
-}
-
void effect::set_texture(D3DXHANDLE param, IDirect3DTexture9 *tex)
{
+ auto iter = m_textures.find(param);
+ if (iter != m_textures.end())
+ {
+ if (iter->second == (void *)tex)
+ {
+ return;
+ }
+ iter->second = (void *)tex;
+ }
+ else
+ {
+ m_textures[param] = (void *)tex;
+ }
m_effect->SetTexture(param, tex);
}
diff --git a/src/osd/modules/render/d3d/d3dhlsl.h b/src/osd/modules/render/d3d/d3dhlsl.h
index f72197cb7b1..6820f3dd316 100644
--- a/src/osd/modules/render/d3d/d3dhlsl.h
+++ b/src/osd/modules/render/d3d/d3dhlsl.h
@@ -2,18 +2,23 @@
// copyright-holders:Aaron Giles
//============================================================
//
-// drawd3d.c - Win32 Direct3D HLSL-specific header
+// drawd3d.h - Win32 Direct3D HLSL-specific header
//
//============================================================
#ifndef __WIN_D3DHLSL__
#define __WIN_D3DHLSL__
-#include <vector>
#include "../frontend/mame/ui/menuitem.h"
#include "../frontend/mame/ui/slider.h"
#include "modules/lib/osdlib.h"
+#include <wrl/client.h>
+
+#include <map>
+#include <memory>
+#include <vector>
+
//============================================================
// TYPE DEFINITIONS
//============================================================
@@ -133,11 +138,8 @@ public:
effect(shaders *shadersys, IDirect3DDevice9 *dev, const char *name, const char *path);
~effect();
- void begin(UINT *passes, DWORD flags);
- void begin_pass(UINT pass);
-
+ void begin(DWORD flags);
void end();
- void end_pass();
void set_technique(const char *name);
@@ -145,7 +147,6 @@ public:
void set_float(D3DXHANDLE param, float value);
void set_int(D3DXHANDLE param, int value);
void set_bool(D3DXHANDLE param, bool value);
- void set_matrix(D3DXHANDLE param, D3DXMATRIX *matrix);
void set_texture(D3DXHANDLE param, IDirect3DTexture9 *tex);
void add_uniform(const char *name, uniform::uniform_type type, int id);
@@ -154,16 +155,26 @@ public:
D3DXHANDLE get_parameter(D3DXHANDLE param, const char *name);
shaders* get_shaders() { return m_shaders; }
+ uint32_t num_passes() { return m_num_passes; }
bool is_valid() { return m_valid; }
+ bool is_active() { return m_active; }
private:
std::vector<std::unique_ptr<uniform>> m_uniform_list;
ID3DXEffect *m_effect;
shaders *m_shaders;
+ uint32_t m_num_passes;
+
+ std::map<D3DXHANDLE, D3DXVECTOR4> m_vecs;
+ std::map<D3DXHANDLE, float> m_floats;
+ std::map<D3DXHANDLE, int> m_ints;
+ std::map<D3DXHANDLE, bool> m_bools;
+ std::map<D3DXHANDLE, void*> m_textures;
bool m_valid;
+ bool m_active;
};
class d3d_render_target;
@@ -300,11 +311,14 @@ public:
shaders();
~shaders();
- bool init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *renderer);
+ bool init(IDirect3D9 *d3dobj, running_machine *machine, renderer_d3d9 *renderer);
- bool enabled() { return post_fx_enable && d3dintf->post_fx_available; }
+ bool enabled() { return post_fx_enable && d3d->post_fx_available(); }
void toggle() { post_fx_enable = initialized && !post_fx_enable; }
+ void begin_frame(render_primitive_list *primlist);
+ void end_frame();
+
void begin_draw();
void end_draw();
@@ -323,6 +337,7 @@ public:
void init_fsfx_quad();
void set_texture(texture_info *info);
+ void set_filter(bool filter_screens);
void remove_render_target(int source_width, int source_height, uint32_t screen_index);
void remove_render_target(d3d_render_target *rt);
@@ -336,8 +351,12 @@ public:
void *get_slider_option(int id, int index = 0);
private:
+ using IDirect3D9Ptr = Microsoft::WRL::ComPtr<IDirect3D9>;
+ using IDirect3DTexture9Ptr = Microsoft::WRL::ComPtr<IDirect3DTexture9>;
+ using IDirect3DSurface9Ptr = Microsoft::WRL::ComPtr<IDirect3DSurface9>;
+
+ void set_curr_effect(effect *curr_effect);
void blit(IDirect3DSurface9 *dst, bool clear_dst, D3DPRIMITIVETYPE prim_type, uint32_t prim_index, uint32_t prim_count);
- void enumerate_screens();
void render_snapshot(IDirect3DSurface9 *surface);
// Time since last call, only updates once per render of all screens
@@ -364,7 +383,7 @@ private:
int screen_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
void ui_pass(poly_info *poly, int vertnum);
- d3d_base * d3dintf; // D3D interface
+ IDirect3D9Ptr d3dobj; // D3D interface
running_machine * machine;
renderer_d3d9 * d3d; // D3D renderer
@@ -372,7 +391,10 @@ private:
bool post_fx_enable; // overall enable flag
bool oversampling_enable; // oversampling enable flag
int num_screens; // number of emulated physical screens
- int curr_screen; // current screen for render target operations
+ int num_targets; // number of emulated screen targets (can be different from above; cf. artwork and Laserdisc games)
+ int curr_target; // current target index for render target operations
+ int targets_per_screen[256]; // screen target count per screen device/container index; estimated maximum count for array size
+ int target_to_screen[256]; // lookup from target index to screen device/container index; estimated maximum count for array size
double acc_t; // accumulated machine time
double delta_t; // data for delta_time
bitmap_argb32 shadow_bitmap; // shadow mask bitmap for post-processing shader
@@ -383,53 +405,59 @@ private:
texture_info * ui_lut_texture;
hlsl_options * options; // current options
- IDirect3DSurface9 * black_surface; // black dummy surface
- IDirect3DTexture9 * black_texture; // black dummy texture
+ IDirect3DSurface9Ptr black_surface; // black dummy surface
+ IDirect3DTexture9Ptr black_texture; // black dummy texture
bool recording_movie; // ongoing movie recording
std::unique_ptr<movie_recorder> recorder; // HLSL post-render movie recorder
bool render_snap; // whether or not to take HLSL post-render snapshot
- IDirect3DSurface9 * snap_copy_target; // snapshot destination surface in system memory
- IDirect3DTexture9 * snap_copy_texture; // snapshot destination surface in system memory
- IDirect3DSurface9 * snap_target; // snapshot upscaled surface
- IDirect3DTexture9 * snap_texture; // snapshot upscaled texture
+ IDirect3DSurface9Ptr snap_copy_target; // snapshot destination surface in system memory
+ IDirect3DTexture9Ptr snap_copy_texture; // snapshot destination surface in system memory
+ IDirect3DSurface9Ptr snap_target; // snapshot upscaled surface
+ IDirect3DTexture9Ptr snap_texture; // snapshot upscaled texture
int snap_width; // snapshot width
int snap_height; // snapshot height
bool initialized; // whether or not we're initialized
// HLSL effects
- IDirect3DSurface9 * backbuffer; // pointer to our device's backbuffer
+ IDirect3DSurface9Ptr backbuffer; // pointer to our device's backbuffer
effect * curr_effect; // pointer to the currently active effect object
- effect * default_effect; // pointer to the primary-effect object
- effect * prescale_effect; // pointer to the prescale-effect object
- effect * post_effect; // pointer to the post-effect object
- effect * distortion_effect; // pointer to the distortion-effect object
- effect * scanline_effect;
- effect * focus_effect; // pointer to the focus-effect object
- effect * phosphor_effect; // pointer to the phosphor-effect object
- effect * deconverge_effect; // pointer to the deconvergence-effect object
- effect * color_effect; // pointer to the color-effect object
- effect * ntsc_effect; // pointer to the NTSC effect object
- effect * bloom_effect; // pointer to the bloom composite effect
- effect * downsample_effect; // pointer to the bloom downsample effect
- effect * vector_effect; // pointer to the vector-effect object
- effect * chroma_effect;
-
+ std::unique_ptr<effect> default_effect; // pointer to the primary-effect object
+ std::unique_ptr<effect> ui_effect; // pointer to the UI-element effect object
+ std::unique_ptr<effect> ui_wrap_effect; // pointer to the UI-element effect object with texture wrapping
+ std::unique_ptr<effect> vector_buffer_effect; // pointer to the vector-buffering effect object
+ std::unique_ptr<effect> prescale_effect; // pointer to the prescale-effect object
+ std::unique_ptr<effect> prescale_point_effect; // pointer to the prescale-effect object with point filtering
+ std::unique_ptr<effect> post_effect; // pointer to the post-effect object
+ std::unique_ptr<effect> distortion_effect; // pointer to the distortion-effect object
+ std::unique_ptr<effect> scanline_effect;
+ std::unique_ptr<effect> focus_effect; // pointer to the focus-effect object
+ std::unique_ptr<effect> phosphor_effect; // pointer to the phosphor-effect object
+ std::unique_ptr<effect> deconverge_effect; // pointer to the deconvergence-effect object
+ std::unique_ptr<effect> color_effect; // pointer to the color-effect object
+ std::unique_ptr<effect> ntsc_effect; // pointer to the NTSC effect object
+ std::unique_ptr<effect> bloom_effect; // pointer to the bloom composite effect
+ std::unique_ptr<effect> downsample_effect; // pointer to the bloom downsample effect
+ std::unique_ptr<effect> vector_effect; // pointer to the vector-effect object
+ std::unique_ptr<effect> chroma_effect;
+
+ texture_info * diffuse_texture;
+ bool filter_screens;
texture_info * curr_texture;
d3d_render_target * curr_render_target;
poly_info * curr_poly;
std::vector<std::unique_ptr<d3d_render_target>> m_render_target_list;
- std::vector<slider*> internal_sliders;
+ std::vector<std::unique_ptr<slider> > internal_sliders;
std::vector<ui::menu_item> m_sliders;
- std::vector<std::unique_ptr<slider_state>> m_core_sliders;
+ std::vector<std::unique_ptr<slider_state> > m_core_sliders;
static slider_desc s_sliders[];
static hlsl_options last_options; // last used options
- static char last_system_name[16]; // last used system
+ static char last_system_name[MAX_DRIVER_NAME_CHARS + 1]; // last used system
osd::dynamic_module::ptr d3dx9_dll;
d3dx_create_effect_from_file_fn d3dx_create_effect_from_file_ptr;
diff --git a/src/osd/modules/render/draw13.cpp b/src/osd/modules/render/draw13.cpp
index af7c8559ca0..a36ee8a8f52 100644
--- a/src/osd/modules/render/draw13.cpp
+++ b/src/osd/modules/render/draw13.cpp
@@ -2,7 +2,7 @@
// copyright-holders: Couriersud, Olivier Galibert, R. Belmont
//============================================================
//
-// draw13.c - SDL 2.0 drawing implementation
+// draw13.cpp - SDL 2.0 drawing implementation
//
// SDLMAME by Olivier Galibert and R. Belmont
//
@@ -10,24 +10,202 @@
//
//============================================================
+#include "render_module.h"
+
+#include "modules/osdmodule.h"
+
+#if defined(OSD_SDL)
+
+// OSD headers
+#include "sdlopts.h"
+#include "window.h"
+
+// lib/util
+#include "options.h"
+
+// emu
+#include "emucore.h"
+#include "render.h"
+
+// standard SDL headers
+#include <SDL2/SDL.h>
+
// standard C headers
+#include <algorithm>
#include <cmath>
#include <cstdio>
+#include <iterator>
+#include <list>
-// MAME headers
-#include "emu.h"
-#include "options.h"
-// OSD headers
-#include "osdsdl.h"
-#include "window.h"
+namespace osd {
+
+namespace {
+
+struct quad_setup_data
+{
+ quad_setup_data() = default;
+
+ void compute(const render_primitive &prim, const int prescale);
+
+ int32_t dudx = 0, dvdx = 0, dudy = 0, dvdy = 0;
+ int32_t startu = 0, startv = 0;
+ int32_t rotwidth = 0, rotheight = 0;
+};
+
+//============================================================
+// Textures
+//============================================================
+
+class renderer_sdl2;
+struct copy_info_t;
+
+/* texture_info holds information about a texture */
+class texture_info
+{
+public:
+ texture_info(renderer_sdl2 *renderer, const render_texinfo &texsource, const quad_setup_data &setup, const uint32_t flags);
+ ~texture_info();
+
+ void set_data(const render_texinfo &texsource, const uint32_t flags);
+ void render_quad(const render_primitive &prim, const int x, const int y);
+ bool matches(const render_primitive &prim, const quad_setup_data &setup);
+
+ copy_info_t const *compute_size_type();
+
+ void *m_pixels; // pixels for the texture
+ int m_pitch;
+
+ copy_info_t const *m_copyinfo;
+ quad_setup_data m_setup;
+
+ osd_ticks_t m_last_access;
+
+ int raw_width() const { return m_texinfo.width; }
+ int raw_height() const { return m_texinfo.height; }
+
+ const render_texinfo &texinfo() const { return m_texinfo; }
+ render_texinfo &texinfo() { return m_texinfo; }
+
+ HashT hash() const { return m_hash; }
+ uint32_t flags() const { return m_flags; }
+
+private:
+ bool is_pixels_owned() const;
+
+ void set_coloralphamode(SDL_Texture *texture_id, const render_color *color);
+
+ Uint32 m_sdl_access;
+ renderer_sdl2 * m_renderer;
+ render_texinfo m_texinfo; // copy of the texture info
+ HashT m_hash; // hash value for the texture (must be >= pointer size)
+ uint32_t m_flags; // rendering flags
-#include "draw13.h"
+ SDL_Texture * m_texture_id;
+ bool m_is_rotated;
+
+ int m_format; // texture format
+ SDL_BlendMode m_sdl_blendmode;
+};
+
+// inline functions and macros
+#include "blit13.ipp"
//============================================================
-// DEBUGGING
+// TEXCOPY FUNCS
//============================================================
+enum SDL_TEXFORMAT_E
+{
+ SDL_TEXFORMAT_ARGB32 = 0,
+ SDL_TEXFORMAT_RGB32,
+ SDL_TEXFORMAT_RGB32_PALETTED,
+ SDL_TEXFORMAT_YUY16,
+ SDL_TEXFORMAT_YUY16_PALETTED,
+ SDL_TEXFORMAT_PALETTE16,
+ SDL_TEXFORMAT_RGB15,
+ SDL_TEXFORMAT_RGB15_PALETTED,
+ SDL_TEXFORMAT_PALETTE16A,
+ SDL_TEXFORMAT_PALETTE16_ARGB1555,
+ SDL_TEXFORMAT_RGB15_ARGB1555,
+ SDL_TEXFORMAT_RGB15_PALETTED_ARGB1555,
+ SDL_TEXFORMAT_LAST = SDL_TEXFORMAT_RGB15_PALETTED_ARGB1555
+};
+
+struct copy_info_t
+{
+ int src_fmt;
+ Uint32 dst_fmt;
+ const blit_base *blitter;
+ Uint32 bm_mask;
+ const char *srcname;
+ const char *dstname;
+ /* Statistics */
+ mutable uint64_t pixel_count;
+ mutable int64_t time;
+ mutable int samples;
+ mutable int perf;
+ /* list */
+ copy_info_t const *next;
+};
+
+/* renderer_sdl2 is the information about SDL for the current screen */
+class renderer_sdl2 : public osd_renderer
+{
+public:
+ renderer_sdl2(
+ osd_window &window,
+ copy_info_t const *const (&blit_info)[SDL_TEXFORMAT_LAST + 1]);
+
+ virtual ~renderer_sdl2()
+ {
+ destroy_all_textures();
+ SDL_DestroyRenderer(m_sdl_renderer);
+ m_sdl_renderer = nullptr;
+ }
+
+ virtual int create() override;
+ virtual int draw(const int update) override;
+ virtual int xy_to_render_target(const int x, const int y, int *xt, int *yt) override;
+ virtual render_primitive_list *get_primitives() override;
+
+ int RendererSupportsFormat(Uint32 format, Uint32 access, const char *sformat);
+
+ SDL_Renderer *m_sdl_renderer;
+ copy_info_t const *const (&m_blit_info)[SDL_TEXFORMAT_LAST + 1];
+
+private:
+ void render_quad(texture_info *texture, const render_primitive &prim, const int x, const int y);
+
+ texture_info *texture_find(const render_primitive &prim, const quad_setup_data &setup);
+ texture_info *texture_update(const render_primitive &prim);
+
+ void destroy_all_textures();
+
+ int32_t m_blittimer;
+
+ std::list<texture_info> m_texlist; // list of active textures
+
+ float m_last_hofs;
+ float m_last_vofs;
+
+ int m_width;
+ int m_height;
+
+ osd_dim m_blit_dim;
+
+ struct
+ {
+ Uint32 format;
+ int status;
+ } fmt_support[30];
+
+ // Stats
+ int64_t m_last_blit_time;
+ int64_t m_last_blit_pixels;
+};
+
+
//============================================================
// CONSTANTS
//============================================================
@@ -60,9 +238,12 @@ static inline bool is_transparent(const float &a)
// CONSTRUCTOR & DESTRUCTOR
//============================================================
-renderer_sdl2::renderer_sdl2(std::shared_ptr<osd_window> window, int extra_flags)
- : osd_renderer(window, FLAG_NEEDS_OPENGL | extra_flags)
+renderer_sdl2::renderer_sdl2(
+ osd_window &window,
+ copy_info_t const *const (&blit_info)[SDL_TEXFORMAT_LAST + 1])
+ : osd_renderer(window)
, m_sdl_renderer(nullptr)
+ , m_blit_info(blit_info)
, m_blittimer(0)
, m_last_hofs(0)
, m_last_vofs(0)
@@ -77,112 +258,8 @@ renderer_sdl2::renderer_sdl2(std::shared_ptr<osd_window> window, int extra_flags
fmt_support[i].format = 0;
fmt_support[i].status = 0;
}
-
- if (!s_blit_info_initialized)
- {
- /* On OSX, calling this from drawsdl2_init will
- * prohibit fullscreen toggling. It is than not possible
- * to toggle from fullscreen to window mode.
- */
- expand_copy_info(s_blit_info_default);
- s_blit_info_initialized = true;
- }
}
-
-//============================================================
-// STATIC VARIABLES
-//============================================================
-
-#define BM_ALL (UINT32_MAX)
-//( SDL_BLENDMODE_MASK | SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MOD)
-
-#define ENTRY(a,b,f) { SDL_TEXFORMAT_ ## a, SDL_PIXELFORMAT_ ## b, &texcopy_ ## f, BM_ALL, #a, #b, 0, 0, 0, 0}
-#define ENTRY_BM(a,b,f,bm) { SDL_TEXFORMAT_ ## a, SDL_PIXELFORMAT_ ## b, &texcopy_ ## f, bm, #a, #b, 0, 0, 0, 0}
-#define ENTRY_LR(a,b,f) { SDL_TEXFORMAT_ ## a, SDL_PIXELFORMAT_ ## b, &texcopy_ ## f, BM_ALL, #a, #b, 0, 0, 0, -1}
-
-const copy_info_t renderer_sdl2::s_blit_info_default[] =
-{
- /* no rotation */
- ENTRY(ARGB32, ARGB8888, argb32_argb32),
- ENTRY_LR(ARGB32, RGB888, argb32_rgb32),
- /* Entry primarily for directfb */
- ENTRY_BM(ARGB32, RGB888, argb32_rgb32, SDL_BLENDMODE_ADD),
- ENTRY_BM(ARGB32, RGB888, argb32_rgb32, SDL_BLENDMODE_MOD),
- ENTRY_BM(ARGB32, RGB888, argb32_rgb32, SDL_BLENDMODE_NONE),
-
- ENTRY(RGB32, ARGB8888, rgb32_argb32),
- ENTRY(RGB32, RGB888, rgb32_rgb32),
-
- ENTRY(RGB32_PALETTED, ARGB8888, rgb32pal_argb32),
- ENTRY(RGB32_PALETTED, RGB888, rgb32pal_argb32),
-
- ENTRY(YUY16, UYVY, yuv16_uyvy),
- ENTRY(YUY16, YUY2, yuv16_yuy2),
- ENTRY(YUY16, YVYU, yuv16_yvyu),
- ENTRY(YUY16, ARGB8888, yuv16_argb32),
- ENTRY(YUY16, RGB888, yuv16_argb32),
-
- ENTRY(YUY16_PALETTED, UYVY, yuv16pal_uyvy),
- ENTRY(YUY16_PALETTED, YUY2, yuv16pal_yuy2),
- ENTRY(YUY16_PALETTED, YVYU, yuv16pal_yvyu),
- ENTRY(YUY16_PALETTED, ARGB8888, yuv16pal_argb32),
- ENTRY(YUY16_PALETTED, RGB888, yuv16pal_argb32),
-
- ENTRY(PALETTE16, ARGB8888, pal16_argb32),
- ENTRY(PALETTE16, RGB888, pal16_argb32),
-
- ENTRY(RGB15, RGB555, rgb15_rgb555),
- ENTRY(RGB15, ARGB1555, rgb15_argb1555),
- ENTRY(RGB15, ARGB8888, rgb15_argb32),
- ENTRY(RGB15, RGB888, rgb15_argb32),
-
- ENTRY(RGB15_PALETTED, ARGB8888, rgb15pal_argb32),
- ENTRY(RGB15_PALETTED, RGB888, rgb15pal_argb32),
-
- ENTRY(PALETTE16A, ARGB8888, pal16a_argb32),
- ENTRY(PALETTE16A, RGB888, pal16a_rgb32),
-
- /* rotation */
- ENTRY(ARGB32, ARGB8888, rot_argb32_argb32),
- ENTRY_LR(ARGB32, RGB888, rot_argb32_rgb32),
- /* Entry primarily for directfb */
- ENTRY_BM(ARGB32, RGB888, rot_argb32_rgb32, SDL_BLENDMODE_ADD),
- ENTRY_BM(ARGB32, RGB888, rot_argb32_rgb32, SDL_BLENDMODE_MOD),
- ENTRY_BM(ARGB32, RGB888, rot_argb32_rgb32, SDL_BLENDMODE_NONE),
-
- ENTRY(RGB32, ARGB8888, rot_rgb32_argb32),
- ENTRY(RGB32, RGB888, rot_argb32_argb32),
-
- ENTRY(RGB32_PALETTED, ARGB8888, rot_rgb32pal_argb32),
- ENTRY(RGB32_PALETTED, RGB888, rot_rgb32pal_argb32),
-
- ENTRY(YUY16, ARGB8888, rot_yuv16_argb32rot),
- ENTRY(YUY16, RGB888, rot_yuv16_argb32rot),
-
- ENTRY(YUY16_PALETTED, ARGB8888, rot_yuv16pal_argb32rot),
- ENTRY(YUY16_PALETTED, RGB888, rot_yuv16pal_argb32rot),
-
- ENTRY(PALETTE16, ARGB8888, rot_pal16_argb32),
- ENTRY(PALETTE16, RGB888, rot_pal16_argb32),
-
- ENTRY(RGB15, RGB555, rot_rgb15_argb1555),
- ENTRY(RGB15, ARGB1555, rot_rgb15_argb1555),
- ENTRY(RGB15, ARGB8888, rot_rgb15_argb32),
- ENTRY(RGB15, RGB888, rot_rgb15_argb32),
-
- ENTRY(RGB15_PALETTED, ARGB8888, rot_rgb15pal_argb32),
- ENTRY(RGB15_PALETTED, RGB888, rot_rgb15pal_argb32),
-
- ENTRY(PALETTE16A, ARGB8888, rot_pal16a_argb32),
- ENTRY(PALETTE16A, RGB888, rot_pal16a_rgb32),
-
-{ -1 },
-};
-
-copy_info_t* renderer_sdl2::s_blit_info[SDL_TEXFORMAT_LAST+1] = { nullptr };
-bool renderer_sdl2::s_blit_info_initialized = false;
-
//============================================================
// INLINES
//============================================================
@@ -277,7 +354,7 @@ void renderer_sdl2::render_quad(texture_info *texture, const render_primitive &p
if (texture)
{
- copy_info_t *copyinfo = texture->m_copyinfo;
+ copy_info_t const *copyinfo = texture->m_copyinfo;
copyinfo->time -= osd_ticks();
texture->render_quad(prim, x, y);
copyinfo->time += osd_ticks();
@@ -288,7 +365,7 @@ void renderer_sdl2::render_quad(texture_info *texture, const render_primitive &p
copyinfo->time += (m_last_blit_time * (int64_t) (texture->raw_width() * texture->raw_height())) / (int64_t) m_last_blit_pixels;
}
copyinfo->samples++;
- copyinfo->perf = ( texture->m_copyinfo->pixel_count * (osd_ticks_per_second()/1000)) / texture->m_copyinfo->time;
+ copyinfo->perf = (texture->m_copyinfo->pixel_count * (osd_ticks_per_second()/1000)) / std::max<int64_t>(texture->m_copyinfo->time, 1);
}
else
{
@@ -329,59 +406,6 @@ int renderer_sdl2::RendererSupportsFormat(Uint32 format, Uint32 access, const ch
return 0;
}
-//============================================================
-// drawsdl_init
-//============================================================
-
-void renderer_sdl2::add_list(copy_info_t **head, const copy_info_t *element, Uint32 bm)
-{
- copy_info_t *newci = new copy_info_t;
- *newci = *element;
-
- newci->bm_mask = bm;
- newci->next = *head;
- *head = newci;
-}
-
-void renderer_sdl2::expand_copy_info(const copy_info_t *list)
-{
- for (const copy_info_t *bi = list; bi->src_fmt != -1; bi++)
- {
- if (bi->bm_mask == BM_ALL)
- {
- add_list(&s_blit_info[bi->src_fmt], bi, SDL_BLENDMODE_NONE);
- add_list(&s_blit_info[bi->src_fmt], bi, SDL_BLENDMODE_ADD);
- add_list(&s_blit_info[bi->src_fmt], bi, SDL_BLENDMODE_MOD);
- add_list(&s_blit_info[bi->src_fmt], bi, SDL_BLENDMODE_BLEND);
- }
- else
- {
- add_list(&s_blit_info[bi->src_fmt], bi, bi->bm_mask);
- }
- }
-}
-
-// FIXME: machine only used to access options.
-void renderer_sdl2::init(running_machine &machine)
-{
- osd_printf_verbose("Using SDL native texturing driver (SDL 2.0+)\n");
-
-#if USE_OPENGL
- // Load the GL library now - else MT will fail
- const char *stemp = downcast<sdl_options &>(machine.options()).gl_lib();
-#else
- const char *stemp = nullptr;
-#endif
- if (stemp != nullptr && strcmp(stemp, OSDOPTVAL_AUTO) == 0)
- stemp = nullptr;
-
- // No fatalerror here since not all video drivers support GL !
- if (SDL_GL_LoadLibrary(stemp) != 0) // Load library (default for e==nullptr
- osd_printf_warning("Warning: Unable to load opengl library: %s\n", stemp ? stemp : "<default>");
- else
- osd_printf_verbose("Loaded opengl shared library: %s\n", stemp ? stemp : "<default>");
-}
-
//============================================================
// sdl_info::create
@@ -434,12 +458,10 @@ int renderer_sdl2::create()
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0");
}
- auto win = assert_window();
-
if (video_config.waitvsync)
- m_sdl_renderer = SDL_CreateRenderer(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
+ m_sdl_renderer = SDL_CreateRenderer(dynamic_cast<sdl_window_info &>(window()).platform_window(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
else
- m_sdl_renderer = SDL_CreateRenderer(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window(), -1, SDL_RENDERER_ACCELERATED);
+ m_sdl_renderer = SDL_CreateRenderer(dynamic_cast<sdl_window_info &>(window()).platform_window(), -1, SDL_RENDERER_ACCELERATED);
if (!m_sdl_renderer)
{
@@ -483,18 +505,14 @@ int renderer_sdl2::xy_to_render_target(int x, int y, int *xt, int *yt)
void renderer_sdl2::destroy_all_textures()
{
- auto win = assert_window();
- if (win == nullptr)
- return;
-
- if(win->m_primlist)
+ if (window().m_primlist)
{
- win->m_primlist->acquire_lock();
- m_texlist.reset();
- win->m_primlist->release_lock();
+ window().m_primlist->acquire_lock();
+ m_texlist.clear();
+ window().m_primlist->release_lock();
}
else
- m_texlist.reset();
+ m_texlist.clear();
}
//============================================================
@@ -507,13 +525,7 @@ int renderer_sdl2::draw(int update)
float vofs, hofs;
int blit_pixels = 0;
- if (video_config.novideo)
- {
- return 0;
- }
-
- auto win = assert_window();
- osd_dim wdim = win->get_size();
+ osd_dim wdim = window().get_size();
if (has_flags(FI_CHANGED) || (wdim.width() != m_width) || (wdim.height() != m_height))
{
@@ -560,10 +572,10 @@ int renderer_sdl2::draw(int update)
m_last_hofs = hofs;
m_last_vofs = vofs;
- win->m_primlist->acquire_lock();
+ window().m_primlist->acquire_lock();
// now draw
- for (render_primitive &prim : *win->m_primlist)
+ for (render_primitive &prim : *window().m_primlist)
{
Uint8 sr, sg, sb, sa;
@@ -593,7 +605,7 @@ int renderer_sdl2::draw(int update)
}
}
- win->m_primlist->release_lock();
+ window().m_primlist->release_lock();
m_last_blit_pixels = blit_pixels;
m_last_blit_time = -osd_ticks();
@@ -612,22 +624,23 @@ int renderer_sdl2::draw(int update)
// texture_compute_size and type
//============================================================
-copy_info_t *texture_info::compute_size_type()
+copy_info_t const *texture_info::compute_size_type()
{
- copy_info_t *result = nullptr;
+ copy_info_t const *result = nullptr;
int maxperf = 0;
- for (copy_info_t *bi = renderer_sdl2::s_blit_info[m_format]; bi != nullptr; bi = bi->next)
+ for (copy_info_t const *bi = m_renderer->m_blit_info[m_format]; bi != nullptr; bi = bi->next)
{
- if ((m_is_rotated == bi->blitter->m_is_rot)
- && (m_sdl_blendmode == bi->bm_mask))
+ if ((m_is_rotated == bi->blitter->m_is_rot) && (m_sdl_blendmode == bi->bm_mask))
{
if (m_renderer->RendererSupportsFormat(bi->dst_fmt, m_sdl_access, bi->dstname))
{
- int perf = bi->perf;
+ int const perf = bi->perf;
if (perf == 0)
+ {
return bi;
- else if (perf > (maxperf * 102) / 100)
+ }
+ else if (perf > ((maxperf * 102) / 100))
{
result = bi;
maxperf = perf;
@@ -639,23 +652,21 @@ copy_info_t *texture_info::compute_size_type()
if (result)
return result;
- /* try last resort handlers */
- for (copy_info_t *bi = renderer_sdl2::s_blit_info[m_format]; bi != nullptr; bi = bi->next)
+ // try last resort handlers
+ for (copy_info_t const *bi = m_renderer->m_blit_info[m_format]; bi != nullptr; bi = bi->next)
{
- if ((m_is_rotated == bi->blitter->m_is_rot)
- && (m_sdl_blendmode == bi->bm_mask))
+ if ((m_is_rotated == bi->blitter->m_is_rot) && (m_sdl_blendmode == bi->bm_mask))
if (m_renderer->RendererSupportsFormat(bi->dst_fmt, m_sdl_access, bi->dstname))
return bi;
}
- //FIXME: crash implement a -do nothing handler */
+ //FIXME: crash implement a -do nothing handler
return nullptr;
}
-// FIXME:
bool texture_info::is_pixels_owned() const
-{ // do we own / allocated it ?
- return ((m_sdl_access == SDL_TEXTUREACCESS_STATIC)
- && (m_copyinfo->blitter->m_is_passthrough));
+{
+ // do we own / allocated it ?
+ return (m_sdl_access == SDL_TEXTUREACCESS_STATIC) && !m_copyinfo->blitter->m_is_passthrough;
}
//============================================================
@@ -745,12 +756,11 @@ texture_info::texture_info(renderer_sdl2 *renderer, const render_texinfo &texsou
m_pixels = malloc(m_setup.rotwidth * m_setup.rotheight * m_copyinfo->blitter->m_dest_bpp);
}
m_last_access = osd_ticks();
-
}
texture_info::~texture_info()
{
- if ( is_pixels_owned() && (m_pixels != nullptr) )
+ if (is_pixels_owned() && m_pixels)
free(m_pixels);
SDL_DestroyTexture(m_texture_id);
}
@@ -764,7 +774,7 @@ void texture_info::set_data(const render_texinfo &texsource, const uint32_t flag
m_copyinfo->time -= osd_ticks();
if (m_sdl_access == SDL_TEXTUREACCESS_STATIC)
{
- if ( m_copyinfo->blitter->m_is_passthrough )
+ if (m_copyinfo->blitter->m_is_passthrough)
{
m_pixels = texsource.base;
m_pitch = m_texinfo.rowpixels * m_copyinfo->blitter->m_dest_bpp;
@@ -778,11 +788,11 @@ void texture_info::set_data(const render_texinfo &texsource, const uint32_t flag
}
else
{
- SDL_LockTexture(m_texture_id, nullptr, (void **) &m_pixels, &m_pitch);
+ SDL_LockTexture(m_texture_id, nullptr, (void **)&m_pixels, &m_pitch);
if ( m_copyinfo->blitter->m_is_passthrough )
{
- uint8_t *src = (uint8_t *) texsource.base;
- uint8_t *dst = (uint8_t *) m_pixels;
+ const uint8_t *src = (uint8_t *)texsource.base;
+ uint8_t *dst = (uint8_t *)m_pixels;
int spitch = texsource.rowpixels * m_copyinfo->blitter->m_dest_bpp;
int num = texsource.width * m_copyinfo->blitter->m_dest_bpp;
int h = texsource.height;
@@ -868,64 +878,38 @@ void quad_setup_data::compute(const render_primitive &prim, const int prescale)
texture_info *renderer_sdl2::texture_find(const render_primitive &prim, const quad_setup_data &setup)
{
- HashT texhash = texture_compute_hash(prim.texture, prim.flags);
- texture_info *texture;
- osd_ticks_t now = osd_ticks();
+ const HashT texhash = texture_compute_hash(prim.texture, prim.flags);
+ const osd_ticks_t now = osd_ticks();
// find a match
- for (texture = m_texlist.first(); texture != nullptr; )
- if (texture->hash() == texhash &&
- texture->matches(prim, setup))
+ for (auto texture = m_texlist.begin(); texture != m_texlist.end(); )
+ {
+ if ((texture->hash() == texhash) && texture->matches(prim, setup))
{
- /* would we choose another blitter based on performance ? */
+ // would we choose another blitter based on performance?
if ((texture->m_copyinfo->samples & 0x7f) == 0x7f)
{
if (texture->m_copyinfo != texture->compute_size_type())
return nullptr;
}
texture->m_last_access = now;
- return texture;
+ return &*texture;
}
else
{
- /* free resources not needed any longer? */
- texture_info *expire = texture;
- texture = texture->next();
- if (now - expire->m_last_access > osd_ticks_per_second())
- m_texlist.remove(*expire);
+ // free resources not needed any longer?
+ if ((now - texture->m_last_access) > osd_ticks_per_second())
+ texture = m_texlist.erase(texture);
+ else
+ ++texture;
}
+ }
// nothing found
return nullptr;
}
//============================================================
-// exit
-//============================================================
-
-void renderer_sdl2::exit()
-{
- if (s_blit_info_initialized)
- {
- for (int i = 0; i <= SDL_TEXFORMAT_LAST; i++)
- {
- for (copy_info_t *bi = s_blit_info[i]; bi != nullptr; )
- {
- if (bi->pixel_count)
- osd_printf_verbose("%s -> %s %s blendmode 0x%02x, %d samples: %d KPixel/sec\n", bi->srcname, bi->dstname,
- bi->blitter->m_is_rot ? "rot" : "norot", bi->bm_mask, bi->samples,
- (int) bi->perf);
- copy_info_t *freeme = bi;
- bi = bi->next;
- delete freeme;
- }
- s_blit_info[i] = nullptr;
- }
- s_blit_info_initialized = false;
- }
-}
-
-//============================================================
// texture_update
//============================================================
@@ -934,22 +918,20 @@ texture_info * renderer_sdl2::texture_update(const render_primitive &prim)
quad_setup_data setup;
texture_info *texture;
- auto win = assert_window();
- setup.compute(prim, win->prescale());
+ setup.compute(prim, window().prescale());
texture = texture_find(prim, setup);
// if we didn't find one, create a new texture
- if (texture == nullptr && prim.texture.base != nullptr)
+ if (!texture && prim.texture.base)
{
- texture = new texture_info(this, prim.texture, setup, prim.flags);
- /* add us to the texture list */
- m_texlist.prepend(*texture);
+ // add us to the texture list
+ texture = &m_texlist.emplace_front(this, prim.texture, setup, prim.flags);
}
- if (texture != nullptr)
+ if (texture)
{
- if (prim.texture.base != nullptr && texture->texinfo().seqid != prim.texture.seqid)
+ if (prim.texture.base && (texture->texinfo().seqid != prim.texture.seqid))
{
texture->texinfo().seqid = prim.texture.seqid;
// if we found it, but with a different seqid, copy the data
@@ -962,16 +944,249 @@ texture_info * renderer_sdl2::texture_update(const render_primitive &prim)
render_primitive_list *renderer_sdl2::get_primitives()
{
- auto win = assert_window();
- if (win == nullptr)
- return nullptr;
-
- osd_dim nd = win->get_size();
+ osd_dim nd = window().get_size();
if (nd != m_blit_dim)
{
m_blit_dim = nd;
notify_changed();
}
- win->target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), win->pixel_aspect());
- return &win->target()->get_primitives();
+ window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().pixel_aspect());
+ return &window().target()->get_primitives();
+}
+
+
+class video_sdl2 : public osd_module, public render_module
+{
+public:
+ video_sdl2()
+ : osd_module(OSD_RENDERER_PROVIDER, "accel")
+ , m_blit_info_initialized(false)
+ , m_gllib_loaded(false)
+ {
+ std::fill(std::begin(m_blit_info), std::end(m_blit_info), nullptr);
+ }
+ ~video_sdl2()
+ {
+ free_copy_info();
+ }
+
+ virtual int init(osd_interface &osd, osd_options const &options) override;
+ virtual void exit() override { free_copy_info(); }
+
+ virtual std::unique_ptr<osd_renderer> create(osd_window &window) override;
+
+protected:
+ virtual unsigned flags() const override { return FLAG_INTERACTIVE | FLAG_SDL_NEEDS_OPENGL; }
+
+private:
+ static inline constexpr Uint32 BM_ALL = UINT32_MAX; // SDL_BLENDMODE_MASK | SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MOD
+
+ void expand_copy_info();
+ void free_copy_info();
+
+ static void add_list(copy_info_t const *&head, copy_info_t const &element, Uint32 bm);
+
+ copy_info_t const *m_blit_info[SDL_TEXFORMAT_LAST + 1];
+ bool m_blit_info_initialized;
+ bool m_gllib_loaded;
+
+ static copy_info_t const s_blit_info_default[];
+};
+
+int video_sdl2::init(osd_interface &osd, osd_options const &options)
+{
+ osd_printf_verbose("Using SDL native texturing driver (SDL 2.0+)\n");
+
+ // Load the GL library now - else MT will fail
+ char const *libname = nullptr;
+#if USE_OPENGL
+ libname = dynamic_cast<sdl_options const &>(options).gl_lib();
+ if (libname && (!*libname || !std::strcmp(libname, OSDOPTVAL_AUTO)))
+ libname = nullptr;
+#endif
+
+ if (!m_gllib_loaded)
+ {
+ // No fatalerror here since not all video drivers support GL!
+ if (SDL_GL_LoadLibrary(libname) != 0)
+ {
+ osd_printf_error("Unable to load OpenGL shared library: %s\n", libname ? libname : "<default>");
+ m_gllib_loaded = true;
+ }
+ else
+ {
+ osd_printf_verbose("Loaded OpenGL shared library: %s\n", libname ? libname : "<default>");
+ }
+ }
+
+ return 0;
+}
+
+std::unique_ptr<osd_renderer> video_sdl2::create(osd_window &window)
+{
+ if (!m_blit_info_initialized)
+ {
+ // On macOS, calling this from drawsdl2_init will prohibit fullscreen toggling.
+ // It is than not possible to toggle from fullscreen to window mode.
+ expand_copy_info();
+ m_blit_info_initialized = true;
+ }
+
+ return std::make_unique<renderer_sdl2>(window, m_blit_info);
+}
+
+void video_sdl2::expand_copy_info()
+{
+ for (const copy_info_t *bi = s_blit_info_default; bi->src_fmt != -1; bi++)
+ {
+ if (bi->bm_mask == BM_ALL)
+ {
+ add_list(m_blit_info[bi->src_fmt], *bi, SDL_BLENDMODE_NONE);
+ add_list(m_blit_info[bi->src_fmt], *bi, SDL_BLENDMODE_ADD);
+ add_list(m_blit_info[bi->src_fmt], *bi, SDL_BLENDMODE_MOD);
+ add_list(m_blit_info[bi->src_fmt], *bi, SDL_BLENDMODE_BLEND);
+ }
+ else
+ {
+ add_list(m_blit_info[bi->src_fmt], *bi, bi->bm_mask);
+ }
+ }
+}
+
+void video_sdl2::free_copy_info()
+{
+ if (m_blit_info_initialized)
+ {
+ for (int i = 0; i <= SDL_TEXFORMAT_LAST; i++)
+ {
+ for (copy_info_t const *bi = m_blit_info[i]; bi != nullptr; )
+ {
+ if (bi->pixel_count)
+ {
+ osd_printf_verbose(
+ "%s -> %s %s blendmode 0x%02x, %d samples: %d KPixel/sec\n",
+ bi->srcname,
+ bi->dstname,
+ bi->blitter->m_is_rot ? "rot" : "norot",
+ bi->bm_mask,
+ bi->samples,
+ bi->perf);
+ }
+ delete std::exchange(bi, bi->next);
+ }
+ m_blit_info[i] = nullptr;
+ }
+ m_blit_info_initialized = false;
+ }
+}
+
+void video_sdl2::add_list(copy_info_t const *&head, copy_info_t const &element, Uint32 bm)
+{
+ copy_info_t *const newci = new copy_info_t(element);
+
+ newci->bm_mask = bm;
+ newci->next = head;
+ head = newci;
}
+
+
+//============================================================
+// STATIC VARIABLES
+//============================================================
+
+#define ENTRY(a,b,f) { SDL_TEXFORMAT_ ## a, SDL_PIXELFORMAT_ ## b, &texcopy_ ## f, BM_ALL, #a, #b, 0, 0, 0, 0}
+#define ENTRY_BM(a,b,f,bm) { SDL_TEXFORMAT_ ## a, SDL_PIXELFORMAT_ ## b, &texcopy_ ## f, bm, #a, #b, 0, 0, 0, 0}
+#define ENTRY_LR(a,b,f) { SDL_TEXFORMAT_ ## a, SDL_PIXELFORMAT_ ## b, &texcopy_ ## f, BM_ALL, #a, #b, 0, 0, 0, -1}
+
+copy_info_t const video_sdl2::s_blit_info_default[] =
+{
+ /* no rotation */
+ ENTRY(ARGB32, ARGB8888, argb32_argb32),
+ ENTRY_LR(ARGB32, RGB888, argb32_rgb32),
+ /* Entry primarily for directfb */
+ ENTRY_BM(ARGB32, RGB888, argb32_rgb32, SDL_BLENDMODE_ADD),
+ ENTRY_BM(ARGB32, RGB888, argb32_rgb32, SDL_BLENDMODE_MOD),
+ ENTRY_BM(ARGB32, RGB888, argb32_rgb32, SDL_BLENDMODE_NONE),
+
+ ENTRY(RGB32, ARGB8888, rgb32_argb32),
+ ENTRY(RGB32, RGB888, rgb32_rgb32),
+
+ ENTRY(RGB32_PALETTED, ARGB8888, rgb32pal_argb32),
+ ENTRY(RGB32_PALETTED, RGB888, rgb32pal_argb32),
+
+ ENTRY(YUY16, UYVY, yuv16_uyvy),
+ ENTRY(YUY16, YUY2, yuv16_yuy2),
+ ENTRY(YUY16, YVYU, yuv16_yvyu),
+ ENTRY(YUY16, ARGB8888, yuv16_argb32),
+ ENTRY(YUY16, RGB888, yuv16_argb32),
+
+ ENTRY(YUY16_PALETTED, UYVY, yuv16pal_uyvy),
+ ENTRY(YUY16_PALETTED, YUY2, yuv16pal_yuy2),
+ ENTRY(YUY16_PALETTED, YVYU, yuv16pal_yvyu),
+ ENTRY(YUY16_PALETTED, ARGB8888, yuv16pal_argb32),
+ ENTRY(YUY16_PALETTED, RGB888, yuv16pal_argb32),
+
+ ENTRY(PALETTE16, ARGB8888, pal16_argb32),
+ ENTRY(PALETTE16, RGB888, pal16_argb32),
+
+ ENTRY(RGB15, RGB555, rgb15_rgb555),
+ ENTRY(RGB15, ARGB1555, rgb15_argb1555),
+ ENTRY(RGB15, ARGB8888, rgb15_argb32),
+ ENTRY(RGB15, RGB888, rgb15_argb32),
+
+ ENTRY(RGB15_PALETTED, ARGB8888, rgb15pal_argb32),
+ ENTRY(RGB15_PALETTED, RGB888, rgb15pal_argb32),
+
+ ENTRY(PALETTE16A, ARGB8888, pal16a_argb32),
+ ENTRY(PALETTE16A, RGB888, pal16a_rgb32),
+
+ /* rotation */
+ ENTRY(ARGB32, ARGB8888, rot_argb32_argb32),
+ ENTRY_LR(ARGB32, RGB888, rot_argb32_rgb32),
+ /* Entry primarily for directfb */
+ ENTRY_BM(ARGB32, RGB888, rot_argb32_rgb32, SDL_BLENDMODE_ADD),
+ ENTRY_BM(ARGB32, RGB888, rot_argb32_rgb32, SDL_BLENDMODE_MOD),
+ ENTRY_BM(ARGB32, RGB888, rot_argb32_rgb32, SDL_BLENDMODE_NONE),
+
+ ENTRY(RGB32, ARGB8888, rot_rgb32_argb32),
+ ENTRY(RGB32, RGB888, rot_argb32_argb32),
+
+ ENTRY(RGB32_PALETTED, ARGB8888, rot_rgb32pal_argb32),
+ ENTRY(RGB32_PALETTED, RGB888, rot_rgb32pal_argb32),
+
+ ENTRY(YUY16, ARGB8888, rot_yuv16_argb32rot),
+ ENTRY(YUY16, RGB888, rot_yuv16_argb32rot),
+
+ ENTRY(YUY16_PALETTED, ARGB8888, rot_yuv16pal_argb32rot),
+ ENTRY(YUY16_PALETTED, RGB888, rot_yuv16pal_argb32rot),
+
+ ENTRY(PALETTE16, ARGB8888, rot_pal16_argb32),
+ ENTRY(PALETTE16, RGB888, rot_pal16_argb32),
+
+ ENTRY(RGB15, RGB555, rot_rgb15_argb1555),
+ ENTRY(RGB15, ARGB1555, rot_rgb15_argb1555),
+ ENTRY(RGB15, ARGB8888, rot_rgb15_argb32),
+ ENTRY(RGB15, RGB888, rot_rgb15_argb32),
+
+ ENTRY(RGB15_PALETTED, ARGB8888, rot_rgb15pal_argb32),
+ ENTRY(RGB15_PALETTED, RGB888, rot_rgb15pal_argb32),
+
+ ENTRY(PALETTE16A, ARGB8888, rot_pal16a_argb32),
+ ENTRY(PALETTE16A, RGB888, rot_pal16a_rgb32),
+
+ { -1 },
+};
+
+} // anonymous namespace
+
+} // namespace osd
+
+
+#else // defined(OSD_SDL)
+
+namespace osd { namespace { MODULE_NOT_SUPPORTED(video_sdl2, OSD_RENDERER_PROVIDER, "accel") } }
+
+#endif // defined(OSD_SDL)
+
+
+MODULE_DEFINITION(RENDERER_SDL2, osd::video_sdl2)
diff --git a/src/osd/modules/render/draw13.h b/src/osd/modules/render/draw13.h
deleted file mode 100644
index d69c84c1c9d..00000000000
--- a/src/osd/modules/render/draw13.h
+++ /dev/null
@@ -1,216 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Couriersud, Olivier Galibert, R. Belmont
-//============================================================
-//
-// draw13.h - SDL 2.0 drawing implementation
-//
-// SDLMAME by Olivier Galibert and R. Belmont
-//
-//============================================================
-
-#ifndef MAME_OSD_MODULES_RENDER_DRAW13_H
-#define MAME_OSD_MODULES_RENDER_DRAW13_H
-
-#pragma once
-
-// OSD headers
-#ifndef OSD_WINDOWS
-#include "osdsdl.h"
-#include "window.h"
-#else
-#include "../windows/window.h"
-typedef uint64_t HashT;
-#endif
-
-// standard SDL headers
-#include <SDL2/SDL.h>
-
-#include "emucore.h"
-#include "render.h"
-
-struct quad_setup_data
-{
- quad_setup_data()
- : dudx(0)
- , dvdx(0)
- , dudy(0)
- , dvdy(0)
- , startu(0)
- , startv(0)
- , rotwidth(0)
- , rotheight(0)
- {
- }
-
- void compute(const render_primitive &prim, const int prescale);
-
- int32_t dudx, dvdx, dudy, dvdy;
- int32_t startu, startv;
- int32_t rotwidth, rotheight;
-};
-
-//============================================================
-// Textures
-//============================================================
-
-class renderer_sdl2;
-struct copy_info_t;
-
-/* texture_info holds information about a texture */
-class texture_info
-{
- friend class simple_list<texture_info>;
-public:
- texture_info(renderer_sdl2 *renderer, const render_texinfo &texsource, const quad_setup_data &setup, const uint32_t flags);
- ~texture_info();
-
- void set_data(const render_texinfo &texsource, const uint32_t flags);
- void render_quad(const render_primitive &prim, const int x, const int y);
- bool matches(const render_primitive &prim, const quad_setup_data &setup);
-
- copy_info_t *compute_size_type();
-
- void *m_pixels; // pixels for the texture
- int m_pitch;
-
- copy_info_t *m_copyinfo;
- quad_setup_data m_setup;
-
- osd_ticks_t m_last_access;
-
- int raw_width() const { return m_texinfo.width; }
- int raw_height() const { return m_texinfo.height; }
-
- texture_info *next() { return m_next; }
- const render_texinfo &texinfo() const { return m_texinfo; }
- render_texinfo &texinfo() { return m_texinfo; }
-
- HashT hash() const { return m_hash; }
- uint32_t flags() const { return m_flags; }
- // FIXME:
- bool is_pixels_owned() const;
-
-private:
- void set_coloralphamode(SDL_Texture *texture_id, const render_color *color);
-
- Uint32 m_sdl_access;
- renderer_sdl2 * m_renderer;
- render_texinfo m_texinfo; // copy of the texture info
- HashT m_hash; // hash value for the texture (must be >= pointer size)
- uint32_t m_flags; // rendering flags
-
- SDL_Texture * m_texture_id;
- bool m_is_rotated;
-
- int m_format; // texture format
- SDL_BlendMode m_sdl_blendmode;
-
- texture_info * m_next; // next texture in the list
-};
-
-//============================================================
-// TEXCOPY FUNCS
-//============================================================
-
-enum SDL_TEXFORMAT_E
-{
- SDL_TEXFORMAT_ARGB32 = 0,
- SDL_TEXFORMAT_RGB32,
- SDL_TEXFORMAT_RGB32_PALETTED,
- SDL_TEXFORMAT_YUY16,
- SDL_TEXFORMAT_YUY16_PALETTED,
- SDL_TEXFORMAT_PALETTE16,
- SDL_TEXFORMAT_RGB15,
- SDL_TEXFORMAT_RGB15_PALETTED,
- SDL_TEXFORMAT_PALETTE16A,
- SDL_TEXFORMAT_PALETTE16_ARGB1555,
- SDL_TEXFORMAT_RGB15_ARGB1555,
- SDL_TEXFORMAT_RGB15_PALETTED_ARGB1555,
- SDL_TEXFORMAT_LAST = SDL_TEXFORMAT_RGB15_PALETTED_ARGB1555
-};
-
-#include "blit13.h"
-
-struct copy_info_t
-{
- int src_fmt;
- Uint32 dst_fmt;
- const blit_base *blitter;
- Uint32 bm_mask;
- const char *srcname;
- const char *dstname;
- /* Statistics */
- uint64_t pixel_count;
- int64_t time;
- int samples;
- int perf;
- /* list */
- copy_info_t *next;
-};
-
-/* renderer_sdl2 is the information about SDL for the current screen */
-class renderer_sdl2 : public osd_renderer
-{
-public:
- renderer_sdl2(std::shared_ptr<osd_window> window, int extra_flags);
-
- virtual ~renderer_sdl2()
- {
- destroy_all_textures();
- SDL_DestroyRenderer(m_sdl_renderer);
- m_sdl_renderer = nullptr;
- }
-
- static void init(running_machine &machine);
- static void exit();
-
- virtual int create() override;
- virtual int draw(const int update) override;
- virtual int xy_to_render_target(const int x, const int y, int *xt, int *yt) override;
- virtual render_primitive_list *get_primitives() override;
-
- int RendererSupportsFormat(Uint32 format, Uint32 access, const char *sformat);
-
- SDL_Renderer * m_sdl_renderer;
-
- static copy_info_t* s_blit_info[SDL_TEXFORMAT_LAST+1];
-
-private:
- void expand_copy_info(const copy_info_t *list);
- void add_list(copy_info_t **head, const copy_info_t *element, Uint32 bm);
-
- void render_quad(texture_info *texture, const render_primitive &prim, const int x, const int y);
-
- texture_info *texture_find(const render_primitive &prim, const quad_setup_data &setup);
- texture_info *texture_update(const render_primitive &prim);
-
- void destroy_all_textures();
-
- int32_t m_blittimer;
-
-
- simple_list<texture_info> m_texlist; // list of active textures
-
- float m_last_hofs;
- float m_last_vofs;
-
- int m_width;
- int m_height;
-
- osd_dim m_blit_dim;
-
- struct
- {
- Uint32 format;
- int status;
- } fmt_support[30];
-
- // Stats
- int64_t m_last_blit_time;
- int64_t m_last_blit_pixels;
-
- static bool s_blit_info_initialized;
- static const copy_info_t s_blit_info_default[];
-};
-
-#endif // MAME_OSD_MODULES_RENDER_DRAW13_H
diff --git a/src/osd/modules/render/drawbgfx.cpp b/src/osd/modules/render/drawbgfx.cpp
index fc9214fe446..36758914961 100644
--- a/src/osd/modules/render/drawbgfx.cpp
+++ b/src/osd/modules/render/drawbgfx.cpp
@@ -5,6 +5,40 @@
// drawbgfx.cpp - BGFX renderer
//
//============================================================
+
+#include "drawbgfx.h"
+
+// render/bgfx
+#include "bgfx/effect.h"
+#include "bgfx/effectmanager.h"
+#include "bgfx/shadermanager.h"
+#include "bgfx/slider.h"
+#include "bgfx/target.h"
+#include "bgfx/target.h"
+#include "bgfx/targetmanager.h"
+#include "bgfx/texture.h"
+#include "bgfx/texturemanager.h"
+#include "bgfx/uniform.h"
+#include "bgfx/view.h"
+
+// render
+#include "aviwrite.h"
+#include "bgfxutil.h"
+#include "render_module.h"
+
+// emu
+#include "emu.h"
+#include "config.h"
+#include "render.h"
+#include "rendutil.h"
+
+// util
+#include "util/xmlfile.h"
+
+// OSD
+#include "modules/lib/osdobj_common.h"
+#include "window.h"
+
#include <bx/math.h>
#include <bx/readerwriter.h>
@@ -22,334 +56,658 @@ extern void *GetOSWindow(void *wincontroller);
#endif
#endif
-// MAMEOS headers
-#include "emu.h"
-#include "window.h"
-#include "render.h"
-#include "rendutil.h"
-#include "aviwrite.h"
+#if defined(SDLMAME_USE_WAYLAND)
+#include <wayland-egl.h>
+#endif
#include <bgfx/bgfx.h>
#include <bgfx/platform.h>
-#include <algorithm>
-#include "drawbgfx.h"
-#include "bgfxutil.h"
-#include "bgfx/texturemanager.h"
-#include "bgfx/targetmanager.h"
-#include "bgfx/shadermanager.h"
-#include "bgfx/effectmanager.h"
-#include "bgfx/chainmanager.h"
-#include "bgfx/effect.h"
-#include "bgfx/texture.h"
-#include "bgfx/target.h"
-#include "bgfx/chain.h"
-#include "bgfx/vertex.h"
-#include "bgfx/uniform.h"
-#include "bgfx/slider.h"
-#include "bgfx/target.h"
-#include "bgfx/view.h"
+#include "imgui/imgui.h"
-#include "modules/lib/osdobj_common.h"
+#include <algorithm>
-#include "imgui/imgui.h"
//============================================================
-// DEBUGGING
+// Renderer interface to parent module
//============================================================
-//============================================================
-// CONSTANTS
-//============================================================
+class renderer_bgfx::parent_module
+{
+public:
+ util::xml::data_node &persistent_settings() { return *m_persistent_settings; }
+ osd_options const &options() const { return *m_options; }
+ uint32_t max_texture_size() const { return m_max_texture_size; }
+
+ template <typename T>
+ util::notifier_subscription subscribe_load(void (T::*func)(util::xml::data_node const &), T *obj)
+ {
+ return m_load_notifier.subscribe(delegate<void (util::xml::data_node const &)>(func, obj));
+ }
+
+ template <typename T>
+ util::notifier_subscription subscribe_save(void (T::*func)(util::xml::data_node &), T *obj)
+ {
+ return m_save_notifier.subscribe(delegate<void (util::xml::data_node &)>(func, obj));
+ }
+
+protected:
+ parent_module()
+ : m_options(nullptr)
+ , m_max_texture_size(0)
+ , m_renderer_count(0)
+ {
+ }
+ virtual ~parent_module()
+ {
+ assert(!m_renderer_count);
+ }
+
+ bool has_active_renderers() const
+ {
+ return 0 < m_renderer_count;
+ }
+
+ util::notifier<util::xml::data_node const &> m_load_notifier;
+ util::notifier<util::xml::data_node &> m_save_notifier;
+ util::xml::file::ptr m_persistent_settings;
+ osd_options const *m_options;
+ uint32_t m_max_texture_size;
+
+private:
+ friend class parent_module_holder;
+
+ virtual void last_renderer_destroyed() = 0;
+
+ void renderer_created()
+ {
+ ++m_renderer_count;
+ }
+
+ void renderer_destroyed()
+ {
+ assert(m_renderer_count);
+ if (!--m_renderer_count)
+ last_renderer_destroyed();
+ }
+
+ unsigned m_renderer_count;
+};
+
+
+inline renderer_bgfx::parent_module_holder::parent_module_holder(parent_module &parent)
+ : m_parent(parent)
+{
+ m_parent.renderer_created();
+}
+
+
+inline renderer_bgfx::parent_module_holder::~parent_module_holder()
+{
+ m_parent.renderer_destroyed();
+}
+
-uint16_t const renderer_bgfx::CACHE_SIZE = 1024;
-uint32_t const renderer_bgfx::PACKABLE_SIZE = 128;
-uint32_t const renderer_bgfx::WHITE_HASH = 0x87654321;
-char const *const renderer_bgfx::WINDOW_PREFIX = "Window 0, ";
//============================================================
-// MACROS
+// OSD MODULE
//============================================================
-#define GIBBERISH (0)
-#define SCENE_VIEW (0)
+namespace osd {
+
+namespace {
+
+class video_bgfx : public osd_module, public render_module, protected renderer_bgfx::parent_module
+{
+public:
+ video_bgfx()
+ : osd_module(OSD_RENDERER_PROVIDER, "bgfx")
+ , m_bgfx_library_initialized(false)
+ {
+ }
+ ~video_bgfx() { exit(); }
+
+ virtual int init(osd_interface &osd, osd_options const &options) override;
+ virtual void exit() override;
+
+ virtual std::unique_ptr<osd_renderer> create(osd_window &window) override;
+
+protected:
+ virtual unsigned flags() const override { return FLAG_INTERACTIVE; }
+
+private:
+ virtual void last_renderer_destroyed() override;
+
+ void load_config(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode);
+ void save_config(config_type cfg_type, util::xml::data_node *parentnode);
+
+ bool init_bgfx_library(osd_window &window);
+
+ static bool set_platform_data(bgfx::PlatformData &platform_data, osd_window const &window);
+
+ bool m_bgfx_library_initialized;
+};
+
//============================================================
-// STATICS
+// video_bgfx::init
//============================================================
-uint32_t renderer_bgfx::s_current_view = 0;
-bool renderer_bgfx::s_bgfx_library_initialized = false;
-uint32_t renderer_bgfx::s_width[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-uint32_t renderer_bgfx::s_height[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+int video_bgfx::init(osd_interface &osd, osd_options const &options)
+{
+ m_options = &options;
+ m_persistent_settings = util::xml::file::create();
+
+ // Check that BGFX directory exists
+ char const *const bgfx_path = options.bgfx_path();
+ osd::directory::ptr directory = osd::directory::open(bgfx_path);
+ if (!directory)
+ {
+ osd_printf_error("Unable to find the BGFX path %s, please install it or fix the bgfx_path setting to use the BGFX renderer.\n", bgfx_path);
+ return -1;
+ }
+ directory.reset();
+
+ // Verify baseline shaders
+ const bool gui_opaque_valid = effect_manager::validate_effect(options, "gui_opaque");
+ const bool gui_blend_valid = effect_manager::validate_effect(options, "gui_blend");
+ const bool gui_multiply_valid = effect_manager::validate_effect(options, "gui_multiply");
+ const bool gui_add_valid = effect_manager::validate_effect(options, "gui_add");
+ const bool all_gui_valid = gui_opaque_valid && gui_blend_valid && gui_multiply_valid && gui_add_valid;
+
+ const bool screen_opaque_valid = effect_manager::validate_effect(options, "screen_opaque");
+ const bool screen_blend_valid = effect_manager::validate_effect(options, "screen_blend");
+ const bool screen_multiply_valid = effect_manager::validate_effect(options, "screen_multiply");
+ const bool screen_add_valid = effect_manager::validate_effect(options, "screen_add");
+ const bool all_screen_valid = screen_opaque_valid && screen_blend_valid && screen_multiply_valid && screen_add_valid;
+
+ if (!all_gui_valid || !all_screen_valid)
+ {
+ osd_printf_error("BGFX: Unable to load required shaders. Please update the %s folder or adjust your bgfx_path setting.\n", options.bgfx_path());
+ return -1;
+ }
+
+ m_max_texture_size = 16384; // Relatively safe default on modern GPUs
+
+ // Register configuration handlers - do this last because it can't be undone
+ downcast<osd_common_t &>(osd).machine().configuration().config_register(
+ "bgfx",
+ configuration_manager::load_delegate(&video_bgfx::load_config, this),
+ configuration_manager::save_delegate(&video_bgfx::save_config, this));
+
+ return 0;
+}
+
//============================================================
-// renderer_bgfx - constructor
+// video_bgfx::exit
//============================================================
-renderer_bgfx::renderer_bgfx(std::shared_ptr<osd_window> w)
- : osd_renderer(w, FLAG_NONE)
- , m_options(downcast<osd_options &>(w->machine().options()))
- , m_framebuffer(nullptr)
- , m_texture_cache(nullptr)
- , m_dimensions(0, 0)
- , m_textures(nullptr)
- , m_targets(nullptr)
- , m_shaders(nullptr)
- , m_effects(nullptr)
- , m_chains(nullptr)
- , m_ortho_view(nullptr)
- , m_max_view(0)
- , m_avi_view(nullptr)
- , m_avi_writer(nullptr)
- , m_avi_target(nullptr)
+void video_bgfx::exit()
{
+ assert(!has_active_renderers());
+
+ if (m_bgfx_library_initialized)
+ {
+ osd_printf_verbose("Shutting down BGFX library\n");
+ imguiDestroy();
+ bgfx::shutdown();
+ m_bgfx_library_initialized = false;
+ }
+ m_max_texture_size = 0;
+ m_persistent_settings.reset();
+ m_options = nullptr;
}
+
//============================================================
-// renderer_bgfx - destructor
+// video_bgfx::create
//============================================================
-renderer_bgfx::~renderer_bgfx()
+std::unique_ptr<osd_renderer> video_bgfx::create(osd_window &window)
{
- bgfx::reset(0, 0, BGFX_RESET_NONE);
-
- if (m_avi_writer != nullptr && m_avi_writer->recording())
+ // start BGFX if this is the first window
+ if (!m_bgfx_library_initialized)
{
- m_avi_writer->stop();
+ assert(window.index() == 0); // bad things will happen otherwise
+ assert(!has_active_renderers());
- m_targets->destroy_target("avibuffer0");
- m_avi_target = nullptr;
+ osd_printf_verbose("Initializing BGFX library\n");
+ if (!init_bgfx_library(window))
+ {
+ osd_printf_error("BGFX library initialization failed\n");
+ return nullptr;
+ }
+ m_bgfx_library_initialized = true;
+ }
- bgfx::destroy(m_avi_texture);
+ return std::make_unique<renderer_bgfx>(window, static_cast<renderer_bgfx::parent_module &>(*this));
+}
- delete m_avi_writer;
- delete [] m_avi_data;
- delete m_avi_view;
+
+//============================================================
+// video_bgfx::last_renderer_destroyed
+//============================================================
+
+void video_bgfx::last_renderer_destroyed()
+{
+ if (m_bgfx_library_initialized)
+ {
+ osd_printf_verbose("No more renderers - shutting down BGFX library\n");
+ imguiDestroy();
+ bgfx::shutdown();
+ m_bgfx_library_initialized = false;
+ m_max_texture_size = 0;
}
+}
- // Cleanup.
- if (m_ortho_view)
- delete m_ortho_view;
- delete m_chains;
- delete m_effects;
- delete m_shaders;
- delete m_textures;
- delete m_targets;
+//============================================================
+// video_bgfx::load_config
+//============================================================
+
+void video_bgfx::load_config(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode)
+{
+ if ((cfg_type == config_type::SYSTEM) && parentnode)
+ m_load_notifier(*parentnode);
}
+//============================================================
+// video_bgfx::save_config
+//============================================================
+
+void video_bgfx::save_config(config_type cfg_type, util::xml::data_node *parentnode)
+{
+ if (cfg_type == config_type::SYSTEM)
+ m_save_notifier(*parentnode);
+}
+
//============================================================
-// renderer_bgfx::init_bgfx_library
+// video_bgfx::init_bgfx_library
//============================================================
-void renderer_bgfx::init_bgfx_library()
+bool video_bgfx::init_bgfx_library(osd_window &window)
{
- std::string backend(m_options.bgfx_backend());
+ osd_dim const wdim = window.get_size();
bgfx::Init init;
init.type = bgfx::RendererType::Count;
init.vendorId = BGFX_PCI_ID_NONE;
- init.resolution.width = s_width[0];
- init.resolution.height = s_height[0];
+ init.resolution.width = wdim.width();
+ init.resolution.height = wdim.height();
init.resolution.numBackBuffers = 1;
- init.resolution.reset = BGFX_RESET_NONE;
- init.platformData = m_platform_data;
- if (backend == "auto")
+ init.resolution.reset = video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE;
+ if (!set_platform_data(init.platformData, window))
{
+ osd_printf_error("Setting BGFX platform data failed\n");
+ return false;
}
+
+ std::string_view const backend(m_options->bgfx_backend());
+ if (backend == "auto")
+ ; // do nothing
else if (backend == "dx9" || backend == "d3d9")
- {
init.type = bgfx::RendererType::Direct3D9;
- }
else if (backend == "dx11" || backend == "d3d11")
- {
init.type = bgfx::RendererType::Direct3D11;
- }
else if (backend == "dx12" || backend == "d3d12")
- {
init.type = bgfx::RendererType::Direct3D12;
- }
else if (backend == "gles")
- {
init.type = bgfx::RendererType::OpenGLES;
- }
else if (backend == "glsl" || backend == "opengl")
- {
init.type = bgfx::RendererType::OpenGL;
- }
else if (backend == "vulkan")
- {
init.type = bgfx::RendererType::Vulkan;
- }
else if (backend == "metal")
- {
init.type = bgfx::RendererType::Metal;
- }
else
- {
- osd_printf_verbose("Unknown backend type '%s', going with auto-detection.\n", backend.c_str());
- }
+ osd_printf_warning("Unknown BGFX backend type '%s', going with auto-detection.\n", backend);
- bgfx::init(init);
- bgfx::reset(s_width[0], s_height[0], video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE);
- // Enable debug text if requested.
- bool bgfx_debug = m_options.bgfx_debug();
+ if (!bgfx::init(init))
+ return false;
+
+ bgfx::reset(wdim.width(), wdim.height(), video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE);
+
+ // Enable debug text if requested
+ bool bgfx_debug = m_options->bgfx_debug();
bgfx::setDebug(bgfx_debug ? BGFX_DEBUG_STATS : BGFX_DEBUG_TEXT);
+ // Get actual maximum texture size
+ bgfx::Caps const *const caps = bgfx::getCaps();
+ m_max_texture_size = caps->limits.maxTextureSize;
+
ScreenVertex::init();
imguiCreate();
-}
+ return true;
+}
//============================================================
-// Utilities for setting up window handles
+// Helper for creating a wayland window
//============================================================
-#ifdef OSD_WINDOWS
-inline void winSetHwnd(bgfx::PlatformData &platform_data, ::HWND _window)
-{
- platform_data.ndt = NULL;
- platform_data.nwh = _window;
- platform_data.context = NULL;
- platform_data.backBuffer = NULL;
- platform_data.backBufferDS = NULL;
- bgfx::setPlatformData(platform_data);
-}
-#elif defined(OSD_MAC)
-inline void macSetWindow(bgfx::PlatformData &platform_data, void *_window)
-{
- platform_data.ndt = NULL;
- platform_data.nwh = GetOSWindow(_window);
- platform_data.context = NULL;
- platform_data.backBuffer = NULL;
- platform_data.backBufferDS = NULL;
- bgfx::setPlatformData(platform_data);
-}
-#elif defined(OSD_SDL)
-static void* sdlNativeWindowHandle(SDL_Window* _window)
+#if defined(SDLMAME_USE_WAYLAND)
+wl_egl_window *create_wl_egl_window(SDL_Window *window, struct wl_surface *surface)
{
- SDL_SysWMinfo wmi;
- SDL_VERSION(&wmi.version);
- if (!SDL_GetWindowWMInfo(_window, &wmi))
+ if (!surface)
{
+ osd_printf_error("Wayland surface missing, aborting\n");
return nullptr;
}
-
-# if BX_PLATFORM_LINUX || BX_PLATFORM_BSD || BX_PLATFORM_RPI
- return (void*)wmi.info.x11.window;
-# elif BX_PLATFORM_OSX
- return wmi.info.cocoa.window;
-# elif BX_PLATFORM_WINDOWS
- return wmi.info.win.window;
-# elif BX_PLATFORM_EMSCRIPTEN || BX_PLATFORM_ANDROID
- return nullptr;
-# endif // BX_PLATFORM_
+ wl_egl_window *win_impl = (wl_egl_window *)SDL_GetWindowData(window, "wl_egl_window");
+ if (!win_impl)
+ {
+ int width, height;
+ SDL_GetWindowSize(window, &width, &height);
+ win_impl = wl_egl_window_create(surface, width, height);
+ if (!win_impl)
+ {
+ osd_printf_error("Creating wayland window failed\n");
+ return nullptr;
+ }
+ SDL_SetWindowData(window, "wl_egl_window", win_impl);
+ }
+ return win_impl;
}
+#endif
-inline bool sdlSetWindow(bgfx::PlatformData &platform_data, SDL_Window* _window)
+
+//============================================================
+// Utility for setting up window handle
+//============================================================
+
+bool video_bgfx::set_platform_data(bgfx::PlatformData &platform_data, osd_window const &window)
{
+#if defined(OSD_WINDOWS)
+ platform_data.ndt = nullptr;
+ platform_data.nwh = dynamic_cast<win_window_info const &>(window).platform_window();
+#elif defined(OSD_MAC)
+ platform_data.ndt = nullptr;
+ platform_data.nwh = GetOSWindow(dynamic_cast<mac_window_info const &>(window).platform_window());
+#else // defined(OSD_*)
SDL_SysWMinfo wmi;
SDL_VERSION(&wmi.version);
- if (!SDL_GetWindowWMInfo(_window, &wmi) )
+ if (!SDL_GetWindowWMInfo(dynamic_cast<sdl_window_info const &>(window).platform_window(), &wmi))
{
+ osd_printf_error("BGFX: Error getting SDL window info: %s\n", SDL_GetError());
return false;
}
-# if BX_PLATFORM_LINUX || BX_PLATFORM_BSD
- platform_data.ndt = wmi.info.x11.display;
- platform_data.nwh = (void*)(uintptr_t)wmi.info.x11.window;
-# elif BX_PLATFORM_OSX
- platform_data.ndt = NULL;
- platform_data.nwh = wmi.info.cocoa.window;
-# elif BX_PLATFORM_WINDOWS
- platform_data.ndt = NULL;
- platform_data.nwh = wmi.info.win.window;
-# endif // BX_PLATFORM_
- platform_data.context = NULL;
- platform_data.backBuffer = NULL;
- platform_data.backBufferDS = NULL;
+ switch (wmi.subsystem)
+ {
+#if defined(SDL_VIDEO_DRIVER_WINDOWS)
+ case SDL_SYSWM_WINDOWS:
+ platform_data.ndt = nullptr;
+ platform_data.nwh = wmi.info.win.window;
+ break;
+#endif
+#if defined(SDL_VIDEO_DRIVER_X11)
+ case SDL_SYSWM_X11:
+ platform_data.ndt = wmi.info.x11.display;
+ platform_data.nwh = (void *)uintptr_t(wmi.info.x11.window);
+ break;
+#endif
+#if defined(SDL_VIDEO_DRIVER_COCOA)
+ case SDL_SYSWM_COCOA:
+ platform_data.ndt = nullptr;
+ platform_data.nwh = wmi.info.cocoa.window;
+ break;
+#endif
+#if defined(SDL_VIDEO_DRIVER_WAYLAND) && SDL_VERSION_ATLEAST(2, 0, 16) && defined(SDLMAME_USE_WAYLAND)
+ case SDL_SYSWM_WAYLAND:
+ platform_data.ndt = wmi.info.wl.display;
+ platform_data.nwh = create_wl_egl_window(dynamic_cast<sdl_window_info const &>(window).platform_window(), wmi.info.wl.surface);
+ if (!platform_data.nwh)
+ {
+ osd_printf_error("BGFX: Error creating a Wayland window\n");
+ return false;
+ }
+ platform_data.type = bgfx::NativeWindowHandleType::Wayland;
+ break;
+#endif
+#if defined(SDL_VIDEO_DRIVER_ANDROID)
+ case SDL_SYSWM_ANDROID:
+ platform_data.ndt = nullptr;
+ platform_data.nwh = wmi.info.android.window;
+ break;
+#endif
+ default:
+ osd_printf_error("BGFX: Unsupported SDL window manager type %u\n", wmi.subsystem);
+ return false;
+ }
+#endif // defined(OSD_*)
+
+ platform_data.context = nullptr;
+ platform_data.backBuffer = nullptr;
+ platform_data.backBufferDS = nullptr;
bgfx::setPlatformData(platform_data);
return true;
}
-#endif
+
+} // anonymous namespace
+
+} // namespace osd
+
+MODULE_DEFINITION(RENDERER_BGFX, osd::video_bgfx)
//============================================================
-// renderer_bgfx::create
+// CONSTANTS
//============================================================
-int renderer_bgfx::create()
+uint16_t const renderer_bgfx::CACHE_SIZE = 1024;
+uint32_t const renderer_bgfx::PACKABLE_SIZE = 128;
+uint32_t const renderer_bgfx::WHITE_HASH = 0x87654321;
+char const *const renderer_bgfx::WINDOW_PREFIX = "Window 0, ";
+
+
+
+//============================================================
+// MACROS
+//============================================================
+
+#define GIBBERISH (0)
+#define SCENE_VIEW (0)
+
+
+
+//============================================================
+// STATICS
+//============================================================
+
+uint32_t renderer_bgfx::s_current_view = 0;
+uint32_t renderer_bgfx::s_width[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+uint32_t renderer_bgfx::s_height[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+
+
+//============================================================
+// helper for getting native platform window
+//============================================================
+
+#ifdef OSD_SDL
+static std::pair<void *, bool> sdlNativeWindowHandle(SDL_Window *window)
{
- std::shared_ptr<osd_window> win = assert_window();
- osd_dim wdim = win->get_size();
- s_width[win->index()] = wdim.width();
- s_height[win->index()] = wdim.height();
- m_dimensions = wdim;
+ SDL_SysWMinfo wmi;
+ SDL_VERSION(&wmi.version);
+ if (!SDL_GetWindowWMInfo(window, &wmi))
+ return std::make_pair(nullptr, false);
- if (s_bgfx_library_initialized)
+ switch (wmi.subsystem)
{
- exit();
+#if defined(SDL_VIDEO_DRIVER_WINDOWS)
+ case SDL_SYSWM_WINDOWS:
+ return std::make_pair(wmi.info.win.window, true);
+#endif
+#if defined(SDL_VIDEO_DRIVER_X11)
+ case SDL_SYSWM_X11:
+ return std::make_pair((void *)uintptr_t(wmi.info.x11.window), true);
+#endif
+#if defined(SDL_VIDEO_DRIVER_COCOA)
+ case SDL_SYSWM_COCOA:
+ return std::make_pair(wmi.info.cocoa.window, true);
+#endif
+#if defined(SDL_VIDEO_DRIVER_WAYLAND) && SDL_VERSION_ATLEAST(2, 0, 16) && defined(SDLMAME_USE_WAYLAND)
+ case SDL_SYSWM_WAYLAND:
+ {
+ void *const platform_window = osd::create_wl_egl_window(window, wmi.info.wl.surface);
+ return std::make_pair(platform_window, platform_window != nullptr);
+ }
+#endif
+#if defined(SDL_VIDEO_DRIVER_ANDROID)
+ case SDL_SYSWM_ANDROID:
+ return std::make_pair(wmi.info.android.window, true);
+#endif
+ default:
+ return std::make_pair(nullptr, false);
}
+}
+#endif // OSD_SDL
+
+
+
+//============================================================
+// renderer_bgfx - constructor
+//============================================================
- if (win->index() == 0)
+renderer_bgfx::renderer_bgfx(osd_window &window, parent_module &parent)
+ : osd_renderer(window)
+ , m_module(parent)
+ , m_framebuffer(nullptr)
+ , m_texture_cache(nullptr)
+ , m_dimensions(0, 0)
+ , m_max_view(0)
+ , m_avi_view(nullptr)
+ , m_avi_writer(nullptr)
+ , m_avi_target(nullptr)
+ , m_load_sub(parent.subscribe_load(&renderer_bgfx::load_config, this))
+ , m_save_sub(parent.subscribe_save(&renderer_bgfx::save_config, this))
+{
+ // load settings if recreated after fullscreen toggle
+ util::xml::data_node *windownode = m_module().persistent_settings().get_child("window");
+ while (windownode)
{
-#ifdef OSD_WINDOWS
- winSetHwnd(m_platform_data, std::static_pointer_cast<win_window_info>(win)->platform_window());
-#elif defined(OSD_MAC)
- macSetWindow(m_platform_data, std::static_pointer_cast<mac_window_info>(win)->platform_window());
-#else
- sdlSetWindow(m_platform_data, std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window());
-#endif
+ if (windownode->get_attribute_int("index", -1) != window.index())
+ {
+ windownode = windownode->get_next_sibling("window");
+ }
+ else
+ {
+ if (!m_config)
+ {
+ m_config = util::xml::file::create();
+ windownode->copy_into(*m_config);
+ }
+ std::exchange(windownode, windownode->get_next_sibling("window"))->delete_node();
+ }
+ }
+}
+
- init_bgfx_library();
+
+//============================================================
+// renderer_bgfx - destructor
+//============================================================
+
+renderer_bgfx::~renderer_bgfx()
+{
+ // persist settings across fullscreen toggle
+ if (m_config)
+ m_config->get_first_child()->copy_into(m_module().persistent_settings());
+ else if (m_chains)
+ m_chains->save_config(m_module().persistent_settings());
+
+ bgfx::reset(0, 0, BGFX_RESET_NONE);
+
+ if (m_avi_writer != nullptr && m_avi_writer->recording())
+ {
+ m_avi_writer->stop();
+
+ m_targets->destroy_target("avibuffer0");
+ m_avi_target = nullptr;
+
+ bgfx::destroy(m_avi_texture);
+
+ delete m_avi_writer;
+ delete [] m_avi_data;
+ delete m_avi_view;
}
+}
- // finish creating the renderer
- m_textures = new texture_manager();
- m_targets = new target_manager(*m_textures);
- m_shaders = new shader_manager();
- m_effects = new effect_manager(*m_shaders);
- // Create program from shaders.
- m_gui_effect[0] = m_effects->get_or_load_effect(m_options, "gui_opaque");
- m_gui_effect[1] = m_effects->get_or_load_effect(m_options, "gui_blend");
- m_gui_effect[2] = m_effects->get_or_load_effect(m_options, "gui_multiply");
- m_gui_effect[3] = m_effects->get_or_load_effect(m_options, "gui_add");
+//============================================================
+// renderer_bgfx::create
+//============================================================
+
+int renderer_bgfx::create()
+{
+ const osd_dim wdim = window().get_size();
+ s_width[window().index()] = wdim.width();
+ s_height[window().index()] = wdim.height();
+ m_dimensions = wdim;
- m_screen_effect[0] = m_effects->get_or_load_effect(m_options, "screen_opaque");
- m_screen_effect[1] = m_effects->get_or_load_effect(m_options, "screen_blend");
- m_screen_effect[2] = m_effects->get_or_load_effect(m_options, "screen_multiply");
- m_screen_effect[3] = m_effects->get_or_load_effect(m_options, "screen_add");
+ // finish creating the renderer
+ m_textures = std::make_unique<texture_manager>();
+ m_targets = std::make_unique<target_manager>(*m_textures);
- if (win->index() != 0)
+ if (window().index() != 0)
{
#ifdef OSD_WINDOWS
- m_framebuffer = m_targets->create_backbuffer(std::static_pointer_cast<win_window_info>(win)->platform_window(), s_width[win->index()], s_height[win->index()]);
+ m_framebuffer = m_targets->create_backbuffer(dynamic_cast<win_window_info &>(window()).platform_window(), s_width[window().index()], s_height[window().index()]);
#elif defined(OSD_MAC)
- m_framebuffer = m_targets->create_backbuffer(GetOSWindow(std::static_pointer_cast<mac_window_info>(win)->platform_window()), s_width[win->index()], s_height[win->index()]);
+ m_framebuffer = m_targets->create_backbuffer(GetOSWindow(dynamic_cast<mac_window_info &>(window()).platform_window()), s_width[window().index()], s_height[window().index()]);
#else
- m_framebuffer = m_targets->create_backbuffer(sdlNativeWindowHandle(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window()), s_width[win->index()], s_height[win->index()]);
+ auto const [winhdl, success] = sdlNativeWindowHandle(dynamic_cast<sdl_window_info &>(window()).platform_window());
+ if (!success)
+ {
+ m_targets.reset();
+ m_textures.reset();
+ return -1;
+ }
+ m_framebuffer = m_targets->create_backbuffer(winhdl, s_width[window().index()], s_height[window().index()]);
#endif
- bgfx::touch(win->index());
+ bgfx::touch(window().index());
- if (m_ortho_view) {
+ if (m_ortho_view)
m_ortho_view->set_backbuffer(m_framebuffer);
- }
}
- m_chains = new chain_manager(win->machine(), m_options, *m_textures, *m_targets, *m_effects, win->index(), *this);
+ m_shaders = std::make_unique<shader_manager>();
+ m_effects = std::make_unique<effect_manager>(*m_shaders);
+
+ // Create program from shaders.
+ m_gui_effect[0] = m_effects->get_or_load_effect(m_module().options(), "gui_opaque");
+ m_gui_effect[1] = m_effects->get_or_load_effect(m_module().options(), "gui_blend");
+ m_gui_effect[2] = m_effects->get_or_load_effect(m_module().options(), "gui_multiply");
+ m_gui_effect[3] = m_effects->get_or_load_effect(m_module().options(), "gui_add");
+
+ m_screen_effect[0] = m_effects->get_or_load_effect(m_module().options(), "screen_opaque");
+ m_screen_effect[1] = m_effects->get_or_load_effect(m_module().options(), "screen_blend");
+ m_screen_effect[2] = m_effects->get_or_load_effect(m_module().options(), "screen_multiply");
+ m_screen_effect[3] = m_effects->get_or_load_effect(m_module().options(), "screen_add");
+
+ const uint32_t max_prescale_size = std::min(2u * std::max(wdim.width(), wdim.height()), m_module().max_texture_size());
+ m_chains = std::make_unique<chain_manager>(
+ window().machine(),
+ m_module().options(),
+ *m_textures,
+ *m_targets,
+ *m_effects,
+ window().index(),
+ *this,
+ window().prescale(),
+ max_prescale_size);
m_sliders_dirty = true;
uint32_t flags = BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP | BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT;
- m_texture_cache = m_textures->create_texture("#cache", bgfx::TextureFormat::BGRA8, CACHE_SIZE, CACHE_SIZE, nullptr, flags);
+ m_texture_cache = m_textures->create_texture("#cache", bgfx::TextureFormat::BGRA8, CACHE_SIZE, 0, CACHE_SIZE, nullptr, 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));
@@ -365,16 +723,12 @@ int renderer_bgfx::create()
void renderer_bgfx::record()
{
- std::shared_ptr<osd_window> win = assert_window();
-
- if (win->index() > 0)
- {
+ if (window().index() > 0)
return;
- }
if (m_avi_writer == nullptr)
{
- m_avi_writer = new avi_write(win->machine(), s_width[0], s_height[0]);
+ m_avi_writer = new avi_write(window().machine(), s_width[0], s_height[0]);
m_avi_data = new uint8_t[s_width[0] * s_height[0] * 4];
m_avi_bitmap.allocate(s_width[0], s_height[0]);
}
@@ -390,8 +744,8 @@ void renderer_bgfx::record()
}
else
{
- m_avi_writer->record(m_options.bgfx_avi_name());
- m_avi_target = m_targets->create_target("avibuffer", bgfx::TextureFormat::BGRA8, s_width[0], s_height[0], TARGET_STYLE_CUSTOM, false, true, 1, 0);
+ m_avi_writer->record(m_module().options().bgfx_avi_name());
+ m_avi_target = m_targets->create_target("avibuffer", bgfx::TextureFormat::BGRA8, s_width[0], s_height[0], 1, 1, TARGET_STYLE_CUSTOM, false, true, 1, 0);
m_avi_texture = bgfx::createTexture2D(s_width[0], s_height[0], false, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_BLIT_DST | BGFX_TEXTURE_READ_BACK);
if (m_avi_view == nullptr)
@@ -401,47 +755,6 @@ void renderer_bgfx::record()
}
}
-bool renderer_bgfx::init(running_machine &machine)
-{
- osd_options &options = downcast<osd_options &>(machine.options());
- const char *bgfx_path = options.bgfx_path();
-
- osd::directory::ptr directory = osd::directory::open(bgfx_path);
- if (directory == nullptr)
- {
- osd_printf_error("Unable to find the BGFX path %s, please install it or fix the bgfx_path setting to use the BGFX renderer.\n", bgfx_path);
- return true;
- }
-
- // Verify baseline shaders.
- const bool gui_opaque_valid = effect_manager::validate_effect(options, "gui_opaque");
- const bool gui_blend_valid = effect_manager::validate_effect(options, "gui_blend");
- const bool gui_multiply_valid = effect_manager::validate_effect(options, "gui_multiply");
- const bool gui_add_valid = effect_manager::validate_effect(options, "gui_add");
- const bool all_gui_valid = gui_opaque_valid && gui_blend_valid && gui_multiply_valid && gui_add_valid;
-
- const bool screen_opaque_valid = effect_manager::validate_effect(options, "screen_opaque");
- const bool screen_blend_valid = effect_manager::validate_effect(options, "screen_blend");
- const bool screen_multiply_valid = effect_manager::validate_effect(options, "screen_multiply");
- const bool screen_add_valid = effect_manager::validate_effect(options, "screen_add");
- const bool all_screen_valid = screen_opaque_valid && screen_blend_valid && screen_multiply_valid && screen_add_valid;
-
- if (!all_gui_valid || !all_screen_valid)
- {
- osd_printf_error("BGFX: Unable to load required shaders. Please update the %s folder or adjust your bgfx_path setting.\n", options.bgfx_path());
- return true;
- }
-
- return false;
-}
-
-void renderer_bgfx::exit()
-{
- imguiDestroy();
- bgfx::shutdown();
- s_bgfx_library_initialized = false;
-}
-
//============================================================
// drawsdl_xy_to_render_target
//============================================================
@@ -480,15 +793,6 @@ void renderer_bgfx::put_packed_quad(render_primitive *prim, uint32_t hash, Scree
float u[4] = { u0, u1, u0, u1 };
float v[4] = { v0, v0, v1, v1 };
- if (bgfx::getRendererType() == bgfx::RendererType::Direct3D9)
- {
- for (int i = 0; i < 4; i++)
- {
- u[i] += 0.5f / size;
- v[i] += 0.5f / size;
- }
- }
-
if (PRIMFLAG_GET_TEXORIENT(prim->flags) & ORIENTATION_SWAP_XY)
{
std::swap(u[1], u[2]);
@@ -529,7 +833,7 @@ void renderer_bgfx::vertex(ScreenVertex* vertex, float x, float y, float z, uint
vertex->m_v = v;
}
-void renderer_bgfx::render_post_screen_quad(int view, render_primitive* prim, bgfx::TransientVertexBuffer* buffer, int32_t screen)
+void renderer_bgfx::render_post_screen_quad(int view, render_primitive* prim, bgfx::TransientVertexBuffer* buffer, int32_t screen, int window_index)
{
auto* vertices = reinterpret_cast<ScreenVertex*>(buffer->data);
@@ -554,6 +858,15 @@ void renderer_bgfx::render_post_screen_quad(int view, render_primitive* prim, bg
uint32_t blend = PRIMFLAG_GET_BLENDMODE(prim->flags);
bgfx::setVertexBuffer(0,buffer);
bgfx::setTexture(0, m_screen_effect[blend]->uniform("s_tex")->handle(), m_targets->target(screen, "output")->texture(), texture_flags);
+
+ bgfx_uniform* inv_view_dims = m_screen_effect[blend]->uniform("u_inv_view_dims");
+ if (inv_view_dims)
+ {
+ float values[2] = { -1.0f / s_width[window_index], 1.0f / s_height[window_index] };
+ inv_view_dims->set(values, sizeof(float) * 2);
+ inv_view_dims->upload();
+ }
+
m_screen_effect[blend]->submit(m_ortho_view->get_index());
}
@@ -563,7 +876,7 @@ void renderer_bgfx::render_avi_quad()
m_avi_view->setup();
bgfx::setViewRect(s_current_view, 0, 0, s_width[0], s_height[0]);
- bgfx::setViewClear(s_current_view, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x00000000, 1.0f, 0);
+ bgfx::setViewClear(s_current_view, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x000000ff, 1.0f, 0);
bgfx::TransientVertexBuffer buffer;
bgfx::allocTransientVertexBuffer(&buffer, 6, ScreenVertex::ms_decl);
@@ -584,11 +897,21 @@ void renderer_bgfx::render_avi_quad()
bgfx::setVertexBuffer(0,&buffer);
bgfx::setTexture(0, m_gui_effect[PRIMFLAG_GET_BLENDMODE(BLENDMODE_NONE)]->uniform("s_tex")->handle(), m_avi_target->texture());
- m_gui_effect[PRIMFLAG_GET_BLENDMODE(BLENDMODE_NONE)]->submit(s_current_view);
+
+ bgfx_effect* effect = m_gui_effect[PRIMFLAG_GET_BLENDMODE(BLENDMODE_NONE)];
+ bgfx_uniform* inv_view_dims = effect->uniform("u_inv_view_dims");
+ if (inv_view_dims)
+ {
+ float values[2] = { -1.0f / s_width[0], 1.0f / s_height[0] };
+ inv_view_dims->set(values, sizeof(float) * 2);
+ inv_view_dims->upload();
+ }
+
+ effect->submit(s_current_view);
s_current_view++;
}
-void renderer_bgfx::render_textured_quad(render_primitive* prim, bgfx::TransientVertexBuffer* buffer)
+void renderer_bgfx::render_textured_quad(render_primitive* prim, bgfx::TransientVertexBuffer* buffer, int window_index)
{
auto* vertices = reinterpret_cast<ScreenVertex*>(buffer->data);
uint32_t rgba = u32Color(prim->color.r * 255, prim->color.g * 255, prim->color.b * 255, prim->color.a * 255);
@@ -625,7 +948,7 @@ void renderer_bgfx::render_textured_quad(render_primitive* prim, bgfx::Transient
else
{
texture = m_textures->create_or_update_mame_texture(prim->flags & PRIMFLAG_TEXFORMAT_MASK
- , tex_width, tex_height, prim->texture.rowpixels, prim->texture.palette, prim->texture.base, prim->texture.seqid
+ , tex_width, prim->texture.width_margin, tex_height, prim->texture.rowpixels, prim->texture.palette, prim->texture.base, prim->texture.seqid
, texture_flags, prim->texture.unique_id, prim->texture.old_id);
}
@@ -634,6 +957,15 @@ void renderer_bgfx::render_textured_quad(render_primitive* prim, bgfx::Transient
uint32_t blend = PRIMFLAG_GET_BLENDMODE(prim->flags);
bgfx::setVertexBuffer(0,buffer);
bgfx::setTexture(0, effects[blend]->uniform("s_tex")->handle(), texture);
+
+ bgfx_uniform* inv_view_dims = effects[blend]->uniform("u_inv_view_dims");
+ if (inv_view_dims)
+ {
+ float values[2] = { -1.0f / s_width[window_index], 1.0f / s_height[window_index] };
+ inv_view_dims->set(values, sizeof(float) * 2);
+ inv_view_dims->upload();
+ }
+
effects[blend]->submit(m_ortho_view->get_index());
if (is_screen)
@@ -852,16 +1184,13 @@ uint32_t renderer_bgfx::u32Color(uint32_t r, uint32_t g, uint32_t b, uint32_t a
int renderer_bgfx::draw(int update)
{
- std::shared_ptr<osd_window> win = assert_window();
-
- int window_index = win->index();
+ int window_index = window().index();
m_seen_views.clear();
- if (m_ortho_view) {
+ if (m_ortho_view)
m_ortho_view->set_index(UINT_MAX);
- }
- osd_dim wdim = win->get_size();
+ osd_dim wdim = window().get_size();
s_width[window_index] = wdim.width();
s_height[window_index] = wdim.height();
@@ -871,9 +1200,9 @@ int renderer_bgfx::draw(int update)
s_current_view = 0;
}
- win->m_primlist->acquire_lock();
- uint32_t num_screens = m_chains->update_screen_textures(s_current_view, win->m_primlist->first(), *win.get());
- win->m_primlist->release_lock();
+ window().m_primlist->acquire_lock();
+ uint32_t num_screens = m_chains->update_screen_textures(s_current_view, window().m_primlist->first(), window());
+ window().m_primlist->release_lock();
bool skip_frame = update_dimensions();
if (skip_frame)
@@ -883,7 +1212,21 @@ int renderer_bgfx::draw(int update)
if (num_screens)
{
- uint32_t chain_view_count = m_chains->process_screen_chains(s_current_view, *win.get());
+ // Restore config after counting screens the first time
+ // Doing this here is hacky - it means config is restored at the wrong
+ // time if the initial view has no screens and the user switches to a
+ // view with screens. The trouble is there's no real interface between
+ // the render targets and the renderer so we don't actually know when
+ // we're first called on to render a live view (as opposed to an info
+ // screen).
+ if (m_config)
+ {
+ osd_printf_verbose("BGFX: Applying configuration for window %d\n", window().index());
+ m_chains->load_config(*m_config->get_first_child());
+ m_config.reset();
+ }
+
+ uint32_t chain_view_count = m_chains->process_screen_chains(s_current_view, window());
s_current_view += chain_view_count;
}
@@ -896,12 +1239,12 @@ int renderer_bgfx::draw(int update)
s_current_view = m_max_view;
}
- win->m_primlist->acquire_lock();
+ window().m_primlist->acquire_lock();
// Mark our texture atlas as dirty if we need to do so
bool atlas_valid = update_atlas();
- render_primitive *prim = win->m_primlist->first();
+ render_primitive *prim = window().m_primlist->first();
std::vector<void*> sources;
while (prim != nullptr)
{
@@ -926,12 +1269,21 @@ int renderer_bgfx::draw(int update)
}
}
- buffer_status status = buffer_primitives(atlas_valid, &prim, &buffer, screen);
+ buffer_status status = buffer_primitives(atlas_valid, &prim, &buffer, screen, window_index);
if (status != BUFFER_EMPTY && status != BUFFER_SCREEN)
{
- bgfx::setVertexBuffer(0,&buffer);
+ bgfx::setVertexBuffer(0, &buffer);
bgfx::setTexture(0, m_gui_effect[blend]->uniform("s_tex")->handle(), m_texture_cache->texture());
+
+ bgfx_uniform* inv_view_dims = m_gui_effect[blend]->uniform("u_inv_view_dims");
+ if (inv_view_dims)
+ {
+ float values[2] = { -1.0f / s_width[window_index], 1.0f / s_height[window_index] };
+ inv_view_dims->set(values, sizeof(float) * 2);
+ inv_view_dims->upload();
+ }
+
m_gui_effect[blend]->submit(m_ortho_view->get_index());
}
@@ -941,7 +1293,7 @@ int renderer_bgfx::draw(int update)
}
}
- win->m_primlist->release_lock();
+ window().m_primlist->release_lock();
// This dummy draw call is here to make sure that view 0 is cleared
// if no other draw calls are submitted to view 0.
@@ -959,7 +1311,7 @@ int renderer_bgfx::draw(int update)
}
}
- if (win->index() == osd_common_t::s_window_list.size() - 1)
+ if (window().index() == osd_common_t::window_list().size() - 1)
{
bgfx::frame();
}
@@ -989,8 +1341,7 @@ void renderer_bgfx::update_recording()
void renderer_bgfx::add_audio_to_recording(const int16_t *buffer, int samples_this_frame)
{
- std::shared_ptr<osd_window> win = assert_window();
- if (m_avi_writer != nullptr && m_avi_writer->recording() && win->index() == 0)
+ if (m_avi_writer != nullptr && m_avi_writer->recording() && window().index() == 0)
{
m_avi_writer->audio_frame(buffer, samples_this_frame);
}
@@ -998,9 +1349,7 @@ void renderer_bgfx::add_audio_to_recording(const int16_t *buffer, int samples_th
bool renderer_bgfx::update_dimensions()
{
- std::shared_ptr<osd_window> win = assert_window();
-
- const uint32_t window_index = win->index();
+ const uint32_t window_index = window().index();
const uint32_t width = s_width[window_index];
const uint32_t height = s_height[window_index];
@@ -1009,15 +1358,14 @@ bool renderer_bgfx::update_dimensions()
bgfx::reset(width, height, video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE);
m_dimensions = osd_dim(width, height);
- if (win->index() != 0)
+ if (window().index() != 0)
{
- delete m_framebuffer;
#ifdef OSD_WINDOWS
- m_framebuffer = m_targets->create_backbuffer(std::static_pointer_cast<win_window_info>(win)->platform_window(), width, height);
+ m_framebuffer = m_targets->create_backbuffer(dynamic_cast<win_window_info &>(window()).platform_window(), width, height);
#elif defined(OSD_MAC)
- m_framebuffer = m_targets->create_backbuffer(GetOSWindow(std::static_pointer_cast<mac_window_info>(win)->platform_window()), width, height);
+ m_framebuffer = m_targets->create_backbuffer(GetOSWindow(dynamic_cast<mac_window_info &>(window()).platform_window()), width, height);
#else
- m_framebuffer = m_targets->create_backbuffer(sdlNativeWindowHandle(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window()), width, height);
+ m_framebuffer = m_targets->create_backbuffer(sdlNativeWindowHandle(dynamic_cast<sdl_window_info &>(window()).platform_window()).first, width, height);
#endif
if (m_ortho_view)
{
@@ -1026,7 +1374,7 @@ bool renderer_bgfx::update_dimensions()
bgfx::setViewFrameBuffer(s_current_view, m_framebuffer->target());
}
- bgfx::setViewClear(s_current_view, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x00000000, 1.0f, 0);
+ bgfx::setViewClear(s_current_view, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x000000ff, 1.0f, 0);
bgfx::setViewMode(s_current_view, bgfx::ViewMode::Sequential);
bgfx::touch(s_current_view);
bgfx::frame();
@@ -1039,7 +1387,7 @@ void renderer_bgfx::setup_ortho_view()
{
if (!m_ortho_view)
{
- m_ortho_view = new bgfx_ortho_view(this, 0, m_framebuffer, m_seen_views);
+ m_ortho_view = std::make_unique<bgfx_ortho_view>(this, 0, m_framebuffer, m_seen_views);
}
if (m_ortho_view->get_index() == UINT_MAX)
{
@@ -1052,10 +1400,6 @@ void renderer_bgfx::setup_ortho_view()
render_primitive_list *renderer_bgfx::get_primitives()
{
- auto win = try_getwindow();
- if (win == nullptr)
- return nullptr;
-
// determines whether the screen container is transformed by the chain's shaders
bool chain_transform = false;
@@ -1066,15 +1410,15 @@ render_primitive_list *renderer_bgfx::get_primitives()
chain_transform = chain->transform();
}
- osd_dim wdim = win->get_size();
+ osd_dim wdim = window().get_size();
if (wdim.width() > 0 && wdim.height() > 0)
- win->target()->set_bounds(wdim.width(), wdim.height(), win->pixel_aspect());
+ window().target()->set_bounds(wdim.width(), wdim.height(), window().pixel_aspect());
- win->target()->set_transform_container(!chain_transform);
- return &win->target()->get_primitives();
+ window().target()->set_transform_container(!chain_transform);
+ return &window().target()->get_primitives();
}
-renderer_bgfx::buffer_status renderer_bgfx::buffer_primitives(bool atlas_valid, render_primitive** prim, bgfx::TransientVertexBuffer* buffer, int32_t screen)
+renderer_bgfx::buffer_status renderer_bgfx::buffer_primitives(bool atlas_valid, render_primitive** prim, bgfx::TransientVertexBuffer* buffer, int32_t screen, int window_index)
{
int vertices = 0;
@@ -1116,18 +1460,18 @@ renderer_bgfx::buffer_status renderer_bgfx::buffer_primitives(bool atlas_valid,
{
#if SCENE_VIEW
setup_view(s_current_view, true);
- render_post_screen_quad(s_current_view, *prim, buffer, screen);
+ render_post_screen_quad(s_current_view, *prim, buffer, screen, window_index);
s_current_view++;
#else
setup_ortho_view();
- render_post_screen_quad(m_ortho_view->get_index(), *prim, buffer, screen);
+ render_post_screen_quad(m_ortho_view->get_index(), *prim, buffer, screen, window_index);
#endif
return BUFFER_SCREEN;
}
else
{
setup_ortho_view();
- render_textured_quad(*prim, buffer);
+ render_textured_quad(*prim, buffer, window_index);
return BUFFER_EMPTY;
}
}
@@ -1208,7 +1552,7 @@ void renderer_bgfx::process_atlas_packs(std::vector<std::vector<rectangle_packer
uint16_t pitch = rect.width();
int width_div_factor = 1;
int width_mul_factor = 1;
- const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(dst_format, rect.format(), rect.rowpixels(), rect.height(), rect.palette(), rect.base(), pitch, width_div_factor, width_mul_factor);
+ const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(dst_format, rect.format(), rect.rowpixels(), 0, rect.height(), rect.palette(), rect.base(), pitch, width_div_factor, width_mul_factor);
bgfx::updateTexture2D(m_texture_cache->texture(), 0, 0, rect.x(), rect.y(), (rect.width() * width_mul_factor) / width_div_factor, rect.height(), mem, pitch);
}
}
@@ -1246,9 +1590,8 @@ bool renderer_bgfx::check_for_dirty_atlas()
{
bool atlas_dirty = false;
- std::shared_ptr<osd_window> win = assert_window();
std::map<uint32_t, rectangle_packer::packable_rectangle> acquired_infos;
- for (render_primitive &prim : *win->m_primlist)
+ for (render_primitive &prim : *window().m_primlist)
{
bool pack = prim.packable(PACKABLE_SIZE);
if (prim.type == render_primitive::QUAD && prim.texture.base != nullptr && pack)
@@ -1261,8 +1604,7 @@ bool renderer_bgfx::check_for_dirty_atlas()
atlas_dirty = true;
m_texinfo.push_back(rectangle_packer::packable_rectangle(hash, prim.flags & PRIMFLAG_TEXFORMAT_MASK,
- prim.texture.width, prim.texture.height,
- prim.texture.rowpixels, prim.texture.palette, prim.texture.base));
+ prim.texture.width, prim.texture.height, prim.texture.rowpixels, prim.texture.palette, prim.texture.base));
acquired_infos[hash] = m_texinfo[m_texinfo.size() - 1];
}
}
@@ -1339,11 +1681,44 @@ void renderer_bgfx::set_sliders_dirty()
m_sliders_dirty = true;
}
-uint32_t renderer_bgfx::get_window_width(uint32_t index) const {
+uint32_t renderer_bgfx::get_window_width(uint32_t index) const
+{
return s_width[index];
}
-uint32_t renderer_bgfx::get_window_height(uint32_t index) const {
+uint32_t renderer_bgfx::get_window_height(uint32_t index) const
+{
return s_height[index];
}
+
+void renderer_bgfx::load_config(util::xml::data_node const &parentnode)
+{
+ util::xml::data_node const *windownode = parentnode.get_child("window");
+ while (windownode)
+ {
+ if (windownode->get_attribute_int("index", -1) != window().index())
+ {
+ windownode = windownode->get_next_sibling("window");
+ continue;
+ }
+
+ if (!m_config)
+ m_config = util::xml::file::create();
+ else
+ m_config->get_first_child()->delete_node();
+ windownode->copy_into(*m_config);
+ m_config->get_first_child()->set_attribute("persist", "0");
+ osd_printf_verbose("BGFX: Found configuration for window %d\n", window().index());
+ break;
+ }
+}
+
+
+void renderer_bgfx::save_config(util::xml::data_node &parentnode)
+{
+ if (m_config)
+ m_config->get_first_child()->copy_into(parentnode);
+ else
+ m_chains->save_config(parentnode);
+}
diff --git a/src/osd/modules/render/drawbgfx.h b/src/osd/modules/render/drawbgfx.h
index fc728e41d67..bb9f538aafa 100644
--- a/src/osd/modules/render/drawbgfx.h
+++ b/src/osd/modules/render/drawbgfx.h
@@ -1,30 +1,34 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
+#ifndef MAME_RENDER_DRAWBGFX_H
+#define MAME_RENDER_DRAWBGFX_H
+
#pragma once
-#ifndef RENDER_BGFX
-#define RENDER_BGFX
+#include "binpacker.h"
+#include "bgfx/chain.h"
+#include "bgfx/chainmanager.h"
+#include "bgfx/vertex.h"
+#include "sliderdirtynotifier.h"
+
+#include "modules/osdwindow.h"
+
+#include "notifier.h"
#include <bgfx/bgfx.h>
#include <map>
+#include <memory>
#include <vector>
-#include "binpacker.h"
-#include "bgfx/vertex.h"
-#include "bgfx/chain.h"
-#include "bgfx/chainmanager.h"
-#include "sliderdirtynotifier.h"
class texture_manager;
class target_manager;
class shader_manager;
class effect_manager;
-class chain_manager;
class bgfx_texture;
class bgfx_effect;
class bgfx_target;
-class bgfx_chain;
class bgfx_view;
class osd_options;
class avi_write;
@@ -33,11 +37,10 @@ class avi_write;
class renderer_bgfx : public osd_renderer, public slider_dirty_notifier
{
public:
- renderer_bgfx(std::shared_ptr<osd_window> w);
- virtual ~renderer_bgfx();
+ class parent_module;
- static bool init(running_machine &machine);
- static void exit();
+ renderer_bgfx(osd_window &window, parent_module &parent_module);
+ virtual ~renderer_bgfx();
virtual int create() override;
virtual int draw(const int update) override;
@@ -62,7 +65,24 @@ public:
static char const *const WINDOW_PREFIX;
private:
- void init_bgfx_library();
+ enum buffer_status
+ {
+ BUFFER_PRE_FLUSH,
+ BUFFER_FLUSH,
+ BUFFER_SCREEN,
+ BUFFER_EMPTY,
+ BUFFER_DONE
+ };
+
+ class parent_module_holder
+ {
+ public:
+ parent_module_holder(parent_module &parent);
+ ~parent_module_holder();
+ parent_module &operator()() const { return m_parent; }
+ private:
+ parent_module &m_parent;
+ };
void vertex(ScreenVertex* vertex, float x, float y, float z, uint32_t rgba, float u, float v);
void render_avi_quad();
@@ -73,18 +93,10 @@ private:
void setup_ortho_view();
void allocate_buffer(render_primitive *prim, uint32_t blend, bgfx::TransientVertexBuffer *buffer);
- enum buffer_status
- {
- BUFFER_PRE_FLUSH,
- BUFFER_FLUSH,
- BUFFER_SCREEN,
- BUFFER_EMPTY,
- BUFFER_DONE
- };
- buffer_status buffer_primitives(bool atlas_valid, render_primitive** prim, bgfx::TransientVertexBuffer* buffer, int32_t screen);
+ buffer_status buffer_primitives(bool atlas_valid, render_primitive** prim, bgfx::TransientVertexBuffer* buffer, int32_t screen, int window_index);
- void render_textured_quad(render_primitive* prim, bgfx::TransientVertexBuffer* buffer);
- void render_post_screen_quad(int view, render_primitive* prim, bgfx::TransientVertexBuffer* buffer, int32_t screen);
+ void render_textured_quad(render_primitive* prim, bgfx::TransientVertexBuffer* buffer, int window_index);
+ void render_post_screen_quad(int view, render_primitive* prim, bgfx::TransientVertexBuffer* buffer, int32_t screen, int window_index);
void put_packed_quad(render_primitive *prim, uint32_t hash, ScreenVertex* vertex);
void put_packed_line(render_primitive *prim, ScreenVertex* vertex);
@@ -100,8 +112,10 @@ private:
void process_atlas_packs(std::vector<std::vector<rectangle_packer::packed_rectangle>>& packed);
uint32_t get_texture_hash(render_primitive *prim);
- osd_options& m_options;
- bgfx::PlatformData m_platform_data;
+ void load_config(util::xml::data_node const &parentnode);
+ void save_config(util::xml::data_node &parentnode);
+
+ parent_module_holder m_module; // keep this where it will be destructed last
bgfx_target *m_framebuffer;
bgfx_texture *m_texture_cache;
@@ -109,11 +123,11 @@ private:
// Original display_mode
osd_dim m_dimensions;
- texture_manager *m_textures;
- target_manager *m_targets;
- shader_manager *m_shaders;
- effect_manager *m_effects;
- chain_manager *m_chains;
+ std::unique_ptr<texture_manager> m_textures;
+ std::unique_ptr<target_manager> m_targets;
+ std::unique_ptr<shader_manager> m_shaders;
+ std::unique_ptr<effect_manager> m_effects;
+ std::unique_ptr<chain_manager> m_chains;
bgfx_effect *m_gui_effect[4];
bgfx_effect *m_screen_effect[4];
@@ -124,7 +138,7 @@ private:
rectangle_packer m_packer;
uint32_t m_white[16*16];
- bgfx_view *m_ortho_view;
+ std::unique_ptr<bgfx_view> m_ortho_view;
uint32_t m_max_view;
bgfx_view *m_avi_view;
@@ -134,14 +148,17 @@ private:
bitmap_rgb32 m_avi_bitmap;
uint8_t *m_avi_data;
+ std::unique_ptr<util::xml::file> m_config;
+ const util::notifier_subscription m_load_sub;
+ const util::notifier_subscription m_save_sub;
+
static const uint16_t CACHE_SIZE;
static const uint32_t PACKABLE_SIZE;
static const uint32_t WHITE_HASH;
static uint32_t s_current_view;
- static bool s_bgfx_library_initialized;
static uint32_t s_width[16];
static uint32_t s_height[16];
};
-#endif // RENDER_BGFX
+#endif // MAME_RENDER_DRAWBGFX_H
diff --git a/src/osd/modules/render/drawd3d.cpp b/src/osd/modules/render/drawd3d.cpp
index cfc494a2be9..542e2f8955d 100644
--- a/src/osd/modules/render/drawd3d.cpp
+++ b/src/osd/modules/render/drawd3d.cpp
@@ -13,21 +13,132 @@
#include "rendutil.h"
#include "screen.h"
-#include "aviio.h"
-
// MAMEOS headers
-#include "winmain.h"
-#include "window.h"
#include "drawd3d.h"
-#include "modules/render/d3d/d3dhlsl.h"
+
+#include "d3d/d3dhlsl.h"
+
+#include "render_module.h"
+
+// from OSD implementation
+#include "window.h"
+#include "winmain.h"
+
+// general OSD headers
#include "modules/monitor/monitor_module.h"
+
+// lib/util
+#include "aviio.h"
+
#include <utility>
+
+//============================================================
+// OSD MODULE
+//============================================================
+
+namespace osd {
+
+namespace {
+
+class video_d3d : public osd_module, public render_module
+{
+public:
+ video_d3d()
+ : osd_module(OSD_RENDERER_PROVIDER, "d3d")
+ , m_options(nullptr)
+ {
+ }
+
+ virtual bool probe() override;
+ virtual int init(osd_interface &osd, osd_options const &options) override;
+ virtual void exit() override;
+
+ virtual std::unique_ptr<osd_renderer> create(osd_window &window) override;
+
+protected:
+ virtual unsigned flags() const override { return FLAG_INTERACTIVE; }
+
+private:
+ using d3d9_create_fn = IDirect3D9 *(WINAPI *)(UINT);
+
+ dynamic_module::ptr m_d3d9_dll;
+ Microsoft::WRL::ComPtr<IDirect3D9> m_d3dobj;
+ osd_options const *m_options;
+};
+
+
+//============================================================
+// video_d3d::probe
+//============================================================
+
+bool video_d3d::probe()
+{
+ // do a dry run of loading the Direct3D 9 DLL
+ return dynamic_module::open({ "d3d9.dll" })->bind<d3d9_create_fn>("Direct3DCreate9") != nullptr;
+}
+
+
+//============================================================
+// video_d3d::init
+//============================================================
+
+int video_d3d::init(osd_interface &osd, osd_options const &options)
+{
+ m_options = &options;
+
+ m_d3d9_dll = dynamic_module::open({ "d3d9.dll" });
+ auto const d3d9_create_ptr = m_d3d9_dll->bind<d3d9_create_fn>("Direct3DCreate9");
+ if (!d3d9_create_ptr)
+ {
+ osd_printf_warning("Direct3D: Could not find Direct3DCreate9 function in d3d9.dll\n");
+ m_d3d9_dll.reset();
+ m_options = nullptr;
+ return -1;
+ }
+
+ m_d3dobj.Attach((d3d9_create_ptr)(D3D_SDK_VERSION));
+ if (!m_d3dobj)
+ {
+ osd_printf_warning("Direct3D: Unable to initialize Direct3D 9\n");
+ m_d3d9_dll.reset();
+ m_options = nullptr;
+ return -1;
+ }
+
+ osd_printf_verbose("Direct3D: Using Direct3D 9\n");
+
+ return 0;
+}
+
+
+//============================================================
+// video_d3d::exit
+//============================================================
+
+void video_d3d::exit()
+{
+ m_d3dobj.Reset();
+ m_d3d9_dll.reset();
+ m_options = nullptr;
+}
+
+
//============================================================
-// TYPE DEFINITIONS
+// video_d3d::create
//============================================================
-typedef IDirect3D9* (WINAPI *d3d9_create_fn)(UINT);
+std::unique_ptr<osd_renderer> video_d3d::create(osd_window &window)
+{
+ return std::make_unique<renderer_d3d9>(window, m_d3dobj);
+}
+
+} // anonymous namespace
+
+} // namespace osd
+
+MODULE_DEFINITION(RENDERER_D3D, osd::video_d3d)
+
//============================================================
@@ -116,13 +227,6 @@ static inline uint32_t ycc_to_rgb(uint8_t y, uint8_t cb, uint8_t cr)
//============================================================
-// drawd3d_init
-//============================================================
-
-static d3d_base *d3dintf = nullptr; // FIX ME
-
-
-//============================================================
// drawd3d_window_init
//============================================================
@@ -174,60 +278,22 @@ void renderer_d3d9::save()
render_primitive_list *renderer_d3d9::get_primitives()
{
RECT client;
- auto win = try_getwindow();
- if (win == nullptr)
- return nullptr;
-
- HWND hWnd = std::static_pointer_cast<win_window_info>(win)->platform_window();
+ HWND hWnd = dynamic_cast<win_window_info &>(window()).platform_window();
if (IsIconic(hWnd))
return nullptr;
- GetClientRectExceptMenu(hWnd, &client, win->fullscreen());
+ GetClientRectExceptMenu(hWnd, &client, window().fullscreen());
if (rect_width(&client) > 0 && rect_height(&client) > 0)
{
- win->target()->set_bounds(rect_width(&client), rect_height(&client), win->pixel_aspect());
- win->target()->set_max_update_rate((get_refresh() == 0) ? get_origmode().RefreshRate : get_refresh());
+ window().target()->set_bounds(rect_width(&client), rect_height(&client), window().pixel_aspect());
+ window().target()->set_max_update_rate((get_refresh() == 0) ? get_origmode().RefreshRate : get_refresh());
}
if (m_shaders != nullptr)
{
// do not transform primitives (scale, offset) if shaders are enabled, the shaders will handle the transformation
- win->target()->set_transform_container(!m_shaders->enabled());
+ window().target()->set_transform_container(!m_shaders->enabled());
}
- return &win->target()->get_primitives();
-}
-
-
-//============================================================
-// renderer_d3d9::init
-//============================================================
-
-bool renderer_d3d9::init(running_machine &machine)
-{
- d3dintf = new d3d_base;
-
- d3dintf->d3d9_dll = osd::dynamic_module::open({ "d3d9.dll" });
-
- d3d9_create_fn d3d9_create_ptr = d3dintf->d3d9_dll->bind<d3d9_create_fn>("Direct3DCreate9");
- if (d3d9_create_ptr == nullptr)
- {
- delete d3dintf;
- d3dintf = nullptr;
- osd_printf_verbose("Direct3D: Unable to find Direct3D 9 runtime library\n");
- return true;
- }
-
- d3dintf->d3dobj = (*d3d9_create_ptr)(D3D_SDK_VERSION);
- if (d3dintf->d3dobj == nullptr)
- {
- delete d3dintf;
- d3dintf = nullptr;
- osd_printf_verbose("Direct3D: Unable to initialize Direct3D 9\n");
- return true;
- }
-
- osd_printf_verbose("Direct3D: Using Direct3D 9\n");
-
- return false;
+ return &window().target()->get_primitives();
}
@@ -242,7 +308,12 @@ int renderer_d3d9::draw(const int update)
return check;
begin_frame();
+
+ // reset blend mode
+ set_blendmode(BLENDMODE_NONE);
+
process_primitives();
+
end_frame();
return 0;
@@ -254,8 +325,12 @@ void renderer_d3d9::set_texture(texture_info *texture)
{
m_last_texture = texture;
m_last_texture_flags = (texture == nullptr ? 0 : texture->get_flags());
+ if (m_shaders->enabled())
+ {
+ m_shaders->set_texture(texture);
+ }
+
HRESULT result = m_device->SetTexture(0, (texture == nullptr) ? get_default_texture()->get_finaltex() : texture->get_finaltex());
- m_shaders->set_texture(texture);
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device set_texture call\n", result);
}
@@ -353,15 +428,20 @@ void renderer_d3d9::set_blendmode(int blendmode)
}
// adjust the bits that changed
+ bool new_blend_enable = false;
if (blendenable != m_last_blendenable)
{
m_last_blendenable = blendenable;
+ if (blendenable)
+ {
+ new_blend_enable = true;
+ }
HRESULT result = m_device->SetRenderState(D3DRS_ALPHABLENDENABLE, blendenable);
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device SetRenderState call\n", result);
}
- if (blendop != m_last_blendop)
+ if (blendop != m_last_blendop || new_blend_enable)
{
m_last_blendop = blendop;
HRESULT result = m_device->SetRenderState(D3DRS_BLENDOP, blendop);
@@ -369,7 +449,7 @@ void renderer_d3d9::set_blendmode(int blendmode)
osd_printf_verbose("Direct3D: Error %08lX during device SetRenderState call\n", result);
}
- if (blendsrc != m_last_blendsrc)
+ if (blendsrc != m_last_blendsrc || new_blend_enable)
{
m_last_blendsrc = blendsrc;
HRESULT result = m_device->SetRenderState(D3DRS_SRCBLEND, blendsrc);
@@ -377,7 +457,7 @@ void renderer_d3d9::set_blendmode(int blendmode)
osd_printf_verbose("Direct3D: Error %08lX during device SetRenderState call\n", result);
}
- if (blenddst != m_last_blenddst)
+ if (blenddst != m_last_blenddst || new_blend_enable)
{
m_last_blenddst = blenddst;
HRESULT result = m_device->SetRenderState(D3DRS_DESTBLEND, blenddst);
@@ -398,14 +478,12 @@ void renderer_d3d9::reset_render_states()
m_last_wrap = (D3DTEXTUREADDRESS)-1;
}
-d3d_texture_manager::d3d_texture_manager(renderer_d3d9 *d3d)
+d3d_texture_manager::d3d_texture_manager(renderer_d3d9 &d3d, IDirect3D9 *d3dobj)
+ : m_renderer(d3d)
+ , m_default_texture(nullptr)
{
- m_renderer = d3d;
-
- m_default_texture = nullptr;
-
D3DCAPS9 caps;
- HRESULT result = d3dintf->d3dobj->GetDeviceCaps(d3d->get_adapter(), D3DDEVTYPE_HAL, &caps);
+ HRESULT result = d3dobj->GetDeviceCaps(d3d.get_adapter(), D3DDEVTYPE_HAL, &caps);
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during GetDeviceCaps call\n", result);
@@ -417,35 +495,30 @@ d3d_texture_manager::d3d_texture_manager(renderer_d3d9 *d3d)
// pick a YUV texture format
m_yuv_format = D3DFMT_UYVY;
- result = d3dintf->d3dobj->CheckDeviceFormat(d3d->get_adapter(), D3DDEVTYPE_HAL, d3d->get_pixel_format(), 0, D3DRTYPE_TEXTURE, D3DFMT_UYVY);
+ result = d3dobj->CheckDeviceFormat(d3d.get_adapter(), D3DDEVTYPE_HAL, d3d.get_pixel_format(), 0, D3DRTYPE_TEXTURE, D3DFMT_UYVY);
if (FAILED(result))
{
m_yuv_format = D3DFMT_YUY2;
- result = d3dintf->d3dobj->CheckDeviceFormat(d3d->get_adapter(), D3DDEVTYPE_HAL, d3d->get_pixel_format(), 0, D3DRTYPE_TEXTURE, D3DFMT_YUY2);
+ result = d3dobj->CheckDeviceFormat(d3d.get_adapter(), D3DDEVTYPE_HAL, d3d.get_pixel_format(), 0, D3DRTYPE_TEXTURE, D3DFMT_YUY2);
if (FAILED(result))
m_yuv_format = D3DFMT_A8R8G8B8;
}
osd_printf_verbose("Direct3D: YUV format = %s\n", (m_yuv_format == D3DFMT_YUY2) ? "YUY2" : (m_yuv_format == D3DFMT_UYVY) ? "UYVY" : "RGB");
- auto win = d3d->assert_window();
-
// set the max texture size
- win->target()->set_max_texture_size(m_texture_max_width, m_texture_max_height);
- osd_printf_verbose("Direct3D: Max texture size = %dx%d\n", (int)m_texture_max_width, (int)m_texture_max_height);
+ d3d.window().target()->set_max_texture_size(m_texture_max_width, m_texture_max_height);
+ osd_printf_verbose("Direct3D: Max texture size = %dx%d\n", m_texture_max_width, m_texture_max_height);
}
void d3d_texture_manager::create_resources()
{
- auto win = m_renderer->assert_window();
-
m_default_bitmap.allocate(8, 8);
- m_default_bitmap.fill(rgb_t(0xff,0xff,0xff,0xff));
-
if (m_default_bitmap.valid())
{
- render_texinfo texture;
+ m_default_bitmap.fill(rgb_t(0xff,0xff,0xff,0xff));
// fake in the basic data so it looks like it came from render.c
+ render_texinfo texture;
texture.base = m_default_bitmap.raw_pixptr(0);
texture.rowpixels = m_default_bitmap.rowpixels();
texture.width = m_default_bitmap.width();
@@ -456,7 +529,7 @@ void d3d_texture_manager::create_resources()
texture.old_id = ~0ULL;
// now create it
- auto tex = std::make_unique<texture_info>(this, &texture, win->prescale(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32));
+ auto tex = std::make_unique<texture_info>(*this, &texture, m_renderer.window().prescale(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32));
m_default_texture = tex.get();
m_texture_list.push_back(std::move(tex));
}
@@ -465,7 +538,6 @@ void d3d_texture_manager::create_resources()
void d3d_texture_manager::delete_resources()
{
// is part of m_texlist and will be free'd there
- //delete m_default_texture;
m_default_texture = nullptr;
// free all textures
@@ -479,16 +551,16 @@ uint32_t d3d_texture_manager::texture_compute_hash(const render_texinfo *texture
texture_info *d3d_texture_manager::find_texinfo(const render_texinfo *texinfo, uint32_t flags)
{
- uint32_t hash = texture_compute_hash(texinfo, flags);
+ const uint32_t hash = texture_compute_hash(texinfo, flags);
// find a match
for (auto it = m_texture_list.begin(); it != m_texture_list.end(); it++)
{
- auto test_screen = (uint32_t)((*it)->get_texinfo().unique_id >> 57);
- uint32_t test_page = (uint32_t)((*it)->get_texinfo().unique_id >> 56) & 1;
- auto prim_screen = (uint32_t)(texinfo->unique_id >> 57);
- uint32_t prim_page = (uint32_t)(texinfo->unique_id >> 56) & 1;
- if (test_screen != prim_screen || test_page != prim_page)
+ const uint32_t test_screen = uint32_t((*it)->get_texinfo().unique_id >> 57);
+ const uint32_t test_page = uint32_t((*it)->get_texinfo().unique_id >> 56) & 1;
+ const uint32_t prim_screen = uint32_t(texinfo->unique_id >> 57);
+ const uint32_t prim_page = uint32_t(texinfo->unique_id >> 56) & 1;
+ if ((test_screen != prim_screen) || (test_page != prim_page))
continue;
if ((*it)->get_hash() == hash &&
@@ -504,11 +576,35 @@ texture_info *d3d_texture_manager::find_texinfo(const render_texinfo *texinfo, u
return nullptr;
}
-renderer_d3d9::renderer_d3d9(std::shared_ptr<osd_window> window)
- : osd_renderer(window, FLAG_NONE), m_adapter(0), m_width(0), m_height(0), m_refresh(0), m_create_error_count(0), m_device(nullptr), m_gamma_supported(0), m_pixformat(),
- m_vertexbuf(nullptr), m_lockedbuf(nullptr), m_numverts(0), m_vectorbatch(nullptr), m_batchindex(0), m_numpolys(0), m_toggle(false),
- m_screen_format(), m_last_texture(nullptr), m_last_texture_flags(0), m_last_blendenable(0), m_last_blendop(0), m_last_blendsrc(0), m_last_blenddst(0), m_last_filter(0),
- m_last_wrap(), m_last_modmode(0), m_shaders(nullptr), m_texture_manager()
+renderer_d3d9::renderer_d3d9(osd_window &window, const IDirect3D9Ptr &d3dobj)
+ : osd_renderer(window)
+ , m_d3dobj(d3dobj)
+ , m_adapter(0)
+ , m_width(0)
+ , m_height(0)
+ , m_refresh(0)
+ , m_create_error_count(0)
+ , m_post_fx_available(true)
+ , m_gamma_supported(0)
+ , m_pixformat()
+ , m_lockedbuf(nullptr)
+ , m_numverts(0)
+ , m_vectorbatch(nullptr)
+ , m_batchindex(0)
+ , m_numpolys(0)
+ , m_toggle(false)
+ , m_screen_format()
+ , m_last_texture(nullptr)
+ , m_last_texture_flags(0)
+ , m_last_blendenable(0)
+ , m_last_blendop(0)
+ , m_last_blendsrc(0)
+ , m_last_blenddst(0)
+ , m_last_filter(0)
+ , m_last_wrap()
+ , m_last_modmode(0)
+ , m_shaders(nullptr)
+ , m_texture_manager()
{
}
@@ -523,8 +619,7 @@ int renderer_d3d9::initialize()
}
// create the device immediately for the full screen case (defer for window mode in update_window_size())
- auto win = assert_window();
- if (win->fullscreen() && device_create(std::static_pointer_cast<win_window_info>(win->main_window())->platform_window()))
+ if (window().fullscreen() && device_create(dynamic_cast<win_window_info &>(window()).main_window()->platform_window()))
{
return false;
}
@@ -534,10 +629,8 @@ int renderer_d3d9::initialize()
int renderer_d3d9::pre_window_draw_check()
{
- auto win = assert_window();
-
// if we're in the middle of resizing, leave things alone
- if (win->m_resize_state == RESIZE_STATE_RESIZING)
+ if (dynamic_cast<win_window_info &>(window()).m_resize_state == win_window_info::RESIZE_STATE_RESIZING)
return 0;
// check if shaders should be toggled
@@ -561,7 +654,7 @@ int renderer_d3d9::pre_window_draw_check()
}
// if we have a device, check the cooperative level
- if (m_device != nullptr)
+ if (m_device)
{
if (device_test_cooperative())
{
@@ -570,14 +663,14 @@ int renderer_d3d9::pre_window_draw_check()
}
// in window mode, we need to track the window size
- if (!win->fullscreen() || m_device == nullptr)
+ if (!window().fullscreen() || !m_device)
{
// if the size changes, skip this update since the render target will be out of date
if (update_window_size())
return 0;
// if we have no device, after updating the size, return an error so GDI can try
- if (m_device == nullptr)
+ if (!m_device)
return 1;
}
@@ -586,18 +679,16 @@ int renderer_d3d9::pre_window_draw_check()
void d3d_texture_manager::update_textures()
{
- auto win = m_renderer->assert_window();
-
- for (render_primitive &prim : *win->m_primlist)
+ for (render_primitive &prim : *m_renderer.window().m_primlist)
{
if (prim.texture.base != nullptr)
{
texture_info *texture = find_texinfo(&prim.texture, prim.flags);
if (texture == nullptr)
{
- int prescale = m_renderer->get_shaders()->enabled() ? 1 : win->prescale();
+ const int prescale = m_renderer.get_shaders()->enabled() ? 1 : m_renderer.window().prescale();
- auto tex = std::make_unique<texture_info>(this, &prim.texture, prescale, prim.flags);
+ auto tex = std::make_unique<texture_info>(*this, &prim.texture, prescale, prim.flags);
texture = tex.get();
m_texture_list.push_back(std::move(tex));
}
@@ -613,21 +704,19 @@ void d3d_texture_manager::update_textures()
}
}
- if (!m_renderer->get_shaders()->enabled())
- {
+ if (!m_renderer.get_shaders()->enabled())
return;
- }
int screen_index = 0;
- for (render_primitive &prim : *win->m_primlist)
+ for (render_primitive &prim : *m_renderer.window().m_primlist)
{
if (PRIMFLAG_GET_SCREENTEX(prim.flags))
{
- if (!m_renderer->get_shaders()->get_texture_target(&prim, prim.texture.width, prim.texture.height, screen_index))
+ if (!m_renderer.get_shaders()->get_texture_target(&prim, prim.texture.width, prim.texture.height, screen_index))
{
- if (!m_renderer->get_shaders()->create_texture_target(&prim, prim.texture.width, prim.texture.height, screen_index))
+ if (!m_renderer.get_shaders()->create_texture_target(&prim, prim.texture.width, prim.texture.height, screen_index))
{
- d3dintf->post_fx_available = false;
+ m_renderer.set_post_fx_unavailable();
break;
}
}
@@ -635,11 +724,11 @@ void d3d_texture_manager::update_textures()
}
else if (PRIMFLAG_GET_VECTORBUF(prim.flags))
{
- if (!m_renderer->get_shaders()->get_vector_target(&prim, screen_index))
+ if (!m_renderer.get_shaders()->get_vector_target(&prim, screen_index))
{
- if (!m_renderer->get_shaders()->create_vector_target(&prim, screen_index))
+ if (!m_renderer.get_shaders()->create_vector_target(&prim, screen_index))
{
- d3dintf->post_fx_available = false;
+ m_renderer.set_post_fx_unavailable();
break;
}
}
@@ -650,13 +739,11 @@ void d3d_texture_manager::update_textures()
void renderer_d3d9::begin_frame()
{
- auto win = assert_window();
-
- HRESULT result = m_device->Clear(0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
+ HRESULT result = m_device->Clear(0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0xff,0,0,0), 0, 0);
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device clear call\n", result);
- win->m_primlist->acquire_lock();
+ window().m_primlist->acquire_lock();
// first update any textures
m_texture_manager->update_textures();
@@ -667,16 +754,17 @@ void renderer_d3d9::begin_frame()
osd_printf_verbose("Direct3D: Error %08lX during device BeginScene call\n", result);
if (m_shaders->enabled())
- m_shaders->init_fsfx_quad();
+ m_shaders->begin_frame(window().m_primlist);
+
+ // set an initial default texture
+ set_texture(nullptr);
}
void renderer_d3d9::process_primitives()
{
- auto win = assert_window();
-
// loop over line primitives
int vector_count = 0;
- for (render_primitive &prim : *win->m_primlist)
+ for (render_primitive &prim : *window().m_primlist)
{
if (prim.type == render_primitive::LINE && PRIMFLAG_GET_VECTOR(prim.flags))
{
@@ -685,7 +773,7 @@ void renderer_d3d9::process_primitives()
}
// Rotating index for vector time offsets
- for (render_primitive &prim : *win->m_primlist)
+ for (render_primitive &prim : *window().m_primlist)
{
switch (prim.type)
{
@@ -716,13 +804,14 @@ void renderer_d3d9::process_primitives()
void renderer_d3d9::end_frame()
{
- auto win = assert_window();
-
- win->m_primlist->release_lock();
+ window().m_primlist->release_lock();
// flush any pending polygons
primitive_flush_pending();
+ if (m_shaders->enabled())
+ m_shaders->end_frame();
+
// finish the scene
HRESULT result = m_device->EndScene();
if (FAILED(result))
@@ -736,8 +825,6 @@ void renderer_d3d9::end_frame()
void renderer_d3d9::update_presentation_parameters()
{
- auto win = assert_window();
-
memset(&m_presentation, 0, sizeof(m_presentation));
m_presentation.BackBufferWidth = m_width;
m_presentation.BackBufferHeight = m_height;
@@ -745,14 +832,14 @@ void renderer_d3d9::update_presentation_parameters()
m_presentation.BackBufferCount = video_config.triplebuf ? 2 : 1;
m_presentation.MultiSampleType = D3DMULTISAMPLE_NONE;
m_presentation.SwapEffect = D3DSWAPEFFECT_DISCARD;
- m_presentation.hDeviceWindow = std::static_pointer_cast<win_window_info>(win)->platform_window();
- m_presentation.Windowed = !win->fullscreen() || win->win_has_menu();
+ m_presentation.hDeviceWindow = dynamic_cast<win_window_info &>(window()).platform_window();
+ m_presentation.Windowed = !window().fullscreen();
m_presentation.EnableAutoDepthStencil = FALSE;
m_presentation.AutoDepthStencilFormat = D3DFMT_D16;
m_presentation.Flags = 0;
m_presentation.FullScreen_RefreshRateInHz = m_refresh;
m_presentation.PresentationInterval = (
- (video_config.triplebuf && win->fullscreen())
+ (video_config.triplebuf && window().fullscreen())
|| video_config.waitvsync
|| video_config.syncrefresh)
? D3DPRESENT_INTERVAL_ONE
@@ -767,13 +854,11 @@ void renderer_d3d9::update_gamma_ramp()
return;
}
- auto win = assert_window();
-
// set the gamma if we need to
- if (win->fullscreen())
+ if (window().fullscreen())
{
// only set the gamma if it's not 1.0
- auto &options = downcast<windows_options &>(win->machine().options());
+ auto &options = downcast<windows_options &>(window().machine().options());
float brightness = options.full_screen_brightness();
float contrast = options.full_screen_contrast();
float gamma = options.full_screen_gamma();
@@ -803,27 +888,23 @@ int renderer_d3d9::device_create(HWND hwnd)
HWND device_hwnd = GetAncestor(hwnd, GA_ROOT);
// if a device exists, free it
- if (m_device != nullptr)
- {
+ if (m_device)
device_delete();
- }
// verify the caps
if (!device_verify_caps())
- {
return 1;
- }
- m_texture_manager = std::make_unique<d3d_texture_manager>(this);
+ m_texture_manager = std::make_unique<d3d_texture_manager>(*this, m_d3dobj.Get());
// try for XRGB first
m_screen_format = D3DFMT_X8R8G8B8;
- HRESULT result = d3dintf->d3dobj->CheckDeviceFormat(m_adapter, D3DDEVTYPE_HAL, m_pixformat, D3DUSAGE_DYNAMIC, D3DRTYPE_TEXTURE, m_screen_format);
+ HRESULT result = m_d3dobj->CheckDeviceFormat(m_adapter, D3DDEVTYPE_HAL, m_pixformat, D3DUSAGE_DYNAMIC, D3DRTYPE_TEXTURE, m_screen_format);
if (FAILED(result))
{
// if not, try for ARGB
m_screen_format = D3DFMT_A8R8G8B8;
- result = d3dintf->d3dobj->CheckDeviceFormat(m_adapter, D3DDEVTYPE_HAL, m_pixformat, D3DUSAGE_DYNAMIC, D3DRTYPE_TEXTURE, m_screen_format);
+ result = m_d3dobj->CheckDeviceFormat(m_adapter, D3DDEVTYPE_HAL, m_pixformat, D3DUSAGE_DYNAMIC, D3DRTYPE_TEXTURE, m_screen_format);
if (FAILED(result))
{
osd_printf_error("Error: unable to configure a screen texture format\n");
@@ -835,8 +916,13 @@ int renderer_d3d9::device_create(HWND hwnd)
update_presentation_parameters();
// create the D3D device
- result = d3dintf->d3dobj->CreateDevice(
- m_adapter, D3DDEVTYPE_HAL, device_hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &m_presentation, &m_device);
+ result = m_d3dobj->CreateDevice(
+ m_adapter,
+ D3DDEVTYPE_HAL,
+ device_hwnd,
+ D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE,
+ &m_presentation,
+ &m_device);
if (FAILED(result))
{
// if we got a "DEVICELOST" error, it may be transitory; count it and only fail if
@@ -869,16 +955,13 @@ int renderer_d3d9::device_create(HWND hwnd)
int renderer_d3d9::device_create_resources()
{
- auto win = assert_window();
-
// create shaders only once
- if (m_shaders == nullptr)
- {
- m_shaders = new shaders;
- }
+ if (!m_shaders)
+ m_shaders = std::make_unique<shaders>();
- if (m_shaders->init(d3dintf, &win->machine(), this))
+ if (m_shaders->init(m_d3dobj.Get(), &window().machine(), this))
{
+ m_post_fx_available = true;
m_shaders->init_slider_list();
m_sliders_dirty = true;
}
@@ -892,12 +975,12 @@ int renderer_d3d9::device_create_resources()
// allocate a vertex buffer to use
HRESULT result = m_device->CreateVertexBuffer(
- sizeof(vertex) * VERTEX_BUFFER_SIZE,
- D3DUSAGE_DYNAMIC | D3DUSAGE_SOFTWAREPROCESSING | D3DUSAGE_WRITEONLY,
- VERTEX_BASE_FORMAT | ((m_shaders->enabled())
- ? D3DFVF_XYZW
- : D3DFVF_XYZRHW),
- D3DPOOL_DEFAULT, &m_vertexbuf, nullptr);
+ sizeof(vertex) * VERTEX_BUFFER_SIZE,
+ D3DUSAGE_DYNAMIC | D3DUSAGE_SOFTWAREPROCESSING | D3DUSAGE_WRITEONLY,
+ VERTEX_BASE_FORMAT | (m_shaders->enabled() ? D3DFVF_XYZW : D3DFVF_XYZRHW),
+ D3DPOOL_DEFAULT,
+ &m_vertexbuf,
+ nullptr);
if (FAILED(result))
{
osd_printf_error("Error creating vertex buffer (%08X)\n", (uint32_t)result);
@@ -906,9 +989,7 @@ int renderer_d3d9::device_create_resources()
// set the vertex format
result = m_device->SetFVF(
- (D3DFORMAT)(VERTEX_BASE_FORMAT | ((m_shaders->enabled())
- ? D3DFVF_XYZW
- : D3DFVF_XYZRHW)));
+ D3DFORMAT(VERTEX_BASE_FORMAT | (m_shaders->enabled() ? D3DFVF_XYZW : D3DFVF_XYZRHW)));
if (FAILED(result))
{
osd_printf_error("Error setting vertex format (%08X)\n", (uint32_t)result);
@@ -960,24 +1041,6 @@ int renderer_d3d9::device_create_resources()
renderer_d3d9::~renderer_d3d9()
{
device_delete();
-
- // todo: throws error when switching from full screen to window mode
- //if (m_shaders != nullptr)
- //{
- // // delete the HLSL interface
- // delete m_shaders;
- // m_shaders = nullptr;
- //}
-}
-
-void renderer_d3d9::exit()
-{
- if (d3dintf != nullptr)
- {
- d3dintf->d3dobj->Release();
- delete d3dintf;
- d3dintf = nullptr;
- }
}
void renderer_d3d9::device_delete()
@@ -990,11 +1053,7 @@ void renderer_d3d9::device_delete()
m_texture_manager.reset();
// free the device itself
- if (m_device != nullptr)
- {
- m_device->Release();
- m_device = nullptr;
- }
+ m_device.Reset();
}
@@ -1004,22 +1063,14 @@ void renderer_d3d9::device_delete()
void renderer_d3d9::device_delete_resources()
{
- if (m_shaders != nullptr)
- {
+ if (m_shaders)
m_shaders->delete_resources();
- }
- if (m_texture_manager != nullptr)
- {
+ if (m_texture_manager)
m_texture_manager->delete_resources();
- }
// free the vertex buffer
- if (m_vertexbuf != nullptr)
- {
- m_vertexbuf->Release();
- m_vertexbuf = nullptr;
- }
+ m_vertexbuf.Reset();
}
@@ -1032,7 +1083,7 @@ bool renderer_d3d9::device_verify_caps()
bool success = true;
D3DCAPS9 caps;
- HRESULT result = d3dintf->d3dobj->GetDeviceCaps(m_adapter, D3DDEVTYPE_HAL, &caps);
+ HRESULT result = m_d3dobj->GetDeviceCaps(m_adapter, D3DDEVTYPE_HAL, &caps);
if (FAILED(result))
{
osd_printf_verbose("Direct3D: Error %08lX during GetDeviceCaps call\n", result);
@@ -1042,7 +1093,7 @@ bool renderer_d3d9::device_verify_caps()
if (caps.MaxPixelShader30InstructionSlots < 512)
{
osd_printf_verbose("Direct3D: Warning - Device does not support Pixel Shader 3.0, falling back to non-PS rendering\n");
- d3dintf->post_fx_available = false;
+ set_post_fx_unavailable();
}
// verify presentation capabilities
@@ -1097,7 +1148,7 @@ bool renderer_d3d9::device_verify_caps()
}
// verify texture formats
- result = d3dintf->d3dobj->CheckDeviceFormat(m_adapter, D3DDEVTYPE_HAL, m_pixformat, 0, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8);
+ result = m_d3dobj->CheckDeviceFormat(m_adapter, D3DDEVTYPE_HAL, m_pixformat, 0, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8);
if (FAILED(result))
{
osd_printf_error("Direct3D Error: Your graphics card does not support the A8R8G8B8 texture format.\n");
@@ -1173,7 +1224,7 @@ int renderer_d3d9::config_adapter_mode()
// get the identifier
D3DADAPTER_IDENTIFIER9 id;
- HRESULT result = d3dintf->d3dobj->GetAdapterIdentifier(m_adapter, 0, &id);
+ HRESULT result = m_d3dobj->GetAdapterIdentifier(m_adapter, 0, &id);
if (FAILED(result))
{
osd_printf_error("Error getting identifier for adapter #%d\n", m_adapter);
@@ -1183,22 +1234,20 @@ int renderer_d3d9::config_adapter_mode()
osd_printf_verbose("Direct3D: Configuring adapter #%d = %s\n", m_adapter, id.Description);
// get the current display mode
- result = d3dintf->d3dobj->GetAdapterDisplayMode(m_adapter, &m_origmode);
+ result = m_d3dobj->GetAdapterDisplayMode(m_adapter, &m_origmode);
if (FAILED(result))
{
osd_printf_error("Error getting mode for adapter #%d\n", m_adapter);
return 1;
}
- auto win = assert_window();
-
- // choose a resolution: window mode case
- if (!win->fullscreen() || !video_config.switchres || win->win_has_menu())
+ if (!window().fullscreen() || !video_config.switchres)
{
- RECT client;
+ // choose a resolution: window mode case
// bounds are from the window client rect
- GetClientRectExceptMenu(std::static_pointer_cast<win_window_info>(win)->platform_window(), &client, win->fullscreen());
+ RECT client;
+ GetClientRectExceptMenu(dynamic_cast<win_window_info &>(window()).platform_window(), &client, window().fullscreen());
m_width = client.right - client.left;
m_height = client.bottom - client.top;
@@ -1209,14 +1258,14 @@ int renderer_d3d9::config_adapter_mode()
// make sure it's a pixel format we can get behind
if (m_pixformat != D3DFMT_X1R5G5B5 && m_pixformat != D3DFMT_R5G6B5 && m_pixformat != D3DFMT_X8R8G8B8)
{
- osd_printf_error("Device %s currently in an unsupported mode\n", win->monitor()->devicename());
+ osd_printf_error("Device %s currently in an unsupported mode\n", window().monitor()->devicename());
return 1;
}
}
-
- // choose a resolution: full screen mode case
else
{
+ // choose a resolution: full screen mode case
+
// default to the current mode exactly
m_width = m_origmode.Width;
m_height = m_origmode.Height;
@@ -1229,10 +1278,10 @@ int renderer_d3d9::config_adapter_mode()
}
// see if we can handle the device type
- result = d3dintf->d3dobj->CheckDeviceType(m_adapter, D3DDEVTYPE_HAL, m_pixformat, m_pixformat, !win->fullscreen());
+ result = m_d3dobj->CheckDeviceType(m_adapter, D3DDEVTYPE_HAL, m_pixformat, m_pixformat, !window().fullscreen());
if (FAILED(result))
{
- osd_printf_error("Proposed video mode not supported on device %s\n", win->monitor()->devicename());
+ osd_printf_error("Proposed video mode not supported on device %s\n", window().monitor()->devicename());
return 1;
}
@@ -1246,18 +1295,16 @@ int renderer_d3d9::config_adapter_mode()
int renderer_d3d9::get_adapter_for_monitor()
{
- int maxadapter = d3dintf->d3dobj->GetAdapterCount();
-
- auto win = assert_window();
+ int maxadapter = m_d3dobj->GetAdapterCount();
// iterate over adapters until we error or find a match
for (int adapternum = 0; adapternum < maxadapter; adapternum++)
{
// get the monitor for this adapter
- HMONITOR curmonitor = d3dintf->d3dobj->GetAdapterMonitor(adapternum);
+ HMONITOR curmonitor = m_d3dobj->GetAdapterMonitor(adapternum);
// if we match the proposed monitor, this is it
- if (curmonitor == reinterpret_cast<HMONITOR>(win->monitor()->oshandle()))
+ if (curmonitor == reinterpret_cast<HMONITOR>(window().monitor()->oshandle()))
{
return adapternum;
}
@@ -1278,10 +1325,8 @@ void renderer_d3d9::pick_best_mode()
int32_t minwidth, minheight;
float best_score = 0.0f;
- auto win = assert_window();
-
// determine the refresh rate of the primary screen
- const screen_device *primary_screen = screen_device_enumerator(win->machine().root_device()).first();
+ const screen_device *primary_screen = screen_device_enumerator(window().machine().root_device()).first();
if (primary_screen != nullptr)
{
target_refresh = ATTOSECONDS_TO_HZ(primary_screen->refresh_attoseconds());
@@ -1291,14 +1336,14 @@ void renderer_d3d9::pick_best_mode()
// note: technically we should not be calling this from an alternate window
// thread; however, it is only done during init time, and the init code on
// the main thread is waiting for us to finish, so it is safe to do so here
- win->target()->compute_minimum_size(minwidth, minheight);
+ window().target()->compute_minimum_size(minwidth, minheight);
// use those as the target for now
int32_t target_width = minwidth;
int32_t target_height = minheight;
// determine the maximum number of modes
- int maxmodes = d3dintf->d3dobj->GetAdapterModeCount(m_adapter, D3DFMT_X8R8G8B8);
+ int maxmodes = m_d3dobj->GetAdapterModeCount(m_adapter, D3DFMT_X8R8G8B8);
// enumerate all the video modes and find the best match
osd_printf_verbose("Direct3D: Selecting video mode...\n");
@@ -1306,7 +1351,7 @@ void renderer_d3d9::pick_best_mode()
{
// check this mode
D3DDISPLAYMODE mode;
- HRESULT result = d3dintf->d3dobj->EnumAdapterModes(m_adapter, D3DFMT_X8R8G8B8, modenum, &mode);
+ HRESULT result = m_d3dobj->EnumAdapterModes(m_adapter, D3DFMT_X8R8G8B8, modenum, &mode);
if (FAILED(result))
break;
@@ -1326,7 +1371,7 @@ void renderer_d3d9::pick_best_mode()
size_score *= 0.1f;
// if we're looking for a particular mode, that's a winner
- if (mode.Width == win->m_win_config.width && mode.Height == win->m_win_config.height)
+ if (mode.Width == window().m_win_config.width && mode.Height == window().m_win_config.height)
size_score = 2.0f;
// compute refresh score
@@ -1337,7 +1382,7 @@ void renderer_d3d9::pick_best_mode()
refresh_score *= 0.1f;
// if we're looking for a particular refresh, make sure it matches
- if (mode.RefreshRate == win->m_win_config.refresh)
+ if (mode.RefreshRate == window().m_win_config.refresh)
refresh_score = 2.0f;
// weight size and refresh equally
@@ -1364,33 +1409,32 @@ void renderer_d3d9::pick_best_mode()
bool renderer_d3d9::update_window_size()
{
- auto win = assert_window();
-
// get the current window bounds
+ auto &win = dynamic_cast<win_window_info &>(window());
RECT client;
- GetClientRectExceptMenu(std::static_pointer_cast<win_window_info>(win)->platform_window(), &client, win->fullscreen());
+ GetClientRectExceptMenu(win.platform_window(), &client, window().fullscreen());
// if we have a device and matching width/height, nothing to do
- if (m_device != nullptr && rect_width(&client) == m_width && rect_height(&client) == m_height)
+ if (m_device && rect_width(&client) == m_width && rect_height(&client) == m_height)
{
// clear out any pending resizing if the area didn't change
- if (win->m_resize_state == RESIZE_STATE_PENDING)
- win->m_resize_state = RESIZE_STATE_NORMAL;
+ if (win.m_resize_state == win_window_info::RESIZE_STATE_PENDING)
+ win.m_resize_state = win_window_info::RESIZE_STATE_NORMAL;
return false;
}
// if we're in the middle of resizing, leave it alone as well
- if (win->m_resize_state == RESIZE_STATE_RESIZING)
+ if (win.m_resize_state == win_window_info::RESIZE_STATE_RESIZING)
return false;
// set the new bounds and create the device again
m_width = rect_width(&client);
m_height = rect_height(&client);
- if (device_create(std::static_pointer_cast<win_window_info>(win->main_window())->platform_window()))
+ if (device_create(win.main_window()->platform_window()))
return false;
// reset the resize state to normal, and indicate we made a change
- win->m_resize_state = RESIZE_STATE_NORMAL;
+ win.m_resize_state = win_window_info::RESIZE_STATE_NORMAL;
return true;
}
@@ -1401,8 +1445,6 @@ bool renderer_d3d9::update_window_size()
void renderer_d3d9::batch_vectors(int vector_count)
{
- auto win = assert_window();
-
float quad_width = 0.0f;
float quad_height = 0.0f;
float target_width = 0.0f;
@@ -1412,9 +1454,10 @@ void renderer_d3d9::batch_vectors(int vector_count)
int triangle_count = vector_count * 2;
m_vectorbatch = mesh_alloc(vertex_count);
m_batchindex = 0;
+ uint32_t tint = 0xffffffff;
uint32_t cached_flags = 0;
- for (render_primitive &prim : *win->m_primlist)
+ for (render_primitive &prim : *window().m_primlist)
{
switch (prim.type)
{
@@ -1423,6 +1466,12 @@ void renderer_d3d9::batch_vectors(int vector_count)
{
batch_vector(prim);
cached_flags = prim.flags;
+
+ const uint8_t a = (uint8_t)std::round(prim.color.a * 255);
+ const uint8_t r = (uint8_t)std::round(prim.color.r * 255);
+ const uint8_t g = (uint8_t)std::round(prim.color.g * 255);
+ const uint8_t b = (uint8_t)std::round(prim.color.b * 255);
+ tint = (a << 24) | (b << 16) | (g << 8) | r;
}
break;
@@ -1433,6 +1482,12 @@ void renderer_d3d9::batch_vectors(int vector_count)
quad_height = prim.get_quad_height();
target_width = prim.get_full_quad_width();
target_height = prim.get_full_quad_height();
+
+ const uint8_t a = (uint8_t)std::round(prim.color.a * 255);
+ const uint8_t r = (uint8_t)std::round(prim.color.r * 255);
+ const uint8_t g = (uint8_t)std::round(prim.color.g * 255);
+ const uint8_t b = (uint8_t)std::round(prim.color.b * 255);
+ tint = (a << 24) | (b << 16) | (g << 8) | r;
}
break;
@@ -1446,15 +1501,15 @@ void renderer_d3d9::batch_vectors(int vector_count)
if (m_shaders->enabled())
{
bool orientation_swap_xy =
- (win->machine().system().flags & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY;
+ (window().machine().system().flags & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY;
bool rotation_swap_xy =
- (win->target()->orientation() & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY;
+ (window().target()->orientation() & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY;
bool swap_xy = orientation_swap_xy ^ rotation_swap_xy;
- bool rotation_0 = win->target()->orientation() == ROT0;
- bool rotation_90 = win->target()->orientation() == ROT90;
- bool rotation_180 = win->target()->orientation() == ROT180;
- bool rotation_270 = win->target()->orientation() == ROT270;
+ bool rotation_0 = window().target()->orientation() == ROT0;
+ bool rotation_90 = window().target()->orientation() == ROT90;
+ bool rotation_180 = window().target()->orientation() == ROT180;
+ bool rotation_270 = window().target()->orientation() == ROT270;
bool flip_x =
((rotation_0 || rotation_270) && orientation_swap_xy) ||
((rotation_180 || rotation_270) && !orientation_swap_xy);
@@ -1510,7 +1565,7 @@ void renderer_d3d9::batch_vectors(int vector_count)
}
// now add a polygon entry
- m_poly[m_numpolys].init(D3DPT_TRIANGLELIST, triangle_count, vertex_count, cached_flags, nullptr, D3DTOP_MODULATE, quad_width, quad_height);
+ m_poly[m_numpolys].init(D3DPT_TRIANGLELIST, triangle_count, vertex_count, cached_flags, nullptr, D3DTOP_MODULATE, quad_width, quad_height, tint);
m_numpolys++;
}
@@ -1652,10 +1707,10 @@ void renderer_d3d9::draw_line(const render_primitive &prim)
vertex[3].v0 = stop.c.y;
// determine the color of the line
- auto r = (int32_t)(prim.color.r * 255.0f);
- auto g = (int32_t)(prim.color.g * 255.0f);
- auto b = (int32_t)(prim.color.b * 255.0f);
- auto a = (int32_t)(prim.color.a * 255.0f);
+ auto r = (int32_t)std::round(prim.color.r * 255.0f);
+ auto g = (int32_t)std::round(prim.color.g * 255.0f);
+ auto b = (int32_t)std::round(prim.color.b * 255.0f);
+ auto a = (int32_t)std::round(prim.color.a * 255.0f);
DWORD color = D3DCOLOR_ARGB(a, r, g, b);
// set the color, Z parameters to standard values
@@ -1667,7 +1722,7 @@ void renderer_d3d9::draw_line(const render_primitive &prim)
}
// now add a polygon entry
- m_poly[m_numpolys].init(D3DPT_TRIANGLESTRIP, 2, 4, prim.flags, nullptr, D3DTOP_MODULATE, 0.0f, 0.0f);
+ m_poly[m_numpolys].init(D3DPT_TRIANGLESTRIP, 2, 4, prim.flags, nullptr, D3DTOP_MODULATE, 0.0f, 0.0f, (uint32_t)color);
m_numpolys++;
}
@@ -1721,10 +1776,10 @@ void renderer_d3d9::draw_quad(const render_primitive &prim)
}
// determine the color, allowing for over modulation
- auto r = (int32_t)(prim.color.r * 255.0f);
- auto g = (int32_t)(prim.color.g * 255.0f);
- auto b = (int32_t)(prim.color.b * 255.0f);
- auto a = (int32_t)(prim.color.a * 255.0f);
+ auto r = (int32_t)std::round(prim.color.r * 255.0f);
+ auto g = (int32_t)std::round(prim.color.g * 255.0f);
+ auto b = (int32_t)std::round(prim.color.b * 255.0f);
+ auto a = (int32_t)std::round(prim.color.a * 255.0f);
DWORD color = D3DCOLOR_ARGB(a, r, g, b);
// adjust half pixel X/Y offset, set the color, Z parameters to standard values
@@ -1738,7 +1793,7 @@ void renderer_d3d9::draw_quad(const render_primitive &prim)
}
// now add a polygon entry
- m_poly[m_numpolys].init(D3DPT_TRIANGLESTRIP, 2, 4, prim.flags, texture, D3DTOP_MODULATE, quad_width, quad_height);
+ m_poly[m_numpolys].init(D3DPT_TRIANGLESTRIP, 2, 4, prim.flags, texture, D3DTOP_MODULATE, quad_width, quad_height, (uint32_t)color);
m_numpolys++;
}
@@ -1798,7 +1853,7 @@ void renderer_d3d9::primitive_flush_pending()
m_lockedbuf = nullptr;
// set the stream
- result = m_device->SetStreamSource(0, m_vertexbuf, 0, sizeof(vertex));
+ result = m_device->SetStreamSource(0, m_vertexbuf.Get(), 0, sizeof(vertex));
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device SetStreamSource call\n", result);
@@ -1826,9 +1881,17 @@ void renderer_d3d9::primitive_flush_pending()
newfilter = FALSE;
if (PRIMFLAG_GET_SCREENTEX(flags))
newfilter = video_config.filter;
- set_filter(newfilter);
- set_wrap(PRIMFLAG_GET_TEXWRAP(flags) ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP);
- set_modmode(m_poly[polynum].modmode());
+
+ if (m_shaders->enabled())
+ {
+ m_shaders->set_filter(newfilter);
+ }
+ else
+ {
+ set_filter(newfilter);
+ set_wrap(PRIMFLAG_GET_TEXWRAP(flags) ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP);
+ set_modmode(m_poly[polynum].modmode());
+ }
}
if (vertnum + m_poly[polynum].numverts() > m_numverts)
@@ -1841,9 +1904,6 @@ void renderer_d3d9::primitive_flush_pending()
if(m_shaders->enabled())
{
- // reset blend mode (handled by shader passes)
- set_blendmode(BLENDMODE_NONE);
-
m_shaders->render_quad(&m_poly[polynum], vertnum);
}
else
@@ -1896,19 +1956,6 @@ void renderer_d3d9::set_sliders_dirty()
texture_info::~texture_info()
{
- if (m_d3dfinaltex != nullptr)
- {
- if (m_d3dtex == m_d3dfinaltex)
- m_d3dtex = nullptr;
-
- m_d3dfinaltex->Release();
- }
-
- if (m_d3dtex != nullptr)
- m_d3dtex->Release();
-
- if (m_d3dsurface != nullptr)
- m_d3dsurface->Release();
}
@@ -1916,153 +1963,117 @@ texture_info::~texture_info()
// texture_info constructor
//============================================================
-texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* texsource, int prescale, uint32_t flags)
+texture_info::texture_info(d3d_texture_manager &manager, const render_texinfo* texsource, int prescale, uint32_t flags)
+ : m_texture_manager(manager)
+ , m_renderer(manager.get_d3d())
+ , m_hash(manager.texture_compute_hash(texsource, flags))
+ , m_flags(flags)
+ , m_texinfo(*texsource)
+ , m_type(!PRIMFLAG_GET_SCREENTEX(flags) ? TEXTURE_TYPE_PLAIN : TEXTURE_TYPE_DYNAMIC) // required to compute texture size
+ , m_xprescale(PRIMFLAG_GET_SCREENTEX(flags) ? prescale : 1)
+ , m_yprescale(PRIMFLAG_GET_SCREENTEX(flags) ? prescale : 1)
{
- HRESULT result;
-
- // fill in the core data
- m_texture_manager = manager;
- m_renderer = m_texture_manager->get_d3d();
- m_hash = m_texture_manager->texture_compute_hash(texsource, flags);
- m_flags = flags;
- m_texinfo = *texsource;
- m_xprescale = prescale;
- m_yprescale = prescale;
-
- m_d3dtex = nullptr;
- m_d3dsurface = nullptr;
- m_d3dfinaltex = nullptr;
-
- // determine texture type, required to compute texture size
- if (!PRIMFLAG_GET_SCREENTEX(flags))
- {
- m_type = TEXTURE_TYPE_PLAIN;
- }
- else
- {
- m_type = TEXTURE_TYPE_DYNAMIC;
- }
-
// compute the size
compute_size(texsource->width, texsource->height);
- // non-screen textures are easy
if (!PRIMFLAG_GET_SCREENTEX(flags))
{
+ // non-screen textures are easy
assert(PRIMFLAG_TEXFORMAT(flags) != TEXFORMAT_YUY16);
- result = m_renderer->get_device()->CreateTexture(m_rawdims.c.x, m_rawdims.c.y, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &m_d3dtex, nullptr);
+ const HRESULT result = m_renderer.get_device()->CreateTexture(m_rawdims.c.x, m_rawdims.c.y, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &m_d3dtex, nullptr);
if (FAILED(result))
goto error;
+
m_d3dfinaltex = m_d3dtex;
}
-
- // screen textures are allocated differently
else
{
- D3DFORMAT format;
- DWORD usage = D3DUSAGE_DYNAMIC;
- D3DPOOL pool = D3DPOOL_DEFAULT;
- int maxdim = std::max(m_renderer->get_presentation()->BackBufferWidth, m_renderer->get_presentation()->BackBufferHeight);
+ // screen textures are allocated differently
// pick the format
+ const DWORD usage = D3DUSAGE_DYNAMIC;
+ const D3DPOOL pool = D3DPOOL_DEFAULT;
+ D3DFORMAT format;
if (PRIMFLAG_GET_TEXFORMAT(flags) == TEXFORMAT_YUY16)
- {
- format = m_texture_manager->get_yuv_format();
- }
+ format = m_texture_manager.get_yuv_format();
else if (PRIMFLAG_GET_TEXFORMAT(flags) == TEXFORMAT_ARGB32)
- {
format = D3DFMT_A8R8G8B8;
- }
else
- {
- format = m_renderer->get_screen_format();
- }
+ format = m_renderer.get_screen_format();
// don't prescale above screen size
- while (m_xprescale > 1 && m_rawdims.c.x * m_xprescale >= 2 * maxdim)
- {
+ const int maxdim = std::max(
+ m_renderer.get_presentation()->BackBufferWidth,
+ m_renderer.get_presentation()->BackBufferHeight);
+
+ while ((m_xprescale > 1) && ((m_rawdims.c.x * m_xprescale) >= (2 * maxdim)))
m_xprescale--;
- }
- while (m_xprescale > 1 && m_rawdims.c.x * m_xprescale > manager->get_max_texture_width())
- {
+ while ((m_xprescale > 1) && ((m_rawdims.c.x * m_xprescale) > manager.get_max_texture_width()))
m_xprescale--;
- }
- while (m_yprescale > 1 && m_rawdims.c.y * m_yprescale >= 2 * maxdim)
- {
+
+ while ((m_yprescale > 1) && ((m_rawdims.c.y * m_yprescale) >= (2 * maxdim)))
m_yprescale--;
- }
- while (m_yprescale > 1 && m_rawdims.c.y * m_yprescale > manager->get_max_texture_height())
- {
+ while ((m_yprescale > 1) && ((m_rawdims.c.y * m_yprescale) > manager.get_max_texture_height()))
m_yprescale--;
- }
-
- auto win = m_renderer->assert_window();
- int prescale = win->prescale();
- if (m_xprescale != prescale || m_yprescale != prescale)
- {
+ const int prescale = m_renderer.window().prescale();
+ if ((m_xprescale != prescale) || (m_yprescale != prescale))
osd_printf_verbose("Direct3D: adjusting prescale from %dx%d to %dx%d\n", prescale, prescale, m_xprescale, m_yprescale);
- }
// loop until we allocate something or error
+ HRESULT result;
for (int attempt = 0; attempt < 2; attempt++)
{
- // second attempt is always 1:1
- if (attempt == 1)
- {
- m_xprescale = m_yprescale = 1;
- }
-
- // screen textures with no prescaling are pretty easy
- if (m_xprescale == 1 && m_yprescale == 1)
+ if ((m_xprescale == 1) && (m_yprescale == 1))
{
- result = m_renderer->get_device()->CreateTexture(m_rawdims.c.x, m_rawdims.c.y, 1, usage, format, pool, &m_d3dtex, nullptr);
+ // screen textures with no prescaling are pretty easy
+ result = m_renderer.get_device()->CreateTexture(m_rawdims.c.x, m_rawdims.c.y, 1, usage, format, pool, &m_d3dtex, nullptr);
if (result == D3D_OK)
{
m_d3dfinaltex = m_d3dtex;
break;
}
}
- // screen textures with prescaling require two allocations
else
{
- result = m_renderer->get_device()->CreateTexture(m_rawdims.c.x, m_rawdims.c.y, 1, usage, format, pool, &m_d3dtex, nullptr);
- if (FAILED(result))
+ // screen textures with prescaling require two allocations
+ result = m_renderer.get_device()->CreateTexture(m_rawdims.c.x, m_rawdims.c.y, 1, usage, format, pool, &m_d3dtex, nullptr);
+ if (result == D3D_OK)
{
- continue;
- }
+ // for the target surface, we allocate a render target texture
+ const int scwidth = m_rawdims.c.x * m_xprescale;
+ const int scheight = m_rawdims.c.y * m_yprescale;
- // for the target surface, we allocate a render target texture
- int scwidth = m_rawdims.c.x * m_xprescale;
- int scheight = m_rawdims.c.y * m_yprescale;
+ // target surfaces typically cannot be YCbCr, so we always pick RGB in that case
+ const D3DFORMAT finalfmt = (format != m_texture_manager.get_yuv_format()) ? format : D3DFMT_A8R8G8B8;
- // target surfaces typically cannot be YCbCr, so we always pick RGB in that case
- D3DFORMAT finalfmt = (format != m_texture_manager->get_yuv_format()) ? format : D3DFMT_A8R8G8B8;
+ result = m_renderer.get_device()->CreateTexture(scwidth, scheight, 1, D3DUSAGE_RENDERTARGET, finalfmt, D3DPOOL_DEFAULT, &m_d3dfinaltex, nullptr);
+ if (result == D3D_OK)
+ break;
- result = m_renderer->get_device()->CreateTexture(scwidth, scheight, 1, D3DUSAGE_RENDERTARGET, finalfmt, D3DPOOL_DEFAULT, &m_d3dfinaltex, nullptr);
- if (result == D3D_OK)
- {
- break;
+ m_d3dtex.Reset();
}
-
- m_d3dtex->Release();
- m_d3dtex = nullptr;
}
+
+ // second attempt is always 1:1
+ m_xprescale = m_yprescale = 1;
}
+ if (FAILED(result))
+ goto error;
}
// copy the data to the texture
+ assert(m_d3dtex);
+ assert(m_d3dfinaltex);
set_data(texsource, flags);
return;
error:
- d3dintf->post_fx_available = false;
+ m_renderer.set_post_fx_unavailable();
osd_printf_error("Direct3D: Critical warning: A texture failed to allocate. Expect things to get bad quickly.\n");
- if (m_d3dsurface != nullptr)
- m_d3dsurface->Release();
- if (m_d3dtex != nullptr)
- m_d3dtex->Release();
+ m_d3dsurface.Reset();
+ m_d3dtex.Reset();
}
@@ -2076,11 +2087,11 @@ void texture_info::compute_size_subroutine(int texwidth, int texheight, int* p_w
int finalwidth = texwidth;
// adjust the aspect ratio if we need to
- while (finalwidth < finalheight && finalheight / finalwidth > m_texture_manager->get_max_texture_aspect())
+ while (finalwidth < finalheight && finalheight / finalwidth > m_texture_manager.get_max_texture_aspect())
{
finalwidth *= 2;
}
- while (finalheight < finalwidth && finalwidth / finalheight > m_texture_manager->get_max_texture_aspect())
+ while (finalheight < finalwidth && finalwidth / finalheight > m_texture_manager.get_max_texture_aspect())
{
finalheight *= 2;
}
@@ -2102,7 +2113,7 @@ void texture_info::compute_size(int texwidth, int texheight)
m_xborderpix = 0;
m_yborderpix = 0;
- bool shaders_enabled = m_renderer->get_shaders()->enabled();
+ bool shaders_enabled = m_renderer.get_shaders()->enabled();
bool wrap_texture = (m_flags & PRIMFLAG_TEXWRAP_MASK) == PRIMFLAG_TEXWRAP_MASK;
// skip border when shaders are enabled
@@ -2126,7 +2137,7 @@ void texture_info::compute_size(int texwidth, int texheight)
compute_size_subroutine(finalwidth, finalheight, &finalwidth, &finalheight);
// if we added pixels for the border, and that just barely pushed us over, take it back
- if (finalwidth > m_texture_manager->get_max_texture_width() || finalheight > m_texture_manager->get_max_texture_height())
+ if (finalwidth > m_texture_manager.get_max_texture_width() || finalheight > m_texture_manager.get_max_texture_height())
{
finalheight = texheight;
finalwidth = texwidth;
@@ -2139,10 +2150,18 @@ void texture_info::compute_size(int texwidth, int texheight)
}
// if we're above the max width/height, do what?
- if (finalwidth > m_texture_manager->get_max_texture_width() || finalheight > m_texture_manager->get_max_texture_height())
+ if (finalwidth > m_texture_manager.get_max_texture_width() || finalheight > m_texture_manager.get_max_texture_height())
{
static bool printed = false;
- if (!printed) osd_printf_warning("Texture too big! (wanted: %dx%d, max is %dx%d)\n", finalwidth, finalheight, (int)m_texture_manager->get_max_texture_width(), (int)m_texture_manager->get_max_texture_height());
+ if (!printed)
+ {
+ osd_printf_warning(
+ "Texture too big! (wanted: %dx%d, max is %dx%d)\n",
+ finalwidth,
+ finalheight,
+ m_texture_manager.get_max_texture_width(),
+ m_texture_manager.get_max_texture_height());
+ }
printed = true;
}
@@ -2395,9 +2414,9 @@ void texture_info::set_data(const render_texinfo *texsource, uint32_t flags)
break;
case TEXFORMAT_YUY16:
- if (m_texture_manager->get_yuv_format() == D3DFMT_YUY2)
+ if (m_texture_manager.get_yuv_format() == D3DFMT_YUY2)
copyline_yuy16_to_yuy2((uint16_t *)dst, (uint16_t *)texsource->base + srcy * texsource->rowpixels, texsource->width, texsource->palette);
- else if (m_texture_manager->get_yuv_format() == D3DFMT_UYVY)
+ else if (m_texture_manager.get_yuv_format() == D3DFMT_UYVY)
copyline_yuy16_to_uyvy((uint16_t *)dst, (uint16_t *)texsource->base + srcy * texsource->rowpixels, texsource->width, texsource->palette);
else
copyline_yuy16_to_argb((uint32_t *)dst, (uint16_t *)texsource->base + srcy * texsource->rowpixels, texsource->width, texsource->palette);
@@ -2432,48 +2451,51 @@ void texture_info::set_data(const render_texinfo *texsource, uint32_t flags)
void texture_info::prescale()
{
- IDirect3DSurface9 *scale_surface;
- HRESULT result;
- int i;
-
// if we don't need to, just skip it
- if (m_d3dtex == m_d3dfinaltex)
+ if (m_d3dtex.Get() == m_d3dfinaltex.Get())
+ {
+ assert(m_xprescale == 1);
+ assert(m_yprescale == 1);
return;
+ }
+
+ assert(m_d3dtex);
+ assert((m_xprescale > 1) || (m_yprescale > 1));
+ HRESULT result;
// for all cases, we need to get the surface of the render target
+ Microsoft::WRL::ComPtr<IDirect3DSurface9> scale_surface;
result = m_d3dfinaltex->GetSurfaceLevel(0, &scale_surface);
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during texture GetSurfaceLevel call\n", result);
// if we have an offscreen plain surface, we can just StretchRect to it
- IDirect3DSurface9 *backbuffer;
-
- assert(m_d3dtex != nullptr);
// first remember the original render target and set the new one
- result = m_renderer->get_device()->GetRenderTarget(0, &backbuffer);
+ Microsoft::WRL::ComPtr<IDirect3DSurface9> backbuffer;
+ result = m_renderer.get_device()->GetRenderTarget(0, &backbuffer);
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device GetRenderTarget call\n", result);
- result = m_renderer->get_device()->SetRenderTarget(0, scale_surface);
+ result = m_renderer.get_device()->SetRenderTarget(0, scale_surface.Get());
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call 1\n", result);
- m_renderer->reset_render_states();
+ m_renderer.reset_render_states();
// start the scene
- result = m_renderer->get_device()->BeginScene();
+ result = m_renderer.get_device()->BeginScene();
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device BeginScene call\n", result);
// configure the rendering pipeline
- m_renderer->set_filter(FALSE);
- m_renderer->set_blendmode(BLENDMODE_NONE);
- result = m_renderer->get_device()->SetTexture(0, m_d3dtex);
+ m_renderer.set_filter(FALSE);
+ m_renderer.set_blendmode(BLENDMODE_NONE);
+ result = m_renderer.get_device()->SetTexture(0, m_d3dtex.Get());
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device SetTexture call\n", result);
// lock the vertex buffer
vertex *lockedbuf;
- result = m_renderer->get_vertex_buffer()->Lock(0, 0, (VOID **)&lockedbuf, D3DLOCK_DISCARD);
+ result = m_renderer.get_vertex_buffer()->Lock(0, 0, (VOID **)&lockedbuf, D3DLOCK_DISCARD);
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during vertex buffer lock call\n", result);
@@ -2498,7 +2520,7 @@ void texture_info::prescale()
lockedbuf[3].v0 = (float)(m_texinfo.height + 2 * m_yborderpix) / (float)m_rawdims.c.y;
// reset the remaining vertex parameters
- for (i = 0; i < 4; i++)
+ for (int i = 0; i < 4; i++)
{
lockedbuf[i].z = 0.0f;
lockedbuf[i].rhw = 1.0f;
@@ -2506,32 +2528,32 @@ void texture_info::prescale()
}
// unlock the vertex buffer
- result = m_renderer->get_vertex_buffer()->Unlock();
+ result = m_renderer.get_vertex_buffer()->Unlock();
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during vertex buffer unlock call\n", result);
// set the stream and draw the triangle strip
- result = m_renderer->get_device()->SetStreamSource(0, m_renderer->get_vertex_buffer(), 0, sizeof(vertex));
+ result = m_renderer.get_device()->SetStreamSource(0, m_renderer.get_vertex_buffer(), 0, sizeof(vertex));
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device SetStreamSource call\n", result);
- result = m_renderer->get_device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
+ result = m_renderer.get_device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device DrawPrimitive call\n", result);
// end the scene
- result = m_renderer->get_device()->EndScene();
+ result = m_renderer.get_device()->EndScene();
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device end_scene call\n", result);
// reset the render target and release our reference to the backbuffer
- result = m_renderer->get_device()->SetRenderTarget(0, backbuffer);
+ result = m_renderer.get_device()->SetRenderTarget(0, backbuffer.Get());
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call 2\n", result);
- backbuffer->Release();
- m_renderer->reset_render_states();
+ backbuffer.Reset();
+ m_renderer.reset_render_states();
// release our reference to the target surface
- scale_surface->Release();
+ scale_surface.Reset();
}
@@ -2541,35 +2563,6 @@ void texture_info::prescale()
d3d_render_target::~d3d_render_target()
{
- for (int index = 0; index < MAX_BLOOM_COUNT; index++)
- {
- if (bloom_texture[index] != nullptr)
- bloom_texture[index]->Release();
-
- if (bloom_surface[index] != nullptr)
- bloom_surface[index]->Release();
- }
-
- for (int index = 0; index < 2; index++)
- {
- if (source_texture[index] != nullptr)
- source_texture[index]->Release();
-
- if (source_surface[index] != nullptr)
- source_surface[index]->Release();
-
- if (target_texture[index] != nullptr)
- target_texture[index]->Release();
-
- if (target_surface[index] != nullptr)
- target_surface[index]->Release();
- }
-
- if (cache_texture != nullptr)
- cache_texture->Release();
-
- if (cache_surface != nullptr)
- cache_surface->Release();
}
@@ -2610,9 +2603,7 @@ bool d3d_render_target::init(renderer_d3d9 *d3d, int source_width, int source_he
cache_texture->GetSurfaceLevel(0, &cache_surface);
- auto win = d3d->assert_window();
-
- const screen_device *first_screen = screen_device_enumerator(win->machine().root_device()).first();
+ const screen_device *first_screen = screen_device_enumerator(d3d->window().machine().root_device()).first();
bool vector_screen =
first_screen != nullptr &&
first_screen->screen_type() == SCREEN_TYPE_VECTOR;
diff --git a/src/osd/modules/render/drawd3d.h b/src/osd/modules/render/drawd3d.h
index 2fa4a30873c..3ab7651d87c 100644
--- a/src/osd/modules/render/drawd3d.h
+++ b/src/osd/modules/render/drawd3d.h
@@ -10,20 +10,24 @@
#pragma once
+#include "d3d/d3dcomm.h"
-#ifdef OSD_WINDOWS
+#include "modules/lib/osdlib.h"
+#include "modules/osdwindow.h"
+
+#include "sliderdirtynotifier.h"
#include <windows.h>
#include <tchar.h>
#include <mmsystem.h>
#include <d3d9.h>
#include <d3dx9.h>
-#include <cmath>
#undef interface
-#include "d3d/d3dcomm.h"
-#include "sliderdirtynotifier.h"
-#include "modules/lib/osdlib.h"
+#include <memory>
+#include <vector>
+#include <cmath>
+
//============================================================
// CONSTANTS
@@ -36,15 +40,6 @@
// TYPE DEFINITIONS
//============================================================
-struct d3d_base
-{
- // internal objects
- IDirect3D9 *d3dobj;
- bool post_fx_available;
-
- osd::dynamic_module::ptr d3d9_dll;
-};
-
class shaders;
struct hlsl_options;
@@ -52,11 +47,10 @@ struct hlsl_options;
class renderer_d3d9 : public osd_renderer, public slider_dirty_notifier
{
public:
- renderer_d3d9(std::shared_ptr<osd_window> window);
- virtual ~renderer_d3d9();
+ using IDirect3D9Ptr = Microsoft::WRL::ComPtr<IDirect3D9>;
- static bool init(running_machine &machine);
- static void exit();
+ renderer_d3d9(osd_window &window, const IDirect3D9Ptr &d3dobj);
+ virtual ~renderer_d3d9();
virtual int create() override;
virtual render_primitive_list *get_primitives() override;
@@ -113,11 +107,13 @@ public:
vec2f get_dims() const { return vec2f(m_width, m_height); }
int get_height() const { return m_height; }
int get_refresh() const { return m_refresh; }
+ bool post_fx_available() const { return m_post_fx_available; }
+ void set_post_fx_unavailable() { m_post_fx_available = false; }
- IDirect3DDevice9 * get_device() const { return m_device; }
+ IDirect3DDevice9 * get_device() const { return m_device.Get(); }
D3DPRESENT_PARAMETERS * get_presentation() { return &m_presentation; }
- IDirect3DVertexBuffer9 *get_vertex_buffer() const { return m_vertexbuf; }
+ IDirect3DVertexBuffer9 *get_vertex_buffer() const { return m_vertexbuf.Get(); }
void set_toggle(bool toggle) { m_toggle = toggle; }
@@ -125,27 +121,32 @@ public:
D3DFORMAT get_pixel_format() const { return m_pixformat; }
D3DDISPLAYMODE get_origmode() const { return m_origmode; }
- uint32_t get_last_texture_flags() const { return m_last_texture_flags; }
+ uint32_t get_last_texture_flags() const { return m_last_texture_flags; }
d3d_texture_manager * get_texture_manager() const { return m_texture_manager.get(); }
texture_info * get_default_texture();
- shaders * get_shaders() const { return m_shaders; }
+ shaders * get_shaders() const { return m_shaders.get(); }
private:
+ using IDirect3DDevice9Ptr = Microsoft::WRL::ComPtr<IDirect3DDevice9>;
+ using IDirect3DVertexBuffer9Ptr = Microsoft::WRL::ComPtr<IDirect3DVertexBuffer9>;
+
+ const IDirect3D9Ptr m_d3dobj; // Direct3D 9 API object
int m_adapter; // ordinal adapter number
int m_width; // current width
int m_height; // current height
int m_refresh; // current refresh rate
int m_create_error_count; // number of consecutive create errors
+ bool m_post_fx_available;
- IDirect3DDevice9 * m_device; // pointer to the Direct3DDevice object
+ IDirect3DDevice9Ptr m_device; // pointer to the Direct3DDevice object
int m_gamma_supported; // is full screen gamma supported?
D3DPRESENT_PARAMETERS m_presentation; // set of presentation parameters
D3DDISPLAYMODE m_origmode; // original display mode for the adapter
D3DFORMAT m_pixformat; // pixel format we are using
- IDirect3DVertexBuffer9 *m_vertexbuf; // pointer to the vertex buffer object
+ IDirect3DVertexBuffer9Ptr m_vertexbuf; // pointer to the vertex buffer object
vertex * m_lockedbuf; // pointer to the locked vertex buffer
int m_numverts; // number of accumulated vertices
@@ -160,20 +161,18 @@ private:
D3DFORMAT m_screen_format; // format to use for screen textures
texture_info * m_last_texture; // previous texture
- uint32_t m_last_texture_flags; // previous texture flags
+ uint32_t m_last_texture_flags; // previous texture flags
int m_last_blendenable; // previous blendmode
int m_last_blendop; // previous blendmode
int m_last_blendsrc; // previous blendmode
int m_last_blenddst; // previous blendmode
int m_last_filter; // previous texture filter
- uint32_t m_last_wrap; // previous wrap state
+ uint32_t m_last_wrap; // previous wrap state
int m_last_modmode; // previous texture modulation
- shaders * m_shaders; // HLSL interface
+ std::unique_ptr<shaders> m_shaders; // HLSL interface
std::unique_ptr<d3d_texture_manager> m_texture_manager; // texture manager
};
-#endif // OSD_WINDOWS
-
#endif // MAME_OSD_MODULES_RENDER_DRAWD3D_H
diff --git a/src/osd/modules/render/drawgdi.cpp b/src/osd/modules/render/drawgdi.cpp
index 32dac94c24a..f922ca24e8f 100644
--- a/src/osd/modules/render/drawgdi.cpp
+++ b/src/osd/modules/render/drawgdi.cpp
@@ -2,21 +2,53 @@
// copyright-holders:Aaron Giles
//============================================================
//
-// drawgdi.c - Win32 GDI drawing
+// drawgdi.cpp - Win32 GDI drawing
//
//============================================================
+#include "render_module.h"
+
+#include "modules/osdmodule.h"
+
+#if defined(OSD_WINDOWS)
+
+#include "window.h"
+
+// emu
#include "emu.h"
-#include "drawgdi.h"
#include "rendersw.hxx"
-//============================================================
-// destructor
-//============================================================
+// standard windows headers
+#include <windows.h>
+
+
+namespace osd {
+
+namespace {
-renderer_gdi::~renderer_gdi()
+// renderer_gdi is the information for the current screen
+class renderer_gdi : public osd_renderer
{
-}
+public:
+ renderer_gdi(osd_window &window)
+ : osd_renderer(window)
+ , m_bmdata(nullptr)
+ , m_bmsize(0)
+ {
+ }
+
+ virtual int create() override;
+ virtual render_primitive_list *get_primitives() override;
+ virtual int draw(const int update) override;
+ virtual void save() override {}
+ virtual void record() override {}
+ virtual void toggle_fsfx() override {}
+
+private:
+ BITMAPINFO m_bminfo;
+ std::unique_ptr<uint8_t []> m_bmdata;
+ size_t m_bmsize;
+};
//============================================================
// renderer_gdi::create
@@ -34,6 +66,7 @@ int renderer_gdi::create()
m_bminfo.bmiHeader.biYPelsPerMeter = 0;
m_bminfo.bmiHeader.biClrUsed = 0;
m_bminfo.bmiHeader.biClrImportant = 0;
+
return 0;
}
@@ -43,16 +76,12 @@ int renderer_gdi::create()
render_primitive_list *renderer_gdi::get_primitives()
{
- auto win = try_getwindow();
- if (win == nullptr)
+ osd_dim const dimensions = window().get_size();
+ if ((dimensions.width() <= 0) || (dimensions.height() <= 0))
return nullptr;
- RECT client;
- GetClientRect(std::static_pointer_cast<win_window_info>(win)->platform_window(), &client);
- if ((rect_width(&client) == 0) || (rect_height(&client) == 0))
- return nullptr;
- win->target()->set_bounds(rect_width(&client), rect_height(&client), win->pixel_aspect());
- return &win->target()->get_primitives();
+ window().target()->set_bounds(dimensions.width(), dimensions.height(), window().pixel_aspect());
+ return &window().target()->get_primitives();
}
//============================================================
@@ -61,23 +90,24 @@ render_primitive_list *renderer_gdi::get_primitives()
int renderer_gdi::draw(const int update)
{
- auto win = assert_window();
+ auto &win = dynamic_cast<win_window_info &>(window());
// we don't have any special resize behaviors
- if (win->m_resize_state == RESIZE_STATE_PENDING)
- win->m_resize_state = RESIZE_STATE_NORMAL;
+ if (win.m_resize_state == win_window_info::RESIZE_STATE_PENDING)
+ win.m_resize_state = win_window_info::RESIZE_STATE_NORMAL;
// get the target bounds
RECT bounds;
- GetClientRect(std::static_pointer_cast<win_window_info>(win)->platform_window(), &bounds);
+ GetClientRect(win.platform_window(), &bounds);
// compute width/height/pitch of target
- int width = rect_width(&bounds);
- int height = rect_height(&bounds);
- int pitch = (width + 3) & ~3;
+ osd_dim const dimensions = win.get_size();
+ int const width = dimensions.width();
+ int const height = dimensions.height();
+ int const pitch = (width + 3) & ~3;
// make sure our temporary bitmap is big enough
- if (pitch * height * 4 > m_bmsize)
+ if ((pitch * height * 4) > m_bmsize)
{
m_bmsize = pitch * height * 4 * 2;
m_bmdata.reset();
@@ -85,9 +115,9 @@ int renderer_gdi::draw(const int update)
}
// draw the primitives to the bitmap
- win->m_primlist->acquire_lock();
- software_renderer<uint32_t, 0,0,0, 16,8,0>::draw_primitives(*win->m_primlist, m_bmdata.get(), width, height, pitch);
- win->m_primlist->release_lock();
+ win.m_primlist->acquire_lock();
+ software_renderer<uint32_t, 0,0,0, 16,8,0>::draw_primitives(*win.m_primlist, m_bmdata.get(), width, height, pitch);
+ win.m_primlist->release_lock();
// fill in bitmap-specific info
m_bminfo.bmiHeader.biWidth = pitch;
@@ -95,8 +125,43 @@ int renderer_gdi::draw(const int update)
// blit to the screen
StretchDIBits(
- win->m_dc, 0, 0, width, height,
+ win.m_dc, 0, 0, width, height,
0, 0, width, height,
m_bmdata.get(), &m_bminfo, DIB_RGB_COLORS, SRCCOPY);
+
return 0;
}
+
+
+class video_gdi : public osd_module, public render_module
+{
+public:
+ video_gdi() : osd_module(OSD_RENDERER_PROVIDER, "gdi") { }
+
+ virtual int init(osd_interface &osd, osd_options const &options) override { return 0; }
+ virtual void exit() override { }
+
+ virtual std::unique_ptr<osd_renderer> create(osd_window &window) override;
+
+protected:
+ virtual unsigned flags() const override { return FLAG_INTERACTIVE; }
+};
+
+std::unique_ptr<osd_renderer> video_gdi::create(osd_window &window)
+{
+ return std::make_unique<renderer_gdi>(window);
+}
+
+} // anonymous namespace
+
+} // namespace osd
+
+
+#else // defined(OSD_WINDOWS)
+
+namespace osd { namespace { MODULE_NOT_SUPPORTED(video_gdi, OSD_RENDERER_PROVIDER, "gdi") } }
+
+#endif // defined(OSD_WINDOWS)
+
+
+MODULE_DEFINITION(RENDERER_GDI, osd::video_gdi)
diff --git a/src/osd/modules/render/drawgdi.h b/src/osd/modules/render/drawgdi.h
deleted file mode 100644
index 0dfc4bf2641..00000000000
--- a/src/osd/modules/render/drawgdi.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
-//============================================================
-//
-// drawgdi.h - Win32 GDI drawing
-//
-//============================================================
-#ifndef MAME_OSD_MODULES_RENDER_DRAWGDI_H
-#define MAME_OSD_MODULES_RENDER_DRAWGDI_H
-
-#pragma once
-
-
-// standard windows headers
-#include <windows.h>
-
-// MAME headers
-
-// MAMEOS headers
-#include "window.h"
-
-
-//============================================================
-// TYPE DEFINITIONS
-//============================================================
-
-/* renderer_gdi is the information for the current screen */
-class renderer_gdi : public osd_renderer
-{
-public:
- renderer_gdi(std::shared_ptr<osd_window> window)
- : osd_renderer(window, FLAG_NONE)
- , m_bmdata(nullptr)
- , m_bmsize(0)
- {
- }
- virtual ~renderer_gdi();
-
- static bool init(running_machine &machine) { return false; }
- static void exit() { }
-
- virtual int create() override;
- virtual render_primitive_list *get_primitives() override;
- virtual int draw(const int update) override;
- virtual void save() override {}
- virtual void record() override {}
- virtual void toggle_fsfx() override {}
-
-private:
- BITMAPINFO m_bminfo;
- std::unique_ptr<uint8_t []> m_bmdata;
- size_t m_bmsize;
-};
-
-#endif // MAME_OSD_MODULES_RENDER_DRAWGDI_H
diff --git a/src/osd/modules/render/drawnone.cpp b/src/osd/modules/render/drawnone.cpp
index 6f591879038..55ce1bbed18 100644
--- a/src/osd/modules/render/drawnone.cpp
+++ b/src/osd/modules/render/drawnone.cpp
@@ -6,25 +6,76 @@
//
//============================================================
-// standard windows headers
-#include <windows.h>
+#include "render_module.h"
-#include "drawnone.h"
+#include "modules/lib/osdobj_common.h"
+#include "modules/osdmodule.h"
+#include "modules/osdwindow.h"
-//============================================================
-// drawnone_window_get_primitives
-//============================================================
+#include "main.h"
+#include "render.h"
+
+#include <memory>
+
+
+namespace osd {
+
+namespace {
+
+class renderer_none : public osd_renderer
+{
+public:
+ renderer_none(osd_window &window) : osd_renderer(window) { }
+
+ virtual int create() override { return 0; }
+ virtual render_primitive_list *get_primitives() override;
+ virtual int draw(const int update) override { return 0; }
+ virtual void save() override { }
+ virtual void record() override { }
+ virtual void toggle_fsfx() override { }
+};
render_primitive_list *renderer_none::get_primitives()
{
- auto win = try_getwindow();
- if (win == nullptr)
+ osd_dim const dimensions = window().get_size();
+ if ((dimensions.width() <= 0) || (dimensions.height() <= 0))
return nullptr;
- RECT client;
- GetClientRect(std::static_pointer_cast<win_window_info>(win)->platform_window(), &client);
- if ((rect_width(&client) == 0) || (rect_height(&client) == 0))
- return nullptr;
- win->target()->set_bounds(rect_width(&client), rect_height(&client), win->pixel_aspect());
- return &win->target()->get_primitives();
+ window().target()->set_bounds(dimensions.width(), dimensions.height(), window().pixel_aspect());
+ return &window().target()->get_primitives();
}
+
+
+class video_none : public osd_module, public render_module
+{
+public:
+ video_none() : osd_module(OSD_RENDERER_PROVIDER, "none") { }
+
+ virtual int init(osd_interface &osd, osd_options const &options) override;
+ virtual void exit() override { }
+
+ virtual std::unique_ptr<osd_renderer> create(osd_window &window) override;
+
+protected:
+ virtual unsigned flags() const override { return 0; }
+};
+
+int video_none::init(osd_interface &osd, osd_options const &options)
+{
+ if (!emulator_info::standalone() && (options.seconds_to_run() == 0))
+ osd_printf_warning("Warning: -video none doesn't make much sense without -seconds_to_run\n");
+
+ return 0;
+}
+
+std::unique_ptr<osd_renderer> video_none::create(osd_window &window)
+{
+ return std::make_unique<renderer_none>(window);
+}
+
+} // anonymous namespace
+
+} // namespace osd
+
+
+MODULE_DEFINITION(RENDERER_NONE, osd::video_none)
diff --git a/src/osd/modules/render/drawnone.h b/src/osd/modules/render/drawnone.h
deleted file mode 100644
index c884f969204..00000000000
--- a/src/osd/modules/render/drawnone.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
-//============================================================
-//
-// drawnone.h - stub "nothing" drawer
-//
-//============================================================
-
-#ifndef __DRAWNONE__
-#define __DRAWNONE__
-
-#include "window.h"
-
-class renderer_none : public osd_renderer
-{
-public:
- renderer_none(std::shared_ptr<osd_window> window)
- : osd_renderer(window, FLAG_NONE) { }
-
- virtual ~renderer_none() { }
-
- static bool init(running_machine &machine) { return false; }
- static void exit() { }
-
- virtual int create() override { return 0; }
- virtual render_primitive_list *get_primitives() override;
- virtual int draw(const int update) override { return 0; }
- virtual void save() override { }
- virtual void record() override { }
- virtual void toggle_fsfx() override { }
-};
-
-#endif // __DRAWNONE__
diff --git a/src/osd/modules/render/drawogl.cpp b/src/osd/modules/render/drawogl.cpp
index 9e200f3817c..f9f76946bf4 100644
--- a/src/osd/modules/render/drawogl.cpp
+++ b/src/osd/modules/render/drawogl.cpp
@@ -12,37 +12,60 @@
//
//============================================================
-// standard C headers
-#include <cmath>
-#include <cstdio>
+#include "render_module.h"
+
+#include "modules/osdmodule.h"
+
+#if USE_OPENGL
-// MAME headers
+// will be picked up from specific OSD implementation
+#include "window.h"
+
+// OSD common headers
+#include "modules/lib/osdlib.h"
+#include "modules/lib/osdobj_common.h"
+#include "modules/opengl/gl_shader_mgr.h"
#include "osdcomm.h"
-#include "emu.h"
-#include "emuopts.h"
-#ifdef OSD_MAC
+// OSD headers
+#if defined(OSD_WINDOWS)
+typedef uint64_t HashT;
+#include "winglcontext.h"
+#elif defined(OSD_MAC)
#define GL_SILENCE_DEPRECATION (1)
+#include "osdmac.h"
+#else
+#include "osdsdl.h"
+#include "sdlglcontext.h"
#endif
+// emu
+#include "emucore.h"
+#include "emuopts.h"
+#include "render.h"
+
+
#if !defined(OSD_WINDOWS) && !defined(OSD_MAC)
+
// standard SDL headers
#define TOBEMIGRATED 1
#include <SDL2/SDL.h>
-#endif
-#include "modules/lib/osdlib.h"
-#include "modules/lib/osdobj_common.h"
+#endif // !defined(OSD_WINDOWS && !defined(OSD_MAC)
-// OpenGL headers
-#include "modules/opengl/osd_opengl.h"
-#include "modules/opengl/gl_shader_tool.h"
-#include "modules/opengl/gl_shader_mgr.h"
+// standard C headers
+#include <cmath>
+#include <cstdio>
+#include <memory>
+#include <utility>
+
#if defined(SDLMAME_MACOSX) || defined(OSD_MAC)
+
#include <cstring>
#include <cstdio>
+
#include <sys/types.h>
#include <sys/sysctl.h>
@@ -72,7 +95,13 @@ typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum m_target, GLuint r
typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum m_target, GLenum internalformat, GLsizei width, GLsizei height);
typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum m_target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers);
-#endif
+
+#endif // defined(SDLMAME_MACOSX) || defined(OSD_MAC)
+
+
+namespace osd {
+
+namespace {
// make sure the extensions compile OK everywhere
#ifndef GL_TEXTURE_STORAGE_HINT_APPLE
@@ -128,7 +157,283 @@ typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuin
#define GL_DEPTH_COMPONENT32 0x81A7
#endif
-#include "drawogl.h"
+
+//============================================================
+// Configuration
+//============================================================
+
+#define GLSL_SHADER_MAX 10
+
+struct ogl_video_config
+{
+ ogl_video_config() = default;
+
+ bool vbo = false;
+ bool pbo = false;
+ bool allowtexturerect = false; // allow GL_ARB_texture_rectangle, default: no
+ bool forcepow2texture = false; // force power of two textures, default: no
+ bool glsl = false;
+ int glsl_filter = 0; // glsl filtering, >0 disables filter
+ std::string glsl_shader_mamebm[GLSL_SHADER_MAX]; // custom glsl shader set, mame bitmap
+ int glsl_shader_mamebm_num = 0; // custom glsl shader set number, mame bitmap
+ std::string glsl_shader_scrn[GLSL_SHADER_MAX]; // custom glsl shader set, screen bitmap
+ int glsl_shader_scrn_num = 0; // custom glsl shader number, screen bitmap
+};
+
+
+//============================================================
+// Textures
+//============================================================
+
+/* ogl_texture_info holds information about a texture */
+class ogl_texture_info
+{
+public:
+ ogl_texture_info(
+#if defined(USE_DISPATCH_GL)
+ osd_gl_dispatch *gld
+#endif
+ )
+#if defined(USE_DISPATCH_GL)
+ : gl_dispatch(gld)
+#endif
+ {
+ for (int i=0; i<2; i++)
+ {
+ mpass_textureunit[i] = 0;
+ mpass_texture_mamebm[i] = 0;
+ mpass_fbo_mamebm[i] = 0;
+ mpass_texture_scrn[i] = 0;
+ mpass_fbo_scrn[i] = 0;
+ }
+ for (int i=0; i<8; i++)
+ texCoord[i] = 0.0f;
+ }
+
+#if defined(USE_DISPATCH_GL)
+ osd_gl_dispatch *const gl_dispatch; // name is magic, can't be changed
+#endif
+ HashT hash = 0; // hash value for the texture (must be >= pointer size)
+ uint32_t flags = 0; // rendering flags
+ render_texinfo texinfo; // copy of the texture info
+ int rawwidth = 0, rawheight = 0; // raw width/height of the texture
+ int rawwidth_create = 0; // raw width/height, pow2 compatible, if needed
+ int rawheight_create = 0; // (create and initial set the texture, not for copy!)
+ int type = 0; // what type of texture are we?
+ int format = 0; // texture format
+ int borderpix = 0; // do we have a 1 pixel border?
+ int xprescale = 0; // what is our X prescale factor?
+ int yprescale = 0; // what is our Y prescale factor?
+ int nocopy = 0; // must the texture date be copied?
+
+ uint32_t texture = 0; // OpenGL texture "name"/ID
+
+ GLenum texTarget = 0; // OpenGL texture target
+ int texpow2 = 0; // Is this texture pow2
+
+ uint32_t mpass_dest_idx = 0; // Multipass dest idx [0..1]
+ uint32_t mpass_textureunit[2]; // texture unit names for GLSL
+
+ uint32_t mpass_texture_mamebm[2]; // Multipass OpenGL texture "name"/ID for the shader
+ uint32_t mpass_fbo_mamebm[2]; // framebuffer object for this texture, multipass
+ uint32_t mpass_texture_scrn[2]; // Multipass OpenGL texture "name"/ID for the shader
+ uint32_t mpass_fbo_scrn[2]; // framebuffer object for this texture, multipass
+
+ uint32_t pbo = 0; // pixel buffer object for this texture (DYNAMIC only!)
+ uint32_t *data = nullptr; // pixels for the texture
+ bool data_own = false; // do we own / allocated it ?
+ GLfloat texCoord[8];
+ GLuint texCoordBufferName;
+
+};
+
+// renderer_ogl is the information about OpenGL for the current screen
+class renderer_ogl : public osd_renderer
+{
+public:
+ renderer_ogl(osd_window &window, ogl_video_config const &ogl_config)
+ : osd_renderer(window)
+ , m_ogl_config(ogl_config)
+ , m_blittimer(0)
+ , m_width(0)
+ , m_height(0)
+ , m_blit_dim(0, 0)
+ , m_initialized(0)
+ , m_last_blendmode(0)
+ , m_texture_max_width(0)
+ , m_texture_max_height(0)
+ , m_texpoweroftwo(0)
+ , m_usevbo(0)
+ , m_usepbo(0)
+ , m_usefbo(0)
+ , m_useglsl(0)
+ , m_glsl_program_num(0)
+ , m_glsl_program_mb2sc(0)
+ , m_usetexturerect(0)
+ , m_init_context(0)
+ , m_last_hofs(0.0f)
+ , m_last_vofs(0.0f)
+ , m_surf_w(0)
+ , m_surf_h(0)
+ {
+ for (int i=0; i < HASH_SIZE + OVERFLOW_SIZE; i++)
+ m_texhash[i] = nullptr;
+ for (int i=0; i < 2*GLSL_SHADER_MAX; i++)
+ m_glsl_program[i] = 0;
+ for (int i=0; i < 8; i++)
+ m_texVerticex[i] = 0.0f;
+ }
+ virtual ~renderer_ogl()
+ {
+ // free the memory in the window
+ destroy_all_textures();
+ }
+
+ virtual int create() override;
+ virtual int draw(const int update) override;
+
+#ifndef OSD_WINDOWS
+ virtual int xy_to_render_target(const int x, const int y, int *xt, int *yt) override;
+#endif
+ virtual render_primitive_list *get_primitives() override
+ {
+ osd_dim nd = window().get_size();
+ if (nd != m_blit_dim)
+ {
+ m_blit_dim = nd;
+ notify_changed();
+ }
+ if ((m_blit_dim.width() == 0) || (m_blit_dim.height() == 0))
+ return nullptr;
+ window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().pixel_aspect());
+ return &window().target()->get_primitives();
+ }
+
+#ifdef OSD_WINDOWS
+ virtual void save() override { }
+ virtual void record() override { }
+ virtual void toggle_fsfx() override { }
+#endif
+
+private:
+ static const uint32_t HASH_SIZE = ((1 << 18) + 1);
+ static const uint32_t OVERFLOW_SIZE = (1 << 12);
+
+ void destroy_all_textures();
+
+ void loadGLExtensions();
+ void loadgl_functions();
+ void initialize_gl();
+ void set_blendmode(int blendmode);
+ HashT texture_compute_hash(const render_texinfo *texture, uint32_t flags);
+ void texture_compute_type_subroutine(const render_texinfo *texsource, ogl_texture_info *texture, uint32_t flags);
+ void texture_compute_size_subroutine(ogl_texture_info *texture, uint32_t flags,
+ uint32_t width, uint32_t height,
+ int* p_width, int* p_height, int* p_width_create, int* p_height_create);
+ void texture_compute_size_type(const render_texinfo *texsource, ogl_texture_info *texture, uint32_t flags);
+ ogl_texture_info *texture_create(const render_texinfo *texsource, uint32_t flags);
+ int texture_shader_create(const render_texinfo *texsource, ogl_texture_info *texture, uint32_t flags);
+ ogl_texture_info *texture_find(const render_primitive *prim);
+ void texture_coord_update(ogl_texture_info *texture, const render_primitive *prim, int shaderIdx);
+ void texture_mpass_flip(ogl_texture_info *texture, int shaderIdx);
+ void texture_shader_update(ogl_texture_info *texture, render_container *container, int shaderIdx);
+ ogl_texture_info * texture_update(const render_primitive *prim, int shaderIdx);
+ void texture_disable(ogl_texture_info * texture);
+ void texture_all_disable();
+
+ int gl_checkFramebufferStatus() const;
+ int texture_fbo_create(uint32_t text_unit, uint32_t text_name, uint32_t fbo_name, int width, int height) const;
+ void texture_set_data(ogl_texture_info *texture, const render_texinfo *texsource, uint32_t flags) const;
+
+ int gl_check_error(bool log, const char *file, int line) const
+ {
+ GLenum const glerr = glGetError();
+ if (GL_NO_ERROR != glerr)
+ {
+ if (log)
+ osd_printf_warning("%s:%d: GL Error: %d 0x%X\n", file, line, int(glerr), unsigned(glerr));
+ }
+ return (GL_NO_ERROR != glerr) ? glerr : 0;
+ }
+
+#define GL_CHECK_ERROR_QUIET() gl_check_error(false, __FILE__, __LINE__)
+#define GL_CHECK_ERROR_NORMAL() gl_check_error(true, __FILE__, __LINE__)
+
+ ogl_video_config const &m_ogl_config;
+
+ int32_t m_blittimer;
+ int m_width;
+ int m_height;
+ osd_dim m_blit_dim;
+
+ std::unique_ptr<osd_gl_context> m_gl_context;
+ std::unique_ptr<glsl_shader_info> m_shader_tool;
+
+ int m_initialized; // is everything well initialized, i.e. all GL stuff etc.
+ // 3D info (GL mode only)
+ ogl_texture_info * m_texhash[HASH_SIZE + OVERFLOW_SIZE];
+ int m_last_blendmode; // previous blendmode
+ int32_t m_texture_max_width; // texture maximum width
+ int32_t m_texture_max_height; // texture maximum height
+ int m_texpoweroftwo; // must textures be power-of-2 sized?
+ int m_usevbo; // runtime check if VBO is available
+ int m_usepbo; // runtime check if PBO is available
+ int m_usefbo; // runtime check if FBO is available
+ int m_useglsl; // runtime check if GLSL is available
+
+ GLhandleARB m_glsl_program[2*GLSL_SHADER_MAX]; // GLSL programs, or 0
+ int m_glsl_program_num; // number of GLSL programs
+ int m_glsl_program_mb2sc; // GLSL program idx, which transforms
+ // the mame-bitmap. screen-bitmap (size/rotation/..)
+ // All progs <= glsl_program_mb2sc using the mame bitmap
+ // as input, otherwise the screen bitmap.
+ // All progs >= glsl_program_mb2sc using the screen bitmap
+ // as output, otherwise the mame bitmap.
+ int m_usetexturerect; // use ARB_texture_rectangle for non-power-of-2, general use
+
+ int m_init_context; // initialize context before next draw
+
+ float m_last_hofs;
+ float m_last_vofs;
+
+ // Static vars from draogl_window_dra
+ int32_t m_surf_w;
+ int32_t m_surf_h;
+ GLfloat m_texVerticex[8];
+
+#if defined(USE_DISPATCH_GL)
+ std::unique_ptr<osd_gl_dispatch> gl_dispatch; // name is magic, can't be changed
+#endif
+
+ // OGL 1.3
+#if defined(GL_ARB_multitexture) && !defined(OSD_MAC)
+ PFNGLACTIVETEXTUREARBPROC m_glActiveTexture = nullptr;
+#else
+ PFNGLACTIVETEXTUREPROC m_glActiveTexture = nullptr;
+#endif
+
+ // VBO
+ PFNGLGENBUFFERSPROC m_glGenBuffers = nullptr;
+ PFNGLDELETEBUFFERSPROC m_glDeleteBuffers = nullptr;
+ PFNGLBINDBUFFERPROC m_glBindBuffer = nullptr;
+ PFNGLBUFFERDATAPROC m_glBufferData = nullptr;
+ PFNGLBUFFERSUBDATAPROC m_glBufferSubData = nullptr;
+
+ // PBO
+ PFNGLMAPBUFFERPROC m_glMapBuffer = nullptr;
+ PFNGLUNMAPBUFFERPROC m_glUnmapBuffer = nullptr;
+
+ // FBO
+ PFNGLISFRAMEBUFFEREXTPROC m_glIsFramebuffer = nullptr;
+ PFNGLBINDFRAMEBUFFEREXTPROC m_glBindFramebuffer = nullptr;
+ PFNGLDELETEFRAMEBUFFERSEXTPROC m_glDeleteFramebuffers = nullptr;
+ PFNGLGENFRAMEBUFFERSEXTPROC m_glGenFramebuffers = nullptr;
+ PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC m_glCheckFramebufferStatus = nullptr;
+ PFNGLFRAMEBUFFERTEXTURE2DEXTPROC m_glFramebufferTexture2D = nullptr;
+
+ static bool s_shown_video_info;
+};
+
//============================================================
// DEBUGGING
@@ -241,103 +546,22 @@ void renderer_ogl::set_blendmode(int blendmode)
}
}
-//============================================================
-// STATIC VARIABLES
-//============================================================
-
-// OGL 1.3
-#if defined(GL_ARB_multitexture) && !defined(OSD_MAC)
-static PFNGLACTIVETEXTUREARBPROC pfn_glActiveTexture = nullptr;
-#else
-static PFNGLACTIVETEXTUREPROC pfn_glActiveTexture = nullptr;
-#endif
-
-// VBO
-static PFNGLGENBUFFERSPROC pfn_glGenBuffers = nullptr;
-static PFNGLDELETEBUFFERSPROC pfn_glDeleteBuffers = nullptr;
-static PFNGLBINDBUFFERPROC pfn_glBindBuffer = nullptr;
-static PFNGLBUFFERDATAPROC pfn_glBufferData = nullptr;
-static PFNGLBUFFERSUBDATAPROC pfn_glBufferSubData = nullptr;
-
-// PBO
-static PFNGLMAPBUFFERPROC pfn_glMapBuffer = nullptr;
-static PFNGLUNMAPBUFFERPROC pfn_glUnmapBuffer = nullptr;
-
-// FBO
-static PFNGLISFRAMEBUFFEREXTPROC pfn_glIsFramebuffer = nullptr;
-static PFNGLBINDFRAMEBUFFEREXTPROC pfn_glBindFramebuffer = nullptr;
-static PFNGLDELETEFRAMEBUFFERSEXTPROC pfn_glDeleteFramebuffers = nullptr;
-static PFNGLGENFRAMEBUFFERSEXTPROC pfn_glGenFramebuffers = nullptr;
-static PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC pfn_glCheckFramebufferStatus = nullptr;
-static PFNGLFRAMEBUFFERTEXTURE2DEXTPROC pfn_glFramebufferTexture2D = nullptr;
-
-static int glsl_shader_feature = GLSL_SHADER_FEAT_PLAIN;
-
-//============================================================
-// Textures
-//============================================================
-
-static void texture_set_data(ogl_texture_info *texture, const render_texinfo *texsource, uint32_t flags);
+static int glsl_shader_feature = glsl_shader_info::FEAT_PLAIN; // FIXME: why is this static?
//============================================================
// Static Variables
//============================================================
bool renderer_ogl::s_shown_video_info = false;
-bool renderer_ogl::s_dll_loaded = false;
-
-void renderer_ogl::init(running_machine &machine)
-{
- s_dll_loaded = false;
-
- load_gl_lib(machine);
-#if defined(OSD_WINDOWS)
- osd_printf_verbose("Using Windows OpenGL driver\n");
-#else
- osd_printf_verbose("Using SDL multi-window OpenGL driver (SDL 2.0+)\n");
-#endif
-}
-
-//============================================================
-// CONSTRUCTOR & DESTRUCTOR
-//============================================================
-
-renderer_ogl::~renderer_ogl()
-{
- // free the memory in the window
- destroy_all_textures();
-
- delete m_gl_context;
- m_gl_context = nullptr;
-}
-
-void renderer_ogl::exit()
-{
- for (int i = 0; i < video_config.glsl_shader_mamebm_num; i++)
- {
- if (nullptr != video_config.glsl_shader_mamebm[i])
- {
- free(video_config.glsl_shader_mamebm[i]);
- video_config.glsl_shader_mamebm[i] = nullptr;
- }
- }
- for (int i =0; i < video_config.glsl_shader_scrn_num; i++)
- {
- if (nullptr != video_config.glsl_shader_scrn[i])
- {
- free(video_config.glsl_shader_scrn[i]);
- video_config.glsl_shader_scrn[i] = nullptr;
- }
- }
-}
//============================================================
// Load the OGL function addresses
//============================================================
-static void loadgl_functions(osd_gl_context *context)
+void renderer_ogl::loadgl_functions()
{
-#ifdef USE_DISPATCH_GL
+#if defined(USE_DISPATCH_GL)
+ gl_dispatch = std::make_unique<osd_gl_dispatch>();
int err_count = 0;
@@ -345,11 +569,11 @@ static void loadgl_functions(osd_gl_context *context)
* while func will be expanded to disp_p->glBegin
*/
- #define OSD_GL(ret,func,params) \
- if (!( func = (ret (APIENTRY *)params) context->getProcAddress( #func ) )) \
- { err_count++; osd_printf_error("GL function %s not found!\n", #func ); }
+ #define OSD_GL(ret, func, params) \
+ if (!m_gl_context->get_proc_address(func, #func)) \
+ { err_count++; osd_printf_error("GL function %s not found!\n", #func); }
- #define OSD_GL_UNUSED(ret,func,params)
+ #define OSD_GL_UNUSED(ret, func, params)
#define GET_GLFUNC 1
#include "modules/opengl/osd_opengl.h"
@@ -361,45 +585,6 @@ static void loadgl_functions(osd_gl_context *context)
#endif
}
-//============================================================
-// Load GL library
-//============================================================
-
-#ifdef USE_DISPATCH_GL
-osd_gl_dispatch *gl_dispatch = nullptr;
-#endif
-
-void renderer_ogl::load_gl_lib(running_machine &machine)
-{
- if (!s_dll_loaded)
- {
-#ifndef OSD_WINDOWS
-#ifdef USE_DISPATCH_GL
- /*
- * directfb and and x11 use this env var
- * SDL_VIDEO_GL_DRIVER
- */
- const char *stemp;
-
- stemp = downcast<sdl_options &>(machine.options()).gl_lib();
- if (stemp != nullptr && strcmp(stemp, OSDOPTVAL_AUTO) == 0)
- stemp = nullptr;
-
- if (SDL_GL_LoadLibrary(stemp) != 0) // Load library (default for e==nullptr
- {
- fatalerror("Unable to load opengl library: %s\n", stemp ? stemp : "<default>");
- }
- osd_printf_verbose("Loaded opengl shared library: %s\n", stemp ? stemp : "<default>");
- /* FIXME: must be freed as well */
-#endif
-#endif
-#ifdef USE_DISPATCH_GL
- gl_dispatch = new osd_gl_dispatch;
-#endif
- s_dll_loaded = true;
- }
-}
-
void renderer_ogl::initialize_gl()
{
int has_and_allow_texturerect = 0;
@@ -425,7 +610,7 @@ void renderer_ogl::initialize_gl()
m_usefbo = 0;
m_useglsl = 0;
- if (video_config.allowtexturerect && (strstr(extstr, "GL_ARB_texture_rectangle") || strstr(extstr, "GL_EXT_texture_rectangle")))
+ if (m_ogl_config.allowtexturerect && (strstr(extstr, "GL_ARB_texture_rectangle") || strstr(extstr, "GL_EXT_texture_rectangle")))
{
has_and_allow_texturerect = 1;
if (!s_shown_video_info)
@@ -435,7 +620,7 @@ void renderer_ogl::initialize_gl()
}
// does this card support non-power-of-two sized textures? (they're faster, so use them if possible)
- if ( !video_config.forcepow2texture && strstr(extstr, "GL_ARB_texture_non_power_of_two"))
+ if ( !m_ogl_config.forcepow2texture && strstr(extstr, "GL_ARB_texture_non_power_of_two"))
{
if (!s_shown_video_info)
{
@@ -465,7 +650,7 @@ void renderer_ogl::initialize_gl()
if (strstr(extstr, "GL_ARB_vertex_buffer_object"))
{
- m_usevbo = video_config.vbo;
+ m_usevbo = m_ogl_config.vbo;
if (!s_shown_video_info)
{
if(m_usevbo)
@@ -479,7 +664,7 @@ void renderer_ogl::initialize_gl()
{
if( m_usevbo )
{
- m_usepbo = video_config.pbo;
+ m_usepbo = m_ogl_config.pbo;
if (!s_shown_video_info)
{
if(m_usepbo)
@@ -522,7 +707,7 @@ void renderer_ogl::initialize_gl()
strstr(extstr, "GL_ARB_fragment_shader")
)
{
- m_useglsl = video_config.glsl;
+ m_useglsl = m_ogl_config.glsl;
if (!s_shown_video_info)
{
if(m_useglsl)
@@ -562,24 +747,22 @@ void renderer_ogl::initialize_gl()
int renderer_ogl::create()
{
- auto win = assert_window();
-
// create renderer
#if defined(OSD_WINDOWS)
- m_gl_context = new win_gl_context(std::static_pointer_cast<win_window_info>(win)->platform_window());
+ m_gl_context.reset(new win_gl_context(dynamic_cast<win_window_info &>(window()).platform_window()));
#elif defined(OSD_MAC)
// TODO
-// m_gl_context = new mac_gl_context(std::static_pointer_cast<mac_window_info>(win)->platform_window());
+// m_gl_context.reset(new mac_gl_context(dynamic_cast<mac_window_info &>(window()).platform_window()));
#else
- m_gl_context = new sdl_gl_context(std::static_pointer_cast<sdl_window_info>(win)->platform_window());
+ m_gl_context.reset(new sdl_gl_context(dynamic_cast<sdl_window_info &>(window()).platform_window()));
#endif
- if (m_gl_context->LastErrorMsg() != nullptr)
+ if (!*m_gl_context)
{
- osd_printf_error("%s\n", m_gl_context->LastErrorMsg());
+ char const *const msg = m_gl_context->last_error_message();
+ osd_printf_error("Creating OpenGL context failed: %s\n", msg ? msg : "unknown error");
return 1;
}
- m_gl_context->SetSwapInterval(video_config.waitvsync ? 1 : 0);
-
+ m_gl_context->set_swap_interval(video_config.waitvsync ? 1 : 0);
m_blittimer = 0;
m_surf_w = 0;
@@ -595,10 +778,9 @@ int renderer_ogl::create()
/* load any GL function addresses
* this must be done here because we need a context
*/
- loadgl_functions(m_gl_context);
+ loadgl_functions();
initialize_gl();
-
m_init_context = 0;
osd_printf_verbose("Leave renderer_ogl::create\n");
@@ -628,27 +810,15 @@ int renderer_ogl::xy_to_render_target(int x, int y, int *xt, int *yt)
void renderer_ogl::destroy_all_textures()
{
- ogl_texture_info *texture = nullptr;
- bool lock=false;
- int i;
- if ( !m_initialized )
+ if (!m_initialized)
return;
- auto win = try_getwindow();
-
- // During destroy this can get called
- // and the window is no longer available
- if (win == nullptr)
- return;
+ m_gl_context->make_current();
- m_gl_context->MakeCurrent();
-
- if(win->m_primlist)
- {
- lock=true;
- win->m_primlist->acquire_lock();
- }
+ bool const lock = bool(window().m_primlist);
+ if (lock)
+ window().m_primlist->acquire_lock();
glFinish();
@@ -656,41 +826,39 @@ void renderer_ogl::destroy_all_textures()
glFinish();
glDisableClientState(GL_VERTEX_ARRAY);
- i=0;
- while (i<HASH_SIZE+OVERFLOW_SIZE)
+ for (int i = 0; i < (HASH_SIZE + OVERFLOW_SIZE); ++i)
{
- texture = m_texhash[i];
- m_texhash[i] = nullptr;
- if (texture != nullptr)
+ ogl_texture_info *const texture = std::exchange(m_texhash[i], nullptr);
+ if (texture)
{
- if(m_usevbo)
+ if (m_usevbo)
{
- pfn_glDeleteBuffers( 1, &(texture->texCoordBufferName) );
+ m_glDeleteBuffers( 1, &(texture->texCoordBufferName) );
texture->texCoordBufferName=0;
}
- if(m_usepbo && texture->pbo)
+ if (m_usepbo && texture->pbo)
{
- pfn_glDeleteBuffers( 1, (GLuint *)&(texture->pbo) );
+ m_glDeleteBuffers( 1, (GLuint *)&(texture->pbo) );
texture->pbo=0;
}
- if( m_glsl_program_num > 1 )
+ if (m_glsl_program_num > 1)
{
assert(m_usefbo);
- pfn_glDeleteFramebuffers(2, (GLuint *)&texture->mpass_fbo_mamebm[0]);
+ m_glDeleteFramebuffers(2, (GLuint *)&texture->mpass_fbo_mamebm[0]);
glDeleteTextures(2, (GLuint *)&texture->mpass_texture_mamebm[0]);
}
- if ( m_glsl_program_mb2sc < m_glsl_program_num - 1 )
+ if (m_glsl_program_mb2sc < m_glsl_program_num - 1)
{
assert(m_usefbo);
- pfn_glDeleteFramebuffers(2, (GLuint *)&texture->mpass_fbo_scrn[0]);
+ m_glDeleteFramebuffers(2, (GLuint *)&texture->mpass_fbo_scrn[0]);
glDeleteTextures(2, (GLuint *)&texture->mpass_texture_scrn[0]);
}
glDeleteTextures(1, (GLuint *)&texture->texture);
- if ( texture->data_own )
+ if (texture->data_own)
{
free(texture->data);
texture->data=nullptr;
@@ -698,18 +866,14 @@ void renderer_ogl::destroy_all_textures()
}
delete texture;
}
- i++;
- }
- if ( m_useglsl )
- {
- glsl_shader_free(m_glsl);
- m_glsl = nullptr;
}
+ m_shader_tool.reset();
+
m_initialized = 0;
if (lock)
- win->m_primlist->release_lock();
+ window().m_primlist->release_lock();
}
//============================================================
// loadGLExtensions
@@ -745,178 +909,138 @@ void renderer_ogl::loadGLExtensions()
// Get Pointers To The GL Functions
// VBO:
- if( m_usevbo )
+ if (m_usevbo)
{
- pfn_glGenBuffers = (PFNGLGENBUFFERSPROC) m_gl_context->getProcAddress("glGenBuffers");
- pfn_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) m_gl_context->getProcAddress("glDeleteBuffers");
- pfn_glBindBuffer = (PFNGLBINDBUFFERPROC) m_gl_context->getProcAddress("glBindBuffer");
- pfn_glBufferData = (PFNGLBUFFERDATAPROC) m_gl_context->getProcAddress("glBufferData");
- pfn_glBufferSubData = (PFNGLBUFFERSUBDATAPROC) m_gl_context->getProcAddress("glBufferSubData");
+ m_gl_context->get_proc_address(m_glGenBuffers, "glGenBuffers");
+ m_gl_context->get_proc_address(m_glDeleteBuffers, "glDeleteBuffers");
+ m_gl_context->get_proc_address(m_glBindBuffer, "glBindBuffer");
+ m_gl_context->get_proc_address(m_glBufferData, "glBufferData");
+ m_gl_context->get_proc_address(m_glBufferSubData, "glBufferSubData");
}
// PBO:
- if ( m_usepbo )
+ if (m_usepbo)
{
- pfn_glMapBuffer = (PFNGLMAPBUFFERPROC) m_gl_context->getProcAddress("glMapBuffer");
- pfn_glUnmapBuffer= (PFNGLUNMAPBUFFERPROC) m_gl_context->getProcAddress("glUnmapBuffer");
+ m_gl_context->get_proc_address(m_glMapBuffer, "glMapBuffer");
+ m_gl_context->get_proc_address(m_glUnmapBuffer, "glUnmapBuffer");
}
// FBO:
- if ( m_usefbo )
+ if (m_usefbo)
{
- pfn_glIsFramebuffer = (PFNGLISFRAMEBUFFEREXTPROC) m_gl_context->getProcAddress("glIsFramebufferEXT");
- pfn_glBindFramebuffer = (PFNGLBINDFRAMEBUFFEREXTPROC) m_gl_context->getProcAddress("glBindFramebufferEXT");
- pfn_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSEXTPROC) m_gl_context->getProcAddress("glDeleteFramebuffersEXT");
- pfn_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSEXTPROC) m_gl_context->getProcAddress("glGenFramebuffersEXT");
- pfn_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) m_gl_context->getProcAddress("glCheckFramebufferStatusEXT");
- pfn_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) m_gl_context->getProcAddress("glFramebufferTexture2DEXT");
+ m_gl_context->get_proc_address(m_glIsFramebuffer, "glIsFramebufferEXT");
+ m_gl_context->get_proc_address(m_glBindFramebuffer, "glBindFramebufferEXT");
+ m_gl_context->get_proc_address(m_glDeleteFramebuffers, "glDeleteFramebuffersEXT");
+ m_gl_context->get_proc_address(m_glGenFramebuffers, "glGenFramebuffersEXT");
+ m_gl_context->get_proc_address(m_glCheckFramebufferStatus, "glCheckFramebufferStatusEXT");
+ m_gl_context->get_proc_address(m_glFramebufferTexture2D, "glFramebufferTexture2DEXT");
}
- if ( m_usevbo &&
- ( !pfn_glGenBuffers || !pfn_glDeleteBuffers ||
- !pfn_glBindBuffer || !pfn_glBufferData || !pfn_glBufferSubData
- ) )
+ if (m_usevbo && (!m_glGenBuffers || !m_glDeleteBuffers || !m_glBindBuffer || !m_glBufferData || !m_glBufferSubData))
{
- m_usepbo=false;
+ m_usepbo = false;
if (_once)
{
- osd_printf_warning("OpenGL: VBO not supported, missing: ");
- if (!pfn_glGenBuffers)
- {
- osd_printf_warning("glGenBuffers, ");
- }
- if (!pfn_glDeleteBuffers)
- {
- osd_printf_warning("glDeleteBuffers");
- }
- if (!pfn_glBindBuffer)
- {
- osd_printf_warning("glBindBuffer, ");
- }
- if (!pfn_glBufferData)
- {
- osd_printf_warning("glBufferData, ");
- }
- if (!pfn_glBufferSubData)
- {
- osd_printf_warning("glBufferSubData, ");
- }
+ osd_printf_warning("OpenGL: VBO not supported, missing:");
+ if (!m_glGenBuffers)
+ osd_printf_warning(" glGenBuffers");
+ if (!m_glDeleteBuffers)
+ osd_printf_warning(" glDeleteBuffers");
+ if (!m_glBindBuffer)
+ osd_printf_warning(" glBindBuffer");
+ if (!m_glBufferData)
+ osd_printf_warning(" glBufferData");
+ if (!m_glBufferSubData)
+ osd_printf_warning(" glBufferSubData");
osd_printf_warning("\n");
}
- if ( m_usevbo )
+ if (m_usevbo)
{
if (_once)
- {
osd_printf_warning("OpenGL: PBO not supported, no VBO support.\n");
- }
- m_usepbo=false;
+ m_usepbo = false;
}
}
- if ( m_usepbo && ( !pfn_glMapBuffer || !pfn_glUnmapBuffer ) )
+ if (m_usepbo && (!m_glMapBuffer || !m_glUnmapBuffer))
{
- m_usepbo=false;
+ m_usepbo = false;
if (_once)
{
- osd_printf_warning("OpenGL: PBO not supported, missing: ");
- if (!pfn_glMapBuffer)
- {
- osd_printf_warning("glMapBuffer, ");
- }
- if (!pfn_glUnmapBuffer)
- {
- osd_printf_warning("glUnmapBuffer, ");
- }
+ osd_printf_warning("OpenGL: PBO not supported, missing:");
+ if (!m_glMapBuffer)
+ osd_printf_warning(" glMapBuffer");
+ if (!m_glUnmapBuffer)
+ osd_printf_warning(" glUnmapBuffer");
osd_printf_warning("\n");
}
}
if ( m_usefbo &&
- ( !pfn_glIsFramebuffer || !pfn_glBindFramebuffer || !pfn_glDeleteFramebuffers ||
- !pfn_glGenFramebuffers || !pfn_glCheckFramebufferStatus || !pfn_glFramebufferTexture2D
+ ( !m_glIsFramebuffer || !m_glBindFramebuffer || !m_glDeleteFramebuffers ||
+ !m_glGenFramebuffers || !m_glCheckFramebufferStatus || !m_glFramebufferTexture2D
))
{
- m_usefbo=false;
+ m_usefbo = false;
if (_once)
{
- osd_printf_warning("OpenGL: FBO not supported, missing: ");
- if (!pfn_glIsFramebuffer)
- {
- osd_printf_warning("pfn_glIsFramebuffer, ");
- }
- if (!pfn_glBindFramebuffer)
- {
- osd_printf_warning("pfn_glBindFramebuffer, ");
- }
- if (!pfn_glDeleteFramebuffers)
- {
- osd_printf_warning("pfn_glDeleteFramebuffers, ");
- }
- if (!pfn_glGenFramebuffers)
- {
- osd_printf_warning("pfn_glGenFramebuffers, ");
- }
- if (!pfn_glCheckFramebufferStatus)
- {
- osd_printf_warning("pfn_glCheckFramebufferStatus, ");
- }
- if (!pfn_glFramebufferTexture2D)
- {
- osd_printf_warning("pfn_glFramebufferTexture2D, ");
- }
+ osd_printf_warning("OpenGL: FBO not supported, missing:");
+ if (!m_glIsFramebuffer)
+ osd_printf_warning(" m_glIsFramebuffer");
+ if (!m_glBindFramebuffer)
+ osd_printf_warning(" m_glBindFramebuffer");
+ if (!m_glDeleteFramebuffers)
+ osd_printf_warning(" m_glDeleteFramebuffers");
+ if (!m_glGenFramebuffers)
+ osd_printf_warning(" m_glGenFramebuffers");
+ if (!m_glCheckFramebufferStatus)
+ osd_printf_warning(" m_glCheckFramebufferStatus");
+ if (!m_glFramebufferTexture2D)
+ osd_printf_warning(" m_glFramebufferTexture2D");
osd_printf_warning("\n");
}
}
if (_once)
{
- if ( m_usevbo )
- {
+ if (m_usevbo)
osd_printf_verbose("OpenGL: VBO supported\n");
- }
else
- {
osd_printf_warning("OpenGL: VBO not supported\n");
- }
- if ( m_usepbo )
- {
+ if (m_usepbo)
osd_printf_verbose("OpenGL: PBO supported\n");
- }
else
- {
osd_printf_warning("OpenGL: PBO not supported\n");
- }
- if ( m_usefbo )
- {
+ if (m_usefbo)
osd_printf_verbose("OpenGL: FBO supported\n");
- }
else
- {
osd_printf_warning("OpenGL: FBO not supported\n");
- }
}
- if ( m_useglsl )
+ if (m_useglsl)
{
#if defined(GL_ARB_multitexture) && !defined(OSD_MAC)
- pfn_glActiveTexture = (PFNGLACTIVETEXTUREARBPROC) m_gl_context->getProcAddress("glActiveTextureARB");
+ m_gl_context->get_proc_address(m_glActiveTexture, "glActiveTextureARB");
#else
- pfn_glActiveTexture = (PFNGLACTIVETEXTUREPROC) m_gl_context->getProcAddress("glActiveTexture");
+ m_gl_context->get_proc_address(m_glActiveTexture, "glActiveTexture");
#endif
- if (!pfn_glActiveTexture)
+ if (!m_glActiveTexture)
{
if (_once)
- {
osd_printf_warning("OpenGL: GLSL disabled, glActiveTexture(ARB) not supported\n");
- }
m_useglsl = 0;
}
}
- if ( m_useglsl )
+ if (m_useglsl)
{
- m_glsl = glsl_shader_init(m_gl_context);
- m_useglsl = (m_glsl != nullptr ? 1 : 0);
+ m_shader_tool = glsl_shader_info::init(
+ *m_gl_context
+#if defined(USE_DISPATCH_GL)
+ , gl_dispatch.get()
+#endif
+ );
+ m_useglsl = (m_shader_tool ? 1 : 0);
if ( ! m_useglsl )
{
@@ -927,9 +1051,9 @@ void renderer_ogl::loadGLExtensions()
}
}
- if ( m_useglsl )
+ if (m_useglsl)
{
- if (assert_window()->prescale() != 1 )
+ if (window().prescale() != 1 )
{
m_useglsl = 0;
if (_once)
@@ -939,15 +1063,14 @@ void renderer_ogl::loadGLExtensions()
}
}
- if ( m_useglsl )
+ if (m_useglsl)
{
- int i;
video_config.filter = false;
- glsl_shader_feature = GLSL_SHADER_FEAT_PLAIN;
+ glsl_shader_feature = glsl_shader_info::FEAT_PLAIN;
m_glsl_program_num = 0;
m_glsl_program_mb2sc = 0;
- for(i=0; i<video_config.glsl_shader_mamebm_num; i++)
+ for (int i=0; i<m_ogl_config.glsl_shader_mamebm_num; i++)
{
if ( !m_usefbo && m_glsl_program_num==1 )
{
@@ -958,60 +1081,65 @@ void renderer_ogl::loadGLExtensions()
break;
}
- if ( glsl_shader_add_mamebm(m_glsl, video_config.glsl_shader_mamebm[i], m_glsl_program_num) )
+ if ( m_shader_tool->add_mamebm(m_ogl_config.glsl_shader_mamebm[i].c_str(), m_glsl_program_num) )
{
osd_printf_error("OpenGL: GLSL loading mame bitmap shader %d failed (%s)\n",
- i, video_config.glsl_shader_mamebm[i]);
- } else {
- glsl_shader_feature = GLSL_SHADER_FEAT_CUSTOM;
+ i, m_ogl_config.glsl_shader_mamebm[i]);
+ }
+ else
+ {
+ glsl_shader_feature = glsl_shader_info::FEAT_CUSTOM;
if (_once)
{
osd_printf_verbose("OpenGL: GLSL using mame bitmap shader filter %d: '%s'\n",
- m_glsl_program_num, video_config.glsl_shader_mamebm[i]);
+ m_glsl_program_num, m_ogl_config.glsl_shader_mamebm[i]);
}
m_glsl_program_mb2sc = m_glsl_program_num; // the last mame_bitmap (mb) shader does it.
m_glsl_program_num++;
}
}
- if ( video_config.glsl_shader_scrn_num > 0 && m_glsl_program_num==0 )
+ if ( m_ogl_config.glsl_shader_scrn_num > 0 && m_glsl_program_num==0 )
{
osd_printf_verbose("OpenGL: GLSL cannot use screen bitmap shader without bitmap shader\n");
}
- for(i=0; m_usefbo && m_glsl_program_num>0 && i<video_config.glsl_shader_scrn_num; i++)
+ for(int i=0; m_usefbo && m_glsl_program_num>0 && i<m_ogl_config.glsl_shader_scrn_num; i++)
{
- if ( glsl_shader_add_scrn(m_glsl, video_config.glsl_shader_scrn[i],
- m_glsl_program_num-1-m_glsl_program_mb2sc) )
+ if ( m_shader_tool->add_scrn(m_ogl_config.glsl_shader_scrn[i].c_str(), m_glsl_program_num-1-m_glsl_program_mb2sc) )
{
osd_printf_error("OpenGL: GLSL loading screen bitmap shader %d failed (%s)\n",
- i, video_config.glsl_shader_scrn[i]);
- } else {
+ i, m_ogl_config.glsl_shader_scrn[i]);
+ }
+ else
+ {
if (_once)
{
osd_printf_verbose("OpenGL: GLSL using screen bitmap shader filter %d: '%s'\n",
- m_glsl_program_num, video_config.glsl_shader_scrn[i]);
+ m_glsl_program_num, m_ogl_config.glsl_shader_scrn[i]);
}
m_glsl_program_num++;
}
}
if ( 0==m_glsl_program_num &&
- 0 <= video_config.glsl_filter && video_config.glsl_filter < GLSL_SHADER_FEAT_INT_NUMBER )
+ 0 <= m_ogl_config.glsl_filter && m_ogl_config.glsl_filter < glsl_shader_info::FEAT_INT_NUMBER )
{
m_glsl_program_mb2sc = m_glsl_program_num; // the last mame_bitmap (mb) shader does it.
m_glsl_program_num++;
- glsl_shader_feature = video_config.glsl_filter;
+ glsl_shader_feature = m_ogl_config.glsl_filter;
if (_once)
{
osd_printf_verbose("OpenGL: GLSL using shader filter '%s', idx: %d, num %d (vid filter: %d)\n",
- glsl_shader_get_filter_name_mamebm(glsl_shader_feature),
+ m_shader_tool->get_filter_name_mamebm(glsl_shader_feature),
glsl_shader_feature, m_glsl_program_num, video_config.filter);
}
}
- } else {
+ }
+ else
+ {
if (_once)
{
osd_printf_verbose("OpenGL: using vid filter: %d\n", video_config.filter);
@@ -1031,16 +1159,7 @@ int renderer_ogl::draw(const int update)
float vofs, hofs;
int pendingPrimitive=GL_NO_PRIMITIVE, curPrimitive=GL_NO_PRIMITIVE;
-#ifdef TOBEMIGRATED
- if (video_config.novideo)
- {
- return 0;
- }
-#endif
-
- auto win = assert_window();
-
- osd_dim wdim = win->get_size();
+ osd_dim wdim = window().get_size();
if (has_flags(FI_CHANGED) || (wdim.width() != m_width) || (wdim.height() != m_height))
{
@@ -1052,7 +1171,7 @@ int renderer_ogl::draw(const int update)
clear_flags(FI_CHANGED);
}
- m_gl_context->MakeCurrent();
+ m_gl_context->make_current();
if (m_init_context)
{
@@ -1192,16 +1311,15 @@ int renderer_ogl::draw(const int update)
hofs = (cw - m_blit_dim.width()) / 2.0f;
}
}
-#else
#endif
m_last_hofs = hofs;
m_last_vofs = vofs;
- win->m_primlist->acquire_lock();
+ window().m_primlist->acquire_lock();
// now draw
- for (render_primitive &prim : *win->m_primlist)
+ for (render_primitive &prim : *window().m_primlist)
{
int i;
@@ -1236,7 +1354,10 @@ int renderer_ogl::draw(const int update)
if(pendingPrimitive!=curPrimitive)
{
- glLineWidth(prim.width);
+ if (curPrimitive==GL_POINTS)
+ glPointSize(prim.width);
+ else
+ glLineWidth(prim.width);
glBegin(curPrimitive);
pendingPrimitive=curPrimitive;
}
@@ -1407,10 +1528,10 @@ int renderer_ogl::draw(const int update)
pendingPrimitive=GL_NO_PRIMITIVE;
}
- win->m_primlist->release_lock();
+ window().m_primlist->release_lock();
m_init_context = 0;
- m_gl_context->SwapBuffer();
+ m_gl_context->swap_buffer();
return 0;
}
@@ -1543,9 +1664,8 @@ void renderer_ogl::texture_compute_size_subroutine(ogl_texture_info *texture, ui
while (texture->yprescale > 1 && height_create * texture->yprescale > m_texture_max_height)
texture->yprescale--;
- auto win = assert_window();
- if (PRIMFLAG_GET_SCREENTEX(flags) && (texture->xprescale != win->prescale() || texture->yprescale != win->prescale()))
- osd_printf_warning("SDL: adjusting prescale from %dx%d to %dx%d\n", win->prescale(), win->prescale(), texture->xprescale, texture->yprescale);
+ if (PRIMFLAG_GET_SCREENTEX(flags) && (texture->xprescale != window().prescale() || texture->yprescale != window().prescale()))
+ osd_printf_warning("SDL: adjusting prescale from %dx%d to %dx%d\n", window().prescale(), window().prescale(), texture->xprescale, texture->yprescale);
width *= texture->xprescale;
height *= texture->yprescale;
@@ -1640,10 +1760,9 @@ void renderer_ogl::texture_compute_size_type(const render_texinfo *texsource, og
// texture_create
//============================================================
-static int gl_checkFramebufferStatus()
+int renderer_ogl::gl_checkFramebufferStatus() const
{
- GLenum status;
- status=(GLenum)pfn_glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
+ GLenum const status = (GLenum)m_glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
switch(status) {
case GL_FRAMEBUFFER_COMPLETE_EXT:
return 0;
@@ -1683,14 +1802,14 @@ static int gl_checkFramebufferStatus()
return -1;
}
-static int texture_fbo_create(uint32_t text_unit, uint32_t text_name, uint32_t fbo_name, int width, int height)
+int renderer_ogl::texture_fbo_create(uint32_t text_unit, uint32_t text_name, uint32_t fbo_name, int width, int height) const
{
- pfn_glActiveTexture(text_unit);
- pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo_name);
+ m_glActiveTexture(text_unit);
+ m_glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo_name);
glBindTexture(GL_TEXTURE_2D, text_name);
{
GLint _width, _height;
- if ( gl_texture_check_size(GL_TEXTURE_2D, 0, GL_RGBA8, width, height,
+ if ( m_shader_tool->texture_check_size(GL_TEXTURE_2D, 0, GL_RGBA8, width, height,
0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, &_width, &_height, 1) )
{
osd_printf_error("cannot create fbo texture, req: %dx%d, avail: %dx%d - bail out\n",
@@ -1708,7 +1827,7 @@ static int texture_fbo_create(uint32_t text_unit, uint32_t text_name, uint32_t f
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- pfn_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+ m_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, text_name, 0);
if ( gl_checkFramebufferStatus() )
@@ -1745,51 +1864,49 @@ int renderer_ogl::texture_shader_create(const render_texinfo *texsource, ogl_tex
for(i=0; i<m_glsl_program_num; i++)
{
if ( i<=m_glsl_program_mb2sc )
- {
- m_glsl_program[i] = glsl_shader_get_program_mamebm(glsl_shader_feature, i);
- } else {
- m_glsl_program[i] = glsl_shader_get_program_scrn(i-1-m_glsl_program_mb2sc);
- }
- pfn_glUseProgramObjectARB(m_glsl_program[i]);
+ m_glsl_program[i] = m_shader_tool->get_program_mamebm(glsl_shader_feature, i);
+ else
+ m_glsl_program[i] = m_shader_tool->get_program_scrn(i-1-m_glsl_program_mb2sc);
+ m_shader_tool->pfn_glUseProgramObjectARB(m_glsl_program[i]);
if ( i<=m_glsl_program_mb2sc )
{
// GL_TEXTURE0 GLSL Uniforms
- uniform_location = pfn_glGetUniformLocationARB(m_glsl_program[i], "color_texture");
- pfn_glUniform1iARB(uniform_location, 0);
+ uniform_location = m_shader_tool->pfn_glGetUniformLocationARB(m_glsl_program[i], "color_texture");
+ m_shader_tool->pfn_glUniform1iARB(uniform_location, 0);
GL_CHECK_ERROR_NORMAL();
}
{
GLfloat color_texture_sz[2] = { (GLfloat)texture->rawwidth, (GLfloat)texture->rawheight };
- uniform_location = pfn_glGetUniformLocationARB(m_glsl_program[i], "color_texture_sz");
- pfn_glUniform2fvARB(uniform_location, 1, &(color_texture_sz[0]));
+ uniform_location = m_shader_tool->pfn_glGetUniformLocationARB(m_glsl_program[i], "color_texture_sz");
+ m_shader_tool->pfn_glUniform2fvARB(uniform_location, 1, &(color_texture_sz[0]));
GL_CHECK_ERROR_NORMAL();
}
GLfloat color_texture_pow2_sz[2] = { (GLfloat)texture->rawwidth_create, (GLfloat)texture->rawheight_create };
- uniform_location = pfn_glGetUniformLocationARB(m_glsl_program[i], "color_texture_pow2_sz");
- pfn_glUniform2fvARB(uniform_location, 1, &(color_texture_pow2_sz[0]));
+ uniform_location = m_shader_tool->pfn_glGetUniformLocationARB(m_glsl_program[i], "color_texture_pow2_sz");
+ m_shader_tool->pfn_glUniform2fvARB(uniform_location, 1, &(color_texture_pow2_sz[0]));
GL_CHECK_ERROR_NORMAL();
GLfloat screen_texture_sz[2] = { (GLfloat) m_blit_dim.width(), (GLfloat) m_blit_dim.height() };
- uniform_location = pfn_glGetUniformLocationARB(m_glsl_program[i], "screen_texture_sz");
- pfn_glUniform2fvARB(uniform_location, 1, &(screen_texture_sz[0]));
+ uniform_location = m_shader_tool->pfn_glGetUniformLocationARB(m_glsl_program[i], "screen_texture_sz");
+ m_shader_tool->pfn_glUniform2fvARB(uniform_location, 1, &(screen_texture_sz[0]));
GL_CHECK_ERROR_NORMAL();
GLfloat screen_texture_pow2_sz[2] = { (GLfloat)surf_w_pow2, (GLfloat)surf_h_pow2 };
- uniform_location = pfn_glGetUniformLocationARB(m_glsl_program[i], "screen_texture_pow2_sz");
- pfn_glUniform2fvARB(uniform_location, 1, &(screen_texture_pow2_sz[0]));
+ uniform_location = m_shader_tool->pfn_glGetUniformLocationARB(m_glsl_program[i], "screen_texture_pow2_sz");
+ m_shader_tool->pfn_glUniform2fvARB(uniform_location, 1, &(screen_texture_pow2_sz[0]));
GL_CHECK_ERROR_NORMAL();
}
- pfn_glUseProgramObjectARB(m_glsl_program[0]); // start with 1st shader
+ m_shader_tool->pfn_glUseProgramObjectARB(m_glsl_program[0]); // start with 1st shader
if( m_glsl_program_num > 1 )
{
// multipass mode
// GL_TEXTURE2/GL_TEXTURE3
- pfn_glGenFramebuffers(2, (GLuint *)&texture->mpass_fbo_mamebm[0]);
+ m_glGenFramebuffers(2, (GLuint *)&texture->mpass_fbo_mamebm[0]);
glGenTextures(2, (GLuint *)&texture->mpass_texture_mamebm[0]);
for (i=0; i<2; i++)
@@ -1803,7 +1920,7 @@ int renderer_ogl::texture_shader_create(const render_texinfo *texsource, ogl_tex
}
}
- pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+ m_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
osd_printf_verbose("GL texture: mpass mame-bmp 2x %dx%d (pow2 %dx%d)\n",
texture->rawwidth, texture->rawheight, texture->rawwidth_create, texture->rawheight_create);
@@ -1813,7 +1930,7 @@ int renderer_ogl::texture_shader_create(const render_texinfo *texsource, ogl_tex
{
// multipass mode
// GL_TEXTURE2/GL_TEXTURE3
- pfn_glGenFramebuffers(2, (GLuint *)&texture->mpass_fbo_scrn[0]);
+ m_glGenFramebuffers(2, (GLuint *)&texture->mpass_fbo_scrn[0]);
glGenTextures(2, (GLuint *)&texture->mpass_texture_scrn[0]);
for (i=0; i<2; i++)
@@ -1834,14 +1951,14 @@ int renderer_ogl::texture_shader_create(const render_texinfo *texsource, ogl_tex
// GL_TEXTURE0
// get a name for this texture
glGenTextures(1, (GLuint *)&texture->texture);
- pfn_glActiveTexture(GL_TEXTURE0);
+ m_glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture->texture);
glPixelStorei(GL_UNPACK_ROW_LENGTH, texture->rawwidth_create);
uint32_t * dummy = nullptr;
GLint _width, _height;
- if ( gl_texture_check_size(GL_TEXTURE_2D, 0, GL_RGBA8,
+ if ( m_shader_tool->texture_check_size(GL_TEXTURE_2D, 0, GL_RGBA8,
texture->rawwidth_create, texture->rawheight_create,
0,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
@@ -1863,7 +1980,7 @@ int renderer_ogl::texture_shader_create(const render_texinfo *texsource, ogl_tex
if ((PRIMFLAG_GET_SCREENTEX(flags)) && video_config.filter)
{
- assert( glsl_shader_feature == GLSL_SHADER_FEAT_PLAIN );
+ assert( glsl_shader_feature == glsl_shader_info::FEAT_PLAIN );
// screen textures get the user's choice of filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -1898,7 +2015,11 @@ ogl_texture_info *renderer_ogl::texture_create(const render_texinfo *texsource,
ogl_texture_info *texture;
// allocate a new texture
- texture = new ogl_texture_info;
+ texture = new ogl_texture_info(
+#if defined(USE_DISPATCH_GL)
+ gl_dispatch.get()
+#endif
+ );
// fill in the core data
texture->hash = texture_compute_hash(texsource, flags);
@@ -1907,9 +2028,8 @@ ogl_texture_info *renderer_ogl::texture_create(const render_texinfo *texsource,
texture->texinfo.seqid = -1; // force set data
if (PRIMFLAG_GET_SCREENTEX(flags))
{
- auto win = assert_window();
- texture->xprescale = win->prescale();
- texture->yprescale = win->prescale();
+ texture->xprescale = window().prescale();
+ texture->yprescale = window().prescale();
}
else
{
@@ -1963,7 +2083,7 @@ ogl_texture_info *renderer_ogl::texture_create(const render_texinfo *texsource,
if ( texture->type != TEXTURE_TYPE_SHADER && m_useglsl)
{
- pfn_glUseProgramObjectARB(0); // back to fixed function pipeline
+ m_shader_tool->pfn_glUseProgramObjectARB(0); // back to fixed function pipeline
}
if ( texture->type==TEXTURE_TYPE_SHADER )
@@ -2028,12 +2148,12 @@ ogl_texture_info *renderer_ogl::texture_create(const render_texinfo *texsource,
assert(m_usepbo);
// create the PBO
- pfn_glGenBuffers(1, (GLuint *)&texture->pbo);
+ m_glGenBuffers(1, (GLuint *)&texture->pbo);
- pfn_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, texture->pbo);
+ m_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, texture->pbo);
// set up the PBO dimension, ..
- pfn_glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB,
+ m_glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB,
texture->rawwidth * texture->rawheight * sizeof(uint32_t),
nullptr, GL_STREAM_DRAW);
}
@@ -2063,10 +2183,10 @@ ogl_texture_info *renderer_ogl::texture_create(const render_texinfo *texsource,
if (m_usevbo)
{
// Generate And Bind The Texture Coordinate Buffer
- pfn_glGenBuffers( 1, &(texture->texCoordBufferName) );
- pfn_glBindBuffer( GL_ARRAY_BUFFER_ARB, texture->texCoordBufferName );
+ m_glGenBuffers( 1, &(texture->texCoordBufferName) );
+ m_glBindBuffer( GL_ARRAY_BUFFER_ARB, texture->texCoordBufferName );
// Load The Data
- pfn_glBufferData( GL_ARRAY_BUFFER_ARB, 4*2*sizeof(GLfloat), texture->texCoord, GL_STREAM_DRAW );
+ m_glBufferData( GL_ARRAY_BUFFER_ARB, 4*2*sizeof(GLfloat), texture->texCoord, GL_STREAM_DRAW );
glTexCoordPointer( 2, GL_FLOAT, 0, (char *) nullptr ); // we are using ARB VBO buffers
}
else
@@ -2327,14 +2447,14 @@ static inline void copyline_yuy16_to_argb(uint32_t *dst, const uint16_t *src, in
// texture_set_data
//============================================================
-static void texture_set_data(ogl_texture_info *texture, const render_texinfo *texsource, uint32_t flags)
+void renderer_ogl::texture_set_data(ogl_texture_info *texture, const render_texinfo *texsource, uint32_t flags) const
{
if ( texture->type == TEXTURE_TYPE_DYNAMIC )
{
assert(texture->pbo);
assert(!texture->nocopy);
- texture->data = (uint32_t *) pfn_glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY);
+ texture->data = (uint32_t *) m_glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY);
}
// note that nocopy and borderpix are mutually exclusive, IOW
@@ -2401,7 +2521,7 @@ static void texture_set_data(ogl_texture_info *texture, const render_texinfo *te
if ( texture->type == TEXTURE_TYPE_SHADER )
{
- pfn_glActiveTexture(GL_TEXTURE0);
+ m_glActiveTexture(GL_TEXTURE0);
glBindTexture(texture->texTarget, texture->texture);
if (texture->nocopy)
@@ -2420,7 +2540,7 @@ static void texture_set_data(ogl_texture_info *texture, const render_texinfo *te
glPixelStorei(GL_UNPACK_ROW_LENGTH, texture->rawwidth);
// unmap the buffer from the CPU space so it can DMA
- pfn_glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB);
+ m_glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB);
// kick off the DMA
glTexSubImage2D(texture->texTarget, 0, 0, 0, texture->rawwidth, texture->rawheight,
@@ -2570,12 +2690,12 @@ void renderer_ogl::texture_mpass_flip(ogl_texture_info *texture, int shaderIdx)
if ( shaderIdx>0 )
{
int uniform_location;
- uniform_location = pfn_glGetUniformLocationARB(m_glsl_program[shaderIdx], "mpass_texture");
- pfn_glUniform1iARB(uniform_location, texture->mpass_textureunit[mpass_src_idx]-GL_TEXTURE0);
+ uniform_location = m_shader_tool->pfn_glGetUniformLocationARB(m_glsl_program[shaderIdx], "mpass_texture");
+ m_shader_tool->pfn_glUniform1iARB(uniform_location, texture->mpass_textureunit[mpass_src_idx]-GL_TEXTURE0);
GL_CHECK_ERROR_NORMAL();
}
- pfn_glActiveTexture(texture->mpass_textureunit[mpass_src_idx]);
+ m_glActiveTexture(texture->mpass_textureunit[mpass_src_idx]);
if ( shaderIdx<=m_glsl_program_mb2sc )
{
glBindTexture(texture->texTarget, texture->mpass_texture_mamebm[mpass_src_idx]);
@@ -2584,22 +2704,22 @@ void renderer_ogl::texture_mpass_flip(ogl_texture_info *texture, int shaderIdx)
{
glBindTexture(texture->texTarget, texture->mpass_texture_scrn[mpass_src_idx]);
}
- pfn_glActiveTexture(texture->mpass_textureunit[texture->mpass_dest_idx]);
+ m_glActiveTexture(texture->mpass_textureunit[texture->mpass_dest_idx]);
glBindTexture(texture->texTarget, 0);
- pfn_glActiveTexture(texture->mpass_textureunit[texture->mpass_dest_idx]);
+ m_glActiveTexture(texture->mpass_textureunit[texture->mpass_dest_idx]);
if ( shaderIdx<m_glsl_program_num-1 )
{
if ( shaderIdx>=m_glsl_program_mb2sc )
{
glBindTexture(texture->texTarget, texture->mpass_texture_scrn[texture->mpass_dest_idx]);
- pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, texture->mpass_fbo_scrn[texture->mpass_dest_idx]);
+ m_glBindFramebuffer(GL_FRAMEBUFFER_EXT, texture->mpass_fbo_scrn[texture->mpass_dest_idx]);
}
else
{
glBindTexture(texture->texTarget, texture->mpass_texture_mamebm[texture->mpass_dest_idx]);
- pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, texture->mpass_fbo_mamebm[texture->mpass_dest_idx]);
+ m_glBindFramebuffer(GL_FRAMEBUFFER_EXT, texture->mpass_fbo_mamebm[texture->mpass_dest_idx]);
}
if ( shaderIdx==0 )
@@ -2620,7 +2740,7 @@ void renderer_ogl::texture_mpass_flip(ogl_texture_info *texture, int shaderIdx)
else
{
glBindTexture(texture->texTarget, 0);
- pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+ m_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
if ( m_glsl_program_mb2sc == m_glsl_program_num-1 )
{
@@ -2628,7 +2748,7 @@ void renderer_ogl::texture_mpass_flip(ogl_texture_info *texture, int shaderIdx)
GL_CHECK_ERROR_NORMAL();
}
- pfn_glActiveTexture(GL_TEXTURE0);
+ m_glActiveTexture(GL_TEXTURE0);
glBindTexture(texture->texTarget, 0);
}
}
@@ -2649,8 +2769,8 @@ void renderer_ogl::texture_shader_update(ogl_texture_info *texture, render_conta
vid_attributes[1] = settings.m_contrast;
vid_attributes[2] = settings.m_brightness;
vid_attributes[3] = 0.0f;
- uniform_location = pfn_glGetUniformLocationARB(m_glsl_program[shaderIdx], "vid_attributes");
- pfn_glUniform4fvARB(uniform_location, 1, &(vid_attributes[shaderIdx]));
+ uniform_location = m_shader_tool->pfn_glGetUniformLocationARB(m_glsl_program[shaderIdx], "vid_attributes");
+ m_shader_tool->pfn_glUniform4fvARB(uniform_location, 1, &(vid_attributes[shaderIdx]));
if ( GL_CHECK_ERROR_QUIET() ) {
osd_printf_verbose("GLSL: could not set 'vid_attributes' for shader prog idx %d\n", shaderIdx);
}
@@ -2671,12 +2791,12 @@ ogl_texture_info * renderer_ogl::texture_update(const render_primitive *prim, in
{
if ( texture->type == TEXTURE_TYPE_SHADER )
{
- pfn_glUseProgramObjectARB(m_glsl_program[shaderIdx]); // back to our shader
+ m_shader_tool->pfn_glUseProgramObjectARB(m_glsl_program[shaderIdx]); // back to our shader
}
else if ( texture->type == TEXTURE_TYPE_DYNAMIC )
{
assert ( m_usepbo ) ;
- pfn_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, texture->pbo);
+ m_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, texture->pbo);
glEnable(texture->texTarget);
}
else
@@ -2716,9 +2836,9 @@ ogl_texture_info * renderer_ogl::texture_update(const render_primitive *prim, in
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
if(m_usevbo)
{
- pfn_glBindBuffer( GL_ARRAY_BUFFER_ARB, texture->texCoordBufferName );
+ m_glBindBuffer( GL_ARRAY_BUFFER_ARB, texture->texCoordBufferName );
// Load The Data
- pfn_glBufferSubData( GL_ARRAY_BUFFER_ARB, 0, 4*2*sizeof(GLfloat), texture->texCoord );
+ m_glBufferSubData( GL_ARRAY_BUFFER_ARB, 0, 4*2*sizeof(GLfloat), texture->texCoord );
glTexCoordPointer( 2, GL_FLOAT, 0, (char *) nullptr ); // we are using ARB VBO buffers
}
else
@@ -2735,34 +2855,41 @@ void renderer_ogl::texture_disable(ogl_texture_info * texture)
if ( texture->type == TEXTURE_TYPE_SHADER )
{
assert ( m_useglsl );
- pfn_glUseProgramObjectARB(0); // back to fixed function pipeline
- } else if ( texture->type == TEXTURE_TYPE_DYNAMIC )
+ m_shader_tool->pfn_glUseProgramObjectARB(0); // back to fixed function pipeline
+ }
+ else if ( texture->type == TEXTURE_TYPE_DYNAMIC )
{
- pfn_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+ m_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, 0);
glDisable(texture->texTarget);
- } else {
+ }
+ else
+ {
glDisable(texture->texTarget);
}
}
void renderer_ogl::texture_all_disable()
{
- if ( m_useglsl )
+ if (m_useglsl)
{
- pfn_glUseProgramObjectARB(0); // back to fixed function pipeline
+ m_shader_tool->pfn_glUseProgramObjectARB(0); // back to fixed function pipeline
- pfn_glActiveTexture(GL_TEXTURE3);
+ m_glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, 0);
- if ( m_usefbo ) pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
- pfn_glActiveTexture(GL_TEXTURE2);
+ if (m_usefbo)
+ m_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+ m_glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, 0);
- if ( m_usefbo ) pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
- pfn_glActiveTexture(GL_TEXTURE1);
+ if (m_usefbo)
+ m_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+ m_glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 0);
- if ( m_usefbo ) pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
- pfn_glActiveTexture(GL_TEXTURE0);
+ if (m_usefbo)
+ m_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+ m_glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 0);
- if ( m_usefbo ) pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+ if (m_usefbo)
+ m_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
}
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
@@ -2775,10 +2902,140 @@ void renderer_ogl::texture_all_disable()
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
if(m_usevbo)
{
- pfn_glBindBuffer( GL_ARRAY_BUFFER_ARB, 0); // unbind ..
+ m_glBindBuffer( GL_ARRAY_BUFFER_ARB, 0); // unbind ..
}
if ( m_usepbo )
{
- pfn_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+ m_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+ }
+}
+
+
+class video_opengl : public osd_module, public render_module
+{
+public:
+ video_opengl()
+ : osd_module(OSD_RENDERER_PROVIDER, "opengl")
+#if defined(USE_DISPATCH_GL)
+ , m_dll_loaded(false)
+#endif
+ {
+ }
+ ~video_opengl() { exit(); }
+
+ virtual int init(osd_interface &osd, osd_options const &options) override;
+ virtual void exit() override;
+
+ virtual std::unique_ptr<osd_renderer> create(osd_window &window) override;
+
+protected:
+ virtual unsigned flags() const override { return FLAG_INTERACTIVE | FLAG_SDL_NEEDS_OPENGL; }
+
+private:
+ ogl_video_config m_ogl_config;
+#if defined(USE_DISPATCH_GL)
+ bool m_dll_loaded;
+#endif
+};
+
+int video_opengl::init(osd_interface &osd, osd_options const &options)
+{
+ m_ogl_config.vbo = options.gl_vbo();
+ m_ogl_config.pbo = options.gl_pbo();
+ m_ogl_config.allowtexturerect = !options.gl_no_texture_rect();
+ m_ogl_config.forcepow2texture = options.gl_force_pow2_texture();
+ m_ogl_config.glsl = options.gl_glsl();
+ if (m_ogl_config.glsl)
+ {
+ m_ogl_config.glsl_filter = options.glsl_filter();
+
+ m_ogl_config.glsl_shader_mamebm_num = 0;
+ for (int i = 0; i < GLSL_SHADER_MAX; i++)
+ {
+ char const *const stemp = options.shader_mame(i);
+ if (stemp && *stemp && strcmp(stemp, OSDOPTVAL_NONE))
+ m_ogl_config.glsl_shader_mamebm[m_ogl_config.glsl_shader_mamebm_num++] = stemp;
+ }
+
+ m_ogl_config.glsl_shader_scrn_num = 0;
+ for (int i = 0; i < GLSL_SHADER_MAX; i++)
+ {
+ char const *const stemp = options.shader_screen(i);
+ if (stemp && *stemp && strcmp(stemp, OSDOPTVAL_NONE))
+ m_ogl_config.glsl_shader_scrn[m_ogl_config.glsl_shader_scrn_num++] = stemp;
+ }
+ }
+ else
+ {
+ m_ogl_config.glsl_filter = 0;
+
+ m_ogl_config.glsl_shader_mamebm_num = 0;
+ for (std::string &s : m_ogl_config.glsl_shader_mamebm)
+ s.clear();
+
+ m_ogl_config.glsl_shader_scrn_num = 0;
+ for (std::string &s : m_ogl_config.glsl_shader_scrn)
+ s.clear();
+ }
+
+#if defined(USE_DISPATCH_GL)
+#if defined(OSD_SDL)
+ if (!m_dll_loaded)
+ {
+ // directfb and and x11 use this env var: SDL_VIDEO_GL_DRIVER
+ char const *libname = dynamic_cast<sdl_options const &>(options).gl_lib();
+ if (libname && (!*libname || !std::strcmp(libname, OSDOPTVAL_AUTO)))
+ libname = nullptr;
+
+ if (SDL_GL_LoadLibrary(libname) != 0)
+ {
+ osd_printf_error("Unable to load OpenGL shared library: %s\n", libname ? libname : "<default>");
+ return -1;
+ }
+
+ osd_printf_verbose("Loaded OpenGL shared library: %s\n", libname ? libname : "<default>");
}
+#endif // defined(OSD_SDL)
+ m_dll_loaded = true;
+#endif // defined(USE_DISPATCH_GL)
+
+#if defined(OSD_WINDOWS)
+ osd_printf_verbose("Using Windows OpenGL driver\n");
+#else // defined(OSD_WINDOWS)
+ osd_printf_verbose("Using SDL multi-window OpenGL driver (SDL 2.0+)\n");
+#endif // defined(OSD_WINDOWS)
+
+ return 0;
+}
+
+void video_opengl::exit()
+{
+#if defined(USE_DISPATCH_GL)
+#if defined(OSD_SDL)
+ if (m_dll_loaded)
+ SDL_GL_UnloadLibrary();
+#endif // defined(OSD_SDL)
+ m_dll_loaded = false;
+#endif // defined(USE_DISPATCH_GL)
+
+ m_ogl_config = ogl_video_config();
+}
+
+std::unique_ptr<osd_renderer> video_opengl::create(osd_window &window)
+{
+ return std::make_unique<renderer_ogl>(window, m_ogl_config);
}
+
+} // anonymous namespace
+
+} // namespace osd
+
+
+#else // USE_OPENGL
+
+namespace osd { namespace { MODULE_NOT_SUPPORTED(video_opengl, OSD_RENDERER_PROVIDER, "opengl") } }
+
+#endif // USE_OPENGL
+
+
+MODULE_DEFINITION(RENDERER_OPENGL, osd::video_opengl)
diff --git a/src/osd/modules/render/drawogl.h b/src/osd/modules/render/drawogl.h
deleted file mode 100644
index 61b9794353c..00000000000
--- a/src/osd/modules/render/drawogl.h
+++ /dev/null
@@ -1,244 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Olivier Galibert, R. Belmont
-//============================================================
-//
-// drawogl.h - SDL software and OpenGL implementation
-//
-// SDLMAME by Olivier Galibert and R. Belmont
-//
-//============================================================
-#ifndef MAME_OSD_MODULES_RENDER_DRAWOGL_H
-#define MAME_OSD_MODULES_RENDER_DRAWOGL_H
-
-#pragma once
-
-// OSD headers
-#ifndef OSD_WINDOWS
-#ifdef OSD_MAC
-#include "osdmac.h"
-#else
-#include "osdsdl.h"
-#endif
-#include "window.h"
-#else
-#include "../windows/window.h"
-typedef uint64_t HashT;
-#endif
-
-#if defined(OSD_WINDOWS)
-#include "winglcontext.h"
-#elif defined (OSD_MAC)
-#else
-#include "sdlglcontext.h"
-#endif
-
-#include "modules/opengl/gl_shader_mgr.h"
-
-#include "emucore.h"
-#include "render.h"
-
-//============================================================
-// Textures
-//============================================================
-
-/* ogl_texture_info holds information about a texture */
-class ogl_texture_info
-{
-public:
- ogl_texture_info()
- : hash(0), flags(0), rawwidth(0), rawheight(0),
- rawwidth_create(0), rawheight_create(0),
- type(0), format(0), borderpix(0), xprescale(0), yprescale(0), nocopy(0),
- texture(0), texTarget(0), texpow2(0), mpass_dest_idx(0), pbo(0), data(nullptr),
- data_own(0), texCoordBufferName(0)
- {
- for (int i=0; i<2; i++)
- {
- mpass_textureunit[i] = 0;
- mpass_texture_mamebm[i] = 0;
- mpass_fbo_mamebm[i] = 0;
- mpass_texture_scrn[i] = 0;
- mpass_fbo_scrn[i] = 0;
- }
- for (int i=0; i<8; i++)
- texCoord[i] = 0.0f;
- }
-
- HashT hash; // hash value for the texture (must be >= pointer size)
- uint32_t flags; // rendering flags
- render_texinfo texinfo; // copy of the texture info
- int rawwidth, rawheight; // raw width/height of the texture
- int rawwidth_create; // raw width/height, pow2 compatible, if needed
- int rawheight_create; // (create and initial set the texture, not for copy!)
- int type; // what type of texture are we?
- int format; // texture format
- int borderpix; // do we have a 1 pixel border?
- int xprescale; // what is our X prescale factor?
- int yprescale; // what is our Y prescale factor?
- int nocopy; // must the texture date be copied?
-
- uint32_t texture; // OpenGL texture "name"/ID
-
- GLenum texTarget; // OpenGL texture target
- int texpow2; // Is this texture pow2
-
- uint32_t mpass_dest_idx; // Multipass dest idx [0..1]
- uint32_t mpass_textureunit[2]; // texture unit names for GLSL
-
- uint32_t mpass_texture_mamebm[2];// Multipass OpenGL texture "name"/ID for the shader
- uint32_t mpass_fbo_mamebm[2]; // framebuffer object for this texture, multipass
- uint32_t mpass_texture_scrn[2]; // Multipass OpenGL texture "name"/ID for the shader
- uint32_t mpass_fbo_scrn[2]; // framebuffer object for this texture, multipass
-
- uint32_t pbo; // pixel buffer object for this texture (DYNAMIC only!)
- uint32_t *data; // pixels for the texture
- int data_own; // do we own / allocated it ?
- GLfloat texCoord[8];
- GLuint texCoordBufferName;
-
-};
-
-/* renderer_ogl is the information about OpenGL for the current screen */
-class renderer_ogl : public osd_renderer
-{
-public:
- renderer_ogl(std::shared_ptr<osd_window> window)
- : osd_renderer(window, FLAG_NEEDS_OPENGL)
- , m_blittimer(0)
- , m_width(0)
- , m_height(0)
- , m_blit_dim(0, 0)
- , m_gl_context(nullptr)
- , m_initialized(0)
- , m_last_blendmode(0)
- , m_texture_max_width(0)
- , m_texture_max_height(0)
- , m_texpoweroftwo(0)
- , m_usevbo(0)
- , m_usepbo(0)
- , m_usefbo(0)
- , m_useglsl(0)
- , m_glsl(nullptr)
- , m_glsl_program_num(0)
- , m_glsl_program_mb2sc(0)
- , m_usetexturerect(0)
- , m_init_context(0)
- , m_last_hofs(0.0f)
- , m_last_vofs(0.0f)
- , m_surf_w(0)
- , m_surf_h(0)
- {
- for (int i=0; i < HASH_SIZE + OVERFLOW_SIZE; i++)
- m_texhash[i] = nullptr;
- for (int i=0; i < 2*GLSL_SHADER_MAX; i++)
- m_glsl_program[i] = 0;
- for (int i=0; i < 8; i++)
- m_texVerticex[i] = 0.0f;
- }
- virtual ~renderer_ogl();
-
- static void init(running_machine &machine);
- static void exit();
-
- virtual int create() override;
- virtual int draw(const int update) override;
-
-#ifndef OSD_WINDOWS
- virtual int xy_to_render_target(const int x, const int y, int *xt, int *yt) override;
-#endif
- virtual render_primitive_list *get_primitives() override
- {
- auto win = try_getwindow();
- if (win == nullptr)
- return nullptr;
-
- osd_dim nd = win->get_size();
- if (nd != m_blit_dim)
- {
- m_blit_dim = nd;
- notify_changed();
- }
- if ((m_blit_dim.width() == 0) || (m_blit_dim.height() == 0))
- return nullptr;
- win->target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), win->pixel_aspect());
- return &win->target()->get_primitives();
- }
-
-#ifdef OSD_WINDOWS
- virtual void save() override { }
- virtual void record() override { }
- virtual void toggle_fsfx() override { }
-#endif
-
-private:
- static const uint32_t HASH_SIZE = ((1 << 10) + 1);
- static const uint32_t OVERFLOW_SIZE = (1 << 10);
-
- void destroy_all_textures();
-
- static void load_gl_lib(running_machine &machine);
- void loadGLExtensions();
- void initialize_gl();
- void set_blendmode(int blendmode);
- HashT texture_compute_hash(const render_texinfo *texture, uint32_t flags);
- void texture_compute_type_subroutine(const render_texinfo *texsource, ogl_texture_info *texture, uint32_t flags);
- void texture_compute_size_subroutine(ogl_texture_info *texture, uint32_t flags,
- uint32_t width, uint32_t height,
- int* p_width, int* p_height, int* p_width_create, int* p_height_create);
- void texture_compute_size_type(const render_texinfo *texsource, ogl_texture_info *texture, uint32_t flags);
- ogl_texture_info *texture_create(const render_texinfo *texsource, uint32_t flags);
- int texture_shader_create(const render_texinfo *texsource, ogl_texture_info *texture, uint32_t flags);
- ogl_texture_info *texture_find(const render_primitive *prim);
- void texture_coord_update(ogl_texture_info *texture, const render_primitive *prim, int shaderIdx);
- void texture_mpass_flip(ogl_texture_info *texture, int shaderIdx);
- void texture_shader_update(ogl_texture_info *texture, render_container *container, int shaderIdx);
- ogl_texture_info * texture_update(const render_primitive *prim, int shaderIdx);
- void texture_disable(ogl_texture_info * texture);
- void texture_all_disable();
-
- int32_t m_blittimer;
- int m_width;
- int m_height;
- osd_dim m_blit_dim;
-
- osd_gl_context *m_gl_context;
-
- int m_initialized; // is everything well initialized, i.e. all GL stuff etc.
- // 3D info (GL mode only)
- ogl_texture_info * m_texhash[HASH_SIZE + OVERFLOW_SIZE];
- int m_last_blendmode; // previous blendmode
- int32_t m_texture_max_width; // texture maximum width
- int32_t m_texture_max_height; // texture maximum height
- int m_texpoweroftwo; // must textures be power-of-2 sized?
- int m_usevbo; // runtime check if VBO is available
- int m_usepbo; // runtime check if PBO is available
- int m_usefbo; // runtime check if FBO is available
- int m_useglsl; // runtime check if GLSL is available
-
- glsl_shader_info *m_glsl; // glsl_shader_info
-
- GLhandleARB m_glsl_program[2*GLSL_SHADER_MAX]; // GLSL programs, or 0
- int m_glsl_program_num; // number of GLSL programs
- int m_glsl_program_mb2sc; // GLSL program idx, which transforms
- // the mame-bitmap. screen-bitmap (size/rotation/..)
- // All progs <= glsl_program_mb2sc using the mame bitmap
- // as input, otherwise the screen bitmap.
- // All progs >= glsl_program_mb2sc using the screen bitmap
- // as output, otherwise the mame bitmap.
- int m_usetexturerect; // use ARB_texture_rectangle for non-power-of-2, general use
-
- int m_init_context; // initialize context before next draw
-
- float m_last_hofs;
- float m_last_vofs;
-
- // Static vars from draogl_window_dra
- int32_t m_surf_w;
- int32_t m_surf_h;
- GLfloat m_texVerticex[8];
-
- static bool s_shown_video_info;
- static bool s_dll_loaded;
-};
-
-#endif // MAME_OSD_MODULES_RENDER_DRAWOGL_H
diff --git a/src/osd/modules/render/drawsdl.cpp b/src/osd/modules/render/drawsdl.cpp
index 9e5de59c412..b1a9e93f42e 100644
--- a/src/osd/modules/render/drawsdl.cpp
+++ b/src/osd/modules/render/drawsdl.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Couriersud, Olivier Galibert, R. Belmont
//============================================================
//
-// drawsdl.c - SDL software and OpenGL implementation
+// drawsdl.cpp - SDL software and OpenGL implementation
//
// SDLMAME by Olivier Galibert and R. Belmont
//
@@ -10,28 +10,37 @@
//
//============================================================
-// standard C headers
-#include <cmath>
-#include <cstdio>
+#include "render_module.h"
+
+#include "modules/osdmodule.h"
+
+#if defined(OSD_SDL)
+
+// from specific OSD implementation
+#include "sdlopts.h"
+#include "window.h"
+
+// general OSD headers
+#include "modules/monitor/monitor_module.h"
// MAME headers
#include "emucore.h"
-#include "ui/uimain.h"
+#include "render.h"
#include "rendersw.hxx"
-// standard SDL headers
+//#include "ui/uimain.h"
+
#include <SDL2/SDL.h>
-// OSD headers
-#include "osdsdl.h"
-#include "window.h"
+// standard C headers
+#include <cmath>
+#include <cstdio>
+#include <memory>
-#include "drawsdl.h"
-#include "modules/monitor/monitor_module.h"
-//============================================================
-// DEBUGGING
-//============================================================
+namespace osd {
+
+namespace {
//============================================================
// CONSTANTS
@@ -41,60 +50,90 @@
#define DRAW2_SCALEMODE_LINEAR "1"
#define DRAW2_SCALEMODE_BEST "2"
-//============================================================
-// PROTOTYPES
-//============================================================
-
-// YUV overlays
-
-static void yuv_RGB_to_YV12(const uint16_t *bitmap, uint8_t *ptr, const int pitch, \
- const uint32_t *lookup, const int width, const int height);
-static void yuv_RGB_to_YV12X2(const uint16_t *bitmap, uint8_t *ptr, const int pitch, \
- const uint32_t *lookup, const int width, const int height);
-static void yuv_RGB_to_YUY2(const uint16_t *bitmap, uint8_t *ptr, const int pitch, \
- const uint32_t *lookup, const int width, const int height);
-static void yuv_RGB_to_YUY2X2(const uint16_t *bitmap, uint8_t *ptr, const int pitch, \
- const uint32_t *lookup, const int width, const int height);
-
-// Static declarations
-static const sdl_scale_mode scale_modes[] =
+struct sdl_scale_mode
{
- { "none", 0, 0, 1, 1, DRAW2_SCALEMODE_NEAREST, 0, nullptr },
- { "hwblit", 1, 0, 1, 1, DRAW2_SCALEMODE_LINEAR, 0, nullptr },
- { "hwbest", 1, 0, 1, 1, DRAW2_SCALEMODE_BEST, 0, nullptr },
- /* SDL1.2 uses interpolation as well */
- { "yv12", 1, 1, 1, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YV12, yuv_RGB_to_YV12 },
- { "yv12x2", 1, 1, 2, 2, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YV12, yuv_RGB_to_YV12X2 },
- { "yuy2", 1, 1, 1, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YUY2, yuv_RGB_to_YUY2 },
- { "yuy2x2", 1, 1, 2, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YUY2, yuv_RGB_to_YUY2X2 },
- { nullptr }
+ const char *name;
+ int is_scale; /* Scale mode? */
+ int is_yuv; /* Yuv mode? */
+ int mult_w; /* Width multiplier */
+ int mult_h; /* Height multiplier */
+ const char *sdl_scale_mode_hint; /* what to use as a hint ? */
+ int pixel_format; /* Pixel/Overlay format */
+ void (*yuv_blit)(const uint16_t *bitmap, uint8_t *ptr, const int pitch, const uint32_t *lookup, const int width, const int height);
};
-int drawsdl_scale_mode(const char *s)
-{
- const sdl_scale_mode *sm = scale_modes;
- int index;
- index = 0;
- while (sm->name != nullptr)
+// renderer_sdl1 is the information about SDL for the current screen
+class renderer_sdl1 : public osd_renderer
+{
+public:
+
+ renderer_sdl1(osd_window &w, sdl_scale_mode const &scale_mode)
+ : osd_renderer(w)
+ , m_scale_mode(scale_mode)
+ , m_sdl_renderer(nullptr)
+ , m_texture_id(nullptr)
+ , m_yuv_lookup()
+ , m_yuv_bitmap()
+ //, m_hw_scale_width(0)
+ //, m_hw_scale_height(0)
+ , m_last_hofs(0)
+ , m_last_vofs(0)
+ , m_blit_dim(0, 0)
+ , m_last_dim(0, 0)
{
- if (strcmp(sm->name, s) == 0)
- return index;
- index++;
- sm++;
}
- return -1;
-}
+ virtual ~renderer_sdl1();
+
+ virtual int create() override;
+ virtual int draw(const int update) override;
+ virtual int xy_to_render_target(const int x, const int y, int *xt, int *yt) override;
+ virtual render_primitive_list *get_primitives() override;
+
+private:
+ void show_info(struct SDL_RendererInfo *render_info);
+
+ void destroy_all_textures();
+ void yuv_init();
+ void setup_texture(const osd_dim &size);
+ void yuv_lookup_set(unsigned int pen, unsigned char red,
+ unsigned char green, unsigned char blue);
+
+ int32_t m_blittimer;
+
+ sdl_scale_mode const &m_scale_mode;
+ SDL_Renderer *m_sdl_renderer;
+ SDL_Texture *m_texture_id;
+
+ // YUV overlay
+ std::unique_ptr<uint32_t []> m_yuv_lookup;
+ std::unique_ptr<uint16_t []> m_yuv_bitmap;
+
+ // if we leave scaling to SDL and the underlying driver, this
+ // is the render_target_width/height to use
+
+ int m_last_hofs;
+ int m_last_vofs;
+ osd_dim m_blit_dim;
+ osd_dim m_last_dim;
+};
+
//============================================================
-// drawsdl_init
+// PROTOTYPES
//============================================================
-void renderer_sdl1::init(running_machine &machine)
-{
- osd_printf_verbose("Using SDL multi-window soft driver (SDL 2.0+)\n");
-}
+// YUV overlays
+
+static void yuv_RGB_to_YV12(const uint16_t *bitmap, uint8_t *ptr, const int pitch,
+ const uint32_t *lookup, const int width, const int height);
+static void yuv_RGB_to_YV12X2(const uint16_t *bitmap, uint8_t *ptr, const int pitch,
+ const uint32_t *lookup, const int width, const int height);
+static void yuv_RGB_to_YUY2(const uint16_t *bitmap, uint8_t *ptr, const int pitch,
+ const uint32_t *lookup, const int width, const int height);
+static void yuv_RGB_to_YUY2X2(const uint16_t *bitmap, uint8_t *ptr, const int pitch,
+ const uint32_t *lookup, const int width, const int height);
//============================================================
// setup_texture for window
@@ -102,38 +141,35 @@ void renderer_sdl1::init(running_machine &machine)
void renderer_sdl1::setup_texture(const osd_dim &size)
{
- const sdl_scale_mode *sdl_sm = &scale_modes[video_config.scale_mode];
SDL_DisplayMode mode;
uint32_t fmt;
- auto win = assert_window();
-
// Determine preferred pixelformat and set up yuv if necessary
- SDL_GetCurrentDisplayMode(win->monitor()->oshandle(), &mode);
+ SDL_GetCurrentDisplayMode(window().monitor()->oshandle(), &mode);
m_yuv_bitmap.reset();
- fmt = (sdl_sm->pixel_format ? sdl_sm->pixel_format : mode.format);
+ fmt = (m_scale_mode.pixel_format ? m_scale_mode.pixel_format : mode.format);
- if (sdl_sm->is_scale)
+ if (m_scale_mode.is_scale)
{
int m_hw_scale_width = 0;
int m_hw_scale_height = 0;
- win->target()->compute_minimum_size(m_hw_scale_width, m_hw_scale_height);
- if (win->prescale())
+ window().target()->compute_minimum_size(m_hw_scale_width, m_hw_scale_height);
+ if (window().prescale())
{
- m_hw_scale_width *= win->prescale();
- m_hw_scale_height *= win->prescale();
+ m_hw_scale_width *= window().prescale();
+ m_hw_scale_height *= window().prescale();
/* This must be a multiple of 2 */
m_hw_scale_width = (m_hw_scale_width + 1) & ~1;
}
- if (sdl_sm->is_yuv)
+ if (m_scale_mode.is_yuv)
m_yuv_bitmap = std::make_unique<uint16_t []>(m_hw_scale_width * m_hw_scale_height);
- int w = m_hw_scale_width * sdl_sm->mult_w;
- int h = m_hw_scale_height * sdl_sm->mult_h;
+ int w = m_hw_scale_width * m_scale_mode.mult_w;
+ int h = m_hw_scale_height * m_scale_mode.mult_h;
m_texture_id = SDL_CreateTexture(m_sdl_renderer, fmt, SDL_TEXTUREACCESS_STREAMING, w, h);
@@ -182,26 +218,23 @@ void renderer_sdl1::show_info(struct SDL_RendererInfo *render_info)
int renderer_sdl1::create()
{
- const sdl_scale_mode *sm = &scale_modes[video_config.scale_mode];
-
- auto win = assert_window();
// create renderer
/* set hints ... */
- SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, sm->sdl_scale_mode_hint);
+ SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, m_scale_mode.sdl_scale_mode_hint);
if (video_config.waitvsync)
- m_sdl_renderer = SDL_CreateRenderer(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
+ m_sdl_renderer = SDL_CreateRenderer(dynamic_cast<sdl_window_info &>(window()).platform_window(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
else
- m_sdl_renderer = SDL_CreateRenderer(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window(), -1, SDL_RENDERER_ACCELERATED);
+ m_sdl_renderer = SDL_CreateRenderer(dynamic_cast<sdl_window_info &>(window()).platform_window(), -1, SDL_RENDERER_ACCELERATED);
if (!m_sdl_renderer)
{
if (video_config.waitvsync)
- m_sdl_renderer = SDL_CreateRenderer(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_SOFTWARE);
+ m_sdl_renderer = SDL_CreateRenderer(dynamic_cast<sdl_window_info &>(window()).platform_window(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_SOFTWARE);
else
- m_sdl_renderer = SDL_CreateRenderer(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window(), -1, SDL_RENDERER_SOFTWARE);
+ m_sdl_renderer = SDL_CreateRenderer(dynamic_cast<sdl_window_info &>(window()).platform_window(), -1, SDL_RENDERER_SOFTWARE);
}
if (!m_sdl_renderer)
@@ -216,18 +249,18 @@ int renderer_sdl1::create()
// Check scale mode
- if (sm->pixel_format)
+ if (m_scale_mode.pixel_format)
{
int i;
int found = 0;
for (i=0; i < render_info.num_texture_formats; i++)
- if (sm->pixel_format == render_info.texture_formats[i])
+ if (m_scale_mode.pixel_format == render_info.texture_formats[i])
found = 1;
if (!found)
{
- fatalerror("window: Scale mode %s not supported!", sm->name);
+ fatalerror("window: Scale mode %s not supported!", m_scale_mode.name);
}
}
@@ -288,7 +321,6 @@ void renderer_sdl1::destroy_all_textures()
int renderer_sdl1::draw(int update)
{
- const sdl_scale_mode *sm = &scale_modes[video_config.scale_mode];
uint8_t *surfptr;
int32_t pitch;
Uint32 rmask, gmask, bmask;
@@ -296,14 +328,7 @@ int renderer_sdl1::draw(int update)
int32_t vofs, hofs, blitwidth, blitheight, ch, cw;
int bpp;
- if (video_config.novideo)
- {
- return 0;
- }
-
- auto win = assert_window();
-
- osd_dim wdim = win->get_size();
+ osd_dim wdim = window().get_size();
if (has_flags(FI_CHANGED) || (wdim != m_last_dim))
{
destroy_all_textures();
@@ -370,15 +395,15 @@ int renderer_sdl1::draw(int update)
m_last_hofs = hofs;
m_last_vofs = vofs;
- win->m_primlist->acquire_lock();
+ window().m_primlist->acquire_lock();
int mamewidth, mameheight;
Uint32 fmt = 0;
int access = 0;
SDL_QueryTexture(m_texture_id, &fmt, &access, &mamewidth, &mameheight);
- mamewidth /= sm->mult_w;
- mameheight /= sm->mult_h;
+ mamewidth /= m_scale_mode.mult_w;
+ mameheight /= m_scale_mode.mult_h;
//printf("w h %d %d %d %d\n", mamewidth, mameheight, blitwidth, blitheight);
// rescale bounds
@@ -388,7 +413,7 @@ int renderer_sdl1::draw(int update)
// FIXME: this could be a lot easier if we get the primlist here!
// Bounds would be set fit for purpose and done!
- for (render_primitive &prim : *win->m_primlist)
+ for (render_primitive &prim : *window().m_primlist)
{
prim.bounds.x0 = floor(fw * prim.bounds.x0 + 0.5f);
prim.bounds.x1 = floor(fw * prim.bounds.x1 + 0.5f);
@@ -397,32 +422,32 @@ int renderer_sdl1::draw(int update)
}
// render to it
- if (!sm->is_yuv)
+ if (!m_scale_mode.is_yuv)
{
switch (rmask)
{
case 0xff000000:
- software_renderer<uint32_t, 0,0,0, 24,16,8>::draw_primitives(*win->m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
+ software_renderer<uint32_t, 0,0,0, 24,16,8>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
break;
case 0x0000ff00:
- software_renderer<uint32_t, 0,0,0, 8,16,24>::draw_primitives(*win->m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
+ software_renderer<uint32_t, 0,0,0, 8,16,24>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
break;
case 0x00ff0000:
- software_renderer<uint32_t, 0,0,0, 16,8,0>::draw_primitives(*win->m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
+ software_renderer<uint32_t, 0,0,0, 16,8,0>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
break;
case 0x000000ff:
- software_renderer<uint32_t, 0,0,0, 0,8,16>::draw_primitives(*win->m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
+ software_renderer<uint32_t, 0,0,0, 0,8,16>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
break;
case 0xf800:
- software_renderer<uint16_t, 3,2,3, 11,5,0>::draw_primitives(*win->m_primlist, surfptr, mamewidth, mameheight, pitch / 2);
+ software_renderer<uint16_t, 3,2,3, 11,5,0>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 2);
break;
case 0x7c00:
- software_renderer<uint16_t, 3,3,3, 10,5,0>::draw_primitives(*win->m_primlist, surfptr, mamewidth, mameheight, pitch / 2);
+ software_renderer<uint16_t, 3,3,3, 10,5,0>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 2);
break;
default:
@@ -434,11 +459,11 @@ int renderer_sdl1::draw(int update)
{
assert (m_yuv_bitmap != nullptr);
assert (surfptr != nullptr);
- software_renderer<uint16_t, 3,3,3, 10,5,0>::draw_primitives(*win->m_primlist, m_yuv_bitmap.get(), mamewidth, mameheight, mamewidth);
- sm->yuv_blit(m_yuv_bitmap.get(), surfptr, pitch, m_yuv_lookup.get(), mamewidth, mameheight);
+ software_renderer<uint16_t, 3,3,3, 10,5,0>::draw_primitives(*window().m_primlist, m_yuv_bitmap.get(), mamewidth, mameheight, mamewidth);
+ m_scale_mode.yuv_blit(m_yuv_bitmap.get(), surfptr, pitch, m_yuv_lookup.get(), mamewidth, mameheight);
}
- win->m_primlist->release_lock();
+ window().m_primlist->release_lock();
// unlock and flip
SDL_UnlockTexture(m_texture_id);
@@ -527,7 +552,7 @@ void renderer_sdl1::yuv_init()
//uint32_t *lookup = sdl->m_yuv_lookup;
-static void yuv_RGB_to_YV12(const uint16_t *bitmap, uint8_t *ptr, const int pitch, \
+static void yuv_RGB_to_YV12(const uint16_t *bitmap, uint8_t *ptr, const int pitch,
const uint32_t *lookup, const int width, const int height)
{
int x, y;
@@ -581,7 +606,7 @@ static void yuv_RGB_to_YV12(const uint16_t *bitmap, uint8_t *ptr, const int pitc
}
}
-static void yuv_RGB_to_YV12X2(const uint16_t *bitmap, uint8_t *ptr, const int pitch, \
+static void yuv_RGB_to_YV12X2(const uint16_t *bitmap, uint8_t *ptr, const int pitch,
const uint32_t *lookup, const int width, const int height)
{
/* this one is used when scale==2 */
@@ -616,7 +641,7 @@ static void yuv_RGB_to_YV12X2(const uint16_t *bitmap, uint8_t *ptr, const int pi
}
}
-static void yuv_RGB_to_YUY2(const uint16_t *bitmap, uint8_t *ptr, const int pitch, \
+static void yuv_RGB_to_YUY2(const uint16_t *bitmap, uint8_t *ptr, const int pitch,
const uint32_t *lookup, const int width, const int height)
{
/* this one is used when scale==2 */
@@ -642,7 +667,7 @@ static void yuv_RGB_to_YUY2(const uint16_t *bitmap, uint8_t *ptr, const int pitc
}
}
-static void yuv_RGB_to_YUY2X2(const uint16_t *bitmap, uint8_t *ptr, const int pitch, \
+static void yuv_RGB_to_YUY2X2(const uint16_t *bitmap, uint8_t *ptr, const int pitch,
const uint32_t *lookup, const int width, const int height)
{
/* this one is used when scale==2 */
@@ -666,16 +691,98 @@ static void yuv_RGB_to_YUY2X2(const uint16_t *bitmap, uint8_t *ptr, const int pi
render_primitive_list *renderer_sdl1::get_primitives()
{
- auto win = try_getwindow();
- if (win == nullptr)
- return nullptr;
-
- osd_dim nd = win->get_size();
+ osd_dim nd = window().get_size();
if (nd != m_blit_dim)
{
m_blit_dim = nd;
notify_changed();
}
- win->target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), win->pixel_aspect());
- return &win->target()->get_primitives();
+ window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().pixel_aspect());
+ return &window().target()->get_primitives();
+}
+
+
+class video_sdl1 : public osd_module, public render_module
+{
+public:
+ video_sdl1()
+ : osd_module(OSD_RENDERER_PROVIDER, "soft")
+ , m_scale_mode(-1)
+ {
+ }
+
+ virtual int init(osd_interface &osd, osd_options const &options) override;
+ virtual void exit() override { }
+
+ virtual std::unique_ptr<osd_renderer> create(osd_window &window) override;
+
+protected:
+ virtual unsigned flags() const override { return FLAG_INTERACTIVE; }
+
+private:
+ static int get_scale_mode(char const *modestr);
+
+ int m_scale_mode;
+
+ static sdl_scale_mode const s_scale_modes[];
+};
+
+int video_sdl1::init(osd_interface &osd, osd_options const &options)
+{
+ osd_printf_verbose("Using SDL multi-window soft driver (SDL 2.0+)\n");
+
+ // yuv settings ...
+ char const *const modestr = dynamic_cast<sdl_options const &>(options).scale_mode();
+ m_scale_mode = get_scale_mode(modestr);
+ if (m_scale_mode < 0)
+ {
+ osd_printf_warning("Invalid yuvmode value %s; reverting to none\n", modestr);
+ m_scale_mode = 0;
+ }
+
+ return 0;
+}
+
+std::unique_ptr<osd_renderer> video_sdl1::create(osd_window &window)
+{
+ return std::make_unique<renderer_sdl1>(window, s_scale_modes[m_scale_mode]);
}
+
+int video_sdl1::get_scale_mode(char const *modestr)
+{
+ const sdl_scale_mode *sm = s_scale_modes;
+ int index = 0;
+ while (sm->name)
+ {
+ if (!strcmp(sm->name, modestr))
+ return index;
+ index++;
+ sm++;
+ }
+ return -1;
+}
+
+sdl_scale_mode const video_sdl1::s_scale_modes[] = {
+ { "none", 0, 0, 1, 1, DRAW2_SCALEMODE_NEAREST, 0, nullptr },
+ { "hwblit", 1, 0, 1, 1, DRAW2_SCALEMODE_LINEAR, 0, nullptr },
+ { "hwbest", 1, 0, 1, 1, DRAW2_SCALEMODE_BEST, 0, nullptr },
+ /* SDL1.2 uses interpolation as well */
+ { "yv12", 1, 1, 1, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YV12, yuv_RGB_to_YV12 },
+ { "yv12x2", 1, 1, 2, 2, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YV12, yuv_RGB_to_YV12X2 },
+ { "yuy2", 1, 1, 1, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YUY2, yuv_RGB_to_YUY2 },
+ { "yuy2x2", 1, 1, 2, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YUY2, yuv_RGB_to_YUY2X2 },
+ { nullptr } };
+
+} // anonymous namespace
+
+} // namespace osd
+
+
+#else // defined(OSD_SDL)
+
+namespace osd { namespace { MODULE_NOT_SUPPORTED(video_sdl1, OSD_RENDERER_PROVIDER, "soft") } }
+
+#endif // defined(OSD_SDL)
+
+
+MODULE_DEFINITION(RENDERER_SDL1, osd::video_sdl1)
diff --git a/src/osd/modules/render/drawsdl.h b/src/osd/modules/render/drawsdl.h
deleted file mode 100644
index bc8246a632d..00000000000
--- a/src/osd/modules/render/drawsdl.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Couriersud, Olivier Galibert, R. Belmont
-//============================================================
-//
-// drawsdl.h - SDL software and OpenGL implementation
-//
-// SDLMAME by Olivier Galibert and R. Belmont
-//
-// yuvmodes by Couriersud
-//
-//============================================================
-
-#ifndef MAME_OSD_MODULES_RENDER_DRAWSDL_H
-#define MAME_OSD_MODULES_RENDER_DRAWSDL_H
-
-#pragma once
-
-#include <SDL2/SDL.h>
-
-/* renderer_sdl1 is the information about SDL for the current screen */
-class renderer_sdl1 : public osd_renderer
-{
-public:
-
- renderer_sdl1(std::shared_ptr<osd_window> w, int extra_flags)
- : osd_renderer(w, FLAG_NEEDS_OPENGL | extra_flags)
- , m_sdl_renderer(nullptr)
- , m_texture_id(nullptr)
- , m_yuv_lookup()
- , m_yuv_bitmap()
- //, m_hw_scale_width(0)
- //, m_hw_scale_height(0)
- , m_last_hofs(0)
- , m_last_vofs(0)
- , m_blit_dim(0, 0)
- , m_last_dim(0, 0)
- {
- }
- virtual ~renderer_sdl1();
-
- static void init(running_machine &machine);
- static void exit() { }
-
- virtual int create() override;
- virtual int draw(const int update) override;
- virtual int xy_to_render_target(const int x, const int y, int *xt, int *yt) override;
- virtual render_primitive_list *get_primitives() override;
-
-private:
- void show_info(struct SDL_RendererInfo *render_info);
-
- void destroy_all_textures();
- void yuv_init();
- void setup_texture(const osd_dim &size);
- void yuv_lookup_set(unsigned int pen, unsigned char red,
- unsigned char green, unsigned char blue);
-
- int32_t m_blittimer;
-
- SDL_Renderer *m_sdl_renderer;
- SDL_Texture *m_texture_id;
-
- // YUV overlay
- std::unique_ptr<uint32_t []> m_yuv_lookup;
- std::unique_ptr<uint16_t []> m_yuv_bitmap;
-
- // if we leave scaling to SDL and the underlying driver, this
- // is the render_target_width/height to use
-
- int m_last_hofs;
- int m_last_vofs;
- osd_dim m_blit_dim;
- osd_dim m_last_dim;
-};
-
-struct sdl_scale_mode
-{
- const char *name;
- int is_scale; /* Scale mode? */
- int is_yuv; /* Yuv mode? */
- int mult_w; /* Width multiplier */
- int mult_h; /* Height multiplier */
- const char *sdl_scale_mode_hint; /* what to use as a hint ? */
- int pixel_format; /* Pixel/Overlay format */
- void (*yuv_blit)(const uint16_t *bitmap, uint8_t *ptr, const int pitch, const uint32_t *lookup, const int width, const int height);
-};
-
-#endif // MAME_OSD_MODULES_RENDER_DRAWSDL_H
diff --git a/src/osd/modules/render/render_module.h b/src/osd/modules/render/render_module.h
new file mode 100644
index 00000000000..b22f35fdb3c
--- /dev/null
+++ b/src/osd/modules/render/render_module.h
@@ -0,0 +1,38 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+#ifndef MAME_OSD_MODULES_RENDER_RENDER_MODULE_H
+#define MAME_OSD_MODULES_RENDER_RENDER_MODULE_H
+
+#pragma once
+
+#include "osdepend.h"
+#include "modules/osdmodule.h"
+
+#include <memory>
+
+
+#define OSD_RENDERER_PROVIDER "video"
+
+
+class osd_renderer;
+class osd_window;
+
+
+class render_module
+{
+public:
+ virtual ~render_module() = default;
+
+ virtual std::unique_ptr<osd_renderer> create(osd_window &window) = 0;
+
+ bool is_interactive() const { return flags() & FLAG_INTERACTIVE; }
+ bool sdl_needs_opengl() const { return flags() & FLAG_SDL_NEEDS_OPENGL; }
+
+protected:
+ static inline constexpr unsigned FLAG_INTERACTIVE = 1;
+ static inline constexpr unsigned FLAG_SDL_NEEDS_OPENGL = 2;
+
+ virtual unsigned flags() const = 0;
+};
+
+#endif // MAME_OSD_MODULES_RENDER_RENDER_MODULE_H
diff --git a/src/osd/modules/render/sdlglcontext.h b/src/osd/modules/render/sdlglcontext.h
index b8ff4d72aa2..d2055060bd6 100644
--- a/src/osd/modules/render/sdlglcontext.h
+++ b/src/osd/modules/render/sdlglcontext.h
@@ -8,61 +8,76 @@
//
//============================================================
+#ifndef MAME_RENDER_SDLGLCONTEXT_H
+#define MAME_RENDER_SDLGLCONTEXT_H
+
#pragma once
-#ifndef __SDL_GL_CONTEXT__
-#define __SDL_GL_CONTEXT__
+#include "modules/opengl/osd_opengl.h"
+
+#include "strformat.h"
#include <SDL2/SDL.h>
-#include "modules/opengl/osd_opengl.h"
+
+#include <string>
+
class sdl_gl_context : public osd_gl_context
{
public:
- sdl_gl_context(SDL_Window *window) : osd_gl_context(), m_context(0), m_window(window)
+ sdl_gl_context(SDL_Window *window) : m_context(0), m_window(window)
{
- m_error[0] = 0;
m_context = SDL_GL_CreateContext(window);
- if (!m_context)
+ if (!m_context)
{
- snprintf(m_error,255, "OpenGL not supported on this driver: %s", SDL_GetError());
+ try { m_error = util::string_format("OpenGL not supported on this driver: %s", SDL_GetError()); }
+ catch (...) { m_error.clear(); }
}
}
+
virtual ~sdl_gl_context()
{
- SDL_GL_DeleteContext(m_context);
+ if (m_context)
+ SDL_GL_DeleteContext(m_context);
}
- virtual void MakeCurrent() override
+
+ virtual explicit operator bool() const override
+ {
+ return bool(m_context);
+ }
+
+ virtual void make_current() override
{
SDL_GL_MakeCurrent(m_window, m_context);
}
- virtual int SetSwapInterval(const int swap) override
+ virtual bool set_swap_interval(const int swap) override
{
- return SDL_GL_SetSwapInterval(swap);
+ return 0 == SDL_GL_SetSwapInterval(swap);
}
- virtual const char *LastErrorMsg() override
+ virtual const char *last_error_message() override
{
- if (m_error[0] == 0)
- return nullptr;
+ if (!m_error.empty())
+ return m_error.c_str();
else
- return m_error;
+ return nullptr;
}
- virtual void *getProcAddress(const char *proc) override
+
+ virtual void *get_proc_address(const char *proc) override
{
return SDL_GL_GetProcAddress(proc);
}
- virtual void SwapBuffer() override
+ virtual void swap_buffer() override
{
SDL_GL_SwapWindow(m_window);
}
private:
SDL_GLContext m_context;
- SDL_Window *m_window;
- char m_error[256];
+ SDL_Window *const m_window;
+ std::string m_error;
};
-#endif // __SDL_GL_CONTEXT__
+#endif // MAME_RENDER_SDLGLCONTEXT_H
diff --git a/src/osd/modules/render/winglcontext.h b/src/osd/modules/render/winglcontext.h
index f0cb1b6af77..48d1462d2f6 100644
--- a/src/osd/modules/render/winglcontext.h
+++ b/src/osd/modules/render/winglcontext.h
@@ -7,168 +7,197 @@
// SDLMAME by Olivier Galibert and R. Belmont
//
//============================================================
+#ifndef MAME_RENDER_WINGLCONTEXT_H
+#define MAME_RENDER_WINGLCONTEXT_H
#pragma once
-#ifndef __WIN_GL_CONTEXT__
-#define __WIN_GL_CONTEXT__
-
#include "modules/opengl/osd_opengl.h"
#include "modules/lib/osdlib.h"
-// Typedefs for dynamically loaded functions
-typedef PROC (WINAPI *wglGetProcAddress_fn)(LPCSTR);
-typedef HGLRC (WINAPI *wglCreateContext_fn)(HDC);
-typedef BOOL (WINAPI *wglDeleteContext_fn)(HGLRC);
-typedef BOOL (WINAPI *wglMakeCurrent_fn)(HDC, HGLRC);
+#include "strconv.h"
+
+#include <cstring>
+#include <string>
-typedef const char * (WINAPI *wglGetExtensionsStringEXT_fn)(void);
-typedef BOOL (WINAPI *wglSwapIntervalEXT_fn)(int);
-typedef int (WINAPI *wglGetSwapIntervalEXT_fn)(void);
class win_gl_context : public osd_gl_context
{
public:
- win_gl_context(HWND window) : osd_gl_context(), m_context(0), m_window(nullptr), m_hdc(0)
- {
- m_error[0] = 0;
+ using osd_gl_context::get_proc_address;
+ win_gl_context(HWND window) : m_context(nullptr), m_window(window), m_hdc(nullptr)
+ {
+ // open DLL and bind required functions
opengl32_dll = osd::dynamic_module::open({ "opengl32.dll" });
-
pfn_wglGetProcAddress = opengl32_dll->bind<wglGetProcAddress_fn>("wglGetProcAddress");
pfn_wglCreateContext = opengl32_dll->bind<wglCreateContext_fn>("wglCreateContext");
pfn_wglDeleteContext = opengl32_dll->bind<wglDeleteContext_fn>("wglDeleteContext");
pfn_wglMakeCurrent = opengl32_dll->bind<wglMakeCurrent_fn>("wglMakeCurrent");
+ if (!pfn_wglGetProcAddress || !pfn_wglCreateContext || !pfn_wglDeleteContext || !pfn_wglMakeCurrent)
+ return;
- if (pfn_wglGetProcAddress == nullptr || pfn_wglCreateContext == nullptr ||
- pfn_wglDeleteContext == nullptr || pfn_wglMakeCurrent == nullptr)
+ m_hdc = GetDC(window);
+ if (!m_hdc)
{
+ get_last_error_string();
return;
}
- pfn_wglGetExtensionsStringEXT = (wglGetExtensionsStringEXT_fn)(*pfn_wglGetProcAddress)("wglGetExtensionsStringEXT");
+ if (setupPixelFormat())
+ {
+ m_context = (*pfn_wglCreateContext)(m_hdc);
+ if (!m_context)
+ get_last_error_string();
+ }
+ if (!m_context)
+ return;
+
+ (*pfn_wglMakeCurrent)(m_hdc, m_context);
+ get_proc_address(pfn_wglGetExtensionsStringEXT, "wglGetExtensionsStringEXT");
if (WGLExtensionSupported("WGL_EXT_swap_control"))
{
- pfn_wglSwapIntervalEXT = (BOOL (WINAPI *) (int)) getProcAddress("wglSwapIntervalEXT");
- pfn_wglGetSwapIntervalEXT = (int (WINAPI *) (void)) getProcAddress("wglGetSwapIntervalEXT");
+ get_proc_address(pfn_wglSwapIntervalEXT, "wglSwapIntervalEXT");
+ get_proc_address(pfn_wglGetSwapIntervalEXT, "wglGetSwapIntervalEXT");
}
else
{
pfn_wglSwapIntervalEXT = nullptr;
pfn_wglGetSwapIntervalEXT = nullptr;
}
-
- m_hdc = GetDC(window);
- if (!setupPixelFormat(m_hdc))
- {
- m_context = (*pfn_wglCreateContext)(m_hdc);
- if (!m_context)
- {
- FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, GetLastError(), 0, m_error, 255, nullptr);
- return;
- }
- (*pfn_wglMakeCurrent)(m_hdc, m_context);
- }
}
virtual ~win_gl_context()
{
- (*pfn_wglDeleteContext)(m_context);
- ReleaseDC(m_window, m_hdc);
+ if (m_context)
+ (*pfn_wglDeleteContext)(m_context);
+
+ if (m_hdc)
+ ReleaseDC(m_window, m_hdc);
+ }
+
+ virtual explicit operator bool() const override
+ {
+ return bool(m_context);
}
- virtual void MakeCurrent() override
+ virtual void make_current() override
{
(*pfn_wglMakeCurrent)(m_hdc, m_context);
}
- virtual const char *LastErrorMsg() override
+ virtual const char *last_error_message() override
{
- if (m_error[0] == 0)
- return nullptr;
+ if (!m_error.empty())
+ return m_error.c_str();
else
- return m_error;
+ return nullptr;
}
- virtual void *getProcAddress(const char *proc) override
+ virtual void *get_proc_address(const char *proc) override
{
- return (void *)(*pfn_wglGetProcAddress)(proc);
+ return reinterpret_cast<void *>(uintptr_t((*pfn_wglGetProcAddress)(proc)));
}
- virtual int SetSwapInterval(const int swap) override
+ virtual bool set_swap_interval(const int swap) override
{
- if (pfn_wglSwapIntervalEXT != nullptr)
- {
- pfn_wglSwapIntervalEXT(swap ? 1 : 0);
- }
- return 0;
+ if (!pfn_wglSwapIntervalEXT)
+ return false;
+
+ pfn_wglSwapIntervalEXT(swap ? 1 : 0);
+ return true;
}
- virtual void SwapBuffer() override
+ virtual void swap_buffer() override
{
SwapBuffers(m_hdc);
//wglSwapLayerBuffers(GetDC(window().m_hwnd), WGL_SWAP_MAIN_PLANE);
}
private:
+ // Typedefs for dynamically loaded functions
+ typedef PROC (WINAPI *wglGetProcAddress_fn)(LPCSTR);
+ typedef HGLRC (WINAPI *wglCreateContext_fn)(HDC);
+ typedef BOOL (WINAPI *wglDeleteContext_fn)(HGLRC);
+ typedef BOOL (WINAPI *wglMakeCurrent_fn)(HDC, HGLRC);
- int setupPixelFormat(HDC hDC)
+ typedef const char * (WINAPI *wglGetExtensionsStringEXT_fn)();
+ typedef BOOL (WINAPI *wglSwapIntervalEXT_fn)(int);
+ typedef int (WINAPI *wglGetSwapIntervalEXT_fn)();
+
+ bool setupPixelFormat()
{
PIXELFORMATDESCRIPTOR pfd = {
- sizeof(PIXELFORMATDESCRIPTOR), /* size */
- 1, /* version */
- PFD_SUPPORT_OPENGL |
- PFD_DRAW_TO_WINDOW |
- PFD_DOUBLEBUFFER, /* support double-buffering */
- PFD_TYPE_RGBA, /* color type */
- 32, /* prefered color depth */
- 0, 0, 0, 0, 0, 0, /* color bits (ignored) */
- 0, /* no alpha buffer */
- 0, /* alpha bits (ignored) */
- 0, /* no accumulation buffer */
- 0, 0, 0, 0, /* accum bits (ignored) */
- 16, /* depth buffer */
- 0, /* no stencil buffer */
- 0, /* no auxiliary buffers */
- PFD_MAIN_PLANE, /* main layer */
- 0, /* reserved */
- 0, 0, 0, /* no layer, visible, damage masks */
- };
-
- int pixelFormat = ChoosePixelFormat(hDC, &pfd);
-
+ sizeof(PIXELFORMATDESCRIPTOR), // size
+ 1, // version
+ PFD_SUPPORT_OPENGL |
+ PFD_DRAW_TO_WINDOW |
+ PFD_DOUBLEBUFFER, // support double-buffering
+ PFD_TYPE_RGBA, // color type
+ 32, // prefered color depth
+ 0, 0, 0, 0, 0, 0, // color bits (ignored)
+ 0, // no alpha buffer
+ 0, // alpha bits (ignored)
+ 0, // no accumulation buffer
+ 0, 0, 0, 0, // accum bits (ignored)
+ 16, // depth buffer
+ 0, // no stencil buffer
+ 0, // no auxiliary buffers
+ PFD_MAIN_PLANE, // main layer
+ 0, // reserved
+ 0, 0, 0, // no layer, visible, damage masks
+ };
+
+ const int pixelFormat = ChoosePixelFormat(m_hdc, &pfd);
if (pixelFormat == 0)
{
- strcpy(m_error, "ChoosePixelFormat failed.");
- return 1;
+ get_last_error_string();
+ return false;
}
- if (SetPixelFormat(hDC, pixelFormat, &pfd) != TRUE)
+ if (SetPixelFormat(m_hdc, pixelFormat, &pfd) != TRUE)
{
- strcpy(m_error, "SetPixelFormat failed.");
- return 1;
+ get_last_error_string();
+ return false;
}
- return 0;
+
+ return true;
}
bool WGLExtensionSupported(const char *extension_name)
{
- if (pfn_wglGetExtensionsStringEXT == nullptr)
+ if (!pfn_wglGetExtensionsStringEXT)
return false;
- // printf("%s\n", pfn_wglGetExtensionsStringEXT());
+ return strstr(pfn_wglGetExtensionsStringEXT(), extension_name) != nullptr;
+ }
- if (strstr(pfn_wglGetExtensionsStringEXT(), extension_name) != nullptr)
- return true;
- else
- return false;
+ void get_last_error_string()
+ {
+ LPTSTR buffer = nullptr;
+ const auto result = FormatMessage(
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+ nullptr,
+ GetLastError(),
+ 0,
+ LPTSTR(&buffer),
+ 0,
+ nullptr);
+ if (!result || !buffer)
+ {
+ m_error.clear();
+ return;
+ }
+ try { m_error = osd::text::from_tstring(buffer); }
+ catch (...) { m_error.clear(); }
+ LocalFree(buffer);
}
HGLRC m_context;
- HWND m_window;
+ HWND const m_window;
HDC m_hdc;
- char m_error[256];
+ std::string m_error;
osd::dynamic_module::ptr opengl32_dll;
wglGetProcAddress_fn pfn_wglGetProcAddress;
@@ -181,4 +210,4 @@ private:
wglGetSwapIntervalEXT_fn pfn_wglGetSwapIntervalEXT;
};
-#endif // __WIN_GL_CONTEXT__
+#endif // MAME_RENDER_WINGLCONTEXT_H