Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Postshader: Let shaders use the previous frame #14528

Merged
merged 6 commits into from
Jun 12, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Postshader: Add uniform for delta since last frame.
Useful mainly when using previous frame output.
  • Loading branch information
unknownbrackets committed Jun 12, 2021
commit 17071e7fecaf1b82e1b245f130eb6f61346a0096
7 changes: 5 additions & 2 deletions Common/GPU/ShaderTranslation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand All @@ -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;
};
Expand All @@ -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.
Expand Down
14 changes: 10 additions & 4 deletions GPU/Common/PresentationCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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) {
Expand Down
2 changes: 2 additions & 0 deletions GPU/Common/PresentationCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -133,6 +134,7 @@ class PresentationCommon {
std::vector<ShaderInfo> postShaderInfo_;
std::vector<Draw::Framebuffer *> previousFramebuffers_;
int previousIndex_ = 0;
PostShaderUniforms previousUniforms_{};

Draw::Texture *srcTexture_ = nullptr;
Draw::Framebuffer *srcFramebuffer_ = nullptr;
Expand Down