Home | History | Annotate | Download | only in shaderexecutor
      1 #ifndef _VKTSHADEREXECUTOR_HPP
      2 #define _VKTSHADEREXECUTOR_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 ShaderExecutor
     25  *//*--------------------------------------------------------------------*/
     26 
     27 #include "deSharedPtr.hpp"
     28 
     29 #include "vktTestCase.hpp"
     30 #include "vkMemUtil.hpp"
     31 #include "vkBuilderUtil.hpp"
     32 
     33 #include "gluVarType.hpp"
     34 
     35 #include "tcuTexture.hpp"
     36 
     37 #include <vector>
     38 
     39 namespace vkt
     40 {
     41 namespace shaderexecutor
     42 {
     43 
     44 using namespace vk;
     45 
     46 //! Shader input / output variable declaration.
     47 struct Symbol
     48 {
     49 	std::string				name;		//!< Symbol name.
     50 	glu::VarType			varType;	//!< Symbol type.
     51 
     52 	Symbol (void) {}
     53 	Symbol (const std::string& name_, const glu::VarType& varType_) : name(name_), varType(varType_) {}
     54 };
     55 
     56 //! Complete shader specification.
     57 struct ShaderSpec
     58 {
     59 	std::vector<Symbol>		inputs;
     60 	std::vector<Symbol>		outputs;
     61 	std::string				globalDeclarations;	//!< These are placed into global scope. Can contain uniform declarations for example.
     62 	std::string				source;				//!< Source snippet to be executed.
     63 
     64 	ShaderSpec (void) {}
     65 };
     66 
     67 // UniformSetup
     68 
     69 class UniformDataBase;
     70 class ShaderExecutor;
     71 
     72 typedef de::SharedPtr<de::UniquePtr<UniformDataBase> > UniformDataSp;
     73 
     74 class UniformSetup
     75 {
     76 public:
     77 										UniformSetup		(void) {}
     78 	virtual								~UniformSetup		(void) {}
     79 
     80 	void								addData				(UniformDataBase* uniformData)
     81 										{
     82 											m_uniforms.push_back(UniformDataSp(new de::UniquePtr<UniformDataBase>(uniformData)));
     83 										}
     84 
     85 	const std::vector<UniformDataSp>&	uniforms			(void) const
     86 										{
     87 											return m_uniforms;
     88 										}
     89 
     90 private:
     91 										UniformSetup		(const UniformSetup&);	// not allowed!
     92 	UniformSetup&						operator=			(const UniformSetup&);	// not allowed!
     93 
     94 	std::vector<UniformDataSp>			m_uniforms;
     95 };
     96 
     97 //! Base class for shader executor.
     98 class ShaderExecutor
     99 {
    100 public:
    101 	virtual					~ShaderExecutor		(void);
    102 
    103 	//! Log executor details (program etc.).
    104 	virtual void			log					(tcu::TestLog& log) const = 0;
    105 
    106 	//! Execute
    107 	virtual void			execute				(const Context& ctx, int numValues, const void* const* inputs, void* const* outputs) = 0;
    108 
    109 	virtual void			setShaderSources	(SourceCollections& programCollection) const = 0;
    110 
    111 	void					setUniforms			(const UniformSetup* uniformSetup)
    112 												{
    113 													m_uniformSetup = de::MovePtr<const UniformSetup>(uniformSetup);
    114 												};
    115 
    116 	void					setupUniformData	(const VkDevice&			vkDevice,
    117 												 const DeviceInterface&		vk,
    118 												 const VkQueue				queue,
    119 												 const deUint32				queueFamilyIndex,
    120 												 Allocator&					memAlloc,
    121 												 deUint32					bindingLocation,
    122 												 VkDescriptorType			descriptorType,
    123 												 deUint32					size,
    124 												 const void*				dataPtr);
    125 
    126 	void					setupUniformArray	(const VkDevice&			vkDevice,
    127 												 const DeviceInterface&		vk,
    128 												 const VkQueue				queue,
    129 												 const deUint32				queueFamilyIndex,
    130 												 Allocator&					memAlloc,
    131 												 deUint32					bindingLocation,
    132 												 VkDescriptorType			descriptorType,
    133 												 deUint32					arraySize,
    134 												 deUint32					size,
    135 												 const void*				dataPtr);
    136 
    137 	void					setupSamplerData	(const VkDevice&			vkDevice,
    138 												 const DeviceInterface&		vk,
    139 												 const VkQueue				queue,
    140 												 const deUint32				queueFamilyIndex,
    141 												 Allocator&					memAlloc,
    142 												 deUint32					bindingLocation,
    143 												 deUint32					numSamplers,
    144 												 const tcu::Sampler&		refSampler,
    145 												 const tcu::TextureFormat&	texFormat,
    146 												 const tcu::IVec3&			texSize,
    147 												 VkImageType				imageType,
    148 												 VkImageViewType			imageViewType,
    149 												 const void*				data);
    150 
    151 	const void*				getBufferPtr		(const deUint32 bindingLocation) const;
    152 
    153 protected:
    154 							ShaderExecutor		(const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
    155 
    156 	void					addUniforms			(const VkDevice& vkDevice, const DeviceInterface& vk, const VkQueue queue, const deUint32 queueFamilyIndex, Allocator& memAlloc);
    157 
    158 	void					uploadUniforms		(DescriptorSetUpdateBuilder& descriptorSetUpdateBuilder, VkDescriptorSet descriptorSet);
    159 
    160 	class UniformInfo;
    161 	typedef de::SharedPtr<de::UniquePtr<UniformInfo> >			UniformInfoSp;
    162 	class BufferUniform;
    163 	typedef de::SharedPtr<de::UniquePtr<BufferUniform> >		BufferUniformSp;
    164 	class SamplerUniform;
    165 	typedef de::SharedPtr<de::UniquePtr<SamplerUniform> >		SamplerUniformSp;
    166 
    167 	typedef de::SharedPtr<Unique<VkBuffer> >			VkBufferSp;
    168 	typedef de::SharedPtr<Unique<VkImage> >				VkImageSp;
    169 	typedef de::SharedPtr<Unique<VkImageView> >			VkImageViewSp;
    170 	typedef de::SharedPtr<Unique<VkSampler> >			VkSamplerSp;
    171 	typedef de::SharedPtr<Allocation>					AllocationSp;
    172 
    173 	class UniformInfo
    174 	{
    175 	public:
    176 		enum UniformType
    177 		{
    178 			UNIFORM_TYPE_BUFFER = 0,
    179 			UNIFORM_TYPE_SAMPLER,
    180 			UNIFORM_TYPE_BUFFER_ARRAY,
    181 			UNIFORM_TYPE_SAMPLER_ARRAY,
    182 
    183 			UNIFORM_TYPE_LAST
    184 		};
    185 
    186 									UniformInfo			(void) {}
    187 		virtual						~UniformInfo		(void) {}
    188 		virtual UniformType			getType				(void) const = 0;
    189 
    190 		VkDescriptorType			type;
    191 		deUint32					location;
    192 	};
    193 
    194 	class BufferUniform : public UniformInfo
    195 	{
    196 	public:
    197 									BufferUniform		(void) {}
    198 		virtual						~BufferUniform		(void) {}
    199 		virtual UniformType			getType				(void) const { return UNIFORM_TYPE_BUFFER; }
    200 
    201 		VkBufferSp					buffer;
    202 		AllocationSp				alloc;
    203 		VkDescriptorBufferInfo		descriptor;
    204 	};
    205 
    206 	class SamplerUniform : public UniformInfo
    207 	{
    208 	public:
    209 									SamplerUniform		(void) {}
    210 		virtual						~SamplerUniform		(void) {}
    211 		virtual UniformType			getType				(void) const { return UNIFORM_TYPE_SAMPLER; }
    212 
    213 		VkImageSp					image;
    214 		VkImageViewSp				imageView;
    215 		VkSamplerSp					sampler;
    216 		AllocationSp				alloc;
    217 		VkDescriptorImageInfo		descriptor;
    218 	};
    219 
    220 	class BufferArrayUniform : public UniformInfo
    221 	{
    222 	public:
    223 											BufferArrayUniform		(void) {}
    224 		virtual								~BufferArrayUniform		(void) {}
    225 		virtual UniformType					getType					(void) const { return UNIFORM_TYPE_BUFFER_ARRAY; }
    226 
    227 		std::vector<BufferUniformSp>		uniforms;
    228 	};
    229 
    230 	class SamplerArrayUniform : public UniformInfo
    231 	{
    232 	public:
    233 											SamplerArrayUniform		(void) {}
    234 		virtual								~SamplerArrayUniform	(void) {}
    235 		virtual UniformType					getType					(void) const { return UNIFORM_TYPE_SAMPLER_ARRAY; }
    236 
    237 		std::vector<SamplerUniformSp>		uniforms;
    238 	};
    239 
    240 	void									uploadImage					(const VkDevice&				vkDevice,
    241 																		 const DeviceInterface&			vk,
    242 																		 const VkQueue					queue,
    243 																		 const deUint32					queueFamilyIndex,
    244 																		 Allocator&						memAlloc,
    245 																		 const tcu::TextureFormat&		texFormat,
    246 																		 const tcu::IVec3&				texSize,
    247 																		 const void*					data,
    248 																		 const deUint32					arraySize,
    249 																		 const VkImageAspectFlags		aspectMask,
    250 																		 VkImage						destImage);
    251 
    252 	de::MovePtr<SamplerUniform>				createSamplerUniform		(const VkDevice&				vkDevice,
    253 																		 const DeviceInterface&			vk,
    254 																		 const VkQueue					queue,
    255 																		 const deUint32					queueFamilyIndex,
    256 																		 Allocator&						memAlloc,
    257 																		 deUint32						bindingLocation,
    258 																		 const tcu::Sampler&			refSampler,
    259 																		 const tcu::TextureFormat&		texFormat,
    260 																		 const tcu::IVec3&				texSize,
    261 																		 VkImageType					imageType,
    262 																		 VkImageViewType				imageViewType,
    263 																		 const void*					data);
    264 
    265 	de::MovePtr<BufferUniform>				createBufferUniform			(const VkDevice&				vkDevice,
    266 																		 const DeviceInterface&			vk,
    267 																		 const VkQueue					queue,
    268 																		 const deUint32					queueFamilyIndex,
    269 																		 Allocator&						memAlloc,
    270 																		 deUint32						bindingLocation,
    271 																		 VkDescriptorType				descriptorType,
    272 																		 deUint32						size,
    273 																		 const void*					dataPtr);
    274 
    275 	const ShaderSpec									m_shaderSpec;
    276 	const glu::ShaderType								m_shaderType;
    277 
    278 	std::vector<UniformInfoSp>							m_uniformInfos;
    279 	de::MovePtr<const UniformSetup>						m_uniformSetup;
    280 	DescriptorSetLayoutBuilder							m_descriptorSetLayoutBuilder;
    281 	DescriptorPoolBuilder								m_descriptorPoolBuilder;
    282 
    283 };
    284 
    285 inline tcu::TestLog& operator<< (tcu::TestLog& log, const ShaderExecutor* executor) { executor->log(log); return log; }
    286 inline tcu::TestLog& operator<< (tcu::TestLog& log, const ShaderExecutor& executor) { executor.log(log); return log; }
    287 
    288 ShaderExecutor* createExecutor(glu::ShaderType shaderType, const ShaderSpec& shaderSpec);
    289 
    290 class UniformDataBase
    291 {
    292 public:
    293 							UniformDataBase		(deUint32 bindingLocation)
    294 													: m_bindingLocation		(bindingLocation)
    295 												{
    296 												}
    297 	virtual					~UniformDataBase	(void) {}
    298 	virtual void			setup				(ShaderExecutor&, const VkDevice&, const DeviceInterface&, const VkQueue, const deUint32, Allocator&) const = 0;
    299 
    300 protected:
    301 	const deUint32			m_bindingLocation;
    302 };
    303 
    304 template<typename T>
    305 class UniformData : public UniformDataBase
    306 {
    307 public:
    308 							UniformData			(deUint32 bindingLocation, VkDescriptorType descriptorType, const T data);
    309 	virtual					~UniformData		(void);
    310 	virtual void			setup				(ShaderExecutor& executor, const VkDevice& vkDevice, const DeviceInterface& vk, const VkQueue queue, const deUint32 queueFamilyIndex, Allocator& memAlloc) const;
    311 
    312 private:
    313 	VkDescriptorType		m_descriptorType;
    314 	T						m_data;
    315 };
    316 
    317 template<typename T>
    318 UniformData<T>::UniformData (deUint32 bindingLocation, VkDescriptorType descriptorType, const T data)
    319 	: UniformDataBase		(bindingLocation)
    320 	, m_descriptorType		(descriptorType)
    321 	, m_data				(data)
    322 {
    323 }
    324 
    325 template<typename T>
    326 UniformData<T>::~UniformData (void)
    327 {
    328 }
    329 
    330 template<typename T>
    331 void UniformData<T>::setup (ShaderExecutor& executor, const VkDevice& vkDevice, const DeviceInterface& vk, const VkQueue queue, const deUint32 queueFamilyIndex, Allocator& memAlloc) const
    332 {
    333 	executor.setupUniformData(vkDevice, vk, queue, queueFamilyIndex, memAlloc, m_bindingLocation, m_descriptorType, sizeof(T), &m_data);
    334 }
    335 
    336 template<typename T>
    337 class UniformArrayData : public UniformDataBase
    338 {
    339 public:
    340 							UniformArrayData	(deUint32 bindingLocation, VkDescriptorType descriptorType, const std::vector<T>& data);
    341 	virtual					~UniformArrayData	(void);
    342 	virtual void			setup				(ShaderExecutor& executor, const VkDevice& vkDevice, const DeviceInterface& vk, const VkQueue queue, const deUint32 queueFamilyIndex, Allocator& memAlloc) const;
    343 
    344 private:
    345 	VkDescriptorType		m_descriptorType;
    346 	std::vector<T>			m_data;
    347 };
    348 
    349 template<typename T>
    350 UniformArrayData<T>::UniformArrayData (deUint32 bindingLocation, VkDescriptorType descriptorType, const std::vector<T>& data)
    351 	: UniformDataBase		(bindingLocation)
    352 	, m_descriptorType		(descriptorType)
    353 	, m_data				(data)
    354 {
    355 }
    356 
    357 template<typename T>
    358 UniformArrayData<T>::~UniformArrayData (void)
    359 {
    360 }
    361 
    362 template<typename T>
    363 void UniformArrayData<T>::setup (ShaderExecutor& executor, const VkDevice& vkDevice, const DeviceInterface& vk, const VkQueue queue, const deUint32 queueFamilyIndex, Allocator& memAlloc) const
    364 {
    365 	DE_ASSERT(!m_data.empty());
    366 	executor.setupUniformArray(vkDevice, vk, queue, queueFamilyIndex, memAlloc, m_bindingLocation, m_descriptorType, (deUint32)m_data.size(), sizeof(T), &m_data[0]);
    367 }
    368 
    369 class SamplerUniformData : public UniformDataBase
    370 {
    371 public:
    372 							SamplerUniformData	(deUint32						bindingLocation,
    373 												 deUint32						numSamplers,
    374 												 const tcu::Sampler&			refSampler,
    375 												 const tcu::TextureFormat&		texFormat,
    376 												 const tcu::IVec3&				texSize,
    377 												 VkImageType					imageType,
    378 												 VkImageViewType				imageViewType,
    379 												 const void*					data);
    380 	virtual					~SamplerUniformData	(void);
    381 	virtual void			setup				(ShaderExecutor& executor, const VkDevice& vkDevice, const DeviceInterface& vk, const VkQueue queue, const deUint32 queueFamilyIndex, Allocator& memAlloc) const;
    382 
    383 private:
    384 	deUint32					m_numSamplers;
    385 	const tcu::Sampler			m_refSampler;
    386 	const tcu::TextureFormat	m_texFormat;
    387 	const tcu::IVec3			m_texSize;
    388 	VkImageType					m_imageType;
    389 	VkImageViewType				m_imageViewType;
    390 	const void*					m_data;
    391 };
    392 
    393 } // shaderexecutor
    394 } // vkt
    395 
    396 #endif // _VKTSHADEREXECUTOR_HPP
    397