Commit d70707b4 by Vladimir Vukicevic Committed by Nicolas Capens

Implement EXT_shader_texture_lod

Main author: Vladimir Vukicevic Original review: https://chromium-review.googlesource.com/#/c/185693/5 BUG=angle:551 Change-Id: I272ee33b315c4a33ff81c1c63c356347da42e545 Reviewed-on: https://chromium-review.googlesource.com/194982Tested-by: 's avatarNicolas Capens <nicolascapens@chromium.org> Reviewed-by: 's avatarShannon Woods <shannonwoods@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 74697cf2
Name
EXT_shader_texture_lod
Name Strings
GL_EXT_shader_texture_lod
Contributors
Benj Lipchak
Ben Bowman
and contributors to the ARB_shader_texture_lod spec,
which provided the basis for this spec.
Contact
Benj Lipchak, Apple (lipchak 'at' apple.com)
IP Status
No known IP issues.
Status
Draft
Version
Last Modified Date: February 24, 2011
Revision: 3
Number
OpenGL ES Extension #77
Dependencies
This extension is written against the OpenGL ES 2.0 Specification.
This extension is written against The OpenGL ES Shading Language,
Language Version 1.00, Document Revision 17.
This extension interacts with EXT_texture_filter_anisotropic.
Overview
This extension adds additional texture functions to the
OpenGL ES Shading Language which provide the shader writer
with explicit control of LOD.
Mipmap texture fetches and anisotropic texture fetches
require implicit derivatives to calculate rho, lambda
and/or the line of anisotropy. These implicit derivatives
will be undefined for texture fetches occurring inside
non-uniform control flow or for vertex shader texture
fetches, resulting in undefined texels.
The additional texture functions introduced with
this extension provide explicit control of LOD
(isotropic texture functions) or provide explicit
derivatives (anisotropic texture functions).
Anisotropic texture functions return defined texels
for mipmap texture fetches or anisotropic texture fetches,
even inside non-uniform control flow. Isotropic texture
functions return defined texels for mipmap texture fetches,
even inside non-uniform control flow. However, isotropic
texture functions return undefined texels for anisotropic
texture fetches.
The existing isotropic vertex texture functions:
vec4 texture2DLodEXT(sampler2D sampler,
vec2 coord,
float lod);
vec4 texture2DProjLodEXT(sampler2D sampler,
vec3 coord,
float lod);
vec4 texture2DProjLodEXT(sampler2D sampler,
vec4 coord,
float lod);
vec4 textureCubeLodEXT(samplerCube sampler,
vec3 coord,
float lod);
are added to the built-in functions for fragment shaders
with "EXT" suffix appended.
New anisotropic texture functions, providing explicit
derivatives:
vec4 texture2DGradEXT(sampler2D sampler,
vec2 P,
vec2 dPdx,
vec2 dPdy);
vec4 texture2DProjGradEXT(sampler2D sampler,
vec3 P,
vec2 dPdx,
vec2 dPdy);
vec4 texture2DProjGradEXT(sampler2D sampler,
vec4 P,
vec2 dPdx,
vec2 dPdy);
vec4 textureCubeGradEXT(samplerCube sampler,
vec3 P,
vec3 dPdx,
vec3 dPdy);
are added to the built-in functions for vertex shaders
and fragment shaders.
New Procedures and Functions
None
New Tokens
None
Additions to Chapter 2 of the OpenGL ES 2.0 Specification (OpenGL Operation)
None
Additions to Chapter 3 of the OpenGL ES 2.0 Specification (Rasterization)
In Section 3.7.7, replace the final paragraph on p. 76 with:
"Let s(x, y) be the function that associates an s texture coordinate
with each set of window coordinates (x, y) that lie within a
primitive; define t(x, y) analogously. Let u(x, y) = wt * s(x, y) and
v(x, y) = ht * t(x, y), where wt and ht are equal to the width and height
of the level zero array.
Let
dUdx = wt*dSdx; dUdy = wt*dSdy;
dVdx = ht*dTdx; dVdy = ht*dTdy; (3.12a)
where dSdx indicates the derivative of s with respect to window x,
and similarly for dTdx.
For a polygon, rho is given at a fragment with window coordinates
(x, y) by
rho = max (
sqrt(dUdx*dUdx + dVdx*dVdx),
sqrt(dUdy*dUdy + dVdy*dVdy)
); (3.12b)"
Additions to Chapter 4 of the OpenGL ES 2.0 Specification (Per-Fragment Operations and the Frame Buffer)
None
Additions to Chapter 5 of the OpenGL ES 2.0 Specification (Special Functions)
None
Additions to Chapter 6 of the OpenGL ES 2.0 Specification (State and State
Requests)
None
Additions to Appendix A of the OpenGL ES 2.0 Specification (Invariance)
None
Additions to version 1.00.17 of the OpenGL ES Shading Language Specification
"A new preprocessor #define is added to the OpenGL Shading Language:
#define GL_EXT_shader_texture_lod 1
Including the following line in a shader can be used to control the
language features described in this extension:
#extension GL_EXT_shader_texture_lod : <behavior>
Where <behavior> is as specified in section 3.3."
Additions to Chapter 8 of version 1.00.17 of the OpenGL ES Shading Language
Specification
8.7 Texture Lookup Functions
Delete the last paragraph, and replace with:
"For the "Lod" functions, lod specifies lambda_base (see equation 3.11 in
The OpenGL ES 2.0 Specification) and specifies dSdx, dTdx = 0 and
dSdy, dTdy = 0 (see equation 3.12a in The OpenGL ES 2.0 Specification).
The "Lod" functions are allowed in a vertex shader. If enabled by the
preprocessor directive #extension, the "Lod" functions are also allowed in
a fragment shader.
For the "Grad" functions, dPdx is the explicit derivative of P with respect
to window x, and similarly dPdy with respect to window y. For the "ProjGrad"
functions, dPdx is the explicit derivative of the projected P with respect
to window x, and similarly for dPdy with respect to window y. For a two-
dimensional texture, dPdx and dPdy are vec2. For a cube map texture,
dPdx and dPdy are vec3.
Let
dSdx = dPdx.s;
dSdy = dPdy.s;
dTdx = dPdx.t;
dTdy = dPdy.t;
and
/ 0.0; for two-dimensional texture
dRdx = (
\ dPdx.p; for cube map texture
/ 0.0; for two-dimensional texture
dRdy = (
\ dPdy.p; for cube map texture
(See equation 3.12a in The OpenGL ES 2.0 Specification.)
If enabled by the preprocessor directive #extension, the "Grad" functions
are allowed in vertex and fragment shaders.
All other texture functions may require implicit derivatives. Implicit
derivatives are undefined within non-uniform control flow or for vertex
shader texture fetches."
Add the following entries to the texture function table:
vec4 texture2DGradEXT(sampler2D sampler,
vec2 P,
vec2 dPdx,
vec2 dPdy);
vec4 texture2DProjGradEXT(sampler2D sampler,
vec3 P,
vec2 dPdx,
vec2 dPdy);
vec4 texture2DProjGradEXT(sampler2D sampler,
vec4 P,
vec2 dPdx,
vec2 dPdy);
vec4 textureCubeGradEXT(samplerCube sampler,
vec3 P,
vec3 dPdx,
vec3 dPdy);
Interactions with EXT_texture_anisotropic
The Lod functions set the derivatives ds/dx, dt/dx, dr/dx,
dx/dy, dt/dy, and dr/dy = 0. Therefore Rhox and Rhoy = 0
0, Rhomax and Rhomin = 0.
Revision History:
3 - 2011-02-24
* Assign extension number
2 - 2010-01-20
* Naming updates
1 - 2010-01-19
* Initial ES version
...@@ -36,8 +36,8 @@ extern "C" { ...@@ -36,8 +36,8 @@ extern "C" {
#endif #endif
// Version number for shader translation API. // Version number for shader translation API.
// It is incremented everytime the API changes. // It is incremented every time the API changes.
#define ANGLE_SH_VERSION 112 #define ANGLE_SH_VERSION 123
// //
// The names of the following enums have been derived by replacing GL prefix // The names of the following enums have been derived by replacing GL prefix
...@@ -88,6 +88,7 @@ typedef enum { ...@@ -88,6 +88,7 @@ typedef enum {
typedef enum { typedef enum {
SH_NONE = 0, SH_NONE = 0,
SH_INT = 0x1404, SH_INT = 0x1404,
SH_UNSIGNED_INT = 0x1405,
SH_FLOAT = 0x1406, SH_FLOAT = 0x1406,
SH_FLOAT_VEC2 = 0x8B50, SH_FLOAT_VEC2 = 0x8B50,
SH_FLOAT_VEC3 = 0x8B51, SH_FLOAT_VEC3 = 0x8B51,
...@@ -95,6 +96,9 @@ typedef enum { ...@@ -95,6 +96,9 @@ typedef enum {
SH_INT_VEC2 = 0x8B53, SH_INT_VEC2 = 0x8B53,
SH_INT_VEC3 = 0x8B54, SH_INT_VEC3 = 0x8B54,
SH_INT_VEC4 = 0x8B55, SH_INT_VEC4 = 0x8B55,
SH_UNSIGNED_INT_VEC2 = 0x8DC6,
SH_UNSIGNED_INT_VEC3 = 0x8DC7,
SH_UNSIGNED_INT_VEC4 = 0x8DC8,
SH_BOOL = 0x8B56, SH_BOOL = 0x8B56,
SH_BOOL_VEC2 = 0x8B57, SH_BOOL_VEC2 = 0x8B57,
SH_BOOL_VEC3 = 0x8B58, SH_BOOL_VEC3 = 0x8B58,
...@@ -102,10 +106,29 @@ typedef enum { ...@@ -102,10 +106,29 @@ typedef enum {
SH_FLOAT_MAT2 = 0x8B5A, SH_FLOAT_MAT2 = 0x8B5A,
SH_FLOAT_MAT3 = 0x8B5B, SH_FLOAT_MAT3 = 0x8B5B,
SH_FLOAT_MAT4 = 0x8B5C, SH_FLOAT_MAT4 = 0x8B5C,
SH_FLOAT_MAT2x3 = 0x8B65,
SH_FLOAT_MAT2x4 = 0x8B66,
SH_FLOAT_MAT3x2 = 0x8B67,
SH_FLOAT_MAT3x4 = 0x8B68,
SH_FLOAT_MAT4x2 = 0x8B69,
SH_FLOAT_MAT4x3 = 0x8B6A,
SH_SAMPLER_2D = 0x8B5E, SH_SAMPLER_2D = 0x8B5E,
SH_SAMPLER_3D = 0x8B5F,
SH_SAMPLER_CUBE = 0x8B60, SH_SAMPLER_CUBE = 0x8B60,
SH_SAMPLER_2D_RECT_ARB = 0x8B63, SH_SAMPLER_2D_RECT_ARB = 0x8B63,
SH_SAMPLER_EXTERNAL_OES = 0x8D66 SH_SAMPLER_EXTERNAL_OES = 0x8D66,
SH_SAMPLER_2D_ARRAY = 0x8DC1,
SH_INT_SAMPLER_2D = 0x8DCA,
SH_INT_SAMPLER_3D = 0x8DCB,
SH_INT_SAMPLER_CUBE = 0x8DCC,
SH_INT_SAMPLER_2D_ARRAY = 0x8DCF,
SH_UNSIGNED_INT_SAMPLER_2D = 0x8DD2,
SH_UNSIGNED_INT_SAMPLER_3D = 0x8DD3,
SH_UNSIGNED_INT_SAMPLER_CUBE = 0x8DD4,
SH_UNSIGNED_INT_SAMPLER_2D_ARRAY = 0x8DD7,
SH_SAMPLER_2D_SHADOW = 0x8B62,
SH_SAMPLER_CUBE_SHADOW = 0x8DC5,
SH_SAMPLER_2D_ARRAY_SHADOW = 0x8DC4
} ShDataType; } ShDataType;
typedef enum { typedef enum {
...@@ -128,7 +151,12 @@ typedef enum { ...@@ -128,7 +151,12 @@ typedef enum {
SH_NAME_MAX_LENGTH = 0x6001, SH_NAME_MAX_LENGTH = 0x6001,
SH_HASHED_NAME_MAX_LENGTH = 0x6002, SH_HASHED_NAME_MAX_LENGTH = 0x6002,
SH_HASHED_NAMES_COUNT = 0x6003, SH_HASHED_NAMES_COUNT = 0x6003,
SH_ACTIVE_UNIFORMS_ARRAY = 0x6004 SH_ACTIVE_UNIFORMS_ARRAY = 0x6004,
SH_SHADER_VERSION = 0x6005,
SH_ACTIVE_INTERFACE_BLOCKS_ARRAY = 0x6006,
SH_ACTIVE_OUTPUT_VARIABLES_ARRAY = 0x6007,
SH_ACTIVE_ATTRIBUTES_ARRAY = 0x6008,
SH_ACTIVE_VARYINGS_ARRAY = 0x6009,
} ShShaderInfo; } ShShaderInfo;
// Compile options. // Compile options.
...@@ -256,11 +284,18 @@ typedef struct ...@@ -256,11 +284,18 @@ typedef struct
int ARB_texture_rectangle; int ARB_texture_rectangle;
int EXT_draw_buffers; int EXT_draw_buffers;
int EXT_frag_depth; int EXT_frag_depth;
int EXT_shader_texture_lod;
// Set to 1 if highp precision is supported in the fragment language. // Set to 1 if highp precision is supported in the fragment language.
// Default is 0. // Default is 0.
int FragmentPrecisionHigh; int FragmentPrecisionHigh;
// GLSL ES 3.0 constants.
int MaxVertexOutputVectors;
int MaxFragmentInputVectors;
int MinProgramTexelOffset;
int MaxProgramTexelOffset;
// Name Hashing. // Name Hashing.
// Set a 64 bit hash function to enable user-defined name hashing. // Set a 64 bit hash function to enable user-defined name hashing.
// Default is NULL. // Default is NULL.
...@@ -368,6 +403,7 @@ COMPILER_EXPORT int ShCompile( ...@@ -368,6 +403,7 @@ COMPILER_EXPORT int ShCompile(
// SH_HASHED_NAME_MAX_LENGTH: the max length of a hashed name including the // SH_HASHED_NAME_MAX_LENGTH: the max length of a hashed name including the
// null termination character. // null termination character.
// SH_HASHED_NAMES_COUNT: the number of hashed names from the latest compile. // SH_HASHED_NAMES_COUNT: the number of hashed names from the latest compile.
// SH_SHADER_VERSION: the version of the shader language
// //
// params: Requested parameter // params: Requested parameter
COMPILER_EXPORT void ShGetInfo(const ShHandle handle, COMPILER_EXPORT void ShGetInfo(const ShHandle handle,
......
...@@ -126,6 +126,7 @@ int main(int argc, char* argv[]) ...@@ -126,6 +126,7 @@ int main(int argc, char* argv[])
case 'i': resources.OES_EGL_image_external = 1; break; case 'i': resources.OES_EGL_image_external = 1; break;
case 'd': resources.OES_standard_derivatives = 1; break; case 'd': resources.OES_standard_derivatives = 1; break;
case 'r': resources.ARB_texture_rectangle = 1; break; case 'r': resources.ARB_texture_rectangle = 1; break;
case 'l': resources.EXT_shader_texture_lod = 1; break;
default: failCode = EFailUsage; default: failCode = EFailUsage;
} }
} else { } else {
...@@ -231,7 +232,8 @@ void usage() ...@@ -231,7 +232,8 @@ void usage()
" -b=h11 : output HLSL11 code\n" " -b=h11 : output HLSL11 code\n"
" -x=i : enable GL_OES_EGL_image_external\n" " -x=i : enable GL_OES_EGL_image_external\n"
" -x=d : enable GL_OES_EGL_standard_derivatives\n" " -x=d : enable GL_OES_EGL_standard_derivatives\n"
" -x=r : enable ARB_texture_rectangle\n"); " -x=r : enable ARB_texture_rectangle\n"
" -x=l : enable EXT_shader_texture_lod\n");
} }
// //
......
...@@ -350,6 +350,21 @@ void InsertBuiltInFunctions(ShShaderType type, ShShaderSpec spec, const ShBuiltI ...@@ -350,6 +350,21 @@ void InsertBuiltInFunctions(ShShaderType type, ShShaderSpec spec, const ShBuiltI
symbolTable.insertBuiltIn(float4, "texture2DRectProj", sampler2DRect, float4); symbolTable.insertBuiltIn(float4, "texture2DRectProj", sampler2DRect, float4);
} }
if (resources.EXT_shader_texture_lod)
{
/* The *Grad* variants are new to both vertex and fragment shaders; the fragment
* shader specific pieces are added separately below.
*/
symbolTable.insertBuiltIn(float4, "texture2DGradEXT", sampler2D, float2, float2, float2);
symbolTable.insertBuiltIn(float4, "texture2DProjGradEXT", sampler2D, float3, float2, float2);
symbolTable.insertBuiltIn(float4, "texture2DProjGradEXT", sampler2D, float4, float2, float2);
symbolTable.insertBuiltIn(float4, "textureCubeGradEXT", samplerCube, float3, float3, float3);
symbolTable.relateToExtension("texture2DGradEXT", "GL_EXT_shader_texture_lod");
symbolTable.relateToExtension("texture2DProjGradEXT", "GL_EXT_shader_texture_lod");
symbolTable.relateToExtension("textureCubeGradEXT", "GL_EXT_shader_texture_lod");
}
if (type == SH_FRAGMENT_SHADER) if (type == SH_FRAGMENT_SHADER)
{ {
symbolTable.insertBuiltIn(float4, "texture2D", sampler2D, float2, float1); symbolTable.insertBuiltIn(float4, "texture2D", sampler2D, float2, float1);
...@@ -374,9 +389,21 @@ void InsertBuiltInFunctions(ShShaderType type, ShShaderSpec spec, const ShBuiltI ...@@ -374,9 +389,21 @@ void InsertBuiltInFunctions(ShShaderType type, ShShaderSpec spec, const ShBuiltI
symbolTable.insertBuiltIn(float3, "fwidth", float3); symbolTable.insertBuiltIn(float3, "fwidth", float3);
symbolTable.insertBuiltIn(float4, "fwidth", float4); symbolTable.insertBuiltIn(float4, "fwidth", float4);
} }
if (resources.EXT_shader_texture_lod)
{
symbolTable.insertBuiltIn(float4, "texture2DLodEXT", sampler2D, float2, float1);
symbolTable.insertBuiltIn(float4, "texture2DProjLodEXT", sampler2D, float3, float1);
symbolTable.insertBuiltIn(float4, "texture2DProjLodEXT", sampler2D, float4, float1);
symbolTable.insertBuiltIn(float4, "textureCubeLodEXT", samplerCube, float3, float1);
symbolTable.relateToExtension("texture2DLodEXT", "GL_EXT_shader_texture_lod");
symbolTable.relateToExtension("texture2DProjLodEXT", "GL_EXT_shader_texture_lod");
symbolTable.relateToExtension("textureCubeLodEXT", "GL_EXT_shader_texture_lod");
}
} }
if(type == SH_VERTEX_SHADER) if (type == SH_VERTEX_SHADER)
{ {
symbolTable.insertBuiltIn(float4, "texture2DLod", sampler2D, float2, float1); symbolTable.insertBuiltIn(float4, "texture2DLod", sampler2D, float2, float1);
symbolTable.insertBuiltIn(float4, "texture2DProjLod", sampler2D, float3, float1); symbolTable.insertBuiltIn(float4, "texture2DProjLod", sampler2D, float3, float1);
...@@ -561,4 +588,6 @@ void InitExtensionBehavior(const ShBuiltInResources& resources, ...@@ -561,4 +588,6 @@ void InitExtensionBehavior(const ShBuiltInResources& resources,
extBehavior["GL_EXT_draw_buffers"] = EBhUndefined; extBehavior["GL_EXT_draw_buffers"] = EBhUndefined;
if (resources.EXT_frag_depth) if (resources.EXT_frag_depth)
extBehavior["GL_EXT_frag_depth"] = EBhUndefined; extBehavior["GL_EXT_frag_depth"] = EBhUndefined;
if (resources.EXT_shader_texture_lod)
extBehavior["GL_EXT_shader_texture_lod"] = EBhUndefined;
} }
...@@ -33,3 +33,24 @@ void TOutputGLSL::visitSymbol(TIntermSymbol* node) ...@@ -33,3 +33,24 @@ void TOutputGLSL::visitSymbol(TIntermSymbol* node)
TOutputGLSLBase::visitSymbol(node); TOutputGLSLBase::visitSymbol(node);
} }
} }
TString TOutputGLSL::translateTextureFunction(TString& name)
{
static const char *simpleRename[] = {
"texture2DLodEXT", "texture2DLod",
"texture2DProjLodEXT", "texture2DProjLod",
"textureCubeLodEXT", "textureCubeLod",
"texture2DGradEXT", "texture2DGradARB",
"texture2DProjGradEXT", "texture2DProjGradARB",
"textureCubeGradEXT", "textureCubeGradARB",
NULL, NULL
};
for (int i = 0; simpleRename[i] != NULL; i += 2) {
if (name == simpleRename[i]) {
return simpleRename[i+1];
}
}
return name;
}
...@@ -21,6 +21,7 @@ public: ...@@ -21,6 +21,7 @@ public:
protected: protected:
virtual bool writeVariablePrecision(TPrecision); virtual bool writeVariablePrecision(TPrecision);
virtual void visitSymbol(TIntermSymbol* node); virtual void visitSymbol(TIntermSymbol* node);
virtual TString translateTextureFunction(TString& name);
}; };
#endif // CROSSCOMPILERGLSL_OUTPUTGLSL_H_ #endif // CROSSCOMPILERGLSL_OUTPUTGLSL_H_
...@@ -798,8 +798,9 @@ TString TOutputGLSLBase::hashVariableName(const TString& name) ...@@ -798,8 +798,9 @@ TString TOutputGLSLBase::hashVariableName(const TString& name)
TString TOutputGLSLBase::hashFunctionName(const TString& mangled_name) TString TOutputGLSLBase::hashFunctionName(const TString& mangled_name)
{ {
TString name = TFunction::unmangleName(mangled_name); TString name = TFunction::unmangleName(mangled_name);
if (mSymbolTable.findBuiltIn(mangled_name) != NULL || name == "main") if (mSymbolTable.findBuiltIn(mangled_name) != NULL || name == "main") {
return name; return translateTextureFunction(name);
}
return hashName(name); return hashName(name);
} }
......
...@@ -50,6 +50,8 @@ protected: ...@@ -50,6 +50,8 @@ protected:
TString hashVariableName(const TString& name); TString hashVariableName(const TString& name);
// Same as hashName(), but without hashing built-in functions. // Same as hashName(), but without hashing built-in functions.
TString hashFunctionName(const TString& mangled_name); TString hashFunctionName(const TString& mangled_name);
// Used to translate function names for differences between ESSL and GLSL
virtual TString translateTextureFunction(TString& name) { return name; }
private: private:
bool structDeclared(const TStructure* structure) const; bool structDeclared(const TStructure* structure) const;
......
...@@ -93,9 +93,12 @@ class OutputHLSL : public TIntermTraverser ...@@ -93,9 +93,12 @@ class OutputHLSL : public TIntermTraverser
bool mUsesTexture2DProj; bool mUsesTexture2DProj;
bool mUsesTexture2DProj_bias; bool mUsesTexture2DProj_bias;
bool mUsesTexture2DProjLod; bool mUsesTexture2DProjLod;
bool mUsesTexture2DGrad;
bool mUsesTexture2DProjGrad;
bool mUsesTextureCube; bool mUsesTextureCube;
bool mUsesTextureCube_bias; bool mUsesTextureCube_bias;
bool mUsesTextureCubeLod; bool mUsesTextureCubeLod;
bool mUsesTextureCubeGrad;
bool mUsesTexture2DLod0; bool mUsesTexture2DLod0;
bool mUsesTexture2DLod0_bias; bool mUsesTexture2DLod0_bias;
bool mUsesTexture2DProjLod0; bool mUsesTexture2DProjLod0;
......
...@@ -89,6 +89,7 @@ void ShInitBuiltInResources(ShBuiltInResources* resources) ...@@ -89,6 +89,7 @@ void ShInitBuiltInResources(ShBuiltInResources* resources)
resources->ARB_texture_rectangle = 0; resources->ARB_texture_rectangle = 0;
resources->EXT_draw_buffers = 0; resources->EXT_draw_buffers = 0;
resources->EXT_frag_depth = 0; resources->EXT_frag_depth = 0;
resources->EXT_shader_texture_lod = 0;
// Disable highp precision in fragment shader by default. // Disable highp precision in fragment shader by default.
resources->FragmentPrecisionHigh = 0; resources->FragmentPrecisionHigh = 0;
......
...@@ -280,7 +280,7 @@ public: ...@@ -280,7 +280,7 @@ public:
return insert(*constant); return insert(*constant);
} }
bool insertBuiltIn(TType *rvalue, const char *name, TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0) bool insertBuiltIn(TType *rvalue, const char *name, TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0, TType *ptype4 = 0)
{ {
TFunction *function = new TFunction(NewPoolTString(name), *rvalue); TFunction *function = new TFunction(NewPoolTString(name), *rvalue);
...@@ -299,6 +299,12 @@ public: ...@@ -299,6 +299,12 @@ public:
function->addParameter(param3); function->addParameter(param3);
} }
if(ptype4)
{
TParameter param4 = {NULL, ptype4};
function->addParameter(param4);
}
return insert(*function); return insert(*function);
} }
......
...@@ -31,6 +31,9 @@ void TranslatorGLSL::translate(TIntermNode* root) { ...@@ -31,6 +31,9 @@ void TranslatorGLSL::translate(TIntermNode* root) {
// Write GLSL version. // Write GLSL version.
writeVersion(getShaderType(), root, sink); writeVersion(getShaderType(), root, sink);
// Write extension behaviour as needed
writeExtensionBehavior();
// Write emulated built-in functions if needed. // Write emulated built-in functions if needed.
getBuiltInFunctionEmulator().OutputEmulatedFunctionDefinition( getBuiltInFunctionEmulator().OutputEmulatedFunctionDefinition(
sink, false); sink, false);
...@@ -42,3 +45,20 @@ void TranslatorGLSL::translate(TIntermNode* root) { ...@@ -42,3 +45,20 @@ void TranslatorGLSL::translate(TIntermNode* root) {
TOutputGLSL outputGLSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(), getSymbolTable()); TOutputGLSL outputGLSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(), getSymbolTable());
root->traverse(&outputGLSL); root->traverse(&outputGLSL);
} }
void TranslatorGLSL::writeExtensionBehavior() {
TInfoSinkBase& sink = getInfoSink().obj;
const TExtensionBehavior& extensionBehavior = getExtensionBehavior();
for (TExtensionBehavior::const_iterator iter = extensionBehavior.begin();
iter != extensionBehavior.end(); ++iter) {
if (iter->second == EBhUndefined)
continue;
// For GLSL output, we don't need to emit most extensions explicitly,
// but some we need to translate.
if (iter->first == "GL_EXT_shader_texture_lod") {
sink << "#extension GL_ARB_shader_texture_lod : "
<< getBehaviorString(iter->second) << "\n";
}
}
}
...@@ -15,6 +15,9 @@ public: ...@@ -15,6 +15,9 @@ public:
protected: protected:
virtual void translate(TIntermNode* root); virtual void translate(TIntermNode* root);
private:
void writeExtensionBehavior();
}; };
#endif // COMPILER_TRANSLATORGLSL_H_ #endif // COMPILER_TRANSLATORGLSL_H_
...@@ -2568,6 +2568,7 @@ void Context::initExtensionString() ...@@ -2568,6 +2568,7 @@ void Context::initExtensionString()
extensionString += "GL_EXT_read_format_bgra "; extensionString += "GL_EXT_read_format_bgra ";
extensionString += "GL_EXT_robustness "; extensionString += "GL_EXT_robustness ";
extensionString += "GL_EXT_shader_texture_lod ";
if (supportsDXT1Textures()) if (supportsDXT1Textures())
{ {
......
...@@ -245,6 +245,7 @@ void Shader::initializeCompiler() ...@@ -245,6 +245,7 @@ void Shader::initializeCompiler()
resources.MaxDrawBuffers = mRenderer->getMaxRenderTargets(); resources.MaxDrawBuffers = mRenderer->getMaxRenderTargets();
resources.OES_standard_derivatives = mRenderer->getDerivativeInstructionSupport(); resources.OES_standard_derivatives = mRenderer->getDerivativeInstructionSupport();
resources.EXT_draw_buffers = mRenderer->getMaxRenderTargets() > 1; resources.EXT_draw_buffers = mRenderer->getMaxRenderTargets() > 1;
resources.EXT_shader_texture_lod = 1;
// resources.OES_EGL_image_external = mRenderer->getShareHandleSupport() ? 1 : 0; // TODO: commented out until the extension is actually supported. // resources.OES_EGL_image_external = mRenderer->getShareHandleSupport() ? 1 : 0; // TODO: commented out until the extension is actually supported.
resources.FragmentPrecisionHigh = 1; // Shader Model 2+ always supports FP24 (s16e7) which corresponds to highp resources.FragmentPrecisionHigh = 1; // Shader Model 2+ always supports FP24 (s16e7) which corresponds to highp
resources.EXT_frag_depth = 1; // Shader Model 2+ always supports explicit depth output resources.EXT_frag_depth = 1; // Shader Model 2+ always supports explicit depth output
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment