Commit 7f694d92 by bajones@chromium.org

Added support for EXT_frag_depth

This change also required that support be added for associating built-in variables with an extension, similar to how functions could be associated with extensions previously. R=alokp@chromium.org Review URL: https://codereview.appspot.com/9827044 git-svn-id: https://angleproject.googlecode.com/svn/trunk@2248 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 4b721cda
...@@ -215,6 +215,7 @@ typedef struct ...@@ -215,6 +215,7 @@ typedef struct
int OES_EGL_image_external; int OES_EGL_image_external;
int ARB_texture_rectangle; int ARB_texture_rectangle;
int EXT_draw_buffers; int EXT_draw_buffers;
int EXT_frag_depth;
// 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.
......
...@@ -108,6 +108,7 @@ enum TQualifier ...@@ -108,6 +108,7 @@ enum TQualifier
// built-ins written by fragment shader // built-ins written by fragment shader
EvqFragColor, EvqFragColor,
EvqFragData, EvqFragData,
EvqFragDepth,
// end of list // end of list
EvqLast EvqLast
...@@ -139,6 +140,7 @@ inline const char* getQualifierString(TQualifier q) ...@@ -139,6 +140,7 @@ inline const char* getQualifierString(TQualifier q)
case EvqFrontFacing: return "FrontFacing"; break; case EvqFrontFacing: return "FrontFacing"; break;
case EvqFragColor: return "FragColor"; break; case EvqFragColor: return "FragColor"; break;
case EvqFragData: return "FragData"; break; case EvqFragData: return "FragData"; break;
case EvqFragDepth: return "FragDepth"; break;
default: return "unknown qualifier"; default: return "unknown qualifier";
} }
} }
......
...@@ -539,6 +539,10 @@ void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec, ...@@ -539,6 +539,10 @@ void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec,
if (spec != SH_CSS_SHADERS_SPEC) { if (spec != SH_CSS_SHADERS_SPEC) {
symbolTable.insert(*new TVariable(NewPoolTString("gl_FragColor"), TType(EbtFloat, EbpMedium, EvqFragColor, 4))); symbolTable.insert(*new TVariable(NewPoolTString("gl_FragColor"), TType(EbtFloat, EbpMedium, EvqFragColor, 4)));
symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqFragData, 4))); symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqFragData, 4)));
if (resources.EXT_frag_depth) {
symbolTable.insert(*new TVariable(NewPoolTString("gl_FragDepthEXT"), TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium, EvqFragDepth, 1)));
symbolTable.relateToExtension("gl_FragDepthEXT", "GL_EXT_frag_depth");
}
} else { } else {
symbolTable.insert(*new TVariable(NewPoolTString("css_MixColor"), TType(EbtFloat, EbpMedium, EvqGlobal, 4))); symbolTable.insert(*new TVariable(NewPoolTString("css_MixColor"), TType(EbtFloat, EbpMedium, EvqGlobal, 4)));
symbolTable.insert(*new TVariable(NewPoolTString("css_ColorMatrix"), TType(EbtFloat, EbpMedium, EvqGlobal, 4, true))); symbolTable.insert(*new TVariable(NewPoolTString("css_ColorMatrix"), TType(EbtFloat, EbpMedium, EvqGlobal, 4, true)));
...@@ -656,4 +660,6 @@ void InitExtensionBehavior(const ShBuiltInResources& resources, ...@@ -656,4 +660,6 @@ void InitExtensionBehavior(const ShBuiltInResources& resources,
extBehavior["GL_ARB_texture_rectangle"] = EBhUndefined; extBehavior["GL_ARB_texture_rectangle"] = EBhUndefined;
if (resources.EXT_draw_buffers) if (resources.EXT_draw_buffers)
extBehavior["GL_EXT_draw_buffers"] = EBhUndefined; extBehavior["GL_EXT_draw_buffers"] = EBhUndefined;
if (resources.EXT_frag_depth)
extBehavior["GL_EXT_frag_depth"] = EBhUndefined;
} }
...@@ -19,3 +19,17 @@ bool TOutputGLSL::writeVariablePrecision(TPrecision) ...@@ -19,3 +19,17 @@ bool TOutputGLSL::writeVariablePrecision(TPrecision)
{ {
return false; return false;
} }
void TOutputGLSL::visitSymbol(TIntermSymbol* node)
{
TInfoSinkBase& out = objSink();
if (node->getSymbol() == "gl_FragDepthEXT")
{
out << "gl_FragDepth";
}
else
{
TOutputGLSLBase::visitSymbol(node);
}
}
...@@ -20,6 +20,7 @@ public: ...@@ -20,6 +20,7 @@ public:
protected: protected:
virtual bool writeVariablePrecision(TPrecision); virtual bool writeVariablePrecision(TPrecision);
virtual void visitSymbol(TIntermSymbol* node);
}; };
#endif // CROSSCOMPILERGLSL_OUTPUTGLSL_H_ #endif // CROSSCOMPILERGLSL_OUTPUTGLSL_H_
...@@ -52,6 +52,7 @@ OutputHLSL::OutputHLSL(TParseContext &context) : TIntermTraverser(true, true, tr ...@@ -52,6 +52,7 @@ OutputHLSL::OutputHLSL(TParseContext &context) : TIntermTraverser(true, true, tr
mUsesPointCoord = false; mUsesPointCoord = false;
mUsesFrontFacing = false; mUsesFrontFacing = false;
mUsesPointSize = false; mUsesPointSize = false;
mUsesFragDepth = false;
mUsesXor = false; mUsesXor = false;
mUsesMod1 = false; mUsesMod1 = false;
mUsesMod2v = false; mUsesMod2v = false;
...@@ -189,6 +190,11 @@ void OutputHLSL::header() ...@@ -189,6 +190,11 @@ void OutputHLSL::header()
out << "\n" out << "\n"
"static float4 gl_Color[1] = {float4(0, 0, 0, 0)};\n"; "static float4 gl_Color[1] = {float4(0, 0, 0, 0)};\n";
if (mUsesFragDepth)
{
out << "static float gl_Depth = 0.0;\n";
}
if (mUsesFragCoord) if (mUsesFragCoord)
{ {
out << "static float4 gl_FragCoord = float4(0, 0, 0, 0);\n"; out << "static float4 gl_FragCoord = float4(0, 0, 0, 0);\n";
...@@ -509,6 +515,11 @@ void OutputHLSL::header() ...@@ -509,6 +515,11 @@ void OutputHLSL::header()
out << "#define GL_USES_POINT_SIZE\n"; out << "#define GL_USES_POINT_SIZE\n";
} }
if (mUsesFragDepth)
{
out << "#define GL_USES_FRAG_DEPTH\n";
}
if (mUsesDepthRange) if (mUsesDepthRange)
{ {
out << "struct gl_DepthRangeParameters\n" out << "struct gl_DepthRangeParameters\n"
...@@ -843,6 +854,11 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node) ...@@ -843,6 +854,11 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node)
mUsesPointSize = true; mUsesPointSize = true;
out << name; out << name;
} }
else if (name == "gl_FragDepthEXT")
{
mUsesFragDepth = true;
out << "gl_Depth";
}
else else
{ {
TQualifier qualifier = node->getQualifier(); TQualifier qualifier = node->getQualifier();
......
...@@ -97,6 +97,7 @@ class OutputHLSL : public TIntermTraverser ...@@ -97,6 +97,7 @@ class OutputHLSL : public TIntermTraverser
bool mUsesPointCoord; bool mUsesPointCoord;
bool mUsesFrontFacing; bool mUsesFrontFacing;
bool mUsesPointSize; bool mUsesPointSize;
bool mUsesFragDepth;
bool mUsesXor; bool mUsesXor;
bool mUsesMod1; bool mUsesMod1;
bool mUsesMod2v; bool mUsesMod2v;
......
...@@ -925,6 +925,27 @@ const TFunction* TParseContext::findFunction(const TSourceLoc& line, TFunction* ...@@ -925,6 +925,27 @@ const TFunction* TParseContext::findFunction(const TSourceLoc& line, TFunction*
return static_cast<const TFunction*>(symbol); return static_cast<const TFunction*>(symbol);
} }
bool TParseContext::isVariableBuiltIn(const TVariable* var)
{
bool builtIn = false;
// First find by unmangled name to check whether the function name has been
// hidden by a variable name or struct typename.
const TSymbol* symbol = symbolTable.find(var->getName(), &builtIn);
if (symbol == 0) {
symbol = symbolTable.find(var->getMangledName(), &builtIn);
}
if (symbol == 0) {
return false;
}
if (!symbol->isVariable()) {
return false;
}
return builtIn;
}
// //
// Initializers show up in several places in the grammar. Have one set of // Initializers show up in several places in the grammar. Have one set of
// code to handle them here. // code to handle them here.
......
...@@ -105,6 +105,7 @@ struct TParseContext { ...@@ -105,6 +105,7 @@ struct TParseContext {
bool containsSampler(TType& type); bool containsSampler(TType& type);
bool areAllChildConst(TIntermAggregate* aggrNode); bool areAllChildConst(TIntermAggregate* aggrNode);
const TFunction* findFunction(const TSourceLoc& line, TFunction* pfnCall, bool *builtIn = 0); const TFunction* findFunction(const TSourceLoc& line, TFunction* pfnCall, bool *builtIn = 0);
bool isVariableBuiltIn(const TVariable* pVar);
bool executeInitializer(const TSourceLoc& line, TString& identifier, TPublicType& pType, bool executeInitializer(const TSourceLoc& line, TString& identifier, TPublicType& pType,
TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0); TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0);
......
...@@ -126,6 +126,7 @@ void ShInitBuiltInResources(ShBuiltInResources* resources) ...@@ -126,6 +126,7 @@ void ShInitBuiltInResources(ShBuiltInResources* resources)
resources->OES_EGL_image_external = 0; resources->OES_EGL_image_external = 0;
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;
// Disable highp precision in fragment shader by default. // Disable highp precision in fragment shader by default.
resources->FragmentPrecisionHigh = 0; resources->FragmentPrecisionHigh = 0;
......
...@@ -223,10 +223,8 @@ void TSymbolTableLevel::relateToOperator(const char* name, TOperator op) ...@@ -223,10 +223,8 @@ void TSymbolTableLevel::relateToOperator(const char* name, TOperator op)
void TSymbolTableLevel::relateToExtension(const char* name, const TString& ext) void TSymbolTableLevel::relateToExtension(const char* name, const TString& ext)
{ {
for (tLevel::iterator it = level.begin(); it != level.end(); ++it) { for (tLevel::iterator it = level.begin(); it != level.end(); ++it) {
if (it->second->isFunction()) { TSymbol* symbol = it->second;
TFunction* function = static_cast<TFunction*>(it->second); if (symbol->getName() == name)
if (function->getName() == name) symbol->relateToExtension(ext);
function->relateToExtension(ext);
}
} }
} }
...@@ -50,13 +50,16 @@ public: ...@@ -50,13 +50,16 @@ public:
virtual bool isVariable() const { return false; } virtual bool isVariable() const { return false; }
void setUniqueId(int id) { uniqueId = id; } void setUniqueId(int id) { uniqueId = id; }
int getUniqueId() const { return uniqueId; } int getUniqueId() const { return uniqueId; }
virtual void dump(TInfoSink &infoSink) const = 0; virtual void dump(TInfoSink &infoSink) const = 0;
void relateToExtension(const TString& ext) { extension = ext; }
const TString& getExtension() const { return extension; }
private: private:
DISALLOW_COPY_AND_ASSIGN(TSymbol); DISALLOW_COPY_AND_ASSIGN(TSymbol);
const TString *name; const TString *name;
unsigned int uniqueId; // For real comparing during code generation unsigned int uniqueId; // For real comparing during code generation
TString extension;
}; };
// //
...@@ -156,9 +159,6 @@ public: ...@@ -156,9 +159,6 @@ public:
void relateToOperator(TOperator o) { op = o; } void relateToOperator(TOperator o) { op = o; }
TOperator getBuiltInOp() const { return op; } TOperator getBuiltInOp() const { return op; }
void relateToExtension(const TString& ext) { extension = ext; }
const TString& getExtension() const { return extension; }
void setDefined() { defined = true; } void setDefined() { defined = true; }
bool isDefined() { return defined; } bool isDefined() { return defined; }
...@@ -175,7 +175,6 @@ private: ...@@ -175,7 +175,6 @@ private:
TType returnType; TType returnType;
TString mangledName; TString mangledName;
TOperator op; TOperator op;
TString extension;
bool defined; bool defined;
}; };
......
...@@ -197,7 +197,14 @@ variable_identifier ...@@ -197,7 +197,14 @@ variable_identifier
context->error(@1, "variable expected", $1.string->c_str()); context->error(@1, "variable expected", $1.string->c_str());
context->recover(); context->recover();
} }
variable = static_cast<const TVariable*>(symbol); variable = static_cast<const TVariable*>(symbol);
if (context->isVariableBuiltIn(variable) &&
!variable->getExtension().empty() &&
context->extensionErrorCheck(@1, variable->getExtension())) {
context->recover();
}
} }
// don't delete $1.string, it's used by error recovery, and the pool // don't delete $1.string, it's used by error recovery, and the pool
......
...@@ -3964,6 +3964,7 @@ void Context::initExtensionString() ...@@ -3964,6 +3964,7 @@ void Context::initExtensionString()
extensionString += "GL_EXT_texture_format_BGRA8888 "; extensionString += "GL_EXT_texture_format_BGRA8888 ";
extensionString += "GL_EXT_texture_storage "; extensionString += "GL_EXT_texture_storage ";
extensionString += "GL_EXT_frag_depth ";
// ANGLE-specific extensions // ANGLE-specific extensions
if (supportsDepthTextures()) if (supportsDepthTextures())
......
...@@ -1549,8 +1549,14 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, std::string& pixelHLSL, std:: ...@@ -1549,8 +1549,14 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, std::string& pixelHLSL, std::
"\n" "\n"
"struct PS_OUTPUT\n" "struct PS_OUTPUT\n"
"{\n" "{\n"
" float4 gl_Color[1] : COLOR;\n" " float4 gl_Color[1] : COLOR;\n";
"};\n"
if (fragmentShader->mUsesFragDepth)
{
pixelHLSL += " float gl_Depth : DEPTH;\n";
}
pixelHLSL += "};\n"
"\n" "\n"
"PS_OUTPUT main(PS_INPUT input)\n" "PS_OUTPUT main(PS_INPUT input)\n"
"{\n"; "{\n";
...@@ -1625,9 +1631,15 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, std::string& pixelHLSL, std:: ...@@ -1625,9 +1631,15 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, std::string& pixelHLSL, std::
pixelHLSL += "\n" pixelHLSL += "\n"
" gl_main();\n" " gl_main();\n"
"\n" "\n"
" PS_OUTPUT output;\n" " PS_OUTPUT output;\n"
" output.gl_Color[0] = gl_Color[0];\n" " output.gl_Color[0] = gl_Color[0];\n";
"\n"
if (fragmentShader->mUsesFragDepth)
{
pixelHLSL += " output.gl_Depth = gl_Depth;\n";
}
pixelHLSL += "\n"
" return output;\n" " return output;\n"
"}\n"; "}\n";
......
...@@ -238,6 +238,7 @@ void Shader::initializeCompiler() ...@@ -238,6 +238,7 @@ void Shader::initializeCompiler()
resources.OES_standard_derivatives = context->supportsDerivativeInstructions() ? 1 : 0; resources.OES_standard_derivatives = context->supportsDerivativeInstructions() ? 1 : 0;
// resources.OES_EGL_image_external = getDisplay()->isD3d9ExDevice() ? 1 : 0; // TODO: commented out until the extension is actually supported. // resources.OES_EGL_image_external = getDisplay()->isD3d9ExDevice() ? 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
mFragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_GLES2_SPEC, SH_HLSL_OUTPUT, &resources); mFragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_GLES2_SPEC, SH_HLSL_OUTPUT, &resources);
mVertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_GLES2_SPEC, SH_HLSL_OUTPUT, &resources); mVertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_GLES2_SPEC, SH_HLSL_OUTPUT, &resources);
...@@ -292,6 +293,7 @@ void Shader::parseVaryings() ...@@ -292,6 +293,7 @@ void Shader::parseVaryings()
mUsesFrontFacing = strstr(mHlsl, "GL_USES_FRONT_FACING") != NULL; mUsesFrontFacing = strstr(mHlsl, "GL_USES_FRONT_FACING") != NULL;
mUsesPointSize = strstr(mHlsl, "GL_USES_POINT_SIZE") != NULL; mUsesPointSize = strstr(mHlsl, "GL_USES_POINT_SIZE") != NULL;
mUsesPointCoord = strstr(mHlsl, "GL_USES_POINT_COORD") != NULL; mUsesPointCoord = strstr(mHlsl, "GL_USES_POINT_COORD") != NULL;
mUsesFragDepth = strstr(mHlsl, "GL_USES_FRAG_DEPTH") != NULL;
} }
} }
...@@ -311,6 +313,7 @@ void Shader::uncompile() ...@@ -311,6 +313,7 @@ void Shader::uncompile()
mUsesFrontFacing = false; mUsesFrontFacing = false;
mUsesPointSize = false; mUsesPointSize = false;
mUsesPointCoord = false; mUsesPointCoord = false;
mUsesFragDepth = false;
} }
void Shader::compileToHLSL(void *compiler) void Shader::compileToHLSL(void *compiler)
......
...@@ -90,6 +90,7 @@ class Shader ...@@ -90,6 +90,7 @@ class Shader
bool mUsesFrontFacing; bool mUsesFrontFacing;
bool mUsesPointSize; bool mUsesPointSize;
bool mUsesPointCoord; bool mUsesPointCoord;
bool mUsesFragDepth;
static void *mFragmentCompiler; static void *mFragmentCompiler;
static void *mVertexCompiler; static void *mVertexCompiler;
......
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