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 "SkString.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     static const char* FormatToStr(Format format) {
     47         switch (format) {
     48             case Format::kUnspecified:  return "";
     49             case Format::kRGBA32F:      return "rgba32f";
     50             case Format::kR32F:         return "r32f";
     51             case Format::kRGBA16F:      return "rgba16f";
     52             case Format::kR16F:         return "r16f";
     53             case Format::kRGBA8:        return "rgba8";
     54             case Format::kR8:           return "r8";
     55             case Format::kRGBA8I:       return "rgba8i";
     56             case Format::kR8I:          return "r8i";
     57         }
     58         SkFAIL("Unexpected format");
     59         return "";
     60     }
     61 
     62     static bool ReadFormat(SkString str, Format* format) {
     63         if (str == "rgba32f") {
     64             *format = Format::kRGBA32F;
     65             return true;
     66         } else if (str == "r32f") {
     67             *format = Format::kR32F;
     68             return true;
     69         } else if (str == "rgba16f") {
     70             *format = Format::kRGBA16F;
     71             return true;
     72         } else if (str == "r16f") {
     73             *format = Format::kR16F;
     74             return true;
     75         } else if (str == "rgba8") {
     76             *format = Format::kRGBA8;
     77             return true;
     78         } else if (str == "r8") {
     79             *format = Format::kR8;
     80             return true;
     81         } else if (str == "rgba8i") {
     82             *format = Format::kRGBA8I;
     83             return true;
     84         } else if (str == "r8i") {
     85             *format = Format::kR8I;
     86             return true;
     87         }
     88         return false;
     89     }
     90 
     91     Layout(int location, int offset, int binding, int index, int set, int builtin,
     92            int inputAttachmentIndex, bool originUpperLeft, bool overrideCoverage,
     93            bool blendSupportAllEquations, Format format, bool pushconstant, Primitive primitive,
     94            int maxVertices, int invocations)
     95     : fLocation(location)
     96     , fOffset(offset)
     97     , fBinding(binding)
     98     , fIndex(index)
     99     , fSet(set)
    100     , fBuiltin(builtin)
    101     , fInputAttachmentIndex(inputAttachmentIndex)
    102     , fOriginUpperLeft(originUpperLeft)
    103     , fOverrideCoverage(overrideCoverage)
    104     , fBlendSupportAllEquations(blendSupportAllEquations)
    105     , fFormat(format)
    106     , fPushConstant(pushconstant)
    107     , fPrimitive(primitive)
    108     , fMaxVertices(maxVertices)
    109     , fInvocations(invocations) {}
    110 
    111     Layout()
    112     : fLocation(-1)
    113     , fOffset(-1)
    114     , fBinding(-1)
    115     , fIndex(-1)
    116     , fSet(-1)
    117     , fBuiltin(-1)
    118     , fInputAttachmentIndex(-1)
    119     , fOriginUpperLeft(false)
    120     , fOverrideCoverage(false)
    121     , fBlendSupportAllEquations(false)
    122     , fFormat(Format::kUnspecified)
    123     , fPushConstant(false)
    124     , fPrimitive(kUnspecified_Primitive)
    125     , fMaxVertices(-1)
    126     , fInvocations(-1) {}
    127 
    128     SkString description() const {
    129         SkString result;
    130         SkString separator;
    131         if (fLocation >= 0) {
    132             result += separator + "location = " + to_string(fLocation);
    133             separator = ", ";
    134         }
    135         if (fOffset >= 0) {
    136             result += separator + "offset = " + to_string(fOffset);
    137             separator = ", ";
    138         }
    139         if (fBinding >= 0) {
    140             result += separator + "binding = " + to_string(fBinding);
    141             separator = ", ";
    142         }
    143         if (fIndex >= 0) {
    144             result += separator + "index = " + to_string(fIndex);
    145             separator = ", ";
    146         }
    147         if (fSet >= 0) {
    148             result += separator + "set = " + to_string(fSet);
    149             separator = ", ";
    150         }
    151         if (fBuiltin >= 0) {
    152             result += separator + "builtin = " + to_string(fBuiltin);
    153             separator = ", ";
    154         }
    155         if (fInputAttachmentIndex >= 0) {
    156             result += separator + "input_attachment_index = " + to_string(fBuiltin);
    157             separator = ", ";
    158         }
    159         if (fOriginUpperLeft) {
    160             result += separator + "origin_upper_left";
    161             separator = ", ";
    162         }
    163         if (fOverrideCoverage) {
    164             result += separator + "override_coverage";
    165             separator = ", ";
    166         }
    167         if (fBlendSupportAllEquations) {
    168             result += separator + "blend_support_all_equations";
    169             separator = ", ";
    170         }
    171         if (Format::kUnspecified != fFormat) {
    172             result += separator + FormatToStr(fFormat);
    173             separator = ", ";
    174         }
    175         if (fPushConstant) {
    176             result += separator + "push_constant";
    177             separator = ", ";
    178         }
    179         switch (fPrimitive) {
    180             case kPoints_Primitive:
    181                 result += separator + "points";
    182                 separator = ", ";
    183                 break;
    184             case kLines_Primitive:
    185                 result += separator + "lines";
    186                 separator = ", ";
    187                 break;
    188             case kLineStrip_Primitive:
    189                 result += separator + "line_strip";
    190                 separator = ", ";
    191                 break;
    192             case kLinesAdjacency_Primitive:
    193                 result += separator + "lines_adjacency";
    194                 separator = ", ";
    195                 break;
    196             case kTriangles_Primitive:
    197                 result += separator + "triangles";
    198                 separator = ", ";
    199                 break;
    200             case kTriangleStrip_Primitive:
    201                 result += separator + "triangle_strip";
    202                 separator = ", ";
    203                 break;
    204             case kTrianglesAdjacency_Primitive:
    205                 result += separator + "triangles_adjacency";
    206                 separator = ", ";
    207                 break;
    208             case kUnspecified_Primitive:
    209                 break;
    210         }
    211         if (fMaxVertices >= 0) {
    212             result += separator + "max_vertices = " + to_string(fMaxVertices);
    213             separator = ", ";
    214         }
    215         if (fInvocations >= 0) {
    216             result += separator + "invocations = " + to_string(fInvocations);
    217             separator = ", ";
    218         }
    219         if (result.size() > 0) {
    220             result = "layout (" + result + ")";
    221         }
    222         return result;
    223     }
    224 
    225     bool operator==(const Layout& other) const {
    226         return fLocation                 == other.fLocation &&
    227                fOffset                   == other.fOffset &&
    228                fBinding                  == other.fBinding &&
    229                fIndex                    == other.fIndex &&
    230                fSet                      == other.fSet &&
    231                fBuiltin                  == other.fBuiltin &&
    232                fInputAttachmentIndex     == other.fInputAttachmentIndex &&
    233                fOriginUpperLeft          == other.fOriginUpperLeft &&
    234                fOverrideCoverage         == other.fOverrideCoverage &&
    235                fBlendSupportAllEquations == other.fBlendSupportAllEquations &&
    236                fFormat                   == other.fFormat &&
    237                fPrimitive                == other.fPrimitive &&
    238                fMaxVertices              == other.fMaxVertices &&
    239                fInvocations              == other.fInvocations;
    240     }
    241 
    242     bool operator!=(const Layout& other) const {
    243         return !(*this == other);
    244     }
    245 
    246     int fLocation;
    247     int fOffset;
    248     int fBinding;
    249     int fIndex;
    250     int fSet;
    251     // builtin comes from SPIR-V and identifies which particular builtin value this object
    252     // represents.
    253     int fBuiltin;
    254     // input_attachment_index comes from Vulkan/SPIR-V to connect a shader variable to the a
    255     // corresponding attachment on the subpass in which the shader is being used.
    256     int fInputAttachmentIndex;
    257     bool fOriginUpperLeft;
    258     bool fOverrideCoverage;
    259     bool fBlendSupportAllEquations;
    260     Format fFormat;
    261     bool fPushConstant;
    262     Primitive fPrimitive;
    263     int fMaxVertices;
    264     int fInvocations;
    265 };
    266 
    267 } // namespace
    268 
    269 #endif
    270