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 "tcuSurface.hpp"
41 #include "tcuVector.hpp"
42 #include "tcuTestLog.hpp"
43 #include "tcuTextureUtil.hpp"
46 #include "deFilePath.hpp"
47 #include "deUniquePtr.hpp"
49 #include "vkPlatform.hpp"
50 #include "vkStrUtil.hpp"
52 #include "vkRefUtil.hpp"
53 #include "vkQueryUtil.hpp"
54 #include "vkDeviceUtil.hpp"
61 namespace shaderrendercase
66 static const int GRID_SIZE = 2;
67 static const int MAX_RENDER_WIDTH = 128;
68 static const int MAX_RENDER_HEIGHT = 112;
69 static const tcu::Vec4 DEFAULT_CLEAR_COLOR = tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f);
76 QuadGrid (int gridSize,
79 const tcu::Vec4& constCoords,
80 const std::vector<tcu::Mat4>& userAttribTransforms,
81 const std::vector<TextureBinding>& textures);
84 int getGridSize (void) const { return m_gridSize; }
85 int getNumVertices (void) const { return m_numVertices; }
86 int getNumTriangles (void) const { return m_numTriangles; }
87 const tcu::Vec4& getConstCoords (void) const { return m_constCoords; }
88 const std::vector<tcu::Mat4> getUserAttribTransforms (void) const { return m_userAttribTransforms; }
89 const std::vector<TextureBinding>& getTextures (void) const { return m_textures; }
91 const tcu::Vec4* getPositions (void) const { return &m_positions[0]; }
92 const float* getAttribOne (void) const { return &m_attribOne[0]; }
93 const tcu::Vec4* getCoords (void) const { return &m_coords[0]; }
94 const tcu::Vec4* getUnitCoords (void) const { return &m_unitCoords[0]; }
96 const tcu::Vec4* getUserAttrib (int attribNdx) const { return &m_userAttribs[attribNdx][0]; }
97 const deUint16* getIndices (void) const { return &m_indices[0]; }
99 tcu::Vec4 getCoords (float sx, float sy) const;
100 tcu::Vec4 getUnitCoords (float sx, float sy) const;
102 int getNumUserAttribs (void) const { return (int)m_userAttribTransforms.size(); }
103 tcu::Vec4 getUserAttrib (int attribNdx, float sx, float sy) const;
106 const int m_gridSize;
107 const int m_numVertices;
108 const int m_numTriangles;
109 const tcu::Vec4 m_constCoords;
110 const std::vector<tcu::Mat4> m_userAttribTransforms;
112 const std::vector<TextureBinding> m_textures;
114 std::vector<tcu::Vec4> m_screenPos;
115 std::vector<tcu::Vec4> m_positions;
116 std::vector<tcu::Vec4> m_coords; //!< Near-unit coordinates, roughly [-2.0 .. 2.0].
117 std::vector<tcu::Vec4> m_unitCoords; //!< Positive-only coordinates [0.0 .. 1.5].
118 std::vector<float> m_attribOne;
119 std::vector<tcu::Vec4> m_userAttribs[ShaderEvalContext::MAX_TEXTURES];
120 std::vector<deUint16> m_indices;
123 QuadGrid::QuadGrid (int gridSize,
126 const tcu::Vec4& constCoords,
127 const std::vector<tcu::Mat4>& userAttribTransforms,
128 const std::vector<TextureBinding>& textures)
129 : m_gridSize (gridSize)
130 , m_numVertices ((gridSize + 1) * (gridSize + 1))
131 , m_numTriangles (gridSize * gridSize * 2)
132 , m_constCoords (constCoords)
133 , m_userAttribTransforms (userAttribTransforms)
134 , m_textures (textures)
136 const tcu::Vec4 viewportScale ((float)width, (float)height, 0.0f, 0.0f);
139 m_screenPos.resize(m_numVertices);
140 m_positions.resize(m_numVertices);
141 m_coords.resize(m_numVertices);
142 m_unitCoords.resize(m_numVertices);
143 m_attribOne.resize(m_numVertices);
146 for (int attrNdx = 0; attrNdx < DE_LENGTH_OF_ARRAY(m_userAttribs); attrNdx++)
147 m_userAttribs[attrNdx].resize(m_numVertices);
149 for (int y = 0; y < gridSize+1; y++)
150 for (int x = 0; x < gridSize+1; x++)
152 float sx = (float)x / (float)gridSize;
153 float sy = (float)y / (float)gridSize;
154 float fx = 2.0f * sx - 1.0f;
155 float fy = 2.0f * sy - 1.0f;
156 int vtxNdx = ((y * (gridSize+1)) + x);
158 m_positions[vtxNdx] = tcu::Vec4(fx, fy, 0.0f, 1.0f);
159 m_coords[vtxNdx] = getCoords(sx, sy);
160 m_unitCoords[vtxNdx] = getUnitCoords(sx, sy);
161 m_attribOne[vtxNdx] = 1.0f;
163 m_screenPos[vtxNdx] = tcu::Vec4(sx, sy, 0.0f, 1.0f) * viewportScale;
165 for (int attribNdx = 0; attribNdx < getNumUserAttribs(); attribNdx++)
166 m_userAttribs[attribNdx][vtxNdx] = getUserAttrib(attribNdx, sx, sy);
170 m_indices.resize(3 * m_numTriangles);
171 for (int y = 0; y < gridSize; y++)
172 for (int x = 0; x < gridSize; x++)
174 int stride = gridSize + 1;
175 int v00 = (y * stride) + x;
176 int v01 = (y * stride) + x + 1;
177 int v10 = ((y+1) * stride) + x;
178 int v11 = ((y+1) * stride) + x + 1;
180 int baseNdx = ((y * gridSize) + x) * 6;
181 m_indices[baseNdx + 0] = (deUint16)v10;
182 m_indices[baseNdx + 1] = (deUint16)v00;
183 m_indices[baseNdx + 2] = (deUint16)v01;
185 m_indices[baseNdx + 3] = (deUint16)v10;
186 m_indices[baseNdx + 4] = (deUint16)v01;
187 m_indices[baseNdx + 5] = (deUint16)v11;
191 QuadGrid::~QuadGrid (void)
195 inline tcu::Vec4 QuadGrid::getCoords (float sx, float sy) const
197 const float fx = 2.0f * sx - 1.0f;
198 const float fy = 2.0f * sy - 1.0f;
199 return tcu::Vec4(fx, fy, -fx + 0.33f*fy, -0.275f*fx - fy);
202 inline tcu::Vec4 QuadGrid::getUnitCoords (float sx, float sy) const
204 return tcu::Vec4(sx, sy, 0.33f*sx + 0.5f*sy, 0.5f*sx + 0.25f*sy);
207 inline tcu::Vec4 QuadGrid::getUserAttrib (int attribNdx, float sx, float sy) const
209 // homogeneous normalized screen-space coordinates
210 return m_userAttribTransforms[attribNdx] * tcu::Vec4(sx, sy, 0.0f, 1.0f);
215 TextureBinding::TextureBinding (const tcu::Archive& archive,
216 const char* filename,
218 const tcu::Sampler& sampler)
220 , m_sampler (sampler)
224 case TYPE_2D: m_binding.tex2D = loadTexture2D(archive, filename); break;
226 TCU_FAIL("Unsupported texture type");
230 tcu::Texture2D* TextureBinding::loadTexture2D (const tcu::Archive& archive, const char* filename)
232 std::string ext = de::FilePath(filename).getFileExtension();
236 // Uncompressed texture.
237 tcu::TextureLevel level;
238 tcu::ImageIO::loadPNG(level, archive, filename);
240 TCU_CHECK_INTERNAL(level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) ||
241 level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8));
243 // \todo [2015-10-08 elecro] for some reason we get better when using RGBA texture even in RGB case, this needs to be investigated
244 tcu::Texture2D* texture = new tcu::Texture2D(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), level.getWidth(), level.getHeight());
249 texture->allocLevel(0);
251 tcu::copy(texture->getLevel(0), level.getAccess());
253 catch (const std::exception&)
262 TCU_FAIL("Unsupported file format"); // TODO: maybe support pkm?
265 // ShaderEvalContext.
267 ShaderEvalContext::ShaderEvalContext (const QuadGrid& quadGrid)
268 : constCoords (quadGrid.getConstCoords())
269 , isDiscarded (false)
270 , m_quadGrid (quadGrid)
272 const std::vector<TextureBinding>& bindings = m_quadGrid.getTextures();
273 DE_ASSERT((int)bindings.size() <= MAX_TEXTURES);
275 // Fill in texture array.
276 for (int ndx = 0; ndx < (int)bindings.size(); ndx++)
278 const TextureBinding& binding = bindings[ndx];
280 if (binding.getType() == TextureBinding::TYPE_NONE)
283 textures[ndx].sampler = binding.getSampler();
285 switch (binding.getType())
287 case TextureBinding::TYPE_2D: textures[ndx].tex2D = binding.get2D(); break;
288 // \todo [2015-09-07 elecro] Add support for the other binding types
290 case TextureBinding::TYPE_CUBE_MAP: textures[ndx].texCube = &binding.getCube()->getRefTexture(); break;
291 case TextureBinding::TYPE_2D_ARRAY: textures[ndx].tex2DArray = &binding.get2DArray()->getRefTexture(); break;
292 case TextureBinding::TYPE_3D: textures[ndx].tex3D = &binding.get3D()->getRefTexture(); break;
295 TCU_THROW(InternalError, "Handling of texture binding type not implemented");
300 ShaderEvalContext::~ShaderEvalContext (void)
304 void ShaderEvalContext::reset (float sx, float sy)
307 color = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
311 coords = m_quadGrid.getCoords(sx, sy);
312 unitCoords = m_quadGrid.getUnitCoords(sx, sy);
314 // Compute user attributes.
315 const int numAttribs = m_quadGrid.getNumUserAttribs();
316 DE_ASSERT(numAttribs <= MAX_USER_ATTRIBS);
317 for (int attribNdx = 0; attribNdx < numAttribs; attribNdx++)
318 in[attribNdx] = m_quadGrid.getUserAttrib(attribNdx, sx, sy);
321 tcu::Vec4 ShaderEvalContext::texture2D (int unitNdx, const tcu::Vec2& texCoords)
323 if (textures[unitNdx].tex2D)
324 return textures[unitNdx].tex2D->sample(textures[unitNdx].sampler, texCoords.x(), texCoords.y(), 0.0f);
326 return tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
331 ShaderEvaluator::ShaderEvaluator (void)
332 : m_evalFunc(DE_NULL)
336 ShaderEvaluator::ShaderEvaluator (ShaderEvalFunc evalFunc)
337 : m_evalFunc(evalFunc)
341 ShaderEvaluator::~ShaderEvaluator (void)
345 void ShaderEvaluator::evaluate (ShaderEvalContext& ctx) const
347 DE_ASSERT(m_evalFunc);
353 UniformSetup::UniformSetup (void)
354 : m_setupFunc(DE_NULL)
358 UniformSetup::UniformSetup (UniformSetupFunc setupFunc)
359 : m_setupFunc(setupFunc)
363 UniformSetup::~UniformSetup (void)
367 void UniformSetup::setup (ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords) const
370 m_setupFunc(instance, constCoords);
375 ShaderRenderCase::ShaderRenderCase (tcu::TestContext& testCtx,
376 const std::string& name,
377 const std::string& description,
378 const bool isVertexCase,
379 const ShaderEvalFunc evalFunc,
380 const UniformSetup* uniformSetup,
381 const AttributeSetupFunc attribFunc)
382 : vkt::TestCase (testCtx, name, description)
383 , m_isVertexCase (isVertexCase)
384 , m_evaluator (new ShaderEvaluator(evalFunc))
385 , m_uniformSetup (uniformSetup ? uniformSetup : new UniformSetup())
386 , m_attribFunc (attribFunc)
389 ShaderRenderCase::ShaderRenderCase (tcu::TestContext& testCtx,
390 const std::string& name,
391 const std::string& description,
392 const bool isVertexCase,
393 const ShaderEvaluator* evaluator,
394 const UniformSetup* uniformSetup,
395 const AttributeSetupFunc attribFunc)
396 : vkt::TestCase (testCtx, name, description)
397 , m_isVertexCase (isVertexCase)
398 , m_evaluator (evaluator)
399 , m_uniformSetup (uniformSetup ? uniformSetup : new UniformSetup())
400 , m_attribFunc (attribFunc)
403 ShaderRenderCase::~ShaderRenderCase (void)
406 m_evaluator = DE_NULL;
407 delete m_uniformSetup;
408 m_uniformSetup = DE_NULL;
411 void ShaderRenderCase::initPrograms (vk::SourceCollections& programCollection) const
413 programCollection.glslSources.add("vert") << glu::VertexSource(m_vertShaderSource);
414 programCollection.glslSources.add("frag") << glu::FragmentSource(m_fragShaderSource);
417 TestInstance* ShaderRenderCase::createInstance (Context& context) const
419 DE_ASSERT(m_evaluator != DE_NULL);
420 DE_ASSERT(m_uniformSetup != DE_NULL);
421 return new ShaderRenderCaseInstance(context, m_isVertexCase, *m_evaluator, *m_uniformSetup, m_attribFunc);
424 // ShaderRenderCaseInstance.
426 ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context& context,
427 const bool isVertexCase,
428 const ShaderEvaluator& evaluator,
429 const UniformSetup& uniformSetup,
430 const AttributeSetupFunc attribFunc)
431 : vkt::TestInstance (context)
432 , m_clearColor (DEFAULT_CLEAR_COLOR)
433 , m_memAlloc (m_context.getDeviceInterface(), m_context.getDevice(), getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()))
434 , m_isVertexCase (isVertexCase)
435 , m_evaluator (evaluator)
436 , m_uniformSetup (uniformSetup)
437 , m_attribFunc (attribFunc)
438 , m_renderSize (100, 100)
439 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
443 ShaderRenderCaseInstance::~ShaderRenderCaseInstance (void)
447 tcu::TestStatus ShaderRenderCaseInstance::iterate (void)
452 const tcu::IVec2 viewportSize = getViewportSize();
453 const int width = viewportSize.x();
454 const int height = viewportSize.y();
456 QuadGrid quadGrid (m_isVertexCase ? GRID_SIZE : 4, width, height, tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f), m_userAttribTransforms, m_textures);
459 tcu::Surface resImage (width, height);
460 render(resImage, quadGrid);
462 // Compute reference.
463 tcu::Surface refImage (width, height);
465 computeVertexReference(refImage, quadGrid);
467 computeFragmentReference(refImage, quadGrid);
470 const bool compareOk = compareImages(resImage, refImage, 0.05f);
473 return tcu::TestStatus::pass("Result image matches reference");
475 return tcu::TestStatus::fail("Image mismatch");
478 void ShaderRenderCaseInstance::setupUniformData (deUint32 bindingLocation, deUint32 size, const void* dataPtr)
480 const VkDevice vkDevice = m_context.getDevice();
481 const DeviceInterface& vk = m_context.getDeviceInterface();
482 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
484 const VkBufferCreateInfo uniformBufferParams =
486 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
487 DE_NULL, // const void* pNext;
488 size, // VkDeviceSize size;
489 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, // VkBufferUsageFlags usage;
490 0u, // VkBufferCreateFlags flags;
491 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
492 1u, // deUint32 queueFamilyCount;
493 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
496 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &uniformBufferParams);
497 de::MovePtr<Allocation> alloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::Any);
498 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), 0));
501 VK_CHECK(vk.mapMemory(vkDevice, alloc->getMemory(), 0, size, 0, &bufferPtr));
502 deMemcpy(bufferPtr, dataPtr, size);
503 vk.unmapMemory(vkDevice, alloc->getMemory());
505 const VkBufferViewCreateInfo viewInfo =
507 VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, // VkStructureType sType;
508 DE_NULL, // void* pNext;
509 *buffer, // VkBuffer buffer;
510 VK_FORMAT_R32_SFLOAT, // VkFormat format;
511 0u, // VkDeviceSize offset;
512 size, // VkDeviceSize range;
515 Move<VkBufferView> bufferView = createBufferView(vk, vkDevice, &viewInfo);
517 // \todo [2015-10-09 elecro] remove the '_hack_padding' variable if the driver support small uniforms,
518 // that is for example one float big uniforms.
519 const deUint32 _hack_padding = size < 4 * sizeof(float) ? (deUint32)(3u * sizeof(float)) : 0u;
521 const VkDescriptorInfo descriptor =
523 bufferView.get(), // VkBufferView bufferView;
524 0, // VkSampler sampler;
525 0, // VkImageView imageView;
526 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
528 *buffer, // VkBuffer buffer;
529 0u, // VkDeviceSize offset;
530 size + _hack_padding, // VkDeviceSize range;
531 }, // VkDescriptorBufferInfo bufferInfo;
534 de::MovePtr<BufferUniform> uniformInfo(new BufferUniform());
535 uniformInfo->type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
536 uniformInfo->descriptor = descriptor;
537 uniformInfo->location = bindingLocation;
538 uniformInfo->buffer = VkBufferSp(new vk::Unique<VkBuffer>(buffer));
539 uniformInfo->bufferView = VkBufferViewSp(new vk::Unique<VkBufferView>(bufferView));
540 uniformInfo->alloc = AllocationSp(new de::UniquePtr<vk::Allocation>(alloc));
542 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniformInfo)));
545 void ShaderRenderCaseInstance::addUniform (deUint32 bindingLocation, vk::VkDescriptorType descriptorType, deUint32 dataSize, const void* data)
547 m_descriptorSetLayoutBuilder.addSingleBinding(descriptorType, vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT);
548 m_descriptorPoolBuilder.addType(descriptorType);
550 setupUniformData(bindingLocation, dataSize, data);
553 void ShaderRenderCaseInstance::addAttribute (deUint32 bindingLocation, vk::VkFormat format, deUint32 sizePerElement, deUint32 count, const void* dataPtr)
555 // Add binding specification
556 const deUint32 binding = (deUint32)m_vertexBindingDescription.size();
557 const VkVertexInputBindingDescription bindingDescription =
561 VK_VERTEX_INPUT_STEP_RATE_VERTEX
564 m_vertexBindingDescription.push_back(bindingDescription);
566 // Add location and format specification
567 const VkVertexInputAttributeDescription attributeDescription =
569 bindingLocation, // deUint32 location;
570 binding, // deUint32 binding;
571 format, // VkFormat format;
572 0u, // deUint32 offsetInBytes;
575 m_vertexattributeDescription.push_back(attributeDescription);
577 // Upload data to buffer
578 const VkDevice vkDevice = m_context.getDevice();
579 const DeviceInterface& vk = m_context.getDeviceInterface();
580 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
582 const VkDeviceSize inputSize = sizePerElement * count;
583 const VkBufferCreateInfo vertexBufferParams =
585 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
586 DE_NULL, // const void* pNext;
587 inputSize, // VkDeviceSize size;
588 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
589 0u, // VkBufferCreateFlags flags;
590 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
591 1u, // deUint32 queueFamilyCount;
592 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
595 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &vertexBufferParams);
596 de::MovePtr<vk::Allocation> alloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::Any);
598 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), 0));
601 VK_CHECK(vk.mapMemory(vkDevice, alloc->getMemory(), 0, inputSize, 0, &bufferPtr));
602 deMemcpy(bufferPtr, dataPtr, inputSize);
603 vk.unmapMemory(vkDevice, alloc->getMemory());
605 m_vertexBuffers.push_back(VkBufferSp(new vk::Unique<VkBuffer>(buffer)));
606 m_vertexBufferAllocs.push_back(AllocationSp(new de::UniquePtr<vk::Allocation>(alloc)));
609 void ShaderRenderCaseInstance::useAttribute (deUint32 bindingLocation, BaseAttributeType type)
611 const EnabledBaseAttribute attribute =
616 m_enabledBaseAttributes.push_back(attribute);
619 void ShaderRenderCaseInstance::setup (void)
623 void ShaderRenderCaseInstance::setupUniforms (const tcu::Vec4& constCoords)
625 m_uniformSetup.setup(*this, constCoords);
628 void ShaderRenderCaseInstance::useUniform (deUint32 bindingLocation, BaseUniformType type)
630 #define UNIFORM_CASE(type, value) case type: addUniform(bindingLocation, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, value); break
635 UNIFORM_CASE(UB_FALSE, 0);
636 UNIFORM_CASE(UB_TRUE, 1);
639 UNIFORM_CASE(UB4_FALSE, tcu::Vec4(0));
640 UNIFORM_CASE(UB4_TRUE, tcu::Vec4(1));
643 UNIFORM_CASE(UI_ZERO, 0);
644 UNIFORM_CASE(UI_ONE, 1);
645 UNIFORM_CASE(UI_TWO, 2);
646 UNIFORM_CASE(UI_THREE, 3);
647 UNIFORM_CASE(UI_FOUR, 4);
648 UNIFORM_CASE(UI_FIVE, 5);
649 UNIFORM_CASE(UI_SIX, 6);
650 UNIFORM_CASE(UI_SEVEN, 7);
651 UNIFORM_CASE(UI_EIGHT, 8);
652 UNIFORM_CASE(UI_ONEHUNDREDONE, 101);
655 UNIFORM_CASE(UI2_MINUS_ONE, tcu::IVec2(-1));
656 UNIFORM_CASE(UI2_ZERO, tcu::IVec2(0));
657 UNIFORM_CASE(UI2_ONE, tcu::IVec2(1));
658 UNIFORM_CASE(UI2_TWO, tcu::IVec2(2));
659 UNIFORM_CASE(UI2_THREE, tcu::IVec2(3));
660 UNIFORM_CASE(UI2_FOUR, tcu::IVec2(4));
661 UNIFORM_CASE(UI2_FIVE, tcu::IVec2(5));
664 UNIFORM_CASE(UI3_MINUS_ONE, tcu::IVec3(-1));
665 UNIFORM_CASE(UI3_ZERO, tcu::IVec3(0));
666 UNIFORM_CASE(UI3_ONE, tcu::IVec3(1));
667 UNIFORM_CASE(UI3_TWO, tcu::IVec3(2));
668 UNIFORM_CASE(UI3_THREE, tcu::IVec3(3));
669 UNIFORM_CASE(UI3_FOUR, tcu::IVec3(4));
670 UNIFORM_CASE(UI3_FIVE, tcu::IVec3(5));
673 UNIFORM_CASE(UI4_MINUS_ONE, tcu::IVec4(-1));
674 UNIFORM_CASE(UI4_ZERO, tcu::IVec4(0));
675 UNIFORM_CASE(UI4_ONE, tcu::IVec4(1));
676 UNIFORM_CASE(UI4_TWO, tcu::IVec4(2));
677 UNIFORM_CASE(UI4_THREE, tcu::IVec4(3));
678 UNIFORM_CASE(UI4_FOUR, tcu::IVec4(4));
679 UNIFORM_CASE(UI4_FIVE, tcu::IVec4(5));
682 UNIFORM_CASE(UF_ZERO, 0.0f);
683 UNIFORM_CASE(UF_ONE, 1.0f);
684 UNIFORM_CASE(UF_TWO, 2.0f);
685 UNIFORM_CASE(UF_THREE, 3.0f);
686 UNIFORM_CASE(UF_FOUR, 4.0f);
687 UNIFORM_CASE(UF_FIVE, 5.0f);
688 UNIFORM_CASE(UF_SIX, 6.0f);
689 UNIFORM_CASE(UF_SEVEN, 7.0f);
690 UNIFORM_CASE(UF_EIGHT, 8.0f);
692 UNIFORM_CASE(UF_HALF, 1.0f / 2.0f);
693 UNIFORM_CASE(UF_THIRD, 1.0f / 3.0f);
694 UNIFORM_CASE(UF_FOURTH, 1.0f / 4.0f);
695 UNIFORM_CASE(UF_FIFTH, 1.0f / 5.0f);
696 UNIFORM_CASE(UF_SIXTH, 1.0f / 6.0f);
697 UNIFORM_CASE(UF_SEVENTH, 1.0f / 7.0f);
698 UNIFORM_CASE(UF_EIGHTH, 1.0f / 8.0f);
701 UNIFORM_CASE(UV2_MINUS_ONE, tcu::Vec2(-1.0f));
702 UNIFORM_CASE(UV2_ZERO, tcu::Vec2(0.0f));
703 UNIFORM_CASE(UV2_ONE, tcu::Vec2(1.0f));
704 UNIFORM_CASE(UV2_TWO, tcu::Vec2(2.0f));
705 UNIFORM_CASE(UV2_THREE, tcu::Vec2(3.0f));
707 UNIFORM_CASE(UV2_HALF, tcu::Vec2(1.0f / 2.0f));
710 UNIFORM_CASE(UV3_MINUS_ONE, tcu::Vec3(-1.0f));
711 UNIFORM_CASE(UV3_ZERO, tcu::Vec3(0.0f));
712 UNIFORM_CASE(UV3_ONE, tcu::Vec3(1.0f));
713 UNIFORM_CASE(UV3_TWO, tcu::Vec3(2.0f));
714 UNIFORM_CASE(UV3_THREE, tcu::Vec3(3.0f));
716 UNIFORM_CASE(UV3_HALF, tcu::Vec3(1.0f / 2.0f));
719 UNIFORM_CASE(UV4_MINUS_ONE, tcu::Vec4(-1.0f));
720 UNIFORM_CASE(UV4_ZERO, tcu::Vec4(0.0f));
721 UNIFORM_CASE(UV4_ONE, tcu::Vec4(1.0f));
722 UNIFORM_CASE(UV4_TWO, tcu::Vec4(2.0f));
723 UNIFORM_CASE(UV4_THREE, tcu::Vec4(3.0f));
725 UNIFORM_CASE(UV4_HALF, tcu::Vec4(1.0f / 2.0f));
727 UNIFORM_CASE(UV4_BLACK, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
728 UNIFORM_CASE(UV4_GRAY, tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f));
729 UNIFORM_CASE(UV4_WHITE, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
732 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Unknown Uniform type: " << type << tcu::TestLog::EndMessage;
739 const tcu::IVec2 ShaderRenderCaseInstance::getViewportSize (void) const
741 return tcu::IVec2(de::min(m_renderSize.x(), MAX_RENDER_WIDTH),
742 de::min(m_renderSize.y(), MAX_RENDER_HEIGHT));
745 Move<VkImage> ShaderRenderCaseInstance::createImage2D (const tcu::Texture2D& texture, const VkFormat format)
747 const VkDevice vkDevice = m_context.getDevice();
748 const DeviceInterface& vk = m_context.getDeviceInterface();
749 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
751 const VkImageCreateInfo imageCreateInfo =
753 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
754 DE_NULL, // const void* pnext;
755 VK_IMAGE_TYPE_2D, // VkImageType imageType;
756 format, // VkFormat format;
757 { texture.getWidth(), texture.getHeight(), 1 }, // VkExtend3D extent;
758 1u, // deUint32 mipLevels;
759 1u, // deUint32 arraySize;
760 1u, // deUint32 samples;
761 VK_IMAGE_TILING_LINEAR, // VkImageTiling tiling;
762 VK_IMAGE_USAGE_SAMPLED_BIT, // VkImageUsageFlags usage;
763 0, // VkImageCreateFlags flags;
764 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
765 1, // deuint32 queueFamilyCount;
766 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
767 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
770 Move<VkImage> vkTexture = createImage(vk, vkDevice, &imageCreateInfo);
774 void ShaderRenderCaseInstance::useSampler2D (deUint32 bindingLocation, deUint32 textureID)
776 const VkDevice vkDevice = m_context.getDevice();
777 const DeviceInterface& vk = m_context.getDeviceInterface();
779 DE_ASSERT(textureID < m_textures.size());
781 const TextureBinding& textureBinding = m_textures[textureID];
782 const tcu::Texture2D* refTexture = textureBinding.get2D();
783 const tcu::Sampler& refSampler = textureBinding.getSampler();
784 const VkFormat format = refTexture->getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
785 ? VK_FORMAT_R8G8B8A8_UNORM
786 : VK_FORMAT_R8G8B8_UNORM;
788 DE_ASSERT(refTexture != DE_NULL);
789 // Create & alloc the image
790 Move<VkImage> vkTexture(createImage2D(*refTexture, format));
792 // Allocate and bind color image memory
793 de::MovePtr<Allocation> allocation = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *vkTexture), MemoryRequirement::Any);
794 VK_CHECK(vk.bindImageMemory(vkDevice, *vkTexture, allocation->getMemory(), allocation->getOffset()));
796 const VkImageSubresource subres =
798 VK_IMAGE_ASPECT_COLOR, // VkImageAspect aspect;
799 0u, // deUint32 mipLevel;
800 0u // deUint32 arraySlice
803 VkSubresourceLayout layout;
804 VK_CHECK(vk.getImageSubresourceLayout(vkDevice, *vkTexture, &subres, &layout));
807 VK_CHECK(vk.mapMemory(vkDevice, allocation->getMemory(), allocation->getOffset(), layout.size, 0u, &imagePtr));
809 tcu::ConstPixelBufferAccess access = refTexture->getLevel(0);
810 tcu::PixelBufferAccess destAccess(refTexture->getFormat(), refTexture->getWidth(), refTexture->getHeight(), 1, imagePtr);
812 tcu::copy(destAccess, access);
814 const vk::VkMappedMemoryRange range =
816 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
817 DE_NULL, // const void* pNext;
818 allocation->getMemory(), // VkDeviceMemory mem;
819 0, // VkDeviceSize offset;
820 layout.size, // VkDeviceSize size;
823 VK_CHECK(vk.flushMappedMemoryRanges(vkDevice, 1u, &range));
824 vk.unmapMemory(vkDevice, allocation->getMemory());
828 const VkSamplerCreateInfo samplerParams =
830 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
832 getVkTexFilter(refSampler.magFilter),
833 getVkTexFilter(refSampler.minFilter),
834 getVkTexMipmapMode(refSampler.minFilter),
835 getVkWrapMode(refSampler.wrapS),
836 getVkWrapMode(refSampler.wrapT),
837 getVkWrapMode(refSampler.wrapR),
838 refSampler.lodThreshold,
840 (refSampler.compare != tcu::Sampler::COMPAREMODE_NONE),
841 getVkCompareMode(refSampler.compare),
844 VK_BORDER_COLOR_INT_OPAQUE_WHITE,
848 Move<VkSampler> sampler = createSampler(vk, vkDevice, &samplerParams);
850 const VkImageViewCreateInfo viewParams =
852 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
853 NULL, // const voide* pNexŧ;
854 *vkTexture, // VkImage image;
855 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
856 format, // VkFormat format;
858 VK_CHANNEL_SWIZZLE_R, // VkChannelSwizzle r;
859 VK_CHANNEL_SWIZZLE_G, // VkChannelSwizzle g;
860 VK_CHANNEL_SWIZZLE_B, // VkChannelSwizzle b;
861 VK_CHANNEL_SWIZZLE_A // VkChannelSwizzle a;
862 }, // VkChannelMapping channels;
864 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
865 0, // deUint32 baseMipLevel;
866 1, // deUint32 mipLevels;
867 0, // deUint32 baseArraySlice;
868 1 // deUint32 arraySize;
869 }, // VkImageSubresourceRange subresourceRange;
870 0u // VkImageViewCreateFlags flags;
873 Move<VkImageView> imageView = createImageView(vk, vkDevice, &viewParams);
875 const vk::VkDescriptorInfo descriptor =
877 0, // VkBufferView bufferView;
878 sampler.get(), // VkSampler sampler;
879 imageView.get(), // VkImageView imageView;
880 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
881 {0, 0, 0}, // VkDescriptorBufferInfo bufferInfo;
884 de::MovePtr<SamplerUniform> uniform(new SamplerUniform());
885 uniform->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
886 uniform->descriptor = descriptor;
887 uniform->location = bindingLocation;
888 uniform->image = VkImageSp(new vk::Unique<VkImage>(vkTexture));
889 uniform->imageView = VkImageViewSp(new vk::Unique<VkImageView>(imageView));
890 uniform->sampler = VkSamplerSp(new vk::Unique<VkSampler>(sampler));
891 uniform->alloc = AllocationSp(new de::UniquePtr<vk::Allocation>(allocation));
893 m_descriptorSetLayoutBuilder.addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, vk::VK_SHADER_STAGE_FRAGMENT_BIT, &uniform->descriptor.sampler);
894 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
896 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniform)));
899 void ShaderRenderCaseInstance::setupDefaultInputs (const QuadGrid& quadGrid)
901 /* Configuration of the vertex input attributes:
902 a_position is at location 0
903 a_coords is at location 1
904 a_unitCoords is at location 2
905 a_one is at location 3
907 User attributes starts from at the location 4.
909 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getPositions());
910 addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getCoords());
911 addAttribute(2u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUnitCoords());
912 addAttribute(3u, VK_FORMAT_R32_SFLOAT, sizeof(float), quadGrid.getNumVertices(), quadGrid.getAttribOne());
916 BaseAttributeType type;
928 BaseAttributeType matrixType;
944 for (size_t attrNdx = 0; attrNdx < m_enabledBaseAttributes.size(); attrNdx++)
946 for (int userNdx = 0; userNdx < DE_LENGTH_OF_ARRAY(userAttributes); userNdx++)
948 if (userAttributes[userNdx].type != m_enabledBaseAttributes[attrNdx].type)
951 addAttribute(m_enabledBaseAttributes[attrNdx].location, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUserAttrib(userNdx));
954 for (int matNdx = 0; matNdx < DE_LENGTH_OF_ARRAY(matrices); matNdx++)
957 if (matrices[matNdx].matrixType != m_enabledBaseAttributes[attrNdx].type)
960 const int numCols = matrices[matNdx].numCols;
962 for (int colNdx = 0; colNdx < numCols; colNdx++)
964 addAttribute(m_enabledBaseAttributes[attrNdx].location + colNdx, VK_FORMAT_R32G32B32A32_SFLOAT, 4 * sizeof(float), quadGrid.getNumVertices(), quadGrid.getUserAttrib(colNdx));
970 void ShaderRenderCaseInstance::render (tcu::Surface& result, const QuadGrid& quadGrid)
972 const VkDevice vkDevice = m_context.getDevice();
973 const DeviceInterface& vk = m_context.getDeviceInterface();
974 const VkQueue queue = m_context.getUniversalQueue();
975 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
977 // Create color image
979 const VkImageCreateInfo colorImageParams =
981 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
982 DE_NULL, // const void* pNext;
983 VK_IMAGE_TYPE_2D, // VkImageType imageType;
984 m_colorFormat, // VkFormat format;
985 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent;
986 1u, // deUint32 mipLevels;
987 1u, // deUint32 arraySize;
988 1u, // deUint32 samples;
989 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
990 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT, // VkImageUsageFlags usage;
991 0u, // VkImageCreateFlags flags;
992 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
993 1u, // deUint32 queueFamilyCount;
994 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
995 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
998 m_colorImage = createImage(vk, vkDevice, &colorImageParams);
1000 // Allocate and bind color image memory
1001 m_colorImageAlloc = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::HostVisible);
1002 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), 0));
1005 // Create color attachment view
1007 const VkImageViewCreateInfo colorImageViewParams =
1009 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1010 DE_NULL, // const void* pNext;
1011 *m_colorImage, // VkImage image;
1012 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
1013 m_colorFormat, // VkFormat format;
1015 VK_CHANNEL_SWIZZLE_R, // VkChannelSwizzle r;
1016 VK_CHANNEL_SWIZZLE_G, // VkChannelSwizzle g;
1017 VK_CHANNEL_SWIZZLE_B, // VkChannelSwizzle b;
1018 VK_CHANNEL_SWIZZLE_A // VkChannelSwizzle a;
1019 }, // VkChannelMapping channels;
1021 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1022 0, // deUint32 baseMipLevel;
1023 1, // deUint32 mipLevels;
1024 0, // deUint32 baseArraySlice;
1025 1 // deUint32 arraySize;
1026 }, // VkImageSubresourceRange subresourceRange;
1027 0u // VkImageViewCreateFlags flags;
1030 m_colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
1033 // Create render pass
1035 const VkAttachmentDescription colorAttachmentDescription =
1037 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION, // VkStructureType sType;
1038 DE_NULL, // const void* pNext;
1039 m_colorFormat, // VkFormat format;
1040 1u, // deUint32 samples;
1041 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
1042 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
1043 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
1044 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
1045 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
1046 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
1047 0u, // VkAttachmentDescriptorFlags flags;
1050 const VkAttachmentDescription attachments[1] =
1052 colorAttachmentDescription
1055 const VkAttachmentReference colorAttachmentReference =
1057 0u, // deUint32 attachment;
1058 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
1061 const VkSubpassDescription subpassDescription =
1063 VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION, // VkStructureType sType;
1064 DE_NULL, // constvoid* pNext;
1065 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
1066 0u, // VkSubpassDescriptionFlags flags;
1067 0u, // deUint32 inputCount;
1068 DE_NULL, // constVkAttachmentReference* pInputAttachments;
1069 1u, // deUint32 colorCount;
1070 &colorAttachmentReference, // constVkAttachmentReference* pColorAttachments;
1071 DE_NULL, // constVkAttachmentReference* pResolveAttachments;
1072 { ~0u, VK_IMAGE_LAYOUT_GENERAL }, // VkAttachmentReference depthStencilAttachment;
1073 0u, // deUint32 preserveCount;
1074 DE_NULL // constVkAttachmentReference* pPreserveAttachments;
1077 const VkRenderPassCreateInfo renderPassParams =
1079 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
1080 DE_NULL, // const void* pNext;
1081 1u, // deUint32 attachmentCount;
1082 attachments, // const VkAttachmentDescription* pAttachments;
1083 1u, // deUint32 subpassCount;
1084 &subpassDescription, // const VkSubpassDescription* pSubpasses;
1085 0u, // deUint32 dependencyCount;
1086 DE_NULL // const VkSubpassDependency* pDependencies;
1089 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
1092 // Create framebuffer
1094 const VkFramebufferCreateInfo framebufferParams =
1096 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
1097 DE_NULL, // const void* pNext;
1098 *m_renderPass, // VkRenderPass renderPass;
1099 1u, // deUint32 attachmentCount;
1100 &*m_colorImageView, // const VkImageView* pAttachments;
1101 (deUint32)m_renderSize.x(), // deUint32 width;
1102 (deUint32)m_renderSize.y(), // deUint32 height;
1103 1u // deUint32 layers;
1106 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
1109 // Create descriptors
1111 setupUniforms(quadGrid.getConstCoords());
1113 m_descriptorSetLayout = m_descriptorSetLayoutBuilder.build(vk, vkDevice);
1114 m_descriptorPool = m_descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1u);
1115 m_descriptorSet = allocDescriptorSet(vk, vkDevice, *m_descriptorPool, VK_DESCRIPTOR_SET_USAGE_STATIC, *m_descriptorSetLayout);
1117 for(deUint32 i = 0; i < m_uniformInfos.size(); i++)
1119 const UniformInfo* uniformInfo = m_uniformInfos[i].get()->get();
1120 deUint32 location = uniformInfo->location;
1121 m_descriptorSetUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &uniformInfo->descriptor);
1124 m_descriptorSetUpdateBuilder.update(vk, vkDevice);
1127 // Create pipeline layout
1129 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1131 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1132 DE_NULL, // const void* pNext;
1133 1u, // deUint32 descriptorSetCount;
1134 &*m_descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
1135 0u, // deUint32 pushConstantRangeCount;
1136 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
1139 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1144 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
1145 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
1147 const VkShaderCreateInfo vertexShaderParams =
1149 VK_STRUCTURE_TYPE_SHADER_CREATE_INFO, // VkStructureType sType;
1150 DE_NULL, // const void* pNext;
1151 *m_vertexShaderModule, // VkShaderModule module;
1152 "main", // const char* pName;
1153 0u, // VkShaderCreateFlags flags;
1154 VK_SHADER_STAGE_VERTEX, // VkShaderStage stage;
1157 const VkShaderCreateInfo fragmentShaderParams =
1159 VK_STRUCTURE_TYPE_SHADER_CREATE_INFO, // VkStructureType sType;
1160 DE_NULL, // const void* pNext;
1161 *m_fragmentShaderModule, // VkShaderModule module;
1162 "main", // const char* pName;
1163 0u, // VkShaderCreateFlags flags;
1164 VK_SHADER_STAGE_FRAGMENT, // VkShaderStage stage;
1167 m_vertexShader = createShader(vk, vkDevice, &vertexShaderParams);
1168 m_fragmentShader= createShader(vk, vkDevice, &fragmentShaderParams);
1173 const VkPipelineShaderStageCreateInfo shaderStageParams[2] =
1176 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1177 DE_NULL, // const void* pNext;
1178 VK_SHADER_STAGE_VERTEX, // VkShaderStage stage;
1179 *m_vertexShader, // VkShader shader;
1180 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1183 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1184 DE_NULL, // const void* pNext;
1185 VK_SHADER_STAGE_FRAGMENT, // VkShaderStage stage;
1186 *m_fragmentShader, // VkShader shader;
1187 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1191 // Add base attributes
1193 // Add test case specific attributes
1195 m_attribFunc(*this, quadGrid.getNumVertices());
1197 setupDefaultInputs(quadGrid);
1199 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
1201 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1202 DE_NULL, // const void* pNext;
1203 (deUint32)m_vertexBindingDescription.size(), // deUint32 bindingCount;
1204 &m_vertexBindingDescription[0], // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1205 (deUint32)m_vertexattributeDescription.size(), // deUint32 attributeCount;
1206 &m_vertexattributeDescription[0], // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1209 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
1211 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
1212 DE_NULL, // const void* pNext;
1213 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology;
1214 false // VkBool32 primitiveRestartEnable;
1217 const VkViewport viewport =
1219 0.0f, // float originX;
1220 0.0f, // float originY;
1221 (float)m_renderSize.x(), // float width;
1222 (float)m_renderSize.y(), // float height;
1223 0.0f, // float minDepth;
1224 1.0f // float maxDepth;
1227 const VkRect2D scissor =
1232 }, // VkOffset2D offset;
1234 m_renderSize.x(), // deUint32 width;
1235 m_renderSize.y(), // deUint32 height;
1236 }, // VkExtent2D extent;
1239 const VkPipelineViewportStateCreateInfo viewportStateParams =
1241 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
1242 DE_NULL, // const void* pNext;
1243 1u, // deUint32 viewportCount;
1244 &viewport, // const VkViewport* pViewports;
1245 1u, // deUint32 scissorsCount;
1246 &scissor, // const VkRect2D* pScissors;
1249 const VkPipelineRasterStateCreateInfo rasterStateParams =
1251 VK_STRUCTURE_TYPE_PIPELINE_RASTER_STATE_CREATE_INFO, // VkStructureType sType;
1252 DE_NULL, // const void* pNext;
1253 false, // VkBool32 depthClipEnable;
1254 false, // VkBool32 rasterizerDiscardEnable;
1255 VK_FILL_MODE_SOLID, // VkFillMode fillMode;
1256 VK_CULL_MODE_NONE, // VkCullMode cullMode;
1257 VK_FRONT_FACE_CCW, // VkFrontFace frontFace;
1258 false, // VkBool32 depthBiasEnable;
1259 0.0f, // float depthBias;
1260 0.0f, // float depthBiasClamp;
1261 0.0f, // float slopeScaledDepthBias;
1262 1.0f, // float lineWidth;
1265 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
1267 false, // VkBool32 blendEnable;
1268 VK_BLEND_ONE, // VkBlend srcBlendColor;
1269 VK_BLEND_ZERO, // VkBlend destBlendColor;
1270 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
1271 VK_BLEND_ONE, // VkBlend srcBlendAlpha;
1272 VK_BLEND_ZERO, // VkBlend destBlendAlpha;
1273 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
1274 VK_CHANNEL_R_BIT | VK_CHANNEL_G_BIT | VK_CHANNEL_B_BIT | VK_CHANNEL_A_BIT // VkChannelFlags channelWriteMask;
1277 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
1279 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1280 DE_NULL, // const void* pNext;
1281 false, // VkBool32 alphaToCoverageEnable;
1282 false, // VkBool32 alphaToOneEnable;
1283 false, // VkBool32 logicOpEnable;
1284 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
1285 1u, // deUint32 attachmentCount;
1286 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
1287 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4];
1290 const VkPipelineDynamicStateCreateInfo dynamicStateInfo =
1292 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
1293 DE_NULL, // const void* pNext;
1294 0u, // deUint32 dynamicStateCount;
1295 DE_NULL // const VkDynamicState* pDynamicStates;
1298 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
1300 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
1301 DE_NULL, // const void* pNext;
1302 2u, // deUint32 stageCount;
1303 shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages;
1304 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
1305 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
1306 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
1307 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
1308 &rasterStateParams, // const VkPipelineRasterStateCreateInfo* pRasterState;
1309 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
1310 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
1311 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
1312 &dynamicStateInfo, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
1313 0u, // VkPipelineCreateFlags flags;
1314 *m_pipelineLayout, // VkPipelineLayout layout;
1315 *m_renderPass, // VkRenderPass renderPass;
1316 0u, // deUint32 subpass;
1317 0u, // VkPipeline basePipelineHandle;
1318 0u // deInt32 basePipelineIndex;
1321 m_graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
1324 // Create vertex indices buffer
1326 const VkDeviceSize indiceBufferSize = quadGrid.getNumTriangles() * 3 * sizeof(deUint16);
1327 const VkBufferCreateInfo indiceBufferParams =
1329 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1330 DE_NULL, // const void* pNext;
1331 indiceBufferSize, // VkDeviceSize size;
1332 VK_BUFFER_USAGE_INDEX_BUFFER_BIT, // VkBufferUsageFlags usage;
1333 0u, // VkBufferCreateFlags flags;
1334 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1335 1u, // deUint32 queueFamilyCount;
1336 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1339 m_indiceBuffer = createBuffer(vk, vkDevice, &indiceBufferParams);
1340 m_indiceBufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_indiceBuffer), MemoryRequirement::HostVisible);
1342 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_indiceBuffer, m_indiceBufferAlloc->getMemory(), 0));
1344 // Load vertice indices into buffer
1346 VK_CHECK(vk.mapMemory(vkDevice, m_indiceBufferAlloc->getMemory(), 0, indiceBufferSize, 0, &bufferPtr));
1347 deMemcpy(bufferPtr, quadGrid.getIndices(), indiceBufferSize);
1348 vk.unmapMemory(vkDevice, m_indiceBufferAlloc->getMemory());
1351 // Create command pool
1353 const VkCmdPoolCreateInfo cmdPoolParams =
1355 VK_STRUCTURE_TYPE_CMD_POOL_CREATE_INFO, // VkStructureType sType;
1356 DE_NULL, // const void* pNext;
1357 queueFamilyIndex, // deUint32 queueFamilyIndex;
1358 VK_CMD_POOL_CREATE_TRANSIENT_BIT // VkCmdPoolCreateFlags flags;
1361 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1364 // Create command buffer
1366 const VkCmdBufferCreateInfo cmdBufferParams =
1368 VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, // VkStructureType sType;
1369 DE_NULL, // const void* pNext;
1370 *m_cmdPool, // VkCmdPool cmdPool;
1371 VK_CMD_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
1372 0u // VkCmdBufferCreateFlags flags;
1375 const VkCmdBufferBeginInfo cmdBufferBeginInfo =
1377 VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, // VkStructureType sType;
1378 DE_NULL, // const void* pNext;
1379 0u, // VkCmdBufferOptimizeFlags flags;
1380 DE_NULL, // VkRenderPass renderPass;
1381 0u, // deUint32 subpass;
1382 DE_NULL // VkFramebuffer framebuffer;
1385 const VkClearValue clearValues =
1393 const VkRenderPassBeginInfo renderPassBeginInfo =
1395 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO , // VkStructureType sType;
1396 DE_NULL, // const void* pNext;
1397 *m_renderPass, // VkRenderPass renderPass;
1398 *m_framebuffer, // VkFramebuffer framebuffer;
1399 { 0, 0, m_renderSize.x(), m_renderSize.y() }, // VkRect2D renderArea;
1400 1, // deUint32 clearValueCount;
1401 &clearValues, // const VkClearValue* pClearValues;
1404 m_cmdBuffer = createCommandBuffer(vk, vkDevice, &cmdBufferParams);
1406 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1408 // Add texture barriers
1409 std::vector<VkImageMemoryBarrier> barriers;
1410 std::vector<void*> barrierPtrs;
1412 for(deUint32 i = 0; i < m_uniformInfos.size(); i++)
1414 const UniformInfo* uniformInfo = m_uniformInfos[i].get()->get();
1416 if (uniformInfo->type != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
1421 const SamplerUniform* sampler = static_cast<const SamplerUniform*>(uniformInfo);
1423 VkImageMemoryBarrier textureBarrier =
1425 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
1427 VK_MEMORY_OUTPUT_HOST_WRITE_BIT | VK_MEMORY_OUTPUT_TRANSFER_BIT,
1429 VK_IMAGE_LAYOUT_UNDEFINED,
1430 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
1433 sampler->image->get(),
1435 VK_IMAGE_ASPECT_COLOR_BIT,
1443 barriers.push_back(textureBarrier);
1444 barrierPtrs.push_back((void*)&barriers.back());
1447 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, (deUint32)barrierPtrs.size(), (const void * const*)&barrierPtrs[0]);
1449 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_RENDER_PASS_CONTENTS_INLINE);
1451 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
1452 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &*m_descriptorSet, 0u, DE_NULL);
1453 vk.cmdBindIndexBuffer(*m_cmdBuffer, *m_indiceBuffer, 0, VK_INDEX_TYPE_UINT16);
1456 const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size();
1457 const std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0);
1459 std::vector<VkBuffer> buffers(numberOfVertexAttributes);
1460 for (size_t i = 0; i < numberOfVertexAttributes; i++)
1462 buffers[i] = m_vertexBuffers[i].get()->get();
1465 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]);
1466 vk.cmdDrawIndexed(*m_cmdBuffer, quadGrid.getNumTriangles() * 3, 1, 0, 0, 0);
1468 vk.cmdEndRenderPass(*m_cmdBuffer);
1469 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1474 const VkFenceCreateInfo fenceParams =
1476 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
1477 DE_NULL, // const void* pNext;
1478 0u // VkFenceCreateFlags flags;
1480 m_fence = createFence(vk, vkDevice, &fenceParams);
1485 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1486 VK_CHECK(vk.queueSubmit(queue, 1, &m_cmdBuffer.get(), *m_fence));
1487 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/));
1490 // Read back the result
1492 const VkDeviceSize imageSizeBytes = (VkDeviceSize)(sizeof(deUint32) * m_renderSize.x() * m_renderSize.y());
1493 const VkBufferCreateInfo readImageBufferParams =
1495 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1496 DE_NULL, // const void* pNext;
1497 imageSizeBytes, // VkDeviceSize size;
1498 VK_BUFFER_USAGE_TRANSFER_DESTINATION_BIT, // VkBufferUsageFlags usage;
1499 0u, // VkBufferCreateFlags flags;
1500 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1501 1u, // deUint32 queueFamilyCount;
1502 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1504 const Unique<VkBuffer> readImageBuffer(createBuffer(vk, vkDevice, &readImageBufferParams));
1505 const de::UniquePtr<Allocation> readImageBufferMemory(m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
1507 VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
1510 // Copy image to buffer
1511 const VkCmdBufferCreateInfo cmdBufferParams =
1513 VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, // VkStructureType sType;
1514 DE_NULL, // const void* pNext;
1515 *m_cmdPool, // VkCmdPool cmdPool;
1516 VK_CMD_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
1517 0u // VkCmdBufferCreateFlags flags;
1520 const VkCmdBufferBeginInfo cmdBufferBeginInfo =
1522 VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, // VkStructureType sType;
1523 DE_NULL, // const void* pNext;
1524 0u, // VkCmdBufferOptimizeFlags flags;
1525 DE_NULL, // VkRenderPass renderPass;
1526 0u, // deUint32 subpass;
1527 DE_NULL // VkFramebuffer framebuffer;
1530 const Move<VkCmdBuffer> cmdBuffer = createCommandBuffer(vk, vkDevice, &cmdBufferParams);
1532 const VkBufferImageCopy copyParams =
1534 0u, // VkDeviceSize bufferOffset;
1535 m_renderSize.x() * 4u, // deUint32 bufferRowLength;
1536 0u, // deUint32 bufferImageHeight;
1538 VK_IMAGE_ASPECT_COLOR, // VkImageAspect aspect;
1539 0u, // deUint32 mipLevel;
1540 0u, // deUint32 arraySlice;
1541 1u, // deUint32 arraySize;
1542 }, // VkImageSubresourceCopy imageSubresource;
1543 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
1544 { m_renderSize.x(), m_renderSize.y(), 1u } // VkExtent3D imageExtent;
1547 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
1548 vk.cmdCopyImageToBuffer(*cmdBuffer, *m_colorImage, VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL, *readImageBuffer, 1u, ©Params);
1549 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
1551 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1552 VK_CHECK(vk.queueSubmit(queue, 1, &cmdBuffer.get(), *m_fence));
1553 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
1556 VK_CHECK(vk.mapMemory(vkDevice, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset(), imageSizeBytes, 0u, &imagePtr));
1558 const VkMappedMemoryRange range =
1560 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
1561 DE_NULL, // const void* pNext;
1562 readImageBufferMemory->getMemory(), // VkDeviceMemory mem;
1563 0, // VkDeviceSize offset;
1564 imageSizeBytes, // VkDeviceSize size;
1567 VK_CHECK(vk.invalidateMappedMemoryRanges(vkDevice, 1u, &range));
1569 const tcu::TextureFormat resultFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
1570 const tcu::ConstPixelBufferAccess resultAccess(resultFormat, m_renderSize.x(), m_renderSize.y(), 1, imagePtr);
1572 tcu::copy(result.getAccess(), resultAccess);
1574 vk.unmapMemory(vkDevice, readImageBufferMemory->getMemory());
1578 void ShaderRenderCaseInstance::computeVertexReference (tcu::Surface& result, const QuadGrid& quadGrid)
1581 const int width = result.getWidth();
1582 const int height = result.getHeight();
1583 const int gridSize = quadGrid.getGridSize();
1584 const int stride = gridSize + 1;
1585 const bool hasAlpha = true; // \todo [2015-09-07 elecro] add correct alpha check
1586 ShaderEvalContext evalCtx (quadGrid);
1588 // Evaluate color for each vertex.
1589 std::vector<tcu::Vec4> colors ((gridSize + 1) * (gridSize + 1));
1590 for (int y = 0; y < gridSize+1; y++)
1591 for (int x = 0; x < gridSize+1; x++)
1593 const float sx = (float)x / (float)gridSize;
1594 const float sy = (float)y / (float)gridSize;
1595 const int vtxNdx = ((y * (gridSize+1)) + x);
1597 evalCtx.reset(sx, sy);
1598 m_evaluator.evaluate(evalCtx);
1599 DE_ASSERT(!evalCtx.isDiscarded); // Discard is not available in vertex shader.
1600 tcu::Vec4 color = evalCtx.color;
1605 colors[vtxNdx] = color;
1609 for (int y = 0; y < gridSize; y++)
1610 for (int x = 0; x < gridSize; x++)
1612 const float x0 = (float)x / (float)gridSize;
1613 const float x1 = (float)(x + 1) / (float)gridSize;
1614 const float y0 = (float)y / (float)gridSize;
1615 const float y1 = (float)(y + 1) / (float)gridSize;
1617 const float sx0 = x0 * (float)width;
1618 const float sx1 = x1 * (float)width;
1619 const float sy0 = y0 * (float)height;
1620 const float sy1 = y1 * (float)height;
1621 const float oosx = 1.0f / (sx1 - sx0);
1622 const float oosy = 1.0f / (sy1 - sy0);
1624 const int ix0 = deCeilFloatToInt32(sx0 - 0.5f);
1625 const int ix1 = deCeilFloatToInt32(sx1 - 0.5f);
1626 const int iy0 = deCeilFloatToInt32(sy0 - 0.5f);
1627 const int iy1 = deCeilFloatToInt32(sy1 - 0.5f);
1629 const int v00 = (y * stride) + x;
1630 const int v01 = (y * stride) + x + 1;
1631 const int v10 = ((y + 1) * stride) + x;
1632 const int v11 = ((y + 1) * stride) + x + 1;
1633 const tcu::Vec4 c00 = colors[v00];
1634 const tcu::Vec4 c01 = colors[v01];
1635 const tcu::Vec4 c10 = colors[v10];
1636 const tcu::Vec4 c11 = colors[v11];
1638 //printf("(%d,%d) -> (%f..%f, %f..%f) (%d..%d, %d..%d)\n", x, y, sx0, sx1, sy0, sy1, ix0, ix1, iy0, iy1);
1640 for (int iy = iy0; iy < iy1; iy++)
1641 for (int ix = ix0; ix < ix1; ix++)
1643 DE_ASSERT(deInBounds32(ix, 0, width));
1644 DE_ASSERT(deInBounds32(iy, 0, height));
1646 const float sfx = (float)ix + 0.5f;
1647 const float sfy = (float)iy + 0.5f;
1648 const float fx1 = deFloatClamp((sfx - sx0) * oosx, 0.0f, 1.0f);
1649 const float fy1 = deFloatClamp((sfy - sy0) * oosy, 0.0f, 1.0f);
1651 // Triangle quad interpolation.
1652 const bool tri = fx1 + fy1 <= 1.0f;
1653 const float tx = tri ? fx1 : (1.0f-fx1);
1654 const float ty = tri ? fy1 : (1.0f-fy1);
1655 const tcu::Vec4& t0 = tri ? c00 : c11;
1656 const tcu::Vec4& t1 = tri ? c01 : c10;
1657 const tcu::Vec4& t2 = tri ? c10 : c01;
1658 const tcu::Vec4 color = t0 + (t1-t0)*tx + (t2-t0)*ty;
1660 result.setPixel(ix, iy, tcu::RGBA(color));
1665 void ShaderRenderCaseInstance::computeFragmentReference (tcu::Surface& result, const QuadGrid& quadGrid)
1668 const int width = result.getWidth();
1669 const int height = result.getHeight();
1670 const bool hasAlpha = true; // \todo [2015-09-07 elecro] add correct alpha check
1671 ShaderEvalContext evalCtx (quadGrid);
1674 for (int y = 0; y < height; y++)
1675 for (int x = 0; x < width; x++)
1677 const float sx = ((float)x + 0.5f) / (float)width;
1678 const float sy = ((float)y + 0.5f) / (float)height;
1680 evalCtx.reset(sx, sy);
1681 m_evaluator.evaluate(evalCtx);
1682 // Select either clear color or computed color based on discarded bit.
1683 tcu::Vec4 color = evalCtx.isDiscarded ? m_clearColor : evalCtx.color;
1688 result.setPixel(x, y, tcu::RGBA(color));
1692 bool ShaderRenderCaseInstance::compareImages (const tcu::Surface& resImage, const tcu::Surface& refImage, float errorThreshold)
1694 return tcu::fuzzyCompare(m_context.getTestContext().getLog(), "ComparisonResult", "Image comparison result", refImage, resImage, errorThreshold, tcu::COMPARE_LOG_RESULT);
1697 } // shaderrendercase