- change FRenderState to store directly to the StreamData struct. This simplifies the vulkan backend and also allows the OpenGL backend to use the same uniform block transfer strategy in the future.

This commit is contained in:
Magnus Norddahl 2019-04-20 04:16:01 +02:00
parent da7a4ceb34
commit 6699cd5462
7 changed files with 136 additions and 184 deletions

View file

@ -111,7 +111,7 @@ bool FGLRenderState::ApplyShader()
{
fogset = -3; // 2D rendering with 'foggy' overlay.
}
else if ((mFogColor & 0xffffff) == 0)
else if ((GetFogColor() & 0xffffff) == 0)
{
fogset = gl_fogmode;
}
@ -121,64 +121,46 @@ bool FGLRenderState::ApplyShader()
}
}
glVertexAttrib4fv(VATTR_COLOR, mColor.vec);
glVertexAttrib4fv(VATTR_NORMAL, mNormal.vec);
glVertexAttrib4fv(VATTR_COLOR, &mStreamData.uVertexColor.X);
glVertexAttrib4fv(VATTR_NORMAL, &mStreamData.uVertexNormal.X);
activeShader->muDesaturation.Set(mDesaturation / 255.f);
activeShader->muDesaturation.Set(mStreamData.uDesaturationFactor);
activeShader->muFogEnabled.Set(fogset);
activeShader->muTextureMode.Set(mTextureMode == TM_NORMAL && mTempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode);
activeShader->muLightParms.Set(mLightParms);
activeShader->muFogColor.Set(mFogColor);
activeShader->muObjectColor.Set(mObjectColor);
activeShader->muDynLightColor.Set(mDynColor.vec);
activeShader->muInterpolationFactor.Set(mInterpolationFactor);
activeShader->muFogColor.Set(mStreamData.uFogColor);
activeShader->muObjectColor.Set(mStreamData.uObjectColor);
activeShader->muDynLightColor.Set(&mStreamData.uDynLightColor.X);
activeShader->muInterpolationFactor.Set(mStreamData.uInterpolationFactor);
activeShader->muTimer.Set((double)(screen->FrameTime - firstFrame) * (double)mShaderTimer / 1000.);
activeShader->muAlphaThreshold.Set(mAlphaThreshold);
activeShader->muLightIndex.Set(-1);
activeShader->muClipSplit.Set(mClipSplit);
activeShader->muSpecularMaterial.Set(mGlossiness, mSpecularLevel);
activeShader->muAddColor.Set(mAddColor);
activeShader->muAddColor.Set(mStreamData.uAddColor);
if (mGlowEnabled)
if (mGlowEnabled || activeShader->currentglowstate)
{
activeShader->muGlowTopColor.Set(mGlowTop.vec);
activeShader->muGlowBottomColor.Set(mGlowBottom.vec);
activeShader->muGlowTopPlane.Set(mGlowTopPlane.vec);
activeShader->muGlowBottomPlane.Set(mGlowBottomPlane.vec);
activeShader->currentglowstate = 1;
}
else if (activeShader->currentglowstate)
{
// if glowing is on, disable it.
activeShader->muGlowTopColor.Set(nulvec);
activeShader->muGlowBottomColor.Set(nulvec);
activeShader->currentglowstate = 0;
activeShader->muGlowTopColor.Set(&mStreamData.uGlowTopColor.X);
activeShader->muGlowBottomColor.Set(&mStreamData.uGlowBottomColor.X);
activeShader->muGlowTopPlane.Set(&mStreamData.uGlowTopPlane.X);
activeShader->muGlowBottomPlane.Set(&mStreamData.uGlowBottomPlane.X);
activeShader->currentglowstate = mGlowEnabled;
}
if (mGradientEnabled)
if (mGradientEnabled || activeShader->currentgradientstate)
{
activeShader->muObjectColor2.Set(mObjectColor2);
activeShader->muGradientTopPlane.Set(mGradientTopPlane.vec);
activeShader->muGradientBottomPlane.Set(mGradientBottomPlane.vec);
activeShader->currentgradientstate = 1;
}
else if (activeShader->currentgradientstate)
{
activeShader->muObjectColor2.Set(0);
activeShader->currentgradientstate = 0;
activeShader->muObjectColor2.Set(mStreamData.uObjectColor2);
activeShader->muGradientTopPlane.Set(&mStreamData.uGradientTopPlane.X);
activeShader->muGradientBottomPlane.Set(&mStreamData.uGradientBottomPlane.X);
activeShader->currentgradientstate = mGradientEnabled;
}
if (mSplitEnabled)
if (mSplitEnabled || activeShader->currentsplitstate)
{
activeShader->muSplitTopPlane.Set(mSplitTopPlane.vec);
activeShader->muSplitBottomPlane.Set(mSplitBottomPlane.vec);
activeShader->currentsplitstate = 1;
}
else if (activeShader->currentsplitstate)
{
activeShader->muSplitTopPlane.Set(nulvec);
activeShader->muSplitBottomPlane.Set(nulvec);
activeShader->currentsplitstate = 0;
activeShader->muSplitTopPlane.Set(&mStreamData.uSplitTopPlane.X);
activeShader->muSplitBottomPlane.Set(&mStreamData.uSplitBottomPlane.X);
activeShader->currentsplitstate = mSplitEnabled;
}
if (mTextureMatrixEnabled)

View file

@ -205,7 +205,7 @@ public:
class FBufferedUniformPE
{
PalEntry mBuffer;
FVector4PalEntry mBuffer;
int mIndex;
public:
@ -215,12 +215,12 @@ public:
mBuffer = 0;
}
void Set(PalEntry newvalue)
void Set(const FVector4PalEntry &newvalue)
{
if (newvalue != mBuffer)
{
mBuffer = newvalue;
glUniform4f(mIndex, newvalue.r/255.f, newvalue.g/255.f, newvalue.b/255.f, newvalue.a/255.f);
glUniform4f(mIndex, newvalue.r, newvalue.g, newvalue.b, newvalue.a);
}
}
};

View file

@ -127,6 +127,57 @@ enum EPassType
MAX_PASS_TYPES
};
struct FVector4PalEntry
{
float r, g, b, a;
bool operator==(const FVector4PalEntry &other) const
{
return r == other.r && g == other.g && b == other.b && a == other.a;
}
bool operator!=(const FVector4PalEntry &other) const
{
return r != other.r || g != other.g || b != other.b || a != other.a;
}
FVector4PalEntry &operator=(PalEntry newvalue)
{
const float normScale = 1.0f / 255.0f;
r = newvalue.r * normScale;
g = newvalue.g * normScale;
b = newvalue.b * normScale;
a = newvalue.a * normScale;
return *this;
}
};
struct StreamData
{
FVector4PalEntry uObjectColor;
FVector4PalEntry uObjectColor2;
FVector4 uDynLightColor;
FVector4PalEntry uAddColor;
FVector4PalEntry uFogColor;
float uDesaturationFactor;
float uInterpolationFactor;
float timer;
int useVertexData;
FVector4 uVertexColor;
FVector4 uVertexNormal;
FVector4 uGlowTopPlane;
FVector4 uGlowTopColor;
FVector4 uGlowBottomPlane;
FVector4 uGlowBottomColor;
FVector4 uGradientTopPlane;
FVector4 uGradientBottomPlane;
FVector4 uSplitTopPlane;
FVector4 uSplitBottomPlane;
};
class FRenderState
{
protected:
@ -142,25 +193,15 @@ protected:
int mLightIndex;
int mSpecialEffect;
int mTextureMode;
int mDesaturation;
int mSoftLight;
float mLightParms[4];
float mAlphaThreshold;
float mClipSplit[2];
float mInterpolationFactor;
FStateVec4 mNormal;
FStateVec4 mColor;
FStateVec4 mGlowTop, mGlowBottom;
FStateVec4 mGlowTopPlane, mGlowBottomPlane;
FStateVec4 mGradientTopPlane, mGradientBottomPlane;
FStateVec4 mSplitTopPlane, mSplitBottomPlane;
PalEntry mAddColor;
StreamData mStreamData = {};
PalEntry mFogColor;
PalEntry mObjectColor;
PalEntry mObjectColor2;
FStateVec4 mDynColor;
FRenderStyle mRenderStyle;
FMaterialState mMaterial;
@ -184,22 +225,23 @@ public:
{
mTextureEnabled = true;
mGradientEnabled = mBrightmapEnabled = mFogEnabled = mGlowEnabled = false;
mFogColor.d = -1;
mFogColor = 0xffffffff;
mStreamData.uFogColor = mFogColor;
mTextureMode = -1;
mDesaturation = 0;
mStreamData.uDesaturationFactor = 0.0f;
mAlphaThreshold = 0.5f;
mModelMatrixEnabled = false;
mTextureMatrixEnabled = false;
mSplitEnabled = false;
mAddColor = 0;
mObjectColor = 0xffffffff;
mObjectColor2 = 0;
mStreamData.uAddColor = 0;
mStreamData.uObjectColor = 0xffffffff;
mStreamData.uObjectColor2 = 0;
mSoftLight = 0;
mLightParms[0] = mLightParms[1] = mLightParms[2] = 0.0f;
mLightParms[3] = -1.f;
mSpecialEffect = EFF_NONE;
mLightIndex = -1;
mInterpolationFactor = 0;
mStreamData.uInterpolationFactor = 0;
mRenderStyle = DefaultRenderStyle();
mMaterial.Reset();
mBias.Reset();
@ -209,16 +251,16 @@ public:
mVertexOffsets[0] = mVertexOffsets[1] = 0;
mIndexBuffer = nullptr;
mColor.Set(1.0f, 1.0f, 1.0f, 1.0f);
mGlowTop.Set(0.0f, 0.0f, 0.0f, 0.0f);
mGlowBottom.Set(0.0f, 0.0f, 0.0f, 0.0f);
mGlowTopPlane.Set(0.0f, 0.0f, 0.0f, 0.0f);
mGlowBottomPlane.Set(0.0f, 0.0f, 0.0f, 0.0f);
mGradientTopPlane.Set(0.0f, 0.0f, 0.0f, 0.0f);
mGradientBottomPlane.Set(0.0f, 0.0f, 0.0f, 0.0f);
mSplitTopPlane.Set(0.0f, 0.0f, 0.0f, 0.0f);
mSplitBottomPlane.Set(0.0f, 0.0f, 0.0f, 0.0f);
mDynColor.Set(0.0f, 0.0f, 0.0f, 0.0f);
mStreamData.uVertexColor = { 1.0f, 1.0f, 1.0f, 1.0f };
mStreamData.uGlowTopColor = { 0.0f, 0.0f, 0.0f, 0.0f };
mStreamData.uGlowBottomColor = { 0.0f, 0.0f, 0.0f, 0.0f };
mStreamData.uGlowTopPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
mStreamData.uGlowBottomPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
mStreamData.uGradientTopPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
mStreamData.uGradientBottomPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
mStreamData.uSplitTopPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
mStreamData.uSplitBottomPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
mStreamData.uDynLightColor = { 0.0f, 0.0f, 0.0f, 0.0f };
mModelMatrix.loadIdentity();
mTextureMatrix.loadIdentity();
@ -227,36 +269,38 @@ public:
void SetNormal(FVector3 norm)
{
mNormal.Set(norm.X, norm.Y, norm.Z, 0.f);
mStreamData.uVertexNormal = { norm.X, norm.Y, norm.Z, 0.f };
}
void SetNormal(float x, float y, float z)
{
mNormal.Set(x, y, z, 0.f);
mStreamData.uVertexNormal = { x, y, z, 0.f };
}
void SetColor(float r, float g, float b, float a = 1.f, int desat = 0)
{
mColor.Set(r, g, b, a);
mDesaturation = desat;
mStreamData.uVertexColor = { r, g, b, a };
mStreamData.uDesaturationFactor = desat * (1.0f / 255.0f);
}
void SetColor(PalEntry pe, int desat = 0)
{
mColor.Set(pe.r / 255.f, pe.g / 255.f, pe.b / 255.f, pe.a / 255.f);
mDesaturation = desat;
const float scale = 1.0f / 255.0f;
mStreamData.uVertexColor = { pe.r * scale, pe.g * scale, pe.b * scale, pe.a * scale };
mStreamData.uDesaturationFactor = desat * (1.0f / 255.0f);
}
void SetColorAlpha(PalEntry pe, float alpha = 1.f, int desat = 0)
{
mColor.Set(pe.r / 255.f, pe.g / 255.f, pe.b / 255.f, alpha);
mDesaturation = desat;
const float scale = 1.0f / 255.0f;
mStreamData.uVertexColor = { pe.r * scale, pe.g * scale, pe.b * scale, alpha };
mStreamData.uDesaturationFactor = desat * (1.0f / 255.0f);
}
void ResetColor()
{
mColor.Set(1, 1, 1, 1);
mDesaturation = 0;
mStreamData.uVertexColor = { 1.0f, 1.0f, 1.0f, 1.0f };
mStreamData.uDesaturationFactor = 0.0f;
}
void SetTextureMode(int mode)
@ -302,6 +346,11 @@ public:
void EnableGlow(bool on)
{
if (mGlowEnabled && !on)
{
mStreamData.uGlowTopColor = { 0.0f, 0.0f, 0.0f, 0.0f };
mStreamData.uGlowBottomColor = { 0.0f, 0.0f, 0.0f, 0.0f };
}
mGlowEnabled = on;
}
@ -317,6 +366,11 @@ public:
void EnableSplit(bool on)
{
if (mSplitEnabled && !on)
{
mStreamData.uSplitTopPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
mStreamData.uSplitBottomPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
}
mSplitEnabled = on;
}
@ -332,8 +386,8 @@ public:
void SetGlowParams(float *t, float *b)
{
mGlowTop.Set(t[0], t[1], t[2], t[3]);
mGlowBottom.Set(b[0], b[1], b[2], b[3]);
mStreamData.uGlowTopColor = { t[0], t[1], t[2], t[3] };
mStreamData.uGlowBottomColor = { b[0], b[1], b[2], b[3] };
}
void SetSoftLightLevel(int llevel, int blendfactor = 0)
@ -351,50 +405,51 @@ public:
{
auto &tn = top.Normal();
auto &bn = bottom.Normal();
mGlowTopPlane.Set((float)tn.X, (float)tn.Y, (float)top.negiC, (float)top.fD());
mGlowBottomPlane.Set((float)bn.X, (float)bn.Y, (float)bottom.negiC, (float)bottom.fD());
mStreamData.uGlowTopPlane = { (float)tn.X, (float)tn.Y, (float)top.negiC, (float)top.fD() };
mStreamData.uGlowBottomPlane = { (float)bn.X, (float)bn.Y, (float)bottom.negiC, (float)bottom.fD() };
}
void SetGradientPlanes(const secplane_t &top, const secplane_t &bottom)
{
auto &tn = top.Normal();
auto &bn = bottom.Normal();
mGradientTopPlane.Set((float)tn.X, (float)tn.Y, (float)top.negiC, (float)top.fD());
mGradientBottomPlane.Set((float)bn.X, (float)bn.Y, (float)bottom.negiC, (float)bottom.fD());
mStreamData.uGradientTopPlane = { (float)tn.X, (float)tn.Y, (float)top.negiC, (float)top.fD() };
mStreamData.uGradientBottomPlane = { (float)bn.X, (float)bn.Y, (float)bottom.negiC, (float)bottom.fD() };
}
void SetSplitPlanes(const secplane_t &top, const secplane_t &bottom)
{
auto &tn = top.Normal();
auto &bn = bottom.Normal();
mSplitTopPlane.Set((float)tn.X, (float)tn.Y, (float)top.negiC, (float)top.fD());
mSplitBottomPlane.Set((float)bn.X, (float)bn.Y, (float)bottom.negiC, (float)bottom.fD());
mStreamData.uSplitTopPlane = { (float)tn.X, (float)tn.Y, (float)top.negiC, (float)top.fD() };
mStreamData.uSplitBottomPlane = { (float)bn.X, (float)bn.Y, (float)bottom.negiC, (float)bottom.fD() };
}
void SetDynLight(float r, float g, float b)
{
mDynColor.Set(r, g, b, 0);
mStreamData.uDynLightColor = { r, g, b, 0.0f };
}
void SetObjectColor(PalEntry pe)
{
mObjectColor = pe;
mStreamData.uObjectColor = pe;
}
void SetObjectColor2(PalEntry pe)
{
mObjectColor2 = pe;
mStreamData.uObjectColor2 = pe;
}
void SetAddColor(PalEntry pe)
{
mAddColor = pe;
mStreamData.uAddColor = pe;
}
void SetFog(PalEntry c, float d)
{
const float LOG2E = 1.442692f; // = 1/log(2)
mFogColor = c;
mStreamData.uFogColor = mFogColor;
if (d >= 0.0f) mLightParms[2] = d * (-LOG2E / 64000.f);
}
@ -505,12 +560,12 @@ public:
void SetInterpolationFactor(float fac)
{
mInterpolationFactor = fac;
mStreamData.uInterpolationFactor = fac;
}
float GetInterpolationFactor()
{
return mInterpolationFactor;
return mStreamData.uInterpolationFactor;
}
void EnableDrawBufferAttachments(bool on) // Used by fog boundary drawer

View file

@ -173,7 +173,7 @@ void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags)
PalEntry color1 = side->GetSpecialColor(tierndx, side_t::walltop, frontsector);
PalEntry color2 = side->GetSpecialColor(tierndx, side_t::wallbottom, frontsector);
state.SetObjectColor(color1);
state.SetObjectColor2(color2);
state.SetObjectColor2((color1 != color2) ? color2 : 0);
state.SetAddColor(side->GetAdditiveColor(tierndx, frontsector));
if (color1 != color2)
{

View file

@ -322,65 +322,13 @@ void VkRenderState::ApplyStreamData()
auto fb = GetVulkanFrameBuffer();
auto passManager = fb->GetRenderPassManager();
const float normScale = 1.0f / 255.0f;
mStreamData.uDesaturationFactor = mDesaturation * normScale;
mStreamData.uFogColor = { mFogColor.r * normScale, mFogColor.g * normScale, mFogColor.b * normScale, mFogColor.a * normScale };
mStreamData.uAddColor = { mAddColor.r * normScale, mAddColor.g * normScale, mAddColor.b * normScale, mAddColor.a * normScale };
mStreamData.uObjectColor = { mObjectColor.r * normScale, mObjectColor.g * normScale, mObjectColor.b * normScale, mObjectColor.a * normScale };
mStreamData.uDynLightColor = mDynColor.vec;
mStreamData.uInterpolationFactor = mInterpolationFactor;
mStreamData.useVertexData = passManager->VertexFormats[static_cast<VKVertexBuffer*>(mVertexBuffer)->VertexFormat].UseVertexData;
mStreamData.uVertexColor = mColor.vec;
mStreamData.uVertexNormal = mNormal.vec;
if (mMaterial.mMaterial && mMaterial.mMaterial->tex)
mStreamData.timer = static_cast<float>((double)(screen->FrameTime - firstFrame) * (double)mMaterial.mMaterial->tex->shaderspeed / 1000.);
else
mStreamData.timer = 0.0f;
if (mGlowEnabled)
{
mStreamData.uGlowTopPlane = mGlowTopPlane.vec;
mStreamData.uGlowTopColor = mGlowTop.vec;
mStreamData.uGlowBottomPlane = mGlowBottomPlane.vec;
mStreamData.uGlowBottomColor = mGlowBottom.vec;
mLastGlowEnabled = true;
}
else if (mLastGlowEnabled)
{
mStreamData.uGlowTopColor = { 0.0f, 0.0f, 0.0f, 0.0f };
mStreamData.uGlowBottomColor = { 0.0f, 0.0f, 0.0f, 0.0f };
mLastGlowEnabled = false;
}
if (mGradientEnabled)
{
mStreamData.uObjectColor2 = { mObjectColor2.r * normScale, mObjectColor2.g * normScale, mObjectColor2.b * normScale, mObjectColor2.a * normScale };
mStreamData.uGradientTopPlane = mGradientTopPlane.vec;
mStreamData.uGradientBottomPlane = mGradientBottomPlane.vec;
mLastGradientEnabled = true;
}
else if (mLastGradientEnabled)
{
mStreamData.uObjectColor2 = { 0.0f, 0.0f, 0.0f, 0.0f };
mLastGradientEnabled = false;
}
if (mSplitEnabled)
{
mStreamData.uSplitTopPlane = mSplitTopPlane.vec;
mStreamData.uSplitBottomPlane = mSplitBottomPlane.vec;
mLastSplitEnabled = true;
}
else if (mLastSplitEnabled)
{
mStreamData.uSplitTopPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
mStreamData.uSplitBottomPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
mLastSplitEnabled = false;
}
mDataIndex++;
if (mDataIndex == MAX_STREAM_DATA)
{
@ -400,7 +348,7 @@ void VkRenderState::ApplyPushConstants()
{
fogset = -3; // 2D rendering with 'foggy' overlay.
}
else if ((mFogColor & 0xffffff) == 0)
else if ((GetFogColor() & 0xffffff) == 0)
{
fogset = gl_fogmode;
}
@ -573,9 +521,6 @@ void VkRenderState::EndRenderPass()
mLastLightBufferOffset = 0xffffffff;
mLastVertexBuffer = nullptr;
mLastIndexBuffer = nullptr;
mLastGlowEnabled = true;
mLastGradientEnabled = true;
mLastSplitEnabled = true;
mLastModelMatrixEnabled = true;
mLastTextureMatrixEnabled = true;
}

View file

@ -88,7 +88,6 @@ protected:
int mCullMode = 0;
MatricesUBO mMatrices = {};
StreamData mStreamData = {};
PushConstants mPushConstants = {};
uint32_t mLastViewpointOffset = 0xffffffff;
@ -107,9 +106,6 @@ protected:
IVertexBuffer *mLastVertexBuffer = nullptr;
IIndexBuffer *mLastIndexBuffer = nullptr;
bool mLastGlowEnabled = true;
bool mLastGradientEnabled = true;
bool mLastSplitEnabled = true;
bool mLastModelMatrixEnabled = true;
bool mLastTextureMatrixEnabled = true;

View file

@ -18,32 +18,6 @@ struct MatricesUBO
VSMatrix TextureMatrix;
};
struct StreamData
{
FVector4 uObjectColor;
FVector4 uObjectColor2;
FVector4 uDynLightColor;
FVector4 uAddColor;
FVector4 uFogColor;
float uDesaturationFactor;
float uInterpolationFactor;
float timer;
int useVertexData;
FVector4 uVertexColor;
FVector4 uVertexNormal;
FVector4 uGlowTopPlane;
FVector4 uGlowTopColor;
FVector4 uGlowBottomPlane;
FVector4 uGlowBottomColor;
FVector4 uGradientTopPlane;
FVector4 uGradientBottomPlane;
FVector4 uSplitTopPlane;
FVector4 uSplitBottomPlane;
};
#define MAX_STREAM_DATA 256
struct StreamUBO