summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2019-06-24 10:22:50 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2019-07-01 17:34:29 +0200
commit854ddb0301ae677a31286da4476318f4e6b74e3f (patch)
tree9e9cdaa09a3d6f12f7636abdec0de15ed694e8a2 /src
parent56fb2266f2d224ba58d262640f318a0439a9fa32 (diff)
rhi: Enhance line width and point size support
...but this will vary between backends, or in some cases even between implementations of the same API. Point size is settable only via the vertex shader (gl_PointSize). It is silently ignored with D3D and HLSL. Line widths other than 1 are supported only on OpenGL and Vulkan. (but this is in fact deprecated with GL and optional with Vulkan) Add QRhi::Feature values for both. The line width is now settable on QRhiGraphicsPipeline. It is not a dynamic state since the static, per-pipeline width is good enough for most cases. (and the feature is not supported on half of the backends anyways so it will get limited use in practice). Change-Id: I6d3a32269527c452b794b2cb8b0f03101eab40b2 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/gui/rhi/qrhi.cpp18
-rw-r--r--src/gui/rhi/qrhi_p.h8
-rw-r--r--src/gui/rhi/qrhid3d11.cpp4
-rw-r--r--src/gui/rhi/qrhigles2.cpp7
-rw-r--r--src/gui/rhi/qrhimetal.mm4
-rw-r--r--src/gui/rhi/qrhivulkan.cpp18
-rw-r--r--src/gui/rhi/qrhivulkan_p_p.h2
7 files changed, 52 insertions, 9 deletions
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp
index 334fa1064a..681a6ddfb8 100644
--- a/src/gui/rhi/qrhi.cpp
+++ b/src/gui/rhi/qrhi.cpp
@@ -494,7 +494,23 @@ QT_BEGIN_NAMESPACE
extension. When false, only 16-bit unsigned elements are supported in the
index buffer.
- \value Compute Indicates that compute shaders are supported.
+ \value Compute Indicates that compute shaders, image load/store, and
+ storage buffers are supported.
+
+ \value WideLines Indicates that lines with a width other than 1 are
+ supported. When reported as not supported, the line width set on the
+ graphics pipeline state is ignored. This can always be false with some
+ backends (D3D11, Metal). With Vulkan, the value depends on the
+ implementation.
+
+ \value VertexShaderPointSize Indicates that the size of rasterized points
+ set via \c{gl_PointSize} in the vertex shader is taken into account. When
+ reported as not supported, drawing points with a size other than 1 is not
+ supported. Setting \c{gl_PointSize} in the shader is still valid then, but
+ is ignored. (for example, when generating HLSL, the assignment is silently
+ dropped from the generated code) Note that some APIs (Metal, Vulkan)
+ require the point size to be set in the shader explicitly whenever drawing
+ points, even when the size is 1, as they do not automatically default to 1.
*/
/*!
diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h
index 0d296d370c..fb8727b265 100644
--- a/src/gui/rhi/qrhi_p.h
+++ b/src/gui/rhi/qrhi_p.h
@@ -1068,6 +1068,9 @@ public:
int sampleCount() const { return m_sampleCount; }
void setSampleCount(int s) { m_sampleCount = s; }
+ float lineWidth() const { return m_lineWidth; }
+ void setLineWidth(float width) { m_lineWidth = width; }
+
QVector<QRhiShaderStage> shaderStages() const { return m_shaderStages; }
void setShaderStages(const QVector<QRhiShaderStage> &stages) { m_shaderStages = stages; }
@@ -1098,6 +1101,7 @@ protected:
quint32 m_stencilReadMask = 0xFF;
quint32 m_stencilWriteMask = 0xFF;
int m_sampleCount = 1;
+ float m_lineWidth = 1.0f;
QVector<QRhiShaderStage> m_shaderStages;
QRhiVertexInputLayout m_vertexInputLayout;
QRhiShaderResourceBindings *m_shaderResourceBindings = nullptr;
@@ -1312,7 +1316,9 @@ public:
NPOTTextureRepeat,
RedOrAlpha8IsRed,
ElementIndexUint,
- Compute
+ Compute,
+ WideLines,
+ VertexShaderPointSize
};
enum BeginFrameFlag {
diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp
index 6b05d68fb5..dc69f50cc8 100644
--- a/src/gui/rhi/qrhid3d11.cpp
+++ b/src/gui/rhi/qrhid3d11.cpp
@@ -378,6 +378,10 @@ bool QRhiD3D11::isFeatureSupported(QRhi::Feature feature) const
return true;
case QRhi::Compute:
return true;
+ case QRhi::WideLines:
+ return false;
+ case QRhi::VertexShaderPointSize:
+ return false;
default:
Q_UNREACHABLE();
return false;
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp
index 7c40a36701..51862cad86 100644
--- a/src/gui/rhi/qrhigles2.cpp
+++ b/src/gui/rhi/qrhigles2.cpp
@@ -618,6 +618,10 @@ bool QRhiGles2::isFeatureSupported(QRhi::Feature feature) const
return caps.elementIndexUint;
case QRhi::Compute:
return false;
+ case QRhi::WideLines:
+ return true;
+ case QRhi::VertexShaderPointSize:
+ return true;
default:
Q_UNREACHABLE();
return false;
@@ -1849,6 +1853,9 @@ void QRhiGles2::executeBindGraphicsPipeline(QRhiGraphicsPipeline *ps)
f->glDisable(GL_STENCIL_TEST);
}
+ if (psD->topology() == QRhiGraphicsPipeline::Lines || psD->topology() == QRhiGraphicsPipeline::LineStrip)
+ f->glLineWidth(psD->m_lineWidth);
+
f->glUseProgram(psD->program);
}
diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm
index 214374e0c6..09b80c831d 100644
--- a/src/gui/rhi/qrhimetal.mm
+++ b/src/gui/rhi/qrhimetal.mm
@@ -523,6 +523,10 @@ bool QRhiMetal::isFeatureSupported(QRhi::Feature feature) const
return true;
case QRhi::Compute:
return true;
+ case QRhi::WideLines:
+ return false;
+ case QRhi::VertexShaderPointSize:
+ return true;
default:
Q_UNREACHABLE();
return false;
diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp
index f6ecd7c00e..8598e5869a 100644
--- a/src/gui/rhi/qrhivulkan.cpp
+++ b/src/gui/rhi/qrhivulkan.cpp
@@ -489,6 +489,9 @@ bool QRhiVulkan::create(QRhi::Flags flags)
// elsewhere states that the minimum bufferOffset is 4...
texbufAlign = qMax<VkDeviceSize>(4, physDevProperties.limits.optimalBufferCopyOffsetAlignment);
+ f->vkGetPhysicalDeviceFeatures(physDev, &physDevFeatures);
+ hasWideLines = physDevFeatures.wideLines;
+
if (!importedAllocator) {
VmaVulkanFunctions afuncs;
afuncs.vkGetPhysicalDeviceProperties = wrap_vkGetPhysicalDeviceProperties;
@@ -3489,24 +3492,21 @@ QMatrix4x4 QRhiVulkan::clipSpaceCorrMatrix() const
bool QRhiVulkan::isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const
{
- VkPhysicalDeviceFeatures features;
- f->vkGetPhysicalDeviceFeatures(physDev, &features);
-
// Note that with some SDKs the validation layer gives an odd warning about
// BC not being supported, even when our check here succeeds. Not much we
// can do about that.
if (format >= QRhiTexture::BC1 && format <= QRhiTexture::BC7) {
- if (!features.textureCompressionBC)
+ if (!physDevFeatures.textureCompressionBC)
return false;
}
if (format >= QRhiTexture::ETC2_RGB8 && format <= QRhiTexture::ETC2_RGBA8) {
- if (!features.textureCompressionETC2)
+ if (!physDevFeatures.textureCompressionETC2)
return false;
}
if (format >= QRhiTexture::ASTC_4x4 && format <= QRhiTexture::ASTC_12x12) {
- if (!features.textureCompressionASTC_LDR)
+ if (!physDevFeatures.textureCompressionASTC_LDR)
return false;
}
@@ -3545,6 +3545,10 @@ bool QRhiVulkan::isFeatureSupported(QRhi::Feature feature) const
return true;
case QRhi::Compute:
return hasCompute;
+ case QRhi::WideLines:
+ return hasWideLines;
+ case QRhi::VertexShaderPointSize:
+ return true;
default:
Q_UNREACHABLE();
return false;
@@ -5612,7 +5616,7 @@ bool QVkGraphicsPipeline::build()
rastInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
rastInfo.cullMode = toVkCullMode(m_cullMode);
rastInfo.frontFace = toVkFrontFace(m_frontFace);
- rastInfo.lineWidth = 1.0f;
+ rastInfo.lineWidth = rhiD->hasWideLines ? m_lineWidth : 1.0f;
pipelineInfo.pRasterizationState = &rastInfo;
VkPipelineMultisampleStateCreateInfo msInfo;
diff --git a/src/gui/rhi/qrhivulkan_p_p.h b/src/gui/rhi/qrhivulkan_p_p.h
index cec9016603..31e0eaa585 100644
--- a/src/gui/rhi/qrhivulkan_p_p.h
+++ b/src/gui/rhi/qrhivulkan_p_p.h
@@ -783,9 +783,11 @@ public:
QVkAllocator allocator = nullptr;
QVulkanFunctions *f = nullptr;
QVulkanDeviceFunctions *df = nullptr;
+ VkPhysicalDeviceFeatures physDevFeatures;
VkPhysicalDeviceProperties physDevProperties;
VkDeviceSize ubufAlign;
VkDeviceSize texbufAlign;
+ bool hasWideLines = false;
bool debugMarkersAvailable = false;
bool vertexAttribDivisorAvailable = false;