- make shaderClipDistance optional

This commit is contained in:
Magnus Norddahl 2019-03-25 19:44:46 +01:00
parent be74675e5e
commit 2d8516b2ca
5 changed files with 50 additions and 20 deletions

View file

@ -220,6 +220,7 @@ std::unique_ptr<VulkanShader> VkShaderManager::LoadVertShader(FString shadername
{
FString code = GetTargetGlslVersion();
code << defines << shaderBindings;
if (!device->UsedDeviceFeatures.shaderClipDistance) code << "#define NO_CLIPDISTANCE_SUPPORT\n";
code << "#line 1\n";
code << LoadPrivateShaderLump(vert_lump).GetChars() << "\n";
@ -233,6 +234,7 @@ std::unique_ptr<VulkanShader> VkShaderManager::LoadFragShader(FString shadername
FString code = GetTargetGlslVersion();
code << defines << shaderBindings;
if (!device->UsedDeviceFeatures.shaderClipDistance) code << "#define NO_CLIPDISTANCE_SUPPORT\n";
if (!alphatest) code << "#define NO_ALPHATEST\n";
if (gbufferpass) code << "#define GBUFFER_PASS\n";

View file

@ -75,13 +75,8 @@ VulkanDevice::VulkanDevice()
InitVolk();
CreateInstance();
CreateSurface();
UsedDeviceFeatures.samplerAnisotropy = VK_TRUE;
UsedDeviceFeatures.fragmentStoresAndAtomics = VK_TRUE;
UsedDeviceFeatures.depthClamp = VK_TRUE;
UsedDeviceFeatures.shaderClipDistance = VK_TRUE;
SelectPhysicalDevice();
SelectFeatures();
CreateDevice();
CreateAllocator();
}
@ -97,13 +92,20 @@ VulkanDevice::~VulkanDevice()
ReleaseResources();
}
bool VulkanDevice::CheckFeatures(const VkPhysicalDeviceFeatures &f)
void VulkanDevice::SelectFeatures()
{
UsedDeviceFeatures.samplerAnisotropy = PhysicalDevice.Features.samplerAnisotropy;
UsedDeviceFeatures.fragmentStoresAndAtomics = PhysicalDevice.Features.fragmentStoresAndAtomics;
UsedDeviceFeatures.depthClamp = PhysicalDevice.Features.depthClamp;
UsedDeviceFeatures.shaderClipDistance = PhysicalDevice.Features.shaderClipDistance;
}
bool VulkanDevice::CheckRequiredFeatures(const VkPhysicalDeviceFeatures &f)
{
return
f.samplerAnisotropy == VK_TRUE &&
f.fragmentStoresAndAtomics == VK_TRUE &&
f.depthClamp == VK_TRUE &&
f.shaderClipDistance == VK_TRUE;
f.depthClamp == VK_TRUE;
}
void VulkanDevice::SelectPhysicalDevice()
@ -114,7 +116,7 @@ void VulkanDevice::SelectPhysicalDevice()
{
const auto &info = AvailableDevices[idx];
if (!CheckFeatures(info.Features))
if (!CheckRequiredFeatures(info.Features))
continue;
VulkanCompatibleDevice dev;

View file

@ -87,7 +87,8 @@ private:
void CreateAllocator();
void ReleaseResources();
static bool CheckFeatures(const VkPhysicalDeviceFeatures &f);
void SelectFeatures();
static bool CheckRequiredFeatures(const VkPhysicalDeviceFeatures &f);
VkDebugUtilsMessengerEXT debugMessenger = VK_NULL_HANDLE;

View file

@ -10,6 +10,11 @@ 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
layout(location=0) out vec4 FragColor;
#ifdef GBUFFER_PASS
layout(location=1) out vec4 FragFog;
@ -542,6 +547,10 @@ vec3 AmbientOcclusionColor()
void main()
{
#ifdef NO_CLIPDISTANCE_SUPPORT
if (ClipDistanceA.x < 0 || ClipDistanceA.y < 0 || ClipDistanceA.z < 0 || ClipDistanceA.w < 0 || ClipDistanceB.x < 0) discard;
#endif
Material material = ProcessMaterial();
vec4 frag = material.Base;

View file

@ -18,6 +18,22 @@ 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;
#define ClipDistance0 ClipDistanceA.x
#define ClipDistance1 ClipDistanceA.y
#define ClipDistance2 ClipDistanceA.z
#define ClipDistance3 ClipDistanceA.w
#define ClipDistance4 ClipDistanceB.x
#else
#define ClipDistance0 gl_ClipDistance[0]
#define ClipDistance1 gl_ClipDistance[1]
#define ClipDistance2 gl_ClipDistance[2]
#define ClipDistance3 gl_ClipDistance[3]
#define ClipDistance4 gl_ClipDistance[4]
#endif
void main()
{
vec2 parmTexCoord;
@ -67,8 +83,8 @@ void main()
if (uSplitBottomPlane.z != 0.0)
{
gl_ClipDistance[3] = ((uSplitTopPlane.w + uSplitTopPlane.x * worldcoord.x + uSplitTopPlane.y * worldcoord.z) * uSplitTopPlane.z) - worldcoord.y;
gl_ClipDistance[4] = worldcoord.y - ((uSplitBottomPlane.w + uSplitBottomPlane.x * worldcoord.x + uSplitBottomPlane.y * worldcoord.z) * uSplitBottomPlane.z);
ClipDistance3 = ((uSplitTopPlane.w + uSplitTopPlane.x * worldcoord.x + uSplitTopPlane.y * worldcoord.z) * uSplitTopPlane.z) - worldcoord.y;
ClipDistance4 = worldcoord.y - ((uSplitBottomPlane.w + uSplitBottomPlane.x * worldcoord.x + uSplitBottomPlane.y * worldcoord.z) * uSplitBottomPlane.z);
}
#ifdef HAS_UNIFORM_VERTEX_DATA
@ -101,25 +117,25 @@ void main()
if (uClipHeightDirection != 0.0) // clip planes used for reflective flats
{
gl_ClipDistance[0] = (worldcoord.y - uClipHeight) * uClipHeightDirection;
ClipDistance0 = (worldcoord.y - uClipHeight) * uClipHeightDirection;
}
else if (uClipLine.x > -1000000.0) // and for line portals - this will never be active at the same time as the reflective planes clipping so it can use the same hardware clip plane.
{
gl_ClipDistance[0] = -( (worldcoord.z - uClipLine.y) * uClipLine.z + (uClipLine.x - worldcoord.x) * uClipLine.w ) + 1.0/32768.0; // allow a tiny bit of imprecisions for colinear linedefs.
ClipDistance0 = -( (worldcoord.z - uClipLine.y) * uClipLine.z + (uClipLine.x - worldcoord.x) * uClipLine.w ) + 1.0/32768.0; // allow a tiny bit of imprecisions for colinear linedefs.
}
else
{
gl_ClipDistance[0] = 1;
ClipDistance0 = 1;
}
// clip planes used for translucency splitting
gl_ClipDistance[1] = worldcoord.y - uClipSplit.x;
gl_ClipDistance[2] = uClipSplit.y - worldcoord.y;
ClipDistance1 = worldcoord.y - uClipSplit.x;
ClipDistance2 = uClipSplit.y - worldcoord.y;
if (uSplitTopPlane == vec4(0.0))
{
gl_ClipDistance[3] = 1;
gl_ClipDistance[4] = 1;
ClipDistance3 = 1.0;
ClipDistance4 = 1.0;
}
gl_PointSize = 1.0;