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 "vkShaderProgram.hpp"
30
31 #include "deUniquePtr.hpp"
32 #include "deSTLUtil.hpp"
33
34 #include <vector>
35 #include <map>
36
37 namespace vk
38 {
39
40 enum ProgramFormat
41 {
42 PROGRAM_FORMAT_SPIRV = 0,
43
44 PROGRAM_FORMAT_LAST
45 };
46
47 class ProgramBinary
48 {
49 public:
50 ProgramBinary(ProgramFormat format, size_t binarySize, const uint8_t *binary);
51
getFormat(void) const52 ProgramFormat getFormat(void) const
53 {
54 return m_format;
55 }
getSize(void) const56 size_t getSize(void) const
57 {
58 return m_binary.size();
59 }
getBinary(void) const60 const uint8_t *getBinary(void) const
61 {
62 return m_binary.empty() ? DE_NULL : &m_binary[0];
63 }
64
setUsed(void) const65 inline void setUsed(void) const
66 {
67 m_used = true;
68 }
getUsed(void) const69 inline bool getUsed(void) const
70 {
71 return m_used;
72 }
73
74 private:
75 const ProgramFormat m_format;
76 const std::vector<uint8_t> m_binary;
77 mutable bool m_used;
78 };
79
80 struct BinaryBuildOptions
81 {
82 };
83
84 template <typename Program, typename BuildOptions>
85 class ProgramCollection
86 {
87 public:
88 ProgramCollection(void);
89 ProgramCollection(const BuildOptions defaultBuildOptions);
90 ~ProgramCollection(void);
91
92 // Forbid copy and assignment.
93 ProgramCollection(const ProgramCollection<Program, BuildOptions> &other) = delete;
94 ProgramCollection<Program, BuildOptions> &operator=(const ProgramCollection<Program, BuildOptions> &other) = delete;
95
96 void clear(void);
97
98 Program &add(const std::string &name);
99 Program &add(const std::string &name, const BuildOptions *buildOptions);
100 void add(const std::string &name, de::MovePtr<Program> &program);
101
102 bool contains(const std::string &name) const;
103 const Program &get(const std::string &name) const;
104
105 class Iterator
106 {
107 private:
108 typedef typename std::map<std::string, Program *>::const_iterator IteratorImpl;
109
110 public:
Iterator(const IteratorImpl & i)111 explicit Iterator(const IteratorImpl &i) : m_impl(i)
112 {
113 }
114
operator ++(void)115 Iterator &operator++(void)
116 {
117 ++m_impl;
118 return *this;
119 }
operator *(void) const120 const Program &operator*(void) const
121 {
122 return getProgram();
123 }
124
getName(void) const125 const std::string &getName(void) const
126 {
127 return m_impl->first;
128 }
getProgram(void) const129 const Program &getProgram(void) const
130 {
131 return *m_impl->second;
132 }
133
operator ==(const Iterator & other) const134 bool operator==(const Iterator &other) const
135 {
136 return m_impl == other.m_impl;
137 }
operator !=(const Iterator & other) const138 bool operator!=(const Iterator &other) const
139 {
140 return m_impl != other.m_impl;
141 }
142
143 private:
144 IteratorImpl m_impl;
145 };
146
begin(void) const147 Iterator begin(void) const
148 {
149 return Iterator(m_programs.begin());
150 }
end(void) const151 Iterator end(void) const
152 {
153 return Iterator(m_programs.end());
154 }
155
empty(void) const156 bool empty(void) const
157 {
158 return m_programs.empty();
159 }
160
161 private:
162 typedef std::map<std::string, Program *> ProgramMap;
163
164 ProgramMap m_programs;
165 BuildOptions m_defaultBuildOptions;
166 };
167
168 template <typename Program, typename BuildOptions>
ProgramCollection(void)169 ProgramCollection<Program, BuildOptions>::ProgramCollection(void)
170 {
171 }
172
173 template <typename Program, typename BuildOptions>
ProgramCollection(const BuildOptions defaultBuildOptions)174 ProgramCollection<Program, BuildOptions>::ProgramCollection(const BuildOptions defaultBuildOptions)
175 : m_programs()
176 , m_defaultBuildOptions(defaultBuildOptions)
177 {
178 }
179
180 template <typename Program, typename BuildOptions>
~ProgramCollection(void)181 ProgramCollection<Program, BuildOptions>::~ProgramCollection(void)
182 {
183 clear();
184 }
185
186 template <typename Program, typename BuildOptions>
clear(void)187 void ProgramCollection<Program, BuildOptions>::clear(void)
188 {
189 for (typename ProgramMap::const_iterator i = m_programs.begin(); i != m_programs.end(); ++i)
190 delete i->second;
191 m_programs.clear();
192 }
193
194 template <typename Program, typename BuildOptions>
add(const std::string & name)195 Program &ProgramCollection<Program, BuildOptions>::add(const std::string &name)
196 {
197 DE_ASSERT(!contains(name));
198 de::MovePtr<Program> prog = de::newMovePtr<Program>();
199 prog->buildOptions = m_defaultBuildOptions;
200 m_programs[name] = prog.get();
201 prog.release();
202 return *m_programs[name];
203 }
204
205 template <typename Program, typename BuildOptions>
add(const std::string & name,const BuildOptions * buildOptions)206 Program &ProgramCollection<Program, BuildOptions>::add(const std::string &name, const BuildOptions *buildOptions)
207 {
208 Program &program = add(name);
209
210 if (buildOptions != DE_NULL)
211 program << *buildOptions;
212
213 return program;
214 }
215
216 template <typename Program, typename BuildOptions>
add(const std::string & name,de::MovePtr<Program> & program)217 void ProgramCollection<Program, BuildOptions>::add(const std::string &name, de::MovePtr<Program> &program)
218 {
219 DE_ASSERT(!contains(name));
220 m_programs[name] = program.get();
221 program.release();
222 }
223
224 template <typename Program, typename BuildOptions>
contains(const std::string & name) const225 bool ProgramCollection<Program, BuildOptions>::contains(const std::string &name) const
226 {
227 return de::contains(m_programs, name);
228 }
229
230 template <typename Program, typename BuildOptions>
get(const std::string & name) const231 const Program &ProgramCollection<Program, BuildOptions>::get(const std::string &name) const
232 {
233 DE_ASSERT(contains(name));
234 return *m_programs.find(name)->second;
235 }
236
237 typedef ProgramCollection<GlslSource, ShaderBuildOptions> GlslSourceCollection;
238 typedef ProgramCollection<HlslSource, ShaderBuildOptions> HlslSourceCollection;
239 typedef ProgramCollection<SpirVAsmSource, SpirVAsmBuildOptions> SpirVAsmCollection;
240
241 struct SourceCollections
242 {
SourceCollectionsvk::SourceCollections243 SourceCollections(const uint32_t usedVulkanVersion_, const ShaderBuildOptions &glslBuildOptions,
244 const ShaderBuildOptions &hlslBuildOptions, const SpirVAsmBuildOptions &spirVAsmBuildOptions)
245 : usedVulkanVersion(usedVulkanVersion_)
246 , glslSources(glslBuildOptions)
247 , hlslSources(hlslBuildOptions)
248 , spirvAsmSources(spirVAsmBuildOptions)
249 {
250 }
251
252 uint32_t usedVulkanVersion;
253 GlslSourceCollection glslSources;
254 HlslSourceCollection hlslSources;
255 SpirVAsmCollection spirvAsmSources;
256 };
257
258 typedef ProgramCollection<ProgramBinary, BinaryBuildOptions> BinaryCollection;
259
260 ProgramBinary *buildProgram(const GlslSource &program, glu::ShaderProgramInfo *buildInfo,
261 const tcu::CommandLine &commandLine);
262 ProgramBinary *buildProgram(const HlslSource &program, glu::ShaderProgramInfo *buildInfo,
263 const tcu::CommandLine &commandLine);
264 ProgramBinary *assembleProgram(const vk::SpirVAsmSource &program, SpirVProgramInfo *buildInfo,
265 const tcu::CommandLine &commandLine);
266 void disassembleProgram(const ProgramBinary &program, std::ostream *dst);
267 bool validateProgram(const ProgramBinary &program, std::ostream *dst, const SpirvValidatorOptions &);
268
269 #ifdef CTS_USES_VULKANSC
270 typedef uint32_t VkShaderModuleCreateFlags;
271 #endif // CTS_USES_VULKANSC
272
273 Move<VkShaderModule> createShaderModule(const DeviceInterface &deviceInterface, VkDevice device,
274 const ProgramBinary &binary, VkShaderModuleCreateFlags flags = 0u);
275
276 glu::ShaderType getGluShaderType(VkShaderStageFlagBits shaderStage);
277 VkShaderStageFlagBits getVkShaderStage(glu::ShaderType shaderType);
278
279 // Returns the max SPIR-V version usable with a given Vulkan version, without requiring an extension.
280 vk::SpirvVersion getMaxSpirvVersionForVulkan(const uint32_t vulkanVersion);
281 // Deprecated. Use getMaxSpirvVersionForVulkan instead.
282 vk::SpirvVersion getMaxSpirvVersionForAsm(const uint32_t vulkanVersion);
283 // Deprecated. Use getMaxSpirvVersionForVulkan instead.
284 vk::SpirvVersion getMaxSpirvVersionForGlsl(const uint32_t vulkanVersion);
285 vk::SpirvVersion getBaselineSpirvVersion(const uint32_t vulkanVersion);
286 SpirvVersion extractSpirvVersion(const ProgramBinary &binary);
287 std::string getSpirvVersionName(const SpirvVersion spirvVersion);
288 SpirvVersion &operator++(SpirvVersion &spirvVersion);
289
290 } // namespace vk
291
292 #endif // _VKPROGRAMS_HPP
293