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

View file

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

View file

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

View file

@ -10,6 +10,11 @@ layout(location = 5) in vec4 vWorldNormal;
layout(location = 6) in vec4 vEyeNormal; layout(location = 6) in vec4 vEyeNormal;
#endif #endif
#ifdef NO_CLIPDISTANCE_SUPPORT
layout(location = 7) in vec4 ClipDistanceA;
layout(location = 8) in vec4 ClipDistanceB;
#endif
layout(location=0) out vec4 FragColor; layout(location=0) out vec4 FragColor;
#ifdef GBUFFER_PASS #ifdef GBUFFER_PASS
layout(location=1) out vec4 FragFog; layout(location=1) out vec4 FragFog;
@ -542,6 +547,10 @@ vec3 AmbientOcclusionColor()
void main() 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(); Material material = ProcessMaterial();
vec4 frag = material.Base; vec4 frag = material.Base;

View file

@ -18,6 +18,22 @@ layout(location = 5) out vec4 vWorldNormal;
layout(location = 6) out vec4 vEyeNormal; layout(location = 6) out vec4 vEyeNormal;
#endif #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() void main()
{ {
vec2 parmTexCoord; vec2 parmTexCoord;
@ -67,8 +83,8 @@ void main()
if (uSplitBottomPlane.z != 0.0) if (uSplitBottomPlane.z != 0.0)
{ {
gl_ClipDistance[3] = ((uSplitTopPlane.w + uSplitTopPlane.x * worldcoord.x + uSplitTopPlane.y * worldcoord.z) * uSplitTopPlane.z) - worldcoord.y; ClipDistance3 = ((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); ClipDistance4 = worldcoord.y - ((uSplitBottomPlane.w + uSplitBottomPlane.x * worldcoord.x + uSplitBottomPlane.y * worldcoord.z) * uSplitBottomPlane.z);
} }
#ifdef HAS_UNIFORM_VERTEX_DATA #ifdef HAS_UNIFORM_VERTEX_DATA
@ -101,25 +117,25 @@ void main()
if (uClipHeightDirection != 0.0) // clip planes used for reflective flats 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. 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 else
{ {
gl_ClipDistance[0] = 1; ClipDistance0 = 1;
} }
// clip planes used for translucency splitting // clip planes used for translucency splitting
gl_ClipDistance[1] = worldcoord.y - uClipSplit.x; ClipDistance1 = worldcoord.y - uClipSplit.x;
gl_ClipDistance[2] = uClipSplit.y - worldcoord.y; ClipDistance2 = uClipSplit.y - worldcoord.y;
if (uSplitTopPlane == vec4(0.0)) if (uSplitTopPlane == vec4(0.0))
{ {
gl_ClipDistance[3] = 1; ClipDistance3 = 1.0;
gl_ClipDistance[4] = 1; ClipDistance4 = 1.0;
} }
gl_PointSize = 1.0; gl_PointSize = 1.0;