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 void clear (void);
78
79 Program& add (const std::string& name);
80 Program& add (const std::string& name, const BuildOptions* buildOptions);
81 void add (const std::string& name, de::MovePtr<Program>& program);
82
83 bool contains (const std::string& name) const;
84 const Program& get (const std::string& name) const;
85
86 class Iterator
87 {
88 private:
89 typedef typename std::map<std::string, Program*>::const_iterator IteratorImpl;
90
91 public:
Iterator(const IteratorImpl & i)92 explicit Iterator (const IteratorImpl& i) : m_impl(i) {}
93
operator ++(void)94 Iterator& operator++ (void) { ++m_impl; return *this; }
operator *(void) const95 const Program& operator* (void) const { return getProgram(); }
96
getName(void) const97 const std::string& getName (void) const { return m_impl->first; }
getProgram(void) const98 const Program& getProgram (void) const { return *m_impl->second; }
99
operator ==(const Iterator & other) const100 bool operator== (const Iterator& other) const { return m_impl == other.m_impl; }
operator !=(const Iterator & other) const101 bool operator!= (const Iterator& other) const { return m_impl != other.m_impl; }
102
103 private:
104
105 IteratorImpl m_impl;
106 };
107
begin(void) const108 Iterator begin (void) const { return Iterator(m_programs.begin()); }
end(void) const109 Iterator end (void) const { return Iterator(m_programs.end()); }
110
empty(void) const111 bool empty (void) const { return m_programs.empty(); }
112
113 private:
114 typedef std::map<std::string, Program*> ProgramMap;
115
116 ProgramMap m_programs;
117 BuildOptions m_defaultBuildOptions;
118 };
119
120 template<typename Program, typename BuildOptions>
ProgramCollection(void)121 ProgramCollection<Program, BuildOptions>::ProgramCollection (void)
122 {
123 }
124
125 template<typename Program, typename BuildOptions>
ProgramCollection(const BuildOptions defaultBuildOptions)126 ProgramCollection<Program, BuildOptions>::ProgramCollection (const BuildOptions defaultBuildOptions)
127 : m_programs()
128 , m_defaultBuildOptions(defaultBuildOptions)
129 {
130 }
131
132 template<typename Program, typename BuildOptions>
~ProgramCollection(void)133 ProgramCollection<Program, BuildOptions>::~ProgramCollection (void)
134 {
135 clear();
136 }
137
138 template<typename Program, typename BuildOptions>
clear(void)139 void ProgramCollection<Program, BuildOptions>::clear (void)
140 {
141 for (typename ProgramMap::const_iterator i = m_programs.begin(); i != m_programs.end(); ++i)
142 delete i->second;
143 m_programs.clear();
144 }
145
146 template<typename Program, typename BuildOptions>
add(const std::string & name)147 Program& ProgramCollection<Program, BuildOptions>::add (const std::string& name)
148 {
149 DE_ASSERT(!contains(name));
150 de::MovePtr<Program> prog = de::newMovePtr<Program>();
151 prog->buildOptions = m_defaultBuildOptions;
152 m_programs[name] = prog.get();
153 prog.release();
154 return *m_programs[name];
155 }
156
157 template<typename Program, typename BuildOptions>
add(const std::string & name,const BuildOptions * buildOptions)158 Program& ProgramCollection<Program, BuildOptions>::add (const std::string& name, const BuildOptions* buildOptions)
159 {
160 Program& program = add(name);
161
162 if (buildOptions != DE_NULL)
163 program << *buildOptions;
164
165 return program;
166 }
167
168 template<typename Program, typename BuildOptions>
add(const std::string & name,de::MovePtr<Program> & program)169 void ProgramCollection<Program, BuildOptions>::add (const std::string& name, de::MovePtr<Program>& program)
170 {
171 DE_ASSERT(!contains(name));
172 m_programs[name] = program.get();
173 program.release();
174 }
175
176 template<typename Program, typename BuildOptions>
contains(const std::string & name) const177 bool ProgramCollection<Program, BuildOptions>::contains (const std::string& name) const
178 {
179 return de::contains(m_programs, name);
180 }
181
182 template<typename Program, typename BuildOptions>
get(const std::string & name) const183 const Program& ProgramCollection<Program, BuildOptions>::get (const std::string& name) const
184 {
185 DE_ASSERT(contains(name));
186 return *m_programs.find(name)->second;
187 }
188
189 typedef ProgramCollection<GlslSource, ShaderBuildOptions> GlslSourceCollection;
190 typedef ProgramCollection<HlslSource, ShaderBuildOptions> HlslSourceCollection;
191 typedef ProgramCollection<SpirVAsmSource, SpirVAsmBuildOptions> SpirVAsmCollection;
192
193 struct SourceCollections
194 {
SourceCollectionsvk::SourceCollections195 SourceCollections (const deUint32 usedVulkanVersion_,
196 const ShaderBuildOptions& glslBuildOptions,
197 const ShaderBuildOptions& hlslBuildOptions,
198 const SpirVAsmBuildOptions& spirVAsmBuildOptions)
199 : usedVulkanVersion(usedVulkanVersion_)
200 , glslSources(glslBuildOptions)
201 , hlslSources(hlslBuildOptions)
202 , spirvAsmSources(spirVAsmBuildOptions)
203 {
204 }
205
206 deUint32 usedVulkanVersion;
207 GlslSourceCollection glslSources;
208 HlslSourceCollection hlslSources;
209 SpirVAsmCollection spirvAsmSources;
210 };
211
212 typedef ProgramCollection<ProgramBinary, BinaryBuildOptions> BinaryCollection;
213
214 ProgramBinary* buildProgram (const GlslSource& program, glu::ShaderProgramInfo* buildInfo, const tcu::CommandLine& commandLine);
215 ProgramBinary* buildProgram (const HlslSource& program, glu::ShaderProgramInfo* buildInfo, const tcu::CommandLine& commandLine);
216 ProgramBinary* assembleProgram (const vk::SpirVAsmSource& program, SpirVProgramInfo* buildInfo, const tcu::CommandLine& commandLine);
217 void disassembleProgram (const ProgramBinary& program, std::ostream* dst);
218 bool validateProgram (const ProgramBinary& program, std::ostream* dst, const SpirvValidatorOptions&);
219
220 Move<VkShaderModule> createShaderModule (const DeviceInterface& deviceInterface, VkDevice device, const ProgramBinary& binary, VkShaderModuleCreateFlags flags);
221
222 glu::ShaderType getGluShaderType (VkShaderStageFlagBits shaderStage);
223 VkShaderStageFlagBits getVkShaderStage (glu::ShaderType shaderType);
224
225 // Returns the max SPIR-V version usable with a given Vulkan version, without requiring an extension.
226 vk::SpirvVersion getMaxSpirvVersionForVulkan (const deUint32 vulkanVersion);
227 // Deprecated. Use getMaxSpirvVersionForVulkan instead.
228 vk::SpirvVersion getMaxSpirvVersionForAsm (const deUint32 vulkanVersion);
229 // Deprecated. Use getMaxSpirvVersionForVulkan instead.
230 vk::SpirvVersion getMaxSpirvVersionForGlsl (const deUint32 vulkanVersion);
231 vk::SpirvVersion getBaselineSpirvVersion (const deUint32 vulkanVersion);
232 SpirvVersion extractSpirvVersion (const ProgramBinary& binary);
233 std::string getSpirvVersionName (const SpirvVersion spirvVersion);
234 SpirvVersion& operator++ (SpirvVersion& spirvVersion);
235
236 } // vk
237
238 #endif // _VKPROGRAMS_HPP
239