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.cpp20
-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.cpp88
-rw-r--r--src/osd/modules/render/bgfx/chain.h27
-rw-r--r--src/osd/modules/render/bgfx/chainentry.cpp126
-rw-r--r--src/osd/modules/render/bgfx/chainentry.h27
-rw-r--r--src/osd/modules/render/bgfx/chainentryreader.cpp147
-rw-r--r--src/osd/modules/render/bgfx/chainentryreader.h12
-rw-r--r--src/osd/modules/render/bgfx/chainmanager.cpp647
-rw-r--r--src/osd/modules/render/bgfx/chainmanager.h116
-rw-r--r--src/osd/modules/render/bgfx/chainreader.cpp62
-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.cpp46
-rw-r--r--src/osd/modules/render/bgfx/effect.h22
-rw-r--r--src/osd/modules/render/bgfx/effectmanager.cpp129
-rw-r--r--src/osd/modules/render/bgfx/effectmanager.h29
-rw-r--r--src/osd/modules/render/bgfx/effectreader.cpp166
-rw-r--r--src/osd/modules/render/bgfx/effectreader.h25
-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.cpp87
-rw-r--r--src/osd/modules/render/bgfx/inputpair.h6
-rw-r--r--src/osd/modules/render/bgfx/parameter.h15
-rw-r--r--src/osd/modules/render/bgfx/paramreader.cpp34
-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.cpp90
-rw-r--r--src/osd/modules/render/bgfx/shadermanager.h29
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/blurs/fs_smart-blur.sc36
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/blurs/vs_smart-blur.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/crt-geom_common.sc203
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom-deluxe.sc202
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom.sc257
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_gaussx.sc37
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_gaussy.sc37
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_lowpass.sc37
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_mipmap8.sc148
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_phosphor_apply.sc29
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_phosphor_update.sc27
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/varying.def.sc5
-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.sc17
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_gaussy.sc17
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_lowpass.sc53
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_mipmap8.sc16
-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.sc8
-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.sc30
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/eagle/vs_eagle.sc8
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_chroma.sc9
-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.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_ntsc_decode.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_ntsc_encode.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.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/hqx/fs_hq3x.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/hqx/fs_hq4x.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/hqx/vs_hq2x.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/hqx/vs_hq3x.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/hqx/vs_hq4x.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/lcd-grid/fs_lcd-grid.sc106
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/lcd-grid/fs_persistence.sc16
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/lcd-grid/varying.def.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/lcd-grid/vs_lcd-grid.sc19
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/lcd-grid/vs_persistence.sc19
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/misc/fs_blit_bcg.sc24
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/misc/fs_blit_palette16.sc37
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/misc/fs_blit_rgb32.sc14
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/misc/fs_blit_yuy16.sc38
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/misc/fs_bob-and-ghost-deinterlace.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/misc/fs_deposterize-pass0.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/misc/fs_deposterize-pass1.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/misc/fs_lut.sc13
-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.sc8
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/misc/vs_deposterize-pass1.sc8
-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/fs_gaussian.sc2
-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/fs_gaussian.sc2
-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/fs_gaussian.sc2
-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/fs_gaussian.sc2
-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/fs_dilation-horizontal-fast.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/warp/vs_dilation-horizontal-fast.sc14
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv1-noblend.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv2-3d.sc10
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv2-fast.sc10
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv2-noblend.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv2.sc10
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv3-noblend.sc10
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv3.sc8
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_custom-jinc2-sharper.sc20
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-2xbr-3d-pass0.sc20
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-2xbr-3d-pass1.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-2xbr-3d-pass2.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass0.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass1.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass1f.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass2.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass3.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass3f.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-fast-pass0.sc8
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-fast-pass1.sc8
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-fast-pass2.sc8
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-pass0.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-pass1.sc8
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-pass2.sc8
-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.sc8
-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.sc9
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-fast-pass1.sc9
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-fast-pass2.sc9
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-pass0.sc8
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-pass1.sc9
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-pass2.sc8
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/vs_super-xbr-pass3.sc8
-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.sc6
-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.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/vs_xbr-lv3.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-sharp.sc8
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v2-gamma.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v2.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v4-gamma.sc8
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v4.sc8
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v4b.sc8
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v5-gamma.sc8
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid.sc10
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-sharp.sc8
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v2-gamma.sc8
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v2.sc8
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v4-gamma.sc8
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v4.sc8
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v4b.sc8
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid-v5-gamma.sc8
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/vs_2xbr-hybrid.sc8
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-a-pass0.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-accuracy-pass0.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-accuracy-pass1.sc12
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-b-pass0.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-c-pass0.sc8
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-d-pass0.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-noblend-pass1.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-pass1.sc10
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-a-pass0.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-accuracy-pass0.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-accuracy-pass1.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-b-pass0.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-c-pass0.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-d-pass0.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-noblend-pass1.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/vs_xbr-lv2-pass1.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv3-multipass/fs_xbr-lv3-pass0.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv3-multipass/fs_xbr-lv3-pass1.sc8
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv3-multipass/vs_xbr-lv3-pass0.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv3-multipass/vs_xbr-lv3-pass1.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/fs_xbr-mlv4-pass1.sc8
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/fs_xbr-mlv4-pass2.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/fs_xbr-mlv4-pass3.sc4
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/fs_xbr-mlv4-pass4.sc10
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/vs_xbr-mlv4-pass1.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/vs_xbr-mlv4-pass2.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/vs_xbr-mlv4-pass3.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/vs_xbr-mlv4-pass4.sc6
-rw-r--r--src/osd/modules/render/bgfx/shaders/fs_screen.sc2
-rw-r--r--src/osd/modules/render/bgfx/shaders/makefile27
-rw-r--r--src/osd/modules/render/bgfx/shaders/shader.mk68
-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.cpp49
-rw-r--r--src/osd/modules/render/bgfx/slider.h25
-rw-r--r--src/osd/modules/render/bgfx/sliderreader.cpp80
-rw-r--r--src/osd/modules/render/bgfx/sliderreader.h16
-rw-r--r--src/osd/modules/render/bgfx/slideruniform.cpp10
-rw-r--r--src/osd/modules/render/bgfx/slideruniform.h10
-rw-r--r--src/osd/modules/render/bgfx/slideruniformreader.cpp17
-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.h32
-rw-r--r--src/osd/modules/render/bgfx/suppressor.cpp9
-rw-r--r--src/osd/modules/render/bgfx/suppressor.h10
-rw-r--r--src/osd/modules/render/bgfx/suppressorreader.cpp25
-rw-r--r--src/osd/modules/render/bgfx/suppressorreader.h12
-rw-r--r--src/osd/modules/render/bgfx/target.cpp24
-rw-r--r--src/osd/modules/render/bgfx/target.h15
-rw-r--r--src/osd/modules/render/bgfx/targetmanager.cpp138
-rw-r--r--src/osd/modules/render/bgfx/targetmanager.h37
-rw-r--r--src/osd/modules/render/bgfx/targetreader.cpp66
-rw-r--r--src/osd/modules/render/bgfx/targetreader.h14
-rw-r--r--src/osd/modules/render/bgfx/texture.cpp26
-rw-r--r--src/osd/modules/render/bgfx/texture.h18
-rw-r--r--src/osd/modules/render/bgfx/texturehandleprovider.h14
-rw-r--r--src/osd/modules/render/bgfx/texturemanager.cpp170
-rw-r--r--src/osd/modules/render/bgfx/texturemanager.h40
-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.cpp24
-rw-r--r--src/osd/modules/render/bgfx/uniform.h14
-rw-r--r--src/osd/modules/render/bgfx/uniformreader.cpp34
-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/vertex.h2
-rw-r--r--src/osd/modules/render/bgfx/view.cpp19
-rw-r--r--src/osd/modules/render/bgfx/view.h6
-rw-r--r--src/osd/modules/render/bgfx/windowparameter.h18
-rw-r--r--src/osd/modules/render/bgfx/writereader.h8
-rw-r--r--src/osd/modules/render/bgfxutil.cpp118
-rw-r--r--src/osd/modules/render/bgfxutil.h8
-rw-r--r--src/osd/modules/render/binpacker.cpp9
-rw-r--r--src/osd/modules/render/binpacker.h38
-rw-r--r--src/osd/modules/render/blit13.ipp (renamed from src/osd/modules/render/blit13.h)20
-rw-r--r--src/osd/modules/render/copyutil.h119
-rw-r--r--src/osd/modules/render/d3d/d3dcomm.h108
-rw-r--r--src/osd/modules/render/d3d/d3dhlsl.cpp1054
-rw-r--r--src/osd/modules/render/d3d/d3dhlsl.h263
-rw-r--r--src/osd/modules/render/draw13.cpp755
-rw-r--r--src/osd/modules/render/draw13.h213
-rw-r--r--src/osd/modules/render/drawbgfx.cpp1147
-rw-r--r--src/osd/modules/render/drawbgfx.h115
-rw-r--r--src/osd/modules/render/drawd3d.cpp1087
-rw-r--r--src/osd/modules/render/drawd3d.h67
-rw-r--r--src/osd/modules/render/drawgdi.cpp131
-rw-r--r--src/osd/modules/render/drawgdi.h55
-rw-r--r--src/osd/modules/render/drawnone.cpp88
-rw-r--r--src/osd/modules/render/drawnone.h33
-rw-r--r--src/osd/modules/render/drawogl.cpp1200
-rw-r--r--src/osd/modules/render/drawogl.h242
-rw-r--r--src/osd/modules/render/drawsdl.cpp370
-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
281 files changed, 8037 insertions, 5493 deletions
diff --git a/src/osd/modules/render/aviwrite.cpp b/src/osd/modules/render/aviwrite.cpp
index b1a4a013af4..e758d467e37 100644
--- a/src/osd/modules/render/aviwrite.cpp
+++ b/src/osd/modules/render/aviwrite.cpp
@@ -10,6 +10,7 @@
#include "aviwrite.h"
#include "modules/lib/osdobj_common.h"
+#include "fileio.h"
#include "screen.h"
@@ -31,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)
{
@@ -47,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();
@@ -56,7 +57,7 @@ void avi_write::begin_avi_recording(const char *name)
m_frame = 0;
m_next_frame_time = m_machine.time();
- const screen_device *primary_screen = screen_device_iterator(m_machine.root_device()).first();
+ const screen_device *primary_screen = screen_device_enumerator(m_machine.root_device()).first();
// build up information about this new movie
avi_file::movie_info info;
info.video_format = 0;
@@ -71,7 +72,7 @@ void avi_write::begin_avi_recording(const char *name)
info.audio_timescale = m_machine.sample_rate();
info.audio_sampletime = 1;
info.audio_numsamples = 0;
- info.audio_channels = 2;
+ info.audio_channels = m_machine.sound().outputs_count();
info.audio_samplebits = 16;
info.audio_samplerate = m_machine.sample_rate();
@@ -80,12 +81,12 @@ 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 osd_file::error 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);
// if we succeeded, make a copy of the name and create the real file over top
- if (filerr == osd_file::error::NONE)
+ if (!filerr)
{
const std::string fullpath = tempfile.fullpath();
tempfile.close();
@@ -141,9 +142,10 @@ void avi_write::audio_frame(const int16_t *buffer, int samples_this_frame)
if (m_output_file != nullptr)
{
// write the next frame
- avi_file::error avierr = m_output_file->append_sound_samples(0, buffer + 0, samples_this_frame, 1);
- if (avierr == avi_file::error::NONE)
- avierr = m_output_file->append_sound_samples(1, buffer + 1, samples_this_frame, 1);
+ int channels = m_machine.sound().outputs_count();
+ avi_file::error avierr = avi_file::error::NONE;
+ for (int channel = 0; channel != channels && avierr == avi_file::error::NONE; channel ++)
+ avierr = m_output_file->append_sound_samples(channel, buffer + channel, samples_this_frame, channels-1);
if (avierr != avi_file::error::NONE)
{
osd_printf_error("Error while logging AVI audio frame: %s\n", avi_file::error_string(avierr));
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 c7691973854..8d5adb0ec25 100644
--- a/src/osd/modules/render/bgfx/chain.cpp
+++ b/src/osd/modules/render/bgfx/chain.cpp
@@ -6,33 +6,48 @@
//
//============================================================
+#include "chain.h"
+
#include "emu.h"
+#include "render.h"
+#include "rendlay.h"
+#include "screen.h"
#include <bx/timer.h>
#include "slider.h"
#include "parameter.h"
#include "entryuniform.h"
+#include "valueuniform.h"
#include "texturemanager.h"
#include "targetmanager.h"
+#include "chainmanager.h"
#include "target.h"
#include "vertex.h"
-#include "screen.h"
+#include "clear.h"
#include "modules/osdwindow.h"
-#include "chain.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)
{
for (bgfx_target* target : m_target_list)
{
@@ -72,14 +87,14 @@ void bgfx_chain::repopulate_targets()
}
}
-void bgfx_chain::process(render_primitive* 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_iterator screen_iterator(window.machine().root_device());
+ screen_device_enumerator screen_iterator(window.machine().root_device());
screen_device* screen_device = screen_iterator.byindex(screen);
- uint16_t screen_count(window.target()->current_view()->screens().count());
- uint16_t screen_width(floorf(prim->get_quad_width() + 0.5f));
- uint16_t screen_height(floorf(prim->get_quad_height() + 0.5f));
+ uint16_t screen_count(window.target()->current_view().visible_screen_count());
+ uint16_t screen_width = prim.m_quad_width;
+ uint16_t screen_height = prim.m_quad_height;
uint32_t rotation_type =
(window.target()->orientation() & ROT90) == ROT90 ? 1 :
(window.target()->orientation() & ROT180) == ROT180 ? 2 :
@@ -102,11 +117,12 @@ void bgfx_chain::process(render_primitive* prim, int view, int screen, texture_m
}
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++;
}
}
@@ -115,13 +131,13 @@ void bgfx_chain::process(render_primitive* prim, int view, int screen, texture_m
static int64_t last = m_current_time;
const int64_t frameTime = m_current_time - last;
last = m_current_time;
- const double freq = double(bx::getHPFrequency());
+ const auto freq = double(bx::getHPFrequency());
const double toMs = 1000.0 / freq;
const double frameTimeInSeconds = (double)frameTime / 1000000.0;
for (bgfx_parameter* param : m_params)
{
- param->tick(frameTimeInSeconds* toMs);
+ param->tick(frameTimeInSeconds * toMs);
}
}
@@ -138,3 +154,35 @@ uint32_t bgfx_chain::applicable_passes()
return applicable_passes;
}
+
+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;
+
+ std::vector<bgfx_input_pair*> inputs;
+ std::vector<std::string> available_textures;
+ inputs.push_back(new bgfx_input_pair(0, "s_tex", source, available_textures, "", chains, m_screen_index));
+ inputs.push_back(new bgfx_input_pair(1, "s_pal", "palette", available_textures, "", chains, m_screen_index));
+
+ std::vector<bgfx_entry_uniform*> uniforms;
+ float value = 1.0f;
+ float values[4] = { 1.0f, 1.0f, 0.0f, 0.0f };
+ uniforms.push_back(new bgfx_value_uniform(new bgfx_uniform("s_tex", bgfx::UniformType::Sampler), &value, 1));
+ uniforms.push_back(new bgfx_value_uniform(new bgfx_uniform("s_pal", bgfx::UniformType::Sampler), &value, 1));
+ uniforms.push_back(new bgfx_value_uniform(new bgfx_uniform("u_tex_size0", bgfx::UniformType::Vec4), values, 4));
+ 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", 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, 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 157f92173cf..5d84bb1ed0c 100644
--- a/src/osd/modules/render/bgfx/chain.h
+++ b/src/osd/modules/render/bgfx/chain.h
@@ -6,18 +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 render_primitive;
class bgfx_slider;
class bgfx_parameter;
class texture_manager;
@@ -28,17 +27,25 @@ 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(render_primitive* 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();
- bool transform() { return m_transform; }
+ bool transform() const { return m_transform; }
+ bool has_converter() const { return m_has_converter; }
+ bool has_adjuster() const { return m_has_adjuster; }
+
+ // 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, const bool apply_tint, std::string name, std::string source, chain_manager &chains);
private:
std::string m_name;
@@ -53,6 +60,8 @@ private:
std::map<std::string, bgfx_target*> m_target_map;
int64_t m_current_time;
uint32_t m_screen_index;
+ bool m_has_converter;
+ 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 d48e279e9d2..c3f3ee3a8e3 100644
--- a/src/osd/modules/render/bgfx/chainentry.cpp
+++ b/src/osd/modules/render/bgfx/chainentry.cpp
@@ -9,10 +9,11 @@
//
//============================================================
-#include "emu.h"
+#include "chainmanager.h"
#include <bgfx/bgfx.h>
#include <bx/math.h>
+#include <cmath>
#include "chainentry.h"
@@ -25,10 +26,12 @@
#include "vertex.h"
#include "suppressor.h"
+#include "emucore.h"
#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)
+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)
@@ -37,6 +40,7 @@ bgfx_chain_entry::bgfx_chain_entry(std::string name, bgfx_effect* effect, clear_
, m_uniforms(uniforms)
, m_targets(targets)
, m_output(output)
+ , m_apply_tint(apply_tint)
{
}
@@ -52,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, render_primitive* 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(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;
}
@@ -67,11 +77,22 @@ void bgfx_chain_entry::submit(int view, render_primitive* prim, texture_manager&
input->bind(m_effect, screen);
}
+ uint32_t tint = 0xffffffff;
+ if (m_apply_tint)
+ {
+ 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, &buffer);
- bgfx::setVertexBuffer(0,&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)
{
@@ -81,7 +102,7 @@ void bgfx_chain_entry::submit(int view, render_primitive* prim, texture_manager&
}
}
- m_effect->submit(view, blend);
+ m_effect->submit(view);
if (m_targets.target(screen, m_output) != nullptr)
{
@@ -89,6 +110,43 @@ void bgfx_chain_entry::submit(int view, render_primitive* prim, texture_manager&
}
}
+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;
@@ -145,13 +203,12 @@ void bgfx_chain_entry::setup_screencount_uniforms(uint16_t screen_count)
}
}
-void bgfx_chain_entry::setup_sourcesize_uniform(render_primitive* prim) const
+void bgfx_chain_entry::setup_sourcesize_uniform(chain_manager::screen_prim &prim) const
{
bgfx_uniform* source_dims = m_effect->uniform("u_source_dims");
if (source_dims != nullptr)
{
- float values[2] = { float(prim->texture.width), float(prim->texture.height) };
- source_dims->set(values, sizeof(float) * 2);
+ source_dims->set(&prim.m_tex_width, sizeof(float) * 2);
}
}
@@ -203,12 +260,12 @@ void bgfx_chain_entry::setup_swapxy_uniform(bool swap_xy) const
}
}
-void bgfx_chain_entry::setup_quaddims_uniform(render_primitive* prim) const
+void bgfx_chain_entry::setup_quaddims_uniform(chain_manager::screen_prim &prim) const
{
bgfx_uniform* quad_dims_uniform = m_effect->uniform("u_quad_dims");
if (quad_dims_uniform != nullptr)
{
- float values[2] = { float(floor((prim->bounds.x1 - prim->bounds.x0) + 0.5f)), float(floor((prim->bounds.y1 - prim->bounds.y0) + 0.5f)) };
+ float values[2] = { float(prim.m_quad_width), float(prim.m_quad_height) };
quad_dims_uniform->set(values, sizeof(float) * 2);
}
}
@@ -223,22 +280,8 @@ void bgfx_chain_entry::setup_screenindex_uniform(int32_t screen) const
}
}
-void bgfx_chain_entry::setup_auto_uniforms(render_primitive* 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(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;
@@ -257,18 +300,23 @@ bool bgfx_chain_entry::setup_view(int view, uint16_t screen_width, uint16_t scre
bgfx::setViewFrameBuffer(view, handle);
bgfx::setViewRect(view, 0, 0, width, height);
+ 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();
+
float projMat[16];
- bx::mtxOrtho(projMat, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f, 0.0f, caps->homogeneousDepth);
+ bx::mtxOrtho(projMat, 0.0f, right_ratio, 1.0f, 0.0f, 0.0f, 100.0f, 0.0f, caps->homogeneousDepth);
bgfx::setViewTransform(view, nullptr, projMat);
m_clear->bind(view);
return true;
}
-void bgfx_chain_entry::put_screen_buffer(render_primitive* prim, bgfx::TransientVertexBuffer* buffer) const
+void bgfx_chain_entry::put_screen_buffer(uint16_t screen_width, uint16_t screen_height, uint32_t screen_tint, bgfx::TransientVertexBuffer* buffer) const
{
if (6 == bgfx::getAvailTransientVertexBuffer(6, ScreenVertex::ms_decl))
{
@@ -279,7 +327,7 @@ void bgfx_chain_entry::put_screen_buffer(render_primitive* prim, bgfx::Transient
return;
}
- ScreenVertex* vertex = reinterpret_cast<ScreenVertex*>(buffer->data);
+ auto* vertex = reinterpret_cast<ScreenVertex*>(buffer->data);
float x[4] = { 0, 1, 0, 1 };
float y[4] = { 0, 0, 1, 1 };
@@ -296,42 +344,42 @@ void bgfx_chain_entry::put_screen_buffer(render_primitive* prim, bgfx::Transient
vertex[0].m_x = x[0];
vertex[0].m_y = y[0];
vertex[0].m_z = 0;
- vertex[0].m_rgba = 0xffffffff;
+ vertex[0].m_rgba = screen_tint;
vertex[0].m_u = u[0];
vertex[0].m_v = v[0];
vertex[1].m_x = x[1];
vertex[1].m_y = y[1];
vertex[1].m_z = 0;
- vertex[1].m_rgba = 0xffffffff;
+ vertex[1].m_rgba = screen_tint;
vertex[1].m_u = u[1];
vertex[1].m_v = v[1];
vertex[2].m_x = x[3];
vertex[2].m_y = y[3];
vertex[2].m_z = 0;
- vertex[2].m_rgba = 0xffffffff;
+ vertex[2].m_rgba = screen_tint;
vertex[2].m_u = u[3];
vertex[2].m_v = v[3];
vertex[3].m_x = x[3];
vertex[3].m_y = y[3];
vertex[3].m_z = 0;
- vertex[3].m_rgba = 0xffffffff;
+ vertex[3].m_rgba = screen_tint;
vertex[3].m_u = u[3];
vertex[3].m_v = v[3];
vertex[4].m_x = x[2];
vertex[4].m_y = y[2];
vertex[4].m_z = 0;
- vertex[4].m_rgba = 0xffffffff;
+ vertex[4].m_rgba = screen_tint;
vertex[4].m_u = u[2];
vertex[4].m_v = v[2];
vertex[5].m_x = x[0];
vertex[5].m_y = y[0];
vertex[5].m_z = 0;
- vertex[5].m_rgba = 0xffffffff;
+ vertex[5].m_rgba = screen_tint;
vertex[5].m_u = u[0];
vertex[5].m_v = v[0];
}
diff --git a/src/osd/modules/render/bgfx/chainentry.h b/src/osd/modules/render/bgfx/chainentry.h
index 64130c5c93e..a7504187879 100644
--- a/src/osd/modules/render/bgfx/chainentry.h
+++ b/src/osd/modules/render/bgfx/chainentry.h
@@ -11,8 +11,8 @@
#pragma once
-#ifndef __DRAWBGFX_CHAIN_ENTRY__
-#define __DRAWBGFX_CHAIN_ENTRY__
+#ifndef DRAWBGFX_CHAIN_ENTRY
+#define DRAWBGFX_CHAIN_ENTRY
#include <bgfx/bgfx.h>
@@ -21,8 +21,8 @@
#include "inputpair.h"
#include "targetmanager.h"
+#include "chainmanager.h"
-class render_primitive;
class bgfx_effect;
class bgfx_target;
class bgfx_entry_uniform;
@@ -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);
+ 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, render_primitive* 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,21 +47,25 @@ public:
bool skip();
private:
- void setup_auto_uniforms(render_primitive* 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);
void setup_screencount_uniforms(uint16_t screen_count);
- void setup_sourcesize_uniform(render_primitive* prim) const;
+ void setup_sourcesize_uniform(chain_manager::screen_prim &prim) const;
void setup_targetsize_uniform(int32_t screen) const;
void setup_targetscale_uniform(int32_t screen) const;
void setup_rotationtype_uniform(uint32_t rotation_type) const;
void setup_swapxy_uniform(bool swap_xy) const;
- void setup_quaddims_uniform(render_primitive* prim) const;
+ void setup_quaddims_uniform(chain_manager::screen_prim &prim) const;
void setup_screenindex_uniform(int32_t screen) const;
- bool setup_view(int view, uint16_t screen_width, uint16_t screen_height, int32_t screen) const;
- void put_screen_buffer(render_primitive* prim, bgfx::TransientVertexBuffer* buffer) 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;
bgfx_effect* m_effect;
@@ -69,6 +75,7 @@ private:
std::vector<bgfx_entry_uniform*> m_uniforms;
target_manager& m_targets;
std::string m_output;
+ bool m_apply_tint;
};
#endif // __DRAWBGFX_CHAIN_ENTRY__
diff --git a/src/osd/modules/render/bgfx/chainentryreader.cpp b/src/osd/modules/render/bgfx/chainentryreader.cpp
index bff221ec40c..ce58816e827 100644
--- a/src/osd/modules/render/bgfx/chainentryreader.cpp
+++ b/src/osd/modules/render/bgfx/chainentryreader.cpp
@@ -6,16 +6,15 @@
//
//============================================================
-#include <string>
+#include "chainentryreader.h"
-#include "emu.h"
+#include "emucore.h"
+#include "fileio.h"
#include "rendutil.h"
#include <modules/render/copyutil.h>
#include <modules/lib/osdobj_common.h>
-#include "chainentryreader.h"
-
#include "texturemanager.h"
#include "targetmanager.h"
#include "effectmanager.h"
@@ -30,15 +29,21 @@
#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))
{
- printf("Failed validation\n");
+ osd_printf_error("Chain entry failed validation.\n");
return nullptr;
}
- bgfx_effect* effect = chains.effects().effect(value["effect"].GetString());
+ bgfx_effect* effect = chains.effects().get_or_load_effect(chains.options(), value["effect"].GetString());
if (effect == nullptr)
{
return nullptr;
@@ -53,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", "");
@@ -84,7 +89,7 @@ bgfx_chain_entry* chain_entry_reader::read_from_value(const Value& value, std::s
texture_name = chains.options().value(option.c_str());
}
- if (texture_name != "" && texture_name != "screen")
+ if (texture_name != "" && texture_name != "screen" && texture_name != "palette")
{
if (selection == "")
{
@@ -109,59 +114,48 @@ bgfx_chain_entry* chain_entry_reader::read_from_value(const Value& value, std::s
}
// get directory of file
- std::string directory_path = std::string(chains.options().art_path());
- std::string file_directory = "";
const size_t last_slash = texture_name.rfind('/');
- if (last_slash != std::string::npos)
- {
- file_directory = texture_name.substr(0, last_slash);
-
- directory_path += "/" + file_directory;
- }
-
- osd::directory::ptr directory = osd::directory::open(directory_path);
- if (directory)
+ const std::string file_directory = last_slash != std::string::npos ? texture_name.substr(0, last_slash) : std::string();
+ file_enumerator directory_path(chains.options().art_path());
+ while (const osd::directory::entry *entry = directory_path.next(file_directory.empty() ? nullptr : file_directory.c_str()))
{
- for (const osd::directory::entry *entry = directory->read(); entry != nullptr; entry = directory->read())
+ if (entry->type == osd::directory::entry::entry_type::FILE)
{
- if (entry->type == osd::directory::entry::entry_type::FILE)
+ std::string file(entry->name);
+ std::string extension(".png");
+
+ // split into file name and extension
+ std::string file_name;
+ std::string file_extension;
+ const size_t last_dot = file.rfind('.');
+ if (last_dot != std::string::npos)
{
- std::string file(entry->name);
- std::string extension(".png");
-
- // split into file name and extension
- std::string file_name;
- std::string file_extension;
- const size_t last_dot = file.rfind('.');
- if (last_dot != std::string::npos)
- {
- file_name = file.substr(0, last_dot);
- file_extension = file.substr(last_dot, file.length() - last_dot);
- }
+ file_name = file.substr(0, last_dot);
+ file_extension = file.substr(last_dot, file.length() - last_dot);
+ }
- std::string file_path;
- if (file_directory == "")
- {
- file_path = file;
- }
- else
- {
- file_path = file_directory + "/" + file;
- }
+ std::string file_path;
+ if (file_directory == "")
+ {
+ file_path = file;
+ }
+ else
+ {
+ file_path = file_directory + PATH_SEPARATOR + file;
+ }
- // check for .png extension
- if (file_extension == extension)
+ // check for .png extension
+ if (file_extension == extension && std::find(texture_names.begin(), texture_names.end(), file_path) == texture_names.end())
+ {
+ // create textures for all files containd in the path of the specified file name
+ uint32_t flags = bilinear ? 0u : (BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT);
+ flags |= clamp ? (BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP | BGFX_SAMPLER_W_CLAMP) : 0u;
+ bgfx_texture* texture = chains.textures().create_png_texture(chains.options().art_path(), file_path, file_path, flags, screen_index);
+ if (texture == nullptr)
{
- // create textures for all files containd in the path of the specified file name
- uint32_t flags = bilinear ? 0u : (BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT);
- flags |= clamp ? (BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP | BGFX_SAMPLER_W_CLAMP) : 0u;
- bgfx_texture* texture = chains.textures().create_png_texture(chains.options().art_path(), file_path, file_path, flags, screen_index);
- if (texture == nullptr)
- {
- return nullptr;
- }
- texture_names.push_back(file_path);
+ return nullptr;
}
+ texture_names.push_back(file_path);
}
}
}
@@ -178,11 +172,15 @@ bgfx_chain_entry* chain_entry_reader::read_from_value(const Value& value, std::s
}
std::string sampler = input["sampler"].GetString();
- bgfx_input_pair* input_pair = new bgfx_input_pair(i, sampler, texture_name, texture_names, selection, chains, screen_index);
+ auto* input_pair = new bgfx_input_pair(i, sampler, texture_name, texture_names, selection, chains, screen_index);
inputs.push_back(input_pair);
}
}
+ // Parse whether or not to apply screen tint in this pass
+ bool applytint = get_bool(value, "applytint", false);
+
+ // Parse uniforms
std::vector<bgfx_entry_uniform*> uniforms;
if (value.HasMember("uniforms"))
{
@@ -228,19 +226,20 @@ bgfx_chain_entry* chain_entry_reader::read_from_value(const Value& value, std::s
}
std::string output = value["output"].GetString();
- return new bgfx_chain_entry(name, effect, clear, suppressors, inputs, uniforms, chains.targets(), output);
+ 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("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 62df9be9613..a15f2f1e584 100644
--- a/src/osd/modules/render/bgfx/chainmanager.cpp
+++ b/src/osd/modules/render/bgfx/chainmanager.cpp
@@ -9,13 +9,16 @@
//
//============================================================
+#include "chainmanager.h"
+
#include <bx/readerwriter.h>
#include <bx/file.h>
-#include "emu.h"
+#include "emucore.h"
+#include "render.h"
#include "../frontend/mame/ui/slider.h"
-#include "osdcore.h"
+#include "modules/lib/osdobj_common.h"
#include "modules/osdwindow.h"
#include <rapidjson/document.h>
@@ -23,32 +26,67 @@
#include "bgfxutil.h"
-#include "chainmanager.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"
+
+#include <algorithm>
+#include <locale>
+
+
using namespace rapidjson;
-const uint32_t chain_manager::CHAIN_NONE = 0;
+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 = 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();
parse_chain_selections(options.bgfx_screen_chains());
+ init_texture_converters();
}
chain_manager::~chain_manager()
@@ -56,14 +94,65 @@ chain_manager::~chain_manager()
destroy_chains();
}
+void chain_manager::init_texture_converters()
+{
+ m_converters.push_back(nullptr);
+ m_converters.push_back(m_effects.get_or_load_effect(m_options, "misc/texconv_palette16"));
+ m_converters.push_back(m_effects.get_or_load_effect(m_options, "misc/texconv_rgb32"));
+ m_converters.push_back(nullptr);
+ m_converters.push_back(m_effects.get_or_load_effect(m_options, "misc/texconv_yuy16"));
+ 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", ""));
-
- std::string chains_path;
- osd_subst_env(chains_path, 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();
}
@@ -73,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)
@@ -82,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;
}
}
@@ -91,107 +179,109 @@ 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(path, 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()))
{
- printf("Unable to open chain file %s, falling back to no post processing\n", path.c_str());
+ osd_printf_warning("Unable to open chain file %s, falling back to no post processing\n", path);
return nullptr;
}
- int32_t size(bx::getSize(&reader));
+ const int32_t size(bx::getSize(&reader));
+
+ 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;
+ }
- char* data = new char[size + 1];
- bx::read(&reader, reinterpret_cast<void*>(data), size);
+ 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()));
- printf("Unable to parse chain %s. Errors returned:\n", path.c_str());
- printf("%s\n", error.c_str());
+ 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)
{
- printf("Unable to load chain %s, falling back to no post processing\n", path.c_str());
+ osd_printf_warning("Unable to load chain %s, falling back to no post processing\n", path);
return nullptr;
}
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);
}
@@ -201,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())
@@ -219,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++;
}
}
@@ -253,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();
}
}
}
@@ -288,19 +387,9 @@ bgfx_chain* chain_manager::screen_chain(uint32_t screen)
}
}
-void chain_manager::process_screen_quad(uint32_t view, uint32_t screen, render_primitive* prim, osd_window &window)
+void chain_manager::process_screen_quad(uint32_t view, uint32_t screen, screen_prim &prim, osd_window& window)
{
- uint16_t tex_width(prim->texture.width);
- uint16_t tex_height(prim->texture.height);
-
- const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(prim->flags & PRIMFLAG_TEXFORMAT_MASK,
- tex_width, tex_height, prim->texture.rowpixels, prim->texture.palette, prim->texture.base);
-
- std::string full_name = "screen" + std::to_string(screen);
- bgfx_texture *texture = new bgfx_texture(full_name, bgfx::TextureFormat::RGBA8, tex_width, tex_height, mem, BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP | BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT);
- m_textures.add_provider(full_name, texture);
-
- const bool any_targets_rebuilt = m_targets.update_target_sizes(screen, tex_width, 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)
@@ -313,24 +402,26 @@ void chain_manager::process_screen_quad(uint32_t view, uint32_t screen, render_p
}
bgfx_chain* chain = screen_chain(screen);
- chain->process(prim, view, screen, m_textures, window, bgfx_util::get_blend_state(PRIMFLAG_GET_BLENDMODE(prim->flags)));
+ chain->process(prim, view, screen, m_textures, window);
view += chain->applicable_passes();
-
- m_textures.add_provider(full_name, nullptr);
- delete texture;
}
-std::vector<render_primitive*> chain_manager::count_screens(render_primitive* prim)
+uint32_t chain_manager::count_screens(render_primitive* prim)
{
- std::vector<render_primitive*> screens;
-
- int screen_count = 0;
+ uint32_t screen_count = 0;
while (prim != nullptr)
{
if (PRIMFLAG_GET_SCREENTEX(prim->flags))
{
+ if (screen_count < m_screen_prims.size())
+ {
+ m_screen_prims[screen_count] = prim;
+ }
+ else
+ {
+ m_screen_prims.push_back(prim);
+ }
screen_count++;
- screens.push_back(prim);
}
prim = prim->next();
}
@@ -338,10 +429,15 @@ std::vector<render_primitive*> chain_manager::count_screens(render_primitive* pr
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);
}
- return screens;
+ if (screen_count < m_screen_prims.size())
+ {
+ m_screen_prims.resize(screen_count);
+ }
+
+ return screen_count;
}
void chain_manager::update_screen_count(uint32_t screen_count)
@@ -355,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
@@ -369,11 +469,20 @@ void chain_manager::update_screen_count(uint32_t screen_count)
}
}
-int32_t chain_manager::slider_changed(running_machine &machine, void *arg, int id, std::string *str, int32_t newval)
+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();
@@ -384,7 +493,7 @@ int32_t chain_manager::slider_changed(running_machine &machine, void *arg, int i
if (str != nullptr)
{
- *str = string_format("%s", m_available_chains[m_current_chain[id]].m_name.c_str());
+ *str = m_available_chains[m_current_chain[id]].m_name;
}
return m_current_chain[id];
@@ -397,42 +506,151 @@ void chain_manager::create_selection_slider(uint32_t screen_index)
return;
}
- std::unique_ptr<slider_state> state = make_unique_clear<slider_state>();
-
- state->minval = 0;
- state->defval = m_current_chain[screen_index];
- state->maxval = m_available_chains.size() - 1;
- state->incval = 1;
+ int32_t minval = 0;
+ int32_t defval = m_current_chain[screen_index];
+ int32_t maxval = m_available_chains.size() - 1;
+ int32_t incval = 1;
using namespace std::placeholders;
- state->update = std::bind(&chain_manager::slider_changed, this, _1, _2, _3, _4, _5);
- state->arg = this;
- state->id = screen_index;
- state->description = "Window " + std::to_string(m_window_index) + ", Screen " + std::to_string(screen_index) + " Effect:";
-
- ui::menu_item item;
- item.text = state->description;
- item.subtext = "";
- item.flags = 0;
- item.ref = state.get();
- item.type = ui::menu_item_type::SLIDER;
- m_selection_sliders.push_back(item);
- m_core_sliders.push_back(std::move(state));
+ 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);
+ m_selection_sliders.emplace_back(item);
+ m_core_sliders.emplace_back(std::move(state));
}
-uint32_t chain_manager::handle_screen_chains(uint32_t view, render_primitive *starting_prim, osd_window& window)
+uint32_t chain_manager::update_screen_textures(uint32_t view, render_primitive *starting_prim, osd_window& window)
{
- std::vector<render_primitive*> screens = count_screens(starting_prim);
+ if (!count_screens(starting_prim))
+ return 0;
- if (screens.size() == 0)
+ for (int screen = 0; screen < m_screen_prims.size(); screen++)
{
- return 0;
+ screen_prim &prim = m_screen_prims[screen];
+ uint16_t tex_width(prim.m_tex_width);
+ uint16_t tex_height(prim.m_tex_height);
+
+ bgfx_texture* texture = screen < m_screen_textures.size() ? m_screen_textures[screen] : nullptr;
+ bgfx_texture* palette = screen < m_screen_palettes.size() ? m_screen_palettes[screen] : nullptr;
+
+ 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;
+ 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.remove_provider(full_name);
+ m_textures.remove_provider(palette_name);
+ texture = nullptr;
+ palette = nullptr;
+ }
+
+ bgfx::TextureFormat::Enum dst_format = bgfx::TextureFormat::BGRA8;
+ uint16_t pitch = prim.m_rowpixels;
+ 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, 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)
+ {
+ 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;
+ 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));
+ 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);
+ 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.emplace_back(nullptr);
+ }
+ m_screen_textures[screen] = texture;
+
+ while (screen >= m_screen_palettes.size())
+ {
+ m_screen_palettes.emplace_back(nullptr);
+ }
+ if (palette)
+ {
+ m_screen_palettes[screen] = palette;
+ }
+ }
+ else
+ {
+ 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));
+ 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);
+ const bgfx::Memory *palmem = bgfx::copy(&m_palette_temp[0], palette_size);
+
+ if (palette)
+ {
+ palette->update(palmem);
+ }
+ else
+ {
+ 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.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())
+ {
+ 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], has_tint, "XXconvert", "source", *this);
+ chain->set_has_converter(true);
+ }
}
+ return m_screen_prims.size();
+}
+
+uint32_t chain_manager::process_screen_chains(uint32_t view, osd_window& window)
+{
// Process each screen as necessary
uint32_t used_views = 0;
uint32_t screen_index = 0;
- for (render_primitive* prim : screens)
+ for (screen_prim &prim : m_screen_prims)
{
if (m_current_chain[screen_index] == CHAIN_NONE || screen_chain(screen_index) == nullptr)
{
@@ -440,14 +658,14 @@ uint32_t chain_manager::handle_screen_chains(uint32_t view, render_primitive *st
continue;
}
- uint16_t screen_width(floorf(prim->get_full_quad_width() + 0.5f));
- uint16_t screen_height(floorf(prim->get_full_quad_height() + 0.5f));
+ uint16_t screen_width = prim.m_screen_width;
+ uint16_t screen_height = prim.m_screen_height;
if (window.swap_xy())
{
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)
@@ -472,12 +690,12 @@ uint32_t chain_manager::handle_screen_chains(uint32_t view, render_primitive *st
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)
@@ -500,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]);
@@ -508,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;
@@ -527,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());
@@ -556,46 +919,38 @@ 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.push_back(slider);
+ 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;
- item.text = core_slider->description;
- item.subtext = "";
- item.flags = 0;
- item.ref = core_slider;
- item.type = ui::menu_item_type::SLIDER;
- m_selection_sliders.push_back(item);
+ ui::menu_item item(ui::menu_item_type::SLIDER, core_slider);
+ item.set_text(core_slider->description);
+ m_selection_sliders.emplace_back(item);
- sliders.push_back(item);
+ sliders.emplace_back(std::move(item));
}
if (chain_sliders.size() > 0)
{
- ui::menu_item item;
- item.text = MENU_SEPARATOR_ITEM;
- item.subtext = "";
- item.flags = 0;
- item.ref = nullptr;
- item.type = ui::menu_item_type::SEPARATOR;
+ ui::menu_item item(ui::menu_item_type::SEPARATOR);
+ item.set_text(MENU_SEPARATOR_ITEM);
- sliders.push_back(item);
+ sliders.emplace_back(std::move(item));
}
}
diff --git a/src/osd/modules/render/bgfx/chainmanager.h b/src/osd/modules/render/bgfx/chainmanager.h
index 4c76a02ee25..0d489d0bd72 100644
--- a/src/osd/modules/render/bgfx/chainmanager.h
+++ b/src/osd/modules/render/bgfx/chainmanager.h
@@ -9,20 +9,23 @@
//
//============================================================
+#ifndef MAME_RENDER_BGFX_CHAINMANAGER_H
+#define MAME_RENDER_BGFX_CHAINMANAGER_H
+
#pragma once
-#ifndef __DRAWBGFX_CHAIN_MANAGER__
-#define __DRAWBGFX_CHAIN_MANAGER__
+#include "effectmanager.h"
+#include "targetmanager.h"
+#include "texturemanager.h"
+
+#include "util/utilfwd.h"
-#include <vector>
#include <map>
#include <string>
+#include <string_view>
+#include <utility>
+#include <vector>
-#include "texturemanager.h"
-#include "targetmanager.h"
-#include "effectmanager.h"
-#include "../frontend/mame/ui/menuitem.h"
-#include "../frontend/mame/ui/sliderchangednotifier.h"
class running_machine;
class osd_window;
@@ -30,33 +33,42 @@ struct slider_state;
class slider_dirty_notifier;
class render_primitive;
+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
{
- }
-
- const std::string m_name;
- const std::string m_path;
-};
-
-class chain_manager : public slider_changed_notifier
-{
-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);
+ public:
+ screen_prim() = default;
+ screen_prim(render_primitive *prim);
+
+ 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;
+ };
+
+ 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 handle_screen_chains(uint32_t view, render_primitive *starting_prim, osd_window& window);
+ uint32_t update_screen_textures(uint32_t view, render_primitive *starting_prim, osd_window& window);
+ uint32_t process_screen_chains(uint32_t view, osd_window& window);
// 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; }
@@ -64,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();
@@ -72,42 +84,76 @@ public:
// Setters
void restore_slider_settings(int32_t id, std::vector<std::vector<float>>& settings);
+ void load_config(util::xml::data_node const &screennode);
+ void save_config(util::xml::data_node &parentnode);
+
private:
+ class chain_desc
+ {
+ public:
+ 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))
+ {
+ }
+
+ std::string m_name;
+ std::string m_path;
+ };
+
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);
- virtual int32_t slider_changed(running_machine &machine, void *arg, int id, std::string *str, int32_t newval) override;
+ 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();
- std::vector<render_primitive*> count_screens(render_primitive* prim);
- void process_screen_quad(uint32_t view, uint32_t screen, render_primitive* prim, osd_window &window);
+ uint32_t count_screens(render_primitive* prim);
+ 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;
std::vector<ui::menu_item> m_selection_sliders;
std::vector<std::unique_ptr<slider_state>> m_core_sliders;
std::vector<int32_t> m_current_chain;
-
- static const uint32_t CHAIN_NONE;
+ std::vector<bgfx_texture*> m_screen_textures;
+ std::vector<bgfx_texture*> m_screen_palettes;
+ std::vector<bgfx_effect*> m_converters;
+ bgfx_effect * m_adjuster;
+ std::vector<screen_prim> m_screen_prims;
+ std::vector<uint8_t> m_palette_temp;
+
+ 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 20e7080dbbe..362baa42c82 100644
--- a/src/osd/modules/render/bgfx/chainreader.cpp
+++ b/src/osd/modules/render/bgfx/chainreader.cpp
@@ -6,25 +6,28 @@
//
//============================================================
-#include <string>
-#include <vector>
-#include <map>
-
-#include "emu.h"
-#include <modules/lib/osdobj_common.h>
-
#include "chainreader.h"
+
#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))
{
@@ -98,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;
@@ -123,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 3cbd714463c..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;
- int32_t 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 fb3d7d933ba..18b43cca9bf 100644
--- a/src/osd/modules/render/bgfx/effect.cpp
+++ b/src/osd/modules/render/bgfx/effect.cpp
@@ -11,52 +11,52 @@
#include "uniform.h"
#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().c_str());
- 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;
}
- 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)
{
- std::map<std::string, bgfx_uniform*>::iterator iter = m_uniforms.find(name);
-
- if (iter != m_uniforms.end())
- {
- return iter->second;
- }
-
- return 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 02ef9fd4f54..07646e6302e 100644
--- a/src/osd/modules/render/bgfx/effect.h
+++ b/src/osd/modules/render/bgfx/effect.h
@@ -6,32 +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);
+ 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 6462ae75f72..e5e5d1698f6 100644
--- a/src/osd/modules/render/bgfx/effectmanager.cpp
+++ b/src/osd/modules/render/bgfx/effectmanager.cpp
@@ -9,86 +9,119 @@
//
//============================================================
+#include "effectmanager.h"
+
+#include "effect.h"
+#include "effectreader.h"
+#include "shadermanager.h"
+
+#include "path.h"
+
+#include "osdfile.h"
+#include "modules/lib/osdobj_common.h"
+
#include <rapidjson/document.h>
#include <rapidjson/error/en.h>
#include <bx/readerwriter.h>
#include <bx/file.h>
-#include "emu.h"
-
#include <bgfx/bgfx.h>
-#include "effectmanager.h"
-#include "effectreader.h"
-#include "effect.h"
+#include <utility>
-using namespace rapidjson;
-effect_manager::~effect_manager()
+static bool prepare_effect_document(const std::string &name, const osd_options &options, rapidjson::Document &document)
{
- for (std::pair<std::string, bgfx_effect*> effect : m_effects)
- {
- delete effect.second;
- }
- m_effects.clear();
-}
-
-bgfx_effect* effect_manager::effect(std::string name)
-{
- std::map<std::string, bgfx_effect*>::iterator iter = m_effects.find(name);
- if (iter != m_effects.end())
+ std::string full_name = name;
+ if (full_name.length() < 5 || (full_name.compare(full_name.length() - 5, 5, ".json") != 0))
{
- return iter->second;
+ full_name += ".json";
}
- return load_effect(name);
-}
-
-bgfx_effect* effect_manager::load_effect(std::string name)
-{
- std::string full_name = name;
- if (full_name.length() < 5 || (full_name.compare(full_name.length() - 5, 5, ".json") != 0)) {
- full_name = full_name + ".json";
- }
- std::string path;
- osd_subst_env(path, util::string_format("%s" PATH_SEPARATOR "effects" PATH_SEPARATOR, m_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()))
{
- printf("Unable to open effect file %s\n", path.c_str());
- return nullptr;
+ osd_printf_error("Unable to open effect file %s\n", path);
+ return false;
}
- int32_t size (bx::getSize(&reader));
+ 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;
+ }
- char* data = new char[size + 1];
- bx::read(&reader, reinterpret_cast<void*>(data), size);
+ bx::ErrorAssert err;
+ bx::read(&reader, reinterpret_cast<void*>(data.get()), size, &err);
bx::close(&reader);
data[size] = 0;
- Document document;
- document.Parse<kParseCommentsFlag>(data);
+ document.Parse<rapidjson::kParseCommentsFlag>(data.get());
+ data.reset();
- delete [] data;
+ if (document.HasParseError())
+ {
+ std::string error(rapidjson::GetParseError_En(document.GetParseError()));
+ 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()
+{
+ // the map will automatically dispose of the effects
+}
- if (document.HasParseError()) {
- std::string error(GetParseError_En(document.GetParseError()));
- printf("Unable to parse effect %s. Errors returned:\n", path.c_str());
- printf("%s\n", error.c_str());
+bgfx_effect* effect_manager::get_or_load_effect(const osd_options &options, const std::string &name)
+{
+ const auto iter = m_effects.find(name);
+ if (iter != m_effects.end())
+ return iter->second.get();
+
+ return load_effect(options, 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))
+ {
return nullptr;
}
- bgfx_effect* effect = effect_reader::read_from_value(document, "Effect '" + name + "': ", m_shaders);
+ std::unique_ptr<bgfx_effect> effect = effect_reader::read_from_value(name, document, "Effect '" + name + "': ", options, m_shaders);
- if (effect == nullptr) {
- printf("Unable to load effect %s\n", path.c_str());
+ if (!effect)
+ {
+ osd_printf_error("Unable to load effect %s\n", name);
return nullptr;
}
- m_effects[name] = effect;
+ return m_effects.emplace(name, std::move(effect)).first->second.get();
+}
+
+bool effect_manager::validate_effect(const osd_options &options, const std::string &name)
+{
+ rapidjson::Document document;
+ if (!prepare_effect_document(name, options, document))
+ {
+ return false;
+ }
- return effect;
+ return effect_reader::validate_value(document, "Effect '" + name + "': ", options);
}
diff --git a/src/osd/modules/render/bgfx/effectmanager.h b/src/osd/modules/render/bgfx/effectmanager.h
index 8125741c7ff..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(osd_options& options, shader_manager& shaders) : m_options(options), m_shaders(shaders) { }
+ effect_manager(shader_manager& shaders);
~effect_manager();
// Getters
- bgfx_effect* effect(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(std::string name);
+ bgfx_effect* load_effect(const osd_options &options, const std::string &name);
- osd_options& m_options;
- 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 3e51cb9d9dc..befdc598537 100644
--- a/src/osd/modules/render/bgfx/effectreader.cpp
+++ b/src/osd/modules/render/bgfx/effectreader.cpp
@@ -6,30 +6,87 @@
//
//============================================================
-#include <string>
-
-#include <bgfx/bgfx.h>
-
-#include "emu.h"
+#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"
-#include "effectreader.h"
+#include <utility>
-bgfx_effect* effect_reader::read_from_value(const Value& value, std::string prefix, shader_manager& shaders)
+
+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)
{
- if (!validate_parameters(value, prefix))
+ uint64_t flags = 0;
+ std::string vertex_name;
+ std::string fragment_name;
+ 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))
+ {
+ return nullptr;
+ }
+
+ 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 effect;
+}
+
+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<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))
+ return false;
+
+ if (!shader_manager::is_shader_present(options, fragment_name))
+ return false;
+
+ return true;
+}
+
+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))
+ {
+ return false;
+ }
+
uint64_t blend = 0;
if (value.HasMember("blend"))
{
@@ -38,34 +95,21 @@ bgfx_effect* effect_reader::read_from_value(const Value& value, std::string pref
uint64_t depth = depth_reader::read_from_value(value["depth"], prefix + "depth: ");
uint64_t cull = cull_reader::read_from_value(value["cull"]);
uint64_t write = write_reader::read_from_value(value["write"]);
+ flags = blend | depth | cull | write;
- std::vector<bgfx_uniform*> uniforms;
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 nullptr;
+ return false;
}
- uniforms.push_back(uniform);
+ uniforms.emplace_back(std::move(uniform));
}
- std::string vertex_name(value["vertex"].GetString());
- bgfx::ShaderHandle vertex_shader = shaders.shader(vertex_name);
- if (vertex_shader.idx == 0xffff)
- {
- for (bgfx_uniform* uniform : uniforms)
- {
- if (uniform != nullptr)
- {
- delete uniform;
- }
- }
- return nullptr;
- }
+ vertex_name = value["vertex"].GetString();
- std::string fragment_name("");
if (value.HasMember("fragment"))
{
fragment_name = value["fragment"].GetString();
@@ -74,33 +118,49 @@ bgfx_effect* effect_reader::read_from_value(const Value& value, std::string pref
{
fragment_name = value["pixel"].GetString();
}
- bgfx::ShaderHandle fragment_shader = shaders.shader(fragment_name);
- if (fragment_shader.idx == 0xffff)
+ else
{
- for (bgfx_uniform* uniform : uniforms)
- {
- if (uniform != nullptr)
- {
- delete uniform;
- }
- }
- return nullptr;
+ fragment_name = "";
+ }
+
+ return true;
+}
+
+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)
+ {
+ return false;
}
- return new bgfx_effect(blend | depth | cull | write, vertex_shader, fragment_shader, uniforms);
+ fragment_shader = shaders.load_shader(options, fragment_name);
+ if (fragment_shader.idx == bgfx::kInvalidHandle)
+ {
+ return false;
+ }
+
+ return true;
}
-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 0bc1b334435..db590e5eeb3 100644
--- a/src/osd/modules/render/bgfx/effectreader.h
+++ b/src/osd/modules/render/bgfx/effectreader.h
@@ -6,25 +6,38 @@
//
//============================================================
+#ifndef MAME_RENDER_BGFX_EFFECTREADER_H
+#define MAME_RENDER_BGFX_EFFECTREADER_H
+
#pragma once
-#ifndef __DRAWBGFX_EFFECT_READER__
-#define __DRAWBGFX_EFFECT_READER__
+#include "statereader.h"
+
+#include <bgfx/bgfx.h>
+#include <memory>
#include <string>
+#include <vector>
-#include "statereader.h"
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, shader_manager& shaders);
+ 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 validate_parameters(const Value& value, std::string prefix);
+ 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 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 4ba30250e6e..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 98d0594e27a..154252db04f 100644
--- a/src/osd/modules/render/bgfx/inputpair.cpp
+++ b/src/osd/modules/render/bgfx/inputpair.cpp
@@ -9,20 +9,20 @@
//
//============================================================
-#include "emu.h"
-#include "../frontend/mame/ui/slider.h"
-
-#include "emucore.h"
-
#include "inputpair.h"
-#include "texture.h"
-#include "target.h"
-#include "effect.h"
-#include "render.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)
@@ -42,27 +42,46 @@ bgfx_input_pair::bgfx_input_pair(int index, std::string sampler, std::string tex
bgfx_input_pair::~bgfx_input_pair()
{
+ m_slider_state.reset();
}
void bgfx_input_pair::bind(bgfx_effect *effect, const int32_t screen) const
{
- assert(effect->uniform(m_sampler) != nullptr);
+ if (effect->uniform(m_sampler) == nullptr)
+ return;
+
std::string name = m_texture + std::to_string(screen);
bgfx_texture_handle_provider* provider = chains().textures().provider(name);
+ 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 != nullptr)
+ if (tex_size && provider)
{
- float values[2] = { float(provider->width()), float(provider->height()) };
+ float values[2] = { rowpixels, height };
tex_size->set(values, sizeof(float) * 2);
}
- bgfx::setTexture(m_index, effect->uniform(m_sampler)->handle(), chains().textures().handle(name));
-}
+ 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 / rowpixels, 1.0f / height };
+ inv_tex_size->set(values, sizeof(float) * 2);
+ }
-int32_t bgfx_input_pair::slider_changed(running_machine &machine, void *arg, int id, std::string *str, int32_t newval)
-{
- return texture_changed(id, str, newval);
+ 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));
}
int32_t bgfx_input_pair::texture_changed(int32_t id, std::string *str, int32_t newval)
@@ -91,7 +110,7 @@ int32_t bgfx_input_pair::texture_changed(int32_t id, std::string *str, int32_t n
file_name = file.substr(0, last_dot);
}
- *str = string_format("%s", file_name.c_str());
+ *str = file_name;
}
return m_current_texture;
@@ -99,25 +118,19 @@ int32_t bgfx_input_pair::texture_changed(int32_t id, std::string *str, int32_t n
void bgfx_input_pair::create_selection_slider(uint32_t screen_index)
{
- m_slider_state = make_unique_clear<slider_state>();
-
- m_slider_state->minval = 0;
- m_slider_state->defval = m_current_texture;
- m_slider_state->maxval = m_available_textures.size() - 1;
- m_slider_state->incval = 1;
+ int32_t minval = 0;
+ int32_t defval = m_current_texture;
+ int32_t maxval = m_available_textures.size() - 1;
+ int32_t incval = 1;
using namespace std::placeholders;
- m_slider_state->update = std::bind(&bgfx_input_pair::slider_changed, this, _1, _2, _3, _4, _5);
- m_slider_state->arg = this;
- m_slider_state->id = screen_index;
- m_slider_state->description = "Window " + std::to_string(chains().window_index()) + ", Screen " + std::to_string(screen_index) + " " + m_selection + ":";
-
- ui::menu_item item;
- item.text = m_slider_state->description;
- item.subtext = "";
- item.flags = 0;
- item.ref = m_slider_state.get();
- item.type = ui::menu_item_type::SLIDER;
+ 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);
m_selection_slider = item;
}
@@ -131,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/inputpair.h b/src/osd/modules/render/bgfx/inputpair.h
index fb3fc58e1f7..668d652200d 100644
--- a/src/osd/modules/render/bgfx/inputpair.h
+++ b/src/osd/modules/render/bgfx/inputpair.h
@@ -14,16 +14,17 @@
#ifndef __DRAWBGFX_INPUT_PAIR__
#define __DRAWBGFX_INPUT_PAIR__
+#include <memory>
#include <string>
+#include <vector>
#include "../frontend/mame/ui/menuitem.h"
-#include "../frontend/mame/ui/sliderchangednotifier.h"
struct slider_state;
class bgfx_effect;
class chain_manager;
-class bgfx_input_pair : public slider_changed_notifier
+class bgfx_input_pair
{
public:
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);
@@ -39,7 +40,6 @@ public:
std::vector<ui::menu_item> get_slider_list();
private:
- virtual int32_t slider_changed(running_machine &machine, void *arg, int /*id*/, std::string *str, int32_t newval) override;
void create_selection_slider(uint32_t screen_index);
bool needs_sliders();
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 f24bb6a475b..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)
{
- float limit = float(value["limit"].GetDouble());
- return new bgfx_time_parameter(name, type, limit);
+ auto limit = float(value["limit"].GetDouble());
+ 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 7583b58dec5..282029cb96a 100644
--- a/src/osd/modules/render/bgfx/shadermanager.cpp
+++ b/src/osd/modules/render/bgfx/shadermanager.cpp
@@ -9,15 +9,17 @@
//
//============================================================
-#include <bx/math.h>
-#include <bx/readerwriter.h>
-#include <bx/file.h>
+#include "shadermanager.h"
-#include "emu.h"
+#include "emucore.h"
-#include <bgfx/bgfx.h>
+#include "osdfile.h"
+#include "modules/lib/osdobj_common.h"
+
+#include <bx/file.h>
+#include <bx/math.h>
+#include <bx/readerwriter.h>
-#include "shadermanager.h"
shader_manager::~shader_manager()
{
@@ -28,7 +30,7 @@ shader_manager::~shader_manager()
m_shaders.clear();
}
-bgfx::ShaderHandle shader_manager::shader(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())
@@ -36,13 +38,60 @@ bgfx::ShaderHandle shader_manager::shader(std::string name)
return iter->second;
}
- return load_shader(name);
+ bgfx::ShaderHandle handle = load_shader(options, name);
+ if (handle.idx != bgfx::kInvalidHandle)
+ {
+ m_shaders[name] = handle;
+ }
+
+ return handle;
+}
+
+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");
+ if (mem != nullptr)
+ {
+ return bgfx::createShader(mem);
+ }
+
+ return BGFX_INVALID_HANDLE;
}
-bgfx::ShaderHandle shader_manager::load_shader(std::string name)
+bool shader_manager::is_shader_present(const osd_options &options, const std::string &name)
{
- std::string shader_path(m_options.bgfx_path());
+ 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, &err);
+ delete [] data;
+ bx::close(&reader);
+
+ return expected_size == read_size;
+ }
+
+ return false;
+}
+
+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;
+
+#if defined(SDLMAME_EMSCRIPTEN)
+ // Hard-code renderer type to OpenGL ES for emscripten builds since the
+ // bgfx::getRendererType() is called here before BGFX has been
+ // initialized and therefore gives the wrong renderer type (Noop).
+ shader_path += "essl" PATH_SEPARATOR;
+ return shader_path;
+#endif
+
switch (bgfx::getRendererType())
{
case bgfx::RendererType::Noop:
@@ -79,29 +128,18 @@ bgfx::ShaderHandle shader_manager::load_shader(std::string name)
fatalerror("Unknown BGFX renderer type %d", bgfx::getRendererType());
}
shader_path += PATH_SEPARATOR;
- osd_subst_env(shader_path, shader_path);
-
- const bgfx::Memory* mem = load_mem(shader_path + name + ".bin");
- if (mem != nullptr)
- {
- bgfx::ShaderHandle handle = bgfx::createShader(mem);
-
- m_shaders[name] = handle;
-
- return handle;
- }
-
- return BGFX_INVALID_HANDLE;
+ 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';
@@ -109,7 +147,7 @@ const bgfx::Memory* shader_manager::load_mem(std::string name)
}
else
{
- printf("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 bee48dcea81..12ac739d35a 100644
--- a/src/osd/modules/render/bgfx/shadermanager.h
+++ b/src/osd/modules/render/bgfx/shadermanager.h
@@ -9,33 +9,36 @@
//
//============================================================
-#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>
-#include "modules/lib/osdobj_common.h"
-
#include <map>
#include <string>
-class shader_manager {
+class osd_options;
+
+
+class shader_manager
+{
public:
- shader_manager(osd_options& options) : m_options(options) { }
+ shader_manager() { }
~shader_manager();
// Getters
- bgfx::ShaderHandle shader(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:
- bgfx::ShaderHandle load_shader(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;
- osd_options& m_options;
+ 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 78229ec9c49..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
@@ -5,7 +5,7 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_color0
/*
Hyllian Smart-Blur Shader
-
+
Copyright (C) 2011-2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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);
-} \ No newline at end of file
+ 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 c82d7c82bec..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
@@ -6,7 +6,7 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_color0
/*
Hyllian Smart-Blur Shader
-
+
Copyright (C) 2011-2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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
new file mode 100644
index 00000000000..9118e42d5c8
--- /dev/null
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/crt-geom_common.sc
@@ -0,0 +1,203 @@
+// Comment the next line to disable interpolation in linear gamma (and gain speed).
+//#define LINEAR_PROCESSING
+
+// Enable 3x oversampling of the beam profile
+#define OVERSAMPLE
+
+// Use the older, purely gaussian beam profile
+#define USEGAUSSIAN
+
+// Macros.
+#define FIX(c) max(abs(c), 1e-5)
+#define PI 3.141592653589
+
+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);
+#ifdef LINEAR_PROCESSING
+ col = pow(col, vec4_splat(CRTgamma.x));
+#endif
+ return col;
+}
+
+// Enable screen curvature.
+uniform vec4 curvature;
+
+uniform vec4 spot_size;
+uniform vec4 spot_growth;
+uniform vec4 spot_growth_power;
+
+uniform vec4 u_interp;
+
+uniform vec4 aperture_strength;
+uniform vec4 aperture_brightboost;
+
+uniform vec4 CRTgamma;
+uniform vec4 monitorsRGB;
+uniform vec4 monitorgamma;
+
+uniform vec4 overscan;
+uniform vec4 aspect;
+
+uniform vec4 d;
+uniform vec4 R;
+
+uniform vec4 cornersize;
+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);
+}
+
+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);
+}
+
+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));
+}
+
+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);
+}
+
+// Calculate the influence of a scanline on the current pixel.
+//
+// 'distance' is the distance in texture coordinates from the current
+// pixel to the scanline in question.
+// 'color' is the colour of the scanline at the horizontal location of
+// 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.
+#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;
+#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);
+#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);
+}
+
+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);
+ }
+}
+
+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;
+}
+
+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
+}
+
+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);
+}
+
+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));
+}
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 c5cfcbf2cdc..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
@@ -12,120 +12,33 @@ $input v_sinangle, v_cosangle, v_stretch, v_one, v_texCoord
#include "common.sh"
-// Comment the next line to disable interpolation in linear gamma (and gain speed).
-//#define LINEAR_PROCESSING
-
-// Enable 3x oversampling of the beam profile
-#define OVERSAMPLE
-
-// Use the older, purely gaussian beam profile
-#define USEGAUSSIAN
-
-// Macros.
-#define FIX(c) max(abs(c), 1e-5)
-#define PI 3.141592653589
-
SAMPLER2D(mpass_texture, 0);
SAMPLER2D(mask_texture, 1);
SAMPLER2D(blur_texture, 2);
-
-#ifdef LINEAR_PROCESSING
-# define TEX2D(c) pow(texture2D(mpass_texture, (c)), vec4(CRTgamma))
-#else
-# define TEX2D(c) texture2D(mpass_texture, (c))
-#endif
-
-// Enable screen curvature.
-uniform vec4 curvature;
+SAMPLER2D(mipmap_texture, 3);
uniform vec4 u_tex_size0;
uniform vec4 u_tex_size1;
uniform vec4 u_quad_dims;
-uniform vec4 aperture_strength;
-
-uniform vec4 CRTgamma;
-uniform vec4 monitorgamma;
-
-uniform vec4 overscan;
-uniform vec4 aspect;
-
-uniform vec4 d;
-uniform vec4 R;
-
-uniform vec4 cornersize;
-uniform vec4 cornersmooth;
+#include "crt-geom_common.sc"
uniform vec4 halation;
+uniform vec4 rasterbloom;
-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);
-}
-
-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);
-}
+uniform vec4 blurwidth;
-vec2 transform(vec2 coord, vec3 stretch, vec2 sinangle, vec2 cosangle)
+vec4 texblur(vec2 c)
{
- 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);
-}
-
-// Calculate the influence of a scanline on the current pixel.
-//
-// 'distance' is the distance in texture coordinates from the current
-// pixel to the scanline in question.
-// 'color' is the colour of the scanline at the horizontal location of
-// 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.
-#ifdef USEGAUSSIAN
- vec4 wid = 0.3 + 0.1 * pow(color, vec4_splat(3.0));
- vec4 weights = vec4(distance / wid);
- return 0.4 * 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);
-#endif
+ 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);
+ vec2 e2c = exp(-c*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 * vec4_splat( c.x * c.y );
}
void main()
@@ -136,6 +49,10 @@ void main()
// | | | | |
// -------------------------------
// | | | | |
+ // | 00 | 10 | 20 | 30 | <-- previous scanline
+ // | | | | |
+ // -------------------------------
+ // | | | | |
// | 01 | 11 | 21 | 31 | <-- current scanline
// | | @ | | |
// -------------------------------
@@ -147,9 +64,10 @@ void main()
//
// 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
+ // in the current scan-line). The grid of lines represents the
// edges of the texels of the underlying texture.
+ // The "deluxe" shader includes contributions from the
+ // previous, current, and next scanlines.
// Texture coordinates of the texel containing the active pixel.
vec2 xy;
@@ -157,79 +75,69 @@ void main()
xy = transform(v_texCoord, v_stretch, v_sinangle, v_cosangle);
else
xy = (v_texCoord-vec2_splat(0.5))/overscan.xy+vec2_splat(0.5);
- vec2 xy0 = xy;
float cval = corner(xy);
+ // extract average brightness from the mipmap texture
+ float avgbright = dot(texture2D(mipmap_texture,vec2(1.0,1.0)).rgb,vec3_splat(1.0))/3.0;
+ float rbloom = 1.0 - rasterbloom.x * ( avgbright - 0.5 );
+ // expand the screen when average brightness is higher
+ xy = (xy - vec2_splat(0.5)) * rbloom + vec2_splat(0.5);
+ vec2 xy0 = 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);
-
+ vec2 ratio_scale = xy * u_tex_size0.xy - vec2(0.5,0.0);
+
#ifdef OVERSAMPLE
float filter = fwidth(ratio_scale.y);
#endif
- vec2 uv_ratio = fract(ratio_scale);
+ vec2 uv_ratio = fract(ratio_scale) - vec2(0.0,0.5);
// Snap to the center of the underlying texel.
xy = (floor(ratio_scale) + vec2_splat(0.5)) / u_tex_size0.xy;
- // Calculate Lanczos scaling coefficients describing the effect
+ // Calculate scaling coefficients describing the effect
// of various neighbour texels in a scanline on the current
// pixel.
- vec4 coeffs = PI * vec4(1.0 + uv_ratio.x, uv_ratio.x, 1.0 - uv_ratio.x, 2.0 - uv_ratio.x);
-
- // Prevent division by zero.
- coeffs = FIX(coeffs);
-
- // Lanczos2 kernel.
- coeffs = 2.0 * sin(coeffs) * sin(coeffs / 2.0) / (coeffs * coeffs);
-
- // Normalize.
- coeffs /= dot(coeffs, vec4_splat(1.0));
-
- // Calculate the effective colour of the current and next
- // scanlines at the horizontal location of the current pixel,
- // using the Lanczos coefficients above.
- vec4 col = clamp(TEX2D(xy + vec2(-v_one.x, 0.0))*coeffs.x +
- TEX2D(xy)*coeffs.y +
- TEX2D(xy +vec2(v_one.x, 0.0))*coeffs.z +
- TEX2D(xy + vec2(2.0 * v_one.x, 0.0))*coeffs.w , 0.0, 1.0);
-
- vec4 col2 = clamp(TEX2D(xy + vec2(-v_one.x, v_one.y))*coeffs.x +
- TEX2D(xy + vec2(0.0, v_one.y))*coeffs.y +
- TEX2D(xy + v_one)*coeffs.z +
- TEX2D(xy + vec2(2.0 * v_one.x, v_one.y))*coeffs.w , 0.0, 1.0);
+ 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 col_prev = sample_scanline(xy + vec2(0.0,-v_one.y), coeffs, v_one.x);
+ vec4 col_next = 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_prev = pow(col_prev, vec4_splat(CRTgamma.x));
+ col_next = pow(col_next, 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);
+ vec4 weights_prev = scanlineWeights(uv_ratio.y + 1.0, col_prev);
+ vec4 weights_next = scanlineWeights(uv_ratio.y - 1.0, col_next);
#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;
+ 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;
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;
+ weights=weights+scanlineWeights(uv_ratio.y, col)/3.0;
+ 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 + col2 * weights2).rgb;
+ vec4 mul_res = col * weights + col_prev * weights_prev + col_next * weights_next;
// halation and corners
- vec3 blur = pow(texture2D(blur_texture,xy0).rgb, vec3_splat(CRTgamma.x));
- mul_res = mix(mul_res, blur, halation.x) * vec3_splat(cval);
-
- // Convert the image gamma for display on our output device.
- mul_res = pow(mul_res, vec3_splat(1.0 / monitorgamma.x));
+ vec4 blur = texblur(xy0);
+ // include factor of rbloom:
+ // (probably imperceptible) brightness reduction when raster grows
+ mul_res = mix(mul_res, blur, halation.x) * vec4_splat(cval*rbloom);
// Shadow mask
- xy = v_texCoord.xy * u_quad_dims.xy / u_tex_size1.xy;
- vec3 mask = texture2D(mask_texture, xy).rgb;
- mask = mix(vec3_splat(1.0), mask, aperture_strength.x);
-
- gl_FragColor = vec4(mul_res*mask, col.a);
+ 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);
+
+ gl_FragColor = vec4(cout,1.0);
}
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 919ba46d0ab..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
@@ -12,216 +12,91 @@ $input v_sinangle, v_cosangle, v_stretch, v_one, v_texCoord
#include "common.sh"
-// Comment the next line to disable interpolation in linear gamma (and gain speed).
-//#define LINEAR_PROCESSING
-
-// Enable 3x oversampling of the beam profile
-#define OVERSAMPLE
-
-// Use the older, purely gaussian beam profile
-#define USEGAUSSIAN
-
-// Macros.
-#define FIX(c) max(abs(c), 1e-5)
-#define PI 3.141592653589
-
SAMPLER2D(mpass_texture, 0);
SAMPLER2D(mask_texture, 1);
-#ifdef LINEAR_PROCESSING
-# define TEX2D(c) pow(texture2D(mpass_texture, (c)), vec4(CRTgamma))
-#else
-# define TEX2D(c) texture2D(mpass_texture, (c))
-#endif
-
-// Enable screen curvature.
-uniform vec4 curvature;
uniform vec4 u_tex_size0;
uniform vec4 u_tex_size1;
uniform vec4 u_quad_dims;
-uniform vec4 aperture_strength;
-
-uniform vec4 CRTgamma;
-uniform vec4 monitorgamma;
-
-uniform vec4 overscan;
-uniform vec4 aspect;
+#include "crt-geom_common.sc"
-uniform vec4 d;
-uniform vec4 R;
-uniform vec4 cornersize;
-uniform vec4 cornersmooth;
-
-float intersect(vec2 xy , vec2 sinangle, vec2 cosangle)
+void main()
{
- 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);
-}
+ // 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);
-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);
-}
+#ifdef OVERSAMPLE
+ float filter = fwidth(ratio_scale.y);
+#endif
+ vec2 uv_ratio = fract(ratio_scale);
-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));
-}
+ // Snap to the center of the underlying texel.
+ xy = (floor(ratio_scale) + vec2_splat(0.5)) / u_tex_size0.xy;
-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);
-}
+ // 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 the influence of a scanline on the current pixel.
-//
-// 'distance' is the distance in texture coordinates from the current
-// pixel to the scanline in question.
-// 'color' is the colour of the scanline at the horizontal location of
-// 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.
-#ifdef USEGAUSSIAN
- vec4 wid = 0.3 + 0.1 * pow(color, vec4_splat(3.0));
- vec4 weights = vec4(distance / wid);
- return 0.4 * 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 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));
#endif
-}
-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);
-
+ // 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
- float filter = fwidth(ratio_scale.y);
+ 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
- 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;
-
- // Calculate Lanczos scaling coefficients describing the effect
- // of various neighbour texels in a scanline on the current
- // pixel.
- vec4 coeffs = PI * vec4(1.0 + uv_ratio.x, uv_ratio.x, 1.0 - uv_ratio.x, 2.0 - uv_ratio.x);
-
- // Prevent division by zero.
- coeffs = FIX(coeffs);
-
- // Lanczos2 kernel.
- coeffs = 2.0 * sin(coeffs) * sin(coeffs / 2.0) / (coeffs * coeffs);
-
- // Normalize.
- coeffs /= dot(coeffs, vec4_splat(1.0));
-
- // Calculate the effective colour of the current and next
- // scanlines at the horizontal location of the current pixel,
- // using the Lanczos coefficients above.
- vec4 col = clamp(TEX2D(xy + vec2(-v_one.x, 0.0))*coeffs.x +
- TEX2D(xy)*coeffs.y +
- TEX2D(xy +vec2(v_one.x, 0.0))*coeffs.z +
- TEX2D(xy + vec2(2.0 * v_one.x, 0.0))*coeffs.w , 0.0, 1.0);
-
- vec4 col2 = clamp(TEX2D(xy + vec2(-v_one.x, v_one.y))*coeffs.x +
- TEX2D(xy + vec2(0.0, v_one.y))*coeffs.y +
- TEX2D(xy + v_one)*coeffs.z +
- TEX2D(xy + vec2(2.0 * v_one.x, v_one.y))*coeffs.w , 0.0, 1.0);
+ vec4 mul_res = col * weights + col2 * weights2 * vec4_splat(cval);
+ // Shadow mask
+ vec3 cout = apply_shadow_mask(v_texCoord.xy, mul_res.rgb);
-#ifndef LINEAR_PROCESSING
- col = pow(col , vec4_splat(CRTgamma.x));
- col2 = pow(col2, vec4_splat(CRTgamma.x));
-#endif
+ // Convert the image gamma for display on our output device.
+ cout = linear_to_output(cout);
- // 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;
-#endif
- vec3 mul_res = (col * weights + col2 * weights2).rgb * vec3_splat(cval);
-
- // Convert the image gamma for display on our output device.
- mul_res = pow(mul_res, vec3_splat(1.0 / monitorgamma.x));
-
- // Color the texel.
-
- xy = v_texCoord.xy * u_quad_dims.xy / u_tex_size1.xy;
- vec3 mask = texture2D(mask_texture, xy).rgb;
- mask = mix(vec3_splat(1.0), mask, aperture_strength.x);
-
- gl_FragColor = vec4(mul_res*mask, col.a);
+ 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 f45d1d5df81..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
@@ -1,4 +1,4 @@
-$input v_texCoord, v_coeffs
+$input v_texCoord, v_coeffs, v_coeffs2
#include "common.sh"
@@ -6,24 +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(-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(+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));
-
- gl_FragColor = vec4( pow(sum*vec3_splat(norm), vec3_splat(1.0/u_gamma.x)), 1.0 );
+ 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 = 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 107d1d7a5bb..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
@@ -1,4 +1,4 @@
-$input v_texCoord, v_coeffs
+$input v_texCoord, v_coeffs, v_coeffs2
#include "common.sh"
@@ -6,24 +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, -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, +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));
-
- gl_FragColor = vec4( pow(sum*vec3_splat(norm), vec3_splat(1.0/u_gamma.x)), 1.0 );
+ 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 = 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
new file mode 100644
index 00000000000..37ab685957c
--- /dev/null
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_lowpass.sc
@@ -0,0 +1,37 @@
+$input v_texCoord, v_lpcoeffs1, v_lpcoeffs2
+
+#include "common.sh"
+
+SAMPLER2D(s_screen, 0);
+
+uniform vec4 u_tex_size0;
+
+vec3 sample_screen(vec2 c)
+{
+ vec2 underscan = step(0.0,c) * step(0.0,vec2_splat(1.0)-c);
+ vec3 col = texture2D(s_screen, c).rgb * vec3_splat(underscan.x*underscan.y);
+ return col;
+}
+
+void main()
+{
+ float onex = 1.0/u_tex_size0.x;
+
+ vec3 sum = sample_screen(v_texCoord) * vec3_splat(v_lpcoeffs1.x);
+ sum +=sample_screen(v_texCoord+vec2(-1.0*onex,0.0))*vec3_splat(v_lpcoeffs1.y);
+ sum +=sample_screen(v_texCoord+vec2( 1.0*onex,0.0))*vec3_splat(v_lpcoeffs1.y);
+ sum +=sample_screen(v_texCoord+vec2(-2.0*onex,0.0))*vec3_splat(v_lpcoeffs1.z);
+ sum +=sample_screen(v_texCoord+vec2( 2.0*onex,0.0))*vec3_splat(v_lpcoeffs1.z);
+ sum +=sample_screen(v_texCoord+vec2(-3.0*onex,0.0))*vec3_splat(v_lpcoeffs1.w);
+ sum +=sample_screen(v_texCoord+vec2( 3.0*onex,0.0))*vec3_splat(v_lpcoeffs1.w);
+ sum +=sample_screen(v_texCoord+vec2(-4.0*onex,0.0))*vec3_splat(v_lpcoeffs2.x);
+ sum +=sample_screen(v_texCoord+vec2( 4.0*onex,0.0))*vec3_splat(v_lpcoeffs2.x);
+ sum +=sample_screen(v_texCoord+vec2(-5.0*onex,0.0))*vec3_splat(v_lpcoeffs2.y);
+ sum +=sample_screen(v_texCoord+vec2( 5.0*onex,0.0))*vec3_splat(v_lpcoeffs2.y);
+ sum +=sample_screen(v_texCoord+vec2(-6.0*onex,0.0))*vec3_splat(v_lpcoeffs2.z);
+ sum +=sample_screen(v_texCoord+vec2( 6.0*onex,0.0))*vec3_splat(v_lpcoeffs2.z);
+ 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, 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
new file mode 100644
index 00000000000..2e0f8038053
--- /dev/null
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_mipmap8.sc
@@ -0,0 +1,148 @@
+$input v_texCoord
+
+#include "common.sh"
+
+SAMPLER2D(s_screen, 0);
+SAMPLER2D(s_mipmap, 1);
+
+uniform vec4 u_tex_size0;
+uniform vec4 u_tex_size1;
+uniform vec4 u_smooth;
+
+/*
+ * Based loosely on the idea outlined at
+ * https://nyorain.github.io/mipmap-compute-shader.html
+ * Each higher mipmap level is delayed by one frame.
+ *
+ * A rectangle containing (1,1) has the last mipmap level
+ * (normally a single pixel containing the average of the frame),
+ * passed through a two-tap IIR temporal filter.
+ */
+
+const vec2 v05 = vec2(0.5,0.5);
+
+// pix has integer coordinates -> average four pixels using bilinear filtering
+vec4 sample_screen(vec2 pix)
+{
+ vec2 border = step(-0.5, u_tex_size0.xy - pix);
+ float weight = border.x * border.y;
+
+ // avoid boundary! if dimensions are odd, average 1 or 2 pixels
+ vec2 x = clamp(pix, vec2_splat(0.0), u_tex_size0.xy - v05);
+ // if we're at the boundary, include weight factor
+ // -> effectively always average 4 pixels, with some of them possibly zero
+ border = clamp(u_tex_size0.xy-x,0.0,1.0);
+ weight *= border.x * border.y;
+
+ vec4 tex = texture2D(s_screen, x / u_tex_size0.xy);
+
+ return tex * vec4_splat(weight);
+}
+
+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;
+
+ // avoid boundary! if dimensions are odd, average 1 or 2 pixels
+ vec2 x = clamp(pix, vec2_splat(0.0), size - v05);
+ // if we're at the boundary, include weight factor
+ // -> effectively always average 4 pixels, with some of them possibly zero
+ border = clamp(size-x,0.0,1.0);
+ weight *= border.x * border.y;
+
+ vec4 tex = texture2D(s_mipmap, (x + offset) / u_tex_size0.xy);
+
+ return tex * vec4_splat(weight);
+}
+
+void main()
+{
+ vec2 pix = v_texCoord.xy * u_tex_size0.xy;
+ vec2 x = pix*vec2_splat(8.0);
+ if (pix.x < u_tex_size0.x * 0.5) {
+ // first level: sample from screen texture
+
+ // sample 4x4 grid
+ // each sample uses bilinear filtering to average a 2x2 region
+ // overall reduction by 8x8
+ 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))
+ + sample_screen(x + vec2(-1.0,-3.0))
+ + sample_screen(x + vec2(-1.0,-1.0))
+ + sample_screen(x + vec2(-1.0, 1.0))
+ + sample_screen(x + vec2(-1.0, 3.0))
+ + sample_screen(x + vec2( 1.0,-3.0))
+ + sample_screen(x + vec2( 1.0,-1.0))
+ + sample_screen(x + vec2( 1.0, 1.0))
+ + sample_screen(x + vec2( 1.0, 3.0))
+ + 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)) ) * 0.0625;
+
+ gl_FragColor = vec4(tex.rgb,1.0);
+ } else {
+ // higher levels: sample from mipmap texture
+ vec2 newsize = u_tex_size0.xy; // size of texture being sampled
+ float fac = 8.0; // keep track of the linear reduction factor
+ float dx = u_tex_size0.x;
+ vec2 offset = vec2_splat(0.0);
+ vec2 offset0 = offset;
+ bool fc = false;
+
+ for (int i = 0; i < 3; i++) { // 3 is sufficient for dimensions up to 4k
+ // place subsequent levels to the right
+ if (pix.x > dx * 0.5) {
+ dx = dx * 0.5;
+ newsize = ceil(newsize*v05*v05*v05); // size of sampled texture is eighthed
+ fac *= 8.0;
+ offset0 = offset;
+ offset.x = offset.x + dx;
+ pix.x -= dx;
+ x = pix * vec2_splat(8.0);
+ if (newsize.x < 8.5 && newsize.y < 8.5) { // reducing to a single pixel
+ fc = true;
+ break;
+ }
+ } else break;
+ }
+
+ if (fc)
+ x = vec2(4.0,4.0);
+
+ 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)
+ + sample_mipmap(x + vec2(-1.0,-3.0),offset0,newsize)
+ + sample_mipmap(x + vec2(-1.0,-1.0),offset0,newsize)
+ + sample_mipmap(x + vec2(-1.0, 1.0),offset0,newsize)
+ + sample_mipmap(x + vec2(-1.0, 3.0),offset0,newsize)
+ + sample_mipmap(x + vec2( 1.0,-3.0),offset0,newsize)
+ + sample_mipmap(x + vec2( 1.0,-1.0),offset0,newsize)
+ + sample_mipmap(x + vec2( 1.0, 1.0),offset0,newsize)
+ + sample_mipmap(x + vec2( 1.0, 3.0),offset0,newsize)
+ + 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) ) * 0.0625;
+
+ 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);
+ vec4 col = tex * vec4_splat(f);
+ if (v_texCoord.y * u_tex_size1.y < ( offset0.y + u_tex_size1.y ) * 0.5) {
+ 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 = mix(col,old,u_smooth.x);
+ }
+ } else {
+ 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 e70036084ff..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
@@ -7,19 +7,36 @@ SAMPLER2D(s_phosphor, 1);
uniform vec4 u_phosphor_power;
uniform vec4 u_phosphor_amplitude;
+uniform vec4 u_phosphor_cutoff;
uniform vec4 u_gamma;
+float decay(float t)
+{
+ // transition smoothly from power to linear at t=t1
+ float t1 = u_phosphor_cutoff.x / ( 1.0 + u_gamma.x / u_phosphor_power.x );
+ float tpow = pow( clamp(t,0.0,t1), -u_phosphor_power.x );
+ // smoothly fade out for t in [t1,cutoff]: linear in gamma space
+ t = clamp(t, 0.0, u_phosphor_cutoff.x);
+ float y = ( t < t1
+ ? tpow
+ : tpow * pow( ( u_phosphor_cutoff.x - t ) / ( u_phosphor_cutoff.x - t1 ), u_gamma.x ) );
+ return y;
+}
+
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 *= vec4_splat( u_phosphor_amplitude.x * decay(t) );
- cphos *= vec3_splat( u_phosphor_amplitude.x / pow(255.0*phosphor.a,u_phosphor_power.x) );
+ vec4 col = pow(cscrn + cphos, vec4(vec3_splat(1.0/u_gamma.x), 1.0));
- vec3 col = pow(cscrn + cphos, vec3_splat(1.0/u_gamma.x));
-
- gl_FragColor = vec4(col, 1.0);
+ gl_FragColor = col;
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_phosphor_update.sc b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_phosphor_update.sc
index 5215054b0db..824a008e96b 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_phosphor_update.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_phosphor_update.sc
@@ -7,8 +7,22 @@ SAMPLER2D(s_phosphor, 1);
uniform vec4 u_phosphor_power;
uniform vec4 u_phosphor_amplitude;
+uniform vec4 u_phosphor_cutoff;
uniform vec4 u_gamma;
+float decay(float t)
+{
+ // transition smoothly from power to linear at t=t1
+ float t1 = u_phosphor_cutoff.x / ( 1.0 + u_gamma.x / u_phosphor_power.x );
+ float tpow = pow( clamp(t,0.0,t1), -u_phosphor_power.x );
+ // smoothly fade out for t in [t1,cutoff]: linear in gamma space
+ t = clamp(t, 0.0, u_phosphor_cutoff.x);
+ float y = ( t < t1
+ ? tpow
+ : tpow * pow( ( u_phosphor_cutoff.x - t ) / ( u_phosphor_cutoff.x - t1 ), u_gamma.x ) );
+ return y;
+}
+
void main()
{
vec4 screen = texture2D(s_screen, v_texCoord);
@@ -17,8 +31,15 @@ void main()
vec3 lum = vec3(0.299,0.587,0.114);
float bscrn = dot(pow(screen.rgb,vec3_splat(u_gamma.x)),lum);
float bphos = dot(pow(phosphor.rgb,vec3_splat(u_gamma.x)),lum);
- //bscrn /= pow(1.0,u_phosphor_power.x);
- bphos /= pow(1.0+255.0*phosphor.a,u_phosphor_power.x);
- gl_FragColor = ( bscrn > bphos ? vec4(screen.rgb,1.0/255.0) : vec4(phosphor.rgb,phosphor.a+1.0/255.0) );
+ // encode the upper 2 bits of the time elapsed in the lower 2 bits of b
+ float t = 1.0 + 255.0*phosphor.a + fract(phosphor.b*255.0/4.0)*1024.0;
+
+ bphos = ( t > 1023.0 ? 0.0 : bphos * decay(t) );
+
+ gl_FragColor = ( bscrn >= bphos
+ ? vec4(screen.rg,floor(screen.b*255.0/4.0)*4.0/255.0,1.0/255.0)
+ : vec4(phosphor.rg,
+ (floor(phosphor.b*255.0/4.0)*4.0 + floor(t/256.0))/255.0,
+ fract(t/256.0)*256.0/255.0 ) );
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/varying.def.sc b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/varying.def.sc
index 034ca88185b..0de371e22c8 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/varying.def.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/varying.def.sc
@@ -1,9 +1,12 @@
vec2 v_texCoord : TEXCOORD0 = vec2(0.0, 0.0);
vec3 v_stretch : TEXCOORD1 = vec3(0.0,0.0,0.0);
-vec2 v_sinangle : TEXCOORD2 = vec2(0.0,0.0);
+vec2 v_sinangle : TEXCOORD2 = vec2(0.0,0.0);
vec2 v_cosangle : TEXCOORD3 = vec2(0.0,0.0);
vec2 v_one : TEXCOORD4 = vec2(0.0,0.0);
vec4 v_coeffs : TEXCOORD5 = vec4(0.0,0.0,0.0,0.0);
+vec4 v_coeffs2 : TEXCOORD6 = vec4(0.0,0.0,0.0,0.0);
+vec4 v_lpcoeffs1: TEXCOORD7 = vec4(0.0,0.0,0.0,0.0);
+vec4 v_lpcoeffs2: TEXCOORD8 = vec4(0.0,0.0,0.0,0.0);
vec3 a_position : POSITION;
vec4 a_color0 : COLOR0;
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 4bd5a57e3ef..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
@@ -1,18 +1,23 @@
$input a_position, a_texcoord0, a_color0
-$output v_texCoord, v_coeffs
+$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));
+ 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 3ff1e07f236..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
@@ -1,18 +1,23 @@
$input a_position, a_texcoord0, a_color0
-$output v_texCoord, v_coeffs
+$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));
+ 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
new file mode 100644
index 00000000000..2ca983d41d7
--- /dev/null
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_lowpass.sc
@@ -0,0 +1,53 @@
+$input a_position, a_texcoord0, a_color0
+$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));
+#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);
+
+ 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) );
+ }
+}
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
new file mode 100644
index 00000000000..8424e153cdb
--- /dev/null
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_mipmap8.sc
@@ -0,0 +1,16 @@
+$input a_position, a_texcoord0, a_color0
+$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));
+#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 37a119ec7d4..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,14 +32,18 @@ $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);
oney = vec2(0.0, 1.0 / u_source_size.y);
-
+
v_color0 = a_color0;
}
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 a07a848ffbd..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
@@ -7,7 +7,7 @@ $input v_color0, texCoord, t1, t2, t3, t4, t5, t6, t7, t8
/* Copied from the Dosbox source code */
/* Copyright (C) 2002-2007 The DOSBox Team */
/* License: GNU-GPL */
-/* Adapted by guest(r) on 16.4.2007 */
+/* Adapted by guest(r) on 16.4.2007 */
#include "common.sh"
@@ -32,10 +32,10 @@ float GET_RESULT(float A, float B, float C, float D)
float r = 0.0;
if (A == C) x += 1.0; else if (B == C) y += 1.0;
if (A == D) x += 1.0; else if (B == D) y += 1.0;
- if (x <= 1.0) r += 1.0;
+ if (x <= 1.0) r += 1.0;
if (y <= 1.0) r -= 1.0;
return r;
-}
+}
void main()
{
@@ -43,7 +43,7 @@ void main()
// Reading the texels
- vec3 C0 = texture2D(decal, t1.xy).xyz;
+ vec3 C0 = texture2D(decal, t1.xy).xyz;
vec3 C1 = texture2D(decal, t1.zw).xyz;
vec3 C2 = texture2D(decal, t2.xy).xyz;
vec3 D3 = texture2D(decal, t2.zw).xyz;
@@ -62,7 +62,7 @@ void main()
vec3 p00,p10,p01,p11;
- // reducing float3 to float
+ // reducing float3 to float
float c0 = reduce(C0); float c1 = reduce(C1);
float c2 = reduce(C2); float c3 = reduce(C3);
float c4 = reduce(C4); float c5 = reduce(C5);
@@ -76,7 +76,7 @@ void main()
/* Copied from the Dosbox source code */
/* Copyright (C) 2002-2007 The DOSBox Team */
/* License: GNU-GPL */
- /* Adapted by guest(r) on 16.4.2007 */
+ /* Adapted by guest(r) on 16.4.2007 */
if (c4 != c8)
{
if (c7 == c5)
@@ -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
{
@@ -158,8 +158,8 @@ void main()
}
}
}
-
+
p10 = (fp.x < 0.50) ? (fp.y < 0.50 ? p00 : p10) : (fp.y < 0.50 ? p01: p11);
-
+
gl_FragColor = vec4(p10.rgb, 1.0);
}
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 d233629a036..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
@@ -8,18 +8,22 @@ $output v_color0, texCoord, t1, t2, t3, t4, t5, t6, t7, t8
/* Copied from the Dosbox source code */
/* Copyright (C) 2002-2007 The DOSBox Team */
/* License: GNU-GPL */
-/* Adapted by guest(r) on 16.4.2007 */
+/* Adapted by guest(r) on 16.4.2007 */
#include "common.sh"
// 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;
float dx = ps.x;
float dy = ps.y;
diff --git a/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_chroma.sc b/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_chroma.sc
index 51bb14676d3..2c11ac8499b 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_chroma.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_chroma.sc
@@ -22,10 +22,11 @@ void main()
vec4 cin = texture2D(s_tex, v_texcoord0);
vec4 cout = vec4(0.0, 0.0, 0.0, cin.a);
mat3 xy = mat3(u_chroma_a.xyz, u_chroma_b.xyz, u_chroma_c.xyz);
- const mat3 XYZ_TO_sRGB = mat3(
- 3.2406, -0.9689, 0.0557,
- -1.5372, 1.8758, -0.2040,
- -0.4986, 0.0415, 1.0570
+
+ mat3 XYZ_TO_sRGB = mtxFromRows3(
+ vec3( 3.2406, -1.5372, -0.4986),
+ vec3(-0.9689, 1.8758, 0.0415),
+ vec3( 0.0557, -0.2040, 1.0570)
);
for (int i = 0; i < 3; ++i) {
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 36f4fa9eaad..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;
}
@@ -183,7 +183,7 @@ void main()
// corner distortion at least by the amount of the image distorition
float distortCornerAmount = max(u_distort_corner.x, u_distortion.x + u_cubic_distortion.x);
- float roundCornerAmount = u_round_corner.x * 0.5;
+ float roundCornerAmount = u_round_corner.x * 0.5;
float smoothBorderAmount = u_smooth_border.x * 0.5;
vec2 TexelDims = vec2(1.0 / u_target_dims.x, 1.0 / u_target_dims.y);
diff --git a/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_ntsc_decode.sc b/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_ntsc_decode.sc
index b196674a094..60b54381ec3 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_ntsc_decode.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_ntsc_decode.sc
@@ -52,7 +52,7 @@ void main()
vec4 PI = vec4(3.1415927, 3.1415927, 3.1415927, 3.1415927);
vec4 PI2 = vec4(6.2831854, 6.2831854, 6.2831854, 6.2831854);
-
+
vec4 Fc_y1 = (u_cc_value.xxxx - u_notch_width.xxxx * onehalf) * TimePerSample;
vec4 Fc_y2 = (u_cc_value.xxxx + u_notch_width.xxxx * onehalf) * TimePerSample;
vec4 Fc_y3 = u_y_freq_response.xxxx * TimePerSample;
@@ -69,7 +69,7 @@ void main()
vec4 Fc_y2_pi2 = Fc_y2 * PI2;
vec4 Fc_y3_pi2 = Fc_y3 * PI2;
vec4 PI2Length = PI2 / SampleCount;
-
+
vec4 W = PI2 * u_cc_value.xxxx * u_scan_time.xxxx;
vec4 WoPI = W / PI;
@@ -120,7 +120,7 @@ void main()
IAccum = IAccum + C * cos(WT) * FilterI;
QAccum = QAccum + C * sin(WT) * FilterQ;
}
-
+
vec3 YIQ = vec3(
(YAccum.r + YAccum.g + YAccum.b + YAccum.a),
(IAccum.r + IAccum.g + IAccum.b + IAccum.a) * 2.0,
diff --git a/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_ntsc_encode.sc b/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_ntsc_encode.sc
index 61964c10c30..e94eeff6962 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_ntsc_encode.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_ntsc_encode.sc
@@ -58,7 +58,7 @@ void main()
const float PI = 3.1415927;
const float PI2 = 6.2831854;
-
+
float W = PI2 * u_cc_value.x * u_scan_time.x;
float WoPI = W / PI;
@@ -69,4 +69,4 @@ void main()
vec4 TW = T * W;
gl_FragColor = Y + I * cos(TW) + Q * sin(TW);
-} \ No newline at end of file
+}
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 38f81111567..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
@@ -57,11 +57,11 @@ void main()
mat3 pattern = mat3(diff(w5, w1), diff(w5, w2), diff(w5, w3), diff(w5, w4), 0.0, diff(w5, w6), diff(w5, w7), diff(w5, w8), diff(w5, w9));
vec4 cross = vec4(diff(w4, w2), diff(w2, w6), diff(w8, w4), diff(w6, w8));
-
+
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 a29c2c00da8..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
@@ -57,11 +57,11 @@ void main()
mat3 pattern = mat3(diff(w5, w1), diff(w5, w2), diff(w5, w3), diff(w5, w4), 0.0, diff(w5, w6), diff(w5, w7), diff(w5, w8), diff(w5, w9));
vec4 cross = vec4(diff(w4, w2), diff(w2, w6), diff(w8, w4), diff(w6, w8));
-
+
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 e6c0e1c2aaa..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
@@ -57,11 +57,11 @@ void main()
mat3 pattern = mat3(diff(w5, w1), diff(w5, w2), diff(w5, w3), diff(w5, w4), 0.0, diff(w5, w6), diff(w5, w7), diff(w5, w8), diff(w5, w9));
vec4 cross = vec4(diff(w4, w2), diff(w2, w6), diff(w8, w4), diff(w6, w8));
-
+
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 a77ac7006f7..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,12 +8,16 @@ $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;
float dx = ps.x;
float dy = ps.y;
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 a77ac7006f7..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,12 +8,16 @@ $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;
float dx = ps.x;
float dy = ps.y;
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 a77ac7006f7..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,12 +8,16 @@ $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;
float dx = ps.x;
float dy = ps.y;
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
new file mode 100644
index 00000000000..801d1a2e9a4
--- /dev/null
+++ b/src/osd/modules/render/bgfx/shaders/chains/lcd-grid/fs_lcd-grid.sc
@@ -0,0 +1,106 @@
+$input v_color0, v_texcoord0
+
+// license:GPL-2.0+
+// copyright-holders:cgwg
+
+#include "common.sh"
+
+SAMPLER2D(s_tex, 0);
+
+uniform vec4 u_tex_size0;
+uniform vec4 u_quad_dims;
+uniform vec4 u_rsubpix;
+uniform vec4 u_gsubpix;
+uniform vec4 u_bsubpix;
+uniform vec4 u_gain;
+uniform vec4 u_LCDgamma;
+uniform vec4 u_blacklevel;
+uniform vec4 u_ambient;
+uniform vec4 u_BGR;
+uniform vec4 u_monitorgamma;
+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;
+}
+
+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 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);
+}
+
+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);
+}
+
+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 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;
+}
+
+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);
+}
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
new file mode 100644
index 00000000000..4c9e998d3ec
--- /dev/null
+++ b/src/osd/modules/render/bgfx/shaders/chains/lcd-grid/fs_persistence.sc
@@ -0,0 +1,16 @@
+$input v_color0, v_texcoord0
+
+#include "common.sh"
+
+SAMPLER2D(s_screen, 0);
+SAMPLER2D(s_motionblur, 1);
+
+uniform vec4 u_persistence;
+
+void main()
+{
+ vec4 screen = texture2D(s_screen , v_texcoord0);
+ vec4 motionblur = texture2D(s_motionblur, v_texcoord0);
+
+ gl_FragColor = mix(screen, motionblur, u_persistence.x);
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/lcd-grid/varying.def.sc b/src/osd/modules/render/bgfx/shaders/chains/lcd-grid/varying.def.sc
new file mode 100644
index 00000000000..2aa3cb425c0
--- /dev/null
+++ b/src/osd/modules/render/bgfx/shaders/chains/lcd-grid/varying.def.sc
@@ -0,0 +1,6 @@
+vec4 v_color0 : COLOR0 = vec4(1.0, 0.0, 0.0, 1.0);
+vec2 v_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0);
+
+vec3 a_position : POSITION;
+vec4 a_color0 : COLOR0;
+vec2 a_texcoord0 : TEXCOORD0;
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
new file mode 100644
index 00000000000..df2b37f203c
--- /dev/null
+++ b/src/osd/modules/render/bgfx/shaders/chains/lcd-grid/vs_lcd-grid.sc
@@ -0,0 +1,19 @@
+$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;
+
+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
new file mode 100644
index 00000000000..df2b37f203c
--- /dev/null
+++ b/src/osd/modules/render/bgfx/shaders/chains/lcd-grid/vs_persistence.sc
@@ -0,0 +1,19 @@
+$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;
+
+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_blit_bcg.sc b/src/osd/modules/render/bgfx/shaders/chains/misc/fs_blit_bcg.sc
new file mode 100644
index 00000000000..37d64462c51
--- /dev/null
+++ b/src/osd/modules/render/bgfx/shaders/chains/misc/fs_blit_bcg.sc
@@ -0,0 +1,24 @@
+$input v_color0, v_texcoord0
+
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz
+
+#include "common.sh"
+
+// Samplers
+SAMPLER2D(s_tex, 0);
+SAMPLER2D(s_pal, 1);
+
+uniform vec4 u_inv_tex_size1;
+
+void main()
+{
+ vec4 src = texture2D(s_tex, v_texcoord0);
+ vec2 blu_uv = vec2(src.b * 256.0, 0.0) * u_inv_tex_size1.xy;
+ vec2 grn_uv = vec2(src.g * 256.0, 1.0) * u_inv_tex_size1.xy;
+ vec2 red_uv = vec2(src.r * 256.0, 2.0) * u_inv_tex_size1.xy;
+ float blu = texture2D(s_pal, blu_uv).b;
+ float grn = texture2D(s_pal, grn_uv).g;
+ float red = texture2D(s_pal, red_uv).r;
+ gl_FragColor = vec4(red, grn, blu, src.a) * v_color0;
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/misc/fs_blit_palette16.sc b/src/osd/modules/render/bgfx/shaders/chains/misc/fs_blit_palette16.sc
new file mode 100644
index 00000000000..6ecfbcb1a72
--- /dev/null
+++ b/src/osd/modules/render/bgfx/shaders/chains/misc/fs_blit_palette16.sc
@@ -0,0 +1,37 @@
+$input v_color0, v_texcoord0
+
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz
+
+#include "common.sh"
+
+// Samplers
+SAMPLER2D(s_tex, 0);
+SAMPLER2D(s_pal, 1);
+
+uniform vec4 u_tex_size0;
+uniform vec4 u_inv_tex_size0;
+uniform vec4 u_inv_tex_size1;
+
+void main()
+{
+ vec2 original_uv = v_texcoord0.xy * u_tex_size0.xy * vec2(2.0, 1.0);
+ float mod_val = mod(original_uv.x, 4.0);
+ vec2 rounded_uv = vec2(original_uv.x - mod_val, original_uv.y) * vec2(0.5, 1.0);
+
+ float inv_width = u_inv_tex_size0.x * 0.5;
+
+ vec2 palette_uv = vec2(0.0, 0.0);
+ if (mod_val < 2.0)
+ {
+ palette_uv.x = texture2D(s_tex, rounded_uv * u_inv_tex_size0.xy + vec2(inv_width * 0.5, 0.0)).r;
+ palette_uv.y = texture2D(s_tex, rounded_uv * u_inv_tex_size0.xy + vec2(inv_width * 1.5, 0.0)).r;
+ }
+ else
+ {
+ palette_uv.x = texture2D(s_tex, rounded_uv * u_inv_tex_size0.xy + vec2(inv_width * 2.5, 0.0)).r;
+ palette_uv.y = texture2D(s_tex, rounded_uv * u_inv_tex_size0.xy + vec2(inv_width * 3.5, 0.0)).r;
+ }
+
+ gl_FragColor = vec4(texture2D(s_pal, palette_uv * vec2(256.0, 256.0) * u_inv_tex_size1.xy).rgb, 1.0) * v_color0;
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/misc/fs_blit_rgb32.sc b/src/osd/modules/render/bgfx/shaders/chains/misc/fs_blit_rgb32.sc
new file mode 100644
index 00000000000..4292e6cddc6
--- /dev/null
+++ b/src/osd/modules/render/bgfx/shaders/chains/misc/fs_blit_rgb32.sc
@@ -0,0 +1,14 @@
+$input v_color0, v_texcoord0
+
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz
+
+#include "common.sh"
+
+// Samplers
+SAMPLER2D(s_tex, 0);
+
+void main()
+{
+ gl_FragColor = vec4(texture2D(s_tex, v_texcoord0).rgb, 1.0) * v_color0;
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/misc/fs_blit_yuy16.sc b/src/osd/modules/render/bgfx/shaders/chains/misc/fs_blit_yuy16.sc
new file mode 100644
index 00000000000..af3eb3e3954
--- /dev/null
+++ b/src/osd/modules/render/bgfx/shaders/chains/misc/fs_blit_yuy16.sc
@@ -0,0 +1,38 @@
+$input v_color0, v_texcoord0
+
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz
+
+#include "common.sh"
+
+// Samplers
+SAMPLER2D(s_tex, 0);
+
+uniform vec4 u_tex_size0;
+uniform vec4 u_inv_tex_size0;
+
+vec3 ycc_to_rgb(float y, float cb, float cr)
+{
+ float common = 1.168627 * (y - 0.062745);
+ float r = saturate(common + 1.603922 * (cr - 0.5));
+ float g = saturate(common - 0.392157 * (cb - 0.5) - 0.815686 * (cr - 0.5));
+ float b = saturate(common + 2.023529 * (cb - 0.5));
+ return vec3(r, g, b);
+}
+
+void main()
+{
+ vec2 half_texel = u_inv_tex_size0.xy * vec2(0.5, 0.5);
+
+ vec2 original_uv = v_texcoord0.xy * u_tex_size0.xy;
+ float mod_val = mod(original_uv.x, 2.0);
+ vec2 rounded_uv = vec2(original_uv.x - mod_val, original_uv.y);
+ vec4 srcpix = texture2D(s_tex, rounded_uv * u_inv_tex_size0.xy + half_texel.x);
+
+ float cr = srcpix.r;
+ float cb = srcpix.b;
+ if (mod_val < 1.0)
+ gl_FragColor = vec4(ycc_to_rgb(srcpix.g, cb, cr), 1.0) * v_color0;
+ else
+ gl_FragColor = vec4(ycc_to_rgb(srcpix.a, cb, cr), 1.0) * v_color0;
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/misc/fs_bob-and-ghost-deinterlace.sc b/src/osd/modules/render/bgfx/shaders/chains/misc/fs_bob-and-ghost-deinterlace.sc
index 45d38a0e020..d69e9a8f7bc 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/misc/fs_bob-and-ghost-deinterlace.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/misc/fs_bob-and-ghost-deinterlace.sc
@@ -7,7 +7,7 @@ $input v_color0, v_texcoord0
Bob-and-ghost Deinterlacing
Author: hunterk
License: Public domain
-
+
Note: This shader is designed to work with the typical interlaced output from an emulator, which displays both even and odd fields twice.
As such, it is inappropriate for general video use unless the video has already been similarly woven beforehand.
*/
@@ -30,7 +30,7 @@ void main()
float y;
// assume anything with a vertical resolution greater than 400 lines is interlaced
- if (u_tex_size0.y > 400.0)
+ if (u_tex_size0.y > 400.0)
{
y = u_tex_size0.y * v_texcoord0.y;// FIXME + IN.frame_count;
res = pow(vec4(texture2D(s0, v_texcoord0 + vec2(0.0, one_pixel.y))), exponent);
@@ -50,6 +50,6 @@ void main()
{
res = vec4(pow(texture2D(s0, v_texcoord0), exponent));
}
-
+
gl_FragColor = vec4(pow((res + color) / 2.0, inv_exponent));
}
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 cbff9f450e8..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
@@ -5,7 +5,7 @@ $input v_color0, v_texcoord0, v_texcoord1
/*
Hyllian's Deposterize Shader - Pass0
-
+
Copyright (C) 2011/2016 Hyllian/Jararaca - sergiogdb@gmail.com
*/
@@ -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 c6e0e87b018..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
@@ -5,7 +5,7 @@ $input v_color0, v_texcoord0, v_texcoord1
/*
Hyllian's Deposterize Shader - Pass1
-
+
Copyright (C) 2011/2016 Hyllian/Jararaca - sergiogdb@gmail.com
*/
@@ -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/fs_lut.sc b/src/osd/modules/render/bgfx/shaders/chains/misc/fs_lut.sc
index 2c8cffab7e1..6b00e4a1934 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/misc/fs_lut.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/misc/fs_lut.sc
@@ -5,9 +5,9 @@ $input v_color0, v_texcoord0
#include "common.sh"
-#define LUT_TEXTURE_WIDTH 4096.0f
-#define LUT_SIZE 64.0f
-#define LUT_SCALE vec2(1.0f / LUT_TEXTURE_WIDTH, 1.0f / LUT_SIZE)
+// Autos
+uniform vec4 u_tex_size1;
+uniform vec4 u_inv_tex_size1;
SAMPLER2D(s_tex, 0);
SAMPLER2D(s_3dlut, 1);
@@ -17,13 +17,12 @@ void main()
vec4 bp = texture2D(s_tex, v_texcoord0);
vec3 color = bp.rgb;
// NOTE: Do not change the order of parameters here.
- vec3 lutcoord = vec3(color.rg * ((LUT_SIZE - 1.0f) + 0.5f) *
- LUT_SCALE, (LUT_SIZE - 1.0f) * color.b);
+ vec3 lutcoord = vec3(color.rg * ((u_tex_size1.y - 1.0) + 0.5) * u_inv_tex_size1.xy, (u_tex_size1.y - 1.0) * color.b);
float shift = floor(lutcoord.z);
- lutcoord.x += shift * LUT_SCALE.y;
+ lutcoord.x += shift * u_inv_tex_size1.y;
color.rgb = mix(texture2D(s_3dlut, lutcoord.xy).rgb,
- texture2D(s_3dlut, vec2(lutcoord.x + LUT_SCALE.y,
+ texture2D(s_3dlut, vec2(lutcoord.x + u_inv_tex_size1.y,
lutcoord.y)).rgb, lutcoord.z - shift);
gl_FragColor = vec4(color, bp.a) * v_color0;
}
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 1c3b3ee592f..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
@@ -6,7 +6,7 @@ $output v_texcoord0, v_texcoord1, v_color0
/*
Hyllian's Deposterize Shader - Pass0 vertex shader
-
+
Copyright (C) 2011/2016 Hyllian/Jararaca - sergiogdb@gmail.com
*/
@@ -14,15 +14,19 @@ $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;
float dy = ps.y;
-
+
// This line fixes a bug in ATI cards.
v_texcoord0 = a_texcoord0 + vec2(0.0000001, 0.0000001);
v_texcoord1 = v_texcoord0.xxxy + vec4(-dx, 0, dx, 0); // D E F
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 7af87394655..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
@@ -6,7 +6,7 @@ $output v_texcoord0, v_texcoord1, v_color0
/*
Hyllian's Deposterize Shader - Pass1 vertex shader
-
+
Copyright (C) 2011/2016 Hyllian/Jararaca - sergiogdb@gmail.com
*/
@@ -14,15 +14,19 @@ $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;
float dy = ps.y;
-
+
// This line fixes a bug in ATI cards.
v_texcoord0 = a_texcoord0 + vec2(0.0000001, 0.0000001);
v_texcoord1 = v_texcoord0.xyyy + vec4(0, -dy, 0, dy); // D E F
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/fs_gaussian.sc b/src/osd/modules/render/bgfx/shaders/chains/pillarbox_left_horizontal/fs_gaussian.sc
index 5375561e8ac..cb6ecf95f0d 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/pillarbox_left_horizontal/fs_gaussian.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/pillarbox_left_horizontal/fs_gaussian.sc
@@ -22,7 +22,7 @@ SAMPLER2D(s_tex, 0);
void main()
{
vec4 sum = vec4(0.0, 0.0, 0.0, 0.0);
-
+
vec2 blur = (u_radius.xx * u_dimension.xy) / u_tex_size0.xy;
sum += texture2D(s_tex, v_texcoord0 - vec2(12.0, 12.0) * blur) * 0.001133;
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/fs_gaussian.sc b/src/osd/modules/render/bgfx/shaders/chains/pillarbox_left_vertical/fs_gaussian.sc
index 5375561e8ac..cb6ecf95f0d 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/pillarbox_left_vertical/fs_gaussian.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/pillarbox_left_vertical/fs_gaussian.sc
@@ -22,7 +22,7 @@ SAMPLER2D(s_tex, 0);
void main()
{
vec4 sum = vec4(0.0, 0.0, 0.0, 0.0);
-
+
vec2 blur = (u_radius.xx * u_dimension.xy) / u_tex_size0.xy;
sum += texture2D(s_tex, v_texcoord0 - vec2(12.0, 12.0) * blur) * 0.001133;
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/fs_gaussian.sc b/src/osd/modules/render/bgfx/shaders/chains/pillarbox_right_horizontal/fs_gaussian.sc
index 5375561e8ac..cb6ecf95f0d 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/pillarbox_right_horizontal/fs_gaussian.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/pillarbox_right_horizontal/fs_gaussian.sc
@@ -22,7 +22,7 @@ SAMPLER2D(s_tex, 0);
void main()
{
vec4 sum = vec4(0.0, 0.0, 0.0, 0.0);
-
+
vec2 blur = (u_radius.xx * u_dimension.xy) / u_tex_size0.xy;
sum += texture2D(s_tex, v_texcoord0 - vec2(12.0, 12.0) * blur) * 0.001133;
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/fs_gaussian.sc b/src/osd/modules/render/bgfx/shaders/chains/pillarbox_right_vertical/fs_gaussian.sc
index 5375561e8ac..cb6ecf95f0d 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/pillarbox_right_vertical/fs_gaussian.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/pillarbox_right_vertical/fs_gaussian.sc
@@ -22,7 +22,7 @@ SAMPLER2D(s_tex, 0);
void main()
{
vec4 sum = vec4(0.0, 0.0, 0.0, 0.0);
-
+
vec2 blur = (u_radius.xx * u_dimension.xy) / u_tex_size0.xy;
sum += texture2D(s_tex, v_texcoord0 - vec2(12.0, 12.0) * blur) * 0.001133;
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/fs_dilation-horizontal-fast.sc b/src/osd/modules/render/bgfx/shaders/chains/warp/fs_dilation-horizontal-fast.sc
index 3f03d8e6adb..d4ba6141c82 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/warp/fs_dilation-horizontal-fast.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/warp/fs_dilation-horizontal-fast.sc
@@ -5,7 +5,7 @@ $input v_texcoord0, v_texcoord1, v_color0
/*
Hyllian's dilation-horizontal-fast Shader
-
+
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -43,4 +43,4 @@ void main()
vec3 res = max(E, max(F, D));
gl_FragColor = vec4(res, 1.0);
-} \ No newline at end of file
+}
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 828dc3078cf..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
@@ -6,7 +6,7 @@ $output v_texcoord0, v_texcoord1, v_color0
/*
Hyllian's dilation-horizontal-fast Shader
-
+
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -32,20 +32,24 @@ $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;
float dx = ps.x;
float dy = ps.y;
- // B
- // D E F
- // H
+ // B
+ // 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/fs_xbr-lv1-noblend.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv1-noblend.sc
index 72212fa74a7..1963dfcd617 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv1-noblend.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv1-noblend.sc
@@ -5,7 +5,7 @@ $input v_texcoord0, v_texcoord1, v_color0
/*
Hyllian's xBR-lv1-noblend Shader
-
+
Copyright (C) 2011-2014 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -129,4 +129,4 @@ void main()
// final sum and weight normalization
gl_FragColor = vec4(res, 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv2-3d.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv2-3d.sc
index d9e44f0d4c7..988699a2642 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv2-3d.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv2-3d.sc
@@ -5,7 +5,7 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texcoo
/*
Hyllian's xBR-lv2-3d Shader
-
+
Copyright (C) 2011-2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -176,7 +176,7 @@ void main()
vec4 Ci = vec4(0.25, 0.25, 0.25, 0.25);
// These inequations define the line below which interpolation occurs.
- vec4 fx = (Ao*fp.y+Bo*fp.x);
+ vec4 fx = (Ao*fp.y+Bo*fp.x);
vec4 fx_left = (Ax*fp.y+Bx*fp.x);
vec4 fx_up = (Ay*fp.y+By*fp.x);
@@ -231,13 +231,13 @@ void main()
vec3 res1 = E.xyz;
res1 = mix(res1, mix(H.xyz, F.xyz, px.x), maximos.x);
res1 = mix(res1, mix(B.xyz, D.xyz, px.z), maximos.z);
-
+
vec3 res2 = E.xyz;
res2 = mix(res2, mix(F.xyz, B.xyz, px.y), maximos.y);
res2 = mix(res2, mix(D.xyz, H.xyz, px.w), maximos.w);
-
+
vec3 E_mix = (c_df(E.xyz, res2) >= c_df(E.xyz, res1)) ? vec3(1.0, 1.0, 1.0) : vec3(0.0, 0.0, 0.0);
vec3 res = mix(res1, res2, E_mix);
gl_FragColor = vec4(res, 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv2-fast.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv2-fast.sc
index 1b47172209e..b4d461cfca0 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv2-fast.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv2-fast.sc
@@ -5,7 +5,7 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_color0
/*
Hyllian's xBR-lv2-lq Shader
-
+
Copyright (C) 2011/2015 Hyllian/Jararaca - sergiogdb@gmail.com
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
@@ -121,7 +121,7 @@ void main()
vec4 Ci = vec4(0.25, 0.25, 0.25, 0.25);
// These inequations define the line below which interpolation occurs.
- vec4 fx = (Ao*fp.y+Bo*fp.x);
+ vec4 fx = (Ao*fp.y+Bo*fp.x);
vec4 fx_left = (Ax*fp.y+Bx*fp.x);
vec4 fx_up = (Ay*fp.y+By*fp.x);
@@ -166,13 +166,13 @@ void main()
vec3 res1 = E.xyz;
res1 = mix(res1, mix(H.xyz, F.xyz, px.x), maximos.x);
res1 = mix(res1, mix(B.xyz, D.xyz, px.z), maximos.z);
-
+
vec3 res2 = E.xyz;
res2 = mix(res2, mix(F.xyz, B.xyz, px.y), maximos.y);
res2 = mix(res2, mix(D.xyz, H.xyz, px.w), maximos.w);
-
+
vec3 E_mix = (c_df(E.xyz, res2) >= c_df(E.xyz, res1)) ? vec3(1.0, 1.0, 1.0) : vec3(0.0, 0.0, 0.0);
vec3 res = mix(res1, res2, E_mix);
gl_FragColor = vec4(res, 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv2-noblend.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv2-noblend.sc
index 80d7269349e..3168daf2ba8 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv2-noblend.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv2-noblend.sc
@@ -5,7 +5,7 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texcoo
/*
Hyllian's xBR-lv2-noblend Shader
-
+
Copyright (C) 2011-2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -148,7 +148,7 @@ void main()
#endif
interp_restriction_lv1 = clamp(interp_restriction_lv1, 0.0, 1.0);
-
+
vec4 interp_restriction_lv2_left = vec4(notEqual(e,g)) * vec4(notEqual(d,g));
vec4 interp_restriction_lv2_up = vec4(notEqual(e,c)) * vec4(notEqual(b,c));
@@ -174,4 +174,4 @@ void main()
vec3 res = mix(res1, res2, res_mix);
gl_FragColor = vec4(res, 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv2.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv2.sc
index 0294c56b84f..75a6dd3296f 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv2.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv2.sc
@@ -5,7 +5,7 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texcoo
/*
Hyllian's xBR-lv2 Shader
-
+
Copyright (C) 2011-2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -136,10 +136,10 @@ void main()
vec4 Ci = vec4(0.25, 0.25, 0.25, 0.25);
// These inequations define the line below which interpolation occurs.
- vec4 fx = (Ao*fp.y+Bo*fp.x);
+ vec4 fx = (Ao*fp.y+Bo*fp.x);
vec4 fx_left = (Ax*fp.y+Bx*fp.x);
vec4 fx_up = (Ay*fp.y+By*fp.x);
-
+
vec4 interp_restriction_lv0 = vec4(notEqual(e,f)) * vec4(notEqual(e,h));
vec4 interp_restriction_lv1 = interp_restriction_lv0;
@@ -191,7 +191,7 @@ void main()
vec3 res1 = E.xyz;
res1 = mix(res1, mix(H.xyz, F.xyz, px.x), maximos.x);
res1 = mix(res1, mix(B.xyz, D.xyz, px.z), maximos.z);
-
+
vec3 res2 = E.xyz;
res2 = mix(res2, mix(F.xyz, B.xyz, px.y), maximos.y);
res2 = mix(res2, mix(D.xyz, H.xyz, px.w), maximos.w);
@@ -200,4 +200,4 @@ void main()
vec3 res = mix(res1, res2, E_mix);
gl_FragColor = vec4(res, 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv3-noblend.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv3-noblend.sc
index 554c222db47..b13606724e5 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv3-noblend.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv3-noblend.sc
@@ -5,7 +5,7 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texcoo
/*
Hyllian's xBR-lv3-noblend - Shader
-
+
Copyright (C) 2011/2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -175,7 +175,7 @@ void main()
#endif
interp_restriction_lv1 = clamp(interp_restriction_lv1, 0.0, 1.0);
-
+
vec4 interp_restriction_lv2_left = vec4(notEqual(e,g)) * vec4(notEqual(d,g));
vec4 interp_restriction_lv2_up = vec4(notEqual(e,c)) * vec4(notEqual(b,c));
vec4 interp_restriction_lv3_left = eq2(g,g0) * vec4(notEqual(d0,g0));
@@ -186,11 +186,11 @@ void main()
vec4 one = vec4(1.0, 1.0, 1.0, 1.0);
vec4 zero = vec4(0.0, 0.0, 0.0, 0.0);
-
+
vec4 edri = vec4(lessThanEqual(wd1,wd2)) * interp_restriction_lv1;
vec4 edr = vec4(lessThan(wd1,wd2)) * interp_restriction_lv1 * ((1.0 - edri.yzwx) + (1.0 - edri.wxyz));
edr = clamp(edr, 0.0, 1.0);
-
+
vec4 hcDiff = df(h,c);
vec4 fgDiff = df(f,g);
vec4 edr_left = vec4(lessThanEqual(XBR_LV2_COEFFICIENT.xxxx * fgDiff, hcDiff)) * interp_restriction_lv2_left * edr * (1.0 - edri.yzwx) * eq(e,c);
@@ -210,4 +210,4 @@ void main()
vec3 res = mix(res1, res2, (df12.y >= df12.x) ? one.xyz : zero.xyz);
gl_FragColor = vec4(res, 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv3.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv3.sc
index 162461d145b..e6a4eb79edb 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv3.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/fs_xbr-lv3.sc
@@ -5,7 +5,7 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texcoo
/*
Hyllian's xBR-lv3 Shader
-
+
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -154,7 +154,7 @@ void main()
vec4 Cw = vec4( 5.0, -1.0, -3.0, 3.0 );
// These inequations define the line below which interpolation occurs.
- vec4 fx = (Ao * fp.y + Bo * fp.x);
+ vec4 fx = (Ao * fp.y + Bo * fp.x);
vec4 fx_left = (Ax * fp.y + Bx * fp.x);
vec4 fx_up = (Ay * fp.y + By * fp.x);
vec4 fx3_left= (Az * fp.y + Bz * fp.x);
@@ -189,7 +189,7 @@ void main()
vec4 edr = vec4(lessThan(weighted_distance(e, c, g, i, h5, f4, h, f), weighted_distance( h, d, i5, f, i4, b, e, i))) * interp_restriction_lv1;
vec4 edr_left = vec4(lessThanEqual(XBR_LV2_COEFFICIENT.xxxx * df(f,g), df(h,c))) * interp_restriction_lv2_left;
vec4 edr_up = vec4(greaterThanEqual(df(f,g), XBR_LV2_COEFFICIENT.xxxx * df(h,c))) * interp_restriction_lv2_up;
-
+
vec4 edr3_left = interp_restriction_lv3_left;
vec4 edr3_up = interp_restriction_lv3_up;
@@ -232,4 +232,4 @@ void main()
vec3 res = mix(res1, res2, E_mix);
gl_FragColor = vec4(res, 1.0);
-} \ No newline at end of file
+}
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 0abd7ff41c9..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
@@ -5,7 +5,7 @@ $input v_texcoord0, v_color0
/*
Hyllian's jinc windowed-jinc 2-lobe sharper with anti-ringing Shader
-
+
Copyright (C) 2011-2014 Hyllian/Jararaca - sergiogdb@gmail.com
*/
@@ -18,14 +18,14 @@ 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.
+// Increase A to get more blur. Decrease it to get a sharper picture.
// B = 0.825 to get rid of dithering. Increase B to get a fine sharpness, though dithering returns.
#define halfpi 1.5707963267948966192313216916398
@@ -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)
@@ -131,4 +131,4 @@ void main()
// final sum and weight normalization
gl_FragColor = vec4(color, 1);
-} \ No newline at end of file
+}
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 8fa47570af5..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
@@ -4,9 +4,9 @@ $input v_texcoord0, v_color0
// copyright-holders:Hyllian
/*
-
+
******* Super XBR 3D Shader - pass0 *******
-
+
Copyright (c) 2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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;
@@ -224,4 +224,4 @@ void main()
color = block_3d ? color : E.xyz;
gl_FragColor = vec4(color, 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-2xbr-3d-pass1.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-2xbr-3d-pass1.sc
index 72009ad3335..2af3f086523 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-2xbr-3d-pass1.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-2xbr-3d-pass1.sc
@@ -4,9 +4,9 @@ $input v_texcoord0, v_color0
// copyright-holders:Hyllian
/*
-
+
******* Super XBR 3D Shader - pass0 *******
-
+
Copyright (c) 2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -208,4 +208,4 @@ void main()
color = block_3d ? color : A;
gl_FragColor = vec4(color, 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-2xbr-3d-pass2.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-2xbr-3d-pass2.sc
index c2656424ed6..1f205de0a1b 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-2xbr-3d-pass2.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-2xbr-3d-pass2.sc
@@ -4,9 +4,9 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_color0
// copyright-holders:Hyllian
/*
-
+
******* Super XBR 3D Shader - pass2 *******
-
+
Copyright (c) 2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -210,4 +210,4 @@ void main()
color = block_3d ? color : A.xyz;
gl_FragColor = vec4(color, 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass0.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass0.sc
index 8a56a3899a6..389435952a7 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass0.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass0.sc
@@ -4,9 +4,9 @@ $input v_texcoord0, v_color0
// copyright-holders:Hyllian
/*
-
+
******* Super 4XBR 3D Shader - pass0 *******
-
+
Copyright (c) 2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -214,4 +214,4 @@ void main()
color = block_3d ? color : E.xyz;
gl_FragColor = vec4(color, 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass1.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass1.sc
index 10288b45f5a..1c805080595 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass1.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass1.sc
@@ -4,9 +4,9 @@ $input v_texcoord0, v_color0
// copyright-holders:Hyllian
/*
-
+
******* Super 4XBR 3D Shader - pass1 *******
-
+
Copyright (c) 2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -207,4 +207,4 @@ void main()
color = block_3d ? color : A.xyz;
gl_FragColor = vec4(color, 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass1f.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass1f.sc
index 51f2c6ea887..4587dc9cc93 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass1f.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass1f.sc
@@ -4,9 +4,9 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_color0
// copyright-holders:Hyllian
/*
-
+
******* Super 4XBR 3D Shader - pass1 *******
-
+
Copyright (c) 2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -208,4 +208,4 @@ void main()
color = block_3d ? color : A.xyz;
gl_FragColor = vec4(color, 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass2.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass2.sc
index f1566381325..1f9727021d7 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass2.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass2.sc
@@ -4,9 +4,9 @@ $input v_texcoord0, v_color0
// copyright-holders:Hyllian
/*
-
+
******* Super 4XBR 3D Shader - pass2 *******
-
+
Copyright (c) 2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -223,4 +223,4 @@ void main()
color = block_3d ? color : E.xyz;
gl_FragColor = vec4(color, 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass3.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass3.sc
index 3aa921a0e37..3e06eb4da47 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass3.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass3.sc
@@ -4,9 +4,9 @@ $input v_texcoord0, v_color0
// copyright-holders:Hyllian
/*
-
+
******* Super 4XBR 3D Shader - pass3 *******
-
+
Copyright (c) 2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -207,4 +207,4 @@ void main()
color = block_3d ? color : A.xyz;
gl_FragColor = vec4(color, 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass3f.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass3f.sc
index b417613a657..2b119f5d066 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass3f.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-4xbr-3d-pass3f.sc
@@ -4,9 +4,9 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_color0
// copyright-holders:Hyllian
/*
-
+
******* Super 4XBR 3D Shader - pass3 *******
-
+
Copyright (c) 2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -208,4 +208,4 @@ void main()
color = block_3d ? color : A.xyz;
gl_FragColor = vec4(color, 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-fast-pass0.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-fast-pass0.sc
index 84fc371a0a7..45bfdb1543b 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-fast-pass0.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-fast-pass0.sc
@@ -4,9 +4,9 @@ $input v_texcoord0, v_color0
// copyright-holders:Hyllian
/*
-
+
******* Super XBR Shader - pass0 *******
-
+
Copyright (c) 2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -161,9 +161,9 @@ void main()
vec4 d_mix = d_edge >= 0.0 ? vec4(1.0, 1.0, 1.0, 1.0) : vec4(0.0, 0.0, 0.0, 0.0);
vec4 min_sample = min4(E, F, H, I) + anti_ring * mix((P2-H)*(F-P1), (P0-E)*(I-P3), d_mix);
vec4 max_sample = max4(E, F, H, I) - anti_ring * mix((P2-H)*(F-P1), (P0-E)*(I-P3), d_mix);
-
+
color = clamp(color, min_sample.xyz, max_sample.xyz);
// color = mix(aux, color, 1-2.0*abs(edge_strength-0.5));
gl_FragColor = vec4(color, 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-fast-pass1.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-fast-pass1.sc
index d67c215de66..0248c9f2357 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-fast-pass1.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-fast-pass1.sc
@@ -4,9 +4,9 @@ $input v_texcoord0, v_color0
// copyright-holders:Hyllian
/*
-
+
******* Super XBR Shader - pass1 *******
-
+
Copyright (c) 2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -155,5 +155,5 @@ void main()
color = clamp(color, min_sample.xyz, max_sample.xyz);
// color = mix(aux, color, 1-2.0*abs(edge_strength-0.5));
- gl_FragColor = vec4(color, 1.0);
-} \ No newline at end of file
+ gl_FragColor = vec4(color, 1.0);
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-fast-pass2.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-fast-pass2.sc
index 89e82d00a31..546525c861d 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-fast-pass2.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-fast-pass2.sc
@@ -4,9 +4,9 @@ $input v_texcoord0, v_color0
// copyright-holders:Hyllian
/*
-
+
******* Super XBR Shader - pass1 *******
-
+
Copyright (c) 2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -158,5 +158,5 @@ void main()
color = clamp(color, min_sample.xyz, max_sample.xyz);
// color = mix(aux, color, 1-2.0*abs(edge_strength-0.5));
- gl_FragColor = vec4(color, 1.0);
-} \ No newline at end of file
+ gl_FragColor = vec4(color, 1.0);
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-pass0.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-pass0.sc
index a1158ebecca..ebae083c9c5 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-pass0.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-pass0.sc
@@ -4,9 +4,9 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_color0
// copyright-holders:Hyllian
/*
-
+
******* Super XBR Shader - pass0 *******
-
+
Copyright (c) 2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -157,4 +157,4 @@ void main()
color = clamp(color, min_sample.xyz, max_sample.xyz);
gl_FragColor = vec4(color, 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-pass1.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-pass1.sc
index 421fc78b58c..c99b19376cd 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-pass1.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-pass1.sc
@@ -4,9 +4,9 @@ $input v_texcoord0, v_color0
// copyright-holders:Hyllian
/*
-
+
******* Super XBR Shader - pass1 *******
-
+
Copyright (c) 2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -174,5 +174,5 @@ void main()
vec4 max_sample = max4(E, F, H, I) - anti_ring * mix((P2-H)*(F-P1), (P0-E)*(I-P3), d_mix);
color = clamp(color, min_sample.xyz, max_sample.xyz);
- gl_FragColor = vec4(color, 1.0);
-} \ No newline at end of file
+ gl_FragColor = vec4(color, 1.0);
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-pass2.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-pass2.sc
index c343dc155a2..0ac5170af33 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-pass2.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/super-xbr/fs_super-xbr-pass2.sc
@@ -4,9 +4,9 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_color0
// copyright-holders:Hyllian
/*
-
+
******* Super XBR Shader - pass1 *******
-
+
Copyright (c) 2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -166,5 +166,5 @@ void main()
vec4 max_sample = max4(E, F, H, I) - anti_ring * mix((P2-H)*(F-P1), (P0-E)*(I-P3), d_mix);
color = clamp(color, min_sample.xyz, max_sample.xyz);
- gl_FragColor = vec4(color, 1.0);
-} \ No newline at end of file
+ gl_FragColor = vec4(color, 1.0);
+}
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 ae3b049b57a..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
@@ -5,9 +5,9 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_color
// copyright-holders:Hyllian
/*
-
+
******* Super XBR 3D Shader - pass2 *******
-
+
Copyright (c) 2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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 67e2a4d6250..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
@@ -5,9 +5,9 @@ $output v_texcoord0, v_color0
// copyright-holders:Hyllian
/*
-
+
******* Super XBR Shader - pass0 vertex shader *******
-
+
Copyright (c) 2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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 d76ec041199..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
@@ -5,9 +5,9 @@ $output v_texcoord0, v_color0
// copyright-holders:Hyllian
/*
-
+
******* Super XBR Shader - pass1 vertex shader *******
-
+
Copyright (c) 2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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 579ee064622..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
@@ -5,9 +5,9 @@ $output v_texcoord0, v_color0
// copyright-holders:Hyllian
/*
-
+
******* Super XBR Shader - pass2 vertex shader *******
-
+
Copyright (c) 2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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 f03cc46e2b7..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
@@ -5,9 +5,9 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_color
// copyright-holders:Hyllian
/*
-
+
******* Super XBR Shader - pass0 vertex shader *******
-
+
Copyright (c) 2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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 67e2a4d6250..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
@@ -5,9 +5,9 @@ $output v_texcoord0, v_color0
// copyright-holders:Hyllian
/*
-
+
******* Super XBR Shader - pass0 vertex shader *******
-
+
Copyright (c) 2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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 51ffe87fcaa..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
@@ -5,9 +5,9 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_color
// copyright-holders:Hyllian
/*
-
+
******* Super XBR Shader - pass0 vertex shader *******
-
+
Copyright (c) 2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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 51ffe87fcaa..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
@@ -5,9 +5,9 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_color
// copyright-holders:Hyllian
/*
-
+
******* Super XBR Shader - pass0 vertex shader *******
-
+
Copyright (c) 2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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 75541985e36..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
@@ -6,7 +6,7 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
/*
Hyllian's xBR-lv2-noblend Shader
-
+
Copyright (C) 2011-2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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 5421eaf2955..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
@@ -6,7 +6,7 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
/*
Hyllian's xBR-lv3-noblend - Shader
-
+
Copyright (C) 2011/2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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 f4ee1f55ab3..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
@@ -6,7 +6,7 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
/*
Hyllian's xBR-lv3 - Shader
-
+
Copyright (C) 2011/2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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/fs_2xbr-hybrid-sharp.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-sharp.sc
index 533bfe0f762..6843efd251a 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-sharp.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-sharp.sc
@@ -5,7 +5,7 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texcoo
/*
Hyllian's 2xBR v3.7c+ReverseAA (squared) Shader
-
+
Copyright (C) 2011/2012 Hyllian/Jararaca - sergiogdb@gmail.com
*/
@@ -171,7 +171,7 @@ void main()
vec3 s = E.xyz;
vec3 n3 = H.xyz;
vec3 n4 = H5.xyz;
-
+
vec3 aa = n2 - n1;
vec3 bb = s - n2;
vec3 cc = n3 - s;
@@ -192,7 +192,7 @@ void main()
s = s1;
n3 = F.xyz;
n4 = F4.xyz;
-
+
aa = n2 - n1;
bb = s - n2;
cc = n3 - s;
@@ -333,4 +333,4 @@ void main()
}
gl_FragColor = vec4(res.xyz, 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v2-gamma.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v2-gamma.sc
index ea58584408b..46b2c3d9162 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v2-gamma.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v2-gamma.sc
@@ -5,7 +5,7 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texcoo
/*
Hyllian's 2xBR v3.8c+ReverseAA (squared) Shader - beta1
-
+
Copyright (C) 2011/2012 Hyllian/Jararaca - sergiogdb@gmail.com
*/
@@ -176,7 +176,7 @@ void main()
vec4 Cy = vec4( 2.0, 0.0, -1.0, 0.5 );
// These inequations define the line below which interpolation occurs.
- vec4 fx = (Ao*fp.y+Bo*fp.x);
+ vec4 fx = (Ao*fp.y+Bo*fp.x);
vec4 fx_left = (Ax*fp.y+Bx*fp.x);
vec4 fx_up = (Ay*fp.y+By*fp.x);
@@ -262,4 +262,4 @@ void main()
res = mix(res, pix, blend);
gl_FragColor = vec4(clamp(GAMMA_OUT(res), 0.0, 1.0), 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v2.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v2.sc
index a4e59937d54..cbb6659d0cd 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v2.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v2.sc
@@ -5,7 +5,7 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texcoo
/*
Hyllian's 2xBR v3.8c+ReverseAA (squared) Shader - Dithering preserved
-
+
Copyright (C) 2011/2012 Hyllian/Jararaca - sergiogdb@gmail.com
*/
@@ -169,7 +169,7 @@ void main()
vec4 Cy = vec4( 2.0, 0.0, -1.0, 0.5 );
// These inequations define the line below which interpolation occurs.
- vec4 fx = (Ao*fp.y+Bo*fp.x);
+ vec4 fx = (Ao*fp.y+Bo*fp.x);
vec4 fx_left = (Ax*fp.y+Bx*fp.x);
vec4 fx_up = (Ay*fp.y+By*fp.x);
@@ -252,4 +252,4 @@ void main()
res = mix(res, pix, blend);
gl_FragColor = vec4(res, 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v4-gamma.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v4-gamma.sc
index 254e8d878cb..45113f32e80 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v4-gamma.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v4-gamma.sc
@@ -5,7 +5,7 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texcoo
/*
Hyllian's 2xBR v3.8c+ReverseAA (squared) Shader - beta3
-
+
Copyright (C) 2011/2012 Hyllian/Jararaca - sergiogdb@gmail.com
*/
@@ -182,7 +182,7 @@ void main()
vec4 Cy = vec4( 2.0, 0.0, -1.0, 0.5 );
// These inequations define the line below which interpolation occurs.
- vec4 fx = (Ao*fp.y+Bo*fp.x);
+ vec4 fx = (Ao*fp.y+Bo*fp.x);
vec4 fx_left = (Ax*fp.y+Bx*fp.x);
vec4 fx_up = (Ay*fp.y+By*fp.x);
@@ -223,7 +223,7 @@ void main()
m = min(m, sharpness * abs(bb));
m = min(m, sharpness * abs(cc));
t = clamp(t, -m, m);
-
+
vec3 s1 = (2.0 * fp.y - 1.0) * t + s;
n1 = D0.xyz;
@@ -278,4 +278,4 @@ void main()
res = mix(res1, res2, step(c_df(E.xyz, res1), c_df(E.xyz, res2)));
gl_FragColor = vec4(clamp(GAMMA_OUT(res), 0.0, 1.0), 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v4.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v4.sc
index e3791fed702..efc8c57d752 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v4.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v4.sc
@@ -5,7 +5,7 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texcoo
/*
Hyllian's 2xBR v3.8c+ReverseAA (squared) Shader - v4
-
+
Copyright (C) 2011/2012 Hyllian/Jararaca - sergiogdb@gmail.com
*/
@@ -175,7 +175,7 @@ void main()
vec4 Cy = vec4( 2.0, 0.0, -1.0, 0.5 );
// These inequations define the line below which interpolation occurs.
- vec4 fx = (Ao*fp.y+Bo*fp.x);
+ vec4 fx = (Ao*fp.y+Bo*fp.x);
vec4 fx_left = (Ax*fp.y+Bx*fp.x);
vec4 fx_up = (Ay*fp.y+By*fp.x);
@@ -216,7 +216,7 @@ void main()
m = min(m, sharpness * abs(bb));
m = min(m, sharpness * abs(cc));
t = clamp(t, -m, m);
-
+
vec3 s1 = (2.0 * fp.y - 1.0) * t + s;
n1 = D0.xyz;
@@ -268,4 +268,4 @@ void main()
res = mix(res1, res2, step(c_df(E.xyz, res1), c_df(E.xyz, res2)));
gl_FragColor = vec4(res, 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v4b.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v4b.sc
index 858342d25c6..0beb806443b 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v4b.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v4b.sc
@@ -5,7 +5,7 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texcoo
/*
Hyllian's 2xBR v3.8b+ReverseAA (semi-rounded) Shader - v4
-
+
Copyright (C) 2011/2012 Hyllian/Jararaca - sergiogdb@gmail.com
*/
@@ -160,7 +160,7 @@ void main()
vec4 Cy = vec4( 2.0, 0.0, -1.0, 0.5 );
// These inequations define the line below which interpolation occurs.
- vec4 fx = (Ao*fp.y+Bo*fp.x);
+ vec4 fx = (Ao*fp.y+Bo*fp.x);
vec4 fx_left = (Ax*fp.y+Bx*fp.x);
vec4 fx_up = (Ay*fp.y+By*fp.x);
@@ -201,7 +201,7 @@ void main()
m = min(m, sharpness * abs(bb));
m = min(m, sharpness * abs(cc));
t = clamp(t, -m, m);
-
+
vec3 s1 = (2.0 * fp.y - 1.0) * t + s;
n1 = D0.xyz;
@@ -253,4 +253,4 @@ void main()
res = mix(res1, res2, step(c_df(E.xyz, res1), c_df(E.xyz, res2)));
gl_FragColor = vec4(res, 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v5-gamma.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v5-gamma.sc
index 1a4ad25e765..4e3c20169ec 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v5-gamma.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid-v5-gamma.sc
@@ -5,7 +5,7 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texcoo
/*
Hyllian's 2xBR v3.8c+ReverseAA (squared) Shader - beta3
-
+
Copyright (C) 2011/2012 Hyllian/Jararaca - sergiogdb@gmail.com
*/
@@ -182,7 +182,7 @@ void main()
vec4 Cy = vec4( 2.0, 0.0, -1.0, 0.5 );
// These inequations define the line below which interpolation occurs.
- vec4 fx = (Ao*fp.y+Bo*fp.x);
+ vec4 fx = (Ao*fp.y+Bo*fp.x);
vec4 fx_left = (Ax*fp.y+Bx*fp.x);
vec4 fx_up = (Ay*fp.y+By*fp.x);
@@ -223,7 +223,7 @@ void main()
m = min(m, sharpness * abs(bb));
m = min(m, sharpness * abs(cc));
t = clamp(t, -m, m);
-
+
vec3 s1 = (2.0 * fp.y - 1.0) * t + s;
n1 = D0.xyz;
@@ -285,4 +285,4 @@ void main()
res = mix(res, pix, blend);
gl_FragColor = vec4(clamp(GAMMA_OUT(res), 0.0, 1.0), 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid.sc
index bf3af2de385..aff101a1212 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-hybrid/fs_2xbr-hybrid.sc
@@ -5,7 +5,7 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texcoo
/*
Hyllian's 2xBR v3.7c+ReverseAA (squared) Shader
-
+
Copyright (C) 2011/2012 Hyllian/Jararaca - sergiogdb@gmail.com
*/
@@ -176,7 +176,7 @@ void main()
vec3 s = E.xyz;
vec3 n3 = H.xyz;
vec3 n4 = H5.xyz;
-
+
vec3 aa = n2 - n1;
vec3 bb = s - n2;
vec3 cc = n3 - s;
@@ -189,7 +189,7 @@ void main()
m = min(m, 2.0 * abs(cc));
vec3 sim1 = (gt3(abs(bb) * 2.0, threshold) + gt3(abs(cc) * 2.0, threshold) + le3(abs(bb) * 2.0, xx) + le3(abs(cc) * 2.0, xx));
t = clamp(t, -m, m);
-
+
vec3 s1 = (2.0 * fp.y - 1.0) * t + s;
n1 = D0.xyz;
@@ -197,7 +197,7 @@ void main()
s = s1;
n3 = F.xyz;
n4 = F4.xyz;
-
+
aa = n2 - n1;
bb = s - n2;
cc = n3 - s;
@@ -338,4 +338,4 @@ void main()
}
gl_FragColor = vec4(res.xyz, 1.0);
-} \ No newline at end of file
+}
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 339c44e284c..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
@@ -6,7 +6,7 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
/*
Hyllian's 2xBR v3.7c+ReverseAA (squared) Shader
-
+
Copyright (C) 2011/2012 Hyllian/Jararaca - sergiogdb@gmail.com
*/
@@ -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;
@@ -60,7 +64,7 @@ void main()
// G5 H5 I5
// This line fix a bug in ATI cards.
- vec2 texCoord = a_texcoord0 + vec2(0.0000001, 0.0000001);
+ vec2 texCoord = a_texcoord0 + vec2(0.0000001, 0.0000001);
v_texcoord1 = v_texcoord0.xxxy + vec4( -dx, 0.0, dx,-2.0*dy); // A1 B1 C1
v_texcoord2 = v_texcoord0.xxxy + vec4( -dx, 0.0, dx, -dy); // A B C
v_texcoord3 = v_texcoord0.xxxy + vec4( -dx, 0.0, dx, 0.0); // D E F
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 9d5468107dd..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
@@ -6,7 +6,7 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
/*
Hyllian's 2xBR v3.8c+ReverseAA (squared) Shader - beta1
-
+
Copyright (C) 2011/2012 Hyllian/Jararaca - sergiogdb@gmail.com
*/
@@ -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;
@@ -60,7 +64,7 @@ void main()
// G5 H5 I5
// This line fix a bug in ATI cards.
- vec2 texCoord = a_texcoord0 + vec2(0.0000001, 0.0000001);
+ vec2 texCoord = a_texcoord0 + vec2(0.0000001, 0.0000001);
v_texcoord1 = v_texcoord0.xxxy + vec4( -dx, 0.0, dx,-2.0*dy); // A1 B1 C1
v_texcoord2 = v_texcoord0.xxxy + vec4( -dx, 0.0, dx, -dy); // A B C
v_texcoord3 = v_texcoord0.xxxy + vec4( -dx, 0.0, dx, 0.0); // D E F
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 8e73b14f713..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
@@ -6,7 +6,7 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
/*
Hyllian's 2xBR v3.8c+ReverseAA (squared) Shader - Dithering preserved
-
+
Copyright (C) 2011/2012 Hyllian/Jararaca - sergiogdb@gmail.com
*/
@@ -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;
@@ -60,7 +64,7 @@ void main()
// G5 H5 I5
// This line fix a bug in ATI cards.
- vec2 texCoord = a_texcoord0 + vec2(0.0000001, 0.0000001);
+ vec2 texCoord = a_texcoord0 + vec2(0.0000001, 0.0000001);
v_texcoord1 = v_texcoord0.xxxy + vec4( -dx, 0.0, dx,-2.0*dy); // A1 B1 C1
v_texcoord2 = v_texcoord0.xxxy + vec4( -dx, 0.0, dx, -dy); // A B C
v_texcoord3 = v_texcoord0.xxxy + vec4( -dx, 0.0, dx, 0.0); // D E F
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 b4509adf38c..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
@@ -6,7 +6,7 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
/*
Hyllian's 2xBR v3.8c+ReverseAA (squared) Shader - beta3
-
+
Copyright (C) 2011/2012 Hyllian/Jararaca - sergiogdb@gmail.com
*/
@@ -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;
@@ -60,7 +64,7 @@ void main()
// G5 H5 I5
// This line fix a bug in ATI cards.
- vec2 texCoord = a_texcoord0 + vec2(0.0000001, 0.0000001);
+ vec2 texCoord = a_texcoord0 + vec2(0.0000001, 0.0000001);
v_texcoord1 = v_texcoord0.xxxy + vec4( -dx, 0.0, dx,-2.0*dy); // A1 B1 C1
v_texcoord2 = v_texcoord0.xxxy + vec4( -dx, 0.0, dx, -dy); // A B C
v_texcoord3 = v_texcoord0.xxxy + vec4( -dx, 0.0, dx, 0.0); // D E F
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 b00c03fbce3..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
@@ -6,7 +6,7 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
/*
Hyllian's 2xBR v3.8c+ReverseAA (squared) Shader - v4
-
+
Copyright (C) 2011/2012 Hyllian/Jararaca - sergiogdb@gmail.com
*/
@@ -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;
@@ -60,7 +64,7 @@ void main()
// G5 H5 I5
// This line fix a bug in ATI cards.
- vec2 texCoord = a_texcoord0 + vec2(0.0000001, 0.0000001);
+ vec2 texCoord = a_texcoord0 + vec2(0.0000001, 0.0000001);
v_texcoord1 = v_texcoord0.xxxy + vec4( -dx, 0.0, dx,-2.0*dy); // A1 B1 C1
v_texcoord2 = v_texcoord0.xxxy + vec4( -dx, 0.0, dx, -dy); // A B C
v_texcoord3 = v_texcoord0.xxxy + vec4( -dx, 0.0, dx, 0.0); // D E F
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 2a33ced4126..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
@@ -6,7 +6,7 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
/*
Hyllian's 2xBR v3.8b+ReverseAA (semi-rounded) Shader - v4
-
+
Copyright (C) 2011/2012 Hyllian/Jararaca - sergiogdb@gmail.com
*/
@@ -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;
@@ -60,7 +64,7 @@ void main()
// G5 H5 I5
// This line fix a bug in ATI cards.
- vec2 texCoord = a_texcoord0 + vec2(0.0000001, 0.0000001);
+ vec2 texCoord = a_texcoord0 + vec2(0.0000001, 0.0000001);
v_texcoord1 = v_texcoord0.xxxy + vec4( -dx, 0.0, dx,-2.0*dy); // A1 B1 C1
v_texcoord2 = v_texcoord0.xxxy + vec4( -dx, 0.0, dx, -dy); // A B C
v_texcoord3 = v_texcoord0.xxxy + vec4( -dx, 0.0, dx, 0.0); // D E F
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 b4509adf38c..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
@@ -6,7 +6,7 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
/*
Hyllian's 2xBR v3.8c+ReverseAA (squared) Shader - beta3
-
+
Copyright (C) 2011/2012 Hyllian/Jararaca - sergiogdb@gmail.com
*/
@@ -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;
@@ -60,7 +64,7 @@ void main()
// G5 H5 I5
// This line fix a bug in ATI cards.
- vec2 texCoord = a_texcoord0 + vec2(0.0000001, 0.0000001);
+ vec2 texCoord = a_texcoord0 + vec2(0.0000001, 0.0000001);
v_texcoord1 = v_texcoord0.xxxy + vec4( -dx, 0.0, dx,-2.0*dy); // A1 B1 C1
v_texcoord2 = v_texcoord0.xxxy + vec4( -dx, 0.0, dx, -dy); // A B C
v_texcoord3 = v_texcoord0.xxxy + vec4( -dx, 0.0, dx, 0.0); // D E F
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 339c44e284c..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
@@ -6,7 +6,7 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
/*
Hyllian's 2xBR v3.7c+ReverseAA (squared) Shader
-
+
Copyright (C) 2011/2012 Hyllian/Jararaca - sergiogdb@gmail.com
*/
@@ -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;
@@ -60,7 +64,7 @@ void main()
// G5 H5 I5
// This line fix a bug in ATI cards.
- vec2 texCoord = a_texcoord0 + vec2(0.0000001, 0.0000001);
+ vec2 texCoord = a_texcoord0 + vec2(0.0000001, 0.0000001);
v_texcoord1 = v_texcoord0.xxxy + vec4( -dx, 0.0, dx,-2.0*dy); // A1 B1 C1
v_texcoord2 = v_texcoord0.xxxy + vec4( -dx, 0.0, dx, -dy); // A B C
v_texcoord3 = v_texcoord0.xxxy + vec4( -dx, 0.0, dx, 0.0); // D E F
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-a-pass0.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-a-pass0.sc
index 5af6ea86cc4..37759601aad 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-a-pass0.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-a-pass0.sc
@@ -5,7 +5,7 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texcoo
/*
Hyllian's xBR LV2 A (squared) - pass0 Shader
-
+
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -156,4 +156,4 @@ void main()
info.z = dot(edr_up, vec4(8.0, 4.0, 2.0, 1.0));
gl_FragColor = vec4(remapTo01(info, vec3(0.0, 0.0, 0.0), vec3(255.0, 255.0, 255.0)), 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-accuracy-pass0.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-accuracy-pass0.sc
index 668922ec18c..5c1fb0c9d47 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-accuracy-pass0.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-accuracy-pass0.sc
@@ -5,7 +5,7 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texcoo
/*
Hyllian's xBR LV2 Accuracy - pass0 Shader
-
+
Copyright (C) 2011-2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -171,4 +171,4 @@ void main()
info.w = dot(edri, vec4(8.0, 4.0, 2.0, 1.0));
gl_FragColor = remapTo01(info, vec4(0.0, 0.0, 0.0, 0.0), vec4(255.0, 255.0, 255.0, 255.0));
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-accuracy-pass1.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-accuracy-pass1.sc
index a32605fca4e..19ebe21366f 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-accuracy-pass1.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-accuracy-pass1.sc
@@ -5,7 +5,7 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_color0
/*
Hyllian's xBR LV2 Accuracy - pass1 Shader
-
+
Copyright (C) 2011-2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -85,7 +85,7 @@ vec4 unpack_info(float i)
float frac_val = fract(i / 2.0f);
info.w = round(frac_val);
i = i / 2.0f - frac_val;
-
+
frac_val = fract(i / 2.0f);
info.z = round(frac_val);
i = i / 2.0f - frac_val;
@@ -118,7 +118,7 @@ void main()
mat4 h = mat4(H, F, B, D);
// These inequations define the line below which interpolation occurs.
- vec4 fx = (Ao*fp.y+Bo*fp.x);
+ vec4 fx = (Ao*fp.y+Bo*fp.x);
vec4 fx_left = (Ax*fp.y+Bx*fp.x);
vec4 fx_up = (Ay*fp.y+By*fp.x);
@@ -148,13 +148,13 @@ void main()
vec4 res1 = E;
res1 = mix(res1, mix(H, F, px.x), maximos.x);
res1 = mix(res1, mix(B, D, px.z), maximos.z);
-
+
vec4 res2 = E;
res2 = mix(res2, mix(F, B, px.y), maximos.y);
res2 = mix(res2, mix(D, H, px.w), maximos.w);
-
+
vec3 E_mix = (df1(E, res2) >= df1(E, res1)) ? vec3(1.0, 1.0, 1.0) : vec3(0.0, 0.0, 0.0);
vec3 res = mix(res1.xyz, res2.xyz, E_mix);
gl_FragColor = vec4(res, 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-b-pass0.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-b-pass0.sc
index 9f9c2836454..0b51db92660 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-b-pass0.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-b-pass0.sc
@@ -5,7 +5,7 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texcoo
/*
Hyllian's xBR LV2 B (squared) - pass0 Shader
-
+
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -157,4 +157,4 @@ void main()
info.z = dot(edr_up, vec4(8.0, 4.0, 2.0, 1.0));
gl_FragColor = vec4(remapTo01(info, vec3(0.0, 0.0, 0.0), vec3(255.0, 255.0, 255.0)), 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-c-pass0.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-c-pass0.sc
index e7cc84b299d..c03b2f83af4 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-c-pass0.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-c-pass0.sc
@@ -5,7 +5,7 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texcoo
/*
Hyllian's xBR LV2 C (squared) - pass0 Shader
-
+
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -119,15 +119,15 @@ void main()
vec4 interp_restriction_lv1 = clamp(vec4(notEqual(e,f)) * vec4(notEqual(e,h)) * ( neq(f,b) * neq(f,c) + neq(h,d) * neq(h,g) + eq(e,i) * (neq(f,f4) * neq(f,i4) + neq(h,h5) * neq(h,i5)) + eq(e,g) + eq(e,c)), vec4(0.0, 0.0, 0.0, 0.0), vec4(1.0, 1.0, 1.0, 1.0));
vec4 interp_restriction_lv2_left = vec4(notEqual(e,g)) * vec4(notEqual(d,g));
vec4 interp_restriction_lv2_up = vec4(notEqual(e,c)) * vec4(notEqual(b,c));
-
+
vec4 edr = vec4(lessThan(weighted_distance(e, c, g, i, h5, f4, h, f), weighted_distance(h, d, i5, f, i4, b, e, i))) * interp_restriction_lv1;
vec4 edr_left = vec4(lessThanEqual(coef * df(f,g), df(h,c))) * interp_restriction_lv2_left * edr;
vec4 edr_up = vec4(greaterThanEqual(df(f,g), coef * df(h,c))) * interp_restriction_lv2_up * edr;
-
+
vec3 info;
info.x = dot(edr, vec4(8.0, 4.0, 2.0, 1.0));
info.y = dot(edr_left, vec4(8.0, 4.0, 2.0, 1.0));
info.z = dot(edr_up, vec4(8.0, 4.0, 2.0, 1.0));
gl_FragColor = vec4(remapTo01(info, vec3(0.0, 0.0, 0.0), vec3(255.0, 255.0, 255.0)), 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-d-pass0.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-d-pass0.sc
index c168b2622a7..e19f6be1eca 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-d-pass0.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-d-pass0.sc
@@ -5,7 +5,7 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texcoo
/*
Hyllian's xBR LV2 D (squared) - pass0 Shader
-
+
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -149,7 +149,7 @@ void main()
vec4 interp_restriction_lv2_up = (ne(e,c) * ne(b,c));
interp_restriction_lv1 = clamp(interp_restriction_lv1, 0.0, 1.0);
-
+
vec4 edr = lt(weighted_distance(e, c, g, i, h5, f4, h, f), weighted_distance(h, d, i5, f, i4, b, e, i)) * interp_restriction_lv1;
vec4 edr_left = le(coef * df(f,g), df(h,c)) * interp_restriction_lv2_left * edr;
vec4 edr_up = ge(df(f,g), coef * df(h,c)) * interp_restriction_lv2_up * edr;
@@ -160,4 +160,4 @@ void main()
info.z = dot(vec4(edr_up ), vec4(8.0, 4.0, 2.0, 1.0));
gl_FragColor = vec4(remapTo01(info, vec3(0.0, 0.0, 0.0), vec3(255.0, 255.0, 255.0)), 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-noblend-pass1.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-noblend-pass1.sc
index c46dd90ba0a..4d15482b4c6 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-noblend-pass1.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-noblend-pass1.sc
@@ -5,7 +5,7 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_color0
/*
Hyllian's xBR LV2 - noblend - pass1 Shader
-
+
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -94,7 +94,7 @@ vec4 unpack_info(float i)
float frac_val = fract(i / 2.0f);
info.w = round(frac_val);
i = i / 2.0f - frac_val;
-
+
frac_val = fract(i / 2.0f);
info.z = round(frac_val);
i = i / 2.0f - frac_val;
@@ -159,4 +159,4 @@ void main()
vec3 res = mix(res1, res2, step(df12.x, df12.y));
gl_FragColor = vec4(res, 1.0);
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-pass1.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-pass1.sc
index 6316e485725..b5de4e02fbf 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-pass1.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv2-multipass/fs_xbr-lv2-pass1.sc
@@ -5,7 +5,7 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_color0
/*
Hyllian's xBR LV2 - pass1 Shader
-
+
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -57,7 +57,7 @@ vec4 unpack_info(float i)
float frac_val = fract(i / 2.0f);
info.w = round(frac_val);
i = i / 2.0f - frac_val;
-
+
frac_val = fract(i / 2.0f);
info.z = round(frac_val);
i = i / 2.0f - frac_val;
@@ -100,7 +100,7 @@ void main()
vec4 Cy = vec4(2.0, 0.0, -1.0, 0.5);
// These inequations define the line below which interpolation occurs.
- vec4 fx = (Ao*fp.y+Bo*fp.x);
+ vec4 fx = (Ao*fp.y+Bo*fp.x);
vec4 fx_left = (Ax*fp.y+Bx*fp.x);
vec4 fx_up = (Ay*fp.y+By*fp.x);
@@ -128,7 +128,7 @@ void main()
mat4 pix = mat4(mix(E, mix(H, F, px.x), maximo.x), mix(E, mix(F, B, px.y), maximo.y), mix(E, mix(B, D, px.z), maximo.z), mix(E, mix(D, H, px.w), maximo.w));
vec4 pixel = instMul(yuv_weighted, pix);
-
+
vec4 diff = df(pixel,e);
vec3 res = pix[0].xyz;
@@ -150,4 +150,4 @@ void main()
}
gl_FragColor = vec4(res, 1.0);
-} \ No newline at end of file
+}
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 3a80bf6f7bb..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
@@ -6,7 +6,7 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
/*
Hyllian's xBR LV2 A (squared) - pass0 Shader
-
+
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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 4cd8b064523..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
@@ -6,7 +6,7 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
/*
Hyllian's xBR LV2 Accuracy - pass0 Shader
-
+
Copyright (C) 2011-2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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 c20050aa1f4..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
@@ -6,7 +6,7 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_color0
/*
Hyllian's xBR LV2 Accuracy - pass1 Shader
-
+
Copyright (C) 2011-2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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 5515f4f4904..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
@@ -6,7 +6,7 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
/*
Hyllian's xBR LV2 B (squared) - pass0 Shader
-
+
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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 9d0b7161844..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
@@ -6,7 +6,7 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
/*
Hyllian's xBR LV2 C (squared) - pass0 Shader
-
+
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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 8f9b4f316d9..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
@@ -6,7 +6,7 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
/*
Hyllian's xBR LV2 D (squared) - pass0 Shader
-
+
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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 86df31a48e4..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
@@ -6,7 +6,7 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_color0
/*
Hyllian's xBR LV2 - noblend - pass1 Shader
-
+
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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 d678e8b0541..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
@@ -6,7 +6,7 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_color0
/*
Hyllian's xBR LV2 - pass1 Shader
-
+
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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 e9328bb4015..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
@@ -5,7 +5,7 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texcoo
/*
Hyllian's xBR level 3 pass0 Shader
-
+
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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); \
- } \
+ }
@@ -213,4 +213,4 @@ void main()
lin0.w, lin1.w, lin2.w, lin3.w));
gl_FragColor = vec4(remapTo01(info, vec4(255.0, 255.0, 255.0, 255.0)));
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv3-multipass/fs_xbr-lv3-pass1.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv3-multipass/fs_xbr-lv3-pass1.sc
index df6d0a72265..407aaf2aaf6 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv3-multipass/fs_xbr-lv3-pass1.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-lv3-multipass/fs_xbr-lv3-pass1.sc
@@ -5,7 +5,7 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_color0
/*
Hyllian's xBR level 3 pass1 Shader
-
+
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -70,7 +70,7 @@ vec4 unpack_info(float i)
float frac_val = fract(i / 2.0f);
info.w = round(frac_val);
i = i / 2.0f - frac_val;
-
+
frac_val = fract(i / 2.0f);
info.z = round(frac_val);
i = i / 2.0f - frac_val;
@@ -124,7 +124,7 @@ void main()
info_nr = info_nr / 2.0 - frac_val;
info_nr = info_nr / 2.0 - fract(info_nr / 2.0);
info_nr = info_nr / 2.0 - fract(info_nr / 2.0);
-
+
frac_val = fract(info_nr / 2.0);
float pxr = round(frac_val);
info_nr = info_nr / 2.0 - frac_val;
@@ -177,4 +177,4 @@ void main()
}
gl_FragColor = vec4(color, 1.0);
-} \ No newline at end of file
+}
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 d4420512bd4..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
@@ -6,7 +6,7 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
/*
Hyllian's xBR level 3 pass0 Shader
-
+
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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 edfd9fa3dd9..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
@@ -6,7 +6,7 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_color0
/*
Hyllian's xBR level 3 pass1 Shader
-
+
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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-pass1.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/fs_xbr-mlv4-pass1.sc
index fe2e3188052..1fe133cebfc 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/fs_xbr-mlv4-pass1.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/fs_xbr-mlv4-pass1.sc
@@ -6,7 +6,7 @@ $input v_texcoord0, v_texcoord1, v_color0
/*
Hyllian's xBR MultiLevel4 Shader - Pass1
-
+
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -43,7 +43,7 @@ const vec4 eq_thresholdold = vec4(15.0, 15.0, 15.0, 15.0);
const vec4 eq_threshold = vec4( 2.0, 2.0, 2.0, 2.0);
const vec4 eq_threshold3 = vec4(25.0, 25.0, 25.0, 25.0);
const vec4 yuv_weight = vec4( 4.0, 1.0, 2.0, 0.0);
-const mat4 yuvT = mat4(0.299, -0.169, 0.499, 0.0, 0.587, -0.331, -0.418, 0.0, 0.114, 0.499, -0.0813, 0.0, 0.0, 0.0, 0.0, 0.0);
+const mat4 yuvT = mat4(0.299, -0.169, 0.499, 0.0, 0.587, -0.331, -0.418, 0.0, 0.114, 0.499, -0.0813, 0.0, 0.0, 0.0, 0.0, 0.0);
const mat4 yuv = mat4(0.299, 0.587, 0.114, 0.0, -0.169, -0.331, 0.499, 0.0, 0.499, -0.418, -0.0813, 0.0, 0.0, 0.0, 0.0, 0.0);
const mat4 yuv_weighted = mat4(4.0 * vec4(0.299, 0.587, 0.114, 0.0), 2.0 * vec4(-0.169, -0.331, 0.499, 0.0), vec4(0.499, -0.418, -0.0813, 0.0), vec4(0.0, 0.0, 0.0, 0.0));
const vec4 maximo = vec4(255.0, 255.0, 255.0, 255.0);
@@ -111,7 +111,7 @@ vec4 weighted_distance(vec4 a, vec4 b, vec4 c, vec4 d, vec4 e, vec4 f, vec4 g, v
void main()
{
- vec4 A3 = TEX(-1,-3); vec4 B3 = TEX( 0,-3); vec4 C3 = TEX( 1,-3);
+ vec4 A3 = TEX(-1,-3); vec4 B3 = TEX( 0,-3); vec4 C3 = TEX( 1,-3);
vec4 A1 = TEX(-1,-2); vec4 B1 = TEX( 0,-2); vec4 C1 = TEX( 1,-2);
vec4 A2 = TEX(-3,-1); vec4 A0 = TEX(-2,-1); vec4 A = TEX(-1,-1);
vec4 B = TEX( 0,-1); vec4 C = TEX( 1,-1); vec4 C4 = TEX( 2,-1); vec4 C6 = TEX( 3,-1);
@@ -205,4 +205,4 @@ void main()
info.w = (edr4_left.w > 0.0 && edr4_up.w == 0.0) ? 8.0 : ((edr4_up.w > 0.0 && edr4_left.w == 0.0) ? 7.0 : ((edr3_left.w > 0.0 && edr3_up.w == 0.0) ? 6.0 : ((edr3_up.w > 0.0 && edr3_left.w == 0.0) ? 5.0 : ((edr_left.w > 0.0 && edr_up.w == 0.0) ? 4.0 : ((edr_up.w > 0.0 && edr_left.w == 0.0) ? 3.0 : (edr.w > 0.0 ? 2.0 : (edr0.w > 0.0 ? 1.0 : 0.0)))))));
gl_FragColor = vec4(remapTo01(info, maximo));
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/fs_xbr-mlv4-pass2.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/fs_xbr-mlv4-pass2.sc
index b0e0edf7778..7c2906246e6 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/fs_xbr-mlv4-pass2.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/fs_xbr-mlv4-pass2.sc
@@ -6,7 +6,7 @@ $input v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texcoo
/*
Hyllian's xBR MultiLevel4 Shader - Pass2
-
+
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -225,11 +225,11 @@ void main()
vec4 jag9 = clamp(jag91 * jag93 + jag92 * jag94 , 0.0, 1.0);
vec4 pe_select = eq(pe, zero) + ((one - nbrs) + jag1) * jag9;
-
+
pe.x = pe_select.x > 0.0 ? pe.x : 1.0;
pe.y = pe_select.y > 0.0 ? pe.y : 1.0;
pe.z = pe_select.z > 0.0 ? pe.z : 1.0;
pe.w = pe_select.w > 0.0 ? pe.w : 1.0;
gl_FragColor = vec4(remapTo01(pe, maximo));
-} \ No newline at end of file
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/fs_xbr-mlv4-pass3.sc b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/fs_xbr-mlv4-pass3.sc
index 00391c77120..07490274d70 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/fs_xbr-mlv4-pass3.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/xbr/xbr-mlv4-multipass/fs_xbr-mlv4-pass3.sc
@@ -6,7 +6,7 @@ $input v_texcoord0, v_texcoord1, v_color0
/*
Hyllian's xBR MultiLevel4 Shader - Pass3
-
+
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -169,4 +169,4 @@ void main()
lparam.w = addr.x * 8.0 + addr.y;
gl_FragColor = vec4(remapTo01(lparam, low, high));
-} \ No newline at end of file
+}
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 535f70a5a7d..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
@@ -6,7 +6,7 @@ $input v_texcoord0, v_texcoord1, v_color0
/*
Hyllian's xBR MultiLevel4 Shader - Pass3
-
+
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -62,7 +62,7 @@ vec4 unpack_info(float i)
float frac_val = fract(i / 2.0f);
info.w = round(frac_val);
i = i / 2.0f - frac_val;
-
+
frac_val = fract(i / 2.0f);
info.z = round(frac_val);
i = i / 2.0f - frac_val;
@@ -110,13 +110,13 @@ 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()
{
float scale_factor = u_target_size.x / u_tex_size1.x;
-
+
vec2 fp = fract(v_texcoord0 * u_tex_size1.xy) - vec2(0.5, 0.5); // pos = pixel position
vec4 UL = texture2D(decal, v_texcoord0 + 0.25 * v_texcoord1.xy + 0.25 * v_texcoord1.zw);
@@ -161,4 +161,4 @@ void main()
color = color_mix(c4, color, E.xyz);
gl_FragColor = vec4(color, 1.0);
-} \ No newline at end of file
+}
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 bab183ddd30..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
@@ -7,7 +7,7 @@ $output v_texcoord0, v_texcoord1, v_color0
/*
Hyllian's xBR MultiLevel4 Shader - Pass1
-
+
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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 71ebf7d574a..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
@@ -7,7 +7,7 @@ $output v_texcoord0, v_texcoord1, v_texcoord2, v_texcoord3, v_texcoord4, v_texco
/*
Hyllian's xBR MultiLevel4 Shader - Pass2
-
+
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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 19195ba5b27..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
@@ -7,7 +7,7 @@ $output v_texcoord0, v_texcoord1, v_color0
/*
Hyllian's xBR MultiLevel4 Shader - Pass3
-
+
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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 bf9f297ec9d..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
@@ -7,7 +7,7 @@ $output v_texcoord0, v_texcoord1, v_color0
/*
Hyllian's xBR MultiLevel4 Shader - Pass4
-
+
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -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/fs_screen.sc b/src/osd/modules/render/bgfx/shaders/fs_screen.sc
index 52dac92785c..ab1bff59dee 100644
--- a/src/osd/modules/render/bgfx/shaders/fs_screen.sc
+++ b/src/osd/modules/render/bgfx/shaders/fs_screen.sc
@@ -6,7 +6,7 @@ $input v_color0, v_texcoord0
#include "common.sh"
// Samplers
-SAMPLER2D(s_tex, 0);
+SAMPLER2D(s_tex, 0);
void main()
{
diff --git a/src/osd/modules/render/bgfx/shaders/makefile b/src/osd/modules/render/bgfx/shaders/makefile
index 1ca45471b9b..c998f2564d9 100644
--- a/src/osd/modules/render/bgfx/shaders/makefile
+++ b/src/osd/modules/render/bgfx/shaders/makefile
@@ -12,25 +12,28 @@ SUBDIRS := $(patsubst .,,$(patsubst ./,,$(shell find . -type d)))
rebuild: main $(SUBDIRS)
endif
+.NOTPARALLEL:
$(SUBDIRS):
@echo $@
ifeq ($(OS),windows)
- @make -s --no-print-directory TARGET=0 SHADERS_DIR=$@/ clean all
- @make -s --no-print-directory TARGET=1 SHADERS_DIR=$@/ clean all
+ $(SILENT) $(MAKE) --no-print-directory TARGET=0 SHADERS_DIR=$@/ clean all SILENT="$(SILENT)"
+ $(SILENT) $(MAKE) --no-print-directory TARGET=1 SHADERS_DIR=$@/ clean all SILENT="$(SILENT)"
endif
- @make -s --no-print-directory TARGET=2 SHADERS_DIR=$@/ clean all
- @make -s --no-print-directory TARGET=3 SHADERS_DIR=$@/ clean all
- @make -s --no-print-directory TARGET=4 SHADERS_DIR=$@/ clean all
- @make -s --no-print-directory TARGET=5 SHADERS_DIR=$@/ clean all
+ $(SILENT) $(MAKE) --no-print-directory TARGET=2 SHADERS_DIR=$@/ clean all SILENT="$(SILENT)"
+ $(SILENT) $(MAKE) --no-print-directory TARGET=3 SHADERS_DIR=$@/ clean all SILENT="$(SILENT)"
+ $(SILENT) $(MAKE) --no-print-directory TARGET=4 SHADERS_DIR=$@/ clean all SILENT="$(SILENT)"
+ $(SILENT) $(MAKE) --no-print-directory TARGET=5 SHADERS_DIR=$@/ clean all SILENT="$(SILENT)"
+ $(SILENT) $(MAKE) --no-print-directory TARGET=7 SHADERS_DIR=$@/ clean all SILENT="$(SILENT)"
main:
ifeq ($(OS),windows)
- @make -s --no-print-directory TARGET=0 clean all
- @make -s --no-print-directory TARGET=1 clean all
+ $(SILENT) $(MAKE) --no-print-directory TARGET=0 clean all SILENT="$(SILENT)"
+ $(SILENT) $(MAKE) --no-print-directory TARGET=1 clean all SILENT="$(SILENT)"
endif
- @make -s --no-print-directory TARGET=2 clean all
- @make -s --no-print-directory TARGET=3 clean all
- @make -s --no-print-directory TARGET=4 clean all
- @make -s --no-print-directory TARGET=5 clean all
+ $(SILENT) $(MAKE) --no-print-directory TARGET=2 clean all SILENT="$(SILENT)"
+ $(SILENT) $(MAKE) --no-print-directory TARGET=3 clean all SILENT="$(SILENT)"
+ $(SILENT) $(MAKE) --no-print-directory TARGET=4 clean all SILENT="$(SILENT)"
+ $(SILENT) $(MAKE) --no-print-directory TARGET=5 clean all SILENT="$(SILENT)"
+ $(SILENT) $(MAKE) --no-print-directory TARGET=7 clean all SILENT="$(SILENT)"
.PHONY: main rebuild $(SUBDIRS)
diff --git a/src/osd/modules/render/bgfx/shaders/shader.mk b/src/osd/modules/render/bgfx/shaders/shader.mk
index e7db3cdc242..cc656d5e828 100644
--- a/src/osd/modules/render/bgfx/shaders/shader.mk
+++ b/src/osd/modules/render/bgfx/shaders/shader.mk
@@ -1,6 +1,6 @@
#
-# Copyright 2011-2019 Branimir Karadzic. All rights reserved.
-# License: http://www.opensource.org/licenses/BSD-2-Clause
+# Copyright 2011-2021 Branimir Karadzic.
+# License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
#
THISDIR:=../../../../../../3rdparty/bgfx/scripts
@@ -19,25 +19,51 @@ ifndef TARGET
.PHONY: all
all:
@echo Usage: make TARGET=# [clean, all, rebuild]
- @echo " TARGET=0 (hlsl - d3d9)"
- @echo " TARGET=1 (hlsl - d3d11)"
- @echo " TARGET=2 (essl - nacl)"
+ @echo " TARGET=0 (hlsl - d3d9 / Windows only!)"
+ @echo " TARGET=1 (hlsl - d3d11 / Windows only!)"
@echo " TARGET=3 (essl - android)"
@echo " TARGET=4 (glsl)"
@echo " TARGET=5 (metal)"
@echo " TARGET=6 (pssl)"
- @echo " TARGET=7 (spriv)"
- @echo " VERBOSE=1 show build commands."
+ @echo " TARGET=7 (spirv)"
+
+.PHONY: build
+build:
+ifeq ($(OS), windows)
+ @make -s --no-print-directory TARGET=0 all
+ @make -s --no-print-directory TARGET=1 all
+endif
+ @make -s --no-print-directory TARGET=3 all
+ @make -s --no-print-directory TARGET=4 all
+ @make -s --no-print-directory TARGET=5 all
+ @make -s --no-print-directory TARGET=7 all
+
+.PHONY: clean
+clean:
+ifeq ($(OS), windows)
+ @make -s --no-print-directory TARGET=0 clean
+ @make -s --no-print-directory TARGET=1 clean
+endif
+ @make -s --no-print-directory TARGET=3 clean
+ @make -s --no-print-directory TARGET=4 clean
+ @make -s --no-print-directory TARGET=5 clean
+ @make -s --no-print-directory TARGET=7 clean
+
+.PHONY: rebuild
+rebuild: clean build
+
else
+ADDITIONAL_INCLUDES?=
+
ifeq ($(TARGET), 0)
VS_FLAGS=--platform windows -p vs_3_0 -O 3
FS_FLAGS=--platform windows -p ps_3_0 -O 3
SHADER_PATH=shaders/dx9/$(SHADERS_DIR)
else
ifeq ($(TARGET), 1)
-VS_FLAGS=--platform windows -p vs_4_0 -O 3
-FS_FLAGS=--platform windows -p ps_4_0 -O 3
+VS_FLAGS=--platform windows -p vs_5_0 -O 3
+FS_FLAGS=--platform windows -p ps_5_0 -O 3
CS_FLAGS=--platform windows -p cs_5_0 -O 1
SHADER_PATH=shaders/dx11/$(SHADERS_DIR)
else
@@ -108,44 +134,38 @@ CS_BIN = $(addprefix $(BUILD_INTERMEDIATE_DIR)/, $(addsuffix .bin, $(basename $(
BIN = $(VS_BIN) $(FS_BIN)
ASM = $(VS_ASM) $(FS_ASM)
-ifeq ($(TARGET), 1)
+ifeq ($(TARGET), $(filter $(TARGET),1 3 4 5 6 7))
BIN += $(CS_BIN)
ASM += $(CS_ASM)
-else
-ifeq ($(TARGET), 3)
-BIN += $(CS_BIN)
-ASM += $(CS_ASM)
-else
-ifeq ($(TARGET), 4)
-BIN += $(CS_BIN)
-ASM += $(CS_ASM)
-endif
-endif
endif
-$(BUILD_INTERMEDIATE_DIR)/vs_%.bin : $(SHADERS_DIR)vs_%.sc
+$(BUILD_INTERMEDIATE_DIR)/vs_%.bin: $(SHADERS_DIR)vs_%.sc
@echo [$(<)]
$(SILENT) $(SHADERC) $(VS_FLAGS) --type vertex --depends -o $(@) -f $(<) --disasm
$(SILENT) cp $(@) $(BUILD_OUTPUT_DIR)/$(@F)
-$(BUILD_INTERMEDIATE_DIR)/fs_%.bin : $(SHADERS_DIR)fs_%.sc
+$(BUILD_INTERMEDIATE_DIR)/fs_%.bin: $(SHADERS_DIR)fs_%.sc
@echo [$(<)]
$(SILENT) $(SHADERC) $(FS_FLAGS) --type fragment --depends -o $(@) -f $(<) --disasm
$(SILENT) cp $(@) $(BUILD_OUTPUT_DIR)/$(@F)
-$(BUILD_INTERMEDIATE_DIR)/cs_%.bin : $(SHADERS_DIR)cs_%.sc
+$(BUILD_INTERMEDIATE_DIR)/cs_%.bin: $(SHADERS_DIR)cs_%.sc
@echo [$(<)]
$(SILENT) $(SHADERC) $(CS_FLAGS) --type compute --depends -o $(@) -f $(<) --disasm
$(SILENT) cp $(@) $(BUILD_OUTPUT_DIR)/$(@F)
.PHONY: all
all: dirs $(BIN)
- @echo Target $(SHADER_PATH)
+ @echo Target $(notdir $(CURDIR)) / $(SHADER_PATH)
.PHONY: clean
clean:
@echo Cleaning...
@-rm -vf $(BIN)
+
+.PHONY: cleanall
+cleanall:
+ @echo Cleaning...
@-$(call CMD_RMDIR,$(BUILD_INTERMEDIATE_DIR))
.PHONY: dirs
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 0cc97275497..dcd64c0c865 100644
--- a/src/osd/modules/render/bgfx/slider.cpp
+++ b/src/osd/modules/render/bgfx/slider.cpp
@@ -6,13 +6,15 @@
//
//============================================================
-#include "emu.h"
-
#include "slider.h"
#include "../frontend/mame/ui/slider.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 "strformat.h"
+
+#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)
@@ -25,7 +27,7 @@ bgfx_slider::bgfx_slider(running_machine &machine, std::string name, float min,
m_max = max;
m_value = def;
- for (std::string string : strings)
+ for (const std::string &string : strings)
{
m_strings.push_back(string);
}
@@ -37,38 +39,21 @@ bgfx_slider::~bgfx_slider()
{
}
-int32_t bgfx_slider::slider_changed(running_machine& /*machine*/, void *arg, int /*id*/, std::string *str, int32_t newval)
-{
- if (arg != nullptr)
- {
- return reinterpret_cast<bgfx_slider*>(arg)->update(str, newval);
- }
- return 0;
-}
-
void bgfx_slider::import(float val)
{
m_value = val;
- slider_changed(m_machine, this, m_slider_state->id, nullptr, int32_t(floor(m_value / m_step + 0.5f)));
+ update(nullptr, int32_t(floor(m_value / m_step + 0.5f)));
}
std::unique_ptr<slider_state> bgfx_slider::create_core_slider()
{
- auto state = make_unique_clear<slider_state>();
-
- state->minval = int32_t(floor(m_min / m_step + 0.5f));
- state->defval = int32_t(floor(m_default / m_step + 0.5f));
- state->maxval = int32_t(floor(m_max / m_step + 0.5f));
- state->incval = int32_t(floor(m_step / m_step + 0.5f));
+ int32_t minval = int32_t(floor(m_min / m_step + 0.5f));
+ int32_t defval = int32_t(floor(m_default / m_step + 0.5f));
+ int32_t maxval = int32_t(floor(m_max / m_step + 0.5f));
+ int32_t incval = int32_t(floor(m_step / m_step + 0.5f));
using namespace std::placeholders;
- state->update = std::bind(&bgfx_slider::slider_changed, this, _1, _2, _3, _4, _5);
-
- state->arg = this;
- state->id = 0;
- state->description = m_description;
-
- return state;
+ return std::make_unique<slider_state>(m_description, minval, defval, maxval, incval, std::bind(&bgfx_slider::update, this, _1, _2));
}
int32_t bgfx_slider::update(std::string *str, int32_t newval)
@@ -83,7 +68,7 @@ int32_t bgfx_slider::update(std::string *str, int32_t newval)
}
if (str != nullptr)
{
- *str = string_format(m_format, m_strings[as_int()]);
+ *str = util::string_format(m_format, m_strings[as_int()]);
}
return as_int();
}
@@ -96,21 +81,21 @@ int32_t bgfx_slider::update(std::string *str, int32_t newval)
}
if (str != nullptr)
{
- *str = string_format(m_format, as_int());
+ *str = util::string_format(m_format, as_int());
}
return as_int();
}
default:
{
- float *val_ptr = reinterpret_cast<float *>(&m_value);
+ auto *val_ptr = reinterpret_cast<float *>(&m_value);
if (newval != SLIDER_NOCHANGE)
{
*val_ptr = float(newval) * m_step;
}
if (str != nullptr)
{
- *str = string_format(m_format, *val_ptr);
+ *str = util::string_format(m_format, *val_ptr);
}
return int32_t(floor(*val_ptr / m_step + 0.5f));
}
diff --git a/src/osd/modules/render/bgfx/slider.h b/src/osd/modules/render/bgfx/slider.h
index d59f8587bd3..89a713da4b3 100644
--- a/src/osd/modules/render/bgfx/slider.h
+++ b/src/osd/modules/render/bgfx/slider.h
@@ -6,21 +6,24 @@
//
//============================================================
-#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>
-#include "../frontend/mame/ui/sliderchangednotifier.h"
-
struct slider_state;
-class bgfx_slider : public slider_changed_notifier
+class running_machine;
+
+class bgfx_slider
{
public:
enum slider_type
@@ -44,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);
@@ -62,7 +68,6 @@ public:
void import(float val);
protected:
- virtual int32_t slider_changed(running_machine &machine, void *arg, int /*id*/, std::string *str, int32_t newval) override;
std::unique_ptr<slider_state> create_core_slider();
int32_t as_int() const { return int32_t(floor(m_value / m_step + 0.5f)); }
@@ -81,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 6d55c9b4db5..96ff2511c96 100644
--- a/src/osd/modules/render/bgfx/sliderreader.cpp
+++ b/src/osd/modules/render/bgfx/sliderreader.cpp
@@ -8,7 +8,6 @@
#include "sliderreader.h"
-#include "emu.h"
#include "slider.h"
#include "chainmanager.h"
@@ -34,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;
@@ -56,11 +55,11 @@ 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;
}
- strings.push_back(std::string(string_array[i].GetString()));
+ strings.emplace_back(std::string(string_array[i].GetString()));
}
}
@@ -83,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;
@@ -114,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 6770c7e10ac..bc116f51ff1 100644
--- a/src/osd/modules/render/bgfx/slideruniform.cpp
+++ b/src/osd/modules/render/bgfx/slideruniform.cpp
@@ -9,18 +9,16 @@
//
//============================================================
-#include "emu.h"
#include "slideruniform.h"
#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 eb359a01b2c..3fdeb0b21e6 100644
--- a/src/osd/modules/render/bgfx/slideruniformreader.cpp
+++ b/src/osd/modules/render/bgfx/slideruniformreader.cpp
@@ -6,16 +6,15 @@
//
//==================================================================
-#include "emu.h"
#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))
{
@@ -36,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 0f43ad71b09..277e6815185 100644
--- a/src/osd/modules/render/bgfx/statereader.cpp
+++ b/src/osd/modules/render/bgfx/statereader.cpp
@@ -9,7 +9,26 @@
#include "statereader.h"
-#include <math.h>
+#include "osdcore.h"
+
+#include <cmath>
+
+
+bool state_reader::V_READER_CHECK(bool condition, const util::format_argument_pack<char> &args)
+{
+ if (!condition)
+ 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;
+}
uint64_t state_reader::get_enum_from_value(const Value& value, std::string name, const uint64_t default_value, const string_to_enum* enums, const int count)
{
@@ -101,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;
}
@@ -112,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
@@ -130,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 8026b4b07d0..69a795d9f04 100644
--- a/src/osd/modules/render/bgfx/statereader.h
+++ b/src/osd/modules/render/bgfx/statereader.h
@@ -7,16 +7,18 @@
//
//================================================================
+#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>
-#include "osdcore.h"
using namespace rapidjson;
@@ -45,22 +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)
{
- 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);
- }
- return condition;
+ 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 fa592255735..8ffb4be6d66 100644
--- a/src/osd/modules/render/bgfx/suppressor.cpp
+++ b/src/osd/modules/render/bgfx/suppressor.cpp
@@ -7,18 +7,19 @@
//
//============================================================
-#include "emu.h"
#include "suppressor.h"
#include "slider.h"
-bgfx_suppressor::bgfx_suppressor(std::vector<bgfx_slider*> sliders, uint32_t condition, combine_mode combine, void* value)
- : m_sliders(sliders)
+#include <cstring>
+
+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 77a109a264b..353b79ad9bf 100644
--- a/src/osd/modules/render/bgfx/suppressorreader.cpp
+++ b/src/osd/modules/render/bgfx/suppressorreader.cpp
@@ -6,9 +6,6 @@
//
//============================================================
-#include "emu.h"
-#include <string>
-
#include "suppressorreader.h"
#include "suppressor.h"
@@ -24,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))
{
@@ -61,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)]);
@@ -72,25 +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.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 cb912aba9ef..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)
@@ -30,16 +33,24 @@ bgfx_target::bgfx_target(std::string name, bgfx::TextureFormat::Enum format, uin
{
m_width *= m_scale;
m_height *= m_scale;
+
uint32_t wrap_mode = BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP;
uint32_t filter_mode = filter ? (BGFX_SAMPLER_MIN_ANISOTROPIC | BGFX_SAMPLER_MAG_ANISOTROPIC) : (BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT);
+ uint32_t depth_flags = wrap_mode | (BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT);
- m_textures = new bgfx::TextureHandle[m_page_count];
+ m_textures = new bgfx::TextureHandle[m_page_count * 2];
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_targets[page] = bgfx::createFrameBuffer(1, &m_textures[page], false);
+
+ 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] };
+ m_targets[page] = bgfx::createFrameBuffer(2, handles, false);
+
assert(m_targets[page].idx != 0xffff);
}
@@ -54,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)
@@ -64,7 +77,7 @@ bgfx_target::bgfx_target(void *handle, uint16_t width, uint16_t height)
, m_page_count(0)
{
m_targets = new bgfx::FrameBufferHandle[1];
- m_targets[0] = bgfx::createFrameBuffer(handle, width, height);
+ m_targets[0] = bgfx::createFrameBuffer(handle, width, height, bgfx::TextureFormat::Count, bgfx::TextureFormat::D32F);
// No backing texture
}
@@ -81,6 +94,7 @@ bgfx_target::~bgfx_target()
for (int page = 0; page < m_page_count; page++)
{
bgfx::destroy(m_targets[page]);
+ bgfx::destroy(m_textures[m_page_count + page]);
bgfx::destroy(m_textures[page]);
}
delete [] m_textures;
diff --git a/src/osd/modules/render/bgfx/target.h b/src/osd/modules/render/bgfx/target.h
index 53fd70dd46b..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,12 +43,18 @@ 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 uint16_t width() const override { return m_width; }
- virtual uint16_t height() const override { return m_height; }
virtual bgfx::TextureHandle texture() const override;
virtual bool is_target() const override { return true; }
+ 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; }
private:
std::string m_name;
@@ -59,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 dfc1678ee34..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,98 +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)
{
- bgfx_target* target = new bgfx_target(name, format, width, height, style, double_buffer, filter, scale, screen);
- std::string full_name = name + std::to_string(screen);
+ const std::string full_name = name + std::to_string(screen);
- m_targets[full_name] = target;
+ auto iter = m_targets.find(full_name);
+ if (iter != m_targets.end())
+ {
+ iter->second.reset();
+ m_textures.remove_provider(full_name);
+ }
- 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[full_name] != nullptr)
+ 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[full_name] = nullptr;
+ m_targets.erase(found);
m_textures.remove_provider(full_name);
}
}
bgfx_target* target_manager::create_backbuffer(void *handle, uint16_t width, uint16_t height)
{
- bgfx_target* 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);
- bgfx_target* target = m_targets[full_name];
- if (target == nullptr)
+ const std::string full_name = name + std::to_string(screen);
+ const auto found = m_targets.find(full_name);
+ if (found != m_targets.end())
{
- osd_printf_verbose("Warning: Attempting to retrieve a nonexistent target '%s' for screen %d\n", name.c_str(), screen);
+ 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 target;
}
-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.push_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;
@@ -133,18 +141,20 @@ 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());
- delete target;
+ 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, 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())
{
- m_native_dims.push_back(osd_dim(0, 0));
+ m_native_dims.emplace_back(osd_dim(0, 0));
}
if (count != m_screen_count)
@@ -155,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[name + std::to_string(screen)] != nullptr)
+ 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::RGBA8, 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 71b82383a59..12386428822 100644
--- a/src/osd/modules/render/bgfx/targetreader.cpp
+++ b/src/osd/modules/render/bgfx/targetreader.cpp
@@ -6,22 +6,29 @@
//
//============================================================
-#include <string>
-
-#include "emu.h"
-#include <modules/lib/osdobj_common.h>
+#include "targetreader.h"
+#include "bgfxutil.h"
#include "chainmanager.h"
-#include "targetreader.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] = {
{ "guest", TARGET_STYLE_GUEST },
{ "native", TARGET_STYLE_NATIVE },
{ "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::RGBA8, 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 ecbf51121ab..2ffa97c0b6f 100644
--- a/src/osd/modules/render/bgfx/texture.cpp
+++ b/src/osd/modules/render/bgfx/texture.cpp
@@ -6,15 +6,19 @@
//
//============================================================
-#include <string.h>
+#include <cstring>
#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)
+ , m_width_mul_factor(1)
{
bgfx::TextureInfo info;
bgfx::calcTextureSize(info, width, height, 1, false, false, 1, format);
@@ -32,18 +36,30 @@ 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)
+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)
+ , m_width_mul_factor(width_mul_factor)
{
+ int adjusted_width = (m_rowpixels * m_width_mul_factor) / m_width_div_factor;
bgfx::TextureInfo info;
- bgfx::calcTextureSize(info, width, height, 1, false, false, 1, format);
- m_texture = bgfx::createTexture2D(width, height, false, 1, format, flags, data);
+ bgfx::calcTextureSize(info, adjusted_width, height, 1, false, false, 1, format);
+ m_texture = bgfx::createTexture2D(adjusted_width, height, false, 1, format, flags, nullptr);
+ bgfx::updateTexture2D(m_texture, 0, 0, 0, 0, adjusted_width, height, data, pitch);
}
bgfx_texture::~bgfx_texture()
{
bgfx::destroy(m_texture);
}
+
+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 7cb6d988150..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);
+ 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
@@ -29,16 +29,26 @@ public:
bgfx::TextureFormat::Enum format() const { return m_format; }
// bgfx_texture_handle_provider
- virtual uint16_t width() const override { return m_width; }
- virtual uint16_t height() const override { return m_height; }
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, 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;
+ int m_width_mul_factor;
bgfx::TextureHandle m_texture;
};
diff --git a/src/osd/modules/render/bgfx/texturehandleprovider.h b/src/osd/modules/render/bgfx/texturehandleprovider.h
index 5620e54974e..35e4e12dc43 100644
--- a/src/osd/modules/render/bgfx/texturehandleprovider.h
+++ b/src/osd/modules/render/bgfx/texturehandleprovider.h
@@ -7,23 +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 a5fbca97f35..b9acd5748e8 100644
--- a/src/osd/modules/render/bgfx/texturemanager.cpp
+++ b/src/osd/modules/render/bgfx/texturemanager.cpp
@@ -9,23 +9,26 @@
//
//============================================================
-#include <bgfx/bgfx.h>
-
#include "texturemanager.h"
-#include "texture.h"
+
#include "bgfxutil.h"
-#include "rendutil.h"
+#include "texture.h"
+
#include "modules/render/copyutil.h"
+#include "osdcore.h"
+
+#include "emucore.h"
+#include "fileio.h"
+#include "rendutil.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)
@@ -35,68 +38,95 @@ 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)
{
- std::map<std::string, bgfx_texture_handle_provider*>::iterator 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)));
+}
+
+void texture_manager::add_provider(const std::string &name, bgfx_texture_handle_provider &provider)
+{
+ 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(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t height, void* data, uint32_t flags)
+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)
{
- bgfx_texture* texture = new bgfx_texture(name, format, width, height, flags, data);
- m_textures[name] = texture;
- return texture;
+ 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.c_str(), OPEN_FLAG_READ);
- render_load_png(bitmap, file, nullptr, file_name.c_str());
+ emu_file file(path, OPEN_FLAG_READ);
+ if (!file.open(file_name))
+ {
+ render_load_png(bitmap, file);
+ file.close();
+ }
if (bitmap.width() == 0 || bitmap.height() == 0)
{
- printf("Unable to load PNG '%s' from path '%s'\n", path.c_str(), file_name.c_str());
+ osd_printf_error("Unable to load PNG '%s' from path '%s'\n", file_name, path);
return nullptr;
}
- uint8_t *data = new uint8_t[bitmap.width() * bitmap.height() * 4];
- uint32_t *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();
- uint32_t* base = reinterpret_cast<uint32_t *>(bitmap.raw_pixptr(0));
+ auto* base = reinterpret_cast<uint32_t *>(bitmap.raw_pixptr(0));
for (int y = 0; y < height; y++)
{
- copy_util::copyline_argb32(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::RGBA8, 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)
{
- std::map<uint64_t, sequenced_handle>::iterator 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;
@@ -116,8 +146,12 @@ bgfx::TextureHandle texture_manager::create_or_update_mame_texture(uint32_t form
}
else
{
- const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(format, width, height, rowpixels, palette, base);
- bgfx::updateTexture2D(handle, 0, 0, 0, 0, (uint16_t)width, (uint16_t)height, mem);
+ bgfx::TextureFormat::Enum dst_format = bgfx::TextureFormat::BGRA8;
+ 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, 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;
}
}
@@ -127,7 +161,7 @@ bgfx::TextureHandle texture_manager::create_or_update_mame_texture(uint32_t form
}
else
{
- std::map<uint64_t, sequenced_handle>::iterator iter = m_mame_textures.find(key);
+ auto iter = m_mame_textures.find(key);
if (iter != m_mame_textures.end())
{
handle = iter->second.handle;
@@ -142,8 +176,12 @@ bgfx::TextureHandle texture_manager::create_or_update_mame_texture(uint32_t form
}
else
{
- const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(format, width, height, rowpixels, palette, base);
- bgfx::updateTexture2D(handle, 0, 0, 0, 0, (uint16_t)width, (uint16_t)height, mem);
+ bgfx::TextureFormat::Enum dst_format = bgfx::TextureFormat::BGRA8;
+ 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, 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;
}
}
@@ -151,46 +189,40 @@ bgfx::TextureHandle texture_manager::create_or_update_mame_texture(uint32_t form
}
}
- const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(format, width, height, rowpixels, palette, base);
- handle = bgfx::createTexture2D(width, height, false, 1, bgfx::TextureFormat::RGBA8, flags, nullptr);
- bgfx::updateTexture2D(handle, 0, 0, 0, 0, (uint16_t)width, (uint16_t)height, mem);
+ bgfx::TextureFormat::Enum dst_format = bgfx::TextureFormat::BGRA8;
+ 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, 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);
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;
- std::map<std::string, bgfx_texture_handle_provider*>::iterator 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)
{
- std::map<std::string, bgfx_texture_handle_provider*>::iterator 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[name] = nullptr;
- }
+ m_textures.erase(name);
}
diff --git a/src/osd/modules/render/bgfx/texturemanager.h b/src/osd/modules/render/bgfx/texturemanager.h
index 3345a1b0ed6..8ed5d410f75 100644
--- a/src/osd/modules/render/bgfx/texturemanager.h
+++ b/src/osd/modules/render/bgfx/texturemanager.h
@@ -9,39 +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 "emu.h"
+#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
{
@@ -51,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 ef33c11f128..238a6a4315d 100644
--- a/src/osd/modules/render/bgfx/uniform.cpp
+++ b/src/osd/modules/render/bgfx/uniform.cpp
@@ -7,13 +7,15 @@
//============================================================
#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::createUniform(m_name.c_str(), m_type);
+ m_handle = BGFX_INVALID_HANDLE;
m_data_size = get_size_for_type(type);
if (m_data_size > 0)
{
@@ -23,13 +25,21 @@ bgfx_uniform::bgfx_uniform(std::string name, bgfx::UniformType::Enum type)
bgfx_uniform::~bgfx_uniform()
{
- bgfx::destroy(m_handle);
+ if (m_handle.idx != bgfx::kInvalidHandle)
+ {
+ bgfx::destroy(m_handle);
+ }
delete [] m_data;
}
+void bgfx_uniform::create()
+{
+ m_handle = bgfx::createUniform(m_name.c_str(), m_type);
+}
+
void bgfx_uniform::upload()
{
- if (m_type != bgfx::UniformType::Int1)
+ if (m_type != bgfx::UniformType::Sampler)
{
bgfx::setUniform(m_handle, m_data);
}
@@ -42,7 +52,7 @@ bgfx_uniform* bgfx_uniform::set(float* value)
bgfx_uniform* bgfx_uniform::set_int(int value)
{
- return set(&value, get_size_for_type(bgfx::UniformType::Int1));
+ return set(&value, get_size_for_type(bgfx::UniformType::Sampler));
}
bgfx_uniform* bgfx_uniform::set_mat3(float* value)
@@ -69,7 +79,7 @@ size_t bgfx_uniform::get_size_for_type(bgfx::UniformType::Enum type)
case bgfx::UniformType::Vec4:
return sizeof(float) * 4;
- case bgfx::UniformType::Int1:
+ case bgfx::UniformType::Sampler:
return sizeof(int);
case bgfx::UniformType::Mat3:
diff --git a/src/osd/modules/render/bgfx/uniform.h b/src/osd/modules/render/bgfx/uniform.h
index aa4c2cc097a..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,13 +18,15 @@
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();
+ 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; }
@@ -45,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 3e3cb5db318..d1eab8098c7 100644
--- a/src/osd/modules/render/bgfx/uniformreader.cpp
+++ b/src/osd/modules/render/bgfx/uniformreader.cpp
@@ -10,14 +10,17 @@
#include "uniform.h"
+#include <cstdlib>
+
+
const uniform_reader::string_to_enum uniform_reader::TYPE_NAMES[uniform_reader::TYPE_COUNT] = {
- { "int", bgfx::UniformType::Int1 },
+ { "int", bgfx::UniformType::Sampler },
{ "vec4", bgfx::UniformType::Vec4 },
{ "mat3", bgfx::UniformType::Mat3 },
{ "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;
- float* 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;
- }
- bgfx_uniform* 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/vertex.h b/src/osd/modules/render/bgfx/vertex.h
index 32b3c36064f..2036296a9d0 100644
--- a/src/osd/modules/render/bgfx/vertex.h
+++ b/src/osd/modules/render/bgfx/vertex.h
@@ -31,7 +31,7 @@ struct ScreenVertex
.end();
}
- static bgfx::VertexDecl ms_decl;
+ static bgfx::VertexLayout ms_decl;
};
#endif // __DRAWBGFX_VERTEX__
diff --git a/src/osd/modules/render/bgfx/view.cpp b/src/osd/modules/render/bgfx/view.cpp
index 893aa77c143..3a731fc71f8 100644
--- a/src/osd/modules/render/bgfx/view.cpp
+++ b/src/osd/modules/render/bgfx/view.cpp
@@ -1,6 +1,9 @@
-#include "emu.h"
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz
+
+#include "view.h"
+
#include "window.h"
-#include "rendutil.h"
#include "../drawbgfx.h"
#include <bx/math.h>
@@ -8,12 +11,9 @@
#include <bgfx/platform.h>
#include "target.h"
-#include "view.h"
void bgfx_view::update() {
- std::shared_ptr<osd_window> win = m_renderer->assert_window();
-
- const uint32_t window_index = win->m_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);
@@ -26,11 +26,14 @@ void bgfx_view::update() {
}
void bgfx_ortho_view::setup() {
- if (m_window_index != 0)
+ if (m_window_index == 0)
+ {
+ bgfx::setViewFrameBuffer(m_index, BGFX_INVALID_HANDLE);
+ }
+ else
{
bgfx::setViewFrameBuffer(m_index, m_backbuffer->target());
}
-
bgfx::setViewRect(m_index, 0, 0, m_view_width, m_view_height);
while ((m_index + 1) > m_seen_views.size())
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 a30b928b817..45df9060c71 100644
--- a/src/osd/modules/render/bgfx/windowparameter.h
+++ b/src/osd/modules/render/bgfx/windowparameter.h
@@ -6,28 +6,26 @@
//
//============================================================
-#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 { };
+ virtual void tick(double delta) override { }
private:
uint32_t m_index;
};
-#endif // __DRAWBGFX_WINDOW_PARAMETER__
+#endif // MAME_RENDER_BGFX_WINDOWPARAMETER_H
diff --git a/src/osd/modules/render/bgfx/writereader.h b/src/osd/modules/render/bgfx/writereader.h
index 7dcd1ac16c9..9f60efd846a 100644
--- a/src/osd/modules/render/bgfx/writereader.h
+++ b/src/osd/modules/render/bgfx/writereader.h
@@ -2,14 +2,14 @@
// copyright-holders:Ryan Holtz
//============================================================
//
-// cullreader.h - BGFX alpha/color write state JSON reader
+// writereader.h - BGFX alpha/color write state JSON reader
//
//============================================================
#pragma once
-#ifndef __DRAWBGFX_WRITE_READER__
-#define __DRAWBGFX_WRITE_READER__
+#ifndef DRAWBGFX_WRITE_READER
+#define DRAWBGFX_WRITE_READER
#include "statereader.h"
@@ -18,4 +18,4 @@ public:
static uint64_t read_from_value(const Value& value);
};
-#endif // __DRAWBGFX_WRITE_READER__
+#endif // DRAWBGFX_WRITE_READER
diff --git a/src/osd/modules/render/bgfxutil.cpp b/src/osd/modules/render/bgfxutil.cpp
index 5ba76cbd2a1..3d555bb60ad 100644
--- a/src/osd/modules/render/bgfxutil.cpp
+++ b/src/osd/modules/render/bgfxutil.cpp
@@ -7,42 +7,97 @@
//============================================================
// MAMEOS headers
-#include "emu.h"
#include "bgfxutil.h"
#include "copyutil.h"
+#include "emucore.h"
#include "render.h"
-const bgfx::Memory* bgfx_util::mame_texture_data_to_bgfx_texture_data(uint32_t format, int width, int height, int rowpixels, const rgb_t *palette, void *base)
+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)
{
- const bgfx::Memory* mem = bgfx::alloc(width * height * 4);
- uint32_t* data = reinterpret_cast<uint32_t*>(mem->data);
- uint16_t* src16 = reinterpret_cast<uint16_t*>(base);
- uint32_t* src32 = reinterpret_cast<uint32_t*>(base);
+ bgfx::TextureInfo info;
+ const bgfx::Memory *data = nullptr;
+ uint8_t *adjusted_base = (uint8_t *)base;
+
+ switch (src_format)
+ {
+ case PRIMFLAG_TEXFORMAT(TEXFORMAT_YUY16):
+ dst_format = bgfx::TextureFormat::BGRA8;
+ width_div_factor = 2;
+ width_mul_factor = 1;
+ out_pitch = rowpixels * 2;
+ bgfx::calcTextureSize(info, rowpixels / width_div_factor, height, 1, false, false, 1, dst_format);
+
+ 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;
+ width_div_factor = 1;
+ width_mul_factor = 2;
+ out_pitch = rowpixels * 2;
+ bgfx::calcTextureSize(info, rowpixels * width_mul_factor, height, 1, false, false, 1, dst_format);
+
+ 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):
+ dst_format = bgfx::TextureFormat::BGRA8;
+ width_div_factor = 1;
+ width_mul_factor = 1;
+ out_pitch = rowpixels * 4;
+ bgfx::calcTextureSize(info, rowpixels, height, 1, false, false, 1, dst_format);
+
+ if (width_margin)
+ {
+ adjusted_base -= width_margin * 4;
+ }
+ data = bgfx::copy(adjusted_base, info.storageSize);
+ break;
+ }
+
+ return data;
+}
+
+const bgfx::Memory* bgfx_util::mame_texture_data_to_bgra32(uint32_t src_format, int width, int height, int rowpixels, const rgb_t *palette, void *base)
+{
+ const bgfx::Memory* mem = bgfx::alloc(rowpixels * height * 4);
+ auto* dst = reinterpret_cast<uint32_t*>(mem->data);
+ auto* src16 = reinterpret_cast<uint16_t*>(base);
+ auto* src32 = reinterpret_cast<uint32_t*>(base);
for (int y = 0; y < height; y++)
{
- uint32_t* dst_line = data + y * width;
- uint16_t* src_line16 = src16 + y * rowpixels;
- uint32_t* src_line32 = src32 + y * rowpixels;
- switch (format)
+ switch (src_format)
{
- case PRIMFLAG_TEXFORMAT(TEXFORMAT_PALETTE16):
- copy_util::copyline_palette16(dst_line, src_line16, width, palette);
- break;
- case PRIMFLAG_TEXFORMAT(TEXFORMAT_YUY16):
- copy_util::copyline_yuy16_to_argb(dst_line, src_line16, width, palette, 1);
- break;
- case PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32):
- copy_util::copyline_argb32(dst_line, src_line32, width, palette);
- break;
- case PRIMFLAG_TEXFORMAT(TEXFORMAT_RGB32):
- copy_util::copyline_rgb32(dst_line, src_line32, width, palette);
- break;
- default:
- break;
+ case PRIMFLAG_TEXFORMAT(TEXFORMAT_PALETTE16):
+ copy_util::copyline_palette16_to_bgra(dst, src16, width, palette);
+ src16 += rowpixels;
+ break;
+ case PRIMFLAG_TEXFORMAT(TEXFORMAT_YUY16):
+ copy_util::copyline_yuy16_to_bgra(dst, src16, width, palette, 1);
+ src16 += rowpixels;
+ break;
+ case PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32):
+ copy_util::copyline_argb32_to_bgra(dst, src32, width, palette);
+ src32 += rowpixels;
+ break;
+ case PRIMFLAG_TEXFORMAT(TEXFORMAT_RGB32):
+ copy_util::copyline_rgb32_to_bgra(dst, src32, width, palette);
+ src32 += rowpixels;
+ break;
+ default:
+ break;
}
+ dst += width;
}
return mem;
}
@@ -54,7 +109,8 @@ 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(BGFX_STATE_BLEND_DST_COLOR, BGFX_STATE_BLEND_ZERO);
+ //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);
default:
@@ -62,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 c733987ef18..aa108a6fb3b 100644
--- a/src/osd/modules/render/bgfxutil.h
+++ b/src/osd/modules/render/bgfxutil.h
@@ -7,12 +7,18 @@
#include <bgfx/bgfx.h>
+#include "palette.h"
+
+#include <cstdint>
+
/* sdl_info is the information about SDL for the current screen */
class bgfx_util
{
public:
- static const bgfx::Memory* mame_texture_data_to_bgfx_texture_data(uint32_t format, int width, int height, int rowpixels, const rgb_t *palette, void *base);
+ 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.cpp b/src/osd/modules/render/binpacker.cpp
index aa80f600e2a..7c605ff7275 100644
--- a/src/osd/modules/render/binpacker.cpp
+++ b/src/osd/modules/render/binpacker.cpp
@@ -6,9 +6,10 @@
//
//============================================================
-#include "emu.h"
#include "binpacker.h"
+
#include <algorithm>
+#include <cstddef>
bool rectangle_packer::pack(const std::vector<packable_rectangle>& rects, std::vector<std::vector<packed_rectangle>>& packs, int pack_size)
{
@@ -19,7 +20,7 @@ bool rectangle_packer::pack(const std::vector<packable_rectangle>& rects, std::v
// Add rects to member array, and check to make sure none is too big
for (size_t rect = 0; rect < rects.size(); rect++)
{
- m_rects.push_back(rectangle(0, 0, rects[rect].width(), rects[rect].height(), rects[rect].hash(), rects[rect].format(), rects[rect].rowpixels(), rects[rect].palette(), rects[rect].base()));
+ m_rects.emplace_back(rectangle(0, 0, rects[rect].width(), rects[rect].height(), rects[rect].hash(), rects[rect].format(), rects[rect].rowpixels(), rects[rect].palette(), rects[rect].base()));
}
// Sort from greatest to least area
@@ -29,7 +30,7 @@ bool rectangle_packer::pack(const std::vector<packable_rectangle>& rects, std::v
while (m_num_packed < (int)m_rects.size())
{
int i = m_packs.size();
- m_packs.push_back(rectangle(m_pack_size));
+ m_packs.emplace_back(rectangle(m_pack_size));
m_roots.push_back(i);
if (!fill(i))
{
@@ -179,7 +180,7 @@ void rectangle_packer::add_pack_to_array(int pack, std::vector<packed_rectangle>
{
if (m_packs[pack].hash != 0)
{
- array.push_back(packed_rectangle(m_packs[pack].hash, m_packs[pack].format,
+ array.emplace_back(packed_rectangle(m_packs[pack].hash, m_packs[pack].format,
m_packs[pack].w, m_packs[pack].h, m_packs[pack].x, m_packs[pack].y,
m_packs[pack].rowpixels, m_packs[pack].palette, m_packs[pack].base));
diff --git a/src/osd/modules/render/binpacker.h b/src/osd/modules/render/binpacker.h
index 55bd03116e5..52efe4abb85 100644
--- a/src/osd/modules/render/binpacker.h
+++ b/src/osd/modules/render/binpacker.h
@@ -5,7 +5,9 @@
#ifndef __RECTPACKER_H__
#define __RECTPACKER_H__
+#include "bitmap.h"
+#include <cstdint>
#include <vector>
class rectangle_packer
@@ -27,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)
@@ -48,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)
@@ -97,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 f3dcea9bf0d..1ac485bab8d 100644
--- a/src/osd/modules/render/blit13.h
+++ b/src/osd/modules/render/blit13.ipp
@@ -119,9 +119,9 @@ FUNCTOR(op_yuv16pal_argb32rot, return pixel_ycc_to_rgb_pal(&src, palbase); )
// Copy and rotation
//============================================================
-struct blit_base {
- blit_base(int dest_bpp, bool is_rot, bool is_passthrough)
- : m_dest_bpp(dest_bpp), m_is_rot(is_rot), m_is_passthrough(is_passthrough)
+struct blit_base
+{
+ blit_base(int dest_bpp, bool is_rot, bool is_passthrough) : m_dest_bpp(dest_bpp), m_is_rot(is_rot), m_is_passthrough(is_passthrough)
{ }
virtual ~blit_base() { }
@@ -137,13 +137,12 @@ struct blit_texcopy : public blit_base
blit_texcopy() : blit_base(sizeof(_dest_type) / _len_div, false, false) { }
void texop(const texture_info *texture, const render_texinfo *texsource) const override
{
- ATTR_UNUSED const rgb_t *palbase = texsource->palette;
- int x, y;
+ const rgb_t *palbase = texsource->palette;
/* loop over Y */
- for (y = 0; y < texsource->height; y++) {
+ for (int y = 0; y < texsource->height; y++) {
_src_type *src = (_src_type *)texsource->base + y * texsource->rowpixels / (_len_div);
_dest_type *dst = (_dest_type *)((uint8_t *)texture->m_pixels + y * texture->m_pitch);
- x = texsource->width / (_len_div);
+ int x = texsource->width / (_len_div);
while (x > 0) {
*dst++ = m_op.op(*src, palbase);
++src;
@@ -164,17 +163,16 @@ struct blit_texrot : public blit_base
blit_texrot() : blit_base(sizeof(_dest_type), true, false) { }
void texop(const texture_info *texture, const render_texinfo *texsource) const override
{
- ATTR_UNUSED const rgb_t *palbase = texsource->palette;
- int x, y;
+ const rgb_t *palbase = texsource->palette;
const quad_setup_data *setup = &texture->m_setup;
int dudx = setup->dudx;
int dvdx = setup->dvdx;
/* loop over Y */
- for (y = 0; y < setup->rotheight; y++) {
+ for (int y = 0; y < setup->rotheight; y++) {
int32_t curu = setup->startu + y * setup->dudy;
int32_t curv = setup->startv + y * setup->dvdy;
_dest_type *dst = (_dest_type *)((uint8_t *)texture->m_pixels + y * texture->m_pitch);
- x = setup->rotwidth;
+ int x = setup->rotwidth;
while (x>0) {
_src_type *src = (_src_type *) texsource->base + (curv >> 16) * texsource->rowpixels + (curu >> 16);
*dst++ = m_op.op(*src, palbase);
diff --git a/src/osd/modules/render/copyutil.h b/src/osd/modules/render/copyutil.h
index 715fcba0dca..65a47a5b332 100644
--- a/src/osd/modules/render/copyutil.h
+++ b/src/osd/modules/render/copyutil.h
@@ -11,6 +11,10 @@
#ifndef __RENDER_COPYUTIL__
#define __RENDER_COPYUTIL__
+#include "palette.h"
+
+#include <cassert>
+
class copy_util
{
@@ -24,6 +28,15 @@ public:
}
}
+ static inline void copyline_palette16_to_bgra(uint32_t *dst, const uint16_t *src, int width, const rgb_t *palette)
+ {
+ for (int x = 0; x < width; x++)
+ {
+ rgb_t srcpixel = palette[*src++];
+ *dst++ = 0xff000000 | (srcpixel.r() << 16) | (srcpixel.g() << 8) | srcpixel.b();
+ }
+ }
+
static inline void copyline_rgb32(uint32_t *dst, const uint32_t *src, int width, const rgb_t *palette)
{
int x;
@@ -49,6 +62,32 @@ public:
}
}
+ static inline void copyline_rgb32_to_bgra(uint32_t *dst, const uint32_t *src, int width, const rgb_t *palette)
+ {
+ int x;
+
+ // palette (really RGB map) case
+ if (palette != nullptr)
+ {
+ for (x = 0; x < width; x++)
+ {
+ rgb_t srcpix = *src++;
+ uint32_t val = 0xff000000 | palette[0x200 + srcpix.b()] | palette[0x100 + srcpix.g()] | palette[srcpix.r()];
+ *dst++ = (val & 0xff00ff00) | ((val & 0x000000ff) << 16) | ((val & 0x00ff0000) >> 16);
+ }
+ }
+
+ // direct case
+ else
+ {
+ for (x = 0; x < width; x++)
+ {
+ rgb_t srcpix = *src++;
+ *dst++ = 0xff000000 | (srcpix.r() << 16) | (srcpix.g() << 8) | srcpix.b();
+ }
+ }
+ }
+
static inline void copyline_argb32(uint32_t *dst, const uint32_t *src, int width, const rgb_t *palette)
{
int x;
@@ -73,6 +112,31 @@ public:
}
}
+ static inline void copyline_argb32_to_bgra(uint32_t *dst, const uint32_t *src, int width, const rgb_t *palette)
+ {
+ int x;
+ // palette (really RGB map) case
+ if (palette != nullptr)
+ {
+ for (x = 0; x < width; x++)
+ {
+ rgb_t srcpix = *src++;
+ uint32_t val = (srcpix & 0xff000000) | palette[0x200 + srcpix.b()] | palette[0x100 + srcpix.g()] | palette[srcpix.r()];
+ *dst++ = (val & 0xff00ff00) | ((val & 0x000000ff) << 16) | ((val & 0x00ff0000) >> 16);
+ }
+ }
+
+ // direct case
+ else
+ {
+ for (x = 0; x < width; x++)
+ {
+ rgb_t srcpix = *src++;
+ *dst++ = (srcpix.a() << 24) | (srcpix.r() << 16) | (srcpix.g() << 8) | srcpix.b();
+ }
+ }
+ }
+
static inline uint32_t ycc_to_rgb(uint8_t y, uint8_t cb, uint8_t cr)
{
/* original equations:
@@ -116,14 +180,12 @@ public:
static inline void copyline_yuy16_to_argb(uint32_t *dst, const uint16_t *src, int width, const rgb_t *palette, int xprescale)
{
- int x;
-
assert(width % 2 == 0);
// palette (really RGB map) case
if (palette != nullptr)
{
- for (x = 0; x < width / 2; x++)
+ for (int x = 0; x < width / 2; x++)
{
uint16_t srcpix0 = *src++;
uint16_t srcpix1 = *src++;
@@ -139,7 +201,7 @@ public:
// direct case
else
{
- for (x = 0; x < width; x += 2)
+ for (int x = 0; x < width; x += 2)
{
uint16_t srcpix0 = *src++;
uint16_t srcpix1 = *src++;
@@ -152,6 +214,55 @@ public:
}
}
}
+
+ static inline void copyline_yuy16_to_bgra(uint32_t *dst, const uint16_t *src, int width, const rgb_t *palette, int xprescale)
+ {
+ assert(width % 2 == 0);
+
+ // palette (really RGB map) case
+ if (palette != nullptr)
+ {
+ for (int x = 0; x < width / 2; x++)
+ {
+ uint16_t srcpix0 = *src++;
+ uint16_t srcpix1 = *src++;
+ uint8_t cb = srcpix0 & 0xff;
+ uint8_t cr = srcpix1 & 0xff;
+ for (int x2 = 0; x2 < xprescale; x2++)
+ {
+ uint32_t val = ycc_to_rgb(palette[0x000 + (srcpix0 >> 8)], cb, cr);
+ *dst++ = (val & 0xff00ff00) | ((val & 0x000000ff) << 16) | ((val & 0x00ff0000) >> 16);
+ }
+ for (int x2 = 0; x2 < xprescale; x2++)
+ {
+ uint32_t val = ycc_to_rgb(palette[0x000 + (srcpix1 >> 8)], cb, cr);
+ *dst++ = (val & 0xff00ff00) | ((val & 0x000000ff) << 16) | ((val & 0x00ff0000) >> 16);
+ }
+ }
+ }
+
+ // direct case
+ else
+ {
+ for (int x = 0; x < width; x += 2)
+ {
+ uint16_t srcpix0 = *src++;
+ uint16_t srcpix1 = *src++;
+ uint8_t cb = srcpix0 & 0xff;
+ uint8_t cr = srcpix1 & 0xff;
+ for (int x2 = 0; x2 < xprescale; x2++)
+ {
+ uint32_t val = ycc_to_rgb(srcpix0 >> 8, cb, cr);
+ *dst++ = (val & 0xff00ff00) | ((val & 0x000000ff) << 16) | ((val & 0x00ff0000) >> 16);
+ }
+ for (int x2 = 0; x2 < xprescale; x2++)
+ {
+ uint32_t val = ycc_to_rgb(srcpix1 >> 8, cb, cr);
+ *dst++ = (val & 0xff00ff00) | ((val & 0x000000ff) << 16) | ((val & 0x00ff0000) >> 16);
+ }
+ }
+ }
+ }
};
#endif // __RENDER_COPYUTIL__
diff --git a/src/osd/modules/render/d3d/d3dcomm.h b/src/osd/modules/render/d3d/d3dcomm.h
index d576c5e7d0c..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_dynamic_supported(0), m_stretch_supported(0), 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();
@@ -73,9 +84,6 @@ public:
texture_info * find_texinfo(const render_texinfo *texture, uint32_t flags);
uint32_t texture_compute_hash(const render_texinfo *texture, uint32_t flags);
- bool is_dynamic_supported() const { return (bool)m_dynamic_supported; }
- void set_dynamic_supported(bool dynamic_supported) { m_dynamic_supported = dynamic_supported; }
- bool is_stretch_supported() const { return (bool)m_stretch_supported; }
D3DFORMAT get_yuv_format() const { return m_yuv_format; }
DWORD get_texture_caps() const { return m_texture_caps; }
@@ -85,14 +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;
- int m_dynamic_supported; // are dynamic textures supported?
- int m_stretch_supported; // is StretchRect with point filtering supported?
+ renderer_d3d9 & m_renderer;
D3DFORMAT m_yuv_format; // format to use for YUV textures
DWORD m_texture_caps; // textureCaps field
@@ -109,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; }
@@ -130,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);
@@ -150,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 */
@@ -175,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;
@@ -185,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; }
@@ -198,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
@@ -209,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 */
@@ -227,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();
@@ -262,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 2a91dade834..c0753f314f7 100644
--- a/src/osd/modules/render/d3d/d3dhlsl.cpp
+++ b/src/osd/modules/render/d3d/d3dhlsl.cpp
@@ -8,13 +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 "screen.h"
+
#include "aviio.h"
#include "png.h"
-#include "screen.h"
// MAMEOS headers
#include "winmain.h"
@@ -25,9 +30,13 @@
#include "strconv.h"
#include "d3dhlsl.h"
#include "../frontend/mame/ui/slider.h"
+
#include <array>
+#include <locale>
+#include <sstream>
#include <utility>
+
//============================================================
// PROTOTYPES
//============================================================
@@ -44,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;
@@ -76,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)
@@ -103,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;
@@ -114,8 +110,8 @@ public:
for (int y = 0; y < m_height; y++)
{
- DWORD *src = (DWORD *)((BYTE *)rect.pBits + y * rect.Pitch);
- uint32_t *dst = &m_frame.pix32(y);
+ auto *src = (DWORD *)((BYTE *)rect.pBits + y * rect.Pitch);
+ uint32_t *dst = &m_frame.pix(y);
for (int x = 0; x < m_width; x++)
{
@@ -138,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;
@@ -150,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
};
@@ -162,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);
}
@@ -216,14 +193,9 @@ shaders::shaders() :
shaders::~shaders()
{
- for (slider* slider : internal_sliders)
- {
- delete slider;
- }
-
- if (options != nullptr)
+ if (options && (&last_options != options))
{
- global_free(options);
+ delete options;
options = nullptr;
}
}
@@ -238,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);
}
@@ -283,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());
@@ -317,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);
}
@@ -331,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;
@@ -342,8 +309,8 @@ void shaders::render_snapshot(IDirect3DSurface9 *surface)
for (int y = 0; y < height; y++)
{
- DWORD *src = (DWORD *)((BYTE *)rect.pBits + y * rect.Pitch);
- uint32_t *dst = &snapshot.pix32(y);
+ auto *src = (DWORD *)((BYTE *)rect.pBits + y * rect.Pitch);
+ uint32_t *dst = &snapshot.pix(y);
for (int x = 0; x < width; x++)
{
@@ -352,49 +319,30 @@ void shaders::render_snapshot(IDirect3DSurface9 *surface)
}
emu_file file(machine->options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- osd_file::error filerr = machine->video().open_next(file, "png");
- if (filerr != osd_file::error::NONE)
+ std::error_condition const filerr = machine->video().open_next(file, "png");
+ if (filerr)
return;
// add two text entries describing the image
std::string text1 = std::string(emulator_info::get_appname()).append(" ").append(emulator_info::get_build_version());
std::string text2 = std::string(machine->system().manufacturer).append(" ").append(machine->system().type.fullname());
- png_info pnginfo;
- pnginfo.add_text("Software", text1.c_str());
- pnginfo.add_text("System", text2.c_str());
+ util::png_info pnginfo;
+ pnginfo.add_text("Software", text1);
+ pnginfo.add_text("System", text2);
// now do the actual work
- png_error error = png_write_bitmap(file, &pnginfo, snapshot, 1 << 24, nullptr);
- if (error != PNGERR_NONE)
- osd_printf_error("Error generating PNG for HLSL snapshot: png_error = %d\n", error);
+ std::error_condition const error = util::png_write_bitmap(file, &pnginfo, snapshot, 1 << 24, nullptr);
+ if (error)
+ osd_printf_error("Error generating PNG for HLSL snapshot (%s:%d %s)\n", error.category().name(), error.value(), error.message());
result = snap_copy_target->UnlockRect();
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();
}
@@ -434,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");
@@ -484,34 +440,29 @@ 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();
-
- windows_options &winoptions = downcast<windows_options &>(machine->options());
+ auto &winoptions = downcast<windows_options &>(machine->options());
post_fx_enable = winoptions.d3d_hlsl_enable();
oversampling_enable = winoptions.d3d_hlsl_oversampling();
snap_width = winoptions.d3d_snap_width();
snap_height = winoptions.d3d_snap_height();
- this->options = (hlsl_options*)global_alloc_clear<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();
@@ -593,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;
}
@@ -607,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()
@@ -708,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);
@@ -716,12 +727,16 @@ 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);
emu_file file(machine->options().art_path(), OPEN_FLAG_READ);
- render_load_png(shadow_bitmap, file, nullptr, options->shadow_mask_texture);
+ if (!file.open(options->shadow_mask_texture))
+ {
+ render_load_png(shadow_bitmap, file);
+ file.close();
+ }
// experimental: if we have a shadow bitmap, create a texture for it
if (shadow_bitmap.valid())
@@ -737,12 +752,16 @@ 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));
}
- render_load_png(lut_bitmap, file, nullptr, options->lut_texture);
+ if (!file.open(options->lut_texture))
+ {
+ render_load_png(lut_bitmap, file);
+ file.close();
+ }
if (lut_bitmap.valid())
{
render_texinfo texture;
@@ -756,12 +775,16 @@ 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));
}
- render_load_png(ui_lut_bitmap, file, nullptr, options->ui_lut_texture);
+ if (!file.open(options->ui_lut_texture))
+ {
+ render_load_png(ui_lut_bitmap, file);
+ file.close();
+ }
if (ui_lut_bitmap.valid())
{
render_texinfo texture;
@@ -775,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);
@@ -855,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);
@@ -862,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);
@@ -874,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);
@@ -886,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);
@@ -901,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;
}
@@ -915,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");
@@ -945,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;
}
@@ -976,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);
@@ -984,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);
+ }
}
//============================================================
@@ -1038,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;
}
@@ -1085,22 +1135,32 @@ rgb_t shaders::apply_color_convolution(rgb_t color)
b = chroma[2] * saturation + luma;
return rgb_t(
- std::max(0, std::min(255, int(r * 255.0f))),
- std::max(0, std::min(255, int(g * 255.0f))),
- std::max(0, std::min(255, int(b * 255.0f))));
+ std::clamp(int(r * 255.0f), 0, 255),
+ std::clamp(int(g * 255.0f), 0, 255),
+ std::clamp(int(b * 255.0f), 0, 255));
}
int shaders::color_convolution_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum)
{
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::ntsc_pass() if NTSC processing is enabled
+ if (!options->yiq_enable)
+ {
+ curr_effect->set_texture("Diffuse", diffuse_texture->get_finaltex());
+ }
- // initial "Diffuse" texture is set in shaders::set_texture() or the result of shaders::ntsc_pass()
+ 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;
}
@@ -1109,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;
}
@@ -1132,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;
}
@@ -1147,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_iterator screen_iterator(machine->root_device());
- screen_device *screen = screen_iterator.byindex(curr_screen);
+ screen_device_enumerator screen_iterator(machine->root_device());
+ 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();
@@ -1161,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;
}
@@ -1184,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;
}
@@ -1205,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;
}
@@ -1230,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_iterator screen_iterator(machine->root_device());
- screen_device *screen = screen_iterator.byindex(curr_screen);
+ screen_device_enumerator screen_iterator(machine->root_device());
+ screen_device *screen = screen_iterator.byindex(target_to_screen[curr_target]);
render_container &screen_container = screen->container();
float xscale = 1.0f / screen_container.xscale();
@@ -1252,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);
@@ -1265,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;
}
@@ -1274,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;
}
@@ -1292,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;
@@ -1319,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);
@@ -1336,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;
}
@@ -1372,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;
}
@@ -1386,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;
}
@@ -1402,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;
}
@@ -1423,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)
{
@@ -1442,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;
}
@@ -1456,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());
}
@@ -1480,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)
@@ -1490,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)
@@ -1512,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);
@@ -1533,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)
@@ -1558,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)
@@ -1611,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
{
@@ -1637,7 +1699,7 @@ void shaders::end_draw()
return;
}
- backbuffer->Release();
+ backbuffer->Release(); // TODO: where's the matching AddRef that requires this explicit Release?
}
@@ -1652,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;
@@ -1661,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);
}
@@ -1692,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;
@@ -1701,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);
@@ -1733,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;
@@ -1742,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);
@@ -1778,16 +1834,6 @@ bool shaders::add_render_target(renderer_d3d9* d3d, render_primitive *prim, int
//============================================================
-// shaders::enumerate_screens
-//============================================================
-void shaders::enumerate_screens()
-{
- screen_device_iterator iter(machine->root_device());
- num_screens = iter.count();
-}
-
-
-//============================================================
// shaders::create_texture_target
//============================================================
@@ -1798,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;
@@ -1807,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);
@@ -1845,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();
@@ -1945,25 +1925,24 @@ void shaders::delete_resources()
static void get_vector(const char *data, int count, float *out, bool report_error)
{
- if (count > 3 &&
- sscanf(data, "%f,%f,%f,%f", &out[0], &out[1], &out[2], &out[3]) < 4 && report_error)
- {
- osd_printf_error("Illegal quad vector value = %s\n", data);
- }
- else if (count > 2 &&
- sscanf(data, "%f,%f,%f", &out[0], &out[1], &out[2]) < 3 && report_error)
- {
- osd_printf_error("Illegal triple vector value = %s\n", data);
- }
- else if (count > 1 &&
- sscanf(data, "%f,%f", &out[0], &out[1]) < 2 && report_error)
- {
- osd_printf_error("Illegal double vector value = %s\n", data);
- }
- else if (count > 0 &&
- sscanf(data, "%f", &out[0]) < 1 && report_error)
+ std::istringstream is(data);
+ is.imbue(std::locale::classic());
+ for (int i = 0; count > i; )
{
- osd_printf_error("Illegal single vector value = %s\n", data);
+ is >> out[i];
+ bool bad = !is;
+ if (++i < count)
+ {
+ char ch;
+ is >> ch;
+ bad = bad || !is || (',' != ch);
+ }
+ if (bad)
+ {
+ if (report_error)
+ osd_printf_error("Illegal %d-item vector value = %s\n", count, data);
+ return;
+ }
}
}
@@ -1974,23 +1953,10 @@ static void get_vector(const char *data, int count, float *out, bool report_erro
// be done in a more ideal way.
//============================================================
-std::unique_ptr<slider_state> shaders::slider_alloc(int id, const char *title, int32_t minval, int32_t defval, int32_t maxval, int32_t incval, void *arg)
+std::unique_ptr<slider_state> shaders::slider_alloc(std::string &&title, int32_t minval, int32_t defval, int32_t maxval, int32_t incval, slider *arg)
{
- auto state = make_unique_clear<slider_state>();
-
- state->minval = minval;
- state->defval = defval;
- state->maxval = maxval;
- state->incval = incval;
-
using namespace std::placeholders;
- state->update = std::bind(&shaders::slider_changed, this, _1, _2, _3, _4, _5);
-
- state->arg = arg;
- state->id = id;
- state->description = title;
-
- return state;
+ return std::make_unique<slider_state>(std::move(title), minval, defval, maxval, incval, std::bind(&slider::update, arg, _1, _2));
}
@@ -2013,7 +1979,7 @@ int32_t slider::update(std::string *str, int32_t newval)
{
case SLIDER_INT_ENUM:
{
- int32_t *val_ptr = reinterpret_cast<int32_t *>(m_value);
+ auto *val_ptr = reinterpret_cast<int32_t *>(m_value);
if (newval != SLIDER_NOCHANGE)
{
*val_ptr = newval;
@@ -2041,7 +2007,7 @@ int32_t slider::update(std::string *str, int32_t newval)
default:
{
- float *val_ptr = reinterpret_cast<float *>(m_value);
+ auto *val_ptr = reinterpret_cast<float *>(m_value);
if (newval != SLIDER_NOCHANGE)
{
*val_ptr = (float)newval * m_desc->scale;
@@ -2056,16 +2022,7 @@ int32_t slider::update(std::string *str, int32_t newval)
return 0;
}
-int32_t shaders::slider_changed(running_machine& /*machine*/, void *arg, int /*id*/, std::string *str, int32_t newval)
-{
- if (arg != nullptr)
- {
- return reinterpret_cast<slider *>(arg)->update(str, 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 };
@@ -2220,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, {} }
@@ -2318,13 +2275,9 @@ 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_iterator(machine->root_device()).first();;
+ const screen_device *first_screen = screen_device_enumerator(machine->root_device()).first();
if (first_screen == nullptr)
{
return;
@@ -2354,37 +2307,32 @@ void shaders::init_slider_list()
for (int j = 0; j < count; j++)
{
- slider* 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(desc->id, name.c_str(), 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;
- item.text = core_slider->description;
- item.subtext = "";
- item.flags = 0;
- item.ref = core_slider.get();
- item.type = ui::menu_item_type::SLIDER;
- m_sliders.push_back(item);
- m_core_sliders.push_back(std::move(core_slider));
+ ui::menu_item item(ui::menu_item_type::SLIDER, core_slider.get());
+ item.set_text(core_slider->description);
+ m_sliders.emplace_back(item);
+ m_core_sliders.emplace_back(std::move(core_slider));
}
}
}
@@ -2414,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_iterator(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 &&
@@ -2431,7 +2378,7 @@ void uniform::update()
}
case CU_SCREEN_COUNT:
{
- int screen_count = win->target()->current_view()->screens().count();
+ int screen_count = d3d->window().target()->current_view().visible_screen_count();
m_shader->set_int("ScreenCount", screen_count);
break;
}
@@ -2494,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:
@@ -2587,6 +2534,7 @@ void uniform::update()
break;
case CU_CHROMA_CONVERSION_GAIN:
m_shader->set_vector("ConversionGain", 3, &options->chroma_conversion_gain[0]);
+ break;
case CU_CHROMA_Y_GAIN:
m_shader->set_vector("YGain", 3, &options->chroma_y_gain[0]);
break;
@@ -2617,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:
{
@@ -2692,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);
@@ -2724,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)
@@ -2737,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)
@@ -2764,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 7f7dacc4538..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;
@@ -175,92 +186,92 @@ class movie_recorder;
/* in the future this will be moved into an OSD/emu shared buffer */
struct hlsl_options
{
- bool params_init;
- bool params_dirty;
- int shadow_mask_tile_mode;
- float shadow_mask_alpha;
- char shadow_mask_texture[1024];
- int shadow_mask_count_x;
- int shadow_mask_count_y;
- float shadow_mask_u_size;
- float shadow_mask_v_size;
- float shadow_mask_u_offset;
- float shadow_mask_v_offset;
- float distortion;
- float cubic_distortion;
- float distort_corner;
- float round_corner;
- float smooth_border;
- float reflection;
- float vignetting;
- float scanline_alpha;
- float scanline_scale;
- float scanline_height;
- float scanline_variation;
- float scanline_bright_scale;
- float scanline_bright_offset;
- float scanline_jitter;
- float hum_bar_alpha;
- float defocus[2];
- float converge_x[3];
- float converge_y[3];
- float radial_converge_x[3];
- float radial_converge_y[3];
- float red_ratio[3];
- float grn_ratio[3];
- float blu_ratio[3];
- float offset[3];
- float scale[3];
- float power[3];
- float floor[3];
- float phosphor[3];
- float saturation;
- int chroma_mode;
- float chroma_a[2];
- float chroma_b[2];
- float chroma_c[2];
- float chroma_conversion_gain[3];
- float chroma_y_gain[3];
+ bool params_init = false;
+ bool params_dirty = false;
+ int shadow_mask_tile_mode = 0;
+ float shadow_mask_alpha = 0.0;
+ char shadow_mask_texture[1024]{ 0 };
+ int shadow_mask_count_x = 0;
+ int shadow_mask_count_y = 0;
+ float shadow_mask_u_size = 0.0;
+ float shadow_mask_v_size = 0.0;
+ float shadow_mask_u_offset = 0.0;
+ float shadow_mask_v_offset = 0.0;
+ float distortion = 0.0;
+ float cubic_distortion = 0.0;
+ float distort_corner = 0.0;
+ float round_corner = 0.0;
+ float smooth_border = 0.0;
+ float reflection = 0.0;
+ float vignetting = 0.0;
+ float scanline_alpha = 0.0;
+ float scanline_scale = 0.0;
+ float scanline_height = 0.0;
+ float scanline_variation = 0.0;
+ float scanline_bright_scale = 0.0;
+ float scanline_bright_offset = 0.0;
+ float scanline_jitter = 0.0;
+ float hum_bar_alpha = 0.0;
+ float defocus[2]{ 0.0 };
+ float converge_x[3]{ 0.0 };
+ float converge_y[3]{ 0.0 };
+ float radial_converge_x[3]{ 0.0 };
+ float radial_converge_y[3]{ 0.0 };
+ float red_ratio[3]{ 0.0 };
+ float grn_ratio[3]{ 0.0 };
+ float blu_ratio[3]{ 0.0 };
+ float offset[3]{ 0.0 };
+ float scale[3]{ 0.0 };
+ float power[3]{ 0.0 };
+ float floor[3]{ 0.0 };
+ float phosphor[3]{ 0.0 };
+ float saturation = 0.0;
+ int chroma_mode = 0;
+ float chroma_a[2]{ 0.0 };
+ float chroma_b[2]{ 0.0 };
+ float chroma_c[2]{ 0.0 };
+ float chroma_conversion_gain[3]{ 0.0 };
+ float chroma_y_gain[3]{ 0.0 };
// NTSC
- int yiq_enable;
- float yiq_jitter;
- float yiq_cc;
- float yiq_a;
- float yiq_b;
- float yiq_o;
- float yiq_p;
- float yiq_n;
- float yiq_y;
- float yiq_i;
- float yiq_q;
- float yiq_scan_time;
- int yiq_phase_count;
+ int yiq_enable = 0;
+ float yiq_jitter = 0.0;
+ float yiq_cc = 0.0;
+ float yiq_a = 0.0;
+ float yiq_b = 0.0;
+ float yiq_o = 0.0;
+ float yiq_p = 0.0;
+ float yiq_n = 0.0;
+ float yiq_y = 0.0;
+ float yiq_i = 0.0;
+ float yiq_q = 0.0;
+ float yiq_scan_time = 0.0;
+ int yiq_phase_count = 0;
// Vectors
- float vector_beam_smooth;
- float vector_length_scale;
- float vector_length_ratio;
+ float vector_beam_smooth = 0.0;
+ float vector_length_scale = 0.0;
+ float vector_length_ratio = 0.0;
// Bloom
- int bloom_blend_mode;
- float bloom_scale;
- float bloom_overdrive[3];
- float bloom_level0_weight;
- float bloom_level1_weight;
- float bloom_level2_weight;
- float bloom_level3_weight;
- float bloom_level4_weight;
- float bloom_level5_weight;
- float bloom_level6_weight;
- float bloom_level7_weight;
- float bloom_level8_weight;
+ int bloom_blend_mode = 0;
+ float bloom_scale = 0.0;
+ float bloom_overdrive[3]{ 0.0 };
+ float bloom_level0_weight = 0.0;
+ float bloom_level1_weight = 0.0;
+ float bloom_level2_weight = 0.0;
+ float bloom_level3_weight = 0.0;
+ float bloom_level4_weight = 0.0;
+ float bloom_level5_weight = 0.0;
+ float bloom_level6_weight = 0.0;
+ float bloom_level7_weight = 0.0;
+ float bloom_level8_weight = 0.0;
// Final
- char lut_texture[1024];
- int lut_enable;
- char ui_lut_texture[1024];
- int ui_lut_enable;
+ char lut_texture[1024]{ 0 };
+ int lut_enable = 0;
+ char ui_lut_texture[1024]{ 0 };
+ int ui_lut_enable = 0;
};
struct slider_desc
@@ -290,7 +301,7 @@ private:
void * m_value;
};
-class shaders : public slider_changed_notifier
+class shaders
{
friend class effect;
friend class uniform;
@@ -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);
@@ -330,15 +345,18 @@ public:
void delete_resources();
// slider-related functions
- virtual int32_t slider_changed(running_machine &machine, void *arg, int /*id*/, std::string *str, int32_t newval) override;
- std::unique_ptr<slider_state> slider_alloc(int id, const char *title, int32_t minval, int32_t defval, int32_t maxval, int32_t incval, void *arg);
+ std::unique_ptr<slider_state> slider_alloc(std::string &&title, int32_t minval, int32_t defval, int32_t maxval, int32_t incval, slider *arg);
void init_slider_list();
std::vector<ui::menu_item> get_slider_list() { return m_sliders; }
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
@@ -365,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
@@ -373,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
@@ -384,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 f99ebf70601..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 @@
//
//============================================================
-// standard C headers
-#include <math.h>
-#include <stdio.h>
+#include "render_module.h"
-// MAME headers
-#include "emu.h"
-#include "options.h"
+#include "modules/osdmodule.h"
+
+#if defined(OSD_SDL)
// OSD headers
-#include "osdsdl.h"
+#include "sdlopts.h"
#include "window.h"
-#include "draw13.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>
+
+
+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;
+};
//============================================================
-// DEBUGGING
+// 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
+
+ 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"
+
+//============================================================
+// 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 = global_alloc(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;
- global_free(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 = global_alloc(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 26a6bb565bf..00000000000
--- a/src/osd/modules/render/draw13.h
+++ /dev/null
@@ -1,213 +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
-//
-//============================================================
-
-#pragma once
-
-#ifndef __DRAW20__
-#define __DRAW20__
-
-// 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>
-
-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 // __DRAW20__
diff --git a/src/osd/modules/render/drawbgfx.cpp b/src/osd/modules/render/drawbgfx.cpp
index 3c15bc3cf96..ef90478e59e 100644
--- a/src/osd/modules/render/drawbgfx.cpp
+++ b/src/osd/modules/render/drawbgfx.cpp
@@ -5,10 +5,44 @@
// 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>
-#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS) || defined(OSD_UWP)
+#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS)
// standard windows headers
#include <windows.h>
#if defined(SDLMAME_WIN32)
@@ -22,38 +56,415 @@ extern void *GetOSWindow(void *wincontroller);
#endif
#endif
-// MAMEOS headers
-#include "emu.h"
-#include "window.h"
-#include "rendutil.h"
-#include "aviwrite.h"
-
#include <bgfx/bgfx.h>
#include <bgfx/platform.h>
+
+#include "imgui/imgui.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"
+//============================================================
+// Renderer interface to parent module
+//============================================================
+
+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();
+}
+
+
+
+//============================================================
+// OSD MODULE
+//============================================================
+
+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;
+};
+
+
+//============================================================
+// video_bgfx::init
+//============================================================
+
+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;
+}
+
+
+//============================================================
+// video_bgfx::exit
+//============================================================
+
+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;
+}
+
+
+//============================================================
+// video_bgfx::create
+//============================================================
+
+std::unique_ptr<osd_renderer> video_bgfx::create(osd_window &window)
+{
+ // start BGFX if this is the first window
+ if (!m_bgfx_library_initialized)
+ {
+ assert(window.index() == 0); // bad things will happen otherwise
+ assert(!has_active_renderers());
+
+ 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;
+ }
+
+ return std::make_unique<renderer_bgfx>(window, static_cast<renderer_bgfx::parent_module &>(*this));
+}
+
+
+//============================================================
+// 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;
+ }
+}
+
+
+//============================================================
+// 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);
+}
+
+
+//============================================================
+// video_bgfx::init_bgfx_library
//============================================================
-// DEBUGGING
+
+bool video_bgfx::init_bgfx_library(osd_window &window)
+{
+ osd_dim const wdim = window.get_size();
+
+ bgfx::Init init;
+ init.type = bgfx::RendererType::Count;
+ init.vendorId = BGFX_PCI_ID_NONE;
+ init.resolution.width = wdim.width();
+ init.resolution.height = wdim.height();
+ init.resolution.numBackBuffers = 1;
+ 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_warning("Unknown BGFX backend type '%s', going with auto-detection.\n", backend);
+
+ 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;
+}
+
+
//============================================================
+// 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());
+#elif defined(SDLMAME_EMSCRIPTEN)
+ platform_data.ndt = nullptr;
+ platform_data.nwh = (void *)"#canvas"; // HTML5 target selector
+#else // defined(OSD_*)
+ SDL_SysWMinfo wmi;
+ SDL_VERSION(&wmi.version);
+ 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;
+ }
+
+ 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)
+ case SDL_SYSWM_WAYLAND:
+ platform_data.ndt = wmi.info.wl.display;
+ platform_data.nwh = 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;
+}
+
+} // anonymous namespace
+
+} // namespace osd
+
+MODULE_DEFINITION(RENDERER_BGFX, osd::video_bgfx)
+
+
//============================================================
// CONSTANTS
@@ -64,6 +475,8 @@ 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
//============================================================
@@ -71,45 +484,113 @@ char const *const renderer_bgfx::WINDOW_PREFIX = "Window 0, ";
#define GIBBERISH (0)
#define SCENE_VIEW (0)
+
+
//============================================================
// STATICS
//============================================================
-bool renderer_bgfx::s_window_set = false;
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)
+{
+ SDL_SysWMinfo wmi;
+ SDL_VERSION(&wmi.version);
+ if (!SDL_GetWindowWMInfo(window, &wmi))
+ return std::make_pair(nullptr, false);
+
+ switch (wmi.subsystem)
+ {
+#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)
+ case SDL_SYSWM_WAYLAND:
+ return std::make_pair(wmi.info.wl.surface, true);
+#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
//============================================================
-renderer_bgfx::renderer_bgfx(std::shared_ptr<osd_window> w)
- : osd_renderer(w, FLAG_NONE)
- , m_options(downcast<osd_options &>(w->machine().options()))
+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_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)
+ , 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)
+ {
+ 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();
+ }
+ }
}
+
+
//============================================================
// 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);
- bgfx::touch(0);
- bgfx::frame();
+
if (m_avi_writer != nullptr && m_avi_writer->recording())
{
m_avi_writer->stop();
@@ -123,257 +604,99 @@ renderer_bgfx::~renderer_bgfx()
delete [] m_avi_data;
delete m_avi_view;
}
-
- // Cleanup.
- delete m_chains;
- delete m_effects;
- delete m_shaders;
- delete m_textures;
- delete m_targets;
}
+
+
//============================================================
// renderer_bgfx::create
//============================================================
-#ifdef OSD_WINDOWS
-inline void winSetHwnd(::HWND _window)
-{
- bgfx::PlatformData pd;
- pd.ndt = NULL;
- pd.nwh = _window;
- pd.context = NULL;
- pd.backBuffer = NULL;
- pd.backBufferDS = NULL;
- bgfx::setPlatformData(pd);
-}
-#elif defined(OSD_MAC)
-inline void macSetWindow(void *_window)
-{
- bgfx::PlatformData pd;
- pd.ndt = NULL;
- pd.nwh = GetOSWindow(_window);
- pd.context = NULL;
- pd.backBuffer = NULL;
- pd.backBufferDS = NULL;
- bgfx::setPlatformData(pd);
-}
-#elif defined(OSD_SDL)
-static void* sdlNativeWindowHandle(SDL_Window* _window)
-{
- SDL_SysWMinfo wmi;
- SDL_VERSION(&wmi.version);
- if (!SDL_GetWindowWMInfo(_window, &wmi))
- {
- 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_STEAMLINK
- return wmi.info.vivante.window;
-# elif BX_PLATFORM_EMSCRIPTEN || BX_PLATFORM_ANDROID
- return nullptr;
-# endif // BX_PLATFORM_
-}
-
-inline bool sdlSetWindow(SDL_Window* _window)
-{
- SDL_SysWMinfo wmi;
- SDL_VERSION(&wmi.version);
- if (!SDL_GetWindowWMInfo(_window, &wmi) )
- {
- return false;
- }
-
- bgfx::PlatformData pd;
-# if BX_PLATFORM_LINUX || BX_PLATFORM_BSD
- pd.ndt = wmi.info.x11.display;
- pd.nwh = (void*)(uintptr_t)wmi.info.x11.window;
-# elif BX_PLATFORM_OSX
- pd.ndt = NULL;
- pd.nwh = wmi.info.cocoa.window;
-# elif BX_PLATFORM_WINDOWS
- pd.ndt = NULL;
- pd.nwh = wmi.info.win.window;
-# elif BX_PLATFORM_STEAMLINK
- pd.ndt = wmi.info.vivante.display;
- pd.nwh = wmi.info.vivante.window;
-# endif // BX_PLATFORM_
- pd.context = NULL;
- pd.backBuffer = NULL;
- pd.backBufferDS = NULL;
- bgfx::setPlatformData(pd);
-
- return true;
-}
-#elif defined(OSD_UWP)
-inline void winrtSetWindow(::IUnknown* _window)
-{
- bgfx::PlatformData pd;
- pd.ndt = NULL;
- pd.nwh = _window;
- pd.context = NULL;
- pd.backBuffer = NULL;
- pd.backBufferDS = NULL;
- bgfx::setPlatformData(pd);
-}
-
-IInspectable* AsInspectable(Platform::Agile<Windows::UI::Core::CoreWindow> win)
-{
- return reinterpret_cast<IInspectable*>(win.Get());
-}
-#endif
-
int renderer_bgfx::create()
{
- // create renderer
- std::shared_ptr<osd_window> win = assert_window();
- osd_dim wdim = win->get_size();
- m_width[win->m_index] = wdim.width();
- m_height[win->m_index] = wdim.height();
- if (win->m_index == 0)
- {
- if (!s_window_set)
- {
- s_window_set = true;
- ScreenVertex::init();
- }
- else
- {
- bgfx::shutdown();
- bgfx::PlatformData blank_pd;
- memset(&blank_pd, 0, sizeof(bgfx::PlatformData));
- bgfx::setPlatformData(blank_pd);
- }
-#ifdef OSD_WINDOWS
- winSetHwnd(std::static_pointer_cast<win_window_info>(win)->platform_window());
-#elif defined(OSD_UWP)
+ const osd_dim wdim = window().get_size();
+ s_width[window().index()] = wdim.width();
+ s_height[window().index()] = wdim.height();
+ m_dimensions = wdim;
- winrtSetWindow(AsInspectable(std::static_pointer_cast<uwp_window_info>(win)->platform_window()));
-#elif defined(OSD_MAC)
- macSetWindow(std::static_pointer_cast<mac_window_info>(win)->platform_window());
-#else
- sdlSetWindow(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window());
-#endif
- std::string backend(m_options.bgfx_backend());
- bgfx::Init init;
- init.type = bgfx::RendererType::Count;
- init.vendorId = BGFX_PCI_ID_NONE;
- init.resolution.width = wdim.width();
- init.resolution.height = wdim.height();
- init.resolution.reset = BGFX_RESET_NONE;
- if (backend == "auto")
- {
- }
- 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 == "gles")
- {
- init.type = bgfx::RendererType::OpenGLES;
- }
- else if (backend == "glsl" || backend == "opengl")
- {
- init.type = bgfx::RendererType::OpenGL;
- }
- else if (backend == "metal")
- {
- init.type = bgfx::RendererType::Metal;
- }
- else
- {
- printf("Unknown backend type '%s', going with auto-detection\n", backend.c_str());
- }
- bgfx::init(init);
- bgfx::reset(m_width[win->m_index], m_height[win->m_index], video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE);
- // Enable debug text.
- bgfx::setDebug(m_options.bgfx_debug() ? BGFX_DEBUG_STATS : BGFX_DEBUG_TEXT);
- m_dimensions = osd_dim(m_width[0], m_height[0]);
- }
-
- m_textures = new texture_manager();
- m_targets = new target_manager(*m_textures);
-
- m_shaders = new shader_manager(m_options);
- m_effects = new effect_manager(m_options, *m_shaders);
+ // finish creating the renderer
+ m_textures = std::make_unique<texture_manager>();
+ m_targets = std::make_unique<target_manager>(*m_textures);
- if (win->m_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(), m_width[win->m_index], m_height[win->m_index]);
-#elif defined(OSD_UWP)
- m_framebuffer = m_targets->create_backbuffer(AsInspectable(std::static_pointer_cast<uwp_window_info>(win)->platform_window()), m_width[win->m_index], m_height[win->m_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()), m_width[win->m_index], m_height[win->m_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()), m_width[win->m_index], m_height[win->m_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->m_index);
+ bgfx::touch(window().index());
- if (m_ortho_view) {
+ if (m_ortho_view)
m_ortho_view->set_backbuffer(m_framebuffer);
- }
}
- // Create program from shaders.
- m_gui_effect[0] = m_effects->effect("gui_opaque");
- m_gui_effect[1] = m_effects->effect("gui_blend");
- m_gui_effect[2] = m_effects->effect("gui_multiply");
- m_gui_effect[3] = m_effects->effect("gui_add");
-
- m_screen_effect[0] = m_effects->effect("screen_opaque");
- m_screen_effect[1] = m_effects->effect("screen_blend");
- m_screen_effect[2] = m_effects->effect("screen_multiply");
- m_screen_effect[3] = m_effects->effect("screen_add");
-
- if ( m_gui_effect[0] == nullptr || m_gui_effect[1] == nullptr || m_gui_effect[2] == nullptr || m_gui_effect[3] == nullptr ||
- m_screen_effect[0] == nullptr || m_screen_effect[1] == nullptr || m_screen_effect[2] == nullptr || m_screen_effect[3] == nullptr)
- {
- fatalerror("BGFX: Unable to load required shaders. Please check and reinstall the %s folder\n", m_options.bgfx_path());
- }
+ m_shaders = std::make_unique<shader_manager>();
+ m_effects = std::make_unique<effect_manager>(*m_shaders);
- m_chains = new chain_manager(win->machine(), m_options, *m_textures, *m_targets, *m_effects, win->m_index, *this);
+ // 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::RGBA8, 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));
- imguiCreate();
-
return 0;
}
+
+
//============================================================
// renderer_bgfx::record
//============================================================
void renderer_bgfx::record()
{
- std::shared_ptr<osd_window> win = assert_window();
-
- if (win->m_index > 0)
- {
+ if (window().index() > 0)
return;
- }
if (m_avi_writer == nullptr)
{
- m_avi_writer = new avi_write(win->machine(), m_width[0], m_height[0]);
- m_avi_data = new uint8_t[m_width[0] * m_height[0] * 4];
- m_avi_bitmap.allocate(m_width[0], m_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]);
}
if (m_avi_writer->recording())
@@ -387,9 +710,9 @@ void renderer_bgfx::record()
}
else
{
- m_avi_writer->record(m_options.bgfx_avi_name());
- m_avi_target = m_targets->create_target("avibuffer", bgfx::TextureFormat::RGBA8, m_width[0], m_height[0], TARGET_STYLE_CUSTOM, false, true, 1, 0);
- m_avi_texture = bgfx::createTexture2D(m_width[0], m_height[0], false, 1, bgfx::TextureFormat::RGBA8, BGFX_TEXTURE_BLIT_DST | BGFX_TEXTURE_READ_BACK);
+ 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)
{
@@ -398,28 +721,6 @@ void renderer_bgfx::record()
}
}
-bool renderer_bgfx::init(running_machine &machine)
-{
- const char *bgfx_path = downcast<osd_options &>(machine.options()).bgfx_path();
-
- osd::directory::ptr directory = osd::directory::open(bgfx_path);
- if (directory == nullptr)
- {
- osd_printf_verbose("Unable to find the %s folder. Please reinstall it to use the BGFX renderer\n", bgfx_path);
- return true;
- }
-
- return false;
-}
-
-void renderer_bgfx::exit()
-{
- imguiDestroy();
-
- bgfx::shutdown();
- s_window_set = false;
-}
-
//============================================================
// drawsdl_xy_to_render_target
//============================================================
@@ -441,12 +742,12 @@ int renderer_bgfx::xy_to_render_target(int x, int y, int *xt, int *yt)
// drawbgfx_window_draw
//============================================================
-bgfx::VertexDecl ScreenVertex::ms_decl;
+bgfx::VertexLayout ScreenVertex::ms_decl;
void renderer_bgfx::put_packed_quad(render_primitive *prim, uint32_t hash, ScreenVertex* vertices)
{
rectangle_packer::packed_rectangle& rect = m_hash_to_entry[hash];
- float size = float(CACHE_SIZE);
+ auto size = float(CACHE_SIZE);
float u0 = (float(rect.x()) + 0.5f) / size;
float v0 = (float(rect.y()) + 0.5f) / size;
float u1 = u0 + (float(rect.width()) - 1.0f) / size;
@@ -498,9 +799,9 @@ 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)
{
- ScreenVertex* vertices = reinterpret_cast<ScreenVertex*>(buffer->data);
+ auto* vertices = reinterpret_cast<ScreenVertex*>(buffer->data);
float x[4] = { prim->bounds.x0, prim->bounds.x1, prim->bounds.x0, prim->bounds.x1 };
float y[4] = { prim->bounds.y0, prim->bounds.y0, prim->bounds.y1, prim->bounds.y1 };
@@ -514,15 +815,24 @@ void renderer_bgfx::render_post_screen_quad(int view, render_primitive* prim, bg
vertex(&vertices[4], x[2], y[2], 0, 0xffffffff, u[2], v[2]);
vertex(&vertices[5], x[0], y[0], 0, 0xffffffff, u[0], v[0]);
- uint32_t texture_flags = BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP;
+ uint32_t texture_flags = 0U;
+ if (!PRIMFLAG_GET_TEXWRAP(prim->flags))
+ texture_flags |= BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP;
if (video_config.filter == 0)
- {
texture_flags |= BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT;
- }
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());
}
@@ -531,15 +841,15 @@ void renderer_bgfx::render_avi_quad()
m_avi_view->set_index(s_current_view);
m_avi_view->setup();
- bgfx::setViewRect(s_current_view, 0, 0, m_width[0], m_height[0]);
- bgfx::setViewClear(s_current_view, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x00000000, 1.0f, 0);
+ bgfx::setViewRect(s_current_view, 0, 0, s_width[0], s_height[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);
- ScreenVertex* vertices = reinterpret_cast<ScreenVertex*>(buffer.data);
+ auto* vertices = reinterpret_cast<ScreenVertex*>(buffer.data);
- float x[4] = { 0.0f, float(m_width[0]), 0.0f, float(m_width[0]) };
- float y[4] = { 0.0f, 0.0f, float(m_height[0]), float(m_height[0]) };
+ float x[4] = { 0.0f, float(s_width[0]), 0.0f, float(s_width[0]) };
+ float y[4] = { 0.0f, 0.0f, float(s_height[0]), float(s_height[0]) };
float u[4] = { 0.0f, 1.0f, 0.0f, 1.0f };
float v[4] = { 0.0f, 0.0f, 1.0f, 1.0f };
uint32_t rgba = 0xffffffff;
@@ -553,13 +863,23 @@ 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)
{
- ScreenVertex* vertices = reinterpret_cast<ScreenVertex*>(buffer->data);
+ 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);
float x[4] = { prim->bounds.x0, prim->bounds.x1, prim->bounds.x0, prim->bounds.x1 };
@@ -574,25 +894,50 @@ void renderer_bgfx::render_textured_quad(render_primitive* prim, bgfx::Transient
vertex(&vertices[4], x[2], y[2], 0, rgba, u[2], v[2]);
vertex(&vertices[5], x[0], y[0], 0, rgba, u[0], v[0]);
- uint32_t texture_flags = BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP;
- if (video_config.filter == 0)
- {
+ uint32_t texture_flags = 0U;
+ if (!PRIMFLAG_GET_TEXWRAP(prim->flags))
+ texture_flags |= BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP;
+ if (!PRIMFLAG_GET_ANTIALIAS(prim->flags))
texture_flags |= BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT;
- }
+ const bool is_screen = PRIMFLAG_GET_SCREENTEX(prim->flags);
uint16_t tex_width(prim->texture.width);
uint16_t tex_height(prim->texture.height);
- bgfx::TextureHandle 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
- , texture_flags, prim->texture.unique_id, prim->texture.old_id);
+ bgfx::TextureHandle texture = BGFX_INVALID_HANDLE;
+ if (is_screen)
+ {
+ const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgra32(prim->flags & PRIMFLAG_TEXFORMAT_MASK
+ , tex_width, tex_height, prim->texture.rowpixels, prim->texture.palette, prim->texture.base);
+ texture = bgfx::createTexture2D(tex_width, tex_height, false, 1, bgfx::TextureFormat::BGRA8, texture_flags, mem);
+ }
+ else
+ {
+ texture = m_textures->create_or_update_mame_texture(prim->flags & PRIMFLAG_TEXFORMAT_MASK
+ , 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);
+ }
- bgfx_effect** effects = PRIMFLAG_GET_SCREENTEX(prim->flags) ? m_screen_effect : m_gui_effect;
+ bgfx_effect** effects = is_screen ? m_screen_effect : m_gui_effect;
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)
+ {
+ bgfx::destroy(texture);
+ }
}
#define MAX_TEMP_COORDS 100
@@ -805,18 +1150,15 @@ 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->m_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();
- m_width[window_index] = wdim.width();
- m_height[window_index] = wdim.height();
+ osd_dim wdim = window().get_size();
+ s_width[window_index] = wdim.width();
+ s_height[window_index] = wdim.height();
// Set view 0 default viewport.
if (window_index == 0)
@@ -824,9 +1166,9 @@ int renderer_bgfx::draw(int update)
s_current_view = 0;
}
- win->m_primlist->acquire_lock();
- s_current_view += m_chains->handle_screen_chains(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)
@@ -834,6 +1176,26 @@ int renderer_bgfx::draw(int update)
return 0;
}
+ if (num_screens)
+ {
+ // 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;
+ }
+
if (s_current_view > m_max_view)
{
m_max_view = s_current_view;
@@ -843,12 +1205,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)
{
@@ -873,12 +1235,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());
}
@@ -888,11 +1259,11 @@ 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.
- bgfx::touch(s_current_view > 0 ? s_current_view - 1 : 0);
+ //bgfx::touch(s_current_view > 0 ? s_current_view - 1 : 0);
// Advance to next frame. Rendering thread will be kicked to
// process submitted rendering primitives.
@@ -904,7 +1275,10 @@ int renderer_bgfx::draw(int update)
bgfx::touch(s_current_view);
update_recording();
}
+ }
+ if (window().index() == osd_common_t::window_list().size() - 1)
+ {
bgfx::frame();
}
@@ -919,7 +1293,7 @@ void renderer_bgfx::update_recording()
int i = 0;
for (int y = 0; y < m_avi_bitmap.height(); y++)
{
- uint32_t *dst = &m_avi_bitmap.pix32(y);
+ uint32_t *dst = &m_avi_bitmap.pix(y);
for (int x = 0; x < m_avi_bitmap.width(); x++)
{
@@ -933,8 +1307,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->m_index == 0)
+ if (m_avi_writer != nullptr && m_avi_writer->recording() && window().index() == 0)
{
m_avi_writer->audio_frame(buffer, samples_this_frame);
}
@@ -942,47 +1315,36 @@ 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->m_index;
- const uint32_t width = m_width[window_index];
- const uint32_t height = m_height[window_index];
+ const uint32_t window_index = window().index();
+ const uint32_t width = s_width[window_index];
+ const uint32_t height = s_height[window_index];
- if (window_index == 0)
+ if (m_dimensions != osd_dim(width, height))
{
- if ((m_dimensions != osd_dim(width, height)))
- {
- bgfx::reset(width, height, video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE);
- m_dimensions = osd_dim(width, height);
- }
- }
- else
- {
- if ((m_dimensions != osd_dim(width, height)))
- {
- bgfx::reset(win->main_window()->get_size().width(), win->main_window()->get_size().height(), video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE);
- m_dimensions = osd_dim(width, height);
+ bgfx::reset(width, height, video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE);
+ m_dimensions = osd_dim(width, height);
- delete m_framebuffer;
+ if (window().index() != 0)
+ {
#ifdef OSD_WINDOWS
- m_framebuffer = m_targets->create_backbuffer(std::static_pointer_cast<win_window_info>(win)->platform_window(), width, height);
-#elif defined(OSD_UWP)
- m_framebuffer = m_targets->create_backbuffer(AsInspectable(std::static_pointer_cast<uwp_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)
+ {
m_ortho_view->set_backbuffer(m_framebuffer);
-
+ }
bgfx::setViewFrameBuffer(s_current_view, m_framebuffer->target());
- bgfx::setViewClear(s_current_view, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x00000000, 1.0f, 0);
- bgfx::setViewMode(s_current_view, bgfx::ViewMode::Sequential);
- bgfx::touch(s_current_view);
- bgfx::frame();
- return true;
}
+
+ 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();
+ return true;
}
return false;
}
@@ -991,17 +1353,38 @@ void renderer_bgfx::setup_ortho_view()
{
if (!m_ortho_view)
{
- m_ortho_view = new bgfx_ortho_view(this, s_current_view, m_framebuffer, m_seen_views);
+ m_ortho_view = std::make_unique<bgfx_ortho_view>(this, 0, m_framebuffer, m_seen_views);
}
- m_ortho_view->update();
- if (m_ortho_view->get_index() == UINT_MAX) {
+ if (m_ortho_view->get_index() == UINT_MAX)
+ {
m_ortho_view->set_index(s_current_view);
m_ortho_view->setup();
s_current_view++;
}
+ m_ortho_view->update();
}
-renderer_bgfx::buffer_status renderer_bgfx::buffer_primitives(bool atlas_valid, render_primitive** prim, bgfx::TransientVertexBuffer* buffer, int32_t screen)
+render_primitive_list *renderer_bgfx::get_primitives()
+{
+ // determines whether the screen container is transformed by the chain's shaders
+ bool chain_transform = false;
+
+ // check the first chain
+ bgfx_chain* chain = this->m_chains->screen_chain(0);
+ if (chain != nullptr)
+ {
+ chain_transform = chain->transform();
+ }
+
+ osd_dim wdim = window().get_size();
+ if (wdim.width() > 0 && wdim.height() > 0)
+ window().target()->set_bounds(wdim.width(), wdim.height(), window().pixel_aspect());
+
+ 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, int window_index)
{
int vertices = 0;
@@ -1043,18 +1426,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;
}
}
@@ -1131,8 +1514,12 @@ void renderer_bgfx::process_atlas_packs(std::vector<std::vector<rectangle_packer
continue;
}
m_hash_to_entry[rect.hash()] = rect;
- const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(rect.format(), rect.width(), rect.height(), rect.rowpixels(), rect.palette(), rect.base());
- bgfx::updateTexture2D(m_texture_cache->texture(), 0, 0, rect.x(), rect.y(), rect.width(), rect.height(), mem);
+ bgfx::TextureFormat::Enum dst_format = bgfx::TextureFormat::BGRA8;
+ 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(), 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);
}
}
}
@@ -1160,7 +1547,8 @@ uint32_t renderer_bgfx::get_texture_hash(render_primitive *prim)
}
return hash;
#else
- return (reinterpret_cast<size_t>(prim->texture.base)) & 0xffffffff;
+ //return (reinterpret_cast<size_t>(prim->texture.base)) & 0xffffffff;
+ return (reinterpret_cast<size_t>(prim->texture.base) ^ reinterpret_cast<size_t>(prim->texture.palette)) & 0xffffffff;
#endif
}
@@ -1168,9 +1556,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)
@@ -1183,8 +1570,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];
}
}
@@ -1261,11 +1647,44 @@ void renderer_bgfx::set_sliders_dirty()
m_sliders_dirty = true;
}
-uint32_t renderer_bgfx::get_window_width(uint32_t index) const {
- return m_width[index];
+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
+{
+ return s_height[index];
}
-uint32_t renderer_bgfx::get_window_height(uint32_t index) const {
- return m_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 e7e648c27d1..bb9f538aafa 100644
--- a/src/osd/modules/render/drawbgfx.h
+++ b/src/osd/modules/render/drawbgfx.h
@@ -1,31 +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"
-#include "../frontend/mame/ui/menuitem.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;
@@ -34,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;
@@ -58,33 +60,30 @@ public:
uint32_t get_window_width(uint32_t index) const;
uint32_t get_window_height(uint32_t index) const;
- virtual render_primitive_list *get_primitives() override
- {
- 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;
-
- // check the first chain
- bgfx_chain* chain = this->m_chains->screen_chain(0);
- if (chain != nullptr)
- {
- chain_transform = chain->transform();
- }
-
- osd_dim wdim = win->get_size();
- if (wdim.width() > 0 && wdim.height() > 0)
- win->target()->set_bounds(wdim.width(), wdim.height(), win->pixel_aspect());
-
- win->target()->set_transform_container(!chain_transform);
- return &win->target()->get_primitives();
- }
+ virtual render_primitive_list *get_primitives() override;
static char const *const WINDOW_PREFIX;
private:
+ 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();
void update_recording();
@@ -94,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);
@@ -121,7 +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;
+ 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;
@@ -129,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];
@@ -143,10 +137,8 @@ private:
std::vector<rectangle_packer::packable_rectangle> m_texinfo;
rectangle_packer m_packer;
- uint32_t m_width[16];
- uint32_t m_height[16];
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;
@@ -156,12 +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 bool s_window_set;
static uint32_t s_current_view;
+ 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 fd1331c47eb..542e2f8955d 100644
--- a/src/osd/modules/render/drawd3d.cpp
+++ b/src/osd/modules/render/drawd3d.cpp
@@ -8,25 +8,137 @@
// MAME headers
#include "emu.h"
+#include "emuopts.h"
#include "render.h"
-
#include "rendutil.h"
-#include "emuopts.h"
-#include "aviio.h"
+#include "screen.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
//============================================================
-// TYPE DEFINITIONS
+
+void video_d3d::exit()
+{
+ m_d3dobj.Reset();
+ m_d3d9_dll.reset();
+ m_options = nullptr;
+}
+
+
//============================================================
+// video_d3d::create
+//============================================================
+
+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)
-typedef IDirect3D9* (WINAPI *d3d9_create_fn)(UINT);
//============================================================
@@ -115,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; // FIX ME
-
-
-//============================================================
// drawd3d_window_init
//============================================================
@@ -173,56 +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 = global_alloc(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)
- {
- 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)
- {
- 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();
}
@@ -237,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;
@@ -249,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);
}
@@ -348,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);
@@ -364,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);
@@ -372,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);
@@ -393,27 +478,15 @@ 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);
- // check for dynamic texture support
- m_dynamic_supported = ((caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES) != 0);
- if (m_dynamic_supported)
- osd_printf_verbose("Direct3D: Using dynamic textures\n");
-
- // check for stretchrect support
- m_stretch_supported = ((caps.StretchRectFilterCaps & D3DPTFILTERCAPS_MAGFPOINT) != 0);
- if (m_stretch_supported && video_config.prescale > 1)
- osd_printf_verbose("Direct3D: Using StretchRect for prescaling\n");
-
// get texture caps
m_texture_caps = caps.TextureCaps;
m_texture_max_aspect = caps.MaxTextureAspectRatio;
@@ -422,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();
@@ -461,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));
}
@@ -470,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
- //global_free(m_default_texture);
m_default_texture = nullptr;
// free all textures
@@ -484,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++)
{
- uint32_t test_screen = (uint32_t)((*it)->get_texinfo().unique_id >> 57);
- uint32_t test_page = (uint32_t)((*it)->get_texinfo().unique_id >> 56) & 1;
- uint32_t 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 &&
@@ -509,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(nullptr)
+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()
{
}
@@ -528,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;
}
@@ -539,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
@@ -566,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())
{
@@ -575,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;
}
@@ -591,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));
}
@@ -618,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;
}
}
@@ -640,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;
}
}
@@ -655,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();
@@ -672,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))
{
@@ -690,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)
{
@@ -721,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))
@@ -741,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;
@@ -750,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
@@ -772,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
- windows_options &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();
@@ -801,44 +881,30 @@ void renderer_d3d9::update_gamma_ramp()
// device_create
//============================================================
-int renderer_d3d9::device_create(HWND device_hwnd)
+int renderer_d3d9::device_create(HWND hwnd)
{
+ // identify the actual window; this is needed so that -attach_window
+ // can work on a non-root 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 = global_alloc(d3d_texture_manager(this));
+ m_texture_manager = std::make_unique<d3d_texture_manager>(*this, m_d3dobj.Get());
-try_again:
// try for XRGB first
m_screen_format = D3DFMT_X8R8G8B8;
- HRESULT result = d3dintf->d3dobj->CheckDeviceFormat(m_adapter, D3DDEVTYPE_HAL, m_pixformat,
- m_texture_manager->is_dynamic_supported()
- ? D3DUSAGE_DYNAMIC
- : 0,
- 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,
- m_texture_manager->is_dynamic_supported()
- ? D3DUSAGE_DYNAMIC
- : 0,
- D3DRTYPE_TEXTURE, m_screen_format);
- if (FAILED(result) && m_texture_manager->is_dynamic_supported())
- {
- m_texture_manager->set_dynamic_supported(false);
- goto try_again;
- }
+ 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");
@@ -850,8 +916,13 @@ try_again:
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
@@ -884,16 +955,13 @@ try_again:
int renderer_d3d9::device_create_resources()
{
- auto win = assert_window();
-
// create shaders only once
- if (m_shaders == nullptr)
- {
- m_shaders = (shaders*)global_alloc_clear<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;
}
@@ -907,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);
@@ -921,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);
@@ -975,23 +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
- // global_free(m_shaders);
- // m_shaders = nullptr;
- //}
-}
-
-void renderer_d3d9::exit()
-{
- if (d3dintf != nullptr)
- {
- d3dintf->d3dobj->Release();
- global_free(d3dintf);
- }
}
void renderer_d3d9::device_delete()
@@ -1001,18 +1050,10 @@ void renderer_d3d9::device_delete()
// we do not delete the HLSL interface here
- if (m_texture_manager != nullptr)
- {
- global_free(m_texture_manager);
- m_texture_manager = nullptr;
- }
+ m_texture_manager.reset();
// free the device itself
- if (m_device != nullptr)
- {
- m_device->Release();
- m_device = nullptr;
- }
+ m_device.Reset();
}
@@ -1022,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();
}
@@ -1050,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);
@@ -1060,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
@@ -1115,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");
@@ -1191,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);
@@ -1201,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;
@@ -1227,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().c_str());
+ 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;
@@ -1247,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().c_str());
+ osd_printf_error("Proposed video mode not supported on device %s\n", window().monitor()->devicename());
return 1;
}
@@ -1264,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;
}
@@ -1296,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_iterator(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());
@@ -1309,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");
@@ -1324,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;
@@ -1344,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
@@ -1355,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
@@ -1382,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;
}
@@ -1419,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;
@@ -1430,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)
{
@@ -1441,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;
@@ -1451,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;
@@ -1464,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);
@@ -1480,8 +1517,8 @@ void renderer_d3d9::batch_vectors(int vector_count)
((rotation_0 || rotation_90) && orientation_swap_xy) ||
((rotation_180 || rotation_90) && !orientation_swap_xy);
- float screen_width = float(this->get_width());
- float screen_height = float(this->get_height());
+ auto screen_width = float(this->get_width());
+ auto screen_height = float(this->get_height());
float half_screen_width = screen_width * 0.5f;
float half_screen_height = screen_height * 0.5f;
float screen_swap_x_factor = 1.0f / screen_width * screen_height;
@@ -1528,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++;
}
@@ -1541,15 +1578,10 @@ void renderer_d3d9::batch_vector(const render_primitive &prim)
}
// compute the effective width based on the direction of the line
- float effwidth = prim.width;
- if (effwidth < 2.0f)
- {
- effwidth = 2.0f;
- }
+ float effwidth = std::max(prim.width, 2.0f);
// determine the bounds of a quad to draw this line
- render_bounds b0, b1;
- render_line_to_quad(&prim.bounds, effwidth, effwidth, &b0, &b1);
+ auto [b0, b1] = render_line_to_quad(prim.bounds, effwidth, effwidth);
float lx = b1.x1 - b0.x1;
float ly = b1.y1 - b0.y1;
@@ -1610,10 +1642,10 @@ void renderer_d3d9::batch_vector(const render_primitive &prim)
}
// determine the color of the line
- int32_t r = (int32_t)(prim.color.r * 255.0f);
- int32_t g = (int32_t)(prim.color.g * 255.0f);
- int32_t b = (int32_t)(prim.color.b * 255.0f);
- int32_t a = (int32_t)(prim.color.a * 255.0f);
+ 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);
DWORD color = D3DCOLOR_ARGB(a, r, g, b);
// set the color, Z parameters to standard values
@@ -1648,15 +1680,10 @@ void renderer_d3d9::draw_line(const render_primitive &prim)
}
// compute the effective width based on the direction of the line
- float effwidth = prim.width;
- if (effwidth < 1.0f)
- {
- effwidth = 1.0f;
- }
+ float effwidth = std::max(prim.width, 1.0f);
// determine the bounds of a quad to draw this line
- render_bounds b0, b1;
- render_line_to_quad(&prim.bounds, effwidth, 0.0f, &b0, &b1);
+ auto [b0, b1] = render_line_to_quad(prim.bounds, effwidth, 0.0f);
vertex[0].x = b0.x0;
vertex[0].y = b0.y0;
@@ -1680,10 +1707,10 @@ void renderer_d3d9::draw_line(const render_primitive &prim)
vertex[3].v0 = stop.c.y;
// determine the color of the line
- int32_t r = (int32_t)(prim.color.r * 255.0f);
- int32_t g = (int32_t)(prim.color.g * 255.0f);
- int32_t b = (int32_t)(prim.color.b * 255.0f);
- int32_t 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
@@ -1695,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++;
}
@@ -1749,10 +1776,10 @@ void renderer_d3d9::draw_quad(const render_primitive &prim)
}
// determine the color, allowing for over modulation
- int32_t r = (int32_t)(prim.color.r * 255.0f);
- int32_t g = (int32_t)(prim.color.g * 255.0f);
- int32_t b = (int32_t)(prim.color.b * 255.0f);
- int32_t 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
@@ -1766,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++;
}
@@ -1826,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);
@@ -1854,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)
@@ -1869,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
@@ -1924,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();
}
@@ -1944,181 +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
- {
- if ((m_xprescale == 1 && m_yprescale == 1) || m_renderer->get_shaders()->enabled())
- {
- m_type = m_texture_manager->is_dynamic_supported() ? TEXTURE_TYPE_DYNAMIC : TEXTURE_TYPE_PLAIN;
- }
- else
- {
- if (m_texture_manager->is_stretch_supported() && PRIMFLAG_GET_TEXFORMAT(flags) != TEXFORMAT_YUY16)
- {
- m_type = TEXTURE_TYPE_SURFACE;
- }
- else
- {
- m_type = m_texture_manager->is_dynamic_supported() ? TEXTURE_TYPE_DYNAMIC : TEXTURE_TYPE_PLAIN;
- }
- }
- }
-
// 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 = m_texture_manager->is_dynamic_supported() ? D3DUSAGE_DYNAMIC : 0;
- D3DPOOL pool = m_texture_manager->is_dynamic_supported() ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED;
- 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)
+ if ((m_xprescale == 1) && (m_yprescale == 1))
{
- m_xprescale = m_yprescale = 1;
- }
-
- // screen textures with no prescaling are pretty easy
- 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
{
- // use an offscreen plain surface for stretching if supported
- // (won't work for YUY textures)
- if (m_texture_manager->is_stretch_supported() && PRIMFLAG_GET_TEXFORMAT(flags) != TEXFORMAT_YUY16)
- {
- result = m_renderer->get_device()->CreateOffscreenPlainSurface(m_rawdims.c.x, m_rawdims.c.y, format, D3DPOOL_DEFAULT, &m_d3dsurface, nullptr);
- if (FAILED(result))
- {
- continue;
- }
- }
- // otherwise, we allocate a dynamic texture for the source
- else
+ // 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)
{
- result = m_renderer->get_device()->CreateTexture(m_rawdims.c.x, m_rawdims.c.y, 1, usage, format, pool, &m_d3dtex, nullptr);
- if (FAILED(result))
- {
- 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();
}
@@ -2132,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;
}
@@ -2158,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
@@ -2168,8 +2123,8 @@ void texture_info::compute_size(int texwidth, int texheight)
if (!wrap_texture)
{
// note we need 2 pixels in X for YUY textures
- m_xborderpix = (PRIMFLAG_GET_TEXFORMAT(m_flags) == TEXFORMAT_YUY16) ? 2 : 1;
- m_yborderpix = 1;
+ //m_xborderpix = (PRIMFLAG_GET_TEXFORMAT(m_flags) == TEXFORMAT_YUY16) ? 2 : 1;
+ //m_yborderpix = 1;
}
}
@@ -2182,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;
@@ -2195,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;
}
@@ -2451,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);
@@ -2488,132 +2451,109 @@ 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
- if (m_type == TEXTURE_TYPE_SURFACE)
- {
- assert(m_d3dsurface != nullptr);
- // set the source bounds
- RECT source;
- source.left = source.top = 0;
- source.right = m_texinfo.width + 2 * m_xborderpix;
- source.bottom = m_texinfo.height + 2 * m_yborderpix;
+ // first remember the original render target and set the new one
+ 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.Get());
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call 1\n", result);
+ m_renderer.reset_render_states();
- // set the target bounds
- RECT dest;
- dest = source;
- dest.right *= m_xprescale;
- dest.bottom *= m_yprescale;
+ // start the scene
+ result = m_renderer.get_device()->BeginScene();
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device BeginScene call\n", result);
- // do the stretchrect
- result = m_renderer->get_device()->StretchRect(m_d3dsurface, &source, scale_surface, &dest, D3DTEXF_POINT);
- if (FAILED(result))
- osd_printf_verbose("Direct3D: Error %08lX during device stretct_rect 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.Get());
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device SetTexture call\n", result);
- // if we are using a texture render target, we need to do more preparations
- else
+ // lock the vertex buffer
+ vertex *lockedbuf;
+ 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);
+
+ // configure the X/Y coordinates on the target surface
+ lockedbuf[0].x = -0.5f;
+ lockedbuf[0].y = -0.5f;
+ lockedbuf[1].x = (float)((m_texinfo.width + 2 * m_xborderpix) * m_xprescale) - 0.5f;
+ lockedbuf[1].y = -0.5f;
+ lockedbuf[2].x = -0.5f;
+ lockedbuf[2].y = (float)((m_texinfo.height + 2 * m_yborderpix) * m_yprescale) - 0.5f;
+ lockedbuf[3].x = (float)((m_texinfo.width + 2 * m_xborderpix) * m_xprescale) - 0.5f;
+ lockedbuf[3].y = (float)((m_texinfo.height + 2 * m_yborderpix) * m_yprescale) - 0.5f;
+
+ // configure the U/V coordintes on the source texture
+ lockedbuf[0].u0 = 0.0f;
+ lockedbuf[0].v0 = 0.0f;
+ lockedbuf[1].u0 = (float)(m_texinfo.width + 2 * m_xborderpix) / (float)m_rawdims.c.x;
+ lockedbuf[1].v0 = 0.0f;
+ lockedbuf[2].u0 = 0.0f;
+ lockedbuf[2].v0 = (float)(m_texinfo.height + 2 * m_yborderpix) / (float)m_rawdims.c.y;
+ lockedbuf[3].u0 = (float)(m_texinfo.width + 2 * m_xborderpix) / (float)m_rawdims.c.x;
+ lockedbuf[3].v0 = (float)(m_texinfo.height + 2 * m_yborderpix) / (float)m_rawdims.c.y;
+
+ // reset the remaining vertex parameters
+ for (int i = 0; i < 4; i++)
{
- 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);
- if (FAILED(result))
- osd_printf_verbose("Direct3D: Error %08lX during device GetRenderTarget call\n", result);
- result = m_renderer->get_device()->SetRenderTarget(0, scale_surface);
- if (FAILED(result))
- osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call 1\n", result);
- m_renderer->reset_render_states();
-
- // start the scene
- 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);
- 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);
- if (FAILED(result))
- osd_printf_verbose("Direct3D: Error %08lX during vertex buffer lock call\n", result);
-
- // configure the X/Y coordinates on the target surface
- lockedbuf[0].x = -0.5f;
- lockedbuf[0].y = -0.5f;
- lockedbuf[1].x = (float)((m_texinfo.width + 2 * m_xborderpix) * m_xprescale) - 0.5f;
- lockedbuf[1].y = -0.5f;
- lockedbuf[2].x = -0.5f;
- lockedbuf[2].y = (float)((m_texinfo.height + 2 * m_yborderpix) * m_yprescale) - 0.5f;
- lockedbuf[3].x = (float)((m_texinfo.width + 2 * m_xborderpix) * m_xprescale) - 0.5f;
- lockedbuf[3].y = (float)((m_texinfo.height + 2 * m_yborderpix) * m_yprescale) - 0.5f;
-
- // configure the U/V coordintes on the source texture
- lockedbuf[0].u0 = 0.0f;
- lockedbuf[0].v0 = 0.0f;
- lockedbuf[1].u0 = (float)(m_texinfo.width + 2 * m_xborderpix) / (float)m_rawdims.c.x;
- lockedbuf[1].v0 = 0.0f;
- lockedbuf[2].u0 = 0.0f;
- lockedbuf[2].v0 = (float)(m_texinfo.height + 2 * m_yborderpix) / (float)m_rawdims.c.y;
- lockedbuf[3].u0 = (float)(m_texinfo.width + 2 * m_xborderpix) / (float)m_rawdims.c.x;
- 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++)
- {
- lockedbuf[i].z = 0.0f;
- lockedbuf[i].rhw = 1.0f;
- lockedbuf[i].color = D3DCOLOR_ARGB(0xff,0xff,0xff,0xff);
- }
+ lockedbuf[i].z = 0.0f;
+ lockedbuf[i].rhw = 1.0f;
+ lockedbuf[i].color = D3DCOLOR_ARGB(0xff,0xff,0xff,0xff);
+ }
- // unlock the vertex buffer
- result = m_renderer->get_vertex_buffer()->Unlock();
- if (FAILED(result))
- osd_printf_verbose("Direct3D: Error %08lX during vertex buffer unlock call\n", result);
+ // unlock the vertex buffer
+ 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));
- 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);
- if (FAILED(result))
- osd_printf_verbose("Direct3D: Error %08lX during device DrawPrimitive 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));
+ 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);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device DrawPrimitive call\n", result);
- // end the scene
- result = m_renderer->get_device()->EndScene();
- if (FAILED(result))
- osd_printf_verbose("Direct3D: Error %08lX during device end_scene call\n", result);
+ // end the scene
+ 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);
- if (FAILED(result))
- osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call 2\n", result);
- backbuffer->Release();
- m_renderer->reset_render_states();
- }
+ // reset the render target and release our reference to the 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.Reset();
+ m_renderer.reset_render_states();
// release our reference to the target surface
- scale_surface->Release();
+ scale_surface.Reset();
}
@@ -2623,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();
}
@@ -2692,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_iterator(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;
@@ -2702,8 +2611,8 @@ bool d3d_render_target::init(renderer_d3d9 *d3d, int source_width, int source_he
float scale_factor = 0.75f;
int scale_count = vector_screen ? MAX_BLOOM_COUNT : HALF_BLOOM_COUNT;
- float bloom_width = (float)source_width;
- float bloom_height = (float)source_height;
+ auto bloom_width = (float)source_width;
+ auto bloom_height = (float)source_height;
float bloom_size = bloom_width < bloom_height ? bloom_width : bloom_height;
for (int bloom_index = 0; bloom_index < scale_count && bloom_size >= 2.0f; bloom_size *= scale_factor)
{
diff --git a/src/osd/modules/render/drawd3d.h b/src/osd/modules/render/drawd3d.h
index 92923904d77..3ab7651d87c 100644
--- a/src/osd/modules/render/drawd3d.h
+++ b/src/osd/modules/render/drawd3d.h
@@ -5,25 +5,29 @@
// drawd3d.h - Win32 Direct3D header
//
//============================================================
+#ifndef MAME_OSD_MODULES_RENDER_DRAWD3D_H
+#define MAME_OSD_MODULES_RENDER_DRAWD3D_H
#pragma once
-#ifndef __WIN_DRAWD3D__
-#define __WIN_DRAWD3D__
+#include "d3d/d3dcomm.h"
+
+#include "modules/lib/osdlib.h"
+#include "modules/osdwindow.h"
-#ifdef OSD_WINDOWS
+#include "sliderdirtynotifier.h"
#include <windows.h>
#include <tchar.h>
#include <mmsystem.h>
#include <d3d9.h>
#include <d3dx9.h>
-#include <math.h>
#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; }
+ 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
- d3d_texture_manager * m_texture_manager; // texture manager
+ std::unique_ptr<d3d_texture_manager> m_texture_manager; // texture manager
};
-#endif // OSD_WINDOWS
-
-#endif // __WIN_DRAWD3D__
+#endif // MAME_OSD_MODULES_RENDER_DRAWD3D_H
diff --git a/src/osd/modules/render/drawgdi.cpp b/src/osd/modules/render/drawgdi.cpp
index bd0e6425b6e..f922ca24e8f 100644
--- a/src/osd/modules/render/drawgdi.cpp
+++ b/src/osd/modules/render/drawgdi.cpp
@@ -2,24 +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
{
- // free the bitmap memory
- if (m_bmdata != nullptr)
- global_free_array(m_bmdata);
-}
+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
@@ -37,6 +66,7 @@ int renderer_gdi::create()
m_bminfo.bmiHeader.biYPelsPerMeter = 0;
m_bminfo.bmiHeader.biClrUsed = 0;
m_bminfo.bmiHeader.biClrImportant = 0;
+
return 0;
}
@@ -46,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();
}
//============================================================
@@ -64,41 +90,78 @@ 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;
- global_free_array(m_bmdata);
- m_bmdata = global_alloc_array(uint8_t, m_bmsize);
+ m_bmdata.reset();
+ m_bmdata = std::make_unique<uint8_t []>(m_bmsize);
}
// 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, 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;
m_bminfo.bmiHeader.biHeight = -height;
// blit to the screen
- StretchDIBits(win->m_dc, 0, 0, width, height,
- 0, 0, width, height,
- m_bmdata, &m_bminfo, DIB_RGB_COLORS, SRCCOPY);
+ StretchDIBits(
+ 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 49d05c18daa..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
-//
-//============================================================
-
-#pragma once
-
-#ifndef __DRAWGDI__
-#define __DRAWGDI__
-
-// 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;
- uint8_t * m_bmdata;
- size_t m_bmsize;
-};
-
-#endif // __DRAWGDI__
diff --git a/src/osd/modules/render/drawnone.cpp b/src/osd/modules/render/drawnone.cpp
index e8bbfa15432..55ce1bbed18 100644
--- a/src/osd/modules/render/drawnone.cpp
+++ b/src/osd/modules/render/drawnone.cpp
@@ -6,36 +6,76 @@
//
//============================================================
-// standard windows headers
-#include <windows.h>
+#include "render_module.h"
-// MAME headers
-#include "emu.h"
+#include "modules/lib/osdobj_common.h"
+#include "modules/osdmodule.h"
+#include "modules/osdwindow.h"
-#include "drawnone.h"
+#include "main.h"
+#include "render.h"
-//============================================================
-// drawnone_window_get_primitives
-//============================================================
+#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;
-#if defined(OSD_WINDOWS)
- GetClientRect(std::static_pointer_cast<win_window_info>(win)->platform_window(), &client);
-#elif defined(OSD_UWP)
- auto bounds = std::static_pointer_cast<uwp_window_info>(win)->platform_window()->Bounds;
- client.left = bounds.Left;
- client.right = bounds.Right;
- client.top = bounds.Top;
- client.bottom = bounds.Bottom;
-#endif
- 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 6837e63bbe3..f9f76946bf4 100644
--- a/src/osd/modules/render/drawogl.cpp
+++ b/src/osd/modules/render/drawogl.cpp
@@ -12,35 +12,63 @@
//
//============================================================
-// standard C headers
-#include <math.h>
-#include <stdio.h>
+#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>
+
#ifndef APIENTRY
#define APIENTRY
#endif
@@ -67,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
@@ -123,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
@@ -236,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();
-
- global_free(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;
@@ -340,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"
@@ -356,45 +585,6 @@ static void loadgl_functions(osd_gl_context *context)
#endif
}
-//============================================================
-// Load GL library
-//============================================================
-
-#ifdef USE_DISPATCH_GL
-osd_gl_dispatch *gl_dispatch;
-#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 = global_alloc(osd_gl_dispatch);
-#endif
- s_dll_loaded = true;
- }
-}
-
void renderer_ogl::initialize_gl()
{
int has_and_allow_texturerect = 0;
@@ -420,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)
@@ -430,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)
{
@@ -460,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)
@@ -474,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)
@@ -517,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)
@@ -557,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 = global_alloc(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 = global_alloc(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 = global_alloc(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;
@@ -590,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");
@@ -623,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 )
- return;
-
- auto win = try_getwindow();
- // During destroy this can get called
- // and the window is no longer available
- if (win == nullptr)
+ if (!m_initialized)
return;
- m_gl_context->MakeCurrent();
+ m_gl_context->make_current();
- 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();
@@ -651,60 +826,54 @@ 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;
texture->data_own=false;
}
- global_free(texture);
+ 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
@@ -740,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 )
{
@@ -922,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)
@@ -934,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 )
{
@@ -953,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);
@@ -1026,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))
{
@@ -1047,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)
{
@@ -1116,7 +1240,42 @@ int renderer_ogl::draw(const int update)
// |_________|
// (0,h) (w,h)
- glViewport(0.0, 0.0, (GLsizei) m_width, (GLsizei) m_height);
+ GLsizei iScale = 1;
+
+ /*
+ Mac hack: macOS version 10.15 and later flipped from assuming you don't support Retina to
+ assuming you do support Retina. SDL 2.0.11 is scheduled to fix this, but it's not out yet.
+ So we double-scale everything if you're on 10.15 or later and SDL is not at least version 2.0.11.
+ */
+ #if defined(SDLMAME_MACOSX) && !defined(OSD_MAC)
+ SDL_version sdlVers;
+ SDL_GetVersion(&sdlVers);
+ // Only do this if SDL is not at least 2.0.11.
+ if ((sdlVers.major == 2) && (sdlVers.minor == 0) && (sdlVers.patch < 11))
+ #endif
+ #if defined(SDLMAME_MACOSX) || defined(OSD_MAC)
+ {
+ // now get the Darwin kernel version
+ int dMaj, dMin, dPatch;
+ char versStr[64];
+ dMaj = dMin = dPatch = 0;
+ size_t size = sizeof(versStr);
+ int retVal = sysctlbyname("kern.osrelease", versStr, &size, NULL, 0);
+ if (retVal == 0)
+ {
+ sscanf(versStr, "%d.%d.%d", &dMaj, &dMin, &dPatch);
+ // 10.15 Catalina is Darwin version 19
+ if (dMaj >= 19)
+ {
+ // do the workaround for Retina being forced on
+ osd_printf_verbose("OpenGL: enabling Retina workaround\n");
+ iScale = 2;
+ }
+ }
+ }
+ #endif
+
+ glViewport(0.0, 0.0, (GLsizei) m_width * iScale, (GLsizei) m_height * iScale);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, (GLdouble) m_width, (GLdouble) m_height, 0.0, 0.0, -1.0);
@@ -1152,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;
@@ -1196,6 +1354,10 @@ int renderer_ogl::draw(const int update)
if(pendingPrimitive!=curPrimitive)
{
+ if (curPrimitive==GL_POINTS)
+ glPointSize(prim.width);
+ else
+ glLineWidth(prim.width);
glBegin(curPrimitive);
pendingPrimitive=curPrimitive;
}
@@ -1212,11 +1374,6 @@ int renderer_ogl::draw(const int update)
}
#else
{
- const line_aa_step *step = line_aa_4step;
- render_bounds b0, b1;
- float r, g, b, a;
- float effwidth;
-
// we're not gonna play fancy here. close anything pending and let's go.
if (pendingPrimitive!=GL_NO_PRIMITIVE && pendingPrimitive!=curPrimitive)
{
@@ -1227,12 +1384,10 @@ int renderer_ogl::draw(const int update)
set_blendmode(sdl, PRIMFLAG_GET_BLENDMODE(prim.flags));
// compute the effective width based on the direction of the line
- effwidth = prim.width();
- if (effwidth < 0.5f)
- effwidth = 0.5f;
+ float effwidth = std::max(prim.width(), 0.5f);
// determine the bounds of a quad to draw this line
- render_line_to_quad(&prim.bounds, effwidth, 0.0f, &b0, &b1);
+ auto [b0, b1] = render_line_to_quad(prim.bounds, effwidth, 0.0f);
// fix window position
b0.x0 += hofs;
@@ -1245,7 +1400,7 @@ int renderer_ogl::draw(const int update)
b1.y1 += vofs;
// iterate over AA steps
- for (step = PRIMFLAG_GET_ANTIALIAS(prim.flags) ? line_aa_4step : line_aa_1step; step->weight != 0; step++)
+ for (const line_aa_step *step = PRIMFLAG_GET_ANTIALIAS(prim.flags) ? line_aa_4step : line_aa_1step; step->weight != 0; step++)
{
glBegin(GL_TRIANGLE_STRIP);
@@ -1262,14 +1417,10 @@ int renderer_ogl::draw(const int update)
glVertex2f(b1.x1 + step->xoffs, b1.y1 + step->yoffs);
// determine the color of the line
- r = (prim.color.r * step->weight);
- g = (prim.color.g * step->weight);
- b = (prim.color.b * step->weight);
- a = (prim.color.a * 255.0f);
- if (r > 1.0) r = 1.0;
- if (g > 1.0) g = 1.0;
- if (b > 1.0) b = 1.0;
- if (a > 1.0) a = 1.0;
+ float r = std::min(prim.color.r * step->weight, 1.0f);
+ float g = std::min(prim.color.g * step->weight, 1.0f);
+ float b = std::min(prim.color.b * step->weight, 1.0f);
+ float a = std::min(prim.color.a * 255.0f, 1.0f);
glColor4f(r, g, b, a);
// texture = texture_update(window, &prim, 0);
@@ -1377,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;
}
@@ -1513,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;
@@ -1610,10 +1760,9 @@ void renderer_ogl::texture_compute_size_type(const render_texinfo *texsource, og
// texture_create
//============================================================
-static int gl_checkFramebufferStatus(void)
+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;
@@ -1653,14 +1802,14 @@ static int gl_checkFramebufferStatus(void)
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",
@@ -1675,10 +1824,10 @@ static int texture_fbo_create(uint32_t text_unit, uint32_t text_name, uint32_t f
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+ 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() )
@@ -1715,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++)
@@ -1773,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);
@@ -1783,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++)
@@ -1804,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,
@@ -1833,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);
@@ -1854,8 +2001,8 @@ int renderer_ogl::texture_shader_create(const render_texinfo *texsource, ogl_tex
}
else
{
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
GL_CHECK_ERROR_NORMAL();
@@ -1868,7 +2015,11 @@ ogl_texture_info *renderer_ogl::texture_create(const render_texinfo *texsource,
ogl_texture_info *texture;
// allocate a new texture
- texture = global_alloc(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);
@@ -1877,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
{
@@ -1933,14 +2083,14 @@ 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 )
{
if ( texture_shader_create(texsource, texture, flags) )
{
- global_free(texture);
+ delete texture;
return nullptr;
}
}
@@ -1976,8 +2126,8 @@ ogl_texture_info *renderer_ogl::texture_create(const render_texinfo *texsource,
if( texture->texTarget==GL_TEXTURE_RECTANGLE_ARB )
{
// texture rectangles can't wrap
- glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
- glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
} else {
// set wrapping mode appropriately
if (texture->flags & PRIMFLAG_TEXWRAP_MASK)
@@ -1987,8 +2137,8 @@ ogl_texture_info *renderer_ogl::texture_create(const render_texinfo *texsource,
}
else
{
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
}
}
@@ -1998,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);
}
@@ -2033,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
@@ -2297,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
@@ -2371,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)
@@ -2390,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,
@@ -2422,7 +2572,7 @@ static int compare_texture_primitive(const ogl_texture_info *texture, const rend
texture->texinfo.width == prim->texture.width &&
texture->texinfo.height == prim->texture.height &&
texture->texinfo.rowpixels == prim->texture.rowpixels &&
- /* texture->texinfo.palette == prim->texture.palette && */
+ texture->texinfo.palette == prim->texture.palette &&
((texture->flags ^ prim->flags) & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) == 0)
return 1;
else
@@ -2540,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]);
@@ -2554,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 )
@@ -2590,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 )
{
@@ -2598,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);
}
}
@@ -2610,8 +2760,7 @@ void renderer_ogl::texture_shader_update(ogl_texture_info *texture, render_conta
if (container!=nullptr)
{
- render_container::user_settings settings;
- container->get_user_settings(settings);
+ render_container::user_settings settings = container->get_user_settings();
/* FIXME: the code below is in just for illustration issue on
* how to set shader variables. gamma, contrast and brightness are
* handled already by the core
@@ -2620,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);
}
@@ -2642,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
@@ -2687,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
@@ -2706,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);
@@ -2746,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 525ba0c3ffa..00000000000
--- a/src/osd/modules/render/drawogl.h
+++ /dev/null
@@ -1,242 +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
-//
-//============================================================
-
-#pragma once
-
-#ifndef __DRAWOGL__
-#define __DRAWOGL__
-
-// 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"
-
-//============================================================
-// 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 // __DRAWOGL__
diff --git a/src/osd/modules/render/drawsdl.cpp b/src/osd/modules/render/drawsdl.cpp
index c80b59185af..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 <math.h>
-#include <stdio.h>
+#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 "emu.h"
-#include "ui/uimain.h"
+#include "emucore.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,42 +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);
- if (m_yuv_bitmap)
- {
- global_free_array(m_yuv_bitmap);
- m_yuv_bitmap = nullptr;
- }
+ 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)
- m_yuv_bitmap = global_alloc_array(uint16_t, m_hw_scale_width * m_hw_scale_height);
+ 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);
@@ -186,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)
@@ -220,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);
}
}
@@ -257,16 +286,6 @@ renderer_sdl1::~renderer_sdl1()
{
destroy_all_textures();
- if (m_yuv_lookup != nullptr)
- {
- global_free_array(m_yuv_lookup);
- m_yuv_lookup = nullptr;
- }
- if (m_yuv_bitmap != nullptr)
- {
- global_free_array(m_yuv_bitmap);
- m_yuv_bitmap = nullptr;
- }
SDL_DestroyRenderer(m_sdl_renderer);
}
@@ -302,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;
@@ -310,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();
@@ -384,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
@@ -402,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);
@@ -411,28 +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(*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:
@@ -444,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, mamewidth, mameheight, mamewidth);
- sm->yuv_blit((uint16_t *)m_yuv_bitmap, surfptr, pitch, m_yuv_lookup, 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);
@@ -521,12 +536,11 @@ void renderer_sdl1::yuv_lookup_set(unsigned int pen, unsigned char red,
void renderer_sdl1::yuv_init()
{
- unsigned char r,g,b;
- if (m_yuv_lookup == nullptr)
- m_yuv_lookup = global_alloc_array(uint32_t, 65536);
- for (r = 0; r < 32; r++)
- for (g = 0; g < 32; g++)
- for (b = 0; b < 32; b++)
+ if (!m_yuv_lookup)
+ m_yuv_lookup = std::make_unique<uint32_t []>(65536);
+ for (unsigned char r = 0; r < 32; r++)
+ for (unsigned char g = 0; g < 32; g++)
+ for (unsigned char b = 0; b < 32; b++)
{
int idx = (r << 10) | (g << 5) | b;
yuv_lookup_set(idx,
@@ -538,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;
@@ -592,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 */
@@ -627,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 */
@@ -653,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 */
@@ -677,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 6c0b51c0663..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
-//
-//============================================================
-
-#pragma once
-
-#ifndef __DRAWSDL1__
-#define __DRAWSDL1__
-
-#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(nullptr)
- , m_yuv_bitmap(nullptr)
- //, 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
- uint32_t *m_yuv_lookup;
- 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 // __DRAWSDL1__
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