- some fixes to the PP shader interface.

The binding point needs to be part of the ShaderUniforms class because Vulkan will need this value to generate the declaration in the shader source.
There's still one issue here: Since OpenGL has no local render state, the buffer must be bound every time it is used. Once the code is better abstracted this should be moved to a higher level class that knows all associated data and how to set it up.
This commit is contained in:
Christoph Oelckers 2018-06-12 21:43:35 +02:00
parent 4ddd9dde79
commit f166624eb2
23 changed files with 67 additions and 47 deletions

View file

@ -71,3 +71,14 @@ void GLUniformBuffer::SetData(const void *data)
glBufferData(GL_UNIFORM_BUFFER, mSize, data, mStaticDraw? GL_STATIC_DRAW : GL_STREAM_DRAW);
}
}
//==========================================================================
//
// This needs to go away later.
//
//==========================================================================
void GLUniformBuffer::Bind(int bindingpoint)
{
glBindBufferBase(GL_UNIFORM_BUFFER, bindingpoint, mBufferId);
}

View file

@ -14,6 +14,7 @@ public:
~GLUniformBuffer();
void SetData(const void *data) override;
void Bind(int bindingpoint) override;
unsigned ID() const
{

View file

@ -53,7 +53,7 @@ void FShadowMap::Update()
GLRenderer->mShadowMapShader->Bind();
GLRenderer->mShadowMapShader->Uniforms->ShadowmapQuality = gl_shadowmap_quality;
GLRenderer->mShadowMapShader->Uniforms.Set(POSTPROCESS_BINDINGPOINT);
GLRenderer->mShadowMapShader->Uniforms.Set();
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, mLightList);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, mNodesBuffer);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, mLinesBuffer);

View file

@ -125,7 +125,7 @@ void FGLRenderer::AmbientOccludeScene()
mLinearDepthShader->Uniforms->InverseDepthRangeB = 0.0f;
mLinearDepthShader->Uniforms->Scale = { sceneScaleX, sceneScaleY };
mLinearDepthShader->Uniforms->Offset = { sceneOffsetX, sceneOffsetY };
mLinearDepthShader->Uniforms.Set(POSTPROCESS_BINDINGPOINT);
mLinearDepthShader->Uniforms.Set();
RenderScreenQuad();
// Apply ambient occlusion
@ -148,7 +148,7 @@ void FGLRenderer::AmbientOccludeScene()
mSSAOShader->Uniforms->AOStrength = aoStrength;
mSSAOShader->Uniforms->Scale = { sceneScaleX, sceneScaleY };
mSSAOShader->Uniforms->Offset = { sceneOffsetX, sceneOffsetY };
mSSAOShader->Uniforms.Set(POSTPROCESS_BINDINGPOINT);
mSSAOShader->Uniforms.Set();
RenderScreenQuad();
// Blur SSAO texture
@ -159,7 +159,7 @@ void FGLRenderer::AmbientOccludeScene()
mDepthBlurShader->Bind(false);
mDepthBlurShader->Uniforms[false]->BlurSharpness = blurSharpness;
mDepthBlurShader->Uniforms[false]->InvFullResolution = { 1.0f / mBuffers->AmbientWidth, 1.0f / mBuffers->AmbientHeight };
mDepthBlurShader->Uniforms[false].Set(POSTPROCESS_BINDINGPOINT);
mDepthBlurShader->Uniforms[false].Set();
RenderScreenQuad();
mBuffers->AmbientFB1.Bind();
@ -168,7 +168,7 @@ void FGLRenderer::AmbientOccludeScene()
mDepthBlurShader->Uniforms[true]->BlurSharpness = blurSharpness;
mDepthBlurShader->Uniforms[true]->InvFullResolution = { 1.0f / mBuffers->AmbientWidth, 1.0f / mBuffers->AmbientHeight };
mDepthBlurShader->Uniforms[true]->PowExponent = gl_ssao_exponent;
mDepthBlurShader->Uniforms[true].Set(POSTPROCESS_BINDINGPOINT);
mDepthBlurShader->Uniforms[true].Set();
RenderScreenQuad();
}
@ -191,7 +191,7 @@ void FGLRenderer::AmbientOccludeScene()
if (gl_multisample > 1) mSSAOCombineShader->Uniforms->SampleCount = gl_multisample;
mSSAOCombineShader->Uniforms->Scale = { sceneScaleX, sceneScaleY };
mSSAOCombineShader->Uniforms->Offset = { sceneOffsetX, sceneOffsetY };
mSSAOCombineShader->Uniforms.Set(POSTPROCESS_BINDINGPOINT);
mSSAOCombineShader->Uniforms.Set();
RenderScreenQuad();
FGLDebug::PopGroup();
@ -225,7 +225,7 @@ void FGLRenderer::UpdateCameraExposure()
mExposureExtractShader->SceneTexture.Set(0);
mExposureExtractShader->Uniforms->Scale = { mSceneViewport.width / (float)mScreenViewport.width, mSceneViewport.height / (float)mScreenViewport.height };
mExposureExtractShader->Uniforms->Offset = { mSceneViewport.left / (float)mScreenViewport.width, mSceneViewport.top / (float)mScreenViewport.height };
mExposureExtractShader->Uniforms.Set(POSTPROCESS_BINDINGPOINT);
mExposureExtractShader->Uniforms.Set();
RenderScreenQuad();
// Find the average value:
@ -262,7 +262,7 @@ void FGLRenderer::UpdateCameraExposure()
mExposureCombineShader->Uniforms->ExposureMin = gl_exposure_min;
mExposureCombineShader->Uniforms->ExposureScale = gl_exposure_scale;
mExposureCombineShader->Uniforms->ExposureSpeed = gl_exposure_speed;
mExposureCombineShader->Uniforms.Set(POSTPROCESS_BINDINGPOINT);
mExposureCombineShader->Uniforms.Set();
RenderScreenQuad();
glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
@ -304,7 +304,7 @@ void FGLRenderer::BloomScene(int fixedcm)
mBloomExtractShader->ExposureTexture.Set(1);
mBloomExtractShader->Uniforms->Scale = { mSceneViewport.width / (float)mScreenViewport.width, mSceneViewport.height / (float)mScreenViewport.height };
mBloomExtractShader->Uniforms->Offset = { mSceneViewport.left / (float)mScreenViewport.width, mSceneViewport.top / (float)mScreenViewport.height };
mBloomExtractShader->Uniforms.Set(POSTPROCESS_BINDINGPOINT);
mBloomExtractShader->Uniforms.Set();
RenderScreenQuad();
// Blur and downscale:
@ -534,7 +534,7 @@ void FGLRenderer::ColormapScene(int fixedcm)
mColormapShader->Uniforms->MapStart = { scm->ColorizeStart[0], scm->ColorizeStart[1], scm->ColorizeStart[2], 0.f };
mColormapShader->Uniforms->MapRange = m;
mColormapShader->Uniforms.Set(POSTPROCESS_BINDINGPOINT);
mColormapShader->Uniforms.Set();
RenderScreenQuad();
mBuffers->NextTexture();
@ -590,7 +590,7 @@ void FGLRenderer::LensDistortScene()
mLensShader->Uniforms->Scale = scale;
mLensShader->Uniforms->LensDistortionCoefficient = k;
mLensShader->Uniforms->CubicDistortionValue = kcube;
mLensShader->Uniforms.Set(POSTPROCESS_BINDINGPOINT);
mLensShader->Uniforms.Set();
RenderScreenQuad();
mBuffers->NextTexture();
@ -626,7 +626,7 @@ void FGLRenderer::ApplyFXAA()
mFXAAShader->Bind();
mFXAAShader->InputTexture.Set(0);
mFXAAShader->Uniforms->ReciprocalResolution = { 1.0f / mBuffers->GetWidth(), 1.0f / mBuffers->GetHeight() };
mFXAAShader->Uniforms.Set(POSTPROCESS_BINDINGPOINT);
mFXAAShader->Uniforms.Set();
RenderScreenQuad();
mBuffers->NextTexture();
@ -745,7 +745,7 @@ void FGLRenderer::DrawPresentTexture(const IntRect &box, bool applyGamma)
mPresentShader->Uniforms->GrayFormula = static_cast<int>(gl_satformula);
}
mPresentShader->Uniforms->Scale = { screen->mScreenViewport.width / (float)mBuffers->GetWidth(), screen->mScreenViewport.height / (float)mBuffers->GetHeight() };
mPresentShader->Uniforms.Set(POSTPROCESS_BINDINGPOINT);
mPresentShader->Uniforms.Set();
RenderScreenQuad();
}

View file

@ -42,7 +42,7 @@ void FLinearDepthShader::Bind()
mShader->SetFragDataLocation(0, "FragColor");
mShader->Link("shaders/glsl/lineardepth");
mShader->SetAttribLocation(0, "PositionInProjection");
mShader->SetUniformBufferLocation(POSTPROCESS_BINDINGPOINT, "Uniforms");
mShader->SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms");
DepthTexture.Init(*mShader, "DepthTexture");
ColorTexture.Init(*mShader, "ColorTexture");
Uniforms.Init();
@ -68,7 +68,7 @@ void FSSAOShader::Bind()
mShader->SetFragDataLocation(0, "FragColor");
mShader->Link("shaders/glsl/ssao");
mShader->SetAttribLocation(0, "PositionInProjection");
mShader->SetUniformBufferLocation(POSTPROCESS_BINDINGPOINT, "Uniforms");
mShader->SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms");
DepthTexture.Init(*mShader, "DepthTexture");
NormalTexture.Init(*mShader, "NormalTexture");
RandomTexture.Init(*mShader, "RandomTexture");
@ -119,7 +119,7 @@ void FDepthBlurShader::Bind(bool vertical)
shader.SetFragDataLocation(0, "FragColor");
shader.Link("shaders/glsl/depthblur");
shader.SetAttribLocation(0, "PositionInProjection");
shader.SetUniformBufferLocation(POSTPROCESS_BINDINGPOINT, "Uniforms");
shader.SetUniformBufferLocation(Uniforms[vertical].BindingPoint(), "Uniforms");
AODepthTexture[vertical].Init(shader, "AODepthTexture");
Uniforms[vertical].Init();
}
@ -144,7 +144,7 @@ void FSSAOCombineShader::Bind()
mShader->SetFragDataLocation(0, "FragColor");
mShader->Link("shaders/glsl/ssaocombine");
mShader->SetAttribLocation(0, "PositionInProjection");
mShader->SetUniformBufferLocation(POSTPROCESS_BINDINGPOINT, "Uniforms");
mShader->SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms");
AODepthTexture.Init(*mShader, "AODepthTexture");
SceneFogTexture.Init(*mShader, "SceneFogTexture");
Uniforms.Init();

View file

@ -42,7 +42,7 @@ public:
}
};
ShaderUniforms<UniformBlock> Uniforms;
ShaderUniforms<UniformBlock, POSTPROCESS_BINDINGPOINT> Uniforms;
private:
std::unique_ptr<FShaderProgram> mShader;
@ -94,7 +94,7 @@ public:
}
};
ShaderUniforms<UniformBlock> Uniforms;
ShaderUniforms<UniformBlock, POSTPROCESS_BINDINGPOINT> Uniforms;
private:
enum Quality
@ -137,7 +137,7 @@ public:
}
};
ShaderUniforms<UniformBlock> Uniforms[2];
ShaderUniforms<UniformBlock, POSTPROCESS_BINDINGPOINT> Uniforms[2];
private:
FShaderProgram mShader[2];
@ -172,7 +172,7 @@ public:
}
};
ShaderUniforms<UniformBlock> Uniforms;
ShaderUniforms<UniformBlock, POSTPROCESS_BINDINGPOINT> Uniforms;
private:
std::unique_ptr<FShaderProgram> mShader;

View file

@ -40,7 +40,7 @@ void FBloomExtractShader::Bind()
mShader.SetFragDataLocation(0, "FragColor");
mShader.Link("shaders/glsl/bloomextract");
mShader.SetAttribLocation(0, "PositionInProjection");
mShader.SetUniformBufferLocation(POSTPROCESS_BINDINGPOINT, "Uniforms");
mShader.SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms");
SceneTexture.Init(mShader, "SceneTexture");
ExposureTexture.Init(mShader, "ExposureTexture");
Uniforms.Init();

View file

@ -26,7 +26,7 @@ public:
}
};
ShaderUniforms<UniformBlock> Uniforms;
ShaderUniforms<UniformBlock, POSTPROCESS_BINDINGPOINT> Uniforms;
private:
FShaderProgram mShader;

View file

@ -41,7 +41,7 @@ void FColormapShader::Bind()
shader.SetFragDataLocation(0, "FragColor");
shader.Link("shaders/glsl/colormap");
shader.SetAttribLocation(0, "PositionInProjection");
shader.SetUniformBufferLocation(POSTPROCESS_BINDINGPOINT, "Uniforms");
shader.SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms");
Uniforms.Init();
}
shader.Bind();

View file

@ -25,7 +25,7 @@ public:
}
};
ShaderUniforms<UniformBlock> Uniforms;
ShaderUniforms<UniformBlock, POSTPROCESS_BINDINGPOINT> Uniforms;
private:

View file

@ -91,7 +91,7 @@ void FFXAAShader::Bind()
shader.SetFragDataLocation(0, "FragColor");
shader.Link("shaders/glsl/fxaa");
shader.SetAttribLocation(0, "PositionInProjection");
shader.SetUniformBufferLocation(POSTPROCESS_BINDINGPOINT, "Uniforms");
shader.SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms");
InputTexture.Init(shader, "InputTexture");
Uniforms.Init();
}

View file

@ -65,7 +65,7 @@ public:
}
};
ShaderUniforms<UniformBlock> Uniforms;
ShaderUniforms<UniformBlock, POSTPROCESS_BINDINGPOINT> Uniforms;
private:
FShaderProgram mShaders[Count];

View file

@ -40,7 +40,7 @@ void FLensShader::Bind()
mShader.SetFragDataLocation(0, "FragColor");
mShader.Link("shaders/glsl/lensdistortion");
mShader.SetAttribLocation(0, "PositionInProjection");
mShader.SetUniformBufferLocation(POSTPROCESS_BINDINGPOINT, "Uniforms");
mShader.SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms");
InputTexture.Init(mShader, "InputTexture");
Uniforms.Init();
}

View file

@ -32,7 +32,7 @@ public:
}
};
ShaderUniforms<UniformBlock> Uniforms;
ShaderUniforms<UniformBlock, POSTPROCESS_BINDINGPOINT> Uniforms;
private:
FShaderProgram mShader;

View file

@ -39,7 +39,7 @@ void FPresentShaderBase::Init(const char * vtx_shader_name, const char * program
mShader.Link(program_name);
mShader.SetAttribLocation(0, "PositionInProjection");
mShader.SetAttribLocation(1, "UV");
mShader.SetUniformBufferLocation(POSTPROCESS_BINDINGPOINT, "Uniforms");
mShader.SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms");
Uniforms.Init();
}

View file

@ -34,7 +34,7 @@ public:
}
};
ShaderUniforms<UniformBlock> Uniforms;
ShaderUniforms<UniformBlock, POSTPROCESS_BINDINGPOINT> Uniforms;
protected:
virtual void Init(const char * vtx_shader_name, const char * program_name);

View file

@ -20,6 +20,7 @@ enum class UniformType
UVec2,
UVec3,
UVec4,
Mat4
};
class UniformFieldDesc
@ -33,7 +34,7 @@ public:
std::size_t Offset;
};
template<typename T>
template<typename T, int bindingpoint>
class ShaderUniforms
{
public:
@ -48,12 +49,17 @@ public:
delete mBuffer;
}
int BindingPoint() const
{
return bindingpoint;
}
FString CreateDeclaration(const char *name, const std::vector<UniformFieldDesc> &fields)
{
mFields = fields;
FString decl;
decl.Format("layout(%s) uniform %s\n{\n", screen->GetUniformLayoutString(mBindingPoint).GetChars(), name);
decl.Format("layout(%s) uniform %s\n{\n", screen->GetUniformLayoutString(bindingpoint).GetChars(), name);
for (const auto &field : fields)
{
decl.AppendFormat("\t%s %s;\n", GetTypeStr(field.Type), field.Name);
@ -69,13 +75,14 @@ public:
mBuffer = screen->CreateUniformBuffer(sizeof(T));
}
void Set(int index)
void Set(bool bind = true)
{
if (mBuffer != nullptr)
mBuffer->SetData(&Values);
// Needs to be done in an API independent way!
glBindBufferBase(GL_UNIFORM_BUFFER, index, ((GLUniformBuffer*)mBuffer)->ID());
// Let's hope this can be done better when things have moved further ahead.
// This really is not the best place to add something that depends on API behavior.
if (bind) mBuffer->Bind(bindingpoint);
}
T *operator->() { return &Values; }
@ -104,12 +111,12 @@ private:
case UniformType::UVec2: return "uvec2";
case UniformType::UVec3: return "uvec3";
case UniformType::UVec4: return "uvec4";
case UniformType::Mat4: return "mat4";
}
}
IUniformBuffer *mBuffer = nullptr;
std::vector<UniformFieldDesc> mFields;
int mBindingPoint; // Fixme: This needs to be known on init because Vulkan wants to put it into the block declaration.
};
class FShaderProgram

View file

@ -35,7 +35,7 @@ void FShadowMapShader::Bind()
mShader.SetFragDataLocation(0, "FragColor");
mShader.Link("shaders/glsl/shadowmap");
mShader.SetAttribLocation(0, "PositionInProjection");
mShader.SetUniformBufferLocation(POSTPROCESS_BINDINGPOINT, "Uniforms");
mShader.SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms");
Uniforms.Init();
}
mShader.Bind();

View file

@ -25,7 +25,7 @@ public:
}
};
ShaderUniforms<UniformBlock> Uniforms;
ShaderUniforms<UniformBlock, POSTPROCESS_BINDINGPOINT> Uniforms;
private:
FShaderProgram mShader;

View file

@ -76,7 +76,7 @@ void FExposureExtractShader::Bind()
mShader.SetFragDataLocation(0, "FragColor");
mShader.Link("shaders/glsl/exposureextract");
mShader.SetAttribLocation(0, "PositionInProjection");
mShader.SetUniformBufferLocation(POSTPROCESS_BINDINGPOINT, "Uniforms");
mShader.SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms");
SceneTexture.Init(mShader, "SceneTexture");
Uniforms.Init();
}
@ -108,7 +108,7 @@ void FExposureCombineShader::Bind()
mShader.SetFragDataLocation(0, "FragColor");
mShader.Link("shaders/glsl/exposurecombine");
mShader.SetAttribLocation(0, "PositionInProjection");
mShader.SetUniformBufferLocation(POSTPROCESS_BINDINGPOINT, "Uniforms");
mShader.SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms");
ExposureTexture.Init(mShader, "ExposureTexture");
Uniforms.Init();
}

View file

@ -53,7 +53,7 @@ public:
}
};
ShaderUniforms<UniformBlock> Uniforms;
ShaderUniforms<UniformBlock, POSTPROCESS_BINDINGPOINT> Uniforms;
private:
FShaderProgram mShader;
@ -96,7 +96,7 @@ public:
}
};
ShaderUniforms<UniformBlock> Uniforms;
ShaderUniforms<UniformBlock, POSTPROCESS_BINDINGPOINT> Uniforms;
private:
FShaderProgram mShader;

View file

@ -118,7 +118,7 @@ static void prepareInterleavedPresent(FPresentStereoShaderBase& shader)
screen->mScreenViewport.width / (float)GLRenderer->mBuffers->GetWidth(),
screen->mScreenViewport.height / (float)GLRenderer->mBuffers->GetHeight()
};
shader.Uniforms.Set(POSTPROCESS_BINDINGPOINT);
shader.Uniforms.Set();
}
// fixme: I don't know how to get absolute window position on Mac and Linux
@ -155,7 +155,7 @@ void CheckerInterleaved3D::Present() const
+ screen->mOutputLetterbox.height + 1 // +1 because of origin at bottom
) % 2; // because we want the top pixel offset, but gl_FragCoord.y is the bottom pixel offset
GLRenderer->mPresent3dCheckerShader->Uniforms.Set(POSTPROCESS_BINDINGPOINT);
GLRenderer->mPresent3dCheckerShader->Uniforms.Set();
GLRenderer->RenderScreenQuad();
}
@ -193,7 +193,7 @@ void ColumnInterleaved3D::Present() const
#endif // _WIN32
GLRenderer->mPresent3dColumnShader->Uniforms->WindowPositionParity = windowHOffset;
GLRenderer->mPresent3dColumnShader->Uniforms.Set(POSTPROCESS_BINDINGPOINT);
GLRenderer->mPresent3dColumnShader->Uniforms.Set();
GLRenderer->RenderScreenQuad();
}
@ -220,7 +220,7 @@ void RowInterleaved3D::Present() const
+ screen->mOutputLetterbox.height + 1 // +1 because of origin at bottom
) % 2;
GLRenderer->mPresent3dColumnShader->Uniforms.Set(POSTPROCESS_BINDINGPOINT);
GLRenderer->mPresent3dColumnShader->Uniforms.Set();
GLRenderer->RenderScreenQuad();
}

View file

@ -12,6 +12,7 @@ protected:
public:
virtual ~IUniformBuffer() {}
virtual void SetData(const void *data) = 0;
virtual void Bind(int bindingpoint) = 0; // This is only here for OpenGL. Vulkan doesn't need the ability to bind this at run time.
};