Commit fecd1afc by Tim Van Patten Committed by Commit Bot

Vulkan: Move necessary members from ProgramState to ProgramExecutable

ProgramPipeline's need to be able to link Programs before drawing, even if the Program's previous linkProgram() failed. To work towards this, some ProgramState members are being moved to ProgramExecutable so they can be saved when linkProgram() succeeds and not overwritten by any subsequent linkProgram() attempts that may fail. This also allows the second half of this change, which is to pass in the Program's ProgramExecutable to GlslangAssignLocations() and GlslangWrapperVk::TransformSpirV() so the values saved from the last successful linkProgram() are used. Bug: angleproject:4514 Test: CQ Change-Id: I68aa429be76c0c6e1b886be09a12200217fcc7ab Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2181448 Commit-Queue: Tim Van Patten <timvp@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 39d187b8
......@@ -25,7 +25,10 @@ ProgramExecutable::ProgramExecutable()
mActiveSamplersMask(0),
mActiveSamplerRefCounts{},
mActiveImagesMask(0),
mCanDrawWith(false)
mCanDrawWith(false),
mTransformFeedbackBufferMode(GL_INTERLEAVED_ATTRIBS),
mSamplerUniformRange(0, 0),
mImageUniformRange(0, 0)
{
mActiveSamplerTypes.fill(TextureType::InvalidEnum);
mActiveSamplerFormats.fill(SamplerFormat::InvalidEnum);
......@@ -47,6 +50,15 @@ void ProgramExecutable::reset()
mActiveSamplerFormats.fill(SamplerFormat::InvalidEnum);
mActiveImagesMask.reset();
mProgramInputs.clear();
mLinkedTransformFeedbackVaryings.clear();
mUniforms.clear();
mUniformBlocks.clear();
mShaderStorageBlocks.clear();
mAtomicCounterBuffers.clear();
mOutputVariables.clear();
mOutputLocations.clear();
}
void ProgramExecutable::load(gl::BinaryInputStream *stream)
......
......@@ -12,6 +12,9 @@
#include "BinaryStream.h"
#include "libANGLE/Caps.h"
#include "libANGLE/InfoLog.h"
#include "libANGLE/ProgramLinkedResources.h"
#include "libANGLE/Shader.h"
#include "libANGLE/Uniform.h"
#include "libANGLE/VaryingPacking.h"
#include "libANGLE/angletypes.h"
......@@ -53,6 +56,45 @@ struct ImageBinding
bool unreferenced;
};
// A varying with transform feedback enabled. If it's an array, either the whole array or one of its
// elements specified by 'arrayIndex' can set to be enabled.
struct TransformFeedbackVarying : public sh::ShaderVariable
{
TransformFeedbackVarying(const sh::ShaderVariable &varyingIn, GLuint arrayIndexIn)
: sh::ShaderVariable(varyingIn), arrayIndex(arrayIndexIn)
{
ASSERT(!isArrayOfArrays());
}
TransformFeedbackVarying(const sh::ShaderVariable &field, const sh::ShaderVariable &parent)
: arrayIndex(GL_INVALID_INDEX)
{
sh::ShaderVariable *thisVar = this;
*thisVar = field;
interpolation = parent.interpolation;
isInvariant = parent.isInvariant;
name = parent.name + "." + name;
mappedName = parent.mappedName + "." + mappedName;
}
std::string nameWithArrayIndex() const
{
std::stringstream fullNameStr;
fullNameStr << name;
if (arrayIndex != GL_INVALID_INDEX)
{
fullNameStr << "[" << arrayIndex << "]";
}
return fullNameStr.str();
}
GLsizei size() const
{
return (isArray() && arrayIndex == GL_INVALID_INDEX ? getOutermostArraySize() : 1);
}
GLuint arrayIndex;
};
class ProgramState;
class ProgramPipelineState;
......@@ -170,6 +212,67 @@ class ProgramExecutable
void updateCanDrawWith();
bool hasVertexAndFragmentShader() const { return mCanDrawWith; }
const std::vector<sh::ShaderVariable> &getProgramInputs() const { return mProgramInputs; }
const std::vector<sh::ShaderVariable> &getOutputVariables() const { return mOutputVariables; }
const std::vector<VariableLocation> &getOutputLocations() const { return mOutputLocations; }
const std::vector<LinkedUniform> &getUniforms() const { return mUniforms; }
const std::vector<InterfaceBlock> &getUniformBlocks() const { return mUniformBlocks; }
const RangeUI &getSamplerUniformRange() const { return mSamplerUniformRange; }
const RangeUI &getImageUniformRange() const { return mImageUniformRange; }
const std::vector<TransformFeedbackVarying> &getLinkedTransformFeedbackVaryings() const
{
return mLinkedTransformFeedbackVaryings;
}
GLint getTransformFeedbackBufferMode() const { return mTransformFeedbackBufferMode; }
GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const
{
ASSERT(uniformBlockIndex < mUniformBlocks.size());
return mUniformBlocks[uniformBlockIndex].binding;
}
GLuint getShaderStorageBlockBinding(GLuint blockIndex) const
{
ASSERT(blockIndex < mShaderStorageBlocks.size());
return mShaderStorageBlocks[blockIndex].binding;
}
const std::vector<GLsizei> &getTransformFeedbackStrides() const
{
return mTransformFeedbackStrides;
}
const std::vector<AtomicCounterBuffer> &getAtomicCounterBuffers() const
{
return mAtomicCounterBuffers;
}
const std::vector<InterfaceBlock> &getShaderStorageBlocks() const
{
return mShaderStorageBlocks;
}
const LinkedUniform &getUniformByIndex(GLuint index) const
{
ASSERT(index < static_cast<size_t>(mUniforms.size()));
return mUniforms[index];
}
ANGLE_INLINE GLuint getActiveUniformBlockCount() const
{
return static_cast<GLuint>(mUniformBlocks.size());
}
ANGLE_INLINE GLuint getActiveAtomicCounterBufferCount() const
{
return static_cast<GLuint>(mAtomicCounterBuffers.size());
}
ANGLE_INLINE GLuint getActiveShaderStorageBlockCount() const
{
return static_cast<GLuint>(mShaderStorageBlocks.size());
}
gl::ProgramLinkedResources &getResources() const
{
ASSERT(mResources);
return *mResources;
}
private:
// TODO(timvp): http://anglebug.com/3570: Investigate removing these friend
// class declarations and accessing the necessary members with getters/setters.
......@@ -211,6 +314,37 @@ class ProgramExecutable
ActiveTextureArray<ShaderBitSet> mActiveImageShaderBits;
bool mCanDrawWith;
// Names and mapped names of output variables that are arrays include [0] in the end, similarly
// to uniforms.
std::vector<sh::ShaderVariable> mOutputVariables;
std::vector<VariableLocation> mOutputLocations;
// Vertex attributes, Fragment input varyings, etc.
std::vector<sh::ShaderVariable> mProgramInputs;
std::vector<TransformFeedbackVarying> mLinkedTransformFeedbackVaryings;
// The size of the data written to each transform feedback buffer per vertex.
std::vector<GLsizei> mTransformFeedbackStrides;
GLenum mTransformFeedbackBufferMode;
// Uniforms are sorted in order:
// 1. Non-opaque uniforms
// 2. Sampler uniforms
// 3. Image uniforms
// 4. Atomic counter uniforms
// 5. Uniform block uniforms
// This makes opaque uniform validation easier, since we don't need a separate list.
// For generating the entries and naming them we follow the spec: GLES 3.1 November 2016 section
// 7.3.1.1 Naming Active Resources. There's a separate entry for each struct member and each
// inner array of an array of arrays. Names and mapped names of uniforms that are arrays include
// [0] in the end. This makes implementation of queries simpler.
std::vector<LinkedUniform> mUniforms;
RangeUI mSamplerUniformRange;
std::vector<InterfaceBlock> mUniformBlocks;
std::vector<AtomicCounterBuffer> mAtomicCounterBuffers;
RangeUI mImageUniformRange;
std::vector<InterfaceBlock> mShaderStorageBlocks;
// TODO: http://anglebug.com/4514: Remove
std::unique_ptr<gl::ProgramLinkedResources> mResources;
};
} // namespace gl
......
......@@ -498,8 +498,9 @@ angle::Result ProgramPipeline::link(const Context *context)
{
Program *program = mState.mPrograms[shaderType];
ASSERT(program);
program->getResources().varyingPacking.reset();
ANGLE_TRY(program->linkMergedVaryings(context, mergedVaryings));
program->getExecutable().getResources().varyingPacking.reset();
ANGLE_TRY(
program->linkMergedVaryings(context, program->getExecutable(), mergedVaryings));
}
}
......
......@@ -99,8 +99,7 @@ std::string GlslangGetMappedSamplerName(const std::string &originalName);
std::string GetXfbBufferName(const uint32_t bufferIndex);
void GlslangAssignLocations(GlslangSourceOptions &options,
const gl::ProgramState &programState,
const gl::ProgramLinkedResources &resources,
const gl::ProgramExecutable &programExecutable,
const gl::ShaderType shaderType,
GlslangProgramInterfaceInfo *programInterfaceInfo,
gl::ShaderMap<ShaderInterfaceVariableInfoMap> *variableInfoMapOut);
......
......@@ -80,7 +80,7 @@ angle::Result ProgramPipelineVk::link(const gl::Context *glContext)
glslangProgramInterfaceInfo.locationsUsedForXfbExtension =
programProgramInterfaceInfo.locationsUsedForXfbExtension;
GlslangAssignLocations(options, glProgram->getState(), glProgram->getResources(),
GlslangAssignLocations(options, glProgram->getState().getProgramExecutable(),
shaderType, &glslangProgramInterfaceInfo,
&mExecutable.getShaderInterfaceVariableInfoMap());
}
......
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