From 369c19bd5d5c08f808ef11769ae35cda1469a99b Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sat, 30 Mar 2024 18:46:37 +0100 Subject: [PATCH] Add statically disabled tessellation on macOS/iOS --- Source/Engine/Graphics/Config.h | 17 +++++++++++------ .../Materials/DeferredMaterialShader.cpp | 2 ++ .../Materials/DeformableMaterialShader.cpp | 2 ++ .../Materials/ForwardMaterialShader.cpp | 2 ++ .../Materials/TerrainMaterialShader.cpp | 2 ++ Source/Engine/Graphics/Shaders/GPUShader.cpp | 4 ++++ .../DirectX/DX11/GPUDeviceDX11.cpp | 2 +- .../DirectX/DX12/GPUDeviceDX12.cpp | 2 +- .../GraphicsDevice/Vulkan/DescriptorSetVulkan.h | 16 +++++++++------- .../GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp | 6 +++--- .../Vulkan/GPUPipelineStateVulkan.cpp | 8 ++++++-- .../Vulkan/GPUPipelineStateVulkan.h | 2 ++ Source/Engine/Platform/Mac/MacDefines.h | 3 +++ Source/Engine/Platform/iOS/iOSDefines.h | 3 +++ 14 files changed, 51 insertions(+), 20 deletions(-) diff --git a/Source/Engine/Graphics/Config.h b/Source/Engine/Graphics/Config.h index e55e2ecf4..f78ea2568 100644 --- a/Source/Engine/Graphics/Config.h +++ b/Source/Engine/Graphics/Config.h @@ -40,13 +40,23 @@ // True if allow graphics profile events and markers #define GPU_ALLOW_PROFILE_EVENTS (!BUILD_RELEASE) +// True if allow hardware tessellation shaders (Hull and Domain shaders) +#ifndef GPU_ALLOW_TESSELLATION_SHADERS +#define GPU_ALLOW_TESSELLATION_SHADERS 1 +#endif + // Enable/disable creating GPU resources on separate threads (otherwise only the main thread can be used) #define GPU_ENABLE_ASYNC_RESOURCES_CREATION 1 // Enable/disable force shaders recompilation #define GPU_FORCE_RECOMPILE_SHADERS 0 -// Default back buffer pixel format +// Define default back buffer(s) format +#ifndef GPU_BACK_BUFFER_PIXEL_FORMAT +#define GPU_BACK_BUFFER_PIXEL_FORMAT PixelFormat::B8G8R8A8_UNorm +#endif + +// Default depth buffer pixel format #ifndef GPU_DEPTH_BUFFER_PIXEL_FORMAT #define GPU_DEPTH_BUFFER_PIXEL_FORMAT PixelFormat::D32_Float #endif @@ -62,11 +72,6 @@ #define GPU_MAX_TEXTURE_MIP_LEVELS 15 #define GPU_MAX_TEXTURE_ARRAY_SIZE 1024 -// Define default back buffer(s) format -#ifndef GPU_BACK_BUFFER_PIXEL_FORMAT -#define GPU_BACK_BUFFER_PIXEL_FORMAT PixelFormat::B8G8R8A8_UNorm -#endif - // Validate configuration #if !ENABLE_ASSERTION #undef GPU_ENABLE_ASSERTION diff --git a/Source/Engine/Graphics/Materials/DeferredMaterialShader.cpp b/Source/Engine/Graphics/Materials/DeferredMaterialShader.cpp index eeffb67d3..48f56350c 100644 --- a/Source/Engine/Graphics/Materials/DeferredMaterialShader.cpp +++ b/Source/Engine/Graphics/Materials/DeferredMaterialShader.cpp @@ -146,6 +146,7 @@ bool DeferredMaterialShader::Load() psDesc.DepthEnable = false; } +#if GPU_ALLOW_TESSELLATION_SHADERS // Check if use tessellation (both material and runtime supports it) const bool useTess = _info.TessellationMode != TessellationMethod::None && GPUDevice::Instance->Limits.HasTessellation; if (useTess) @@ -153,6 +154,7 @@ bool DeferredMaterialShader::Load() psDesc.HS = _shader->GetHS("HS"); psDesc.DS = _shader->GetDS("DS"); } +#endif // GBuffer Pass psDesc.VS = _shader->GetVS("VS"); diff --git a/Source/Engine/Graphics/Materials/DeformableMaterialShader.cpp b/Source/Engine/Graphics/Materials/DeformableMaterialShader.cpp index 6dd9a8dbc..f5b7f2368 100644 --- a/Source/Engine/Graphics/Materials/DeformableMaterialShader.cpp +++ b/Source/Engine/Graphics/Materials/DeformableMaterialShader.cpp @@ -115,6 +115,7 @@ bool DeformableMaterialShader::Load() psDesc.DepthEnable = (_info.FeaturesFlags & MaterialFeaturesFlags::DisableDepthTest) == MaterialFeaturesFlags::None; psDesc.DepthWriteEnable = (_info.FeaturesFlags & MaterialFeaturesFlags::DisableDepthWrite) == MaterialFeaturesFlags::None; +#if GPU_ALLOW_TESSELLATION_SHADERS // Check if use tessellation (both material and runtime supports it) const bool useTess = _info.TessellationMode != TessellationMethod::None && GPUDevice::Instance->Limits.HasTessellation; if (useTess) @@ -122,6 +123,7 @@ bool DeformableMaterialShader::Load() psDesc.HS = _shader->GetHS("HS"); psDesc.DS = _shader->GetDS("DS"); } +#endif #if USE_EDITOR if (_shader->HasShader("PS_QuadOverdraw")) diff --git a/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp b/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp index af2ad7957..af2b30348 100644 --- a/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp +++ b/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp @@ -133,6 +133,7 @@ bool ForwardMaterialShader::Load() psDesc.DepthEnable = (_info.FeaturesFlags & MaterialFeaturesFlags::DisableDepthTest) == MaterialFeaturesFlags::None; psDesc.DepthWriteEnable = (_info.FeaturesFlags & MaterialFeaturesFlags::DisableDepthWrite) == MaterialFeaturesFlags::None; +#if GPU_ALLOW_TESSELLATION_SHADERS // Check if use tessellation (both material and runtime supports it) const bool useTess = _info.TessellationMode != TessellationMethod::None && GPUDevice::Instance->Limits.HasTessellation; if (useTess) @@ -140,6 +141,7 @@ bool ForwardMaterialShader::Load() psDesc.HS = _shader->GetHS("HS"); psDesc.DS = _shader->GetDS("DS"); } +#endif #if USE_EDITOR if (_shader->HasShader("PS_QuadOverdraw")) diff --git a/Source/Engine/Graphics/Materials/TerrainMaterialShader.cpp b/Source/Engine/Graphics/Materials/TerrainMaterialShader.cpp index bcf194907..c155cb7f2 100644 --- a/Source/Engine/Graphics/Materials/TerrainMaterialShader.cpp +++ b/Source/Engine/Graphics/Materials/TerrainMaterialShader.cpp @@ -136,6 +136,7 @@ bool TerrainMaterialShader::Load() psDesc.DepthEnable = (_info.FeaturesFlags & MaterialFeaturesFlags::DisableDepthTest) == MaterialFeaturesFlags::None; psDesc.DepthWriteEnable = (_info.FeaturesFlags & MaterialFeaturesFlags::DisableDepthWrite) == MaterialFeaturesFlags::None; +#if GPU_ALLOW_TESSELLATION_SHADERS // Check if use tessellation (both material and runtime supports it) const bool useTess = _info.TessellationMode != TessellationMethod::None && GPUDevice::Instance->Limits.HasTessellation; if (useTess) @@ -143,6 +144,7 @@ bool TerrainMaterialShader::Load() psDesc.HS = _shader->GetHS("HS"); psDesc.DS = _shader->GetDS("DS"); } +#endif // Support blending but then use only emissive channel switch (_info.BlendMode) diff --git a/Source/Engine/Graphics/Shaders/GPUShader.cpp b/Source/Engine/Graphics/Shaders/GPUShader.cpp index e3ebe6c8b..0f1e0918b 100644 --- a/Source/Engine/Graphics/Shaders/GPUShader.cpp +++ b/Source/Engine/Graphics/Shaders/GPUShader.cpp @@ -126,6 +126,10 @@ bool GPUShader::Create(MemoryReadStream& stream) LOG(Warning, "Failed to create {} Shader program '{}' ({}).", ::ToString(type), String(initializer.Name), name); continue; } +#if !GPU_ALLOW_TESSELLATION_SHADERS + if (type == ShaderStage::Hull || type == ShaderStage::Domain) + continue; +#endif GPUShaderProgram* shader = CreateGPUShaderProgram(type, initializer, cache, cacheSize, stream); if (shader == nullptr) { diff --git a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.cpp b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.cpp index b15163bfe..f4d61a830 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.cpp @@ -351,7 +351,7 @@ bool GPUDeviceDX11::Init() D3D11_FEATURE_DATA_D3D11_OPTIONS2 featureDataD3D11Options2 = {}; _device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS2, &featureDataD3D11Options2, sizeof(featureDataD3D11Options2)); limits.HasCompute = d3D10XHardwareOptions.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x != 0; - limits.HasTessellation = true; + limits.HasTessellation = GPU_ALLOW_TESSELLATION_SHADERS; limits.HasGeometryShaders = true; limits.HasInstancing = true; limits.HasVolumeTextureRendering = true; diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.cpp b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.cpp index d564bed55..c2c1b9366 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.cpp @@ -373,7 +373,7 @@ bool GPUDeviceDX12::Init() { auto& limits = Limits; limits.HasCompute = true; - limits.HasTessellation = true; + limits.HasTessellation = GPU_ALLOW_TESSELLATION_SHADERS; limits.HasGeometryShaders = true; limits.HasInstancing = true; limits.HasVolumeTextureRendering = true; diff --git a/Source/Engine/GraphicsDevice/Vulkan/DescriptorSetVulkan.h b/Source/Engine/GraphicsDevice/Vulkan/DescriptorSetVulkan.h index 8a5d706d6..9c2ea192f 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/DescriptorSetVulkan.h +++ b/Source/Engine/GraphicsDevice/Vulkan/DescriptorSetVulkan.h @@ -25,21 +25,23 @@ namespace DescriptorSet enum Stage { // Vertex shader stage - Vertex = 0, + Vertex, // Pixel shader stage - Pixel = 1, + Pixel, // Geometry shader stage - Geometry = 2, + Geometry, +#if GPU_ALLOW_TESSELLATION_SHADERS // Hull shader stage - Hull = 3, + Hull, // Domain shader stage - Domain = 4, + Domain, +#endif // Graphics pipeline stages count - GraphicsStagesCount = 5, + GraphicsStagesCount, // Compute pipeline slot Compute = 0, // The maximum amount of slots for all stages - Max = 5, + Max = GraphicsStagesCount, }; template diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp index 71a154ae8..818414fc0 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp @@ -1686,10 +1686,10 @@ bool GPUDeviceVulkan::Init() auto& limits = Limits; limits.HasCompute = GetShaderProfile() == ShaderProfile::Vulkan_SM5 && PhysicalDeviceLimits.maxComputeWorkGroupCount[0] >= GPU_MAX_CS_DISPATCH_THREAD_GROUPS && PhysicalDeviceLimits.maxComputeWorkGroupCount[1] >= GPU_MAX_CS_DISPATCH_THREAD_GROUPS; -#if PLATFORM_MAC || PLATFORM_IOS - limits.HasTessellation = false; // MoltenVK has artifacts when using tess -#else +#if GPU_ALLOW_TESSELLATION_SHADERS limits.HasTessellation = !!PhysicalDeviceFeatures.tessellationShader && PhysicalDeviceLimits.maxBoundDescriptorSets > (uint32_t)DescriptorSet::Domain; +#else + limits.HasTessellation = false; #endif #if PLATFORM_ANDROID || PLATFORM_IOS limits.HasGeometryShaders = false; // Don't even try GS on mobile diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUPipelineStateVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUPipelineStateVulkan.cpp index 5fd40fdbb..8d2ff6dae 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUPipelineStateVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUPipelineStateVulkan.cpp @@ -133,17 +133,17 @@ PipelineLayoutVulkan* GPUPipelineStateVulkan::GetLayout() return _layout; DescriptorSetLayoutInfoVulkan descriptorSetLayoutInfo; - #define INIT_SHADER_STAGE(set, bit) \ if (DescriptorInfoPerStage[DescriptorSet::set]) \ descriptorSetLayoutInfo.AddBindingsForStage(bit, DescriptorSet::set, DescriptorInfoPerStage[DescriptorSet::set]) INIT_SHADER_STAGE(Vertex, VK_SHADER_STAGE_VERTEX_BIT); +#if GPU_ALLOW_TESSELLATION_SHADERS INIT_SHADER_STAGE(Hull, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT); INIT_SHADER_STAGE(Domain, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT); +#endif INIT_SHADER_STAGE(Geometry, VK_SHADER_STAGE_GEOMETRY_BIT); INIT_SHADER_STAGE(Pixel, VK_SHADER_STAGE_FRAGMENT_BIT); #undef INIT_SHADER_STAGE - _layout = _device->GetOrCreateLayout(descriptorSetLayoutInfo); ASSERT(_layout); DescriptorSetsLayout = &_layout->DescriptorSetLayout; @@ -253,8 +253,10 @@ bool GPUPipelineStateVulkan::Init(const Description& desc) stage.pName = desc.type->GetName().Get(); \ } INIT_SHADER_STAGE(VS, Vertex, VK_SHADER_STAGE_VERTEX_BIT); +#if GPU_ALLOW_TESSELLATION_SHADERS INIT_SHADER_STAGE(HS, Hull, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT); INIT_SHADER_STAGE(DS, Domain, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT); +#endif INIT_SHADER_STAGE(GS, Geometry, VK_SHADER_STAGE_GEOMETRY_BIT); INIT_SHADER_STAGE(PS, Pixel, VK_SHADER_STAGE_FRAGMENT_BIT); #undef INIT_SHADER_STAGE @@ -278,6 +280,7 @@ bool GPUPipelineStateVulkan::Init(const Description& desc) _descInputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; _desc.pInputAssemblyState = &_descInputAssembly; +#if GPU_ALLOW_TESSELLATION_SHADERS // Tessellation if (desc.HS) { @@ -285,6 +288,7 @@ bool GPUPipelineStateVulkan::Init(const Description& desc) _descTessellation.patchControlPoints = desc.HS->GetControlPointsCount(); _desc.pTessellationState = &_descTessellation; } +#endif // Viewport RenderToolsVulkan::ZeroStruct(_descViewport, VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO); diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUPipelineStateVulkan.h b/Source/Engine/GraphicsDevice/Vulkan/GPUPipelineStateVulkan.h index e3386064b..b8b326e83 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUPipelineStateVulkan.h +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUPipelineStateVulkan.h @@ -93,7 +93,9 @@ private: VkGraphicsPipelineCreateInfo _desc; VkPipelineShaderStageCreateInfo _shaderStages[ShaderStage_Count - 1]; VkPipelineInputAssemblyStateCreateInfo _descInputAssembly; +#if GPU_ALLOW_TESSELLATION_SHADERS VkPipelineTessellationStateCreateInfo _descTessellation; +#endif VkPipelineViewportStateCreateInfo _descViewport; VkPipelineDynamicStateCreateInfo _descDynamic; VkDynamicState _dynamicStates[3]; diff --git a/Source/Engine/Platform/Mac/MacDefines.h b/Source/Engine/Platform/Mac/MacDefines.h index 456bd0b65..9c1188907 100644 --- a/Source/Engine/Platform/Mac/MacDefines.h +++ b/Source/Engine/Platform/Mac/MacDefines.h @@ -22,4 +22,7 @@ #define PLATFORM_HAS_HEADLESS_MODE 1 #define PLATFORM_DEBUG_BREAK __builtin_trap() +// MoltenVK has artifacts when using tess so disable it +#define GPU_ALLOW_TESSELLATION_SHADERS 0 + #endif diff --git a/Source/Engine/Platform/iOS/iOSDefines.h b/Source/Engine/Platform/iOS/iOSDefines.h index f3fd8f048..fcc30fb11 100644 --- a/Source/Engine/Platform/iOS/iOSDefines.h +++ b/Source/Engine/Platform/iOS/iOSDefines.h @@ -18,4 +18,7 @@ #define USE_MONO_AOT 1 #define USE_MONO_AOT_MODE MONO_AOT_MODE_FULL +// MoltenVK has artifacts when using tess so disable it +#define GPU_ALLOW_TESSELLATION_SHADERS 0 + #endif