blob: 8f089d7c3e6a4e3a2c8b15f378d63ac9624ef96d [file] [log] [blame]
// Copyright 2018 The Amber Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/executor.h"
#include <cassert>
#include <utility>
#include <vector>
#include "src/engine.h"
#include "src/make_unique.h"
#include "src/script.h"
#include "src/shader_compiler.h"
namespace amber {
Executor::Executor() = default;
Executor::~Executor() = default;
Result Executor::CompileShaders(const amber::Script* script,
const ShaderMap& shader_map,
Options* options) {
for (auto& pipeline : script->GetPipelines()) {
for (auto& shader_info : pipeline->GetShaders()) {
ShaderCompiler sc(script->GetSpvTargetEnv(),
options->disable_spirv_validation);
Result r;
std::vector<uint32_t> data;
std::tie(r, data) = sc.Compile(&shader_info, shader_map);
if (!r.IsSuccess())
return r;
shader_info.SetData(std::move(data));
}
}
return {};
}
Result Executor::Execute(Engine* engine,
const amber::Script* script,
const ShaderMap& shader_map,
Options* options) {
engine->SetEngineData(script->GetEngineData());
if (!script->GetPipelines().empty()) {
Result r = CompileShaders(script, shader_map, options);
if (!r.IsSuccess())
return r;
// OpenCL specific pipeline updates.
for (auto& pipeline : script->GetPipelines()) {
r = pipeline->UpdateOpenCLBufferBindings();
if (!r.IsSuccess())
return r;
r = pipeline->GenerateOpenCLPodBuffers();
if (!r.IsSuccess())
return r;
}
for (auto& pipeline : script->GetPipelines()) {
r = engine->CreatePipeline(pipeline.get());
if (!r.IsSuccess())
return r;
}
}
if (options->execution_type == ExecutionType::kPipelineCreateOnly)
return {};
// Process Commands
for (const auto& cmd : script->GetCommands()) {
if (options->delegate && options->delegate->LogExecuteCalls()) {
options->delegate->Log(std::to_string(cmd->GetLine()) + ": " +
cmd->ToString());
}
Result r = ExecuteCommand(engine, cmd.get());
if (!r.IsSuccess())
return r;
}
return {};
}
Result Executor::ExecuteCommand(Engine* engine, Command* cmd) {
if (cmd->IsProbe()) {
auto* buffer = cmd->AsProbe()->GetBuffer();
assert(buffer);
Format* fmt = buffer->GetFormat();
return verifier_.Probe(cmd->AsProbe(), fmt, buffer->GetElementStride(),
buffer->GetRowStride(), buffer->GetWidth(),
buffer->GetHeight(), buffer->ValuePtr()->data());
}
if (cmd->IsProbeSSBO()) {
auto probe_ssbo = cmd->AsProbeSSBO();
const auto* buffer = cmd->AsProbe()->GetBuffer();
assert(buffer);
return verifier_.ProbeSSBO(probe_ssbo, buffer->ElementCount(),
buffer->ValuePtr()->data());
}
if (cmd->IsClear())
return engine->DoClear(cmd->AsClear());
if (cmd->IsClearColor())
return engine->DoClearColor(cmd->AsClearColor());
if (cmd->IsClearDepth())
return engine->DoClearDepth(cmd->AsClearDepth());
if (cmd->IsClearStencil())
return engine->DoClearStencil(cmd->AsClearStencil());
if (cmd->IsCompareBuffer()) {
auto compare = cmd->AsCompareBuffer();
auto buffer_1 = compare->GetBuffer1();
auto buffer_2 = compare->GetBuffer2();
switch (compare->GetComparator()) {
case CompareBufferCommand::Comparator::kRmse:
return buffer_1->CompareRMSE(buffer_2, compare->GetTolerance());
case CompareBufferCommand::Comparator::kHistogramEmd:
return buffer_1->CompareHistogramEMD(buffer_2, compare->GetTolerance());
case CompareBufferCommand::Comparator::kEq:
return buffer_1->IsEqual(buffer_2);
}
}
if (cmd->IsCopy()) {
auto copy = cmd->AsCopy();
auto buffer_from = copy->GetBufferFrom();
auto buffer_to = copy->GetBufferTo();
return buffer_from->CopyTo(buffer_to);
}
if (cmd->IsDrawRect())
return engine->DoDrawRect(cmd->AsDrawRect());
if (cmd->IsDrawArrays())
return engine->DoDrawArrays(cmd->AsDrawArrays());
if (cmd->IsCompute())
return engine->DoCompute(cmd->AsCompute());
if (cmd->IsEntryPoint())
return engine->DoEntryPoint(cmd->AsEntryPoint());
if (cmd->IsPatchParameterVertices())
return engine->DoPatchParameterVertices(cmd->AsPatchParameterVertices());
if (cmd->IsBuffer())
return engine->DoBuffer(cmd->AsBuffer());
if (cmd->IsRepeat()) {
for (uint32_t i = 0; i < cmd->AsRepeat()->GetCount(); ++i) {
for (const auto& sub_cmd : cmd->AsRepeat()->GetCommands()) {
Result r = ExecuteCommand(engine, sub_cmd.get());
if (!r.IsSuccess())
return r;
}
}
return {};
}
return Result("Unknown command type: " +
std::to_string(static_cast<uint32_t>(cmd->GetType())));
}
} // namespace amber