1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and/or associated documentation files (the
10 * "Materials"), to deal in the Materials without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sublicense, and/or sell copies of the Materials, and to
13 * permit persons to whom the Materials are furnished to do so, subject to
14 * the following conditions:
16 * The above copyright notice(s) and this permission notice shall be included
17 * in all copies or substantial portions of the Materials.
19 * The Materials are Confidential Information as defined by the
20 * Khronos Membership Agreement until designated non-confidential by Khronos,
21 * at which point this condition clause shall be removed.
23 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
27 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
33 * \brief Vulkan ShaderRenderCase
34 *//*--------------------------------------------------------------------*/
36 #include "vktShaderRender.hpp"
38 #include "tcuImageCompare.hpp"
39 #include "tcuImageIO.hpp"
40 #include "tcuTestLog.hpp"
41 #include "tcuTextureUtil.hpp"
42 #include "tcuSurface.hpp"
43 #include "tcuVector.hpp"
45 #include "deFilePath.hpp"
47 #include "deUniquePtr.hpp"
49 #include "vkDeviceUtil.hpp"
50 #include "vkImageUtil.hpp"
51 #include "vkPlatform.hpp"
52 #include "vkQueryUtil.hpp"
54 #include "vkRefUtil.hpp"
55 #include "vkStrUtil.hpp"
56 #include "vkTypeUtil.hpp"
71 static const int s_gridSize = 2;
72 static const int s_maxRenderWidth = 128;
73 static const int s_maxRenderHeight = 128;
74 static const tcu::Vec4 s_defaultClearColor = tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f);
76 static bool isSupportedLinearTilingFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format)
78 VkFormatProperties formatProps;
80 instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);
82 return (formatProps.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0u;
85 static bool isSupportedOptimalTilingFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format)
87 VkFormatProperties formatProps;
89 instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);
91 return (formatProps.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0u;
94 static VkImageMemoryBarrier createImageMemoryBarrier (const VkImage& image,
95 VkAccessFlags srcAccessMask,
96 VkAccessFlags dstAccessMask,
97 VkImageLayout oldLayout,
98 VkImageLayout newLayout)
100 VkImageMemoryBarrier imageMemoryBarrier =
102 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
103 DE_NULL, // const void* pNext;
104 srcAccessMask, // VkAccessFlags srcAccessMask;
105 dstAccessMask, // VkAccessFlags dstAccessMask;
106 oldLayout, // VkImageLayout oldLayout;
107 newLayout, // VkImageLayout newLayout;
108 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
109 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
110 image, // VkImage image;
112 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
113 0, // deUint32 baseMipLevel;
114 1, // deUint32 mipLevels;
115 0, // deUint32 baseArrayLayer;
116 1 // deUint32 arraySize;
117 } // VkImageSubresourceRange subresourceRange;
119 return imageMemoryBarrier;
129 QuadGrid (int gridSize,
132 const tcu::Vec4& constCoords,
133 const std::vector<tcu::Mat4>& userAttribTransforms,
134 const std::vector<TextureBindingSp>& textures);
137 int getGridSize (void) const { return m_gridSize; }
138 int getNumVertices (void) const { return m_numVertices; }
139 int getNumTriangles (void) const { return m_numTriangles; }
140 const tcu::Vec4& getConstCoords (void) const { return m_constCoords; }
141 const std::vector<tcu::Mat4> getUserAttribTransforms (void) const { return m_userAttribTransforms; }
142 const std::vector<TextureBindingSp>& getTextures (void) const { return m_textures; }
144 const tcu::Vec4* getPositions (void) const { return &m_positions[0]; }
145 const float* getAttribOne (void) const { return &m_attribOne[0]; }
146 const tcu::Vec4* getCoords (void) const { return &m_coords[0]; }
147 const tcu::Vec4* getUnitCoords (void) const { return &m_unitCoords[0]; }
149 const tcu::Vec4* getUserAttrib (int attribNdx) const { return &m_userAttribs[attribNdx][0]; }
150 const deUint16* getIndices (void) const { return &m_indices[0]; }
152 tcu::Vec4 getCoords (float sx, float sy) const;
153 tcu::Vec4 getUnitCoords (float sx, float sy) const;
155 int getNumUserAttribs (void) const { return (int)m_userAttribTransforms.size(); }
156 tcu::Vec4 getUserAttrib (int attribNdx, float sx, float sy) const;
159 const int m_gridSize;
160 const int m_numVertices;
161 const int m_numTriangles;
162 const tcu::Vec4 m_constCoords;
163 const std::vector<tcu::Mat4> m_userAttribTransforms;
165 const std::vector<TextureBindingSp>& m_textures;
167 std::vector<tcu::Vec4> m_screenPos;
168 std::vector<tcu::Vec4> m_positions;
169 std::vector<tcu::Vec4> m_coords; //!< Near-unit coordinates, roughly [-2.0 .. 2.0].
170 std::vector<tcu::Vec4> m_unitCoords; //!< Positive-only coordinates [0.0 .. 1.5].
171 std::vector<float> m_attribOne;
172 std::vector<tcu::Vec4> m_userAttribs[ShaderEvalContext::MAX_TEXTURES];
173 std::vector<deUint16> m_indices;
176 QuadGrid::QuadGrid (int gridSize,
179 const tcu::Vec4& constCoords,
180 const std::vector<tcu::Mat4>& userAttribTransforms,
181 const std::vector<TextureBindingSp>& textures)
182 : m_gridSize (gridSize)
183 , m_numVertices ((gridSize + 1) * (gridSize + 1))
184 , m_numTriangles (gridSize * gridSize * 2)
185 , m_constCoords (constCoords)
186 , m_userAttribTransforms (userAttribTransforms)
187 , m_textures (textures)
189 const tcu::Vec4 viewportScale ((float)width, (float)height, 0.0f, 0.0f);
192 m_screenPos.resize(m_numVertices);
193 m_positions.resize(m_numVertices);
194 m_coords.resize(m_numVertices);
195 m_unitCoords.resize(m_numVertices);
196 m_attribOne.resize(m_numVertices);
199 for (int attrNdx = 0; attrNdx < DE_LENGTH_OF_ARRAY(m_userAttribs); attrNdx++)
200 m_userAttribs[attrNdx].resize(m_numVertices);
202 for (int y = 0; y < gridSize+1; y++)
203 for (int x = 0; x < gridSize+1; x++)
205 float sx = (float)x / (float)gridSize;
206 float sy = (float)y / (float)gridSize;
207 float fx = 2.0f * sx - 1.0f;
208 float fy = 2.0f * sy - 1.0f;
209 int vtxNdx = ((y * (gridSize+1)) + x);
211 m_positions[vtxNdx] = tcu::Vec4(fx, fy, 0.0f, 1.0f);
212 m_coords[vtxNdx] = getCoords(sx, sy);
213 m_unitCoords[vtxNdx] = getUnitCoords(sx, sy);
214 m_attribOne[vtxNdx] = 1.0f;
216 m_screenPos[vtxNdx] = tcu::Vec4(sx, sy, 0.0f, 1.0f) * viewportScale;
218 for (int attribNdx = 0; attribNdx < getNumUserAttribs(); attribNdx++)
219 m_userAttribs[attribNdx][vtxNdx] = getUserAttrib(attribNdx, sx, sy);
223 m_indices.resize(3 * m_numTriangles);
224 for (int y = 0; y < gridSize; y++)
225 for (int x = 0; x < gridSize; x++)
227 int stride = gridSize + 1;
228 int v00 = (y * stride) + x;
229 int v01 = (y * stride) + x + 1;
230 int v10 = ((y+1) * stride) + x;
231 int v11 = ((y+1) * stride) + x + 1;
233 int baseNdx = ((y * gridSize) + x) * 6;
234 m_indices[baseNdx + 0] = (deUint16)v10;
235 m_indices[baseNdx + 1] = (deUint16)v00;
236 m_indices[baseNdx + 2] = (deUint16)v01;
238 m_indices[baseNdx + 3] = (deUint16)v10;
239 m_indices[baseNdx + 4] = (deUint16)v01;
240 m_indices[baseNdx + 5] = (deUint16)v11;
244 QuadGrid::~QuadGrid (void)
248 inline tcu::Vec4 QuadGrid::getCoords (float sx, float sy) const
250 const float fx = 2.0f * sx - 1.0f;
251 const float fy = 2.0f * sy - 1.0f;
252 return tcu::Vec4(fx, fy, -fx + 0.33f*fy, -0.275f*fx - fy);
255 inline tcu::Vec4 QuadGrid::getUnitCoords (float sx, float sy) const
257 return tcu::Vec4(sx, sy, 0.33f*sx + 0.5f*sy, 0.5f*sx + 0.25f*sy);
260 inline tcu::Vec4 QuadGrid::getUserAttrib (int attribNdx, float sx, float sy) const
262 // homogeneous normalized screen-space coordinates
263 return m_userAttribTransforms[attribNdx] * tcu::Vec4(sx, sy, 0.0f, 1.0f);
268 TextureBinding::TextureBinding (const tcu::Archive& archive,
269 const char* filename,
271 const tcu::Sampler& sampler)
273 , m_sampler (sampler)
277 case TYPE_2D: m_binding.tex2D = loadTexture2D(archive, filename).release(); break;
279 DE_FATAL("Unsupported texture type");
283 TextureBinding::~TextureBinding (void)
287 case TYPE_2D: delete m_binding.tex2D; break;
293 de::MovePtr<tcu::Texture2D> TextureBinding::loadTexture2D (const tcu::Archive& archive, const char* filename)
295 tcu::TextureLevel level;
296 tcu::ImageIO::loadImage(level, archive, filename);
298 TCU_CHECK_INTERNAL(level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) ||
299 level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8));
301 // \todo [2015-10-08 elecro] for some reason we get better when using RGBA texture even in RGB case, this needs to be investigated
302 de::MovePtr<tcu::Texture2D> texture(new tcu::Texture2D(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), level.getWidth(), level.getHeight()));
305 texture->allocLevel(0);
306 tcu::copy(texture->getLevel(0), level.getAccess());
311 // ShaderEvalContext.
313 ShaderEvalContext::ShaderEvalContext (const QuadGrid& quadGrid)
314 : constCoords (quadGrid.getConstCoords())
315 , isDiscarded (false)
316 , m_quadGrid (quadGrid)
318 const std::vector<TextureBindingSp>& bindings = m_quadGrid.getTextures();
319 DE_ASSERT((int)bindings.size() <= MAX_TEXTURES);
321 // Fill in texture array.
322 for (int ndx = 0; ndx < (int)bindings.size(); ndx++)
324 const TextureBinding& binding = *bindings[ndx];
326 if (binding.getType() == TextureBinding::TYPE_NONE)
329 textures[ndx].sampler = binding.getSampler();
331 switch (binding.getType())
333 case TextureBinding::TYPE_2D: textures[ndx].tex2D = &binding.get2D(); break;
334 // \todo [2015-09-07 elecro] Add support for the other binding types
336 case TextureBinding::TYPE_CUBE_MAP: textures[ndx].texCube = binding.getCube(); break;
337 case TextureBinding::TYPE_2D_ARRAY: textures[ndx].tex2DArray = binding.get2DArray(); break;
338 case TextureBinding::TYPE_3D: textures[ndx].tex3D = binding.get3D(); break;
341 TCU_THROW(InternalError, "Handling of texture binding type not implemented");
346 ShaderEvalContext::~ShaderEvalContext (void)
350 void ShaderEvalContext::reset (float sx, float sy)
353 color = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
357 coords = m_quadGrid.getCoords(sx, sy);
358 unitCoords = m_quadGrid.getUnitCoords(sx, sy);
360 // Compute user attributes.
361 const int numAttribs = m_quadGrid.getNumUserAttribs();
362 DE_ASSERT(numAttribs <= MAX_USER_ATTRIBS);
363 for (int attribNdx = 0; attribNdx < numAttribs; attribNdx++)
364 in[attribNdx] = m_quadGrid.getUserAttrib(attribNdx, sx, sy);
367 tcu::Vec4 ShaderEvalContext::texture2D (int unitNdx, const tcu::Vec2& texCoords)
369 if (textures[unitNdx].tex2D)
370 return textures[unitNdx].tex2D->sample(textures[unitNdx].sampler, texCoords.x(), texCoords.y(), 0.0f);
372 return tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
377 ShaderEvaluator::ShaderEvaluator (void)
378 : m_evalFunc(DE_NULL)
382 ShaderEvaluator::ShaderEvaluator (ShaderEvalFunc evalFunc)
383 : m_evalFunc(evalFunc)
387 ShaderEvaluator::~ShaderEvaluator (void)
391 void ShaderEvaluator::evaluate (ShaderEvalContext& ctx) const
393 DE_ASSERT(m_evalFunc);
399 UniformSetup::UniformSetup (void)
400 : m_setupFunc(DE_NULL)
404 UniformSetup::UniformSetup (UniformSetupFunc setupFunc)
405 : m_setupFunc(setupFunc)
409 UniformSetup::~UniformSetup (void)
413 void UniformSetup::setup (ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords) const
416 m_setupFunc(instance, constCoords);
421 ShaderRenderCase::ShaderRenderCase (tcu::TestContext& testCtx,
422 const std::string& name,
423 const std::string& description,
424 const bool isVertexCase,
425 const ShaderEvalFunc evalFunc,
426 const UniformSetup* uniformSetup,
427 const AttributeSetupFunc attribFunc)
428 : vkt::TestCase (testCtx, name, description)
429 , m_isVertexCase (isVertexCase)
430 , m_evaluator (new ShaderEvaluator(evalFunc))
431 , m_uniformSetup (uniformSetup ? uniformSetup : new UniformSetup())
432 , m_attribFunc (attribFunc)
435 ShaderRenderCase::ShaderRenderCase (tcu::TestContext& testCtx,
436 const std::string& name,
437 const std::string& description,
438 const bool isVertexCase,
439 const ShaderEvaluator* evaluator,
440 const UniformSetup* uniformSetup,
441 const AttributeSetupFunc attribFunc)
442 : vkt::TestCase (testCtx, name, description)
443 , m_isVertexCase (isVertexCase)
444 , m_evaluator (evaluator)
445 , m_uniformSetup (uniformSetup ? uniformSetup : new UniformSetup())
446 , m_attribFunc (attribFunc)
449 ShaderRenderCase::~ShaderRenderCase (void)
453 void ShaderRenderCase::initPrograms (vk::SourceCollections& programCollection) const
455 programCollection.glslSources.add("vert") << glu::VertexSource(m_vertShaderSource);
456 programCollection.glslSources.add("frag") << glu::FragmentSource(m_fragShaderSource);
459 TestInstance* ShaderRenderCase::createInstance (Context& context) const
461 DE_ASSERT(m_evaluator != DE_NULL);
462 DE_ASSERT(m_uniformSetup != DE_NULL);
463 return new ShaderRenderCaseInstance(context, m_isVertexCase, *m_evaluator, *m_uniformSetup, m_attribFunc);
466 // ShaderRenderCaseInstance.
468 ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context& context,
469 const bool isVertexCase,
470 const ShaderEvaluator& evaluator,
471 const UniformSetup& uniformSetup,
472 const AttributeSetupFunc attribFunc)
473 : vkt::TestInstance (context)
474 , m_clearColor (s_defaultClearColor)
475 , m_memAlloc (context.getDefaultAllocator())
476 , m_isVertexCase (isVertexCase)
477 , m_evaluator (evaluator)
478 , m_uniformSetup (uniformSetup)
479 , m_attribFunc (attribFunc)
480 , m_renderSize (128, 128)
481 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
485 ShaderRenderCaseInstance::~ShaderRenderCaseInstance (void)
489 tcu::TestStatus ShaderRenderCaseInstance::iterate (void)
494 const tcu::IVec2 viewportSize = getViewportSize();
495 const int width = viewportSize.x();
496 const int height = viewportSize.y();
498 QuadGrid quadGrid (m_isVertexCase ? s_gridSize : 4, width, height, tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f), m_userAttribTransforms, m_textures);
501 tcu::Surface resImage (width, height);
502 render(resImage, quadGrid);
504 // Compute reference.
505 tcu::Surface refImage (width, height);
507 computeVertexReference(refImage, quadGrid);
509 computeFragmentReference(refImage, quadGrid);
512 const bool compareOk = compareImages(resImage, refImage, 0.05f);
515 return tcu::TestStatus::pass("Result image matches reference");
517 return tcu::TestStatus::fail("Image mismatch");
520 void ShaderRenderCaseInstance::setupUniformData (deUint32 bindingLocation, size_t size, const void* dataPtr)
522 const VkDevice vkDevice = m_context.getDevice();
523 const DeviceInterface& vk = m_context.getDeviceInterface();
524 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
526 const VkBufferCreateInfo uniformBufferParams =
528 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
529 DE_NULL, // const void* pNext;
530 0u, // VkBufferCreateFlags flags;
531 size, // VkDeviceSize size;
532 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, // VkBufferUsageFlags usage;
533 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
534 1u, // deUint32 queueFamilyCount;
535 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
538 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &uniformBufferParams);
539 de::MovePtr<Allocation> alloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
540 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
542 deMemcpy(alloc->getHostPtr(), dataPtr, size);
543 flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), size);
545 de::MovePtr<BufferUniform> uniformInfo(new BufferUniform());
546 uniformInfo->type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
547 uniformInfo->descriptor = makeDescriptorBufferInfo(*buffer, 0u, size);
548 uniformInfo->location = bindingLocation;
549 uniformInfo->buffer = VkBufferSp(new vk::Unique<VkBuffer>(buffer));
550 uniformInfo->alloc = AllocationSp(alloc.release());
552 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniformInfo)));
555 void ShaderRenderCaseInstance::addUniform (deUint32 bindingLocation, vk::VkDescriptorType descriptorType, size_t dataSize, const void* data)
557 m_descriptorSetLayoutBuilder.addSingleBinding(descriptorType, vk::VK_SHADER_STAGE_ALL);
558 m_descriptorPoolBuilder.addType(descriptorType);
560 setupUniformData(bindingLocation, dataSize, data);
563 void ShaderRenderCaseInstance::addAttribute (deUint32 bindingLocation,
565 deUint32 sizePerElement,
569 // Add binding specification
570 const deUint32 binding = (deUint32)m_vertexBindingDescription.size();
571 const VkVertexInputBindingDescription bindingDescription =
573 binding, // deUint32 binding;
574 sizePerElement, // deUint32 stride;
575 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate stepRate;
578 m_vertexBindingDescription.push_back(bindingDescription);
580 // Add location and format specification
581 const VkVertexInputAttributeDescription attributeDescription =
583 bindingLocation, // deUint32 location;
584 binding, // deUint32 binding;
585 format, // VkFormat format;
586 0u, // deUint32 offset;
589 m_vertexattributeDescription.push_back(attributeDescription);
591 // Upload data to buffer
592 const VkDevice vkDevice = m_context.getDevice();
593 const DeviceInterface& vk = m_context.getDeviceInterface();
594 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
596 const VkDeviceSize inputSize = sizePerElement * count;
597 const VkBufferCreateInfo vertexBufferParams =
599 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
600 DE_NULL, // const void* pNext;
601 0u, // VkBufferCreateFlags flags;
602 inputSize, // VkDeviceSize size;
603 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
604 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
605 1u, // deUint32 queueFamilyCount;
606 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
609 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &vertexBufferParams);
610 de::MovePtr<vk::Allocation> alloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
611 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
613 deMemcpy(alloc->getHostPtr(), dataPtr, (size_t)inputSize);
614 flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), inputSize);
616 m_vertexBuffers.push_back(VkBufferSp(new vk::Unique<VkBuffer>(buffer)));
617 m_vertexBufferAllocs.push_back(AllocationSp(alloc.release()));
620 void ShaderRenderCaseInstance::useAttribute (deUint32 bindingLocation, BaseAttributeType type)
622 const EnabledBaseAttribute attribute =
624 bindingLocation, // deUint32 location;
625 type // BaseAttributeType type;
627 m_enabledBaseAttributes.push_back(attribute);
630 void ShaderRenderCaseInstance::setup (void)
634 void ShaderRenderCaseInstance::setupUniforms (const tcu::Vec4& constCoords)
636 m_uniformSetup.setup(*this, constCoords);
639 void ShaderRenderCaseInstance::useUniform (deUint32 bindingLocation, BaseUniformType type)
641 #define UNIFORM_CASE(type, value) case type: addUniform(bindingLocation, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, value); break
646 UNIFORM_CASE(UB_FALSE, 0);
647 UNIFORM_CASE(UB_TRUE, 1);
650 UNIFORM_CASE(UB4_FALSE, tcu::Vec4(0));
651 UNIFORM_CASE(UB4_TRUE, tcu::Vec4(1));
654 UNIFORM_CASE(UI_ZERO, 0);
655 UNIFORM_CASE(UI_ONE, 1);
656 UNIFORM_CASE(UI_TWO, 2);
657 UNIFORM_CASE(UI_THREE, 3);
658 UNIFORM_CASE(UI_FOUR, 4);
659 UNIFORM_CASE(UI_FIVE, 5);
660 UNIFORM_CASE(UI_SIX, 6);
661 UNIFORM_CASE(UI_SEVEN, 7);
662 UNIFORM_CASE(UI_EIGHT, 8);
663 UNIFORM_CASE(UI_ONEHUNDREDONE, 101);
666 UNIFORM_CASE(UI2_MINUS_ONE, tcu::IVec2(-1));
667 UNIFORM_CASE(UI2_ZERO, tcu::IVec2(0));
668 UNIFORM_CASE(UI2_ONE, tcu::IVec2(1));
669 UNIFORM_CASE(UI2_TWO, tcu::IVec2(2));
670 UNIFORM_CASE(UI2_THREE, tcu::IVec2(3));
671 UNIFORM_CASE(UI2_FOUR, tcu::IVec2(4));
672 UNIFORM_CASE(UI2_FIVE, tcu::IVec2(5));
675 UNIFORM_CASE(UI3_MINUS_ONE, tcu::IVec3(-1));
676 UNIFORM_CASE(UI3_ZERO, tcu::IVec3(0));
677 UNIFORM_CASE(UI3_ONE, tcu::IVec3(1));
678 UNIFORM_CASE(UI3_TWO, tcu::IVec3(2));
679 UNIFORM_CASE(UI3_THREE, tcu::IVec3(3));
680 UNIFORM_CASE(UI3_FOUR, tcu::IVec3(4));
681 UNIFORM_CASE(UI3_FIVE, tcu::IVec3(5));
684 UNIFORM_CASE(UI4_MINUS_ONE, tcu::IVec4(-1));
685 UNIFORM_CASE(UI4_ZERO, tcu::IVec4(0));
686 UNIFORM_CASE(UI4_ONE, tcu::IVec4(1));
687 UNIFORM_CASE(UI4_TWO, tcu::IVec4(2));
688 UNIFORM_CASE(UI4_THREE, tcu::IVec4(3));
689 UNIFORM_CASE(UI4_FOUR, tcu::IVec4(4));
690 UNIFORM_CASE(UI4_FIVE, tcu::IVec4(5));
693 UNIFORM_CASE(UF_ZERO, 0.0f);
694 UNIFORM_CASE(UF_ONE, 1.0f);
695 UNIFORM_CASE(UF_TWO, 2.0f);
696 UNIFORM_CASE(UF_THREE, 3.0f);
697 UNIFORM_CASE(UF_FOUR, 4.0f);
698 UNIFORM_CASE(UF_FIVE, 5.0f);
699 UNIFORM_CASE(UF_SIX, 6.0f);
700 UNIFORM_CASE(UF_SEVEN, 7.0f);
701 UNIFORM_CASE(UF_EIGHT, 8.0f);
703 UNIFORM_CASE(UF_HALF, 1.0f / 2.0f);
704 UNIFORM_CASE(UF_THIRD, 1.0f / 3.0f);
705 UNIFORM_CASE(UF_FOURTH, 1.0f / 4.0f);
706 UNIFORM_CASE(UF_FIFTH, 1.0f / 5.0f);
707 UNIFORM_CASE(UF_SIXTH, 1.0f / 6.0f);
708 UNIFORM_CASE(UF_SEVENTH, 1.0f / 7.0f);
709 UNIFORM_CASE(UF_EIGHTH, 1.0f / 8.0f);
712 UNIFORM_CASE(UV2_MINUS_ONE, tcu::Vec2(-1.0f));
713 UNIFORM_CASE(UV2_ZERO, tcu::Vec2(0.0f));
714 UNIFORM_CASE(UV2_ONE, tcu::Vec2(1.0f));
715 UNIFORM_CASE(UV2_TWO, tcu::Vec2(2.0f));
716 UNIFORM_CASE(UV2_THREE, tcu::Vec2(3.0f));
718 UNIFORM_CASE(UV2_HALF, tcu::Vec2(1.0f / 2.0f));
721 UNIFORM_CASE(UV3_MINUS_ONE, tcu::Vec3(-1.0f));
722 UNIFORM_CASE(UV3_ZERO, tcu::Vec3(0.0f));
723 UNIFORM_CASE(UV3_ONE, tcu::Vec3(1.0f));
724 UNIFORM_CASE(UV3_TWO, tcu::Vec3(2.0f));
725 UNIFORM_CASE(UV3_THREE, tcu::Vec3(3.0f));
727 UNIFORM_CASE(UV3_HALF, tcu::Vec3(1.0f / 2.0f));
730 UNIFORM_CASE(UV4_MINUS_ONE, tcu::Vec4(-1.0f));
731 UNIFORM_CASE(UV4_ZERO, tcu::Vec4(0.0f));
732 UNIFORM_CASE(UV4_ONE, tcu::Vec4(1.0f));
733 UNIFORM_CASE(UV4_TWO, tcu::Vec4(2.0f));
734 UNIFORM_CASE(UV4_THREE, tcu::Vec4(3.0f));
736 UNIFORM_CASE(UV4_HALF, tcu::Vec4(1.0f / 2.0f));
738 UNIFORM_CASE(UV4_BLACK, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
739 UNIFORM_CASE(UV4_GRAY, tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f));
740 UNIFORM_CASE(UV4_WHITE, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
743 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Unknown Uniform type: " << type << tcu::TestLog::EndMessage;
750 const tcu::IVec2 ShaderRenderCaseInstance::getViewportSize (void) const
752 return tcu::IVec2(de::min(m_renderSize.x(), s_maxRenderWidth),
753 de::min(m_renderSize.y(), s_maxRenderHeight));
756 Move<VkImage> ShaderRenderCaseInstance::createImage2D (const tcu::Texture2D& texture,
757 const VkFormat format,
758 const VkImageUsageFlags usage,
759 const VkImageTiling tiling)
761 const VkDevice vkDevice = m_context.getDevice();
762 const DeviceInterface& vk = m_context.getDeviceInterface();
763 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
765 const VkImageCreateInfo imageCreateInfo =
767 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
768 DE_NULL, // const void* pNext;
769 0, // VkImageCreateFlags flags;
770 VK_IMAGE_TYPE_2D, // VkImageType imageType;
771 format, // VkFormat format;
772 { texture.getWidth(), texture.getHeight(), 1 }, // VkExtend3D extent;
773 1u, // deUint32 mipLevels;
774 1u, // deUint32 arraySize;
775 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
776 tiling, // VkImageTiling tiling;
777 usage, // VkImageUsageFlags usage;
778 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
779 1, // deuint32 queueFamilyCount;
780 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
781 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
784 Move<VkImage> vkTexture = createImage(vk, vkDevice, &imageCreateInfo);
788 de::MovePtr<Allocation> ShaderRenderCaseInstance::uploadImage2D (const tcu::Texture2D& refTexture,
789 const VkImage& vkTexture)
791 const VkDevice vkDevice = m_context.getDevice();
792 const DeviceInterface& vk = m_context.getDeviceInterface();
794 de::MovePtr<Allocation> allocation = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, vkTexture), MemoryRequirement::HostVisible);
795 VK_CHECK(vk.bindImageMemory(vkDevice, vkTexture, allocation->getMemory(), allocation->getOffset()));
797 const VkImageSubresource subres =
799 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
800 0u, // deUint32 mipLevel;
801 0u // deUint32 arraySlice
804 VkSubresourceLayout layout;
805 vk.getImageSubresourceLayout(vkDevice, vkTexture, &subres, &layout);
807 tcu::ConstPixelBufferAccess access = refTexture.getLevel(0);
808 tcu::PixelBufferAccess destAccess (refTexture.getFormat(), refTexture.getWidth(), refTexture.getHeight(), 1, allocation->getHostPtr());
810 tcu::copy(destAccess, access);
812 flushMappedMemoryRange(vk, vkDevice, allocation->getMemory(), allocation, layout.size);
817 void ShaderRenderCaseInstance::copyTilingImageToOptimal (const vk::VkImage& srcImage,
818 const vk::VkImage& dstImage,
822 const VkDevice vkDevice = m_context.getDevice();
823 const DeviceInterface& vk = m_context.getDeviceInterface();
824 const VkQueue queue = m_context.getUniversalQueue();
825 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
827 // Create command pool
828 const VkCommandPoolCreateInfo cmdPoolParams =
830 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
831 DE_NULL, // const void* pNext;
832 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
833 queueFamilyIndex, // deUint32 queueFamilyIndex;
836 Move<VkCommandPool> cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
838 // Create command buffer
839 const VkCommandBufferAllocateInfo cmdBufferParams =
841 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
842 DE_NULL, // const void* pNext;
843 *cmdPool, // VkCommandPool commandPool;
844 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
845 1u // deUint32 bufferCount;
848 const VkCommandBufferUsageFlags usageFlags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
849 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
851 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
852 DE_NULL, // const void* pNext;
853 usageFlags, // VkCommandBufferUsageFlags flags;
854 DE_NULL, // VkRenderPass renderPass;
855 0u, // deUint32 subpass;
856 DE_NULL, // VkFramebuffer framebuffer;
857 VK_FALSE, // VkBool32 occlusionQueryEnable;
858 (VkQueryControlFlags)0,
859 (VkQueryPipelineStatisticFlags)0,
862 Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
864 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
866 // Add image barriers
867 const VkImageMemoryBarrier layoutBarriers[2] =
869 createImageMemoryBarrier(srcImage, (VkAccessFlags)0u, (VkAccessFlags)0u, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL),
870 createImageMemoryBarrier(dstImage, (VkAccessFlags)0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
873 for (deUint32 barrierNdx = 0; barrierNdx < DE_LENGTH_OF_ARRAY(layoutBarriers); barrierNdx++)
875 const VkImageMemoryBarrier* memoryBarrier = &layoutBarriers[barrierNdx];
876 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, (const void * const*)&memoryBarrier);
880 const VkImageCopy imageCopy =
883 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect;
884 0u, // deUint32 mipLevel;
885 0u, // deUint32 arrayLayer;
886 1u // deUint32 arraySize;
887 }, // VkImageSubresourceCopy srcSubresource;
892 }, // VkOffset3D srcOffset;
894 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect;
895 0u, // deUint32 mipLevel;
896 0u, // deUint32 arrayLayer;
897 1u // deUint32 arraySize;
898 }, // VkImageSubresourceCopy destSubResource;
903 }, // VkOffset3D dstOffset;
905 width, // int32 width;
906 height, // int32 height;
908 } // VkExtent3D extent;
911 vk.cmdCopyImage(*cmdBuffer, srcImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &imageCopy);
913 // Add destination barrier
914 const VkImageMemoryBarrier dstBarrier =
915 createImageMemoryBarrier(dstImage, VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT, 0u, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
917 const void* const* barrier = (const void* const*)&dstBarrier;
918 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, (const void* const*)&barrier);
920 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
922 const VkFenceCreateInfo fenceParams =
924 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
925 DE_NULL, // const void* pNext;
926 0u // VkFenceCreateFlags flags;
928 const Unique<VkFence> fence (createFence(vk, vkDevice, &fenceParams));
929 const VkSubmitInfo submitInfo =
931 VK_STRUCTURE_TYPE_SUBMIT_INFO,
934 (const VkSemaphore*)DE_NULL,
938 (const VkSemaphore*)DE_NULL,
943 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
944 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
945 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/));
948 void ShaderRenderCaseInstance::useSampler2D (deUint32 bindingLocation, deUint32 textureID)
950 DE_ASSERT(textureID < m_textures.size());
952 const VkDevice vkDevice = m_context.getDevice();
953 const DeviceInterface& vk = m_context.getDeviceInterface();
954 const TextureBinding& textureBinding = *m_textures[textureID];
955 const tcu::Texture2D& refTexture = textureBinding.get2D();
956 const tcu::Sampler& refSampler = textureBinding.getSampler();
957 const VkFormat format = refTexture.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
958 ? VK_FORMAT_R8G8B8A8_UNORM
959 : VK_FORMAT_R8G8B8_UNORM;
961 // Create & alloc the image
962 Move<VkImage> vkTexture;
963 de::MovePtr<Allocation> allocation;
965 if (isSupportedLinearTilingFormat(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), format))
967 vkTexture = createImage2D(refTexture, format, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_LINEAR);
968 allocation = uploadImage2D(refTexture, *vkTexture);
970 else if (isSupportedOptimalTilingFormat(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), format))
972 Move<VkImage> stagingTexture (createImage2D(refTexture, format, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_LINEAR));
973 de::MovePtr<Allocation> stagingAlloc (uploadImage2D(refTexture, *stagingTexture));
975 const VkImageUsageFlags dstUsageFlags = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
976 vkTexture = createImage2D(refTexture, format, dstUsageFlags, VK_IMAGE_TILING_OPTIMAL);
977 allocation = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *vkTexture), MemoryRequirement::Any);
978 VK_CHECK(vk.bindImageMemory(vkDevice, *vkTexture, allocation->getMemory(), allocation->getOffset()));
980 copyTilingImageToOptimal(*stagingTexture, *vkTexture, refTexture.getWidth(), refTexture.getHeight());
984 TCU_THROW(InternalError, "Unable to create 2D image");
988 const bool compareEnabled = (refSampler.compare != tcu::Sampler::COMPAREMODE_NONE);
989 const VkSamplerCreateInfo samplerParams =
991 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
992 DE_NULL, // const void* pNext;
993 (VkSamplerCreateFlags)0,
994 mapFilterMode(refSampler.magFilter), // VkTexFilter magFilter;
995 mapFilterMode(refSampler.minFilter), // VkTexFilter minFilter;
996 mapMipmapMode(refSampler.minFilter), // VkTexMipmapMode mipMode;
997 mapWrapMode(refSampler.wrapS), // VkTexAddressMode addressModeU;
998 mapWrapMode(refSampler.wrapT), // VkTexAddressMode addressModeV;
999 mapWrapMode(refSampler.wrapR), // VkTexAddressMode addressModeW;
1000 refSampler.lodThreshold, // float mipLodBias;
1001 1, // float maxAnisotropy;
1002 compareEnabled, // VkBool32 compareEnable;
1003 mapCompareMode(refSampler.compare), // VkCompareOp compareOp;
1004 0.0f, // float minLod;
1005 0.0f, // float maxLod;
1006 VK_BORDER_COLOR_INT_OPAQUE_WHITE, // VkBorderColor boderColor;
1007 VK_FALSE, // VkBool32 unnormalizerdCoordinates;
1010 Move<VkSampler> sampler = createSampler(vk, vkDevice, &samplerParams);
1012 const VkImageViewCreateInfo viewParams =
1014 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1015 NULL, // const voide* pNext;
1016 0u, // VkImageViewCreateFlags flags;
1017 *vkTexture, // VkImage image;
1018 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
1019 format, // VkFormat format;
1021 VK_COMPONENT_SWIZZLE_R, // VkChannelSwizzle r;
1022 VK_COMPONENT_SWIZZLE_G, // VkChannelSwizzle g;
1023 VK_COMPONENT_SWIZZLE_B, // VkChannelSwizzle b;
1024 VK_COMPONENT_SWIZZLE_A // VkChannelSwizzle a;
1025 }, // VkChannelMapping channels;
1027 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1028 0, // deUint32 baseMipLevel;
1029 1, // deUint32 mipLevels;
1030 0, // deUint32 baseArraySlice;
1031 1 // deUint32 arraySize;
1032 }, // VkImageSubresourceRange subresourceRange;
1035 Move<VkImageView> imageView = createImageView(vk, vkDevice, &viewParams);
1037 const vk::VkDescriptorImageInfo descriptor =
1039 sampler.get(), // VkSampler sampler;
1040 imageView.get(), // VkImageView imageView;
1041 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
1044 de::MovePtr<SamplerUniform> uniform(new SamplerUniform());
1045 uniform->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
1046 uniform->descriptor = descriptor;
1047 uniform->location = bindingLocation;
1048 uniform->image = VkImageSp(new vk::Unique<VkImage>(vkTexture));
1049 uniform->imageView = VkImageViewSp(new vk::Unique<VkImageView>(imageView));
1050 uniform->sampler = VkSamplerSp(new vk::Unique<VkSampler>(sampler));
1051 uniform->alloc = AllocationSp(allocation.release());
1053 m_descriptorSetLayoutBuilder.addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, vk::VK_SHADER_STAGE_ALL, &uniform->descriptor.sampler);
1054 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
1056 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniform)));
1059 void ShaderRenderCaseInstance::setupDefaultInputs (const QuadGrid& quadGrid)
1061 /* Configuration of the vertex input attributes:
1062 a_position is at location 0
1063 a_coords is at location 1
1064 a_unitCoords is at location 2
1065 a_one is at location 3
1067 User attributes starts from at the location 4.
1069 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getPositions());
1070 addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getCoords());
1071 addAttribute(2u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUnitCoords());
1072 addAttribute(3u, VK_FORMAT_R32_SFLOAT, sizeof(float), quadGrid.getNumVertices(), quadGrid.getAttribOne());
1076 BaseAttributeType type;
1078 } userAttributes[] =
1088 BaseAttributeType matrixType;
1104 for (size_t attrNdx = 0; attrNdx < m_enabledBaseAttributes.size(); attrNdx++)
1106 for (int userNdx = 0; userNdx < DE_LENGTH_OF_ARRAY(userAttributes); userNdx++)
1108 if (userAttributes[userNdx].type != m_enabledBaseAttributes[attrNdx].type)
1111 addAttribute(m_enabledBaseAttributes[attrNdx].location, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUserAttrib(userNdx));
1114 for (int matNdx = 0; matNdx < DE_LENGTH_OF_ARRAY(matrices); matNdx++)
1117 if (matrices[matNdx].matrixType != m_enabledBaseAttributes[attrNdx].type)
1120 const int numCols = matrices[matNdx].numCols;
1122 for (int colNdx = 0; colNdx < numCols; colNdx++)
1124 addAttribute(m_enabledBaseAttributes[attrNdx].location + colNdx, VK_FORMAT_R32G32B32A32_SFLOAT, (deUint32)(4 * sizeof(float)), quadGrid.getNumVertices(), quadGrid.getUserAttrib(colNdx));
1130 void ShaderRenderCaseInstance::render (tcu::Surface& result, const QuadGrid& quadGrid)
1132 const VkDevice vkDevice = m_context.getDevice();
1133 const DeviceInterface& vk = m_context.getDeviceInterface();
1134 const VkQueue queue = m_context.getUniversalQueue();
1135 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1137 // Create color image
1139 const VkImageCreateInfo colorImageParams =
1141 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1142 DE_NULL, // const void* pNext;
1143 0u, // VkImageCreateFlags flags;
1144 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1145 m_colorFormat, // VkFormat format;
1146 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent;
1147 1u, // deUint32 mipLevels;
1148 1u, // deUint32 arraySize;
1149 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
1150 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1151 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
1152 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1153 1u, // deUint32 queueFamilyCount;
1154 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1155 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1158 m_colorImage = createImage(vk, vkDevice, &colorImageParams);
1160 // Allocate and bind color image memory
1161 m_colorImageAlloc = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
1162 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
1165 // Create color attachment view
1167 const VkImageViewCreateInfo colorImageViewParams =
1169 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1170 DE_NULL, // const void* pNext;
1171 0u, // VkImageViewCreateFlags flags;
1172 *m_colorImage, // VkImage image;
1173 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
1174 m_colorFormat, // VkFormat format;
1176 VK_COMPONENT_SWIZZLE_R, // VkChannelSwizzle r;
1177 VK_COMPONENT_SWIZZLE_G, // VkChannelSwizzle g;
1178 VK_COMPONENT_SWIZZLE_B, // VkChannelSwizzle b;
1179 VK_COMPONENT_SWIZZLE_A // VkChannelSwizzle a;
1180 }, // VkChannelMapping channels;
1182 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1183 0, // deUint32 baseMipLevel;
1184 1, // deUint32 mipLevels;
1185 0, // deUint32 baseArraySlice;
1186 1 // deUint32 arraySize;
1187 }, // VkImageSubresourceRange subresourceRange;
1190 m_colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
1193 // Create render pass
1195 const VkAttachmentDescription attachmentDescription =
1197 (VkAttachmentDescriptionFlags)0,
1198 m_colorFormat, // VkFormat format;
1199 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
1200 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
1201 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
1202 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
1203 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
1204 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
1205 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
1208 const VkAttachmentReference attachmentReference =
1210 0u, // deUint32 attachment;
1211 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
1214 const VkSubpassDescription subpassDescription =
1216 0u, // VkSubpassDescriptionFlags flags;
1217 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
1218 0u, // deUint32 inputCount;
1219 DE_NULL, // constVkAttachmentReference* pInputAttachments;
1220 1u, // deUint32 colorCount;
1221 &attachmentReference, // constVkAttachmentReference* pColorAttachments;
1222 DE_NULL, // constVkAttachmentReference* pResolveAttachments;
1223 DE_NULL, // VkAttachmentReference depthStencilAttachment;
1224 0u, // deUint32 preserveCount;
1225 DE_NULL // constVkAttachmentReference* pPreserveAttachments;
1228 const VkRenderPassCreateInfo renderPassParams =
1230 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
1231 DE_NULL, // const void* pNext;
1232 (VkRenderPassCreateFlags)0,
1233 1u, // deUint32 attachmentCount;
1234 &attachmentDescription, // const VkAttachmentDescription* pAttachments;
1235 1u, // deUint32 subpassCount;
1236 &subpassDescription, // const VkSubpassDescription* pSubpasses;
1237 0u, // deUint32 dependencyCount;
1238 DE_NULL // const VkSubpassDependency* pDependencies;
1241 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
1244 // Create framebuffer
1246 const VkFramebufferCreateInfo framebufferParams =
1248 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
1249 DE_NULL, // const void* pNext;
1250 (VkFramebufferCreateFlags)0,
1251 *m_renderPass, // VkRenderPass renderPass;
1252 1u, // deUint32 attachmentCount;
1253 &*m_colorImageView, // const VkImageView* pAttachments;
1254 (deUint32)m_renderSize.x(), // deUint32 width;
1255 (deUint32)m_renderSize.y(), // deUint32 height;
1256 1u // deUint32 layers;
1259 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
1262 // Create descriptors
1264 setupUniforms(quadGrid.getConstCoords());
1266 m_descriptorSetLayout = m_descriptorSetLayoutBuilder.build(vk, vkDevice);
1267 m_descriptorPool = m_descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1270 const VkDescriptorSetAllocateInfo allocInfo =
1272 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1276 &m_descriptorSetLayout.get(),
1279 m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
1282 for (deUint32 i = 0; i < m_uniformInfos.size(); i++)
1284 const UniformInfo* uniformInfo = m_uniformInfos[i].get()->get();
1285 deUint32 location = uniformInfo->location;
1287 if (uniformInfo->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
1289 const BufferUniform* bufferInfo = dynamic_cast<const BufferUniform*>(uniformInfo);
1291 m_descriptorSetUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &bufferInfo->descriptor);
1293 else if (uniformInfo->type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
1295 const SamplerUniform* samplerInfo = dynamic_cast<const SamplerUniform*>(uniformInfo);
1297 m_descriptorSetUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &samplerInfo->descriptor);
1300 DE_FATAL("Impossible");
1303 m_descriptorSetUpdateBuilder.update(vk, vkDevice);
1306 // Create pipeline layout
1308 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1310 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1311 DE_NULL, // const void* pNext;
1312 (VkPipelineLayoutCreateFlags)0,
1313 1u, // deUint32 descriptorSetCount;
1314 &*m_descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
1315 0u, // deUint32 pushConstantRangeCount;
1316 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
1319 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1324 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
1325 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
1330 const VkPipelineShaderStageCreateInfo shaderStageParams[2] =
1333 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1334 DE_NULL, // const void* pNext;
1335 (VkPipelineShaderStageCreateFlags)0,
1336 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStage stage;
1337 *m_vertexShaderModule, // VkShader shader;
1339 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1342 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1343 DE_NULL, // const void* pNext;
1344 (VkPipelineShaderStageCreateFlags)0,
1345 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStage stage;
1346 *m_fragmentShaderModule, // VkShader shader;
1348 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1352 // Add test case specific attributes
1354 m_attribFunc(*this, quadGrid.getNumVertices());
1356 // Add base attributes
1357 setupDefaultInputs(quadGrid);
1359 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
1361 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1362 DE_NULL, // const void* pNext;
1363 (VkPipelineVertexInputStateCreateFlags)0,
1364 (deUint32)m_vertexBindingDescription.size(), // deUint32 bindingCount;
1365 &m_vertexBindingDescription[0], // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1366 (deUint32)m_vertexattributeDescription.size(), // deUint32 attributeCount;
1367 &m_vertexattributeDescription[0], // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1370 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
1372 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
1373 DE_NULL, // const void* pNext;
1374 (VkPipelineInputAssemblyStateCreateFlags)0,
1375 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology;
1376 false // VkBool32 primitiveRestartEnable;
1379 const VkViewport viewport =
1381 0.0f, // float originX;
1382 0.0f, // float originY;
1383 (float)m_renderSize.x(), // float width;
1384 (float)m_renderSize.y(), // float height;
1385 0.0f, // float minDepth;
1386 1.0f // float maxDepth;
1389 const VkRect2D scissor =
1394 }, // VkOffset2D offset;
1396 m_renderSize.x(), // deUint32 width;
1397 m_renderSize.y(), // deUint32 height;
1398 }, // VkExtent2D extent;
1401 const VkPipelineViewportStateCreateInfo viewportStateParams =
1403 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
1404 DE_NULL, // const void* pNext;
1405 (VkPipelineViewportStateCreateFlags)0,
1406 1u, // deUint32 viewportCount;
1407 &viewport, // const VkViewport* pViewports;
1408 1u, // deUint32 scissorsCount;
1409 &scissor, // const VkRect2D* pScissors;
1412 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
1414 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
1415 DE_NULL, // const void* pNext;
1416 (VkPipelineRasterizationStateCreateFlags)0,
1417 false, // VkBool32 depthClipEnable;
1418 false, // VkBool32 rasterizerDiscardEnable;
1419 VK_POLYGON_MODE_FILL, // VkFillMode fillMode;
1420 VK_CULL_MODE_NONE, // VkCullMode cullMode;
1421 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
1422 false, // VkBool32 depthBiasEnable;
1423 0.0f, // float depthBias;
1424 0.0f, // float depthBiasClamp;
1425 0.0f, // float slopeScaledDepthBias;
1426 1.0f, // float lineWidth;
1429 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1431 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
1432 DE_NULL, // const void* pNext;
1433 0u, // VkPipelineMultisampleStateCreateFlags flags;
1434 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
1435 VK_FALSE, // VkBool32 sampleShadingEnable;
1436 0.0f, // float minSampleShading;
1437 DE_NULL, // const VkSampleMask* pSampleMask;
1438 VK_FALSE, // VkBool32 alphaToCoverageEnable;
1439 VK_FALSE // VkBool32 alphaToOneEnable;
1442 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
1444 false, // VkBool32 blendEnable;
1445 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor;
1446 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendColor;
1447 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
1448 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha;
1449 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendAlpha;
1450 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
1451 (VK_COLOR_COMPONENT_R_BIT |
1452 VK_COLOR_COMPONENT_G_BIT |
1453 VK_COLOR_COMPONENT_B_BIT |
1454 VK_COLOR_COMPONENT_A_BIT), // VkChannelFlags channelWriteMask;
1457 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
1459 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1460 DE_NULL, // const void* pNext;
1461 (VkPipelineColorBlendStateCreateFlags)0,
1462 false, // VkBool32 logicOpEnable;
1463 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
1464 1u, // deUint32 attachmentCount;
1465 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
1466 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4];
1469 const VkPipelineDynamicStateCreateInfo dynamicStateInfo =
1471 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
1472 DE_NULL, // const void* pNext;
1473 (VkPipelineDynamicStateCreateFlags)0,
1474 0u, // deUint32 dynamicStateCount;
1475 DE_NULL // const VkDynamicState* pDynamicStates;
1478 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
1480 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
1481 DE_NULL, // const void* pNext;
1482 0u, // VkPipelineCreateFlags flags;
1483 2u, // deUint32 stageCount;
1484 shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages;
1485 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
1486 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
1487 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
1488 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
1489 &rasterStateParams, // const VkPipelineRasterStateCreateInfo* pRasterState;
1490 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
1491 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
1492 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
1493 &dynamicStateInfo, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
1494 *m_pipelineLayout, // VkPipelineLayout layout;
1495 *m_renderPass, // VkRenderPass renderPass;
1496 0u, // deUint32 subpass;
1497 0u, // VkPipeline basePipelineHandle;
1498 0u // deInt32 basePipelineIndex;
1501 m_graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
1504 // Create vertex indices buffer
1506 const VkDeviceSize indiceBufferSize = quadGrid.getNumTriangles() * 3 * sizeof(deUint16);
1507 const VkBufferCreateInfo indiceBufferParams =
1509 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1510 DE_NULL, // const void* pNext;
1511 0u, // VkBufferCreateFlags flags;
1512 indiceBufferSize, // VkDeviceSize size;
1513 VK_BUFFER_USAGE_INDEX_BUFFER_BIT, // VkBufferUsageFlags usage;
1514 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1515 1u, // deUint32 queueFamilyCount;
1516 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1519 m_indiceBuffer = createBuffer(vk, vkDevice, &indiceBufferParams);
1520 m_indiceBufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_indiceBuffer), MemoryRequirement::HostVisible);
1522 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_indiceBuffer, m_indiceBufferAlloc->getMemory(), m_indiceBufferAlloc->getOffset()));
1524 // Load vertice indices into buffer
1525 deMemcpy(m_indiceBufferAlloc->getHostPtr(), quadGrid.getIndices(), (size_t)indiceBufferSize);
1526 flushMappedMemoryRange(vk, vkDevice, m_indiceBufferAlloc->getMemory(), m_indiceBufferAlloc->getOffset(), indiceBufferSize);
1529 // Create command pool
1531 const VkCommandPoolCreateInfo cmdPoolParams =
1533 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
1534 DE_NULL, // const void* pNext;
1535 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
1536 queueFamilyIndex, // deUint32 queueFamilyIndex;
1539 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1542 // Create command buffer
1544 const VkCommandBufferAllocateInfo cmdBufferParams =
1546 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
1547 DE_NULL, // const void* pNext;
1548 *m_cmdPool, // VkCmdPool cmdPool;
1549 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
1550 1u // deUint32 bufferCount;
1553 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1555 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1556 DE_NULL, // const void* pNext;
1557 0u, // VkCmdBufferOptimizeFlags flags;
1558 DE_NULL, // VkRenderPass renderPass;
1559 0u, // deUint32 subpass;
1560 DE_NULL, // VkFramebuffer framebuffer;
1562 (VkQueryControlFlags)0,
1563 (VkQueryPipelineStatisticFlags)0,
1566 const VkClearValue clearValues = makeClearValueColorF32(m_clearColor.x(),
1571 const VkRenderPassBeginInfo renderPassBeginInfo =
1573 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
1574 DE_NULL, // const void* pNext;
1575 *m_renderPass, // VkRenderPass renderPass;
1576 *m_framebuffer, // VkFramebuffer framebuffer;
1577 { { 0, 0 }, {m_renderSize.x(), m_renderSize.y() } }, // VkRect2D renderArea;
1578 1, // deUint32 clearValueCount;
1579 &clearValues, // const VkClearValue* pClearValues;
1582 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
1584 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1586 // Add texture barriers
1587 std::vector<VkImageMemoryBarrier> barriers;
1588 std::vector<void*> barrierPtrs;
1590 for(deUint32 i = 0; i < m_uniformInfos.size(); i++)
1592 const UniformInfo* uniformInfo = m_uniformInfos[i].get()->get();
1594 if (uniformInfo->type != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
1599 const SamplerUniform* sampler = static_cast<const SamplerUniform*>(uniformInfo);
1601 const VkAccessFlags outputMask = VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
1602 const VkImageMemoryBarrier textureBarrier = createImageMemoryBarrier(sampler->image->get(), outputMask, 0u, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
1604 barriers.push_back(textureBarrier);
1605 barrierPtrs.push_back((void*)&barriers.back());
1608 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, (deUint32)barrierPtrs.size(), (barrierPtrs.size() ? (const void * const*)&barrierPtrs[0] : DE_NULL));
1610 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1612 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
1613 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &*m_descriptorSet, 0u, DE_NULL);
1614 vk.cmdBindIndexBuffer(*m_cmdBuffer, *m_indiceBuffer, 0, VK_INDEX_TYPE_UINT16);
1616 const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size();
1617 const std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0);
1619 std::vector<VkBuffer> buffers(numberOfVertexAttributes);
1620 for (size_t i = 0; i < numberOfVertexAttributes; i++)
1622 buffers[i] = m_vertexBuffers[i].get()->get();
1625 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]);
1626 vk.cmdDrawIndexed(*m_cmdBuffer, quadGrid.getNumTriangles() * 3, 1, 0, 0, 0);
1628 vk.cmdEndRenderPass(*m_cmdBuffer);
1629 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1634 const VkFenceCreateInfo fenceParams =
1636 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
1637 DE_NULL, // const void* pNext;
1638 0u // VkFenceCreateFlags flags;
1640 m_fence = createFence(vk, vkDevice, &fenceParams);
1645 const VkSubmitInfo submitInfo =
1647 VK_STRUCTURE_TYPE_SUBMIT_INFO,
1650 (const VkSemaphore*)DE_NULL,
1654 (const VkSemaphore*)DE_NULL,
1657 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1658 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
1659 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/));
1662 // Read back the result
1664 const VkDeviceSize imageSizeBytes = (VkDeviceSize)(sizeof(deUint32) * m_renderSize.x() * m_renderSize.y());
1665 const VkBufferCreateInfo readImageBufferParams =
1667 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1668 DE_NULL, // const void* pNext;
1669 0u, // VkBufferCreateFlags flags;
1670 imageSizeBytes, // VkDeviceSize size;
1671 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
1672 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1673 1u, // deUint32 queueFamilyCount;
1674 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1676 const Unique<VkBuffer> readImageBuffer (createBuffer(vk, vkDevice, &readImageBufferParams));
1677 const de::UniquePtr<Allocation> readImageBufferMemory (m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
1679 VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
1681 // Copy image to buffer
1682 const VkCommandBufferAllocateInfo cmdBufferParams =
1684 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
1685 DE_NULL, // const void* pNext;
1686 *m_cmdPool, // VkCmdPool cmdPool;
1687 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
1688 1u // deUint32 bufferCount;
1691 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1693 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1694 DE_NULL, // const void* pNext;
1695 0u, // VkCmdBufferOptimizeFlags flags;
1696 DE_NULL, // VkRenderPass renderPass;
1697 0u, // deUint32 subpass;
1698 DE_NULL, // VkFramebuffer framebuffer;
1700 (VkQueryControlFlags)0,
1701 (VkQueryPipelineStatisticFlags)0,
1704 const Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
1706 const VkBufferImageCopy copyParams =
1708 0u, // VkDeviceSize bufferOffset;
1709 (deUint32)m_renderSize.x(), // deUint32 bufferRowLength;
1710 (deUint32)m_renderSize.y(), // deUint32 bufferImageHeight;
1712 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect;
1713 0u, // deUint32 mipLevel;
1714 0u, // deUint32 arraySlice;
1715 1u, // deUint32 arraySize;
1716 }, // VkImageSubresourceCopy imageSubresource;
1717 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
1718 { m_renderSize.x(), m_renderSize.y(), 1u } // VkExtent3D imageExtent;
1720 const VkSubmitInfo submitInfo =
1722 VK_STRUCTURE_TYPE_SUBMIT_INFO,
1725 (const VkSemaphore*)DE_NULL,
1729 (const VkSemaphore*)DE_NULL,
1732 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
1733 vk.cmdCopyImageToBuffer(*cmdBuffer, *m_colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, ©Params);
1734 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
1736 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1737 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
1738 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
1740 invalidateMappedMemoryRange(vk, vkDevice, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset(), imageSizeBytes);
1742 const tcu::TextureFormat resultFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
1743 const tcu::ConstPixelBufferAccess resultAccess (resultFormat, m_renderSize.x(), m_renderSize.y(), 1, readImageBufferMemory->getHostPtr());
1745 tcu::copy(result.getAccess(), resultAccess);
1749 void ShaderRenderCaseInstance::computeVertexReference (tcu::Surface& result, const QuadGrid& quadGrid)
1752 const int width = result.getWidth();
1753 const int height = result.getHeight();
1754 const int gridSize = quadGrid.getGridSize();
1755 const int stride = gridSize + 1;
1756 const bool hasAlpha = true; // \todo [2015-09-07 elecro] add correct alpha check
1757 ShaderEvalContext evalCtx (quadGrid);
1759 // Evaluate color for each vertex.
1760 std::vector<tcu::Vec4> colors ((gridSize + 1) * (gridSize + 1));
1761 for (int y = 0; y < gridSize+1; y++)
1762 for (int x = 0; x < gridSize+1; x++)
1764 const float sx = (float)x / (float)gridSize;
1765 const float sy = (float)y / (float)gridSize;
1766 const int vtxNdx = ((y * (gridSize+1)) + x);
1768 evalCtx.reset(sx, sy);
1769 m_evaluator.evaluate(evalCtx);
1770 DE_ASSERT(!evalCtx.isDiscarded); // Discard is not available in vertex shader.
1771 tcu::Vec4 color = evalCtx.color;
1776 colors[vtxNdx] = color;
1780 for (int y = 0; y < gridSize; y++)
1781 for (int x = 0; x < gridSize; x++)
1783 const float x0 = (float)x / (float)gridSize;
1784 const float x1 = (float)(x + 1) / (float)gridSize;
1785 const float y0 = (float)y / (float)gridSize;
1786 const float y1 = (float)(y + 1) / (float)gridSize;
1788 const float sx0 = x0 * (float)width;
1789 const float sx1 = x1 * (float)width;
1790 const float sy0 = y0 * (float)height;
1791 const float sy1 = y1 * (float)height;
1792 const float oosx = 1.0f / (sx1 - sx0);
1793 const float oosy = 1.0f / (sy1 - sy0);
1795 const int ix0 = deCeilFloatToInt32(sx0 - 0.5f);
1796 const int ix1 = deCeilFloatToInt32(sx1 - 0.5f);
1797 const int iy0 = deCeilFloatToInt32(sy0 - 0.5f);
1798 const int iy1 = deCeilFloatToInt32(sy1 - 0.5f);
1800 const int v00 = (y * stride) + x;
1801 const int v01 = (y * stride) + x + 1;
1802 const int v10 = ((y + 1) * stride) + x;
1803 const int v11 = ((y + 1) * stride) + x + 1;
1804 const tcu::Vec4 c00 = colors[v00];
1805 const tcu::Vec4 c01 = colors[v01];
1806 const tcu::Vec4 c10 = colors[v10];
1807 const tcu::Vec4 c11 = colors[v11];
1809 //printf("(%d,%d) -> (%f..%f, %f..%f) (%d..%d, %d..%d)\n", x, y, sx0, sx1, sy0, sy1, ix0, ix1, iy0, iy1);
1811 for (int iy = iy0; iy < iy1; iy++)
1812 for (int ix = ix0; ix < ix1; ix++)
1814 DE_ASSERT(deInBounds32(ix, 0, width));
1815 DE_ASSERT(deInBounds32(iy, 0, height));
1817 const float sfx = (float)ix + 0.5f;
1818 const float sfy = (float)iy + 0.5f;
1819 const float fx1 = deFloatClamp((sfx - sx0) * oosx, 0.0f, 1.0f);
1820 const float fy1 = deFloatClamp((sfy - sy0) * oosy, 0.0f, 1.0f);
1822 // Triangle quad interpolation.
1823 const bool tri = fx1 + fy1 <= 1.0f;
1824 const float tx = tri ? fx1 : (1.0f-fx1);
1825 const float ty = tri ? fy1 : (1.0f-fy1);
1826 const tcu::Vec4& t0 = tri ? c00 : c11;
1827 const tcu::Vec4& t1 = tri ? c01 : c10;
1828 const tcu::Vec4& t2 = tri ? c10 : c01;
1829 const tcu::Vec4 color = t0 + (t1-t0)*tx + (t2-t0)*ty;
1831 result.setPixel(ix, iy, tcu::RGBA(color));
1836 void ShaderRenderCaseInstance::computeFragmentReference (tcu::Surface& result, const QuadGrid& quadGrid)
1839 const int width = result.getWidth();
1840 const int height = result.getHeight();
1841 const bool hasAlpha = true; // \todo [2015-09-07 elecro] add correct alpha check
1842 ShaderEvalContext evalCtx (quadGrid);
1845 for (int y = 0; y < height; y++)
1846 for (int x = 0; x < width; x++)
1848 const float sx = ((float)x + 0.5f) / (float)width;
1849 const float sy = ((float)y + 0.5f) / (float)height;
1851 evalCtx.reset(sx, sy);
1852 m_evaluator.evaluate(evalCtx);
1853 // Select either clear color or computed color based on discarded bit.
1854 tcu::Vec4 color = evalCtx.isDiscarded ? m_clearColor : evalCtx.color;
1859 result.setPixel(x, y, tcu::RGBA(color));
1863 bool ShaderRenderCaseInstance::compareImages (const tcu::Surface& resImage, const tcu::Surface& refImage, float errorThreshold)
1865 return tcu::fuzzyCompare(m_context.getTestContext().getLog(), "ComparisonResult", "Image comparison result", refImage, resImage, errorThreshold, tcu::COMPARE_LOG_RESULT);