summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author ImJezze <jezze@gmx.net>2016-06-19 14:18:40 +0200
committer ImJezze <jezze@gmx.net>2016-06-20 00:03:43 +0200
commitf056b622bcad7c19a521a9a5a181471ff301f5f2 (patch)
tree49903f9144d464e92b45b261b8cc04942a942440
parenta45a1fcf0d76986b23f3dee65fa1e7034fa26315 (diff)
Fixed crash of D3D when sliders menu is openend and resizing the window or switching between window and full screen mode
-rw-r--r--src/osd/modules/render/d3d/d3dhlsl.cpp209
-rw-r--r--src/osd/modules/render/d3d/d3dhlsl.h20
-rw-r--r--src/osd/modules/render/drawd3d.cpp345
-rw-r--r--src/osd/modules/render/drawd3d.h19
4 files changed, 319 insertions, 274 deletions
diff --git a/src/osd/modules/render/d3d/d3dhlsl.cpp b/src/osd/modules/render/d3d/d3dhlsl.cpp
index 9dcb3f06f8e..be7138bfe6f 100644
--- a/src/osd/modules/render/d3d/d3dhlsl.cpp
+++ b/src/osd/modules/render/d3d/d3dhlsl.cpp
@@ -43,23 +43,13 @@ static void get_vector(const char *data, int count, float *out, bool report_erro
//============================================================
shaders::shaders() :
- d3dintf(nullptr), machine(nullptr), d3d(nullptr), num_screens(0), curr_screen(0),
- avi_output_file(nullptr), avi_frame(0), avi_copy_surface(nullptr), avi_copy_texture(nullptr), avi_final_target(nullptr), avi_final_texture(nullptr),
+ d3dintf(nullptr), machine(nullptr), d3d(nullptr), post_fx_enable(false), oversampling_enable(false), paused(true), num_screens(0), curr_screen(0), lastidx(-1),
+ shadow_texture(nullptr), options(nullptr), avi_output_file(nullptr), avi_frame(0), avi_copy_surface(nullptr), avi_copy_texture(nullptr), avi_final_target(nullptr), avi_final_texture(nullptr),
black_surface(nullptr), black_texture(nullptr), render_snap(false), snap_rendered(false), snap_copy_target(nullptr), snap_copy_texture(nullptr), snap_target(nullptr), snap_texture(nullptr),
- snap_width(0), snap_height(0), lines_pending(false), backbuffer(nullptr), curr_effect(nullptr), default_effect(nullptr), prescale_effect(nullptr), post_effect(nullptr), distortion_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), fsfx_vertices(nullptr), curr_texture(nullptr), curr_render_target(nullptr), curr_poly(nullptr)
+ snap_width(0), snap_height(0), lines_pending(false), initialized(false), backbuffer(nullptr), curr_effect(nullptr), default_effect(nullptr), prescale_effect(nullptr), post_effect(nullptr),
+ distortion_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), fsfx_vertices(nullptr), curr_texture(nullptr), curr_render_target(nullptr), curr_poly(nullptr), targethead(nullptr), cachehead(nullptr)
{
- master_enable = false;
- vector_enable = true;
- oversampling_enable = false;
- shadow_texture = nullptr;
- options = nullptr;
- paused = true;
- lastidx = -1;
- targethead = nullptr;
- cachehead = nullptr;
- initialized = false;
}
@@ -74,6 +64,12 @@ shaders::~shaders()
delete slider;
}
+ if (options != nullptr)
+ {
+ global_free(options);
+ options = nullptr;
+ }
+
cache_target *currcache = cachehead;
while(cachehead != nullptr)
{
@@ -98,7 +94,7 @@ shaders::~shaders()
void shaders::window_save()
{
- if (!master_enable || !d3dintf->post_fx_available)
+ if (!enabled())
{
return;
}
@@ -130,7 +126,7 @@ void shaders::window_save()
void shaders::window_record()
{
- if (!master_enable || !d3dintf->post_fx_available)
+ if (!enabled())
{
return;
}
@@ -155,7 +151,7 @@ void shaders::window_record()
void shaders::avi_update_snap(IDirect3DSurface9 *surface)
{
- if (!master_enable || !d3dintf->post_fx_available)
+ if (!enabled())
{
return;
}
@@ -208,7 +204,7 @@ void shaders::avi_update_snap(IDirect3DSurface9 *surface)
void shaders::render_snapshot(IDirect3DSurface9 *surface)
{
- if (!master_enable || !d3dintf->post_fx_available)
+ if (!enabled())
{
return;
}
@@ -310,7 +306,7 @@ void shaders::render_snapshot(IDirect3DSurface9 *surface)
void shaders::record_texture()
{
- if (!master_enable || !d3dintf->post_fx_available)
+ if (!enabled())
{
return;
}
@@ -353,7 +349,7 @@ void shaders::record_texture()
void shaders::end_avi_recording()
{
- if (!master_enable || !d3dintf->post_fx_available)
+ if (!enabled())
{
return;
}
@@ -369,52 +365,12 @@ void shaders::end_avi_recording()
//============================================================
-// shaders::toggle
-//============================================================
-
-void shaders::toggle(std::vector<ui::menu_item>& sliders)
-{
- if (master_enable)
- {
- if (initialized)
- {
- // free shader resources before renderer resources
- delete_resources(false);
- }
-
- master_enable = !master_enable;
-
- // free shader resources and re-create
- d3d->device_delete_resources();
- d3d->device_create_resources();
- }
- else
- {
- master_enable = !master_enable;
-
- // free shader resources and re-create
- d3d->device_delete_resources();
- d3d->device_create_resources();
-
- if (!initialized)
- {
- // re-create shader resources after renderer resources
- bool failed = create_resources(false, sliders);
- if (failed)
- {
- master_enable = false;
- }
- }
- }
-}
-
-//============================================================
// shaders::begin_avi_recording
//============================================================
void shaders::begin_avi_recording(const char *name)
{
- if (!master_enable || !d3dintf->post_fx_available)
+ if (!enabled())
{
return;
}
@@ -573,7 +529,7 @@ void shaders::remove_render_target(d3d_render_target *rt)
void shaders::set_texture(texture_info *texture)
{
- if (!master_enable || !d3dintf->post_fx_available)
+ if (!enabled())
{
return;
}
@@ -602,53 +558,64 @@ void shaders::set_texture(texture_info *texture)
// shaders::init
//============================================================
-void shaders::init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *renderer)
+bool shaders::init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *renderer)
{
- d3dx9_dll = osd::dynamic_module::open({ "d3dx9_43.dll" });
+ osd_printf_verbose("Direct3D: Initialize HLSL\n");
- d3dx_create_effect_from_file_ptr = d3dx9_dll->bind<d3dx_create_effect_from_file_fn>("D3DXCreateEffectFromFileW");
- if (!d3dx_create_effect_from_file_ptr)
+ if (initialized)
{
- osd_printf_verbose("Direct3D: Unable to find D3DXCreateEffectFromFileW\n");
- d3dintf->post_fx_available = false;
- return;
+ return false;
}
- d3dintf->post_fx_available = true;
- this->d3dintf = d3dintf;
- this->machine = machine;
- this->d3d = renderer;
- this->options = renderer->get_shaders_options();
-
// check if no driver loaded (not all settings might be loaded yet)
if (&machine->system() == &GAME_NAME(___empty))
{
- return;
+ return false;
}
- // check if another driver is loaded
+ // check if another driver is loaded and reset last options
if (std::strcmp(machine->system().name, last_system_name) != 0)
{
strncpy(last_system_name, machine->system().name, sizeof(last_system_name));
- options->params_init = false;
last_options.params_init = false;
}
+ d3dx9_dll = osd::dynamic_module::open({ "d3dx9_43.dll" });
+
+ d3dx_create_effect_from_file_ptr = d3dx9_dll->bind<d3dx_create_effect_from_file_fn>("D3DXCreateEffectFromFileW");
+ if (!d3dx_create_effect_from_file_ptr)
+ {
+ osd_printf_verbose("Direct3D: Unable to find D3DXCreateEffectFromFileW\n");
+ return false;
+ }
+
+ d3dintf->post_fx_available = true;
+
+ this->d3dintf = d3dintf;
+ this->machine = machine;
+ this->d3d = renderer;
+
enumerate_screens();
windows_options &winoptions = downcast<windows_options &>(machine->options());
- master_enable = winoptions.d3d_hlsl_enable();
+ 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)
{
+ osd_printf_verbose("Direct3D: First restore options\n");
options = &last_options;
}
+ // read options if not initialized
if (!options->params_init)
{
strncpy(options->shadow_mask_texture, winoptions.screen_shadow_mask_texture(), sizeof(options->shadow_mask_texture));
@@ -719,9 +686,19 @@ void shaders::init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *r
options->bloom_level8_weight = winoptions.screen_bloom_lvl8_weight();
options->params_init = true;
+
+ osd_printf_verbose("Direct3D: First store options\n");
+ last_options = *options;
+ options = &last_options;
}
options->params_dirty = true;
+
+ initialized = true;
+
+ osd_printf_verbose("Direct3D: HLSL initialized\n");
+
+ return true;
}
@@ -734,7 +711,7 @@ void shaders::init_fsfx_quad(void *vertbuf)
// Called at the start of each frame by the D3D code in order to reserve two triangles
// that are guaranteed to be at a fixed position so as to simply use D3DPT_TRIANGLELIST, 0, 2
// instead of having to do bookkeeping about a specific screen quad
- if (!master_enable || !d3dintf->post_fx_available)
+ if (!enabled())
{
return;
}
@@ -805,15 +782,16 @@ void shaders::init_fsfx_quad(void *vertbuf)
// shaders::create_resources
//============================================================
-int shaders::create_resources(bool reset, std::vector<ui::menu_item>& sliders)
+int shaders::create_resources()
{
- if (!master_enable || !d3dintf->post_fx_available)
+ if (!initialized || !enabled())
{
return 0;
}
if (last_options.params_init)
{
+ osd_printf_verbose("Direct3D: Restore options\n");
options = &last_options;
}
@@ -982,11 +960,6 @@ int shaders::create_resources(bool reset, std::vector<ui::menu_item>& sliders)
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);
- initialized = true;
-
- std::vector<ui::menu_item> my_sliders = init_slider_list();
- sliders.insert(sliders.end(), my_sliders.begin(), my_sliders.end());
-
return 0;
}
@@ -997,7 +970,7 @@ int shaders::create_resources(bool reset, std::vector<ui::menu_item>& sliders)
void shaders::begin_draw()
{
- if (!master_enable || !d3dintf->post_fx_available)
+ if (!enabled())
{
return;
}
@@ -1094,7 +1067,7 @@ void shaders::blit(
void shaders::end_frame()
{
- if (!master_enable || !d3dintf->post_fx_available)
+ if (!enabled())
{
return;
}
@@ -1587,7 +1560,7 @@ void shaders::ui_pass(poly_info *poly, int vertnum)
void shaders::render_quad(poly_info *poly, int vertnum)
{
- if (!master_enable || !d3dintf->post_fx_available)
+ if (!enabled())
{
return;
}
@@ -1644,7 +1617,7 @@ void shaders::render_quad(poly_info *poly, int vertnum)
curr_screen++;
}
- else if (PRIMFLAG_GET_VECTOR(poly->get_flags()) && vector_enable)
+ else if (PRIMFLAG_GET_VECTOR(poly->get_flags()))
{
lines_pending = true;
@@ -1673,7 +1646,7 @@ void shaders::render_quad(poly_info *poly, int vertnum)
osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call\n", result);
}
}
- else if (PRIMFLAG_GET_VECTORBUF(poly->get_flags()) && vector_enable)
+ else if (PRIMFLAG_GET_VECTORBUF(poly->get_flags()))
{
curr_screen = curr_screen < num_screens ? curr_screen : 0;
@@ -1748,7 +1721,7 @@ void shaders::render_quad(poly_info *poly, int vertnum)
void shaders::end_draw()
{
- if (!master_enable || !d3dintf->post_fx_available)
+ if (!enabled())
{
return;
}
@@ -1790,6 +1763,11 @@ bool shaders::add_cache_target(renderer_d3d9* d3d, texture_info* texture, int so
d3d_render_target* shaders::get_texture_target(render_primitive *prim, texture_info *texture)
{
+ if (!enabled())
+ {
+ return nullptr;
+ }
+
auto win = d3d->assert_window();
int target_width = int(prim->get_quad_width() + 0.5f);
@@ -1810,7 +1788,7 @@ d3d_render_target* shaders::get_texture_target(render_primitive *prim, texture_i
// check if the size of the screen quad has changed
if (target->target_width != target_width || target->target_height != target_height)
{
- osd_printf_verbose("get_texture_target() - invalid size\n");
+ osd_printf_verbose("Direct3D: Get texture target - invalid size\n");
return nullptr;
}
}
@@ -1821,7 +1799,7 @@ d3d_render_target* shaders::get_texture_target(render_primitive *prim, texture_i
d3d_render_target* shaders::get_vector_target(render_primitive *prim)
{
- if (!vector_enable)
+ if (!enabled())
{
return nullptr;
}
@@ -1850,7 +1828,7 @@ d3d_render_target* shaders::get_vector_target(render_primitive *prim)
// check if the size of the screen quad has changed
if (target->target_width != target_width || target->target_height != target_height)
{
- osd_printf_verbose("get_vector_target() - invalid size\n");
+ osd_printf_verbose("Direct3D: Get vector target - invalid size\n");
return nullptr;
}
}
@@ -1859,8 +1837,13 @@ d3d_render_target* shaders::get_vector_target(render_primitive *prim)
return target;
}
-void shaders::create_vector_target(render_primitive *prim)
+bool shaders::create_vector_target(render_primitive *prim)
{
+ if (!enabled())
+ {
+ return false;
+ }
+
auto win = d3d->assert_window();
// source and target size are the same for vector targets
@@ -1876,11 +1859,13 @@ void shaders::create_vector_target(render_primitive *prim)
std::swap(target_width, target_height);
}
- osd_printf_verbose("create_vector_target() - %d, %d\n", target_width, target_height);
+ osd_printf_verbose("Direct3D: Create vector target - %dx%d\n", target_width, target_height);
if (!add_render_target(d3d, prim, nullptr, source_width, source_height, target_width, target_height))
{
- vector_enable = false;
+ return false;
}
+
+ return true;
}
@@ -1966,7 +1951,7 @@ void shaders::enumerate_screens()
bool shaders::register_texture(render_primitive *prim, texture_info *texture)
{
- if (!master_enable || !d3dintf->post_fx_available)
+ if (!enabled())
{
return false;
}
@@ -1985,7 +1970,7 @@ bool shaders::register_texture(render_primitive *prim, texture_info *texture)
std::swap(target_width, target_height);
}
- osd_printf_verbose("register_texture() - %d, %d\n", target_width, target_height);
+ osd_printf_verbose("Direct3D: Register texture - %dx%d\n", target_width, target_height);
if (!add_render_target(d3d, prim, texture, source_width, source_height, target_width, target_height))
{
return false;
@@ -1999,21 +1984,21 @@ bool shaders::register_texture(render_primitive *prim, texture_info *texture)
// shaders::delete_resources
//============================================================
-void shaders::delete_resources(bool reset)
+void shaders::delete_resources()
{
- if (!master_enable || !d3dintf->post_fx_available)
+ if (!initialized || !enabled())
{
return;
}
+ end_avi_recording();
+
if (options != nullptr)
{
+ osd_printf_verbose("Direct3D: Store options\n");
last_options = *options;
- options = nullptr;
}
- initialized = false;
-
cache_target *currcache = cachehead;
while(cachehead != nullptr)
{
@@ -2490,9 +2475,9 @@ void *shaders::get_slider_option(int id, int index)
return nullptr;
}
-std::vector<ui::menu_item> shaders::init_slider_list()
+void shaders::init_slider_list()
{
- std::vector<ui::menu_item> sliders;
+ m_sliders.clear();
for (slider* slider : internal_sliders)
{
@@ -2503,7 +2488,7 @@ std::vector<ui::menu_item> shaders::init_slider_list()
auto first_screen = machine->first_screen();
if (first_screen == nullptr)
{
- return sliders;
+ return;
}
int screen_type = first_screen->screen_type();
@@ -2559,12 +2544,10 @@ std::vector<ui::menu_item> shaders::init_slider_list()
item.flags = 0;
item.ref = core_slider;
item.type = ui::menu_item_type::SLIDER;
- sliders.push_back(item);
+ m_sliders.push_back(item);
}
}
}
-
- return sliders;
}
diff --git a/src/osd/modules/render/d3d/d3dhlsl.h b/src/osd/modules/render/d3d/d3dhlsl.h
index 3c9daa3c6ad..1b3fdc1fa2d 100644
--- a/src/osd/modules/render/d3d/d3dhlsl.h
+++ b/src/osd/modules/render/d3d/d3dhlsl.h
@@ -301,14 +301,13 @@ public:
shaders();
~shaders();
- void init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *renderer);
+ bool init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *renderer);
- bool enabled() { return master_enable; }
- void toggle(std::vector<ui::menu_item>& sliders);
+ bool enabled() { return post_fx_enable && d3dintf->post_fx_available; }
+ void toggle() { post_fx_enable = initialized && !post_fx_enable; }
- bool vector_enabled() { return master_enable && vector_enable; }
d3d_render_target* get_vector_target(render_primitive *prim);
- void create_vector_target(render_primitive *prim);
+ bool create_vector_target(render_primitive *prim);
void begin_frame();
void end_frame();
@@ -339,13 +338,14 @@ public:
void remove_render_target(int source_width, int source_height, UINT32 screen_index, UINT32 page_index);
void remove_render_target(d3d_render_target *rt);
- int create_resources(bool reset, std::vector<ui::menu_item>& sliders);
- void delete_resources(bool reset);
+ int create_resources();
+ void delete_resources();
// slider-related functions
virtual INT32 slider_changed(running_machine &machine, void *arg, int /*id*/, std::string *str, INT32 newval) override;
slider_state* slider_alloc(running_machine &machine, int id, const char *title, INT32 minval, INT32 defval, INT32 maxval, INT32 incval, void *arg);
- std::vector<ui::menu_item> init_slider_list();
+ 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:
@@ -382,8 +382,7 @@ private:
running_machine * machine;
renderer_d3d9 * d3d; // D3D renderer
- bool master_enable; // overall enable flag
- bool vector_enable; // vector post-processing enable flag
+ bool post_fx_enable; // overall enable flag
bool oversampling_enable; // oversampling enable flag
bool paused; // whether or not rendering is currently paused
int num_screens; // number of emulated physical screens
@@ -442,6 +441,7 @@ private:
cache_target * cachehead;
std::vector<slider*> internal_sliders;
+ std::vector<ui::menu_item> m_sliders;
static slider_desc s_sliders[];
static hlsl_options last_options; // last used options
diff --git a/src/osd/modules/render/drawd3d.cpp b/src/osd/modules/render/drawd3d.cpp
index 4fb1696a1eb..ce024866319 100644
--- a/src/osd/modules/render/drawd3d.cpp
+++ b/src/osd/modules/render/drawd3d.cpp
@@ -137,7 +137,7 @@ int renderer_d3d9::create()
void renderer_d3d9::toggle_fsfx()
{
- set_restarting(true);
+ set_toggle(true);
}
void renderer_d3d9::record()
@@ -184,14 +184,14 @@ render_primitive_list *renderer_d3d9::get_primitives()
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;
+ return true;
}
d3dintf->d3dobj = (*d3d9_create_ptr)(D3D_SDK_VERSION);
@@ -520,21 +520,23 @@ texture_info *d3d_texture_manager::find_texinfo(const render_texinfo *texinfo, U
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_restarting(false), m_mod2x_supported(0), m_mod4x_supported(0),
+ 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_hlsl_buf(nullptr), m_shaders(nullptr), m_shaders_options(nullptr), m_texture_manager(nullptr)
+ m_last_wrap(), m_last_modmode(0), m_hlsl_buf(nullptr), m_shaders(nullptr), m_texture_manager(nullptr)
{
}
int renderer_d3d9::initialize()
{
+ osd_printf_verbose("Direct3D: Initialize\n");
+
// configure the adapter for the mode we want
if (config_adapter_mode())
{
return false;
}
- // create the device immediately for the full screen case (defer for window mode)
+ // 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(win->main_window()->platform_window<HWND>()))
{
@@ -552,13 +554,24 @@ int renderer_d3d9::pre_window_draw_check()
if (win->m_resize_state == RESIZE_STATE_RESIZING)
return 0;
- // if we're restarting the renderer, leave things alone
- if (m_restarting)
+ // check if shaders should be toggled
+ if (m_toggle)
{
- m_sliders.clear();
- m_shaders->toggle(m_sliders);
+ m_toggle = false;
+
+ // free resources
+ device_delete_resources();
- m_restarting = false;
+ m_shaders->toggle();
+ m_sliders_dirty = true;
+
+ // re-create resources
+ if (device_create_resources())
+ {
+ osd_printf_verbose("Direct3D: failed to recreate resources for device; failing permanently\n");
+ device_delete();
+ return 1;
+ }
}
// if we have a device, check the cooperative level
@@ -630,11 +643,14 @@ void d3d_texture_manager::update_textures()
}
else if(PRIMFLAG_GET_VECTORBUF(prim.flags))
{
- if (m_renderer->get_shaders()->vector_enabled())
+ if (m_renderer->get_shaders()->enabled())
{
if (!m_renderer->get_shaders()->get_vector_target(&prim))
{
- m_renderer->get_shaders()->create_vector_target(&prim);
+ if (!m_renderer->get_shaders()->create_vector_target(&prim))
+ {
+ d3dintf->post_fx_available = false;
+ }
}
}
}
@@ -736,6 +752,65 @@ void renderer_d3d9::end_frame()
osd_printf_verbose("Direct3D: Error %08lX during device present call\n", result);
}
+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;
+ m_presentation.BackBufferFormat = m_pixformat;
+ m_presentation.BackBufferCount = video_config.triplebuf ? 2 : 1;
+ m_presentation.MultiSampleType = D3DMULTISAMPLE_NONE;
+ m_presentation.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ m_presentation.hDeviceWindow = win->platform_window<HWND>();
+ m_presentation.Windowed = !win->fullscreen() || win->win_has_menu();
+ 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.waitvsync
+ || video_config.syncrefresh)
+ ? D3DPRESENT_INTERVAL_ONE
+ : D3DPRESENT_INTERVAL_IMMEDIATE;
+}
+
+
+void renderer_d3d9::update_gamma_ramp()
+{
+ if (m_gamma_supported)
+ {
+ return;
+ }
+
+ auto win = assert_window();
+
+ // create a standard ramp
+ D3DGAMMARAMP ramp;
+
+ // set the gamma if we need to
+ if (win->fullscreen())
+ {
+ // only set the gamma if it's not 1.0
+ windows_options &options = downcast<windows_options &>(win->machine().options());
+ float brightness = options.full_screen_brightness();
+ float contrast = options.full_screen_contrast();
+ float gamma = options.full_screen_gamma();
+ if (brightness != 1.0f || contrast != 1.0f || gamma != 1.0f)
+ {
+ for (int i = 0; i < 256; i++)
+ {
+ ramp.red[i] = ramp.green[i] = ramp.blue[i] = apply_brightness_contrast_gamma(i, brightness, contrast, gamma) << 8;
+ }
+ }
+ }
+
+ m_device->SetGammaRamp(0, 0, &ramp);
+}
+
+
//============================================================
// device_create
//============================================================
@@ -749,22 +824,8 @@ int renderer_d3d9::device_create(HWND device_hwnd)
}
// verify the caps
- int verify = device_verify_caps();
- if (verify == 2)
+ if (device_verify_caps())
{
- osd_printf_error("Error: Device does not meet minimum requirements for Direct3D rendering\n");
- return 1;
- }
- if (verify == 1)
- {
- osd_printf_warning("Warning: Device may not perform well for Direct3D rendering\n");
- }
-
- // verify texture formats
- HRESULT result = d3dintf->d3dobj->CheckDeviceFormat(m_adapter, D3DDEVTYPE_HAL, m_pixformat, 0, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8);
- if (FAILED(result))
- {
- osd_printf_error("Error: A8R8G8B8 format textures not supported\n");
return 1;
}
@@ -773,12 +834,20 @@ int renderer_d3d9::device_create(HWND device_hwnd)
try_again:
// try for XRGB first
m_screen_format = D3DFMT_X8R8G8B8;
- 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 = 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))
{
// 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);
+ 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);
@@ -791,29 +860,12 @@ try_again:
}
}
- auto win = assert_window();
-
// initialize the D3D presentation parameters
- memset(&m_presentation, 0, sizeof(m_presentation));
- m_presentation.BackBufferWidth = m_width;
- m_presentation.BackBufferHeight = m_height;
- m_presentation.BackBufferFormat = m_pixformat;
- m_presentation.BackBufferCount = video_config.triplebuf ? 2 : 1;
- m_presentation.MultiSampleType = D3DMULTISAMPLE_NONE;
- m_presentation.SwapEffect = D3DSWAPEFFECT_DISCARD;
- m_presentation.hDeviceWindow = win->platform_window<HWND>();
- m_presentation.Windowed = !win->fullscreen() || win->win_has_menu();
- 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.waitvsync || video_config.syncrefresh) ?
- D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
+ 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 = d3dintf->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
@@ -834,52 +886,7 @@ try_again:
m_create_error_count = 0;
osd_printf_verbose("Direct3D: Device created at %dx%d\n", m_width, m_height);
- // set the gamma if we need to
- if (win->fullscreen())
- {
- // only set the gamma if it's not 1.0f
- windows_options &options = downcast<windows_options &>(win->machine().options());
- float brightness = options.full_screen_brightness();
- float contrast = options.full_screen_contrast();
- float gamma = options.full_screen_gamma();
- if (brightness != 1.0f || contrast != 1.0f || gamma != 1.0f)
- {
- // warn if we can't do it
- if (!m_gamma_supported)
- {
- osd_printf_warning("Direct3D: Warning - device does not support full screen gamma correction.\n");
- }
- else
- {
- // create a standard ramp and set it
- D3DGAMMARAMP ramp;
- for (int i = 0; i < 256; i++)
- {
- ramp.red[i] = ramp.green[i] = ramp.blue[i] = apply_brightness_contrast_gamma(i, brightness, contrast, gamma) << 8;
- }
- m_device->SetGammaRamp(0, 0, &ramp);
- }
- }
- }
-
- // create shader options only once
- if (m_shaders_options == nullptr)
- {
- m_shaders_options = (hlsl_options*)global_alloc_clear<hlsl_options>();
- m_shaders_options->params_init = false;
- }
-
- m_shaders = (shaders*)global_alloc_clear<shaders>();
- m_shaders->init(d3dintf, &win->machine(), this);
-
- m_sliders.clear();
- int failed = m_shaders->create_resources(false, m_sliders);
- if (failed)
- {
- return failed;
- }
-
- m_sliders_dirty = true;
+ update_gamma_ramp();
return device_create_resources();
}
@@ -891,11 +898,35 @@ 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->init(d3dintf, &win->machine(), this))
+ {
+ m_shaders->init_slider_list();
+ m_sliders_dirty = true;
+ }
+
+ // create resources
+ if (m_shaders->create_resources())
+ {
+ osd_printf_verbose("Direct3D: failed to create HLSL resources for device\n");
+ return 1;
+ }
+
// 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() && d3dintf->post_fx_available) ? D3DFVF_XYZW : D3DFVF_XYZRHW),
- D3DPOOL_DEFAULT, &m_vertexbuf, nullptr);
+ HRESULT result = m_device->CreateVertexBuffer(
+ sizeof(vertex) * VERTEX_BUFFER_SIZE,
+ D3DUSAGE_DYNAMIC | D3DUSAGE_SOFTWAREPROCESSING | D3DUSAGE_WRITEONLY,
+ VERTEX_BASE_FORMAT | ((m_shaders->enabled() && d3dintf->post_fx_available)
+ ? D3DFVF_XYZW
+ : D3DFVF_XYZRHW),
+ D3DPOOL_DEFAULT, &m_vertexbuf, nullptr);
if (FAILED(result))
{
osd_printf_error("Error creating vertex buffer (%08X)\n", (UINT32)result);
@@ -903,8 +934,10 @@ int renderer_d3d9::device_create_resources()
}
// set the vertex format
- result = m_device->SetFVF((D3DFORMAT)(VERTEX_BASE_FORMAT | ((m_shaders->enabled() &&
- d3dintf->post_fx_available) ? D3DFVF_XYZW : D3DFVF_XYZRHW)));
+ result = m_device->SetFVF(
+ (D3DFORMAT)(VERTEX_BASE_FORMAT | ((m_shaders->enabled() && d3dintf->post_fx_available)
+ ? D3DFVF_XYZW
+ : D3DFVF_XYZRHW)));
if (FAILED(result))
{
osd_printf_error("Error setting vertex format (%08X)\n", (UINT32)result);
@@ -955,16 +988,15 @@ int renderer_d3d9::device_create_resources()
renderer_d3d9::~renderer_d3d9()
{
- if (get_shaders() != nullptr && get_shaders()->recording())
- get_shaders()->window_record();
-
device_delete();
- if (m_shaders_options != nullptr)
- {
- global_free(m_shaders_options);
- m_shaders_options = nullptr;
- }
+ // 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()
@@ -978,19 +1010,11 @@ void renderer_d3d9::exit()
void renderer_d3d9::device_delete()
{
- if (m_shaders != nullptr)
- {
- // free our effects
- m_sliders.clear();
- m_shaders->delete_resources(false);
-
- // delete the HLSL interface
- global_free(m_shaders);
- }
-
// free our base resources
device_delete_resources();
+ // we do not delete the HLSL interface here
+
if (m_texture_manager != nullptr)
{
global_free(m_texture_manager);
@@ -1012,6 +1036,11 @@ void renderer_d3d9::device_delete()
void renderer_d3d9::device_delete_resources()
{
+ if (m_shaders != nullptr)
+ {
+ m_shaders->delete_resources();
+ }
+
if (m_texture_manager != nullptr)
{
m_texture_manager->delete_resources();
@@ -1032,12 +1061,14 @@ void renderer_d3d9::device_delete_resources()
int renderer_d3d9::device_verify_caps()
{
- int retval = 0;
+ int verify = 0;
D3DCAPS9 caps;
HRESULT result = d3dintf->d3dobj->GetDeviceCaps(m_adapter, D3DDEVTYPE_HAL, &caps);
if (FAILED(result))
+ {
osd_printf_verbose("Direct3D: Error %08lX during GetDeviceCaps call\n", result);
+ }
if (caps.MaxPixelShader30InstructionSlots < 512)
{
@@ -1049,40 +1080,59 @@ int renderer_d3d9::device_verify_caps()
if (!(caps.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE))
{
osd_printf_verbose("Direct3D: Error - Device does not support immediate presentations\n");
- retval = 2;
+ verify = 2;
}
if (!(caps.PresentationIntervals & D3DPRESENT_INTERVAL_ONE))
{
osd_printf_verbose("Direct3D: Error - Device does not support per-refresh presentations\n");
- retval = 2;
+ verify = 2;
}
// verify device capabilities
if (!(caps.DevCaps & D3DDEVCAPS_CANRENDERAFTERFLIP))
{
osd_printf_verbose("Direct3D: Warning - Device does not support queued rendering after a page flip\n");
- retval = 1;
+ verify = 1;
}
if (!(caps.DevCaps & D3DDEVCAPS_HWRASTERIZATION))
{
osd_printf_verbose("Direct3D: Warning - Device does not support hardware rasterization\n");
- retval = 1;
+ verify = 1;
}
// verify texture operation capabilities
if (!(caps.TextureOpCaps & D3DTEXOPCAPS_MODULATE))
{
osd_printf_verbose("Direct3D: Warning - Device does not support texture modulation\n");
- retval = 1;
+ verify = 1;
}
- // set a simpler flag to indicate mod2x and mod4x texture modes
- m_mod2x_supported = ((caps.TextureOpCaps & D3DTEXOPCAPS_MODULATE2X) != 0);
- m_mod4x_supported = ((caps.TextureOpCaps & D3DTEXOPCAPS_MODULATE4X) != 0);
-
m_gamma_supported = ((caps.Caps2 & D3DCAPS2_FULLSCREENGAMMA) != 0);
+ if (!m_gamma_supported)
+ {
+ osd_printf_warning("Direct3D: Warning - device does not support full screen gamma correction.\n");
+ }
+
+ // verify texture formats
+ result = d3dintf->d3dobj->CheckDeviceFormat(m_adapter, D3DDEVTYPE_HAL, m_pixformat, 0, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8);
+ if (FAILED(result))
+ {
+ osd_printf_error("Error: A8R8G8B8 format textures not supported\n");
+ verify = 2;
+ }
- return retval;
+ if (verify == 2)
+ {
+ osd_printf_error("Error: Device does not meet minimum requirements for Direct3D rendering\n");
+ return 1;
+ }
+ if (verify == 1)
+ {
+ osd_printf_warning("Warning: Device may not perform well for Direct3D rendering\n");
+ return 1;
+ }
+
+ return 0;
}
@@ -1103,8 +1153,6 @@ int renderer_d3d9::device_test_cooperative()
osd_printf_verbose("Direct3D: resetting device\n");
// free all existing resources and call reset on the device
- m_sliders.clear();
- m_shaders->delete_resources(true);
device_delete_resources();
result = m_device->Reset(&m_presentation);
@@ -1122,15 +1170,8 @@ int renderer_d3d9::device_test_cooperative()
device_delete();
return 1;
}
-
- m_sliders.clear();
- if (m_shaders->create_resources(true, m_sliders))
- {
- osd_printf_verbose("Direct3D: failed to recreate HLSL resources for device; failing permanently\n");
- device_delete();
- return 1;
- }
}
+
return 0;
}
@@ -1870,6 +1911,28 @@ void renderer_d3d9::primitive_flush_pending()
}
+std::vector<ui::menu_item> renderer_d3d9::get_slider_list()
+{
+ m_sliders_dirty = false;
+
+ std::vector<ui::menu_item> sliders;
+ sliders.insert(sliders.end(), m_sliders.begin(), m_sliders.end());
+
+ if (m_shaders != nullptr && m_shaders->enabled())
+ {
+ std::vector<ui::menu_item> s_slider = m_shaders->get_slider_list();
+ sliders.insert(sliders.end(), s_slider.begin(), s_slider.end());
+ }
+
+ return sliders;
+}
+
+void renderer_d3d9::set_sliders_dirty()
+{
+ m_sliders_dirty = true;
+}
+
+
//============================================================
// texture_info destructor
//============================================================
diff --git a/src/osd/modules/render/drawd3d.h b/src/osd/modules/render/drawd3d.h
index 1c044299b36..61ea0bc4a65 100644
--- a/src/osd/modules/render/drawd3d.h
+++ b/src/osd/modules/render/drawd3d.h
@@ -23,6 +23,7 @@
#undef interface
#include "d3d/d3dcomm.h"
+#include "sliderdirtynotifier.h"
#include "modules/lib/osdlib.h"
//============================================================
@@ -49,7 +50,7 @@ class shaders;
struct hlsl_options;
/* renderer is the information about Direct3D for the current screen */
-class renderer_d3d9 : public osd_renderer
+class renderer_d3d9 : public osd_renderer, public slider_dirty_notifier
{
public:
renderer_d3d9(std::shared_ptr<osd_window> window);
@@ -64,6 +65,8 @@ public:
virtual void save() override;
virtual void record() override;
virtual void toggle_fsfx() override;
+ virtual std::vector<ui::menu_item> get_slider_list() override;
+ virtual void set_sliders_dirty() override;
int initialize();
@@ -71,6 +74,8 @@ public:
int device_create_resources();
void device_delete();
void device_delete_resources();
+ void update_presentation_parameters();
+ void update_gamma_ramp();
int device_verify_caps();
int device_test_cooperative();
@@ -117,9 +122,7 @@ public:
VOID ** get_locked_buffer_ptr()const { return (VOID **)&m_lockedbuf; }
void set_locked_buffer(vertex *lockedbuf) { m_lockedbuf = lockedbuf; }
- void set_restarting(bool restarting) { m_restarting = restarting; }
- bool is_mod2x_supported() const { return (bool)m_mod2x_supported; }
- bool is_mod4x_supported() const { return (bool)m_mod4x_supported; }
+ void set_toggle(bool toggle) { m_toggle = toggle; }
D3DFORMAT get_screen_format() const { return m_screen_format; }
D3DFORMAT get_pixel_format() const { return m_pixformat; }
@@ -131,7 +134,6 @@ public:
texture_info * get_default_texture();
shaders * get_shaders() const { return m_shaders; }
- hlsl_options * get_shaders_options() const { return m_shaders_options; }
private:
int m_adapter; // ordinal adapter number
@@ -156,10 +158,8 @@ private:
poly_info m_poly[VERTEX_BUFFER_SIZE/3];// array to hold polygons as they are created
int m_numpolys; // number of accumulated polygons
- bool m_restarting; // if we're restarting
+ bool m_toggle; // if we're toggle fsfx
- int m_mod2x_supported; // is D3DTOP_MODULATE2X supported?
- int m_mod4x_supported; // is D3DTOP_MODULATE4X supported?
D3DFORMAT m_screen_format; // format to use for screen textures
texture_info * m_last_texture; // previous texture
@@ -174,9 +174,8 @@ private:
void * m_hlsl_buf; // HLSL vertex data
shaders * m_shaders; // HLSL interface
- hlsl_options * m_shaders_options; // HLSL options
- d3d_texture_manager * m_texture_manager; // texture manager
+ d3d_texture_manager * m_texture_manager; // texture manager
};
#endif // OSD_WINDOWS