Fix phosphor shader to work properly for multi-screen games and

multi-window use.

	hlsl/phosphor.fx: Update semantics.

	src/osd/modules/render/d3d/d3dhlsl.cpp: Implement
shaders::delta_time member function.

	src/osd/modules/render/d3d/d3dhlsl.h: Add acc_t and delta_t
members for use by shaders::delta_time.  Member function returns the
amount of time since itself has been called, for use by time-dependent
shaders.
This commit is contained in:
Westley M. Martinez 2016-12-12 22:09:59 -08:00
parent 35035aae28
commit 77fd0232e6
3 changed files with 30 additions and 22 deletions

View File

@ -94,17 +94,17 @@ VS_OUTPUT vs_main(VS_INPUT Input)
//-----------------------------------------------------------------------------
uniform float3 Phosphor = float3(0.0f, 0.0f, 0.0f);
uniform float dt = 0.0f;
static const float f = 30.0f;
uniform float DeltaTime = 0.0f;
static const float F = 30.0f;
float4 ps_main(PS_INPUT Input) : COLOR
{
float4 CurrPix = tex2D(DiffuseSampler, Input.TexCoord);
float3 PrevPix = tex2D(PreviousSampler, Input.PrevCoord).rgb;
PrevPix.r *= Phosphor.r == 0 ? 0 : pow(Phosphor.r, f * dt);
PrevPix.g *= Phosphor.g == 0 ? 0 : pow(Phosphor.g, f * dt);
PrevPix.b *= Phosphor.b == 0 ? 0 : pow(Phosphor.b, f * dt);
PrevPix.r *= Phosphor.r == 0 ? 0 : pow(Phosphor.r, F * DeltaTime);
PrevPix.g *= Phosphor.g == 0 ? 0 : pow(Phosphor.g, F * DeltaTime);
PrevPix.b *= Phosphor.b == 0 ? 0 : pow(Phosphor.b, F * DeltaTime);
float RedMax = max(CurrPix.r, PrevPix.r);
float GreenMax = max(CurrPix.g, PrevPix.g);
float BlueMax = max(CurrPix.b, PrevPix.b);

View File

@ -164,14 +164,15 @@ private:
shaders::shaders() :
d3dintf(nullptr), machine(nullptr), d3d(nullptr), post_fx_enable(false), oversampling_enable(false),
num_screens(0), curr_screen(0), shadow_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), focus_effect(nullptr),
phosphor_effect(nullptr), deconverge_effect(nullptr), color_effect(nullptr), ntsc_effect(nullptr),
bloom_effect(nullptr), downsample_effect(nullptr), vector_effect(nullptr), curr_texture(nullptr),
curr_render_target(nullptr), curr_poly(nullptr), d3dx_create_effect_from_file_ptr(nullptr)
num_screens(0), curr_screen(0), acc_t(0), delta_t(0), shadow_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),
focus_effect(nullptr), phosphor_effect(nullptr), deconverge_effect(nullptr), color_effect(nullptr),
ntsc_effect(nullptr), bloom_effect(nullptr), downsample_effect(nullptr), vector_effect(nullptr),
curr_texture(nullptr), curr_render_target(nullptr), curr_poly(nullptr),
d3dx_create_effect_from_file_ptr(nullptr)
{
}
@ -900,6 +901,18 @@ void shaders::blit(
curr_effect->end();
}
double shaders::delta_time()
{
double t;
if (curr_screen == 0) {
t = machine->time().as_double();
delta_t = t - acc_t;
acc_t = t;
}
return delta_t;
}
//============================================================
// shaders::find_render_target
@ -1061,11 +1074,7 @@ int shaders::defocus_pass(d3d_render_target *rt, int source_index, poly_info *po
int shaders::phosphor_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum)
{
static double ct = 0;
int next_index = source_index;
float dt;
double t;
// skip phosphor if no influencing settings
if (options->phosphor[0] == 0.0f && options->phosphor[1] == 0.0f && options->phosphor[2] == 0.0f)
@ -1074,15 +1083,12 @@ int shaders::phosphor_pass(d3d_render_target *rt, int source_index, poly_info *p
}
// Shader needs time between last update
t = machine->time().as_double();
dt = (float) (t - ct);
ct = t;
curr_effect = phosphor_effect;
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_bool("Passthrough", false);
curr_effect->set_float("dt", dt);
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);

View File

@ -319,7 +319,7 @@ private:
void enumerate_screens();
void render_snapshot(IDirect3DSurface9 *surface);
double delta_time(); // Time since last call to itself; only updates for Screen 0
d3d_render_target* find_render_target(int source_width, int source_height, uint32_t screen_index);
rgb_t apply_color_convolution(rgb_t color);
@ -349,6 +349,8 @@ private:
bool oversampling_enable; // oversampling enable flag
int num_screens; // number of emulated physical screens
int curr_screen; // current screen for render target operations
double acc_t; // accumulated machine time
double delta_t; // time since last call to delta_time
bitmap_argb32 shadow_bitmap; // shadow mask bitmap for post-processing shader
texture_info * shadow_texture; // shadow mask texture for post-processing shader
hlsl_options * options; // current options