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 GRID_SIZE = 2;
72 static const deUint32 MAX_RENDER_WIDTH = 128;
73 static const deUint32 MAX_RENDER_HEIGHT = 128;
74 static const tcu::Vec4 DEFAULT_CLEAR_COLOR = 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 (DEFAULT_CLEAR_COLOR)
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::UVec2 viewportSize = getViewportSize();
495 const int width = viewportSize.x();
496 const int height = viewportSize.y();
498 QuadGrid quadGrid (m_isVertexCase ? GRID_SIZE : 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::UVec2 ShaderRenderCaseInstance::getViewportSize (void) const
752 return tcu::UVec2(de::min(m_renderSize.x(), MAX_RENDER_WIDTH),
753 de::min(m_renderSize.y(), MAX_RENDER_HEIGHT));
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;
773 (deUint32)texture.getWidth(),
774 (deUint32)texture.getHeight(),
776 }, // VkExtend3D extent;
777 1u, // deUint32 mipLevels;
778 1u, // deUint32 arraySize;
779 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
780 tiling, // VkImageTiling tiling;
781 usage, // VkImageUsageFlags usage;
782 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
783 1, // deuint32 queueFamilyCount;
784 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
785 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
788 Move<VkImage> vkTexture = createImage(vk, vkDevice, &imageCreateInfo);
792 de::MovePtr<Allocation> ShaderRenderCaseInstance::uploadImage2D (const tcu::Texture2D& refTexture,
793 const VkImage& vkTexture)
795 const VkDevice vkDevice = m_context.getDevice();
796 const DeviceInterface& vk = m_context.getDeviceInterface();
798 de::MovePtr<Allocation> allocation = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, vkTexture), MemoryRequirement::HostVisible);
799 VK_CHECK(vk.bindImageMemory(vkDevice, vkTexture, allocation->getMemory(), allocation->getOffset()));
801 const VkImageSubresource subres =
803 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
804 0u, // deUint32 mipLevel;
805 0u // deUint32 arraySlice
808 VkSubresourceLayout layout;
809 vk.getImageSubresourceLayout(vkDevice, vkTexture, &subres, &layout);
811 tcu::ConstPixelBufferAccess access = refTexture.getLevel(0);
812 tcu::PixelBufferAccess destAccess (refTexture.getFormat(), refTexture.getWidth(), refTexture.getHeight(), 1, allocation->getHostPtr());
814 tcu::copy(destAccess, access);
816 flushMappedMemoryRange(vk, vkDevice, allocation->getMemory(), allocation->getOffset(), layout.size);
821 void ShaderRenderCaseInstance::copyTilingImageToOptimal (const vk::VkImage& srcImage,
822 const vk::VkImage& dstImage,
826 const VkDevice vkDevice = m_context.getDevice();
827 const DeviceInterface& vk = m_context.getDeviceInterface();
828 const VkQueue queue = m_context.getUniversalQueue();
829 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
831 // Create command pool
832 const VkCommandPoolCreateInfo cmdPoolParams =
834 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
835 DE_NULL, // const void* pNext;
836 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
837 queueFamilyIndex, // deUint32 queueFamilyIndex;
840 Move<VkCommandPool> cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
842 // Create command buffer
843 const VkCommandBufferAllocateInfo cmdBufferParams =
845 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
846 DE_NULL, // const void* pNext;
847 *cmdPool, // VkCommandPool commandPool;
848 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
849 1u // deUint32 bufferCount;
852 const VkCommandBufferUsageFlags usageFlags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
853 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
855 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
856 DE_NULL, // const void* pNext;
857 usageFlags, // VkCommandBufferUsageFlags flags;
858 (const VkCommandBufferInheritanceInfo*)DE_NULL,
861 Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
863 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
865 // Add image barriers
866 const VkImageMemoryBarrier layoutBarriers[2] =
868 createImageMemoryBarrier(srcImage, (VkAccessFlags)0u, (VkAccessFlags)0u, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL),
869 createImageMemoryBarrier(dstImage, (VkAccessFlags)0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
872 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
873 0, (const VkMemoryBarrier*)DE_NULL,
874 0, (const VkBufferMemoryBarrier*)DE_NULL,
875 DE_LENGTH_OF_ARRAY(layoutBarriers), layoutBarriers);
878 const VkImageCopy imageCopy =
881 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect;
882 0u, // deUint32 mipLevel;
883 0u, // deUint32 arrayLayer;
884 1u // deUint32 arraySize;
885 }, // VkImageSubresourceCopy srcSubresource;
890 }, // VkOffset3D srcOffset;
892 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect;
893 0u, // deUint32 mipLevel;
894 0u, // deUint32 arrayLayer;
895 1u // deUint32 arraySize;
896 }, // VkImageSubresourceCopy destSubResource;
901 }, // VkOffset3D dstOffset;
903 width, // int32 width;
904 height, // int32 height;
906 } // VkExtent3D extent;
909 vk.cmdCopyImage(*cmdBuffer, srcImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &imageCopy);
911 // Add destination barrier
912 const VkImageMemoryBarrier dstBarrier =
913 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);
915 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
916 0, (const VkMemoryBarrier*)DE_NULL,
917 0, (const VkBufferMemoryBarrier*)DE_NULL,
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,
935 (const VkPipelineStageFlags*)DE_NULL,
939 (const VkSemaphore*)DE_NULL,
944 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
945 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
946 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/));
949 void ShaderRenderCaseInstance::useSampler2D (deUint32 bindingLocation, deUint32 textureID)
951 DE_ASSERT(textureID < m_textures.size());
953 const VkDevice vkDevice = m_context.getDevice();
954 const DeviceInterface& vk = m_context.getDeviceInterface();
955 const TextureBinding& textureBinding = *m_textures[textureID];
956 const tcu::Texture2D& refTexture = textureBinding.get2D();
957 const tcu::Sampler& refSampler = textureBinding.getSampler();
958 const VkFormat format = refTexture.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
959 ? VK_FORMAT_R8G8B8A8_UNORM
960 : VK_FORMAT_R8G8B8_UNORM;
962 // Create & alloc the image
963 Move<VkImage> vkTexture;
964 de::MovePtr<Allocation> allocation;
966 if (isSupportedLinearTilingFormat(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), format))
968 vkTexture = createImage2D(refTexture, format, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_LINEAR);
969 allocation = uploadImage2D(refTexture, *vkTexture);
971 else if (isSupportedOptimalTilingFormat(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), format))
973 Move<VkImage> stagingTexture (createImage2D(refTexture, format, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_LINEAR));
974 de::MovePtr<Allocation> stagingAlloc (uploadImage2D(refTexture, *stagingTexture));
976 const VkImageUsageFlags dstUsageFlags = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
977 vkTexture = createImage2D(refTexture, format, dstUsageFlags, VK_IMAGE_TILING_OPTIMAL);
978 allocation = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *vkTexture), MemoryRequirement::Any);
979 VK_CHECK(vk.bindImageMemory(vkDevice, *vkTexture, allocation->getMemory(), allocation->getOffset()));
981 copyTilingImageToOptimal(*stagingTexture, *vkTexture, refTexture.getWidth(), refTexture.getHeight());
985 TCU_THROW(InternalError, "Unable to create 2D image");
989 const VkSamplerCreateInfo samplerParams = mapSampler(refSampler, refTexture.getFormat());
990 Move<VkSampler> sampler = createSampler(vk, vkDevice, &samplerParams);
992 const VkImageViewCreateInfo viewParams =
994 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
995 NULL, // const voide* pNext;
996 0u, // VkImageViewCreateFlags flags;
997 *vkTexture, // VkImage image;
998 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
999 format, // VkFormat format;
1001 VK_COMPONENT_SWIZZLE_R, // VkChannelSwizzle r;
1002 VK_COMPONENT_SWIZZLE_G, // VkChannelSwizzle g;
1003 VK_COMPONENT_SWIZZLE_B, // VkChannelSwizzle b;
1004 VK_COMPONENT_SWIZZLE_A // VkChannelSwizzle a;
1005 }, // VkChannelMapping channels;
1007 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1008 0, // deUint32 baseMipLevel;
1009 1, // deUint32 mipLevels;
1010 0, // deUint32 baseArraySlice;
1011 1 // deUint32 arraySize;
1012 }, // VkImageSubresourceRange subresourceRange;
1015 Move<VkImageView> imageView = createImageView(vk, vkDevice, &viewParams);
1017 const vk::VkDescriptorImageInfo descriptor =
1019 sampler.get(), // VkSampler sampler;
1020 imageView.get(), // VkImageView imageView;
1021 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
1024 de::MovePtr<SamplerUniform> uniform(new SamplerUniform());
1025 uniform->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
1026 uniform->descriptor = descriptor;
1027 uniform->location = bindingLocation;
1028 uniform->image = VkImageSp(new vk::Unique<VkImage>(vkTexture));
1029 uniform->imageView = VkImageViewSp(new vk::Unique<VkImageView>(imageView));
1030 uniform->sampler = VkSamplerSp(new vk::Unique<VkSampler>(sampler));
1031 uniform->alloc = AllocationSp(allocation.release());
1033 m_descriptorSetLayoutBuilder.addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, vk::VK_SHADER_STAGE_ALL, &uniform->descriptor.sampler);
1034 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
1036 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniform)));
1039 void ShaderRenderCaseInstance::setupDefaultInputs (const QuadGrid& quadGrid)
1041 /* Configuration of the vertex input attributes:
1042 a_position is at location 0
1043 a_coords is at location 1
1044 a_unitCoords is at location 2
1045 a_one is at location 3
1047 User attributes starts from at the location 4.
1049 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getPositions());
1050 addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getCoords());
1051 addAttribute(2u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUnitCoords());
1052 addAttribute(3u, VK_FORMAT_R32_SFLOAT, sizeof(float), quadGrid.getNumVertices(), quadGrid.getAttribOne());
1056 BaseAttributeType type;
1058 } userAttributes[] =
1068 BaseAttributeType matrixType;
1084 for (size_t attrNdx = 0; attrNdx < m_enabledBaseAttributes.size(); attrNdx++)
1086 for (int userNdx = 0; userNdx < DE_LENGTH_OF_ARRAY(userAttributes); userNdx++)
1088 if (userAttributes[userNdx].type != m_enabledBaseAttributes[attrNdx].type)
1091 addAttribute(m_enabledBaseAttributes[attrNdx].location, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUserAttrib(userNdx));
1094 for (int matNdx = 0; matNdx < DE_LENGTH_OF_ARRAY(matrices); matNdx++)
1097 if (matrices[matNdx].matrixType != m_enabledBaseAttributes[attrNdx].type)
1100 const int numCols = matrices[matNdx].numCols;
1102 for (int colNdx = 0; colNdx < numCols; colNdx++)
1104 addAttribute(m_enabledBaseAttributes[attrNdx].location + colNdx, VK_FORMAT_R32G32B32A32_SFLOAT, (deUint32)(4 * sizeof(float)), quadGrid.getNumVertices(), quadGrid.getUserAttrib(colNdx));
1110 void ShaderRenderCaseInstance::render (tcu::Surface& result, const QuadGrid& quadGrid)
1112 const VkDevice vkDevice = m_context.getDevice();
1113 const DeviceInterface& vk = m_context.getDeviceInterface();
1114 const VkQueue queue = m_context.getUniversalQueue();
1115 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1117 // Create color image
1119 const VkImageCreateInfo colorImageParams =
1121 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1122 DE_NULL, // const void* pNext;
1123 0u, // VkImageCreateFlags flags;
1124 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1125 m_colorFormat, // VkFormat format;
1126 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent;
1127 1u, // deUint32 mipLevels;
1128 1u, // deUint32 arraySize;
1129 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
1130 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1131 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
1132 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1133 1u, // deUint32 queueFamilyCount;
1134 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1135 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1138 m_colorImage = createImage(vk, vkDevice, &colorImageParams);
1140 // Allocate and bind color image memory
1141 m_colorImageAlloc = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
1142 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
1145 // Create color attachment view
1147 const VkImageViewCreateInfo colorImageViewParams =
1149 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1150 DE_NULL, // const void* pNext;
1151 0u, // VkImageViewCreateFlags flags;
1152 *m_colorImage, // VkImage image;
1153 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
1154 m_colorFormat, // VkFormat format;
1156 VK_COMPONENT_SWIZZLE_R, // VkChannelSwizzle r;
1157 VK_COMPONENT_SWIZZLE_G, // VkChannelSwizzle g;
1158 VK_COMPONENT_SWIZZLE_B, // VkChannelSwizzle b;
1159 VK_COMPONENT_SWIZZLE_A // VkChannelSwizzle a;
1160 }, // VkChannelMapping channels;
1162 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1163 0, // deUint32 baseMipLevel;
1164 1, // deUint32 mipLevels;
1165 0, // deUint32 baseArraySlice;
1166 1 // deUint32 arraySize;
1167 }, // VkImageSubresourceRange subresourceRange;
1170 m_colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
1173 // Create render pass
1175 const VkAttachmentDescription attachmentDescription =
1177 (VkAttachmentDescriptionFlags)0,
1178 m_colorFormat, // VkFormat format;
1179 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
1180 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
1181 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
1182 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
1183 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
1184 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
1185 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
1188 const VkAttachmentReference attachmentReference =
1190 0u, // deUint32 attachment;
1191 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
1194 const VkSubpassDescription subpassDescription =
1196 0u, // VkSubpassDescriptionFlags flags;
1197 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
1198 0u, // deUint32 inputCount;
1199 DE_NULL, // constVkAttachmentReference* pInputAttachments;
1200 1u, // deUint32 colorCount;
1201 &attachmentReference, // constVkAttachmentReference* pColorAttachments;
1202 DE_NULL, // constVkAttachmentReference* pResolveAttachments;
1203 DE_NULL, // VkAttachmentReference depthStencilAttachment;
1204 0u, // deUint32 preserveCount;
1205 DE_NULL // constVkAttachmentReference* pPreserveAttachments;
1208 const VkRenderPassCreateInfo renderPassParams =
1210 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
1211 DE_NULL, // const void* pNext;
1212 (VkRenderPassCreateFlags)0,
1213 1u, // deUint32 attachmentCount;
1214 &attachmentDescription, // const VkAttachmentDescription* pAttachments;
1215 1u, // deUint32 subpassCount;
1216 &subpassDescription, // const VkSubpassDescription* pSubpasses;
1217 0u, // deUint32 dependencyCount;
1218 DE_NULL // const VkSubpassDependency* pDependencies;
1221 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
1224 // Create framebuffer
1226 const VkFramebufferCreateInfo framebufferParams =
1228 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
1229 DE_NULL, // const void* pNext;
1230 (VkFramebufferCreateFlags)0,
1231 *m_renderPass, // VkRenderPass renderPass;
1232 1u, // deUint32 attachmentCount;
1233 &*m_colorImageView, // const VkImageView* pAttachments;
1234 (deUint32)m_renderSize.x(), // deUint32 width;
1235 (deUint32)m_renderSize.y(), // deUint32 height;
1236 1u // deUint32 layers;
1239 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
1242 // Create descriptors
1244 setupUniforms(quadGrid.getConstCoords());
1246 m_descriptorSetLayout = m_descriptorSetLayoutBuilder.build(vk, vkDevice);
1247 if (!m_uniformInfos.empty())
1249 m_descriptorPool = m_descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1250 const VkDescriptorSetAllocateInfo allocInfo =
1252 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1256 &m_descriptorSetLayout.get(),
1259 m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
1262 for (deUint32 i = 0; i < m_uniformInfos.size(); i++)
1264 const UniformInfo* uniformInfo = m_uniformInfos[i].get()->get();
1265 deUint32 location = uniformInfo->location;
1267 if (uniformInfo->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
1269 const BufferUniform* bufferInfo = dynamic_cast<const BufferUniform*>(uniformInfo);
1271 m_descriptorSetUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &bufferInfo->descriptor);
1273 else if (uniformInfo->type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
1275 const SamplerUniform* samplerInfo = dynamic_cast<const SamplerUniform*>(uniformInfo);
1277 m_descriptorSetUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &samplerInfo->descriptor);
1280 DE_FATAL("Impossible");
1283 m_descriptorSetUpdateBuilder.update(vk, vkDevice);
1286 // Create pipeline layout
1288 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1290 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1291 DE_NULL, // const void* pNext;
1292 (VkPipelineLayoutCreateFlags)0,
1293 1u, // deUint32 descriptorSetCount;
1294 &*m_descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
1295 0u, // deUint32 pushConstantRangeCount;
1296 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
1299 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1304 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
1305 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
1310 const VkPipelineShaderStageCreateInfo shaderStageParams[2] =
1313 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1314 DE_NULL, // const void* pNext;
1315 (VkPipelineShaderStageCreateFlags)0,
1316 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStage stage;
1317 *m_vertexShaderModule, // VkShader shader;
1319 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1322 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1323 DE_NULL, // const void* pNext;
1324 (VkPipelineShaderStageCreateFlags)0,
1325 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStage stage;
1326 *m_fragmentShaderModule, // VkShader shader;
1328 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1332 // Add test case specific attributes
1334 m_attribFunc(*this, quadGrid.getNumVertices());
1336 // Add base attributes
1337 setupDefaultInputs(quadGrid);
1339 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
1341 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1342 DE_NULL, // const void* pNext;
1343 (VkPipelineVertexInputStateCreateFlags)0,
1344 (deUint32)m_vertexBindingDescription.size(), // deUint32 bindingCount;
1345 &m_vertexBindingDescription[0], // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1346 (deUint32)m_vertexattributeDescription.size(), // deUint32 attributeCount;
1347 &m_vertexattributeDescription[0], // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1350 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
1352 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
1353 DE_NULL, // const void* pNext;
1354 (VkPipelineInputAssemblyStateCreateFlags)0,
1355 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology;
1356 false // VkBool32 primitiveRestartEnable;
1359 const VkViewport viewport =
1361 0.0f, // float originX;
1362 0.0f, // float originY;
1363 (float)m_renderSize.x(), // float width;
1364 (float)m_renderSize.y(), // float height;
1365 0.0f, // float minDepth;
1366 1.0f // float maxDepth;
1369 const VkRect2D scissor =
1374 }, // VkOffset2D offset;
1376 m_renderSize.x(), // deUint32 width;
1377 m_renderSize.y(), // deUint32 height;
1378 }, // VkExtent2D extent;
1381 const VkPipelineViewportStateCreateInfo viewportStateParams =
1383 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
1384 DE_NULL, // const void* pNext;
1385 (VkPipelineViewportStateCreateFlags)0,
1386 1u, // deUint32 viewportCount;
1387 &viewport, // const VkViewport* pViewports;
1388 1u, // deUint32 scissorsCount;
1389 &scissor, // const VkRect2D* pScissors;
1392 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
1394 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
1395 DE_NULL, // const void* pNext;
1396 (VkPipelineRasterizationStateCreateFlags)0,
1397 false, // VkBool32 depthClipEnable;
1398 false, // VkBool32 rasterizerDiscardEnable;
1399 VK_POLYGON_MODE_FILL, // VkFillMode fillMode;
1400 VK_CULL_MODE_NONE, // VkCullMode cullMode;
1401 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
1402 false, // VkBool32 depthBiasEnable;
1403 0.0f, // float depthBias;
1404 0.0f, // float depthBiasClamp;
1405 0.0f, // float slopeScaledDepthBias;
1406 1.0f, // float lineWidth;
1409 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1411 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
1412 DE_NULL, // const void* pNext;
1413 0u, // VkPipelineMultisampleStateCreateFlags flags;
1414 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
1415 VK_FALSE, // VkBool32 sampleShadingEnable;
1416 0.0f, // float minSampleShading;
1417 DE_NULL, // const VkSampleMask* pSampleMask;
1418 VK_FALSE, // VkBool32 alphaToCoverageEnable;
1419 VK_FALSE // VkBool32 alphaToOneEnable;
1422 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
1424 false, // VkBool32 blendEnable;
1425 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor;
1426 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendColor;
1427 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
1428 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha;
1429 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendAlpha;
1430 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
1431 (VK_COLOR_COMPONENT_R_BIT |
1432 VK_COLOR_COMPONENT_G_BIT |
1433 VK_COLOR_COMPONENT_B_BIT |
1434 VK_COLOR_COMPONENT_A_BIT), // VkChannelFlags channelWriteMask;
1437 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
1439 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1440 DE_NULL, // const void* pNext;
1441 (VkPipelineColorBlendStateCreateFlags)0,
1442 false, // VkBool32 logicOpEnable;
1443 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
1444 1u, // deUint32 attachmentCount;
1445 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
1446 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4];
1449 const VkPipelineDynamicStateCreateInfo dynamicStateInfo =
1451 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
1452 DE_NULL, // const void* pNext;
1453 (VkPipelineDynamicStateCreateFlags)0,
1454 0u, // deUint32 dynamicStateCount;
1455 DE_NULL // const VkDynamicState* pDynamicStates;
1458 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
1460 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
1461 DE_NULL, // const void* pNext;
1462 0u, // VkPipelineCreateFlags flags;
1463 2u, // deUint32 stageCount;
1464 shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages;
1465 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
1466 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
1467 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
1468 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
1469 &rasterStateParams, // const VkPipelineRasterStateCreateInfo* pRasterState;
1470 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
1471 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
1472 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
1473 &dynamicStateInfo, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
1474 *m_pipelineLayout, // VkPipelineLayout layout;
1475 *m_renderPass, // VkRenderPass renderPass;
1476 0u, // deUint32 subpass;
1477 0u, // VkPipeline basePipelineHandle;
1478 0u // deInt32 basePipelineIndex;
1481 m_graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
1484 // Create vertex indices buffer
1486 const VkDeviceSize indiceBufferSize = quadGrid.getNumTriangles() * 3 * sizeof(deUint16);
1487 const VkBufferCreateInfo indiceBufferParams =
1489 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1490 DE_NULL, // const void* pNext;
1491 0u, // VkBufferCreateFlags flags;
1492 indiceBufferSize, // VkDeviceSize size;
1493 VK_BUFFER_USAGE_INDEX_BUFFER_BIT, // VkBufferUsageFlags usage;
1494 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1495 1u, // deUint32 queueFamilyCount;
1496 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1499 m_indiceBuffer = createBuffer(vk, vkDevice, &indiceBufferParams);
1500 m_indiceBufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_indiceBuffer), MemoryRequirement::HostVisible);
1502 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_indiceBuffer, m_indiceBufferAlloc->getMemory(), m_indiceBufferAlloc->getOffset()));
1504 // Load vertice indices into buffer
1505 deMemcpy(m_indiceBufferAlloc->getHostPtr(), quadGrid.getIndices(), (size_t)indiceBufferSize);
1506 flushMappedMemoryRange(vk, vkDevice, m_indiceBufferAlloc->getMemory(), m_indiceBufferAlloc->getOffset(), indiceBufferSize);
1509 // Create command pool
1511 const VkCommandPoolCreateInfo cmdPoolParams =
1513 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
1514 DE_NULL, // const void* pNext;
1515 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
1516 queueFamilyIndex, // deUint32 queueFamilyIndex;
1519 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1522 // Create command buffer
1524 const VkCommandBufferAllocateInfo cmdBufferParams =
1526 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
1527 DE_NULL, // const void* pNext;
1528 *m_cmdPool, // VkCmdPool cmdPool;
1529 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
1530 1u // deUint32 bufferCount;
1533 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1535 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1536 DE_NULL, // const void* pNext;
1537 0u, // VkCmdBufferOptimizeFlags flags;
1538 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1541 const VkClearValue clearValues = makeClearValueColorF32(m_clearColor.x(),
1546 const VkRenderPassBeginInfo renderPassBeginInfo =
1548 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
1549 DE_NULL, // const void* pNext;
1550 *m_renderPass, // VkRenderPass renderPass;
1551 *m_framebuffer, // VkFramebuffer framebuffer;
1552 { { 0, 0 }, {m_renderSize.x(), m_renderSize.y() } }, // VkRect2D renderArea;
1553 1, // deUint32 clearValueCount;
1554 &clearValues, // const VkClearValue* pClearValues;
1557 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
1559 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1561 // Add texture barriers
1562 std::vector<VkImageMemoryBarrier> barriers;
1564 for(deUint32 i = 0; i < m_uniformInfos.size(); i++)
1566 const UniformInfo* uniformInfo = m_uniformInfos[i].get()->get();
1568 if (uniformInfo->type != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
1573 const SamplerUniform* sampler = static_cast<const SamplerUniform*>(uniformInfo);
1575 const VkAccessFlags outputMask = VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
1576 const VkImageMemoryBarrier textureBarrier = createImageMemoryBarrier(sampler->image->get(), outputMask, 0u, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
1578 barriers.push_back(textureBarrier);
1581 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
1582 0, (const VkMemoryBarrier*)DE_NULL,
1583 0, (const VkBufferMemoryBarrier*)DE_NULL,
1584 (deUint32)barriers.size(), (barriers.empty() ? (const VkImageMemoryBarrier*)DE_NULL : &barriers[0]));
1586 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1588 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
1589 if (!m_uniformInfos.empty())
1590 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &*m_descriptorSet, 0u, DE_NULL);
1591 vk.cmdBindIndexBuffer(*m_cmdBuffer, *m_indiceBuffer, 0, VK_INDEX_TYPE_UINT16);
1593 const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size();
1594 const std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0);
1596 std::vector<VkBuffer> buffers(numberOfVertexAttributes);
1597 for (size_t i = 0; i < numberOfVertexAttributes; i++)
1599 buffers[i] = m_vertexBuffers[i].get()->get();
1602 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]);
1603 vk.cmdDrawIndexed(*m_cmdBuffer, quadGrid.getNumTriangles() * 3, 1, 0, 0, 0);
1605 vk.cmdEndRenderPass(*m_cmdBuffer);
1606 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1611 const VkFenceCreateInfo fenceParams =
1613 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
1614 DE_NULL, // const void* pNext;
1615 0u // VkFenceCreateFlags flags;
1617 m_fence = createFence(vk, vkDevice, &fenceParams);
1622 const VkSubmitInfo submitInfo =
1624 VK_STRUCTURE_TYPE_SUBMIT_INFO,
1627 (const VkSemaphore*)DE_NULL,
1628 (const VkPipelineStageFlags*)DE_NULL,
1632 (const VkSemaphore*)DE_NULL,
1635 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1636 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
1637 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/));
1640 // Read back the result
1642 const VkDeviceSize imageSizeBytes = (VkDeviceSize)(sizeof(deUint32) * m_renderSize.x() * m_renderSize.y());
1643 const VkBufferCreateInfo readImageBufferParams =
1645 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1646 DE_NULL, // const void* pNext;
1647 0u, // VkBufferCreateFlags flags;
1648 imageSizeBytes, // VkDeviceSize size;
1649 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
1650 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1651 1u, // deUint32 queueFamilyCount;
1652 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1654 const Unique<VkBuffer> readImageBuffer (createBuffer(vk, vkDevice, &readImageBufferParams));
1655 const de::UniquePtr<Allocation> readImageBufferMemory (m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
1657 VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
1659 // Copy image to buffer
1660 const VkCommandBufferAllocateInfo cmdBufferParams =
1662 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
1663 DE_NULL, // const void* pNext;
1664 *m_cmdPool, // VkCmdPool cmdPool;
1665 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
1666 1u // deUint32 bufferCount;
1669 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1671 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1672 DE_NULL, // const void* pNext;
1673 0u, // VkCmdBufferOptimizeFlags flags;
1674 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1677 const Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
1679 const VkBufferImageCopy copyParams =
1681 0u, // VkDeviceSize bufferOffset;
1682 (deUint32)m_renderSize.x(), // deUint32 bufferRowLength;
1683 (deUint32)m_renderSize.y(), // deUint32 bufferImageHeight;
1685 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect;
1686 0u, // deUint32 mipLevel;
1687 0u, // deUint32 arraySlice;
1688 1u, // deUint32 arraySize;
1689 }, // VkImageSubresourceCopy imageSubresource;
1690 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
1691 { m_renderSize.x(), m_renderSize.y(), 1u } // VkExtent3D imageExtent;
1693 const VkSubmitInfo submitInfo =
1695 VK_STRUCTURE_TYPE_SUBMIT_INFO,
1698 (const VkSemaphore*)DE_NULL,
1699 (const VkPipelineStageFlags*)DE_NULL,
1703 (const VkSemaphore*)DE_NULL,
1706 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
1707 vk.cmdCopyImageToBuffer(*cmdBuffer, *m_colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, ©Params);
1708 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
1710 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1711 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
1712 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
1714 invalidateMappedMemoryRange(vk, vkDevice, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset(), imageSizeBytes);
1716 const tcu::TextureFormat resultFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
1717 const tcu::ConstPixelBufferAccess resultAccess (resultFormat, m_renderSize.x(), m_renderSize.y(), 1, readImageBufferMemory->getHostPtr());
1719 tcu::copy(result.getAccess(), resultAccess);
1723 void ShaderRenderCaseInstance::computeVertexReference (tcu::Surface& result, const QuadGrid& quadGrid)
1726 const int width = result.getWidth();
1727 const int height = result.getHeight();
1728 const int gridSize = quadGrid.getGridSize();
1729 const int stride = gridSize + 1;
1730 const bool hasAlpha = true; // \todo [2015-09-07 elecro] add correct alpha check
1731 ShaderEvalContext evalCtx (quadGrid);
1733 // Evaluate color for each vertex.
1734 std::vector<tcu::Vec4> colors ((gridSize + 1) * (gridSize + 1));
1735 for (int y = 0; y < gridSize+1; y++)
1736 for (int x = 0; x < gridSize+1; x++)
1738 const float sx = (float)x / (float)gridSize;
1739 const float sy = (float)y / (float)gridSize;
1740 const int vtxNdx = ((y * (gridSize+1)) + x);
1742 evalCtx.reset(sx, sy);
1743 m_evaluator.evaluate(evalCtx);
1744 DE_ASSERT(!evalCtx.isDiscarded); // Discard is not available in vertex shader.
1745 tcu::Vec4 color = evalCtx.color;
1750 colors[vtxNdx] = color;
1754 for (int y = 0; y < gridSize; y++)
1755 for (int x = 0; x < gridSize; x++)
1757 const float x0 = (float)x / (float)gridSize;
1758 const float x1 = (float)(x + 1) / (float)gridSize;
1759 const float y0 = (float)y / (float)gridSize;
1760 const float y1 = (float)(y + 1) / (float)gridSize;
1762 const float sx0 = x0 * (float)width;
1763 const float sx1 = x1 * (float)width;
1764 const float sy0 = y0 * (float)height;
1765 const float sy1 = y1 * (float)height;
1766 const float oosx = 1.0f / (sx1 - sx0);
1767 const float oosy = 1.0f / (sy1 - sy0);
1769 const int ix0 = deCeilFloatToInt32(sx0 - 0.5f);
1770 const int ix1 = deCeilFloatToInt32(sx1 - 0.5f);
1771 const int iy0 = deCeilFloatToInt32(sy0 - 0.5f);
1772 const int iy1 = deCeilFloatToInt32(sy1 - 0.5f);
1774 const int v00 = (y * stride) + x;
1775 const int v01 = (y * stride) + x + 1;
1776 const int v10 = ((y + 1) * stride) + x;
1777 const int v11 = ((y + 1) * stride) + x + 1;
1778 const tcu::Vec4 c00 = colors[v00];
1779 const tcu::Vec4 c01 = colors[v01];
1780 const tcu::Vec4 c10 = colors[v10];
1781 const tcu::Vec4 c11 = colors[v11];
1783 //printf("(%d,%d) -> (%f..%f, %f..%f) (%d..%d, %d..%d)\n", x, y, sx0, sx1, sy0, sy1, ix0, ix1, iy0, iy1);
1785 for (int iy = iy0; iy < iy1; iy++)
1786 for (int ix = ix0; ix < ix1; ix++)
1788 DE_ASSERT(deInBounds32(ix, 0, width));
1789 DE_ASSERT(deInBounds32(iy, 0, height));
1791 const float sfx = (float)ix + 0.5f;
1792 const float sfy = (float)iy + 0.5f;
1793 const float fx1 = deFloatClamp((sfx - sx0) * oosx, 0.0f, 1.0f);
1794 const float fy1 = deFloatClamp((sfy - sy0) * oosy, 0.0f, 1.0f);
1796 // Triangle quad interpolation.
1797 const bool tri = fx1 + fy1 <= 1.0f;
1798 const float tx = tri ? fx1 : (1.0f-fx1);
1799 const float ty = tri ? fy1 : (1.0f-fy1);
1800 const tcu::Vec4& t0 = tri ? c00 : c11;
1801 const tcu::Vec4& t1 = tri ? c01 : c10;
1802 const tcu::Vec4& t2 = tri ? c10 : c01;
1803 const tcu::Vec4 color = t0 + (t1-t0)*tx + (t2-t0)*ty;
1805 result.setPixel(ix, iy, tcu::RGBA(color));
1810 void ShaderRenderCaseInstance::computeFragmentReference (tcu::Surface& result, const QuadGrid& quadGrid)
1813 const int width = result.getWidth();
1814 const int height = result.getHeight();
1815 const bool hasAlpha = true; // \todo [2015-09-07 elecro] add correct alpha check
1816 ShaderEvalContext evalCtx (quadGrid);
1819 for (int y = 0; y < height; y++)
1820 for (int x = 0; x < width; x++)
1822 const float sx = ((float)x + 0.5f) / (float)width;
1823 const float sy = ((float)y + 0.5f) / (float)height;
1825 evalCtx.reset(sx, sy);
1826 m_evaluator.evaluate(evalCtx);
1827 // Select either clear color or computed color based on discarded bit.
1828 tcu::Vec4 color = evalCtx.isDiscarded ? m_clearColor : evalCtx.color;
1833 result.setPixel(x, y, tcu::RGBA(color));
1837 bool ShaderRenderCaseInstance::compareImages (const tcu::Surface& resImage, const tcu::Surface& refImage, float errorThreshold)
1839 return tcu::fuzzyCompare(m_context.getTestContext().getLog(), "ComparisonResult", "Image comparison result", refImage, resImage, errorThreshold, tcu::COMPARE_LOG_RESULT);