Enforce OOB requirements for binding with multiple attributes
authorNoah Fredriks <Noah.Fredriks@amd.com>
Thu, 9 Nov 2017 21:00:29 +0000 (16:00 -0500)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Fri, 12 Jan 2018 12:02:25 +0000 (07:02 -0500)
The spec states that, if any vertex input attribute using a specific
vertex input binding is out of bounds, then all vertex input attributes
using that vertex input binding for that vertex shader invocation are
considered out of bounds.

Affects: dEQP-VK.robustness.vertex_access.*.vertex_incomplete

Components: Vulkan

VK-GL-CTS issue: 848

Change-Id: I6a9222a0b2a53368af361419105793a5301a6bf6
(cherry picked from commit 65df12f839cea43333b11a4da900f838d5f44150)

external/vulkancts/modules/vulkan/robustness/vktRobustnessVertexAccessTests.cpp

index 0f15ba1..a016efa 100644 (file)
@@ -758,7 +758,7 @@ bool VertexAccessInstance::verifyResult (void)
        std::ostringstream                      logMsg;
        const DeviceInterface&          vk                                              = m_context.getDeviceInterface();
        tcu::TestLog&                           log                                             = m_context.getTestContext().getLog();
-       const int                                       numChannels                             = getNumUsedChannels(mapVkFormat(m_inputFormat).order);
+       const deUint32                          numChannels                             = getNumUsedChannels(mapVkFormat(m_inputFormat).order);
        const deUint32                          numScalarsPerVertex             = numChannels * 3; // Use 3 identical attributes
        void*                                           outDataPtr                              = m_outBufferAlloc->getHostPtr();
        const deUint32                          outValueSize                    = sizeof(deUint32);
@@ -782,11 +782,12 @@ bool VertexAccessInstance::verifyResult (void)
                VkDeviceSize            inBufferAllocSize;
                deUint32                        inBufferValueIndex;
                bool                            isOutOfBoundsAccess             = false;
-               const bool                      isInstanceRateValue             = ((valueNdx / numChannels) % 3 == 2);
+               const deUint32          attributeIndex                  = (valueNdx / numChannels) % 3;
                const deUint32*         outValuePtr                             = (deUint32*)outDataPtr + valueNdx;
 
-               if (isInstanceRateValue)
+               if (attributeIndex == 2)
                {
+                       // Instance rate
                        const deUint32  elementIndex    = valueNdx / (numScalarsPerVertex * m_numVertices); // instance id
 
                        numInBufferValues       = m_numInstanceValues;
@@ -796,6 +797,7 @@ bool VertexAccessInstance::verifyResult (void)
                }
                else
                {
+                       // Vertex rate
                        const deUint32  vertexNdx               = valueNdx / numScalarsPerVertex;
                        const deUint32  instanceNdx             = vertexNdx / m_numVertices;
                        const deUint32  elementIndex    = valueNdx / numScalarsPerVertex; // vertex id
@@ -804,6 +806,10 @@ bool VertexAccessInstance::verifyResult (void)
                        inBufferPtr                     = m_vertexRateBufferAlloc->getHostPtr();
                        inBufferAllocSize       = m_vertexRateBufferAllocSize;
                        inBufferValueIndex      = (getIndex(elementIndex) * (numChannels * 2)) + (valueNdx % numScalarsPerVertex) - instanceNdx * (m_numVertices * numChannels * 2);
+
+                       // Binding 0 contains two attributes, so bounds checking for attribute 0 must also consider attribute 1 to determine if the binding is out of bounds.
+                       if ((attributeIndex == 0) && (numInBufferValues >= numChannels))
+                               numInBufferValues -= numChannels;
                }
 
                isOutOfBoundsAccess     = (inBufferValueIndex >= numInBufferValues);
@@ -815,8 +821,6 @@ bool VertexAccessInstance::verifyResult (void)
 
                // Log value information
                {
-                       const deUint32  attributeIndex  = (valueNdx % numScalarsPerVertex) / numChannels;
-
                        // Vertex separator
                        if (valueNdx && valueNdx % numScalarsPerVertex == 0)
                                logMsg << "\n";