GrGLSLVarying.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*
  2. * Copyright 2015 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. #ifndef GrGLSLVarying_DEFINED
  8. #define GrGLSLVarying_DEFINED
  9. #include "include/private/GrTypesPriv.h"
  10. #include "src/gpu/GrAllocator.h"
  11. #include "src/gpu/GrGeometryProcessor.h"
  12. #include "src/gpu/GrShaderVar.h"
  13. #include "src/gpu/glsl/GrGLSLProgramDataManager.h"
  14. class GrGLSLProgramBuilder;
  15. #ifdef SK_DEBUG
  16. static bool is_matrix(GrSLType type) {
  17. switch (type) {
  18. case kFloat2x2_GrSLType:
  19. case kFloat3x3_GrSLType:
  20. case kFloat4x4_GrSLType:
  21. case kHalf2x2_GrSLType:
  22. case kHalf3x3_GrSLType:
  23. case kHalf4x4_GrSLType:
  24. return true;
  25. default:
  26. return false;
  27. }
  28. }
  29. #endif
  30. class GrGLSLVarying {
  31. public:
  32. enum class Scope {
  33. kVertToFrag,
  34. kVertToGeo,
  35. kGeoToFrag
  36. };
  37. GrGLSLVarying() = default;
  38. GrGLSLVarying(GrSLType type, Scope scope = Scope::kVertToFrag)
  39. : fType(type)
  40. , fScope(scope) {
  41. // Metal doesn't support varying matrices, so we disallow them everywhere for consistency
  42. SkASSERT(!is_matrix(type));
  43. }
  44. void reset(GrSLType type, Scope scope = Scope::kVertToFrag) {
  45. // Metal doesn't support varying matrices, so we disallow them everywhere for consistency
  46. SkASSERT(!is_matrix(type));
  47. *this = GrGLSLVarying();
  48. fType = type;
  49. fScope = scope;
  50. }
  51. GrSLType type() const { return fType; }
  52. Scope scope() const { return fScope; }
  53. bool isInVertexShader() const { return Scope::kGeoToFrag != fScope; }
  54. bool isInFragmentShader() const { return Scope::kVertToGeo != fScope; }
  55. const char* vsOut() const { SkASSERT(this->isInVertexShader()); return fVsOut; }
  56. const char* gsIn() const { return fGsIn; }
  57. const char* gsOut() const { return fGsOut; }
  58. const char* fsIn() const { SkASSERT(this->isInFragmentShader()); return fFsIn; }
  59. private:
  60. GrSLType fType = kVoid_GrSLType;
  61. Scope fScope = Scope::kVertToFrag;
  62. const char* fVsOut = nullptr;
  63. const char* fGsIn = nullptr;
  64. const char* fGsOut = nullptr;
  65. const char* fFsIn = nullptr;
  66. friend class GrGLSLVaryingHandler;
  67. };
  68. static const int kVaryingsPerBlock = 8;
  69. class GrGLSLVaryingHandler {
  70. public:
  71. explicit GrGLSLVaryingHandler(GrGLSLProgramBuilder* program)
  72. : fVaryings(kVaryingsPerBlock)
  73. , fVertexInputs(kVaryingsPerBlock)
  74. , fVertexOutputs(kVaryingsPerBlock)
  75. , fGeomInputs(kVaryingsPerBlock)
  76. , fGeomOutputs(kVaryingsPerBlock)
  77. , fFragInputs(kVaryingsPerBlock)
  78. , fFragOutputs(kVaryingsPerBlock)
  79. , fProgramBuilder(program)
  80. , fDefaultInterpolationModifier(nullptr) {}
  81. virtual ~GrGLSLVaryingHandler() {}
  82. /*
  83. * Notifies the varying handler that this shader will never emit geometry in perspective and
  84. * therefore does not require perspective-correct interpolation. When supported, this allows
  85. * varyings to use the "noperspective" keyword, which means the GPU can use cheaper math for
  86. * interpolation.
  87. */
  88. void setNoPerspective();
  89. enum class Interpolation {
  90. kInterpolated,
  91. kCanBeFlat, // Use "flat" if it will be faster.
  92. kMustBeFlat // Use "flat" even if it is known to be slow.
  93. };
  94. /*
  95. * addVarying allows fine grained control for setting up varyings between stages. Calling this
  96. * function will make sure all necessary decls are setup for the client. The client however is
  97. * responsible for setting up all shader code (e.g "vOut = vIn;") If you just need to take an
  98. * attribute and pass it through to an output value in a fragment shader, use
  99. * addPassThroughAttribute.
  100. * TODO convert most uses of addVarying to addPassThroughAttribute
  101. */
  102. void addVarying(const char* name, GrGLSLVarying* varying,
  103. Interpolation = Interpolation::kInterpolated);
  104. /*
  105. * The GP can use these calls to pass an attribute through all shaders directly to 'output' in
  106. * the fragment shader. Though these calls affect both the vertex shader and fragment shader,
  107. * they expect 'output' to be defined in the fragment shader before the call is made. If there
  108. * is a geometry shader, we will simply take the value of the varying from the first vertex and
  109. * that will be set as the output varying for all emitted vertices.
  110. * TODO it might be nicer behavior to have a flag to declare output inside these calls
  111. */
  112. void addPassThroughAttribute(const GrGeometryProcessor::Attribute&, const char* output,
  113. Interpolation = Interpolation::kInterpolated);
  114. void emitAttributes(const GrGeometryProcessor& gp);
  115. // This should be called once all attributes and varyings have been added to the
  116. // GrGLSLVaryingHanlder and before getting/adding any of the declarations to the shaders.
  117. void finalize();
  118. void getVertexDecls(SkString* inputDecls, SkString* outputDecls) const;
  119. void getGeomDecls(SkString* inputDecls, SkString* outputDecls) const;
  120. void getFragDecls(SkString* inputDecls, SkString* outputDecls) const;
  121. protected:
  122. struct VaryingInfo {
  123. GrSLType fType;
  124. bool fIsFlat;
  125. SkString fVsOut;
  126. SkString fGsOut;
  127. GrShaderFlags fVisibility;
  128. };
  129. typedef GrTAllocator<VaryingInfo> VaryingList;
  130. typedef GrTAllocator<GrShaderVar> VarArray;
  131. typedef GrGLSLProgramDataManager::VaryingHandle VaryingHandle;
  132. VaryingList fVaryings;
  133. VarArray fVertexInputs;
  134. VarArray fVertexOutputs;
  135. VarArray fGeomInputs;
  136. VarArray fGeomOutputs;
  137. VarArray fFragInputs;
  138. VarArray fFragOutputs;
  139. // This is not owned by the class
  140. GrGLSLProgramBuilder* fProgramBuilder;
  141. private:
  142. void addAttribute(const GrShaderVar& var);
  143. virtual void onFinalize() = 0;
  144. // helper function for get*Decls
  145. void appendDecls(const VarArray& vars, SkString* out) const;
  146. const char* fDefaultInterpolationModifier;
  147. friend class GrGLSLProgramBuilder;
  148. };
  149. #endif