зеркало из https://github.com/mozilla/gecko-dev.git
Bug 827106 - Cherry-pick ANGLE r1638 - r=jgilbert
This commit is contained in:
Родитель
7235347b03
Коммит
17599d2cd7
|
@ -12,6 +12,7 @@ TransGaming Inc.
|
|||
3DLabs Inc. Ltd.
|
||||
|
||||
Adobe Systems Inc.
|
||||
Apple Inc.
|
||||
Autodesk, Inc.
|
||||
Cloud Party, Inc.
|
||||
Intel Corporation
|
||||
|
|
|
@ -56,6 +56,7 @@ DEFINES += -DCOMPILER_IMPLEMENTATION
|
|||
VPATH += $(srcdir)/src/compiler
|
||||
# src/compiler:
|
||||
CPPSRCS += \
|
||||
ArrayBoundsClamper.cpp \
|
||||
BuiltInFunctionEmulator.cpp \
|
||||
Compiler.cpp \
|
||||
compiler_debug.cpp \
|
||||
|
|
|
@ -26,6 +26,10 @@ In this order:
|
|||
Adds emulation for faceforward(float,float,float), which is needed to
|
||||
prevent crashing on Mac+Intel. See bug 771406.
|
||||
|
||||
angle-r1638.patch
|
||||
Adds uniform array index clamping on non-Windows platforms.
|
||||
Windows would require r1719, r1733, r1734.
|
||||
|
||||
In addition to these patches, the Makefile.in files are ours, they're not present in
|
||||
upsteam ANGLE. Therefore, changes made to the Makefile.in files should not be stored
|
||||
in the local .patch files.
|
||||
|
|
|
@ -0,0 +1,475 @@
|
|||
# HG changeset patch
|
||||
# Parent faf255e4400222ee23c29ddcc76fb3dce56145f4
|
||||
|
||||
diff --git a/gfx/angle/AUTHORS b/gfx/angle/AUTHORS
|
||||
--- a/gfx/angle/AUTHORS
|
||||
+++ b/gfx/angle/AUTHORS
|
||||
@@ -7,16 +7,17 @@
|
||||
# Name or Organization
|
||||
# Email addresses for individuals are tracked elsewhere to avoid spam.
|
||||
|
||||
Google Inc.
|
||||
TransGaming Inc.
|
||||
3DLabs Inc. Ltd.
|
||||
|
||||
Adobe Systems Inc.
|
||||
+Apple Inc.
|
||||
Autodesk, Inc.
|
||||
Cloud Party, Inc.
|
||||
Intel Corporation
|
||||
Mozilla Corporation
|
||||
Turbulenz
|
||||
Klarälvdalens Datakonsult AB
|
||||
|
||||
Jacek Caban
|
||||
diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
|
||||
--- a/gfx/angle/Makefile.in
|
||||
+++ b/gfx/angle/Makefile.in
|
||||
@@ -51,16 +51,17 @@ LOCAL_INCLUDES += \
|
||||
-I$(srcdir)/include/KHR \
|
||||
-I$(srcdir)/src
|
||||
|
||||
DEFINES += -DCOMPILER_IMPLEMENTATION
|
||||
|
||||
VPATH += $(srcdir)/src/compiler
|
||||
# src/compiler:
|
||||
CPPSRCS += \
|
||||
+ ArrayBoundsClamper.cpp \
|
||||
BuiltInFunctionEmulator.cpp \
|
||||
Compiler.cpp \
|
||||
compiler_debug.cpp \
|
||||
DetectRecursion.cpp \
|
||||
Diagnostics.cpp \
|
||||
DirectiveHandler.cpp \
|
||||
ForLoopUnroll.cpp \
|
||||
glslang_lex.cpp \
|
||||
diff --git a/gfx/angle/README.mozilla b/gfx/angle/README.mozilla
|
||||
--- a/gfx/angle/README.mozilla
|
||||
+++ b/gfx/angle/README.mozilla
|
||||
@@ -21,16 +21,20 @@ In this order:
|
||||
|
||||
angle-long-ident-spooky-hash.patch:
|
||||
Use Spooky Hash for long identifier hashing. See bug 676071.
|
||||
|
||||
angle-faceforward-emu.patch:
|
||||
Adds emulation for faceforward(float,float,float), which is needed to
|
||||
prevent crashing on Mac+Intel. See bug 771406.
|
||||
|
||||
+ angle-r1638.patch
|
||||
+ Adds uniform array index clamping on non-Windows platforms.
|
||||
+ Windows would require r1719, r1733, r1734.
|
||||
+
|
||||
In addition to these patches, the Makefile.in files are ours, they're not present in
|
||||
upsteam ANGLE. Therefore, changes made to the Makefile.in files should not be stored
|
||||
in the local .patch files.
|
||||
|
||||
|
||||
== How to do a clean-slate upgrade ==
|
||||
1. Backup our moz-specific files:
|
||||
README.mozilla
|
||||
diff --git a/gfx/angle/include/GLSLANG/ShaderLang.h b/gfx/angle/include/GLSLANG/ShaderLang.h
|
||||
--- a/gfx/angle/include/GLSLANG/ShaderLang.h
|
||||
+++ b/gfx/angle/include/GLSLANG/ShaderLang.h
|
||||
@@ -145,17 +145,23 @@ typedef enum {
|
||||
// restrictions on fragment shaders.
|
||||
// This flag only has an effect if all of the following are true:
|
||||
// - The shader spec is SH_WEBGL_SPEC.
|
||||
// - The compile options contain the SH_TIMING_RESTRICTIONS flag.
|
||||
// - The shader type is SH_FRAGMENT_SHADER.
|
||||
SH_DEPENDENCY_GRAPH = 0x0400,
|
||||
|
||||
// Enforce the GLSL 1.017 Appendix A section 7 packing restrictions.
|
||||
- SH_ENFORCE_PACKING_RESTRICTIONS = 0x0800
|
||||
+ SH_ENFORCE_PACKING_RESTRICTIONS = 0x0800,
|
||||
+
|
||||
+ // This flag ensures all indirect (expression-based) array indexing
|
||||
+ // is clamped to the bounds of the array. This ensures, for example,
|
||||
+ // that you cannot read off the end of a uniform, whether an array
|
||||
+ // vec234, or mat234 type.
|
||||
+ SH_CLAMP_INDIRECT_ARRAY_BOUNDS = 0x1000
|
||||
} ShCompileOptions;
|
||||
|
||||
//
|
||||
// Driver must call this first, once, before doing any other
|
||||
// compiler operations.
|
||||
// If the function succeeds, the return value is nonzero, else zero.
|
||||
//
|
||||
COMPILER_EXPORT int ShInitialize();
|
||||
diff --git a/gfx/angle/src/build_angle.gypi b/gfx/angle/src/build_angle.gypi
|
||||
--- a/gfx/angle/src/build_angle.gypi
|
||||
+++ b/gfx/angle/src/build_angle.gypi
|
||||
@@ -54,16 +54,18 @@
|
||||
'include_dirs': [
|
||||
'.',
|
||||
'../include',
|
||||
],
|
||||
'defines': [
|
||||
'COMPILER_IMPLEMENTATION',
|
||||
],
|
||||
'sources': [
|
||||
+ 'compiler/ArrayBoundsClamper.cpp',
|
||||
+ 'compiler/ArrayBoundsClamper.h',
|
||||
'compiler/BaseTypes.h',
|
||||
'compiler/BuiltInFunctionEmulator.cpp',
|
||||
'compiler/BuiltInFunctionEmulator.h',
|
||||
'compiler/Common.h',
|
||||
'compiler/Compiler.cpp',
|
||||
'compiler/ConstantUnion.h',
|
||||
'compiler/debug.cpp',
|
||||
'compiler/debug.h',
|
||||
diff --git a/gfx/angle/src/compiler/Compiler.cpp b/gfx/angle/src/compiler/Compiler.cpp
|
||||
--- a/gfx/angle/src/compiler/Compiler.cpp
|
||||
+++ b/gfx/angle/src/compiler/Compiler.cpp
|
||||
@@ -1,14 +1,15 @@
|
||||
//
|
||||
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
+#include "compiler/ArrayBoundsClamper.h"
|
||||
#include "compiler/BuiltInFunctionEmulator.h"
|
||||
#include "compiler/DetectRecursion.h"
|
||||
#include "compiler/ForLoopUnroll.h"
|
||||
#include "compiler/Initialize.h"
|
||||
#include "compiler/InitializeParseContext.h"
|
||||
#include "compiler/MapLongVariableNames.h"
|
||||
#include "compiler/ParseHelper.h"
|
||||
#include "compiler/RenameFunction.h"
|
||||
@@ -187,16 +188,20 @@ bool TCompiler::compile(const char* cons
|
||||
// Unroll for-loop markup needs to happen after validateLimitations pass.
|
||||
if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX))
|
||||
ForLoopUnroll::MarkForLoopsWithIntegerIndicesForUnrolling(root);
|
||||
|
||||
// Built-in function emulation needs to happen after validateLimitations pass.
|
||||
if (success && (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS))
|
||||
builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(root);
|
||||
|
||||
+ // Clamping uniform array bounds needs to happen after validateLimitations pass.
|
||||
+ if (success && (compileOptions & SH_CLAMP_INDIRECT_ARRAY_BOUNDS))
|
||||
+ arrayBoundsClamper.MarkIndirectArrayBoundsForClamping(root);
|
||||
+
|
||||
// Call mapLongVariableNames() before collectAttribsUniforms() so in
|
||||
// collectAttribsUniforms() we already have the mapped symbol names and
|
||||
// we could composite mapped and original variable names.
|
||||
// Also, if we hash all the names, then no need to do this for long names.
|
||||
if (success && (compileOptions & SH_MAP_LONG_VARIABLE_NAMES) && hashFunction == NULL)
|
||||
mapLongVariableNames(root);
|
||||
|
||||
if (success && (compileOptions & SH_ATTRIBUTES_UNIFORMS)) {
|
||||
@@ -232,16 +237,17 @@ bool TCompiler::InitBuiltInSymbolTable(c
|
||||
|
||||
builtIns.initialize(shaderType, shaderSpec, resources);
|
||||
return InitializeSymbolTable(builtIns.getBuiltInStrings(),
|
||||
shaderType, shaderSpec, resources, infoSink, symbolTable);
|
||||
}
|
||||
|
||||
void TCompiler::clearResults()
|
||||
{
|
||||
+ arrayBoundsClamper.Cleanup();
|
||||
infoSink.info.erase();
|
||||
infoSink.obj.erase();
|
||||
infoSink.debug.erase();
|
||||
|
||||
attribs.clear();
|
||||
uniforms.clear();
|
||||
|
||||
builtInFunctionEmulator.Cleanup();
|
||||
@@ -348,8 +354,14 @@ const TExtensionBehavior& TCompiler::get
|
||||
{
|
||||
return extensionBehavior;
|
||||
}
|
||||
|
||||
const BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const
|
||||
{
|
||||
return builtInFunctionEmulator;
|
||||
}
|
||||
+
|
||||
+const ArrayBoundsClamper& TCompiler::getArrayBoundsClamper() const
|
||||
+{
|
||||
+ return arrayBoundsClamper;
|
||||
+}
|
||||
+
|
||||
diff --git a/gfx/angle/src/compiler/OutputGLSLBase.cpp b/gfx/angle/src/compiler/OutputGLSLBase.cpp
|
||||
--- a/gfx/angle/src/compiler/OutputGLSLBase.cpp
|
||||
+++ b/gfx/angle/src/compiler/OutputGLSLBase.cpp
|
||||
@@ -207,18 +207,47 @@ bool TOutputGLSLBase::visitBinary(Visit
|
||||
case EOpVectorTimesMatrixAssign:
|
||||
case EOpVectorTimesScalarAssign:
|
||||
case EOpMatrixTimesScalarAssign:
|
||||
case EOpMatrixTimesMatrixAssign:
|
||||
writeTriplet(visit, "(", " *= ", ")");
|
||||
break;
|
||||
|
||||
case EOpIndexDirect:
|
||||
+ writeTriplet(visit, NULL, "[", "]");
|
||||
+ break;
|
||||
case EOpIndexIndirect:
|
||||
- writeTriplet(visit, NULL, "[", "]");
|
||||
+ if (node->getAddIndexClamp())
|
||||
+ {
|
||||
+ if (visit == InVisit)
|
||||
+ {
|
||||
+ out << "[webgl_int_clamp(";
|
||||
+ }
|
||||
+ else if (visit == PostVisit)
|
||||
+ {
|
||||
+ int maxSize;
|
||||
+ TIntermTyped *left = node->getLeft();
|
||||
+ TType leftType = left->getType();
|
||||
+
|
||||
+ if (left->isArray())
|
||||
+ {
|
||||
+ // The shader will fail validation if the array length is not > 0.
|
||||
+ maxSize = leftType.getArraySize() - 1;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ maxSize = leftType.getNominalSize() - 1;
|
||||
+ }
|
||||
+ out << ", 0, " << maxSize << ")]";
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ writeTriplet(visit, NULL, "[", "]");
|
||||
+ }
|
||||
break;
|
||||
case EOpIndexDirectStruct:
|
||||
if (visit == InVisit)
|
||||
{
|
||||
out << ".";
|
||||
// TODO(alokp): ASSERT
|
||||
out << hashName(node->getType().getFieldName());
|
||||
visitChildren = false;
|
||||
diff --git a/gfx/angle/src/compiler/ShHandle.h b/gfx/angle/src/compiler/ShHandle.h
|
||||
--- a/gfx/angle/src/compiler/ShHandle.h
|
||||
+++ b/gfx/angle/src/compiler/ShHandle.h
|
||||
@@ -11,16 +11,17 @@
|
||||
// Machine independent part of the compiler private objects
|
||||
// sent as ShHandle to the driver.
|
||||
//
|
||||
// This should not be included by driver code.
|
||||
//
|
||||
|
||||
#include "GLSLANG/ShaderLang.h"
|
||||
|
||||
+#include "compiler/ArrayBoundsClamper.h"
|
||||
#include "compiler/BuiltInFunctionEmulator.h"
|
||||
#include "compiler/ExtensionBehavior.h"
|
||||
#include "compiler/HashNames.h"
|
||||
#include "compiler/InfoSink.h"
|
||||
#include "compiler/SymbolTable.h"
|
||||
#include "compiler/VariableInfo.h"
|
||||
|
||||
class LongNameMap;
|
||||
@@ -101,30 +102,32 @@ protected:
|
||||
// Returns true if the shader does not use samplers.
|
||||
bool enforceVertexShaderTimingRestrictions(TIntermNode* root);
|
||||
// Returns true if the shader does not use sampler dependent values to affect control
|
||||
// flow or in operations whose time can depend on the input values.
|
||||
bool enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph);
|
||||
// Get built-in extensions with default behavior.
|
||||
const TExtensionBehavior& getExtensionBehavior() const;
|
||||
|
||||
+ const ArrayBoundsClamper& getArrayBoundsClamper() const;
|
||||
const BuiltInFunctionEmulator& getBuiltInFunctionEmulator() const;
|
||||
|
||||
private:
|
||||
ShShaderType shaderType;
|
||||
ShShaderSpec shaderSpec;
|
||||
|
||||
int maxUniformVectors;
|
||||
|
||||
// Built-in symbol table for the given language, spec, and resources.
|
||||
// It is preserved from compile-to-compile.
|
||||
TSymbolTable symbolTable;
|
||||
// Built-in extensions with default behavior.
|
||||
TExtensionBehavior extensionBehavior;
|
||||
|
||||
+ ArrayBoundsClamper arrayBoundsClamper;
|
||||
BuiltInFunctionEmulator builtInFunctionEmulator;
|
||||
|
||||
// Results of compilation.
|
||||
TInfoSink infoSink; // Output sink.
|
||||
TVariableInfoList attribs; // Active attributes in the compiled shader.
|
||||
TVariableInfoList uniforms; // Active uniforms in the compiled shader.
|
||||
|
||||
// Cached copy of the ref-counted singleton.
|
||||
diff --git a/gfx/angle/src/compiler/TranslatorESSL.cpp b/gfx/angle/src/compiler/TranslatorESSL.cpp
|
||||
--- a/gfx/angle/src/compiler/TranslatorESSL.cpp
|
||||
+++ b/gfx/angle/src/compiler/TranslatorESSL.cpp
|
||||
@@ -17,16 +17,19 @@ void TranslatorESSL::translate(TIntermNo
|
||||
|
||||
// Write built-in extension behaviors.
|
||||
writeExtensionBehavior();
|
||||
|
||||
// Write emulated built-in functions if needed.
|
||||
getBuiltInFunctionEmulator().OutputEmulatedFunctionDefinition(
|
||||
sink, getShaderType() == SH_FRAGMENT_SHADER);
|
||||
|
||||
+ // Write array bounds clamping emulation if needed.
|
||||
+ getArrayBoundsClamper().OutputClampingFunctionDefinition(sink);
|
||||
+
|
||||
// Write translated shader.
|
||||
TOutputESSL outputESSL(sink, getHashFunction(), getNameMap(), getSymbolTable());
|
||||
root->traverse(&outputESSL);
|
||||
}
|
||||
|
||||
void TranslatorESSL::writeExtensionBehavior() {
|
||||
TInfoSinkBase& sink = getInfoSink().obj;
|
||||
const TExtensionBehavior& extensionBehavior = getExtensionBehavior();
|
||||
diff --git a/gfx/angle/src/compiler/TranslatorGLSL.cpp b/gfx/angle/src/compiler/TranslatorGLSL.cpp
|
||||
--- a/gfx/angle/src/compiler/TranslatorGLSL.cpp
|
||||
+++ b/gfx/angle/src/compiler/TranslatorGLSL.cpp
|
||||
@@ -30,12 +30,15 @@ void TranslatorGLSL::translate(TIntermNo
|
||||
|
||||
// Write GLSL version.
|
||||
writeVersion(getShaderType(), root, sink);
|
||||
|
||||
// Write emulated built-in functions if needed.
|
||||
getBuiltInFunctionEmulator().OutputEmulatedFunctionDefinition(
|
||||
sink, false);
|
||||
|
||||
+ // Write array bounds clamping emulation if needed.
|
||||
+ getArrayBoundsClamper().OutputClampingFunctionDefinition(sink);
|
||||
+
|
||||
// Write translated shader.
|
||||
TOutputGLSL outputGLSL(sink, getHashFunction(), getNameMap(), getSymbolTable());
|
||||
root->traverse(&outputGLSL);
|
||||
}
|
||||
diff --git a/gfx/angle/src/compiler/intermOut.cpp b/gfx/angle/src/compiler/intermOut.cpp
|
||||
--- a/gfx/angle/src/compiler/intermOut.cpp
|
||||
+++ b/gfx/angle/src/compiler/intermOut.cpp
|
||||
@@ -37,17 +37,17 @@ protected:
|
||||
|
||||
TString TType::getCompleteString() const
|
||||
{
|
||||
TStringStream stream;
|
||||
|
||||
if (qualifier != EvqTemporary && qualifier != EvqGlobal)
|
||||
stream << getQualifierString() << " " << getPrecisionString() << " ";
|
||||
if (array)
|
||||
- stream << "array of ";
|
||||
+ stream << "array[" << getArraySize() << "] of ";
|
||||
if (matrix)
|
||||
stream << size << "X" << size << " matrix of ";
|
||||
else if (size > 1)
|
||||
stream << size << "-component vector of ";
|
||||
|
||||
stream << getBasicString();
|
||||
return stream.str();
|
||||
}
|
||||
diff --git a/gfx/angle/src/compiler/intermediate.h b/gfx/angle/src/compiler/intermediate.h
|
||||
--- a/gfx/angle/src/compiler/intermediate.h
|
||||
+++ b/gfx/angle/src/compiler/intermediate.h
|
||||
@@ -386,30 +386,36 @@ protected:
|
||||
TOperator op;
|
||||
};
|
||||
|
||||
//
|
||||
// Nodes for all the basic binary math operators.
|
||||
//
|
||||
class TIntermBinary : public TIntermOperator {
|
||||
public:
|
||||
- TIntermBinary(TOperator o) : TIntermOperator(o) {}
|
||||
+ TIntermBinary(TOperator o) : TIntermOperator(o), addIndexClamp(false) {}
|
||||
|
||||
virtual TIntermBinary* getAsBinaryNode() { return this; }
|
||||
virtual void traverse(TIntermTraverser*);
|
||||
|
||||
void setLeft(TIntermTyped* n) { left = n; }
|
||||
void setRight(TIntermTyped* n) { right = n; }
|
||||
TIntermTyped* getLeft() const { return left; }
|
||||
TIntermTyped* getRight() const { return right; }
|
||||
bool promote(TInfoSink&);
|
||||
|
||||
+ void setAddIndexClamp() { addIndexClamp = true; }
|
||||
+ bool getAddIndexClamp() { return addIndexClamp; }
|
||||
+
|
||||
protected:
|
||||
TIntermTyped* left;
|
||||
TIntermTyped* right;
|
||||
+
|
||||
+ // If set to true, wrap any EOpIndexIndirect with a clamp to bounds.
|
||||
+ bool addIndexClamp;
|
||||
};
|
||||
|
||||
//
|
||||
// Nodes for unary math operators.
|
||||
//
|
||||
class TIntermUnary : public TIntermOperator {
|
||||
public:
|
||||
TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0), useEmulatedFunction(false) {}
|
||||
diff --git a/gfx/angle/src/compiler/translator_common.vcxproj b/gfx/angle/src/compiler/translator_common.vcxproj
|
||||
--- a/gfx/angle/src/compiler/translator_common.vcxproj
|
||||
+++ b/gfx/angle/src/compiler/translator_common.vcxproj
|
||||
@@ -133,16 +133,17 @@
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4267;4512;4702;4718;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
+ <ClCompile Include="ArrayBoundsClamper.cpp" />
|
||||
<ClCompile Include="BuiltInFunctionEmulator.cpp" />
|
||||
<ClCompile Include="Compiler.cpp" />
|
||||
<ClCompile Include="debug.cpp" />
|
||||
<ClCompile Include="DetectRecursion.cpp" />
|
||||
<ClCompile Include="Diagnostics.cpp" />
|
||||
<ClCompile Include="DirectiveHandler.cpp" />
|
||||
<ClCompile Include="ForLoopUnroll.cpp" />
|
||||
<ClCompile Include="InfoSink.cpp" />
|
||||
@@ -220,16 +221,17 @@
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(Outputs)</Outputs>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
+ <ClInclude Include="ArrayBoundsClamper.h" />
|
||||
<ClInclude Include="BaseTypes.h" />
|
||||
<ClInclude Include="BuiltInFunctionEmulator.h" />
|
||||
<ClInclude Include="Common.h" />
|
||||
<ClInclude Include="ConstantUnion.h" />
|
||||
<ClInclude Include="debug.h" />
|
||||
<ClInclude Include="DetectRecursion.h" />
|
||||
<ClInclude Include="Diagnostics.h" />
|
||||
<ClInclude Include="DirectiveHandler.h" />
|
||||
@@ -274,9 +276,9 @@
|
||||
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
|
||||
<LinkLibraryDependencies>true</LinkLibraryDependencies>
|
||||
<UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
-</Project>
|
||||
\ No newline at end of file
|
||||
+</Project>
|
||||
diff --git a/gfx/angle/src/libGLESv2/Makefile.in b/gfx/angle/src/libGLESv2/Makefile.in
|
||||
--- a/gfx/angle/src/libGLESv2/Makefile.in
|
||||
+++ b/gfx/angle/src/libGLESv2/Makefile.in
|
||||
@@ -64,16 +64,17 @@ LOCAL_INCLUDES = \
|
||||
-I$(srcdir)/../../include/KHR \
|
||||
-I$(srcdir)/..
|
||||
|
||||
DEFINES += -DCOMPILER_IMPLEMENTATION
|
||||
|
||||
VPATH += $(srcdir)/../compiler
|
||||
# src/compiler:
|
||||
CPPSRCS += \
|
||||
+ ArrayBoundsClamper.cpp \
|
||||
BuiltInFunctionEmulator.cpp \
|
||||
Compiler.cpp \
|
||||
compiler_debug.cpp \
|
||||
DetectRecursion.cpp \
|
||||
Diagnostics.cpp \
|
||||
DirectiveHandler.cpp \
|
||||
ForLoopUnroll.cpp \
|
||||
glslang_lex.cpp \
|
|
@ -150,7 +150,13 @@ typedef enum {
|
|||
SH_DEPENDENCY_GRAPH = 0x0400,
|
||||
|
||||
// Enforce the GLSL 1.017 Appendix A section 7 packing restrictions.
|
||||
SH_ENFORCE_PACKING_RESTRICTIONS = 0x0800
|
||||
SH_ENFORCE_PACKING_RESTRICTIONS = 0x0800,
|
||||
|
||||
// This flag ensures all indirect (expression-based) array indexing
|
||||
// is clamped to the bounds of the array. This ensures, for example,
|
||||
// that you cannot read off the end of a uniform, whether an array
|
||||
// vec234, or mat234 type.
|
||||
SH_CLAMP_INDIRECT_ARRAY_BOUNDS = 0x1000
|
||||
} ShCompileOptions;
|
||||
|
||||
//
|
||||
|
|
|
@ -59,6 +59,8 @@
|
|||
'COMPILER_IMPLEMENTATION',
|
||||
],
|
||||
'sources': [
|
||||
'compiler/ArrayBoundsClamper.cpp',
|
||||
'compiler/ArrayBoundsClamper.h',
|
||||
'compiler/BaseTypes.h',
|
||||
'compiler/BuiltInFunctionEmulator.cpp',
|
||||
'compiler/BuiltInFunctionEmulator.h',
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright (C) 2012 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE, INC. OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "compiler/ArrayBoundsClamper.h"
|
||||
|
||||
const char* kIntClampBegin = "// BEGIN: Generated code for array bounds clamping\n\n";
|
||||
const char* kIntClampEnd = "// END: Generated code for array bounds clamping\n\n";
|
||||
const char* kIntClampDefinition = "int webgl_int_clamp(int value, int minValue, int maxValue) { return ((value < minValue) ? minValue : ((value > maxValue) ? maxValue : value)); }\n\n";
|
||||
|
||||
namespace {
|
||||
|
||||
class ArrayBoundsClamperMarker : public TIntermTraverser {
|
||||
public:
|
||||
ArrayBoundsClamperMarker()
|
||||
: mNeedsClamp(false)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool visitBinary(Visit visit, TIntermBinary* node)
|
||||
{
|
||||
if (node->getOp() == EOpIndexIndirect)
|
||||
{
|
||||
TIntermTyped* left = node->getLeft();
|
||||
if (left->isArray() || left->isVector() || left->isMatrix())
|
||||
{
|
||||
node->setAddIndexClamp();
|
||||
mNeedsClamp = true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetNeedsClamp() { return mNeedsClamp; }
|
||||
|
||||
private:
|
||||
bool mNeedsClamp;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
ArrayBoundsClamper::ArrayBoundsClamper()
|
||||
: mArrayBoundsClampDefinitionNeeded(false)
|
||||
{
|
||||
}
|
||||
|
||||
void ArrayBoundsClamper::OutputClampingFunctionDefinition(TInfoSinkBase& out) const
|
||||
{
|
||||
if (!mArrayBoundsClampDefinitionNeeded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
out << kIntClampBegin << kIntClampDefinition << kIntClampEnd;
|
||||
}
|
||||
|
||||
void ArrayBoundsClamper::MarkIndirectArrayBoundsForClamping(TIntermNode* root)
|
||||
{
|
||||
ASSERT(root);
|
||||
|
||||
ArrayBoundsClamperMarker clamper;
|
||||
root->traverse(&clamper);
|
||||
if (clamper.GetNeedsClamp())
|
||||
{
|
||||
SetArrayBoundsClampDefinitionNeeded();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (C) 2012 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE, INC. OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef COMPILER_ARRAY_BOUNDS_CLAMPER_H_
|
||||
#define COMPILER_ARRAY_BOUNDS_CLAMPER_H_
|
||||
|
||||
#include "GLSLANG/ShaderLang.h"
|
||||
|
||||
#include "compiler/InfoSink.h"
|
||||
#include "compiler/intermediate.h"
|
||||
|
||||
class ArrayBoundsClamper {
|
||||
public:
|
||||
ArrayBoundsClamper();
|
||||
|
||||
// Output array clamp function source into the shader source.
|
||||
void OutputClampingFunctionDefinition(TInfoSinkBase& out) const;
|
||||
|
||||
// Marks nodes in the tree that index arrays indirectly as
|
||||
// requiring clamping.
|
||||
void MarkIndirectArrayBoundsForClamping(TIntermNode* root);
|
||||
|
||||
void Cleanup()
|
||||
{
|
||||
mArrayBoundsClampDefinitionNeeded = false;
|
||||
}
|
||||
|
||||
private:
|
||||
bool GetArrayBoundsClampDefinitionNeeded() const { return mArrayBoundsClampDefinitionNeeded; }
|
||||
void SetArrayBoundsClampDefinitionNeeded() { mArrayBoundsClampDefinitionNeeded = true; }
|
||||
|
||||
bool mArrayBoundsClampDefinitionNeeded;
|
||||
};
|
||||
|
||||
#endif // COMPILER_ARRAY_BOUNDS_CLAMPER_H_
|
|
@ -4,6 +4,7 @@
|
|||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#include "compiler/ArrayBoundsClamper.h"
|
||||
#include "compiler/BuiltInFunctionEmulator.h"
|
||||
#include "compiler/DetectRecursion.h"
|
||||
#include "compiler/ForLoopUnroll.h"
|
||||
|
@ -192,6 +193,10 @@ bool TCompiler::compile(const char* const shaderStrings[],
|
|||
if (success && (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS))
|
||||
builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(root);
|
||||
|
||||
// Clamping uniform array bounds needs to happen after validateLimitations pass.
|
||||
if (success && (compileOptions & SH_CLAMP_INDIRECT_ARRAY_BOUNDS))
|
||||
arrayBoundsClamper.MarkIndirectArrayBoundsForClamping(root);
|
||||
|
||||
// Call mapLongVariableNames() before collectAttribsUniforms() so in
|
||||
// collectAttribsUniforms() we already have the mapped symbol names and
|
||||
// we could composite mapped and original variable names.
|
||||
|
@ -237,6 +242,7 @@ bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources& resources)
|
|||
|
||||
void TCompiler::clearResults()
|
||||
{
|
||||
arrayBoundsClamper.Cleanup();
|
||||
infoSink.info.erase();
|
||||
infoSink.obj.erase();
|
||||
infoSink.debug.erase();
|
||||
|
@ -353,3 +359,9 @@ const BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const
|
|||
{
|
||||
return builtInFunctionEmulator;
|
||||
}
|
||||
|
||||
const ArrayBoundsClamper& TCompiler::getArrayBoundsClamper() const
|
||||
{
|
||||
return arrayBoundsClamper;
|
||||
}
|
||||
|
||||
|
|
|
@ -212,9 +212,38 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary* node)
|
|||
break;
|
||||
|
||||
case EOpIndexDirect:
|
||||
case EOpIndexIndirect:
|
||||
writeTriplet(visit, NULL, "[", "]");
|
||||
break;
|
||||
case EOpIndexIndirect:
|
||||
if (node->getAddIndexClamp())
|
||||
{
|
||||
if (visit == InVisit)
|
||||
{
|
||||
out << "[webgl_int_clamp(";
|
||||
}
|
||||
else if (visit == PostVisit)
|
||||
{
|
||||
int maxSize;
|
||||
TIntermTyped *left = node->getLeft();
|
||||
TType leftType = left->getType();
|
||||
|
||||
if (left->isArray())
|
||||
{
|
||||
// The shader will fail validation if the array length is not > 0.
|
||||
maxSize = leftType.getArraySize() - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxSize = leftType.getNominalSize() - 1;
|
||||
}
|
||||
out << ", 0, " << maxSize << ")]";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
writeTriplet(visit, NULL, "[", "]");
|
||||
}
|
||||
break;
|
||||
case EOpIndexDirectStruct:
|
||||
if (visit == InVisit)
|
||||
{
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "GLSLANG/ShaderLang.h"
|
||||
|
||||
#include "compiler/ArrayBoundsClamper.h"
|
||||
#include "compiler/BuiltInFunctionEmulator.h"
|
||||
#include "compiler/ExtensionBehavior.h"
|
||||
#include "compiler/HashNames.h"
|
||||
|
@ -106,6 +107,7 @@ protected:
|
|||
// Get built-in extensions with default behavior.
|
||||
const TExtensionBehavior& getExtensionBehavior() const;
|
||||
|
||||
const ArrayBoundsClamper& getArrayBoundsClamper() const;
|
||||
const BuiltInFunctionEmulator& getBuiltInFunctionEmulator() const;
|
||||
|
||||
private:
|
||||
|
@ -120,6 +122,7 @@ private:
|
|||
// Built-in extensions with default behavior.
|
||||
TExtensionBehavior extensionBehavior;
|
||||
|
||||
ArrayBoundsClamper arrayBoundsClamper;
|
||||
BuiltInFunctionEmulator builtInFunctionEmulator;
|
||||
|
||||
// Results of compilation.
|
||||
|
|
|
@ -22,6 +22,9 @@ void TranslatorESSL::translate(TIntermNode* root) {
|
|||
getBuiltInFunctionEmulator().OutputEmulatedFunctionDefinition(
|
||||
sink, getShaderType() == SH_FRAGMENT_SHADER);
|
||||
|
||||
// Write array bounds clamping emulation if needed.
|
||||
getArrayBoundsClamper().OutputClampingFunctionDefinition(sink);
|
||||
|
||||
// Write translated shader.
|
||||
TOutputESSL outputESSL(sink, getHashFunction(), getNameMap(), getSymbolTable());
|
||||
root->traverse(&outputESSL);
|
||||
|
|
|
@ -35,6 +35,9 @@ void TranslatorGLSL::translate(TIntermNode* root) {
|
|||
getBuiltInFunctionEmulator().OutputEmulatedFunctionDefinition(
|
||||
sink, false);
|
||||
|
||||
// Write array bounds clamping emulation if needed.
|
||||
getArrayBoundsClamper().OutputClampingFunctionDefinition(sink);
|
||||
|
||||
// Write translated shader.
|
||||
TOutputGLSL outputGLSL(sink, getHashFunction(), getNameMap(), getSymbolTable());
|
||||
root->traverse(&outputGLSL);
|
||||
|
|
|
@ -42,7 +42,7 @@ TString TType::getCompleteString() const
|
|||
if (qualifier != EvqTemporary && qualifier != EvqGlobal)
|
||||
stream << getQualifierString() << " " << getPrecisionString() << " ";
|
||||
if (array)
|
||||
stream << "array of ";
|
||||
stream << "array[" << getArraySize() << "] of ";
|
||||
if (matrix)
|
||||
stream << size << "X" << size << " matrix of ";
|
||||
else if (size > 1)
|
||||
|
|
|
@ -391,7 +391,7 @@ protected:
|
|||
//
|
||||
class TIntermBinary : public TIntermOperator {
|
||||
public:
|
||||
TIntermBinary(TOperator o) : TIntermOperator(o) {}
|
||||
TIntermBinary(TOperator o) : TIntermOperator(o), addIndexClamp(false) {}
|
||||
|
||||
virtual TIntermBinary* getAsBinaryNode() { return this; }
|
||||
virtual void traverse(TIntermTraverser*);
|
||||
|
@ -402,9 +402,15 @@ public:
|
|||
TIntermTyped* getRight() const { return right; }
|
||||
bool promote(TInfoSink&);
|
||||
|
||||
void setAddIndexClamp() { addIndexClamp = true; }
|
||||
bool getAddIndexClamp() { return addIndexClamp; }
|
||||
|
||||
protected:
|
||||
TIntermTyped* left;
|
||||
TIntermTyped* right;
|
||||
|
||||
// If set to true, wrap any EOpIndexIndirect with a clamp to bounds.
|
||||
bool addIndexClamp;
|
||||
};
|
||||
|
||||
//
|
||||
|
|
|
@ -138,6 +138,7 @@
|
|||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ArrayBoundsClamper.cpp" />
|
||||
<ClCompile Include="BuiltInFunctionEmulator.cpp" />
|
||||
<ClCompile Include="Compiler.cpp" />
|
||||
<ClCompile Include="debug.cpp" />
|
||||
|
@ -225,6 +226,7 @@
|
|||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ArrayBoundsClamper.h" />
|
||||
<ClInclude Include="BaseTypes.h" />
|
||||
<ClInclude Include="BuiltInFunctionEmulator.h" />
|
||||
<ClInclude Include="Common.h" />
|
||||
|
@ -279,4 +281,4 @@
|
|||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -69,6 +69,7 @@ DEFINES += -DCOMPILER_IMPLEMENTATION
|
|||
VPATH += $(srcdir)/../compiler
|
||||
# src/compiler:
|
||||
CPPSRCS += \
|
||||
ArrayBoundsClamper.cpp \
|
||||
BuiltInFunctionEmulator.cpp \
|
||||
Compiler.cpp \
|
||||
compiler_debug.cpp \
|
||||
|
|
Загрузка…
Ссылка в новой задаче