Postshader: Add uniform for delta since last frame.

Useful mainly when using previous frame output.
This commit is contained in:
Unknown W. Brackets 2021-06-12 11:27:26 -07:00
parent 7bbaae492b
commit 17071e7fec
3 changed files with 17 additions and 6 deletions

View file

@ -85,6 +85,7 @@ cbuffer data : register(b0) {
float2 u_texelDelta;
float2 u_pixelDelta;
float4 u_time;
float4 u_timeDelta;
float4 u_setting;
float u_video;
};
@ -101,6 +102,7 @@ layout (std140, set = 0, binding = 0) uniform Data {
vec2 u_texelDelta;
vec2 u_pixelDelta;
vec4 u_time;
vec4 u_timeDelta;
vec4 u_setting;
float u_video;
};
@ -111,8 +113,9 @@ float4 gl_HalfPixel : register(c0);
float2 u_texelDelta : register(c1);
float2 u_pixelDelta : register(c2);
float4 u_time : register(c3);
float4 u_setting : register(c4);
float u_video : register(c5);
float4 u_timeDelta : register(c4);
float4 u_setting : register(c5);
float u_video : register(c6);
)";
// SPIRV-Cross' HLSL output has some deficiencies we need to work around.

View file

@ -185,6 +185,10 @@ void PresentationCommon::CalculatePostShaderUniforms(int bufferWidth, int buffer
uniforms->pixelDelta[0] = u_pixel_delta;
uniforms->pixelDelta[1] = v_pixel_delta;
memcpy(uniforms->time, time, 4 * sizeof(float));
uniforms->timeDelta[0] = time[0] - previousUniforms_.time[0];
uniforms->timeDelta[1] = (time[2] - previousUniforms_.time[2]) * (1.0f / 60.0f);
uniforms->timeDelta[2] = time[2] - previousUniforms_.time[2];
uniforms->timeDelta[3] = time[3] != previousUniforms_.time[3] ? 1.0f : 0.0f;
uniforms->video = hasVideo_ ? 1.0f : 0.0f;
// The shader translator tacks this onto our shaders, if we don't set it they render garbage.
@ -286,8 +290,9 @@ bool PresentationCommon::BuildPostShader(const ShaderInfo *shaderInfo, const Sha
{ "u_texelDelta", 1, 1, UniformType::FLOAT2, offsetof(PostShaderUniforms, texelDelta) },
{ "u_pixelDelta", 2, 2, UniformType::FLOAT2, offsetof(PostShaderUniforms, pixelDelta) },
{ "u_time", 3, 3, UniformType::FLOAT4, offsetof(PostShaderUniforms, time) },
{ "u_setting", 4, 4, UniformType::FLOAT4, offsetof(PostShaderUniforms, setting) },
{ "u_video", 5, 5, UniformType::FLOAT1, offsetof(PostShaderUniforms, video) },
{ "u_timeDelta", 4, 4, UniformType::FLOAT4, offsetof(PostShaderUniforms, timeDelta) },
{ "u_setting", 5, 5, UniformType::FLOAT4, offsetof(PostShaderUniforms, setting) },
{ "u_video", 6, 6, UniformType::FLOAT1, offsetof(PostShaderUniforms, video) },
} };
Draw::Pipeline *pipeline = CreatePipeline({ vs, fs }, true, &postShaderDesc);
@ -642,6 +647,7 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u
// Grab the previous framebuffer early so we can change previousIndex_ when we want.
Draw::Framebuffer *previousFramebuffer = previousFramebuffers_.empty() ? nullptr : previousFramebuffers_[previousIndex_];
PostShaderUniforms uniforms;
const auto performShaderPass = [&](const ShaderInfo *shaderInfo, Draw::Framebuffer *postShaderFramebuffer, Draw::Pipeline *postShaderPipeline) {
if (postShaderOutput) {
draw_->BindFramebufferAsTexture(postShaderOutput, 0, Draw::FB_COLOR_BIT, 0);
@ -658,7 +664,6 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u
draw_->SetViewports(1, &viewport);
draw_->SetScissorRect(0, 0, nextWidth, nextHeight);
PostShaderUniforms uniforms;
CalculatePostShaderUniforms(lastWidth, lastHeight, nextWidth, nextHeight, shaderInfo, &uniforms);
draw_->BindPipeline(postShaderPipeline);
@ -746,7 +751,6 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u
BindSource(1);
if (isFinalAtOutputResolution && previousFramebuffers_.empty()) {
PostShaderUniforms uniforms;
CalculatePostShaderUniforms(lastWidth, lastHeight, (int)rc.w, (int)rc.h, &postShaderInfo_.back(), &uniforms);
draw_->UpdateDynamicUniformBuffer(&uniforms, sizeof(uniforms));
} else {
@ -789,6 +793,8 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u
// Unbinds all textures and samplers too, needed since sometimes a MakePixelTexture is deleted etc.
draw_->BindPipeline(nullptr);
previousUniforms_ = uniforms;
}
void PresentationCommon::CalculateRenderResolution(int *width, int *height, int *scaleFactor, bool *upscaling, bool *ssaa) {

View file

@ -31,6 +31,7 @@ struct CardboardSettings {
struct PostShaderUniforms {
float texelDelta[2]; float pixelDelta[2];
float time[4];
float timeDelta[4];
float setting[4];
float video; float pad[3];
// Used on Direct3D9.
@ -133,6 +134,7 @@ protected:
std::vector<ShaderInfo> postShaderInfo_;
std::vector<Draw::Framebuffer *> previousFramebuffers_;
int previousIndex_ = 0;
PostShaderUniforms previousUniforms_{};
Draw::Texture *srcTexture_ = nullptr;
Draw::Framebuffer *srcFramebuffer_ = nullptr;