Bug 690735 - upgrade ANGLE to r774 - no review, just syncing with upstream

This doesn't involve any Makefile change so should be relatively safe.

This is needed for:
  * BUILTIN_FUNCTION_EMULATION (r773,774), blocker for 665578
  * extensions validation in shaders (r745), blocker for 684853
  * major performance improvements and bug fixes
This commit is contained in:
Benoit Jacob 2011-10-01 00:03:10 -04:00
parent 10cd4a93c8
commit d0562bfee9
48 changed files with 1942 additions and 1157 deletions

View File

@ -1,15 +1,16 @@
This is the ANGLE project, from http://code.google.com/p/angleproject/.
This is the ANGLE project, from http://code.google.com/p/angleproject/
Current revision: r740
Current revision: r774
== Applied local patches ==
In this order:
angle-nspr-misc.patch - don't bother with ANGLE_OS detection with NSPR
angle-renaming.patch - rename debug.h to compilerdebug.h to avoid conflict in our makefiles
angle-intrinsic-msvc2005.patch - work around a MSVC 2005 compile error
angle-instrinsic-msvc2005.patch - work around a MSVC 2005 compile error
angle-limit-identifiers-to-250-chars.patch - see bug 675625
angle-use-xmalloc.patch - see bug 680840. Can drop this patch whenever the new preprocessor lands.
angle-mCurrentValueOffsets-size_t.patch - ANGLE bug 220 - compile fix on win64
In addition to these patches, the Makefile.in files are ours, they're not present in upsteam ANGLE.

View File

@ -1,6 +1,40 @@
# HG changeset patch
# Parent 09fc6e32e6c5d4cdcb3c01f6849ccb8cdae7e8e0
# Parent cf38970fcf3b4bee12f09b3747b7b7711bc77ad8
diff --git a/gfx/angle/angle-renaming-debug.patch b/gfx/angle/angle-renaming-debug.patch
--- a/gfx/angle/angle-renaming-debug.patch
+++ b/gfx/angle/angle-renaming-debug.patch
@@ -1,11 +1,10 @@
# HG changeset patch
-# Parent 96359f46b01fdb37e791f564495e8b2755a05233
-
+# Parent 70640278da97b0ca49e21c4bb52766b8af7db4db
diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
--- a/gfx/angle/Makefile.in
+++ b/gfx/angle/Makefile.in
@@ -73,17 +73,17 @@ CPPSRCS = \
parseConst.cpp \
ParseHelper.cpp \
PoolAlloc.cpp \
QualifierAlive.cpp \
@@ -129,17 +128,17 @@ diff --git a/gfx/angle/src/compiler/comp
#include <assert.h>
#ifdef _DEBUG
#define TRACE_ENABLED // define to enable debug message tracing
diff --git a/gfx/angle/src/compiler/osinclude.h b/gfx/angle/src/compiler/osinclude.h
--- a/gfx/angle/src/compiler/osinclude.h
+++ b/gfx/angle/src/compiler/osinclude.h
-@@ -32,17 +32,17 @@
+@@ -30,17 +30,17 @@
#include <windows.h>
#elif defined(ANGLE_OS_POSIX)
#include <pthread.h>
#include <semaphore.h>
#include <errno.h>
#endif // ANGLE_USE_NSPR
diff --git a/gfx/angle/src/libGLESv2/Texture.cpp b/gfx/angle/src/libGLESv2/Texture.cpp
--- a/gfx/angle/src/libGLESv2/Texture.cpp
+++ b/gfx/angle/src/libGLESv2/Texture.cpp

View File

@ -1,3 +1,5 @@
# HG changeset patch
# Parent f9415c10c3ebd27856500cca7a0ee0f28a16f53c
diff --git a/gfx/angle/src/compiler/preprocessor/scanner.h b/gfx/angle/src/compiler/preprocessor/scanner.h
--- a/gfx/angle/src/compiler/preprocessor/scanner.h
+++ b/gfx/angle/src/compiler/preprocessor/scanner.h

View File

@ -0,0 +1,24 @@
# HG changeset patch
# Parent 693fb23429fdbf40e272e1c48887479cc597e0bc
diff --git a/gfx/angle/src/libGLESv2/VertexDataManager.h b/gfx/angle/src/libGLESv2/VertexDataManager.h
--- a/gfx/angle/src/libGLESv2/VertexDataManager.h
+++ b/gfx/angle/src/libGLESv2/VertexDataManager.h
@@ -127,17 +127,17 @@ class VertexDataManager
Context *const mContext;
IDirect3DDevice9 *const mDevice;
StreamingVertexBuffer *mStreamingBuffer;
bool mDirtyCurrentValue[MAX_VERTEX_ATTRIBS];
StreamingVertexBuffer *mCurrentValueBuffer[MAX_VERTEX_ATTRIBS];
- UINT mCurrentValueOffsets[MAX_VERTEX_ATTRIBS];
+ std::size_t mCurrentValueOffsets[MAX_VERTEX_ATTRIBS];
// Attribute format conversion
struct FormatConverter
{
bool identity;
std::size_t outputElementSize;
void (*convertArray)(const void *in, std::size_t stride, std::size_t n, void *out);
D3DDECLTYPE d3dDeclType;

View File

@ -1,26 +1,2 @@
# HG changeset patch
# Parent 99de3c7d00973e65e295911b2b8b66c75cfe24bb
diff --git a/gfx/angle/src/compiler/osinclude.h b/gfx/angle/src/compiler/osinclude.h
--- a/gfx/angle/src/compiler/osinclude.h
+++ b/gfx/angle/src/compiler/osinclude.h
@@ -7,17 +7,19 @@
#ifndef __OSINCLUDE_H
#define __OSINCLUDE_H
//
// This file contains contains os-specific datatypes and
// declares any os-specific functions.
//
-#if defined(_WIN32) || defined(_WIN64)
+#if defined(ANGLE_USE_NSPR)
+/* no need to define anything when using NSPR */
+#elif defined(_WIN32) || defined(_WIN64)
#define ANGLE_OS_WIN
#elif defined(__APPLE__) || defined(__linux__) || \
defined(__FreeBSD__) || defined(__OpenBSD__) || \
defined(__sun)
#define ANGLE_OS_POSIX
#else
#error Unsupported platform.
#endif
# Parent 6a9ec71ad85de76c551a5398b1427d9f76430b1f

View File

@ -1,6 +1,5 @@
# HG changeset patch
# Parent 96359f46b01fdb37e791f564495e8b2755a05233
# Parent 70640278da97b0ca49e21c4bb52766b8af7db4db
diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
--- a/gfx/angle/Makefile.in
+++ b/gfx/angle/Makefile.in
@ -134,7 +133,7 @@ diff --git a/gfx/angle/src/compiler/compilerdebug.h b/gfx/angle/src/compiler/com
diff --git a/gfx/angle/src/compiler/osinclude.h b/gfx/angle/src/compiler/osinclude.h
--- a/gfx/angle/src/compiler/osinclude.h
+++ b/gfx/angle/src/compiler/osinclude.h
@@ -32,17 +32,17 @@
@@ -30,17 +30,17 @@
#include <windows.h>
#elif defined(ANGLE_OS_POSIX)
#include <pthread.h>

View File

@ -0,0 +1,145 @@
# HG changeset patch
# Parent 74f1894d664435118be4fdefd53cabfdaa9985bc
diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
--- a/gfx/angle/Makefile.in
+++ b/gfx/angle/Makefile.in
@@ -123,16 +123,18 @@ CSRCS = \
memory.c \
scanner.c \
symbols.c \
tokens.c \
$(NULL)
DEFINES += -DANGLE_USE_NSPR -DANGLE_BUILD
+EXTRA_DSO_LDOPTS = $(MOZALLOC_LIB)
+
ifdef MOZ_ANGLE
# libEGL depends on (links against!) libGLESv2!
DIRS = src/libGLESv2 src/libEGL
libs::
expand "$(MOZ_D3DX9_CAB)" -F:$(MOZ_D3DX9_DLL) "$(DIST)/bin"
expand "$(MOZ_D3DCOMPILER_CAB)" -F:$(MOZ_D3DCOMPILER_DLL) "$(DIST)/bin"
diff --git a/gfx/angle/README.mozilla b/gfx/angle/README.mozilla
--- a/gfx/angle/README.mozilla
+++ b/gfx/angle/README.mozilla
@@ -4,16 +4,17 @@ Current revision: r740
== Applied local patches ==
In this order:
angle-nspr-misc.patch - don't bother with ANGLE_OS detection with NSPR
angle-renaming.patch - rename debug.h to compilerdebug.h to avoid conflict in our makefiles
angle-intrinsic-msvc2005.patch - work around a MSVC 2005 compile error
angle-limit-identifiers-to-250-chars.patch - see bug 675625
+ angle-use-xmalloc.patch - see bug 680840. Can drop this patch whenever the new preprocessor lands.
In addition to these patches, the Makefile.in files are ours, they're not present in upsteam ANGLE.
== How to update this ANGLE copy ==
1. Unapply patches
2. Apply diff with new ANGLE version
3. Reapply patches.
diff --git a/gfx/angle/angle-limit-identifiers-to-250-chars.patch b/gfx/angle/angle-limit-identifiers-to-250-chars.patch
--- a/gfx/angle/angle-limit-identifiers-to-250-chars.patch
+++ b/gfx/angle/angle-limit-identifiers-to-250-chars.patch
@@ -1,8 +1,10 @@
+# HG changeset patch
+# Parent f9415c10c3ebd27856500cca7a0ee0f28a16f53c
diff --git a/gfx/angle/src/compiler/preprocessor/scanner.h b/gfx/angle/src/compiler/preprocessor/scanner.h
--- a/gfx/angle/src/compiler/preprocessor/scanner.h
+++ b/gfx/angle/src/compiler/preprocessor/scanner.h
@@ -44,17 +44,19 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILI
//
// scanner.h
//
diff --git a/gfx/angle/src/compiler/preprocessor/atom.c b/gfx/angle/src/compiler/preprocessor/atom.c
--- a/gfx/angle/src/compiler/preprocessor/atom.c
+++ b/gfx/angle/src/compiler/preprocessor/atom.c
@@ -48,16 +48,18 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILI
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "compiler/compilerdebug.h"
#include "compiler/preprocessor/slglobals.h"
+#include "../../../../../memory/mozalloc/mozalloc.h"
+
#undef malloc
#undef realloc
#undef free
///////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////// String table: //////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
@@ -318,31 +320,23 @@ static int AddAtomFixed(AtomTable *atabl
*/
static int GrowAtomTable(AtomTable *atable, int size)
{
int *newmap, *newrev;
if (atable->size < size) {
if (atable->amap) {
- newmap = realloc(atable->amap, sizeof(int)*size);
- newrev = realloc(atable->arev, sizeof(int)*size);
+ newmap = moz_xrealloc(atable->amap, sizeof(int)*size);
+ newrev = moz_xrealloc(atable->arev, sizeof(int)*size);
} else {
- newmap = malloc(sizeof(int)*size);
- newrev = malloc(sizeof(int)*size);
+ newmap = moz_xmalloc(sizeof(int)*size);
+ newrev = moz_xmalloc(sizeof(int)*size);
atable->size = 0;
}
- if (!newmap || !newrev) {
- /* failed to grow -- error */
- if (newmap)
- atable->amap = newmap;
- if (newrev)
- atable->arev = newrev;
- return -1;
- }
memset(&newmap[atable->size], 0, (size - atable->size) * sizeof(int));
memset(&newrev[atable->size], 0, (size - atable->size) * sizeof(int));
atable->amap = newmap;
atable->arev = newrev;
atable->size = size;
}
return 0;
} // GrowAtomTable
diff --git a/gfx/angle/src/libEGL/Makefile.in b/gfx/angle/src/libEGL/Makefile.in
--- a/gfx/angle/src/libEGL/Makefile.in
+++ b/gfx/angle/src/libEGL/Makefile.in
@@ -150,8 +150,10 @@ RCFILE = $(srcdir)/libEGL.rc
include $(topsrcdir)/config/rules.mk
EXTRA_DSO_LDOPTS = "$(MOZ_DIRECTX_SDK_PATH)/lib/$(MOZ_DIRECTX_SDK_CPU_SUFFIX)/d3d9.lib" \
"$(MOZ_DIRECTX_SDK_PATH)/lib/$(MOZ_DIRECTX_SDK_CPU_SUFFIX)/dxguid.lib" \
"$(DIST)/lib/libGLESv2.lib" \
dwmapi.lib \
delayimp.lib \
/delayload:dwmapi.dll
+
+EXTRA_DSO_LDOPTS += $(MOZALLOC_LIB)
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
@@ -159,8 +159,10 @@ CPPSRCS += \
DEFFILE = $(srcdir)/libGLESv2.def
RCFILE = $(srcdir)/libGLESv2.rc
include $(topsrcdir)/config/rules.mk
EXTRA_DSO_LDOPTS = "$(MOZ_DIRECTX_SDK_PATH)/lib/$(MOZ_DIRECTX_SDK_CPU_SUFFIX)/d3d9.lib" \
"$(MOZ_DIRECTX_SDK_PATH)/lib/$(MOZ_DIRECTX_SDK_CPU_SUFFIX)/d3dx9.lib" \
"$(MOZ_DIRECTX_SDK_PATH)/lib/$(MOZ_DIRECTX_SDK_CPU_SUFFIX)/D3DCompiler.lib"
+
+EXTRA_DSO_LDOPTS += $(MOZALLOC_LIB)

View File

@ -97,7 +97,17 @@ int main(int argc, char* argv[])
failCode = EFailUsage;
}
break;
case 'a': resources.OES_EGL_image_external = 1; break;
case 'x':
if (argv[0][2] == '=') {
switch (argv[0][3]) {
case 'i': resources.OES_EGL_image_external = 1; break;
case 'd': resources.OES_standard_derivatives = 1; break;
default: failCode = EFailUsage;
}
} else {
failCode = EFailUsage;
}
break;
default: failCode = EFailUsage;
}
} else {
@ -178,7 +188,7 @@ int main(int argc, char* argv[])
//
void usage()
{
printf("Usage: translate [-i -m -o -u -l -e -b=e -b=g -b=h -a] file1 file2 ...\n"
printf("Usage: translate [-i -m -o -u -l -e -b=e -b=g -b=h -x=i -x=d] file1 file2 ...\n"
"Where: filename : filename ending in .frag or .vert\n"
" -i : print intermediate tree\n"
" -m : map long variable names\n"
@ -189,7 +199,8 @@ void usage()
" -b=e : output GLSL ES code (this is by default)\n"
" -b=g : output GLSL code\n"
" -b=h : output HLSL code\n"
" -a : enable GL_OES_EGL_image_external\n");
" -x=i : enable GL_OES_EGL_image_external\n"
" -x=d : enable GL_OES_EGL_standard_derivatives\n");
}
//

View File

@ -1,7 +1,7 @@
#define MAJOR_VERSION 0
#define MINOR_VERSION 0
#define BUILD_VERSION 0
#define BUILD_REVISION 740
#define BUILD_REVISION 774
#define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x)

View File

@ -10,19 +10,210 @@
namespace {
const char* kFunctionEmulationSource[] = {
"float webgl_normalize_emu(float a) { return normalize(a) * 1; }",
"vec2 webgl_normalize_emu(vec2 a) { return normalize(a) * 1; }",
"vec3 webgl_normalize_emu(vec3 a) { return normalize(a) * 1; }",
"vec4 webgl_normalize_emu(vec4 a) { return normalize(a) * 1; }",
"float webgl_abs_emu(float a) { float rt = abs(a); if (rt < 0.0) rt = 0.0; return rt; }",
"vec2 webgl_abs_emu(vec2 a) { vec2 rt = abs(a); if (rt[0] < 0.0) rt[0] = 0.0; return rt; }",
"vec3 webgl_abs_emu(vec3 a) { vec3 rt = abs(a); if (rt[0] < 0.0) rt[0] = 0.0; return rt; }",
"vec4 webgl_abs_emu(vec4 a) { vec4 rt = abs(a); if (rt[0] < 0.0) rt[0] = 0.0; return rt; }",
"float webgl_sign_emu(float a) { float rt = sign(a); if (rt > 1.0) rt = 1.0; return rt; }",
"vec2 webgl_sign_emu(vec2 a) { float rt = sign(a); if (rt[0] > 1.0) rt[0] = 1.0; return rt; }",
"vec3 webgl_sign_emu(vec3 a) { float rt = sign(a); if (rt[0] > 1.0) rt[0] = 1.0; return rt; }",
"vec4 webgl_sign_emu(vec4 a) { float rt = sign(a); if (rt[0] > 1.0) rt[0] = 1.0; return rt; }",
// we use macros here instead of function definitions to work around more GLSL
// compiler bugs, in particular on NVIDIA hardware on Mac OSX. Macros are
// problematic because if the argument has side-effects they will be repeatedly
// evaluated. This is unlikely to show up in real shaders, but is something to
// consider.
const char* kFunctionEmulationVertexSource[] = {
"#error no emulation for atan(float, float)",
"vec2 webgl_atan_emu(vec2 y, vec2 x) { return vec2(atan(y[0], x[0]), atan(y[1], x[1])); }",
"vec3 webgl_atan_emu(vec3 y, vec3 x) { return vec3(atan(y[0], x[0]), atan(y[1], x[1]), atan(y[2], x[2])); }",
"vec4 webgl_atan_emu(vec4 y, vec4 x) { return vec4(atan(y[0], x[0]), atan(y[1], x[1]), atan(y[2], x[2]), atan(y[3], x[3])); }",
"#error no emulation for cos(float)",
"#error no emulation for cos(vec2)",
"#error no emulation for cos(vec3)",
"#error no emulation for cos(vec4)",
"#define webgl_distance_emu(x, y) ((x) >= (y) ? (x) - (y) : (y) - (x))",
"#error no emulation for distance(vec2, vec2)",
"#error no emulation for distance(vec3, vec3)",
"#error no emulation for distance(vec4, vec4)",
"#define webgl_dot_emu(x, y) ((x) * (y))",
"#error no emulation for dot(vec2, vec2)",
"#error no emulation for dot(vec3, vec3)",
"#error no emulation for dot(vec4, vec4)",
"#define webgl_length_emu(x) ((x) >= 0.0 ? (x) : -(x))",
"#error no emulation for length(vec2)",
"#error no emulation for length(vec3)",
"#error no emulation for length(vec4)",
"#error no emulation for mod(float, float)",
"vec2 webgl_mod_emu(vec2 x, vec2 y) { return vec2(mod(x[0], y[0]), mod(x[1], y[1])); }",
"vec3 webgl_mod_emu(vec3 x, vec3 y) { return vec3(mod(x[0], y[0]), mod(x[1], y[1]), mod(x[2], y[2])); }",
"vec4 webgl_mod_emu(vec4 x, vec4 y) { return vec4(mod(x[0], y[0]), mod(x[1], y[1]), mod(x[2], y[2]), mod(x[3], y[3])); }",
"#define webgl_normalize_emu(x) ((x) == 0.0 ? 0.0 : ((x) > 0.0 ? 1.0 : -1.0))",
"#error no emulation for normalize(vec2)",
"#error no emulation for normalize(vec3)",
"#error no emulation for normalize(vec4)",
"#define webgl_reflect_emu(I, N) ((I) - 2.0 * (N) * (I) * (N))",
"#error no emulation for reflect(vec2, vec2)",
"#error no emulation for reflect(vec3, vec3)",
"#error no emulation for reflect(vec4, vec4)"
};
const char* kFunctionEmulationFragmentSource[] = {
"#error no emulation for atan(float, float)",
"#error no emulation for atan(vec2, vec2)",
"#error no emulation for atan(vec3, vec3)",
"#error no emulation for atan(vec4, vec4)",
"webgl_emu_precision float webgl_cos_emu(webgl_emu_precision float a) { return cos(a); }",
"webgl_emu_precision vec2 webgl_cos_emu(webgl_emu_precision vec2 a) { return cos(a); }",
"webgl_emu_precision vec3 webgl_cos_emu(webgl_emu_precision vec3 a) { return cos(a); }",
"webgl_emu_precision vec4 webgl_cos_emu(webgl_emu_precision vec4 a) { return cos(a); }",
"#error no emulation for distance(float, float)",
"#error no emulation for distance(vec2, vec2)",
"#error no emulation for distance(vec3, vec3)",
"#error no emulation for distance(vec4, vec4)",
"#error no emulation for dot(float, float)",
"#error no emulation for dot(vec2, vec2)",
"#error no emulation for dot(vec3, vec3)",
"#error no emulation for dot(vec4, vec4)",
"#error no emulation for length(float)",
"#error no emulation for length(vec2)",
"#error no emulation for length(vec3)",
"#error no emulation for length(vec4)",
"#error no emulation for mod(float, float)",
"#error no emulation for mod(vec2, vec2)",
"#error no emulation for mod(vec3, vec3)",
"#error no emulation for mod(vec4, vec4)",
"#error no emulation for normalize(float)",
"#error no emulation for normalize(vec2)",
"#error no emulation for normalize(vec3)",
"#error no emulation for normalize(vec4)",
"#error no emulation for reflect(float, float)",
"#error no emulation for reflect(vec2, vec2)",
"#error no emulation for reflect(vec3, vec3)",
"#error no emulation for reflect(vec4, vec4)"
};
const bool kFunctionEmulationVertexMask[] = {
#if defined(__APPLE__)
// Work around ATI driver bugs in Mac.
false, // TFunctionAtan1_1
false, // TFunctionAtan2_2
false, // TFunctionAtan3_3
false, // TFunctionAtan4_4
false, // TFunctionCos1
false, // TFunctionCos2
false, // TFunctionCos3
false, // TFunctionCos4
true, // TFunctionDistance1_1
false, // TFunctionDistance2_2
false, // TFunctionDistance3_3
false, // TFunctionDistance4_4
true, // TFunctionDot1_1
false, // TFunctionDot2_2
false, // TFunctionDot3_3
false, // TFunctionDot4_4
true, // TFunctionLength1
false, // TFunctionLength2
false, // TFunctionLength3
false, // TFunctionLength4
false, // TFunctionMod1_1
false, // TFunctionMod2_2
false, // TFunctionMod3_3
false, // TFunctionMod4_4
true, // TFunctionNormalize1
false, // TFunctionNormalize2
false, // TFunctionNormalize3
false, // TFunctionNormalize4
true, // TFunctionReflect1_1
false, // TFunctionReflect2_2
false, // TFunctionReflect3_3
false, // TFunctionReflect4_4
#else
// Work around D3D driver bug in Win.
false, // TFunctionAtan1_1
true, // TFunctionAtan2_2
true, // TFunctionAtan3_3
true, // TFunctionAtan4_4
false, // TFunctionCos1
false, // TFunctionCos2
false, // TFunctionCos3
false, // TFunctionCos4
false, // TFunctionDistance1_1
false, // TFunctionDistance2_2
false, // TFunctionDistance3_3
false, // TFunctionDistance4_4
false, // TFunctionDot1_1
false, // TFunctionDot2_2
false, // TFunctionDot3_3
false, // TFunctionDot4_4
false, // TFunctionLength1
false, // TFunctionLength2
false, // TFunctionLength3
false, // TFunctionLength4
false, // TFunctionMod1_1
true, // TFunctionMod2_2
true, // TFunctionMod3_3
true, // TFunctionMod4_4
false, // TFunctionNormalize1
false, // TFunctionNormalize2
false, // TFunctionNormalize3
false, // TFunctionNormalize4
false, // TFunctionReflect1_1
false, // TFunctionReflect2_2
false, // TFunctionReflect3_3
false, // TFunctionReflect4_4
#endif
false // TFunctionUnknown
};
const bool kFunctionEmulationFragmentMask[] = {
false, // TFunctionAtan1_1
false, // TFunctionAtan2_2
false, // TFunctionAtan3_3
false, // TFunctionAtan4_4
#if defined(__APPLE__)
// Work around a ATI driver bug in Mac that causes crashes.
true, // TFunctionCos1
true, // TFunctionCos2
true, // TFunctionCos3
true, // TFunctionCos4
#else
false, // TFunctionCos1
false, // TFunctionCos2
false, // TFunctionCos3
false, // TFunctionCos4
#endif
false, // TFunctionDistance1_1
false, // TFunctionDistance2_2
false, // TFunctionDistance3_3
false, // TFunctionDistance4_4
false, // TFunctionDot1_1
false, // TFunctionDot2_2
false, // TFunctionDot3_3
false, // TFunctionDot4_4
false, // TFunctionLength1
false, // TFunctionLength2
false, // TFunctionLength3
false, // TFunctionLength4
false, // TFunctionMod1_1
false, // TFunctionMod2_2
false, // TFunctionMod3_3
false, // TFunctionMod4_4
false, // TFunctionNormalize1
false, // TFunctionNormalize2
false, // TFunctionNormalize3
false, // TFunctionNormalize4
false, // TFunctionReflect1_1
false, // TFunctionReflect2_2
false, // TFunctionReflect3_3
false, // TFunctionReflect4_4
false // TFunctionUnknown
};
class BuiltInFunctionEmulationMarker : public TIntermTraverser {
@ -43,66 +234,95 @@ public:
return true;
}
virtual bool visitAggregate(Visit visit, TIntermAggregate* node)
{
if (visit == PreVisit) {
// Here we handle all the built-in functions instead of the ones we
// currently identified as problematic.
switch (node->getOp()) {
case EOpLessThan:
case EOpGreaterThan:
case EOpLessThanEqual:
case EOpGreaterThanEqual:
case EOpVectorEqual:
case EOpVectorNotEqual:
case EOpMod:
case EOpPow:
case EOpAtan:
case EOpMin:
case EOpMax:
case EOpClamp:
case EOpMix:
case EOpStep:
case EOpSmoothStep:
case EOpDistance:
case EOpDot:
case EOpCross:
case EOpFaceForward:
case EOpReflect:
case EOpRefract:
case EOpMul:
break;
default:
return true;
};
const TIntermSequence& sequence = node->getSequence();
// Right now we only handle built-in functions with two parameters.
if (sequence.size() != 2)
return true;
TIntermTyped* param1 = sequence[0]->getAsTyped();
TIntermTyped* param2 = sequence[1]->getAsTyped();
if (!param1 || !param2)
return true;
bool needToEmulate = mEmulator.SetFunctionCalled(
node->getOp(), param1->getType(), param2->getType());
if (needToEmulate)
node->setUseEmulatedFunction();
}
return true;
}
private:
BuiltInFunctionEmulator& mEmulator;
};
} // anonymous namepsace
BuiltInFunctionEmulator::BuiltInFunctionEmulator()
: mFunctionGroupMask(TFunctionGroupAll)
BuiltInFunctionEmulator::BuiltInFunctionEmulator(ShShaderType shaderType)
{
}
void BuiltInFunctionEmulator::SetFunctionGroupMask(
unsigned int functionGroupMask)
{
mFunctionGroupMask = functionGroupMask;
if (shaderType == SH_FRAGMENT_SHADER) {
mFunctionMask = kFunctionEmulationFragmentMask;
mFunctionSource = kFunctionEmulationFragmentSource;
} else {
mFunctionMask = kFunctionEmulationVertexMask;
mFunctionSource = kFunctionEmulationVertexSource;
}
}
bool BuiltInFunctionEmulator::SetFunctionCalled(
TOperator op, const TType& returnType)
TOperator op, const TType& param)
{
TBuiltInFunction function = IdentifyFunction(op, returnType);
if (function == TFunctionUnknown)
TBuiltInFunction function = IdentifyFunction(op, param);
return SetFunctionCalled(function);
}
bool BuiltInFunctionEmulator::SetFunctionCalled(
TOperator op, const TType& param1, const TType& param2)
{
TBuiltInFunction function = IdentifyFunction(op, param1, param2);
return SetFunctionCalled(function);
}
bool BuiltInFunctionEmulator::SetFunctionCalled(
BuiltInFunctionEmulator::TBuiltInFunction function) {
if (function == TFunctionUnknown || mFunctionMask[function] == false)
return false;
for (size_t i = 0; i < mFunctions.size(); ++i) {
if (mFunctions[i] == function)
return true;
}
switch (function) {
case TFunctionNormalize1:
case TFunctionNormalize2:
case TFunctionNormalize3:
case TFunctionNormalize4:
if (mFunctionGroupMask & TFunctionGroupNormalize) {
mFunctions.push_back(function);
return true;
}
break;
case TFunctionAbs1:
case TFunctionAbs2:
case TFunctionAbs3:
case TFunctionAbs4:
if (mFunctionGroupMask & TFunctionGroupAbs) {
mFunctions.push_back(function);
return true;
}
break;
case TFunctionSign1:
case TFunctionSign2:
case TFunctionSign3:
case TFunctionSign4:
if (mFunctionGroupMask & TFunctionGroupSign) {
mFunctions.push_back(function);
return true;
}
break;
default:
UNREACHABLE();
break;
}
return false;
mFunctions.push_back(function);
return true;
}
void BuiltInFunctionEmulator::OutputEmulatedFunctionDefinition(
@ -112,33 +332,82 @@ void BuiltInFunctionEmulator::OutputEmulatedFunctionDefinition(
return;
out << "// BEGIN: Generated code for built-in function emulation\n\n";
if (withPrecision) {
out << "#if defined(GL_FRAGMENT_PRECISION_HIGH) && (GL_FRAGMENT_PRECISION_HIGH == 1)\n"
<< "precision highp float;\n"
out << "#if defined(GL_FRAGMENT_PRECISION_HIGH)\n"
<< "#define webgl_emulation_precision highp\n"
<< "#else\n"
<< "precision mediump float;\n"
<< "#define webgl_emulation_precision mediump\n"
<< "#endif\n\n";
} else {
out << "#define webgl_emulation_precision\n\n";
}
for (size_t i = 0; i < mFunctions.size(); ++i) {
out << kFunctionEmulationSource[mFunctions[i]] << "\n\n";
out << mFunctionSource[mFunctions[i]] << "\n\n";
}
out << "// END: Generated code for built-in function emulation\n\n";
}
BuiltInFunctionEmulator::TBuiltInFunction
BuiltInFunctionEmulator::IdentifyFunction(TOperator op, const TType& returnType)
BuiltInFunctionEmulator::IdentifyFunction(
TOperator op, const TType& param)
{
if (param.getNominalSize() > 4)
return TFunctionUnknown;
unsigned int function = TFunctionUnknown;
if (op == EOpNormalize)
function = TFunctionNormalize1;
else if (op == EOpAbs)
function = TFunctionAbs1;
else if (op == EOpSign)
function = TFunctionSign1;
else
return static_cast<TBuiltInFunction>(function);
switch (op) {
case EOpCos:
function = TFunctionCos1;
break;
case EOpLength:
function = TFunctionLength1;
break;
case EOpNormalize:
function = TFunctionNormalize1;
break;
default:
break;
}
if (function == TFunctionUnknown)
return TFunctionUnknown;
if (param.isVector())
function += param.getNominalSize() - 1;
return static_cast<TBuiltInFunction>(function);
}
if (returnType.isVector())
function += returnType.getNominalSize() - 1;
BuiltInFunctionEmulator::TBuiltInFunction
BuiltInFunctionEmulator::IdentifyFunction(
TOperator op, const TType& param1, const TType& param2)
{
// Right now for all the emulated functions with two parameters, the two
// parameters have the same type.
if (param1.isVector() != param2.isVector() ||
param1.getNominalSize() != param2.getNominalSize() ||
param1.getNominalSize() > 4)
return TFunctionUnknown;
unsigned int function = TFunctionUnknown;
switch (op) {
case EOpAtan:
function = TFunctionAtan1_1;
break;
case EOpDistance:
function = TFunctionDistance1_1;
break;
case EOpDot:
function = TFunctionDot1_1;
break;
case EOpMod:
function = TFunctionMod1_1;
break;
case EOpReflect:
function = TFunctionReflect1_1;
break;
default:
break;
}
if (function == TFunctionUnknown)
return TFunctionUnknown;
if (param1.isVector())
function += param1.getNominalSize() - 1;
return static_cast<TBuiltInFunction>(function);
}
@ -151,6 +420,11 @@ void BuiltInFunctionEmulator::MarkBuiltInFunctionsForEmulation(
root->traverse(&marker);
}
void BuiltInFunctionEmulator::Cleanup()
{
mFunctions.clear();
}
//static
TString BuiltInFunctionEmulator::GetEmulatedFunctionName(
const TString& name)

View File

@ -7,21 +7,11 @@
#ifndef COMPILIER_BUILT_IN_FUNCTION_EMULATOR_H_
#define COMPILIER_BUILT_IN_FUNCTION_EMULATOR_H_
#include "GLSLANG/ShaderLang.h"
#include "compiler/InfoSink.h"
#include "compiler/intermediate.h"
//
// Built-in function groups. We only list the ones that might need to be
// emulated in certain os/drivers, assuming they are no more than 32.
//
enum TBuiltInFunctionGroup {
TFunctionGroupNormalize = 1 << 0,
TFunctionGroupAbs = 1 << 1,
TFunctionGroupSign = 1 << 2,
TFunctionGroupAll =
TFunctionGroupNormalize | TFunctionGroupAbs | TFunctionGroupSign
};
//
// This class decides which built-in functions need to be replaced with the
// emulated ones.
@ -29,23 +19,15 @@ enum TBuiltInFunctionGroup {
//
class BuiltInFunctionEmulator {
public:
BuiltInFunctionEmulator();
// functionGroupMask is a bitmap of TBuiltInFunctionGroup.
// We only emulate functions that are marked by this mask and are actually
// called in a given shader.
// By default the value is TFunctionGroupAll.
void SetFunctionGroupMask(unsigned int functionGroupMask);
BuiltInFunctionEmulator(ShShaderType shaderType);
// Records that a function is called by the shader and might needs to be
// emulated. If the function's group is not in mFunctionGroupFilter, this
// becomes an no-op.
// Returns true if the function call needs to be replaced with an emulated
// one.
// TODO(zmo): for now, an operator and a return type is enough to identify
// the function we want to emulate. Should make this more flexible to
// handle any functions.
bool SetFunctionCalled(TOperator op, const TType& returnType);
bool SetFunctionCalled(TOperator op, const TType& param);
bool SetFunctionCalled(
TOperator op, const TType& param1, const TType& param2);
// Output function emulation definition. This should be before any other
// shader source.
@ -53,6 +35,8 @@ public:
void MarkBuiltInFunctionsForEmulation(TIntermNode* root);
void Cleanup();
// "name(" becomes "webgl_name_emu(".
static TString GetEmulatedFunctionName(const TString& name);
@ -61,26 +45,59 @@ private:
// Built-in functions.
//
enum TBuiltInFunction {
TFunctionNormalize1 = 0, // float normalize(float);
TFunctionAtan1_1 = 0, // float atan(float, float);
TFunctionAtan2_2, // vec2 atan(vec2, vec2);
TFunctionAtan3_3, // vec3 atan(vec3, vec2);
TFunctionAtan4_4, // vec4 atan(vec4, vec2);
TFunctionCos1, // float cos(float);
TFunctionCos2, // vec2 cos(vec2);
TFunctionCos3, // vec3 cos(vec3);
TFunctionCos4, // vec4 cos(vec4);
TFunctionDistance1_1, // float distance(float, float);
TFunctionDistance2_2, // vec2 distance(vec2, vec2);
TFunctionDistance3_3, // vec3 distance(vec3, vec3);
TFunctionDistance4_4, // vec4 distance(vec4, vec4);
TFunctionDot1_1, // float dot(float, float);
TFunctionDot2_2, // vec2 dot(vec2, vec2);
TFunctionDot3_3, // vec3 dot(vec3, vec3);
TFunctionDot4_4, // vec4 dot(vec4, vec4);
TFunctionLength1, // float length(float);
TFunctionLength2, // float length(vec2);
TFunctionLength3, // float length(vec3);
TFunctionLength4, // float length(vec4);
TFunctionMod1_1, // float mod(float, float);
TFunctionMod2_2, // vec2 mod(vec2, vec2);
TFunctionMod3_3, // vec3 mod(vec3, vec3);
TFunctionMod4_4, // vec4 mod(vec4, vec4);
TFunctionNormalize1, // float normalize(float);
TFunctionNormalize2, // vec2 normalize(vec2);
TFunctionNormalize3, // vec3 normalize(vec3);
TFunctionNormalize4, // fec4 normalize(vec4);
TFunctionAbs1, // float abs(float);
TFunctionAbs2, // vec2 abs(vec2);
TFunctionAbs3, // vec3 abs(vec3);
TFunctionAbs4, // vec4 abs(vec4);
TFunctionSign1, // float sign(float);
TFunctionSign2, // vec2 sign(vec2);
TFunctionSign3, // vec3 sign(vec3);
TFunctionSign4, // vec4 sign(vec4);
TFunctionNormalize4, // vec4 normalize(vec4);
TFunctionReflect1_1, // float reflect(float, float);
TFunctionReflect2_2, // vec2 reflect(vec2, vec2);
TFunctionReflect3_3, // vec3 reflect(vec3, vec3);
TFunctionReflect4_4, // vec4 reflect(vec4, vec4);
TFunctionUnknown
};
// Same TODO as SetFunctionCalled.
TBuiltInFunction IdentifyFunction(TOperator op, const TType& returnType);
TBuiltInFunction IdentifyFunction(TOperator op, const TType& param);
TBuiltInFunction IdentifyFunction(
TOperator op, const TType& param1, const TType& param2);
TVector<TBuiltInFunction> mFunctions;
unsigned int mFunctionGroupMask; // a bitmap of TBuiltInFunctionGroup.
bool SetFunctionCalled(TBuiltInFunction function);
std::vector<TBuiltInFunction> mFunctions;
const bool* mFunctionMask; // a boolean flag for each function.
const char** mFunctionSource;
};
#endif // COMPILIER_BUILT_IN_FUNCTION_EMULATOR_H_

View File

@ -88,7 +88,8 @@ TShHandleBase::~TShHandleBase() {
TCompiler::TCompiler(ShShaderType type, ShShaderSpec spec)
: shaderType(type),
shaderSpec(spec)
shaderSpec(spec),
builtInFunctionEmulator(type)
{
}
@ -208,6 +209,8 @@ void TCompiler::clearResults()
attribs.clear();
uniforms.clear();
builtInFunctionEmulator.Cleanup();
}
bool TCompiler::detectRecursion(TIntermNode* root)

View File

@ -23,7 +23,7 @@ TString mapLongName(int id, const TString& name, bool isVarying)
} // anonymous namespace
MapLongVariableNames::MapLongVariableNames(
TMap<TString, TString>& varyingLongNameMap)
std::map<std::string, std::string>& varyingLongNameMap)
: mVaryingLongNameMap(varyingLongNameMap)
{
}
@ -57,13 +57,13 @@ bool MapLongVariableNames::visitLoop(Visit, TIntermLoop* node)
TString MapLongVariableNames::mapVaryingLongName(const TString& name)
{
TMap<TString, TString>::const_iterator it = mVaryingLongNameMap.find(name);
std::map<std::string, std::string>::const_iterator it = mVaryingLongNameMap.find(name.c_str());
if (it != mVaryingLongNameMap.end())
return (*it).second;
return (*it).second.c_str();
int id = mVaryingLongNameMap.size();
TString mappedName = mapLongName(id, name, true);
mVaryingLongNameMap.insert(
TMap<TString, TString>::value_type(name, mappedName));
std::map<std::string, std::string>::value_type(name.c_str(), mappedName.c_str()));
return mappedName;
}

View File

@ -19,7 +19,7 @@
// longer than MAX_IDENTIFIER_NAME_SIZE to MAX_IDENTIFIER_NAME_SIZE.
class MapLongVariableNames : public TIntermTraverser {
public:
MapLongVariableNames(TMap<TString, TString>& varyingLongNameMap);
MapLongVariableNames(std::map<std::string, std::string>& varyingLongNameMap);
virtual void visitSymbol(TIntermSymbol*);
virtual bool visitLoop(Visit, TIntermLoop*);
@ -27,7 +27,7 @@ public:
private:
TString mapVaryingLongName(const TString& name);
TMap<TString, TString>& mVaryingLongNameMap;
std::map<std::string, std::string>& mVaryingLongNameMap;
};
#endif // COMPILER_MAP_LONG_VARIABLE_NAMES_H_

View File

@ -436,6 +436,8 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate* node)
{
bool visitChildren = true;
TInfoSinkBase& out = objSink();
TString preString;
bool delayedWrite = false;
switch (node->getOp())
{
case EOpSequence: {
@ -582,34 +584,38 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate* node)
}
break;
case EOpLessThan: writeTriplet(visit, "lessThan(", ", ", ")"); break;
case EOpGreaterThan: writeTriplet(visit, "greaterThan(", ", ", ")"); break;
case EOpLessThanEqual: writeTriplet(visit, "lessThanEqual(", ", ", ")"); break;
case EOpGreaterThanEqual: writeTriplet(visit, "greaterThanEqual(", ", ", ")"); break;
case EOpVectorEqual: writeTriplet(visit, "equal(", ", ", ")"); break;
case EOpVectorNotEqual: writeTriplet(visit, "notEqual(", ", ", ")"); break;
case EOpLessThan: preString = "lessThan("; delayedWrite = true; break;
case EOpGreaterThan: preString = "greaterThan("; delayedWrite = true; break;
case EOpLessThanEqual: preString = "lessThanEqual("; delayedWrite = true; break;
case EOpGreaterThanEqual: preString = "greaterThanEqual("; delayedWrite = true; break;
case EOpVectorEqual: preString = "equal("; delayedWrite = true; break;
case EOpVectorNotEqual: preString = "notEqual("; delayedWrite = true; break;
case EOpComma: writeTriplet(visit, NULL, ", ", NULL); break;
case EOpMod: writeTriplet(visit, "mod(", ", ", ")"); break;
case EOpPow: writeTriplet(visit, "pow(", ", ", ")"); break;
case EOpAtan: writeTriplet(visit, "atan(", ", ", ")"); break;
case EOpMin: writeTriplet(visit, "min(", ", ", ")"); break;
case EOpMax: writeTriplet(visit, "max(", ", ", ")"); break;
case EOpClamp: writeTriplet(visit, "clamp(", ", ", ")"); break;
case EOpMix: writeTriplet(visit, "mix(", ", ", ")"); break;
case EOpStep: writeTriplet(visit, "step(", ", ", ")"); break;
case EOpSmoothStep: writeTriplet(visit, "smoothstep(", ", ", ")"); break;
case EOpMod: preString = "mod("; delayedWrite = true; break;
case EOpPow: preString = "pow("; delayedWrite = true; break;
case EOpAtan: preString = "atan("; delayedWrite = true; break;
case EOpMin: preString = "min("; delayedWrite = true; break;
case EOpMax: preString = "max("; delayedWrite = true; break;
case EOpClamp: preString = "clamp("; delayedWrite = true; break;
case EOpMix: preString = "mix("; delayedWrite = true; break;
case EOpStep: preString = "step("; delayedWrite = true; break;
case EOpSmoothStep: preString = "smoothstep("; delayedWrite = true; break;
case EOpDistance: writeTriplet(visit, "distance(", ", ", ")"); break;
case EOpDot: writeTriplet(visit, "dot(", ", ", ")"); break;
case EOpCross: writeTriplet(visit, "cross(", ", ", ")"); break;
case EOpFaceForward: writeTriplet(visit, "faceforward(", ", ", ")"); break;
case EOpReflect: writeTriplet(visit, "reflect(", ", ", ")"); break;
case EOpRefract: writeTriplet(visit, "refract(", ", ", ")"); break;
case EOpMul: writeTriplet(visit, "matrixCompMult(", ", ", ")"); break;
case EOpDistance: preString = "distance("; delayedWrite = true; break;
case EOpDot: preString = "dot("; delayedWrite = true; break;
case EOpCross: preString = "cross("; delayedWrite = true; break;
case EOpFaceForward: preString = "faceforward("; delayedWrite = true; break;
case EOpReflect: preString = "reflect("; delayedWrite = true; break;
case EOpRefract: preString = "refract("; delayedWrite = true; break;
case EOpMul: preString = "matrixCompMult("; delayedWrite = true; break;
default: UNREACHABLE(); break;
}
if (delayedWrite && visit == PreVisit && node->getUseEmulatedFunction())
preString = BuiltInFunctionEmulator::GetEmulatedFunctionName(preString);
if (delayedWrite)
writeTriplet(visit, preString.c_str(), ", ", ")");
return visitChildren;
}

View File

@ -136,7 +136,7 @@ void OutputHLSL::header()
{
if (mReferencedUniforms.find(name.c_str()) != mReferencedUniforms.end())
{
uniforms += "uniform " + typeString(type) + " " + decorate(name) + arrayString(type) + ";\n";
uniforms += "uniform " + typeString(type) + " " + decorateUniform(name, type.isArray()) + arrayString(type) + ";\n";
}
}
else if (qualifier == EvqVaryingIn || qualifier == EvqInvariantVaryingIn)
@ -300,7 +300,7 @@ void OutputHLSL::header()
{
if (mReferencedUniforms.find(name.c_str()) != mReferencedUniforms.end())
{
uniforms += "uniform " + typeString(type) + " " + decorate(name) + arrayString(type) + ";\n";
uniforms += "uniform " + typeString(type) + " " + decorateUniform(name, type.isArray()) + arrayString(type) + ";\n";
}
}
else if (qualifier == EvqAttribute)
@ -729,17 +729,22 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node)
if (qualifier == EvqUniform)
{
mReferencedUniforms.insert(name.c_str());
out << decorateUniform(name, node->isArray());
}
else if (qualifier == EvqAttribute)
{
mReferencedAttributes.insert(name.c_str());
out << decorate(name);
}
else if (qualifier == EvqVaryingOut || qualifier == EvqInvariantVaryingOut || qualifier == EvqVaryingIn || qualifier == EvqInvariantVaryingIn)
{
mReferencedVaryings.insert(name.c_str());
out << decorate(name);
}
else
{
out << decorate(name);
}
out << decorate(name);
}
}
@ -1610,7 +1615,7 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
}
outputLineDirective(node->getLine());
out << "}\n";
out << ";}\n";
if (node->getType() == ELoopDoWhile)
{
@ -1844,7 +1849,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
}
outputLineDirective(node->getLine());
out << "}\n";
out << ";}\n";
initial += 255 * increment;
iterations -= 255;
@ -2045,14 +2050,7 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI
typedef std::vector<TType> ParameterArray;
ParameterArray ctorParameters;
if (parameters)
{
for (TIntermSequence::const_iterator parameter = parameters->begin(); parameter != parameters->end(); parameter++)
{
ctorParameters.push_back((*parameter)->getAsTyped()->getType());
}
}
else if (type.getStruct())
if (type.getStruct())
{
mStructNames.insert(decorate(name));
@ -2081,6 +2079,13 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI
ctorParameters.push_back(*fields[i].type);
}
}
else if (parameters)
{
for (TIntermSequence::const_iterator parameter = parameters->begin(); parameter != parameters->end(); parameter++)
{
ctorParameters.push_back((*parameter)->getAsTyped()->getType());
}
}
else UNREACHABLE();
TString constructor;
@ -2337,13 +2342,21 @@ TString OutputHLSL::structLookup(const TString &typeName)
TString OutputHLSL::decorate(const TString &string)
{
if (string.substr(0, 3) != "gl_" && string.substr(0, 3) != "dx_")
if (string.compare(0, 3, "gl_") != 0 && string.compare(0, 3, "dx_") != 0)
{
return "_" + string;
}
else
return string;
}
TString OutputHLSL::decorateUniform(const TString &string, bool array)
{
if (array)
{
return string;
return "ar_" + string; // Allows identifying arrays of size 1
}
return decorate(string);
}
}

View File

@ -31,7 +31,8 @@ class OutputHLSL : public TIntermTraverser
static TString qualifierString(TQualifier qualifier);
static TString arrayString(const TType &type);
static TString initializer(const TType &type);
static TString decorate(const TString &string); // Prepend an underscore to avoid naming clashes
static TString decorate(const TString &string); // Prepends an underscore to avoid naming clashes
static TString decorateUniform(const TString &string, bool array);
protected:
void header();

View File

@ -448,16 +448,16 @@ bool TParseContext::reservedErrorCheck(int line, const TString& identifier)
{
static const char* reservedErrMsg = "reserved built-in name";
if (!symbolTable.atBuiltInLevel()) {
if (identifier.substr(0, 3) == TString("gl_")) {
if (identifier.compare(0, 3, "gl_") == 0) {
error(line, reservedErrMsg, "gl_", "");
return true;
}
if (shaderSpec == SH_WEBGL_SPEC) {
if (identifier.substr(0, 6) == TString("webgl_")) {
if (identifier.compare(0, 6, "webgl_") == 0) {
error(line, reservedErrMsg, "webgl_", "");
return true;
}
if (identifier.substr(0, 7) == TString("_webgl_")) {
if (identifier.compare(0, 7, "_webgl_") == 0) {
error(line, reservedErrMsg, "_webgl_", "");
return true;
}
@ -929,7 +929,8 @@ bool TParseContext::extensionErrorCheck(int line, const TString& extension)
error(line, "extension", extension.c_str(), "is not supported");
return true;
}
if (iter->second == EBhDisable) {
// In GLSL ES, an extension's default behavior is "disable".
if (iter->second == EBhDisable || iter->second == EBhUndefined) {
error(line, "extension", extension.c_str(), "is disabled");
return true;
}

View File

@ -101,7 +101,7 @@ private:
TVariableInfoList uniforms; // Active uniforms in the compiled shader.
// Pair of long varying varibale name <originalName, mappedName>.
TMap<TString, TString> varyingLongNameMap;
std::map<std::string, std::string> varyingLongNameMap;
};
//

View File

@ -425,7 +425,10 @@ public:
protected:
TIntermTyped* operand;
bool useEmulatedFunction; // if set to true, replace the function call by an emulated one.
// If set to true, replace the built-in function call with an emulated one
// to work around driver bugs.
bool useEmulatedFunction;
};
typedef TVector<TIntermNode*> TIntermSequence;
@ -436,8 +439,8 @@ typedef TMap<TString, TString> TPragmaTable;
//
class TIntermAggregate : public TIntermOperator {
public:
TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(0), endLine(0) { }
TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(0) { }
TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(0), endLine(0), useEmulatedFunction(false) { }
TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(0), useEmulatedFunction(false) { }
~TIntermAggregate() { delete pragmaTable; }
virtual TIntermAggregate* getAsAggregate() { return this; }
@ -460,6 +463,9 @@ public:
void setEndLine(TSourceLoc line) { endLine = line; }
TSourceLoc getEndLine() const { return endLine; }
void setUseEmulatedFunction() { useEmulatedFunction = true; }
bool getUseEmulatedFunction() { return useEmulatedFunction; }
protected:
TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
@ -471,6 +477,10 @@ protected:
bool debug;
TPragmaTable *pragmaTable;
TSourceLoc endLine;
// If set to true, replace the built-in function call with an emulated one
// to work around driver bugs.
bool useEmulatedFunction;
};
//

View File

@ -12,13 +12,11 @@
// declares any os-specific functions.
//
#if defined(ANGLE_USE_NSPR)
/* no need to define anything when using NSPR */
#elif defined(_WIN32) || defined(_WIN64)
#if defined(_WIN32) || defined(_WIN64)
#define ANGLE_OS_WIN
#elif defined(__APPLE__) || defined(__linux__) || \
defined(__FreeBSD__) || defined(__OpenBSD__) || \
defined(__sun)
defined(__sun) || defined(ANDROID)
#define ANGLE_OS_POSIX
#else
#error Unsupported platform.

View File

@ -6,16 +6,134 @@
#include "Context.h"
#include <algorithm>
#include <sstream>
#include "compiler/debug.h"
#include "stl_utils.h"
#include "token_type.h"
static bool isMacroNameReserved(const std::string* name)
{
ASSERT(name);
// Names prefixed with "GL_" are reserved.
if (name->substr(0, 3) == "GL_")
return true;
// Names containing two consecutive underscores are reserved.
if (name->find("__") != std::string::npos)
return true;
return false;
}
namespace pp
{
Context::Context(int count, const char* const string[], const int length[],
TokenVector* output)
: input(count, string, length),
output(output),
lexer(NULL)
Context::Context()
: mLexer(NULL),
mInput(NULL),
mOutput(NULL)
{
}
Context::~Context()
{
destroyLexer();
}
bool Context::init()
{
return initLexer();
// TODO(alokp): Define built-in macros here so that we do not need to
// define them everytime in process().
}
bool Context::process(int count,
const char* const string[],
const int length[],
TokenVector* output)
{
ASSERT((count >=0) && (string != NULL) && (output != NULL));
// Setup.
mInput = new Input(count, string, length);
mOutput = output;
defineBuiltInMacro("GL_ES", 1);
// Parse.
bool success = parse();
// Cleanup.
reset();
return success;
}
bool Context::defineMacro(pp::Token::Location location,
pp::Macro::Type type,
std::string* name,
pp::TokenVector* parameters,
pp::TokenVector* replacements)
{
std::auto_ptr<Macro> macro(new Macro(type, name, parameters, replacements));
if (isMacroNameReserved(name))
{
// TODO(alokp): Report error.
return false;
}
if (isMacroDefined(name))
{
// TODO(alokp): Report error.
return false;
}
mMacros[*name] = macro.release();
return true;
}
bool Context::undefineMacro(const std::string* name)
{
MacroSet::iterator iter = mMacros.find(*name);
if (iter == mMacros.end())
{
// TODO(alokp): Report error.
return false;
}
mMacros.erase(iter);
return true;
}
bool Context::isMacroDefined(const std::string* name)
{
return mMacros.find(*name) != mMacros.end();
}
// Reset to initialized state.
void Context::reset()
{
std::for_each(mMacros.begin(), mMacros.end(), DeleteSecond());
mMacros.clear();
delete mInput;
mInput = NULL;
mOutput = NULL;
}
void Context::defineBuiltInMacro(const std::string& name, int value)
{
std::ostringstream stream;
stream << value;
Token* token = new Token(0, INT_CONSTANT, new std::string(stream.str()));
TokenVector* replacements = new pp::TokenVector(1, token);
mMacros[name] = new Macro(Macro::kTypeObj,
new std::string(name),
NULL,
replacements);
}
} // namespace pp

View File

@ -7,6 +7,9 @@
#ifndef COMPILER_PREPROCESSOR_CONTEXT_H_
#define COMPILER_PREPROCESSOR_CONTEXT_H_
#include <map>
#include "common/angleutils.h"
#include "Input.h"
#include "Macro.h"
#include "Token.h"
@ -14,16 +17,42 @@
namespace pp
{
struct Context
class Context
{
Context(int count, const char* const string[], const int length[],
TokenVector* output);
public:
Context();
~Context();
Input input;
TokenVector* output;
bool init();
bool process(int count, const char* const string[], const int length[],
TokenVector* output);
void* lexer; // Lexer handle.
MacroSet macros; // Defined macros.
void* lexer() { return mLexer; }
int readInput(char* buf, int maxSize);
TokenVector* output() { return mOutput; }
bool defineMacro(pp::Token::Location location,
pp::Macro::Type type,
std::string* name,
pp::TokenVector* parameters,
pp::TokenVector* replacements);
bool undefineMacro(const std::string* name);
bool isMacroDefined(const std::string* name);
private:
DISALLOW_COPY_AND_ASSIGN(Context);
typedef std::map<std::string, Macro*> MacroSet;
void reset();
bool initLexer();
void destroyLexer();
void defineBuiltInMacro(const std::string& name, int value);
bool parse();
void* mLexer; // Lexer handle.
Input* mInput;
TokenVector* mOutput;
MacroSet mMacros; // Defined macros.
};
} // namespace pp

View File

@ -7,27 +7,44 @@
#ifndef COMPILER_PREPROCESSOR_MACRO_H_
#define COMPILER_PREPROCESSOR_MACRO_H_
#include <map>
#include <string>
#include <vector>
#include "common/angleutils.h"
#include "Token.h"
namespace pp
{
struct Macro
class Macro
{
public:
enum Type
{
kTypeObj,
kTypeFunc
};
Type type;
std::string identifier;
TokenVector parameters;
TokenVector replacements;
// Takes ownership of pointer parameters.
Macro(Type type,
std::string* name,
TokenVector* parameters,
TokenVector* replacements);
~Macro();
Type type() const { return mType; }
const std::string* identifier() const { return mName; }
const TokenVector* parameters() const { return mParameters; }
const TokenVector* replacements() const { return mReplacements; }
private:
DISALLOW_COPY_AND_ASSIGN(Macro);
Type mType;
std::string* mName;
TokenVector* mParameters;
TokenVector* mReplacements;
};
typedef std::map<std::string, Macro> MacroSet;
} // namespace pp
#endif COMPILER_PREPROCESSOR_MACRO_H_

View File

@ -6,12 +6,30 @@
#include "Preprocessor.h"
#include <algorithm>
#include "compiler/debug.h"
#include "Context.h"
#include "stl_utils.h"
namespace pp
{
Preprocessor::Preprocessor() : mContext(NULL)
{
}
Preprocessor::~Preprocessor()
{
delete mContext;
}
bool Preprocessor::init()
{
mContext = new Context;
return mContext->init();
}
bool Preprocessor::process(int count,
const char* const string[],
const int length[])
@ -20,22 +38,14 @@ bool Preprocessor::process(int count,
if ((count < 0) || (string == NULL))
return false;
clearResults();
Context context(count, string, length, &mTokens);
if (!initLexer(&context))
return false;
reset();
bool success = parse(&context);
destroyLexer(&context);
return success;
return mContext->process(count, string, length, &mTokens);
}
void Preprocessor::clearResults()
void Preprocessor::reset()
{
for (TokenVector::iterator i = mTokens.begin(); i != mTokens.end(); ++i)
delete (*i);
std::for_each(mTokens.begin(), mTokens.end(), Delete());
mTokens.clear();
}

View File

@ -13,27 +13,27 @@
namespace pp
{
struct Context;
class Context;
class Preprocessor
{
public:
Preprocessor() { }
Preprocessor();
~Preprocessor();
bool init();
bool process(int count, const char* const string[], const int length[]);
TokenIterator begin() const { return mTokens.begin(); }
TokenIterator end() const { return mTokens.end(); }
private:
DISALLOW_COPY_AND_ASSIGN(Preprocessor);
static bool initLexer(Context* context);
static void destroyLexer(Context* context);
static bool parse(Context* context);
void clearResults();
// Reset to initialized state.
void reset();
Context* mContext;
TokenVector mTokens; // Output.
};

View File

@ -40,9 +40,6 @@ std::ostream& operator<<(std::ostream& out, const Token& token)
{
switch (token.type())
{
case SPACE:
out << " ";
break;
case INT_CONSTANT:
case FLOAT_CONSTANT:
case IDENTIFIER:

View File

@ -10,6 +10,8 @@
#include <string>
#include <vector>
#include "common/angleutils.h"
namespace pp
{
@ -29,6 +31,8 @@ class Token
const std::string* value() const { return mValue; }
private:
DISALLOW_COPY_AND_ASSIGN(Token);
Location mLocation;
int mType;
std::string* mValue;

View File

@ -26,7 +26,6 @@ IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh.
#include "compiler/debug.h"
#include "Context.h"
#include "pp_tab.h"
#include "Preprocessor.h"
#define YY_USER_ACTION \
do { \
@ -36,9 +35,9 @@ IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh.
} while(0);
#define YY_INPUT(buf, result, maxSize) \
result = readInput(yyextra, buf, maxSize);
static int readInput(pp::Context* context, char* buf, int maxSize);
result = yyextra->readInput(buf, maxSize);
static std::string* extractMacroName(const char* str, int len);
%}
%option noyywrap nounput never-interactive
@ -64,9 +63,15 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".")
{HASH} { return HASH; }
{HASH}define { return HASH_DEFINE_OBJ; }
{HASH}define{HSPACE}+/{IDENTIFIER}"(" { return HASH_DEFINE_FUNC; }
{HASH}undef { return HASH_UNDEF; }
{HASH}define{HSPACE}+{IDENTIFIER}/[ \t\n] {
yylval->sval = extractMacroName(yytext, yyleng);
return HASH_DEFINE_OBJ;
}
{HASH}define{HSPACE}+{IDENTIFIER}/"(" {
yylval->sval = extractMacroName(yytext, yyleng);
return HASH_DEFINE_FUNC;
}
{HASH}undef{HSPACE}+ { return HASH_UNDEF; }
{HASH}if { return HASH_IF; }
{HASH}ifdef { return HASH_IFDEF; }
@ -99,7 +104,7 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".")
{PUNCTUATOR} { return yytext[0]; }
{HSPACE}+ { return SPACE; }
[ \t\v\f]+ { /* Ignore whitespace */ }
\n {
++yylineno; yycolumn = 0;
@ -110,24 +115,42 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".")
%%
int readInput(pp::Context* context, char* buf, int maxSize)
std::string* extractMacroName(const char* str, int len)
{
yyscan_t lexer = context->lexer;
ASSERT(lexer);
// The input string is of the form {HASH}define{HSPACE}+{IDENTIFIER}
// We just need to find the last HSPACE.
ASSERT(str && (len > 8)); // strlen("#define ") == 8;
std::string* name = NULL;
for (int i = len - 1; i >= 0; --i)
{
if ((str[i] == ' ') || (str[i] == '\t'))
{
name = new std::string(str + i + 1, len - i - 1);
break;
}
}
ASSERT(name);
return name;
}
namespace pp {
int Context::readInput(char* buf, int maxSize)
{
int nread = YY_NULL;
while (!context->input.eof() &&
(context->input.error() == pp::Input::kErrorNone) &&
while (!mInput->eof() &&
(mInput->error() == pp::Input::kErrorNone) &&
(nread == YY_NULL))
{
int line = 0, file = 0;
pp::Token::decodeLocation(yyget_lineno(lexer), &line, &file);
file = context->input.stringIndex();
yyset_lineno(pp::Token::encodeLocation(line, file), lexer);
pp::Token::decodeLocation(yyget_lineno(mLexer), &line, &file);
file = mInput->stringIndex();
yyset_lineno(pp::Token::encodeLocation(line, file), mLexer);
nread = context->input.read(buf, maxSize);
nread = mInput->read(buf, maxSize);
if (context->input.error() == pp::Input::kErrorUnexpectedEOF)
if (mInput->error() == pp::Input::kErrorUnexpectedEOF)
{
// TODO(alokp): Report error.
}
@ -135,27 +158,23 @@ int readInput(pp::Context* context, char* buf, int maxSize)
return nread;
}
namespace pp {
bool Preprocessor::initLexer(Context* context)
bool Context::initLexer()
{
ASSERT(context->lexer == NULL);
ASSERT(mLexer == NULL);
yyscan_t lexer = 0;
if (yylex_init_extra(context, &lexer))
if (yylex_init_extra(this, &mLexer))
return false;
context->lexer = lexer;
yyrestart(0, lexer);
yyrestart(0, mLexer);
return true;
}
void Preprocessor::destroyLexer(Context* context)
void Context::destroyLexer()
{
ASSERT(context->lexer);
ASSERT(mLexer);
yylex_destroy(context->lexer);
context->lexer = 0;
yylex_destroy(mLexer);
mLexer = NULL;
}
} // namespace pp

View File

@ -23,9 +23,8 @@ WHICH GENERATES THE GLSL ES PARSER.
// This file is auto-generated by generate_glslang_parser.sh. DO NOT EDIT!
#include "Context.h"
#include "Preprocessor.h"
#define YYLEX_PARAM context->lexer
#define YYLEX_PARAM context->lexer()
#define YYDEBUG 1
%}
@ -37,7 +36,6 @@ WHICH GENERATES THE GLSL ES PARSER.
%union {
int ival;
std::string* sval;
std::vector<std::string*>* slist;
pp::Token* tval;
pp::TokenVector* tlist;
}
@ -48,27 +46,18 @@ static void yyerror(YYLTYPE* llocp,
pp::Context* context,
const char* reason);
static void defineMacro(pp::Context* context,
YYLTYPE* llocp,
pp::Macro::Type type,
const std::string* identifier,
std::vector<std::string*>* parameters,
pp::TokenVector* replacements);
static void undefineMacro(pp::Context* context, const std::string* identifier);
static bool isMacroDefined(pp::Context* context, const std::string* identifier);
static void pushConditionalBlock(pp::Context* context, bool condition);
static void popConditionalBlock(pp::Context* context);
%}
%token HASH HASH_DEFINE_OBJ HASH_DEFINE_FUNC HASH_UNDEF
%token HASH HASH_UNDEF
%token HASH_IF HASH_IFDEF HASH_IFNDEF HASH_ELSE HASH_ELIF HASH_ENDIF DEFINED
%token HASH_ERROR HASH_PRAGMA HASH_EXTENSION HASH_VERSION HASH_LINE
%token SPACE
%token <sval> HASH_DEFINE_OBJ HASH_DEFINE_FUNC
%token <sval> INT_CONSTANT FLOAT_CONSTANT IDENTIFIER
%type <ival> operator
%type <slist> parameter_list
%type <tval> conditional_token token
%type <tlist> text_line replacement_token_list conditional_token_list token_list
%type <tlist> parameter_list replacement_list conditional_list token_list
%%
input
@ -77,41 +66,41 @@ input
;
line
: text_line {
// TODO(alokp): Expand macros.
pp::TokenVector* out = context->output;
out->insert(out->end(), $1->begin(), $1->end());
delete $1;
}
: text_line
| control_line
;
text_line
: '\n' { $$ = NULL; }
| token_list '\n' { $$ = $1; }
: '\n'
| token_list '\n' {
// TODO(alokp): Expand macros.
pp::TokenVector* out = context->output();
out->insert(out->end(), $1->begin(), $1->end());
delete $1;
}
;
control_line
: HASH '\n'
| HASH_DEFINE_OBJ IDENTIFIER replacement_token_list '\n' {
defineMacro(context, & @2, pp::Macro::kTypeObj, $2, NULL, $3);
| HASH_DEFINE_OBJ replacement_list '\n' {
context->defineMacro(@1.first_line, pp::Macro::kTypeObj, $1, NULL, $2);
}
| HASH_DEFINE_FUNC IDENTIFIER '(' parameter_list ')' replacement_token_list '\n' {
defineMacro(context, & @2, pp::Macro::kTypeFunc, $2, $4, $6);
| HASH_DEFINE_FUNC '(' parameter_list ')' replacement_list '\n' {
context->defineMacro(@1.first_line, pp::Macro::kTypeFunc, $1, $3, $5);
}
| HASH_UNDEF IDENTIFIER '\n' {
undefineMacro(context, $2);
context->undefineMacro($2);
}
| HASH_IF conditional_token_list '\n' {
| HASH_IF conditional_list '\n' {
pushConditionalBlock(context, $2 ? true : false);
}
| HASH_IFDEF IDENTIFIER '\n' {
pushConditionalBlock(context, isMacroDefined(context, $2));
pushConditionalBlock(context, context->isMacroDefined($2));
}
| HASH_IFNDEF IDENTIFIER '\n' {
pushConditionalBlock(context, !isMacroDefined(context, $2));
pushConditionalBlock(context, !context->isMacroDefined($2));
}
| HASH_ELIF conditional_token_list '\n' {
| HASH_ELIF conditional_list '\n' {
}
| HASH_ELSE '\n' {
}
@ -125,39 +114,29 @@ control_line
| HASH_LINE '\n'
;
replacement_token_list
: /* empty */ { $$ = NULL }
replacement_list
: /* empty */ { $$ = NULL; }
| token_list
;
conditional_token_list
: conditional_token {
$$ = new pp::TokenVector;
$$->push_back($1);
}
| conditional_token_list conditional_token {
$$ = $1;
$$->push_back($2);
}
;
conditional_token
: DEFINED IDENTIFIER {
}
| DEFINED '(' IDENTIFIER ')' {
}
| token
;
parameter_list
: /* empty */ { $$ = NULL; }
| IDENTIFIER {
$$ = new std::vector<std::string*>();
$$->push_back($1);
$$ = new pp::TokenVector;
$$->push_back(new pp::Token(@1.first_line, IDENTIFIER, $1));
}
| parameter_list ',' IDENTIFIER {
$$ = $1;
$$->push_back($3);
$$->push_back(new pp::Token(@3.first_line, IDENTIFIER, $3));
}
conditional_list
: conditional_token {
$$ = new pp::TokenVector;
$$->push_back($1);
}
| conditional_list conditional_token {
$$ = $1;
$$->push_back($2);
}
;
@ -172,13 +151,18 @@ token_list
}
;
conditional_token
: DEFINED IDENTIFIER {
}
| DEFINED '(' IDENTIFIER ')' {
}
| token
;
token
: operator {
$$ = new pp::Token(@1.first_line, $1, NULL);
}
| SPACE {
$$ = new pp::Token(@1.first_line, SPACE, NULL);
}
| INT_CONSTANT {
$$ = new pp::Token(@1.first_line, INT_CONSTANT, $1);
}
@ -223,24 +207,6 @@ void yyerror(YYLTYPE* llocp, pp::Context* context, const char* reason)
{
}
void defineMacro(pp::Context* context,
YYLTYPE* llocp,
pp::Macro::Type type,
const std::string* identifier,
std::vector<std::string*>* parameters,
pp::TokenVector* replacements)
{
}
void undefineMacro(pp::Context* context, const std::string* identifier)
{
}
bool isMacroDefined(pp::Context* context, const std::string* identifier)
{
return false;
}
void pushConditionalBlock(pp::Context* context, bool condition)
{
}
@ -250,10 +216,10 @@ void popConditionalBlock(pp::Context* context)
}
namespace pp {
bool Preprocessor::parse(Context* context)
bool Context::parse()
{
yydebug = 1;
return yyparse(context) == 0 ? true : false;
return yyparse(this) == 0 ? true : false;
}
} // namespace pp

View File

@ -380,48 +380,38 @@ struct yy_trans_info
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
static yyconst flex_int16_t yy_acclist[57] =
static yyconst flex_int16_t yy_accept[105] =
{ 0,
24, 23, 21, 23, 22, 23, 20, 23, 20, 23,
18, 23, 18, 23, 17, 23, 17, 23, 21, 23,
1, 23, 21, 19, 19, 18, 18, 17, 17, 21,
1, 1, 19, 18, 17, 5, 19, 17, 17, 9,
8, 16, 17, 10, 12, 6, 4, 11, 17, 2,
7, 13,16387, 15, 8195, 14
} ;
0, 0, 24, 23, 21, 22, 20, 20, 18, 18,
17, 17, 21, 1, 21, 19, 19, 18, 0, 0,
0, 18, 17, 17, 21, 1, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 19, 18, 17, 0,
0, 0, 0, 0, 5, 0, 0, 0, 0, 0,
19, 17, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 17, 0, 9, 8, 0, 0,
0, 0, 0, 16, 0, 0, 0, 17, 0, 10,
12, 0, 6, 0, 0, 0, 0, 11, 0, 0,
7, 13, 4, 0, 0, 0, 15, 0, 0, 2,
static yyconst flex_int16_t yy_accept[104] =
{ 0,
1, 1, 1, 2, 3, 5, 7, 9, 11, 13,
15, 17, 19, 21, 23, 24, 25, 26, 27, 27,
27, 27, 28, 29, 30, 31, 32, 33, 33, 33,
33, 33, 33, 33, 33, 33, 33, 34, 35, 36,
36, 36, 36, 36, 36, 37, 37, 37, 37, 37,
37, 38, 39, 39, 39, 39, 39, 39, 39, 39,
39, 39, 39, 39, 39, 40, 40, 41, 42, 42,
42, 42, 42, 42, 43, 43, 43, 43, 44, 44,
45, 46, 46, 47, 47, 47, 48, 48, 50, 51,
51, 52, 53, 53, 54, 54, 55, 55, 55, 56,
56, 57, 57
3, 0, 14, 0
} ;
static yyconst flex_int32_t yy_ec[256] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
4, 4, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 2, 4, 1, 5, 1, 4, 4, 1, 6,
4, 4, 7, 4, 7, 8, 4, 9, 10, 10,
10, 10, 10, 10, 10, 11, 11, 4, 4, 4,
4, 4, 4, 1, 12, 12, 12, 12, 13, 12,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 15, 14, 14,
4, 1, 4, 4, 14, 1, 16, 12, 12, 17,
1, 2, 5, 1, 6, 1, 5, 5, 1, 7,
5, 5, 8, 5, 8, 9, 5, 10, 11, 11,
11, 11, 11, 11, 11, 12, 12, 5, 5, 5,
5, 5, 5, 1, 13, 13, 13, 13, 14, 13,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 16, 15, 15,
5, 1, 5, 5, 15, 1, 17, 13, 13, 18,
18, 19, 20, 14, 21, 14, 14, 22, 23, 24,
25, 26, 14, 27, 28, 29, 30, 31, 14, 32,
14, 14, 4, 4, 4, 4, 1, 1, 1, 1,
19, 20, 21, 15, 22, 15, 15, 23, 24, 25,
26, 27, 15, 28, 29, 30, 31, 32, 15, 33,
15, 15, 5, 5, 5, 5, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@ -438,119 +428,112 @@ static yyconst flex_int32_t yy_ec[256] =
1, 1, 1, 1, 1
} ;
static yyconst flex_int32_t yy_meta[33] =
static yyconst flex_int32_t yy_meta[34] =
{ 0,
1, 2, 1, 1, 1, 3, 1, 1, 4, 4,
4, 5, 6, 7, 7, 5, 5, 6, 5, 7,
1, 2, 3, 1, 1, 1, 3, 1, 1, 4,
4, 4, 5, 6, 7, 7, 5, 5, 6, 5,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7
7, 7, 7
} ;
static yyconst flex_int16_t yy_base[109] =
static yyconst flex_int16_t yy_base[111] =
{ 0,
0, 17, 171, 172, 168, 172, 172, 3, 27, 52,
0, 151, 27, 69, 166, 26, 28, 1, 21, 40,
0, 0, 0, 148, 50, 0, 0, 148, 42, 146,
143, 136, 138, 143, 47, 66, 69, 0, 139, 140,
60, 141, 130, 127, 65, 131, 138, 136, 125, 74,
83, 127, 129, 130, 130, 126, 121, 127, 126, 126,
124, 121, 122, 111, 120, 113, 172, 172, 117, 108,
110, 114, 114, 172, 108, 111, 108, 103, 101, 172,
172, 85, 172, 79, 81, 172, 71, 0, 71, 51,
172, 172, 44, 65, 28, 172, 42, 19, 172, 9,
0, 18, 184, 185, 11, 185, 185, 21, 28, 53,
0, 164, 39, 71, 12, 32, 34, 1, 39, 44,
0, 0, 0, 162, 64, 0, 0, 162, 46, 160,
157, 150, 152, 157, 70, 47, 65, 0, 153, 154,
62, 155, 144, 141, 67, 145, 152, 150, 139, 76,
85, 141, 143, 144, 144, 140, 135, 141, 140, 140,
138, 135, 136, 125, 134, 127, 185, 185, 131, 122,
124, 128, 128, 185, 122, 125, 122, 125, 123, 185,
185, 112, 185, 120, 113, 127, 97, 0, 107, 86,
185, 185, 105, 76, 81, 34, 185, 97, 10, 185,
172, 172, 100, 104, 108, 111, 116, 121
185, 103, 185, 185, 110, 114, 118, 121, 126, 132
} ;
static yyconst flex_int16_t yy_def[109] =
static yyconst flex_int16_t yy_def[111] =
{ 0,
103, 103, 102, 102, 102, 102, 102, 102, 102, 102,
104, 104, 102, 102, 102, 105, 105, 9, 18, 102,
106, 10, 104, 104, 102, 14, 14, 102, 102, 102,
102, 102, 102, 102, 102, 102, 102, 106, 104, 102,
102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
102, 104, 102, 102, 102, 102, 102, 102, 102, 102,
102, 102, 102, 102, 104, 102, 102, 102, 102, 102,
102, 102, 102, 102, 102, 102, 102, 104, 102, 102,
102, 102, 102, 102, 102, 102, 102, 104, 102, 102,
102, 102, 102, 107, 102, 102, 108, 102, 102, 108,
105, 105, 104, 104, 104, 104, 104, 104, 104, 104,
106, 106, 104, 104, 104, 107, 107, 9, 18, 104,
108, 10, 106, 106, 104, 14, 14, 104, 104, 104,
104, 104, 104, 104, 104, 104, 104, 108, 106, 104,
104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
104, 106, 104, 104, 104, 104, 104, 104, 104, 104,
104, 104, 104, 104, 106, 104, 104, 104, 104, 104,
104, 104, 104, 104, 104, 104, 104, 106, 104, 104,
104, 104, 104, 104, 104, 104, 104, 106, 104, 104,
104, 104, 104, 104, 109, 104, 104, 110, 104, 104,
102, 0, 102, 102, 102, 102, 102, 102
104, 110, 104, 0, 104, 104, 104, 104, 104, 104
} ;
static yyconst flex_int16_t yy_nxt[205] =
static yyconst flex_int16_t yy_nxt[219] =
{ 0,
4, 5, 6, 7, 4, 7, 7, 8, 9, 10,
10, 16, 16, 16, 99, 102, 12, 4, 13, 6,
7, 14, 7, 7, 8, 9, 10, 10, 25, 19,
19, 26, 102, 12, 17, 18, 18, 19, 35, 20,
35, 21, 101, 35, 20, 35, 36, 99, 37, 37,
37, 25, 98, 50, 26, 51, 51, 51, 21, 17,
22, 22, 22, 41, 20, 42, 94, 96, 43, 20,
27, 95, 94, 44, 37, 37, 37, 37, 37, 37,
54, 59, 51, 51, 51, 28, 29, 55, 60, 30,
31, 51, 51, 51, 32, 93, 92, 91, 33, 34,
4, 5, 6, 5, 7, 4, 7, 7, 8, 9,
10, 10, 15, 15, 15, 15, 104, 12, 4, 13,
6, 5, 7, 14, 7, 7, 8, 9, 10, 10,
16, 16, 16, 104, 103, 12, 17, 18, 18, 19,
25, 20, 15, 21, 26, 35, 20, 35, 19, 19,
35, 36, 35, 37, 37, 37, 37, 37, 37, 99,
21, 17, 22, 22, 22, 25, 20, 15, 41, 26,
42, 20, 27, 43, 37, 37, 37, 50, 44, 51,
51, 51, 95, 54, 59, 51, 51, 51, 28, 29,
55, 60, 30, 31, 51, 51, 51, 32, 100, 100,
97, 33, 34, 101, 100, 100, 93, 96, 95, 101,
11, 11, 11, 11, 11, 11, 11, 23, 23, 23,
23, 16, 90, 16, 38, 38, 38, 97, 89, 88,
97, 97, 97, 100, 100, 100, 100, 100, 87, 86,
85, 84, 83, 82, 81, 80, 79, 78, 77, 76,
75, 74, 73, 72, 71, 70, 69, 68, 67, 66,
65, 64, 63, 62, 61, 58, 57, 56, 53, 52,
49, 48, 47, 46, 45, 40, 39, 15, 24, 15,
102, 3, 102, 102, 102, 102, 102, 102, 102, 102,
102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
23, 16, 94, 16, 38, 38, 38, 98, 93, 92,
98, 98, 98, 102, 102, 102, 102, 102, 102, 91,
90, 89, 88, 87, 86, 85, 84, 83, 82, 81,
80, 79, 78, 77, 76, 75, 74, 73, 72, 71,
70, 69, 68, 67, 66, 65, 64, 63, 62, 61,
58, 57, 56, 53, 52, 49, 48, 47, 46, 45,
40, 39, 24, 104, 3, 104, 104, 104, 104, 104,
104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
102, 102, 102, 102
104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
104, 104, 104, 104, 104, 104, 104, 104
} ;
static yyconst flex_int16_t yy_chk[205] =
static yyconst flex_int16_t yy_chk[219] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 8, 8, 8, 100, 18, 1, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 13, 19,
19, 13, 18, 2, 9, 9, 9, 9, 16, 9,
17, 9, 98, 16, 9, 17, 20, 97, 20, 20,
20, 25, 95, 35, 25, 35, 35, 35, 9, 10,
10, 10, 10, 29, 10, 29, 94, 93, 29, 10,
14, 90, 89, 29, 36, 36, 36, 37, 37, 37,
41, 45, 50, 50, 50, 14, 14, 41, 45, 14,
14, 51, 51, 51, 14, 87, 85, 84, 14, 14,
1, 1, 5, 15, 5, 15, 18, 1, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
8, 8, 8, 18, 99, 2, 9, 9, 9, 9,
13, 9, 13, 9, 13, 16, 9, 17, 19, 19,
16, 20, 17, 20, 20, 20, 36, 36, 36, 96,
9, 10, 10, 10, 10, 25, 10, 25, 29, 25,
29, 10, 14, 29, 37, 37, 37, 35, 29, 35,
35, 35, 95, 41, 45, 50, 50, 50, 14, 14,
41, 45, 14, 14, 51, 51, 51, 14, 98, 98,
103, 103, 103, 103, 103, 103, 103, 104, 104, 104,
104, 105, 82, 105, 106, 106, 106, 107, 79, 78,
107, 107, 107, 108, 108, 108, 108, 108, 77, 76,
75, 73, 72, 71, 70, 69, 66, 65, 64, 63,
62, 61, 60, 59, 58, 57, 56, 55, 54, 53,
52, 49, 48, 47, 46, 44, 43, 42, 40, 39,
34, 33, 32, 31, 30, 28, 24, 15, 12, 5,
3, 102, 102, 102, 102, 102, 102, 102, 102, 102,
102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
94, 14, 14, 98, 102, 102, 93, 90, 89, 102,
105, 105, 105, 105, 105, 105, 105, 106, 106, 106,
106, 107, 87, 107, 108, 108, 108, 109, 86, 85,
109, 109, 109, 110, 110, 110, 110, 110, 110, 84,
82, 79, 78, 77, 76, 75, 73, 72, 71, 70,
69, 66, 65, 64, 63, 62, 61, 60, 59, 58,
57, 56, 55, 54, 53, 52, 49, 48, 47, 46,
44, 43, 42, 40, 39, 34, 33, 32, 31, 30,
28, 24, 12, 3, 104, 104, 104, 104, 104, 104,
104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
102, 102, 102, 102
104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
104, 104, 104, 104, 104, 104, 104, 104
} ;
/* Table of booleans, true if rule could match eol. */
static yyconst flex_int32_t yy_rule_can_match_eol[24] =
{ 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, };
#define YY_TRAILING_MASK 0x2000
#define YY_TRAILING_HEAD_MASK 0x4000
#define REJECT \
{ \
*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ \
yy_cp = yyg->yy_full_match; /* restore poss. backed-over text */ \
yyg->yy_lp = yyg->yy_full_lp; /* restore orig. accepting pos. */ \
yyg->yy_state_ptr = yyg->yy_full_state; /* restore orig. state */ \
yy_current_state = *yyg->yy_state_ptr; /* restore curr. state */ \
++yyg->yy_lp; \
goto find_rule; \
}
/* The intent behind this definition is that it'll catch
* any uses of REJECT which flex missed.
*/
#define REJECT reject_used_but_not_detected
#define yymore() yymore_used_but_not_detected
#define YY_MORE_ADJ 0
#define YY_RESTORE_YY_MORE_OFFSET
@ -571,7 +554,6 @@ IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh.
#include "compiler/debug.h"
#include "Context.h"
#include "pp_tab.h"
#include "Preprocessor.h"
#define YY_USER_ACTION \
do { \
@ -581,9 +563,9 @@ IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh.
} while(0);
#define YY_INPUT(buf, result, maxSize) \
result = readInput(yyextra, buf, maxSize);
static int readInput(pp::Context* context, char* buf, int maxSize);
result = yyextra->readInput(buf, maxSize);
static std::string* extractMacroName(const char* str, int len);
#define INITIAL 0
@ -617,17 +599,6 @@ struct yyguts_t
int yylineno_r;
int yy_flex_debug_r;
yy_state_type *yy_state_buf;
yy_state_type *yy_state_ptr;
char *yy_full_match;
int yy_lp;
/* These are only needed for trailing context rules,
* but there's no conditional variable for that yet. */
int yy_looking_for_trail_begin;
int yy_full_lp;
int *yy_full_state;
char *yytext_r;
int yy_more_flag;
int yy_more_len;
@ -844,12 +815,6 @@ YY_DECL
YY_USER_INIT;
#endif
/* Create the reject buffer large enough to save one state per allowed character. */
if ( ! yyg->yy_state_buf )
yyg->yy_state_buf = (yy_state_type *)ppalloc(YY_STATE_BUF_SIZE ,yyscanner);
if ( ! yyg->yy_state_buf )
YY_FATAL_ERROR( "out of dynamic memory in pplex()" );
if ( ! yyg->yy_start )
yyg->yy_start = 1; /* first start state */
@ -882,64 +847,30 @@ YY_DECL
yy_current_state = yyg->yy_start;
yy_current_state += YY_AT_BOL();
yyg->yy_state_ptr = yyg->yy_state_buf;
*yyg->yy_state_ptr++ = yy_current_state;
yy_match:
do
{
register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
if ( yy_accept[yy_current_state] )
{
yyg->yy_last_accepting_state = yy_current_state;
yyg->yy_last_accepting_cpos = yy_cp;
}
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 103 )
if ( yy_current_state >= 105 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
*yyg->yy_state_ptr++ = yy_current_state;
++yy_cp;
}
while ( yy_current_state != 102 );
while ( yy_current_state != 104 );
yy_cp = yyg->yy_last_accepting_cpos;
yy_current_state = yyg->yy_last_accepting_state;
yy_find_action:
yy_current_state = *--yyg->yy_state_ptr;
yyg->yy_lp = yy_accept[yy_current_state];
find_rule: /* we branch to this label when backing up */
for ( ; ; ) /* until we find what rule we matched */
{
if ( yyg->yy_lp && yyg->yy_lp < yy_accept[yy_current_state + 1] )
{
yy_act = yy_acclist[yyg->yy_lp];
if ( yy_act & YY_TRAILING_HEAD_MASK ||
yyg->yy_looking_for_trail_begin )
{
if ( yy_act == yyg->yy_looking_for_trail_begin )
{
yyg->yy_looking_for_trail_begin = 0;
yy_act &= ~YY_TRAILING_HEAD_MASK;
break;
}
}
else if ( yy_act & YY_TRAILING_MASK )
{
yyg->yy_looking_for_trail_begin = yy_act & ~YY_TRAILING_MASK;
yyg->yy_looking_for_trail_begin |= YY_TRAILING_HEAD_MASK;
}
else
{
yyg->yy_full_match = yy_cp;
yyg->yy_full_state = yyg->yy_state_ptr;
yyg->yy_full_lp = yyg->yy_lp;
break;
}
++yyg->yy_lp;
goto find_rule;
}
--yy_cp;
yy_current_state = *--yyg->yy_state_ptr;
yyg->yy_lp = yy_accept[yy_current_state];
}
yy_act = yy_accept[yy_current_state];
YY_DO_BEFORE_ACTION;
@ -959,17 +890,37 @@ do_action: /* This label is used only to access EOF actions. */
switch ( yy_act )
{ /* beginning of action switch */
case 0: /* must back up */
/* undo the effects of YY_DO_BEFORE_ACTION */
*yy_cp = yyg->yy_hold_char;
yy_cp = yyg->yy_last_accepting_cpos;
yy_current_state = yyg->yy_last_accepting_state;
goto yy_find_action;
case 1:
YY_RULE_SETUP
{ return HASH; }
YY_BREAK
case 2:
/* rule 2 can match eol */
*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */
yyg->yy_c_buf_p = yy_cp -= 1;
YY_DO_BEFORE_ACTION; /* set up yytext again */
YY_RULE_SETUP
{ return HASH_DEFINE_OBJ; }
{
yylval->sval = extractMacroName(yytext, yyleng);
return HASH_DEFINE_OBJ;
}
YY_BREAK
case 3:
*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */
yyg->yy_c_buf_p = yy_cp -= 1;
YY_DO_BEFORE_ACTION; /* set up yytext again */
YY_RULE_SETUP
{ return HASH_DEFINE_FUNC; }
{
yylval->sval = extractMacroName(yytext, yyleng);
return HASH_DEFINE_FUNC;
}
YY_BREAK
case 4:
YY_RULE_SETUP
@ -1050,7 +1001,7 @@ YY_RULE_SETUP
YY_BREAK
case 21:
YY_RULE_SETUP
{ return SPACE; }
{ /* Ignore whitespace */ }
YY_BREAK
case 22:
/* rule 22 can match eol */
@ -1131,7 +1082,8 @@ ECHO;
else
{
yy_cp = yyg->yy_c_buf_p;
yy_cp = yyg->yy_last_accepting_cpos;
yy_current_state = yyg->yy_last_accepting_state;
goto yy_find_action;
}
}
@ -1257,8 +1209,37 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
while ( num_to_read <= 0 )
{ /* Not enough room in the buffer - grow it. */
YY_FATAL_ERROR(
"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
/* just a shorter name for the current buffer */
YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
int yy_c_buf_p_offset =
(int) (yyg->yy_c_buf_p - b->yy_ch_buf);
if ( b->yy_is_our_buffer )
{
int new_size = b->yy_buf_size * 2;
if ( new_size <= 0 )
b->yy_buf_size += b->yy_buf_size / 8;
else
b->yy_buf_size *= 2;
b->yy_ch_buf = (char *)
/* Include room in for 2 EOB chars. */
pprealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
}
else
/* Can't grow it, we don't own it. */
b->yy_ch_buf = 0;
if ( ! b->yy_ch_buf )
YY_FATAL_ERROR(
"fatal error - scanner input buffer overflow" );
yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
number_to_move - 1;
}
@ -1319,20 +1300,21 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
yy_current_state = yyg->yy_start;
yy_current_state += YY_AT_BOL();
yyg->yy_state_ptr = yyg->yy_state_buf;
*yyg->yy_state_ptr++ = yy_current_state;
for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
{
register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
if ( yy_accept[yy_current_state] )
{
yyg->yy_last_accepting_state = yy_current_state;
yyg->yy_last_accepting_cpos = yy_cp;
}
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 103 )
if ( yy_current_state >= 105 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
*yyg->yy_state_ptr++ = yy_current_state;
}
return yy_current_state;
@ -1347,18 +1329,22 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
{
register int yy_is_jam;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
register char *yy_cp = yyg->yy_c_buf_p;
register YY_CHAR yy_c = 1;
if ( yy_accept[yy_current_state] )
{
yyg->yy_last_accepting_state = yy_current_state;
yyg->yy_last_accepting_cpos = yy_cp;
}
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 103 )
if ( yy_current_state >= 105 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
yy_is_jam = (yy_current_state == 102);
if ( ! yy_is_jam )
*yyg->yy_state_ptr++ = yy_current_state;
yy_is_jam = (yy_current_state == 104);
return yy_is_jam ? 0 : yy_current_state;
}
@ -2123,11 +2109,6 @@ static int yy_init_globals (yyscan_t yyscanner)
yyg->yy_start_stack_depth = 0;
yyg->yy_start_stack = NULL;
yyg->yy_state_buf = 0;
yyg->yy_state_ptr = 0;
yyg->yy_full_match = 0;
yyg->yy_lp = 0;
/* Defined in main.c */
#ifdef YY_STDINIT
yyin = stdin;
@ -2163,9 +2144,6 @@ int pplex_destroy (yyscan_t yyscanner)
ppfree(yyg->yy_start_stack ,yyscanner );
yyg->yy_start_stack = NULL;
ppfree ( yyg->yy_state_buf , yyscanner);
yyg->yy_state_buf = NULL;
/* Reset the globals. This is important in a non-reentrant scanner so the next time
* pplex() is called, initialization will occur. */
yy_init_globals( yyscanner);
@ -2224,24 +2202,42 @@ void ppfree (void * ptr , yyscan_t yyscanner)
#define YYTABLES_NAME "yytables"
int readInput(pp::Context* context, char* buf, int maxSize)
std::string* extractMacroName(const char* str, int len)
{
yyscan_t lexer = context->lexer;
ASSERT(lexer);
// The input string is of the form {HASH}define{HSPACE}+{IDENTIFIER}
// We just need to find the last HSPACE.
ASSERT(str && (len > 8)); // strlen("#define ") == 8;
std::string* name = NULL;
for (int i = len - 1; i >= 0; --i)
{
if ((str[i] == ' ') || (str[i] == '\t'))
{
name = new std::string(str + i + 1, len - i - 1);
break;
}
}
ASSERT(name);
return name;
}
namespace pp {
int Context::readInput(char* buf, int maxSize)
{
int nread = YY_NULL;
while (!context->input.eof() &&
(context->input.error() == pp::Input::kErrorNone) &&
while (!mInput->eof() &&
(mInput->error() == pp::Input::kErrorNone) &&
(nread == YY_NULL))
{
int line = 0, file = 0;
pp::Token::decodeLocation(ppget_lineno(lexer), &line, &file);
file = context->input.stringIndex();
ppset_lineno(pp::Token::encodeLocation(line, file),lexer);
pp::Token::decodeLocation(ppget_lineno(mLexer), &line, &file);
file = mInput->stringIndex();
ppset_lineno(pp::Token::encodeLocation(line, file),mLexer);
nread = context->input.read(buf, maxSize);
nread = mInput->read(buf, maxSize);
if (context->input.error() == pp::Input::kErrorUnexpectedEOF)
if (mInput->error() == pp::Input::kErrorUnexpectedEOF)
{
// TODO(alokp): Report error.
}
@ -2249,27 +2245,23 @@ int readInput(pp::Context* context, char* buf, int maxSize)
return nread;
}
namespace pp {
bool Preprocessor::initLexer(Context* context)
bool Context::initLexer()
{
ASSERT(context->lexer == NULL);
ASSERT(mLexer == NULL);
yyscan_t lexer = 0;
if (pplex_init_extra(context,&lexer))
if (pplex_init_extra(this,&mLexer))
return false;
context->lexer = lexer;
pprestart(0,lexer);
pprestart(0,mLexer);
return true;
}
void Preprocessor::destroyLexer(Context* context)
void Context::destroyLexer()
{
ASSERT(context->lexer);
ASSERT(mLexer);
pplex_destroy(context->lexer);
context->lexer = 0;
pplex_destroy(mLexer);
mLexer = NULL;
}
} // namespace pp

View File

@ -75,48 +75,46 @@
know about them. */
enum yytokentype {
HASH = 258,
HASH_DEFINE_OBJ = 259,
HASH_DEFINE_FUNC = 260,
HASH_UNDEF = 261,
HASH_IF = 262,
HASH_IFDEF = 263,
HASH_IFNDEF = 264,
HASH_ELSE = 265,
HASH_ELIF = 266,
HASH_ENDIF = 267,
DEFINED = 268,
HASH_ERROR = 269,
HASH_PRAGMA = 270,
HASH_EXTENSION = 271,
HASH_VERSION = 272,
HASH_LINE = 273,
SPACE = 274,
INT_CONSTANT = 275,
FLOAT_CONSTANT = 276,
IDENTIFIER = 277
HASH_UNDEF = 259,
HASH_IF = 260,
HASH_IFDEF = 261,
HASH_IFNDEF = 262,
HASH_ELSE = 263,
HASH_ELIF = 264,
HASH_ENDIF = 265,
DEFINED = 266,
HASH_ERROR = 267,
HASH_PRAGMA = 268,
HASH_EXTENSION = 269,
HASH_VERSION = 270,
HASH_LINE = 271,
HASH_DEFINE_OBJ = 272,
HASH_DEFINE_FUNC = 273,
INT_CONSTANT = 274,
FLOAT_CONSTANT = 275,
IDENTIFIER = 276
};
#endif
/* Tokens. */
#define HASH 258
#define HASH_DEFINE_OBJ 259
#define HASH_DEFINE_FUNC 260
#define HASH_UNDEF 261
#define HASH_IF 262
#define HASH_IFDEF 263
#define HASH_IFNDEF 264
#define HASH_ELSE 265
#define HASH_ELIF 266
#define HASH_ENDIF 267
#define DEFINED 268
#define HASH_ERROR 269
#define HASH_PRAGMA 270
#define HASH_EXTENSION 271
#define HASH_VERSION 272
#define HASH_LINE 273
#define SPACE 274
#define INT_CONSTANT 275
#define FLOAT_CONSTANT 276
#define IDENTIFIER 277
#define HASH_UNDEF 259
#define HASH_IF 260
#define HASH_IFDEF 261
#define HASH_IFNDEF 262
#define HASH_ELSE 263
#define HASH_ELIF 264
#define HASH_ENDIF 265
#define DEFINED 266
#define HASH_ERROR 267
#define HASH_PRAGMA 268
#define HASH_EXTENSION 269
#define HASH_VERSION 270
#define HASH_LINE 271
#define HASH_DEFINE_OBJ 272
#define HASH_DEFINE_FUNC 273
#define INT_CONSTANT 274
#define FLOAT_CONSTANT 275
#define IDENTIFIER 276
@ -133,9 +131,8 @@
// This file is auto-generated by generate_glslang_parser.sh. DO NOT EDIT!
#include "Context.h"
#include "Preprocessor.h"
#define YYLEX_PARAM context->lexer
#define YYLEX_PARAM context->lexer()
#define YYDEBUG 1
@ -163,7 +160,6 @@ typedef union YYSTYPE
{
int ival;
std::string* sval;
std::vector<std::string*>* slist;
pp::Token* tval;
pp::TokenVector* tlist;
}
@ -197,14 +193,6 @@ static void yyerror(YYLTYPE* llocp,
pp::Context* context,
const char* reason);
static void defineMacro(pp::Context* context,
YYLTYPE* llocp,
pp::Macro::Type type,
const std::string* identifier,
std::vector<std::string*>* parameters,
pp::TokenVector* replacements);
static void undefineMacro(pp::Context* context, const std::string* identifier);
static bool isMacroDefined(pp::Context* context, const std::string* identifier);
static void pushConditionalBlock(pp::Context* context, bool condition);
static void popConditionalBlock(pp::Context* context);
@ -427,20 +415,20 @@ union yyalloc
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 2
/* YYLAST -- Last index in YYTABLE. */
#define YYLAST 244
#define YYLAST 247
/* YYNTOKENS -- Number of terminals. */
#define YYNTOKENS 48
#define YYNTOKENS 47
/* YYNNTS -- Number of nonterminals. */
#define YYNNTS 12
/* YYNRULES -- Number of rules. */
#define YYNRULES 63
#define YYNRULES 62
/* YYNRULES -- Number of states. */
#define YYNSTATES 94
#define YYNSTATES 91
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
#define YYUNDEFTOK 2
#define YYMAXUTOK 277
#define YYMAXUTOK 276
#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@ -449,18 +437,18 @@ union yyalloc
static const yytype_uint8 yytranslate[] =
{
0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
23, 2, 2, 2, 2, 2, 2, 2, 2, 2,
22, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 44, 2, 2, 2, 38, 41, 2,
24, 25, 37, 34, 26, 35, 33, 36, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 45, 46,
29, 43, 30, 47, 2, 2, 2, 2, 2, 2,
2, 2, 2, 43, 2, 2, 2, 37, 40, 2,
23, 24, 36, 33, 25, 34, 32, 35, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 44, 45,
28, 42, 29, 46, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 27, 2, 28, 39, 2, 2, 2, 2, 2,
2, 26, 2, 27, 38, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 31, 40, 32, 42, 2, 2, 2,
2, 2, 2, 30, 39, 31, 41, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@ -475,7 +463,7 @@ static const yytype_uint8 yytranslate[] =
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22
15, 16, 17, 18, 19, 20, 21
};
#if YYDEBUG
@ -484,46 +472,45 @@ static const yytype_uint8 yytranslate[] =
static const yytype_uint8 yyprhs[] =
{
0, 0, 3, 4, 7, 9, 11, 13, 16, 19,
24, 32, 36, 40, 44, 48, 52, 55, 58, 61,
64, 67, 70, 73, 74, 76, 78, 81, 84, 89,
91, 92, 94, 98, 100, 103, 105, 107, 109, 111,
113, 115, 117, 119, 121, 123, 125, 127, 129, 131,
133, 135, 137, 139, 141, 143, 145, 147, 149, 151,
153, 155, 157, 159
23, 30, 34, 38, 42, 46, 50, 53, 56, 59,
62, 65, 68, 71, 72, 74, 75, 77, 81, 83,
86, 88, 91, 94, 99, 101, 103, 105, 107, 109,
111, 113, 115, 117, 119, 121, 123, 125, 127, 129,
131, 133, 135, 137, 139, 141, 143, 145, 147, 149,
151, 153, 155
};
/* YYRHS -- A `-1'-separated list of the rules' RHS. */
static const yytype_int8 yyrhs[] =
{
49, 0, -1, -1, 49, 50, -1, 51, -1, 52,
-1, 23, -1, 57, 23, -1, 3, 23, -1, 4,
22, 53, 23, -1, 5, 22, 24, 56, 25, 53,
23, -1, 6, 22, 23, -1, 7, 54, 23, -1,
8, 22, 23, -1, 9, 22, 23, -1, 11, 54,
23, -1, 10, 23, -1, 12, 23, -1, 14, 23,
-1, 15, 23, -1, 16, 23, -1, 17, 23, -1,
18, 23, -1, -1, 57, -1, 55, -1, 54, 55,
-1, 13, 22, -1, 13, 24, 22, 25, -1, 58,
-1, -1, 22, -1, 56, 26, 22, -1, 58, -1,
57, 58, -1, 59, -1, 19, -1, 20, -1, 21,
-1, 22, -1, 27, -1, 28, -1, 29, -1, 30,
-1, 24, -1, 25, -1, 31, -1, 32, -1, 33,
-1, 34, -1, 35, -1, 36, -1, 37, -1, 38,
-1, 39, -1, 40, -1, 41, -1, 42, -1, 43,
-1, 44, -1, 45, -1, 46, -1, 26, -1, 47,
-1
48, 0, -1, -1, 48, 49, -1, 50, -1, 51,
-1, 22, -1, 55, 22, -1, 3, 22, -1, 17,
52, 22, -1, 18, 23, 53, 24, 52, 22, -1,
4, 21, 22, -1, 5, 54, 22, -1, 6, 21,
22, -1, 7, 21, 22, -1, 9, 54, 22, -1,
8, 22, -1, 10, 22, -1, 12, 22, -1, 13,
22, -1, 14, 22, -1, 15, 22, -1, 16, 22,
-1, -1, 55, -1, -1, 21, -1, 53, 25, 21,
-1, 56, -1, 54, 56, -1, 57, -1, 55, 57,
-1, 11, 21, -1, 11, 23, 21, 24, -1, 57,
-1, 58, -1, 19, -1, 20, -1, 21, -1, 26,
-1, 27, -1, 28, -1, 29, -1, 23, -1, 24,
-1, 30, -1, 31, -1, 32, -1, 33, -1, 34,
-1, 35, -1, 36, -1, 37, -1, 38, -1, 39,
-1, 40, -1, 41, -1, 42, -1, 43, -1, 44,
-1, 45, -1, 25, -1, 46, -1
};
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const yytype_uint8 yyrline[] =
{
0, 74, 74, 76, 80, 86, 90, 91, 95, 96,
99, 102, 105, 108, 111, 114, 116, 118, 121, 122,
123, 124, 125, 129, 130, 134, 138, 145, 147, 149,
153, 154, 158, 165, 169, 176, 179, 182, 185, 188,
194, 195, 196, 197, 198, 199, 200, 201, 202, 203,
204, 205, 206, 207, 208, 209, 210, 211, 212, 213,
214, 215, 216, 217
0, 63, 63, 65, 69, 70, 74, 75, 84, 85,
88, 91, 94, 97, 100, 103, 105, 107, 110, 111,
112, 113, 114, 118, 119, 122, 123, 127, 133, 137,
144, 148, 155, 157, 159, 163, 166, 169, 172, 178,
179, 180, 181, 182, 183, 184, 185, 186, 187, 188,
189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
199, 200, 201
};
#endif
@ -532,16 +519,16 @@ static const yytype_uint8 yyrline[] =
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] =
{
"$end", "error", "$undefined", "HASH", "HASH_DEFINE_OBJ",
"HASH_DEFINE_FUNC", "HASH_UNDEF", "HASH_IF", "HASH_IFDEF", "HASH_IFNDEF",
"HASH_ELSE", "HASH_ELIF", "HASH_ENDIF", "DEFINED", "HASH_ERROR",
"HASH_PRAGMA", "HASH_EXTENSION", "HASH_VERSION", "HASH_LINE", "SPACE",
"INT_CONSTANT", "FLOAT_CONSTANT", "IDENTIFIER", "'\\n'", "'('", "')'",
"','", "'['", "']'", "'<'", "'>'", "'{'", "'}'", "'.'", "'+'", "'-'",
"'/'", "'*'", "'%'", "'^'", "'|'", "'&'", "'~'", "'='", "'!'", "':'",
"';'", "'?'", "$accept", "input", "line", "text_line", "control_line",
"replacement_token_list", "conditional_token_list", "conditional_token",
"parameter_list", "token_list", "token", "operator", 0
"$end", "error", "$undefined", "HASH", "HASH_UNDEF", "HASH_IF",
"HASH_IFDEF", "HASH_IFNDEF", "HASH_ELSE", "HASH_ELIF", "HASH_ENDIF",
"DEFINED", "HASH_ERROR", "HASH_PRAGMA", "HASH_EXTENSION", "HASH_VERSION",
"HASH_LINE", "HASH_DEFINE_OBJ", "HASH_DEFINE_FUNC", "INT_CONSTANT",
"FLOAT_CONSTANT", "IDENTIFIER", "'\\n'", "'('", "')'", "','", "'['",
"']'", "'<'", "'>'", "'{'", "'}'", "'.'", "'+'", "'-'", "'/'", "'*'",
"'%'", "'^'", "'|'", "'&'", "'~'", "'='", "'!'", "':'", "';'", "'?'",
"$accept", "input", "line", "text_line", "control_line",
"replacement_list", "parameter_list", "conditional_list", "token_list",
"conditional_token", "token", "operator", 0
};
#endif
@ -552,34 +539,34 @@ static const yytype_uint16 yytoknum[] =
{
0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
275, 276, 277, 10, 40, 41, 44, 91, 93, 60,
62, 123, 125, 46, 43, 45, 47, 42, 37, 94,
124, 38, 126, 61, 33, 58, 59, 63
275, 276, 10, 40, 41, 44, 91, 93, 60, 62,
123, 125, 46, 43, 45, 47, 42, 37, 94, 124,
38, 126, 61, 33, 58, 59, 63
};
# endif
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
static const yytype_uint8 yyr1[] =
{
0, 48, 49, 49, 50, 50, 51, 51, 52, 52,
52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
52, 52, 52, 53, 53, 54, 54, 55, 55, 55,
56, 56, 56, 57, 57, 58, 58, 58, 58, 58,
59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
59, 59, 59, 59
0, 47, 48, 48, 49, 49, 50, 50, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 52, 52, 53, 53, 53, 54, 54,
55, 55, 56, 56, 56, 57, 57, 57, 57, 58,
58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
58, 58, 58
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
static const yytype_uint8 yyr2[] =
{
0, 2, 0, 2, 1, 1, 1, 2, 2, 4,
7, 3, 3, 3, 3, 3, 2, 2, 2, 2,
2, 2, 2, 0, 1, 1, 2, 2, 4, 1,
0, 1, 3, 1, 2, 1, 1, 1, 1, 1,
0, 2, 0, 2, 1, 1, 1, 2, 2, 3,
6, 3, 3, 3, 3, 3, 2, 2, 2, 2,
2, 2, 2, 0, 1, 0, 1, 3, 1, 2,
1, 2, 2, 4, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1
1, 1, 1
};
/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@ -588,46 +575,46 @@ static const yytype_uint8 yyr2[] =
static const yytype_uint8 yydefact[] =
{
2, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 36, 37,
38, 39, 6, 44, 45, 62, 40, 41, 42, 43,
0, 0, 0, 0, 0, 0, 23, 0, 36, 37,
38, 6, 43, 44, 61, 39, 40, 41, 42, 45,
46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 58, 59, 60, 61, 63, 3, 4, 5,
0, 33, 35, 8, 23, 0, 0, 0, 0, 25,
29, 0, 0, 16, 0, 17, 18, 19, 20, 21,
22, 7, 34, 0, 24, 30, 11, 27, 0, 12,
26, 13, 14, 15, 9, 31, 0, 0, 23, 0,
28, 0, 32, 10
56, 57, 58, 59, 60, 62, 3, 4, 5, 0,
30, 35, 8, 0, 0, 0, 28, 34, 0, 0,
16, 0, 17, 18, 19, 20, 21, 22, 0, 24,
25, 7, 31, 11, 32, 0, 12, 29, 13, 14,
15, 9, 26, 0, 0, 23, 0, 33, 0, 27,
10
};
/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int8 yydefgoto[] =
{
-1, 1, 47, 48, 49, 73, 58, 59, 86, 74,
60, 52
-1, 1, 46, 47, 48, 68, 83, 55, 69, 56,
57, 51
};
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */
#define YYPACT_NINF -29
#define YYPACT_NINF -55
static const yytype_int16 yypact[] =
{
-29, 1, -29, -9, 29, 33, 35, 139, 36, 37,
38, 139, 39, 40, 41, 42, 43, 44, -29, -29,
-29, -29, -29, -29, -29, -29, -29, -29, -29, -29,
-29, -29, -29, -29, -29, -29, -29, -29, -29, -29,
-29, -29, -29, -29, -29, -29, -29, -29, -29, -29,
168, -29, -29, -29, 197, 45, 47, 30, 69, -29,
-29, 48, 49, -29, 104, -29, -29, -29, -29, -29,
-29, -29, -29, 51, 197, 46, -29, -29, 53, -29,
-29, -29, -29, -29, -29, -29, -23, 52, 197, 54,
-29, 55, -29, -29
-55, 73, -55, -17, -18, 145, -10, -9, -16, 145,
-8, 22, 23, 24, 25, 27, 201, 28, -55, -55,
-55, -55, -55, -55, -55, -55, -55, -55, -55, -55,
-55, -55, -55, -55, -55, -55, -55, -55, -55, -55,
-55, -55, -55, -55, -55, -55, -55, -55, -55, 173,
-55, -55, -55, 30, -19, -3, -55, -55, 31, 32,
-55, 109, -55, -55, -55, -55, -55, -55, 33, 201,
29, -55, -55, -55, -55, 35, -55, -55, -55, -55,
-55, -55, -55, -15, -11, 201, 36, -55, 37, -55,
-55
};
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int8 yypgoto[] =
{
-29, -29, -29, -29, -29, -28, 68, -8, -29, 79,
-1, -29
-55, -55, -55, -55, -55, -27, -55, 51, 60, -54,
-1, -55
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
@ -637,76 +624,76 @@ static const yytype_int8 yypgoto[] =
#define YYTABLE_NINF -1
static const yytype_uint8 yytable[] =
{
51, 2, 88, 89, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 53, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
38, 39, 40, 41, 42, 43, 44, 45, 46, 72,
80, 54, 77, 51, 78, 55, 80, 56, 61, 62,
91, 63, 65, 66, 67, 68, 69, 70, 85, 75,
76, 81, 82, 72, 84, 87, 92, 90, 93, 64,
50, 0, 57, 0, 0, 0, 0, 51, 18, 19,
20, 21, 79, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 57, 0, 0,
0, 0, 0, 18, 19, 20, 21, 83, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
45, 46, 57, 0, 0, 0, 0, 0, 18, 19,
20, 21, 0, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 18, 19, 20,
21, 71, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 18, 19, 20, 21,
0, 23, 24, 25, 26, 27, 28, 29, 30, 31,
50, 77, 74, 53, 75, 52, 60, 77, 54, 85,
86, 58, 59, 87, 62, 50, 18, 19, 20, 76,
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
42, 43, 44, 45, 46
42, 43, 44, 45, 63, 64, 65, 66, 72, 67,
82, 70, 73, 78, 79, 81, 84, 89, 88, 90,
61, 49, 0, 0, 0, 0, 0, 0, 72, 0,
0, 0, 0, 2, 0, 0, 3, 4, 5, 6,
7, 8, 9, 10, 50, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
54, 0, 0, 0, 0, 0, 0, 0, 18, 19,
20, 80, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 54, 0, 0, 0,
0, 0, 0, 0, 18, 19, 20, 0, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
44, 45, 18, 19, 20, 71, 22, 23, 24, 25,
26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
18, 19, 20, 0, 22, 23, 24, 25, 26, 27,
28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
38, 39, 40, 41, 42, 43, 44, 45
};
static const yytype_int8 yycheck[] =
{
1, 0, 25, 26, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 23, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 42, 43, 44, 45, 46, 47, 50,
58, 22, 22, 54, 24, 22, 64, 22, 22, 22,
88, 23, 23, 23, 23, 23, 23, 23, 22, 24,
23, 23, 23, 74, 23, 22, 22, 25, 23, 11,
1, -1, 13, -1, -1, -1, -1, 88, 19, 20,
1, 55, 21, 21, 23, 22, 22, 61, 11, 24,
25, 21, 21, 24, 22, 16, 19, 20, 21, 22,
23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
43, 44, 45, 46, 22, 22, 22, 22, 49, 22,
21, 23, 22, 22, 22, 22, 21, 21, 85, 22,
9, 1, -1, -1, -1, -1, -1, -1, 69, -1,
-1, -1, -1, 0, -1, -1, 3, 4, 5, 6,
7, 8, 9, 10, 85, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
11, -1, -1, -1, -1, -1, -1, -1, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 13, -1, -1,
-1, -1, -1, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
46, 47, 13, -1, -1, -1, -1, -1, 19, 20,
21, 22, -1, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
42, 43, 44, 45, 46, 47, 19, 20, 21, 22,
-1, 24, 25, 26, 27, 28, 29, 30, 31, 32,
33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
43, 44, 45, 46, 47
41, 42, 43, 44, 45, 46, 11, -1, -1, -1,
-1, -1, -1, -1, 19, 20, 21, -1, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
45, 46, 19, 20, 21, 22, 23, 24, 25, 26,
27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
19, 20, 21, -1, 23, 24, 25, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 42, 43, 44, 45, 46
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
static const yytype_uint8 yystos[] =
{
0, 49, 0, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 14, 15, 16, 17, 18, 19, 20,
0, 48, 0, 3, 4, 5, 6, 7, 8, 9,
10, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 50, 51, 52,
57, 58, 59, 23, 22, 22, 22, 13, 54, 55,
58, 22, 22, 23, 54, 23, 23, 23, 23, 23,
23, 23, 58, 53, 57, 24, 23, 22, 24, 23,
55, 23, 23, 23, 23, 22, 56, 22, 25, 26,
25, 53, 22, 23
41, 42, 43, 44, 45, 46, 49, 50, 51, 55,
57, 58, 22, 21, 11, 54, 56, 57, 21, 21,
22, 54, 22, 22, 22, 22, 22, 22, 52, 55,
23, 22, 57, 22, 21, 23, 22, 56, 22, 22,
22, 22, 21, 53, 21, 24, 25, 24, 52, 21,
22
};
#define yyerrok (yyerrstatus = 0)
@ -1548,44 +1535,34 @@ yyreduce:
YY_REDUCE_PRINT (yyn);
switch (yyn)
{
case 4:
case 7:
{
// TODO(alokp): Expand macros.
pp::TokenVector* out = context->output;
out->insert(out->end(), (yyvsp[(1) - (1)].tlist)->begin(), (yyvsp[(1) - (1)].tlist)->end());
delete (yyvsp[(1) - (1)].tlist);
pp::TokenVector* out = context->output();
out->insert(out->end(), (yyvsp[(1) - (2)].tlist)->begin(), (yyvsp[(1) - (2)].tlist)->end());
delete (yyvsp[(1) - (2)].tlist);
;}
break;
case 6:
{ (yyval.tlist) = NULL; ;}
break;
case 7:
{ (yyval.tlist) = (yyvsp[(1) - (2)].tlist); ;}
break;
case 9:
{
defineMacro(context, & (yylsp[(2) - (4)]), pp::Macro::kTypeObj, (yyvsp[(2) - (4)].sval), NULL, (yyvsp[(3) - (4)].tlist));
context->defineMacro((yylsp[(1) - (3)]).first_line, pp::Macro::kTypeObj, (yyvsp[(1) - (3)].sval), NULL, (yyvsp[(2) - (3)].tlist));
;}
break;
case 10:
{
defineMacro(context, & (yylsp[(2) - (7)]), pp::Macro::kTypeFunc, (yyvsp[(2) - (7)].sval), (yyvsp[(4) - (7)].slist), (yyvsp[(6) - (7)].tlist));
context->defineMacro((yylsp[(1) - (6)]).first_line, pp::Macro::kTypeFunc, (yyvsp[(1) - (6)].sval), (yyvsp[(3) - (6)].tlist), (yyvsp[(5) - (6)].tlist));
;}
break;
case 11:
{
undefineMacro(context, (yyvsp[(2) - (3)].sval));
context->undefineMacro((yyvsp[(2) - (3)].sval));
;}
break;
@ -1599,14 +1576,14 @@ yyreduce:
case 13:
{
pushConditionalBlock(context, isMacroDefined(context, (yyvsp[(2) - (3)].sval)));
pushConditionalBlock(context, context->isMacroDefined((yyvsp[(2) - (3)].sval)));
;}
break;
case 14:
{
pushConditionalBlock(context, !isMacroDefined(context, (yyvsp[(2) - (3)].sval)));
pushConditionalBlock(context, !context->isMacroDefined((yyvsp[(2) - (3)].sval)));
;}
break;
@ -1631,67 +1608,39 @@ yyreduce:
case 23:
{ (yyval.tlist) = NULL ;}
{ (yyval.tlist) = NULL; ;}
break;
case 25:
{
(yyval.tlist) = new pp::TokenVector;
(yyval.tlist)->push_back((yyvsp[(1) - (1)].tval));
;}
{ (yyval.tlist) = NULL; ;}
break;
case 26:
{
(yyval.tlist) = (yyvsp[(1) - (2)].tlist);
(yyval.tlist)->push_back((yyvsp[(2) - (2)].tval));
(yyval.tlist) = new pp::TokenVector;
(yyval.tlist)->push_back(new pp::Token((yylsp[(1) - (1)]).first_line, IDENTIFIER, (yyvsp[(1) - (1)].sval)));
;}
break;
case 27:
{
(yyval.tlist) = (yyvsp[(1) - (3)].tlist);
(yyval.tlist)->push_back(new pp::Token((yylsp[(3) - (3)]).first_line, IDENTIFIER, (yyvsp[(3) - (3)].sval)));
;}
break;
case 28:
{
;}
break;
case 30:
{ (yyval.slist) = NULL; ;}
break;
case 31:
{
(yyval.slist) = new std::vector<std::string*>();
(yyval.slist)->push_back((yyvsp[(1) - (1)].sval));
;}
break;
case 32:
{
(yyval.slist) = (yyvsp[(1) - (3)].slist);
(yyval.slist)->push_back((yyvsp[(3) - (3)].sval));
;}
break;
case 33:
{
(yyval.tlist) = new pp::TokenVector;
(yyval.tlist)->push_back((yyvsp[(1) - (1)].tval));
;}
break;
case 34:
case 29:
{
(yyval.tlist) = (yyvsp[(1) - (2)].tlist);
@ -1699,6 +1648,34 @@ yyreduce:
;}
break;
case 30:
{
(yyval.tlist) = new pp::TokenVector;
(yyval.tlist)->push_back((yyvsp[(1) - (1)].tval));
;}
break;
case 31:
{
(yyval.tlist) = (yyvsp[(1) - (2)].tlist);
(yyval.tlist)->push_back((yyvsp[(2) - (2)].tval));
;}
break;
case 32:
{
;}
break;
case 33:
{
;}
break;
case 35:
{
@ -1709,147 +1686,140 @@ yyreduce:
case 36:
{
(yyval.tval) = new pp::Token((yylsp[(1) - (1)]).first_line, SPACE, NULL);
(yyval.tval) = new pp::Token((yylsp[(1) - (1)]).first_line, INT_CONSTANT, (yyvsp[(1) - (1)].sval));
;}
break;
case 37:
{
(yyval.tval) = new pp::Token((yylsp[(1) - (1)]).first_line, INT_CONSTANT, (yyvsp[(1) - (1)].sval));
(yyval.tval) = new pp::Token((yylsp[(1) - (1)]).first_line, FLOAT_CONSTANT, (yyvsp[(1) - (1)].sval));
;}
break;
case 38:
{
(yyval.tval) = new pp::Token((yylsp[(1) - (1)]).first_line, FLOAT_CONSTANT, (yyvsp[(1) - (1)].sval));
(yyval.tval) = new pp::Token((yylsp[(1) - (1)]).first_line, IDENTIFIER, (yyvsp[(1) - (1)].sval));
;}
break;
case 39:
{
(yyval.tval) = new pp::Token((yylsp[(1) - (1)]).first_line, IDENTIFIER, (yyvsp[(1) - (1)].sval));
;}
{ (yyval.ival) = '['; ;}
break;
case 40:
{ (yyval.ival) = '['; ;}
{ (yyval.ival) = ']'; ;}
break;
case 41:
{ (yyval.ival) = ']'; ;}
{ (yyval.ival) = '<'; ;}
break;
case 42:
{ (yyval.ival) = '<'; ;}
{ (yyval.ival) = '>'; ;}
break;
case 43:
{ (yyval.ival) = '>'; ;}
{ (yyval.ival) = '('; ;}
break;
case 44:
{ (yyval.ival) = '('; ;}
{ (yyval.ival) = ')'; ;}
break;
case 45:
{ (yyval.ival) = ')'; ;}
{ (yyval.ival) = '{'; ;}
break;
case 46:
{ (yyval.ival) = '{'; ;}
{ (yyval.ival) = '}'; ;}
break;
case 47:
{ (yyval.ival) = '}'; ;}
{ (yyval.ival) = '.'; ;}
break;
case 48:
{ (yyval.ival) = '.'; ;}
{ (yyval.ival) = '+'; ;}
break;
case 49:
{ (yyval.ival) = '+'; ;}
{ (yyval.ival) = '-'; ;}
break;
case 50:
{ (yyval.ival) = '-'; ;}
{ (yyval.ival) = '/'; ;}
break;
case 51:
{ (yyval.ival) = '/'; ;}
{ (yyval.ival) = '*'; ;}
break;
case 52:
{ (yyval.ival) = '*'; ;}
{ (yyval.ival) = '%'; ;}
break;
case 53:
{ (yyval.ival) = '%'; ;}
{ (yyval.ival) = '^'; ;}
break;
case 54:
{ (yyval.ival) = '^'; ;}
{ (yyval.ival) = '|'; ;}
break;
case 55:
{ (yyval.ival) = '|'; ;}
{ (yyval.ival) = '&'; ;}
break;
case 56:
{ (yyval.ival) = '&'; ;}
{ (yyval.ival) = '~'; ;}
break;
case 57:
{ (yyval.ival) = '~'; ;}
{ (yyval.ival) = '='; ;}
break;
case 58:
{ (yyval.ival) = '='; ;}
{ (yyval.ival) = '!'; ;}
break;
case 59:
{ (yyval.ival) = '!'; ;}
{ (yyval.ival) = ':'; ;}
break;
case 60:
{ (yyval.ival) = ':'; ;}
{ (yyval.ival) = ';'; ;}
break;
case 61:
{ (yyval.ival) = ';'; ;}
break;
case 62:
{ (yyval.ival) = ','; ;}
break;
case 63:
case 62:
{ (yyval.ival) = '?'; ;}
break;
@ -2083,24 +2053,6 @@ void yyerror(YYLTYPE* llocp, pp::Context* context, const char* reason)
{
}
void defineMacro(pp::Context* context,
YYLTYPE* llocp,
pp::Macro::Type type,
const std::string* identifier,
std::vector<std::string*>* parameters,
pp::TokenVector* replacements)
{
}
void undefineMacro(pp::Context* context, const std::string* identifier)
{
}
bool isMacroDefined(pp::Context* context, const std::string* identifier)
{
return false;
}
void pushConditionalBlock(pp::Context* context, bool condition)
{
}
@ -2110,10 +2062,10 @@ void popConditionalBlock(pp::Context* context)
}
namespace pp {
bool Preprocessor::parse(Context* context)
bool Context::parse()
{
yydebug = 1;
return yyparse(context) == 0 ? true : false;
return yyparse(this) == 0 ? true : false;
}
} // namespace pp

View File

@ -40,48 +40,46 @@
know about them. */
enum yytokentype {
HASH = 258,
HASH_DEFINE_OBJ = 259,
HASH_DEFINE_FUNC = 260,
HASH_UNDEF = 261,
HASH_IF = 262,
HASH_IFDEF = 263,
HASH_IFNDEF = 264,
HASH_ELSE = 265,
HASH_ELIF = 266,
HASH_ENDIF = 267,
DEFINED = 268,
HASH_ERROR = 269,
HASH_PRAGMA = 270,
HASH_EXTENSION = 271,
HASH_VERSION = 272,
HASH_LINE = 273,
SPACE = 274,
INT_CONSTANT = 275,
FLOAT_CONSTANT = 276,
IDENTIFIER = 277
HASH_UNDEF = 259,
HASH_IF = 260,
HASH_IFDEF = 261,
HASH_IFNDEF = 262,
HASH_ELSE = 263,
HASH_ELIF = 264,
HASH_ENDIF = 265,
DEFINED = 266,
HASH_ERROR = 267,
HASH_PRAGMA = 268,
HASH_EXTENSION = 269,
HASH_VERSION = 270,
HASH_LINE = 271,
HASH_DEFINE_OBJ = 272,
HASH_DEFINE_FUNC = 273,
INT_CONSTANT = 274,
FLOAT_CONSTANT = 275,
IDENTIFIER = 276
};
#endif
/* Tokens. */
#define HASH 258
#define HASH_DEFINE_OBJ 259
#define HASH_DEFINE_FUNC 260
#define HASH_UNDEF 261
#define HASH_IF 262
#define HASH_IFDEF 263
#define HASH_IFNDEF 264
#define HASH_ELSE 265
#define HASH_ELIF 266
#define HASH_ENDIF 267
#define DEFINED 268
#define HASH_ERROR 269
#define HASH_PRAGMA 270
#define HASH_EXTENSION 271
#define HASH_VERSION 272
#define HASH_LINE 273
#define SPACE 274
#define INT_CONSTANT 275
#define FLOAT_CONSTANT 276
#define IDENTIFIER 277
#define HASH_UNDEF 259
#define HASH_IF 260
#define HASH_IFDEF 261
#define HASH_IFNDEF 262
#define HASH_ELSE 263
#define HASH_ELIF 264
#define HASH_ENDIF 265
#define DEFINED 266
#define HASH_ERROR 267
#define HASH_PRAGMA 268
#define HASH_EXTENSION 269
#define HASH_VERSION 270
#define HASH_LINE 271
#define HASH_DEFINE_OBJ 272
#define HASH_DEFINE_FUNC 273
#define INT_CONSTANT 274
#define FLOAT_CONSTANT 275
#define IDENTIFIER 276
@ -92,7 +90,6 @@ typedef union YYSTYPE
{
int ival;
std::string* sval;
std::vector<std::string*>* slist;
pp::Token* tval;
pp::TokenVector* tlist;
}

View File

@ -515,6 +515,11 @@ EGLSurface Display::createWindowSurface(HWND window, EGLConfig config, const EGL
return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
}
if (isDeviceLost()) {
if (!restoreLostDevice())
return EGL_NO_SURFACE;
}
Surface *surface = new Surface(this, configuration, window);
if (!surface->initialize())
@ -622,6 +627,11 @@ EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle,
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
}
if (isDeviceLost()) {
if (!restoreLostDevice())
return EGL_NO_SURFACE;
}
Surface *surface = new Surface(this, configuration, shareHandle, width, height, textureFormat, textureTarget);
if (!surface->initialize())
@ -646,22 +656,8 @@ EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *sha
}
else if (isDeviceLost()) // Lost device
{
// Release surface resources to make the Reset() succeed
for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
{
(*surface)->release();
}
if (!resetDevice())
{
if (!restoreLostDevice())
return NULL;
}
// Restore any surfaces that may have been lost
for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
{
(*surface)->resetSwapChain();
}
}
const egl::Config *config = mConfigSet.get(configHandle);
@ -672,6 +668,29 @@ EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *sha
return context;
}
bool Display::restoreLostDevice()
{
// Release surface resources to make the Reset() succeed
for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
{
(*surface)->release();
}
if (!resetDevice())
{
return false;
}
// Restore any surfaces that may have been lost
for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
{
(*surface)->resetSwapChain();
}
return true;
}
void Display::destroySurface(egl::Surface *surface)
{
delete surface;
@ -756,10 +775,12 @@ bool Display::isDeviceLost()
{
return FAILED(mDeviceEx->CheckDeviceState(NULL));
}
else
else if(mDevice)
{
return FAILED(mDevice->TestCooperativeLevel());
}
return false; // No device yet, so no reset required
}
void Display::getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray)
@ -922,17 +943,24 @@ D3DPRESENT_PARAMETERS Display::getDefaultPresentParameters()
void Display::initExtensionString()
{
mExtensionString += "EGL_ANGLE_query_surface_pointer ";
HMODULE swiftShader = GetModuleHandle(TEXT("swiftshader_d3d9.dll"));
bool isd3d9ex = isD3d9ExDevice();
mExtensionString = "";
if (isd3d9ex) {
mExtensionString += "EGL_ANGLE_d3d_share_handle_client_buffer ";
}
mExtensionString += "EGL_ANGLE_query_surface_pointer ";
if (swiftShader)
{
mExtensionString += "EGL_ANGLE_software_display ";
}
if (isD3d9ExDevice()) {
if (isd3d9ex) {
mExtensionString += "EGL_ANGLE_surface_d3d_texture_2d_share_handle ";
mExtensionString += "EGL_ANGLE_d3d_share_handle_client_buffer ";
}
std::string::size_type end = mExtensionString.find_last_not_of(' ');

View File

@ -85,6 +85,8 @@ class Display
D3DPRESENT_PARAMETERS getDefaultPresentParameters();
bool restoreLostDevice();
EGLNativeDisplayType mDisplayId;
const HDC mDc;

View File

@ -191,8 +191,26 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
// the current process, disable use of FlipEx.
DWORD windowPID;
GetWindowThreadProcessId(mWindow, &windowPID);
if(windowPID != GetCurrentProcessId())
useFlipEx = false;
if (windowPID != GetCurrentProcessId())
{
useFlipEx = false;
}
// Various hardware does not support D3DSWAPEFFECT_FLIPEX when either the
// device format or back buffer format is not 32-bit.
HDC deviceContext = GetDC(0);
int deviceFormatBits = GetDeviceCaps(deviceContext, BITSPIXEL);
ReleaseDC(0, deviceContext);
if (mConfig->mBufferSize != 32 || deviceFormatBits != 32)
{
useFlipEx = false;
}
// D3DSWAPEFFECT_FLIPEX is always VSYNCed
if (mSwapInterval == 0)
{
useFlipEx = false;
}
presentParameters.AutoDepthStencilFormat = mConfig->mDepthStencilFormat;
// We set BackBufferCount = 1 even when we use D3DSWAPEFFECT_FLIPEX.

View File

@ -7,7 +7,7 @@
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
#include <windows.h>
#include "../common/version.h"
/////////////////////////////////////////////////////////////////////////////

View File

@ -74,6 +74,8 @@ void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset)
{
invalidateStaticData();
}
mUnmodifiedDataUse = 0;
}
StaticVertexBuffer *Buffer::getStaticVertexBuffer()

View File

@ -363,7 +363,12 @@ void Context::markAllStateDirty()
mAppliedRenderTargetSerial = 0;
mAppliedDepthbufferSerial = 0;
mAppliedStencilbufferSerial = 0;
mAppliedIBSerial = 0;
mDepthStencilInitialized = false;
mViewportInitialized = false;
mRenderTargetDescInitialized = false;
mVertexDeclarationCache.markStateDirty();
mClearStateDirty = true;
mCullStateDirty = true;
@ -1618,12 +1623,14 @@ bool Context::applyRenderTarget(bool ignoreViewport)
IDirect3DSurface9 *depthStencil = NULL;
bool renderTargetChanged = false;
unsigned int renderTargetSerial = framebufferObject->getRenderTargetSerial();
if (renderTargetSerial != mAppliedRenderTargetSerial)
{
device->SetRenderTarget(0, renderTarget);
mAppliedRenderTargetSerial = renderTargetSerial;
mScissorStateDirty = true; // Scissor area must be clamped to render target's size-- this is different for different render targets.
renderTargetChanged = true;
}
unsigned int depthbufferSerial = 0;
@ -1661,9 +1668,13 @@ bool Context::applyRenderTarget(bool ignoreViewport)
mDepthStencilInitialized = true;
}
if (!mRenderTargetDescInitialized || renderTargetChanged)
{
renderTarget->GetDesc(&mRenderTargetDesc);
mRenderTargetDescInitialized = true;
}
D3DVIEWPORT9 viewport;
D3DSURFACE_DESC desc;
renderTarget->GetDesc(&desc);
float zNear = clamp01(mState.zNear);
float zFar = clamp01(mState.zFar);
@ -1672,18 +1683,18 @@ bool Context::applyRenderTarget(bool ignoreViewport)
{
viewport.X = 0;
viewport.Y = 0;
viewport.Width = desc.Width;
viewport.Height = desc.Height;
viewport.Width = mRenderTargetDesc.Width;
viewport.Height = mRenderTargetDesc.Height;
viewport.MinZ = 0.0f;
viewport.MaxZ = 1.0f;
}
else
{
RECT rect = transformPixelRect(mState.viewportX, mState.viewportY, mState.viewportWidth, mState.viewportHeight, desc.Height);
viewport.X = clamp(rect.left, 0L, static_cast<LONG>(desc.Width));
viewport.Y = clamp(rect.top, 0L, static_cast<LONG>(desc.Height));
viewport.Width = clamp(rect.right - rect.left, 0L, static_cast<LONG>(desc.Width) - static_cast<LONG>(viewport.X));
viewport.Height = clamp(rect.bottom - rect.top, 0L, static_cast<LONG>(desc.Height) - static_cast<LONG>(viewport.Y));
RECT rect = transformPixelRect(mState.viewportX, mState.viewportY, mState.viewportWidth, mState.viewportHeight, mRenderTargetDesc.Height);
viewport.X = clamp(rect.left, 0L, static_cast<LONG>(mRenderTargetDesc.Width));
viewport.Y = clamp(rect.top, 0L, static_cast<LONG>(mRenderTargetDesc.Height));
viewport.Width = clamp(rect.right - rect.left, 0L, static_cast<LONG>(mRenderTargetDesc.Width) - static_cast<LONG>(viewport.X));
viewport.Height = clamp(rect.bottom - rect.top, 0L, static_cast<LONG>(mRenderTargetDesc.Height) - static_cast<LONG>(viewport.Y));
viewport.MinZ = zNear;
viewport.MaxZ = zFar;
}
@ -1693,17 +1704,22 @@ bool Context::applyRenderTarget(bool ignoreViewport)
return false; // Nothing to render
}
device->SetViewport(&viewport);
if (!mViewportInitialized || memcmp(&viewport, &mSetViewport, sizeof mSetViewport) != 0)
{
device->SetViewport(&viewport);
mSetViewport = viewport;
mViewportInitialized = true;
}
if (mScissorStateDirty)
{
if (mState.scissorTest)
{
RECT rect = transformPixelRect(mState.scissorX, mState.scissorY, mState.scissorWidth, mState.scissorHeight, desc.Height);
rect.left = clamp(rect.left, 0L, static_cast<LONG>(desc.Width));
rect.top = clamp(rect.top, 0L, static_cast<LONG>(desc.Height));
rect.right = clamp(rect.right, 0L, static_cast<LONG>(desc.Width));
rect.bottom = clamp(rect.bottom, 0L, static_cast<LONG>(desc.Height));
RECT rect = transformPixelRect(mState.scissorX, mState.scissorY, mState.scissorWidth, mState.scissorHeight, mRenderTargetDesc.Height);
rect.left = clamp(rect.left, 0L, static_cast<LONG>(mRenderTargetDesc.Width));
rect.top = clamp(rect.top, 0L, static_cast<LONG>(mRenderTargetDesc.Height));
rect.right = clamp(rect.right, 0L, static_cast<LONG>(mRenderTargetDesc.Width));
rect.bottom = clamp(rect.bottom, 0L, static_cast<LONG>(mRenderTargetDesc.Height));
device->SetScissorRect(&rect);
device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
}
@ -2024,7 +2040,11 @@ GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode
if (err == GL_NO_ERROR)
{
device->SetIndices(indexInfo->indexBuffer);
if (indexInfo->serial != mAppliedIBSerial)
{
device->SetIndices(indexInfo->indexBuffer);
mAppliedIBSerial = indexInfo->serial;
}
}
return err;
@ -2035,14 +2055,13 @@ void Context::applyShaders()
{
IDirect3DDevice9 *device = getDevice();
Program *programObject = getCurrentProgram();
IDirect3DVertexShader9 *vertexShader = programObject->getVertexShader();
IDirect3DPixelShader9 *pixelShader = programObject->getPixelShader();
device->SetVertexShader(vertexShader);
device->SetPixelShader(pixelShader);
if (programObject->getSerial() != mAppliedProgramSerial)
{
IDirect3DVertexShader9 *vertexShader = programObject->getVertexShader();
IDirect3DPixelShader9 *pixelShader = programObject->getPixelShader();
device->SetPixelShader(pixelShader);
device->SetVertexShader(vertexShader);
programObject->dirtyAllUniforms();
mAppliedProgramSerial = programObject->getSerial();
}
@ -2510,6 +2529,7 @@ void Context::clear(GLbitfield mask)
device->SetPixelShader(NULL);
device->SetVertexShader(NULL);
device->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
device->SetStreamSource(0, NULL, 0, 0);
device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
@ -2907,6 +2927,7 @@ void Context::drawClosingLine(unsigned int first, unsigned int last)
if (succeeded)
{
device->SetIndices(mClosingIB->getBuffer());
mAppliedIBSerial = mClosingIB->getSerial();
device->DrawIndexedPrimitive(D3DPT_LINELIST, 0, 0, last, offset, 1);
}
@ -3348,68 +3369,76 @@ void Context::setVertexAttrib(GLuint index, const GLfloat *values)
mVertexDataManager->dirtyCurrentValue(index);
}
// keep list sorted in following order
// OES extensions
// EXT extensions
// Vendor extensions
void Context::initExtensionString()
{
mExtensionString = "";
// OES extensions
if (supports32bitIndices())
{
mExtensionString += "GL_OES_element_index_uint ";
}
mExtensionString += "GL_OES_packed_depth_stencil ";
mExtensionString += "GL_EXT_texture_format_BGRA8888 ";
mExtensionString += "GL_EXT_read_format_bgra ";
mExtensionString += "GL_ANGLE_framebuffer_blit ";
mExtensionString += "GL_OES_rgb8_rgba8 ";
mExtensionString += "GL_OES_standard_derivatives ";
if (supportsEventQueries())
if (supportsHalfFloatTextures())
{
mExtensionString += "GL_NV_fence ";
mExtensionString += "GL_OES_texture_half_float ";
}
if (supportsHalfFloatLinearFilter())
{
mExtensionString += "GL_OES_texture_half_float_linear ";
}
if (supportsFloatTextures())
{
mExtensionString += "GL_OES_texture_float ";
}
if (supportsFloatLinearFilter())
{
mExtensionString += "GL_OES_texture_float_linear ";
}
if (supportsNonPower2Texture())
{
mExtensionString += "GL_OES_texture_npot ";
}
// Multi-vendor (EXT) extensions
mExtensionString += "GL_EXT_read_format_bgra ";
if (supportsDXT1Textures())
{
mExtensionString += "GL_EXT_texture_compression_dxt1 ";
}
if (supportsDXT3Textures())
{
mExtensionString += "GL_ANGLE_texture_compression_dxt3 ";
}
if (supportsDXT5Textures())
{
mExtensionString += "GL_ANGLE_texture_compression_dxt5 ";
}
if (supportsFloatTextures())
{
mExtensionString += "GL_OES_texture_float ";
}
if (supportsHalfFloatTextures())
{
mExtensionString += "GL_OES_texture_half_float ";
}
if (supportsFloatLinearFilter())
{
mExtensionString += "GL_OES_texture_float_linear ";
}
if (supportsHalfFloatLinearFilter())
{
mExtensionString += "GL_OES_texture_half_float_linear ";
}
mExtensionString += "GL_EXT_texture_format_BGRA8888 ";
// ANGLE-specific extensions
mExtensionString += "GL_ANGLE_framebuffer_blit ";
if (getMaxSupportedSamples() != 0)
{
mExtensionString += "GL_ANGLE_framebuffer_multisample ";
}
if (supports32bitIndices())
if (supportsDXT3Textures())
{
mExtensionString += "GL_OES_element_index_uint ";
mExtensionString += "GL_ANGLE_texture_compression_dxt3 ";
}
if (supportsDXT5Textures())
{
mExtensionString += "GL_ANGLE_texture_compression_dxt5 ";
}
if (supportsNonPower2Texture())
// Other vendor-specific extensions
if (supportsEventQueries())
{
mExtensionString += "GL_OES_texture_npot ";
mExtensionString += "GL_NV_fence ";
}
std::string::size_type end = mExtensionString.find_last_not_of(' ');
@ -3744,7 +3773,15 @@ GLenum VertexDeclarationCache::applyDeclaration(TranslatedAttribute attributes[]
{
if (attributes[i].active)
{
device->SetStreamSource(i, attributes[i].vertexBuffer, attributes[i].offset, attributes[i].stride);
if (mAppliedVBs[i].serial != attributes[i].serial ||
mAppliedVBs[i].stride != attributes[i].stride ||
mAppliedVBs[i].offset != attributes[i].offset)
{
device->SetStreamSource(i, attributes[i].vertexBuffer, attributes[i].offset, attributes[i].stride);
mAppliedVBs[i].serial = attributes[i].serial;
mAppliedVBs[i].stride = attributes[i].stride;
mAppliedVBs[i].offset = attributes[i].offset;
}
element->Stream = i;
element->Offset = 0;
@ -3765,8 +3802,12 @@ GLenum VertexDeclarationCache::applyDeclaration(TranslatedAttribute attributes[]
if (memcmp(entry->cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9)) == 0 && entry->vertexDeclaration)
{
entry->lruCount = ++mMaxLru;
device->SetVertexDeclaration(entry->vertexDeclaration);
if(entry->vertexDeclaration != mLastSetVDecl)
{
device->SetVertexDeclaration(entry->vertexDeclaration);
mLastSetVDecl = entry->vertexDeclaration;
}
return GL_NO_ERROR;
}
}
@ -3785,16 +3826,29 @@ GLenum VertexDeclarationCache::applyDeclaration(TranslatedAttribute attributes[]
{
lastCache->vertexDeclaration->Release();
lastCache->vertexDeclaration = NULL;
// mLastSetVDecl is set to the replacement, so we don't have to worry
// about it.
}
memcpy(lastCache->cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9));
device->CreateVertexDeclaration(elements, &lastCache->vertexDeclaration);
device->SetVertexDeclaration(lastCache->vertexDeclaration);
mLastSetVDecl = lastCache->vertexDeclaration;
lastCache->lruCount = ++mMaxLru;
return GL_NO_ERROR;
}
void VertexDeclarationCache::markStateDirty()
{
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
mAppliedVBs[i].serial = 0;
}
mLastSetVDecl = NULL;
}
}
extern "C"

View File

@ -230,11 +230,23 @@ class VertexDeclarationCache
GLenum applyDeclaration(TranslatedAttribute attributes[], Program *program);
void markStateDirty();
private:
UINT mMaxLru;
enum { NUM_VERTEX_DECL_CACHE_ENTRIES = 16 };
struct VBData
{
unsigned int serial;
unsigned int stride;
unsigned int offset;
};
VBData mAppliedVBs[MAX_VERTEX_ATTRIBS];
IDirect3DVertexDeclaration9 *mLastSetVDecl;
struct VertexDeclCacheEntry
{
D3DVERTEXELEMENT9 cachedElements[MAX_VERTEX_ATTRIBS + 1];
@ -526,7 +538,12 @@ class Context
unsigned int mAppliedRenderTargetSerial;
unsigned int mAppliedDepthbufferSerial;
unsigned int mAppliedStencilbufferSerial;
unsigned int mAppliedIBSerial;
bool mDepthStencilInitialized;
bool mViewportInitialized;
D3DVIEWPORT9 mSetViewport;
bool mRenderTargetDescInitialized;
D3DSURFACE_DESC mRenderTargetDesc;
bool mSupportsShaderModel3;
bool mSupportsVertexTexture;

View File

@ -22,6 +22,7 @@ namespace
namespace gl
{
unsigned int IndexBuffer::mCurrentSerial = 1;
IndexDataManager::IndexDataManager(Context *context, IDirect3DDevice9 *device) : mDevice(device)
{
@ -200,6 +201,7 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, Buffer *bu
}
translated->indexBuffer = indexBuffer->getBuffer();
translated->serial = indexBuffer->getSerial();
translated->startIndex = streamOffset / indexSize(format);
if (buffer)
@ -232,6 +234,7 @@ IndexBuffer::IndexBuffer(IDirect3DDevice9 *device, UINT size, D3DFORMAT format)
{
D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY);
HRESULT result = device->CreateIndexBuffer(size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, format, pool, &mIndexBuffer, NULL);
mSerial = issueSerial();
if (FAILED(result))
{
@ -253,6 +256,16 @@ IDirect3DIndexBuffer9 *IndexBuffer::getBuffer() const
return mIndexBuffer;
}
unsigned int IndexBuffer::getSerial() const
{
return mSerial;
}
unsigned int IndexBuffer::issueSerial()
{
return mCurrentSerial++;
}
void IndexBuffer::unmap()
{
if (mIndexBuffer)
@ -305,6 +318,7 @@ void StreamingIndexBuffer::reserveSpace(UINT requiredSpace, GLenum type)
D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY);
HRESULT result = mDevice->CreateIndexBuffer(mBufferSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, type == GL_UNSIGNED_INT ? D3DFMT_INDEX32 : D3DFMT_INDEX16, pool, &mIndexBuffer, NULL);
mSerial = issueSerial();
if (FAILED(result))
{
@ -358,6 +372,7 @@ void StaticIndexBuffer::reserveSpace(UINT requiredSpace, GLenum type)
{
D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_WRITEONLY);
HRESULT result = mDevice->CreateIndexBuffer(requiredSpace, D3DUSAGE_WRITEONLY, type == GL_UNSIGNED_INT ? D3DFMT_INDEX32 : D3DFMT_INDEX16, pool, &mIndexBuffer, NULL);
mSerial = issueSerial();
if (FAILED(result))
{
@ -381,24 +396,25 @@ bool StaticIndexBuffer::lookupType(GLenum type)
UINT StaticIndexBuffer::lookupRange(intptr_t offset, GLsizei count, UINT *minIndex, UINT *maxIndex)
{
for (unsigned int range = 0; range < mCache.size(); range++)
{
if (mCache[range].offset == offset && mCache[range].count == count)
{
*minIndex = mCache[range].minIndex;
*maxIndex = mCache[range].maxIndex;
IndexRange range = {offset, count};
return mCache[range].streamOffset;
}
std::map<IndexRange, IndexResult>::iterator res = mCache.find(range);
if (res == mCache.end())
{
return -1;
}
return -1;
*minIndex = res->second.minIndex;
*maxIndex = res->second.maxIndex;
return res->second.streamOffset;
}
void StaticIndexBuffer::addRange(intptr_t offset, GLsizei count, UINT minIndex, UINT maxIndex, UINT streamOffset)
{
IndexRange indexRange = {offset, count, minIndex, maxIndex, streamOffset};
mCache.push_back(indexRange);
IndexRange indexRange = {offset, count};
IndexResult indexResult = {minIndex, maxIndex, streamOffset};
mCache[indexRange] = indexResult;
}
}

View File

@ -28,6 +28,7 @@ struct TranslatedIndexData
UINT startIndex;
IDirect3DIndexBuffer9 *indexBuffer;
unsigned int serial;
};
class IndexBuffer
@ -42,6 +43,7 @@ class IndexBuffer
virtual void reserveSpace(UINT requiredSpace, GLenum type) = 0;
IDirect3DIndexBuffer9 *getBuffer() const;
unsigned int getSerial() const;
protected:
IDirect3DDevice9 *const mDevice;
@ -49,6 +51,10 @@ class IndexBuffer
IDirect3DIndexBuffer9 *mIndexBuffer;
UINT mBufferSize;
unsigned int mSerial;
static unsigned int issueSerial();
static unsigned int mCurrentSerial;
private:
DISALLOW_COPY_AND_ASSIGN(IndexBuffer);
};
@ -87,12 +93,28 @@ class StaticIndexBuffer : public IndexBuffer
intptr_t offset;
GLsizei count;
bool operator<(const IndexRange& rhs) const
{
if (offset != rhs.offset)
{
return offset < rhs.offset;
}
if (count != rhs.count)
{
return count < rhs.count;
}
return false;
}
};
struct IndexResult
{
UINT minIndex;
UINT maxIndex;
UINT streamOffset;
};
std::vector<IndexRange> mCache;
std::map<IndexRange, IndexResult> mCache;
};
class IndexDataManager

View File

@ -24,6 +24,7 @@
namespace gl
{
unsigned int Program::mCurrentSerial = 1;
const char *fakepath = "C:\\fakepath";
std::string str(int i)
{
@ -32,7 +33,8 @@ std::string str(int i)
return buffer;
}
Uniform::Uniform(GLenum type, const std::string &name, unsigned int arraySize) : type(type), name(name), arraySize(arraySize)
Uniform::Uniform(GLenum type, const std::string &_name, unsigned int arraySize)
: type(type), _name(_name), name(Program::undecorateUniform(_name)), arraySize(arraySize)
{
int bytes = UniformTypeSize(type) * arraySize;
data = new unsigned char[bytes];
@ -46,8 +48,13 @@ Uniform::~Uniform()
delete[] data;
}
UniformLocation::UniformLocation(const std::string &name, unsigned int element, unsigned int index)
: name(name), element(element), index(index)
bool Uniform::isArray()
{
return _name.compare(0, 3, "ar_") == 0;
}
UniformLocation::UniformLocation(const std::string &_name, unsigned int element, unsigned int index)
: name(Program::undecorateUniform(_name)), element(element), index(index)
{
}
@ -248,24 +255,23 @@ TextureType Program::getSamplerTextureType(SamplerType type, unsigned int sample
return TEXTURE_2D;
}
GLint Program::getUniformLocation(const char *name, bool decorated)
GLint Program::getUniformLocation(std::string name)
{
std::string _name = decorated ? name : decorate(name);
int subscript = 0;
// Strip any trailing array operator and retrieve the subscript
size_t open = _name.find_last_of('[');
size_t close = _name.find_last_of(']');
if (open != std::string::npos && close == _name.length() - 1)
size_t open = name.find_last_of('[');
size_t close = name.find_last_of(']');
if (open != std::string::npos && close == name.length() - 1)
{
subscript = atoi(_name.substr(open + 1).c_str());
_name.erase(open);
subscript = atoi(name.substr(open + 1).c_str());
name.erase(open);
}
unsigned int numUniforms = mUniformIndex.size();
for (unsigned int location = 0; location < numUniforms; location++)
{
if (mUniformIndex[location].name == _name &&
if (mUniformIndex[location].name == name &&
mUniformIndex[location].element == subscript)
{
return location;
@ -993,7 +999,7 @@ ID3D10Blob *Program::compileToBinary(const char *hlsl, const char *profile, ID3D
ID3D10Blob *binary = NULL;
ID3D10Blob *errorMessage = NULL;
result = D3DCompile(hlsl, strlen(hlsl), NULL, NULL, NULL, "main", profile, flags, 0, &binary, &errorMessage);
result = D3DCompile(hlsl, strlen(hlsl), fakepath, NULL, NULL, "main", profile, flags, 0, &binary, &errorMessage);
if (errorMessage)
{
@ -1007,7 +1013,6 @@ ID3D10Blob *Program::compileToBinary(const char *hlsl, const char *profile, ID3D
errorMessage = NULL;
}
if (FAILED(result))
{
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
@ -1277,7 +1282,7 @@ bool Program::linkVaryings()
default: UNREACHABLE();
}
mVertexHLSL += decorate(attribute->name) + " : TEXCOORD" + str(semanticIndex) + ";\n";
mVertexHLSL += decorateAttribute(attribute->name) + " : TEXCOORD" + str(semanticIndex) + ";\n";
semanticIndex += VariableRowCount(attribute->type);
}
@ -1312,14 +1317,14 @@ bool Program::linkVaryings()
for (AttributeArray::iterator attribute = mVertexShader->mAttributes.begin(); attribute != mVertexShader->mAttributes.end(); attribute++)
{
mVertexHLSL += " " + decorate(attribute->name) + " = ";
mVertexHLSL += " " + decorateAttribute(attribute->name) + " = ";
if (VariableRowCount(attribute->type) > 1) // Matrix
{
mVertexHLSL += "transpose";
}
mVertexHLSL += "(input." + decorate(attribute->name) + ");\n";
mVertexHLSL += "(input." + decorateAttribute(attribute->name) + ");\n";
}
mVertexHLSL += "\n"
@ -1588,12 +1593,12 @@ void Program::link()
// these uniforms are searched as already-decorated because gl_ and dx_
// are reserved prefixes, and do not receive additional decoration
mDxDepthRangeLocation = getUniformLocation("dx_DepthRange", true);
mDxDepthLocation = getUniformLocation("dx_Depth", true);
mDxViewportLocation = getUniformLocation("dx_Viewport", true);
mDxHalfPixelSizeLocation = getUniformLocation("dx_HalfPixelSize", true);
mDxFrontCCWLocation = getUniformLocation("dx_FrontCCW", true);
mDxPointsOrLinesLocation = getUniformLocation("dx_PointsOrLines", true);
mDxDepthRangeLocation = getUniformLocation("dx_DepthRange");
mDxDepthLocation = getUniformLocation("dx_Depth");
mDxViewportLocation = getUniformLocation("dx_Viewport");
mDxHalfPixelSizeLocation = getUniformLocation("dx_HalfPixelSize");
mDxFrontCCWLocation = getUniformLocation("dx_FrontCCW");
mDxPointsOrLinesLocation = getUniformLocation("dx_PointsOrLines");
mLinked = true; // Success
}
@ -1784,9 +1789,9 @@ bool Program::defineUniform(const D3DXHANDLE &constantHandle, const D3DXCONSTANT
}
}
bool Program::defineUniform(const D3DXCONSTANT_DESC &constantDescription, std::string &name)
bool Program::defineUniform(const D3DXCONSTANT_DESC &constantDescription, std::string &_name)
{
Uniform *uniform = createUniform(constantDescription, name);
Uniform *uniform = createUniform(constantDescription, _name);
if(!uniform)
{
@ -1794,7 +1799,7 @@ bool Program::defineUniform(const D3DXCONSTANT_DESC &constantDescription, std::s
}
// Check if already defined
GLint location = getUniformLocation(name.c_str(), true);
GLint location = getUniformLocation(uniform->name);
GLenum type = uniform->type;
if (location >= 0)
@ -1816,13 +1821,13 @@ bool Program::defineUniform(const D3DXCONSTANT_DESC &constantDescription, std::s
for (unsigned int i = 0; i < uniform->arraySize; ++i)
{
mUniformIndex.push_back(UniformLocation(name, i, uniformIndex));
mUniformIndex.push_back(UniformLocation(_name, i, uniformIndex));
}
return true;
}
Uniform *Program::createUniform(const D3DXCONSTANT_DESC &constantDescription, std::string &name)
Uniform *Program::createUniform(const D3DXCONSTANT_DESC &constantDescription, std::string &_name)
{
if (constantDescription.Rows == 1) // Vectors and scalars
{
@ -1831,44 +1836,44 @@ Uniform *Program::createUniform(const D3DXCONSTANT_DESC &constantDescription, st
case D3DXPT_SAMPLER2D:
switch (constantDescription.Columns)
{
case 1: return new Uniform(GL_SAMPLER_2D, name, constantDescription.Elements);
case 1: return new Uniform(GL_SAMPLER_2D, _name, constantDescription.Elements);
default: UNREACHABLE();
}
break;
case D3DXPT_SAMPLERCUBE:
switch (constantDescription.Columns)
{
case 1: return new Uniform(GL_SAMPLER_CUBE, name, constantDescription.Elements);
case 1: return new Uniform(GL_SAMPLER_CUBE, _name, constantDescription.Elements);
default: UNREACHABLE();
}
break;
case D3DXPT_BOOL:
switch (constantDescription.Columns)
{
case 1: return new Uniform(GL_BOOL, name, constantDescription.Elements);
case 2: return new Uniform(GL_BOOL_VEC2, name, constantDescription.Elements);
case 3: return new Uniform(GL_BOOL_VEC3, name, constantDescription.Elements);
case 4: return new Uniform(GL_BOOL_VEC4, name, constantDescription.Elements);
case 1: return new Uniform(GL_BOOL, _name, constantDescription.Elements);
case 2: return new Uniform(GL_BOOL_VEC2, _name, constantDescription.Elements);
case 3: return new Uniform(GL_BOOL_VEC3, _name, constantDescription.Elements);
case 4: return new Uniform(GL_BOOL_VEC4, _name, constantDescription.Elements);
default: UNREACHABLE();
}
break;
case D3DXPT_INT:
switch (constantDescription.Columns)
{
case 1: return new Uniform(GL_INT, name, constantDescription.Elements);
case 2: return new Uniform(GL_INT_VEC2, name, constantDescription.Elements);
case 3: return new Uniform(GL_INT_VEC3, name, constantDescription.Elements);
case 4: return new Uniform(GL_INT_VEC4, name, constantDescription.Elements);
case 1: return new Uniform(GL_INT, _name, constantDescription.Elements);
case 2: return new Uniform(GL_INT_VEC2, _name, constantDescription.Elements);
case 3: return new Uniform(GL_INT_VEC3, _name, constantDescription.Elements);
case 4: return new Uniform(GL_INT_VEC4, _name, constantDescription.Elements);
default: UNREACHABLE();
}
break;
case D3DXPT_FLOAT:
switch (constantDescription.Columns)
{
case 1: return new Uniform(GL_FLOAT, name, constantDescription.Elements);
case 2: return new Uniform(GL_FLOAT_VEC2, name, constantDescription.Elements);
case 3: return new Uniform(GL_FLOAT_VEC3, name, constantDescription.Elements);
case 4: return new Uniform(GL_FLOAT_VEC4, name, constantDescription.Elements);
case 1: return new Uniform(GL_FLOAT, _name, constantDescription.Elements);
case 2: return new Uniform(GL_FLOAT_VEC2, _name, constantDescription.Elements);
case 3: return new Uniform(GL_FLOAT_VEC3, _name, constantDescription.Elements);
case 4: return new Uniform(GL_FLOAT_VEC4, _name, constantDescription.Elements);
default: UNREACHABLE();
}
break;
@ -1883,9 +1888,9 @@ Uniform *Program::createUniform(const D3DXCONSTANT_DESC &constantDescription, st
case D3DXPT_FLOAT:
switch (constantDescription.Rows)
{
case 2: return new Uniform(GL_FLOAT_MAT2, name, constantDescription.Elements);
case 3: return new Uniform(GL_FLOAT_MAT3, name, constantDescription.Elements);
case 4: return new Uniform(GL_FLOAT_MAT4, name, constantDescription.Elements);
case 2: return new Uniform(GL_FLOAT_MAT2, _name, constantDescription.Elements);
case 3: return new Uniform(GL_FLOAT_MAT3, _name, constantDescription.Elements);
case 4: return new Uniform(GL_FLOAT_MAT4, _name, constantDescription.Elements);
default: UNREACHABLE();
}
break;
@ -1898,28 +1903,28 @@ Uniform *Program::createUniform(const D3DXCONSTANT_DESC &constantDescription, st
}
// This method needs to match OutputHLSL::decorate
std::string Program::decorate(const std::string &string)
std::string Program::decorateAttribute(const std::string &name)
{
if (string.substr(0, 3) != "gl_" && string.substr(0, 3) != "dx_")
if (name.compare(0, 3, "gl_") != 0 && name.compare(0, 3, "dx_") != 0)
{
return "_" + string;
}
else
{
return string;
return "_" + name;
}
return name;
}
std::string Program::undecorate(const std::string &string)
std::string Program::undecorateUniform(const std::string &_name)
{
if (string.substr(0, 1) == "_")
if (_name[0] == '_')
{
return string.substr(1);
return _name.substr(1);
}
else
else if (_name.compare(0, 3, "ar_") == 0)
{
return string;
return _name.substr(3);
}
return _name;
}
bool Program::applyUniform1bv(GLint location, GLsizei count, const GLboolean *v)
@ -2448,29 +2453,22 @@ bool Program::applyUniform4iv(GLint location, GLsizei count, const GLint *v)
// append a santized message to the program info log.
// The D3D compiler includes the current working directory
// in some of the warning or error messages, so lets remove
// any occurrances of those that we find in the log.
// The D3D compiler includes a fake file path in some of the warning or error
// messages, so lets remove all occurrences of this fake file path from the log.
void Program::appendToInfoLogSanitized(const char *message)
{
std::string msg(message);
CHAR path[MAX_PATH] = "";
size_t len;
len = GetCurrentDirectoryA(MAX_PATH, path);
if (len > 0 && len < MAX_PATH)
size_t found;
do
{
size_t found;
do {
found = msg.find(path);
if (found != std::string::npos)
{
// the +1 here is intentional so that we remove
// the trailing '\' that occurs after the path
msg.erase(found, len+1);
}
} while (found != std::string::npos);
found = msg.find(fakepath);
if (found != std::string::npos)
{
msg.erase(found, strlen(fakepath));
}
}
while (found != std::string::npos);
appendToInfoLog("%s\n", msg.c_str());
}
@ -2780,7 +2778,7 @@ void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, G
unsigned int uniform;
for (uniform = 0; uniform < mUniforms.size(); uniform++)
{
if (mUniforms[uniform]->name.substr(0, 3) == "dx_")
if (mUniforms[uniform]->name.compare(0, 3, "dx_") == 0)
{
continue;
}
@ -2797,9 +2795,9 @@ void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, G
if (bufsize > 0)
{
std::string string = undecorate(mUniforms[uniform]->name);
std::string string = mUniforms[uniform]->name;
if (mUniforms[uniform]->arraySize != 1)
if (mUniforms[uniform]->isArray())
{
string += "[0]";
}
@ -2825,7 +2823,7 @@ GLint Program::getActiveUniformCount()
unsigned int numUniforms = mUniforms.size();
for (unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++)
{
if (mUniforms[uniformIndex]->name.substr(0, 3) != "dx_")
if (mUniforms[uniformIndex]->name.compare(0, 3, "dx_") != 0)
{
count++;
}
@ -2841,10 +2839,10 @@ GLint Program::getActiveUniformMaxLength()
unsigned int numUniforms = mUniforms.size();
for (unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++)
{
if (!mUniforms[uniformIndex]->name.empty() && mUniforms[uniformIndex]->name.substr(0, 3) != "dx_")
if (!mUniforms[uniformIndex]->name.empty() && mUniforms[uniformIndex]->name.compare(0, 3, "dx_") != 0)
{
int length = (int)(undecorate(mUniforms[uniformIndex]->name).length() + 1);
if (mUniforms[uniformIndex]->arraySize != 1)
int length = (int)(mUniforms[uniformIndex]->name.length() + 1);
if (mUniforms[uniformIndex]->isArray())
{
length += 3; // Counting in "[0]".
}
@ -2979,8 +2977,8 @@ void Program::getConstantHandles(Uniform *targetUniform, D3DXHANDLE *constantPS,
{
if (!targetUniform->handlesSet)
{
targetUniform->psHandle = mConstantTablePS->GetConstantByName(0, targetUniform->name.c_str());
targetUniform->vsHandle = mConstantTableVS->GetConstantByName(0, targetUniform->name.c_str());
targetUniform->psHandle = mConstantTablePS->GetConstantByName(0, targetUniform->_name.c_str());
targetUniform->vsHandle = mConstantTableVS->GetConstantByName(0, targetUniform->_name.c_str());
targetUniform->handlesSet = true;
}

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// 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.
//
@ -28,12 +28,15 @@ class VertexShader;
// Helper struct representing a single shader uniform
struct Uniform
{
Uniform(GLenum type, const std::string &name, unsigned int arraySize);
Uniform(GLenum type, const std::string &_name, unsigned int arraySize);
~Uniform();
bool isArray();
const GLenum type;
const std::string name;
const std::string _name; // Decorated name
const std::string name; // Undecorated name
const unsigned int arraySize;
unsigned char *data;
@ -47,7 +50,7 @@ struct Uniform
// Struct used for correlating uniforms/elements of uniform arrays to handles
struct UniformLocation
{
UniformLocation(const std::string &name, unsigned int element, unsigned int index);
UniformLocation(const std::string &_name, unsigned int element, unsigned int index);
std::string name;
unsigned int element;
@ -75,7 +78,7 @@ class Program
GLint getSamplerMapping(SamplerType type, unsigned int samplerIndex);
TextureType getSamplerTextureType(SamplerType type, unsigned int samplerIndex);
GLint getUniformLocation(const char *name, bool decorated);
GLint getUniformLocation(std::string name);
bool setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
bool setUniform2fv(GLint location, GLsizei count, const GLfloat *v);
bool setUniform3fv(GLint location, GLsizei count, const GLfloat *v);
@ -127,6 +130,9 @@ class Program
unsigned int getSerial() const;
static std::string decorateAttribute(const std::string &name); // Prepend an underscore
static std::string undecorateUniform(const std::string &_name); // Remove leading underscore
private:
DISALLOW_COPY_AND_ASSIGN(Program);
@ -165,9 +171,6 @@ class Program
void appendToInfoLog(const char *info, ...);
void resetInfoLog();
static std::string decorate(const std::string &string); // Prepend an underscore
static std::string undecorate(const std::string &string); // Remove leading underscore
static unsigned int issueSerial();
FragmentShader *mFragmentShader;

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// 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.
//
@ -21,10 +21,13 @@
namespace
{
enum { INITIAL_STREAM_BUFFER_SIZE = 1024*1024 };
// This has to be at least 4k or else it fails on ATI cards.
enum { CONSTANT_VERTEX_BUFFER_SIZE = 4096 };
}
namespace gl
{
unsigned int VertexBuffer::mCurrentSerial = 1;
VertexDataManager::VertexDataManager(Context *context, IDirect3DDevice9 *device) : mContext(context), mDevice(device)
{
@ -32,6 +35,7 @@ VertexDataManager::VertexDataManager(Context *context, IDirect3DDevice9 *device)
{
mDirtyCurrentValue[i] = true;
mCurrentValueBuffer[i] = NULL;
mCurrentValueOffsets[i] = 0;
}
const D3DCAPS9 &caps = context->getDeviceCaps();
@ -234,24 +238,43 @@ GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, Translat
}
translated[i].vertexBuffer = vertexBuffer->getBuffer();
translated[i].serial = vertexBuffer->getSerial();
translated[i].type = converter.d3dDeclType;
translated[i].stride = converter.outputElementSize;
translated[i].offset = streamOffset;
}
else
{
if (!mCurrentValueBuffer[i])
{
mCurrentValueBuffer[i] = new StreamingVertexBuffer(mDevice, CONSTANT_VERTEX_BUFFER_SIZE);
}
StreamingVertexBuffer *buffer = mCurrentValueBuffer[i];
if (mDirtyCurrentValue[i])
{
delete mCurrentValueBuffer[i];
mCurrentValueBuffer[i] = new ConstantVertexBuffer(mDevice, attribs[i].mCurrentValue[0], attribs[i].mCurrentValue[1], attribs[i].mCurrentValue[2], attribs[i].mCurrentValue[3]);
mDirtyCurrentValue[i] = false;
const int requiredSpace = 4 * sizeof(float);
buffer->addRequiredSpace(requiredSpace);
buffer->reserveRequiredSpace();
float *data = static_cast<float*>(buffer->map(VertexAttribute(), requiredSpace, &mCurrentValueOffsets[i]));
if (data)
{
data[0] = attribs[i].mCurrentValue[0];
data[1] = attribs[i].mCurrentValue[1];
data[2] = attribs[i].mCurrentValue[2];
data[3] = attribs[i].mCurrentValue[3];
buffer->unmap();
mDirtyCurrentValue[i] = false;
}
}
translated[i].vertexBuffer = mCurrentValueBuffer[i]->getBuffer();
translated[i].serial = mCurrentValueBuffer[i]->getSerial();
translated[i].type = D3DDECLTYPE_FLOAT4;
translated[i].stride = 0;
translated[i].offset = 0;
translated[i].offset = mCurrentValueOffsets[i];
}
}
}
@ -521,6 +544,7 @@ VertexBuffer::VertexBuffer(IDirect3DDevice9 *device, std::size_t size, DWORD usa
{
D3DPOOL pool = getDisplay()->getBufferPool(usageFlags);
HRESULT result = device->CreateVertexBuffer(size, usageFlags, 0, pool, &mVertexBuffer, NULL);
mSerial = issueSerial();
if (FAILED(result))
{
@ -550,35 +574,14 @@ IDirect3DVertexBuffer9 *VertexBuffer::getBuffer() const
return mVertexBuffer;
}
ConstantVertexBuffer::ConstantVertexBuffer(IDirect3DDevice9 *device, float x, float y, float z, float w) : VertexBuffer(device, 4 * sizeof(float), D3DUSAGE_WRITEONLY)
unsigned int VertexBuffer::getSerial() const
{
void *buffer = NULL;
if (mVertexBuffer)
{
HRESULT result = mVertexBuffer->Lock(0, 0, &buffer, 0);
if (FAILED(result))
{
ERR("Lock failed with error 0x%08x", result);
}
}
if (buffer)
{
float *vector = (float*)buffer;
vector[0] = x;
vector[1] = y;
vector[2] = z;
vector[3] = w;
mVertexBuffer->Unlock();
}
return mSerial;
}
ConstantVertexBuffer::~ConstantVertexBuffer()
unsigned int VertexBuffer::issueSerial()
{
return mCurrentSerial++;
}
ArrayVertexBuffer::ArrayVertexBuffer(IDirect3DDevice9 *device, std::size_t size, DWORD usageFlags) : VertexBuffer(device, size, usageFlags)
@ -640,6 +643,7 @@ void StreamingVertexBuffer::reserveRequiredSpace()
D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY);
HRESULT result = mDevice->CreateVertexBuffer(mBufferSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, pool, &mVertexBuffer, NULL);
mSerial = issueSerial();
if (FAILED(result))
{
@ -686,7 +690,7 @@ void *StaticVertexBuffer::map(const VertexAttribute &attribute, std::size_t requ
}
int attributeOffset = attribute.mOffset % attribute.stride();
VertexElement element = {attribute.mType, attribute.mSize, attribute.mNormalized, attributeOffset, mWritePosition};
VertexElement element = {attribute.mType, attribute.mSize, attribute.stride(), attribute.mNormalized, attributeOffset, mWritePosition};
mCache.push_back(element);
*streamOffset = mWritePosition;
@ -702,7 +706,8 @@ void StaticVertexBuffer::reserveRequiredSpace()
{
D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_WRITEONLY);
HRESULT result = mDevice->CreateVertexBuffer(mRequiredSpace, D3DUSAGE_WRITEONLY, 0, pool, &mVertexBuffer, NULL);
mSerial = issueSerial();
if (FAILED(result))
{
ERR("Out of memory allocating a vertex buffer of size %lu.", mRequiredSpace);
@ -723,7 +728,10 @@ std::size_t StaticVertexBuffer::lookupAttribute(const VertexAttribute &attribute
{
for (unsigned int element = 0; element < mCache.size(); element++)
{
if (mCache[element].type == attribute.mType && mCache[element].size == attribute.mSize && mCache[element].normalized == attribute.mNormalized)
if (mCache[element].type == attribute.mType &&
mCache[element].size == attribute.mSize &&
mCache[element].stride == attribute.stride() &&
mCache[element].normalized == attribute.mNormalized)
{
if (mCache[element].attributeOffset == attribute.mOffset % attribute.stride())
{

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// 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.
//
@ -30,6 +30,7 @@ struct TranslatedAttribute
UINT stride; // 0 means not to advance the read pointer at all
IDirect3DVertexBuffer9 *vertexBuffer;
unsigned int serial;
};
class VertexBuffer
@ -41,22 +42,20 @@ class VertexBuffer
void unmap();
IDirect3DVertexBuffer9 *getBuffer() const;
unsigned int getSerial() const;
protected:
IDirect3DDevice9 *const mDevice;
IDirect3DVertexBuffer9 *mVertexBuffer;
unsigned int mSerial;
static unsigned int issueSerial();
static unsigned int mCurrentSerial;
private:
DISALLOW_COPY_AND_ASSIGN(VertexBuffer);
};
class ConstantVertexBuffer : public VertexBuffer
{
public:
ConstantVertexBuffer(IDirect3DDevice9 *device, float x, float y, float z, float w);
~ConstantVertexBuffer();
};
class ArrayVertexBuffer : public VertexBuffer
{
public:
@ -100,6 +99,7 @@ class StaticVertexBuffer : public ArrayVertexBuffer
{
GLenum type;
GLint size;
GLsizei stride;
bool normalized;
int attributeOffset;
@ -131,7 +131,8 @@ class VertexDataManager
StreamingVertexBuffer *mStreamingBuffer;
bool mDirtyCurrentValue[MAX_VERTEX_ATTRIBS];
ConstantVertexBuffer *mCurrentValueBuffer[MAX_VERTEX_ATTRIBS];
StreamingVertexBuffer *mCurrentValueBuffer[MAX_VERTEX_ATTRIBS];
std::size_t mCurrentValueOffsets[MAX_VERTEX_ATTRIBS];
// Attribute format conversion
struct FormatConverter

View File

@ -3446,7 +3446,7 @@ int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
return error(GL_INVALID_OPERATION, -1);
}
return programObject->getUniformLocation(name, false);
return programObject->getUniformLocation(name);
}
}
catch(std::bad_alloc&)

View File

@ -7,7 +7,7 @@
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
#include <windows.h>
#include "../common/version.h"
/////////////////////////////////////////////////////////////////////////////