1 // Copyright 2018 The Amber Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef SRC_SCRIPT_H_ 16 #define SRC_SCRIPT_H_ 17 18 #include <cstdint> 19 #include <map> 20 #include <memory> 21 #include <string> 22 #include <utility> 23 #include <vector> 24 25 #include "amber/recipe.h" 26 #include "amber/result.h" 27 #include "src/buffer.h" 28 #include "src/command.h" 29 #include "src/engine.h" 30 #include "src/format.h" 31 #include "src/pipeline.h" 32 #include "src/shader.h" 33 34 namespace amber { 35 36 /// Class representing the script to be run against an engine. 37 class Script : public RecipeImpl { 38 public: 39 Script(); 40 ~Script() override; 41 42 bool IsKnownFeature(const std::string& name) const; 43 44 /// Retrieves information on the shaders in the given script. 45 std::vector<ShaderInfo> GetShaderInfo() const override; 46 47 /// Returns required features in the given recipe. GetRequiredFeatures()48 std::vector<std::string> GetRequiredFeatures() const override { 49 return engine_info_.required_features; 50 } 51 52 /// Returns required device extensions in the given recipe. GetRequiredDeviceExtensions()53 std::vector<std::string> GetRequiredDeviceExtensions() const override { 54 return engine_info_.required_device_extensions; 55 } 56 57 /// Returns required instance extensions in the given recipe. GetRequiredInstanceExtensions()58 std::vector<std::string> GetRequiredInstanceExtensions() const override { 59 return engine_info_.required_instance_extensions; 60 } 61 62 /// Sets the fence timeout to |timeout_ms|. SetFenceTimeout(uint32_t timeout_ms)63 void SetFenceTimeout(uint32_t timeout_ms) override { 64 engine_data_.fence_timeout_ms = timeout_ms; 65 } 66 67 /// Adds |pipeline| to the list of known pipelines. The |pipeline| must have 68 /// a unique name over all pipelines in the script. AddPipeline(std::unique_ptr<Pipeline> pipeline)69 Result AddPipeline(std::unique_ptr<Pipeline> pipeline) { 70 if (name_to_pipeline_.count(pipeline->GetName()) > 0) 71 return Result("duplicate pipeline name provided"); 72 73 pipelines_.push_back(std::move(pipeline)); 74 name_to_pipeline_[pipelines_.back()->GetName()] = pipelines_.back().get(); 75 return {}; 76 } 77 78 /// Retrieves the pipeline with |name|, |nullptr| if not found. GetPipeline(const std::string & name)79 Pipeline* GetPipeline(const std::string& name) const { 80 auto it = name_to_pipeline_.find(name); 81 return it == name_to_pipeline_.end() ? nullptr : it->second; 82 } 83 84 /// Retrieves a list of all pipelines. GetPipelines()85 const std::vector<std::unique_ptr<Pipeline>>& GetPipelines() const { 86 return pipelines_; 87 } 88 89 /// Adds |shader| to the list of known shaders. The |shader| must have a 90 /// unique name over all shaders in the script. AddShader(std::unique_ptr<Shader> shader)91 Result AddShader(std::unique_ptr<Shader> shader) { 92 if (name_to_shader_.count(shader->GetName()) > 0) 93 return Result("duplicate shader name provided"); 94 95 shaders_.push_back(std::move(shader)); 96 name_to_shader_[shaders_.back()->GetName()] = shaders_.back().get(); 97 return {}; 98 } 99 100 /// Retrieves the shader with |name|, |nullptr| if not found. GetShader(const std::string & name)101 Shader* GetShader(const std::string& name) const { 102 auto it = name_to_shader_.find(name); 103 return it == name_to_shader_.end() ? nullptr : it->second; 104 } 105 106 /// Retrieves a list of all shaders. GetShaders()107 const std::vector<std::unique_ptr<Shader>>& GetShaders() const { 108 return shaders_; 109 } 110 111 /// Adds |buffer| to the list of known buffers. The |buffer| must have a 112 /// unique name over all buffers in the script. AddBuffer(std::unique_ptr<Buffer> buffer)113 Result AddBuffer(std::unique_ptr<Buffer> buffer) { 114 if (name_to_buffer_.count(buffer->GetName()) > 0) 115 return Result("duplicate buffer name provided"); 116 117 buffers_.push_back(std::move(buffer)); 118 name_to_buffer_[buffers_.back()->GetName()] = buffers_.back().get(); 119 return {}; 120 } 121 122 /// Retrieves the buffer with |name|, |nullptr| if not found. GetBuffer(const std::string & name)123 Buffer* GetBuffer(const std::string& name) const { 124 auto it = name_to_buffer_.find(name); 125 return it == name_to_buffer_.end() ? nullptr : it->second; 126 } 127 128 /// Retrieves a list of all buffers. GetBuffers()129 const std::vector<std::unique_ptr<Buffer>>& GetBuffers() const { 130 return buffers_; 131 } 132 133 /// Adds |feature| to the list of features that must be supported by the 134 /// engine. AddRequiredFeature(const std::string & feature)135 void AddRequiredFeature(const std::string& feature) { 136 engine_info_.required_features.push_back(feature); 137 } 138 139 /// Adds |ext| to the list of device extensions that must be supported. AddRequiredDeviceExtension(const std::string & ext)140 void AddRequiredDeviceExtension(const std::string& ext) { 141 engine_info_.required_device_extensions.push_back(ext); 142 } 143 144 /// Adds |ext| to the list of instance extensions that must be supported. AddRequiredInstanceExtension(const std::string & ext)145 void AddRequiredInstanceExtension(const std::string& ext) { 146 engine_info_.required_instance_extensions.push_back(ext); 147 } 148 149 /// Adds |ext| to the list of extensions that must be supported by the engine. 150 /// Note, this should only be used by the VkScript engine where there is no 151 /// differentiation between the types of extensions. 152 void AddRequiredExtension(const std::string& ext); 153 154 /// Retrieves the engine configuration data for this script. GetEngineData()155 EngineData& GetEngineData() { return engine_data_; } 156 /// Retrieves the engine configuration data for this script. GetEngineData()157 const EngineData& GetEngineData() const { return engine_data_; } 158 159 /// Sets |cmds| to the list of commands to execute against the engine. SetCommands(std::vector<std::unique_ptr<Command>> cmds)160 void SetCommands(std::vector<std::unique_ptr<Command>> cmds) { 161 commands_ = std::move(cmds); 162 } 163 164 /// Retrieves the list of commands to execute against the engine. GetCommands()165 const std::vector<std::unique_ptr<Command>>& GetCommands() const { 166 return commands_; 167 } 168 169 /// Sets the SPIR-V target environment. SetSpvTargetEnv(const std::string & env)170 void SetSpvTargetEnv(const std::string& env) { spv_env_ = env; } 171 /// Retrieves the SPIR-V target environment. GetSpvTargetEnv()172 const std::string& GetSpvTargetEnv() const { return spv_env_; } 173 174 /// Assign ownership of the format to the script. RegisterFormat(std::unique_ptr<Format> fmt)175 Format* RegisterFormat(std::unique_ptr<Format> fmt) { 176 formats_.push_back(std::move(fmt)); 177 return formats_.back().get(); 178 } 179 180 /// Assigns ownership of the type to the script. RegisterType(std::unique_ptr<type::Type> type)181 type::Type* RegisterType(std::unique_ptr<type::Type> type) { 182 types_.push_back(std::move(type)); 183 return types_.back().get(); 184 } 185 186 /// Adds |type| to the list of known types. The |type| must have 187 /// a unique name over all types in the script. AddType(const std::string & name,std::unique_ptr<type::Type> type)188 Result AddType(const std::string& name, std::unique_ptr<type::Type> type) { 189 if (name_to_type_.count(name) > 0) 190 return Result("duplicate type name provided"); 191 192 name_to_type_[name] = std::move(type); 193 return {}; 194 } 195 196 /// Retrieves the type with |name|, |nullptr| if not found. GetType(const std::string & name)197 type::Type* GetType(const std::string& name) const { 198 auto it = name_to_type_.find(name); 199 return it == name_to_type_.end() ? nullptr : it->second.get(); 200 } 201 202 type::Type* ParseType(const std::string& str); 203 204 private: 205 struct { 206 std::vector<std::string> required_features; 207 std::vector<std::string> required_device_extensions; 208 std::vector<std::string> required_instance_extensions; 209 } engine_info_; 210 211 EngineData engine_data_; 212 std::string spv_env_; 213 std::map<std::string, Shader*> name_to_shader_; 214 std::map<std::string, Buffer*> name_to_buffer_; 215 std::map<std::string, Pipeline*> name_to_pipeline_; 216 std::map<std::string, std::unique_ptr<type::Type>> name_to_type_; 217 std::vector<std::unique_ptr<Shader>> shaders_; 218 std::vector<std::unique_ptr<Command>> commands_; 219 std::vector<std::unique_ptr<Buffer>> buffers_; 220 std::vector<std::unique_ptr<Pipeline>> pipelines_; 221 std::vector<std::unique_ptr<type::Type>> types_; 222 std::vector<std::unique_ptr<Format>> formats_; 223 }; 224 225 } // namespace amber 226 227 #endif // SRC_SCRIPT_H_ 228