1 /*------------------------------------------------------------------------
2 * Copyright (c) 2015 The Khronos Group Inc.
3 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and/or associated documentation files (the
7 * "Materials"), to deal in the Materials without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Materials, and to
10 * permit persons to whom the Materials are furnished to do so, subject to
11 * the following conditions:
13 * The above copyright notice(s) and this permission notice shall be included
14 * in all copies or substantial portions of the Materials.
16 * The Materials are Confidential Information as defined by the
17 * Khronos Membership Agreement until designated non-confidential by Khronos,
18 * at which point this condition clause shall be removed.
20 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
30 * \brief Vulkan ShaderRenderCase
31 *//*--------------------------------------------------------------------*/
33 #include "vktShaderRenderCase.hpp"
35 #include "tcuImageCompare.hpp"
36 #include "tcuSurface.hpp"
37 #include "tcuVector.hpp"
38 #include "tcuTestLog.hpp"
41 #include "deUniquePtr.hpp"
43 #include "vkPlatform.hpp"
44 #include "vkStrUtil.hpp"
46 #include "vkRefUtil.hpp"
47 #include "vkQueryUtil.hpp"
48 #include "vkDeviceUtil.hpp"
55 namespace shaderrendercase
60 static const int GRID_SIZE = 2;
61 static const int MAX_RENDER_WIDTH = 128;
62 static const int MAX_RENDER_HEIGHT = 112;
63 static const tcu::Vec4 DEFAULT_CLEAR_COLOR = tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f);
70 QuadGrid (int gridSize,
73 const tcu::Vec4& constCoords,
74 const std::vector<tcu::Mat4>& userAttribTransforms,
75 const std::vector<TextureBinding>& textures);
78 int getGridSize (void) const { return m_gridSize; }
79 int getNumVertices (void) const { return m_numVertices; }
80 int getNumTriangles (void) const { return m_numTriangles; }
81 const tcu::Vec4& getConstCoords (void) const { return m_constCoords; }
82 const std::vector<tcu::Mat4> getUserAttribTransforms (void) const { return m_userAttribTransforms; }
83 const std::vector<TextureBinding>& getTextures (void) const { return m_textures; }
85 const tcu::Vec4* getPositions (void) const { return &m_positions[0]; }
86 const float* getAttribOne (void) const { return &m_attribOne[0]; }
87 const tcu::Vec4* getCoords (void) const { return &m_coords[0]; }
88 const tcu::Vec4* getUnitCoords (void) const { return &m_unitCoords[0]; }
90 const tcu::Vec4* getUserAttrib (int attribNdx) const { return &m_userAttribs[attribNdx][0]; }
91 const deUint16* getIndices (void) const { return &m_indices[0]; }
93 tcu::Vec4 getCoords (float sx, float sy) const;
94 tcu::Vec4 getUnitCoords (float sx, float sy) const;
96 int getNumUserAttribs (void) const { return (int)m_userAttribTransforms.size(); }
97 tcu::Vec4 getUserAttrib (int attribNdx, float sx, float sy) const;
103 tcu::Vec4 m_constCoords;
104 std::vector<tcu::Mat4> m_userAttribTransforms;
106 std::vector<TextureBinding> m_textures;
108 std::vector<tcu::Vec4> m_screenPos;
109 std::vector<tcu::Vec4> m_positions;
110 std::vector<tcu::Vec4> m_coords; //!< Near-unit coordinates, roughly [-2.0 .. 2.0].
111 std::vector<tcu::Vec4> m_unitCoords; //!< Positive-only coordinates [0.0 .. 1.5].
112 std::vector<float> m_attribOne;
113 std::vector<tcu::Vec4> m_userAttribs[ShaderEvalContext::MAX_TEXTURES];
114 std::vector<deUint16> m_indices;
117 QuadGrid::QuadGrid (int gridSize,
120 const tcu::Vec4& constCoords,
121 const std::vector<tcu::Mat4>& userAttribTransforms,
122 const std::vector<TextureBinding>& textures)
123 : m_gridSize (gridSize)
124 , m_numVertices ((gridSize + 1) * (gridSize + 1))
125 , m_numTriangles (gridSize * gridSize * 2)
126 , m_constCoords (constCoords)
127 , m_userAttribTransforms (userAttribTransforms)
128 , m_textures (textures)
130 tcu::Vec4 viewportScale = tcu::Vec4((float)width, (float)height, 0.0f, 0.0f);
133 m_screenPos.resize(m_numVertices);
134 m_positions.resize(m_numVertices);
135 m_coords.resize(m_numVertices);
136 m_unitCoords.resize(m_numVertices);
137 m_attribOne.resize(m_numVertices);
140 for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_userAttribs); i++)
141 m_userAttribs[i].resize(m_numVertices);
143 for (int y = 0; y < gridSize+1; y++)
144 for (int x = 0; x < gridSize+1; x++)
146 float sx = (float)x / (float)gridSize;
147 float sy = (float)y / (float)gridSize;
148 float fx = 2.0f * sx - 1.0f;
149 float fy = 2.0f * sy - 1.0f;
150 int vtxNdx = ((y * (gridSize+1)) + x);
152 m_positions[vtxNdx] = tcu::Vec4(fx, fy, 0.0f, 1.0f);
153 m_coords[vtxNdx] = getCoords(sx, sy);
154 m_unitCoords[vtxNdx] = getUnitCoords(sx, sy);
155 m_attribOne[vtxNdx] = 1.0f;
157 m_screenPos[vtxNdx] = tcu::Vec4(sx, sy, 0.0f, 1.0f) * viewportScale;
159 for (int attribNdx = 0; attribNdx < getNumUserAttribs(); attribNdx++)
160 m_userAttribs[attribNdx][vtxNdx] = getUserAttrib(attribNdx, sx, sy);
164 m_indices.resize(3 * m_numTriangles);
165 for (int y = 0; y < gridSize; y++)
166 for (int x = 0; x < gridSize; x++)
168 int stride = gridSize + 1;
169 int v00 = (y * stride) + x;
170 int v01 = (y * stride) + x + 1;
171 int v10 = ((y+1) * stride) + x;
172 int v11 = ((y+1) * stride) + x + 1;
174 int baseNdx = ((y * gridSize) + x) * 6;
175 m_indices[baseNdx + 0] = (deUint16)v10;
176 m_indices[baseNdx + 1] = (deUint16)v00;
177 m_indices[baseNdx + 2] = (deUint16)v01;
179 m_indices[baseNdx + 3] = (deUint16)v10;
180 m_indices[baseNdx + 4] = (deUint16)v01;
181 m_indices[baseNdx + 5] = (deUint16)v11;
185 QuadGrid::~QuadGrid (void)
189 inline tcu::Vec4 QuadGrid::getCoords (float sx, float sy) const
191 float fx = 2.0f * sx - 1.0f;
192 float fy = 2.0f * sy - 1.0f;
193 return tcu::Vec4(fx, fy, -fx + 0.33f*fy, -0.275f*fx - fy);
196 inline tcu::Vec4 QuadGrid::getUnitCoords (float sx, float sy) const
198 return tcu::Vec4(sx, sy, 0.33f*sx + 0.5f*sy, 0.5f*sx + 0.25f*sy);
201 inline tcu::Vec4 QuadGrid::getUserAttrib (int attribNdx, float sx, float sy) const
203 // homogeneous normalized screen-space coordinates
204 return m_userAttribTransforms[attribNdx] * tcu::Vec4(sx, sy, 0.0f, 1.0f);
209 TextureBinding::TextureBinding (const Texture2D* tex2D, const tcu::Sampler& sampler)
211 , m_sampler (sampler)
213 m_binding.tex2D = tex2D;
219 // ShaderEvalContext.
221 ShaderEvalContext::ShaderEvalContext (const QuadGrid& quadGrid_)
222 : constCoords(quadGrid_.getConstCoords())
224 , quadGrid(quadGrid_)
226 const std::vector<TextureBinding>& bindings = quadGrid.getTextures();
227 DE_ASSERT((int)bindings.size() <= MAX_TEXTURES);
229 // Fill in texture array.
230 for (int ndx = 0; ndx < (int)bindings.size(); ndx++)
232 const TextureBinding& binding = bindings[ndx];
234 if (binding.getType() == TextureBinding::TYPE_NONE)
237 textures[ndx].sampler = binding.getSampler();
239 switch (binding.getType())
241 case TextureBinding::TYPE_2D: textures[ndx].tex2D = &binding.get2D()->getRefTexture(); break;
242 // \todo [2015-09-07 elecro] Add support for the other binding types
244 case TextureBinding::TYPE_CUBE_MAP: textures[ndx].texCube = &binding.getCube()->getRefTexture(); break;
245 case TextureBinding::TYPE_2D_ARRAY: textures[ndx].tex2DArray = &binding.get2DArray()->getRefTexture(); break;
246 case TextureBinding::TYPE_3D: textures[ndx].tex3D = &binding.get3D()->getRefTexture(); break;
249 TCU_THROW(InternalError, "Handling of texture binding type not implemented");
254 ShaderEvalContext::~ShaderEvalContext (void)
258 void ShaderEvalContext::reset (float sx, float sy)
261 color = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
265 coords = quadGrid.getCoords(sx, sy);
266 unitCoords = quadGrid.getUnitCoords(sx, sy);
268 // Compute user attributes.
269 int numAttribs = quadGrid.getNumUserAttribs();
270 DE_ASSERT(numAttribs <= MAX_USER_ATTRIBS);
271 for (int attribNdx = 0; attribNdx < numAttribs; attribNdx++)
272 in[attribNdx] = quadGrid.getUserAttrib(attribNdx, sx, sy);
275 tcu::Vec4 ShaderEvalContext::texture2D (int unitNdx, const tcu::Vec2& texCoords)
277 if (textures[unitNdx].tex2D)
278 return textures[unitNdx].tex2D->sample(textures[unitNdx].sampler, texCoords.x(), texCoords.y(), 0.0f);
280 return tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
286 ShaderEvaluator::ShaderEvaluator (void)
287 : m_evalFunc(DE_NULL)
291 ShaderEvaluator::ShaderEvaluator (ShaderEvalFunc evalFunc)
292 : m_evalFunc(evalFunc)
296 ShaderEvaluator::~ShaderEvaluator (void)
300 void ShaderEvaluator::evaluate (ShaderEvalContext& ctx)
302 DE_ASSERT(m_evalFunc);
309 UniformSetup::UniformSetup (void)
310 : m_setupFunc(DE_NULL)
314 UniformSetup::UniformSetup (UniformSetupFunc setupFunc)
315 : m_setupFunc(setupFunc)
319 UniformSetup::~UniformSetup (void)
323 void UniformSetup::setup (ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords)
326 m_setupFunc(instance, constCoords);
329 // ShaderRenderCaseInstance.
331 ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context& context, bool isVertexCase, ShaderEvaluator& evaluator, UniformSetup& uniformSetup, AttributeSetupFunc attribFunc)
332 : vkt::TestInstance(context)
333 , m_clearColor(DEFAULT_CLEAR_COLOR)
334 , m_memAlloc(m_context.getDeviceInterface(), m_context.getDevice(), getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()))
335 , m_isVertexCase(isVertexCase)
336 , m_evaluator(evaluator)
337 , m_uniformSetup(uniformSetup)
338 , m_attribFunc(attribFunc)
339 , m_renderSize(100, 100)
340 , m_colorFormat(VK_FORMAT_R8G8B8A8_UNORM)
344 ShaderRenderCaseInstance::~ShaderRenderCaseInstance (void)
346 const VkDevice vkDevice = m_context.getDevice();
347 const DeviceInterface& vk = m_context.getDeviceInterface();
349 for (size_t i = 0; i < m_vertexBuffers.size(); i++)
351 VK_CHECK(vk.freeMemory(vkDevice, m_vertexBufferAllocs[i]->getMemory()));
352 VK_CHECK(vk.destroyBuffer(vkDevice, m_vertexBuffers[i]));
356 for (size_t i = 0; i < m_uniformInfos.size(); i++)
358 if (m_uniformInfos[i].type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
360 VK_CHECK(vk.destroyBufferView(vkDevice, m_uniformInfos[i].descriptor.bufferView));
361 VK_CHECK(vk.freeMemory(vkDevice, m_uniformInfos[i].alloc->getMemory()));
362 VK_CHECK(vk.destroyBuffer(vkDevice, m_uniformInfos[i].buffer));
364 else if (m_uniformInfos[i].type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
366 VK_CHECK(vk.destroyImageView(vkDevice, m_uniformInfos[i].descriptor.imageView));
367 VK_CHECK(vk.destroySampler(vkDevice, m_uniformInfos[i].descriptor.sampler));
374 tcu::TestStatus ShaderRenderCaseInstance::iterate (void)
379 tcu::IVec2 viewportSize = getViewportSize();
380 int width = viewportSize.x();
381 int height = viewportSize.y();
383 QuadGrid quadGrid (m_isVertexCase ? GRID_SIZE : 4, width, height, tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f), m_userAttribTransforms, m_textures);
386 tcu::Surface resImage (width, height);
387 render(resImage, quadGrid);
389 // Compute reference.
390 tcu::Surface refImage (width, height);
392 computeVertexReference(refImage, quadGrid);
394 computeFragmentReference(refImage, quadGrid);
397 bool compareOk = compareImages(resImage, refImage, 0.05f);
400 return tcu::TestStatus::pass("Result image matches reference");
402 return tcu::TestStatus::fail("Image mismatch");
405 void ShaderRenderCaseInstance::setupUniformData (deUint32 bindingLocation, deUint32 size, const void* dataPtr)
407 const VkDevice vkDevice = m_context.getDevice();
408 const DeviceInterface& vk = m_context.getDeviceInterface();
409 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
411 const VkBufferCreateInfo uniformBufferParams =
413 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
414 DE_NULL, // const void* pNext;
415 size, // VkDeviceSize size;
416 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, // VkBufferUsageFlags usage;
417 0u, // VkBufferCreateFlags flags;
418 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
419 1u, // deUint32 queueFamilyCount;
420 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
423 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &uniformBufferParams);
424 de::MovePtr<Allocation> alloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::Any);
425 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), 0));
428 VK_CHECK(vk.mapMemory(vkDevice, alloc->getMemory(), 0, size, 0, &bufferPtr));
429 deMemcpy(bufferPtr, dataPtr, size);
430 VK_CHECK(vk.unmapMemory(vkDevice, alloc->getMemory()));
432 const VkBufferViewCreateInfo viewInfo =
434 VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, // VkStructureType sType;
435 DE_NULL, // void* pNext;
436 *buffer, // VkBuffer buffer;
437 VK_BUFFER_VIEW_TYPE_FORMATTED, // VkBufferViewType viewType;
438 VK_FORMAT_R32_SFLOAT, // VkFormat format;
439 0u, // VkDeviceSize offset;
440 size // VkDeviceSize range;
443 Move<VkBufferView> bufferView = createBufferView(vk, vkDevice, &viewInfo);
445 const VkDescriptorInfo descriptor =
447 bufferView.disown(), // VkBufferView bufferView;
448 0, // VkSampler sampler;
449 0, // VkImageView imageView;
450 0, // VkAttachmentView attachmentView;
451 (vk::VkImageLayout)0, // VkImageLayout imageLayout;
454 UniformInfo uniformInfo;
455 uniformInfo.buffer = buffer.disown();
456 uniformInfo.alloc = alloc.release();
457 uniformInfo.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
458 uniformInfo.descriptor = descriptor;
459 uniformInfo.location = bindingLocation;
461 m_uniformInfos.push_back(uniformInfo);
464 void ShaderRenderCaseInstance::addUniform (deUint32 bindingLocation, vk::VkDescriptorType descriptorType, deUint32 dataSize, const void* data)
466 m_descriptorSetLayoutBuilder.addSingleBinding(descriptorType, vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT);
467 m_descriptorPoolBuilder.addType(descriptorType);
469 setupUniformData(bindingLocation, dataSize, data);
472 void ShaderRenderCaseInstance::addAttribute (deUint32 bindingLocation, vk::VkFormat format, deUint32 sizePerElement, deUint32 count, const void* dataPtr)
474 // Add binding specification
475 const deUint32 binding = (deUint32)m_vertexBindingDescription.size();
476 const VkVertexInputBindingDescription bindingDescription =
480 VK_VERTEX_INPUT_STEP_RATE_VERTEX
483 m_vertexBindingDescription.push_back(bindingDescription);
485 // Add location and format specification
486 const VkVertexInputAttributeDescription attributeDescription =
488 bindingLocation, // deUint32 location;
489 binding, // deUint32 binding;
490 format, // VkFormat format;
491 0u, // deUint32 offsetInBytes;
494 m_vertexattributeDescription.push_back(attributeDescription);
496 // Upload data to buffer
497 const VkDevice vkDevice = m_context.getDevice();
498 const DeviceInterface& vk = m_context.getDeviceInterface();
499 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
501 const VkDeviceSize inputSize = sizePerElement * count;
502 const VkBufferCreateInfo vertexBufferParams =
504 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
505 DE_NULL, // const void* pNext;
506 inputSize, // VkDeviceSize size;
507 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
508 0u, // VkBufferCreateFlags flags;
509 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
510 1u, // deUint32 queueFamilyCount;
511 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
514 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &vertexBufferParams);
515 de::MovePtr<vk::Allocation> alloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::Any);
517 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), 0));
520 VK_CHECK(vk.mapMemory(vkDevice, alloc->getMemory(), 0, inputSize, 0, &bufferPtr));
521 deMemcpy(bufferPtr, dataPtr, inputSize);
522 VK_CHECK(vk.unmapMemory(vkDevice, alloc->getMemory()));
524 m_vertexBuffers.push_back(buffer.disown());
525 m_vertexBufferAllocs.push_back(alloc.release());
528 void ShaderRenderCaseInstance::useAttribute (deUint32 bindingLocation, BaseAttributeType type)
530 const EnabledBaseAttribute attribute =
535 m_enabledBaseAttributes.push_back(attribute);
538 void ShaderRenderCaseInstance::setupShaderData (void)
543 void ShaderRenderCaseInstance::setup (void)
548 void ShaderRenderCaseInstance::setupUniforms (const tcu::Vec4& constCoords)
551 DE_UNREF(constCoords);
552 m_uniformSetup.setup(*this, constCoords);
555 void ShaderRenderCaseInstance::useUniform (deUint32 bindingLocation, BaseUniformType type)
557 #define UNIFORM_CASE(type, value) case type: addUniform(bindingLocation, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, value); break
562 UNIFORM_CASE(UB_FALSE, 0);
563 UNIFORM_CASE(UB_TRUE, 1);
566 UNIFORM_CASE(UB4_FALSE, tcu::Vec4(0));
567 UNIFORM_CASE(UB4_TRUE, tcu::Vec4(1));
570 UNIFORM_CASE(UI_ZERO, 0);
571 UNIFORM_CASE(UI_ONE, 1);
572 UNIFORM_CASE(UI_TWO, 2);
573 UNIFORM_CASE(UI_THREE, 3);
574 UNIFORM_CASE(UI_FOUR, 4);
575 UNIFORM_CASE(UI_FIVE, 5);
576 UNIFORM_CASE(UI_SIX, 6);
577 UNIFORM_CASE(UI_SEVEN, 7);
578 UNIFORM_CASE(UI_EIGTH, 8);
579 UNIFORM_CASE(UI_ONEHUNDREDONE, 101);
582 UNIFORM_CASE(UI2_MINUS_ONE, tcu::IVec2(-1));
583 UNIFORM_CASE(UI2_ZERO, tcu::IVec2(0));
584 UNIFORM_CASE(UI2_ONE, tcu::IVec2(1));
585 UNIFORM_CASE(UI2_TWO, tcu::IVec2(2));
586 UNIFORM_CASE(UI2_THREE, tcu::IVec2(3));
587 UNIFORM_CASE(UI2_FOUR, tcu::IVec2(4));
588 UNIFORM_CASE(UI2_FIVE, tcu::IVec2(5));
591 UNIFORM_CASE(UI3_MINUS_ONE, tcu::IVec3(-1));
592 UNIFORM_CASE(UI3_ZERO, tcu::IVec3(0));
593 UNIFORM_CASE(UI3_ONE, tcu::IVec3(1));
594 UNIFORM_CASE(UI3_TWO, tcu::IVec3(2));
595 UNIFORM_CASE(UI3_THREE, tcu::IVec3(3));
596 UNIFORM_CASE(UI3_FOUR, tcu::IVec3(4));
597 UNIFORM_CASE(UI3_FIVE, tcu::IVec3(5));
600 UNIFORM_CASE(UI4_MINUS_ONE, tcu::IVec4(-1));
601 UNIFORM_CASE(UI4_ZERO, tcu::IVec4(0));
602 UNIFORM_CASE(UI4_ONE, tcu::IVec4(1));
603 UNIFORM_CASE(UI4_TWO, tcu::IVec4(2));
604 UNIFORM_CASE(UI4_THREE, tcu::IVec4(3));
605 UNIFORM_CASE(UI4_FOUR, tcu::IVec4(4));
606 UNIFORM_CASE(UI4_FIVE, tcu::IVec4(5));
609 UNIFORM_CASE(UF_ZERO, 0.0f);
610 UNIFORM_CASE(UF_ONE, 1.0f);
611 UNIFORM_CASE(UF_TWO, 2.0f);
612 UNIFORM_CASE(UF_THREE, 3.0f);
613 UNIFORM_CASE(UF_FOUR, 4.0f);
614 UNIFORM_CASE(UF_FIVE, 5.0f);
615 UNIFORM_CASE(UF_SIX, 6.0f);
616 UNIFORM_CASE(UF_SEVEN, 7.0f);
617 UNIFORM_CASE(UF_EIGTH, 8.0f);
619 UNIFORM_CASE(UF_HALF, 1.0f / 2.0f);
620 UNIFORM_CASE(UF_THIRD, 1.0f / 3.0f);
621 UNIFORM_CASE(UF_FOURTH, 1.0f / 4.0f);
622 UNIFORM_CASE(UF_FIFTH, 1.0f / 5.0f);
623 UNIFORM_CASE(UF_SIXTH, 1.0f / 6.0f);
624 UNIFORM_CASE(UF_SEVENTH, 1.0f / 7.0f);
625 UNIFORM_CASE(UF_EIGHTH, 1.0f / 8.0f);
628 UNIFORM_CASE(UV2_MINUS_ONE, tcu::Vec2(-1.0f));
629 UNIFORM_CASE(UV2_ZERO, tcu::Vec2(0.0f));
630 UNIFORM_CASE(UV2_ONE, tcu::Vec2(1.0f));
631 UNIFORM_CASE(UV2_TWO, tcu::Vec2(2.0f));
632 UNIFORM_CASE(UV2_THREE, tcu::Vec2(3.0f));
634 UNIFORM_CASE(UV2_HALF, tcu::Vec2(1.0f / 2.0f));
637 UNIFORM_CASE(UV3_MINUS_ONE, tcu::Vec3(-1.0f));
638 UNIFORM_CASE(UV3_ZERO, tcu::Vec3(0.0f));
639 UNIFORM_CASE(UV3_ONE, tcu::Vec3(1.0f));
640 UNIFORM_CASE(UV3_TWO, tcu::Vec3(2.0f));
641 UNIFORM_CASE(UV3_THREE, tcu::Vec3(3.0f));
643 UNIFORM_CASE(UV3_HALF, tcu::Vec3(1.0f / 2.0f));
646 UNIFORM_CASE(UV4_MINUS_ONE, tcu::Vec4(-1.0f));
647 UNIFORM_CASE(UV4_ZERO, tcu::Vec4(0.0f));
648 UNIFORM_CASE(UV4_ONE, tcu::Vec4(1.0f));
649 UNIFORM_CASE(UV4_TWO, tcu::Vec4(2.0f));
650 UNIFORM_CASE(UV4_THREE, tcu::Vec4(3.0f));
652 UNIFORM_CASE(UV4_HALF, tcu::Vec4(1.0f / 2.0f));
654 UNIFORM_CASE(UV4_BLACK, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
655 UNIFORM_CASE(UV4_GRAY, tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f));
656 UNIFORM_CASE(UV4_WHITE, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
659 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Unknown Uniform type: " << type << tcu::TestLog::EndMessage;
667 tcu::IVec2 ShaderRenderCaseInstance::getViewportSize (void) const
669 return tcu::IVec2(de::min(m_renderSize.x(), MAX_RENDER_WIDTH),
670 de::min(m_renderSize.y(), MAX_RENDER_HEIGHT));
673 void ShaderRenderCaseInstance::useSampler2D (deUint32 bindingLocation, deUint32 textureID)
675 const VkDevice vkDevice = m_context.getDevice();
676 const DeviceInterface& vk = m_context.getDeviceInterface();
678 DE_ASSERT(textureID < m_textures.size());
680 const TextureBinding& textureBinding = m_textures[textureID];
681 const Texture2D* texture = textureBinding.get2D();
682 const tcu::Sampler& refSampler = textureBinding.getSampler();
685 const VkSamplerCreateInfo samplerParams =
687 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
689 mapTexFilter(refSampler.magFilter),
690 mapTexFilter(refSampler.minFilter),
691 mapTexMipmapMode(refSampler.minFilter),
692 mapWrapMode(refSampler.wrapS),
693 mapWrapMode(refSampler.wrapT),
694 mapWrapMode(refSampler.wrapR),
695 refSampler.lodThreshold,
697 (refSampler.compare != tcu::Sampler::COMPAREMODE_NONE),
698 mapCompareMode(refSampler.compare),
701 VK_BORDER_COLOR_INT_OPAQUE_WHITE
704 Move<VkSampler> sampler = createSampler(vk, vkDevice, &samplerParams);
706 const VkImageViewCreateInfo viewParams =
708 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
710 .image = *texture->getVkTexture(),
711 .viewType = VK_IMAGE_VIEW_TYPE_2D,
712 .format = texture->getVkFormat(),
713 .channels = { VK_CHANNEL_SWIZZLE_R,
714 VK_CHANNEL_SWIZZLE_G,
715 VK_CHANNEL_SWIZZLE_B,
716 VK_CHANNEL_SWIZZLE_A },
717 .subresourceRange = { VK_IMAGE_ASPECT_COLOR, 0, 1, 0, 1 },
720 Move<VkImageView> imageView = createImageView(vk, vkDevice, &viewParams);
722 const vk::VkDescriptorInfo descriptor =
724 0, // VkBufferView bufferView;
725 sampler.disown(), // VkSampler sampler;
726 imageView.disown(), // VkImageView imageView;
727 0, // VkAttachmentView attachmentView;
728 vk::VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
731 UniformInfo newUniformInfo;
732 m_uniformInfos.push_back(newUniformInfo);
734 UniformInfo& uniformInfo = m_uniformInfos[m_uniformInfos.size() - 1];
736 uniformInfo.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
737 uniformInfo.descriptor = descriptor;
738 uniformInfo.location = bindingLocation;
740 m_descriptorSetLayoutBuilder.addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, vk::VK_SHADER_STAGE_FRAGMENT_BIT, &uniformInfo.descriptor.sampler);
741 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
744 void ShaderRenderCaseInstance::setupDefaultInputs (const QuadGrid& quadGrid)
746 /* Configuration of the vertex input attributes:
747 a_position is at location 0
748 a_coords is at location 1
749 a_unitCoords is at location 2
750 a_one is at location 3
752 User attributes starts from at the location 4.
754 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getPositions());
755 addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getCoords());
756 addAttribute(2u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUnitCoords());
757 addAttribute(3u, VK_FORMAT_R32_SFLOAT, sizeof(float), quadGrid.getNumVertices(), quadGrid.getAttribOne());
761 BaseAttributeType type;
773 BaseAttributeType matrixType;
788 for (size_t i = 0; i < m_enabledBaseAttributes.size(); i++)
790 for (int userNdx = 0; userNdx < DE_LENGTH_OF_ARRAY(userAttributes); userNdx++)
792 if (userAttributes[userNdx].type != m_enabledBaseAttributes[i].type)
795 addAttribute(m_enabledBaseAttributes[i].location, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUserAttrib(userNdx));
798 for (int matNdx = 0; matNdx < DE_LENGTH_OF_ARRAY(matrices); matNdx++)
801 if (matrices[matNdx].matrixType != m_enabledBaseAttributes[i].type)
804 int numCols = matrices[matNdx].numCols;
806 for (int colNdx = 0; colNdx < numCols; colNdx++)
808 addAttribute(m_enabledBaseAttributes[i].location + colNdx, VK_FORMAT_R32G32B32A32_SFLOAT, 4 * sizeof(float), quadGrid.getNumVertices(), quadGrid.getUserAttrib(colNdx));
814 void ShaderRenderCaseInstance::render (tcu::Surface& result, const QuadGrid& quadGrid)
816 const VkDevice vkDevice = m_context.getDevice();
817 const DeviceInterface& vk = m_context.getDeviceInterface();
818 const VkQueue queue = m_context.getUniversalQueue();
819 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
821 // Create color image
823 const VkImageCreateInfo colorImageParams =
825 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
826 DE_NULL, // const void* pNext;
827 VK_IMAGE_TYPE_2D, // VkImageType imageType;
828 m_colorFormat, // VkFormat format;
829 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent;
830 1u, // deUint32 mipLevels;
831 1u, // deUint32 arraySize;
832 1u, // deUint32 samples;
833 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
834 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT, // VkImageUsageFlags usage;
835 0u, // VkImageCreateFlags flags;
836 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
837 1u, // deUint32 queueFamilyCount;
838 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
841 m_colorImage = createImage(vk, vkDevice, &colorImageParams);
843 // Allocate and bind color image memory
844 m_colorImageAlloc = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::HostVisible);
845 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), 0));
848 // Create color attachment view
850 const VkAttachmentViewCreateInfo colorAttachmentViewParams =
852 VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO, // VkStructureType sType;
853 DE_NULL, // constvoid* pNext;
854 *m_colorImage, // VkImage image;
855 m_colorFormat, // VkFormat format;
856 0u, // deUint32 mipLevel;
857 0u, // deUint32 baseArraySlice;
858 1u, // deUint32 arraySize;
859 0u // VkAttachmentViewCreateFlags flags;
862 m_colorAttachmentView = createAttachmentView(vk, vkDevice, &colorAttachmentViewParams);
865 // Create render pass
867 const VkAttachmentDescription colorAttachmentDescription =
869 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION, // VkStructureType sType;
870 DE_NULL, // const void* pNext;
871 m_colorFormat, // VkFormat format;
872 1u, // deUint32 samples;
873 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
874 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
875 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
876 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
877 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
878 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
881 const VkAttachmentDescription attachments[1] =
883 colorAttachmentDescription
886 const VkAttachmentReference colorAttachmentReference =
888 0u, // deUint32 attachment;
889 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
892 const VkSubpassDescription subpassDescription =
894 VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION, // VkStructureType sType;
895 DE_NULL, // constvoid* pNext;
896 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
897 0u, // VkSubpassDescriptionFlags flags;
898 0u, // deUint32 inputCount;
899 DE_NULL, // constVkAttachmentReference* inputAttachments;
900 1u, // deUint32 colorCount;
901 &colorAttachmentReference, // constVkAttachmentReference* colorAttachments;
902 DE_NULL, // constVkAttachmentReference* resolveAttachments;
903 { ~0u, VK_IMAGE_LAYOUT_GENERAL }, // VkAttachmentReference depthStencilAttachment;
904 0u, // deUint32 preserveCount;
905 DE_NULL // constVkAttachmentReference* preserveAttachments;
908 const VkRenderPassCreateInfo renderPassParams =
910 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
911 DE_NULL, // const void* pNext;
912 1u, // deUint32 attachmentCount;
913 attachments, // const VkAttachmentDescription* pAttachments;
914 1u, // deUint32 subpassCount;
915 &subpassDescription, // const VkSubpassDescription* pSubpasses;
916 0u, // deUint32 dependencyCount;
917 DE_NULL // const VkSubpassDependency* pDependencies;
920 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
923 // Create framebuffer
925 const VkAttachmentBindInfo attachmentBindInfos[1] =
927 { *m_colorAttachmentView, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL },
930 const VkFramebufferCreateInfo framebufferParams =
932 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
933 DE_NULL, // const void* pNext;
934 *m_renderPass, // VkRenderPass renderPass;
935 1u, // deUint32 attachmentCount;
936 attachmentBindInfos, // const VkAttachmentBindInfo* pAttachments;
937 (deUint32)m_renderSize.x(), // deUint32 width;
938 (deUint32)m_renderSize.y(), // deUint32 height;
939 1u // deUint32 layers;
942 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
945 // Create descriptors
947 setupUniforms(quadGrid.getConstCoords());
949 m_descriptorSetLayout = m_descriptorSetLayoutBuilder.build(vk, vkDevice);
950 m_descriptorPool = m_descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1u);
951 m_descriptorSet = allocDescriptorSet(vk, vkDevice, *m_descriptorPool, VK_DESCRIPTOR_SET_USAGE_STATIC, *m_descriptorSetLayout);
953 for(deUint32 i = 0; i < m_uniformInfos.size(); i++)
955 deUint32 location = m_uniformInfos[i].location;
956 m_descriptorSetUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), m_uniformInfos[i].type, &m_uniformInfos[i].descriptor);
959 m_descriptorSetUpdateBuilder.update(vk, vkDevice);
962 // Create pipeline layout
964 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
966 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
967 DE_NULL, // const void* pNext;
968 1u, // deUint32 descriptorSetCount;
969 &*m_descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
970 0u, // deUint32 pushConstantRangeCount;
971 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
974 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
979 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
980 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
982 const VkShaderCreateInfo vertexShaderParams =
984 VK_STRUCTURE_TYPE_SHADER_CREATE_INFO, // VkStructureType sType;
985 DE_NULL, // const void* pNext;
986 *m_vertexShaderModule, // VkShaderModule module;
987 "main", // const char* pName;
988 0u // VkShaderCreateFlags flags;
991 const VkShaderCreateInfo fragmentShaderParams =
993 VK_STRUCTURE_TYPE_SHADER_CREATE_INFO, // VkStructureType sType;
994 DE_NULL, // const void* pNext;
995 *m_fragmentShaderModule, // VkShaderModule module;
996 "main", // const char* pName;
997 0u // VkShaderCreateFlags flags;
1000 m_vertexShader = createShader(vk, vkDevice, &vertexShaderParams);
1001 m_fragmentShader= createShader(vk, vkDevice, &fragmentShaderParams);
1006 const VkPipelineShaderStageCreateInfo shaderStageParams[2] =
1009 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1010 DE_NULL, // const void* pNext;
1011 VK_SHADER_STAGE_VERTEX, // VkShaderStage stage;
1012 *m_vertexShader, // VkShader shader;
1013 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1016 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1017 DE_NULL, // const void* pNext;
1018 VK_SHADER_STAGE_FRAGMENT, // VkShaderStage stage;
1019 *m_fragmentShader, // VkShader shader;
1020 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1024 // Add base attributes
1026 // Add test case specific attributes
1028 m_attribFunc(*this, quadGrid.getNumVertices());
1030 setupDefaultInputs(quadGrid);
1032 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
1034 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1035 DE_NULL, // const void* pNext;
1036 (deUint32)m_vertexBindingDescription.size(), // deUint32 bindingCount;
1037 &m_vertexBindingDescription[0], // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1038 (deUint32)m_vertexattributeDescription.size(), // deUint32 attributeCount;
1039 &m_vertexattributeDescription[0], // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1042 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
1044 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
1045 DE_NULL, // const void* pNext;
1046 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology;
1047 false // VkBool32 primitiveRestartEnable;
1050 const VkPipelineViewportStateCreateInfo viewportStateParams =
1052 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
1053 DE_NULL, // const void* pNext;
1054 1u // deUint32 viewportCount;
1057 const VkPipelineRasterStateCreateInfo rasterStateParams =
1059 VK_STRUCTURE_TYPE_PIPELINE_RASTER_STATE_CREATE_INFO, // VkStructureType sType;
1060 DE_NULL, // const void* pNext;
1061 false, // VkBool32 depthClipEnable;
1062 false, // VkBool32 rasterizerDiscardEnable;
1063 VK_FILL_MODE_SOLID, // VkFillMode fillMode;
1064 VK_CULL_MODE_NONE, // VkCullMode cullMode;
1065 VK_FRONT_FACE_CCW // VkFrontFace frontFace;
1068 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
1070 false, // VkBool32 blendEnable;
1071 VK_BLEND_ONE, // VkBlend srcBlendColor;
1072 VK_BLEND_ZERO, // VkBlend destBlendColor;
1073 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
1074 VK_BLEND_ONE, // VkBlend srcBlendAlpha;
1075 VK_BLEND_ZERO, // VkBlend destBlendAlpha;
1076 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
1077 VK_CHANNEL_R_BIT | VK_CHANNEL_G_BIT | VK_CHANNEL_B_BIT | VK_CHANNEL_A_BIT // VkChannelFlags channelWriteMask;
1080 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
1082 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1083 DE_NULL, // const void* pNext;
1084 false, // VkBool32 alphaToCoverageEnable;
1085 false, // VkBool32 logicOpEnable;
1086 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
1087 1u, // deUint32 attachmentCount;
1088 &colorBlendAttachmentState // const VkPipelineColorBlendAttachmentState* pAttachments;
1091 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
1093 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
1094 DE_NULL, // const void* pNext;
1095 2u, // deUint32 stageCount;
1096 shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages;
1097 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
1098 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
1099 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
1100 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
1101 &rasterStateParams, // const VkPipelineRasterStateCreateInfo* pRasterState;
1102 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
1103 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
1104 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
1105 0u, // VkPipelineCreateFlags flags;
1106 *m_pipelineLayout, // VkPipelineLayout layout;
1107 *m_renderPass, // VkRenderPass renderPass;
1108 0u, // deUint32 subpass;
1109 0u, // VkPipeline basePipelineHandle;
1110 0u // deInt32 basePipelineIndex;
1113 m_graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
1116 // Create dynamic states
1118 const VkViewport viewport =
1120 0.0f, // float originX;
1121 0.0f, // float originY;
1122 (float)m_renderSize.x(), // float width;
1123 (float)m_renderSize.y(), // float height;
1124 0.0f, // float minDepth;
1125 1.0f // float maxDepth;
1128 const VkRect2D scissor =
1136 const VkDynamicViewportStateCreateInfo viewportStateParams =
1138 VK_STRUCTURE_TYPE_DYNAMIC_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
1139 DE_NULL, // const void* pNext;
1140 1, // deUint32 viewportAndScissorCount;
1141 &viewport, // const VkViewport* pViewports;
1142 &scissor // const VkRect2D* pScissors;
1145 const VkDynamicRasterStateCreateInfo rasterStateParams =
1147 VK_STRUCTURE_TYPE_DYNAMIC_RASTER_STATE_CREATE_INFO, // VkStructureType sType;
1148 DE_NULL, // const void* pNext;
1149 0.0f, // float depthBias;
1150 0.0f, // float depthBiasClamp;
1151 0.0f, // float slopeScaledDepthBias;
1152 1.0f, // float lineWidth;
1156 const VkDynamicColorBlendStateCreateInfo colorBlendStateParams =
1158 VK_STRUCTURE_TYPE_DYNAMIC_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1159 DE_NULL, // const void* pNext;
1160 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConst[4];
1163 m_viewportState = createDynamicViewportState(vk, vkDevice, &viewportStateParams);
1164 m_rasterState = createDynamicRasterState(vk, vkDevice, &rasterStateParams);
1165 m_colorBlendState = createDynamicColorBlendState(vk, vkDevice, &colorBlendStateParams);
1168 // Create vertex indices buffer
1170 const VkDeviceSize indiceBufferSize = quadGrid.getNumTriangles() * 3 * sizeof(deUint16);
1171 const VkBufferCreateInfo indiceBufferParams =
1173 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1174 DE_NULL, // const void* pNext;
1175 indiceBufferSize, // VkDeviceSize size;
1176 VK_BUFFER_USAGE_INDEX_BUFFER_BIT, // VkBufferUsageFlags usage;
1177 0u, // VkBufferCreateFlags flags;
1178 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1179 1u, // deUint32 queueFamilyCount;
1180 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1183 m_indiceBuffer = createBuffer(vk, vkDevice, &indiceBufferParams);
1184 m_indiceBufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_indiceBuffer), MemoryRequirement::HostVisible);
1186 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_indiceBuffer, m_indiceBufferAlloc->getMemory(), 0));
1188 // Load vertice indices into buffer
1190 VK_CHECK(vk.mapMemory(vkDevice, m_indiceBufferAlloc->getMemory(), 0, indiceBufferSize, 0, &bufferPtr));
1191 deMemcpy(bufferPtr, quadGrid.getIndices(), indiceBufferSize);
1192 VK_CHECK(vk.unmapMemory(vkDevice, m_indiceBufferAlloc->getMemory()));
1195 // Create command pool
1197 const VkCmdPoolCreateInfo cmdPoolParams =
1199 VK_STRUCTURE_TYPE_CMD_POOL_CREATE_INFO, // VkStructureType sType;
1200 DE_NULL, // const void* pNext;
1201 queueFamilyIndex, // deUint32 queueFamilyIndex;
1202 VK_CMD_POOL_CREATE_TRANSIENT_BIT // VkCmdPoolCreateFlags flags;
1205 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1208 // Create command buffer
1210 const VkCmdBufferCreateInfo cmdBufferParams =
1212 VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, // VkStructureType sType;
1213 DE_NULL, // const void* pNext;
1214 *m_cmdPool, // VkCmdPool cmdPool;
1215 VK_CMD_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
1216 0u // VkCmdBufferCreateFlags flags;
1219 const VkCmdBufferBeginInfo cmdBufferBeginInfo =
1221 VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, // VkStructureType sType;
1222 DE_NULL, // const void* pNext;
1223 0u, // VkCmdBufferOptimizeFlags flags;
1224 DE_NULL, // VkRenderPass renderPass;
1225 DE_NULL // VkFramebuffer framebuffer;
1228 const VkClearValue attachmentClearValues[1] =
1230 { m_clearColor.x(), m_clearColor.y(), m_clearColor.z(), m_clearColor.w() }
1233 const VkRenderPassBeginInfo renderPassBeginInfo =
1235 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO , // VkStructureType sType;
1236 DE_NULL, // const void* pNext;
1237 *m_renderPass, // VkRenderPass renderPass;
1238 *m_framebuffer, // VkFramebuffer framebuffer;
1239 { 0, 0, m_renderSize.x(), m_renderSize.y() }, // VkRect2D renderArea;
1240 1, // deUint32 attachmentCount;
1241 attachmentClearValues // const VkClearValue* pAttachmentClearValues;
1244 m_cmdBuffer = createCommandBuffer(vk, vkDevice, &cmdBufferParams);
1246 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1248 // Add texture barriers
1249 std::vector<VkImageMemoryBarrier> barriers;
1250 std::vector<void*> barrierPtrs;
1252 for(size_t i = 0; i < m_textures.size(); i++)
1254 const TextureBinding& textureBinding = m_textures[i];
1255 const Texture2D* texture = textureBinding.get2D();
1256 VkImageMemoryBarrier textureBarrier =
1258 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
1260 VK_MEMORY_OUTPUT_HOST_WRITE_BIT | VK_MEMORY_OUTPUT_TRANSFER_BIT,
1262 VK_IMAGE_LAYOUT_UNDEFINED,
1263 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
1266 *texture->getVkTexture(),
1268 VK_IMAGE_ASPECT_COLOR,
1276 barriers.push_back(textureBarrier);
1277 barrierPtrs.push_back((void*)&barriers[i]);
1280 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]);
1282 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_RENDER_PASS_CONTENTS_INLINE);
1284 vk.cmdBindDynamicViewportState(*m_cmdBuffer, *m_viewportState);
1285 vk.cmdBindDynamicRasterState(*m_cmdBuffer, *m_rasterState);
1287 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
1288 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &*m_descriptorSet, 0u, DE_NULL);
1289 vk.cmdBindIndexBuffer(*m_cmdBuffer, *m_indiceBuffer, 0, VK_INDEX_TYPE_UINT16);
1292 const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size();
1293 std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0);
1295 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, numberOfVertexAttributes, &m_vertexBuffers[0], &offsets[0]);
1296 vk.cmdDrawIndexed(*m_cmdBuffer, 0, quadGrid.getNumTriangles() * 3, 0, 0, 1);
1298 vk.cmdEndRenderPass(*m_cmdBuffer);
1299 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1304 const VkFenceCreateInfo fenceParams =
1306 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
1307 DE_NULL, // const void* pNext;
1308 0u // VkFenceCreateFlags flags;
1310 m_fence = createFence(vk, vkDevice, &fenceParams);
1315 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1316 VK_CHECK(vk.queueSubmit(queue, 1, &m_cmdBuffer.get(), *m_fence));
1317 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/));
1320 // Read back the result
1322 const VkDeviceSize imageSizeBytes = (VkDeviceSize)(sizeof(deUint32) * m_renderSize.x() * m_renderSize.y());
1323 const VkBufferCreateInfo readImageBufferParams =
1325 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1326 DE_NULL, // const void* pNext;
1327 imageSizeBytes, // VkDeviceSize size;
1328 VK_BUFFER_USAGE_TRANSFER_DESTINATION_BIT, // VkBufferUsageFlags usage;
1329 0u, // VkBufferCreateFlags flags;
1330 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1331 1u, // deUint32 queueFamilyCount;
1332 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1334 const Unique<VkBuffer> readImageBuffer(createBuffer(vk, vkDevice, &readImageBufferParams));
1335 const de::UniquePtr<Allocation> readImageBufferMemory(m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
1337 VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
1340 // Copy image to buffer
1341 Move<VkCmdBuffer> cmdBuffer;
1343 const VkCmdBufferCreateInfo cmdBufferParams =
1345 VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, // VkStructureType sType;
1346 DE_NULL, // const void* pNext;
1347 *m_cmdPool, // VkCmdPool cmdPool;
1348 VK_CMD_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
1349 0u // VkCmdBufferCreateFlags flags;
1352 const VkCmdBufferBeginInfo cmdBufferBeginInfo =
1354 VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, // VkStructureType sType;
1355 DE_NULL, // const void* pNext;
1356 0u, // VkCmdBufferOptimizeFlags flags;
1357 DE_NULL, // VkRenderPass renderPass;
1358 DE_NULL // VkFramebuffer framebuffer;
1361 cmdBuffer = createCommandBuffer(vk, vkDevice, &cmdBufferParams);
1363 const VkBufferImageCopy copyParams =
1365 0u, // VkDeviceSize bufferOffset;
1366 m_renderSize.x() * 4u, // deUint32 bufferRowLength;
1367 0u, // deUint32 bufferImageHeight;
1369 VK_IMAGE_ASPECT_COLOR, // VkImageAspect aspect;
1370 0u, // deUint32 mipLevel;
1371 0u, // deUint32 arraySlice;
1372 }, // VkImageSubresource imageSubresource;
1373 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
1374 { m_renderSize.x(), m_renderSize.y(), 1u } // VkExtent3D imageExtent;
1377 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
1378 vk.cmdCopyImageToBuffer(*cmdBuffer, *m_colorImage, VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL, *readImageBuffer, 1u, ©Params);
1379 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
1381 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1382 VK_CHECK(vk.queueSubmit(queue, 1, &cmdBuffer.get(), *m_fence));
1383 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
1386 VK_CHECK(vk.mapMemory(vkDevice, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset(), imageSizeBytes, 0u, &imagePtr));
1388 const VkMappedMemoryRange range =
1390 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
1391 DE_NULL, // const void* pNext;
1392 readImageBufferMemory->getMemory(), // VkDeviceMemory mem;
1393 0, // VkDeviceSize offset;
1394 imageSizeBytes, // VkDeviceSize size;
1397 VK_CHECK(vk.invalidateMappedMemoryRanges(vkDevice, 1u, &range));
1399 deMemcpy(result.getAccess().getDataPtr(), imagePtr, imageSizeBytes);
1401 VK_CHECK(vk.unmapMemory(vkDevice, readImageBufferMemory->getMemory()));
1405 void ShaderRenderCaseInstance::computeVertexReference (tcu::Surface& result, const QuadGrid& quadGrid)
1408 int width = result.getWidth();
1409 int height = result.getHeight();
1410 int gridSize = quadGrid.getGridSize();
1411 int stride = gridSize + 1;
1412 bool hasAlpha = true; // \todo [2015-09-07 elecro] add correct alpha check
1413 ShaderEvalContext evalCtx (quadGrid);
1415 // Evaluate color for each vertex.
1416 std::vector<tcu::Vec4> colors ((gridSize + 1) * (gridSize + 1));
1417 for (int y = 0; y < gridSize+1; y++)
1418 for (int x = 0; x < gridSize+1; x++)
1420 float sx = (float)x / (float)gridSize;
1421 float sy = (float)y / (float)gridSize;
1422 int vtxNdx = ((y * (gridSize+1)) + x);
1424 evalCtx.reset(sx, sy);
1425 m_evaluator.evaluate(evalCtx);
1426 DE_ASSERT(!evalCtx.isDiscarded); // Discard is not available in vertex shader.
1427 tcu::Vec4 color = evalCtx.color;
1432 colors[vtxNdx] = color;
1436 for (int y = 0; y < gridSize; y++)
1437 for (int x = 0; x < gridSize; x++)
1439 float x0 = (float)x / (float)gridSize;
1440 float x1 = (float)(x + 1) / (float)gridSize;
1441 float y0 = (float)y / (float)gridSize;
1442 float y1 = (float)(y + 1) / (float)gridSize;
1444 float sx0 = x0 * (float)width;
1445 float sx1 = x1 * (float)width;
1446 float sy0 = y0 * (float)height;
1447 float sy1 = y1 * (float)height;
1448 float oosx = 1.0f / (sx1 - sx0);
1449 float oosy = 1.0f / (sy1 - sy0);
1451 int ix0 = deCeilFloatToInt32(sx0 - 0.5f);
1452 int ix1 = deCeilFloatToInt32(sx1 - 0.5f);
1453 int iy0 = deCeilFloatToInt32(sy0 - 0.5f);
1454 int iy1 = deCeilFloatToInt32(sy1 - 0.5f);
1456 int v00 = (y * stride) + x;
1457 int v01 = (y * stride) + x + 1;
1458 int v10 = ((y + 1) * stride) + x;
1459 int v11 = ((y + 1) * stride) + x + 1;
1460 tcu::Vec4 c00 = colors[v00];
1461 tcu::Vec4 c01 = colors[v01];
1462 tcu::Vec4 c10 = colors[v10];
1463 tcu::Vec4 c11 = colors[v11];
1465 //printf("(%d,%d) -> (%f..%f, %f..%f) (%d..%d, %d..%d)\n", x, y, sx0, sx1, sy0, sy1, ix0, ix1, iy0, iy1);
1467 for (int iy = iy0; iy < iy1; iy++)
1468 for (int ix = ix0; ix < ix1; ix++)
1470 DE_ASSERT(deInBounds32(ix, 0, width));
1471 DE_ASSERT(deInBounds32(iy, 0, height));
1473 float sfx = (float)ix + 0.5f;
1474 float sfy = (float)iy + 0.5f;
1475 float fx1 = deFloatClamp((sfx - sx0) * oosx, 0.0f, 1.0f);
1476 float fy1 = deFloatClamp((sfy - sy0) * oosy, 0.0f, 1.0f);
1478 // Triangle quad interpolation.
1479 bool tri = fx1 + fy1 <= 1.0f;
1480 float tx = tri ? fx1 : (1.0f-fx1);
1481 float ty = tri ? fy1 : (1.0f-fy1);
1482 const tcu::Vec4& t0 = tri ? c00 : c11;
1483 const tcu::Vec4& t1 = tri ? c01 : c10;
1484 const tcu::Vec4& t2 = tri ? c10 : c01;
1485 tcu::Vec4 color = t0 + (t1-t0)*tx + (t2-t0)*ty;
1487 result.setPixel(ix, iy, tcu::RGBA(color));
1492 void ShaderRenderCaseInstance::computeFragmentReference (tcu::Surface& result, const QuadGrid& quadGrid)
1495 int width = result.getWidth();
1496 int height = result.getHeight();
1497 bool hasAlpha = true; // \todo [2015-09-07 elecro] add correct alpha check
1498 ShaderEvalContext evalCtx (quadGrid);
1501 for (int y = 0; y < height; y++)
1502 for (int x = 0; x < width; x++)
1504 float sx = ((float)x + 0.5f) / (float)width;
1505 float sy = ((float)y + 0.5f) / (float)height;
1507 evalCtx.reset(sx, sy);
1508 m_evaluator.evaluate(evalCtx);
1509 // Select either clear color or computed color based on discarded bit.
1510 tcu::Vec4 color = evalCtx.isDiscarded ? m_clearColor : evalCtx.color;
1515 result.setPixel(x, y, tcu::RGBA(color));
1519 bool ShaderRenderCaseInstance::compareImages (const tcu::Surface& resImage, const tcu::Surface& refImage, float errorThreshold)
1521 return tcu::fuzzyCompare(m_context.getTestContext().getLog(), "ComparisonResult", "Image comparison result", refImage, resImage, errorThreshold, tcu::COMPARE_LOG_RESULT);
1525 } // shaderrendercase