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 Flag {
     23         kOriginUpperLeft_Flag            = 1 <<  0,
     24         kOverrideCoverage_Flag           = 1 <<  1,
     25         kPushConstant_Flag               = 1 <<  2,
     26         kBlendSupportAllEquations_Flag   = 1 <<  3,
     27         kBlendSupportMultiply_Flag       = 1 <<  4,
     28         kBlendSupportScreen_Flag         = 1 <<  5,
     29         kBlendSupportOverlay_Flag        = 1 <<  6,
     30         kBlendSupportDarken_Flag         = 1 <<  7,
     31         kBlendSupportLighten_Flag        = 1 <<  8,
     32         kBlendSupportColorDodge_Flag     = 1 <<  9,
     33         kBlendSupportColorBurn_Flag      = 1 << 10,
     34         kBlendSupportHardLight_Flag      = 1 << 11,
     35         kBlendSupportSoftLight_Flag      = 1 << 12,
     36         kBlendSupportDifference_Flag     = 1 << 13,
     37         kBlendSupportExclusion_Flag      = 1 << 14,
     38         kBlendSupportHSLHue_Flag         = 1 << 15,
     39         kBlendSupportHSLSaturation_Flag  = 1 << 16,
     40         kBlendSupportHSLColor_Flag       = 1 << 17,
     41         kBlendSupportHSLLuminosity_Flag  = 1 << 18
     42     };
     43 
     44     enum Primitive {
     45         kUnspecified_Primitive = -1,
     46         kPoints_Primitive,
     47         kLines_Primitive,
     48         kLineStrip_Primitive,
     49         kLinesAdjacency_Primitive,
     50         kTriangles_Primitive,
     51         kTriangleStrip_Primitive,
     52         kTrianglesAdjacency_Primitive
     53     };
     54 
     55     // These are used by images in GLSL. We only support a subset of what GL supports.
     56     enum class Format {
     57         kUnspecified = -1,
     58         kRGBA32F,
     59         kR32F,
     60         kRGBA16F,
     61         kR16F,
     62         kRGBA8,
     63         kR8,
     64         kRGBA8I,
     65         kR8I,
     66     };
     67 
     68     // used by SkSL processors
     69     enum Key {
     70         // field is not a key
     71         kNo_Key,
     72         // field is a key
     73         kKey_Key,
     74         // key is 0 or 1 depending on whether the matrix is an identity matrix
     75         kIdentity_Key,
     76     };
     77 
     78     static const char* FormatToStr(Format format) {
     79         switch (format) {
     80             case Format::kUnspecified:  return "";
     81             case Format::kRGBA32F:      return "rgba32f";
     82             case Format::kR32F:         return "r32f";
     83             case Format::kRGBA16F:      return "rgba16f";
     84             case Format::kR16F:         return "r16f";
     85             case Format::kRGBA8:        return "rgba8";
     86             case Format::kR8:           return "r8";
     87             case Format::kRGBA8I:       return "rgba8i";
     88             case Format::kR8I:          return "r8i";
     89         }
     90         ABORT("Unexpected format");
     91     }
     92 
     93     static bool ReadFormat(String str, Format* format) {
     94         if (str == "rgba32f") {
     95             *format = Format::kRGBA32F;
     96             return true;
     97         } else if (str == "r32f") {
     98             *format = Format::kR32F;
     99             return true;
    100         } else if (str == "rgba16f") {
    101             *format = Format::kRGBA16F;
    102             return true;
    103         } else if (str == "r16f") {
    104             *format = Format::kR16F;
    105             return true;
    106         } else if (str == "rgba8") {
    107             *format = Format::kRGBA8;
    108             return true;
    109         } else if (str == "r8") {
    110             *format = Format::kR8;
    111             return true;
    112         } else if (str == "rgba8i") {
    113             *format = Format::kRGBA8I;
    114             return true;
    115         } else if (str == "r8i") {
    116             *format = Format::kR8I;
    117             return true;
    118         }
    119         return false;
    120     }
    121 
    122     Layout(int flags, int location, int offset, int binding, int index, int set, int builtin,
    123            int inputAttachmentIndex, Format format, Primitive primitive, int maxVertices,
    124            int invocations, String when, Key key, StringFragment ctype)
    125     : fFlags(flags)
    126     , fLocation(location)
    127     , fOffset(offset)
    128     , fBinding(binding)
    129     , fIndex(index)
    130     , fSet(set)
    131     , fBuiltin(builtin)
    132     , fInputAttachmentIndex(inputAttachmentIndex)
    133     , fFormat(format)
    134     , fPrimitive(primitive)
    135     , fMaxVertices(maxVertices)
    136     , fInvocations(invocations)
    137     , fWhen(when)
    138     , fKey(key)
    139     , fCType(ctype) {}
    140 
    141     Layout()
    142     : fFlags(0)
    143     , fLocation(-1)
    144     , fOffset(-1)
    145     , fBinding(-1)
    146     , fIndex(-1)
    147     , fSet(-1)
    148     , fBuiltin(-1)
    149     , fInputAttachmentIndex(-1)
    150     , fFormat(Format::kUnspecified)
    151     , fPrimitive(kUnspecified_Primitive)
    152     , fMaxVertices(-1)
    153     , fInvocations(-1)
    154     , fKey(kNo_Key) {}
    155 
    156     String description() const {
    157         String result;
    158         String separator;
    159         if (fLocation >= 0) {
    160             result += separator + "location = " + to_string(fLocation);
    161             separator = ", ";
    162         }
    163         if (fOffset >= 0) {
    164             result += separator + "offset = " + to_string(fOffset);
    165             separator = ", ";
    166         }
    167         if (fBinding >= 0) {
    168             result += separator + "binding = " + to_string(fBinding);
    169             separator = ", ";
    170         }
    171         if (fIndex >= 0) {
    172             result += separator + "index = " + to_string(fIndex);
    173             separator = ", ";
    174         }
    175         if (fSet >= 0) {
    176             result += separator + "set = " + to_string(fSet);
    177             separator = ", ";
    178         }
    179         if (fBuiltin >= 0) {
    180             result += separator + "builtin = " + to_string(fBuiltin);
    181             separator = ", ";
    182         }
    183         if (fInputAttachmentIndex >= 0) {
    184             result += separator + "input_attachment_index = " + to_string(fBuiltin);
    185             separator = ", ";
    186         }
    187         if (Format::kUnspecified != fFormat) {
    188             result += separator + FormatToStr(fFormat);
    189             separator = ", ";
    190         }
    191         if (fFlags & kOriginUpperLeft_Flag) {
    192             result += separator + "origin_upper_left";
    193             separator = ", ";
    194         }
    195         if (fFlags & kOverrideCoverage_Flag) {
    196             result += separator + "override_coverage";
    197             separator = ", ";
    198         }
    199         if (fFlags & kBlendSupportAllEquations_Flag) {
    200             result += separator + "blend_support_all_equations";
    201             separator = ", ";
    202         }
    203         if (fFlags & kBlendSupportMultiply_Flag) {
    204             result += separator + "blend_support_multiply";
    205             separator = ", ";
    206         }
    207         if (fFlags & kBlendSupportScreen_Flag) {
    208             result += separator + "blend_support_screen";
    209             separator = ", ";
    210         }
    211         if (fFlags & kBlendSupportOverlay_Flag) {
    212             result += separator + "blend_support_overlay";
    213             separator = ", ";
    214         }
    215         if (fFlags & kBlendSupportDarken_Flag) {
    216             result += separator + "blend_support_darken";
    217             separator = ", ";
    218         }
    219         if (fFlags & kBlendSupportLighten_Flag) {
    220             result += separator + "blend_support_lighten";
    221             separator = ", ";
    222         }
    223         if (fFlags & kBlendSupportColorDodge_Flag) {
    224             result += separator + "blend_support_colordodge";
    225             separator = ", ";
    226         }
    227         if (fFlags & kBlendSupportColorBurn_Flag) {
    228             result += separator + "blend_support_colorburn";
    229             separator = ", ";
    230         }
    231         if (fFlags & kBlendSupportHardLight_Flag) {
    232             result += separator + "blend_support_hardlight";
    233             separator = ", ";
    234         }
    235         if (fFlags & kBlendSupportSoftLight_Flag) {
    236             result += separator + "blend_support_softlight";
    237             separator = ", ";
    238         }
    239         if (fFlags & kBlendSupportDifference_Flag) {
    240             result += separator + "blend_support_difference";
    241             separator = ", ";
    242         }
    243         if (fFlags & kBlendSupportExclusion_Flag) {
    244             result += separator + "blend_support_exclusion";
    245             separator = ", ";
    246         }
    247         if (fFlags & kBlendSupportHSLHue_Flag) {
    248             result += separator + "blend_support_hsl_hue";
    249             separator = ", ";
    250         }
    251         if (fFlags & kBlendSupportHSLSaturation_Flag) {
    252             result += separator + "blend_support_hsl_saturation";
    253             separator = ", ";
    254         }
    255         if (fFlags & kBlendSupportHSLColor_Flag) {
    256             result += separator + "blend_support_hsl_color";
    257             separator = ", ";
    258         }
    259         if (fFlags & kBlendSupportHSLLuminosity_Flag) {
    260             result += separator + "blend_support_hsl_luminosity";
    261             separator = ", ";
    262         }
    263         if (fFlags & kPushConstant_Flag) {
    264             result += separator + "push_constant";
    265             separator = ", ";
    266         }
    267         switch (fPrimitive) {
    268             case kPoints_Primitive:
    269                 result += separator + "points";
    270                 separator = ", ";
    271                 break;
    272             case kLines_Primitive:
    273                 result += separator + "lines";
    274                 separator = ", ";
    275                 break;
    276             case kLineStrip_Primitive:
    277                 result += separator + "line_strip";
    278                 separator = ", ";
    279                 break;
    280             case kLinesAdjacency_Primitive:
    281                 result += separator + "lines_adjacency";
    282                 separator = ", ";
    283                 break;
    284             case kTriangles_Primitive:
    285                 result += separator + "triangles";
    286                 separator = ", ";
    287                 break;
    288             case kTriangleStrip_Primitive:
    289                 result += separator + "triangle_strip";
    290                 separator = ", ";
    291                 break;
    292             case kTrianglesAdjacency_Primitive:
    293                 result += separator + "triangles_adjacency";
    294                 separator = ", ";
    295                 break;
    296             case kUnspecified_Primitive:
    297                 break;
    298         }
    299         if (fMaxVertices >= 0) {
    300             result += separator + "max_vertices = " + to_string(fMaxVertices);
    301             separator = ", ";
    302         }
    303         if (fInvocations >= 0) {
    304             result += separator + "invocations = " + to_string(fInvocations);
    305             separator = ", ";
    306         }
    307         if (fWhen.size()) {
    308             result += separator + "when = " + fWhen;
    309             separator = ", ";
    310         }
    311         if (result.size() > 0) {
    312             result = "layout (" + result + ")";
    313         }
    314         return result;
    315     }
    316 
    317     bool operator==(const Layout& other) const {
    318         return fFlags                == other.fFlags &&
    319                fLocation             == other.fLocation &&
    320                fOffset               == other.fOffset &&
    321                fBinding              == other.fBinding &&
    322                fIndex                == other.fIndex &&
    323                fSet                  == other.fSet &&
    324                fBuiltin              == other.fBuiltin &&
    325                fInputAttachmentIndex == other.fInputAttachmentIndex &&
    326                fFormat               == other.fFormat &&
    327                fPrimitive            == other.fPrimitive &&
    328                fMaxVertices          == other.fMaxVertices &&
    329                fInvocations          == other.fInvocations;
    330     }
    331 
    332     bool operator!=(const Layout& other) const {
    333         return !(*this == other);
    334     }
    335 
    336     int fFlags;
    337     int fLocation;
    338     int fOffset;
    339     int fBinding;
    340     int fIndex;
    341     int fSet;
    342     // builtin comes from SPIR-V and identifies which particular builtin value this object
    343     // represents.
    344     int fBuiltin;
    345     // input_attachment_index comes from Vulkan/SPIR-V to connect a shader variable to the a
    346     // corresponding attachment on the subpass in which the shader is being used.
    347     int fInputAttachmentIndex;
    348     Format fFormat;
    349     Primitive fPrimitive;
    350     int fMaxVertices;
    351     int fInvocations;
    352     String fWhen;
    353     Key fKey;
    354     StringFragment fCType;
    355 };
    356 
    357 } // namespace
    358 
    359 #endif
    360