Commit 016105bb by Jiawei Shao Committed by Commit Bot

Store shader information in ShaderMap in class Program and Compiler

This patch is the first one in the series of using ShaderMap as the container of the resources for each type of shader everywhere in ANGLE. This patch defines the new data structure ShaderMap and use it in class Program and Compiler in ANGLE front-end. The following work includes: 1. Use ShaderMap in D3D back-ends. 2. Use ShaderMap in Vulkan back-ends. BUG=angleproject:2169 Change-Id: I1c284d95f5a071c45bb468901eabc15694fffe38 Reviewed-on: https://chromium-review.googlesource.com/1011722 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent 76b2c385
...@@ -55,10 +55,7 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const ContextState &state) ...@@ -55,10 +55,7 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const ContextState &state)
state.getExtensions().webglCompatibility)), state.getExtensions().webglCompatibility)),
mOutputType(mImplementation->getTranslatorOutputType()), mOutputType(mImplementation->getTranslatorOutputType()),
mResources(), mResources(),
mFragmentCompiler(nullptr), mShaderCompilers({})
mVertexCompiler(nullptr),
mComputeCompiler(nullptr),
mGeometryCompiler(nullptr)
{ {
ASSERT(state.getClientMajorVersion() == 2 || state.getClientMajorVersion() == 3); ASSERT(state.getClientMajorVersion() == 2 || state.getClientMajorVersion() == 3);
...@@ -156,40 +153,17 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const ContextState &state) ...@@ -156,40 +153,17 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const ContextState &state)
Compiler::~Compiler() Compiler::~Compiler()
{ {
if (mFragmentCompiler) for (ShaderType shaderType : AllShaderTypes())
{ {
sh::Destruct(mFragmentCompiler); ShHandle compilerHandle = mShaderCompilers[shaderType];
mFragmentCompiler = nullptr; if (compilerHandle)
{
ASSERT(activeCompilerHandles > 0); sh::Destruct(compilerHandle);
activeCompilerHandles--; mShaderCompilers[shaderType] = nullptr;
}
if (mVertexCompiler)
{
sh::Destruct(mVertexCompiler);
mVertexCompiler = nullptr;
ASSERT(activeCompilerHandles > 0);
activeCompilerHandles--;
}
if (mComputeCompiler)
{
sh::Destruct(mComputeCompiler);
mComputeCompiler = nullptr;
ASSERT(activeCompilerHandles > 0);
activeCompilerHandles--;
}
if (mGeometryCompiler)
{
sh::Destruct(mGeometryCompiler);
mGeometryCompiler = nullptr;
ASSERT(activeCompilerHandles > 0); ASSERT(activeCompilerHandles > 0);
activeCompilerHandles--; activeCompilerHandles--;
}
} }
if (activeCompilerHandles == 0) if (activeCompilerHandles == 0)
...@@ -202,26 +176,8 @@ Compiler::~Compiler() ...@@ -202,26 +176,8 @@ Compiler::~Compiler()
ShHandle Compiler::getCompilerHandle(ShaderType type) ShHandle Compiler::getCompilerHandle(ShaderType type)
{ {
ShHandle *compiler = nullptr; ASSERT(type != ShaderType::InvalidEnum);
switch (type) ShHandle *compiler = &mShaderCompilers[type];
{
case ShaderType::Vertex:
compiler = &mVertexCompiler;
break;
case ShaderType::Fragment:
compiler = &mFragmentCompiler;
break;
case ShaderType::Compute:
compiler = &mComputeCompiler;
break;
case ShaderType::Geometry:
compiler = &mGeometryCompiler;
break;
default:
UNREACHABLE();
return nullptr;
}
if (!(*compiler)) if (!(*compiler))
{ {
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#include "GLSLANG/ShaderLang.h" #include "GLSLANG/ShaderLang.h"
#include "libANGLE/Error.h" #include "libANGLE/Error.h"
#include "libANGLE/PackedGLEnums_autogen.h" #include "libANGLE/PackedGLEnums.h"
#include "libANGLE/RefCountObject.h" #include "libANGLE/RefCountObject.h"
namespace rx namespace rx
...@@ -41,10 +41,7 @@ class Compiler final : public RefCountObjectNoID ...@@ -41,10 +41,7 @@ class Compiler final : public RefCountObjectNoID
ShShaderOutput mOutputType; ShShaderOutput mOutputType;
ShBuiltInResources mResources; ShBuiltInResources mResources;
ShHandle mFragmentCompiler; ShaderMap<ShHandle> mShaderCompilers;
ShHandle mVertexCompiler;
ShHandle mComputeCompiler;
ShHandle mGeometryCompiler;
}; };
} // namespace gl } // namespace gl
......
...@@ -172,8 +172,16 @@ struct AllShaderTypes ...@@ -172,8 +172,16 @@ struct AllShaderTypes
angle::EnumIterator<ShaderType> end() const { return kAfterShaderTypeMax; } angle::EnumIterator<ShaderType> end() const { return kAfterShaderTypeMax; }
}; };
constexpr size_t kGraphicsShaderCount = static_cast<size_t>(ShaderType::EnumCount) - 1u;
// Arrange the shader types in the order of rendering pipeline
constexpr std::array<ShaderType, kGraphicsShaderCount> kAllGraphicsShaderTypes = {
ShaderType::Vertex, ShaderType::Geometry, ShaderType::Fragment};
using ShaderBitSet = angle::PackedEnumBitSet<ShaderType>; using ShaderBitSet = angle::PackedEnumBitSet<ShaderType>;
template <typename T>
using ShaderMap = angle::PackedEnumMap<ShaderType, T>;
TextureType SamplerTypeToTextureType(GLenum samplerType); TextureType SamplerTypeToTextureType(GLenum samplerType);
} // namespace gl } // namespace gl
......
...@@ -700,10 +700,7 @@ ImageBinding::~ImageBinding() = default; ...@@ -700,10 +700,7 @@ ImageBinding::~ImageBinding() = default;
// ProgramState implementation. // ProgramState implementation.
ProgramState::ProgramState() ProgramState::ProgramState()
: mLabel(), : mLabel(),
mAttachedFragmentShader(nullptr), mAttachedShaders({}),
mAttachedVertexShader(nullptr),
mAttachedComputeShader(nullptr),
mAttachedGeometryShader(nullptr),
mTransformFeedbackBufferMode(GL_INTERLEAVED_ATTRIBS), mTransformFeedbackBufferMode(GL_INTERLEAVED_ATTRIBS),
mMaxActiveAttribLocation(0), mMaxActiveAttribLocation(0),
mSamplerUniformRange(0, 0), mSamplerUniformRange(0, 0),
...@@ -722,8 +719,7 @@ ProgramState::ProgramState() ...@@ -722,8 +719,7 @@ ProgramState::ProgramState()
ProgramState::~ProgramState() ProgramState::~ProgramState()
{ {
ASSERT(!mAttachedVertexShader && !mAttachedFragmentShader && !mAttachedComputeShader && ASSERT(!hasAttachedShader());
!mAttachedGeometryShader);
} }
const std::string &ProgramState::getLabel() const std::string &ProgramState::getLabel()
...@@ -733,20 +729,8 @@ const std::string &ProgramState::getLabel() ...@@ -733,20 +729,8 @@ const std::string &ProgramState::getLabel()
Shader *ProgramState::getAttachedShader(ShaderType shaderType) const Shader *ProgramState::getAttachedShader(ShaderType shaderType) const
{ {
switch (shaderType) ASSERT(shaderType != ShaderType::InvalidEnum);
{ return mAttachedShaders[shaderType];
case ShaderType::Vertex:
return mAttachedVertexShader;
case ShaderType::Fragment:
return mAttachedFragmentShader;
case ShaderType::Compute:
return mAttachedComputeShader;
case ShaderType::Geometry:
return mAttachedGeometryShader;
default:
UNREACHABLE();
return nullptr;
}
} }
GLuint ProgramState::getUniformIndexFromName(const std::string &name) const GLuint ProgramState::getUniformIndexFromName(const std::string &name) const
...@@ -800,6 +784,18 @@ GLuint ProgramState::getAttributeLocation(const std::string &name) const ...@@ -800,6 +784,18 @@ GLuint ProgramState::getAttributeLocation(const std::string &name) const
return static_cast<GLuint>(-1); return static_cast<GLuint>(-1);
} }
bool ProgramState::hasAttachedShader() const
{
for (const Shader *shader : mAttachedShaders)
{
if (shader)
{
return true;
}
}
return false;
}
Program::Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, GLuint handle) Program::Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, GLuint handle)
: mProgram(factory->createProgram(mState)), : mProgram(factory->createProgram(mState)),
mValidated(false), mValidated(false),
...@@ -821,35 +817,19 @@ Program::~Program() ...@@ -821,35 +817,19 @@ Program::~Program()
void Program::onDestroy(const Context *context) void Program::onDestroy(const Context *context)
{ {
if (mState.mAttachedVertexShader != nullptr) for (ShaderType shaderType : AllShaderTypes())
{
mState.mAttachedVertexShader->release(context);
mState.mAttachedVertexShader = nullptr;
}
if (mState.mAttachedFragmentShader != nullptr)
{
mState.mAttachedFragmentShader->release(context);
mState.mAttachedFragmentShader = nullptr;
}
if (mState.mAttachedComputeShader != nullptr)
{
mState.mAttachedComputeShader->release(context);
mState.mAttachedComputeShader = nullptr;
}
if (mState.mAttachedGeometryShader != nullptr)
{ {
mState.mAttachedGeometryShader->release(context); if (mState.mAttachedShaders[shaderType])
mState.mAttachedGeometryShader = nullptr; {
mState.mAttachedShaders[shaderType]->release(context);
mState.mAttachedShaders[shaderType] = nullptr;
}
} }
// TODO(jmadill): Handle error in the Context. // TODO(jmadill): Handle error in the Context.
ANGLE_SWALLOW_ERR(mProgram->destroy(context)); ANGLE_SWALLOW_ERR(mProgram->destroy(context));
ASSERT(!mState.mAttachedVertexShader && !mState.mAttachedFragmentShader && ASSERT(!mState.hasAttachedShader());
!mState.mAttachedComputeShader && !mState.mAttachedGeometryShader);
SafeDelete(mProgram); SafeDelete(mProgram);
delete this; delete this;
...@@ -867,82 +847,35 @@ const std::string &Program::getLabel() const ...@@ -867,82 +847,35 @@ const std::string &Program::getLabel() const
void Program::attachShader(Shader *shader) void Program::attachShader(Shader *shader)
{ {
switch (shader->getType()) ShaderType shaderType = shader->getType();
{ ASSERT(shaderType != ShaderType::InvalidEnum);
case ShaderType::Vertex:
{ mState.mAttachedShaders[shaderType] = shader;
ASSERT(!mState.mAttachedVertexShader); mState.mAttachedShaders[shaderType]->addRef();
mState.mAttachedVertexShader = shader;
mState.mAttachedVertexShader->addRef();
break;
}
case ShaderType::Fragment:
{
ASSERT(!mState.mAttachedFragmentShader);
mState.mAttachedFragmentShader = shader;
mState.mAttachedFragmentShader->addRef();
break;
}
case ShaderType::Compute:
{
ASSERT(!mState.mAttachedComputeShader);
mState.mAttachedComputeShader = shader;
mState.mAttachedComputeShader->addRef();
break;
}
case ShaderType::Geometry:
{
ASSERT(!mState.mAttachedGeometryShader);
mState.mAttachedGeometryShader = shader;
mState.mAttachedGeometryShader->addRef();
break;
}
default:
UNREACHABLE();
}
} }
void Program::detachShader(const Context *context, Shader *shader) void Program::detachShader(const Context *context, Shader *shader)
{ {
switch (shader->getType()) ShaderType shaderType = shader->getType();
ASSERT(shaderType != ShaderType::InvalidEnum);
ASSERT(mState.mAttachedShaders[shaderType] == shader);
shader->release(context);
mState.mAttachedShaders[shaderType] = nullptr;
}
int Program::getAttachedShadersCount() const
{
int numAttachedShaders = 0;
for (const Shader *shader : mState.mAttachedShaders)
{ {
case ShaderType::Vertex: if (shader)
{
ASSERT(mState.mAttachedVertexShader == shader);
shader->release(context);
mState.mAttachedVertexShader = nullptr;
break;
}
case ShaderType::Fragment:
{
ASSERT(mState.mAttachedFragmentShader == shader);
shader->release(context);
mState.mAttachedFragmentShader = nullptr;
break;
}
case ShaderType::Compute:
{
ASSERT(mState.mAttachedComputeShader == shader);
shader->release(context);
mState.mAttachedComputeShader = nullptr;
break;
}
case ShaderType::Geometry:
{ {
ASSERT(mState.mAttachedGeometryShader == shader); ++numAttachedShaders;
shader->release(context);
mState.mAttachedGeometryShader = nullptr;
break;
} }
default:
UNREACHABLE();
} }
}
int Program::getAttachedShadersCount() const return numAttachedShaders;
{
return (mState.mAttachedVertexShader ? 1 : 0) + (mState.mAttachedFragmentShader ? 1 : 0) +
(mState.mAttachedComputeShader ? 1 : 0) + (mState.mAttachedGeometryShader ? 1 : 0);
} }
const Shader *Program::getAttachedShader(ShaderType shaderType) const const Shader *Program::getAttachedShader(ShaderType shaderType) const
...@@ -1079,7 +1012,7 @@ Error Program::link(const gl::Context *context) ...@@ -1079,7 +1012,7 @@ Error Program::link(const gl::Context *context)
// Re-link shaders after the unlink call. // Re-link shaders after the unlink call.
ASSERT(linkValidateShaders(context, mInfoLog)); ASSERT(linkValidateShaders(context, mInfoLog));
if (mState.mAttachedComputeShader) if (mState.mAttachedShaders[ShaderType::Compute])
{ {
if (!linkUniforms(context, mInfoLog, mUniformLocationBindings)) if (!linkUniforms(context, mInfoLog, mUniformLocationBindings))
{ {
...@@ -1135,8 +1068,8 @@ Error Program::link(const gl::Context *context) ...@@ -1135,8 +1068,8 @@ Error Program::link(const gl::Context *context)
const auto &mergedVaryings = getMergedVaryings(context); const auto &mergedVaryings = getMergedVaryings(context);
ASSERT(mState.mAttachedVertexShader); ASSERT(mState.mAttachedShaders[ShaderType::Vertex]);
mState.mNumViews = mState.mAttachedVertexShader->getNumViews(context); mState.mNumViews = mState.mAttachedShaders[ShaderType::Vertex]->getNumViews(context);
linkOutputVariables(context); linkOutputVariables(context);
...@@ -1212,24 +1145,12 @@ void Program::updateLinkedShaderStages() ...@@ -1212,24 +1145,12 @@ void Program::updateLinkedShaderStages()
{ {
mState.mLinkedShaderStages.reset(); mState.mLinkedShaderStages.reset();
if (mState.mAttachedVertexShader) for (const Shader *shader : mState.mAttachedShaders)
{ {
mState.mLinkedShaderStages.set(ShaderType::Vertex); if (shader)
} {
mState.mLinkedShaderStages.set(shader->getType());
if (mState.mAttachedFragmentShader) }
{
mState.mLinkedShaderStages.set(ShaderType::Fragment);
}
if (mState.mAttachedComputeShader)
{
mState.mLinkedShaderStages.set(ShaderType::Compute);
}
if (mState.mAttachedGeometryShader)
{
mState.mLinkedShaderStages.set(ShaderType::Geometry);
} }
} }
...@@ -1451,39 +1372,12 @@ void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shade ...@@ -1451,39 +1372,12 @@ void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shade
{ {
int total = 0; int total = 0;
if (mState.mAttachedComputeShader) for (const Shader *shader : mState.mAttachedShaders)
{ {
if (total < maxCount) if (shader && (total < maxCount))
{ {
shaders[total] = mState.mAttachedComputeShader->getHandle(); shaders[total] = shader->getHandle();
total++; ++total;
}
}
if (mState.mAttachedVertexShader)
{
if (total < maxCount)
{
shaders[total] = mState.mAttachedVertexShader->getHandle();
total++;
}
}
if (mState.mAttachedFragmentShader)
{
if (total < maxCount)
{
shaders[total] = mState.mAttachedFragmentShader->getHandle();
total++;
}
}
if (mState.mAttachedGeometryShader)
{
if (total < maxCount)
{
shaders[total] = mState.mAttachedGeometryShader->getHandle();
total++;
} }
} }
...@@ -2261,10 +2155,10 @@ GLenum Program::getTransformFeedbackBufferMode() const ...@@ -2261,10 +2155,10 @@ GLenum Program::getTransformFeedbackBufferMode() const
bool Program::linkValidateShaders(const Context *context, InfoLog &infoLog) bool Program::linkValidateShaders(const Context *context, InfoLog &infoLog)
{ {
Shader *vertexShader = mState.mAttachedVertexShader; Shader *vertexShader = mState.mAttachedShaders[ShaderType::Vertex];
Shader *fragmentShader = mState.mAttachedFragmentShader; Shader *fragmentShader = mState.mAttachedShaders[ShaderType::Fragment];
Shader *computeShader = mState.mAttachedComputeShader; Shader *computeShader = mState.mAttachedShaders[ShaderType::Compute];
Shader *geometryShader = mState.mAttachedGeometryShader; Shader *geometryShader = mState.mAttachedShaders[ShaderType::Geometry];
bool isComputeShaderAttached = (computeShader != nullptr); bool isComputeShaderAttached = (computeShader != nullptr);
bool isGraphicsShaderAttached = bool isGraphicsShaderAttached =
...@@ -2400,22 +2294,24 @@ const TransformFeedbackVarying &Program::getTransformFeedbackVaryingResource(GLu ...@@ -2400,22 +2294,24 @@ const TransformFeedbackVarying &Program::getTransformFeedbackVaryingResource(GLu
bool Program::linkVaryings(const Context *context, InfoLog &infoLog) const bool Program::linkVaryings(const Context *context, InfoLog &infoLog) const
{ {
std::vector<Shader *> activeShaders; Shader *previousShader = nullptr;
activeShaders.push_back(mState.mAttachedVertexShader); for (ShaderType shaderType : kAllGraphicsShaderTypes)
if (mState.mAttachedGeometryShader)
{ {
activeShaders.push_back(mState.mAttachedGeometryShader); Shader *currentShader = mState.mAttachedShaders[shaderType];
} if (!currentShader)
activeShaders.push_back(mState.mAttachedFragmentShader); {
continue;
}
const size_t activeShaderCount = activeShaders.size(); if (previousShader)
for (size_t shaderIndex = 0; shaderIndex < activeShaderCount - 1; ++shaderIndex)
{
if (!linkValidateShaderInterfaceMatching(context, activeShaders[shaderIndex],
activeShaders[shaderIndex + 1], infoLog))
{ {
return false; if (!linkValidateShaderInterfaceMatching(context, previousShader, currentShader,
infoLog))
{
return false;
}
} }
previousShader = currentShader;
} }
if (!linkValidateBuiltInVaryings(context, infoLog)) if (!linkValidateBuiltInVaryings(context, infoLog))
...@@ -2498,12 +2394,12 @@ bool Program::linkValidateShaderInterfaceMatching(const Context *context, ...@@ -2498,12 +2394,12 @@ bool Program::linkValidateShaderInterfaceMatching(const Context *context,
bool Program::linkValidateFragmentInputBindings(const Context *context, gl::InfoLog &infoLog) const bool Program::linkValidateFragmentInputBindings(const Context *context, gl::InfoLog &infoLog) const
{ {
ASSERT(mState.mAttachedFragmentShader); ASSERT(mState.mAttachedShaders[ShaderType::Fragment]);
std::map<GLuint, std::string> staticFragmentInputLocations; std::map<GLuint, std::string> staticFragmentInputLocations;
const std::vector<sh::Varying> &fragmentInputVaryings = const std::vector<sh::Varying> &fragmentInputVaryings =
mState.mAttachedFragmentShader->getInputVaryings(context); mState.mAttachedShaders[ShaderType::Fragment]->getInputVaryings(context);
for (const sh::Varying &input : fragmentInputVaryings) for (const sh::Varying &input : fragmentInputVaryings)
{ {
if (input.isBuiltIn() || !input.staticUse) if (input.isBuiltIn() || !input.staticUse)
...@@ -2812,9 +2708,9 @@ bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog) ...@@ -2812,9 +2708,9 @@ bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog)
{ {
const auto &caps = context->getCaps(); const auto &caps = context->getCaps();
if (mState.mAttachedComputeShader) if (mState.mAttachedShaders[ShaderType::Compute])
{ {
Shader &computeShader = *mState.mAttachedComputeShader; Shader &computeShader = *mState.mAttachedShaders[ShaderType::Compute];
const auto &computeUniformBlocks = computeShader.getUniformBlocks(context); const auto &computeUniformBlocks = computeShader.getUniformBlocks(context);
if (!ValidateInterfaceBlocksCount( if (!ValidateInterfaceBlocksCount(
...@@ -2837,8 +2733,8 @@ bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog) ...@@ -2837,8 +2733,8 @@ bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog)
return true; return true;
} }
Shader &vertexShader = *mState.mAttachedVertexShader; Shader &vertexShader = *mState.mAttachedShaders[ShaderType::Vertex];
Shader &fragmentShader = *mState.mAttachedFragmentShader; Shader &fragmentShader = *mState.mAttachedShaders[ShaderType::Fragment];
const auto &vertexUniformBlocks = vertexShader.getUniformBlocks(context); const auto &vertexUniformBlocks = vertexShader.getUniformBlocks(context);
const auto &fragmentUniformBlocks = fragmentShader.getUniformBlocks(context); const auto &fragmentUniformBlocks = fragmentShader.getUniformBlocks(context);
...@@ -2858,7 +2754,7 @@ bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog) ...@@ -2858,7 +2754,7 @@ bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog)
return false; return false;
} }
Shader *geometryShader = mState.mAttachedGeometryShader; Shader *geometryShader = mState.mAttachedShaders[ShaderType::Geometry];
if (geometryShader) if (geometryShader)
{ {
const auto &geometryUniformBlocks = geometryShader->getUniformBlocks(context); const auto &geometryUniformBlocks = geometryShader->getUniformBlocks(context);
...@@ -3029,8 +2925,8 @@ LinkMismatchError Program::LinkValidateVaryings(const sh::Varying &outputVarying ...@@ -3029,8 +2925,8 @@ LinkMismatchError Program::LinkValidateVaryings(const sh::Varying &outputVarying
bool Program::linkValidateBuiltInVaryings(const Context *context, InfoLog &infoLog) const bool Program::linkValidateBuiltInVaryings(const Context *context, InfoLog &infoLog) const
{ {
Shader *vertexShader = mState.mAttachedVertexShader; Shader *vertexShader = mState.mAttachedShaders[ShaderType::Vertex];
Shader *fragmentShader = mState.mAttachedFragmentShader; Shader *fragmentShader = mState.mAttachedShaders[ShaderType::Fragment];
const auto &vertexVaryings = vertexShader->getOutputVaryings(context); const auto &vertexVaryings = vertexShader->getOutputVaryings(context);
const auto &fragmentVaryings = fragmentShader->getInputVaryings(context); const auto &fragmentVaryings = fragmentShader->getInputVaryings(context);
int shaderVersion = vertexShader->getShaderVersion(context); int shaderVersion = vertexShader->getShaderVersion(context);
...@@ -3215,36 +3111,21 @@ bool Program::linkValidateTransformFeedback(const gl::Context *context, ...@@ -3215,36 +3111,21 @@ bool Program::linkValidateTransformFeedback(const gl::Context *context,
bool Program::linkValidateGlobalNames(const Context *context, InfoLog &infoLog) const bool Program::linkValidateGlobalNames(const Context *context, InfoLog &infoLog) const
{ {
const std::vector<sh::Uniform> &vertexUniforms =
mState.mAttachedVertexShader->getUniforms(context);
const std::vector<sh::Uniform> &fragmentUniforms =
mState.mAttachedFragmentShader->getUniforms(context);
const std::vector<sh::Uniform> *geometryUniforms =
(mState.mAttachedGeometryShader) ? &mState.mAttachedGeometryShader->getUniforms(context)
: nullptr;
const std::vector<sh::Attribute> &attributes = const std::vector<sh::Attribute> &attributes =
mState.mAttachedVertexShader->getActiveAttributes(context); mState.mAttachedShaders[ShaderType::Vertex]->getActiveAttributes(context);
for (const auto &attrib : attributes) for (const auto &attrib : attributes)
{ {
for (const auto &uniform : vertexUniforms) for (ShaderType shaderType : kAllGraphicsShaderTypes)
{
if (uniform.name == attrib.name)
{
infoLog << "Name conflicts between a uniform and an attribute: " << attrib.name;
return false;
}
}
for (const auto &uniform : fragmentUniforms)
{ {
if (uniform.name == attrib.name) Shader *shader = mState.mAttachedShaders[shaderType];
if (!shader)
{ {
infoLog << "Name conflicts between a uniform and an attribute: " << attrib.name; continue;
return false;
} }
}
if (geometryUniforms) const std::vector<sh::Uniform> &uniforms = shader->getUniforms(context);
{ for (const auto &uniform : uniforms)
for (const auto &uniform : *geometryUniforms)
{ {
if (uniform.name == attrib.name) if (uniform.name == attrib.name)
{ {
...@@ -3254,6 +3135,7 @@ bool Program::linkValidateGlobalNames(const Context *context, InfoLog &infoLog) ...@@ -3254,6 +3135,7 @@ bool Program::linkValidateGlobalNames(const Context *context, InfoLog &infoLog)
} }
} }
} }
return true; return true;
} }
...@@ -3297,12 +3179,14 @@ ProgramMergedVaryings Program::getMergedVaryings(const Context *context) const ...@@ -3297,12 +3179,14 @@ ProgramMergedVaryings Program::getMergedVaryings(const Context *context) const
{ {
ProgramMergedVaryings merged; ProgramMergedVaryings merged;
for (const sh::Varying &varying : mState.mAttachedVertexShader->getOutputVaryings(context)) for (const sh::Varying &varying :
mState.mAttachedShaders[ShaderType::Vertex]->getOutputVaryings(context))
{ {
merged[varying.name].vertex = &varying; merged[varying.name].vertex = &varying;
} }
for (const sh::Varying &varying : mState.mAttachedFragmentShader->getInputVaryings(context)) for (const sh::Varying &varying :
mState.mAttachedShaders[ShaderType::Fragment]->getInputVaryings(context))
{ {
merged[varying.name].fragment = &varying; merged[varying.name].fragment = &varying;
} }
...@@ -3312,7 +3196,7 @@ ProgramMergedVaryings Program::getMergedVaryings(const Context *context) const ...@@ -3312,7 +3196,7 @@ ProgramMergedVaryings Program::getMergedVaryings(const Context *context) const
void Program::linkOutputVariables(const Context *context) void Program::linkOutputVariables(const Context *context)
{ {
Shader *fragmentShader = mState.mAttachedFragmentShader; Shader *fragmentShader = mState.mAttachedShaders[ShaderType::Fragment];
ASSERT(fragmentShader != nullptr); ASSERT(fragmentShader != nullptr);
ASSERT(mState.mOutputVariableTypes.empty()); ASSERT(mState.mOutputVariableTypes.empty());
......
...@@ -352,6 +352,8 @@ class ProgramState final : angle::NonCopyable ...@@ -352,6 +352,8 @@ class ProgramState final : angle::NonCopyable
const ShaderBitSet &getLinkedShaderStages() const { return mLinkedShaderStages; } const ShaderBitSet &getLinkedShaderStages() const { return mLinkedShaderStages; }
bool hasAttachedShader() const;
private: private:
friend class MemoryProgramCache; friend class MemoryProgramCache;
friend class Program; friend class Program;
...@@ -362,10 +364,7 @@ class ProgramState final : angle::NonCopyable ...@@ -362,10 +364,7 @@ class ProgramState final : angle::NonCopyable
sh::WorkGroupSize mComputeShaderLocalSize; sh::WorkGroupSize mComputeShaderLocalSize;
Shader *mAttachedFragmentShader; ShaderMap<Shader *> mAttachedShaders;
Shader *mAttachedVertexShader;
Shader *mAttachedComputeShader;
Shader *mAttachedGeometryShader;
std::vector<std::string> mTransformFeedbackVaryingNames; std::vector<std::string> mTransformFeedbackVaryingNames;
std::vector<TransformFeedbackVarying> mLinkedTransformFeedbackVaryings; std::vector<TransformFeedbackVarying> mLinkedTransformFeedbackVaryings;
......
...@@ -188,27 +188,29 @@ bool UniformLinker::validateGraphicsUniforms(const Context *context, InfoLog &in ...@@ -188,27 +188,29 @@ bool UniformLinker::validateGraphicsUniforms(const Context *context, InfoLog &in
{ {
// Check that uniforms defined in the graphics shaders are identical // Check that uniforms defined in the graphics shaders are identical
std::map<std::string, ShaderUniform> linkedUniforms; std::map<std::string, ShaderUniform> linkedUniforms;
for (const sh::Uniform &vertexUniform :
mState.getAttachedShader(ShaderType::Vertex)->getUniforms(context))
{
linkedUniforms[vertexUniform.name] = std::make_pair(ShaderType::Vertex, &vertexUniform);
}
std::vector<Shader *> activeShadersToLink;
if (mState.getAttachedShader(ShaderType::Geometry))
{
activeShadersToLink.push_back(mState.getAttachedShader(ShaderType::Geometry));
}
activeShadersToLink.push_back(mState.getAttachedShader(ShaderType::Fragment));
const size_t numActiveShadersToLink = activeShadersToLink.size(); for (ShaderType shaderType : kAllGraphicsShaderTypes)
for (size_t shaderIndex = 0; shaderIndex < numActiveShadersToLink; ++shaderIndex)
{ {
bool isLastShader = (shaderIndex == numActiveShadersToLink - 1); Shader *currentShader = mState.getAttachedShader(shaderType);
if (!ValidateGraphicsUniformsPerShader(context, activeShadersToLink[shaderIndex], if (currentShader)
!isLastShader, &linkedUniforms, infoLog))
{ {
return false; if (shaderType == ShaderType::Vertex)
{
for (const sh::Uniform &vertexUniform : currentShader->getUniforms(context))
{
linkedUniforms[vertexUniform.name] =
std::make_pair(ShaderType::Vertex, &vertexUniform);
}
}
else
{
bool isLastShader = (shaderType == ShaderType::Fragment);
if (!ValidateGraphicsUniformsPerShader(context, currentShader, !isLastShader,
&linkedUniforms, infoLog))
{
return false;
}
}
} }
} }
...@@ -802,7 +804,7 @@ bool UniformLinker::checkMaxCombinedAtomicCounters(const Caps &caps, InfoLog &in ...@@ -802,7 +804,7 @@ bool UniformLinker::checkMaxCombinedAtomicCounters(const Caps &caps, InfoLog &in
// InterfaceBlockLinker implementation. // InterfaceBlockLinker implementation.
InterfaceBlockLinker::InterfaceBlockLinker(std::vector<InterfaceBlock> *blocksOut) InterfaceBlockLinker::InterfaceBlockLinker(std::vector<InterfaceBlock> *blocksOut)
: mBlocksOut(blocksOut) : mShaderBlocks({}), mBlocksOut(blocksOut)
{ {
} }
...@@ -810,10 +812,10 @@ InterfaceBlockLinker::~InterfaceBlockLinker() ...@@ -810,10 +812,10 @@ InterfaceBlockLinker::~InterfaceBlockLinker()
{ {
} }
void InterfaceBlockLinker::addShaderBlocks(ShaderType shader, void InterfaceBlockLinker::addShaderBlocks(ShaderType shaderType,
const std::vector<sh::InterfaceBlock> *blocks) const std::vector<sh::InterfaceBlock> *blocks)
{ {
mShaderBlocks.push_back(std::make_pair(shader, blocks)); mShaderBlocks[shaderType] = blocks;
} }
void InterfaceBlockLinker::linkBlocks(const GetBlockSize &getBlockSize, void InterfaceBlockLinker::linkBlocks(const GetBlockSize &getBlockSize,
...@@ -823,11 +825,14 @@ void InterfaceBlockLinker::linkBlocks(const GetBlockSize &getBlockSize, ...@@ -823,11 +825,14 @@ void InterfaceBlockLinker::linkBlocks(const GetBlockSize &getBlockSize,
std::set<std::string> visitedList; std::set<std::string> visitedList;
for (const auto &shaderBlocks : mShaderBlocks) for (ShaderType shaderType : AllShaderTypes())
{ {
const ShaderType shaderType = shaderBlocks.first; if (!mShaderBlocks[shaderType])
{
continue;
}
for (const auto &block : *shaderBlocks.second) for (const auto &block : *mShaderBlocks[shaderType])
{ {
if (!IsActiveInterfaceBlock(block)) if (!IsActiveInterfaceBlock(block))
continue; continue;
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#include "angle_gl.h" #include "angle_gl.h"
#include "common/angleutils.h" #include "common/angleutils.h"
#include "libANGLE/PackedGLEnums_autogen.h" #include "libANGLE/PackedGLEnums.h"
#include "libANGLE/VaryingPacking.h" #include "libANGLE/VaryingPacking.h"
#include <functional> #include <functional>
...@@ -234,8 +234,7 @@ class InterfaceBlockLinker : angle::NonCopyable ...@@ -234,8 +234,7 @@ class InterfaceBlockLinker : angle::NonCopyable
ShaderType shaderType, ShaderType shaderType,
bool active) const = 0; bool active) const = 0;
using ShaderBlocks = std::pair<ShaderType, const std::vector<sh::InterfaceBlock> *>; ShaderMap<const std::vector<sh::InterfaceBlock> *> mShaderBlocks;
std::vector<ShaderBlocks> mShaderBlocks;
std::vector<InterfaceBlock> *mBlocksOut; std::vector<InterfaceBlock> *mBlocksOut;
......
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