Commit a5527071 by Andrei Volykhin Committed by Commit Bot

Add support for EXT_YUV_target

Add new sampler type "__samplerExternal2DY2YEXT" to sample a YUV texture image and output color value without any color conversion, new additional type to specify color space standard formula and built-in functions for yuv to rgb transformation. Change-Id: I1780650fe84cd75191c1ca1e4118e89d585bfd92 Reviewed-on: https://chromium-review.googlesource.com/454697Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Commit-Queue: Corentin Wallez <cwallez@chromium.org>
parent c1ebf5bd
......@@ -47,3 +47,4 @@ Sebastian Bergstein
James Ross-Gowan
Nickolay Artamonov
Ihsan Akmal
Andrei Volykhin
......@@ -95,6 +95,7 @@ Tibor den Ouden
Régis Fénéon
Sebastian Bergstein
James Ross-Gowan
Andrei Volykhin
Microsoft Corporation
Cooper Partin
......
......@@ -25,7 +25,7 @@
// Version number for shader translation API.
// It is incremented every time the API changes.
#define ANGLE_SH_VERSION 173
#define ANGLE_SH_VERSION 174
enum ShShaderSpec
{
......@@ -264,6 +264,7 @@ struct ShBuiltInResources
int NV_shader_framebuffer_fetch;
int ARM_shader_framebuffer_fetch;
int OVR_multiview;
int EXT_YUV_target;
// 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
......
......@@ -209,6 +209,7 @@ int main(int argc, char *argv[])
resources.OVR_multiview = 1;
compileOptions |= SH_TRANSLATE_VIEWID_OVR_TO_UNIFORM;
break;
case 'y': resources.EXT_YUV_target = 1; break;
default: failCode = EFailUsage;
}
// clang-format on
......@@ -346,7 +347,8 @@ void usage()
" -x=f : enable EXT_shader_framebuffer_fetch\n"
" -x=n : enable NV_shader_framebuffer_fetch\n"
" -x=a : enable ARM_shader_framebuffer_fetch\n"
" -x=m : enable OVR_multiview\n");
" -x=m : enable OVR_multiview\n"
" -x=y : enable YUV_target\n");
// clang-format on
}
......@@ -526,6 +528,9 @@ void PrintVariable(const std::string &prefix, size_t index, const sh::ShaderVari
break;
case GL_SAMPLER_EXTERNAL_OES: typeName = "GL_SAMPLER_EXTERNAL_OES"; break;
case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
typeName = "GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT";
break;
default: typeName = "UNKNOWN"; break;
}
......
......@@ -150,6 +150,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
resources.EXT_shader_framebuffer_fetch = 1;
resources.NV_shader_framebuffer_fetch = 1;
resources.ARM_shader_framebuffer_fetch = 1;
resources.EXT_YUV_target = 1;
resources.MaxDualSourceDrawBuffers = 1;
if (!translator->Init(resources))
......
......@@ -65,12 +65,14 @@ enum TBasicType
EbtIVec, // non type: represents ivec2, ivec3, and ivec4
EbtUVec, // non type: represents uvec2, uvec3, and uvec4
EbtBVec, // non type: represents bvec2, bvec3, and bvec4
EbtYuvCscStandardEXT, // Only valid if EXT_YUV_target exists.
EbtGuardSamplerBegin, // non type: see implementation of IsSampler()
EbtSampler2D,
EbtSampler3D,
EbtSamplerCube,
EbtSampler2DArray,
EbtSamplerExternalOES, // Only valid if OES_EGL_image_external exists.
EbtSamplerExternal2DY2YEXT, // Only valid if GL_EXT_YUV_target exists.
EbtSampler2DRect, // Only valid if GL_ARB_texture_rectangle exists.
EbtSampler2DMS,
EbtISampler2D,
......@@ -221,6 +223,7 @@ inline bool IsIntegerSampler(TBasicType type)
case EbtSampler3D:
case EbtSamplerCube:
case EbtSamplerExternalOES:
case EbtSamplerExternal2DY2YEXT:
case EbtSampler2DRect:
case EbtSampler2DArray:
case EbtSampler2DShadow:
......@@ -310,6 +313,7 @@ inline bool IsSampler2D(TBasicType type)
case EbtUSampler2DArray:
case EbtSampler2DRect:
case EbtSamplerExternalOES:
case EbtSamplerExternal2DY2YEXT:
case EbtSampler2DShadow:
case EbtSampler2DArrayShadow:
case EbtSampler2DMS:
......@@ -343,6 +347,7 @@ inline bool IsSamplerCube(TBasicType type)
case EbtSampler2D:
case EbtSampler3D:
case EbtSamplerExternalOES:
case EbtSamplerExternal2DY2YEXT:
case EbtSampler2DRect:
case EbtSampler2DArray:
case EbtSampler2DMS:
......@@ -375,6 +380,7 @@ inline bool IsSampler3D(TBasicType type)
case EbtSampler2D:
case EbtSamplerCube:
case EbtSamplerExternalOES:
case EbtSamplerExternal2DY2YEXT:
case EbtSampler2DRect:
case EbtSampler2DArray:
case EbtSampler2DMS:
......@@ -411,6 +417,7 @@ inline bool IsSamplerArray(TBasicType type)
case EbtUSampler2D:
case EbtSampler2DRect:
case EbtSamplerExternalOES:
case EbtSamplerExternal2DY2YEXT:
case EbtSampler3D:
case EbtISampler3D:
case EbtUSampler3D:
......@@ -452,6 +459,7 @@ inline bool IsShadowSampler(TBasicType type)
case EbtSampler3D:
case EbtSamplerCube:
case EbtSamplerExternalOES:
case EbtSamplerExternal2DY2YEXT:
case EbtSampler2DRect:
case EbtSampler2DArray:
case EbtSampler2DMS:
......@@ -599,6 +607,14 @@ enum TLayoutBlockStorage
EbsStd140
};
enum TYuvCscStandardEXT
{
EycsUndefined,
EycsItu601,
EycsItu601FullRange,
EycsItu709
};
struct TLayoutQualifier
{
int location;
......@@ -617,6 +633,9 @@ struct TLayoutQualifier
// OVR_multiview num_views.
int numViews;
// EXT_YUV_target yuv layout qualifier.
bool yuv;
static TLayoutQualifier create()
{
TLayoutQualifier layoutQualifier;
......@@ -629,6 +648,7 @@ struct TLayoutQualifier
layoutQualifier.localSize.fill(-1);
layoutQualifier.binding = -1;
layoutQualifier.numViews = -1;
layoutQualifier.yuv = false;
layoutQualifier.imageInternalFormat = EiifUnspecified;
return layoutQualifier;
......@@ -636,7 +656,7 @@ struct TLayoutQualifier
bool isEmpty() const
{
return location == -1 && binding == -1 && numViews == -1 &&
return location == -1 && binding == -1 && numViews == -1 && yuv == false &&
matrixPacking == EmpUnspecified && blockStorage == EbsUnspecified &&
!localSize.isAnyValueSet() && imageInternalFormat == EiifUnspecified;
}
......@@ -649,9 +669,9 @@ struct TLayoutQualifier
(location != -1 || binding != -1 || matrixPacking != EmpUnspecified ||
blockStorage != EbsUnspecified || imageInternalFormat != EiifUnspecified);
// we can have either the work group size specified, or number of views, or the other layout
// qualifiers.
return (workSizeSpecified ? 1 : 0) + (numViewsSet ? 1 : 0) +
// we can have either the work group size specified, or number of views,
// or yuv layout qualifier, or the other layout qualifiers.
return (workSizeSpecified ? 1 : 0) + (numViewsSet ? 1 : 0) + (yuv ? 1 : 0) +
(otherLayoutQualifiersSpecified ? 1 : 0) <=
1;
}
......@@ -842,6 +862,33 @@ inline const char *getImageInternalFormatString(TLayoutImageInternalFormat iifq)
}
}
inline TYuvCscStandardEXT getYuvCscStandardEXT(const std::string &str)
{
if (str == "itu_601")
return EycsItu601;
else if (str == "itu_601_full_range")
return EycsItu601FullRange;
else if (str == "itu_709")
return EycsItu709;
return EycsUndefined;
}
inline const char *getYuvCscStandardEXTString(TYuvCscStandardEXT ycsq)
{
switch (ycsq)
{
case EycsItu601:
return "itu_601";
case EycsItu601FullRange:
return "itu_601_full_range";
case EycsItu709:
return "itu_709";
default:
UNREACHABLE();
return "unknown color space conversion standard";
}
}
} // namespace sh
#endif // COMPILER_TRANSLATOR_BASETYPES_H_
......@@ -571,6 +571,8 @@ bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources)
initSamplerDefaultPrecision(EbtSamplerCube);
// SamplerExternalOES is specified in the extension to have default precision.
initSamplerDefaultPrecision(EbtSamplerExternalOES);
// SamplerExternal2DY2YEXT is specified in the extension to have default precision.
initSamplerDefaultPrecision(EbtSamplerExternal2DY2YEXT);
// It isn't specified whether Sampler2DRect has default precision.
initSamplerDefaultPrecision(EbtSampler2DRect);
......@@ -618,6 +620,7 @@ void TCompiler::setResourceString()
<< ":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
<< ":EXT_YUV_target:" << compileResources.EXT_YUV_target
<< ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors
<< ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors
<< ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset
......
......@@ -198,6 +198,11 @@ bool TConstantUnion::operator==(const bool b) const
return b == bConst;
}
bool TConstantUnion::operator==(const TYuvCscStandardEXT s) const
{
return s == yuvCscStandardEXTConst;
}
bool TConstantUnion::operator==(const TConstantUnion &constant) const
{
if (constant.type != type)
......@@ -213,6 +218,8 @@ bool TConstantUnion::operator==(const TConstantUnion &constant) const
return constant.fConst == fConst;
case EbtBool:
return constant.bConst == bConst;
case EbtYuvCscStandardEXT:
return constant.yuvCscStandardEXTConst == yuvCscStandardEXTConst;
default:
return false;
}
......@@ -238,6 +245,11 @@ bool TConstantUnion::operator!=(const bool b) const
return !operator==(b);
}
bool TConstantUnion::operator!=(const TYuvCscStandardEXT s) const
{
return !operator==(s);
}
bool TConstantUnion::operator!=(const TConstantUnion &constant) const
{
return !operator==(constant);
......
......@@ -46,20 +46,29 @@ class TConstantUnion
type = EbtBool;
}
void setYuvCscStandardEXTConst(TYuvCscStandardEXT s)
{
yuvCscStandardEXTConst = s;
type = EbtYuvCscStandardEXT;
}
int getIConst() const { return iConst; }
unsigned int getUConst() const { return uConst; }
float getFConst() const { return fConst; }
bool getBConst() const { return bConst; }
TYuvCscStandardEXT getYuvCscStandardEXTConst() const { return yuvCscStandardEXTConst; }
bool operator==(const int i) const;
bool operator==(const unsigned int u) const;
bool operator==(const float f) const;
bool operator==(const bool b) const;
bool operator==(const TYuvCscStandardEXT s) const;
bool operator==(const TConstantUnion &constant) const;
bool operator!=(const int i) const;
bool operator!=(const unsigned int u) const;
bool operator!=(const float f) const;
bool operator!=(const bool b) const;
bool operator!=(const TYuvCscStandardEXT s) const;
bool operator!=(const TConstantUnion &constant) const;
bool operator>(const TConstantUnion &constant) const;
bool operator<(const TConstantUnion &constant) const;
......@@ -97,6 +106,7 @@ class TConstantUnion
unsigned int uConst; // used for uvec, scalar uints
bool bConst; // used for bvec, scalar bools
float fConst; // used for vec, mat, scalar floats
TYuvCscStandardEXT yuvCscStandardEXTConst;
};
TBasicType type;
......
......@@ -391,6 +391,25 @@ void InsertBuiltInFunctions(sh::GLenum type,
float4);
}
if (resources.EXT_YUV_target)
{
const TType *samplerExternal2DY2YEXT = TCache::getType(EbtSamplerExternal2DY2YEXT);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, "GL_EXT_YUV_target", float4, "texture",
samplerExternal2DY2YEXT, float2);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, "GL_EXT_YUV_target", float4, "textureProj",
samplerExternal2DY2YEXT, float3);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, "GL_EXT_YUV_target", float4, "textureProj",
samplerExternal2DY2YEXT, float4);
const TType *yuvCscStandardEXT = TCache::getType(EbtYuvCscStandardEXT);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, "GL_EXT_YUV_target", float3, "rgb_2_yuv", float3,
yuvCscStandardEXT);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, "GL_EXT_YUV_target", float3, "yuv_2_rgb", float3,
yuvCscStandardEXT);
}
if (type == GL_FRAGMENT_SHADER)
{
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2D, float2, float1);
......@@ -413,6 +432,18 @@ void InsertBuiltInFunctions(sh::GLenum type,
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES,
float4, float1);
}
if (resources.EXT_YUV_target)
{
const TType *samplerExternal2DY2YEXT = TCache::getType(EbtSamplerExternal2DY2YEXT);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, "GL_EXT_YUV_target", float4, "texture",
samplerExternal2DY2YEXT, float2, float1);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, "GL_EXT_YUV_target", float4, "textureProj",
samplerExternal2DY2YEXT, float3, float1);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, "GL_EXT_YUV_target", float4, "textureProj",
samplerExternal2DY2YEXT, float4, float1);
}
}
const TType *sampler2DShadow = TCache::getType(EbtSampler2DShadow);
......@@ -452,6 +483,14 @@ void InsertBuiltInFunctions(sh::GLenum type,
symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", samplerExternalOES, int1);
}
if (resources.EXT_YUV_target)
{
const TType *samplerExternal2DY2YEXT = TCache::getType(EbtSamplerExternal2DY2YEXT);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, "GL_EXT_YUV_target", int2, "textureSize",
samplerExternal2DY2YEXT, int1);
}
if (type == GL_FRAGMENT_SHADER)
{
symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpDFdx, genType, genType);
......@@ -532,6 +571,14 @@ void InsertBuiltInFunctions(sh::GLenum type,
int1);
}
if (resources.EXT_YUV_target)
{
const TType *samplerExternal2DY2YEXT = TCache::getType(EbtSamplerExternal2DY2YEXT);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, "GL_EXT_YUV_target", float4, "texelFetch",
samplerExternal2DY2YEXT, int2, int1);
}
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler2D, int2, int1,
int2);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler3D, int3, int1,
......@@ -906,6 +953,10 @@ void InitExtensionBehavior(const ShBuiltInResources &resources, TExtensionBehavi
extBehavior["GL_OVR_multiview"] = EBhUndefined;
extBehavior["GL_OVR_multiview2"] = EBhUndefined;
}
if (resources.EXT_YUV_target)
{
extBehavior["GL_EXT_YUV_target"] = EBhUndefined;
}
}
void ResetExtensionBehavior(TExtensionBehavior &extBehavior)
......
......@@ -73,6 +73,11 @@ bool NeedsToWriteLayoutQualifier(const TType &type)
return true;
}
if (type.getQualifier() == EvqFragmentOut && layoutQualifier.yuv == true)
{
return true;
}
if (IsOpaqueType(type.getBasicType()) && layoutQualifier.binding != -1)
{
return true;
......@@ -214,6 +219,14 @@ void TOutputGLSLBase::writeLayoutQualifier(const TType &type)
}
}
if (type.getQualifier() == EvqFragmentOut)
{
if (layoutQualifier.yuv == true)
{
out << listItemPrefix << "yuv";
}
}
if (IsOpaqueType(type.getBasicType()))
{
if (layoutQualifier.binding >= 0)
......@@ -414,6 +427,9 @@ const TConstantUnion *TOutputGLSLBase::writeConstantUnion(const TType &type,
case EbtBool:
out << pConstUnion->getBConst();
break;
case EbtYuvCscStandardEXT:
out << getYuvCscStandardEXTString(pConstUnion->getYuvCscStandardEXTConst());
break;
default:
UNREACHABLE();
}
......
......@@ -1188,6 +1188,15 @@ void TParseContext::singleDeclarationErrorCheck(const TPublicType &publicType,
return;
}
if ((publicType.qualifier != EvqTemporary && publicType.qualifier != EvqGlobal &&
publicType.qualifier != EvqConst) &&
publicType.getBasicType() == EbtYuvCscStandardEXT)
{
error(identifierLocation, "cannot be used with a yuvCscStandardEXT",
getQualifierString(publicType.qualifier));
return;
}
// check for layout qualifier issues
const TLayoutQualifier layoutQualifier = publicType.layoutQualifier;
......@@ -1226,6 +1235,19 @@ void TParseContext::singleDeclarationErrorCheck(const TPublicType &publicType,
checkLocationIsNotSpecified(identifierLocation, publicType.layoutQualifier);
}
if (publicType.qualifier == EvqFragmentOut)
{
if (layoutQualifier.location != -1 && layoutQualifier.yuv == true)
{
error(identifierLocation, "invalid layout qualifier combination", "yuv");
return;
}
}
else
{
checkYuvIsNotSpecified(identifierLocation, layoutQualifier.yuv);
}
if (IsImage(publicType.getBasicType()))
{
......@@ -1402,6 +1424,14 @@ void TParseContext::checkUniformLocationInRange(const TSourceLoc &location,
}
}
void TParseContext::checkYuvIsNotSpecified(const TSourceLoc &location, bool yuv)
{
if (yuv != false)
{
error(location, "invalid layout qualifier: only valid on program outputs", "yuv");
}
}
void TParseContext::functionCallLValueErrorCheck(const TFunction *fnCandidate,
TIntermAggregate *fnCall)
{
......@@ -2340,6 +2370,8 @@ void TParseContext::parseGlobalLayoutQualifier(const TTypeQualifierBuilder &type
checkInternalFormatIsNotSpecified(typeQualifier.line, layoutQualifier.imageInternalFormat);
checkYuvIsNotSpecified(typeQualifier.line, layoutQualifier.yuv);
if (typeQualifier.qualifier == EvqComputeIn)
{
if (mComputeShaderLocalSizeDeclared &&
......@@ -2818,6 +2850,8 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
// TODO(oetuaho): Remove this and support binding for blocks.
checkBindingIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.binding);
checkYuvIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.yuv);
TLayoutQualifier blockLayoutQualifier = typeQualifier.layoutQualifier;
checkLocationIsNotSpecified(typeQualifier.line, blockLayoutQualifier);
......@@ -3304,6 +3338,11 @@ TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierTyp
error(qualifierTypeLine, "invalid layout qualifier: location requires an argument",
qualifierType.c_str());
}
else if (qualifierType == "yuv" && isExtensionEnabled("GL_EXT_YUV_target") &&
mShaderType == GL_FRAGMENT_SHADER)
{
qualifier.yuv = true;
}
else if (qualifierType == "rgba32f")
{
checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
......
......@@ -399,6 +399,8 @@ class TParseContext : angle::NonCopyable
int objectLocationCount,
const TLayoutQualifier &layoutQualifier);
void checkYuvIsNotSpecified(const TSourceLoc &location, bool yuv);
TIntermTyped *addBinaryMathInternal(TOperator op,
TIntermTyped *left,
TIntermTyped *right,
......
......@@ -560,6 +560,10 @@ TLayoutQualifier JoinLayoutQualifiers(TLayoutQualifier leftQualifier,
joinedQualifier.location = rightQualifier.location;
++joinedQualifier.locationsSpecified;
}
if (rightQualifier.yuv != false)
{
joinedQualifier.yuv = rightQualifier.yuv;
}
if (rightQualifier.binding != -1)
{
joinedQualifier.binding = rightQualifier.binding;
......
......@@ -163,6 +163,7 @@ void InitBuiltInResources(ShBuiltInResources *resources)
resources->NV_shader_framebuffer_fetch = 0;
resources->ARM_shader_framebuffer_fetch = 0;
resources->OVR_multiview = 0;
resources->EXT_YUV_target = 0;
resources->NV_draw_buffers = 0;
......
......@@ -33,6 +33,8 @@ const char *getBasicString(TBasicType t)
return "uint";
case EbtBool:
return "bool";
case EbtYuvCscStandardEXT:
return "yuvCscStandardEXT";
case EbtSampler2D:
return "sampler2D";
case EbtSampler3D:
......@@ -41,6 +43,8 @@ const char *getBasicString(TBasicType t)
return "samplerCube";
case EbtSamplerExternalOES:
return "samplerExternalOES";
case EbtSamplerExternal2DY2YEXT:
return "__samplerExternal2DY2YEXT";
case EbtSampler2DRect:
return "sampler2DRect";
case EbtSampler2DArray:
......@@ -292,6 +296,9 @@ TString TType::buildMangledName() const
case EbtBool:
mangledName += 'b';
break;
case EbtYuvCscStandardEXT:
mangledName += "ycs";
break;
case EbtSampler2D:
mangledName += "s2";
break;
......@@ -307,6 +314,9 @@ TString TType::buildMangledName() const
case EbtSamplerExternalOES:
mangledName += "sext";
break;
case EbtSamplerExternal2DY2YEXT:
mangledName += "sext2y2y";
break;
case EbtSampler2DRect:
mangledName += "s2r";
break;
......
......@@ -25,7 +25,8 @@ ValidateOutputs::ValidateOutputs(const TExtensionBehavior &extBehavior, int maxD
: TIntermTraverser(true, false, false),
mMaxDrawBuffers(maxDrawBuffers),
mAllowUnspecifiedOutputLocationResolution(
IsExtensionEnabled(extBehavior, "GL_EXT_blend_func_extended"))
IsExtensionEnabled(extBehavior, "GL_EXT_blend_func_extended")),
mUsesFragDepth(false)
{
}
......@@ -41,15 +42,23 @@ void ValidateOutputs::visitSymbol(TIntermSymbol *symbol)
if (qualifier == EvqFragmentOut)
{
if (symbol->getType().getLayoutQualifier().location == -1)
if (symbol->getType().getLayoutQualifier().location != -1)
{
mUnspecifiedLocationOutputs.push_back(symbol);
mOutputs.push_back(symbol);
}
else if (symbol->getType().getLayoutQualifier().yuv == true)
{
mYuvOutputs.push_back(symbol);
}
else
{
mOutputs.push_back(symbol);
mUnspecifiedLocationOutputs.push_back(symbol);
}
}
else if (qualifier == EvqFragDepth || qualifier == EvqFragDepthEXT)
{
mUsesFragDepth = true;
}
}
void ValidateOutputs::validate(TDiagnostics *diagnostics) const
......@@ -106,6 +115,18 @@ void ValidateOutputs::validate(TDiagnostics *diagnostics) const
diagnostics);
}
}
if (!mYuvOutputs.empty() && (mYuvOutputs.size() > 1 || mUsesFragDepth || !mOutputs.empty() ||
!mUnspecifiedLocationOutputs.empty()))
{
for (const auto &symbol : mYuvOutputs)
{
error(*symbol,
"not allowed to specify yuv qualifier when using depth or multiple color "
"fragment outputs",
diagnostics);
}
}
}
} // namespace sh
......@@ -29,10 +29,12 @@ class ValidateOutputs : public TIntermTraverser
private:
int mMaxDrawBuffers;
bool mAllowUnspecifiedOutputLocationResolution;
bool mUsesFragDepth;
typedef std::vector<TIntermSymbol *> OutputVector;
OutputVector mOutputs;
OutputVector mUnspecifiedLocationOutputs;
OutputVector mYuvOutputs;
std::set<std::string> mVisitedSymbols;
};
......
......@@ -79,10 +79,12 @@ static int ES2_ident_ES3_keyword(TParseContext *context, int token);
static int ES2_ident_ES3_reserved_ES3_1_keyword(TParseContext *context, int token);
static int ES2_and_ES3_reserved_ES3_1_keyword(TParseContext *context, int token);
static int ES2_and_ES3_ident_ES3_1_keyword(TParseContext *context, int token);
static int ES3_extension_keyword_else_ident(TParseContext *context, const char *extension, int token);
static int uint_constant(TParseContext *context);
static int int_constant(TParseContext *context);
static int float_constant(yyscan_t yyscanner);
static int floatsuffix_check(TParseContext* context);
static int yuvcscstandardext_constant(TParseContext *context);
%}
%option noyywrap nounput never-interactive
......@@ -194,11 +196,17 @@ O [0-7]
"sampler2DShadow" { return ES2_reserved_ES3_keyword(context, SAMPLER2DSHADOW); }
"samplerCubeShadow" { return ES2_ident_ES3_keyword(context, SAMPLERCUBESHADOW); }
"sampler2DArrayShadow" { return ES2_ident_ES3_keyword(context, SAMPLER2DARRAYSHADOW); }
"__samplerExternal2DY2YEXT" { return ES3_extension_keyword_else_ident(context, "GL_EXT_YUV_target", SAMPLEREXTERNAL2DY2YEXT); }
"struct" { return STRUCT; }
"layout" { return ES2_ident_ES3_keyword(context, LAYOUT); }
"yuvCscStandardEXT" { return ES3_extension_keyword_else_ident(context, "GL_EXT_YUV_target", YUVCSCSTANDARDEXT); }
"itu_601" { return yuvcscstandardext_constant(context); }
"itu_601_full_range" { return yuvcscstandardext_constant(context); }
"itu_709" { return yuvcscstandardext_constant(context); }
"image2D" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IMAGE2D); }
"iimage2D" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IIMAGE2D); }
"uimage2D" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, UIMAGE2D); }
......@@ -533,6 +541,21 @@ int ES2_and_ES3_ident_ES3_1_keyword(TParseContext *context, int token)
return token;
}
int ES3_extension_keyword_else_ident(TParseContext *context, const char* extension, int token)
{
struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
yyscan_t yyscanner = (yyscan_t) context->getScanner();
// a reserved word in GLSL ES 3.00 with enabled extension, otherwise could be used as an identifier/type name
if (context->getShaderVersion() >= 300 && context->isExtensionEnabled(extension))
{
return token;
}
yylval->lex.string = NewPoolTString(yytext);
return check_type(yyscanner);
}
int uint_constant(TParseContext *context)
{
struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
......@@ -594,6 +617,22 @@ int float_constant(yyscan_t yyscanner) {
return FLOATCONSTANT;
}
int yuvcscstandardext_constant(TParseContext *context)
{
struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
yyscan_t yyscanner = (yyscan_t) context->getScanner();
// a reserved word in GLSL ES 3.00 with enabled extension, otherwise could be used as an identifier/type name
if (context->getShaderVersion() >= 300 && context->isExtensionEnabled("GL_EXT_YUV_target"))
{
yylval->lex.string = NewPoolTString(yytext);
return YUVCSCSTANDARDEXTCONSTANT;
}
yylval->lex.string = NewPoolTString(yytext);
return check_type(yyscanner);
}
int glslang_initialize(TParseContext* context) {
yyscan_t scanner = NULL;
if (yylex_init_extra(context, &scanner))
......
......@@ -178,9 +178,11 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons
%token <lex> USAMPLER2D USAMPLER3D USAMPLERCUBE USAMPLER2DARRAY
%token <lex> SAMPLER2DMS ISAMPLER2DMS USAMPLER2DMS
%token <lex> SAMPLER3D SAMPLER3DRECT SAMPLER2DSHADOW SAMPLERCUBESHADOW SAMPLER2DARRAYSHADOW
%token <lex> SAMPLEREXTERNAL2DY2YEXT
%token <lex> IMAGE2D IIMAGE2D UIMAGE2D IMAGE3D IIMAGE3D UIMAGE3D IMAGE2DARRAY IIMAGE2DARRAY UIMAGE2DARRAY
%token <lex> IMAGECUBE IIMAGECUBE UIMAGECUBE
%token <lex> LAYOUT
%token <lex> YUVCSCSTANDARDEXT YUVCSCSTANDARDEXTCONSTANT
%token <lex> IDENTIFIER TYPE_NAME FLOATCONSTANT INTCONSTANT UINTCONSTANT BOOLCONSTANT
%token <lex> FIELD_SELECTION
......@@ -280,6 +282,14 @@ primary_expression
unionArray->setBConst($1.b);
$$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @1);
}
| YUVCSCSTANDARDEXTCONSTANT {
if (!context->isExtensionEnabled("GL_EXT_YUV_target")) {
context->error(@1, "unsupported value", $1.string->c_str());
}
TConstantUnion *unionArray = new TConstantUnion[1];
unionArray->setYuvCscStandardEXTConst(getYuvCscStandardEXT($1.string->c_str()));
$$ = context->intermediate.addConstantUnion(unionArray, TType(EbtYuvCscStandardEXT, EbpUndefined, EvqConst), @1);
}
| LEFT_PAREN expression RIGHT_PAREN {
$$ = $2;
}
......@@ -1130,6 +1140,12 @@ type_specifier_nonarray
$$.initialize(EbtFloat, @1);
$$.setMatrix(4, 3);
}
| YUVCSCSTANDARDEXT {
if (!context->isExtensionEnabled("GL_EXT_YUV_target")) {
context->error(@1, "unsupported type", "yuvCscStandardEXT");
}
$$.initialize(EbtYuvCscStandardEXT, @1);
}
| SAMPLER2D {
$$.initialize(EbtSampler2D, @1);
}
......@@ -1191,6 +1207,12 @@ type_specifier_nonarray
}
$$.initialize(EbtSamplerExternalOES, @1);
}
| SAMPLEREXTERNAL2DY2YEXT {
if (!context->isExtensionEnabled("GL_EXT_YUV_target")) {
context->error(@1, "unsupported type", "__samplerExternal2DY2YEXT");
}
$$.initialize(EbtSamplerExternal2DY2YEXT, @1);
}
| SAMPLER2DRECT {
if (!context->supportsExtension("GL_ARB_texture_rectangle")) {
context->error(@1, "unsupported type", "sampler2DRect");
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -130,71 +130,74 @@ enum yytokentype
SAMPLER2DSHADOW = 336,
SAMPLERCUBESHADOW = 337,
SAMPLER2DARRAYSHADOW = 338,
IMAGE2D = 339,
IIMAGE2D = 340,
UIMAGE2D = 341,
IMAGE3D = 342,
IIMAGE3D = 343,
UIMAGE3D = 344,
IMAGE2DARRAY = 345,
IIMAGE2DARRAY = 346,
UIMAGE2DARRAY = 347,
IMAGECUBE = 348,
IIMAGECUBE = 349,
UIMAGECUBE = 350,
LAYOUT = 351,
IDENTIFIER = 352,
TYPE_NAME = 353,
FLOATCONSTANT = 354,
INTCONSTANT = 355,
UINTCONSTANT = 356,
BOOLCONSTANT = 357,
FIELD_SELECTION = 358,
LEFT_OP = 359,
RIGHT_OP = 360,
INC_OP = 361,
DEC_OP = 362,
LE_OP = 363,
GE_OP = 364,
EQ_OP = 365,
NE_OP = 366,
AND_OP = 367,
OR_OP = 368,
XOR_OP = 369,
MUL_ASSIGN = 370,
DIV_ASSIGN = 371,
ADD_ASSIGN = 372,
MOD_ASSIGN = 373,
LEFT_ASSIGN = 374,
RIGHT_ASSIGN = 375,
AND_ASSIGN = 376,
XOR_ASSIGN = 377,
OR_ASSIGN = 378,
SUB_ASSIGN = 379,
LEFT_PAREN = 380,
RIGHT_PAREN = 381,
LEFT_BRACKET = 382,
RIGHT_BRACKET = 383,
LEFT_BRACE = 384,
RIGHT_BRACE = 385,
DOT = 386,
COMMA = 387,
COLON = 388,
EQUAL = 389,
SEMICOLON = 390,
BANG = 391,
DASH = 392,
TILDE = 393,
PLUS = 394,
STAR = 395,
SLASH = 396,
PERCENT = 397,
LEFT_ANGLE = 398,
RIGHT_ANGLE = 399,
VERTICAL_BAR = 400,
CARET = 401,
AMPERSAND = 402,
QUESTION = 403
SAMPLEREXTERNAL2DY2YEXT = 339,
IMAGE2D = 340,
IIMAGE2D = 341,
UIMAGE2D = 342,
IMAGE3D = 343,
IIMAGE3D = 344,
UIMAGE3D = 345,
IMAGE2DARRAY = 346,
IIMAGE2DARRAY = 347,
UIMAGE2DARRAY = 348,
IMAGECUBE = 349,
IIMAGECUBE = 350,
UIMAGECUBE = 351,
LAYOUT = 352,
YUVCSCSTANDARDEXT = 353,
YUVCSCSTANDARDEXTCONSTANT = 354,
IDENTIFIER = 355,
TYPE_NAME = 356,
FLOATCONSTANT = 357,
INTCONSTANT = 358,
UINTCONSTANT = 359,
BOOLCONSTANT = 360,
FIELD_SELECTION = 361,
LEFT_OP = 362,
RIGHT_OP = 363,
INC_OP = 364,
DEC_OP = 365,
LE_OP = 366,
GE_OP = 367,
EQ_OP = 368,
NE_OP = 369,
AND_OP = 370,
OR_OP = 371,
XOR_OP = 372,
MUL_ASSIGN = 373,
DIV_ASSIGN = 374,
ADD_ASSIGN = 375,
MOD_ASSIGN = 376,
LEFT_ASSIGN = 377,
RIGHT_ASSIGN = 378,
AND_ASSIGN = 379,
XOR_ASSIGN = 380,
OR_ASSIGN = 381,
SUB_ASSIGN = 382,
LEFT_PAREN = 383,
RIGHT_PAREN = 384,
LEFT_BRACKET = 385,
RIGHT_BRACKET = 386,
LEFT_BRACE = 387,
RIGHT_BRACE = 388,
DOT = 389,
COMMA = 390,
COLON = 391,
EQUAL = 392,
SEMICOLON = 393,
BANG = 394,
DASH = 395,
TILDE = 396,
PLUS = 397,
STAR = 398,
SLASH = 399,
PERCENT = 400,
LEFT_ANGLE = 401,
RIGHT_ANGLE = 402,
VERTICAL_BAR = 403,
CARET = 404,
AMPERSAND = 405,
QUESTION = 406
};
#endif
......
......@@ -609,9 +609,14 @@ void TOutputTraverser::visitConstantUnion(TIntermConstantUnion *node)
out << node->getUnionArrayPointer()[i].getUConst();
out << " (const uint)\n";
break;
case EbtYuvCscStandardEXT:
out << getYuvCscStandardEXTString(
node->getUnionArrayPointer()[i].getYuvCscStandardEXTConst());
out << " (const yuvCscStandardEXT)\n";
break;
default:
out.prefix(SH_ERROR);
out << "Unknown constant";
out << "Unknown constant\n";
break;
}
}
......
......@@ -334,6 +334,8 @@ GLenum GLVariableType(const TType &type)
return GL_SAMPLER_CUBE;
case EbtSamplerExternalOES:
return GL_SAMPLER_EXTERNAL_OES;
case EbtSamplerExternal2DY2YEXT:
return GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT;
case EbtSampler2DRect:
return GL_SAMPLER_2D_RECT_ARB;
case EbtSampler2DArray:
......
......@@ -55,6 +55,7 @@
'<(angle_path)/src/tests/compiler_tests/DebugShaderPrecision_test.cpp',
'<(angle_path)/src/tests/compiler_tests/EmulateGLFragColorBroadcast_test.cpp',
'<(angle_path)/src/tests/compiler_tests/ExpressionLimit_test.cpp',
'<(angle_path)/src/tests/compiler_tests/EXT_YUV_target_test.cpp',
'<(angle_path)/src/tests/compiler_tests/EXT_blend_func_extended_test.cpp',
'<(angle_path)/src/tests/compiler_tests/FloatLex_test.cpp',
'<(angle_path)/src/tests/compiler_tests/FragDepth_test.cpp',
......
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