1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7 * Copyright (c) 2016 The Android Open Source Project
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
23 * \brief Vulkan ShaderRenderCase
24 *//*--------------------------------------------------------------------*/
26 #include "vktShaderRender.hpp"
28 #include "tcuImageCompare.hpp"
29 #include "tcuImageIO.hpp"
30 #include "tcuTestLog.hpp"
31 #include "tcuTextureUtil.hpp"
32 #include "tcuSurface.hpp"
33 #include "tcuVector.hpp"
35 #include "deFilePath.hpp"
37 #include "deUniquePtr.hpp"
39 #include "vkDeviceUtil.hpp"
40 #include "vkImageUtil.hpp"
41 #include "vkPlatform.hpp"
42 #include "vkQueryUtil.hpp"
44 #include "vkRefUtil.hpp"
45 #include "vkStrUtil.hpp"
46 #include "vkTypeUtil.hpp"
47 #include "vkCmdUtil.hpp"
48 #include "vkObjUtil.hpp"
60 VkImageViewType textureTypeToImageViewType (TextureBinding::Type type)
64 case TextureBinding::TYPE_1D: return VK_IMAGE_VIEW_TYPE_1D;
65 case TextureBinding::TYPE_2D: return VK_IMAGE_VIEW_TYPE_2D;
66 case TextureBinding::TYPE_3D: return VK_IMAGE_VIEW_TYPE_3D;
67 case TextureBinding::TYPE_CUBE_MAP: return VK_IMAGE_VIEW_TYPE_CUBE;
68 case TextureBinding::TYPE_1D_ARRAY: return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
69 case TextureBinding::TYPE_2D_ARRAY: return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
70 case TextureBinding::TYPE_CUBE_ARRAY: return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
73 DE_FATAL("Impossible");
74 return (VkImageViewType)0;
78 VkImageType viewTypeToImageType (VkImageViewType type)
82 case VK_IMAGE_VIEW_TYPE_1D:
83 case VK_IMAGE_VIEW_TYPE_1D_ARRAY: return VK_IMAGE_TYPE_1D;
84 case VK_IMAGE_VIEW_TYPE_2D:
85 case VK_IMAGE_VIEW_TYPE_2D_ARRAY: return VK_IMAGE_TYPE_2D;
86 case VK_IMAGE_VIEW_TYPE_3D: return VK_IMAGE_TYPE_3D;
87 case VK_IMAGE_VIEW_TYPE_CUBE:
88 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return VK_IMAGE_TYPE_2D;
91 DE_FATAL("Impossible");
92 return (VkImageType)0;
96 vk::VkImageUsageFlags textureUsageFlags (void)
98 return (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
101 vk::VkImageCreateFlags textureCreateFlags (vk::VkImageViewType viewType, ShaderRenderCaseInstance::ImageBackingMode backingMode)
103 const bool isCube = (viewType == VK_IMAGE_VIEW_TYPE_CUBE || viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY);
104 VkImageCreateFlags imageCreateFlags = (isCube ? static_cast<VkImageCreateFlags>(VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) : 0u);
106 if (backingMode == ShaderRenderCaseInstance::IMAGE_BACKING_MODE_SPARSE)
107 imageCreateFlags |= (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT);
109 return imageCreateFlags;
115 static const deUint32 MAX_RENDER_WIDTH = 128;
116 static const deUint32 MAX_RENDER_HEIGHT = 128;
117 static const tcu::Vec4 DEFAULT_CLEAR_COLOR = tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f);
119 /*! Gets the next multiple of a given divisor */
120 static deUint32 getNextMultiple (deUint32 divisor, deUint32 value)
122 if (value % divisor == 0)
126 return value + divisor - (value % divisor);
129 /*! Gets the next value that is multiple of all given divisors */
130 static deUint32 getNextMultiple (const std::vector<deUint32>& divisors, deUint32 value)
132 deUint32 nextMultiple = value;
133 bool nextMultipleFound = false;
137 nextMultipleFound = true;
139 for (size_t divNdx = 0; divNdx < divisors.size(); divNdx++)
140 nextMultipleFound = nextMultipleFound && (nextMultiple % divisors[divNdx] == 0);
142 if (nextMultipleFound)
145 DE_ASSERT(nextMultiple < ~((deUint32)0u));
146 nextMultiple = getNextMultiple(divisors[0], nextMultiple + 1);
159 QuadGrid (int gridSize,
162 const tcu::Vec4& constCoords,
163 const std::vector<tcu::Mat4>& userAttribTransforms,
164 const std::vector<TextureBindingSp>& textures);
167 int getGridSize (void) const { return m_gridSize; }
168 int getNumVertices (void) const { return m_numVertices; }
169 int getNumTriangles (void) const { return m_numTriangles; }
170 const tcu::Vec4& getConstCoords (void) const { return m_constCoords; }
171 const std::vector<tcu::Mat4> getUserAttribTransforms (void) const { return m_userAttribTransforms; }
172 const std::vector<TextureBindingSp>& getTextures (void) const { return m_textures; }
174 const tcu::Vec4* getPositions (void) const { return &m_positions[0]; }
175 const float* getAttribOne (void) const { return &m_attribOne[0]; }
176 const tcu::Vec4* getCoords (void) const { return &m_coords[0]; }
177 const tcu::Vec4* getUnitCoords (void) const { return &m_unitCoords[0]; }
179 const tcu::Vec4* getUserAttrib (int attribNdx) const { return &m_userAttribs[attribNdx][0]; }
180 const deUint16* getIndices (void) const { return &m_indices[0]; }
182 tcu::Vec4 getCoords (float sx, float sy) const;
183 tcu::Vec4 getUnitCoords (float sx, float sy) const;
185 int getNumUserAttribs (void) const { return (int)m_userAttribTransforms.size(); }
186 tcu::Vec4 getUserAttrib (int attribNdx, float sx, float sy) const;
189 const int m_gridSize;
190 const int m_numVertices;
191 const int m_numTriangles;
192 const tcu::Vec4 m_constCoords;
193 const std::vector<tcu::Mat4> m_userAttribTransforms;
195 const std::vector<TextureBindingSp>& m_textures;
197 std::vector<tcu::Vec4> m_screenPos;
198 std::vector<tcu::Vec4> m_positions;
199 std::vector<tcu::Vec4> m_coords; //!< Near-unit coordinates, roughly [-2.0 .. 2.0].
200 std::vector<tcu::Vec4> m_unitCoords; //!< Positive-only coordinates [0.0 .. 1.5].
201 std::vector<float> m_attribOne;
202 std::vector<tcu::Vec4> m_userAttribs[ShaderEvalContext::MAX_TEXTURES];
203 std::vector<deUint16> m_indices;
206 QuadGrid::QuadGrid (int gridSize,
209 const tcu::Vec4& constCoords,
210 const std::vector<tcu::Mat4>& userAttribTransforms,
211 const std::vector<TextureBindingSp>& textures)
212 : m_gridSize (gridSize)
213 , m_numVertices ((gridSize + 1) * (gridSize + 1))
214 , m_numTriangles (gridSize * gridSize * 2)
215 , m_constCoords (constCoords)
216 , m_userAttribTransforms (userAttribTransforms)
217 , m_textures (textures)
219 const tcu::Vec4 viewportScale ((float)width, (float)height, 0.0f, 0.0f);
222 m_screenPos.resize(m_numVertices);
223 m_positions.resize(m_numVertices);
224 m_coords.resize(m_numVertices);
225 m_unitCoords.resize(m_numVertices);
226 m_attribOne.resize(m_numVertices);
229 for (int attrNdx = 0; attrNdx < DE_LENGTH_OF_ARRAY(m_userAttribs); attrNdx++)
230 m_userAttribs[attrNdx].resize(m_numVertices);
232 for (int y = 0; y < gridSize+1; y++)
233 for (int x = 0; x < gridSize+1; x++)
235 float sx = (float)x / (float)gridSize;
236 float sy = (float)y / (float)gridSize;
237 float fx = 2.0f * sx - 1.0f;
238 float fy = 2.0f * sy - 1.0f;
239 int vtxNdx = ((y * (gridSize+1)) + x);
241 m_positions[vtxNdx] = tcu::Vec4(fx, fy, 0.0f, 1.0f);
242 m_coords[vtxNdx] = getCoords(sx, sy);
243 m_unitCoords[vtxNdx] = getUnitCoords(sx, sy);
244 m_attribOne[vtxNdx] = 1.0f;
246 m_screenPos[vtxNdx] = tcu::Vec4(sx, sy, 0.0f, 1.0f) * viewportScale;
248 for (int attribNdx = 0; attribNdx < getNumUserAttribs(); attribNdx++)
249 m_userAttribs[attribNdx][vtxNdx] = getUserAttrib(attribNdx, sx, sy);
253 m_indices.resize(3 * m_numTriangles);
254 for (int y = 0; y < gridSize; y++)
255 for (int x = 0; x < gridSize; x++)
257 int stride = gridSize + 1;
258 int v00 = (y * stride) + x;
259 int v01 = (y * stride) + x + 1;
260 int v10 = ((y+1) * stride) + x;
261 int v11 = ((y+1) * stride) + x + 1;
263 int baseNdx = ((y * gridSize) + x) * 6;
264 m_indices[baseNdx + 0] = (deUint16)v10;
265 m_indices[baseNdx + 1] = (deUint16)v00;
266 m_indices[baseNdx + 2] = (deUint16)v01;
268 m_indices[baseNdx + 3] = (deUint16)v10;
269 m_indices[baseNdx + 4] = (deUint16)v01;
270 m_indices[baseNdx + 5] = (deUint16)v11;
274 QuadGrid::~QuadGrid (void)
278 inline tcu::Vec4 QuadGrid::getCoords (float sx, float sy) const
280 const float fx = 2.0f * sx - 1.0f;
281 const float fy = 2.0f * sy - 1.0f;
282 return tcu::Vec4(fx, fy, -fx + 0.33f*fy, -0.275f*fx - fy);
285 inline tcu::Vec4 QuadGrid::getUnitCoords (float sx, float sy) const
287 return tcu::Vec4(sx, sy, 0.33f*sx + 0.5f*sy, 0.5f*sx + 0.25f*sy);
290 inline tcu::Vec4 QuadGrid::getUserAttrib (int attribNdx, float sx, float sy) const
292 // homogeneous normalized screen-space coordinates
293 return m_userAttribTransforms[attribNdx] * tcu::Vec4(sx, sy, 0.0f, 1.0f);
298 TextureBinding::TextureBinding (const tcu::Archive& archive,
299 const char* filename,
301 const tcu::Sampler& sampler)
303 , m_sampler (sampler)
307 case TYPE_2D: m_binding.tex2D = loadTexture2D(archive, filename).release(); break;
309 DE_FATAL("Unsupported texture type");
313 TextureBinding::TextureBinding (const tcu::Texture1D* tex1D, const tcu::Sampler& sampler)
315 , m_sampler (sampler)
317 m_binding.tex1D = tex1D;
320 TextureBinding::TextureBinding (const tcu::Texture2D* tex2D, const tcu::Sampler& sampler)
322 , m_sampler (sampler)
324 m_binding.tex2D = tex2D;
327 TextureBinding::TextureBinding (const tcu::Texture3D* tex3D, const tcu::Sampler& sampler)
329 , m_sampler (sampler)
331 m_binding.tex3D = tex3D;
334 TextureBinding::TextureBinding (const tcu::TextureCube* texCube, const tcu::Sampler& sampler)
335 : m_type (TYPE_CUBE_MAP)
336 , m_sampler (sampler)
338 m_binding.texCube = texCube;
341 TextureBinding::TextureBinding (const tcu::Texture1DArray* tex1DArray, const tcu::Sampler& sampler)
342 : m_type (TYPE_1D_ARRAY)
343 , m_sampler (sampler)
345 m_binding.tex1DArray = tex1DArray;
348 TextureBinding::TextureBinding (const tcu::Texture2DArray* tex2DArray, const tcu::Sampler& sampler)
349 : m_type (TYPE_2D_ARRAY)
350 , m_sampler (sampler)
352 m_binding.tex2DArray = tex2DArray;
355 TextureBinding::TextureBinding (const tcu::TextureCubeArray* texCubeArray, const tcu::Sampler& sampler)
356 : m_type (TYPE_CUBE_ARRAY)
357 , m_sampler (sampler)
359 m_binding.texCubeArray = texCubeArray;
362 TextureBinding::~TextureBinding (void)
366 case TYPE_1D: delete m_binding.tex1D; break;
367 case TYPE_2D: delete m_binding.tex2D; break;
368 case TYPE_3D: delete m_binding.tex3D; break;
369 case TYPE_CUBE_MAP: delete m_binding.texCube; break;
370 case TYPE_1D_ARRAY: delete m_binding.tex1DArray; break;
371 case TYPE_2D_ARRAY: delete m_binding.tex2DArray; break;
372 case TYPE_CUBE_ARRAY: delete m_binding.texCubeArray; break;
377 de::MovePtr<tcu::Texture2D> TextureBinding::loadTexture2D (const tcu::Archive& archive, const char* filename)
379 tcu::TextureLevel level;
380 tcu::ImageIO::loadImage(level, archive, filename);
382 TCU_CHECK_INTERNAL(level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) ||
383 level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8));
385 // \todo [2015-10-08 elecro] for some reason we get better when using RGBA texture even in RGB case, this needs to be investigated
386 de::MovePtr<tcu::Texture2D> texture(new tcu::Texture2D(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), level.getWidth(), level.getHeight()));
389 texture->allocLevel(0);
390 tcu::copy(texture->getLevel(0), level.getAccess());
395 // ShaderEvalContext.
397 ShaderEvalContext::ShaderEvalContext (const QuadGrid& quadGrid)
398 : constCoords (quadGrid.getConstCoords())
399 , isDiscarded (false)
400 , m_quadGrid (quadGrid)
402 const std::vector<TextureBindingSp>& bindings = m_quadGrid.getTextures();
403 DE_ASSERT((int)bindings.size() <= MAX_TEXTURES);
405 // Fill in texture array.
406 for (int ndx = 0; ndx < (int)bindings.size(); ndx++)
408 const TextureBinding& binding = *bindings[ndx];
410 if (binding.getType() == TextureBinding::TYPE_NONE)
413 textures[ndx].sampler = binding.getSampler();
415 switch (binding.getType())
417 case TextureBinding::TYPE_1D: textures[ndx].tex1D = &binding.get1D(); break;
418 case TextureBinding::TYPE_2D: textures[ndx].tex2D = &binding.get2D(); break;
419 case TextureBinding::TYPE_3D: textures[ndx].tex3D = &binding.get3D(); break;
420 case TextureBinding::TYPE_CUBE_MAP: textures[ndx].texCube = &binding.getCube(); break;
421 case TextureBinding::TYPE_1D_ARRAY: textures[ndx].tex1DArray = &binding.get1DArray(); break;
422 case TextureBinding::TYPE_2D_ARRAY: textures[ndx].tex2DArray = &binding.get2DArray(); break;
423 case TextureBinding::TYPE_CUBE_ARRAY: textures[ndx].texCubeArray = &binding.getCubeArray(); break;
425 TCU_THROW(InternalError, "Handling of texture binding type not implemented");
430 ShaderEvalContext::~ShaderEvalContext (void)
434 void ShaderEvalContext::reset (float sx, float sy)
437 color = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
441 coords = m_quadGrid.getCoords(sx, sy);
442 unitCoords = m_quadGrid.getUnitCoords(sx, sy);
444 // Compute user attributes.
445 const int numAttribs = m_quadGrid.getNumUserAttribs();
446 DE_ASSERT(numAttribs <= MAX_USER_ATTRIBS);
447 for (int attribNdx = 0; attribNdx < numAttribs; attribNdx++)
448 in[attribNdx] = m_quadGrid.getUserAttrib(attribNdx, sx, sy);
451 tcu::Vec4 ShaderEvalContext::texture2D (int unitNdx, const tcu::Vec2& texCoords)
453 if (textures[unitNdx].tex2D)
454 return textures[unitNdx].tex2D->sample(textures[unitNdx].sampler, texCoords.x(), texCoords.y(), 0.0f);
456 return tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
461 ShaderEvaluator::ShaderEvaluator (void)
462 : m_evalFunc(DE_NULL)
466 ShaderEvaluator::ShaderEvaluator (ShaderEvalFunc evalFunc)
467 : m_evalFunc(evalFunc)
471 ShaderEvaluator::~ShaderEvaluator (void)
475 void ShaderEvaluator::evaluate (ShaderEvalContext& ctx) const
477 DE_ASSERT(m_evalFunc);
483 UniformSetup::UniformSetup (void)
484 : m_setupFunc(DE_NULL)
488 UniformSetup::UniformSetup (UniformSetupFunc setupFunc)
489 : m_setupFunc(setupFunc)
493 UniformSetup::~UniformSetup (void)
497 void UniformSetup::setup (ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords) const
500 m_setupFunc(instance, constCoords);
505 ShaderRenderCase::ShaderRenderCase (tcu::TestContext& testCtx,
506 const std::string& name,
507 const std::string& description,
508 const bool isVertexCase,
509 const ShaderEvalFunc evalFunc,
510 const UniformSetup* uniformSetup,
511 const AttributeSetupFunc attribFunc)
512 : vkt::TestCase (testCtx, name, description)
513 , m_isVertexCase (isVertexCase)
514 , m_evaluator (new ShaderEvaluator(evalFunc))
515 , m_uniformSetup (uniformSetup ? uniformSetup : new UniformSetup())
516 , m_attribFunc (attribFunc)
519 ShaderRenderCase::ShaderRenderCase (tcu::TestContext& testCtx,
520 const std::string& name,
521 const std::string& description,
522 const bool isVertexCase,
523 const ShaderEvaluator* evaluator,
524 const UniformSetup* uniformSetup,
525 const AttributeSetupFunc attribFunc)
526 : vkt::TestCase (testCtx, name, description)
527 , m_isVertexCase (isVertexCase)
528 , m_evaluator (evaluator)
529 , m_uniformSetup (uniformSetup ? uniformSetup : new UniformSetup())
530 , m_attribFunc (attribFunc)
533 ShaderRenderCase::~ShaderRenderCase (void)
537 void ShaderRenderCase::initPrograms (vk::SourceCollections& programCollection) const
539 programCollection.glslSources.add("vert") << glu::VertexSource(m_vertShaderSource);
540 programCollection.glslSources.add("frag") << glu::FragmentSource(m_fragShaderSource);
543 TestInstance* ShaderRenderCase::createInstance (Context& context) const
545 DE_ASSERT(m_evaluator != DE_NULL);
546 DE_ASSERT(m_uniformSetup != DE_NULL);
547 return new ShaderRenderCaseInstance(context, m_isVertexCase, *m_evaluator, *m_uniformSetup, m_attribFunc);
550 // ShaderRenderCaseInstance.
552 ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context& context)
553 : vkt::TestInstance (context)
554 , m_imageBackingMode (IMAGE_BACKING_MODE_REGULAR)
555 , m_quadGridSize (static_cast<deUint32>(GRID_SIZE_DEFAULT_FRAGMENT))
556 , m_memAlloc (getAllocator())
557 , m_clearColor (DEFAULT_CLEAR_COLOR)
558 , m_isVertexCase (false)
559 , m_vertexShaderName ("vert")
560 , m_fragmentShaderName ("frag")
561 , m_renderSize (MAX_RENDER_WIDTH, MAX_RENDER_HEIGHT)
562 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
563 , m_evaluator (DE_NULL)
564 , m_uniformSetup (DE_NULL)
565 , m_attribFunc (DE_NULL)
566 , m_sampleCount (VK_SAMPLE_COUNT_1_BIT)
567 , m_fuzzyCompare (true)
572 ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context& context,
573 const bool isVertexCase,
574 const ShaderEvaluator& evaluator,
575 const UniformSetup& uniformSetup,
576 const AttributeSetupFunc attribFunc,
577 const ImageBackingMode imageBackingMode,
578 const deUint32 gridSize,
579 const bool fuzzyCompare)
580 : vkt::TestInstance (context)
581 , m_imageBackingMode (imageBackingMode)
582 , m_quadGridSize (gridSize == static_cast<deUint32>(GRID_SIZE_DEFAULTS)
584 ? static_cast<deUint32>(GRID_SIZE_DEFAULT_VERTEX)
585 : static_cast<deUint32>(GRID_SIZE_DEFAULT_FRAGMENT))
587 , m_memAlloc (getAllocator())
588 , m_clearColor (DEFAULT_CLEAR_COLOR)
589 , m_isVertexCase (isVertexCase)
590 , m_vertexShaderName ("vert")
591 , m_fragmentShaderName ("frag")
592 , m_renderSize (MAX_RENDER_WIDTH, MAX_RENDER_HEIGHT)
593 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
594 , m_evaluator (&evaluator)
595 , m_uniformSetup (&uniformSetup)
596 , m_attribFunc (attribFunc)
597 , m_sampleCount (VK_SAMPLE_COUNT_1_BIT)
598 , m_fuzzyCompare (fuzzyCompare)
602 ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context& context,
603 const bool isVertexCase,
604 const ShaderEvaluator* evaluator,
605 const UniformSetup* uniformSetup,
606 const AttributeSetupFunc attribFunc,
607 const ImageBackingMode imageBackingMode,
608 const deUint32 gridSize)
609 : vkt::TestInstance (context)
610 , m_imageBackingMode (imageBackingMode)
611 , m_quadGridSize (gridSize == static_cast<deUint32>(GRID_SIZE_DEFAULTS)
613 ? static_cast<deUint32>(GRID_SIZE_DEFAULT_VERTEX)
614 : static_cast<deUint32>(GRID_SIZE_DEFAULT_FRAGMENT))
616 , m_memAlloc (getAllocator())
617 , m_clearColor (DEFAULT_CLEAR_COLOR)
618 , m_isVertexCase (isVertexCase)
619 , m_vertexShaderName ("vert")
620 , m_fragmentShaderName ("frag")
621 , m_renderSize (MAX_RENDER_WIDTH, MAX_RENDER_HEIGHT)
622 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
623 , m_evaluator (evaluator)
624 , m_uniformSetup (uniformSetup)
625 , m_attribFunc (attribFunc)
626 , m_sampleCount (VK_SAMPLE_COUNT_1_BIT)
627 , m_fuzzyCompare (false)
631 vk::Allocator& ShaderRenderCaseInstance::getAllocator (void) const
633 return m_context.getDefaultAllocator();
636 ShaderRenderCaseInstance::~ShaderRenderCaseInstance (void)
640 VkDevice ShaderRenderCaseInstance::getDevice (void) const
642 return m_context.getDevice();
645 deUint32 ShaderRenderCaseInstance::getUniversalQueueFamilyIndex (void) const
647 return m_context.getUniversalQueueFamilyIndex();
650 deUint32 ShaderRenderCaseInstance::getSparseQueueFamilyIndex (void) const
652 return m_context.getSparseQueueFamilyIndex();
655 const DeviceInterface& ShaderRenderCaseInstance::getDeviceInterface (void) const
657 return m_context.getDeviceInterface();
660 VkQueue ShaderRenderCaseInstance::getUniversalQueue (void) const
662 return m_context.getUniversalQueue();
665 VkQueue ShaderRenderCaseInstance::getSparseQueue (void) const
667 return m_context.getSparseQueue();
670 VkPhysicalDevice ShaderRenderCaseInstance::getPhysicalDevice (void) const
672 return m_context.getPhysicalDevice();
675 const InstanceInterface& ShaderRenderCaseInstance::getInstanceInterface (void) const
677 return m_context.getInstanceInterface();
680 tcu::TestStatus ShaderRenderCaseInstance::iterate (void)
685 const tcu::UVec2 viewportSize = getViewportSize();
686 const int width = viewportSize.x();
687 const int height = viewportSize.y();
689 m_quadGrid = de::MovePtr<QuadGrid>(new QuadGrid(m_quadGridSize, width, height, getDefaultConstCoords(), m_userAttribTransforms, m_textures));
692 tcu::Surface resImage (width, height);
694 render(m_quadGrid->getNumVertices(), m_quadGrid->getNumTriangles(), m_quadGrid->getIndices(), m_quadGrid->getConstCoords());
695 tcu::copy(resImage.getAccess(), m_resultImage.getAccess());
697 // Compute reference.
698 tcu::Surface refImage (width, height);
700 computeVertexReference(refImage, *m_quadGrid);
702 computeFragmentReference(refImage, *m_quadGrid);
705 const bool compareOk = compareImages(resImage, refImage, 0.2f);
708 return tcu::TestStatus::pass("Result image matches reference");
710 return tcu::TestStatus::fail("Image mismatch");
713 void ShaderRenderCaseInstance::setup (void)
715 m_resultImage = tcu::TextureLevel();
716 m_descriptorSetLayoutBuilder = de::MovePtr<DescriptorSetLayoutBuilder> (new DescriptorSetLayoutBuilder());
717 m_descriptorPoolBuilder = de::MovePtr<DescriptorPoolBuilder> (new DescriptorPoolBuilder());
718 m_descriptorSetUpdateBuilder = de::MovePtr<DescriptorSetUpdateBuilder> (new DescriptorSetUpdateBuilder());
720 m_uniformInfos.clear();
721 m_vertexBindingDescription.clear();
722 m_vertexAttributeDescription.clear();
723 m_vertexBuffers.clear();
724 m_vertexBufferAllocs.clear();
725 m_pushConstantRanges.clear();
728 void ShaderRenderCaseInstance::setupUniformData (deUint32 bindingLocation, size_t size, const void* dataPtr)
730 const VkDevice vkDevice = getDevice();
731 const DeviceInterface& vk = getDeviceInterface();
732 const deUint32 queueFamilyIndex = getUniversalQueueFamilyIndex();
734 const VkBufferCreateInfo uniformBufferParams =
736 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
737 DE_NULL, // const void* pNext;
738 0u, // VkBufferCreateFlags flags;
739 size, // VkDeviceSize size;
740 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, // VkBufferUsageFlags usage;
741 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
742 1u, // deUint32 queueFamilyCount;
743 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
746 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &uniformBufferParams);
747 de::MovePtr<Allocation> alloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
748 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
750 deMemcpy(alloc->getHostPtr(), dataPtr, size);
751 flushAlloc(vk, vkDevice, *alloc);
753 de::MovePtr<BufferUniform> uniformInfo(new BufferUniform());
754 uniformInfo->type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
755 uniformInfo->descriptor = makeDescriptorBufferInfo(*buffer, 0u, size);
756 uniformInfo->location = bindingLocation;
757 uniformInfo->buffer = VkBufferSp(new vk::Unique<VkBuffer>(buffer));
758 uniformInfo->alloc = AllocationSp(alloc.release());
760 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniformInfo)));
763 void ShaderRenderCaseInstance::addUniform (deUint32 bindingLocation, vk::VkDescriptorType descriptorType, size_t dataSize, const void* data)
765 m_descriptorSetLayoutBuilder->addSingleBinding(descriptorType, vk::VK_SHADER_STAGE_ALL);
766 m_descriptorPoolBuilder->addType(descriptorType);
768 setupUniformData(bindingLocation, dataSize, data);
771 void ShaderRenderCaseInstance::addAttribute (deUint32 bindingLocation,
773 deUint32 sizePerElement,
777 // Portability requires stride to be multiply of minVertexInputBindingStrideAlignment
778 // this value is usually 4 and current tests meet this requirement but
779 // if this changes in future then this limit should be verified in checkSupport
780 #ifndef CTS_USES_VULKANSC
781 if (m_context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
782 ((sizePerElement % m_context.getPortabilitySubsetProperties().minVertexInputBindingStrideAlignment) != 0))
784 DE_FATAL("stride is not multiply of minVertexInputBindingStrideAlignment");
786 #endif // CTS_USES_VULKANSC
788 // Add binding specification
789 const deUint32 binding = (deUint32)m_vertexBindingDescription.size();
790 const VkVertexInputBindingDescription bindingDescription =
792 binding, // deUint32 binding;
793 sizePerElement, // deUint32 stride;
794 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate stepRate;
797 m_vertexBindingDescription.push_back(bindingDescription);
799 // Add location and format specification
800 const VkVertexInputAttributeDescription attributeDescription =
802 bindingLocation, // deUint32 location;
803 binding, // deUint32 binding;
804 format, // VkFormat format;
805 0u, // deUint32 offset;
808 m_vertexAttributeDescription.push_back(attributeDescription);
810 // Upload data to buffer
811 const VkDevice vkDevice = getDevice();
812 const DeviceInterface& vk = getDeviceInterface();
813 const deUint32 queueFamilyIndex = getUniversalQueueFamilyIndex();
815 const VkDeviceSize inputSize = sizePerElement * count;
816 const VkBufferCreateInfo vertexBufferParams =
818 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
819 DE_NULL, // const void* pNext;
820 0u, // VkBufferCreateFlags flags;
821 inputSize, // VkDeviceSize size;
822 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
823 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
824 1u, // deUint32 queueFamilyCount;
825 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
828 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &vertexBufferParams);
829 de::MovePtr<vk::Allocation> alloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
830 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
832 deMemcpy(alloc->getHostPtr(), dataPtr, (size_t)inputSize);
833 flushAlloc(vk, vkDevice, *alloc);
835 m_vertexBuffers.push_back(VkBufferSp(new vk::Unique<VkBuffer>(buffer)));
836 m_vertexBufferAllocs.push_back(AllocationSp(alloc.release()));
839 void ShaderRenderCaseInstance::useAttribute (deUint32 bindingLocation, BaseAttributeType type)
841 const EnabledBaseAttribute attribute =
843 bindingLocation, // deUint32 location;
844 type // BaseAttributeType type;
846 m_enabledBaseAttributes.push_back(attribute);
849 void ShaderRenderCaseInstance::setupUniforms (const tcu::Vec4& constCoords)
852 m_uniformSetup->setup(*this, constCoords);
855 void ShaderRenderCaseInstance::useUniform (deUint32 bindingLocation, BaseUniformType type)
857 #define UNIFORM_CASE(type, value) case type: addUniform(bindingLocation, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, value); break
862 UNIFORM_CASE(UB_FALSE, 0);
863 UNIFORM_CASE(UB_TRUE, 1);
866 UNIFORM_CASE(UB4_FALSE, tcu::Vec4(0));
867 UNIFORM_CASE(UB4_TRUE, tcu::Vec4(1));
870 UNIFORM_CASE(UI_ZERO, 0);
871 UNIFORM_CASE(UI_ONE, 1);
872 UNIFORM_CASE(UI_TWO, 2);
873 UNIFORM_CASE(UI_THREE, 3);
874 UNIFORM_CASE(UI_FOUR, 4);
875 UNIFORM_CASE(UI_FIVE, 5);
876 UNIFORM_CASE(UI_SIX, 6);
877 UNIFORM_CASE(UI_SEVEN, 7);
878 UNIFORM_CASE(UI_EIGHT, 8);
879 UNIFORM_CASE(UI_ONEHUNDREDONE, 101);
882 UNIFORM_CASE(UI2_MINUS_ONE, tcu::IVec2(-1));
883 UNIFORM_CASE(UI2_ZERO, tcu::IVec2(0));
884 UNIFORM_CASE(UI2_ONE, tcu::IVec2(1));
885 UNIFORM_CASE(UI2_TWO, tcu::IVec2(2));
886 UNIFORM_CASE(UI2_THREE, tcu::IVec2(3));
887 UNIFORM_CASE(UI2_FOUR, tcu::IVec2(4));
888 UNIFORM_CASE(UI2_FIVE, tcu::IVec2(5));
891 UNIFORM_CASE(UI3_MINUS_ONE, tcu::IVec3(-1));
892 UNIFORM_CASE(UI3_ZERO, tcu::IVec3(0));
893 UNIFORM_CASE(UI3_ONE, tcu::IVec3(1));
894 UNIFORM_CASE(UI3_TWO, tcu::IVec3(2));
895 UNIFORM_CASE(UI3_THREE, tcu::IVec3(3));
896 UNIFORM_CASE(UI3_FOUR, tcu::IVec3(4));
897 UNIFORM_CASE(UI3_FIVE, tcu::IVec3(5));
900 UNIFORM_CASE(UI4_MINUS_ONE, tcu::IVec4(-1));
901 UNIFORM_CASE(UI4_ZERO, tcu::IVec4(0));
902 UNIFORM_CASE(UI4_ONE, tcu::IVec4(1));
903 UNIFORM_CASE(UI4_TWO, tcu::IVec4(2));
904 UNIFORM_CASE(UI4_THREE, tcu::IVec4(3));
905 UNIFORM_CASE(UI4_FOUR, tcu::IVec4(4));
906 UNIFORM_CASE(UI4_FIVE, tcu::IVec4(5));
909 UNIFORM_CASE(UF_ZERO, 0.0f);
910 UNIFORM_CASE(UF_ONE, 1.0f);
911 UNIFORM_CASE(UF_TWO, 2.0f);
912 UNIFORM_CASE(UF_THREE, 3.0f);
913 UNIFORM_CASE(UF_FOUR, 4.0f);
914 UNIFORM_CASE(UF_FIVE, 5.0f);
915 UNIFORM_CASE(UF_SIX, 6.0f);
916 UNIFORM_CASE(UF_SEVEN, 7.0f);
917 UNIFORM_CASE(UF_EIGHT, 8.0f);
919 UNIFORM_CASE(UF_HALF, 1.0f / 2.0f);
920 UNIFORM_CASE(UF_THIRD, 1.0f / 3.0f);
921 UNIFORM_CASE(UF_FOURTH, 1.0f / 4.0f);
922 UNIFORM_CASE(UF_FIFTH, 1.0f / 5.0f);
923 UNIFORM_CASE(UF_SIXTH, 1.0f / 6.0f);
924 UNIFORM_CASE(UF_SEVENTH, 1.0f / 7.0f);
925 UNIFORM_CASE(UF_EIGHTH, 1.0f / 8.0f);
928 UNIFORM_CASE(UV2_MINUS_ONE, tcu::Vec2(-1.0f));
929 UNIFORM_CASE(UV2_ZERO, tcu::Vec2(0.0f));
930 UNIFORM_CASE(UV2_ONE, tcu::Vec2(1.0f));
931 UNIFORM_CASE(UV2_TWO, tcu::Vec2(2.0f));
932 UNIFORM_CASE(UV2_THREE, tcu::Vec2(3.0f));
934 UNIFORM_CASE(UV2_HALF, tcu::Vec2(1.0f / 2.0f));
937 UNIFORM_CASE(UV3_MINUS_ONE, tcu::Vec3(-1.0f));
938 UNIFORM_CASE(UV3_ZERO, tcu::Vec3(0.0f));
939 UNIFORM_CASE(UV3_ONE, tcu::Vec3(1.0f));
940 UNIFORM_CASE(UV3_TWO, tcu::Vec3(2.0f));
941 UNIFORM_CASE(UV3_THREE, tcu::Vec3(3.0f));
943 UNIFORM_CASE(UV3_HALF, tcu::Vec3(1.0f / 2.0f));
946 UNIFORM_CASE(UV4_MINUS_ONE, tcu::Vec4(-1.0f));
947 UNIFORM_CASE(UV4_ZERO, tcu::Vec4(0.0f));
948 UNIFORM_CASE(UV4_ONE, tcu::Vec4(1.0f));
949 UNIFORM_CASE(UV4_TWO, tcu::Vec4(2.0f));
950 UNIFORM_CASE(UV4_THREE, tcu::Vec4(3.0f));
952 UNIFORM_CASE(UV4_HALF, tcu::Vec4(1.0f / 2.0f));
954 UNIFORM_CASE(UV4_BLACK, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
955 UNIFORM_CASE(UV4_GRAY, tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f));
956 UNIFORM_CASE(UV4_WHITE, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
959 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Unknown Uniform type: " << type << tcu::TestLog::EndMessage;
966 const tcu::UVec2 ShaderRenderCaseInstance::getViewportSize (void) const
968 return tcu::UVec2(de::min(m_renderSize.x(), MAX_RENDER_WIDTH),
969 de::min(m_renderSize.y(), MAX_RENDER_HEIGHT));
972 void ShaderRenderCaseInstance::setSampleCount (VkSampleCountFlagBits sampleCount)
974 m_sampleCount = sampleCount;
977 bool ShaderRenderCaseInstance::isMultiSampling (void) const
979 return m_sampleCount != VK_SAMPLE_COUNT_1_BIT;
982 void ShaderRenderCaseInstance::uploadImage (const tcu::TextureFormat& texFormat,
983 const TextureData& textureData,
984 const tcu::Sampler& refSampler,
986 deUint32 arrayLayers,
989 const VkDevice vkDevice = getDevice();
990 const DeviceInterface& vk = getDeviceInterface();
991 const VkQueue queue = getUniversalQueue();
992 const deUint32 queueFamilyIndex = getUniversalQueueFamilyIndex();
994 const bool isShadowSampler = refSampler.compare != tcu::Sampler::COMPAREMODE_NONE;
995 const VkImageAspectFlags aspectMask = isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
996 deUint32 bufferSize = 0u;
997 Move<VkBuffer> buffer;
998 de::MovePtr<Allocation> bufferAlloc;
999 std::vector<VkBufferImageCopy> copyRegions;
1000 std::vector<deUint32> offsetMultiples;
1002 offsetMultiples.push_back(4u);
1003 offsetMultiples.push_back(texFormat.getPixelSize());
1005 // Calculate buffer size
1006 for (TextureData::const_iterator mit = textureData.begin(); mit != textureData.end(); ++mit)
1008 for (TextureLayerData::const_iterator lit = mit->begin(); lit != mit->end(); ++lit)
1010 const tcu::ConstPixelBufferAccess& access = *lit;
1012 bufferSize = getNextMultiple(offsetMultiples, bufferSize);
1013 bufferSize += access.getWidth() * access.getHeight() * access.getDepth() * access.getFormat().getPixelSize();
1017 // Create source buffer
1019 const VkBufferCreateInfo bufferParams =
1021 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1022 DE_NULL, // const void* pNext;
1023 0u, // VkBufferCreateFlags flags;
1024 bufferSize, // VkDeviceSize size;
1025 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
1026 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1027 0u, // deUint32 queueFamilyIndexCount;
1028 DE_NULL, // const deUint32* pQueueFamilyIndices;
1031 buffer = createBuffer(vk, vkDevice, &bufferParams);
1032 bufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
1033 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
1036 // Get copy regions and write buffer data
1038 deUint32 layerDataOffset = 0;
1039 deUint8* destPtr = (deUint8*)bufferAlloc->getHostPtr();
1041 for (size_t levelNdx = 0; levelNdx < textureData.size(); levelNdx++)
1043 const TextureLayerData& layerData = textureData[levelNdx];
1045 for (size_t layerNdx = 0; layerNdx < layerData.size(); layerNdx++)
1047 layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset);
1049 const tcu::ConstPixelBufferAccess& access = layerData[layerNdx];
1050 const tcu::PixelBufferAccess destAccess (access.getFormat(), access.getSize(), destPtr + layerDataOffset);
1052 const VkBufferImageCopy layerRegion =
1054 layerDataOffset, // VkDeviceSize bufferOffset;
1055 (deUint32)access.getWidth(), // deUint32 bufferRowLength;
1056 (deUint32)access.getHeight(), // deUint32 bufferImageHeight;
1057 { // VkImageSubresourceLayers imageSubresource;
1058 aspectMask, // VkImageAspectFlags aspectMask;
1059 (deUint32)levelNdx, // uint32_t mipLevel;
1060 (deUint32)layerNdx, // uint32_t baseArrayLayer;
1061 1u // uint32_t layerCount;
1063 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
1064 { // VkExtent3D imageExtent;
1065 (deUint32)access.getWidth(),
1066 (deUint32)access.getHeight(),
1067 (deUint32)access.getDepth()
1071 copyRegions.push_back(layerRegion);
1072 tcu::copy(destAccess, access);
1074 layerDataOffset += access.getWidth() * access.getHeight() * access.getDepth() * access.getFormat().getPixelSize();
1079 flushAlloc(vk, vkDevice, *bufferAlloc);
1081 if(m_externalCommandPool.get() != DE_NULL)
1082 copyBufferToImage(vk, vkDevice, queue, queueFamilyIndex, *buffer, bufferSize, copyRegions, DE_NULL, aspectMask, mipLevels, arrayLayers, destImage, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, &(m_externalCommandPool.get()->get()));
1084 copyBufferToImage(vk, vkDevice, queue, queueFamilyIndex, *buffer, bufferSize, copyRegions, DE_NULL, aspectMask, mipLevels, arrayLayers, destImage);
1087 void ShaderRenderCaseInstance::clearImage (const tcu::Sampler& refSampler,
1089 deUint32 arrayLayers,
1092 const VkDevice vkDevice = m_context.getDevice();
1093 const DeviceInterface& vk = m_context.getDeviceInterface();
1094 const VkQueue queue = m_context.getUniversalQueue();
1095 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1097 const bool isShadowSampler = refSampler.compare != tcu::Sampler::COMPAREMODE_NONE;
1098 const VkImageAspectFlags aspectMask = isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
1099 Move<VkCommandPool> cmdPool;
1100 Move<VkCommandBuffer> cmdBuffer;
1102 VkClearValue clearValue;
1103 deMemset(&clearValue, 0, sizeof(clearValue));
1106 // Create command pool
1107 VkCommandPool activeCmdPool;
1108 if (m_externalCommandPool.get() == DE_NULL)
1110 // Create local command pool
1111 cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1112 activeCmdPool = *cmdPool;
1116 // Use external command pool if available
1117 activeCmdPool = m_externalCommandPool.get()->get();
1119 // Create command buffer
1120 cmdBuffer = allocateCommandBuffer(vk, vkDevice, activeCmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1122 const VkImageMemoryBarrier preImageBarrier =
1124 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1125 DE_NULL, // const void* pNext;
1126 0u, // VkAccessFlags srcAccessMask;
1127 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1128 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1129 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
1130 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1131 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1132 destImage, // VkImage image;
1133 { // VkImageSubresourceRange subresourceRange;
1134 aspectMask, // VkImageAspect aspect;
1135 0u, // deUint32 baseMipLevel;
1136 mipLevels, // deUint32 mipLevels;
1137 0u, // deUint32 baseArraySlice;
1138 arrayLayers // deUint32 arraySize;
1142 const VkImageMemoryBarrier postImageBarrier =
1144 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1145 DE_NULL, // const void* pNext;
1146 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1147 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
1148 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1149 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout;
1150 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1151 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1152 destImage, // VkImage image;
1153 { // VkImageSubresourceRange subresourceRange;
1154 aspectMask, // VkImageAspect aspect;
1155 0u, // deUint32 baseMipLevel;
1156 mipLevels, // deUint32 mipLevels;
1157 0u, // deUint32 baseArraySlice;
1158 arrayLayers // deUint32 arraySize;
1162 const VkImageSubresourceRange clearRange =
1164 aspectMask, // VkImageAspectFlags aspectMask;
1165 0u, // deUint32 baseMipLevel;
1166 mipLevels, // deUint32 levelCount;
1167 0u, // deUint32 baseArrayLayer;
1168 arrayLayers // deUint32 layerCount;
1171 // Copy buffer to image
1172 beginCommandBuffer(vk, *cmdBuffer);
1173 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier);
1174 if (aspectMask == VK_IMAGE_ASPECT_COLOR_BIT)
1176 vk.cmdClearColorImage(*cmdBuffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &clearRange);
1180 vk.cmdClearDepthStencilImage(*cmdBuffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.depthStencil, 1, &clearRange);
1182 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
1183 endCommandBuffer(vk, *cmdBuffer);
1185 submitCommandsAndWait(vk, vkDevice, queue, cmdBuffer.get());
1188 VkExtent3D mipLevelExtents (const VkExtent3D& baseExtents, const deUint32 mipLevel)
1192 result.width = std::max(baseExtents.width >> mipLevel, 1u);
1193 result.height = std::max(baseExtents.height >> mipLevel, 1u);
1194 result.depth = std::max(baseExtents.depth >> mipLevel, 1u);
1199 tcu::UVec3 alignedDivide (const VkExtent3D& extent, const VkExtent3D& divisor)
1203 result.x() = extent.width / divisor.width + ((extent.width % divisor.width != 0) ? 1u : 0u);
1204 result.y() = extent.height / divisor.height + ((extent.height % divisor.height != 0) ? 1u : 0u);
1205 result.z() = extent.depth / divisor.depth + ((extent.depth % divisor.depth != 0) ? 1u : 0u);
1210 bool isImageSizeSupported (const VkImageType imageType, const tcu::UVec3& imageSize, const vk::VkPhysicalDeviceLimits& limits)
1214 case VK_IMAGE_TYPE_1D:
1215 return (imageSize.x() <= limits.maxImageDimension1D
1216 && imageSize.y() == 1
1217 && imageSize.z() == 1);
1218 case VK_IMAGE_TYPE_2D:
1219 return (imageSize.x() <= limits.maxImageDimension2D
1220 && imageSize.y() <= limits.maxImageDimension2D
1221 && imageSize.z() == 1);
1222 case VK_IMAGE_TYPE_3D:
1223 return (imageSize.x() <= limits.maxImageDimension3D
1224 && imageSize.y() <= limits.maxImageDimension3D
1225 && imageSize.z() <= limits.maxImageDimension3D);
1227 DE_FATAL("Unknown image type");
1232 void ShaderRenderCaseInstance::checkSparseSupport (const VkImageCreateInfo& imageInfo) const
1234 #ifdef CTS_USES_VULKANSC
1235 TCU_THROW(NotSupportedError, "Vulkan SC does not support sparse operations");
1236 #endif // CTS_USES_VULKANSC
1237 const InstanceInterface& instance = getInstanceInterface();
1238 const VkPhysicalDevice physicalDevice = getPhysicalDevice();
1239 const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(instance, physicalDevice);
1240 #ifndef CTS_USES_VULKANSC
1241 const std::vector<VkSparseImageFormatProperties> sparseImageFormatPropVec = getPhysicalDeviceSparseImageFormatProperties(
1242 instance, physicalDevice, imageInfo.format, imageInfo.imageType, imageInfo.samples, imageInfo.usage, imageInfo.tiling);
1243 #endif // CTS_USES_VULKANSC
1245 if (!deviceFeatures.shaderResourceResidency)
1246 TCU_THROW(NotSupportedError, "Required feature: shaderResourceResidency.");
1248 if (!deviceFeatures.sparseBinding)
1249 TCU_THROW(NotSupportedError, "Required feature: sparseBinding.");
1251 if (imageInfo.imageType == VK_IMAGE_TYPE_2D && !deviceFeatures.sparseResidencyImage2D)
1252 TCU_THROW(NotSupportedError, "Required feature: sparseResidencyImage2D.");
1254 if (imageInfo.imageType == VK_IMAGE_TYPE_3D && !deviceFeatures.sparseResidencyImage3D)
1255 TCU_THROW(NotSupportedError, "Required feature: sparseResidencyImage3D.");
1256 #ifndef CTS_USES_VULKANSC
1257 if (sparseImageFormatPropVec.size() == 0)
1258 TCU_THROW(NotSupportedError, "The image format does not support sparse operations");
1259 #endif // CTS_USES_VULKANSC
1262 #ifndef CTS_USES_VULKANSC
1263 void ShaderRenderCaseInstance::uploadSparseImage (const tcu::TextureFormat& texFormat,
1264 const TextureData& textureData,
1265 const tcu::Sampler& refSampler,
1266 const deUint32 mipLevels,
1267 const deUint32 arrayLayers,
1268 const VkImage sparseImage,
1269 const VkImageCreateInfo& imageCreateInfo,
1270 const tcu::UVec3 texSize)
1272 const VkDevice vkDevice = getDevice();
1273 const DeviceInterface& vk = getDeviceInterface();
1274 const VkPhysicalDevice physicalDevice = getPhysicalDevice();
1275 const VkQueue queue = getUniversalQueue();
1276 const VkQueue sparseQueue = getSparseQueue();
1277 const deUint32 queueFamilyIndex = getUniversalQueueFamilyIndex();
1278 const InstanceInterface& instance = getInstanceInterface();
1279 const VkPhysicalDeviceProperties deviceProperties = getPhysicalDeviceProperties(instance, physicalDevice);
1280 const bool isShadowSampler = refSampler.compare != tcu::Sampler::COMPAREMODE_NONE;
1281 const VkImageAspectFlags aspectMask = isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
1282 const Unique<VkSemaphore> imageMemoryBindSemaphore(createSemaphore(vk, vkDevice));
1283 Move<VkBuffer> buffer;
1284 deUint32 bufferSize = 0u;
1285 de::MovePtr<Allocation> bufferAlloc;
1286 std::vector<VkBufferImageCopy> copyRegions;
1287 std::vector<deUint32> offsetMultiples;
1289 offsetMultiples.push_back(4u);
1290 offsetMultiples.push_back(texFormat.getPixelSize());
1292 if (isImageSizeSupported(imageCreateInfo.imageType, texSize, deviceProperties.limits) == false)
1293 TCU_THROW(NotSupportedError, "Image size not supported for device.");
1295 allocateAndBindSparseImage(vk, vkDevice, physicalDevice, instance, imageCreateInfo, *imageMemoryBindSemaphore, sparseQueue, m_memAlloc, m_allocations, texFormat, sparseImage);
1297 // Calculate buffer size
1298 for (TextureData::const_iterator mit = textureData.begin(); mit != textureData.end(); ++mit)
1300 for (TextureLayerData::const_iterator lit = mit->begin(); lit != mit->end(); ++lit)
1302 const tcu::ConstPixelBufferAccess& access = *lit;
1304 bufferSize = getNextMultiple(offsetMultiples, bufferSize);
1305 bufferSize += access.getWidth() * access.getHeight() * access.getDepth() * access.getFormat().getPixelSize();
1310 // Create source buffer
1311 const VkBufferCreateInfo bufferParams =
1313 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1314 DE_NULL, // const void* pNext;
1315 0u, // VkBufferCreateFlags flags;
1316 bufferSize, // VkDeviceSize size;
1317 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
1318 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1319 0u, // deUint32 queueFamilyIndexCount;
1320 DE_NULL, // const deUint32* pQueueFamilyIndices;
1323 buffer = createBuffer(vk, vkDevice, &bufferParams);
1324 bufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
1326 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
1329 // Get copy regions and write buffer data
1331 deUint32 layerDataOffset = 0;
1332 deUint8* destPtr = (deUint8*)bufferAlloc->getHostPtr();
1334 for (size_t levelNdx = 0; levelNdx < textureData.size(); levelNdx++)
1336 const TextureLayerData& layerData = textureData[levelNdx];
1338 for (size_t layerNdx = 0; layerNdx < layerData.size(); layerNdx++)
1340 layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset);
1342 const tcu::ConstPixelBufferAccess& access = layerData[layerNdx];
1343 const tcu::PixelBufferAccess destAccess (access.getFormat(), access.getSize(), destPtr + layerDataOffset);
1345 const VkBufferImageCopy layerRegion =
1347 layerDataOffset, // VkDeviceSize bufferOffset;
1348 (deUint32)access.getWidth(), // deUint32 bufferRowLength;
1349 (deUint32)access.getHeight(), // deUint32 bufferImageHeight;
1350 { // VkImageSubresourceLayers imageSubresource;
1351 aspectMask, // VkImageAspectFlags aspectMask;
1352 (deUint32)levelNdx, // uint32_t mipLevel;
1353 (deUint32)layerNdx, // uint32_t baseArrayLayer;
1354 1u // uint32_t layerCount;
1356 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
1357 { // VkExtent3D imageExtent;
1358 (deUint32)access.getWidth(),
1359 (deUint32)access.getHeight(),
1360 (deUint32)access.getDepth()
1364 copyRegions.push_back(layerRegion);
1365 tcu::copy(destAccess, access);
1367 layerDataOffset += access.getWidth() * access.getHeight() * access.getDepth() * access.getFormat().getPixelSize();
1371 copyBufferToImage(vk, vkDevice, queue, queueFamilyIndex, *buffer, bufferSize, copyRegions, &(*imageMemoryBindSemaphore), aspectMask, mipLevels, arrayLayers, sparseImage);
1373 #endif // CTS_USES_VULKANSC
1375 void ShaderRenderCaseInstance::useSampler (deUint32 bindingLocation, deUint32 textureId)
1377 DE_ASSERT(textureId < m_textures.size());
1379 const TextureBinding& textureBinding = *m_textures[textureId];
1380 const TextureBinding::Type textureType = textureBinding.getType();
1381 const tcu::Sampler& refSampler = textureBinding.getSampler();
1382 const TextureBinding::Parameters& textureParams = textureBinding.getParameters();
1383 const bool isMSTexture = textureParams.samples != vk::VK_SAMPLE_COUNT_1_BIT;
1384 deUint32 mipLevels = 1u;
1385 deUint32 arrayLayers = 1u;
1386 tcu::TextureFormat texFormat;
1388 TextureData textureData;
1390 if (textureType == TextureBinding::TYPE_2D)
1392 const tcu::Texture2D& texture = textureBinding.get2D();
1394 texFormat = texture.getFormat();
1395 texSize = tcu::UVec3(texture.getWidth(), texture.getHeight(), 1u);
1396 mipLevels = isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1399 textureData.resize(mipLevels);
1401 for (deUint32 level = 0; level < mipLevels; ++level)
1403 if (texture.isLevelEmpty(level))
1406 textureData[level].push_back(texture.getLevel(level));
1409 else if (textureType == TextureBinding::TYPE_CUBE_MAP)
1411 const tcu::TextureCube& texture = textureBinding.getCube();
1413 texFormat = texture.getFormat();
1414 texSize = tcu::UVec3(texture.getSize(), texture.getSize(), 1u);
1415 mipLevels = isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1418 static const tcu::CubeFace cubeFaceMapping[tcu::CUBEFACE_LAST] =
1420 tcu::CUBEFACE_POSITIVE_X,
1421 tcu::CUBEFACE_NEGATIVE_X,
1422 tcu::CUBEFACE_POSITIVE_Y,
1423 tcu::CUBEFACE_NEGATIVE_Y,
1424 tcu::CUBEFACE_POSITIVE_Z,
1425 tcu::CUBEFACE_NEGATIVE_Z
1428 textureData.resize(mipLevels);
1430 for (deUint32 level = 0; level < mipLevels; ++level)
1432 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; ++faceNdx)
1434 tcu::CubeFace face = cubeFaceMapping[faceNdx];
1436 if (texture.isLevelEmpty(face, level))
1439 textureData[level].push_back(texture.getLevelFace(level, face));
1443 else if (textureType == TextureBinding::TYPE_2D_ARRAY)
1445 const tcu::Texture2DArray& texture = textureBinding.get2DArray();
1447 texFormat = texture.getFormat();
1448 texSize = tcu::UVec3(texture.getWidth(), texture.getHeight(), 1u);
1449 mipLevels = isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1450 arrayLayers = (deUint32)texture.getNumLayers();
1452 textureData.resize(mipLevels);
1454 for (deUint32 level = 0; level < mipLevels; ++level)
1456 if (texture.isLevelEmpty(level))
1459 const tcu::ConstPixelBufferAccess& levelLayers = texture.getLevel(level);
1460 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1462 for (deUint32 layer = 0; layer < arrayLayers; ++layer)
1464 const deUint32 layerOffset = layerSize * layer;
1465 tcu::ConstPixelBufferAccess layerData (levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1466 textureData[level].push_back(layerData);
1470 else if (textureType == TextureBinding::TYPE_3D)
1472 const tcu::Texture3D& texture = textureBinding.get3D();
1474 texFormat = texture.getFormat();
1475 texSize = tcu::UVec3(texture.getWidth(), texture.getHeight(), texture.getDepth());
1476 mipLevels = isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1479 textureData.resize(mipLevels);
1481 for (deUint32 level = 0; level < mipLevels; ++level)
1483 if (texture.isLevelEmpty(level))
1486 textureData[level].push_back(texture.getLevel(level));
1489 else if (textureType == TextureBinding::TYPE_1D)
1491 const tcu::Texture1D& texture = textureBinding.get1D();
1493 texFormat = texture.getFormat();
1494 texSize = tcu::UVec3(texture.getWidth(), 1, 1);
1495 mipLevels = isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1498 textureData.resize(mipLevels);
1500 for (deUint32 level = 0; level < mipLevels; ++level)
1502 if (texture.isLevelEmpty(level))
1505 textureData[level].push_back(texture.getLevel(level));
1508 else if (textureType == TextureBinding::TYPE_1D_ARRAY)
1510 const tcu::Texture1DArray& texture = textureBinding.get1DArray();
1512 texFormat = texture.getFormat();
1513 texSize = tcu::UVec3(texture.getWidth(), 1, 1);
1514 mipLevels = isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1515 arrayLayers = (deUint32)texture.getNumLayers();
1517 textureData.resize(mipLevels);
1519 for (deUint32 level = 0; level < mipLevels; ++level)
1521 if (texture.isLevelEmpty(level))
1524 const tcu::ConstPixelBufferAccess& levelLayers = texture.getLevel(level);
1525 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
1527 for (deUint32 layer = 0; layer < arrayLayers; ++layer)
1529 const deUint32 layerOffset = layerSize * layer;
1530 tcu::ConstPixelBufferAccess layerData (levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1531 textureData[level].push_back(layerData);
1535 else if (textureType == TextureBinding::TYPE_CUBE_ARRAY)
1537 const tcu::TextureCubeArray& texture = textureBinding.getCubeArray();
1538 texFormat = texture.getFormat();
1539 texSize = tcu::UVec3(texture.getSize(), texture.getSize(), 1);
1540 mipLevels = isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1541 arrayLayers = texture.getDepth();
1543 textureData.resize(mipLevels);
1545 for (deUint32 level = 0; level < mipLevels; ++level)
1547 if (texture.isLevelEmpty(level))
1550 const tcu::ConstPixelBufferAccess& levelLayers = texture.getLevel(level);
1551 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1553 for (deUint32 layer = 0; layer < arrayLayers; ++layer)
1555 const deUint32 layerOffset = layerSize * layer;
1556 tcu::ConstPixelBufferAccess layerData (levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1557 textureData[level].push_back(layerData);
1563 TCU_THROW(InternalError, "Invalid texture type");
1566 createSamplerUniform(bindingLocation, textureType, textureBinding.getParameters().initialization, texFormat, texSize, textureData, refSampler, mipLevels, arrayLayers, textureParams);
1569 void ShaderRenderCaseInstance::setPushConstantRanges (const deUint32 rangeCount, const vk::VkPushConstantRange* const pcRanges)
1571 m_pushConstantRanges.clear();
1572 for (deUint32 i = 0; i < rangeCount; ++i)
1574 m_pushConstantRanges.push_back(pcRanges[i]);
1578 void ShaderRenderCaseInstance::updatePushConstants (vk::VkCommandBuffer, vk::VkPipelineLayout)
1582 void ShaderRenderCaseInstance::createSamplerUniform (deUint32 bindingLocation,
1583 TextureBinding::Type textureType,
1584 TextureBinding::Init textureInit,
1585 const tcu::TextureFormat& texFormat,
1586 const tcu::UVec3 texSize,
1587 const TextureData& textureData,
1588 const tcu::Sampler& refSampler,
1590 deUint32 arrayLayers,
1591 TextureBinding::Parameters textureParams)
1593 const VkDevice vkDevice = getDevice();
1594 const DeviceInterface& vk = getDeviceInterface();
1595 const deUint32 queueFamilyIndex = getUniversalQueueFamilyIndex();
1596 const deUint32 sparseFamilyIndex = (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE) ? getSparseQueueFamilyIndex() : queueFamilyIndex;
1598 const bool isShadowSampler = refSampler.compare != tcu::Sampler::COMPAREMODE_NONE;
1600 // when isShadowSampler is true mapSampler utill will set compareEnabled in
1601 // VkSamplerCreateInfo to true and in portability this functionality is under
1602 // feature flag - note that this is safety check as this is known at the
1603 // TestCase level and NotSupportedError should be thrown from checkSupport
1604 #ifndef CTS_USES_VULKANSC
1605 if (isShadowSampler &&
1606 m_context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
1607 !m_context.getPortabilitySubsetFeatures().mutableComparisonSamplers)
1609 DE_FATAL("mutableComparisonSamplers support should be checked in checkSupport");
1611 #endif // CTS_USES_VULKANSC
1613 const VkImageAspectFlags aspectMask = isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
1614 const VkImageViewType imageViewType = textureTypeToImageViewType(textureType);
1615 const VkImageType imageType = viewTypeToImageType(imageViewType);
1616 const VkSharingMode sharingMode = (queueFamilyIndex != sparseFamilyIndex) ? VK_SHARING_MODE_CONCURRENT : VK_SHARING_MODE_EXCLUSIVE;
1617 const VkFormat format = mapTextureFormat(texFormat);
1618 const VkImageUsageFlags imageUsageFlags = textureUsageFlags();
1619 const VkImageCreateFlags imageCreateFlags = textureCreateFlags(imageViewType, m_imageBackingMode);
1621 const deUint32 queueIndexCount = (queueFamilyIndex != sparseFamilyIndex) ? 2 : 1;
1622 const deUint32 queueIndices[] =
1628 Move<VkImage> vkTexture;
1629 de::MovePtr<Allocation> allocation;
1632 const VkImageCreateInfo imageParams =
1634 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1635 DE_NULL, // const void* pNext;
1636 imageCreateFlags, // VkImageCreateFlags flags;
1637 imageType, // VkImageType imageType;
1638 format, // VkFormat format;
1639 { // VkExtent3D extent;
1644 mipLevels, // deUint32 mipLevels;
1645 arrayLayers, // deUint32 arrayLayers;
1646 textureParams.samples, // VkSampleCountFlagBits samples;
1647 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1648 imageUsageFlags, // VkImageUsageFlags usage;
1649 sharingMode, // VkSharingMode sharingMode;
1650 queueIndexCount, // deUint32 queueFamilyIndexCount;
1651 queueIndices, // const deUint32* pQueueFamilyIndices;
1652 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
1655 if (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE)
1657 checkSparseSupport(imageParams);
1660 vkTexture = createImage(vk, vkDevice, &imageParams);
1661 allocation = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *vkTexture), MemoryRequirement::Any);
1663 if (m_imageBackingMode != IMAGE_BACKING_MODE_SPARSE)
1665 VK_CHECK(vk.bindImageMemory(vkDevice, *vkTexture, allocation->getMemory(), allocation->getOffset()));
1668 switch (textureInit)
1670 case TextureBinding::INIT_UPLOAD_DATA:
1672 // upload*Image functions use cmdCopyBufferToImage, which is invalid for multisample images
1673 DE_ASSERT(textureParams.samples == VK_SAMPLE_COUNT_1_BIT);
1675 if (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE)
1677 #ifndef CTS_USES_VULKANSC
1678 uploadSparseImage(texFormat, textureData, refSampler, mipLevels, arrayLayers, *vkTexture, imageParams, texSize);
1679 #endif // CTS_USES_VULKANSC
1683 // Upload texture data
1684 uploadImage(texFormat, textureData, refSampler, mipLevels, arrayLayers, *vkTexture);
1688 case TextureBinding::INIT_CLEAR:
1689 clearImage(refSampler, mipLevels, arrayLayers, *vkTexture);
1692 DE_FATAL("Impossible");
1696 const auto& minMaxLod = textureParams.minMaxLod;
1697 const VkSamplerCreateInfo samplerParams = (minMaxLod
1698 ? mapSampler(refSampler, texFormat, minMaxLod.get().minLod, minMaxLod.get().maxLod)
1699 : mapSampler(refSampler, texFormat));
1700 Move<VkSampler> sampler = createSampler(vk, vkDevice, &samplerParams);
1701 const deUint32 baseMipLevel = textureParams.baseMipLevel;
1702 const vk::VkComponentMapping components = textureParams.componentMapping;
1703 const VkImageViewCreateInfo viewParams =
1705 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1706 NULL, // const voide* pNext;
1707 0u, // VkImageViewCreateFlags flags;
1708 *vkTexture, // VkImage image;
1709 imageViewType, // VkImageViewType viewType;
1710 format, // VkFormat format;
1711 components, // VkChannelMapping channels;
1713 aspectMask, // VkImageAspectFlags aspectMask;
1714 baseMipLevel, // deUint32 baseMipLevel;
1715 mipLevels - baseMipLevel, // deUint32 mipLevels;
1716 0, // deUint32 baseArraySlice;
1717 arrayLayers // deUint32 arraySize;
1718 }, // VkImageSubresourceRange subresourceRange;
1721 Move<VkImageView> imageView = createImageView(vk, vkDevice, &viewParams);
1723 const vk::VkDescriptorImageInfo descriptor =
1725 sampler.get(), // VkSampler sampler;
1726 imageView.get(), // VkImageView imageView;
1727 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout imageLayout;
1730 de::MovePtr<SamplerUniform> uniform(new SamplerUniform());
1731 uniform->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
1732 uniform->descriptor = descriptor;
1733 uniform->location = bindingLocation;
1734 uniform->image = VkImageSp(new vk::Unique<VkImage>(vkTexture));
1735 uniform->imageView = VkImageViewSp(new vk::Unique<VkImageView>(imageView));
1736 uniform->sampler = VkSamplerSp(new vk::Unique<VkSampler>(sampler));
1737 uniform->alloc = AllocationSp(allocation.release());
1739 m_descriptorSetLayoutBuilder->addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, vk::VK_SHADER_STAGE_ALL, DE_NULL);
1740 m_descriptorPoolBuilder->addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
1742 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniform)));
1745 void ShaderRenderCaseInstance::setupDefaultInputs (void)
1747 /* Configuration of the vertex input attributes:
1748 a_position is at location 0
1749 a_coords is at location 1
1750 a_unitCoords is at location 2
1751 a_one is at location 3
1753 User attributes starts from at the location 4.
1756 DE_ASSERT(m_quadGrid);
1757 const QuadGrid& quadGrid = *m_quadGrid;
1759 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getPositions());
1760 addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getCoords());
1761 addAttribute(2u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUnitCoords());
1762 addAttribute(3u, VK_FORMAT_R32_SFLOAT, sizeof(float), quadGrid.getNumVertices(), quadGrid.getAttribOne());
1766 BaseAttributeType type;
1768 } userAttributes[] =
1778 BaseAttributeType matrixType;
1794 for (size_t attrNdx = 0; attrNdx < m_enabledBaseAttributes.size(); attrNdx++)
1796 for (int userNdx = 0; userNdx < DE_LENGTH_OF_ARRAY(userAttributes); userNdx++)
1798 if (userAttributes[userNdx].type != m_enabledBaseAttributes[attrNdx].type)
1801 addAttribute(m_enabledBaseAttributes[attrNdx].location, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUserAttrib(userNdx));
1804 for (int matNdx = 0; matNdx < DE_LENGTH_OF_ARRAY(matrices); matNdx++)
1807 if (matrices[matNdx].matrixType != m_enabledBaseAttributes[attrNdx].type)
1810 const int numCols = matrices[matNdx].numCols;
1812 for (int colNdx = 0; colNdx < numCols; colNdx++)
1814 addAttribute(m_enabledBaseAttributes[attrNdx].location + colNdx, VK_FORMAT_R32G32B32A32_SFLOAT, (deUint32)(4 * sizeof(float)), quadGrid.getNumVertices(), quadGrid.getUserAttrib(colNdx));
1820 void ShaderRenderCaseInstance::render (deUint32 numVertices,
1821 deUint32 numTriangles,
1822 const deUint16* indices,
1823 const tcu::Vec4& constCoords)
1825 render(numVertices, numTriangles * 3, indices, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, constCoords);
1828 void ShaderRenderCaseInstance::render (deUint32 numVertices,
1829 deUint32 numIndices,
1830 const deUint16* indices,
1831 VkPrimitiveTopology topology,
1832 const tcu::Vec4& constCoords)
1834 const VkDevice vkDevice = getDevice();
1835 const DeviceInterface& vk = getDeviceInterface();
1836 const VkQueue queue = getUniversalQueue();
1837 const deUint32 queueFamilyIndex = getUniversalQueueFamilyIndex();
1839 vk::Move<vk::VkImage> colorImage;
1840 de::MovePtr<vk::Allocation> colorImageAlloc;
1841 vk::Move<vk::VkImageView> colorImageView;
1842 vk::Move<vk::VkImage> resolvedImage;
1843 de::MovePtr<vk::Allocation> resolvedImageAlloc;
1844 vk::Move<vk::VkImageView> resolvedImageView;
1845 vk::Move<vk::VkRenderPass> renderPass;
1846 vk::Move<vk::VkFramebuffer> framebuffer;
1847 vk::Move<vk::VkPipelineLayout> pipelineLayout;
1848 vk::Move<vk::VkPipeline> graphicsPipeline;
1849 vk::Move<vk::VkShaderModule> vertexShaderModule;
1850 vk::Move<vk::VkShaderModule> fragmentShaderModule;
1851 vk::Move<vk::VkBuffer> indexBuffer;
1852 de::MovePtr<vk::Allocation> indexBufferAlloc;
1853 vk::Move<vk::VkDescriptorSetLayout> descriptorSetLayout;
1854 vk::Move<vk::VkDescriptorPool> descriptorPool;
1855 vk::Move<vk::VkDescriptorSet> descriptorSet;
1856 vk::Move<vk::VkCommandPool> cmdPool;
1857 vk::Move<vk::VkCommandBuffer> cmdBuffer;
1859 // Create color image
1861 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1862 VkImageFormatProperties properties;
1864 if ((getInstanceInterface().getPhysicalDeviceImageFormatProperties(getPhysicalDevice(),
1867 VK_IMAGE_TILING_OPTIMAL,
1870 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1872 TCU_THROW(NotSupportedError, "Format not supported");
1875 if ((properties.sampleCounts & m_sampleCount) != m_sampleCount)
1877 TCU_THROW(NotSupportedError, "Format not supported");
1880 const VkImageCreateInfo colorImageParams =
1882 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1883 DE_NULL, // const void* pNext;
1884 0u, // VkImageCreateFlags flags;
1885 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1886 m_colorFormat, // VkFormat format;
1887 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent;
1888 1u, // deUint32 mipLevels;
1889 1u, // deUint32 arraySize;
1890 m_sampleCount, // deUint32 samples;
1891 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1892 imageUsage, // VkImageUsageFlags usage;
1893 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1894 1u, // deUint32 queueFamilyCount;
1895 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1896 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1899 colorImage = createImage(vk, vkDevice, &colorImageParams);
1901 // Allocate and bind color image memory
1902 colorImageAlloc = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *colorImage), MemoryRequirement::Any);
1903 VK_CHECK(vk.bindImageMemory(vkDevice, *colorImage, colorImageAlloc->getMemory(), colorImageAlloc->getOffset()));
1906 // Create color attachment view
1908 const VkImageViewCreateInfo colorImageViewParams =
1910 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1911 DE_NULL, // const void* pNext;
1912 0u, // VkImageViewCreateFlags flags;
1913 *colorImage, // VkImage image;
1914 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
1915 m_colorFormat, // VkFormat format;
1917 VK_COMPONENT_SWIZZLE_R, // VkChannelSwizzle r;
1918 VK_COMPONENT_SWIZZLE_G, // VkChannelSwizzle g;
1919 VK_COMPONENT_SWIZZLE_B, // VkChannelSwizzle b;
1920 VK_COMPONENT_SWIZZLE_A // VkChannelSwizzle a;
1921 }, // VkChannelMapping channels;
1923 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1924 0, // deUint32 baseMipLevel;
1925 1, // deUint32 mipLevels;
1926 0, // deUint32 baseArraySlice;
1927 1 // deUint32 arraySize;
1928 }, // VkImageSubresourceRange subresourceRange;
1931 colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
1934 if (isMultiSampling())
1938 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1939 VkImageFormatProperties properties;
1941 if ((getInstanceInterface().getPhysicalDeviceImageFormatProperties(getPhysicalDevice(),
1944 VK_IMAGE_TILING_OPTIMAL,
1947 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1949 TCU_THROW(NotSupportedError, "Format not supported");
1952 const VkImageCreateInfo imageCreateInfo =
1954 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1955 DE_NULL, // const void* pNext;
1956 0u, // VkImageCreateFlags flags;
1957 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1958 m_colorFormat, // VkFormat format;
1959 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent;
1960 1u, // deUint32 mipLevels;
1961 1u, // deUint32 arrayLayers;
1962 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1963 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1964 imageUsage, // VkImageUsageFlags usage;
1965 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1966 1u, // deUint32 queueFamilyIndexCount;
1967 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1968 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
1971 resolvedImage = vk::createImage(vk, vkDevice, &imageCreateInfo, DE_NULL);
1972 resolvedImageAlloc = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *resolvedImage), MemoryRequirement::Any);
1973 VK_CHECK(vk.bindImageMemory(vkDevice, *resolvedImage, resolvedImageAlloc->getMemory(), resolvedImageAlloc->getOffset()));
1976 // Resolved Image View
1978 const VkImageViewCreateInfo imageViewCreateInfo =
1980 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1981 DE_NULL, // const void* pNext;
1982 0u, // VkImageViewCreateFlags flags;
1983 *resolvedImage, // VkImage image;
1984 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
1985 m_colorFormat, // VkFormat format;
1987 VK_COMPONENT_SWIZZLE_R, // VkChannelSwizzle r;
1988 VK_COMPONENT_SWIZZLE_G, // VkChannelSwizzle g;
1989 VK_COMPONENT_SWIZZLE_B, // VkChannelSwizzle b;
1990 VK_COMPONENT_SWIZZLE_A // VkChannelSwizzle a;
1993 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1994 0u, // deUint32 baseMipLevel;
1995 1u, // deUint32 mipLevels;
1996 0u, // deUint32 baseArrayLayer;
1997 1u, // deUint32 arraySize;
1998 }, // VkImageSubresourceRange subresourceRange;
2001 resolvedImageView = vk::createImageView(vk, vkDevice, &imageViewCreateInfo, DE_NULL);
2005 // Create render pass
2007 const VkAttachmentDescription attachmentDescription[] =
2010 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
2011 m_colorFormat, // VkFormat format;
2012 m_sampleCount, // deUint32 samples;
2013 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
2014 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2015 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
2016 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
2017 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
2018 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
2021 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
2022 m_colorFormat, // VkFormat format;
2023 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
2024 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp;
2025 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2026 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
2027 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
2028 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
2029 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
2033 const VkAttachmentReference attachmentReference =
2035 0u, // deUint32 attachment;
2036 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
2039 const VkAttachmentReference resolveAttachmentRef =
2041 1u, // deUint32 attachment;
2042 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
2045 const VkSubpassDescription subpassDescription =
2047 0u, // VkSubpassDescriptionFlags flags;
2048 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
2049 0u, // deUint32 inputCount;
2050 DE_NULL, // constVkAttachmentReference* pInputAttachments;
2051 1u, // deUint32 colorCount;
2052 &attachmentReference, // constVkAttachmentReference* pColorAttachments;
2053 isMultiSampling() ? &resolveAttachmentRef : DE_NULL,// constVkAttachmentReference* pResolveAttachments;
2054 DE_NULL, // VkAttachmentReference depthStencilAttachment;
2055 0u, // deUint32 preserveCount;
2056 DE_NULL // constVkAttachmentReference* pPreserveAttachments;
2059 const VkRenderPassCreateInfo renderPassParams =
2061 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
2062 DE_NULL, // const void* pNext;
2063 0u, // VkRenderPassCreateFlags flags;
2064 isMultiSampling() ? 2u : 1u, // deUint32 attachmentCount;
2065 attachmentDescription, // const VkAttachmentDescription* pAttachments;
2066 1u, // deUint32 subpassCount;
2067 &subpassDescription, // const VkSubpassDescription* pSubpasses;
2068 0u, // deUint32 dependencyCount;
2069 DE_NULL // const VkSubpassDependency* pDependencies;
2072 renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
2075 // Create framebuffer
2077 const VkImageView attachments[] =
2083 const VkFramebufferCreateInfo framebufferParams =
2085 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
2086 DE_NULL, // const void* pNext;
2087 (VkFramebufferCreateFlags)0,
2088 *renderPass, // VkRenderPass renderPass;
2089 isMultiSampling() ? 2u : 1u, // deUint32 attachmentCount;
2090 attachments, // const VkImageView* pAttachments;
2091 (deUint32)m_renderSize.x(), // deUint32 width;
2092 (deUint32)m_renderSize.y(), // deUint32 height;
2093 1u // deUint32 layers;
2096 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
2099 // Create descriptors
2101 setupUniforms(constCoords);
2103 descriptorSetLayout = m_descriptorSetLayoutBuilder->build(vk, vkDevice);
2104 if (!m_uniformInfos.empty())
2106 descriptorPool = m_descriptorPoolBuilder->build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2107 const VkDescriptorSetAllocateInfo allocInfo =
2109 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2113 &descriptorSetLayout.get(),
2116 descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
2119 for (deUint32 i = 0; i < m_uniformInfos.size(); i++)
2121 const UniformInfo* uniformInfo = m_uniformInfos[i].get()->get();
2122 deUint32 location = uniformInfo->location;
2124 if (uniformInfo->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
2126 const BufferUniform* bufferInfo = dynamic_cast<const BufferUniform*>(uniformInfo);
2128 m_descriptorSetUpdateBuilder->writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &bufferInfo->descriptor);
2130 else if (uniformInfo->type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
2132 const SamplerUniform* samplerInfo = dynamic_cast<const SamplerUniform*>(uniformInfo);
2134 m_descriptorSetUpdateBuilder->writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &samplerInfo->descriptor);
2137 DE_FATAL("Impossible");
2140 m_descriptorSetUpdateBuilder->update(vk, vkDevice);
2143 // Create pipeline layout
2145 const VkPushConstantRange* const pcRanges = m_pushConstantRanges.empty() ? DE_NULL : &m_pushConstantRanges[0];
2146 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
2148 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
2149 DE_NULL, // const void* pNext;
2150 (VkPipelineLayoutCreateFlags)0,
2151 1u, // deUint32 descriptorSetCount;
2152 &*descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
2153 deUint32(m_pushConstantRanges.size()), // deUint32 pushConstantRangeCount;
2154 pcRanges // const VkPushConstantRange* pPushConstantRanges;
2157 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
2162 vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get(m_vertexShaderName), 0);
2163 fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get(m_fragmentShaderName), 0);
2168 // Add test case specific attributes
2170 m_attribFunc(*this, numVertices);
2172 // Add base attributes
2173 setupDefaultInputs();
2175 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
2177 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
2178 DE_NULL, // const void* pNext;
2179 (VkPipelineVertexInputStateCreateFlags)0,
2180 (deUint32)m_vertexBindingDescription.size(), // deUint32 bindingCount;
2181 &m_vertexBindingDescription[0], // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
2182 (deUint32)m_vertexAttributeDescription.size(), // deUint32 attributeCount;
2183 &m_vertexAttributeDescription[0], // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
2186 const std::vector<VkViewport> viewports (1, makeViewport(m_renderSize));
2187 const std::vector<VkRect2D> scissors (1, makeRect2D(m_renderSize));
2189 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
2191 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
2192 DE_NULL, // const void* pNext;
2193 0u, // VkPipelineMultisampleStateCreateFlags flags;
2194 m_sampleCount, // VkSampleCountFlagBits rasterizationSamples;
2195 VK_FALSE, // VkBool32 sampleShadingEnable;
2196 0.0f, // float minSampleShading;
2197 DE_NULL, // const VkSampleMask* pSampleMask;
2198 VK_FALSE, // VkBool32 alphaToCoverageEnable;
2199 VK_FALSE // VkBool32 alphaToOneEnable;
2202 graphicsPipeline = makeGraphicsPipeline(vk, // const DeviceInterface& vk
2203 vkDevice, // const VkDevice device
2204 *pipelineLayout, // const VkPipelineLayout pipelineLayout
2205 *vertexShaderModule, // const VkShaderModule vertexShaderModule
2206 DE_NULL, // const VkShaderModule tessellationControlShaderModule
2207 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
2208 DE_NULL, // const VkShaderModule geometryShaderModule
2209 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
2210 *renderPass, // const VkRenderPass renderPass
2211 viewports, // const std::vector<VkViewport>& viewports
2212 scissors, // const std::vector<VkRect2D>& scissors
2213 topology, // const VkPrimitiveTopology topology
2214 0u, // const deUint32 subpass
2215 0u, // const deUint32 patchControlPoints
2216 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
2217 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
2218 &multisampleStateParams); // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
2221 // Create vertex indices buffer
2222 if (numIndices != 0)
2224 const VkDeviceSize indexBufferSize = numIndices * sizeof(deUint16);
2225 const VkBufferCreateInfo indexBufferParams =
2227 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2228 DE_NULL, // const void* pNext;
2229 0u, // VkBufferCreateFlags flags;
2230 indexBufferSize, // VkDeviceSize size;
2231 VK_BUFFER_USAGE_INDEX_BUFFER_BIT, // VkBufferUsageFlags usage;
2232 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2233 1u, // deUint32 queueFamilyCount;
2234 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
2237 indexBuffer = createBuffer(vk, vkDevice, &indexBufferParams);
2238 indexBufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *indexBuffer), MemoryRequirement::HostVisible);
2240 VK_CHECK(vk.bindBufferMemory(vkDevice, *indexBuffer, indexBufferAlloc->getMemory(), indexBufferAlloc->getOffset()));
2242 // Load vertice indices into buffer
2243 deMemcpy(indexBufferAlloc->getHostPtr(), indices, (size_t)indexBufferSize);
2244 flushAlloc(vk, vkDevice, *indexBufferAlloc);
2247 VkCommandPool activeCmdPool;
2248 if (m_externalCommandPool.get() == DE_NULL)
2250 // Create local command pool
2251 cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
2252 activeCmdPool = *cmdPool;
2256 // Use external command pool if available
2257 activeCmdPool = m_externalCommandPool.get()->get();
2260 // Create command buffer
2262 cmdBuffer = allocateCommandBuffer(vk, vkDevice, activeCmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2264 beginCommandBuffer(vk, *cmdBuffer);
2267 const VkImageMemoryBarrier imageBarrier =
2269 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
2270 DE_NULL, // const void* pNext;
2271 0u, // VkAccessFlags srcAccessMask;
2272 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
2273 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
2274 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
2275 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2276 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2277 *colorImage, // VkImage image;
2278 { // VkImageSubresourceRange subresourceRange;
2279 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
2280 0u, // deUint32 baseMipLevel;
2281 1u, // deUint32 mipLevels;
2282 0u, // deUint32 baseArrayLayer;
2283 1u, // deUint32 arraySize;
2287 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, DE_NULL, 1, &imageBarrier);
2289 if (isMultiSampling()) {
2290 // add multisample barrier
2291 const VkImageMemoryBarrier multiSampleImageBarrier =
2293 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
2294 DE_NULL, // const void* pNext;
2295 0u, // VkAccessFlags srcAccessMask;
2296 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
2297 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
2298 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
2299 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2300 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2301 *resolvedImage, // VkImage image;
2302 { // VkImageSubresourceRange subresourceRange;
2303 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
2304 0u, // deUint32 baseMipLevel;
2305 1u, // deUint32 mipLevels;
2306 0u, // deUint32 baseArrayLayer;
2307 1u, // deUint32 arraySize;
2311 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, DE_NULL, 1, &multiSampleImageBarrier);
2315 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), m_clearColor);
2317 updatePushConstants(*cmdBuffer, *pipelineLayout);
2318 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
2319 if (!m_uniformInfos.empty())
2320 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1, &*descriptorSet, 0u, DE_NULL);
2322 const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size();
2323 const std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0);
2325 std::vector<VkBuffer> buffers(numberOfVertexAttributes);
2326 for (size_t i = 0; i < numberOfVertexAttributes; i++)
2328 buffers[i] = m_vertexBuffers[i].get()->get();
2331 vk.cmdBindVertexBuffers(*cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]);
2332 if (numIndices != 0)
2334 vk.cmdBindIndexBuffer(*cmdBuffer, *indexBuffer, 0, VK_INDEX_TYPE_UINT16);
2335 vk.cmdDrawIndexed(*cmdBuffer, numIndices, 1, 0, 0, 0);
2338 vk.cmdDraw(*cmdBuffer, numVertices, 1, 0, 0);
2340 endRenderPass(vk, *cmdBuffer);
2341 endCommandBuffer(vk, *cmdBuffer);
2345 submitCommandsAndWait(vk, vkDevice, queue, cmdBuffer.get());
2347 // Read back the result
2349 const tcu::TextureFormat resultFormat = mapVkFormat(m_colorFormat);
2350 const VkDeviceSize imageSizeBytes = (VkDeviceSize)(resultFormat.getPixelSize() * m_renderSize.x() * m_renderSize.y());
2351 const VkBufferCreateInfo readImageBufferParams =
2353 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2354 DE_NULL, // const void* pNext;
2355 0u, // VkBufferCreateFlags flags;
2356 imageSizeBytes, // VkDeviceSize size;
2357 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
2358 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2359 1u, // deUint32 queueFamilyCount;
2360 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2362 const Unique<VkBuffer> readImageBuffer (createBuffer(vk, vkDevice, &readImageBufferParams));
2363 const de::UniquePtr<Allocation> readImageBufferMemory (m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
2365 VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
2367 // Copy image to buffer
2368 const Move<VkCommandBuffer> resultCmdBuffer = allocateCommandBuffer(vk, vkDevice, activeCmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2370 beginCommandBuffer(vk, *resultCmdBuffer);
2372 copyImageToBuffer(vk, *resultCmdBuffer, isMultiSampling() ? *resolvedImage : *colorImage, *readImageBuffer, tcu::IVec2(m_renderSize.x(), m_renderSize.y()));
2374 endCommandBuffer(vk, *resultCmdBuffer);
2376 submitCommandsAndWait(vk, vkDevice, queue, resultCmdBuffer.get());
2378 invalidateAlloc(vk, vkDevice, *readImageBufferMemory);
2380 const tcu::ConstPixelBufferAccess resultAccess (resultFormat, m_renderSize.x(), m_renderSize.y(), 1, readImageBufferMemory->getHostPtr());
2382 m_resultImage.setStorage(resultFormat, m_renderSize.x(), m_renderSize.y());
2383 tcu::copy(m_resultImage.getAccess(), resultAccess);
2387 void ShaderRenderCaseInstance::computeVertexReference (tcu::Surface& result, const QuadGrid& quadGrid)
2389 DE_ASSERT(m_evaluator);
2392 const int width = result.getWidth();
2393 const int height = result.getHeight();
2394 const int gridSize = quadGrid.getGridSize();
2395 const int stride = gridSize + 1;
2396 const bool hasAlpha = true; // \todo [2015-09-07 elecro] add correct alpha check
2397 ShaderEvalContext evalCtx (quadGrid);
2399 // Evaluate color for each vertex.
2400 std::vector<tcu::Vec4> colors ((gridSize + 1) * (gridSize + 1));
2401 for (int y = 0; y < gridSize+1; y++)
2402 for (int x = 0; x < gridSize+1; x++)
2404 const float sx = (float)x / (float)gridSize;
2405 const float sy = (float)y / (float)gridSize;
2406 const int vtxNdx = ((y * (gridSize+1)) + x);
2408 evalCtx.reset(sx, sy);
2409 m_evaluator->evaluate(evalCtx);
2410 DE_ASSERT(!evalCtx.isDiscarded); // Discard is not available in vertex shader.
2411 tcu::Vec4 color = evalCtx.color;
2416 colors[vtxNdx] = color;
2420 for (int y = 0; y < gridSize; y++)
2421 for (int x = 0; x < gridSize; x++)
2423 const float x0 = (float)x / (float)gridSize;
2424 const float x1 = (float)(x + 1) / (float)gridSize;
2425 const float y0 = (float)y / (float)gridSize;
2426 const float y1 = (float)(y + 1) / (float)gridSize;
2428 const float sx0 = x0 * (float)width;
2429 const float sx1 = x1 * (float)width;
2430 const float sy0 = y0 * (float)height;
2431 const float sy1 = y1 * (float)height;
2432 const float oosx = 1.0f / (sx1 - sx0);
2433 const float oosy = 1.0f / (sy1 - sy0);
2435 const int ix0 = deCeilFloatToInt32(sx0 - 0.5f);
2436 const int ix1 = deCeilFloatToInt32(sx1 - 0.5f);
2437 const int iy0 = deCeilFloatToInt32(sy0 - 0.5f);
2438 const int iy1 = deCeilFloatToInt32(sy1 - 0.5f);
2440 const int v00 = (y * stride) + x;
2441 const int v01 = (y * stride) + x + 1;
2442 const int v10 = ((y + 1) * stride) + x;
2443 const int v11 = ((y + 1) * stride) + x + 1;
2444 const tcu::Vec4 c00 = colors[v00];
2445 const tcu::Vec4 c01 = colors[v01];
2446 const tcu::Vec4 c10 = colors[v10];
2447 const tcu::Vec4 c11 = colors[v11];
2449 //printf("(%d,%d) -> (%f..%f, %f..%f) (%d..%d, %d..%d)\n", x, y, sx0, sx1, sy0, sy1, ix0, ix1, iy0, iy1);
2451 for (int iy = iy0; iy < iy1; iy++)
2452 for (int ix = ix0; ix < ix1; ix++)
2454 DE_ASSERT(deInBounds32(ix, 0, width));
2455 DE_ASSERT(deInBounds32(iy, 0, height));
2457 const float sfx = (float)ix + 0.5f;
2458 const float sfy = (float)iy + 0.5f;
2459 const float fx1 = deFloatClamp((sfx - sx0) * oosx, 0.0f, 1.0f);
2460 const float fy1 = deFloatClamp((sfy - sy0) * oosy, 0.0f, 1.0f);
2462 // Triangle quad interpolation.
2463 const bool tri = fx1 + fy1 <= 1.0f;
2464 const float tx = tri ? fx1 : (1.0f-fx1);
2465 const float ty = tri ? fy1 : (1.0f-fy1);
2466 const tcu::Vec4& t0 = tri ? c00 : c11;
2467 const tcu::Vec4& t1 = tri ? c01 : c10;
2468 const tcu::Vec4& t2 = tri ? c10 : c01;
2469 const tcu::Vec4 color = t0 + (t1-t0)*tx + (t2-t0)*ty;
2471 result.setPixel(ix, iy, tcu::RGBA(color));
2476 void ShaderRenderCaseInstance::computeFragmentReference (tcu::Surface& result, const QuadGrid& quadGrid)
2478 DE_ASSERT(m_evaluator);
2481 const int width = result.getWidth();
2482 const int height = result.getHeight();
2483 const bool hasAlpha = true; // \todo [2015-09-07 elecro] add correct alpha check
2484 ShaderEvalContext evalCtx (quadGrid);
2487 for (int y = 0; y < height; y++)
2488 for (int x = 0; x < width; x++)
2490 const float sx = ((float)x + 0.5f) / (float)width;
2491 const float sy = ((float)y + 0.5f) / (float)height;
2493 evalCtx.reset(sx, sy);
2494 m_evaluator->evaluate(evalCtx);
2495 // Select either clear color or computed color based on discarded bit.
2496 tcu::Vec4 color = evalCtx.isDiscarded ? m_clearColor : evalCtx.color;
2501 result.setPixel(x, y, tcu::RGBA(color));
2505 bool ShaderRenderCaseInstance::compareImages (const tcu::Surface& resImage, const tcu::Surface& refImage, float errorThreshold)
2508 return tcu::fuzzyCompare(m_context.getTestContext().getLog(), "ComparisonResult", "Image comparison result", refImage, resImage, errorThreshold, tcu::COMPARE_LOG_EVERYTHING);
2510 return tcu::pixelThresholdCompare(m_context.getTestContext().getLog(), "ComparisonResult", "Image comparison result", refImage, resImage, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_EVERYTHING);