- compile main.vp and main.fp for vulkan

This commit is contained in:
Magnus Norddahl 2019-02-22 11:30:48 +01:00
parent a97d736bd9
commit 52460d53d9
5 changed files with 231 additions and 35 deletions

View file

@ -1,32 +1,209 @@
#include "vk_shader.h"
#include "vulkan/system/vk_builders.h"
#include "hwrenderer/utility/hw_shaderpatcher.h"
#include "w_wad.h"
#include "doomerrors.h"
#include <ShaderLang.h>
VkShaderManager::VkShaderManager()
VkShaderManager::VkShaderManager(VulkanDevice *device) : device(device)
{
ShInitialize();
#if 0
{
const char *lumpName = "shaders/glsl/screenquad.vp";
int lump = Wads.CheckNumForFullName(lumpName, 0);
if (lump == -1) I_FatalError("Unable to load '%s'", lumpName);
FString code = Wads.ReadLump(lump).GetString().GetChars();
FString patchedCode;
patchedCode.AppendFormat("#version %d\n", 450);
patchedCode << "#line 1\n";
patchedCode << code;
ShaderBuilder builder;
builder.setVertexShader(patchedCode);
auto shader = builder.create(dev);
}
#endif
vert = LoadVertShader("shaders/glsl/main.vp", "");
frag = LoadFragShader("shaders/glsl/main.fp", "shaders/glsl/func_normal.fp", "shaders/glsl/material_normal.fp", "");
}
VkShaderManager::~VkShaderManager()
{
ShFinalize();
}
static const char *shaderBindings = R"(
// This must match the HWViewpointUniforms struct
layout(set = 0, binding = 0, std140) uniform ViewpointUBO {
mat4 ProjectionMatrix;
mat4 ViewMatrix;
mat4 NormalViewMatrix;
vec4 uCameraPos;
vec4 uClipLine;
float uGlobVis; // uGlobVis = R_GetGlobVis(r_visibility) / 32.0
int uPalLightLevels;
int uViewHeight; // Software fuzz scaling
float uClipHeight;
float uClipHeightDirection;
int uShadowmapFilter;
float timer; // timer data for material shaders
};
// light buffers
layout(set = 0, binding = 1, std430) buffer LightBufferSSO
{
vec4 lights[];
};
// textures
layout(set = 1, binding = 0) uniform sampler2D tex;
layout(set = 1, binding = 1) uniform sampler2D texture2;
layout(set = 1, binding = 2) uniform sampler2D texture3;
layout(set = 1, binding = 3) uniform sampler2D texture4;
layout(set = 1, binding = 4) uniform sampler2D texture5;
layout(set = 1, binding = 5) uniform sampler2D texture6;
layout(set = 1, binding = 16) uniform sampler2D ShadowMap;
// This must match the PushConstants struct
layout(push_constant, std140) uniform PushConstants
{
int uTextureMode;
vec2 uClipSplit;
float uAlphaThreshold;
// colors
vec4 uObjectColor;
vec4 uObjectColor2;
vec4 uDynLightColor;
vec4 uAddColor;
vec4 uFogColor;
float uDesaturationFactor;
float uInterpolationFactor;
// Glowing walls stuff
vec4 uGlowTopPlane;
vec4 uGlowTopColor;
vec4 uGlowBottomPlane;
vec4 uGlowBottomColor;
vec4 uGradientTopPlane;
vec4 uGradientBottomPlane;
vec4 uSplitTopPlane;
vec4 uSplitBottomPlane;
// Lighting + Fog
float uLightLevel;
float uFogDensity;
float uLightFactor;
float uLightDist;
int uFogEnabled;
// dynamic lights
int uLightIndex;
// Blinn glossiness and specular level
vec2 uSpecularMaterial;
// matrices
mat4 ModelMatrix;
mat4 NormalModelMatrix;
mat4 TextureMatrix;
};
// material types
#if defined(SPECULAR)
#define normaltexture texture2
#define speculartexture texture3
#define brighttexture texture4
#elif defined(PBR)
#define normaltexture texture2
#define metallictexture texture3
#define roughnesstexture texture4
#define aotexture texture5
#define brighttexture texture6
#else
#define brighttexture texture2
#endif
#define SUPPORTS_SHADOWMAPS
)";
std::unique_ptr<VulkanShader> VkShaderManager::LoadVertShader(const char *vert_lump, const char *defines)
{
FString code = GetTargetGlslVersion();
code << defines << shaderBindings;
code << "#line 1\n";
code << LoadShaderLump(vert_lump).GetChars() << "\n";
ShaderBuilder builder;
builder.setVertexShader(code);
return builder.create(device);
}
std::unique_ptr<VulkanShader> VkShaderManager::LoadFragShader(const char *frag_lump, const char *material_lump, const char *light_lump, const char *defines)
{
FString code = GetTargetGlslVersion();
code << defines << shaderBindings;
code << "\n#line 1\n";
code << LoadShaderLump(frag_lump).GetChars() << "\n";
if (material_lump)
{
if (material_lump[0] != '#')
{
FString pp_code = LoadShaderLump(material_lump);
if (pp_code.IndexOf("ProcessMaterial") < 0)
{
// this looks like an old custom hardware shader.
// add ProcessMaterial function that calls the older ProcessTexel function
code << "\n" << LoadShaderLump("shaders/glsl/func_defaultmat.fp").GetChars() << "\n";
if (pp_code.IndexOf("ProcessTexel") < 0)
{
// this looks like an even older custom hardware shader.
// We need to replace the ProcessTexel call to make it work.
code.Substitute("material.Base = ProcessTexel();", "material.Base = Process(vec4(1.0));");
}
if (pp_code.IndexOf("ProcessLight") >= 0)
{
// The ProcessLight signatured changed. Forward to the old one.
code << "\nvec4 ProcessLight(vec4 color);\n";
code << "\nvec4 ProcessLight(Material material, vec4 color) { return ProcessLight(color); }\n";
}
}
code << "\n#line 1\n";
code << RemoveLegacyUserUniforms(pp_code).GetChars();
code.Substitute("gl_TexCoord[0]", "vTexCoord"); // fix old custom shaders.
if (pp_code.IndexOf("ProcessLight") < 0)
{
code << "\n" << LoadShaderLump("shaders/glsl/func_defaultlight.fp").GetChars() << "\n";
}
}
else
{
// material_lump is not a lump name but the source itself (from generated shaders)
code << (material_lump + 1) << "\n";
}
}
if (light_lump)
{
code << "\n#line 1\n";
code << LoadShaderLump(light_lump).GetChars();
}
ShaderBuilder builder;
builder.setFragmentShader(code);
return builder.create(device);
}
FString VkShaderManager::GetTargetGlslVersion()
{
return "#version 450 core\n";
}
FString VkShaderManager::LoadShaderLump(const char *lumpname)
{
int lump = Wads.CheckNumForFullName(lumpname, 0);
if (lump == -1) I_Error("Unable to load '%s'", lumpname);
FMemLump data = Wads.ReadLump(lump);
return data.GetString();
}

View file

@ -5,6 +5,9 @@
#include "r_data/matrix.h"
#include "name.h"
class VulkanDevice;
class VulkanShader;
struct PushConstants
{
int uTextureMode;
@ -54,6 +57,18 @@ struct PushConstants
class VkShaderManager
{
public:
VkShaderManager();
VkShaderManager(VulkanDevice *device);
~VkShaderManager();
std::unique_ptr<VulkanShader> vert;
std::unique_ptr<VulkanShader> frag;
private:
std::unique_ptr<VulkanShader> LoadVertShader(const char *vert_lump, const char *defines);
std::unique_ptr<VulkanShader> LoadFragShader(const char *frag_lump, const char *material_lump, const char *light_lump, const char *defines);
FString GetTargetGlslVersion();
FString LoadShaderLump(const char *lumpname);
VulkanDevice *device;
};

View file

@ -71,7 +71,7 @@ void VulkanFrameBuffer::InitializeState()
mViewpoints = new GLViewpointBuffer;
mLights = new FLightBuffer();
mShaderManager.reset(new VkShaderManager());
mShaderManager.reset(new VkShaderManager(device));
mSamplerManager.reset(new VkSamplerManager(device));
mRenderState.reset(new VkRenderState());
}

View file

@ -1,11 +1,14 @@
in vec4 pixelpos;
in vec3 glowdist;
in vec3 gradientdist;
in vec4 vWorldNormal;
in vec4 vEyeNormal;
in vec4 vTexCoord;
in vec4 vColor;
layout(location = 0) in vec4 vTexCoord;
layout(location = 1) in vec4 vColor;
#ifndef SIMPLE // we do not need these for simple shaders
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
layout(location=0) out vec4 FragColor;
#ifdef GBUFFER_PASS

View file

@ -2,21 +2,22 @@
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;
#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;
out vec4 pixelpos;
out vec3 glowdist;
out vec3 gradientdist;
out vec4 vWorldNormal;
out vec4 vEyeNormal;
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
out vec4 vTexCoord;
out vec4 vColor;
void main()
{
vec2 parmTexCoord;