Use uniform declarations in HWRenderState to automatically build:

- uniform change tracking (OpenGL: FBufferedUniform*)
- uniform block and push constants structs (Vulkan)
- GLSL for uniforms (OpenGL)
- structs and variable redirection defines (Vulkan)

Also adds support for easily moving an uniform to or from push constants by changing its uniform family.
This commit is contained in:
Magnus Norddahl 2019-12-21 22:13:45 +01:00
parent 738b9ceb08
commit 078f2e9e82
21 changed files with 608 additions and 515 deletions

View file

@ -99,7 +99,7 @@ bool FGLRenderState::ApplyShader()
}
else
{
activeShader = GLRenderer->mShaderManager->Get(mTextureEnabled ? mEffectState : SHADER_NoTexture, mAlphaThreshold >= 0.f, mPassType);
activeShader = GLRenderer->mShaderManager->Get(mTextureEnabled ? mEffectState : SHADER_NoTexture, GetUniform<float>(UniformName::uAlphaThreshold) >= 0.f, mPassType);
activeShader->Bind();
}
@ -121,50 +121,13 @@ bool FGLRenderState::ApplyShader()
}
}
glVertexAttrib4fv(VATTR_COLOR, &mStreamData.uVertexColor.X);
glVertexAttrib4fv(VATTR_NORMAL, &mStreamData.uVertexNormal.X);
glVertexAttrib4fv(VATTR_COLOR, (const float*)GetUniformData(UniformName::uVertexColor));
glVertexAttrib4fv(VATTR_NORMAL, (const float*)GetUniformData(UniformName::uVertexNormal));
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(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(mStreamData.uAddColor);
activeShader->muTextureAddColor.Set(mStreamData.uTextureAddColor);
activeShader->muTextureModulateColor.Set(mStreamData.uTextureModulateColor);
activeShader->muTextureBlendColor.Set(mStreamData.uTextureBlendColor);
if (mGlowEnabled || activeShader->currentglowstate)
{
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 || activeShader->currentgradientstate)
{
activeShader->muObjectColor2.Set(mStreamData.uObjectColor2);
activeShader->muGradientTopPlane.Set(&mStreamData.uGradientTopPlane.X);
activeShader->muGradientBottomPlane.Set(&mStreamData.uGradientBottomPlane.X);
activeShader->currentgradientstate = mGradientEnabled;
}
if (mSplitEnabled || activeShader->currentsplitstate)
{
activeShader->muSplitTopPlane.Set(&mStreamData.uSplitTopPlane.X);
activeShader->muSplitBottomPlane.Set(&mStreamData.uSplitBottomPlane.X);
activeShader->currentsplitstate = mSplitEnabled;
}
SetUniform(UniformName::uFogEnabled, fogset);
SetUniform(UniformName::uTextureMode, mTextureMode == TM_NORMAL && mTempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode);
SetUniform(UniformName::timer, (double)(screen->FrameTime - firstFrame) * (double)mShaderTimer / 1000.);
SetUniform(UniformName::uSpecularMaterial, FVector2{ mGlossiness, mSpecularLevel });
if (mTextureMatrixEnabled)
{
@ -192,7 +155,7 @@ bool FGLRenderState::ApplyShader()
matrixToGL(identityMatrix, activeShader->normalmodelmatrix_index);
}
int index = mLightIndex;
int index = GetUniform<int>(UniformName::uLightIndex);
// Mess alert for crappy AncientGL!
if (!screen->mLights->GetBufferType() && index >= 0)
{
@ -205,8 +168,41 @@ bool FGLRenderState::ApplyShader()
static_cast<GLDataBuffer*>(screen->mLights->GetBuffer())->BindRange(nullptr, start, size);
}
}
SetUniform(UniformName::uLightIndex, index);
// Apply uniforms:
GLuint* locations = activeShader->UniformLocations.data();
int* lastupdates = activeShader->UniformLastUpdates.data();
int count = (int)mUniformInfo.size();
for (int i = 0; i < count; i++)
{
if (lastupdates[i] != mUniformInfo.data()[i].LastUpdate)
{
const void* data = GetUniformData((UniformName)i);
GLuint location = locations[i];
switch (mUniformInfo[i].Type)
{
default:
case UniformType::Vec4: glUniform4fv(location, 1, (float*)data); break;
case UniformType::Float: glUniform1fv(location, 1, (float*)data); break;
case UniformType::Int: glUniform1iv(location, 1, (int*)data); break;
case UniformType::Mat4: glUniformMatrix4fv(location, 1, GL_FALSE, (float*)data); break;
case UniformType::UInt: glUniform1iv(location, 1, (int*)data); break;
case UniformType::Vec2: glUniform2fv(location, 1, (float*)data); break;
case UniformType::Vec3: glUniform3fv(location, 1, (float*)data); break;
case UniformType::IVec2: glUniform1iv(location, 1, (int*)data); break;
case UniformType::IVec3: glUniform1iv(location, 1, (int*)data); break;
case UniformType::IVec4: glUniform1iv(location, 1, (int*)data); break;
case UniformType::UVec2: glUniform1iv(location, 1, (int*)data); break;
case UniformType::UVec3: glUniform1iv(location, 1, (int*)data); break;
case UniformType::UVec4: glUniform1iv(location, 1, (int*)data); break;
}
lastupdates[i] = mUniformInfo[i].LastUpdate;
}
}
activeShader->muLightIndex.Set(index);
return true;
}

View file

@ -232,49 +232,19 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
int uShadowmapFilter;
};
)";
i_data += "uniform int uTextureMode;\n";
i_data += "uniform vec2 uClipSplit;\n";
i_data += "uniform float uAlphaThreshold;\n";
// colors
i_data += "uniform vec4 uObjectColor;\n";
i_data += "uniform vec4 uObjectColor2;\n";
i_data += "uniform vec4 uDynLightColor;\n";
i_data += "uniform vec4 uAddColor;\n";
i_data += "uniform vec4 uTextureBlendColor;\n";
i_data += "uniform vec4 uTextureModulateColor;\n";
i_data += "uniform vec4 uTextureAddColor;\n";
i_data += "uniform vec4 uBlendColor;\n";
i_data += "uniform vec4 uFogColor;\n";
i_data += "uniform float uDesaturationFactor;\n";
i_data += "uniform float uInterpolationFactor;\n";
// Generate uniform declarations:
// Glowing walls stuff
i_data += "uniform vec4 uGlowTopPlane;\n";
i_data += "uniform vec4 uGlowTopColor;\n";
i_data += "uniform vec4 uGlowBottomPlane;\n";
i_data += "uniform vec4 uGlowBottomColor;\n";
int index = 0;
for (const auto& info : gl_RenderState.GetUniformInfo())
{
if (info.Name.empty())
I_FatalError("Missing uniform declaration for index %d", index);
index++;
i_data += "uniform vec4 uGradientTopPlane;\n";
i_data += "uniform vec4 uGradientBottomPlane;\n";
i_data += "uniform vec4 uSplitTopPlane;\n";
i_data += "uniform vec4 uSplitBottomPlane;\n";
// Lighting + Fog
i_data += "uniform vec4 uLightAttr;\n";
i_data += "#define uLightLevel uLightAttr.a\n";
i_data += "#define uFogDensity uLightAttr.b\n";
i_data += "#define uLightFactor uLightAttr.g\n";
i_data += "#define uLightDist uLightAttr.r\n";
i_data += "uniform int uFogEnabled;\n";
// dynamic lights
i_data += "uniform int uLightIndex;\n";
// Blinn glossiness and specular level
i_data += "uniform vec2 uSpecularMaterial;\n";
static const char* glsltype[] = { "int", "uint", "float", "vec2", "vec3", "vec4", "ivec2", "ivec3", "ivec4", "uvec2", "uvec3", "uvec4", "mat4" };
i_data.AppendFormat("uniform %s %s;\n", glsltype[(int)info.Type], info.Name.c_str());
}
// matrices
i_data += "uniform mat4 ModelMatrix;\n";
@ -303,9 +273,6 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
i_data += "uniform sampler2D texture5;\n";
i_data += "uniform sampler2D texture6;\n";
// timer data
i_data += "uniform float timer;\n";
// material types
i_data += "#if defined(SPECULAR)\n";
i_data += "#define normaltexture texture2\n";
@ -518,32 +485,16 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
hFragProg = 0;
}
muDesaturation.Init(hShader, "uDesaturationFactor");
muFogEnabled.Init(hShader, "uFogEnabled");
muTextureMode.Init(hShader, "uTextureMode");
muLightParms.Init(hShader, "uLightAttr");
muClipSplit.Init(hShader, "uClipSplit");
muLightIndex.Init(hShader, "uLightIndex");
muFogColor.Init(hShader, "uFogColor");
muDynLightColor.Init(hShader, "uDynLightColor");
muObjectColor.Init(hShader, "uObjectColor");
muObjectColor2.Init(hShader, "uObjectColor2");
muGlowBottomColor.Init(hShader, "uGlowBottomColor");
muGlowTopColor.Init(hShader, "uGlowTopColor");
muGlowBottomPlane.Init(hShader, "uGlowBottomPlane");
muGlowTopPlane.Init(hShader, "uGlowTopPlane");
muGradientBottomPlane.Init(hShader, "uGradientBottomPlane");
muGradientTopPlane.Init(hShader, "uGradientTopPlane");
muSplitBottomPlane.Init(hShader, "uSplitBottomPlane");
muSplitTopPlane.Init(hShader, "uSplitTopPlane");
muInterpolationFactor.Init(hShader, "uInterpolationFactor");
muAlphaThreshold.Init(hShader, "uAlphaThreshold");
muSpecularMaterial.Init(hShader, "uSpecularMaterial");
muAddColor.Init(hShader, "uAddColor");
muTextureAddColor.Init(hShader, "uTextureAddColor");
muTextureModulateColor.Init(hShader, "uTextureModulateColor");
muTextureBlendColor.Init(hShader, "uTextureBlendColor");
muTimer.Init(hShader, "timer");
const auto& uniformInfo = gl_RenderState.GetUniformInfo();
UniformLastUpdates.resize(uniformInfo.size());
UniformLocations.resize(uniformInfo.size(), (GLuint)-1);
int count = (int)uniformInfo.size();
for (int i = 0; i < count; i++)
{
const auto& name = uniformInfo[i].Name;
if (!name.empty())
UniformLocations[i] = glGetUniformLocation(hShader, name.c_str());
}
lights_index = glGetUniformLocation(hShader, "lights");
modelmatrix_index = glGetUniformLocation(hShader, "ModelMatrix");

View file

@ -235,41 +235,14 @@ class FShader
unsigned int hFragProg;
FName mName;
FBufferedUniform1f muDesaturation;
FBufferedUniform1i muFogEnabled;
FBufferedUniform1i muTextureMode;
FBufferedUniform4f muLightParms;
FBufferedUniform2f muClipSplit;
FBufferedUniform1i muLightIndex;
FBufferedUniformPE muFogColor;
FBufferedUniform4f muDynLightColor;
FBufferedUniformPE muObjectColor;
FBufferedUniformPE muObjectColor2;
FBufferedUniformPE muAddColor;
FBufferedUniformPE muTextureBlendColor;
FBufferedUniformPE muTextureModulateColor;
FBufferedUniformPE muTextureAddColor;
FUniform4f muGlowBottomColor;
FUniform4f muGlowTopColor;
FUniform4f muGlowBottomPlane;
FUniform4f muGlowTopPlane;
FUniform4f muGradientBottomPlane;
FUniform4f muGradientTopPlane;
FUniform4f muSplitBottomPlane;
FUniform4f muSplitTopPlane;
FBufferedUniform1f muInterpolationFactor;
FBufferedUniform1f muAlphaThreshold;
FBufferedUniform2f muSpecularMaterial;
FBufferedUniform1f muTimer;
std::vector<int> UniformLastUpdates;
std::vector<GLuint> UniformLocations;
int lights_index;
int modelmatrix_index;
int normalmodelmatrix_index;
int texturematrix_index;
int currentglowstate = 0;
int currentgradientstate = 0;
int currentsplitstate = 0;
int currentcliplinestate = 0;
int currentfixedcolormap = 0;
bool currentTextureMatrixState = true;// by setting the matrix state to 'true' it is guaranteed to be set the first time the render state gets applied.

View file

@ -7,6 +7,7 @@
#include "hw_drawlist.h"
#include "matrix.h"
#include "hwrenderer/textures/hw_material.h"
#include "hwrenderer/data/shaderuniforms.h"
struct FColormap;
class IVertexBuffer;
@ -172,38 +173,217 @@ struct FVector4PalEntry
};
struct StreamData
enum class UniformName
{
FVector4PalEntry uObjectColor;
FVector4PalEntry uObjectColor2;
FVector4 uDynLightColor;
FVector4PalEntry uAddColor;
FVector4PalEntry uTextureAddColor;
FVector4PalEntry uTextureModulateColor;
FVector4PalEntry uTextureBlendColor;
FVector4PalEntry uFogColor;
float uDesaturationFactor;
float uInterpolationFactor;
float timer;
int useVertexData;
FVector4 uVertexColor;
FVector4 uVertexNormal;
uObjectColor,
uObjectColor2,
uDynLightColor,
uAddColor,
uTextureAddColor,
uTextureModulateColor,
uTextureBlendColor,
uFogColor,
uDesaturationFactor,
uInterpolationFactor,
timer,
useVertexData,
uVertexColor,
uVertexNormal,
FVector4 uGlowTopPlane;
FVector4 uGlowTopColor;
FVector4 uGlowBottomPlane;
FVector4 uGlowBottomColor;
uGlowTopPlane,
uGlowTopColor,
uGlowBottomPlane,
uGlowBottomColor,
FVector4 uGradientTopPlane;
FVector4 uGradientBottomPlane;
uGradientTopPlane,
uGradientBottomPlane,
FVector4 uSplitTopPlane;
FVector4 uSplitBottomPlane;
uSplitTopPlane,
uSplitBottomPlane,
uObjectBlendMode,
uObjectDesaturationFactor,
uObjectColorizeFactor,
uObjectInvertColor,
uTextureMode,
uAlphaThreshold,
uClipSplit,
uLightLevel,
uFogDensity,
uLightFactor,
uLightDist,
uFogEnabled,
uLightIndex,
uSpecularMaterial,
uDataIndex,
uPadding1,
uPadding2,
uPadding3
};
enum class UniformFamily
{
Normal,
//Matrix,
PushConstant,
NumFamilies
};
class FRenderState
{
protected:
FRenderState()
{
// Important: the following declarations must be compatible with the GLSL std140 layout rules.
// DeclareUniform does not automatically insert padding to enforce this.
DeclareUniform(UniformName::uObjectColor, "uObjectColor", UniformType::Vec4);
DeclareUniform(UniformName::uObjectColor2, "uObjectColor2", UniformType::Vec4);
DeclareUniform(UniformName::uDynLightColor, "uDynLightColor", UniformType::Vec4);
DeclareUniform(UniformName::uAddColor, "uAddColor", UniformType::Vec4);
DeclareUniform(UniformName::uTextureAddColor, "uTextureAddColor", UniformType::Vec4);
DeclareUniform(UniformName::uTextureModulateColor, "uTextureModulateColor", UniformType::Vec4);
DeclareUniform(UniformName::uTextureBlendColor, "uTextureBlendColor", UniformType::Vec4);
DeclareUniform(UniformName::uFogColor, "uFogColor", UniformType::Vec4);
DeclareUniform(UniformName::uDesaturationFactor, "uDesaturationFactor", UniformType::Float);
DeclareUniform(UniformName::uInterpolationFactor, "uInterpolationFactor", UniformType::Float);
DeclareUniform(UniformName::timer, "timer", UniformType::Float);
DeclareUniform(UniformName::useVertexData, "useVertexData", UniformType::Int);
DeclareUniform(UniformName::uVertexColor, "uVertexColor", UniformType::Vec4);
DeclareUniform(UniformName::uVertexNormal, "uVertexNormal", UniformType::Vec4);
DeclareUniform(UniformName::uGlowTopPlane, "uGlowTopPlane", UniformType::Vec4);
DeclareUniform(UniformName::uGlowTopColor, "uGlowTopColor", UniformType::Vec4);
DeclareUniform(UniformName::uGlowBottomPlane, "uGlowBottomPlane", UniformType::Vec4);
DeclareUniform(UniformName::uGlowBottomColor, "uGlowBottomColor", UniformType::Vec4);
DeclareUniform(UniformName::uGradientTopPlane, "uGradientTopPlane", UniformType::Vec4);
DeclareUniform(UniformName::uGradientBottomPlane, "uGradientBottomPlane", UniformType::Vec4);
DeclareUniform(UniformName::uSplitTopPlane, "uSplitTopPlane", UniformType::Vec4);
DeclareUniform(UniformName::uSplitBottomPlane, "uSplitBottomPlane", UniformType::Vec4);
DeclareUniform(UniformName::uObjectBlendMode, "uObjectBlendMode", UniformType::Float);
DeclareUniform(UniformName::uObjectInvertColor, "uObjectInvertColor", UniformType::Float);
DeclareUniform(UniformName::uObjectDesaturationFactor, "uObjectDesaturationFactor", UniformType::Float);
DeclareUniform(UniformName::uObjectColorizeFactor, "uObjectColorizeFactor", UniformType::Float);
DeclareUniform(UniformName::uTextureMode, "uTextureMode", UniformType::Int, UniformFamily::PushConstant);
DeclareUniform(UniformName::uAlphaThreshold, "uAlphaThreshold", UniformType::Float, UniformFamily::PushConstant);
DeclareUniform(UniformName::uClipSplit, "uClipSplit", UniformType::Vec2, UniformFamily::PushConstant);
DeclareUniform(UniformName::uLightLevel, "uLightLevel", UniformType::Float, UniformFamily::PushConstant);
DeclareUniform(UniformName::uFogDensity, "uFogDensity", UniformType::Float, UniformFamily::PushConstant);
DeclareUniform(UniformName::uLightFactor, "uLightFactor", UniformType::Float, UniformFamily::PushConstant);
DeclareUniform(UniformName::uLightDist, "uLightDist", UniformType::Float, UniformFamily::PushConstant);
DeclareUniform(UniformName::uFogEnabled, "uFogEnabled", UniformType::Int, UniformFamily::PushConstant);
DeclareUniform(UniformName::uLightIndex, "uLightIndex", UniformType::Int, UniformFamily::PushConstant);
DeclareUniform(UniformName::uSpecularMaterial, "uSpecularMaterial", UniformType::Vec2, UniformFamily::PushConstant);
DeclareUniform(UniformName::uDataIndex, "uDataIndex", UniformType::Int, UniformFamily::PushConstant);
DeclareUniform(UniformName::uPadding1, "uPadding1", UniformType::Int, UniformFamily::PushConstant);
DeclareUniform(UniformName::uPadding2, "uPadding2", UniformType::Int, UniformFamily::PushConstant);
DeclareUniform(UniformName::uPadding3, "uPadding3", UniformType::Int, UniformFamily::PushConstant);
}
void DeclareUniform(UniformName nameIndex, const char* glslname, UniformType type, UniformFamily family = UniformFamily::Normal)
{
size_t index = (size_t)nameIndex;
if (mUniformInfo.size() <= index)
mUniformInfo.resize(index + 1);
auto& data = mUniformData[(int)family];
UniformInfo& info = mUniformInfo[index];
info.Name = glslname;
info.Type = type;
info.Family = family;
info.Offset = (int)data.size();
static const int bytesize[] = { 4, 4, 4, 8, 12, 16, 8, 12, 16, 8, 12, 16, 16 };
data.resize(data.size() + bytesize[(int)type]);
}
void SetUniform(UniformName nameIndex, const PalEntry& value)
{
SetUniform(nameIndex, FVector4(value.r * (1.0f / 255.0f), value.g * (1.0f / 255.0f), value.b * (1.0f / 255.0f), value.a * (1.0f / 255.0f)));
}
void SetUniform(UniformName nameIndex, double value)
{
SetUniform(nameIndex, (float)value);
}
void SetUniform(UniformName nameIndex, const DVector2& value)
{
SetUniform(nameIndex, FVector2((float)value.X, (float)value.Y));
}
void SetUniform(UniformName nameIndex, const DVector3& value)
{
SetUniform(nameIndex, FVector3((float)value.X, (float)value.Y, (float)value.Z));
}
void SetUniform(UniformName nameIndex, const DVector4& value)
{
SetUniform(nameIndex, FVector4((float)value.X, (float)value.Y, (float)value.Z, (float)value.W));
}
template<typename T>
void SetUniform(UniformName nameIndex, const T& value)
{
T* dest = (T*)GetUniformData(nameIndex);
if (*dest != value)
{
*dest = value;
mUniformInfo[(int)nameIndex].LastUpdate++;
}
}
void SetUniformAlpha(UniformName nameIndex, float alpha)
{
float* dest = (float*)GetUniformData(nameIndex);
if (dest[3] != alpha)
{
dest[3] = alpha;
mUniformInfo[(int)nameIndex].LastUpdate++;
}
}
void SetUniformIntegerAlpha(UniformName nameIndex, const PalEntry& value)
{
SetUniform(nameIndex, FVector4(value.r * (1.0f / 255.0f), value.g * (1.0f / 255.0f), value.b * (1.0f / 255.0f), (float)value.a));
}
template<typename T>
T GetUniform(UniformName nameIndex)
{
return *(T*)GetUniformData(nameIndex);
}
void* GetUniformData(UniformName nameIndex)
{
const auto& info = mUniformInfo[(int)nameIndex];
return mUniformData[(int)info.Family].data() + info.Offset;
}
struct UniformInfo
{
std::string Name;
UniformType Type = {};
UniformFamily Family = {};
int Offset = 0;
int LastUpdate = 0;
};
std::vector<UniformInfo> mUniformInfo;
std::vector<uint8_t> mUniformData[(int)UniformFamily::NumFamilies];
uint8_t mFogEnabled;
uint8_t mTextureEnabled:1;
uint8_t mGlowEnabled : 1;
@ -213,16 +393,10 @@ protected:
uint8_t mTextureMatrixEnabled : 1;
uint8_t mSplitEnabled : 1;
int mLightIndex;
int mSpecialEffect;
int mTextureMode;
int mSoftLight;
float mLightParms[4];
float mAlphaThreshold;
float mClipSplit[2];
StreamData mStreamData = {};
PalEntry mFogColor;
FRenderStyle mRenderStyle;
@ -243,31 +417,36 @@ public:
VSMatrix mTextureMatrix;
public:
const std::vector<UniformInfo>& GetUniformInfo() const { return mUniformInfo; }
const void* GetUniformData(UniformFamily family) const { return mUniformData[(int)family].data(); }
uint32_t GetUniformDataSize(UniformFamily family) const { return (uint32_t)mUniformData[(int)family].size(); }
void Reset()
{
mTextureEnabled = true;
mGradientEnabled = mBrightmapEnabled = mFogEnabled = mGlowEnabled = false;
mFogColor = 0xffffffff;
mStreamData.uFogColor = mFogColor;
SetUniform(UniformName::uFogColor, mFogColor);
mTextureMode = -1;
mStreamData.uDesaturationFactor = 0.0f;
mAlphaThreshold = 0.5f;
SetUniform(UniformName::uDesaturationFactor, 0.0f);
SetUniform(UniformName::uAlphaThreshold, 0.5f);
mModelMatrixEnabled = false;
mTextureMatrixEnabled = false;
mSplitEnabled = false;
mStreamData.uAddColor = 0;
mStreamData.uObjectColor = 0xffffffff;
mStreamData.uObjectColor2 = 0;
mStreamData.uTextureBlendColor = 0;
mStreamData.uTextureAddColor = 0;
mStreamData.uTextureModulateColor = 0;
SetUniform(UniformName::uAddColor, 0);
SetUniform(UniformName::uObjectColor, 0xffffffff);
SetUniform(UniformName::uObjectColor2, 0);
SetUniform(UniformName::uTextureBlendColor, 0);
SetUniform(UniformName::uTextureAddColor, 0);
SetUniform(UniformName::uTextureModulateColor, 0);
mSoftLight = 0;
mLightParms[0] = mLightParms[1] = mLightParms[2] = 0.0f;
mLightParms[3] = -1.f;
SetUniform(UniformName::uLightDist, 0.0f);
SetUniform(UniformName::uLightFactor, 0.0f);
SetUniform(UniformName::uFogDensity, 0.0f);
SetUniform(UniformName::uLightLevel, -1.f);
mSpecialEffect = EFF_NONE;
mLightIndex = -1;
mStreamData.uInterpolationFactor = 0;
SetUniform(UniformName::uLightIndex, -1);
SetUniform(UniformName::uInterpolationFactor, 0);
mRenderStyle = DefaultRenderStyle();
mMaterial.Reset();
mBias.Reset();
@ -277,16 +456,16 @@ public:
mVertexOffsets[0] = mVertexOffsets[1] = 0;
mIndexBuffer = nullptr;
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 };
SetUniform(UniformName::uVertexColor, FVector4{ 1.0f, 1.0f, 1.0f, 1.0f });
SetUniform(UniformName::uGlowTopColor, FVector4{ 0.0f, 0.0f, 0.0f, 0.0f });
SetUniform(UniformName::uGlowBottomColor, FVector4{ 0.0f, 0.0f, 0.0f, 0.0f });
SetUniform(UniformName::uGlowTopPlane, FVector4{ 0.0f, 0.0f, 0.0f, 0.0f });
SetUniform(UniformName::uGlowBottomPlane, FVector4{ 0.0f, 0.0f, 0.0f, 0.0f });
SetUniform(UniformName::uGradientTopPlane, FVector4{ 0.0f, 0.0f, 0.0f, 0.0f });
SetUniform(UniformName::uGradientBottomPlane, FVector4{ 0.0f, 0.0f, 0.0f, 0.0f });
SetUniform(UniformName::uSplitTopPlane, FVector4{ 0.0f, 0.0f, 0.0f, 0.0f });
SetUniform(UniformName::uSplitBottomPlane, FVector4{ 0.0f, 0.0f, 0.0f, 0.0f });
SetUniform(UniformName::uDynLightColor, FVector4{ 0.0f, 0.0f, 0.0f, 0.0f });
mModelMatrix.loadIdentity();
mTextureMatrix.loadIdentity();
@ -295,38 +474,38 @@ public:
void SetNormal(FVector3 norm)
{
mStreamData.uVertexNormal = { norm.X, norm.Y, norm.Z, 0.f };
SetUniform(UniformName::uVertexNormal, FVector4{ norm.X, norm.Y, norm.Z, 0.f });
}
void SetNormal(float x, float y, float z)
{
mStreamData.uVertexNormal = { x, y, z, 0.f };
SetUniform(UniformName::uVertexNormal, FVector4{ x, y, z, 0.f });
}
void SetColor(float r, float g, float b, float a = 1.f, int desat = 0)
{
mStreamData.uVertexColor = { r, g, b, a };
mStreamData.uDesaturationFactor = desat * (1.0f / 255.0f);
SetUniform(UniformName::uVertexColor, FVector4{ r, g, b, a });
SetUniform(UniformName::uDesaturationFactor, desat * (1.0f / 255.0f));
}
void SetColor(PalEntry pe, int desat = 0)
{
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);
SetUniform(UniformName::uVertexColor, FVector4{ pe.r * scale, pe.g * scale, pe.b * scale, pe.a * scale });
SetUniform(UniformName::uDesaturationFactor, desat * (1.0f / 255.0f));
}
void SetColorAlpha(PalEntry pe, float alpha = 1.f, int desat = 0)
{
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);
SetUniform(UniformName::uVertexColor, FVector4{ pe.r * scale, pe.g * scale, pe.b * scale, alpha });
SetUniform(UniformName::uDesaturationFactor, desat * (1.0f / 255.0f));
}
void ResetColor()
{
mStreamData.uVertexColor = { 1.0f, 1.0f, 1.0f, 1.0f };
mStreamData.uDesaturationFactor = 0.0f;
SetUniform(UniformName::uVertexColor, FVector4{ 1.0f, 1.0f, 1.0f, 1.0f });
SetUniform(UniformName::uDesaturationFactor, 0.0f);
}
void SetTextureMode(int mode)
@ -374,8 +553,8 @@ public:
{
if (mGlowEnabled && !on)
{
mStreamData.uGlowTopColor = { 0.0f, 0.0f, 0.0f, 0.0f };
mStreamData.uGlowBottomColor = { 0.0f, 0.0f, 0.0f, 0.0f };
SetUniform(UniformName::uGlowTopColor, FVector4{ 0.0f, 0.0f, 0.0f, 0.0f });
SetUniform(UniformName::uGlowBottomColor, FVector4{ 0.0f, 0.0f, 0.0f, 0.0f });
}
mGlowEnabled = on;
}
@ -394,8 +573,8 @@ public:
{
if (mSplitEnabled && !on)
{
mStreamData.uSplitTopPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
mStreamData.uSplitBottomPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
SetUniform(UniformName::uSplitTopPlane, FVector4{ 0.0f, 0.0f, 0.0f, 0.0f });
SetUniform(UniformName::uSplitBottomPlane, FVector4{ 0.0f, 0.0f, 0.0f, 0.0f });
}
mSplitEnabled = on;
}
@ -412,78 +591,78 @@ public:
void SetGlowParams(float *t, float *b)
{
mStreamData.uGlowTopColor = { t[0], t[1], t[2], t[3] };
mStreamData.uGlowBottomColor = { b[0], b[1], b[2], b[3] };
SetUniform(UniformName::uGlowTopColor, FVector4{ t[0], t[1], t[2], t[3] });
SetUniform(UniformName::uGlowBottomColor, FVector4{ b[0], b[1], b[2], b[3] });
}
void SetSoftLightLevel(int llevel, int blendfactor = 0)
{
if (blendfactor == 0) mLightParms[3] = llevel / 255.f;
else mLightParms[3] = -1.f;
if (blendfactor == 0) SetUniform(UniformName::uLightLevel, llevel / 255.f);
else SetUniform(UniformName::uLightLevel, -1.f);
}
void SetNoSoftLightLevel()
{
mLightParms[3] = -1.f;
SetUniform(UniformName::uLightLevel, -1.f);
}
void SetGlowPlanes(const secplane_t &top, const secplane_t &bottom)
{
auto &tn = top.Normal();
auto &bn = bottom.Normal();
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() };
SetUniform(UniformName::uGlowTopPlane, FVector4{ (float)tn.X, (float)tn.Y, (float)top.negiC, (float)top.fD() });
SetUniform(UniformName::uGlowBottomPlane, FVector4{ (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();
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() };
SetUniform(UniformName::uGradientTopPlane, FVector4{ (float)tn.X, (float)tn.Y, (float)top.negiC, (float)top.fD() });
SetUniform(UniformName::uGradientBottomPlane, FVector4{ (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();
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() };
SetUniform(UniformName::uSplitTopPlane, FVector4{ (float)tn.X, (float)tn.Y, (float)top.negiC, (float)top.fD() });
SetUniform(UniformName::uSplitBottomPlane, FVector4{ (float)bn.X, (float)bn.Y, (float)bottom.negiC, (float)bottom.fD() });
}
void SetDynLight(float r, float g, float b)
{
mStreamData.uDynLightColor = { r, g, b, 0.0f };
SetUniform(UniformName::uDynLightColor, FVector4{ r, g, b, 0.0f });
}
void SetObjectColor(PalEntry pe)
{
mStreamData.uObjectColor = pe;
SetUniform(UniformName::uObjectColor, pe);
}
void SetObjectColor2(PalEntry pe)
{
mStreamData.uObjectColor2 = pe;
SetUniform(UniformName::uObjectColor2, pe);
}
void SetAddColor(PalEntry pe)
{
mStreamData.uAddColor = pe;
SetUniform(UniformName::uAddColor, pe);
}
void ApplyTextureManipulation(TextureManipulation* texfx)
{
if (!texfx || texfx->AddColor.a == 0)
{
mStreamData.uTextureAddColor.a = 0; // we only need to set the flags to 0
SetUniformAlpha(UniformName::uTextureAddColor, 0); // we only need to set the flags to 0
}
else
{
// set up the whole thing
mStreamData.uTextureAddColor.SetIA(texfx->AddColor);
SetUniformIntegerAlpha(UniformName::uTextureAddColor, texfx->AddColor);
auto pe = texfx->ModulateColor;
mStreamData.uTextureModulateColor.SetFlt(pe.r * pe.a / 255.f, pe.g * pe.a / 255.f, pe.b * pe.a / 255.f, texfx->DesaturationFactor);
mStreamData.uTextureBlendColor = texfx->BlendColor;
SetUniform(UniformName::uTextureModulateColor, FVector4{ pe.r * pe.a / 255.f, pe.g * pe.a / 255.f, pe.b * pe.a / 255.f, texfx->DesaturationFactor });
SetUniform(UniformName::uTextureBlendColor, texfx->BlendColor);
}
}
@ -491,14 +670,14 @@ public:
{
const float LOG2E = 1.442692f; // = 1/log(2)
mFogColor = c;
mStreamData.uFogColor = mFogColor;
if (d >= 0.0f) mLightParms[2] = d * (-LOG2E / 64000.f);
SetUniform(UniformName::uFogColor, mFogColor);
if (d >= 0.0f) SetUniform(UniformName::uFogDensity, d * (-LOG2E / 64000.f));
}
void SetLightParms(float f, float d)
{
mLightParms[1] = f;
mLightParms[0] = d;
SetUniform(UniformName::uLightFactor, f);
SetUniform(UniformName::uLightDist, d);
}
PalEntry GetFogColor() const
@ -508,8 +687,8 @@ public:
void AlphaFunc(int func, float thresh)
{
if (func == Alpha_Greater) mAlphaThreshold = thresh;
else mAlphaThreshold = thresh - 0.001f;
if (func == Alpha_Greater) SetUniform(UniformName::uAlphaThreshold, thresh);
else SetUniform(UniformName::uAlphaThreshold, thresh - 0.001f);
}
void SetPlaneTextureRotation(HWSectorPlane *plane, FMaterial *texture)
@ -522,7 +701,7 @@ public:
void SetLightIndex(int index)
{
mLightIndex = index;
SetUniform(UniformName::uLightIndex, index);
}
void SetRenderStyle(FRenderStyle rs)
@ -560,24 +739,22 @@ public:
void SetClipSplit(float bottom, float top)
{
mClipSplit[0] = bottom;
mClipSplit[1] = top;
SetUniform(UniformName::uClipSplit, FVector2(bottom, top));
}
void SetClipSplit(float *vals)
{
memcpy(mClipSplit, vals, 2 * sizeof(float));
SetUniform(UniformName::uClipSplit, FVector2(vals[0], vals[1]));
}
void GetClipSplit(float *out)
{
memcpy(out, mClipSplit, 2 * sizeof(float));
memcpy(out, GetUniformData(UniformName::uClipSplit), 2 * sizeof(float));
}
void ClearClipSplit()
{
mClipSplit[0] = -1000000.f;
mClipSplit[1] = 1000000.f;
SetUniform(UniformName::uClipSplit, FVector2(-1000000.f, 1000000.f));
}
void SetVertexBuffer(IVertexBuffer *vb, int offset0, int offset1)
@ -602,12 +779,12 @@ public:
void SetInterpolationFactor(float fac)
{
mStreamData.uInterpolationFactor = fac;
SetUniform(UniformName::uInterpolationFactor, fac);
}
float GetInterpolationFactor()
{
return mStreamData.uInterpolationFactor;
return GetUniform<float>(UniformName::uInterpolationFactor);
}
void EnableDrawBufferAttachments(bool on) // Used by fog boundary drawer

View file

@ -246,21 +246,33 @@ void PolyRenderState::Apply()
else
{
int effectState = mMaterial.mOverrideShader >= 0 ? mMaterial.mOverrideShader : (mMaterial.mMaterial ? mMaterial.mMaterial->GetShaderIndex() : 0);
mDrawCommands->SetShader(EFF_NONE, mTextureEnabled ? effectState : SHADER_NoTexture, mAlphaThreshold >= 0.f);
mDrawCommands->SetShader(EFF_NONE, mTextureEnabled ? effectState : SHADER_NoTexture, GetUniform<float>(UniformName::uAlphaThreshold) >= 0.f);
}
PolyPushConstants constants;
constants.uFogEnabled = fogset;
constants.uTextureMode = mTextureMode == TM_NORMAL && mTempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode;
constants.uLightDist = mLightParms[0];
constants.uLightFactor = mLightParms[1];
constants.uFogDensity = mLightParms[2];
constants.uLightLevel = mLightParms[3];
constants.uAlphaThreshold = mAlphaThreshold;
constants.uClipSplit = { mClipSplit[0], mClipSplit[1] };
constants.uLightIndex = mLightIndex;
PolyUniforms uniforms;
uniforms.uFogEnabled = fogset;
uniforms.uTextureMode = mTextureMode == TM_NORMAL && mTempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode;
uniforms.uLightDist = GetUniform<float>(UniformName::uLightDist);
uniforms.uLightFactor = GetUniform<float>(UniformName::uLightFactor);
uniforms.uFogDensity = GetUniform<float>(UniformName::uFogDensity);
uniforms.uLightLevel = GetUniform<float>(UniformName::uLightLevel);
uniforms.uAlphaThreshold = GetUniform<float>(UniformName::uAlphaThreshold);
uniforms.uClipSplit = GetUniform<Vec2f>(UniformName::uClipSplit);
uniforms.uLightIndex = GetUniform<int>(UniformName::uLightIndex);
uniforms.uDesaturationFactor = GetUniform<float>(UniformName::uDesaturationFactor);
uniforms.uInterpolationFactor = GetUniform<float>(UniformName::uInterpolationFactor);
uniforms.uObjectColor = GetUniform<Color4f>(UniformName::uObjectColor);
uniforms.uObjectColor2 = GetUniform<Color4f>(UniformName::uObjectColor2);
uniforms.uGradientTopPlane = GetUniform<FVector4>(UniformName::uGradientTopPlane);
uniforms.uGradientBottomPlane = GetUniform<FVector4>(UniformName::uGradientBottomPlane);
uniforms.uSplitTopPlane = GetUniform<FVector4>(UniformName::uSplitTopPlane);
uniforms.uSplitBottomPlane = GetUniform<FVector4>(UniformName::uSplitBottomPlane);
uniforms.uVertexColor = GetUniform<FVector4>(UniformName::uVertexColor);
uniforms.uVertexNormal = GetUniform<FVector3>(UniformName::uVertexNormal);
uniforms.uAddColor = GetUniform<Color4f>(UniformName::uAddColor);
uniforms.uFogColor = GetUniform<Color4f>(UniformName::uFogColor);
mDrawCommands->PushStreamData(mStreamData, constants);
mDrawCommands->PushStreamData(uniforms);
ApplyMatrices();
if (mBias.mChanged)

View file

@ -112,23 +112,21 @@ void PolyTriangleThreadData::UpdateClip()
clip.bottom = MIN(MIN(viewport_y + viewport_height, scissor.bottom), dest_height);
}
void PolyTriangleThreadData::PushStreamData(const StreamData &data, const PolyPushConstants &constants)
void PolyTriangleThreadData::PushStreamData(const PolyUniforms &data)
{
mainVertexShader.Data = data;
mainVertexShader.uClipSplit = constants.uClipSplit;
mainVertexShader.uClipSplit = data.uClipSplit;
PushConstants = &constants;
AlphaThreshold = clamp((int)(PushConstants->uAlphaThreshold * 255.0f + 0.5f), 0, 255) << 24;
AlphaThreshold = clamp((int)(data.uAlphaThreshold * 255.0f + 0.5f), 0, 255) << 24;
numPolyLights = 0;
if (constants.uLightIndex >= 0)
if (data.uLightIndex >= 0)
{
const FVector4 &lightRange = lights[constants.uLightIndex];
const FVector4 &lightRange = lights[data.uLightIndex];
static_assert(sizeof(FVector4) == 16, "sizeof(FVector4) is not 16 bytes");
if (lightRange.Y > lightRange.X)
{
int start = constants.uLightIndex + 1;
int start = data.uLightIndex + 1;
int modulatedStart = static_cast<int>(lightRange.X) + start;
int modulatedEnd = static_cast<int>(lightRange.Y) + start;
for (int i = modulatedStart; i < modulatedEnd; i += 4)

View file

@ -64,7 +64,7 @@ public:
void UpdateClip();
void PushStreamData(const StreamData &data, const PolyPushConstants &constants);
void PushStreamData(const PolyUniforms &data);
void PushMatrices(const VSMatrix &modelMatrix, const VSMatrix &normalModelMatrix, const VSMatrix &textureMatrix);
void DrawIndexed(int index, int count, PolyDrawMode mode);
@ -142,7 +142,6 @@ public:
int EffectState = 0;
bool AlphaTest = false;
uint32_t AlphaThreshold = 0x7f000000;
const PolyPushConstants* PushConstants = nullptr;
const void *vertices = nullptr;
const unsigned int *elements = nullptr;

View file

@ -299,12 +299,11 @@ private:
class PolyPushStreamDataCommand : public PolyDrawerCommand
{
public:
PolyPushStreamDataCommand(const StreamData& data, const PolyPushConstants& constants) : data(data), constants(constants) { }
void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->PushStreamData(data, constants); }
PolyPushStreamDataCommand(const PolyUniforms& data) : data(data) { }
void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->PushStreamData(data); }
private:
StreamData data;
PolyPushConstants constants;
PolyUniforms data;
};
class PolyDrawCommand : public PolyDrawerCommand
@ -434,9 +433,9 @@ void PolyCommandBuffer::SetShader(int specialEffect, int effectState, bool alpha
mQueue->Push<PolySetShaderCommand>(specialEffect, effectState, alphaTest);
}
void PolyCommandBuffer::PushStreamData(const StreamData &data, const PolyPushConstants &constants)
void PolyCommandBuffer::PushStreamData(const PolyUniforms &data)
{
mQueue->Push<PolyPushStreamDataCommand>(data, constants);
mQueue->Push<PolyPushStreamDataCommand>(data);
}
void PolyCommandBuffer::PushMatrices(const VSMatrix &modelMatrix, const VSMatrix &normalModelMatrix, const VSMatrix &textureMatrix)

View file

@ -33,7 +33,6 @@ class RenderMemory;
class PolyDrawerCommand;
class PolyInputAssembly;
class PolyDepthStencil;
struct PolyPushConstants;
enum class PolyDrawMode
{
@ -68,7 +67,7 @@ public:
void SetRenderStyle(FRenderStyle style);
void SetTexture(int unit, void *pixels, int width, int height, bool bgra);
void SetShader(int specialEffect, int effectState, bool alphaTest);
void PushStreamData(const StreamData &data, const PolyPushConstants &constants);
void PushStreamData(const PolyUniforms& data);
void PushMatrices(const VSMatrix &modelMatrix, const VSMatrix &normalModelMatrix, const VSMatrix &textureMatrix);
void ClearDepth(float value);
void ClearStencil(uint8_t value);
@ -97,23 +96,6 @@ private:
std::vector<uint8_t> stencilbuffer;
};
struct PolyPushConstants
{
int uTextureMode;
float uAlphaThreshold;
Vec2f uClipSplit;
// Lighting + Fog
float uLightLevel;
float uFogDensity;
float uLightFactor;
float uLightDist;
int uFogEnabled;
// dynamic lights
int uLightIndex;
};
class PolyInputAssembly
{
public:

View file

@ -23,6 +23,39 @@ public:
Vec4f vWorldNormal;
};
struct Color4f { float r, g, b, a; };
class PolyUniforms
{
public:
int uTextureMode;
float uAlphaThreshold;
Vec2f uClipSplit;
float uLightLevel;
float uFogDensity;
float uLightFactor;
float uLightDist;
int uFogEnabled;
int uLightIndex;
float uDesaturationFactor;
float uInterpolationFactor;
Color4f uObjectColor;
Color4f uObjectColor2;
FVector4 uGradientTopPlane;
FVector4 uGradientBottomPlane;
FVector4 uSplitTopPlane;
FVector4 uSplitBottomPlane;
FVector4 uVertexColor;
FVector3 uVertexNormal;
Color4f uFogColor;
Color4f uAddColor;
};
class PolyMainVertexShader : public ShadedTriVertex
{
public:
@ -42,7 +75,7 @@ public:
VSMatrix ModelMatrix;
VSMatrix NormalModelMatrix;
VSMatrix TextureMatrix;
StreamData Data;
PolyUniforms Data;
Vec2f uClipSplit;
const HWViewpointUniforms *Viewpoint = nullptr;

View file

@ -219,14 +219,14 @@ static void WriteDynLightArray(int x0, int x1, PolyTriangleThreadData* thread)
static void WriteLightArray(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread)
{
auto constants = thread->PushConstants;
auto uniforms = &thread->mainVertexShader.Data;
auto vColorR = thread->scanline.vColorR;
auto vColorG = thread->scanline.vColorG;
auto vColorB = thread->scanline.vColorB;
auto vColorA = thread->scanline.vColorA;
if (thread->PushConstants->uLightLevel >= 0.0f)
if (uniforms->uLightLevel >= 0.0f)
{
float startX = x0 + (0.5f - args->v1->x);
float startY = y + (0.5f - args->v1->y);
@ -235,7 +235,7 @@ static void WriteLightArray(int y, int x0, int x1, const TriDrawTriangleArgs* ar
float globVis = thread->mainVertexShader.Viewpoint->mGlobVis;
uint32_t light = (int)(constants->uLightLevel * 255.0f);
uint32_t light = (int)(uniforms->uLightLevel * 255.0f);
fixed_t shade = (fixed_t)((2.0f - (light + 12.0f) / 128.0f) * (float)FRACUNIT);
fixed_t lightpos = (fixed_t)(globVis * posW * (float)FRACUNIT);
fixed_t lightstep = (fixed_t)(globVis * stepW * (float)FRACUNIT);
@ -278,10 +278,10 @@ static void WriteLightArray(int y, int x0, int x1, const TriDrawTriangleArgs* ar
}
}
}
else if (constants->uFogEnabled > 0)
else if (uniforms->uFogEnabled > 0)
{
float uLightDist = constants->uLightDist;
float uLightFactor = constants->uLightFactor;
float uLightDist = uniforms->uLightDist;
float uLightFactor = uniforms->uLightFactor;
float* w = thread->scanline.W;
uint32_t* lightarray = thread->scanline.lightarray;
for (int x = x0; x < x1; x++)
@ -292,7 +292,7 @@ static void WriteLightArray(int y, int x0, int x1, const TriDrawTriangleArgs* ar
uint32_t b = thread->scanline.vColorB[x];
float fogdist = MAX(16.0f, w[x]);
float fogfactor = std::exp2(constants->uFogDensity * fogdist);
float fogfactor = std::exp2(uniforms->uFogDensity * fogdist);
// brightening around the player for light mode 2:
if (fogdist < uLightDist)
@ -459,7 +459,7 @@ void WriteVaryings(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyT
WriteVaryingColor(args->v1->g * args->v1->w + args->gradientX.G * startX + args->gradientY.G * startY, args->gradientX.G, x0, x1, thread->scanline.W, thread->scanline.vColorG);
WriteVaryingColor(args->v1->b * args->v1->w + args->gradientX.B * startX + args->gradientY.B * startY, args->gradientX.B, x0, x1, thread->scanline.W, thread->scanline.vColorB);
if (thread->PushConstants->uFogEnabled != -3 && thread->PushConstants->uTextureMode != TM_FOGLAYER)
if (thread->mainVertexShader.Data.uFogEnabled != -3 && thread->mainVertexShader.Data.uTextureMode != TM_FOGLAYER)
WriteLightArray(y, x0, x1, args, thread);
if (thread->numPolyLights > 0)

View file

@ -46,7 +46,7 @@ static uint32_t SampleTexture(uint32_t u, uint32_t v, const void* texPixels, int
static void EffectFogBoundary(int x0, int x1, PolyTriangleThreadData* thread)
{
float uFogDensity = thread->PushConstants->uFogDensity;
float uFogDensity = thread->mainVertexShader.Data.uFogDensity;
uint32_t fogcolor = MAKEARGB(
0,
static_cast<int>(clamp(thread->mainVertexShader.Data.uFogColor.r, 0.0f, 1.0f) * 255.0f),
@ -380,9 +380,9 @@ static void ProcessMaterial(int x0, int x1, PolyTriangleThreadData* thread)
}
else // func_normal
{
auto constants = thread->PushConstants;
auto uniforms = &thread->mainVertexShader.Data;
switch (constants->uTextureMode)
switch (uniforms->uTextureMode)
{
default:
case TM_NORMAL:
@ -395,7 +395,7 @@ static void ProcessMaterial(int x0, int x1, PolyTriangleThreadData* thread)
case TM_INVERTOPAQUE: FuncNormal_InvertOpaque(x0, x1, thread); break;
}
if (constants->uTextureMode != TM_FOGLAYER)
if (uniforms->uTextureMode != TM_FOGLAYER)
{
auto& streamdata = thread->mainVertexShader.Data;
@ -429,7 +429,7 @@ static void GetLightColor(int x0, int x1, PolyTriangleThreadData* thread)
uint32_t* fragcolor = thread->scanline.FragColor;
uint32_t* lightarray = thread->scanline.lightarray;
if (thread->PushConstants->uFogEnabled >= 0)
if (thread->mainVertexShader.Data.uFogEnabled >= 0)
{
for (int x = x0; x < x1; x++)
{
@ -458,7 +458,7 @@ static void GetLightColor(int x0, int x1, PolyTriangleThreadData* thread)
uint32_t fogR = (int)((thread->mainVertexShader.Data.uFogColor.r) * 255.0f);
uint32_t fogG = (int)((thread->mainVertexShader.Data.uFogColor.g) * 255.0f);
uint32_t fogB = (int)((thread->mainVertexShader.Data.uFogColor.b) * 255.0f);
float uFogDensity = thread->PushConstants->uFogDensity;
float uFogDensity = thread->mainVertexShader.Data.uFogDensity;
float* w = thread->scanline.W;
for (int x = x0; x < x1; x++)
@ -501,10 +501,10 @@ static void MainFP(int x0, int x1, PolyTriangleThreadData* thread)
if (thread->AlphaTest)
RunAlphaTest(x0, x1, thread);
auto constants = thread->PushConstants;
if (constants->uFogEnabled != -3)
auto uniforms = &thread->mainVertexShader.Data;
if (uniforms->uFogEnabled != -3)
{
if (constants->uTextureMode != TM_FOGLAYER)
if (uniforms->uTextureMode != TM_FOGLAYER)
{
GetLightColor(x0, x1, thread);
}
@ -512,10 +512,10 @@ static void MainFP(int x0, int x1, PolyTriangleThreadData* thread)
{
/*float fogdist = 0.0f;
float fogfactor = 0.0f;
if (constants->uFogEnabled != 0)
if (uniforms->uFogEnabled != 0)
{
fogdist = MAX(16.0f, w[x]);
fogfactor = std::exp2(constants->uFogDensity * fogdist);
fogfactor = std::exp2(uniforms->uFogDensity * fogdist);
}
frag = vec4(uFogColor.rgb, (1.0 - fogfactor) * frag.a * 0.75 * vColor.a);*/
}
@ -532,7 +532,7 @@ static void MainFP(int x0, int x1, PolyTriangleThreadData* thread)
auto vColorA = thread->scanline.vColorA;
uint32_t* fragcolor = thread->scanline.FragColor;
if (constants->uTextureMode == TM_FOGLAYER)
if (uniforms->uTextureMode == TM_FOGLAYER)
{
// float gray = grayscale(frag);
// vec4 cm = (uObjectColor + gray * (uAddColor - uObjectColor)) * 2;

View file

@ -142,7 +142,7 @@ VulkanPipelineLayout* VkRenderPassManager::GetPipelineLayout(int numLayers)
builder.addSetLayout(DynamicSetLayout.get());
if (numLayers != 0)
builder.addSetLayout(GetTextureSetLayout(numLayers));
builder.addPushConstantRange(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PushConstants));
builder.addPushConstantRange(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, GetVulkanFrameBuffer()->GetRenderState()->GetUniformDataSize(UniformFamily::PushConstant));
layout = builder.create(GetVulkanFrameBuffer()->device);
layout->SetDebugName("VkRenderPassManager.PipelineLayout");
return layout.get();
@ -178,8 +178,8 @@ void VkRenderPassManager::UpdateDynamicSet()
WriteDescriptors update;
update.addBuffer(DynamicSet.get(), 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->ViewpointUBO->mBuffer.get(), 0, sizeof(HWViewpointUniforms));
update.addBuffer(DynamicSet.get(), 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->LightBufferSSO->mBuffer.get());
update.addBuffer(DynamicSet.get(), 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->MatrixBuffer->UniformBuffer->mBuffer.get(), 0, sizeof(MatricesUBO));
update.addBuffer(DynamicSet.get(), 3, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->StreamBuffer->UniformBuffer->mBuffer.get(), 0, sizeof(StreamUBO));
update.addBuffer(DynamicSet.get(), 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->MatrixBufferWriter->Buffer()->mBuffer.get(), 0, sizeof(MatricesUBO));
update.addBuffer(DynamicSet.get(), 3, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->StreamBufferWriter->Buffer()->mBuffer.get(), 0, fb->StreamBufferWriter->BlockSize());
update.addCombinedImageSampler(DynamicSet.get(), 4, fb->GetBuffers()->Shadowmap.View.get(), fb->GetBuffers()->ShadowmapSampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
update.updateSets(fb->device);
}

View file

@ -166,9 +166,9 @@ void VkRenderState::Apply(int dt)
mApplyCount = 0;
}
ApplyRenderPass(dt);
ApplyStreamData();
ApplyMatrices();
ApplyRenderPass(dt);
ApplyScissor();
ApplyViewport();
ApplyStencilRef();
@ -219,7 +219,7 @@ void VkRenderState::ApplyRenderPass(int dt)
int effectState = mMaterial.mOverrideShader >= 0 ? mMaterial.mOverrideShader : (mMaterial.mMaterial ? mMaterial.mMaterial->GetShaderIndex() : 0);
pipelineKey.SpecialEffect = EFF_NONE;
pipelineKey.EffectState = mTextureEnabled ? effectState : SHADER_NoTexture;
pipelineKey.AlphaTest = mAlphaThreshold >= 0.f;
pipelineKey.AlphaTest = GetUniform<float>(UniformName::uAlphaThreshold) >= 0.f;
}
// Is this the one we already have?
@ -313,17 +313,17 @@ void VkRenderState::ApplyStreamData()
auto fb = GetVulkanFrameBuffer();
auto passManager = fb->GetRenderPassManager();
mStreamData.useVertexData = passManager->GetVertexFormat(static_cast<VKVertexBuffer*>(mVertexBuffer)->VertexFormat)->UseVertexData;
SetUniform(UniformName::useVertexData, passManager->GetVertexFormat(static_cast<VKVertexBuffer*>(mVertexBuffer)->VertexFormat)->UseVertexData);
if (mMaterial.mMaterial && mMaterial.mMaterial->tex)
mStreamData.timer = static_cast<float>((double)(screen->FrameTime - firstFrame) * (double)mMaterial.mMaterial->tex->shaderspeed / 1000.);
SetUniform(UniformName::timer, static_cast<float>((double)(screen->FrameTime - firstFrame) * (double)mMaterial.mMaterial->tex->shaderspeed / 1000.));
else
mStreamData.timer = 0.0f;
SetUniform(UniformName::timer, 0.0f);
if (!mStreamBufferWriter.Write(mStreamData))
if (!mStreamBufferWriter->Write(GetUniformData(UniformFamily::Normal)))
{
WaitForStreamBuffers();
mStreamBufferWriter.Write(mStreamData);
mStreamBufferWriter->Write(GetUniformData(UniformFamily::Normal));
}
}
@ -350,32 +350,25 @@ void VkRenderState::ApplyPushConstants()
if (mMaterial.mMaterial && mMaterial.mMaterial->tex && mMaterial.mMaterial->tex->isHardwareCanvas())
tempTM = TM_OPAQUE;
mPushConstants.uFogEnabled = fogset;
mPushConstants.uTextureMode = mTextureMode == TM_NORMAL && tempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode;
mPushConstants.uLightDist = mLightParms[0];
mPushConstants.uLightFactor = mLightParms[1];
mPushConstants.uFogDensity = mLightParms[2];
mPushConstants.uLightLevel = mLightParms[3];
mPushConstants.uAlphaThreshold = mAlphaThreshold;
mPushConstants.uClipSplit = { mClipSplit[0], mClipSplit[1] };
SetUniform(UniformName::uFogEnabled, fogset);
SetUniform(UniformName::uTextureMode, mTextureMode == TM_NORMAL && tempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode);
if (mMaterial.mMaterial && mMaterial.mMaterial->tex)
mPushConstants.uSpecularMaterial = { mMaterial.mMaterial->tex->Glossiness, mMaterial.mMaterial->tex->SpecularLevel };
SetUniform(UniformName::uSpecularMaterial, FVector2{ mMaterial.mMaterial->tex->Glossiness, mMaterial.mMaterial->tex->SpecularLevel });
mPushConstants.uLightIndex = mLightIndex;
mPushConstants.uDataIndex = mStreamBufferWriter.DataIndex();
SetUniform(UniformName::uDataIndex, mStreamBufferWriter->DataIndex());
auto fb = GetVulkanFrameBuffer();
auto passManager = fb->GetRenderPassManager();
mCommandBuffer->pushConstants(passManager->GetPipelineLayout(mPipelineKey.NumTextureLayers), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, (uint32_t)sizeof(PushConstants), &mPushConstants);
mCommandBuffer->pushConstants(passManager->GetPipelineLayout(mPipelineKey.NumTextureLayers), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, GetUniformDataSize(UniformFamily::PushConstant), GetUniformData(UniformFamily::PushConstant));
}
void VkRenderState::ApplyMatrices()
{
if (!mMatrixBufferWriter.Write(mModelMatrix, mModelMatrixEnabled, mTextureMatrix, mTextureMatrixEnabled))
if (!mMatrixBufferWriter->Write(mModelMatrix, mModelMatrixEnabled, mTextureMatrix, mTextureMatrixEnabled))
{
WaitForStreamBuffers();
mMatrixBufferWriter.Write(mModelMatrix, mModelMatrixEnabled, mTextureMatrix, mTextureMatrixEnabled);
mMatrixBufferWriter->Write(mModelMatrix, mModelMatrixEnabled, mTextureMatrix, mTextureMatrixEnabled);
}
}
@ -419,8 +412,8 @@ void VkRenderState::ApplyMaterial()
void VkRenderState::ApplyDynamicSet()
{
auto fb = GetVulkanFrameBuffer();
uint32_t matrixOffset = mMatrixBufferWriter.Offset();
uint32_t streamDataOffset = mStreamBufferWriter.StreamDataOffset();
uint32_t matrixOffset = mMatrixBufferWriter->Offset();
uint32_t streamDataOffset = mStreamBufferWriter->StreamDataOffset();
if (mViewpointOffset != mLastViewpointOffset || matrixOffset != mLastMatricesOffset || streamDataOffset != mLastStreamDataOffset)
{
auto passManager = fb->GetRenderPassManager();
@ -438,8 +431,8 @@ void VkRenderState::WaitForStreamBuffers()
{
GetVulkanFrameBuffer()->WaitForCommands(false);
mApplyCount = 0;
mStreamBufferWriter.Reset();
mMatrixBufferWriter.Reset();
mStreamBufferWriter->Reset();
mMatrixBufferWriter->Reset();
}
void VkRenderState::Bind(int bindingpoint, uint32_t offset)
@ -475,8 +468,8 @@ void VkRenderState::EndRenderPass()
void VkRenderState::EndFrame()
{
mMatrixBufferWriter.Reset();
mStreamBufferWriter.Reset();
mMatrixBufferWriter->Reset();
mStreamBufferWriter->Reset();
}
void VkRenderState::EnableDrawBuffers(int count)
@ -548,6 +541,9 @@ void VkRenderState::BeginRenderPass(VulkanCommandBuffer *cmdbuffer)
mMaterial.mChanged = true;
mClearTargets = 0;
mStreamBufferWriter = fb->StreamBufferWriter;
mMatrixBufferWriter = fb->MatrixBufferWriter;
}
/////////////////////////////////////////////////////////////////////////////

View file

@ -91,15 +91,13 @@ protected:
int mColorMask = 15;
int mCullMode = 0;
PushConstants mPushConstants = {};
uint32_t mLastViewpointOffset = 0xffffffff;
uint32_t mLastMatricesOffset = 0xffffffff;
uint32_t mLastStreamDataOffset = 0xffffffff;
uint32_t mViewpointOffset = 0;
VkStreamBufferWriter mStreamBufferWriter;
VkMatrixBufferWriter mMatrixBufferWriter;
VkStreamBufferWriter *mStreamBufferWriter = nullptr;
VkMatrixBufferWriter *mMatrixBufferWriter = nullptr;
int mLastVertexOffsets[2] = { 0, 0 };
IVertexBuffer *mLastVertexBuffer = nullptr;

View file

@ -32,13 +32,22 @@ uint32_t VkStreamBuffer::NextStreamDataBlock()
VkStreamBufferWriter::VkStreamBufferWriter()
{
mBuffer = GetVulkanFrameBuffer()->StreamBuffer;
mStreamDataSize = GetVulkanFrameBuffer()->GetRenderState()->GetUniformDataSize(UniformFamily::Normal);
mMaxStreamData = 65536 / mStreamDataSize;
mBuffer = new VkStreamBuffer(mStreamDataSize * mMaxStreamData, 300);
mDataIndex = mMaxStreamData - 1;
mStreamDataOffset = 0;
}
bool VkStreamBufferWriter::Write(const StreamData& data)
VkStreamBufferWriter::~VkStreamBufferWriter()
{
delete mBuffer;
}
bool VkStreamBufferWriter::Write(const void* data)
{
mDataIndex++;
if (mDataIndex == MAX_STREAM_DATA)
if (mDataIndex == mMaxStreamData)
{
mDataIndex = 0;
mStreamDataOffset = mBuffer->NextStreamDataBlock();
@ -46,13 +55,13 @@ bool VkStreamBufferWriter::Write(const StreamData& data)
return false;
}
uint8_t* ptr = (uint8_t*)mBuffer->UniformBuffer->Memory();
memcpy(ptr + mStreamDataOffset + sizeof(StreamData) * mDataIndex, &data, sizeof(StreamData));
memcpy(ptr + mStreamDataOffset + mStreamDataSize * mDataIndex, data, mStreamDataSize);
return true;
}
void VkStreamBufferWriter::Reset()
{
mDataIndex = MAX_STREAM_DATA - 1;
mDataIndex = mMaxStreamData - 1;
mStreamDataOffset = 0;
mBuffer->Reset();
}
@ -61,10 +70,16 @@ void VkStreamBufferWriter::Reset()
VkMatrixBufferWriter::VkMatrixBufferWriter()
{
mBuffer = GetVulkanFrameBuffer()->MatrixBuffer;
auto fb = GetVulkanFrameBuffer();
mBuffer = new VkStreamBuffer(sizeof(MatricesUBO), 50000);
mIdentityMatrix.loadIdentity();
}
VkMatrixBufferWriter::~VkMatrixBufferWriter()
{
delete mBuffer;
}
template<typename T>
static void BufferedSet(bool& modified, T& dst, const T& src)
{

View file

@ -4,42 +4,7 @@
#include "vulkan/system/vk_buffers.h"
#include "vulkan/shaders/vk_shader.h"
class VkStreamBuffer;
class VkMatrixBuffer;
class VkStreamBufferWriter
{
public:
VkStreamBufferWriter();
bool Write(const StreamData& data);
void Reset();
uint32_t DataIndex() const { return mDataIndex; }
uint32_t StreamDataOffset() const { return mStreamDataOffset; }
private:
VkStreamBuffer* mBuffer;
uint32_t mDataIndex = MAX_STREAM_DATA - 1;
uint32_t mStreamDataOffset = 0;
};
class VkMatrixBufferWriter
{
public:
VkMatrixBufferWriter();
bool Write(const VSMatrix& modelMatrix, bool modelMatrixEnabled, const VSMatrix& textureMatrix, bool textureMatrixEnabled);
void Reset();
uint32_t Offset() const { return mOffset; }
private:
VkStreamBuffer* mBuffer;
MatricesUBO mMatrices = {};
VSMatrix mIdentityMatrix;
uint32_t mOffset = 0;
};
class VKDataBuffer;
class VkStreamBuffer
{
@ -51,8 +16,50 @@ public:
void Reset() { mStreamDataOffset = 0; }
VKDataBuffer* UniformBuffer = nullptr;
uint32_t mBlockSize = 0;
private:
uint32_t mBlockSize = 0;
uint32_t mStreamDataOffset = 0;
};
class VkStreamBufferWriter
{
public:
VkStreamBufferWriter();
~VkStreamBufferWriter();
bool Write(const void* data);
void Reset();
uint32_t DataIndex() const { return mDataIndex; }
uint32_t StreamDataOffset() const { return mStreamDataOffset; }
VKDataBuffer* Buffer() const { return mBuffer->UniformBuffer; }
uint32_t BlockSize() const { return mBuffer->mBlockSize; }
uint32_t MaxStreamData() const { return mMaxStreamData; }
private:
VkStreamBuffer* mBuffer;
uint32_t mStreamDataSize;
uint32_t mMaxStreamData;
uint32_t mDataIndex;
uint32_t mStreamDataOffset;
};
class VkMatrixBufferWriter
{
public:
VkMatrixBufferWriter();
~VkMatrixBufferWriter();
bool Write(const VSMatrix& modelMatrix, bool modelMatrixEnabled, const VSMatrix& textureMatrix, bool textureMatrixEnabled);
void Reset();
uint32_t Offset() const { return mOffset; }
VKDataBuffer* Buffer() const { return mBuffer->UniformBuffer; }
private:
VkStreamBuffer* mBuffer;
MatricesUBO mMatrices = {};
VSMatrix mIdentityMatrix;
uint32_t mOffset = 0;
};

View file

@ -2,6 +2,9 @@
#include "vk_shader.h"
#include "vulkan/system/vk_builders.h"
#include "hwrenderer/utility/hw_shaderpatcher.h"
#include "rendering/vulkan/system/vk_framebuffer.h"
#include "rendering/vulkan/renderer/vk_streambuffer.h"
#include "rendering/vulkan/renderer/vk_renderstate.h"
#include "w_wad.h"
#include "doomerrors.h"
#include <ShaderLang.h>
@ -112,39 +115,6 @@ static const char *shaderBindings = R"(
mat4 TextureMatrix;
};
struct StreamData
{
vec4 uObjectColor;
vec4 uObjectColor2;
vec4 uDynLightColor;
vec4 uAddColor;
vec4 uTextureAddColor;
vec4 uTextureModulateColor;
vec4 uTextureBlendColor;
vec4 uFogColor;
float uDesaturationFactor;
float uInterpolationFactor;
float timer; // timer data for material shaders
int useVertexData;
vec4 uVertexColor;
vec4 uVertexNormal;
vec4 uGlowTopPlane;
vec4 uGlowTopColor;
vec4 uGlowBottomPlane;
vec4 uGlowBottomColor;
vec4 uGradientTopPlane;
vec4 uGradientBottomPlane;
vec4 uSplitTopPlane;
vec4 uSplitBottomPlane;
};
layout(set = 0, binding = 3, std140) uniform StreamUBO {
StreamData data[MAX_STREAM_DATA];
};
layout(set = 0, binding = 4) uniform sampler2D ShadowMap;
// textures
@ -155,30 +125,6 @@ static const char *shaderBindings = R"(
layout(set = 1, binding = 4) uniform sampler2D texture5;
layout(set = 1, binding = 5) uniform sampler2D texture6;
// This must match the PushConstants struct
layout(push_constant) uniform PushConstants
{
int uTextureMode;
float uAlphaThreshold;
vec2 uClipSplit;
// Lighting + Fog
float uLightLevel;
float uFogDensity;
float uLightFactor;
float uLightDist;
int uFogEnabled;
// dynamic lights
int uLightIndex;
// Blinn glossiness and specular level
vec2 uSpecularMaterial;
int uDataIndex;
int padding1, padding2, padding3;
};
// material types
#if defined(SPECULAR)
#define normaltexture texture2
@ -194,29 +140,6 @@ static const char *shaderBindings = R"(
#define brighttexture texture2
#endif
#define uObjectColor data[uDataIndex].uObjectColor
#define uObjectColor2 data[uDataIndex].uObjectColor2
#define uDynLightColor data[uDataIndex].uDynLightColor
#define uAddColor data[uDataIndex].uAddColor
#define uTextureBlendColor data[uDataIndex].uTextureBlendColor
#define uTextureModulateColor data[uDataIndex].uTextureModulateColor
#define uTextureAddColor data[uDataIndex].uTextureAddColor
#define uFogColor data[uDataIndex].uFogColor
#define uDesaturationFactor data[uDataIndex].uDesaturationFactor
#define uInterpolationFactor data[uDataIndex].uInterpolationFactor
#define timer data[uDataIndex].timer
#define useVertexData data[uDataIndex].useVertexData
#define uVertexColor data[uDataIndex].uVertexColor
#define uVertexNormal data[uDataIndex].uVertexNormal
#define uGlowTopPlane data[uDataIndex].uGlowTopPlane
#define uGlowTopColor data[uDataIndex].uGlowTopColor
#define uGlowBottomPlane data[uDataIndex].uGlowBottomPlane
#define uGlowBottomColor data[uDataIndex].uGlowBottomColor
#define uGradientTopPlane data[uDataIndex].uGradientTopPlane
#define uGradientBottomPlane data[uDataIndex].uGradientBottomPlane
#define uSplitTopPlane data[uDataIndex].uSplitTopPlane
#define uSplitBottomPlane data[uDataIndex].uSplitBottomPlane
#define SUPPORTS_SHADOWMAPS
#define VULKAN_COORDINATE_SYSTEM
#define HAS_UNIFORM_VERTEX_DATA
@ -233,13 +156,74 @@ static const char *shaderBindings = R"(
vec4 noise4(vec4) { return vec4(0); }
)";
static void AppendStructMembers(FString& code, UniformFamily family)
{
int index = 0;
for (const auto& info : GetVulkanFrameBuffer()->GetRenderState()->GetUniformInfo())
{
if (info.Name.empty())
I_FatalError("Missing uniform declaration for index %d", index);
index++;
if (info.Family == family)
{
static const char* glsltype[] = { "int", "uint", "float", "vec2", "vec3", "vec4", "ivec2", "ivec3", "ivec4", "uvec2", "uvec3", "uvec4", "mat4" };
code.AppendFormat("\t%s %s;\n", glsltype[(int)info.Type], info.Name.c_str());
}
}
}
static void AppendStructDefines(FString& code, UniformFamily family)
{
// Generate defines so the shader code can still access the uniforms as if they weren't part of the block:
for (const auto& info : GetVulkanFrameBuffer()->GetRenderState()->GetUniformInfo())
{
if (info.Family == family)
{
code.AppendFormat("#define %s data[uDataIndex].%s\n", info.Name.c_str(), info.Name.c_str());
}
}
}
static FString GetUniformBindings()
{
FString code;
// Uniform struct:
code << "struct StreamData\n";
code << "{\n";
AppendStructMembers(code, UniformFamily::Normal);
code << "};\n\n";
// Generate uniform block that holds multiple uniform structs:
code << "layout(set = 0, binding = 3, std140) uniform StreamUBO {\n";
code.AppendFormat("\tStreamData data[%d];\n", GetVulkanFrameBuffer()->StreamBufferWriter->MaxStreamData());
code << "};\n\n";
AppendStructDefines(code, UniformFamily::Normal);
// Generate push constants struct:
code << "layout(push_constant) uniform PushConstants\n";
code << "{\n";
AppendStructMembers(code, UniformFamily::PushConstant);
code << "};\n\n";
return code;
}
std::unique_ptr<VulkanShader> VkShaderManager::LoadVertShader(FString shadername, const char *vert_lump, const char *defines)
{
FString code = GetTargetGlslVersion();
code << defines;
code << "\n#define MAX_STREAM_DATA " << std::to_string(MAX_STREAM_DATA).c_str() << "\n";
code << shaderBindings;
if (!device->UsedDeviceFeatures.shaderClipDistance) code << "#define NO_CLIPDISTANCE_SUPPORT\n";
code << shaderBindings;
code << GetUniformBindings().GetChars();
code << "#line 1\n";
code << LoadPrivateShaderLump(vert_lump).GetChars() << "\n";
@ -251,14 +235,15 @@ std::unique_ptr<VulkanShader> VkShaderManager::LoadVertShader(FString shadername
std::unique_ptr<VulkanShader> VkShaderManager::LoadFragShader(FString shadername, const char *frag_lump, const char *material_lump, const char *light_lump, const char *defines, bool alphatest, bool gbufferpass)
{
FString code = GetTargetGlslVersion();
code << defines;
code << "\n#define MAX_STREAM_DATA " << std::to_string(MAX_STREAM_DATA).c_str() << "\n";
code << shaderBindings;
code << defines;
if (!device->UsedDeviceFeatures.shaderClipDistance) code << "#define NO_CLIPDISTANCE_SUPPORT\n";
if (!alphatest) code << "#define NO_ALPHATEST\n";
if (gbufferpass) code << "#define GBUFFER_PASS\n";
code << shaderBindings;
code << GetUniformBindings().GetChars();
code << "\n#line 1\n";
code << LoadPrivateShaderLump(frag_lump).GetChars() << "\n";

View file

@ -18,36 +18,6 @@ struct MatricesUBO
VSMatrix TextureMatrix;
};
#define MAX_STREAM_DATA ((int)(65536 / sizeof(StreamData)))
struct StreamUBO
{
StreamData data[MAX_STREAM_DATA];
};
struct PushConstants
{
int uTextureMode;
float uAlphaThreshold;
FVector2 uClipSplit;
// Lighting + Fog
float uLightLevel;
float uFogDensity;
float uLightFactor;
float uLightDist;
int uFogEnabled;
// dynamic lights
int uLightIndex;
// Blinn glossiness and specular level
FVector2 uSpecularMaterial;
int uDataIndex;
int padding1, padding2, padding3;
};
class VkShaderProgram
{
public:

View file

@ -109,8 +109,8 @@ VulkanFrameBuffer::~VulkanFrameBuffer()
VKBuffer::ResetAll();
PPResource::ResetAll();
delete MatrixBuffer;
delete StreamBuffer;
delete MatrixBufferWriter;
delete StreamBufferWriter;
delete mVertexData;
delete mSkyData;
delete mViewpoints;
@ -161,19 +161,19 @@ void VulkanFrameBuffer::InitializeState()
CreateFanToTrisIndexBuffer();
// To do: move this to HW renderer interface maybe?
MatrixBuffer = new VkStreamBuffer(sizeof(MatricesUBO), 50000);
StreamBuffer = new VkStreamBuffer(sizeof(StreamUBO), 300);
mShaderManager.reset(new VkShaderManager(device));
mSamplerManager.reset(new VkSamplerManager(device));
mRenderPassManager->Init();
#ifdef __APPLE__
mRenderState.reset(new VkRenderStateMolten());
#else
mRenderState.reset(new VkRenderState());
#endif
StreamBufferWriter = new VkStreamBufferWriter();
MatrixBufferWriter = new VkMatrixBufferWriter();
mShaderManager.reset(new VkShaderManager(device));
mSamplerManager.reset(new VkSamplerManager(device));
mRenderPassManager->Init();
if (device->graphicsTimeQueries)
{
QueryPoolBuilder querybuilder;

View file

@ -14,6 +14,8 @@ class VKDataBuffer;
class VkHardwareTexture;
class VkRenderBuffers;
class VkPostprocess;
class VkStreamBufferWriter;
class VkMatrixBufferWriter;
class SWSceneDrawer;
class VulkanFrameBuffer : public SystemBaseFrameBuffer
@ -42,8 +44,8 @@ public:
VKDataBuffer *ViewpointUBO = nullptr;
VKDataBuffer *LightBufferSSO = nullptr;
VkStreamBuffer *MatrixBuffer = nullptr;
VkStreamBuffer *StreamBuffer = nullptr;
VkStreamBufferWriter *StreamBufferWriter = nullptr;
VkMatrixBufferWriter *MatrixBufferWriter = nullptr;
VKDataBuffer *LightNodes = nullptr;
VKDataBuffer *LightLines = nullptr;