unify layouts (and move in/out variables to c++) in preparation for gpu sprite traces
This commit is contained in:
parent
8d0ab22e05
commit
998fdec6e8
6 changed files with 176 additions and 102 deletions
|
|
@ -172,8 +172,100 @@ VkShaderProgram* VkShaderManager::Get(const VkShaderKey& key)
|
|||
return &program;
|
||||
}
|
||||
|
||||
enum class FieldCondition
|
||||
{
|
||||
ALWAYS,
|
||||
NOTSIMPLE,
|
||||
HAS_CLIPDISTANCE,
|
||||
USELEVELMESH,
|
||||
GBUFFER_PASS,
|
||||
SHADE_VERTEX,
|
||||
};
|
||||
|
||||
struct BuiltinFieldDesc : public VaryingFieldDesc
|
||||
{
|
||||
FieldCondition cond;
|
||||
};
|
||||
|
||||
static std::vector<VaryingFieldDesc> vertexShaderInputs
|
||||
{
|
||||
{"aPosition", "", UniformType::Vec4}, //0, VATTR_VERTEX
|
||||
{"aTexCoord", "", UniformType::Vec2}, //1, VATTR_TEXCOORD
|
||||
{"aColor", "", UniformType::Vec4}, //2, VATTR_COLOR
|
||||
{"aVertex2", "", UniformType::Vec4}, //3, VATTR_VERTEX2
|
||||
{"aNormal", "", UniformType::Vec4}, //4, VATTR_NORMAL
|
||||
{"aNormal2", "", UniformType::Vec4}, //5, VATTR_NORMAL2
|
||||
{"aLightmap", "", UniformType::Vec2}, //6, VATTR_LIGHTMAP
|
||||
{"aBoneWeight", "", UniformType::Vec4}, //7, VATTR_BONEWEIGHT
|
||||
{"aBoneSelector", "", UniformType::UVec4}, //8, VATTR_BONESELECTOR
|
||||
{"aDataIndex", "", UniformType::Int}, //9, VATTR_UNIFORM_INDEXES
|
||||
};
|
||||
|
||||
static std::vector<BuiltinFieldDesc> vertexShaderOutputs
|
||||
{
|
||||
{"vTexCoord", "", UniformType::Vec4, FieldCondition::ALWAYS}, //0
|
||||
{"vColor", "", UniformType::Vec4, FieldCondition::ALWAYS}, //1
|
||||
{"pixelpos", "", UniformType::Vec4, FieldCondition::NOTSIMPLE}, //2
|
||||
{"glowdist", "", UniformType::Vec3, FieldCondition::NOTSIMPLE}, //3
|
||||
{"gradientdist", "", UniformType::Vec3, FieldCondition::NOTSIMPLE}, //4
|
||||
{"vWorldNormal", "", UniformType::Vec4, FieldCondition::NOTSIMPLE}, //5
|
||||
{"vEyeNormal", "", UniformType::Vec4, FieldCondition::NOTSIMPLE}, //6
|
||||
{"ClipDistanceA", "", UniformType::Vec4, FieldCondition::HAS_CLIPDISTANCE}, //7
|
||||
{"ClipDistanceB", "", UniformType::Vec4, FieldCondition::HAS_CLIPDISTANCE}, //8
|
||||
{"vLightmap", "", UniformType::Vec3, FieldCondition::ALWAYS}, //9
|
||||
{"uDataIndex", "flat", UniformType::Int, FieldCondition::USELEVELMESH}, //10
|
||||
};
|
||||
|
||||
static std::vector<BuiltinFieldDesc> fragShaderOutputs
|
||||
{
|
||||
{"FragColor", "", UniformType::Vec4, FieldCondition::ALWAYS}, //0
|
||||
{"FragFog", "", UniformType::Vec4, FieldCondition::GBUFFER_PASS}, //1
|
||||
{"FragNormal", "", UniformType::Vec4, FieldCondition::GBUFFER_PASS}, //2
|
||||
};
|
||||
|
||||
void AddFields(FString &layoutBlock, int &index, bool is_in, const std::vector<VaryingFieldDesc> &fields)
|
||||
{
|
||||
for(auto &field : fields)
|
||||
{
|
||||
layoutBlock.AppendFormat("layout(location = %d) %s %s %s %s;\n", index, field.Property.GetChars(), is_in ? "in" : "out", GetTypeStr(field.Type), field.Name.GetChars());
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
void AddBuiltinFields(FString &layoutBlock, int &index, bool is_in, const std::vector<BuiltinFieldDesc> &fields, const VkShaderKey& key, bool hasClipDistance)
|
||||
{
|
||||
for(auto &field : fields)
|
||||
{
|
||||
switch(field.cond)
|
||||
{
|
||||
case FieldCondition::NOTSIMPLE:
|
||||
if(key.Simple) continue;
|
||||
break;
|
||||
case FieldCondition::HAS_CLIPDISTANCE:
|
||||
if(!hasClipDistance) continue;
|
||||
break;
|
||||
case FieldCondition::GBUFFER_PASS:
|
||||
if(!key.GBufferPass) continue;
|
||||
break;
|
||||
case FieldCondition::USELEVELMESH:
|
||||
if(!key.UseLevelMesh) continue;
|
||||
break;
|
||||
case FieldCondition::SHADE_VERTEX:
|
||||
if(!key.ShadeVertex) continue;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
layoutBlock.AppendFormat("layout(location = %d) %s %s %s %s;\n", index, field.Property.GetChars(), is_in ? "in" : "out", GetTypeStr(field.Type), field.Name.GetChars());
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
void VkShaderManager::BuildLayoutBlock(FString &layoutBlock, bool isFrag, const VkShaderKey& key, const UserShaderDesc *shader)
|
||||
{
|
||||
bool hasClipDistance = fb->GetDevice()->EnabledFeatures.Features.shaderClipDistance;
|
||||
|
||||
layoutBlock << "// This must match the PushConstants struct\n";
|
||||
layoutBlock << "layout(push_constant) uniform PushConstants\n";
|
||||
layoutBlock << "{\n";
|
||||
|
|
@ -198,15 +290,31 @@ void VkShaderManager::BuildLayoutBlock(FString &layoutBlock, bool isFrag, const
|
|||
}
|
||||
}
|
||||
layoutBlock << "};\n";
|
||||
layoutBlock << "#line 1\n";
|
||||
|
||||
layoutBlock << LoadPrivateShaderLump("shaders/scene/layout_shared.glsl").GetChars() << "\n";
|
||||
layoutBlock << LoadPrivateShaderLump(isFrag ? "shaders/scene/layout_frag.glsl" : "shaders/scene/layout_vert.glsl").GetChars() << "\n";
|
||||
|
||||
int varyingLocation = 11;
|
||||
if(shader) for(auto &varying : shader->Varyings)
|
||||
if(!isFrag)
|
||||
{
|
||||
layoutBlock.AppendFormat("layout(location = %d) %s %s %s %s;\n", varyingLocation, varying.Property.GetChars(), isFrag ? "in" : "out", GetTypeStr(varying.Type), varying.Name.GetChars());
|
||||
varyingLocation++;
|
||||
int index = 0;
|
||||
AddFields(layoutBlock, index, true, vertexShaderInputs);
|
||||
}
|
||||
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
AddBuiltinFields(layoutBlock, index, isFrag, vertexShaderOutputs, key, hasClipDistance);
|
||||
|
||||
if(shader)
|
||||
{
|
||||
AddFields(layoutBlock, index, isFrag, shader->Varyings);
|
||||
}
|
||||
}
|
||||
|
||||
if(isFrag)
|
||||
{
|
||||
int index = 0;
|
||||
AddBuiltinFields(layoutBlock, index, false, fragShaderOutputs, key, hasClipDistance);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -223,6 +331,11 @@ void VkShaderManager::BuildDefinesBlock(FString &definesBlock, const char *defin
|
|||
definesBlock << "#define MAX_LIGHT_DATA " << std::to_string(MAX_LIGHT_DATA).c_str() << "\n";
|
||||
definesBlock << "#define MAX_FOGBALL_DATA " << std::to_string(MAX_FOGBALL_DATA).c_str() << "\n";
|
||||
|
||||
if(isFrag)
|
||||
{
|
||||
definesBlock << "#define FRAGSHADER\n";
|
||||
}
|
||||
|
||||
#ifdef NPOT_EMULATION
|
||||
definesBlock << "#define NPOT_EMULATION\n";
|
||||
#endif
|
||||
|
|
@ -235,7 +348,8 @@ void VkShaderManager::BuildDefinesBlock(FString &definesBlock, const char *defin
|
|||
if (!key.AlphaTest) definesBlock << "#define NO_ALPHATEST\n";
|
||||
if (key.GBufferPass) definesBlock << "#define GBUFFER_PASS\n";
|
||||
if (key.AlphaTestOnly) definesBlock << "#define ALPHATEST_ONLY\n";
|
||||
if (key.Simple3D) definesBlock << "#define SIMPLE\n#define SIMPLE3D\n";
|
||||
if (key.Simple) definesBlock << "#define SIMPLE\n";
|
||||
if (key.Simple3D) definesBlock << "#define SIMPLE3D\n";
|
||||
|
||||
switch(key.LightBlendMode)
|
||||
{
|
||||
|
|
@ -304,6 +418,14 @@ void VkShaderManager::BuildDefinesBlock(FString &definesBlock, const char *defin
|
|||
if (key.SWLightBanded) definesBlock << "#define SWLIGHT_BANDED\n";
|
||||
if (key.FogBalls) definesBlock << "#define FOGBALLS\n";
|
||||
|
||||
|
||||
switch (key.ShadeVertex)
|
||||
{
|
||||
case 1: definesBlock << "#define SHADE_VERTEX\n"; break;
|
||||
case 2: definesBlock << "#define SHADE_VERTEX_CENTER\n"; break;
|
||||
//case 3: definesBlock << "#define ???\n"; break;
|
||||
}
|
||||
|
||||
definesBlock << ((key.Simple2D) ? "#define uFogEnabled -3\n" : "#define uFogEnabled 0\n");
|
||||
|
||||
}
|
||||
|
|
@ -334,7 +456,7 @@ std::unique_ptr<VulkanShader> VkShaderManager::LoadVertShader(FString shadername
|
|||
.DebugName(shadername.GetChars())
|
||||
.AddSource("VersionBlock", GetVersionBlock().GetChars())
|
||||
.AddSource("DefinesBlock", definesBlock.GetChars())
|
||||
.AddSource("LayoutBlock", layoutBlock.GetChars())
|
||||
.AddSource("shaders/scene/layout_shared.glsl", layoutBlock.GetChars())
|
||||
.AddSource(vert_lump_custom ? vert_lump_custom : vert_lump, codeBlock.GetChars())
|
||||
.OnIncludeLocal([=](std::string headerName, std::string includerName, size_t depth) { return OnInclude(headerName.c_str(), includerName.c_str(), depth, false); })
|
||||
.OnIncludeSystem([=](std::string headerName, std::string includerName, size_t depth) { return OnInclude(headerName.c_str(), includerName.c_str(), depth, true); })
|
||||
|
|
|
|||
|
|
@ -80,7 +80,9 @@ public:
|
|||
struct
|
||||
{
|
||||
uint64_t AlphaTest : 1; // !NO_ALPHATEST
|
||||
uint64_t Simple2D : 1; // uFogEnabled == -3
|
||||
uint64_t Simple : 1; // SIMPLE
|
||||
uint64_t Simple2D : 1; // SIMPLE2D, uFogEnabled == -3
|
||||
uint64_t Simple3D : 1; // SIMPLE3D
|
||||
uint64_t TextureMode : 3; // uTextureMode & 0xffff
|
||||
uint64_t ClampY : 1; // uTextureMode & TEXF_ClampY
|
||||
uint64_t Brightmap : 1; // uTextureMode & TEXF_Brightmap
|
||||
|
|
@ -104,8 +106,8 @@ public:
|
|||
uint64_t LightAttenuationMode : 1; // LIGHT_ATTENUATION_LINEAR , LIGHT_ATTENUATION_INVERSE_SQUARE
|
||||
uint64_t UseRaytracePrecise : 1; // USE_RAYTRACE_PRECISE
|
||||
uint64_t ShadowmapFilter : 4; // SHADOWMAP_FILTER
|
||||
uint64_t Simple3D : 1; // SIMPLE3D
|
||||
uint64_t Unused : 31;
|
||||
uint64_t ShadeVertex : 2; // 0 = nothing, 1 = SHADE_VERTEX, 2 = SHADE_VERTEX_CENTER
|
||||
uint64_t Unused : 28;
|
||||
};
|
||||
uint64_t AsQWORD = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -264,6 +264,7 @@ void VkRenderState::ApplyRenderPass(int dt)
|
|||
{
|
||||
pipelineKey.ShaderKey.SpecialEffect = mSpecialEffect;
|
||||
pipelineKey.ShaderKey.EffectState = 0;
|
||||
pipelineKey.ShaderKey.Simple = (mSpecialEffect == EFF_BURN || mSpecialEffect == EFF_STENCIL || mSpecialEffect == EFF_PORTAL);
|
||||
pipelineKey.ShaderKey.AlphaTest = false;
|
||||
}
|
||||
else
|
||||
|
|
@ -274,6 +275,9 @@ void VkRenderState::ApplyRenderPass(int dt)
|
|||
if (r_skipmats && pipelineKey.ShaderKey.EffectState >= 3 && pipelineKey.ShaderKey.EffectState <= 4)
|
||||
pipelineKey.ShaderKey.EffectState = 0;
|
||||
pipelineKey.ShaderKey.AlphaTest = mSurfaceUniforms.uAlphaThreshold >= 0.f;
|
||||
|
||||
pipelineKey.ShaderKey.Simple = mWireframe;
|
||||
pipelineKey.ShaderKey.Simple3D = mWireframe; // simple notexture drawing for wireframe
|
||||
}
|
||||
|
||||
int uTextureMode = GetTextureModeAndFlags((mMaterial.mMaterial && mMaterial.mMaterial->Source()->isHardwareCanvas()) ? TM_OPAQUE : TM_NORMAL);
|
||||
|
|
@ -283,8 +287,6 @@ void VkRenderState::ApplyRenderPass(int dt)
|
|||
pipelineKey.ShaderKey.Detailmap = (uTextureMode & TEXF_Detailmap) != 0;
|
||||
pipelineKey.ShaderKey.Glowmap = (uTextureMode & TEXF_Glowmap) != 0;
|
||||
|
||||
pipelineKey.ShaderKey.Simple3D = mWireframe; // simple notexture drawing for wireframe
|
||||
|
||||
pipelineKey.ShaderKey.DepthFadeThreshold = mSurfaceUniforms.uDepthFadeThreshold > 0.0f;
|
||||
|
||||
// The way GZDoom handles state is just plain insanity!
|
||||
|
|
|
|||
|
|
@ -1,57 +0,0 @@
|
|||
|
||||
layout(location = 0) in vec4 vTexCoord;
|
||||
layout(location = 1) in vec4 vColor;
|
||||
layout(location = 9) in vec3 vLightmap;
|
||||
|
||||
#ifndef SIMPLE
|
||||
layout(location = 2) in vec4 pixelpos;
|
||||
layout(location = 3) in vec3 glowdist;
|
||||
layout(location = 4) in vec3 gradientdist;
|
||||
layout(location = 5) in vec4 vWorldNormal;
|
||||
layout(location = 6) in vec4 vEyeNormal;
|
||||
#endif
|
||||
|
||||
#ifdef NO_CLIPDISTANCE_SUPPORT
|
||||
layout(location = 7) in vec4 ClipDistanceA;
|
||||
layout(location = 8) in vec4 ClipDistanceB;
|
||||
#endif
|
||||
|
||||
#if defined(USE_LEVELMESH)
|
||||
layout(location = 10) in flat int uDataIndex;
|
||||
#endif
|
||||
|
||||
layout(location=0) out vec4 FragColor;
|
||||
#ifdef GBUFFER_PASS
|
||||
layout(location=1) out vec4 FragFog;
|
||||
layout(location=2) out vec4 FragNormal;
|
||||
#endif
|
||||
|
||||
vec4 texture(int index, vec2 p)
|
||||
{
|
||||
return texture(textures[uTextureIndex + index], p);
|
||||
}
|
||||
|
||||
vec4 texture(int index, vec2 p, float bias)
|
||||
{
|
||||
return texture(textures[uTextureIndex + index], p, bias);
|
||||
}
|
||||
|
||||
ivec2 textureSize(int index, int lod)
|
||||
{
|
||||
return textureSize(textures[uTextureIndex + index], lod);
|
||||
}
|
||||
|
||||
vec4 textureGrad(int index, vec2 P, vec2 dPdx, vec2 dPdy)
|
||||
{
|
||||
return textureGrad(textures[uTextureIndex + index], P, dPdx, dPdy);
|
||||
}
|
||||
|
||||
vec4 textureLod(int index, vec2 P, float lod)
|
||||
{
|
||||
return textureLod(textures[uTextureIndex + index], P, lod);
|
||||
}
|
||||
|
||||
vec4 texelFetch(int index, ivec2 P, int lod)
|
||||
{
|
||||
return texelFetch(textures[uTextureIndex + index], P, lod);
|
||||
}
|
||||
|
|
@ -81,3 +81,41 @@ float noise1(float) { return 0; }
|
|||
vec2 noise2(vec2) { return vec2(0); }
|
||||
vec3 noise3(vec3) { return vec3(0); }
|
||||
vec4 noise4(vec4) { return vec4(0); }
|
||||
|
||||
vec4 texture(int index, vec2 p)
|
||||
{
|
||||
#ifndef FRAGSHADER
|
||||
return textureLod(textures[uTextureIndex + index], p, 0.0);
|
||||
#else
|
||||
return texture(textures[uTextureIndex + index], p);
|
||||
#endif
|
||||
}
|
||||
|
||||
vec4 texture(int index, vec2 p, float bias)
|
||||
{
|
||||
#ifndef FRAGSHADER
|
||||
return textureLod(textures[uTextureIndex + index], p, 0.0);
|
||||
#else
|
||||
return texture(textures[uTextureIndex + index], p, bias);
|
||||
#endif
|
||||
}
|
||||
|
||||
ivec2 textureSize(int index, int lod)
|
||||
{
|
||||
return textureSize(textures[uTextureIndex + index], lod);
|
||||
}
|
||||
|
||||
vec4 textureGrad(int index, vec2 P, vec2 dPdx, vec2 dPdy)
|
||||
{
|
||||
return textureGrad(textures[uTextureIndex + index], P, dPdx, dPdy);
|
||||
}
|
||||
|
||||
vec4 textureLod(int index, vec2 P, float lod)
|
||||
{
|
||||
return textureLod(textures[uTextureIndex + index], P, lod);
|
||||
}
|
||||
|
||||
vec4 texelFetch(int index, ivec2 P, int lod)
|
||||
{
|
||||
return texelFetch(textures[uTextureIndex + index], P, lod);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,33 +0,0 @@
|
|||
|
||||
layout(location = 0) in vec4 aPosition;
|
||||
layout(location = 1) in vec2 aTexCoord;
|
||||
layout(location = 2) in vec4 aColor;
|
||||
|
||||
layout(location = 0) out vec4 vTexCoord;
|
||||
layout(location = 1) out vec4 vColor;
|
||||
layout(location = 9) out vec3 vLightmap;
|
||||
|
||||
#ifndef SIMPLE // we do not need these for simple shaders
|
||||
layout(location = 3) in vec4 aVertex2;
|
||||
layout(location = 4) in vec4 aNormal;
|
||||
layout(location = 5) in vec4 aNormal2;
|
||||
layout(location = 6) in vec2 aLightmap;
|
||||
layout(location = 7) in vec4 aBoneWeight;
|
||||
layout(location = 8) in uvec4 aBoneSelector;
|
||||
|
||||
layout(location = 2) out vec4 pixelpos;
|
||||
layout(location = 3) out vec3 glowdist;
|
||||
layout(location = 4) out vec3 gradientdist;
|
||||
layout(location = 5) out vec4 vWorldNormal;
|
||||
layout(location = 6) out vec4 vEyeNormal;
|
||||
#endif
|
||||
|
||||
#ifdef NO_CLIPDISTANCE_SUPPORT
|
||||
layout(location = 7) out vec4 ClipDistanceA;
|
||||
layout(location = 8) out vec4 ClipDistanceB;
|
||||
#endif
|
||||
|
||||
#if defined(USE_LEVELMESH)
|
||||
layout(location = 9) in int aDataIndex;
|
||||
layout(location = 10) out flat int uDataIndex;
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue