- d3dhlsl.c: Free HLSL resources on device reset. Fixes hang when alt-tabbing

away from a fullscreen window and back. [MooglyGuy]
This commit is contained in:
Ryan Holtz 2013-01-05 19:02:01 +00:00
parent a77655df86
commit 3d1e0d9d65
3 changed files with 152 additions and 137 deletions

View File

@ -777,7 +777,7 @@ void hlsl_info::init_fsfx_quad(void *vertbuf)
// hlsl_info::create_resources
//============================================================
int hlsl_info::create_resources()
int hlsl_info::create_resources(bool reset)
{
if (!master_enable || !d3dintf->post_fx_available)
return 0;
@ -802,182 +802,185 @@ int hlsl_info::create_resources()
windows_options &winoptions = downcast<windows_options &>(window->machine().options());
options = (hlsl_options*)global_alloc_clear(hlsl_options);
options->params_dirty = true;
strcpy(options->shadow_mask_texture, downcast<windows_options &>(window->machine().options()).screen_shadow_mask_texture()); // unsafe
write_ini = downcast<windows_options &>(window->machine().options()).hlsl_write_ini();
read_ini = downcast<windows_options &>(window->machine().options()).hlsl_read_ini();
if(read_ini)
if (!reset)
{
emu_file ini_file(downcast<windows_options &>(window->machine().options()).screen_post_fx_dir(), OPEN_FLAG_READ | OPEN_FLAG_CREATE_PATHS);
file_error filerr = open_next((d3d_info*)window->drawdata, ini_file, downcast<windows_options &>(window->machine().options()).hlsl_ini_name(), "ini", 0);
options = (hlsl_options*)global_alloc_clear(hlsl_options);
read_ini = false;
if (filerr == FILERR_NONE)
options->params_dirty = true;
strcpy(options->shadow_mask_texture, downcast<windows_options &>(window->machine().options()).screen_shadow_mask_texture()); // unsafe
write_ini = downcast<windows_options &>(window->machine().options()).hlsl_write_ini();
read_ini = downcast<windows_options &>(window->machine().options()).hlsl_read_ini();
if(read_ini)
{
ini_file.seek(0, SEEK_END);
if (ini_file.tell() >= 1000)
emu_file ini_file(downcast<windows_options &>(window->machine().options()).screen_post_fx_dir(), OPEN_FLAG_READ | OPEN_FLAG_CREATE_PATHS);
file_error filerr = open_next((d3d_info*)window->drawdata, ini_file, downcast<windows_options &>(window->machine().options()).hlsl_ini_name(), "ini", 0);
read_ini = false;
if (filerr == FILERR_NONE)
{
read_ini = true;
ini_file.seek(0, SEEK_SET);
ini_file.seek(0, SEEK_END);
if (ini_file.tell() >= 1000)
{
read_ini = true;
ini_file.seek(0, SEEK_SET);
int en = 0;
char buf[1024];
ini_file.gets(buf, 1024);
sscanf(buf, "hlsl_enable %d\n", &en);
master_enable = en == 1;
int en = 0;
char buf[1024];
ini_file.gets(buf, 1024);
sscanf(buf, "hlsl_enable %d\n", &en);
master_enable = en == 1;
ini_file.gets(buf, 1024);
sscanf(buf, "hlsl_prescale_x %d\n", &prescale_force_x);
ini_file.gets(buf, 1024);
sscanf(buf, "hlsl_prescale_x %d\n", &prescale_force_x);
ini_file.gets(buf, 1024);
sscanf(buf, "hlsl_prescale_y %d\n", &prescale_force_y);
ini_file.gets(buf, 1024);
sscanf(buf, "hlsl_prescale_y %d\n", &prescale_force_y);
ini_file.gets(buf, 1024);
sscanf(buf, "hlsl_preset %d\n", &preset);
ini_file.gets(buf, 1024);
sscanf(buf, "hlsl_preset %d\n", &preset);
ini_file.gets(buf, 1024);
sscanf(buf, "hlsl_snap_width %d\n", &snap_width);
ini_file.gets(buf, 1024);
sscanf(buf, "hlsl_snap_width %d\n", &snap_width);
ini_file.gets(buf, 1024);
sscanf(buf, "hlsl_snap_height %d\n", &snap_height);
ini_file.gets(buf, 1024);
sscanf(buf, "hlsl_snap_height %d\n", &snap_height);
ini_file.gets(buf, 1024);
sscanf(buf, "shadow_mask_alpha %f\n", &options->shadow_mask_alpha);
ini_file.gets(buf, 1024);
sscanf(buf, "shadow_mask_alpha %f\n", &options->shadow_mask_alpha);
ini_file.gets(buf, 1024);
sscanf(buf, "shadow_mask_texture %s\n", options->shadow_mask_texture);
ini_file.gets(buf, 1024);
sscanf(buf, "shadow_mask_texture %s\n", options->shadow_mask_texture);
ini_file.gets(buf, 1024);
sscanf(buf, "shadow_mask_x_count %d\n", &options->shadow_mask_count_x);
ini_file.gets(buf, 1024);
sscanf(buf, "shadow_mask_x_count %d\n", &options->shadow_mask_count_x);
ini_file.gets(buf, 1024);
sscanf(buf, "shadow_mask_y_count %d\n", &options->shadow_mask_count_y);
ini_file.gets(buf, 1024);
sscanf(buf, "shadow_mask_y_count %d\n", &options->shadow_mask_count_y);
ini_file.gets(buf, 1024);
sscanf(buf, "shadow_mask_usize %f\n", &options->shadow_mask_u_size);
ini_file.gets(buf, 1024);
sscanf(buf, "shadow_mask_usize %f\n", &options->shadow_mask_u_size);
ini_file.gets(buf, 1024);
sscanf(buf, "shadow_mask_vsize %f\n", &options->shadow_mask_v_size);
ini_file.gets(buf, 1024);
sscanf(buf, "shadow_mask_vsize %f\n", &options->shadow_mask_v_size);
ini_file.gets(buf, 1024);
sscanf(buf, "curvature %f\n", &options->curvature);
ini_file.gets(buf, 1024);
sscanf(buf, "curvature %f\n", &options->curvature);
ini_file.gets(buf, 1024);
sscanf(buf, "pincushion %f\n", &options->pincushion);
ini_file.gets(buf, 1024);
sscanf(buf, "pincushion %f\n", &options->pincushion);
ini_file.gets(buf, 1024);
sscanf(buf, "scanline_alpha %f\n", &options->scanline_alpha);
ini_file.gets(buf, 1024);
sscanf(buf, "scanline_alpha %f\n", &options->scanline_alpha);
ini_file.gets(buf, 1024);
sscanf(buf, "scanline_size %f\n", &options->scanline_scale);
ini_file.gets(buf, 1024);
sscanf(buf, "scanline_size %f\n", &options->scanline_scale);
ini_file.gets(buf, 1024);
sscanf(buf, "scanline_height %f\n", &options->scanline_height);
ini_file.gets(buf, 1024);
sscanf(buf, "scanline_height %f\n", &options->scanline_height);
ini_file.gets(buf, 1024);
sscanf(buf, "scanline_bright_scale %f\n", &options->scanline_bright_scale);
ini_file.gets(buf, 1024);
sscanf(buf, "scanline_bright_scale %f\n", &options->scanline_bright_scale);
ini_file.gets(buf, 1024);
sscanf(buf, "scanline_bright_offset %f\n", &options->scanline_bright_offset);
ini_file.gets(buf, 1024);
sscanf(buf, "scanline_bright_offset %f\n", &options->scanline_bright_offset);
ini_file.gets(buf, 1024);
sscanf(buf, "scanline_jitter %f\n", &options->scanline_offset);
ini_file.gets(buf, 1024);
sscanf(buf, "scanline_jitter %f\n", &options->scanline_offset);
ini_file.gets(buf, 1024);
for(int idx = 0; idx < strlen(buf); idx++) if(buf[idx] == ',') buf[idx] = ' ';
sscanf(buf, "defocus %f %f\n", &options->defocus[0], &options->defocus[1]);
ini_file.gets(buf, 1024);
for(int idx = 0; idx < strlen(buf); idx++) if(buf[idx] == ',') buf[idx] = ' ';
sscanf(buf, "defocus %f %f\n", &options->defocus[0], &options->defocus[1]);
ini_file.gets(buf, 1024);
for(int idx = 0; idx < strlen(buf); idx++) if(buf[idx] == ',') buf[idx] = ' ';
sscanf(buf, "converge_x %f %f %f\n", &options->converge_x[0], &options->converge_x[1], &options->converge_x[2]);
ini_file.gets(buf, 1024);
for(int idx = 0; idx < strlen(buf); idx++) if(buf[idx] == ',') buf[idx] = ' ';
sscanf(buf, "converge_x %f %f %f\n", &options->converge_x[0], &options->converge_x[1], &options->converge_x[2]);
ini_file.gets(buf, 1024);
for(int idx = 0; idx < strlen(buf); idx++) if(buf[idx] == ',') buf[idx] = ' ';
sscanf(buf, "converge_y %f %f %f\n", &options->converge_y[0], &options->converge_y[1], &options->converge_y[2]);
ini_file.gets(buf, 1024);
for(int idx = 0; idx < strlen(buf); idx++) if(buf[idx] == ',') buf[idx] = ' ';
sscanf(buf, "converge_y %f %f %f\n", &options->converge_y[0], &options->converge_y[1], &options->converge_y[2]);
ini_file.gets(buf, 1024);
for(int idx = 0; idx < strlen(buf); idx++) if(buf[idx] == ',') buf[idx] = ' ';
sscanf(buf, "radial_converge_x %f %f %f\n", &options->radial_converge_x[0], &options->radial_converge_x[1], &options->radial_converge_x[2]);
ini_file.gets(buf, 1024);
for(int idx = 0; idx < strlen(buf); idx++) if(buf[idx] == ',') buf[idx] = ' ';
sscanf(buf, "radial_converge_x %f %f %f\n", &options->radial_converge_x[0], &options->radial_converge_x[1], &options->radial_converge_x[2]);
ini_file.gets(buf, 1024);
for(int idx = 0; idx < strlen(buf); idx++) if(buf[idx] == ',') buf[idx] = ' ';
sscanf(buf, "radial_converge_y %f %f %f\n", &options->radial_converge_y[0], &options->radial_converge_y[1], &options->radial_converge_y[2]);
ini_file.gets(buf, 1024);
for(int idx = 0; idx < strlen(buf); idx++) if(buf[idx] == ',') buf[idx] = ' ';
sscanf(buf, "radial_converge_y %f %f %f\n", &options->radial_converge_y[0], &options->radial_converge_y[1], &options->radial_converge_y[2]);
ini_file.gets(buf, 1024);
for(int idx = 0; idx < strlen(buf); idx++) if(buf[idx] == ',') buf[idx] = ' ';
sscanf(buf, "red_ratio %f %f %f\n", &options->red_ratio[0], &options->red_ratio[1], &options->red_ratio[2]);
ini_file.gets(buf, 1024);
for(int idx = 0; idx < strlen(buf); idx++) if(buf[idx] == ',') buf[idx] = ' ';
sscanf(buf, "red_ratio %f %f %f\n", &options->red_ratio[0], &options->red_ratio[1], &options->red_ratio[2]);
ini_file.gets(buf, 1024);
for(int idx = 0; idx < strlen(buf); idx++) if(buf[idx] == ',') buf[idx] = ' ';
sscanf(buf, "grn_ratio %f %f %f\n", &options->grn_ratio[0], &options->grn_ratio[1], &options->grn_ratio[2]);
ini_file.gets(buf, 1024);
for(int idx = 0; idx < strlen(buf); idx++) if(buf[idx] == ',') buf[idx] = ' ';
sscanf(buf, "grn_ratio %f %f %f\n", &options->grn_ratio[0], &options->grn_ratio[1], &options->grn_ratio[2]);
ini_file.gets(buf, 1024);
for(int idx = 0; idx < strlen(buf); idx++) if(buf[idx] == ',') buf[idx] = ' ';
sscanf(buf, "blu_ratio %f %f %f\n", &options->blu_ratio[0], &options->blu_ratio[1], &options->blu_ratio[2]);
ini_file.gets(buf, 1024);
for(int idx = 0; idx < strlen(buf); idx++) if(buf[idx] == ',') buf[idx] = ' ';
sscanf(buf, "blu_ratio %f %f %f\n", &options->blu_ratio[0], &options->blu_ratio[1], &options->blu_ratio[2]);
ini_file.gets(buf, 1024);
sscanf(buf, "saturation %f\n", &options->saturation);
ini_file.gets(buf, 1024);
sscanf(buf, "saturation %f\n", &options->saturation);
ini_file.gets(buf, 1024);
for(int idx = 0; idx < strlen(buf); idx++) if(buf[idx] == ',') buf[idx] = ' ';
sscanf(buf, "offset %f %f %f\n", &options->offset[0], &options->offset[1], &options->offset[2]);
ini_file.gets(buf, 1024);
for(int idx = 0; idx < strlen(buf); idx++) if(buf[idx] == ',') buf[idx] = ' ';
sscanf(buf, "offset %f %f %f\n", &options->offset[0], &options->offset[1], &options->offset[2]);
ini_file.gets(buf, 1024);
for(int idx = 0; idx < strlen(buf); idx++) if(buf[idx] == ',') buf[idx] = ' ';
sscanf(buf, "scale %f %f %f\n", &options->scale[0], &options->scale[1], &options->scale[2]);
ini_file.gets(buf, 1024);
for(int idx = 0; idx < strlen(buf); idx++) if(buf[idx] == ',') buf[idx] = ' ';
sscanf(buf, "scale %f %f %f\n", &options->scale[0], &options->scale[1], &options->scale[2]);
ini_file.gets(buf, 1024);
for(int idx = 0; idx < strlen(buf); idx++) if(buf[idx] == ',') buf[idx] = ' ';
sscanf(buf, "power %f %f %f\n", &options->power[0], &options->power[1], &options->power[2]);
ini_file.gets(buf, 1024);
for(int idx = 0; idx < strlen(buf); idx++) if(buf[idx] == ',') buf[idx] = ' ';
sscanf(buf, "power %f %f %f\n", &options->power[0], &options->power[1], &options->power[2]);
ini_file.gets(buf, 1024);
for(int idx = 0; idx < strlen(buf); idx++) if(buf[idx] == ',') buf[idx] = ' ';
sscanf(buf, "floor %f %f %f\n", &options->floor[0], &options->floor[1], &options->floor[2]);
ini_file.gets(buf, 1024);
for(int idx = 0; idx < strlen(buf); idx++) if(buf[idx] == ',') buf[idx] = ' ';
sscanf(buf, "floor %f %f %f\n", &options->floor[0], &options->floor[1], &options->floor[2]);
ini_file.gets(buf, 1024);
for(int idx = 0; idx < strlen(buf); idx++) if(buf[idx] == ',') buf[idx] = ' ';
sscanf(buf, "phosphor_life %f %f %f\n", &options->phosphor[0], &options->phosphor[1], &options->phosphor[2]);
ini_file.gets(buf, 1024);
for(int idx = 0; idx < strlen(buf); idx++) if(buf[idx] == ',') buf[idx] = ' ';
sscanf(buf, "phosphor_life %f %f %f\n", &options->phosphor[0], &options->phosphor[1], &options->phosphor[2]);
ini_file.gets(buf, 1024);
sscanf(buf, "yiq_enable %d\n", &en);
options->yiq_enable = en == 1;
ini_file.gets(buf, 1024);
sscanf(buf, "yiq_enable %d\n", &en);
options->yiq_enable = en == 1;
ini_file.gets(buf, 1024);
sscanf(buf, "yiq_cc %f\n", &options->yiq_cc);
ini_file.gets(buf, 1024);
sscanf(buf, "yiq_cc %f\n", &options->yiq_cc);
ini_file.gets(buf, 1024);
sscanf(buf, "yiq_a %f\n", &options->yiq_a);
ini_file.gets(buf, 1024);
sscanf(buf, "yiq_a %f\n", &options->yiq_a);
ini_file.gets(buf, 1024);
sscanf(buf, "yiq_b %f\n", &options->yiq_b);
ini_file.gets(buf, 1024);
sscanf(buf, "yiq_b %f\n", &options->yiq_b);
ini_file.gets(buf, 1024);
sscanf(buf, "yiq_o %f\n", &options->yiq_o);
ini_file.gets(buf, 1024);
sscanf(buf, "yiq_o %f\n", &options->yiq_o);
ini_file.gets(buf, 1024);
sscanf(buf, "yiq_p %f\n", &options->yiq_p);
ini_file.gets(buf, 1024);
sscanf(buf, "yiq_p %f\n", &options->yiq_p);
ini_file.gets(buf, 1024);
sscanf(buf, "yiq_n %f\n", &options->yiq_n);
ini_file.gets(buf, 1024);
sscanf(buf, "yiq_n %f\n", &options->yiq_n);
ini_file.gets(buf, 1024);
sscanf(buf, "yiq_y %f\n", &options->yiq_y);
ini_file.gets(buf, 1024);
sscanf(buf, "yiq_y %f\n", &options->yiq_y);
ini_file.gets(buf, 1024);
sscanf(buf, "yiq_i %f\n", &options->yiq_i);
ini_file.gets(buf, 1024);
sscanf(buf, "yiq_i %f\n", &options->yiq_i);
ini_file.gets(buf, 1024);
sscanf(buf, "yiq_q %f\n", &options->yiq_q);
ini_file.gets(buf, 1024);
sscanf(buf, "yiq_q %f\n", &options->yiq_q);
ini_file.gets(buf, 1024);
sscanf(buf, "yiq_scan_time %f\n", &options->yiq_scan_time);
ini_file.gets(buf, 1024);
sscanf(buf, "yiq_scan_time %f\n", &options->yiq_scan_time);
ini_file.gets(buf, 1024);
sscanf(buf, "yiq_phase_count %d\n", &options->yiq_phase_count);
ini_file.gets(buf, 1024);
sscanf(buf, "yiq_phase_count %d\n", &options->yiq_phase_count);
}
}
}
}
@ -2055,12 +2058,12 @@ bool hlsl_info::register_texture(d3d_texture_info *texture, int width, int heigh
// hlsl_info::delete_resources
//============================================================
void hlsl_info::delete_resources()
void hlsl_info::delete_resources(bool reset)
{
if (!master_enable || !d3dintf->post_fx_available)
return;
if(write_ini)
if(write_ini && !reset)
{
emu_file file(downcast<windows_options &>(window->machine().options()).screen_post_fx_dir(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
file_error filerr = open_next((d3d_info*)window->drawdata, file, downcast<windows_options &>(window->machine().options()).hlsl_ini_name(), "ini", 0);
@ -2116,6 +2119,11 @@ void hlsl_info::delete_resources()
file.printf("yiq_phase_count %d\n", options->yiq_phase_count);
}
while (targethead != NULL)
{
remove_render_target(targethead);
}
if (effect != NULL)
{
(*d3dintf->effect.release)(effect);
@ -2167,10 +2175,6 @@ void hlsl_info::delete_resources()
yiq_decode_effect = NULL;
}
for (int index = 0; index < 9; index++)
{
}
if (avi_copy_texture != NULL)
{
(*d3dintf->texture.release)(avi_copy_texture);

View File

@ -147,8 +147,8 @@ public:
void remove_render_target(int width, int height, UINT32 screen_index, UINT32 page_index);
void remove_render_target(d3d_render_target *rt);
int create_resources();
void delete_resources();
int create_resources(bool reset);
void delete_resources(bool reset);
// slider-related functions
slider_state *init_slider_list();

View File

@ -803,7 +803,7 @@ try_again:
d3d->default_texture = texture_create(d3d, &texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32));
}
int ret = d3d->hlsl->create_resources();
int ret = d3d->hlsl->create_resources(false);
if (ret != 0)
return ret;
@ -900,7 +900,7 @@ static int device_create_resources(d3d_info *d3d)
static void device_delete(d3d_info *d3d)
{
// free our effects
d3d->hlsl->delete_resources();
d3d->hlsl->delete_resources(false);
// delete the HLSL interface
global_free(d3d->hlsl);
@ -1144,11 +1144,15 @@ static int device_test_cooperative(d3d_info *d3d)
// free all existing resources and call reset on the device
device_delete_resources(d3d);
d3d->hlsl->delete_resources(true);
result = (*d3dintf->device.reset)(d3d->device, &d3d->presentation);
// if it didn't work, punt to GDI
if (result != D3D_OK)
{
printf("Unable to reset, result %08x\n", (UINT32)result);
return 1;
}
// try to create the resources again; if that didn't work, delete the whole thing
if (device_create_resources(d3d))
@ -1157,6 +1161,13 @@ static int device_test_cooperative(d3d_info *d3d)
device_delete(d3d);
return 1;
}
if (d3d->hlsl->create_resources(true))
{
mame_printf_verbose("Direct3D: failed to recreate HLSL resources for device; failing permanently\n");
device_delete(d3d);
return 1;
}
}
return 0;
}