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
int OES_EGL_image_external;
int ARB_texture_rectangle;
int EXT_draw_buffers;
int EXT_frag_depth;
// Set to 1 if highp precision is supported in the fragment language.
// Default is 0.
......
......@@ -108,6 +108,7 @@ enum TQualifier
// built-ins written by fragment shader
EvqFragColor,
EvqFragData,
EvqFragDepth,
// end of list
EvqLast
......@@ -139,6 +140,7 @@ inline const char* getQualifierString(TQualifier q)
case EvqFrontFacing: return "FrontFacing"; break;
case EvqFragColor: return "FragColor"; break;
case EvqFragData: return "FragData"; break;
case EvqFragDepth: return "FragDepth"; break;
default: return "unknown qualifier";
}
}
......
......@@ -539,6 +539,10 @@ void IdentifyBuiltIns(ShShaderType type, ShShaderSpec 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_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 {
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)));
......@@ -656,4 +660,6 @@ void InitExtensionBehavior(const ShBuiltInResources& resources,
extBehavior["GL_ARB_texture_rectangle"] = EBhUndefined;
if (resources.EXT_draw_buffers)
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)
{
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:
protected:
virtual bool writeVariablePrecision(TPrecision);
virtual void visitSymbol(TIntermSymbol* node);
};
#endif // CROSSCOMPILERGLSL_OUTPUTGLSL_H_
......@@ -52,6 +52,7 @@ OutputHLSL::OutputHLSL(TParseContext &context) : TIntermTraverser(true, true, tr
mUsesPointCoord = false;
mUsesFrontFacing = false;
mUsesPointSize = false;
mUsesFragDepth = false;
mUsesXor = false;
mUsesMod1 = false;
mUsesMod2v = false;
......@@ -189,6 +190,11 @@ void OutputHLSL::header()
out << "\n"
"static float4 gl_Color[1] = {float4(0, 0, 0, 0)};\n";
if (mUsesFragDepth)
{
out << "static float gl_Depth = 0.0;\n";
}
if (mUsesFragCoord)
{
out << "static float4 gl_FragCoord = float4(0, 0, 0, 0);\n";
......@@ -509,6 +515,11 @@ void OutputHLSL::header()
out << "#define GL_USES_POINT_SIZE\n";
}
if (mUsesFragDepth)
{
out << "#define GL_USES_FRAG_DEPTH\n";
}
if (mUsesDepthRange)
{
out << "struct gl_DepthRangeParameters\n"
......@@ -843,6 +854,11 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node)
mUsesPointSize = true;
out << name;
}
else if (name == "gl_FragDepthEXT")
{
mUsesFragDepth = true;
out << "gl_Depth";
}
else
{
TQualifier qualifier = node->getQualifier();
......
......@@ -97,6 +97,7 @@ class OutputHLSL : public TIntermTraverser
bool mUsesPointCoord;
bool mUsesFrontFacing;
bool mUsesPointSize;
bool mUsesFragDepth;
bool mUsesXor;
bool mUsesMod1;
bool mUsesMod2v;
......
......@@ -925,6 +925,27 @@ const TFunction* TParseContext::findFunction(const TSourceLoc& line, TFunction*
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
// code to handle them here.
......
......@@ -105,6 +105,7 @@ struct TParseContext {
bool containsSampler(TType& type);
bool areAllChildConst(TIntermAggregate* aggrNode);
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,
TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0);
......
......@@ -126,6 +126,7 @@ void ShInitBuiltInResources(ShBuiltInResources* resources)
resources->OES_EGL_image_external = 0;
resources->ARB_texture_rectangle = 0;
resources->EXT_draw_buffers = 0;
resources->EXT_frag_depth = 0;
// Disable highp precision in fragment shader by default.
resources->FragmentPrecisionHigh = 0;
......
......@@ -223,10 +223,8 @@ void TSymbolTableLevel::relateToOperator(const char* name, TOperator op)
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* symbol = it->second;
if (symbol->getName() == name)
symbol->relateToExtension(ext);
}
}
......@@ -50,13 +50,16 @@ public:
virtual bool isVariable() const { return false; }
void setUniqueId(int id) { uniqueId = id; }
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:
DISALLOW_COPY_AND_ASSIGN(TSymbol);
const TString *name;
unsigned int uniqueId; // For real comparing during code generation
TString extension;
};
//
......@@ -156,9 +159,6 @@ public:
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; }
......@@ -175,7 +175,6 @@ private:
TType returnType;
TString mangledName;
TOperator op;
TString extension;
bool defined;
};
......
......@@ -197,7 +197,14 @@ variable_identifier
context->error(@1, "variable expected", $1.string->c_str());
context->recover();
}
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
......
......@@ -3964,6 +3964,7 @@ void Context::initExtensionString()
extensionString += "GL_EXT_texture_format_BGRA8888 ";
extensionString += "GL_EXT_texture_storage ";
extensionString += "GL_EXT_frag_depth ";
// ANGLE-specific extensions
if (supportsDepthTextures())
......
......@@ -1549,8 +1549,14 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, std::string& pixelHLSL, std::
"\n"
"struct PS_OUTPUT\n"
"{\n"
" float4 gl_Color[1] : COLOR;\n"
"};\n"
" float4 gl_Color[1] : COLOR;\n";
if (fragmentShader->mUsesFragDepth)
{
pixelHLSL += " float gl_Depth : DEPTH;\n";
}
pixelHLSL += "};\n"
"\n"
"PS_OUTPUT main(PS_INPUT input)\n"
"{\n";
......@@ -1625,9 +1631,15 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, std::string& pixelHLSL, std::
pixelHLSL += "\n"
" gl_main();\n"
"\n"
" PS_OUTPUT output;\n"
" output.gl_Color[0] = gl_Color[0];\n"
"\n"
" PS_OUTPUT output;\n"
" output.gl_Color[0] = gl_Color[0];\n";
if (fragmentShader->mUsesFragDepth)
{
pixelHLSL += " output.gl_Depth = gl_Depth;\n";
}
pixelHLSL += "\n"
" return output;\n"
"}\n";
......
......@@ -238,6 +238,7 @@ void Shader::initializeCompiler()
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.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);
mVertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_GLES2_SPEC, SH_HLSL_OUTPUT, &resources);
......@@ -292,6 +293,7 @@ void Shader::parseVaryings()
mUsesFrontFacing = strstr(mHlsl, "GL_USES_FRONT_FACING") != NULL;
mUsesPointSize = strstr(mHlsl, "GL_USES_POINT_SIZE") != NULL;
mUsesPointCoord = strstr(mHlsl, "GL_USES_POINT_COORD") != NULL;
mUsesFragDepth = strstr(mHlsl, "GL_USES_FRAG_DEPTH") != NULL;
}
}
......@@ -311,6 +313,7 @@ void Shader::uncompile()
mUsesFrontFacing = false;
mUsesPointSize = false;
mUsesPointCoord = false;
mUsesFragDepth = false;
}
void Shader::compileToHLSL(void *compiler)
......
......@@ -90,6 +90,7 @@ class Shader
bool mUsesFrontFacing;
bool mUsesPointSize;
bool mUsesPointCoord;
bool mUsesFragDepth;
static void *mFragmentCompiler;
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