Use timestamps for image descriptor updates (#3152)
This commit is contained in:
@@ -60,7 +60,7 @@ public:
|
||||
|
||||
void allocate();
|
||||
|
||||
void markDirty(bool value = true);
|
||||
virtual void markDirty();
|
||||
void bind(CommandEncoder& encoder);
|
||||
|
||||
protected:
|
||||
@@ -91,7 +91,13 @@ public:
|
||||
ImageDescriptorSet(Context& context_);
|
||||
virtual ~ImageDescriptorSet() = default;
|
||||
|
||||
void markDirty() override;
|
||||
const std::chrono::duration<double>& getLastModified() const { return lastModified; }
|
||||
|
||||
void update(const std::array<gfx::Texture2DPtr, shaders::maxTextureCountPerShader>& textures);
|
||||
|
||||
protected:
|
||||
std::chrono::duration<double> lastModified;
|
||||
};
|
||||
|
||||
} // namespace vulkan
|
||||
|
||||
@@ -60,6 +60,7 @@ public:
|
||||
size_t numChannels() const noexcept override;
|
||||
|
||||
bool isDirty() const { return samplerStateDirty || textureDirty; }
|
||||
bool isModifiedAfter(const std::chrono::duration<double>& t) const { return t < lastModified; }
|
||||
|
||||
void create() noexcept override;
|
||||
|
||||
@@ -112,6 +113,7 @@ private:
|
||||
std::shared_ptr<PremultipliedImage> imageData{nullptr};
|
||||
bool textureDirty{true};
|
||||
bool samplerStateDirty{true};
|
||||
std::chrono::duration<double> lastModified{0};
|
||||
|
||||
SharedImageAllocation imageAllocation;
|
||||
vk::ImageLayout imageLayout{vk::ImageLayout::eUndefined};
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <mbgl/vulkan/texture2d.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
#include <mbgl/util/instrumentation.hpp>
|
||||
#include <mbgl/util/monotonic_timer.hpp>
|
||||
|
||||
#include <cassert>
|
||||
#include <math.h>
|
||||
@@ -120,8 +121,8 @@ void DescriptorSet::allocate() {
|
||||
dirty = std::vector(descriptorSets.size(), true);
|
||||
}
|
||||
|
||||
void DescriptorSet::markDirty(bool value) {
|
||||
std::fill(dirty.begin(), dirty.end(), value);
|
||||
void DescriptorSet::markDirty() {
|
||||
std::fill(dirty.begin(), dirty.end(), true);
|
||||
}
|
||||
|
||||
void DescriptorSet::bind(CommandEncoder& encoder) {
|
||||
@@ -186,7 +187,14 @@ void UniformDescriptorSet::update(const gfx::UniformBufferArray& uniforms,
|
||||
}
|
||||
|
||||
ImageDescriptorSet::ImageDescriptorSet(Context& context_)
|
||||
: DescriptorSet(context_, DescriptorSetType::DrawableImage) {}
|
||||
: DescriptorSet(context_, DescriptorSetType::DrawableImage),
|
||||
lastModified(0.0) {}
|
||||
|
||||
void ImageDescriptorSet::markDirty() {
|
||||
DescriptorSet::markDirty();
|
||||
|
||||
lastModified = util::MonotonicTimer::now();
|
||||
}
|
||||
|
||||
void ImageDescriptorSet::update(const std::array<gfx::Texture2DPtr, shaders::maxTextureCountPerShader>& textures) {
|
||||
MLN_TRACE_FUNC();
|
||||
|
||||
@@ -436,8 +436,8 @@ bool Drawable::bindDescriptors(CommandEncoder& encoder) const noexcept {
|
||||
for (const auto& texture : textures) {
|
||||
if (!texture) continue;
|
||||
const auto textureImpl = static_cast<const Texture2D*>(texture.get());
|
||||
if (textureImpl->isDirty()) {
|
||||
impl->imageDescriptorSet->markDirty(true);
|
||||
if (textureImpl->isModifiedAfter(impl->imageDescriptorSet->getLastModified())) {
|
||||
impl->imageDescriptorSet->markDirty();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -362,7 +362,9 @@ void Texture2D::createTexture() {
|
||||
context.renderingStats().numCreatedTextures++;
|
||||
context.renderingStats().numActiveTextures++;
|
||||
context.renderingStats().memTextures += getDataSize();
|
||||
|
||||
textureDirty = false;
|
||||
lastModified = util::MonotonicTimer::now();
|
||||
}
|
||||
|
||||
void Texture2D::createSampler() {
|
||||
@@ -392,6 +394,7 @@ void Texture2D::createSampler() {
|
||||
sampler = context.getBackend().getDevice()->createSampler(samplerCreateInfo);
|
||||
|
||||
samplerStateDirty = false;
|
||||
lastModified = util::MonotonicTimer::now();
|
||||
}
|
||||
|
||||
void Texture2D::destroyTexture() {
|
||||
|
||||
Reference in New Issue
Block a user