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
...@@ -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);
......
...@@ -475,10 +475,15 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Caps &caps, ...@@ -475,10 +475,15 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Caps &caps,
ASSERT((*shaderHLSL)[gl::ShaderType::Vertex].empty() && ASSERT((*shaderHLSL)[gl::ShaderType::Vertex].empty() &&
(*shaderHLSL)[gl::ShaderType::Fragment].empty()); (*shaderHLSL)[gl::ShaderType::Fragment].empty());
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"
<< "}"; << "}";
std::string vertexSource = vertexShaderGL->getTranslatedSource(); if (vertexShaderGL)
angle::ReplaceSubstring(&vertexSource, std::string(MAIN_PROLOGUE_STUB_STRING), {
" initAttributes(input);\n"); std::string vertexSource = vertexShaderGL->getTranslatedSource();
angle::ReplaceSubstring(&vertexSource, std::string(VERTEX_OUTPUT_STUB_STRING), angle::ReplaceSubstring(&vertexSource, std::string(MAIN_PROLOGUE_STUB_STRING),
vertexGenerateOutput.str()); " initAttributes(input);\n");
vertexStream << vertexSource; angle::ReplaceSubstring(&vertexSource, std::string(VERTEX_OUTPUT_STUB_STRING),
vertexGenerateOutput.str());
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,30 +847,35 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Caps &caps, ...@@ -839,30 +847,35 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Caps &caps,
pixelPrologue << ";\n"; pixelPrologue << ";\n";
} }
std::string pixelSource = fragmentShaderGL->getTranslatedSource(); if (fragmentShaderGL)
if (fragmentShader->usesFrontFacing())
{ {
if (shaderModel >= 4) std::string pixelSource = fragmentShaderGL->getTranslatedSource();
if (fragmentShader->usesFrontFacing())
{ {
angle::ReplaceSubstring(&pixelSource, std::string(PIXEL_MAIN_PARAMETERS_STUB_STRING), if (shaderModel >= 4)
"PS_INPUT input, bool isFrontFace : SV_IsFrontFace"); {
angle::ReplaceSubstring(&pixelSource,
std::string(PIXEL_MAIN_PARAMETERS_STUB_STRING),
"PS_INPUT input, bool isFrontFace : SV_IsFrontFace");
}
else
{
angle::ReplaceSubstring(&pixelSource,
std::string(PIXEL_MAIN_PARAMETERS_STUB_STRING),
"PS_INPUT input, float vFace : VFACE");
}
} }
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");
} }
}
else
{
angle::ReplaceSubstring(&pixelSource, std::string(PIXEL_MAIN_PARAMETERS_STUB_STRING),
"PS_INPUT input");
}
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 =
GetImplAs<ShaderGL>(mState.getAttachedShader(gl::ShaderType::Fragment));
const ShaderGL *geometryShaderGL = rx::SafeGetImplAs<ShaderGL, gl::Shader>(
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()); const ShaderGL *shaderGL =
rx::SafeGetImplAs<ShaderGL, gl::Shader>(mState.getAttachedShader(shaderType));
if (shaderGL)
{
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 =
GetImplAs<ShaderGL>(mState.getAttachedShader(gl::ShaderType::Fragment));
const ShaderGL *geometryShaderGL = rx::SafeGetImplAs<ShaderGL, gl::Shader>(
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()); const ShaderGL *shaderGL =
rx::SafeGetImplAs<ShaderGL>(mState.getAttachedShader(shaderType));
if (shaderGL)
{
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), {
&intermediateSources); CleanupUnusedEntities(useOldRewriteStructSamplers, programState, resources, shaderType,
&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