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 "vktShaderRenderCase.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"
62 namespace shaderrendercase
67 static const int GRID_SIZE = 2;
68 static const int MAX_RENDER_WIDTH = 128;
69 static const int MAX_RENDER_HEIGHT = 112;
70 static const tcu::Vec4 DEFAULT_CLEAR_COLOR = tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f);
72 static bool isSupportedLinearTilingFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format)
74 VkFormatProperties formatProps;
76 VK_CHECK(instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps));
78 return (formatProps.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0u;
81 static bool isSupportedOptimalTilingFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format)
83 VkFormatProperties formatProps;
85 VK_CHECK(instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps));
87 return (formatProps.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0u;
90 static VkImageMemoryBarrier createImageMemoryBarrier (const VkImage& image,
91 VkMemoryOutputFlags outputMask,
92 VkMemoryInputFlags inputMask,
93 VkImageLayout oldLayout,
94 VkImageLayout newLayout)
96 VkImageMemoryBarrier imageMemoryBarrier =
98 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
99 DE_NULL, // const void* pNext;
100 outputMask, // VkMemoryOutputFlags outputMask;
101 inputMask, // VkMemoryInputFlags inputMask;
102 oldLayout, // VkImageLayout oldLayout;
103 newLayout, // VkImageLayout newLayout;
104 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
105 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
106 image, // VkImage image;
108 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
109 0, // deUint32 baseMipLevel;
110 1, // deUint32 mipLevels;
111 0, // deUint32 baseArrayLayer;
112 1 // deUint32 arraySize;
113 } // VkImageSubresourceRange subresourceRange;
115 return imageMemoryBarrier;
123 QuadGrid (int gridSize,
126 const tcu::Vec4& constCoords,
127 const std::vector<tcu::Mat4>& userAttribTransforms,
128 const std::vector<TextureBindingSp>& textures);
131 int getGridSize (void) const { return m_gridSize; }
132 int getNumVertices (void) const { return m_numVertices; }
133 int getNumTriangles (void) const { return m_numTriangles; }
134 const tcu::Vec4& getConstCoords (void) const { return m_constCoords; }
135 const std::vector<tcu::Mat4> getUserAttribTransforms (void) const { return m_userAttribTransforms; }
136 const std::vector<TextureBindingSp>& getTextures (void) const { return m_textures; }
138 const tcu::Vec4* getPositions (void) const { return &m_positions[0]; }
139 const float* getAttribOne (void) const { return &m_attribOne[0]; }
140 const tcu::Vec4* getCoords (void) const { return &m_coords[0]; }
141 const tcu::Vec4* getUnitCoords (void) const { return &m_unitCoords[0]; }
143 const tcu::Vec4* getUserAttrib (int attribNdx) const { return &m_userAttribs[attribNdx][0]; }
144 const deUint16* getIndices (void) const { return &m_indices[0]; }
146 tcu::Vec4 getCoords (float sx, float sy) const;
147 tcu::Vec4 getUnitCoords (float sx, float sy) const;
149 int getNumUserAttribs (void) const { return (int)m_userAttribTransforms.size(); }
150 tcu::Vec4 getUserAttrib (int attribNdx, float sx, float sy) const;
153 const int m_gridSize;
154 const int m_numVertices;
155 const int m_numTriangles;
156 const tcu::Vec4 m_constCoords;
157 const std::vector<tcu::Mat4> m_userAttribTransforms;
159 const std::vector<TextureBindingSp>& m_textures;
161 std::vector<tcu::Vec4> m_screenPos;
162 std::vector<tcu::Vec4> m_positions;
163 std::vector<tcu::Vec4> m_coords; //!< Near-unit coordinates, roughly [-2.0 .. 2.0].
164 std::vector<tcu::Vec4> m_unitCoords; //!< Positive-only coordinates [0.0 .. 1.5].
165 std::vector<float> m_attribOne;
166 std::vector<tcu::Vec4> m_userAttribs[ShaderEvalContext::MAX_TEXTURES];
167 std::vector<deUint16> m_indices;
170 QuadGrid::QuadGrid (int gridSize,
173 const tcu::Vec4& constCoords,
174 const std::vector<tcu::Mat4>& userAttribTransforms,
175 const std::vector<TextureBindingSp>& textures)
176 : m_gridSize (gridSize)
177 , m_numVertices ((gridSize + 1) * (gridSize + 1))
178 , m_numTriangles (gridSize * gridSize * 2)
179 , m_constCoords (constCoords)
180 , m_userAttribTransforms (userAttribTransforms)
181 , m_textures (textures)
183 const tcu::Vec4 viewportScale ((float)width, (float)height, 0.0f, 0.0f);
186 m_screenPos.resize(m_numVertices);
187 m_positions.resize(m_numVertices);
188 m_coords.resize(m_numVertices);
189 m_unitCoords.resize(m_numVertices);
190 m_attribOne.resize(m_numVertices);
193 for (int attrNdx = 0; attrNdx < DE_LENGTH_OF_ARRAY(m_userAttribs); attrNdx++)
194 m_userAttribs[attrNdx].resize(m_numVertices);
196 for (int y = 0; y < gridSize+1; y++)
197 for (int x = 0; x < gridSize+1; x++)
199 float sx = (float)x / (float)gridSize;
200 float sy = (float)y / (float)gridSize;
201 float fx = 2.0f * sx - 1.0f;
202 float fy = 2.0f * sy - 1.0f;
203 int vtxNdx = ((y * (gridSize+1)) + x);
205 m_positions[vtxNdx] = tcu::Vec4(fx, fy, 0.0f, 1.0f);
206 m_coords[vtxNdx] = getCoords(sx, sy);
207 m_unitCoords[vtxNdx] = getUnitCoords(sx, sy);
208 m_attribOne[vtxNdx] = 1.0f;
210 m_screenPos[vtxNdx] = tcu::Vec4(sx, sy, 0.0f, 1.0f) * viewportScale;
212 for (int attribNdx = 0; attribNdx < getNumUserAttribs(); attribNdx++)
213 m_userAttribs[attribNdx][vtxNdx] = getUserAttrib(attribNdx, sx, sy);
217 m_indices.resize(3 * m_numTriangles);
218 for (int y = 0; y < gridSize; y++)
219 for (int x = 0; x < gridSize; x++)
221 int stride = gridSize + 1;
222 int v00 = (y * stride) + x;
223 int v01 = (y * stride) + x + 1;
224 int v10 = ((y+1) * stride) + x;
225 int v11 = ((y+1) * stride) + x + 1;
227 int baseNdx = ((y * gridSize) + x) * 6;
228 m_indices[baseNdx + 0] = (deUint16)v10;
229 m_indices[baseNdx + 1] = (deUint16)v00;
230 m_indices[baseNdx + 2] = (deUint16)v01;
232 m_indices[baseNdx + 3] = (deUint16)v10;
233 m_indices[baseNdx + 4] = (deUint16)v01;
234 m_indices[baseNdx + 5] = (deUint16)v11;
238 QuadGrid::~QuadGrid (void)
242 inline tcu::Vec4 QuadGrid::getCoords (float sx, float sy) const
244 const float fx = 2.0f * sx - 1.0f;
245 const float fy = 2.0f * sy - 1.0f;
246 return tcu::Vec4(fx, fy, -fx + 0.33f*fy, -0.275f*fx - fy);
249 inline tcu::Vec4 QuadGrid::getUnitCoords (float sx, float sy) const
251 return tcu::Vec4(sx, sy, 0.33f*sx + 0.5f*sy, 0.5f*sx + 0.25f*sy);
254 inline tcu::Vec4 QuadGrid::getUserAttrib (int attribNdx, float sx, float sy) const
256 // homogeneous normalized screen-space coordinates
257 return m_userAttribTransforms[attribNdx] * tcu::Vec4(sx, sy, 0.0f, 1.0f);
262 TextureBinding::TextureBinding (const tcu::Archive& archive,
263 const char* filename,
265 const tcu::Sampler& sampler)
267 , m_sampler (sampler)
271 case TYPE_2D: m_binding.tex2D = loadTexture2D(archive, filename).release(); break;
273 TCU_FAIL("Unsupported texture type");
277 TextureBinding::~TextureBinding (void)
281 case TYPE_2D: delete m_binding.tex2D; break;
287 de::MovePtr<tcu::Texture2D> TextureBinding::loadTexture2D (const tcu::Archive& archive, const char* filename)
289 tcu::TextureLevel level;
290 tcu::ImageIO::loadImage(level, archive, filename);
292 TCU_CHECK_INTERNAL(level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) ||
293 level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8));
295 // \todo [2015-10-08 elecro] for some reason we get better when using RGBA texture even in RGB case, this needs to be investigated
296 de::MovePtr<tcu::Texture2D> texture(new tcu::Texture2D(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), level.getWidth(), level.getHeight()));
299 texture->allocLevel(0);
300 tcu::copy(texture->getLevel(0), level.getAccess());
305 // ShaderEvalContext.
307 ShaderEvalContext::ShaderEvalContext (const QuadGrid& quadGrid)
308 : constCoords (quadGrid.getConstCoords())
309 , isDiscarded (false)
310 , m_quadGrid (quadGrid)
312 const std::vector<TextureBindingSp>& bindings = m_quadGrid.getTextures();
313 DE_ASSERT((int)bindings.size() <= MAX_TEXTURES);
315 // Fill in texture array.
316 for (int ndx = 0; ndx < (int)bindings.size(); ndx++)
318 const TextureBinding& binding = *bindings[ndx];
320 if (binding.getType() == TextureBinding::TYPE_NONE)
323 textures[ndx].sampler = binding.getSampler();
325 switch (binding.getType())
327 case TextureBinding::TYPE_2D: textures[ndx].tex2D = &binding.get2D(); break;
328 // \todo [2015-09-07 elecro] Add support for the other binding types
330 case TextureBinding::TYPE_CUBE_MAP: textures[ndx].texCube = binding.getCube(); break;
331 case TextureBinding::TYPE_2D_ARRAY: textures[ndx].tex2DArray = binding.get2DArray(); break;
332 case TextureBinding::TYPE_3D: textures[ndx].tex3D = binding.get3D(); break;
335 TCU_THROW(InternalError, "Handling of texture binding type not implemented");
340 ShaderEvalContext::~ShaderEvalContext (void)
344 void ShaderEvalContext::reset (float sx, float sy)
347 color = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
351 coords = m_quadGrid.getCoords(sx, sy);
352 unitCoords = m_quadGrid.getUnitCoords(sx, sy);
354 // Compute user attributes.
355 const int numAttribs = m_quadGrid.getNumUserAttribs();
356 DE_ASSERT(numAttribs <= MAX_USER_ATTRIBS);
357 for (int attribNdx = 0; attribNdx < numAttribs; attribNdx++)
358 in[attribNdx] = m_quadGrid.getUserAttrib(attribNdx, sx, sy);
361 tcu::Vec4 ShaderEvalContext::texture2D (int unitNdx, const tcu::Vec2& texCoords)
363 if (textures[unitNdx].tex2D)
364 return textures[unitNdx].tex2D->sample(textures[unitNdx].sampler, texCoords.x(), texCoords.y(), 0.0f);
366 return tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
371 ShaderEvaluator::ShaderEvaluator (void)
372 : m_evalFunc(DE_NULL)
376 ShaderEvaluator::ShaderEvaluator (ShaderEvalFunc evalFunc)
377 : m_evalFunc(evalFunc)
381 ShaderEvaluator::~ShaderEvaluator (void)
385 void ShaderEvaluator::evaluate (ShaderEvalContext& ctx) const
387 DE_ASSERT(m_evalFunc);
393 UniformSetup::UniformSetup (void)
394 : m_setupFunc(DE_NULL)
398 UniformSetup::UniformSetup (UniformSetupFunc setupFunc)
399 : m_setupFunc(setupFunc)
403 UniformSetup::~UniformSetup (void)
407 void UniformSetup::setup (ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords) const
410 m_setupFunc(instance, constCoords);
415 ShaderRenderCase::ShaderRenderCase (tcu::TestContext& testCtx,
416 const std::string& name,
417 const std::string& description,
418 const bool isVertexCase,
419 const ShaderEvalFunc evalFunc,
420 const UniformSetup* uniformSetup,
421 const AttributeSetupFunc attribFunc)
422 : vkt::TestCase (testCtx, name, description)
423 , m_isVertexCase (isVertexCase)
424 , m_evaluator (new ShaderEvaluator(evalFunc))
425 , m_uniformSetup (uniformSetup ? uniformSetup : new UniformSetup())
426 , m_attribFunc (attribFunc)
429 ShaderRenderCase::ShaderRenderCase (tcu::TestContext& testCtx,
430 const std::string& name,
431 const std::string& description,
432 const bool isVertexCase,
433 const ShaderEvaluator* evaluator,
434 const UniformSetup* uniformSetup,
435 const AttributeSetupFunc attribFunc)
436 : vkt::TestCase (testCtx, name, description)
437 , m_isVertexCase (isVertexCase)
438 , m_evaluator (evaluator)
439 , m_uniformSetup (uniformSetup ? uniformSetup : new UniformSetup())
440 , m_attribFunc (attribFunc)
443 ShaderRenderCase::~ShaderRenderCase (void)
447 void ShaderRenderCase::initPrograms (vk::SourceCollections& programCollection) const
449 programCollection.glslSources.add("vert") << glu::VertexSource(m_vertShaderSource);
450 programCollection.glslSources.add("frag") << glu::FragmentSource(m_fragShaderSource);
453 TestInstance* ShaderRenderCase::createInstance (Context& context) const
455 DE_ASSERT(m_evaluator != DE_NULL);
456 DE_ASSERT(m_uniformSetup != DE_NULL);
457 return new ShaderRenderCaseInstance(context, m_isVertexCase, *m_evaluator, *m_uniformSetup, m_attribFunc);
460 // ShaderRenderCaseInstance.
462 ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context& context,
463 const bool isVertexCase,
464 const ShaderEvaluator& evaluator,
465 const UniformSetup& uniformSetup,
466 const AttributeSetupFunc attribFunc)
467 : vkt::TestInstance (context)
468 , m_clearColor (DEFAULT_CLEAR_COLOR)
469 , m_memAlloc (context.getDefaultAllocator())
470 , m_isVertexCase (isVertexCase)
471 , m_evaluator (evaluator)
472 , m_uniformSetup (uniformSetup)
473 , m_attribFunc (attribFunc)
474 , m_renderSize (100, 100)
475 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
479 ShaderRenderCaseInstance::~ShaderRenderCaseInstance (void)
483 tcu::TestStatus ShaderRenderCaseInstance::iterate (void)
488 const tcu::IVec2 viewportSize = getViewportSize();
489 const int width = viewportSize.x();
490 const int height = viewportSize.y();
492 QuadGrid quadGrid (m_isVertexCase ? GRID_SIZE : 4, width, height, tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f), m_userAttribTransforms, m_textures);
495 tcu::Surface resImage (width, height);
496 render(resImage, quadGrid);
498 // Compute reference.
499 tcu::Surface refImage (width, height);
501 computeVertexReference(refImage, quadGrid);
503 computeFragmentReference(refImage, quadGrid);
506 const bool compareOk = compareImages(resImage, refImage, 0.05f);
509 return tcu::TestStatus::pass("Result image matches reference");
511 return tcu::TestStatus::fail("Image mismatch");
514 void ShaderRenderCaseInstance::setupUniformData (deUint32 bindingLocation, deUint32 size, const void* dataPtr)
516 const VkDevice vkDevice = m_context.getDevice();
517 const DeviceInterface& vk = m_context.getDeviceInterface();
518 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
520 const VkBufferCreateInfo uniformBufferParams =
522 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
523 DE_NULL, // const void* pNext;
524 size, // VkDeviceSize size;
525 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, // VkBufferUsageFlags usage;
526 0u, // VkBufferCreateFlags flags;
527 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
528 1u, // deUint32 queueFamilyCount;
529 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
532 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &uniformBufferParams);
533 de::MovePtr<Allocation> alloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
534 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
536 deMemcpy(alloc->getHostPtr(), dataPtr, size);
537 flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), size);
539 const VkBufferViewCreateInfo viewInfo =
541 VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, // VkStructureType sType;
542 DE_NULL, // void* pNext;
543 *buffer, // VkBuffer buffer;
544 VK_FORMAT_R32_SFLOAT, // VkFormat format;
545 0u, // VkDeviceSize offset;
546 size, // VkDeviceSize range;
549 Move<VkBufferView> bufferView = createBufferView(vk, vkDevice, &viewInfo);
551 // \todo [2015-10-09 elecro] remove the '_hack_padding' variable if the driver support small uniforms,
552 // that is for example one float big uniforms.
553 const deUint32 _hack_padding = size < 4 * sizeof(float) ? (deUint32)(3u * sizeof(float)) : 0u;
555 const VkDescriptorInfo descriptor =
557 bufferView.get(), // VkBufferView bufferView;
558 0, // VkSampler sampler;
559 0, // VkImageView imageView;
560 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
562 *buffer, // VkBuffer buffer;
563 0u, // VkDeviceSize offset;
564 size + _hack_padding, // VkDeviceSize range;
565 }, // VkDescriptorBufferInfo bufferInfo;
568 de::MovePtr<BufferUniform> uniformInfo(new BufferUniform());
569 uniformInfo->type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
570 uniformInfo->descriptor = descriptor;
571 uniformInfo->location = bindingLocation;
572 uniformInfo->buffer = VkBufferSp(new vk::Unique<VkBuffer>(buffer));
573 uniformInfo->bufferView = VkBufferViewSp(new vk::Unique<VkBufferView>(bufferView));
574 uniformInfo->alloc = AllocationSp(alloc.release());
576 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniformInfo)));
579 void ShaderRenderCaseInstance::addUniform (deUint32 bindingLocation, vk::VkDescriptorType descriptorType, deUint32 dataSize, const void* data)
581 m_descriptorSetLayoutBuilder.addSingleBinding(descriptorType, vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT);
582 m_descriptorPoolBuilder.addType(descriptorType);
584 setupUniformData(bindingLocation, dataSize, data);
587 void ShaderRenderCaseInstance::addAttribute (deUint32 bindingLocation,
589 deUint32 sizePerElement,
593 // Add binding specification
594 const deUint32 binding = (deUint32)m_vertexBindingDescription.size();
595 const VkVertexInputBindingDescription bindingDescription =
597 binding, // deUint32 binding;
598 sizePerElement, // deUint32 strideInBytes;
599 VK_VERTEX_INPUT_STEP_RATE_VERTEX // VkVertexInputStepRate stepRate;
602 m_vertexBindingDescription.push_back(bindingDescription);
604 // Add location and format specification
605 const VkVertexInputAttributeDescription attributeDescription =
607 bindingLocation, // deUint32 location;
608 binding, // deUint32 binding;
609 format, // VkFormat format;
610 0u, // deUint32 offsetInBytes;
613 m_vertexattributeDescription.push_back(attributeDescription);
615 // Upload data to buffer
616 const VkDevice vkDevice = m_context.getDevice();
617 const DeviceInterface& vk = m_context.getDeviceInterface();
618 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
620 const VkDeviceSize inputSize = sizePerElement * count;
621 const VkBufferCreateInfo vertexBufferParams =
623 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
624 DE_NULL, // const void* pNext;
625 inputSize, // VkDeviceSize size;
626 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
627 0u, // VkBufferCreateFlags flags;
628 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
629 1u, // deUint32 queueFamilyCount;
630 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
633 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &vertexBufferParams);
634 de::MovePtr<vk::Allocation> alloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
635 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
637 deMemcpy(alloc->getHostPtr(), dataPtr, inputSize);
638 flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), inputSize);
640 m_vertexBuffers.push_back(VkBufferSp(new vk::Unique<VkBuffer>(buffer)));
641 m_vertexBufferAllocs.push_back(AllocationSp(alloc.release()));
644 void ShaderRenderCaseInstance::useAttribute (deUint32 bindingLocation, BaseAttributeType type)
646 const EnabledBaseAttribute attribute =
648 bindingLocation, // deUint32 location;
649 type // BaseAttributeType type;
651 m_enabledBaseAttributes.push_back(attribute);
654 void ShaderRenderCaseInstance::setup (void)
658 void ShaderRenderCaseInstance::setupUniforms (const tcu::Vec4& constCoords)
660 m_uniformSetup.setup(*this, constCoords);
663 void ShaderRenderCaseInstance::useUniform (deUint32 bindingLocation, BaseUniformType type)
665 #define UNIFORM_CASE(type, value) case type: addUniform(bindingLocation, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, value); break
670 UNIFORM_CASE(UB_FALSE, 0);
671 UNIFORM_CASE(UB_TRUE, 1);
674 UNIFORM_CASE(UB4_FALSE, tcu::Vec4(0));
675 UNIFORM_CASE(UB4_TRUE, tcu::Vec4(1));
678 UNIFORM_CASE(UI_ZERO, 0);
679 UNIFORM_CASE(UI_ONE, 1);
680 UNIFORM_CASE(UI_TWO, 2);
681 UNIFORM_CASE(UI_THREE, 3);
682 UNIFORM_CASE(UI_FOUR, 4);
683 UNIFORM_CASE(UI_FIVE, 5);
684 UNIFORM_CASE(UI_SIX, 6);
685 UNIFORM_CASE(UI_SEVEN, 7);
686 UNIFORM_CASE(UI_EIGHT, 8);
687 UNIFORM_CASE(UI_ONEHUNDREDONE, 101);
690 UNIFORM_CASE(UI2_MINUS_ONE, tcu::IVec2(-1));
691 UNIFORM_CASE(UI2_ZERO, tcu::IVec2(0));
692 UNIFORM_CASE(UI2_ONE, tcu::IVec2(1));
693 UNIFORM_CASE(UI2_TWO, tcu::IVec2(2));
694 UNIFORM_CASE(UI2_THREE, tcu::IVec2(3));
695 UNIFORM_CASE(UI2_FOUR, tcu::IVec2(4));
696 UNIFORM_CASE(UI2_FIVE, tcu::IVec2(5));
699 UNIFORM_CASE(UI3_MINUS_ONE, tcu::IVec3(-1));
700 UNIFORM_CASE(UI3_ZERO, tcu::IVec3(0));
701 UNIFORM_CASE(UI3_ONE, tcu::IVec3(1));
702 UNIFORM_CASE(UI3_TWO, tcu::IVec3(2));
703 UNIFORM_CASE(UI3_THREE, tcu::IVec3(3));
704 UNIFORM_CASE(UI3_FOUR, tcu::IVec3(4));
705 UNIFORM_CASE(UI3_FIVE, tcu::IVec3(5));
708 UNIFORM_CASE(UI4_MINUS_ONE, tcu::IVec4(-1));
709 UNIFORM_CASE(UI4_ZERO, tcu::IVec4(0));
710 UNIFORM_CASE(UI4_ONE, tcu::IVec4(1));
711 UNIFORM_CASE(UI4_TWO, tcu::IVec4(2));
712 UNIFORM_CASE(UI4_THREE, tcu::IVec4(3));
713 UNIFORM_CASE(UI4_FOUR, tcu::IVec4(4));
714 UNIFORM_CASE(UI4_FIVE, tcu::IVec4(5));
717 UNIFORM_CASE(UF_ZERO, 0.0f);
718 UNIFORM_CASE(UF_ONE, 1.0f);
719 UNIFORM_CASE(UF_TWO, 2.0f);
720 UNIFORM_CASE(UF_THREE, 3.0f);
721 UNIFORM_CASE(UF_FOUR, 4.0f);
722 UNIFORM_CASE(UF_FIVE, 5.0f);
723 UNIFORM_CASE(UF_SIX, 6.0f);
724 UNIFORM_CASE(UF_SEVEN, 7.0f);
725 UNIFORM_CASE(UF_EIGHT, 8.0f);
727 UNIFORM_CASE(UF_HALF, 1.0f / 2.0f);
728 UNIFORM_CASE(UF_THIRD, 1.0f / 3.0f);
729 UNIFORM_CASE(UF_FOURTH, 1.0f / 4.0f);
730 UNIFORM_CASE(UF_FIFTH, 1.0f / 5.0f);
731 UNIFORM_CASE(UF_SIXTH, 1.0f / 6.0f);
732 UNIFORM_CASE(UF_SEVENTH, 1.0f / 7.0f);
733 UNIFORM_CASE(UF_EIGHTH, 1.0f / 8.0f);
736 UNIFORM_CASE(UV2_MINUS_ONE, tcu::Vec2(-1.0f));
737 UNIFORM_CASE(UV2_ZERO, tcu::Vec2(0.0f));
738 UNIFORM_CASE(UV2_ONE, tcu::Vec2(1.0f));
739 UNIFORM_CASE(UV2_TWO, tcu::Vec2(2.0f));
740 UNIFORM_CASE(UV2_THREE, tcu::Vec2(3.0f));
742 UNIFORM_CASE(UV2_HALF, tcu::Vec2(1.0f / 2.0f));
745 UNIFORM_CASE(UV3_MINUS_ONE, tcu::Vec3(-1.0f));
746 UNIFORM_CASE(UV3_ZERO, tcu::Vec3(0.0f));
747 UNIFORM_CASE(UV3_ONE, tcu::Vec3(1.0f));
748 UNIFORM_CASE(UV3_TWO, tcu::Vec3(2.0f));
749 UNIFORM_CASE(UV3_THREE, tcu::Vec3(3.0f));
751 UNIFORM_CASE(UV3_HALF, tcu::Vec3(1.0f / 2.0f));
754 UNIFORM_CASE(UV4_MINUS_ONE, tcu::Vec4(-1.0f));
755 UNIFORM_CASE(UV4_ZERO, tcu::Vec4(0.0f));
756 UNIFORM_CASE(UV4_ONE, tcu::Vec4(1.0f));
757 UNIFORM_CASE(UV4_TWO, tcu::Vec4(2.0f));
758 UNIFORM_CASE(UV4_THREE, tcu::Vec4(3.0f));
760 UNIFORM_CASE(UV4_HALF, tcu::Vec4(1.0f / 2.0f));
762 UNIFORM_CASE(UV4_BLACK, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
763 UNIFORM_CASE(UV4_GRAY, tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f));
764 UNIFORM_CASE(UV4_WHITE, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
767 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Unknown Uniform type: " << type << tcu::TestLog::EndMessage;
774 const tcu::IVec2 ShaderRenderCaseInstance::getViewportSize (void) const
776 return tcu::IVec2(de::min(m_renderSize.x(), MAX_RENDER_WIDTH),
777 de::min(m_renderSize.y(), MAX_RENDER_HEIGHT));
780 Move<VkImage> ShaderRenderCaseInstance::createImage2D (const tcu::Texture2D& texture,
781 const VkFormat format,
782 const VkImageUsageFlags usage,
783 const VkImageTiling tiling)
785 const VkDevice vkDevice = m_context.getDevice();
786 const DeviceInterface& vk = m_context.getDeviceInterface();
787 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
789 const VkImageCreateInfo imageCreateInfo =
791 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
792 DE_NULL, // const void* pnext;
793 VK_IMAGE_TYPE_2D, // VkImageType imageType;
794 format, // VkFormat format;
795 { texture.getWidth(), texture.getHeight(), 1 }, // VkExtend3D extent;
796 1u, // deUint32 mipLevels;
797 1u, // deUint32 arraySize;
798 1u, // deUint32 samples;
799 tiling, // VkImageTiling tiling;
800 usage, // VkImageUsageFlags usage;
801 0, // VkImageCreateFlags flags;
802 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
803 1, // deuint32 queueFamilyCount;
804 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
805 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
808 Move<VkImage> vkTexture = createImage(vk, vkDevice, &imageCreateInfo);
812 de::MovePtr<Allocation> ShaderRenderCaseInstance::uploadImage2D (const tcu::Texture2D& refTexture,
813 const VkImage& vkTexture)
815 const VkDevice vkDevice = m_context.getDevice();
816 const DeviceInterface& vk = m_context.getDeviceInterface();
818 de::MovePtr<Allocation> allocation = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, vkTexture), MemoryRequirement::HostVisible);
819 VK_CHECK(vk.bindImageMemory(vkDevice, vkTexture, allocation->getMemory(), allocation->getOffset()));
821 const VkImageSubresource subres =
823 VK_IMAGE_ASPECT_COLOR, // VkImageAspect aspect;
824 0u, // deUint32 mipLevel;
825 0u // deUint32 arraySlice
828 VkSubresourceLayout layout;
829 VK_CHECK(vk.getImageSubresourceLayout(vkDevice, vkTexture, &subres, &layout));
831 tcu::ConstPixelBufferAccess access = refTexture.getLevel(0);
832 tcu::PixelBufferAccess destAccess (refTexture.getFormat(), refTexture.getWidth(), refTexture.getHeight(), 1, allocation->getHostPtr());
834 tcu::copy(destAccess, access);
836 flushMappedMemoryRange(vk, vkDevice, allocation->getMemory(), allocation, layout.size);
841 void ShaderRenderCaseInstance::copyTilingImageToOptimal (const vk::VkImage& srcImage,
842 const vk::VkImage& dstImage,
846 const VkDevice vkDevice = m_context.getDevice();
847 const DeviceInterface& vk = m_context.getDeviceInterface();
848 const VkQueue queue = m_context.getUniversalQueue();
849 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
851 // Create command pool
852 const VkCmdPoolCreateInfo cmdPoolParams =
854 VK_STRUCTURE_TYPE_CMD_POOL_CREATE_INFO, // VkStructureType sType;
855 DE_NULL, // const void* pNext;
856 queueFamilyIndex, // deUint32 queueFamilyIndex;
857 VK_CMD_POOL_CREATE_TRANSIENT_BIT // VkCmdPoolCreateFlags flags;
860 Move<VkCmdPool> cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
862 // Create command buffer
863 const VkCmdBufferCreateInfo cmdBufferParams =
865 VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, // VkStructureType sType;
866 DE_NULL, // const void* pNext;
867 *cmdPool, // VkCmdPool cmdPool;
868 VK_CMD_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
869 0u // VkCmdBufferCreateFlags flags;
872 const VkCmdBufferOptimizeFlags optimizeFlags = VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT | VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT;
873 const VkCmdBufferBeginInfo cmdBufferBeginInfo =
875 VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, // VkStructureType sType;
876 DE_NULL, // const void* pNext;
877 optimizeFlags, // VkCmdBufferOptimizeFlags flags;
878 DE_NULL, // VkRenderPass renderPass;
879 0u, // deUint32 subpass;
880 DE_NULL // VkFramebuffer framebuffer;
883 Move<VkCmdBuffer> cmdBuffer = createCommandBuffer(vk, vkDevice, &cmdBufferParams);
885 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
887 // Add image barriers
888 const VkImageMemoryBarrier layoutBarriers[2] =
890 createImageMemoryBarrier(srcImage, 0u, 0u, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL),
891 createImageMemoryBarrier(dstImage, 0u, VK_MEMORY_INPUT_TRANSFER_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL)
894 for (deUint32 barrierNdx = 0; barrierNdx < DE_LENGTH_OF_ARRAY(layoutBarriers); barrierNdx++)
896 const VkImageMemoryBarrier* memoryBarrier = &layoutBarriers[barrierNdx];
897 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, (const void * const*)&memoryBarrier);
901 const VkImageCopy imageCopy =
904 VK_IMAGE_ASPECT_COLOR, // VkImageAspect aspect;
905 0u, // deUint32 mipLevel;
906 0u, // deUint32 arrayLayer;
907 1u // deUint32 arraySize;
908 }, // VkImageSubresourceCopy srcSubresource;
913 }, // VkOffset3D srcOffset;
915 VK_IMAGE_ASPECT_COLOR, // VkImageAspect aspect;
916 0u, // deUint32 mipLevel;
917 0u, // deUint32 arrayLayer;
918 1u // deUint32 arraySize;
919 }, // VkImageSubresourceCopy destSubResource;
924 }, // VkOffset3D dstOffset;
926 width, // int32 width;
927 height, // int32 height;
929 } // VkExtent3D extent;
932 vk.cmdCopyImage(*cmdBuffer, srcImage, VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL, dstImage, VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, 1, &imageCopy);
934 // Add destination barrier
935 const VkImageMemoryBarrier dstBarrier =
936 createImageMemoryBarrier(dstImage, VK_MEMORY_OUTPUT_HOST_WRITE_BIT | VK_MEMORY_OUTPUT_TRANSFER_BIT, 0u, VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
938 const void* const* barrier = (const void* const*)&dstBarrier;
939 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, (const void* const*)&barrier);
941 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
943 const VkFenceCreateInfo fenceParams =
945 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
946 DE_NULL, // const void* pNext;
947 0u // VkFenceCreateFlags flags;
949 Move<VkFence> fence = createFence(vk, vkDevice, &fenceParams);
952 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
953 VK_CHECK(vk.queueSubmit(queue, 1, &cmdBuffer.get(), *fence));
954 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/));
957 void ShaderRenderCaseInstance::useSampler2D (deUint32 bindingLocation, deUint32 textureID)
959 DE_ASSERT(textureID < m_textures.size());
961 const VkDevice vkDevice = m_context.getDevice();
962 const DeviceInterface& vk = m_context.getDeviceInterface();
963 const TextureBinding& textureBinding = *m_textures[textureID];
964 const tcu::Texture2D& refTexture = textureBinding.get2D();
965 const tcu::Sampler& refSampler = textureBinding.getSampler();
966 const VkFormat format = refTexture.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
967 ? VK_FORMAT_R8G8B8A8_UNORM
968 : VK_FORMAT_R8G8B8_UNORM;
970 // Create & alloc the image
971 Move<VkImage> vkTexture;
972 de::MovePtr<Allocation> allocation;
974 if (isSupportedLinearTilingFormat(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), format))
976 vkTexture = createImage2D(refTexture, format, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_LINEAR);
977 allocation = uploadImage2D(refTexture, *vkTexture);
979 else if (isSupportedOptimalTilingFormat(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), format))
981 Move<VkImage> stagingTexture (createImage2D(refTexture, format, VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT, VK_IMAGE_TILING_LINEAR));
982 de::MovePtr<Allocation> stagingAlloc (uploadImage2D(refTexture, *stagingTexture));
984 const VkImageUsageFlags dstUsageFlags = VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
985 vkTexture = createImage2D(refTexture, format, dstUsageFlags, VK_IMAGE_TILING_OPTIMAL);
986 allocation = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *vkTexture), MemoryRequirement::Any);
987 VK_CHECK(vk.bindImageMemory(vkDevice, *vkTexture, allocation->getMemory(), allocation->getOffset()));
989 copyTilingImageToOptimal(*stagingTexture, *vkTexture, refTexture.getWidth(), refTexture.getHeight());
993 TCU_THROW(InternalError, "Unable to create 2D image");
997 const bool compareEnabled = (refSampler.compare != tcu::Sampler::COMPAREMODE_NONE);
998 const VkSamplerCreateInfo samplerParams =
1000 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
1001 DE_NULL, // const void* pNext;
1002 mapFilterMode(refSampler.magFilter), // VkTexFilter magFilter;
1003 mapFilterMode(refSampler.minFilter), // VkTexFilter minFilter;
1004 mapMipmapMode(refSampler.minFilter), // VkTexMipmapMode mipMode;
1005 mapWrapMode(refSampler.wrapS), // VkTexAddressMode addressModeU;
1006 mapWrapMode(refSampler.wrapT), // VkTexAddressMode addressModeV;
1007 mapWrapMode(refSampler.wrapR), // VkTexAddressMode addressModeW;
1008 refSampler.lodThreshold, // float mipLodBias;
1009 1, // float maxAnisotropy;
1010 compareEnabled, // VkBool32 compareEnable;
1011 mapCompareMode(refSampler.compare), // VkCompareOp compareOp;
1012 0.0f, // float minLod;
1013 0.0f, // float maxLod;
1014 VK_BORDER_COLOR_INT_OPAQUE_WHITE, // VkBorderColor boderColor;
1015 VK_FALSE, // VkBool32 unnormalizerdCoordinates;
1018 Move<VkSampler> sampler = createSampler(vk, vkDevice, &samplerParams);
1020 const VkImageViewCreateInfo viewParams =
1022 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1023 NULL, // const voide* pNexŧ;
1024 *vkTexture, // VkImage image;
1025 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
1026 format, // VkFormat format;
1028 VK_CHANNEL_SWIZZLE_R, // VkChannelSwizzle r;
1029 VK_CHANNEL_SWIZZLE_G, // VkChannelSwizzle g;
1030 VK_CHANNEL_SWIZZLE_B, // VkChannelSwizzle b;
1031 VK_CHANNEL_SWIZZLE_A // VkChannelSwizzle a;
1032 }, // VkChannelMapping channels;
1034 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1035 0, // deUint32 baseMipLevel;
1036 1, // deUint32 mipLevels;
1037 0, // deUint32 baseArraySlice;
1038 1 // deUint32 arraySize;
1039 }, // VkImageSubresourceRange subresourceRange;
1040 0u // VkImageViewCreateFlags flags;
1043 Move<VkImageView> imageView = createImageView(vk, vkDevice, &viewParams);
1045 const vk::VkDescriptorInfo descriptor =
1047 0, // VkBufferView bufferView;
1048 sampler.get(), // VkSampler sampler;
1049 imageView.get(), // VkImageView imageView;
1050 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
1051 {0, 0, 0}, // VkDescriptorBufferInfo bufferInfo;
1054 de::MovePtr<SamplerUniform> uniform(new SamplerUniform());
1055 uniform->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
1056 uniform->descriptor = descriptor;
1057 uniform->location = bindingLocation;
1058 uniform->image = VkImageSp(new vk::Unique<VkImage>(vkTexture));
1059 uniform->imageView = VkImageViewSp(new vk::Unique<VkImageView>(imageView));
1060 uniform->sampler = VkSamplerSp(new vk::Unique<VkSampler>(sampler));
1061 uniform->alloc = AllocationSp(allocation.release());
1063 m_descriptorSetLayoutBuilder.addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, vk::VK_SHADER_STAGE_FRAGMENT_BIT, &uniform->descriptor.sampler);
1064 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
1066 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniform)));
1069 void ShaderRenderCaseInstance::setupDefaultInputs (const QuadGrid& quadGrid)
1071 /* Configuration of the vertex input attributes:
1072 a_position is at location 0
1073 a_coords is at location 1
1074 a_unitCoords is at location 2
1075 a_one is at location 3
1077 User attributes starts from at the location 4.
1079 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getPositions());
1080 addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getCoords());
1081 addAttribute(2u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUnitCoords());
1082 addAttribute(3u, VK_FORMAT_R32_SFLOAT, sizeof(float), quadGrid.getNumVertices(), quadGrid.getAttribOne());
1086 BaseAttributeType type;
1088 } userAttributes[] =
1098 BaseAttributeType matrixType;
1114 for (size_t attrNdx = 0; attrNdx < m_enabledBaseAttributes.size(); attrNdx++)
1116 for (int userNdx = 0; userNdx < DE_LENGTH_OF_ARRAY(userAttributes); userNdx++)
1118 if (userAttributes[userNdx].type != m_enabledBaseAttributes[attrNdx].type)
1121 addAttribute(m_enabledBaseAttributes[attrNdx].location, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUserAttrib(userNdx));
1124 for (int matNdx = 0; matNdx < DE_LENGTH_OF_ARRAY(matrices); matNdx++)
1127 if (matrices[matNdx].matrixType != m_enabledBaseAttributes[attrNdx].type)
1130 const int numCols = matrices[matNdx].numCols;
1132 for (int colNdx = 0; colNdx < numCols; colNdx++)
1134 addAttribute(m_enabledBaseAttributes[attrNdx].location + colNdx, VK_FORMAT_R32G32B32A32_SFLOAT, 4 * sizeof(float), quadGrid.getNumVertices(), quadGrid.getUserAttrib(colNdx));
1140 void ShaderRenderCaseInstance::render (tcu::Surface& result, const QuadGrid& quadGrid)
1142 const VkDevice vkDevice = m_context.getDevice();
1143 const DeviceInterface& vk = m_context.getDeviceInterface();
1144 const VkQueue queue = m_context.getUniversalQueue();
1145 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1147 // Create color image
1149 const VkImageCreateInfo colorImageParams =
1151 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1152 DE_NULL, // const void* pNext;
1153 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1154 m_colorFormat, // VkFormat format;
1155 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent;
1156 1u, // deUint32 mipLevels;
1157 1u, // deUint32 arraySize;
1158 1u, // deUint32 samples;
1159 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1160 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT, // VkImageUsageFlags usage;
1161 0u, // VkImageCreateFlags flags;
1162 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1163 1u, // deUint32 queueFamilyCount;
1164 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1165 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1168 m_colorImage = createImage(vk, vkDevice, &colorImageParams);
1170 // Allocate and bind color image memory
1171 m_colorImageAlloc = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
1172 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
1175 // Create color attachment view
1177 const VkImageViewCreateInfo colorImageViewParams =
1179 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1180 DE_NULL, // const void* pNext;
1181 *m_colorImage, // VkImage image;
1182 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
1183 m_colorFormat, // VkFormat format;
1185 VK_CHANNEL_SWIZZLE_R, // VkChannelSwizzle r;
1186 VK_CHANNEL_SWIZZLE_G, // VkChannelSwizzle g;
1187 VK_CHANNEL_SWIZZLE_B, // VkChannelSwizzle b;
1188 VK_CHANNEL_SWIZZLE_A // VkChannelSwizzle a;
1189 }, // VkChannelMapping channels;
1191 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1192 0, // deUint32 baseMipLevel;
1193 1, // deUint32 mipLevels;
1194 0, // deUint32 baseArraySlice;
1195 1 // deUint32 arraySize;
1196 }, // VkImageSubresourceRange subresourceRange;
1197 0u // VkImageViewCreateFlags flags;
1200 m_colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
1203 // Create render pass
1205 const VkAttachmentDescription attachmentDescription =
1207 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION, // VkStructureType sType;
1208 DE_NULL, // const void* pNext;
1209 m_colorFormat, // VkFormat format;
1210 1u, // deUint32 samples;
1211 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
1212 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
1213 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
1214 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
1215 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
1216 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
1217 0u, // VkAttachmentDescriptorFlags flags;
1220 const VkAttachmentReference attachmentReference =
1222 0u, // deUint32 attachment;
1223 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
1226 const VkSubpassDescription subpassDescription =
1228 VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION, // VkStructureType sType;
1229 DE_NULL, // constvoid* pNext;
1230 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
1231 0u, // VkSubpassDescriptionFlags flags;
1232 0u, // deUint32 inputCount;
1233 DE_NULL, // constVkAttachmentReference* pInputAttachments;
1234 1u, // deUint32 colorCount;
1235 &attachmentReference, // constVkAttachmentReference* pColorAttachments;
1236 DE_NULL, // constVkAttachmentReference* pResolveAttachments;
1237 { ~0u, VK_IMAGE_LAYOUT_GENERAL }, // VkAttachmentReference depthStencilAttachment;
1238 0u, // deUint32 preserveCount;
1239 DE_NULL // constVkAttachmentReference* pPreserveAttachments;
1242 const VkRenderPassCreateInfo renderPassParams =
1244 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
1245 DE_NULL, // const void* pNext;
1246 1u, // deUint32 attachmentCount;
1247 &attachmentDescription, // const VkAttachmentDescription* pAttachments;
1248 1u, // deUint32 subpassCount;
1249 &subpassDescription, // const VkSubpassDescription* pSubpasses;
1250 0u, // deUint32 dependencyCount;
1251 DE_NULL // const VkSubpassDependency* pDependencies;
1254 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
1257 // Create framebuffer
1259 const VkFramebufferCreateInfo framebufferParams =
1261 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
1262 DE_NULL, // const void* pNext;
1263 *m_renderPass, // VkRenderPass renderPass;
1264 1u, // deUint32 attachmentCount;
1265 &*m_colorImageView, // const VkImageView* pAttachments;
1266 (deUint32)m_renderSize.x(), // deUint32 width;
1267 (deUint32)m_renderSize.y(), // deUint32 height;
1268 1u // deUint32 layers;
1271 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
1274 // Create descriptors
1276 setupUniforms(quadGrid.getConstCoords());
1278 m_descriptorSetLayout = m_descriptorSetLayoutBuilder.build(vk, vkDevice);
1279 m_descriptorPool = m_descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1u);
1280 m_descriptorSet = allocDescriptorSet(vk, vkDevice, *m_descriptorPool, VK_DESCRIPTOR_SET_USAGE_STATIC, *m_descriptorSetLayout);
1282 for(deUint32 i = 0; i < m_uniformInfos.size(); i++)
1284 const UniformInfo* uniformInfo = m_uniformInfos[i].get()->get();
1285 deUint32 location = uniformInfo->location;
1286 m_descriptorSetUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &uniformInfo->descriptor);
1289 m_descriptorSetUpdateBuilder.update(vk, vkDevice);
1292 // Create pipeline layout
1294 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1296 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1297 DE_NULL, // const void* pNext;
1298 1u, // deUint32 descriptorSetCount;
1299 &*m_descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
1300 0u, // deUint32 pushConstantRangeCount;
1301 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
1304 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1309 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
1310 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
1312 const VkShaderCreateInfo vertexShaderParams =
1314 VK_STRUCTURE_TYPE_SHADER_CREATE_INFO, // VkStructureType sType;
1315 DE_NULL, // const void* pNext;
1316 *m_vertexShaderModule, // VkShaderModule module;
1317 "main", // const char* pName;
1318 0u, // VkShaderCreateFlags flags;
1319 VK_SHADER_STAGE_VERTEX, // VkShaderStage stage;
1322 const VkShaderCreateInfo fragmentShaderParams =
1324 VK_STRUCTURE_TYPE_SHADER_CREATE_INFO, // VkStructureType sType;
1325 DE_NULL, // const void* pNext;
1326 *m_fragmentShaderModule, // VkShaderModule module;
1327 "main", // const char* pName;
1328 0u, // VkShaderCreateFlags flags;
1329 VK_SHADER_STAGE_FRAGMENT, // VkShaderStage stage;
1332 m_vertexShader = createShader(vk, vkDevice, &vertexShaderParams);
1333 m_fragmentShader= createShader(vk, vkDevice, &fragmentShaderParams);
1338 const VkPipelineShaderStageCreateInfo shaderStageParams[2] =
1341 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1342 DE_NULL, // const void* pNext;
1343 VK_SHADER_STAGE_VERTEX, // VkShaderStage stage;
1344 *m_vertexShader, // VkShader shader;
1345 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1348 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1349 DE_NULL, // const void* pNext;
1350 VK_SHADER_STAGE_FRAGMENT, // VkShaderStage stage;
1351 *m_fragmentShader, // VkShader shader;
1352 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1356 // Add test case specific attributes
1358 m_attribFunc(*this, quadGrid.getNumVertices());
1360 // Add base attributes
1361 setupDefaultInputs(quadGrid);
1363 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
1365 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1366 DE_NULL, // const void* pNext;
1367 (deUint32)m_vertexBindingDescription.size(), // deUint32 bindingCount;
1368 &m_vertexBindingDescription[0], // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1369 (deUint32)m_vertexattributeDescription.size(), // deUint32 attributeCount;
1370 &m_vertexattributeDescription[0], // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1373 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
1375 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
1376 DE_NULL, // const void* pNext;
1377 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology;
1378 false // VkBool32 primitiveRestartEnable;
1381 const VkViewport viewport =
1383 0.0f, // float originX;
1384 0.0f, // float originY;
1385 (float)m_renderSize.x(), // float width;
1386 (float)m_renderSize.y(), // float height;
1387 0.0f, // float minDepth;
1388 1.0f // float maxDepth;
1391 const VkRect2D scissor =
1396 }, // VkOffset2D offset;
1398 m_renderSize.x(), // deUint32 width;
1399 m_renderSize.y(), // deUint32 height;
1400 }, // VkExtent2D extent;
1403 const VkPipelineViewportStateCreateInfo viewportStateParams =
1405 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
1406 DE_NULL, // const void* pNext;
1407 1u, // deUint32 viewportCount;
1408 &viewport, // const VkViewport* pViewports;
1409 1u, // deUint32 scissorsCount;
1410 &scissor, // const VkRect2D* pScissors;
1413 const VkPipelineRasterStateCreateInfo rasterStateParams =
1415 VK_STRUCTURE_TYPE_PIPELINE_RASTER_STATE_CREATE_INFO, // VkStructureType sType;
1416 DE_NULL, // const void* pNext;
1417 false, // VkBool32 depthClipEnable;
1418 false, // VkBool32 rasterizerDiscardEnable;
1419 VK_FILL_MODE_SOLID, // VkFillMode fillMode;
1420 VK_CULL_MODE_NONE, // VkCullMode cullMode;
1421 VK_FRONT_FACE_CCW, // 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 VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
1431 false, // VkBool32 blendEnable;
1432 VK_BLEND_ONE, // VkBlend srcBlendColor;
1433 VK_BLEND_ZERO, // VkBlend destBlendColor;
1434 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
1435 VK_BLEND_ONE, // VkBlend srcBlendAlpha;
1436 VK_BLEND_ZERO, // VkBlend destBlendAlpha;
1437 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
1438 VK_CHANNEL_R_BIT | VK_CHANNEL_G_BIT | VK_CHANNEL_B_BIT | VK_CHANNEL_A_BIT // VkChannelFlags channelWriteMask;
1441 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
1443 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1444 DE_NULL, // const void* pNext;
1445 false, // VkBool32 alphaToCoverageEnable;
1446 false, // VkBool32 alphaToOneEnable;
1447 false, // VkBool32 logicOpEnable;
1448 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
1449 1u, // deUint32 attachmentCount;
1450 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
1451 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4];
1454 const VkPipelineDynamicStateCreateInfo dynamicStateInfo =
1456 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
1457 DE_NULL, // const void* pNext;
1458 0u, // deUint32 dynamicStateCount;
1459 DE_NULL // const VkDynamicState* pDynamicStates;
1462 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
1464 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
1465 DE_NULL, // const void* pNext;
1466 2u, // deUint32 stageCount;
1467 shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages;
1468 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
1469 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
1470 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
1471 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
1472 &rasterStateParams, // const VkPipelineRasterStateCreateInfo* pRasterState;
1473 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
1474 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
1475 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
1476 &dynamicStateInfo, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
1477 0u, // VkPipelineCreateFlags flags;
1478 *m_pipelineLayout, // VkPipelineLayout layout;
1479 *m_renderPass, // VkRenderPass renderPass;
1480 0u, // deUint32 subpass;
1481 0u, // VkPipeline basePipelineHandle;
1482 0u // deInt32 basePipelineIndex;
1485 m_graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
1488 // Create vertex indices buffer
1490 const VkDeviceSize indiceBufferSize = quadGrid.getNumTriangles() * 3 * sizeof(deUint16);
1491 const VkBufferCreateInfo indiceBufferParams =
1493 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1494 DE_NULL, // const void* pNext;
1495 indiceBufferSize, // VkDeviceSize size;
1496 VK_BUFFER_USAGE_INDEX_BUFFER_BIT, // VkBufferUsageFlags usage;
1497 0u, // VkBufferCreateFlags flags;
1498 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1499 1u, // deUint32 queueFamilyCount;
1500 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1503 m_indiceBuffer = createBuffer(vk, vkDevice, &indiceBufferParams);
1504 m_indiceBufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_indiceBuffer), MemoryRequirement::HostVisible);
1506 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_indiceBuffer, m_indiceBufferAlloc->getMemory(), m_indiceBufferAlloc->getOffset()));
1508 // Load vertice indices into buffer
1509 deMemcpy(m_indiceBufferAlloc->getHostPtr(), quadGrid.getIndices(), indiceBufferSize);
1510 flushMappedMemoryRange(vk, vkDevice, m_indiceBufferAlloc->getMemory(), m_indiceBufferAlloc->getOffset(), indiceBufferSize);
1513 // Create command pool
1515 const VkCmdPoolCreateInfo cmdPoolParams =
1517 VK_STRUCTURE_TYPE_CMD_POOL_CREATE_INFO, // VkStructureType sType;
1518 DE_NULL, // const void* pNext;
1519 queueFamilyIndex, // deUint32 queueFamilyIndex;
1520 VK_CMD_POOL_CREATE_TRANSIENT_BIT // VkCmdPoolCreateFlags flags;
1523 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1526 // Create command buffer
1528 const VkCmdBufferCreateInfo cmdBufferParams =
1530 VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, // VkStructureType sType;
1531 DE_NULL, // const void* pNext;
1532 *m_cmdPool, // VkCmdPool cmdPool;
1533 VK_CMD_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
1534 0u // VkCmdBufferCreateFlags flags;
1537 const VkCmdBufferBeginInfo cmdBufferBeginInfo =
1539 VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, // VkStructureType sType;
1540 DE_NULL, // const void* pNext;
1541 0u, // VkCmdBufferOptimizeFlags flags;
1542 DE_NULL, // VkRenderPass renderPass;
1543 0u, // deUint32 subpass;
1544 DE_NULL // VkFramebuffer framebuffer;
1547 const VkClearValue clearValues =
1555 const VkRenderPassBeginInfo renderPassBeginInfo =
1557 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO , // VkStructureType sType;
1558 DE_NULL, // const void* pNext;
1559 *m_renderPass, // VkRenderPass renderPass;
1560 *m_framebuffer, // VkFramebuffer framebuffer;
1561 { 0, 0, m_renderSize.x(), m_renderSize.y() }, // VkRect2D renderArea;
1562 1, // deUint32 clearValueCount;
1563 &clearValues, // const VkClearValue* pClearValues;
1566 m_cmdBuffer = createCommandBuffer(vk, vkDevice, &cmdBufferParams);
1568 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1570 // Add texture barriers
1571 std::vector<VkImageMemoryBarrier> barriers;
1572 std::vector<void*> barrierPtrs;
1574 for(deUint32 i = 0; i < m_uniformInfos.size(); i++)
1576 const UniformInfo* uniformInfo = m_uniformInfos[i].get()->get();
1578 if (uniformInfo->type != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
1583 const SamplerUniform* sampler = static_cast<const SamplerUniform*>(uniformInfo);
1585 VkMemoryOutputFlags outputMask = VK_MEMORY_OUTPUT_HOST_WRITE_BIT | VK_MEMORY_OUTPUT_TRANSFER_BIT;
1586 VkImageMemoryBarrier textureBarrier = createImageMemoryBarrier(sampler->image->get(), outputMask, 0u, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
1588 barriers.push_back(textureBarrier);
1589 barrierPtrs.push_back((void*)&barriers.back());
1592 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));
1594 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_RENDER_PASS_CONTENTS_INLINE);
1596 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
1597 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &*m_descriptorSet, 0u, DE_NULL);
1598 vk.cmdBindIndexBuffer(*m_cmdBuffer, *m_indiceBuffer, 0, VK_INDEX_TYPE_UINT16);
1600 const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size();
1601 const std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0);
1603 std::vector<VkBuffer> buffers(numberOfVertexAttributes);
1604 for (size_t i = 0; i < numberOfVertexAttributes; i++)
1606 buffers[i] = m_vertexBuffers[i].get()->get();
1609 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]);
1610 vk.cmdDrawIndexed(*m_cmdBuffer, quadGrid.getNumTriangles() * 3, 1, 0, 0, 0);
1612 vk.cmdEndRenderPass(*m_cmdBuffer);
1613 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1618 const VkFenceCreateInfo fenceParams =
1620 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
1621 DE_NULL, // const void* pNext;
1622 0u // VkFenceCreateFlags flags;
1624 m_fence = createFence(vk, vkDevice, &fenceParams);
1629 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1630 VK_CHECK(vk.queueSubmit(queue, 1, &m_cmdBuffer.get(), *m_fence));
1631 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/));
1634 // Read back the result
1636 const VkDeviceSize imageSizeBytes = (VkDeviceSize)(sizeof(deUint32) * m_renderSize.x() * m_renderSize.y());
1637 const VkBufferCreateInfo readImageBufferParams =
1639 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1640 DE_NULL, // const void* pNext;
1641 imageSizeBytes, // VkDeviceSize size;
1642 VK_BUFFER_USAGE_TRANSFER_DESTINATION_BIT, // VkBufferUsageFlags usage;
1643 0u, // VkBufferCreateFlags flags;
1644 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1645 1u, // deUint32 queueFamilyCount;
1646 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1648 const Unique<VkBuffer> readImageBuffer (createBuffer(vk, vkDevice, &readImageBufferParams));
1649 const de::UniquePtr<Allocation> readImageBufferMemory (m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
1651 VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
1653 // Copy image to buffer
1654 const VkCmdBufferCreateInfo cmdBufferParams =
1656 VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, // VkStructureType sType;
1657 DE_NULL, // const void* pNext;
1658 *m_cmdPool, // VkCmdPool cmdPool;
1659 VK_CMD_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
1660 0u // VkCmdBufferCreateFlags flags;
1663 const VkCmdBufferBeginInfo cmdBufferBeginInfo =
1665 VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, // VkStructureType sType;
1666 DE_NULL, // const void* pNext;
1667 0u, // VkCmdBufferOptimizeFlags flags;
1668 DE_NULL, // VkRenderPass renderPass;
1669 0u, // deUint32 subpass;
1670 DE_NULL // VkFramebuffer framebuffer;
1673 const Move<VkCmdBuffer> cmdBuffer = createCommandBuffer(vk, vkDevice, &cmdBufferParams);
1675 const VkBufferImageCopy copyParams =
1677 0u, // VkDeviceSize bufferOffset;
1678 (deUint32)m_renderSize.x(), // deUint32 bufferRowLength;
1679 (deUint32)m_renderSize.y(), // deUint32 bufferImageHeight;
1681 VK_IMAGE_ASPECT_COLOR, // VkImageAspect aspect;
1682 0u, // deUint32 mipLevel;
1683 0u, // deUint32 arraySlice;
1684 1u, // deUint32 arraySize;
1685 }, // VkImageSubresourceCopy imageSubresource;
1686 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
1687 { m_renderSize.x(), m_renderSize.y(), 1u } // VkExtent3D imageExtent;
1690 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
1691 vk.cmdCopyImageToBuffer(*cmdBuffer, *m_colorImage, VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL, *readImageBuffer, 1u, ©Params);
1692 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
1694 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1695 VK_CHECK(vk.queueSubmit(queue, 1, &cmdBuffer.get(), *m_fence));
1696 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
1698 invalidateMappedMemoryRange(vk, vkDevice, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset(), imageSizeBytes);
1700 const tcu::TextureFormat resultFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
1701 const tcu::ConstPixelBufferAccess resultAccess (resultFormat, m_renderSize.x(), m_renderSize.y(), 1, readImageBufferMemory->getHostPtr());
1703 tcu::copy(result.getAccess(), resultAccess);
1707 void ShaderRenderCaseInstance::computeVertexReference (tcu::Surface& result, const QuadGrid& quadGrid)
1710 const int width = result.getWidth();
1711 const int height = result.getHeight();
1712 const int gridSize = quadGrid.getGridSize();
1713 const int stride = gridSize + 1;
1714 const bool hasAlpha = true; // \todo [2015-09-07 elecro] add correct alpha check
1715 ShaderEvalContext evalCtx (quadGrid);
1717 // Evaluate color for each vertex.
1718 std::vector<tcu::Vec4> colors ((gridSize + 1) * (gridSize + 1));
1719 for (int y = 0; y < gridSize+1; y++)
1720 for (int x = 0; x < gridSize+1; x++)
1722 const float sx = (float)x / (float)gridSize;
1723 const float sy = (float)y / (float)gridSize;
1724 const int vtxNdx = ((y * (gridSize+1)) + x);
1726 evalCtx.reset(sx, sy);
1727 m_evaluator.evaluate(evalCtx);
1728 DE_ASSERT(!evalCtx.isDiscarded); // Discard is not available in vertex shader.
1729 tcu::Vec4 color = evalCtx.color;
1734 colors[vtxNdx] = color;
1738 for (int y = 0; y < gridSize; y++)
1739 for (int x = 0; x < gridSize; x++)
1741 const float x0 = (float)x / (float)gridSize;
1742 const float x1 = (float)(x + 1) / (float)gridSize;
1743 const float y0 = (float)y / (float)gridSize;
1744 const float y1 = (float)(y + 1) / (float)gridSize;
1746 const float sx0 = x0 * (float)width;
1747 const float sx1 = x1 * (float)width;
1748 const float sy0 = y0 * (float)height;
1749 const float sy1 = y1 * (float)height;
1750 const float oosx = 1.0f / (sx1 - sx0);
1751 const float oosy = 1.0f / (sy1 - sy0);
1753 const int ix0 = deCeilFloatToInt32(sx0 - 0.5f);
1754 const int ix1 = deCeilFloatToInt32(sx1 - 0.5f);
1755 const int iy0 = deCeilFloatToInt32(sy0 - 0.5f);
1756 const int iy1 = deCeilFloatToInt32(sy1 - 0.5f);
1758 const int v00 = (y * stride) + x;
1759 const int v01 = (y * stride) + x + 1;
1760 const int v10 = ((y + 1) * stride) + x;
1761 const int v11 = ((y + 1) * stride) + x + 1;
1762 const tcu::Vec4 c00 = colors[v00];
1763 const tcu::Vec4 c01 = colors[v01];
1764 const tcu::Vec4 c10 = colors[v10];
1765 const tcu::Vec4 c11 = colors[v11];
1767 //printf("(%d,%d) -> (%f..%f, %f..%f) (%d..%d, %d..%d)\n", x, y, sx0, sx1, sy0, sy1, ix0, ix1, iy0, iy1);
1769 for (int iy = iy0; iy < iy1; iy++)
1770 for (int ix = ix0; ix < ix1; ix++)
1772 DE_ASSERT(deInBounds32(ix, 0, width));
1773 DE_ASSERT(deInBounds32(iy, 0, height));
1775 const float sfx = (float)ix + 0.5f;
1776 const float sfy = (float)iy + 0.5f;
1777 const float fx1 = deFloatClamp((sfx - sx0) * oosx, 0.0f, 1.0f);
1778 const float fy1 = deFloatClamp((sfy - sy0) * oosy, 0.0f, 1.0f);
1780 // Triangle quad interpolation.
1781 const bool tri = fx1 + fy1 <= 1.0f;
1782 const float tx = tri ? fx1 : (1.0f-fx1);
1783 const float ty = tri ? fy1 : (1.0f-fy1);
1784 const tcu::Vec4& t0 = tri ? c00 : c11;
1785 const tcu::Vec4& t1 = tri ? c01 : c10;
1786 const tcu::Vec4& t2 = tri ? c10 : c01;
1787 const tcu::Vec4 color = t0 + (t1-t0)*tx + (t2-t0)*ty;
1789 result.setPixel(ix, iy, tcu::RGBA(color));
1794 void ShaderRenderCaseInstance::computeFragmentReference (tcu::Surface& result, const QuadGrid& quadGrid)
1797 const int width = result.getWidth();
1798 const int height = result.getHeight();
1799 const bool hasAlpha = true; // \todo [2015-09-07 elecro] add correct alpha check
1800 ShaderEvalContext evalCtx (quadGrid);
1803 for (int y = 0; y < height; y++)
1804 for (int x = 0; x < width; x++)
1806 const float sx = ((float)x + 0.5f) / (float)width;
1807 const float sy = ((float)y + 0.5f) / (float)height;
1809 evalCtx.reset(sx, sy);
1810 m_evaluator.evaluate(evalCtx);
1811 // Select either clear color or computed color based on discarded bit.
1812 tcu::Vec4 color = evalCtx.isDiscarded ? m_clearColor : evalCtx.color;
1817 result.setPixel(x, y, tcu::RGBA(color));
1821 bool ShaderRenderCaseInstance::compareImages (const tcu::Surface& resImage, const tcu::Surface& refImage, float errorThreshold)
1823 return tcu::fuzzyCompare(m_context.getTestContext().getLog(), "ComparisonResult", "Image comparison result", refImage, resImage, errorThreshold, tcu::COMPARE_LOG_RESULT);
1826 } // shaderrendercase