1#ifndef _VKPROGRAMS_HPP
2#define _VKPROGRAMS_HPP
3/*-------------------------------------------------------------------------
4 * Vulkan CTS Framework
5 * --------------------
6 *
7 * Copyright (c) 2015 Google Inc.
8 *
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
12 *
13 *      http://www.apache.org/licenses/LICENSE-2.0
14 *
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.
20 *
21 *//*!
22 * \file
23 * \brief Program utilities.
24 *//*--------------------------------------------------------------------*/
25
26#include "vkDefs.hpp"
27#include "vkRef.hpp"
28#include "vkSpirVProgram.hpp"
29#include "gluShaderProgram.hpp"
30#include "deUniquePtr.hpp"
31#include "deSTLUtil.hpp"
32
33#include <vector>
34#include <map>
35
36namespace tcu
37{
38class TestLog;
39} // tcu
40
41namespace vk
42{
43
44enum ProgramFormat
45{
46	PROGRAM_FORMAT_SPIRV = 0,
47
48	PROGRAM_FORMAT_LAST
49};
50
51class ProgramBinary
52{
53public:
54								ProgramBinary	(ProgramFormat format, size_t binarySize, const deUint8* binary);
55
56	ProgramFormat				getFormat		(void) const { return m_format;										}
57	size_t						getSize			(void) const { return m_binary.size();								}
58	const deUint8*				getBinary		(void) const { return m_binary.empty() ? DE_NULL : &m_binary[0];	}
59
60private:
61	const ProgramFormat			m_format;
62	const std::vector<deUint8>	m_binary;
63};
64
65template<typename Program>
66class ProgramCollection
67{
68public:
69								ProgramCollection	(void);
70								~ProgramCollection	(void);
71
72	void						clear				(void);
73
74	Program&					add					(const std::string& name);
75	void						add					(const std::string& name, de::MovePtr<Program>& program);
76
77	bool						contains			(const std::string& name) const;
78	const Program&				get					(const std::string& name) const;
79
80	class Iterator
81	{
82	private:
83		typedef typename std::map<std::string, Program*>::const_iterator	IteratorImpl;
84
85	public:
86		explicit			Iterator	(const IteratorImpl& i) : m_impl(i) {}
87
88		Iterator&			operator++	(void)			{ ++m_impl; return *this;	}
89		const Program&		operator*	(void) const	{ return getProgram();		}
90
91		const std::string&	getName		(void) const	{ return m_impl->first;		}
92		const Program&		getProgram	(void) const	{ return *m_impl->second;	}
93
94		bool				operator==	(const Iterator& other) const	{ return m_impl == other.m_impl;	}
95		bool				operator!=	(const Iterator& other) const	{ return m_impl != other.m_impl;	}
96
97	private:
98
99		IteratorImpl	m_impl;
100	};
101
102	Iterator					begin				(void) const { return Iterator(m_programs.begin());	}
103	Iterator					end					(void) const { return Iterator(m_programs.end());	}
104
105private:
106	typedef std::map<std::string, Program*>	ProgramMap;
107
108	ProgramMap					m_programs;
109};
110
111template<typename Program>
112ProgramCollection<Program>::ProgramCollection (void)
113{
114}
115
116template<typename Program>
117ProgramCollection<Program>::~ProgramCollection (void)
118{
119	clear();
120}
121
122template<typename Program>
123void ProgramCollection<Program>::clear (void)
124{
125	for (typename ProgramMap::const_iterator i = m_programs.begin(); i != m_programs.end(); ++i)
126		delete i->second;
127	m_programs.clear();
128}
129
130template<typename Program>
131Program& ProgramCollection<Program>::add (const std::string& name)
132{
133	DE_ASSERT(!contains(name));
134	de::MovePtr<Program> prog = de::newMovePtr<Program>();
135	m_programs[name] = prog.get();
136	prog.release();
137	return *m_programs[name];
138}
139
140template<typename Program>
141void ProgramCollection<Program>::add (const std::string& name, de::MovePtr<Program>& program)
142{
143	DE_ASSERT(!contains(name));
144	m_programs[name] = program.get();
145	program.release();
146}
147
148template<typename Program>
149bool ProgramCollection<Program>::contains (const std::string& name) const
150{
151	return de::contains(m_programs, name);
152}
153
154template<typename Program>
155const Program& ProgramCollection<Program>::get (const std::string& name) const
156{
157	DE_ASSERT(contains(name));
158	return *m_programs.find(name)->second;
159}
160
161typedef vk::ProgramCollection<glu::ProgramSources>	GlslSourceCollection;
162typedef vk::ProgramCollection<vk::SpirVAsmSource>	SpirVAsmCollection;
163
164struct SourceCollections
165{
166	GlslSourceCollection	glslSources;
167	SpirVAsmCollection		spirvAsmSources;
168};
169
170typedef ProgramCollection<ProgramBinary>		BinaryCollection;
171
172ProgramBinary*			buildProgram		(const glu::ProgramSources& program, ProgramFormat binaryFormat, glu::ShaderProgramInfo* buildInfo);
173ProgramBinary*			assembleProgram		(const vk::SpirVAsmSource& program, SpirVProgramInfo* buildInfo);
174void					disassembleProgram	(const ProgramBinary& program, std::ostream* dst);
175bool					validateProgram		(const ProgramBinary& program, std::ostream* dst);
176
177Move<VkShaderModule>	createShaderModule	(const DeviceInterface& deviceInterface, VkDevice device, const ProgramBinary& binary, VkShaderModuleCreateFlags flags);
178
179glu::ShaderType			getGluShaderType	(VkShaderStageFlagBits shaderStage);
180VkShaderStageFlagBits	getVkShaderStage	(glu::ShaderType shaderType);
181
182} // vk
183
184#endif // _VKPROGRAMS_HPP
185