зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-i to m-c
This commit is contained in:
Коммит
3b2bdecb9e
|
@ -10,6 +10,7 @@
|
|||
#include "ImageAccessible.h"
|
||||
#include "mozilla/Likely.h"
|
||||
#include "nsMai.h"
|
||||
#include "nsIURI.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::a11y;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "nsIWebProgress.h"
|
||||
#include "prenv.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIURI.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::a11y;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "nsIServiceManager.h"
|
||||
#include "nsIDOMHTMLImageElement.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIURI.h"
|
||||
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "nsIFrame.h"
|
||||
#include "nsImageFrame.h"
|
||||
#include "nsImageMap.h"
|
||||
#include "nsIURI.h"
|
||||
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include "States.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsRect.h"
|
||||
|
||||
#include "nsTArray.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "nsIAccessibleTypes.h"
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsIURI.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::a11y;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ImageAccessibleWrap.h"
|
||||
#include "nsIURI.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::a11y;
|
||||
|
|
|
@ -57,6 +57,18 @@ function onSidebarLoad(callback) {
|
|||
}, true);
|
||||
}
|
||||
|
||||
function ensureWorkerLoaded(provider, callback) {
|
||||
// once the worker responds to a ping we know it must be up.
|
||||
let port = provider.getWorkerPort();
|
||||
port.onmessage = function(msg) {
|
||||
if (msg.data.topic == "pong") {
|
||||
port.close();
|
||||
callback();
|
||||
}
|
||||
}
|
||||
port.postMessage({topic: "ping"})
|
||||
}
|
||||
|
||||
let manifest = { // normal provider
|
||||
name: "provider 1",
|
||||
origin: "https://example.com",
|
||||
|
@ -99,9 +111,13 @@ var tests = {
|
|||
});
|
||||
sbrowser.contentDocument.getElementById("btnTryAgain").click();
|
||||
});
|
||||
// go offline then attempt to load the sidebar - it should fail.
|
||||
goOffline();
|
||||
Services.prefs.setBoolPref("social.sidebar.open", true);
|
||||
// we want the worker to be fully loaded before going offline, otherwise
|
||||
// it might fail due to going offline.
|
||||
ensureWorkerLoaded(Social.provider, function() {
|
||||
// go offline then attempt to load the sidebar - it should fail.
|
||||
goOffline();
|
||||
Services.prefs.setBoolPref("social.sidebar.open", true);
|
||||
});
|
||||
},
|
||||
|
||||
testFlyout: function(next) {
|
||||
|
|
|
@ -13,26 +13,10 @@ import shutil
|
|||
import subprocess
|
||||
import sys
|
||||
|
||||
from distutils.version import StrictVersion
|
||||
|
||||
|
||||
# Minimum version of Python required to build.
|
||||
MINIMUM_PYTHON_VERSION = StrictVersion('2.7.3')
|
||||
MINIMUM_PYTHON_MAJOR = 2
|
||||
|
||||
|
||||
UPGRADE_WINDOWS = '''
|
||||
Please upgrade to the latest MozillaBuild development environments. See
|
||||
https://developer.mozilla.org/en-US/docs/Developer_Guide/Build_Instructions/Windows_Prerequisites
|
||||
'''.lstrip()
|
||||
|
||||
UPGRADE_OTHER = '''
|
||||
Run |mach bootstrap| to ensure your system is up to date.
|
||||
|
||||
If you still receive this error, your shell environment is likely detecting
|
||||
another Python version. Ensure a modern Python can be found in the paths
|
||||
defined by the $PATH environment variable and try again.
|
||||
'''.lstrip()
|
||||
MINIMUM_PYTHON_MINOR = 7
|
||||
|
||||
|
||||
class VirtualenvManager(object):
|
||||
|
@ -359,20 +343,13 @@ class VirtualenvManager(object):
|
|||
|
||||
def verify_python_version(log_handle):
|
||||
"""Ensure the current version of Python is sufficient."""
|
||||
major, minor, micro = sys.version_info[:3]
|
||||
|
||||
our = StrictVersion('%d.%d.%d' % (major, minor, micro))
|
||||
|
||||
if major != MINIMUM_PYTHON_MAJOR or our < MINIMUM_PYTHON_VERSION:
|
||||
log_handle.write('Python %s or greater (but not Python 3) is '
|
||||
'required to build. ' % MINIMUM_PYTHON_VERSION)
|
||||
log_handle.write('You are running Python %s.\n' % our)
|
||||
|
||||
if os.name in ('nt', 'ce'):
|
||||
log_handle.write(UPGRADE_WINDOWS)
|
||||
else:
|
||||
log_handle.write(UPGRADE_OTHER)
|
||||
major, minor = sys.version_info[:2]
|
||||
|
||||
if major != MINIMUM_PYTHON_MAJOR or minor < MINIMUM_PYTHON_MINOR:
|
||||
log_handle.write('Python %d.%d or greater (but not Python 3) is '
|
||||
'required to build. ' %
|
||||
(MINIMUM_PYTHON_MAJOR, MINIMUM_PYTHON_MINOR))
|
||||
log_handle.write('You are running Python %d.%d.\n' % (major, minor))
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "nsHTMLCSSStyleSheet.h"
|
||||
#include "nsCSSParser.h"
|
||||
#include "nsStyledElement.h"
|
||||
#include "nsIURI.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace mozilla;
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "nsGkAtoms.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIURI.h"
|
||||
|
||||
// image copy stuff
|
||||
#include "nsIImageLoadingContent.h"
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "WebGL2Context.h"
|
||||
#include "GLContext.h"
|
||||
#include "mozilla/dom/WebGL2RenderingContextBinding.h"
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "GLContext.h"
|
||||
|
||||
#include "nsString.h"
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "AccessCheck.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "nsRuleData.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIURI.h"
|
||||
|
||||
NS_IMPL_NS_NEW_HTML_ELEMENT(Shared)
|
||||
|
||||
|
|
|
@ -9,13 +9,14 @@
|
|||
#include "nsIDOMClientRect.h"
|
||||
#include "nsIDOMClientRectList.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsRect.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
struct nsRect;
|
||||
|
||||
class nsClientRect MOZ_FINAL : public nsIDOMClientRect
|
||||
, public nsWrapperCache
|
||||
{
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "mozAutoDocUpdate.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIURI.h"
|
||||
|
||||
#include "mozilla/dom/ElementBinding.h"
|
||||
|
||||
|
|
|
@ -9,9 +9,9 @@
|
|||
#include "WMF.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "nsRect.h"
|
||||
|
||||
class nsIntSize;
|
||||
struct nsIntSize;
|
||||
struct nsIntRect;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
#include "nsEventListenerManager.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsSize.h"
|
||||
#include "nsRect.h"
|
||||
#include "mozFlushType.h"
|
||||
#include "prclist.h"
|
||||
#include "nsIDOMStorageEvent.h"
|
||||
|
@ -98,7 +97,8 @@ class nsGlobalWindow;
|
|||
class nsDOMEventTargetHelper;
|
||||
class nsDOMWindowUtils;
|
||||
class nsIIdleService;
|
||||
class nsIntSize;
|
||||
struct nsIntSize;
|
||||
struct nsRect;
|
||||
|
||||
class nsWindowSizes;
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@ using mozilla::DefaultXDisplay;
|
|||
#include "nsIDocShell.h"
|
||||
#include "ImageContainer.h"
|
||||
#include "nsIDOMHTMLCollection.h"
|
||||
#include "GLContext.h"
|
||||
|
||||
#include "nsContentCID.h"
|
||||
#include "nsWidgetsCID.h"
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include "base/basictypes.h"
|
||||
#include "nsPoint.h"
|
||||
#include "npapi.h"
|
||||
#include "nsRect.h"
|
||||
|
||||
// Make this includable from non-Objective-C code.
|
||||
#ifndef __OBJC__
|
||||
|
|
|
@ -8,9 +8,10 @@
|
|||
#define dom_plugins_PluginUtilsOSX_h 1
|
||||
|
||||
#include "npapi.h"
|
||||
#include "nsRect.h"
|
||||
#include "mozilla/gfx/QuartzSupport.h"
|
||||
|
||||
struct nsIntRect;
|
||||
|
||||
namespace mozilla {
|
||||
namespace plugins {
|
||||
namespace PluginUtilsOSX {
|
||||
|
|
|
@ -30,4 +30,3 @@ Boying Lu
|
|||
Aitor Moreno
|
||||
Yuri O'Donnell
|
||||
Josh Soref
|
||||
Evan Wallace
|
||||
|
|
|
@ -9,7 +9,9 @@
|
|||
TransGaming Inc.
|
||||
Nicolas Capens
|
||||
Daniel Koch
|
||||
Geoff Lang
|
||||
Andrew Lewycky
|
||||
Jamie Madill
|
||||
Gavriel State
|
||||
Shannon Woods
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ VPATH += $(srcdir)/src/compiler
|
|||
VPATH += $(srcdir)/src/compiler/depgraph
|
||||
VPATH += $(srcdir)/src/compiler/timing
|
||||
VPATH += $(srcdir)/src/third_party/compiler
|
||||
VPATH += $(srcdir)/src/third_party/murmurhash
|
||||
|
||||
# Target: 'translator_glsl'
|
||||
# Requires: 'translator_common'
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
Name: ANGLE
|
||||
URL: https://code.google.com/p/angleproject/
|
||||
Version: 2422
|
||||
License: BSD
|
||||
License File: LICENSE
|
||||
|
||||
Description:
|
||||
ANGLE is a conformant implementation of the OpenGL ES 2.0
|
||||
specification that is hardware‐accelerated via Direct3D.
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
This is the ANGLE project, from http://code.google.com/p/angleproject/
|
||||
|
||||
Current revision: r2042
|
||||
|
||||
Current revision: f3fc6571dca9832876e09c63b0958d413737757b
|
||||
Date of revision: 2013-08-02
|
||||
|
||||
== Applied local patches ==
|
||||
In this order:
|
||||
|
@ -15,13 +15,26 @@ In this order:
|
|||
|
||||
angle-build-d3dcompiler-list.patch:
|
||||
Move `ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES` define from make files to
|
||||
Display.cpp, where it's used.
|
||||
Renderer.cpp, where it's used.
|
||||
|
||||
angle-build-khrplatform-h-path.patch:
|
||||
Fix include path for khrplatform.h.
|
||||
|
||||
angle-long-ident-spooky-hash.patch:
|
||||
Use Spooky Hash for long identifier hashing. See bug 676071.
|
||||
angle-build-case-sensitive.patch
|
||||
Fixes cross compilation on case sensitive OSes.
|
||||
|
||||
angle-build-dedupe-uniform-cpp-h.patch:
|
||||
Rename: "src/compiler/Uniform.{cpp,h}"
|
||||
To: "src/compiler/CompilerUniform.{cpp,h}"
|
||||
Repair includes accordingly.
|
||||
|
||||
angle-build-ttype.patch:
|
||||
Remove bit-field markings for TType, since GCC4.7 emits a default
|
||||
copy constructor which fails to compile.
|
||||
|
||||
angle-long-ident-hash.patch:
|
||||
Use MurmurHash3 for long identifier hashing. See bug 676071, where we used
|
||||
Spooky Hash, before ANGLE came with MurmurHash3.
|
||||
|
||||
angle-faceforward-emu.patch:
|
||||
Adds emulation for faceforward(float,float,float), which is needed to
|
||||
|
@ -31,34 +44,34 @@ In this order:
|
|||
Fixes TCompiler::Init to treat `resources.ArrayIndexClampingStrategy`
|
||||
as a request for the default strategy.
|
||||
|
||||
angle-cross-compilation.patch
|
||||
Fixes cross compilation on case sensitive OSes.
|
||||
angle-tex-pool-default.patch:
|
||||
Don't use D3DPOOL_MANAGED on D3D9. Just use D3DPOOL_DEFAULT.
|
||||
|
||||
angle-line-loop-overflow.patch
|
||||
Fixes a forgotten overflow check on drawing line loop
|
||||
ANGLE bug : http://code.google.com/p/angleproject/issues/detail?id=444
|
||||
ANGLE revision : 07dda9519cf4
|
||||
|
||||
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.
|
||||
In addition to these patches, the Makefile.in and moz.build build files are ours,
|
||||
they're not present in upsteam ANGLE. Therefore, changes made to the build 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
|
||||
Makefile.in
|
||||
moz.build
|
||||
*.patch
|
||||
src/libEGL/Makefile.in
|
||||
src/libEGL/moz.build
|
||||
src/libGLESv2/Makefile.in
|
||||
src/libGLESv2/moz.build
|
||||
|
||||
2. $ rm -rf gfx/angle
|
||||
|
||||
3. Copy the folder containing the angle rev you want onto gfx/angle.
|
||||
$ svn export -r <rev> <src> <moz-central>/gfx/angle
|
||||
Or:
|
||||
$ git checkout-index --prefix <moz-central>/gfx/angle/ -a
|
||||
|
||||
4. Fold our moz-specific files into this new angle folder. (Makefiles, README)
|
||||
4a. Remove the unused directories. (test/, samples/, etc)
|
||||
4a. Remove the unused files. (test/, samples/, msvc files)
|
||||
|
||||
5. Clear out the "Applied Local Patches" section above, since we're going to
|
||||
repopulate it.
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
From: Jeff Gilbert <jgilbert@mozilla.com>
|
||||
* * *
|
||||
Bug 840577 - Fix ANGLE cross compilation on case sensitive OSes, relanded
|
||||
|
||||
diff --git a/gfx/angle/src/libGLESv2/precompiled.h b/gfx/angle/src/libGLESv2/precompiled.h
|
||||
--- a/gfx/angle/src/libGLESv2/precompiled.h
|
||||
+++ b/gfx/angle/src/libGLESv2/precompiled.h
|
||||
@@ -30,13 +30,13 @@
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include <d3d9.h>
|
||||
#include <D3D11.h>
|
||||
#include <dxgi.h>
|
||||
-#include <D3Dcompiler.h>
|
||||
+#include <d3dcompiler.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <hash_map>
|
||||
#endif
|
|
@ -1,16 +1,16 @@
|
|||
From: Jeff Gilbert <jgilbert@mozilla.com>
|
||||
|
||||
diff --git a/gfx/angle/src/libEGL/Display.cpp b/gfx/angle/src/libEGL/Display.cpp
|
||||
--- a/gfx/angle/src/libEGL/Display.cpp
|
||||
+++ b/gfx/angle/src/libEGL/Display.cpp
|
||||
@@ -26,16 +26,22 @@
|
||||
// The "Debug This Pixel..." feature in PIX often fails when using the
|
||||
// D3D9Ex interfaces. In order to get debug pixel to work on a Vista/Win 7
|
||||
// machine, define "ANGLE_ENABLE_D3D9EX=0" in your project file.
|
||||
#if !defined(ANGLE_ENABLE_D3D9EX)
|
||||
// Enables use of the IDirect3D9Ex interface, when available
|
||||
#define ANGLE_ENABLE_D3D9EX 1
|
||||
#endif // !defined(ANGLE_ENABLE_D3D9EX)
|
||||
diff --git a/gfx/angle/src/libGLESv2/renderer/Renderer.cpp b/gfx/angle/src/libGLESv2/renderer/Renderer.cpp
|
||||
--- a/gfx/angle/src/libGLESv2/renderer/Renderer.cpp
|
||||
+++ b/gfx/angle/src/libGLESv2/renderer/Renderer.cpp
|
||||
@@ -15,16 +15,23 @@
|
||||
#include "libGLESv2/renderer/Renderer11.h"
|
||||
#include "libGLESv2/utilities.h"
|
||||
|
||||
#if !defined(ANGLE_ENABLE_D3D11)
|
||||
// Enables use of the Direct3D 11 API for a default display, when available
|
||||
#define ANGLE_ENABLE_D3D11 0
|
||||
#endif
|
||||
|
||||
+#define ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES \
|
||||
+ { \
|
||||
|
@ -18,11 +18,24 @@ diff --git a/gfx/angle/src/libEGL/Display.cpp b/gfx/angle/src/libEGL/Display.cpp
|
|||
+ TEXT("d3dcompiler_43.dll") \
|
||||
+ }
|
||||
+
|
||||
namespace egl
|
||||
+
|
||||
namespace rx
|
||||
{
|
||||
namespace
|
||||
|
||||
Renderer::Renderer(egl::Display *display) : mDisplay(display)
|
||||
{
|
||||
typedef std::map<EGLNativeDisplayType, Display*> DisplayMap;
|
||||
DisplayMap displays;
|
||||
mD3dCompilerModule = NULL;
|
||||
mD3DCompileFunc = NULL;
|
||||
}
|
||||
@@ -212,9 +219,9 @@ rx::Renderer *glCreateRenderer(egl::Disp
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void glDestroyRenderer(rx::Renderer *renderer)
|
||||
{
|
||||
delete renderer;
|
||||
}
|
||||
|
||||
-}
|
||||
\ No newline at end of file
|
||||
+}
|
||||
|
|
|
@ -69,7 +69,7 @@ diff --git a/gfx/angle/src/compiler/OutputHLSL.cpp b/gfx/angle/src/compiler/Outp
|
|||
--- a/gfx/angle/src/compiler/OutputHLSL.cpp
|
||||
+++ b/gfx/angle/src/compiler/OutputHLSL.cpp
|
||||
@@ -2,17 +2,17 @@
|
||||
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
|
||||
// Copyright (c) 2002-2013 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.
|
||||
//
|
||||
|
@ -90,25 +90,25 @@ diff --git a/gfx/angle/src/compiler/OutputHLSL.cpp b/gfx/angle/src/compiler/Outp
|
|||
diff --git a/gfx/angle/src/compiler/Types.h b/gfx/angle/src/compiler/Types.h
|
||||
--- a/gfx/angle/src/compiler/Types.h
|
||||
+++ b/gfx/angle/src/compiler/Types.h
|
||||
@@ -4,17 +4,17 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
@@ -6,17 +6,17 @@
|
||||
|
||||
#ifndef _TYPES_INCLUDED
|
||||
#define _TYPES_INCLUDED
|
||||
|
||||
#include "common/angleutils.h"
|
||||
|
||||
#include "compiler/BaseTypes.h"
|
||||
#include "compiler/Common.h"
|
||||
-#include "compiler/debug.h"
|
||||
+#include "compiler/compiler_debug.h"
|
||||
|
||||
class TType;
|
||||
struct TPublicType;
|
||||
class TType;
|
||||
|
||||
//
|
||||
// Need to have association of line numbers to types in a list for building structs.
|
||||
//
|
||||
struct TTypeLine {
|
||||
class TField
|
||||
{
|
||||
public:
|
||||
POOL_ALLOCATOR_NEW_DELETE();
|
||||
diff --git a/gfx/angle/src/compiler/debug.cpp b/gfx/angle/src/compiler/compiler_debug.cpp
|
||||
rename from gfx/angle/src/compiler/debug.cpp
|
||||
rename to gfx/angle/src/compiler/compiler_debug.cpp
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
From: Jeff Gilbert <jgilbert@mozilla.com>
|
||||
|
||||
diff --git a/gfx/angle/src/compiler/Uniform.cpp b/gfx/angle/src/compiler/CompilerUniform.cpp
|
||||
rename from gfx/angle/src/compiler/Uniform.cpp
|
||||
rename to gfx/angle/src/compiler/CompilerUniform.cpp
|
||||
--- a/gfx/angle/src/compiler/Uniform.cpp
|
||||
+++ b/gfx/angle/src/compiler/CompilerUniform.cpp
|
||||
@@ -1,15 +1,15 @@
|
||||
//
|
||||
// Copyright (c) 2013 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/Uniform.h"
|
||||
+#include "CompilerUniform.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
Uniform::Uniform(GLenum type, GLenum precision, const char *name, int arraySize, int registerIndex)
|
||||
{
|
||||
this->type = type;
|
||||
this->precision = precision;
|
||||
diff --git a/gfx/angle/src/compiler/Uniform.h b/gfx/angle/src/compiler/CompilerUniform.h
|
||||
rename from gfx/angle/src/compiler/Uniform.h
|
||||
rename to gfx/angle/src/compiler/CompilerUniform.h
|
||||
diff --git a/gfx/angle/src/compiler/OutputHLSL.h b/gfx/angle/src/compiler/OutputHLSL.h
|
||||
--- a/gfx/angle/src/compiler/OutputHLSL.h
|
||||
+++ b/gfx/angle/src/compiler/OutputHLSL.h
|
||||
@@ -11,17 +11,17 @@
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
#define GL_APICALL
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
#include "compiler/intermediate.h"
|
||||
#include "compiler/ParseHelper.h"
|
||||
-#include "compiler/Uniform.h"
|
||||
+#include "compiler/CompilerUniform.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
class UnfoldShortCircuit;
|
||||
|
||||
class OutputHLSL : public TIntermTraverser
|
||||
{
|
||||
public:
|
||||
diff --git a/gfx/angle/src/compiler/TranslatorHLSL.h b/gfx/angle/src/compiler/TranslatorHLSL.h
|
||||
--- a/gfx/angle/src/compiler/TranslatorHLSL.h
|
||||
+++ b/gfx/angle/src/compiler/TranslatorHLSL.h
|
||||
@@ -3,17 +3,17 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_TRANSLATORHLSL_H_
|
||||
#define COMPILER_TRANSLATORHLSL_H_
|
||||
|
||||
#include "compiler/ShHandle.h"
|
||||
-#include "compiler/Uniform.h"
|
||||
+#include "compiler/CompilerUniform.h"
|
||||
|
||||
class TranslatorHLSL : public TCompiler {
|
||||
public:
|
||||
TranslatorHLSL(ShShaderType type, ShShaderSpec spec, ShShaderOutput output);
|
||||
|
||||
virtual TranslatorHLSL *getAsTranslatorHLSL() { return this; }
|
||||
const sh::ActiveUniforms &getUniforms() { return mActiveUniforms; }
|
||||
|
||||
diff --git a/gfx/angle/src/libGLESv2/Shader.h b/gfx/angle/src/libGLESv2/Shader.h
|
||||
--- a/gfx/angle/src/libGLESv2/Shader.h
|
||||
+++ b/gfx/angle/src/libGLESv2/Shader.h
|
||||
@@ -13,17 +13,17 @@
|
||||
#define LIBGLESV2_SHADER_H_
|
||||
|
||||
#define GL_APICALL
|
||||
#include <GLES2/gl2.h>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
-#include "compiler/Uniform.h"
|
||||
+#include "compiler/CompilerUniform.h"
|
||||
#include "common/angleutils.h"
|
||||
|
||||
namespace rx
|
||||
{
|
||||
class Renderer;
|
||||
}
|
||||
|
||||
namespace gl
|
|
@ -0,0 +1,52 @@
|
|||
From: Jeff Gilbert <jgilbert@mozilla.com>
|
||||
|
||||
diff --git a/gfx/angle/src/compiler/Types.h b/gfx/angle/src/compiler/Types.h
|
||||
--- a/gfx/angle/src/compiler/Types.h
|
||||
+++ b/gfx/angle/src/compiler/Types.h
|
||||
@@ -90,17 +90,17 @@ private:
|
||||
//
|
||||
// Base class for things that have a type.
|
||||
//
|
||||
class TType
|
||||
{
|
||||
public:
|
||||
POOL_ALLOCATOR_NEW_DELETE();
|
||||
TType() {}
|
||||
- TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) :
|
||||
+ TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, char s = 1, bool m = false, bool a = false) :
|
||||
type(t), precision(p), qualifier(q), size(s), matrix(m), array(a), arraySize(0), structure(0)
|
||||
{
|
||||
}
|
||||
explicit TType(const TPublicType &p);
|
||||
TType(TStructure* userDef, TPrecision p = EbpUndefined) :
|
||||
type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0), structure(userDef)
|
||||
{
|
||||
}
|
||||
@@ -229,22 +229,22 @@ public:
|
||||
|
||||
bool isStructureContainingArrays() const {
|
||||
return structure ? structure->containsArrays() : false;
|
||||
}
|
||||
|
||||
private:
|
||||
TString buildMangledName() const;
|
||||
|
||||
- TBasicType type : 6;
|
||||
+ TBasicType type;
|
||||
TPrecision precision;
|
||||
- TQualifier qualifier : 7;
|
||||
- int size : 8; // size of vector or matrix, not size of array
|
||||
- unsigned int matrix : 1;
|
||||
- unsigned int array : 1;
|
||||
+ TQualifier qualifier;
|
||||
+ char size; // size of vector or matrix, not size of array
|
||||
+ bool matrix;
|
||||
+ bool array;
|
||||
int arraySize;
|
||||
|
||||
TStructure* structure; // 0 unless this is a struct
|
||||
|
||||
mutable TString mangled;
|
||||
};
|
||||
|
||||
//
|
|
@ -1,50 +0,0 @@
|
|||
From: Jacek Caban <jacek@codeweavers.com>
|
||||
Bug 840577 - Fix ANGLE cross compilation on case sensitive OSes, relanded
|
||||
|
||||
|
||||
diff --git a/gfx/angle/src/common/system.h b/gfx/angle/src/common/system.h
|
||||
index f071a05..74f659b 100644
|
||||
--- a/gfx/angle/src/common/system.h
|
||||
+++ b/gfx/angle/src/common/system.h
|
||||
@@ -10,17 +10,17 @@
|
||||
#define COMMON_SYSTEM_H
|
||||
|
||||
#if !defined(WIN32_LEAN_AND_MEAN)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#include <d3d9.h>
|
||||
-#include <D3Dcompiler.h>
|
||||
+#include <d3dcompiler.h>
|
||||
#include <d3d9types.h>
|
||||
#include <mmsystem.h>
|
||||
|
||||
#if defined(min)
|
||||
#undef min
|
||||
#endif
|
||||
|
||||
#if defined(max)
|
||||
diff --git a/gfx/angle/src/libEGL/Display.h b/gfx/angle/src/libEGL/Display.h
|
||||
index 5859cf2..a1a7870 100644
|
||||
--- a/gfx/angle/src/libEGL/Display.h
|
||||
+++ b/gfx/angle/src/libEGL/Display.h
|
||||
@@ -8,17 +8,17 @@
|
||||
// display on which graphics are drawn. Implements EGLDisplay.
|
||||
// [EGL 1.4] section 2.1.2 page 3.
|
||||
|
||||
#ifndef LIBEGL_DISPLAY_H_
|
||||
#define LIBEGL_DISPLAY_H_
|
||||
|
||||
#include "common/system.h"
|
||||
#include <d3d9.h>
|
||||
-#include <D3Dcompiler.h>
|
||||
+#include <d3dcompiler.h>
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "libGLESv2/Context.h"
|
||||
|
||||
#include "libEGL/Config.h"
|
||||
#include "libEGL/ShaderCache.h"
|
|
@ -3,7 +3,7 @@ From: Jeff Gilbert <jgilbert@mozilla.com>
|
|||
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
|
||||
@@ -124,18 +124,21 @@ bool TCompiler::Init(const ShBuiltInReso
|
||||
@@ -130,18 +130,21 @@ bool TCompiler::Init(const ShBuiltInReso
|
||||
TScopedPoolAllocator scopedAlloc(&allocator, false);
|
||||
|
||||
// Generate built-in symbol table.
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
# HG changeset patch
|
||||
# Parent 308e3cf5ba75fdf8ed3bdd3dc766410b708b98ef
|
||||
|
||||
diff --git a/gfx/angle/src/libGLESv2/IndexDataManager.cpp b/gfx/angle/src/libGLESv2/IndexDataManager.cpp
|
||||
--- a/gfx/angle/src/libGLESv2/IndexDataManager.cpp
|
||||
+++ b/gfx/angle/src/libGLESv2/IndexDataManager.cpp
|
||||
@@ -375,17 +375,18 @@ void StreamingIndexBuffer::reserveSpace(
|
||||
|
||||
if (FAILED(result))
|
||||
{
|
||||
ERR("Out of memory allocating a vertex buffer of size %lu.", mBufferSize);
|
||||
}
|
||||
|
||||
mWritePosition = 0;
|
||||
}
|
||||
- else if (mWritePosition + requiredSpace > mBufferSize) // Recycle
|
||||
+ else if (mWritePosition + requiredSpace > mBufferSize ||
|
||||
+ mWritePosition + requiredSpace < mWritePosition) // Recycle
|
||||
{
|
||||
void *dummy;
|
||||
mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
|
||||
mIndexBuffer->Unlock();
|
||||
|
||||
mWritePosition = 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
From: Jeff Gilbert <jgilbert@mozilla.com>
|
||||
|
||||
diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
|
||||
--- a/gfx/angle/Makefile.in
|
||||
+++ b/gfx/angle/Makefile.in
|
||||
@@ -32,16 +32,17 @@ LOCAL_INCLUDES += \
|
||||
-I$(srcdir)/src
|
||||
|
||||
DEFINES += -DCOMPILER_IMPLEMENTATION
|
||||
|
||||
VPATH += $(srcdir)/src/compiler
|
||||
VPATH += $(srcdir)/src/compiler/depgraph
|
||||
VPATH += $(srcdir)/src/compiler/timing
|
||||
VPATH += $(srcdir)/src/third_party/compiler
|
||||
+VPATH += $(srcdir)/src/third_party/murmurhash
|
||||
|
||||
# Target: 'translator_glsl'
|
||||
# Requires: 'translator_common'
|
||||
# src/compiler:
|
||||
ifdef MOZ_ANGLE_RENDERER
|
||||
|
||||
libs::
|
||||
ifdef MOZ_D3DCOMPILER_CAB
|
||||
diff --git a/gfx/angle/moz.build b/gfx/angle/moz.build
|
||||
--- a/gfx/angle/moz.build
|
||||
+++ b/gfx/angle/moz.build
|
||||
@@ -83,16 +83,21 @@ CPP_SOURCES += [
|
||||
'RestrictVertexShaderTiming.cpp',
|
||||
]
|
||||
|
||||
# src/third_party/compiler:
|
||||
CPP_SOURCES += [
|
||||
'ArrayBoundsClamper.cpp',
|
||||
]
|
||||
|
||||
+# src/third_party/murmurhash:
|
||||
+CPP_SOURCES += [
|
||||
+ 'MurmurHash3.cpp',
|
||||
+]
|
||||
+
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
CPP_SOURCES += [
|
||||
'ossource_win.cpp',
|
||||
]
|
||||
else:
|
||||
CPP_SOURCES += [
|
||||
'ossource_posix.cpp',
|
||||
]
|
||||
diff --git a/gfx/angle/src/compiler/MapLongVariableNames.cpp b/gfx/angle/src/compiler/MapLongVariableNames.cpp
|
||||
--- a/gfx/angle/src/compiler/MapLongVariableNames.cpp
|
||||
+++ b/gfx/angle/src/compiler/MapLongVariableNames.cpp
|
||||
@@ -1,29 +1,39 @@
|
||||
//
|
||||
// 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/MapLongVariableNames.h"
|
||||
|
||||
+#include "third_party/murmurhash/MurmurHash3.h"
|
||||
+
|
||||
namespace {
|
||||
|
||||
TString mapLongName(size_t id, const TString& name, bool isGlobal)
|
||||
{
|
||||
ASSERT(name.size() > MAX_SHORTENED_IDENTIFIER_SIZE);
|
||||
TStringStream stream;
|
||||
- stream << "webgl_";
|
||||
- if (isGlobal)
|
||||
- stream << "g";
|
||||
- stream << id;
|
||||
- if (name[0] != '_')
|
||||
- stream << "_";
|
||||
- stream << name.substr(0, MAX_SHORTENED_IDENTIFIER_SIZE - stream.str().size());
|
||||
+
|
||||
+ uint64_t hash[2] = {0, 0};
|
||||
+ MurmurHash3_x64_128(name.data(), name.length(), 0, hash);
|
||||
+
|
||||
+ // We want to avoid producing a string with a double underscore,
|
||||
+ // which would be an illegal GLSL identifier. We can assume that the
|
||||
+ // original identifier doesn't have a double underscore, otherwise
|
||||
+ // it's illegal anyway.
|
||||
+ stream << (name[0] == '_' ? "webgl" : "webgl_")
|
||||
+ << name.substr(0, 9)
|
||||
+ << (name[8] == '_' ? "" : "_")
|
||||
+ << std::hex
|
||||
+ << hash[0];
|
||||
+ ASSERT(stream.str().length() <= MAX_SHORTENED_IDENTIFIER_SIZE);
|
||||
+ ASSERT(stream.str().length() >= MAX_SHORTENED_IDENTIFIER_SIZE - 2);
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
LongNameMap* gLongNameMapInstance = NULL;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
LongNameMap::LongNameMap()
|
||||
diff --git a/gfx/angle/src/libGLESv2/moz.build b/gfx/angle/src/libGLESv2/moz.build
|
||||
--- a/gfx/angle/src/libGLESv2/moz.build
|
||||
+++ b/gfx/angle/src/libGLESv2/moz.build
|
||||
@@ -71,16 +71,21 @@ CPP_SOURCES += [
|
||||
'RestrictVertexShaderTiming.cpp',
|
||||
]
|
||||
|
||||
# src/third_party/compiler:
|
||||
CPP_SOURCES += [
|
||||
'ArrayBoundsClamper.cpp',
|
||||
]
|
||||
|
||||
+# src/third_party/murmurhash:
|
||||
+CPP_SOURCES += [
|
||||
+ 'MurmurHash3.cpp',
|
||||
+]
|
||||
+
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
CPP_SOURCES += [
|
||||
'ossource_win.cpp',
|
||||
]
|
||||
else:
|
||||
CPP_SOURCES += [
|
||||
'ossource_posix.cpp',
|
||||
]
|
||||
@@ -165,13 +170,8 @@ CPP_SOURCES += [
|
||||
'TextureStorage11.cpp',
|
||||
'TextureStorage9.cpp',
|
||||
'VertexBuffer.cpp',
|
||||
'VertexBuffer9.cpp',
|
||||
'VertexBuffer11.cpp',
|
||||
'VertexDataManager.cpp',
|
||||
'VertexDeclarationCache.cpp',
|
||||
]
|
||||
-
|
||||
-# src/third_party/murmurhash:
|
||||
-CPP_SOURCES += [
|
||||
- 'MurmurHash3.cpp',
|
||||
-]
|
|
@ -1,743 +0,0 @@
|
|||
# HG changeset patch
|
||||
# Parent 262218204644915abb2add8aa52195c24035c293
|
||||
|
||||
diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
|
||||
--- a/gfx/angle/Makefile.in
|
||||
+++ b/gfx/angle/Makefile.in
|
||||
@@ -84,16 +84,17 @@ CPPSRCS += \
|
||||
intermOut.cpp \
|
||||
IntermTraverse.cpp \
|
||||
MapLongVariableNames.cpp \
|
||||
parseConst.cpp \
|
||||
ParseHelper.cpp \
|
||||
PoolAlloc.cpp \
|
||||
QualifierAlive.cpp \
|
||||
RemoveTree.cpp \
|
||||
+ spooky.cpp \
|
||||
SymbolTable.cpp \
|
||||
util.cpp \
|
||||
ValidateLimitations.cpp \
|
||||
VariableInfo.cpp \
|
||||
VariablePacker.cpp \
|
||||
$(NULL)
|
||||
|
||||
VPATH += $(srcdir)/src/compiler/depgraph
|
||||
diff --git a/gfx/angle/src/compiler/MapLongVariableNames.cpp b/gfx/angle/src/compiler/MapLongVariableNames.cpp
|
||||
--- a/gfx/angle/src/compiler/MapLongVariableNames.cpp
|
||||
+++ b/gfx/angle/src/compiler/MapLongVariableNames.cpp
|
||||
@@ -1,29 +1,36 @@
|
||||
//
|
||||
// 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/MapLongVariableNames.h"
|
||||
+#include "spooky.h"
|
||||
|
||||
namespace {
|
||||
|
||||
TString mapLongName(size_t id, const TString& name, bool isGlobal)
|
||||
{
|
||||
ASSERT(name.size() > MAX_SHORTENED_IDENTIFIER_SIZE);
|
||||
TStringStream stream;
|
||||
- stream << "webgl_";
|
||||
- if (isGlobal)
|
||||
- stream << "g";
|
||||
- stream << id;
|
||||
- if (name[0] != '_')
|
||||
- stream << "_";
|
||||
- stream << name.substr(0, MAX_SHORTENED_IDENTIFIER_SIZE - stream.str().size());
|
||||
+ uint64 hash = SpookyHash::Hash64(name.data(), name.length(), 0);
|
||||
+
|
||||
+ // We want to avoid producing a string with a double underscore,
|
||||
+ // which would be an illegal GLSL identifier. We can assume that the
|
||||
+ // original identifier doesn't have a double underscore, otherwise
|
||||
+ // it's illegal anyway.
|
||||
+ stream << (name[0] == '_' ? "webgl" : "webgl_")
|
||||
+ << name.substr(0, 9)
|
||||
+ << (name[8] == '_' ? "" : "_")
|
||||
+ << std::hex
|
||||
+ << hash;
|
||||
+ ASSERT(stream.str().length() <= MAX_SHORTENED_IDENTIFIER_SIZE);
|
||||
+ ASSERT(stream.str().length() >= MAX_SHORTENED_IDENTIFIER_SIZE - 2);
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
LongNameMap* gLongNameMapInstance = NULL;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
LongNameMap::LongNameMap()
|
||||
diff --git a/gfx/angle/src/compiler/spooky.cpp b/gfx/angle/src/compiler/spooky.cpp
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/gfx/angle/src/compiler/spooky.cpp
|
||||
@@ -0,0 +1,348 @@
|
||||
+// Spooky Hash
|
||||
+// A 128-bit noncryptographic hash, for checksums and table lookup
|
||||
+// By Bob Jenkins. Public domain.
|
||||
+// Oct 31 2010: published framework, disclaimer ShortHash isn't right
|
||||
+// Nov 7 2010: disabled ShortHash
|
||||
+// Oct 31 2011: replace End, ShortMix, ShortEnd, enable ShortHash again
|
||||
+
|
||||
+#include <memory.h>
|
||||
+#include <string.h>
|
||||
+#include "spooky.h"
|
||||
+
|
||||
+#define ALLOW_UNALIGNED_READS 1
|
||||
+
|
||||
+//
|
||||
+// short hash ... it could be used on any message,
|
||||
+// but it's used by Spooky just for short messages.
|
||||
+//
|
||||
+void SpookyHash::Short(
|
||||
+ const void *message,
|
||||
+ size_t length,
|
||||
+ uint64 *hash1,
|
||||
+ uint64 *hash2)
|
||||
+{
|
||||
+ uint64 buf[sc_numVars];
|
||||
+ union
|
||||
+ {
|
||||
+ const uint8 *p8;
|
||||
+ uint32 *p32;
|
||||
+ uint64 *p64;
|
||||
+ size_t i;
|
||||
+ } u;
|
||||
+
|
||||
+ u.p8 = (const uint8 *)message;
|
||||
+
|
||||
+ if (!ALLOW_UNALIGNED_READS && (u.i & 0x7))
|
||||
+ {
|
||||
+ memcpy(buf, message, length);
|
||||
+ u.p64 = buf;
|
||||
+ }
|
||||
+
|
||||
+ size_t remainder = length%32;
|
||||
+ uint64 a=*hash1;
|
||||
+ uint64 b=*hash2;
|
||||
+ uint64 c=sc_const;
|
||||
+ uint64 d=sc_const;
|
||||
+
|
||||
+ if (length > 15)
|
||||
+ {
|
||||
+ const uint64 *end = u.p64 + (length/32)*4;
|
||||
+
|
||||
+ // handle all complete sets of 32 bytes
|
||||
+ for (; u.p64 < end; u.p64 += 4)
|
||||
+ {
|
||||
+ c += u.p64[0];
|
||||
+ d += u.p64[1];
|
||||
+ ShortMix(a,b,c,d);
|
||||
+ a += u.p64[2];
|
||||
+ b += u.p64[3];
|
||||
+ }
|
||||
+
|
||||
+ //Handle the case of 16+ remaining bytes.
|
||||
+ if (remainder >= 16)
|
||||
+ {
|
||||
+ c += u.p64[0];
|
||||
+ d += u.p64[1];
|
||||
+ ShortMix(a,b,c,d);
|
||||
+ u.p64 += 2;
|
||||
+ remainder -= 16;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // Handle the last 0..15 bytes, and its length
|
||||
+ d = ((uint64)length) << 56;
|
||||
+ switch (remainder)
|
||||
+ {
|
||||
+ case 15:
|
||||
+ d += ((uint64)u.p8[14]) << 48;
|
||||
+ case 14:
|
||||
+ d += ((uint64)u.p8[13]) << 40;
|
||||
+ case 13:
|
||||
+ d += ((uint64)u.p8[12]) << 32;
|
||||
+ case 12:
|
||||
+ d += u.p32[2];
|
||||
+ c += u.p64[0];
|
||||
+ break;
|
||||
+ case 11:
|
||||
+ d += ((uint64)u.p8[10]) << 16;
|
||||
+ case 10:
|
||||
+ d += ((uint64)u.p8[9]) << 8;
|
||||
+ case 9:
|
||||
+ d += (uint64)u.p8[8];
|
||||
+ case 8:
|
||||
+ c += u.p64[0];
|
||||
+ break;
|
||||
+ case 7:
|
||||
+ c += ((uint64)u.p8[6]) << 48;
|
||||
+ case 6:
|
||||
+ c += ((uint64)u.p8[5]) << 40;
|
||||
+ case 5:
|
||||
+ c += ((uint64)u.p8[4]) << 32;
|
||||
+ case 4:
|
||||
+ c += u.p32[0];
|
||||
+ break;
|
||||
+ case 3:
|
||||
+ c += ((uint64)u.p8[2]) << 16;
|
||||
+ case 2:
|
||||
+ c += ((uint64)u.p8[1]) << 8;
|
||||
+ case 1:
|
||||
+ c += (uint64)u.p8[0];
|
||||
+ break;
|
||||
+ case 0:
|
||||
+ c += sc_const;
|
||||
+ d += sc_const;
|
||||
+ }
|
||||
+ ShortEnd(a,b,c,d);
|
||||
+ *hash1 = a;
|
||||
+ *hash2 = b;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+// do the whole hash in one call
|
||||
+void SpookyHash::Hash128(
|
||||
+ const void *message,
|
||||
+ size_t length,
|
||||
+ uint64 *hash1,
|
||||
+ uint64 *hash2)
|
||||
+{
|
||||
+ if (length < sc_bufSize)
|
||||
+ {
|
||||
+ Short(message, length, hash1, hash2);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ uint64 h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11;
|
||||
+ uint64 buf[sc_numVars];
|
||||
+ uint64 *end;
|
||||
+ union
|
||||
+ {
|
||||
+ const uint8 *p8;
|
||||
+ uint64 *p64;
|
||||
+ size_t i;
|
||||
+ } u;
|
||||
+ size_t remainder;
|
||||
+
|
||||
+ h0=h3=h6=h9 = *hash1;
|
||||
+ h1=h4=h7=h10 = *hash2;
|
||||
+ h2=h5=h8=h11 = sc_const;
|
||||
+
|
||||
+ u.p8 = (const uint8 *)message;
|
||||
+ end = u.p64 + (length/sc_blockSize)*sc_numVars;
|
||||
+
|
||||
+ // handle all whole sc_blockSize blocks of bytes
|
||||
+ if (ALLOW_UNALIGNED_READS || ((u.i & 0x7) == 0))
|
||||
+ {
|
||||
+ while (u.p64 < end)
|
||||
+ {
|
||||
+ Mix(u.p64, h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11);
|
||||
+ u.p64 += sc_numVars;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ while (u.p64 < end)
|
||||
+ {
|
||||
+ memcpy(buf, u.p64, sc_blockSize);
|
||||
+ Mix(buf, h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11);
|
||||
+ u.p64 += sc_numVars;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // handle the last partial block of sc_blockSize bytes
|
||||
+ remainder = (length - ((const uint8 *)end-(const uint8 *)message));
|
||||
+ memcpy(buf, end, remainder);
|
||||
+ memset(((uint8 *)buf)+remainder, 0, sc_blockSize-remainder);
|
||||
+ ((uint8 *)buf)[sc_blockSize-1] = remainder;
|
||||
+ Mix(buf, h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11);
|
||||
+
|
||||
+ // do some final mixing
|
||||
+ End(h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11);
|
||||
+ *hash1 = h0;
|
||||
+ *hash2 = h1;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+
|
||||
+// init spooky state
|
||||
+void SpookyHash::Init(uint64 seed1, uint64 seed2)
|
||||
+{
|
||||
+ m_length = 0;
|
||||
+ m_remainder = 0;
|
||||
+ m_state[0] = seed1;
|
||||
+ m_state[1] = seed2;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+// add a message fragment to the state
|
||||
+void SpookyHash::Update(const void *message, size_t length)
|
||||
+{
|
||||
+ uint64 h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11;
|
||||
+ size_t newLength = length + m_remainder;
|
||||
+ uint8 remainder;
|
||||
+ union
|
||||
+ {
|
||||
+ const uint8 *p8;
|
||||
+ uint64 *p64;
|
||||
+ size_t i;
|
||||
+ } u;
|
||||
+ const uint64 *end;
|
||||
+
|
||||
+ // Is this message fragment too short? If it is, stuff it away.
|
||||
+ if (newLength < sc_bufSize)
|
||||
+ {
|
||||
+ memcpy(&((uint8 *)m_data)[m_remainder], message, length);
|
||||
+ m_length = length + m_length;
|
||||
+ m_remainder = (uint8)newLength;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ // init the variables
|
||||
+ if (m_length < sc_bufSize)
|
||||
+ {
|
||||
+ h0=h3=h6=h9 = m_state[0];
|
||||
+ h1=h4=h7=h10 = m_state[1];
|
||||
+ h2=h5=h8=h11 = sc_const;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ h0 = m_state[0];
|
||||
+ h1 = m_state[1];
|
||||
+ h2 = m_state[2];
|
||||
+ h3 = m_state[3];
|
||||
+ h4 = m_state[4];
|
||||
+ h5 = m_state[5];
|
||||
+ h6 = m_state[6];
|
||||
+ h7 = m_state[7];
|
||||
+ h8 = m_state[8];
|
||||
+ h9 = m_state[9];
|
||||
+ h10 = m_state[10];
|
||||
+ h11 = m_state[11];
|
||||
+ }
|
||||
+ m_length = length + m_length;
|
||||
+
|
||||
+ // if we've got anything stuffed away, use it now
|
||||
+ if (m_remainder)
|
||||
+ {
|
||||
+ uint8 prefix = sc_bufSize-m_remainder;
|
||||
+ memcpy(&(((uint8 *)m_data)[m_remainder]), message, prefix);
|
||||
+ u.p64 = m_data;
|
||||
+ Mix(u.p64, h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11);
|
||||
+ Mix(&u.p64[sc_numVars], h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11);
|
||||
+ u.p8 = ((const uint8 *)message) + prefix;
|
||||
+ length -= prefix;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ u.p8 = (const uint8 *)message;
|
||||
+ }
|
||||
+
|
||||
+ // handle all whole blocks of sc_blockSize bytes
|
||||
+ end = u.p64 + (length/sc_blockSize)*sc_numVars;
|
||||
+ remainder = (uint8)(length-((const uint8 *)end-u.p8));
|
||||
+ if (ALLOW_UNALIGNED_READS || (u.i & 0x7) == 0)
|
||||
+ {
|
||||
+ while (u.p64 < end)
|
||||
+ {
|
||||
+ Mix(u.p64, h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11);
|
||||
+ u.p64 += sc_numVars;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ while (u.p64 < end)
|
||||
+ {
|
||||
+ memcpy(m_data, u.p8, sc_blockSize);
|
||||
+ Mix(m_data, h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11);
|
||||
+ u.p64 += sc_numVars;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // stuff away the last few bytes
|
||||
+ m_remainder = remainder;
|
||||
+ memcpy(m_data, end, remainder);
|
||||
+
|
||||
+ // stuff away the variables
|
||||
+ m_state[0] = h0;
|
||||
+ m_state[1] = h1;
|
||||
+ m_state[2] = h2;
|
||||
+ m_state[3] = h3;
|
||||
+ m_state[4] = h4;
|
||||
+ m_state[5] = h5;
|
||||
+ m_state[6] = h6;
|
||||
+ m_state[7] = h7;
|
||||
+ m_state[8] = h8;
|
||||
+ m_state[9] = h9;
|
||||
+ m_state[10] = h10;
|
||||
+ m_state[11] = h11;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+// report the hash for the concatenation of all message fragments so far
|
||||
+void SpookyHash::Final(uint64 *hash1, uint64 *hash2)
|
||||
+{
|
||||
+ // init the variables
|
||||
+ if (m_length < sc_bufSize)
|
||||
+ {
|
||||
+ Short( m_data, m_length, hash1, hash2);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ const uint64 *data = (const uint64 *)m_data;
|
||||
+ uint8 remainder = m_remainder;
|
||||
+
|
||||
+ uint64 h0 = m_state[0];
|
||||
+ uint64 h1 = m_state[1];
|
||||
+ uint64 h2 = m_state[2];
|
||||
+ uint64 h3 = m_state[3];
|
||||
+ uint64 h4 = m_state[4];
|
||||
+ uint64 h5 = m_state[5];
|
||||
+ uint64 h6 = m_state[6];
|
||||
+ uint64 h7 = m_state[7];
|
||||
+ uint64 h8 = m_state[8];
|
||||
+ uint64 h9 = m_state[9];
|
||||
+ uint64 h10 = m_state[10];
|
||||
+ uint64 h11 = m_state[11];
|
||||
+
|
||||
+ if (remainder >= sc_blockSize)
|
||||
+ {
|
||||
+ // m_data can contain two blocks; handle any whole first block
|
||||
+ Mix(data, h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11);
|
||||
+ data += sc_numVars;
|
||||
+ remainder -= sc_blockSize;
|
||||
+ }
|
||||
+
|
||||
+ // mix in the last partial block, and the length mod sc_blockSize
|
||||
+ memset(&((uint8 *)data)[remainder], 0, (sc_blockSize-remainder));
|
||||
+
|
||||
+ ((uint8 *)data)[sc_blockSize-1] = remainder;
|
||||
+ Mix(data, h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11);
|
||||
+
|
||||
+ // do some final mixing
|
||||
+ End(h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11);
|
||||
+
|
||||
+ *hash1 = h0;
|
||||
+ *hash2 = h1;
|
||||
+}
|
||||
+
|
||||
diff --git a/gfx/angle/src/compiler/spooky.h b/gfx/angle/src/compiler/spooky.h
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/gfx/angle/src/compiler/spooky.h
|
||||
@@ -0,0 +1,293 @@
|
||||
+//
|
||||
+// SpookyHash: a 128-bit noncryptographic hash function
|
||||
+// By Bob Jenkins, public domain
|
||||
+// Oct 31 2010: alpha, framework + SpookyHash::Mix appears right
|
||||
+// Oct 31 2011: alpha again, Mix only good to 2^^69 but rest appears right
|
||||
+// Dec 31 2011: beta, improved Mix, tested it for 2-bit deltas
|
||||
+// Feb 2 2012: production, same bits as beta
|
||||
+// Feb 5 2012: adjusted definitions of uint* to be more portable
|
||||
+//
|
||||
+// Up to 4 bytes/cycle for long messages. Reasonably fast for short messages.
|
||||
+// All 1 or 2 bit deltas achieve avalanche within 1% bias per output bit.
|
||||
+//
|
||||
+// This was developed for and tested on 64-bit x86-compatible processors.
|
||||
+// It assumes the processor is little-endian. There is a macro
|
||||
+// controlling whether unaligned reads are allowed (by default they are).
|
||||
+// This should be an equally good hash on big-endian machines, but it will
|
||||
+// compute different results on them than on little-endian machines.
|
||||
+//
|
||||
+// Google's CityHash has similar specs to SpookyHash, and CityHash is faster
|
||||
+// on some platforms. MD4 and MD5 also have similar specs, but they are orders
|
||||
+// of magnitude slower. CRCs are two or more times slower, but unlike
|
||||
+// SpookyHash, they have nice math for combining the CRCs of pieces to form
|
||||
+// the CRCs of wholes. There are also cryptographic hashes, but those are even
|
||||
+// slower than MD5.
|
||||
+//
|
||||
+
|
||||
+#include <stddef.h>
|
||||
+
|
||||
+#ifdef _MSC_VER
|
||||
+# define INLINE __forceinline
|
||||
+ typedef unsigned __int64 uint64;
|
||||
+ typedef unsigned __int32 uint32;
|
||||
+ typedef unsigned __int16 uint16;
|
||||
+ typedef unsigned __int8 uint8;
|
||||
+#else
|
||||
+# include <stdint.h>
|
||||
+# define INLINE inline
|
||||
+ typedef uint64_t uint64;
|
||||
+ typedef uint32_t uint32;
|
||||
+ typedef uint16_t uint16;
|
||||
+ typedef uint8_t uint8;
|
||||
+#endif
|
||||
+
|
||||
+
|
||||
+class SpookyHash
|
||||
+{
|
||||
+public:
|
||||
+ //
|
||||
+ // SpookyHash: hash a single message in one call, produce 128-bit output
|
||||
+ //
|
||||
+ static void Hash128(
|
||||
+ const void *message, // message to hash
|
||||
+ size_t length, // length of message in bytes
|
||||
+ uint64 *hash1, // in/out: in seed 1, out hash value 1
|
||||
+ uint64 *hash2); // in/out: in seed 2, out hash value 2
|
||||
+
|
||||
+ //
|
||||
+ // Hash64: hash a single message in one call, return 64-bit output
|
||||
+ //
|
||||
+ static uint64 Hash64(
|
||||
+ const void *message, // message to hash
|
||||
+ size_t length, // length of message in bytes
|
||||
+ uint64 seed) // seed
|
||||
+ {
|
||||
+ uint64 hash1 = seed;
|
||||
+ Hash128(message, length, &hash1, &seed);
|
||||
+ return hash1;
|
||||
+ }
|
||||
+
|
||||
+ //
|
||||
+ // Hash32: hash a single message in one call, produce 32-bit output
|
||||
+ //
|
||||
+ static uint32 Hash32(
|
||||
+ const void *message, // message to hash
|
||||
+ size_t length, // length of message in bytes
|
||||
+ uint32 seed) // seed
|
||||
+ {
|
||||
+ uint64 hash1 = seed, hash2 = seed;
|
||||
+ Hash128(message, length, &hash1, &hash2);
|
||||
+ return (uint32)hash1;
|
||||
+ }
|
||||
+
|
||||
+ //
|
||||
+ // Init: initialize the context of a SpookyHash
|
||||
+ //
|
||||
+ void Init(
|
||||
+ uint64 seed1, // any 64-bit value will do, including 0
|
||||
+ uint64 seed2); // different seeds produce independent hashes
|
||||
+
|
||||
+ //
|
||||
+ // Update: add a piece of a message to a SpookyHash state
|
||||
+ //
|
||||
+ void Update(
|
||||
+ const void *message, // message fragment
|
||||
+ size_t length); // length of message fragment in bytes
|
||||
+
|
||||
+
|
||||
+ //
|
||||
+ // Final: compute the hash for the current SpookyHash state
|
||||
+ //
|
||||
+ // This does not modify the state; you can keep updating it afterward
|
||||
+ //
|
||||
+ // The result is the same as if SpookyHash() had been called with
|
||||
+ // all the pieces concatenated into one message.
|
||||
+ //
|
||||
+ void Final(
|
||||
+ uint64 *hash1, // out only: first 64 bits of hash value.
|
||||
+ uint64 *hash2); // out only: second 64 bits of hash value.
|
||||
+
|
||||
+ //
|
||||
+ // left rotate a 64-bit value by k bytes
|
||||
+ //
|
||||
+ static INLINE uint64 Rot64(uint64 x, int k)
|
||||
+ {
|
||||
+ return (x << k) | (x >> (64 - k));
|
||||
+ }
|
||||
+
|
||||
+ //
|
||||
+ // This is used if the input is 96 bytes long or longer.
|
||||
+ //
|
||||
+ // The internal state is fully overwritten every 96 bytes.
|
||||
+ // Every input bit appears to cause at least 128 bits of entropy
|
||||
+ // before 96 other bytes are combined, when run forward or backward
|
||||
+ // For every input bit,
|
||||
+ // Two inputs differing in just that input bit
|
||||
+ // Where "differ" means xor or subtraction
|
||||
+ // And the base value is random
|
||||
+ // When run forward or backwards one Mix
|
||||
+ // I tried 3 pairs of each; they all differed by at least 212 bits.
|
||||
+ //
|
||||
+ static INLINE void Mix(
|
||||
+ const uint64 *data,
|
||||
+ uint64 &s0, uint64 &s1, uint64 &s2, uint64 &s3,
|
||||
+ uint64 &s4, uint64 &s5, uint64 &s6, uint64 &s7,
|
||||
+ uint64 &s8, uint64 &s9, uint64 &s10,uint64 &s11)
|
||||
+ {
|
||||
+ s0 += data[0]; s2 ^= s10; s11 ^= s0; s0 = Rot64(s0,11); s11 += s1;
|
||||
+ s1 += data[1]; s3 ^= s11; s0 ^= s1; s1 = Rot64(s1,32); s0 += s2;
|
||||
+ s2 += data[2]; s4 ^= s0; s1 ^= s2; s2 = Rot64(s2,43); s1 += s3;
|
||||
+ s3 += data[3]; s5 ^= s1; s2 ^= s3; s3 = Rot64(s3,31); s2 += s4;
|
||||
+ s4 += data[4]; s6 ^= s2; s3 ^= s4; s4 = Rot64(s4,17); s3 += s5;
|
||||
+ s5 += data[5]; s7 ^= s3; s4 ^= s5; s5 = Rot64(s5,28); s4 += s6;
|
||||
+ s6 += data[6]; s8 ^= s4; s5 ^= s6; s6 = Rot64(s6,39); s5 += s7;
|
||||
+ s7 += data[7]; s9 ^= s5; s6 ^= s7; s7 = Rot64(s7,57); s6 += s8;
|
||||
+ s8 += data[8]; s10 ^= s6; s7 ^= s8; s8 = Rot64(s8,55); s7 += s9;
|
||||
+ s9 += data[9]; s11 ^= s7; s8 ^= s9; s9 = Rot64(s9,54); s8 += s10;
|
||||
+ s10 += data[10]; s0 ^= s8; s9 ^= s10; s10 = Rot64(s10,22); s9 += s11;
|
||||
+ s11 += data[11]; s1 ^= s9; s10 ^= s11; s11 = Rot64(s11,46); s10 += s0;
|
||||
+ }
|
||||
+
|
||||
+ //
|
||||
+ // Mix all 12 inputs together so that h0, h1 are a hash of them all.
|
||||
+ //
|
||||
+ // For two inputs differing in just the input bits
|
||||
+ // Where "differ" means xor or subtraction
|
||||
+ // And the base value is random, or a counting value starting at that bit
|
||||
+ // The final result will have each bit of h0, h1 flip
|
||||
+ // For every input bit,
|
||||
+ // with probability 50 +- .3%
|
||||
+ // For every pair of input bits,
|
||||
+ // with probability 50 +- 3%
|
||||
+ //
|
||||
+ // This does not rely on the last Mix() call having already mixed some.
|
||||
+ // Two iterations was almost good enough for a 64-bit result, but a
|
||||
+ // 128-bit result is reported, so End() does three iterations.
|
||||
+ //
|
||||
+ static INLINE void EndPartial(
|
||||
+ uint64 &h0, uint64 &h1, uint64 &h2, uint64 &h3,
|
||||
+ uint64 &h4, uint64 &h5, uint64 &h6, uint64 &h7,
|
||||
+ uint64 &h8, uint64 &h9, uint64 &h10,uint64 &h11)
|
||||
+ {
|
||||
+ h11+= h1; h2 ^= h11; h1 = Rot64(h1,44);
|
||||
+ h0 += h2; h3 ^= h0; h2 = Rot64(h2,15);
|
||||
+ h1 += h3; h4 ^= h1; h3 = Rot64(h3,34);
|
||||
+ h2 += h4; h5 ^= h2; h4 = Rot64(h4,21);
|
||||
+ h3 += h5; h6 ^= h3; h5 = Rot64(h5,38);
|
||||
+ h4 += h6; h7 ^= h4; h6 = Rot64(h6,33);
|
||||
+ h5 += h7; h8 ^= h5; h7 = Rot64(h7,10);
|
||||
+ h6 += h8; h9 ^= h6; h8 = Rot64(h8,13);
|
||||
+ h7 += h9; h10^= h7; h9 = Rot64(h9,38);
|
||||
+ h8 += h10; h11^= h8; h10= Rot64(h10,53);
|
||||
+ h9 += h11; h0 ^= h9; h11= Rot64(h11,42);
|
||||
+ h10+= h0; h1 ^= h10; h0 = Rot64(h0,54);
|
||||
+ }
|
||||
+
|
||||
+ static INLINE void End(
|
||||
+ uint64 &h0, uint64 &h1, uint64 &h2, uint64 &h3,
|
||||
+ uint64 &h4, uint64 &h5, uint64 &h6, uint64 &h7,
|
||||
+ uint64 &h8, uint64 &h9, uint64 &h10,uint64 &h11)
|
||||
+ {
|
||||
+ EndPartial(h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11);
|
||||
+ EndPartial(h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11);
|
||||
+ EndPartial(h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11);
|
||||
+ }
|
||||
+
|
||||
+ //
|
||||
+ // The goal is for each bit of the input to expand into 128 bits of
|
||||
+ // apparent entropy before it is fully overwritten.
|
||||
+ // n trials both set and cleared at least m bits of h0 h1 h2 h3
|
||||
+ // n: 2 m: 29
|
||||
+ // n: 3 m: 46
|
||||
+ // n: 4 m: 57
|
||||
+ // n: 5 m: 107
|
||||
+ // n: 6 m: 146
|
||||
+ // n: 7 m: 152
|
||||
+ // when run forwards or backwards
|
||||
+ // for all 1-bit and 2-bit diffs
|
||||
+ // with diffs defined by either xor or subtraction
|
||||
+ // with a base of all zeros plus a counter, or plus another bit, or random
|
||||
+ //
|
||||
+ static INLINE void ShortMix(uint64 &h0, uint64 &h1, uint64 &h2, uint64 &h3)
|
||||
+ {
|
||||
+ h2 = Rot64(h2,50); h2 += h3; h0 ^= h2;
|
||||
+ h3 = Rot64(h3,52); h3 += h0; h1 ^= h3;
|
||||
+ h0 = Rot64(h0,30); h0 += h1; h2 ^= h0;
|
||||
+ h1 = Rot64(h1,41); h1 += h2; h3 ^= h1;
|
||||
+ h2 = Rot64(h2,54); h2 += h3; h0 ^= h2;
|
||||
+ h3 = Rot64(h3,48); h3 += h0; h1 ^= h3;
|
||||
+ h0 = Rot64(h0,38); h0 += h1; h2 ^= h0;
|
||||
+ h1 = Rot64(h1,37); h1 += h2; h3 ^= h1;
|
||||
+ h2 = Rot64(h2,62); h2 += h3; h0 ^= h2;
|
||||
+ h3 = Rot64(h3,34); h3 += h0; h1 ^= h3;
|
||||
+ h0 = Rot64(h0,5); h0 += h1; h2 ^= h0;
|
||||
+ h1 = Rot64(h1,36); h1 += h2; h3 ^= h1;
|
||||
+ }
|
||||
+
|
||||
+ //
|
||||
+ // Mix all 4 inputs together so that h0, h1 are a hash of them all.
|
||||
+ //
|
||||
+ // For two inputs differing in just the input bits
|
||||
+ // Where "differ" means xor or subtraction
|
||||
+ // And the base value is random, or a counting value starting at that bit
|
||||
+ // The final result will have each bit of h0, h1 flip
|
||||
+ // For every input bit,
|
||||
+ // with probability 50 +- .3% (it is probably better than that)
|
||||
+ // For every pair of input bits,
|
||||
+ // with probability 50 +- .75% (the worst case is approximately that)
|
||||
+ //
|
||||
+ static INLINE void ShortEnd(uint64 &h0, uint64 &h1, uint64 &h2, uint64 &h3)
|
||||
+ {
|
||||
+ h3 ^= h2; h2 = Rot64(h2,15); h3 += h2;
|
||||
+ h0 ^= h3; h3 = Rot64(h3,52); h0 += h3;
|
||||
+ h1 ^= h0; h0 = Rot64(h0,26); h1 += h0;
|
||||
+ h2 ^= h1; h1 = Rot64(h1,51); h2 += h1;
|
||||
+ h3 ^= h2; h2 = Rot64(h2,28); h3 += h2;
|
||||
+ h0 ^= h3; h3 = Rot64(h3,9); h0 += h3;
|
||||
+ h1 ^= h0; h0 = Rot64(h0,47); h1 += h0;
|
||||
+ h2 ^= h1; h1 = Rot64(h1,54); h2 += h1;
|
||||
+ h3 ^= h2; h2 = Rot64(h2,32); h3 += h2;
|
||||
+ h0 ^= h3; h3 = Rot64(h3,25); h0 += h3;
|
||||
+ h1 ^= h0; h0 = Rot64(h0,63); h1 += h0;
|
||||
+ }
|
||||
+
|
||||
+private:
|
||||
+
|
||||
+ //
|
||||
+ // Short is used for messages under 192 bytes in length
|
||||
+ // Short has a low startup cost, the normal mode is good for long
|
||||
+ // keys, the cost crossover is at about 192 bytes. The two modes were
|
||||
+ // held to the same quality bar.
|
||||
+ //
|
||||
+ static void Short(
|
||||
+ const void *message,
|
||||
+ size_t length,
|
||||
+ uint64 *hash1,
|
||||
+ uint64 *hash2);
|
||||
+
|
||||
+ // number of uint64's in internal state
|
||||
+ static const size_t sc_numVars = 12;
|
||||
+
|
||||
+ // size of the internal state
|
||||
+ static const size_t sc_blockSize = sc_numVars*8;
|
||||
+
|
||||
+ // size of buffer of unhashed data, in bytes
|
||||
+ static const size_t sc_bufSize = 2*sc_blockSize;
|
||||
+
|
||||
+ //
|
||||
+ // sc_const: a constant which:
|
||||
+ // * is not zero
|
||||
+ // * is odd
|
||||
+ // * is a not-very-regular mix of 1's and 0's
|
||||
+ // * does not need any other special mathematical properties
|
||||
+ //
|
||||
+ static const uint64 sc_const = 0xdeadbeefdeadbeefLL;
|
||||
+
|
||||
+ uint64 m_data[2*sc_numVars]; // unhashed data, for partial messages
|
||||
+ uint64 m_state[sc_numVars]; // internal state of the hash
|
||||
+ size_t m_length; // total length of the input so far
|
||||
+ uint8 m_remainder; // length of unhashed data stashed in m_data
|
||||
+};
|
||||
+
|
||||
+
|
||||
+
|
||||
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
|
||||
@@ -91,16 +91,17 @@ CPPSRCS += \
|
||||
intermOut.cpp \
|
||||
IntermTraverse.cpp \
|
||||
MapLongVariableNames.cpp \
|
||||
parseConst.cpp \
|
||||
ParseHelper.cpp \
|
||||
PoolAlloc.cpp \
|
||||
QualifierAlive.cpp \
|
||||
RemoveTree.cpp \
|
||||
+ spooky.cpp \
|
||||
SymbolTable.cpp \
|
||||
util.cpp \
|
||||
ValidateLimitations.cpp \
|
||||
VariableInfo.cpp \
|
||||
VariablePacker.cpp \
|
||||
$(NULL)
|
||||
|
||||
VPATH += $(srcdir)/../compiler/depgraph
|
|
@ -0,0 +1,24 @@
|
|||
From: Jeff Gilbert <jgilbert@mozilla.com>
|
||||
|
||||
diff --git a/gfx/angle/src/libGLESv2/renderer/Renderer9.cpp b/gfx/angle/src/libGLESv2/renderer/Renderer9.cpp
|
||||
--- a/gfx/angle/src/libGLESv2/renderer/Renderer9.cpp
|
||||
+++ b/gfx/angle/src/libGLESv2/renderer/Renderer9.cpp
|
||||
@@ -3128,17 +3128,17 @@ D3DPOOL Renderer9::getTexturePool(DWORD
|
||||
if (mD3d9Ex != NULL)
|
||||
{
|
||||
return D3DPOOL_DEFAULT;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(usage & (D3DUSAGE_DEPTHSTENCIL | D3DUSAGE_RENDERTARGET)))
|
||||
{
|
||||
- return D3DPOOL_MANAGED;
|
||||
+ return D3DPOOL_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
return D3DPOOL_DEFAULT;
|
||||
}
|
||||
|
||||
bool Renderer9::copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged)
|
||||
{
|
|
@ -110,6 +110,10 @@
|
|||
'LinkIncremental': '2',
|
||||
},
|
||||
},
|
||||
'xcode_settings': {
|
||||
'COPY_PHASE_STRIP': 'NO',
|
||||
'GCC_OPTIMIZATION_LEVEL': '0',
|
||||
},
|
||||
}, # Debug
|
||||
'Release': {
|
||||
'inherit_from': ['Common'],
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
# This file is used by gcl to get repository specific information.
|
||||
CODE_REVIEW_SERVER: codereview.appspot.com
|
||||
CC_LIST: angleproject-review@googlegroups.com
|
||||
VIEW_VC: http://code.google.com/p/angleproject/source/detail?r=
|
|
@ -0,0 +1,68 @@
|
|||
Name
|
||||
|
||||
ANGLE_direct3d_display
|
||||
|
||||
Name Strings
|
||||
|
||||
EGL_ANGLE_direct3d_display
|
||||
|
||||
Contributors
|
||||
|
||||
Nicolas Capens
|
||||
Shannon Woods
|
||||
|
||||
Contacts
|
||||
|
||||
Shannon Woods, Google Inc. (shannonwoods 'at' chromium.org)
|
||||
|
||||
Status
|
||||
|
||||
In progress
|
||||
|
||||
Version
|
||||
|
||||
Version 1, May 15, 2013
|
||||
|
||||
Number
|
||||
|
||||
EGL Extension #??
|
||||
|
||||
Dependencies
|
||||
|
||||
This extension is written against the wording of the EGL 1.4
|
||||
Specification.
|
||||
|
||||
Overview
|
||||
|
||||
This extension allows for specifying the behavior of the renderer backing the display.
|
||||
|
||||
New Types
|
||||
|
||||
None
|
||||
|
||||
New Procedures and Functions
|
||||
|
||||
None
|
||||
|
||||
New Tokens
|
||||
|
||||
EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE (EGLNativeDisplayType)-2
|
||||
EGL_D3D11_ONLY_DISPLAY_ANGLE (EGLNativeDisplayType)-3
|
||||
|
||||
Additions to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors)
|
||||
|
||||
Add before the last sentence of the first paragraph of section 3.2,
|
||||
"Initialization":
|
||||
|
||||
"If <display_id> is EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE, the display returned
|
||||
will be backed by a Direct3D 11 renderer if one is available, or by a
|
||||
Direct3D 9 renderer otherwise. If <display_id> is EGL_D3D11_ONLY_DISPLAY_ANGLE,
|
||||
the display returned will be backed by a Direct3D 11 renderer if one is
|
||||
available, or will return NULL otherwise."
|
||||
|
||||
Issues
|
||||
|
||||
Revision History
|
||||
|
||||
Version 1, 2013/05/15 - First draft.
|
||||
|
|
@ -306,6 +306,12 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay
|
|||
#define EGL_SOFTWARE_DISPLAY_ANGLE ((EGLNativeDisplayType)-1)
|
||||
#endif
|
||||
|
||||
#ifndef EGL_ANGLE_direct3d_display
|
||||
#define EGL_ANGLE_direct3d_display 1
|
||||
#define EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ((EGLNativeDisplayType)-2)
|
||||
#define EGL_D3D11_ONLY_DISPLAY_ANGLE ((EGLNativeDisplayType)-3)
|
||||
#endif
|
||||
|
||||
#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle
|
||||
#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1
|
||||
#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200
|
||||
|
|
|
@ -556,6 +556,44 @@ typedef void* GLeglImageOES;
|
|||
#define GL_COLOR_ATTACHMENT15_NV 0x8CEF
|
||||
#endif
|
||||
|
||||
/* GL_EXT_draw_buffers */
|
||||
#ifndef GL_EXT_draw_buffers
|
||||
#define GL_MAX_DRAW_BUFFERS_EXT 0x8824
|
||||
#define GL_DRAW_BUFFER0_EXT 0x8825
|
||||
#define GL_DRAW_BUFFER1_EXT 0x8826
|
||||
#define GL_DRAW_BUFFER2_EXT 0x8827
|
||||
#define GL_DRAW_BUFFER3_EXT 0x8828
|
||||
#define GL_DRAW_BUFFER4_EXT 0x8829
|
||||
#define GL_DRAW_BUFFER5_EXT 0x882A
|
||||
#define GL_DRAW_BUFFER6_EXT 0x882B
|
||||
#define GL_DRAW_BUFFER7_EXT 0x882C
|
||||
#define GL_DRAW_BUFFER8_EXT 0x882D
|
||||
#define GL_DRAW_BUFFER9_EXT 0x882E
|
||||
#define GL_DRAW_BUFFER10_EXT 0x882F
|
||||
#define GL_DRAW_BUFFER11_EXT 0x8830
|
||||
#define GL_DRAW_BUFFER12_EXT 0x8831
|
||||
#define GL_DRAW_BUFFER13_EXT 0x8832
|
||||
#define GL_DRAW_BUFFER14_EXT 0x8833
|
||||
#define GL_DRAW_BUFFER15_EXT 0x8834
|
||||
#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0
|
||||
#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1
|
||||
#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2
|
||||
#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3
|
||||
#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4
|
||||
#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5
|
||||
#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6
|
||||
#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7
|
||||
#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8
|
||||
#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9
|
||||
#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA
|
||||
#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB
|
||||
#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC
|
||||
#define GL_COLOR_ATTACHMENT13_EXT 0x8CED
|
||||
#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE
|
||||
#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF
|
||||
#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF
|
||||
#endif
|
||||
|
||||
/* GL_NV_fbo_color_attachments */
|
||||
#ifndef GL_NV_fbo_color_attachments
|
||||
#define GL_MAX_COLOR_ATTACHMENTS_NV 0x8CDF
|
||||
|
@ -1331,6 +1369,14 @@ GL_APICALL void GL_APIENTRY glDrawBuffersNV (GLsizei n, const GLenum *bufs);
|
|||
typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSNVPROC) (GLsizei n, const GLenum *bufs);
|
||||
#endif
|
||||
|
||||
#ifndef GL_EXT_draw_buffers
|
||||
#define GL_EXT_draw_buffers 1
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GL_APICALL void GL_APIENTRY glDrawBuffersEXT (GLsizei n, const GLenum *bufs);
|
||||
#endif
|
||||
typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSEXTPROC) (GLsizei n, const GLenum *bufs);
|
||||
#endif
|
||||
|
||||
/* GL_NV_fbo_color_attachments */
|
||||
#ifndef GL_NV_fbo_color_attachments
|
||||
#define GL_NV_fbo_color_attachments 1
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
|
||||
// Copyright (c) 2002-2013 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.
|
||||
//
|
||||
|
@ -78,9 +78,11 @@ typedef enum {
|
|||
} ShShaderSpec;
|
||||
|
||||
typedef enum {
|
||||
SH_ESSL_OUTPUT = 0x8B45,
|
||||
SH_GLSL_OUTPUT = 0x8B46,
|
||||
SH_HLSL_OUTPUT = 0x8B47
|
||||
SH_ESSL_OUTPUT = 0x8B45,
|
||||
SH_GLSL_OUTPUT = 0x8B46,
|
||||
SH_HLSL_OUTPUT = 0x8B47,
|
||||
SH_HLSL9_OUTPUT = 0x8B47,
|
||||
SH_HLSL11_OUTPUT = 0x8B48
|
||||
} ShShaderOutput;
|
||||
|
||||
typedef enum {
|
||||
|
@ -116,7 +118,8 @@ typedef enum {
|
|||
SH_MAPPED_NAME_MAX_LENGTH = 0x6000,
|
||||
SH_NAME_MAX_LENGTH = 0x6001,
|
||||
SH_HASHED_NAME_MAX_LENGTH = 0x6002,
|
||||
SH_HASHED_NAMES_COUNT = 0x6003
|
||||
SH_HASHED_NAMES_COUNT = 0x6003,
|
||||
SH_ACTIVE_UNIFORMS_ARRAY = 0x6004
|
||||
} ShShaderInfo;
|
||||
|
||||
// Compile options.
|
||||
|
@ -159,7 +162,13 @@ typedef enum {
|
|||
// vec234, or mat234 type. The ShArrayIndexClampingStrategy enum,
|
||||
// specified in the ShBuiltInResources when constructing the
|
||||
// compiler, selects the strategy for the clamping implementation.
|
||||
SH_CLAMP_INDIRECT_ARRAY_BOUNDS = 0x1000
|
||||
SH_CLAMP_INDIRECT_ARRAY_BOUNDS = 0x1000,
|
||||
|
||||
// This flag limits the complexity of an expression.
|
||||
SH_LIMIT_EXPRESSION_COMPLEXITY = 0x2000,
|
||||
|
||||
// This flag limits the depth of the call stack.
|
||||
SH_LIMIT_CALL_STACK_DEPTH = 0x4000,
|
||||
} ShCompileOptions;
|
||||
|
||||
// Defines alternate strategies for implementing array index clamping.
|
||||
|
@ -209,6 +218,7 @@ typedef struct
|
|||
int OES_EGL_image_external;
|
||||
int ARB_texture_rectangle;
|
||||
int EXT_draw_buffers;
|
||||
int EXT_frag_depth;
|
||||
|
||||
// Set to 1 if highp precision is supported in the fragment language.
|
||||
// Default is 0.
|
||||
|
@ -222,6 +232,12 @@ typedef struct
|
|||
// Selects a strategy to use when implementing array index clamping.
|
||||
// Default is SH_CLAMP_WITH_CLAMP_INTRINSIC.
|
||||
ShArrayIndexClampingStrategy ArrayIndexClampingStrategy;
|
||||
|
||||
// The maximum complexity an expression can be.
|
||||
int MaxExpressionComplexity;
|
||||
|
||||
// The maximum depth a call stack can be.
|
||||
int MaxCallStackDepth;
|
||||
} ShBuiltInResources;
|
||||
|
||||
//
|
||||
|
@ -248,7 +264,7 @@ typedef void* ShHandle;
|
|||
// spec: Specifies the language spec the compiler must conform to -
|
||||
// SH_GLES2_SPEC or SH_WEBGL_SPEC.
|
||||
// output: Specifies the output code type - SH_ESSL_OUTPUT, SH_GLSL_OUTPUT,
|
||||
// or SH_HLSL_OUTPUT.
|
||||
// SH_HLSL9_OUTPUT or SH_HLSL11_OUTPUT.
|
||||
// resources: Specifies the built-in resources.
|
||||
COMPILER_EXPORT ShHandle ShConstructCompiler(
|
||||
ShShaderType type,
|
||||
|
@ -411,6 +427,18 @@ COMPILER_EXPORT void ShGetNameHashingEntry(const ShHandle handle,
|
|||
char* name,
|
||||
char* hashedName);
|
||||
|
||||
// Returns a parameter from a compiled shader.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
// pname: Specifies the parameter to query.
|
||||
// The following parameters are defined:
|
||||
// SH_ACTIVE_UNIFORMS_ARRAY: an STL vector of active uniforms. Valid only for
|
||||
// HLSL output.
|
||||
// params: Requested parameter
|
||||
COMPILER_EXPORT void ShGetInfoPointer(const ShHandle handle,
|
||||
ShShaderInfo pname,
|
||||
void** params);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -34,12 +34,15 @@ CPP_SOURCES += [
|
|||
'Tokenizer.cpp',
|
||||
]
|
||||
|
||||
|
||||
# Target: 'translator_common'
|
||||
# Requires: 'preprocessor'
|
||||
# src/compiler:
|
||||
CPP_SOURCES += [
|
||||
'BuiltInFunctionEmulator.cpp',
|
||||
'Compiler.cpp',
|
||||
'compiler_debug.cpp',
|
||||
'DetectRecursion.cpp',
|
||||
'DetectCallDepth.cpp',
|
||||
'Diagnostics.cpp',
|
||||
'DirectiveHandler.cpp',
|
||||
'ForLoopUnroll.cpp',
|
||||
|
@ -58,8 +61,8 @@ CPP_SOURCES += [
|
|||
'PoolAlloc.cpp',
|
||||
'QualifierAlive.cpp',
|
||||
'RemoveTree.cpp',
|
||||
'spooky.cpp',
|
||||
'SymbolTable.cpp',
|
||||
'CompilerUniform.cpp',
|
||||
'util.cpp',
|
||||
'ValidateLimitations.cpp',
|
||||
'VariableInfo.cpp',
|
||||
|
@ -85,6 +88,11 @@ CPP_SOURCES += [
|
|||
'ArrayBoundsClamper.cpp',
|
||||
]
|
||||
|
||||
# src/third_party/murmurhash:
|
||||
CPP_SOURCES += [
|
||||
'MurmurHash3.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
CPP_SOURCES += [
|
||||
'ossource_win.cpp',
|
||||
|
@ -94,6 +102,7 @@ else:
|
|||
'ossource_posix.cpp',
|
||||
]
|
||||
|
||||
|
||||
# Target: 'translator_glsl'
|
||||
# Requires: 'translator_common'
|
||||
# src/compiler:
|
||||
|
@ -109,8 +118,5 @@ CPP_SOURCES += [
|
|||
]
|
||||
|
||||
LIBRARY_NAME = 'angle'
|
||||
|
||||
LIBXUL_LIBRARY = True
|
||||
|
||||
MSVC_ENABLE_PGO = True
|
||||
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual C++ Express 2010
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libEGL", "libEGL\libEGL.vcxproj", "{E746FCA9-64C3-433E-85E8-9A5A67AB7ED6}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libGLESv2", "libGLESv2\libGLESv2.vcxproj", "{B5871A7A-968C-42E3-A33B-981E6F448E78}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "translator_hlsl", "compiler\translator_hlsl.vcxproj", "{5620F0E4-6C43-49BC-A178-B804E1A0C3A7}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "translator_common", "compiler\translator_common.vcxproj", "{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "preprocessor", "compiler\preprocessor\preprocessor.vcxproj", "{FBE32DF3-0FB0-4F2F-A424-2C21BD7BC325}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{E746FCA9-64C3-433E-85E8-9A5A67AB7ED6}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{E746FCA9-64C3-433E-85E8-9A5A67AB7ED6}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{E746FCA9-64C3-433E-85E8-9A5A67AB7ED6}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{E746FCA9-64C3-433E-85E8-9A5A67AB7ED6}.Debug|x64.Build.0 = Debug|x64
|
||||
{E746FCA9-64C3-433E-85E8-9A5A67AB7ED6}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{E746FCA9-64C3-433E-85E8-9A5A67AB7ED6}.Release|Win32.Build.0 = Release|Win32
|
||||
{E746FCA9-64C3-433E-85E8-9A5A67AB7ED6}.Release|x64.ActiveCfg = Release|x64
|
||||
{E746FCA9-64C3-433E-85E8-9A5A67AB7ED6}.Release|x64.Build.0 = Release|x64
|
||||
{B5871A7A-968C-42E3-A33B-981E6F448E78}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{B5871A7A-968C-42E3-A33B-981E6F448E78}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{B5871A7A-968C-42E3-A33B-981E6F448E78}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B5871A7A-968C-42E3-A33B-981E6F448E78}.Debug|x64.Build.0 = Debug|x64
|
||||
{B5871A7A-968C-42E3-A33B-981E6F448E78}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{B5871A7A-968C-42E3-A33B-981E6F448E78}.Release|Win32.Build.0 = Release|Win32
|
||||
{B5871A7A-968C-42E3-A33B-981E6F448E78}.Release|x64.ActiveCfg = Release|x64
|
||||
{B5871A7A-968C-42E3-A33B-981E6F448E78}.Release|x64.Build.0 = Release|x64
|
||||
{5620F0E4-6C43-49BC-A178-B804E1A0C3A7}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{5620F0E4-6C43-49BC-A178-B804E1A0C3A7}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{5620F0E4-6C43-49BC-A178-B804E1A0C3A7}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{5620F0E4-6C43-49BC-A178-B804E1A0C3A7}.Debug|x64.Build.0 = Debug|x64
|
||||
{5620F0E4-6C43-49BC-A178-B804E1A0C3A7}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{5620F0E4-6C43-49BC-A178-B804E1A0C3A7}.Release|Win32.Build.0 = Release|Win32
|
||||
{5620F0E4-6C43-49BC-A178-B804E1A0C3A7}.Release|x64.ActiveCfg = Release|x64
|
||||
{5620F0E4-6C43-49BC-A178-B804E1A0C3A7}.Release|x64.Build.0 = Release|x64
|
||||
{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}.Debug|x64.Build.0 = Debug|x64
|
||||
{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}.Release|Win32.Build.0 = Release|Win32
|
||||
{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}.Release|x64.ActiveCfg = Release|x64
|
||||
{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}.Release|x64.Build.0 = Release|x64
|
||||
{FBE32DF3-0FB0-4F2F-A424-2C21BD7BC325}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{FBE32DF3-0FB0-4F2F-A424-2C21BD7BC325}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{FBE32DF3-0FB0-4F2F-A424-2C21BD7BC325}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{FBE32DF3-0FB0-4F2F-A424-2C21BD7BC325}.Debug|x64.Build.0 = Debug|x64
|
||||
{FBE32DF3-0FB0-4F2F-A424-2C21BD7BC325}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{FBE32DF3-0FB0-4F2F-A424-2C21BD7BC325}.Release|Win32.Build.0 = Release|Win32
|
||||
{FBE32DF3-0FB0-4F2F-A424-2C21BD7BC325}.Release|x64.ActiveCfg = Release|x64
|
||||
{FBE32DF3-0FB0-4F2F-A424-2C21BD7BC325}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -72,8 +72,8 @@
|
|||
'compiler/ConstantUnion.h',
|
||||
'compiler/debug.cpp',
|
||||
'compiler/debug.h',
|
||||
'compiler/DetectRecursion.cpp',
|
||||
'compiler/DetectRecursion.h',
|
||||
'compiler/DetectCallDepth.cpp',
|
||||
'compiler/DetectCallDepth.h',
|
||||
'compiler/Diagnostics.h',
|
||||
'compiler/Diagnostics.cpp',
|
||||
'compiler/DirectiveHandler.h',
|
||||
|
@ -118,6 +118,8 @@
|
|||
'compiler/SymbolTable.cpp',
|
||||
'compiler/SymbolTable.h',
|
||||
'compiler/Types.h',
|
||||
'compiler/Uniform.cpp',
|
||||
'compiler/Uniform.h',
|
||||
'compiler/util.cpp',
|
||||
'compiler/util.h',
|
||||
'compiler/ValidateLimitations.cpp',
|
||||
|
@ -221,28 +223,26 @@
|
|||
'include_dirs': [
|
||||
'.',
|
||||
'../include',
|
||||
'libGLESv2',
|
||||
],
|
||||
'sources': [
|
||||
'third_party/murmurhash/MurmurHash3.h',
|
||||
'third_party/murmurhash/MurmurHash3.cpp',
|
||||
'common/angleutils.h',
|
||||
'common/debug.cpp',
|
||||
'common/debug.h',
|
||||
'common/RefCountObject.cpp',
|
||||
'common/RefCountObject.h',
|
||||
'common/version.h',
|
||||
'libGLESv2/IndexDataManager.cpp',
|
||||
'libGLESv2/IndexDataManager.h',
|
||||
'libGLESv2/vertexconversion.h',
|
||||
'libGLESv2/VertexDataManager.cpp',
|
||||
'libGLESv2/VertexDataManager.h',
|
||||
'libGLESv2/precompiled.h',
|
||||
'libGLESv2/precompiled.cpp',
|
||||
'libGLESv2/BinaryStream.h',
|
||||
'libGLESv2/Blit.cpp',
|
||||
'libGLESv2/Blit.h',
|
||||
'libGLESv2/Buffer.cpp',
|
||||
'libGLESv2/Buffer.h',
|
||||
'libGLESv2/constants.h',
|
||||
'libGLESv2/Context.cpp',
|
||||
'libGLESv2/Context.h',
|
||||
'libGLESv2/D3DConstantTable.cpp',
|
||||
'libGLESv2/D3DConstantTable.h',
|
||||
'libGLESv2/angletypes.h',
|
||||
'libGLESv2/Fence.cpp',
|
||||
'libGLESv2/Fence.h',
|
||||
'libGLESv2/Float16ToFloat32.cpp',
|
||||
|
@ -264,13 +264,97 @@
|
|||
'libGLESv2/Query.cpp',
|
||||
'libGLESv2/Renderbuffer.cpp',
|
||||
'libGLESv2/Renderbuffer.h',
|
||||
'libGLESv2/renderer/Blit.cpp',
|
||||
'libGLESv2/renderer/Blit.h',
|
||||
'libGLESv2/renderer/BufferStorage.h',
|
||||
'libGLESv2/renderer/BufferStorage.cpp',
|
||||
'libGLESv2/renderer/BufferStorage9.cpp',
|
||||
'libGLESv2/renderer/BufferStorage9.h',
|
||||
'libGLESv2/renderer/BufferStorage11.cpp',
|
||||
'libGLESv2/renderer/BufferStorage11.h',
|
||||
'libGLESv2/renderer/FenceImpl.h',
|
||||
'libGLESv2/renderer/Fence9.cpp',
|
||||
'libGLESv2/renderer/Fence9.h',
|
||||
'libGLESv2/renderer/Fence11.cpp',
|
||||
'libGLESv2/renderer/Fence11.h',
|
||||
'libGLESv2/renderer/generatemip.h',
|
||||
'libGLESv2/renderer/Image.cpp',
|
||||
'libGLESv2/renderer/Image.h',
|
||||
'libGLESv2/renderer/Image11.cpp',
|
||||
'libGLESv2/renderer/Image11.h',
|
||||
'libGLESv2/renderer/Image9.cpp',
|
||||
'libGLESv2/renderer/Image9.h',
|
||||
'libGLESv2/renderer/ImageSSE2.cpp',
|
||||
'libGLESv2/renderer/IndexBuffer.cpp',
|
||||
'libGLESv2/renderer/IndexBuffer.h',
|
||||
'libGLESv2/renderer/IndexBuffer9.cpp',
|
||||
'libGLESv2/renderer/IndexBuffer9.h',
|
||||
'libGLESv2/renderer/IndexBuffer11.cpp',
|
||||
'libGLESv2/renderer/IndexBuffer11.h',
|
||||
'libGLESv2/renderer/IndexDataManager.cpp',
|
||||
'libGLESv2/renderer/IndexDataManager.h',
|
||||
'libGLESv2/renderer/IndexRangeCache.cpp',
|
||||
'libGLESv2/renderer/IndexRangeCache.h',
|
||||
'libGLESv2/renderer/InputLayoutCache.cpp',
|
||||
'libGLESv2/renderer/InputLayoutCache.h',
|
||||
'libGLESv2/renderer/QueryImpl.h',
|
||||
'libGLESv2/renderer/Query9.cpp',
|
||||
'libGLESv2/renderer/Query9.h',
|
||||
'libGLESv2/renderer/Query11.cpp',
|
||||
'libGLESv2/renderer/Query11.h',
|
||||
'libGLESv2/renderer/Renderer.cpp',
|
||||
'libGLESv2/renderer/Renderer.h',
|
||||
'libGLESv2/renderer/Renderer11.cpp',
|
||||
'libGLESv2/renderer/Renderer11.h',
|
||||
'libGLESv2/renderer/renderer11_utils.cpp',
|
||||
'libGLESv2/renderer/renderer11_utils.h',
|
||||
'libGLESv2/renderer/Renderer9.cpp',
|
||||
'libGLESv2/renderer/Renderer9.h',
|
||||
'libGLESv2/renderer/renderer9_utils.cpp',
|
||||
'libGLESv2/renderer/renderer9_utils.h',
|
||||
'libGLESv2/renderer/RenderStateCache.cpp',
|
||||
'libGLESv2/renderer/RenderStateCache.h',
|
||||
'libGLESv2/renderer/RenderTarget.h',
|
||||
'libGLESv2/renderer/RenderTarget11.h',
|
||||
'libGLESv2/renderer/RenderTarget11.cpp',
|
||||
'libGLESv2/renderer/RenderTarget9.h',
|
||||
'libGLESv2/renderer/RenderTarget9.cpp',
|
||||
'libGLESv2/renderer/ShaderCache.h',
|
||||
'libGLESv2/renderer/ShaderExecutable.h',
|
||||
'libGLESv2/renderer/ShaderExecutable9.cpp',
|
||||
'libGLESv2/renderer/ShaderExecutable9.h',
|
||||
'libGLESv2/renderer/ShaderExecutable11.cpp',
|
||||
'libGLESv2/renderer/ShaderExecutable11.h',
|
||||
'libGLESv2/renderer/SwapChain.h',
|
||||
'libGLESv2/renderer/SwapChain9.cpp',
|
||||
'libGLESv2/renderer/SwapChain9.h',
|
||||
'libGLESv2/renderer/SwapChain11.cpp',
|
||||
'libGLESv2/renderer/SwapChain11.h',
|
||||
'libGLESv2/renderer/TextureStorage.cpp',
|
||||
'libGLESv2/renderer/TextureStorage.h',
|
||||
'libGLESv2/renderer/TextureStorage11.cpp',
|
||||
'libGLESv2/renderer/TextureStorage11.h',
|
||||
'libGLESv2/renderer/TextureStorage9.cpp',
|
||||
'libGLESv2/renderer/TextureStorage9.h',
|
||||
'libGLESv2/renderer/VertexBuffer.cpp',
|
||||
'libGLESv2/renderer/VertexBuffer.h',
|
||||
'libGLESv2/renderer/VertexBuffer9.cpp',
|
||||
'libGLESv2/renderer/VertexBuffer9.h',
|
||||
'libGLESv2/renderer/VertexBuffer11.cpp',
|
||||
'libGLESv2/renderer/VertexBuffer11.h',
|
||||
'libGLESv2/renderer/vertexconversion.h',
|
||||
'libGLESv2/renderer/VertexDataManager.cpp',
|
||||
'libGLESv2/renderer/VertexDataManager.h',
|
||||
'libGLESv2/renderer/VertexDeclarationCache.cpp',
|
||||
'libGLESv2/renderer/VertexDeclarationCache.h',
|
||||
'libGLESv2/ResourceManager.cpp',
|
||||
'libGLESv2/ResourceManager.h',
|
||||
'libGLESv2/Shader.cpp',
|
||||
'libGLESv2/Shader.h',
|
||||
'libGLESv2/Texture.cpp',
|
||||
'libGLESv2/TextureSSE2.cpp',
|
||||
'libGLESv2/Texture.h',
|
||||
'libGLESv2/Uniform.cpp',
|
||||
'libGLESv2/Uniform.h',
|
||||
'libGLESv2/utilities.cpp',
|
||||
'libGLESv2/utilities.h',
|
||||
],
|
||||
|
@ -280,6 +364,7 @@
|
|||
'VCLinkerTool': {
|
||||
'AdditionalDependencies': [
|
||||
'd3d9.lib',
|
||||
'dxguid.lib',
|
||||
],
|
||||
}
|
||||
},
|
||||
|
@ -291,6 +376,7 @@
|
|||
'include_dirs': [
|
||||
'.',
|
||||
'../include',
|
||||
'libGLESv2',
|
||||
],
|
||||
'sources': [
|
||||
'common/angleutils.h',
|
||||
|
@ -317,7 +403,6 @@
|
|||
'VCLinkerTool': {
|
||||
'AdditionalDependencies': [
|
||||
'd3d9.lib',
|
||||
'dxguid.lib',
|
||||
],
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "precompiled.h"
|
||||
//
|
||||
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
|
|
|
@ -9,12 +9,39 @@
|
|||
#ifndef COMMON_ANGLEUTILS_H_
|
||||
#define COMMON_ANGLEUTILS_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
// A macro to disallow the copy constructor and operator= functions
|
||||
// This must be used in the private: declarations for a class
|
||||
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
|
||||
TypeName(const TypeName&); \
|
||||
void operator=(const TypeName&)
|
||||
|
||||
template <typename T, unsigned int N>
|
||||
inline unsigned int ArraySize(T(&)[N])
|
||||
{
|
||||
return N;
|
||||
}
|
||||
|
||||
template <typename T, unsigned int N>
|
||||
void SafeRelease(T (&resourceBlock)[N])
|
||||
{
|
||||
for (unsigned int i = 0; i < N; i++)
|
||||
{
|
||||
SafeRelease(resourceBlock[i]);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void SafeRelease(T& resource)
|
||||
{
|
||||
if (resource)
|
||||
{
|
||||
resource->Release();
|
||||
resource = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
@ -23,4 +50,7 @@
|
|||
#define VENDOR_ID_INTEL 0x8086
|
||||
#define VENDOR_ID_NVIDIA 0x10DE
|
||||
|
||||
#define GL_BGRA4_ANGLEX 0x6ABC
|
||||
#define GL_BGR5_A1_ANGLEX 0x6ABD
|
||||
|
||||
#endif // COMMON_ANGLEUTILS_H_
|
||||
|
|
|
@ -7,10 +7,6 @@
|
|||
// debug.cpp: Debugging utilities.
|
||||
|
||||
#include "common/debug.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "common/system.h"
|
||||
#include <d3d9.h>
|
||||
|
||||
|
|
|
@ -99,6 +99,13 @@ namespace gl
|
|||
#define UNREACHABLE() ERR("\t! Unreachable reached: %s(%d)\n", __FUNCTION__, __LINE__)
|
||||
#endif
|
||||
|
||||
// A macro that determines whether an object has a given runtime type.
|
||||
#if !defined(NDEBUG) && (!defined(_MSC_VER) || defined(_CPPRTTI))
|
||||
#define HAS_DYNAMIC_TYPE(type, obj) (dynamic_cast<type >(obj) != NULL)
|
||||
#else
|
||||
#define HAS_DYNAMIC_TYPE(type, obj) true
|
||||
#endif
|
||||
|
||||
// A macro functioning as a compile-time assert to validate constant conditions
|
||||
#define META_ASSERT(condition) typedef int COMPILE_TIME_ASSERT_##__LINE__[static_cast<bool>(condition)?1:-1]
|
||||
|
||||
|
|
|
@ -14,10 +14,6 @@
|
|||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#include <d3d9.h>
|
||||
#include <d3dcompiler.h>
|
||||
#include <d3d9types.h>
|
||||
#include <mmsystem.h>
|
||||
|
||||
#if defined(min)
|
||||
#undef min
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#define MAJOR_VERSION 1
|
||||
#define MINOR_VERSION 0
|
||||
#define MINOR_VERSION 2
|
||||
#define BUILD_VERSION 0
|
||||
#define BUILD_REVISION 2040
|
||||
#define BUILD_REVISION 2431
|
||||
|
||||
#define STRINGIFY(x) #x
|
||||
#define MACRO_STRINGIFY(x) STRINGIFY(x)
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
--- a/src/compiler/glslang_lex.cpp
|
||||
+++ b/src/compiler/glslang_lex.cpp
|
||||
@@ -68,6 +68,7 @@ typedef int16_t flex_int16_t;
|
||||
typedef uint16_t flex_uint16_t;
|
||||
typedef int32_t flex_int32_t;
|
||||
typedef uint32_t flex_uint32_t;
|
||||
+typedef uint64_t flex_uint64_t;
|
||||
#else
|
||||
typedef signed char flex_int8_t;
|
||||
typedef short int flex_int16_t;
|
||||
@@ -191,6 +192,11 @@ typedef void* yyscan_t;
|
||||
typedef struct yy_buffer_state *YY_BUFFER_STATE;
|
||||
#endif
|
||||
|
||||
+#ifndef YY_TYPEDEF_YY_SIZE_T
|
||||
+#define YY_TYPEDEF_YY_SIZE_T
|
||||
+typedef size_t yy_size_t;
|
||||
+#endif
|
||||
+
|
||||
#define EOB_ACT_CONTINUE_SCAN 0
|
||||
#define EOB_ACT_END_OF_FILE 1
|
||||
#define EOB_ACT_LAST_MATCH 2
|
||||
@@ -204,7 +210,7 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE;
|
||||
*/
|
||||
#define YY_LESS_LINENO(n) \
|
||||
do { \
|
||||
- int yyl;\
|
||||
+ yy_size_t yyl;\
|
||||
for ( yyl = n; yyl < yyleng; ++yyl )\
|
||||
if ( yytext[yyl] == '\n' )\
|
||||
--yylineno;\
|
||||
@@ -226,11 +232,6 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE;
|
||||
|
||||
#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
|
||||
|
||||
-#ifndef YY_TYPEDEF_YY_SIZE_T
|
||||
-#define YY_TYPEDEF_YY_SIZE_T
|
||||
-typedef size_t yy_size_t;
|
||||
-#endif
|
||||
-
|
||||
#ifndef YY_STRUCT_YY_BUFFER_STATE
|
||||
#define YY_STRUCT_YY_BUFFER_STATE
|
||||
struct yy_buffer_state
|
||||
@@ -248,7 +249,7 @@ struct yy_buffer_state
|
||||
/* Number of characters read into yy_ch_buf, not including EOB
|
||||
* characters.
|
||||
*/
|
||||
- int yy_n_chars;
|
||||
+ yy_size_t yy_n_chars;
|
||||
|
||||
/* Whether we "own" the buffer - i.e., we know we created it,
|
||||
* and can realloc() it to grow it, and should free() it to
|
||||
@@ -327,7 +328,7 @@ static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
|
||||
|
||||
YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
|
||||
YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
|
||||
-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
|
||||
+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner );
|
||||
|
||||
void *yyalloc (yy_size_t ,yyscan_t yyscanner );
|
||||
void *yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
|
||||
@@ -378,7 +379,7 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
|
||||
*/
|
||||
#define YY_DO_BEFORE_ACTION \
|
||||
yyg->yytext_ptr = yy_bp; \
|
||||
- yyleng = (size_t) (yy_cp - yy_bp); \
|
||||
+ yyleng = (yy_size_t) (yy_cp - yy_bp); \
|
||||
yyg->yy_hold_char = *yy_cp; \
|
||||
*yy_cp = '\0'; \
|
||||
yyg->yy_c_buf_p = yy_cp;
|
||||
@@ -1035,8 +1036,8 @@ struct yyguts_t
|
||||
size_t yy_buffer_stack_max; /**< capacity of stack. */
|
||||
YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
|
||||
char yy_hold_char;
|
||||
- int yy_n_chars;
|
||||
- int yyleng_r;
|
||||
+ yy_size_t yy_n_chars;
|
||||
+ yy_size_t yyleng_r;
|
||||
char *yy_c_buf_p;
|
||||
int yy_init;
|
||||
int yy_start;
|
||||
@@ -1089,7 +1090,7 @@ FILE *yyget_out (yyscan_t yyscanner );
|
||||
|
||||
void yyset_out (FILE * out_str ,yyscan_t yyscanner );
|
||||
|
||||
-int yyget_leng (yyscan_t yyscanner );
|
||||
+yy_size_t yyget_leng (yyscan_t yyscanner );
|
||||
|
||||
char *yyget_text (yyscan_t yyscanner );
|
||||
|
||||
@@ -1158,7 +1159,7 @@ static int input (yyscan_t yyscanner );
|
||||
if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
|
||||
{ \
|
||||
int c = '*'; \
|
||||
- int n; \
|
||||
+ yy_size_t n; \
|
||||
for ( n = 0; n < max_size && \
|
||||
(c = getc( yyin )) != EOF && c != '\n'; ++n ) \
|
||||
buf[n] = (char) c; \
|
||||
@@ -1317,7 +1318,7 @@ yy_find_action:
|
||||
|
||||
if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
|
||||
{
|
||||
- int yyl;
|
||||
+ yy_size_t yyl;
|
||||
for ( yyl = 0; yyl < yyleng; ++yyl )
|
||||
if ( yytext[yyl] == '\n' )
|
||||
|
||||
@@ -2203,7 +2204,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
|
||||
|
||||
else
|
||||
{
|
||||
- int num_to_read =
|
||||
+ yy_size_t num_to_read =
|
||||
YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
|
||||
|
||||
while ( num_to_read <= 0 )
|
||||
@@ -2217,7 +2218,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
|
||||
|
||||
if ( b->yy_is_our_buffer )
|
||||
{
|
||||
- int new_size = b->yy_buf_size * 2;
|
||||
+ yy_size_t new_size = b->yy_buf_size * 2;
|
||||
|
||||
if ( new_size <= 0 )
|
||||
b->yy_buf_size += b->yy_buf_size / 8;
|
||||
@@ -2248,7 +2249,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
|
||||
|
||||
/* Read in more data. */
|
||||
YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
|
||||
- yyg->yy_n_chars, (size_t) num_to_read );
|
||||
+ yyg->yy_n_chars, num_to_read );
|
||||
|
||||
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
|
||||
}
|
||||
@@ -2373,7 +2374,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
|
||||
|
||||
else
|
||||
{ /* need more input */
|
||||
- int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
|
||||
+ yy_size_t offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
|
||||
++yyg->yy_c_buf_p;
|
||||
|
||||
switch ( yy_get_next_buffer( yyscanner ) )
|
||||
@@ -2660,7 +2661,7 @@ void yypop_buffer_state (yyscan_t yyscanner)
|
||||
*/
|
||||
static void yyensure_buffer_stack (yyscan_t yyscanner)
|
||||
{
|
||||
- int num_to_alloc;
|
||||
+ yy_size_t num_to_alloc;
|
||||
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
|
||||
|
||||
if (!yyg->yy_buffer_stack) {
|
||||
@@ -2758,12 +2759,11 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
|
||||
* @param yyscanner The scanner object.
|
||||
* @return the newly allocated buffer state object.
|
||||
*/
|
||||
-YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner)
|
||||
+YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len , yyscan_t yyscanner)
|
||||
{
|
||||
YY_BUFFER_STATE b;
|
||||
char *buf;
|
||||
- yy_size_t n;
|
||||
- int i;
|
||||
+ yy_size_t n, i;
|
||||
|
||||
/* Get memory for full buffer, including space for trailing EOB's. */
|
||||
n = _yybytes_len + 2;
|
||||
@@ -2913,7 +2913,7 @@ FILE *yyget_out (yyscan_t yyscanner)
|
||||
/** Get the length of the current token.
|
||||
* @param yyscanner The scanner object.
|
||||
*/
|
||||
-int yyget_leng (yyscan_t yyscanner)
|
||||
+yy_size_t yyget_leng (yyscan_t yyscanner)
|
||||
{
|
||||
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
|
||||
return yyleng;
|
|
@ -90,10 +90,6 @@ enum TQualifier
|
|||
EvqInvariantVaryingOut, // vertex shaders only read/write
|
||||
EvqUniform, // Readonly, vertex and fragment
|
||||
|
||||
// pack/unpack input and output
|
||||
EvqInput,
|
||||
EvqOutput,
|
||||
|
||||
// parameters
|
||||
EvqIn,
|
||||
EvqOut,
|
||||
|
@ -112,6 +108,7 @@ enum TQualifier
|
|||
// built-ins written by fragment shader
|
||||
EvqFragColor,
|
||||
EvqFragData,
|
||||
EvqFragDepth,
|
||||
|
||||
// end of list
|
||||
EvqLast
|
||||
|
@ -137,14 +134,13 @@ inline const char* getQualifierString(TQualifier q)
|
|||
case EvqIn: return "in"; break;
|
||||
case EvqOut: return "out"; break;
|
||||
case EvqInOut: return "inout"; break;
|
||||
case EvqInput: return "input"; break;
|
||||
case EvqOutput: return "output"; break;
|
||||
case EvqPosition: return "Position"; break;
|
||||
case EvqPointSize: return "PointSize"; break;
|
||||
case EvqFragCoord: return "FragCoord"; break;
|
||||
case EvqFrontFacing: return "FrontFacing"; break;
|
||||
case EvqFragColor: return "FragColor"; break;
|
||||
case EvqFragData: return "FragData"; break;
|
||||
case EvqFragDepth: return "FragDepth"; break;
|
||||
default: return "unknown qualifier";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
|
||||
// Copyright (c) 2002-2013 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.
|
||||
//
|
||||
|
@ -14,9 +14,11 @@
|
|||
TCompiler* ConstructCompiler(
|
||||
ShShaderType type, ShShaderSpec spec, ShShaderOutput output)
|
||||
{
|
||||
switch (output) {
|
||||
case SH_HLSL_OUTPUT:
|
||||
return new TranslatorHLSL(type, spec);
|
||||
switch (output)
|
||||
{
|
||||
case SH_HLSL9_OUTPUT:
|
||||
case SH_HLSL11_OUTPUT:
|
||||
return new TranslatorHLSL(type, spec, output);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -14,36 +14,24 @@
|
|||
|
||||
#include "compiler/PoolAlloc.h"
|
||||
|
||||
// We need two pieces of information to report errors/warnings - string and
|
||||
// line number. We encode these into a single int so that it can be easily
|
||||
// incremented/decremented by lexer. The right SOURCE_LOC_LINE_SIZE bits store
|
||||
// line number while the rest store the string number. Since the shaders are
|
||||
// usually small, we should not run out of memory. SOURCE_LOC_LINE_SIZE
|
||||
// can be increased to alleviate this issue.
|
||||
typedef int TSourceLoc;
|
||||
const unsigned int SOURCE_LOC_LINE_SIZE = 16; // in bits.
|
||||
const unsigned int SOURCE_LOC_LINE_MASK = (1 << SOURCE_LOC_LINE_SIZE) - 1;
|
||||
|
||||
inline TSourceLoc EncodeSourceLoc(int string, int line) {
|
||||
return (string << SOURCE_LOC_LINE_SIZE) | (line & SOURCE_LOC_LINE_MASK);
|
||||
}
|
||||
|
||||
inline void DecodeSourceLoc(TSourceLoc loc, int* string, int* line) {
|
||||
if (string) *string = loc >> SOURCE_LOC_LINE_SIZE;
|
||||
if (line) *line = loc & SOURCE_LOC_LINE_MASK;
|
||||
}
|
||||
struct TSourceLoc {
|
||||
int first_file;
|
||||
int first_line;
|
||||
int last_file;
|
||||
int last_line;
|
||||
};
|
||||
|
||||
//
|
||||
// Put POOL_ALLOCATOR_NEW_DELETE in base classes to make them use this scheme.
|
||||
//
|
||||
#define POOL_ALLOCATOR_NEW_DELETE(A) \
|
||||
void* operator new(size_t s) { return (A).allocate(s); } \
|
||||
void* operator new(size_t, void *_Where) { return (_Where); } \
|
||||
void operator delete(void*) { } \
|
||||
void operator delete(void *, void *) { } \
|
||||
void* operator new[](size_t s) { return (A).allocate(s); } \
|
||||
void* operator new[](size_t, void *_Where) { return (_Where); } \
|
||||
void operator delete[](void*) { } \
|
||||
#define POOL_ALLOCATOR_NEW_DELETE() \
|
||||
void* operator new(size_t s) { return GetGlobalPoolAllocator()->allocate(s); } \
|
||||
void* operator new(size_t, void *_Where) { return (_Where); } \
|
||||
void operator delete(void*) { } \
|
||||
void operator delete(void *, void *) { } \
|
||||
void* operator new[](size_t s) { return GetGlobalPoolAllocator()->allocate(s); } \
|
||||
void* operator new[](size_t, void *_Where) { return (_Where); } \
|
||||
void operator delete[](void*) { } \
|
||||
void operator delete[](void *, void *) { }
|
||||
|
||||
//
|
||||
|
@ -54,7 +42,7 @@ typedef std::basic_string <char, std::char_traits<char>, TStringAllocator> TStri
|
|||
typedef std::basic_ostringstream<char, std::char_traits<char>, TStringAllocator> TStringStream;
|
||||
inline TString* NewPoolTString(const char* s)
|
||||
{
|
||||
void* memory = GlobalPoolAllocator.allocate(sizeof(TString));
|
||||
void* memory = GetGlobalPoolAllocator()->allocate(sizeof(TString));
|
||||
return new(memory) TString(s);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
//
|
||||
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
|
||||
// Copyright (c) 2002-2013 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/BuiltInFunctionEmulator.h"
|
||||
#include "compiler/DetectRecursion.h"
|
||||
#include "compiler/DetectCallDepth.h"
|
||||
#include "compiler/ForLoopUnroll.h"
|
||||
#include "compiler/Initialize.h"
|
||||
#include "compiler/InitializeParseContext.h"
|
||||
|
@ -27,51 +27,6 @@ bool isWebGLBasedSpec(ShShaderSpec spec)
|
|||
}
|
||||
|
||||
namespace {
|
||||
bool InitializeSymbolTable(
|
||||
const TBuiltInStrings& builtInStrings,
|
||||
ShShaderType type, ShShaderSpec spec, const ShBuiltInResources& resources,
|
||||
TInfoSink& infoSink, TSymbolTable& symbolTable)
|
||||
{
|
||||
TIntermediate intermediate(infoSink);
|
||||
TExtensionBehavior extBehavior;
|
||||
InitExtensionBehavior(resources, extBehavior);
|
||||
// The builtins deliberately don't specify precisions for the function
|
||||
// arguments and return types. For that reason we don't try to check them.
|
||||
TParseContext parseContext(symbolTable, extBehavior, intermediate, type, spec, 0, false, NULL, infoSink);
|
||||
parseContext.fragmentPrecisionHigh = resources.FragmentPrecisionHigh == 1;
|
||||
|
||||
GlobalParseContext = &parseContext;
|
||||
|
||||
assert(symbolTable.isEmpty());
|
||||
//
|
||||
// Parse the built-ins. This should only happen once per
|
||||
// language symbol table.
|
||||
//
|
||||
// Push the symbol table to give it an initial scope. This
|
||||
// push should not have a corresponding pop, so that built-ins
|
||||
// are preserved, and the test for an empty table fails.
|
||||
//
|
||||
symbolTable.push();
|
||||
|
||||
for (TBuiltInStrings::const_iterator i = builtInStrings.begin(); i != builtInStrings.end(); ++i)
|
||||
{
|
||||
const char* builtInShaders = i->c_str();
|
||||
int builtInLengths = static_cast<int>(i->size());
|
||||
if (builtInLengths <= 0)
|
||||
continue;
|
||||
|
||||
if (PaParseStrings(1, &builtInShaders, &builtInLengths, &parseContext) != 0)
|
||||
{
|
||||
infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
IdentifyBuiltIns(type, spec, resources, symbolTable);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
class TScopedPoolAllocator {
|
||||
public:
|
||||
TScopedPoolAllocator(TPoolAllocator* allocator, bool pushPop)
|
||||
|
@ -103,6 +58,9 @@ TShHandleBase::~TShHandleBase() {
|
|||
TCompiler::TCompiler(ShShaderType type, ShShaderSpec spec)
|
||||
: shaderType(type),
|
||||
shaderSpec(spec),
|
||||
maxUniformVectors(0),
|
||||
maxExpressionComplexity(0),
|
||||
maxCallStackDepth(0),
|
||||
fragmentPrecisionHigh(false),
|
||||
clampingStrategy(SH_CLAMP_WITH_CLAMP_INTRINSIC),
|
||||
builtInFunctionEmulator(type)
|
||||
|
@ -121,6 +79,8 @@ bool TCompiler::Init(const ShBuiltInResources& resources)
|
|||
maxUniformVectors = (shaderType == SH_VERTEX_SHADER) ?
|
||||
resources.MaxVertexUniformVectors :
|
||||
resources.MaxFragmentUniformVectors;
|
||||
maxExpressionComplexity = resources.MaxExpressionComplexity;
|
||||
maxCallStackDepth = resources.MaxCallStackDepth;
|
||||
TScopedPoolAllocator scopedAlloc(&allocator, false);
|
||||
|
||||
// Generate built-in symbol table.
|
||||
|
@ -168,13 +128,15 @@ bool TCompiler::compile(const char* const shaderStrings[],
|
|||
shaderType, shaderSpec, compileOptions, true,
|
||||
sourcePath, infoSink);
|
||||
parseContext.fragmentPrecisionHigh = fragmentPrecisionHigh;
|
||||
GlobalParseContext = &parseContext;
|
||||
SetGlobalParseContext(&parseContext);
|
||||
|
||||
// We preserve symbols at the built-in level from compile-to-compile.
|
||||
// Start pushing the user-defined symbols at global level.
|
||||
symbolTable.push();
|
||||
if (!symbolTable.atGlobalLevel())
|
||||
infoSink.info.message(EPrefixInternalError, "Wrong symbol table level");
|
||||
if (!symbolTable.atGlobalLevel()) {
|
||||
infoSink.info.prefix(EPrefixInternalError);
|
||||
infoSink.info << "Wrong symbol table level";
|
||||
}
|
||||
|
||||
// Parse shader.
|
||||
bool success =
|
||||
|
@ -185,7 +147,7 @@ bool TCompiler::compile(const char* const shaderStrings[],
|
|||
success = intermediate.postProcess(root);
|
||||
|
||||
if (success)
|
||||
success = detectRecursion(root);
|
||||
success = detectCallDepth(root, infoSink, (compileOptions & SH_LIMIT_CALL_STACK_DEPTH) != 0);
|
||||
|
||||
if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING))
|
||||
success = validateLimitations(root);
|
||||
|
@ -208,6 +170,10 @@ bool TCompiler::compile(const char* const shaderStrings[],
|
|||
if (success && (compileOptions & SH_CLAMP_INDIRECT_ARRAY_BOUNDS))
|
||||
arrayBoundsClamper.MarkIndirectArrayBoundsForClamping(root);
|
||||
|
||||
// Disallow expressions deemed too complex.
|
||||
if (success && (compileOptions & SH_LIMIT_EXPRESSION_COMPLEXITY))
|
||||
success = limitExpressionComplexity(root);
|
||||
|
||||
// Call mapLongVariableNames() before collectAttribsUniforms() so in
|
||||
// collectAttribsUniforms() we already have the mapped symbol names and
|
||||
// we could composite mapped and original variable names.
|
||||
|
@ -220,7 +186,8 @@ bool TCompiler::compile(const char* const shaderStrings[],
|
|||
if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS) {
|
||||
success = enforcePackingRestrictions();
|
||||
if (!success) {
|
||||
infoSink.info.message(EPrefixError, "too many uniforms");
|
||||
infoSink.info.prefix(EPrefixError);
|
||||
infoSink.info << "too many uniforms";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -242,13 +209,42 @@ bool TCompiler::compile(const char* const shaderStrings[],
|
|||
return success;
|
||||
}
|
||||
|
||||
bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources& resources)
|
||||
bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources)
|
||||
{
|
||||
TBuiltIns builtIns;
|
||||
compileResources = resources;
|
||||
|
||||
builtIns.initialize(shaderType, shaderSpec, resources);
|
||||
return InitializeSymbolTable(builtIns.getBuiltInStrings(),
|
||||
shaderType, shaderSpec, resources, infoSink, symbolTable);
|
||||
assert(symbolTable.isEmpty());
|
||||
symbolTable.push();
|
||||
|
||||
TPublicType integer;
|
||||
integer.type = EbtInt;
|
||||
integer.size = 1;
|
||||
integer.matrix = false;
|
||||
integer.array = false;
|
||||
|
||||
TPublicType floatingPoint;
|
||||
floatingPoint.type = EbtFloat;
|
||||
floatingPoint.size = 1;
|
||||
floatingPoint.matrix = false;
|
||||
floatingPoint.array = false;
|
||||
|
||||
switch(shaderType)
|
||||
{
|
||||
case SH_FRAGMENT_SHADER:
|
||||
symbolTable.setDefaultPrecision(integer, EbpMedium);
|
||||
break;
|
||||
case SH_VERTEX_SHADER:
|
||||
symbolTable.setDefaultPrecision(integer, EbpHigh);
|
||||
symbolTable.setDefaultPrecision(floatingPoint, EbpHigh);
|
||||
break;
|
||||
default: assert(false && "Language not supported");
|
||||
}
|
||||
|
||||
InsertBuiltInFunctions(shaderType, shaderSpec, resources, symbolTable);
|
||||
|
||||
IdentifyBuiltIns(shaderType, shaderSpec, resources, symbolTable);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TCompiler::clearResults()
|
||||
|
@ -266,18 +262,24 @@ void TCompiler::clearResults()
|
|||
nameMap.clear();
|
||||
}
|
||||
|
||||
bool TCompiler::detectRecursion(TIntermNode* root)
|
||||
bool TCompiler::detectCallDepth(TIntermNode* root, TInfoSink& infoSink, bool limitCallStackDepth)
|
||||
{
|
||||
DetectRecursion detect;
|
||||
DetectCallDepth detect(infoSink, limitCallStackDepth, maxCallStackDepth);
|
||||
root->traverse(&detect);
|
||||
switch (detect.detectRecursion()) {
|
||||
case DetectRecursion::kErrorNone:
|
||||
switch (detect.detectCallDepth()) {
|
||||
case DetectCallDepth::kErrorNone:
|
||||
return true;
|
||||
case DetectRecursion::kErrorMissingMain:
|
||||
infoSink.info.message(EPrefixError, "Missing main()");
|
||||
case DetectCallDepth::kErrorMissingMain:
|
||||
infoSink.info.prefix(EPrefixError);
|
||||
infoSink.info << "Missing main()";
|
||||
return false;
|
||||
case DetectRecursion::kErrorRecursion:
|
||||
infoSink.info.message(EPrefixError, "Function recursion detected");
|
||||
case DetectCallDepth::kErrorRecursion:
|
||||
infoSink.info.prefix(EPrefixError);
|
||||
infoSink.info << "Function recursion detected";
|
||||
return false;
|
||||
case DetectCallDepth::kErrorMaxDepthExceeded:
|
||||
infoSink.info.prefix(EPrefixError);
|
||||
infoSink.info << "Function call stack too deep";
|
||||
return false;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
|
@ -323,6 +325,28 @@ bool TCompiler::enforceTimingRestrictions(TIntermNode* root, bool outputGraph)
|
|||
}
|
||||
}
|
||||
|
||||
bool TCompiler::limitExpressionComplexity(TIntermNode* root)
|
||||
{
|
||||
TIntermTraverser traverser;
|
||||
root->traverse(&traverser);
|
||||
TDependencyGraph graph(root);
|
||||
|
||||
for (TFunctionCallVector::const_iterator iter = graph.beginUserDefinedFunctionCalls();
|
||||
iter != graph.endUserDefinedFunctionCalls();
|
||||
++iter)
|
||||
{
|
||||
TGraphFunctionCall* samplerSymbol = *iter;
|
||||
TDependencyGraphTraverser graphTraverser;
|
||||
samplerSymbol->traverse(&graphTraverser);
|
||||
}
|
||||
|
||||
if (traverser.getMaxDepth() > maxExpressionComplexity) {
|
||||
infoSink.info << "Expression too complex.";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TCompiler::enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph)
|
||||
{
|
||||
RestrictFragmentShaderTiming restrictor(infoSink.info);
|
||||
|
@ -366,6 +390,11 @@ const TExtensionBehavior& TCompiler::getExtensionBehavior() const
|
|||
return extensionBehavior;
|
||||
}
|
||||
|
||||
const ShBuiltInResources& TCompiler::getResources() const
|
||||
{
|
||||
return compileResources;
|
||||
}
|
||||
|
||||
const ArrayBoundsClamper& TCompiler::getArrayBoundsClamper() const
|
||||
{
|
||||
return arrayBoundsClamper;
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
//
|
||||
// Copyright (c) 2013 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 "CompilerUniform.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
Uniform::Uniform(GLenum type, GLenum precision, const char *name, int arraySize, int registerIndex)
|
||||
{
|
||||
this->type = type;
|
||||
this->precision = precision;
|
||||
this->name = name;
|
||||
this->arraySize = arraySize;
|
||||
this->registerIndex = registerIndex;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
//
|
||||
// Copyright (c) 2013 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.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_UNIFORM_H_
|
||||
#define COMPILER_UNIFORM_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#define GL_APICALL
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
struct Uniform
|
||||
{
|
||||
Uniform(GLenum type, GLenum precision, const char *name, int arraySize, int registerIndex);
|
||||
|
||||
GLenum type;
|
||||
GLenum precision;
|
||||
std::string name;
|
||||
unsigned int arraySize;
|
||||
|
||||
int registerIndex;
|
||||
};
|
||||
|
||||
typedef std::vector<Uniform> ActiveUniforms;
|
||||
|
||||
}
|
||||
|
||||
#endif // COMPILER_UNIFORM_H_
|
|
@ -11,13 +11,13 @@
|
|||
|
||||
class ConstantUnion {
|
||||
public:
|
||||
POOL_ALLOCATOR_NEW_DELETE();
|
||||
ConstantUnion()
|
||||
{
|
||||
iConst = 0;
|
||||
type = EbtVoid;
|
||||
}
|
||||
|
||||
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
|
||||
void setIConst(int i) {iConst = i; type = EbtInt; }
|
||||
void setFConst(float f) {fConst = f; type = EbtFloat; }
|
||||
void setBConst(bool b) {bConst = b; type = EbtBool; }
|
||||
|
|
|
@ -0,0 +1,185 @@
|
|||
//
|
||||
// Copyright (c) 2002-2011 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/DetectCallDepth.h"
|
||||
#include "compiler/InfoSink.h"
|
||||
|
||||
DetectCallDepth::FunctionNode::FunctionNode(const TString& fname)
|
||||
: name(fname),
|
||||
visit(PreVisit)
|
||||
{
|
||||
}
|
||||
|
||||
const TString& DetectCallDepth::FunctionNode::getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
void DetectCallDepth::FunctionNode::addCallee(
|
||||
DetectCallDepth::FunctionNode* callee)
|
||||
{
|
||||
for (size_t i = 0; i < callees.size(); ++i) {
|
||||
if (callees[i] == callee)
|
||||
return;
|
||||
}
|
||||
callees.push_back(callee);
|
||||
}
|
||||
|
||||
int DetectCallDepth::FunctionNode::detectCallDepth(DetectCallDepth* detectCallDepth, int depth)
|
||||
{
|
||||
ASSERT(visit == PreVisit);
|
||||
ASSERT(detectCallDepth);
|
||||
|
||||
int maxDepth = depth;
|
||||
visit = InVisit;
|
||||
for (size_t i = 0; i < callees.size(); ++i) {
|
||||
switch (callees[i]->visit) {
|
||||
case InVisit:
|
||||
// cycle detected, i.e., recursion detected.
|
||||
return kInfiniteCallDepth;
|
||||
case PostVisit:
|
||||
break;
|
||||
case PreVisit: {
|
||||
// Check before we recurse so we don't go too depth
|
||||
if (detectCallDepth->checkExceedsMaxDepth(depth))
|
||||
return depth;
|
||||
int callDepth = callees[i]->detectCallDepth(detectCallDepth, depth + 1);
|
||||
// Check after we recurse so we can exit immediately and provide info.
|
||||
if (detectCallDepth->checkExceedsMaxDepth(callDepth)) {
|
||||
detectCallDepth->getInfoSink().info << "<-" << callees[i]->getName();
|
||||
return callDepth;
|
||||
}
|
||||
maxDepth = std::max(callDepth, maxDepth);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
visit = PostVisit;
|
||||
return maxDepth;
|
||||
}
|
||||
|
||||
void DetectCallDepth::FunctionNode::reset()
|
||||
{
|
||||
visit = PreVisit;
|
||||
}
|
||||
|
||||
DetectCallDepth::DetectCallDepth(TInfoSink& infoSink, bool limitCallStackDepth, int maxCallStackDepth)
|
||||
: TIntermTraverser(true, false, true, false),
|
||||
currentFunction(NULL),
|
||||
infoSink(infoSink),
|
||||
maxDepth(limitCallStackDepth ? maxCallStackDepth : FunctionNode::kInfiniteCallDepth)
|
||||
{
|
||||
}
|
||||
|
||||
DetectCallDepth::~DetectCallDepth()
|
||||
{
|
||||
for (size_t i = 0; i < functions.size(); ++i)
|
||||
delete functions[i];
|
||||
}
|
||||
|
||||
bool DetectCallDepth::visitAggregate(Visit visit, TIntermAggregate* node)
|
||||
{
|
||||
switch (node->getOp())
|
||||
{
|
||||
case EOpPrototype:
|
||||
// Function declaration.
|
||||
// Don't add FunctionNode here because node->getName() is the
|
||||
// unmangled function name.
|
||||
break;
|
||||
case EOpFunction: {
|
||||
// Function definition.
|
||||
if (visit == PreVisit) {
|
||||
currentFunction = findFunctionByName(node->getName());
|
||||
if (currentFunction == NULL) {
|
||||
currentFunction = new FunctionNode(node->getName());
|
||||
functions.push_back(currentFunction);
|
||||
}
|
||||
} else if (visit == PostVisit) {
|
||||
currentFunction = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EOpFunctionCall: {
|
||||
// Function call.
|
||||
if (visit == PreVisit) {
|
||||
FunctionNode* func = findFunctionByName(node->getName());
|
||||
if (func == NULL) {
|
||||
func = new FunctionNode(node->getName());
|
||||
functions.push_back(func);
|
||||
}
|
||||
if (currentFunction)
|
||||
currentFunction->addCallee(func);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DetectCallDepth::checkExceedsMaxDepth(int depth)
|
||||
{
|
||||
return depth >= maxDepth;
|
||||
}
|
||||
|
||||
void DetectCallDepth::resetFunctionNodes()
|
||||
{
|
||||
for (size_t i = 0; i < functions.size(); ++i) {
|
||||
functions[i]->reset();
|
||||
}
|
||||
}
|
||||
|
||||
DetectCallDepth::ErrorCode DetectCallDepth::detectCallDepthForFunction(FunctionNode* func)
|
||||
{
|
||||
currentFunction = NULL;
|
||||
resetFunctionNodes();
|
||||
|
||||
int maxCallDepth = func->detectCallDepth(this, 1);
|
||||
|
||||
if (maxCallDepth == FunctionNode::kInfiniteCallDepth)
|
||||
return kErrorRecursion;
|
||||
|
||||
if (maxCallDepth >= maxDepth)
|
||||
return kErrorMaxDepthExceeded;
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DetectCallDepth::ErrorCode DetectCallDepth::detectCallDepth()
|
||||
{
|
||||
if (maxDepth != FunctionNode::kInfiniteCallDepth) {
|
||||
// Check all functions because the driver may fail on them
|
||||
// TODO: Before detectingRecursion, strip unused functions.
|
||||
for (size_t i = 0; i < functions.size(); ++i) {
|
||||
ErrorCode error = detectCallDepthForFunction(functions[i]);
|
||||
if (error != kErrorNone)
|
||||
return error;
|
||||
}
|
||||
} else {
|
||||
FunctionNode* main = findFunctionByName("main(");
|
||||
if (main == NULL)
|
||||
return kErrorMissingMain;
|
||||
|
||||
return detectCallDepthForFunction(main);
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DetectCallDepth::FunctionNode* DetectCallDepth::findFunctionByName(
|
||||
const TString& name)
|
||||
{
|
||||
for (size_t i = 0; i < functions.size(); ++i) {
|
||||
if (functions[i]->getName() == name)
|
||||
return functions[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -9,28 +9,36 @@
|
|||
|
||||
#include "GLSLANG/ShaderLang.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include "compiler/intermediate.h"
|
||||
#include "compiler/VariableInfo.h"
|
||||
|
||||
class TInfoSink;
|
||||
|
||||
// Traverses intermediate tree to detect function recursion.
|
||||
class DetectRecursion : public TIntermTraverser {
|
||||
class DetectCallDepth : public TIntermTraverser {
|
||||
public:
|
||||
enum ErrorCode {
|
||||
kErrorMissingMain,
|
||||
kErrorRecursion,
|
||||
kErrorMaxDepthExceeded,
|
||||
kErrorNone
|
||||
};
|
||||
|
||||
DetectRecursion();
|
||||
~DetectRecursion();
|
||||
DetectCallDepth(TInfoSink& infoSync, bool limitCallStackDepth, int maxCallStackDepth);
|
||||
~DetectCallDepth();
|
||||
|
||||
virtual bool visitAggregate(Visit, TIntermAggregate*);
|
||||
|
||||
ErrorCode detectRecursion();
|
||||
bool checkExceedsMaxDepth(int depth);
|
||||
|
||||
ErrorCode detectCallDepth();
|
||||
|
||||
private:
|
||||
class FunctionNode {
|
||||
public:
|
||||
static const int kInfiniteCallDepth = INT_MAX;
|
||||
|
||||
FunctionNode(const TString& fname);
|
||||
|
||||
const TString& getName() const;
|
||||
|
@ -38,8 +46,11 @@ private:
|
|||
// If a function is already in the callee list, this becomes a no-op.
|
||||
void addCallee(FunctionNode* callee);
|
||||
|
||||
// Return true if recursive function calls are detected.
|
||||
bool detectRecursion();
|
||||
// Returns kInifinityCallDepth if recursive function calls are detected.
|
||||
int detectCallDepth(DetectCallDepth* detectCallDepth, int depth);
|
||||
|
||||
// Reset state.
|
||||
void reset();
|
||||
|
||||
private:
|
||||
// mangled function name is unique.
|
||||
|
@ -51,10 +62,19 @@ private:
|
|||
Visit visit;
|
||||
};
|
||||
|
||||
ErrorCode detectCallDepthForFunction(FunctionNode* func);
|
||||
FunctionNode* findFunctionByName(const TString& name);
|
||||
void resetFunctionNodes();
|
||||
|
||||
TInfoSink& getInfoSink() { return infoSink; }
|
||||
|
||||
TVector<FunctionNode*> functions;
|
||||
FunctionNode* currentFunction;
|
||||
TInfoSink& infoSink;
|
||||
int maxDepth;
|
||||
|
||||
DetectCallDepth(const DetectCallDepth&);
|
||||
void operator=(const DetectCallDepth&);
|
||||
};
|
||||
|
||||
#endif // COMPILER_DETECT_RECURSION_H_
|
|
@ -1,125 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2002-2011 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/DetectRecursion.h"
|
||||
|
||||
DetectRecursion::FunctionNode::FunctionNode(const TString& fname)
|
||||
: name(fname),
|
||||
visit(PreVisit)
|
||||
{
|
||||
}
|
||||
|
||||
const TString& DetectRecursion::FunctionNode::getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
void DetectRecursion::FunctionNode::addCallee(
|
||||
DetectRecursion::FunctionNode* callee)
|
||||
{
|
||||
for (size_t i = 0; i < callees.size(); ++i) {
|
||||
if (callees[i] == callee)
|
||||
return;
|
||||
}
|
||||
callees.push_back(callee);
|
||||
}
|
||||
|
||||
bool DetectRecursion::FunctionNode::detectRecursion()
|
||||
{
|
||||
ASSERT(visit == PreVisit);
|
||||
visit = InVisit;
|
||||
for (size_t i = 0; i < callees.size(); ++i) {
|
||||
switch (callees[i]->visit) {
|
||||
case InVisit:
|
||||
// cycle detected, i.e., recursion detected.
|
||||
return true;
|
||||
case PostVisit:
|
||||
break;
|
||||
case PreVisit: {
|
||||
bool recursion = callees[i]->detectRecursion();
|
||||
if (recursion)
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
visit = PostVisit;
|
||||
return false;
|
||||
}
|
||||
|
||||
DetectRecursion::DetectRecursion()
|
||||
: currentFunction(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
DetectRecursion::~DetectRecursion()
|
||||
{
|
||||
for (size_t i = 0; i < functions.size(); ++i)
|
||||
delete functions[i];
|
||||
}
|
||||
|
||||
bool DetectRecursion::visitAggregate(Visit visit, TIntermAggregate* node)
|
||||
{
|
||||
switch (node->getOp())
|
||||
{
|
||||
case EOpPrototype:
|
||||
// Function declaration.
|
||||
// Don't add FunctionNode here because node->getName() is the
|
||||
// unmangled function name.
|
||||
break;
|
||||
case EOpFunction: {
|
||||
// Function definition.
|
||||
if (visit == PreVisit) {
|
||||
currentFunction = findFunctionByName(node->getName());
|
||||
if (currentFunction == NULL) {
|
||||
currentFunction = new FunctionNode(node->getName());
|
||||
functions.push_back(currentFunction);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EOpFunctionCall: {
|
||||
// Function call.
|
||||
if (visit == PreVisit) {
|
||||
ASSERT(currentFunction != NULL);
|
||||
FunctionNode* func = findFunctionByName(node->getName());
|
||||
if (func == NULL) {
|
||||
func = new FunctionNode(node->getName());
|
||||
functions.push_back(func);
|
||||
}
|
||||
currentFunction->addCallee(func);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
DetectRecursion::ErrorCode DetectRecursion::detectRecursion()
|
||||
{
|
||||
FunctionNode* main = findFunctionByName("main(");
|
||||
if (main == NULL)
|
||||
return kErrorMissingMain;
|
||||
if (main->detectRecursion())
|
||||
return kErrorRecursion;
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DetectRecursion::FunctionNode* DetectRecursion::findFunctionByName(
|
||||
const TString& name)
|
||||
{
|
||||
for (size_t i = 0; i < functions.size(); ++i) {
|
||||
if (functions[i]->getName() == name)
|
||||
return functions[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -46,7 +46,7 @@ void TDiagnostics::writeInfo(Severity severity,
|
|||
TInfoSinkBase& sink = mInfoSink.info;
|
||||
/* VC++ format: file(linenum) : error #: 'token' : extrainfo */
|
||||
sink.prefix(prefix);
|
||||
sink.location(EncodeSourceLoc(loc.file, loc.line));
|
||||
sink.location(loc.file, loc.line);
|
||||
sink << "'" << token << "' : " << reason << " " << extra << "\n";
|
||||
}
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
#include "compiler/InfoSink.h"
|
||||
|
||||
void TInfoSinkBase::prefix(TPrefixType message) {
|
||||
switch(message) {
|
||||
void TInfoSinkBase::prefix(TPrefixType p) {
|
||||
switch(p) {
|
||||
case EPrefixNone:
|
||||
break;
|
||||
case EPrefixWarning:
|
||||
|
@ -31,29 +31,24 @@ void TInfoSinkBase::prefix(TPrefixType message) {
|
|||
}
|
||||
}
|
||||
|
||||
void TInfoSinkBase::location(TSourceLoc loc) {
|
||||
int string = 0, line = 0;
|
||||
DecodeSourceLoc(loc, &string, &line);
|
||||
|
||||
void TInfoSinkBase::location(int file, int line) {
|
||||
TPersistStringStream stream;
|
||||
if (line)
|
||||
stream << string << ":" << line;
|
||||
stream << file << ":" << line;
|
||||
else
|
||||
stream << string << ":? ";
|
||||
stream << file << ":? ";
|
||||
stream << ": ";
|
||||
|
||||
sink.append(stream.str());
|
||||
}
|
||||
|
||||
void TInfoSinkBase::message(TPrefixType message, const char* s) {
|
||||
prefix(message);
|
||||
sink.append(s);
|
||||
sink.append("\n");
|
||||
void TInfoSinkBase::location(const TSourceLoc& loc) {
|
||||
location(loc.first_file, loc.first_line);
|
||||
}
|
||||
|
||||
void TInfoSinkBase::message(TPrefixType message, const char* s, TSourceLoc loc) {
|
||||
prefix(message);
|
||||
void TInfoSinkBase::message(TPrefixType p, const TSourceLoc& loc, const char* m) {
|
||||
prefix(p);
|
||||
location(loc);
|
||||
sink.append(s);
|
||||
sink.append(m);
|
||||
sink.append("\n");
|
||||
}
|
||||
|
|
|
@ -96,10 +96,10 @@ public:
|
|||
const TPersistString& str() const { return sink; }
|
||||
const char* c_str() const { return sink.c_str(); }
|
||||
|
||||
void prefix(TPrefixType message);
|
||||
void location(TSourceLoc loc);
|
||||
void message(TPrefixType message, const char* s);
|
||||
void message(TPrefixType message, const char* s, TSourceLoc loc);
|
||||
void prefix(TPrefixType p);
|
||||
void location(int file, int line);
|
||||
void location(const TSourceLoc& loc);
|
||||
void message(TPrefixType p, const TSourceLoc& loc, const char* m);
|
||||
|
||||
private:
|
||||
TPersistString sink;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
|
||||
// Copyright (c) 2002-2013 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.
|
||||
//
|
||||
|
@ -14,513 +14,413 @@
|
|||
|
||||
#include "compiler/intermediate.h"
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Prototypes for built-in functions seen by both vertex and fragment shaders.
|
||||
//
|
||||
//============================================================================
|
||||
static TString BuiltInFunctionsCommon(const ShBuiltInResources& resources)
|
||||
void InsertBuiltInFunctions(ShShaderType type, ShShaderSpec spec, const ShBuiltInResources &resources, TSymbolTable &symbolTable)
|
||||
{
|
||||
TString s;
|
||||
TType *float1 = new TType(EbtFloat, EbpUndefined, EvqGlobal, 1);
|
||||
TType *float2 = new TType(EbtFloat, EbpUndefined, EvqGlobal, 2);
|
||||
TType *float3 = new TType(EbtFloat, EbpUndefined, EvqGlobal, 3);
|
||||
TType *float4 = new TType(EbtFloat, EbpUndefined, EvqGlobal, 4);
|
||||
|
||||
TType *int2 = new TType(EbtInt, EbpUndefined, EvqGlobal, 2);
|
||||
TType *int3 = new TType(EbtInt, EbpUndefined, EvqGlobal, 3);
|
||||
TType *int4 = new TType(EbtInt, EbpUndefined, EvqGlobal, 4);
|
||||
|
||||
//
|
||||
// Angle and Trigonometric Functions.
|
||||
//
|
||||
s.append(TString("float radians(float degrees);"));
|
||||
s.append(TString("vec2 radians(vec2 degrees);"));
|
||||
s.append(TString("vec3 radians(vec3 degrees);"));
|
||||
s.append(TString("vec4 radians(vec4 degrees);"));
|
||||
symbolTable.insertBuiltIn(float1, "radians", float1);
|
||||
symbolTable.insertBuiltIn(float2, "radians", float2);
|
||||
symbolTable.insertBuiltIn(float3, "radians", float3);
|
||||
symbolTable.insertBuiltIn(float4, "radians", float4);
|
||||
|
||||
s.append(TString("float degrees(float radians);"));
|
||||
s.append(TString("vec2 degrees(vec2 radians);"));
|
||||
s.append(TString("vec3 degrees(vec3 radians);"));
|
||||
s.append(TString("vec4 degrees(vec4 radians);"));
|
||||
symbolTable.insertBuiltIn(float1, "degrees", float1);
|
||||
symbolTable.insertBuiltIn(float2, "degrees", float2);
|
||||
symbolTable.insertBuiltIn(float3, "degrees", float3);
|
||||
symbolTable.insertBuiltIn(float4, "degrees", float4);
|
||||
|
||||
s.append(TString("float sin(float angle);"));
|
||||
s.append(TString("vec2 sin(vec2 angle);"));
|
||||
s.append(TString("vec3 sin(vec3 angle);"));
|
||||
s.append(TString("vec4 sin(vec4 angle);"));
|
||||
symbolTable.insertBuiltIn(float1, "sin", float1);
|
||||
symbolTable.insertBuiltIn(float2, "sin", float2);
|
||||
symbolTable.insertBuiltIn(float3, "sin", float3);
|
||||
symbolTable.insertBuiltIn(float4, "sin", float4);
|
||||
|
||||
s.append(TString("float cos(float angle);"));
|
||||
s.append(TString("vec2 cos(vec2 angle);"));
|
||||
s.append(TString("vec3 cos(vec3 angle);"));
|
||||
s.append(TString("vec4 cos(vec4 angle);"));
|
||||
symbolTable.insertBuiltIn(float1, "cos", float1);
|
||||
symbolTable.insertBuiltIn(float2, "cos", float2);
|
||||
symbolTable.insertBuiltIn(float3, "cos", float3);
|
||||
symbolTable.insertBuiltIn(float4, "cos", float4);
|
||||
|
||||
s.append(TString("float tan(float angle);"));
|
||||
s.append(TString("vec2 tan(vec2 angle);"));
|
||||
s.append(TString("vec3 tan(vec3 angle);"));
|
||||
s.append(TString("vec4 tan(vec4 angle);"));
|
||||
symbolTable.insertBuiltIn(float1, "tan", float1);
|
||||
symbolTable.insertBuiltIn(float2, "tan", float2);
|
||||
symbolTable.insertBuiltIn(float3, "tan", float3);
|
||||
symbolTable.insertBuiltIn(float4, "tan", float4);
|
||||
|
||||
s.append(TString("float asin(float x);"));
|
||||
s.append(TString("vec2 asin(vec2 x);"));
|
||||
s.append(TString("vec3 asin(vec3 x);"));
|
||||
s.append(TString("vec4 asin(vec4 x);"));
|
||||
symbolTable.insertBuiltIn(float1, "asin", float1);
|
||||
symbolTable.insertBuiltIn(float2, "asin", float2);
|
||||
symbolTable.insertBuiltIn(float3, "asin", float3);
|
||||
symbolTable.insertBuiltIn(float4, "asin", float4);
|
||||
|
||||
s.append(TString("float acos(float x);"));
|
||||
s.append(TString("vec2 acos(vec2 x);"));
|
||||
s.append(TString("vec3 acos(vec3 x);"));
|
||||
s.append(TString("vec4 acos(vec4 x);"));
|
||||
symbolTable.insertBuiltIn(float1, "acos", float1);
|
||||
symbolTable.insertBuiltIn(float2, "acos", float2);
|
||||
symbolTable.insertBuiltIn(float3, "acos", float3);
|
||||
symbolTable.insertBuiltIn(float4, "acos", float4);
|
||||
|
||||
s.append(TString("float atan(float y, float x);"));
|
||||
s.append(TString("vec2 atan(vec2 y, vec2 x);"));
|
||||
s.append(TString("vec3 atan(vec3 y, vec3 x);"));
|
||||
s.append(TString("vec4 atan(vec4 y, vec4 x);"));
|
||||
symbolTable.insertBuiltIn(float1, "atan", float1, float1);
|
||||
symbolTable.insertBuiltIn(float2, "atan", float2, float2);
|
||||
symbolTable.insertBuiltIn(float3, "atan", float3, float3);
|
||||
symbolTable.insertBuiltIn(float4, "atan", float4, float4);
|
||||
|
||||
s.append(TString("float atan(float y_over_x);"));
|
||||
s.append(TString("vec2 atan(vec2 y_over_x);"));
|
||||
s.append(TString("vec3 atan(vec3 y_over_x);"));
|
||||
s.append(TString("vec4 atan(vec4 y_over_x);"));
|
||||
symbolTable.insertBuiltIn(float1, "atan", float1);
|
||||
symbolTable.insertBuiltIn(float2, "atan", float2);
|
||||
symbolTable.insertBuiltIn(float3, "atan", float3);
|
||||
symbolTable.insertBuiltIn(float4, "atan", float4);
|
||||
|
||||
//
|
||||
// Exponential Functions.
|
||||
//
|
||||
s.append(TString("float pow(float x, float y);"));
|
||||
s.append(TString("vec2 pow(vec2 x, vec2 y);"));
|
||||
s.append(TString("vec3 pow(vec3 x, vec3 y);"));
|
||||
s.append(TString("vec4 pow(vec4 x, vec4 y);"));
|
||||
symbolTable.insertBuiltIn(float1, "pow", float1, float1);
|
||||
symbolTable.insertBuiltIn(float2, "pow", float2, float2);
|
||||
symbolTable.insertBuiltIn(float3, "pow", float3, float3);
|
||||
symbolTable.insertBuiltIn(float4, "pow", float4, float4);
|
||||
|
||||
s.append(TString("float exp(float x);"));
|
||||
s.append(TString("vec2 exp(vec2 x);"));
|
||||
s.append(TString("vec3 exp(vec3 x);"));
|
||||
s.append(TString("vec4 exp(vec4 x);"));
|
||||
symbolTable.insertBuiltIn(float1, "exp", float1);
|
||||
symbolTable.insertBuiltIn(float2, "exp", float2);
|
||||
symbolTable.insertBuiltIn(float3, "exp", float3);
|
||||
symbolTable.insertBuiltIn(float4, "exp", float4);
|
||||
|
||||
s.append(TString("float log(float x);"));
|
||||
s.append(TString("vec2 log(vec2 x);"));
|
||||
s.append(TString("vec3 log(vec3 x);"));
|
||||
s.append(TString("vec4 log(vec4 x);"));
|
||||
symbolTable.insertBuiltIn(float1, "log", float1);
|
||||
symbolTable.insertBuiltIn(float2, "log", float2);
|
||||
symbolTable.insertBuiltIn(float3, "log", float3);
|
||||
symbolTable.insertBuiltIn(float4, "log", float4);
|
||||
|
||||
s.append(TString("float exp2(float x);"));
|
||||
s.append(TString("vec2 exp2(vec2 x);"));
|
||||
s.append(TString("vec3 exp2(vec3 x);"));
|
||||
s.append(TString("vec4 exp2(vec4 x);"));
|
||||
symbolTable.insertBuiltIn(float1, "exp2", float1);
|
||||
symbolTable.insertBuiltIn(float2, "exp2", float2);
|
||||
symbolTable.insertBuiltIn(float3, "exp2", float3);
|
||||
symbolTable.insertBuiltIn(float4, "exp2", float4);
|
||||
|
||||
s.append(TString("float log2(float x);"));
|
||||
s.append(TString("vec2 log2(vec2 x);"));
|
||||
s.append(TString("vec3 log2(vec3 x);"));
|
||||
s.append(TString("vec4 log2(vec4 x);"));
|
||||
symbolTable.insertBuiltIn(float1, "log2", float1);
|
||||
symbolTable.insertBuiltIn(float2, "log2", float2);
|
||||
symbolTable.insertBuiltIn(float3, "log2", float3);
|
||||
symbolTable.insertBuiltIn(float4, "log2", float4);
|
||||
|
||||
s.append(TString("float sqrt(float x);"));
|
||||
s.append(TString("vec2 sqrt(vec2 x);"));
|
||||
s.append(TString("vec3 sqrt(vec3 x);"));
|
||||
s.append(TString("vec4 sqrt(vec4 x);"));
|
||||
symbolTable.insertBuiltIn(float1, "sqrt", float1);
|
||||
symbolTable.insertBuiltIn(float2, "sqrt", float2);
|
||||
symbolTable.insertBuiltIn(float3, "sqrt", float3);
|
||||
symbolTable.insertBuiltIn(float4, "sqrt", float4);
|
||||
|
||||
s.append(TString("float inversesqrt(float x);"));
|
||||
s.append(TString("vec2 inversesqrt(vec2 x);"));
|
||||
s.append(TString("vec3 inversesqrt(vec3 x);"));
|
||||
s.append(TString("vec4 inversesqrt(vec4 x);"));
|
||||
symbolTable.insertBuiltIn(float1, "inversesqrt", float1);
|
||||
symbolTable.insertBuiltIn(float2, "inversesqrt", float2);
|
||||
symbolTable.insertBuiltIn(float3, "inversesqrt", float3);
|
||||
symbolTable.insertBuiltIn(float4, "inversesqrt", float4);
|
||||
|
||||
//
|
||||
// Common Functions.
|
||||
//
|
||||
s.append(TString("float abs(float x);"));
|
||||
s.append(TString("vec2 abs(vec2 x);"));
|
||||
s.append(TString("vec3 abs(vec3 x);"));
|
||||
s.append(TString("vec4 abs(vec4 x);"));
|
||||
symbolTable.insertBuiltIn(float1, "abs", float1);
|
||||
symbolTable.insertBuiltIn(float2, "abs", float2);
|
||||
symbolTable.insertBuiltIn(float3, "abs", float3);
|
||||
symbolTable.insertBuiltIn(float4, "abs", float4);
|
||||
|
||||
s.append(TString("float sign(float x);"));
|
||||
s.append(TString("vec2 sign(vec2 x);"));
|
||||
s.append(TString("vec3 sign(vec3 x);"));
|
||||
s.append(TString("vec4 sign(vec4 x);"));
|
||||
symbolTable.insertBuiltIn(float1, "sign", float1);
|
||||
symbolTable.insertBuiltIn(float2, "sign", float2);
|
||||
symbolTable.insertBuiltIn(float3, "sign", float3);
|
||||
symbolTable.insertBuiltIn(float4, "sign", float4);
|
||||
|
||||
s.append(TString("float floor(float x);"));
|
||||
s.append(TString("vec2 floor(vec2 x);"));
|
||||
s.append(TString("vec3 floor(vec3 x);"));
|
||||
s.append(TString("vec4 floor(vec4 x);"));
|
||||
symbolTable.insertBuiltIn(float1, "floor", float1);
|
||||
symbolTable.insertBuiltIn(float2, "floor", float2);
|
||||
symbolTable.insertBuiltIn(float3, "floor", float3);
|
||||
symbolTable.insertBuiltIn(float4, "floor", float4);
|
||||
|
||||
s.append(TString("float ceil(float x);"));
|
||||
s.append(TString("vec2 ceil(vec2 x);"));
|
||||
s.append(TString("vec3 ceil(vec3 x);"));
|
||||
s.append(TString("vec4 ceil(vec4 x);"));
|
||||
symbolTable.insertBuiltIn(float1, "ceil", float1);
|
||||
symbolTable.insertBuiltIn(float2, "ceil", float2);
|
||||
symbolTable.insertBuiltIn(float3, "ceil", float3);
|
||||
symbolTable.insertBuiltIn(float4, "ceil", float4);
|
||||
|
||||
s.append(TString("float fract(float x);"));
|
||||
s.append(TString("vec2 fract(vec2 x);"));
|
||||
s.append(TString("vec3 fract(vec3 x);"));
|
||||
s.append(TString("vec4 fract(vec4 x);"));
|
||||
symbolTable.insertBuiltIn(float1, "fract", float1);
|
||||
symbolTable.insertBuiltIn(float2, "fract", float2);
|
||||
symbolTable.insertBuiltIn(float3, "fract", float3);
|
||||
symbolTable.insertBuiltIn(float4, "fract", float4);
|
||||
|
||||
s.append(TString("float mod(float x, float y);"));
|
||||
s.append(TString("vec2 mod(vec2 x, float y);"));
|
||||
s.append(TString("vec3 mod(vec3 x, float y);"));
|
||||
s.append(TString("vec4 mod(vec4 x, float y);"));
|
||||
s.append(TString("vec2 mod(vec2 x, vec2 y);"));
|
||||
s.append(TString("vec3 mod(vec3 x, vec3 y);"));
|
||||
s.append(TString("vec4 mod(vec4 x, vec4 y);"));
|
||||
symbolTable.insertBuiltIn(float1, "mod", float1, float1);
|
||||
symbolTable.insertBuiltIn(float2, "mod", float2, float1);
|
||||
symbolTable.insertBuiltIn(float3, "mod", float3, float1);
|
||||
symbolTable.insertBuiltIn(float4, "mod", float4, float1);
|
||||
symbolTable.insertBuiltIn(float2, "mod", float2, float2);
|
||||
symbolTable.insertBuiltIn(float3, "mod", float3, float3);
|
||||
symbolTable.insertBuiltIn(float4, "mod", float4, float4);
|
||||
|
||||
s.append(TString("float min(float x, float y);"));
|
||||
s.append(TString("vec2 min(vec2 x, float y);"));
|
||||
s.append(TString("vec3 min(vec3 x, float y);"));
|
||||
s.append(TString("vec4 min(vec4 x, float y);"));
|
||||
s.append(TString("vec2 min(vec2 x, vec2 y);"));
|
||||
s.append(TString("vec3 min(vec3 x, vec3 y);"));
|
||||
s.append(TString("vec4 min(vec4 x, vec4 y);"));
|
||||
symbolTable.insertBuiltIn(float1, "min", float1, float1);
|
||||
symbolTable.insertBuiltIn(float2, "min", float2, float1);
|
||||
symbolTable.insertBuiltIn(float3, "min", float3, float1);
|
||||
symbolTable.insertBuiltIn(float4, "min", float4, float1);
|
||||
symbolTable.insertBuiltIn(float2, "min", float2, float2);
|
||||
symbolTable.insertBuiltIn(float3, "min", float3, float3);
|
||||
symbolTable.insertBuiltIn(float4, "min", float4, float4);
|
||||
|
||||
s.append(TString("float max(float x, float y);"));
|
||||
s.append(TString("vec2 max(vec2 x, float y);"));
|
||||
s.append(TString("vec3 max(vec3 x, float y);"));
|
||||
s.append(TString("vec4 max(vec4 x, float y);"));
|
||||
s.append(TString("vec2 max(vec2 x, vec2 y);"));
|
||||
s.append(TString("vec3 max(vec3 x, vec3 y);"));
|
||||
s.append(TString("vec4 max(vec4 x, vec4 y);"));
|
||||
symbolTable.insertBuiltIn(float1, "max", float1, float1);
|
||||
symbolTable.insertBuiltIn(float2, "max", float2, float1);
|
||||
symbolTable.insertBuiltIn(float3, "max", float3, float1);
|
||||
symbolTable.insertBuiltIn(float4, "max", float4, float1);
|
||||
symbolTable.insertBuiltIn(float2, "max", float2, float2);
|
||||
symbolTable.insertBuiltIn(float3, "max", float3, float3);
|
||||
symbolTable.insertBuiltIn(float4, "max", float4, float4);
|
||||
|
||||
s.append(TString("float clamp(float x, float minVal, float maxVal);"));
|
||||
s.append(TString("vec2 clamp(vec2 x, float minVal, float maxVal);"));
|
||||
s.append(TString("vec3 clamp(vec3 x, float minVal, float maxVal);"));
|
||||
s.append(TString("vec4 clamp(vec4 x, float minVal, float maxVal);"));
|
||||
s.append(TString("vec2 clamp(vec2 x, vec2 minVal, vec2 maxVal);"));
|
||||
s.append(TString("vec3 clamp(vec3 x, vec3 minVal, vec3 maxVal);"));
|
||||
s.append(TString("vec4 clamp(vec4 x, vec4 minVal, vec4 maxVal);"));
|
||||
symbolTable.insertBuiltIn(float1, "clamp", float1, float1, float1);
|
||||
symbolTable.insertBuiltIn(float2, "clamp", float2, float1, float1);
|
||||
symbolTable.insertBuiltIn(float3, "clamp", float3, float1, float1);
|
||||
symbolTable.insertBuiltIn(float4, "clamp", float4, float1, float1);
|
||||
symbolTable.insertBuiltIn(float2, "clamp", float2, float2, float2);
|
||||
symbolTable.insertBuiltIn(float3, "clamp", float3, float3, float3);
|
||||
symbolTable.insertBuiltIn(float4, "clamp", float4, float4, float4);
|
||||
|
||||
s.append(TString("float mix(float x, float y, float a);"));
|
||||
s.append(TString("vec2 mix(vec2 x, vec2 y, float a);"));
|
||||
s.append(TString("vec3 mix(vec3 x, vec3 y, float a);"));
|
||||
s.append(TString("vec4 mix(vec4 x, vec4 y, float a);"));
|
||||
s.append(TString("vec2 mix(vec2 x, vec2 y, vec2 a);"));
|
||||
s.append(TString("vec3 mix(vec3 x, vec3 y, vec3 a);"));
|
||||
s.append(TString("vec4 mix(vec4 x, vec4 y, vec4 a);"));
|
||||
symbolTable.insertBuiltIn(float1, "mix", float1, float1, float1);
|
||||
symbolTable.insertBuiltIn(float2, "mix", float2, float2, float1);
|
||||
symbolTable.insertBuiltIn(float3, "mix", float3, float3, float1);
|
||||
symbolTable.insertBuiltIn(float4, "mix", float4, float4, float1);
|
||||
symbolTable.insertBuiltIn(float2, "mix", float2, float2, float2);
|
||||
symbolTable.insertBuiltIn(float3, "mix", float3, float3, float3);
|
||||
symbolTable.insertBuiltIn(float4, "mix", float4, float4, float4);
|
||||
|
||||
s.append(TString("float step(float edge, float x);"));
|
||||
s.append(TString("vec2 step(vec2 edge, vec2 x);"));
|
||||
s.append(TString("vec3 step(vec3 edge, vec3 x);"));
|
||||
s.append(TString("vec4 step(vec4 edge, vec4 x);"));
|
||||
s.append(TString("vec2 step(float edge, vec2 x);"));
|
||||
s.append(TString("vec3 step(float edge, vec3 x);"));
|
||||
s.append(TString("vec4 step(float edge, vec4 x);"));
|
||||
symbolTable.insertBuiltIn(float1, "step", float1, float1);
|
||||
symbolTable.insertBuiltIn(float2, "step", float2, float2);
|
||||
symbolTable.insertBuiltIn(float3, "step", float3, float3);
|
||||
symbolTable.insertBuiltIn(float4, "step", float4, float4);
|
||||
symbolTable.insertBuiltIn(float2, "step", float1, float2);
|
||||
symbolTable.insertBuiltIn(float3, "step", float1, float3);
|
||||
symbolTable.insertBuiltIn(float4, "step", float1, float4);
|
||||
|
||||
s.append(TString("float smoothstep(float edge0, float edge1, float x);"));
|
||||
s.append(TString("vec2 smoothstep(vec2 edge0, vec2 edge1, vec2 x);"));
|
||||
s.append(TString("vec3 smoothstep(vec3 edge0, vec3 edge1, vec3 x);"));
|
||||
s.append(TString("vec4 smoothstep(vec4 edge0, vec4 edge1, vec4 x);"));
|
||||
s.append(TString("vec2 smoothstep(float edge0, float edge1, vec2 x);"));
|
||||
s.append(TString("vec3 smoothstep(float edge0, float edge1, vec3 x);"));
|
||||
s.append(TString("vec4 smoothstep(float edge0, float edge1, vec4 x);"));
|
||||
symbolTable.insertBuiltIn(float1, "smoothstep", float1, float1, float1);
|
||||
symbolTable.insertBuiltIn(float2, "smoothstep", float2, float2, float2);
|
||||
symbolTable.insertBuiltIn(float3, "smoothstep", float3, float3, float3);
|
||||
symbolTable.insertBuiltIn(float4, "smoothstep", float4, float4, float4);
|
||||
symbolTable.insertBuiltIn(float2, "smoothstep", float1, float1, float2);
|
||||
symbolTable.insertBuiltIn(float3, "smoothstep", float1, float1, float3);
|
||||
symbolTable.insertBuiltIn(float4, "smoothstep", float1, float1, float4);
|
||||
|
||||
//
|
||||
// Geometric Functions.
|
||||
//
|
||||
s.append(TString("float length(float x);"));
|
||||
s.append(TString("float length(vec2 x);"));
|
||||
s.append(TString("float length(vec3 x);"));
|
||||
s.append(TString("float length(vec4 x);"));
|
||||
symbolTable.insertBuiltIn(float1, "length", float1);
|
||||
symbolTable.insertBuiltIn(float1, "length", float2);
|
||||
symbolTable.insertBuiltIn(float1, "length", float3);
|
||||
symbolTable.insertBuiltIn(float1, "length", float4);
|
||||
|
||||
s.append(TString("float distance(float p0, float p1);"));
|
||||
s.append(TString("float distance(vec2 p0, vec2 p1);"));
|
||||
s.append(TString("float distance(vec3 p0, vec3 p1);"));
|
||||
s.append(TString("float distance(vec4 p0, vec4 p1);"));
|
||||
symbolTable.insertBuiltIn(float1, "distance", float1, float1);
|
||||
symbolTable.insertBuiltIn(float1, "distance", float2, float2);
|
||||
symbolTable.insertBuiltIn(float1, "distance", float3, float3);
|
||||
symbolTable.insertBuiltIn(float1, "distance", float4, float4);
|
||||
|
||||
s.append(TString("float dot(float x, float y);"));
|
||||
s.append(TString("float dot(vec2 x, vec2 y);"));
|
||||
s.append(TString("float dot(vec3 x, vec3 y);"));
|
||||
s.append(TString("float dot(vec4 x, vec4 y);"));
|
||||
symbolTable.insertBuiltIn(float1, "dot", float1, float1);
|
||||
symbolTable.insertBuiltIn(float1, "dot", float2, float2);
|
||||
symbolTable.insertBuiltIn(float1, "dot", float3, float3);
|
||||
symbolTable.insertBuiltIn(float1, "dot", float4, float4);
|
||||
|
||||
s.append(TString("vec3 cross(vec3 x, vec3 y);"));
|
||||
s.append(TString("float normalize(float x);"));
|
||||
s.append(TString("vec2 normalize(vec2 x);"));
|
||||
s.append(TString("vec3 normalize(vec3 x);"));
|
||||
s.append(TString("vec4 normalize(vec4 x);"));
|
||||
symbolTable.insertBuiltIn(float3, "cross", float3, float3);
|
||||
symbolTable.insertBuiltIn(float1, "normalize", float1);
|
||||
symbolTable.insertBuiltIn(float2, "normalize", float2);
|
||||
symbolTable.insertBuiltIn(float3, "normalize", float3);
|
||||
symbolTable.insertBuiltIn(float4, "normalize", float4);
|
||||
|
||||
s.append(TString("float faceforward(float N, float I, float Nref);"));
|
||||
s.append(TString("vec2 faceforward(vec2 N, vec2 I, vec2 Nref);"));
|
||||
s.append(TString("vec3 faceforward(vec3 N, vec3 I, vec3 Nref);"));
|
||||
s.append(TString("vec4 faceforward(vec4 N, vec4 I, vec4 Nref);"));
|
||||
symbolTable.insertBuiltIn(float1, "faceforward", float1, float1, float1);
|
||||
symbolTable.insertBuiltIn(float2, "faceforward", float2, float2, float2);
|
||||
symbolTable.insertBuiltIn(float3, "faceforward", float3, float3, float3);
|
||||
symbolTable.insertBuiltIn(float4, "faceforward", float4, float4, float4);
|
||||
|
||||
s.append(TString("float reflect(float I, float N);"));
|
||||
s.append(TString("vec2 reflect(vec2 I, vec2 N);"));
|
||||
s.append(TString("vec3 reflect(vec3 I, vec3 N);"));
|
||||
s.append(TString("vec4 reflect(vec4 I, vec4 N);"));
|
||||
symbolTable.insertBuiltIn(float1, "reflect", float1, float1);
|
||||
symbolTable.insertBuiltIn(float2, "reflect", float2, float2);
|
||||
symbolTable.insertBuiltIn(float3, "reflect", float3, float3);
|
||||
symbolTable.insertBuiltIn(float4, "reflect", float4, float4);
|
||||
|
||||
s.append(TString("float refract(float I, float N, float eta);"));
|
||||
s.append(TString("vec2 refract(vec2 I, vec2 N, float eta);"));
|
||||
s.append(TString("vec3 refract(vec3 I, vec3 N, float eta);"));
|
||||
s.append(TString("vec4 refract(vec4 I, vec4 N, float eta);"));
|
||||
symbolTable.insertBuiltIn(float1, "refract", float1, float1, float1);
|
||||
symbolTable.insertBuiltIn(float2, "refract", float2, float2, float1);
|
||||
symbolTable.insertBuiltIn(float3, "refract", float3, float3, float1);
|
||||
symbolTable.insertBuiltIn(float4, "refract", float4, float4, float1);
|
||||
|
||||
TType *mat2 = new TType(EbtFloat, EbpUndefined, EvqGlobal, 2, true);
|
||||
TType *mat3 = new TType(EbtFloat, EbpUndefined, EvqGlobal, 3, true);
|
||||
TType *mat4 = new TType(EbtFloat, EbpUndefined, EvqGlobal, 4, true);
|
||||
|
||||
//
|
||||
// Matrix Functions.
|
||||
//
|
||||
s.append(TString("mat2 matrixCompMult(mat2 x, mat2 y);"));
|
||||
s.append(TString("mat3 matrixCompMult(mat3 x, mat3 y);"));
|
||||
s.append(TString("mat4 matrixCompMult(mat4 x, mat4 y);"));
|
||||
symbolTable.insertBuiltIn(mat2, "matrixCompMult", mat2, mat2);
|
||||
symbolTable.insertBuiltIn(mat3, "matrixCompMult", mat3, mat3);
|
||||
symbolTable.insertBuiltIn(mat4, "matrixCompMult", mat4, mat4);
|
||||
|
||||
TType *bool1 = new TType(EbtBool, EbpUndefined, EvqGlobal, 1);
|
||||
TType *bool2 = new TType(EbtBool, EbpUndefined, EvqGlobal, 2);
|
||||
TType *bool3 = new TType(EbtBool, EbpUndefined, EvqGlobal, 3);
|
||||
TType *bool4 = new TType(EbtBool, EbpUndefined, EvqGlobal, 4);
|
||||
|
||||
//
|
||||
// Vector relational functions.
|
||||
//
|
||||
s.append(TString("bvec2 lessThan(vec2 x, vec2 y);"));
|
||||
s.append(TString("bvec3 lessThan(vec3 x, vec3 y);"));
|
||||
s.append(TString("bvec4 lessThan(vec4 x, vec4 y);"));
|
||||
symbolTable.insertBuiltIn(bool2, "lessThan", float2, float2);
|
||||
symbolTable.insertBuiltIn(bool3, "lessThan", float3, float3);
|
||||
symbolTable.insertBuiltIn(bool4, "lessThan", float4, float4);
|
||||
|
||||
s.append(TString("bvec2 lessThan(ivec2 x, ivec2 y);"));
|
||||
s.append(TString("bvec3 lessThan(ivec3 x, ivec3 y);"));
|
||||
s.append(TString("bvec4 lessThan(ivec4 x, ivec4 y);"));
|
||||
symbolTable.insertBuiltIn(bool2, "lessThan", int2, int2);
|
||||
symbolTable.insertBuiltIn(bool3, "lessThan", int3, int3);
|
||||
symbolTable.insertBuiltIn(bool4, "lessThan", int4, int4);
|
||||
|
||||
s.append(TString("bvec2 lessThanEqual(vec2 x, vec2 y);"));
|
||||
s.append(TString("bvec3 lessThanEqual(vec3 x, vec3 y);"));
|
||||
s.append(TString("bvec4 lessThanEqual(vec4 x, vec4 y);"));
|
||||
symbolTable.insertBuiltIn(bool2, "lessThanEqual", float2, float2);
|
||||
symbolTable.insertBuiltIn(bool3, "lessThanEqual", float3, float3);
|
||||
symbolTable.insertBuiltIn(bool4, "lessThanEqual", float4, float4);
|
||||
|
||||
s.append(TString("bvec2 lessThanEqual(ivec2 x, ivec2 y);"));
|
||||
s.append(TString("bvec3 lessThanEqual(ivec3 x, ivec3 y);"));
|
||||
s.append(TString("bvec4 lessThanEqual(ivec4 x, ivec4 y);"));
|
||||
symbolTable.insertBuiltIn(bool2, "lessThanEqual", int2, int2);
|
||||
symbolTable.insertBuiltIn(bool3, "lessThanEqual", int3, int3);
|
||||
symbolTable.insertBuiltIn(bool4, "lessThanEqual", int4, int4);
|
||||
|
||||
s.append(TString("bvec2 greaterThan(vec2 x, vec2 y);"));
|
||||
s.append(TString("bvec3 greaterThan(vec3 x, vec3 y);"));
|
||||
s.append(TString("bvec4 greaterThan(vec4 x, vec4 y);"));
|
||||
symbolTable.insertBuiltIn(bool2, "greaterThan", float2, float2);
|
||||
symbolTable.insertBuiltIn(bool3, "greaterThan", float3, float3);
|
||||
symbolTable.insertBuiltIn(bool4, "greaterThan", float4, float4);
|
||||
|
||||
s.append(TString("bvec2 greaterThan(ivec2 x, ivec2 y);"));
|
||||
s.append(TString("bvec3 greaterThan(ivec3 x, ivec3 y);"));
|
||||
s.append(TString("bvec4 greaterThan(ivec4 x, ivec4 y);"));
|
||||
symbolTable.insertBuiltIn(bool2, "greaterThan", int2, int2);
|
||||
symbolTable.insertBuiltIn(bool3, "greaterThan", int3, int3);
|
||||
symbolTable.insertBuiltIn(bool4, "greaterThan", int4, int4);
|
||||
|
||||
s.append(TString("bvec2 greaterThanEqual(vec2 x, vec2 y);"));
|
||||
s.append(TString("bvec3 greaterThanEqual(vec3 x, vec3 y);"));
|
||||
s.append(TString("bvec4 greaterThanEqual(vec4 x, vec4 y);"));
|
||||
symbolTable.insertBuiltIn(bool2, "greaterThanEqual", float2, float2);
|
||||
symbolTable.insertBuiltIn(bool3, "greaterThanEqual", float3, float3);
|
||||
symbolTable.insertBuiltIn(bool4, "greaterThanEqual", float4, float4);
|
||||
|
||||
s.append(TString("bvec2 greaterThanEqual(ivec2 x, ivec2 y);"));
|
||||
s.append(TString("bvec3 greaterThanEqual(ivec3 x, ivec3 y);"));
|
||||
s.append(TString("bvec4 greaterThanEqual(ivec4 x, ivec4 y);"));
|
||||
symbolTable.insertBuiltIn(bool2, "greaterThanEqual", int2, int2);
|
||||
symbolTable.insertBuiltIn(bool3, "greaterThanEqual", int3, int3);
|
||||
symbolTable.insertBuiltIn(bool4, "greaterThanEqual", int4, int4);
|
||||
|
||||
s.append(TString("bvec2 equal(vec2 x, vec2 y);"));
|
||||
s.append(TString("bvec3 equal(vec3 x, vec3 y);"));
|
||||
s.append(TString("bvec4 equal(vec4 x, vec4 y);"));
|
||||
symbolTable.insertBuiltIn(bool2, "equal", float2, float2);
|
||||
symbolTable.insertBuiltIn(bool3, "equal", float3, float3);
|
||||
symbolTable.insertBuiltIn(bool4, "equal", float4, float4);
|
||||
|
||||
s.append(TString("bvec2 equal(ivec2 x, ivec2 y);"));
|
||||
s.append(TString("bvec3 equal(ivec3 x, ivec3 y);"));
|
||||
s.append(TString("bvec4 equal(ivec4 x, ivec4 y);"));
|
||||
symbolTable.insertBuiltIn(bool2, "equal", int2, int2);
|
||||
symbolTable.insertBuiltIn(bool3, "equal", int3, int3);
|
||||
symbolTable.insertBuiltIn(bool4, "equal", int4, int4);
|
||||
|
||||
s.append(TString("bvec2 equal(bvec2 x, bvec2 y);"));
|
||||
s.append(TString("bvec3 equal(bvec3 x, bvec3 y);"));
|
||||
s.append(TString("bvec4 equal(bvec4 x, bvec4 y);"));
|
||||
symbolTable.insertBuiltIn(bool2, "equal", bool2, bool2);
|
||||
symbolTable.insertBuiltIn(bool3, "equal", bool3, bool3);
|
||||
symbolTable.insertBuiltIn(bool4, "equal", bool4, bool4);
|
||||
|
||||
s.append(TString("bvec2 notEqual(vec2 x, vec2 y);"));
|
||||
s.append(TString("bvec3 notEqual(vec3 x, vec3 y);"));
|
||||
s.append(TString("bvec4 notEqual(vec4 x, vec4 y);"));
|
||||
symbolTable.insertBuiltIn(bool2, "notEqual", float2, float2);
|
||||
symbolTable.insertBuiltIn(bool3, "notEqual", float3, float3);
|
||||
symbolTable.insertBuiltIn(bool4, "notEqual", float4, float4);
|
||||
|
||||
s.append(TString("bvec2 notEqual(ivec2 x, ivec2 y);"));
|
||||
s.append(TString("bvec3 notEqual(ivec3 x, ivec3 y);"));
|
||||
s.append(TString("bvec4 notEqual(ivec4 x, ivec4 y);"));
|
||||
symbolTable.insertBuiltIn(bool2, "notEqual", int2, int2);
|
||||
symbolTable.insertBuiltIn(bool3, "notEqual", int3, int3);
|
||||
symbolTable.insertBuiltIn(bool4, "notEqual", int4, int4);
|
||||
|
||||
s.append(TString("bvec2 notEqual(bvec2 x, bvec2 y);"));
|
||||
s.append(TString("bvec3 notEqual(bvec3 x, bvec3 y);"));
|
||||
s.append(TString("bvec4 notEqual(bvec4 x, bvec4 y);"));
|
||||
symbolTable.insertBuiltIn(bool2, "notEqual", bool2, bool2);
|
||||
symbolTable.insertBuiltIn(bool3, "notEqual", bool3, bool3);
|
||||
symbolTable.insertBuiltIn(bool4, "notEqual", bool4, bool4);
|
||||
|
||||
s.append(TString("bool any(bvec2 x);"));
|
||||
s.append(TString("bool any(bvec3 x);"));
|
||||
s.append(TString("bool any(bvec4 x);"));
|
||||
symbolTable.insertBuiltIn(bool1, "any", bool2);
|
||||
symbolTable.insertBuiltIn(bool1, "any", bool3);
|
||||
symbolTable.insertBuiltIn(bool1, "any", bool4);
|
||||
|
||||
s.append(TString("bool all(bvec2 x);"));
|
||||
s.append(TString("bool all(bvec3 x);"));
|
||||
s.append(TString("bool all(bvec4 x);"));
|
||||
symbolTable.insertBuiltIn(bool1, "all", bool2);
|
||||
symbolTable.insertBuiltIn(bool1, "all", bool3);
|
||||
symbolTable.insertBuiltIn(bool1, "all", bool4);
|
||||
|
||||
s.append(TString("bvec2 not(bvec2 x);"));
|
||||
s.append(TString("bvec3 not(bvec3 x);"));
|
||||
s.append(TString("bvec4 not(bvec4 x);"));
|
||||
symbolTable.insertBuiltIn(bool2, "not", bool2);
|
||||
symbolTable.insertBuiltIn(bool3, "not", bool3);
|
||||
symbolTable.insertBuiltIn(bool4, "not", bool4);
|
||||
|
||||
TType *sampler2D = new TType(EbtSampler2D, EbpUndefined, EvqGlobal, 1);
|
||||
TType *samplerCube = new TType(EbtSamplerCube, EbpUndefined, EvqGlobal, 1);
|
||||
|
||||
//
|
||||
// Texture Functions.
|
||||
// Texture Functions for GLSL ES 1.0
|
||||
//
|
||||
s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord);"));
|
||||
s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord);"));
|
||||
s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord);"));
|
||||
s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord);"));
|
||||
symbolTable.insertBuiltIn(float4, "texture2D", sampler2D, float2);
|
||||
symbolTable.insertBuiltIn(float4, "texture2DProj", sampler2D, float3);
|
||||
symbolTable.insertBuiltIn(float4, "texture2DProj", sampler2D, float4);
|
||||
symbolTable.insertBuiltIn(float4, "textureCube", samplerCube, float3);
|
||||
|
||||
if (resources.OES_EGL_image_external) {
|
||||
s.append(TString("vec4 texture2D(samplerExternalOES sampler, vec2 coord);"));
|
||||
s.append(TString("vec4 texture2DProj(samplerExternalOES sampler, vec3 coord);"));
|
||||
s.append(TString("vec4 texture2DProj(samplerExternalOES sampler, vec4 coord);"));
|
||||
if (resources.OES_EGL_image_external)
|
||||
{
|
||||
TType *samplerExternalOES = new TType(EbtSamplerExternalOES, EbpUndefined, EvqGlobal, 1);
|
||||
|
||||
symbolTable.insertBuiltIn(float4, "texture2D", samplerExternalOES, float2);
|
||||
symbolTable.insertBuiltIn(float4, "texture2DProj", samplerExternalOES, float3);
|
||||
symbolTable.insertBuiltIn(float4, "texture2DProj", samplerExternalOES, float4);
|
||||
}
|
||||
|
||||
if (resources.ARB_texture_rectangle) {
|
||||
s.append(TString("vec4 texture2DRect(sampler2DRect sampler, vec2 coord);"));
|
||||
s.append(TString("vec4 texture2DRectProj(sampler2DRect sampler, vec3 coord);"));
|
||||
s.append(TString("vec4 texture2DRectProj(sampler2DRect sampler, vec4 coord);"));
|
||||
if (resources.ARB_texture_rectangle)
|
||||
{
|
||||
TType *sampler2DRect = new TType(EbtSampler2DRect, EbpUndefined, EvqGlobal, 1);
|
||||
|
||||
symbolTable.insertBuiltIn(float4, "texture2DRect", sampler2DRect, float2);
|
||||
symbolTable.insertBuiltIn(float4, "texture2DRectProj", sampler2DRect, float3);
|
||||
symbolTable.insertBuiltIn(float4, "texture2DRectProj", sampler2DRect, float4);
|
||||
}
|
||||
|
||||
//
|
||||
// Noise functions.
|
||||
//
|
||||
//s.append(TString("float noise1(float x);"));
|
||||
//s.append(TString("float noise1(vec2 x);"));
|
||||
//s.append(TString("float noise1(vec3 x);"));
|
||||
//s.append(TString("float noise1(vec4 x);"));
|
||||
if (type == SH_FRAGMENT_SHADER)
|
||||
{
|
||||
symbolTable.insertBuiltIn(float4, "texture2D", sampler2D, float2, float1);
|
||||
symbolTable.insertBuiltIn(float4, "texture2DProj", sampler2D, float3, float1);
|
||||
symbolTable.insertBuiltIn(float4, "texture2DProj", sampler2D, float4, float1);
|
||||
symbolTable.insertBuiltIn(float4, "textureCube", samplerCube, float3, float1);
|
||||
|
||||
//s.append(TString("vec2 noise2(float x);"));
|
||||
//s.append(TString("vec2 noise2(vec2 x);"));
|
||||
//s.append(TString("vec2 noise2(vec3 x);"));
|
||||
//s.append(TString("vec2 noise2(vec4 x);"));
|
||||
if (resources.OES_standard_derivatives)
|
||||
{
|
||||
symbolTable.insertBuiltIn(float1, "dFdx", float1);
|
||||
symbolTable.insertBuiltIn(float2, "dFdx", float2);
|
||||
symbolTable.insertBuiltIn(float3, "dFdx", float3);
|
||||
symbolTable.insertBuiltIn(float4, "dFdx", float4);
|
||||
|
||||
//s.append(TString("vec3 noise3(float x);"));
|
||||
//s.append(TString("vec3 noise3(vec2 x);"));
|
||||
//s.append(TString("vec3 noise3(vec3 x);"));
|
||||
//s.append(TString("vec3 noise3(vec4 x);"));
|
||||
symbolTable.insertBuiltIn(float1, "dFdy", float1);
|
||||
symbolTable.insertBuiltIn(float2, "dFdy", float2);
|
||||
symbolTable.insertBuiltIn(float3, "dFdy", float3);
|
||||
symbolTable.insertBuiltIn(float4, "dFdy", float4);
|
||||
|
||||
//s.append(TString("vec4 noise4(float x);"));
|
||||
//s.append(TString("vec4 noise4(vec2 x);"));
|
||||
//s.append(TString("vec4 noise4(vec3 x);"));
|
||||
//s.append(TString("vec4 noise4(vec4 x);"));
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Prototypes for built-in functions seen by vertex shaders only.
|
||||
//
|
||||
//============================================================================
|
||||
static TString BuiltInFunctionsVertex(const ShBuiltInResources& resources)
|
||||
{
|
||||
TString s;
|
||||
|
||||
//
|
||||
// Geometric Functions.
|
||||
//
|
||||
//s.append(TString("vec4 ftransform();"));
|
||||
|
||||
//
|
||||
// Texture Functions.
|
||||
//
|
||||
s.append(TString("vec4 texture2DLod(sampler2D sampler, vec2 coord, float lod);"));
|
||||
s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec3 coord, float lod);"));
|
||||
s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec4 coord, float lod);"));
|
||||
s.append(TString("vec4 textureCubeLod(samplerCube sampler, vec3 coord, float lod);"));
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Prototypes for built-in functions seen by fragment shaders only.
|
||||
//
|
||||
//============================================================================
|
||||
static TString BuiltInFunctionsFragment(const ShBuiltInResources& resources)
|
||||
{
|
||||
TString s;
|
||||
|
||||
//
|
||||
// Texture Functions.
|
||||
//
|
||||
s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord, float bias);"));
|
||||
s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord, float bias);"));
|
||||
s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord, float bias);"));
|
||||
s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord, float bias);"));
|
||||
|
||||
if (resources.OES_standard_derivatives) {
|
||||
s.append(TString("float dFdx(float p);"));
|
||||
s.append(TString("vec2 dFdx(vec2 p);"));
|
||||
s.append(TString("vec3 dFdx(vec3 p);"));
|
||||
s.append(TString("vec4 dFdx(vec4 p);"));
|
||||
|
||||
s.append(TString("float dFdy(float p);"));
|
||||
s.append(TString("vec2 dFdy(vec2 p);"));
|
||||
s.append(TString("vec3 dFdy(vec3 p);"));
|
||||
s.append(TString("vec4 dFdy(vec4 p);"));
|
||||
|
||||
s.append(TString("float fwidth(float p);"));
|
||||
s.append(TString("vec2 fwidth(vec2 p);"));
|
||||
s.append(TString("vec3 fwidth(vec3 p);"));
|
||||
s.append(TString("vec4 fwidth(vec4 p);"));
|
||||
symbolTable.insertBuiltIn(float1, "fwidth", float1);
|
||||
symbolTable.insertBuiltIn(float2, "fwidth", float2);
|
||||
symbolTable.insertBuiltIn(float3, "fwidth", float3);
|
||||
symbolTable.insertBuiltIn(float4, "fwidth", float4);
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Standard uniforms.
|
||||
//
|
||||
//============================================================================
|
||||
static TString StandardUniforms()
|
||||
{
|
||||
TString s;
|
||||
if(type == SH_VERTEX_SHADER)
|
||||
{
|
||||
symbolTable.insertBuiltIn(float4, "texture2DLod", sampler2D, float2, float1);
|
||||
symbolTable.insertBuiltIn(float4, "texture2DProjLod", sampler2D, float3, float1);
|
||||
symbolTable.insertBuiltIn(float4, "texture2DProjLod", sampler2D, float4, float1);
|
||||
symbolTable.insertBuiltIn(float4, "textureCubeLod", samplerCube, float3, float1);
|
||||
}
|
||||
|
||||
//
|
||||
// Depth range in window coordinates
|
||||
//
|
||||
s.append(TString("struct gl_DepthRangeParameters {"));
|
||||
s.append(TString(" highp float near;")); // n
|
||||
s.append(TString(" highp float far;")); // f
|
||||
s.append(TString(" highp float diff;")); // f - n
|
||||
s.append(TString("};"));
|
||||
s.append(TString("uniform gl_DepthRangeParameters gl_DepthRange;"));
|
||||
TFieldList *fields = NewPoolTFieldList();
|
||||
TField *near = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("near"));
|
||||
TField *far = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("far"));
|
||||
TField *diff = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("diff"));
|
||||
fields->push_back(near);
|
||||
fields->push_back(far);
|
||||
fields->push_back(diff);
|
||||
TStructure *depthRangeStruct = new TStructure(NewPoolTString("gl_DepthRangeParameters"), fields);
|
||||
TVariable *depthRangeParameters = new TVariable(&depthRangeStruct->name(), depthRangeStruct, true);
|
||||
symbolTable.insert(*depthRangeParameters);
|
||||
TVariable *depthRange = new TVariable(NewPoolTString("gl_DepthRange"), TType(depthRangeStruct));
|
||||
depthRange->setQualifier(EvqUniform);
|
||||
symbolTable.insert(*depthRange);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Default precision for vertex shaders.
|
||||
//
|
||||
//============================================================================
|
||||
static TString DefaultPrecisionVertex()
|
||||
{
|
||||
TString s;
|
||||
|
||||
s.append(TString("precision highp int;"));
|
||||
s.append(TString("precision highp float;"));
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Default precision for fragment shaders.
|
||||
//
|
||||
//============================================================================
|
||||
static TString DefaultPrecisionFragment()
|
||||
{
|
||||
TString s;
|
||||
|
||||
s.append(TString("precision mediump int;"));
|
||||
// No default precision for float in fragment shaders
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Implementation dependent built-in constants.
|
||||
//
|
||||
//============================================================================
|
||||
static TString BuiltInConstants(ShShaderSpec spec, const ShBuiltInResources &resources)
|
||||
{
|
||||
TStringStream s;
|
||||
|
||||
s << "const int gl_MaxVertexAttribs = " << resources.MaxVertexAttribs << ";";
|
||||
s << "const int gl_MaxVertexUniformVectors = " << resources.MaxVertexUniformVectors << ";";
|
||||
|
||||
s << "const int gl_MaxVaryingVectors = " << resources.MaxVaryingVectors << ";";
|
||||
s << "const int gl_MaxVertexTextureImageUnits = " << resources.MaxVertexTextureImageUnits << ";";
|
||||
s << "const int gl_MaxCombinedTextureImageUnits = " << resources.MaxCombinedTextureImageUnits << ";";
|
||||
s << "const int gl_MaxTextureImageUnits = " << resources.MaxTextureImageUnits << ";";
|
||||
s << "const int gl_MaxFragmentUniformVectors = " << resources.MaxFragmentUniformVectors << ";";
|
||||
//
|
||||
// Implementation dependent built-in constants.
|
||||
//
|
||||
symbolTable.insertConstInt("gl_MaxVertexAttribs", resources.MaxVertexAttribs);
|
||||
symbolTable.insertConstInt("gl_MaxVertexUniformVectors", resources.MaxVertexUniformVectors);
|
||||
symbolTable.insertConstInt("gl_MaxVaryingVectors", resources.MaxVaryingVectors);
|
||||
symbolTable.insertConstInt("gl_MaxVertexTextureImageUnits", resources.MaxVertexTextureImageUnits);
|
||||
symbolTable.insertConstInt("gl_MaxCombinedTextureImageUnits", resources.MaxCombinedTextureImageUnits);
|
||||
symbolTable.insertConstInt("gl_MaxTextureImageUnits", resources.MaxTextureImageUnits);
|
||||
symbolTable.insertConstInt("gl_MaxFragmentUniformVectors", resources.MaxFragmentUniformVectors);
|
||||
|
||||
if (spec != SH_CSS_SHADERS_SPEC)
|
||||
s << "const int gl_MaxDrawBuffers = " << resources.MaxDrawBuffers << ";";
|
||||
|
||||
return s.str();
|
||||
}
|
||||
|
||||
void TBuiltIns::initialize(ShShaderType type, ShShaderSpec spec,
|
||||
const ShBuiltInResources& resources)
|
||||
{
|
||||
switch (type) {
|
||||
case SH_FRAGMENT_SHADER:
|
||||
builtInStrings.push_back(DefaultPrecisionFragment());
|
||||
builtInStrings.push_back(BuiltInFunctionsCommon(resources));
|
||||
builtInStrings.push_back(BuiltInFunctionsFragment(resources));
|
||||
builtInStrings.push_back(StandardUniforms());
|
||||
break;
|
||||
|
||||
case SH_VERTEX_SHADER:
|
||||
builtInStrings.push_back(DefaultPrecisionVertex());
|
||||
builtInStrings.push_back(BuiltInFunctionsCommon(resources));
|
||||
builtInStrings.push_back(BuiltInFunctionsVertex(resources));
|
||||
builtInStrings.push_back(StandardUniforms());
|
||||
break;
|
||||
|
||||
default: assert(false && "Language not supported");
|
||||
{
|
||||
symbolTable.insertConstInt("gl_MaxDrawBuffers", resources.MaxDrawBuffers);
|
||||
}
|
||||
|
||||
builtInStrings.push_back(BuiltInConstants(spec, resources));
|
||||
}
|
||||
|
||||
void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec,
|
||||
const ShBuiltInResources& resources,
|
||||
TSymbolTable& symbolTable)
|
||||
const ShBuiltInResources &resources,
|
||||
TSymbolTable &symbolTable)
|
||||
{
|
||||
//
|
||||
// First, insert some special built-in variables that are not in
|
||||
|
@ -539,6 +439,10 @@ void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec,
|
|||
if (spec != SH_CSS_SHADERS_SPEC) {
|
||||
symbolTable.insert(*new TVariable(NewPoolTString("gl_FragColor"), TType(EbtFloat, EbpMedium, EvqFragColor, 4)));
|
||||
symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqFragData, 4)));
|
||||
if (resources.EXT_frag_depth) {
|
||||
symbolTable.insert(*new TVariable(NewPoolTString("gl_FragDepthEXT"), TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium, EvqFragDepth, 1)));
|
||||
symbolTable.relateToExtension("gl_FragDepthEXT", "GL_EXT_frag_depth");
|
||||
}
|
||||
} else {
|
||||
symbolTable.insert(*new TVariable(NewPoolTString("css_MixColor"), TType(EbtFloat, EbpMedium, EvqGlobal, 4)));
|
||||
symbolTable.insert(*new TVariable(NewPoolTString("css_ColorMatrix"), TType(EbtFloat, EbpMedium, EvqGlobal, 4, true)));
|
||||
|
@ -560,8 +464,6 @@ void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec,
|
|||
// expected to be resolved through a library of functions, versus as
|
||||
// operations.
|
||||
//
|
||||
symbolTable.relateToOperator("not", EOpVectorLogicalNot);
|
||||
|
||||
symbolTable.relateToOperator("matrixCompMult", EOpMul);
|
||||
|
||||
symbolTable.relateToOperator("equal", EOpVectorEqual);
|
||||
|
@ -612,6 +514,7 @@ void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec,
|
|||
|
||||
symbolTable.relateToOperator("any", EOpAny);
|
||||
symbolTable.relateToOperator("all", EOpAll);
|
||||
symbolTable.relateToOperator("not", EOpVectorLogicalNot);
|
||||
|
||||
// Map language-specific operators.
|
||||
switch(type) {
|
||||
|
@ -656,4 +559,6 @@ void InitExtensionBehavior(const ShBuiltInResources& resources,
|
|||
extBehavior["GL_ARB_texture_rectangle"] = EBhUndefined;
|
||||
if (resources.EXT_draw_buffers)
|
||||
extBehavior["GL_EXT_draw_buffers"] = EBhUndefined;
|
||||
if (resources.EXT_frag_depth)
|
||||
extBehavior["GL_EXT_frag_depth"] = EBhUndefined;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
|
||||
// Copyright (c) 2002-2013 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.
|
||||
//
|
||||
|
@ -11,19 +11,7 @@
|
|||
#include "compiler/ShHandle.h"
|
||||
#include "compiler/SymbolTable.h"
|
||||
|
||||
typedef TVector<TString> TBuiltInStrings;
|
||||
|
||||
class TBuiltIns {
|
||||
public:
|
||||
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
|
||||
|
||||
void initialize(ShShaderType type, ShShaderSpec spec,
|
||||
const ShBuiltInResources& resources);
|
||||
const TBuiltInStrings& getBuiltInStrings() { return builtInStrings; }
|
||||
|
||||
protected:
|
||||
TBuiltInStrings builtInStrings;
|
||||
};
|
||||
void InsertBuiltInFunctions(ShShaderType type, ShShaderSpec spec, const ShBuiltInResources &resources, TSymbolTable &table);
|
||||
|
||||
void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec,
|
||||
const ShBuiltInResources& resources,
|
||||
|
|
|
@ -10,25 +10,8 @@
|
|||
#include "compiler/InitializeParseContext.h"
|
||||
#include "compiler/osinclude.h"
|
||||
|
||||
OS_TLSIndex ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
|
||||
|
||||
bool InitProcess()
|
||||
{
|
||||
if (ThreadInitializeIndex != OS_INVALID_TLS_INDEX) {
|
||||
//
|
||||
// Function is re-entrant.
|
||||
//
|
||||
return true;
|
||||
}
|
||||
|
||||
ThreadInitializeIndex = OS_AllocTLSIndex();
|
||||
|
||||
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
|
||||
assert(0 && "InitProcess(): Failed to allocate TLS area for init flag");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (!InitializePoolIndex()) {
|
||||
assert(0 && "InitProcess(): Failed to initalize global pool");
|
||||
return false;
|
||||
|
@ -39,77 +22,11 @@ bool InitProcess()
|
|||
return false;
|
||||
}
|
||||
|
||||
return InitThread();
|
||||
}
|
||||
|
||||
bool DetachProcess()
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
|
||||
return true;
|
||||
|
||||
success = DetachThread();
|
||||
|
||||
if (!FreeParseContextIndex())
|
||||
success = false;
|
||||
|
||||
FreePoolIndex();
|
||||
|
||||
OS_FreeTLSIndex(ThreadInitializeIndex);
|
||||
ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool InitThread()
|
||||
{
|
||||
//
|
||||
// This function is re-entrant
|
||||
//
|
||||
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
|
||||
assert(0 && "InitThread(): Process hasn't been initalised.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (OS_GetTLSValue(ThreadInitializeIndex) != 0)
|
||||
return true;
|
||||
|
||||
InitializeGlobalPools();
|
||||
|
||||
if (!InitializeGlobalParseContext())
|
||||
return false;
|
||||
|
||||
if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)1)) {
|
||||
assert(0 && "InitThread(): Unable to set init flag.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DetachThread()
|
||||
void DetachProcess()
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
|
||||
return true;
|
||||
|
||||
//
|
||||
// Function is re-entrant and this thread may not have been initalised.
|
||||
//
|
||||
if (OS_GetTLSValue(ThreadInitializeIndex) != 0) {
|
||||
if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)0)) {
|
||||
assert(0 && "DetachThread(): Unable to clear init flag.");
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (!FreeParseContext())
|
||||
success = false;
|
||||
|
||||
FreeGlobalPools();
|
||||
}
|
||||
|
||||
return success;
|
||||
FreeParseContextIndex();
|
||||
FreePoolIndex();
|
||||
}
|
||||
|
||||
|
|
|
@ -7,10 +7,7 @@
|
|||
#define __INITIALIZEDLL_H
|
||||
|
||||
bool InitProcess();
|
||||
bool DetachProcess();
|
||||
|
||||
bool InitThread();
|
||||
bool DetachThread();
|
||||
void DetachProcess();
|
||||
|
||||
#endif // __INITIALIZEDLL_H
|
||||
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
#ifndef __INITIALIZE_GLOBALS_INCLUDED_
|
||||
#define __INITIALIZE_GLOBALS_INCLUDED_
|
||||
|
||||
void InitializeGlobalPools();
|
||||
void FreeGlobalPools();
|
||||
bool InitializePoolIndex();
|
||||
void FreePoolIndex();
|
||||
|
||||
|
|
|
@ -12,85 +12,29 @@ OS_TLSIndex GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
|
|||
|
||||
bool InitializeParseContextIndex()
|
||||
{
|
||||
if (GlobalParseContextIndex != OS_INVALID_TLS_INDEX) {
|
||||
assert(0 && "InitializeParseContextIndex(): Parse Context already initalized");
|
||||
return false;
|
||||
}
|
||||
assert(GlobalParseContextIndex == OS_INVALID_TLS_INDEX);
|
||||
|
||||
//
|
||||
// Allocate a TLS index.
|
||||
//
|
||||
GlobalParseContextIndex = OS_AllocTLSIndex();
|
||||
|
||||
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
|
||||
assert(0 && "InitializeParseContextIndex(): Parse Context already initalized");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return GlobalParseContextIndex != OS_INVALID_TLS_INDEX;
|
||||
}
|
||||
|
||||
bool FreeParseContextIndex()
|
||||
void FreeParseContextIndex()
|
||||
{
|
||||
OS_TLSIndex tlsiIndex = GlobalParseContextIndex;
|
||||
|
||||
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
|
||||
assert(0 && "FreeParseContextIndex(): Parse Context index not initalized");
|
||||
return false;
|
||||
}
|
||||
assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
|
||||
|
||||
OS_FreeTLSIndex(GlobalParseContextIndex);
|
||||
GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
|
||||
|
||||
return OS_FreeTLSIndex(tlsiIndex);
|
||||
}
|
||||
|
||||
bool InitializeGlobalParseContext()
|
||||
void SetGlobalParseContext(TParseContext* context)
|
||||
{
|
||||
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
|
||||
assert(0 && "InitializeGlobalParseContext(): Parse Context index not initalized");
|
||||
return false;
|
||||
}
|
||||
|
||||
TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
|
||||
if (lpParseContext != 0) {
|
||||
assert(0 && "InitializeParseContextIndex(): Parse Context already initalized");
|
||||
return false;
|
||||
}
|
||||
|
||||
TThreadParseContext *lpThreadData = new TThreadParseContext();
|
||||
if (lpThreadData == 0) {
|
||||
assert(0 && "InitializeGlobalParseContext(): Unable to create thread parse context");
|
||||
return false;
|
||||
}
|
||||
|
||||
lpThreadData->lpGlobalParseContext = 0;
|
||||
OS_SetTLSValue(GlobalParseContextIndex, lpThreadData);
|
||||
|
||||
return true;
|
||||
assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
|
||||
OS_SetTLSValue(GlobalParseContextIndex, context);
|
||||
}
|
||||
|
||||
bool FreeParseContext()
|
||||
TParseContext* GetGlobalParseContext()
|
||||
{
|
||||
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
|
||||
assert(0 && "FreeParseContext(): Parse Context index not initalized");
|
||||
return false;
|
||||
}
|
||||
|
||||
TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
|
||||
if (lpParseContext)
|
||||
delete lpParseContext;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TParseContextPointer& GetGlobalParseContext()
|
||||
{
|
||||
//
|
||||
// Minimal error checking for speed
|
||||
//
|
||||
|
||||
TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
|
||||
|
||||
return lpParseContext->lpGlobalParseContext;
|
||||
assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
|
||||
return static_cast<TParseContext*>(OS_GetTLSValue(GlobalParseContextIndex));
|
||||
}
|
||||
|
||||
|
|
|
@ -8,19 +8,10 @@
|
|||
#define __INITIALIZE_PARSE_CONTEXT_INCLUDED_
|
||||
|
||||
bool InitializeParseContextIndex();
|
||||
bool FreeParseContextIndex();
|
||||
|
||||
bool InitializeGlobalParseContext();
|
||||
bool FreeParseContext();
|
||||
void FreeParseContextIndex();
|
||||
|
||||
struct TParseContext;
|
||||
typedef TParseContext* TParseContextPointer;
|
||||
extern TParseContextPointer& GetGlobalParseContext();
|
||||
#define GlobalParseContext GetGlobalParseContext()
|
||||
|
||||
typedef struct TThreadParseContextRec
|
||||
{
|
||||
TParseContext *lpGlobalParseContext;
|
||||
} TThreadParseContext;
|
||||
extern void SetGlobalParseContext(TParseContext* context);
|
||||
extern TParseContext* GetGlobalParseContext();
|
||||
|
||||
#endif // __INITIALIZE_PARSE_CONTEXT_INCLUDED_
|
||||
|
|
|
@ -131,7 +131,7 @@ const char* getOperatorString(TOperator op) {
|
|||
//
|
||||
// Returns the added node.
|
||||
//
|
||||
TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, TSourceLoc line)
|
||||
TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, const TSourceLoc& line)
|
||||
{
|
||||
TIntermSymbol* node = new TIntermSymbol(id, name, type);
|
||||
node->setLine(line);
|
||||
|
@ -144,7 +144,7 @@ TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType
|
|||
//
|
||||
// Returns the added node.
|
||||
//
|
||||
TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line, TSymbolTable& symbolTable)
|
||||
TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc& line, TSymbolTable& symbolTable)
|
||||
{
|
||||
switch (op) {
|
||||
case EOpEqual:
|
||||
|
@ -200,8 +200,6 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
|
|||
// one and promote it to the right type.
|
||||
//
|
||||
TIntermBinary* node = new TIntermBinary(op);
|
||||
if (line == 0)
|
||||
line = right->getLine();
|
||||
node->setLine(line);
|
||||
|
||||
node->setLeft(left);
|
||||
|
@ -230,15 +228,13 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
|
|||
//
|
||||
// Returns the added node.
|
||||
//
|
||||
TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line)
|
||||
TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc& line)
|
||||
{
|
||||
//
|
||||
// Like adding binary math, except the conversion can only go
|
||||
// from right to left.
|
||||
//
|
||||
TIntermBinary* node = new TIntermBinary(op);
|
||||
if (line == 0)
|
||||
line = left->getLine();
|
||||
node->setLine(line);
|
||||
|
||||
TIntermTyped* child = addConversion(op, left->getType(), right);
|
||||
|
@ -260,11 +256,9 @@ TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TInterm
|
|||
// Returns the added node.
|
||||
// The caller should set the type of the returned node.
|
||||
//
|
||||
TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc line)
|
||||
TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, const TSourceLoc& line)
|
||||
{
|
||||
TIntermBinary* node = new TIntermBinary(op);
|
||||
if (line == 0)
|
||||
line = index->getLine();
|
||||
node->setLine(line);
|
||||
node->setLeft(base);
|
||||
node->setRight(index);
|
||||
|
@ -279,13 +273,13 @@ TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermT
|
|||
//
|
||||
// Returns the added node.
|
||||
//
|
||||
TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, TSourceLoc line, TSymbolTable& symbolTable)
|
||||
TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, const TSourceLoc& line, TSymbolTable& symbolTable)
|
||||
{
|
||||
TIntermUnary* node;
|
||||
TIntermTyped* child = childNode->getAsTyped();
|
||||
|
||||
if (child == 0) {
|
||||
infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", line);
|
||||
infoSink.info.message(EPrefixInternalError, line, "Bad type in AddUnaryMath");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -348,8 +342,6 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode,
|
|||
// Make a new node for the operator.
|
||||
//
|
||||
node = new TIntermUnary(op);
|
||||
if (line == 0)
|
||||
line = child->getLine();
|
||||
node->setLine(line);
|
||||
node->setOperand(child);
|
||||
|
||||
|
@ -376,7 +368,7 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode,
|
|||
// Returns an aggregate node, which could be the one passed in if
|
||||
// it was already an aggregate but no operator was set.
|
||||
//
|
||||
TIntermAggregate* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, TSourceLoc line)
|
||||
TIntermAggregate* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, const TSourceLoc& line)
|
||||
{
|
||||
TIntermAggregate* aggNode;
|
||||
|
||||
|
@ -391,8 +383,6 @@ TIntermAggregate* TIntermediate::setAggregateOperator(TIntermNode* node, TOperat
|
|||
//
|
||||
aggNode = new TIntermAggregate();
|
||||
aggNode->getSequence().push_back(node);
|
||||
if (line == 0)
|
||||
line = node->getLine();
|
||||
}
|
||||
} else
|
||||
aggNode = new TIntermAggregate();
|
||||
|
@ -401,8 +391,7 @@ TIntermAggregate* TIntermediate::setAggregateOperator(TIntermNode* node, TOperat
|
|||
// Set the operator.
|
||||
//
|
||||
aggNode->setOp(op);
|
||||
if (line != 0)
|
||||
aggNode->setLine(line);
|
||||
aggNode->setLine(line);
|
||||
|
||||
return aggNode;
|
||||
}
|
||||
|
@ -491,7 +480,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
|||
case EbtInt: newOp = EOpConvIntToFloat; break;
|
||||
case EbtBool: newOp = EOpConvBoolToFloat; break;
|
||||
default:
|
||||
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
|
||||
infoSink.info.message(EPrefixInternalError, node->getLine(), "Bad promotion node");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
@ -500,7 +489,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
|||
case EbtInt: newOp = EOpConvIntToBool; break;
|
||||
case EbtFloat: newOp = EOpConvFloatToBool; break;
|
||||
default:
|
||||
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
|
||||
infoSink.info.message(EPrefixInternalError, node->getLine(), "Bad promotion node");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
@ -509,12 +498,12 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
|||
case EbtBool: newOp = EOpConvBoolToInt; break;
|
||||
case EbtFloat: newOp = EOpConvFloatToInt; break;
|
||||
default:
|
||||
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
|
||||
infoSink.info.message(EPrefixInternalError, node->getLine(), "Bad promotion node");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
infoSink.info.message(EPrefixInternalError, "Bad promotion type", node->getLine());
|
||||
infoSink.info.message(EPrefixInternalError, node->getLine(), "Bad promotion type");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -534,7 +523,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
|||
// Returns the resulting aggregate, unless 0 was passed in for
|
||||
// both existing nodes.
|
||||
//
|
||||
TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, TSourceLoc line)
|
||||
TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc& line)
|
||||
{
|
||||
if (left == 0 && right == 0)
|
||||
return 0;
|
||||
|
@ -551,8 +540,7 @@ TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* r
|
|||
if (right)
|
||||
aggNode->getSequence().push_back(right);
|
||||
|
||||
if (line != 0)
|
||||
aggNode->setLine(line);
|
||||
aggNode->setLine(line);
|
||||
|
||||
return aggNode;
|
||||
}
|
||||
|
@ -562,18 +550,14 @@ TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* r
|
|||
//
|
||||
// Returns an aggregate, unless 0 was passed in for the existing node.
|
||||
//
|
||||
TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, TSourceLoc line)
|
||||
TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, const TSourceLoc& line)
|
||||
{
|
||||
if (node == 0)
|
||||
return 0;
|
||||
|
||||
TIntermAggregate* aggNode = new TIntermAggregate;
|
||||
aggNode->getSequence().push_back(node);
|
||||
|
||||
if (line != 0)
|
||||
aggNode->setLine(line);
|
||||
else
|
||||
aggNode->setLine(node->getLine());
|
||||
aggNode->setLine(line);
|
||||
|
||||
return aggNode;
|
||||
}
|
||||
|
@ -585,7 +569,7 @@ TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, TSourceLoc lin
|
|||
//
|
||||
// Returns the selection node created.
|
||||
//
|
||||
TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, TSourceLoc line)
|
||||
TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, const TSourceLoc& line)
|
||||
{
|
||||
//
|
||||
// For compile time constant selections, prune the code and
|
||||
|
@ -606,7 +590,7 @@ TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nod
|
|||
}
|
||||
|
||||
|
||||
TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc line)
|
||||
TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc& line)
|
||||
{
|
||||
if (left->getType().getQualifier() == EvqConst && right->getType().getQualifier() == EvqConst) {
|
||||
return right;
|
||||
|
@ -626,7 +610,7 @@ TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, T
|
|||
//
|
||||
// Returns the selection node created, or 0 if one could not be.
|
||||
//
|
||||
TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc line)
|
||||
TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc& line)
|
||||
{
|
||||
//
|
||||
// Get compatible types.
|
||||
|
@ -669,7 +653,7 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true
|
|||
// Returns the constant union node created.
|
||||
//
|
||||
|
||||
TIntermConstantUnion* TIntermediate::addConstantUnion(ConstantUnion* unionArrayPointer, const TType& t, TSourceLoc line)
|
||||
TIntermConstantUnion* TIntermediate::addConstantUnion(ConstantUnion* unionArrayPointer, const TType& t, const TSourceLoc& line)
|
||||
{
|
||||
TIntermConstantUnion* node = new TIntermConstantUnion(unionArrayPointer, t);
|
||||
node->setLine(line);
|
||||
|
@ -677,7 +661,7 @@ TIntermConstantUnion* TIntermediate::addConstantUnion(ConstantUnion* unionArrayP
|
|||
return node;
|
||||
}
|
||||
|
||||
TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc line)
|
||||
TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, const TSourceLoc& line)
|
||||
{
|
||||
|
||||
TIntermAggregate* node = new TIntermAggregate(EOpSequence);
|
||||
|
@ -700,7 +684,7 @@ TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc line)
|
|||
//
|
||||
// Create loop nodes.
|
||||
//
|
||||
TIntermNode* TIntermediate::addLoop(TLoopType type, TIntermNode* init, TIntermTyped* cond, TIntermTyped* expr, TIntermNode* body, TSourceLoc line)
|
||||
TIntermNode* TIntermediate::addLoop(TLoopType type, TIntermNode* init, TIntermTyped* cond, TIntermTyped* expr, TIntermNode* body, const TSourceLoc& line)
|
||||
{
|
||||
TIntermNode* node = new TIntermLoop(type, init, cond, expr, body);
|
||||
node->setLine(line);
|
||||
|
@ -711,12 +695,12 @@ TIntermNode* TIntermediate::addLoop(TLoopType type, TIntermNode* init, TIntermTy
|
|||
//
|
||||
// Add branches.
|
||||
//
|
||||
TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TSourceLoc line)
|
||||
TIntermBranch* TIntermediate::addBranch(TOperator branchOp, const TSourceLoc& line)
|
||||
{
|
||||
return addBranch(branchOp, 0, line);
|
||||
}
|
||||
|
||||
TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, TSourceLoc line)
|
||||
TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, const TSourceLoc& line)
|
||||
{
|
||||
TIntermBranch* node = new TIntermBranch(branchOp, expression);
|
||||
node->setLine(line);
|
||||
|
@ -861,7 +845,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
|
|||
{
|
||||
// This function only handles scalars, vectors, and matrices.
|
||||
if (left->isArray() || right->isArray()) {
|
||||
infoSink.info.message(EPrefixInternalError, "Invalid operation for arrays", getLine());
|
||||
infoSink.info.message(EPrefixInternalError, getLine(), "Invalid operation for arrays");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -966,7 +950,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
|
|||
setType(TType(basicType, higherPrecision, EvqTemporary, size, false));
|
||||
}
|
||||
} else {
|
||||
infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
|
||||
infoSink.info.message(EPrefixInternalError, getLine(), "Missing elses");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
@ -995,7 +979,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
|
|||
setType(TType(basicType, higherPrecision, EvqTemporary, size, false));
|
||||
}
|
||||
} else {
|
||||
infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
|
||||
infoSink.info.message(EPrefixInternalError, getLine(), "Missing elses");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
@ -1035,23 +1019,22 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
|
|||
|
||||
bool CompareStruct(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray)
|
||||
{
|
||||
const TTypeList* fields = leftNodeType.getStruct();
|
||||
const TFieldList& fields = leftNodeType.getStruct()->fields();
|
||||
|
||||
size_t structSize = fields->size();
|
||||
int index = 0;
|
||||
size_t structSize = fields.size();
|
||||
size_t index = 0;
|
||||
|
||||
for (size_t j = 0; j < structSize; j++) {
|
||||
int size = (*fields)[j].type->getObjectSize();
|
||||
for (int i = 0; i < size; i++) {
|
||||
if ((*fields)[j].type->getBasicType() == EbtStruct) {
|
||||
if (!CompareStructure(*(*fields)[j].type, &rightUnionArray[index], &leftUnionArray[index]))
|
||||
size_t size = fields[j]->type()->getObjectSize();
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
if (fields[j]->type()->getBasicType() == EbtStruct) {
|
||||
if (!CompareStructure(*(fields[j]->type()), &rightUnionArray[index], &leftUnionArray[index]))
|
||||
return false;
|
||||
} else {
|
||||
if (leftUnionArray[index] != rightUnionArray[index])
|
||||
return false;
|
||||
index++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -1063,10 +1046,10 @@ bool CompareStructure(const TType& leftNodeType, ConstantUnion* rightUnionArray,
|
|||
TType typeWithoutArrayness = leftNodeType;
|
||||
typeWithoutArrayness.clearArrayness();
|
||||
|
||||
int arraySize = leftNodeType.getArraySize();
|
||||
size_t arraySize = leftNodeType.getArraySize();
|
||||
|
||||
for (int i = 0; i < arraySize; ++i) {
|
||||
int offset = typeWithoutArrayness.getObjectSize() * i;
|
||||
for (size_t i = 0; i < arraySize; ++i) {
|
||||
size_t offset = typeWithoutArrayness.getObjectSize() * i;
|
||||
if (!CompareStruct(typeWithoutArrayness, &rightUnionArray[offset], &leftUnionArray[offset]))
|
||||
return false;
|
||||
}
|
||||
|
@ -1086,7 +1069,7 @@ bool CompareStructure(const TType& leftNodeType, ConstantUnion* rightUnionArray,
|
|||
TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNode, TInfoSink& infoSink)
|
||||
{
|
||||
ConstantUnion *unionArray = getUnionArrayPointer();
|
||||
int objectSize = getType().getObjectSize();
|
||||
size_t objectSize = getType().getObjectSize();
|
||||
|
||||
if (constantNode) { // binary operations
|
||||
TIntermConstantUnion *node = constantNode->getAsConstantUnion();
|
||||
|
@ -1096,13 +1079,13 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
|
|||
// for a case like float f = 1.2 + vec4(2,3,4,5);
|
||||
if (constantNode->getType().getObjectSize() == 1 && objectSize > 1) {
|
||||
rightUnionArray = new ConstantUnion[objectSize];
|
||||
for (int i = 0; i < objectSize; ++i)
|
||||
for (size_t i = 0; i < objectSize; ++i)
|
||||
rightUnionArray[i] = *node->getUnionArrayPointer();
|
||||
returnType = getType();
|
||||
} else if (constantNode->getType().getObjectSize() > 1 && objectSize == 1) {
|
||||
// for a case like float f = vec4(2,3,4,5) + 1.2;
|
||||
unionArray = new ConstantUnion[constantNode->getType().getObjectSize()];
|
||||
for (int i = 0; i < constantNode->getType().getObjectSize(); ++i)
|
||||
for (size_t i = 0; i < constantNode->getType().getObjectSize(); ++i)
|
||||
unionArray[i] = *getUnionArrayPointer();
|
||||
returnType = node->getType();
|
||||
objectSize = constantNode->getType().getObjectSize();
|
||||
|
@ -1116,14 +1099,14 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
|
|||
case EOpAdd:
|
||||
tempConstArray = new ConstantUnion[objectSize];
|
||||
{// support MSVC++6.0
|
||||
for (int i = 0; i < objectSize; i++)
|
||||
for (size_t i = 0; i < objectSize; i++)
|
||||
tempConstArray[i] = unionArray[i] + rightUnionArray[i];
|
||||
}
|
||||
break;
|
||||
case EOpSub:
|
||||
tempConstArray = new ConstantUnion[objectSize];
|
||||
{// support MSVC++6.0
|
||||
for (int i = 0; i < objectSize; i++)
|
||||
for (size_t i = 0; i < objectSize; i++)
|
||||
tempConstArray[i] = unionArray[i] - rightUnionArray[i];
|
||||
}
|
||||
break;
|
||||
|
@ -1133,13 +1116,13 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
|
|||
case EOpMatrixTimesScalar:
|
||||
tempConstArray = new ConstantUnion[objectSize];
|
||||
{// support MSVC++6.0
|
||||
for (int i = 0; i < objectSize; i++)
|
||||
for (size_t i = 0; i < objectSize; i++)
|
||||
tempConstArray[i] = unionArray[i] * rightUnionArray[i];
|
||||
}
|
||||
break;
|
||||
case EOpMatrixTimesMatrix:
|
||||
if (getType().getBasicType() != EbtFloat || node->getBasicType() != EbtFloat) {
|
||||
infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for matrix multiply", getLine());
|
||||
infoSink.info.message(EPrefixInternalError, getLine(), "Constant Folding cannot be done for matrix multiply");
|
||||
return 0;
|
||||
}
|
||||
{// support MSVC++6.0
|
||||
|
@ -1158,11 +1141,11 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
|
|||
case EOpDiv:
|
||||
tempConstArray = new ConstantUnion[objectSize];
|
||||
{// support MSVC++6.0
|
||||
for (int i = 0; i < objectSize; i++) {
|
||||
for (size_t i = 0; i < objectSize; i++) {
|
||||
switch (getType().getBasicType()) {
|
||||
case EbtFloat:
|
||||
if (rightUnionArray[i] == 0.0f) {
|
||||
infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", getLine());
|
||||
infoSink.info.message(EPrefixWarning, getLine(), "Divide by zero error during constant folding");
|
||||
tempConstArray[i].setFConst(unionArray[i].getFConst() < 0 ? -FLT_MAX : FLT_MAX);
|
||||
} else
|
||||
tempConstArray[i].setFConst(unionArray[i].getFConst() / rightUnionArray[i].getFConst());
|
||||
|
@ -1170,13 +1153,13 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
|
|||
|
||||
case EbtInt:
|
||||
if (rightUnionArray[i] == 0) {
|
||||
infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", getLine());
|
||||
infoSink.info.message(EPrefixWarning, getLine(), "Divide by zero error during constant folding");
|
||||
tempConstArray[i].setIConst(INT_MAX);
|
||||
} else
|
||||
tempConstArray[i].setIConst(unionArray[i].getIConst() / rightUnionArray[i].getIConst());
|
||||
break;
|
||||
default:
|
||||
infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"/\"", getLine());
|
||||
infoSink.info.message(EPrefixInternalError, getLine(), "Constant folding cannot be done for \"/\"");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -1185,7 +1168,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
|
|||
|
||||
case EOpMatrixTimesVector:
|
||||
if (node->getBasicType() != EbtFloat) {
|
||||
infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for matrix times vector", getLine());
|
||||
infoSink.info.message(EPrefixInternalError, getLine(), "Constant Folding cannot be done for matrix times vector");
|
||||
return 0;
|
||||
}
|
||||
tempConstArray = new ConstantUnion[getNominalSize()];
|
||||
|
@ -1206,7 +1189,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
|
|||
|
||||
case EOpVectorTimesMatrix:
|
||||
if (getType().getBasicType() != EbtFloat) {
|
||||
infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for vector times matrix", getLine());
|
||||
infoSink.info.message(EPrefixInternalError, getLine(), "Constant Folding cannot be done for vector times matrix");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1224,7 +1207,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
|
|||
case EOpLogicalAnd: // this code is written for possible future use, will not get executed currently
|
||||
tempConstArray = new ConstantUnion[objectSize];
|
||||
{// support MSVC++6.0
|
||||
for (int i = 0; i < objectSize; i++)
|
||||
for (size_t i = 0; i < objectSize; i++)
|
||||
tempConstArray[i] = unionArray[i] && rightUnionArray[i];
|
||||
}
|
||||
break;
|
||||
|
@ -1232,7 +1215,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
|
|||
case EOpLogicalOr: // this code is written for possible future use, will not get executed currently
|
||||
tempConstArray = new ConstantUnion[objectSize];
|
||||
{// support MSVC++6.0
|
||||
for (int i = 0; i < objectSize; i++)
|
||||
for (size_t i = 0; i < objectSize; i++)
|
||||
tempConstArray[i] = unionArray[i] || rightUnionArray[i];
|
||||
}
|
||||
break;
|
||||
|
@ -1240,7 +1223,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
|
|||
case EOpLogicalXor:
|
||||
tempConstArray = new ConstantUnion[objectSize];
|
||||
{// support MSVC++6.0
|
||||
for (int i = 0; i < objectSize; i++)
|
||||
for (size_t i = 0; i < objectSize; i++)
|
||||
switch (getType().getBasicType()) {
|
||||
case EbtBool: tempConstArray[i].setBConst((unionArray[i] == rightUnionArray[i]) ? false : true); break;
|
||||
default: assert(false && "Default missing");
|
||||
|
@ -1286,7 +1269,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
|
|||
if (!CompareStructure(node->getType(), node->getUnionArrayPointer(), unionArray))
|
||||
boolNodeFlag = true;
|
||||
} else {
|
||||
for (int i = 0; i < objectSize; i++) {
|
||||
for (size_t i = 0; i < objectSize; i++) {
|
||||
if (unionArray[i] != rightUnionArray[i]) {
|
||||
boolNodeFlag = true;
|
||||
break; // break out of for loop
|
||||
|
@ -1312,7 +1295,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
|
|||
if (CompareStructure(node->getType(), node->getUnionArrayPointer(), unionArray))
|
||||
boolNodeFlag = true;
|
||||
} else {
|
||||
for (int i = 0; i < objectSize; i++) {
|
||||
for (size_t i = 0; i < objectSize; i++) {
|
||||
if (unionArray[i] == rightUnionArray[i]) {
|
||||
boolNodeFlag = true;
|
||||
break; // break out of for loop
|
||||
|
@ -1334,7 +1317,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
|
|||
return tempNode;
|
||||
|
||||
default:
|
||||
infoSink.info.message(EPrefixInternalError, "Invalid operator for constant folding", getLine());
|
||||
infoSink.info.message(EPrefixInternalError, getLine(), "Invalid operator for constant folding");
|
||||
return 0;
|
||||
}
|
||||
tempNode = new TIntermConstantUnion(tempConstArray, returnType);
|
||||
|
@ -1347,14 +1330,14 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
|
|||
//
|
||||
TIntermConstantUnion *newNode = 0;
|
||||
ConstantUnion* tempConstArray = new ConstantUnion[objectSize];
|
||||
for (int i = 0; i < objectSize; i++) {
|
||||
for (size_t i = 0; i < objectSize; i++) {
|
||||
switch(op) {
|
||||
case EOpNegative:
|
||||
switch (getType().getBasicType()) {
|
||||
case EbtFloat: tempConstArray[i].setFConst(-unionArray[i].getFConst()); break;
|
||||
case EbtInt: tempConstArray[i].setIConst(-unionArray[i].getIConst()); break;
|
||||
default:
|
||||
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
|
||||
infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
@ -1362,7 +1345,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
|
|||
switch (getType().getBasicType()) {
|
||||
case EbtBool: tempConstArray[i].setBConst(!unionArray[i].getBConst()); break;
|
||||
default:
|
||||
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
|
||||
infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
@ -1378,11 +1361,11 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
|
|||
|
||||
TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node)
|
||||
{
|
||||
int size = node->getType().getObjectSize();
|
||||
size_t size = node->getType().getObjectSize();
|
||||
|
||||
ConstantUnion *leftUnionArray = new ConstantUnion[size];
|
||||
|
||||
for (int i=0; i < size; i++) {
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
|
||||
switch (promoteTo) {
|
||||
case EbtFloat:
|
||||
|
@ -1397,7 +1380,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
|
|||
leftUnionArray[i].setFConst(static_cast<float>(node->getFConst(i)));
|
||||
break;
|
||||
default:
|
||||
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
|
||||
infoSink.info.message(EPrefixInternalError, node->getLine(), "Cannot promote");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
@ -1413,7 +1396,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
|
|||
leftUnionArray[i].setIConst(static_cast<int>(node->getFConst(i)));
|
||||
break;
|
||||
default:
|
||||
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
|
||||
infoSink.info.message(EPrefixInternalError, node->getLine(), "Cannot promote");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
@ -1429,13 +1412,13 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
|
|||
leftUnionArray[i].setBConst(node->getFConst(i) != 0.0f);
|
||||
break;
|
||||
default:
|
||||
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
|
||||
infoSink.info.message(EPrefixInternalError, node->getLine(), "Cannot promote");
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
infoSink.info.message(EPrefixInternalError, "Incorrect data type found", node->getLine());
|
||||
infoSink.info.message(EPrefixInternalError, node->getLine(), "Incorrect data type found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
//
|
||||
|
||||
#include "compiler/MapLongVariableNames.h"
|
||||
#include "spooky.h"
|
||||
|
||||
#include "third_party/murmurhash/MurmurHash3.h"
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -13,7 +14,9 @@ TString mapLongName(size_t id, const TString& name, bool isGlobal)
|
|||
{
|
||||
ASSERT(name.size() > MAX_SHORTENED_IDENTIFIER_SIZE);
|
||||
TStringStream stream;
|
||||
uint64 hash = SpookyHash::Hash64(name.data(), name.length(), 0);
|
||||
|
||||
uint64_t hash[2] = {0, 0};
|
||||
MurmurHash3_x64_128(name.data(), name.length(), 0, hash);
|
||||
|
||||
// We want to avoid producing a string with a double underscore,
|
||||
// which would be an illegal GLSL identifier. We can assume that the
|
||||
|
@ -23,7 +26,7 @@ TString mapLongName(size_t id, const TString& name, bool isGlobal)
|
|||
<< name.substr(0, 9)
|
||||
<< (name[8] == '_' ? "" : "_")
|
||||
<< std::hex
|
||||
<< hash;
|
||||
<< hash[0];
|
||||
ASSERT(stream.str().length() <= MAX_SHORTENED_IDENTIFIER_SIZE);
|
||||
ASSERT(stream.str().length() >= MAX_SHORTENED_IDENTIFIER_SIZE - 2);
|
||||
return stream.str();
|
||||
|
|
|
@ -19,3 +19,17 @@ bool TOutputGLSL::writeVariablePrecision(TPrecision)
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void TOutputGLSL::visitSymbol(TIntermSymbol* node)
|
||||
{
|
||||
TInfoSinkBase& out = objSink();
|
||||
|
||||
if (node->getSymbol() == "gl_FragDepthEXT")
|
||||
{
|
||||
out << "gl_FragDepth";
|
||||
}
|
||||
else
|
||||
{
|
||||
TOutputGLSLBase::visitSymbol(node);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ public:
|
|||
|
||||
protected:
|
||||
virtual bool writeVariablePrecision(TPrecision);
|
||||
virtual void visitSymbol(TIntermSymbol* node);
|
||||
};
|
||||
|
||||
#endif // CROSSCOMPILERGLSL_OUTPUTGLSL_H_
|
||||
|
|
|
@ -79,25 +79,9 @@ void TOutputGLSLBase::writeVariableType(const TType& type)
|
|||
if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal))
|
||||
out << type.getQualifierString() << " ";
|
||||
// Declare the struct if we have not done so already.
|
||||
if ((type.getBasicType() == EbtStruct) &&
|
||||
(mDeclaredStructs.find(type.getTypeName()) == mDeclaredStructs.end()))
|
||||
if ((type.getBasicType() == EbtStruct) && !structDeclared(type.getStruct()))
|
||||
{
|
||||
out << "struct " << hashName(type.getTypeName()) << "{\n";
|
||||
const TTypeList* structure = type.getStruct();
|
||||
ASSERT(structure != NULL);
|
||||
for (size_t i = 0; i < structure->size(); ++i)
|
||||
{
|
||||
const TType* fieldType = (*structure)[i].type;
|
||||
ASSERT(fieldType != NULL);
|
||||
if (writeVariablePrecision(fieldType->getPrecision()))
|
||||
out << " ";
|
||||
out << getTypeName(*fieldType) << " " << hashName(fieldType->getFieldName());
|
||||
if (fieldType->isArray())
|
||||
out << arrayBrackets(*fieldType);
|
||||
out << ";\n";
|
||||
}
|
||||
out << "}";
|
||||
mDeclaredStructs.insert(type.getTypeName());
|
||||
declareStruct(type.getStruct());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -138,24 +122,25 @@ const ConstantUnion* TOutputGLSLBase::writeConstantUnion(const TType& type,
|
|||
|
||||
if (type.getBasicType() == EbtStruct)
|
||||
{
|
||||
out << hashName(type.getTypeName()) << "(";
|
||||
const TTypeList* structure = type.getStruct();
|
||||
ASSERT(structure != NULL);
|
||||
for (size_t i = 0; i < structure->size(); ++i)
|
||||
const TStructure* structure = type.getStruct();
|
||||
out << hashName(structure->name()) << "(";
|
||||
|
||||
const TFieldList& fields = structure->fields();
|
||||
for (size_t i = 0; i < fields.size(); ++i)
|
||||
{
|
||||
const TType* fieldType = (*structure)[i].type;
|
||||
const TType* fieldType = fields[i]->type();
|
||||
ASSERT(fieldType != NULL);
|
||||
pConstUnion = writeConstantUnion(*fieldType, pConstUnion);
|
||||
if (i != structure->size() - 1) out << ", ";
|
||||
if (i != fields.size() - 1) out << ", ";
|
||||
}
|
||||
out << ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
int size = type.getObjectSize();
|
||||
size_t size = type.getObjectSize();
|
||||
bool writeType = size > 1;
|
||||
if (writeType) out << getTypeName(type) << "(";
|
||||
for (int i = 0; i < size; ++i, ++pConstUnion)
|
||||
for (size_t i = 0; i < size; ++i, ++pConstUnion)
|
||||
{
|
||||
switch (pConstUnion->getType())
|
||||
{
|
||||
|
@ -260,12 +245,18 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary* node)
|
|||
case EOpIndexDirectStruct:
|
||||
if (visit == InVisit)
|
||||
{
|
||||
// Here we are writing out "foo.bar", where "foo" is struct
|
||||
// and "bar" is field. In AST, it is represented as a binary
|
||||
// node, where left child represents "foo" and right child "bar".
|
||||
// The node itself represents ".". The struct field "bar" is
|
||||
// actually stored as an index into TStructure::fields.
|
||||
out << ".";
|
||||
// TODO(alokp): ASSERT
|
||||
TString fieldName = node->getType().getFieldName();
|
||||
const TStructure* structure = node->getLeft()->getType().getStruct();
|
||||
const TIntermConstantUnion* index = node->getRight()->getAsConstantUnion();
|
||||
const TField* field = structure->fields()[index->getIConst(0)];
|
||||
|
||||
const TType& structType = node->getLeft()->getType();
|
||||
if (!mSymbolTable.findBuiltIn(structType.getTypeName()))
|
||||
TString fieldName = field->name();
|
||||
if (!mSymbolTable.findBuiltIn(structure->name()))
|
||||
fieldName = hashName(fieldName);
|
||||
|
||||
out << fieldName;
|
||||
|
@ -596,7 +587,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate* node)
|
|||
{
|
||||
const TType& type = node->getType();
|
||||
ASSERT(type.getBasicType() == EbtStruct);
|
||||
out << hashName(type.getTypeName()) << "(";
|
||||
out << hashName(type.getStruct()->name()) << "(";
|
||||
}
|
||||
else if (visit == InVisit)
|
||||
{
|
||||
|
@ -765,7 +756,7 @@ TString TOutputGLSLBase::getTypeName(const TType& type)
|
|||
else
|
||||
{
|
||||
if (type.getBasicType() == EbtStruct)
|
||||
out << hashName(type.getTypeName());
|
||||
out << hashName(type.getStruct()->name());
|
||||
else
|
||||
out << type.getBasicString();
|
||||
}
|
||||
|
@ -798,3 +789,29 @@ TString TOutputGLSLBase::hashFunctionName(const TString& mangled_name)
|
|||
return name;
|
||||
return hashName(name);
|
||||
}
|
||||
|
||||
bool TOutputGLSLBase::structDeclared(const TStructure* structure) const
|
||||
{
|
||||
return mDeclaredStructs.find(structure->name()) != mDeclaredStructs.end();
|
||||
}
|
||||
|
||||
void TOutputGLSLBase::declareStruct(const TStructure* structure)
|
||||
{
|
||||
TInfoSinkBase& out = objSink();
|
||||
|
||||
out << "struct " << hashName(structure->name()) << "{\n";
|
||||
const TFieldList& fields = structure->fields();
|
||||
for (size_t i = 0; i < fields.size(); ++i)
|
||||
{
|
||||
const TField* field = fields[i];
|
||||
if (writeVariablePrecision(field->type()->getPrecision()))
|
||||
out << " ";
|
||||
out << getTypeName(*field->type()) << " " << hashName(field->name());
|
||||
if (field->type()->isArray())
|
||||
out << arrayBrackets(*field->type());
|
||||
out << ";\n";
|
||||
}
|
||||
out << "}";
|
||||
|
||||
mDeclaredStructs.insert(structure->name());
|
||||
}
|
||||
|
|
|
@ -52,6 +52,9 @@ protected:
|
|||
TString hashFunctionName(const TString& mangled_name);
|
||||
|
||||
private:
|
||||
bool structDeclared(const TStructure* structure) const;
|
||||
void declareStruct(const TStructure* structure);
|
||||
|
||||
TInfoSinkBase& mObjSink;
|
||||
bool mDeclaringVariables;
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
|
||||
// Copyright (c) 2002-2013 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.
|
||||
//
|
||||
|
@ -9,9 +9,14 @@
|
|||
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
#define GL_APICALL
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
#include "compiler/intermediate.h"
|
||||
#include "compiler/ParseHelper.h"
|
||||
#include "compiler/CompilerUniform.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
@ -20,14 +25,16 @@ class UnfoldShortCircuit;
|
|||
class OutputHLSL : public TIntermTraverser
|
||||
{
|
||||
public:
|
||||
explicit OutputHLSL(TParseContext &context);
|
||||
OutputHLSL(TParseContext &context, const ShBuiltInResources& resources, ShShaderOutput outputType);
|
||||
~OutputHLSL();
|
||||
|
||||
void output();
|
||||
|
||||
TInfoSinkBase &getBodyStream();
|
||||
const ActiveUniforms &getUniforms();
|
||||
|
||||
TString typeString(const TType &type);
|
||||
TString textureString(const TType &type);
|
||||
static TString qualifierString(TQualifier qualifier);
|
||||
static TString arrayString(const TType &type);
|
||||
static TString initializer(const TType &type);
|
||||
|
@ -64,6 +71,7 @@ class OutputHLSL : public TIntermTraverser
|
|||
TString structLookup(const TString &typeName);
|
||||
|
||||
TParseContext &mContext;
|
||||
const ShShaderOutput mOutputType;
|
||||
UnfoldShortCircuit *mUnfoldShortCircuit;
|
||||
bool mInsideFunction;
|
||||
|
||||
|
@ -72,9 +80,10 @@ class OutputHLSL : public TIntermTraverser
|
|||
TInfoSinkBase mBody;
|
||||
TInfoSinkBase mFooter;
|
||||
|
||||
std::set<std::string> mReferencedUniforms;
|
||||
std::set<std::string> mReferencedAttributes;
|
||||
std::set<std::string> mReferencedVaryings;
|
||||
typedef std::map<TString, TIntermSymbol*> ReferencedSymbols;
|
||||
ReferencedSymbols mReferencedUniforms;
|
||||
ReferencedSymbols mReferencedAttributes;
|
||||
ReferencedSymbols mReferencedVaryings;
|
||||
|
||||
// Parameters determining what goes in the header output
|
||||
bool mUsesTexture2D;
|
||||
|
@ -92,11 +101,14 @@ class OutputHLSL : public TIntermTraverser
|
|||
bool mUsesTexture2DProjLod0_bias;
|
||||
bool mUsesTextureCubeLod0;
|
||||
bool mUsesTextureCubeLod0_bias;
|
||||
bool mUsesFragColor;
|
||||
bool mUsesFragData;
|
||||
bool mUsesDepthRange;
|
||||
bool mUsesFragCoord;
|
||||
bool mUsesPointCoord;
|
||||
bool mUsesFrontFacing;
|
||||
bool mUsesPointSize;
|
||||
bool mUsesFragDepth;
|
||||
bool mUsesXor;
|
||||
bool mUsesMod1;
|
||||
bool mUsesMod2v;
|
||||
|
@ -109,23 +121,13 @@ class OutputHLSL : public TIntermTraverser
|
|||
bool mUsesFaceforward2;
|
||||
bool mUsesFaceforward3;
|
||||
bool mUsesFaceforward4;
|
||||
bool mUsesEqualMat2;
|
||||
bool mUsesEqualMat3;
|
||||
bool mUsesEqualMat4;
|
||||
bool mUsesEqualVec2;
|
||||
bool mUsesEqualVec3;
|
||||
bool mUsesEqualVec4;
|
||||
bool mUsesEqualIVec2;
|
||||
bool mUsesEqualIVec3;
|
||||
bool mUsesEqualIVec4;
|
||||
bool mUsesEqualBVec2;
|
||||
bool mUsesEqualBVec3;
|
||||
bool mUsesEqualBVec4;
|
||||
bool mUsesAtan2_1;
|
||||
bool mUsesAtan2_2;
|
||||
bool mUsesAtan2_3;
|
||||
bool mUsesAtan2_4;
|
||||
|
||||
int mNumRenderTargets;
|
||||
|
||||
typedef std::set<TString> Constructors;
|
||||
Constructors mConstructors;
|
||||
|
||||
|
@ -146,6 +148,18 @@ class OutputHLSL : public TIntermTraverser
|
|||
bool mInsideDiscontinuousLoop;
|
||||
|
||||
TIntermSymbol *mExcessiveLoopIndex;
|
||||
|
||||
int mUniformRegister;
|
||||
int mSamplerRegister;
|
||||
|
||||
TString registerString(TIntermSymbol *operand);
|
||||
int samplerRegister(TIntermSymbol *sampler);
|
||||
int uniformRegister(TIntermSymbol *uniform);
|
||||
void declareUniform(const TType &type, const TString &name, int index);
|
||||
static GLenum glVariableType(const TType &type);
|
||||
static GLenum glVariablePrecision(const TType &type);
|
||||
|
||||
ActiveUniforms mActiveUniforms;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
// Look at a '.' field selector string and change it into offsets
|
||||
// for a vector.
|
||||
//
|
||||
bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TVectorFields& fields, int line)
|
||||
bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TVectorFields& fields, const TSourceLoc& line)
|
||||
{
|
||||
fields.num = (int) compString.size();
|
||||
if (fields.num > 4) {
|
||||
|
@ -115,7 +115,7 @@ bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TV
|
|||
// Look at a '.' field selector string and change it into offsets
|
||||
// for a matrix.
|
||||
//
|
||||
bool TParseContext::parseMatrixFields(const TString& compString, int matSize, TMatrixFields& fields, int line)
|
||||
bool TParseContext::parseMatrixFields(const TString& compString, int matSize, TMatrixFields& fields, const TSourceLoc& line)
|
||||
{
|
||||
fields.wholeRow = false;
|
||||
fields.wholeCol = false;
|
||||
|
@ -175,22 +175,24 @@ void TParseContext::recover()
|
|||
//
|
||||
// Used by flex/bison to output all syntax and parsing errors.
|
||||
//
|
||||
void TParseContext::error(TSourceLoc loc,
|
||||
void TParseContext::error(const TSourceLoc& loc,
|
||||
const char* reason, const char* token,
|
||||
const char* extraInfo)
|
||||
{
|
||||
pp::SourceLocation srcLoc;
|
||||
DecodeSourceLoc(loc, &srcLoc.file, &srcLoc.line);
|
||||
srcLoc.file = loc.first_file;
|
||||
srcLoc.line = loc.first_line;
|
||||
diagnostics.writeInfo(pp::Diagnostics::ERROR,
|
||||
srcLoc, reason, token, extraInfo);
|
||||
|
||||
}
|
||||
|
||||
void TParseContext::warning(TSourceLoc loc,
|
||||
void TParseContext::warning(const TSourceLoc& loc,
|
||||
const char* reason, const char* token,
|
||||
const char* extraInfo) {
|
||||
pp::SourceLocation srcLoc;
|
||||
DecodeSourceLoc(loc, &srcLoc.file, &srcLoc.line);
|
||||
srcLoc.file = loc.first_file;
|
||||
srcLoc.line = loc.first_line;
|
||||
diagnostics.writeInfo(pp::Diagnostics::WARNING,
|
||||
srcLoc, reason, token, extraInfo);
|
||||
}
|
||||
|
@ -203,7 +205,7 @@ void TParseContext::trace(const char* str)
|
|||
//
|
||||
// Same error message for all places assignments don't work.
|
||||
//
|
||||
void TParseContext::assignError(int line, const char* op, TString left, TString right)
|
||||
void TParseContext::assignError(const TSourceLoc& line, const char* op, TString left, TString right)
|
||||
{
|
||||
std::stringstream extraInfoStream;
|
||||
extraInfoStream << "cannot convert from '" << right << "' to '" << left << "'";
|
||||
|
@ -214,7 +216,7 @@ void TParseContext::assignError(int line, const char* op, TString left, TString
|
|||
//
|
||||
// Same error message for all places unary operations don't work.
|
||||
//
|
||||
void TParseContext::unaryOpError(int line, const char* op, TString operand)
|
||||
void TParseContext::unaryOpError(const TSourceLoc& line, const char* op, TString operand)
|
||||
{
|
||||
std::stringstream extraInfoStream;
|
||||
extraInfoStream << "no operation '" << op << "' exists that takes an operand of type " << operand
|
||||
|
@ -226,7 +228,7 @@ void TParseContext::unaryOpError(int line, const char* op, TString operand)
|
|||
//
|
||||
// Same error message for all binary operations don't work.
|
||||
//
|
||||
void TParseContext::binaryOpError(int line, const char* op, TString left, TString right)
|
||||
void TParseContext::binaryOpError(const TSourceLoc& line, const char* op, TString left, TString right)
|
||||
{
|
||||
std::stringstream extraInfoStream;
|
||||
extraInfoStream << "no operation '" << op << "' exists that takes a left-hand operand of type '" << left
|
||||
|
@ -235,7 +237,7 @@ void TParseContext::binaryOpError(int line, const char* op, TString left, TStrin
|
|||
error(line, " wrong operand types ", op, extraInfo.c_str());
|
||||
}
|
||||
|
||||
bool TParseContext::precisionErrorCheck(int line, TPrecision precision, TBasicType type){
|
||||
bool TParseContext::precisionErrorCheck(const TSourceLoc& line, TPrecision precision, TBasicType type){
|
||||
if (!checksPrecisionErrors)
|
||||
return false;
|
||||
switch( type ){
|
||||
|
@ -263,7 +265,7 @@ bool TParseContext::precisionErrorCheck(int line, TPrecision precision, TBasicTy
|
|||
//
|
||||
// Returns true if the was an error.
|
||||
//
|
||||
bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* node)
|
||||
bool TParseContext::lValueErrorCheck(const TSourceLoc& line, const char* op, TIntermTyped* node)
|
||||
{
|
||||
TIntermSymbol* symNode = node->getAsSymbolNode();
|
||||
TIntermBinary* binaryNode = node->getAsBinaryNode();
|
||||
|
@ -317,7 +319,6 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod
|
|||
case EvqAttribute: message = "can't modify an attribute"; break;
|
||||
case EvqUniform: message = "can't modify a uniform"; break;
|
||||
case EvqVaryingIn: message = "can't modify a varying"; break;
|
||||
case EvqInput: message = "can't modify an input"; break;
|
||||
case EvqFragCoord: message = "can't modify gl_FragCoord"; break;
|
||||
case EvqFrontFacing: message = "can't modify gl_FrontFacing"; break;
|
||||
case EvqPointCoord: message = "can't modify gl_PointCoord"; break;
|
||||
|
@ -409,7 +410,7 @@ bool TParseContext::integerErrorCheck(TIntermTyped* node, const char* token)
|
|||
//
|
||||
// Returns true if the was an error.
|
||||
//
|
||||
bool TParseContext::globalErrorCheck(int line, bool global, const char* token)
|
||||
bool TParseContext::globalErrorCheck(const TSourceLoc& line, bool global, const char* token)
|
||||
{
|
||||
if (global)
|
||||
return false;
|
||||
|
@ -428,7 +429,7 @@ bool TParseContext::globalErrorCheck(int line, bool global, const char* token)
|
|||
//
|
||||
// Returns true if there was an error.
|
||||
//
|
||||
bool TParseContext::reservedErrorCheck(int line, const TString& identifier)
|
||||
bool TParseContext::reservedErrorCheck(const TSourceLoc& line, const TString& identifier)
|
||||
{
|
||||
static const char* reservedErrMsg = "reserved built-in name";
|
||||
if (!symbolTable.atBuiltInLevel()) {
|
||||
|
@ -466,7 +467,7 @@ bool TParseContext::reservedErrorCheck(int line, const TString& identifier)
|
|||
//
|
||||
// Returns true if there was an error in construction.
|
||||
//
|
||||
bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction& function, TOperator op, TType* type)
|
||||
bool TParseContext::constructorErrorCheck(const TSourceLoc& line, TIntermNode* node, TFunction& function, TOperator op, TType* type)
|
||||
{
|
||||
*type = function.getReturnType();
|
||||
|
||||
|
@ -487,7 +488,7 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction
|
|||
// again, there is an extra argument, so 'overfull' will become true.
|
||||
//
|
||||
|
||||
int size = 0;
|
||||
size_t size = 0;
|
||||
bool constType = true;
|
||||
bool full = false;
|
||||
bool overFull = false;
|
||||
|
@ -534,7 +535,7 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction
|
|||
return true;
|
||||
}
|
||||
|
||||
if (op == EOpConstructStruct && !type->isArray() && int(type->getStruct()->size()) != function.getParamCount()) {
|
||||
if (op == EOpConstructStruct && !type->isArray() && int(type->getStruct()->fields().size()) != function.getParamCount()) {
|
||||
error(line, "Number of constructor parameters does not match the number of structure fields", "constructor");
|
||||
return true;
|
||||
}
|
||||
|
@ -568,7 +569,7 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction
|
|||
//
|
||||
// returns true in case of an error
|
||||
//
|
||||
bool TParseContext::voidErrorCheck(int line, const TString& identifier, const TPublicType& pubType)
|
||||
bool TParseContext::voidErrorCheck(const TSourceLoc& line, const TString& identifier, const TPublicType& pubType)
|
||||
{
|
||||
if (pubType.type == EbtVoid) {
|
||||
error(line, "illegal use of type 'void'", identifier.c_str());
|
||||
|
@ -582,7 +583,7 @@ bool TParseContext::voidErrorCheck(int line, const TString& identifier, const TP
|
|||
//
|
||||
// returns true in case of an error
|
||||
//
|
||||
bool TParseContext::boolErrorCheck(int line, const TIntermTyped* type)
|
||||
bool TParseContext::boolErrorCheck(const TSourceLoc& line, const TIntermTyped* type)
|
||||
{
|
||||
if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) {
|
||||
error(line, "boolean expression expected", "");
|
||||
|
@ -596,7 +597,7 @@ bool TParseContext::boolErrorCheck(int line, const TIntermTyped* type)
|
|||
//
|
||||
// returns true in case of an error
|
||||
//
|
||||
bool TParseContext::boolErrorCheck(int line, const TPublicType& pType)
|
||||
bool TParseContext::boolErrorCheck(const TSourceLoc& line, const TPublicType& pType)
|
||||
{
|
||||
if (pType.type != EbtBool || pType.array || pType.matrix || (pType.size > 1)) {
|
||||
error(line, "boolean expression expected", "");
|
||||
|
@ -606,7 +607,7 @@ bool TParseContext::boolErrorCheck(int line, const TPublicType& pType)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const char* reason)
|
||||
bool TParseContext::samplerErrorCheck(const TSourceLoc& line, const TPublicType& pType, const char* reason)
|
||||
{
|
||||
if (pType.type == EbtStruct) {
|
||||
if (containsSampler(*pType.userDef)) {
|
||||
|
@ -625,7 +626,7 @@ bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const
|
|||
return false;
|
||||
}
|
||||
|
||||
bool TParseContext::structQualifierErrorCheck(int line, const TPublicType& pType)
|
||||
bool TParseContext::structQualifierErrorCheck(const TSourceLoc& line, const TPublicType& pType)
|
||||
{
|
||||
if ((pType.qualifier == EvqVaryingIn || pType.qualifier == EvqVaryingOut || pType.qualifier == EvqAttribute) &&
|
||||
pType.type == EbtStruct) {
|
||||
|
@ -640,7 +641,7 @@ bool TParseContext::structQualifierErrorCheck(int line, const TPublicType& pType
|
|||
return false;
|
||||
}
|
||||
|
||||
bool TParseContext::parameterSamplerErrorCheck(int line, TQualifier qualifier, const TType& type)
|
||||
bool TParseContext::parameterSamplerErrorCheck(const TSourceLoc& line, TQualifier qualifier, const TType& type)
|
||||
{
|
||||
if ((qualifier == EvqOut || qualifier == EvqInOut) &&
|
||||
type.getBasicType() != EbtStruct && IsSampler(type.getBasicType())) {
|
||||
|
@ -657,9 +658,9 @@ bool TParseContext::containsSampler(TType& type)
|
|||
return true;
|
||||
|
||||
if (type.getBasicType() == EbtStruct) {
|
||||
TTypeList& structure = *type.getStruct();
|
||||
for (unsigned int i = 0; i < structure.size(); ++i) {
|
||||
if (containsSampler(*structure[i].type))
|
||||
const TFieldList& fields = type.getStruct()->fields();
|
||||
for (unsigned int i = 0; i < fields.size(); ++i) {
|
||||
if (containsSampler(*fields[i]->type()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -672,7 +673,7 @@ bool TParseContext::containsSampler(TType& type)
|
|||
//
|
||||
// Returns true if there was an error.
|
||||
//
|
||||
bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size)
|
||||
bool TParseContext::arraySizeErrorCheck(const TSourceLoc& line, TIntermTyped* expr, int& size)
|
||||
{
|
||||
TIntermConstantUnion* constant = expr->getAsConstantUnion();
|
||||
if (constant == 0 || constant->getBasicType() != EbtInt) {
|
||||
|
@ -696,7 +697,7 @@ bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size)
|
|||
//
|
||||
// Returns true if there is an error.
|
||||
//
|
||||
bool TParseContext::arrayQualifierErrorCheck(int line, TPublicType type)
|
||||
bool TParseContext::arrayQualifierErrorCheck(const TSourceLoc& line, TPublicType type)
|
||||
{
|
||||
if ((type.qualifier == EvqAttribute) || (type.qualifier == EvqConst)) {
|
||||
error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str());
|
||||
|
@ -711,7 +712,7 @@ bool TParseContext::arrayQualifierErrorCheck(int line, TPublicType type)
|
|||
//
|
||||
// Returns true if there is an error.
|
||||
//
|
||||
bool TParseContext::arrayTypeErrorCheck(int line, TPublicType type)
|
||||
bool TParseContext::arrayTypeErrorCheck(const TSourceLoc& line, TPublicType type)
|
||||
{
|
||||
//
|
||||
// Can the type be an array?
|
||||
|
@ -732,7 +733,7 @@ bool TParseContext::arrayTypeErrorCheck(int line, TPublicType type)
|
|||
//
|
||||
// Returns true if there was an error.
|
||||
//
|
||||
bool TParseContext::arrayErrorCheck(int line, TString& identifier, TPublicType type, TVariable*& variable)
|
||||
bool TParseContext::arrayErrorCheck(const TSourceLoc& line, TString& identifier, TPublicType type, TVariable*& variable)
|
||||
{
|
||||
//
|
||||
// Don't check for reserved word use until after we know it's not in the symbol table,
|
||||
|
@ -777,16 +778,6 @@ bool TParseContext::arrayErrorCheck(int line, TString& identifier, TPublicType t
|
|||
return true;
|
||||
}
|
||||
|
||||
TType* t = variable->getArrayInformationType();
|
||||
while (t != 0) {
|
||||
if (t->getMaxArraySize() > type.arraySize) {
|
||||
error(line, "higher index value already used for the array", identifier.c_str());
|
||||
return true;
|
||||
}
|
||||
t->setArraySize(type.arraySize);
|
||||
t = t->getArrayInformationType();
|
||||
}
|
||||
|
||||
if (type.arraySize)
|
||||
variable->getType().setArraySize(type.arraySize);
|
||||
}
|
||||
|
@ -797,56 +788,12 @@ bool TParseContext::arrayErrorCheck(int line, TString& identifier, TPublicType t
|
|||
return false;
|
||||
}
|
||||
|
||||
bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, bool updateFlag, TSourceLoc line)
|
||||
{
|
||||
bool builtIn = false;
|
||||
TSymbol* symbol = symbolTable.find(node->getSymbol(), &builtIn);
|
||||
if (symbol == 0) {
|
||||
error(line, " undeclared identifier", node->getSymbol().c_str());
|
||||
return true;
|
||||
}
|
||||
TVariable* variable = static_cast<TVariable*>(symbol);
|
||||
|
||||
type->setArrayInformationType(variable->getArrayInformationType());
|
||||
variable->updateArrayInformationType(type);
|
||||
|
||||
// special casing to test index value of gl_FragData. If the accessed index is >= gl_MaxDrawBuffers
|
||||
// its an error
|
||||
if (node->getSymbol() == "gl_FragData") {
|
||||
TSymbol* fragData = symbolTable.find("gl_MaxDrawBuffers", &builtIn);
|
||||
ASSERT(fragData);
|
||||
|
||||
int fragDataValue = static_cast<TVariable*>(fragData)->getConstPointer()[0].getIConst();
|
||||
if (fragDataValue <= size) {
|
||||
error(line, "", "[", "gl_FragData can only have a max array size of up to gl_MaxDrawBuffers");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// we dont want to update the maxArraySize when this flag is not set, we just want to include this
|
||||
// node type in the chain of node types so that its updated when a higher maxArraySize comes in.
|
||||
if (!updateFlag)
|
||||
return false;
|
||||
|
||||
size++;
|
||||
variable->getType().setMaxArraySize(size);
|
||||
type->setMaxArraySize(size);
|
||||
TType* tt = type;
|
||||
|
||||
while(tt->getArrayInformationType() != 0) {
|
||||
tt = tt->getArrayInformationType();
|
||||
tt->setMaxArraySize(size);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Enforce non-initializer type/qualifier rules.
|
||||
//
|
||||
// Returns true if there was an error.
|
||||
//
|
||||
bool TParseContext::nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type, bool array)
|
||||
bool TParseContext::nonInitConstErrorCheck(const TSourceLoc& line, TString& identifier, TPublicType& type, bool array)
|
||||
{
|
||||
if (type.qualifier == EvqConst)
|
||||
{
|
||||
|
@ -878,7 +825,7 @@ bool TParseContext::nonInitConstErrorCheck(int line, TString& identifier, TPubli
|
|||
//
|
||||
// Returns true if there was an error.
|
||||
//
|
||||
bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType& type, TVariable*& variable)
|
||||
bool TParseContext::nonInitErrorCheck(const TSourceLoc& line, TString& identifier, TPublicType& type, TVariable*& variable)
|
||||
{
|
||||
if (reservedErrorCheck(line, identifier))
|
||||
recover();
|
||||
|
@ -898,7 +845,7 @@ bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType
|
|||
return false;
|
||||
}
|
||||
|
||||
bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type)
|
||||
bool TParseContext::paramErrorCheck(const TSourceLoc& line, TQualifier qualifier, TQualifier paramQualifier, TType* type)
|
||||
{
|
||||
if (qualifier != EvqConst && qualifier != EvqTemporary) {
|
||||
error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier));
|
||||
|
@ -917,7 +864,7 @@ bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TQualifier p
|
|||
return false;
|
||||
}
|
||||
|
||||
bool TParseContext::extensionErrorCheck(int line, const TString& extension)
|
||||
bool TParseContext::extensionErrorCheck(const TSourceLoc& line, const TString& extension)
|
||||
{
|
||||
const TExtensionBehavior& extBehavior = extensionBehavior();
|
||||
TExtensionBehavior::const_iterator iter = extBehavior.find(extension.c_str());
|
||||
|
@ -945,18 +892,17 @@ bool TParseContext::supportsExtension(const char* extension)
|
|||
return (iter != extbehavior.end());
|
||||
}
|
||||
|
||||
void TParseContext::handleExtensionDirective(int line, const char* extName, const char* behavior)
|
||||
bool TParseContext::isExtensionEnabled(const char* extension) const
|
||||
{
|
||||
pp::SourceLocation loc;
|
||||
DecodeSourceLoc(line, &loc.file, &loc.line);
|
||||
directiveHandler.handleExtension(loc, extName, behavior);
|
||||
}
|
||||
const TExtensionBehavior& extbehavior = extensionBehavior();
|
||||
TExtensionBehavior::const_iterator iter = extbehavior.find(extension);
|
||||
|
||||
void TParseContext::handlePragmaDirective(int line, const char* name, const char* value)
|
||||
{
|
||||
pp::SourceLocation loc;
|
||||
DecodeSourceLoc(line, &loc.file, &loc.line);
|
||||
directiveHandler.handlePragma(loc, name, value);
|
||||
if (iter == extbehavior.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (iter->second == EBhEnable || iter->second == EBhRequire);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -970,12 +916,13 @@ void TParseContext::handlePragmaDirective(int line, const char* name, const char
|
|||
//
|
||||
// Return the function symbol if found, otherwise 0.
|
||||
//
|
||||
const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *builtIn)
|
||||
const TFunction* TParseContext::findFunction(const TSourceLoc& line, TFunction* call, bool *builtIn)
|
||||
{
|
||||
// First find by unmangled name to check whether the function name has been
|
||||
// hidden by a variable name or struct typename.
|
||||
// If a function is found, check for one with a matching argument list.
|
||||
const TSymbol* symbol = symbolTable.find(call->getName(), builtIn);
|
||||
if (symbol == 0) {
|
||||
if (symbol == 0 || symbol->isFunction()) {
|
||||
symbol = symbolTable.find(call->getMangledName(), builtIn);
|
||||
}
|
||||
|
||||
|
@ -996,7 +943,7 @@ const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *bu
|
|||
// Initializers show up in several places in the grammar. Have one set of
|
||||
// code to handle them here.
|
||||
//
|
||||
bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType,
|
||||
bool TParseContext::executeInitializer(const TSourceLoc& line, TString& identifier, TPublicType& pType,
|
||||
TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable)
|
||||
{
|
||||
TType type = TType(pType);
|
||||
|
@ -1048,13 +995,7 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu
|
|||
return true;
|
||||
}
|
||||
if (initializer->getAsConstantUnion()) {
|
||||
ConstantUnion* unionArray = variable->getConstPointer();
|
||||
|
||||
if (type.getObjectSize() == 1 && type.getBasicType() != EbtStruct) {
|
||||
*unionArray = (initializer->getAsConstantUnion()->getUnionArrayPointer())[0];
|
||||
} else {
|
||||
variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer());
|
||||
}
|
||||
variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer());
|
||||
} else if (initializer->getAsSymbolNode()) {
|
||||
const TSymbol* symbol = symbolTable.find(initializer->getAsSymbolNode()->getSymbol());
|
||||
const TVariable* tVar = static_cast<const TVariable*>(symbol);
|
||||
|
@ -1108,16 +1049,16 @@ bool TParseContext::areAllChildConst(TIntermAggregate* aggrNode)
|
|||
//
|
||||
// Returns 0 for an error or the constructed node (aggregate or typed) for no error.
|
||||
//
|
||||
TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type, TOperator op, TFunction* fnCall, TSourceLoc line)
|
||||
TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type, TOperator op, TFunction* fnCall, const TSourceLoc& line)
|
||||
{
|
||||
if (node == 0)
|
||||
return 0;
|
||||
|
||||
TIntermAggregate* aggrNode = node->getAsAggregate();
|
||||
|
||||
TTypeList::const_iterator memberTypes;
|
||||
TFieldList::const_iterator memberFields;
|
||||
if (op == EOpConstructStruct)
|
||||
memberTypes = type->getStruct()->begin();
|
||||
memberFields = type->getStruct()->fields().begin();
|
||||
|
||||
TType elementType = *type;
|
||||
if (type->isArray())
|
||||
|
@ -1139,7 +1080,7 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type
|
|||
if (type->isArray())
|
||||
newNode = constructStruct(node, &elementType, 1, node->getLine(), false);
|
||||
else if (op == EOpConstructStruct)
|
||||
newNode = constructStruct(node, (*memberTypes).type, 1, node->getLine(), false);
|
||||
newNode = constructStruct(node, (*memberFields)->type(), 1, node->getLine(), false);
|
||||
else
|
||||
newNode = constructBuiltIn(type, op, node, node->getLine(), false);
|
||||
|
||||
|
@ -1170,7 +1111,7 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type
|
|||
if (type->isArray())
|
||||
newNode = constructStruct(*p, &elementType, paramCount+1, node->getLine(), true);
|
||||
else if (op == EOpConstructStruct)
|
||||
newNode = constructStruct(*p, (memberTypes[paramCount]).type, paramCount+1, node->getLine(), true);
|
||||
newNode = constructStruct(*p, memberFields[paramCount]->type(), paramCount+1, node->getLine(), true);
|
||||
else
|
||||
newNode = constructBuiltIn(type, op, *p, node->getLine(), true);
|
||||
|
||||
|
@ -1216,7 +1157,7 @@ TIntermTyped* TParseContext::foldConstConstructor(TIntermAggregate* aggrNode, co
|
|||
//
|
||||
// Returns 0 for an error or the constructed node.
|
||||
//
|
||||
TIntermTyped* TParseContext::constructBuiltIn(const TType* type, TOperator op, TIntermNode* node, TSourceLoc line, bool subset)
|
||||
TIntermTyped* TParseContext::constructBuiltIn(const TType* type, TOperator op, TIntermNode* node, const TSourceLoc& line, bool subset)
|
||||
{
|
||||
TIntermTyped* newNode;
|
||||
TOperator basicOp;
|
||||
|
@ -1278,7 +1219,7 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType* type, TOperator op, T
|
|||
//
|
||||
// Returns 0 for an error or the input node itself if the expected and the given parameter types match.
|
||||
//
|
||||
TIntermTyped* TParseContext::constructStruct(TIntermNode* node, TType* type, int paramCount, TSourceLoc line, bool subset)
|
||||
TIntermTyped* TParseContext::constructStruct(TIntermNode* node, TType* type, int paramCount, const TSourceLoc& line, bool subset)
|
||||
{
|
||||
if (*type == node->getAsTyped()->getType()) {
|
||||
if (subset)
|
||||
|
@ -1305,7 +1246,7 @@ TIntermTyped* TParseContext::constructStruct(TIntermNode* node, TType* type, int
|
|||
// node or it could be the intermediate tree representation of accessing fields in a constant structure or column of
|
||||
// a constant matrix.
|
||||
//
|
||||
TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, TSourceLoc line)
|
||||
TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, const TSourceLoc& line)
|
||||
{
|
||||
TIntermTyped* typedNode;
|
||||
TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
|
||||
|
@ -1327,7 +1268,7 @@ TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTy
|
|||
ConstantUnion* constArray = new ConstantUnion[fields.num];
|
||||
|
||||
for (int i = 0; i < fields.num; i++) {
|
||||
if (fields.offsets[i] >= node->getType().getObjectSize()) {
|
||||
if (fields.offsets[i] >= node->getType().getNominalSize()) {
|
||||
std::stringstream extraInfoStream;
|
||||
extraInfoStream << "vector field selection out of range '" << fields.offsets[i] << "'";
|
||||
std::string extraInfo = extraInfoStream.str();
|
||||
|
@ -1349,7 +1290,7 @@ TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTy
|
|||
// to the function could either be a symbol node (m[0] where m is a constant matrix)that represents a
|
||||
// constant matrix or it could be the tree representation of the constant matrix (s.m1[0] where s is a constant structure)
|
||||
//
|
||||
TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, TSourceLoc line)
|
||||
TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, const TSourceLoc& line)
|
||||
{
|
||||
TIntermTyped* typedNode;
|
||||
TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
|
||||
|
@ -1384,7 +1325,7 @@ TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, T
|
|||
// to the function could either be a symbol node (a[0] where a is a constant array)that represents a
|
||||
// constant array or it could be the tree representation of the constant array (s.a1[0] where s is a constant structure)
|
||||
//
|
||||
TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line)
|
||||
TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, const TSourceLoc& line)
|
||||
{
|
||||
TIntermTyped* typedNode;
|
||||
TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
|
||||
|
@ -1400,9 +1341,8 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS
|
|||
index = 0;
|
||||
}
|
||||
|
||||
int arrayElementSize = arrayElementType.getObjectSize();
|
||||
|
||||
if (tempConstantNode) {
|
||||
size_t arrayElementSize = arrayElementType.getObjectSize();
|
||||
ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer();
|
||||
typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), line);
|
||||
} else {
|
||||
|
@ -1421,22 +1361,21 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS
|
|||
// If there is an embedded/nested struct, it appropriately calls addConstStructNested or addConstStructFromAggr
|
||||
// function and returns the parse-tree with the values of the embedded/nested struct.
|
||||
//
|
||||
TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* node, TSourceLoc line)
|
||||
TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* node, const TSourceLoc& line)
|
||||
{
|
||||
const TTypeList* fields = node->getType().getStruct();
|
||||
TIntermTyped *typedNode;
|
||||
int instanceSize = 0;
|
||||
unsigned int index = 0;
|
||||
TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion();
|
||||
const TFieldList& fields = node->getType().getStruct()->fields();
|
||||
|
||||
for ( index = 0; index < fields->size(); ++index) {
|
||||
if ((*fields)[index].type->getFieldName() == identifier) {
|
||||
size_t instanceSize = 0;
|
||||
for (size_t index = 0; index < fields.size(); ++index) {
|
||||
if (fields[index]->name() == identifier) {
|
||||
break;
|
||||
} else {
|
||||
instanceSize += (*fields)[index].type->getObjectSize();
|
||||
instanceSize += fields[index]->type()->getObjectSize();
|
||||
}
|
||||
}
|
||||
|
||||
TIntermTyped* typedNode = 0;
|
||||
TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
|
||||
if (tempConstantNode) {
|
||||
ConstantUnion* constArray = tempConstantNode->getUnionArrayPointer();
|
||||
|
||||
|
@ -1451,7 +1390,7 @@ TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* n
|
|||
return typedNode;
|
||||
}
|
||||
|
||||
bool TParseContext::enterStructDeclaration(int line, const TString& identifier)
|
||||
bool TParseContext::enterStructDeclaration(const TSourceLoc& line, const TString& identifier)
|
||||
{
|
||||
++structNestingLevel;
|
||||
|
||||
|
@ -1477,21 +1416,21 @@ const int kWebGLMaxStructNesting = 4;
|
|||
|
||||
} // namespace
|
||||
|
||||
bool TParseContext::structNestingErrorCheck(TSourceLoc line, const TType& fieldType)
|
||||
bool TParseContext::structNestingErrorCheck(const TSourceLoc& line, const TField& field)
|
||||
{
|
||||
if (!isWebGLBasedSpec(shaderSpec)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fieldType.getBasicType() != EbtStruct) {
|
||||
if (field.type()->getBasicType() != EbtStruct) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We're already inside a structure definition at this point, so add
|
||||
// one to the field's struct nesting.
|
||||
if (1 + fieldType.getDeepestStructNesting() > kWebGLMaxStructNesting) {
|
||||
if (1 + field.type()->getDeepestStructNesting() > kWebGLMaxStructNesting) {
|
||||
std::stringstream extraInfoStream;
|
||||
extraInfoStream << "Reference of struct type " << fieldType.getTypeName()
|
||||
extraInfoStream << "Reference of struct type " << field.name()
|
||||
<< " exceeds maximum struct nesting of " << kWebGLMaxStructNesting;
|
||||
std::string extraInfo = extraInfoStream.str();
|
||||
error(line, "", "", extraInfo.c_str());
|
||||
|
@ -1501,6 +1440,140 @@ bool TParseContext::structNestingErrorCheck(TSourceLoc line, const TType& fieldT
|
|||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Parse an array index expression
|
||||
//
|
||||
TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc& location, TIntermTyped *indexExpression)
|
||||
{
|
||||
TIntermTyped *indexedExpression = NULL;
|
||||
|
||||
if (!baseExpression->isArray() && !baseExpression->isMatrix() && !baseExpression->isVector())
|
||||
{
|
||||
if (baseExpression->getAsSymbolNode())
|
||||
{
|
||||
error(location, " left of '[' is not of type array, matrix, or vector ", baseExpression->getAsSymbolNode()->getSymbol().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
error(location, " left of '[' is not of type array, matrix, or vector ", "expression");
|
||||
}
|
||||
recover();
|
||||
}
|
||||
|
||||
if (indexExpression->getQualifier() == EvqConst)
|
||||
{
|
||||
int index = indexExpression->getAsConstantUnion()->getIConst(0);
|
||||
if (index < 0)
|
||||
{
|
||||
std::stringstream infoStream;
|
||||
infoStream << index;
|
||||
std::string info = infoStream.str();
|
||||
error(location, "negative index", info.c_str());
|
||||
recover();
|
||||
index = 0;
|
||||
}
|
||||
if (baseExpression->getType().getQualifier() == EvqConst)
|
||||
{
|
||||
if (baseExpression->isArray())
|
||||
{
|
||||
// constant folding for arrays
|
||||
indexedExpression = addConstArrayNode(index, baseExpression, location);
|
||||
}
|
||||
else if (baseExpression->isVector())
|
||||
{
|
||||
// constant folding for vectors
|
||||
TVectorFields fields;
|
||||
fields.num = 1;
|
||||
fields.offsets[0] = index; // need to do it this way because v.xy sends fields integer array
|
||||
indexedExpression = addConstVectorNode(fields, baseExpression, location);
|
||||
}
|
||||
else if (baseExpression->isMatrix())
|
||||
{
|
||||
// constant folding for matrices
|
||||
indexedExpression = addConstMatrixNode(index, baseExpression, location);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (baseExpression->isArray())
|
||||
{
|
||||
if (index >= baseExpression->getType().getArraySize())
|
||||
{
|
||||
std::stringstream extraInfoStream;
|
||||
extraInfoStream << "array index out of range '" << index << "'";
|
||||
std::string extraInfo = extraInfoStream.str();
|
||||
error(location, "", "[", extraInfo.c_str());
|
||||
recover();
|
||||
index = baseExpression->getType().getArraySize() - 1;
|
||||
}
|
||||
else if (baseExpression->getQualifier() == EvqFragData && index > 0 && !isExtensionEnabled("GL_EXT_draw_buffers"))
|
||||
{
|
||||
error(location, "", "[", "array indexes for gl_FragData must be zero when GL_EXT_draw_buffers is disabled");
|
||||
recover();
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
else if ((baseExpression->isVector() || baseExpression->isMatrix()) && baseExpression->getType().getNominalSize() <= index)
|
||||
{
|
||||
std::stringstream extraInfoStream;
|
||||
extraInfoStream << "field selection out of range '" << index << "'";
|
||||
std::string extraInfo = extraInfoStream.str();
|
||||
error(location, "", "[", extraInfo.c_str());
|
||||
recover();
|
||||
index = baseExpression->getType().getNominalSize() - 1;
|
||||
}
|
||||
|
||||
indexExpression->getAsConstantUnion()->getUnionArrayPointer()->setIConst(index);
|
||||
indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
indexedExpression = intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location);
|
||||
}
|
||||
|
||||
if (indexedExpression == 0)
|
||||
{
|
||||
ConstantUnion *unionArray = new ConstantUnion[1];
|
||||
unionArray->setFConst(0.0f);
|
||||
indexedExpression = intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), location);
|
||||
}
|
||||
else if (baseExpression->isArray())
|
||||
{
|
||||
const TType &baseType = baseExpression->getType();
|
||||
if (baseType.getStruct())
|
||||
{
|
||||
TType copyOfType(baseType.getStruct());
|
||||
indexedExpression->setType(copyOfType);
|
||||
}
|
||||
else
|
||||
{
|
||||
indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqTemporary, baseExpression->getNominalSize(), baseExpression->isMatrix()));
|
||||
}
|
||||
|
||||
if (baseExpression->getType().getQualifier() == EvqConst)
|
||||
{
|
||||
indexedExpression->getTypePointer()->setQualifier(EvqConst);
|
||||
}
|
||||
}
|
||||
else if (baseExpression->isMatrix())
|
||||
{
|
||||
TQualifier qualifier = baseExpression->getType().getQualifier() == EvqConst ? EvqConst : EvqTemporary;
|
||||
indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), qualifier, baseExpression->getNominalSize()));
|
||||
}
|
||||
else if (baseExpression->isVector())
|
||||
{
|
||||
TQualifier qualifier = baseExpression->getType().getQualifier() == EvqConst ? EvqConst : EvqTemporary;
|
||||
indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), qualifier));
|
||||
}
|
||||
else
|
||||
{
|
||||
indexedExpression->setType(baseExpression->getType());
|
||||
}
|
||||
|
||||
return indexedExpression;
|
||||
}
|
||||
|
||||
//
|
||||
// Parse an array of strings using yyparse.
|
||||
//
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
|
||||
// Copyright (c) 2002-2013 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.
|
||||
//
|
||||
|
@ -33,10 +33,8 @@ struct TParseContext {
|
|||
compileOptions(options),
|
||||
sourcePath(sourcePath),
|
||||
treeRoot(0),
|
||||
lexAfterType(false),
|
||||
loopNestingLevel(0),
|
||||
structNestingLevel(0),
|
||||
inTypeParen(false),
|
||||
currentFunctionType(NULL),
|
||||
functionReturnsValue(false),
|
||||
checksPrecisionErrors(checksPrecErrors),
|
||||
|
@ -51,16 +49,13 @@ struct TParseContext {
|
|||
int compileOptions;
|
||||
const char* sourcePath; // Path of source file or NULL.
|
||||
TIntermNode* treeRoot; // root of parse tree being created
|
||||
bool lexAfterType; // true if we've recognized a type, so can only be looking for an identifier
|
||||
int loopNestingLevel; // 0 if outside all loops
|
||||
int structNestingLevel; // incremented while parsing a struct declaration
|
||||
bool inTypeParen; // true if in parentheses, looking only for an identifier
|
||||
const TType* currentFunctionType; // the return type of the function that's currently being parsed
|
||||
bool functionReturnsValue; // true if a non-void function has a return
|
||||
bool checksPrecisionErrors; // true if an error will be generated when a variable is declared without precision, explicit or implicit.
|
||||
bool fragmentPrecisionHigh; // true if highp precision is supported in the fragment language.
|
||||
TString HashErrMsg;
|
||||
bool AfterEOF;
|
||||
TDiagnostics diagnostics;
|
||||
TDirectiveHandler directiveHandler;
|
||||
pp::Preprocessor preprocessor;
|
||||
|
@ -68,71 +63,69 @@ struct TParseContext {
|
|||
|
||||
int numErrors() const { return diagnostics.numErrors(); }
|
||||
TInfoSink& infoSink() { return diagnostics.infoSink(); }
|
||||
void error(TSourceLoc loc, const char *reason, const char* token,
|
||||
void error(const TSourceLoc& loc, const char *reason, const char* token,
|
||||
const char* extraInfo="");
|
||||
void warning(TSourceLoc loc, const char* reason, const char* token,
|
||||
void warning(const TSourceLoc& loc, const char* reason, const char* token,
|
||||
const char* extraInfo="");
|
||||
void trace(const char* str);
|
||||
void recover();
|
||||
|
||||
bool parseVectorFields(const TString&, int vecSize, TVectorFields&, int line);
|
||||
bool parseMatrixFields(const TString&, int matSize, TMatrixFields&, int line);
|
||||
bool parseVectorFields(const TString&, int vecSize, TVectorFields&, const TSourceLoc& line);
|
||||
bool parseMatrixFields(const TString&, int matSize, TMatrixFields&, const TSourceLoc& line);
|
||||
|
||||
bool reservedErrorCheck(int line, const TString& identifier);
|
||||
void assignError(int line, const char* op, TString left, TString right);
|
||||
void unaryOpError(int line, const char* op, TString operand);
|
||||
void binaryOpError(int line, const char* op, TString left, TString right);
|
||||
bool precisionErrorCheck(int line, TPrecision precision, TBasicType type);
|
||||
bool lValueErrorCheck(int line, const char* op, TIntermTyped*);
|
||||
bool reservedErrorCheck(const TSourceLoc& line, const TString& identifier);
|
||||
void assignError(const TSourceLoc& line, const char* op, TString left, TString right);
|
||||
void unaryOpError(const TSourceLoc& line, const char* op, TString operand);
|
||||
void binaryOpError(const TSourceLoc& line, const char* op, TString left, TString right);
|
||||
bool precisionErrorCheck(const TSourceLoc& line, TPrecision precision, TBasicType type);
|
||||
bool lValueErrorCheck(const TSourceLoc& line, const char* op, TIntermTyped*);
|
||||
bool constErrorCheck(TIntermTyped* node);
|
||||
bool integerErrorCheck(TIntermTyped* node, const char* token);
|
||||
bool globalErrorCheck(int line, bool global, const char* token);
|
||||
bool constructorErrorCheck(int line, TIntermNode*, TFunction&, TOperator, TType*);
|
||||
bool arraySizeErrorCheck(int line, TIntermTyped* expr, int& size);
|
||||
bool arrayQualifierErrorCheck(int line, TPublicType type);
|
||||
bool arrayTypeErrorCheck(int line, TPublicType type);
|
||||
bool arrayErrorCheck(int line, TString& identifier, TPublicType type, TVariable*& variable);
|
||||
bool voidErrorCheck(int, const TString&, const TPublicType&);
|
||||
bool boolErrorCheck(int, const TIntermTyped*);
|
||||
bool boolErrorCheck(int, const TPublicType&);
|
||||
bool samplerErrorCheck(int line, const TPublicType& pType, const char* reason);
|
||||
bool structQualifierErrorCheck(int line, const TPublicType& pType);
|
||||
bool parameterSamplerErrorCheck(int line, TQualifier qualifier, const TType& type);
|
||||
bool nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type, bool array);
|
||||
bool nonInitErrorCheck(int line, TString& identifier, TPublicType& type, TVariable*& variable);
|
||||
bool paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type);
|
||||
bool extensionErrorCheck(int line, const TString&);
|
||||
|
||||
const TExtensionBehavior& extensionBehavior() const { return directiveHandler.extensionBehavior(); }
|
||||
bool supportsExtension(const char* extension);
|
||||
void handleExtensionDirective(int line, const char* extName, const char* behavior);
|
||||
bool globalErrorCheck(const TSourceLoc& line, bool global, const char* token);
|
||||
bool constructorErrorCheck(const TSourceLoc& line, TIntermNode*, TFunction&, TOperator, TType*);
|
||||
bool arraySizeErrorCheck(const TSourceLoc& line, TIntermTyped* expr, int& size);
|
||||
bool arrayQualifierErrorCheck(const TSourceLoc& line, TPublicType type);
|
||||
bool arrayTypeErrorCheck(const TSourceLoc& line, TPublicType type);
|
||||
bool arrayErrorCheck(const TSourceLoc& line, TString& identifier, TPublicType type, TVariable*& variable);
|
||||
bool voidErrorCheck(const TSourceLoc&, const TString&, const TPublicType&);
|
||||
bool boolErrorCheck(const TSourceLoc&, const TIntermTyped*);
|
||||
bool boolErrorCheck(const TSourceLoc&, const TPublicType&);
|
||||
bool samplerErrorCheck(const TSourceLoc& line, const TPublicType& pType, const char* reason);
|
||||
bool structQualifierErrorCheck(const TSourceLoc& line, const TPublicType& pType);
|
||||
bool parameterSamplerErrorCheck(const TSourceLoc& line, TQualifier qualifier, const TType& type);
|
||||
bool nonInitConstErrorCheck(const TSourceLoc& line, TString& identifier, TPublicType& type, bool array);
|
||||
bool nonInitErrorCheck(const TSourceLoc& line, TString& identifier, TPublicType& type, TVariable*& variable);
|
||||
bool paramErrorCheck(const TSourceLoc& line, TQualifier qualifier, TQualifier paramQualifier, TType* type);
|
||||
bool extensionErrorCheck(const TSourceLoc& line, const TString&);
|
||||
|
||||
const TPragma& pragma() const { return directiveHandler.pragma(); }
|
||||
void handlePragmaDirective(int line, const char* name, const char* value);
|
||||
const TExtensionBehavior& extensionBehavior() const { return directiveHandler.extensionBehavior(); }
|
||||
bool supportsExtension(const char* extension);
|
||||
bool isExtensionEnabled(const char* extension) const;
|
||||
|
||||
bool containsSampler(TType& type);
|
||||
bool areAllChildConst(TIntermAggregate* aggrNode);
|
||||
const TFunction* findFunction(int line, TFunction* pfnCall, bool *builtIn = 0);
|
||||
bool executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType,
|
||||
const TFunction* findFunction(const TSourceLoc& line, TFunction* pfnCall, bool *builtIn = 0);
|
||||
bool executeInitializer(const TSourceLoc& line, TString& identifier, TPublicType& pType,
|
||||
TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0);
|
||||
bool arraySetMaxSize(TIntermSymbol*, TType*, int, bool, TSourceLoc);
|
||||
|
||||
TIntermTyped* addConstructor(TIntermNode*, const TType*, TOperator, TFunction*, TSourceLoc);
|
||||
TIntermTyped* addConstructor(TIntermNode*, const TType*, TOperator, TFunction*, const TSourceLoc&);
|
||||
TIntermTyped* foldConstConstructor(TIntermAggregate* aggrNode, const TType& type);
|
||||
TIntermTyped* constructStruct(TIntermNode*, TType*, int, TSourceLoc, bool subset);
|
||||
TIntermTyped* constructBuiltIn(const TType*, TOperator, TIntermNode*, TSourceLoc, bool subset);
|
||||
TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, TSourceLoc);
|
||||
TIntermTyped* addConstMatrixNode(int , TIntermTyped*, TSourceLoc);
|
||||
TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line);
|
||||
TIntermTyped* addConstStruct(TString& , TIntermTyped*, TSourceLoc);
|
||||
TIntermTyped* constructStruct(TIntermNode*, TType*, int, const TSourceLoc&, bool subset);
|
||||
TIntermTyped* constructBuiltIn(const TType*, TOperator, TIntermNode*, const TSourceLoc&, bool subset);
|
||||
TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, const TSourceLoc&);
|
||||
TIntermTyped* addConstMatrixNode(int , TIntermTyped*, const TSourceLoc&);
|
||||
TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, const TSourceLoc& line);
|
||||
TIntermTyped* addConstStruct(TString& , TIntermTyped*, const TSourceLoc&);
|
||||
TIntermTyped* addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc& location, TIntermTyped *indexExpression);
|
||||
|
||||
// Performs an error check for embedded struct declarations.
|
||||
// Returns true if an error was raised due to the declaration of
|
||||
// this struct.
|
||||
bool enterStructDeclaration(TSourceLoc line, const TString& identifier);
|
||||
bool enterStructDeclaration(const TSourceLoc& line, const TString& identifier);
|
||||
void exitStructDeclaration();
|
||||
|
||||
bool structNestingErrorCheck(TSourceLoc line, const TType& fieldType);
|
||||
bool structNestingErrorCheck(const TSourceLoc& line, const TField& field);
|
||||
};
|
||||
|
||||
int PaParseStrings(size_t count, const char* const string[], const int length[],
|
||||
|
|
|
@ -17,55 +17,32 @@
|
|||
|
||||
OS_TLSIndex PoolIndex = OS_INVALID_TLS_INDEX;
|
||||
|
||||
void InitializeGlobalPools()
|
||||
{
|
||||
TThreadGlobalPools* globalPools= static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
|
||||
if (globalPools)
|
||||
return;
|
||||
|
||||
TThreadGlobalPools* threadData = new TThreadGlobalPools();
|
||||
threadData->globalPoolAllocator = 0;
|
||||
|
||||
OS_SetTLSValue(PoolIndex, threadData);
|
||||
}
|
||||
|
||||
void FreeGlobalPools()
|
||||
{
|
||||
// Release the allocated memory for this thread.
|
||||
TThreadGlobalPools* globalPools= static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
|
||||
if (!globalPools)
|
||||
return;
|
||||
|
||||
delete globalPools;
|
||||
}
|
||||
|
||||
bool InitializePoolIndex()
|
||||
{
|
||||
// Allocate a TLS index.
|
||||
if ((PoolIndex = OS_AllocTLSIndex()) == OS_INVALID_TLS_INDEX)
|
||||
return false;
|
||||
assert(PoolIndex == OS_INVALID_TLS_INDEX);
|
||||
|
||||
return true;
|
||||
PoolIndex = OS_AllocTLSIndex();
|
||||
return PoolIndex != OS_INVALID_TLS_INDEX;
|
||||
}
|
||||
|
||||
void FreePoolIndex()
|
||||
{
|
||||
// Release the TLS index.
|
||||
assert(PoolIndex != OS_INVALID_TLS_INDEX);
|
||||
|
||||
OS_FreeTLSIndex(PoolIndex);
|
||||
PoolIndex = OS_INVALID_TLS_INDEX;
|
||||
}
|
||||
|
||||
TPoolAllocator& GetGlobalPoolAllocator()
|
||||
TPoolAllocator* GetGlobalPoolAllocator()
|
||||
{
|
||||
TThreadGlobalPools* threadData = static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
|
||||
|
||||
return *threadData->globalPoolAllocator;
|
||||
assert(PoolIndex != OS_INVALID_TLS_INDEX);
|
||||
return static_cast<TPoolAllocator*>(OS_GetTLSValue(PoolIndex));
|
||||
}
|
||||
|
||||
void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator)
|
||||
{
|
||||
TThreadGlobalPools* threadData = static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
|
||||
|
||||
threadData->globalPoolAllocator = poolAllocator;
|
||||
assert(PoolIndex != OS_INVALID_TLS_INDEX);
|
||||
OS_SetTLSValue(PoolIndex, poolAllocator);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -228,24 +205,27 @@ void TPoolAllocator::popAll()
|
|||
|
||||
void* TPoolAllocator::allocate(size_t numBytes)
|
||||
{
|
||||
// If we are using guard blocks, all allocations are bracketed by
|
||||
// them: [guardblock][allocation][guardblock]. numBytes is how
|
||||
// much memory the caller asked for. allocationSize is the total
|
||||
// size including guard blocks. In release build,
|
||||
// guardBlockSize=0 and this all gets optimized away.
|
||||
size_t allocationSize = TAllocation::allocationSize(numBytes);
|
||||
|
||||
//
|
||||
// Just keep some interesting statistics.
|
||||
//
|
||||
++numCalls;
|
||||
totalBytes += numBytes;
|
||||
|
||||
// If we are using guard blocks, all allocations are bracketed by
|
||||
// them: [guardblock][allocation][guardblock]. numBytes is how
|
||||
// much memory the caller asked for. allocationSize is the total
|
||||
// size including guard blocks. In release build,
|
||||
// guardBlockSize=0 and this all gets optimized away.
|
||||
size_t allocationSize = TAllocation::allocationSize(numBytes);
|
||||
// Detect integer overflow.
|
||||
if (allocationSize < numBytes)
|
||||
return 0;
|
||||
|
||||
//
|
||||
// Do the allocation, most likely case first, for efficiency.
|
||||
// This step could be moved to be inline sometime.
|
||||
//
|
||||
if (currentPageOffset + allocationSize <= pageSize) {
|
||||
if (allocationSize <= pageSize - currentPageOffset) {
|
||||
//
|
||||
// Safe to allocate from currentPageOffset.
|
||||
//
|
||||
|
@ -256,12 +236,16 @@ void* TPoolAllocator::allocate(size_t numBytes)
|
|||
return initializeAllocation(inUseList, memory, numBytes);
|
||||
}
|
||||
|
||||
if (allocationSize + headerSkip > pageSize) {
|
||||
if (allocationSize > pageSize - headerSkip) {
|
||||
//
|
||||
// Do a multi-page allocation. Don't mix these with the others.
|
||||
// The OS is efficient and allocating and free-ing multiple pages.
|
||||
//
|
||||
size_t numBytesToAlloc = allocationSize + headerSkip;
|
||||
// Detect integer overflow.
|
||||
if (numBytesToAlloc < allocationSize)
|
||||
return 0;
|
||||
|
||||
tHeader* memory = reinterpret_cast<tHeader*>(::new char[numBytesToAlloc]);
|
||||
if (memory == 0)
|
||||
return 0;
|
||||
|
|
|
@ -219,14 +219,8 @@ private:
|
|||
// different times. But a simple use is to have a global pop
|
||||
// with everyone using the same global allocator.
|
||||
//
|
||||
extern TPoolAllocator& GetGlobalPoolAllocator();
|
||||
extern TPoolAllocator* GetGlobalPoolAllocator();
|
||||
extern void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator);
|
||||
#define GlobalPoolAllocator GetGlobalPoolAllocator()
|
||||
|
||||
struct TThreadGlobalPools
|
||||
{
|
||||
TPoolAllocator* globalPoolAllocator;
|
||||
};
|
||||
|
||||
//
|
||||
// This STL compatible allocator is intended to be used as the allocator
|
||||
|
@ -253,7 +247,7 @@ public:
|
|||
pointer address(reference x) const { return &x; }
|
||||
const_pointer address(const_reference x) const { return &x; }
|
||||
|
||||
pool_allocator() : allocator(&GlobalPoolAllocator) { }
|
||||
pool_allocator() : allocator(GetGlobalPoolAllocator()) { }
|
||||
pool_allocator(TPoolAllocator& a) : allocator(&a) { }
|
||||
pool_allocator(const pool_allocator<T>& p) : allocator(p.allocator) { }
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
class LongNameMap;
|
||||
class TCompiler;
|
||||
class TDependencyGraph;
|
||||
class TranslatorHLSL;
|
||||
|
||||
//
|
||||
// Helper function to identify specs that are based on the WebGL spec,
|
||||
|
@ -42,6 +43,7 @@ public:
|
|||
TShHandleBase();
|
||||
virtual ~TShHandleBase();
|
||||
virtual TCompiler* getAsCompiler() { return 0; }
|
||||
virtual TranslatorHLSL* getAsTranslatorHLSL() { return 0; }
|
||||
|
||||
protected:
|
||||
// Memory allocator. Allocates and tracks memory required by the compiler.
|
||||
|
@ -81,8 +83,8 @@ protected:
|
|||
bool InitBuiltInSymbolTable(const ShBuiltInResources& resources);
|
||||
// Clears the results from the previous compilation.
|
||||
void clearResults();
|
||||
// Return true if function recursion is detected.
|
||||
bool detectRecursion(TIntermNode* root);
|
||||
// Return true if function recursion is detected or call depth exceeded.
|
||||
bool detectCallDepth(TIntermNode* root, TInfoSink& infoSink, bool limitCallStackDepth);
|
||||
// Rewrites a shader's intermediate tree according to the CSS Shaders spec.
|
||||
void rewriteCSSShader(TIntermNode* root);
|
||||
// Returns true if the given shader does not exceed the minimum
|
||||
|
@ -104,8 +106,12 @@ protected:
|
|||
// 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);
|
||||
// Return true if the maximum expression complexity below the limit.
|
||||
bool limitExpressionComplexity(TIntermNode* root);
|
||||
// Get built-in extensions with default behavior.
|
||||
const TExtensionBehavior& getExtensionBehavior() const;
|
||||
// Get the resources set by InitBuiltInSymbolTable
|
||||
const ShBuiltInResources& getResources() const;
|
||||
|
||||
const ArrayBoundsClamper& getArrayBoundsClamper() const;
|
||||
ShArrayIndexClampingStrategy getArrayIndexClampingStrategy() const;
|
||||
|
@ -116,6 +122,10 @@ private:
|
|||
ShShaderSpec shaderSpec;
|
||||
|
||||
int maxUniformVectors;
|
||||
int maxExpressionComplexity;
|
||||
int maxCallStackDepth;
|
||||
|
||||
ShBuiltInResources compileResources;
|
||||
|
||||
// Built-in symbol table for the given language, spec, and resources.
|
||||
// It is preserved from compile-to-compile.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
|
||||
// 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.
|
||||
//
|
||||
|
@ -14,6 +14,7 @@
|
|||
#include "compiler/InitializeDll.h"
|
||||
#include "compiler/preprocessor/length_limits.h"
|
||||
#include "compiler/ShHandle.h"
|
||||
#include "compiler/TranslatorHLSL.h"
|
||||
|
||||
//
|
||||
// This is the platform independent interface between an OGL driver
|
||||
|
@ -84,15 +85,13 @@ static void getVariableInfo(ShShaderInfo varType,
|
|||
}
|
||||
|
||||
//
|
||||
// Driver must call this first, once, before doing any other
|
||||
// compiler operations.
|
||||
// Driver must call this first, once, before doing any other compiler operations.
|
||||
// Subsequent calls to this function are no-op.
|
||||
//
|
||||
int ShInitialize()
|
||||
{
|
||||
if (!InitProcess())
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
static const bool kInitialized = InitProcess();
|
||||
return kInitialized ? 1 : 0;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -100,9 +99,7 @@ int ShInitialize()
|
|||
//
|
||||
int ShFinalize()
|
||||
{
|
||||
if (!DetachProcess())
|
||||
return 0;
|
||||
|
||||
DetachProcess();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -126,6 +123,7 @@ void ShInitBuiltInResources(ShBuiltInResources* resources)
|
|||
resources->OES_EGL_image_external = 0;
|
||||
resources->ARB_texture_rectangle = 0;
|
||||
resources->EXT_draw_buffers = 0;
|
||||
resources->EXT_frag_depth = 0;
|
||||
|
||||
// Disable highp precision in fragment shader by default.
|
||||
resources->FragmentPrecisionHigh = 0;
|
||||
|
@ -143,9 +141,6 @@ ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec,
|
|||
ShShaderOutput output,
|
||||
const ShBuiltInResources* resources)
|
||||
{
|
||||
if (!InitThread())
|
||||
return 0;
|
||||
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec, output));
|
||||
TCompiler* compiler = base->getAsCompiler();
|
||||
if (compiler == 0)
|
||||
|
@ -184,9 +179,6 @@ int ShCompile(
|
|||
size_t numStrings,
|
||||
int compileOptions)
|
||||
{
|
||||
if (!InitThread())
|
||||
return 0;
|
||||
|
||||
if (handle == 0)
|
||||
return 0;
|
||||
|
||||
|
@ -351,3 +343,21 @@ void ShGetNameHashingEntry(const ShHandle handle,
|
|||
// To be on the safe side in case the source is longer than expected.
|
||||
hashedName[len - 1] = '\0';
|
||||
}
|
||||
|
||||
void ShGetInfoPointer(const ShHandle handle, ShShaderInfo pname, void** params)
|
||||
{
|
||||
if (!handle || !params)
|
||||
return;
|
||||
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
|
||||
TranslatorHLSL* translator = base->getAsTranslatorHLSL();
|
||||
if (!translator) return;
|
||||
|
||||
switch(pname)
|
||||
{
|
||||
case SH_ACTIVE_UNIFORMS_ARRAY:
|
||||
*params = (void*)&translator->getUniforms();
|
||||
break;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,48 +17,34 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "common/angleutils.h"
|
||||
#include <climits>
|
||||
|
||||
TType::TType(const TPublicType &p) :
|
||||
type(p.type), precision(p.precision), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize),
|
||||
maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0)
|
||||
type(p.type), precision(p.precision), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize), structure(0)
|
||||
{
|
||||
if (p.userDef) {
|
||||
if (p.userDef)
|
||||
structure = p.userDef->getStruct();
|
||||
typeName = NewPoolTString(p.userDef->getTypeName().c_str());
|
||||
computeDeepestStructNesting();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Recursively generate mangled names.
|
||||
//
|
||||
void TType::buildMangledName(TString& mangledName)
|
||||
TString TType::buildMangledName() const
|
||||
{
|
||||
TString mangledName;
|
||||
if (isMatrix())
|
||||
mangledName += 'm';
|
||||
else if (isVector())
|
||||
mangledName += 'v';
|
||||
|
||||
switch (type) {
|
||||
case EbtFloat: mangledName += 'f'; break;
|
||||
case EbtInt: mangledName += 'i'; break;
|
||||
case EbtBool: mangledName += 'b'; break;
|
||||
case EbtSampler2D: mangledName += "s2"; break;
|
||||
case EbtSamplerCube: mangledName += "sC"; break;
|
||||
case EbtStruct:
|
||||
mangledName += "struct-";
|
||||
if (typeName)
|
||||
mangledName += *typeName;
|
||||
{// support MSVC++6.0
|
||||
for (unsigned int i = 0; i < structure->size(); ++i) {
|
||||
mangledName += '-';
|
||||
(*structure)[i].type->buildMangledName(mangledName);
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
case EbtFloat: mangledName += 'f'; break;
|
||||
case EbtInt: mangledName += 'i'; break;
|
||||
case EbtBool: mangledName += 'b'; break;
|
||||
case EbtSampler2D: mangledName += "s2"; break;
|
||||
case EbtSamplerCube: mangledName += "sC"; break;
|
||||
case EbtStruct: mangledName += structure->mangledName(); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
mangledName += static_cast<char>('0' + getNominalSize());
|
||||
|
@ -69,55 +55,74 @@ void TType::buildMangledName(TString& mangledName)
|
|||
mangledName += buf;
|
||||
mangledName += ']';
|
||||
}
|
||||
return mangledName;
|
||||
}
|
||||
|
||||
int TType::getStructSize() const
|
||||
size_t TType::getObjectSize() const
|
||||
{
|
||||
if (!getStruct()) {
|
||||
assert(false && "Not a struct");
|
||||
return 0;
|
||||
size_t totalSize = 0;
|
||||
|
||||
if (getBasicType() == EbtStruct)
|
||||
totalSize = structure->objectSize();
|
||||
else if (matrix)
|
||||
totalSize = size * size;
|
||||
else
|
||||
totalSize = size;
|
||||
|
||||
if (isArray()) {
|
||||
size_t arraySize = getArraySize();
|
||||
if (arraySize > INT_MAX / totalSize)
|
||||
totalSize = INT_MAX;
|
||||
else
|
||||
totalSize *= arraySize;
|
||||
}
|
||||
|
||||
if (structureSize == 0)
|
||||
for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
|
||||
structureSize += ((*tl).type)->getObjectSize();
|
||||
|
||||
return structureSize;
|
||||
return totalSize;
|
||||
}
|
||||
|
||||
void TType::computeDeepestStructNesting()
|
||||
bool TStructure::containsArrays() const
|
||||
{
|
||||
if (!getStruct()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int maxNesting = 0;
|
||||
for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); ++tl) {
|
||||
maxNesting = std::max(maxNesting, ((*tl).type)->getDeepestStructNesting());
|
||||
}
|
||||
|
||||
deepestStructNesting = 1 + maxNesting;
|
||||
}
|
||||
|
||||
bool TType::isStructureContainingArrays() const
|
||||
{
|
||||
if (!structure)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (TTypeList::const_iterator member = structure->begin(); member != structure->end(); member++)
|
||||
{
|
||||
if (member->type->isArray() ||
|
||||
member->type->isStructureContainingArrays())
|
||||
{
|
||||
for (size_t i = 0; i < mFields->size(); ++i) {
|
||||
const TType* fieldType = (*mFields)[i]->type();
|
||||
if (fieldType->isArray() || fieldType->isStructureContainingArrays())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
TString TStructure::buildMangledName() const
|
||||
{
|
||||
TString mangledName("struct-");
|
||||
mangledName += *mName;
|
||||
for (size_t i = 0; i < mFields->size(); ++i) {
|
||||
mangledName += '-';
|
||||
mangledName += (*mFields)[i]->type()->getMangledName();
|
||||
}
|
||||
return mangledName;
|
||||
}
|
||||
|
||||
size_t TStructure::calculateObjectSize() const
|
||||
{
|
||||
size_t size = 0;
|
||||
for (size_t i = 0; i < mFields->size(); ++i) {
|
||||
size_t fieldSize = (*mFields)[i]->type()->getObjectSize();
|
||||
if (fieldSize > INT_MAX - size)
|
||||
size = INT_MAX;
|
||||
else
|
||||
size += fieldSize;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
int TStructure::calculateDeepestNesting() const
|
||||
{
|
||||
int maxNesting = 0;
|
||||
for (size_t i = 0; i < mFields->size(); ++i) {
|
||||
maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting());
|
||||
}
|
||||
return 1 + maxNesting;
|
||||
}
|
||||
|
||||
//
|
||||
// Dump functions.
|
||||
//
|
||||
|
@ -196,84 +201,8 @@ void TSymbolTableLevel::relateToOperator(const char* name, TOperator op)
|
|||
void TSymbolTableLevel::relateToExtension(const char* name, const TString& ext)
|
||||
{
|
||||
for (tLevel::iterator it = level.begin(); it != level.end(); ++it) {
|
||||
if (it->second->isFunction()) {
|
||||
TFunction* function = static_cast<TFunction*>(it->second);
|
||||
if (function->getName() == name)
|
||||
function->relateToExtension(ext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TSymbol::TSymbol(const TSymbol& copyOf)
|
||||
{
|
||||
name = NewPoolTString(copyOf.name->c_str());
|
||||
uniqueId = copyOf.uniqueId;
|
||||
}
|
||||
|
||||
TVariable::TVariable(const TVariable& copyOf, TStructureMap& remapper) : TSymbol(copyOf)
|
||||
{
|
||||
type.copyType(copyOf.type, remapper);
|
||||
userType = copyOf.userType;
|
||||
// for builtIn symbol table level, unionArray and arrayInformation pointers should be NULL
|
||||
assert(copyOf.arrayInformationType == 0);
|
||||
arrayInformationType = 0;
|
||||
|
||||
if (copyOf.unionArray) {
|
||||
assert(!copyOf.type.getStruct());
|
||||
assert(copyOf.type.getObjectSize() == 1);
|
||||
unionArray = new ConstantUnion[1];
|
||||
unionArray[0] = copyOf.unionArray[0];
|
||||
} else
|
||||
unionArray = 0;
|
||||
}
|
||||
|
||||
TVariable* TVariable::clone(TStructureMap& remapper)
|
||||
{
|
||||
TVariable *variable = new TVariable(*this, remapper);
|
||||
|
||||
return variable;
|
||||
}
|
||||
|
||||
TFunction::TFunction(const TFunction& copyOf, TStructureMap& remapper) : TSymbol(copyOf)
|
||||
{
|
||||
for (unsigned int i = 0; i < copyOf.parameters.size(); ++i) {
|
||||
TParameter param;
|
||||
parameters.push_back(param);
|
||||
parameters.back().copyParam(copyOf.parameters[i], remapper);
|
||||
}
|
||||
|
||||
returnType.copyType(copyOf.returnType, remapper);
|
||||
mangledName = copyOf.mangledName;
|
||||
op = copyOf.op;
|
||||
defined = copyOf.defined;
|
||||
}
|
||||
|
||||
TFunction* TFunction::clone(TStructureMap& remapper)
|
||||
{
|
||||
TFunction *function = new TFunction(*this, remapper);
|
||||
|
||||
return function;
|
||||
}
|
||||
|
||||
TSymbolTableLevel* TSymbolTableLevel::clone(TStructureMap& remapper)
|
||||
{
|
||||
TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
|
||||
tLevel::iterator iter;
|
||||
for (iter = level.begin(); iter != level.end(); ++iter) {
|
||||
symTableLevel->insert(*iter->second->clone(remapper));
|
||||
}
|
||||
|
||||
return symTableLevel;
|
||||
}
|
||||
|
||||
void TSymbolTable::copyTable(const TSymbolTable& copyOf)
|
||||
{
|
||||
TStructureMap remapper;
|
||||
uniqueId = copyOf.uniqueId;
|
||||
for (unsigned int i = 0; i < copyOf.table.size(); ++i) {
|
||||
table.push_back(copyOf.table[i]->clone(remapper));
|
||||
}
|
||||
for( unsigned int i = 0; i < copyOf.precisionStack.size(); i++) {
|
||||
precisionStack.push_back( copyOf.precisionStack[i] );
|
||||
TSymbol* symbol = it->second;
|
||||
if (symbol->getName() == name)
|
||||
symbol->relateToExtension(ext);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
|
||||
// Copyright (c) 2002-2013 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.
|
||||
//
|
||||
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include <assert.h>
|
||||
|
||||
#include "common/angleutils.h"
|
||||
#include "compiler/InfoSink.h"
|
||||
#include "compiler/intermediate.h"
|
||||
|
||||
|
@ -40,9 +41,10 @@
|
|||
//
|
||||
class TSymbol {
|
||||
public:
|
||||
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
|
||||
POOL_ALLOCATOR_NEW_DELETE();
|
||||
TSymbol(const TString *n) : name(n) { }
|
||||
virtual ~TSymbol() { /* don't delete name, it's from the pool */ }
|
||||
|
||||
const TString& getName() const { return *name; }
|
||||
virtual const TString& getMangledName() const { return getName(); }
|
||||
virtual bool isFunction() const { return false; }
|
||||
|
@ -50,12 +52,15 @@ public:
|
|||
void setUniqueId(int id) { uniqueId = id; }
|
||||
int getUniqueId() const { return uniqueId; }
|
||||
virtual void dump(TInfoSink &infoSink) const = 0;
|
||||
TSymbol(const TSymbol&);
|
||||
virtual TSymbol* clone(TStructureMap& remapper) = 0;
|
||||
void relateToExtension(const TString& ext) { extension = ext; }
|
||||
const TString& getExtension() const { return extension; }
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(TSymbol);
|
||||
|
||||
protected:
|
||||
const TString *name;
|
||||
unsigned int uniqueId; // For real comparing during code generation
|
||||
TString extension;
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -70,15 +75,13 @@ protected:
|
|||
//
|
||||
class TVariable : public TSymbol {
|
||||
public:
|
||||
TVariable(const TString *name, const TType& t, bool uT = false ) : TSymbol(name), type(t), userType(uT), unionArray(0), arrayInformationType(0) { }
|
||||
TVariable(const TString *name, const TType& t, bool uT = false ) : TSymbol(name), type(t), userType(uT), unionArray(0) { }
|
||||
virtual ~TVariable() { }
|
||||
virtual bool isVariable() const { return true; }
|
||||
TType& getType() { return type; }
|
||||
const TType& getType() const { return type; }
|
||||
bool isUserType() const { return userType; }
|
||||
void setQualifier(TQualifier qualifier) { type.setQualifier(qualifier); }
|
||||
void updateArrayInformationType(TType *t) { arrayInformationType = t; }
|
||||
TType* getArrayInformationType() { return arrayInformationType; }
|
||||
|
||||
virtual void dump(TInfoSink &infoSink) const;
|
||||
|
||||
|
@ -100,16 +103,15 @@ public:
|
|||
delete[] unionArray;
|
||||
unionArray = constArray;
|
||||
}
|
||||
TVariable(const TVariable&, TStructureMap& remapper); // copy constructor
|
||||
virtual TVariable* clone(TStructureMap& remapper);
|
||||
|
||||
protected:
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(TVariable);
|
||||
|
||||
TType type;
|
||||
bool userType;
|
||||
// we are assuming that Pool Allocator will free the memory allocated to unionArray
|
||||
// when this object is destroyed
|
||||
ConstantUnion *unionArray;
|
||||
TType *arrayInformationType; // this is used for updating maxArraySize in all the references to a given symbol
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -119,11 +121,6 @@ protected:
|
|||
struct TParameter {
|
||||
TString *name;
|
||||
TType* type;
|
||||
void copyParam(const TParameter& param, TStructureMap& remapper)
|
||||
{
|
||||
name = NewPoolTString(param.name->c_str());
|
||||
type = param.type->clone(remapper);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -163,9 +160,6 @@ public:
|
|||
void relateToOperator(TOperator o) { op = o; }
|
||||
TOperator getBuiltInOp() const { return op; }
|
||||
|
||||
void relateToExtension(const TString& ext) { extension = ext; }
|
||||
const TString& getExtension() const { return extension; }
|
||||
|
||||
void setDefined() { defined = true; }
|
||||
bool isDefined() { return defined; }
|
||||
|
||||
|
@ -173,16 +167,15 @@ public:
|
|||
const TParameter& getParam(size_t i) const { return parameters[i]; }
|
||||
|
||||
virtual void dump(TInfoSink &infoSink) const;
|
||||
TFunction(const TFunction&, TStructureMap& remapper);
|
||||
virtual TFunction* clone(TStructureMap& remapper);
|
||||
|
||||
protected:
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(TFunction);
|
||||
|
||||
typedef TVector<TParameter> TParamList;
|
||||
TParamList parameters;
|
||||
TType returnType;
|
||||
TString mangledName;
|
||||
TOperator op;
|
||||
TString extension;
|
||||
bool defined;
|
||||
};
|
||||
|
||||
|
@ -194,21 +187,26 @@ public:
|
|||
typedef const tLevel::value_type tLevelPair;
|
||||
typedef std::pair<tLevel::iterator, bool> tInsertResult;
|
||||
|
||||
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
|
||||
POOL_ALLOCATOR_NEW_DELETE();
|
||||
TSymbolTableLevel() { }
|
||||
~TSymbolTableLevel();
|
||||
|
||||
bool insert(TSymbol& symbol)
|
||||
bool insert(const TString &name, TSymbol &symbol)
|
||||
{
|
||||
//
|
||||
// returning true means symbol was added to the table
|
||||
//
|
||||
tInsertResult result;
|
||||
result = level.insert(tLevelPair(symbol.getMangledName(), &symbol));
|
||||
result = level.insert(tLevelPair(name, &symbol));
|
||||
|
||||
return result.second;
|
||||
}
|
||||
|
||||
bool insert(TSymbol &symbol)
|
||||
{
|
||||
return insert(symbol.getMangledName(), symbol);
|
||||
}
|
||||
|
||||
TSymbol* find(const TString& name) const
|
||||
{
|
||||
tLevel::const_iterator it = level.find(name);
|
||||
|
@ -231,7 +229,6 @@ public:
|
|||
void relateToOperator(const char* name, TOperator op);
|
||||
void relateToExtension(const char* name, const TString& ext);
|
||||
void dump(TInfoSink &infoSink) const;
|
||||
TSymbolTableLevel* clone(TStructureMap& remapper);
|
||||
|
||||
protected:
|
||||
tLevel level;
|
||||
|
@ -282,6 +279,35 @@ public:
|
|||
return table[currentLevel()]->insert(symbol);
|
||||
}
|
||||
|
||||
bool insertConstInt(const char *name, int value)
|
||||
{
|
||||
TVariable *constant = new TVariable(NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConst, 1));
|
||||
constant->getConstPointer()->setIConst(value);
|
||||
return insert(*constant);
|
||||
}
|
||||
|
||||
bool insertBuiltIn(TType *rvalue, const char *name, TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0)
|
||||
{
|
||||
TFunction *function = new TFunction(NewPoolTString(name), *rvalue);
|
||||
|
||||
TParameter param1 = {NULL, ptype1};
|
||||
function->addParameter(param1);
|
||||
|
||||
if(ptype2)
|
||||
{
|
||||
TParameter param2 = {NULL, ptype2};
|
||||
function->addParameter(param2);
|
||||
}
|
||||
|
||||
if(ptype3)
|
||||
{
|
||||
TParameter param3 = {NULL, ptype3};
|
||||
function->addParameter(param3);
|
||||
}
|
||||
|
||||
return insert(*function);
|
||||
}
|
||||
|
||||
TSymbol* find(const TString& name, bool* builtIn = 0, bool *sameScope = 0)
|
||||
{
|
||||
int level = currentLevel();
|
||||
|
@ -321,7 +347,6 @@ public:
|
|||
}
|
||||
int getMaxSymbolId() { return uniqueId; }
|
||||
void dump(TInfoSink &infoSink) const;
|
||||
void copyTable(const TSymbolTable& copyOf);
|
||||
|
||||
bool setDefaultPrecision( const TPublicType& type, TPrecision prec ){
|
||||
if (IsSampler(type.type))
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
|
||||
// Copyright (c) 2002-2013 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.
|
||||
//
|
||||
|
@ -9,15 +9,16 @@
|
|||
#include "compiler/InitializeParseContext.h"
|
||||
#include "compiler/OutputHLSL.h"
|
||||
|
||||
TranslatorHLSL::TranslatorHLSL(ShShaderType type, ShShaderSpec spec)
|
||||
: TCompiler(type, spec)
|
||||
TranslatorHLSL::TranslatorHLSL(ShShaderType type, ShShaderSpec spec, ShShaderOutput output)
|
||||
: TCompiler(type, spec), mOutputType(output)
|
||||
{
|
||||
}
|
||||
|
||||
void TranslatorHLSL::translate(TIntermNode *root)
|
||||
{
|
||||
TParseContext& parseContext = *GetGlobalParseContext();
|
||||
sh::OutputHLSL outputHLSL(parseContext);
|
||||
sh::OutputHLSL outputHLSL(parseContext, getResources(), mOutputType);
|
||||
|
||||
outputHLSL.output();
|
||||
mActiveUniforms = outputHLSL.getUniforms();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
|
||||
// Copyright (c) 2002-2013 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.
|
||||
//
|
||||
|
@ -8,13 +8,20 @@
|
|||
#define COMPILER_TRANSLATORHLSL_H_
|
||||
|
||||
#include "compiler/ShHandle.h"
|
||||
#include "compiler/CompilerUniform.h"
|
||||
|
||||
class TranslatorHLSL : public TCompiler {
|
||||
public:
|
||||
TranslatorHLSL(ShShaderType type, ShShaderSpec spec);
|
||||
TranslatorHLSL(ShShaderType type, ShShaderSpec spec, ShShaderOutput output);
|
||||
|
||||
virtual TranslatorHLSL *getAsTranslatorHLSL() { return this; }
|
||||
const sh::ActiveUniforms &getUniforms() { return mActiveUniforms; }
|
||||
|
||||
protected:
|
||||
virtual void translate(TIntermNode* root);
|
||||
|
||||
sh::ActiveUniforms mActiveUniforms;
|
||||
ShShaderOutput mOutputType;
|
||||
};
|
||||
|
||||
#endif // COMPILER_TRANSLATORHLSL_H_
|
||||
|
|
|
@ -7,30 +7,85 @@
|
|||
#ifndef _TYPES_INCLUDED
|
||||
#define _TYPES_INCLUDED
|
||||
|
||||
#include "common/angleutils.h"
|
||||
|
||||
#include "compiler/BaseTypes.h"
|
||||
#include "compiler/Common.h"
|
||||
#include "compiler/compiler_debug.h"
|
||||
|
||||
class TType;
|
||||
struct TPublicType;
|
||||
class TType;
|
||||
|
||||
//
|
||||
// Need to have association of line numbers to types in a list for building structs.
|
||||
//
|
||||
struct TTypeLine {
|
||||
TType* type;
|
||||
int line;
|
||||
};
|
||||
typedef TVector<TTypeLine> TTypeList;
|
||||
|
||||
inline TTypeList* NewPoolTTypeList()
|
||||
class TField
|
||||
{
|
||||
void* memory = GlobalPoolAllocator.allocate(sizeof(TTypeList));
|
||||
return new(memory) TTypeList;
|
||||
public:
|
||||
POOL_ALLOCATOR_NEW_DELETE();
|
||||
TField(TType* type, TString* name) : mType(type), mName(name) {}
|
||||
|
||||
// TODO(alokp): We should only return const type.
|
||||
// Fix it by tweaking grammar.
|
||||
TType* type() { return mType; }
|
||||
const TType* type() const { return mType; }
|
||||
|
||||
const TString& name() const { return *mName; }
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(TField);
|
||||
TType* mType;
|
||||
TString* mName;
|
||||
};
|
||||
|
||||
typedef TVector<TField*> TFieldList;
|
||||
inline TFieldList* NewPoolTFieldList()
|
||||
{
|
||||
void* memory = GetGlobalPoolAllocator()->allocate(sizeof(TFieldList));
|
||||
return new(memory) TFieldList;
|
||||
}
|
||||
|
||||
typedef TMap<TTypeList*, TTypeList*> TStructureMap;
|
||||
typedef TMap<TTypeList*, TTypeList*>::iterator TStructureMapIterator;
|
||||
class TStructure
|
||||
{
|
||||
public:
|
||||
POOL_ALLOCATOR_NEW_DELETE();
|
||||
TStructure(TString* name, TFieldList* fields)
|
||||
: mName(name),
|
||||
mFields(fields),
|
||||
mObjectSize(0),
|
||||
mDeepestNesting(0) {
|
||||
}
|
||||
|
||||
const TString& name() const { return *mName; }
|
||||
const TFieldList& fields() const { return *mFields; }
|
||||
|
||||
const TString& mangledName() const {
|
||||
if (mMangledName.empty())
|
||||
mMangledName = buildMangledName();
|
||||
return mMangledName;
|
||||
}
|
||||
size_t objectSize() const {
|
||||
if (mObjectSize == 0)
|
||||
mObjectSize = calculateObjectSize();
|
||||
return mObjectSize;
|
||||
};
|
||||
int deepestNesting() const {
|
||||
if (mDeepestNesting == 0)
|
||||
mDeepestNesting = calculateDeepestNesting();
|
||||
return mDeepestNesting;
|
||||
}
|
||||
bool containsArrays() const;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(TStructure);
|
||||
TString buildMangledName() const;
|
||||
size_t calculateObjectSize() const;
|
||||
int calculateDeepestNesting() const;
|
||||
|
||||
TString* mName;
|
||||
TFieldList* mFields;
|
||||
|
||||
mutable TString mMangledName;
|
||||
mutable size_t mObjectSize;
|
||||
mutable int mDeepestNesting;
|
||||
};
|
||||
|
||||
//
|
||||
// Base class for things that have a type.
|
||||
|
@ -38,72 +93,16 @@ typedef TMap<TTypeList*, TTypeList*>::iterator TStructureMapIterator;
|
|||
class TType
|
||||
{
|
||||
public:
|
||||
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
|
||||
POOL_ALLOCATOR_NEW_DELETE();
|
||||
TType() {}
|
||||
TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) :
|
||||
type(t), precision(p), qualifier(q), size(s), matrix(m), array(a), arraySize(0),
|
||||
maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0)
|
||||
TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, char s = 1, bool m = false, bool a = false) :
|
||||
type(t), precision(p), qualifier(q), size(s), matrix(m), array(a), arraySize(0), structure(0)
|
||||
{
|
||||
}
|
||||
explicit TType(const TPublicType &p);
|
||||
TType(TTypeList* userDef, const TString& n, TPrecision p = EbpUndefined) :
|
||||
type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0),
|
||||
maxArraySize(0), arrayInformationType(0), structure(userDef), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0)
|
||||
TType(TStructure* userDef, TPrecision p = EbpUndefined) :
|
||||
type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0), structure(userDef)
|
||||
{
|
||||
typeName = NewPoolTString(n.c_str());
|
||||
}
|
||||
|
||||
void copyType(const TType& copyOf, TStructureMap& remapper)
|
||||
{
|
||||
type = copyOf.type;
|
||||
precision = copyOf.precision;
|
||||
qualifier = copyOf.qualifier;
|
||||
size = copyOf.size;
|
||||
matrix = copyOf.matrix;
|
||||
array = copyOf.array;
|
||||
arraySize = copyOf.arraySize;
|
||||
|
||||
TStructureMapIterator iter;
|
||||
if (copyOf.structure) {
|
||||
if ((iter = remapper.find(structure)) == remapper.end()) {
|
||||
// create the new structure here
|
||||
structure = NewPoolTTypeList();
|
||||
for (unsigned int i = 0; i < copyOf.structure->size(); ++i) {
|
||||
TTypeLine typeLine;
|
||||
typeLine.line = (*copyOf.structure)[i].line;
|
||||
typeLine.type = (*copyOf.structure)[i].type->clone(remapper);
|
||||
structure->push_back(typeLine);
|
||||
}
|
||||
} else {
|
||||
structure = iter->second;
|
||||
}
|
||||
} else
|
||||
structure = 0;
|
||||
|
||||
fieldName = 0;
|
||||
if (copyOf.fieldName)
|
||||
fieldName = NewPoolTString(copyOf.fieldName->c_str());
|
||||
typeName = 0;
|
||||
if (copyOf.typeName)
|
||||
typeName = NewPoolTString(copyOf.typeName->c_str());
|
||||
|
||||
mangled = 0;
|
||||
if (copyOf.mangled)
|
||||
mangled = NewPoolTString(copyOf.mangled->c_str());
|
||||
|
||||
structureSize = copyOf.structureSize;
|
||||
maxArraySize = copyOf.maxArraySize;
|
||||
deepestStructNesting = copyOf.deepestStructNesting;
|
||||
assert(copyOf.arrayInformationType == 0);
|
||||
arrayInformationType = 0; // arrayInformationType should not be set for builtIn symbol table level
|
||||
}
|
||||
|
||||
TType* clone(TStructureMap& remapper)
|
||||
{
|
||||
TType *newType = new TType();
|
||||
newType->copyType(*this, remapper);
|
||||
|
||||
return newType;
|
||||
}
|
||||
|
||||
TBasicType getBasicType() const { return type; }
|
||||
|
@ -119,21 +118,42 @@ public:
|
|||
int getNominalSize() const { return size; }
|
||||
void setNominalSize(int s) { size = s; }
|
||||
// Full size of single instance of type
|
||||
int getObjectSize() const
|
||||
size_t getObjectSize() const;
|
||||
|
||||
int elementRegisterCount() const
|
||||
{
|
||||
int totalSize;
|
||||
if (structure)
|
||||
{
|
||||
const TFieldList &fields = getStruct()->fields();
|
||||
int registerCount = 0;
|
||||
|
||||
if (getBasicType() == EbtStruct)
|
||||
totalSize = getStructSize();
|
||||
else if (matrix)
|
||||
totalSize = size * size;
|
||||
for (size_t i = 0; i < fields.size(); i++)
|
||||
{
|
||||
registerCount += fields[i]->type()->totalRegisterCount();
|
||||
}
|
||||
|
||||
return registerCount;
|
||||
}
|
||||
else if (isMatrix())
|
||||
{
|
||||
return getNominalSize();
|
||||
}
|
||||
else
|
||||
totalSize = size;
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (isArray())
|
||||
totalSize *= std::max(getArraySize(), getMaxArraySize());
|
||||
|
||||
return totalSize;
|
||||
int totalRegisterCount() const
|
||||
{
|
||||
if (array)
|
||||
{
|
||||
return arraySize * elementRegisterCount();
|
||||
}
|
||||
else
|
||||
{
|
||||
return elementRegisterCount();
|
||||
}
|
||||
}
|
||||
|
||||
bool isMatrix() const { return matrix ? true : false; }
|
||||
|
@ -142,47 +162,20 @@ public:
|
|||
bool isArray() const { return array ? true : false; }
|
||||
int getArraySize() const { return arraySize; }
|
||||
void setArraySize(int s) { array = true; arraySize = s; }
|
||||
int getMaxArraySize () const { return maxArraySize; }
|
||||
void setMaxArraySize (int s) { maxArraySize = s; }
|
||||
void clearArrayness() { array = false; arraySize = 0; maxArraySize = 0; }
|
||||
void setArrayInformationType(TType* t) { arrayInformationType = t; }
|
||||
TType* getArrayInformationType() const { return arrayInformationType; }
|
||||
void clearArrayness() { array = false; arraySize = 0; }
|
||||
|
||||
bool isVector() const { return size > 1 && !matrix; }
|
||||
bool isScalar() const { return size == 1 && !matrix && !structure; }
|
||||
|
||||
TTypeList* getStruct() const { return structure; }
|
||||
void setStruct(TTypeList* s) { structure = s; computeDeepestStructNesting(); }
|
||||
TStructure* getStruct() const { return structure; }
|
||||
void setStruct(TStructure* s) { structure = s; }
|
||||
|
||||
const TString& getTypeName() const
|
||||
{
|
||||
assert(typeName);
|
||||
return *typeName;
|
||||
}
|
||||
void setTypeName(const TString& n)
|
||||
{
|
||||
typeName = NewPoolTString(n.c_str());
|
||||
}
|
||||
|
||||
bool isField() const { return fieldName != 0; }
|
||||
const TString& getFieldName() const
|
||||
{
|
||||
assert(fieldName);
|
||||
return *fieldName;
|
||||
}
|
||||
void setFieldName(const TString& n)
|
||||
{
|
||||
fieldName = NewPoolTString(n.c_str());
|
||||
}
|
||||
|
||||
TString& getMangledName() {
|
||||
if (!mangled) {
|
||||
mangled = NewPoolTString("");
|
||||
buildMangledName(*mangled);
|
||||
*mangled += ';' ;
|
||||
const TString& getMangledName() const {
|
||||
if (mangled.empty()) {
|
||||
mangled = buildMangledName();
|
||||
mangled += ';';
|
||||
}
|
||||
|
||||
return *mangled;
|
||||
return mangled;
|
||||
}
|
||||
|
||||
bool sameElementType(const TType& right) const {
|
||||
|
@ -230,32 +223,28 @@ public:
|
|||
// For type "nesting2", this method would return 2 -- the number
|
||||
// of structures through which indirection must occur to reach the
|
||||
// deepest field (nesting2.field1.position).
|
||||
int getDeepestStructNesting() const { return deepestStructNesting; }
|
||||
int getDeepestStructNesting() const {
|
||||
return structure ? structure->deepestNesting() : 0;
|
||||
}
|
||||
|
||||
bool isStructureContainingArrays() const;
|
||||
bool isStructureContainingArrays() const {
|
||||
return structure ? structure->containsArrays() : false;
|
||||
}
|
||||
|
||||
protected:
|
||||
void buildMangledName(TString&);
|
||||
int getStructSize() const;
|
||||
void computeDeepestStructNesting();
|
||||
private:
|
||||
TString buildMangledName() const;
|
||||
|
||||
TBasicType type : 6;
|
||||
TBasicType type;
|
||||
TPrecision precision;
|
||||
TQualifier qualifier : 7;
|
||||
int size : 8; // size of vector or matrix, not size of array
|
||||
unsigned int matrix : 1;
|
||||
unsigned int array : 1;
|
||||
TQualifier qualifier;
|
||||
char size; // size of vector or matrix, not size of array
|
||||
bool matrix;
|
||||
bool array;
|
||||
int arraySize;
|
||||
int maxArraySize;
|
||||
TType* arrayInformationType;
|
||||
|
||||
TTypeList* structure; // 0 unless this is a struct
|
||||
mutable int structureSize;
|
||||
int deepestStructNesting;
|
||||
TStructure* structure; // 0 unless this is a struct
|
||||
|
||||
TString *fieldName; // for structure field names
|
||||
TString *mangled;
|
||||
TString *typeName; // for structure field type name
|
||||
mutable TString mangled;
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -277,9 +266,9 @@ struct TPublicType
|
|||
bool array;
|
||||
int arraySize;
|
||||
TType* userDef;
|
||||
int line;
|
||||
TSourceLoc line;
|
||||
|
||||
void setBasic(TBasicType bt, TQualifier q, int ln = 0)
|
||||
void setBasic(TBasicType bt, TQualifier q, const TSourceLoc& ln)
|
||||
{
|
||||
type = bt;
|
||||
qualifier = q;
|
||||
|
|
|
@ -435,7 +435,7 @@ bool ValidateLimitations::validateFunctionCall(TIntermAggregate* node)
|
|||
return true;
|
||||
|
||||
bool valid = true;
|
||||
TSymbolTable& symbolTable = GlobalParseContext->symbolTable;
|
||||
TSymbolTable& symbolTable = GetGlobalParseContext()->symbolTable;
|
||||
TSymbol* symbol = symbolTable.find(node->getName());
|
||||
ASSERT(symbol && symbol->isFunction());
|
||||
TFunction* function = static_cast<TFunction*>(symbol);
|
||||
|
|
|
@ -131,12 +131,13 @@ void getUserDefinedVariableInfo(const TType& type,
|
|||
{
|
||||
ASSERT(type.getBasicType() == EbtStruct);
|
||||
|
||||
const TTypeList* structure = type.getStruct();
|
||||
for (size_t i = 0; i < structure->size(); ++i) {
|
||||
const TType* fieldType = (*structure)[i].type;
|
||||
getVariableInfo(*fieldType,
|
||||
name + "." + fieldType->getFieldName(),
|
||||
mappedName + "." + TIntermTraverser::hash(fieldType->getFieldName(), hashFunction),
|
||||
const TFieldList& fields = type.getStruct()->fields();
|
||||
for (size_t i = 0; i < fields.size(); ++i) {
|
||||
const TType& fieldType = *(fields[i]->type());
|
||||
const TString& fieldName = fields[i]->name();
|
||||
getVariableInfo(fieldType,
|
||||
name + "." + fieldName,
|
||||
mappedName + "." + TIntermTraverser::hash(fieldName, hashFunction),
|
||||
infoList,
|
||||
hashFunction);
|
||||
}
|
||||
|
|
|
@ -25,3 +25,4 @@ script_dir=$(dirname $0)
|
|||
# Generate Parser
|
||||
run_flex glslang
|
||||
run_bison glslang
|
||||
patch --silent --forward < 64bit-lexer-safety.patch
|
||||
|
|
|
@ -47,7 +47,10 @@ WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp).
|
|||
#pragma warning(disable : 4102)
|
||||
#endif
|
||||
|
||||
#define YY_USER_ACTION yylval->lex.line = yylineno;
|
||||
#define YY_USER_ACTION \
|
||||
yylloc->first_file = yylloc->last_file = yycolumn; \
|
||||
yylloc->first_line = yylloc->last_line = yylineno;
|
||||
|
||||
#define YY_INPUT(buf, result, max_size) \
|
||||
result = string_input(buf, max_size, yyscanner);
|
||||
|
||||
|
@ -57,10 +60,8 @@ static int reserved_word(yyscan_t yyscanner);
|
|||
%}
|
||||
|
||||
%option noyywrap nounput never-interactive
|
||||
%option yylineno reentrant bison-bridge
|
||||
%option stack
|
||||
%option yylineno reentrant bison-bridge bison-locations
|
||||
%option extra-type="TParseContext*"
|
||||
%x COMMENT FIELDS
|
||||
|
||||
D [0-9]
|
||||
L [a-zA-Z_]
|
||||
|
@ -70,73 +71,60 @@ O [0-7]
|
|||
|
||||
%%
|
||||
|
||||
%{
|
||||
TParseContext* context = yyextra;
|
||||
%}
|
||||
"invariant" { return INVARIANT; }
|
||||
"highp" { return HIGH_PRECISION; }
|
||||
"mediump" { return MEDIUM_PRECISION; }
|
||||
"lowp" { return LOW_PRECISION; }
|
||||
"precision" { return PRECISION; }
|
||||
|
||||
/* Single-line comments */
|
||||
"//"[^\n]* ;
|
||||
"attribute" { return ATTRIBUTE; }
|
||||
"const" { return CONST_QUAL; }
|
||||
"uniform" { return UNIFORM; }
|
||||
"varying" { return VARYING; }
|
||||
|
||||
/* Multi-line comments */
|
||||
"/*" { yy_push_state(COMMENT, yyscanner); }
|
||||
<COMMENT>. |
|
||||
<COMMENT>\n ;
|
||||
<COMMENT>"*/" { yy_pop_state(yyscanner); }
|
||||
"break" { return BREAK; }
|
||||
"continue" { return CONTINUE; }
|
||||
"do" { return DO; }
|
||||
"for" { return FOR; }
|
||||
"while" { return WHILE; }
|
||||
|
||||
"invariant" { return(INVARIANT); }
|
||||
"highp" { return(HIGH_PRECISION); }
|
||||
"mediump" { return(MEDIUM_PRECISION); }
|
||||
"lowp" { return(LOW_PRECISION); }
|
||||
"precision" { return(PRECISION); }
|
||||
"if" { return IF; }
|
||||
"else" { return ELSE; }
|
||||
|
||||
"attribute" { return(ATTRIBUTE); }
|
||||
"const" { return(CONST_QUAL); }
|
||||
"uniform" { return(UNIFORM); }
|
||||
"varying" { return(VARYING); }
|
||||
"in" { return IN_QUAL; }
|
||||
"out" { return OUT_QUAL; }
|
||||
"inout" { return INOUT_QUAL; }
|
||||
|
||||
"break" { return(BREAK); }
|
||||
"continue" { return(CONTINUE); }
|
||||
"do" { return(DO); }
|
||||
"for" { return(FOR); }
|
||||
"while" { return(WHILE); }
|
||||
"float" { return FLOAT_TYPE; }
|
||||
"int" { return INT_TYPE; }
|
||||
"void" { return VOID_TYPE; }
|
||||
"bool" { return BOOL_TYPE; }
|
||||
"true" { yylval->lex.b = true; return BOOLCONSTANT; }
|
||||
"false" { yylval->lex.b = false; return BOOLCONSTANT; }
|
||||
|
||||
"if" { return(IF); }
|
||||
"else" { return(ELSE); }
|
||||
"discard" { return DISCARD; }
|
||||
"return" { return RETURN; }
|
||||
|
||||
"in" { return(IN_QUAL); }
|
||||
"out" { return(OUT_QUAL); }
|
||||
"inout" { return(INOUT_QUAL); }
|
||||
"mat2" { return MATRIX2; }
|
||||
"mat3" { return MATRIX3; }
|
||||
"mat4" { return MATRIX4; }
|
||||
|
||||
"float" { context->lexAfterType = true; return(FLOAT_TYPE); }
|
||||
"int" { context->lexAfterType = true; return(INT_TYPE); }
|
||||
"void" { context->lexAfterType = true; return(VOID_TYPE); }
|
||||
"bool" { context->lexAfterType = true; return(BOOL_TYPE); }
|
||||
"true" { yylval->lex.b = true; return(BOOLCONSTANT); }
|
||||
"false" { yylval->lex.b = false; return(BOOLCONSTANT); }
|
||||
"vec2" { return VEC2; }
|
||||
"vec3" { return VEC3; }
|
||||
"vec4" { return VEC4; }
|
||||
"ivec2" { return IVEC2; }
|
||||
"ivec3" { return IVEC3; }
|
||||
"ivec4" { return IVEC4; }
|
||||
"bvec2" { return BVEC2; }
|
||||
"bvec3" { return BVEC3; }
|
||||
"bvec4" { return BVEC4; }
|
||||
|
||||
"discard" { return(DISCARD); }
|
||||
"return" { return(RETURN); }
|
||||
"sampler2D" { return SAMPLER2D; }
|
||||
"samplerCube" { return SAMPLERCUBE; }
|
||||
"samplerExternalOES" { return SAMPLER_EXTERNAL_OES; }
|
||||
"sampler2DRect" { return SAMPLER2DRECT; }
|
||||
|
||||
"mat2" { context->lexAfterType = true; return(MATRIX2); }
|
||||
"mat3" { context->lexAfterType = true; return(MATRIX3); }
|
||||
"mat4" { context->lexAfterType = true; return(MATRIX4); }
|
||||
|
||||
"vec2" { context->lexAfterType = true; return (VEC2); }
|
||||
"vec3" { context->lexAfterType = true; return (VEC3); }
|
||||
"vec4" { context->lexAfterType = true; return (VEC4); }
|
||||
"ivec2" { context->lexAfterType = true; return (IVEC2); }
|
||||
"ivec3" { context->lexAfterType = true; return (IVEC3); }
|
||||
"ivec4" { context->lexAfterType = true; return (IVEC4); }
|
||||
"bvec2" { context->lexAfterType = true; return (BVEC2); }
|
||||
"bvec3" { context->lexAfterType = true; return (BVEC3); }
|
||||
"bvec4" { context->lexAfterType = true; return (BVEC4); }
|
||||
|
||||
"sampler2D" { context->lexAfterType = true; return SAMPLER2D; }
|
||||
"samplerCube" { context->lexAfterType = true; return SAMPLERCUBE; }
|
||||
"samplerExternalOES" { context->lexAfterType = true; return SAMPLER_EXTERNAL_OES; }
|
||||
"sampler2DRect" { context->lexAfterType = true; return SAMPLER2DRECT; }
|
||||
|
||||
"struct" { context->lexAfterType = true; return(STRUCT); }
|
||||
"struct" { return STRUCT; }
|
||||
|
||||
"asm" { return reserved_word(yyscanner); }
|
||||
|
||||
|
@ -183,13 +171,11 @@ O [0-7]
|
|||
"fvec3" { return reserved_word(yyscanner); }
|
||||
"fvec4" { return reserved_word(yyscanner); }
|
||||
|
||||
"sampler1D" { return reserved_word(yyscanner); }
|
||||
"sampler3D" { return reserved_word(yyscanner); }
|
||||
|
||||
"sampler1DShadow" { return reserved_word(yyscanner); }
|
||||
"sampler2DShadow" { return reserved_word(yyscanner); }
|
||||
|
||||
"sampler3DRect" { return reserved_word(yyscanner); }
|
||||
"sampler1D" { return reserved_word(yyscanner); }
|
||||
"sampler3D" { return reserved_word(yyscanner); }
|
||||
"sampler1DShadow" { return reserved_word(yyscanner); }
|
||||
"sampler2DShadow" { return reserved_word(yyscanner); }
|
||||
"sampler3DRect" { return reserved_word(yyscanner); }
|
||||
"sampler2DRectShadow" { return reserved_word(yyscanner); }
|
||||
|
||||
"sizeof" { return reserved_word(yyscanner); }
|
||||
|
@ -203,72 +189,64 @@ O [0-7]
|
|||
return check_type(yyscanner);
|
||||
}
|
||||
|
||||
0[xX]{H}+ { yylval->lex.i = static_cast<int>(strtol(yytext, 0, 0)); return(INTCONSTANT); }
|
||||
0{O}+ { yylval->lex.i = static_cast<int>(strtol(yytext, 0, 0)); return(INTCONSTANT); }
|
||||
0{D}+ { context->error(yylineno, "Invalid Octal number.", yytext); context->recover(); return 0;}
|
||||
{D}+ { yylval->lex.i = static_cast<int>(strtol(yytext, 0, 0)); return(INTCONSTANT); }
|
||||
0[xX]{H}+ { yylval->lex.i = static_cast<int>(strtol(yytext, 0, 0)); return INTCONSTANT; }
|
||||
0{O}+ { yylval->lex.i = static_cast<int>(strtol(yytext, 0, 0)); return INTCONSTANT; }
|
||||
{D}+ { yylval->lex.i = static_cast<int>(strtol(yytext, 0, 0)); return INTCONSTANT; }
|
||||
|
||||
{D}+{E} { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
|
||||
{D}+"."{D}*({E})? { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
|
||||
"."{D}+({E})? { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
|
||||
{D}+{E} { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return FLOATCONSTANT; }
|
||||
{D}+"."{D}*({E})? { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return FLOATCONSTANT; }
|
||||
"."{D}+({E})? { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return FLOATCONSTANT; }
|
||||
|
||||
"+=" { return(ADD_ASSIGN); }
|
||||
"-=" { return(SUB_ASSIGN); }
|
||||
"*=" { return(MUL_ASSIGN); }
|
||||
"/=" { return(DIV_ASSIGN); }
|
||||
"%=" { return(MOD_ASSIGN); }
|
||||
"<<=" { return(LEFT_ASSIGN); }
|
||||
">>=" { return(RIGHT_ASSIGN); }
|
||||
"&=" { return(AND_ASSIGN); }
|
||||
"^=" { return(XOR_ASSIGN); }
|
||||
"|=" { return(OR_ASSIGN); }
|
||||
"+=" { return ADD_ASSIGN; }
|
||||
"-=" { return SUB_ASSIGN; }
|
||||
"*=" { return MUL_ASSIGN; }
|
||||
"/=" { return DIV_ASSIGN; }
|
||||
"%=" { return MOD_ASSIGN; }
|
||||
"<<=" { return LEFT_ASSIGN; }
|
||||
">>=" { return RIGHT_ASSIGN; }
|
||||
"&=" { return AND_ASSIGN; }
|
||||
"^=" { return XOR_ASSIGN; }
|
||||
"|=" { return OR_ASSIGN; }
|
||||
|
||||
"++" { return(INC_OP); }
|
||||
"--" { return(DEC_OP); }
|
||||
"&&" { return(AND_OP); }
|
||||
"||" { return(OR_OP); }
|
||||
"^^" { return(XOR_OP); }
|
||||
"<=" { return(LE_OP); }
|
||||
">=" { return(GE_OP); }
|
||||
"==" { return(EQ_OP); }
|
||||
"!=" { return(NE_OP); }
|
||||
"<<" { return(LEFT_OP); }
|
||||
">>" { return(RIGHT_OP); }
|
||||
";" { context->lexAfterType = false; return(SEMICOLON); }
|
||||
("{"|"<%") { context->lexAfterType = false; return(LEFT_BRACE); }
|
||||
("}"|"%>") { return(RIGHT_BRACE); }
|
||||
"," { if (context->inTypeParen) context->lexAfterType = false; return(COMMA); }
|
||||
":" { return(COLON); }
|
||||
"=" { context->lexAfterType = false; return(EQUAL); }
|
||||
"(" { context->lexAfterType = false; context->inTypeParen = true; return(LEFT_PAREN); }
|
||||
")" { context->inTypeParen = false; return(RIGHT_PAREN); }
|
||||
("["|"<:") { return(LEFT_BRACKET); }
|
||||
("]"|":>") { return(RIGHT_BRACKET); }
|
||||
"." { BEGIN(FIELDS); return(DOT); }
|
||||
"!" { return(BANG); }
|
||||
"-" { return(DASH); }
|
||||
"~" { return(TILDE); }
|
||||
"+" { return(PLUS); }
|
||||
"*" { return(STAR); }
|
||||
"/" { return(SLASH); }
|
||||
"%" { return(PERCENT); }
|
||||
"<" { return(LEFT_ANGLE); }
|
||||
">" { return(RIGHT_ANGLE); }
|
||||
"|" { return(VERTICAL_BAR); }
|
||||
"^" { return(CARET); }
|
||||
"&" { return(AMPERSAND); }
|
||||
"?" { return(QUESTION); }
|
||||
"++" { return INC_OP; }
|
||||
"--" { return DEC_OP; }
|
||||
"&&" { return AND_OP; }
|
||||
"||" { return OR_OP; }
|
||||
"^^" { return XOR_OP; }
|
||||
"<=" { return LE_OP; }
|
||||
">=" { return GE_OP; }
|
||||
"==" { return EQ_OP; }
|
||||
"!=" { return NE_OP; }
|
||||
"<<" { return LEFT_OP; }
|
||||
">>" { return RIGHT_OP; }
|
||||
";" { return SEMICOLON; }
|
||||
("{"|"<%") { return LEFT_BRACE; }
|
||||
("}"|"%>") { return RIGHT_BRACE; }
|
||||
"," { return COMMA; }
|
||||
":" { return COLON; }
|
||||
"=" { return EQUAL; }
|
||||
"(" { return LEFT_PAREN; }
|
||||
")" { return RIGHT_PAREN; }
|
||||
("["|"<:") { return LEFT_BRACKET; }
|
||||
("]"|":>") { return RIGHT_BRACKET; }
|
||||
"." { return DOT; }
|
||||
"!" { return BANG; }
|
||||
"-" { return DASH; }
|
||||
"~" { return TILDE; }
|
||||
"+" { return PLUS; }
|
||||
"*" { return STAR; }
|
||||
"/" { return SLASH; }
|
||||
"%" { return PERCENT; }
|
||||
"<" { return LEFT_ANGLE; }
|
||||
">" { return RIGHT_ANGLE; }
|
||||
"|" { return VERTICAL_BAR; }
|
||||
"^" { return CARET; }
|
||||
"&" { return AMPERSAND; }
|
||||
"?" { return QUESTION; }
|
||||
|
||||
<FIELDS>{L}({L}|{D})* {
|
||||
BEGIN(INITIAL);
|
||||
yylval->lex.string = NewPoolTString(yytext);
|
||||
return FIELD_SELECTION;
|
||||
}
|
||||
<FIELDS>[ \t\v\f\r] {}
|
||||
|
||||
[ \t\v\n\f\r] { }
|
||||
<*><<EOF>> { context->AfterEOF = true; yyterminate(); }
|
||||
<*>. { context->warning(yylineno, "Unknown char", yytext, ""); return 0; }
|
||||
[ \t\v\n\f\r] { }
|
||||
<<EOF>> { yyterminate(); }
|
||||
. { assert(false); return 0; }
|
||||
|
||||
%%
|
||||
|
||||
|
@ -278,7 +256,8 @@ yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner) {
|
|||
yy_size_t len = token.type == pp::Token::LAST ? 0 : token.text.size();
|
||||
if (len < max_size)
|
||||
memcpy(buf, token.text.c_str(), len);
|
||||
yyset_lineno(EncodeSourceLoc(token.location.file, token.location.line), yyscanner);
|
||||
yyset_column(token.location.file, yyscanner);
|
||||
yyset_lineno(token.location.line, yyscanner);
|
||||
|
||||
if (len >= max_size)
|
||||
YY_FATAL_ERROR("Input buffer overflow");
|
||||
|
@ -292,12 +271,10 @@ int check_type(yyscan_t yyscanner) {
|
|||
|
||||
int token = IDENTIFIER;
|
||||
TSymbol* symbol = yyextra->symbolTable.find(yytext);
|
||||
if (yyextra->lexAfterType == false && symbol && symbol->isVariable()) {
|
||||
if (symbol && symbol->isVariable()) {
|
||||
TVariable* variable = static_cast<TVariable*>(symbol);
|
||||
if (variable->isUserType()) {
|
||||
yyextra->lexAfterType = true;
|
||||
if (variable->isUserType())
|
||||
token = TYPE_NAME;
|
||||
}
|
||||
}
|
||||
yylval->lex.symbol = symbol;
|
||||
return token;
|
||||
|
@ -306,22 +283,11 @@ int check_type(yyscan_t yyscanner) {
|
|||
int reserved_word(yyscan_t yyscanner) {
|
||||
struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
|
||||
|
||||
yyextra->error(yylineno, "Illegal use of reserved word", yytext, "");
|
||||
yyextra->error(*yylloc, "Illegal use of reserved word", yytext, "");
|
||||
yyextra->recover();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void yyerror(TParseContext* context, const char* reason) {
|
||||
struct yyguts_t* yyg = (struct yyguts_t*) context->scanner;
|
||||
|
||||
if (context->AfterEOF) {
|
||||
context->error(yylineno, reason, "unexpected EOF");
|
||||
} else {
|
||||
context->error(yylineno, reason, yytext);
|
||||
}
|
||||
context->recover();
|
||||
}
|
||||
|
||||
int glslang_initialize(TParseContext* context) {
|
||||
yyscan_t scanner = NULL;
|
||||
if (yylex_init_extra(context, &scanner))
|
||||
|
@ -344,8 +310,8 @@ int glslang_finalize(TParseContext* context) {
|
|||
int glslang_scan(size_t count, const char* const string[], const int length[],
|
||||
TParseContext* context) {
|
||||
yyrestart(NULL, context->scanner);
|
||||
yyset_lineno(EncodeSourceLoc(0, 1), context->scanner);
|
||||
context->AfterEOF = false;
|
||||
yyset_column(0, context->scanner);
|
||||
yyset_lineno(1, context->scanner);
|
||||
|
||||
// Initialize preprocessor.
|
||||
if (!context->preprocessor.init(count, string, length))
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,9 +1,8 @@
|
|||
/* A Bison parser, made by GNU Bison 2.4.2. */
|
||||
/* A Bison parser, made by GNU Bison 2.7. */
|
||||
|
||||
/* Skeleton interface for Bison's Yacc-like parsers in C
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2006, 2009-2010 Free Software
|
||||
Foundation, Inc.
|
||||
Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -31,6 +30,23 @@
|
|||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
#ifndef YY_YY_GLSLANG_TAB_H_INCLUDED
|
||||
# define YY_YY_GLSLANG_TAB_H_INCLUDED
|
||||
/* Enabling traces. */
|
||||
#ifndef YYDEBUG
|
||||
# define YYDEBUG 0
|
||||
#endif
|
||||
#if YYDEBUG
|
||||
extern int yydebug;
|
||||
#endif
|
||||
/* "%code requires" blocks. */
|
||||
|
||||
|
||||
#define YYLTYPE TSourceLoc
|
||||
#define YYLTYPE_IS_DECLARED 1
|
||||
|
||||
|
||||
|
||||
|
||||
/* Tokens. */
|
||||
#ifndef YYTOKENTYPE
|
||||
|
@ -85,64 +101,61 @@
|
|||
FLOATCONSTANT = 302,
|
||||
INTCONSTANT = 303,
|
||||
BOOLCONSTANT = 304,
|
||||
FIELD_SELECTION = 305,
|
||||
LEFT_OP = 306,
|
||||
RIGHT_OP = 307,
|
||||
INC_OP = 308,
|
||||
DEC_OP = 309,
|
||||
LE_OP = 310,
|
||||
GE_OP = 311,
|
||||
EQ_OP = 312,
|
||||
NE_OP = 313,
|
||||
AND_OP = 314,
|
||||
OR_OP = 315,
|
||||
XOR_OP = 316,
|
||||
MUL_ASSIGN = 317,
|
||||
DIV_ASSIGN = 318,
|
||||
ADD_ASSIGN = 319,
|
||||
MOD_ASSIGN = 320,
|
||||
LEFT_ASSIGN = 321,
|
||||
RIGHT_ASSIGN = 322,
|
||||
AND_ASSIGN = 323,
|
||||
XOR_ASSIGN = 324,
|
||||
OR_ASSIGN = 325,
|
||||
SUB_ASSIGN = 326,
|
||||
LEFT_PAREN = 327,
|
||||
RIGHT_PAREN = 328,
|
||||
LEFT_BRACKET = 329,
|
||||
RIGHT_BRACKET = 330,
|
||||
LEFT_BRACE = 331,
|
||||
RIGHT_BRACE = 332,
|
||||
DOT = 333,
|
||||
COMMA = 334,
|
||||
COLON = 335,
|
||||
EQUAL = 336,
|
||||
SEMICOLON = 337,
|
||||
BANG = 338,
|
||||
DASH = 339,
|
||||
TILDE = 340,
|
||||
PLUS = 341,
|
||||
STAR = 342,
|
||||
SLASH = 343,
|
||||
PERCENT = 344,
|
||||
LEFT_ANGLE = 345,
|
||||
RIGHT_ANGLE = 346,
|
||||
VERTICAL_BAR = 347,
|
||||
CARET = 348,
|
||||
AMPERSAND = 349,
|
||||
QUESTION = 350
|
||||
LEFT_OP = 305,
|
||||
RIGHT_OP = 306,
|
||||
INC_OP = 307,
|
||||
DEC_OP = 308,
|
||||
LE_OP = 309,
|
||||
GE_OP = 310,
|
||||
EQ_OP = 311,
|
||||
NE_OP = 312,
|
||||
AND_OP = 313,
|
||||
OR_OP = 314,
|
||||
XOR_OP = 315,
|
||||
MUL_ASSIGN = 316,
|
||||
DIV_ASSIGN = 317,
|
||||
ADD_ASSIGN = 318,
|
||||
MOD_ASSIGN = 319,
|
||||
LEFT_ASSIGN = 320,
|
||||
RIGHT_ASSIGN = 321,
|
||||
AND_ASSIGN = 322,
|
||||
XOR_ASSIGN = 323,
|
||||
OR_ASSIGN = 324,
|
||||
SUB_ASSIGN = 325,
|
||||
LEFT_PAREN = 326,
|
||||
RIGHT_PAREN = 327,
|
||||
LEFT_BRACKET = 328,
|
||||
RIGHT_BRACKET = 329,
|
||||
LEFT_BRACE = 330,
|
||||
RIGHT_BRACE = 331,
|
||||
DOT = 332,
|
||||
COMMA = 333,
|
||||
COLON = 334,
|
||||
EQUAL = 335,
|
||||
SEMICOLON = 336,
|
||||
BANG = 337,
|
||||
DASH = 338,
|
||||
TILDE = 339,
|
||||
PLUS = 340,
|
||||
STAR = 341,
|
||||
SLASH = 342,
|
||||
PERCENT = 343,
|
||||
LEFT_ANGLE = 344,
|
||||
RIGHT_ANGLE = 345,
|
||||
VERTICAL_BAR = 346,
|
||||
CARET = 347,
|
||||
AMPERSAND = 348,
|
||||
QUESTION = 349
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
typedef union YYSTYPE
|
||||
{
|
||||
|
||||
|
||||
struct {
|
||||
TSourceLoc line;
|
||||
union {
|
||||
TString *string;
|
||||
float f;
|
||||
|
@ -152,7 +165,6 @@ typedef union YYSTYPE
|
|||
TSymbol* symbol;
|
||||
} lex;
|
||||
struct {
|
||||
TSourceLoc line;
|
||||
TOperator op;
|
||||
union {
|
||||
TIntermNode* intermNode;
|
||||
|
@ -166,8 +178,8 @@ typedef union YYSTYPE
|
|||
TQualifier qualifier;
|
||||
TFunction* function;
|
||||
TParameter param;
|
||||
TTypeLine typeLine;
|
||||
TTypeList* typeList;
|
||||
TField* field;
|
||||
TFieldList* fieldList;
|
||||
};
|
||||
} interm;
|
||||
|
||||
|
@ -179,6 +191,32 @@ typedef union YYSTYPE
|
|||
# define YYSTYPE_IS_DECLARED 1
|
||||
#endif
|
||||
|
||||
#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
|
||||
typedef struct YYLTYPE
|
||||
{
|
||||
int first_line;
|
||||
int first_column;
|
||||
int last_line;
|
||||
int last_column;
|
||||
} YYLTYPE;
|
||||
# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYLTYPE_IS_DECLARED 1
|
||||
# define YYLTYPE_IS_TRIVIAL 1
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef YYPARSE_PARAM
|
||||
#if defined __STDC__ || defined __cplusplus
|
||||
int yyparse (void *YYPARSE_PARAM);
|
||||
#else
|
||||
int yyparse ();
|
||||
#endif
|
||||
#else /* ! YYPARSE_PARAM */
|
||||
#if defined __STDC__ || defined __cplusplus
|
||||
int yyparse (TParseContext* context);
|
||||
#else
|
||||
int yyparse ();
|
||||
#endif
|
||||
#endif /* ! YYPARSE_PARAM */
|
||||
|
||||
#endif /* !YY_YY_GLSLANG_TAB_H_INCLUDED */
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче