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"
31 #include "deSharedPtr.hpp"
32 #include "deUniquePtr.hpp"
35 #include "vkRefUtil.hpp"
36 #include "vkPrograms.hpp"
38 #include "vkMemUtil.hpp"
39 #include "vkBuilderUtil.hpp"
40 #include "vkTypeUtil.hpp"
41 #include "vkPlatform.hpp"
43 #include "vktTestCaseUtil.hpp"
53 LineStream (int indent = 0) { m_indent = indent; }
56 const char* str (void) const { m_string = m_stream.str(); return m_string.c_str(); }
57 LineStream& operator<< (const char* line) { for (int i = 0; i < m_indent; i++) { m_stream << "\t"; } m_stream << line << "\n"; return *this; }
61 std::ostringstream m_stream;
62 mutable std::string m_string;
66 class ShaderRenderCaseInstance;
95 deUint32 baseMipLevel;
96 vk::VkComponentMapping componentMapping;
97 vk::VkSampleCountFlagBits samples;
100 Parameters (deUint32 baseMipLevel_ = 0,
101 vk::VkComponentMapping componentMapping_ = vk::makeComponentMappingRGBA(),
102 vk::VkSampleCountFlagBits samples_ = vk::VK_SAMPLE_COUNT_1_BIT,
103 Init initialization_ = INIT_UPLOAD_DATA)
104 : baseMipLevel (baseMipLevel_)
105 , componentMapping (componentMapping_)
107 , initialization (initialization_)
112 TextureBinding (const tcu::Archive& archive,
113 const char* filename,
115 const tcu::Sampler& sampler);
117 TextureBinding (const tcu::Texture1D* tex1D, const tcu::Sampler& sampler);
118 TextureBinding (const tcu::Texture2D* tex2D, const tcu::Sampler& sampler);
119 TextureBinding (const tcu::Texture3D* tex3D, const tcu::Sampler& sampler);
120 TextureBinding (const tcu::TextureCube* texCube, const tcu::Sampler& sampler);
121 TextureBinding (const tcu::Texture1DArray* tex1DArray, const tcu::Sampler& sampler);
122 TextureBinding (const tcu::Texture2DArray* tex2DArray, const tcu::Sampler& sampler);
123 TextureBinding (const tcu::TextureCubeArray* texCubeArray, const tcu::Sampler& sampler);
125 ~TextureBinding (void);
127 Type getType (void) const { return m_type; }
128 const tcu::Sampler& getSampler (void) const { return m_sampler; }
130 const tcu::Texture1D& get1D (void) const { DE_ASSERT(getType() == TYPE_1D && m_binding.tex1D != NULL); return *m_binding.tex1D; }
131 const tcu::Texture2D& get2D (void) const { DE_ASSERT(getType() == TYPE_2D && m_binding.tex2D != NULL); return *m_binding.tex2D; }
132 const tcu::Texture3D& get3D (void) const { DE_ASSERT(getType() == TYPE_3D && m_binding.tex3D != NULL); return *m_binding.tex3D; }
133 const tcu::TextureCube& getCube (void) const { DE_ASSERT(getType() == TYPE_CUBE_MAP && m_binding.texCube != NULL); return *m_binding.texCube; }
134 const tcu::Texture1DArray& get1DArray (void) const { DE_ASSERT(getType() == TYPE_1D_ARRAY && m_binding.tex1DArray != NULL); return *m_binding.tex1DArray; }
135 const tcu::Texture2DArray& get2DArray (void) const { DE_ASSERT(getType() == TYPE_2D_ARRAY && m_binding.tex2DArray != NULL); return *m_binding.tex2DArray; }
136 const tcu::TextureCubeArray& getCubeArray (void) const { DE_ASSERT(getType() == TYPE_CUBE_ARRAY && m_binding.texCubeArray != NULL); return *m_binding.texCubeArray; }
138 void setParameters (const Parameters& params) { m_params = params; }
139 const Parameters& getParameters (void) const { return m_params; }
142 TextureBinding (const TextureBinding&); // not allowed!
143 TextureBinding& operator= (const TextureBinding&); // not allowed!
145 static de::MovePtr<tcu::Texture2D> loadTexture2D (const tcu::Archive& archive, const char* filename);
148 tcu::Sampler m_sampler;
153 const tcu::Texture1D* tex1D;
154 const tcu::Texture2D* tex2D;
155 const tcu::Texture3D* tex3D;
156 const tcu::TextureCube* texCube;
157 const tcu::Texture1DArray* tex1DArray;
158 const tcu::Texture2DArray* tex2DArray;
159 const tcu::TextureCubeArray* texCubeArray;
163 typedef de::SharedPtr<TextureBinding> TextureBindingSp;
165 // ShaderEvalContext.
167 class ShaderEvalContext
173 MAX_USER_ATTRIBS = 4,
179 tcu::Sampler sampler;
180 const tcu::Texture1D* tex1D;
181 const tcu::Texture2D* tex2D;
182 const tcu::Texture3D* tex3D;
183 const tcu::TextureCube* texCube;
184 const tcu::Texture1DArray* tex1DArray;
185 const tcu::Texture2DArray* tex2DArray;
186 const tcu::TextureCubeArray* texCubeArray;
188 inline ShaderSampler (void)
193 , tex1DArray (DE_NULL)
194 , tex2DArray (DE_NULL)
195 , texCubeArray (DE_NULL)
200 ShaderEvalContext (const QuadGrid& quadGrid);
201 ~ShaderEvalContext (void);
203 void reset (float sx, float sy);
207 tcu::Vec4 unitCoords;
208 tcu::Vec4 constCoords;
210 tcu::Vec4 in[MAX_USER_ATTRIBS];
211 ShaderSampler textures[MAX_TEXTURES];
218 inline void discard (void) { isDiscarded = true; }
219 tcu::Vec4 texture2D (int unitNdx, const tcu::Vec2& coords);
222 const QuadGrid& m_quadGrid;
225 typedef void (*ShaderEvalFunc) (ShaderEvalContext& c);
227 inline void evalCoordsPassthroughX (ShaderEvalContext& c) { c.color.x() = c.coords.x(); }
228 inline void evalCoordsPassthroughXY (ShaderEvalContext& c) { c.color.xy() = c.coords.swizzle(0,1); }
229 inline void evalCoordsPassthroughXYZ (ShaderEvalContext& c) { c.color.xyz() = c.coords.swizzle(0,1,2); }
230 inline void evalCoordsPassthrough (ShaderEvalContext& c) { c.color = c.coords; }
231 inline void evalCoordsSwizzleWZYX (ShaderEvalContext& c) { c.color = c.coords.swizzle(3,2,1,0); }
234 // Either inherit a class with overridden evaluate() or just pass in an evalFunc.
236 class ShaderEvaluator
239 ShaderEvaluator (void);
240 ShaderEvaluator (const ShaderEvalFunc evalFunc);
241 virtual ~ShaderEvaluator (void);
243 virtual void evaluate (ShaderEvalContext& ctx) const;
246 ShaderEvaluator (const ShaderEvaluator&); // not allowed!
247 ShaderEvaluator& operator= (const ShaderEvaluator&); // not allowed!
249 const ShaderEvalFunc m_evalFunc;
254 typedef void (*UniformSetupFunc) (ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords);
260 UniformSetup (const UniformSetupFunc setup);
261 virtual ~UniformSetup (void);
262 virtual void setup (ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords) const;
265 UniformSetup (const UniformSetup&); // not allowed!
266 UniformSetup& operator= (const UniformSetup&); // not allowed!
268 const UniformSetupFunc m_setupFunc;
271 typedef void (*AttributeSetupFunc) (ShaderRenderCaseInstance& instance, deUint32 numVertices);
273 class ShaderRenderCase : public vkt::TestCase
276 ShaderRenderCase (tcu::TestContext& testCtx,
277 const std::string& name,
278 const std::string& description,
279 const bool isVertexCase,
280 const ShaderEvalFunc evalFunc,
281 const UniformSetup* uniformSetup,
282 const AttributeSetupFunc attribFunc);
284 ShaderRenderCase (tcu::TestContext& testCtx,
285 const std::string& name,
286 const std::string& description,
287 const bool isVertexCase,
288 const ShaderEvaluator* evaluator,
289 const UniformSetup* uniformSetup,
290 const AttributeSetupFunc attribFunc);
292 virtual ~ShaderRenderCase (void);
293 virtual void initPrograms (vk::SourceCollections& programCollection) const;
294 virtual TestInstance* createInstance (Context& context) const;
297 std::string m_vertShaderSource;
298 std::string m_fragShaderSource;
300 const bool m_isVertexCase;
301 const de::UniquePtr<const ShaderEvaluator> m_evaluator;
302 const de::UniquePtr<const UniformSetup> m_uniformSetup;
303 const AttributeSetupFunc m_attribFunc;
409 enum BaseAttributeType
429 // ShaderRenderCaseInstance.
431 class ShaderRenderCaseInstance : public vkt::TestInstance
434 enum ImageBackingMode
436 IMAGE_BACKING_MODE_REGULAR = 0,
437 IMAGE_BACKING_MODE_SPARSE,
440 ShaderRenderCaseInstance (Context& context);
441 ShaderRenderCaseInstance (Context& context,
442 const bool isVertexCase,
443 const ShaderEvaluator& evaluator,
444 const UniformSetup& uniformSetup,
445 const AttributeSetupFunc attribFunc,
446 const ImageBackingMode imageBackingMode = IMAGE_BACKING_MODE_REGULAR);
448 virtual ~ShaderRenderCaseInstance (void);
449 virtual tcu::TestStatus iterate (void);
451 void addAttribute (deUint32 bindingLocation,
453 deUint32 sizePerElement,
456 void useAttribute (deUint32 bindingLocation,
457 BaseAttributeType type);
460 void addUniform (deUint32 bindingLocation,
461 vk::VkDescriptorType descriptorType,
463 void addUniform (deUint32 bindingLocation,
464 vk::VkDescriptorType descriptorType,
467 void useUniform (deUint32 bindingLocation,
468 BaseUniformType type);
469 void useSampler (deUint32 bindingLocation,
472 static const tcu::Vec4 getDefaultConstCoords (void) { return tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f); }
473 void setPushConstantRanges (const deUint32 rangeCount, const vk::VkPushConstantRange* const pcRanges);
474 virtual void updatePushConstants (vk::VkCommandBuffer commandBuffer, vk::VkPipelineLayout pipelineLayout);
477 ShaderRenderCaseInstance (Context& context,
478 const bool isVertexCase,
479 const ShaderEvaluator* evaluator,
480 const UniformSetup* uniformSetup,
481 const AttributeSetupFunc attribFunc,
482 const ImageBackingMode imageBackingMode = IMAGE_BACKING_MODE_REGULAR);
484 virtual void setup (void);
485 virtual void setupUniforms (const tcu::Vec4& constCoords);
486 virtual void setupDefaultInputs (void);
488 void render (deUint32 numVertices,
489 deUint32 numTriangles,
490 const deUint16* indices,
491 const tcu::Vec4& constCoords = getDefaultConstCoords());
493 void render (deUint32 numVertices,
495 const deUint16* indices,
496 vk::VkPrimitiveTopology topology,
497 const tcu::Vec4& constCoords = getDefaultConstCoords());
499 const tcu::TextureLevel& getResultImage (void) const { return m_resultImage; }
501 const tcu::UVec2 getViewportSize (void) const;
503 void setSampleCount (vk::VkSampleCountFlagBits sampleCount);
505 bool isMultiSampling (void) const;
507 ImageBackingMode m_imageBackingMode;
512 SparseContext (vkt::Context& context);
514 vkt::Context& m_context;
515 const deUint32 m_queueFamilyIndex;
516 vk::Unique<vk::VkDevice> m_device;
517 vk::DeviceDriver m_deviceInterface;
519 const de::UniquePtr<vk::Allocator> m_allocator;
521 vk::Move<vk::VkDevice> createDevice (void) const;
522 vk::Allocator* createAllocator (void) const;
526 de::UniquePtr<SparseContext> m_sparseContext;
528 vk::Allocator& m_memAlloc;
529 const tcu::Vec4 m_clearColor;
530 const bool m_isVertexCase;
532 std::vector<tcu::Mat4> m_userAttribTransforms;
533 std::vector<TextureBindingSp> m_textures;
535 std::string m_vertexShaderName;
536 std::string m_fragmentShaderName;
537 tcu::UVec2 m_renderSize;
538 vk::VkFormat m_colorFormat;
541 typedef std::vector<tcu::ConstPixelBufferAccess> TextureLayerData;
542 typedef std::vector<TextureLayerData> TextureData;
544 void uploadImage (const tcu::TextureFormat& texFormat,
545 const TextureData& textureData,
546 const tcu::Sampler& refSampler,
548 deUint32 arrayLayers,
549 vk::VkImage destImage);
551 void clearImage (const tcu::Sampler& refSampler,
553 deUint32 arrayLayers,
554 vk::VkImage destImage);
556 void checkSparseSupport (const vk::VkImageType imageType) const;
558 void uploadSparseImage (const tcu::TextureFormat& texFormat,
559 const TextureData& textureData,
560 const tcu::Sampler& refSampler,
561 const deUint32 mipLevels,
562 const deUint32 arrayLayers,
563 const vk::VkImage sparseImage,
564 const vk::VkImageCreateInfo& imageCreateInfo,
565 const tcu::UVec3 texSize);
567 void createSamplerUniform (deUint32 bindingLocation,
568 TextureBinding::Type textureType,
569 TextureBinding::Init textureInit,
570 const tcu::TextureFormat& texFormat,
571 const tcu::UVec3 texSize,
572 const TextureData& textureData,
573 const tcu::Sampler& refSampler,
575 deUint32 arrayLayers,
576 TextureBinding::Parameters textureParams);
578 void setupUniformData (deUint32 bindingLocation, size_t size, const void* dataPtr);
580 void computeVertexReference (tcu::Surface& result, const QuadGrid& quadGrid);
581 void computeFragmentReference (tcu::Surface& result, const QuadGrid& quadGrid);
582 bool compareImages (const tcu::Surface& resImage,
583 const tcu::Surface& refImage,
584 float errorThreshold);
587 const ShaderEvaluator* m_evaluator;
588 const UniformSetup* m_uniformSetup;
589 const AttributeSetupFunc m_attribFunc;
590 de::MovePtr<QuadGrid> m_quadGrid;
591 tcu::TextureLevel m_resultImage;
593 struct EnabledBaseAttribute
596 BaseAttributeType type;
598 std::vector<EnabledBaseAttribute> m_enabledBaseAttributes;
600 de::MovePtr<vk::DescriptorSetLayoutBuilder> m_descriptorSetLayoutBuilder;
601 de::MovePtr<vk::DescriptorPoolBuilder> m_descriptorPoolBuilder;
602 de::MovePtr<vk::DescriptorSetUpdateBuilder> m_descriptorSetUpdateBuilder;
604 typedef de::SharedPtr<vk::Unique<vk::VkBuffer> > VkBufferSp;
605 typedef de::SharedPtr<vk::Unique<vk::VkImage> > VkImageSp;
606 typedef de::SharedPtr<vk::Unique<vk::VkImageView> > VkImageViewSp;
607 typedef de::SharedPtr<vk::Unique<vk::VkSampler> > VkSamplerSp;
608 typedef de::SharedPtr<vk::Allocation> AllocationSp;
613 UniformInfo (void) {}
614 virtual ~UniformInfo (void) {}
616 vk::VkDescriptorType type;
620 class BufferUniform : public UniformInfo
623 BufferUniform (void) {}
624 virtual ~BufferUniform (void) {}
628 vk::VkDescriptorBufferInfo descriptor;
631 class SamplerUniform : public UniformInfo
634 SamplerUniform (void) {}
635 virtual ~SamplerUniform (void) {}
638 VkImageViewSp imageView;
641 vk::VkDescriptorImageInfo descriptor;
644 typedef de::SharedPtr<de::UniquePtr<UniformInfo> > UniformInfoSp;
645 std::vector<UniformInfoSp> m_uniformInfos;
647 std::vector< de::SharedPtr<vk::Allocation> > m_allocations;
649 std::vector<vk::VkVertexInputBindingDescription> m_vertexBindingDescription;
650 std::vector<vk::VkVertexInputAttributeDescription> m_vertexAttributeDescription;
652 std::vector<VkBufferSp> m_vertexBuffers;
653 std::vector<AllocationSp> m_vertexBufferAllocs;
655 vk::VkSampleCountFlagBits m_sampleCount;
656 std::vector<vk::VkPushConstantRange> m_pushConstantRanges;
658 // Wrapper functions around m_context calls to support sparse cases.
659 vk::VkDevice getDevice (void) const;
660 deUint32 getUniversalQueueFamilyIndex (void) const;
661 const vk::DeviceInterface& getDeviceInterface (void) const;
662 vk::VkQueue getUniversalQueue (void) const;
663 vk::VkPhysicalDevice getPhysicalDevice (void) const;
664 const vk::InstanceInterface& getInstanceInterface (void) const;
665 SparseContext* createSparseContext (void) const;
666 vk::Allocator& getAllocator (void) const;
670 void ShaderRenderCaseInstance::addUniform (deUint32 bindingLocation, vk::VkDescriptorType descriptorType, const T& data)
672 addUniform(bindingLocation, descriptorType, sizeof(T), &data);
678 #endif // _VKTSHADERRENDER_HPP