diff options
Diffstat (limited to 'src/osd/modules/render/d3d/d3dhlsl.cpp')
-rw-r--r-- | src/osd/modules/render/d3d/d3dhlsl.cpp | 1054 |
1 files changed, 527 insertions, 527 deletions
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); } |