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 deUint8* binary);
51
getFormat(void) const52 ProgramFormat getFormat (void) const { return m_format; }
getSize(void) const53 size_t getSize (void) const { return m_binary.size(); }
getBinary(void) const54 const deUint8* getBinary (void) const { return m_binary.empty() ? DE_NULL : &m_binary[0]; }
55
setUsed(void) const56 inline void setUsed (void) const { m_used = true; }
getUsed(void) const57 inline bool getUsed (void) const { return m_used; }
58
59 private:
60 const ProgramFormat m_format;
61 const std::vector<deUint8> m_binary;
62 mutable bool m_used;
63 };
64
65 struct BinaryBuildOptions
66 {
67 };
68
69 template<typename Program, typename BuildOptions>
70 class ProgramCollection
71 {
72 public:
73 ProgramCollection (void);
74 ProgramCollection (const BuildOptions defaultBuildOptions);
75 ~ProgramCollection (void);
76
77 // Forbid copy and assignment.
78 ProgramCollection (const ProgramCollection<Program, BuildOptions>& other) = delete;
79 ProgramCollection<Program, BuildOptions>& operator=(const ProgramCollection<Program, BuildOptions>& other) = delete;
80
81 void clear (void);
82
83 Program& add (const std::string& name);
84 Program& add (const std::string& name, const BuildOptions* buildOptions);
85 void add (const std::string& name, de::MovePtr<Program>& program);
86
87 bool contains (const std::string& name) const;
88 const Program& get (const std::string& name) const;
89
90 class Iterator
91 {
92 private:
93 typedef typename std::map<std::string, Program*>::const_iterator IteratorImpl;
94
95 public:
Iterator(const IteratorImpl & i)96 explicit Iterator (const IteratorImpl& i) : m_impl(i) {}
97
operator ++(void)98 Iterator& operator++ (void) { ++m_impl; return *this; }
operator *(void) const99 const Program& operator* (void) const { return getProgram(); }
100
getName(void) const101 const std::string& getName (void) const { return m_impl->first; }
getProgram(void) const102 const Program& getProgram (void) const { return *m_impl->second; }
103
operator ==(const Iterator & other) const104 bool operator== (const Iterator& other) const { return m_impl == other.m_impl; }
operator !=(const Iterator & other) const105 bool operator!= (const Iterator& other) const { return m_impl != other.m_impl; }
106
107 private:
108
109 IteratorImpl m_impl;
110 };
111
begin(void) const112 Iterator begin (void) const { return Iterator(m_programs.begin()); }
end(void) const113 Iterator end (void) const { return Iterator(m_programs.end()); }
114
empty(void) const115 bool empty (void) const { return m_programs.empty(); }
116
117 private:
118 typedef std::map<std::string, Program*> ProgramMap;
119
120 ProgramMap m_programs;
121 BuildOptions m_defaultBuildOptions;
122 };
123
124 template<typename Program, typename BuildOptions>
ProgramCollection(void)125 ProgramCollection<Program, BuildOptions>::ProgramCollection (void)
126 {
127 }
128
129 template<typename Program, typename BuildOptions>
ProgramCollection(const BuildOptions defaultBuildOptions)130 ProgramCollection<Program, BuildOptions>::ProgramCollection (const BuildOptions defaultBuildOptions)
131 : m_programs()
132 , m_defaultBuildOptions(defaultBuildOptions)
133 {
134 }
135
136 template<typename Program, typename BuildOptions>
~ProgramCollection(void)137 ProgramCollection<Program, BuildOptions>::~ProgramCollection (void)
138 {
139 clear();
140 }
141
142 template<typename Program, typename BuildOptions>
clear(void)143 void ProgramCollection<Program, BuildOptions>::clear (void)
144 {
145 for (typename ProgramMap::const_iterator i = m_programs.begin(); i != m_programs.end(); ++i)
146 delete i->second;
147 m_programs.clear();
148 }
149
150 template<typename Program, typename BuildOptions>
add(const std::string & name)151 Program& ProgramCollection<Program, BuildOptions>::add (const std::string& name)
152 {
153 DE_ASSERT(!contains(name));
154 de::MovePtr<Program> prog = de::newMovePtr<Program>();
155 prog->buildOptions = m_defaultBuildOptions;
156 m_programs[name] = prog.get();
157 prog.release();
158 return *m_programs[name];
159 }
160
161 template<typename Program, typename BuildOptions>
add(const std::string & name,const BuildOptions * buildOptions)162 Program& ProgramCollection<Program, BuildOptions>::add (const std::string& name, const BuildOptions* buildOptions)
163 {
164 Program& program = add(name);
165
166 if (buildOptions != DE_NULL)
167 program << *buildOptions;
168
169 return program;
170 }
171
172 template<typename Program, typename BuildOptions>
add(const std::string & name,de::MovePtr<Program> & program)173 void ProgramCollection<Program, BuildOptions>::add (const std::string& name, de::MovePtr<Program>& program)
174 {
175 DE_ASSERT(!contains(name));
176 m_programs[name] = program.get();
177 program.release();
178 }
179
180 template<typename Program, typename BuildOptions>
contains(const std::string & name) const181 bool ProgramCollection<Program, BuildOptions>::contains (const std::string& name) const
182 {
183 return de::contains(m_programs, name);
184 }
185
186 template<typename Program, typename BuildOptions>
get(const std::string & name) const187 const Program& ProgramCollection<Program, BuildOptions>::get (const std::string& name) const
188 {
189 DE_ASSERT(contains(name));
190 return *m_programs.find(name)->second;
191 }
192
193 typedef ProgramCollection<GlslSource, ShaderBuildOptions> GlslSourceCollection;
194 typedef ProgramCollection<HlslSource, ShaderBuildOptions> HlslSourceCollection;
195 typedef ProgramCollection<SpirVAsmSource, SpirVAsmBuildOptions> SpirVAsmCollection;
196
197 struct SourceCollections
198 {
SourceCollectionsvk::SourceCollections199 SourceCollections (const deUint32 usedVulkanVersion_,
200 const ShaderBuildOptions& glslBuildOptions,
201 const ShaderBuildOptions& hlslBuildOptions,
202 const SpirVAsmBuildOptions& spirVAsmBuildOptions)
203 : usedVulkanVersion(usedVulkanVersion_)
204 , glslSources(glslBuildOptions)
205 , hlslSources(hlslBuildOptions)
206 , spirvAsmSources(spirVAsmBuildOptions)
207 {
208 }
209
210 deUint32 usedVulkanVersion;
211 GlslSourceCollection glslSources;
212 HlslSourceCollection hlslSources;
213 SpirVAsmCollection spirvAsmSources;
214 };
215
216 typedef ProgramCollection<ProgramBinary, BinaryBuildOptions> BinaryCollection;
217
218 ProgramBinary* buildProgram (const GlslSource& program, glu::ShaderProgramInfo* buildInfo, const tcu::CommandLine& commandLine);
219 ProgramBinary* buildProgram (const HlslSource& program, glu::ShaderProgramInfo* buildInfo, const tcu::CommandLine& commandLine);
220 ProgramBinary* assembleProgram (const vk::SpirVAsmSource& program, SpirVProgramInfo* buildInfo, const tcu::CommandLine& commandLine);
221 void disassembleProgram (const ProgramBinary& program, std::ostream* dst);
222 bool validateProgram (const ProgramBinary& program, std::ostream* dst, const SpirvValidatorOptions&);
223
224 #ifdef CTS_USES_VULKANSC
225 typedef deUint32 VkShaderModuleCreateFlags;
226 #endif // CTS_USES_VULKANSC
227
228 Move<VkShaderModule> createShaderModule (const DeviceInterface& deviceInterface, VkDevice device, const ProgramBinary& binary, VkShaderModuleCreateFlags flags = 0u);
229
230 glu::ShaderType getGluShaderType (VkShaderStageFlagBits shaderStage);
231 VkShaderStageFlagBits getVkShaderStage (glu::ShaderType shaderType);
232
233 // Returns the max SPIR-V version usable with a given Vulkan version, without requiring an extension.
234 vk::SpirvVersion getMaxSpirvVersionForVulkan (const deUint32 vulkanVersion);
235 // Deprecated. Use getMaxSpirvVersionForVulkan instead.
236 vk::SpirvVersion getMaxSpirvVersionForAsm (const deUint32 vulkanVersion);
237 // Deprecated. Use getMaxSpirvVersionForVulkan instead.
238 vk::SpirvVersion getMaxSpirvVersionForGlsl (const deUint32 vulkanVersion);
239 vk::SpirvVersion getBaselineSpirvVersion (const deUint32 vulkanVersion);
240 SpirvVersion extractSpirvVersion (const ProgramBinary& binary);
241 std::string getSpirvVersionName (const SpirvVersion spirvVersion);
242 SpirvVersion& operator++ (SpirvVersion& spirvVersion);
243
244 } // vk
245
246 #endif // _VKPROGRAMS_HPP
247