mirror of
https://github.com/godotengine/godot-angle-static.git
synced 2026-01-03 14:09:33 +03:00
GL: Use the executable instead of program
In a few places, the program was still being directly referenced instead of the executable (in particular when dealing with multiview). Bug: angleproject:8297 Change-Id: I15d0865bf58376a9f85efeec739dd93b49ceaea7 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4846475 Reviewed-by: Geoff Lang <geofflang@chromium.org> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
This commit is contained in:
committed by
Angle LUCI CQ
parent
632ded9e0a
commit
06411d1623
@@ -37,6 +37,25 @@
|
||||
|
||||
namespace rx
|
||||
{
|
||||
namespace
|
||||
{
|
||||
GLsizei GetDrawAdjustedInstanceCount(const gl::ProgramExecutable *executable)
|
||||
{
|
||||
const bool usesMultiview = executable->usesMultiview();
|
||||
return usesMultiview ? executable->getNumViews() : 0;
|
||||
}
|
||||
|
||||
GLsizei GetInstancedDrawAdjustedInstanceCount(const gl::ProgramExecutable *executable,
|
||||
GLsizei instanceCount)
|
||||
{
|
||||
GLsizei adjustedInstanceCount = instanceCount;
|
||||
if (executable->usesMultiview())
|
||||
{
|
||||
adjustedInstanceCount *= executable->getNumViews();
|
||||
}
|
||||
return adjustedInstanceCount;
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
ContextGL::ContextGL(const gl::State &state,
|
||||
gl::ErrorSet *errorSet,
|
||||
@@ -322,16 +341,15 @@ angle::Result ContextGL::drawArrays(const gl::Context *context,
|
||||
GLint first,
|
||||
GLsizei count)
|
||||
{
|
||||
const gl::Program *program = context->getState().getProgram();
|
||||
const bool usesMultiview = program->usesMultiview();
|
||||
const GLsizei instanceCount = usesMultiview ? program->getNumViews() : 0;
|
||||
const gl::ProgramExecutable *executable = context->getState().getProgramExecutable();
|
||||
const GLsizei instanceCount = GetDrawAdjustedInstanceCount(executable);
|
||||
|
||||
#if defined(ANGLE_STATE_VALIDATION_ENABLED)
|
||||
validateState();
|
||||
#endif
|
||||
|
||||
ANGLE_TRY(setDrawArraysState(context, first, count, instanceCount));
|
||||
if (!usesMultiview)
|
||||
if (!executable->usesMultiview())
|
||||
{
|
||||
ANGLE_GL_TRY(context, getFunctions()->drawArrays(ToGLenum(mode), first, count));
|
||||
}
|
||||
@@ -351,12 +369,9 @@ angle::Result ContextGL::drawArraysInstanced(const gl::Context *context,
|
||||
GLsizei count,
|
||||
GLsizei instanceCount)
|
||||
{
|
||||
GLsizei adjustedInstanceCount = instanceCount;
|
||||
const gl::Program *program = context->getState().getProgram();
|
||||
if (program->usesMultiview())
|
||||
{
|
||||
adjustedInstanceCount *= program->getNumViews();
|
||||
}
|
||||
const gl::ProgramExecutable *executable = context->getState().getProgramExecutable();
|
||||
const GLsizei adjustedInstanceCount =
|
||||
GetInstancedDrawAdjustedInstanceCount(executable, instanceCount);
|
||||
|
||||
ANGLE_TRY(setDrawArraysState(context, first, count, adjustedInstanceCount));
|
||||
ANGLE_GL_TRY(context, getFunctions()->drawArraysInstanced(ToGLenum(mode), first, count,
|
||||
@@ -366,8 +381,7 @@ angle::Result ContextGL::drawArraysInstanced(const gl::Context *context,
|
||||
return angle::Result::Continue;
|
||||
}
|
||||
|
||||
gl::AttributesMask ContextGL::updateAttributesForBaseInstance(const gl::Program *program,
|
||||
GLuint baseInstance)
|
||||
gl::AttributesMask ContextGL::updateAttributesForBaseInstance(GLuint baseInstance)
|
||||
{
|
||||
const gl::ProgramExecutable *executable = getState().getProgramExecutable();
|
||||
gl::AttributesMask attribToUpdateMask;
|
||||
@@ -450,12 +464,9 @@ angle::Result ContextGL::drawArraysInstancedBaseInstance(const gl::Context *cont
|
||||
GLsizei instanceCount,
|
||||
GLuint baseInstance)
|
||||
{
|
||||
GLsizei adjustedInstanceCount = instanceCount;
|
||||
const gl::Program *program = context->getState().getProgram();
|
||||
if (program->usesMultiview())
|
||||
{
|
||||
adjustedInstanceCount *= program->getNumViews();
|
||||
}
|
||||
const gl::ProgramExecutable *executable = context->getState().getProgramExecutable();
|
||||
const GLsizei adjustedInstanceCount =
|
||||
GetInstancedDrawAdjustedInstanceCount(executable, instanceCount);
|
||||
|
||||
ANGLE_TRY(setDrawArraysState(context, first, count, adjustedInstanceCount));
|
||||
|
||||
@@ -475,8 +486,7 @@ angle::Result ContextGL::drawArraysInstancedBaseInstance(const gl::Context *cont
|
||||
// pointer offset calling vertexAttribPointer Will refactor stateCache and pass baseInstance
|
||||
// to setDrawArraysState to set pointer offset
|
||||
|
||||
gl::AttributesMask attribToResetMask =
|
||||
updateAttributesForBaseInstance(program, baseInstance);
|
||||
gl::AttributesMask attribToResetMask = updateAttributesForBaseInstance(baseInstance);
|
||||
|
||||
ANGLE_GL_TRY(context, functions->drawArraysInstanced(ToGLenum(mode), first, count,
|
||||
adjustedInstanceCount));
|
||||
@@ -495,18 +505,17 @@ angle::Result ContextGL::drawElements(const gl::Context *context,
|
||||
gl::DrawElementsType type,
|
||||
const void *indices)
|
||||
{
|
||||
const gl::State &glState = context->getState();
|
||||
const gl::Program *program = glState.getProgram();
|
||||
const bool usesMultiview = program->usesMultiview();
|
||||
const GLsizei instanceCount = usesMultiview ? program->getNumViews() : 0;
|
||||
const void *drawIndexPtr = nullptr;
|
||||
const gl::State &glState = context->getState();
|
||||
const gl::ProgramExecutable *executable = glState.getProgramExecutable();
|
||||
const GLsizei instanceCount = GetDrawAdjustedInstanceCount(executable);
|
||||
const void *drawIndexPtr = nullptr;
|
||||
|
||||
#if defined(ANGLE_STATE_VALIDATION_ENABLED)
|
||||
validateState();
|
||||
#endif // ANGLE_STATE_VALIDATION_ENABLED
|
||||
|
||||
ANGLE_TRY(setDrawElementsState(context, count, type, indices, instanceCount, &drawIndexPtr));
|
||||
if (!usesMultiview)
|
||||
if (!executable->usesMultiview())
|
||||
{
|
||||
ANGLE_GL_TRY(context, getFunctions()->drawElements(ToGLenum(mode), count, ToGLenum(type),
|
||||
drawIndexPtr));
|
||||
@@ -529,18 +538,17 @@ angle::Result ContextGL::drawElementsBaseVertex(const gl::Context *context,
|
||||
const void *indices,
|
||||
GLint baseVertex)
|
||||
{
|
||||
const gl::State &glState = context->getState();
|
||||
const gl::Program *program = glState.getProgram();
|
||||
const bool usesMultiview = program->usesMultiview();
|
||||
const GLsizei instanceCount = usesMultiview ? program->getNumViews() : 0;
|
||||
const void *drawIndexPtr = nullptr;
|
||||
const gl::State &glState = context->getState();
|
||||
const gl::ProgramExecutable *executable = glState.getProgramExecutable();
|
||||
const GLsizei instanceCount = GetDrawAdjustedInstanceCount(executable);
|
||||
const void *drawIndexPtr = nullptr;
|
||||
|
||||
#if defined(ANGLE_STATE_VALIDATION_ENABLED)
|
||||
validateState();
|
||||
#endif // ANGLE_STATE_VALIDATION_ENABLED
|
||||
|
||||
ANGLE_TRY(setDrawElementsState(context, count, type, indices, instanceCount, &drawIndexPtr));
|
||||
if (!usesMultiview)
|
||||
if (!executable->usesMultiview())
|
||||
{
|
||||
ANGLE_GL_TRY(context, getFunctions()->drawElementsBaseVertex(
|
||||
ToGLenum(mode), count, ToGLenum(type), drawIndexPtr, baseVertex));
|
||||
@@ -563,12 +571,9 @@ angle::Result ContextGL::drawElementsInstanced(const gl::Context *context,
|
||||
const void *indices,
|
||||
GLsizei instances)
|
||||
{
|
||||
GLsizei adjustedInstanceCount = instances;
|
||||
const gl::Program *program = context->getState().getProgram();
|
||||
if (program->usesMultiview())
|
||||
{
|
||||
adjustedInstanceCount *= program->getNumViews();
|
||||
}
|
||||
const gl::ProgramExecutable *executable = context->getState().getProgramExecutable();
|
||||
const GLsizei adjustedInstanceCount =
|
||||
GetInstancedDrawAdjustedInstanceCount(executable, instances);
|
||||
const void *drawIndexPointer = nullptr;
|
||||
|
||||
ANGLE_TRY(setDrawElementsState(context, count, type, indices, adjustedInstanceCount,
|
||||
@@ -587,12 +592,9 @@ angle::Result ContextGL::drawElementsInstancedBaseVertex(const gl::Context *cont
|
||||
GLsizei instances,
|
||||
GLint baseVertex)
|
||||
{
|
||||
GLsizei adjustedInstanceCount = instances;
|
||||
const gl::Program *program = context->getState().getProgram();
|
||||
if (program->usesMultiview())
|
||||
{
|
||||
adjustedInstanceCount *= program->getNumViews();
|
||||
}
|
||||
const gl::ProgramExecutable *executable = context->getState().getProgramExecutable();
|
||||
const GLsizei adjustedInstanceCount =
|
||||
GetInstancedDrawAdjustedInstanceCount(executable, instances);
|
||||
const void *drawIndexPointer = nullptr;
|
||||
|
||||
ANGLE_TRY(setDrawElementsState(context, count, type, indices, adjustedInstanceCount,
|
||||
@@ -614,12 +616,9 @@ angle::Result ContextGL::drawElementsInstancedBaseVertexBaseInstance(const gl::C
|
||||
GLint baseVertex,
|
||||
GLuint baseInstance)
|
||||
{
|
||||
GLsizei adjustedInstanceCount = instances;
|
||||
const gl::Program *program = context->getState().getProgram();
|
||||
if (program->usesMultiview())
|
||||
{
|
||||
adjustedInstanceCount *= program->getNumViews();
|
||||
}
|
||||
const gl::ProgramExecutable *executable = context->getState().getProgramExecutable();
|
||||
const GLsizei adjustedInstanceCount =
|
||||
GetInstancedDrawAdjustedInstanceCount(executable, instances);
|
||||
const void *drawIndexPointer = nullptr;
|
||||
|
||||
ANGLE_TRY(setDrawElementsState(context, count, type, indices, adjustedInstanceCount,
|
||||
@@ -638,8 +637,7 @@ angle::Result ContextGL::drawElementsInstancedBaseVertexBaseInstance(const gl::C
|
||||
{
|
||||
// GL 3.3+ or GLES 3.2+
|
||||
// TODO(http://anglebug.com/3910): same as above
|
||||
gl::AttributesMask attribToResetMask =
|
||||
updateAttributesForBaseInstance(program, baseInstance);
|
||||
gl::AttributesMask attribToResetMask = updateAttributesForBaseInstance(baseInstance);
|
||||
|
||||
ANGLE_GL_TRY(context, functions->drawElementsInstancedBaseVertex(
|
||||
ToGLenum(mode), count, ToGLenum(type), drawIndexPointer,
|
||||
@@ -661,14 +659,13 @@ angle::Result ContextGL::drawRangeElements(const gl::Context *context,
|
||||
gl::DrawElementsType type,
|
||||
const void *indices)
|
||||
{
|
||||
const gl::Program *program = context->getState().getProgram();
|
||||
const bool usesMultiview = program->usesMultiview();
|
||||
const GLsizei instanceCount = usesMultiview ? program->getNumViews() : 0;
|
||||
const void *drawIndexPointer = nullptr;
|
||||
const gl::ProgramExecutable *executable = mState.getProgramExecutable();
|
||||
const GLsizei instanceCount = GetDrawAdjustedInstanceCount(executable);
|
||||
const void *drawIndexPointer = nullptr;
|
||||
|
||||
ANGLE_TRY(
|
||||
setDrawElementsState(context, count, type, indices, instanceCount, &drawIndexPointer));
|
||||
if (!usesMultiview)
|
||||
if (!executable->usesMultiview())
|
||||
{
|
||||
ANGLE_GL_TRY(context, getFunctions()->drawRangeElements(ToGLenum(mode), start, end, count,
|
||||
ToGLenum(type), drawIndexPointer));
|
||||
@@ -693,14 +690,13 @@ angle::Result ContextGL::drawRangeElementsBaseVertex(const gl::Context *context,
|
||||
const void *indices,
|
||||
GLint baseVertex)
|
||||
{
|
||||
const gl::Program *program = context->getState().getProgram();
|
||||
const bool usesMultiview = program->usesMultiview();
|
||||
const GLsizei instanceCount = usesMultiview ? program->getNumViews() : 0;
|
||||
const void *drawIndexPointer = nullptr;
|
||||
const gl::ProgramExecutable *executable = mState.getProgramExecutable();
|
||||
const GLsizei instanceCount = GetDrawAdjustedInstanceCount(executable);
|
||||
const void *drawIndexPointer = nullptr;
|
||||
|
||||
ANGLE_TRY(
|
||||
setDrawElementsState(context, count, type, indices, instanceCount, &drawIndexPointer));
|
||||
if (!usesMultiview)
|
||||
if (!executable->usesMultiview())
|
||||
{
|
||||
ANGLE_GL_TRY(context, getFunctions()->drawRangeElementsBaseVertex(
|
||||
ToGLenum(mode), start, end, count, ToGLenum(type),
|
||||
|
||||
@@ -313,8 +313,7 @@ class ContextGL : public ContextImpl
|
||||
GLsizei instanceCount,
|
||||
const void **outIndices);
|
||||
|
||||
gl::AttributesMask updateAttributesForBaseInstance(const gl::Program *program,
|
||||
GLuint baseInstance);
|
||||
gl::AttributesMask updateAttributesForBaseInstance(GLuint baseInstance);
|
||||
void resetUpdatedAttributes(gl::AttributesMask attribMask);
|
||||
|
||||
// Resets draw state prior to drawing load/store operations for EXT_shader_pixel_local_storage,
|
||||
|
||||
@@ -1372,8 +1372,8 @@ angle::Result FramebufferGL::syncState(const gl::Context *context,
|
||||
|
||||
if (attachment && mState.id() == context->getState().getDrawFramebuffer()->id())
|
||||
{
|
||||
stateManager->updateMultiviewBaseViewLayerIndexUniform(context->getState().getProgram(),
|
||||
getState());
|
||||
stateManager->updateMultiviewBaseViewLayerIndexUniform(
|
||||
context->getState().getProgramExecutable(), getState());
|
||||
}
|
||||
|
||||
return angle::Result::Continue;
|
||||
|
||||
@@ -19,7 +19,9 @@ ProgramExecutableGL::ProgramExecutableGL(const gl::ProgramExecutable *executable
|
||||
: ProgramExecutableImpl(executable),
|
||||
mHasAppliedTransformFeedbackVaryings(false),
|
||||
mClipDistanceEnabledUniformLocation(-1),
|
||||
mMultiviewBaseViewLayerIndexUniformLocation(-1)
|
||||
mMultiviewBaseViewLayerIndexUniformLocation(-1),
|
||||
mProgramID(0),
|
||||
mFunctions(nullptr)
|
||||
{}
|
||||
|
||||
ProgramExecutableGL::~ProgramExecutableGL() {}
|
||||
@@ -39,6 +41,11 @@ void ProgramExecutableGL::postLink(const FunctionsGL *functions,
|
||||
const angle::FeaturesGL &features,
|
||||
GLuint programID)
|
||||
{
|
||||
// Cache the following so the executable is capable of making the appropriate GL calls without
|
||||
// having to involve ProgramGL.
|
||||
mProgramID = programID;
|
||||
mFunctions = functions;
|
||||
|
||||
// Query the uniform information
|
||||
ASSERT(mUniformRealLocationMap.empty());
|
||||
const auto &uniformLocations = mExecutable->getUniformLocations();
|
||||
@@ -88,4 +95,25 @@ void ProgramExecutableGL::postLink(const FunctionsGL *functions,
|
||||
ASSERT(mMultiviewBaseViewLayerIndexUniformLocation != -1);
|
||||
}
|
||||
}
|
||||
|
||||
void ProgramExecutableGL::updateEnabledClipDistances(uint8_t enabledClipDistancesPacked) const
|
||||
{
|
||||
ASSERT(mExecutable->hasClipDistance());
|
||||
ASSERT(mClipDistanceEnabledUniformLocation != -1);
|
||||
|
||||
ASSERT(mFunctions->programUniform1ui != nullptr);
|
||||
mFunctions->programUniform1ui(mProgramID, mClipDistanceEnabledUniformLocation,
|
||||
enabledClipDistancesPacked);
|
||||
}
|
||||
|
||||
void ProgramExecutableGL::enableLayeredRenderingPath(int baseViewIndex) const
|
||||
{
|
||||
ASSERT(mExecutable->usesMultiview());
|
||||
ASSERT(mMultiviewBaseViewLayerIndexUniformLocation != -1);
|
||||
|
||||
ASSERT(mFunctions->programUniform1i != nullptr);
|
||||
mFunctions->programUniform1i(mProgramID, mMultiviewBaseViewLayerIndexUniformLocation,
|
||||
baseViewIndex);
|
||||
}
|
||||
|
||||
} // namespace rx
|
||||
|
||||
@@ -29,6 +29,10 @@ class ProgramExecutableGL : public ProgramExecutableImpl
|
||||
|
||||
void destroy(const gl::Context *context) override;
|
||||
|
||||
void updateEnabledClipDistances(uint8_t enabledClipDistancesPacked) const;
|
||||
|
||||
void enableLayeredRenderingPath(int baseViewIndex) const;
|
||||
|
||||
private:
|
||||
friend class ProgramGL;
|
||||
|
||||
@@ -45,6 +49,10 @@ class ProgramExecutableGL : public ProgramExecutableImpl
|
||||
GLint mClipDistanceEnabledUniformLocation;
|
||||
|
||||
GLint mMultiviewBaseViewLayerIndexUniformLocation;
|
||||
|
||||
// The program for which the executable was built
|
||||
GLuint mProgramID;
|
||||
const FunctionsGL *mFunctions;
|
||||
};
|
||||
|
||||
} // namespace rx
|
||||
|
||||
@@ -968,26 +968,6 @@ bool ProgramGL::checkLinkStatus()
|
||||
return true;
|
||||
}
|
||||
|
||||
void ProgramGL::updateEnabledClipDistances(uint8_t enabledClipDistancesPacked) const
|
||||
{
|
||||
ASSERT(mState.getExecutable().hasClipDistance());
|
||||
ASSERT(getExecutable()->mClipDistanceEnabledUniformLocation != -1);
|
||||
|
||||
ASSERT(mFunctions->programUniform1ui != nullptr);
|
||||
mFunctions->programUniform1ui(mProgramID, getExecutable()->mClipDistanceEnabledUniformLocation,
|
||||
enabledClipDistancesPacked);
|
||||
}
|
||||
|
||||
void ProgramGL::enableLayeredRenderingPath(int baseViewIndex) const
|
||||
{
|
||||
ASSERT(mState.getExecutable().usesMultiview());
|
||||
ASSERT(getExecutable()->mMultiviewBaseViewLayerIndexUniformLocation != -1);
|
||||
|
||||
ASSERT(mFunctions->programUniform1i != nullptr);
|
||||
mFunctions->programUniform1i(
|
||||
mProgramID, getExecutable()->mMultiviewBaseViewLayerIndexUniformLocation, baseViewIndex);
|
||||
}
|
||||
|
||||
void ProgramGL::getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const
|
||||
{
|
||||
mFunctions->getUniformfv(mProgramID, uniLoc(location), params);
|
||||
|
||||
@@ -110,10 +110,6 @@ class ProgramGL : public ProgramImpl
|
||||
|
||||
ANGLE_INLINE GLuint getProgramID() const { return mProgramID; }
|
||||
|
||||
void updateEnabledClipDistances(uint8_t enabledClipDistancesPacked) const;
|
||||
|
||||
void enableLayeredRenderingPath(int baseViewIndex) const;
|
||||
|
||||
angle::Result syncState(const gl::Context *context,
|
||||
const gl::Program::DirtyBits &dirtyBits) override;
|
||||
|
||||
|
||||
@@ -1006,13 +1006,13 @@ void StateManagerGL::updateProgramTextureBindings(const gl::Context *context)
|
||||
|
||||
void StateManagerGL::updateProgramStorageBufferBindings(const gl::Context *context)
|
||||
{
|
||||
const gl::State &glState = context->getState();
|
||||
const gl::Program *program = glState.getProgram();
|
||||
const gl::State &glState = context->getState();
|
||||
const gl::ProgramExecutable *executable = glState.getProgramExecutable();
|
||||
|
||||
for (size_t blockIndex = 0; blockIndex < program->getActiveShaderStorageBlockCount();
|
||||
for (size_t blockIndex = 0; blockIndex < executable->getActiveShaderStorageBlockCount();
|
||||
blockIndex++)
|
||||
{
|
||||
GLuint binding = program->getShaderStorageBlockBinding(static_cast<GLuint>(blockIndex));
|
||||
GLuint binding = executable->getShaderStorageBlockBinding(static_cast<GLuint>(blockIndex));
|
||||
const auto &shaderStorageBuffer = glState.getIndexedShaderStorageBuffer(binding);
|
||||
|
||||
if (shaderStorageBuffer.get() != nullptr)
|
||||
@@ -1034,14 +1034,14 @@ void StateManagerGL::updateProgramStorageBufferBindings(const gl::Context *conte
|
||||
|
||||
void StateManagerGL::updateProgramUniformBufferBindings(const gl::Context *context)
|
||||
{
|
||||
// Sync the current program state
|
||||
const gl::State &glState = context->getState();
|
||||
const gl::Program *program = glState.getProgram();
|
||||
// Sync the current program executable state
|
||||
const gl::State &glState = context->getState();
|
||||
const gl::ProgramExecutable *executable = glState.getProgramExecutable();
|
||||
|
||||
for (size_t uniformBlockIndex = 0; uniformBlockIndex < program->getActiveUniformBlockCount();
|
||||
for (size_t uniformBlockIndex = 0; uniformBlockIndex < executable->getActiveUniformBlockCount();
|
||||
uniformBlockIndex++)
|
||||
{
|
||||
GLuint binding = program->getUniformBlockBinding(static_cast<GLuint>(uniformBlockIndex));
|
||||
GLuint binding = executable->getUniformBlockBinding(static_cast<GLuint>(uniformBlockIndex));
|
||||
const auto &uniformBuffer = glState.getIndexedUniformBuffer(binding);
|
||||
|
||||
if (uniformBuffer.get() != nullptr)
|
||||
@@ -1063,10 +1063,10 @@ void StateManagerGL::updateProgramUniformBufferBindings(const gl::Context *conte
|
||||
|
||||
void StateManagerGL::updateProgramAtomicCounterBufferBindings(const gl::Context *context)
|
||||
{
|
||||
const gl::State &glState = context->getState();
|
||||
const gl::Program *program = glState.getProgram();
|
||||
const gl::State &glState = context->getState();
|
||||
const gl::ProgramExecutable *executable = glState.getProgramExecutable();
|
||||
|
||||
for (const auto &atomicCounterBuffer : program->getState().getAtomicCounterBuffers())
|
||||
for (const auto &atomicCounterBuffer : executable->getAtomicCounterBuffers())
|
||||
{
|
||||
GLuint binding = atomicCounterBuffer.binding;
|
||||
const auto &buffer = glState.getIndexedAtomicCounterBuffer(binding);
|
||||
@@ -1100,7 +1100,7 @@ void StateManagerGL::updateProgramImageBindings(const gl::Context *context)
|
||||
|
||||
ASSERT(context->getClientVersion() >= gl::ES_3_1 ||
|
||||
context->getExtensions().shaderPixelLocalStorageANGLE ||
|
||||
program->getImageBindings().empty());
|
||||
executable->getImageBindings().empty());
|
||||
for (size_t imageUnitIndex : executable->getActiveImagesMask())
|
||||
{
|
||||
const gl::ImageUnit &imageUnit = glState.getImageUnit(imageUnitIndex);
|
||||
@@ -2171,10 +2171,10 @@ angle::Result StateManagerGL::syncState(const gl::Context *context,
|
||||
mHasSeparateFramebufferBindings ? GL_DRAW_FRAMEBUFFER : GL_FRAMEBUFFER,
|
||||
framebufferGL->getFramebufferID());
|
||||
|
||||
const gl::Program *program = state.getProgram();
|
||||
if (program)
|
||||
const gl::ProgramExecutable *executable = state.getProgramExecutable();
|
||||
if (executable)
|
||||
{
|
||||
updateMultiviewBaseViewLayerIndexUniform(program, framebufferGL->getState());
|
||||
updateMultiviewBaseViewLayerIndexUniform(executable, framebufferGL->getState());
|
||||
}
|
||||
|
||||
// Changing the draw framebuffer binding sometimes requires resetting srgb blending.
|
||||
@@ -2193,7 +2193,7 @@ angle::Result StateManagerGL::syncState(const gl::Context *context,
|
||||
VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(state.getVertexArray());
|
||||
bindVertexArray(vaoGL->getVertexArrayID(), vaoGL->getNativeState());
|
||||
|
||||
ANGLE_TRY(propagateProgramToVAO(context, state.getProgram(),
|
||||
ANGLE_TRY(propagateProgramToVAO(context, state.getProgramExecutable(),
|
||||
GetImplAs<VertexArrayGL>(state.getVertexArray())));
|
||||
|
||||
if (mFeatures.syncVertexArraysToDefault.enabled)
|
||||
@@ -2240,10 +2240,9 @@ angle::Result StateManagerGL::syncState(const gl::Context *context,
|
||||
}
|
||||
case gl::state::DIRTY_BIT_PROGRAM_EXECUTABLE:
|
||||
{
|
||||
const gl::Program *program = state.getProgram();
|
||||
const gl::ProgramExecutable *executable = state.getProgramExecutable();
|
||||
|
||||
if (program && executable)
|
||||
if (executable)
|
||||
{
|
||||
iter.setLaterBit(gl::state::DIRTY_BIT_TEXTURE_BINDINGS);
|
||||
|
||||
@@ -2252,39 +2251,39 @@ angle::Result StateManagerGL::syncState(const gl::Context *context,
|
||||
iter.setLaterBit(gl::state::DIRTY_BIT_IMAGE_BINDINGS);
|
||||
}
|
||||
|
||||
if (program->getActiveShaderStorageBlockCount() > 0)
|
||||
if (executable->getActiveShaderStorageBlockCount() > 0)
|
||||
{
|
||||
iter.setLaterBit(gl::state::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING);
|
||||
}
|
||||
|
||||
if (program->getActiveUniformBlockCount() > 0)
|
||||
if (executable->getActiveUniformBlockCount() > 0)
|
||||
{
|
||||
iter.setLaterBit(gl::state::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS);
|
||||
}
|
||||
|
||||
if (program->getActiveAtomicCounterBufferCount() > 0)
|
||||
if (executable->getActiveAtomicCounterBufferCount() > 0)
|
||||
{
|
||||
iter.setLaterBit(gl::state::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING);
|
||||
}
|
||||
|
||||
if (mIsMultiviewEnabled && program->usesMultiview())
|
||||
if (mIsMultiviewEnabled && executable->usesMultiview())
|
||||
{
|
||||
updateMultiviewBaseViewLayerIndexUniform(
|
||||
program, state.getDrawFramebuffer()->getImplementation()->getState());
|
||||
executable,
|
||||
state.getDrawFramebuffer()->getImplementation()->getState());
|
||||
}
|
||||
|
||||
if (mFeatures.emulateClipDistanceState.enabled)
|
||||
{
|
||||
updateEmulatedClipDistanceState(executable, program,
|
||||
updateEmulatedClipDistanceState(executable,
|
||||
state.getEnabledClipDistances());
|
||||
}
|
||||
}
|
||||
|
||||
if (!program ||
|
||||
!program->getExecutable().hasLinkedShaderStage(gl::ShaderType::Compute))
|
||||
if (!executable || !executable->hasLinkedShaderStage(gl::ShaderType::Compute))
|
||||
{
|
||||
ANGLE_TRY(propagateProgramToVAO(
|
||||
context, program, GetImplAs<VertexArrayGL>(state.getVertexArray())));
|
||||
context, executable, GetImplAs<VertexArrayGL>(state.getVertexArray())));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2367,7 +2366,6 @@ angle::Result StateManagerGL::syncState(const gl::Context *context,
|
||||
if (mFeatures.emulateClipDistanceState.enabled)
|
||||
{
|
||||
updateEmulatedClipDistanceState(state.getProgramExecutable(),
|
||||
state.getProgram(),
|
||||
state.getEnabledClipDistances());
|
||||
}
|
||||
break;
|
||||
@@ -2690,7 +2688,7 @@ void StateManagerGL::setTextureCubemapSeamlessEnabled(bool enabled)
|
||||
}
|
||||
|
||||
angle::Result StateManagerGL::propagateProgramToVAO(const gl::Context *context,
|
||||
const gl::Program *program,
|
||||
const gl::ProgramExecutable *executable,
|
||||
VertexArrayGL *vao)
|
||||
{
|
||||
if (vao == nullptr)
|
||||
@@ -2701,45 +2699,44 @@ angle::Result StateManagerGL::propagateProgramToVAO(const gl::Context *context,
|
||||
// Number of views:
|
||||
if (mIsMultiviewEnabled)
|
||||
{
|
||||
int programNumViews = 1;
|
||||
if (program && program->usesMultiview())
|
||||
int numViews = 1;
|
||||
if (executable && executable->usesMultiview())
|
||||
{
|
||||
programNumViews = program->getNumViews();
|
||||
numViews = executable->getNumViews();
|
||||
}
|
||||
ANGLE_TRY(vao->applyNumViewsToDivisor(context, programNumViews));
|
||||
ANGLE_TRY(vao->applyNumViewsToDivisor(context, numViews));
|
||||
}
|
||||
|
||||
// Attribute enabled mask:
|
||||
if (program)
|
||||
if (executable)
|
||||
{
|
||||
ANGLE_TRY(vao->applyActiveAttribLocationsMask(
|
||||
context, program->getExecutable().getActiveAttribLocationsMask()));
|
||||
ANGLE_TRY(vao->applyActiveAttribLocationsMask(context,
|
||||
executable->getActiveAttribLocationsMask()));
|
||||
}
|
||||
|
||||
return angle::Result::Continue;
|
||||
}
|
||||
|
||||
void StateManagerGL::updateMultiviewBaseViewLayerIndexUniformImpl(
|
||||
const gl::Program *program,
|
||||
const gl::ProgramExecutable *executable,
|
||||
const gl::FramebufferState &drawFramebufferState) const
|
||||
{
|
||||
ASSERT(mIsMultiviewEnabled && program && program->usesMultiview());
|
||||
const ProgramGL *programGL = GetImplAs<ProgramGL>(program);
|
||||
ASSERT(mIsMultiviewEnabled && executable && executable->usesMultiview());
|
||||
const ProgramExecutableGL *executableGL = GetImplAs<ProgramExecutableGL>(executable);
|
||||
if (drawFramebufferState.isMultiview())
|
||||
{
|
||||
programGL->enableLayeredRenderingPath(drawFramebufferState.getBaseViewIndex());
|
||||
executableGL->enableLayeredRenderingPath(drawFramebufferState.getBaseViewIndex());
|
||||
}
|
||||
}
|
||||
|
||||
void StateManagerGL::updateEmulatedClipDistanceState(const gl::ProgramExecutable *executable,
|
||||
const gl::Program *program,
|
||||
const gl::ClipDistanceEnableBits enables) const
|
||||
{
|
||||
ASSERT(mFeatures.emulateClipDistanceState.enabled);
|
||||
if (executable && executable->hasClipDistance())
|
||||
{
|
||||
const ProgramGL *programGL = GetImplAs<ProgramGL>(program);
|
||||
programGL->updateEnabledClipDistances(static_cast<uint8_t>(enables.bits()));
|
||||
const ProgramExecutableGL *executableGL = GetImplAs<ProgramExecutableGL>(executable);
|
||||
executableGL->updateEnabledClipDistances(static_cast<uint8_t>(enables.bits()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -290,12 +290,12 @@ class StateManagerGL final : angle::NonCopyable
|
||||
const gl::state::ExtendedDirtyBits &extendedBitMask);
|
||||
|
||||
ANGLE_INLINE void updateMultiviewBaseViewLayerIndexUniform(
|
||||
const gl::Program *program,
|
||||
const gl::ProgramExecutable *executable,
|
||||
const gl::FramebufferState &drawFramebufferState) const
|
||||
{
|
||||
if (mIsMultiviewEnabled && program && program->usesMultiview())
|
||||
if (mIsMultiviewEnabled && executable && executable->usesMultiview())
|
||||
{
|
||||
updateMultiviewBaseViewLayerIndexUniformImpl(program, drawFramebufferState);
|
||||
updateMultiviewBaseViewLayerIndexUniformImpl(executable, drawFramebufferState);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,7 +322,7 @@ class StateManagerGL final : angle::NonCopyable
|
||||
void setTextureCubemapSeamlessEnabled(bool enabled);
|
||||
|
||||
angle::Result propagateProgramToVAO(const gl::Context *context,
|
||||
const gl::Program *program,
|
||||
const gl::ProgramExecutable *executable,
|
||||
VertexArrayGL *vao);
|
||||
|
||||
void updateProgramTextureBindings(const gl::Context *context);
|
||||
@@ -344,11 +344,10 @@ class StateManagerGL final : angle::NonCopyable
|
||||
void syncTransformFeedbackState(const gl::Context *context);
|
||||
|
||||
void updateEmulatedClipDistanceState(const gl::ProgramExecutable *executable,
|
||||
const gl::Program *program,
|
||||
const gl::ClipDistanceEnableBits enables) const;
|
||||
|
||||
void updateMultiviewBaseViewLayerIndexUniformImpl(
|
||||
const gl::Program *program,
|
||||
const gl::ProgramExecutable *executable,
|
||||
const gl::FramebufferState &drawFramebufferState) const;
|
||||
|
||||
void syncBlendFromNativeContext(const gl::Extensions &extensions, ExternalContextState *state);
|
||||
|
||||
@@ -482,17 +482,16 @@ bool ValidateTextureMaxAnisotropyValue(const Context *context,
|
||||
|
||||
bool ValidateFragmentShaderColorBufferMaskMatch(const Context *context)
|
||||
{
|
||||
const auto &glState = context->getState();
|
||||
const Program *program = context->getActiveLinkedProgram();
|
||||
const Framebuffer *framebuffer = glState.getDrawFramebuffer();
|
||||
const auto &glState = context->getState();
|
||||
const ProgramExecutable *executable = context->getState().getLinkedProgramExecutable(context);
|
||||
const Framebuffer *framebuffer = glState.getDrawFramebuffer();
|
||||
|
||||
const auto &blendStateExt = glState.getBlendStateExt();
|
||||
auto drawBufferMask = framebuffer->getDrawBufferMask() & blendStateExt.compareColorMask(0);
|
||||
auto dualSourceBlendingMask = drawBufferMask & blendStateExt.getEnabledMask() &
|
||||
blendStateExt.getUsesExtendedBlendFactorMask();
|
||||
auto fragmentOutputMask = program->getExecutable().getActiveOutputVariablesMask();
|
||||
auto fragmentSecondaryOutputMask =
|
||||
program->getExecutable().getActiveSecondaryOutputVariablesMask();
|
||||
auto fragmentOutputMask = executable->getActiveOutputVariablesMask();
|
||||
auto fragmentSecondaryOutputMask = executable->getActiveSecondaryOutputVariablesMask();
|
||||
|
||||
return drawBufferMask == (drawBufferMask & fragmentOutputMask) &&
|
||||
dualSourceBlendingMask == (dualSourceBlendingMask & fragmentSecondaryOutputMask);
|
||||
@@ -511,11 +510,11 @@ bool ValidateFragmentShaderColorBufferTypeMatch(const Context *context)
|
||||
|
||||
bool ValidateVertexShaderAttributeTypeMatch(const Context *context)
|
||||
{
|
||||
const auto &glState = context->getState();
|
||||
const Program *program = context->getActiveLinkedProgram();
|
||||
const VertexArray *vao = context->getState().getVertexArray();
|
||||
const auto &glState = context->getState();
|
||||
const ProgramExecutable *executable = context->getState().getLinkedProgramExecutable(context);
|
||||
const VertexArray *vao = context->getState().getVertexArray();
|
||||
|
||||
if (!program)
|
||||
if (executable == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -528,9 +527,8 @@ bool ValidateVertexShaderAttributeTypeMatch(const Context *context)
|
||||
vaoAttribTypeBits = (vaoAttribEnabledMask & vaoAttribTypeBits);
|
||||
vaoAttribTypeBits |= (~vaoAttribEnabledMask & stateCurrentValuesTypeBits);
|
||||
|
||||
const ProgramExecutable &executable = program->getExecutable();
|
||||
return ValidateComponentTypeMasks(executable.getAttributesTypeMask().to_ulong(),
|
||||
vaoAttribTypeBits, executable.getAttributesMask().to_ulong(),
|
||||
return ValidateComponentTypeMasks(executable->getAttributesTypeMask().to_ulong(),
|
||||
vaoAttribTypeBits, executable->getAttributesMask().to_ulong(),
|
||||
0xFFFF);
|
||||
}
|
||||
|
||||
@@ -4402,7 +4400,7 @@ const char *ValidateDrawStates(const Context *context, GLenum *outErrorCode)
|
||||
}
|
||||
|
||||
// Validate that we are rendering with a linked program.
|
||||
if (executable == nullptr)
|
||||
if (!program->isLinked())
|
||||
{
|
||||
return kProgramNotLinked;
|
||||
}
|
||||
|
||||
@@ -398,6 +398,12 @@ class MultiviewRenderDualViewTest : public MultiviewRenderTest
|
||||
GLuint mProgram;
|
||||
};
|
||||
|
||||
class MultiviewRenderDualViewTestNoWebGL : public MultiviewRenderDualViewTest
|
||||
{
|
||||
protected:
|
||||
MultiviewRenderDualViewTestNoWebGL() { setWebGLCompatibilityEnabled(false); }
|
||||
};
|
||||
|
||||
// Base class for tests that care mostly about draw call validity and not rendering results.
|
||||
class MultiviewDrawValidationTest : public MultiviewTest
|
||||
{
|
||||
@@ -930,6 +936,116 @@ TEST_P(MultiviewRenderDualViewTest, DrawArrays)
|
||||
checkOutput();
|
||||
}
|
||||
|
||||
// The test checks that glDrawArrays can be used to render into two views, after the program
|
||||
// executable has been installed and the program relinked (with a failing link, and using a
|
||||
// different number of views).
|
||||
TEST_P(MultiviewRenderDualViewTestNoWebGL, DrawArraysAfterFailedRelink)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!requestMultiviewExtension(isMultisampled()));
|
||||
ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D());
|
||||
|
||||
std::string ext =
|
||||
GetParam().mMultiviewExtension == multiview ? "GL_OVR_multiview" : "GL_OVR_multiview2";
|
||||
|
||||
const std::string kVS = R"(#version 300 es
|
||||
#extension )" + ext + R"( : require
|
||||
layout(num_views = 2) in;
|
||||
void main()
|
||||
{
|
||||
vec2 pos = vec2(0.0);
|
||||
switch (gl_VertexID) {
|
||||
case 0: pos = vec2(-1.0, -1.0); break;
|
||||
case 1: pos = vec2(1.0, -1.0); break;
|
||||
case 2: pos = vec2(-1.0, 1.0); break;
|
||||
case 3: pos = vec2(1.0, 1.0); break;
|
||||
};
|
||||
pos.x = gl_ViewID_OVR == 0u ? pos.x * 0.5 + 0.5 : pos.x * 0.5 - 0.5;
|
||||
gl_Position = vec4(pos, 0.0, 1.0);
|
||||
})";
|
||||
|
||||
const std::string kFS = R"(#version 300 es
|
||||
#extension )" + ext + R"( : require
|
||||
precision mediump float;
|
||||
out vec4 col;
|
||||
void main()
|
||||
{
|
||||
col = vec4(0, 1, 0, 1);
|
||||
})";
|
||||
|
||||
const std::string kBadVS = R"(#version 300 es
|
||||
#extension )" + ext + R"( : require
|
||||
layout(num_views = 4) in;
|
||||
out vec4 linkError;
|
||||
void main()
|
||||
{
|
||||
vec2 pos = vec2(0.0);
|
||||
switch (gl_VertexID) {
|
||||
case 0: pos = vec2(-1.0, -1.0); break;
|
||||
case 1: pos = vec2(1.0, -1.0); break;
|
||||
case 2: pos = vec2(-1.0, 1.0); break;
|
||||
case 3: pos = vec2(1.0, 1.0); break;
|
||||
};
|
||||
pos.x = gl_ViewID_OVR == 0u ? pos.x * 0.5 + 0.5 : pos.x * 0.5 - 0.5;
|
||||
gl_Position = vec4(pos, 0.0, 1.0);
|
||||
linkError = vec4(0);
|
||||
})";
|
||||
|
||||
const std::string kBadFS = R"(#version 300 es
|
||||
#extension )" + ext + R"( : require
|
||||
precision mediump float;
|
||||
flat in uvec4 linkError;
|
||||
out vec4 col;
|
||||
void main()
|
||||
{
|
||||
col = vec4(linkError);
|
||||
})";
|
||||
|
||||
// First, create a good program
|
||||
GLuint program = glCreateProgram();
|
||||
GLuint vs = CompileShader(GL_VERTEX_SHADER, kVS.c_str());
|
||||
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, kFS.c_str());
|
||||
|
||||
glAttachShader(program, vs);
|
||||
glAttachShader(program, fs);
|
||||
|
||||
glLinkProgram(program);
|
||||
CheckLinkStatusAndReturnProgram(program, true);
|
||||
|
||||
// Detach the shaders for the sake of DrawArraysAfterFailedRelink
|
||||
glDetachShader(program, vs);
|
||||
glDetachShader(program, fs);
|
||||
|
||||
glDeleteShader(vs);
|
||||
glDeleteShader(fs);
|
||||
|
||||
// Install the executable
|
||||
glUseProgram(program);
|
||||
|
||||
// Relink the program but in an erroneous way
|
||||
GLuint badVs = CompileShader(GL_VERTEX_SHADER, kBadVS.c_str());
|
||||
GLuint badFs = CompileShader(GL_FRAGMENT_SHADER, kBadFS.c_str());
|
||||
|
||||
glAttachShader(program, badVs);
|
||||
glAttachShader(program, badFs);
|
||||
|
||||
glLinkProgram(program);
|
||||
|
||||
glDeleteShader(badVs);
|
||||
glDeleteShader(badFs);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
// Issue a draw and make sure everything works.
|
||||
glClearColor(0, 0, 0, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
// drawQuad(mProgram, "vPosition", 0.0f, 1.0f, true);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
checkOutput();
|
||||
|
||||
glDeleteProgram(program);
|
||||
}
|
||||
|
||||
// The test checks that glDrawElements can be used to render into two views.
|
||||
TEST_P(MultiviewRenderDualViewTest, DrawElements)
|
||||
{
|
||||
@@ -2377,6 +2493,11 @@ ANGLE_INSTANTIATE_TEST(MultiviewRenderDualViewTest,
|
||||
ALL_SINGLESAMPLE_CONFIGS(),
|
||||
ALL_MULTISAMPLE_CONFIGS());
|
||||
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MultiviewRenderDualViewTestNoWebGL);
|
||||
ANGLE_INSTANTIATE_TEST(MultiviewRenderDualViewTestNoWebGL,
|
||||
ALL_SINGLESAMPLE_CONFIGS(),
|
||||
ALL_MULTISAMPLE_CONFIGS());
|
||||
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MultiviewRenderTest);
|
||||
ANGLE_INSTANTIATE_TEST(MultiviewRenderTest, ALL_SINGLESAMPLE_CONFIGS(), ALL_MULTISAMPLE_CONFIGS());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user