mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 19:35:51 +00:00
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:
parent
09b31b5a80
commit
b7aa678078
@ -1,3 +1 @@
|
||||
conformance/glsl/functions/glsl-function-atan-xy.html
|
||||
conformance/glsl/misc/struct-nesting-under-maximum.html
|
||||
conformance/more/functions/uniformfArrayLen1.html
|
||||
|
@ -47,4 +47,5 @@ Yore Apex
|
||||
Mark Callow
|
||||
Yuriy O'Donnell
|
||||
Sam Hocevar
|
||||
Pierre Leveille
|
||||
|
||||
|
@ -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 = [
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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) |
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -14,7 +14,7 @@
|
||||
# manually maintained ones.
|
||||
'../samples/build_samples.gyp:*',
|
||||
'../src/build_angle.gyp:*',
|
||||
# '../tests/tests.gyp:*',
|
||||
'../tests/build_tests.gyp:*',
|
||||
],
|
||||
},
|
||||
],
|
||||
|
@ -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',
|
||||
|
359
gfx/angle/extensions/ANGLE_instanced_arrays.txt
Normal file
359
gfx/angle/extensions/ANGLE_instanced_arrays.txt
Normal 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
|
@ -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
|
||||
|
@ -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
|
||||
*------------------------------------------------------------------------*/
|
||||
|
@ -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',
|
||||
|
@ -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++)
|
||||
|
@ -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
|
||||
|
@ -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 )
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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',
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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]);
|
||||
|
@ -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.
|
||||
|
151
gfx/angle/src/compiler/preprocessor/lexer_glue.cpp
Normal file
151
gfx/angle/src/compiler/preprocessor/lexer_glue.cpp
Normal 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;
|
||||
}
|
15
gfx/angle/src/compiler/preprocessor/lexer_glue.h
Normal file
15
gfx/angle/src/compiler/preprocessor/lexer_glue.h
Normal 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_
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
36
gfx/angle/src/compiler/preprocessor/new/Lexer.cpp
Normal file
36
gfx/angle/src/compiler/preprocessor/new/Lexer.cpp
Normal 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
|
||||
|
42
gfx/angle/src/compiler/preprocessor/new/Lexer.h
Normal file
42
gfx/angle/src/compiler/preprocessor/new/Lexer.h
Normal 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_
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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_
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
18
gfx/angle/src/compiler/preprocessor/new/pp_utils.h
Normal file
18
gfx/angle/src/compiler/preprocessor/new/pp_utils.h
Normal 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_
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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: ///////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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';
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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++)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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++)
|
||||
|
@ -167,6 +167,9 @@ EXPORTS
|
||||
glEndQueryEXT @169
|
||||
glGetQueryivEXT @170
|
||||
glGetQueryObjectuivEXT @171
|
||||
glVertexAttribDivisorANGLE @172
|
||||
glDrawArraysInstancedANGLE @173
|
||||
glDrawElementsInstancedANGLE @174
|
||||
|
||||
; EGL dependencies
|
||||
glCreateContext @144 NONAME
|
||||
|
44
gfx/angle/tests/build_tests.gyp
Normal file
44
gfx/angle/tests/build_tests.gyp
Normal 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:
|
149
gfx/angle/tests/preprocessor_tests/identifier_test.cpp
Normal file
149
gfx/angle/tests/preprocessor_tests/identifier_test.cpp
Normal 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());
|
||||
}
|
140
gfx/angle/tests/preprocessor_tests/number_test.cpp
Normal file
140
gfx/angle/tests/preprocessor_tests/number_test.cpp
Normal 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");
|
||||
}
|
116
gfx/angle/tests/preprocessor_tests/space_test.cpp
Normal file
116
gfx/angle/tests/preprocessor_tests/space_test.cpp
Normal 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());
|
||||
}
|
89
gfx/angle/tests/preprocessor_tests/token_test.cpp
Normal file
89
gfx/angle/tests/preprocessor_tests/token_test.cpp
Normal 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());
|
||||
}
|
Loading…
Reference in New Issue
Block a user