Enforce OOB requirements for binding with multiple attributes
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
diff --git a/external/vulkancts/modules/vulkan/robustness/vktRobustnessVertexAccessTests.cpp b/external/vulkancts/modules/vulkan/robustness/vktRobustnessVertexAccessTests.cpp
index a0c33f4..c66b914 100644
--- a/external/vulkancts/modules/vulkan/robustness/vktRobustnessVertexAccessTests.cpp
+++ b/external/vulkancts/modules/vulkan/robustness/vktRobustnessVertexAccessTests.cpp
@@ -758,7 +758,7 @@
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 @@
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 @@
}
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 @@
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 @@
// Log value information
{
- const deUint32 attributeIndex = (valueNdx % numScalarsPerVertex) / numChannels;
-
// Vertex separator
if (valueNdx && valueNdx % numScalarsPerVertex == 0)
logMsg << "\n";