1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Imagination Technologies Ltd.
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
22 * \brief Vertex Input Tests
23 *//*--------------------------------------------------------------------*/
25 #include "vktPipelineVertexInputTests.hpp"
26 #include "vktTestGroupUtil.hpp"
27 #include "vktPipelineClearUtil.hpp"
28 #include "vktPipelineImageUtil.hpp"
29 #include "vktPipelineVertexUtil.hpp"
30 #include "vktPipelineReferenceRenderer.hpp"
31 #include "vktTestCase.hpp"
32 #include "vktTestCaseUtil.hpp"
33 #include "vkImageUtil.hpp"
34 #include "vkMemUtil.hpp"
35 #include "vkPrograms.hpp"
36 #include "vkQueryUtil.hpp"
38 #include "vkRefUtil.hpp"
39 #include "tcuFloat.hpp"
40 #include "tcuImageCompare.hpp"
41 #include "deFloat16.h"
43 #include "deRandom.hpp"
44 #include "deStringUtil.hpp"
45 #include "deUniquePtr.hpp"
60 bool isSupportedVertexFormat (Context& context, VkFormat format)
62 if (isVertexFormatDouble(format) && !context.getDeviceFeatures().shaderFloat64)
65 VkFormatProperties formatProps;
66 deMemset(&formatProps, 0, sizeof(VkFormatProperties));
67 context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), format, &formatProps);
69 return (formatProps.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) != 0u;
72 float getRepresentableDifferenceUnorm (VkFormat format)
74 DE_ASSERT(isVertexFormatUnorm(format) || isVertexFormatSRGB(format));
76 return 1.0f / float((1 << (getVertexFormatComponentSize(format) * 8)) - 1);
79 float getRepresentableDifferenceSnorm (VkFormat format)
81 DE_ASSERT(isVertexFormatSnorm(format));
83 return 1.0f / float((1 << (getVertexFormatComponentSize(format) * 8 - 1)) - 1);
86 deUint32 getNextMultipleOffset (deUint32 divisor, deUint32 value)
88 if (value % divisor == 0)
91 return divisor - (value % divisor);
94 class VertexInputTest : public vkt::TestCase
131 GLSL_BASIC_TYPE_UINT,
132 GLSL_BASIC_TYPE_FLOAT,
133 GLSL_BASIC_TYPE_DOUBLE
138 BINDING_MAPPING_ONE_TO_ONE, //!< Vertex input bindings will not contain data for more than one attribute.
139 BINDING_MAPPING_ONE_TO_MANY //!< Vertex input bindings can contain data for more than one attribute.
144 ATTRIBUTE_LAYOUT_INTERLEAVED, //!< Attribute data is bundled together as if in a structure: [pos 0][color 0][pos 1][color 1]...
145 ATTRIBUTE_LAYOUT_SEQUENTIAL //!< Data for each attribute is laid out separately: [pos 0][pos 1]...[color 0][color 1]...
146 // Sequential only makes a difference if ONE_TO_MANY mapping is used (more than one attribute in a binding).
153 VkVertexInputRate inputRate;
156 struct GlslTypeDescription
159 int vertexInputComponentCount;
160 int vertexInputCount;
161 GlslBasicType basicType;
164 static const GlslTypeDescription s_glslTypeDescriptions[GLSL_TYPE_COUNT];
166 VertexInputTest (tcu::TestContext& testContext,
167 const std::string& name,
168 const std::string& description,
169 const std::vector<AttributeInfo>& attributeInfos,
170 BindingMapping bindingMapping,
171 AttributeLayout attributeLayout);
173 virtual ~VertexInputTest (void) {}
174 virtual void initPrograms (SourceCollections& programCollection) const;
175 virtual TestInstance* createInstance (Context& context) const;
176 static bool isCompatibleType (VkFormat format, GlslType glslType);
179 AttributeInfo getAttributeInfo (size_t attributeNdx) const;
180 size_t getNumAttributes (void) const;
181 std::string getGlslInputDeclarations (void) const;
182 std::string getGlslVertexCheck (void) const;
183 std::string getGlslAttributeConditions (const AttributeInfo& attributeInfo, const std::string attributeIndex) const;
184 static tcu::Vec4 getFormatThreshold (VkFormat format);
186 const std::vector<AttributeInfo> m_attributeInfos;
187 const BindingMapping m_bindingMapping;
188 const AttributeLayout m_attributeLayout;
189 const bool m_queryMaxAttributes;
190 bool m_usesDoubleType;
191 mutable size_t m_maxAttributes;
194 class VertexInputInstance : public vkt::TestInstance
197 struct VertexInputAttributeDescription
199 VertexInputTest::GlslType glslType;
200 int vertexInputIndex;
201 VkVertexInputAttributeDescription vkDescription;
204 typedef std::vector<VertexInputAttributeDescription> AttributeDescriptionList;
206 VertexInputInstance (Context& context,
207 const AttributeDescriptionList& attributeDescriptions,
208 const std::vector<VkVertexInputBindingDescription>& bindingDescriptions,
209 const std::vector<VkDeviceSize>& bindingOffsets);
211 virtual ~VertexInputInstance (void);
212 virtual tcu::TestStatus iterate (void);
215 static void writeVertexInputData (deUint8* destPtr, const VkVertexInputBindingDescription& bindingDescription, const VkDeviceSize bindingOffset, const AttributeDescriptionList& attributes);
216 static void writeVertexInputValue (deUint8* destPtr, const VertexInputAttributeDescription& attributes, int indexId);
219 tcu::TestStatus verifyImage (void);
222 std::vector<VkBuffer> m_vertexBuffers;
223 std::vector<Allocation*> m_vertexBufferAllocs;
225 const tcu::UVec2 m_renderSize;
226 const VkFormat m_colorFormat;
228 Move<VkImage> m_colorImage;
229 de::MovePtr<Allocation> m_colorImageAlloc;
230 Move<VkImage> m_depthImage;
231 Move<VkImageView> m_colorAttachmentView;
232 Move<VkRenderPass> m_renderPass;
233 Move<VkFramebuffer> m_framebuffer;
235 Move<VkShaderModule> m_vertexShaderModule;
236 Move<VkShaderModule> m_fragmentShaderModule;
238 Move<VkPipelineLayout> m_pipelineLayout;
239 Move<VkPipeline> m_graphicsPipeline;
241 Move<VkCommandPool> m_cmdPool;
242 Move<VkCommandBuffer> m_cmdBuffer;
244 Move<VkFence> m_fence;
247 const VertexInputTest::GlslTypeDescription VertexInputTest::s_glslTypeDescriptions[GLSL_TYPE_COUNT] =
249 { "int", 1, 1, GLSL_BASIC_TYPE_INT },
250 { "ivec2", 2, 1, GLSL_BASIC_TYPE_INT },
251 { "ivec3", 3, 1, GLSL_BASIC_TYPE_INT },
252 { "ivec4", 4, 1, GLSL_BASIC_TYPE_INT },
254 { "uint", 1, 1, GLSL_BASIC_TYPE_UINT },
255 { "uvec2", 2, 1, GLSL_BASIC_TYPE_UINT },
256 { "uvec3", 3, 1, GLSL_BASIC_TYPE_UINT },
257 { "uvec4", 4, 1, GLSL_BASIC_TYPE_UINT },
259 { "float", 1, 1, GLSL_BASIC_TYPE_FLOAT },
260 { "vec2", 2, 1, GLSL_BASIC_TYPE_FLOAT },
261 { "vec3", 3, 1, GLSL_BASIC_TYPE_FLOAT },
262 { "vec4", 4, 1, GLSL_BASIC_TYPE_FLOAT },
263 { "mat2", 2, 2, GLSL_BASIC_TYPE_FLOAT },
264 { "mat3", 3, 3, GLSL_BASIC_TYPE_FLOAT },
265 { "mat4", 4, 4, GLSL_BASIC_TYPE_FLOAT },
267 { "double", 1, 1, GLSL_BASIC_TYPE_DOUBLE },
268 { "dvec2", 2, 1, GLSL_BASIC_TYPE_DOUBLE },
269 { "dvec3", 3, 1, GLSL_BASIC_TYPE_DOUBLE },
270 { "dvec4", 4, 1, GLSL_BASIC_TYPE_DOUBLE },
271 { "dmat2", 2, 2, GLSL_BASIC_TYPE_DOUBLE },
272 { "dmat3", 3, 3, GLSL_BASIC_TYPE_DOUBLE },
273 { "dmat4", 4, 4, GLSL_BASIC_TYPE_DOUBLE }
277 VertexInputTest::VertexInputTest (tcu::TestContext& testContext,
278 const std::string& name,
279 const std::string& description,
280 const std::vector<AttributeInfo>& attributeInfos,
281 BindingMapping bindingMapping,
282 AttributeLayout attributeLayout)
284 : vkt::TestCase (testContext, name, description)
285 , m_attributeInfos (attributeInfos)
286 , m_bindingMapping (bindingMapping)
287 , m_attributeLayout (attributeLayout)
288 , m_queryMaxAttributes (attributeInfos.size() == 0)
289 , m_maxAttributes (16)
291 DE_ASSERT(m_attributeLayout == ATTRIBUTE_LAYOUT_INTERLEAVED || m_bindingMapping == BINDING_MAPPING_ONE_TO_MANY);
293 m_usesDoubleType = false;
295 for (size_t attributeNdx = 0; attributeNdx < m_attributeInfos.size(); attributeNdx++)
297 if (s_glslTypeDescriptions[m_attributeInfos[attributeNdx].glslType].basicType == GLSL_BASIC_TYPE_DOUBLE)
299 m_usesDoubleType = true;
305 deUint32 getAttributeBinding (const VertexInputTest::BindingMapping bindingMapping, const VkVertexInputRate firstInputRate, const VkVertexInputRate inputRate, const deUint32 attributeNdx)
307 if (bindingMapping == VertexInputTest::BINDING_MAPPING_ONE_TO_ONE)
309 // Each attribute uses a unique binding
312 else // bindingMapping == BINDING_MAPPING_ONE_TO_MANY
314 // Alternate between two bindings
315 return deUint32(firstInputRate + inputRate) % 2u;
319 //! Number of locations used up by an attribute.
320 deUint32 getConsumedLocations (const VertexInputTest::AttributeInfo& attributeInfo)
322 // double formats with more than 2 components will take 2 locations
323 const VertexInputTest::GlslType type = attributeInfo.glslType;
324 if ((type == VertexInputTest::GLSL_TYPE_DMAT2 || type == VertexInputTest::GLSL_TYPE_DMAT3 || type == VertexInputTest::GLSL_TYPE_DMAT4) &&
325 (attributeInfo.vkType == VK_FORMAT_R64G64B64_SFLOAT || attributeInfo.vkType == VK_FORMAT_R64G64B64A64_SFLOAT))
333 VertexInputTest::AttributeInfo VertexInputTest::getAttributeInfo (size_t attributeNdx) const
335 if (m_queryMaxAttributes)
337 AttributeInfo attributeInfo =
340 VK_FORMAT_R8G8B8A8_SNORM,
341 (attributeNdx % 2 == 0) ? VK_VERTEX_INPUT_RATE_VERTEX : VK_VERTEX_INPUT_RATE_INSTANCE
344 return attributeInfo;
348 return m_attributeInfos.at(attributeNdx);
352 size_t VertexInputTest::getNumAttributes (void) const
354 if (m_queryMaxAttributes)
355 return m_maxAttributes;
357 return m_attributeInfos.size();
360 TestInstance* VertexInputTest::createInstance (Context& context) const
362 typedef VertexInputInstance::VertexInputAttributeDescription VertexInputAttributeDescription;
364 // Check upfront for maximum number of vertex input attributes
366 const InstanceInterface& vki = context.getInstanceInterface();
367 const VkPhysicalDevice physDevice = context.getPhysicalDevice();
368 const VkPhysicalDeviceLimits limits = getPhysicalDeviceProperties(vki, physDevice).limits;
370 const deUint32 maxAttributes = limits.maxVertexInputAttributes;
372 if (m_attributeInfos.size() > maxAttributes)
374 const std::string notSupportedStr = "Unsupported number of vertex input attributes, maxVertexInputAttributes: " + de::toString(maxAttributes);
375 TCU_THROW(NotSupportedError, notSupportedStr.c_str());
378 // Use VkPhysicalDeviceLimits::maxVertexInputAttributes
379 if (m_queryMaxAttributes)
380 m_maxAttributes = maxAttributes;
383 // Create enough binding descriptions with random offsets
384 std::vector<VkVertexInputBindingDescription> bindingDescriptions;
385 std::vector<VkDeviceSize> bindingOffsets;
386 const size_t numAttributes = getNumAttributes();
387 const size_t numBindings = (m_bindingMapping == BINDING_MAPPING_ONE_TO_ONE) ? numAttributes : ((numAttributes > 1) ? 2 : 1);
388 const VkVertexInputRate firstInputrate = getAttributeInfo(0).inputRate;
390 for (size_t bindingNdx = 0; bindingNdx < numBindings; ++bindingNdx)
392 // Bindings alternate between STEP_RATE_VERTEX and STEP_RATE_INSTANCE
393 const VkVertexInputRate inputRate = ((firstInputrate + bindingNdx) % 2 == 0) ? VK_VERTEX_INPUT_RATE_VERTEX : VK_VERTEX_INPUT_RATE_INSTANCE;
395 // Stride will be updated when creating the attribute descriptions
396 const VkVertexInputBindingDescription bindingDescription =
398 static_cast<deUint32>(bindingNdx), // deUint32 binding;
399 0u, // deUint32 stride;
400 inputRate // VkVertexInputRate inputRate;
403 bindingDescriptions.push_back(bindingDescription);
404 bindingOffsets.push_back(4 * bindingNdx);
407 std::vector<VertexInputAttributeDescription> attributeDescriptions;
408 deUint32 attributeLocation = 0;
409 std::vector<deUint32> attributeOffsets (bindingDescriptions.size(), 0);
410 std::vector<deUint32> attributeMaxSizes (bindingDescriptions.size(), 0); // max component or vector size, depending on which layout we are using
412 // To place the attributes sequentially we need to know the largest attribute and use its size in stride and offset calculations.
413 if (m_attributeLayout == ATTRIBUTE_LAYOUT_SEQUENTIAL)
414 for (size_t attributeNdx = 0; attributeNdx < numAttributes; ++attributeNdx)
416 const AttributeInfo& attributeInfo = getAttributeInfo(attributeNdx);
417 const deUint32 attributeBinding = getAttributeBinding(m_bindingMapping, firstInputrate, attributeInfo.inputRate, static_cast<deUint32>(attributeNdx));
418 const deUint32 inputSize = getVertexFormatSize(attributeInfo.vkType);
420 attributeMaxSizes[attributeBinding] = de::max(attributeMaxSizes[attributeBinding], inputSize);
423 // Create attribute descriptions, assign them to bindings and update stride.
424 for (size_t attributeNdx = 0; attributeNdx < numAttributes; ++attributeNdx)
426 const AttributeInfo& attributeInfo = getAttributeInfo(attributeNdx);
427 const GlslTypeDescription& glslTypeDescription = s_glslTypeDescriptions[attributeInfo.glslType];
428 const deUint32 inputSize = getVertexFormatSize(attributeInfo.vkType);
429 const deUint32 attributeBinding = getAttributeBinding(m_bindingMapping, firstInputrate, attributeInfo.inputRate, static_cast<deUint32>(attributeNdx));
430 const deUint32 vertexCount = (attributeInfo.inputRate == VK_VERTEX_INPUT_RATE_VERTEX) ? (4 * 2) : 2;
432 VertexInputAttributeDescription attributeDescription =
434 attributeInfo.glslType, // GlslType glslType;
435 0, // int vertexInputIndex;
437 0u, // uint32_t location;
438 attributeBinding, // uint32_t binding;
439 attributeInfo.vkType, // VkFormat format;
440 0u, // uint32_t offset;
444 // Matrix types add each column as a separate attribute.
445 for (int descNdx = 0; descNdx < glslTypeDescription.vertexInputCount; ++descNdx)
447 attributeDescription.vertexInputIndex = descNdx;
448 attributeDescription.vkDescription.location = attributeLocation;
450 if (m_attributeLayout == ATTRIBUTE_LAYOUT_INTERLEAVED)
452 const deUint32 offsetToComponentAlignment = getNextMultipleOffset(getVertexFormatComponentSize(attributeInfo.vkType),
453 (deUint32)bindingOffsets[attributeBinding] + attributeOffsets[attributeBinding]);
454 attributeOffsets[attributeBinding] += offsetToComponentAlignment;
456 attributeDescription.vkDescription.offset = attributeOffsets[attributeBinding];
457 attributeDescriptions.push_back(attributeDescription);
459 bindingDescriptions[attributeBinding].stride += offsetToComponentAlignment + inputSize;
460 attributeOffsets[attributeBinding] += inputSize;
461 attributeMaxSizes[attributeBinding] = de::max(attributeMaxSizes[attributeBinding], getVertexFormatComponentSize(attributeInfo.vkType));
463 else // m_attributeLayout == ATTRIBUTE_LAYOUT_SEQUENTIAL
465 attributeDescription.vkDescription.offset = attributeOffsets[attributeBinding];
466 attributeDescriptions.push_back(attributeDescription);
468 attributeOffsets[attributeBinding] += vertexCount * attributeMaxSizes[attributeBinding];
471 attributeLocation += getConsumedLocations(attributeInfo);
474 if (m_attributeLayout == ATTRIBUTE_LAYOUT_SEQUENTIAL)
475 bindingDescriptions[attributeBinding].stride = attributeMaxSizes[attributeBinding];
478 // Make sure the stride results in aligned access
479 for (size_t bindingNdx = 0; bindingNdx < bindingDescriptions.size(); ++bindingNdx)
481 if (attributeMaxSizes[bindingNdx] > 0)
482 bindingDescriptions[bindingNdx].stride += getNextMultipleOffset(attributeMaxSizes[bindingNdx], bindingDescriptions[bindingNdx].stride);
485 // Check upfront for maximum number of vertex input bindings
487 const InstanceInterface& vki = context.getInstanceInterface();
488 const VkPhysicalDevice physDevice = context.getPhysicalDevice();
489 const VkPhysicalDeviceLimits limits = getPhysicalDeviceProperties(vki, physDevice).limits;
491 const deUint32 maxBindings = limits.maxVertexInputBindings;
493 if (bindingDescriptions.size() > maxBindings)
495 const std::string notSupportedStr = "Unsupported number of vertex input bindings, maxVertexInputBindings: " + de::toString(maxBindings);
496 TCU_THROW(NotSupportedError, notSupportedStr.c_str());
500 return new VertexInputInstance(context, attributeDescriptions, bindingDescriptions, bindingOffsets);
503 void VertexInputTest::initPrograms (SourceCollections& programCollection) const
505 std::ostringstream vertexSrc;
507 vertexSrc << "#version 440\n"
508 << "layout(constant_id = 0) const int numAttributes = " << m_maxAttributes << ";\n"
509 << getGlslInputDeclarations()
510 << "layout(location = 0) out highp vec4 vtxColor;\n"
511 << "out gl_PerVertex {\n"
512 << " vec4 gl_Position;\n"
515 // NOTE: double abs(double x) undefined in glslang ??
516 if (m_usesDoubleType)
517 vertexSrc << "double abs (double x) { if (x < 0.0LF) return -x; else return x; }\n";
519 vertexSrc << "void main (void)\n"
521 << getGlslVertexCheck()
524 programCollection.glslSources.add("attribute_test_vert") << glu::VertexSource(vertexSrc.str());
526 programCollection.glslSources.add("attribute_test_frag") << glu::FragmentSource(
528 "layout(location = 0) in highp vec4 vtxColor;\n"
529 "layout(location = 0) out highp vec4 fragColor;\n"
532 " fragColor = vtxColor;\n"
536 std::string VertexInputTest::getGlslInputDeclarations (void) const
538 std::ostringstream glslInputs;
539 deUint32 location = 0;
541 if (m_queryMaxAttributes)
543 const GlslTypeDescription& glslTypeDesc = s_glslTypeDescriptions[GLSL_TYPE_VEC4];
544 glslInputs << "layout(location = 0) in " << glslTypeDesc.name << " attr[numAttributes];\n";
548 for (size_t attributeNdx = 0; attributeNdx < m_attributeInfos.size(); attributeNdx++)
550 const GlslTypeDescription& glslTypeDesc = s_glslTypeDescriptions[m_attributeInfos[attributeNdx].glslType];
552 glslInputs << "layout(location = " << location << ") in " << glslTypeDesc.name << " attr" << attributeNdx << ";\n";
553 location += glslTypeDesc.vertexInputCount;
557 return glslInputs.str();
560 std::string VertexInputTest::getGlslVertexCheck (void) const
562 std::ostringstream glslCode;
563 int totalInputComponentCount = 0;
565 glslCode << " int okCount = 0;\n";
567 if (m_queryMaxAttributes)
569 const AttributeInfo attributeInfo = getAttributeInfo(0);
571 glslCode << " for (int checkNdx = 0; checkNdx < numAttributes; checkNdx++)\n"
573 << " uint index = (checkNdx % 2 == 0) ? gl_VertexIndex : gl_InstanceIndex;\n";
575 glslCode << getGlslAttributeConditions(attributeInfo, "checkNdx")
578 const int vertexInputCount = VertexInputTest::s_glslTypeDescriptions[attributeInfo.glslType].vertexInputCount;
579 totalInputComponentCount += vertexInputCount * VertexInputTest::s_glslTypeDescriptions[attributeInfo.glslType].vertexInputComponentCount;
582 " if (okCount == " << totalInputComponentCount << " * numAttributes)\n"
584 " if (gl_InstanceIndex == 0)\n"
585 " vtxColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
587 " vtxColor = vec4(0.0, 0.0, 1.0, 1.0);\n"
591 " vtxColor = vec4(okCount / float(" << totalInputComponentCount << " * numAttributes), 0.0f, 0.0f, 1.0);\n" <<
593 " if (gl_InstanceIndex == 0)\n"
595 " if (gl_VertexIndex == 0) gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
596 " else if (gl_VertexIndex == 1) gl_Position = vec4(0.0, -1.0, 0.0, 1.0);\n"
597 " else if (gl_VertexIndex == 2) gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
598 " else if (gl_VertexIndex == 3) gl_Position = vec4(0.0, 1.0, 0.0, 1.0);\n"
599 " else gl_Position = vec4(0.0);\n"
603 " if (gl_VertexIndex == 0) gl_Position = vec4(0.0, -1.0, 0.0, 1.0);\n"
604 " else if (gl_VertexIndex == 1) gl_Position = vec4(1.0, -1.0, 0.0, 1.0);\n"
605 " else if (gl_VertexIndex == 2) gl_Position = vec4(0.0, 1.0, 0.0, 1.0);\n"
606 " else if (gl_VertexIndex == 3) gl_Position = vec4(1.0, 1.0, 0.0, 1.0);\n"
607 " else gl_Position = vec4(0.0);\n"
612 for (size_t attributeNdx = 0; attributeNdx < m_attributeInfos.size(); attributeNdx++)
614 glslCode << getGlslAttributeConditions(m_attributeInfos[attributeNdx], de::toString(attributeNdx));
616 const int vertexInputCount = VertexInputTest::s_glslTypeDescriptions[m_attributeInfos[attributeNdx].glslType].vertexInputCount;
617 totalInputComponentCount += vertexInputCount * VertexInputTest::s_glslTypeDescriptions[m_attributeInfos[attributeNdx].glslType].vertexInputComponentCount;
621 " if (okCount == " << totalInputComponentCount << ")\n"
623 " if (gl_InstanceIndex == 0)\n"
624 " vtxColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
626 " vtxColor = vec4(0.0, 0.0, 1.0, 1.0);\n"
630 " vtxColor = vec4(okCount / float(" << totalInputComponentCount << "), 0.0f, 0.0f, 1.0);\n" <<
632 " if (gl_InstanceIndex == 0)\n"
634 " if (gl_VertexIndex == 0) gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
635 " else if (gl_VertexIndex == 1) gl_Position = vec4(0.0, -1.0, 0.0, 1.0);\n"
636 " else if (gl_VertexIndex == 2) gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
637 " else if (gl_VertexIndex == 3) gl_Position = vec4(0.0, 1.0, 0.0, 1.0);\n"
638 " else gl_Position = vec4(0.0);\n"
642 " if (gl_VertexIndex == 0) gl_Position = vec4(0.0, -1.0, 0.0, 1.0);\n"
643 " else if (gl_VertexIndex == 1) gl_Position = vec4(1.0, -1.0, 0.0, 1.0);\n"
644 " else if (gl_VertexIndex == 2) gl_Position = vec4(0.0, 1.0, 0.0, 1.0);\n"
645 " else if (gl_VertexIndex == 3) gl_Position = vec4(1.0, 1.0, 0.0, 1.0);\n"
646 " else gl_Position = vec4(0.0);\n"
649 return glslCode.str();
652 std::string VertexInputTest::getGlslAttributeConditions (const AttributeInfo& attributeInfo, const std::string attributeIndex) const
654 std::ostringstream glslCode;
655 std::ostringstream attributeVar;
656 const int componentCount = VertexInputTest::s_glslTypeDescriptions[attributeInfo.glslType].vertexInputComponentCount;
657 const int vertexInputCount = VertexInputTest::s_glslTypeDescriptions[attributeInfo.glslType].vertexInputCount;
658 const deUint32 totalComponentCount = componentCount * vertexInputCount;
659 const tcu::Vec4 threshold = getFormatThreshold(attributeInfo.vkType);
660 deUint32 componentIndex = 0;
661 const std::string indexStr = m_queryMaxAttributes ? "[" + attributeIndex + "]" : attributeIndex;
662 const std::string indentStr = m_queryMaxAttributes ? "\t\t" : "\t";
665 if (m_queryMaxAttributes)
668 indexId = (attributeInfo.inputRate == VK_VERTEX_INPUT_RATE_VERTEX) ? "gl_VertexIndex" : "gl_InstanceIndex";
670 attributeVar << "attr" << indexStr;
672 glslCode << std::fixed;
674 for (int columnNdx = 0; columnNdx< vertexInputCount; columnNdx++)
676 for (int rowNdx = 0; rowNdx < componentCount; rowNdx++)
678 std::string accessStr;
680 // Build string representing the access to the attribute component
681 std::ostringstream accessStream;
682 accessStream << attributeVar.str();
684 if (vertexInputCount == 1)
686 if (componentCount > 1)
687 accessStream << "[" << rowNdx << "]";
691 accessStream << "[" << columnNdx << "][" << rowNdx << "]";
694 accessStr = accessStream.str();
697 if (isVertexFormatSint(attributeInfo.vkType))
699 glslCode << indentStr << "if (" << accessStr << " == -(" << totalComponentCount << " * " << indexId << " + " << componentIndex << "))\n";
701 else if (isVertexFormatUint(attributeInfo.vkType))
703 glslCode << indentStr << "if (" << accessStr << " == uint(" << totalComponentCount << " * " << indexId << " + " << componentIndex << "))\n";
705 else if (isVertexFormatSfloat(attributeInfo.vkType))
707 if (VertexInputTest::s_glslTypeDescriptions[attributeInfo.glslType].basicType == VertexInputTest::GLSL_BASIC_TYPE_DOUBLE)
709 glslCode << indentStr << "if (abs(" << accessStr << " + double(0.01 * (" << totalComponentCount << ".0 * float(" << indexId << ") + " << componentIndex << ".0))) < double(" << threshold[rowNdx] << "))\n";
713 glslCode << indentStr << "if (abs(" << accessStr << " + (0.01 * (" << totalComponentCount << ".0 * float(" << indexId << ") + " << componentIndex << ".0))) < " << threshold[rowNdx] << ")\n";
716 else if (isVertexFormatSscaled(attributeInfo.vkType))
718 glslCode << indentStr << "if (abs(" << accessStr << " + (" << totalComponentCount << ".0 * float(" << indexId << ") + " << componentIndex << ".0)) < " << threshold[rowNdx] << ")\n";
720 else if (isVertexFormatUscaled(attributeInfo.vkType))
722 glslCode << indentStr << "if (abs(" << accessStr << " - (" << totalComponentCount << ".0 * float(" << indexId << ") + " << componentIndex << ".0)) < " << threshold[rowNdx] << ")\n";
724 else if (isVertexFormatSnorm(attributeInfo.vkType))
726 const float representableDiff = getRepresentableDifferenceSnorm(attributeInfo.vkType);
728 glslCode << indentStr << "if (abs(" << accessStr << " - (-1.0 + " << representableDiff << " * (" << totalComponentCount << ".0 * float(" << indexId << ") + " << componentIndex << ".0))) < " << threshold[rowNdx] << ")\n";
730 else if (isVertexFormatUnorm(attributeInfo.vkType) || isVertexFormatSRGB(attributeInfo.vkType))
732 const float representableDiff = getRepresentableDifferenceUnorm(attributeInfo.vkType);
734 glslCode << indentStr << "if (abs(" << accessStr << " - " << "(" << representableDiff << " * (" << totalComponentCount << ".0 * float(" << indexId << ") + " << componentIndex << ".0))) < " << threshold[rowNdx] << ")\n";
741 glslCode << indentStr << "\tokCount++;\n\n";
746 return glslCode.str();
749 tcu::Vec4 VertexInputTest::getFormatThreshold (VkFormat format)
755 case VK_FORMAT_R32_SFLOAT:
756 case VK_FORMAT_R32G32_SFLOAT:
757 case VK_FORMAT_R32G32B32_SFLOAT:
758 case VK_FORMAT_R32G32B32A32_SFLOAT:
759 case VK_FORMAT_R64_SFLOAT:
760 case VK_FORMAT_R64G64_SFLOAT:
761 case VK_FORMAT_R64G64B64_SFLOAT:
762 case VK_FORMAT_R64G64B64A64_SFLOAT:
763 return Vec4(0.00001f);
769 if (isVertexFormatSnorm(format))
771 return Vec4(1.5f * getRepresentableDifferenceSnorm(format));
773 else if (isVertexFormatUnorm(format))
775 return Vec4(1.5f * getRepresentableDifferenceUnorm(format));
781 VertexInputInstance::VertexInputInstance (Context& context,
782 const AttributeDescriptionList& attributeDescriptions,
783 const std::vector<VkVertexInputBindingDescription>& bindingDescriptions,
784 const std::vector<VkDeviceSize>& bindingOffsets)
785 : vkt::TestInstance (context)
786 , m_renderSize (16, 16)
787 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
789 DE_ASSERT(bindingDescriptions.size() == bindingOffsets.size());
791 const DeviceInterface& vk = context.getDeviceInterface();
792 const VkDevice vkDevice = context.getDevice();
793 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
794 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
795 const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
797 // Check upfront for unsupported features
798 for (size_t attributeNdx = 0; attributeNdx < attributeDescriptions.size(); attributeNdx++)
800 const VkVertexInputAttributeDescription& attributeDescription = attributeDescriptions[attributeNdx].vkDescription;
801 if (!isSupportedVertexFormat(context, attributeDescription.format))
803 throw tcu::NotSupportedError(std::string("Unsupported format for vertex input: ") + getFormatName(attributeDescription.format));
807 // Create color image
809 const VkImageCreateInfo colorImageParams =
811 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
812 DE_NULL, // const void* pNext;
813 0u, // VkImageCreateFlags flags;
814 VK_IMAGE_TYPE_2D, // VkImageType imageType;
815 m_colorFormat, // VkFormat format;
816 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent;
817 1u, // deUint32 mipLevels;
818 1u, // deUint32 arrayLayers;
819 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
820 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
821 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
822 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
823 1u, // deUint32 queueFamilyIndexCount;
824 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
825 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
828 m_colorImage = createImage(vk, vkDevice, &colorImageParams);
830 // Allocate and bind color image memory
831 m_colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
832 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
835 // Create color attachment view
837 const VkImageViewCreateInfo colorAttachmentViewParams =
839 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
840 DE_NULL, // const void* pNext;
841 0u, // VkImageViewCreateFlags flags;
842 *m_colorImage, // VkImage image;
843 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
844 m_colorFormat, // VkFormat format;
845 componentMappingRGBA, // VkComponentMapping components;
846 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
849 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
852 // Create render pass
854 const VkAttachmentDescription colorAttachmentDescription =
856 0u, // VkAttachmentDescriptionFlags flags;
857 m_colorFormat, // VkFormat format;
858 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
859 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
860 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
861 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
862 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
863 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
864 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
867 const VkAttachmentReference colorAttachmentReference =
869 0u, // deUint32 attachment;
870 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
873 const VkSubpassDescription subpassDescription =
875 0u, // VkSubpassDescriptionFlags flags;
876 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
877 0u, // deUint32 inputAttachmentCount;
878 DE_NULL, // const VkAttachmentReference* pInputAttachments;
879 1u, // deUint32 colorAttachmentCount;
880 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments;
881 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
882 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
883 0u, // deUint32 preserveAttachmentCount;
884 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
887 const VkRenderPassCreateInfo renderPassParams =
889 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
890 DE_NULL, // const void* pNext;
891 0u, // VkRenderPassCreateFlags flags;
892 1u, // deUint32 attachmentCount;
893 &colorAttachmentDescription, // const VkAttachmentDescription* pAttachments;
894 1u, // deUint32 subpassCount;
895 &subpassDescription, // const VkSubpassDescription* pSubpasses;
896 0u, // deUint32 dependencyCount;
897 DE_NULL // const VkSubpassDependency* pDependencies;
900 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
903 // Create framebuffer
905 const VkFramebufferCreateInfo framebufferParams =
907 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
908 DE_NULL, // const void* pNext;
909 0u, // VkFramebufferCreateFlags flags;
910 *m_renderPass, // VkRenderPass renderPass;
911 1u, // deUint32 attachmentCount;
912 &m_colorAttachmentView.get(), // const VkImageView* pAttachments;
913 (deUint32)m_renderSize.x(), // deUint32 width;
914 (deUint32)m_renderSize.y(), // deUint32 height;
915 1u // deUint32 layers;
918 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
921 // Create pipeline layout
923 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
925 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
926 DE_NULL, // const void* pNext;
927 0u, // VkPipelineLayoutCreateFlags flags;
928 0u, // deUint32 setLayoutCount;
929 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
930 0u, // deUint32 pushConstantRangeCount;
931 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
934 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
937 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("attribute_test_vert"), 0);
938 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("attribute_test_frag"), 0);
940 // Create specialization constant
941 deUint32 specializationData = static_cast<deUint32>(attributeDescriptions.size());
943 const VkSpecializationMapEntry specializationMapEntry =
945 0, // uint32_t constantID
946 0, // uint32_t offset
947 sizeof(specializationData), // uint32_t size
950 const VkSpecializationInfo specializationInfo =
952 1, // uint32_t mapEntryCount
953 &specializationMapEntry, // const void* pMapEntries
954 sizeof(specializationData), // size_t dataSize
955 &specializationData // const void* pData
960 const VkPipelineShaderStageCreateInfo shaderStageParams[2] =
963 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
964 DE_NULL, // const void* pNext;
965 0u, // VkPipelineShaderStageCreateFlags flags;
966 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
967 *m_vertexShaderModule, // VkShaderModule module;
968 "main", // const char* pName;
969 &specializationInfo // const VkSpecializationInfo* pSpecializationInfo;
972 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
973 DE_NULL, // const void* pNext;
974 0u, // VkPipelineShaderStageCreateFlags flags;
975 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage;
976 *m_fragmentShaderModule, // VkShaderModule module;
977 "main", // const char* pName;
978 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
982 // Create vertex attribute array and check if their VK formats are supported
983 std::vector<VkVertexInputAttributeDescription> vkAttributeDescriptions;
984 for (size_t attributeNdx = 0; attributeNdx < attributeDescriptions.size(); attributeNdx++)
986 const VkVertexInputAttributeDescription& attributeDescription = attributeDescriptions[attributeNdx].vkDescription;
987 vkAttributeDescriptions.push_back(attributeDescription);
990 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
992 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
993 DE_NULL, // const void* pNext;
994 0u, // VkPipelineVertexInputStateCreateFlags flags;
995 (deUint32)bindingDescriptions.size(), // deUint32 vertexBindingDescriptionCount;
996 bindingDescriptions.data(), // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
997 (deUint32)vkAttributeDescriptions.size(), // deUint32 vertexAttributeDescriptionCount;
998 vkAttributeDescriptions.data() // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1001 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
1003 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
1004 DE_NULL, // const void* pNext;
1005 0u, // VkPipelineInputAssemblyStateCreateFlags flags;
1006 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // VkPrimitiveTopology topology;
1007 false // VkBool32 primitiveRestartEnable;
1010 const VkViewport viewport =
1014 (float)m_renderSize.x(), // float width;
1015 (float)m_renderSize.y(), // float height;
1016 0.0f, // float minDepth;
1017 1.0f // float maxDepth;
1020 const VkRect2D scissor = { { 0, 0 }, { m_renderSize.x(), m_renderSize.y() } };
1022 const VkPipelineViewportStateCreateInfo viewportStateParams =
1024 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
1025 DE_NULL, // const void* pNext;
1026 0u, // VkPipelineViewportStateCreateFlags flags;
1027 1u, // deUint32 viewportCount;
1028 &viewport, // const VkViewport* pViewports;
1029 1u, // deUint32 scissorCount;
1030 &scissor // const VkRect2D* pScissors;
1033 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
1035 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
1036 DE_NULL, // const void* pNext;
1037 0u, // VkPipelineRasterizationStateCreateFlags flags;
1038 false, // VkBool32 depthClampEnable;
1039 false, // VkBool32 rasterizerDiscardEnable;
1040 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
1041 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
1042 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
1043 VK_FALSE, // VkBool32 depthBiasEnable;
1044 0.0f, // float depthBiasConstantFactor;
1045 0.0f, // float depthBiasClamp;
1046 0.0f, // float depthBiasSlopeFactor;
1047 1.0f, // float lineWidth;
1050 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
1052 false, // VkBool32 blendEnable;
1053 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
1054 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
1055 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
1056 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
1057 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
1058 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
1059 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // VkColorComponentFlags colorWriteMask;
1060 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
1063 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
1065 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1066 DE_NULL, // const void* pNext;
1067 0u, // VkPipelineColorBlendStateCreateFlags flags;
1068 false, // VkBool32 logicOpEnable;
1069 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
1070 1u, // deUint32 attachmentCount;
1071 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
1072 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4];
1075 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1077 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
1078 DE_NULL, // const void* pNext;
1079 0u, // VkPipelineMultisampleStateCreateFlags flags;
1080 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
1081 false, // VkBool32 sampleShadingEnable;
1082 0.0f, // float minSampleShading;
1083 DE_NULL, // const VkSampleMask* pSampleMask;
1084 false, // VkBool32 alphaToCoverageEnable;
1085 false // VkBool32 alphaToOneEnable;
1088 VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
1090 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
1091 DE_NULL, // const void* pNext;
1092 0u, // VkPipelineDepthStencilStateCreateFlags flags;
1093 false, // VkBool32 depthTestEnable;
1094 false, // VkBool32 depthWriteEnable;
1095 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
1096 false, // VkBool32 depthBoundsTestEnable;
1097 false, // VkBool32 stencilTestEnable;
1098 // VkStencilOpState front;
1100 VK_STENCIL_OP_KEEP, // VkStencilOp failOp;
1101 VK_STENCIL_OP_KEEP, // VkStencilOp passOp;
1102 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp;
1103 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
1104 0u, // deUint32 compareMask;
1105 0u, // deUint32 writeMask;
1106 0u, // deUint32 reference;
1108 // VkStencilOpState back;
1110 VK_STENCIL_OP_KEEP, // VkStencilOp failOp;
1111 VK_STENCIL_OP_KEEP, // VkStencilOp passOp;
1112 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp;
1113 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
1114 0u, // deUint32 compareMask;
1115 0u, // deUint32 writeMask;
1116 0u, // deUint32 reference;
1118 0.0f, // float minDepthBounds;
1119 1.0f, // float maxDepthBounds;
1122 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
1124 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
1125 DE_NULL, // const void* pNext;
1126 0u, // VkPipelineCreateFlags flags;
1127 2u, // deUint32 stageCount;
1128 shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages;
1129 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
1130 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
1131 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
1132 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
1133 &rasterStateParams, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
1134 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
1135 &depthStencilStateParams, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
1136 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
1137 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
1138 *m_pipelineLayout, // VkPipelineLayout layout;
1139 *m_renderPass, // VkRenderPass renderPass;
1140 0u, // deUint32 subpass;
1141 0u, // VkPipeline basePipelineHandle;
1142 0u // deInt32 basePipelineIndex;
1145 m_graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
1148 // Create vertex buffer
1150 const VkBufferCreateInfo vertexBufferParams =
1152 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1153 DE_NULL, // const void* pNext;
1154 0u, // VkBufferCreateFlags flags;
1155 4096u, // VkDeviceSize size;
1156 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
1157 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1158 1u, // deUint32 queueFamilyIndexCount;
1159 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1162 // Upload data for each vertex input binding
1163 for (deUint32 bindingNdx = 0; bindingNdx < bindingDescriptions.size(); bindingNdx++)
1165 Move<VkBuffer> vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
1166 de::MovePtr<Allocation> vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
1168 VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset()));
1170 writeVertexInputData((deUint8*)vertexBufferAlloc->getHostPtr(), bindingDescriptions[bindingNdx], bindingOffsets[bindingNdx], attributeDescriptions);
1171 flushMappedMemoryRange(vk, vkDevice, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset(), vertexBufferParams.size);
1173 m_vertexBuffers.push_back(vertexBuffer.disown());
1174 m_vertexBufferAllocs.push_back(vertexBufferAlloc.release());
1178 // Create command pool
1179 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1181 // Create command buffer
1183 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1185 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1186 DE_NULL, // const void* pNext;
1187 0u, // VkCommandBufferUsageFlags flags;
1188 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1191 const VkClearValue attachmentClearValue = defaultClearValue(m_colorFormat);
1193 const VkRenderPassBeginInfo renderPassBeginInfo =
1195 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
1196 DE_NULL, // const void* pNext;
1197 *m_renderPass, // VkRenderPass renderPass;
1198 *m_framebuffer, // VkFramebuffer framebuffer;
1199 { { 0, 0 }, { m_renderSize.x(), m_renderSize.y() } }, // VkRect2D renderArea;
1200 1u, // deUint32 clearValueCount;
1201 &attachmentClearValue // const VkClearValue* pClearValues;
1204 const VkImageMemoryBarrier attachmentLayoutBarrier =
1206 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1207 DE_NULL, // const void* pNext;
1208 0u, // VkAccessFlags srcAccessMask;
1209 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
1210 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1211 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
1212 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1213 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1214 *m_colorImage, // VkImage image;
1215 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
1218 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1220 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1222 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0,
1223 0u, DE_NULL, 0u, DE_NULL, 1u, &attachmentLayoutBarrier);
1225 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1227 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
1229 std::vector<VkBuffer> vertexBuffers;
1230 for (size_t bufferNdx = 0; bufferNdx < m_vertexBuffers.size(); bufferNdx++)
1231 vertexBuffers.push_back(m_vertexBuffers[bufferNdx]);
1233 if (vertexBuffers.size() <= 1)
1235 // One vertex buffer
1236 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, (deUint32)vertexBuffers.size(), vertexBuffers.data(), bindingOffsets.data());
1240 // Smoke-test vkCmdBindVertexBuffers(..., startBinding, ... )
1242 const deUint32 firstHalfLength = (deUint32)vertexBuffers.size() / 2;
1243 const deUint32 secondHalfLength = firstHalfLength + (deUint32)(vertexBuffers.size() % 2);
1245 // Bind first half of vertex buffers
1246 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, firstHalfLength, vertexBuffers.data(), bindingOffsets.data());
1248 // Bind second half of vertex buffers
1249 vk.cmdBindVertexBuffers(*m_cmdBuffer, firstHalfLength, secondHalfLength,
1250 vertexBuffers.data() + firstHalfLength,
1251 bindingOffsets.data() + firstHalfLength);
1254 vk.cmdDraw(*m_cmdBuffer, 4, 2, 0, 0);
1256 vk.cmdEndRenderPass(*m_cmdBuffer);
1257 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1261 m_fence = createFence(vk, vkDevice);
1264 VertexInputInstance::~VertexInputInstance (void)
1266 const DeviceInterface& vk = m_context.getDeviceInterface();
1267 const VkDevice vkDevice = m_context.getDevice();
1269 for (size_t bufferNdx = 0; bufferNdx < m_vertexBuffers.size(); bufferNdx++)
1270 vk.destroyBuffer(vkDevice, m_vertexBuffers[bufferNdx], DE_NULL);
1272 for (size_t allocNdx = 0; allocNdx < m_vertexBufferAllocs.size(); allocNdx++)
1273 delete m_vertexBufferAllocs[allocNdx];
1276 void VertexInputInstance::writeVertexInputData(deUint8* destPtr, const VkVertexInputBindingDescription& bindingDescription, const VkDeviceSize bindingOffset, const AttributeDescriptionList& attributes)
1278 const deUint32 vertexCount = (bindingDescription.inputRate == VK_VERTEX_INPUT_RATE_VERTEX) ? (4 * 2) : 2;
1280 deUint8* destOffsetPtr = ((deUint8 *)destPtr) + bindingOffset;
1281 for (deUint32 vertexNdx = 0; vertexNdx < vertexCount; vertexNdx++)
1283 for (size_t attributeNdx = 0; attributeNdx < attributes.size(); attributeNdx++)
1285 const VertexInputAttributeDescription& attribDesc = attributes[attributeNdx];
1287 // Only write vertex input data to bindings referenced by attribute descriptions
1288 if (attribDesc.vkDescription.binding == bindingDescription.binding)
1290 writeVertexInputValue(destOffsetPtr + attribDesc.vkDescription.offset, attribDesc, vertexNdx);
1293 destOffsetPtr += bindingDescription.stride;
1297 void writeVertexInputValueSint (deUint8* destPtr, VkFormat format, int componentNdx, deInt32 value)
1299 const deUint32 componentSize = getVertexFormatComponentSize(format);
1300 deUint8* destFormatPtr = ((deUint8*)destPtr) + componentSize * componentNdx;
1302 switch (componentSize)
1305 *((deInt8*)destFormatPtr) = (deInt8)value;
1309 *((deInt16*)destFormatPtr) = (deInt16)value;
1313 *((deInt32*)destFormatPtr) = (deInt32)value;
1321 void writeVertexInputValueUint (deUint8* destPtr, VkFormat format, int componentNdx, deUint32 value)
1323 const deUint32 componentSize = getVertexFormatComponentSize(format);
1324 deUint8* destFormatPtr = ((deUint8*)destPtr) + componentSize * componentNdx;
1326 switch (componentSize)
1329 *((deUint8 *)destFormatPtr) = (deUint8)value;
1333 *((deUint16 *)destFormatPtr) = (deUint16)value;
1337 *((deUint32 *)destFormatPtr) = (deUint32)value;
1345 void writeVertexInputValueSfloat (deUint8* destPtr, VkFormat format, int componentNdx, float value)
1347 const deUint32 componentSize = getVertexFormatComponentSize(format);
1348 deUint8* destFormatPtr = ((deUint8*)destPtr) + componentSize * componentNdx;
1350 switch (componentSize)
1354 deFloat16 f16 = deFloat32To16(value);
1355 deMemcpy(destFormatPtr, &f16, sizeof(f16));
1360 deMemcpy(destFormatPtr, &value, sizeof(value));
1368 void VertexInputInstance::writeVertexInputValue (deUint8* destPtr, const VertexInputAttributeDescription& attribute, int indexId)
1370 const int vertexInputCount = VertexInputTest::s_glslTypeDescriptions[attribute.glslType].vertexInputCount;
1371 const int componentCount = VertexInputTest::s_glslTypeDescriptions[attribute.glslType].vertexInputComponentCount;
1372 const deUint32 totalComponentCount = componentCount * vertexInputCount;
1373 const deUint32 vertexInputIndex = indexId * totalComponentCount + attribute.vertexInputIndex * componentCount;
1374 const bool hasBGROrder = isVertexFormatComponentOrderBGR(attribute.vkDescription.format);
1377 for (int componentNdx = 0; componentNdx < componentCount; componentNdx++)
1381 if (componentNdx == 0)
1383 else if (componentNdx == 2)
1386 swizzledNdx = componentNdx;
1389 swizzledNdx = componentNdx;
1391 switch (attribute.glslType)
1393 case VertexInputTest::GLSL_TYPE_INT:
1394 case VertexInputTest::GLSL_TYPE_IVEC2:
1395 case VertexInputTest::GLSL_TYPE_IVEC3:
1396 case VertexInputTest::GLSL_TYPE_IVEC4:
1397 writeVertexInputValueSint(destPtr, attribute.vkDescription.format, componentNdx, -(deInt32)(vertexInputIndex + swizzledNdx));
1400 case VertexInputTest::GLSL_TYPE_UINT:
1401 case VertexInputTest::GLSL_TYPE_UVEC2:
1402 case VertexInputTest::GLSL_TYPE_UVEC3:
1403 case VertexInputTest::GLSL_TYPE_UVEC4:
1404 writeVertexInputValueUint(destPtr, attribute.vkDescription.format, componentNdx, vertexInputIndex + swizzledNdx);
1407 case VertexInputTest::GLSL_TYPE_FLOAT:
1408 case VertexInputTest::GLSL_TYPE_VEC2:
1409 case VertexInputTest::GLSL_TYPE_VEC3:
1410 case VertexInputTest::GLSL_TYPE_VEC4:
1411 case VertexInputTest::GLSL_TYPE_MAT2:
1412 case VertexInputTest::GLSL_TYPE_MAT3:
1413 case VertexInputTest::GLSL_TYPE_MAT4:
1414 if (isVertexFormatSfloat(attribute.vkDescription.format))
1416 writeVertexInputValueSfloat(destPtr, attribute.vkDescription.format, componentNdx, -(0.01f * (float)(vertexInputIndex + swizzledNdx)));
1418 else if (isVertexFormatSscaled(attribute.vkDescription.format))
1420 writeVertexInputValueSint(destPtr, attribute.vkDescription.format, componentNdx, -(deInt32)(vertexInputIndex + swizzledNdx));
1422 else if (isVertexFormatUscaled(attribute.vkDescription.format) || isVertexFormatUnorm(attribute.vkDescription.format) || isVertexFormatSRGB(attribute.vkDescription.format))
1424 writeVertexInputValueUint(destPtr, attribute.vkDescription.format, componentNdx, vertexInputIndex + swizzledNdx);
1426 else if (isVertexFormatSnorm(attribute.vkDescription.format))
1428 const deInt32 minIntValue = -((1 << (getVertexFormatComponentSize(attribute.vkDescription.format) * 8 - 1))) + 1;
1429 writeVertexInputValueSint(destPtr, attribute.vkDescription.format, componentNdx, minIntValue + (vertexInputIndex + swizzledNdx));
1435 case VertexInputTest::GLSL_TYPE_DOUBLE:
1436 case VertexInputTest::GLSL_TYPE_DVEC2:
1437 case VertexInputTest::GLSL_TYPE_DVEC3:
1438 case VertexInputTest::GLSL_TYPE_DVEC4:
1439 case VertexInputTest::GLSL_TYPE_DMAT2:
1440 case VertexInputTest::GLSL_TYPE_DMAT3:
1441 case VertexInputTest::GLSL_TYPE_DMAT4:
1442 *(reinterpret_cast<double *>(destPtr) + componentNdx) = -0.01 * (vertexInputIndex + swizzledNdx);
1452 tcu::TestStatus VertexInputInstance::iterate (void)
1454 const DeviceInterface& vk = m_context.getDeviceInterface();
1455 const VkDevice vkDevice = m_context.getDevice();
1456 const VkQueue queue = m_context.getUniversalQueue();
1457 const VkSubmitInfo submitInfo =
1459 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
1460 DE_NULL, // const void* pNext;
1461 0u, // deUint32 waitSemaphoreCount;
1462 DE_NULL, // const VkSemaphore* pWaitSemaphores;
1463 (const VkPipelineStageFlags*)DE_NULL,
1464 1u, // deUint32 commandBufferCount;
1465 &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
1466 0u, // deUint32 signalSemaphoreCount;
1467 DE_NULL // const VkSemaphore* pSignalSemaphores;
1470 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1471 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
1472 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/));
1474 return verifyImage();
1477 bool VertexInputTest::isCompatibleType (VkFormat format, GlslType glslType)
1479 const GlslTypeDescription glslTypeDesc = s_glslTypeDescriptions[glslType];
1481 if ((deUint32)s_glslTypeDescriptions[glslType].vertexInputComponentCount == getVertexFormatComponentCount(format))
1483 switch (glslTypeDesc.basicType)
1485 case GLSL_BASIC_TYPE_INT:
1486 return isVertexFormatSint(format);
1488 case GLSL_BASIC_TYPE_UINT:
1489 return isVertexFormatUint(format);
1491 case GLSL_BASIC_TYPE_FLOAT:
1492 return getVertexFormatComponentSize(format) <= 4 && (isVertexFormatSfloat(format) || isVertexFormatSnorm(format) || isVertexFormatUnorm(format) || isVertexFormatSscaled(format) || isVertexFormatUscaled(format) || isVertexFormatSRGB(format));
1494 case GLSL_BASIC_TYPE_DOUBLE:
1495 return isVertexFormatSfloat(format) && getVertexFormatComponentSize(format) == 8;
1506 tcu::TestStatus VertexInputInstance::verifyImage (void)
1508 bool compareOk = false;
1509 const tcu::TextureFormat tcuColorFormat = mapVkFormat(m_colorFormat);
1510 tcu::TextureLevel reference (tcuColorFormat, m_renderSize.x(), m_renderSize.y());
1511 const tcu::PixelBufferAccess refRedSubregion (tcu::getSubregion(reference.getAccess(),
1512 deRoundFloatToInt32((float)m_renderSize.x() * 0.0f),
1513 deRoundFloatToInt32((float)m_renderSize.y() * 0.0f),
1514 deRoundFloatToInt32((float)m_renderSize.x() * 0.5f),
1515 deRoundFloatToInt32((float)m_renderSize.y() * 1.0f)));
1516 const tcu::PixelBufferAccess refBlueSubregion (tcu::getSubregion(reference.getAccess(),
1517 deRoundFloatToInt32((float)m_renderSize.x() * 0.5f),
1518 deRoundFloatToInt32((float)m_renderSize.y() * 0.0f),
1519 deRoundFloatToInt32((float)m_renderSize.x() * 0.5f),
1520 deRoundFloatToInt32((float)m_renderSize.y() * 1.0f)));
1522 // Create reference image
1523 tcu::clear(reference.getAccess(), defaultClearColor(tcuColorFormat));
1524 tcu::clear(refRedSubregion, tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
1525 tcu::clear(refBlueSubregion, tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
1527 // Compare result with reference image
1529 const DeviceInterface& vk = m_context.getDeviceInterface();
1530 const VkDevice vkDevice = m_context.getDevice();
1531 const VkQueue queue = m_context.getUniversalQueue();
1532 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1533 SimpleAllocator allocator (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
1534 de::MovePtr<tcu::TextureLevel> result = readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize);
1536 compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
1539 reference.getAccess(),
1540 result->getAccess(),
1541 tcu::UVec4(2, 2, 2, 2),
1542 tcu::IVec3(1, 1, 0),
1544 tcu::COMPARE_LOG_RESULT);
1548 return tcu::TestStatus::pass("Result image matches reference");
1550 return tcu::TestStatus::fail("Image mismatch");
1553 std::string getAttributeInfoCaseName (const VertexInputTest::AttributeInfo& attributeInfo)
1555 std::ostringstream caseName;
1556 const std::string formatName = getFormatName(attributeInfo.vkType);
1558 caseName << "as_" << de::toLower(formatName.substr(10)) << "_rate_";
1560 if (attributeInfo.inputRate == VK_VERTEX_INPUT_RATE_VERTEX)
1561 caseName << "vertex";
1563 caseName << "instance";
1565 return caseName.str();
1568 std::string getAttributeInfoDescription (const VertexInputTest::AttributeInfo& attributeInfo)
1570 std::ostringstream caseDesc;
1572 caseDesc << std::string(VertexInputTest::s_glslTypeDescriptions[attributeInfo.glslType].name) << " from type " << getFormatName(attributeInfo.vkType) << " with ";
1574 if (attributeInfo.inputRate == VK_VERTEX_INPUT_RATE_VERTEX)
1575 caseDesc << "vertex input rate ";
1577 caseDesc << "instance input rate ";
1579 return caseDesc.str();
1582 std::string getAttributeInfosDescription (const std::vector<VertexInputTest::AttributeInfo>& attributeInfos)
1584 std::ostringstream caseDesc;
1586 caseDesc << "Uses vertex attributes:\n";
1588 for (size_t attributeNdx = 0; attributeNdx < attributeInfos.size(); attributeNdx++)
1589 caseDesc << "\t- " << getAttributeInfoDescription (attributeInfos[attributeNdx]) << "\n";
1591 return caseDesc.str();
1594 struct CompatibleFormats
1596 VertexInputTest::GlslType glslType;
1597 std::vector<VkFormat> compatibleVkFormats;
1600 void createSingleAttributeCases (tcu::TestCaseGroup* singleAttributeTests, VertexInputTest::GlslType glslType)
1602 const VkFormat vertexFormats[] =
1604 // Required, unpacked
1609 VK_FORMAT_R8G8_UNORM,
1610 VK_FORMAT_R8G8_SNORM,
1611 VK_FORMAT_R8G8_UINT,
1612 VK_FORMAT_R8G8_SINT,
1613 VK_FORMAT_R8G8B8A8_UNORM,
1614 VK_FORMAT_R8G8B8A8_SNORM,
1615 VK_FORMAT_R8G8B8A8_UINT,
1616 VK_FORMAT_R8G8B8A8_SINT,
1617 VK_FORMAT_B8G8R8A8_UNORM,
1618 VK_FORMAT_R16_UNORM,
1619 VK_FORMAT_R16_SNORM,
1622 VK_FORMAT_R16_SFLOAT,
1623 VK_FORMAT_R16G16_UNORM,
1624 VK_FORMAT_R16G16_SNORM,
1625 VK_FORMAT_R16G16_UINT,
1626 VK_FORMAT_R16G16_SINT,
1627 VK_FORMAT_R16G16_SFLOAT,
1628 VK_FORMAT_R16G16B16A16_UNORM,
1629 VK_FORMAT_R16G16B16A16_SNORM,
1630 VK_FORMAT_R16G16B16A16_UINT,
1631 VK_FORMAT_R16G16B16A16_SINT,
1632 VK_FORMAT_R16G16B16A16_SFLOAT,
1635 VK_FORMAT_R32_SFLOAT,
1636 VK_FORMAT_R32G32_UINT,
1637 VK_FORMAT_R32G32_SINT,
1638 VK_FORMAT_R32G32_SFLOAT,
1639 VK_FORMAT_R32G32B32_UINT,
1640 VK_FORMAT_R32G32B32_SINT,
1641 VK_FORMAT_R32G32B32_SFLOAT,
1642 VK_FORMAT_R32G32B32A32_UINT,
1643 VK_FORMAT_R32G32B32A32_SINT,
1644 VK_FORMAT_R32G32B32A32_SFLOAT,
1647 VK_FORMAT_R8G8_USCALED,
1648 VK_FORMAT_R8G8_SSCALED,
1649 VK_FORMAT_R16_USCALED,
1650 VK_FORMAT_R16_SSCALED,
1651 VK_FORMAT_R8G8B8_USCALED,
1652 VK_FORMAT_R8G8B8_SSCALED,
1653 VK_FORMAT_B8G8R8_USCALED,
1654 VK_FORMAT_B8G8R8_SSCALED,
1655 VK_FORMAT_R8G8B8A8_USCALED,
1656 VK_FORMAT_R8G8B8A8_SSCALED,
1657 VK_FORMAT_B8G8R8A8_USCALED,
1658 VK_FORMAT_B8G8R8A8_SSCALED,
1659 VK_FORMAT_R16G16_USCALED,
1660 VK_FORMAT_R16G16_SSCALED,
1661 VK_FORMAT_R16G16B16_USCALED,
1662 VK_FORMAT_R16G16B16_SSCALED,
1663 VK_FORMAT_R16G16B16A16_USCALED,
1664 VK_FORMAT_R16G16B16A16_SSCALED,
1668 VK_FORMAT_R8G8_SRGB,
1669 VK_FORMAT_R8G8B8_SRGB,
1670 VK_FORMAT_B8G8R8_SRGB,
1671 VK_FORMAT_R8G8B8A8_SRGB,
1672 VK_FORMAT_B8G8R8A8_SRGB,
1675 VK_FORMAT_R64_SFLOAT,
1676 VK_FORMAT_R64G64_SFLOAT,
1677 VK_FORMAT_R64G64B64_SFLOAT,
1678 VK_FORMAT_R64G64B64A64_SFLOAT,
1681 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(vertexFormats); formatNdx++)
1683 if (VertexInputTest::isCompatibleType(vertexFormats[formatNdx], glslType))
1685 // Create test case for RATE_VERTEX
1686 VertexInputTest::AttributeInfo attributeInfo;
1687 attributeInfo.vkType = vertexFormats[formatNdx];
1688 attributeInfo.glslType = glslType;
1689 attributeInfo.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
1691 singleAttributeTests->addChild(new VertexInputTest(singleAttributeTests->getTestContext(),
1692 getAttributeInfoCaseName(attributeInfo),
1693 getAttributeInfoDescription(attributeInfo),
1694 std::vector<VertexInputTest::AttributeInfo>(1, attributeInfo),
1695 VertexInputTest::BINDING_MAPPING_ONE_TO_ONE,
1696 VertexInputTest::ATTRIBUTE_LAYOUT_INTERLEAVED));
1698 // Create test case for RATE_INSTANCE
1699 attributeInfo.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE;
1701 singleAttributeTests->addChild(new VertexInputTest(singleAttributeTests->getTestContext(),
1702 getAttributeInfoCaseName(attributeInfo),
1703 getAttributeInfoDescription(attributeInfo),
1704 std::vector<VertexInputTest::AttributeInfo>(1, attributeInfo),
1705 VertexInputTest::BINDING_MAPPING_ONE_TO_ONE,
1706 VertexInputTest::ATTRIBUTE_LAYOUT_INTERLEAVED));
1711 void createSingleAttributeTests (tcu::TestCaseGroup* singleAttributeTests)
1713 for (int glslTypeNdx = 0; glslTypeNdx < VertexInputTest::GLSL_TYPE_COUNT; glslTypeNdx++)
1715 VertexInputTest::GlslType glslType = (VertexInputTest::GlslType)glslTypeNdx;
1716 addTestGroup(singleAttributeTests, VertexInputTest::s_glslTypeDescriptions[glslType].name, "", createSingleAttributeCases, glslType);
1720 // Create all unique GlslType combinations recursively
1721 void createMultipleAttributeCases (deUint32 depth, deUint32 firstNdx, CompatibleFormats* compatibleFormats, de::Random& randomFunc, tcu::TestCaseGroup& testGroup, VertexInputTest::BindingMapping bindingMapping, VertexInputTest::AttributeLayout attributeLayout, const std::vector<VertexInputTest::AttributeInfo>& attributeInfos = std::vector<VertexInputTest::AttributeInfo>(0))
1723 tcu::TestContext& testCtx = testGroup.getTestContext();
1725 // Exclude double values, which are not included in vertexFormats
1726 for (deUint32 currentNdx = firstNdx; currentNdx < VertexInputTest::GLSL_TYPE_DOUBLE - depth; currentNdx++)
1728 std::vector <VertexInputTest::AttributeInfo> newAttributeInfos = attributeInfos;
1731 VertexInputTest::AttributeInfo attributeInfo;
1732 attributeInfo.glslType = (VertexInputTest::GlslType)currentNdx;
1733 attributeInfo.inputRate = (depth % 2 == 0) ? VK_VERTEX_INPUT_RATE_VERTEX : VK_VERTEX_INPUT_RATE_INSTANCE;
1734 attributeInfo.vkType = VK_FORMAT_LAST;
1736 newAttributeInfos.push_back(attributeInfo);
1742 // Select a random compatible format for each attribute
1743 for (size_t i = 0; i < newAttributeInfos.size(); i++)
1745 const std::vector<VkFormat>& formats = compatibleFormats[newAttributeInfos[i].glslType].compatibleVkFormats;
1746 newAttributeInfos[i].vkType = formats[randomFunc.getUint32() % formats.size()];
1749 const std::string caseName = VertexInputTest::s_glslTypeDescriptions[currentNdx].name;
1750 const std::string caseDesc = getAttributeInfosDescription(newAttributeInfos);
1752 testGroup.addChild(new VertexInputTest(testCtx, caseName, caseDesc, newAttributeInfos, bindingMapping, attributeLayout));
1757 const std::string name = VertexInputTest::s_glslTypeDescriptions[currentNdx].name;
1758 de::MovePtr<tcu::TestCaseGroup> newTestGroup (new tcu::TestCaseGroup(testCtx, name.c_str(), ""));
1760 createMultipleAttributeCases(depth - 1u, currentNdx + 1u, compatibleFormats, randomFunc, *newTestGroup, bindingMapping, attributeLayout, newAttributeInfos);
1761 testGroup.addChild(newTestGroup.release());
1766 void createMultipleAttributeTests (tcu::TestCaseGroup* multipleAttributeTests)
1768 // Required vertex formats, unpacked
1769 const VkFormat vertexFormats[] =
1775 VK_FORMAT_R8G8_UNORM,
1776 VK_FORMAT_R8G8_SNORM,
1777 VK_FORMAT_R8G8_UINT,
1778 VK_FORMAT_R8G8_SINT,
1779 VK_FORMAT_R8G8B8A8_UNORM,
1780 VK_FORMAT_R8G8B8A8_SNORM,
1781 VK_FORMAT_R8G8B8A8_UINT,
1782 VK_FORMAT_R8G8B8A8_SINT,
1783 VK_FORMAT_B8G8R8A8_UNORM,
1784 VK_FORMAT_R16_UNORM,
1785 VK_FORMAT_R16_SNORM,
1788 VK_FORMAT_R16_SFLOAT,
1789 VK_FORMAT_R16G16_UNORM,
1790 VK_FORMAT_R16G16_SNORM,
1791 VK_FORMAT_R16G16_UINT,
1792 VK_FORMAT_R16G16_SINT,
1793 VK_FORMAT_R16G16_SFLOAT,
1794 VK_FORMAT_R16G16B16A16_UNORM,
1795 VK_FORMAT_R16G16B16A16_SNORM,
1796 VK_FORMAT_R16G16B16A16_UINT,
1797 VK_FORMAT_R16G16B16A16_SINT,
1798 VK_FORMAT_R16G16B16A16_SFLOAT,
1801 VK_FORMAT_R32_SFLOAT,
1802 VK_FORMAT_R32G32_UINT,
1803 VK_FORMAT_R32G32_SINT,
1804 VK_FORMAT_R32G32_SFLOAT,
1805 VK_FORMAT_R32G32B32_UINT,
1806 VK_FORMAT_R32G32B32_SINT,
1807 VK_FORMAT_R32G32B32_SFLOAT,
1808 VK_FORMAT_R32G32B32A32_UINT,
1809 VK_FORMAT_R32G32B32A32_SINT,
1810 VK_FORMAT_R32G32B32A32_SFLOAT
1813 // Find compatible VK formats for each GLSL vertex type
1814 CompatibleFormats compatibleFormats[VertexInputTest::GLSL_TYPE_COUNT];
1816 for (int glslTypeNdx = 0; glslTypeNdx < VertexInputTest::GLSL_TYPE_COUNT; glslTypeNdx++)
1818 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(vertexFormats); formatNdx++)
1820 if (VertexInputTest::isCompatibleType(vertexFormats[formatNdx], (VertexInputTest::GlslType)glslTypeNdx))
1821 compatibleFormats[glslTypeNdx].compatibleVkFormats.push_back(vertexFormats[formatNdx]);
1826 de::Random randomFunc(102030);
1827 tcu::TestContext& testCtx = multipleAttributeTests->getTestContext();
1828 de::MovePtr<tcu::TestCaseGroup> oneToOneAttributeTests(new tcu::TestCaseGroup(testCtx, "attributes", ""));
1829 de::MovePtr<tcu::TestCaseGroup> oneToManyAttributeTests(new tcu::TestCaseGroup(testCtx, "attributes", ""));
1830 de::MovePtr<tcu::TestCaseGroup> oneToManySequentialAttributeTests(new tcu::TestCaseGroup(testCtx, "attributes_sequential", ""));
1832 createMultipleAttributeCases(2u, 0u, compatibleFormats, randomFunc, *oneToOneAttributeTests, VertexInputTest::BINDING_MAPPING_ONE_TO_ONE, VertexInputTest::ATTRIBUTE_LAYOUT_INTERLEAVED);
1833 createMultipleAttributeCases(2u, 0u, compatibleFormats, randomFunc, *oneToManyAttributeTests, VertexInputTest::BINDING_MAPPING_ONE_TO_MANY, VertexInputTest::ATTRIBUTE_LAYOUT_INTERLEAVED);
1834 createMultipleAttributeCases(2u, 0u, compatibleFormats, randomFunc, *oneToManySequentialAttributeTests, VertexInputTest::BINDING_MAPPING_ONE_TO_MANY, VertexInputTest::ATTRIBUTE_LAYOUT_SEQUENTIAL);
1836 de::MovePtr<tcu::TestCaseGroup> bindingOneToOneTests(new tcu::TestCaseGroup(testCtx, "binding_one_to_one", "Each attribute uses a unique binding"));
1837 bindingOneToOneTests->addChild(oneToOneAttributeTests.release());
1838 multipleAttributeTests->addChild(bindingOneToOneTests.release());
1840 de::MovePtr<tcu::TestCaseGroup> bindingOneToManyTests(new tcu::TestCaseGroup(testCtx, "binding_one_to_many", "Attributes share the same binding"));
1841 bindingOneToManyTests->addChild(oneToManyAttributeTests.release());
1842 bindingOneToManyTests->addChild(oneToManySequentialAttributeTests.release());
1843 multipleAttributeTests->addChild(bindingOneToManyTests.release());
1846 void createMaxAttributeTests (tcu::TestCaseGroup* maxAttributeTests)
1848 // Required vertex formats, unpacked
1849 const VkFormat vertexFormats[] =
1855 VK_FORMAT_R8G8_UNORM,
1856 VK_FORMAT_R8G8_SNORM,
1857 VK_FORMAT_R8G8_UINT,
1858 VK_FORMAT_R8G8_SINT,
1859 VK_FORMAT_R8G8B8A8_UNORM,
1860 VK_FORMAT_R8G8B8A8_SNORM,
1861 VK_FORMAT_R8G8B8A8_UINT,
1862 VK_FORMAT_R8G8B8A8_SINT,
1863 VK_FORMAT_B8G8R8A8_UNORM,
1864 VK_FORMAT_R16_UNORM,
1865 VK_FORMAT_R16_SNORM,
1868 VK_FORMAT_R16_SFLOAT,
1869 VK_FORMAT_R16G16_UNORM,
1870 VK_FORMAT_R16G16_SNORM,
1871 VK_FORMAT_R16G16_UINT,
1872 VK_FORMAT_R16G16_SINT,
1873 VK_FORMAT_R16G16_SFLOAT,
1874 VK_FORMAT_R16G16B16A16_UNORM,
1875 VK_FORMAT_R16G16B16A16_SNORM,
1876 VK_FORMAT_R16G16B16A16_UINT,
1877 VK_FORMAT_R16G16B16A16_SINT,
1878 VK_FORMAT_R16G16B16A16_SFLOAT,
1881 VK_FORMAT_R32_SFLOAT,
1882 VK_FORMAT_R32G32_UINT,
1883 VK_FORMAT_R32G32_SINT,
1884 VK_FORMAT_R32G32_SFLOAT,
1885 VK_FORMAT_R32G32B32_UINT,
1886 VK_FORMAT_R32G32B32_SINT,
1887 VK_FORMAT_R32G32B32_SFLOAT,
1888 VK_FORMAT_R32G32B32A32_UINT,
1889 VK_FORMAT_R32G32B32A32_SINT,
1890 VK_FORMAT_R32G32B32A32_SFLOAT
1893 // VkPhysicalDeviceLimits::maxVertexInputAttributes is used when attributeCount is 0
1894 const deUint32 attributeCount[] = { 16, 32, 64, 128, 0 };
1895 tcu::TestContext& testCtx (maxAttributeTests->getTestContext());
1896 de::Random randomFunc (132030);
1898 // Find compatible VK formats for each GLSL vertex type
1899 CompatibleFormats compatibleFormats[VertexInputTest::GLSL_TYPE_COUNT];
1901 for (int glslTypeNdx = 0; glslTypeNdx < VertexInputTest::GLSL_TYPE_COUNT; glslTypeNdx++)
1903 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(vertexFormats); formatNdx++)
1905 if (VertexInputTest::isCompatibleType(vertexFormats[formatNdx], (VertexInputTest::GlslType)glslTypeNdx))
1906 compatibleFormats[glslTypeNdx].compatibleVkFormats.push_back(vertexFormats[formatNdx]);
1911 for (deUint32 attributeCountNdx = 0; attributeCountNdx < DE_LENGTH_OF_ARRAY(attributeCount); attributeCountNdx++)
1913 const std::string groupName = (attributeCount[attributeCountNdx] == 0 ? "query_max" : de::toString(attributeCount[attributeCountNdx])) + "_attributes";
1914 const std::string groupDesc = de::toString(attributeCount[attributeCountNdx]) + " vertex input attributes";
1916 de::MovePtr<tcu::TestCaseGroup> numAttributeTests(new tcu::TestCaseGroup(testCtx, groupName.c_str(), groupDesc.c_str()));
1917 de::MovePtr<tcu::TestCaseGroup> bindingOneToOneTests(new tcu::TestCaseGroup(testCtx, "binding_one_to_one", "Each attribute uses a unique binding"));
1918 de::MovePtr<tcu::TestCaseGroup> bindingOneToManyTests(new tcu::TestCaseGroup(testCtx, "binding_one_to_many", "Attributes share the same binding"));
1920 std::vector<VertexInputTest::AttributeInfo> attributeInfos(attributeCount[attributeCountNdx]);
1922 for (deUint32 attributeNdx = 0; attributeNdx < attributeCount[attributeCountNdx]; attributeNdx++)
1924 // Use random glslTypes, each consuming one attribute location
1925 const VertexInputTest::GlslType glslType = (VertexInputTest::GlslType)(randomFunc.getUint32() % VertexInputTest::GLSL_TYPE_MAT2);
1926 const std::vector<VkFormat>& formats = compatibleFormats[glslType].compatibleVkFormats;
1927 const VkFormat format = formats[randomFunc.getUint32() % formats.size()];
1929 attributeInfos[attributeNdx].glslType = glslType;
1930 attributeInfos[attributeNdx].inputRate = ((attributeCountNdx + attributeNdx) % 2 == 0) ? VK_VERTEX_INPUT_RATE_VERTEX : VK_VERTEX_INPUT_RATE_INSTANCE;
1931 attributeInfos[attributeNdx].vkType = format;
1934 bindingOneToOneTests->addChild(new VertexInputTest(testCtx, "interleaved", "Interleaved attribute layout", attributeInfos, VertexInputTest::BINDING_MAPPING_ONE_TO_ONE, VertexInputTest::ATTRIBUTE_LAYOUT_INTERLEAVED));
1935 bindingOneToManyTests->addChild(new VertexInputTest(testCtx, "interleaved", "Interleaved attribute layout", attributeInfos, VertexInputTest::BINDING_MAPPING_ONE_TO_MANY, VertexInputTest::ATTRIBUTE_LAYOUT_INTERLEAVED));
1936 bindingOneToManyTests->addChild(new VertexInputTest(testCtx, "sequential", "Sequential attribute layout", attributeInfos, VertexInputTest::BINDING_MAPPING_ONE_TO_MANY, VertexInputTest::ATTRIBUTE_LAYOUT_SEQUENTIAL));
1938 numAttributeTests->addChild(bindingOneToOneTests.release());
1939 numAttributeTests->addChild(bindingOneToManyTests.release());
1940 maxAttributeTests->addChild(numAttributeTests.release());
1946 void createVertexInputTests (tcu::TestCaseGroup* vertexInputTests)
1948 addTestGroup(vertexInputTests, "single_attribute", "Uses one attribute", createSingleAttributeTests);
1949 addTestGroup(vertexInputTests, "multiple_attributes", "Uses more than one attribute", createMultipleAttributeTests);
1950 addTestGroup(vertexInputTests, "max_attributes", "Implementations can use as many vertex input attributes as they advertise", createMaxAttributeTests);