- read sampler bindings from the shader instead of tagging along a large amount of support data.

Works for most shaders, except SSAO.
This commit is contained in:
Christoph Oelckers 2018-06-13 15:53:56 +02:00
parent 59827cd601
commit ce50b0e46b
49 changed files with 283 additions and 259 deletions

View file

@ -680,7 +680,7 @@ file( GLOB HEADER_FILES
hwrenderer/dynlights/*.h
hwrenderer/scene/*.h
hwrenderer/textures/*.h
hwrenderer/utilities/*.h
hwrenderer/utility/*.h
gl/*.h
gl/data/*.h
gl/dynlights/*.h
@ -1061,6 +1061,7 @@ set (PCH_SOURCES
hwrenderer/utility/hw_clock.cpp
hwrenderer/utility/hw_cvars.cpp
hwrenderer/utility/hw_lighting.cpp
hwrenderer/utility/hw_shaderpatcher.cpp
menu/joystickmenu.cpp
menu/loadsavemenu.cpp

View file

@ -116,8 +116,6 @@ void FGLRenderer::AmbientOccludeScene()
mBuffers->BindSceneDepthTexture(0);
mBuffers->BindSceneColorTexture(1);
mLinearDepthShader->Bind();
mLinearDepthShader->DepthTexture.Set(0);
mLinearDepthShader->ColorTexture.Set(1);
if (gl_multisample > 1) mLinearDepthShader->Uniforms->SampleIndex = 0;
mLinearDepthShader->Uniforms->LinearizeDepthA = 1.0f / GetZFar() - 1.0f / GetZNear();
mLinearDepthShader->Uniforms->LinearizeDepthB = MAX(1.0f / GetZNear(), 1.e-8f);
@ -134,9 +132,6 @@ void FGLRenderer::AmbientOccludeScene()
mBuffers->AmbientRandomTexture[randomTexture].Bind(1, GL_NEAREST, GL_REPEAT);
mBuffers->BindSceneNormalTexture(2);
mSSAOShader->Bind();
mSSAOShader->DepthTexture.Set(0);
mSSAOShader->RandomTexture.Set(1);
mSSAOShader->NormalTexture.Set(2);
if (gl_multisample > 1) mSSAOShader->Uniforms->SampleIndex = 0;
mSSAOShader->Uniforms->UVToViewA = { 2.0f * invFocalLenX, 2.0f * invFocalLenY };
mSSAOShader->Uniforms->UVToViewB = { -invFocalLenX, -invFocalLenY };
@ -186,8 +181,6 @@ void FGLRenderer::AmbientOccludeScene()
mBuffers->AmbientTexture1.Bind(0, GL_LINEAR);
mBuffers->BindSceneFogTexture(1);
mSSAOCombineShader->Bind();
mSSAOCombineShader->AODepthTexture.Set(0);
mSSAOCombineShader->SceneFogTexture.Set(1);
if (gl_multisample > 1) mSSAOCombineShader->Uniforms->SampleCount = gl_multisample;
mSSAOCombineShader->Uniforms->Scale = { sceneScaleX, sceneScaleY };
mSSAOCombineShader->Uniforms->Offset = { sceneOffsetX, sceneOffsetY };
@ -222,7 +215,6 @@ void FGLRenderer::UpdateCameraExposure()
glViewport(0, 0, level0.Width, level0.Height);
mBuffers->BindCurrentTexture(0, GL_LINEAR);
mExposureExtractShader->Bind();
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();
@ -238,7 +230,6 @@ void FGLRenderer::UpdateCameraExposure()
glViewport(0, 0, next.Width, next.Height);
level.Texture.Bind(0);
mExposureAverageShader->Bind();
mExposureAverageShader->ExposureTexture.Set(0);
RenderScreenQuad();
}
@ -257,7 +248,6 @@ void FGLRenderer::UpdateCameraExposure()
}
mBuffers->ExposureLevels.Last().Texture.Bind(0);
mExposureCombineShader->Bind();
mExposureCombineShader->ExposureTexture.Set(0);
mExposureCombineShader->Uniforms->ExposureBase = gl_exposure_base;
mExposureCombineShader->Uniforms->ExposureMin = gl_exposure_min;
mExposureCombineShader->Uniforms->ExposureScale = gl_exposure_scale;
@ -307,7 +297,6 @@ static void RenderBlur(FGLRenderer *renderer, float blurAmount, PPTexture input,
ComputeBlurSamples(7, blurAmount, renderer->mBlurShader->Uniforms[vertical]->SampleWeights);
renderer->mBlurShader->Bind(vertical);
renderer->mBlurShader->SourceTexture[vertical].Set(0);
renderer->mBlurShader->Uniforms[vertical].Set(POSTPROCESS_BINDINGPOINT);
input.Bind(0);
@ -341,8 +330,6 @@ void FGLRenderer::BloomScene(int fixedcm)
mBuffers->BindCurrentTexture(0, GL_LINEAR);
mBuffers->ExposureTexture.Bind(1);
mBloomExtractShader->Bind();
mBloomExtractShader->SceneTexture.Set(0);
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();
@ -371,7 +358,6 @@ void FGLRenderer::BloomScene(int fixedcm)
glViewport(0, 0, next.Width, next.Height);
level.VTexture.Bind(0, GL_LINEAR);
mBloomCombineShader->Bind();
mBloomCombineShader->BloomTexture.Set(0);
RenderScreenQuad();
}
@ -386,7 +372,6 @@ void FGLRenderer::BloomScene(int fixedcm)
glBlendFunc(GL_ONE, GL_ONE);
level0.VTexture.Bind(0, GL_LINEAR);
mBloomCombineShader->Bind();
mBloomCombineShader->BloomTexture.Set(0);
RenderScreenQuad();
glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
@ -450,7 +435,6 @@ void FGLRenderer::BlurScene(float gameinfobluramount)
glViewport(0, 0, next.Width, next.Height);
level.VTexture.Bind(0, GL_LINEAR);
mBloomCombineShader->Bind();
mBloomCombineShader->BloomTexture.Set(0);
RenderScreenQuad();
}
@ -486,24 +470,20 @@ void FGLRenderer::TonemapScene()
mBuffers->BindNextFB();
mBuffers->BindCurrentTexture(0);
mTonemapShader->Bind();
mTonemapShader->SceneTexture.Set(0);
if (mTonemapShader->IsPaletteMode())
{
glActiveTexture(GL_TEXTURE1);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, mTonemapPalette->GetTextureHandle(0));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glActiveTexture(GL_TEXTURE0);
mTonemapShader->PaletteLUT.Set(1);
}
else
{
mBuffers->ExposureTexture.Bind(1);
mTonemapShader->ExposureTexture.Set(1);
}
RenderScreenQuad();
@ -625,7 +605,6 @@ void FGLRenderer::LensDistortScene()
mBuffers->BindNextFB();
mBuffers->BindCurrentTexture(0, GL_LINEAR);
mLensShader->Bind();
mLensShader->InputTexture.Set(0);
mLensShader->Uniforms->AspectRatio = aspect;
mLensShader->Uniforms->Scale = scale;
mLensShader->Uniforms->LensDistortionCoefficient = k;
@ -657,14 +636,12 @@ void FGLRenderer::ApplyFXAA()
mBuffers->BindNextFB();
mBuffers->BindCurrentTexture(0);
mFXAALumaShader->Bind();
mFXAALumaShader->InputTexture.Set(0);
RenderScreenQuad();
mBuffers->NextTexture();
mBuffers->BindNextFB();
mBuffers->BindCurrentTexture(0, GL_LINEAR);
mFXAAShader->Bind();
mFXAAShader->InputTexture.Set(0);
mFXAAShader->Uniforms->ReciprocalResolution = { 1.0f / mBuffers->GetWidth(), 1.0f / mBuffers->GetHeight() };
mFXAAShader->Uniforms.Set();
RenderScreenQuad();
@ -768,7 +745,6 @@ void FGLRenderer::DrawPresentTexture(const IntRect &box, bool applyGamma)
}
mPresentShader->Bind();
mPresentShader->InputTexture.Set(0);
if (!applyGamma || framebuffer->IsHWGammaActive())
{
mPresentShader->Uniforms->InvGamma = 1.0f;

View file

@ -41,8 +41,6 @@ void FLinearDepthShader::Bind()
mShader->Compile(FShaderProgram::Fragment, "shaders/glsl/lineardepth.fp", prolog, 330);
mShader->Link("shaders/glsl/lineardepth");
mShader->SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms");
DepthTexture.Init(*mShader, "DepthTexture");
ColorTexture.Init(*mShader, "ColorTexture");
Uniforms.Init();
mMultisample = multisample;
}
@ -65,9 +63,6 @@ void FSSAOShader::Bind()
mShader->Compile(FShaderProgram::Fragment, "shaders/glsl/ssao.fp", prolog, 330);
mShader->Link("shaders/glsl/ssao");
mShader->SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms");
DepthTexture.Init(*mShader, "DepthTexture");
NormalTexture.Init(*mShader, "NormalTexture");
RandomTexture.Init(*mShader, "RandomTexture");
Uniforms.Init();
mMultisample = multisample;
}
@ -114,7 +109,6 @@ void FDepthBlurShader::Bind(bool vertical)
shader.Compile(FShaderProgram::Fragment, "shaders/glsl/depthblur.fp", prolog, 330);
shader.Link("shaders/glsl/depthblur");
shader.SetUniformBufferLocation(Uniforms[vertical].BindingPoint(), "Uniforms");
AODepthTexture[vertical].Init(shader, "AODepthTexture");
Uniforms[vertical].Init();
}
shader.Bind();
@ -137,8 +131,6 @@ void FSSAOCombineShader::Bind()
mShader->Compile(FShaderProgram::Fragment, "shaders/glsl/ssaocombine.fp", prolog, 330);
mShader->Link("shaders/glsl/ssaocombine");
mShader->SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms");
AODepthTexture.Init(*mShader, "AODepthTexture");
SceneFogTexture.Init(*mShader, "SceneFogTexture");
Uniforms.Init();
mMultisample = multisample;
}

View file

@ -10,9 +10,6 @@ class FLinearDepthShader
public:
void Bind();
FBufferedUniformSampler DepthTexture;
FBufferedUniformSampler ColorTexture;
struct UniformBlock
{
int SampleIndex;
@ -54,10 +51,6 @@ class FSSAOShader
public:
void Bind();
FBufferedUniformSampler DepthTexture;
FBufferedUniformSampler NormalTexture;
FBufferedUniformSampler RandomTexture;
struct UniformBlock
{
FVector2 UVToViewA;
@ -118,8 +111,6 @@ class FDepthBlurShader
public:
void Bind(bool vertical);
FBufferedUniformSampler AODepthTexture[2];
struct UniformBlock
{
float BlurSharpness;
@ -148,9 +139,6 @@ class FSSAOCombineShader
public:
void Bind();
FBufferedUniformSampler AODepthTexture;
FBufferedUniformSampler SceneFogTexture;
struct UniformBlock
{
int SampleCount;

View file

@ -39,8 +39,6 @@ void FBloomExtractShader::Bind()
mShader.Compile(FShaderProgram::Fragment, "shaders/glsl/bloomextract.fp", prolog, 330);
mShader.Link("shaders/glsl/bloomextract");
mShader.SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms");
SceneTexture.Init(mShader, "SceneTexture");
ExposureTexture.Init(mShader, "ExposureTexture");
Uniforms.Init();
}
mShader.Bind();
@ -53,7 +51,6 @@ void FBloomCombineShader::Bind()
mShader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330);
mShader.Compile(FShaderProgram::Fragment, "shaders/glsl/bloomcombine.fp", "", 330);
mShader.Link("shaders/glsl/bloomcombine");
BloomTexture.Init(mShader, "Bloom");
}
mShader.Bind();
}

View file

@ -8,9 +8,6 @@ class FBloomExtractShader
public:
void Bind();
FBufferedUniformSampler SceneTexture;
FBufferedUniformSampler ExposureTexture;
struct UniformBlock
{
FVector2 Scale;
@ -37,8 +34,6 @@ class FBloomCombineShader
public:
void Bind();
FBufferedUniformSampler BloomTexture;
private:
FShaderProgram mShader;
};

View file

@ -46,7 +46,6 @@ void FBlurShader::Bind(bool vertical)
mShader[vertical].Compile(FShaderProgram::Fragment, "shaders/glsl/blur.fp", prolog, 330);
mShader[vertical].Link("shaders/glsl/blur");
mShader[vertical].SetUniformBufferLocation(POSTPROCESS_BINDINGPOINT, "Uniforms");
SourceTexture[vertical].Init(mShader[vertical], "SourceTexture");
Uniforms[vertical].Init();
}

View file

@ -13,8 +13,6 @@ class FBlurShader
public:
void Bind(bool vertical);
FBufferedUniformSampler SourceTexture[2];
struct UniformBlock
{
float SampleWeights[8];

View file

@ -35,7 +35,6 @@ void FColormapShader::Bind()
if (!shader)
{
FString prolog = Uniforms.CreateDeclaration("Uniforms", UniformBlock::Desc());
shader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330);
shader.Compile(FShaderProgram::Fragment, "shaders/glsl/colormap.fp", prolog, 330);
shader.Link("shaders/glsl/colormap");

View file

@ -8,8 +8,6 @@ class FColormapShader
public:
void Bind();
FBufferedUniformSampler SceneTexture;
struct UniformBlock
{
FVector4 MapStart;

View file

@ -36,7 +36,6 @@ void FFXAALumaShader::Bind()
mShader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330);
mShader.Compile(FShaderProgram::Fragment, "shaders/glsl/fxaa.fp", "#define FXAA_LUMA_PASS\n", 330);
mShader.Link("shaders/glsl/fxaa");
InputTexture.Init(mShader, "InputTexture");
}
mShader.Bind();
@ -81,14 +80,13 @@ void FFXAAShader::Bind()
if (!shader)
{
const FString prolog = Uniforms.CreateDeclaration("Uniforms", UniformBlock::Desc()) + GetDefines();
FString prolog = Uniforms.CreateDeclaration("Uniforms", UniformBlock::Desc()) + GetDefines();
const int maxVersion = GetMaxVersion();
shader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330);
shader.Compile(FShaderProgram::Fragment, "shaders/glsl/fxaa.fp", prolog, maxVersion);
shader.Link("shaders/glsl/fxaa");
shader.SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms");
InputTexture.Init(shader, "InputTexture");
Uniforms.Init();
}

View file

@ -35,8 +35,6 @@ class FFXAALumaShader
public:
void Bind();
FBufferedUniform1i InputTexture;
private:
FShaderProgram mShader;
};
@ -47,8 +45,6 @@ class FFXAAShader : public IFXAAShader
public:
void Bind();
FBufferedUniform1i InputTexture;
struct UniformBlock
{
FVector2 ReciprocalResolution;

View file

@ -39,7 +39,6 @@ void FLensShader::Bind()
mShader.Compile(FShaderProgram::Fragment, "shaders/glsl/lensdistortion.fp", prolog, 330);
mShader.Link("shaders/glsl/lensdistortion");
mShader.SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms");
InputTexture.Init(mShader, "InputTexture");
Uniforms.Init();
}
mShader.Bind();

View file

@ -8,8 +8,6 @@ class FLensShader
public:
void Bind();
FBufferedUniformSampler InputTexture;
struct UniformBlock
{
float AspectRatio;

View file

@ -93,8 +93,6 @@ void PostProcessShaderInstance::Run()
UpdateUniforms();
BindTextures();
mInputTexture.Set(0);
GLRenderer->RenderScreenQuad();
glActiveTexture(GL_TEXTURE0);

View file

@ -22,7 +22,7 @@ private:
void BindTextures();
FShaderProgram mProgram;
FBufferedUniformSampler mInputTexture;
FUniform1i mInputTexture;
std::map<FTexture*, int> mTextureHandles;
};

View file

@ -30,13 +30,6 @@
#include "gl_load/gl_system.h"
#include "gl/shaders/gl_present3dRowshader.h"
void FPresentStereoShaderBase::Init(const char * vtx_shader_name, const char * program_name)
{
FPresentShaderBase::Init(vtx_shader_name, program_name);
LeftEyeTexture.Init(mShader, "LeftEyeTexture");
RightEyeTexture.Init(mShader, "RightEyeTexture");
}
void FPresent3DCheckerShader::Bind()
{
if (!mShader)

View file

@ -31,29 +31,19 @@
#include "gl_shaderprogram.h"
#include "gl_presentshader.h"
class FPresentStereoShaderBase : public FPresentShaderBase
{
public:
FBufferedUniformSampler LeftEyeTexture;
FBufferedUniformSampler RightEyeTexture;
protected:
void Init(const char * vtx_shader_name, const char * program_name) override;
};
class FPresent3DCheckerShader : public FPresentStereoShaderBase
class FPresent3DCheckerShader : public FPresentShaderBase
{
public:
void Bind() override;
};
class FPresent3DColumnShader : public FPresentStereoShaderBase
class FPresent3DColumnShader : public FPresentShaderBase
{
public:
void Bind() override;
};
class FPresent3DRowShader : public FPresentStereoShaderBase
class FPresent3DRowShader : public FPresentShaderBase
{
public:
void Bind() override;

View file

@ -45,7 +45,6 @@ void FPresentShader::Bind()
if (!mShader)
{
Init("shaders/glsl/present.fp", "shaders/glsl/present");
InputTexture.Init(mShader, "InputTexture");
}
mShader.Bind();
}

View file

@ -46,7 +46,6 @@ class FPresentShader : public FPresentShaderBase
public:
void Bind() override;
FBufferedUniformSampler InputTexture;
};
#endif

View file

@ -32,6 +32,7 @@
#include "w_wad.h"
#include "doomerrors.h"
#include "cmdlib.h"
#include "hwrenderer/utility/hw_shaderpatcher.h"
#include "gl_load/gl_interface.h"
#include "gl/system/gl_debug.h"
@ -41,88 +42,6 @@
#include "gl/shaders/gl_shader.h"
#include "gl/dynlights/gl_lightbuffer.h"
static bool IsGlslWhitespace(char c)
{
switch (c)
{
case ' ':
case '\r':
case '\n':
case '\t':
case '\f':
return true;
default:
return false;
}
}
static FString NextGlslToken(const char *chars, long len, long &pos)
{
// Eat whitespace
long tokenStart = pos;
while (tokenStart != len && IsGlslWhitespace(chars[tokenStart]))
tokenStart++;
// Find token end
long tokenEnd = tokenStart;
while (tokenEnd != len && !IsGlslWhitespace(chars[tokenEnd]) && chars[tokenEnd] != ';')
tokenEnd++;
pos = tokenEnd;
return FString(chars + tokenStart, tokenEnd - tokenStart);
}
static FString RemoveLegacyUserUniforms(FString code)
{
// User shaders must declare their uniforms via the GLDEFS file.
// The following code searches for legacy uniform declarations in the shader itself and replaces them with whitespace.
long len = (long)code.Len();
char *chars = code.LockBuffer();
long startIndex = 0;
while (true)
{
long matchIndex = code.IndexOf("uniform", startIndex);
if (matchIndex == -1)
break;
bool isLegacyUniformName = false;
bool isKeywordStart = matchIndex == 0 || IsGlslWhitespace(chars[matchIndex - 1]);
bool isKeywordEnd = matchIndex + 7 == len || IsGlslWhitespace(chars[matchIndex + 7]);
if (isKeywordStart && isKeywordEnd)
{
long pos = matchIndex + 7;
FString type = NextGlslToken(chars, len, pos);
FString identifier = NextGlslToken(chars, len, pos);
isLegacyUniformName = type.Compare("float") == 0 && identifier.Compare("timer") == 0;
}
if (isLegacyUniformName)
{
long statementEndIndex = code.IndexOf(';', matchIndex + 7);
if (statementEndIndex == -1)
statementEndIndex = len;
for (long i = matchIndex; i <= statementEndIndex; i++)
{
if (!IsGlslWhitespace(chars[i]))
chars[i] = ' ';
}
startIndex = statementEndIndex;
}
else
{
startIndex = matchIndex + 7;
}
}
code.UnlockBuffer();
return code;
}
bool FShader::Load(const char * name, const char * vert_prog_lump, const char * frag_prog_lump, const char * proc_prog_lump, const char * light_fragprog, const char * defines)
{
static char buffer[10000];

View file

@ -230,29 +230,6 @@ public:
}
};
class FBufferedUniformSampler
{
int mBuffer;
int mIndex;
public:
void Init(GLuint hShader, const GLchar *name)
{
mIndex = glGetUniformLocation(hShader, name);
mBuffer = -1;
}
void Set(int newvalue)
{
if (newvalue != mBuffer)
{
mBuffer = newvalue;
glUniform1i(mIndex, newvalue);
}
}
};
class FShader
{
friend class FShaderCollection;

View file

@ -31,6 +31,7 @@
#include "hwrenderer/utility/hw_cvars.h"
#include "gl/system/gl_debug.h"
#include "gl/shaders/gl_shaderprogram.h"
#include "hwrenderer/utility/hw_shaderpatcher.h"
#include "w_wad.h"
FShaderProgram::FShaderProgram()
@ -135,11 +136,27 @@ void FShaderProgram::Link(const char *name)
{
I_FatalError("Link Shader '%s':\n%s\n", name, GetProgramInfoLog(mProgram).GetChars());
}
// This is only for old OpenGL which didn't allow to set the binding from within the shader.
if (screen->glslversion < 4.20)
{
glUseProgram(mProgram);
for (auto &uni : samplerstobind)
{
auto index = glGetUniformLocation(mProgram, uni.first);
if (index >= 0)
{
glUniform1i(index, uni.second);
}
}
}
samplerstobind.Clear();
samplerstobind.ShrinkToFit();
}
//==========================================================================
//
// Set uniform buffer location
// Set uniform buffer location (only useful for GL 3.3)
//
//==========================================================================
@ -227,5 +244,11 @@ FString FShaderProgram::PatchShader(ShaderType type, const FString &code, const
patchedCode << "#line 1\n";
patchedCode << code;
if (maxGlslVersion < 420)
{
// Here we must strip out all layout(binding) declarations for sampler uniforms and store them in 'samplerstobind' which can then be processed by the link function.
patchedCode = RemoveSamplerBindings(patchedCode, samplerstobind);
}
return patchedCode;
}

View file

@ -22,6 +22,7 @@ public:
void Compile(ShaderType type, const char *name, const FString &code, const char *defines, int maxGlslVersion);
void Link(const char *name);
void SetUniformBufferLocation(int index, const char *name);
void Bind();
operator GLuint() const { return mProgram; }
@ -31,7 +32,7 @@ private:
FShaderProgram(const FShaderProgram &) = delete;
FShaderProgram &operator=(const FShaderProgram &) = delete;
static FString PatchShader(ShaderType type, const FString &code, const char *defines, int maxGlslVersion);
FString PatchShader(ShaderType type, const FString &code, const char *defines, int maxGlslVersion);
void CreateShader(ShaderType type);
FString GetShaderInfoLog(GLuint handle);
@ -39,4 +40,5 @@ private:
GLuint mProgram = 0;
GLuint mShaders[NumShaderTypes];
TArray<std::pair<FString, int>> samplerstobind;
};

View file

@ -35,12 +35,11 @@ void FTonemapShader::Bind()
auto &shader = mShader[gl_tonemap];
if (!shader)
{
auto prolog = GetDefines(gl_tonemap);
shader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330);
shader.Compile(FShaderProgram::Fragment, "shaders/glsl/tonemap.fp", GetDefines(gl_tonemap), 330);
shader.Compile(FShaderProgram::Fragment, "shaders/glsl/tonemap.fp", prolog, 330);
shader.Link("shaders/glsl/tonemap");
SceneTexture.Init(shader, "InputTexture");
ExposureTexture.Init(shader, "ExposureTexture");
PaletteLUT.Init(shader, "PaletteLUT");
}
shader.Bind();
}
@ -73,7 +72,6 @@ void FExposureExtractShader::Bind()
mShader.Compile(FShaderProgram::Fragment, "shaders/glsl/exposureextract.fp", prolog, 330);
mShader.Link("shaders/glsl/exposureextract");
mShader.SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms");
SceneTexture.Init(mShader, "SceneTexture");
Uniforms.Init();
}
mShader.Bind();
@ -86,7 +84,6 @@ void FExposureAverageShader::Bind()
mShader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 400);
mShader.Compile(FShaderProgram::Fragment, "shaders/glsl/exposureaverage.fp", "", 400);
mShader.Link("shaders/glsl/exposureaverage");
ExposureTexture.Init(mShader, "ExposureTexture");
}
mShader.Bind();
}
@ -101,7 +98,6 @@ void FExposureCombineShader::Bind()
mShader.Compile(FShaderProgram::Fragment, "shaders/glsl/exposurecombine.fp", prolog, 330);
mShader.Link("shaders/glsl/exposurecombine");
mShader.SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms");
ExposureTexture.Init(mShader, "ExposureTexture");
Uniforms.Init();
}
mShader.Bind();

View file

@ -8,10 +8,6 @@ class FTonemapShader
public:
void Bind();
FBufferedUniformSampler SceneTexture;
FBufferedUniformSampler ExposureTexture;
FBufferedUniformSampler PaletteLUT;
static bool IsPaletteMode();
private:
@ -36,8 +32,6 @@ class FExposureExtractShader
public:
void Bind();
FBufferedUniformSampler SceneTexture;
struct UniformBlock
{
FVector2 Scale;
@ -64,8 +58,6 @@ class FExposureAverageShader
public:
void Bind();
FBufferedUniformSampler ExposureTexture;
private:
FShaderProgram mShader;
};
@ -75,8 +67,6 @@ class FExposureCombineShader
public:
void Bind();
FBufferedUniformSampler ExposureTexture;
struct UniformBlock
{
float ExposureBase;

View file

@ -74,7 +74,7 @@ const RowInterleaved3D& RowInterleaved3D::getInstance(float ipd)
return instance;
}
static void prepareInterleavedPresent(FPresentStereoShaderBase& shader)
static void prepareInterleavedPresent(FPresentShaderBase& shader)
{
GLRenderer->mBuffers->BindOutputFB();
GLRenderer->ClearBorders();
@ -96,8 +96,6 @@ static void prepareInterleavedPresent(FPresentStereoShaderBase& shader)
glViewport(box.left, box.top, box.width, box.height);
shader.Bind();
shader.LeftEyeTexture.Set(0);
shader.RightEyeTexture.Set(1);
if ( GLRenderer->framebuffer->IsHWGammaActive() )
{

View file

@ -164,7 +164,19 @@ struct SamplerUniform
case SamplerType::uSamplerCube: return "usamplerCube";
}
}
static FString CreateDeclaration(std::vector<SamplerUniform> &samplers)
{
FString build;
for (auto &sampler : samplers)
{
if (screen->glslversion >= 4.2f) build.AppendFormat("layout(binding = %d) uniform", sampler.mBinding);
build.AppendFormat("%s %s;\n", sampler.GetTypeStr(), sampler.mName);
}
return build;
}
int mBinding;
SamplerType mType;
const char *mName;

View file

@ -0,0 +1,187 @@
//
//---------------------------------------------------------------------------
//
// Copyright(C) 2004-2018 Christoph Oelckers
// All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see http://www.gnu.org/licenses/
//
//--------------------------------------------------------------------------
//
/*
** hw_shaderpatcher.cpp
**
** Modifies shader source to account for different syntax versions or engine changes.
**
*/
#include "hw_shaderpatcher.h"
static bool IsGlslWhitespace(char c)
{
switch (c)
{
case ' ':
case '\r':
case '\n':
case '\t':
case '\f':
return true;
default:
return false;
}
}
static FString NextGlslToken(const char *chars, long len, long &pos)
{
// Eat whitespace
long tokenStart = pos;
while (tokenStart != len && IsGlslWhitespace(chars[tokenStart]))
tokenStart++;
// Find token end
long tokenEnd = tokenStart;
while (tokenEnd != len && !IsGlslWhitespace(chars[tokenEnd]) && chars[tokenEnd] != ';')
tokenEnd++;
pos = tokenEnd;
return FString(chars + tokenStart, tokenEnd - tokenStart);
}
static bool isShaderType(const char *name)
{
return !strcmp(name, "sampler1D") || !strcmp(name, "sampler2D") || !strcmp(name, "sampler3D") || !strcmp(name, "samplerCube") || !strcmp(name, "sampler2DMS");
}
FString RemoveLegacyUserUniforms(FString code)
{
// User shaders must declare their uniforms via the GLDEFS file.
// The following code searches for legacy uniform declarations in the shader itself and replaces them with whitespace.
long len = (long)code.Len();
char *chars = code.LockBuffer();
long startIndex = 0;
while (true)
{
long matchIndex = code.IndexOf("uniform", startIndex);
if (matchIndex == -1)
break;
bool isLegacyUniformName = false;
bool isKeywordStart = matchIndex == 0 || IsGlslWhitespace(chars[matchIndex - 1]);
bool isKeywordEnd = matchIndex + 7 == len || IsGlslWhitespace(chars[matchIndex + 7]);
if (isKeywordStart && isKeywordEnd)
{
long pos = matchIndex + 7;
FString type = NextGlslToken(chars, len, pos);
FString identifier = NextGlslToken(chars, len, pos);
isLegacyUniformName = type.Compare("float") == 0 && identifier.Compare("timer") == 0;
}
if (isLegacyUniformName)
{
long statementEndIndex = code.IndexOf(';', matchIndex + 7);
if (statementEndIndex == -1)
statementEndIndex = len;
for (long i = matchIndex; i <= statementEndIndex; i++)
{
if (!IsGlslWhitespace(chars[i]))
chars[i] = ' ';
}
startIndex = statementEndIndex;
}
else
{
startIndex = matchIndex + 7;
}
}
code.UnlockBuffer();
return code;
}
FString RemoveSamplerBindings(FString code, TArray<std::pair<FString, int>> &samplerstobind)
{
long len = (long)code.Len();
char *chars = code.LockBuffer();
long startIndex = 0;
long startpos, endpos;
while (true)
{
long matchIndex = code.IndexOf("layout(binding", startIndex);
if (matchIndex == -1)
break;
bool isSamplerUniformName = false;
bool isKeywordStart = matchIndex == 0 || IsGlslWhitespace(chars[matchIndex - 1]);
bool isKeywordEnd = matchIndex + 14 == len || IsGlslWhitespace(chars[matchIndex + 14]) || chars[matchIndex + 14] == '=';
if (isKeywordStart && isKeywordEnd)
{
long pos = matchIndex + 14;
startpos = matchIndex;
while (IsGlslWhitespace(chars[pos])) pos++;
if (chars[pos] == '=')
{
char *p;
pos++;
auto val = strtol(&chars[pos], &p, 0);
if (p != &chars[pos])
{
pos = long(p - chars);
while (IsGlslWhitespace(chars[pos])) pos++;
if (chars[pos] == ')')
{
endpos = ++pos;
FString uniform = NextGlslToken(chars, len, pos);
FString type = NextGlslToken(chars, len, pos);
FString identifier = NextGlslToken(chars, len, pos);
isSamplerUniformName = uniform.Compare("uniform") == 0 && isShaderType(type);
if (isSamplerUniformName)
{
samplerstobind.Push(std::make_pair(identifier, val));
for (auto pos = startpos; pos < endpos; pos++)
{
if (!IsGlslWhitespace(chars[pos]))
chars[pos] = ' ';
}
}
}
}
}
}
if (isSamplerUniformName)
{
startIndex = endpos;
}
else
{
startIndex = matchIndex + 7;
}
}
code.UnlockBuffer();
return code;
}

View file

@ -0,0 +1,9 @@
#pragma once
#include "tarray.h"
#include "zstring.h"
#include "utility"
FString RemoveLegacyUserUniforms(FString code);
FString RemoveSamplerBindings(FString code, TArray<std::pair<FString, int>> &samplerstobind); // For GL 3.3 compatibility which cannot declare sampler bindings in the sampler source.

View file

@ -117,6 +117,7 @@ struct FColormap;
class FileWriter;
enum FTextureFormat : uint32_t;
class FModelRenderer;
struct SamplerUniform;
// TagItem definitions for DrawTexture. As far as I know, tag lists
// originated on the Amiga.

View file

@ -2,7 +2,7 @@
in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
uniform sampler2D Bloom;
layout(binding=0) uniform sampler2D Bloom;
void main()
{

View file

@ -1,9 +1,8 @@
in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
uniform sampler2D SceneTexture;
uniform sampler2D ExposureTexture;
layout(binding=0) uniform sampler2D SceneTexture;
layout(binding=1) uniform sampler2D ExposureTexture;
void main()
{

View file

@ -2,7 +2,7 @@
in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
uniform sampler2D SourceTexture;
layout(binding=0) uniform sampler2D SourceTexture;
void main()
{

View file

@ -1,12 +1,11 @@
in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
uniform sampler2D tex;
layout(binding=0) uniform sampler2D SceneTexture;
void main()
{
vec4 frag = texture(tex, TexCoord);
vec4 frag = texture(SceneTexture, TexCoord);
float gray = (frag.r * 0.3 + frag.g * 0.56 + frag.b * 0.14);
vec4 cm = uFixedColormapStart + gray * uFixedColormapRange;
FragColor = vec4(clamp(cm.rgb, 0.0, 1.0), frag.a);

View file

@ -2,7 +2,7 @@
in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
uniform sampler2D AODepthTexture;
layout(binding=0) uniform sampler2D AODepthTexture;
#define KERNEL_RADIUS 3.0

View file

@ -1,8 +1,7 @@
in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
uniform sampler2D ExposureTexture;
layout(binding=0) uniform sampler2D ExposureTexture;
void main()
{

View file

@ -2,7 +2,7 @@
in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
uniform sampler2D ExposureTexture;
layout(binding=0) uniform sampler2D ExposureTexture;
void main()
{

View file

@ -2,7 +2,7 @@
in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
uniform sampler2D SceneTexture;
layout(binding=0) uniform sampler2D SceneTexture;
void main()
{

View file

@ -35,7 +35,7 @@
in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
uniform sampler2D InputTexture;
layout(binding=0) uniform sampler2D InputTexture;
#ifdef FXAA_LUMA_PASS

View file

@ -32,7 +32,7 @@
in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
uniform sampler2D InputTexture;
layout(binding=0) uniform sampler2D InputTexture;
void main()
{

View file

@ -3,11 +3,11 @@ in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
#if defined(MULTISAMPLE)
uniform sampler2DMS DepthTexture;
uniform sampler2DMS ColorTexture;
layout(binding=0) uniform sampler2DMS DepthTexture;
layout(binding=1) uniform sampler2DMS ColorTexture;
#else
uniform sampler2D DepthTexture;
uniform sampler2D ColorTexture;
layout(binding=0) uniform sampler2D DepthTexture;
layout(binding=1) uniform sampler2D ColorTexture;
#endif
float normalizeDepth(float depth)

View file

@ -2,7 +2,7 @@
in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
uniform sampler2D InputTexture;
layout(binding=0) uniform sampler2D InputTexture;
vec4 ApplyGamma(vec4 c)
{

View file

@ -2,8 +2,8 @@
in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
uniform sampler2D LeftEyeTexture;
uniform sampler2D RightEyeTexture;
layout(binding=0) uniform sampler2D LeftEyeTexture;
layout(binding=1) uniform sampler2D RightEyeTexture;
vec4 ApplyGamma(vec4 c)
{

View file

@ -2,8 +2,8 @@
in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
uniform sampler2D LeftEyeTexture;
uniform sampler2D RightEyeTexture;
layout(binding=0) uniform sampler2D LeftEyeTexture;
layout(binding=1) uniform sampler2D RightEyeTexture;
vec4 ApplyGamma(vec4 c)
{

View file

@ -2,8 +2,8 @@
in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
uniform sampler2D LeftEyeTexture;
uniform sampler2D RightEyeTexture;
layout(binding=0) uniform sampler2D LeftEyeTexture;
layout(binding=1) uniform sampler2D RightEyeTexture;
vec4 ApplyGamma(vec4 c)
{

View file

@ -2,16 +2,16 @@
in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
uniform sampler2D DepthTexture;
layout(binding=0) uniform sampler2D DepthTexture;
#if defined(MULTISAMPLE)
uniform sampler2DMS NormalTexture;
layout(binding=1) uniform sampler2DMS NormalTexture;
#else
uniform sampler2D NormalTexture;
layout(binding=1) uniform sampler2D NormalTexture;
#endif
#if defined(USE_RANDOM_TEXTURE)
uniform sampler2D RandomTexture;
layout(binding=2) uniform sampler2D RandomTexture;
#endif
#define PI 3.14159265358979323846

View file

@ -2,12 +2,12 @@
in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
uniform sampler2D AODepthTexture;
layout(binding=0) uniform sampler2D AODepthTexture;
#if defined(MULTISAMPLE)
uniform sampler2DMS SceneFogTexture;
layout(binding=1) uniform sampler2DMS SceneFogTexture;
#else
uniform sampler2D SceneFogTexture;
layout(binding=1) uniform sampler2D SceneFogTexture;
#endif
void main()

View file

@ -2,8 +2,8 @@
in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
uniform sampler2D InputTexture;
uniform sampler2D ExposureTexture;
layout(binding=0) uniform sampler2D InputTexture;
layout(binding=1) uniform sampler2D ExposureTexture;
vec3 Linear(vec3 c)
{
@ -65,7 +65,7 @@ vec3 Tonemap(vec3 color)
#elif defined(PALETTE)
uniform sampler2D PaletteLUT;
layout(binding=2) uniform sampler2D PaletteLUT;
vec3 Tonemap(vec3 color)
{