Commit ea7a2121 by Erik Dahlström Committed by Jamie Madill

Add GLSL/ESSL validator/translator support for GL_EXT_shader_framebuffer_fetch.

BUG=angle:834 Change-Id: I2d4e25909a8e1266b9bb7f1d4421324143157c8a Reviewed-on: https://chromium-review.googlesource.com/231032Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarErik Dahlström <ed@opera.com>
parent 870352a1
...@@ -48,7 +48,7 @@ typedef unsigned int GLenum; ...@@ -48,7 +48,7 @@ typedef unsigned int GLenum;
// Version number for shader translation API. // Version number for shader translation API.
// It is incremented every time the API changes. // It is incremented every time the API changes.
#define ANGLE_SH_VERSION 132 #define ANGLE_SH_VERSION 133
typedef enum { typedef enum {
SH_GLES2_SPEC = 0x8B40, SH_GLES2_SPEC = 0x8B40,
...@@ -224,6 +224,9 @@ typedef struct ...@@ -224,6 +224,9 @@ typedef struct
int EXT_frag_depth; int EXT_frag_depth;
int EXT_shader_texture_lod; int EXT_shader_texture_lod;
int WEBGL_debug_shader_precision; int WEBGL_debug_shader_precision;
int EXT_shader_framebuffer_fetch;
int NV_shader_framebuffer_fetch;
int ARM_shader_framebuffer_fetch;
// Set to 1 to enable replacing GL_EXT_draw_buffers #extension directives // Set to 1 to enable replacing GL_EXT_draw_buffers #extension directives
// with GL_NV_draw_buffers in ESSL output. This flag can be used to emulate // with GL_NV_draw_buffers in ESSL output. This flag can be used to emulate
......
...@@ -140,6 +140,9 @@ int main(int argc, char *argv[]) ...@@ -140,6 +140,9 @@ int main(int argc, char *argv[])
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; case 'l': resources.EXT_shader_texture_lod = 1; break;
case 'f': resources.EXT_shader_framebuffer_fetch = 1; break;
case 'n': resources.NV_shader_framebuffer_fetch = 1; break;
case 'a': resources.ARM_shader_framebuffer_fetch = 1; break;
default: failCode = EFailUsage; default: failCode = EFailUsage;
} }
} }
...@@ -248,7 +251,10 @@ void usage() ...@@ -248,7 +251,10 @@ void usage()
" -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"); " -x=l : enable EXT_shader_texture_lod\n"
" -x=f : enable EXT_shader_framebuffer_fetch\n"
" -x=n : enable NV_shader_framebuffer_fetch\n"
" -x=a : enable ARM_shader_framebuffer_fetch\n");
} }
// //
......
...@@ -307,6 +307,10 @@ enum TQualifier ...@@ -307,6 +307,10 @@ enum TQualifier
EvqFragData, EvqFragData,
EvqFragDepth, EvqFragDepth,
// built-ins written by the shader_framebuffer_fetch extension(s)
EvqLastFragColor,
EvqLastFragData,
// GLSL ES 3.0 vertex output and fragment input // GLSL ES 3.0 vertex output and fragment input
EvqSmooth, // Incomplete qualifier, smooth is the default EvqSmooth, // Incomplete qualifier, smooth is the default
EvqFlat, // Incomplete qualifier EvqFlat, // Incomplete qualifier
...@@ -396,6 +400,8 @@ inline const char* getQualifierString(TQualifier q) ...@@ -396,6 +400,8 @@ inline const char* getQualifierString(TQualifier q)
case EvqSmoothIn: return "smooth in"; break; case EvqSmoothIn: return "smooth in"; break;
case EvqCentroidIn: return "centroid in"; break; case EvqCentroidIn: return "centroid in"; break;
case EvqFlatIn: return "flat in"; break; case EvqFlatIn: return "flat in"; break;
case EvqLastFragColor: return "LastFragColor"; break;
case EvqLastFragData: return "LastFragData"; break;
default: return "unknown qualifier"; default: return "unknown qualifier";
} }
} }
......
...@@ -392,6 +392,9 @@ void TCompiler::setResourceString() ...@@ -392,6 +392,9 @@ void TCompiler::setResourceString()
<< ":MaxCallStackDepth:" << compileResources.MaxCallStackDepth << ":MaxCallStackDepth:" << compileResources.MaxCallStackDepth
<< ":EXT_frag_depth:" << compileResources.EXT_frag_depth << ":EXT_frag_depth:" << compileResources.EXT_frag_depth
<< ":EXT_shader_texture_lod:" << compileResources.EXT_shader_texture_lod << ":EXT_shader_texture_lod:" << compileResources.EXT_shader_texture_lod
<< ":EXT_shader_framebuffer_fetch:" << compileResources.EXT_shader_framebuffer_fetch
<< ":NV_shader_framebuffer_fetch:" << compileResources.NV_shader_framebuffer_fetch
<< ":ARM_shader_framebuffer_fetch:" << compileResources.ARM_shader_framebuffer_fetch
<< ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors << ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors
<< ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors << ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors
<< ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset << ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset
......
...@@ -620,6 +620,19 @@ void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec, ...@@ -620,6 +620,19 @@ void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec,
symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragDepthEXT"), TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium, EvqFragDepth, 1))); symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragDepthEXT"), TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium, EvqFragDepth, 1)));
symbolTable.relateToExtension(ESSL1_BUILTINS, "gl_FragDepthEXT", "GL_EXT_frag_depth"); symbolTable.relateToExtension(ESSL1_BUILTINS, "gl_FragDepthEXT", "GL_EXT_frag_depth");
} }
if (resources.EXT_shader_framebuffer_fetch)
{
symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_LastFragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqLastFragData, 4)));
}
else if (resources.NV_shader_framebuffer_fetch)
{
symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_LastFragColor"), TType(EbtFloat, EbpMedium, EvqLastFragColor, 4)));
symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_LastFragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqLastFragData, 4)));
}
else if (resources.ARM_shader_framebuffer_fetch)
{
symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_LastFragColorARM"), TType(EbtFloat, EbpMedium, EvqLastFragColor, 4)));
}
} else { } else {
symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("css_MixColor"), TType(EbtFloat, EbpMedium, EvqGlobal, 4))); symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("css_MixColor"), TType(EbtFloat, EbpMedium, EvqGlobal, 4)));
symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("css_ColorMatrix"), TType(EbtFloat, EbpMedium, EvqGlobal, 4, 4))); symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("css_ColorMatrix"), TType(EbtFloat, EbpMedium, EvqGlobal, 4, 4)));
...@@ -714,6 +727,14 @@ void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec, ...@@ -714,6 +727,14 @@ void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec,
symbolTable.relateToExtension(ESSL1_BUILTINS, "texture2DProjLodEXT", "GL_EXT_shader_texture_lod"); symbolTable.relateToExtension(ESSL1_BUILTINS, "texture2DProjLodEXT", "GL_EXT_shader_texture_lod");
symbolTable.relateToExtension(ESSL1_BUILTINS, "textureCubeLodEXT", "GL_EXT_shader_texture_lod"); symbolTable.relateToExtension(ESSL1_BUILTINS, "textureCubeLodEXT", "GL_EXT_shader_texture_lod");
} }
if (resources.NV_shader_framebuffer_fetch)
{
symbolTable.relateToExtension(ESSL1_BUILTINS, "gl_LastFragColor", "GL_NV_shader_framebuffer_fetch");
}
else if (resources.ARM_shader_framebuffer_fetch)
{
symbolTable.relateToExtension(ESSL1_BUILTINS, "gl_LastFragColorARM", "GL_ARM_shader_framebuffer_fetch");
}
break; break;
default: break; default: break;
} }
...@@ -737,6 +758,22 @@ void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec, ...@@ -737,6 +758,22 @@ void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec,
TType fragData(EbtFloat, EbpMedium, EvqFragData, 4, 1, true); TType fragData(EbtFloat, EbpMedium, EvqFragData, 4, 1, true);
fragData.setArraySize(resources.MaxDrawBuffers); fragData.setArraySize(resources.MaxDrawBuffers);
symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragData"), fragData)); symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragData"), fragData));
if (resources.EXT_shader_framebuffer_fetch || resources.NV_shader_framebuffer_fetch) {
// Set up gl_LastFragData. The array size.
TType lastFragData(EbtFloat, EbpMedium, EvqLastFragData, 4, 1, true);
lastFragData.setArraySize(resources.MaxDrawBuffers);
symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_LastFragData"), lastFragData));
if (resources.EXT_shader_framebuffer_fetch)
{
symbolTable.relateToExtension(ESSL1_BUILTINS, "gl_LastFragData", "GL_EXT_shader_framebuffer_fetch");
}
else if (resources.NV_shader_framebuffer_fetch)
{
symbolTable.relateToExtension(ESSL1_BUILTINS, "gl_LastFragData", "GL_NV_shader_framebuffer_fetch");
}
}
} }
break; break;
default: break; default: break;
...@@ -758,4 +795,10 @@ void InitExtensionBehavior(const ShBuiltInResources& resources, ...@@ -758,4 +795,10 @@ void InitExtensionBehavior(const ShBuiltInResources& resources,
extBehavior["GL_EXT_frag_depth"] = EBhUndefined; extBehavior["GL_EXT_frag_depth"] = EBhUndefined;
if (resources.EXT_shader_texture_lod) if (resources.EXT_shader_texture_lod)
extBehavior["GL_EXT_shader_texture_lod"] = EBhUndefined; extBehavior["GL_EXT_shader_texture_lod"] = EBhUndefined;
if (resources.EXT_shader_framebuffer_fetch)
extBehavior["GL_EXT_shader_framebuffer_fetch"] = EBhUndefined;
if (resources.NV_shader_framebuffer_fetch)
extBehavior["GL_NV_shader_framebuffer_fetch"] = EBhUndefined;
if (resources.ARM_shader_framebuffer_fetch)
extBehavior["GL_ARM_shader_framebuffer_fetch"] = EBhUndefined;
} }
...@@ -796,9 +796,24 @@ bool TParseContext::arrayErrorCheck(const TSourceLoc& line, const TString& ident ...@@ -796,9 +796,24 @@ bool TParseContext::arrayErrorCheck(const TSourceLoc& line, const TString& ident
bool sameScope = false; bool sameScope = false;
TSymbol* symbol = symbolTable.find(identifier, 0, &builtIn, &sameScope); TSymbol* symbol = symbolTable.find(identifier, 0, &builtIn, &sameScope);
if (symbol == 0 || !sameScope) { if (symbol == 0 || !sameScope) {
if (reservedErrorCheck(line, identifier)) bool needsReservedErrorCheck = true;
return true;
// gl_LastFragData may be redeclared with a new precision qualifier
if (identifier.compare(0, 15, "gl_LastFragData") == 0) {
if (type.arraySize == static_cast<const TVariable*>(symbolTable.findBuiltIn("gl_MaxDrawBuffers", shaderVersion))->getConstPointer()->getIConst()) {
if (TSymbol* builtInSymbol = symbolTable.findBuiltIn(identifier, shaderVersion)) {
needsReservedErrorCheck = extensionErrorCheck(line, builtInSymbol->getExtension());
}
} else {
error(line, "redeclaration of array with size != gl_MaxDrawBuffers", identifier.c_str());
return true;
}
}
if (needsReservedErrorCheck)
if (reservedErrorCheck(line, identifier))
return true;
variable = new TVariable(&identifier, TType(type)); variable = new TVariable(&identifier, TType(type));
if (type.arraySize) if (type.arraySize)
......
...@@ -154,6 +154,9 @@ void ShInitBuiltInResources(ShBuiltInResources* resources) ...@@ -154,6 +154,9 @@ void ShInitBuiltInResources(ShBuiltInResources* resources)
resources->EXT_frag_depth = 0; resources->EXT_frag_depth = 0;
resources->EXT_shader_texture_lod = 0; resources->EXT_shader_texture_lod = 0;
resources->WEBGL_debug_shader_precision = 0; resources->WEBGL_debug_shader_precision = 0;
resources->EXT_shader_framebuffer_fetch = 0;
resources->NV_shader_framebuffer_fetch = 0;
resources->ARM_shader_framebuffer_fetch = 0;
resources->NV_draw_buffers = 0; resources->NV_draw_buffers = 0;
......
...@@ -50,7 +50,10 @@ void TranslatorESSL::writeExtensionBehavior() { ...@@ -50,7 +50,10 @@ void TranslatorESSL::writeExtensionBehavior() {
for (TExtensionBehavior::const_iterator iter = extensionBehavior.begin(); for (TExtensionBehavior::const_iterator iter = extensionBehavior.begin();
iter != extensionBehavior.end(); ++iter) { iter != extensionBehavior.end(); ++iter) {
if (iter->second != EBhUndefined) { if (iter->second != EBhUndefined) {
if (getResources().NV_draw_buffers && iter->first == "GL_EXT_draw_buffers") { if (getResources().NV_shader_framebuffer_fetch && iter->first == "GL_EXT_shader_framebuffer_fetch") {
sink << "#extension GL_NV_shader_framebuffer_fetch : "
<< getBehaviorString(iter->second) << "\n";
} else if (getResources().NV_draw_buffers && iter->first == "GL_EXT_draw_buffers") {
sink << "#extension GL_NV_draw_buffers : " sink << "#extension GL_NV_draw_buffers : "
<< getBehaviorString(iter->second) << "\n"; << getBehaviorString(iter->second) << "\n";
} else { } else {
......
...@@ -144,6 +144,7 @@ CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs, ...@@ -144,6 +144,7 @@ CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs,
mFragCoordAdded(false), mFragCoordAdded(false),
mPositionAdded(false), mPositionAdded(false),
mPointSizeAdded(false), mPointSizeAdded(false),
mLastFragDataAdded(false),
mHashFunction(hashFunction), mHashFunction(hashFunction),
mSymbolTable(symbolTable) mSymbolTable(symbolTable)
{ {
...@@ -281,6 +282,22 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol) ...@@ -281,6 +282,22 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
mPointSizeAdded = true; mPointSizeAdded = true;
} }
return; return;
case EvqLastFragData:
if (!mLastFragDataAdded)
{
Varying info;
const char kName[] = "gl_LastFragData";
info.name = kName;
info.mappedName = kName;
info.type = GL_FLOAT_VEC4;
info.arraySize = static_cast<const TVariable*>(mSymbolTable.findBuiltIn("gl_MaxDrawBuffers", 100))->getConstPointer()->getIConst();
info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
info.staticUse = true;
info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
mVaryings->push_back(info);
mLastFragDataAdded = true;
}
return;
default: default:
break; break;
} }
......
...@@ -53,6 +53,7 @@ class CollectVariables : public TIntermTraverser ...@@ -53,6 +53,7 @@ class CollectVariables : public TIntermTraverser
bool mPositionAdded; bool mPositionAdded;
bool mPointSizeAdded; bool mPointSizeAdded;
bool mLastFragDataAdded;
ShHashFunction64 mHashFunction; ShHashFunction64 mHashFunction;
......
...@@ -119,6 +119,9 @@ Extensions::Extensions() ...@@ -119,6 +119,9 @@ Extensions::Extensions()
packReverseRowOrder(false), packReverseRowOrder(false),
standardDerivatives(false), standardDerivatives(false),
shaderTextureLOD(false), shaderTextureLOD(false),
shaderFramebufferFetch(false),
ARMshaderFramebufferFetch(false),
NVshaderFramebufferFetch(false),
fragDepth(false), fragDepth(false),
textureUsage(false), textureUsage(false),
translatedShaderSource(false), translatedShaderSource(false),
...@@ -173,6 +176,9 @@ std::vector<std::string> Extensions::getStrings() const ...@@ -173,6 +176,9 @@ std::vector<std::string> Extensions::getStrings() const
InsertExtensionString("GL_ANGLE_pack_reverse_row_order", packReverseRowOrder, &extensionStrings); InsertExtensionString("GL_ANGLE_pack_reverse_row_order", packReverseRowOrder, &extensionStrings);
InsertExtensionString("GL_OES_standard_derivatives", standardDerivatives, &extensionStrings); InsertExtensionString("GL_OES_standard_derivatives", standardDerivatives, &extensionStrings);
InsertExtensionString("GL_EXT_shader_texture_lod", shaderTextureLOD, &extensionStrings); InsertExtensionString("GL_EXT_shader_texture_lod", shaderTextureLOD, &extensionStrings);
InsertExtensionString("GL_NV_shader_framebuffer_fetch", NVshaderFramebufferFetch, &extensionStrings);
InsertExtensionString("GL_ARM_shader_framebuffer_fetch", ARMshaderFramebufferFetch,&extensionStrings);
InsertExtensionString("GL_EXT_shader_framebuffer_fetch", shaderFramebufferFetch, &extensionStrings);
InsertExtensionString("GL_EXT_frag_depth", fragDepth, &extensionStrings); InsertExtensionString("GL_EXT_frag_depth", fragDepth, &extensionStrings);
InsertExtensionString("GL_ANGLE_texture_usage", textureUsage, &extensionStrings); InsertExtensionString("GL_ANGLE_texture_usage", textureUsage, &extensionStrings);
InsertExtensionString("GL_ANGLE_translated_shader_source", translatedShaderSource, &extensionStrings); InsertExtensionString("GL_ANGLE_translated_shader_source", translatedShaderSource, &extensionStrings);
......
...@@ -192,6 +192,15 @@ struct ANGLE_EXPORT Extensions ...@@ -192,6 +192,15 @@ struct ANGLE_EXPORT Extensions
// GL_EXT_shader_texture_lod // GL_EXT_shader_texture_lod
bool shaderTextureLOD; bool shaderTextureLOD;
// GL_EXT_shader_framebuffer_fetch
bool shaderFramebufferFetch;
// GL_ARM_shader_framebuffer_fetch
bool ARMshaderFramebufferFetch;
// GL_NV_shader_framebuffer_fetch
bool NVshaderFramebufferFetch;
// GL_EXT_frag_depth // GL_EXT_frag_depth
bool fragDepth; bool fragDepth;
......
...@@ -125,6 +125,9 @@ void ShaderD3D::initializeCompiler(const gl::Data &data) ...@@ -125,6 +125,9 @@ void ShaderD3D::initializeCompiler(const gl::Data &data)
resources.OES_standard_derivatives = extensions.standardDerivatives; resources.OES_standard_derivatives = extensions.standardDerivatives;
resources.EXT_draw_buffers = extensions.drawBuffers; resources.EXT_draw_buffers = extensions.drawBuffers;
resources.EXT_shader_texture_lod = 1; resources.EXT_shader_texture_lod = 1;
resources.EXT_shader_framebuffer_fetch = 0;
resources.NV_shader_framebuffer_fetch = 0;
resources.ARM_shader_framebuffer_fetch = 0;
// 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