[Mesa-dev] [PATCH vulkan/spec 1/3] Add an extension to specify that derivative groups are quads

Jason Ekstrand jason at jlekstrand.net
Tue Nov 6 21:48:16 UTC 2018


This came to the top of my list recently due to a difference between
OpenGL and Vulkan discard operations and D3D's discard operation.  The
OpenGL and Vulkan discard is defined to be control flow and derivatives
are undefined after discard.  With D3D, derivatives are considered
well-defined after discard.

In order to work around this, DXVK (and I would assume VKD3D though I'm
not sure), simply sets a global boolean instead of doing the discard and
then emits `if (do_discard) discard;` at the end of the shader.  For
complex shadaers, this leads to the shader doing way more work than
needed and poor performance.  If, on the other hand, they knew that
derivative groups are just subgroup quads, they could do something
better:

    bool want_discard;

    void d3d_discard()
    {
        want_discard = true;
        if (subgroupClusteredAnd(want_discard, 4))
            discard;
    }

    void main()
    {
        want_discard = false;

        // stuff

        if (some_condition)
            d3d_discard();

        // Exepensive stuff

        if (want_discard)
            discard;
    }
---
 chapters/features.txt        | 21 +++++++++++++++++++++
 chapters/shaders.txt         | 12 ++++++++++++
 chapters/textures.txt        |  8 ++++++++
 include/vulkan/vulkan_core.h | 15 +++++++++++++--
 xml/vk.xml                   | 13 ++++++++++---
 5 files changed, 64 insertions(+), 5 deletions(-)

diff --git a/chapters/features.txt b/chapters/features.txt
index 08c8d8420..3d22972ea 100644
--- a/chapters/features.txt
+++ b/chapters/features.txt
@@ -2969,6 +2969,27 @@ more slink:VkSubgroupFeatureFlagBits.
 
 endif::VK_VERSION_1_1[]
 
+ifdef::VK_EXT_derivative_group_quad[]
+
+[open,refpage='VkPhysicalDeviceDerivativeGroupQuadPropertiesEXT',desc='Structure describing the relationship between derivative groups and subgroup quads for an implementation',type='structs']
+--
+
+The sname:VkPhysicalDeviceDerivativeGroupQuadPropertiesEXT structure is
+defined as:
+
+include::../api/structs/VkPhysicalDeviceDerivativeGroupQuadPropertiesEXT.txt[]
+
+The members of the sname:VkPhysicalDeviceDerivativeGroupQuadPropertiesEXT
+structure describe the following implementation-dependent limits:
+
+  * pname:derivativeGroupsAreSubgroupQuads is a boolean that specifies that
+    derivative groups in fragment shaders correspond to subgroup quads.
+--
+
+include::../validity/structs/VkPhysicalDeviceDerivativeGroupQuadPropertiesEXT.txt[]
+
+endif::VK_EXT_derivative_group_quad[]
+
 ifdef::VK_EXT_blend_operation_advanced[]
 
 [open,refpage='VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT',desc='Structure describing advanced blending limits that can be supported by an implementation',type='structs']
diff --git a/chapters/shaders.txt b/chapters/shaders.txt
index 5cb3edb35..11d3ea9db 100644
--- a/chapters/shaders.txt
+++ b/chapters/shaders.txt
@@ -808,6 +808,11 @@ A _derivative group_ (see the subsection "`Control Flow`" of section 2 of
 the SPIR-V 1.00 Revision 4 specification) for a fragment shader is the set
 of invocations generated by a single primitive (point, line, or triangle),
 including any helper invocations generated by that primitive.
+ifdef::VK_EXT_derivative_group_quad[]
+If the fname:derivativeGroupsAreSubgroupQuads field of
+slink:VkPhysicalDeviceDerivativeGroupQuadPropertiesEXT is ename:VK_TRUE, a
+derivative group for a fragment shader is a single subgroup quad.
+endif::VK_EXT_derivative_group_quad[]
 ifdef::VK_NV_compute_shader_derivatives[]
 A derivative group for a compute shader is a single local workgroup.
 endif::VK_NV_compute_shader_derivatives[]
@@ -920,6 +925,13 @@ The operations supported are add, mul, min, max, and, or, xor.
 
 The quad subgroup operations allow clusters of 4 invocations (a quad), to
 share data efficiently with each other.
+ifdef::VK_EXT_derivative_group_quad[]
+For fragment shaders, if the fname:derivativeGroupsAreSubgroupQuads field of
+slink:VkPhysicalDeviceDerivativeGroupQuadPropertiesEXT is ename:VK_TRUE,
+each quad corresponds to one of the groups of four shader
+invocations used for
+<<texture-derivatives-compute,derivatives>>.
+endif::VK_EXT_derivative_group_quad[]
 ifdef::VK_NV_compute_shader_derivatives[]
 For compute shaders using the code:DerivativeGroupQuadsNV or
 code:DerivativeGroupLinearNV execution modes, each quad corresponds to one
diff --git a/chapters/textures.txt b/chapters/textures.txt
index a7bfaedc3..46a292381 100644
--- a/chapters/textures.txt
+++ b/chapters/textures.txt
@@ -1387,6 +1387,14 @@ Implementations must: make the same choice of either coarse or fine for both
 code:OpDPdx and code:OpDPdy, and implementations should: make the choice
 that is more efficient to compute.
 
+ifdef::VK_EXT_derivative_group_quad[]
+If the fname:derivativeGroupsAreSubgroupQuads field of
+slink:VkPhysicalDeviceDerivativeGroupQuadPropertiesEXT is ename:VK_TRUE,
+the 2x2 neighborhood of fragments corresponds exactly to a subgroup quad
+the invocations in each quad are ordered to have attribute values of
+P~i0,j0~, P~i1,j0~, P~i0,j1~, and P~i1,j1~, respectively.
+endif::VK_EXT_derivative_group_quad[]
+
 ifdef::VK_NV_compute_shader_derivatives[]
 [[texture-derivatives-compute]]
 === Compute Shader Derivatives
diff --git a/include/vulkan/vulkan_core.h b/include/vulkan/vulkan_core.h
index 4cd8ed51d..7b304eafe 100644
--- a/include/vulkan/vulkan_core.h
+++ b/include/vulkan/vulkan_core.h
@@ -451,6 +451,7 @@ typedef enum VkStructureType {
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV = 1000205002,
     VK_STRUCTURE_TYPE_CHECKPOINT_DATA_NV = 1000206000,
     VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV = 1000206001,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DERIVATIVE_GROUP_QUAD_PROPERTIES_EXT = 1000209000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = 1000211000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT = 1000212000,
     VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA = 1000214000,
@@ -7791,8 +7792,6 @@ typedef struct VkPipelineCoverageModulationStateCreateInfoNV {
 
 
 #define VK_EXT_image_drm_format_modifier 1
-#define VK_EXT_EXTENSION_159_SPEC_VERSION 0
-#define VK_EXT_EXTENSION_159_EXTENSION_NAME "VK_EXT_extension_159"
 #define VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_SPEC_VERSION 1
 #define VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME "VK_EXT_image_drm_format_modifier"
 
@@ -8791,6 +8790,18 @@ VKAPI_ATTR void VKAPI_CALL vkGetQueueCheckpointDataNV(
     VkCheckpointDataNV*                         pCheckpointData);
 #endif
 
+#define VK_EXT_derivative_group_quad 1
+#define VK_EXT_DERIVATIVE_GROUP_QUAD_SPEC_VERSION 1
+#define VK_EXT_DERIVATIVE_GROUP_QUAD_EXTENSION_NAME "VK_EXT_derivative_group_quad"
+
+typedef struct VkPhysicalDeviceDerivativeGroupQuadPropertiesEXT {
+    VkStructureType    sType;
+    const void*        pNext;
+    VkBool32           derivativeGroupsAreSubgroupQuads;
+} VkPhysicalDeviceDerivativeGroupQuadPropertiesEXT;
+
+
+
 #define VK_EXT_pci_bus_info 1
 #define VK_EXT_PCI_BUS_INFO_SPEC_VERSION  1
 #define VK_EXT_PCI_BUS_INFO_EXTENSION_NAME "VK_EXT_pci_bus_info"
diff --git a/xml/vk.xml b/xml/vk.xml
index 24cc3ce78..93dc66159 100644
--- a/xml/vk.xml
+++ b/xml/vk.xml
@@ -3590,6 +3590,11 @@ server.
             <member>const <type>void</type>*                      <name>pNext</name></member>
             <member><type>VkMemoryOverallocationBehaviorAMD</type> <name>overallocationBehavior</name></member>
         </type>
+        <type category="struct" name="VkPhysicalDeviceDerivativeGroupQuadPropertiesEXT"  structextends="VkPhysicalDeviceProperties2">
+            <member values="VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DERIVATIVE_GROUP_QUAD_PROPERTIES_EXT"><type>VkStructureType</type> <name>sType</name></member>
+            <member>const <type>void</type>*                      <name>pNext</name></member>
+            <member><type>VkBool32</type>                         <name>derivativeGroupsAreSubgroupQuads</name></member>
+        </type>
     </types>
 
     <comment>Vulkan enumerant (token) definitions</comment>
@@ -9893,10 +9898,12 @@ server.
                 <enum value=""VK_KHR_extension_209""          name="VK_KHR_EXTENSION_209_EXTENSION_NAME"/>
             </require>
         </extension>
-        <extension name="VK_INTEL_extension_210" number="210" type="device" author="INTEL" contact="Jason Ekstrand @jekstrand" supported="disabled">
+        <extension name="VK_EXT_derivative_group_quad" number="210" type="device" requiresCore="1.1" author="EXT" contact="Jason Ekstrand @jekstrand" supported="vulkan">
             <require>
-                <enum value="0"                                         name="VK_KHR_EXTENSION_210_SPEC_VERSION"/>
-                <enum value=""VK_KHR_extension_210""          name="VK_KHR_EXTENSION_210_EXTENSION_NAME"/>
+                <enum value="1"                                         name="VK_EXT_DERIVATIVE_GROUP_QUAD_SPEC_VERSION"/>
+                <enum value=""VK_EXT_derivative_group_quad""  name="VK_EXT_DERIVATIVE_GROUP_QUAD_EXTENSION_NAME"/>
+                <enum offset="0" extends="VkStructureType"              name="VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DERIVATIVE_GROUP_QUAD_PROPERTIES_EXT"/>
+                <type name="VkPhysicalDeviceDerivativeGroupQuadPropertiesEXT"/>
             </require>
         </extension>
         <extension name="VK_INTEL_extension_211" number="211" type="device" author="INTEL" contact="Jason Ekstrand @jekstrand" supported="disabled">
-- 
2.19.1



More information about the mesa-dev mailing list