From 4f2b4e0e5ef021864ceb05299ebf67f9751777d2 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 21 Apr 2022 12:43:39 +0200 Subject: [PATCH] rhi: Add a feature flag for non-fill polygon modes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's one thing that this is not part of OpenGL ES, but it is optional even with Vulkan, with some mobile GPUs not offering the feature at all. Change-Id: I4e2c6642eccb0793e69074b4b6eeb2b7cef3516e Reviewed-by: Christian Strømme --- src/gui/rhi/qrhi.cpp | 11 ++++++++++- src/gui/rhi/qrhi_p.h | 3 ++- src/gui/rhi/qrhid3d11.cpp | 2 ++ src/gui/rhi/qrhigles2.cpp | 2 ++ src/gui/rhi/qrhimetal.mm | 2 ++ src/gui/rhi/qrhivulkan.cpp | 4 ++++ src/gui/rhi/qrhivulkan_p_p.h | 1 + tests/auto/gui/rhi/qrhi/tst_qrhi.cpp | 3 ++- 8 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index 4ed9370fa2..8fccdfe680 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -744,6 +744,12 @@ Q_LOGGING_CATEGORY(QRHI_LOG_INFO, "qt.rhi.general") it does not map well to all graphics APIs, and it is only meant to provide support for special cases anyhow. In practice the feature can be expected to be supported with Direct3D 11 and Vulkan. + + \value NonFillPolygonMode Indicates that setting a PolygonMode other than + the default Fill is supported for QRhiGraphicsPipeline. A common use case + for changing the mode to Line is to get wireframe rendering. This however + is not available as a core OpenGL ES feature, and is optional with Vulkan + as well as some mobile GPUs may not offer the feature. */ /*! @@ -4324,7 +4330,10 @@ QDebug operator<<(QDebug dbg, const QRhiShaderResourceBindings &srb) the fill mode used when rasterizing polygons. Polygons may be drawn as solids (Fill), or as a wire mesh (Line). - \note OpenGL ES does not support Polygon Mode + Support for non-fill polygon modes is optional and is indicated by the + QRhi::NonFillPolygonMode feature. With OpenGL ES and some Vulkan + implementations the feature will likely be reported as unspported, which + then means values other than Fill cannot be used. \value Fill The interior of the polygon is filled (default) \value Line Boundary edges of the polygon are drawn as line segments. diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h index bbc404f09b..b85c757b0b 100644 --- a/src/gui/rhi/qrhi_p.h +++ b/src/gui/rhi/qrhi_p.h @@ -1697,7 +1697,8 @@ public: TextureArrays, Tessellation, GeometryShader, - TextureArrayRange + TextureArrayRange, + NonFillPolygonMode }; enum BeginFrameFlag { diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp index f6e07f347e..c90dbd6e7d 100644 --- a/src/gui/rhi/qrhid3d11.cpp +++ b/src/gui/rhi/qrhid3d11.cpp @@ -576,6 +576,8 @@ bool QRhiD3D11::isFeatureSupported(QRhi::Feature feature) const return false; case QRhi::TextureArrayRange: return true; + case QRhi::NonFillPolygonMode: + return true; default: Q_UNREACHABLE(); return false; diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index 6dae48e6a1..18defa36aa 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -1281,6 +1281,8 @@ bool QRhiGles2::isFeatureSupported(QRhi::Feature feature) const return caps.geometryShader; case QRhi::TextureArrayRange: return false; + case QRhi::NonFillPolygonMode: + return !caps.gles; default: Q_UNREACHABLE(); return false; diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index 8ae5e25ffa..385aedbd7e 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -635,6 +635,8 @@ bool QRhiMetal::isFeatureSupported(QRhi::Feature feature) const return false; case QRhi::TextureArrayRange: return false; + case QRhi::NonFillPolygonMode: + return true; default: Q_UNREACHABLE(); return false; diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp index 108f43b4c6..4729bb51ca 100644 --- a/src/gui/rhi/qrhivulkan.cpp +++ b/src/gui/rhi/qrhivulkan.cpp @@ -702,6 +702,8 @@ bool QRhiVulkan::create(QRhi::Flags flags) caps.tessellation = physDevFeatures.tessellationShader; caps.geometryShader = physDevFeatures.geometryShader; + caps.nonFillPolygonMode = physDevFeatures.fillModeNonSolid; + if (!importedAllocator) { VmaVulkanFunctions afuncs; afuncs.vkGetPhysicalDeviceProperties = wrap_vkGetPhysicalDeviceProperties; @@ -4330,6 +4332,8 @@ bool QRhiVulkan::isFeatureSupported(QRhi::Feature feature) const return caps.geometryShader; case QRhi::TextureArrayRange: return true; + case QRhi::NonFillPolygonMode: + return caps.nonFillPolygonMode; default: Q_UNREACHABLE(); return false; diff --git a/src/gui/rhi/qrhivulkan_p_p.h b/src/gui/rhi/qrhivulkan_p_p.h index 30cde199c8..345a9d4351 100644 --- a/src/gui/rhi/qrhivulkan_p_p.h +++ b/src/gui/rhi/qrhivulkan_p_p.h @@ -892,6 +892,7 @@ public: bool tessellation = false; bool vulkan11OrHigher = false; bool geometryShader = false; + bool nonFillPolygonMode = false; } caps; VkPipelineCache pipelineCache = VK_NULL_HANDLE; diff --git a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp index a0b2345d24..feefd849cd 100644 --- a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp +++ b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp @@ -407,7 +407,8 @@ void tst_QRhi::create() QRhi::TextureArrays, QRhi::Tessellation, QRhi::GeometryShader, - QRhi::TextureArrayRange + QRhi::TextureArrayRange, + QRhi::NonFillPolygonMode }; for (size_t i = 0; i isFeatureSupported(features[i]);