• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "src/executor.h"
16 
17 #include <cassert>
18 #include <string>
19 #include <utility>
20 #include <vector>
21 
22 #include "src/engine.h"
23 #include "src/make_unique.h"
24 #include "src/script.h"
25 #include "src/shader_compiler.h"
26 
27 namespace amber {
28 
29 Executor::Executor() = default;
30 
31 Executor::~Executor() = default;
32 
CompileShaders(const amber::Script * script,const ShaderMap & shader_map,Options * options)33 Result Executor::CompileShaders(const amber::Script* script,
34                                 const ShaderMap& shader_map,
35                                 Options* options) {
36   for (auto& pipeline : script->GetPipelines()) {
37     for (auto& shader_info : pipeline->GetShaders()) {
38       std::string target_env = shader_info.GetShader()->GetTargetEnv();
39       if (target_env.empty())
40         target_env = script->GetSpvTargetEnv();
41 
42       ShaderCompiler sc(target_env, options->disable_spirv_validation,
43                         script->GetVirtualFiles());
44 
45       Result r;
46       std::vector<uint32_t> data;
47       std::tie(r, data) = sc.Compile(pipeline.get(), &shader_info, shader_map);
48       if (!r.IsSuccess())
49         return r;
50 
51       shader_info.SetData(std::move(data));
52     }
53   }
54   return {};
55 }
56 
Execute(Engine * engine,const amber::Script * script,const ShaderMap & shader_map,Options * options,Delegate * delegate)57 Result Executor::Execute(Engine* engine,
58                          const amber::Script* script,
59                          const ShaderMap& shader_map,
60                          Options* options,
61                          Delegate* delegate) {
62   engine->SetEngineData(script->GetEngineData());
63 
64   if (!script->GetPipelines().empty()) {
65     Result r = CompileShaders(script, shader_map, options);
66     if (!r.IsSuccess())
67       return r;
68 
69     // OpenCL specific pipeline updates.
70     for (auto& pipeline : script->GetPipelines()) {
71       r = pipeline->UpdateOpenCLBufferBindings();
72       if (!r.IsSuccess())
73         return r;
74       r = pipeline->GenerateOpenCLPodBuffers();
75       if (!r.IsSuccess())
76         return r;
77       r = pipeline->GenerateOpenCLLiteralSamplers();
78       if (!r.IsSuccess())
79         return r;
80       r = pipeline->GenerateOpenCLPushConstants();
81       if (!r.IsSuccess())
82         return r;
83     }
84 
85     for (auto& pipeline : script->GetPipelines()) {
86       r = engine->CreatePipeline(pipeline.get());
87       if (!r.IsSuccess())
88         return r;
89     }
90   }
91 
92   if (options->execution_type == ExecutionType::kPipelineCreateOnly)
93     return {};
94 
95   // Process Commands
96   for (const auto& cmd : script->GetCommands()) {
97     if (delegate && delegate->LogExecuteCalls()) {
98       delegate->Log(std::to_string(cmd->GetLine()) + ": " + cmd->ToString());
99     }
100 
101     Result r = ExecuteCommand(engine, cmd.get());
102     if (!r.IsSuccess())
103       return r;
104   }
105   return {};
106 }
107 
ExecuteCommand(Engine * engine,Command * cmd)108 Result Executor::ExecuteCommand(Engine* engine, Command* cmd) {
109   if (cmd->IsProbe()) {
110     auto* buffer = cmd->AsProbe()->GetBuffer();
111     assert(buffer);
112 
113     Format* fmt = buffer->GetFormat();
114     return verifier_.Probe(cmd->AsProbe(), fmt, buffer->GetElementStride(),
115                            buffer->GetRowStride(), buffer->GetWidth(),
116                            buffer->GetHeight(), buffer->ValuePtr()->data());
117   }
118   if (cmd->IsProbeSSBO()) {
119     auto probe_ssbo = cmd->AsProbeSSBO();
120 
121     const auto* buffer = cmd->AsProbe()->GetBuffer();
122     assert(buffer);
123 
124     return verifier_.ProbeSSBO(probe_ssbo, buffer->ElementCount(),
125                                buffer->ValuePtr()->data());
126   }
127   if (cmd->IsClear())
128     return engine->DoClear(cmd->AsClear());
129   if (cmd->IsClearColor())
130     return engine->DoClearColor(cmd->AsClearColor());
131   if (cmd->IsClearDepth())
132     return engine->DoClearDepth(cmd->AsClearDepth());
133   if (cmd->IsClearStencil())
134     return engine->DoClearStencil(cmd->AsClearStencil());
135   if (cmd->IsCompareBuffer()) {
136     auto compare = cmd->AsCompareBuffer();
137     auto buffer_1 = compare->GetBuffer1();
138     auto buffer_2 = compare->GetBuffer2();
139     switch (compare->GetComparator()) {
140       case CompareBufferCommand::Comparator::kRmse:
141         return buffer_1->CompareRMSE(buffer_2, compare->GetTolerance());
142       case CompareBufferCommand::Comparator::kHistogramEmd:
143         return buffer_1->CompareHistogramEMD(buffer_2, compare->GetTolerance());
144       case CompareBufferCommand::Comparator::kEq:
145         return buffer_1->IsEqual(buffer_2);
146     }
147   }
148   if (cmd->IsCopy()) {
149     auto copy = cmd->AsCopy();
150     auto buffer_from = copy->GetBufferFrom();
151     auto buffer_to = copy->GetBufferTo();
152     return buffer_from->CopyTo(buffer_to);
153   }
154   if (cmd->IsDrawRect())
155     return engine->DoDrawRect(cmd->AsDrawRect());
156   if (cmd->IsDrawGrid())
157     return engine->DoDrawGrid(cmd->AsDrawGrid());
158   if (cmd->IsDrawArrays())
159     return engine->DoDrawArrays(cmd->AsDrawArrays());
160   if (cmd->IsCompute())
161     return engine->DoCompute(cmd->AsCompute());
162   if (cmd->IsEntryPoint())
163     return engine->DoEntryPoint(cmd->AsEntryPoint());
164   if (cmd->IsPatchParameterVertices())
165     return engine->DoPatchParameterVertices(cmd->AsPatchParameterVertices());
166   if (cmd->IsBuffer())
167     return engine->DoBuffer(cmd->AsBuffer());
168   if (cmd->IsRepeat()) {
169     for (uint32_t i = 0; i < cmd->AsRepeat()->GetCount(); ++i) {
170       for (const auto& sub_cmd : cmd->AsRepeat()->GetCommands()) {
171         Result r = ExecuteCommand(engine, sub_cmd.get());
172         if (!r.IsSuccess())
173           return r;
174       }
175     }
176     return {};
177   }
178   return Result("Unknown command type: " +
179                 std::to_string(static_cast<uint32_t>(cmd->GetType())));
180 }
181 
182 }  // namespace amber
183