Home | History | Annotate | Download | only in ir
      1 /*
      2  * Copyright 2016 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef SKSL_LAYOUT
      9 #define SKSL_LAYOUT
     10 
     11 #include "SkSLString.h"
     12 #include "SkSLUtil.h"
     13 
     14 namespace SkSL {
     15 
     16 /**
     17  * Represents a layout block appearing before a variable declaration, as in:
     18  *
     19  * layout (location = 0) int x;
     20  */
     21 struct Layout {
     22     enum Primitive {
     23         kUnspecified_Primitive = -1,
     24         kPoints_Primitive,
     25         kLines_Primitive,
     26         kLineStrip_Primitive,
     27         kLinesAdjacency_Primitive,
     28         kTriangles_Primitive,
     29         kTriangleStrip_Primitive,
     30         kTrianglesAdjacency_Primitive
     31     };
     32 
     33     // These are used by images in GLSL. We only support a subset of what GL supports.
     34     enum class Format {
     35         kUnspecified = -1,
     36         kRGBA32F,
     37         kR32F,
     38         kRGBA16F,
     39         kR16F,
     40         kRGBA8,
     41         kR8,
     42         kRGBA8I,
     43         kR8I,
     44     };
     45 
     46     // used by SkSL processors
     47     enum Key {
     48         // field is not a key
     49         kNo_Key,
     50         // field is a key
     51         kKey_Key,
     52         // key is 0 or 1 depending on whether the matrix is an identity matrix
     53         kIdentity_Key,
     54     };
     55 
     56     static const char* FormatToStr(Format format) {
     57         switch (format) {
     58             case Format::kUnspecified:  return "";
     59             case Format::kRGBA32F:      return "rgba32f";
     60             case Format::kR32F:         return "r32f";
     61             case Format::kRGBA16F:      return "rgba16f";
     62             case Format::kR16F:         return "r16f";
     63             case Format::kRGBA8:        return "rgba8";
     64             case Format::kR8:           return "r8";
     65             case Format::kRGBA8I:       return "rgba8i";
     66             case Format::kR8I:          return "r8i";
     67         }
     68         ABORT("Unexpected format");
     69     }
     70 
     71     static bool ReadFormat(String str, Format* format) {
     72         if (str == "rgba32f") {
     73             *format = Format::kRGBA32F;
     74             return true;
     75         } else if (str == "r32f") {
     76             *format = Format::kR32F;
     77             return true;
     78         } else if (str == "rgba16f") {
     79             *format = Format::kRGBA16F;
     80             return true;
     81         } else if (str == "r16f") {
     82             *format = Format::kR16F;
     83             return true;
     84         } else if (str == "rgba8") {
     85             *format = Format::kRGBA8;
     86             return true;
     87         } else if (str == "r8") {
     88             *format = Format::kR8;
     89             return true;
     90         } else if (str == "rgba8i") {
     91             *format = Format::kRGBA8I;
     92             return true;
     93         } else if (str == "r8i") {
     94             *format = Format::kR8I;
     95             return true;
     96         }
     97         return false;
     98     }
     99 
    100     Layout(int location, int offset, int binding, int index, int set, int builtin,
    101            int inputAttachmentIndex, bool originUpperLeft, bool overrideCoverage,
    102            bool blendSupportAllEquations, Format format, bool pushconstant, Primitive primitive,
    103            int maxVertices, int invocations, String when, Key key)
    104     : fLocation(location)
    105     , fOffset(offset)
    106     , fBinding(binding)
    107     , fIndex(index)
    108     , fSet(set)
    109     , fBuiltin(builtin)
    110     , fInputAttachmentIndex(inputAttachmentIndex)
    111     , fOriginUpperLeft(originUpperLeft)
    112     , fOverrideCoverage(overrideCoverage)
    113     , fBlendSupportAllEquations(blendSupportAllEquations)
    114     , fFormat(format)
    115     , fPushConstant(pushconstant)
    116     , fPrimitive(primitive)
    117     , fMaxVertices(maxVertices)
    118     , fInvocations(invocations)
    119     , fWhen(when)
    120     , fKey(key) {}
    121 
    122     Layout()
    123     : fLocation(-1)
    124     , fOffset(-1)
    125     , fBinding(-1)
    126     , fIndex(-1)
    127     , fSet(-1)
    128     , fBuiltin(-1)
    129     , fInputAttachmentIndex(-1)
    130     , fOriginUpperLeft(false)
    131     , fOverrideCoverage(false)
    132     , fBlendSupportAllEquations(false)
    133     , fFormat(Format::kUnspecified)
    134     , fPushConstant(false)
    135     , fPrimitive(kUnspecified_Primitive)
    136     , fMaxVertices(-1)
    137     , fInvocations(-1)
    138     , fKey(kNo_Key) {}
    139 
    140     String description() const {
    141         String result;
    142         String separator;
    143         if (fLocation >= 0) {
    144             result += separator + "location = " + to_string(fLocation);
    145             separator = ", ";
    146         }
    147         if (fOffset >= 0) {
    148             result += separator + "offset = " + to_string(fOffset);
    149             separator = ", ";
    150         }
    151         if (fBinding >= 0) {
    152             result += separator + "binding = " + to_string(fBinding);
    153             separator = ", ";
    154         }
    155         if (fIndex >= 0) {
    156             result += separator + "index = " + to_string(fIndex);
    157             separator = ", ";
    158         }
    159         if (fSet >= 0) {
    160             result += separator + "set = " + to_string(fSet);
    161             separator = ", ";
    162         }
    163         if (fBuiltin >= 0) {
    164             result += separator + "builtin = " + to_string(fBuiltin);
    165             separator = ", ";
    166         }
    167         if (fInputAttachmentIndex >= 0) {
    168             result += separator + "input_attachment_index = " + to_string(fBuiltin);
    169             separator = ", ";
    170         }
    171         if (fOriginUpperLeft) {
    172             result += separator + "origin_upper_left";
    173             separator = ", ";
    174         }
    175         if (fOverrideCoverage) {
    176             result += separator + "override_coverage";
    177             separator = ", ";
    178         }
    179         if (fBlendSupportAllEquations) {
    180             result += separator + "blend_support_all_equations";
    181             separator = ", ";
    182         }
    183         if (Format::kUnspecified != fFormat) {
    184             result += separator + FormatToStr(fFormat);
    185             separator = ", ";
    186         }
    187         if (fPushConstant) {
    188             result += separator + "push_constant";
    189             separator = ", ";
    190         }
    191         switch (fPrimitive) {
    192             case kPoints_Primitive:
    193                 result += separator + "points";
    194                 separator = ", ";
    195                 break;
    196             case kLines_Primitive:
    197                 result += separator + "lines";
    198                 separator = ", ";
    199                 break;
    200             case kLineStrip_Primitive:
    201                 result += separator + "line_strip";
    202                 separator = ", ";
    203                 break;
    204             case kLinesAdjacency_Primitive:
    205                 result += separator + "lines_adjacency";
    206                 separator = ", ";
    207                 break;
    208             case kTriangles_Primitive:
    209                 result += separator + "triangles";
    210                 separator = ", ";
    211                 break;
    212             case kTriangleStrip_Primitive:
    213                 result += separator + "triangle_strip";
    214                 separator = ", ";
    215                 break;
    216             case kTrianglesAdjacency_Primitive:
    217                 result += separator + "triangles_adjacency";
    218                 separator = ", ";
    219                 break;
    220             case kUnspecified_Primitive:
    221                 break;
    222         }
    223         if (fMaxVertices >= 0) {
    224             result += separator + "max_vertices = " + to_string(fMaxVertices);
    225             separator = ", ";
    226         }
    227         if (fInvocations >= 0) {
    228             result += separator + "invocations = " + to_string(fInvocations);
    229             separator = ", ";
    230         }
    231         if (fWhen.size()) {
    232             result += separator + "when = " + fWhen;
    233             separator = ", ";
    234         }
    235         switch (fKey) {
    236             case kNo_Key:
    237                 break;
    238             case kKey_Key:
    239                 result += separator + "key";
    240                 separator = ", ";
    241                 break;
    242             case kIdentity_Key:
    243                 result += separator + "key=identity";
    244                 separator = ", ";
    245                 break;
    246         }
    247         if (result.size() > 0) {
    248             result = "layout (" + result + ")";
    249         }
    250         return result;
    251     }
    252 
    253     bool operator==(const Layout& other) const {
    254         return fLocation                 == other.fLocation &&
    255                fOffset                   == other.fOffset &&
    256                fBinding                  == other.fBinding &&
    257                fIndex                    == other.fIndex &&
    258                fSet                      == other.fSet &&
    259                fBuiltin                  == other.fBuiltin &&
    260                fInputAttachmentIndex     == other.fInputAttachmentIndex &&
    261                fOriginUpperLeft          == other.fOriginUpperLeft &&
    262                fOverrideCoverage         == other.fOverrideCoverage &&
    263                fBlendSupportAllEquations == other.fBlendSupportAllEquations &&
    264                fFormat                   == other.fFormat &&
    265                fPrimitive                == other.fPrimitive &&
    266                fMaxVertices              == other.fMaxVertices &&
    267                fInvocations              == other.fInvocations;
    268     }
    269 
    270     bool operator!=(const Layout& other) const {
    271         return !(*this == other);
    272     }
    273 
    274     int fLocation;
    275     int fOffset;
    276     int fBinding;
    277     int fIndex;
    278     int fSet;
    279     // builtin comes from SPIR-V and identifies which particular builtin value this object
    280     // represents.
    281     int fBuiltin;
    282     // input_attachment_index comes from Vulkan/SPIR-V to connect a shader variable to the a
    283     // corresponding attachment on the subpass in which the shader is being used.
    284     int fInputAttachmentIndex;
    285     bool fOriginUpperLeft;
    286     bool fOverrideCoverage;
    287     bool fBlendSupportAllEquations;
    288     Format fFormat;
    289     bool fPushConstant;
    290     Primitive fPrimitive;
    291     int fMaxVertices;
    292     int fInvocations;
    293     String fWhen;
    294     Key fKey;
    295 };
    296 
    297 } // namespace
    298 
    299 #endif
    300