[Impeller] when mips are disabled, also disable from sampler options. (#161765)
If we have disabled mipmap generation on a platform due to GPU driver bugs, make sure that all sampling options used declare that only the base mip level should be read. Otherwise we can end up sampling from unpopulated mip levels.
This commit is contained in:
parent
5e24ac89bc
commit
fe257cbf5a
@ -24,6 +24,7 @@ impeller_component("vulkan_unittests") {
|
||||
"test/mock_vulkan.cc",
|
||||
"test/mock_vulkan.h",
|
||||
"test/mock_vulkan_unittests.cc",
|
||||
"test/sampler_library_vk_unittests.cc",
|
||||
"test/swapchain_unittests.cc",
|
||||
]
|
||||
deps = [
|
||||
|
@ -464,6 +464,7 @@ void ContextVK::Setup(Settings settings) {
|
||||
std::make_unique<DriverInfoVK>(device_holder->physical_device);
|
||||
workarounds_ = GetWorkaroundsFromDriverInfo(*driver_info);
|
||||
caps->ApplyWorkarounds(workarounds_);
|
||||
sampler_library->ApplyWorkarounds(workarounds_);
|
||||
|
||||
device_holder_ = std::move(device_holder);
|
||||
idle_waiter_vk_ = std::make_shared<IdleWaiterVK>(device_holder_);
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "impeller/renderer/backend/vulkan/sampler_library_vk.h"
|
||||
|
||||
#include "impeller/core/formats.h"
|
||||
#include "impeller/renderer/backend/vulkan/sampler_vk.h"
|
||||
|
||||
namespace impeller {
|
||||
@ -14,9 +15,18 @@ SamplerLibraryVK::SamplerLibraryVK(
|
||||
|
||||
SamplerLibraryVK::~SamplerLibraryVK() = default;
|
||||
|
||||
void SamplerLibraryVK::ApplyWorkarounds(const WorkaroundsVK& workarounds) {
|
||||
mips_disabled_workaround_ = workarounds.broken_mipmap_generation;
|
||||
}
|
||||
|
||||
raw_ptr<const Sampler> SamplerLibraryVK::GetSampler(
|
||||
const SamplerDescriptor& desc) {
|
||||
uint64_t p_key = SamplerDescriptor::ToKey(desc);
|
||||
SamplerDescriptor desc_copy = desc;
|
||||
if (mips_disabled_workaround_) {
|
||||
desc_copy.mip_filter = MipFilter::kBase;
|
||||
}
|
||||
|
||||
uint64_t p_key = SamplerDescriptor::ToKey(desc_copy);
|
||||
for (const auto& [key, value] : samplers_) {
|
||||
if (key == p_key) {
|
||||
return raw_ptr(value);
|
||||
@ -27,7 +37,8 @@ raw_ptr<const Sampler> SamplerLibraryVK::GetSampler(
|
||||
return raw_ptr<const Sampler>(nullptr);
|
||||
}
|
||||
samplers_.push_back(std::make_pair(
|
||||
p_key, std::make_shared<SamplerVK>(device_holder->GetDevice(), desc)));
|
||||
p_key,
|
||||
std::make_shared<SamplerVK>(device_holder->GetDevice(), desc_copy)));
|
||||
return raw_ptr(samplers_.back().second);
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "impeller/core/sampler.h"
|
||||
#include "impeller/core/sampler_descriptor.h"
|
||||
#include "impeller/renderer/backend/vulkan/device_holder_vk.h"
|
||||
#include "impeller/renderer/backend/vulkan/workarounds_vk.h"
|
||||
#include "impeller/renderer/sampler_library.h"
|
||||
|
||||
namespace impeller {
|
||||
@ -20,13 +21,16 @@ class SamplerLibraryVK final
|
||||
// |SamplerLibrary|
|
||||
~SamplerLibraryVK() override;
|
||||
|
||||
explicit SamplerLibraryVK(const std::weak_ptr<DeviceHolderVK>& device_holder);
|
||||
|
||||
void ApplyWorkarounds(const WorkaroundsVK& workarounds);
|
||||
|
||||
private:
|
||||
friend class ContextVK;
|
||||
|
||||
std::weak_ptr<DeviceHolderVK> device_holder_;
|
||||
std::vector<std::pair<uint64_t, std::shared_ptr<const Sampler>>> samplers_;
|
||||
|
||||
explicit SamplerLibraryVK(const std::weak_ptr<DeviceHolderVK>& device_holder);
|
||||
bool mips_disabled_workaround_ = false;
|
||||
|
||||
// |SamplerLibrary|
|
||||
raw_ptr<const Sampler> GetSampler(
|
||||
|
@ -37,6 +37,7 @@ class SamplerVK final : public Sampler, public BackendCast<SamplerVK, Sampler> {
|
||||
const vk::Device device_;
|
||||
SharedHandleVK<vk::Sampler> sampler_;
|
||||
std::shared_ptr<YUVConversionVK> yuv_conversion_;
|
||||
bool mips_disabled_workaround_ = false;
|
||||
bool is_valid_ = false;
|
||||
|
||||
SamplerVK(const SamplerVK&) = delete;
|
||||
|
@ -0,0 +1,39 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <memory>
|
||||
#include "flutter/testing/testing.h" // IWYU pragma: keep
|
||||
#include "gtest/gtest.h"
|
||||
#include "impeller/core/formats.h"
|
||||
#include "impeller/core/sampler_descriptor.h"
|
||||
#include "impeller/renderer/backend/vulkan/command_pool_vk.h"
|
||||
#include "impeller/renderer/backend/vulkan/sampler_library_vk.h"
|
||||
#include "impeller/renderer/backend/vulkan/test/mock_vulkan.h"
|
||||
#include "impeller/renderer/backend/vulkan/workarounds_vk.h"
|
||||
|
||||
namespace impeller {
|
||||
namespace testing {
|
||||
|
||||
TEST(SamplerLibraryVK, WorkaroundsCanDisableReadingFromMipLevels) {
|
||||
auto const context = MockVulkanContextBuilder().Build();
|
||||
|
||||
auto library_vk =
|
||||
std::make_shared<SamplerLibraryVK>(context->GetDeviceHolder());
|
||||
std::shared_ptr<SamplerLibrary> library = library_vk;
|
||||
|
||||
SamplerDescriptor desc;
|
||||
desc.mip_filter = MipFilter::kLinear;
|
||||
|
||||
auto sampler = library->GetSampler(desc);
|
||||
EXPECT_EQ(sampler->GetDescriptor().mip_filter, MipFilter::kLinear);
|
||||
|
||||
// Apply mips disabled workaround.
|
||||
library_vk->ApplyWorkarounds(WorkaroundsVK{.broken_mipmap_generation = true});
|
||||
|
||||
sampler = library->GetSampler(desc);
|
||||
EXPECT_EQ(sampler->GetDescriptor().mip_filter, MipFilter::kBase);
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
} // namespace impeller
|
Loading…
x
Reference in New Issue
Block a user