Home | History | Annotate | Download | only in shaderrender
      1 #ifndef _VKTSHADERRENDER_HPP
      2 #define _VKTSHADERRENDER_HPP
      3 /*------------------------------------------------------------------------
      4  * Vulkan Conformance Tests
      5  * ------------------------
      6  *
      7  * Copyright (c) 2015 The Khronos Group Inc.
      8  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
      9  *
     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
     13  *
     14  *      http://www.apache.org/licenses/LICENSE-2.0
     15  *
     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.
     21  *
     22  *//*!
     23  * \file
     24  * \brief Vulkan ShaderRenderCase
     25  *//*--------------------------------------------------------------------*/
     26 
     27 #include "tcuTexture.hpp"
     28 #include "tcuSurface.hpp"
     29 
     30 #include "deMemory.h"
     31 #include "deSharedPtr.hpp"
     32 #include "deUniquePtr.hpp"
     33 
     34 #include "vkDefs.hpp"
     35 #include "vkPrograms.hpp"
     36 #include "vkRef.hpp"
     37 #include "vkMemUtil.hpp"
     38 #include "vkBuilderUtil.hpp"
     39 
     40 #include "vktTestCaseUtil.hpp"
     41 
     42 namespace vkt
     43 {
     44 namespace sr
     45 {
     46 
     47 class LineStream
     48 {
     49 public:
     50 						LineStream		(int indent = 0)	{ m_indent = indent; }
     51 						~LineStream		(void)				{}
     52 
     53 	const char*			str				(void) const		{ m_string = m_stream.str(); return m_string.c_str(); }
     54 	LineStream&			operator<<		(const char* line)	{ for (int i = 0; i < m_indent; i++) { m_stream << "\t"; } m_stream << line << "\n"; return *this; }
     55 
     56 private:
     57 	int					m_indent;
     58 	std::ostringstream	m_stream;
     59 	mutable std::string	m_string;
     60 };
     61 
     62 class QuadGrid;
     63 class ShaderRenderCaseInstance;
     64 
     65 class TextureBinding
     66 {
     67 public:
     68 	enum Type
     69 	{
     70 		TYPE_NONE = 0,
     71 		TYPE_2D,
     72 		TYPE_CUBE_MAP,
     73 		TYPE_2D_ARRAY,
     74 		TYPE_3D,
     75 
     76 		TYPE_LAST
     77 	};
     78 
     79 										TextureBinding		(const tcu::Archive&	archive,
     80 															const char*				filename,
     81 															const Type				type,
     82 															const tcu::Sampler&		sampler);
     83 										~TextureBinding		(void);
     84 	Type								getType				(void) const { return m_type;		}
     85 	const tcu::Sampler&					getSampler			(void) const { return m_sampler;	}
     86 	const tcu::Texture2D&				get2D				(void) const { DE_ASSERT(getType() == TYPE_2D && m_binding.tex2D !=NULL); return *m_binding.tex2D; }
     87 
     88 private:
     89 										TextureBinding		(const TextureBinding&);	// not allowed!
     90 	TextureBinding&						operator=			(const TextureBinding&);	// not allowed!
     91 
     92 	static de::MovePtr<tcu::Texture2D>	loadTexture2D		(const tcu::Archive& archive, const char* filename);
     93 
     94 	Type								m_type;
     95 	tcu::Sampler						m_sampler;
     96 
     97 	union
     98 	{
     99 		const tcu::Texture2D*	tex2D;
    100 	} m_binding;
    101 };
    102 
    103 typedef de::SharedPtr<TextureBinding> TextureBindingSp;
    104 
    105 // ShaderEvalContext.
    106 
    107 class ShaderEvalContext
    108 {
    109 public:
    110 	// Limits.
    111 	enum
    112 	{
    113 		MAX_USER_ATTRIBS	= 4,
    114 		MAX_TEXTURES		= 4
    115 	};
    116 
    117 	struct ShaderSampler
    118 	{
    119 		tcu::Sampler				sampler;
    120 		const tcu::Texture2D*		tex2D;
    121 		const tcu::TextureCube*		texCube;
    122 		const tcu::Texture2DArray*	tex2DArray;
    123 		const tcu::Texture3D*		tex3D;
    124 
    125 		inline ShaderSampler (void)
    126 			: tex2D		(DE_NULL)
    127 			, texCube	(DE_NULL)
    128 			, tex2DArray(DE_NULL)
    129 			, tex3D		(DE_NULL)
    130 		{
    131 		}
    132 	};
    133 
    134 							ShaderEvalContext		(const QuadGrid& quadGrid);
    135 							~ShaderEvalContext		(void);
    136 
    137 	void					reset					(float sx, float sy);
    138 
    139 	// Inputs.
    140 	tcu::Vec4				coords;
    141 	tcu::Vec4				unitCoords;
    142 	tcu::Vec4				constCoords;
    143 
    144 	tcu::Vec4				in[MAX_USER_ATTRIBS];
    145 	ShaderSampler			textures[MAX_TEXTURES];
    146 
    147 	// Output.
    148 	tcu::Vec4				color;
    149 	bool					isDiscarded;
    150 
    151 	// Functions.
    152 	inline void				discard					(void)  { isDiscarded = true; }
    153 	tcu::Vec4				texture2D				(int unitNdx, const tcu::Vec2& coords);
    154 
    155 private:
    156 	const QuadGrid&			m_quadGrid;
    157 };
    158 
    159 typedef void (*ShaderEvalFunc) (ShaderEvalContext& c);
    160 
    161 inline void evalCoordsPassthroughX		(ShaderEvalContext& c) { c.color.x() = c.coords.x(); }
    162 inline void evalCoordsPassthroughXY		(ShaderEvalContext& c) { c.color.xy() = c.coords.swizzle(0,1); }
    163 inline void evalCoordsPassthroughXYZ	(ShaderEvalContext& c) { c.color.xyz() = c.coords.swizzle(0,1,2); }
    164 inline void evalCoordsPassthrough		(ShaderEvalContext& c) { c.color = c.coords; }
    165 inline void evalCoordsSwizzleWZYX		(ShaderEvalContext& c) { c.color = c.coords.swizzle(3,2,1,0); }
    166 
    167 // ShaderEvaluator
    168 // Either inherit a class with overridden evaluate() or just pass in an evalFunc.
    169 
    170 class ShaderEvaluator
    171 {
    172 public:
    173 							ShaderEvaluator			(void);
    174 							ShaderEvaluator			(const ShaderEvalFunc evalFunc);
    175 	virtual					~ShaderEvaluator		(void);
    176 
    177 	virtual void			evaluate				(ShaderEvalContext& ctx) const;
    178 
    179 private:
    180 							ShaderEvaluator			(const ShaderEvaluator&);   // not allowed!
    181 	ShaderEvaluator&		operator=				(const ShaderEvaluator&);   // not allowed!
    182 
    183 	const ShaderEvalFunc	m_evalFunc;
    184 };
    185 
    186 // UniformSetup
    187 
    188 typedef void (*UniformSetupFunc) (ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords);
    189 
    190 class UniformSetup
    191 {
    192 public:
    193 							UniformSetup			(void);
    194 							UniformSetup			(const UniformSetupFunc setup);
    195 	virtual					~UniformSetup			(void);
    196 	virtual void			setup					(ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords) const;
    197 
    198 private:
    199 							UniformSetup			(const UniformSetup&);	// not allowed!
    200 	UniformSetup&			operator=				(const UniformSetup&);	// not allowed!
    201 
    202 	const UniformSetupFunc	m_setupFunc;
    203 };
    204 
    205 typedef void (*AttributeSetupFunc) (ShaderRenderCaseInstance& instance, deUint32 numVertices);
    206 
    207 class ShaderRenderCase : public vkt::TestCase
    208 {
    209 public:
    210 													ShaderRenderCase	(tcu::TestContext&			testCtx,
    211 																		 const std::string&			name,
    212 																		 const std::string&			description,
    213 																		 const bool					isVertexCase,
    214 																		 const ShaderEvalFunc		evalFunc,
    215 																		 const UniformSetup*		uniformSetup,
    216 																		 const AttributeSetupFunc	attribFunc);
    217 
    218 													ShaderRenderCase	(tcu::TestContext&			testCtx,
    219 																		 const std::string&			name,
    220 																		 const std::string&			description,
    221 																		 const bool					isVertexCase,
    222 																		 const ShaderEvaluator*		evaluator,
    223 																		 const UniformSetup*		uniformSetup,
    224 																		 const AttributeSetupFunc	attribFunc);
    225 
    226 
    227 	virtual											~ShaderRenderCase	(void);
    228 	virtual	void									initPrograms		(vk::SourceCollections& programCollection) const;
    229 	virtual	TestInstance*							createInstance		(Context& context) const;
    230 
    231 protected:
    232 	std::string										m_vertShaderSource;
    233 	std::string										m_fragShaderSource;
    234 
    235 	const bool										m_isVertexCase;
    236 	const de::UniquePtr<const ShaderEvaluator>		m_evaluator;
    237 	const de::UniquePtr<const UniformSetup>			m_uniformSetup;
    238 	const AttributeSetupFunc						m_attribFunc;
    239 };
    240 
    241 
    242 enum BaseUniformType
    243 {
    244 // Bool
    245 	UB_FALSE,
    246 	UB_TRUE,
    247 
    248 // BVec4
    249 	UB4_FALSE,
    250 	UB4_TRUE,
    251 
    252 // Integers
    253 	UI_ZERO,
    254 	UI_ONE,
    255 	UI_TWO,
    256 	UI_THREE,
    257 	UI_FOUR,
    258 	UI_FIVE,
    259 	UI_SIX,
    260 	UI_SEVEN,
    261 	UI_EIGHT,
    262 	UI_ONEHUNDREDONE,
    263 
    264 // IVec2
    265 	UI2_MINUS_ONE,
    266 	UI2_ZERO,
    267 	UI2_ONE,
    268 	UI2_TWO,
    269 	UI2_THREE,
    270 	UI2_FOUR,
    271 	UI2_FIVE,
    272 
    273 // IVec3
    274 	UI3_MINUS_ONE,
    275 	UI3_ZERO,
    276 	UI3_ONE,
    277 	UI3_TWO,
    278 	UI3_THREE,
    279 	UI3_FOUR,
    280 	UI3_FIVE,
    281 
    282 // IVec4
    283 	UI4_MINUS_ONE,
    284 	UI4_ZERO,
    285 	UI4_ONE,
    286 	UI4_TWO,
    287 	UI4_THREE,
    288 	UI4_FOUR,
    289 	UI4_FIVE,
    290 
    291 // Float
    292 	UF_ZERO,
    293 	UF_ONE,
    294 	UF_TWO,
    295 	UF_THREE,
    296 	UF_FOUR,
    297 	UF_FIVE,
    298 	UF_SIX,
    299 	UF_SEVEN,
    300 	UF_EIGHT,
    301 
    302 	UF_HALF,
    303 	UF_THIRD,
    304 	UF_FOURTH,
    305 	UF_FIFTH,
    306 	UF_SIXTH,
    307 	UF_SEVENTH,
    308 	UF_EIGHTH,
    309 
    310 // Vec2
    311 	UV2_MINUS_ONE,
    312 	UV2_ZERO,
    313 	UV2_ONE,
    314 	UV2_TWO,
    315 	UV2_THREE,
    316 
    317 	UV2_HALF,
    318 
    319 // Vec3
    320 	UV3_MINUS_ONE,
    321 	UV3_ZERO,
    322 	UV3_ONE,
    323 	UV3_TWO,
    324 	UV3_THREE,
    325 
    326 	UV3_HALF,
    327 
    328 // Vec4
    329 	UV4_MINUS_ONE,
    330 	UV4_ZERO,
    331 	UV4_ONE,
    332 	UV4_TWO,
    333 	UV4_THREE,
    334 
    335 	UV4_HALF,
    336 
    337 	UV4_BLACK,
    338 	UV4_GRAY,
    339 	UV4_WHITE
    340 };
    341 
    342 enum BaseAttributeType
    343 {
    344 // User attributes
    345 	A_IN0,
    346 	A_IN1,
    347 	A_IN2,
    348 	A_IN3,
    349 
    350 // Matrices
    351 	MAT2,
    352 	MAT2x3,
    353 	MAT2x4,
    354 	MAT3x2,
    355 	MAT3,
    356 	MAT3x4,
    357 	MAT4x2,
    358 	MAT4x3,
    359 	MAT4
    360 };
    361 
    362 // ShaderRenderCaseInstance.
    363 
    364 class ShaderRenderCaseInstance : public vkt::TestInstance
    365 {
    366 public:
    367 														ShaderRenderCaseInstance	(Context&					context,
    368 																					const bool					isVertexCase,
    369 																					const ShaderEvaluator&		evaluator,
    370 																					const UniformSetup&			uniformSetup,
    371 																					const AttributeSetupFunc	attribFunc);
    372 
    373 	virtual												~ShaderRenderCaseInstance	(void);
    374 	virtual tcu::TestStatus								iterate						(void);
    375 
    376 	void												addAttribute				(deUint32			bindingLocation,
    377 																					vk::VkFormat		format,
    378 																					deUint32			sizePerElement,
    379 																					deUint32			count,
    380 																					const void*			data);
    381 	void												useAttribute				(deUint32			bindingLocation,
    382 																					BaseAttributeType	type);
    383 
    384 	template<typename T>
    385 	void												addUniform					(deUint32				bindingLocation,
    386 																					vk::VkDescriptorType	descriptorType,
    387 																					const T&				data);
    388 	void												addUniform					(deUint32				bindingLocation,
    389 																					vk::VkDescriptorType	descriptorType,
    390 																					size_t					dataSize,
    391 																					const void*				data);
    392 	void												useUniform					(deUint32				bindingLocation,
    393 																					BaseUniformType			type);
    394 	void												useSampler2D				(deUint32				bindingLocation,
    395 																					deUint32				textureId);
    396 
    397 protected:
    398 	virtual void										setup						(void);
    399 	virtual void										setupUniforms				(const tcu::Vec4& constCoords);
    400 
    401 	const tcu::UVec2									getViewportSize				(void) const;
    402 
    403 	std::vector<tcu::Mat4>								m_userAttribTransforms;
    404 	const tcu::Vec4										m_clearColor;
    405 	std::vector<TextureBindingSp>						m_textures;
    406 
    407 	vk::Allocator&										m_memAlloc;
    408 
    409 private:
    410 
    411 	void												setupTextures				(void);
    412 	de::MovePtr<vk::Allocation>							uploadImage2D				(const tcu::Texture2D&			refTexture,
    413 																					 const vk::VkImage&				vkTexture);
    414 	vk::Move<vk::VkImage>								createImage2D				(const tcu::Texture2D&			texture,
    415 																					 const vk::VkFormat				format,
    416 																					 const vk::VkImageUsageFlags	usage,
    417 																					 const vk::VkImageTiling		tiling);
    418 	void												copyTilingImageToOptimal	(const vk::VkImage&				srcImage,
    419 																					 const vk::VkImage&				dstImage,
    420 																					 deUint32						width,
    421 																					 deUint32						height);
    422 
    423 	void												setupUniformData			(deUint32 bindingLocation, size_t size, const void* dataPtr);
    424 	void												setupDefaultInputs			(const QuadGrid& quadGrid);
    425 
    426 	void												render						(tcu::Surface& result, const QuadGrid& quadGrid);
    427 	void												computeVertexReference		(tcu::Surface& result, const QuadGrid& quadGrid);
    428 	void												computeFragmentReference	(tcu::Surface& result, const QuadGrid& quadGrid);
    429 	bool												compareImages				(const tcu::Surface&	resImage,
    430 																					 const tcu::Surface&	refImage,
    431 																					 float					errorThreshold);
    432 
    433 	const bool											m_isVertexCase;
    434 	const ShaderEvaluator&								m_evaluator;
    435 	const UniformSetup&									m_uniformSetup;
    436 	const AttributeSetupFunc							m_attribFunc;
    437 
    438 	struct EnabledBaseAttribute
    439 	{
    440 		deUint32			location;
    441 		BaseAttributeType	type;
    442 	};
    443 	std::vector<EnabledBaseAttribute>					m_enabledBaseAttributes;
    444 
    445 	const tcu::UVec2									m_renderSize;
    446 	const vk::VkFormat									m_colorFormat;
    447 
    448 	vk::Move<vk::VkImage>								m_colorImage;
    449 	de::MovePtr<vk::Allocation>							m_colorImageAlloc;
    450 	vk::Move<vk::VkImageView>							m_colorImageView;
    451 
    452 	vk::Move<vk::VkRenderPass>							m_renderPass;
    453 	vk::Move<vk::VkFramebuffer>							m_framebuffer;
    454 	vk::Move<vk::VkPipelineLayout>						m_pipelineLayout;
    455 	vk::Move<vk::VkPipeline>							m_graphicsPipeline;
    456 
    457 	vk::Move<vk::VkShaderModule>						m_vertexShaderModule;
    458 	vk::Move<vk::VkShaderModule>						m_fragmentShaderModule;
    459 
    460 	vk::Move<vk::VkBuffer>								m_indiceBuffer;
    461 	de::MovePtr<vk::Allocation>							m_indiceBufferAlloc;
    462 
    463 	vk::Move<vk::VkDescriptorSetLayout>					m_descriptorSetLayout;
    464 
    465 	vk::Move<vk::VkDescriptorPool>						m_descriptorPool;
    466 	vk::Move<vk::VkDescriptorSet>						m_descriptorSet;
    467 
    468 	vk::Move<vk::VkCommandPool>							m_cmdPool;
    469 	vk::Move<vk::VkCommandBuffer>						m_cmdBuffer;
    470 
    471 	vk::Move<vk::VkFence>								m_fence;
    472 
    473 	vk::DescriptorSetLayoutBuilder						m_descriptorSetLayoutBuilder;
    474 	vk::DescriptorPoolBuilder							m_descriptorPoolBuilder;
    475 	vk::DescriptorSetUpdateBuilder						m_descriptorSetUpdateBuilder;
    476 
    477 	typedef de::SharedPtr<vk::Unique<vk::VkBuffer> >		VkBufferSp;
    478 
    479 	typedef de::SharedPtr<vk::Unique<vk::VkImage> >			VkImageSp;
    480 	typedef de::SharedPtr<vk::Unique<vk::VkImageView> >		VkImageViewSp;
    481 	typedef de::SharedPtr<vk::Unique<vk::VkSampler> >		VkSamplerSp;
    482 	typedef de::SharedPtr<vk::Allocation>					AllocationSp;
    483 
    484 	class UniformInfo
    485 	{
    486 	public:
    487 									UniformInfo		(void) {}
    488 		virtual						~UniformInfo	(void) {}
    489 
    490 		vk::VkDescriptorType		type;
    491 		deUint32					location;
    492 	};
    493 
    494 	class BufferUniform : public UniformInfo
    495 	{
    496 	public:
    497 									BufferUniform	(void) {}
    498 		virtual						~BufferUniform	(void) {}
    499 
    500 		VkBufferSp					buffer;
    501 		AllocationSp				alloc;
    502 		vk::VkDescriptorBufferInfo	descriptor;
    503 	};
    504 
    505 	class SamplerUniform : public UniformInfo
    506 	{
    507 	public:
    508 									SamplerUniform	(void) {}
    509 		virtual						~SamplerUniform	(void) {}
    510 
    511 		VkImageSp					image;
    512 		VkImageViewSp				imageView;
    513 		VkSamplerSp					sampler;
    514 		AllocationSp				alloc;
    515 		vk::VkDescriptorImageInfo	descriptor;
    516 	};
    517 
    518 	typedef de::SharedPtr<de::UniquePtr<UniformInfo> >	UniformInfoSp;
    519 	std::vector<UniformInfoSp>							m_uniformInfos;
    520 
    521 	std::vector<vk::VkVertexInputBindingDescription>	m_vertexBindingDescription;
    522 	std::vector<vk::VkVertexInputAttributeDescription>	m_vertexattributeDescription;
    523 
    524 	std::vector<VkBufferSp>								m_vertexBuffers;
    525 	std::vector<AllocationSp>							m_vertexBufferAllocs;
    526 };
    527 
    528 template<typename T>
    529 void ShaderRenderCaseInstance::addUniform (deUint32 bindingLocation, vk::VkDescriptorType descriptorType, const T& data)
    530 {
    531 	addUniform(bindingLocation, descriptorType, sizeof(T), &data);
    532 }
    533 
    534 } // sr
    535 } // vkt
    536 
    537 #endif // _VKTSHADERRENDER_HPP
    538