Hash :
b007c74d
Author :
Date :
2024-01-23T14:17:54
GL: Separate dirty bits leading to glUniformBlockBinding The GL backend is special in that it needs to make actual calls (native glUniformBlockBinding) in response to (application) glUniformBlockBinding calls. The other backends just remap the bindings based on that information when creating descriptor sets. Previously, an optimization to track which bindings have changed used the same dirty bits that were used to signify when the GL backend needs to make these native calls. That ended up as a source of bugs. In a previous change [1], the context DIRTY_BIT_UNIFORM_BUFFER_BINDINGS is set when these mappings change, which fixes some of these issues. That change obviates the need for an actual backend sync of programs, except for GL programs that need to make these native calls. This change splits the dirty bits maintained for the purposes of the GL backend, moves them to that backend and removes the program backend sync. [1]: https://chromium-review.googlesource.com/c/angle/angle/+/5228599 Bug: angleproject:8493 Bug: b/318806125 Change-Id: I73c6514e88a116f1cd701cb06da0d8c38f07f7f6 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5230137 Reviewed-by: Geoff Lang <geofflang@chromium.org> Reviewed-by: Charlie Lao <cclao@google.com> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
//
// Copyright 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ProgramImpl.h: Defines the abstract rx::ProgramImpl class.
#ifndef LIBANGLE_RENDERER_PROGRAMIMPL_H_
#define LIBANGLE_RENDERER_PROGRAMIMPL_H_
#include "common/BinaryStream.h"
#include "common/WorkerThread.h"
#include "common/angleutils.h"
#include "libANGLE/Constants.h"
#include "libANGLE/Program.h"
#include "libANGLE/Shader.h"
#include <functional>
#include <map>
namespace gl
{
class Context;
struct ProgramLinkedResources;
} // namespace gl
namespace sh
{
struct BlockMemberInfo;
}
namespace rx
{
// The link job is split as such:
//
// - Front-end link
// - Back-end link
// - Independent back-end link subtasks (typically native driver compile jobs)
// - Post-link finalization
//
// Each step depends on the previous. These steps are executed as such:
//
// 1. Program::link calls into ProgramImpl::link
// - ProgramImpl::link runs whatever needs the Context, such as releasing resources
// - ProgramImpl::link returns a LinkTask
// 2. Program::link implements a closure that calls the front-end link and passes the results to
// the backend's LinkTask.
// 3. The LinkTask potentially returns a set of LinkSubTasks to be scheduled by the worker pool
// 4. Once the link is resolved, the post-link finalization is run
//
// In the above, steps 1 and 4 are done under the share group lock. Steps 2 and 3 can be done in
// threads or without holding the share group lock if the backend supports it.
class LinkSubTask : public angle::Closure
{
public:
~LinkSubTask() override = default;
virtual angle::Result getResult(const gl::Context *context, gl::InfoLog &infoLog) = 0;
};
class LinkTask
{
public:
virtual ~LinkTask() = default;
// Used for link()
virtual std::vector<std::shared_ptr<LinkSubTask>> link(
const gl::ProgramLinkedResources &resources,
const gl::ProgramMergedVaryings &mergedVaryings,
bool *areSubTasksOptionalOut);
// Used for load()
virtual std::vector<std::shared_ptr<LinkSubTask>> load(bool *areSubTasksOptionalOut);
virtual angle::Result getResult(const gl::Context *context, gl::InfoLog &infoLog) = 0;
// Used by the GL backend to query whether the driver is linking in parallel internally.
virtual bool isLinkingInternally();
};
class ProgramImpl : angle::NonCopyable
{
public:
ProgramImpl(const gl::ProgramState &state) : mState(state) {}
virtual ~ProgramImpl() {}
virtual void destroy(const gl::Context *context) {}
virtual angle::Result load(const gl::Context *context,
gl::BinaryInputStream *stream,
std::shared_ptr<LinkTask> *loadTaskOut,
egl::CacheGetResult *resultOut) = 0;
virtual void save(const gl::Context *context, gl::BinaryOutputStream *stream) = 0;
virtual void setBinaryRetrievableHint(bool retrievable) = 0;
virtual void setSeparable(bool separable) = 0;
virtual void prepareForLink(const gl::ShaderMap<ShaderImpl *> &shaders) {}
virtual angle::Result link(const gl::Context *context,
std::shared_ptr<LinkTask> *linkTaskOut) = 0;
virtual GLboolean validate(const gl::Caps &caps) = 0;
// Implementation-specific method for ignoring unreferenced uniforms. Some implementations may
// perform more extensive analysis and ignore some locations that ANGLE doesn't detect as
// unreferenced. This method is not required to be overriden by a back-end.
virtual void markUnusedUniformLocations(std::vector<gl::VariableLocation> *uniformLocations,
std::vector<gl::SamplerBinding> *samplerBindings,
std::vector<gl::ImageBinding> *imageBindings)
{}
const gl::ProgramState &getState() const { return mState; }
virtual angle::Result onLabelUpdate(const gl::Context *context);
// Called when glUniformBlockBinding is called.
virtual void onUniformBlockBinding(gl::UniformBlockIndex uniformBlockIndex) {}
protected:
const gl::ProgramState &mState;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_PROGRAMIMPL_H_