Commit 5d27a696 by Tim Van Patten Committed by Commit Bot

Support separable shader programs

The spec states: Shader stages including vertex shaders, fragment shaders, and compute shaders...A single program object can contain all of these shaders, or any subset thereof. This change allows shader programs without a fragment shader. The biggest driver of this change is dEQP since a large number of tests create shader programs without a fragment shader. Bug: angleproject:3803 Test: dEQP-GLES31.functional.program_interface_query Change-Id: Id6cb098c62a1489a14b9ec1b31bd4cd59f655e49 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1752010 Commit-Queue: Tim Van Patten <timvp@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCody Northrop <cnorthrop@google.com> Reviewed-by: 's avatarTim Van Patten <timvp@google.com>
parent 378c1881
...@@ -989,6 +989,7 @@ ProgramState::ProgramState() ...@@ -989,6 +989,7 @@ ProgramState::ProgramState()
mImageUniformRange(0, 0), mImageUniformRange(0, 0),
mAtomicCounterUniformRange(0, 0), mAtomicCounterUniformRange(0, 0),
mBinaryRetrieveableHint(false), mBinaryRetrieveableHint(false),
mSeparable(false),
mNumViews(-1), mNumViews(-1),
// [GL_EXT_geometry_shader] Table 20.22 // [GL_EXT_geometry_shader] Table 20.22
mGeometryShaderInputPrimitiveType(PrimitiveMode::Triangles), mGeometryShaderInputPrimitiveType(PrimitiveMode::Triangles),
...@@ -1464,8 +1465,11 @@ angle::Result Program::link(const Context *context) ...@@ -1464,8 +1465,11 @@ angle::Result Program::link(const Context *context)
const auto &mergedVaryings = getMergedVaryings(); const auto &mergedVaryings = getMergedVaryings();
ASSERT(mState.mAttachedShaders[ShaderType::Vertex]); gl::Shader *vertexShader = mState.mAttachedShaders[ShaderType::Vertex];
mState.mNumViews = mState.mAttachedShaders[ShaderType::Vertex]->getNumViews(); if (vertexShader)
{
mState.mNumViews = vertexShader->getNumViews();
}
InitUniformBlockLinker(mState, &resources->uniformBlockLinker); InitUniformBlockLinker(mState, &resources->uniformBlockLinker);
InitShaderStorageBlockLinker(mState, &resources->shaderStorageBlockLinker); InitShaderStorageBlockLinker(mState, &resources->shaderStorageBlockLinker);
...@@ -2818,26 +2822,52 @@ bool Program::linkValidateShaders(InfoLog &infoLog) ...@@ -2818,26 +2822,52 @@ bool Program::linkValidateShaders(InfoLog &infoLog)
} }
else else
{ {
if (isSeparable())
{
ASSERT(!fragmentShader || fragmentShader->getType() == ShaderType::Fragment);
if (fragmentShader && !fragmentShader->isCompiled())
{
infoLog << "Fragment shader is not compiled.";
return false;
}
ASSERT(!vertexShader || vertexShader->getType() == ShaderType::Vertex);
if (vertexShader && !vertexShader->isCompiled())
{
infoLog << "Vertex shader is not compiled.";
return false;
}
}
else
{
if (!fragmentShader || !fragmentShader->isCompiled()) if (!fragmentShader || !fragmentShader->isCompiled())
{ {
infoLog << "No compiled fragment shader when at least one graphics shader is attached."; infoLog
<< "No compiled fragment shader when at least one graphics shader is attached.";
return false; return false;
} }
ASSERT(fragmentShader->getType() == ShaderType::Fragment); ASSERT(fragmentShader->getType() == ShaderType::Fragment);
if (!vertexShader || !vertexShader->isCompiled()) if (!vertexShader || !vertexShader->isCompiled())
{ {
infoLog << "No compiled vertex shader when at least one graphics shader is attached."; infoLog
<< "No compiled vertex shader when at least one graphics shader is attached.";
return false; return false;
} }
ASSERT(vertexShader->getType() == ShaderType::Vertex); ASSERT(vertexShader->getType() == ShaderType::Vertex);
}
if (vertexShader && fragmentShader)
{
int vertexShaderVersion = vertexShader->getShaderVersion(); int vertexShaderVersion = vertexShader->getShaderVersion();
if (fragmentShader->getShaderVersion() != vertexShaderVersion) int fragmentShaderVersion = fragmentShader->getShaderVersion();
if (fragmentShaderVersion != vertexShaderVersion)
{ {
infoLog << "Fragment shader version does not match vertex shader version."; infoLog << "Fragment shader version does not match vertex shader version.";
return false; return false;
} }
}
if (geometryShader) if (geometryShader)
{ {
...@@ -2857,7 +2887,8 @@ bool Program::linkValidateShaders(InfoLog &infoLog) ...@@ -2857,7 +2887,8 @@ bool Program::linkValidateShaders(InfoLog &infoLog)
return false; return false;
} }
if (geometryShader->getShaderVersion() != vertexShaderVersion) if (vertexShader &&
(geometryShader->getShaderVersion() != vertexShader->getShaderVersion()))
{ {
mInfoLog << "Geometry shader version does not match vertex shader version."; mInfoLog << "Geometry shader version does not match vertex shader version.";
return false; return false;
...@@ -3075,13 +3106,16 @@ bool Program::linkValidateShaderInterfaceMatching(gl::Shader *generatingShader, ...@@ -3075,13 +3106,16 @@ bool Program::linkValidateShaderInterfaceMatching(gl::Shader *generatingShader,
bool Program::linkValidateFragmentInputBindings(gl::InfoLog &infoLog) const bool Program::linkValidateFragmentInputBindings(gl::InfoLog &infoLog) const
{ {
ASSERT(mState.mAttachedShaders[ShaderType::Fragment]);
std::map<GLuint, std::string> staticFragmentInputLocations; std::map<GLuint, std::string> staticFragmentInputLocations;
const std::vector<sh::Varying> &fragmentInputVaryings = Shader *fragmentShader = mState.mAttachedShaders[ShaderType::Fragment];
mState.mAttachedShaders[ShaderType::Fragment]->getInputVaryings();
for (const sh::Varying &input : fragmentInputVaryings) if (!fragmentShader)
{
return true;
}
for (const sh::Varying &input : fragmentShader->getInputVaryings())
{ {
if (input.isBuiltIn() || !input.staticUse) if (input.isBuiltIn() || !input.staticUse)
{ {
...@@ -3247,16 +3281,23 @@ bool Program::linkAttributes(const Context *context, InfoLog &infoLog) ...@@ -3247,16 +3281,23 @@ bool Program::linkAttributes(const Context *context, InfoLog &infoLog)
const Caps &caps = context->getCaps(); const Caps &caps = context->getCaps();
const Limitations &limitations = context->getLimitations(); const Limitations &limitations = context->getLimitations();
bool webglCompatibility = context->getExtensions().webglCompatibility; bool webglCompatibility = context->getExtensions().webglCompatibility;
int shaderVersion = -1;
unsigned int usedLocations = 0;
Shader *vertexShader = mState.getAttachedShader(ShaderType::Vertex); Shader *vertexShader = mState.getAttachedShader(gl::ShaderType::Vertex);
int shaderVersion = vertexShader->getShaderVersion(); if (!vertexShader)
{
// No vertex shader, so no attributes, so nothing to do
return true;
}
unsigned int usedLocations = 0; shaderVersion = vertexShader->getShaderVersion();
if (shaderVersion >= 300) if (shaderVersion >= 300)
{ {
// In GLSL ES 3.00.6, aliasing checks should be done with all declared attributes - see GLSL // In GLSL ES 3.00.6, aliasing checks should be done with all declared attributes -
// ES 3.00.6 section 12.46. Inactive attributes will be pruned after aliasing checks. // see GLSL ES 3.00.6 section 12.46. Inactive attributes will be pruned after
// aliasing checks.
mState.mAttributes = vertexShader->getAllAttributes(); mState.mAttributes = vertexShader->getAllAttributes();
} }
else else
...@@ -3264,8 +3305,8 @@ bool Program::linkAttributes(const Context *context, InfoLog &infoLog) ...@@ -3264,8 +3305,8 @@ bool Program::linkAttributes(const Context *context, InfoLog &infoLog)
// In GLSL ES 1.00.17 we only do aliasing checks for active attributes. // In GLSL ES 1.00.17 we only do aliasing checks for active attributes.
mState.mAttributes = vertexShader->getActiveAttributes(); mState.mAttributes = vertexShader->getActiveAttributes();
} }
GLuint maxAttribs = caps.maxVertexAttributes;
GLuint maxAttribs = caps.maxVertexAttributes;
std::vector<sh::Attribute *> usedAttribMap(maxAttribs, nullptr); std::vector<sh::Attribute *> usedAttribMap(maxAttribs, nullptr);
// Assign locations to attributes that have a binding location and check for attribute aliasing. // Assign locations to attributes that have a binding location and check for attribute aliasing.
...@@ -3589,6 +3630,13 @@ bool Program::linkValidateBuiltInVaryings(InfoLog &infoLog) const ...@@ -3589,6 +3630,13 @@ bool Program::linkValidateBuiltInVaryings(InfoLog &infoLog) const
{ {
Shader *vertexShader = mState.mAttachedShaders[ShaderType::Vertex]; Shader *vertexShader = mState.mAttachedShaders[ShaderType::Vertex];
Shader *fragmentShader = mState.mAttachedShaders[ShaderType::Fragment]; Shader *fragmentShader = mState.mAttachedShaders[ShaderType::Fragment];
if (!vertexShader || !fragmentShader)
{
// We can't validate an interface if we don't have both a producer and a consumer
return true;
}
const auto &vertexVaryings = vertexShader->getOutputVaryings(); const auto &vertexVaryings = vertexShader->getOutputVaryings();
const auto &fragmentVaryings = fragmentShader->getInputVaryings(); const auto &fragmentVaryings = fragmentShader->getInputVaryings();
int shaderVersion = vertexShader->getShaderVersion(); int shaderVersion = vertexShader->getShaderVersion();
...@@ -3772,8 +3820,6 @@ bool Program::linkValidateTransformFeedback(const Version &version, ...@@ -3772,8 +3820,6 @@ bool Program::linkValidateTransformFeedback(const Version &version,
bool Program::linkValidateGlobalNames(InfoLog &infoLog) const bool Program::linkValidateGlobalNames(InfoLog &infoLog) const
{ {
const std::vector<sh::Attribute> &attributes =
mState.mAttachedShaders[ShaderType::Vertex]->getActiveAttributes();
std::unordered_map<std::string, const sh::Uniform *> uniformMap; std::unordered_map<std::string, const sh::Uniform *> uniformMap;
using BlockAndFieldPair = using BlockAndFieldPair =
std::pair<const sh::InterfaceBlock *, const sh::InterfaceBlockField *>; std::pair<const sh::InterfaceBlock *, const sh::InterfaceBlockField *>;
...@@ -3857,7 +3903,10 @@ bool Program::linkValidateGlobalNames(InfoLog &infoLog) const ...@@ -3857,7 +3903,10 @@ bool Program::linkValidateGlobalNames(InfoLog &infoLog) const
} }
// Validate no uniform names conflict with attribute names // Validate no uniform names conflict with attribute names
for (const auto &attrib : attributes) gl::Shader *vertexShader = mState.mAttachedShaders[ShaderType::Vertex];
if (vertexShader)
{
for (const auto &attrib : vertexShader->getActiveAttributes())
{ {
if (uniformMap.count(attrib.name)) if (uniformMap.count(attrib.name))
{ {
...@@ -3865,6 +3914,7 @@ bool Program::linkValidateGlobalNames(InfoLog &infoLog) const ...@@ -3865,6 +3914,7 @@ bool Program::linkValidateGlobalNames(InfoLog &infoLog) const
return false; return false;
} }
} }
}
// Validate no Uniform Block fields conflict with other Uniforms // Validate no Uniform Block fields conflict with other Uniforms
for (const auto &uniformBlockField : uniformBlockFieldMap) for (const auto &uniformBlockField : uniformBlockFieldMap)
...@@ -3920,17 +3970,23 @@ ProgramMergedVaryings Program::getMergedVaryings() const ...@@ -3920,17 +3970,23 @@ ProgramMergedVaryings Program::getMergedVaryings() const
{ {
ProgramMergedVaryings merged; ProgramMergedVaryings merged;
for (const sh::Varying &varying : Shader *vertexShader = mState.mAttachedShaders[ShaderType::Vertex];
mState.mAttachedShaders[ShaderType::Vertex]->getOutputVaryings()) if (vertexShader)
{
for (const sh::Varying &varying : vertexShader->getOutputVaryings())
{ {
merged[varying.name].vertex = &varying; merged[varying.name].vertex = &varying;
} }
}
for (const sh::Varying &varying : Shader *fragmentShader = mState.mAttachedShaders[ShaderType::Fragment];
mState.mAttachedShaders[ShaderType::Fragment]->getInputVaryings()) if (fragmentShader)
{
for (const sh::Varying &varying : fragmentShader->getInputVaryings())
{ {
merged[varying.name].fragment = &varying; merged[varying.name].fragment = &varying;
} }
}
return merged; return merged;
} }
...@@ -4035,13 +4091,19 @@ bool Program::linkOutputVariables(const Caps &caps, ...@@ -4035,13 +4091,19 @@ bool Program::linkOutputVariables(const Caps &caps,
GLuint combinedShaderStorageBlocksCount) GLuint combinedShaderStorageBlocksCount)
{ {
Shader *fragmentShader = mState.mAttachedShaders[ShaderType::Fragment]; Shader *fragmentShader = mState.mAttachedShaders[ShaderType::Fragment];
ASSERT(fragmentShader != nullptr);
ASSERT(mState.mOutputVariableTypes.empty()); ASSERT(mState.mOutputVariableTypes.empty());
ASSERT(mState.mActiveOutputVariables.none()); ASSERT(mState.mActiveOutputVariables.none());
ASSERT(mState.mDrawBufferTypeMask.none()); ASSERT(mState.mDrawBufferTypeMask.none());
if (!fragmentShader)
{
// No fragment shader, so nothing to link
return true;
}
const auto &outputVariables = fragmentShader->getActiveOutputVariables(); const auto &outputVariables = fragmentShader->getActiveOutputVariables();
// Gather output variable types // Gather output variable types
for (const auto &outputVariable : outputVariables) for (const auto &outputVariable : outputVariables)
{ {
...@@ -4095,7 +4157,7 @@ bool Program::linkOutputVariables(const Caps &caps, ...@@ -4095,7 +4157,7 @@ bool Program::linkOutputVariables(const Caps &caps,
} }
// Skip this step for GLES2 shaders. // Skip this step for GLES2 shaders.
if (fragmentShader->getShaderVersion() == 100) if (fragmentShader && fragmentShader->getShaderVersion() == 100)
return true; return true;
mState.mOutputVariables = outputVariables; mState.mOutputVariables = outputVariables;
......
...@@ -462,16 +462,16 @@ void Shader::resolveCompile() ...@@ -462,16 +462,16 @@ void Shader::resolveCompile()
} }
case ShaderType::Vertex: case ShaderType::Vertex:
{ {
{
mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle)); mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
mState.mAllAttributes = GetShaderVariables(sh::GetAttributes(compilerHandle)); mState.mAllAttributes = GetShaderVariables(sh::GetAttributes(compilerHandle));
mState.mActiveAttributes = GetActiveShaderVariables(&mState.mAllAttributes); mState.mActiveAttributes = GetActiveShaderVariables(&mState.mAllAttributes);
mState.mNumViews = sh::GetVertexShaderNumViews(compilerHandle); mState.mNumViews = sh::GetVertexShaderNumViews(compilerHandle);
}
break; break;
} }
case ShaderType::Fragment: case ShaderType::Fragment:
{ {
mState.mAllAttributes = GetShaderVariables(sh::GetAttributes(compilerHandle));
mState.mActiveAttributes = GetActiveShaderVariables(&mState.mAllAttributes);
mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle)); mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
// TODO(jmadill): Figure out why we only sort in the FS, and if we need to. // TODO(jmadill): Figure out why we only sort in the FS, and if we need to.
std::sort(mState.mInputVaryings.begin(), mState.mInputVaryings.end(), CompareShaderVar); std::sort(mState.mInputVaryings.begin(), mState.mInputVaryings.end(), CompareShaderVar);
......
...@@ -477,9 +477,14 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Caps &caps, ...@@ -477,9 +477,14 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Caps &caps,
gl::Shader *vertexShaderGL = programData.getAttachedShader(ShaderType::Vertex); gl::Shader *vertexShaderGL = programData.getAttachedShader(ShaderType::Vertex);
gl::Shader *fragmentShaderGL = programData.getAttachedShader(ShaderType::Fragment); gl::Shader *fragmentShaderGL = programData.getAttachedShader(ShaderType::Fragment);
const ShaderD3D *fragmentShader = GetImplAs<ShaderD3D>(fragmentShaderGL);
const int shaderModel = mRenderer->getMajorShaderModel(); const int shaderModel = mRenderer->getMajorShaderModel();
const ShaderD3D *fragmentShader = nullptr;
if (fragmentShaderGL)
{
fragmentShader = GetImplAs<ShaderD3D>(fragmentShaderGL);
}
// usesViewScale() isn't supported in the D3D9 renderer // usesViewScale() isn't supported in the D3D9 renderer
ASSERT(shaderModel >= 4 || !programMetadata.usesViewScale()); ASSERT(shaderModel >= 4 || !programMetadata.usesViewScale());
...@@ -488,7 +493,7 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Caps &caps, ...@@ -488,7 +493,7 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Caps &caps,
mRenderer->getFeatures().useInstancedPointSpriteEmulation.enabled; mRenderer->getFeatures().useInstancedPointSpriteEmulation.enabled;
// Validation done in the compiler // Validation done in the compiler
ASSERT(!fragmentShader->usesFragColor() || !fragmentShader->usesFragData()); ASSERT(!fragmentShader || !fragmentShader->usesFragColor() || !fragmentShader->usesFragData());
std::ostringstream vertexStream; std::ostringstream vertexStream;
vertexStream << "struct VS_OUTPUT\n"; vertexStream << "struct VS_OUTPUT\n";
...@@ -670,12 +675,15 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Caps &caps, ...@@ -670,12 +675,15 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Caps &caps,
<< " return output;\n" << " return output;\n"
<< "}"; << "}";
if (vertexShaderGL)
{
std::string vertexSource = vertexShaderGL->getTranslatedSource(); std::string vertexSource = vertexShaderGL->getTranslatedSource();
angle::ReplaceSubstring(&vertexSource, std::string(MAIN_PROLOGUE_STUB_STRING), angle::ReplaceSubstring(&vertexSource, std::string(MAIN_PROLOGUE_STUB_STRING),
" initAttributes(input);\n"); " initAttributes(input);\n");
angle::ReplaceSubstring(&vertexSource, std::string(VERTEX_OUTPUT_STUB_STRING), angle::ReplaceSubstring(&vertexSource, std::string(VERTEX_OUTPUT_STUB_STRING),
vertexGenerateOutput.str()); vertexGenerateOutput.str());
vertexStream << vertexSource; vertexStream << vertexSource;
}
const auto &pixelBuiltins = builtinsD3D[gl::ShaderType::Fragment]; const auto &pixelBuiltins = builtinsD3D[gl::ShaderType::Fragment];
...@@ -686,7 +694,7 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Caps &caps, ...@@ -686,7 +694,7 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Caps &caps,
pixelStream << "\n"; pixelStream << "\n";
std::ostringstream pixelPrologue; std::ostringstream pixelPrologue;
if (fragmentShader->usesViewID()) if (fragmentShader && fragmentShader->usesViewID())
{ {
ASSERT(pixelBuiltins.glViewIDOVR.enabled); ASSERT(pixelBuiltins.glViewIDOVR.enabled);
pixelPrologue << " ViewID_OVR = input.gl_ViewID_OVR;\n"; pixelPrologue << " ViewID_OVR = input.gl_ViewID_OVR;\n";
...@@ -774,7 +782,7 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Caps &caps, ...@@ -774,7 +782,7 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Caps &caps,
<< " gl_PointCoord.y = 1.0 - input.gl_PointCoord.y;\n"; << " gl_PointCoord.y = 1.0 - input.gl_PointCoord.y;\n";
} }
if (fragmentShader->usesFrontFacing()) if (fragmentShader && fragmentShader->usesFrontFacing())
{ {
if (shaderModel <= 3) if (shaderModel <= 3)
{ {
...@@ -839,18 +847,22 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Caps &caps, ...@@ -839,18 +847,22 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Caps &caps,
pixelPrologue << ";\n"; pixelPrologue << ";\n";
} }
if (fragmentShaderGL)
{
std::string pixelSource = fragmentShaderGL->getTranslatedSource(); std::string pixelSource = fragmentShaderGL->getTranslatedSource();
if (fragmentShader->usesFrontFacing()) if (fragmentShader->usesFrontFacing())
{ {
if (shaderModel >= 4) if (shaderModel >= 4)
{ {
angle::ReplaceSubstring(&pixelSource, std::string(PIXEL_MAIN_PARAMETERS_STUB_STRING), angle::ReplaceSubstring(&pixelSource,
std::string(PIXEL_MAIN_PARAMETERS_STUB_STRING),
"PS_INPUT input, bool isFrontFace : SV_IsFrontFace"); "PS_INPUT input, bool isFrontFace : SV_IsFrontFace");
} }
else else
{ {
angle::ReplaceSubstring(&pixelSource, std::string(PIXEL_MAIN_PARAMETERS_STUB_STRING), angle::ReplaceSubstring(&pixelSource,
std::string(PIXEL_MAIN_PARAMETERS_STUB_STRING),
"PS_INPUT input, float vFace : VFACE"); "PS_INPUT input, float vFace : VFACE");
} }
} }
...@@ -863,6 +875,7 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Caps &caps, ...@@ -863,6 +875,7 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Caps &caps,
angle::ReplaceSubstring(&pixelSource, std::string(MAIN_PROLOGUE_STUB_STRING), angle::ReplaceSubstring(&pixelSource, std::string(MAIN_PROLOGUE_STUB_STRING),
pixelPrologue.str()); pixelPrologue.str());
pixelStream << pixelSource; pixelStream << pixelSource;
}
(*shaderHLSL)[gl::ShaderType::Vertex] = vertexStream.str(); (*shaderHLSL)[gl::ShaderType::Vertex] = vertexStream.str();
(*shaderHLSL)[gl::ShaderType::Fragment] = pixelStream.str(); (*shaderHLSL)[gl::ShaderType::Fragment] = pixelStream.str();
...@@ -1231,8 +1244,14 @@ void DynamicHLSL::getPixelShaderOutputKey(const gl::State &data, ...@@ -1231,8 +1244,14 @@ void DynamicHLSL::getPixelShaderOutputKey(const gl::State &data,
} }
else else
{ {
const auto &shaderOutputVars = const ShaderD3D *fragmentShader = metadata.getFragmentShader();
metadata.getFragmentShader()->getData().getActiveOutputVariables();
if (!fragmentShader)
{
return;
}
const auto &shaderOutputVars = fragmentShader->getData().getActiveOutputVariables();
for (size_t outputLocationIndex = 0u; for (size_t outputLocationIndex = 0u;
outputLocationIndex < programData.getOutputLocations().size(); ++outputLocationIndex) outputLocationIndex < programData.getOutputLocations().size(); ++outputLocationIndex)
......
...@@ -42,6 +42,11 @@ void GetDefaultInputLayoutFromShader(gl::Shader *vertexShader, gl::InputLayout * ...@@ -42,6 +42,11 @@ void GetDefaultInputLayoutFromShader(gl::Shader *vertexShader, gl::InputLayout *
{ {
inputLayoutOut->clear(); inputLayoutOut->clear();
if (!vertexShader)
{
return;
}
for (const sh::Attribute &shaderAttr : vertexShader->getActiveAttributes()) for (const sh::Attribute &shaderAttr : vertexShader->getActiveAttributes())
{ {
if (shaderAttr.type != GL_NONE) if (shaderAttr.type != GL_NONE)
...@@ -404,34 +409,39 @@ int ProgramD3DMetadata::getRendererMajorShaderModel() const ...@@ -404,34 +409,39 @@ int ProgramD3DMetadata::getRendererMajorShaderModel() const
bool ProgramD3DMetadata::usesBroadcast(const gl::State &data) const bool ProgramD3DMetadata::usesBroadcast(const gl::State &data) const
{ {
return (mAttachedShaders[gl::ShaderType::Fragment]->usesFragColor() && const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment];
mAttachedShaders[gl::ShaderType::Fragment]->usesMultipleRenderTargets() && return (shader && shader->usesFragColor() && shader->usesMultipleRenderTargets() &&
data.getClientMajorVersion() < 3); data.getClientMajorVersion() < 3);
} }
bool ProgramD3DMetadata::usesSecondaryColor() const bool ProgramD3DMetadata::usesSecondaryColor() const
{ {
return mAttachedShaders[gl::ShaderType::Fragment]->usesSecondaryColor(); const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment];
return (shader && shader->usesSecondaryColor());
} }
bool ProgramD3DMetadata::usesFragDepth() const bool ProgramD3DMetadata::usesFragDepth() const
{ {
return mAttachedShaders[gl::ShaderType::Fragment]->usesFragDepth(); const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment];
return (shader && shader->usesFragDepth());
} }
bool ProgramD3DMetadata::usesPointCoord() const bool ProgramD3DMetadata::usesPointCoord() const
{ {
return mAttachedShaders[gl::ShaderType::Fragment]->usesPointCoord(); const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment];
return (shader && shader->usesPointCoord());
} }
bool ProgramD3DMetadata::usesFragCoord() const bool ProgramD3DMetadata::usesFragCoord() const
{ {
return mAttachedShaders[gl::ShaderType::Fragment]->usesFragCoord(); const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment];
return (shader && shader->usesFragCoord());
} }
bool ProgramD3DMetadata::usesPointSize() const bool ProgramD3DMetadata::usesPointSize() const
{ {
return mAttachedShaders[gl::ShaderType::Vertex]->usesPointSize(); const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Vertex];
return (shader && shader->usesPointSize());
} }
bool ProgramD3DMetadata::usesInsertedPointCoordValue() const bool ProgramD3DMetadata::usesInsertedPointCoordValue() const
...@@ -447,17 +457,20 @@ bool ProgramD3DMetadata::usesViewScale() const ...@@ -447,17 +457,20 @@ bool ProgramD3DMetadata::usesViewScale() const
bool ProgramD3DMetadata::hasANGLEMultiviewEnabled() const bool ProgramD3DMetadata::hasANGLEMultiviewEnabled() const
{ {
return mAttachedShaders[gl::ShaderType::Vertex]->hasANGLEMultiviewEnabled(); const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Vertex];
return (shader && shader->hasANGLEMultiviewEnabled());
} }
bool ProgramD3DMetadata::usesVertexID() const bool ProgramD3DMetadata::usesVertexID() const
{ {
return mAttachedShaders[gl::ShaderType::Vertex]->usesVertexID(); const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Vertex];
return (shader && shader->usesVertexID());
} }
bool ProgramD3DMetadata::usesViewID() const bool ProgramD3DMetadata::usesViewID() const
{ {
return mAttachedShaders[gl::ShaderType::Fragment]->usesViewID(); const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment];
return (shader && shader->usesViewID());
} }
bool ProgramD3DMetadata::canSelectViewInVertexShader() const bool ProgramD3DMetadata::canSelectViewInVertexShader() const
...@@ -492,12 +505,15 @@ bool ProgramD3DMetadata::usesSystemValuePointSize() const ...@@ -492,12 +505,15 @@ bool ProgramD3DMetadata::usesSystemValuePointSize() const
bool ProgramD3DMetadata::usesMultipleFragmentOuts() const bool ProgramD3DMetadata::usesMultipleFragmentOuts() const
{ {
return mAttachedShaders[gl::ShaderType::Fragment]->usesMultipleRenderTargets(); const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment];
return (shader && shader->usesMultipleRenderTargets());
} }
bool ProgramD3DMetadata::usesCustomOutVars() const bool ProgramD3DMetadata::usesCustomOutVars() const
{ {
int version = mAttachedShaders[gl::ShaderType::Vertex]->getData().getShaderVersion();
const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Vertex];
int version = shader ? shader->getData().getShaderVersion() : -1;
switch (mClientType) switch (mClientType)
{ {
...@@ -1635,6 +1651,11 @@ class ProgramD3D::GetVertexExecutableTask : public ProgramD3D::GetExecutableTask ...@@ -1635,6 +1651,11 @@ class ProgramD3D::GetVertexExecutableTask : public ProgramD3D::GetExecutableTask
GetVertexExecutableTask(ProgramD3D *program) : GetExecutableTask(program) {} GetVertexExecutableTask(ProgramD3D *program) : GetExecutableTask(program) {}
angle::Result run() override angle::Result run() override
{ {
if (!mProgram->mState.getAttachedShader(gl::ShaderType::Vertex))
{
return angle::Result::Continue;
}
mProgram->updateCachedInputLayoutFromShader(); mProgram->updateCachedInputLayoutFromShader();
ANGLE_TRY(mProgram->getVertexExecutableForCachedInputLayout(this, &mExecutable, &mInfoLog)); ANGLE_TRY(mProgram->getVertexExecutableForCachedInputLayout(this, &mExecutable, &mInfoLog));
...@@ -1657,6 +1678,11 @@ class ProgramD3D::GetPixelExecutableTask : public ProgramD3D::GetExecutableTask ...@@ -1657,6 +1678,11 @@ class ProgramD3D::GetPixelExecutableTask : public ProgramD3D::GetExecutableTask
GetPixelExecutableTask(ProgramD3D *program) : GetExecutableTask(program) {} GetPixelExecutableTask(ProgramD3D *program) : GetExecutableTask(program) {}
angle::Result run() override angle::Result run() override
{ {
if (!mProgram->mState.getAttachedShader(gl::ShaderType::Fragment))
{
return angle::Result::Continue;
}
mProgram->updateCachedOutputLayoutFromShader(); mProgram->updateCachedOutputLayoutFromShader();
ANGLE_TRY(mProgram->getPixelExecutableForCachedOutputLayout(this, &mExecutable, &mInfoLog)); ANGLE_TRY(mProgram->getPixelExecutableForCachedOutputLayout(this, &mExecutable, &mInfoLog));
...@@ -1876,10 +1902,11 @@ std::unique_ptr<LinkEvent> ProgramD3D::compileProgramExecutables(const gl::Conte ...@@ -1876,10 +1902,11 @@ std::unique_ptr<LinkEvent> ProgramD3D::compileProgramExecutables(const gl::Conte
auto pixelTask = std::make_shared<GetPixelExecutableTask>(this); auto pixelTask = std::make_shared<GetPixelExecutableTask>(this);
auto geometryTask = std::make_shared<GetGeometryExecutableTask>(this, context->getState()); auto geometryTask = std::make_shared<GetGeometryExecutableTask>(this, context->getState());
bool useGS = usesGeometryShader(context->getState(), gl::PrimitiveMode::Points); bool useGS = usesGeometryShader(context->getState(), gl::PrimitiveMode::Points);
const ShaderD3D *vertexShaderD3D = gl::Shader *vertexShader = mState.getAttachedShader(gl::ShaderType::Vertex);
GetImplAs<ShaderD3D>(mState.getAttachedShader(gl::ShaderType::Vertex)); gl::Shader *fragmentShader = mState.getAttachedShader(gl::ShaderType::Fragment);
const ShaderD3D *vertexShaderD3D = vertexShader ? GetImplAs<ShaderD3D>(vertexShader) : nullptr;
const ShaderD3D *fragmentShaderD3D = const ShaderD3D *fragmentShaderD3D =
GetImplAs<ShaderD3D>(mState.getAttachedShader(gl::ShaderType::Fragment)); fragmentShader ? GetImplAs<ShaderD3D>(fragmentShader) : nullptr;
return std::make_unique<GraphicsProgramLinkEvent>(infoLog, context->getWorkerThreadPool(), return std::make_unique<GraphicsProgramLinkEvent>(infoLog, context->getWorkerThreadPool(),
vertexTask, pixelTask, geometryTask, useGS, vertexTask, pixelTask, geometryTask, useGS,
...@@ -2010,7 +2037,8 @@ std::unique_ptr<LinkEvent> ProgramD3D::link(const gl::Context *context, ...@@ -2010,7 +2037,8 @@ std::unique_ptr<LinkEvent> ProgramD3D::link(const gl::Context *context,
if (mRenderer->getNativeLimitations().noFrontFacingSupport) if (mRenderer->getNativeLimitations().noFrontFacingSupport)
{ {
if (shadersD3D[gl::ShaderType::Fragment]->usesFrontFacing()) const ShaderD3D *fragmentShader = shadersD3D[gl::ShaderType::Fragment];
if (fragmentShader && fragmentShader->usesFrontFacing())
{ {
infoLog << "The current renderer doesn't support gl_FrontFacing"; infoLog << "The current renderer doesn't support gl_FrontFacing";
return std::make_unique<LinkEventDone>(angle::Result::Incomplete); return std::make_unique<LinkEventDone>(angle::Result::Incomplete);
...@@ -2023,7 +2051,8 @@ std::unique_ptr<LinkEvent> ProgramD3D::link(const gl::Context *context, ...@@ -2023,7 +2051,8 @@ std::unique_ptr<LinkEvent> ProgramD3D::link(const gl::Context *context,
mDynamicHLSL->generateShaderLinkHLSL(context->getCaps(), mState, metadata, mDynamicHLSL->generateShaderLinkHLSL(context->getCaps(), mState, metadata,
resources.varyingPacking, builtins, &mShaderHLSL); resources.varyingPacking, builtins, &mShaderHLSL);
mUsesPointSize = shadersD3D[gl::ShaderType::Vertex]->usesPointSize(); const ShaderD3D *vertexShader = shadersD3D[gl::ShaderType::Vertex];
mUsesPointSize = vertexShader && vertexShader->usesPointSize();
mDynamicHLSL->getPixelShaderOutputKey(data, mState, metadata, &mPixelShaderKey); mDynamicHLSL->getPixelShaderOutputKey(data, mState, metadata, &mPixelShaderKey);
mUsesFragDepth = metadata.usesFragDepth(); mUsesFragDepth = metadata.usesFragDepth();
mUsesVertexID = metadata.usesVertexID(); mUsesVertexID = metadata.usesVertexID();
...@@ -2920,7 +2949,10 @@ unsigned int ProgramD3D::issueSerial() ...@@ -2920,7 +2949,10 @@ unsigned int ProgramD3D::issueSerial()
void ProgramD3D::initAttribLocationsToD3DSemantic() void ProgramD3D::initAttribLocationsToD3DSemantic()
{ {
gl::Shader *vertexShader = mState.getAttachedShader(gl::ShaderType::Vertex); gl::Shader *vertexShader = mState.getAttachedShader(gl::ShaderType::Vertex);
ASSERT(vertexShader != nullptr); if (!vertexShader)
{
return;
}
// Init semantic index // Init semantic index
int semanticIndex = 0; int semanticIndex = 0;
......
...@@ -256,19 +256,14 @@ std::unique_ptr<LinkEvent> ProgramGL::link(const gl::Context *context, ...@@ -256,19 +256,14 @@ std::unique_ptr<LinkEvent> ProgramGL::link(const gl::Context *context,
&transformFeedbackVaryings[0], mState.getTransformFeedbackBufferMode()); &transformFeedbackVaryings[0], mState.getTransformFeedbackBufferMode());
} }
const ShaderGL *vertexShaderGL = for (const gl::ShaderType shaderType : gl::kAllGraphicsShaderTypes)
GetImplAs<ShaderGL>(mState.getAttachedShader(gl::ShaderType::Vertex)); {
const ShaderGL *fragmentShaderGL = const ShaderGL *shaderGL =
GetImplAs<ShaderGL>(mState.getAttachedShader(gl::ShaderType::Fragment)); rx::SafeGetImplAs<ShaderGL, gl::Shader>(mState.getAttachedShader(shaderType));
const ShaderGL *geometryShaderGL = rx::SafeGetImplAs<ShaderGL, gl::Shader>( if (shaderGL)
mState.getAttachedShader(gl::ShaderType::Geometry));
// Attach the shaders
mFunctions->attachShader(mProgramID, vertexShaderGL->getShaderID());
mFunctions->attachShader(mProgramID, fragmentShaderGL->getShaderID());
if (geometryShaderGL)
{ {
mFunctions->attachShader(mProgramID, geometryShaderGL->getShaderID()); mFunctions->attachShader(mProgramID, shaderGL->getShaderID());
}
} }
// Bind attribute locations to match the GL layer. // Bind attribute locations to match the GL layer.
...@@ -288,7 +283,8 @@ std::unique_ptr<LinkEvent> ProgramGL::link(const gl::Context *context, ...@@ -288,7 +283,8 @@ std::unique_ptr<LinkEvent> ProgramGL::link(const gl::Context *context,
// Otherwise shader-assigned locations will work. // Otherwise shader-assigned locations will work.
if (context->getExtensions().blendFuncExtended) if (context->getExtensions().blendFuncExtended)
{ {
if (mState.getAttachedShader(gl::ShaderType::Fragment)->getShaderVersion() == 100) gl::Shader *fragmentShader = mState.getAttachedShader(gl::ShaderType::Fragment);
if (fragmentShader && fragmentShader->getShaderVersion() == 100)
{ {
// TODO(http://anglebug.com/2833): The bind done below is only valid in case the // TODO(http://anglebug.com/2833): The bind done below is only valid in case the
// compiler transforms the shader outputs to the angle/webgl prefixed ones. If we // compiler transforms the shader outputs to the angle/webgl prefixed ones. If we
...@@ -434,19 +430,14 @@ std::unique_ptr<LinkEvent> ProgramGL::link(const gl::Context *context, ...@@ -434,19 +430,14 @@ std::unique_ptr<LinkEvent> ProgramGL::link(const gl::Context *context,
} }
else else
{ {
const ShaderGL *vertexShaderGL = for (const gl::ShaderType shaderType : gl::kAllGraphicsShaderTypes)
GetImplAs<ShaderGL>(mState.getAttachedShader(gl::ShaderType::Vertex)); {
const ShaderGL *fragmentShaderGL = const ShaderGL *shaderGL =
GetImplAs<ShaderGL>(mState.getAttachedShader(gl::ShaderType::Fragment)); rx::SafeGetImplAs<ShaderGL>(mState.getAttachedShader(shaderType));
const ShaderGL *geometryShaderGL = rx::SafeGetImplAs<ShaderGL, gl::Shader>( if (shaderGL)
mState.getAttachedShader(gl::ShaderType::Geometry));
// Detach the shaders
mFunctions->detachShader(mProgramID, vertexShaderGL->getShaderID());
mFunctions->detachShader(mProgramID, fragmentShaderGL->getShaderID());
if (geometryShaderGL)
{ {
mFunctions->detachShader(mProgramID, geometryShaderGL->getShaderID()); mFunctions->detachShader(mProgramID, shaderGL->getShaderID());
}
} }
} }
// Verify the link // Verify the link
......
...@@ -491,21 +491,21 @@ void GenerateTransformFeedbackOutputs(const gl::ProgramState &programState, ...@@ -491,21 +491,21 @@ void GenerateTransformFeedbackOutputs(const gl::ProgramState &programState,
} }
void AssignAttributeLocations(const gl::ProgramState &programState, void AssignAttributeLocations(const gl::ProgramState &programState,
IntermediateShaderSource *vertexSource) IntermediateShaderSource *shaderSource)
{ {
ASSERT(!vertexSource->empty()); ASSERT(!shaderSource->empty());
// Parse attribute locations and replace them in the vertex shader. // Parse attribute locations and replace them in the vertex shader.
// See corresponding code in OutputVulkanGLSL.cpp. // See corresponding code in OutputVulkanGLSL.cpp.
for (const sh::Attribute &attribute : programState.getAttributes()) for (const sh::Attribute &attribute : programState.getAttributes())
{ {
// Warning: If we endup supporting ES 3.0 shaders and up, Program::linkAttributes is going // Warning: If we end up supporting ES 3.0 shaders and up, Program::linkAttributes is
// to bring us all attributes in this list instead of only the active ones. // going to bring us all attributes in this list instead of only the active ones.
ASSERT(attribute.active); ASSERT(attribute.active);
std::string locationString = "location = " + Str(attribute.location); std::string locationString = "location = " + Str(attribute.location);
vertexSource->insertLayoutSpecifier(attribute.name, locationString); shaderSource->insertLayoutSpecifier(attribute.name, locationString);
vertexSource->insertQualifierSpecifier(attribute.name, "in"); shaderSource->insertQualifierSpecifier(attribute.name, "in");
} }
} }
...@@ -519,8 +519,6 @@ std::string RemoveArrayZeroSubscript(const std::string &expression) ...@@ -519,8 +519,6 @@ std::string RemoveArrayZeroSubscript(const std::string &expression)
void AssignOutputLocations(const gl::ProgramState &programState, void AssignOutputLocations(const gl::ProgramState &programState,
IntermediateShaderSource *fragmentSource) IntermediateShaderSource *fragmentSource)
{ {
ASSERT(!fragmentSource->empty());
// Parse output locations and replace them in the fragment shader. // Parse output locations and replace them in the fragment shader.
// See corresponding code in OutputVulkanGLSL.cpp. // See corresponding code in OutputVulkanGLSL.cpp.
// TODO(syoussefi): Add support for EXT_blend_func_extended. http://anglebug.com/3385 // TODO(syoussefi): Add support for EXT_blend_func_extended. http://anglebug.com/3385
...@@ -573,9 +571,6 @@ void AssignVaryingLocations(const gl::ProgramLinkedResources &resources, ...@@ -573,9 +571,6 @@ void AssignVaryingLocations(const gl::ProgramLinkedResources &resources,
IntermediateShaderSource *outStageSource, IntermediateShaderSource *outStageSource,
IntermediateShaderSource *inStageSource) IntermediateShaderSource *inStageSource)
{ {
ASSERT(!outStageSource->empty());
ASSERT(!inStageSource->empty());
// Assign varying locations. // Assign varying locations.
for (const gl::PackedVaryingRegister &varyingReg : resources.varyingPacking.getRegisterList()) for (const gl::PackedVaryingRegister &varyingReg : resources.varyingPacking.getRegisterList())
{ {
...@@ -813,25 +808,26 @@ void AssignTextureBindings(bool useOldRewriteStructSamplers, ...@@ -813,25 +808,26 @@ void AssignTextureBindings(bool useOldRewriteStructSamplers,
void CleanupUnusedEntities(bool useOldRewriteStructSamplers, void CleanupUnusedEntities(bool useOldRewriteStructSamplers,
const gl::ProgramState &programState, const gl::ProgramState &programState,
const gl::ProgramLinkedResources &resources, const gl::ProgramLinkedResources &resources,
gl::Shader *glVertexShader, gl::ShaderType shaderType,
gl::ShaderMap<IntermediateShaderSource> *shaderSources) gl::ShaderMap<IntermediateShaderSource> *shaderSources)
{ {
IntermediateShaderSource &vertexSource = (*shaderSources)[gl::ShaderType::Vertex]; gl::Shader *shader = programState.getAttachedShader(shaderType);
if (!vertexSource.empty()) IntermediateShaderSource &source = (*shaderSources)[shaderType];
if (!source.empty())
{ {
ASSERT(glVertexShader != nullptr); ASSERT(shader != nullptr);
// The attributes in the programState could have been filled with active attributes only // The attributes in the programState could have been filled with active attributes only
// depending on the shader version. If there is inactive attributes left, we have to remove // depending on the shader version. If there is inactive attributes left, we have to remove
// their @@ QUALIFIER and @@ LAYOUT markers. // their @@ QUALIFIER and @@ LAYOUT markers.
for (const sh::Attribute &attribute : glVertexShader->getAllAttributes()) for (const sh::Attribute &attribute : shader->getAllAttributes())
{ {
if (attribute.active) if (attribute.active)
{ {
continue; continue;
} }
vertexSource.eraseLayoutAndQualifierSpecifiers(attribute.name, ""); source.eraseLayoutAndQualifierSpecifiers(attribute.name, "");
} }
} }
...@@ -919,13 +915,21 @@ void GlslangWrapper::GetShaderSource(bool useOldRewriteStructSamplers, ...@@ -919,13 +915,21 @@ void GlslangWrapper::GetShaderSource(bool useOldRewriteStructSamplers,
AssignOutputLocations(programState, fragmentSource); AssignOutputLocations(programState, fragmentSource);
AssignVaryingLocations(resources, vertexSource, fragmentSource); AssignVaryingLocations(resources, vertexSource, fragmentSource);
} }
else if (!fragmentSource->empty())
{
AssignAttributeLocations(programState, fragmentSource);
AssignOutputLocations(programState, fragmentSource);
AssignVaryingLocations(resources, vertexSource, fragmentSource);
}
AssignUniformBindings(&intermediateSources); AssignUniformBindings(&intermediateSources);
AssignBufferBindings(programState, &intermediateSources); AssignBufferBindings(programState, &intermediateSources);
AssignTextureBindings(useOldRewriteStructSamplers, programState, &intermediateSources); AssignTextureBindings(useOldRewriteStructSamplers, programState, &intermediateSources);
CleanupUnusedEntities(useOldRewriteStructSamplers, programState, resources, for (const auto shaderType : gl::kAllGraphicsShaderTypes)
programState.getAttachedShader(gl::ShaderType::Vertex), {
CleanupUnusedEntities(useOldRewriteStructSamplers, programState, resources, shaderType,
&intermediateSources); &intermediateSources);
}
// Write transform feedback output code. // Write transform feedback output code.
if (!vertexSource->empty()) if (!vertexSource->empty())
......
...@@ -484,7 +484,7 @@ void ProgramVk::setBinaryRetrievableHint(bool retrievable) ...@@ -484,7 +484,7 @@ void ProgramVk::setBinaryRetrievableHint(bool retrievable)
void ProgramVk::setSeparable(bool separable) void ProgramVk::setSeparable(bool separable)
{ {
UNIMPLEMENTED(); // Nohting to do here yet.
} }
std::unique_ptr<LinkEvent> ProgramVk::link(const gl::Context *context, std::unique_ptr<LinkEvent> ProgramVk::link(const gl::Context *context,
......
...@@ -635,7 +635,7 @@ ...@@ -635,7 +635,7 @@
// Front-end query bugs: // Front-end query bugs:
3520 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_limited_query.resource_query = FAIL 3520 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_limited_query.resource_query = FAIL
3520 VULKAN : dEQP-GLES31.functional.program_interface_query.program_*.resource_list.compute.empty = FAIL 3520 VULKAN : dEQP-GLES31.functional.program_interface_query.program_input.resource_list.compute.empty = FAIL
3520 VULKAN : dEQP-GLES31.functional.program_interface_query.shader_storage_block.buffer_data_size.* = FAIL 3520 VULKAN : dEQP-GLES31.functional.program_interface_query.shader_storage_block.buffer_data_size.* = FAIL
// Shader support: // Shader support:
...@@ -656,13 +656,55 @@ ...@@ -656,13 +656,55 @@
// SSBO and Image qualifiers: // SSBO and Image qualifiers:
3602 VULKAN : dEQP-GLES31.functional.synchronization.in_invocation.ssbo_alias_overwrite = FAIL 3602 VULKAN : dEQP-GLES31.functional.synchronization.in_invocation.ssbo_alias_overwrite = FAIL
// Array of array in atomic counters:
3566 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.atomic_counter_buffer_index.default_block.array.var_array_array = SKIP
3566 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.location.default_block.array.array.atomic_uint = SKIP
// Struct referenced by: // Struct referenced by:
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.*.referenced_by*struct* = FAIL 3596 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.referenced_by_shader.compute.uniform_block.float_*struct* = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.referenced_by_shader.compute.block_array.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.referenced_by_shader.separable_vertex.uniform_block.float_*struct* = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.referenced_by_shader.separable_vertex.block_array.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.referenced_by_shader.vertex_fragment.uniform_block.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.referenced_by_shader.vertex_fragment.block_array.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.referenced_by_shader.vertex_fragment_only_vertex.uniform_block.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.referenced_by_shader.vertex_fragment_only_vertex.block_array.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.referenced_by_shader.vertex_fragment_only_fragment.uniform_block.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.referenced_by_shader.vertex_fragment_only_fragment.block_array.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.compute.named_block.float_*struct* = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.compute.block_array.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.separable_vertex.named_block.float_*struct* = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.separable_vertex.named_block.float_array_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.separable_vertex.named_block.float_struct_array = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.separable_vertex.named_block.float_struct_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.separable_vertex.named_block.float_unsized_struct_array = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.separable_vertex.block_array.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.vertex_fragment.named_block.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.vertex_fragment.block_array.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.vertex_fragment_only_vertex.named_block.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.vertex_fragment_only_vertex.block_array.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.vertex_fragment_only_fragment.named_block.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.vertex_fragment_only_fragment.block_array.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.*random* = FAIL 3596 VULKAN : dEQP-GLES31.functional.program_interface_query.*random* = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.referenced_by_shader.separable_fragment.uniform_block.*struct* = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.referenced_by_shader.separable_fragment.block_array.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.program_input.resource_list.separable_fragment.* = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.program_input.array_size.separable_fragment.* = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.program_input.location.separable_fragment.var* = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.program_input.name_length.separable_fragment.var* = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.program_input.type.separable_fragment.* = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.separable_fragment.named_block.float*struct* = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.separable_fragment.block_array.float_struct = FAIL
// Separate shader objects:
3570 VULKAN : dEQP-GLES31.functional.program_interface_query.program_input.referenced_by.referenced_by_separable_fragment = FAIL
3570 VULKAN : dEQP-GLES31.functional.program_interface_query.program_input.referenced_by.referenced_by_vertex_fragment = SKIP
3570 VULKAN : dEQP-GLES31.functional.program_interface_query.program_output.resource_list.separable_vertex.* = FAIL
3570 VULKAN : dEQP-GLES31.functional.program_interface_query.program_output.array_size.separable_vertex.var* = FAIL
3570 VULKAN : dEQP-GLES31.functional.program_interface_query.program_output.location.separable_vertex.var* = FAIL
3570 VULKAN : dEQP-GLES31.functional.program_interface_query.program_output.name_length.separable_vertex.var* = FAIL
3570 VULKAN : dEQP-GLES31.functional.program_interface_query.program_output.referenced_by.referenced_by_separable_vertex = FAIL
3570 VULKAN : dEQP-GLES31.functional.program_interface_query.program_output.referenced_by.referenced_by_vertex_fragment = SKIP
3570 VULKAN : dEQP-GLES31.functional.program_interface_query.program_output.type.separable_vertex.basic_type.* = FAIL
3570 VULKAN : dEQP-GLES31.functional.program_interface_query.program_output.type.separable_vertex.array.* = FAIL
3570 VULKAN : dEQP-GLES31.functional.program_interface_query.program_output.type.separable_vertex.struct.* = FAIL
3570 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.random.* = FAIL
// Block name matching failure: // Block name matching failure:
3459 VULKAN : dEQP-GLES31.functional.shaders.linkage.es31.shader_storage_block.mismatch_with_and_without_instance_name = FAIL 3459 VULKAN : dEQP-GLES31.functional.shaders.linkage.es31.shader_storage_block.mismatch_with_and_without_instance_name = FAIL
...@@ -684,10 +726,6 @@ ...@@ -684,10 +726,6 @@
// Framebuffer without attachments: // Framebuffer without attachments:
3579 ANDROID VULKAN : dEQP-GLES31.functional.fbo.no_attachments.* = SKIP 3579 ANDROID VULKAN : dEQP-GLES31.functional.fbo.no_attachments.* = SKIP
// Separate shader objects:
3570 VULKAN : dEQP-GLES31.functional.program_interface_query.*separable_* = FAIL
3570 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.random.* = FAIL
// Debug: // Debug:
3590 VULKAN : dEQP-GLES31.functional.debug.negative_coverage.* = SKIP 3590 VULKAN : dEQP-GLES31.functional.debug.negative_coverage.* = SKIP
3590 VULKAN : dEQP-GLES31.functional.debug.error_groups.case_14 = SKIP 3590 VULKAN : dEQP-GLES31.functional.debug.error_groups.case_14 = SKIP
......
...@@ -750,7 +750,7 @@ void ANGLETestBase::drawQuad(GLuint program, ...@@ -750,7 +750,7 @@ void ANGLETestBase::drawQuad(GLuint program,
GLint positionLocation = glGetAttribLocation(program, positionAttribName.c_str()); GLint positionLocation = glGetAttribLocation(program, positionAttribName.c_str());
std::array<Vector3, 6> quadVertices; std::array<Vector3, 6> quadVertices = GetQuadVertices();
if (useVertexBuffer) if (useVertexBuffer)
{ {
...@@ -760,7 +760,6 @@ void ANGLETestBase::drawQuad(GLuint program, ...@@ -760,7 +760,6 @@ void ANGLETestBase::drawQuad(GLuint program,
} }
else else
{ {
quadVertices = GetQuadVertices();
for (Vector3 &vertex : quadVertices) for (Vector3 &vertex : quadVertices)
{ {
vertex.x() *= positionAttribXYScale; vertex.x() *= positionAttribXYScale;
......
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