зеркало из https://github.com/mozilla/pjs.git
b=602396; upgrade ANGLE to r445
This commit is contained in:
Родитель
bfa142f3af
Коммит
f53063a201
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,183 +1,123 @@
|
|||
|
||||
/* A Bison parser, made by GNU Bison 2.4.1. */
|
||||
|
||||
/* 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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
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, 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
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
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
|
||||
/* Put the tokens into the symbol table, so that GDB and other debuggers
|
||||
know about them. */
|
||||
enum yytokentype {
|
||||
INVARIANT = 258,
|
||||
HIGH_PRECISION = 259,
|
||||
MEDIUM_PRECISION = 260,
|
||||
LOW_PRECISION = 261,
|
||||
PRECISION = 262,
|
||||
ATTRIBUTE = 263,
|
||||
CONST_QUAL = 264,
|
||||
BOOL_TYPE = 265,
|
||||
FLOAT_TYPE = 266,
|
||||
INT_TYPE = 267,
|
||||
BREAK = 268,
|
||||
CONTINUE = 269,
|
||||
DO = 270,
|
||||
ELSE = 271,
|
||||
FOR = 272,
|
||||
IF = 273,
|
||||
DISCARD = 274,
|
||||
RETURN = 275,
|
||||
BVEC2 = 276,
|
||||
BVEC3 = 277,
|
||||
BVEC4 = 278,
|
||||
IVEC2 = 279,
|
||||
IVEC3 = 280,
|
||||
IVEC4 = 281,
|
||||
VEC2 = 282,
|
||||
VEC3 = 283,
|
||||
VEC4 = 284,
|
||||
MATRIX2 = 285,
|
||||
MATRIX3 = 286,
|
||||
MATRIX4 = 287,
|
||||
IN_QUAL = 288,
|
||||
OUT_QUAL = 289,
|
||||
INOUT_QUAL = 290,
|
||||
UNIFORM = 291,
|
||||
VARYING = 292,
|
||||
STRUCT = 293,
|
||||
VOID_TYPE = 294,
|
||||
WHILE = 295,
|
||||
SAMPLER2D = 296,
|
||||
SAMPLERCUBE = 297,
|
||||
IDENTIFIER = 298,
|
||||
TYPE_NAME = 299,
|
||||
FLOATCONSTANT = 300,
|
||||
INTCONSTANT = 301,
|
||||
BOOLCONSTANT = 302,
|
||||
FIELD_SELECTION = 303,
|
||||
LEFT_OP = 304,
|
||||
RIGHT_OP = 305,
|
||||
INC_OP = 306,
|
||||
DEC_OP = 307,
|
||||
LE_OP = 308,
|
||||
GE_OP = 309,
|
||||
EQ_OP = 310,
|
||||
NE_OP = 311,
|
||||
AND_OP = 312,
|
||||
OR_OP = 313,
|
||||
XOR_OP = 314,
|
||||
MUL_ASSIGN = 315,
|
||||
DIV_ASSIGN = 316,
|
||||
ADD_ASSIGN = 317,
|
||||
MOD_ASSIGN = 318,
|
||||
LEFT_ASSIGN = 319,
|
||||
RIGHT_ASSIGN = 320,
|
||||
AND_ASSIGN = 321,
|
||||
XOR_ASSIGN = 322,
|
||||
OR_ASSIGN = 323,
|
||||
SUB_ASSIGN = 324,
|
||||
LEFT_PAREN = 325,
|
||||
RIGHT_PAREN = 326,
|
||||
LEFT_BRACKET = 327,
|
||||
RIGHT_BRACKET = 328,
|
||||
LEFT_BRACE = 329,
|
||||
RIGHT_BRACE = 330,
|
||||
DOT = 331,
|
||||
COMMA = 332,
|
||||
COLON = 333,
|
||||
EQUAL = 334,
|
||||
SEMICOLON = 335,
|
||||
BANG = 336,
|
||||
DASH = 337,
|
||||
TILDE = 338,
|
||||
PLUS = 339,
|
||||
STAR = 340,
|
||||
SLASH = 341,
|
||||
PERCENT = 342,
|
||||
LEFT_ANGLE = 343,
|
||||
RIGHT_ANGLE = 344,
|
||||
VERTICAL_BAR = 345,
|
||||
CARET = 346,
|
||||
AMPERSAND = 347,
|
||||
QUESTION = 348
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
typedef union YYSTYPE
|
||||
{
|
||||
|
||||
|
||||
struct {
|
||||
TSourceLoc line;
|
||||
union {
|
||||
TString *string;
|
||||
float f;
|
||||
int i;
|
||||
bool b;
|
||||
};
|
||||
TSymbol* symbol;
|
||||
} lex;
|
||||
struct {
|
||||
TSourceLoc line;
|
||||
TOperator op;
|
||||
union {
|
||||
TIntermNode* intermNode;
|
||||
TIntermNodePair nodePair;
|
||||
TIntermTyped* intermTypedNode;
|
||||
TIntermAggregate* intermAggregate;
|
||||
};
|
||||
union {
|
||||
TPublicType type;
|
||||
TPrecision precision;
|
||||
TQualifier qualifier;
|
||||
TFunction* function;
|
||||
TParameter param;
|
||||
TTypeLine typeLine;
|
||||
TTypeList* typeList;
|
||||
};
|
||||
} interm;
|
||||
|
||||
|
||||
|
||||
} YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
TSourceLoc line;
|
||||
union {
|
||||
TString *string;
|
||||
float f;
|
||||
int i;
|
||||
bool b;
|
||||
};
|
||||
TSymbol* symbol;
|
||||
} lex;
|
||||
struct {
|
||||
TSourceLoc line;
|
||||
TOperator op;
|
||||
union {
|
||||
TIntermNode* intermNode;
|
||||
TIntermNodePair nodePair;
|
||||
TIntermTyped* intermTypedNode;
|
||||
TIntermAggregate* intermAggregate;
|
||||
};
|
||||
union {
|
||||
TPublicType type;
|
||||
TPrecision precision;
|
||||
TQualifier qualifier;
|
||||
TFunction* function;
|
||||
TParameter param;
|
||||
TTypeLine typeLine;
|
||||
TTypeList* typeList;
|
||||
};
|
||||
} interm;
|
||||
} YYSTYPE;
|
||||
#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 IDENTIFIER 298
|
||||
#define TYPE_NAME 299
|
||||
#define FLOATCONSTANT 300
|
||||
#define INTCONSTANT 301
|
||||
#define BOOLCONSTANT 302
|
||||
#define FIELD_SELECTION 303
|
||||
#define LEFT_OP 304
|
||||
#define RIGHT_OP 305
|
||||
#define INC_OP 306
|
||||
#define DEC_OP 307
|
||||
#define LE_OP 308
|
||||
#define GE_OP 309
|
||||
#define EQ_OP 310
|
||||
#define NE_OP 311
|
||||
#define AND_OP 312
|
||||
#define OR_OP 313
|
||||
#define XOR_OP 314
|
||||
#define MUL_ASSIGN 315
|
||||
#define DIV_ASSIGN 316
|
||||
#define ADD_ASSIGN 317
|
||||
#define MOD_ASSIGN 318
|
||||
#define LEFT_ASSIGN 319
|
||||
#define RIGHT_ASSIGN 320
|
||||
#define AND_ASSIGN 321
|
||||
#define XOR_ASSIGN 322
|
||||
#define OR_ASSIGN 323
|
||||
#define SUB_ASSIGN 324
|
||||
#define LEFT_PAREN 325
|
||||
#define RIGHT_PAREN 326
|
||||
#define LEFT_BRACKET 327
|
||||
#define RIGHT_BRACKET 328
|
||||
#define LEFT_BRACE 329
|
||||
#define RIGHT_BRACE 330
|
||||
#define DOT 331
|
||||
#define COMMA 332
|
||||
#define COLON 333
|
||||
#define EQUAL 334
|
||||
#define SEMICOLON 335
|
||||
#define BANG 336
|
||||
#define DASH 337
|
||||
#define TILDE 338
|
||||
#define PLUS 339
|
||||
#define STAR 340
|
||||
#define SLASH 341
|
||||
#define PERCENT 342
|
||||
#define LEFT_ANGLE 343
|
||||
#define RIGHT_ANGLE 344
|
||||
#define VERTICAL_BAR 345
|
||||
#define CARET 346
|
||||
#define AMPERSAND 347
|
||||
#define QUESTION 348
|
||||
|
||||
|
|
|
@ -222,6 +222,12 @@ typedef void* GLeglImageOES;
|
|||
#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368
|
||||
#endif
|
||||
|
||||
/* GL_EXT_texture_compression_dxt1 */
|
||||
#ifndef GL_EXT_texture_compression_dxt1
|
||||
#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
|
||||
#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* IMG extension tokens
|
||||
*------------------------------------------------------------------------*/
|
||||
|
@ -350,6 +356,25 @@ typedef void* GLeglImageOES;
|
|||
#define GL_MULTISAMPLE_BUFFER_BIT7_QCOM 0x80000000
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* ANGLE extension tokens
|
||||
*------------------------------------------------------------------------*/
|
||||
|
||||
/* GL_ANGLE_framebuffer_blit */
|
||||
#ifndef GL_ANGLE_framebuffer_blit
|
||||
#define GL_READ_FRAMEBUFFER_ANGLE 0x8CA8
|
||||
#define GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9
|
||||
#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6 // alias GL_FRAMEBUFFER_BINDING
|
||||
#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA
|
||||
#endif
|
||||
|
||||
/* GL_ANGLE_framebuffer_multisample */
|
||||
#ifndef GL_ANGLE_framebuffer_multisample
|
||||
#define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56
|
||||
#define GL_MAX_SAMPLES_ANGLE 0x8D57
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* End of extension tokens, start of corresponding extension functions
|
||||
*------------------------------------------------------------------------*/
|
||||
|
@ -623,6 +648,11 @@ typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GL
|
|||
#define GL_EXT_texture_type_2_10_10_10_REV 1
|
||||
#endif
|
||||
|
||||
/* GL_EXT_texture_compression_dxt1 */
|
||||
#ifndef GL_EXT_texture_compression_dxt1
|
||||
#define GL_EXT_texture_compression_dxt1 1
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* IMG extension functions
|
||||
*------------------------------------------------------------------------*/
|
||||
|
@ -766,6 +796,34 @@ typedef void (GL_APIENTRYP PFNGLSTARTTILINGQCOMPROC) (GLuint x, GLuint y, GLuint
|
|||
typedef void (GL_APIENTRYP PFNGLENDTILINGQCOMPROC) (GLbitfield preserveMask);
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* ANGLE extension functions
|
||||
*------------------------------------------------------------------------*/
|
||||
|
||||
/* GL_ANGLE_framebuffer_blit */
|
||||
#ifndef GL_ANGLE_framebuffer_blit
|
||||
#define GL_ANGLE_framebuffer_blit 1
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GL_APICALL void GL_APIENTRY glBlitFramebufferANGLE (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
|
||||
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
|
||||
GLbitfield mask, GLenum filter);
|
||||
#endif
|
||||
typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERANGLEPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
|
||||
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
|
||||
GLbitfield mask, GLenum filter);
|
||||
#endif
|
||||
|
||||
/* GL_ANGLE_framebuffer_multisample */
|
||||
#ifndef GL_ANGLE_framebuffer_multisample
|
||||
#define GL_ANGLE_framebuffer_multisample 1
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleANGLE (GLenum target, GLsizei samples, GLenum internalformat,
|
||||
GLsizei width, GLsizei height);
|
||||
#endif
|
||||
typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat,
|
||||
GLsizei width, GLsizei height);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef _RESOURCE_LIMITS_INCLUDED_
|
||||
#define _RESOURCE_LIMITS_INCLUDED_
|
||||
|
||||
struct TBuiltInResource
|
||||
{
|
||||
int maxVertexAttribs;
|
||||
int maxVertexUniformVectors;
|
||||
int maxVaryingVectors;
|
||||
int maxVertexTextureImageUnits;
|
||||
int maxCombinedTextureImageUnits;
|
||||
int maxTextureImageUnits;
|
||||
int maxFragmentUniformVectors;
|
||||
int maxDrawBuffers;
|
||||
};
|
||||
#endif // _RESOURCE_LIMITS_INCLUDED_
|
|
@ -6,24 +6,6 @@
|
|||
#ifndef _COMPILER_INTERFACE_INCLUDED_
|
||||
#define _COMPILER_INTERFACE_INCLUDED_
|
||||
|
||||
#include "nscore.h"
|
||||
|
||||
#include "ResourceLimits.h"
|
||||
|
||||
#ifdef WIN32
|
||||
# if !defined(MOZ_ENABLE_LIBXUL) && !defined(MOZ_STATIC_BUILD)
|
||||
# ifdef ANGLE_BUILD
|
||||
# define ANGLE_API NS_EXPORT
|
||||
# else
|
||||
# define ANGLE_API NS_IMPORT
|
||||
# endif
|
||||
# else
|
||||
# define ANGLE_API /*nothing*/
|
||||
# endif
|
||||
#else
|
||||
# define ANGLE_API NS_EXTERNAL_VIS
|
||||
#endif
|
||||
|
||||
//
|
||||
// This is the platform independent interface between an OGL driver
|
||||
// and the shading language compiler.
|
||||
|
@ -32,47 +14,100 @@
|
|||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Version number for shader translation API.
|
||||
// It is incremented everytime the API changes.
|
||||
#define SH_VERSION 101
|
||||
|
||||
//
|
||||
// The names of the following enums have been derived by replacing GL prefix
|
||||
// with SH. For example, SH_INFO_LOG_LENGTH is equivalent to GL_INFO_LOG_LENGTH.
|
||||
// The enum values are also equal to the values of their GL counterpart. This
|
||||
// is done to make it easier for applications to use the shader library.
|
||||
//
|
||||
typedef enum {
|
||||
SH_FRAGMENT_SHADER = 0x8B30,
|
||||
SH_VERTEX_SHADER = 0x8B31
|
||||
} ShShaderType;
|
||||
|
||||
typedef enum {
|
||||
SH_GLES2_SPEC = 0x8B40,
|
||||
SH_WEBGL_SPEC = 0x8B41
|
||||
} ShShaderSpec;
|
||||
|
||||
typedef enum {
|
||||
SH_NONE = 0,
|
||||
SH_INT = 0x1404,
|
||||
SH_FLOAT = 0x1406,
|
||||
SH_FLOAT_VEC2 = 0x8B50,
|
||||
SH_FLOAT_VEC3 = 0x8B51,
|
||||
SH_FLOAT_VEC4 = 0x8B52,
|
||||
SH_INT_VEC2 = 0x8B53,
|
||||
SH_INT_VEC3 = 0x8B54,
|
||||
SH_INT_VEC4 = 0x8B55,
|
||||
SH_BOOL = 0x8B56,
|
||||
SH_BOOL_VEC2 = 0x8B57,
|
||||
SH_BOOL_VEC3 = 0x8B58,
|
||||
SH_BOOL_VEC4 = 0x8B59,
|
||||
SH_FLOAT_MAT2 = 0x8B5A,
|
||||
SH_FLOAT_MAT3 = 0x8B5B,
|
||||
SH_FLOAT_MAT4 = 0x8B5C,
|
||||
SH_SAMPLER_2D = 0x8B5E,
|
||||
SH_SAMPLER_CUBE = 0x8B60
|
||||
} ShDataType;
|
||||
|
||||
typedef enum {
|
||||
SH_INFO_LOG_LENGTH = 0x8B84,
|
||||
SH_OBJECT_CODE_LENGTH = 0x8B88, // GL_SHADER_SOURCE_LENGTH
|
||||
SH_ACTIVE_UNIFORMS = 0x8B86,
|
||||
SH_ACTIVE_UNIFORM_MAX_LENGTH = 0x8B87,
|
||||
SH_ACTIVE_ATTRIBUTES = 0x8B89,
|
||||
SH_ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A
|
||||
} ShShaderInfo;
|
||||
|
||||
// Compile options.
|
||||
typedef enum {
|
||||
SH_VALIDATE = 0,
|
||||
SH_INTERMEDIATE_TREE = 0x001,
|
||||
SH_OBJECT_CODE = 0x002,
|
||||
SH_ATTRIBUTES_UNIFORMS = 0x004
|
||||
} ShCompileOptions;
|
||||
|
||||
//
|
||||
// Driver must call this first, once, before doing any other
|
||||
// compiler operations.
|
||||
//
|
||||
ANGLE_API int ShInitialize();
|
||||
int ShInitialize();
|
||||
//
|
||||
// Driver should call this at shutdown.
|
||||
//
|
||||
ANGLE_API int ShFinalize();
|
||||
//
|
||||
// Types of languages the compiler can consume.
|
||||
//
|
||||
typedef enum {
|
||||
EShLangVertex,
|
||||
EShLangFragment,
|
||||
EShLangCount
|
||||
} EShLanguage;
|
||||
int ShFinalize();
|
||||
|
||||
//
|
||||
// The language specification compiler conforms to.
|
||||
// It currently supports OpenGL ES and WebGL specifications.
|
||||
// Implementation dependent built-in resources (constants and extensions).
|
||||
// The names for these resources has been obtained by stripping gl_/GL_.
|
||||
//
|
||||
typedef enum {
|
||||
EShSpecGLES2,
|
||||
EShSpecWebGL
|
||||
} EShSpec;
|
||||
typedef struct
|
||||
{
|
||||
// Constants.
|
||||
int MaxVertexAttribs;
|
||||
int MaxVertexUniformVectors;
|
||||
int MaxVaryingVectors;
|
||||
int MaxVertexTextureImageUnits;
|
||||
int MaxCombinedTextureImageUnits;
|
||||
int MaxTextureImageUnits;
|
||||
int MaxFragmentUniformVectors;
|
||||
int MaxDrawBuffers;
|
||||
|
||||
// Extensions.
|
||||
// Set to 1 to enable the extension, else 0.
|
||||
int OES_standard_derivatives;
|
||||
} ShBuiltInResources;
|
||||
|
||||
//
|
||||
// Optimization level for the compiler.
|
||||
// Initialize built-in resources with minimum expected values.
|
||||
//
|
||||
typedef enum {
|
||||
EShOptNoGeneration,
|
||||
EShOptNone,
|
||||
EShOptSimple, // Optimizations that can be done quickly
|
||||
EShOptFull // Optimizations that will take more time
|
||||
} EShOptimizationLevel;
|
||||
|
||||
enum TDebugOptions {
|
||||
EDebugOpNone = 0x000,
|
||||
EDebugOpIntermediate = 0x001 // Writes intermediate tree into info-log.
|
||||
};
|
||||
void ShInitBuiltInResources(ShBuiltInResources* resources);
|
||||
|
||||
//
|
||||
// ShHandle held by but opaque to the driver. It is allocated,
|
||||
|
@ -86,30 +121,123 @@ typedef void* ShHandle;
|
|||
//
|
||||
// Driver calls these to create and destroy compiler objects.
|
||||
//
|
||||
ANGLE_API ShHandle ShConstructCompiler(EShLanguage, EShSpec, const TBuiltInResource*);
|
||||
ANGLE_API void ShDestruct(ShHandle);
|
||||
// Returns the handle of constructed compiler.
|
||||
// Parameters:
|
||||
// type: Specifies the type of shader - SH_FRAGMENT_SHADER or SH_VERTEX_SHADER.
|
||||
// spec: Specifies the language spec the compiler must conform to -
|
||||
// SH_GLES2_SPEC or SH_WEBGL_SPEC.
|
||||
// resources: Specifies the built-in resources.
|
||||
ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec,
|
||||
const ShBuiltInResources* resources);
|
||||
void ShDestruct(ShHandle handle);
|
||||
|
||||
//
|
||||
// The return value of ShCompile is boolean, indicating
|
||||
// success or failure.
|
||||
// Compiles the given shader source.
|
||||
// If the function succeeds, the return value is nonzero, else zero.
|
||||
// Parameters:
|
||||
// handle: Specifies the handle of compiler to be used.
|
||||
// shaderStrings: Specifies an array of pointers to null-terminated strings
|
||||
// containing the shader source code.
|
||||
// numStrings: Specifies the number of elements in shaderStrings array.
|
||||
// compileOptions: A mask containing the following parameters:
|
||||
// SH_VALIDATE: Performs validations only.
|
||||
// SH_INTERMEDIATE_TREE: Writes intermediate tree to info log.
|
||||
// Can be queried by calling ShGetInfoLog().
|
||||
// SH_OBJECT_CODE: Translates intermediate tree to glsl or hlsl shader.
|
||||
// Can be queried by calling ShGetObjectCode().
|
||||
// SH_ATTRIBUTES_UNIFORMS: Extracts attributes and uniforms.
|
||||
// Can be queried by calling ShGetActiveAttrib() and
|
||||
// ShGetActiveUniform().
|
||||
//
|
||||
// The info-log should be written by ShCompile into
|
||||
// ShHandle, so it can answer future queries.
|
||||
//
|
||||
ANGLE_API int ShCompile(
|
||||
const ShHandle,
|
||||
int ShCompile(
|
||||
const ShHandle handle,
|
||||
const char* const shaderStrings[],
|
||||
const int numStrings,
|
||||
const EShOptimizationLevel,
|
||||
int debugOptions
|
||||
int compileOptions
|
||||
);
|
||||
|
||||
//
|
||||
// All the following return 0 if the information is not
|
||||
// available in the object passed down, or the object is bad.
|
||||
//
|
||||
ANGLE_API const char* ShGetInfoLog(const ShHandle);
|
||||
ANGLE_API const char* ShGetObjectCode(const ShHandle);
|
||||
// Returns a parameter from a compiled shader.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
// pname: Specifies the parameter to query.
|
||||
// The following parameters are defined:
|
||||
// SH_INFO_LOG_LENGTH: the number of characters in the information log
|
||||
// including the null termination character.
|
||||
// SH_OBJECT_CODE_LENGTH: the number of characters in the object code
|
||||
// including the null termination character.
|
||||
// SH_ACTIVE_ATTRIBUTES: the number of active attribute variables.
|
||||
// SH_ACTIVE_ATTRIBUTE_MAX_LENGTH: the length of the longest active attribute
|
||||
// variable name including the null
|
||||
// termination character.
|
||||
// SH_ACTIVE_UNIFORMS: the number of active uniform variables.
|
||||
// SH_ACTIVE_UNIFORM_MAX_LENGTH: the length of the longest active uniform
|
||||
// variable name including the null
|
||||
// termination character.
|
||||
//
|
||||
// params: Requested parameter
|
||||
void ShGetInfo(const ShHandle handle, ShShaderInfo pname, int* params);
|
||||
|
||||
// Returns nul-terminated information log for a compiled shader.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
// infoLog: Specifies an array of characters that is used to return
|
||||
// the information log. It is assumed that infoLog has enough memory
|
||||
// to accomodate the information log. The size of the buffer required
|
||||
// to store the returned information log can be obtained by calling
|
||||
// ShGetInfo with SH_INFO_LOG_LENGTH.
|
||||
void ShGetInfoLog(const ShHandle handle, char* infoLog);
|
||||
|
||||
// Returns null-terminated object code for a compiled shader.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
// infoLog: Specifies an array of characters that is used to return
|
||||
// the object code. It is assumed that infoLog has enough memory to
|
||||
// accomodate the object code. The size of the buffer required to
|
||||
// store the returned object code can be obtained by calling
|
||||
// ShGetInfo with SH_OBJECT_CODE_LENGTH.
|
||||
void ShGetObjectCode(const ShHandle handle, char* objCode);
|
||||
|
||||
// Returns information about an active attribute variable.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
// index: Specifies the index of the attribute variable to be queried.
|
||||
// length: Returns the number of characters actually written in the string
|
||||
// indicated by name (excluding the null terminator) if a value other
|
||||
// than NULL is passed.
|
||||
// size: Returns the size of the attribute variable.
|
||||
// type: Returns the data type of the attribute variable.
|
||||
// name: Returns a null terminated string containing the name of the
|
||||
// attribute variable. It is assumed that name has enough memory to
|
||||
// accomodate the attribute variable name. The size of the buffer
|
||||
// required to store the attribute variable name can be obtained by
|
||||
// calling ShGetInfo with SH_ACTIVE_ATTRIBUTE_MAX_LENGTH.
|
||||
void ShGetActiveAttrib(const ShHandle handle,
|
||||
int index,
|
||||
int* length,
|
||||
int* size,
|
||||
ShDataType* type,
|
||||
char* name);
|
||||
|
||||
// Returns information about an active uniform variable.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
// index: Specifies the index of the uniform variable to be queried.
|
||||
// length: Returns the number of characters actually written in the string
|
||||
// indicated by name (excluding the null terminator) if a value
|
||||
// other than NULL is passed.
|
||||
// size: Returns the size of the uniform variable.
|
||||
// type: Returns the data type of the uniform variable.
|
||||
// name: Returns a null terminated string containing the name of the
|
||||
// uniform variable. It is assumed that name has enough memory to
|
||||
// accomodate the uniform variable name. The size of the buffer required
|
||||
// to store the uniform variable name can be obtained by calling
|
||||
// ShGetInfo with SH_ACTIVE_UNIFORMS_MAX_LENGTH.
|
||||
void ShGetActiveUniform(const ShHandle handle,
|
||||
int index,
|
||||
int* length,
|
||||
int* size,
|
||||
ShDataType* type,
|
||||
char* name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -3,6 +3,11 @@
|
|||
# found in the LICENSE file.
|
||||
|
||||
{
|
||||
'target_defaults': {
|
||||
'defines': [
|
||||
'TRACE_OUTPUT_FILE="angle-debug.txt"',
|
||||
],
|
||||
},
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'translator_common',
|
||||
|
@ -19,6 +24,7 @@
|
|||
'sources': [
|
||||
'compiler/BaseTypes.h',
|
||||
'compiler/Common.h',
|
||||
'compiler/Compiler.cpp',
|
||||
'compiler/ConstantUnion.h',
|
||||
'compiler/debug.cpp',
|
||||
'compiler/debug.h',
|
||||
|
@ -52,6 +58,8 @@
|
|||
'compiler/SymbolTable.h',
|
||||
'compiler/Types.h',
|
||||
'compiler/unistd.h',
|
||||
'compiler/VariableInfo.cpp',
|
||||
'compiler/VariableInfo.h',
|
||||
'compiler/preprocessor/atom.c',
|
||||
'compiler/preprocessor/atom.h',
|
||||
'compiler/preprocessor/compile.h',
|
||||
|
@ -177,6 +185,8 @@
|
|||
'libGLESv2/Buffer.h',
|
||||
'libGLESv2/Context.cpp',
|
||||
'libGLESv2/Context.h',
|
||||
'libGLESv2/Fence.cpp',
|
||||
'libGLESv2/Fence.h',
|
||||
'libGLESv2/Framebuffer.cpp',
|
||||
'libGLESv2/Framebuffer.h',
|
||||
'libGLESv2/libGLESv2.cpp',
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifndef TRACE_OUTPUT_FILE
|
||||
#define TRACE_OUTPUT_FILE "debug.txt"
|
||||
#endif
|
||||
|
||||
static bool trace_on = true;
|
||||
|
||||
namespace gl
|
||||
|
@ -21,7 +25,7 @@ void trace(const char *format, ...)
|
|||
{
|
||||
if (format)
|
||||
{
|
||||
FILE *file = fopen("debug.txt", "a");
|
||||
FILE *file = fopen(TRACE_OUTPUT_FILE, "a");
|
||||
|
||||
if (file)
|
||||
{
|
||||
|
|
|
@ -51,6 +51,21 @@ enum TBasicType
|
|||
EbtAddress, // should be deprecated??
|
||||
};
|
||||
|
||||
inline const char* getBasicString(TBasicType t)
|
||||
{
|
||||
switch (t)
|
||||
{
|
||||
case EbtVoid: return "void"; break;
|
||||
case EbtFloat: return "float"; break;
|
||||
case EbtInt: return "int"; break;
|
||||
case EbtBool: return "bool"; break;
|
||||
case EbtSampler2D: return "sampler2D"; break;
|
||||
case EbtSamplerCube: return "samplerCube"; break;
|
||||
case EbtStruct: return "structure"; break;
|
||||
default: return "unknown type";
|
||||
}
|
||||
}
|
||||
|
||||
inline bool IsSampler(TBasicType type)
|
||||
{
|
||||
return type > EbtGuardSamplerBegin && type < EbtGuardSamplerEnd;
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
// compile object used by higher level code. It returns
|
||||
// a subclass of TCompiler.
|
||||
//
|
||||
TCompiler* ConstructCompiler(EShLanguage language, EShSpec spec)
|
||||
TCompiler* ConstructCompiler(ShShaderType type, ShShaderSpec spec)
|
||||
{
|
||||
return new TranslatorGLSL(language, spec);
|
||||
return new TranslatorGLSL(type, spec);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
// compile object used by higher level code. It returns
|
||||
// a subclass of TCompiler.
|
||||
//
|
||||
TCompiler* ConstructCompiler(EShLanguage language, EShSpec spec)
|
||||
TCompiler* ConstructCompiler(ShShaderType type, ShShaderSpec spec)
|
||||
{
|
||||
return new TranslatorHLSL(language, spec);
|
||||
return new TranslatorHLSL(type, spec);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -71,6 +71,4 @@ public:
|
|||
TMap(const tAllocator& a) : std::map<K, D, CMP, tAllocator>(std::map<K, D, CMP, tAllocator>::key_compare(), a) {}
|
||||
};
|
||||
|
||||
typedef TMap<TString, TString> TPragmaTable;
|
||||
|
||||
#endif // _COMMON_INCLUDED_
|
||||
|
|
|
@ -0,0 +1,168 @@
|
|||
//
|
||||
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#include "compiler/Initialize.h"
|
||||
#include "compiler/ParseHelper.h"
|
||||
#include "compiler/ShHandle.h"
|
||||
|
||||
static bool InitializeSymbolTable(
|
||||
const TBuiltInStrings& builtInStrings,
|
||||
ShShaderType type, ShShaderSpec spec, const ShBuiltInResources& resources,
|
||||
TInfoSink& infoSink, TSymbolTable& symbolTable)
|
||||
{
|
||||
TIntermediate intermediate(infoSink);
|
||||
TExtensionBehavior extBehavior;
|
||||
TParseContext parseContext(symbolTable, extBehavior, intermediate, type, spec, infoSink);
|
||||
|
||||
GlobalParseContext = &parseContext;
|
||||
|
||||
setInitialState();
|
||||
|
||||
assert(symbolTable.isEmpty());
|
||||
//
|
||||
// Parse the built-ins. This should only happen once per
|
||||
// language symbol table.
|
||||
//
|
||||
// Push the symbol table to give it an initial scope. This
|
||||
// push should not have a corresponding pop, so that built-ins
|
||||
// are preserved, and the test for an empty table fails.
|
||||
//
|
||||
symbolTable.push();
|
||||
|
||||
//Initialize the Preprocessor
|
||||
if (InitPreprocessor())
|
||||
{
|
||||
infoSink.info.message(EPrefixInternalError, "Unable to intialize the Preprocessor");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (TBuiltInStrings::const_iterator i = builtInStrings.begin(); i != builtInStrings.end(); ++i)
|
||||
{
|
||||
const char* builtInShaders = i->c_str();
|
||||
int builtInLengths = static_cast<int>(i->size());
|
||||
if (builtInLengths <= 0)
|
||||
continue;
|
||||
|
||||
if (PaParseStrings(&builtInShaders, &builtInLengths, 1, parseContext) != 0)
|
||||
{
|
||||
infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
IdentifyBuiltIns(type, spec, resources, symbolTable);
|
||||
|
||||
FinalizePreprocessor();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void DefineExtensionMacros(const TExtensionBehavior& extBehavior)
|
||||
{
|
||||
for (TExtensionBehavior::const_iterator iter = extBehavior.begin();
|
||||
iter != extBehavior.end(); ++iter) {
|
||||
PredefineIntMacro(iter->first.c_str(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
TCompiler::TCompiler(ShShaderType type, ShShaderSpec spec)
|
||||
: shaderType(type),
|
||||
shaderSpec(spec)
|
||||
{
|
||||
}
|
||||
|
||||
TCompiler::~TCompiler()
|
||||
{
|
||||
}
|
||||
|
||||
bool TCompiler::Init(const ShBuiltInResources& resources)
|
||||
{
|
||||
// Generate built-in symbol table.
|
||||
if (!InitBuiltInSymbolTable(resources))
|
||||
return false;
|
||||
|
||||
InitExtensionBehavior(resources, extensionBehavior);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TCompiler::compile(const char* const shaderStrings[],
|
||||
const int numStrings,
|
||||
int compileOptions)
|
||||
{
|
||||
clearResults();
|
||||
|
||||
if (numStrings == 0)
|
||||
return true;
|
||||
|
||||
TIntermediate intermediate(infoSink);
|
||||
TParseContext parseContext(symbolTable, extensionBehavior, intermediate,
|
||||
shaderType, shaderSpec, infoSink);
|
||||
GlobalParseContext = &parseContext;
|
||||
setInitialState();
|
||||
|
||||
// Initialize preprocessor.
|
||||
InitPreprocessor();
|
||||
DefineExtensionMacros(extensionBehavior);
|
||||
|
||||
// We preserve symbols at the built-in level from compile-to-compile.
|
||||
// Start pushing the user-defined symbols at global level.
|
||||
symbolTable.push();
|
||||
if (!symbolTable.atGlobalLevel())
|
||||
infoSink.info.message(EPrefixInternalError, "Wrong symbol table level");
|
||||
|
||||
// Parse shader.
|
||||
bool success =
|
||||
(PaParseStrings(shaderStrings, 0, numStrings, parseContext) == 0) &&
|
||||
(parseContext.treeRoot != NULL);
|
||||
if (success) {
|
||||
success = intermediate.postProcess(parseContext.treeRoot);
|
||||
|
||||
if (success && (compileOptions & SH_INTERMEDIATE_TREE))
|
||||
intermediate.outputTree(parseContext.treeRoot);
|
||||
|
||||
if (success && (compileOptions & SH_OBJECT_CODE))
|
||||
translate(parseContext.treeRoot);
|
||||
|
||||
if (success && (compileOptions & SH_ATTRIBUTES_UNIFORMS))
|
||||
collectAttribsUniforms(parseContext.treeRoot);
|
||||
}
|
||||
|
||||
// Cleanup memory.
|
||||
intermediate.remove(parseContext.treeRoot);
|
||||
// Ensure symbol table is returned to the built-in level,
|
||||
// throwing away all but the built-ins.
|
||||
while (!symbolTable.atBuiltInLevel())
|
||||
symbolTable.pop();
|
||||
FinalizePreprocessor();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources& resources)
|
||||
{
|
||||
TBuiltIns builtIns;
|
||||
|
||||
builtIns.initialize(shaderType, shaderSpec, resources);
|
||||
return InitializeSymbolTable(builtIns.getBuiltInStrings(),
|
||||
shaderType, shaderSpec, resources, infoSink, symbolTable);
|
||||
}
|
||||
|
||||
void TCompiler::clearResults()
|
||||
{
|
||||
infoSink.info.erase();
|
||||
infoSink.obj.erase();
|
||||
infoSink.debug.erase();
|
||||
|
||||
attribs.clear();
|
||||
uniforms.clear();
|
||||
}
|
||||
|
||||
void TCompiler::collectAttribsUniforms(TIntermNode* root)
|
||||
{
|
||||
CollectAttribsUniforms collect(attribs, uniforms);
|
||||
root->traverse(&collect);
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
//
|
||||
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef _EXTENSION_BEHAVIOR_INCLUDED_
|
||||
#define _EXTENSION_BEHAVIOR_INCLUDED_
|
||||
|
||||
#include "compiler/Common.h"
|
||||
|
||||
typedef enum {
|
||||
EBhRequire,
|
||||
EBhEnable,
|
||||
EBhWarn,
|
||||
EBhDisable
|
||||
} TBehavior;
|
||||
|
||||
typedef TMap<TString, TBehavior> TExtensionBehavior;
|
||||
|
||||
#endif // _EXTENSION_TABLE_INCLUDED_
|
|
@ -91,6 +91,7 @@ public:
|
|||
}
|
||||
|
||||
void erase() { sink.clear(); }
|
||||
int size() { return static_cast<int>(sink.size()); }
|
||||
|
||||
const TPersistString& str() const { return sink; }
|
||||
const char* c_str() const { return sink.c_str(); }
|
||||
|
|
|
@ -310,15 +310,6 @@ static TString BuiltInFunctionsCommon()
|
|||
s.append(TString("bvec3 not(bvec3 x);"));
|
||||
s.append(TString("bvec4 not(bvec4 x);"));
|
||||
|
||||
//
|
||||
// Texture Functions.
|
||||
//
|
||||
s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord);"));
|
||||
s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord);"));
|
||||
s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord);"));
|
||||
|
||||
s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord);"));
|
||||
|
||||
//
|
||||
// Noise functions.
|
||||
//
|
||||
|
@ -342,7 +333,6 @@ static TString BuiltInFunctionsCommon()
|
|||
//s.append(TString("vec4 noise4(vec3 x);"));
|
||||
//s.append(TString("vec4 noise4(vec4 x);"));
|
||||
|
||||
s.append(TString("\n"));
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -351,7 +341,7 @@ static TString BuiltInFunctionsCommon()
|
|||
// Prototypes for built-in functions seen by vertex shaders only.
|
||||
//
|
||||
//============================================================================
|
||||
static TString BuiltInFunctionsVertex()
|
||||
static TString BuiltInFunctionsVertex(const ShBuiltInResources& resources)
|
||||
{
|
||||
TString s;
|
||||
|
||||
|
@ -363,12 +353,18 @@ static TString BuiltInFunctionsVertex()
|
|||
//
|
||||
// Texture Functions.
|
||||
//
|
||||
s.append(TString("vec4 texture2DLod(sampler2D sampler, vec2 coord, float lod);"));
|
||||
s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec3 coord, float lod);"));
|
||||
s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec4 coord, float lod);"));
|
||||
s.append(TString("vec4 textureCubeLod(samplerCube sampler, vec3 coord, float lod);"));
|
||||
if (resources.MaxVertexTextureImageUnits > 0) {
|
||||
s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord);"));
|
||||
s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord);"));
|
||||
s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord);"));
|
||||
s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord);"));
|
||||
|
||||
s.append(TString("vec4 texture2DLod(sampler2D sampler, vec2 coord, float lod);"));
|
||||
s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec3 coord, float lod);"));
|
||||
s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec4 coord, float lod);"));
|
||||
s.append(TString("vec4 textureCubeLod(samplerCube sampler, vec3 coord, float lod);"));
|
||||
}
|
||||
|
||||
s.append(TString("\n"));
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -377,34 +373,40 @@ static TString BuiltInFunctionsVertex()
|
|||
// Prototypes for built-in functions seen by fragment shaders only.
|
||||
//
|
||||
//============================================================================
|
||||
static TString BuiltInFunctionsFragment()
|
||||
static TString BuiltInFunctionsFragment(const ShBuiltInResources& resources)
|
||||
{
|
||||
TString s;
|
||||
|
||||
//
|
||||
// Texture Functions.
|
||||
//
|
||||
s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord);"));
|
||||
s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord);"));
|
||||
s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord);"));
|
||||
s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord);"));
|
||||
|
||||
s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord, float bias);"));
|
||||
s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord, float bias);"));
|
||||
s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord, float bias);"));
|
||||
s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord, float bias);"));
|
||||
|
||||
//s.append(TString("float dFdx(float p);"));
|
||||
//s.append(TString("vec2 dFdx(vec2 p);"));
|
||||
//s.append(TString("vec3 dFdx(vec3 p);"));
|
||||
//s.append(TString("vec4 dFdx(vec4 p);"));
|
||||
if (resources.OES_standard_derivatives) {
|
||||
s.append(TString("float dFdx(float p);"));
|
||||
s.append(TString("vec2 dFdx(vec2 p);"));
|
||||
s.append(TString("vec3 dFdx(vec3 p);"));
|
||||
s.append(TString("vec4 dFdx(vec4 p);"));
|
||||
|
||||
//s.append(TString("float dFdy(float p);"));
|
||||
//s.append(TString("vec2 dFdy(vec2 p);"));
|
||||
//s.append(TString("vec3 dFdy(vec3 p);"));
|
||||
//s.append(TString("vec4 dFdy(vec4 p);"));
|
||||
s.append(TString("float dFdy(float p);"));
|
||||
s.append(TString("vec2 dFdy(vec2 p);"));
|
||||
s.append(TString("vec3 dFdy(vec3 p);"));
|
||||
s.append(TString("vec4 dFdy(vec4 p);"));
|
||||
|
||||
s.append(TString("float fwidth(float p);"));
|
||||
s.append(TString("vec2 fwidth(vec2 p);"));
|
||||
s.append(TString("vec3 fwidth(vec3 p);"));
|
||||
s.append(TString("vec4 fwidth(vec4 p);"));
|
||||
s.append(TString("float fwidth(float p);"));
|
||||
s.append(TString("vec2 fwidth(vec2 p);"));
|
||||
s.append(TString("vec3 fwidth(vec3 p);"));
|
||||
s.append(TString("vec4 fwidth(vec4 p);"));
|
||||
}
|
||||
|
||||
s.append(TString("\n"));
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -427,7 +429,6 @@ static TString StandardUniforms()
|
|||
s.append(TString("};"));
|
||||
s.append(TString("uniform gl_DepthRangeParameters gl_DepthRange;"));
|
||||
|
||||
s.append(TString("\n"));
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -443,7 +444,6 @@ static TString DefaultPrecisionVertex()
|
|||
s.append(TString("precision highp int;"));
|
||||
s.append(TString("precision highp float;"));
|
||||
|
||||
s.append(TString("\n"));
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -459,7 +459,6 @@ static TString DefaultPrecisionFragment()
|
|||
s.append(TString("precision mediump int;"));
|
||||
// No default precision for float in fragment shaders
|
||||
|
||||
s.append(TString("\n"));
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -468,37 +467,38 @@ static TString DefaultPrecisionFragment()
|
|||
// Implementation dependent built-in constants.
|
||||
//
|
||||
//============================================================================
|
||||
static TString BuiltInConstants(const TBuiltInResource &resources)
|
||||
static TString BuiltInConstants(const ShBuiltInResources &resources)
|
||||
{
|
||||
TStringStream s;
|
||||
|
||||
s << "const int gl_MaxVertexAttribs = " << resources.maxVertexAttribs << ";";
|
||||
s << "const int gl_MaxVertexUniformVectors = " << resources.maxVertexUniformVectors << ";";
|
||||
s << "const int gl_MaxVertexAttribs = " << resources.MaxVertexAttribs << ";";
|
||||
s << "const int gl_MaxVertexUniformVectors = " << resources.MaxVertexUniformVectors << ";";
|
||||
|
||||
s << "const int gl_MaxVaryingVectors = " << resources.maxVaryingVectors << ";";
|
||||
s << "const int gl_MaxVertexTextureImageUnits = " << resources.maxVertexTextureImageUnits << ";";
|
||||
s << "const int gl_MaxCombinedTextureImageUnits = " << resources.maxCombinedTextureImageUnits << ";";
|
||||
s << "const int gl_MaxTextureImageUnits = " << resources.maxTextureImageUnits << ";";
|
||||
s << "const int gl_MaxFragmentUniformVectors = " << resources.maxFragmentUniformVectors << ";";
|
||||
s << "const int gl_MaxDrawBuffers = " << resources.maxDrawBuffers << ";";
|
||||
s << "const int gl_MaxVaryingVectors = " << resources.MaxVaryingVectors << ";";
|
||||
s << "const int gl_MaxVertexTextureImageUnits = " << resources.MaxVertexTextureImageUnits << ";";
|
||||
s << "const int gl_MaxCombinedTextureImageUnits = " << resources.MaxCombinedTextureImageUnits << ";";
|
||||
s << "const int gl_MaxTextureImageUnits = " << resources.MaxTextureImageUnits << ";";
|
||||
s << "const int gl_MaxFragmentUniformVectors = " << resources.MaxFragmentUniformVectors << ";";
|
||||
s << "const int gl_MaxDrawBuffers = " << resources.MaxDrawBuffers << ";";
|
||||
|
||||
return s.str();
|
||||
}
|
||||
|
||||
void TBuiltIns::initialize(EShLanguage language, EShSpec spec, const TBuiltInResource& resources)
|
||||
void TBuiltIns::initialize(ShShaderType type, ShShaderSpec spec,
|
||||
const ShBuiltInResources& resources)
|
||||
{
|
||||
switch (language) {
|
||||
case EShLangFragment:
|
||||
switch (type) {
|
||||
case SH_FRAGMENT_SHADER:
|
||||
builtInStrings.push_back(DefaultPrecisionFragment());
|
||||
builtInStrings.push_back(BuiltInFunctionsCommon());
|
||||
builtInStrings.push_back(BuiltInFunctionsFragment());
|
||||
builtInStrings.push_back(BuiltInFunctionsFragment(resources));
|
||||
builtInStrings.push_back(StandardUniforms());
|
||||
break;
|
||||
|
||||
case EShLangVertex:
|
||||
case SH_VERTEX_SHADER:
|
||||
builtInStrings.push_back(DefaultPrecisionVertex());
|
||||
builtInStrings.push_back(BuiltInFunctionsCommon());
|
||||
builtInStrings.push_back(BuiltInFunctionsVertex());
|
||||
builtInStrings.push_back(BuiltInFunctionsVertex(resources));
|
||||
builtInStrings.push_back(StandardUniforms());
|
||||
break;
|
||||
|
||||
|
@ -508,14 +508,16 @@ void TBuiltIns::initialize(EShLanguage language, EShSpec spec, const TBuiltInRes
|
|||
builtInStrings.push_back(BuiltInConstants(resources));
|
||||
}
|
||||
|
||||
void IdentifyBuiltIns(EShLanguage language, EShSpec spec, const TBuiltInResource& resources, TSymbolTable& symbolTable)
|
||||
void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec,
|
||||
const ShBuiltInResources& resources,
|
||||
TSymbolTable& symbolTable)
|
||||
{
|
||||
//
|
||||
// First, insert some special built-in variables that are not in
|
||||
// the built-in header files.
|
||||
//
|
||||
switch(language) {
|
||||
case EShLangFragment:
|
||||
switch(type) {
|
||||
case SH_FRAGMENT_SHADER:
|
||||
symbolTable.insert(*new TVariable(NewPoolTString("gl_FragCoord"), TType(EbtFloat, EbpMedium, EvqFragCoord, 4)));
|
||||
symbolTable.insert(*new TVariable(NewPoolTString("gl_FrontFacing"), TType(EbtBool, EbpUndefined, EvqFrontFacing, 1)));
|
||||
symbolTable.insert(*new TVariable(NewPoolTString("gl_FragColor"), TType(EbtFloat, EbpMedium, EvqFragColor, 4)));
|
||||
|
@ -523,7 +525,7 @@ void IdentifyBuiltIns(EShLanguage language, EShSpec spec, const TBuiltInResource
|
|||
symbolTable.insert(*new TVariable(NewPoolTString("gl_PointCoord"), TType(EbtFloat, EbpMedium, EvqPointCoord, 2)));
|
||||
break;
|
||||
|
||||
case EShLangVertex:
|
||||
case SH_VERTEX_SHADER:
|
||||
symbolTable.insert(*new TVariable(NewPoolTString("gl_Position"), TType(EbtFloat, EbpHigh, EvqPosition, 4)));
|
||||
symbolTable.insert(*new TVariable(NewPoolTString("gl_PointSize"), TType(EbtFloat, EbpMedium, EvqPointSize, 1)));
|
||||
break;
|
||||
|
@ -591,23 +593,29 @@ void IdentifyBuiltIns(EShLanguage language, EShSpec spec, const TBuiltInResource
|
|||
symbolTable.relateToOperator("all", EOpAll);
|
||||
|
||||
// Map language-specific operators.
|
||||
switch(language) {
|
||||
case EShLangVertex:
|
||||
switch(type) {
|
||||
case SH_VERTEX_SHADER:
|
||||
break;
|
||||
case EShLangFragment:
|
||||
//symbolTable.relateToOperator("dFdx", EOpDPdx); // OES_standard_derivatives extension
|
||||
//symbolTable.relateToOperator("dFdy", EOpDPdy); // OES_standard_derivatives extension
|
||||
//symbolTable.relateToOperator("fwidth", EOpFwidth); // OES_standard_derivatives extension
|
||||
case SH_FRAGMENT_SHADER:
|
||||
if (resources.OES_standard_derivatives) {
|
||||
symbolTable.relateToOperator("dFdx", EOpDFdx);
|
||||
symbolTable.relateToOperator("dFdy", EOpDFdy);
|
||||
symbolTable.relateToOperator("fwidth", EOpFwidth);
|
||||
|
||||
symbolTable.relateToExtension("dFdx", "GL_OES_standard_derivatives");
|
||||
symbolTable.relateToExtension("dFdy", "GL_OES_standard_derivatives");
|
||||
symbolTable.relateToExtension("fwidth", "GL_OES_standard_derivatives");
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
// Finally add resource-specific variables.
|
||||
switch(language) {
|
||||
case EShLangFragment: {
|
||||
switch(type) {
|
||||
case SH_FRAGMENT_SHADER: {
|
||||
// Set up gl_FragData. The array size.
|
||||
TType fragData(EbtFloat, EbpMedium, EvqFragColor, 4, false, true);
|
||||
fragData.setArraySize(resources.maxDrawBuffers);
|
||||
fragData.setArraySize(resources.MaxDrawBuffers);
|
||||
symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData"), fragData));
|
||||
}
|
||||
break;
|
||||
|
@ -615,3 +623,9 @@ void IdentifyBuiltIns(EShLanguage language, EShSpec spec, const TBuiltInResource
|
|||
}
|
||||
}
|
||||
|
||||
void InitExtensionBehavior(const ShBuiltInResources& resources,
|
||||
TExtensionBehavior& extBehavior)
|
||||
{
|
||||
if (resources.OES_standard_derivatives)
|
||||
extBehavior["GL_OES_standard_derivatives"] = EBhDisable;
|
||||
}
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
#ifndef _INITIALIZE_INCLUDED_
|
||||
#define _INITIALIZE_INCLUDED_
|
||||
|
||||
#include "GLSLANG/ResourceLimits.h"
|
||||
|
||||
#include "compiler/Common.h"
|
||||
#include "compiler/ShHandle.h"
|
||||
#include "compiler/SymbolTable.h"
|
||||
|
@ -19,17 +17,23 @@ class TBuiltIns {
|
|||
public:
|
||||
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
|
||||
|
||||
void initialize(EShLanguage language, EShSpec spec, const TBuiltInResource& resources);
|
||||
void initialize(ShShaderType type, ShShaderSpec spec,
|
||||
const ShBuiltInResources& resources);
|
||||
const TBuiltInStrings& getBuiltInStrings() { return builtInStrings; }
|
||||
|
||||
protected:
|
||||
TBuiltInStrings builtInStrings;
|
||||
};
|
||||
|
||||
void IdentifyBuiltIns(EShLanguage language, EShSpec spec, const TBuiltInResource& resources,
|
||||
void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec,
|
||||
const ShBuiltInResources& resources,
|
||||
TSymbolTable& symbolTable);
|
||||
|
||||
void InitExtensionBehavior(const ShBuiltInResources& resources,
|
||||
TExtensionBehavior& extensionBehavior);
|
||||
|
||||
extern "C" int InitPreprocessor(void);
|
||||
extern "C" int FinalizePreprocessor(void);
|
||||
extern "C" void PredefineIntMacro(const char *name, int value);
|
||||
|
||||
#endif // _INITIALIZE_INCLUDED_
|
||||
|
|
|
@ -51,18 +51,23 @@ TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType
|
|||
TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line, TSymbolTable& symbolTable)
|
||||
{
|
||||
switch (op) {
|
||||
case EOpEqual:
|
||||
case EOpNotEqual:
|
||||
if (left->isArray())
|
||||
return 0;
|
||||
break;
|
||||
case EOpLessThan:
|
||||
case EOpGreaterThan:
|
||||
case EOpLessThanEqual:
|
||||
case EOpGreaterThanEqual:
|
||||
if (left->getType().isMatrix() || left->getType().isArray() || left->getType().isVector() || left->getType().getBasicType() == EbtStruct) {
|
||||
if (left->isMatrix() || left->isArray() || left->isVector() || left->getBasicType() == EbtStruct) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case EOpLogicalOr:
|
||||
case EOpLogicalXor:
|
||||
case EOpLogicalAnd:
|
||||
if (left->getType().getBasicType() != EbtBool || left->getType().isMatrix() || left->getType().isArray() || left->getType().isVector()) {
|
||||
if (left->getBasicType() != EbtBool || left->isMatrix() || left->isArray() || left->isVector()) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
@ -70,7 +75,7 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
|
|||
case EOpSub:
|
||||
case EOpDiv:
|
||||
case EOpMul:
|
||||
if (left->getType().getBasicType() == EbtStruct || left->getType().getBasicType() == EbtBool)
|
||||
if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool)
|
||||
return 0;
|
||||
default: break;
|
||||
}
|
||||
|
@ -78,8 +83,10 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
|
|||
//
|
||||
// First try converting the children to compatible types.
|
||||
//
|
||||
|
||||
if (!(left->getType().getStruct() && right->getType().getStruct())) {
|
||||
if (left->getType().getStruct() && right->getType().getStruct()) {
|
||||
if (left->getType() != right->getType())
|
||||
return 0;
|
||||
} else {
|
||||
TIntermTyped* child = addConversion(op, left->getType(), right);
|
||||
if (child)
|
||||
right = child;
|
||||
|
@ -90,12 +97,8 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
|
|||
else
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (left->getType() != right->getType())
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Need a new node holding things together then. Make
|
||||
// one and promote it to the right type.
|
||||
|
@ -107,18 +110,16 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
|
|||
|
||||
node->setLeft(left);
|
||||
node->setRight(right);
|
||||
if (! node->promote(infoSink))
|
||||
if (!node->promote(infoSink))
|
||||
return 0;
|
||||
|
||||
TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
|
||||
TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
|
||||
|
||||
//
|
||||
// See if we can fold constants.
|
||||
//
|
||||
|
||||
TIntermTyped* typedReturnNode = 0;
|
||||
if ( leftTempConstant && rightTempConstant) {
|
||||
TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
|
||||
TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
|
||||
if (leftTempConstant && rightTempConstant) {
|
||||
typedReturnNode = leftTempConstant->fold(node->getOp(), rightTempConstant, infoSink);
|
||||
|
||||
if (typedReturnNode)
|
||||
|
@ -303,7 +304,7 @@ TIntermAggregate* TIntermediate::setAggregateOperator(TIntermNode* node, TOperat
|
|||
//
|
||||
// Set the operator.
|
||||
//
|
||||
aggNode->setOperator(op);
|
||||
aggNode->setOp(op);
|
||||
if (line != 0)
|
||||
aggNode->setLine(line);
|
||||
|
||||
|
@ -515,9 +516,9 @@ TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, T
|
|||
return right;
|
||||
} else {
|
||||
TIntermTyped *commaAggregate = growAggregate(left, right, line);
|
||||
commaAggregate->getAsAggregate()->setOperator(EOpComma);
|
||||
commaAggregate->getAsAggregate()->setOp(EOpComma);
|
||||
commaAggregate->setType(right->getType());
|
||||
commaAggregate->getTypePointer()->changeQualifier(EvqTemporary);
|
||||
commaAggregate->getTypePointer()->setQualifier(EvqTemporary);
|
||||
return commaAggregate;
|
||||
}
|
||||
}
|
||||
|
@ -630,7 +631,7 @@ TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expres
|
|||
// This is to be executed once the final root is put on top by the parsing
|
||||
// process.
|
||||
//
|
||||
bool TIntermediate::postProcess(TIntermNode* root, EShLanguage language)
|
||||
bool TIntermediate::postProcess(TIntermNode* root)
|
||||
{
|
||||
if (root == 0)
|
||||
return true;
|
||||
|
@ -640,7 +641,7 @@ bool TIntermediate::postProcess(TIntermNode* root, EShLanguage language)
|
|||
//
|
||||
TIntermAggregate* aggRoot = root->getAsAggregate();
|
||||
if (aggRoot && aggRoot->getOp() == EOpNull)
|
||||
aggRoot->setOperator(EOpSequence);
|
||||
aggRoot->setOp(EOpSequence);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -760,6 +761,12 @@ bool TIntermUnary::promote(TInfoSink&)
|
|||
//
|
||||
bool TIntermBinary::promote(TInfoSink& infoSink)
|
||||
{
|
||||
// This function only handles scalars, vectors, and matrices.
|
||||
if (left->isArray() || right->isArray()) {
|
||||
infoSink.info.message(EPrefixInternalError, "Invalid operation for arrays", getLine());
|
||||
return false;
|
||||
}
|
||||
|
||||
// GLSL ES 2.0 does not support implicit type casting.
|
||||
// So the basic type should always match.
|
||||
if (left->getBasicType() != right->getBasicType())
|
||||
|
@ -773,46 +780,12 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
|
|||
|
||||
// The result gets promoted to the highest precision.
|
||||
TPrecision higherPrecision = GetHigherPrecision(left->getPrecision(), right->getPrecision());
|
||||
getTypePointer()->changePrecision(higherPrecision);
|
||||
getTypePointer()->setPrecision(higherPrecision);
|
||||
|
||||
// Binary operations results in temporary variables unless both
|
||||
// operands are const.
|
||||
if (left->getQualifier() != EvqConst || right->getQualifier() != EvqConst) {
|
||||
getTypePointer()->changeQualifier(EvqTemporary);
|
||||
}
|
||||
|
||||
//
|
||||
// Array operations.
|
||||
//
|
||||
if (left->isArray() || right->isArray()) {
|
||||
//
|
||||
// Arrays types have to be exact matches.
|
||||
//
|
||||
if (left->getType() != right->getType())
|
||||
return false;
|
||||
|
||||
switch (op) {
|
||||
//
|
||||
// Promote to conditional
|
||||
//
|
||||
case EOpEqual:
|
||||
case EOpNotEqual:
|
||||
setType(TType(EbtBool, EbpUndefined));
|
||||
break;
|
||||
|
||||
//
|
||||
// Set array information.
|
||||
//
|
||||
case EOpAssign:
|
||||
case EOpInitialize:
|
||||
getTypePointer()->setArraySize(left->getType().getArraySize());
|
||||
getTypePointer()->setArrayInformationType(left->getType().getArrayInformationType());
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
getTypePointer()->setQualifier(EvqTemporary);
|
||||
}
|
||||
|
||||
int size = std::max(left->getNominalSize(), right->getNominalSize());
|
||||
|
@ -964,7 +937,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
|
|||
|
||||
bool CompareStruct(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray)
|
||||
{
|
||||
TTypeList* fields = leftNodeType.getStruct();
|
||||
const TTypeList* fields = leftNodeType.getStruct();
|
||||
|
||||
size_t structSize = fields->size();
|
||||
int index = 0;
|
||||
|
|
|
@ -374,6 +374,10 @@ bool TOutputGLSL::visitUnary(Visit visit, TIntermUnary* node)
|
|||
case EOpLength: writeTriplet(visit, "length(", NULL, ")"); break;
|
||||
case EOpNormalize: writeTriplet(visit, "normalize(", NULL, ")"); break;
|
||||
|
||||
case EOpDFdx: writeTriplet(visit, "dFdx(", NULL, ")"); break;
|
||||
case EOpDFdy: writeTriplet(visit, "dFdy(", NULL, ")"); break;
|
||||
case EOpFwidth: writeTriplet(visit, "fwidth(", NULL, ")"); break;
|
||||
|
||||
case EOpAny: writeTriplet(visit, "any(", NULL, ")"); break;
|
||||
case EOpAll: writeTriplet(visit, "all(", NULL, ")"); break;
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ int OutputHLSL::vectorSize(const TType &type) const
|
|||
|
||||
void OutputHLSL::header()
|
||||
{
|
||||
EShLanguage language = mContext.language;
|
||||
ShShaderType shaderType = mContext.shaderType;
|
||||
TInfoSinkBase &out = mHeader;
|
||||
|
||||
for (StructDeclarations::iterator structDeclaration = mStructDeclarations.begin(); structDeclaration != mStructDeclarations.end(); structDeclaration++)
|
||||
|
@ -109,7 +109,7 @@ void OutputHLSL::header()
|
|||
out << *constructor;
|
||||
}
|
||||
|
||||
if (language == EShLangFragment)
|
||||
if (shaderType == SH_FRAGMENT_SHADER)
|
||||
{
|
||||
TString uniforms;
|
||||
TString varyings;
|
||||
|
@ -791,11 +791,11 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
|
|||
{
|
||||
if (node->getLeft()->isMatrix())
|
||||
{
|
||||
switch (node->getLeft()->getSize())
|
||||
switch (node->getLeft()->getNominalSize())
|
||||
{
|
||||
case 2 * 2: mUsesEqualMat2 = true; break;
|
||||
case 3 * 3: mUsesEqualMat3 = true; break;
|
||||
case 4 * 4: mUsesEqualMat4 = true; break;
|
||||
case 2: mUsesEqualMat2 = true; break;
|
||||
case 3: mUsesEqualMat3 = true; break;
|
||||
case 4: mUsesEqualMat4 = true; break;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
@ -804,7 +804,7 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
|
|||
switch (node->getLeft()->getBasicType())
|
||||
{
|
||||
case EbtFloat:
|
||||
switch (node->getLeft()->getSize())
|
||||
switch (node->getLeft()->getNominalSize())
|
||||
{
|
||||
case 2: mUsesEqualVec2 = true; break;
|
||||
case 3: mUsesEqualVec3 = true; break;
|
||||
|
@ -813,7 +813,7 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
|
|||
}
|
||||
break;
|
||||
case EbtInt:
|
||||
switch (node->getLeft()->getSize())
|
||||
switch (node->getLeft()->getNominalSize())
|
||||
{
|
||||
case 2: mUsesEqualIVec2 = true; break;
|
||||
case 3: mUsesEqualIVec3 = true; break;
|
||||
|
@ -822,7 +822,7 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
|
|||
}
|
||||
break;
|
||||
case EbtBool:
|
||||
switch (node->getLeft()->getSize())
|
||||
switch (node->getLeft()->getNominalSize())
|
||||
{
|
||||
case 2: mUsesEqualBVec2 = true; break;
|
||||
case 3: mUsesEqualBVec3 = true; break;
|
||||
|
@ -933,9 +933,9 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
|
|||
case EOpFract: outputTriplet(visit, "frac(", "", ")"); break;
|
||||
case EOpLength: outputTriplet(visit, "length(", "", ")"); break;
|
||||
case EOpNormalize: outputTriplet(visit, "normalize(", "", ")"); break;
|
||||
// case EOpDPdx: outputTriplet(visit, "ddx(", "", ")"); break;
|
||||
// case EOpDPdy: outputTriplet(visit, "ddy(", "", ")"); break;
|
||||
// case EOpFwidth: outputTriplet(visit, "fwidth(", "", ")"); break;
|
||||
case EOpDFdx: outputTriplet(visit, "ddx(", "", ")"); break;
|
||||
case EOpDFdy: outputTriplet(visit, "ddy(", "", ")"); break;
|
||||
case EOpFwidth: outputTriplet(visit, "fwidth(", "", ")"); break;
|
||||
case EOpAny: outputTriplet(visit, "any(", "", ")"); break;
|
||||
case EOpAll: outputTriplet(visit, "all(", "", ")"); break;
|
||||
default: UNREACHABLE();
|
||||
|
@ -946,7 +946,7 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
|
|||
|
||||
bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||
{
|
||||
EShLanguage language = mContext.language;
|
||||
ShShaderType shaderType = mContext.shaderType;
|
||||
TInfoSinkBase &out = mBody;
|
||||
|
||||
switch (node->getOp())
|
||||
|
@ -1288,7 +1288,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
|
|||
case EOpVectorNotEqual: outputTriplet(visit, "(", " != ", ")"); break;
|
||||
case EOpMod:
|
||||
{
|
||||
switch (node->getSequence()[0]->getAsTyped()->getSize()) // Number of components in the first argument
|
||||
switch (node->getSequence()[0]->getAsTyped()->getNominalSize()) // Number of components in the first argument
|
||||
{
|
||||
case 1: mUsesMod1 = true; break;
|
||||
case 2: mUsesMod2 = true; break;
|
||||
|
@ -1317,7 +1317,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
|
|||
case EOpCross: outputTriplet(visit, "cross(", ", ", ")"); break;
|
||||
case EOpFaceForward:
|
||||
{
|
||||
switch (node->getSequence()[0]->getAsTyped()->getSize()) // Number of components in the first argument
|
||||
switch (node->getSequence()[0]->getAsTyped()->getNominalSize()) // Number of components in the first argument
|
||||
{
|
||||
case 1: mUsesFaceforward1 = true; break;
|
||||
case 2: mUsesFaceforward2 = true; break;
|
||||
|
@ -1553,7 +1553,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
|
|||
|
||||
if (symbol && constant)
|
||||
{
|
||||
if (constant->getBasicType() == EbtInt && constant->getSize() == 1)
|
||||
if (constant->getBasicType() == EbtInt && constant->getNominalSize() == 1)
|
||||
{
|
||||
index = symbol;
|
||||
initial = constant->getUnionArrayPointer()[0].getIConst();
|
||||
|
@ -1575,7 +1575,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
|
|||
|
||||
if (constant)
|
||||
{
|
||||
if (constant->getBasicType() == EbtInt && constant->getSize() == 1)
|
||||
if (constant->getBasicType() == EbtInt && constant->getNominalSize() == 1)
|
||||
{
|
||||
comparator = test->getOp();
|
||||
limit = constant->getUnionArrayPointer()[0].getIConst();
|
||||
|
@ -1597,7 +1597,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
|
|||
|
||||
if (constant)
|
||||
{
|
||||
if (constant->getBasicType() == EbtInt && constant->getSize() == 1)
|
||||
if (constant->getBasicType() == EbtInt && constant->getNominalSize() == 1)
|
||||
{
|
||||
int value = constant->getUnionArrayPointer()[0].getIConst();
|
||||
|
||||
|
@ -1848,8 +1848,8 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI
|
|||
|
||||
TType ctorType = type;
|
||||
ctorType.clearArrayness();
|
||||
ctorType.changePrecision(EbpHigh);
|
||||
ctorType.changeQualifier(EvqTemporary);
|
||||
ctorType.setPrecision(EbpHigh);
|
||||
ctorType.setQualifier(EvqTemporary);
|
||||
|
||||
TString ctorName = type.getStruct() ? decorate(name) : name;
|
||||
|
||||
|
|
|
@ -415,7 +415,7 @@ bool TParseContext::reservedErrorCheck(int line, const TString& identifier)
|
|||
error(line, reservedErrMsg, "gl_", "");
|
||||
return true;
|
||||
}
|
||||
if (spec == EShSpecWebGL) {
|
||||
if (shaderSpec == SH_WEBGL_SPEC) {
|
||||
if (identifier.substr(0, 6) == TString("webgl_")) {
|
||||
error(line, reservedErrMsg, "webgl_", "");
|
||||
return true;
|
||||
|
@ -471,22 +471,23 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction
|
|||
bool matrixInMatrix = false;
|
||||
bool arrayArg = false;
|
||||
for (int i = 0; i < function.getParamCount(); ++i) {
|
||||
size += function[i].type->getObjectSize();
|
||||
const TParameter& param = function.getParam(i);
|
||||
size += param.type->getObjectSize();
|
||||
|
||||
if (constructingMatrix && function[i].type->isMatrix())
|
||||
if (constructingMatrix && param.type->isMatrix())
|
||||
matrixInMatrix = true;
|
||||
if (full)
|
||||
overFull = true;
|
||||
if (op != EOpConstructStruct && !type->isArray() && size >= type->getObjectSize())
|
||||
full = true;
|
||||
if (function[i].type->getQualifier() != EvqConst)
|
||||
if (param.type->getQualifier() != EvqConst)
|
||||
constType = false;
|
||||
if (function[i].type->isArray())
|
||||
if (param.type->isArray())
|
||||
arrayArg = true;
|
||||
}
|
||||
|
||||
if (constType)
|
||||
type->changeQualifier(EvqConst);
|
||||
type->setQualifier(EvqConst);
|
||||
|
||||
if (type->isArray() && type->getArraySize() != function.getParamCount()) {
|
||||
error(line, "array constructor needs one argument per array element", "constructor", "");
|
||||
|
@ -586,14 +587,14 @@ bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const
|
|||
{
|
||||
if (pType.type == EbtStruct) {
|
||||
if (containsSampler(*pType.userDef)) {
|
||||
error(line, reason, TType::getBasicString(pType.type), "(structure contains a sampler)");
|
||||
error(line, reason, getBasicString(pType.type), "(structure contains a sampler)");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
} else if (IsSampler(pType.type)) {
|
||||
error(line, reason, TType::getBasicString(pType.type), "");
|
||||
error(line, reason, getBasicString(pType.type), "");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -674,14 +675,11 @@ bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size)
|
|||
//
|
||||
bool TParseContext::arrayQualifierErrorCheck(int line, TPublicType type)
|
||||
{
|
||||
if (type.qualifier == EvqAttribute) {
|
||||
if ((type.qualifier == EvqAttribute) || (type.qualifier == EvqConst)) {
|
||||
error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str(), "");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type.qualifier == EvqConst && extensionErrorCheck(line, "GL_3DL_array_objects"))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -879,23 +877,29 @@ bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TQualifier p
|
|||
}
|
||||
|
||||
if (qualifier == EvqConst)
|
||||
type->changeQualifier(EvqConstReadOnly);
|
||||
type->setQualifier(EvqConstReadOnly);
|
||||
else
|
||||
type->changeQualifier(paramQualifier);
|
||||
type->setQualifier(paramQualifier);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TParseContext::extensionErrorCheck(int line, const char* extension)
|
||||
{
|
||||
if (extensionBehavior[extension] == EBhWarn) {
|
||||
infoSink.info.message(EPrefixWarning, ("extension " + TString(extension) + " is being used").c_str(), line);
|
||||
return false;
|
||||
}
|
||||
if (extensionBehavior[extension] == EBhDisable) {
|
||||
error(line, "extension", extension, "is disabled");
|
||||
bool TParseContext::extensionErrorCheck(int line, const TString& extension)
|
||||
{
|
||||
TExtensionBehavior::const_iterator iter = extensionBehavior.find(extension);
|
||||
if (iter == extensionBehavior.end()) {
|
||||
error(line, "extension", extension.c_str(), "is not supported");
|
||||
return true;
|
||||
}
|
||||
if (iter->second == EBhDisable) {
|
||||
error(line, "extension", extension.c_str(), "is disabled");
|
||||
return true;
|
||||
}
|
||||
if (iter->second == EBhWarn) {
|
||||
TString msg = "extension " + extension + " is being used";
|
||||
infoSink.info.message(EPrefixWarning, msg.c_str(), line);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -976,13 +980,13 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu
|
|||
if (qualifier == EvqConst) {
|
||||
if (qualifier != initializer->getType().getQualifier()) {
|
||||
error(line, " assigning non-constant to", "=", "'%s'", variable->getType().getCompleteString().c_str());
|
||||
variable->getType().changeQualifier(EvqTemporary);
|
||||
variable->getType().setQualifier(EvqTemporary);
|
||||
return true;
|
||||
}
|
||||
if (type != initializer->getType()) {
|
||||
error(line, " non-matching types for const initializer ",
|
||||
variable->getType().getQualifierString(), "");
|
||||
variable->getType().changeQualifier(EvqTemporary);
|
||||
variable->getType().setQualifier(EvqTemporary);
|
||||
return true;
|
||||
}
|
||||
if (initializer->getAsConstantUnion()) {
|
||||
|
@ -1001,7 +1005,7 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu
|
|||
variable->shareConstPointer(constArray);
|
||||
} else {
|
||||
error(line, " cannot assign to", "=", "'%s'", variable->getType().getCompleteString().c_str());
|
||||
variable->getType().changeQualifier(EvqTemporary);
|
||||
variable->getType().setQualifier(EvqTemporary);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1052,7 +1056,7 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type
|
|||
|
||||
TIntermAggregate* aggrNode = node->getAsAggregate();
|
||||
|
||||
TTypeList::iterator memberTypes;
|
||||
TTypeList::const_iterator memberTypes;
|
||||
if (op == EOpConstructStruct)
|
||||
memberTypes = type->getStruct()->begin();
|
||||
|
||||
|
@ -1350,7 +1354,7 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS
|
|||
//
|
||||
TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* node, TSourceLoc line)
|
||||
{
|
||||
TTypeList* fields = node->getType().getStruct();
|
||||
const TTypeList* fields = node->getType().getStruct();
|
||||
TIntermTyped *typedNode;
|
||||
int instanceSize = 0;
|
||||
unsigned int index = 0;
|
||||
|
@ -1378,19 +1382,6 @@ TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* n
|
|||
return typedNode;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize all supported extensions to disable
|
||||
//
|
||||
void TParseContext::initializeExtensionBehavior()
|
||||
{
|
||||
//
|
||||
// example code: extensionBehavior["test"] = EBhDisable; // where "test" is the name of
|
||||
// supported extension
|
||||
//
|
||||
extensionBehavior["GL_ARB_texture_rectangle"] = EBhRequire;
|
||||
extensionBehavior["GL_3DL_array_objects"] = EBhDisable;
|
||||
}
|
||||
|
||||
OS_TLSIndex GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
|
||||
|
||||
bool InitializeParseContextIndex()
|
||||
|
|
|
@ -6,9 +6,10 @@
|
|||
#ifndef _PARSER_HELPER_INCLUDED_
|
||||
#define _PARSER_HELPER_INCLUDED_
|
||||
|
||||
#include "compiler/ExtensionBehavior.h"
|
||||
#include "compiler/localintermediate.h"
|
||||
#include "compiler/ShHandle.h"
|
||||
#include "compiler/SymbolTable.h"
|
||||
#include "compiler/localintermediate.h"
|
||||
|
||||
struct TMatrixFields {
|
||||
bool wholeRow;
|
||||
|
@ -17,13 +18,6 @@ struct TMatrixFields {
|
|||
int col;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
EBhRequire,
|
||||
EBhEnable,
|
||||
EBhWarn,
|
||||
EBhDisable
|
||||
} TBehavior;
|
||||
|
||||
struct TPragma {
|
||||
TPragma(bool o, bool d) : optimize(o), debug(d) { }
|
||||
bool optimize;
|
||||
|
@ -36,15 +30,16 @@ struct TPragma {
|
|||
// they can be passed to the parser without needing a global.
|
||||
//
|
||||
struct TParseContext {
|
||||
TParseContext(TSymbolTable& symt, TIntermediate& interm, EShLanguage l, EShSpec s, TInfoSink& is) :
|
||||
intermediate(interm), symbolTable(symt), infoSink(is), language(l), spec(s), treeRoot(0),
|
||||
TParseContext(TSymbolTable& symt, const TExtensionBehavior& ext, TIntermediate& interm, ShShaderType type, ShShaderSpec spec, TInfoSink& is) :
|
||||
intermediate(interm), symbolTable(symt), extensionBehavior(ext), infoSink(is), shaderType(type), shaderSpec(spec), treeRoot(0),
|
||||
recoveredFromError(false), numErrors(0), lexAfterType(false), loopNestingLevel(0),
|
||||
inTypeParen(false), contextPragma(true, false) { }
|
||||
TIntermediate& intermediate; // to hold and build a parse tree
|
||||
TSymbolTable& symbolTable; // symbol table that goes with the language currently being parsed
|
||||
TExtensionBehavior extensionBehavior; // mapping between supported extensions and current behavior.
|
||||
TInfoSink& infoSink;
|
||||
EShLanguage language; // vertex or fragment language (future: pack or unpack)
|
||||
EShSpec spec; // The language specification compiler conforms to - GLES2 or WebGL.
|
||||
ShShaderType shaderType; // vertex or fragment language (future: pack or unpack)
|
||||
ShShaderSpec shaderSpec; // The language specification compiler conforms to - GLES2 or WebGL.
|
||||
TIntermNode* treeRoot; // root of parse tree being created
|
||||
bool recoveredFromError; // true if a parse error has occurred, but we continue to parse
|
||||
int numErrors;
|
||||
|
@ -53,8 +48,6 @@ struct TParseContext {
|
|||
bool inTypeParen; // true if in parentheses, looking only for an identifier
|
||||
const TType* currentFunctionType; // the return type of the function that's currently being parsed
|
||||
bool functionReturnsValue; // true if a non-void function has a return
|
||||
TMap<TString, TBehavior> extensionBehavior;
|
||||
void initializeExtensionBehavior();
|
||||
|
||||
void error(TSourceLoc, const char *szReason, const char *szToken,
|
||||
const char *szExtraInfoFormat, ...);
|
||||
|
@ -86,7 +79,7 @@ struct TParseContext {
|
|||
bool nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type);
|
||||
bool nonInitErrorCheck(int line, TString& identifier, TPublicType& type);
|
||||
bool paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type);
|
||||
bool extensionErrorCheck(int line, const char*);
|
||||
bool extensionErrorCheck(int line, const TString&);
|
||||
const TFunction* findFunction(int line, TFunction* pfnCall, bool *builtIn = 0);
|
||||
bool executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType,
|
||||
TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0);
|
||||
|
@ -105,7 +98,7 @@ struct TParseContext {
|
|||
bool AfterEOF;
|
||||
};
|
||||
|
||||
int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext&);
|
||||
int PaParseStrings(const char* const argv[], const int strLen[], int argc, TParseContext&);
|
||||
void PaReservedWord();
|
||||
int PaIdentOrType(TString& id, TParseContext&, TSymbol*&);
|
||||
int PaParseComment(int &lineno, TParseContext&);
|
||||
|
|
|
@ -16,11 +16,12 @@
|
|||
|
||||
#include "GLSLANG/ShaderLang.h"
|
||||
|
||||
#include "compiler/ExtensionBehavior.h"
|
||||
#include "compiler/InfoSink.h"
|
||||
#include "compiler/SymbolTable.h"
|
||||
#include "compiler/VariableInfo.h"
|
||||
|
||||
class TCompiler;
|
||||
class TIntermNode;
|
||||
|
||||
//
|
||||
// The base class used to back handles returned to the driver.
|
||||
|
@ -38,27 +39,44 @@ public:
|
|||
//
|
||||
class TCompiler : public TShHandleBase {
|
||||
public:
|
||||
TCompiler(EShLanguage l, EShSpec s) : language(l), spec(s) { }
|
||||
virtual ~TCompiler() { }
|
||||
|
||||
EShLanguage getLanguage() const { return language; }
|
||||
EShSpec getSpec() const { return spec; }
|
||||
TSymbolTable& getSymbolTable() { return symbolTable; }
|
||||
TInfoSink& getInfoSink() { return infoSink; }
|
||||
|
||||
virtual bool compile(TIntermNode* root) = 0;
|
||||
|
||||
TCompiler(ShShaderType type, ShShaderSpec spec);
|
||||
virtual ~TCompiler();
|
||||
virtual TCompiler* getAsCompiler() { return this; }
|
||||
|
||||
bool Init(const ShBuiltInResources& resources);
|
||||
bool compile(const char* const shaderStrings[],
|
||||
const int numStrings,
|
||||
int compileOptions);
|
||||
|
||||
// Get results of the last compilation.
|
||||
TInfoSink& getInfoSink() { return infoSink; }
|
||||
const TVariableInfoList& getAttribs() const { return attribs; }
|
||||
const TVariableInfoList& getUniforms() const { return uniforms; }
|
||||
|
||||
protected:
|
||||
EShLanguage language;
|
||||
EShSpec spec;
|
||||
// Initialize symbol-table with built-in symbols.
|
||||
bool InitBuiltInSymbolTable(const ShBuiltInResources& resources);
|
||||
// Clears the results from the previous compilation.
|
||||
void clearResults();
|
||||
// Collect info for all attribs and uniforms.
|
||||
void collectAttribsUniforms(TIntermNode* root);
|
||||
// Translate to object code.
|
||||
virtual void translate(TIntermNode* root) = 0;
|
||||
|
||||
private:
|
||||
ShShaderType shaderType;
|
||||
ShShaderSpec shaderSpec;
|
||||
|
||||
// Built-in symbol table for the given language, spec, and resources.
|
||||
// It is preserved from compile-to-compile.
|
||||
TSymbolTable symbolTable;
|
||||
// Output sink.
|
||||
TInfoSink infoSink;
|
||||
// Built-in extensions with default behavior.
|
||||
TExtensionBehavior extensionBehavior;
|
||||
|
||||
// Results of compilation.
|
||||
TInfoSink infoSink; // Output sink.
|
||||
TVariableInfoList attribs; // Active attributes in the compiled shader.
|
||||
TVariableInfoList uniforms; // Active uniforms in the compiled shader.
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -70,7 +88,7 @@ protected:
|
|||
// destroy the machine dependent objects, which contain the
|
||||
// above machine independent information.
|
||||
//
|
||||
TCompiler* ConstructCompiler(EShLanguage, EShSpec);
|
||||
TCompiler* ConstructCompiler(ShShaderType type, ShShaderSpec spec);
|
||||
void DeleteCompiler(TCompiler*);
|
||||
|
||||
#endif // _SHHANDLE_INCLUDED_
|
||||
|
|
|
@ -11,79 +11,56 @@
|
|||
|
||||
#include "GLSLANG/ShaderLang.h"
|
||||
|
||||
#include "compiler/Initialize.h"
|
||||
#include "compiler/InitializeDll.h"
|
||||
#include "compiler/ParseHelper.h"
|
||||
#include "compiler/ShHandle.h"
|
||||
#include "compiler/SymbolTable.h"
|
||||
|
||||
static bool InitializeSymbolTable(
|
||||
const TBuiltInStrings& builtInStrings,
|
||||
EShLanguage language, EShSpec spec, const TBuiltInResource& resources,
|
||||
TInfoSink& infoSink, TSymbolTable& symbolTable)
|
||||
{
|
||||
TIntermediate intermediate(infoSink);
|
||||
TParseContext parseContext(symbolTable, intermediate, language, spec, infoSink);
|
||||
|
||||
GlobalParseContext = &parseContext;
|
||||
|
||||
setInitialState();
|
||||
|
||||
assert(symbolTable.isEmpty());
|
||||
//
|
||||
// Parse the built-ins. This should only happen once per
|
||||
// language symbol table.
|
||||
//
|
||||
// Push the symbol table to give it an initial scope. This
|
||||
// push should not have a corresponding pop, so that built-ins
|
||||
// are preserved, and the test for an empty table fails.
|
||||
//
|
||||
symbolTable.push();
|
||||
|
||||
//Initialize the Preprocessor
|
||||
if (InitPreprocessor())
|
||||
{
|
||||
infoSink.info.message(EPrefixInternalError, "Unable to intialize the Preprocessor");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (TBuiltInStrings::const_iterator i = builtInStrings.begin(); i != builtInStrings.end(); ++i)
|
||||
{
|
||||
const char* builtInShaders[1];
|
||||
int builtInLengths[1];
|
||||
|
||||
builtInShaders[0] = (*i).c_str();
|
||||
builtInLengths[0] = (int) (*i).size();
|
||||
|
||||
if (PaParseStrings(const_cast<char**>(builtInShaders), builtInLengths, 1, parseContext) != 0)
|
||||
{
|
||||
infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
IdentifyBuiltIns(language, spec, resources, symbolTable);
|
||||
|
||||
FinalizePreprocessor();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool GenerateBuiltInSymbolTable(
|
||||
EShLanguage language, EShSpec spec, const TBuiltInResource& resources,
|
||||
TInfoSink& infoSink, TSymbolTable& symbolTable)
|
||||
{
|
||||
TBuiltIns builtIns;
|
||||
|
||||
builtIns.initialize(language, spec, resources);
|
||||
return InitializeSymbolTable(builtIns.getBuiltInStrings(), language, spec, resources, infoSink, symbolTable);
|
||||
}
|
||||
|
||||
//
|
||||
// This is the platform independent interface between an OGL driver
|
||||
// and the shading language compiler.
|
||||
//
|
||||
|
||||
static int getVariableMaxLength(const TVariableInfoList& varList)
|
||||
{
|
||||
TString::size_type maxLen = 0;
|
||||
for (TVariableInfoList::const_iterator i = varList.begin();
|
||||
i != varList.end(); ++i)
|
||||
{
|
||||
maxLen = std::max(maxLen, i->name.size());
|
||||
}
|
||||
// Add 1 to include null-termination character.
|
||||
return static_cast<int>(maxLen) + 1;
|
||||
}
|
||||
|
||||
static void getVariableInfo(ShShaderInfo varType,
|
||||
const ShHandle handle,
|
||||
int index,
|
||||
int* length,
|
||||
int* size,
|
||||
ShDataType* type,
|
||||
char* name)
|
||||
{
|
||||
if (!handle || !size || !type || !name)
|
||||
return;
|
||||
ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
|
||||
(varType == SH_ACTIVE_UNIFORMS));
|
||||
|
||||
TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
|
||||
TCompiler* compiler = base->getAsCompiler();
|
||||
if (compiler == 0)
|
||||
return;
|
||||
|
||||
const TVariableInfoList& varList = varType == SH_ACTIVE_ATTRIBUTES ?
|
||||
compiler->getAttribs() : compiler->getUniforms();
|
||||
if (index < 0 || index >= static_cast<int>(varList.size()))
|
||||
return;
|
||||
|
||||
const TVariableInfo& varInfo = varList[index];
|
||||
if (length) *length = varInfo.name.size();
|
||||
*size = varInfo.size;
|
||||
*type = varInfo.type;
|
||||
strcpy(name, varInfo.name.c_str());
|
||||
}
|
||||
|
||||
//
|
||||
// Driver must call this first, once, before doing any other
|
||||
// compiler operations.
|
||||
|
@ -96,22 +73,52 @@ int ShInitialize()
|
|||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup symbol tables
|
||||
//
|
||||
int ShFinalize()
|
||||
{
|
||||
if (!DetachProcess())
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize built-in resources with minimum expected values.
|
||||
//
|
||||
void ShInitBuiltInResources(ShBuiltInResources* resources)
|
||||
{
|
||||
// Constants.
|
||||
resources->MaxVertexAttribs = 8;
|
||||
resources->MaxVertexUniformVectors = 128;
|
||||
resources->MaxVaryingVectors = 8;
|
||||
resources->MaxVertexTextureImageUnits = 0;
|
||||
resources->MaxCombinedTextureImageUnits = 8;
|
||||
resources->MaxTextureImageUnits = 8;
|
||||
resources->MaxFragmentUniformVectors = 16;
|
||||
resources->MaxDrawBuffers = 1;
|
||||
|
||||
// Extensions.
|
||||
resources->OES_standard_derivatives = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Driver calls these to create and destroy compiler objects.
|
||||
//
|
||||
|
||||
ShHandle ShConstructCompiler(EShLanguage language, EShSpec spec, const TBuiltInResource* resources)
|
||||
ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec,
|
||||
const ShBuiltInResources* resources)
|
||||
{
|
||||
if (!InitThread())
|
||||
return 0;
|
||||
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(language, spec));
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec));
|
||||
TCompiler* compiler = base->getAsCompiler();
|
||||
if (compiler == 0)
|
||||
return 0;
|
||||
|
||||
// Generate built-in symbol table.
|
||||
if (!GenerateBuiltInSymbolTable(language, spec, *resources, compiler->getInfoSink(), compiler->getSymbolTable())) {
|
||||
if (!compiler->Init(*resources)) {
|
||||
ShDestruct(base);
|
||||
return 0;
|
||||
}
|
||||
|
@ -130,17 +137,6 @@ void ShDestruct(ShHandle handle)
|
|||
DeleteCompiler(base->getAsCompiler());
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup symbol tables
|
||||
//
|
||||
int ShFinalize()
|
||||
{
|
||||
if (!DetachProcess())
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Do an actual compile on the given strings. The result is left
|
||||
// in the given compile object.
|
||||
|
@ -152,9 +148,7 @@ int ShCompile(
|
|||
const ShHandle handle,
|
||||
const char* const shaderStrings[],
|
||||
const int numStrings,
|
||||
const EShOptimizationLevel optLevel,
|
||||
int debugOptions
|
||||
)
|
||||
int compileOptions)
|
||||
{
|
||||
if (!InitThread())
|
||||
return 0;
|
||||
|
@ -166,83 +160,11 @@ int ShCompile(
|
|||
TCompiler* compiler = base->getAsCompiler();
|
||||
if (compiler == 0)
|
||||
return 0;
|
||||
|
||||
|
||||
GlobalPoolAllocator.push();
|
||||
TInfoSink& infoSink = compiler->getInfoSink();
|
||||
infoSink.info.erase();
|
||||
infoSink.debug.erase();
|
||||
infoSink.obj.erase();
|
||||
|
||||
if (numStrings == 0)
|
||||
return 1;
|
||||
bool success = compiler->compile(shaderStrings, numStrings, compileOptions);
|
||||
|
||||
TIntermediate intermediate(infoSink);
|
||||
TSymbolTable& symbolTable = compiler->getSymbolTable();
|
||||
|
||||
TParseContext parseContext(symbolTable, intermediate, compiler->getLanguage(), compiler->getSpec(), infoSink);
|
||||
parseContext.initializeExtensionBehavior();
|
||||
GlobalParseContext = &parseContext;
|
||||
|
||||
setInitialState();
|
||||
|
||||
InitPreprocessor();
|
||||
//
|
||||
// Parse the application's shaders. All the following symbol table
|
||||
// work will be throw-away, so push a new allocation scope that can
|
||||
// be thrown away, then push a scope for the current shader's globals.
|
||||
//
|
||||
bool success = true;
|
||||
|
||||
symbolTable.push();
|
||||
if (!symbolTable.atGlobalLevel())
|
||||
parseContext.infoSink.info.message(EPrefixInternalError, "Wrong symbol table level");
|
||||
|
||||
int ret = PaParseStrings(const_cast<char**>(shaderStrings), 0, numStrings, parseContext);
|
||||
if (ret)
|
||||
success = false;
|
||||
|
||||
if (success && parseContext.treeRoot) {
|
||||
if (optLevel == EShOptNoGeneration)
|
||||
parseContext.infoSink.info.message(EPrefixNone, "No errors. No code generation was requested.");
|
||||
else {
|
||||
success = intermediate.postProcess(parseContext.treeRoot, parseContext.language);
|
||||
|
||||
if (success) {
|
||||
|
||||
if (debugOptions & EDebugOpIntermediate)
|
||||
intermediate.outputTree(parseContext.treeRoot);
|
||||
|
||||
//
|
||||
// Call the machine dependent compiler
|
||||
//
|
||||
if (!compiler->compile(parseContext.treeRoot))
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
} else if (!success) {
|
||||
parseContext.infoSink.info.prefix(EPrefixError);
|
||||
parseContext.infoSink.info << parseContext.numErrors << " compilation errors. No code generated.\n\n";
|
||||
success = false;
|
||||
if (debugOptions & EDebugOpIntermediate)
|
||||
intermediate.outputTree(parseContext.treeRoot);
|
||||
} else if (!parseContext.treeRoot) {
|
||||
parseContext.error(1, "Unexpected end of file.", "", "");
|
||||
parseContext.infoSink.info << parseContext.numErrors << " compilation errors. No code generated.\n\n";
|
||||
success = false;
|
||||
if (debugOptions & EDebugOpIntermediate)
|
||||
intermediate.outputTree(parseContext.treeRoot);
|
||||
}
|
||||
|
||||
intermediate.remove(parseContext.treeRoot);
|
||||
|
||||
//
|
||||
// Ensure symbol table is returned to the built-in level,
|
||||
// throwing away all but the built-ins.
|
||||
//
|
||||
while (!symbolTable.atBuiltInLevel())
|
||||
symbolTable.pop();
|
||||
|
||||
FinalizePreprocessor();
|
||||
//
|
||||
// Throw away all the temporary memory used by the compilation process.
|
||||
//
|
||||
|
@ -251,43 +173,91 @@ int ShCompile(
|
|||
return success ? 1 : 0;
|
||||
}
|
||||
|
||||
void ShGetInfo(const ShHandle handle, ShShaderInfo pname, int* params)
|
||||
{
|
||||
if (!handle || !params)
|
||||
return;
|
||||
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
|
||||
TCompiler* compiler = base->getAsCompiler();
|
||||
if (!compiler) return;
|
||||
|
||||
switch(pname)
|
||||
{
|
||||
case SH_INFO_LOG_LENGTH:
|
||||
*params = compiler->getInfoSink().info.size() + 1;
|
||||
break;
|
||||
case SH_OBJECT_CODE_LENGTH:
|
||||
*params = compiler->getInfoSink().obj.size() + 1;
|
||||
break;
|
||||
case SH_ACTIVE_UNIFORMS:
|
||||
*params = compiler->getUniforms().size();
|
||||
break;
|
||||
case SH_ACTIVE_UNIFORM_MAX_LENGTH:
|
||||
*params = getVariableMaxLength(compiler->getUniforms());
|
||||
break;
|
||||
case SH_ACTIVE_ATTRIBUTES:
|
||||
*params = compiler->getAttribs().size();
|
||||
break;
|
||||
case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
|
||||
*params = getVariableMaxLength(compiler->getAttribs());
|
||||
break;
|
||||
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Return any compiler log of messages for the application.
|
||||
//
|
||||
const char* ShGetInfoLog(const ShHandle handle)
|
||||
void ShGetInfoLog(const ShHandle handle, char* infoLog)
|
||||
{
|
||||
if (!InitThread())
|
||||
return 0;
|
||||
|
||||
if (handle == 0)
|
||||
return 0;
|
||||
if (!handle || !infoLog)
|
||||
return;
|
||||
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
|
||||
TInfoSink* infoSink = 0;
|
||||
TCompiler* compiler = base->getAsCompiler();
|
||||
if (!compiler) return;
|
||||
|
||||
if (base->getAsCompiler())
|
||||
infoSink = &(base->getAsCompiler()->getInfoSink());
|
||||
|
||||
infoSink->info << infoSink->debug.c_str();
|
||||
return infoSink->info.c_str();
|
||||
TInfoSink& infoSink = compiler->getInfoSink();
|
||||
strcpy(infoLog, infoSink.info.c_str());
|
||||
}
|
||||
|
||||
//
|
||||
// Return any object code.
|
||||
//
|
||||
const char* ShGetObjectCode(const ShHandle handle)
|
||||
void ShGetObjectCode(const ShHandle handle, char* objCode)
|
||||
{
|
||||
if (!InitThread())
|
||||
return 0;
|
||||
|
||||
if (handle == 0)
|
||||
return 0;
|
||||
if (!handle || !objCode)
|
||||
return;
|
||||
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
|
||||
TInfoSink* infoSink;
|
||||
TCompiler* compiler = base->getAsCompiler();
|
||||
if (!compiler) return;
|
||||
|
||||
if (base->getAsCompiler())
|
||||
infoSink = &(base->getAsCompiler()->getInfoSink());
|
||||
|
||||
return infoSink->obj.c_str();
|
||||
TInfoSink& infoSink = compiler->getInfoSink();
|
||||
strcpy(objCode, infoSink.obj.c_str());
|
||||
}
|
||||
|
||||
void ShGetActiveAttrib(const ShHandle handle,
|
||||
int index,
|
||||
int* length,
|
||||
int* size,
|
||||
ShDataType* type,
|
||||
char* name)
|
||||
{
|
||||
getVariableInfo(SH_ACTIVE_ATTRIBUTES,
|
||||
handle, index, length, size, type, name);
|
||||
}
|
||||
|
||||
void ShGetActiveUniform(const ShHandle handle,
|
||||
int index,
|
||||
int* length,
|
||||
int* size,
|
||||
ShDataType* type,
|
||||
char* name)
|
||||
{
|
||||
getVariableInfo(SH_ACTIVE_UNIFORMS,
|
||||
handle, index, length, size, type, name);
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ int TType::getStructSize() const
|
|||
}
|
||||
|
||||
if (structureSize == 0)
|
||||
for (TTypeList::iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
|
||||
for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
|
||||
structureSize += ((*tl).type)->getObjectSize();
|
||||
|
||||
return structureSize;
|
||||
|
@ -140,6 +140,22 @@ void TSymbolTableLevel::relateToOperator(const char* name, TOperator op)
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Change all function entries in the table with the non-mangled name
|
||||
// to be related to the provided built-in extension. This is a low
|
||||
// performance operation, and only intended for symbol tables that
|
||||
// live across a large number of compiles.
|
||||
//
|
||||
void TSymbolTableLevel::relateToExtension(const char* name, const TString& ext)
|
||||
{
|
||||
for (tLevel::iterator it = level.begin(); it != level.end(); ++it) {
|
||||
if (it->second->isFunction()) {
|
||||
TFunction* function = static_cast<TFunction*>(it->second);
|
||||
if (function->getName() == name)
|
||||
function->relateToExtension(ext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TSymbol::TSymbol(const TSymbol& copyOf)
|
||||
{
|
||||
|
|
|
@ -76,7 +76,7 @@ public:
|
|||
TType& getType() { return type; }
|
||||
const TType& getType() const { return type; }
|
||||
bool isUserType() const { return userType; }
|
||||
void changeQualifier(TQualifier qualifier) { type.changeQualifier(qualifier); }
|
||||
void setQualifier(TQualifier qualifier) { type.setQualifier(qualifier); }
|
||||
void updateArrayInformationType(TType *t) { arrayInformationType = t; }
|
||||
TType* getArrayInformationType() { return arrayInformationType; }
|
||||
|
||||
|
@ -156,14 +156,18 @@ public:
|
|||
|
||||
const TString& getMangledName() const { return mangledName; }
|
||||
const TType& getReturnType() const { return returnType; }
|
||||
|
||||
void relateToOperator(TOperator o) { op = o; }
|
||||
TOperator getBuiltInOp() const { return op; }
|
||||
|
||||
void relateToExtension(const TString& ext) { extension = ext; }
|
||||
const TString& getExtension() const { return extension; }
|
||||
|
||||
void setDefined() { defined = true; }
|
||||
bool isDefined() { return defined; }
|
||||
|
||||
int getParamCount() const { return static_cast<int>(parameters.size()); }
|
||||
TParameter& operator [](int i) { return parameters[i]; }
|
||||
const TParameter& operator [](int i) const { return parameters[i]; }
|
||||
int getParamCount() const { return static_cast<int>(parameters.size()); }
|
||||
const TParameter& getParam(int i) const { return parameters[i]; }
|
||||
|
||||
virtual void dump(TInfoSink &infoSink) const;
|
||||
TFunction(const TFunction&, TStructureMap& remapper);
|
||||
|
@ -175,6 +179,7 @@ protected:
|
|||
TType returnType;
|
||||
TString mangledName;
|
||||
TOperator op;
|
||||
TString extension;
|
||||
bool defined;
|
||||
};
|
||||
|
||||
|
@ -221,6 +226,7 @@ public:
|
|||
}
|
||||
|
||||
void relateToOperator(const char* name, TOperator op);
|
||||
void relateToExtension(const char* name, const TString& ext);
|
||||
void dump(TInfoSink &infoSink) const;
|
||||
TSymbolTableLevel* clone(TStructureMap& remapper);
|
||||
|
||||
|
@ -289,8 +295,16 @@ public:
|
|||
return symbol;
|
||||
}
|
||||
|
||||
TSymbolTableLevel* getGlobalLevel() { assert(table.size() >= 2); return table[1]; }
|
||||
void relateToOperator(const char* name, TOperator op) { table[0]->relateToOperator(name, op); }
|
||||
TSymbolTableLevel* getGlobalLevel() {
|
||||
assert(table.size() >= 2);
|
||||
return table[1];
|
||||
}
|
||||
void relateToOperator(const char* name, TOperator op) {
|
||||
table[0]->relateToOperator(name, op);
|
||||
}
|
||||
void relateToExtension(const char* name, const TString& ext) {
|
||||
table[0]->relateToExtension(name, ext);
|
||||
}
|
||||
int getMaxSymbolId() { return uniqueId; }
|
||||
void dump(TInfoSink &infoSink) const;
|
||||
void copyTable(const TSymbolTable& copyOf);
|
||||
|
|
|
@ -8,13 +8,11 @@
|
|||
|
||||
#include "compiler/OutputGLSL.h"
|
||||
|
||||
TranslatorGLSL::TranslatorGLSL(EShLanguage lang, EShSpec spec)
|
||||
: TCompiler(lang, spec) {
|
||||
TranslatorGLSL::TranslatorGLSL(ShShaderType type, ShShaderSpec spec)
|
||||
: TCompiler(type, spec) {
|
||||
}
|
||||
|
||||
bool TranslatorGLSL::compile(TIntermNode* root) {
|
||||
TOutputGLSL outputGLSL(infoSink.obj);
|
||||
void TranslatorGLSL::translate(TIntermNode* root) {
|
||||
TOutputGLSL outputGLSL(getInfoSink().obj);
|
||||
root->traverse(&outputGLSL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -11,8 +11,10 @@
|
|||
|
||||
class TranslatorGLSL : public TCompiler {
|
||||
public:
|
||||
TranslatorGLSL(EShLanguage lang, EShSpec spec);
|
||||
virtual bool compile(TIntermNode* root);
|
||||
TranslatorGLSL(ShShaderType type, ShShaderSpec spec);
|
||||
|
||||
protected:
|
||||
virtual void translate(TIntermNode* root);
|
||||
};
|
||||
|
||||
#endif // COMPILER_TRANSLATORGLSL_H_
|
||||
|
|
|
@ -8,17 +8,15 @@
|
|||
|
||||
#include "compiler/OutputHLSL.h"
|
||||
|
||||
TranslatorHLSL::TranslatorHLSL(EShLanguage lang, EShSpec spec)
|
||||
: TCompiler(lang, spec)
|
||||
TranslatorHLSL::TranslatorHLSL(ShShaderType type, ShShaderSpec spec)
|
||||
: TCompiler(type, spec)
|
||||
{
|
||||
}
|
||||
|
||||
bool TranslatorHLSL::compile(TIntermNode *root)
|
||||
void TranslatorHLSL::translate(TIntermNode *root)
|
||||
{
|
||||
TParseContext& parseContext = *GetGlobalParseContext();
|
||||
sh::OutputHLSL outputHLSL(parseContext);
|
||||
|
||||
outputHLSL.output();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -11,8 +11,10 @@
|
|||
|
||||
class TranslatorHLSL : public TCompiler {
|
||||
public:
|
||||
TranslatorHLSL(EShLanguage lang, EShSpec spec);
|
||||
virtual bool compile(TIntermNode* root);
|
||||
TranslatorHLSL(ShShaderType type, ShShaderSpec spec);
|
||||
|
||||
protected:
|
||||
virtual void translate(TIntermNode* root);
|
||||
};
|
||||
|
||||
#endif // COMPILER_TRANSLATORHLSL_H_
|
||||
|
|
|
@ -82,28 +82,27 @@ typedef TMap<TTypeList*, TTypeList*>::iterator TStructureMapIterator;
|
|||
class TType {
|
||||
public:
|
||||
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
|
||||
explicit TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) :
|
||||
type(t), precision(p), qualifier(q), size(s), matrix(m), array(a), arraySize(0),
|
||||
structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0)
|
||||
{ }
|
||||
TType() {}
|
||||
TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) :
|
||||
type(t), precision(p), qualifier(q), size(s), matrix(m), array(a), arraySize(0),
|
||||
structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0)
|
||||
{
|
||||
}
|
||||
explicit TType(const TPublicType &p) :
|
||||
type(p.type), precision(p.precision), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize),
|
||||
structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0)
|
||||
{
|
||||
if (p.userDef) {
|
||||
structure = p.userDef->getStruct();
|
||||
typeName = NewPoolTString(p.userDef->getTypeName().c_str());
|
||||
}
|
||||
}
|
||||
explicit TType(TTypeList* userDef, const TString& n, TPrecision p = EbpUndefined) :
|
||||
type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0),
|
||||
structure(userDef), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0) {
|
||||
typeName = NewPoolTString(n.c_str());
|
||||
}
|
||||
explicit TType() {}
|
||||
virtual ~TType() {}
|
||||
|
||||
TType(const TType& type) { *this = type; }
|
||||
type(p.type), precision(p.precision), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize),
|
||||
structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0)
|
||||
{
|
||||
if (p.userDef) {
|
||||
structure = p.userDef->getStruct();
|
||||
typeName = NewPoolTString(p.userDef->getTypeName().c_str());
|
||||
}
|
||||
}
|
||||
TType(TTypeList* userDef, const TString& n, TPrecision p = EbpUndefined) :
|
||||
type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0),
|
||||
structure(userDef), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0)
|
||||
{
|
||||
typeName = NewPoolTString(n.c_str());
|
||||
}
|
||||
|
||||
void copyType(const TType& copyOf, TStructureMap& remapper)
|
||||
{
|
||||
|
@ -157,77 +156,19 @@ public:
|
|||
return newType;
|
||||
}
|
||||
|
||||
virtual void setType(TBasicType t, int s, bool m, bool a, int aS = 0)
|
||||
{ type = t; size = s; matrix = m; array = a; arraySize = aS; }
|
||||
virtual void setType(TBasicType t, int s, bool m, TType* userDef = 0)
|
||||
{ type = t;
|
||||
size = s;
|
||||
matrix = m;
|
||||
if (userDef)
|
||||
structure = userDef->getStruct();
|
||||
// leave array information intact.
|
||||
}
|
||||
virtual void setTypeName(const TString& n) { typeName = NewPoolTString(n.c_str()); }
|
||||
virtual void setFieldName(const TString& n) { fieldName = NewPoolTString(n.c_str()); }
|
||||
virtual const TString& getTypeName() const
|
||||
{
|
||||
assert(typeName);
|
||||
return *typeName;
|
||||
}
|
||||
TBasicType getBasicType() const { return type; }
|
||||
void setBasicType(TBasicType t) { type = t; }
|
||||
|
||||
virtual const TString& getFieldName() const
|
||||
{
|
||||
assert(fieldName);
|
||||
return *fieldName;
|
||||
}
|
||||
TPrecision getPrecision() const { return precision; }
|
||||
void setPrecision(TPrecision p) { precision = p; }
|
||||
|
||||
virtual TBasicType getBasicType() const { return type; }
|
||||
virtual TPrecision getPrecision() const { return precision; }
|
||||
virtual TQualifier getQualifier() const { return qualifier; }
|
||||
virtual void changePrecision(TPrecision p) { precision = p; }
|
||||
virtual void changeQualifier(TQualifier q) { qualifier = q; }
|
||||
TQualifier getQualifier() const { return qualifier; }
|
||||
void setQualifier(TQualifier q) { qualifier = q; }
|
||||
|
||||
// One-dimensional size of single instance type
|
||||
virtual int getNominalSize() const { return size; }
|
||||
|
||||
// Full-dimensional size of single instance of type
|
||||
virtual int getInstanceSize() const
|
||||
{
|
||||
if (matrix)
|
||||
return size * size;
|
||||
else
|
||||
return size;
|
||||
}
|
||||
|
||||
virtual bool isMatrix() const { return matrix ? true : false; }
|
||||
virtual bool isArray() const { return array ? true : false; }
|
||||
bool isField() const { return fieldName != 0; }
|
||||
int getArraySize() const { return arraySize; }
|
||||
void setArraySize(int s) { array = true; arraySize = s; }
|
||||
void setMaxArraySize (int s) { maxArraySize = s; }
|
||||
int getMaxArraySize () const { return maxArraySize; }
|
||||
void clearArrayness() { array = false; arraySize = 0; maxArraySize = 0; }
|
||||
void setArrayInformationType(TType* t) { arrayInformationType = t; }
|
||||
TType* getArrayInformationType() const { return arrayInformationType; }
|
||||
virtual bool isVector() const { return size > 1 && !matrix; }
|
||||
virtual bool isScalar() const { return size == 1 && !matrix && !structure; }
|
||||
static const char* getBasicString(TBasicType t) {
|
||||
switch (t) {
|
||||
case EbtVoid: return "void"; break;
|
||||
case EbtFloat: return "float"; break;
|
||||
case EbtInt: return "int"; break;
|
||||
case EbtBool: return "bool"; break;
|
||||
case EbtSampler2D: return "sampler2D"; break;
|
||||
case EbtSamplerCube: return "samplerCube"; break;
|
||||
case EbtStruct: return "structure"; break;
|
||||
default: return "unknown type";
|
||||
}
|
||||
}
|
||||
const char* getBasicString() const { return TType::getBasicString(type); }
|
||||
const char* getPrecisionString() const { return ::getPrecisionString(precision); }
|
||||
const char* getQualifierString() const { return ::getQualifierString(qualifier); }
|
||||
TTypeList* getStruct() { return structure; }
|
||||
|
||||
int getNominalSize() const { return size; }
|
||||
void setNominalSize(int s) { size = s; }
|
||||
// Full size of single instance of type
|
||||
int getObjectSize() const
|
||||
{
|
||||
int totalSize;
|
||||
|
@ -245,7 +186,45 @@ public:
|
|||
return totalSize;
|
||||
}
|
||||
|
||||
bool isMatrix() const { return matrix ? true : false; }
|
||||
void setMatrix(bool m) { matrix = m; }
|
||||
|
||||
bool isArray() const { return array ? true : false; }
|
||||
int getArraySize() const { return arraySize; }
|
||||
void setArraySize(int s) { array = true; arraySize = s; }
|
||||
int getMaxArraySize () const { return maxArraySize; }
|
||||
void setMaxArraySize (int s) { maxArraySize = s; }
|
||||
void clearArrayness() { array = false; arraySize = 0; maxArraySize = 0; }
|
||||
void setArrayInformationType(TType* t) { arrayInformationType = t; }
|
||||
TType* getArrayInformationType() const { return arrayInformationType; }
|
||||
|
||||
bool isVector() const { return size > 1 && !matrix; }
|
||||
bool isScalar() const { return size == 1 && !matrix && !structure; }
|
||||
|
||||
TTypeList* getStruct() const { return structure; }
|
||||
void setStruct(TTypeList* s) { structure = s; }
|
||||
|
||||
const TString& getTypeName() const
|
||||
{
|
||||
assert(typeName);
|
||||
return *typeName;
|
||||
}
|
||||
void setTypeName(const TString& n)
|
||||
{
|
||||
typeName = NewPoolTString(n.c_str());
|
||||
}
|
||||
|
||||
bool isField() const { return fieldName != 0; }
|
||||
const TString& getFieldName() const
|
||||
{
|
||||
assert(fieldName);
|
||||
return *fieldName;
|
||||
}
|
||||
void setFieldName(const TString& n)
|
||||
{
|
||||
fieldName = NewPoolTString(n.c_str());
|
||||
}
|
||||
|
||||
TString& getMangledName() {
|
||||
if (!mangled) {
|
||||
mangled = NewPoolTString("");
|
||||
|
@ -255,6 +234,7 @@ public:
|
|||
|
||||
return *mangled;
|
||||
}
|
||||
|
||||
bool sameElementType(const TType& right) const {
|
||||
return type == right.type &&
|
||||
size == right.size &&
|
||||
|
@ -282,6 +262,10 @@ public:
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* getBasicString() const { return ::getBasicString(type); }
|
||||
const char* getPrecisionString() const { return ::getPrecisionString(precision); }
|
||||
const char* getQualifierString() const { return ::getQualifierString(qualifier); }
|
||||
TString getCompleteString() const;
|
||||
|
||||
protected:
|
||||
|
@ -295,11 +279,12 @@ protected:
|
|||
unsigned int matrix : 1;
|
||||
unsigned int array : 1;
|
||||
int arraySize;
|
||||
int maxArraySize;
|
||||
TType* arrayInformationType;
|
||||
|
||||
TTypeList* structure; // 0 unless this is a struct
|
||||
mutable int structureSize;
|
||||
int maxArraySize;
|
||||
TType* arrayInformationType;
|
||||
|
||||
TString *fieldName; // for structure field names
|
||||
TString *mangled;
|
||||
TString *typeName; // for structure field type name
|
||||
|
|
|
@ -0,0 +1,210 @@
|
|||
//
|
||||
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#include "compiler/VariableInfo.h"
|
||||
|
||||
static TString arrayBrackets(int index)
|
||||
{
|
||||
TStringStream stream;
|
||||
stream << "[" << index << "]";
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
// Returns the data type for an attribute or uniform.
|
||||
static ShDataType getVariableDataType(const TType& type)
|
||||
{
|
||||
switch (type.getBasicType()) {
|
||||
case EbtFloat:
|
||||
if (type.isMatrix()) {
|
||||
switch (type.getNominalSize()) {
|
||||
case 2: return SH_FLOAT_MAT2;
|
||||
case 3: return SH_FLOAT_MAT3;
|
||||
case 4: return SH_FLOAT_MAT4;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
} else if (type.isVector()) {
|
||||
switch (type.getNominalSize()) {
|
||||
case 2: return SH_FLOAT_VEC2;
|
||||
case 3: return SH_FLOAT_VEC3;
|
||||
case 4: return SH_FLOAT_VEC4;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
} else {
|
||||
return SH_FLOAT;
|
||||
}
|
||||
case EbtInt:
|
||||
if (type.isMatrix()) {
|
||||
UNREACHABLE();
|
||||
} else if (type.isVector()) {
|
||||
switch (type.getNominalSize()) {
|
||||
case 2: return SH_INT_VEC2;
|
||||
case 3: return SH_INT_VEC3;
|
||||
case 4: return SH_INT_VEC4;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
} else {
|
||||
return SH_INT;
|
||||
}
|
||||
case EbtBool:
|
||||
if (type.isMatrix()) {
|
||||
UNREACHABLE();
|
||||
} else if (type.isVector()) {
|
||||
switch (type.getNominalSize()) {
|
||||
case 2: return SH_BOOL_VEC2;
|
||||
case 3: return SH_BOOL_VEC3;
|
||||
case 4: return SH_BOOL_VEC4;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
} else {
|
||||
return SH_BOOL;
|
||||
}
|
||||
case EbtSampler2D: return SH_SAMPLER_2D;
|
||||
case EbtSamplerCube: return SH_SAMPLER_CUBE;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
return SH_NONE;
|
||||
}
|
||||
|
||||
static void getBuiltInVariableInfo(const TType& type,
|
||||
const TString& name,
|
||||
TVariableInfoList& infoList);
|
||||
static void getUserDefinedVariableInfo(const TType& type,
|
||||
const TString& name,
|
||||
TVariableInfoList& infoList);
|
||||
|
||||
// Returns info for an attribute or uniform.
|
||||
static void getVariableInfo(const TType& type,
|
||||
const TString& name,
|
||||
TVariableInfoList& infoList)
|
||||
{
|
||||
if (type.getBasicType() == EbtStruct) {
|
||||
if (type.isArray()) {
|
||||
for (int i = 0; i < type.getArraySize(); ++i) {
|
||||
TString lname = name + arrayBrackets(i);
|
||||
getUserDefinedVariableInfo(type, lname, infoList);
|
||||
}
|
||||
} else {
|
||||
getUserDefinedVariableInfo(type, name, infoList);
|
||||
}
|
||||
} else {
|
||||
getBuiltInVariableInfo(type, name, infoList);
|
||||
}
|
||||
}
|
||||
|
||||
void getBuiltInVariableInfo(const TType& type,
|
||||
const TString& name,
|
||||
TVariableInfoList& infoList)
|
||||
{
|
||||
ASSERT(type.getBasicType() != EbtStruct);
|
||||
|
||||
TVariableInfo varInfo;
|
||||
if (type.isArray()) {
|
||||
varInfo.name = (name + "[0]").c_str();
|
||||
varInfo.size = type.getArraySize();
|
||||
} else {
|
||||
varInfo.name = name.c_str();
|
||||
varInfo.size = 1;
|
||||
}
|
||||
varInfo.type = getVariableDataType(type);
|
||||
infoList.push_back(varInfo);
|
||||
}
|
||||
|
||||
void getUserDefinedVariableInfo(const TType& type,
|
||||
const TString& name,
|
||||
TVariableInfoList& infoList)
|
||||
{
|
||||
ASSERT(type.getBasicType() == EbtStruct);
|
||||
|
||||
TString lname = name + ".";
|
||||
const TTypeList* structure = type.getStruct();
|
||||
for (size_t i = 0; i < structure->size(); ++i) {
|
||||
const TType* fieldType = (*structure)[i].type;
|
||||
getVariableInfo(*fieldType,
|
||||
lname + fieldType->getFieldName(),
|
||||
infoList);
|
||||
}
|
||||
}
|
||||
|
||||
CollectAttribsUniforms::CollectAttribsUniforms(TVariableInfoList& attribs,
|
||||
TVariableInfoList& uniforms)
|
||||
: mAttribs(attribs),
|
||||
mUniforms(uniforms)
|
||||
{
|
||||
}
|
||||
|
||||
// We are only interested in attribute and uniform variable declaration.
|
||||
void CollectAttribsUniforms::visitSymbol(TIntermSymbol*)
|
||||
{
|
||||
}
|
||||
|
||||
void CollectAttribsUniforms::visitConstantUnion(TIntermConstantUnion*)
|
||||
{
|
||||
}
|
||||
|
||||
bool CollectAttribsUniforms::visitBinary(Visit, TIntermBinary*)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CollectAttribsUniforms::visitUnary(Visit, TIntermUnary*)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CollectAttribsUniforms::visitSelection(Visit, TIntermSelection*)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CollectAttribsUniforms::visitAggregate(Visit, TIntermAggregate* node)
|
||||
{
|
||||
bool visitChildren = false;
|
||||
|
||||
switch (node->getOp())
|
||||
{
|
||||
case EOpSequence:
|
||||
// We need to visit sequence children to get to variable declarations.
|
||||
visitChildren = true;
|
||||
break;
|
||||
case EOpDeclaration: {
|
||||
const TIntermSequence& sequence = node->getSequence();
|
||||
TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier();
|
||||
if (qualifier == EvqAttribute || qualifier == EvqUniform)
|
||||
{
|
||||
TVariableInfoList& infoList = qualifier == EvqAttribute ?
|
||||
mAttribs : mUniforms;
|
||||
for (TIntermSequence::const_iterator i = sequence.begin();
|
||||
i != sequence.end(); ++i)
|
||||
{
|
||||
const TIntermSymbol* variable = (*i)->getAsSymbolNode();
|
||||
// The only case in which the sequence will not contain a
|
||||
// TIntermSymbol node is initialization. It will contain a
|
||||
// TInterBinary node in that case. Since attributes and unifroms
|
||||
// cannot be initialized in a shader, we must have only
|
||||
// TIntermSymbol nodes in the sequence.
|
||||
ASSERT(variable != NULL);
|
||||
getVariableInfo(variable->getType(), variable->getSymbol(),
|
||||
infoList);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
|
||||
return visitChildren;
|
||||
}
|
||||
|
||||
bool CollectAttribsUniforms::visitLoop(Visit, TIntermLoop*)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CollectAttribsUniforms::visitBranch(Visit, TIntermBranch*)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
//
|
||||
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#include "GLSLANG/ShaderLang.h"
|
||||
#include "compiler/intermediate.h"
|
||||
|
||||
// Provides information about a variable.
|
||||
// It is currently being used to store info about active attribs and uniforms.
|
||||
struct TVariableInfo {
|
||||
TPersistString name;
|
||||
ShDataType type;
|
||||
int size;
|
||||
};
|
||||
typedef std::vector<TVariableInfo> TVariableInfoList;
|
||||
|
||||
// Traverses intermediate tree to collect all attributes and uniforms.
|
||||
class CollectAttribsUniforms : public TIntermTraverser {
|
||||
public:
|
||||
CollectAttribsUniforms(TVariableInfoList& attribs,
|
||||
TVariableInfoList& uniforms);
|
||||
|
||||
virtual void visitSymbol(TIntermSymbol*);
|
||||
virtual void visitConstantUnion(TIntermConstantUnion*);
|
||||
virtual bool visitBinary(Visit, TIntermBinary*);
|
||||
virtual bool visitUnary(Visit, TIntermUnary*);
|
||||
virtual bool visitSelection(Visit, TIntermSelection*);
|
||||
virtual bool visitAggregate(Visit, TIntermAggregate*);
|
||||
virtual bool visitLoop(Visit, TIntermLoop*);
|
||||
virtual bool visitBranch(Visit, TIntermBranch*);
|
||||
|
||||
private:
|
||||
TVariableInfoList& mAttribs;
|
||||
TVariableInfoList& mUniforms;
|
||||
};
|
||||
|
|
@ -274,7 +274,7 @@ int yy_input(char* buf, int max_size)
|
|||
//
|
||||
// Returns 0 for success, as per yyparse().
|
||||
//
|
||||
int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext& parseContextLocal)
|
||||
int PaParseStrings(const char* const argv[], const int strLen[], int argc, TParseContext& parseContextLocal)
|
||||
{
|
||||
int argv0len;
|
||||
|
||||
|
|
|
@ -40,48 +40,26 @@ compiler/tools. Remove it when we can exclusively use the newer version.
|
|||
#define YY_DECL int yylex(YYSTYPE* pyylval, void* parseContextLocal)
|
||||
extern void yyerror(const char*);
|
||||
|
||||
#define FRAG_VERT_ONLY(S, L) { \
|
||||
if (parseContext->language != EShLangFragment && \
|
||||
parseContext->language != EShLangVertex) { \
|
||||
parseContext->error(L, " supported in vertex/fragment shaders only ", S, "", ""); \
|
||||
parseContext->recover(); \
|
||||
} \
|
||||
#define FRAG_VERT_ONLY(S, L) { \
|
||||
if (parseContext->shaderType != SH_FRAGMENT_SHADER && \
|
||||
parseContext->shaderType != SH_VERTEX_SHADER) { \
|
||||
parseContext->error(L, " supported in vertex/fragment shaders only ", S, "", ""); \
|
||||
parseContext->recover(); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define VERTEX_ONLY(S, L) { \
|
||||
if (parseContext->language != EShLangVertex) { \
|
||||
parseContext->error(L, " supported in vertex shaders only ", S, "", ""); \
|
||||
parseContext->recover(); \
|
||||
} \
|
||||
#define VERTEX_ONLY(S, L) { \
|
||||
if (parseContext->shaderType != SH_VERTEX_SHADER) { \
|
||||
parseContext->error(L, " supported in vertex shaders only ", S, "", ""); \
|
||||
parseContext->recover(); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define FRAG_ONLY(S, L) { \
|
||||
if (parseContext->language != EShLangFragment) { \
|
||||
parseContext->error(L, " supported in fragment shaders only ", S, "", ""); \
|
||||
parseContext->recover(); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define PACK_ONLY(S, L) { \
|
||||
if (parseContext->language != EShLangPack) { \
|
||||
parseContext->error(L, " supported in pack shaders only ", S, "", ""); \
|
||||
parseContext->recover(); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define UNPACK_ONLY(S, L) { \
|
||||
if (parseContext->language != EShLangUnpack) { \
|
||||
parseContext->error(L, " supported in unpack shaders only ", S, "", ""); \
|
||||
parseContext->recover(); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define PACK_UNPACK_ONLY(S, L) { \
|
||||
if (parseContext->language != EShLangUnpack && \
|
||||
parseContext->language != EShLangPack) { \
|
||||
parseContext->error(L, " supported in pack/unpack shaders only ", S, "", ""); \
|
||||
parseContext->recover(); \
|
||||
} \
|
||||
#define FRAG_ONLY(S, L) { \
|
||||
if (parseContext->shaderType != SH_FRAGMENT_SHADER) { \
|
||||
parseContext->error(L, " supported in fragment shaders only ", S, "", ""); \
|
||||
parseContext->recover(); \
|
||||
} \
|
||||
}
|
||||
%}
|
||||
%union {
|
||||
|
@ -311,7 +289,7 @@ postfix_expression
|
|||
$$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary, $1->getNominalSize(), $1->isMatrix()));
|
||||
|
||||
if ($1->getType().getQualifier() == EvqConst)
|
||||
$$->getTypePointer()->changeQualifier(EvqConst);
|
||||
$$->getTypePointer()->setQualifier(EvqConst);
|
||||
} else if ($1->isMatrix() && $1->getType().getQualifier() == EvqConst)
|
||||
$$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqConst, $1->getNominalSize()));
|
||||
else if ($1->isMatrix())
|
||||
|
@ -389,7 +367,7 @@ postfix_expression
|
|||
}
|
||||
} else if ($1->getBasicType() == EbtStruct) {
|
||||
bool fieldFound = false;
|
||||
TTypeList* fields = $1->getType().getStruct();
|
||||
const TTypeList* fields = $1->getType().getStruct();
|
||||
if (fields == 0) {
|
||||
parseContext->error($2.line, "structure has no fields", "Internal Error", "");
|
||||
parseContext->recover();
|
||||
|
@ -413,7 +391,7 @@ postfix_expression
|
|||
$$->setType(*(*fields)[i].type);
|
||||
// change the qualifier of the return type, not of the structure field
|
||||
// as the structure definition is shared between various structures.
|
||||
$$->getTypePointer()->changeQualifier(EvqConst);
|
||||
$$->getTypePointer()->setQualifier(EvqConst);
|
||||
}
|
||||
} else {
|
||||
ConstantUnion *unionArray = new ConstantUnion[1];
|
||||
|
@ -501,9 +479,12 @@ function_call
|
|||
fnCandidate = parseContext->findFunction($1.line, fnCall, &builtIn);
|
||||
if (fnCandidate) {
|
||||
//
|
||||
// A declared function. But, it might still map to a built-in
|
||||
// operation.
|
||||
// A declared function.
|
||||
//
|
||||
if (builtIn && !fnCandidate->getExtension().empty() &&
|
||||
parseContext->extensionErrorCheck($1.line, fnCandidate->getExtension())) {
|
||||
parseContext->recover();
|
||||
}
|
||||
op = fnCandidate->getBuiltInOp();
|
||||
if (builtIn && op != EOpNull) {
|
||||
//
|
||||
|
@ -537,16 +518,14 @@ function_call
|
|||
$$->getAsAggregate()->setName(fnCandidate->getMangledName());
|
||||
|
||||
TQualifier qual;
|
||||
TQualifierList& qualifierList = $$->getAsAggregate()->getQualifier();
|
||||
for (int i = 0; i < fnCandidate->getParamCount(); ++i) {
|
||||
qual = (*fnCandidate)[i].type->getQualifier();
|
||||
qual = fnCandidate->getParam(i).type->getQualifier();
|
||||
if (qual == EvqOut || qual == EvqInOut) {
|
||||
if (parseContext->lValueErrorCheck($$->getLine(), "assign", $$->getAsAggregate()->getSequence()[i]->getAsTyped())) {
|
||||
parseContext->error($1.intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error", "");
|
||||
parseContext->recover();
|
||||
}
|
||||
}
|
||||
qualifierList.push_back(qual);
|
||||
}
|
||||
}
|
||||
$$->setType(fnCandidate->getReturnType());
|
||||
|
@ -625,19 +604,16 @@ function_identifier
|
|||
// Constructor
|
||||
//
|
||||
if ($1.array) {
|
||||
if (parseContext->extensionErrorCheck($1.line, "GL_3DL_array_objects")) {
|
||||
parseContext->recover();
|
||||
$1.setArray(false);
|
||||
}
|
||||
// Constructors for arrays are not allowed.
|
||||
parseContext->error($1.line, "cannot construct this type", "array", "");
|
||||
parseContext->recover();
|
||||
$1.setArray(false);
|
||||
}
|
||||
|
||||
TOperator op = EOpNull;
|
||||
if ($1.userDef) {
|
||||
TString tempString = "";
|
||||
TType type($1);
|
||||
TFunction *function = new TFunction(&tempString, type, EOpConstructStruct);
|
||||
$$ = function;
|
||||
op = EOpConstructStruct;
|
||||
} else {
|
||||
TOperator op = EOpNull;
|
||||
switch ($1.type) {
|
||||
case EbtFloat:
|
||||
if ($1.matrix) {
|
||||
|
@ -671,18 +647,19 @@ function_identifier
|
|||
case 4: FRAG_VERT_ONLY("bvec4", $1.line); op = EOpConstructBVec4; break;
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
if (op == EOpNull) {
|
||||
parseContext->error($1.line, "cannot construct this type", TType::getBasicString($1.type), "");
|
||||
parseContext->error($1.line, "cannot construct this type", getBasicString($1.type), "");
|
||||
parseContext->recover();
|
||||
$1.type = EbtFloat;
|
||||
op = EOpConstructFloat;
|
||||
}
|
||||
TString tempString = "";
|
||||
TType type($1);
|
||||
TFunction *function = new TFunction(&tempString, type, op);
|
||||
$$ = function;
|
||||
}
|
||||
TString tempString;
|
||||
TType type($1);
|
||||
TFunction *function = new TFunction(&tempString, type, op);
|
||||
$$ = function;
|
||||
}
|
||||
| IDENTIFIER {
|
||||
if (parseContext->reservedErrorCheck($1.line, *$1.string))
|
||||
|
@ -851,8 +828,7 @@ equality_expression
|
|||
ConstantUnion *unionArray = new ConstantUnion[1];
|
||||
unionArray->setBConst(false);
|
||||
$$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
|
||||
} else if (($1->isArray() || $3->isArray()) && parseContext->extensionErrorCheck($2.line, "GL_3DL_array_objects"))
|
||||
parseContext->recover();
|
||||
}
|
||||
}
|
||||
| equality_expression NE_OP relational_expression {
|
||||
$$ = parseContext->intermediate.addBinaryMath(EOpNotEqual, $1, $3, $2.line, parseContext->symbolTable);
|
||||
|
@ -862,8 +838,7 @@ equality_expression
|
|||
ConstantUnion *unionArray = new ConstantUnion[1];
|
||||
unionArray->setBConst(false);
|
||||
$$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
|
||||
} else if (($1->isArray() || $3->isArray()) && parseContext->extensionErrorCheck($2.line, "GL_3DL_array_objects"))
|
||||
parseContext->recover();
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -949,8 +924,7 @@ assignment_expression
|
|||
parseContext->assignError($2.line, "assign", $1->getCompleteString(), $3->getCompleteString());
|
||||
parseContext->recover();
|
||||
$$ = $1;
|
||||
} else if (($1->isArray() || $3->isArray()) && parseContext->extensionErrorCheck($2.line, "GL_3DL_array_objects"))
|
||||
parseContext->recover();
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -994,7 +968,7 @@ declaration
|
|||
|
||||
for (int i = 0; i < function.getParamCount(); i++)
|
||||
{
|
||||
TParameter ¶m = function[i];
|
||||
const TParameter ¶m = function.getParam(i);
|
||||
if (param.name != 0)
|
||||
{
|
||||
TVariable *variable = new TVariable(param.name, *param.type);
|
||||
|
@ -1007,12 +981,12 @@ declaration
|
|||
}
|
||||
}
|
||||
|
||||
prototype->setOperator(EOpPrototype);
|
||||
prototype->setOp(EOpPrototype);
|
||||
$$ = prototype;
|
||||
}
|
||||
| init_declarator_list SEMICOLON {
|
||||
if ($1.intermAggregate)
|
||||
$1.intermAggregate->setOperator(EOpDeclaration);
|
||||
$1.intermAggregate->setOp(EOpDeclaration);
|
||||
$$ = $1.intermAggregate;
|
||||
}
|
||||
| PRECISION precision_qualifier type_specifier_no_prec SEMICOLON {
|
||||
|
@ -1038,8 +1012,8 @@ function_prototype
|
|||
parseContext->recover();
|
||||
}
|
||||
for (int i = 0; i < prevDec->getParamCount(); ++i) {
|
||||
if ((*prevDec)[i].type->getQualifier() != (*$1)[i].type->getQualifier()) {
|
||||
parseContext->error($2.line, "overloaded functions must have the same parameter qualifiers", (*$1)[i].type->getQualifierString(), "");
|
||||
if (prevDec->getParam(i).type->getQualifier() != $1->getParam(i).type->getQualifier()) {
|
||||
parseContext->error($2.line, "overloaded functions must have the same parameter qualifiers", $1->getParam(i).type->getQualifierString(), "");
|
||||
parseContext->recover();
|
||||
}
|
||||
}
|
||||
|
@ -1272,75 +1246,6 @@ init_declarator_list
|
|||
$$.intermAggregate = parseContext->intermediate.growAggregate($1.intermNode, parseContext->intermediate.addSymbol(0, *$3.string, type, $3.line), $3.line);
|
||||
}
|
||||
}
|
||||
| init_declarator_list COMMA IDENTIFIER LEFT_BRACKET RIGHT_BRACKET EQUAL initializer {
|
||||
if (parseContext->structQualifierErrorCheck($3.line, $1.type))
|
||||
parseContext->recover();
|
||||
|
||||
$$ = $1;
|
||||
|
||||
TVariable* variable = 0;
|
||||
if (parseContext->arrayTypeErrorCheck($4.line, $1.type) || parseContext->arrayQualifierErrorCheck($4.line, $1.type))
|
||||
parseContext->recover();
|
||||
else {
|
||||
$1.type.setArray(true, $7->getType().getArraySize());
|
||||
if (parseContext->arrayErrorCheck($4.line, *$3.string, $1.type, variable))
|
||||
parseContext->recover();
|
||||
}
|
||||
|
||||
if (parseContext->extensionErrorCheck($$.line, "GL_3DL_array_objects"))
|
||||
parseContext->recover();
|
||||
else {
|
||||
TIntermNode* intermNode;
|
||||
if (!parseContext->executeInitializer($3.line, *$3.string, $1.type, $7, intermNode, variable)) {
|
||||
//
|
||||
// build the intermediate representation
|
||||
//
|
||||
if (intermNode)
|
||||
$$.intermAggregate = parseContext->intermediate.growAggregate($1.intermNode, intermNode, $6.line);
|
||||
else
|
||||
$$.intermAggregate = $1.intermAggregate;
|
||||
} else {
|
||||
parseContext->recover();
|
||||
$$.intermAggregate = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
| init_declarator_list COMMA IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer {
|
||||
if (parseContext->structQualifierErrorCheck($3.line, $1.type))
|
||||
parseContext->recover();
|
||||
|
||||
$$ = $1;
|
||||
|
||||
TVariable* variable = 0;
|
||||
if (parseContext->arrayTypeErrorCheck($4.line, $1.type) || parseContext->arrayQualifierErrorCheck($4.line, $1.type))
|
||||
parseContext->recover();
|
||||
else {
|
||||
int size;
|
||||
if (parseContext->arraySizeErrorCheck($4.line, $5, size))
|
||||
parseContext->recover();
|
||||
$1.type.setArray(true, size);
|
||||
if (parseContext->arrayErrorCheck($4.line, *$3.string, $1.type, variable))
|
||||
parseContext->recover();
|
||||
}
|
||||
|
||||
if (parseContext->extensionErrorCheck($$.line, "GL_3DL_array_objects"))
|
||||
parseContext->recover();
|
||||
else {
|
||||
TIntermNode* intermNode;
|
||||
if (!parseContext->executeInitializer($3.line, *$3.string, $1.type, $8, intermNode, variable)) {
|
||||
//
|
||||
// build the intermediate representation
|
||||
//
|
||||
if (intermNode)
|
||||
$$.intermAggregate = parseContext->intermediate.growAggregate($1.intermNode, intermNode, $7.line);
|
||||
else
|
||||
$$.intermAggregate = $1.intermAggregate;
|
||||
} else {
|
||||
parseContext->recover();
|
||||
$$.intermAggregate = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
| init_declarator_list COMMA IDENTIFIER EQUAL initializer {
|
||||
if (parseContext->structQualifierErrorCheck($3.line, $1.type))
|
||||
parseContext->recover();
|
||||
|
@ -1531,18 +1436,14 @@ fully_specified_type
|
|||
$$ = $1;
|
||||
|
||||
if ($1.array) {
|
||||
if (parseContext->extensionErrorCheck($1.line, "GL_3DL_array_objects")) {
|
||||
parseContext->recover();
|
||||
$1.setArray(false);
|
||||
}
|
||||
parseContext->error($1.line, "not supported", "first-class array", "");
|
||||
parseContext->recover();
|
||||
$1.setArray(false);
|
||||
}
|
||||
}
|
||||
| type_qualifier type_specifier {
|
||||
if ($2.array && parseContext->extensionErrorCheck($2.line, "GL_3DL_array_objects")) {
|
||||
parseContext->recover();
|
||||
$2.setArray(false);
|
||||
}
|
||||
if ($2.array && parseContext->arrayQualifierErrorCheck($2.line, $1)) {
|
||||
if ($2.array) {
|
||||
parseContext->error($2.line, "not supported", "first-class array", "");
|
||||
parseContext->recover();
|
||||
$2.setArray(false);
|
||||
}
|
||||
|
@ -1575,7 +1476,7 @@ type_qualifier
|
|||
| VARYING {
|
||||
if (parseContext->globalErrorCheck($1.line, parseContext->symbolTable.atGlobalLevel(), "varying"))
|
||||
parseContext->recover();
|
||||
if (parseContext->language == EShLangVertex)
|
||||
if (parseContext->shaderType == SH_VERTEX_SHADER)
|
||||
$$.setBasic(EbtVoid, EvqVaryingOut, $1.line);
|
||||
else
|
||||
$$.setBasic(EbtVoid, EvqVaryingIn, $1.line);
|
||||
|
@ -1583,7 +1484,7 @@ type_qualifier
|
|||
| INVARIANT VARYING {
|
||||
if (parseContext->globalErrorCheck($1.line, parseContext->symbolTable.atGlobalLevel(), "invariant varying"))
|
||||
parseContext->recover();
|
||||
if (parseContext->language == EShLangVertex)
|
||||
if (parseContext->shaderType == SH_VERTEX_SHADER)
|
||||
$$.setBasic(EbtVoid, EvqInvariantVaryingOut, $1.line);
|
||||
else
|
||||
$$.setBasic(EbtVoid, EvqInvariantVaryingIn, $1.line);
|
||||
|
@ -1795,19 +1696,24 @@ struct_declaration
|
|||
}
|
||||
for (unsigned int i = 0; i < $$->size(); ++i) {
|
||||
//
|
||||
// Careful not to replace already know aspects of type, like array-ness
|
||||
// Careful not to replace already known aspects of type, like array-ness
|
||||
//
|
||||
(*$$)[i].type->setType($1.type, $1.size, $1.matrix, $1.userDef);
|
||||
TType* type = (*$$)[i].type;
|
||||
type->setBasicType($1.type);
|
||||
type->setNominalSize($1.size);
|
||||
type->setMatrix($1.matrix);
|
||||
|
||||
// don't allow arrays of arrays
|
||||
if ((*$$)[i].type->isArray()) {
|
||||
if (type->isArray()) {
|
||||
if (parseContext->arrayTypeErrorCheck($1.line, $1))
|
||||
parseContext->recover();
|
||||
}
|
||||
if ($1.array)
|
||||
(*$$)[i].type->setArraySize($1.arraySize);
|
||||
if ($1.userDef)
|
||||
(*$$)[i].type->setTypeName($1.userDef->getTypeName());
|
||||
type->setArraySize($1.arraySize);
|
||||
if ($1.userDef) {
|
||||
type->setStruct($1.userDef->getStruct());
|
||||
type->setTypeName($1.userDef->getTypeName());
|
||||
}
|
||||
}
|
||||
}
|
||||
;
|
||||
|
@ -1873,7 +1779,7 @@ compound_statement
|
|||
: LEFT_BRACE RIGHT_BRACE { $$ = 0; }
|
||||
| LEFT_BRACE { parseContext->symbolTable.push(); } statement_list { parseContext->symbolTable.pop(); } RIGHT_BRACE {
|
||||
if ($3 != 0)
|
||||
$3->setOperator(EOpSequence);
|
||||
$3->setOp(EOpSequence);
|
||||
$$ = $3;
|
||||
}
|
||||
;
|
||||
|
@ -1890,7 +1796,7 @@ compound_statement_no_new_scope
|
|||
}
|
||||
| LEFT_BRACE statement_list RIGHT_BRACE {
|
||||
if ($2)
|
||||
$2->setOperator(EOpSequence);
|
||||
$2->setOp(EOpSequence);
|
||||
$$ = $2;
|
||||
}
|
||||
;
|
||||
|
@ -2065,8 +1971,8 @@ external_declaration
|
|||
|
||||
function_definition
|
||||
: function_prototype {
|
||||
TFunction& function = *($1.function);
|
||||
TFunction* prevDec = static_cast<TFunction*>(parseContext->symbolTable.find(function.getMangledName()));
|
||||
TFunction* function = $1.function;
|
||||
TFunction* prevDec = static_cast<TFunction*>(parseContext->symbolTable.find(function->getMangledName()));
|
||||
//
|
||||
// Note: 'prevDec' could be 'function' if this is the first time we've seen function
|
||||
// as it would have just been put in the symbol table. Otherwise, we're looking up
|
||||
|
@ -2076,7 +1982,7 @@ function_definition
|
|||
//
|
||||
// Then this function already has a body.
|
||||
//
|
||||
parseContext->error($1.line, "function already has a body", function.getName().c_str(), "");
|
||||
parseContext->error($1.line, "function already has a body", function->getName().c_str(), "");
|
||||
parseContext->recover();
|
||||
}
|
||||
prevDec->setDefined();
|
||||
|
@ -2084,13 +1990,13 @@ function_definition
|
|||
//
|
||||
// Raise error message if main function takes any parameters or return anything other than void
|
||||
//
|
||||
if (function.getName() == "main") {
|
||||
if (function.getParamCount() > 0) {
|
||||
parseContext->error($1.line, "function cannot take any parameter(s)", function.getName().c_str(), "");
|
||||
if (function->getName() == "main") {
|
||||
if (function->getParamCount() > 0) {
|
||||
parseContext->error($1.line, "function cannot take any parameter(s)", function->getName().c_str(), "");
|
||||
parseContext->recover();
|
||||
}
|
||||
if (function.getReturnType().getBasicType() != EbtVoid) {
|
||||
parseContext->error($1.line, "", function.getReturnType().getBasicString(), "main function cannot return a value");
|
||||
if (function->getReturnType().getBasicType() != EbtVoid) {
|
||||
parseContext->error($1.line, "", function->getReturnType().getBasicString(), "main function cannot return a value");
|
||||
parseContext->recover();
|
||||
}
|
||||
}
|
||||
|
@ -2115,8 +2021,8 @@ function_definition
|
|||
// knows where to find parameters.
|
||||
//
|
||||
TIntermAggregate* paramNodes = new TIntermAggregate;
|
||||
for (int i = 0; i < function.getParamCount(); i++) {
|
||||
TParameter& param = function[i];
|
||||
for (int i = 0; i < function->getParamCount(); i++) {
|
||||
const TParameter& param = function->getParam(i);
|
||||
if (param.name != 0) {
|
||||
TVariable *variable = new TVariable(param.name, *param.type);
|
||||
//
|
||||
|
@ -2127,10 +2033,6 @@ function_definition
|
|||
parseContext->recover();
|
||||
delete variable;
|
||||
}
|
||||
//
|
||||
// Transfer ownership of name pointer to symbol table.
|
||||
//
|
||||
param.name = 0;
|
||||
|
||||
//
|
||||
// Add the parameter to the HIL
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
//
|
||||
class TOutputTraverser : public TIntermTraverser {
|
||||
public:
|
||||
TOutputTraverser(TInfoSink& i) : infoSink(i) { }
|
||||
TInfoSink& infoSink;
|
||||
TOutputTraverser(TInfoSinkBase& i) : sink(i) { }
|
||||
TInfoSinkBase& sink;
|
||||
|
||||
protected:
|
||||
void visitSymbol(TIntermSymbol*);
|
||||
|
@ -56,14 +56,14 @@ TString TType::getCompleteString() const
|
|||
// Helper functions for printing, not part of traversing.
|
||||
//
|
||||
|
||||
void OutputTreeText(TInfoSink& infoSink, TIntermNode* node, const int depth)
|
||||
void OutputTreeText(TInfoSinkBase& sink, TIntermNode* node, const int depth)
|
||||
{
|
||||
int i;
|
||||
|
||||
infoSink.debug.location(node->getLine());
|
||||
sink.location(node->getLine());
|
||||
|
||||
for (i = 0; i < depth; ++i)
|
||||
infoSink.debug << " ";
|
||||
sink << " ";
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -77,226 +77,226 @@ void OutputTreeText(TInfoSink& infoSink, TIntermNode* node, const int depth)
|
|||
|
||||
void TOutputTraverser::visitSymbol(TIntermSymbol* node)
|
||||
{
|
||||
OutputTreeText(infoSink, node, depth);
|
||||
OutputTreeText(sink, node, depth);
|
||||
|
||||
infoSink.debug << "'" << node->getSymbol() << "' ";
|
||||
infoSink.debug << "(" << node->getCompleteString() << ")\n";
|
||||
sink << "'" << node->getSymbol() << "' ";
|
||||
sink << "(" << node->getCompleteString() << ")\n";
|
||||
}
|
||||
|
||||
bool TOutputTraverser::visitBinary(Visit visit, TIntermBinary* node)
|
||||
{
|
||||
TInfoSink& out = infoSink;
|
||||
TInfoSinkBase& out = sink;
|
||||
|
||||
OutputTreeText(out, node, depth);
|
||||
|
||||
switch (node->getOp()) {
|
||||
case EOpAssign: out.debug << "move second child to first child"; break;
|
||||
case EOpInitialize: out.debug << "initialize first child with second child"; break;
|
||||
case EOpAddAssign: out.debug << "add second child into first child"; break;
|
||||
case EOpSubAssign: out.debug << "subtract second child into first child"; break;
|
||||
case EOpMulAssign: out.debug << "multiply second child into first child"; break;
|
||||
case EOpVectorTimesMatrixAssign: out.debug << "matrix mult second child into first child"; break;
|
||||
case EOpVectorTimesScalarAssign: out.debug << "vector scale second child into first child"; break;
|
||||
case EOpMatrixTimesScalarAssign: out.debug << "matrix scale second child into first child"; break;
|
||||
case EOpMatrixTimesMatrixAssign: out.debug << "matrix mult second child into first child"; break;
|
||||
case EOpDivAssign: out.debug << "divide second child into first child"; break;
|
||||
case EOpIndexDirect: out.debug << "direct index"; break;
|
||||
case EOpIndexIndirect: out.debug << "indirect index"; break;
|
||||
case EOpIndexDirectStruct: out.debug << "direct index for structure"; break;
|
||||
case EOpVectorSwizzle: out.debug << "vector swizzle"; break;
|
||||
case EOpAssign: out << "move second child to first child"; break;
|
||||
case EOpInitialize: out << "initialize first child with second child"; break;
|
||||
case EOpAddAssign: out << "add second child into first child"; break;
|
||||
case EOpSubAssign: out << "subtract second child into first child"; break;
|
||||
case EOpMulAssign: out << "multiply second child into first child"; break;
|
||||
case EOpVectorTimesMatrixAssign: out << "matrix mult second child into first child"; break;
|
||||
case EOpVectorTimesScalarAssign: out << "vector scale second child into first child"; break;
|
||||
case EOpMatrixTimesScalarAssign: out << "matrix scale second child into first child"; break;
|
||||
case EOpMatrixTimesMatrixAssign: out << "matrix mult second child into first child"; break;
|
||||
case EOpDivAssign: out << "divide second child into first child"; break;
|
||||
case EOpIndexDirect: out << "direct index"; break;
|
||||
case EOpIndexIndirect: out << "indirect index"; break;
|
||||
case EOpIndexDirectStruct: out << "direct index for structure"; break;
|
||||
case EOpVectorSwizzle: out << "vector swizzle"; break;
|
||||
|
||||
case EOpAdd: out.debug << "add"; break;
|
||||
case EOpSub: out.debug << "subtract"; break;
|
||||
case EOpMul: out.debug << "component-wise multiply"; break;
|
||||
case EOpDiv: out.debug << "divide"; break;
|
||||
case EOpEqual: out.debug << "Compare Equal"; break;
|
||||
case EOpNotEqual: out.debug << "Compare Not Equal"; break;
|
||||
case EOpLessThan: out.debug << "Compare Less Than"; break;
|
||||
case EOpGreaterThan: out.debug << "Compare Greater Than"; break;
|
||||
case EOpLessThanEqual: out.debug << "Compare Less Than or Equal"; break;
|
||||
case EOpGreaterThanEqual: out.debug << "Compare Greater Than or Equal"; break;
|
||||
case EOpAdd: out << "add"; break;
|
||||
case EOpSub: out << "subtract"; break;
|
||||
case EOpMul: out << "component-wise multiply"; break;
|
||||
case EOpDiv: out << "divide"; break;
|
||||
case EOpEqual: out << "Compare Equal"; break;
|
||||
case EOpNotEqual: out << "Compare Not Equal"; break;
|
||||
case EOpLessThan: out << "Compare Less Than"; break;
|
||||
case EOpGreaterThan: out << "Compare Greater Than"; break;
|
||||
case EOpLessThanEqual: out << "Compare Less Than or Equal"; break;
|
||||
case EOpGreaterThanEqual: out << "Compare Greater Than or Equal"; break;
|
||||
|
||||
case EOpVectorTimesScalar: out.debug << "vector-scale"; break;
|
||||
case EOpVectorTimesMatrix: out.debug << "vector-times-matrix"; break;
|
||||
case EOpMatrixTimesVector: out.debug << "matrix-times-vector"; break;
|
||||
case EOpMatrixTimesScalar: out.debug << "matrix-scale"; break;
|
||||
case EOpMatrixTimesMatrix: out.debug << "matrix-multiply"; break;
|
||||
case EOpVectorTimesScalar: out << "vector-scale"; break;
|
||||
case EOpVectorTimesMatrix: out << "vector-times-matrix"; break;
|
||||
case EOpMatrixTimesVector: out << "matrix-times-vector"; break;
|
||||
case EOpMatrixTimesScalar: out << "matrix-scale"; break;
|
||||
case EOpMatrixTimesMatrix: out << "matrix-multiply"; break;
|
||||
|
||||
case EOpLogicalOr: out.debug << "logical-or"; break;
|
||||
case EOpLogicalXor: out.debug << "logical-xor"; break;
|
||||
case EOpLogicalAnd: out.debug << "logical-and"; break;
|
||||
default: out.debug << "<unknown op>";
|
||||
case EOpLogicalOr: out << "logical-or"; break;
|
||||
case EOpLogicalXor: out << "logical-xor"; break;
|
||||
case EOpLogicalAnd: out << "logical-and"; break;
|
||||
default: out << "<unknown op>";
|
||||
}
|
||||
|
||||
out.debug << " (" << node->getCompleteString() << ")";
|
||||
out << " (" << node->getCompleteString() << ")";
|
||||
|
||||
out.debug << "\n";
|
||||
out << "\n";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary* node)
|
||||
{
|
||||
TInfoSink& out = infoSink;
|
||||
TInfoSinkBase& out = sink;
|
||||
|
||||
OutputTreeText(out, node, depth);
|
||||
|
||||
switch (node->getOp()) {
|
||||
case EOpNegative: out.debug << "Negate value"; break;
|
||||
case EOpNegative: out << "Negate value"; break;
|
||||
case EOpVectorLogicalNot:
|
||||
case EOpLogicalNot: out.debug << "Negate conditional"; break;
|
||||
case EOpLogicalNot: out << "Negate conditional"; break;
|
||||
|
||||
case EOpPostIncrement: out.debug << "Post-Increment"; break;
|
||||
case EOpPostDecrement: out.debug << "Post-Decrement"; break;
|
||||
case EOpPreIncrement: out.debug << "Pre-Increment"; break;
|
||||
case EOpPreDecrement: out.debug << "Pre-Decrement"; break;
|
||||
case EOpPostIncrement: out << "Post-Increment"; break;
|
||||
case EOpPostDecrement: out << "Post-Decrement"; break;
|
||||
case EOpPreIncrement: out << "Pre-Increment"; break;
|
||||
case EOpPreDecrement: out << "Pre-Decrement"; break;
|
||||
|
||||
case EOpConvIntToBool: out.debug << "Convert int to bool"; break;
|
||||
case EOpConvFloatToBool:out.debug << "Convert float to bool";break;
|
||||
case EOpConvBoolToFloat:out.debug << "Convert bool to float";break;
|
||||
case EOpConvIntToFloat: out.debug << "Convert int to float"; break;
|
||||
case EOpConvFloatToInt: out.debug << "Convert float to int"; break;
|
||||
case EOpConvBoolToInt: out.debug << "Convert bool to int"; break;
|
||||
case EOpConvIntToBool: out << "Convert int to bool"; break;
|
||||
case EOpConvFloatToBool:out << "Convert float to bool";break;
|
||||
case EOpConvBoolToFloat:out << "Convert bool to float";break;
|
||||
case EOpConvIntToFloat: out << "Convert int to float"; break;
|
||||
case EOpConvFloatToInt: out << "Convert float to int"; break;
|
||||
case EOpConvBoolToInt: out << "Convert bool to int"; break;
|
||||
|
||||
case EOpRadians: out.debug << "radians"; break;
|
||||
case EOpDegrees: out.debug << "degrees"; break;
|
||||
case EOpSin: out.debug << "sine"; break;
|
||||
case EOpCos: out.debug << "cosine"; break;
|
||||
case EOpTan: out.debug << "tangent"; break;
|
||||
case EOpAsin: out.debug << "arc sine"; break;
|
||||
case EOpAcos: out.debug << "arc cosine"; break;
|
||||
case EOpAtan: out.debug << "arc tangent"; break;
|
||||
case EOpRadians: out << "radians"; break;
|
||||
case EOpDegrees: out << "degrees"; break;
|
||||
case EOpSin: out << "sine"; break;
|
||||
case EOpCos: out << "cosine"; break;
|
||||
case EOpTan: out << "tangent"; break;
|
||||
case EOpAsin: out << "arc sine"; break;
|
||||
case EOpAcos: out << "arc cosine"; break;
|
||||
case EOpAtan: out << "arc tangent"; break;
|
||||
|
||||
case EOpExp: out.debug << "exp"; break;
|
||||
case EOpLog: out.debug << "log"; break;
|
||||
case EOpExp2: out.debug << "exp2"; break;
|
||||
case EOpLog2: out.debug << "log2"; break;
|
||||
case EOpSqrt: out.debug << "sqrt"; break;
|
||||
case EOpInverseSqrt: out.debug << "inverse sqrt"; break;
|
||||
case EOpExp: out << "exp"; break;
|
||||
case EOpLog: out << "log"; break;
|
||||
case EOpExp2: out << "exp2"; break;
|
||||
case EOpLog2: out << "log2"; break;
|
||||
case EOpSqrt: out << "sqrt"; break;
|
||||
case EOpInverseSqrt: out << "inverse sqrt"; break;
|
||||
|
||||
case EOpAbs: out.debug << "Absolute value"; break;
|
||||
case EOpSign: out.debug << "Sign"; break;
|
||||
case EOpFloor: out.debug << "Floor"; break;
|
||||
case EOpCeil: out.debug << "Ceiling"; break;
|
||||
case EOpFract: out.debug << "Fraction"; break;
|
||||
case EOpAbs: out << "Absolute value"; break;
|
||||
case EOpSign: out << "Sign"; break;
|
||||
case EOpFloor: out << "Floor"; break;
|
||||
case EOpCeil: out << "Ceiling"; break;
|
||||
case EOpFract: out << "Fraction"; break;
|
||||
|
||||
case EOpLength: out.debug << "length"; break;
|
||||
case EOpNormalize: out.debug << "normalize"; break;
|
||||
// case EOpDPdx: out.debug << "dPdx"; break;
|
||||
// case EOpDPdy: out.debug << "dPdy"; break;
|
||||
// case EOpFwidth: out.debug << "fwidth"; break;
|
||||
case EOpLength: out << "length"; break;
|
||||
case EOpNormalize: out << "normalize"; break;
|
||||
// case EOpDPdx: out << "dPdx"; break;
|
||||
// case EOpDPdy: out << "dPdy"; break;
|
||||
// case EOpFwidth: out << "fwidth"; break;
|
||||
|
||||
case EOpAny: out.debug << "any"; break;
|
||||
case EOpAll: out.debug << "all"; break;
|
||||
case EOpAny: out << "any"; break;
|
||||
case EOpAll: out << "all"; break;
|
||||
|
||||
default: out.debug.message(EPrefixError, "Bad unary op");
|
||||
default: out.message(EPrefixError, "Bad unary op");
|
||||
}
|
||||
|
||||
out.debug << " (" << node->getCompleteString() << ")";
|
||||
out << " (" << node->getCompleteString() << ")";
|
||||
|
||||
out.debug << "\n";
|
||||
out << "\n";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate* node)
|
||||
{
|
||||
TInfoSink& out = infoSink;
|
||||
TInfoSinkBase& out = sink;
|
||||
|
||||
if (node->getOp() == EOpNull) {
|
||||
out.debug.message(EPrefixError, "node is still EOpNull!");
|
||||
out.message(EPrefixError, "node is still EOpNull!");
|
||||
return true;
|
||||
}
|
||||
|
||||
OutputTreeText(out, node, depth);
|
||||
|
||||
switch (node->getOp()) {
|
||||
case EOpSequence: out.debug << "Sequence\n"; return true;
|
||||
case EOpComma: out.debug << "Comma\n"; return true;
|
||||
case EOpFunction: out.debug << "Function Definition: " << node->getName(); break;
|
||||
case EOpFunctionCall: out.debug << "Function Call: " << node->getName(); break;
|
||||
case EOpParameters: out.debug << "Function Parameters: "; break;
|
||||
case EOpSequence: out << "Sequence\n"; return true;
|
||||
case EOpComma: out << "Comma\n"; return true;
|
||||
case EOpFunction: out << "Function Definition: " << node->getName(); break;
|
||||
case EOpFunctionCall: out << "Function Call: " << node->getName(); break;
|
||||
case EOpParameters: out << "Function Parameters: "; break;
|
||||
|
||||
case EOpConstructFloat: out.debug << "Construct float"; break;
|
||||
case EOpConstructVec2: out.debug << "Construct vec2"; break;
|
||||
case EOpConstructVec3: out.debug << "Construct vec3"; break;
|
||||
case EOpConstructVec4: out.debug << "Construct vec4"; break;
|
||||
case EOpConstructBool: out.debug << "Construct bool"; break;
|
||||
case EOpConstructBVec2: out.debug << "Construct bvec2"; break;
|
||||
case EOpConstructBVec3: out.debug << "Construct bvec3"; break;
|
||||
case EOpConstructBVec4: out.debug << "Construct bvec4"; break;
|
||||
case EOpConstructInt: out.debug << "Construct int"; break;
|
||||
case EOpConstructIVec2: out.debug << "Construct ivec2"; break;
|
||||
case EOpConstructIVec3: out.debug << "Construct ivec3"; break;
|
||||
case EOpConstructIVec4: out.debug << "Construct ivec4"; break;
|
||||
case EOpConstructMat2: out.debug << "Construct mat2"; break;
|
||||
case EOpConstructMat3: out.debug << "Construct mat3"; break;
|
||||
case EOpConstructMat4: out.debug << "Construct mat4"; break;
|
||||
case EOpConstructStruct: out.debug << "Construct structure"; break;
|
||||
case EOpConstructFloat: out << "Construct float"; break;
|
||||
case EOpConstructVec2: out << "Construct vec2"; break;
|
||||
case EOpConstructVec3: out << "Construct vec3"; break;
|
||||
case EOpConstructVec4: out << "Construct vec4"; break;
|
||||
case EOpConstructBool: out << "Construct bool"; break;
|
||||
case EOpConstructBVec2: out << "Construct bvec2"; break;
|
||||
case EOpConstructBVec3: out << "Construct bvec3"; break;
|
||||
case EOpConstructBVec4: out << "Construct bvec4"; break;
|
||||
case EOpConstructInt: out << "Construct int"; break;
|
||||
case EOpConstructIVec2: out << "Construct ivec2"; break;
|
||||
case EOpConstructIVec3: out << "Construct ivec3"; break;
|
||||
case EOpConstructIVec4: out << "Construct ivec4"; break;
|
||||
case EOpConstructMat2: out << "Construct mat2"; break;
|
||||
case EOpConstructMat3: out << "Construct mat3"; break;
|
||||
case EOpConstructMat4: out << "Construct mat4"; break;
|
||||
case EOpConstructStruct: out << "Construct structure"; break;
|
||||
|
||||
case EOpLessThan: out.debug << "Compare Less Than"; break;
|
||||
case EOpGreaterThan: out.debug << "Compare Greater Than"; break;
|
||||
case EOpLessThanEqual: out.debug << "Compare Less Than or Equal"; break;
|
||||
case EOpGreaterThanEqual: out.debug << "Compare Greater Than or Equal"; break;
|
||||
case EOpVectorEqual: out.debug << "Equal"; break;
|
||||
case EOpVectorNotEqual: out.debug << "NotEqual"; break;
|
||||
case EOpLessThan: out << "Compare Less Than"; break;
|
||||
case EOpGreaterThan: out << "Compare Greater Than"; break;
|
||||
case EOpLessThanEqual: out << "Compare Less Than or Equal"; break;
|
||||
case EOpGreaterThanEqual: out << "Compare Greater Than or Equal"; break;
|
||||
case EOpVectorEqual: out << "Equal"; break;
|
||||
case EOpVectorNotEqual: out << "NotEqual"; break;
|
||||
|
||||
case EOpMod: out.debug << "mod"; break;
|
||||
case EOpPow: out.debug << "pow"; break;
|
||||
case EOpMod: out << "mod"; break;
|
||||
case EOpPow: out << "pow"; break;
|
||||
|
||||
case EOpAtan: out.debug << "arc tangent"; break;
|
||||
case EOpAtan: out << "arc tangent"; break;
|
||||
|
||||
case EOpMin: out.debug << "min"; break;
|
||||
case EOpMax: out.debug << "max"; break;
|
||||
case EOpClamp: out.debug << "clamp"; break;
|
||||
case EOpMix: out.debug << "mix"; break;
|
||||
case EOpStep: out.debug << "step"; break;
|
||||
case EOpSmoothStep: out.debug << "smoothstep"; break;
|
||||
case EOpMin: out << "min"; break;
|
||||
case EOpMax: out << "max"; break;
|
||||
case EOpClamp: out << "clamp"; break;
|
||||
case EOpMix: out << "mix"; break;
|
||||
case EOpStep: out << "step"; break;
|
||||
case EOpSmoothStep: out << "smoothstep"; break;
|
||||
|
||||
case EOpDistance: out.debug << "distance"; break;
|
||||
case EOpDot: out.debug << "dot-product"; break;
|
||||
case EOpCross: out.debug << "cross-product"; break;
|
||||
case EOpFaceForward: out.debug << "face-forward"; break;
|
||||
case EOpReflect: out.debug << "reflect"; break;
|
||||
case EOpRefract: out.debug << "refract"; break;
|
||||
case EOpMul: out.debug << "component-wise multiply"; break;
|
||||
case EOpDistance: out << "distance"; break;
|
||||
case EOpDot: out << "dot-product"; break;
|
||||
case EOpCross: out << "cross-product"; break;
|
||||
case EOpFaceForward: out << "face-forward"; break;
|
||||
case EOpReflect: out << "reflect"; break;
|
||||
case EOpRefract: out << "refract"; break;
|
||||
case EOpMul: out << "component-wise multiply"; break;
|
||||
|
||||
default: out.debug.message(EPrefixError, "Bad aggregation op");
|
||||
default: out.message(EPrefixError, "Bad aggregation op");
|
||||
}
|
||||
|
||||
if (node->getOp() != EOpSequence && node->getOp() != EOpParameters)
|
||||
out.debug << " (" << node->getCompleteString() << ")";
|
||||
out << " (" << node->getCompleteString() << ")";
|
||||
|
||||
out.debug << "\n";
|
||||
out << "\n";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TOutputTraverser::visitSelection(Visit visit, TIntermSelection* node)
|
||||
{
|
||||
TInfoSink& out = infoSink;
|
||||
TInfoSinkBase& out = sink;
|
||||
|
||||
OutputTreeText(out, node, depth);
|
||||
|
||||
out.debug << "Test condition and select";
|
||||
out.debug << " (" << node->getCompleteString() << ")\n";
|
||||
out << "Test condition and select";
|
||||
out << " (" << node->getCompleteString() << ")\n";
|
||||
|
||||
++depth;
|
||||
|
||||
OutputTreeText(infoSink, node, depth);
|
||||
out.debug << "Condition\n";
|
||||
OutputTreeText(sink, node, depth);
|
||||
out << "Condition\n";
|
||||
node->getCondition()->traverse(this);
|
||||
|
||||
OutputTreeText(infoSink, node, depth);
|
||||
OutputTreeText(sink, node, depth);
|
||||
if (node->getTrueBlock()) {
|
||||
out.debug << "true case\n";
|
||||
out << "true case\n";
|
||||
node->getTrueBlock()->traverse(this);
|
||||
} else
|
||||
out.debug << "true case is null\n";
|
||||
out << "true case is null\n";
|
||||
|
||||
if (node->getFalseBlock()) {
|
||||
OutputTreeText(infoSink, node, depth);
|
||||
out.debug << "false case\n";
|
||||
OutputTreeText(sink, node, depth);
|
||||
out << "false case\n";
|
||||
node->getFalseBlock()->traverse(this);
|
||||
}
|
||||
|
||||
|
@ -307,7 +307,7 @@ bool TOutputTraverser::visitSelection(Visit visit, TIntermSelection* node)
|
|||
|
||||
void TOutputTraverser::visitConstantUnion(TIntermConstantUnion* node)
|
||||
{
|
||||
TInfoSink& out = infoSink;
|
||||
TInfoSinkBase& out = sink;
|
||||
|
||||
int size = node->getType().getObjectSize();
|
||||
|
||||
|
@ -316,23 +316,23 @@ void TOutputTraverser::visitConstantUnion(TIntermConstantUnion* node)
|
|||
switch (node->getUnionArrayPointer()[i].getType()) {
|
||||
case EbtBool:
|
||||
if (node->getUnionArrayPointer()[i].getBConst())
|
||||
out.debug << "true";
|
||||
out << "true";
|
||||
else
|
||||
out.debug << "false";
|
||||
out << "false";
|
||||
|
||||
out.debug << " (" << "const bool" << ")";
|
||||
out.debug << "\n";
|
||||
out << " (" << "const bool" << ")";
|
||||
out << "\n";
|
||||
break;
|
||||
case EbtFloat:
|
||||
out.debug << node->getUnionArrayPointer()[i].getFConst();
|
||||
out.debug << " (const float)\n";
|
||||
out << node->getUnionArrayPointer()[i].getFConst();
|
||||
out << " (const float)\n";
|
||||
break;
|
||||
case EbtInt:
|
||||
out.debug << node->getUnionArrayPointer()[i].getIConst();
|
||||
out.debug << " (const int)\n";
|
||||
out << node->getUnionArrayPointer()[i].getIConst();
|
||||
out << " (const int)\n";
|
||||
break;
|
||||
default:
|
||||
out.info.message(EPrefixInternalError, "Unknown constant", node->getLine());
|
||||
out.message(EPrefixInternalError, "Unknown constant", node->getLine());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -340,34 +340,34 @@ void TOutputTraverser::visitConstantUnion(TIntermConstantUnion* node)
|
|||
|
||||
bool TOutputTraverser::visitLoop(Visit visit, TIntermLoop* node)
|
||||
{
|
||||
TInfoSink& out = infoSink;
|
||||
TInfoSinkBase& out = sink;
|
||||
|
||||
OutputTreeText(out, node, depth);
|
||||
|
||||
out.debug << "Loop with condition ";
|
||||
out << "Loop with condition ";
|
||||
if (! node->testFirst())
|
||||
out.debug << "not ";
|
||||
out.debug << "tested first\n";
|
||||
out << "not ";
|
||||
out << "tested first\n";
|
||||
|
||||
++depth;
|
||||
|
||||
OutputTreeText(infoSink, node, depth);
|
||||
OutputTreeText(sink, node, depth);
|
||||
if (node->getTest()) {
|
||||
out.debug << "Loop Condition\n";
|
||||
out << "Loop Condition\n";
|
||||
node->getTest()->traverse(this);
|
||||
} else
|
||||
out.debug << "No loop condition\n";
|
||||
out << "No loop condition\n";
|
||||
|
||||
OutputTreeText(infoSink, node, depth);
|
||||
OutputTreeText(sink, node, depth);
|
||||
if (node->getBody()) {
|
||||
out.debug << "Loop Body\n";
|
||||
out << "Loop Body\n";
|
||||
node->getBody()->traverse(this);
|
||||
} else
|
||||
out.debug << "No loop body\n";
|
||||
out << "No loop body\n";
|
||||
|
||||
if (node->getTerminal()) {
|
||||
OutputTreeText(infoSink, node, depth);
|
||||
out.debug << "Loop Terminal Expression\n";
|
||||
OutputTreeText(sink, node, depth);
|
||||
out << "Loop Terminal Expression\n";
|
||||
node->getTerminal()->traverse(this);
|
||||
}
|
||||
|
||||
|
@ -378,25 +378,25 @@ bool TOutputTraverser::visitLoop(Visit visit, TIntermLoop* node)
|
|||
|
||||
bool TOutputTraverser::visitBranch(Visit visit, TIntermBranch* node)
|
||||
{
|
||||
TInfoSink& out = infoSink;
|
||||
TInfoSinkBase& out = sink;
|
||||
|
||||
OutputTreeText(out, node, depth);
|
||||
|
||||
switch (node->getFlowOp()) {
|
||||
case EOpKill: out.debug << "Branch: Kill"; break;
|
||||
case EOpBreak: out.debug << "Branch: Break"; break;
|
||||
case EOpContinue: out.debug << "Branch: Continue"; break;
|
||||
case EOpReturn: out.debug << "Branch: Return"; break;
|
||||
default: out.debug << "Branch: Unknown Branch"; break;
|
||||
case EOpKill: out << "Branch: Kill"; break;
|
||||
case EOpBreak: out << "Branch: Break"; break;
|
||||
case EOpContinue: out << "Branch: Continue"; break;
|
||||
case EOpReturn: out << "Branch: Return"; break;
|
||||
default: out << "Branch: Unknown Branch"; break;
|
||||
}
|
||||
|
||||
if (node->getExpression()) {
|
||||
out.debug << " with expression\n";
|
||||
out << " with expression\n";
|
||||
++depth;
|
||||
node->getExpression()->traverse(this);
|
||||
--depth;
|
||||
} else
|
||||
out.debug << "\n";
|
||||
out << "\n";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -411,7 +411,7 @@ void TIntermediate::outputTree(TIntermNode* root)
|
|||
if (root == 0)
|
||||
return;
|
||||
|
||||
TOutputTraverser it(infoSink);
|
||||
TOutputTraverser it(infoSink.info);
|
||||
|
||||
root->traverse(&it);
|
||||
}
|
||||
|
|
|
@ -129,9 +129,9 @@ enum TOperator {
|
|||
EOpReflect,
|
||||
EOpRefract,
|
||||
|
||||
//EOpDPdx, // Fragment only, OES_standard_derivatives extension
|
||||
//EOpDPdy, // Fragment only, OES_standard_derivatives extension
|
||||
//EOpFwidth, // Fragment only, OES_standard_derivatives extension
|
||||
EOpDFdx, // Fragment only, OES_standard_derivatives extension
|
||||
EOpDFdy, // Fragment only, OES_standard_derivatives extension
|
||||
EOpFwidth, // Fragment only, OES_standard_derivatives extension
|
||||
|
||||
EOpMatrixTimesMatrix,
|
||||
|
||||
|
@ -203,8 +203,10 @@ public:
|
|||
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
|
||||
|
||||
TIntermNode() : line(0) {}
|
||||
virtual TSourceLoc getLine() const { return line; }
|
||||
virtual void setLine(TSourceLoc l) { line = l; }
|
||||
|
||||
TSourceLoc getLine() const { return line; }
|
||||
void setLine(TSourceLoc l) { line = l; }
|
||||
|
||||
virtual void traverse(TIntermTraverser*) = 0;
|
||||
virtual TIntermTyped* getAsTyped() { return 0; }
|
||||
virtual TIntermConstantUnion* getAsConstantUnion() { return 0; }
|
||||
|
@ -215,6 +217,7 @@ public:
|
|||
virtual TIntermSymbol* getAsSymbolNode() { return 0; }
|
||||
virtual TIntermLoop* getAsLoopNode() { return 0; }
|
||||
virtual ~TIntermNode() { }
|
||||
|
||||
protected:
|
||||
TSourceLoc line;
|
||||
};
|
||||
|
@ -233,22 +236,23 @@ struct TIntermNodePair {
|
|||
class TIntermTyped : public TIntermNode {
|
||||
public:
|
||||
TIntermTyped(const TType& t) : type(t) { }
|
||||
virtual TIntermTyped* getAsTyped() { return this; }
|
||||
virtual void setType(const TType& t) { type = t; }
|
||||
virtual const TType& getType() const { return type; }
|
||||
virtual TType* getTypePointer() { return &type; }
|
||||
virtual TIntermTyped* getAsTyped() { return this; }
|
||||
|
||||
virtual TBasicType getBasicType() const { return type.getBasicType(); }
|
||||
virtual TQualifier getQualifier() const { return type.getQualifier(); }
|
||||
virtual TPrecision getPrecision() const { return type.getPrecision(); }
|
||||
virtual int getNominalSize() const { return type.getNominalSize(); }
|
||||
virtual int getSize() const { return type.getInstanceSize(); }
|
||||
virtual bool isMatrix() const { return type.isMatrix(); }
|
||||
virtual bool isArray() const { return type.isArray(); }
|
||||
virtual bool isVector() const { return type.isVector(); }
|
||||
virtual bool isScalar() const { return type.isScalar(); }
|
||||
const char* getBasicString() const { return type.getBasicString(); }
|
||||
const char* getQualifierString() const { return type.getQualifierString(); }
|
||||
void setType(const TType& t) { type = t; }
|
||||
const TType& getType() const { return type; }
|
||||
TType* getTypePointer() { return &type; }
|
||||
|
||||
TBasicType getBasicType() const { return type.getBasicType(); }
|
||||
TQualifier getQualifier() const { return type.getQualifier(); }
|
||||
TPrecision getPrecision() const { return type.getPrecision(); }
|
||||
int getNominalSize() const { return type.getNominalSize(); }
|
||||
|
||||
bool isMatrix() const { return type.isMatrix(); }
|
||||
bool isArray() const { return type.isArray(); }
|
||||
bool isVector() const { return type.isVector(); }
|
||||
bool isScalar() const { return type.isScalar(); }
|
||||
const char* getBasicString() const { return type.getBasicString(); }
|
||||
const char* getQualifierString() const { return type.getQualifierString(); }
|
||||
TString getCompleteString() const { return type.getCompleteString(); }
|
||||
|
||||
protected:
|
||||
|
@ -266,13 +270,16 @@ public:
|
|||
test(aTest),
|
||||
terminal(aTerminal),
|
||||
first(testFirst) { }
|
||||
|
||||
virtual TIntermLoop* getAsLoopNode() { return this; }
|
||||
virtual void traverse(TIntermTraverser*);
|
||||
|
||||
TIntermNode *getInit() { return init; }
|
||||
TIntermNode *getBody() { return body; }
|
||||
TIntermTyped *getTest() { return test; }
|
||||
TIntermTyped *getTerminal() { return terminal; }
|
||||
bool testFirst() { return first; }
|
||||
|
||||
protected:
|
||||
TIntermNode *init;
|
||||
TIntermNode *body; // code to loop over
|
||||
|
@ -289,9 +296,12 @@ public:
|
|||
TIntermBranch(TOperator op, TIntermTyped* e) :
|
||||
flowOp(op),
|
||||
expression(e) { }
|
||||
|
||||
virtual void traverse(TIntermTraverser*);
|
||||
|
||||
TOperator getFlowOp() { return flowOp; }
|
||||
TIntermTyped* getExpression() { return expression; }
|
||||
|
||||
protected:
|
||||
TOperator flowOp;
|
||||
TIntermTyped* expression; // non-zero except for "return exp;" statements
|
||||
|
@ -307,10 +317,13 @@ public:
|
|||
// it is essential to use "symbol = sym" to assign to symbol
|
||||
TIntermSymbol(int i, const TString& sym, const TType& t) :
|
||||
TIntermTyped(t), id(i) { symbol = sym;}
|
||||
virtual int getId() const { return id; }
|
||||
virtual const TString& getSymbol() const { return symbol; }
|
||||
|
||||
int getId() const { return id; }
|
||||
const TString& getSymbol() const { return symbol; }
|
||||
|
||||
virtual void traverse(TIntermTraverser*);
|
||||
virtual TIntermSymbol* getAsSymbolNode() { return this; }
|
||||
|
||||
protected:
|
||||
int id;
|
||||
TString symbol;
|
||||
|
@ -319,11 +332,15 @@ protected:
|
|||
class TIntermConstantUnion : public TIntermTyped {
|
||||
public:
|
||||
TIntermConstantUnion(ConstantUnion *unionPointer, const TType& t) : TIntermTyped(t), unionArrayPointer(unionPointer) { }
|
||||
|
||||
ConstantUnion* getUnionArrayPointer() const { return unionArrayPointer; }
|
||||
void setUnionArrayPointer(ConstantUnion *c) { unionArrayPointer = c; }
|
||||
|
||||
virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
|
||||
virtual void traverse(TIntermTraverser* );
|
||||
virtual TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&);
|
||||
virtual void traverse(TIntermTraverser*);
|
||||
|
||||
TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&);
|
||||
|
||||
protected:
|
||||
ConstantUnion *unionArrayPointer;
|
||||
};
|
||||
|
@ -334,9 +351,11 @@ protected:
|
|||
class TIntermOperator : public TIntermTyped {
|
||||
public:
|
||||
TOperator getOp() const { return op; }
|
||||
void setOp(TOperator o) { op = o; }
|
||||
|
||||
bool modifiesState() const;
|
||||
bool isConstructor() const;
|
||||
virtual bool promote(TInfoSink&) { return true; }
|
||||
|
||||
protected:
|
||||
TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat, EbpUndefined)), op(o) {}
|
||||
TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {}
|
||||
|
@ -349,13 +368,16 @@ protected:
|
|||
class TIntermBinary : public TIntermOperator {
|
||||
public:
|
||||
TIntermBinary(TOperator o) : TIntermOperator(o) {}
|
||||
virtual void traverse(TIntermTraverser*);
|
||||
virtual void setLeft(TIntermTyped* n) { left = n; }
|
||||
virtual void setRight(TIntermTyped* n) { right = n; }
|
||||
virtual TIntermTyped* getLeft() const { return left; }
|
||||
virtual TIntermTyped* getRight() const { return right; }
|
||||
|
||||
virtual TIntermBinary* getAsBinaryNode() { return this; }
|
||||
virtual bool promote(TInfoSink&);
|
||||
virtual void traverse(TIntermTraverser*);
|
||||
|
||||
void setLeft(TIntermTyped* n) { left = n; }
|
||||
void setRight(TIntermTyped* n) { right = n; }
|
||||
TIntermTyped* getLeft() const { return left; }
|
||||
TIntermTyped* getRight() const { return right; }
|
||||
bool promote(TInfoSink&);
|
||||
|
||||
protected:
|
||||
TIntermTyped* left;
|
||||
TIntermTyped* right;
|
||||
|
@ -368,17 +390,21 @@ class TIntermUnary : public TIntermOperator {
|
|||
public:
|
||||
TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0) {}
|
||||
TIntermUnary(TOperator o) : TIntermOperator(o), operand(0) {}
|
||||
|
||||
virtual void traverse(TIntermTraverser*);
|
||||
virtual void setOperand(TIntermTyped* o) { operand = o; }
|
||||
virtual TIntermTyped* getOperand() { return operand; }
|
||||
virtual TIntermUnary* getAsUnaryNode() { return this; }
|
||||
virtual bool promote(TInfoSink&);
|
||||
|
||||
void setOperand(TIntermTyped* o) { operand = o; }
|
||||
TIntermTyped* getOperand() { return operand; }
|
||||
bool promote(TInfoSink&);
|
||||
|
||||
protected:
|
||||
TIntermTyped* operand;
|
||||
};
|
||||
|
||||
typedef TVector<TIntermNode*> TIntermSequence;
|
||||
typedef TVector<int> TQualifierList;
|
||||
typedef TMap<TString, TString> TPragmaTable;
|
||||
//
|
||||
// Nodes that operate on an arbitrary sized set of children.
|
||||
//
|
||||
|
@ -387,28 +413,32 @@ public:
|
|||
TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(0) { }
|
||||
TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(0) { }
|
||||
~TIntermAggregate() { delete pragmaTable; }
|
||||
|
||||
virtual TIntermAggregate* getAsAggregate() { return this; }
|
||||
virtual void setOperator(TOperator o) { op = o; }
|
||||
virtual TIntermSequence& getSequence() { return sequence; }
|
||||
virtual void setName(const TString& n) { name = n; }
|
||||
virtual const TString& getName() const { return name; }
|
||||
virtual void traverse(TIntermTraverser*);
|
||||
virtual void setUserDefined() { userDefined = true; }
|
||||
virtual bool isUserDefined() { return userDefined; }
|
||||
virtual TQualifierList& getQualifier() { return qualifier; }
|
||||
|
||||
TIntermSequence& getSequence() { return sequence; }
|
||||
|
||||
void setName(const TString& n) { name = n; }
|
||||
const TString& getName() const { return name; }
|
||||
|
||||
void setUserDefined() { userDefined = true; }
|
||||
bool isUserDefined() { return userDefined; }
|
||||
|
||||
void setOptimize(bool o) { optimize = o; }
|
||||
void setDebug(bool d) { debug = d; }
|
||||
bool getOptimize() { return optimize; }
|
||||
void setDebug(bool d) { debug = d; }
|
||||
bool getDebug() { return debug; }
|
||||
void addToPragmaTable(const TPragmaTable& pTable);
|
||||
const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
|
||||
|
||||
protected:
|
||||
TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
|
||||
TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
|
||||
TIntermSequence sequence;
|
||||
TQualifierList qualifier;
|
||||
TString name;
|
||||
bool userDefined; // used for user defined function names
|
||||
|
||||
bool optimize;
|
||||
bool debug;
|
||||
TPragmaTable *pragmaTable;
|
||||
|
@ -423,12 +453,15 @@ public:
|
|||
TIntermTyped(TType(EbtVoid, EbpUndefined)), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
|
||||
TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
|
||||
TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
|
||||
|
||||
virtual void traverse(TIntermTraverser*);
|
||||
|
||||
bool usesTernaryOperator() const { return getBasicType() != EbtVoid; }
|
||||
virtual TIntermNode* getCondition() const { return condition; }
|
||||
virtual TIntermNode* getTrueBlock() const { return trueBlock; }
|
||||
virtual TIntermNode* getFalseBlock() const { return falseBlock; }
|
||||
virtual TIntermSelection* getAsSelectionNode() { return this; }
|
||||
TIntermNode* getCondition() const { return condition; }
|
||||
TIntermNode* getTrueBlock() const { return trueBlock; }
|
||||
TIntermNode* getFalseBlock() const { return falseBlock; }
|
||||
TIntermSelection* getAsSelectionNode() { return this; }
|
||||
|
||||
protected:
|
||||
TIntermTyped* condition;
|
||||
TIntermNode* trueBlock;
|
||||
|
|
|
@ -44,7 +44,7 @@ public:
|
|||
TIntermBranch* addBranch(TOperator, TSourceLoc);
|
||||
TIntermBranch* addBranch(TOperator, TIntermTyped*, TSourceLoc);
|
||||
TIntermTyped* addSwizzle(TVectorFields&, TSourceLoc);
|
||||
bool postProcess(TIntermNode*, EShLanguage);
|
||||
bool postProcess(TIntermNode*);
|
||||
void remove(TIntermNode*);
|
||||
void outputTree(TIntermNode*);
|
||||
|
||||
|
|
|
@ -89,10 +89,10 @@ struct CPPStruct_Rec {
|
|||
// Globals used to communicate between PaParseStrings() and yy_input()and
|
||||
// also across the files.(gen_glslang.cpp and scanner.c)
|
||||
//
|
||||
int PaWhichStr; // which string we're parsing
|
||||
int* PaStrLen; // array of lengths of the PaArgv strings
|
||||
int PaArgc; // count of strings in the array
|
||||
char** PaArgv; // our array of strings to parse
|
||||
int PaWhichStr; // which string we're parsing
|
||||
const int* PaStrLen; // array of lengths of the PaArgv strings
|
||||
int PaArgc; // count of strings in the array
|
||||
const char* const* PaArgv; // our array of strings to parse
|
||||
unsigned int tokensBeforeEOF : 1;
|
||||
};
|
||||
|
||||
|
|
|
@ -47,5 +47,5 @@ extern CPPStruct *cpp;
|
|||
int InitCPPStruct(void);
|
||||
int InitScanner(CPPStruct *cpp);
|
||||
int InitAtomTable(AtomTable *atable, int htsize);
|
||||
int ScanFromString(char *s);
|
||||
int ScanFromString(const char *s);
|
||||
char* GetStringOfAtom(AtomTable *atable, int atom);
|
||||
|
|
|
@ -170,7 +170,7 @@ static void str_ungetch(StringInputSrc *in, int ch, yystypepp *type) {
|
|||
}
|
||||
} // str_ungetch
|
||||
|
||||
int ScanFromString(char *s)
|
||||
int ScanFromString(const char *s)
|
||||
{
|
||||
|
||||
StringInputSrc *in = malloc(sizeof(StringInputSrc));
|
||||
|
|
|
@ -73,7 +73,7 @@ typedef struct InputSrc {
|
|||
} InputSrc;
|
||||
|
||||
int InitScanner(CPPStruct *cpp); // Intialise the cpp scanner.
|
||||
int ScanFromString(char *); // Start scanning the input from the string mentioned.
|
||||
int ScanFromString(const char *); // Start scanning the input from the string mentioned.
|
||||
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 SetLineNumber(int);
|
||||
|
|
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
|
@ -0,0 +1,38 @@
|
|||
Flex carries the copyright used for BSD software, slightly modified
|
||||
because it originated at the Lawrence Berkeley (not Livermore!) Laboratory,
|
||||
which operates under a contract with the Department of Energy:
|
||||
|
||||
Copyright (c) 1990 The Regents of the University of California.
|
||||
All rights reserved.
|
||||
|
||||
This code is derived from software contributed to Berkeley by
|
||||
Vern Paxson.
|
||||
|
||||
The United States Government has rights in this work pursuant
|
||||
to contract no. DE-AC03-76SF00098 between the United States
|
||||
Department of Energy and the University of California.
|
||||
|
||||
Redistribution and use in source and binary forms are permitted
|
||||
provided that: (1) source distributions retain this entire
|
||||
copyright notice and comment, and (2) distributions including
|
||||
binaries display the following acknowledgement: ``This product
|
||||
includes software developed by the University of California,
|
||||
Berkeley and its contributors'' in the documentation or other
|
||||
materials provided with the distribution and in all advertising
|
||||
materials mentioning features or use of this software. Neither the
|
||||
name of the University nor the names of its contributors may be
|
||||
used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE.
|
||||
|
||||
This basically says "do whatever you please with this software except
|
||||
remove this notice or take advantage of the University's (or the flex
|
||||
authors') name".
|
||||
|
||||
Note that the "flex.skl" scanner skeleton carries no copyright notice.
|
||||
You are free to do whatever you please with scanners generated using flex;
|
||||
for them, you are not even bound by the above copyright.
|
|
@ -0,0 +1,14 @@
|
|||
The standalone Bison and Flex win32 executables
|
||||
were created by Wilbur Streett and can be obtained from:
|
||||
http://userpages.monmouth.com/~wstreett/lex-yacc/lex-yacc.html
|
||||
|
||||
Bison version 1.24:
|
||||
See COPYING.bison for license information.
|
||||
The original source distribution for bison can be obtained from the following location:
|
||||
http://angleproject.googlecode.com/files/bison.zip
|
||||
|
||||
Flex version 2.5.2
|
||||
See COPYING.flex for license information.
|
||||
The original source distribution for flex can be obtained from the following location:
|
||||
http://angleproject.googlecode.com/files/flex.zip
|
||||
|
Двоичный файл не отображается.
|
@ -0,0 +1,334 @@
|
|||
|
||||
extern int timeclock;
|
||||
|
||||
|
||||
int yyerror; /* Yyerror and yycost are set by guards. */
|
||||
int yycost; /* If yyerror is set to a nonzero value by a */
|
||||
/* guard, the reduction with which the guard */
|
||||
/* is associated is not performed, and the */
|
||||
/* error recovery mechanism is invoked. */
|
||||
/* Yycost indicates the cost of performing */
|
||||
/* the reduction given the attributes of the */
|
||||
/* symbols. */
|
||||
|
||||
|
||||
/* YYMAXDEPTH indicates the size of the parser's state and value */
|
||||
/* stacks. */
|
||||
|
||||
#ifndef YYMAXDEPTH
|
||||
#define YYMAXDEPTH 500
|
||||
#endif
|
||||
|
||||
/* YYMAXRULES must be at least as large as the number of rules that */
|
||||
/* could be placed in the rule queue. That number could be determined */
|
||||
/* from the grammar and the size of the stack, but, as yet, it is not. */
|
||||
|
||||
#ifndef YYMAXRULES
|
||||
#define YYMAXRULES 100
|
||||
#endif
|
||||
|
||||
#ifndef YYMAXBACKUP
|
||||
#define YYMAXBACKUP 100
|
||||
#endif
|
||||
|
||||
|
||||
short yyss[YYMAXDEPTH]; /* the state stack */
|
||||
YYSTYPE yyvs[YYMAXDEPTH]; /* the semantic value stack */
|
||||
YYLTYPE yyls[YYMAXDEPTH]; /* the location stack */
|
||||
short yyrq[YYMAXRULES]; /* the rule queue */
|
||||
int yychar; /* the lookahead symbol */
|
||||
|
||||
YYSTYPE yylval; /* the semantic value of the */
|
||||
/* lookahead symbol */
|
||||
|
||||
YYSTYPE yytval; /* the semantic value for the state */
|
||||
/* at the top of the state stack. */
|
||||
|
||||
YYSTYPE yyval; /* the variable used to return */
|
||||
/* semantic values from the action */
|
||||
/* routines */
|
||||
|
||||
YYLTYPE yylloc; /* location data for the lookahead */
|
||||
/* symbol */
|
||||
|
||||
YYLTYPE yytloc; /* location data for the state at the */
|
||||
/* top of the state stack */
|
||||
|
||||
|
||||
int yynunlexed;
|
||||
short yyunchar[YYMAXBACKUP];
|
||||
YYSTYPE yyunval[YYMAXBACKUP];
|
||||
YYLTYPE yyunloc[YYMAXBACKUP];
|
||||
|
||||
short *yygssp; /* a pointer to the top of the state */
|
||||
/* stack; only set during error */
|
||||
/* recovery. */
|
||||
|
||||
YYSTYPE *yygvsp; /* a pointer to the top of the value */
|
||||
/* stack; only set during error */
|
||||
/* recovery. */
|
||||
|
||||
YYLTYPE *yyglsp; /* a pointer to the top of the */
|
||||
/* location stack; only set during */
|
||||
/* error recovery. */
|
||||
|
||||
|
||||
/* Yyget is an interface between the parser and the lexical analyzer. */
|
||||
/* It is costly to provide such an interface, but it avoids requiring */
|
||||
/* the lexical analyzer to be able to back up the scan. */
|
||||
|
||||
yyget()
|
||||
{
|
||||
if (yynunlexed > 0)
|
||||
{
|
||||
yynunlexed--;
|
||||
yychar = yyunchar[yynunlexed];
|
||||
yylval = yyunval[yynunlexed];
|
||||
yylloc = yyunloc[yynunlexed];
|
||||
}
|
||||
else if (yychar <= 0)
|
||||
yychar = 0;
|
||||
else
|
||||
{
|
||||
yychar = yylex();
|
||||
if (yychar < 0)
|
||||
yychar = 0;
|
||||
else yychar = YYTRANSLATE(yychar);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
yyunlex(chr, val, loc)
|
||||
int chr;
|
||||
YYSTYPE val;
|
||||
YYLTYPE loc;
|
||||
{
|
||||
yyunchar[yynunlexed] = chr;
|
||||
yyunval[yynunlexed] = val;
|
||||
yyunloc[yynunlexed] = loc;
|
||||
yynunlexed++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
yyrestore(first, last)
|
||||
register short *first;
|
||||
register short *last;
|
||||
{
|
||||
register short *ssp;
|
||||
register short *rp;
|
||||
register int symbol;
|
||||
register int state;
|
||||
register int tvalsaved;
|
||||
|
||||
ssp = yygssp;
|
||||
yyunlex(yychar, yylval, yylloc);
|
||||
|
||||
tvalsaved = 0;
|
||||
while (first != last)
|
||||
{
|
||||
symbol = yystos[*ssp];
|
||||
if (symbol < YYNTBASE)
|
||||
{
|
||||
yyunlex(symbol, yytval, yytloc);
|
||||
tvalsaved = 1;
|
||||
ssp--;
|
||||
}
|
||||
|
||||
ssp--;
|
||||
|
||||
if (first == yyrq)
|
||||
first = yyrq + YYMAXRULES;
|
||||
|
||||
first--;
|
||||
|
||||
for (rp = yyrhs + yyprhs[*first]; symbol = *rp; rp++)
|
||||
{
|
||||
if (symbol < YYNTBASE)
|
||||
state = yytable[yypact[*ssp] + symbol];
|
||||
else
|
||||
{
|
||||
state = yypgoto[symbol - YYNTBASE] + *ssp;
|
||||
|
||||
if (state >= 0 && state <= YYLAST && yycheck[state] == *ssp)
|
||||
state = yytable[state];
|
||||
else
|
||||
state = yydefgoto[symbol - YYNTBASE];
|
||||
}
|
||||
|
||||
*++ssp = state;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! tvalsaved && ssp > yyss)
|
||||
{
|
||||
yyunlex(yystos[*ssp], yytval, yytloc);
|
||||
ssp--;
|
||||
}
|
||||
|
||||
yygssp = ssp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
yyparse()
|
||||
{
|
||||
register int yystate;
|
||||
register int yyn;
|
||||
register short *yyssp;
|
||||
register short *yyrq0;
|
||||
register short *yyptr;
|
||||
register YYSTYPE *yyvsp;
|
||||
|
||||
int yylen;
|
||||
YYLTYPE *yylsp;
|
||||
short *yyrq1;
|
||||
short *yyrq2;
|
||||
|
||||
yystate = 0;
|
||||
yyssp = yyss - 1;
|
||||
yyvsp = yyvs - 1;
|
||||
yylsp = yyls - 1;
|
||||
yyrq0 = yyrq;
|
||||
yyrq1 = yyrq0;
|
||||
yyrq2 = yyrq0;
|
||||
|
||||
yychar = yylex();
|
||||
if (yychar < 0)
|
||||
yychar = 0;
|
||||
else yychar = YYTRANSLATE(yychar);
|
||||
|
||||
yynewstate:
|
||||
|
||||
if (yyssp >= yyss + YYMAXDEPTH - 1)
|
||||
{
|
||||
yyabort("Parser Stack Overflow");
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
*++yyssp = yystate;
|
||||
|
||||
yyresume:
|
||||
|
||||
yyn = yypact[yystate];
|
||||
if (yyn == YYFLAG)
|
||||
goto yydefault;
|
||||
|
||||
yyn += yychar;
|
||||
if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar)
|
||||
goto yydefault;
|
||||
|
||||
yyn = yytable[yyn];
|
||||
if (yyn < 0)
|
||||
{
|
||||
yyn = -yyn;
|
||||
goto yyreduce;
|
||||
}
|
||||
else if (yyn == 0)
|
||||
goto yyerrlab;
|
||||
|
||||
yystate = yyn;
|
||||
|
||||
yyptr = yyrq2;
|
||||
while (yyptr != yyrq1)
|
||||
{
|
||||
yyn = *yyptr++;
|
||||
yylen = yyr2[yyn];
|
||||
yyvsp -= yylen;
|
||||
yylsp -= yylen;
|
||||
|
||||
yyguard(yyn, yyvsp, yylsp);
|
||||
if (yyerror)
|
||||
goto yysemerr;
|
||||
|
||||
yyaction(yyn, yyvsp, yylsp);
|
||||
*++yyvsp = yyval;
|
||||
|
||||
yylsp++;
|
||||
if (yylen == 0)
|
||||
{
|
||||
yylsp->timestamp = timeclock;
|
||||
yylsp->first_line = yytloc.first_line;
|
||||
yylsp->first_column = yytloc.first_column;
|
||||
yylsp->last_line = (yylsp-1)->last_line;
|
||||
yylsp->last_column = (yylsp-1)->last_column;
|
||||
yylsp->text = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
yylsp->last_line = (yylsp+yylen-1)->last_line;
|
||||
yylsp->last_column = (yylsp+yylen-1)->last_column;
|
||||
}
|
||||
|
||||
if (yyptr == yyrq + YYMAXRULES)
|
||||
yyptr = yyrq;
|
||||
}
|
||||
|
||||
if (yystate == YYFINAL)
|
||||
YYACCEPT;
|
||||
|
||||
yyrq2 = yyptr;
|
||||
yyrq1 = yyrq0;
|
||||
|
||||
*++yyvsp = yytval;
|
||||
*++yylsp = yytloc;
|
||||
yytval = yylval;
|
||||
yytloc = yylloc;
|
||||
yyget();
|
||||
|
||||
goto yynewstate;
|
||||
|
||||
yydefault:
|
||||
|
||||
yyn = yydefact[yystate];
|
||||
if (yyn == 0)
|
||||
goto yyerrlab;
|
||||
|
||||
yyreduce:
|
||||
|
||||
*yyrq0++ = yyn;
|
||||
|
||||
if (yyrq0 == yyrq + YYMAXRULES)
|
||||
yyrq0 = yyrq;
|
||||
|
||||
if (yyrq0 == yyrq2)
|
||||
{
|
||||
yyabort("Parser Rule Queue Overflow");
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
yyssp -= yyr2[yyn];
|
||||
yyn = yyr1[yyn];
|
||||
|
||||
yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
|
||||
if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
|
||||
yystate = yytable[yystate];
|
||||
else
|
||||
yystate = yydefgoto[yyn - YYNTBASE];
|
||||
|
||||
goto yynewstate;
|
||||
|
||||
yysemerr:
|
||||
*--yyptr = yyn;
|
||||
yyrq2 = yyptr;
|
||||
yyvsp += yyr2[yyn];
|
||||
|
||||
yyerrlab:
|
||||
|
||||
yygssp = yyssp;
|
||||
yygvsp = yyvsp;
|
||||
yyglsp = yylsp;
|
||||
yyrestore(yyrq0, yyrq2);
|
||||
yyrecover();
|
||||
yystate = *yygssp;
|
||||
yyssp = yygssp;
|
||||
yyvsp = yygvsp;
|
||||
yyrq0 = yyrq;
|
||||
yyrq1 = yyrq0;
|
||||
yyrq2 = yyrq0;
|
||||
goto yyresume;
|
||||
}
|
||||
|
||||
$
|
|
@ -0,0 +1,699 @@
|
|||
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
|
||||
|
||||
/* Skeleton output parser for bison,
|
||||
Copyright (C) 1984, 1989, 1990 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.
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* As a special exception, when this file is copied by Bison into a
|
||||
Bison output file, you may use that output file without restriction.
|
||||
This special exception was added by the Free Software Foundation
|
||||
in version 1.24 of Bison. */
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define alloca __builtin_alloca
|
||||
#else /* not __GNUC__ */
|
||||
#if HAVE_ALLOCA_H
|
||||
#include <alloca.h>
|
||||
#else /* not HAVE_ALLOCA_H */
|
||||
#ifdef _AIX
|
||||
#pragma alloca
|
||||
#else /* not _AIX */
|
||||
char *alloca ();
|
||||
#endif /* not _AIX */
|
||||
#endif /* not HAVE_ALLOCA_H */
|
||||
#endif /* not __GNUC__ */
|
||||
|
||||
extern void yyerror(char* s);
|
||||
|
||||
#ifndef alloca
|
||||
#ifdef __GNUC__
|
||||
#define alloca __builtin_alloca
|
||||
#else /* not GNU C. */
|
||||
#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
|
||||
#include <alloca.h>
|
||||
#else /* not sparc */
|
||||
#if (defined (MSDOS) && !defined (__TURBOC__)) || defined (WIN32)
|
||||
#include <malloc.h>
|
||||
#else /* not MSDOS, or __TURBOC__ */
|
||||
#if defined(_AIX)
|
||||
#include <malloc.h>
|
||||
#pragma alloca
|
||||
#else /* not MSDOS, __TURBOC__, or _AIX */
|
||||
#ifdef __hpux
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
void *alloca (unsigned int);
|
||||
};
|
||||
#else /* not __cplusplus */
|
||||
void *alloca ();
|
||||
#endif /* not __cplusplus */
|
||||
#endif /* __hpux */
|
||||
#endif /* not _AIX */
|
||||
#endif /* not MSDOS, or __TURBOC__ */
|
||||
#endif /* not sparc. */
|
||||
#endif /* not GNU C. */
|
||||
#endif /* alloca not defined. */
|
||||
|
||||
/* This is the parser code that is written into each bison parser
|
||||
when the %semantic_parser declaration is not specified in the grammar.
|
||||
It was written by Richard Stallman by simplifying the hairy parser
|
||||
used when %semantic_parser is specified. */
|
||||
|
||||
/* Note: there must be only one dollar sign in this file.
|
||||
It is replaced by the list of actions, each action
|
||||
as one case of the switch. */
|
||||
|
||||
#define yyerrok (yyerrstatus = 0)
|
||||
#define yyclearin (yychar = YYEMPTY)
|
||||
#define YYEMPTY -2
|
||||
#define YYEOF 0
|
||||
#define YYACCEPT return(0)
|
||||
#define YYABORT return(1)
|
||||
#define YYERROR goto yyerrlab1
|
||||
/* 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. */
|
||||
#define YYFAIL goto yyerrlab
|
||||
#define YYRECOVERING() (!!yyerrstatus)
|
||||
#define YYBACKUP(token, value) \
|
||||
do \
|
||||
if (yychar == YYEMPTY && yylen == 1) \
|
||||
{ yychar = (token), yylval = (value); \
|
||||
yychar1 = YYTRANSLATE (yychar); \
|
||||
YYPOPSTACK; \
|
||||
goto yybackup; \
|
||||
} \
|
||||
else \
|
||||
{ yyerror ("syntax error: cannot back up"); YYERROR; } \
|
||||
while (0)
|
||||
|
||||
#define YYTERROR 1
|
||||
#define YYERRCODE 256
|
||||
|
||||
#ifndef YYPURE
|
||||
#define YYLEX yylex()
|
||||
#endif
|
||||
|
||||
#ifdef YYPURE
|
||||
#ifdef YYLSP_NEEDED
|
||||
#ifdef YYLEX_PARAM
|
||||
#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
|
||||
#else
|
||||
#define YYLEX yylex(&yylval, &yylloc)
|
||||
#endif
|
||||
#else /* not YYLSP_NEEDED */
|
||||
#ifdef YYLEX_PARAM
|
||||
#define YYLEX yylex(&yylval, YYLEX_PARAM)
|
||||
#else
|
||||
#define YYLEX yylex(&yylval)
|
||||
#endif
|
||||
#endif /* not YYLSP_NEEDED */
|
||||
#endif
|
||||
|
||||
/* If nonreentrant, generate the variables here */
|
||||
|
||||
#ifndef YYPURE
|
||||
|
||||
int yychar; /* the lookahead symbol */
|
||||
YYSTYPE yylval; /* the semantic value of the */
|
||||
/* lookahead symbol */
|
||||
|
||||
#ifdef YYLSP_NEEDED
|
||||
YYLTYPE yylloc; /* location data for the lookahead */
|
||||
/* symbol */
|
||||
#endif
|
||||
|
||||
int yynerrs; /* number of parse errors so far */
|
||||
#endif /* not YYPURE */
|
||||
|
||||
#if YYDEBUG != 0
|
||||
int yydebug; /* nonzero means print parse trace */
|
||||
/* Since this is uninitialized, it does not stop multiple parsers
|
||||
from coexisting. */
|
||||
#endif
|
||||
|
||||
/* YYINITDEPTH indicates the initial size of the parser's stacks */
|
||||
|
||||
#ifndef YYINITDEPTH
|
||||
#define YYINITDEPTH 200
|
||||
#endif
|
||||
|
||||
/* YYMAXDEPTH is the maximum size the stacks can grow to
|
||||
(effective only if the built-in stack extension method is used). */
|
||||
|
||||
#if YYMAXDEPTH == 0
|
||||
#undef YYMAXDEPTH
|
||||
#endif
|
||||
|
||||
#ifndef YYMAXDEPTH
|
||||
#define YYMAXDEPTH 10000
|
||||
#endif
|
||||
|
||||
/* Prevent warning if -Wstrict-prototypes. */
|
||||
#ifdef __GNUC__
|
||||
int yyparse (void);
|
||||
#endif
|
||||
|
||||
#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
|
||||
#define __yy_memcpy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT)
|
||||
#else /* not GNU C or C++ */
|
||||
#ifndef __cplusplus
|
||||
|
||||
/* This is the most reliable way to avoid incompatibilities
|
||||
in available built-in functions on various systems. */
|
||||
static void
|
||||
__yy_memcpy (from, to, count)
|
||||
char *from;
|
||||
char *to;
|
||||
size_t count;
|
||||
{
|
||||
register char *f = from;
|
||||
register char *t = to;
|
||||
register size_t i = count;
|
||||
|
||||
while (i-- > 0)
|
||||
*t++ = *f++;
|
||||
}
|
||||
|
||||
#else /* __cplusplus */
|
||||
|
||||
/* This is the most reliable way to avoid incompatibilities
|
||||
in available built-in functions on various systems. */
|
||||
static void
|
||||
__yy_memcpy (char *from, char *to, size_t count)
|
||||
{
|
||||
register char *f = from;
|
||||
register char *t = to;
|
||||
register size_t i = count;
|
||||
|
||||
while (i-- > 0)
|
||||
*t++ = *f++;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* The user can define YYPARSE_PARAM as the name of an argument to be passed
|
||||
into yyparse. The argument should have type void *.
|
||||
It should actually point to an object.
|
||||
Grammar actions can access the variable by casting it
|
||||
to the proper pointer type. */
|
||||
|
||||
#ifdef YYPARSE_PARAM
|
||||
#ifndef YYPARSE_PARAM_DECL
|
||||
#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
|
||||
#endif
|
||||
#else
|
||||
#define YYPARSE_PARAM
|
||||
#define YYPARSE_PARAM_DECL
|
||||
#endif
|
||||
|
||||
extern YY_DECL;
|
||||
|
||||
int
|
||||
yyparse(YYPARSE_PARAM_DECL YYPARSE_PARAM) {
|
||||
register int yystate;
|
||||
register int yyn;
|
||||
register short *yyssp;
|
||||
register YYSTYPE *yyvsp;
|
||||
int yyerrstatus; /* number of tokens to shift before error messages enabled */
|
||||
int yychar1 = 0; /* lookahead token as an internal (translated) token number */
|
||||
|
||||
short yyssa[YYINITDEPTH]; /* the state stack */
|
||||
YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
|
||||
|
||||
short *yyss = yyssa; /* refer to the stacks thru separate pointers */
|
||||
YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
|
||||
|
||||
#ifdef YYLSP_NEEDED
|
||||
YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
|
||||
YYLTYPE *yyls = yylsa;
|
||||
YYLTYPE *yylsp;
|
||||
|
||||
#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
|
||||
#else
|
||||
#define YYPOPSTACK (yyvsp--, yyssp--)
|
||||
#endif
|
||||
|
||||
size_t yystacksize = YYINITDEPTH;
|
||||
|
||||
#ifdef YYPURE
|
||||
int yychar;
|
||||
YYSTYPE yylval;
|
||||
int yynerrs;
|
||||
#ifdef YYLSP_NEEDED
|
||||
YYLTYPE yylloc;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
YYSTYPE yyval; /* the variable used to return */
|
||||
/* semantic values from the action */
|
||||
/* routines */
|
||||
|
||||
int yylen;
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
fprintf(stderr, "Starting parse\n");
|
||||
#endif
|
||||
|
||||
yystate = 0;
|
||||
yyerrstatus = 0;
|
||||
yynerrs = 0;
|
||||
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 - 1;
|
||||
yyvsp = yyvs;
|
||||
#ifdef YYLSP_NEEDED
|
||||
yylsp = yyls;
|
||||
#endif
|
||||
|
||||
/* Push a new state, which is found in yystate . */
|
||||
/* In all cases, when you get here, the value and location stacks
|
||||
have just been pushed. so pushing a state here evens the stacks. */
|
||||
yynewstate:
|
||||
|
||||
*++yyssp = yystate;
|
||||
|
||||
if (yyssp >= yyss + yystacksize - 1)
|
||||
{
|
||||
/* Give user a chance to reallocate the stack */
|
||||
/* Use copies of these so that the &'s don't force the real ones into memory. */
|
||||
YYSTYPE *yyvs1 = yyvs;
|
||||
short *yyss1 = yyss;
|
||||
#ifdef YYLSP_NEEDED
|
||||
YYLTYPE *yyls1 = yyls;
|
||||
#endif
|
||||
|
||||
/* Get the current used size of the three stacks, in elements. */
|
||||
size_t size = yyssp - yyss + 1;
|
||||
|
||||
#ifdef yyoverflow
|
||||
/* Each stack pointer address is followed by the size of
|
||||
the data in use in that stack, in bytes. */
|
||||
#ifdef YYLSP_NEEDED
|
||||
/* This used to be a conditional around just the two extra args,
|
||||
but that might be undefined if yyoverflow is a macro. */
|
||||
yyoverflow("parser stack overflow",
|
||||
&yyss1, size * sizeof (*yyssp),
|
||||
&yyvs1, size * sizeof (*yyvsp),
|
||||
&yyls1, size * sizeof (*yylsp),
|
||||
&yystacksize);
|
||||
#else
|
||||
yyoverflow("parser stack overflow",
|
||||
&yyss1, size * sizeof (*yyssp),
|
||||
&yyvs1, size * sizeof (*yyvsp),
|
||||
&yystacksize);
|
||||
#endif
|
||||
|
||||
yyss = yyss1; yyvs = yyvs1;
|
||||
#ifdef YYLSP_NEEDED
|
||||
yyls = yyls1;
|
||||
#endif
|
||||
#else /* no yyoverflow */
|
||||
/* Extend the stack our own way. */
|
||||
if (yystacksize >= YYMAXDEPTH)
|
||||
{
|
||||
yyerror("parser stack overflow");
|
||||
return 2;
|
||||
}
|
||||
yystacksize *= 2;
|
||||
if (yystacksize > YYMAXDEPTH)
|
||||
yystacksize = YYMAXDEPTH;
|
||||
yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
|
||||
__yy_memcpy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp));
|
||||
yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
|
||||
__yy_memcpy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp));
|
||||
#ifdef YYLSP_NEEDED
|
||||
yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
|
||||
__yy_memcpy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp));
|
||||
#endif
|
||||
#endif /* no yyoverflow */
|
||||
|
||||
yyssp = yyss + size - 1;
|
||||
yyvsp = yyvs + size - 1;
|
||||
#ifdef YYLSP_NEEDED
|
||||
yylsp = yyls + size - 1;
|
||||
#endif
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
fprintf(stderr, "Stack size increased to %d\n", yystacksize);
|
||||
#endif
|
||||
|
||||
if (yyssp >= yyss + yystacksize - 1)
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
fprintf(stderr, "Entering state %d\n", yystate);
|
||||
#endif
|
||||
|
||||
goto yybackup;
|
||||
yybackup:
|
||||
|
||||
/* Do appropriate processing given the current state. */
|
||||
/* Read a lookahead token if we need one and don't already have one. */
|
||||
/* yyresume: */
|
||||
|
||||
/* First try to decide what to do without reference to lookahead token. */
|
||||
|
||||
yyn = yypact[yystate];
|
||||
if (yyn == YYFLAG)
|
||||
goto yydefault;
|
||||
|
||||
/* Not known => get a lookahead token if don't already have one. */
|
||||
|
||||
/* yychar is either YYEMPTY or YYEOF
|
||||
or a valid token in external form. */
|
||||
|
||||
if (yychar == YYEMPTY)
|
||||
{
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
fprintf(stderr, "Reading a token: ");
|
||||
#endif
|
||||
yychar = YYLEX;
|
||||
}
|
||||
|
||||
/* Convert token to internal form (in yychar1) for indexing tables with */
|
||||
|
||||
if (yychar <= 0) /* This means end of input. */
|
||||
{
|
||||
yychar1 = 0;
|
||||
yychar = YYEOF; /* Don't call YYLEX any more */
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
fprintf(stderr, "Now at end of input.\n");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
yychar1 = YYTRANSLATE(yychar);
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
{
|
||||
fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
|
||||
/* Give the individual parser a way to print the precise meaning
|
||||
of a token, for further debugging info. */
|
||||
#ifdef YYPRINT
|
||||
YYPRINT (stderr, yychar, yylval);
|
||||
#endif
|
||||
fprintf (stderr, ")\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
yyn += yychar1;
|
||||
if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
|
||||
goto yydefault;
|
||||
|
||||
yyn = yytable[yyn];
|
||||
|
||||
/* yyn is what to do for this token type in this state.
|
||||
Negative => reduce, -yyn is rule number.
|
||||
Positive => shift, yyn is new state.
|
||||
New state is final state => don't bother to shift,
|
||||
just return success.
|
||||
0, or most negative number => error. */
|
||||
|
||||
if (yyn < 0)
|
||||
{
|
||||
if (yyn == YYFLAG)
|
||||
goto yyerrlab;
|
||||
yyn = -yyn;
|
||||
goto yyreduce;
|
||||
}
|
||||
else if (yyn == 0)
|
||||
goto yyerrlab;
|
||||
|
||||
if (yyn == YYFINAL)
|
||||
YYACCEPT;
|
||||
|
||||
/* Shift the lookahead token. */
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
|
||||
#endif
|
||||
|
||||
/* Discard the token being shifted unless it is eof. */
|
||||
if (yychar != YYEOF)
|
||||
yychar = YYEMPTY;
|
||||
|
||||
*++yyvsp = yylval;
|
||||
#ifdef YYLSP_NEEDED
|
||||
*++yylsp = yylloc;
|
||||
#endif
|
||||
|
||||
/* count tokens shifted since error; after three, turn off error status. */
|
||||
if (yyerrstatus) yyerrstatus--;
|
||||
|
||||
yystate = yyn;
|
||||
goto yynewstate;
|
||||
|
||||
/* Do the default action for the current state. */
|
||||
yydefault:
|
||||
|
||||
yyn = yydefact[yystate];
|
||||
if (yyn == 0)
|
||||
goto yyerrlab;
|
||||
|
||||
/* Do a reduction. yyn is the number of a rule to reduce with. */
|
||||
yyreduce:
|
||||
yylen = yyr2[yyn];
|
||||
if (yylen > 0)
|
||||
yyval = yyvsp[1-yylen]; /* implement default value of the action */
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
{
|
||||
int i;
|
||||
|
||||
fprintf (stderr, "Reducing via rule %d (line %d), ",
|
||||
yyn, yyrline[yyn]);
|
||||
|
||||
/* Print the symbols being reduced, and their result. */
|
||||
for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
|
||||
fprintf (stderr, "%s ", yytname[yyrhs[i]]);
|
||||
fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
|
||||
}
|
||||
#endif
|
||||
|
||||
$ /* the action file gets copied in in place of this dollarsign */
|
||||
yyvsp -= yylen;
|
||||
yyssp -= yylen;
|
||||
#ifdef YYLSP_NEEDED
|
||||
yylsp -= yylen;
|
||||
#endif
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
{
|
||||
short *ssp1 = yyss - 1;
|
||||
fprintf (stderr, "state stack now");
|
||||
while (ssp1 != yyssp)
|
||||
fprintf (stderr, " %d", *++ssp1);
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
*++yyvsp = yyval;
|
||||
|
||||
#ifdef YYLSP_NEEDED
|
||||
yylsp++;
|
||||
if (yylen == 0)
|
||||
{
|
||||
yylsp->first_line = yylloc.first_line;
|
||||
yylsp->first_column = yylloc.first_column;
|
||||
yylsp->last_line = (yylsp-1)->last_line;
|
||||
yylsp->last_column = (yylsp-1)->last_column;
|
||||
yylsp->text = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
yylsp->last_line = (yylsp+yylen-1)->last_line;
|
||||
yylsp->last_column = (yylsp+yylen-1)->last_column;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Now "shift" the result of the reduction.
|
||||
Determine what state that goes to,
|
||||
based on the state we popped back to
|
||||
and the rule number reduced by. */
|
||||
|
||||
yyn = yyr1[yyn];
|
||||
|
||||
yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
|
||||
if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
|
||||
yystate = yytable[yystate];
|
||||
else
|
||||
yystate = yydefgoto[yyn - YYNTBASE];
|
||||
|
||||
goto yynewstate;
|
||||
|
||||
yyerrlab: /* here on detecting error */
|
||||
|
||||
if (! yyerrstatus)
|
||||
/* If not already recovering from an error, report this error. */
|
||||
{
|
||||
++yynerrs;
|
||||
|
||||
#ifdef YYERROR_VERBOSE
|
||||
yyn = yypact[yystate];
|
||||
|
||||
if (yyn > YYFLAG && yyn < YYLAST)
|
||||
{
|
||||
int size = 0;
|
||||
char *msg;
|
||||
int x, count;
|
||||
|
||||
count = 0;
|
||||
/* Start X at -yyn if nec to avoid negative indexes in yycheck. */
|
||||
for (x = (yyn < 0 ? -yyn : 0);
|
||||
x < (sizeof(yytname) / sizeof(char *)); x++)
|
||||
if (yycheck[x + yyn] == x)
|
||||
size += strlen(yytname[x]) + 15, count++;
|
||||
msg = (char *) malloc(size + 15);
|
||||
if (msg != 0)
|
||||
{
|
||||
strcpy(msg, "parse error");
|
||||
|
||||
if (count < 5)
|
||||
{
|
||||
count = 0;
|
||||
for (x = (yyn < 0 ? -yyn : 0);
|
||||
x < (sizeof(yytname) / sizeof(char *)); x++)
|
||||
if (yycheck[x + yyn] == x)
|
||||
{
|
||||
strcat(msg, count == 0 ? ", expecting `" : " or `");
|
||||
strcat(msg, yytname[x]);
|
||||
strcat(msg, "'");
|
||||
count++;
|
||||
}
|
||||
}
|
||||
yyerror(msg);
|
||||
free(msg);
|
||||
}
|
||||
else
|
||||
yyerror ("parse error; also virtual memory exceeded");
|
||||
}
|
||||
else
|
||||
#endif /* YYERROR_VERBOSE */
|
||||
yyerror("parse error");
|
||||
}
|
||||
|
||||
goto yyerrlab1;
|
||||
yyerrlab1: /* here on error raised explicitly by an action */
|
||||
|
||||
if (yyerrstatus == 3)
|
||||
{
|
||||
/* if just tried and failed to reuse lookahead token after an error, discard it. */
|
||||
|
||||
/* return failure if at end of input */
|
||||
if (yychar == YYEOF)
|
||||
YYABORT;
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
|
||||
#endif
|
||||
|
||||
yychar = YYEMPTY;
|
||||
}
|
||||
|
||||
/* Else will try to reuse lookahead token
|
||||
after shifting the error token. */
|
||||
|
||||
yyerrstatus = 3; /* Each real token shifted decrements this */
|
||||
|
||||
goto yyerrhandle;
|
||||
|
||||
yyerrdefault: /* current state does not do anything special for the error token. */
|
||||
|
||||
#if 0
|
||||
/* This is wrong; only states that explicitly want error tokens
|
||||
should shift them. */
|
||||
yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
|
||||
if (yyn) goto yydefault;
|
||||
#endif
|
||||
|
||||
yyerrpop: /* pop the current state because it cannot handle the error token */
|
||||
|
||||
if (yyssp == yyss) YYABORT;
|
||||
yyvsp--;
|
||||
yystate = *--yyssp;
|
||||
#ifdef YYLSP_NEEDED
|
||||
yylsp--;
|
||||
#endif
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
{
|
||||
short *ssp1 = yyss - 1;
|
||||
fprintf (stderr, "Error: state stack now");
|
||||
while (ssp1 != yyssp)
|
||||
fprintf (stderr, " %d", *++ssp1);
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
yyerrhandle:
|
||||
|
||||
yyn = yypact[yystate];
|
||||
if (yyn == YYFLAG)
|
||||
goto yyerrdefault;
|
||||
|
||||
yyn += YYTERROR;
|
||||
if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
|
||||
goto yyerrdefault;
|
||||
|
||||
yyn = yytable[yyn];
|
||||
if (yyn < 0)
|
||||
{
|
||||
if (yyn == YYFLAG)
|
||||
goto yyerrpop;
|
||||
yyn = -yyn;
|
||||
goto yyreduce;
|
||||
}
|
||||
else if (yyn == 0)
|
||||
goto yyerrpop;
|
||||
|
||||
if (yyn == YYFINAL)
|
||||
YYACCEPT;
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
fprintf(stderr, "Shifting error token, ");
|
||||
#endif
|
||||
|
||||
*++yyvsp = yylval;
|
||||
#ifdef YYLSP_NEEDED
|
||||
*++yylsp = yylloc;
|
||||
#endif
|
||||
|
||||
yystate = yyn;
|
||||
goto yynewstate;
|
||||
}
|
Двоичный файл не отображается.
|
@ -151,6 +151,10 @@
|
|||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\Compiler.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\debug.cpp"
|
||||
>
|
||||
|
@ -261,6 +265,10 @@
|
|||
RelativePath=".\SymbolTable.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\VariableInfo.cpp"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="preprocessor"
|
||||
>
|
||||
|
@ -403,6 +411,10 @@
|
|||
RelativePath=".\unistd.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\VariableInfo.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="preprocessor"
|
||||
>
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
|
||||
#include "libEGL/main.h"
|
||||
|
||||
#define REF_RAST 0 // Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros
|
||||
#define REF_RAST 0 // Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros
|
||||
#define ENABLE_D3D9EX 1 // Enables use of the IDirect3D9Ex interface, when available
|
||||
|
||||
namespace egl
|
||||
{
|
||||
|
@ -40,7 +41,6 @@ Display::Display(HDC deviceContext) : mDc(deviceContext)
|
|||
|
||||
mMinSwapInterval = 1;
|
||||
mMaxSwapInterval = 1;
|
||||
setSwapInterval(1);
|
||||
}
|
||||
|
||||
Display::~Display()
|
||||
|
@ -77,7 +77,7 @@ bool Display::initialize()
|
|||
// Use Direct3D9Ex if available. Among other things, this version is less
|
||||
// inclined to report a lost context, for example when the user switches
|
||||
// desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are available.
|
||||
if (Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9ex)))
|
||||
if (ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9ex)))
|
||||
{
|
||||
ASSERT(mD3d9ex);
|
||||
mD3d9ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9));
|
||||
|
@ -95,12 +95,24 @@ bool Display::initialize()
|
|||
// UNIMPLEMENTED(); // FIXME: Determine which adapter index the device context corresponds to
|
||||
}
|
||||
|
||||
HRESULT result = mD3d9->GetDeviceCaps(mAdapter, mDeviceType, &mDeviceCaps);
|
||||
|
||||
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
|
||||
HRESULT result;
|
||||
|
||||
do
|
||||
{
|
||||
return error(EGL_BAD_ALLOC, false);
|
||||
result = mD3d9->GetDeviceCaps(mAdapter, mDeviceType, &mDeviceCaps);
|
||||
|
||||
if (result == D3DERR_NOTAVAILABLE)
|
||||
{
|
||||
Sleep(0); // Give the driver some time to initialize/recover
|
||||
}
|
||||
else if (FAILED(result)) // D3DERR_OUTOFVIDEOMEMORY, E_OUTOFMEMORY, D3DERR_INVALIDDEVICE, or another error we can't recover from
|
||||
{
|
||||
return error(EGL_BAD_ALLOC, false);
|
||||
}
|
||||
}
|
||||
while(result == D3DERR_NOTAVAILABLE);
|
||||
|
||||
ASSERT(SUCCEEDED(result));
|
||||
|
||||
if (mDeviceCaps.PixelShaderVersion < D3DPS_VERSION(2, 0))
|
||||
{
|
||||
|
@ -164,7 +176,7 @@ bool Display::initialize()
|
|||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
// FIXME: Enumerate multi-sampling
|
||||
// FIXME: enumerate multi-sampling
|
||||
|
||||
configSet.add(currentDisplayMode, mMinSwapInterval, mMaxSwapInterval, renderTargetFormat, depthStencilFormat, 0);
|
||||
}
|
||||
|
@ -183,13 +195,6 @@ bool Display::initialize()
|
|||
|
||||
mConfigSet.mSet.insert(configuration);
|
||||
}
|
||||
|
||||
if (!createDevice())
|
||||
{
|
||||
terminate();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isInitialized())
|
||||
|
@ -199,23 +204,34 @@ bool Display::initialize()
|
|||
return false;
|
||||
}
|
||||
|
||||
static const TCHAR windowName[] = TEXT("AngleHiddenWindow");
|
||||
static const TCHAR className[] = TEXT("STATIC");
|
||||
|
||||
mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Display::terminate()
|
||||
{
|
||||
for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
|
||||
while (!mSurfaceSet.empty())
|
||||
{
|
||||
delete *surface;
|
||||
destroySurface(*mSurfaceSet.begin());
|
||||
}
|
||||
|
||||
for (ContextSet::iterator context = mContextSet.begin(); context != mContextSet.end(); context++)
|
||||
while (!mContextSet.empty())
|
||||
{
|
||||
glDestroyContext(*context);
|
||||
destroyContext(*mContextSet.begin());
|
||||
}
|
||||
|
||||
if (mDevice)
|
||||
{
|
||||
// If the device is lost, reset it first to prevent leaving the driver in an unstable state
|
||||
if (FAILED(mDevice->TestCooperativeLevel()))
|
||||
{
|
||||
resetDevice();
|
||||
}
|
||||
|
||||
mDevice->Release();
|
||||
mDevice = NULL;
|
||||
}
|
||||
|
@ -314,33 +330,12 @@ bool Display::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value)
|
|||
|
||||
bool Display::createDevice()
|
||||
{
|
||||
static const TCHAR windowName[] = TEXT("AngleHiddenWindow");
|
||||
static const TCHAR className[] = TEXT("STATIC");
|
||||
|
||||
mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);
|
||||
|
||||
D3DPRESENT_PARAMETERS presentParameters = {0};
|
||||
|
||||
// The default swap chain is never actually used. Surface will create a new swap chain with the proper parameters.
|
||||
presentParameters.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
|
||||
presentParameters.BackBufferCount = 1;
|
||||
presentParameters.BackBufferFormat = D3DFMT_UNKNOWN;
|
||||
presentParameters.BackBufferWidth = 1;
|
||||
presentParameters.BackBufferHeight = 1;
|
||||
presentParameters.EnableAutoDepthStencil = FALSE;
|
||||
presentParameters.Flags = 0;
|
||||
presentParameters.hDeviceWindow = mDeviceWindow;
|
||||
presentParameters.MultiSampleQuality = 0;
|
||||
presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
|
||||
presentParameters.PresentationInterval = convertInterval(mMinSwapInterval);
|
||||
presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
presentParameters.Windowed = TRUE;
|
||||
|
||||
D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
|
||||
DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES;
|
||||
|
||||
HRESULT result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice);
|
||||
|
||||
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
|
||||
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DEVICELOST)
|
||||
{
|
||||
return error(EGL_BAD_ALLOC, false);
|
||||
}
|
||||
|
@ -349,14 +344,13 @@ bool Display::createDevice()
|
|||
{
|
||||
result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentParameters, &mDevice);
|
||||
|
||||
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
|
||||
if (FAILED(result))
|
||||
{
|
||||
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_NOTAVAILABLE || result == D3DERR_DEVICELOST);
|
||||
return error(EGL_BAD_ALLOC, false);
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(SUCCEEDED(result));
|
||||
|
||||
// Permanent non-default states
|
||||
mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
|
||||
|
||||
|
@ -365,6 +359,29 @@ bool Display::createDevice()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Display::resetDevice()
|
||||
{
|
||||
D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
|
||||
HRESULT result;
|
||||
|
||||
do
|
||||
{
|
||||
Sleep(0); // Give the graphics driver some CPU time
|
||||
|
||||
result = mDevice->Reset(&presentParameters);
|
||||
}
|
||||
while (result == D3DERR_DEVICELOST);
|
||||
|
||||
if (FAILED(result))
|
||||
{
|
||||
return error(EGL_BAD_ALLOC, false);
|
||||
}
|
||||
|
||||
ASSERT(SUCCEEDED(result));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Surface *Display::createWindowSurface(HWND window, EGLConfig config)
|
||||
{
|
||||
const Config *configuration = mConfigSet.get(config);
|
||||
|
@ -377,6 +394,27 @@ Surface *Display::createWindowSurface(HWND window, EGLConfig config)
|
|||
|
||||
EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *shareContext)
|
||||
{
|
||||
if (!mDevice)
|
||||
{
|
||||
if (!createDevice())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if (FAILED(mDevice->TestCooperativeLevel())) // Lost device
|
||||
{
|
||||
if (!resetDevice())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Restore any surfaces that may have been lost
|
||||
for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
|
||||
{
|
||||
(*surface)->resetSwapChain();
|
||||
}
|
||||
}
|
||||
|
||||
const egl::Config *config = mConfigSet.get(configHandle);
|
||||
|
||||
gl::Context *context = glCreateContext(config, shareContext);
|
||||
|
@ -395,6 +433,14 @@ void Display::destroyContext(gl::Context *context)
|
|||
{
|
||||
glDestroyContext(context);
|
||||
mContextSet.erase(context);
|
||||
|
||||
if (mContextSet.empty() && mDevice && FAILED(mDevice->TestCooperativeLevel())) // Last context of a lost device
|
||||
{
|
||||
for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
|
||||
{
|
||||
(*surface)->release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Display::isInitialized()
|
||||
|
@ -430,37 +476,26 @@ bool Display::hasExistingWindowSurface(HWND window)
|
|||
return false;
|
||||
}
|
||||
|
||||
void Display::setSwapInterval(GLint interval)
|
||||
EGLint Display::getMinSwapInterval()
|
||||
{
|
||||
mSwapInterval = interval;
|
||||
mSwapInterval = std::max(mSwapInterval, mMinSwapInterval);
|
||||
mSwapInterval = std::min(mSwapInterval, mMaxSwapInterval);
|
||||
|
||||
mPresentInterval = convertInterval(mSwapInterval);
|
||||
return mMinSwapInterval;
|
||||
}
|
||||
|
||||
DWORD Display::getPresentInterval()
|
||||
EGLint Display::getMaxSwapInterval()
|
||||
{
|
||||
return mPresentInterval;
|
||||
}
|
||||
|
||||
DWORD Display::convertInterval(GLint interval)
|
||||
{
|
||||
switch(interval)
|
||||
{
|
||||
case 0: return D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||
case 1: return D3DPRESENT_INTERVAL_ONE;
|
||||
case 2: return D3DPRESENT_INTERVAL_TWO;
|
||||
case 3: return D3DPRESENT_INTERVAL_THREE;
|
||||
case 4: return D3DPRESENT_INTERVAL_FOUR;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
|
||||
return D3DPRESENT_INTERVAL_DEFAULT;
|
||||
return mMaxSwapInterval;
|
||||
}
|
||||
|
||||
IDirect3DDevice9 *Display::getDevice()
|
||||
{
|
||||
if (!mDevice)
|
||||
{
|
||||
if (!createDevice())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return mDevice;
|
||||
}
|
||||
|
||||
|
@ -468,4 +503,113 @@ D3DCAPS9 Display::getDeviceCaps()
|
|||
{
|
||||
return mDeviceCaps;
|
||||
}
|
||||
|
||||
void Display::getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray)
|
||||
{
|
||||
for (int multiSampleIndex = 0; multiSampleIndex <= D3DMULTISAMPLE_16_SAMPLES; multiSampleIndex++)
|
||||
{
|
||||
HRESULT result = mD3d9->CheckDeviceMultiSampleType(mAdapter, mDeviceType, format,
|
||||
TRUE, (D3DMULTISAMPLE_TYPE)multiSampleIndex, NULL);
|
||||
|
||||
multiSampleArray[multiSampleIndex] = SUCCEEDED(result);
|
||||
}
|
||||
}
|
||||
|
||||
bool Display::getCompressedTextureSupport()
|
||||
{
|
||||
D3DDISPLAYMODE currentDisplayMode;
|
||||
mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode);
|
||||
|
||||
return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1));
|
||||
}
|
||||
|
||||
bool Display::getFloatTextureSupport(bool *filtering, bool *renderable)
|
||||
{
|
||||
D3DDISPLAYMODE currentDisplayMode;
|
||||
mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode);
|
||||
|
||||
*filtering = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
|
||||
D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) &&
|
||||
SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
|
||||
D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
|
||||
|
||||
*renderable = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
|
||||
D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F))&&
|
||||
SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
|
||||
D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
|
||||
|
||||
if (!filtering && !renderable)
|
||||
{
|
||||
return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
|
||||
D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) &&
|
||||
SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
|
||||
D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool Display::getHalfFloatTextureSupport(bool *filtering, bool *renderable)
|
||||
{
|
||||
D3DDISPLAYMODE currentDisplayMode;
|
||||
mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode);
|
||||
|
||||
*filtering = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
|
||||
D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &&
|
||||
SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
|
||||
D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
|
||||
|
||||
*renderable = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
|
||||
D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &&
|
||||
SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
|
||||
D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
|
||||
|
||||
if (!filtering && !renderable)
|
||||
{
|
||||
return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
|
||||
D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &&
|
||||
SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
|
||||
D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool Display::getEventQuerySupport()
|
||||
{
|
||||
IDirect3DQuery9 *query;
|
||||
HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &query);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
query->Release();
|
||||
}
|
||||
|
||||
return result != D3DERR_NOTAVAILABLE;
|
||||
}
|
||||
|
||||
D3DPRESENT_PARAMETERS Display::getDefaultPresentParameters()
|
||||
{
|
||||
D3DPRESENT_PARAMETERS presentParameters = {0};
|
||||
|
||||
// The default swap chain is never actually used. Surface will create a new swap chain with the proper parameters.
|
||||
presentParameters.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
|
||||
presentParameters.BackBufferCount = 1;
|
||||
presentParameters.BackBufferFormat = D3DFMT_UNKNOWN;
|
||||
presentParameters.BackBufferWidth = 1;
|
||||
presentParameters.BackBufferHeight = 1;
|
||||
presentParameters.EnableAutoDepthStencil = FALSE;
|
||||
presentParameters.Flags = 0;
|
||||
presentParameters.hDeviceWindow = mDeviceWindow;
|
||||
presentParameters.MultiSampleQuality = 0;
|
||||
presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
|
||||
presentParameters.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
||||
presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
presentParameters.Windowed = TRUE;
|
||||
|
||||
return presentParameters;
|
||||
}
|
||||
}
|
|
@ -54,15 +54,22 @@ class Display
|
|||
bool isValidSurface(egl::Surface *surface);
|
||||
bool hasExistingWindowSurface(HWND window);
|
||||
|
||||
void setSwapInterval(GLint interval);
|
||||
DWORD getPresentInterval();
|
||||
static DWORD convertInterval(GLint interval);
|
||||
EGLint getMinSwapInterval();
|
||||
EGLint getMaxSwapInterval();
|
||||
|
||||
virtual IDirect3DDevice9 *getDevice();
|
||||
virtual D3DCAPS9 getDeviceCaps();
|
||||
virtual void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray);
|
||||
virtual bool getCompressedTextureSupport();
|
||||
virtual bool getEventQuerySupport();
|
||||
virtual bool getFloatTextureSupport(bool *filtering, bool *renderable);
|
||||
virtual bool getHalfFloatTextureSupport(bool *filtering, bool *renderable);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(Display);
|
||||
|
||||
D3DPRESENT_PARAMETERS getDefaultPresentParameters();
|
||||
|
||||
const HDC mDc;
|
||||
|
||||
HMODULE mD3d9Module;
|
||||
|
@ -76,11 +83,9 @@ class Display
|
|||
HWND mDeviceWindow;
|
||||
|
||||
bool mSceneStarted;
|
||||
GLint mSwapInterval;
|
||||
EGLint mMaxSwapInterval;
|
||||
EGLint mMinSwapInterval;
|
||||
DWORD mPresentInterval;
|
||||
|
||||
|
||||
typedef std::set<Surface*> SurfaceSet;
|
||||
SurfaceSet mSurfaceSet;
|
||||
|
||||
|
@ -90,6 +95,7 @@ class Display
|
|||
ContextSet mContextSet;
|
||||
|
||||
bool createDevice();
|
||||
bool resetDevice();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -31,45 +31,59 @@ Surface::Surface(Display *display, const Config *config, HWND window)
|
|||
mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING); // FIXME: Determine actual pixel aspect ratio
|
||||
mRenderBuffer = EGL_BACK_BUFFER;
|
||||
mSwapBehavior = EGL_BUFFER_PRESERVED;
|
||||
mSwapInterval = -1;
|
||||
setSwapInterval(1);
|
||||
|
||||
resetSwapChain();
|
||||
}
|
||||
|
||||
Surface::~Surface()
|
||||
{
|
||||
release();
|
||||
}
|
||||
|
||||
void Surface::release()
|
||||
{
|
||||
if (mSwapChain)
|
||||
{
|
||||
mSwapChain->Release();
|
||||
mSwapChain = NULL;
|
||||
}
|
||||
|
||||
if (mBackBuffer)
|
||||
{
|
||||
mBackBuffer->Release();
|
||||
mBackBuffer = NULL;
|
||||
}
|
||||
|
||||
if (mRenderTarget)
|
||||
{
|
||||
mRenderTarget->Release();
|
||||
mRenderTarget = NULL;
|
||||
}
|
||||
|
||||
if (mDepthStencil)
|
||||
{
|
||||
mDepthStencil->Release();
|
||||
mDepthStencil = NULL;
|
||||
}
|
||||
|
||||
if (mFlipTexture)
|
||||
{
|
||||
mFlipTexture->Release();
|
||||
mFlipTexture = NULL;
|
||||
}
|
||||
|
||||
if (mFlipState)
|
||||
{
|
||||
mFlipState->Release();
|
||||
mFlipState = NULL;
|
||||
}
|
||||
|
||||
if (mPreFlipState)
|
||||
{
|
||||
mPreFlipState->Release();
|
||||
mPreFlipState = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,6 +91,11 @@ void Surface::resetSwapChain()
|
|||
{
|
||||
IDirect3DDevice9 *device = mDisplay->getDevice();
|
||||
|
||||
if (device == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
D3DPRESENT_PARAMETERS presentParameters = {0};
|
||||
|
||||
presentParameters.AutoDepthStencilFormat = mConfig->mDepthStencilFormat;
|
||||
|
@ -87,12 +106,17 @@ void Surface::resetSwapChain()
|
|||
presentParameters.hDeviceWindow = getWindowHandle();
|
||||
presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented
|
||||
presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented
|
||||
presentParameters.PresentationInterval = Display::convertInterval(mConfig->mMinSwapInterval);
|
||||
presentParameters.PresentationInterval = mPresentInterval;
|
||||
presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
presentParameters.Windowed = TRUE;
|
||||
|
||||
RECT windowRect;
|
||||
GetClientRect(getWindowHandle(), &windowRect);
|
||||
if (!GetClientRect(getWindowHandle(), &windowRect))
|
||||
{
|
||||
ASSERT(false);
|
||||
return;
|
||||
}
|
||||
|
||||
presentParameters.BackBufferWidth = windowRect.right - windowRect.left;
|
||||
presentParameters.BackBufferHeight = windowRect.bottom - windowRect.top;
|
||||
|
||||
|
@ -173,6 +197,8 @@ void Surface::resetSwapChain()
|
|||
mRenderTarget = renderTarget;
|
||||
mFlipTexture = flipTexture;
|
||||
|
||||
mPresentIntervalDirty = false;
|
||||
|
||||
// The flip state block recorded mFlipTexture so it is now invalid.
|
||||
releaseRecordedState(device);
|
||||
}
|
||||
|
@ -305,11 +331,16 @@ void Surface::releaseRecordedState(IDirect3DDevice9 *device)
|
|||
}
|
||||
}
|
||||
|
||||
bool Surface::checkForWindowResize()
|
||||
bool Surface::checkForOutOfDateSwapChain()
|
||||
{
|
||||
RECT client;
|
||||
GetClientRect(getWindowHandle(), &client);
|
||||
if (getWidth() != client.right - client.left || getHeight() != client.bottom - client.top)
|
||||
if (!GetClientRect(getWindowHandle(), &client))
|
||||
{
|
||||
ASSERT(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getWidth() != client.right - client.left || getHeight() != client.bottom - client.top || mPresentIntervalDirty)
|
||||
{
|
||||
resetSwapChain();
|
||||
|
||||
|
@ -324,6 +355,22 @@ bool Surface::checkForWindowResize()
|
|||
return false;
|
||||
}
|
||||
|
||||
DWORD Surface::convertInterval(EGLint interval)
|
||||
{
|
||||
switch(interval)
|
||||
{
|
||||
case 0: return D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||
case 1: return D3DPRESENT_INTERVAL_ONE;
|
||||
case 2: return D3DPRESENT_INTERVAL_TWO;
|
||||
case 3: return D3DPRESENT_INTERVAL_THREE;
|
||||
case 4: return D3DPRESENT_INTERVAL_FOUR;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
|
||||
return D3DPRESENT_INTERVAL_DEFAULT;
|
||||
}
|
||||
|
||||
|
||||
bool Surface::swap()
|
||||
{
|
||||
if (mSwapChain)
|
||||
|
@ -337,7 +384,7 @@ bool Surface::swap()
|
|||
EGLint oldWidth = mWidth;
|
||||
EGLint oldHeight = mHeight;
|
||||
|
||||
checkForWindowResize();
|
||||
checkForOutOfDateSwapChain();
|
||||
|
||||
IDirect3DDevice9 *device = mDisplay->getDevice();
|
||||
|
||||
|
@ -370,7 +417,7 @@ bool Surface::swap()
|
|||
restoreState(device);
|
||||
|
||||
mDisplay->endScene();
|
||||
HRESULT result = mSwapChain->Present(NULL, NULL, NULL, NULL, mDisplay->getPresentInterval());
|
||||
HRESULT result = mSwapChain->Present(NULL, NULL, NULL, NULL, 0);
|
||||
|
||||
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR)
|
||||
{
|
||||
|
@ -418,4 +465,19 @@ IDirect3DSurface9 *Surface::getDepthStencil()
|
|||
|
||||
return mDepthStencil;
|
||||
}
|
||||
|
||||
void Surface::setSwapInterval(EGLint interval)
|
||||
{
|
||||
if (mSwapInterval == interval)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mSwapInterval = interval;
|
||||
mSwapInterval = std::max(mSwapInterval, mDisplay->getMinSwapInterval());
|
||||
mSwapInterval = std::min(mSwapInterval, mDisplay->getMaxSwapInterval());
|
||||
|
||||
mPresentInterval = convertInterval(mSwapInterval);
|
||||
mPresentIntervalDirty = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,9 @@ class Surface
|
|||
|
||||
~Surface();
|
||||
|
||||
void release();
|
||||
void resetSwapChain();
|
||||
|
||||
HWND getWindowHandle();
|
||||
bool swap();
|
||||
|
||||
|
@ -38,6 +41,8 @@ class Surface
|
|||
virtual IDirect3DSurface9 *getRenderTarget();
|
||||
virtual IDirect3DSurface9 *getDepthStencil();
|
||||
|
||||
void setSwapInterval(EGLint interval);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(Surface);
|
||||
|
||||
|
@ -48,8 +53,9 @@ class Surface
|
|||
IDirect3DSurface9 *mDepthStencil;
|
||||
IDirect3DTexture9 *mFlipTexture;
|
||||
|
||||
void resetSwapChain();
|
||||
bool checkForWindowResize();
|
||||
bool checkForOutOfDateSwapChain();
|
||||
|
||||
static DWORD convertInterval(EGLint interval);
|
||||
|
||||
void applyFlipState(IDirect3DDevice9 *device);
|
||||
void restoreState(IDirect3DDevice9 *device);
|
||||
|
@ -77,6 +83,9 @@ class Surface
|
|||
// EGLenum textureTarget; // Type of texture: 2D or no texture
|
||||
// EGLenum vgAlphaFormat; // Alpha format for OpenVG
|
||||
// EGLenum vgColorSpace; // Color space for OpenVG
|
||||
EGLint mSwapInterval;
|
||||
DWORD mPresentInterval;
|
||||
bool mPresentIntervalDirty;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -746,7 +746,14 @@ EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval)
|
|||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
display->setSwapInterval(interval);
|
||||
egl::Surface *draw_surface = static_cast<egl::Surface*>(egl::getCurrentDrawSurface());
|
||||
|
||||
if (draw_surface == NULL)
|
||||
{
|
||||
return error(EGL_BAD_SURFACE, EGL_FALSE);
|
||||
}
|
||||
|
||||
draw_surface->setSwapInterval(interval);
|
||||
|
||||
return success(EGL_TRUE);
|
||||
}
|
||||
|
@ -825,7 +832,7 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface
|
|||
gl::Context *context = static_cast<gl::Context*>(ctx);
|
||||
IDirect3DDevice9 *device = display->getDevice();
|
||||
|
||||
if (!device || device->TestCooperativeLevel() != D3D_OK)
|
||||
if (!device || FAILED(device->TestCooperativeLevel()))
|
||||
{
|
||||
return error(EGL_CONTEXT_LOST, EGL_FALSE);
|
||||
}
|
||||
|
|
|
@ -382,6 +382,11 @@ bool Blit::setFormatConvertShaders(GLenum destFormat)
|
|||
|
||||
IDirect3DTexture9 *Blit::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect)
|
||||
{
|
||||
if (!surface)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
egl::Display *display = getDisplay();
|
||||
IDirect3DDevice9 *device = getDevice();
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -12,6 +12,7 @@
|
|||
|
||||
#define GL_APICALL
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
#define EGLAPI
|
||||
#include <EGL/egl.h>
|
||||
#include <d3d9.h>
|
||||
|
@ -51,6 +52,7 @@ class VertexDataManager;
|
|||
class IndexDataManager;
|
||||
class BufferBackEnd;
|
||||
class Blit;
|
||||
class Fence;
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -157,6 +159,7 @@ struct State
|
|||
GLfloat lineWidth;
|
||||
|
||||
GLenum generateMipmapHint;
|
||||
GLenum fragmentShaderDerivativeHint;
|
||||
|
||||
GLint viewportX;
|
||||
GLint viewportY;
|
||||
|
@ -181,7 +184,8 @@ struct State
|
|||
BindingPointer<Buffer> elementArrayBuffer;
|
||||
BindingPointer<Texture> texture2D;
|
||||
BindingPointer<Texture> textureCubeMap;
|
||||
GLuint framebuffer;
|
||||
GLuint readFramebuffer;
|
||||
GLuint drawFramebuffer;
|
||||
BindingPointer<Renderbuffer> renderbuffer;
|
||||
GLuint currentProgram;
|
||||
|
||||
|
@ -263,6 +267,7 @@ class Context
|
|||
void setLineWidth(GLfloat width);
|
||||
|
||||
void setGenerateMipmapHint(GLenum hint);
|
||||
void setFragmentShaderDerivativeHint(GLenum hint);
|
||||
|
||||
void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
|
||||
|
@ -273,7 +278,8 @@ class Context
|
|||
|
||||
void setActiveSampler(int active);
|
||||
|
||||
GLuint getFramebufferHandle() const;
|
||||
GLuint getReadFramebufferHandle() const;
|
||||
GLuint getDrawFramebufferHandle() const;
|
||||
GLuint getRenderbufferHandle() const;
|
||||
|
||||
GLuint getArrayBufferHandle() const;
|
||||
|
@ -310,11 +316,16 @@ class Context
|
|||
GLuint createFramebuffer();
|
||||
void deleteFramebuffer(GLuint framebuffer);
|
||||
|
||||
// Fences are owned by the Context.
|
||||
GLuint createFence();
|
||||
void deleteFence(GLuint fence);
|
||||
|
||||
void bindArrayBuffer(GLuint buffer);
|
||||
void bindElementArrayBuffer(GLuint buffer);
|
||||
void bindTexture2D(GLuint texture);
|
||||
void bindTextureCubeMap(GLuint texture);
|
||||
void bindFramebuffer(GLuint framebuffer);
|
||||
void bindReadFramebuffer(GLuint framebuffer);
|
||||
void bindDrawFramebuffer(GLuint framebuffer);
|
||||
void bindRenderbuffer(GLuint renderbuffer);
|
||||
void useProgram(GLuint program);
|
||||
|
||||
|
@ -325,6 +336,7 @@ class Context
|
|||
void setVertexAttrib(GLuint index, const GLfloat *values);
|
||||
|
||||
Buffer *getBuffer(GLuint handle);
|
||||
Fence *getFence(GLuint handle);
|
||||
Shader *getShader(GLuint handle);
|
||||
Program *getProgram(GLuint handle);
|
||||
Texture *getTexture(GLuint handle);
|
||||
|
@ -337,7 +349,8 @@ class Context
|
|||
Texture2D *getTexture2D();
|
||||
TextureCubeMap *getTextureCubeMap();
|
||||
Texture *getSamplerTexture(unsigned int sampler, SamplerType type);
|
||||
Framebuffer *getFramebuffer();
|
||||
Framebuffer *getReadFramebuffer();
|
||||
Framebuffer *getDrawFramebuffer();
|
||||
|
||||
bool getFloatv(GLenum pname, GLfloat *params);
|
||||
bool getIntegerv(GLenum pname, GLint *params);
|
||||
|
@ -370,7 +383,21 @@ class Context
|
|||
GLenum getError();
|
||||
|
||||
bool supportsShaderModel3() const;
|
||||
GLsizei getMaxSupportedSamples() const;
|
||||
int getNearestSupportedSamples(D3DFORMAT format, int requested) const;
|
||||
const char *getExtensionString() const;
|
||||
bool supportsEventQueries() const;
|
||||
bool supportsCompressedTextures() const;
|
||||
bool supportsFloatTextures() const;
|
||||
bool supportsFloatLinearFilter() const;
|
||||
bool supportsFloatRenderableTextures() const;
|
||||
bool supportsHalfFloatTextures() const;
|
||||
bool supportsHalfFloatLinearFilter() const;
|
||||
bool supportsHalfFloatRenderableTextures() const;
|
||||
|
||||
void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
|
||||
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
|
||||
GLbitfield mask);
|
||||
|
||||
Blit *getBlitter() { return mBlit; }
|
||||
|
||||
|
@ -390,21 +417,21 @@ class Context
|
|||
|
||||
bool cullSkipsDraw(GLenum drawMode);
|
||||
bool isTriangleMode(GLenum drawMode);
|
||||
bool hasStencil();
|
||||
|
||||
const egl::Config *const mConfig;
|
||||
|
||||
State mState;
|
||||
|
||||
Texture2D *mTexture2DZero;
|
||||
TextureCubeMap *mTextureCubeMapZero;
|
||||
BindingPointer<Texture2D> mTexture2DZero;
|
||||
BindingPointer<TextureCubeMap> mTextureCubeMapZero;
|
||||
|
||||
Colorbuffer *mColorbufferZero;
|
||||
DepthStencilbuffer *mDepthStencilbufferZero;
|
||||
|
||||
typedef std::map<GLuint, Framebuffer*> FramebufferMap;
|
||||
FramebufferMap mFramebufferMap;
|
||||
|
||||
typedef std::map<GLuint, Fence*> FenceMap;
|
||||
FenceMap mFenceMap;
|
||||
|
||||
void initExtensionString();
|
||||
std::string mExtensionString;
|
||||
|
||||
|
@ -414,7 +441,7 @@ class Context
|
|||
|
||||
Blit *mBlit;
|
||||
|
||||
Texture *mIncompleteTextures[SAMPLER_TYPE_COUNT];
|
||||
BindingPointer<Texture> mIncompleteTextures[SAMPLER_TYPE_COUNT];
|
||||
|
||||
// Recorded errors
|
||||
bool mInvalidEnum;
|
||||
|
@ -429,8 +456,19 @@ class Context
|
|||
unsigned int mAppliedRenderTargetSerial;
|
||||
unsigned int mAppliedDepthbufferSerial;
|
||||
unsigned int mAppliedStencilbufferSerial;
|
||||
bool mDepthStencilInitialized;
|
||||
|
||||
bool mSupportsShaderModel3;
|
||||
std::map<D3DFORMAT, bool *> mMultiSampleSupport;
|
||||
GLsizei mMaxSupportedSamples;
|
||||
bool mSupportsEventQueries;
|
||||
bool mSupportsCompressedTextures;
|
||||
bool mSupportsFloatTextures;
|
||||
bool mSupportsFloatLinearFilter;
|
||||
bool mSupportsFloatRenderableTextures;
|
||||
bool mSupportsHalfFloatTextures;
|
||||
bool mSupportsHalfFloatLinearFilter;
|
||||
bool mSupportsHalfFloatRenderableTextures;
|
||||
|
||||
// state caching flags
|
||||
bool mClearStateDirty;
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
//
|
||||
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// Fence.cpp: Implements the gl::Fence class, which supports the GL_NV_fence extension.
|
||||
|
||||
#include "libGLESv2/Fence.h"
|
||||
|
||||
#include "libGLESv2/main.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
Fence::Fence()
|
||||
{
|
||||
mQuery = NULL;
|
||||
mCondition = GL_NONE;
|
||||
mStatus = GL_FALSE;
|
||||
}
|
||||
|
||||
Fence::~Fence()
|
||||
{
|
||||
if (mQuery != NULL)
|
||||
{
|
||||
mQuery->Release();
|
||||
mQuery = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
GLboolean Fence::isFence()
|
||||
{
|
||||
// GL_NV_fence spec:
|
||||
// A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence.
|
||||
return mQuery != NULL;
|
||||
}
|
||||
|
||||
void Fence::setFence(GLenum condition)
|
||||
{
|
||||
if (mQuery != NULL)
|
||||
{
|
||||
mQuery->Release();
|
||||
mQuery = NULL;
|
||||
}
|
||||
|
||||
if (FAILED(getDevice()->CreateQuery(D3DQUERYTYPE_EVENT, &mQuery)))
|
||||
{
|
||||
return error(GL_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
HRESULT result = mQuery->Issue(D3DISSUE_END);
|
||||
ASSERT(SUCCEEDED(result));
|
||||
|
||||
mCondition = condition;
|
||||
mStatus = GL_FALSE;
|
||||
}
|
||||
|
||||
GLboolean Fence::testFence()
|
||||
{
|
||||
if (mQuery == NULL)
|
||||
{
|
||||
return error(GL_INVALID_OPERATION, GL_TRUE);
|
||||
}
|
||||
|
||||
HRESULT result = mQuery->GetData(NULL, 0, D3DGETDATA_FLUSH);
|
||||
|
||||
if (result == D3DERR_DEVICELOST)
|
||||
{
|
||||
return error(GL_OUT_OF_MEMORY, GL_TRUE);
|
||||
}
|
||||
|
||||
ASSERT(result == S_OK || result == S_FALSE);
|
||||
mStatus = result == S_OK;
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
void Fence::finishFence()
|
||||
{
|
||||
if (mQuery == NULL)
|
||||
{
|
||||
return error(GL_INVALID_OPERATION);
|
||||
}
|
||||
|
||||
while (!testFence())
|
||||
{
|
||||
Sleep(0);
|
||||
}
|
||||
}
|
||||
|
||||
void Fence::getFenceiv(GLenum pname, GLint *params)
|
||||
{
|
||||
if (mQuery == NULL)
|
||||
{
|
||||
return error(GL_INVALID_OPERATION);
|
||||
}
|
||||
|
||||
switch (pname)
|
||||
{
|
||||
case GL_FENCE_STATUS_NV:
|
||||
{
|
||||
// GL_NV_fence spec:
|
||||
// Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV
|
||||
// or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.
|
||||
if (mStatus)
|
||||
{
|
||||
params[0] = GL_TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
HRESULT result = mQuery->GetData(NULL, 0, 0);
|
||||
|
||||
if (result == D3DERR_DEVICELOST)
|
||||
{
|
||||
params[0] = GL_TRUE;
|
||||
return error(GL_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
ASSERT(result == S_OK || result == S_FALSE);
|
||||
mStatus = result == S_OK;
|
||||
params[0] = mStatus;
|
||||
|
||||
break;
|
||||
}
|
||||
case GL_FENCE_CONDITION_NV:
|
||||
params[0] = mCondition;
|
||||
break;
|
||||
default:
|
||||
return error(GL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
//
|
||||
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// Fence.h: Defines the gl::Fence class, which supports the GL_NV_fence extension.
|
||||
|
||||
#ifndef LIBGLESV2_FENCE_H_
|
||||
#define LIBGLESV2_FENCE_H_
|
||||
|
||||
#define GL_APICALL
|
||||
#include <GLES2/gl2.h>
|
||||
#include <d3d9.h>
|
||||
|
||||
#include "common/angleutils.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
class Fence
|
||||
{
|
||||
public:
|
||||
Fence();
|
||||
virtual ~Fence();
|
||||
|
||||
GLboolean isFence();
|
||||
void setFence(GLenum condition);
|
||||
GLboolean testFence();
|
||||
void finishFence();
|
||||
void getFenceiv(GLenum pname, GLint *params);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(Fence);
|
||||
|
||||
IDirect3DQuery9* mQuery;
|
||||
GLenum mCondition;
|
||||
GLboolean mStatus;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // LIBGLESV2_FENCE_H_
|
|
@ -140,6 +140,23 @@ IDirect3DSurface9 *Framebuffer::getRenderTarget()
|
|||
return NULL;
|
||||
}
|
||||
|
||||
IDirect3DSurface9 *Framebuffer::getDepthStencil()
|
||||
{
|
||||
Renderbuffer *depthstencilbuffer = mDepthbufferPointer.get();
|
||||
|
||||
if (!depthstencilbuffer)
|
||||
{
|
||||
depthstencilbuffer = mStencilbufferPointer.get();
|
||||
}
|
||||
|
||||
if (depthstencilbuffer)
|
||||
{
|
||||
return depthstencilbuffer->getDepthStencil();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned int Framebuffer::getDepthbufferSerial()
|
||||
{
|
||||
Renderbuffer *depthbuffer = mDepthbufferPointer.get();
|
||||
|
@ -152,6 +169,18 @@ unsigned int Framebuffer::getDepthbufferSerial()
|
|||
return 0;
|
||||
}
|
||||
|
||||
unsigned int Framebuffer::getStencilbufferSerial()
|
||||
{
|
||||
Renderbuffer *stencilbuffer = mStencilbufferPointer.get();
|
||||
|
||||
if (stencilbuffer)
|
||||
{
|
||||
return stencilbuffer->getSerial();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Colorbuffer *Framebuffer::getColorbuffer()
|
||||
{
|
||||
Renderbuffer *rb = mColorbufferPointer.get();
|
||||
|
@ -224,10 +253,43 @@ GLuint Framebuffer::getStencilbufferHandle()
|
|||
return mStencilbufferPointer.id();
|
||||
}
|
||||
|
||||
bool Framebuffer::hasStencil()
|
||||
{
|
||||
if (mStencilbufferType != GL_NONE)
|
||||
{
|
||||
DepthStencilbuffer *stencilbufferObject = getStencilbuffer();
|
||||
|
||||
if (stencilbufferObject)
|
||||
{
|
||||
return stencilbufferObject->getStencilSize() > 0;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Framebuffer::isMultisample()
|
||||
{
|
||||
// If the framebuffer is not complete, attachment samples may be mismatched, and it
|
||||
// cannot be used as a multisample framebuffer. If it is complete, it is required to
|
||||
// have a color attachment, and all its attachments must have the same number of samples,
|
||||
// so the number of samples for the colorbuffer will indicate whether the framebuffer is
|
||||
// multisampled.
|
||||
if (completeness() == GL_FRAMEBUFFER_COMPLETE && getColorbuffer()->getSamples() > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
GLenum Framebuffer::completeness()
|
||||
{
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
int samples = -1;
|
||||
|
||||
if (mColorbufferType != GL_NONE)
|
||||
{
|
||||
|
@ -243,8 +305,23 @@ GLenum Framebuffer::completeness()
|
|||
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
|
||||
}
|
||||
|
||||
if (IsTextureTarget(mColorbufferType))
|
||||
{
|
||||
if (IsCompressed(colorbuffer->getFormat()))
|
||||
{
|
||||
return GL_FRAMEBUFFER_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (colorbuffer->isFloatingPoint() && (!getContext()->supportsFloatRenderableTextures() ||
|
||||
!getContext()->supportsHalfFloatRenderableTextures()))
|
||||
{
|
||||
return GL_FRAMEBUFFER_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
width = colorbuffer->getWidth();
|
||||
height = colorbuffer->getHeight();
|
||||
samples = colorbuffer->getSamples();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -277,6 +354,23 @@ GLenum Framebuffer::completeness()
|
|||
{
|
||||
return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
|
||||
}
|
||||
|
||||
if (samples == -1)
|
||||
{
|
||||
samples = depthbuffer->getSamples();
|
||||
}
|
||||
else if (samples != depthbuffer->getSamples())
|
||||
{
|
||||
return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
|
||||
}
|
||||
|
||||
if (IsTextureTarget(mDepthbufferType))
|
||||
{
|
||||
if (IsCompressed(depthbuffer->getFormat()))
|
||||
{
|
||||
return GL_FRAMEBUFFER_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mStencilbufferType != GL_NONE)
|
||||
|
@ -302,6 +396,23 @@ GLenum Framebuffer::completeness()
|
|||
{
|
||||
return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
|
||||
}
|
||||
|
||||
if (samples == -1)
|
||||
{
|
||||
samples = stencilbuffer->getSamples();
|
||||
}
|
||||
else if (samples != stencilbuffer->getSamples())
|
||||
{
|
||||
return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
|
||||
}
|
||||
|
||||
if (IsTextureTarget(mStencilbufferType))
|
||||
{
|
||||
if (IsCompressed(stencilbuffer->getFormat()))
|
||||
{
|
||||
return GL_FRAMEBUFFER_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mDepthbufferType == GL_RENDERBUFFER && mStencilbufferType == GL_RENDERBUFFER)
|
||||
|
@ -330,6 +441,18 @@ DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *color, DepthStencilbuffer *d
|
|||
mStencilbufferPointer.set(depthStencilRenderbuffer);
|
||||
}
|
||||
|
||||
int Framebuffer::getSamples()
|
||||
{
|
||||
if (completeness() == GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
return getColorbuffer()->getSamples();
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
GLenum DefaultFramebuffer::completeness()
|
||||
{
|
||||
return GL_FRAMEBUFFER_COMPLETE;
|
||||
|
|
|
@ -44,6 +44,7 @@ class Framebuffer
|
|||
|
||||
unsigned int getRenderTargetSerial();
|
||||
unsigned int getDepthbufferSerial();
|
||||
unsigned int getStencilbufferSerial();
|
||||
|
||||
Colorbuffer *getColorbuffer();
|
||||
DepthStencilbuffer *getDepthbuffer();
|
||||
|
@ -57,6 +58,10 @@ class Framebuffer
|
|||
GLuint getDepthbufferHandle();
|
||||
GLuint getStencilbufferHandle();
|
||||
|
||||
bool hasStencil();
|
||||
bool isMultisample();
|
||||
int getSamples();
|
||||
|
||||
virtual GLenum completeness();
|
||||
|
||||
protected:
|
||||
|
|
|
@ -595,7 +595,9 @@ bool Program::setUniform1iv(GLint location, GLsizei count, const GLint *v)
|
|||
Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
|
||||
targetUniform->dirty = true;
|
||||
|
||||
if (targetUniform->type == GL_INT)
|
||||
if (targetUniform->type == GL_INT ||
|
||||
targetUniform->type == GL_SAMPLER_2D ||
|
||||
targetUniform->type == GL_SAMPLER_CUBE)
|
||||
{
|
||||
int arraySize = targetUniform->arraySize;
|
||||
|
||||
|
@ -949,6 +951,8 @@ void Program::applyUniforms()
|
|||
case GL_FLOAT_MAT2: applyUniformMatrix2fv(location, arraySize, f); break;
|
||||
case GL_FLOAT_MAT3: applyUniformMatrix3fv(location, arraySize, f); break;
|
||||
case GL_FLOAT_MAT4: applyUniformMatrix4fv(location, arraySize, f); break;
|
||||
case GL_SAMPLER_2D:
|
||||
case GL_SAMPLER_CUBE:
|
||||
case GL_INT: applyUniform1iv(location, arraySize, i); break;
|
||||
case GL_INT_VEC2: applyUniform2iv(location, arraySize, i); break;
|
||||
case GL_INT_VEC3: applyUniform3iv(location, arraySize, i); break;
|
||||
|
@ -1737,10 +1741,16 @@ Uniform *Program::createUniform(const D3DXCONSTANT_DESC &constantDescription, st
|
|||
switch (constantDescription.Type)
|
||||
{
|
||||
case D3DXPT_SAMPLER2D:
|
||||
switch (constantDescription.Columns)
|
||||
{
|
||||
case 1: return new Uniform(GL_SAMPLER_2D, name, constantDescription.Elements);
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
break;
|
||||
case D3DXPT_SAMPLERCUBE:
|
||||
switch (constantDescription.Columns)
|
||||
{
|
||||
case 1: return new Uniform(GL_INT, name, constantDescription.Elements);
|
||||
case 1: return new Uniform(GL_SAMPLER_CUBE, name, constantDescription.Elements);
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
break;
|
||||
|
@ -2371,6 +2381,7 @@ void Program::resetInfoLog()
|
|||
if (mInfoLog)
|
||||
{
|
||||
delete [] mInfoLog;
|
||||
mInfoLog = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ RefCountObject::RefCountObject(GLuint id)
|
|||
|
||||
RefCountObject::~RefCountObject()
|
||||
{
|
||||
ASSERT(mRefCount == 0);
|
||||
}
|
||||
|
||||
void RefCountObject::addRef() const
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "libGLESv2/Renderbuffer.h"
|
||||
|
||||
#include "libGLESv2/main.h"
|
||||
#include "libGLESv2/Texture.h"
|
||||
#include "libGLESv2/utilities.h"
|
||||
|
||||
namespace gl
|
||||
|
@ -68,6 +69,11 @@ GLenum Renderbuffer::getFormat() const
|
|||
return mStorage->getFormat();
|
||||
}
|
||||
|
||||
D3DFORMAT Renderbuffer::getD3DFormat() const
|
||||
{
|
||||
return mStorage->getD3DFormat();
|
||||
}
|
||||
|
||||
unsigned int Renderbuffer::getSerial() const
|
||||
{
|
||||
return mStorage->getSerial();
|
||||
|
@ -136,6 +142,21 @@ GLenum RenderbufferStorage::getFormat() const
|
|||
return mFormat;
|
||||
}
|
||||
|
||||
bool RenderbufferStorage::isFloatingPoint() const
|
||||
{
|
||||
return false; // no floating point renderbuffers
|
||||
}
|
||||
|
||||
D3DFORMAT RenderbufferStorage::getD3DFormat() const
|
||||
{
|
||||
return mD3DFormat;
|
||||
}
|
||||
|
||||
GLsizei RenderbufferStorage::getSamples() const
|
||||
{
|
||||
return mSamples;
|
||||
}
|
||||
|
||||
unsigned int RenderbufferStorage::getSerial() const
|
||||
{
|
||||
return mSerial;
|
||||
|
@ -156,20 +177,42 @@ Colorbuffer::Colorbuffer(IDirect3DSurface9 *renderTarget) : mRenderTarget(render
|
|||
renderTarget->GetDesc(&description);
|
||||
|
||||
setSize(description.Width, description.Height);
|
||||
mD3DFormat = description.Format;
|
||||
mSamples = es2dx::GetSamplesFromMultisampleType(description.MultiSampleType);
|
||||
}
|
||||
else
|
||||
{
|
||||
mD3DFormat = D3DFMT_UNKNOWN;
|
||||
mSamples = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Colorbuffer::Colorbuffer(int width, int height, GLenum format)
|
||||
Colorbuffer::Colorbuffer(const Texture* texture) : mRenderTarget(NULL)
|
||||
{
|
||||
setSize(texture->getWidth(), texture->getHeight());
|
||||
mD3DFormat = texture->getD3DFormat();
|
||||
mSamples = 0;
|
||||
}
|
||||
|
||||
Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples)
|
||||
{
|
||||
IDirect3DDevice9 *device = getDevice();
|
||||
|
||||
mRenderTarget = NULL;
|
||||
D3DFORMAT requestedFormat = es2dx::ConvertRenderbufferFormat(format);
|
||||
int supportedSamples = getContext()->getNearestSupportedSamples(requestedFormat, samples);
|
||||
|
||||
if (supportedSamples == -1)
|
||||
{
|
||||
error(GL_OUT_OF_MEMORY);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (width > 0 && height > 0)
|
||||
{
|
||||
HRESULT result = device->CreateRenderTarget(width, height, es2dx::ConvertRenderbufferFormat(format),
|
||||
D3DMULTISAMPLE_NONE, 0, FALSE, &mRenderTarget, NULL);
|
||||
HRESULT result = device->CreateRenderTarget(width, height, requestedFormat,
|
||||
es2dx::GetMultisampleTypeFromSamples(supportedSamples), 0, FALSE, &mRenderTarget, NULL);
|
||||
|
||||
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
|
||||
{
|
||||
|
@ -185,11 +228,15 @@ Colorbuffer::Colorbuffer(int width, int height, GLenum format)
|
|||
{
|
||||
setSize(width, height);
|
||||
mFormat = format;
|
||||
mD3DFormat = requestedFormat;
|
||||
mSamples = supportedSamples;
|
||||
}
|
||||
else
|
||||
{
|
||||
setSize(0, 0);
|
||||
mFormat = GL_RGBA4;
|
||||
mD3DFormat = D3DFMT_UNKNOWN;
|
||||
mSamples = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -273,16 +320,34 @@ DepthStencilbuffer::DepthStencilbuffer(IDirect3DSurface9 *depthStencil) : mDepth
|
|||
depthStencil->GetDesc(&description);
|
||||
|
||||
setSize(description.Width, description.Height);
|
||||
mFormat = GL_DEPTH24_STENCIL8_OES;
|
||||
mFormat = (description.Format == D3DFMT_D16 ? GL_DEPTH_COMPONENT16 : GL_DEPTH24_STENCIL8_OES);
|
||||
mSamples = es2dx::GetSamplesFromMultisampleType(description.MultiSampleType);
|
||||
mD3DFormat = description.Format;
|
||||
}
|
||||
else
|
||||
{
|
||||
mD3DFormat = D3DFMT_UNKNOWN;
|
||||
mSamples = 0;
|
||||
}
|
||||
}
|
||||
|
||||
DepthStencilbuffer::DepthStencilbuffer(int width, int height)
|
||||
DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples)
|
||||
{
|
||||
IDirect3DDevice9 *device = getDevice();
|
||||
|
||||
mDepthStencil = NULL;
|
||||
HRESULT result = device->CreateDepthStencilSurface(width, height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, 0);
|
||||
|
||||
int supportedSamples = getContext()->getNearestSupportedSamples(D3DFMT_D24S8, samples);
|
||||
|
||||
if (supportedSamples == -1)
|
||||
{
|
||||
error(GL_OUT_OF_MEMORY);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
HRESULT result = device->CreateDepthStencilSurface(width, height, D3DFMT_D24S8, es2dx::GetMultisampleTypeFromSamples(supportedSamples),
|
||||
0, FALSE, &mDepthStencil, 0);
|
||||
|
||||
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
|
||||
{
|
||||
|
@ -296,12 +361,16 @@ DepthStencilbuffer::DepthStencilbuffer(int width, int height)
|
|||
if (mDepthStencil)
|
||||
{
|
||||
setSize(width, height);
|
||||
mFormat = GL_DEPTH24_STENCIL8_OES;
|
||||
mFormat = GL_DEPTH24_STENCIL8_OES;
|
||||
mD3DFormat = D3DFMT_D24S8;
|
||||
mSamples = supportedSamples;
|
||||
}
|
||||
else
|
||||
{
|
||||
setSize(0, 0);
|
||||
mFormat = GL_RGBA4; //default format
|
||||
mD3DFormat = D3DFMT_UNKNOWN;
|
||||
mSamples = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -364,7 +433,7 @@ Depthbuffer::Depthbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuffer(d
|
|||
}
|
||||
}
|
||||
|
||||
Depthbuffer::Depthbuffer(int width, int height) : DepthStencilbuffer(width, height)
|
||||
Depthbuffer::Depthbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
|
||||
{
|
||||
if (getDepthStencil())
|
||||
{
|
||||
|
@ -402,7 +471,7 @@ Stencilbuffer::Stencilbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuff
|
|||
}
|
||||
}
|
||||
|
||||
Stencilbuffer::Stencilbuffer(int width, int height) : DepthStencilbuffer(width, height)
|
||||
Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
|
||||
{
|
||||
if (getDepthStencil())
|
||||
{
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
namespace gl
|
||||
{
|
||||
class Texture;
|
||||
|
||||
// A class derived from RenderbufferStorage is created whenever glRenderbufferStorage
|
||||
// is called. The specific concrete type depends on whether the internal format is
|
||||
|
@ -41,7 +42,10 @@ class RenderbufferStorage
|
|||
|
||||
virtual int getWidth() const;
|
||||
virtual int getHeight() const;
|
||||
GLenum getFormat() const;
|
||||
virtual GLenum getFormat() const;
|
||||
virtual bool isFloatingPoint() const;
|
||||
D3DFORMAT getD3DFormat() const;
|
||||
GLsizei getSamples() const;
|
||||
unsigned int getSerial() const;
|
||||
|
||||
static unsigned int issueSerial();
|
||||
|
@ -49,6 +53,8 @@ class RenderbufferStorage
|
|||
protected:
|
||||
void setSize(int width, int height);
|
||||
GLenum mFormat;
|
||||
D3DFORMAT mD3DFormat;
|
||||
GLsizei mSamples;
|
||||
unsigned int mSerial;
|
||||
|
||||
private:
|
||||
|
@ -80,6 +86,7 @@ class Renderbuffer : public RefCountObject
|
|||
int getWidth() const;
|
||||
int getHeight() const;
|
||||
GLenum getFormat() const;
|
||||
D3DFORMAT getD3DFormat() const;
|
||||
unsigned int getSerial() const;
|
||||
|
||||
void setStorage(RenderbufferStorage *newStorage);
|
||||
|
@ -95,7 +102,8 @@ class Colorbuffer : public RenderbufferStorage
|
|||
{
|
||||
public:
|
||||
explicit Colorbuffer(IDirect3DSurface9 *renderTarget);
|
||||
Colorbuffer(int width, int height, GLenum format);
|
||||
explicit Colorbuffer(const Texture* texture);
|
||||
Colorbuffer(int width, int height, GLenum format, GLsizei samples);
|
||||
|
||||
~Colorbuffer();
|
||||
|
||||
|
@ -119,7 +127,7 @@ class DepthStencilbuffer : public RenderbufferStorage
|
|||
{
|
||||
public:
|
||||
explicit DepthStencilbuffer(IDirect3DSurface9 *depthStencil);
|
||||
DepthStencilbuffer(int width, int height);
|
||||
DepthStencilbuffer(int width, int height, GLsizei samples);
|
||||
|
||||
~DepthStencilbuffer();
|
||||
|
||||
|
@ -140,7 +148,7 @@ class Depthbuffer : public DepthStencilbuffer
|
|||
{
|
||||
public:
|
||||
explicit Depthbuffer(IDirect3DSurface9 *depthStencil);
|
||||
Depthbuffer(int width, int height);
|
||||
Depthbuffer(int width, int height, GLsizei samples);
|
||||
|
||||
~Depthbuffer();
|
||||
|
||||
|
@ -155,7 +163,7 @@ class Stencilbuffer : public DepthStencilbuffer
|
|||
{
|
||||
public:
|
||||
explicit Stencilbuffer(IDirect3DSurface9 *depthStencil);
|
||||
Stencilbuffer(int width, int height);
|
||||
Stencilbuffer(int width, int height, GLsizei samples);
|
||||
|
||||
~Stencilbuffer();
|
||||
|
||||
|
|
|
@ -331,7 +331,7 @@ void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer)
|
|||
{
|
||||
if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
|
||||
{
|
||||
Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(0, 0, GL_RGBA4));
|
||||
Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(0, 0, GL_RGBA4, 0));
|
||||
mRenderbufferMap[renderbuffer] = renderbufferObject;
|
||||
renderbufferObject->addRef();
|
||||
}
|
||||
|
|
|
@ -34,18 +34,20 @@ Shader::Shader(ResourceManager *manager, GLuint handle) : mHandle(handle), mReso
|
|||
|
||||
if (result)
|
||||
{
|
||||
TBuiltInResource resources;
|
||||
resources.maxVertexAttribs = MAX_VERTEX_ATTRIBS;
|
||||
resources.maxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
|
||||
resources.maxVaryingVectors = MAX_VARYING_VECTORS;
|
||||
resources.maxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
|
||||
resources.maxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
|
||||
resources.maxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
|
||||
resources.maxFragmentUniformVectors = MAX_FRAGMENT_UNIFORM_VECTORS;
|
||||
resources.maxDrawBuffers = MAX_DRAW_BUFFERS;
|
||||
ShBuiltInResources resources;
|
||||
ShInitBuiltInResources(&resources);
|
||||
resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
|
||||
resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
|
||||
resources.MaxVaryingVectors = MAX_VARYING_VECTORS;
|
||||
resources.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
|
||||
resources.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
|
||||
resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
|
||||
resources.MaxFragmentUniformVectors = MAX_FRAGMENT_UNIFORM_VECTORS;
|
||||
resources.MaxDrawBuffers = MAX_DRAW_BUFFERS;
|
||||
resources.OES_standard_derivatives = 1;
|
||||
|
||||
mFragmentCompiler = ShConstructCompiler(EShLangFragment, EShSpecGLES2, &resources);
|
||||
mVertexCompiler = ShConstructCompiler(EShLangVertex, EShSpecGLES2, &resources);
|
||||
mFragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_GLES2_SPEC, &resources);
|
||||
mVertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_GLES2_SPEC, &resources);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -279,21 +281,23 @@ void Shader::compileToHLSL(void *compiler)
|
|||
delete[] mInfoLog;
|
||||
mInfoLog = NULL;
|
||||
|
||||
int result = ShCompile(compiler, &mSource, 1, EShOptNone, EDebugOpNone);
|
||||
const char *obj = ShGetObjectCode(compiler);
|
||||
const char *info = ShGetInfoLog(compiler);
|
||||
int result = ShCompile(compiler, &mSource, 1, SH_OBJECT_CODE);
|
||||
|
||||
if (result)
|
||||
{
|
||||
mHlsl = new char[strlen(obj) + 1];
|
||||
strcpy(mHlsl, obj);
|
||||
int objCodeLen = 0;
|
||||
ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &objCodeLen);
|
||||
mHlsl = new char[objCodeLen];
|
||||
ShGetObjectCode(compiler, mHlsl);
|
||||
|
||||
TRACE("\n%s", mHlsl);
|
||||
}
|
||||
else
|
||||
{
|
||||
mInfoLog = new char[strlen(info) + 1];
|
||||
strcpy(mInfoLog, info);
|
||||
int infoLogLen = 0;
|
||||
ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen);
|
||||
mInfoLog = new char[infoLogLen];
|
||||
ShGetInfoLog(compiler, mInfoLog);
|
||||
|
||||
TRACE("\n%s", mInfoLog);
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -18,6 +18,7 @@
|
|||
#include <d3d9.h>
|
||||
|
||||
#include "libGLESv2/Renderbuffer.h"
|
||||
#include "libGLESv2/RefCountObject.h"
|
||||
#include "libGLESv2/utilities.h"
|
||||
#include "common/debug.h"
|
||||
|
||||
|
@ -55,8 +56,12 @@ class Texture : public RefCountObject
|
|||
GLuint getWidth() const;
|
||||
GLuint getHeight() const;
|
||||
|
||||
virtual GLenum getFormat() const = 0;
|
||||
virtual bool isComplete() const = 0;
|
||||
virtual bool isCompressed() const = 0;
|
||||
bool isFloatingPoint() const;
|
||||
|
||||
D3DFORMAT getD3DFormat() const;
|
||||
IDirect3DBaseTexture9 *getTexture();
|
||||
virtual Renderbuffer *getColorbuffer(GLenum target) = 0;
|
||||
|
||||
|
@ -82,6 +87,8 @@ class Texture : public RefCountObject
|
|||
|
||||
virtual int getWidth() const;
|
||||
virtual int getHeight() const;
|
||||
virtual GLenum getFormat() const;
|
||||
virtual bool isFloatingPoint() const;
|
||||
|
||||
private:
|
||||
Texture *mTexture;
|
||||
|
@ -103,11 +110,12 @@ class Texture : public RefCountObject
|
|||
IDirect3DSurface9 *surface;
|
||||
};
|
||||
|
||||
static D3DFORMAT selectFormat(GLenum format);
|
||||
int imagePitch(const Image& img) const;
|
||||
static D3DFORMAT selectFormat(GLenum format, GLenum type);
|
||||
|
||||
void setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img);
|
||||
bool subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img);
|
||||
void setCompressedImage(GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *img);
|
||||
bool subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *img);
|
||||
|
||||
void needRenderTarget();
|
||||
|
||||
|
@ -135,6 +143,7 @@ class Texture : public RefCountObject
|
|||
GLenum mMagFilter;
|
||||
GLenum mWrapS;
|
||||
GLenum mWrapT;
|
||||
GLenum mType;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(Texture);
|
||||
|
@ -142,11 +151,53 @@ class Texture : public RefCountObject
|
|||
void loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type,
|
||||
GLint unpackAlignment, const void *input, std::size_t outputPitch, void *output) const;
|
||||
|
||||
void loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
|
||||
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
|
||||
void loadAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
|
||||
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
|
||||
void loadAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
|
||||
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
|
||||
void loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
|
||||
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
|
||||
void loadLuminanceFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
|
||||
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
|
||||
void loadLuminanceHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
|
||||
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
|
||||
void loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
|
||||
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
|
||||
void loadLuminanceAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
|
||||
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
|
||||
void loadLuminanceAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
|
||||
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
|
||||
void loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
|
||||
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
|
||||
void loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
|
||||
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
|
||||
void loadRGBFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
|
||||
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
|
||||
void loadRGBHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
|
||||
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
|
||||
void loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
|
||||
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
|
||||
void loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
|
||||
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
|
||||
void loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
|
||||
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
|
||||
void loadRGBAFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
|
||||
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
|
||||
void loadRGBAHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
|
||||
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
|
||||
void loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
|
||||
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
|
||||
|
||||
void createSurface(GLsizei width, GLsizei height, GLenum format, GLenum type, Image *img);
|
||||
|
||||
IDirect3DBaseTexture9 *mBaseTexture; // This is a weak pointer. The derived class is assumed to own a strong pointer.
|
||||
|
||||
bool mDirty;
|
||||
bool mDirtyMetaData;
|
||||
bool mIsRenderable;
|
||||
|
||||
};
|
||||
|
||||
class Texture2D : public Texture
|
||||
|
@ -157,13 +208,17 @@ class Texture2D : public Texture
|
|||
~Texture2D();
|
||||
|
||||
GLenum getTarget() const;
|
||||
GLenum getFormat() const;
|
||||
|
||||
void setImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
|
||||
void setCompressedImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
|
||||
void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
|
||||
void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
|
||||
void copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
|
||||
void copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
|
||||
|
||||
bool isComplete() const;
|
||||
bool isCompressed() const;
|
||||
|
||||
virtual void generateMipmaps();
|
||||
|
||||
|
@ -179,14 +234,14 @@ class Texture2D : public Texture
|
|||
|
||||
virtual bool dirtyImageData() const;
|
||||
|
||||
bool redefineTexture(GLint level, GLenum internalFormat, GLsizei width, GLsizei height);
|
||||
bool redefineTexture(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum type);
|
||||
void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
|
||||
|
||||
Image mImageArray[MAX_TEXTURE_LEVELS];
|
||||
|
||||
IDirect3DTexture9 *mTexture;
|
||||
|
||||
Renderbuffer *mColorbufferProxy;
|
||||
BindingPointer<Renderbuffer> mColorbufferProxy;
|
||||
};
|
||||
|
||||
class TextureCubeMap : public Texture
|
||||
|
@ -197,6 +252,7 @@ class TextureCubeMap : public Texture
|
|||
~TextureCubeMap();
|
||||
|
||||
GLenum getTarget() const;
|
||||
GLenum getFormat() const;
|
||||
|
||||
void setImagePosX(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
|
||||
void setImageNegX(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
|
||||
|
@ -205,11 +261,15 @@ class TextureCubeMap : public Texture
|
|||
void setImagePosZ(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
|
||||
void setImageNegZ(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
|
||||
|
||||
void setCompressedImage(GLenum face, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
|
||||
|
||||
void subImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
|
||||
void subImageCompressed(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
|
||||
void copyImage(GLenum face, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
|
||||
void copySubImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
|
||||
|
||||
bool isComplete() const;
|
||||
bool isCompressed() const;
|
||||
|
||||
virtual void generateMipmaps();
|
||||
|
||||
|
@ -241,7 +301,7 @@ class TextureCubeMap : public Texture
|
|||
|
||||
IDirect3DCubeTexture9 *mTexture;
|
||||
|
||||
Renderbuffer *mFaceProxies[6];
|
||||
BindingPointer<Renderbuffer> mFaceProxies[6];
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -144,11 +144,20 @@ EXPORTS
|
|||
glViewport @142
|
||||
|
||||
; Extensions
|
||||
glTexImage3DOES @143
|
||||
|
||||
glTexImage3DOES @143
|
||||
glBlitFramebufferANGLE @149
|
||||
glRenderbufferStorageMultisampleANGLE @150
|
||||
glDeleteFencesNV @151
|
||||
glFinishFenceNV @152
|
||||
glGenFencesNV @153
|
||||
glGetFenceivNV @154
|
||||
glIsFenceNV @155
|
||||
glSetFenceNV @156
|
||||
glTestFenceNV @157
|
||||
|
||||
; EGL dependencies
|
||||
glCreateContext @144 NONAME
|
||||
glDestroyContext @145 NONAME
|
||||
glMakeCurrent @146 NONAME
|
||||
glGetCurrentContext @147 NONAME
|
||||
glCreateContext @144 NONAME
|
||||
glDestroyContext @145 NONAME
|
||||
glMakeCurrent @146 NONAME
|
||||
glGetCurrentContext @147 NONAME
|
||||
glGetProcAddress @148 NONAME
|
|
@ -200,6 +200,10 @@
|
|||
RelativePath="..\common\debug.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Fence.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Framebuffer.cpp"
|
||||
>
|
||||
|
@ -278,6 +282,10 @@
|
|||
RelativePath=".\Context.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Fence.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Framebuffer.h"
|
||||
>
|
||||
|
|
|
@ -25,6 +25,8 @@ int UniformComponentCount(GLenum type)
|
|||
case GL_BOOL:
|
||||
case GL_FLOAT:
|
||||
case GL_INT:
|
||||
case GL_SAMPLER_2D:
|
||||
case GL_SAMPLER_CUBE:
|
||||
return 1;
|
||||
case GL_BOOL_VEC2:
|
||||
case GL_FLOAT_VEC2:
|
||||
|
@ -68,6 +70,8 @@ GLenum UniformComponentType(GLenum type)
|
|||
case GL_FLOAT_MAT4:
|
||||
return GL_FLOAT;
|
||||
case GL_INT:
|
||||
case GL_SAMPLER_2D:
|
||||
case GL_SAMPLER_CUBE:
|
||||
case GL_INT_VEC2:
|
||||
case GL_INT_VEC3:
|
||||
case GL_INT_VEC4:
|
||||
|
@ -183,6 +187,49 @@ GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment)
|
|||
return (rawPitch + alignment - 1) & ~(alignment - 1);
|
||||
}
|
||||
|
||||
GLsizei ComputeCompressedPitch(GLsizei width, GLenum format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
|
||||
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
ASSERT(width % 4 == 0);
|
||||
|
||||
return 8 * width / 4;
|
||||
}
|
||||
|
||||
GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
|
||||
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 8 * (GLsizei)ceil((float)width / 4.0f) * (GLsizei)ceil((float)height / 4.0f);
|
||||
}
|
||||
|
||||
bool IsCompressed(GLenum format)
|
||||
{
|
||||
if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
|
||||
format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the size, in bytes, of a single texel in an Image
|
||||
int ComputePixelSize(GLenum format, GLenum type)
|
||||
{
|
||||
|
@ -204,6 +251,28 @@ int ComputePixelSize(GLenum format, GLenum type)
|
|||
case GL_UNSIGNED_SHORT_5_5_5_1:
|
||||
case GL_UNSIGNED_SHORT_5_6_5:
|
||||
return sizeof(unsigned short);
|
||||
case GL_FLOAT:
|
||||
switch (format)
|
||||
{
|
||||
case GL_ALPHA: return sizeof(float);
|
||||
case GL_LUMINANCE: return sizeof(float);
|
||||
case GL_LUMINANCE_ALPHA: return sizeof(float) * 2;
|
||||
case GL_RGB: return sizeof(float) * 3;
|
||||
case GL_RGBA: return sizeof(float) * 4;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
break;
|
||||
case GL_HALF_FLOAT_OES:
|
||||
switch (format)
|
||||
{
|
||||
case GL_ALPHA: return sizeof(unsigned short);
|
||||
case GL_LUMINANCE: return sizeof(unsigned short);
|
||||
case GL_LUMINANCE_ALPHA: return sizeof(unsigned short) * 2;
|
||||
case GL_RGB: return sizeof(unsigned short) * 3;
|
||||
case GL_RGBA: return sizeof(unsigned short) * 4;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
break;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
|
||||
|
@ -240,6 +309,21 @@ bool CheckTextureFormatType(GLenum format, GLenum type)
|
|||
return false;
|
||||
}
|
||||
|
||||
case GL_FLOAT:
|
||||
case GL_HALF_FLOAT_OES:
|
||||
switch (format)
|
||||
{
|
||||
case GL_RGBA:
|
||||
case GL_RGB:
|
||||
case GL_ALPHA:
|
||||
case GL_LUMINANCE:
|
||||
case GL_LUMINANCE_ALPHA:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
case GL_UNSIGNED_SHORT_4_4_4_4:
|
||||
case GL_UNSIGNED_SHORT_5_5_5_1:
|
||||
return (format == GL_RGBA);
|
||||
|
@ -465,6 +549,10 @@ unsigned int GetAlphaSize(D3DFORMAT colorFormat)
|
|||
{
|
||||
switch (colorFormat)
|
||||
{
|
||||
case D3DFMT_A16B16G16R16F:
|
||||
return 16;
|
||||
case D3DFMT_A32B32G32R32F:
|
||||
return 32;
|
||||
case D3DFMT_A2R10G10B10:
|
||||
return 2;
|
||||
case D3DFMT_A8R8G8B8:
|
||||
|
@ -484,6 +572,10 @@ unsigned int GetRedSize(D3DFORMAT colorFormat)
|
|||
{
|
||||
switch (colorFormat)
|
||||
{
|
||||
case D3DFMT_A16B16G16R16F:
|
||||
return 16;
|
||||
case D3DFMT_A32B32G32R32F:
|
||||
return 32;
|
||||
case D3DFMT_A2R10G10B10:
|
||||
return 10;
|
||||
case D3DFMT_A8R8G8B8:
|
||||
|
@ -502,6 +594,10 @@ unsigned int GetGreenSize(D3DFORMAT colorFormat)
|
|||
{
|
||||
switch (colorFormat)
|
||||
{
|
||||
case D3DFMT_A16B16G16R16F:
|
||||
return 16;
|
||||
case D3DFMT_A32B32G32R32F:
|
||||
return 32;
|
||||
case D3DFMT_A2R10G10B10:
|
||||
return 10;
|
||||
case D3DFMT_A8R8G8B8:
|
||||
|
@ -521,6 +617,10 @@ unsigned int GetBlueSize(D3DFORMAT colorFormat)
|
|||
{
|
||||
switch (colorFormat)
|
||||
{
|
||||
case D3DFMT_A16B16G16R16F:
|
||||
return 16;
|
||||
case D3DFMT_A32B32G32R32F:
|
||||
return 32;
|
||||
case D3DFMT_A2R10G10B10:
|
||||
return 10;
|
||||
case D3DFMT_A8R8G8B8:
|
||||
|
@ -601,12 +701,31 @@ D3DFORMAT ConvertRenderbufferFormat(GLenum format)
|
|||
switch (format)
|
||||
{
|
||||
case GL_RGBA4:
|
||||
case GL_RGB5_A1: return D3DFMT_A8R8G8B8;
|
||||
case GL_RGB5_A1:
|
||||
case GL_RGBA8_OES: return D3DFMT_A8R8G8B8;
|
||||
case GL_RGB565: return D3DFMT_R5G6B5;
|
||||
case GL_RGB8_OES: return D3DFMT_X8R8G8B8;
|
||||
case GL_DEPTH_COMPONENT16:
|
||||
case GL_STENCIL_INDEX8: return D3DFMT_D24S8;
|
||||
case GL_STENCIL_INDEX8:
|
||||
case GL_DEPTH24_STENCIL8_OES: return D3DFMT_D24S8;
|
||||
default: UNREACHABLE(); return D3DFMT_A8R8G8B8;
|
||||
}
|
||||
}
|
||||
|
||||
GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type)
|
||||
{
|
||||
if (type == D3DMULTISAMPLE_NONMASKABLE)
|
||||
return 0;
|
||||
else
|
||||
return type;
|
||||
}
|
||||
|
||||
D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples)
|
||||
{
|
||||
if (samples <= 1)
|
||||
return D3DMULTISAMPLE_NONE;
|
||||
else
|
||||
return (D3DMULTISAMPLE_TYPE)samples;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,6 +29,9 @@ int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsig
|
|||
|
||||
int ComputePixelSize(GLenum format, GLenum type);
|
||||
GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment);
|
||||
GLsizei ComputeCompressedPitch(GLsizei width, GLenum format);
|
||||
GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format);
|
||||
bool IsCompressed(GLenum format);
|
||||
bool IsCubemapTextureTarget(GLenum target);
|
||||
bool IsTextureTarget(GLenum target);
|
||||
bool CheckTextureFormatType(GLenum format, GLenum type);
|
||||
|
@ -57,6 +60,8 @@ unsigned int GetStencilSize(D3DFORMAT stencilFormat);
|
|||
bool ConvertPrimitiveType(GLenum primitiveType, GLsizei primitiveCount,
|
||||
D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount);
|
||||
D3DFORMAT ConvertRenderbufferFormat(GLenum format);
|
||||
D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples);
|
||||
GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type);
|
||||
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче