GL: Support clip and cull distance redeclarations
* Fixed gl_PerVertex qualifier string.
* Updated ValidateClipCullDistanceTraverser to output
redeclared array sizes and maximum constant indices.
* Made DeclarePerVertexBlocks available for non-Vulkan
outputs.
* Updated DeclarePerVertexBlocks to remove gl_ClipDistance
and gl_CullDistance redeclarations.
* Enabled DeclarePerVertexBlocks for ESSL output when
gl_ClipDistance or gl_CullDistance are redeclared.
* Updated ESSL output to use 3.10 shading language version,
when the context has GL_EXT_clip_cull_distance enabled.
* Updated ESSL output to enable GL_EXT_shader_io_blocks
when gl_ClipDistance or gl_CullDistance are redeclared.
* Updated extension exposure conditions.
* Fixed typos in ParseContext.
Bug: angleproject:7763
Change-Id: Ib87368a1953ad546a407d634d8b00f71cf92c40c
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4083705
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Alexey Knyazev <lexa.knyazev@gmail.com>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
diff --git a/src/compiler.gni b/src/compiler.gni
index a264c35..3d5edbf 100644
--- a/src/compiler.gni
+++ b/src/compiler.gni
@@ -131,6 +131,8 @@
"src/compiler/translator/tree_ops/ConvertUnsupportedConstructorsToFunctionCalls.h",
"src/compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.cpp",
"src/compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.h",
+ "src/compiler/translator/tree_ops/DeclarePerVertexBlocks.cpp",
+ "src/compiler/translator/tree_ops/DeclarePerVertexBlocks.h",
"src/compiler/translator/tree_ops/DeferGlobalInitializers.cpp",
"src/compiler/translator/tree_ops/DeferGlobalInitializers.h",
"src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.cpp",
@@ -343,8 +345,6 @@
"src/compiler/translator/OutputSPIRV.cpp",
"src/compiler/translator/OutputSPIRV.h",
"src/compiler/translator/TranslatorVulkan.cpp",
- "src/compiler/translator/tree_ops/vulkan/DeclarePerVertexBlocks.cpp",
- "src/compiler/translator/tree_ops/vulkan/DeclarePerVertexBlocks.h",
"src/compiler/translator/tree_ops/vulkan/EmulateAdvancedBlendEquations.cpp",
"src/compiler/translator/tree_ops/vulkan/EmulateAdvancedBlendEquations.h",
"src/compiler/translator/tree_ops/vulkan/EmulateDithering.cpp",
diff --git a/src/compiler/translator/BaseTypes.h b/src/compiler/translator/BaseTypes.h
index c99953e..8da1a95 100644
--- a/src/compiler/translator/BaseTypes.h
+++ b/src/compiler/translator/BaseTypes.h
@@ -1615,7 +1615,7 @@
case EvqPatchOut: return "patch out";
case EvqTessControlIn: return "in";
case EvqTessControlOut: return "out";
- case EvqPerVertexOut: return "gl_out";
+ case EvqPerVertexOut: return "out";
case EvqPatchVerticesIn: return "PatchVerticesIn";
case EvqTessLevelOuter: return "TessLevelOuter";
case EvqTessLevelInner: return "TessLevelInner";
diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp
index 2e5e335..92de5a9 100644
--- a/src/compiler/translator/Compiler.cpp
+++ b/src/compiler/translator/Compiler.cpp
@@ -841,11 +841,13 @@
return false;
}
- if (parseContext.isExtensionEnabled(TExtension::EXT_clip_cull_distance))
+ if (parseContext.isExtensionEnabled(TExtension::EXT_clip_cull_distance) ||
+ parseContext.isExtensionEnabled(TExtension::APPLE_clip_distance))
{
- if (!ValidateClipCullDistance(root, &mDiagnostics,
- mResources.MaxCombinedClipAndCullDistances,
- compileOptions.limitSimultaneousClipAndCullDistanceUsage))
+ if (!ValidateClipCullDistance(
+ root, &mDiagnostics, mResources.MaxCombinedClipAndCullDistances,
+ compileOptions.limitSimultaneousClipAndCullDistanceUsage, &mClipDistanceSize,
+ &mCullDistanceSize, &mClipDistanceMaxIndex, &mCullDistanceMaxIndex))
{
return false;
}
@@ -1436,6 +1438,11 @@
mNumViews = -1;
+ mClipDistanceSize = 0;
+ mCullDistanceSize = 0;
+ mClipDistanceMaxIndex = -1;
+ mCullDistanceMaxIndex = -1;
+
mGeometryShaderInputPrimitiveType = EptUndefined;
mGeometryShaderOutputPrimitiveType = EptUndefined;
mGeometryShaderInvocations = 0;
diff --git a/src/compiler/translator/Compiler.h b/src/compiler/translator/Compiler.h
index 8a87d5e..f209997 100644
--- a/src/compiler/translator/Compiler.h
+++ b/src/compiler/translator/Compiler.h
@@ -207,6 +207,21 @@
// it's expected to no longer transform.
void enableValidateNoMoreTransformations();
+ bool areClipDistanceOrCullDistanceRedeclared() const
+ {
+ return mClipDistanceSize != 0 || mCullDistanceSize != 0;
+ }
+
+ uint8_t getClipDistanceArraySize() const
+ {
+ return mClipDistanceSize ? mClipDistanceSize : (mClipDistanceMaxIndex + 1);
+ }
+
+ uint8_t getCullDistanceArraySize() const
+ {
+ return mCullDistanceSize ? mCullDistanceSize : (mCullDistanceMaxIndex + 1);
+ }
+
protected:
// Add emulated functions to the built-in function emulator.
virtual void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
@@ -339,6 +354,12 @@
// GL_OVR_multiview num_views.
int mNumViews;
+ // Track gl_ClipDistance / gl_CullDistance usage.
+ uint8_t mClipDistanceSize;
+ uint8_t mCullDistanceSize;
+ int8_t mClipDistanceMaxIndex;
+ int8_t mCullDistanceMaxIndex;
+
// geometry shader parameters.
int mGeometryShaderMaxVertices;
int mGeometryShaderInvocations;
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index 5878d50..46195be 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -4991,7 +4991,7 @@
if (field->name() == "gl_Position" || field->name() == "gl_PointSize" ||
field->name() == "gl_ClipDistance" || field->name() == "gl_CullDistance")
{
- // These builtins can be redifined only when used within a redefiend gl_PerVertex
+ // These builtins can be redefined only when used within a redefined gl_PerVertex
// block
if (interfaceBlock->name() != "gl_PerVertex")
{
diff --git a/src/compiler/translator/ParseContext.h b/src/compiler/translator/ParseContext.h
index 2397df9..b418216 100644
--- a/src/compiler/translator/ParseContext.h
+++ b/src/compiler/translator/ParseContext.h
@@ -612,10 +612,6 @@
TType type,
const TSourceLoc &line);
- void checkCombinedClipCullDistanceIsValid(const TSourceLoc &line,
- const ImmutableString &identifier,
- const int arraySize);
-
// Check texture offset is within range.
void checkSingleTextureOffset(const TSourceLoc &line,
const TConstantUnion *values,
diff --git a/src/compiler/translator/TranslatorESSL.cpp b/src/compiler/translator/TranslatorESSL.cpp
index a9b4ed4..58cda4e 100644
--- a/src/compiler/translator/TranslatorESSL.cpp
+++ b/src/compiler/translator/TranslatorESSL.cpp
@@ -10,6 +10,7 @@
#include "common/utilities.h"
#include "compiler/translator/BuiltInFunctionEmulatorGLSL.h"
#include "compiler/translator/OutputESSL.h"
+#include "compiler/translator/tree_ops/DeclarePerVertexBlocks.h"
#include "compiler/translator/tree_ops/RecordConstantPrecision.h"
namespace sh
@@ -35,10 +36,12 @@
TInfoSinkBase &sink = getInfoSink().obj;
int shaderVer = getShaderVersion(); // Frontend shader version.
- if (hasPixelLocalStorageUniforms() &&
- compileOptions.pls.type == ShPixelLocalStorageType::ImageLoadStore)
+ if ((shaderVer > 100 && getResources().EXT_clip_cull_distance) ||
+ (hasPixelLocalStorageUniforms() &&
+ compileOptions.pls.type == ShPixelLocalStorageType::ImageLoadStore))
{
- // The backend translator emits shader image code. Use a minimum version of 310.
+ // The backend translator emits interface blocks or shader image code.
+ // Use a minimum version of 310.
shaderVer = std::max(shaderVer, 310);
}
if (shaderVer > 100)
@@ -79,6 +82,17 @@
sink << "// END: Generated code for built-in function emulation\n\n";
}
+ if (getShaderType() == GL_VERTEX_SHADER)
+ {
+ // Move gl_ClipDistance and/or gl_CullDistance redeclarations to gl_PerVertex.
+ if (IsExtensionEnabled(getExtensionBehavior(), TExtension::EXT_clip_cull_distance) &&
+ areClipDistanceOrCullDistanceRedeclared() &&
+ !DeclarePerVertexBlocks(this, root, &getSymbolTable()))
+ {
+ return false;
+ }
+ }
+
if (getShaderType() == GL_FRAGMENT_SHADER)
{
EmitEarlyFragmentTestsGLSL(*this, sink);
@@ -178,6 +192,14 @@
ASSERT(compileOptions.emulateGLBaseVertexBaseInstance);
continue;
}
+ else if (iter->first == TExtension::EXT_clip_cull_distance &&
+ areClipDistanceOrCullDistanceRedeclared())
+ {
+ sink << "#extension GL_EXT_clip_cull_distance : " << GetBehaviorString(iter->second)
+ << "\n"
+ << "#extension GL_EXT_shader_io_blocks : " << GetBehaviorString(iter->second)
+ << "\n";
+ }
else if (iter->first == TExtension::ANGLE_shader_pixel_local_storage)
{
if (compileOptions.pls.type == ShPixelLocalStorageType::PixelLocalStorageEXT)
diff --git a/src/compiler/translator/TranslatorVulkan.cpp b/src/compiler/translator/TranslatorVulkan.cpp
index e415b9c..3af080d 100644
--- a/src/compiler/translator/TranslatorVulkan.cpp
+++ b/src/compiler/translator/TranslatorVulkan.cpp
@@ -19,6 +19,7 @@
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/OutputSPIRV.h"
#include "compiler/translator/StaticType.h"
+#include "compiler/translator/tree_ops/DeclarePerVertexBlocks.h"
#include "compiler/translator/tree_ops/MonomorphizeUnsupportedFunctions.h"
#include "compiler/translator/tree_ops/RecordConstantPrecision.h"
#include "compiler/translator/tree_ops/RemoveAtomicCounterBuiltins.h"
@@ -29,7 +30,6 @@
#include "compiler/translator/tree_ops/RewriteDfdy.h"
#include "compiler/translator/tree_ops/RewriteStructSamplers.h"
#include "compiler/translator/tree_ops/SeparateStructFromUniformDeclarations.h"
-#include "compiler/translator/tree_ops/vulkan/DeclarePerVertexBlocks.h"
#include "compiler/translator/tree_ops/vulkan/EmulateAdvancedBlendEquations.h"
#include "compiler/translator/tree_ops/vulkan/EmulateDithering.h"
#include "compiler/translator/tree_ops/vulkan/EmulateFragColorData.h"
diff --git a/src/compiler/translator/ValidateClipCullDistance.cpp b/src/compiler/translator/ValidateClipCullDistance.cpp
index 18fca2b..9b364b9 100644
--- a/src/compiler/translator/ValidateClipCullDistance.cpp
+++ b/src/compiler/translator/ValidateClipCullDistance.cpp
@@ -31,17 +31,21 @@
ValidateClipCullDistanceTraverser();
void validate(TDiagnostics *diagnostics,
const unsigned int maxCombinedClipAndCullDistances,
- const bool limitSimultaneousClipAndCullDistanceUsage);
+ const bool limitSimultaneousClipAndCullDistanceUsage,
+ uint8_t *clipDistanceSizeOut,
+ uint8_t *cullDistanceSizeOut,
+ int8_t *clipDistanceMaxIndexOut,
+ int8_t *cullDistanceMaxIndexOut);
private:
bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
bool visitBinary(Visit visit, TIntermBinary *node) override;
- unsigned int mClipDistanceSize;
- unsigned int mCullDistanceSize;
+ uint8_t mClipDistanceSize;
+ uint8_t mCullDistanceSize;
- unsigned int mMaxClipDistanceIndex;
- unsigned int mMaxCullDistanceIndex;
+ int8_t mMaxClipDistanceIndex;
+ int8_t mMaxCullDistanceIndex;
const TIntermSymbol *mClipDistance;
const TIntermSymbol *mCullDistance;
@@ -51,8 +55,8 @@
: TIntermTraverser(true, false, false),
mClipDistanceSize(0),
mCullDistanceSize(0),
- mMaxClipDistanceIndex(0),
- mMaxCullDistanceIndex(0),
+ mMaxClipDistanceIndex(-1),
+ mMaxCullDistanceIndex(-1),
mClipDistance(nullptr),
mCullDistance(nullptr)
{}
@@ -74,12 +78,12 @@
if (symbol->getName() == "gl_ClipDistance")
{
- mClipDistanceSize = symbol->getOutermostArraySize();
+ mClipDistanceSize = static_cast<uint8_t>(symbol->getOutermostArraySize());
mClipDistance = symbol;
}
else if (symbol->getName() == "gl_CullDistance")
{
- mCullDistanceSize = symbol->getOutermostArraySize();
+ mCullDistanceSize = static_cast<uint8_t>(symbol->getOutermostArraySize());
mCullDistance = symbol;
}
@@ -109,7 +113,7 @@
const TConstantUnion *constIdx = node->getRight()->getConstantValue();
if (constIdx)
{
- unsigned int idx = 0;
+ int idx = 0;
switch (constIdx->getType())
{
case EbtInt:
@@ -119,7 +123,7 @@
idx = constIdx->getUConst();
break;
case EbtFloat:
- idx = static_cast<unsigned int>(constIdx->getFConst());
+ idx = static_cast<int>(constIdx->getFConst());
break;
case EbtBool:
idx = constIdx->getBConst() ? 1 : 0;
@@ -133,7 +137,7 @@
{
if (idx > mMaxClipDistanceIndex)
{
- mMaxClipDistanceIndex = idx;
+ mMaxClipDistanceIndex = static_cast<int8_t>(idx);
if (!mClipDistance)
{
mClipDistance = left;
@@ -145,7 +149,7 @@
ASSERT(varName == "gl_CullDistance");
if (idx > mMaxCullDistanceIndex)
{
- mMaxCullDistanceIndex = idx;
+ mMaxCullDistanceIndex = static_cast<int8_t>(idx);
if (!mCullDistance)
{
mCullDistance = left;
@@ -160,7 +164,11 @@
void ValidateClipCullDistanceTraverser::validate(
TDiagnostics *diagnostics,
const unsigned int maxCombinedClipAndCullDistances,
- const bool limitSimultaneousClipAndCullDistanceUsage)
+ const bool limitSimultaneousClipAndCullDistanceUsage,
+ uint8_t *clipDistanceSizeOut,
+ uint8_t *cullDistanceSizeOut,
+ int8_t *clipDistanceMaxIndexOut,
+ int8_t *cullDistanceMaxIndexOut)
{
ASSERT(diagnostics);
@@ -196,6 +204,12 @@
"not be greater than 4.",
diagnostics);
}
+
+ // Update the compiler state
+ *clipDistanceSizeOut = mClipDistanceSize;
+ *cullDistanceSizeOut = mCullDistanceSize;
+ *clipDistanceMaxIndexOut = mMaxClipDistanceIndex;
+ *cullDistanceMaxIndexOut = mMaxCullDistanceIndex;
}
} // anonymous namespace
@@ -203,13 +217,18 @@
bool ValidateClipCullDistance(TIntermBlock *root,
TDiagnostics *diagnostics,
const unsigned int maxCombinedClipAndCullDistances,
- const bool limitSimultaneousClipAndCullDistanceUsage)
+ const bool limitSimultaneousClipAndCullDistanceUsage,
+ uint8_t *clipDistanceSizeOut,
+ uint8_t *cullDistanceSizeOut,
+ int8_t *clipDistanceMaxIndexOut,
+ int8_t *cullDistanceMaxIndexOut)
{
ValidateClipCullDistanceTraverser varyingValidator;
root->traverse(&varyingValidator);
int numErrorsBefore = diagnostics->numErrors();
- varyingValidator.validate(diagnostics, maxCombinedClipAndCullDistances,
- limitSimultaneousClipAndCullDistanceUsage);
+ varyingValidator.validate(
+ diagnostics, maxCombinedClipAndCullDistances, limitSimultaneousClipAndCullDistanceUsage,
+ clipDistanceSizeOut, cullDistanceSizeOut, clipDistanceMaxIndexOut, cullDistanceMaxIndexOut);
return (diagnostics->numErrors() == numErrorsBefore);
}
diff --git a/src/compiler/translator/ValidateClipCullDistance.h b/src/compiler/translator/ValidateClipCullDistance.h
index 2e63e6c..2be74fa 100644
--- a/src/compiler/translator/ValidateClipCullDistance.h
+++ b/src/compiler/translator/ValidateClipCullDistance.h
@@ -21,7 +21,11 @@
bool ValidateClipCullDistance(TIntermBlock *root,
TDiagnostics *diagnostics,
const unsigned int maxCombinedClipAndCullDistances,
- const bool limitSimultaneousClipAndCullDistanceUsage);
+ const bool limitSimultaneousClipAndCullDistanceUsage,
+ uint8_t *clipDistanceSizeOut,
+ uint8_t *cullDistanceSizeOut,
+ int8_t *clipDistanceMaxIndexOut,
+ int8_t *cullDistanceMaxIndexOut);
} // namespace sh
diff --git a/src/compiler/translator/tree_ops/vulkan/DeclarePerVertexBlocks.cpp b/src/compiler/translator/tree_ops/DeclarePerVertexBlocks.cpp
similarity index 84%
rename from src/compiler/translator/tree_ops/vulkan/DeclarePerVertexBlocks.cpp
rename to src/compiler/translator/tree_ops/DeclarePerVertexBlocks.cpp
index 45fd094..90f2fe0 100644
--- a/src/compiler/translator/tree_ops/vulkan/DeclarePerVertexBlocks.cpp
+++ b/src/compiler/translator/tree_ops/DeclarePerVertexBlocks.cpp
@@ -6,7 +6,7 @@
// DeclarePerVertexBlocks: Declare gl_PerVertex blocks if not already.
//
-#include "compiler/translator/tree_ops/vulkan/DeclarePerVertexBlocks.h"
+#include "compiler/translator/tree_ops/DeclarePerVertexBlocks.h"
#include "compiler/translator/Compiler.h"
#include "compiler/translator/ImmutableStringBuilder.h"
@@ -45,23 +45,18 @@
// Traverser that:
//
-// 1. Inspects global qualifier declarations and extracts whether any of the gl_PerVertex built-ins
-// are invariant or precise. These declarations are then dropped.
-// 2. Finds the array size of gl_ClipDistance and gl_CullDistance built-in, if any.
+// Inspects global qualifier declarations and extracts whether any of the gl_PerVertex built-ins
+// are invariant or precise. These declarations are then dropped.
class InspectPerVertexBuiltInsTraverser : public TIntermTraverser
{
public:
InspectPerVertexBuiltInsTraverser(TCompiler *compiler,
TSymbolTable *symbolTable,
PerVertexMemberFlags *invariantFlagsOut,
- PerVertexMemberFlags *preciseFlagsOut,
- uint32_t *clipDistanceArraySizeOut,
- uint32_t *cullDistanceArraySizeOut)
+ PerVertexMemberFlags *preciseFlagsOut)
: TIntermTraverser(true, false, false, symbolTable),
mInvariantFlagsOut(invariantFlagsOut),
- mPreciseFlagsOut(preciseFlagsOut),
- mClipDistanceArraySizeOut(clipDistanceArraySizeOut),
- mCullDistanceArraySizeOut(cullDistanceArraySizeOut)
+ mPreciseFlagsOut(preciseFlagsOut)
{}
bool visitGlobalQualifierDeclaration(Visit visit,
@@ -90,27 +85,35 @@
return false;
}
- void visitSymbol(TIntermSymbol *symbol) override
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
{
+ const TIntermSequence &sequence = *(node->getSequence());
+
+ ASSERT(sequence.size() == 1);
+
+ const TIntermSymbol *symbol = sequence.front()->getAsSymbolNode();
+ if (symbol == nullptr)
+ {
+ return true;
+ }
+
const TType &type = symbol->getType();
switch (type.getQualifier())
{
case EvqClipDistance:
- *mClipDistanceArraySizeOut = type.getOutermostArraySize();
- break;
case EvqCullDistance:
- *mCullDistanceArraySizeOut = type.getOutermostArraySize();
break;
default:
- break;
+ return true;
}
+
+ mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), node, TIntermSequence());
+ return true;
}
private:
PerVertexMemberFlags *mInvariantFlagsOut;
PerVertexMemberFlags *mPreciseFlagsOut;
- uint32_t *mClipDistanceArraySizeOut;
- uint32_t *mCullDistanceArraySizeOut;
};
// Traverser that:
@@ -125,8 +128,8 @@
TSymbolTable *symbolTable,
const PerVertexMemberFlags &invariantFlags,
const PerVertexMemberFlags &preciseFlags,
- uint32_t clipDistanceArraySize,
- uint32_t cullDistanceArraySize)
+ uint8_t clipDistanceArraySize,
+ uint8_t cullDistanceArraySize)
: TIntermTraverser(true, false, false, symbolTable),
mShaderType(compiler->getShaderType()),
mShaderVersion(compiler->getShaderVersion()),
@@ -242,7 +245,7 @@
return;
}
- const int fieldIndex = GetPerVertexFieldIndex(type->getQualifier(), variable->name());
+ int fieldIndex = GetPerVertexFieldIndex(type->getQualifier(), variable->name());
// Not the built-in we are looking for.
if (fieldIndex < 0)
@@ -250,6 +253,12 @@
return;
}
+ // If gl_ClipDistance is not used, it will be skipped and gl_CullDistance will have index 2.
+ if (fieldIndex == 3 && mClipDistanceArraySize == 0)
+ {
+ fieldIndex = 2;
+ }
+
// Declare the output gl_PerVertex if not already.
if (mPerVertexOutVar == nullptr)
{
@@ -326,13 +335,15 @@
TType *positionType = new TType(*vec4Type);
TType *pointSizeType = new TType(*floatType);
- TType *clipDistanceType = new TType(*floatType);
- TType *cullDistanceType = new TType(*floatType);
+ TType *clipDistanceType = mClipDistanceArraySize ? new TType(*floatType) : nullptr;
+ TType *cullDistanceType = mCullDistanceArraySize ? new TType(*floatType) : nullptr;
positionType->setQualifier(EvqPosition);
pointSizeType->setQualifier(EvqPointSize);
- clipDistanceType->setQualifier(EvqClipDistance);
- cullDistanceType->setQualifier(EvqCullDistance);
+ if (clipDistanceType)
+ clipDistanceType->setQualifier(EvqClipDistance);
+ if (cullDistanceType)
+ cullDistanceType->setQualifier(EvqCullDistance);
TPrecision pointSizePrecision = EbpHigh;
if (mShaderType == GL_VERTEX_SHADER)
@@ -349,30 +360,38 @@
// TODO: handle interaction with GS and T*S where the two can have different sizes. These
// values are valid for EvqPerVertexOut only. For EvqPerVertexIn, the size should come from
// the declaration of gl_in. http://anglebug.com/5466.
- clipDistanceType->makeArray(std::max(mClipDistanceArraySize, 1u));
- cullDistanceType->makeArray(std::max(mCullDistanceArraySize, 1u));
+ if (clipDistanceType)
+ clipDistanceType->makeArray(mClipDistanceArraySize);
+ if (cullDistanceType)
+ cullDistanceType->makeArray(mCullDistanceArraySize);
if (qualifier == EvqPerVertexOut)
{
positionType->setInvariant(mPerVertexOutInvariantFlags[0]);
pointSizeType->setInvariant(mPerVertexOutInvariantFlags[1]);
- clipDistanceType->setInvariant(mPerVertexOutInvariantFlags[2]);
- cullDistanceType->setInvariant(mPerVertexOutInvariantFlags[3]);
+ if (clipDistanceType)
+ clipDistanceType->setInvariant(mPerVertexOutInvariantFlags[2]);
+ if (cullDistanceType)
+ cullDistanceType->setInvariant(mPerVertexOutInvariantFlags[3]);
positionType->setPrecise(mPerVertexOutPreciseFlags[0]);
pointSizeType->setPrecise(mPerVertexOutPreciseFlags[1]);
- clipDistanceType->setPrecise(mPerVertexOutPreciseFlags[2]);
- cullDistanceType->setPrecise(mPerVertexOutPreciseFlags[3]);
+ if (clipDistanceType)
+ clipDistanceType->setPrecise(mPerVertexOutPreciseFlags[2]);
+ if (cullDistanceType)
+ cullDistanceType->setPrecise(mPerVertexOutPreciseFlags[3]);
}
fields->push_back(new TField(positionType, ImmutableString("gl_Position"), TSourceLoc(),
SymbolType::AngleInternal));
fields->push_back(new TField(pointSizeType, ImmutableString("gl_PointSize"), TSourceLoc(),
SymbolType::AngleInternal));
- fields->push_back(new TField(clipDistanceType, ImmutableString("gl_ClipDistance"),
- TSourceLoc(), SymbolType::AngleInternal));
- fields->push_back(new TField(cullDistanceType, ImmutableString("gl_CullDistance"),
- TSourceLoc(), SymbolType::AngleInternal));
+ if (clipDistanceType)
+ fields->push_back(new TField(clipDistanceType, ImmutableString("gl_ClipDistance"),
+ TSourceLoc(), SymbolType::AngleInternal));
+ if (cullDistanceType)
+ fields->push_back(new TField(cullDistanceType, ImmutableString("gl_CullDistance"),
+ TSourceLoc(), SymbolType::AngleInternal));
TInterfaceBlock *interfaceBlock =
new TInterfaceBlock(mSymbolTable, ImmutableString("gl_PerVertex"), fields,
@@ -433,8 +452,8 @@
GLenum mShaderType;
int mShaderVersion;
const ShBuiltInResources &mResources;
- uint32_t mClipDistanceArraySize;
- uint32_t mCullDistanceArraySize;
+ uint8_t mClipDistanceArraySize;
+ uint8_t mCullDistanceArraySize;
const TVariable *mPerVertexInVar;
const TVariable *mPerVertexOutVar;
@@ -479,30 +498,18 @@
}
// First, visit all global qualifier declarations and find which built-ins are invariant or
- // precise. At the same time, find out the size of gl_ClipDistance and gl_CullDistance arrays.
+ // precise. At the same time, remove gl_ClipDistance and gl_CullDistance array redeclarations.
PerVertexMemberFlags invariantFlags = {};
PerVertexMemberFlags preciseFlags = {};
- uint32_t clipDistanceArraySize = 0, cullDistanceArraySize = 0;
InspectPerVertexBuiltInsTraverser infoTraverser(compiler, symbolTable, &invariantFlags,
- &preciseFlags, &clipDistanceArraySize,
- &cullDistanceArraySize);
+ &preciseFlags);
root->traverse(&infoTraverser);
if (!infoTraverser.updateTree(compiler, root))
{
return false;
}
- // If not specified, take the clip/cull distance size from the resources.
- if (clipDistanceArraySize == 0)
- {
- clipDistanceArraySize = compiler->getResources().MaxClipDistances;
- }
- if (cullDistanceArraySize == 0)
- {
- cullDistanceArraySize = compiler->getResources().MaxCullDistances;
- }
-
// If #pragma STDGL invariant(all) is specified, make all outputs invariant.
if (compiler->getPragma().stdgl.invariantAll)
{
@@ -511,7 +518,8 @@
// Then declare the in and out gl_PerVertex I/O blocks.
DeclarePerVertexBlocksTraverser traverser(compiler, symbolTable, invariantFlags, preciseFlags,
- clipDistanceArraySize, cullDistanceArraySize);
+ compiler->getClipDistanceArraySize(),
+ compiler->getCullDistanceArraySize());
root->traverse(&traverser);
if (!traverser.updateTree(compiler, root))
{
diff --git a/src/compiler/translator/tree_ops/vulkan/DeclarePerVertexBlocks.h b/src/compiler/translator/tree_ops/DeclarePerVertexBlocks.h
similarity index 71%
rename from src/compiler/translator/tree_ops/vulkan/DeclarePerVertexBlocks.h
rename to src/compiler/translator/tree_ops/DeclarePerVertexBlocks.h
index 2ec5e58..4c90deb 100644
--- a/src/compiler/translator/tree_ops/vulkan/DeclarePerVertexBlocks.h
+++ b/src/compiler/translator/tree_ops/DeclarePerVertexBlocks.h
@@ -3,12 +3,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
-// DeclarePerVertexBlocks: If gl_PerVertex is not already declared, it is declared and builts are
+// DeclarePerVertexBlocks: If gl_PerVertex is not already declared, it is declared and builtins are
// turned into references into that I/O block.
//
-#ifndef COMPILER_TRANSLATOR_TREEOPS_VULKAN_DECLAREPERVERTEXBLOCKS_H_
-#define COMPILER_TRANSLATOR_TREEOPS_VULKAN_DECLAREPERVERTEXBLOCKS_H_
+#ifndef COMPILER_TRANSLATOR_TREEOPS_DECLAREPERVERTEXBLOCKS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_DECLAREPERVERTEXBLOCKS_H_
#include "common/angleutils.h"
@@ -23,4 +23,4 @@
TSymbolTable *symbolTable);
} // namespace sh
-#endif // COMPILER_TRANSLATOR_TREEOPS_VULKAN_DECLAREPERVERTEXBLOCKS_H_
+#endif // COMPILER_TRANSLATOR_TREEOPS_DECLAREPERVERTEXBLOCKS_H_
diff --git a/src/libANGLE/renderer/gl/renderergl_utils.cpp b/src/libANGLE/renderer/gl/renderergl_utils.cpp
index d6ad40e..6911247 100644
--- a/src/libANGLE/renderer/gl/renderergl_utils.cpp
+++ b/src/libANGLE/renderer/gl/renderergl_utils.cpp
@@ -1941,12 +1941,14 @@
caps->maxClipDistances = QuerySingleGLInt(functions, GL_MAX_CLIP_DISTANCES_APPLE);
}
- // GL_EXT_clip_cull_distance
+ // GL_EXT_clip_cull_distance spec requires shader interface blocks to support
+ // built-in array redeclarations on OpenGL ES.
extensions->clipCullDistanceEXT = !features.disableClipCullDistance.enabled &&
- ((functions->isAtLeastGL(gl::Version(3, 0)) &&
+ (functions->isAtLeastGL(gl::Version(4, 5)) ||
+ (functions->isAtLeastGL(gl::Version(3, 0)) &&
functions->hasGLExtension("GL_ARB_cull_distance")) ||
- functions->isAtLeastGL(gl::Version(4, 5)) ||
- functions->hasGLESExtension("GL_EXT_clip_cull_distance"));
+ (extensions->shaderIoBlocksEXT &&
+ functions->hasGLESExtension("GL_EXT_clip_cull_distance")));
if (extensions->clipCullDistanceEXT)
{
caps->maxClipDistances = QuerySingleGLInt(functions, GL_MAX_CLIP_DISTANCES_EXT);