Diff
Modified: trunk/LayoutTests/ChangeLog (131932 => 131933)
--- trunk/LayoutTests/ChangeLog 2012-10-19 19:34:57 UTC (rev 131932)
+++ trunk/LayoutTests/ChangeLog 2012-10-19 19:45:03 UTC (rev 131933)
@@ -1,3 +1,15 @@
+2012-10-18 Dean Jackson <[email protected]>
+
+ Shader translator needs option to clamp uniform array accesses in vertex shaders
+ https://bugs.webkit.org/show_bug.cgi?id=98977
+ https://code.google.com/p/angleproject/issues/detail?id=49
+
+ Reviewed by Alok Priyadarshi and Ken Russell.
+
+ * fast/canvas/webgl/array-bounds-clamping-expected.txt: Added.
+ * fast/canvas/webgl/array-bounds-clamping.html: Added.
+ * platform/chromium/TestExpectations: Won't pass on Chromium until this patch is upstreamed.
+
2012-09-08 Alpha Lam <[email protected]>
[chromium] Implement deferred image decoding
Added: trunk/LayoutTests/fast/canvas/webgl/array-bounds-clamping-expected.txt (0 => 131933)
--- trunk/LayoutTests/fast/canvas/webgl/array-bounds-clamping-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/canvas/webgl/array-bounds-clamping-expected.txt 2012-10-19 19:45:03 UTC (rev 131933)
@@ -0,0 +1,12 @@
+ Checks that array access in a shader can not read out of bounds
+
+PASS Top left corner should clamp to index 0
+PASS Inside top right corner should clamp to index 0
+PASS Inside bottom left corner should clamp to index 0
+PASS Bottom right corner should clamp to index 7
+PASS Outside bottom left corner should clamp to index 7
+PASS Outside top right corner should clamp to index 7
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Property changes on: trunk/LayoutTests/fast/canvas/webgl/array-bounds-clamping-expected.txt
___________________________________________________________________
Added: svn:mime-type
Added: svn:keywords
Added: svn:eol-style
Added: trunk/LayoutTests/fast/canvas/webgl/array-bounds-clamping.html (0 => 131933)
--- trunk/LayoutTests/fast/canvas/webgl/array-bounds-clamping.html (rev 0)
+++ trunk/LayoutTests/fast/canvas/webgl/array-bounds-clamping.html 2012-10-19 19:45:03 UTC (rev 131933)
@@ -0,0 +1,106 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<title>WebGL array bounds clamping conformance test.</title>
+<script src=""
+<script src="" </script>
+</head>
+<body>
+<canvas id="example" width="40" height="40" style="width: 40px; height: 40px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vPosition;
+attribute float index;
+uniform float shades[8];
+varying vec4 texColor;
+void main()
+{
+ gl_Position = vPosition;
+ texColor = vec4(shades[int(index)], 0, 0, 1.0);
+}
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">
+#ifdef GL_ES
+precision highp float;
+#endif
+varying vec4 texColor;
+void main()
+{
+ gl_FragColor = texColor;
+}
+</script>
+
+<script>
+function init()
+{
+ if (window.initNonKhronosFramework)
+ window.initNonKhronosFramework(false);
+
+ debug("Checks that array access in a shader can not read out of bounds");
+ debug("");
+
+ gl = initWebGL("example", "vshader", "fshader", [ "vPosition", "index" ],
+ [ 1, 1, 1, 1 ], 1);
+
+ gl.disable(gl.DEPTH_TEST);
+ gl.disable(gl.BLEND);
+
+ var vertexObject = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+ gl.bufferData(gl.ARRAY_BUFFER,
+ new Float32Array([ -1,1,0, 1,1,0, -1,-1,0,
+ -1,-1,0, 1,1,0, 1,-1,0 ]),
+ gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
+
+ var vertexObject = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+ gl.bufferData(gl.ARRAY_BUFFER,
+ // Create an array that exercises well outside the
+ // limits on each side, near the limits, and the
+ // exact limits.
+ // This should be clamped to [0, 0, 0, 7, 7, 7]
+ new Float32Array([ -Number.MAX_VALUE, -1, 0, 7, 8, Number.MAX_VALUE]),
+ gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(1);
+ gl.vertexAttribPointer(1, 1, gl.FLOAT, false, 0, 0);
+
+ var loc = gl.getUniformLocation(gl.program, "shades");
+ gl.uniform1fv(loc, [0.25, 0.5, 0, 0, 0, 0, 0.75, 1]);
+
+ checkRedValue(0, 38, 64, "Top left corner should clamp to index 0");
+ checkRedValue(37, 38, 64, "Inside top right corner should clamp to index 0");
+ checkRedValue(0, 1, 64, "Inside bottom left corner should clamp to index 0");
+
+ checkRedValue(38, 0, 255, "Bottom right corner should clamp to index 7");
+ checkRedValue(3, 1, 255, "Outside bottom left corner should clamp to index 7");
+ checkRedValue(38, 37, 255, "Outside top right corner should clamp to index 7");
+
+ function checkRedValue(x, y, value, msg) {
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ gl.flush();
+ var buf = new Uint8Array(4);
+ gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ if (buf[0] != value || buf[1] != 0 || buf[2] != 0 || buf[3] != 255) {
+ debug('expected: rgb(' + value + ', 0, 0, 255) was rgb(' + buf[0] + ', ' + buf[1] + ', ' + buf[2] + ', ' + buf[3] + ')');
+ testFailed(msg);
+ return;
+ }
+ testPassed(msg);
+ }
+}
+
+init();
+</script>
+<script src=""
+</body>
+</html>
+
Property changes on: trunk/LayoutTests/fast/canvas/webgl/array-bounds-clamping.html
___________________________________________________________________
Added: svn:mime-type
Added: svn:keywords
Added: svn:eol-style
Modified: trunk/LayoutTests/platform/chromium/TestExpectations (131932 => 131933)
--- trunk/LayoutTests/platform/chromium/TestExpectations 2012-10-19 19:34:57 UTC (rev 131932)
+++ trunk/LayoutTests/platform/chromium/TestExpectations 2012-10-19 19:45:03 UTC (rev 131933)
@@ -2363,6 +2363,9 @@
crbug.com/60651 fast/canvas/webgl/uniform-location.html [ Failure Timeout ]
crbug.com/60651 platform/chromium/virtual/gpu/fast/canvas/webgl/uniform-location.html [ Failure Timeout ]
+# This will fail in Chromium until the patch is upstreamed to ANGLE
+webkit.org/b/98977 fast/canvas/webgl/array-bounds-clamping.html [ Failure ]
+
# Flaky since r68438:r68445 or before that.
webkit.org/b/46693 [ Mac ] fast/repaint/repaint-svg-after-style-change.html [ Failure ]
Modified: trunk/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj (131932 => 131933)
--- trunk/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj 2012-10-19 19:34:57 UTC (rev 131932)
+++ trunk/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj 2012-10-19 19:45:03 UTC (rev 131933)
@@ -9,6 +9,8 @@
/* Begin PBXBuildFile section */
312BDB0C15FECAC90097EBC7 /* ANGLE.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 312BDB0915FEC91E0097EBC7 /* ANGLE.plist */; };
312BDB0E15FECAE50097EBC7 /* ANGLE.txt in CopyFiles */ = {isa = PBXBuildFile; fileRef = 312BDB0A15FECA3A0097EBC7 /* ANGLE.txt */; };
+ 3158EA0E1630968D006BE5EE /* ArrayBoundsClamper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3158EA0C1630968D006BE5EE /* ArrayBoundsClamper.cpp */; };
+ 3158EA0F1630968D006BE5EE /* ArrayBoundsClamper.h in Headers */ = {isa = PBXBuildFile; fileRef = 3158EA0D1630968D006BE5EE /* ArrayBoundsClamper.h */; };
49951C0314B7AAB30060E96E /* length_limits.h in Headers */ = {isa = PBXBuildFile; fileRef = 49951C0214B7AAB30060E96E /* length_limits.h */; };
49951C0914B7AAD80060E96E /* BuiltInFunctionEmulator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49951C0514B7AAD70060E96E /* BuiltInFunctionEmulator.cpp */; };
49951C0A14B7AAD80060E96E /* BuiltInFunctionEmulator.h in Headers */ = {isa = PBXBuildFile; fileRef = 49951C0614B7AAD80060E96E /* BuiltInFunctionEmulator.h */; };
@@ -136,6 +138,8 @@
/* Begin PBXFileReference section */
312BDB0915FEC91E0097EBC7 /* ANGLE.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = ANGLE.plist; sourceTree = "<group>"; };
312BDB0A15FECA3A0097EBC7 /* ANGLE.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ANGLE.txt; sourceTree = "<group>"; };
+ 3158EA0C1630968D006BE5EE /* ArrayBoundsClamper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArrayBoundsClamper.cpp; sourceTree = "<group>"; };
+ 3158EA0D1630968D006BE5EE /* ArrayBoundsClamper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayBoundsClamper.h; sourceTree = "<group>"; };
49951C0214B7AAB30060E96E /* length_limits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = length_limits.h; sourceTree = "<group>"; };
49951C0514B7AAD70060E96E /* BuiltInFunctionEmulator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BuiltInFunctionEmulator.cpp; sourceTree = "<group>"; };
49951C0614B7AAD80060E96E /* BuiltInFunctionEmulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BuiltInFunctionEmulator.h; sourceTree = "<group>"; };
@@ -544,6 +548,8 @@
FB39D2201200F35A00088E69 /* compiler */ = {
isa = PBXGroup;
children = (
+ 3158EA0C1630968D006BE5EE /* ArrayBoundsClamper.cpp */,
+ 3158EA0D1630968D006BE5EE /* ArrayBoundsClamper.h */,
FB39D2211200F35A00088E69 /* BaseTypes.h */,
49951C0514B7AAD70060E96E /* BuiltInFunctionEmulator.cpp */,
49951C0614B7AAD80060E96E /* BuiltInFunctionEmulator.h */,
@@ -712,6 +718,7 @@
A265683E159C23E100398539 /* DependencyGraphOutput.h in Headers */,
A2656841159C23E100398539 /* RestrictFragmentShaderTiming.h in Headers */,
A2656843159C23E100398539 /* RestrictVertexShaderTiming.h in Headers */,
+ 3158EA0F1630968D006BE5EE /* ArrayBoundsClamper.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -829,6 +836,7 @@
A265683F159C23E100398539 /* DependencyGraphTraverse.cpp in Sources */,
A2656840159C23E100398539 /* RestrictFragmentShaderTiming.cpp in Sources */,
A2656842159C23E100398539 /* RestrictVertexShaderTiming.cpp in Sources */,
+ 3158EA0E1630968D006BE5EE /* ArrayBoundsClamper.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Modified: trunk/Source/ThirdParty/ANGLE/ChangeLog (131932 => 131933)
--- trunk/Source/ThirdParty/ANGLE/ChangeLog 2012-10-19 19:34:57 UTC (rev 131932)
+++ trunk/Source/ThirdParty/ANGLE/ChangeLog 2012-10-19 19:45:03 UTC (rev 131933)
@@ -1,3 +1,59 @@
+2012-10-18 Dean Jackson <[email protected]>
+
+ Shader translator needs option to clamp uniform array accesses in vertex shaders
+ https://bugs.webkit.org/show_bug.cgi?id=98977
+ https://code.google.com/p/angleproject/issues/detail?id=49
+
+ Reviewed by Alok Priyadarshi and Ken Russell.
+
+ WebGL does not allow GLSL code to index a uniform array outside its bounds. Add a
+ flag to the ANGLE compiler to insert clamp statements around such indexing.
+ Since it is possible to access vec2/3/4 and mat2/3/4 components by array indexing,
+ they must be similarly clamped.
+
+ Unfortunately, it is currently not possible to always determine that the indexing is
+ operating on a uniform variable. For example, suppose we have "uniform mat4 a". ANGLE
+ is currently not able to tell us that the rvalue of "a[0]" is a uniform, just that
+ it has a size of 4. Therefore, the clamping is done on all indirect array indexing.
+
+ This will have a performance impact. Future enhancements may be able to determine
+ cases where the clamping is not necessary. Currently only direct indexing is skipped
+ (i.e. looking up a value using a constant index).
+
+ The clamp insertion is only performed on the GLSL output. Direct3D already guarantees
+ that out-of-bounds uniform array access returns a zero value.
+
+ * ANGLE.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * include/GLSLANG/ShaderLang.h: New compiler option.
+ * src/compiler/ArrayBoundsClamper.cpp: Added.
+ (ArrayBoundsClamper::ArrayBoundsClamper):
+ (ArrayBoundsClamper::OutputClampingFunctionDefinition): Injects a clamping function for integers into GLSL source.
+ (ArrayBoundsClamper::MarkIndirectArrayBoundsForClamping): Examines the AST looking for non-direct array indexing.
+ * src/compiler/ArrayBoundsClamper.h: Added.
+ (ArrayBoundsClamper):
+ (ArrayBoundsClamper::GetArrayBoundsClampDefinitionNeeded):
+ (ArrayBoundsClamper::SetArrayBoundsClampDefinitionNeeded): Marks the object as needing to output the clamping function.
+ (ArrayBoundsClamper::Cleanup): Resets the state so that subsequent runs start fresh.
+ * src/compiler/Compiler.cpp:
+ (TCompiler::compile): Run the clamping code if the compile option was set.
+ (TCompiler::clearResults):
+ (TCompiler::getArrayBoundsClamper):
+ * src/compiler/OutputGLSLBase.cpp:
+ (TOutputGLSLBase::visitBinary): If the _expression_ has been flagged, insert an appropriate "clamp" statement.
+ * src/compiler/ShHandle.h:
+ (TCompiler):
+ * src/compiler/TranslatorESSL.cpp:
+ (TranslatorESSL::translate):
+ * src/compiler/TranslatorGLSL.cpp:
+ (TranslatorGLSL::translate):
+ * src/compiler/intermOut.cpp:
+ (TType::getCompleteString): Add array size to intermediate tree output.
+ * src/compiler/intermediate.h:
+ (TIntermBinary::setAddIndexClamp): New flag for indicating a binary _expression_ needs clamping.
+ (TIntermBinary::getAddIndexClamp):
+ (TIntermBinary):
+
2012-09-13 Mark Rowe <[email protected]>
<rdar://problem/12255720> Fix the build with newer Clang
Modified: trunk/Source/ThirdParty/ANGLE/Target.pri (131932 => 131933)
--- trunk/Source/ThirdParty/ANGLE/Target.pri 2012-10-19 19:34:57 UTC (rev 131932)
+++ trunk/Source/ThirdParty/ANGLE/Target.pri 2012-10-19 19:45:03 UTC (rev 131933)
@@ -17,6 +17,7 @@
$$SOURCE_DIR/include
HEADERS += \
+ src/compiler/ArrayBoundsClamper.h \
src/compiler/BaseTypes.h \
src/compiler/BuiltInFunctionEmulator.h \
src/compiler/Common.h \
@@ -90,6 +91,7 @@
src/compiler/VersionGLSL.h
SOURCES += \
+ src/compiler/ArrayBoundsClamper.cpp \
src/compiler/BuiltInFunctionEmulator.cpp \
src/compiler/CodeGenGLSL.cpp \
src/compiler/Compiler.cpp \
Modified: trunk/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h (131932 => 131933)
--- trunk/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h 2012-10-19 19:34:57 UTC (rev 131932)
+++ trunk/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h 2012-10-19 19:45:03 UTC (rev 131933)
@@ -142,7 +142,13 @@
// - 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
+ SH_DEPENDENCY_GRAPH = 0x0400,
+
+ // 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 = 0x0800
} ShCompileOptions;
//
Added: trunk/Source/ThirdParty/ANGLE/src/compiler/ArrayBoundsClamper.cpp (0 => 131933)
--- trunk/Source/ThirdParty/ANGLE/src/compiler/ArrayBoundsClamper.cpp (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/ArrayBoundsClamper.cpp 2012-10-19 19:45:03 UTC (rev 131933)
@@ -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();
+ }
+}
+
Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/ArrayBoundsClamper.cpp
___________________________________________________________________
Added: svn:keywords
Added: svn:eol-style
Added: trunk/Source/ThirdParty/ANGLE/src/compiler/ArrayBoundsClamper.h (0 => 131933)
--- trunk/Source/ThirdParty/ANGLE/src/compiler/ArrayBoundsClamper.h (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/ArrayBoundsClamper.h 2012-10-19 19:45:03 UTC (rev 131933)
@@ -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_
Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/ArrayBoundsClamper.h
___________________________________________________________________
Added: svn:keywords
Added: svn:eol-style
Modified: trunk/Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp (131932 => 131933)
--- trunk/Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp 2012-10-19 19:34:57 UTC (rev 131932)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp 2012-10-19 19:45:03 UTC (rev 131933)
@@ -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"
@@ -186,6 +187,10 @@
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.
@@ -231,6 +236,7 @@
uniforms.clear();
builtInFunctionEmulator.Cleanup();
+ arrayBoundsClamper.Cleanup();
}
bool TCompiler::detectRecursion(TIntermNode* root)
@@ -331,3 +337,9 @@
{
return builtInFunctionEmulator;
}
+
+const ArrayBoundsClamper& TCompiler::getArrayBoundsClamper() const
+{
+ return arrayBoundsClamper;
+}
+
Modified: trunk/Source/ThirdParty/ANGLE/src/compiler/OutputGLSLBase.cpp (131932 => 131933)
--- trunk/Source/ThirdParty/ANGLE/src/compiler/OutputGLSLBase.cpp 2012-10-19 19:34:57 UTC (rev 131932)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/OutputGLSLBase.cpp 2012-10-19 19:45:03 UTC (rev 131933)
@@ -235,9 +235,38 @@
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)
{
Modified: trunk/Source/ThirdParty/ANGLE/src/compiler/ShHandle.h (131932 => 131933)
--- trunk/Source/ThirdParty/ANGLE/src/compiler/ShHandle.h 2012-10-19 19:34:57 UTC (rev 131932)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/ShHandle.h 2012-10-19 19:45:03 UTC (rev 131933)
@@ -16,6 +16,7 @@
#include "GLSLANG/ShaderLang.h"
+#include "compiler/ArrayBoundsClamper.h"
#include "compiler/BuiltInFunctionEmulator.h"
#include "compiler/ExtensionBehavior.h"
#include "compiler/InfoSink.h"
@@ -98,6 +99,7 @@
// Get built-in extensions with default behavior.
const TExtensionBehavior& getExtensionBehavior() const;
+ const ArrayBoundsClamper& getArrayBoundsClamper() const;
const BuiltInFunctionEmulator& getBuiltInFunctionEmulator() const;
private:
@@ -110,6 +112,7 @@
// Built-in extensions with default behavior.
TExtensionBehavior extensionBehavior;
+ ArrayBoundsClamper arrayBoundsClamper;
BuiltInFunctionEmulator builtInFunctionEmulator;
// Results of compilation.
Modified: trunk/Source/ThirdParty/ANGLE/src/compiler/TranslatorESSL.cpp (131932 => 131933)
--- trunk/Source/ThirdParty/ANGLE/src/compiler/TranslatorESSL.cpp 2012-10-19 19:34:57 UTC (rev 131932)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/TranslatorESSL.cpp 2012-10-19 19:45:03 UTC (rev 131933)
@@ -22,6 +22,9 @@
getBuiltInFunctionEmulator().OutputEmulatedFunctionDefinition(
sink, getShaderType() == SH_FRAGMENT_SHADER);
+ // Write array bounds clamping emulation if needed.
+ getArrayBoundsClamper().OutputClampingFunctionDefinition(sink);
+
// Write translated shader.
TOutputESSL outputESSL(sink);
root->traverse(&outputESSL);
Modified: trunk/Source/ThirdParty/ANGLE/src/compiler/TranslatorGLSL.cpp (131932 => 131933)
--- trunk/Source/ThirdParty/ANGLE/src/compiler/TranslatorGLSL.cpp 2012-10-19 19:34:57 UTC (rev 131932)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/TranslatorGLSL.cpp 2012-10-19 19:45:03 UTC (rev 131933)
@@ -35,6 +35,9 @@
getBuiltInFunctionEmulator().OutputEmulatedFunctionDefinition(
sink, false);
+ // Write array bounds clamping emulation if needed.
+ getArrayBoundsClamper().OutputClampingFunctionDefinition(sink);
+
// Write translated shader.
TOutputGLSL outputGLSL(sink);
root->traverse(&outputGLSL);
Modified: trunk/Source/ThirdParty/ANGLE/src/compiler/intermOut.cpp (131932 => 131933)
--- trunk/Source/ThirdParty/ANGLE/src/compiler/intermOut.cpp 2012-10-19 19:34:57 UTC (rev 131932)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/intermOut.cpp 2012-10-19 19:45:03 UTC (rev 131933)
@@ -42,7 +42,7 @@
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)
Modified: trunk/Source/ThirdParty/ANGLE/src/compiler/intermediate.h (131932 => 131933)
--- trunk/Source/ThirdParty/ANGLE/src/compiler/intermediate.h 2012-10-19 19:34:57 UTC (rev 131932)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/intermediate.h 2012-10-19 19:45:03 UTC (rev 131933)
@@ -400,9 +400,15 @@
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;
};
//
Modified: trunk/Source/WebCore/ChangeLog (131932 => 131933)
--- trunk/Source/WebCore/ChangeLog 2012-10-19 19:34:57 UTC (rev 131932)
+++ trunk/Source/WebCore/ChangeLog 2012-10-19 19:45:03 UTC (rev 131933)
@@ -1,3 +1,19 @@
+2012-10-18 Dean Jackson <[email protected]>
+
+ Shader translator needs option to clamp uniform array accesses in vertex shaders
+ https://bugs.webkit.org/show_bug.cgi?id=98977
+ https://code.google.com/p/angleproject/issues/detail?id=49
+
+ Reviewed by Alok Priyadarshi and Ken Russell.
+
+ WebGL forbids out-of-bounds array access in shaders. Rewrite any shaders to
+ ensure that non-direct array indexing is clamped to the bounds of the array.
+
+ Test: fast/canvas/webgl/array-bounds-clamping.html
+
+ * platform/graphics/ANGLEWebKitBridge.cpp:
+ (WebCore::ANGLEWebKitBridge::compileShaderSource): Pass new compiler option SH_CLAMP_INDIRECT_ARRAY_BOUNDS
+
2012-10-19 Justin Novosad <[email protected]>
[Chromium] Reduce memory footprint of canvas pattern object with deferred rendering
Modified: trunk/Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp (131932 => 131933)
--- trunk/Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp 2012-10-19 19:34:57 UTC (rev 131932)
+++ trunk/Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp 2012-10-19 19:45:03 UTC (rev 131933)
@@ -173,6 +173,12 @@
const char* const shaderSourceStrings[] = { shaderSource };
+#if !PLATFORM(CHROMIUM)
+ // Chromium does not use the ANGLE bundled in WebKit source, and thus
+ // does not yet have the symbol SH_CLAMP_INDIRECT_ARRAY_BOUNDS.
+ extraCompileOptions |= SH_CLAMP_INDIRECT_ARRAY_BOUNDS;
+#endif
+
bool validateSuccess = ShCompile(compiler, shaderSourceStrings, 1, SH_OBJECT_CODE | SH_ATTRIBUTES_UNIFORMS | extraCompileOptions);
if (!validateSuccess) {
int logSize = getValidationResultValue(compiler, SH_INFO_LOG_LENGTH);