Bug 734657 - Upgrade ANGLE to r1042 - no review

The upstream is at:
  http://code.google.com/p/angleproject/

This update allows to pass all conformance tests on Windows with ANGLE renderer; also fixes 2 crashes (see dependent bugs).
This commit is contained in:
Benoit Jacob 2012-04-15 15:05:00 -04:00
parent 09b31b5a80
commit b7aa678078
100 changed files with 4493 additions and 2973 deletions

View File

@ -1,3 +1 @@
conformance/glsl/functions/glsl-function-atan-xy.html
conformance/glsl/misc/struct-nesting-under-maximum.html
conformance/more/functions/uniformfArrayLen1.html

View File

@ -47,4 +47,5 @@ Yore Apex
Mark Callow
Yuriy O'Donnell
Sam Hocevar
Pierre Leveille

View File

@ -1,6 +1,9 @@
deps = {
"trunk/third_party/gyp":
"http://gyp.googlecode.com/svn/trunk@1080",
"trunk/third_party/googletest":
"http://googletest.googlecode.com/svn/trunk@573", #release 1.6.0
}
hooks = [

View File

@ -60,6 +60,7 @@ LOCAL_INCLUDES += -I$(srcdir)/include -I$(srcdir)/src
VPATH += $(srcdir)/src
VPATH += $(srcdir)/src/compiler
VPATH += $(srcdir)/src/compiler/preprocessor
VPATH += $(srcdir)/src/compiler/preprocessor/new
CPPSRCS = \
Compiler.cpp \
@ -86,6 +87,12 @@ CPPSRCS = \
MapLongVariableNames.cpp \
spooky.cpp \
BuiltInFunctionEmulator.cpp \
Input.cpp \
Lexer.cpp \
pp_lex.cpp \
Preprocessor.cpp \
Token.cpp \
lexer_glue.cpp \
$(NULL)
# flex/yacc generated files

View File

@ -1,6 +1,6 @@
This is the ANGLE project, from http://code.google.com/p/angleproject/
Current revision: r963
Current revision: r1042
== Applied local patches ==
@ -8,10 +8,9 @@ In this order:
angle-renaming-debug.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-use-xmalloc.patch - see bug 680840. Can drop this patch whenever the new preprocessor lands.
angle-castrate-bug-241.patch - see bug 699033 / angle bug 241
angle-enforce-readpixels-spec.patch - see bug 724476.
angle-impl-read-bgra.patch - see bug 724476.
gfx/angle/angle-long-identifier-hash-spooky.patch - see bug 676071
angle-long-identifier-hash-spooky.patch - see bug 676071
In addition to these patches, the Makefile.in files are ours, they're not present in upsteam ANGLE.

View File

@ -1,6 +1,5 @@
From: Jeff Gilbert <jgilbert@mozilla.com>
Bug 724476 - ANGLE Bug 293 - Enforce readPixels format/type semantics
# HG changeset patch
# Parent 8d84c8d4e3ed41a4941afdf9d51819b19ca64716
diff --git a/gfx/angle/src/libGLESv2/libGLESv2.cpp b/gfx/angle/src/libGLESv2/libGLESv2.cpp
--- a/gfx/angle/src/libGLESv2/libGLESv2.cpp
+++ b/gfx/angle/src/libGLESv2/libGLESv2.cpp

View File

@ -1,10 +1,9 @@
From: Jeff Gilbert <jgilbert@mozilla.com>
Bug 724476 - ANGLE Bug 294 - Use BGRA/UBYTE as exposed fast format/type for readPixels
# HG changeset patch
# Parent 8b838be49f115022e403c850c24b28ad62d72ad6
diff --git a/gfx/angle/src/libGLESv2/Context.cpp b/gfx/angle/src/libGLESv2/Context.cpp
--- a/gfx/angle/src/libGLESv2/Context.cpp
+++ b/gfx/angle/src/libGLESv2/Context.cpp
@@ -2520,16 +2520,17 @@ void Context::readPixels(GLint x, GLint
@@ -2518,16 +2518,17 @@ void Context::readPixels(GLint x, GLint
{
if (desc.Format == D3DFMT_A8R8G8B8 &&
format == GL_BGRA_EXT &&
@ -22,7 +21,7 @@ diff --git a/gfx/angle/src/libGLESv2/Context.cpp b/gfx/angle/src/libGLESv2/Conte
for (int i = 0; i < rect.right - rect.left; i++)
{
@@ -2666,20 +2667,20 @@ void Context::readPixels(GLint x, GLint
@@ -2665,20 +2666,20 @@ void Context::readPixels(GLint x, GLint
((unsigned short)( a + 0.5f) << 15) |
((unsigned short)(31 * r + 0.5f) << 10) |
((unsigned short)(31 * g + 0.5f) << 5) |

View File

@ -1,5 +1,5 @@
# HG changeset patch
# Parent 6ee54a11fd135a2b594db77f7eaf83f06ee7b1d8
# Parent 4ef86d96d456866537beea57b0a4451cf919cd34
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,6 +1,5 @@
# HG changeset patch
# Parent 69255fe4cb94f1681bc9200db37c0ad3de171abc
# Parent 268bda9ac676b6f4cca5aa044d0dcefff2008535
diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
--- a/gfx/angle/Makefile.in
+++ b/gfx/angle/Makefile.in

View File

@ -1,9 +1,9 @@
# HG changeset patch
# Parent 326590fb862cf7e277487f48c7a434bde3566ea0
# Parent f22671e05062a082c7b22192868b804fbf42653b
diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
--- a/gfx/angle/Makefile.in
+++ b/gfx/angle/Makefile.in
@@ -75,17 +75,17 @@ CPPSRCS = \
@@ -73,17 +73,17 @@ CPPSRCS = \
parseConst.cpp \
ParseHelper.cpp \
PoolAlloc.cpp \
@ -48,7 +48,7 @@ diff --git a/gfx/angle/src/compiler/OutputHLSL.cpp b/gfx/angle/src/compiler/Outp
+++ b/gfx/angle/src/compiler/OutputHLSL.cpp
@@ -1,17 +1,17 @@
//
// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@ -191,8 +191,8 @@ diff --git a/gfx/angle/src/compiler/preprocessor/tokens.c b/gfx/angle/src/compil
#include "compiler/preprocessor/slglobals.h"
#include "compiler/util.h"
///////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////// Preprocessor and Token Recorder and Playback: ////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
#if defined(_MSC_VER)
#pragma warning(disable: 4054)
#pragma warning(disable: 4152)
#endif
/*

View File

@ -1,9 +1,9 @@
# HG changeset patch
# Parent 93033f21b121382b50e5bc9787edf704d6906508
# Parent 6ccfe6b908da8ade8b37e772ed8a9f3c494d8ef9
diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
--- a/gfx/angle/Makefile.in
+++ b/gfx/angle/Makefile.in
@@ -129,16 +129,18 @@ CSRCS = \
@@ -127,16 +127,18 @@ CSRCS = \
$(NULL)
DEFINES += -DANGLE_USE_NSPR -DANGLE_BUILD -DCOMPILER_IMPLEMENTATION

View File

@ -14,7 +14,7 @@
# manually maintained ones.
'../samples/build_samples.gyp:*',
'../src/build_angle.gyp:*',
# '../tests/tests.gyp:*',
'../tests/build_tests.gyp:*',
],
},
],

View File

@ -40,7 +40,6 @@
'PreprocessorDefinitions': [
'_CRT_SECURE_NO_DEPRECATE',
'_HAS_EXCEPTIONS=0',
'_HAS_TR1=0',
'_WIN32_WINNT=0x0600',
'_WINDOWS',
'NOMINMAX',
@ -49,7 +48,8 @@
'WINVER=0x0600',
],
'RuntimeTypeInfo': 'false',
'WarningLevel': '3',
'WarningLevel': '4',
'DisableSpecificWarnings': '4100;4127;4189;4239;4244;4245;4512;4702',
},
'VCLinkerTool': {
'FixedBaseAddress': '1',

View File

@ -0,0 +1,359 @@
Name
ANGLE_instanced_arrays
Name Strings
GL_ANGLE_instanced_arrays
Contributors
Contributors to ARB_instanced_arrays
Nicolas Capens, TransGaming Inc.
James Helferty, TransGaming Inc.
Kenneth Russell, Google Inc.
Vangelis Kokkevis, Google Inc.
Contact
Daniel Koch, TransGaming Inc. (daniel 'at' transgaming.com)
Status
Implemented in ANGLE r976.
Version
Last Modified Date: February 8, 2012
Author Revision: 3
Number
OpenGL ES Extension #??
Dependencies
OpenGL ES 2.0 is required.
This extension is written against the OpenGL ES 2.0 Specification.
Overview
A common use case in GL for some applications is to be able to
draw the same object, or groups of similar objects that share
vertex data, primitive count and type, multiple times. This
extension provides a means of accelerating such use cases while
restricting the number of API calls, and keeping the amount of
duplicate data to a minimum.
This extension introduces an array "divisor" for generic
vertex array attributes, which when non-zero specifies that the
attribute is "instanced." An instanced attribute does not
advance per-vertex as usual, but rather after every <divisor>
conceptual draw calls.
(Attributes which aren't instanced are repeated in their entirety
for every conceptual draw call.)
By specifying transform data in an instanced attribute or series
of instanced attributes, vertex shaders can, in concert with the
instancing draw calls, draw multiple instances of an object with
one draw call.
IP Status
No known IP claims.
New Tokens
Accepted by the <pname> parameters of GetVertexAttribfv and
GetVertexAttribiv:
VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE
New Procedures and Functions
void DrawArraysInstancedANGLE(enum mode, int first, sizei count,
sizei primcount);
void DrawElementsInstancedANGLE(enum mode, sizei count, enum type,
const void *indices, sizei primcount);
void VertexAttribDivisorANGLE(uint index, uint divisor);
Additions to Chapter 2 of the OpenGL ES 2.0 Specification
(OpenGL ES Operation)
Modify section 2.8 (Vertex Arrays), p. 21
After description of EnableVertexAttribArray / DisableVertexAttribArray
add the following:
"The command
void VertexAttribDivisorANGLE(uint index, uint divisor);
modifies the rate at which generic vertex attributes advance when
rendering multiple instances of primitives in a single draw call
(see DrawArraysInstancedANGLE and DrawElementsInstancedANGLE below).
If <divisor> is zero, the attribute at slot <index> advances once
per vertex. If <divisor> is non-zero, the attribute advances once
per <divisor> instances of the primitives being rendered.
An attribute is referred to as "instanced" if its <divisor> value is
non-zero."
Replace the text describing DrawArrays and DrawElements in the
"Transferring Array Elements" subsection of 2.8, from the second paragraph
through the end of the section with the following:
"The command
void DrawArraysOneInstance( enum mode, int first, sizei count, int instance );
does not exist in the GL, but is used to describe functionality in
the rest of this section. This function constructs a sequence of
geometric primitives by transferring elements <first> through <first> +
<count> - 1 of each enabled non-instanced array to the GL. <mode>
specifies what kind of primitives are constructed, as defined in section
2.6.1.
If an enabled vertex attribute array is instanced (it has a non-zero
attribute <divisor> as specified by VertexAttribDivisorANGLE), the element
that is transferred to the GL is given by:
floor( <instance> / <divisor> ).
If an array corresponding to a generic attribute required by a vertex shader
is not enabled, then the corresponding element is taken from the current
generic attribute state (see section 2.7).
If an array corresponding to a generic attribute required by a vertex shader
is enabled, the corresponding current generic attribute value is unaffected
by the execution of DrawArraysOneInstance.
Specifying <first> < 0 results in undefined behavior. Generating the error
INVALID_VALUE is recommended in this case.
The command
void DrawArrays( enum mode, int first, sizei count );
is equivalent to the command sequence
DrawArraysOneInstance(mode, first, count, 0);
The command
void DrawArraysInstancedANGLE(enum mode, int first, sizei count,
sizei primcount);
behaves identically to DrawArrays except that <primcount>
instances of the range of elements are executed, and the
<instance> advances for each iteration. Instanced attributes that
have <divisor> N, (where N > 0, as specified by
VertexAttribDivisorANGLE) advance once every N instances.
It has the same effect as:
if (mode, count, or primcount is invalid)
generate appropriate error
else {
for (i = 0; i < primcount; i++) {
DrawArraysOneInstance(mode, first, count, i);
}
}
The command
void DrawElementsOneInstance( enum mode, sizei count, enum type,
void *indices, int instance );
does not exist in the GL, but is used to describe functionality in
the rest of this section. This command constructs a sequence of
geometric primitives by successively transferring the <count> elements
whose indices are stored in the currently bound element array buffer
(see section 2.9.2) at the offset defined by <indices> to the GL.
The <i>-th element transferred by DrawElementsOneInstance will be taken
from element <indices>[i] of each enabled non-instanced array.
<type> must be one of UNSIGNED_BYTE, UNSIGNED_SHORT, or UNSIGNED_INT,
indicating that the index values are of GL type ubyte, ushort, or uint
respectively. <mode> specifies what kind of primitives are constructed,
as defined in section 2.6.1.
If an enabled vertex attribute array is instanced (it has a non-zero
attribute <divisor> as specified by VertexAttribDivisorANGLE), the element
that is transferred to the GL is given by:
floor( <instance> / <divisor> );
If an array corresponding to a generic attribute required by a vertex
shader is not enabled, then the corresponding element is taken from the
current generic attribute state (see section 2.7). Otherwise, if an array
is enabled, the corresponding current generic attribute value is
unaffected by the execution of DrawElementsOneInstance.
The command
void DrawElements( enum mode, sizei count, enum type,
const void *indices);
behaves identically to DrawElementsOneInstance with the <instance>
parameter set to zero; the effect of calling
DrawElements(mode, count, type, indices);
is equivalent to the command sequence:
if (mode, count or type is invalid )
generate appropriate error
else
DrawElementsOneInstance(mode, count, type, indices, 0);
The command
void DrawElementsInstancedANGLE(enum mode, sizei count, enum type,
const void *indices, sizei primcount);
behaves identically to DrawElements except that <primcount>
instances of the set of elements are executed and the instance
advances between each set. Instanced attributes are advanced as they do
during the execution of DrawArraysInstancedANGLE. It has the same effect as:
if (mode, count, primcount, or type is invalid )
generate appropriate error
else {
for (int i = 0; i < primcount; i++) {
DrawElementsOneInstance(mode, count, type, indices, i);
}
}
If the number of supported generic vertex attributes (the value of
MAX_VERTEX_ATTRIBS) is <n>, then the client state required to implement
vertex arrays consists of <n> boolean values, <n> memory pointers, <n>
integer stride values, <n> symbolic constants representing array types,
<n> integers representing values per element, <n> boolean values
indicating normalization, and <n> integers representing vertex attribute
divisors.
In the initial state, the boolean values are each false, the memory
pointers are each NULL, the strides are each zero, the array types are
each FLOAT, the integers representing values per element are each four,
and the divisors are each zero."
Additions to Chapter 3 of the OpenGL ES 2.0 Specification (Rasterization)
None
Additions to Chapter 4 of the OpenGL ES 2.0 Specification (Per-Fragment
Operations and the Framebuffer)
None
Additions to Chapter 5 of the OpenGL ES 2.0 Specification (Special Functions)
None
Additions to Chapter 6 of the OpenGL ES 2.0 Specification (State and State
Requests)
In section 6.1.8, add VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE to the list of
pnames accepted by GetVertexAttribfv and GetVertexAttribiv.
Additions to the AGL/EGL/GLX/WGL Specifications
None
Dependencies on OES_element_index_uint
If OES_element_index_uint is not supported, removed all references
to UNSIGNED_INT indices and the associated GL data type uint in
the description of DrawElementsOneInstance.
Errors
INVALID_VALUE is generated by VertexAttribDivisorANGLE if <index>
is greater than or equal to MAX_VERTEX_ATTRIBS.
INVALID_ENUM is generated by DrawElementsInstancedANGLE if <type> is
not one of UNSIGNED_BYTE, UNSIGNED_SHORT or UNSIGNED_INT.
INVALID_VALUE is generated by DrawArraysInstancedANGLE if <first>,
<count>, or <primcount> is less than zero.
INVALID_ENUM is generated by DrawArraysInstancedANGLE or
DrawElementsInstancedANGLE if <mode> is not one of the modes described in
section 2.6.1.
INVALID_VALUE is generated by DrawElementsInstancedANGLE if <count> or
<primcount> is less than zero.
INVALID_OPERATION is generated by DrawArraysInstancedANGLE or
DrawElementsInstancedANGLE if there is not at least one enabled
vertex attribute array that has a <divisor> of zero and is bound to an
active generic attribute value in the program used for the draw command.
New State
Changes to table 6.7, p. 268 (Vertex Array Data)
Initial
Get Value Type Get Command Value Description Sec.
--------- ----- ----------- ------- ----------- ----
VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 8*xZ+ GetVertexAttrib 0 Instance Divisor 2.8
Issues
1) Should vertex attribute zero be instance-able?
Resolved: Yes.
Discussion: In Direct3D 9 stream 0 must be specified as indexed data
and it cannot be instanced. In ANGLE we can work around this by
remapping any other stream that does have indexed data (ie a zero
attribute divisor) to stream 0 in D3D9. This works because the HLSL
vertex shader matches attributes against the stream by using the
shader semantic index.
2) Can all vertex attributes be instanced simultaneously?
Resolved: No
Discussion: In rare cases it is possible for no attribute to have a
divisor of 0, meaning that all attributes are instanced and none of
them are regularly indexed. This in turn means each instance can only
have a single position element, and so it only actually renders
something when rendering point primitives. This is not a very
meaningful way of using instancing (which is likely why D3D restricts
stream 0 to be indexed regularly for position data in the first place).
We could implement it by drawing these points one at a time (essentially
emulating instancing), but it would not be very efficient and there
seems to be little-to-no value in doing so.
If all of the enabled vertex attribute arrays that are bound to active
generic attributes in the program have a non-zero divisor, the draw
call should return INVALID_OPERATION.
3) Direct3D 9 only supports instancing for DrawIndexedPrimitive which
corresponds to DrawElementsInstanced. Should we support
DrawArraysInstanced?
Resolved: Yes
Discussion: This can be supported easily enough by simply manufacturing
a linear index buffer of sufficient size and using that to do indexed
D3D9 drawing.
4) How much data is needed in a buffer for an instanced attribute?
Resolved: Where stride is the value passed to VertexAttribPointer:
if stride > 0
size = stride * ceil(primcount / divisor);
else
size = elementsize * ceil(primcount / divisor);
Revision History
#3 February 8, 2012 dgkoch
- clarify Issue 3 and the error condition for no indexed attributes
#2 January 24, 2012 dgkoch
- fix typos, add clarifications, and more errors
#1 January 17, 2012 dgkoch
- initial GLES2 version from ARB_instanced_arrays

View File

@ -18,16 +18,16 @@ Contributors
Status
XXX - Not complete yet!!!
Implemented in ANGLE ES2
Version
Last Modified Date: November 22, 2011
Author Revision: 1
Last Modified Date: February 22, 2011
Author Revision: 22
Number
XXX not yet
TBD
Dependencies
@ -59,9 +59,6 @@ IP Status
No known IP claims.
Issues
New Procedures and Functions
None
@ -108,6 +105,8 @@ Additions to Chapter 3 of the OpenGL 3.2 Specification (Rasterization)
is packed in the same manner as when PACK_REVERSE_ROW_ORDER_ANGLE is
FALSE.
Additions to Chapter 6 of the OpenGL 3.2 Specification (State and State Requests)
In Section 6.1.4 add the following sentence to the fifth paragraph
(beginning with "For three-dimensional and two-dimensional array
textures..."):
@ -142,23 +141,29 @@ New Implementation Dependent State
None
Issues
None
Sample Code
/* Allocate space to hold the pixel data */
const GLvoid* pixels = malloc(width * height * 4);
/* Bind the framebuffer object to be read */
glBindFramebuffer(READ_FRAMEBUFFER, framebuffer);
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
/* Enable row order reversal */
glPixelStore(PACK_REVERSE_ROW_ORDER_ANGLE, TRUE);
glPixelStore(GL_PACK_REVERSE_ROW_ORDER_ANGLE, TRUE);
/* The pixel data stored in pixels will be in top-down order, ready for
* use with a windowing system API that expects this order.
*/
glReadPixels(x, y, width, height, RGBA, UNSIGNED_BYTE, pixels);
glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
Revision History
Revision 1, 2011/11/22 (Brian Salomon)
- First version
Revision 2, 2012/02/22 (dgkoch)
- prepare for publishing

View File

@ -233,6 +233,11 @@ typedef void* GLeglImageOES;
#define GL_FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3
#endif
/* GL_ANGLE_instanced_arrays */
#ifndef GL_ANGLE_instanced_arrays
#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE
#endif
/*------------------------------------------------------------------------*
* APPLE extension tokens
*------------------------------------------------------------------------*/
@ -951,6 +956,19 @@ typedef void (GL_APIENTRYP PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC) (GLuint shad
#define GL_ANGLE_texture_usage 1
#endif
/* GL_ANGLE_instanced_arrays */
#ifndef GL_ANGLE_instanced_arrays
#define GL_ANGLE_instanced_arrays 1
#ifdef GL_GLEXT_PROTOTYPES
GL_APICALL void GL_APIENTRY glVertexAttribDivisorANGLE(GLuint index, GLuint divisor);
GL_APICALL void GL_APIENTRY glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount);
GL_APICALL void GL_APIENTRY glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
#endif
typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORANGLEPROC) (GLuint index, GLuint divisor);
typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDANGLEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDANGLEPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
#endif
/*------------------------------------------------------------------------*
* APPLE extension functions
*------------------------------------------------------------------------*/

View File

@ -17,31 +17,31 @@
'translator/translator.cpp',
],
},
{
'target_name': 'essl_to_hlsl',
'type': 'executable',
'dependencies': [
'../src/build_angle.gyp:translator_hlsl',
],
'include_dirs': [
'../include',
'../src',
],
'sources': [
'translator/translator.cpp',
'../src/common/debug.cpp',
],
'msvs_settings': {
'VCLinkerTool': {
'AdditionalLibraryDirectories': ['$(DXSDK_DIR)/lib/x86'],
'AdditionalDependencies': ['d3d9.lib'],
}
}
},
],
'conditions': [
['OS=="win"', {
'targets': [
{
'target_name': 'essl_to_hlsl',
'type': 'executable',
'dependencies': [
'../src/build_angle.gyp:translator_hlsl',
],
'include_dirs': [
'../include',
'../src',
],
'sources': [
'translator/translator.cpp',
'../src/common/debug.cpp',
],
'msvs_settings': {
'VCLinkerTool': {
'AdditionalLibraryDirectories': ['$(DXSDK_DIR)/lib/x86'],
'AdditionalDependencies': ['d3d9.lib'],
}
}
},
{
'target_name': 'es_util',
'type': 'static_library',

View File

@ -171,7 +171,7 @@ esOrtho(ESMatrix *result, float left, float right, float bottom, float top, floa
void ESUTIL_API
esMatrixMultiply(ESMatrix *result, ESMatrix *srcA, ESMatrix *srcB)
{
ESMatrix tmp;
ESMatrix tmp = { 0.0f };
int i;
for (i=0; i<4; i++)

View File

@ -26,6 +26,9 @@
#include "esUtil.h"
#include "esUtil_win.h"
#if defined(_MSC_VER)
#pragma warning(disable: 4204) // nonstandard extension used : non-constant aggregate initializer
#endif
///
// Extensions

View File

@ -151,7 +151,7 @@ GLuint CreateMipMappedTexture2D( )
int level;
GLubyte *pixels;
GLubyte *prevImage;
GLubyte *newImage;
GLubyte *newImage = NULL;
pixels = GenCheckImage( width, height, 8 );
if ( pixels == NULL )

View File

@ -219,7 +219,8 @@ ShShaderType FindShaderType(const char* fileName)
if (ext && strcmp(ext, ".sl") == 0)
for (; ext > fileName && ext[0] != '.'; ext--);
if (ext = strrchr(fileName, '.')) {
ext = strrchr(fileName, '.');
if (ext) {
if (strncmp(ext, ".frag", 4) == 0) return SH_FRAGMENT_SHADER;
if (strncmp(ext, ".vert", 4) == 0) return SH_VERTEX_SHADER;
}

View File

@ -3,9 +3,6 @@
# found in the LICENSE file.
{
'variables': {
'chromium_code': 1,
},
'target_defaults': {
'defines': [
'ANGLE_DISABLE_TRACE',
@ -13,9 +10,27 @@
],
},
'targets': [
{
'target_name': 'preprocessor',
'type': 'static_library',
'include_dirs': [
],
'sources': [
'compiler/preprocessor/new/Input.cpp',
'compiler/preprocessor/new/Input.h',
'compiler/preprocessor/new/Lexer.cpp',
'compiler/preprocessor/new/Lexer.h',
'compiler/preprocessor/new/pp_lex.cpp',
'compiler/preprocessor/new/Preprocessor.cpp',
'compiler/preprocessor/new/Preprocessor.h',
'compiler/preprocessor/new/Token.cpp',
'compiler/preprocessor/new/Token.h',
],
},
{
'target_name': 'translator_common',
'type': 'static_library',
'dependencies': ['preprocessor'],
'include_dirs': [
'.',
'../include',
@ -76,6 +91,7 @@
'compiler/ValidateLimitations.h',
'compiler/VariableInfo.cpp',
'compiler/VariableInfo.h',
# Old preprocessor
'compiler/preprocessor/atom.c',
'compiler/preprocessor/atom.h',
'compiler/preprocessor/compile.h',
@ -83,6 +99,8 @@
'compiler/preprocessor/cpp.h',
'compiler/preprocessor/cppstruct.c',
'compiler/preprocessor/length_limits.h',
'compiler/preprocessor/lexer_glue.cpp',
'compiler/preprocessor/lexer_glue.h',
'compiler/preprocessor/memory.c',
'compiler/preprocessor/memory.h',
'compiler/preprocessor/parser.h',
@ -131,34 +149,34 @@
'compiler/VersionGLSL.h',
],
},
{
'target_name': 'translator_hlsl',
'type': '<(component)',
'dependencies': ['translator_common'],
'include_dirs': [
'.',
'../include',
],
'defines': [
'COMPILER_IMPLEMENTATION',
],
'sources': [
'compiler/ShaderLang.cpp',
'compiler/CodeGenHLSL.cpp',
'compiler/OutputHLSL.cpp',
'compiler/OutputHLSL.h',
'compiler/TranslatorHLSL.cpp',
'compiler/TranslatorHLSL.h',
'compiler/UnfoldSelect.cpp',
'compiler/UnfoldSelect.h',
'compiler/SearchSymbol.cpp',
'compiler/SearchSymbol.h',
],
},
],
'conditions': [
['OS=="win"', {
'targets': [
{
'target_name': 'translator_hlsl',
'type': '<(component)',
'dependencies': ['translator_common'],
'include_dirs': [
'.',
'../include',
],
'defines': [
'COMPILER_IMPLEMENTATION',
],
'sources': [
'compiler/ShaderLang.cpp',
'compiler/CodeGenHLSL.cpp',
'compiler/OutputHLSL.cpp',
'compiler/OutputHLSL.h',
'compiler/TranslatorHLSL.cpp',
'compiler/TranslatorHLSL.h',
'compiler/UnfoldSelect.cpp',
'compiler/UnfoldSelect.h',
'compiler/SearchSymbol.cpp',
'compiler/SearchSymbol.h',
],
},
{
'target_name': 'libGLESv2',
'type': 'shared_library',

View File

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

View File

@ -47,6 +47,7 @@ enum TBasicType
EbtGuardSamplerEnd, // non type: see implementation of IsSampler()
EbtStruct,
EbtAddress, // should be deprecated??
EbtInvariant, // used as a type when qualifying a previously declared variable as being invariant
};
inline const char* getBasicString(TBasicType t)

View File

@ -16,11 +16,6 @@ namespace {
// 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)",
@ -41,11 +36,6 @@ const char* kFunctionEmulationVertexSource[] = {
"#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)",
@ -58,42 +48,32 @@ const char* kFunctionEmulationVertexSource[] = {
};
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)",
"#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)",
"#error no emulation for dot(float, float)",
"#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)",
"#error no emulation for length(float)",
"#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)",
"#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)",
"#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)",
"#error no emulation for reflect(float, float)",
"#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)"
@ -102,10 +82,6 @@ const char* kFunctionEmulationFragmentSource[] = {
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
@ -122,10 +98,6 @@ const bool kFunctionEmulationVertexMask[] = {
false, // TFunctionLength2
false, // TFunctionLength3
false, // TFunctionLength4
false, // TFunctionMod1_1
false, // TFunctionMod2_2
false, // TFunctionMod3_3
false, // TFunctionMod4_4
true, // TFunctionNormalize1
false, // TFunctionNormalize2
false, // TFunctionNormalize3
@ -136,10 +108,6 @@ const bool kFunctionEmulationVertexMask[] = {
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
@ -156,10 +124,6 @@ const bool kFunctionEmulationVertexMask[] = {
false, // TFunctionLength2
false, // TFunctionLength3
false, // TFunctionLength4
false, // TFunctionMod1_1
true, // TFunctionMod2_2
true, // TFunctionMod3_3
true, // TFunctionMod4_4
false, // TFunctionNormalize1
false, // TFunctionNormalize2
false, // TFunctionNormalize3
@ -173,22 +137,38 @@ const bool kFunctionEmulationVertexMask[] = {
};
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.
// Work around ATI driver bugs in Mac.
true, // TFunctionCos1
true, // TFunctionCos2
true, // TFunctionCos3
true, // 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
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, // TFunctionCos1
false, // TFunctionCos2
false, // TFunctionCos3
false, // TFunctionCos4
#endif
false, // TFunctionDistance1_1
false, // TFunctionDistance2_2
false, // TFunctionDistance3_3
@ -201,10 +181,6 @@ const bool kFunctionEmulationFragmentMask[] = {
false, // TFunctionLength2
false, // TFunctionLength3
false, // TFunctionLength4
false, // TFunctionMod1_1
false, // TFunctionMod2_2
false, // TFunctionMod3_3
false, // TFunctionMod4_4
false, // TFunctionNormalize1
false, // TFunctionNormalize2
false, // TFunctionNormalize3
@ -213,6 +189,7 @@ const bool kFunctionEmulationFragmentMask[] = {
false, // TFunctionReflect2_2
false, // TFunctionReflect3_3
false, // TFunctionReflect4_4
#endif
false // TFunctionUnknown
};
@ -386,18 +363,12 @@ BuiltInFunctionEmulator::IdentifyFunction(
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;

View File

@ -45,12 +45,7 @@ private:
// Built-in functions.
//
enum TBuiltInFunction {
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);
TFunctionCos1 = 0, // float cos(float);
TFunctionCos2, // vec2 cos(vec2);
TFunctionCos3, // vec3 cos(vec3);
TFunctionCos4, // vec4 cos(vec4);
@ -70,11 +65,6 @@ private:
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);

View File

@ -11,6 +11,10 @@
class ConstantUnion {
public:
ConstantUnion()
{
iConst = 0;
}
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
void setIConst(int i) {iConst = i; type = EbtInt; }
@ -54,8 +58,6 @@ public:
default:
return false;
}
return false;
}
bool operator!=(const int i) const
@ -89,8 +91,6 @@ public:
default:
return false; // Invalid operation, handled at semantic analysis
}
return false;
}
bool operator<(const ConstantUnion& constant) const
@ -104,8 +104,6 @@ public:
default:
return false; // Invalid operation, handled at semantic analysis
}
return false;
}
ConstantUnion operator+(const ConstantUnion& constant) const

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@ -373,7 +373,7 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode,
// their operator to EOpSequence.
//
// Returns an aggregate node, which could be the one passed in if
// it was already an aggregate.
// it was already an aggregate but no operator was set.
//
TIntermAggregate* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, TSourceLoc line)
{
@ -592,10 +592,10 @@ TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nod
//
if (cond->getAsTyped() && cond->getAsTyped()->getAsConstantUnion()) {
if (cond->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->getBConst())
return nodePair.node1;
if (cond->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->getBConst() == true)
return nodePair.node1 ? setAggregateOperator(nodePair.node1, EOpSequence, nodePair.node1->getLine()) : NULL;
else
return nodePair.node2;
return nodePair.node2 ? setAggregateOperator(nodePair.node2, EOpSequence, nodePair.node2->getLine()) : NULL;
}
TIntermSelection* node = new TIntermSelection(cond, nodePair.node1, nodePair.node2);
@ -656,6 +656,7 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true
// Make a selection node.
//
TIntermSelection* node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType());
node->getTypePointer()->setQualifier(EvqTemporary);
node->setLine(line);
return node;
@ -1371,8 +1372,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
newNode->setLine(getLine());
return newNode;
}
return this;
}
TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node)

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@ -67,7 +67,10 @@ OutputHLSL::OutputHLSL(TParseContext &context) : TIntermTraverser(true, true, tr
mUsesEqualBVec2 = false;
mUsesEqualBVec3 = false;
mUsesEqualBVec4 = false;
mUsesAtan2 = false;
mUsesAtan2_1 = false;
mUsesAtan2_2 = false;
mUsesAtan2_3 = false;
mUsesAtan2_4 = false;
mScopeDepth = 0;
@ -703,7 +706,7 @@ void OutputHLSL::header()
"}\n";
}
if (mUsesAtan2)
if (mUsesAtan2_1)
{
out << "float atanyx(float y, float x)\n"
"{\n"
@ -711,6 +714,39 @@ void OutputHLSL::header()
" return atan2(y, x);\n"
"}\n";
}
if (mUsesAtan2_2)
{
out << "float2 atanyx(float2 y, float2 x)\n"
"{\n"
" if(x[0] == 0 && y[0] == 0) x[0] = 1;\n"
" if(x[1] == 0 && y[1] == 0) x[1] = 1;\n"
" return float2(atan2(y[0], x[0]), atan2(y[1], x[1]));\n"
"}\n";
}
if (mUsesAtan2_3)
{
out << "float3 atanyx(float3 y, float3 x)\n"
"{\n"
" if(x[0] == 0 && y[0] == 0) x[0] = 1;\n"
" if(x[1] == 0 && y[1] == 0) x[1] = 1;\n"
" if(x[2] == 0 && y[2] == 0) x[2] = 1;\n"
" return float3(atan2(y[0], x[0]), atan2(y[1], x[1]), atan2(y[2], x[2]));\n"
"}\n";
}
if (mUsesAtan2_4)
{
out << "float4 atanyx(float4 y, float4 x)\n"
"{\n"
" if(x[0] == 0 && y[0] == 0) x[0] = 1;\n"
" if(x[1] == 0 && y[1] == 0) x[1] = 1;\n"
" if(x[2] == 0 && y[2] == 0) x[2] = 1;\n"
" if(x[3] == 0 && y[3] == 0) x[3] = 1;\n"
" return float4(atan2(y[0], x[0]), atan2(y[1], x[1]), atan2(y[2], x[2]), atan2(y[3], x[3]));\n"
"}\n";
}
}
void OutputHLSL::visitSymbol(TIntermSymbol *node)
@ -861,7 +897,7 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
case EOpIndexDirectStruct:
if (visit == InVisit)
{
out << "." + node->getType().getFieldName();
out << "." + decorateField(node->getType().getFieldName(), node->getLeft()->getType());
return false;
}
@ -937,9 +973,9 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
const TType *fieldType = (*fields)[i].type;
node->getLeft()->traverse(this);
out << "." + fieldType->getFieldName() + " == ";
out << "." + decorateField(fieldType->getFieldName(), node->getLeft()->getType()) + " == ";
node->getRight()->traverse(this);
out << "." + fieldType->getFieldName();
out << "." + decorateField(fieldType->getFieldName(), node->getLeft()->getType());
if (i < fields->size() - 1)
{
@ -1032,8 +1068,6 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
{
TInfoSinkBase &out = mBody;
switch (node->getOp())
{
case EOpNegative: outputTriplet(visit, "(-", "", ")"); break;
@ -1110,7 +1144,6 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
{
ShShaderType shaderType = mContext.shaderType;
TInfoSinkBase &out = mBody;
switch (node->getOp())
@ -1252,7 +1285,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
return false;
}
break;
case EOpComma: outputTriplet(visit, "", ", ", ""); break;
case EOpComma: outputTriplet(visit, "(", ", ", ")"); break;
case EOpFunction:
{
TString name = TFunction::unmangleName(node->getName());
@ -1279,6 +1312,11 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
if (symbol)
{
if (symbol->getType().getStruct())
{
addConstructor(symbol->getType(), scopedStruct(symbol->getType().getTypeName()), NULL);
}
out << argumentString(symbol);
if (i < arguments.size() - 1)
@ -1497,7 +1535,14 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpPow: outputTriplet(visit, "pow(", ", ", ")"); break;
case EOpAtan:
ASSERT(node->getSequence().size() == 2); // atan(x) is a unary operator
mUsesAtan2 = true;
switch (node->getSequence()[0]->getAsTyped()->getNominalSize())
{
case 1: mUsesAtan2_1 = true; break;
case 2: mUsesAtan2_2 = true; break;
case 3: mUsesAtan2_3 = true; break;
case 4: mUsesAtan2_4 = true; break;
default: UNREACHABLE();
}
outputTriplet(visit, "atanyx(", ", ", ")");
break;
case EOpMin: outputTriplet(visit, "min(", ", ", ")"); break;
@ -1595,14 +1640,14 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
if (node->getType() == ELoopDoWhile)
{
out << "do\n";
out << "{do\n";
outputLineDirective(node->getLine());
out << "{\n";
}
else
{
out << "for(";
out << "{for(";
if (node->getInit())
{
@ -1644,10 +1689,10 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
node->getCondition()->traverse(this);
out << ")";
out << ");";
}
out << ";\n";
out << "}\n";
return false;
}
@ -1839,7 +1884,6 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
while (iterations > 0)
{
int remainder = (limit - initial) % increment;
int clampedLimit = initial + increment * std::min(255, iterations);
// for(int index = initial; index < clampedLimit; index += increment)
@ -1968,7 +2012,7 @@ TString OutputHLSL::typeString(const TType &type)
{
const TType &field = *fields[i].type;
string += " " + typeString(field) + " " + field.getFieldName() + arrayString(field) + ";\n";
string += " " + typeString(field) + " " + decorate(field.getFieldName()) + arrayString(field) + ";\n";
}
string += "} ";
@ -2062,6 +2106,11 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI
return; // Nameless structures don't have constructors
}
if (type.getStruct() && mStructNames.find(decorate(name)) != mStructNames.end())
{
return; // Already added
}
TType ctorType = type;
ctorType.clearArrayness();
ctorType.setPrecision(EbpHigh);
@ -2086,7 +2135,7 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI
{
const TType &field = *fields[i].type;
structure += " " + typeString(field) + " " + field.getFieldName() + arrayString(field) + ";\n";
structure += " " + typeString(field) + " " + decorateField(field.getFieldName(), type) + arrayString(field) + ";\n";
}
structure += "};\n";
@ -2385,4 +2434,14 @@ TString OutputHLSL::decorateUniform(const TString &string, const TType &type)
return decorate(string);
}
TString OutputHLSL::decorateField(const TString &string, const TType &structure)
{
if (structure.getTypeName().compare(0, 3, "gl_") != 0)
{
return decorate(string);
}
return string;
}
}

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@ -33,6 +33,7 @@ class OutputHLSL : public TIntermTraverser
static TString initializer(const TType &type);
static TString decorate(const TString &string); // Prepends an underscore to avoid naming clashes
static TString decorateUniform(const TString &string, const TType &type);
static TString decorateField(const TString &string, const TType &structure);
protected:
void header();
@ -113,7 +114,10 @@ class OutputHLSL : public TIntermTraverser
bool mUsesEqualBVec2;
bool mUsesEqualBVec3;
bool mUsesEqualBVec4;
bool mUsesAtan2;
bool mUsesAtan2_1;
bool mUsesAtan2_2;
bool mUsesAtan2_3;
bool mUsesAtan2_4;
typedef std::set<TString> Constructors;
Constructors mConstructors;

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@ -463,10 +463,8 @@ bool TParseContext::reservedErrorCheck(int line, const TString& identifier)
}
}
if (identifier.find("__") != TString::npos) {
//error(line, "Two consecutive underscores are reserved for future use.", identifier.c_str(), "", "");
//return true;
infoSink.info.message(EPrefixWarning, "Two consecutive underscores are reserved for future use.", line);
return false;
error(line, "identifiers containing two consecutive underscores (__) are reserved as possible future keywords", identifier.c_str(), "", "");
return true;
}
}
@ -1490,8 +1488,9 @@ int PaParseStrings(int count, const char* const string[], const int length[],
if (glslang_initialize(context))
return 1;
glslang_scan(count, string, length, context);
int error = glslang_parse(context);
int error = glslang_scan(count, string, length, context);
if (!error)
error = glslang_parse(context);
glslang_finalize(context);
FinalizePreprocessor();

View File

@ -157,8 +157,13 @@ void TAllocation::checkGuardBlock(unsigned char* blockMem, unsigned char val, co
char assertMsg[80];
// We don't print the assert message. It's here just to be helpful.
sprintf(assertMsg, "PoolAlloc: Damage %s %lu byte allocation at 0x%p\n",
#if defined(_MSC_VER)
sprintf(assertMsg, "PoolAlloc: Damage %s %Iu byte allocation at 0x%p\n",
locText, size, data());
#else
sprintf(assertMsg, "PoolAlloc: Damage %s %zu byte allocation at 0x%p\n",
locText, size, data());
#endif
assert(0 && "PoolAlloc: Damage in guard block");
}
}

View File

@ -9,6 +9,10 @@
// are documented in the header file.
//
#if defined(_MSC_VER)
#pragma warning(disable: 4718)
#endif
#include "compiler/SymbolTable.h"
#include <stdio.h>

View File

@ -302,6 +302,12 @@ public:
assert(table.size() >= 2);
return table[1];
}
TSymbolTableLevel* getOuterLevel() {
assert(table.size() >= 2);
return table[currentLevel() - 1];
}
void relateToOperator(const char* name, TOperator op) {
table[0]->relateToOperator(name, op);
}

View File

@ -10,7 +10,6 @@
#include "compiler/BaseTypes.h"
#include "compiler/Common.h"
#include "compiler/compilerdebug.h"
#include <cstdlib>
//
// Need to have association of line numbers to types in a list for building structs.
@ -209,7 +208,7 @@ public:
const TString& getTypeName() const
{
if(!typeName) abort();
assert(typeName);
return *typeName;
}
void setTypeName(const TString& n)

View File

@ -8,9 +8,9 @@ struct TParseContext;
extern int glslang_initialize(TParseContext* context);
extern int glslang_finalize(TParseContext* context);
extern void glslang_scan(int count,
const char* const string[],
const int length[],
TParseContext* context);
extern int glslang_scan(int count,
const char* const string[],
const int length[],
TParseContext* context);
extern int glslang_parse(TParseContext* context);

View File

@ -1,6 +1,6 @@
/*
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@ -15,7 +15,7 @@ WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp).
%top{
//
// Copyright (c) 2010 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@ -24,9 +24,14 @@ WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp).
// Ignore errors in auto-generated code.
#if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wswitch-enum"
#elif defined(_MSC_VER)
#pragma warning(disable: 4065)
#pragma warning(disable: 4189)
#pragma warning(disable: 4505)
#pragma warning(disable: 4701)
#endif
}
@ -154,6 +159,7 @@ O [0-7]
"extern" { return reserved_word(yyscanner); }
"external" { return reserved_word(yyscanner); }
"interface" { return reserved_word(yyscanner); }
"flat" { return reserved_word(yyscanner); }
"long" { return reserved_word(yyscanner); }
"short" { return reserved_word(yyscanner); }
@ -161,6 +167,7 @@ O [0-7]
"half" { return reserved_word(yyscanner); }
"fixed" { return reserved_word(yyscanner); }
"unsigned" { return reserved_word(yyscanner); }
"superp" { return reserved_word(yyscanner); }
"input" { return reserved_word(yyscanner); }
"output" { return reserved_word(yyscanner); }
@ -168,12 +175,21 @@ O [0-7]
"hvec2" { return reserved_word(yyscanner); }
"hvec3" { return reserved_word(yyscanner); }
"hvec4" { return reserved_word(yyscanner); }
"fvec2" { return reserved_word(yyscanner); }
"fvec3" { return reserved_word(yyscanner); }
"fvec4" { return reserved_word(yyscanner); }
"dvec2" { return reserved_word(yyscanner); }
"dvec3" { return reserved_word(yyscanner); }
"dvec4" { return reserved_word(yyscanner); }
"fvec2" { return reserved_word(yyscanner); }
"fvec3" { return reserved_word(yyscanner); }
"fvec4" { return reserved_word(yyscanner); }
"sampler1D" { return reserved_word(yyscanner); }
"sampler3D" { return reserved_word(yyscanner); }
"sampler1DShadow" { return reserved_word(yyscanner); }
"sampler2DShadow" { return reserved_word(yyscanner); }
"sampler3DRect" { return reserved_word(yyscanner); }
"sampler2DRectShadow" { return reserved_word(yyscanner); }
"sizeof" { return reserved_word(yyscanner); }
"cast" { return reserved_word(yyscanner); }
@ -563,19 +579,15 @@ int glslang_finalize(TParseContext* context) {
return yylex_destroy(scanner);
}
void glslang_scan(int count, const char* const string[], const int length[],
TParseContext* context) {
int glslang_scan(int count, const char* const string[], const int length[],
TParseContext* context) {
yyrestart(NULL, context->scanner);
yyset_lineno(EncodeSourceLoc(0, 1), context->scanner);
context->AfterEOF = false;
// Init preprocessor.
cpp->pC = context;
cpp->PaWhichStr = 0;
cpp->PaArgv = string;
cpp->PaArgc = count;
cpp->PaStrLen = length;
cpp->pastFirstStatement = 0;
ScanFromString(string[0]);
return InitScannerInput(cpp, count, string, length);
}

View File

@ -24,9 +24,14 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
// Ignore errors in auto-generated code.
#if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wswitch-enum"
#elif defined(_MSC_VER)
#pragma warning(disable: 4065)
#pragma warning(disable: 4189)
#pragma warning(disable: 4505)
#pragma warning(disable: 4701)
#endif
#include "compiler/SymbolTable.h"
@ -136,7 +141,7 @@ extern void yyerror(TParseContext* context, const char* reason);
%type <interm.intermNode> declaration external_declaration
%type <interm.intermNode> for_init_statement compound_statement_no_new_scope
%type <interm.nodePair> selection_rest_statement for_rest_statement
%type <interm.intermNode> iteration_statement jump_statement statement_no_new_scope
%type <interm.intermNode> iteration_statement jump_statement statement_no_new_scope statement_with_scope
%type <interm> single_declaration init_declarator_list
%type <interm> parameter_declaration parameter_declarator parameter_type_specifier
@ -975,6 +980,8 @@ declaration
prototype->setOp(EOpPrototype);
$$ = prototype;
context->symbolTable.pop();
}
| init_declarator_list SEMICOLON {
if ($1.intermAggregate)
@ -1019,7 +1026,9 @@ function_prototype
$$.function = $1;
$$.line = $2.line;
context->symbolTable.insert(*$$.function);
// We're at the inner scope level of the function's arguments and body statement.
// Add the function prototype to the surrounding scope instead.
context->symbolTable.getOuterLevel()->insert(*$$.function);
}
;
@ -1077,6 +1086,8 @@ function_header
TType type($1);
function = new TFunction($2.string, type);
$$ = function;
context->symbolTable.push();
}
;
@ -1178,6 +1189,12 @@ init_declarator_list
$$ = $1;
}
| init_declarator_list COMMA IDENTIFIER {
if ($1.type.type == EbtInvariant && !$3.symbol)
{
context->error($3.line, "undeclared identifier declared as invariant", $3.string->c_str(), "");
context->recover();
}
TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$3.string, TType($1.type), $3.line);
$$.intermAggregate = context->intermediate.growAggregate($1.intermNode, symbol, $3.line);
@ -1342,8 +1359,21 @@ single_declaration
}
| INVARIANT IDENTIFIER {
VERTEX_ONLY("invariant declaration", $1.line);
$$.qualifier = EvqInvariantVaryingOut;
$$.intermAggregate = 0;
if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "invariant varying"))
context->recover();
$$.type.setBasic(EbtInvariant, EvqInvariantVaryingOut, $2.line);
if (!$2.symbol)
{
context->error($2.line, "undeclared identifier declared as invariant", $2.string->c_str(), "");
context->recover();
$$.intermAggregate = 0;
}
else
{
TIntermSymbol *symbol = context->intermediate.addSymbol(0, *$2.string, TType($$.type), $2.line);
$$.intermAggregate = context->intermediate.makeAggregate(symbol, $2.line);
}
}
//
@ -1807,6 +1837,11 @@ statement_no_new_scope
| simple_statement { $$ = $1; }
;
statement_with_scope
: { context->symbolTable.push(); } compound_statement_no_new_scope { context->symbolTable.pop(); $$ = $2; }
| { context->symbolTable.push(); } simple_statement { context->symbolTable.pop(); $$ = $2; }
;
compound_statement_no_new_scope
// Statement that doesn't create a new scope, for selection_statement, iteration_statement
: LEFT_BRACE RIGHT_BRACE {
@ -1844,11 +1879,11 @@ selection_statement
;
selection_rest_statement
: statement ELSE statement {
: statement_with_scope ELSE statement_with_scope {
$$.node1 = $1;
$$.node2 = $3;
}
| statement {
| statement_with_scope {
$$.node1 = $1;
$$.node2 = 0;
}
@ -1885,7 +1920,7 @@ iteration_statement
$$ = context->intermediate.addLoop(ELoopWhile, 0, $4, 0, $6, $1.line);
--context->loopNestingLevel;
}
| DO { ++context->loopNestingLevel; } statement WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON {
| DO { ++context->loopNestingLevel; } statement_with_scope WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON {
if (context->boolErrorCheck($8.line, $6))
context->recover();
@ -2021,11 +2056,6 @@ function_definition
}
}
//
// New symbol table scope for body of function plus its arguments
//
context->symbolTable.push();
//
// Remember the return type for later checking for RETURN statements.
//
@ -2078,7 +2108,7 @@ function_definition
context->error($1.line, "function does not return a value:", "", $1.function->getName().c_str());
context->recover();
}
context->symbolTable.pop();
$$ = context->intermediate.growAggregate($1.intermAggregate, $3, 0);
context->intermediate.setAggregateOperator($$, EOpFunction, $1.line);
$$->getAsAggregate()->setName($1.function->getMangledName().c_str());
@ -2092,6 +2122,8 @@ function_definition
if ($3 && $3->getAsAggregate())
$$->getAsAggregate()->setEndLine($3->getAsAggregate()->getEndLine());
context->symbolTable.pop();
}
;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,24 +1,22 @@
/* A Bison parser, made by GNU Bison 2.3. */
/* A Bison parser, made by GNU Bison 2.4.2. */
/* Skeleton interface for Bison's Yacc-like parsers in C
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
Copyright (C) 1984, 1989-1990, 2000-2006, 2009-2010 Free Software
Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@ -29,10 +27,11 @@
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
@ -134,108 +133,14 @@
QUESTION = 350
};
#endif
/* Tokens. */
#define INVARIANT 258
#define HIGH_PRECISION 259
#define MEDIUM_PRECISION 260
#define LOW_PRECISION 261
#define PRECISION 262
#define ATTRIBUTE 263
#define CONST_QUAL 264
#define BOOL_TYPE 265
#define FLOAT_TYPE 266
#define INT_TYPE 267
#define BREAK 268
#define CONTINUE 269
#define DO 270
#define ELSE 271
#define FOR 272
#define IF 273
#define DISCARD 274
#define RETURN 275
#define BVEC2 276
#define BVEC3 277
#define BVEC4 278
#define IVEC2 279
#define IVEC3 280
#define IVEC4 281
#define VEC2 282
#define VEC3 283
#define VEC4 284
#define MATRIX2 285
#define MATRIX3 286
#define MATRIX4 287
#define IN_QUAL 288
#define OUT_QUAL 289
#define INOUT_QUAL 290
#define UNIFORM 291
#define VARYING 292
#define STRUCT 293
#define VOID_TYPE 294
#define WHILE 295
#define SAMPLER2D 296
#define SAMPLERCUBE 297
#define SAMPLER_EXTERNAL_OES 298
#define SAMPLER2DRECT 299
#define IDENTIFIER 300
#define TYPE_NAME 301
#define FLOATCONSTANT 302
#define INTCONSTANT 303
#define BOOLCONSTANT 304
#define FIELD_SELECTION 305
#define LEFT_OP 306
#define RIGHT_OP 307
#define INC_OP 308
#define DEC_OP 309
#define LE_OP 310
#define GE_OP 311
#define EQ_OP 312
#define NE_OP 313
#define AND_OP 314
#define OR_OP 315
#define XOR_OP 316
#define MUL_ASSIGN 317
#define DIV_ASSIGN 318
#define ADD_ASSIGN 319
#define MOD_ASSIGN 320
#define LEFT_ASSIGN 321
#define RIGHT_ASSIGN 322
#define AND_ASSIGN 323
#define XOR_ASSIGN 324
#define OR_ASSIGN 325
#define SUB_ASSIGN 326
#define LEFT_PAREN 327
#define RIGHT_PAREN 328
#define LEFT_BRACKET 329
#define RIGHT_BRACKET 330
#define LEFT_BRACE 331
#define RIGHT_BRACE 332
#define DOT 333
#define COMMA 334
#define COLON 335
#define EQUAL 336
#define SEMICOLON 337
#define BANG 338
#define DASH 339
#define TILDE 340
#define PLUS 341
#define STAR 342
#define SLASH 343
#define PERCENT 344
#define LEFT_ANGLE 345
#define RIGHT_ANGLE 346
#define VERTICAL_BAR 347
#define CARET 348
#define AMPERSAND 349
#define QUESTION 350
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
{
struct {
TSourceLoc line;
union {
@ -265,14 +170,15 @@ typedef union YYSTYPE
TTypeList* typeList;
};
} interm;
}
/* Line 1489 of yacc.c. */
YYSTYPE;
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif

View File

@ -53,6 +53,12 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "compiler/preprocessor/slglobals.h"
#if defined(_MSC_VER)
#pragma warning(disable: 4054)
#pragma warning(disable: 4152)
#pragma warning(disable: 4706)
#endif
static int CPPif(yystypepp * yylvalpp);
/* Don't use memory.c's replacements, as we clean up properly here */
@ -682,9 +688,7 @@ static int CPPpragma(yystypepp * yylvalpp)
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
}
cpp->currentInput->ungetch(cpp->currentInput, token, yylvalpp);
HandlePragma((const char**)allTokens, tokenCount);
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
for (i = 0; i < tokenCount; ++i) {
free (allTokens[i]);

View File

@ -73,7 +73,7 @@ void CPPShInfoLogMsg(const char*); // Store cpp Err Msg into Sh.Info.Lo
void CPPWarningToInfoLog(const char *msg); // Prints warning messages into info log
void HandlePragma(const char**, int numTokens); // #pragma directive container.
void ResetTString(void); // #error Message as TString.
void CPPErrorToInfoLog(char*); // Stick all cpp errors into Sh.Info.log .
void CPPErrorToInfoLog(const char*); // Stick all cpp errors into Sh.Info.log .
void StoreStr(char*); // Store the TString in Parse Context.
void SetLineNumber(int); // Set line number.
void SetStringNumber(int); // Set string number.

View File

@ -0,0 +1,151 @@
//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include <stdlib.h>
#include <string.h>
extern "C" {
#include "compiler/preprocessor/lexer_glue.h"
#include "compiler/preprocessor/slglobals.h"
#include "compiler/preprocessor/scanner.h"
}
#include "compiler/preprocessor/new/Lexer.h"
#include "compiler/preprocessor/new/Token.h"
struct InputSrcLexer
{
InputSrc base;
pp::Lexer* lexer;
};
static bool CopySymbolName(const std::string& name, yystypepp* yylvalpp)
{
if (name.length() > MAX_SYMBOL_NAME_LEN)
{
CPPErrorToInfoLog("BUFFER OVERFLOW");
return false;
}
strcpy(yylvalpp->symbol_name, name.c_str());
return true;
}
static int lex(InputSrc* in, yystypepp* yylvalpp)
{
InputSrcLexer* src = ((InputSrcLexer *)in);
pp::Token token;
int ret = src->lexer->lex(&token);
switch (ret)
{
case 0: // EOF
delete src->lexer;
free(src);
cpp->currentInput = 0;
ret = EOF;
break;
case pp::Token::IDENTIFIER:
if (CopySymbolName(token.value, yylvalpp))
{
yylvalpp->sc_ident = LookUpAddString(atable, token.value.c_str());
}
ret = CPP_IDENTIFIER;
break;
case pp::Token::CONST_INT:
if (CopySymbolName(token.value, yylvalpp))
{
yylvalpp->sc_int = atoi(token.value.c_str());
}
ret = CPP_INTCONSTANT;
break;
case pp::Token::CONST_FLOAT:
CopySymbolName(token.value, yylvalpp);
ret = CPP_FLOATCONSTANT;
break;
case pp::Token::OP_INC:
ret = CPP_INC_OP;
break;
case pp::Token::OP_DEC:
ret = CPP_DEC_OP;
break;
case pp::Token::OP_RIGHT:
ret = CPP_RIGHT_OP;
break;
case pp::Token::OP_LE:
ret = CPP_LE_OP;
break;
case pp::Token::OP_GE:
ret = CPP_GE_OP;
break;
case pp::Token::OP_EQ:
ret = CPP_EQ_OP;
break;
case pp::Token::OP_NE:
ret = CPP_NE_OP;
break;
case pp::Token::OP_AND:
ret = CPP_AND_OP;
break;
case pp::Token::OP_XOR:
ret = CPP_XOR_OP;
break;
case pp::Token::OP_OR:
ret = CPP_OR_OP;
break;
case pp::Token::OP_ADD_ASSIGN:
ret = CPP_ADD_ASSIGN;
break;
case pp::Token::OP_SUB_ASSIGN:
ret = CPP_SUB_ASSIGN;
break;
case pp::Token::OP_MUL_ASSIGN:
ret = CPP_MUL_ASSIGN;
break;
case pp::Token::OP_DIV_ASSIGN:
ret = CPP_DIV_ASSIGN;
break;
case pp::Token::OP_MOD_ASSIGN:
ret = CPP_MOD_ASSIGN;
break;
case pp::Token::OP_LEFT_ASSIGN:
ret = CPP_LEFT_ASSIGN;
break;
case pp::Token::OP_RIGHT_ASSIGN:
ret = CPP_RIGHT_ASSIGN;
break;
case pp::Token::OP_AND_ASSIGN:
ret = CPP_AND_ASSIGN;
break;
case pp::Token::OP_XOR_ASSIGN:
ret = CPP_XOR_ASSIGN;
break;
case pp::Token::OP_OR_ASSIGN:
ret = CPP_OR_ASSIGN;
break;
default:
break;
}
SetLineNumber(token.location.line);
SetStringNumber(token.location.string);
return ret;
}
InputSrc* LexerInputSrc(int count, const char* const string[], const int length[])
{
pp::Lexer* lexer = new pp::Lexer;
if (!lexer->init(count, string, length))
{
delete lexer;
return 0;
}
InputSrcLexer* in = (InputSrcLexer *) malloc(sizeof(InputSrcLexer));
memset(in, 0, sizeof(InputSrcLexer));
in->base.line = 1;
in->base.scan = lex;
in->lexer = lexer;
return &in->base;
}

View File

@ -0,0 +1,15 @@
//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#ifndef COMPILER_PREPROCESSOR_LEXER_GLUE_H_
#define COMPILER_PREPROCESSOR_LEXER_GLUE_H_
struct InputSrc;
InputSrc* LexerInputSrc(int count, const char* const string[], const int length[]);
#endif // COMPILER_PREPROCESSOR_LEXER_GLUE_H_

View File

@ -52,6 +52,10 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "compiler/preprocessor/memory.h"
#if defined(_MSC_VER)
#pragma warning(disable: 4706)
#endif
// default alignment and chunksize, if called with 0 arguments
#define CHUNKSIZE (64*1024)
#define ALIGN 8

View File

@ -45,6 +45,8 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef __MEMORY_H
#define __MEMORY_H
#include <stddef.h>
typedef struct MemoryPool_rec MemoryPool;
extern MemoryPool *mem_CreatePool(size_t chunksize, unsigned int align);

View File

@ -10,6 +10,7 @@
#include <sstream>
#include "compiler/debug.h"
#include "Lexer.h"
#include "stl_utils.h"
#include "token_type.h"
@ -31,24 +32,12 @@ static bool isMacroNameReserved(const std::string* name)
namespace pp
{
Context::Context()
: mLexer(NULL),
mInput(NULL),
mOutput(NULL)
Context::Context() : 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,
@ -59,7 +48,8 @@ bool Context::process(int count,
ASSERT((count >=0) && (string != NULL) && (output != NULL));
// Setup.
mInput = new Input(count, string, length);
mLexer.reset(new Lexer);
if (!mLexer->init(count, string, length)) return false;
mOutput = output;
defineBuiltInMacro("GL_ES", 1);
@ -71,6 +61,11 @@ bool Context::process(int count,
return success;
}
int Context::lex(YYSTYPE* lvalp, YYLTYPE* llocp)
{
return mLexer->lex(lvalp, llocp);
}
bool Context::defineMacro(pp::Token::Location location,
pp::Macro::Type type,
std::string* name,
@ -116,10 +111,8 @@ void Context::reset()
std::for_each(mMacros.begin(), mMacros.end(), DeleteSecond());
mMacros.clear();
delete mInput;
mInput = NULL;
mOutput = NULL;
mLexer.reset();
}
void Context::defineBuiltInMacro(const std::string& name, int value)

View File

@ -10,27 +10,30 @@
#include <map>
#include "common/angleutils.h"
#include "Input.h"
#include "Macro.h"
#include "Token.h"
struct YYLTYPE;
union YYSTYPE;
namespace pp
{
class Lexer;
class Context
{
public:
Context();
~Context();
bool init();
bool process(int count, const char* const string[], const int length[],
TokenVector* output);
void* lexer() { return mLexer; }
int readInput(char* buf, int maxSize);
TokenVector* output() { return mOutput; }
int lex(YYSTYPE* lvalp, YYLTYPE* llocp);
bool defineMacro(pp::Token::Location location,
pp::Macro::Type type,
std::string* name,
@ -44,13 +47,10 @@ class 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;
std::auto_ptr<Lexer> mLexer;
TokenVector* mOutput;
MacroSet mMacros; // Defined macros.
};

View File

@ -6,10 +6,9 @@
#include "Input.h"
#include <cassert>
#include <cstdio>
#include "compiler/debug.h"
namespace pp
{
@ -22,13 +21,13 @@ Input::Input(int count, const char* const string[], const int length[])
mError(kErrorNone),
mState(kStateInitial)
{
ASSERT(mCount >= 0);
assert(mCount >= 0);
switchToNextString();
}
bool Input::eof() const
{
ASSERT(mIndex <= mCount);
assert(mIndex <= mCount);
return mIndex == mCount;
}
@ -96,7 +95,7 @@ int Input::read(char* buf, int bufSize)
break;
default:
ASSERT(false);
assert(false);
break;
}
}
@ -114,7 +113,7 @@ int Input::getChar()
// Switch to next string if the current one is fully read.
int length = stringLength(mIndex);
// We never read from empty string.
ASSERT(length != 0);
assert(length != 0);
if (((length < 0) && (str[mSize] == '\0')) ||
((length > 0) && (mSize == length)))
switchToNextString();
@ -137,7 +136,7 @@ int Input::peekChar()
void Input::switchToNextString()
{
ASSERT(mIndex < mCount);
assert(mIndex < mCount);
mSize = 0;
do
@ -148,7 +147,7 @@ void Input::switchToNextString()
bool Input::isStringEmpty(int index)
{
ASSERT(index < mCount);
assert(index < mCount);
const char* str = mString[mIndex];
int length = stringLength(mIndex);
@ -157,7 +156,7 @@ bool Input::isStringEmpty(int index)
int Input::stringLength(int index)
{
ASSERT(index < mCount);
assert(index < mCount);
return mLength ? mLength[index] : -1;
}

View File

@ -0,0 +1,36 @@
//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "Lexer.h"
#include <cassert>
#include "Input.h"
namespace pp
{
Lexer::Lexer() : mHandle(0), mLeadingSpace(false)
{
}
Lexer::~Lexer()
{
destroyLexer();
}
bool Lexer::init(int count, const char* const string[], const int length[])
{
assert((count >=0) && (string != NULL));
if ((count < 0) || (string == NULL))
return false;
mInput.reset(new Input(count, string, length));
return initLexer();
}
} // namespace pp

View File

@ -0,0 +1,42 @@
//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#ifndef COMPILER_PREPROCESSOR_LEXER_H_
#define COMPILER_PREPROCESSOR_LEXER_H_
#include <memory>
#include "pp_utils.h"
namespace pp
{
class Input;
struct Token;
class Lexer
{
public:
Lexer();
~Lexer();
bool init(int count, const char* const string[], const int length[]);
int lex(Token* token);
private:
PP_DISALLOW_COPY_AND_ASSIGN(Lexer);
bool initLexer();
void destroyLexer();
void* mHandle; // Lexer handle.
bool mLeadingSpace;
std::auto_ptr<Input> mInput; // Input buffer.
};
} // namespace pp
#endif // COMPILER_PREPROCESSOR_LEXER_H_

View File

@ -6,47 +6,19 @@
#include "Preprocessor.h"
#include <algorithm>
#include "compiler/debug.h"
#include "Context.h"
#include "stl_utils.h"
namespace pp
{
Preprocessor::Preprocessor() : mContext(NULL)
bool Preprocessor::init(int count,
const char* const string[],
const int length[])
{
return mLexer.init(count, string, length);
}
Preprocessor::~Preprocessor()
int Preprocessor::lex(Token* token)
{
delete mContext;
}
bool Preprocessor::init()
{
mContext = new Context;
return mContext->init();
}
bool Preprocessor::process(int count,
const char* const string[],
const int length[])
{
ASSERT((count >=0) && (string != NULL));
if ((count < 0) || (string == NULL))
return false;
reset();
return mContext->process(count, string, length, &mTokens);
}
void Preprocessor::reset()
{
std::for_each(mTokens.begin(), mTokens.end(), Delete());
mTokens.clear();
return mLexer.lex(token);
}
} // namespace pp

View File

@ -7,34 +7,23 @@
#ifndef COMPILER_PREPROCESSOR_PREPROCESSOR_H_
#define COMPILER_PREPROCESSOR_PREPROCESSOR_H_
#include "common/angleutils.h"
#include "Token.h"
#include "Lexer.h"
#include "pp_utils.h"
namespace pp
{
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(); }
bool init(int count, const char* const string[], const int length[]);
int lex(Token* token);
private:
DISALLOW_COPY_AND_ASSIGN(Preprocessor);
// Reset to initialized state.
void reset();
Context* mContext;
TokenVector mTokens; // Output.
PP_DISALLOW_COPY_AND_ASSIGN(Preprocessor);
Lexer mLexer;
};
} // namespace pp

View File

@ -6,50 +6,16 @@
#include "Token.h"
#include "token_type.h"
static const int kLocationLineSize = 16; // in bits.
static const int kLocationLineMask = (1 << kLocationLineSize) - 1;
namespace pp
{
Token::Location Token::encodeLocation(int line, int file)
{
return (file << kLocationLineSize) | (line & kLocationLineMask);
}
void Token::decodeLocation(Location loc, int* line, int* file)
{
if (file) *file = loc >> kLocationLineSize;
if (line) *line = loc & kLocationLineMask;
}
Token::Token(Location location, int type, std::string* value)
: mLocation(location),
mType(type),
mValue(value)
{
}
Token::~Token() {
delete mValue;
}
std::ostream& operator<<(std::ostream& out, const Token& token)
{
switch (token.type())
{
case INT_CONSTANT:
case FLOAT_CONSTANT:
case IDENTIFIER:
out << *(token.value());
break;
default:
out << static_cast<char>(token.type());
break;
}
if (token.hasLeadingSpace())
out << " ";
out << token.value;
return out;
}
} // namespace pp
} // namespace pp

View File

@ -7,42 +7,85 @@
#ifndef COMPILER_PREPROCESSOR_TOKEN_H_
#define COMPILER_PREPROCESSOR_TOKEN_H_
#include <ostream>
#include <string>
#include <vector>
#include "common/angleutils.h"
namespace pp
{
class Token
struct Token
{
public:
typedef int Location;
static Location encodeLocation(int line, int file);
static void decodeLocation(Location loc, int* line, int* file);
enum Type
{
IDENTIFIER = 258,
// Takes ownership of string.
Token(Location location, int type, std::string* value);
~Token();
CONST_INT,
CONST_FLOAT,
Location location() const { return mLocation; }
int type() const { return mType; }
const std::string* value() const { return mValue; }
OP_INC,
OP_DEC,
OP_LEFT,
OP_RIGHT,
OP_LE,
OP_GE,
OP_EQ,
OP_NE,
OP_AND,
OP_XOR,
OP_OR,
OP_ADD_ASSIGN,
OP_SUB_ASSIGN,
OP_MUL_ASSIGN,
OP_DIV_ASSIGN,
OP_MOD_ASSIGN,
OP_LEFT_ASSIGN,
OP_RIGHT_ASSIGN,
OP_AND_ASSIGN,
OP_XOR_ASSIGN,
OP_OR_ASSIGN
};
enum Flags
{
HAS_LEADING_SPACE = 1 << 0
};
struct Location
{
Location() : line(0), string(0) { }
bool equals(const Location& other) const
{
return (line == other.line) && (string == other.string);
}
private:
DISALLOW_COPY_AND_ASSIGN(Token);
int line;
int string;
};
Location mLocation;
int mType;
std::string* mValue;
Token() : type(0), flags(0) { }
bool equals(const Token& other) const
{
return (type == other.type) &&
(flags == other.flags) &&
(location.equals(other.location)) &&
(value == other.value);
}
bool hasLeadingSpace() const { return (flags & HAS_LEADING_SPACE) != 0; }
void setHasLeadingSpace(bool space)
{
if (space)
flags |= HAS_LEADING_SPACE;
else
flags &= ~HAS_LEADING_SPACE;
}
int type;
int flags;
Location location;
std::string value;
};
typedef std::vector<Token*> TokenVector;
typedef TokenVector::const_iterator TokenIterator;
extern std::ostream& operator<<(std::ostream& out, const Token& token);
} // namepsace pp
#endif // COMPILER_PREPROCESSOR_TOKEN_H_

View File

@ -23,31 +23,30 @@ 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 "Input.h"
#include "Lexer.h"
#include "Token.h"
#define YY_USER_ACTION \
do { \
yylloc->first_line = yylineno; \
yylloc->first_column = yycolumn + 1; \
yycolumn += yyleng; \
typedef std::string YYSTYPE;
typedef pp::Token::Location YYLTYPE;
#define YY_USER_ACTION \
do { \
yylloc->line = yylineno; \
yylloc->string = 0; \
} while(0);
#define YY_INPUT(buf, result, maxSize) \
result = yyextra->readInput(buf, maxSize);
static std::string* extractMacroName(const char* str, int len);
result = readInput(buf, maxSize, yyscanner);
static int readInput(char* buf, int maxSize, yyscan_t scanner);
%}
%option noyywrap nounput never-interactive
%option yylineno reentrant bison-bridge bison-locations
%option stack
%option prefix="pp"
%option extra-type="pp::Context*"
%option extra-type="pp::Input*"
HSPACE [ \t]
HASH ^{HSPACE}*#{HSPACE}*
IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]*
PUNCTUATOR [][<>(){}.+-/*%^|&~=!:;,?]
@ -61,120 +60,98 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".")
%%
{HASH} { return HASH; }
{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; }
{HASH}ifndef { return HASH_IFNDEF; }
{HASH}else { return HASH_ELSE; }
{HASH}elif { return HASH_ELIF; }
{HASH}endif { return HASH_ENDIF; }
"defined" { return DEFINED; }
{HASH}error { return HASH_ERROR; }
{HASH}pragma { return HASH_PRAGMA; }
{HASH}extension { return HASH_EXTENSION; }
{HASH}version { return HASH_VERSION; }
{HASH}line { return HASH_LINE; }
# { return yytext[0]; }
{IDENTIFIER} {
yylval->sval = new std::string(yytext, yyleng);
return IDENTIFIER;
yylval->assign(yytext, yyleng);
return pp::Token::IDENTIFIER;
}
{DECIMAL_CONSTANT}|{OCTAL_CONSTANT}|{HEXADECIMAL_CONSTANT} {
yylval->sval = new std::string(yytext, yyleng);
return INT_CONSTANT;
yylval->assign(yytext, yyleng);
return pp::Token::CONST_INT;
}
({DIGIT}+{EXPONENT_PART})|({FRACTIONAL_CONSTANT}{EXPONENT_PART}?) {
yylval->sval = new std::string(yytext, yyleng);
return FLOAT_CONSTANT;
yylval->assign(yytext, yyleng);
return pp::Token::CONST_FLOAT;
}
"++" { return pp::Token::OP_INC; }
"--" { return pp::Token::OP_DEC; }
"<<" { return pp::Token::OP_LEFT; }
">>" { return pp::Token::OP_RIGHT; }
"<=" { return pp::Token::OP_LE; }
">=" { return pp::Token::OP_GE; }
"==" { return pp::Token::OP_EQ; }
"!=" { return pp::Token::OP_NE; }
"&&" { return pp::Token::OP_AND; }
"^^" { return pp::Token::OP_XOR; }
"||" { return pp::Token::OP_OR; }
"+=" { return pp::Token::OP_ADD_ASSIGN; }
"-=" { return pp::Token::OP_SUB_ASSIGN; }
"*=" { return pp::Token::OP_MUL_ASSIGN; }
"/=" { return pp::Token::OP_DIV_ASSIGN; }
"%=" { return pp::Token::OP_MOD_ASSIGN; }
"<<=" { return pp::Token::OP_LEFT_ASSIGN; }
">>=" { return pp::Token::OP_RIGHT_ASSIGN; }
"&=" { return pp::Token::OP_AND_ASSIGN; }
"^=" { return pp::Token::OP_XOR_ASSIGN; }
"|=" { return pp::Token::OP_OR_ASSIGN; }
{PUNCTUATOR} { return yytext[0]; }
[ \t\v\f]+ { return ' '; }
\n { return yytext[0]; }
[ \t\v\f]+ { /* Ignore whitespace */ }
\n {
++yylineno; yycolumn = 0;
return yytext[0];
}
<*><<EOF>> { yyterminate(); }
<*><<EOF>> { yyterminate(); }
%%
std::string* extractMacroName(const char* str, int len)
{
// 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 readInput(char* buf, int maxSize, yyscan_t scanner)
{
int nread = YY_NULL;
while (!mInput->eof() &&
(mInput->error() == pp::Input::kErrorNone) &&
pp::Input* input = yyget_extra(scanner);
while (!input->eof() &&
(input->error() == pp::Input::kErrorNone) &&
(nread == YY_NULL))
{
int line = 0, file = 0;
pp::Token::decodeLocation(yyget_lineno(mLexer), &line, &file);
file = mInput->stringIndex();
yyset_lineno(pp::Token::encodeLocation(line, file), mLexer);
nread = mInput->read(buf, maxSize);
if (mInput->error() == pp::Input::kErrorUnexpectedEOF)
{
// TODO(alokp): Report error.
}
nread = input->read(buf, maxSize);
}
return nread;
}
bool Context::initLexer()
{
ASSERT(mLexer == NULL);
namespace pp {
if (yylex_init_extra(this, &mLexer))
int Lexer::lex(Token* token)
{
token->type = yylex(&token->value, &token->location, mHandle);
while (token->type == ' ')
{
mLeadingSpace = true;
token->type = yylex(&token->value, &token->location, mHandle);
}
token->setHasLeadingSpace(mLeadingSpace);
mLeadingSpace = false;
return token->type;
}
bool Lexer::initLexer()
{
if ((mHandle == NULL) && yylex_init_extra(mInput.get(), &mHandle))
return false;
yyrestart(0, mLexer);
yyrestart(0, mHandle);
return true;
}
void Context::destroyLexer()
void Lexer::destroyLexer()
{
ASSERT(mLexer);
if (mHandle == NULL)
return;
yylex_destroy(mLexer);
mLexer = NULL;
yylex_destroy(mHandle);
mHandle = NULL;
}
} // namespace pp

View File

@ -22,9 +22,13 @@ WHICH GENERATES THE GLSL ES PARSER.
// This file is auto-generated by generate_glslang_parser.sh. DO NOT EDIT!
#if defined(__GNUC__)
#elif defined(_MSC_VER)
#pragma warning(disable: 4065)
#endif
#include "Context.h"
#define YYLEX_PARAM context->lexer()
#define YYDEBUG 1
%}
@ -32,6 +36,7 @@ WHICH GENERATES THE GLSL ES PARSER.
%name-prefix="pp"
%locations
%parse-param {pp::Context* context}
%lex-param {pp::Context* context}
%union {
int ival;
@ -41,7 +46,7 @@ WHICH GENERATES THE GLSL ES PARSER.
}
%{
extern int yylex(YYSTYPE* lvalp, YYLTYPE* llocp, void* lexer);
static int yylex(YYSTYPE* lvalp, YYLTYPE* llocp, pp::Context* context);
static void yyerror(YYLTYPE* llocp,
pp::Context* context,
const char* reason);
@ -203,6 +208,11 @@ operator
%%
int yylex(YYSTYPE* lvalp, YYLTYPE* llocp, pp::Context* context)
{
return context->lex(lvalp, llocp);
}
void yyerror(YYLTYPE* llocp, pp::Context* context, const char* reason)
{
}

View File

@ -1,4 +1,4 @@
#line 16 "compiler/preprocessor/new/pp.l"
#line 16 "./pp.l"
//
// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@ -9,7 +9,7 @@
#line 13 "compiler/preprocessor/new/pp_lex.cpp"
#line 13 "./pp_lex.cpp"
#define YY_INT_ALIGNED short int
@ -371,8 +371,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
*yy_cp = '\0'; \
yyg->yy_c_buf_p = yy_cp;
#define YY_NUM_RULES 23
#define YY_END_OF_BUFFER 24
#define YY_NUM_RULES 29
#define YY_END_OF_BUFFER 30
/* This struct is not used in this scanner,
but its presence is necessary. */
struct yy_trans_info
@ -380,38 +380,33 @@ struct yy_trans_info
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
static yyconst flex_int16_t yy_accept[105] =
static yyconst flex_int16_t yy_accept[62] =
{ 0,
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,
3, 0, 14, 0
0, 0, 30, 29, 27, 28, 26, 1, 26, 26,
26, 26, 26, 26, 26, 26, 3, 3, 26, 26,
26, 2, 26, 26, 27, 12, 20, 13, 23, 18,
5, 16, 6, 17, 4, 19, 4, 3, 0, 0,
0, 3, 7, 9, 11, 10, 8, 2, 24, 14,
25, 15, 0, 0, 4, 3, 21, 22, 0, 4,
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,
2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
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,
1, 2, 4, 1, 5, 1, 6, 7, 1, 8,
8, 9, 10, 8, 11, 12, 13, 14, 15, 15,
15, 15, 15, 15, 15, 16, 16, 8, 8, 17,
18, 19, 8, 1, 20, 20, 20, 20, 21, 20,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 23, 22, 22,
8, 1, 8, 24, 22, 1, 20, 20, 20, 20,
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,
21, 20, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22, 23,
22, 22, 8, 25, 8, 8, 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,
@ -428,107 +423,76 @@ static yyconst flex_int32_t yy_ec[256] =
1, 1, 1, 1, 1
} ;
static yyconst flex_int32_t yy_meta[34] =
static yyconst flex_int32_t yy_meta[26] =
{ 0,
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
1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
2, 3, 1, 4, 4, 4, 1, 1, 1, 5,
6, 7, 7, 1, 1
} ;
static yyconst flex_int16_t yy_base[111] =
static yyconst flex_int16_t yy_base[68] =
{ 0,
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,
185, 103, 185, 185, 110, 114, 118, 121, 126, 132
0, 0, 99, 100, 96, 100, 79, 100, 78, 19,
100, 77, 17, 18, 16, 76, 26, 22, 27, 74,
32, 0, 15, 28, 84, 100, 100, 100, 100, 100,
100, 100, 100, 100, 62, 100, 55, 37, 40, 46,
0, 40, 30, 100, 100, 100, 10, 0, 100, 100,
100, 100, 48, 48, 51, 0, 100, 100, 54, 57,
100, 71, 74, 78, 83, 84, 89
} ;
static yyconst flex_int16_t yy_def[111] =
static yyconst flex_int16_t yy_def[68] =
{ 0,
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,
104, 110, 104, 0, 104, 104, 104, 104, 104, 104
61, 1, 61, 61, 61, 61, 61, 61, 61, 61,
61, 61, 61, 61, 61, 61, 61, 62, 61, 61,
61, 63, 61, 61, 61, 61, 61, 61, 61, 61,
61, 61, 61, 61, 64, 61, 64, 17, 38, 65,
66, 62, 61, 61, 61, 61, 61, 63, 61, 61,
61, 61, 67, 61, 61, 66, 61, 61, 61, 61,
0, 61, 61, 61, 61, 61, 61
} ;
static yyconst flex_int16_t yy_nxt[219] =
static yyconst flex_int16_t yy_nxt[126] =
{ 0,
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,
4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 18, 19, 20, 21, 22,
22, 22, 22, 23, 24, 28, 31, 58, 33, 35,
35, 35, 49, 37, 32, 34, 29, 37, 50, 38,
38, 39, 40, 43, 44, 51, 40, 57, 41, 46,
47, 37, 52, 39, 39, 54, 54, 59, 59, 61,
40, 55, 55, 55, 55, 55, 55, 60, 60, 60,
60, 60, 60, 42, 42, 53, 42, 48, 48, 48,
48, 35, 53, 35, 55, 25, 55, 56, 56, 56,
60, 45, 60, 36, 30, 27, 26, 25, 61, 3,
97, 33, 34, 101, 100, 100, 93, 96, 95, 101,
11, 11, 11, 11, 11, 11, 11, 23, 23, 23,
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,
104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
104, 104, 104, 104, 104, 104, 104, 104
61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
61, 61, 61, 61, 61
} ;
static yyconst flex_int16_t yy_chk[219] =
static yyconst flex_int16_t yy_chk[126] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
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,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 10, 13, 47, 14, 15,
15, 15, 23, 18, 13, 14, 10, 17, 23, 17,
17, 17, 18, 19, 19, 24, 17, 43, 17, 21,
21, 42, 24, 39, 39, 40, 40, 53, 53, 38,
42, 54, 54, 54, 55, 55, 55, 59, 59, 59,
60, 60, 60, 62, 62, 37, 62, 63, 63, 63,
63, 64, 35, 64, 65, 25, 65, 66, 66, 66,
67, 20, 67, 16, 12, 9, 7, 5, 3, 61,
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,
104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
104, 104, 104, 104, 104, 104, 104, 104
61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
61, 61, 61, 61, 61
} ;
/* Table of booleans, true if rule could match eol. */
static yyconst flex_int32_t yy_rule_can_match_eol[24] =
static yyconst flex_int32_t yy_rule_can_match_eol[30] =
{ 0,
0, 1, 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, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 0, };
/* The intent behind this definition is that it'll catch
* any uses of REJECT which flex missed.
@ -551,25 +515,27 @@ http://msdn.microsoft.com/en-us/library/2scxys89.aspx
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 "Input.h"
#include "Lexer.h"
#include "Token.h"
#define YY_USER_ACTION \
do { \
yylloc->first_line = yylineno; \
yylloc->first_column = yycolumn + 1; \
yycolumn += yyleng; \
typedef std::string YYSTYPE;
typedef pp::Token::Location YYLTYPE;
#define YY_USER_ACTION \
do { \
yylloc->line = yylineno; \
yylloc->string = 0; \
} while(0);
#define YY_INPUT(buf, result, maxSize) \
result = yyextra->readInput(buf, maxSize);
static std::string* extractMacroName(const char* str, int len);
result = readInput(buf, maxSize, yyscanner);
static int readInput(char* buf, int maxSize, yyscan_t scanner);
#define INITIAL 0
#define YY_EXTRA_TYPE pp::Context*
#define YY_EXTRA_TYPE pp::Input*
/* Holds the entire state of the reentrant scanner. */
struct yyguts_t
@ -688,12 +654,6 @@ static int input (yyscan_t yyscanner );
#endif
static void yy_push_state (int new_state ,yyscan_t yyscanner);
static void yy_pop_state (yyscan_t yyscanner );
static int yy_top_state (yyscan_t yyscanner );
/* Amount of stuff to slurp up with each read. */
#ifndef YY_READ_BUF_SIZE
#define YY_READ_BUF_SIZE 8192
@ -789,9 +749,6 @@ extern int pplex \
#endif
#define YY_RULE_SETUP \
if ( yyleng > 0 ) \
YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \
(yytext[yyleng - 1] == '\n'); \
YY_USER_ACTION
/** The main scanner function which does all the work.
@ -846,7 +803,6 @@ YY_DECL
yy_bp = yy_cp;
yy_current_state = yyg->yy_start;
yy_current_state += YY_AT_BOL();
yy_match:
do
{
@ -859,13 +815,13 @@ yy_match:
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 >= 105 )
if ( yy_current_state >= 62 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
++yy_cp;
}
while ( yy_current_state != 104 );
while ( yy_current_state != 61 );
yy_cp = yyg->yy_last_accepting_cpos;
yy_current_state = yyg->yy_last_accepting_state;
@ -899,122 +855,130 @@ do_action: /* This label is used only to access EOF actions. */
case 1:
YY_RULE_SETUP
{ return HASH; }
{ return yytext[0]; }
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
{
yylval->sval = extractMacroName(yytext, yyleng);
return HASH_DEFINE_OBJ;
yylval->assign(yytext, yyleng);
return pp::Token::IDENTIFIER;
}
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
{
yylval->sval = extractMacroName(yytext, yyleng);
return HASH_DEFINE_FUNC;
yylval->assign(yytext, yyleng);
return pp::Token::CONST_INT;
}
YY_BREAK
case 4:
YY_RULE_SETUP
{ return HASH_UNDEF; }
{
yylval->assign(yytext, yyleng);
return pp::Token::CONST_FLOAT;
}
YY_BREAK
case 5:
YY_RULE_SETUP
{ return HASH_IF; }
{ return pp::Token::OP_INC; }
YY_BREAK
case 6:
YY_RULE_SETUP
{ return HASH_IFDEF; }
{ return pp::Token::OP_DEC; }
YY_BREAK
case 7:
YY_RULE_SETUP
{ return HASH_IFNDEF; }
{ return pp::Token::OP_LEFT; }
YY_BREAK
case 8:
YY_RULE_SETUP
{ return HASH_ELSE; }
{ return pp::Token::OP_RIGHT; }
YY_BREAK
case 9:
YY_RULE_SETUP
{ return HASH_ELIF; }
{ return pp::Token::OP_LE; }
YY_BREAK
case 10:
YY_RULE_SETUP
{ return HASH_ENDIF; }
{ return pp::Token::OP_GE; }
YY_BREAK
case 11:
YY_RULE_SETUP
{ return DEFINED; }
{ return pp::Token::OP_EQ; }
YY_BREAK
case 12:
YY_RULE_SETUP
{ return HASH_ERROR; }
{ return pp::Token::OP_NE; }
YY_BREAK
case 13:
YY_RULE_SETUP
{ return HASH_PRAGMA; }
{ return pp::Token::OP_AND; }
YY_BREAK
case 14:
YY_RULE_SETUP
{ return HASH_EXTENSION; }
{ return pp::Token::OP_XOR; }
YY_BREAK
case 15:
YY_RULE_SETUP
{ return HASH_VERSION; }
{ return pp::Token::OP_OR; }
YY_BREAK
case 16:
YY_RULE_SETUP
{ return HASH_LINE; }
{ return pp::Token::OP_ADD_ASSIGN; }
YY_BREAK
case 17:
YY_RULE_SETUP
{
yylval->sval = new std::string(yytext, yyleng);
return IDENTIFIER;
}
{ return pp::Token::OP_SUB_ASSIGN; }
YY_BREAK
case 18:
YY_RULE_SETUP
{
yylval->sval = new std::string(yytext, yyleng);
return INT_CONSTANT;
}
{ return pp::Token::OP_MUL_ASSIGN; }
YY_BREAK
case 19:
YY_RULE_SETUP
{
yylval->sval = new std::string(yytext, yyleng);
return FLOAT_CONSTANT;
}
{ return pp::Token::OP_DIV_ASSIGN; }
YY_BREAK
case 20:
YY_RULE_SETUP
{ return yytext[0]; }
{ return pp::Token::OP_MOD_ASSIGN; }
YY_BREAK
case 21:
YY_RULE_SETUP
{ /* Ignore whitespace */ }
{ return pp::Token::OP_LEFT_ASSIGN; }
YY_BREAK
case 22:
/* rule 22 can match eol */
YY_RULE_SETUP
{
++yylineno; yycolumn = 0;
return yytext[0];
}
{ return pp::Token::OP_RIGHT_ASSIGN; }
YY_BREAK
case 23:
YY_RULE_SETUP
{ return pp::Token::OP_AND_ASSIGN; }
YY_BREAK
case 24:
YY_RULE_SETUP
{ return pp::Token::OP_XOR_ASSIGN; }
YY_BREAK
case 25:
YY_RULE_SETUP
{ return pp::Token::OP_OR_ASSIGN; }
YY_BREAK
case 26:
YY_RULE_SETUP
{ return yytext[0]; }
YY_BREAK
case 27:
YY_RULE_SETUP
{ return ' '; }
YY_BREAK
case 28:
/* rule 28 can match eol */
YY_RULE_SETUP
{ return yytext[0]; }
YY_BREAK
case YY_STATE_EOF(INITIAL):
{ yyterminate(); }
YY_BREAK
case 23:
case 29:
YY_RULE_SETUP
ECHO;
YY_BREAK
@ -1298,7 +1262,6 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yy_current_state = yyg->yy_start;
yy_current_state += YY_AT_BOL();
for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
{
@ -1311,7 +1274,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
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 >= 105 )
if ( yy_current_state >= 62 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@ -1340,11 +1303,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
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 >= 105 )
if ( yy_current_state >= 62 )
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 == 104);
yy_is_jam = (yy_current_state == 61);
return yy_is_jam ? 0 : yy_current_state;
}
@ -1420,8 +1383,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
*yyg->yy_c_buf_p = '\0'; /* preserve yytext */
yyg->yy_hold_char = *++yyg->yy_c_buf_p;
YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n');
if ( YY_CURRENT_BUFFER_LVALUE->yy_at_bol )
if ( c == '\n' )
do{ yylineno++;
yycolumn=0;
@ -1790,46 +1752,6 @@ YY_BUFFER_STATE pp_scan_bytes (yyconst char * yybytes, int _yybytes_len , yysc
return b;
}
static void yy_push_state (int new_state , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
if ( yyg->yy_start_stack_ptr >= yyg->yy_start_stack_depth )
{
yy_size_t new_size;
yyg->yy_start_stack_depth += YY_START_STACK_INCR;
new_size = yyg->yy_start_stack_depth * sizeof( int );
if ( ! yyg->yy_start_stack )
yyg->yy_start_stack = (int *) ppalloc(new_size ,yyscanner );
else
yyg->yy_start_stack = (int *) pprealloc((void *) yyg->yy_start_stack,new_size ,yyscanner );
if ( ! yyg->yy_start_stack )
YY_FATAL_ERROR( "out of memory expanding start-condition stack" );
}
yyg->yy_start_stack[yyg->yy_start_stack_ptr++] = YY_START;
BEGIN(new_state);
}
static void yy_pop_state (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
if ( --yyg->yy_start_stack_ptr < 0 )
YY_FATAL_ERROR( "start-condition stack underflow" );
BEGIN(yyg->yy_start_stack[yyg->yy_start_stack_ptr]);
}
static int yy_top_state (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yyg->yy_start_stack[yyg->yy_start_stack_ptr - 1];
}
#ifndef YY_EXIT_FAILURE
#define YY_EXIT_FAILURE 2
#endif
@ -2202,66 +2124,51 @@ void ppfree (void * ptr , yyscan_t yyscanner)
#define YYTABLES_NAME "yytables"
std::string* extractMacroName(const char* str, int len)
{
// 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 readInput(char* buf, int maxSize, yyscan_t scanner)
{
int nread = YY_NULL;
while (!mInput->eof() &&
(mInput->error() == pp::Input::kErrorNone) &&
pp::Input* input = ppget_extra(scanner);
while (!input->eof() &&
(input->error() == pp::Input::kErrorNone) &&
(nread == YY_NULL))
{
int line = 0, file = 0;
pp::Token::decodeLocation(ppget_lineno(mLexer), &line, &file);
file = mInput->stringIndex();
ppset_lineno(pp::Token::encodeLocation(line, file),mLexer);
nread = mInput->read(buf, maxSize);
if (mInput->error() == pp::Input::kErrorUnexpectedEOF)
{
// TODO(alokp): Report error.
}
nread = input->read(buf, maxSize);
}
return nread;
}
bool Context::initLexer()
{
ASSERT(mLexer == NULL);
namespace pp {
if (pplex_init_extra(this,&mLexer))
int Lexer::lex(Token* token)
{
token->type = pplex(&token->value,&token->location,mHandle);
while (token->type == ' ')
{
mLeadingSpace = true;
token->type = pplex(&token->value,&token->location,mHandle);
}
token->setHasLeadingSpace(mLeadingSpace);
mLeadingSpace = false;
return token->type;
}
bool Lexer::initLexer()
{
if ((mHandle == NULL) && pplex_init_extra(mInput.get(),&mHandle))
return false;
pprestart(0,mLexer);
pprestart(0,mHandle);
return true;
}
void Context::destroyLexer()
void Lexer::destroyLexer()
{
ASSERT(mLexer);
if (mHandle == NULL)
return;
pplex_destroy(mLexer);
mLexer = NULL;
pplex_destroy(mHandle);
mHandle = NULL;
}
} // namespace pp

View File

@ -1,24 +1,22 @@
/* A Bison parser, made by GNU Bison 2.3. */
/* A Bison parser, made by GNU Bison 2.4.2. */
/* Skeleton implementation for Bison's Yacc-like parsers in C
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
Copyright (C) 1984, 1989-1990, 2000-2006, 2009-2010 Free Software
Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@ -29,7 +27,7 @@
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
@ -47,7 +45,7 @@
#define YYBISON 1
/* Bison version. */
#define YYBISON_VERSION "2.3"
#define YYBISON_VERSION "2.4.2"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@ -55,18 +53,65 @@
/* Pure parsers. */
#define YYPURE 1
/* Push parsers. */
#define YYPUSH 0
/* Pull parsers. */
#define YYPULL 1
/* Using locations. */
#define YYLSP_NEEDED 1
/* Substitute the variable and function names. */
#define yyparse ppparse
#define yylex pplex
#define yyerror pperror
#define yylval pplval
#define yychar ppchar
#define yydebug ppdebug
#define yynerrs ppnerrs
#define yylloc pplloc
#define yyparse ppparse
#define yylex pplex
#define yyerror pperror
#define yylval pplval
#define yychar ppchar
#define yydebug ppdebug
#define yynerrs ppnerrs
#define yylloc pplloc
/* Copy the first part of user declarations. */
//
// Copyright (c) 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.
//
// This file is auto-generated by generate_glslang_parser.sh. DO NOT EDIT!
#if defined(__GNUC__)
#elif defined(_MSC_VER)
#pragma warning(disable: 4065)
#endif
#include "Context.h"
#define YYDEBUG 1
/* Enabling traces. */
#ifndef YYDEBUG
# define YYDEBUG 0
#endif
/* Enabling verbose error messages. */
#ifdef YYERROR_VERBOSE
# undef YYERROR_VERBOSE
# define YYERROR_VERBOSE 1
#else
# define YYERROR_VERBOSE 0
#endif
/* Enabling the token table. */
#ifndef YYTOKEN_TABLE
# define YYTOKEN_TABLE 0
#endif
/* Tokens. */
#ifndef YYTOKENTYPE
@ -95,80 +140,25 @@
IDENTIFIER = 276
};
#endif
/* Tokens. */
#define HASH 258
#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
/* Copy the first part of user declarations. */
//
// Copyright (c) 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.
//
// This file is auto-generated by generate_glslang_parser.sh. DO NOT EDIT!
#include "Context.h"
#define YYLEX_PARAM context->lexer()
#define YYDEBUG 1
/* Enabling traces. */
#ifndef YYDEBUG
# define YYDEBUG 0
#endif
/* Enabling verbose error messages. */
#ifdef YYERROR_VERBOSE
# undef YYERROR_VERBOSE
# define YYERROR_VERBOSE 1
#else
# define YYERROR_VERBOSE 0
#endif
/* Enabling the token table. */
#ifndef YYTOKEN_TABLE
# define YYTOKEN_TABLE 0
#endif
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
{
int ival;
std::string* sval;
pp::Token* tval;
pp::TokenVector* tlist;
}
/* Line 187 of yacc.c. */
YYSTYPE;
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif
#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
@ -188,7 +178,7 @@ typedef struct YYLTYPE
/* Copy the second part of user declarations. */
extern int yylex(YYSTYPE* lvalp, YYLTYPE* llocp, void* lexer);
static int yylex(YYSTYPE* lvalp, YYLTYPE* llocp, pp::Context* context);
static void yyerror(YYLTYPE* llocp,
pp::Context* context,
const char* reason);
@ -197,8 +187,6 @@ static void pushConditionalBlock(pp::Context* context, bool condition);
static void popConditionalBlock(pp::Context* context);
/* Line 216 of yacc.c. */
#ifdef short
# undef short
@ -248,7 +236,7 @@ typedef short int yytype_int16;
#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
#ifndef YY_
# if YYENABLE_NLS
# if defined YYENABLE_NLS && YYENABLE_NLS
# if ENABLE_NLS
# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
# define YY_(msgid) dgettext ("bison-runtime", msgid)
@ -273,14 +261,14 @@ typedef short int yytype_int16;
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
static int
YYID (int i)
YYID (int yyi)
#else
static int
YYID (i)
int i;
YYID (yyi)
int yyi;
#endif
{
return i;
return yyi;
}
#endif
@ -362,9 +350,9 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
/* A type that is properly aligned for any stack member. */
union yyalloc
{
yytype_int16 yyss;
YYSTYPE yyvs;
YYLTYPE yyls;
yytype_int16 yyss_alloc;
YYSTYPE yyvs_alloc;
YYLTYPE yyls_alloc;
};
/* The size of the maximum gap between one aligned stack and the next. */
@ -399,12 +387,12 @@ union yyalloc
elements in the stack, and YYPTR gives the new location of the
stack. Advance YYPTR to a properly aligned location for the next
stack. */
# define YYSTACK_RELOCATE(Stack) \
# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
do \
{ \
YYSIZE_T yynewbytes; \
YYCOPY (&yyptr->Stack, Stack, yysize); \
Stack = &yyptr->Stack; \
YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
Stack = &yyptr->Stack_alloc; \
yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
yyptr += yynewbytes / sizeof (*yyptr); \
} \
@ -504,13 +492,13 @@ static const yytype_int8 yyrhs[] =
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const yytype_uint8 yyrline[] =
{
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
0, 68, 68, 70, 74, 75, 79, 80, 89, 90,
93, 96, 99, 102, 105, 108, 110, 112, 115, 116,
117, 118, 119, 123, 124, 127, 128, 132, 138, 142,
149, 153, 160, 162, 164, 168, 171, 174, 177, 183,
184, 185, 186, 187, 188, 189, 190, 191, 192, 193,
194, 195, 196, 197, 198, 199, 200, 201, 202, 203,
204, 205, 206
};
#endif
@ -708,9 +696,18 @@ static const yytype_uint8 yystos[] =
/* Like YYERROR except do call yyerror. This remains here temporarily
to ease the transition to the new meaning of YYERROR, for GCC.
Once GCC version 2 has supplanted version 1, this can go. */
Once GCC version 2 has supplanted version 1, this can go. However,
YYFAIL appears to be in use. Nevertheless, it is formally deprecated
in Bison 2.4.2's NEWS entry, where a plan to phase it out is
discussed. */
#define YYFAIL goto yyerrlab
#if defined YYFAIL
/* This is here to suppress warnings from the GCC cpp's
-Wunused-macros. Normally we don't worry about that warning, but
some users do, and we want to make it easy for users to remove
YYFAIL uses, which will produce warnings from Bison 2.5. */
#endif
#define YYRECOVERING() (!!yyerrstatus)
@ -767,7 +764,7 @@ while (YYID (0))
we won't break user code: when these are the locations we know. */
#ifndef YY_LOCATION_PRINT
# if YYLTYPE_IS_TRIVIAL
# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
# define YY_LOCATION_PRINT(File, Loc) \
fprintf (File, "%d.%d-%d.%d", \
(Loc).first_line, (Loc).first_column, \
@ -783,7 +780,7 @@ while (YYID (0))
#ifdef YYLEX_PARAM
# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
#else
# define YYLEX yylex (&yylval, &yylloc)
# define YYLEX yylex (&yylval, &yylloc, context)
#endif
/* Enable debugging if requested. */
@ -886,17 +883,20 @@ yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, context)
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
static void
yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
#else
static void
yy_stack_print (bottom, top)
yytype_int16 *bottom;
yytype_int16 *top;
yy_stack_print (yybottom, yytop)
yytype_int16 *yybottom;
yytype_int16 *yytop;
#endif
{
YYFPRINTF (stderr, "Stack now");
for (; bottom <= top; ++bottom)
YYFPRINTF (stderr, " %d", *bottom);
for (; yybottom <= yytop; yybottom++)
{
int yybot = *yybottom;
YYFPRINTF (stderr, " %d", yybot);
}
YYFPRINTF (stderr, "\n");
}
@ -932,11 +932,11 @@ yy_reduce_print (yyvsp, yylsp, yyrule, context)
/* The symbols being reduced. */
for (yyi = 0; yyi < yynrhs; yyi++)
{
fprintf (stderr, " $%d = ", yyi + 1);
YYFPRINTF (stderr, " $%d = ", yyi + 1);
yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
&(yyvsp[(yyi + 1) - (yynrhs)])
, &(yylsp[(yyi + 1) - (yynrhs)]) , context);
fprintf (stderr, "\n");
YYFPRINTF (stderr, "\n");
}
}
@ -1220,10 +1220,8 @@ yydestruct (yymsg, yytype, yyvaluep, yylocationp, context)
break;
}
}
/* Prevent warnings from -Wmissing-prototypes. */
#ifdef YYPARSE_PARAM
#if defined __STDC__ || defined __cplusplus
int yyparse (void *YYPARSE_PARAM);
@ -1242,10 +1240,9 @@ int yyparse ();
/*----------.
| yyparse. |
`----------*/
/*-------------------------.
| yyparse or yypush_parse. |
`-------------------------*/
#ifdef YYPARSE_PARAM
#if (defined __STDC__ || defined __C99__FUNC__ \
@ -1269,24 +1266,59 @@ yyparse (context)
#endif
#endif
{
/* The look-ahead symbol. */
/* The lookahead symbol. */
int yychar;
/* The semantic value of the look-ahead symbol. */
/* The semantic value of the lookahead symbol. */
YYSTYPE yylval;
/* Number of syntax errors so far. */
int yynerrs;
/* Location data for the look-ahead symbol. */
/* Location data for the lookahead symbol. */
YYLTYPE yylloc;
int yystate;
/* Number of syntax errors so far. */
int yynerrs;
int yystate;
/* Number of tokens to shift before error messages enabled. */
int yyerrstatus;
/* The stacks and their tools:
`yyss': related to states.
`yyvs': related to semantic values.
`yyls': related to locations.
Refer to the stacks thru separate pointers, to allow yyoverflow
to reallocate them elsewhere. */
/* The state stack. */
yytype_int16 yyssa[YYINITDEPTH];
yytype_int16 *yyss;
yytype_int16 *yyssp;
/* The semantic value stack. */
YYSTYPE yyvsa[YYINITDEPTH];
YYSTYPE *yyvs;
YYSTYPE *yyvsp;
/* The location stack. */
YYLTYPE yylsa[YYINITDEPTH];
YYLTYPE *yyls;
YYLTYPE *yylsp;
/* The locations where the error started and ended. */
YYLTYPE yyerror_range[2];
YYSIZE_T yystacksize;
int yyn;
int yyresult;
/* Number of tokens to shift before error messages enabled. */
int yyerrstatus;
/* Look-ahead token as an internal (translated) token number. */
int yytoken = 0;
/* Lookahead token as an internal (translated) token number. */
int yytoken;
/* The variables used to return semantic value and location from the
action routines. */
YYSTYPE yyval;
YYLTYPE yyloc;
#if YYERROR_VERBOSE
/* Buffer for error messages, and its allocated size. */
char yymsgbuf[128];
@ -1294,63 +1326,37 @@ YYLTYPE yylloc;
YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
#endif
/* Three stacks and their tools:
`yyss': related to states,
`yyvs': related to semantic values,
`yyls': related to locations.
Refer to the stacks thru separate pointers, to allow yyoverflow
to reallocate them elsewhere. */
/* The state stack. */
yytype_int16 yyssa[YYINITDEPTH];
yytype_int16 *yyss = yyssa;
yytype_int16 *yyssp;
/* The semantic value stack. */
YYSTYPE yyvsa[YYINITDEPTH];
YYSTYPE *yyvs = yyvsa;
YYSTYPE *yyvsp;
/* The location stack. */
YYLTYPE yylsa[YYINITDEPTH];
YYLTYPE *yyls = yylsa;
YYLTYPE *yylsp;
/* The locations where the error started and ended. */
YYLTYPE yyerror_range[2];
#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
YYSIZE_T yystacksize = YYINITDEPTH;
/* The variables used to return semantic value and location from the
action routines. */
YYSTYPE yyval;
YYLTYPE yyloc;
/* The number of symbols on the RHS of the reduced rule.
Keep to zero when no symbol should be popped. */
int yylen = 0;
yytoken = 0;
yyss = yyssa;
yyvs = yyvsa;
yyls = yylsa;
yystacksize = YYINITDEPTH;
YYDPRINTF ((stderr, "Starting parse\n"));
yystate = 0;
yyerrstatus = 0;
yynerrs = 0;
yychar = YYEMPTY; /* Cause a token to be read. */
yychar = YYEMPTY; /* Cause a token to be read. */
/* Initialize stack pointers.
Waste one element of value and location stack
so that they stay on the same level as the state stack.
The wasted elements are never initialized. */
yyssp = yyss;
yyvsp = yyvs;
yylsp = yyls;
#if YYLTYPE_IS_TRIVIAL
#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
/* Initialize the default location before parsing starts. */
yylloc.first_line = yylloc.last_line = 1;
yylloc.first_column = yylloc.last_column = 0;
yylloc.first_column = yylloc.last_column = 1;
#endif
goto yysetstate;
@ -1389,6 +1395,7 @@ YYLTYPE yylloc;
&yyvs1, yysize * sizeof (*yyvsp),
&yyls1, yysize * sizeof (*yylsp),
&yystacksize);
yyls = yyls1;
yyss = yyss1;
yyvs = yyvs1;
@ -1410,9 +1417,9 @@ YYLTYPE yylloc;
(union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
if (! yyptr)
goto yyexhaustedlab;
YYSTACK_RELOCATE (yyss);
YYSTACK_RELOCATE (yyvs);
YYSTACK_RELOCATE (yyls);
YYSTACK_RELOCATE (yyss_alloc, yyss);
YYSTACK_RELOCATE (yyvs_alloc, yyvs);
YYSTACK_RELOCATE (yyls_alloc, yyls);
# undef YYSTACK_RELOCATE
if (yyss1 != yyssa)
YYSTACK_FREE (yyss1);
@ -1433,6 +1440,9 @@ YYLTYPE yylloc;
YYDPRINTF ((stderr, "Entering state %d\n", yystate));
if (yystate == YYFINAL)
YYACCEPT;
goto yybackup;
/*-----------.
@ -1441,16 +1451,16 @@ YYLTYPE yylloc;
yybackup:
/* Do appropriate processing given the current state. Read a
look-ahead token if we need one and don't already have one. */
lookahead token if we need one and don't already have one. */
/* First try to decide what to do without reference to look-ahead token. */
/* First try to decide what to do without reference to lookahead token. */
yyn = yypact[yystate];
if (yyn == YYPACT_NINF)
goto yydefault;
/* Not known => get a look-ahead token if don't already have one. */
/* Not known => get a lookahead token if don't already have one. */
/* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
/* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
if (yychar == YYEMPTY)
{
YYDPRINTF ((stderr, "Reading a token: "));
@ -1482,20 +1492,16 @@ yybackup:
goto yyreduce;
}
if (yyn == YYFINAL)
YYACCEPT;
/* Count tokens shifted since error; after three, turn off error
status. */
if (yyerrstatus)
yyerrstatus--;
/* Shift the look-ahead token. */
/* Shift the lookahead token. */
YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
/* Discard the shifted token unless it is eof. */
if (yychar != YYEOF)
yychar = YYEMPTY;
/* Discard the shifted token. */
yychar = YYEMPTY;
yystate = yyn;
*++yyvsp = yylval;
@ -1542,78 +1548,78 @@ yyreduce:
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 9:
{
context->defineMacro((yylsp[(1) - (3)]).first_line, pp::Macro::kTypeObj, (yyvsp[(1) - (3)].sval), NULL, (yyvsp[(2) - (3)].tlist));
;}
}
break;
case 10:
{
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:
{
context->undefineMacro((yyvsp[(2) - (3)].sval));
;}
}
break;
case 12:
{
pushConditionalBlock(context, (yyvsp[(2) - (3)].tlist) ? true : false);
;}
}
break;
case 13:
{
pushConditionalBlock(context, context->isMacroDefined((yyvsp[(2) - (3)].sval)));
;}
}
break;
case 14:
{
pushConditionalBlock(context, !context->isMacroDefined((yyvsp[(2) - (3)].sval)));
;}
}
break;
case 15:
{
;}
}
break;
case 16:
{
;}
}
break;
case 17:
{
popConditionalBlock(context);
;}
}
break;
case 23:
{ (yyval.tlist) = NULL; ;}
{ (yyval.tlist) = NULL; }
break;
case 25:
{ (yyval.tlist) = NULL; ;}
{ (yyval.tlist) = NULL; }
break;
case 26:
@ -1621,7 +1627,7 @@ yyreduce:
{
(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:
@ -1629,7 +1635,7 @@ yyreduce:
{
(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:
@ -1637,7 +1643,7 @@ yyreduce:
{
(yyval.tlist) = new pp::TokenVector;
(yyval.tlist)->push_back((yyvsp[(1) - (1)].tval));
;}
}
break;
case 29:
@ -1645,7 +1651,7 @@ yyreduce:
{
(yyval.tlist) = (yyvsp[(1) - (2)].tlist);
(yyval.tlist)->push_back((yyvsp[(2) - (2)].tval));
;}
}
break;
case 30:
@ -1653,7 +1659,7 @@ yyreduce:
{
(yyval.tlist) = new pp::TokenVector;
(yyval.tlist)->push_back((yyvsp[(1) - (1)].tval));
;}
}
break;
case 31:
@ -1661,171 +1667,170 @@ yyreduce:
{
(yyval.tlist) = (yyvsp[(1) - (2)].tlist);
(yyval.tlist)->push_back((yyvsp[(2) - (2)].tval));
;}
}
break;
case 32:
{
;}
}
break;
case 33:
{
;}
}
break;
case 35:
{
(yyval.tval) = new pp::Token((yylsp[(1) - (1)]).first_line, (yyvsp[(1) - (1)].ival), NULL);
;}
}
break;
case 36:
{
(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, FLOAT_CONSTANT, (yyvsp[(1) - (1)].sval));
;}
}
break;
case 38:
{
(yyval.tval) = new pp::Token((yylsp[(1) - (1)]).first_line, IDENTIFIER, (yyvsp[(1) - (1)].sval));
;}
}
break;
case 39:
{ (yyval.ival) = '['; ;}
{ (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) = ','; ;}
{ (yyval.ival) = ','; }
break;
case 62:
{ (yyval.ival) = '?'; ;}
{ (yyval.ival) = '?'; }
break;
/* Line 1267 of yacc.c. */
default: break;
}
@ -1902,7 +1907,7 @@ yyerrlab:
if (yyerrstatus == 3)
{
/* If just tried and failed to reuse look-ahead token after an
/* If just tried and failed to reuse lookahead token after an
error, discard it. */
if (yychar <= YYEOF)
@ -1919,7 +1924,7 @@ yyerrlab:
}
}
/* Else will try to reuse look-ahead token after shifting the error
/* Else will try to reuse lookahead token after shifting the error
token. */
goto yyerrlab1;
@ -1977,14 +1982,11 @@ yyerrlab1:
YY_STACK_PRINT (yyss, yyssp);
}
if (yyn == YYFINAL)
YYACCEPT;
*++yyvsp = yylval;
yyerror_range[1] = yylloc;
/* Using YYLLOC is tempting, but would change the location of
the look-ahead. YYLOC is available though. */
the lookahead. YYLOC is available though. */
YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
*++yylsp = yyloc;
@ -2009,7 +2011,7 @@ yyabortlab:
yyresult = 1;
goto yyreturn;
#ifndef yyoverflow
#if !defined(yyoverflow) || YYERROR_VERBOSE
/*-------------------------------------------------.
| yyexhaustedlab -- memory exhaustion comes here. |
`-------------------------------------------------*/
@ -2020,7 +2022,7 @@ yyexhaustedlab:
#endif
yyreturn:
if (yychar != YYEOF && yychar != YYEMPTY)
if (yychar != YYEMPTY)
yydestruct ("Cleanup: discarding lookahead",
yytoken, &yylval, &yylloc, context);
/* Do not reclaim the symbols of the rule which action triggered
@ -2049,6 +2051,11 @@ yyreturn:
int yylex(YYSTYPE* lvalp, YYLTYPE* llocp, pp::Context* context)
{
return context->lex(lvalp, llocp);
}
void yyerror(YYLTYPE* llocp, pp::Context* context, const char* reason)
{
}

View File

@ -1,24 +1,22 @@
/* A Bison parser, made by GNU Bison 2.3. */
/* A Bison parser, made by GNU Bison 2.4.2. */
/* Skeleton interface for Bison's Yacc-like parsers in C
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
Copyright (C) 1984, 1989-1990, 2000-2006, 2009-2010 Free Software
Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@ -29,10 +27,11 @@
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
@ -60,45 +59,25 @@
IDENTIFIER = 276
};
#endif
/* Tokens. */
#define HASH 258
#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
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
{
int ival;
std::string* sval;
pp::Token* tval;
pp::TokenVector* tlist;
}
/* Line 1489 of yacc.c. */
YYSTYPE;
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif
@ -117,3 +96,4 @@ typedef struct YYLTYPE
#endif

View File

@ -0,0 +1,18 @@
//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// pp_utils.h: Common preprocessor utilities
#ifndef COMPILER_PREPROCESSOR_PPUTILS_H_
#define COMPILER_PREPROCESSOR_PPUTILS_H_
// A macro to disallow the copy constructor and operator= functions
// This must be used in the private: declarations for a class.
#define PP_DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \
void operator=(const TypeName&)
#endif // COMPILER_PREPROCESSOR_PPUTILS_H_

View File

@ -47,5 +47,4 @@ extern CPPStruct *cpp;
int InitCPPStruct(void);
int InitScanner(CPPStruct *cpp);
int InitAtomTable(AtomTable *atable, int htsize);
int ScanFromString(const char *s);
char* GetStringOfAtom(AtomTable *atable, int atom);

View File

@ -59,6 +59,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif
#include "compiler/preprocessor/slglobals.h"
#include "compiler/preprocessor/lexer_glue.h"
#include "compiler/util.h"
typedef struct StringInputSrc {
@ -66,6 +67,8 @@ typedef struct StringInputSrc {
char *p;
} StringInputSrc;
static int ScanFromString(const char *s);
static int eof_scan(InputSrc *is, yystypepp * yylvalpp)
{
return EOF;
@ -126,6 +129,25 @@ int FreeScanner(void)
return (FreeCPP());
}
// Define this to 1 to use the new lexer.
#define CPP_USE_NEW_LEXER 0
int InitScannerInput(CPPStruct *cpp, int count, const char* const string[], const int length[])
{
#if CPP_USE_NEW_LEXER
InputSrc* in = LexerInputSrc(count, string, length);
if (!in) return 1;
cpp->currentInput = in;
#else
cpp->PaWhichStr = 0;
cpp->PaArgv = string;
cpp->PaArgc = count;
cpp->PaStrLen = length;
ScanFromString(string[0]);
#endif
return 0;
}
/*
* str_getch()
* takes care of reading from multiple strings.
@ -665,8 +687,6 @@ int yylex_CPP(char* buf, int maxSize)
return 0;
}
}
return 0;
} // yylex
//Checks if the token just read is EOF or not.

View File

@ -69,9 +69,9 @@ typedef struct InputSrc {
} InputSrc;
int InitScanner(CPPStruct *cpp); // Intialise the cpp scanner.
int ScanFromString(const char *); // Start scanning the input from the string mentioned.
int InitScannerInput(CPPStruct *cpp, int count, const char* const string[], const int length[]);
int check_EOF(int); // check if we hit a EOF abruptly
void CPPErrorToInfoLog(char *); // sticking the msg,line into the Shader's.Info.log
void CPPErrorToInfoLog(const char *); // sticking the msg,line into the Shader's.Info.log
void SetLineNumber(int);
void SetStringNumber(int);
void IncLineNumber(void);

View File

@ -51,6 +51,10 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "compiler/preprocessor/slglobals.h"
#if defined(_MSC_VER)
#pragma warning(disable: 4706)
#endif
///////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////// Symbol Table Variables: ///////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -105,7 +105,7 @@ Symbol *NewSymbol(SourceLoc *loc, Scope *fScope, int name, symbolkind kind);
Symbol *AddSymbol(SourceLoc *loc, Scope *fScope, int atom, symbolkind kind);
Symbol *LookUpLocalSymbol(Scope *fScope, int atom);
Symbol *LookUpSymbol(Scope *fScope, int atom);
void CPPErrorToInfoLog(char *);
void CPPErrorToInfoLog(const char *);
#endif // !defined(__SYMBOLS_H)

View File

@ -54,6 +54,11 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "compiler/preprocessor/slglobals.h"
#include "compiler/util.h"
#if defined(_MSC_VER)
#pragma warning(disable: 4054)
#pragma warning(disable: 4152)
#endif
///////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////// Preprocessor and Token Recorder and Playback: ////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
@ -260,6 +265,8 @@ int ReadToken(TokenStream *pTok, yystypepp * yylvalpp)
char string_val[MAX_STRING_LEN + 1];
int ltoken, len;
char ch;
int base, accum;
char ch_val;
ltoken = lReadByte(pTok);
if (ltoken >= 0) {
@ -310,18 +317,41 @@ int ReadToken(TokenStream *pTok, yystypepp * yylvalpp)
break;
case CPP_INTCONSTANT:
len = 0;
accum = 0;
ch = lReadByte(pTok);
while ((ch >= '0' && ch <= '9'))
{
if (len < MAX_SYMBOL_NAME_LEN) {
if (ch == '0') {
symbol_name[len++] = ch;
ch = lReadByte(pTok);
if (ch == 'x' || ch == 'X') {
symbol_name[len++] = ch;
base = 16;
ch = lReadByte(pTok);
} else {
base = 8;
}
} else {
base = 10;
}
while (len < MAX_SYMBOL_NAME_LEN)
{
ch_val = -1;
if (isdigit(ch))
ch_val = ch - '0';
else if (isxdigit(ch))
ch_val = tolower(ch) - 'a' + 10;
if (ch_val < 0 || ch_val >= base)
break;
symbol_name[len++] = ch;
accum = accum * base + ch_val;
ch = lReadByte(pTok);
}
symbol_name[len] = '\0';
assert(ch == '\0');
strcpy(yylvalpp->symbol_name,symbol_name);
yylvalpp->sc_int=atoi(yylvalpp->symbol_name);
strcpy(yylvalpp->symbol_name, symbol_name);
yylvalpp->sc_int = accum;
break;
case '(':
yylvalpp->sc_int = lReadByte(pTok);

View File

@ -48,6 +48,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if !defined(__TOKENS_H)
#define __TOKENS_H 1
#include <stdio.h>
#include "compiler/preprocessor/parser.h"
#define EOF_SY (-1)

View File

@ -321,25 +321,25 @@ bool ConfigSet::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint
case EGL_RED_SIZE: match = config->mRedSize >= attribute[1]; break;
case EGL_DEPTH_SIZE: match = config->mDepthSize >= attribute[1]; break;
case EGL_STENCIL_SIZE: match = config->mStencilSize >= attribute[1]; break;
case EGL_CONFIG_CAVEAT: match = config->mConfigCaveat == attribute[1]; break;
case EGL_CONFIG_CAVEAT: match = config->mConfigCaveat == (EGLenum) attribute[1]; break;
case EGL_CONFIG_ID: match = config->mConfigID == attribute[1]; break;
case EGL_LEVEL: match = config->mLevel >= attribute[1]; break;
case EGL_NATIVE_RENDERABLE: match = config->mNativeRenderable == attribute[1]; break;
case EGL_NATIVE_RENDERABLE: match = config->mNativeRenderable == (EGLBoolean) attribute[1]; break;
case EGL_NATIVE_VISUAL_TYPE: match = config->mNativeVisualType == attribute[1]; break;
case EGL_SAMPLES: match = config->mSamples >= attribute[1]; break;
case EGL_SAMPLE_BUFFERS: match = config->mSampleBuffers >= attribute[1]; break;
case EGL_SURFACE_TYPE: match = (config->mSurfaceType & attribute[1]) == attribute[1]; break;
case EGL_TRANSPARENT_TYPE: match = config->mTransparentType == attribute[1]; break;
case EGL_TRANSPARENT_TYPE: match = config->mTransparentType == (EGLenum) attribute[1]; break;
case EGL_TRANSPARENT_BLUE_VALUE: match = config->mTransparentBlueValue == attribute[1]; break;
case EGL_TRANSPARENT_GREEN_VALUE: match = config->mTransparentGreenValue == attribute[1]; break;
case EGL_TRANSPARENT_RED_VALUE: match = config->mTransparentRedValue == attribute[1]; break;
case EGL_BIND_TO_TEXTURE_RGB: match = config->mBindToTextureRGB == attribute[1]; break;
case EGL_BIND_TO_TEXTURE_RGBA: match = config->mBindToTextureRGBA == attribute[1]; break;
case EGL_BIND_TO_TEXTURE_RGB: match = config->mBindToTextureRGB == (EGLBoolean) attribute[1]; break;
case EGL_BIND_TO_TEXTURE_RGBA: match = config->mBindToTextureRGBA == (EGLBoolean) attribute[1]; break;
case EGL_MIN_SWAP_INTERVAL: match = config->mMinSwapInterval == attribute[1]; break;
case EGL_MAX_SWAP_INTERVAL: match = config->mMaxSwapInterval == attribute[1]; break;
case EGL_LUMINANCE_SIZE: match = config->mLuminanceSize >= attribute[1]; break;
case EGL_ALPHA_MASK_SIZE: match = config->mAlphaMaskSize >= attribute[1]; break;
case EGL_COLOR_BUFFER_TYPE: match = config->mColorBufferType == attribute[1]; break;
case EGL_COLOR_BUFFER_TYPE: match = config->mColorBufferType == (EGLenum) attribute[1]; break;
case EGL_RENDERABLE_TYPE: match = (config->mRenderableType & attribute[1]) == attribute[1]; break;
case EGL_MATCH_NATIVE_PIXMAP: match = false; UNIMPLEMENTED(); break;
case EGL_CONFORMANT: match = (config->mConformant & attribute[1]) == attribute[1]; break;

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@ -288,6 +288,12 @@ bool Display::initialize()
mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);
if (!createDevice())
{
terminate();
return false;
}
return true;
}
@ -1131,7 +1137,6 @@ D3DPRESENT_PARAMETERS Display::getDefaultPresentParameters()
void Display::initExtensionString()
{
HMODULE swiftShader = GetModuleHandle(TEXT("swiftshader_d3d9.dll"));
bool isd3d9ex = isD3d9ExDevice();
mExtensionString = "";
@ -1139,7 +1144,7 @@ void Display::initExtensionString()
mExtensionString += "EGL_EXT_create_context_robustness ";
// ANGLE-specific extensions
if (isd3d9ex)
if (shareHandleSupported())
{
mExtensionString += "EGL_ANGLE_d3d_share_handle_client_buffer ";
}
@ -1151,7 +1156,7 @@ void Display::initExtensionString()
mExtensionString += "EGL_ANGLE_software_display ";
}
if (isd3d9ex)
if (shareHandleSupported())
{
mExtensionString += "EGL_ANGLE_surface_d3d_texture_2d_share_handle ";
}
@ -1170,6 +1175,12 @@ const char *Display::getExtensionString() const
return mExtensionString.c_str();
}
bool Display::shareHandleSupported() const
{
// PIX doesn't seem to support using share handles, so disable them.
return isD3d9ExDevice() && !gl::perfActive();
}
// Only Direct3D 10 ready devices support all the necessary vertex texture formats.
// We test this using D3D9 by checking support for the R16F format.
bool Display::getVertexTextureSupport() const
@ -1215,4 +1226,9 @@ bool Display::getOcclusionQuerySupport() const
}
}
bool Display::getInstancingSupport() const
{
return mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0);
}
}

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@ -79,14 +79,16 @@ class Display
virtual bool getVertexTextureSupport() const;
virtual bool getNonPower2TextureSupport() const;
virtual bool getOcclusionQuerySupport() const;
virtual bool getInstancingSupport() const;
virtual D3DPOOL getBufferPool(DWORD usage) const;
virtual D3DPOOL getTexturePool(bool renderable) const;
virtual void notifyDeviceLost();
bool isDeviceLost();
bool isD3d9ExDevice() { return mD3d9Ex != NULL; }
bool isD3d9ExDevice() const { return mD3d9Ex != NULL; }
const char *getExtensionString() const;
bool shareHandleSupported() const;
private:
DISALLOW_COPY_AND_ASSIGN(Display);

View File

@ -68,6 +68,7 @@ LOCAL_INCLUDES = \
VPATH += $(srcdir)/.. \
$(srcdir)/../compiler \
$(srcdir)/../compiler/preprocessor \
$(srcdir)/../compiler/preprocessor/new \
$(srcdir)/../common \
$(NULL)
@ -98,6 +99,12 @@ CPPSRCS = \
MapLongVariableNames.cpp \
spooky.cpp \
BuiltInFunctionEmulator.cpp \
Input.cpp \
Lexer.cpp \
pp_lex.cpp \
Preprocessor.cpp \
Token.cpp \
lexer_glue.cpp \
$(NULL)
# flex/yacc generated files

View File

@ -253,7 +253,7 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain);
} else {
HANDLE *pShareHandle = NULL;
if (mDisplay->isD3d9ExDevice()) {
if (mDisplay->shareHandleSupported()) {
pShareHandle = &mShareHandle;
}

View File

@ -105,8 +105,6 @@ EGLDisplay __stdcall eglGetDisplay(EGLNativeDisplayType display_id)
{
return error(EGL_BAD_ALLOC, EGL_NO_DISPLAY);
}
return EGL_NO_DISPLAY;
}
EGLBoolean __stdcall eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
@ -137,8 +135,6 @@ EGLBoolean __stdcall eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
{
return error(EGL_BAD_ALLOC, EGL_FALSE);
}
return EGL_FALSE;
}
EGLBoolean __stdcall eglTerminate(EGLDisplay dpy)
@ -162,8 +158,6 @@ EGLBoolean __stdcall eglTerminate(EGLDisplay dpy)
{
return error(EGL_BAD_ALLOC, EGL_FALSE);
}
return EGL_FALSE;
}
const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name)
@ -197,8 +191,6 @@ const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name)
{
return error(EGL_BAD_ALLOC, (const char*)NULL);
}
return NULL;
}
EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
@ -234,8 +226,6 @@ EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint co
{
return error(EGL_BAD_ALLOC, EGL_FALSE);
}
return EGL_FALSE;
}
EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
@ -273,8 +263,6 @@ EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
{
return error(EGL_BAD_ALLOC, EGL_FALSE);
}
return EGL_FALSE;
}
EGLBoolean __stdcall eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
@ -302,8 +290,6 @@ EGLBoolean __stdcall eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint
{
return error(EGL_BAD_ALLOC, EGL_FALSE);
}
return EGL_FALSE;
}
EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
@ -333,8 +319,6 @@ EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EG
{
return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
}
return EGL_NO_SURFACE;
}
EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
@ -357,8 +341,6 @@ EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, c
{
return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
}
return EGL_NO_SURFACE;
}
EGLSurface __stdcall eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
@ -383,8 +365,6 @@ EGLSurface __stdcall eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EG
{
return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
}
return EGL_NO_SURFACE;
}
EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
@ -414,8 +394,6 @@ EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
{
return error(EGL_BAD_ALLOC, EGL_FALSE);
}
return EGL_FALSE;
}
EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
@ -501,8 +479,6 @@ EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint
{
return error(EGL_BAD_ALLOC, EGL_FALSE);
}
return EGL_FALSE;
}
EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value)
@ -540,8 +516,6 @@ EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surf
{
return error(EGL_BAD_ALLOC, EGL_FALSE);
}
return EGL_FALSE;
}
EGLBoolean __stdcall eglBindAPI(EGLenum api)
@ -569,8 +543,6 @@ EGLBoolean __stdcall eglBindAPI(EGLenum api)
{
return error(EGL_BAD_ALLOC, EGL_FALSE);
}
return EGL_FALSE;
}
EGLenum __stdcall eglQueryAPI(void)
@ -587,8 +559,6 @@ EGLenum __stdcall eglQueryAPI(void)
{
return error(EGL_BAD_ALLOC, EGL_FALSE);
}
return EGL_FALSE;
}
EGLBoolean __stdcall eglWaitClient(void)
@ -605,8 +575,6 @@ EGLBoolean __stdcall eglWaitClient(void)
{
return error(EGL_BAD_ALLOC, EGL_FALSE);
}
return EGL_FALSE;
}
EGLBoolean __stdcall eglReleaseThread(void)
@ -623,8 +591,6 @@ EGLBoolean __stdcall eglReleaseThread(void)
{
return error(EGL_BAD_ALLOC, EGL_FALSE);
}
return EGL_FALSE;
}
EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
@ -653,8 +619,6 @@ EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum bu
{
return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
}
return EGL_NO_SURFACE;
}
EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
@ -680,8 +644,6 @@ EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint
{
return error(EGL_BAD_ALLOC, EGL_FALSE);
}
return EGL_FALSE;
}
EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
@ -729,8 +691,6 @@ EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint
{
return error(EGL_BAD_ALLOC, EGL_FALSE);
}
return EGL_FALSE;
}
EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
@ -775,8 +735,6 @@ EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLi
{
return error(EGL_BAD_ALLOC, EGL_FALSE);
}
return EGL_FALSE;
}
EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval)
@ -807,8 +765,6 @@ EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval)
{
return error(EGL_BAD_ALLOC, EGL_FALSE);
}
return EGL_FALSE;
}
EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
@ -836,7 +792,7 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte
if (attribute[1] == EGL_TRUE)
{
return error(EGL_BAD_CONFIG, EGL_NO_CONTEXT); // Unimplemented
robust_access = true;
// robust_access = true;
}
else if (attribute[1] != EGL_FALSE)
return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
@ -881,8 +837,6 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte
{
return error(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
}
return EGL_NO_CONTEXT;
}
EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
@ -912,8 +866,6 @@ EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
{
return error(EGL_BAD_ALLOC, EGL_FALSE);
}
return EGL_FALSE;
}
EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
@ -954,9 +906,6 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface
UNIMPLEMENTED(); // FIXME
}
egl::Surface* previousDraw = static_cast<egl::Surface*>(egl::getCurrentDrawSurface());
egl::Surface* previousRead = static_cast<egl::Surface*>(egl::getCurrentReadSurface());
egl::setCurrentDisplay(dpy);
egl::setCurrentDrawSurface(draw);
egl::setCurrentReadSurface(read);
@ -969,8 +918,6 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface
{
return error(EGL_BAD_ALLOC, EGL_FALSE);
}
return EGL_FALSE;
}
EGLContext __stdcall eglGetCurrentContext(void)
@ -987,8 +934,6 @@ EGLContext __stdcall eglGetCurrentContext(void)
{
return error(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
}
return EGL_NO_CONTEXT;
}
EGLSurface __stdcall eglGetCurrentSurface(EGLint readdraw)
@ -1016,8 +961,6 @@ EGLSurface __stdcall eglGetCurrentSurface(EGLint readdraw)
{
return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
}
return EGL_NO_SURFACE;
}
EGLDisplay __stdcall eglGetCurrentDisplay(void)
@ -1034,8 +977,6 @@ EGLDisplay __stdcall eglGetCurrentDisplay(void)
{
return error(EGL_BAD_ALLOC, EGL_NO_DISPLAY);
}
return EGL_NO_DISPLAY;
}
EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
@ -1061,8 +1002,6 @@ EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attr
{
return error(EGL_BAD_ALLOC, EGL_FALSE);
}
return EGL_FALSE;
}
EGLBoolean __stdcall eglWaitGL(void)
@ -1079,8 +1018,6 @@ EGLBoolean __stdcall eglWaitGL(void)
{
return error(EGL_BAD_ALLOC, EGL_FALSE);
}
return EGL_FALSE;
}
EGLBoolean __stdcall eglWaitNative(EGLint engine)
@ -1097,8 +1034,6 @@ EGLBoolean __stdcall eglWaitNative(EGLint engine)
{
return error(EGL_BAD_ALLOC, EGL_FALSE);
}
return EGL_FALSE;
}
EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
@ -1165,8 +1100,6 @@ EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativ
{
return error(EGL_BAD_ALLOC, EGL_FALSE);
}
return EGL_FALSE;
}
EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height)
@ -1239,7 +1172,5 @@ __eglMustCastToProperFunctionPointerType __stdcall eglGetProcAddress(const char
{
return error(EGL_BAD_ALLOC, (__eglMustCastToProperFunctionPointerType)NULL);
}
return NULL;
}
}

View File

@ -50,7 +50,8 @@
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
WarningLevel="4"
DisableSpecificWarnings="4100;4127;4189;4239;4244;4245;4512;4702"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="4"
WarnAsError="true"
@ -130,7 +131,8 @@
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBEGL_EXPORTS;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;_SECURE_SCL=0"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
WarningLevel="4"
DisableSpecificWarnings="4100;4127;4189;4239;4244;4245;4512;4702"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
WarnAsError="true"
@ -213,7 +215,8 @@
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
WarningLevel="4"
DisableSpecificWarnings="4100;4127;4189;4239;4244;4245;4512;4702"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
WarnAsError="true"
@ -294,7 +297,8 @@
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBEGL_EXPORTS;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;_SECURE_SCL=0"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
WarningLevel="4"
DisableSpecificWarnings="4100;4127;4189;4239;4244;4245;4512;4702"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
WarnAsError="true"

View File

@ -504,6 +504,11 @@ void Blit::setCommonBlitState()
RECT scissorRect = {0}; // Scissoring is disabled for flipping, but we need this to capture and restore the old rectangle
device->SetScissorRect(&scissorRect);
for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
device->SetStreamSourceFreq(i, 1);
}
}
void Blit::render()

View File

@ -48,12 +48,12 @@ class Buffer : public RefCountObject
DISALLOW_COPY_AND_ASSIGN(Buffer);
GLubyte *mContents;
size_t mSize;
GLsizeiptr mSize;
GLenum mUsage;
StaticVertexBuffer *mStaticVertexBuffer;
StaticIndexBuffer *mStaticIndexBuffer;
size_t mUnmodifiedDataUse;
GLsizeiptr mUnmodifiedDataUse;
};
}

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@ -32,11 +32,6 @@
#undef near
#undef far
namespace
{
enum { CLOSING_INDEX_BUFFER_SIZE = 4096 };
}
namespace gl
{
Context::Context(const egl::Config *config, const gl::Context *shareContext, bool notifyResets, bool robustAccess) : mConfig(config)
@ -153,7 +148,7 @@ Context::Context(const egl::Config *config, const gl::Context *shareContext, boo
mVertexDataManager = NULL;
mIndexDataManager = NULL;
mBlit = NULL;
mClosingIB = NULL;
mLineLoopIB = NULL;
mInvalidEnum = false;
mInvalidValue = false;
@ -244,7 +239,7 @@ Context::~Context()
delete mVertexDataManager;
delete mIndexDataManager;
delete mBlit;
delete mClosingIB;
delete mLineLoopIB;
if (mMaskedClearSavedState)
{
@ -267,9 +262,10 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
mIndexDataManager = new IndexDataManager(this, mDevice);
mBlit = new Blit(this);
mSupportsShaderModel3 = mDeviceCaps.PixelShaderVersion == D3DPS_VERSION(3, 0);
mSupportsShaderModel3 = mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0);
mSupportsVertexTexture = mDisplay->getVertexTextureSupport();
mSupportsNonPower2Texture = mDisplay->getNonPower2TextureSupport();
mSupportsInstancing = mDisplay->getInstancingSupport();
mMaxTextureDimension = std::min(std::min((int)mDeviceCaps.MaxTextureWidth, (int)mDeviceCaps.MaxTextureHeight),
(int)gl::IMPLEMENTATION_MAX_TEXTURE_SIZE);
@ -944,7 +940,7 @@ GLuint Context::createFence()
{
GLuint handle = mFenceHandleAllocator.allocate();
mFenceMap[handle] = new Fence;
mFenceMap[handle] = new Fence(mDisplay);
return handle;
}
@ -1192,6 +1188,7 @@ void Context::beginQuery(GLenum target, GLuint query)
break;
default:
ASSERT(false);
return;
}
Query *queryObject = getQuery(query, true, target);
@ -1229,6 +1226,7 @@ void Context::endQuery(GLenum target)
break;
default:
ASSERT(false);
return;
}
Query *queryObject = mState.activeQuery[qType].get();
@ -2248,21 +2246,21 @@ void Context::applyState(GLenum drawMode)
}
}
GLenum Context::applyVertexBuffer(GLint first, GLsizei count)
GLenum Context::applyVertexBuffer(GLint first, GLsizei count, GLsizei instances, GLsizei *repeatDraw)
{
TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];
GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes);
GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes, instances);
if (err != GL_NO_ERROR)
{
return err;
}
return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, getCurrentProgram());
return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, getCurrentProgram(), instances, repeatDraw);
}
// Applies the indices and element array bindings to the Direct3D 9 device
GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
GLenum Context::applyIndexBuffer(const GLvoid *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
{
GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer.get(), indices, indexInfo);
@ -2432,7 +2430,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
HRESULT result;
IDirect3DSurface9 *systemSurface = NULL;
bool directToPixels = getPackReverseRowOrder() && getPackAlignment() <= 4 && mDisplay->isD3d9ExDevice() &&
x == 0 && y == 0 && width == desc.Width && height == desc.Height &&
x == 0 && y == 0 && UINT(width) == desc.Width && UINT(height) == desc.Height &&
desc.Format == D3DFMT_A8R8G8B8 && format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE;
if (directToPixels)
{
@ -2616,6 +2614,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
default:
UNIMPLEMENTED(); // FIXME
UNREACHABLE();
return;
}
switch (format)
@ -2808,6 +2807,11 @@ void Context::clear(GLbitfield mask)
mDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
mDevice->SetRenderState(D3DRS_TEXTUREFACTOR, color);
mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
mDevice->SetStreamSourceFreq(i, 1);
}
hr = mDevice->EndStateBlock(&mMaskedClearSavedState);
ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
@ -2867,6 +2871,11 @@ void Context::clear(GLbitfield mask)
mDevice->SetRenderState(D3DRS_TEXTUREFACTOR, color);
mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
mDevice->SetStreamSourceFreq(i, 1);
}
float quad[4][4]; // A quadrilateral covering the target, aligned to match the edges
quad[0][0] = -0.5f;
quad[0][1] = mRenderTargetDesc.Height - 0.5f;
@ -2909,7 +2918,7 @@ void Context::clear(GLbitfield mask)
}
}
void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances)
{
if (!mState.currentProgram)
{
@ -2934,7 +2943,8 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
applyState(mode);
GLenum err = applyVertexBuffer(first, count);
GLsizei repeatDraw = 1;
GLenum err = applyVertexBuffer(first, count, instances, &repeatDraw);
if (err != GL_NO_ERROR)
{
return error(err);
@ -2952,16 +2962,40 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
{
mDisplay->startScene();
mDevice->DrawPrimitive(primitiveType, 0, primitiveCount);
if (mode == GL_LINE_LOOP) // Draw the last segment separately
if (mode == GL_LINE_LOOP)
{
drawClosingLine(0, count - 1, 0);
drawLineLoop(count, GL_NONE, NULL, 0);
}
else if (instances > 0)
{
StaticIndexBuffer *countingIB = mIndexDataManager->getCountingIndices(count);
if (countingIB)
{
if (mAppliedIBSerial != countingIB->getSerial())
{
mDevice->SetIndices(countingIB->getBuffer());
mAppliedIBSerial = countingIB->getSerial();
}
for (int i = 0; i < repeatDraw; i++)
{
mDevice->DrawIndexedPrimitive(primitiveType, 0, 0, count, 0, primitiveCount);
}
}
else
{
ERR("Could not create a counting index buffer for glDrawArraysInstanced.");
return error(GL_OUT_OF_MEMORY);
}
}
else // Regular case
{
mDevice->DrawPrimitive(primitiveType, 0, primitiveCount);
}
}
}
void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instances)
{
if (!mState.currentProgram)
{
@ -2999,7 +3033,8 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *
}
GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
err = applyVertexBuffer(indexInfo.minIndex, vertexCount);
GLsizei repeatDraw = 1;
err = applyVertexBuffer(indexInfo.minIndex, vertexCount, instances, &repeatDraw);
if (err != GL_NO_ERROR)
{
return error(err);
@ -3017,11 +3052,16 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *
{
mDisplay->startScene();
mDevice->DrawIndexedPrimitive(primitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, vertexCount, indexInfo.startIndex, primitiveCount);
if (mode == GL_LINE_LOOP) // Draw the last segment separately
if (mode == GL_LINE_LOOP)
{
drawClosingLine(count, type, indices, indexInfo.minIndex);
drawLineLoop(count, type, indices, indexInfo.minIndex);
}
else
{
for (int i = 0; i < repeatDraw; i++)
{
mDevice->DrawIndexedPrimitive(primitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, vertexCount, indexInfo.startIndex, primitiveCount);
}
}
}
}
@ -3032,99 +3072,149 @@ void Context::sync(bool block)
mDisplay->sync(block);
}
void Context::drawClosingLine(unsigned int first, unsigned int last, int minIndex)
void Context::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex)
{
IDirect3DIndexBuffer9 *indexBuffer = NULL;
bool succeeded = false;
UINT offset;
if (supports32bitIndices())
{
const int spaceNeeded = 2 * sizeof(unsigned int);
if (!mClosingIB)
{
mClosingIB = new StreamingIndexBuffer(mDevice, CLOSING_INDEX_BUFFER_SIZE, D3DFMT_INDEX32);
}
mClosingIB->reserveSpace(spaceNeeded, GL_UNSIGNED_INT);
unsigned int *data = static_cast<unsigned int*>(mClosingIB->map(spaceNeeded, &offset));
if (data)
{
data[0] = last;
data[1] = first;
mClosingIB->unmap();
offset /= 4;
succeeded = true;
}
}
else
{
const int spaceNeeded = 2 * sizeof(unsigned short);
if (!mClosingIB)
{
mClosingIB = new StreamingIndexBuffer(mDevice, CLOSING_INDEX_BUFFER_SIZE, D3DFMT_INDEX16);
}
mClosingIB->reserveSpace(spaceNeeded, GL_UNSIGNED_SHORT);
unsigned short *data = static_cast<unsigned short*>(mClosingIB->map(spaceNeeded, &offset));
if (data)
{
data[0] = last;
data[1] = first;
mClosingIB->unmap();
offset /= 2;
succeeded = true;
}
}
if (succeeded)
{
mDevice->SetIndices(mClosingIB->getBuffer());
mAppliedIBSerial = mClosingIB->getSerial();
mDevice->DrawIndexedPrimitive(D3DPT_LINELIST, -minIndex, minIndex, last, offset, 1);
}
else
{
ERR("Could not create an index buffer for closing a line loop.");
error(GL_OUT_OF_MEMORY);
}
}
void Context::drawClosingLine(GLsizei count, GLenum type, const void *indices, int minIndex)
{
unsigned int first = 0;
unsigned int last = 0;
if (mState.elementArrayBuffer.get())
// Get the raw indices for an indexed draw
if (type != GL_NONE && mState.elementArrayBuffer.get())
{
Buffer *indexBuffer = mState.elementArrayBuffer.get();
intptr_t offset = reinterpret_cast<intptr_t>(indices);
indices = static_cast<const GLubyte*>(indexBuffer->data()) + offset;
}
switch (type)
{
case GL_UNSIGNED_BYTE:
first = static_cast<const GLubyte*>(indices)[0];
last = static_cast<const GLubyte*>(indices)[count - 1];
break;
case GL_UNSIGNED_SHORT:
first = static_cast<const GLushort*>(indices)[0];
last = static_cast<const GLushort*>(indices)[count - 1];
break;
case GL_UNSIGNED_INT:
first = static_cast<const GLuint*>(indices)[0];
last = static_cast<const GLuint*>(indices)[count - 1];
break;
default: UNREACHABLE();
}
UINT startIndex = 0;
bool succeeded = false;
drawClosingLine(first, last, minIndex);
if (supports32bitIndices())
{
const int spaceNeeded = (count + 1) * sizeof(unsigned int);
if (!mLineLoopIB)
{
mLineLoopIB = new StreamingIndexBuffer(mDevice, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX32);
}
if (mLineLoopIB)
{
mLineLoopIB->reserveSpace(spaceNeeded, GL_UNSIGNED_INT);
UINT offset = 0;
unsigned int *data = static_cast<unsigned int*>(mLineLoopIB->map(spaceNeeded, &offset));
startIndex = offset / 4;
if (data)
{
switch (type)
{
case GL_NONE: // Non-indexed draw
for (int i = 0; i < count; i++)
{
data[i] = i;
}
data[count] = 0;
break;
case GL_UNSIGNED_BYTE:
for (int i = 0; i < count; i++)
{
data[i] = static_cast<const GLubyte*>(indices)[i];
}
data[count] = static_cast<const GLubyte*>(indices)[0];
break;
case GL_UNSIGNED_SHORT:
for (int i = 0; i < count; i++)
{
data[i] = static_cast<const GLushort*>(indices)[i];
}
data[count] = static_cast<const GLushort*>(indices)[0];
break;
case GL_UNSIGNED_INT:
for (int i = 0; i < count; i++)
{
data[i] = static_cast<const GLuint*>(indices)[i];
}
data[count] = static_cast<const GLuint*>(indices)[0];
break;
default: UNREACHABLE();
}
mLineLoopIB->unmap();
succeeded = true;
}
}
}
else
{
const int spaceNeeded = (count + 1) * sizeof(unsigned short);
if (!mLineLoopIB)
{
mLineLoopIB = new StreamingIndexBuffer(mDevice, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX16);
}
if (mLineLoopIB)
{
mLineLoopIB->reserveSpace(spaceNeeded, GL_UNSIGNED_SHORT);
UINT offset = 0;
unsigned short *data = static_cast<unsigned short*>(mLineLoopIB->map(spaceNeeded, &offset));
startIndex = offset / 2;
if (data)
{
switch (type)
{
case GL_NONE: // Non-indexed draw
for (int i = 0; i < count; i++)
{
data[i] = i;
}
data[count] = 0;
break;
case GL_UNSIGNED_BYTE:
for (int i = 0; i < count; i++)
{
data[i] = static_cast<const GLubyte*>(indices)[i];
}
data[count] = static_cast<const GLubyte*>(indices)[0];
break;
case GL_UNSIGNED_SHORT:
for (int i = 0; i < count; i++)
{
data[i] = static_cast<const GLushort*>(indices)[i];
}
data[count] = static_cast<const GLushort*>(indices)[0];
break;
case GL_UNSIGNED_INT:
for (int i = 0; i < count; i++)
{
data[i] = static_cast<const GLuint*>(indices)[i];
}
data[count] = static_cast<const GLuint*>(indices)[0];
break;
default: UNREACHABLE();
}
mLineLoopIB->unmap();
succeeded = true;
}
}
}
if (succeeded)
{
if (mAppliedIBSerial != mLineLoopIB->getSerial())
{
mDevice->SetIndices(mLineLoopIB->getBuffer());
mAppliedIBSerial = mLineLoopIB->getSerial();
}
mDevice->DrawIndexedPrimitive(D3DPT_LINESTRIP, -minIndex, minIndex, count, startIndex, count);
}
else
{
ERR("Could not create a looping index buffer for GL_LINE_LOOP.");
return error(GL_OUT_OF_MEMORY);
}
}
void Context::recordInvalidEnum()
@ -3373,6 +3463,11 @@ bool Context::supportsNonPower2Texture() const
return mSupportsNonPower2Texture;
}
bool Context::supportsInstancing() const
{
return mSupportsInstancing;
}
void Context::detachBuffer(GLuint buffer)
{
// [OpenGL ES 2.0.24] section 2.9 page 22:
@ -3561,6 +3656,13 @@ void Context::setVertexAttrib(GLuint index, const GLfloat *values)
mVertexDataManager->dirtyCurrentValue(index);
}
void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
{
ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
mState.vertexAttribute[index].mDivisor = divisor;
}
// keep list sorted in following order
// OES extensions
// EXT extensions
@ -3625,6 +3727,11 @@ void Context::initExtensionString()
mExtensionString += "GL_ANGLE_framebuffer_multisample ";
}
if (supportsInstancing())
{
mExtensionString += "GL_ANGLE_instanced_arrays ";
}
mExtensionString += "GL_ANGLE_pack_reverse_row_order ";
if (supportsDXT3Textures())
@ -3968,8 +4075,44 @@ VertexDeclarationCache::~VertexDeclarationCache()
}
}
GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], Program *program)
GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], Program *program, GLsizei instances, GLsizei *repeatDraw)
{
*repeatDraw = 1;
int indexedAttribute = MAX_VERTEX_ATTRIBS;
int instancedAttribute = MAX_VERTEX_ATTRIBS;
if (instances > 0)
{
// Find an indexed attribute to be mapped to D3D stream 0
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
if (attributes[i].active)
{
if (indexedAttribute == MAX_VERTEX_ATTRIBS)
{
if (attributes[i].divisor == 0)
{
indexedAttribute = i;
}
}
else if (instancedAttribute == MAX_VERTEX_ATTRIBS)
{
if (attributes[i].divisor != 0)
{
instancedAttribute = i;
}
}
else break; // Found both an indexed and instanced attribute
}
}
if (indexedAttribute == MAX_VERTEX_ATTRIBS)
{
return GL_INVALID_OPERATION;
}
}
D3DVERTEXELEMENT9 elements[MAX_VERTEX_ATTRIBS + 1];
D3DVERTEXELEMENT9 *element = &elements[0];
@ -3977,17 +4120,53 @@ GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Transl
{
if (attributes[i].active)
{
if (mAppliedVBs[i].serial != attributes[i].serial ||
mAppliedVBs[i].stride != attributes[i].stride ||
mAppliedVBs[i].offset != attributes[i].offset)
int stream = i;
if (instances > 0)
{
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;
// Due to a bug on ATI cards we can't enable instancing when none of the attributes are instanced.
if (instancedAttribute == MAX_VERTEX_ATTRIBS)
{
*repeatDraw = instances;
}
else
{
if (i == indexedAttribute)
{
stream = 0;
}
else if (i == 0)
{
stream = indexedAttribute;
}
UINT frequency = 1;
if (attributes[i].divisor == 0)
{
frequency = D3DSTREAMSOURCE_INDEXEDDATA | instances;
}
else
{
frequency = D3DSTREAMSOURCE_INSTANCEDATA | attributes[i].divisor;
}
device->SetStreamSourceFreq(stream, frequency);
mInstancingEnabled = true;
}
}
element->Stream = i;
if (mAppliedVBs[stream].serial != attributes[i].serial ||
mAppliedVBs[stream].stride != attributes[i].stride ||
mAppliedVBs[stream].offset != attributes[i].offset)
{
device->SetStreamSource(stream, attributes[i].vertexBuffer, attributes[i].offset, attributes[i].stride);
mAppliedVBs[stream].serial = attributes[i].serial;
mAppliedVBs[stream].stride = attributes[i].stride;
mAppliedVBs[stream].offset = attributes[i].offset;
}
element->Stream = stream;
element->Offset = 0;
element->Type = attributes[i].type;
element->Method = D3DDECLMETHOD_DEFAULT;
@ -3997,6 +4176,19 @@ GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Transl
}
}
if (instances == 0 || instancedAttribute == MAX_VERTEX_ATTRIBS)
{
if (mInstancingEnabled)
{
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
device->SetStreamSourceFreq(i, 1);
}
mInstancingEnabled = false;
}
}
static const D3DVERTEXELEMENT9 end = D3DDECL_END();
*(element++) = end;
@ -4051,6 +4243,7 @@ void VertexDeclarationCache::markStateDirty()
}
mLastSetVDecl = NULL;
mInstancingEnabled = true; // Forces it to be disabled when not used
}
}

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@ -104,7 +104,7 @@ struct Color
class VertexAttribute
{
public:
VertexAttribute() : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mArrayEnabled(false)
VertexAttribute() : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mArrayEnabled(false), mDivisor(0)
{
mCurrentValue[0] = 0.0f;
mCurrentValue[1] = 0.0f;
@ -147,6 +147,7 @@ class VertexAttribute
bool mArrayEnabled; // From glEnable/DisableVertexAttribArray
float mCurrentValue[4]; // From glVertexAttrib
unsigned int mDivisor;
};
typedef VertexAttribute VertexAttributeArray[MAX_VERTEX_ATTRIBS];
@ -243,14 +244,14 @@ class VertexDeclarationCache
VertexDeclarationCache();
~VertexDeclarationCache();
GLenum applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], Program *program);
GLenum applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], Program *program, GLsizei instances, GLsizei *repeatDraw);
void markStateDirty();
private:
UINT mMaxLru;
enum { NUM_VERTEX_DECL_CACHE_ENTRIES = 16 };
enum { NUM_VERTEX_DECL_CACHE_ENTRIES = 32 };
struct VBData
{
@ -261,6 +262,7 @@ class VertexDeclarationCache
VBData mAppliedVBs[MAX_VERTEX_ATTRIBS];
IDirect3DVertexDeclaration9 *mLastSetVDecl;
bool mInstancingEnabled;
struct VertexDeclCacheEntry
{
@ -423,6 +425,7 @@ class Context
void setRenderbufferStorage(RenderbufferStorage *renderbuffer);
void setVertexAttrib(GLuint index, const GLfloat *values);
void setVertexAttribDivisor(GLuint index, GLuint divisor);
Buffer *getBuffer(GLuint handle);
Fence *getFence(GLuint handle);
@ -450,13 +453,11 @@ class Context
void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels);
void clear(GLbitfield mask);
void drawArrays(GLenum mode, GLint first, GLsizei count);
void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);
void drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances);
void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instances);
void sync(bool block); // flush/finish
// Draw the last segment of a line loop
void drawClosingLine(unsigned int first, unsigned int last, int minIndex);
void drawClosingLine(GLsizei count, GLenum type, const void *indices, int minIndex);
void drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex);
void recordInvalidEnum();
void recordInvalidValue();
@ -496,6 +497,7 @@ class Context
bool supportsLuminanceAlphaTextures() const;
bool supports32bitIndices() const;
bool supportsNonPower2Texture() const;
bool supportsInstancing() const;
void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
@ -510,8 +512,8 @@ class Context
bool applyRenderTarget(bool ignoreViewport);
void applyState(GLenum drawMode);
GLenum applyVertexBuffer(GLint first, GLsizei count);
GLenum applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
GLenum applyVertexBuffer(GLint first, GLsizei count, GLsizei instances, GLsizei *repeatDraw);
GLenum applyIndexBuffer(const GLvoid *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
void applyShaders();
void applyTextures();
void applyTextures(SamplerType type);
@ -558,7 +560,7 @@ class Context
Blit *mBlit;
StreamingIndexBuffer *mClosingIB;
StreamingIndexBuffer *mLineLoopIB;
BindingPointer<Texture> mIncompleteTextures[TEXTURE_TYPE_COUNT];
@ -595,6 +597,7 @@ class Context
bool mSupportsShaderModel3;
bool mSupportsVertexTexture;
bool mSupportsNonPower2Texture;
bool mSupportsInstancing;
int mMaxRenderbufferDimension;
int mMaxTextureDimension;
int mMaxCubeTextureDimension;

View File

@ -13,8 +13,9 @@
namespace gl
{
Fence::Fence()
{
Fence::Fence(egl::Display* display)
{
mDisplay = display;
mQuery = NULL;
mCondition = GL_NONE;
mStatus = GL_FALSE;
@ -24,7 +25,7 @@ Fence::~Fence()
{
if (mQuery != NULL)
{
getDisplay()->freeEventQuery(mQuery);
mDisplay->freeEventQuery(mQuery);
}
}
@ -39,7 +40,7 @@ void Fence::setFence(GLenum condition)
{
if (!mQuery)
{
mQuery = getDisplay()->allocateEventQuery();
mQuery = mDisplay->allocateEventQuery();
if (!mQuery)
{
return error(GL_OUT_OF_MEMORY);

View File

@ -15,13 +15,18 @@
#include "common/angleutils.h"
namespace egl
{
class Display;
}
namespace gl
{
class Fence
{
public:
Fence();
explicit Fence(egl::Display* display);
virtual ~Fence();
GLboolean isFence();
@ -33,6 +38,7 @@ class Fence
private:
DISALLOW_COPY_AND_ASSIGN(Fence);
egl::Display* mDisplay;
IDirect3DQuery9* mQuery;
GLenum mCondition;
GLboolean mStatus;

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@ -15,11 +15,6 @@
#include "libGLESv2/mathutil.h"
#include "libGLESv2/main.h"
namespace
{
enum { INITIAL_INDEX_BUFFER_SIZE = 4096 * sizeof(GLuint) };
}
namespace gl
{
unsigned int IndexBuffer::mCurrentSerial = 1;
@ -48,12 +43,15 @@ IndexDataManager::IndexDataManager(Context *context, IDirect3DDevice9 *device) :
{
ERR("Failed to allocate the streaming index buffer(s).");
}
mCountingBuffer = NULL;
}
IndexDataManager::~IndexDataManager()
{
delete mStreamingBufferShort;
delete mStreamingBufferInt;
delete mCountingBuffer;
}
void convertIndices(GLenum type, const void *input, GLsizei count, void *output)
@ -92,7 +90,7 @@ void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLu
}
}
void computeRange(GLenum type, const void *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
void computeRange(GLenum type, const GLvoid *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
{
if (type == GL_UNSIGNED_BYTE)
{
@ -109,7 +107,7 @@ void computeRange(GLenum type, const void *indices, GLsizei count, GLuint *minIn
else UNREACHABLE();
}
GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, Buffer *buffer, const void *indices, TranslatedIndexData *translated)
GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, Buffer *buffer, const GLvoid *indices, TranslatedIndexData *translated)
{
if (!mStreamingBufferShort)
{
@ -228,6 +226,61 @@ std::size_t IndexDataManager::typeSize(GLenum type) const
}
}
StaticIndexBuffer *IndexDataManager::getCountingIndices(GLsizei count)
{
if (count <= 65536) // 16-bit indices
{
const unsigned int spaceNeeded = count * sizeof(unsigned short);
if (!mCountingBuffer || mCountingBuffer->size() < spaceNeeded)
{
delete mCountingBuffer;
mCountingBuffer = new StaticIndexBuffer(mDevice);
mCountingBuffer->reserveSpace(spaceNeeded, GL_UNSIGNED_SHORT);
UINT offset;
unsigned short *data = static_cast<unsigned short*>(mCountingBuffer->map(spaceNeeded, &offset));
if (data)
{
for(int i = 0; i < count; i++)
{
data[i] = i;
}
mCountingBuffer->unmap();
}
}
}
else if (mStreamingBufferInt) // 32-bit indices supported
{
const unsigned int spaceNeeded = count * sizeof(unsigned int);
if (!mCountingBuffer || mCountingBuffer->size() < spaceNeeded)
{
delete mCountingBuffer;
mCountingBuffer = new StaticIndexBuffer(mDevice);
mCountingBuffer->reserveSpace(spaceNeeded, GL_UNSIGNED_INT);
UINT offset;
unsigned int *data = static_cast<unsigned int*>(mCountingBuffer->map(spaceNeeded, &offset));
if (data)
{
for(int i = 0; i < count; i++)
{
data[i] = i;
}
mCountingBuffer->unmap();
}
}
}
else return NULL;
return mCountingBuffer;
}
IndexBuffer::IndexBuffer(IDirect3DDevice9 *device, UINT size, D3DFORMAT format) : mDevice(device), mBufferSize(size), mIndexBuffer(NULL)
{
if (size > 0)

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@ -18,6 +18,11 @@
#include "libGLESv2/Context.h"
namespace
{
enum { INITIAL_INDEX_BUFFER_SIZE = 4096 * sizeof(GLuint) };
}
namespace gl
{
@ -123,7 +128,8 @@ class IndexDataManager
IndexDataManager(Context *context, IDirect3DDevice9 *evice);
virtual ~IndexDataManager();
GLenum prepareIndexData(GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices, TranslatedIndexData *translated);
GLenum prepareIndexData(GLenum type, GLsizei count, Buffer *arrayElementBuffer, const GLvoid *indices, TranslatedIndexData *translated);
StaticIndexBuffer *getCountingIndices(GLsizei count);
private:
DISALLOW_COPY_AND_ASSIGN(IndexDataManager);
@ -135,6 +141,7 @@ class IndexDataManager
StreamingIndexBuffer *mStreamingBufferShort;
StreamingIndexBuffer *mStreamingBufferInt;
StaticIndexBuffer *mCountingBuffer;
};
}

View File

@ -69,6 +69,7 @@ LOCAL_INCLUDES = \
VPATH += $(srcdir)/..
VPATH += $(srcdir)/../compiler
VPATH += $(srcdir)/../compiler/preprocessor
VPATH += $(srcdir)/../compiler/preprocessor/new
VPATH += $(srcdir)/../common
# Translator/compiler first
@ -98,6 +99,12 @@ CPPSRCS = \
MapLongVariableNames.cpp \
spooky.cpp \
BuiltInFunctionEmulator.cpp \
Input.cpp \
Lexer.cpp \
pp_lex.cpp \
Preprocessor.cpp \
Token.cpp \
lexer_glue.cpp \
$(NULL)
# flex/yacc generated files

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@ -270,7 +270,7 @@ TextureType Program::getSamplerTextureType(SamplerType type, unsigned int sample
GLint Program::getUniformLocation(std::string name)
{
int subscript = 0;
unsigned int subscript = 0;
// Strip any trailing array operator and retrieve the subscript
size_t open = name.find_last_of('[');
@ -1145,7 +1145,7 @@ int Program::packVaryings(const Varying *packing[][4])
Context *context = getContext();
const int maxVaryingVectors = context->getMaximumVaryingVectors();
for (VaryingList::iterator varying = mFragmentShader->varyings.begin(); varying != mFragmentShader->varyings.end(); varying++)
for (VaryingList::iterator varying = mFragmentShader->mVaryings.begin(); varying != mFragmentShader->mVaryings.end(); varying++)
{
int n = VariableRowCount(varying->type) * varying->size;
int m = VariableColumnCount(varying->type);
@ -1296,13 +1296,13 @@ bool Program::linkVaryings()
}
// Reset the varying register assignments
for (VaryingList::iterator fragVar = mFragmentShader->varyings.begin(); fragVar != mFragmentShader->varyings.end(); fragVar++)
for (VaryingList::iterator fragVar = mFragmentShader->mVaryings.begin(); fragVar != mFragmentShader->mVaryings.end(); fragVar++)
{
fragVar->reg = -1;
fragVar->col = -1;
}
for (VaryingList::iterator vtxVar = mVertexShader->varyings.begin(); vtxVar != mVertexShader->varyings.end(); vtxVar++)
for (VaryingList::iterator vtxVar = mVertexShader->mVaryings.begin(); vtxVar != mVertexShader->mVaryings.end(); vtxVar++)
{
vtxVar->reg = -1;
vtxVar->col = -1;
@ -1329,11 +1329,11 @@ bool Program::linkVaryings()
return false;
}
for (VaryingList::iterator input = mFragmentShader->varyings.begin(); input != mFragmentShader->varyings.end(); input++)
for (VaryingList::iterator input = mFragmentShader->mVaryings.begin(); input != mFragmentShader->mVaryings.end(); input++)
{
bool matched = false;
for (VaryingList::iterator output = mVertexShader->varyings.begin(); output != mVertexShader->varyings.end(); output++)
for (VaryingList::iterator output = mVertexShader->mVaryings.begin(); output != mVertexShader->mVaryings.end(); output++)
{
if (output->name == input->name)
{
@ -1444,7 +1444,7 @@ bool Program::linkVaryings()
mVertexHLSL += " output.gl_FragCoord = gl_Position;\n";
}
for (VaryingList::iterator varying = mVertexShader->varyings.begin(); varying != mVertexShader->varyings.end(); varying++)
for (VaryingList::iterator varying = mVertexShader->mVaryings.begin(); varying != mVertexShader->mVaryings.end(); varying++)
{
if (varying->reg >= 0)
{
@ -1512,7 +1512,7 @@ bool Program::linkVaryings()
mPixelHLSL += "struct PS_INPUT\n"
"{\n";
for (VaryingList::iterator varying = mFragmentShader->varyings.begin(); varying != mFragmentShader->varyings.end(); varying++)
for (VaryingList::iterator varying = mFragmentShader->mVaryings.begin(); varying != mFragmentShader->mVaryings.end(); varying++)
{
if (varying->reg >= 0)
{
@ -1588,7 +1588,7 @@ bool Program::linkVaryings()
mPixelHLSL += " gl_FrontFacing = dx_PointsOrLines || (dx_FrontCCW ? (input.vFace >= 0.0) : (input.vFace <= 0.0));\n";
}
for (VaryingList::iterator varying = mFragmentShader->varyings.begin(); varying != mFragmentShader->varyings.end(); varying++)
for (VaryingList::iterator varying = mFragmentShader->mVaryings.begin(); varying != mFragmentShader->mVaryings.end(); varying++)
{
if (varying->reg >= 0)
{
@ -1902,7 +1902,7 @@ 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, const std::string &_name)
{
Uniform *uniform = createUniform(constantDescription, _name);
@ -1943,7 +1943,7 @@ bool Program::defineUniform(const D3DXCONSTANT_DESC &constantDescription, std::s
return true;
}
Uniform *Program::createUniform(const D3DXCONSTANT_DESC &constantDescription, std::string &_name)
Uniform *Program::createUniform(const D3DXCONSTANT_DESC &constantDescription, const std::string &_name)
{
if (constantDescription.Rows == 1) // Vectors and scalars
{
@ -2031,16 +2031,26 @@ std::string Program::decorateAttribute(const std::string &name)
std::string Program::undecorateUniform(const std::string &_name)
{
if (_name[0] == '_')
std::string name = _name;
// Remove any structure field decoration
size_t pos = 0;
while ((pos = name.find("._", pos)) != std::string::npos)
{
return _name.substr(1);
name.replace(pos, 2, ".");
}
else if (_name.compare(0, 3, "ar_") == 0)
// Remove the leading decoration
if (name[0] == '_')
{
return _name.substr(3);
return name.substr(1);
}
else if (name.compare(0, 3, "ar_") == 0)
{
return name.substr(3);
}
return _name;
return name;
}
void Program::applyUniformnbv(Uniform *targetUniform, GLsizei count, int width, const GLboolean *v)
@ -2454,17 +2464,14 @@ void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog)
{
int index = 0;
if (mInfoLog)
if (bufSize > 0)
{
while (index < bufSize - 1 && index < (int)strlen(mInfoLog))
if (mInfoLog)
{
infoLog[index] = mInfoLog[index];
index++;
index = std::min(bufSize - 1, (int)strlen(mInfoLog));
memcpy(infoLog, mInfoLog, index);
}
}
if (bufSize)
{
infoLog[index] = '\0';
}

View File

@ -154,8 +154,8 @@ class Program
bool linkUniforms(ID3DXConstantTable *constantTable);
bool defineUniform(const D3DXHANDLE &constantHandle, const D3DXCONSTANT_DESC &constantDescription, std::string name = "");
bool defineUniform(const D3DXCONSTANT_DESC &constantDescription, std::string &name);
Uniform *createUniform(const D3DXCONSTANT_DESC &constantDescription, std::string &name);
bool defineUniform(const D3DXCONSTANT_DESC &constantDescription, const std::string &name);
Uniform *createUniform(const D3DXCONSTANT_DESC &constantDescription, const std::string &name);
bool applyUniformnfv(Uniform *targetUniform, const GLfloat *v);
bool applyUniform1iv(Uniform *targetUniform, GLsizei count, const GLint *v);
bool applyUniform2iv(Uniform *targetUniform, GLsizei count, const GLint *v);

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@ -27,32 +27,8 @@ Shader::Shader(ResourceManager *manager, GLuint handle) : mHandle(handle), mReso
mHlsl = NULL;
mInfoLog = NULL;
// Perform a one-time initialization of the shader compiler (or after being destructed by releaseCompiler)
if (!mFragmentCompiler)
{
int result = ShInitialize();
if (result)
{
ShBuiltInResources resources;
ShInitBuiltInResources(&resources);
Context *context = getContext();
resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
resources.MaxVaryingVectors = context->getMaximumVaryingVectors();
resources.MaxVertexTextureImageUnits = context->getMaximumVertexTextureImageUnits();
resources.MaxCombinedTextureImageUnits = context->getMaximumCombinedTextureImageUnits();
resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
resources.MaxFragmentUniformVectors = context->getMaximumFragmentUniformVectors();
resources.MaxDrawBuffers = MAX_DRAW_BUFFERS;
resources.OES_standard_derivatives = 1;
// resources.OES_EGL_image_external = getDisplay()->isD3d9ExDevice() ? 1 : 0; // TODO: commented out until the extension is actually supported.
mFragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_GLES2_SPEC, SH_HLSL_OUTPUT, &resources);
mVertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_GLES2_SPEC, SH_HLSL_OUTPUT, &resources);
}
}
uncompile();
initializeCompiler();
mRefCount = 0;
mDeleteStatus = false;
@ -126,17 +102,14 @@ void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog)
{
int index = 0;
if (mInfoLog)
if (bufSize > 0)
{
while (index < bufSize - 1 && index < (int)strlen(mInfoLog))
if (mInfoLog)
{
infoLog[index] = mInfoLog[index];
index++;
index = std::min(bufSize - 1, (int)strlen(mInfoLog));
memcpy(infoLog, mInfoLog, index);
}
}
if (bufSize)
{
infoLog[index] = '\0';
}
@ -174,17 +147,14 @@ void Shader::getSourceImpl(char *source, GLsizei bufSize, GLsizei *length, char
{
int index = 0;
if (source)
if (bufSize > 0)
{
while (index < bufSize - 1 && index < (int)strlen(source))
if (source)
{
buffer[index] = source[index];
index++;
index = std::min(bufSize - 1, (int)strlen(source));
memcpy(buffer, source, index);
}
}
if (bufSize)
{
buffer[index] = '\0';
}
@ -244,6 +214,36 @@ void Shader::flagForDeletion()
mDeleteStatus = true;
}
// Perform a one-time initialization of the shader compiler (or after being destructed by releaseCompiler)
void Shader::initializeCompiler()
{
if (!mFragmentCompiler)
{
int result = ShInitialize();
if (result)
{
ShBuiltInResources resources;
ShInitBuiltInResources(&resources);
Context *context = getContext();
resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
resources.MaxVaryingVectors = context->getMaximumVaryingVectors();
resources.MaxVertexTextureImageUnits = context->getMaximumVertexTextureImageUnits();
resources.MaxCombinedTextureImageUnits = context->getMaximumCombinedTextureImageUnits();
resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
resources.MaxFragmentUniformVectors = context->getMaximumFragmentUniformVectors();
resources.MaxDrawBuffers = MAX_DRAW_BUFFERS;
resources.OES_standard_derivatives = 1;
// resources.OES_EGL_image_external = getDisplay()->isD3d9ExDevice() ? 1 : 0; // TODO: commented out until the extension is actually supported.
mFragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_GLES2_SPEC, SH_HLSL_OUTPUT, &resources);
mVertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_GLES2_SPEC, SH_HLSL_OUTPUT, &resources);
}
}
}
void Shader::releaseCompiler()
{
ShDestruct(mFragmentCompiler);
@ -282,7 +282,7 @@ void Shader::parseVaryings()
*array = '\0';
}
varyings.push_back(Varying(parseType(varyingType), varyingName, size, array != NULL));
mVaryings.push_back(Varying(parseType(varyingType), varyingName, size, array != NULL));
input = strstr(input, ";") + 2;
}
@ -294,36 +294,56 @@ void Shader::parseVaryings()
}
}
void Shader::compileToHLSL(void *compiler)
// initialize/clean up previous state
void Shader::uncompile()
{
if (isCompiled() || !mSource)
{
return;
}
// set by compileToHLSL
delete[] mHlsl;
mHlsl = NULL;
delete[] mInfoLog;
mInfoLog = NULL;
// set by parseVaryings
mVaryings.clear();
mUsesFragCoord = false;
mUsesFrontFacing = false;
mUsesPointSize = false;
mUsesPointCoord = false;
}
void Shader::compileToHLSL(void *compiler)
{
// ensure we don't pass a NULL source to the compiler
char *source = "\0";
if (mSource)
{
source = mSource;
}
// ensure the compiler is loaded
initializeCompiler();
int compileOptions = SH_OBJECT_CODE;
std::string sourcePath;
if (perfActive())
{
sourcePath = getTempPath();
writeFile(sourcePath.c_str(), mSource, strlen(mSource));
writeFile(sourcePath.c_str(), source, strlen(source));
compileOptions |= SH_LINE_DIRECTIVES;
}
int result;
if (sourcePath.empty())
{
result = ShCompile(compiler, &mSource, 1, compileOptions);
result = ShCompile(compiler, &source, 1, compileOptions);
}
else
{
const char* sourceStrings[2] =
{
sourcePath.c_str(),
mSource
source
};
result = ShCompile(compiler, sourceStrings, 2, compileOptions | SH_SOURCE_PATH);
@ -478,8 +498,18 @@ GLenum VertexShader::getType()
return GL_VERTEX_SHADER;
}
void VertexShader::uncompile()
{
Shader::uncompile();
// set by ParseAttributes
mAttributes.clear();
};
void VertexShader::compile()
{
uncompile();
compileToHLSL(mVertexCompiler);
parseAttributes();
parseVaryings();
@ -506,9 +536,10 @@ int VertexShader::getSemanticIndex(const std::string &attributeName)
void VertexShader::parseAttributes()
{
if (mHlsl)
const char *hlsl = getHLSL();
if (hlsl)
{
const char *input = strstr(mHlsl, "// Attributes") + 14;
const char *input = strstr(hlsl, "// Attributes") + 14;
while(true)
{
@ -544,8 +575,10 @@ GLenum FragmentShader::getType()
void FragmentShader::compile()
{
uncompile();
compileToHLSL(mFragmentCompiler);
parseVaryings();
varyings.sort(compareVarying);
mVaryings.sort(compareVarying);
}
}

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@ -62,6 +62,7 @@ class Shader
void getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer);
virtual void compile() = 0;
virtual void uncompile();
bool isCompiled();
const char *getHLSL();
@ -74,8 +75,6 @@ class Shader
static void releaseCompiler();
protected:
DISALLOW_COPY_AND_ASSIGN(Shader);
void parseVaryings();
void compileToHLSL(void *compiler);
@ -85,6 +84,21 @@ class Shader
static GLenum parseType(const std::string &type);
static bool compareVarying(const Varying &x, const Varying &y);
VaryingList mVaryings;
bool mUsesFragCoord;
bool mUsesFrontFacing;
bool mUsesPointSize;
bool mUsesPointCoord;
static void *mFragmentCompiler;
static void *mVertexCompiler;
private:
DISALLOW_COPY_AND_ASSIGN(Shader);
void initializeCompiler();
const GLuint mHandle;
unsigned int mRefCount; // Number of program objects this shader is attached to
bool mDeleteStatus; // Flag to indicate that the shader can be deleted when no longer in use
@ -93,17 +107,7 @@ class Shader
char *mHlsl;
char *mInfoLog;
VaryingList varyings;
bool mUsesFragCoord;
bool mUsesFrontFacing;
bool mUsesPointSize;
bool mUsesPointCoord;
ResourceManager *mResourceManager;
static void *mFragmentCompiler;
static void *mVertexCompiler;
};
struct Attribute
@ -133,6 +137,7 @@ class VertexShader : public Shader
virtual GLenum getType();
virtual void compile();
virtual void uncompile();
int getSemanticIndex(const std::string &attributeName);
private:

View File

@ -270,7 +270,7 @@ void Image::updateSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint y
{
IDirect3DSurface9 *sourceSurface = getSurface();
if (sourceSurface != destSurface)
if (sourceSurface && sourceSurface != destSurface)
{
RECT rect = transformPixelRect(xoffset, yoffset, width, height, mHeight);
@ -290,10 +290,19 @@ void Image::updateSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint y
}
// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input
// into the target pixel rectangle at output with outputPitch bytes in between each line.
// into the target pixel rectangle at locked.pBits with locked.Pitch bytes in between each line.
void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum type,
GLint unpackAlignment, const void *input, size_t outputPitch, void *output) const
GLint unpackAlignment, const void *input)
{
RECT lockRect = transformPixelRect(xoffset, yoffset, width, height, mHeight);
D3DLOCKED_RECT locked;
HRESULT result = lock(&locked, &lockRect);
if (FAILED(result))
{
return;
}
GLsizei inputPitch = -ComputePitch(width, mFormat, type, unpackAlignment);
input = ((char*)input) - inputPitch * (height - 1);
@ -303,29 +312,29 @@ void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height
switch (mFormat)
{
case GL_ALPHA:
loadAlphaData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
loadAlphaData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
case GL_LUMINANCE:
loadLuminanceData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output, getD3DFormat() == D3DFMT_L8);
loadLuminanceData(width, height, inputPitch, input, locked.Pitch, locked.pBits, getD3DFormat() == D3DFMT_L8);
break;
case GL_LUMINANCE_ALPHA:
loadLuminanceAlphaData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output, getD3DFormat() == D3DFMT_A8L8);
loadLuminanceAlphaData(width, height, inputPitch, input, locked.Pitch, locked.pBits, getD3DFormat() == D3DFMT_A8L8);
break;
case GL_RGB:
loadRGBUByteData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
loadRGBUByteData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
case GL_RGBA:
if (supportsSSE2())
{
loadRGBAUByteDataSSE2(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
loadRGBAUByteDataSSE2(width, height, inputPitch, input, locked.Pitch, locked.pBits);
}
else
{
loadRGBAUByteData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
loadRGBAUByteData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
}
break;
case GL_BGRA_EXT:
loadBGRAData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
loadBGRAData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
default: UNREACHABLE();
}
@ -334,7 +343,7 @@ void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height
switch (mFormat)
{
case GL_RGB:
loadRGB565Data(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
loadRGB565Data(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
default: UNREACHABLE();
}
@ -343,7 +352,7 @@ void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height
switch (mFormat)
{
case GL_RGBA:
loadRGBA4444Data(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
loadRGBA4444Data(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
default: UNREACHABLE();
}
@ -352,7 +361,7 @@ void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height
switch (mFormat)
{
case GL_RGBA:
loadRGBA5551Data(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
loadRGBA5551Data(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
default: UNREACHABLE();
}
@ -362,19 +371,19 @@ void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height
{
// float textures are converted to RGBA, not BGRA, as they're stored that way in D3D
case GL_ALPHA:
loadAlphaFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
loadAlphaFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
case GL_LUMINANCE:
loadLuminanceFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
loadLuminanceFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
case GL_LUMINANCE_ALPHA:
loadLuminanceAlphaFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
loadLuminanceAlphaFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
case GL_RGB:
loadRGBFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
loadRGBFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
case GL_RGBA:
loadRGBAFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
loadRGBAFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
default: UNREACHABLE();
}
@ -384,28 +393,30 @@ void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height
{
// float textures are converted to RGBA, not BGRA, as they're stored that way in D3D
case GL_ALPHA:
loadAlphaHalfFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
loadAlphaHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
case GL_LUMINANCE:
loadLuminanceHalfFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
loadLuminanceHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
case GL_LUMINANCE_ALPHA:
loadLuminanceAlphaHalfFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
loadLuminanceAlphaHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
case GL_RGB:
loadRGBHalfFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
loadRGBHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
case GL_RGBA:
loadRGBAHalfFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
loadRGBAHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
default: UNREACHABLE();
}
break;
default: UNREACHABLE();
}
unlock();
}
void Image::loadAlphaData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void Image::loadAlphaData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const
{
const unsigned char *source = NULL;
@ -414,7 +425,7 @@ void Image::loadAlphaData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei h
for (int y = 0; y < height; y++)
{
source = static_cast<const unsigned char*>(input) + y * inputPitch;
dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
dest = static_cast<unsigned char*>(output) + y * outputPitch;
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = 0;
@ -425,7 +436,7 @@ void Image::loadAlphaData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei h
}
}
void Image::loadAlphaFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void Image::loadAlphaFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const
{
const float *source = NULL;
@ -434,7 +445,7 @@ void Image::loadAlphaFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsi
for (int y = 0; y < height; y++)
{
source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 16);
dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = 0;
@ -445,7 +456,7 @@ void Image::loadAlphaFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsi
}
}
void Image::loadAlphaHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void Image::loadAlphaHalfFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const
{
const unsigned short *source = NULL;
@ -454,7 +465,7 @@ void Image::loadAlphaHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width,
for (int y = 0; y < height; y++)
{
source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 8);
dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + y * outputPitch);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = 0;
@ -465,17 +476,16 @@ void Image::loadAlphaHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width,
}
}
void Image::loadLuminanceData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void Image::loadLuminanceData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const
{
const int destBytesPerPixel = native? 1: 4;
const unsigned char *source = NULL;
unsigned char *dest = NULL;
for (int y = 0; y < height; y++)
{
source = static_cast<const unsigned char*>(input) + y * inputPitch;
dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * destBytesPerPixel;
dest = static_cast<unsigned char*>(output) + y * outputPitch;
if (!native) // BGRA8 destination format
{
@ -494,7 +504,7 @@ void Image::loadLuminanceData(GLint xoffset, GLint yoffset, GLsizei width, GLsiz
}
}
void Image::loadLuminanceFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void Image::loadLuminanceFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const
{
const float *source = NULL;
@ -503,7 +513,7 @@ void Image::loadLuminanceFloatData(GLint xoffset, GLint yoffset, GLsizei width,
for (int y = 0; y < height; y++)
{
source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 16);
dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = source[x];
@ -514,7 +524,7 @@ void Image::loadLuminanceFloatData(GLint xoffset, GLint yoffset, GLsizei width,
}
}
void Image::loadLuminanceHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void Image::loadLuminanceHalfFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const
{
const unsigned short *source = NULL;
@ -523,7 +533,7 @@ void Image::loadLuminanceHalfFloatData(GLint xoffset, GLint yoffset, GLsizei wid
for (int y = 0; y < height; y++)
{
source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 8);
dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + y * outputPitch);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = source[x];
@ -534,17 +544,16 @@ void Image::loadLuminanceHalfFloatData(GLint xoffset, GLint yoffset, GLsizei wid
}
}
void Image::loadLuminanceAlphaData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void Image::loadLuminanceAlphaData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const
{
const int destBytesPerPixel = native? 2: 4;
const unsigned char *source = NULL;
unsigned char *dest = NULL;
for (int y = 0; y < height; y++)
{
source = static_cast<const unsigned char*>(input) + y * inputPitch;
dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * destBytesPerPixel;
dest = static_cast<unsigned char*>(output) + y * outputPitch;
if (!native) // BGRA8 destination format
{
@ -563,7 +572,7 @@ void Image::loadLuminanceAlphaData(GLint xoffset, GLint yoffset, GLsizei width,
}
}
void Image::loadLuminanceAlphaFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void Image::loadLuminanceAlphaFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const
{
const float *source = NULL;
@ -572,7 +581,7 @@ void Image::loadLuminanceAlphaFloatData(GLint xoffset, GLint yoffset, GLsizei wi
for (int y = 0; y < height; y++)
{
source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 16);
dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = source[2*x+0];
@ -583,7 +592,7 @@ void Image::loadLuminanceAlphaFloatData(GLint xoffset, GLint yoffset, GLsizei wi
}
}
void Image::loadLuminanceAlphaHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void Image::loadLuminanceAlphaHalfFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const
{
const unsigned short *source = NULL;
@ -592,7 +601,7 @@ void Image::loadLuminanceAlphaHalfFloatData(GLint xoffset, GLint yoffset, GLsize
for (int y = 0; y < height; y++)
{
source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 8);
dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + y * outputPitch);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = source[2*x+0];
@ -603,7 +612,7 @@ void Image::loadLuminanceAlphaHalfFloatData(GLint xoffset, GLint yoffset, GLsize
}
}
void Image::loadRGBUByteData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void Image::loadRGBUByteData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const
{
const unsigned char *source = NULL;
@ -612,7 +621,7 @@ void Image::loadRGBUByteData(GLint xoffset, GLint yoffset, GLsizei width, GLsize
for (int y = 0; y < height; y++)
{
source = static_cast<const unsigned char*>(input) + y * inputPitch;
dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
dest = static_cast<unsigned char*>(output) + y * outputPitch;
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = source[x * 3 + 2];
@ -623,7 +632,7 @@ void Image::loadRGBUByteData(GLint xoffset, GLint yoffset, GLsizei width, GLsize
}
}
void Image::loadRGB565Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void Image::loadRGB565Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const
{
const unsigned short *source = NULL;
@ -632,7 +641,7 @@ void Image::loadRGB565Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei
for (int y = 0; y < height; y++)
{
source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
dest = static_cast<unsigned char*>(output) + y * outputPitch;
for (int x = 0; x < width; x++)
{
unsigned short rgba = source[x];
@ -644,7 +653,7 @@ void Image::loadRGB565Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei
}
}
void Image::loadRGBFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void Image::loadRGBFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const
{
const float *source = NULL;
@ -653,7 +662,7 @@ void Image::loadRGBFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsize
for (int y = 0; y < height; y++)
{
source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 16);
dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = source[x * 3 + 0];
@ -664,7 +673,7 @@ void Image::loadRGBFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsize
}
}
void Image::loadRGBHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void Image::loadRGBHalfFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const
{
const unsigned short *source = NULL;
@ -673,7 +682,7 @@ void Image::loadRGBHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GL
for (int y = 0; y < height; y++)
{
source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 8);
dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + y * outputPitch);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = source[x * 3 + 0];
@ -684,7 +693,7 @@ void Image::loadRGBHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GL
}
}
void Image::loadRGBAUByteDataSSE2(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void Image::loadRGBAUByteDataSSE2(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const
{
const unsigned int *source = NULL;
@ -694,7 +703,7 @@ void Image::loadRGBAUByteDataSSE2(GLint xoffset, GLint yoffset, GLsizei width, G
for (int y = 0; y < height; y++)
{
source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4);
dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + y * outputPitch);
int x = 0;
// Make output writes aligned
@ -726,7 +735,7 @@ void Image::loadRGBAUByteDataSSE2(GLint xoffset, GLint yoffset, GLsizei width, G
}
}
void Image::loadRGBAUByteData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void Image::loadRGBAUByteData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const
{
const unsigned int *source = NULL;
@ -734,7 +743,7 @@ void Image::loadRGBAUByteData(GLint xoffset, GLint yoffset, GLsizei width, GLsiz
for (int y = 0; y < height; y++)
{
source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4);
dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + y * outputPitch);
for (int x = 0; x < width; x++)
{
@ -744,7 +753,7 @@ void Image::loadRGBAUByteData(GLint xoffset, GLint yoffset, GLsizei width, GLsiz
}
}
void Image::loadRGBA4444Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void Image::loadRGBA4444Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const
{
const unsigned short *source = NULL;
@ -753,7 +762,7 @@ void Image::loadRGBA4444Data(GLint xoffset, GLint yoffset, GLsizei width, GLsize
for (int y = 0; y < height; y++)
{
source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
dest = static_cast<unsigned char*>(output) + y * outputPitch;
for (int x = 0; x < width; x++)
{
unsigned short rgba = source[x];
@ -765,7 +774,7 @@ void Image::loadRGBA4444Data(GLint xoffset, GLint yoffset, GLsizei width, GLsize
}
}
void Image::loadRGBA5551Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void Image::loadRGBA5551Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const
{
const unsigned short *source = NULL;
@ -774,7 +783,7 @@ void Image::loadRGBA5551Data(GLint xoffset, GLint yoffset, GLsizei width, GLsize
for (int y = 0; y < height; y++)
{
source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
dest = static_cast<unsigned char*>(output) + y * outputPitch;
for (int x = 0; x < width; x++)
{
unsigned short rgba = source[x];
@ -786,7 +795,7 @@ void Image::loadRGBA5551Data(GLint xoffset, GLint yoffset, GLsizei width, GLsize
}
}
void Image::loadRGBAFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void Image::loadRGBAFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const
{
const float *source = NULL;
@ -795,12 +804,12 @@ void Image::loadRGBAFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsiz
for (int y = 0; y < height; y++)
{
source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 16);
dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
memcpy(dest, source, width * 16);
}
}
void Image::loadRGBAHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void Image::loadRGBAHalfFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const
{
const unsigned char *source = NULL;
@ -809,12 +818,12 @@ void Image::loadRGBAHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, G
for (int y = 0; y < height; y++)
{
source = static_cast<const unsigned char*>(input) + y * inputPitch;
dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 8;
dest = static_cast<unsigned char*>(output) + y * outputPitch;
memcpy(dest, source, width * 8);
}
}
void Image::loadBGRAData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void Image::loadBGRAData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const
{
const unsigned char *source = NULL;
@ -823,25 +832,43 @@ void Image::loadBGRAData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei he
for (int y = 0; y < height; y++)
{
source = static_cast<const unsigned char*>(input) + y * inputPitch;
dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
dest = static_cast<unsigned char*>(output) + y * outputPitch;
memcpy(dest, source, width*4);
}
}
void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const {
const void *input) {
ASSERT(xoffset % 4 == 0);
ASSERT(yoffset % 4 == 0);
RECT lockRect = transformPixelRect(xoffset, yoffset, width, height, mHeight);
D3DLOCKED_RECT locked;
HRESULT result = lock(&locked, &lockRect);
if (FAILED(result))
{
return;
}
GLsizei inputPitch = -ComputeCompressedPitch(width, mFormat);
GLsizei inputSize = ComputeCompressedSize(width, height, mFormat);
input = ((char*)input) + inputSize + inputPitch;
switch (getD3DFormat())
{
case D3DFMT_DXT1:
loadDXT1Data(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
loadDXT1Data(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
case D3DFMT_DXT3:
loadDXT3Data(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
loadDXT3Data(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
case D3DFMT_DXT5:
loadDXT5Data(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
loadDXT5Data(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
}
unlock();
}
static void FlipCopyDXT1BlockFull(const unsigned int* source, unsigned int* dest) {
@ -954,11 +981,9 @@ static void FlipCopyDXT5BlockHalf(const unsigned int* source, unsigned int* dest
FlipCopyDXT1BlockHalf(source + 2, dest + 2);
}
void Image::loadDXT1Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void Image::loadDXT1Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const
{
ASSERT(xoffset % 4 == 0);
ASSERT(yoffset % 4 == 0);
ASSERT(width % 4 == 0 || width == 2 || width == 1);
ASSERT(inputPitch % 8 == 0);
ASSERT(outputPitch % 8 == 0);
@ -991,7 +1016,7 @@ void Image::loadDXT1Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei he
for (int y = 0; y < height / 4; ++y)
{
const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
unsigned int *dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 8);
unsigned int *dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + y * outputPitch);
for (int x = 0; x < intsAcross; x += 2)
{
@ -1002,11 +1027,9 @@ void Image::loadDXT1Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei he
}
}
void Image::loadDXT3Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void Image::loadDXT3Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const
{
ASSERT(xoffset % 4 == 0);
ASSERT(yoffset % 4 == 0);
ASSERT(width % 4 == 0 || width == 2 || width == 1);
ASSERT(inputPitch % 16 == 0);
ASSERT(outputPitch % 16 == 0);
@ -1041,7 +1064,7 @@ void Image::loadDXT3Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei he
for (int y = 0; y < height / 4; ++y)
{
const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
unsigned int *dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 16);
unsigned int *dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + y * outputPitch);
for (int x = 0; x < intsAcross; x += 4)
{
@ -1052,11 +1075,9 @@ void Image::loadDXT3Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei he
}
}
void Image::loadDXT5Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void Image::loadDXT5Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const
{
ASSERT(xoffset % 4 == 0);
ASSERT(yoffset % 4 == 0);
ASSERT(width % 4 == 0 || width == 2 || width == 1);
ASSERT(inputPitch % 16 == 0);
ASSERT(outputPitch % 16 == 0);
@ -1091,7 +1112,7 @@ void Image::loadDXT5Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei he
for (int y = 0; y < height / 4; ++y)
{
const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
unsigned int *dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 16);
unsigned int *dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + y * outputPitch);
for (int x = 0; x < intsAcross; x += 4)
{
@ -1456,15 +1477,7 @@ void Texture::setImage(GLint unpackAlignment, const void *pixels, Image *image)
{
if (pixels != NULL)
{
D3DLOCKED_RECT locked;
HRESULT result = image->lock(&locked, NULL);
if (SUCCEEDED(result))
{
image->loadData(0, 0, image->getWidth(), image->getHeight(), image->getType(), unpackAlignment, pixels, locked.Pitch, locked.pBits);
image->unlock();
}
image->loadData(0, 0, image->getWidth(), image->getHeight(), image->getType(), unpackAlignment, pixels);
mDirtyImages = true;
}
}
@ -1473,17 +1486,7 @@ void Texture::setCompressedImage(GLsizei imageSize, const void *pixels, Image *i
{
if (pixels != NULL)
{
D3DLOCKED_RECT locked;
HRESULT result = image->lock(&locked, NULL);
if (SUCCEEDED(result))
{
int inputPitch = ComputeCompressedPitch(image->getWidth(), image->getFormat());
int inputSize = ComputeCompressedSize(image->getWidth(), image->getHeight(), image->getFormat());
image->loadCompressedData(0, 0, image->getWidth(), image->getHeight(), -inputPitch, static_cast<const char*>(pixels) + inputSize - inputPitch, locked.Pitch, locked.pBits);
image->unlock();
}
image->loadCompressedData(0, 0, image->getWidth(), image->getHeight(), pixels);
mDirtyImages = true;
}
}
@ -1510,15 +1513,7 @@ bool Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei heig
if (pixels != NULL)
{
D3DLOCKED_RECT locked;
HRESULT result = image->lock(&locked, NULL);
if (SUCCEEDED(result))
{
image->loadData(xoffset, transformPixelYOffset(yoffset, height, image->getHeight()), width, height, type, unpackAlignment, pixels, locked.Pitch, locked.pBits);
image->unlock();
}
image->loadData(xoffset, yoffset, width, height, type, unpackAlignment, pixels);
mDirtyImages = true;
}
@ -1541,23 +1536,7 @@ bool Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GL
if (pixels != NULL)
{
RECT updateRegion;
updateRegion.left = xoffset;
updateRegion.right = xoffset + width;
updateRegion.bottom = yoffset + height;
updateRegion.top = yoffset;
D3DLOCKED_RECT locked;
HRESULT result = image->lock(&locked, &updateRegion);
if (SUCCEEDED(result))
{
int inputPitch = ComputeCompressedPitch(width, format);
int inputSize = ComputeCompressedSize(width, height, format);
image->loadCompressedData(xoffset, transformPixelYOffset(yoffset, height, image->getHeight()), width, height, -inputPitch, static_cast<const char*>(pixels) + inputSize - inputPitch, locked.Pitch, locked.pBits);
image->unlock();
}
image->loadCompressedData(xoffset, yoffset, width, height, pixels);
mDirtyImages = true;
}
@ -2583,7 +2562,9 @@ bool TextureCubeMap::isSamplerComplete() const
case GL_LINEAR_MIPMAP_LINEAR:
mipmapping = true;
break;
default: UNREACHABLE();
default:
UNREACHABLE();
return false;
}
if ((getInternalFormat() == GL_FLOAT && !getContext()->supportsFloat32LinearFilter()) ||
@ -2752,9 +2733,6 @@ void TextureCubeMap::convertToRenderTarget()
if (mTexStorage != NULL)
{
egl::Display *display = getDisplay();
IDirect3DDevice9 *device = display->getDevice();
int levels = levelCount();
for (int f = 0; f < 6; f++)
{

View File

@ -53,9 +53,6 @@ class Image
void markDirty() {mDirty = true;}
void markClean() {mDirty = false;}
HRESULT lock(D3DLOCKED_RECT *lockedRect, const RECT *rect);
void unlock();
bool isRenderableFormat() const;
D3DFORMAT getD3DFormat() const;
@ -70,55 +67,55 @@ class Image
void updateSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum type,
GLint unpackAlignment, const void *input, std::size_t outputPitch, void *output) const;
GLint unpackAlignment, const void *input);
void loadAlphaData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void loadAlphaData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadAlphaFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void loadAlphaFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadAlphaHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void loadAlphaHalfFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void loadLuminanceData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const;
void loadLuminanceFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void loadLuminanceFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void loadLuminanceHalfFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceAlphaData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void loadLuminanceAlphaData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const;
void loadLuminanceAlphaFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void loadLuminanceAlphaFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceAlphaHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void loadLuminanceAlphaHalfFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBUByteData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void loadRGBUByteData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGB565Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void loadRGB565Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void loadRGBFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void loadRGBHalfFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAUByteDataSSE2(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void loadRGBAUByteDataSSE2(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAUByteData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void loadRGBAUByteData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBA4444Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void loadRGBA4444Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBA5551Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void loadRGBA5551Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void loadRGBAFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void loadRGBAHalfFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadBGRAData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void loadBGRAData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadDXT1Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
const void *input);
void loadDXT1Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadDXT3Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void loadDXT3Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadDXT5Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
void loadDXT5Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget);
@ -128,6 +125,9 @@ class Image
void createSurface();
HRESULT lock(D3DLOCKED_RECT *lockedRect, const RECT *rect);
void unlock();
GLsizei mWidth;
GLsizei mHeight;
GLenum mFormat;

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@ -65,7 +65,7 @@ VertexDataManager::~VertexDataManager()
}
}
std::size_t VertexDataManager::writeAttributeData(ArrayVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute)
std::size_t VertexDataManager::writeAttributeData(ArrayVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute, GLsizei instances)
{
Buffer *buffer = attribute.mBoundBuffer.get();
@ -78,7 +78,7 @@ std::size_t VertexDataManager::writeAttributeData(ArrayVertexBuffer *vertexBuffe
if (vertexBuffer)
{
output = vertexBuffer->map(attribute, spaceRequired(attribute, count), &streamOffset);
output = vertexBuffer->map(attribute, spaceRequired(attribute, count, instances), &streamOffset);
}
if (output == NULL)
@ -100,7 +100,10 @@ std::size_t VertexDataManager::writeAttributeData(ArrayVertexBuffer *vertexBuffe
input = static_cast<const char*>(attribute.mPointer);
}
input += inputStride * start;
if (instances == 0 || attribute.mDivisor == 0)
{
input += inputStride * start;
}
if (converter.identity && inputStride == elementSize)
{
@ -116,7 +119,7 @@ std::size_t VertexDataManager::writeAttributeData(ArrayVertexBuffer *vertexBuffe
return streamOffset;
}
GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *translated)
GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *translated, GLsizei instances)
{
if (!mStreamingBuffer)
{
@ -144,7 +147,7 @@ GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, Translat
if (staticBuffer->size() == 0)
{
int totalCount = elementsInBuffer(attribs[i], buffer->size());
staticBuffer->addRequiredSpace(spaceRequired(attribs[i], totalCount));
staticBuffer->addRequiredSpace(spaceRequired(attribs[i], totalCount, 0));
}
else if (staticBuffer->lookupAttribute(attribs[i]) == -1)
{
@ -159,19 +162,19 @@ GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, Translat
if (staticBuffer == previousStaticBuffer)
{
mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[previous], count));
mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[previous], count, instances));
}
}
}
mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[i], count));
mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[i], count, instances));
buffer->invalidateStaticData();
}
}
else
{
mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[i], count));
mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[i], count, instances));
}
}
}
@ -225,17 +228,22 @@ GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, Translat
int totalCount = elementsInBuffer(attribs[i], buffer->size());
int startIndex = attribs[i].mOffset / attribs[i].stride();
streamOffset = writeAttributeData(staticBuffer, -startIndex, totalCount, attribs[i]);
streamOffset = writeAttributeData(staticBuffer, -startIndex, totalCount, attribs[i], 0);
}
if (streamOffset != -1)
{
streamOffset += (start + attribs[i].mOffset / attribs[i].stride()) * converter.outputElementSize;
streamOffset += (attribs[i].mOffset / attribs[i].stride()) * converter.outputElementSize;
if (instances == 0 || attribs[i].mDivisor == 0)
{
streamOffset += start * converter.outputElementSize;
}
}
}
else
{
streamOffset = writeAttributeData(mStreamingBuffer, start, count, attribs[i]);
streamOffset = writeAttributeData(mStreamingBuffer, start, count, attribs[i], instances);
}
if (streamOffset == -1)
@ -245,6 +253,8 @@ GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, Translat
translated[i].vertexBuffer = vertexBuffer->getBuffer();
translated[i].serial = vertexBuffer->getSerial();
translated[i].divisor = attribs[i].mDivisor;
translated[i].type = converter.d3dDeclType;
translated[i].stride = converter.outputElementSize;
translated[i].offset = streamOffset;
@ -277,6 +287,7 @@ GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, Translat
translated[i].vertexBuffer = mCurrentValueBuffer[i]->getBuffer();
translated[i].serial = mCurrentValueBuffer[i]->getSerial();
translated[i].divisor = 0;
translated[i].type = D3DDECLTYPE_FLOAT4;
translated[i].stride = 0;
@ -301,9 +312,18 @@ GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, Translat
return GL_NO_ERROR;
}
std::size_t VertexDataManager::spaceRequired(const VertexAttribute &attrib, std::size_t count) const
std::size_t VertexDataManager::spaceRequired(const VertexAttribute &attrib, std::size_t count, GLsizei instances) const
{
return formatConverter(attrib).outputElementSize * count;
size_t elementSize = formatConverter(attrib).outputElementSize;
if (instances == 0 || attrib.mDivisor == 0)
{
return elementSize * count;
}
else
{
return elementSize * ((instances + attrib.mDivisor - 1) / attrib.mDivisor);
}
}
// Mapping from OpenGL-ES vertex attrib type to D3D decl type:
@ -497,14 +517,20 @@ public:
{ TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 4) }, \
}
#define TRANSLATIONS_FOR_TYPE_NO_NORM(type) \
{ \
{ TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \
{ TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \
}
const VertexDataManager::TranslationDescription VertexDataManager::mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = // [GL types as enumerated by typeIndex()][normalized][size-1]
{
TRANSLATIONS_FOR_TYPE(GL_BYTE),
TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_BYTE),
TRANSLATIONS_FOR_TYPE(GL_SHORT),
TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_SHORT),
TRANSLATIONS_FOR_TYPE(GL_FIXED),
TRANSLATIONS_FOR_TYPE(GL_FLOAT)
TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FIXED),
TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FLOAT)
};
void VertexDataManager::checkVertexCaps(DWORD declTypes)

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@ -31,6 +31,7 @@ struct TranslatedAttribute
IDirect3DVertexBuffer9 *vertexBuffer;
unsigned int serial;
unsigned int divisor;
};
class VertexBuffer
@ -117,13 +118,13 @@ class VertexDataManager
void dirtyCurrentValue(int index) { mDirtyCurrentValue[index] = true; }
GLenum prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *outAttribs);
GLenum prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *outAttribs, GLsizei instances);
private:
DISALLOW_COPY_AND_ASSIGN(VertexDataManager);
std::size_t spaceRequired(const VertexAttribute &attrib, std::size_t count) const;
std::size_t writeAttributeData(ArrayVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute);
std::size_t spaceRequired(const VertexAttribute &attrib, std::size_t count, GLsizei instances) const;
std::size_t writeAttributeData(ArrayVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute, GLsizei instances);
Context *const mContext;
IDirect3DDevice9 *const mDevice;

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@ -1932,7 +1932,34 @@ void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
if (context)
{
context->drawArrays(mode, first, count);
context->drawArrays(mode, first, count, 0);
}
}
catch(std::bad_alloc&)
{
return error(GL_OUT_OF_MEMORY);
}
}
void __stdcall glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
{
EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei primcount = %d)", mode, first, count, primcount);
try
{
if (count < 0 || first < 0 || primcount < 0)
{
return error(GL_INVALID_VALUE);
}
if (primcount > 0)
{
gl::Context *context = gl::getNonLostContext();
if (context)
{
context->drawArrays(mode, first, count, primcount);
}
}
}
catch(std::bad_alloc&)
@ -1972,7 +1999,50 @@ void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLv
return error(GL_INVALID_ENUM);
}
context->drawElements(mode, count, type, indices);
context->drawElements(mode, count, type, indices, 0);
}
}
catch(std::bad_alloc&)
{
return error(GL_OUT_OF_MEMORY);
}
}
void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount)
{
EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei primcount = %d)",
mode, count, type, indices, primcount);
try
{
if (count < 0 || primcount < 0)
{
return error(GL_INVALID_VALUE);
}
if (primcount > 0)
{
gl::Context *context = gl::getNonLostContext();
if (context)
{
switch (type)
{
case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT:
break;
case GL_UNSIGNED_INT:
if (!context->supports32bitIndices())
{
return error(GL_INVALID_ENUM);
}
break;
default:
return error(GL_INVALID_ENUM);
}
context->drawElements(mode, count, type, indices, primcount);
}
}
}
catch(std::bad_alloc&)
@ -2969,7 +3039,11 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
{
attachmentObjectType = GL_TEXTURE;
}
else UNREACHABLE();
else
{
UNREACHABLE();
return;
}
switch (pname)
{
@ -3244,7 +3318,6 @@ void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params)
if (context)
{
gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
if (!queryObject)
@ -3547,8 +3620,6 @@ const GLubyte* __stdcall glGetString(GLenum name)
{
return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
}
return NULL;
}
void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
@ -3907,6 +3978,9 @@ void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
params[i] = attribState.mCurrentValue[i];
}
break;
case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
*params = (GLfloat)attribState.mDivisor;
break;
default: return error(GL_INVALID_ENUM);
}
}
@ -3961,6 +4035,9 @@ void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
}
break;
case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
*params = (GLint)attribState.mDivisor;
break;
default: return error(GL_INVALID_ENUM);
}
}
@ -4919,7 +4996,7 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
return error(GL_INVALID_VALUE);
}
if (internalformat != format)
if (internalformat != GLint(format))
{
return error(GL_INVALID_OPERATION);
}
@ -6212,6 +6289,30 @@ void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
}
}
void __stdcall glVertexAttribDivisorANGLE(GLuint index, GLuint divisor)
{
EVENT("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
try
{
if (index >= gl::MAX_VERTEX_ATTRIBS)
{
return error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
if (context)
{
context->setVertexAttribDivisor(index, divisor);
}
}
catch(std::bad_alloc&)
{
return error(GL_OUT_OF_MEMORY);
}
}
void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
{
EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
@ -6384,6 +6485,9 @@ __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *
{"glEndQueryEXT", (__eglMustCastToProperFunctionPointerType)glEndQueryEXT},
{"glGetQueryivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryivEXT},
{"glGetQueryObjectuivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryObjectuivEXT},
{"glVertexAttribDivisorANGLE", (__eglMustCastToProperFunctionPointerType)glVertexAttribDivisorANGLE},
{"glDrawArraysInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawArraysInstancedANGLE},
{"glDrawElementsInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawElementsInstancedANGLE},
};
for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)

View File

@ -167,6 +167,9 @@ EXPORTS
glEndQueryEXT @169
glGetQueryivEXT @170
glGetQueryObjectuivEXT @171
glVertexAttribDivisorANGLE @172
glDrawArraysInstancedANGLE @173
glDrawElementsInstancedANGLE @174
; EGL dependencies
glCreateContext @144 NONAME

View File

@ -0,0 +1,44 @@
# Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
{
'targets': [
{
'target_name': 'gtest',
'type': 'static_library',
'include_dirs': [
'../third_party/googletest',
'../third_party/googletest/include',
],
'sources': [
'../third_party/googletest/src/gtest-all.cc',
],
},
{
'target_name': 'preprocessor_tests',
'type': 'executable',
'dependencies': [
'../src/build_angle.gyp:preprocessor',
'gtest',
],
'include_dirs': [
'../src/compiler/preprocessor/new',
'../third_party/googletest/include',
],
'sources': [
'../third_party/googletest/src/gtest_main.cc',
'preprocessor_tests/identifier_test.cpp',
'preprocessor_tests/number_test.cpp',
'preprocessor_tests/token_test.cpp',
'preprocessor_tests/space_test.cpp',
],
},
],
}
# Local Variables:
# tab-width:2
# indent-tabs-mode:nil
# End:
# vim: set expandtab tabstop=2 shiftwidth=2:

View File

@ -0,0 +1,149 @@
//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "gtest/gtest.h"
#include "Preprocessor.h"
#include "Token.h"
static void PreprocessAndVerifyIdentifier(const char* str)
{
pp::Token token;
pp::Preprocessor preprocessor;
ASSERT_TRUE(preprocessor.init(1, &str, 0));
EXPECT_EQ(pp::Token::IDENTIFIER, preprocessor.lex(&token));
EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_STREQ(str, token.value.c_str());
}
#if GTEST_HAS_COMBINE
typedef std::tr1::tuple<char, char> IdentifierParams;
class IdentifierTest : public testing::TestWithParam<IdentifierParams>
{
};
// This test covers identifier names of form [_a-zA-Z][_a-zA-Z0-9]?.
TEST_P(IdentifierTest, IdentifierIdentified)
{
std::string str(1, std::tr1::get<0>(GetParam()));
char c = std::tr1::get<1>(GetParam());
if (c != '\0') str.push_back(c);
PreprocessAndVerifyIdentifier(str.c_str());
}
// Test string: '_'
INSTANTIATE_TEST_CASE_P(SingleLetter_Underscore,
IdentifierTest,
testing::Combine(testing::Values('_'),
testing::Values('\0')));
// Test string: [a-f]
INSTANTIATE_TEST_CASE_P(SingleLetter_a_f,
IdentifierTest,
testing::Combine(testing::Range('a', 'f'),
testing::Values('\0')));
// Test string: [A-F]
INSTANTIATE_TEST_CASE_P(SingleLetter_A_F,
IdentifierTest,
testing::Combine(testing::Range('A', 'F'),
testing::Values('\0')));
// Test string: "__"
INSTANTIATE_TEST_CASE_P(DoubleLetter_Underscore_Underscore,
IdentifierTest,
testing::Combine(testing::Values('_'),
testing::Values('_')));
// Test string: "_"[a-f]
INSTANTIATE_TEST_CASE_P(DoubleLetter_Underscore_a_f,
IdentifierTest,
testing::Combine(testing::Values('_'),
testing::Range('a', 'f')));
// Test string: "_"[A-F]
INSTANTIATE_TEST_CASE_P(DoubleLetter_Underscore_A_F,
IdentifierTest,
testing::Combine(testing::Values('_'),
testing::Range('A', 'F')));
// Test string: "_"[0-9]
INSTANTIATE_TEST_CASE_P(DoubleLetter_Underscore_0_9,
IdentifierTest,
testing::Combine(testing::Values('_'),
testing::Range('0', '9')));
// Test string: [a-f]"_"
INSTANTIATE_TEST_CASE_P(DoubleLetter_a_f_Underscore,
IdentifierTest,
testing::Combine(testing::Range('a', 'f'),
testing::Values('_')));
// Test string: [a-f][a-f]
INSTANTIATE_TEST_CASE_P(DoubleLetter_a_f_a_f,
IdentifierTest,
testing::Combine(testing::Range('a', 'f'),
testing::Range('a', 'f')));
// Test string: [a-f][A-f]
INSTANTIATE_TEST_CASE_P(DoubleLetter_a_f_A_F,
IdentifierTest,
testing::Combine(testing::Range('a', 'f'),
testing::Range('A', 'F')));
// Test string: [a-f][0-9]
INSTANTIATE_TEST_CASE_P(DoubleLetter_a_f_0_9,
IdentifierTest,
testing::Combine(testing::Range('a', 'f'),
testing::Range('0', '9')));
// Test string: [A-F]"_"
INSTANTIATE_TEST_CASE_P(DoubleLetter_A_F_Underscore,
IdentifierTest,
testing::Combine(testing::Range('A', 'F'),
testing::Values('_')));
// Test string: [A-F][a-f]
INSTANTIATE_TEST_CASE_P(DoubleLetter_A_F_a_f,
IdentifierTest,
testing::Combine(testing::Range('A', 'F'),
testing::Range('a', 'f')));
// Test string: [A-F][A-F]
INSTANTIATE_TEST_CASE_P(DoubleLetter_A_F_A_F,
IdentifierTest,
testing::Combine(testing::Range('A', 'F'),
testing::Range('A', 'F')));
// Test string: [A-F][0-9]
INSTANTIATE_TEST_CASE_P(DoubleLetter_A_F_0_9,
IdentifierTest,
testing::Combine(testing::Range('A', 'F'),
testing::Range('0', '9')));
#endif // GTEST_HAS_COMBINE
// The tests above cover one-letter and various combinations of two-letter
// identifier names. This test covers all characters in a single string.
TEST(IdentifierTestAllCharacters, IdentifierIdentified)
{
std::string str;
for (int c = 'a'; c <= 'z'; ++c)
str.push_back(c);
str.push_back('_');
for (int c = 'A'; c <= 'Z'; ++c)
str.push_back(c);
str.push_back('_');
for (int c = '0'; c <= '9'; ++c)
str.push_back(c);
PreprocessAndVerifyIdentifier(str.c_str());
}

View File

@ -0,0 +1,140 @@
//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "gtest/gtest.h"
#include "Preprocessor.h"
#include "Token.h"
#if GTEST_HAS_COMBINE
typedef std::tr1::tuple<const char*, char> IntegerParams;
class IntegerTest : public testing::TestWithParam<IntegerParams>
{
};
TEST_P(IntegerTest, IntegerIdentified)
{
std::string str(std::tr1::get<0>(GetParam())); // prefix.
str.push_back(std::tr1::get<1>(GetParam())); // digit.
const char* cstr = str.c_str();
pp::Token token;
pp::Preprocessor preprocessor;
ASSERT_TRUE(preprocessor.init(1, &cstr, 0));
EXPECT_EQ(pp::Token::CONST_INT, preprocessor.lex(&token));
EXPECT_EQ(pp::Token::CONST_INT, token.type);
EXPECT_STREQ(cstr, token.value.c_str());
}
INSTANTIATE_TEST_CASE_P(DecimalInteger,
IntegerTest,
testing::Combine(testing::Values(""),
testing::Range('0', '9')));
INSTANTIATE_TEST_CASE_P(OctalInteger,
IntegerTest,
testing::Combine(testing::Values("0"),
testing::Range('0', '7')));
INSTANTIATE_TEST_CASE_P(HexadecimalInteger_0_9,
IntegerTest,
testing::Combine(testing::Values("0x"),
testing::Range('0', '9')));
INSTANTIATE_TEST_CASE_P(HexadecimalInteger_a_f,
IntegerTest,
testing::Combine(testing::Values("0x"),
testing::Range('a', 'f')));
INSTANTIATE_TEST_CASE_P(HexadecimalInteger_A_F,
IntegerTest,
testing::Combine(testing::Values("0x"),
testing::Range('A', 'F')));
static void PreprocessAndVerifyFloat(const char* str)
{
pp::Token token;
pp::Preprocessor preprocessor;
ASSERT_TRUE(preprocessor.init(1, &str, 0));
EXPECT_EQ(pp::Token::CONST_FLOAT, preprocessor.lex(&token));
EXPECT_EQ(pp::Token::CONST_FLOAT, token.type);
EXPECT_STREQ(str, token.value.c_str());
}
typedef std::tr1::tuple<char, char, const char*, char> FloatScientificParams;
class FloatScientificTest : public testing::TestWithParam<FloatScientificParams>
{
};
// This test covers floating point numbers of form [0-9][eE][+-]?[0-9].
TEST_P(FloatScientificTest, FloatIdentified)
{
std::string str;
str.push_back(std::tr1::get<0>(GetParam())); // significand [0-9].
str.push_back(std::tr1::get<1>(GetParam())); // separator [eE].
str.append(std::tr1::get<2>(GetParam())); // sign [" " "+" "-"].
str.push_back(std::tr1::get<3>(GetParam())); // exponent [0-9].
SCOPED_TRACE("FloatScientificTest");
PreprocessAndVerifyFloat(str.c_str());
}
INSTANTIATE_TEST_CASE_P(FloatScientific,
FloatScientificTest,
testing::Combine(testing::Range('0', '9'),
testing::Values('e', 'E'),
testing::Values("", "+", "-"),
testing::Range('0', '9')));
typedef std::tr1::tuple<char, char> FloatFractionParams;
class FloatFractionTest : public testing::TestWithParam<FloatFractionParams>
{
};
// This test covers floating point numbers of form [0-9]"." and [0-9]?"."[0-9].
TEST_P(FloatFractionTest, FloatIdentified)
{
std::string str;
char significand = std::tr1::get<0>(GetParam());
if (significand != '\0')
str.push_back(significand);
str.push_back('.');
char fraction = std::tr1::get<1>(GetParam());
if (fraction != '\0')
str.push_back(fraction);
SCOPED_TRACE("FloatFractionTest");
PreprocessAndVerifyFloat(str.c_str());
}
INSTANTIATE_TEST_CASE_P(FloatFraction_X_X,
FloatFractionTest,
testing::Combine(testing::Range('0', '9'),
testing::Range('0', '9')));
INSTANTIATE_TEST_CASE_P(FloatFraction_0_X,
FloatFractionTest,
testing::Combine(testing::Values('\0'),
testing::Range('0', '9')));
INSTANTIATE_TEST_CASE_P(FloatFraction_X_0,
FloatFractionTest,
testing::Combine(testing::Range('0', '9'),
testing::Values('\0')));
#endif // GTEST_HAS_COMBINE
// In the tests above we have tested individual parts of a float separately.
// This test has all parts of a float.
TEST(FloatFractionScientificTest, FloatIdentified)
{
SCOPED_TRACE("FloatFractionScientificTest");
PreprocessAndVerifyFloat("0.1e+2");
}

View File

@ -0,0 +1,116 @@
//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "gtest/gtest.h"
#include "Preprocessor.h"
#include "Token.h"
// Whitespace characters allowed in GLSL.
// Note that newline characters (\n) will be tested separately.
static const char kSpaceChars[] = {' ', '\t', '\v', '\f'};
#if GTEST_HAS_PARAM_TEST
// This test fixture tests the processing of a single whitespace character.
// All tests in this fixture are ran with all possible whitespace character
// allowed in GLSL.
class SpaceCharTest : public testing::TestWithParam<char>
{
};
TEST_P(SpaceCharTest, SpaceIgnored)
{
// Construct test string with the whitespace char before "foo".
const char* identifier = "foo";
std::string str(1, GetParam());
str.append(identifier);
const char* cstr = str.c_str();
pp::Token token;
pp::Preprocessor preprocessor;
ASSERT_TRUE(preprocessor.init(1, &cstr, 0));
// Identifier "foo" is returned after ignoring the whitespace characters.
EXPECT_EQ(pp::Token::IDENTIFIER, preprocessor.lex(&token));
EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_STREQ(identifier, token.value.c_str());
// The whitespace character is however recorded with the next token.
EXPECT_TRUE(token.hasLeadingSpace());
}
INSTANTIATE_TEST_CASE_P(SingleSpaceChar,
SpaceCharTest,
testing::ValuesIn(kSpaceChars));
#endif // GTEST_HAS_PARAM_TEST
#if GTEST_HAS_COMBINE
// This test fixture tests the processing of a string containing consecutive
// whitespace characters. All tests in this fixture are ran with all possible
// combinations of whitespace characters allowed in GLSL.
typedef std::tr1::tuple<char, char, char> SpaceStringParams;
class SpaceStringTest : public testing::TestWithParam<SpaceStringParams>
{
};
TEST_P(SpaceStringTest, SpaceIgnored)
{
// Construct test string with the whitespace char before "foo".
const char* identifier = "foo";
std::string str(1, std::tr1::get<0>(GetParam()));
str.push_back(std::tr1::get<1>(GetParam()));
str.push_back(std::tr1::get<2>(GetParam()));
str.append(identifier);
const char* cstr = str.c_str();
pp::Token token;
pp::Preprocessor preprocessor;
ASSERT_TRUE(preprocessor.init(1, &cstr, 0));
// Identifier "foo" is returned after ignoring the whitespace characters.
EXPECT_EQ(pp::Token::IDENTIFIER, preprocessor.lex(&token));
EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_STREQ(identifier, token.value.c_str());
// The whitespace character is however recorded with the next token.
EXPECT_TRUE(token.hasLeadingSpace());
}
INSTANTIATE_TEST_CASE_P(SpaceCharCombination,
SpaceStringTest,
testing::Combine(testing::ValuesIn(kSpaceChars),
testing::ValuesIn(kSpaceChars),
testing::ValuesIn(kSpaceChars)));
#endif // GTEST_HAS_COMBINE
// The tests above make sure that the space char is recorded in the
// next token. This test makes sure that a token is not incorrectly marked
// to have leading space.
TEST(SpaceTest, LeadingSpace)
{
const char* str = " foo+ -bar";
pp::Token token;
pp::Preprocessor preprocessor;
ASSERT_TRUE(preprocessor.init(1, &str, 0));
EXPECT_EQ(pp::Token::IDENTIFIER, preprocessor.lex(&token));
EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_STREQ("foo", token.value.c_str());
EXPECT_TRUE(token.hasLeadingSpace());
EXPECT_EQ('+', preprocessor.lex(&token));
EXPECT_EQ('+', token.type);
EXPECT_FALSE(token.hasLeadingSpace());
EXPECT_EQ('-', preprocessor.lex(&token));
EXPECT_EQ('-', token.type);
EXPECT_TRUE(token.hasLeadingSpace());
EXPECT_EQ(pp::Token::IDENTIFIER, preprocessor.lex(&token));
EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_STREQ("bar", token.value.c_str());
EXPECT_FALSE(token.hasLeadingSpace());
}

View File

@ -0,0 +1,89 @@
//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "gtest/gtest.h"
#include "Token.h"
TEST(TokenTest, DefaultConstructor)
{
pp::Token token;
EXPECT_EQ(0, token.type);
EXPECT_EQ(0, token.flags);
EXPECT_EQ(0, token.location.line);
EXPECT_EQ(0, token.location.string);
EXPECT_STREQ("", token.value.c_str());
}
TEST(TokenTest, Assignment)
{
pp::Token token;
token.type = 1;
token.flags = 1;
token.location.line = 1;
token.location.string = 1;
token.value.assign("foo");
token = pp::Token();
EXPECT_EQ(0, token.type);
EXPECT_EQ(0, token.flags);
EXPECT_EQ(0, token.location.line);
EXPECT_EQ(0, token.location.string);
EXPECT_STREQ("", token.value.c_str());
}
TEST(TokenTest, Equals)
{
pp::Token token;
EXPECT_TRUE(token.equals(pp::Token()));
token.type = 1;
EXPECT_FALSE(token.equals(pp::Token()));
token.type = 0;
token.flags = 1;
EXPECT_FALSE(token.equals(pp::Token()));
token.flags = 0;
token.location.line = 1;
EXPECT_FALSE(token.equals(pp::Token()));
token.location.line = 0;
token.location.string = 1;
EXPECT_FALSE(token.equals(pp::Token()));
token.location.string = 0;
token.value.assign("foo");
EXPECT_FALSE(token.equals(pp::Token()));
token.value.clear();
EXPECT_TRUE(token.equals(pp::Token()));
}
TEST(TokenTest, HasLeadingSpace)
{
pp::Token token;
EXPECT_FALSE(token.hasLeadingSpace());
token.setHasLeadingSpace(true);
EXPECT_TRUE(token.hasLeadingSpace());
token.setHasLeadingSpace(false);
EXPECT_FALSE(token.hasLeadingSpace());
}
TEST(TokenTest, Write)
{
pp::Token token;
token.value.assign("foo");
std::stringstream out1;
out1 << token;
EXPECT_TRUE(out1.good());
EXPECT_STREQ("foo", out1.str().c_str());
token.setHasLeadingSpace(true);
std::stringstream out2;
out2 << token;
EXPECT_TRUE(out2.good());
EXPECT_STREQ(" foo", out2.str().c_str());
}