summaryrefslogtreecommitdiffstats
path: root/src/gui/rhi/qrhi_p.h
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2022-01-10 16:45:46 +0100
committerLaszlo Agocs <laszlo.agocs@qt.io>2022-01-13 13:44:29 +0100
commita325016aa9847b15f1fed4bb714c9dd8da51eff7 (patch)
tree1bc934424aae6e478530724c3f00c970e8560a54 /src/gui/rhi/qrhi_p.h
parentc1f7194b44a2186f723c85e215e57dfa677538c0 (diff)
rhi: Add the basic infrastructure for tessellation support
...but this will only be supported with Vulkan and OpenGL 4.0+ and OpenGL ES 3.2+ for the time being. Taking the Vulkan model as our standard, the situation is the following: - Vulkan is ok, qsb secretly accepts .tesc and .tese files as input already (plus QShader already has the necessary plumbing when it comes to enums and such) To switch the tessellation domain origin to bottom left we require Vulkan 1.1 (don't bother with VK_KHR_maintenance2 on top of 1.0 at this point since 1.1 or 1.2 implementations should be common by now). The change is essential to allow the same evaluation shader to work with both OpenGL and Vulkan: this way we can use the same shader source, declaring the tessellation winding order as CCW, with both APIs. - OpenGL 4.0 and OpenGL ES 3.2 (or ES 3.1 with the Android extension pack, but we won't bother with checking that for now) can be made working without much complications, though we need to be careful when it comes to gathering and setting uniforms so that we do not leave the new tessellation stages out. We will stick to the Vulkan model in the sense that the inner and outer tessellation levels must be specified from the control shader, and cannot be specified from the host side, even though OpenGL would allow this. (basically the same story as with point size in vertex shaders) - D3D11 would be no problem API-wise, and we could likely implement the support for hull and domain shader stages in the backend, but SPIRV-Cross does not support translating tessellation shaders to HLSL. Attempting to feed in a .tesc or .tese file to qsb with --hlsl specified will always fail. One issue here is how hull shaders are structured, with the patchconstantfunc attribute specifying a separate function computing the patch constant data. With GLSL there is a single entry point in the tessellation control shader, which then performs both the calculations on the control points as well as the constant data (such as, the inner and outer tessellation factors). One option here is to inject handwritten HLSL shaders in the .qsb files using qsb's replace (-r) mode, but this is not exactly a viable universal solution. - Metal uses a different tessellation pipeline involving compute shaders. This needs more investigation but probably not something we can prioritize in practice. SPIRV-Cross does support this, generating a compute shader for control and a (post-)vertex shader for evaluation, presumably in order to enable MoltenVK to function when it comes to tessellation, but it is not clear yet how usable this is for us. Change-Id: Ic953c63850bda5bc912c7ac354425041b43157ef Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src/gui/rhi/qrhi_p.h')
-rw-r--r--src/gui/rhi/qrhi_p.h18
1 files changed, 14 insertions, 4 deletions
diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h
index dc788dd1e8..8c38b6383d 100644
--- a/src/gui/rhi/qrhi_p.h
+++ b/src/gui/rhi/qrhi_p.h
@@ -295,6 +295,8 @@ class Q_GUI_EXPORT QRhiShaderStage
public:
enum Type {
Vertex,
+ TessellationControl,
+ TessellationEvaluation,
Fragment,
Compute
};
@@ -347,8 +349,10 @@ public:
enum StageFlag {
VertexStage = 1 << 0,
- FragmentStage = 1 << 1,
- ComputeStage = 1 << 2
+ TessellationControlStage = 1 << 1,
+ TessellationEvaluationStage = 1 << 2,
+ FragmentStage = 1 << 3,
+ ComputeStage = 1 << 4
};
Q_DECLARE_FLAGS(StageFlags, StageFlag)
@@ -1126,7 +1130,8 @@ public:
TriangleFan,
Lines,
LineStrip,
- Points
+ Points,
+ Patches
};
enum CullMode {
@@ -1297,6 +1302,9 @@ public:
QRhiRenderPassDescriptor *renderPassDescriptor() const { return m_renderPassDesc; }
void setRenderPassDescriptor(QRhiRenderPassDescriptor *desc) { m_renderPassDesc = desc; }
+ int patchControlPointCount() const { return m_patchControlPointCount; }
+ void setPatchControlPointCount(int count) { m_patchControlPointCount = count; }
+
virtual bool create() = 0;
protected:
@@ -1318,6 +1326,7 @@ protected:
float m_lineWidth = 1.0f;
int m_depthBias = 0;
float m_slopeScaledDepthBias = 0.0f;
+ int m_patchControlPointCount = 3;
QVarLengthArray<QRhiShaderStage, 4> m_shaderStages;
QRhiVertexInputLayout m_vertexInputLayout;
QRhiShaderResourceBindings *m_shaderResourceBindings = nullptr;
@@ -1654,7 +1663,8 @@ public:
RenderBufferImport,
ThreeDimensionalTextures,
RenderTo3DTextureSlice,
- TextureArrays
+ TextureArrays,
+ Tessellation
};
enum BeginFrameFlag {