mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Postshader: Add uniform for delta since last frame.
Useful mainly when using previous frame output.
This commit is contained in:
parent
7bbaae492b
commit
17071e7fec
3 changed files with 17 additions and 6 deletions
|
@ -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.
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue