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
56 private:
57 const ProgramFormat m_format;
58 const std::vector<deUint8> m_binary;
59 };
60
61 struct BinaryBuildOptions
62 {
63 };
64
65 template<typename Program, typename BuildOptions>
66 class ProgramCollection
67 {
68 public:
69 ProgramCollection (void);
70 ProgramCollection (const BuildOptions defaultBuildOptions);
71 ~ProgramCollection (void);
72
73 void clear (void);
74
75 Program& add (const std::string& name);
76 Program& add (const std::string& name, const BuildOptions* buildOptions);
77 void add (const std::string& name, de::MovePtr<Program>& program);
78
79 bool contains (const std::string& name) const;
80 const Program& get (const std::string& name) const;
81
82 class Iterator
83 {
84 private:
85 typedef typename std::map<std::string, Program*>::const_iterator IteratorImpl;
86
87 public:
Iterator(const IteratorImpl & i)88 explicit Iterator (const IteratorImpl& i) : m_impl(i) {}
89
operator ++(void)90 Iterator& operator++ (void) { ++m_impl; return *this; }
operator *(void) const91 const Program& operator* (void) const { return getProgram(); }
92
getName(void) const93 const std::string& getName (void) const { return m_impl->first; }
getProgram(void) const94 const Program& getProgram (void) const { return *m_impl->second; }
95
operator ==(const Iterator & other) const96 bool operator== (const Iterator& other) const { return m_impl == other.m_impl; }
operator !=(const Iterator & other) const97 bool operator!= (const Iterator& other) const { return m_impl != other.m_impl; }
98
99 private:
100
101 IteratorImpl m_impl;
102 };
103
begin(void) const104 Iterator begin (void) const { return Iterator(m_programs.begin()); }
end(void) const105 Iterator end (void) const { return Iterator(m_programs.end()); }
106
empty(void) const107 bool empty (void) const { return m_programs.empty(); }
108
109 private:
110 typedef std::map<std::string, Program*> ProgramMap;
111
112 ProgramMap m_programs;
113 BuildOptions m_defaultBuildOptions;
114 };
115
116 template<typename Program, typename BuildOptions>
ProgramCollection(void)117 ProgramCollection<Program, BuildOptions>::ProgramCollection (void)
118 {
119 }
120
121 template<typename Program, typename BuildOptions>
ProgramCollection(const BuildOptions defaultBuildOptions)122 ProgramCollection<Program, BuildOptions>::ProgramCollection (const BuildOptions defaultBuildOptions)
123 : m_programs()
124 , m_defaultBuildOptions(defaultBuildOptions)
125 {
126 }
127
128 template<typename Program, typename BuildOptions>
~ProgramCollection(void)129 ProgramCollection<Program, BuildOptions>::~ProgramCollection (void)
130 {
131 clear();
132 }
133
134 template<typename Program, typename BuildOptions>
clear(void)135 void ProgramCollection<Program, BuildOptions>::clear (void)
136 {
137 for (typename ProgramMap::const_iterator i = m_programs.begin(); i != m_programs.end(); ++i)
138 delete i->second;
139 m_programs.clear();
140 }
141
142 template<typename Program, typename BuildOptions>
add(const std::string & name)143 Program& ProgramCollection<Program, BuildOptions>::add (const std::string& name)
144 {
145 DE_ASSERT(!contains(name));
146 de::MovePtr<Program> prog = de::newMovePtr<Program>();
147 prog->buildOptions = m_defaultBuildOptions;
148 m_programs[name] = prog.get();
149 prog.release();
150 return *m_programs[name];
151 }
152
153 template<typename Program, typename BuildOptions>
add(const std::string & name,const BuildOptions * buildOptions)154 Program& ProgramCollection<Program, BuildOptions>::add (const std::string& name, const BuildOptions* buildOptions)
155 {
156 Program& program = add(name);
157
158 if (buildOptions != DE_NULL)
159 program << *buildOptions;
160
161 return program;
162 }
163
164 template<typename Program, typename BuildOptions>
add(const std::string & name,de::MovePtr<Program> & program)165 void ProgramCollection<Program, BuildOptions>::add (const std::string& name, de::MovePtr<Program>& program)
166 {
167 DE_ASSERT(!contains(name));
168 m_programs[name] = program.get();
169 program.release();
170 }
171
172 template<typename Program, typename BuildOptions>
contains(const std::string & name) const173 bool ProgramCollection<Program, BuildOptions>::contains (const std::string& name) const
174 {
175 return de::contains(m_programs, name);
176 }
177
178 template<typename Program, typename BuildOptions>
get(const std::string & name) const179 const Program& ProgramCollection<Program, BuildOptions>::get (const std::string& name) const
180 {
181 DE_ASSERT(contains(name));
182 return *m_programs.find(name)->second;
183 }
184
185 typedef ProgramCollection<GlslSource, ShaderBuildOptions> GlslSourceCollection;
186 typedef ProgramCollection<HlslSource, ShaderBuildOptions> HlslSourceCollection;
187 typedef ProgramCollection<SpirVAsmSource, SpirVAsmBuildOptions> SpirVAsmCollection;
188
189 struct SourceCollections
190 {
SourceCollectionsvk::SourceCollections191 SourceCollections (const deUint32 usedVulkanVersion_,
192 const ShaderBuildOptions& glslBuildOptions,
193 const ShaderBuildOptions& hlslBuildOptions,
194 const SpirVAsmBuildOptions& spirVAsmBuildOptions)
195 : usedVulkanVersion(usedVulkanVersion_)
196 , glslSources(glslBuildOptions)
197 , hlslSources(hlslBuildOptions)
198 , spirvAsmSources(spirVAsmBuildOptions)
199 {
200 }
201
202 deUint32 usedVulkanVersion;
203 GlslSourceCollection glslSources;
204 HlslSourceCollection hlslSources;
205 SpirVAsmCollection spirvAsmSources;
206 };
207
208 typedef ProgramCollection<ProgramBinary, BinaryBuildOptions> BinaryCollection;
209
210 ProgramBinary* buildProgram (const GlslSource& program, glu::ShaderProgramInfo* buildInfo);
211 ProgramBinary* buildProgram (const HlslSource& program, glu::ShaderProgramInfo* buildInfo);
212 ProgramBinary* assembleProgram (const vk::SpirVAsmSource& program, SpirVProgramInfo* buildInfo);
213 void disassembleProgram (const ProgramBinary& program, std::ostream* dst);
214 bool validateProgram (const ProgramBinary& program, std::ostream* dst);
215
216 Move<VkShaderModule> createShaderModule (const DeviceInterface& deviceInterface, VkDevice device, const ProgramBinary& binary, VkShaderModuleCreateFlags flags);
217
218 glu::ShaderType getGluShaderType (VkShaderStageFlagBits shaderStage);
219 VkShaderStageFlagBits getVkShaderStage (glu::ShaderType shaderType);
220
221 vk::SpirvVersion getMaxSpirvVersionForAsm (const deUint32 vulkanVersion);
222 vk::SpirvVersion getMaxSpirvVersionForGlsl (const deUint32 vulkanVersion);
223 vk::SpirvVersion getBaselineSpirvVersion (const deUint32 vulkanVersion);
224 SpirvVersion extractSpirvVersion (const ProgramBinary& binary);
225 std::string getSpirvVersionName (const SpirvVersion spirvVersion);
226 SpirvVersion& operator++ (SpirvVersion& spirvVersion);
227
228 } // vk
229
230 #endif // _VKPROGRAMS_HPP
231