Hash :
d7aa0130
Author :
Date :
2021-04-26T16:56:15
Upstream Apple's direct-to-Metal backend: compile translator. This change is meant to merge the translator changes from Apple's direct-to-Metal backend. Taken from Kyle Piddington's CL: https://chromium-review.googlesource.com/c/angle/angle/+/2857366/ The goal of this CL is to merge the translator code in a state that compiles, but not to switch the Metal backend over to use this translator backend yet. Bug: angleproject:5505 Change-Id: I68a6354604498cd5fd1eb96c13fc56f3b38f2bd0 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2897536 Reviewed-by: Jonah Ryan-Davis <jonahr@google.com> Commit-Queue: Jonah Ryan-Davis <jonahr@google.com>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
//
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#ifndef COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_MODIFYSTRUCT_H_
#define COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_MODIFYSTRUCT_H_
#include <cstring>
#include <unordered_map>
#include <unordered_set>
#include "compiler/translator/Compiler.h"
#include "compiler/translator/TranslatorMetalDirect/IdGen.h"
#include "compiler/translator/TranslatorMetalDirect/Layout.h"
#include "compiler/translator/TranslatorMetalDirect/Name.h"
#include "compiler/translator/TranslatorMetalDirect/ProgramPrelude.h"
#include "compiler/translator/TranslatorMetalDirect/SymbolEnv.h"
namespace sh
{
enum class ConvertType
{
OriginalToModified,
ModifiedToOriginal,
};
// Configures how struct modification is performed.
class ModifyStructConfig
{
public:
struct Predicate
{
using Func = bool (*)(const TField &);
static bool False(const TField &) { return false; }
static bool True(const TField &) { return true; }
};
struct SaturateVector
{
// Valid return values are [0, 1, 2, 3, 4].
// If original dim >= return value, the field remains untouched.
using Func = int (*)(const TField &);
static int DontSaturate(const TField &) { return 0; }
static int FullySaturate(const TField &) { return 4; }
};
public:
ModifyStructConfig(ConvertType convertType, bool allowPacking, bool allowPadding)
: convertType(convertType), allowPacking(allowPacking), allowPadding(allowPadding)
{}
// Matrix field is split into multiple fields of row vectors.
Predicate::Func splitMatrixColumns = Predicate::False;
// Array fields are split into multiple fields of element type.
Predicate::Func inlineArray = Predicate::False;
// Struct fields have their subfields inlined directly.
Predicate::Func inlineStruct = Predicate::False;
// Struct fields are modified.
Predicate::Func recurseStruct = Predicate::False;
// Vector and scalar bool fields are promoted to uint fields.
Predicate::Func promoteBoolToUint = Predicate::False;
// Creates a new structure where scalar or vector fields are saturated vectors.
// e.g. `float -> float4`.
// e.g. `float2 -> float4`.
SaturateVector::Func saturateScalarOrVector = SaturateVector::DontSaturate;
// Creates a new structure where scalar or vector array fields are saturated.
// e.g. `float[10] -> float4[10]`
// e.g. `float2[10] -> float4[10]`
SaturateVector::Func saturateScalarOrVectorArrays = SaturateVector::DontSaturate;
// Creates a new structure where matrix fields are row-saturated.
// e.g. `float2x2 -> float2x4`.
SaturateVector::Func saturateMatrixRows = SaturateVector::DontSaturate;
TLayoutBlockStorage initialBlockStorage = kDefaultLayoutBlockStorage;
TLayoutMatrixPacking initialMatrixPacking = kDefaultLayoutMatrixPacking;
ConvertType convertType;
bool allowPacking;
bool allowPadding;
AddressSpace externalAddressSpace;
};
struct ModifiedStructMachinery
{
const TStructure *modifiedStruct = nullptr;
TIntermFunctionDefinition *funcOriginalToModified = nullptr;
TIntermFunctionDefinition *funcModifiedToOriginal = nullptr;
TIntermFunctionDefinition *&getConverter(ConvertType convertType)
{
if (convertType == ConvertType::OriginalToModified)
{
return funcOriginalToModified;
}
else
{
return funcModifiedToOriginal;
}
}
};
// Indexed by topological order.
class ModifiedStructMachineries
{
public:
size_t size() const;
const ModifiedStructMachinery &at(size_t index) const;
const ModifiedStructMachinery *find(const TStructure &s) const;
void insert(const TStructure &s, const ModifiedStructMachinery &machinery);
private:
std::unordered_map<const TStructure *, ModifiedStructMachinery> originalToMachinery;
std::vector<const TStructure *> ordering;
};
// Returns true and `outMachinery` populated if modifications were performed.
// Returns false otherwise.
bool TryCreateModifiedStruct(TCompiler &compiler,
SymbolEnv &symbolEnv,
IdGen &idGen,
const ModifyStructConfig &config,
const TStructure &originalStruct,
const Name &modifiedStructName,
ModifiedStructMachineries &outMachineries,
const bool isUBO,
const bool allowPadding);
} // namespace sh
#endif // COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_MODIFYSTRUCT_H_