1 #ifndef _VKTSHADERRENDER_HPP
2 #define _VKTSHADERRENDER_HPP
3 /*------------------------------------------------------------------------
4 * Vulkan Conformance Tests
5 * ------------------------
7 * Copyright (c) 2015 The Khronos Group Inc.
8 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
24 * \brief Vulkan ShaderRenderCase
25 *//*--------------------------------------------------------------------*/
27 #include "tcuTexture.hpp"
28 #include "tcuSurface.hpp"
29 #include "tcuMaybe.hpp"
32 #include "deSharedPtr.hpp"
33 #include "deUniquePtr.hpp"
36 #include "vkRefUtil.hpp"
37 #include "vkPrograms.hpp"
39 #include "vkMemUtil.hpp"
40 #include "vkBuilderUtil.hpp"
41 #include "vkTypeUtil.hpp"
42 #include "vkPlatform.hpp"
44 #include "vktTestCaseUtil.hpp"
54 LineStream (int indent = 0) { m_indent = indent; }
57 const char* str (void) const { m_string = m_stream.str(); return m_string.c_str(); }
58 LineStream& operator<< (const char* line) { for (int i = 0; i < m_indent; i++) { m_stream << "\t"; } m_stream << line << "\n"; return *this; }
62 std::ostringstream m_stream;
63 mutable std::string m_string;
67 class ShaderRenderCaseInstance;
99 MinMaxLod (float min, float max) : minLod(min), maxLod(max) {}
104 deUint32 baseMipLevel;
105 vk::VkComponentMapping componentMapping;
106 vk::VkSampleCountFlagBits samples;
108 tcu::Maybe<MinMaxLod> minMaxLod;
110 Parameters (deUint32 baseMipLevel_ = 0,
111 vk::VkComponentMapping componentMapping_ = vk::makeComponentMappingRGBA(),
112 vk::VkSampleCountFlagBits samples_ = vk::VK_SAMPLE_COUNT_1_BIT,
113 Init initialization_ = INIT_UPLOAD_DATA,
114 const tcu::Maybe<MinMaxLod>& minMaxLod_ = tcu::Nothing)
115 : baseMipLevel (baseMipLevel_)
116 , componentMapping (componentMapping_)
118 , initialization (initialization_)
119 , minMaxLod (minMaxLod_)
124 TextureBinding (const tcu::Archive& archive,
125 const char* filename,
127 const tcu::Sampler& sampler);
129 TextureBinding (const tcu::Texture1D* tex1D, const tcu::Sampler& sampler);
130 TextureBinding (const tcu::Texture2D* tex2D, const tcu::Sampler& sampler);
131 TextureBinding (const tcu::Texture3D* tex3D, const tcu::Sampler& sampler);
132 TextureBinding (const tcu::TextureCube* texCube, const tcu::Sampler& sampler);
133 TextureBinding (const tcu::Texture1DArray* tex1DArray, const tcu::Sampler& sampler);
134 TextureBinding (const tcu::Texture2DArray* tex2DArray, const tcu::Sampler& sampler);
135 TextureBinding (const tcu::TextureCubeArray* texCubeArray, const tcu::Sampler& sampler);
137 ~TextureBinding (void);
139 Type getType (void) const { return m_type; }
140 const tcu::Sampler& getSampler (void) const { return m_sampler; }
142 const tcu::Texture1D& get1D (void) const { DE_ASSERT(getType() == TYPE_1D && m_binding.tex1D != NULL); return *m_binding.tex1D; }
143 const tcu::Texture2D& get2D (void) const { DE_ASSERT(getType() == TYPE_2D && m_binding.tex2D != NULL); return *m_binding.tex2D; }
144 const tcu::Texture3D& get3D (void) const { DE_ASSERT(getType() == TYPE_3D && m_binding.tex3D != NULL); return *m_binding.tex3D; }
145 const tcu::TextureCube& getCube (void) const { DE_ASSERT(getType() == TYPE_CUBE_MAP && m_binding.texCube != NULL); return *m_binding.texCube; }
146 const tcu::Texture1DArray& get1DArray (void) const { DE_ASSERT(getType() == TYPE_1D_ARRAY && m_binding.tex1DArray != NULL); return *m_binding.tex1DArray; }
147 const tcu::Texture2DArray& get2DArray (void) const { DE_ASSERT(getType() == TYPE_2D_ARRAY && m_binding.tex2DArray != NULL); return *m_binding.tex2DArray; }
148 const tcu::TextureCubeArray& getCubeArray (void) const { DE_ASSERT(getType() == TYPE_CUBE_ARRAY && m_binding.texCubeArray != NULL); return *m_binding.texCubeArray; }
150 void setParameters (const Parameters& params) { m_params = params; }
151 const Parameters& getParameters (void) const { return m_params; }
154 TextureBinding (const TextureBinding&); // not allowed!
155 TextureBinding& operator= (const TextureBinding&); // not allowed!
157 static de::MovePtr<tcu::Texture2D> loadTexture2D (const tcu::Archive& archive, const char* filename);
160 tcu::Sampler m_sampler;
165 const tcu::Texture1D* tex1D;
166 const tcu::Texture2D* tex2D;
167 const tcu::Texture3D* tex3D;
168 const tcu::TextureCube* texCube;
169 const tcu::Texture1DArray* tex1DArray;
170 const tcu::Texture2DArray* tex2DArray;
171 const tcu::TextureCubeArray* texCubeArray;
175 typedef de::SharedPtr<TextureBinding> TextureBindingSp;
177 // ShaderEvalContext.
179 class ShaderEvalContext
185 MAX_USER_ATTRIBS = 4,
191 tcu::Sampler sampler;
192 const tcu::Texture1D* tex1D;
193 const tcu::Texture2D* tex2D;
194 const tcu::Texture3D* tex3D;
195 const tcu::TextureCube* texCube;
196 const tcu::Texture1DArray* tex1DArray;
197 const tcu::Texture2DArray* tex2DArray;
198 const tcu::TextureCubeArray* texCubeArray;
200 inline ShaderSampler (void)
205 , tex1DArray (DE_NULL)
206 , tex2DArray (DE_NULL)
207 , texCubeArray (DE_NULL)
212 ShaderEvalContext (const QuadGrid& quadGrid);
213 ~ShaderEvalContext (void);
215 void reset (float sx, float sy);
219 tcu::Vec4 unitCoords;
220 tcu::Vec4 constCoords;
222 tcu::Vec4 in[MAX_USER_ATTRIBS];
223 ShaderSampler textures[MAX_TEXTURES];
230 inline void discard (void) { isDiscarded = true; }
231 tcu::Vec4 texture2D (int unitNdx, const tcu::Vec2& coords);
234 const QuadGrid& m_quadGrid;
237 typedef void (*ShaderEvalFunc) (ShaderEvalContext& c);
239 inline void evalCoordsPassthroughX (ShaderEvalContext& c) { c.color.x() = c.coords.x(); }
240 inline void evalCoordsPassthroughXY (ShaderEvalContext& c) { c.color.xy() = c.coords.swizzle(0,1); }
241 inline void evalCoordsPassthroughXYZ (ShaderEvalContext& c) { c.color.xyz() = c.coords.swizzle(0,1,2); }
242 inline void evalCoordsPassthrough (ShaderEvalContext& c) { c.color = c.coords; }
243 inline void evalCoordsSwizzleWZYX (ShaderEvalContext& c) { c.color = c.coords.swizzle(3,2,1,0); }
246 // Either inherit a class with overridden evaluate() or just pass in an evalFunc.
248 class ShaderEvaluator
251 ShaderEvaluator (void);
252 ShaderEvaluator (const ShaderEvalFunc evalFunc);
253 virtual ~ShaderEvaluator (void);
255 virtual void evaluate (ShaderEvalContext& ctx) const;
258 ShaderEvaluator (const ShaderEvaluator&); // not allowed!
259 ShaderEvaluator& operator= (const ShaderEvaluator&); // not allowed!
261 const ShaderEvalFunc m_evalFunc;
266 typedef void (*UniformSetupFunc) (ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords);
272 UniformSetup (const UniformSetupFunc setup);
273 virtual ~UniformSetup (void);
274 virtual void setup (ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords) const;
277 UniformSetup (const UniformSetup&); // not allowed!
278 UniformSetup& operator= (const UniformSetup&); // not allowed!
280 const UniformSetupFunc m_setupFunc;
283 typedef void (*AttributeSetupFunc) (ShaderRenderCaseInstance& instance, deUint32 numVertices);
285 class ShaderRenderCase : public vkt::TestCase
288 ShaderRenderCase (tcu::TestContext& testCtx,
289 const std::string& name,
290 const std::string& description,
291 const bool isVertexCase,
292 const ShaderEvalFunc evalFunc,
293 const UniformSetup* uniformSetup,
294 const AttributeSetupFunc attribFunc);
296 ShaderRenderCase (tcu::TestContext& testCtx,
297 const std::string& name,
298 const std::string& description,
299 const bool isVertexCase,
300 const ShaderEvaluator* evaluator,
301 const UniformSetup* uniformSetup,
302 const AttributeSetupFunc attribFunc);
304 virtual ~ShaderRenderCase (void);
305 virtual void initPrograms (vk::SourceCollections& programCollection) const;
306 virtual TestInstance* createInstance (Context& context) const;
309 std::string m_vertShaderSource;
310 std::string m_fragShaderSource;
312 const bool m_isVertexCase;
313 const de::UniquePtr<const ShaderEvaluator> m_evaluator;
314 const de::UniquePtr<const UniformSetup> m_uniformSetup;
315 const AttributeSetupFunc m_attribFunc;
421 enum BaseAttributeType
441 // ShaderRenderCaseInstance.
443 class ShaderRenderCaseInstance : public vkt::TestInstance
446 enum ImageBackingMode
448 IMAGE_BACKING_MODE_REGULAR = 0,
449 IMAGE_BACKING_MODE_SPARSE,
452 // Default wertex and fragment grid sizes are used by a large collection of tests
453 // to generate input sets. Some tests might change their behavior if the
454 // default grid size values are altered, so care should be taken to confirm that
455 // any changes to default values do not produce regressions.
456 // If a particular tests needs to use a different grid size value, rather than
457 // modifying the default grid size values for all tests, it is recommended that
458 // the test specifies the required grid size using the gridSize parameter in the
459 // ShaderRenderCaseInstance constuctor instead.
462 GRID_SIZE_DEFAULTS = 0,
463 GRID_SIZE_DEFAULT_VERTEX = 90,
464 GRID_SIZE_DEFAULT_FRAGMENT = 4,
467 ShaderRenderCaseInstance (Context& context);
468 ShaderRenderCaseInstance (Context& context,
469 const bool isVertexCase,
470 const ShaderEvaluator& evaluator,
471 const UniformSetup& uniformSetup,
472 const AttributeSetupFunc attribFunc,
473 const ImageBackingMode imageBackingMode = IMAGE_BACKING_MODE_REGULAR,
474 const deUint32 gridSize = static_cast<deUint32>(GRID_SIZE_DEFAULTS),
475 const bool fuzzyCompare = true);
477 virtual ~ShaderRenderCaseInstance (void);
478 virtual tcu::TestStatus iterate (void);
480 void addAttribute (deUint32 bindingLocation,
482 deUint32 sizePerElement,
485 void useAttribute (deUint32 bindingLocation,
486 BaseAttributeType type);
489 void addUniform (deUint32 bindingLocation,
490 vk::VkDescriptorType descriptorType,
492 void addUniform (deUint32 bindingLocation,
493 vk::VkDescriptorType descriptorType,
496 void useUniform (deUint32 bindingLocation,
497 BaseUniformType type);
498 void useSampler (deUint32 bindingLocation,
501 static const tcu::Vec4 getDefaultConstCoords (void) { return tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f); }
502 void setPushConstantRanges (const deUint32 rangeCount, const vk::VkPushConstantRange* const pcRanges);
503 virtual void updatePushConstants (vk::VkCommandBuffer commandBuffer, vk::VkPipelineLayout pipelineLayout);
506 ShaderRenderCaseInstance (Context& context,
507 const bool isVertexCase,
508 const ShaderEvaluator* evaluator,
509 const UniformSetup* uniformSetup,
510 const AttributeSetupFunc attribFunc,
511 const ImageBackingMode imageBackingMode = IMAGE_BACKING_MODE_REGULAR,
512 const deUint32 gridSize = static_cast<deUint32>(GRID_SIZE_DEFAULTS));
514 virtual void setup (void);
515 virtual void setupUniforms (const tcu::Vec4& constCoords);
516 virtual void setupDefaultInputs (void);
518 void render (deUint32 numVertices,
519 deUint32 numTriangles,
520 const deUint16* indices,
521 const tcu::Vec4& constCoords = getDefaultConstCoords());
523 void render (deUint32 numVertices,
525 const deUint16* indices,
526 vk::VkPrimitiveTopology topology,
527 const tcu::Vec4& constCoords = getDefaultConstCoords());
529 const tcu::TextureLevel& getResultImage (void) const { return m_resultImage; }
531 const tcu::UVec2 getViewportSize (void) const;
533 void setSampleCount (vk::VkSampleCountFlagBits sampleCount);
535 bool isMultiSampling (void) const;
537 ImageBackingMode m_imageBackingMode;
539 deUint32 m_quadGridSize;
542 vk::Allocator& m_memAlloc;
543 const tcu::Vec4 m_clearColor;
544 const bool m_isVertexCase;
546 std::vector<tcu::Mat4> m_userAttribTransforms;
547 std::vector<TextureBindingSp> m_textures;
549 std::string m_vertexShaderName;
550 std::string m_fragmentShaderName;
551 tcu::UVec2 m_renderSize;
552 vk::VkFormat m_colorFormat;
554 de::SharedPtr<vk::Unique<vk::VkCommandPool> > m_externalCommandPool;
556 typedef std::vector<tcu::ConstPixelBufferAccess> TextureLayerData;
557 typedef std::vector<TextureLayerData> TextureData;
559 void uploadImage (const tcu::TextureFormat& texFormat,
560 const TextureData& textureData,
561 const tcu::Sampler& refSampler,
563 deUint32 arrayLayers,
564 vk::VkImage destImage);
566 void clearImage (const tcu::Sampler& refSampler,
568 deUint32 arrayLayers,
569 vk::VkImage destImage);
571 void checkSparseSupport (const vk::VkImageCreateInfo& imageInfo) const;
572 #ifndef CTS_USES_VULKANSC
573 void uploadSparseImage (const tcu::TextureFormat& texFormat,
574 const TextureData& textureData,
575 const tcu::Sampler& refSampler,
576 const deUint32 mipLevels,
577 const deUint32 arrayLayers,
578 const vk::VkImage sparseImage,
579 const vk::VkImageCreateInfo& imageCreateInfo,
580 const tcu::UVec3 texSize);
581 #endif // CTS_USES_VULKANSC
582 void createSamplerUniform (deUint32 bindingLocation,
583 TextureBinding::Type textureType,
584 TextureBinding::Init textureInit,
585 const tcu::TextureFormat& texFormat,
586 const tcu::UVec3 texSize,
587 const TextureData& textureData,
588 const tcu::Sampler& refSampler,
590 deUint32 arrayLayers,
591 TextureBinding::Parameters textureParams);
593 void setupUniformData (deUint32 bindingLocation, size_t size, const void* dataPtr);
595 void computeVertexReference (tcu::Surface& result, const QuadGrid& quadGrid);
596 void computeFragmentReference (tcu::Surface& result, const QuadGrid& quadGrid);
597 bool compareImages (const tcu::Surface& resImage,
598 const tcu::Surface& refImage,
599 float errorThreshold);
602 const ShaderEvaluator* m_evaluator;
603 const UniformSetup* m_uniformSetup;
604 const AttributeSetupFunc m_attribFunc;
605 de::MovePtr<QuadGrid> m_quadGrid;
606 tcu::TextureLevel m_resultImage;
608 struct EnabledBaseAttribute
611 BaseAttributeType type;
613 std::vector<EnabledBaseAttribute> m_enabledBaseAttributes;
615 de::MovePtr<vk::DescriptorSetLayoutBuilder> m_descriptorSetLayoutBuilder;
616 de::MovePtr<vk::DescriptorPoolBuilder> m_descriptorPoolBuilder;
617 de::MovePtr<vk::DescriptorSetUpdateBuilder> m_descriptorSetUpdateBuilder;
619 typedef de::SharedPtr<vk::Unique<vk::VkBuffer> > VkBufferSp;
620 typedef de::SharedPtr<vk::Unique<vk::VkImage> > VkImageSp;
621 typedef de::SharedPtr<vk::Unique<vk::VkImageView> > VkImageViewSp;
622 typedef de::SharedPtr<vk::Unique<vk::VkSampler> > VkSamplerSp;
623 typedef de::SharedPtr<vk::Allocation> AllocationSp;
628 UniformInfo (void) {}
629 virtual ~UniformInfo (void) {}
631 vk::VkDescriptorType type;
635 class BufferUniform : public UniformInfo
638 BufferUniform (void) {}
639 virtual ~BufferUniform (void) {}
643 vk::VkDescriptorBufferInfo descriptor;
646 class SamplerUniform : public UniformInfo
649 SamplerUniform (void) {}
650 virtual ~SamplerUniform (void) {}
653 VkImageViewSp imageView;
656 vk::VkDescriptorImageInfo descriptor;
659 typedef de::SharedPtr<de::UniquePtr<UniformInfo> > UniformInfoSp;
660 std::vector<UniformInfoSp> m_uniformInfos;
662 std::vector< de::SharedPtr<vk::Allocation> > m_allocations;
664 std::vector<vk::VkVertexInputBindingDescription> m_vertexBindingDescription;
665 std::vector<vk::VkVertexInputAttributeDescription> m_vertexAttributeDescription;
667 std::vector<VkBufferSp> m_vertexBuffers;
668 std::vector<AllocationSp> m_vertexBufferAllocs;
670 vk::VkSampleCountFlagBits m_sampleCount;
671 std::vector<vk::VkPushConstantRange> m_pushConstantRanges;
675 vk::VkDevice getDevice (void) const;
676 deUint32 getUniversalQueueFamilyIndex (void) const;
677 deUint32 getSparseQueueFamilyIndex (void) const;
678 const vk::DeviceInterface& getDeviceInterface (void) const;
679 vk::VkQueue getUniversalQueue (void) const;
680 vk::VkQueue getSparseQueue (void) const;
681 vk::VkPhysicalDevice getPhysicalDevice (void) const;
682 const vk::InstanceInterface& getInstanceInterface (void) const;
683 vk::Allocator& getAllocator (void) const;
687 void ShaderRenderCaseInstance::addUniform (deUint32 bindingLocation, vk::VkDescriptorType descriptorType, const T& data)
689 addUniform(bindingLocation, descriptorType, sizeof(T), &data);
692 vk::VkImageViewType textureTypeToImageViewType (TextureBinding::Type type);
693 vk::VkImageType viewTypeToImageType (vk::VkImageViewType type);
694 vk::VkImageUsageFlags textureUsageFlags (void);
695 vk::VkImageCreateFlags textureCreateFlags (vk::VkImageViewType viewType, ShaderRenderCaseInstance::ImageBackingMode backingMode);
700 #endif // _VKTSHADERRENDER_HPP