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<TextureBinding>& 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<TextureBinding>& 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<TextureBinding> 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<TextureBinding>& 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); break;
273 TCU_FAIL("Unsupported texture type");
277 tcu::Texture2D* TextureBinding::loadTexture2D (const tcu::Archive& archive, const char* filename)
279 std::string ext = de::FilePath(filename).getFileExtension();
283 // Uncompressed texture.
284 tcu::TextureLevel level;
285 tcu::ImageIO::loadPNG(level, archive, filename);
287 TCU_CHECK_INTERNAL(level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) ||
288 level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8));
290 // \todo [2015-10-08 elecro] for some reason we get better when using RGBA texture even in RGB case, this needs to be investigated
291 tcu::Texture2D* texture = new tcu::Texture2D(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), level.getWidth(), level.getHeight());
296 texture->allocLevel(0);
298 tcu::copy(texture->getLevel(0), level.getAccess());
300 catch (const std::exception&)
309 TCU_FAIL("Unsupported file format"); // TODO: maybe support pkm?
312 // ShaderEvalContext.
314 ShaderEvalContext::ShaderEvalContext (const QuadGrid& quadGrid)
315 : constCoords (quadGrid.getConstCoords())
316 , isDiscarded (false)
317 , m_quadGrid (quadGrid)
319 const std::vector<TextureBinding>& bindings = m_quadGrid.getTextures();
320 DE_ASSERT((int)bindings.size() <= MAX_TEXTURES);
322 // Fill in texture array.
323 for (int ndx = 0; ndx < (int)bindings.size(); ndx++)
325 const TextureBinding& binding = bindings[ndx];
327 if (binding.getType() == TextureBinding::TYPE_NONE)
330 textures[ndx].sampler = binding.getSampler();
332 switch (binding.getType())
334 case TextureBinding::TYPE_2D: textures[ndx].tex2D = binding.get2D(); break;
335 // \todo [2015-09-07 elecro] Add support for the other binding types
337 case TextureBinding::TYPE_CUBE_MAP: textures[ndx].texCube = binding.getCube(); break;
338 case TextureBinding::TYPE_2D_ARRAY: textures[ndx].tex2DArray = binding.get2DArray(); break;
339 case TextureBinding::TYPE_3D: textures[ndx].tex3D = binding.get3D(); break;
342 TCU_THROW(InternalError, "Handling of texture binding type not implemented");
347 ShaderEvalContext::~ShaderEvalContext (void)
351 void ShaderEvalContext::reset (float sx, float sy)
354 color = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
358 coords = m_quadGrid.getCoords(sx, sy);
359 unitCoords = m_quadGrid.getUnitCoords(sx, sy);
361 // Compute user attributes.
362 const int numAttribs = m_quadGrid.getNumUserAttribs();
363 DE_ASSERT(numAttribs <= MAX_USER_ATTRIBS);
364 for (int attribNdx = 0; attribNdx < numAttribs; attribNdx++)
365 in[attribNdx] = m_quadGrid.getUserAttrib(attribNdx, sx, sy);
368 tcu::Vec4 ShaderEvalContext::texture2D (int unitNdx, const tcu::Vec2& texCoords)
370 if (textures[unitNdx].tex2D)
371 return textures[unitNdx].tex2D->sample(textures[unitNdx].sampler, texCoords.x(), texCoords.y(), 0.0f);
373 return tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
378 ShaderEvaluator::ShaderEvaluator (void)
379 : m_evalFunc(DE_NULL)
383 ShaderEvaluator::ShaderEvaluator (ShaderEvalFunc evalFunc)
384 : m_evalFunc(evalFunc)
388 ShaderEvaluator::~ShaderEvaluator (void)
392 void ShaderEvaluator::evaluate (ShaderEvalContext& ctx) const
394 DE_ASSERT(m_evalFunc);
400 UniformSetup::UniformSetup (void)
401 : m_setupFunc(DE_NULL)
405 UniformSetup::UniformSetup (UniformSetupFunc setupFunc)
406 : m_setupFunc(setupFunc)
410 UniformSetup::~UniformSetup (void)
414 void UniformSetup::setup (ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords) const
417 m_setupFunc(instance, constCoords);
422 ShaderRenderCase::ShaderRenderCase (tcu::TestContext& testCtx,
423 const std::string& name,
424 const std::string& description,
425 const bool isVertexCase,
426 const ShaderEvalFunc evalFunc,
427 const UniformSetup* uniformSetup,
428 const AttributeSetupFunc attribFunc)
429 : vkt::TestCase (testCtx, name, description)
430 , m_isVertexCase (isVertexCase)
431 , m_evaluator (new ShaderEvaluator(evalFunc))
432 , m_uniformSetup (uniformSetup ? uniformSetup : new UniformSetup())
433 , m_attribFunc (attribFunc)
436 ShaderRenderCase::ShaderRenderCase (tcu::TestContext& testCtx,
437 const std::string& name,
438 const std::string& description,
439 const bool isVertexCase,
440 const ShaderEvaluator* evaluator,
441 const UniformSetup* uniformSetup,
442 const AttributeSetupFunc attribFunc)
443 : vkt::TestCase (testCtx, name, description)
444 , m_isVertexCase (isVertexCase)
445 , m_evaluator (evaluator)
446 , m_uniformSetup (uniformSetup ? uniformSetup : new UniformSetup())
447 , m_attribFunc (attribFunc)
450 ShaderRenderCase::~ShaderRenderCase (void)
453 m_evaluator = DE_NULL;
454 delete m_uniformSetup;
455 m_uniformSetup = DE_NULL;
458 void ShaderRenderCase::initPrograms (vk::SourceCollections& programCollection) const
460 programCollection.glslSources.add("vert") << glu::VertexSource(m_vertShaderSource);
461 programCollection.glslSources.add("frag") << glu::FragmentSource(m_fragShaderSource);
464 TestInstance* ShaderRenderCase::createInstance (Context& context) const
466 DE_ASSERT(m_evaluator != DE_NULL);
467 DE_ASSERT(m_uniformSetup != DE_NULL);
468 return new ShaderRenderCaseInstance(context, m_isVertexCase, *m_evaluator, *m_uniformSetup, m_attribFunc);
471 // ShaderRenderCaseInstance.
473 ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context& context,
474 const bool isVertexCase,
475 const ShaderEvaluator& evaluator,
476 const UniformSetup& uniformSetup,
477 const AttributeSetupFunc attribFunc)
478 : vkt::TestInstance (context)
479 , m_clearColor (DEFAULT_CLEAR_COLOR)
480 , m_memAlloc (m_context.getDeviceInterface(), m_context.getDevice(), getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()))
481 , m_isVertexCase (isVertexCase)
482 , m_evaluator (evaluator)
483 , m_uniformSetup (uniformSetup)
484 , m_attribFunc (attribFunc)
485 , m_renderSize (100, 100)
486 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
490 ShaderRenderCaseInstance::~ShaderRenderCaseInstance (void)
494 tcu::TestStatus ShaderRenderCaseInstance::iterate (void)
499 const tcu::IVec2 viewportSize = getViewportSize();
500 const int width = viewportSize.x();
501 const int height = viewportSize.y();
503 QuadGrid quadGrid (m_isVertexCase ? GRID_SIZE : 4, width, height, tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f), m_userAttribTransforms, m_textures);
506 tcu::Surface resImage (width, height);
507 render(resImage, quadGrid);
509 // Compute reference.
510 tcu::Surface refImage (width, height);
512 computeVertexReference(refImage, quadGrid);
514 computeFragmentReference(refImage, quadGrid);
517 const bool compareOk = compareImages(resImage, refImage, 0.05f);
520 return tcu::TestStatus::pass("Result image matches reference");
522 return tcu::TestStatus::fail("Image mismatch");
525 void ShaderRenderCaseInstance::setupUniformData (deUint32 bindingLocation, deUint32 size, const void* dataPtr)
527 const VkDevice vkDevice = m_context.getDevice();
528 const DeviceInterface& vk = m_context.getDeviceInterface();
529 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
531 const VkBufferCreateInfo uniformBufferParams =
533 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
534 DE_NULL, // const void* pNext;
535 size, // VkDeviceSize size;
536 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, // VkBufferUsageFlags usage;
537 0u, // VkBufferCreateFlags flags;
538 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
539 1u, // deUint32 queueFamilyCount;
540 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
543 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &uniformBufferParams);
544 de::MovePtr<Allocation> alloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
545 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
548 VK_CHECK(vk.mapMemory(vkDevice, alloc->getMemory(), alloc->getOffset(), size, 0, &bufferPtr));
549 deMemcpy(bufferPtr, dataPtr, size);
550 flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), size);
551 vk.unmapMemory(vkDevice, alloc->getMemory());
553 const VkBufferViewCreateInfo viewInfo =
555 VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, // VkStructureType sType;
556 DE_NULL, // void* pNext;
557 *buffer, // VkBuffer buffer;
558 VK_FORMAT_R32_SFLOAT, // VkFormat format;
559 0u, // VkDeviceSize offset;
560 size, // VkDeviceSize range;
563 Move<VkBufferView> bufferView = createBufferView(vk, vkDevice, &viewInfo);
565 // \todo [2015-10-09 elecro] remove the '_hack_padding' variable if the driver support small uniforms,
566 // that is for example one float big uniforms.
567 const deUint32 _hack_padding = size < 4 * sizeof(float) ? (deUint32)(3u * sizeof(float)) : 0u;
569 const VkDescriptorInfo descriptor =
571 bufferView.get(), // VkBufferView bufferView;
572 0, // VkSampler sampler;
573 0, // VkImageView imageView;
574 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
576 *buffer, // VkBuffer buffer;
577 0u, // VkDeviceSize offset;
578 size + _hack_padding, // VkDeviceSize range;
579 }, // VkDescriptorBufferInfo bufferInfo;
582 de::MovePtr<BufferUniform> uniformInfo(new BufferUniform());
583 uniformInfo->type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
584 uniformInfo->descriptor = descriptor;
585 uniformInfo->location = bindingLocation;
586 uniformInfo->buffer = VkBufferSp(new vk::Unique<VkBuffer>(buffer));
587 uniformInfo->bufferView = VkBufferViewSp(new vk::Unique<VkBufferView>(bufferView));
588 uniformInfo->alloc = AllocationSp(new de::UniquePtr<vk::Allocation>(alloc));
590 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniformInfo)));
593 void ShaderRenderCaseInstance::addUniform (deUint32 bindingLocation, vk::VkDescriptorType descriptorType, deUint32 dataSize, const void* data)
595 m_descriptorSetLayoutBuilder.addSingleBinding(descriptorType, vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT);
596 m_descriptorPoolBuilder.addType(descriptorType);
598 setupUniformData(bindingLocation, dataSize, data);
601 void ShaderRenderCaseInstance::addAttribute (deUint32 bindingLocation,
603 deUint32 sizePerElement,
607 // Add binding specification
608 const deUint32 binding = (deUint32)m_vertexBindingDescription.size();
609 const VkVertexInputBindingDescription bindingDescription =
611 binding, // deUint32 binding;
612 sizePerElement, // deUint32 strideInBytes;
613 VK_VERTEX_INPUT_STEP_RATE_VERTEX // VkVertexInputStepRate stepRate;
616 m_vertexBindingDescription.push_back(bindingDescription);
618 // Add location and format specification
619 const VkVertexInputAttributeDescription attributeDescription =
621 bindingLocation, // deUint32 location;
622 binding, // deUint32 binding;
623 format, // VkFormat format;
624 0u, // deUint32 offsetInBytes;
627 m_vertexattributeDescription.push_back(attributeDescription);
629 // Upload data to buffer
630 const VkDevice vkDevice = m_context.getDevice();
631 const DeviceInterface& vk = m_context.getDeviceInterface();
632 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
634 const VkDeviceSize inputSize = sizePerElement * count;
635 const VkBufferCreateInfo vertexBufferParams =
637 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
638 DE_NULL, // const void* pNext;
639 inputSize, // VkDeviceSize size;
640 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
641 0u, // VkBufferCreateFlags flags;
642 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
643 1u, // deUint32 queueFamilyCount;
644 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
647 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &vertexBufferParams);
648 de::MovePtr<vk::Allocation> alloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
650 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
653 VK_CHECK(vk.mapMemory(vkDevice, alloc->getMemory(), alloc->getOffset(), inputSize, 0, &bufferPtr));
654 deMemcpy(bufferPtr, dataPtr, inputSize);
655 flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), inputSize);
656 vk.unmapMemory(vkDevice, alloc->getMemory());
658 m_vertexBuffers.push_back(VkBufferSp(new vk::Unique<VkBuffer>(buffer)));
659 m_vertexBufferAllocs.push_back(AllocationSp(new de::UniquePtr<vk::Allocation>(alloc)));
662 void ShaderRenderCaseInstance::useAttribute (deUint32 bindingLocation, BaseAttributeType type)
664 const EnabledBaseAttribute attribute =
666 bindingLocation, // deUint32 location;
667 type // BaseAttributeType type;
669 m_enabledBaseAttributes.push_back(attribute);
672 void ShaderRenderCaseInstance::setup (void)
676 void ShaderRenderCaseInstance::setupUniforms (const tcu::Vec4& constCoords)
678 m_uniformSetup.setup(*this, constCoords);
681 void ShaderRenderCaseInstance::useUniform (deUint32 bindingLocation, BaseUniformType type)
683 #define UNIFORM_CASE(type, value) case type: addUniform(bindingLocation, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, value); break
688 UNIFORM_CASE(UB_FALSE, 0);
689 UNIFORM_CASE(UB_TRUE, 1);
692 UNIFORM_CASE(UB4_FALSE, tcu::Vec4(0));
693 UNIFORM_CASE(UB4_TRUE, tcu::Vec4(1));
696 UNIFORM_CASE(UI_ZERO, 0);
697 UNIFORM_CASE(UI_ONE, 1);
698 UNIFORM_CASE(UI_TWO, 2);
699 UNIFORM_CASE(UI_THREE, 3);
700 UNIFORM_CASE(UI_FOUR, 4);
701 UNIFORM_CASE(UI_FIVE, 5);
702 UNIFORM_CASE(UI_SIX, 6);
703 UNIFORM_CASE(UI_SEVEN, 7);
704 UNIFORM_CASE(UI_EIGHT, 8);
705 UNIFORM_CASE(UI_ONEHUNDREDONE, 101);
708 UNIFORM_CASE(UI2_MINUS_ONE, tcu::IVec2(-1));
709 UNIFORM_CASE(UI2_ZERO, tcu::IVec2(0));
710 UNIFORM_CASE(UI2_ONE, tcu::IVec2(1));
711 UNIFORM_CASE(UI2_TWO, tcu::IVec2(2));
712 UNIFORM_CASE(UI2_THREE, tcu::IVec2(3));
713 UNIFORM_CASE(UI2_FOUR, tcu::IVec2(4));
714 UNIFORM_CASE(UI2_FIVE, tcu::IVec2(5));
717 UNIFORM_CASE(UI3_MINUS_ONE, tcu::IVec3(-1));
718 UNIFORM_CASE(UI3_ZERO, tcu::IVec3(0));
719 UNIFORM_CASE(UI3_ONE, tcu::IVec3(1));
720 UNIFORM_CASE(UI3_TWO, tcu::IVec3(2));
721 UNIFORM_CASE(UI3_THREE, tcu::IVec3(3));
722 UNIFORM_CASE(UI3_FOUR, tcu::IVec3(4));
723 UNIFORM_CASE(UI3_FIVE, tcu::IVec3(5));
726 UNIFORM_CASE(UI4_MINUS_ONE, tcu::IVec4(-1));
727 UNIFORM_CASE(UI4_ZERO, tcu::IVec4(0));
728 UNIFORM_CASE(UI4_ONE, tcu::IVec4(1));
729 UNIFORM_CASE(UI4_TWO, tcu::IVec4(2));
730 UNIFORM_CASE(UI4_THREE, tcu::IVec4(3));
731 UNIFORM_CASE(UI4_FOUR, tcu::IVec4(4));
732 UNIFORM_CASE(UI4_FIVE, tcu::IVec4(5));
735 UNIFORM_CASE(UF_ZERO, 0.0f);
736 UNIFORM_CASE(UF_ONE, 1.0f);
737 UNIFORM_CASE(UF_TWO, 2.0f);
738 UNIFORM_CASE(UF_THREE, 3.0f);
739 UNIFORM_CASE(UF_FOUR, 4.0f);
740 UNIFORM_CASE(UF_FIVE, 5.0f);
741 UNIFORM_CASE(UF_SIX, 6.0f);
742 UNIFORM_CASE(UF_SEVEN, 7.0f);
743 UNIFORM_CASE(UF_EIGHT, 8.0f);
745 UNIFORM_CASE(UF_HALF, 1.0f / 2.0f);
746 UNIFORM_CASE(UF_THIRD, 1.0f / 3.0f);
747 UNIFORM_CASE(UF_FOURTH, 1.0f / 4.0f);
748 UNIFORM_CASE(UF_FIFTH, 1.0f / 5.0f);
749 UNIFORM_CASE(UF_SIXTH, 1.0f / 6.0f);
750 UNIFORM_CASE(UF_SEVENTH, 1.0f / 7.0f);
751 UNIFORM_CASE(UF_EIGHTH, 1.0f / 8.0f);
754 UNIFORM_CASE(UV2_MINUS_ONE, tcu::Vec2(-1.0f));
755 UNIFORM_CASE(UV2_ZERO, tcu::Vec2(0.0f));
756 UNIFORM_CASE(UV2_ONE, tcu::Vec2(1.0f));
757 UNIFORM_CASE(UV2_TWO, tcu::Vec2(2.0f));
758 UNIFORM_CASE(UV2_THREE, tcu::Vec2(3.0f));
760 UNIFORM_CASE(UV2_HALF, tcu::Vec2(1.0f / 2.0f));
763 UNIFORM_CASE(UV3_MINUS_ONE, tcu::Vec3(-1.0f));
764 UNIFORM_CASE(UV3_ZERO, tcu::Vec3(0.0f));
765 UNIFORM_CASE(UV3_ONE, tcu::Vec3(1.0f));
766 UNIFORM_CASE(UV3_TWO, tcu::Vec3(2.0f));
767 UNIFORM_CASE(UV3_THREE, tcu::Vec3(3.0f));
769 UNIFORM_CASE(UV3_HALF, tcu::Vec3(1.0f / 2.0f));
772 UNIFORM_CASE(UV4_MINUS_ONE, tcu::Vec4(-1.0f));
773 UNIFORM_CASE(UV4_ZERO, tcu::Vec4(0.0f));
774 UNIFORM_CASE(UV4_ONE, tcu::Vec4(1.0f));
775 UNIFORM_CASE(UV4_TWO, tcu::Vec4(2.0f));
776 UNIFORM_CASE(UV4_THREE, tcu::Vec4(3.0f));
778 UNIFORM_CASE(UV4_HALF, tcu::Vec4(1.0f / 2.0f));
780 UNIFORM_CASE(UV4_BLACK, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
781 UNIFORM_CASE(UV4_GRAY, tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f));
782 UNIFORM_CASE(UV4_WHITE, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
785 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Unknown Uniform type: " << type << tcu::TestLog::EndMessage;
792 const tcu::IVec2 ShaderRenderCaseInstance::getViewportSize (void) const
794 return tcu::IVec2(de::min(m_renderSize.x(), MAX_RENDER_WIDTH),
795 de::min(m_renderSize.y(), MAX_RENDER_HEIGHT));
798 Move<VkImage> ShaderRenderCaseInstance::createImage2D (const tcu::Texture2D& texture,
799 const VkFormat format,
800 const VkImageUsageFlags usage,
801 const VkImageTiling tiling)
803 const VkDevice vkDevice = m_context.getDevice();
804 const DeviceInterface& vk = m_context.getDeviceInterface();
805 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
807 const VkImageCreateInfo imageCreateInfo =
809 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
810 DE_NULL, // const void* pnext;
811 VK_IMAGE_TYPE_2D, // VkImageType imageType;
812 format, // VkFormat format;
813 { texture.getWidth(), texture.getHeight(), 1 }, // VkExtend3D extent;
814 1u, // deUint32 mipLevels;
815 1u, // deUint32 arraySize;
816 1u, // deUint32 samples;
817 tiling, // VkImageTiling tiling;
818 usage, // VkImageUsageFlags usage;
819 0, // VkImageCreateFlags flags;
820 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
821 1, // deuint32 queueFamilyCount;
822 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
823 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
826 Move<VkImage> vkTexture = createImage(vk, vkDevice, &imageCreateInfo);
830 de::MovePtr<Allocation> ShaderRenderCaseInstance::uploadImage2D (const tcu::Texture2D& refTexture,
831 const VkImage& vkTexture)
833 const VkDevice vkDevice = m_context.getDevice();
834 const DeviceInterface& vk = m_context.getDeviceInterface();
836 de::MovePtr<Allocation> allocation = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, vkTexture), MemoryRequirement::HostVisible);
837 VK_CHECK(vk.bindImageMemory(vkDevice, vkTexture, allocation->getMemory(), allocation->getOffset()));
839 const VkImageSubresource subres =
841 VK_IMAGE_ASPECT_COLOR, // VkImageAspect aspect;
842 0u, // deUint32 mipLevel;
843 0u // deUint32 arraySlice
846 VkSubresourceLayout layout;
847 VK_CHECK(vk.getImageSubresourceLayout(vkDevice, vkTexture, &subres, &layout));
850 VK_CHECK(vk.mapMemory(vkDevice, allocation->getMemory(), allocation->getOffset(), layout.size, 0u, &imagePtr));
852 tcu::ConstPixelBufferAccess access = refTexture.getLevel(0);
853 tcu::PixelBufferAccess destAccess(refTexture.getFormat(), refTexture.getWidth(), refTexture.getHeight(), 1, imagePtr);
855 tcu::copy(destAccess, access);
857 flushMappedMemoryRange(vk, vkDevice, allocation->getMemory(), allocation, layout.size);
858 vk.unmapMemory(vkDevice, allocation->getMemory());
863 void ShaderRenderCaseInstance::copyTilingImageToOptimal (const vk::VkImage& srcImage,
864 const vk::VkImage& dstImage,
868 const VkDevice vkDevice = m_context.getDevice();
869 const DeviceInterface& vk = m_context.getDeviceInterface();
870 const VkQueue queue = m_context.getUniversalQueue();
871 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
873 // Create command pool
874 const VkCmdPoolCreateInfo cmdPoolParams =
876 VK_STRUCTURE_TYPE_CMD_POOL_CREATE_INFO, // VkStructureType sType;
877 DE_NULL, // const void* pNext;
878 queueFamilyIndex, // deUint32 queueFamilyIndex;
879 VK_CMD_POOL_CREATE_TRANSIENT_BIT // VkCmdPoolCreateFlags flags;
882 Move<VkCmdPool> cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
884 // Create command buffer
885 const VkCmdBufferCreateInfo cmdBufferParams =
887 VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, // VkStructureType sType;
888 DE_NULL, // const void* pNext;
889 *cmdPool, // VkCmdPool cmdPool;
890 VK_CMD_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
891 0u // VkCmdBufferCreateFlags flags;
894 const VkCmdBufferOptimizeFlags optimizeFlags = VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT | VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT;
895 const VkCmdBufferBeginInfo cmdBufferBeginInfo =
897 VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, // VkStructureType sType;
898 DE_NULL, // const void* pNext;
899 optimizeFlags, // VkCmdBufferOptimizeFlags flags;
900 DE_NULL, // VkRenderPass renderPass;
901 0u, // deUint32 subpass;
902 DE_NULL // VkFramebuffer framebuffer;
905 Move<VkCmdBuffer> cmdBuffer = createCommandBuffer(vk, vkDevice, &cmdBufferParams);
907 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
909 // Add image barriers
910 const VkImageMemoryBarrier layoutBarriers[2] =
912 createImageMemoryBarrier(srcImage, 0u, 0u, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL),
913 createImageMemoryBarrier(dstImage, 0u, VK_MEMORY_INPUT_TRANSFER_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL)
916 for (deUint32 barrierNdx = 0; barrierNdx < DE_LENGTH_OF_ARRAY(layoutBarriers); barrierNdx++)
918 const VkImageMemoryBarrier* memoryBarrier = &layoutBarriers[barrierNdx];
919 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, (const void * const*)&memoryBarrier);
923 const VkImageCopy imageCopy =
926 VK_IMAGE_ASPECT_COLOR, // VkImageAspect aspect;
927 0u, // deUint32 mipLevel;
928 0u, // deUint32 arrayLayer;
929 1u // deUint32 arraySize;
930 }, // VkImageSubresourceCopy srcSubresource;
935 }, // VkOffset3D srcOffset;
937 VK_IMAGE_ASPECT_COLOR, // VkImageAspect aspect;
938 0u, // deUint32 mipLevel;
939 0u, // deUint32 arrayLayer;
940 1u // deUint32 arraySize;
941 }, // VkImageSubresourceCopy destSubResource;
946 }, // VkOffset3D dstOffset;
948 width, // int32 width;
949 height, // int32 height;
951 } // VkExtent3D extent;
954 vk.cmdCopyImage(*cmdBuffer, srcImage, VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL, dstImage, VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, 1, &imageCopy);
956 // Add destination barrier
957 const VkImageMemoryBarrier dstBarrier =
958 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);
960 const void* const* barrier = (const void* const*)&dstBarrier;
961 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, (const void* const*)&barrier);
963 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
965 const VkFenceCreateInfo fenceParams =
967 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
968 DE_NULL, // const void* pNext;
969 0u // VkFenceCreateFlags flags;
971 Move<VkFence> fence = createFence(vk, vkDevice, &fenceParams);
974 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
975 VK_CHECK(vk.queueSubmit(queue, 1, &cmdBuffer.get(), *fence));
976 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/));
979 void ShaderRenderCaseInstance::useSampler2D (deUint32 bindingLocation, deUint32 textureID)
981 DE_ASSERT(textureID < m_textures.size());
983 const VkDevice vkDevice = m_context.getDevice();
984 const DeviceInterface& vk = m_context.getDeviceInterface();
985 const TextureBinding& textureBinding = m_textures[textureID];
986 const tcu::Texture2D* refTexture = textureBinding.get2D();
987 const tcu::Sampler& refSampler = textureBinding.getSampler();
988 const VkFormat format = refTexture->getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
989 ? VK_FORMAT_R8G8B8A8_UNORM
990 : VK_FORMAT_R8G8B8_UNORM;
992 DE_ASSERT(refTexture != DE_NULL);
994 // Create & alloc the image
995 Move<VkImage> vkTexture;
996 de::MovePtr<Allocation> allocation;
998 if (isSupportedLinearTilingFormat(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), format))
1000 vkTexture = createImage2D(*refTexture, format, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_LINEAR);
1001 allocation = uploadImage2D(*refTexture, *vkTexture);
1003 else if (isSupportedOptimalTilingFormat(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), format))
1005 Move<VkImage> stagingTexture (createImage2D(*refTexture, format, VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT, VK_IMAGE_TILING_LINEAR));
1006 de::MovePtr<Allocation> stagingAlloc (uploadImage2D(*refTexture, *stagingTexture));
1008 const VkImageUsageFlags dstUsageFlags = VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
1009 vkTexture = createImage2D(*refTexture, format, dstUsageFlags, VK_IMAGE_TILING_OPTIMAL);
1010 allocation = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *vkTexture), MemoryRequirement::Any);
1011 VK_CHECK(vk.bindImageMemory(vkDevice, *vkTexture, allocation->getMemory(), allocation->getOffset()));
1013 copyTilingImageToOptimal(*stagingTexture, *vkTexture, refTexture->getWidth(), refTexture->getHeight());
1017 TCU_THROW(InternalError, "Unable to create 2D image");
1021 const bool compareEnabled = (refSampler.compare != tcu::Sampler::COMPAREMODE_NONE);
1022 const VkSamplerCreateInfo samplerParams =
1024 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
1025 DE_NULL, // const void* pNext;
1026 mapFilterMode(refSampler.magFilter), // VkTexFilter magFilter;
1027 mapFilterMode(refSampler.minFilter), // VkTexFilter minFilter;
1028 mapMipmapMode(refSampler.minFilter), // VkTexMipmapMode mipMode;
1029 mapWrapMode(refSampler.wrapS), // VkTexAddressMode addressModeU;
1030 mapWrapMode(refSampler.wrapT), // VkTexAddressMode addressModeV;
1031 mapWrapMode(refSampler.wrapR), // VkTexAddressMode addressModeW;
1032 refSampler.lodThreshold, // float mipLodBias;
1033 1, // float maxAnisotropy;
1034 compareEnabled, // VkBool32 compareEnable;
1035 mapCompareMode(refSampler.compare), // VkCompareOp compareOp;
1036 0.0f, // float minLod;
1037 0.0f, // float maxLod;
1038 VK_BORDER_COLOR_INT_OPAQUE_WHITE, // VkBorderColor boderColor;
1039 VK_FALSE, // VkBool32 unnormalizerdCoordinates;
1042 Move<VkSampler> sampler = createSampler(vk, vkDevice, &samplerParams);
1044 const VkImageViewCreateInfo viewParams =
1046 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1047 NULL, // const voide* pNexŧ;
1048 *vkTexture, // VkImage image;
1049 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
1050 format, // VkFormat format;
1052 VK_CHANNEL_SWIZZLE_R, // VkChannelSwizzle r;
1053 VK_CHANNEL_SWIZZLE_G, // VkChannelSwizzle g;
1054 VK_CHANNEL_SWIZZLE_B, // VkChannelSwizzle b;
1055 VK_CHANNEL_SWIZZLE_A // VkChannelSwizzle a;
1056 }, // VkChannelMapping channels;
1058 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1059 0, // deUint32 baseMipLevel;
1060 1, // deUint32 mipLevels;
1061 0, // deUint32 baseArraySlice;
1062 1 // deUint32 arraySize;
1063 }, // VkImageSubresourceRange subresourceRange;
1064 0u // VkImageViewCreateFlags flags;
1067 Move<VkImageView> imageView = createImageView(vk, vkDevice, &viewParams);
1069 const vk::VkDescriptorInfo descriptor =
1071 0, // VkBufferView bufferView;
1072 sampler.get(), // VkSampler sampler;
1073 imageView.get(), // VkImageView imageView;
1074 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
1075 {0, 0, 0}, // VkDescriptorBufferInfo bufferInfo;
1078 de::MovePtr<SamplerUniform> uniform(new SamplerUniform());
1079 uniform->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
1080 uniform->descriptor = descriptor;
1081 uniform->location = bindingLocation;
1082 uniform->image = VkImageSp(new vk::Unique<VkImage>(vkTexture));
1083 uniform->imageView = VkImageViewSp(new vk::Unique<VkImageView>(imageView));
1084 uniform->sampler = VkSamplerSp(new vk::Unique<VkSampler>(sampler));
1085 uniform->alloc = AllocationSp(new de::UniquePtr<vk::Allocation>(allocation));
1087 m_descriptorSetLayoutBuilder.addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, vk::VK_SHADER_STAGE_FRAGMENT_BIT, &uniform->descriptor.sampler);
1088 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
1090 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniform)));
1093 void ShaderRenderCaseInstance::setupDefaultInputs (const QuadGrid& quadGrid)
1095 /* Configuration of the vertex input attributes:
1096 a_position is at location 0
1097 a_coords is at location 1
1098 a_unitCoords is at location 2
1099 a_one is at location 3
1101 User attributes starts from at the location 4.
1103 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getPositions());
1104 addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getCoords());
1105 addAttribute(2u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUnitCoords());
1106 addAttribute(3u, VK_FORMAT_R32_SFLOAT, sizeof(float), quadGrid.getNumVertices(), quadGrid.getAttribOne());
1110 BaseAttributeType type;
1112 } userAttributes[] =
1122 BaseAttributeType matrixType;
1138 for (size_t attrNdx = 0; attrNdx < m_enabledBaseAttributes.size(); attrNdx++)
1140 for (int userNdx = 0; userNdx < DE_LENGTH_OF_ARRAY(userAttributes); userNdx++)
1142 if (userAttributes[userNdx].type != m_enabledBaseAttributes[attrNdx].type)
1145 addAttribute(m_enabledBaseAttributes[attrNdx].location, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUserAttrib(userNdx));
1148 for (int matNdx = 0; matNdx < DE_LENGTH_OF_ARRAY(matrices); matNdx++)
1151 if (matrices[matNdx].matrixType != m_enabledBaseAttributes[attrNdx].type)
1154 const int numCols = matrices[matNdx].numCols;
1156 for (int colNdx = 0; colNdx < numCols; colNdx++)
1158 addAttribute(m_enabledBaseAttributes[attrNdx].location + colNdx, VK_FORMAT_R32G32B32A32_SFLOAT, 4 * sizeof(float), quadGrid.getNumVertices(), quadGrid.getUserAttrib(colNdx));
1164 void ShaderRenderCaseInstance::render (tcu::Surface& result, const QuadGrid& quadGrid)
1166 const VkDevice vkDevice = m_context.getDevice();
1167 const DeviceInterface& vk = m_context.getDeviceInterface();
1168 const VkQueue queue = m_context.getUniversalQueue();
1169 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1171 // Create color image
1173 const VkImageCreateInfo colorImageParams =
1175 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1176 DE_NULL, // const void* pNext;
1177 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1178 m_colorFormat, // VkFormat format;
1179 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent;
1180 1u, // deUint32 mipLevels;
1181 1u, // deUint32 arraySize;
1182 1u, // deUint32 samples;
1183 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1184 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT, // VkImageUsageFlags usage;
1185 0u, // VkImageCreateFlags flags;
1186 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1187 1u, // deUint32 queueFamilyCount;
1188 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1189 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1192 m_colorImage = createImage(vk, vkDevice, &colorImageParams);
1194 // Allocate and bind color image memory
1195 m_colorImageAlloc = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
1196 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
1199 // Create color attachment view
1201 const VkImageViewCreateInfo colorImageViewParams =
1203 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1204 DE_NULL, // const void* pNext;
1205 *m_colorImage, // VkImage image;
1206 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
1207 m_colorFormat, // VkFormat format;
1209 VK_CHANNEL_SWIZZLE_R, // VkChannelSwizzle r;
1210 VK_CHANNEL_SWIZZLE_G, // VkChannelSwizzle g;
1211 VK_CHANNEL_SWIZZLE_B, // VkChannelSwizzle b;
1212 VK_CHANNEL_SWIZZLE_A // VkChannelSwizzle a;
1213 }, // VkChannelMapping channels;
1215 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1216 0, // deUint32 baseMipLevel;
1217 1, // deUint32 mipLevels;
1218 0, // deUint32 baseArraySlice;
1219 1 // deUint32 arraySize;
1220 }, // VkImageSubresourceRange subresourceRange;
1221 0u // VkImageViewCreateFlags flags;
1224 m_colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
1227 // Create render pass
1229 const VkAttachmentDescription colorAttachmentDescription =
1231 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION, // VkStructureType sType;
1232 DE_NULL, // const void* pNext;
1233 m_colorFormat, // VkFormat format;
1234 1u, // deUint32 samples;
1235 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
1236 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
1237 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
1238 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
1239 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
1240 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
1241 0u, // VkAttachmentDescriptorFlags flags;
1244 const VkAttachmentReference colorAttachmentReference =
1246 0u, // deUint32 attachment;
1247 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
1250 const VkSubpassDescription subpassDescription =
1252 VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION, // VkStructureType sType;
1253 DE_NULL, // constvoid* pNext;
1254 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
1255 0u, // VkSubpassDescriptionFlags flags;
1256 0u, // deUint32 inputCount;
1257 DE_NULL, // constVkAttachmentReference* pInputAttachments;
1258 1u, // deUint32 colorCount;
1259 &colorAttachmentReference, // constVkAttachmentReference* pColorAttachments;
1260 DE_NULL, // constVkAttachmentReference* pResolveAttachments;
1261 { ~0u, VK_IMAGE_LAYOUT_GENERAL }, // VkAttachmentReference depthStencilAttachment;
1262 0u, // deUint32 preserveCount;
1263 DE_NULL // constVkAttachmentReference* pPreserveAttachments;
1266 const VkRenderPassCreateInfo renderPassParams =
1268 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
1269 DE_NULL, // const void* pNext;
1270 1u, // deUint32 attachmentCount;
1271 &colorAttachmentDescription, // const VkAttachmentDescription* pAttachments;
1272 1u, // deUint32 subpassCount;
1273 &subpassDescription, // const VkSubpassDescription* pSubpasses;
1274 0u, // deUint32 dependencyCount;
1275 DE_NULL // const VkSubpassDependency* pDependencies;
1278 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
1281 // Create framebuffer
1283 const VkFramebufferCreateInfo framebufferParams =
1285 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
1286 DE_NULL, // const void* pNext;
1287 *m_renderPass, // VkRenderPass renderPass;
1288 1u, // deUint32 attachmentCount;
1289 &*m_colorImageView, // const VkImageView* pAttachments;
1290 (deUint32)m_renderSize.x(), // deUint32 width;
1291 (deUint32)m_renderSize.y(), // deUint32 height;
1292 1u // deUint32 layers;
1295 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
1298 // Create descriptors
1300 setupUniforms(quadGrid.getConstCoords());
1302 m_descriptorSetLayout = m_descriptorSetLayoutBuilder.build(vk, vkDevice);
1303 m_descriptorPool = m_descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1u);
1304 m_descriptorSet = allocDescriptorSet(vk, vkDevice, *m_descriptorPool, VK_DESCRIPTOR_SET_USAGE_STATIC, *m_descriptorSetLayout);
1306 for(deUint32 i = 0; i < m_uniformInfos.size(); i++)
1308 const UniformInfo* uniformInfo = m_uniformInfos[i].get()->get();
1309 deUint32 location = uniformInfo->location;
1310 m_descriptorSetUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &uniformInfo->descriptor);
1313 m_descriptorSetUpdateBuilder.update(vk, vkDevice);
1316 // Create pipeline layout
1318 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1320 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1321 DE_NULL, // const void* pNext;
1322 1u, // deUint32 descriptorSetCount;
1323 &*m_descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
1324 0u, // deUint32 pushConstantRangeCount;
1325 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
1328 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1333 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
1334 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
1336 const VkShaderCreateInfo vertexShaderParams =
1338 VK_STRUCTURE_TYPE_SHADER_CREATE_INFO, // VkStructureType sType;
1339 DE_NULL, // const void* pNext;
1340 *m_vertexShaderModule, // VkShaderModule module;
1341 "main", // const char* pName;
1342 0u, // VkShaderCreateFlags flags;
1343 VK_SHADER_STAGE_VERTEX, // VkShaderStage stage;
1346 const VkShaderCreateInfo fragmentShaderParams =
1348 VK_STRUCTURE_TYPE_SHADER_CREATE_INFO, // VkStructureType sType;
1349 DE_NULL, // const void* pNext;
1350 *m_fragmentShaderModule, // VkShaderModule module;
1351 "main", // const char* pName;
1352 0u, // VkShaderCreateFlags flags;
1353 VK_SHADER_STAGE_FRAGMENT, // VkShaderStage stage;
1356 m_vertexShader = createShader(vk, vkDevice, &vertexShaderParams);
1357 m_fragmentShader= createShader(vk, vkDevice, &fragmentShaderParams);
1362 const VkPipelineShaderStageCreateInfo shaderStageParams[2] =
1365 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1366 DE_NULL, // const void* pNext;
1367 VK_SHADER_STAGE_VERTEX, // VkShaderStage stage;
1368 *m_vertexShader, // VkShader shader;
1369 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1372 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1373 DE_NULL, // const void* pNext;
1374 VK_SHADER_STAGE_FRAGMENT, // VkShaderStage stage;
1375 *m_fragmentShader, // VkShader shader;
1376 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1380 // Add test case specific attributes
1382 m_attribFunc(*this, quadGrid.getNumVertices());
1384 // Add base attributes
1385 setupDefaultInputs(quadGrid);
1387 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
1389 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1390 DE_NULL, // const void* pNext;
1391 (deUint32)m_vertexBindingDescription.size(), // deUint32 bindingCount;
1392 &m_vertexBindingDescription[0], // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1393 (deUint32)m_vertexattributeDescription.size(), // deUint32 attributeCount;
1394 &m_vertexattributeDescription[0], // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1397 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
1399 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
1400 DE_NULL, // const void* pNext;
1401 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology;
1402 false // VkBool32 primitiveRestartEnable;
1405 const VkViewport viewport =
1407 0.0f, // float originX;
1408 0.0f, // float originY;
1409 (float)m_renderSize.x(), // float width;
1410 (float)m_renderSize.y(), // float height;
1411 0.0f, // float minDepth;
1412 1.0f // float maxDepth;
1415 const VkRect2D scissor =
1420 }, // VkOffset2D offset;
1422 m_renderSize.x(), // deUint32 width;
1423 m_renderSize.y(), // deUint32 height;
1424 }, // VkExtent2D extent;
1427 const VkPipelineViewportStateCreateInfo viewportStateParams =
1429 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
1430 DE_NULL, // const void* pNext;
1431 1u, // deUint32 viewportCount;
1432 &viewport, // const VkViewport* pViewports;
1433 1u, // deUint32 scissorsCount;
1434 &scissor, // const VkRect2D* pScissors;
1437 const VkPipelineRasterStateCreateInfo rasterStateParams =
1439 VK_STRUCTURE_TYPE_PIPELINE_RASTER_STATE_CREATE_INFO, // VkStructureType sType;
1440 DE_NULL, // const void* pNext;
1441 false, // VkBool32 depthClipEnable;
1442 false, // VkBool32 rasterizerDiscardEnable;
1443 VK_FILL_MODE_SOLID, // VkFillMode fillMode;
1444 VK_CULL_MODE_NONE, // VkCullMode cullMode;
1445 VK_FRONT_FACE_CCW, // VkFrontFace frontFace;
1446 false, // VkBool32 depthBiasEnable;
1447 0.0f, // float depthBias;
1448 0.0f, // float depthBiasClamp;
1449 0.0f, // float slopeScaledDepthBias;
1450 1.0f, // float lineWidth;
1453 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
1455 false, // VkBool32 blendEnable;
1456 VK_BLEND_ONE, // VkBlend srcBlendColor;
1457 VK_BLEND_ZERO, // VkBlend destBlendColor;
1458 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
1459 VK_BLEND_ONE, // VkBlend srcBlendAlpha;
1460 VK_BLEND_ZERO, // VkBlend destBlendAlpha;
1461 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
1462 VK_CHANNEL_R_BIT | VK_CHANNEL_G_BIT | VK_CHANNEL_B_BIT | VK_CHANNEL_A_BIT // VkChannelFlags channelWriteMask;
1465 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
1467 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1468 DE_NULL, // const void* pNext;
1469 false, // VkBool32 alphaToCoverageEnable;
1470 false, // VkBool32 alphaToOneEnable;
1471 false, // VkBool32 logicOpEnable;
1472 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
1473 1u, // deUint32 attachmentCount;
1474 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
1475 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4];
1478 const VkPipelineDynamicStateCreateInfo dynamicStateInfo =
1480 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
1481 DE_NULL, // const void* pNext;
1482 0u, // deUint32 dynamicStateCount;
1483 DE_NULL // const VkDynamicState* pDynamicStates;
1486 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
1488 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
1489 DE_NULL, // const void* pNext;
1490 2u, // deUint32 stageCount;
1491 shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages;
1492 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
1493 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
1494 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
1495 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
1496 &rasterStateParams, // const VkPipelineRasterStateCreateInfo* pRasterState;
1497 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
1498 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
1499 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
1500 &dynamicStateInfo, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
1501 0u, // VkPipelineCreateFlags flags;
1502 *m_pipelineLayout, // VkPipelineLayout layout;
1503 *m_renderPass, // VkRenderPass renderPass;
1504 0u, // deUint32 subpass;
1505 0u, // VkPipeline basePipelineHandle;
1506 0u // deInt32 basePipelineIndex;
1509 m_graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
1512 // Create vertex indices buffer
1514 const VkDeviceSize indiceBufferSize = quadGrid.getNumTriangles() * 3 * sizeof(deUint16);
1515 const VkBufferCreateInfo indiceBufferParams =
1517 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1518 DE_NULL, // const void* pNext;
1519 indiceBufferSize, // VkDeviceSize size;
1520 VK_BUFFER_USAGE_INDEX_BUFFER_BIT, // VkBufferUsageFlags usage;
1521 0u, // VkBufferCreateFlags flags;
1522 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1523 1u, // deUint32 queueFamilyCount;
1524 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1527 m_indiceBuffer = createBuffer(vk, vkDevice, &indiceBufferParams);
1528 m_indiceBufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_indiceBuffer), MemoryRequirement::HostVisible);
1530 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_indiceBuffer, m_indiceBufferAlloc->getMemory(), m_indiceBufferAlloc->getOffset()));
1532 // Load vertice indices into buffer
1534 VK_CHECK(vk.mapMemory(vkDevice, m_indiceBufferAlloc->getMemory(), m_indiceBufferAlloc->getOffset(), indiceBufferSize, 0, &bufferPtr));
1535 deMemcpy(bufferPtr, quadGrid.getIndices(), indiceBufferSize);
1536 flushMappedMemoryRange(vk, vkDevice, m_indiceBufferAlloc->getMemory(), m_indiceBufferAlloc->getOffset(), indiceBufferSize);
1537 vk.unmapMemory(vkDevice, m_indiceBufferAlloc->getMemory());
1540 // Create command pool
1542 const VkCmdPoolCreateInfo cmdPoolParams =
1544 VK_STRUCTURE_TYPE_CMD_POOL_CREATE_INFO, // VkStructureType sType;
1545 DE_NULL, // const void* pNext;
1546 queueFamilyIndex, // deUint32 queueFamilyIndex;
1547 VK_CMD_POOL_CREATE_TRANSIENT_BIT // VkCmdPoolCreateFlags flags;
1550 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1553 // Create command buffer
1555 const VkCmdBufferCreateInfo cmdBufferParams =
1557 VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, // VkStructureType sType;
1558 DE_NULL, // const void* pNext;
1559 *m_cmdPool, // VkCmdPool cmdPool;
1560 VK_CMD_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
1561 0u // VkCmdBufferCreateFlags flags;
1564 const VkCmdBufferBeginInfo cmdBufferBeginInfo =
1566 VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, // VkStructureType sType;
1567 DE_NULL, // const void* pNext;
1568 0u, // VkCmdBufferOptimizeFlags flags;
1569 DE_NULL, // VkRenderPass renderPass;
1570 0u, // deUint32 subpass;
1571 DE_NULL // VkFramebuffer framebuffer;
1574 const VkClearValue clearValues =
1582 const VkRenderPassBeginInfo renderPassBeginInfo =
1584 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO , // VkStructureType sType;
1585 DE_NULL, // const void* pNext;
1586 *m_renderPass, // VkRenderPass renderPass;
1587 *m_framebuffer, // VkFramebuffer framebuffer;
1588 { 0, 0, m_renderSize.x(), m_renderSize.y() }, // VkRect2D renderArea;
1589 1, // deUint32 clearValueCount;
1590 &clearValues, // const VkClearValue* pClearValues;
1593 m_cmdBuffer = createCommandBuffer(vk, vkDevice, &cmdBufferParams);
1595 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1597 // Add texture barriers
1598 std::vector<VkImageMemoryBarrier> barriers;
1599 std::vector<void*> barrierPtrs;
1601 for(deUint32 i = 0; i < m_uniformInfos.size(); i++)
1603 const UniformInfo* uniformInfo = m_uniformInfos[i].get()->get();
1605 if (uniformInfo->type != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
1610 const SamplerUniform* sampler = static_cast<const SamplerUniform*>(uniformInfo);
1612 VkMemoryOutputFlags outputMask = VK_MEMORY_OUTPUT_HOST_WRITE_BIT | VK_MEMORY_OUTPUT_TRANSFER_BIT;
1613 VkImageMemoryBarrier textureBarrier = createImageMemoryBarrier(sampler->image->get(), outputMask, 0u, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
1615 barriers.push_back(textureBarrier);
1616 barrierPtrs.push_back((void*)&barriers.back());
1619 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));
1621 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_RENDER_PASS_CONTENTS_INLINE);
1623 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
1624 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &*m_descriptorSet, 0u, DE_NULL);
1625 vk.cmdBindIndexBuffer(*m_cmdBuffer, *m_indiceBuffer, 0, VK_INDEX_TYPE_UINT16);
1627 const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size();
1628 const std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0);
1630 std::vector<VkBuffer> buffers(numberOfVertexAttributes);
1631 for (size_t i = 0; i < numberOfVertexAttributes; i++)
1633 buffers[i] = m_vertexBuffers[i].get()->get();
1636 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]);
1637 vk.cmdDrawIndexed(*m_cmdBuffer, quadGrid.getNumTriangles() * 3, 1, 0, 0, 0);
1639 vk.cmdEndRenderPass(*m_cmdBuffer);
1640 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1645 const VkFenceCreateInfo fenceParams =
1647 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
1648 DE_NULL, // const void* pNext;
1649 0u // VkFenceCreateFlags flags;
1651 m_fence = createFence(vk, vkDevice, &fenceParams);
1656 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1657 VK_CHECK(vk.queueSubmit(queue, 1, &m_cmdBuffer.get(), *m_fence));
1658 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/));
1661 // Read back the result
1663 const VkDeviceSize imageSizeBytes = (VkDeviceSize)(sizeof(deUint32) * m_renderSize.x() * m_renderSize.y());
1664 const VkBufferCreateInfo readImageBufferParams =
1666 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1667 DE_NULL, // const void* pNext;
1668 imageSizeBytes, // VkDeviceSize size;
1669 VK_BUFFER_USAGE_TRANSFER_DESTINATION_BIT, // VkBufferUsageFlags usage;
1670 0u, // VkBufferCreateFlags flags;
1671 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1672 1u, // deUint32 queueFamilyCount;
1673 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1675 const Unique<VkBuffer> readImageBuffer(createBuffer(vk, vkDevice, &readImageBufferParams));
1676 const de::UniquePtr<Allocation> readImageBufferMemory(m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
1678 VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
1681 // Copy image to buffer
1682 const VkCmdBufferCreateInfo cmdBufferParams =
1684 VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, // VkStructureType sType;
1685 DE_NULL, // const void* pNext;
1686 *m_cmdPool, // VkCmdPool cmdPool;
1687 VK_CMD_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
1688 0u // VkCmdBufferCreateFlags flags;
1691 const VkCmdBufferBeginInfo cmdBufferBeginInfo =
1693 VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, // VkStructureType sType;
1694 DE_NULL, // const void* pNext;
1695 0u, // VkCmdBufferOptimizeFlags flags;
1696 DE_NULL, // VkRenderPass renderPass;
1697 0u, // deUint32 subpass;
1698 DE_NULL // VkFramebuffer framebuffer;
1701 const Move<VkCmdBuffer> cmdBuffer = createCommandBuffer(vk, vkDevice, &cmdBufferParams);
1703 const VkBufferImageCopy copyParams =
1705 0u, // VkDeviceSize bufferOffset;
1706 (deUint32)m_renderSize.x(), // deUint32 bufferRowLength;
1707 (deUint32)m_renderSize.y(), // deUint32 bufferImageHeight;
1709 VK_IMAGE_ASPECT_COLOR, // VkImageAspect aspect;
1710 0u, // deUint32 mipLevel;
1711 0u, // deUint32 arraySlice;
1712 1u, // deUint32 arraySize;
1713 }, // VkImageSubresourceCopy imageSubresource;
1714 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
1715 { m_renderSize.x(), m_renderSize.y(), 1u } // VkExtent3D imageExtent;
1718 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
1719 vk.cmdCopyImageToBuffer(*cmdBuffer, *m_colorImage, VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL, *readImageBuffer, 1u, ©Params);
1720 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
1722 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1723 VK_CHECK(vk.queueSubmit(queue, 1, &cmdBuffer.get(), *m_fence));
1724 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
1727 VK_CHECK(vk.mapMemory(vkDevice, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset(), imageSizeBytes, 0u, &imagePtr));
1728 invalidateMappedMemoryRange(vk, vkDevice, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset(), imageSizeBytes);
1730 const tcu::TextureFormat resultFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
1731 const tcu::ConstPixelBufferAccess resultAccess(resultFormat, m_renderSize.x(), m_renderSize.y(), 1, imagePtr);
1733 tcu::copy(result.getAccess(), resultAccess);
1735 vk.unmapMemory(vkDevice, readImageBufferMemory->getMemory());
1739 void ShaderRenderCaseInstance::computeVertexReference (tcu::Surface& result, const QuadGrid& quadGrid)
1742 const int width = result.getWidth();
1743 const int height = result.getHeight();
1744 const int gridSize = quadGrid.getGridSize();
1745 const int stride = gridSize + 1;
1746 const bool hasAlpha = true; // \todo [2015-09-07 elecro] add correct alpha check
1747 ShaderEvalContext evalCtx (quadGrid);
1749 // Evaluate color for each vertex.
1750 std::vector<tcu::Vec4> colors ((gridSize + 1) * (gridSize + 1));
1751 for (int y = 0; y < gridSize+1; y++)
1752 for (int x = 0; x < gridSize+1; x++)
1754 const float sx = (float)x / (float)gridSize;
1755 const float sy = (float)y / (float)gridSize;
1756 const int vtxNdx = ((y * (gridSize+1)) + x);
1758 evalCtx.reset(sx, sy);
1759 m_evaluator.evaluate(evalCtx);
1760 DE_ASSERT(!evalCtx.isDiscarded); // Discard is not available in vertex shader.
1761 tcu::Vec4 color = evalCtx.color;
1766 colors[vtxNdx] = color;
1770 for (int y = 0; y < gridSize; y++)
1771 for (int x = 0; x < gridSize; x++)
1773 const float x0 = (float)x / (float)gridSize;
1774 const float x1 = (float)(x + 1) / (float)gridSize;
1775 const float y0 = (float)y / (float)gridSize;
1776 const float y1 = (float)(y + 1) / (float)gridSize;
1778 const float sx0 = x0 * (float)width;
1779 const float sx1 = x1 * (float)width;
1780 const float sy0 = y0 * (float)height;
1781 const float sy1 = y1 * (float)height;
1782 const float oosx = 1.0f / (sx1 - sx0);
1783 const float oosy = 1.0f / (sy1 - sy0);
1785 const int ix0 = deCeilFloatToInt32(sx0 - 0.5f);
1786 const int ix1 = deCeilFloatToInt32(sx1 - 0.5f);
1787 const int iy0 = deCeilFloatToInt32(sy0 - 0.5f);
1788 const int iy1 = deCeilFloatToInt32(sy1 - 0.5f);
1790 const int v00 = (y * stride) + x;
1791 const int v01 = (y * stride) + x + 1;
1792 const int v10 = ((y + 1) * stride) + x;
1793 const int v11 = ((y + 1) * stride) + x + 1;
1794 const tcu::Vec4 c00 = colors[v00];
1795 const tcu::Vec4 c01 = colors[v01];
1796 const tcu::Vec4 c10 = colors[v10];
1797 const tcu::Vec4 c11 = colors[v11];
1799 //printf("(%d,%d) -> (%f..%f, %f..%f) (%d..%d, %d..%d)\n", x, y, sx0, sx1, sy0, sy1, ix0, ix1, iy0, iy1);
1801 for (int iy = iy0; iy < iy1; iy++)
1802 for (int ix = ix0; ix < ix1; ix++)
1804 DE_ASSERT(deInBounds32(ix, 0, width));
1805 DE_ASSERT(deInBounds32(iy, 0, height));
1807 const float sfx = (float)ix + 0.5f;
1808 const float sfy = (float)iy + 0.5f;
1809 const float fx1 = deFloatClamp((sfx - sx0) * oosx, 0.0f, 1.0f);
1810 const float fy1 = deFloatClamp((sfy - sy0) * oosy, 0.0f, 1.0f);
1812 // Triangle quad interpolation.
1813 const bool tri = fx1 + fy1 <= 1.0f;
1814 const float tx = tri ? fx1 : (1.0f-fx1);
1815 const float ty = tri ? fy1 : (1.0f-fy1);
1816 const tcu::Vec4& t0 = tri ? c00 : c11;
1817 const tcu::Vec4& t1 = tri ? c01 : c10;
1818 const tcu::Vec4& t2 = tri ? c10 : c01;
1819 const tcu::Vec4 color = t0 + (t1-t0)*tx + (t2-t0)*ty;
1821 result.setPixel(ix, iy, tcu::RGBA(color));
1826 void ShaderRenderCaseInstance::computeFragmentReference (tcu::Surface& result, const QuadGrid& quadGrid)
1829 const int width = result.getWidth();
1830 const int height = result.getHeight();
1831 const bool hasAlpha = true; // \todo [2015-09-07 elecro] add correct alpha check
1832 ShaderEvalContext evalCtx (quadGrid);
1835 for (int y = 0; y < height; y++)
1836 for (int x = 0; x < width; x++)
1838 const float sx = ((float)x + 0.5f) / (float)width;
1839 const float sy = ((float)y + 0.5f) / (float)height;
1841 evalCtx.reset(sx, sy);
1842 m_evaluator.evaluate(evalCtx);
1843 // Select either clear color or computed color based on discarded bit.
1844 tcu::Vec4 color = evalCtx.isDiscarded ? m_clearColor : evalCtx.color;
1849 result.setPixel(x, y, tcu::RGBA(color));
1853 bool ShaderRenderCaseInstance::compareImages (const tcu::Surface& resImage, const tcu::Surface& refImage, float errorThreshold)
1855 return tcu::fuzzyCompare(m_context.getTestContext().getLog(), "ComparisonResult", "Image comparison result", refImage, resImage, errorThreshold, tcu::COMPARE_LOG_RESULT);
1858 } // shaderrendercase