Commit 913f4f42 by Tim Van Patten Committed by Commit Bot

Vulkan: Support VS, FS, and CS in the same PPO

This CL adds support for a Program Pipeline Object to have a VS, FS, and CS attached to the same PPO and then using that PPO for both draw and dispatch calls. Bug: angleproject:3570 Test: KHR-GLES31.core.compute_shader.sso* Change-Id: I262cdbdfd442f6db5ba2b45d1308003102b237cb Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2150078Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Reviewed-by: 's avatarCourtney Goeltzenleuchter <courtneygo@google.com> Commit-Queue: Tim Van Patten <timvp@google.com>
parent 78dcba58
...@@ -3579,6 +3579,10 @@ ANGLE_INLINE angle::Result Context::prepareForCopyImage() ...@@ -3579,6 +3579,10 @@ ANGLE_INLINE angle::Result Context::prepareForCopyImage()
ANGLE_INLINE angle::Result Context::prepareForDispatch() ANGLE_INLINE angle::Result Context::prepareForDispatch()
{ {
// We always assume PPOs are used for draws, until they aren't. If we are executing a dispatch
// with a PPO, we need to convert it from a "draw"-type to "dispatch"-type.
convertPpoToComputeOrDraw(true);
ANGLE_TRY(syncDirtyObjects(mComputeDirtyObjects)); ANGLE_TRY(syncDirtyObjects(mComputeDirtyObjects));
return syncDirtyBits(mComputeDirtyBits); return syncDirtyBits(mComputeDirtyBits);
} }
...@@ -5516,11 +5520,35 @@ void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGr ...@@ -5516,11 +5520,35 @@ void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGr
} }
ANGLE_CONTEXT_TRY(prepareForDispatch()); ANGLE_CONTEXT_TRY(prepareForDispatch());
ANGLE_CONTEXT_TRY(mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ));
angle::Result result =
mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ);
// We always assume PPOs are used for draws, until they aren't. If we just executed a dispatch
// with a PPO, we need to convert it back to a "draw"-type.
convertPpoToComputeOrDraw(false);
if (ANGLE_UNLIKELY(IsError(result)))
{
return;
}
MarkShaderStorageBufferUsage(this); MarkShaderStorageBufferUsage(this);
} }
void Context::convertPpoToComputeOrDraw(bool isCompute)
{
Program *program = mState.getProgram();
ProgramPipeline *pipeline = mState.getProgramPipeline();
if (!program && pipeline)
{
pipeline->getExecutable().setIsCompute(isCompute);
pipeline->setDirtyBit(ProgramPipeline::DirtyBitType::DIRTY_BIT_DRAW_DISPATCH_CHANGE);
mState.mDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM_PIPELINE);
mState.mDirtyBits.set(State::DirtyBitType::DIRTY_BIT_PROGRAM_EXECUTABLE);
}
}
void Context::dispatchComputeIndirect(GLintptr indirect) void Context::dispatchComputeIndirect(GLintptr indirect)
{ {
ANGLE_CONTEXT_TRY(prepareForDispatch()); ANGLE_CONTEXT_TRY(prepareForDispatch());
......
...@@ -651,6 +651,8 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl ...@@ -651,6 +651,8 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
GLsizei count, GLsizei count,
const GLint *v); const GLint *v);
void convertPpoToComputeOrDraw(bool isCompute);
State mState; State mState;
bool mShared; bool mShared;
bool mSkipValidation; bool mSkipValidation;
......
...@@ -1211,20 +1211,12 @@ bool ProgramState::hasAttachedShader() const ...@@ -1211,20 +1211,12 @@ bool ProgramState::hasAttachedShader() const
ShaderType ProgramState::getFirstAttachedShaderStageType() const ShaderType ProgramState::getFirstAttachedShaderStageType() const
{ {
for (const gl::ShaderType shaderType : gl::kAllGraphicsShaderTypes) if (mExecutable.getLinkedShaderStages().none())
{ {
if (mExecutable.hasLinkedShaderStage(shaderType)) return ShaderType::InvalidEnum;
{
return shaderType;
}
} }
if (mExecutable.hasLinkedShaderStage(ShaderType::Compute)) return *mExecutable.getLinkedShaderStages().begin();
{
return ShaderType::Compute;
}
return ShaderType::InvalidEnum;
} }
ShaderType ProgramState::getLastAttachedShaderStageType() const ShaderType ProgramState::getLastAttachedShaderStageType() const
...@@ -1665,13 +1657,13 @@ void Program::resolveLinkImpl(const Context *context) ...@@ -1665,13 +1657,13 @@ void Program::resolveLinkImpl(const Context *context)
void Program::updateLinkedShaderStages() void Program::updateLinkedShaderStages()
{ {
mState.mExecutable.getLinkedShaderStages().reset(); mState.mExecutable.resetLinkedShaderStages();
for (const Shader *shader : mState.mAttachedShaders) for (const Shader *shader : mState.mAttachedShaders)
{ {
if (shader) if (shader)
{ {
mState.mExecutable.getLinkedShaderStages().set(shader->getType()); mState.mExecutable.setLinkedShaderStages(shader->getType());
} }
} }
} }
...@@ -5064,13 +5056,6 @@ angle::Result Program::serialize(const Context *context, angle::MemoryBuffer *bi ...@@ -5064,13 +5056,6 @@ angle::Result Program::serialize(const Context *context, angle::MemoryBuffer *bi
stream.writeInt(mState.mNumViews); stream.writeInt(mState.mNumViews);
stream.writeInt(mState.mEarlyFramentTestsOptimization); stream.writeInt(mState.mEarlyFramentTestsOptimization);
static_assert(MAX_VERTEX_ATTRIBS * 2 <= sizeof(uint32_t) * 8,
"All bits of mAttributesTypeMask types and mask fit into 32 bits each");
stream.writeInt(static_cast<int>(mState.mExecutable.mAttributesTypeMask.to_ulong()));
stream.writeInt(static_cast<int>(mState.mExecutable.mAttributesMask.to_ulong()));
stream.writeInt(mState.mExecutable.getActiveAttribLocationsMask().to_ulong());
stream.writeInt(mState.mExecutable.mMaxActiveAttribLocation);
stream.writeInt(mState.getProgramInputs().size()); stream.writeInt(mState.getProgramInputs().size());
for (const sh::ShaderVariable &attrib : mState.getProgramInputs()) for (const sh::ShaderVariable &attrib : mState.getProgramInputs())
{ {
...@@ -5216,7 +5201,7 @@ angle::Result Program::serialize(const Context *context, angle::MemoryBuffer *bi ...@@ -5216,7 +5201,7 @@ angle::Result Program::serialize(const Context *context, angle::MemoryBuffer *bi
stream.writeInt(mState.getAtomicCounterUniformRange().low()); stream.writeInt(mState.getAtomicCounterUniformRange().low());
stream.writeInt(mState.getAtomicCounterUniformRange().high()); stream.writeInt(mState.getAtomicCounterUniformRange().high());
stream.writeInt(mState.mExecutable.getLinkedShaderStages().to_ulong()); mState.mExecutable.save(&stream);
mProgram->save(context, &stream); mProgram->save(context, &stream);
...@@ -5265,14 +5250,6 @@ angle::Result Program::deserialize(const Context *context, ...@@ -5265,14 +5250,6 @@ angle::Result Program::deserialize(const Context *context,
mState.mNumViews = stream.readInt<int>(); mState.mNumViews = stream.readInt<int>();
mState.mEarlyFramentTestsOptimization = stream.readInt<bool>(); mState.mEarlyFramentTestsOptimization = stream.readInt<bool>();
static_assert(MAX_VERTEX_ATTRIBS * 2 <= sizeof(uint32_t) * 8,
"Too many vertex attribs for mask: All bits of mAttributesTypeMask types and "
"mask fit into 32 bits each");
mState.mExecutable.mAttributesTypeMask = gl::ComponentTypeMask(stream.readInt<uint32_t>());
mState.mExecutable.mAttributesMask = stream.readInt<gl::AttributesMask>();
mState.mExecutable.mActiveAttribLocationsMask = stream.readInt<gl::AttributesMask>();
mState.mExecutable.mMaxActiveAttribLocation = stream.readInt<unsigned int>();
unsigned int attribCount = stream.readInt<unsigned int>(); unsigned int attribCount = stream.readInt<unsigned int>();
ASSERT(mState.mProgramInputs.empty()); ASSERT(mState.mProgramInputs.empty());
for (unsigned int attribIndex = 0; attribIndex < attribCount; ++attribIndex) for (unsigned int attribIndex = 0; attribIndex < attribCount; ++attribIndex)
...@@ -5470,13 +5447,14 @@ angle::Result Program::deserialize(const Context *context, ...@@ -5470,13 +5447,14 @@ angle::Result Program::deserialize(const Context *context,
static_assert(static_cast<unsigned long>(ShaderType::EnumCount) <= sizeof(unsigned long) * 8, static_assert(static_cast<unsigned long>(ShaderType::EnumCount) <= sizeof(unsigned long) * 8,
"Too many shader types"); "Too many shader types");
mState.mExecutable.getLinkedShaderStages() = ShaderBitSet(stream.readInt<uint8_t>());
if (!mState.mAttachedShaders[ShaderType::Compute]) if (!mState.mAttachedShaders[ShaderType::Compute])
{ {
mState.updateTransformFeedbackStrides(); mState.updateTransformFeedbackStrides();
} }
mState.mExecutable.load(&stream);
postResolveLink(context); postResolveLink(context);
return angle::Result::Continue; return angle::Result::Continue;
......
...@@ -353,6 +353,10 @@ class ProgramState final : angle::NonCopyable ...@@ -353,6 +353,10 @@ class ProgramState final : angle::NonCopyable
return mAttachedShadersMarkedForDetach[shaderType]; return mAttachedShadersMarkedForDetach[shaderType];
} }
// A Program can only either be graphics or compute, but never both, so it
// can answer isCompute() based on which shaders it has.
bool isCompute() const { return mExecutable.hasLinkedShaderStage(ShaderType::Compute); }
private: private:
friend class MemoryProgramCache; friend class MemoryProgramCache;
friend class Program; friend class Program;
......
...@@ -48,6 +48,33 @@ void ProgramExecutable::reset() ...@@ -48,6 +48,33 @@ void ProgramExecutable::reset()
mActiveImagesMask.reset(); mActiveImagesMask.reset();
} }
void ProgramExecutable::load(gl::BinaryInputStream *stream)
{
static_assert(MAX_VERTEX_ATTRIBS * 2 <= sizeof(uint32_t) * 8,
"Too many vertex attribs for mask: All bits of mAttributesTypeMask types and "
"mask fit into 32 bits each");
mAttributesTypeMask = gl::ComponentTypeMask(stream->readInt<uint32_t>());
mAttributesMask = stream->readInt<gl::AttributesMask>();
mActiveAttribLocationsMask = stream->readInt<gl::AttributesMask>();
mMaxActiveAttribLocation = stream->readInt<unsigned int>();
mLinkedGraphicsShaderStages = ShaderBitSet(stream->readInt<uint8_t>());
mLinkedComputeShaderStages = ShaderBitSet(stream->readInt<uint8_t>());
}
void ProgramExecutable::save(gl::BinaryOutputStream *stream) const
{
static_assert(MAX_VERTEX_ATTRIBS * 2 <= sizeof(uint32_t) * 8,
"All bits of mAttributesTypeMask types and mask fit into 32 bits each");
stream->writeInt(static_cast<int>(mAttributesTypeMask.to_ulong()));
stream->writeInt(static_cast<int>(mAttributesMask.to_ulong()));
stream->writeInt(mActiveAttribLocationsMask.to_ulong());
stream->writeInt(mMaxActiveAttribLocation);
stream->writeInt(mLinkedGraphicsShaderStages.bits());
stream->writeInt(mLinkedComputeShaderStages.bits());
}
const ProgramState *ProgramExecutable::getProgramState(ShaderType shaderType) const const ProgramState *ProgramExecutable::getProgramState(ShaderType shaderType) const
{ {
if (mProgramState && if (mProgramState &&
...@@ -64,6 +91,30 @@ const ProgramState *ProgramExecutable::getProgramState(ShaderType shaderType) co ...@@ -64,6 +91,30 @@ const ProgramState *ProgramExecutable::getProgramState(ShaderType shaderType) co
return nullptr; return nullptr;
} }
bool ProgramExecutable::isCompute() const
{
ASSERT(mProgramState || mProgramPipelineState);
if (mProgramState)
{
return mProgramState->isCompute();
}
return mProgramPipelineState->isCompute();
}
void ProgramExecutable::setIsCompute(bool isComputeIn)
{
// A Program can only either be graphics or compute, but never both, so it can answer
// isCompute() based on which shaders it has. However, a PPO can have both graphics and compute
// programs attached, so we don't know if the PPO is a 'graphics' or 'compute' PPO until the
// actual draw/dispatch call, which is why only PPOs need to record the type of call here.
if (mProgramPipelineState)
{
mProgramPipelineState->setIsCompute(isComputeIn);
}
}
int ProgramExecutable::getInfoLogLength() const int ProgramExecutable::getInfoLogLength() const
{ {
return static_cast<int>(mInfoLog.getLength()); return static_cast<int>(mInfoLog.getLength());
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#ifndef LIBANGLE_PROGRAMEXECUTABLE_H_ #ifndef LIBANGLE_PROGRAMEXECUTABLE_H_
#define LIBANGLE_PROGRAMEXECUTABLE_H_ #define LIBANGLE_PROGRAMEXECUTABLE_H_
#include "BinaryStream.h"
#include "libANGLE/Caps.h" #include "libANGLE/Caps.h"
#include "libANGLE/InfoLog.h" #include "libANGLE/InfoLog.h"
#include "libANGLE/VaryingPacking.h" #include "libANGLE/VaryingPacking.h"
...@@ -63,6 +64,9 @@ class ProgramExecutable ...@@ -63,6 +64,9 @@ class ProgramExecutable
void reset(); void reset();
void save(gl::BinaryOutputStream *stream) const;
void load(gl::BinaryInputStream *stream);
const ProgramState *getProgramState(ShaderType shaderType) const; const ProgramState *getProgramState(ShaderType shaderType) const;
int getInfoLogLength() const; int getInfoLogLength() const;
...@@ -71,15 +75,38 @@ class ProgramExecutable ...@@ -71,15 +75,38 @@ class ProgramExecutable
std::string getInfoLogString() const; std::string getInfoLogString() const;
void resetInfoLog() { mInfoLog.reset(); } void resetInfoLog() { mInfoLog.reset(); }
const ShaderBitSet &getLinkedShaderStages() const { return mLinkedShaderStages; } void resetLinkedShaderStages()
ShaderBitSet &getLinkedShaderStages() { return mLinkedShaderStages; } {
mLinkedComputeShaderStages.reset();
mLinkedGraphicsShaderStages.reset();
}
const ShaderBitSet &getLinkedShaderStages() const
{
return isCompute() ? mLinkedComputeShaderStages : mLinkedGraphicsShaderStages;
}
void setLinkedShaderStages(ShaderType shaderType)
{
if (shaderType == ShaderType::Compute)
{
mLinkedComputeShaderStages.set(ShaderType::Compute);
}
else
{
mLinkedGraphicsShaderStages.set(shaderType);
}
}
bool hasLinkedShaderStage(ShaderType shaderType) const bool hasLinkedShaderStage(ShaderType shaderType) const
{ {
ASSERT(shaderType != ShaderType::InvalidEnum); ASSERT(shaderType != ShaderType::InvalidEnum);
return mLinkedShaderStages[shaderType]; return (shaderType == ShaderType::Compute) ? mLinkedComputeShaderStages[shaderType]
: mLinkedGraphicsShaderStages[shaderType];
} }
size_t getLinkedShaderStageCount() const { return mLinkedShaderStages.count(); } size_t getLinkedShaderStageCount() const
bool isCompute() const { return hasLinkedShaderStage(ShaderType::Compute); } {
return isCompute() ? mLinkedComputeShaderStages.count()
: mLinkedGraphicsShaderStages.count();
}
bool isCompute() const;
const AttributesMask &getActiveAttribLocationsMask() const const AttributesMask &getActiveAttribLocationsMask() const
{ {
...@@ -136,6 +163,8 @@ class ProgramExecutable ...@@ -136,6 +163,8 @@ class ProgramExecutable
mProgramPipelineState = state; mProgramPipelineState = state;
} }
void setIsCompute(bool isComputeIn);
private: private:
// TODO(timvp): http://anglebug.com/3570: Investigate removing these friend // TODO(timvp): http://anglebug.com/3570: Investigate removing these friend
// class declarations and accessing the necessary members with getters/setters. // class declarations and accessing the necessary members with getters/setters.
...@@ -156,7 +185,8 @@ class ProgramExecutable ...@@ -156,7 +185,8 @@ class ProgramExecutable
InfoLog mInfoLog; InfoLog mInfoLog;
ShaderBitSet mLinkedShaderStages; ShaderBitSet mLinkedGraphicsShaderStages;
ShaderBitSet mLinkedComputeShaderStages;
angle::BitSet<MAX_VERTEX_ATTRIBS> mActiveAttribLocationsMask; angle::BitSet<MAX_VERTEX_ATTRIBS> mActiveAttribLocationsMask;
unsigned int mMaxActiveAttribLocation; unsigned int mMaxActiveAttribLocation;
......
...@@ -23,7 +23,11 @@ namespace gl ...@@ -23,7 +23,11 @@ namespace gl
{ {
ProgramPipelineState::ProgramPipelineState() ProgramPipelineState::ProgramPipelineState()
: mLabel(), mActiveShaderProgram(nullptr), mValid(false), mHasBeenBound(false) : mLabel(),
mIsCompute(false),
mActiveShaderProgram(nullptr),
mValid(false),
mHasBeenBound(false)
{ {
mExecutable.setProgramPipelineState(this); mExecutable.setProgramPipelineState(this);
...@@ -118,7 +122,7 @@ bool ProgramPipelineState::usesShaderProgram(ShaderProgramID programId) const ...@@ -118,7 +122,7 @@ bool ProgramPipelineState::usesShaderProgram(ShaderProgramID programId) const
bool ProgramPipelineState::hasDefaultUniforms() const bool ProgramPipelineState::hasDefaultUniforms() const
{ {
for (const gl::ShaderType shaderType : gl::AllShaderTypes()) for (const gl::ShaderType shaderType : mExecutable.getLinkedShaderStages())
{ {
const Program *shaderProgram = getShaderProgram(shaderType); const Program *shaderProgram = getShaderProgram(shaderType);
if (shaderProgram && shaderProgram->getState().hasDefaultUniforms()) if (shaderProgram && shaderProgram->getState().hasDefaultUniforms())
...@@ -132,7 +136,7 @@ bool ProgramPipelineState::hasDefaultUniforms() const ...@@ -132,7 +136,7 @@ bool ProgramPipelineState::hasDefaultUniforms() const
bool ProgramPipelineState::hasTextures() const bool ProgramPipelineState::hasTextures() const
{ {
for (const gl::ShaderType shaderType : gl::AllShaderTypes()) for (const gl::ShaderType shaderType : mExecutable.getLinkedShaderStages())
{ {
const Program *shaderProgram = getShaderProgram(shaderType); const Program *shaderProgram = getShaderProgram(shaderType);
if (shaderProgram && shaderProgram->getState().hasTextures()) if (shaderProgram && shaderProgram->getState().hasTextures())
...@@ -146,7 +150,7 @@ bool ProgramPipelineState::hasTextures() const ...@@ -146,7 +150,7 @@ bool ProgramPipelineState::hasTextures() const
bool ProgramPipelineState::hasUniformBuffers() const bool ProgramPipelineState::hasUniformBuffers() const
{ {
for (const gl::ShaderType shaderType : gl::AllShaderTypes()) for (const gl::ShaderType shaderType : mExecutable.getLinkedShaderStages())
{ {
const Program *shaderProgram = getShaderProgram(shaderType); const Program *shaderProgram = getShaderProgram(shaderType);
if (shaderProgram && shaderProgram->getState().hasUniformBuffers()) if (shaderProgram && shaderProgram->getState().hasUniformBuffers())
...@@ -160,7 +164,7 @@ bool ProgramPipelineState::hasUniformBuffers() const ...@@ -160,7 +164,7 @@ bool ProgramPipelineState::hasUniformBuffers() const
bool ProgramPipelineState::hasStorageBuffers() const bool ProgramPipelineState::hasStorageBuffers() const
{ {
for (const gl::ShaderType shaderType : gl::AllShaderTypes()) for (const gl::ShaderType shaderType : mExecutable.getLinkedShaderStages())
{ {
const Program *shaderProgram = getShaderProgram(shaderType); const Program *shaderProgram = getShaderProgram(shaderType);
if (shaderProgram && shaderProgram->getState().hasStorageBuffers()) if (shaderProgram && shaderProgram->getState().hasStorageBuffers())
...@@ -174,7 +178,7 @@ bool ProgramPipelineState::hasStorageBuffers() const ...@@ -174,7 +178,7 @@ bool ProgramPipelineState::hasStorageBuffers() const
bool ProgramPipelineState::hasAtomicCounterBuffers() const bool ProgramPipelineState::hasAtomicCounterBuffers() const
{ {
for (const gl::ShaderType shaderType : gl::AllShaderTypes()) for (const gl::ShaderType shaderType : mExecutable.getLinkedShaderStages())
{ {
const Program *shaderProgram = getShaderProgram(shaderType); const Program *shaderProgram = getShaderProgram(shaderType);
if (shaderProgram && shaderProgram->getState().hasAtomicCounterBuffers()) if (shaderProgram && shaderProgram->getState().hasAtomicCounterBuffers())
...@@ -188,7 +192,7 @@ bool ProgramPipelineState::hasAtomicCounterBuffers() const ...@@ -188,7 +192,7 @@ bool ProgramPipelineState::hasAtomicCounterBuffers() const
bool ProgramPipelineState::hasImages() const bool ProgramPipelineState::hasImages() const
{ {
for (const gl::ShaderType shaderType : gl::AllShaderTypes()) for (const gl::ShaderType shaderType : mExecutable.getLinkedShaderStages())
{ {
const Program *shaderProgram = getShaderProgram(shaderType); const Program *shaderProgram = getShaderProgram(shaderType);
if (shaderProgram && shaderProgram->getState().hasImages()) if (shaderProgram && shaderProgram->getState().hasImages())
...@@ -202,7 +206,7 @@ bool ProgramPipelineState::hasImages() const ...@@ -202,7 +206,7 @@ bool ProgramPipelineState::hasImages() const
bool ProgramPipelineState::hasTransformFeedbackOutput() const bool ProgramPipelineState::hasTransformFeedbackOutput() const
{ {
for (const gl::ShaderType shaderType : gl::AllShaderTypes()) for (const gl::ShaderType shaderType : mExecutable.getLinkedShaderStages())
{ {
const Program *shaderProgram = getShaderProgram(shaderType); const Program *shaderProgram = getShaderProgram(shaderType);
if (shaderProgram && shaderProgram->getState().hasTransformFeedbackOutput()) if (shaderProgram && shaderProgram->getState().hasTransformFeedbackOutput())
...@@ -273,13 +277,14 @@ void ProgramPipeline::useProgramStages(const Context *context, ...@@ -273,13 +277,14 @@ void ProgramPipeline::useProgramStages(const Context *context,
void ProgramPipeline::updateLinkedShaderStages() void ProgramPipeline::updateLinkedShaderStages()
{ {
mState.mExecutable.mLinkedShaderStages.reset(); mState.mExecutable.resetLinkedShaderStages();
for (const ShaderType shaderType : gl::AllShaderTypes()) for (const ShaderType shaderType : gl::AllShaderTypes())
{ {
if (mState.mPrograms[shaderType]) Program *program = mState.mPrograms[shaderType];
if (program)
{ {
mState.mExecutable.mLinkedShaderStages.set(shaderType); mState.mExecutable.setLinkedShaderStages(shaderType);
} }
} }
} }
...@@ -302,7 +307,7 @@ void ProgramPipeline::updateExecutableAttributes() ...@@ -302,7 +307,7 @@ void ProgramPipeline::updateExecutableAttributes()
void ProgramPipeline::updateExecutableTextures() void ProgramPipeline::updateExecutableTextures()
{ {
for (const ShaderType shaderType : gl::AllShaderTypes()) for (const ShaderType shaderType : mState.mExecutable.getLinkedShaderStages())
{ {
const Program *program = getShaderProgram(shaderType); const Program *program = getShaderProgram(shaderType);
if (program) if (program)
...@@ -342,15 +347,13 @@ ProgramMergedVaryings ProgramPipeline::getMergedVaryings() const ...@@ -342,15 +347,13 @@ ProgramMergedVaryings ProgramPipeline::getMergedVaryings() const
// Note that kAllGraphicsShaderTypes is sorted according to the rendering pipeline. // Note that kAllGraphicsShaderTypes is sorted according to the rendering pipeline.
ShaderType lastActiveStage = ShaderType::InvalidEnum; ShaderType lastActiveStage = ShaderType::InvalidEnum;
for (ShaderType stage : kAllGraphicsShaderTypes) for (ShaderType shaderType : getExecutable().getLinkedShaderStages())
{ {
previousActiveStage[stage] = lastActiveStage; previousActiveStage[shaderType] = lastActiveStage;
const Program *program = getShaderProgram(stage); const Program *program = getShaderProgram(shaderType);
if (program) ASSERT(program);
{ lastActiveStage = shaderType;
lastActiveStage = stage;
}
} }
// First, go through output varyings and create two maps (one by name, one by location) for // First, go through output varyings and create two maps (one by name, one by location) for
...@@ -362,18 +365,12 @@ ProgramMergedVaryings ProgramPipeline::getMergedVaryings() const ...@@ -362,18 +365,12 @@ ProgramMergedVaryings ProgramPipeline::getMergedVaryings() const
ProgramMergedVaryings merged; ProgramMergedVaryings merged;
// Gather output varyings. // Gather output varyings.
for (ShaderType shaderType : kAllGraphicsShaderTypes) for (ShaderType shaderType : getExecutable().getLinkedShaderStages())
{ {
const Program *program = getShaderProgram(shaderType); const Program *program = getShaderProgram(shaderType);
if (!program) ASSERT(program);
{
continue;
}
Shader *shader = program->getState().getAttachedShader(shaderType); Shader *shader = program->getState().getAttachedShader(shaderType);
if (!shader) ASSERT(shader);
{
continue;
}
for (const sh::ShaderVariable &varying : shader->getOutputVaryings()) for (const sh::ShaderVariable &varying : shader->getOutputVaryings())
{ {
...@@ -397,18 +394,12 @@ ProgramMergedVaryings ProgramPipeline::getMergedVaryings() const ...@@ -397,18 +394,12 @@ ProgramMergedVaryings ProgramPipeline::getMergedVaryings() const
} }
// Gather input varyings, and match them with output varyings of the previous stage. // Gather input varyings, and match them with output varyings of the previous stage.
for (ShaderType shaderType : kAllGraphicsShaderTypes) for (ShaderType shaderType : getExecutable().getLinkedShaderStages())
{ {
const Program *program = getShaderProgram(shaderType); const Program *program = getShaderProgram(shaderType);
if (!program) ASSERT(program);
{
continue;
}
Shader *shader = program->getState().getAttachedShader(shaderType); Shader *shader = program->getState().getAttachedShader(shaderType);
if (!shader) ASSERT(shader);
{
continue;
}
ShaderType previousStage = previousActiveStage[shaderType]; ShaderType previousStage = previousActiveStage[shaderType];
for (const sh::ShaderVariable &varying : shader->getInputVaryings()) for (const sh::ShaderVariable &varying : shader->getInputVaryings())
...@@ -497,14 +488,12 @@ angle::Result ProgramPipeline::link(const Context *context) ...@@ -497,14 +488,12 @@ angle::Result ProgramPipeline::link(const Context *context)
VaryingPacking varyingPacking(maxVaryingVectors, packMode); VaryingPacking varyingPacking(maxVaryingVectors, packMode);
const ProgramMergedVaryings &mergedVaryings = getMergedVaryings(); const ProgramMergedVaryings &mergedVaryings = getMergedVaryings();
for (ShaderType shaderType : kAllGraphicsShaderTypes) for (ShaderType shaderType : getExecutable().getLinkedShaderStages())
{ {
Program *program = mState.mPrograms[shaderType]; Program *program = mState.mPrograms[shaderType];
if (program) ASSERT(program);
{ program->getResources().varyingPacking.reset();
program->getResources().varyingPacking.reset(); ANGLE_TRY(program->linkMergedVaryings(context, mergedVaryings));
ANGLE_TRY(program->linkMergedVaryings(context, mergedVaryings));
}
} }
} }
...@@ -516,13 +505,10 @@ angle::Result ProgramPipeline::link(const Context *context) ...@@ -516,13 +505,10 @@ angle::Result ProgramPipeline::link(const Context *context)
bool ProgramPipeline::linkVaryings(InfoLog &infoLog) const bool ProgramPipeline::linkVaryings(InfoLog &infoLog) const
{ {
Shader *previousShader = nullptr; Shader *previousShader = nullptr;
for (ShaderType shaderType : kAllGraphicsShaderTypes) for (ShaderType shaderType : getExecutable().getLinkedShaderStages())
{ {
Program *currentProgram = mState.mPrograms[shaderType]; Program *currentProgram = mState.mPrograms[shaderType];
if (!currentProgram) ASSERT(currentProgram);
{
continue;
}
Shader *currentShader = Shader *currentShader =
const_cast<Shader *>(currentProgram->getState().getAttachedShader(shaderType)); const_cast<Shader *>(currentProgram->getState().getAttachedShader(shaderType));
...@@ -563,7 +549,7 @@ void ProgramPipeline::validate(const gl::Context *context) ...@@ -563,7 +549,7 @@ void ProgramPipeline::validate(const gl::Context *context)
InfoLog &infoLog = mState.mExecutable.getInfoLog(); InfoLog &infoLog = mState.mExecutable.getInfoLog();
infoLog.reset(); infoLog.reset();
for (const ShaderType shaderType : gl::AllShaderTypes()) for (const ShaderType shaderType : mState.mExecutable.getLinkedShaderStages())
{ {
Program *shaderProgram = mState.mPrograms[shaderType]; Program *shaderProgram = mState.mPrograms[shaderType];
if (shaderProgram) if (shaderProgram)
...@@ -591,17 +577,15 @@ void ProgramPipeline::validate(const gl::Context *context) ...@@ -591,17 +577,15 @@ void ProgramPipeline::validate(const gl::Context *context)
{ {
mState.mValid = false; mState.mValid = false;
for (const ShaderType shaderType : gl::AllShaderTypes()) for (const ShaderType shaderType : mState.mExecutable.getLinkedShaderStages())
{ {
Program *shaderProgram = mState.mPrograms[shaderType]; Program *shaderProgram = mState.mPrograms[shaderType];
if (shaderProgram) ASSERT(shaderProgram);
shaderProgram->validate(caps);
std::string shaderInfoString = shaderProgram->getExecutable().getInfoLogString();
if (shaderInfoString.length())
{ {
shaderProgram->validate(caps); infoLog << shaderInfoString << "\n";
std::string shaderInfoString = shaderProgram->getExecutable().getInfoLogString();
if (shaderInfoString.length())
{
infoLog << shaderInfoString << "\n";
}
} }
} }
} }
......
...@@ -38,6 +38,12 @@ class ProgramPipelineState final : angle::NonCopyable ...@@ -38,6 +38,12 @@ class ProgramPipelineState final : angle::NonCopyable
const std::string &getLabel() const; const std::string &getLabel() const;
// A PPO can have both graphics and compute programs attached, so
// we don't know if the PPO is a 'graphics' or 'compute' PPO until the
// actual draw/dispatch call.
bool isCompute() const { return mIsCompute; }
void setIsCompute(bool isCompute) { mIsCompute = isCompute; }
const ProgramExecutable &getProgramExecutable() const { return mExecutable; } const ProgramExecutable &getProgramExecutable() const { return mExecutable; }
ProgramExecutable &getProgramExecutable() { return mExecutable; } ProgramExecutable &getProgramExecutable() { return mExecutable; }
...@@ -67,6 +73,8 @@ class ProgramPipelineState final : angle::NonCopyable ...@@ -67,6 +73,8 @@ class ProgramPipelineState final : angle::NonCopyable
std::string mLabel; std::string mLabel;
bool mIsCompute;
// The active shader program // The active shader program
Program *mActiveShaderProgram; Program *mActiveShaderProgram;
// The shader programs for each stage. // The shader programs for each stage.
...@@ -140,9 +148,9 @@ class ProgramPipeline final : public RefCountObject<ProgramPipelineID>, public L ...@@ -140,9 +148,9 @@ class ProgramPipeline final : public RefCountObject<ProgramPipelineID>, public L
{ {
// One of the program stages in the PPO changed. // One of the program stages in the PPO changed.
DIRTY_BIT_PROGRAM_STAGE, DIRTY_BIT_PROGRAM_STAGE,
DIRTY_BIT_DUMMY, // Used to make DIRTY_BIT_COUNT > 0 DIRTY_BIT_DRAW_DISPATCH_CHANGE,
DIRTY_BIT_COUNT = DIRTY_BIT_DUMMY, DIRTY_BIT_COUNT = DIRTY_BIT_DRAW_DISPATCH_CHANGE + 1,
}; };
using DirtyBits = angle::BitSet<DIRTY_BIT_COUNT>; using DirtyBits = angle::BitSet<DIRTY_BIT_COUNT>;
......
...@@ -1817,7 +1817,6 @@ angle::Result State::useProgramStages(const Context *context, ...@@ -1817,7 +1817,6 @@ angle::Result State::useProgramStages(const Context *context,
{ {
programPipeline->useProgramStages(context, stages, shaderProgram); programPipeline->useProgramStages(context, stages, shaderProgram);
ANGLE_TRY(onProgramPipelineExecutableChange(context, programPipeline)); ANGLE_TRY(onProgramPipelineExecutableChange(context, programPipeline));
mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_PIPELINE);
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -3273,7 +3272,7 @@ angle::Result State::onProgramPipelineExecutableChange(const Context *context, ...@@ -3273,7 +3272,7 @@ angle::Result State::onProgramPipelineExecutableChange(const Context *context,
if (programPipeline->hasAnyDirtyBit()) if (programPipeline->hasAnyDirtyBit())
{ {
mDirtyObjects.set(DIRTY_OBJECT_PROGRAM); mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_PIPELINE);
} }
// Set any bound textures. // Set any bound textures.
......
...@@ -1966,6 +1966,7 @@ angle::Result GlslangTransformSpirvCode(const GlslangErrorCallback &callback, ...@@ -1966,6 +1966,7 @@ angle::Result GlslangTransformSpirvCode(const GlslangErrorCallback &callback,
} }
angle::Result GlslangGetShaderSpirvCode(const GlslangErrorCallback &callback, angle::Result GlslangGetShaderSpirvCode(const GlslangErrorCallback &callback,
const gl::ShaderBitSet &linkedShaderStages,
const gl::Caps &glCaps, const gl::Caps &glCaps,
const gl::ShaderMap<std::string> &shaderSources, const gl::ShaderMap<std::string> &shaderSources,
const ShaderMapInterfaceVariableInfoMap &variableInfoMap, const ShaderMapInterfaceVariableInfoMap &variableInfoMap,
...@@ -1974,7 +1975,7 @@ angle::Result GlslangGetShaderSpirvCode(const GlslangErrorCallback &callback, ...@@ -1974,7 +1975,7 @@ angle::Result GlslangGetShaderSpirvCode(const GlslangErrorCallback &callback,
gl::ShaderMap<SpirvBlob> initialSpirvBlobs; gl::ShaderMap<SpirvBlob> initialSpirvBlobs;
ANGLE_TRY(GetShaderSpirvCode(callback, glCaps, shaderSources, &initialSpirvBlobs)); ANGLE_TRY(GetShaderSpirvCode(callback, glCaps, shaderSources, &initialSpirvBlobs));
for (const gl::ShaderType shaderType : gl::AllShaderTypes()) for (const gl::ShaderType shaderType : linkedShaderStages)
{ {
// we pass in false here to skip modifications related to early fragment tests // we pass in false here to skip modifications related to early fragment tests
// optimizations and line rasterization. These are done in the initProgram time since they // optimizations and line rasterization. These are done in the initProgram time since they
......
...@@ -124,6 +124,7 @@ angle::Result GlslangTransformSpirvCode(const GlslangErrorCallback &callback, ...@@ -124,6 +124,7 @@ angle::Result GlslangTransformSpirvCode(const GlslangErrorCallback &callback,
SpirvBlob *spirvBlobOut); SpirvBlob *spirvBlobOut);
angle::Result GlslangGetShaderSpirvCode(const GlslangErrorCallback &callback, angle::Result GlslangGetShaderSpirvCode(const GlslangErrorCallback &callback,
const gl::ShaderBitSet &linkedShaderStages,
const gl::Caps &glCaps, const gl::Caps &glCaps,
const gl::ShaderMap<std::string> &shaderSources, const gl::ShaderMap<std::string> &shaderSources,
const ShaderMapInterfaceVariableInfoMap &variableInfoMap, const ShaderMapInterfaceVariableInfoMap &variableInfoMap,
......
...@@ -317,8 +317,9 @@ angle::Result ProgramMtl::linkImpl(const gl::Context *glContext, ...@@ -317,8 +317,9 @@ angle::Result ProgramMtl::linkImpl(const gl::Context *glContext,
// Convert GLSL to spirv code // Convert GLSL to spirv code
gl::ShaderMap<std::vector<uint32_t>> shaderCodes; gl::ShaderMap<std::vector<uint32_t>> shaderCodes;
ANGLE_TRY(mtl::GlslangGetShaderSpirvCode(contextMtl, contextMtl->getCaps(), shaderSources, ANGLE_TRY(mtl::GlslangGetShaderSpirvCode(
variableInfoMap, &shaderCodes)); contextMtl, mState.getProgramExecutable().getLinkedShaderStages(), contextMtl->getCaps(),
shaderSources, variableInfoMap, &shaderCodes));
// Convert spirv code to MSL // Convert spirv code to MSL
ANGLE_TRY(convertToMsl(glContext, gl::ShaderType::Vertex, infoLog, ANGLE_TRY(convertToMsl(glContext, gl::ShaderType::Vertex, infoLog,
......
...@@ -25,6 +25,7 @@ void GlslangGetShaderSource(const gl::ProgramState &programState, ...@@ -25,6 +25,7 @@ void GlslangGetShaderSource(const gl::ProgramState &programState,
ShaderMapInterfaceVariableInfoMap *variableInfoMapOut); ShaderMapInterfaceVariableInfoMap *variableInfoMapOut);
angle::Result GlslangGetShaderSpirvCode(ErrorHandler *context, angle::Result GlslangGetShaderSpirvCode(ErrorHandler *context,
const gl::ShaderBitSet &linkedShaderStages,
const gl::Caps &glCaps, const gl::Caps &glCaps,
const gl::ShaderMap<std::string> &shaderSources, const gl::ShaderMap<std::string> &shaderSources,
const ShaderMapInterfaceVariableInfoMap &variableInfoMap, const ShaderMapInterfaceVariableInfoMap &variableInfoMap,
......
...@@ -59,14 +59,15 @@ void GlslangGetShaderSource(const gl::ProgramState &programState, ...@@ -59,14 +59,15 @@ void GlslangGetShaderSource(const gl::ProgramState &programState,
} }
angle::Result GlslangGetShaderSpirvCode(ErrorHandler *context, angle::Result GlslangGetShaderSpirvCode(ErrorHandler *context,
const gl::ShaderBitSet &linkedShaderStages,
const gl::Caps &glCaps, const gl::Caps &glCaps,
const gl::ShaderMap<std::string> &shaderSources, const gl::ShaderMap<std::string> &shaderSources,
const ShaderMapInterfaceVariableInfoMap &variableInfoMap, const ShaderMapInterfaceVariableInfoMap &variableInfoMap,
gl::ShaderMap<std::vector<uint32_t>> *shaderCodeOut) gl::ShaderMap<std::vector<uint32_t>> *shaderCodeOut)
{ {
return rx::GlslangGetShaderSpirvCode( return rx::GlslangGetShaderSpirvCode(
[context](GlslangError error) { return HandleError(context, error); }, glCaps, [context](GlslangError error) { return HandleError(context, error); }, linkedShaderStages,
shaderSources, variableInfoMap, shaderCodeOut); glCaps, shaderSources, variableInfoMap, shaderCodeOut);
} }
} // namespace mtl } // namespace mtl
} // namespace rx } // namespace rx
...@@ -2659,18 +2659,15 @@ angle::Result ContextVk::updateScissor(const gl::State &glState) ...@@ -2659,18 +2659,15 @@ angle::Result ContextVk::updateScissor(const gl::State &glState)
void ContextVk::invalidateProgramBindingHelper(const gl::State &glState) void ContextVk::invalidateProgramBindingHelper(const gl::State &glState)
{ {
mExecutable = nullptr; mProgram = nullptr;
mProgramPipeline = nullptr;
mExecutable = nullptr;
if (glState.getProgram()) if (glState.getProgram())
{ {
mProgram = vk::GetImpl(glState.getProgram()); mProgram = vk::GetImpl(glState.getProgram());
mExecutable = &mProgram->getExecutable(); mExecutable = &mProgram->getExecutable();
} }
else
{
mProgram = nullptr;
mExecutable = nullptr;
}
if (glState.getProgramPipeline()) if (glState.getProgramPipeline())
{ {
...@@ -2681,10 +2678,6 @@ void ContextVk::invalidateProgramBindingHelper(const gl::State &glState) ...@@ -2681,10 +2678,6 @@ void ContextVk::invalidateProgramBindingHelper(const gl::State &glState)
mExecutable = &mProgramPipeline->getExecutable(); mExecutable = &mProgramPipeline->getExecutable();
} }
} }
else
{
mProgramPipeline = nullptr;
}
} }
angle::Result ContextVk::invalidateProgramExecutableHelper(const gl::Context *context) angle::Result ContextVk::invalidateProgramExecutableHelper(const gl::Context *context)
......
...@@ -71,14 +71,15 @@ void GlslangWrapperVk::GetShaderSource(const angle::FeaturesVk &features, ...@@ -71,14 +71,15 @@ void GlslangWrapperVk::GetShaderSource(const angle::FeaturesVk &features,
// static // static
angle::Result GlslangWrapperVk::GetShaderCode( angle::Result GlslangWrapperVk::GetShaderCode(
vk::Context *context, vk::Context *context,
const gl::ShaderBitSet &linkedShaderStages,
const gl::Caps &glCaps, const gl::Caps &glCaps,
const gl::ShaderMap<std::string> &shaderSources, const gl::ShaderMap<std::string> &shaderSources,
const ShaderMapInterfaceVariableInfoMap &variableInfoMap, const ShaderMapInterfaceVariableInfoMap &variableInfoMap,
gl::ShaderMap<std::vector<uint32_t>> *shaderCodeOut) gl::ShaderMap<std::vector<uint32_t>> *shaderCodeOut)
{ {
return GlslangGetShaderSpirvCode( return GlslangGetShaderSpirvCode(
[context](GlslangError error) { return ErrorHandler(context, error); }, glCaps, [context](GlslangError error) { return ErrorHandler(context, error); }, linkedShaderStages,
shaderSources, variableInfoMap, shaderCodeOut); glCaps, shaderSources, variableInfoMap, shaderCodeOut);
} }
// static // static
......
...@@ -38,6 +38,7 @@ class GlslangWrapperVk ...@@ -38,6 +38,7 @@ class GlslangWrapperVk
ShaderMapInterfaceVariableInfoMap *variableInfoMapOut); ShaderMapInterfaceVariableInfoMap *variableInfoMapOut);
static angle::Result GetShaderCode(vk::Context *context, static angle::Result GetShaderCode(vk::Context *context,
const gl::ShaderBitSet &linkedShaderStages,
const gl::Caps &glCaps, const gl::Caps &glCaps,
const gl::ShaderMap<std::string> &shaderSources, const gl::ShaderMap<std::string> &shaderSources,
const ShaderMapInterfaceVariableInfoMap &variableInfoMap, const ShaderMapInterfaceVariableInfoMap &variableInfoMap,
......
...@@ -31,13 +31,14 @@ ShaderInfo::ShaderInfo() {} ...@@ -31,13 +31,14 @@ ShaderInfo::ShaderInfo() {}
ShaderInfo::~ShaderInfo() = default; ShaderInfo::~ShaderInfo() = default;
angle::Result ShaderInfo::initShaders(ContextVk *contextVk, angle::Result ShaderInfo::initShaders(ContextVk *contextVk,
const gl::ShaderBitSet &linkedShaderStages,
const gl::ShaderMap<std::string> &shaderSources, const gl::ShaderMap<std::string> &shaderSources,
const ShaderMapInterfaceVariableInfoMap &variableInfoMap) const ShaderMapInterfaceVariableInfoMap &variableInfoMap)
{ {
ASSERT(!valid()); ASSERT(!valid());
ANGLE_TRY(GlslangWrapperVk::GetShaderCode(contextVk, contextVk->getCaps(), shaderSources, ANGLE_TRY(GlslangWrapperVk::GetShaderCode(contextVk, linkedShaderStages, contextVk->getCaps(),
variableInfoMap, &mSpirvBlobs)); shaderSources, variableInfoMap, &mSpirvBlobs));
mIsInitialized = true; mIsInitialized = true;
return angle::Result::Continue; return angle::Result::Continue;
...@@ -140,7 +141,6 @@ void ProgramInfo::release(ContextVk *contextVk) ...@@ -140,7 +141,6 @@ void ProgramInfo::release(ContextVk *contextVk)
ProgramExecutableVk::ProgramExecutableVk() ProgramExecutableVk::ProgramExecutableVk()
: mEmptyDescriptorSets{}, : mEmptyDescriptorSets{},
mNumDefaultUniformDescriptors(0), mNumDefaultUniformDescriptors(0),
mPipelineLayoutCreated(false),
mDynamicBufferOffsets{}, mDynamicBufferOffsets{},
mProgram(nullptr), mProgram(nullptr),
mProgramPipeline(nullptr) mProgramPipeline(nullptr)
...@@ -162,7 +162,6 @@ void ProgramExecutableVk::reset(ContextVk *contextVk) ...@@ -162,7 +162,6 @@ void ProgramExecutableVk::reset(ContextVk *contextVk)
mDescriptorSets.clear(); mDescriptorSets.clear();
mEmptyDescriptorSets.fill(VK_NULL_HANDLE); mEmptyDescriptorSets.fill(VK_NULL_HANDLE);
mPipelineLayoutCreated = false;
mNumDefaultUniformDescriptors = 0; mNumDefaultUniformDescriptors = 0;
mTransformOptionBits.reset(); mTransformOptionBits.reset();
...@@ -179,10 +178,11 @@ void ProgramExecutableVk::reset(ContextVk *contextVk) ...@@ -179,10 +178,11 @@ void ProgramExecutableVk::reset(ContextVk *contextVk)
mTextureDescriptorsCache.clear(); mTextureDescriptorsCache.clear();
mDescriptorBuffersCache.clear(); mDescriptorBuffersCache.clear();
for (ProgramInfo &programInfo : mProgramInfos) for (ProgramInfo &programInfo : mGraphicsProgramInfos)
{ {
programInfo.release(contextVk); programInfo.release(contextVk);
} }
mComputeProgramInfo.release(contextVk);
} }
std::unique_ptr<rx::LinkEvent> ProgramExecutableVk::load(gl::BinaryInputStream *stream) std::unique_ptr<rx::LinkEvent> ProgramExecutableVk::load(gl::BinaryInputStream *stream)
...@@ -575,14 +575,14 @@ angle::Result ProgramExecutableVk::getGraphicsPipeline( ...@@ -575,14 +575,14 @@ angle::Result ProgramExecutableVk::getGraphicsPipeline(
const gl::State &glState = contextVk->getState(); const gl::State &glState = contextVk->getState();
mTransformOptionBits[ProgramTransformOption::EnableLineRasterEmulation] = mTransformOptionBits[ProgramTransformOption::EnableLineRasterEmulation] =
contextVk->isBresenhamEmulationEnabled(mode); contextVk->isBresenhamEmulationEnabled(mode);
ProgramInfo &programInfo = getProgramInfo(mTransformOptionBits); ProgramInfo &programInfo = getGraphicsProgramInfo(mTransformOptionBits);
RendererVk *renderer = contextVk->getRenderer(); RendererVk *renderer = contextVk->getRenderer();
vk::PipelineCache *pipelineCache = nullptr; vk::PipelineCache *pipelineCache = nullptr;
const gl::ProgramExecutable *executable = glState.getProgramExecutable(); const gl::ProgramExecutable *glExecutable = glState.getProgramExecutable();
ASSERT(executable); ASSERT(glExecutable && !glExecutable->isCompute());
for (const gl::ShaderType shaderType : executable->getLinkedShaderStages()) for (const gl::ShaderType shaderType : glExecutable->getLinkedShaderStages())
{ {
ProgramVk *programVk = getShaderProgram(glState, shaderType); ProgramVk *programVk = getShaderProgram(glState, shaderType);
if (programVk) if (programVk)
...@@ -593,7 +593,7 @@ angle::Result ProgramExecutableVk::getGraphicsPipeline( ...@@ -593,7 +593,7 @@ angle::Result ProgramExecutableVk::getGraphicsPipeline(
} }
vk::ShaderProgramHelper *shaderProgram = programInfo.getShaderProgram(); vk::ShaderProgramHelper *shaderProgram = programInfo.getShaderProgram();
ASSERT(shaderProgram && shaderProgram->isGraphicsProgram()); ASSERT(shaderProgram);
ANGLE_TRY(renderer->getPipelineCache(&pipelineCache)); ANGLE_TRY(renderer->getPipelineCache(&pipelineCache));
return shaderProgram->getGraphicsPipeline( return shaderProgram->getGraphicsPipeline(
contextVk, &contextVk->getRenderPassCache(), *pipelineCache, contextVk, &contextVk->getRenderPassCache(), *pipelineCache,
...@@ -604,25 +604,22 @@ angle::Result ProgramExecutableVk::getGraphicsPipeline( ...@@ -604,25 +604,22 @@ angle::Result ProgramExecutableVk::getGraphicsPipeline(
angle::Result ProgramExecutableVk::getComputePipeline(ContextVk *contextVk, angle::Result ProgramExecutableVk::getComputePipeline(ContextVk *contextVk,
vk::PipelineAndSerial **pipelineOut) vk::PipelineAndSerial **pipelineOut)
{ {
const gl::State &glState = contextVk->getState(); const gl::State &glState = contextVk->getState();
ProgramInfo &programInfo = getDefaultProgramInfo(); const gl::ProgramExecutable *glExecutable = glState.getProgramExecutable();
ASSERT(glExecutable && glExecutable->isCompute());
ProgramVk *programVk = getShaderProgram(glState, gl::ShaderType::Compute); ProgramVk *programVk = getShaderProgram(glState, gl::ShaderType::Compute);
ASSERT(programVk); ASSERT(programVk);
ProgramInfo &programInfo = getComputeProgramInfo();
ANGLE_TRY(programVk->initComputeProgram(contextVk, programInfo)); ANGLE_TRY(programVk->initComputeProgram(contextVk, programInfo));
vk::ShaderProgramHelper *shaderProgram = programInfo.getShaderProgram(); vk::ShaderProgramHelper *shaderProgram = programInfo.getShaderProgram();
ASSERT(shaderProgram && !shaderProgram->isGraphicsProgram()); ASSERT(shaderProgram);
return shaderProgram->getComputePipeline(contextVk, getPipelineLayout(), pipelineOut); return shaderProgram->getComputePipeline(contextVk, getPipelineLayout(), pipelineOut);
} }
angle::Result ProgramExecutableVk::createPipelineLayout(const gl::Context *glContext) angle::Result ProgramExecutableVk::createPipelineLayout(const gl::Context *glContext)
{ {
if (mPipelineLayoutCreated)
{
return angle::Result::Continue;
}
const gl::State &glState = glContext->getState(); const gl::State &glState = glContext->getState();
ContextVk *contextVk = vk::GetImpl(glContext); ContextVk *contextVk = vk::GetImpl(glContext);
RendererVk *renderer = contextVk->getRenderer(); RendererVk *renderer = contextVk->getRenderer();
...@@ -819,8 +816,6 @@ angle::Result ProgramExecutableVk::createPipelineLayout(const gl::Context *glCon ...@@ -819,8 +816,6 @@ angle::Result ProgramExecutableVk::createPipelineLayout(const gl::Context *glCon
constexpr VkMemoryPropertyFlags kMemoryType = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; constexpr VkMemoryPropertyFlags kMemoryType = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
angle::Result status = mEmptyBuffer.init(contextVk, emptyBufferInfo, kMemoryType); angle::Result status = mEmptyBuffer.init(contextVk, emptyBufferInfo, kMemoryType);
mPipelineLayoutCreated = true;
return status; return status;
} }
......
...@@ -28,6 +28,7 @@ class ShaderInfo final : angle::NonCopyable ...@@ -28,6 +28,7 @@ class ShaderInfo final : angle::NonCopyable
~ShaderInfo(); ~ShaderInfo();
angle::Result initShaders(ContextVk *contextVk, angle::Result initShaders(ContextVk *contextVk,
const gl::ShaderBitSet &linkedShaderStages,
const gl::ShaderMap<std::string> &shaderSources, const gl::ShaderMap<std::string> &shaderSources,
const ShaderMapInterfaceVariableInfoMap &variableInfoMap); const ShaderMapInterfaceVariableInfoMap &variableInfoMap);
void release(ContextVk *contextVk); void release(ContextVk *contextVk);
...@@ -119,11 +120,12 @@ class ProgramExecutableVk ...@@ -119,11 +120,12 @@ class ProgramExecutableVk
gl::ShaderMap<const gl::ProgramState *> *programStatesOut); gl::ShaderMap<const gl::ProgramState *> *programStatesOut);
const gl::ProgramExecutable &getGlExecutable(); const gl::ProgramExecutable &getGlExecutable();
ProgramInfo &getDefaultProgramInfo() { return mProgramInfos[0]; } ProgramInfo &getGraphicsDefaultProgramInfo() { return mGraphicsProgramInfos[0]; }
ProgramInfo &getProgramInfo(ProgramTransformOptionBits optionBits) ProgramInfo &getGraphicsProgramInfo(ProgramTransformOptionBits optionBits)
{ {
return mProgramInfos[optionBits.to_ulong()]; return mGraphicsProgramInfos[optionBits.to_ulong()];
} }
ProgramInfo &getComputeProgramInfo() { return mComputeProgramInfo; }
angle::Result getGraphicsPipeline(ContextVk *contextVk, angle::Result getGraphicsPipeline(ContextVk *contextVk,
gl::PrimitiveMode mode, gl::PrimitiveMode mode,
...@@ -223,7 +225,6 @@ class ProgramExecutableVk ...@@ -223,7 +225,6 @@ class ProgramExecutableVk
// deleted while this program is in use. // deleted while this program is in use.
vk::BindingPointer<vk::PipelineLayout> mPipelineLayout; vk::BindingPointer<vk::PipelineLayout> mPipelineLayout;
vk::DescriptorSetLayoutPointerArray mDescriptorSetLayouts; vk::DescriptorSetLayoutPointerArray mDescriptorSetLayouts;
bool mPipelineLayoutCreated;
// Keep bindings to the descriptor pools. This ensures the pools stay valid while the Program // Keep bindings to the descriptor pools. This ensures the pools stay valid while the Program
// is in use. // is in use.
...@@ -240,7 +241,8 @@ class ProgramExecutableVk ...@@ -240,7 +241,8 @@ class ProgramExecutableVk
// since that's slow to calculate. // since that's slow to calculate.
ShaderMapInterfaceVariableInfoMap mVariableInfoMap; ShaderMapInterfaceVariableInfoMap mVariableInfoMap;
ProgramInfo mProgramInfos[static_cast<int>(ProgramTransformOption::PermutationCount)]; ProgramInfo mGraphicsProgramInfos[static_cast<int>(ProgramTransformOption::PermutationCount)];
ProgramInfo mComputeProgramInfo;
ProgramTransformOptionBits mTransformOptionBits; ProgramTransformOptionBits mTransformOptionBits;
......
...@@ -302,7 +302,8 @@ std::unique_ptr<LinkEvent> ProgramVk::link(const gl::Context *context, ...@@ -302,7 +302,8 @@ std::unique_ptr<LinkEvent> ProgramVk::link(const gl::Context *context,
// Compile the shaders. // Compile the shaders.
angle::Result status = angle::Result status =
mShaderInfo.initShaders(contextVk, shaderSources, mExecutable.mVariableInfoMap); mShaderInfo.initShaders(contextVk, mState.getProgramExecutable().getLinkedShaderStages(),
shaderSources, mExecutable.mVariableInfoMap);
if (status != angle::Result::Continue) if (status != angle::Result::Continue)
{ {
return std::make_unique<LinkEventDone>(status); return std::make_unique<LinkEventDone>(status);
......
...@@ -1278,14 +1278,6 @@ class ShaderProgramHelper : angle::NonCopyable ...@@ -1278,14 +1278,6 @@ class ShaderProgramHelper : angle::NonCopyable
void destroy(VkDevice device); void destroy(VkDevice device);
void release(ContextVk *contextVk); void release(ContextVk *contextVk);
bool isGraphicsProgram() const
{
ASSERT((mShaders[gl::ShaderType::Vertex].valid() ||
mShaders[gl::ShaderType::Fragment].valid()) !=
mShaders[gl::ShaderType::Compute].valid());
return !mShaders[gl::ShaderType::Compute].valid();
}
ShaderAndSerial &getShader(gl::ShaderType shaderType) { return mShaders[shaderType].get(); } ShaderAndSerial &getShader(gl::ShaderType shaderType) { return mShaders[shaderType].get(); }
void setShader(gl::ShaderType shaderType, RefCounted<ShaderAndSerial> *shader); void setShader(gl::ShaderType shaderType, RefCounted<ShaderAndSerial> *shader);
......
...@@ -36,11 +36,6 @@ ...@@ -36,11 +36,6 @@
//// Failures blocking an official GLES 3.1 conformance run on SwiftShader //// Failures blocking an official GLES 3.1 conformance run on SwiftShader
//// ////
// Verify that compute and non-compute stages can be attached to one pipeline object:
3570 VULKAN : KHR-GLES31.core.compute_shader.sso-compute-pipeline = SKIP
3570 VULKAN : KHR-GLES31.core.compute_shader.sso-case2 = SKIP
3570 VULKAN : KHR-GLES31.core.compute_shader.sso-case3 = SKIP
3570 SWIFTSHADER : KHR-GLES31.core.shader_image_load_store.advanced-sso-simple = SKIP
// Separate shader objects: // Separate shader objects:
3570 VULKAN : KHR-GLES31.core.sepshaderobjs.StateInteraction = SKIP 3570 VULKAN : KHR-GLES31.core.sepshaderobjs.StateInteraction = SKIP
...@@ -75,9 +70,6 @@ ...@@ -75,9 +70,6 @@
3605 VULKAN : KHR-GLES31.core.texture_gather.* = FAIL 3605 VULKAN : KHR-GLES31.core.texture_gather.* = FAIL
// Dispatch indirect: // Dispatch indirect:
4188 VULKAN : KHR-GLES31.core.compute_shader.resource-image = FAIL
4191 VULKAN : KHR-GLES31.core.compute_shader.resources-max = FAIL
4192 VULKAN : KHR-GLES31.core.compute_shader.pipeline-post-xfb = FAIL
3726 VULKAN PIXEL2ORXL : KHR-GLES31.core.compute_shader.pipeline-compute-chain = FAIL 3726 VULKAN PIXEL2ORXL : KHR-GLES31.core.compute_shader.pipeline-compute-chain = FAIL
4194 VULKAN PIXEL2ORXL : KHR-GLES31.core.compute_shader.resource-ubo = FAIL 4194 VULKAN PIXEL2ORXL : KHR-GLES31.core.compute_shader.resource-ubo = FAIL
4194 VULKAN PIXEL2ORXL : KHR-GLES31.core.compute_shader.built-in-variables = FAIL 4194 VULKAN PIXEL2ORXL : KHR-GLES31.core.compute_shader.built-in-variables = FAIL
......
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