blob: b3c3a2b6d8e0fc1421742ab2efaa80c8b1ceea20 [file] [log] [blame]
// Copyright 2019 The Shaderc Authors. All rights reserved.
//
// 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.
#ifndef LIBSHADERC_SPVC_SRC_SPVCIR_PASS_H_
#define LIBSHADERC_SPVC_SRC_SPVCIR_PASS_H_
#include <spirv_glsl.hpp>
#include <spirv_hlsl.hpp>
#include <spirv_msl.hpp>
#include "source/opt/pass.h" // Accessing a private spirv-tools header.
#include "spirv-tools/libspirv.hpp"
#include "spvc/spvc.h"
namespace spvtools {
namespace opt {
// this WIP pass generates spvc IR and does not throw exceptions
class SpvcIrPass : public Pass {
public:
SpvcIrPass(spirv_cross::ParsedIR *ir);
const char *name() const override { return "spvc-if-pass"; }
Status Process() override;
IRContext::Analysis GetPreservedAnalyses() override {
return IRContext::kAnalysisNone;
}
// Given an spirv Instruction adds its SPIRV-Corss IR equivalent to ir_
void GenerateSpirvCrossIR(Instruction *inst);
private:
spirv_cross::ParsedIR *ir_;
spirv_cross::SPIRFunction *current_function_ = nullptr;
spirv_cross::SPIRBlock *current_block_ = nullptr;
Pass::Status status_;
// A data structure to store type aliases.
// spirv-cross comment: This must be an ordered data structure so we always
// pick the same type aliases.
spirv_cross::SmallVector<uint32_t> global_struct_cache_;
// used to save our offset into the input spirv string
uint32_t offset_ = 5;
// copied from spirv-cross (class Parser)
// Adds an instruction to the SPIRV-Cross IR, for the given result Id and with
// given type and arguments.
// Returns the constructed instruction.
// TODO(sarahM0): explore whether it's better to replace with explicit set,
// se1, set2, ...
template <typename T, typename... P>
T &set(uint32_t id, P &&... args) {
ir_->add_typed_id(static_cast<spirv_cross::Types>(T::type), id);
auto &var =
spirv_cross::variant_set<T>(ir_->ids[id], std::forward<P>(args)...);
var.self = id;
return var;
}
// copied from spirv-cross (class Parser)
// For a given result Id returns the previously constructed instruction.
template <typename T>
T &get(uint32_t id) {
return spirv_cross::variant_get<T>(ir_->ids[id]);
}
template <typename T>
const T &get(uint32_t id) const {
return spirv_cross::variant_get<T>(ir_->ids[id]);
}
// copied from spirv-cross (class Parser)
// For a given result Id returns the instruction if it was previously
// constructed and had the same result Type otherwise returns nullptr.
template <typename T>
T *maybe_get(uint32_t id) {
if (id >= ir_->ids.size())
return nullptr;
else if (ir_->ids[id].get_type() ==
static_cast<spirv_cross::Types>(T::type))
return &get<T>(id);
else
return nullptr;
}
template <typename T>
const T *maybe_get(uint32_t id) const {
if (id >= ir_->ids.size())
return nullptr;
else if (ir_->ids[id].get_type() ==
static_cast<spirv_cross::Types>(T::type))
return &get<T>(id);
else
return nullptr;
}
// Check boolean condition. If false record the error message, and set pass
// status to failure to stop processing.
bool CheckConditionAndSetErrorMessage(bool condition, std::string message);
// Returns true only if to the given spirv-cross types are equivalent
bool types_are_logically_equivalent(const spirv_cross::SPIRType &a,
const spirv_cross::SPIRType &b) const;
// Given an id and its type, sets all of its entries and sub-entries to null
void make_constant_null(uint32_t id, uint32_t type);
};
} // namespace opt
} // namespace spvtools
#endif // LIBSHADERC_SPVC_SRC_SPVCIR_PASS_H_