Hash :
1efcbdb6
Author :
Date :
2019-10-22T12:32:04
Vulkan: Fix sampler object lifetime. Using the same scheme as we do for VkImageViews we can track VkSampler lifetime using SharedResourceUse. This fixes the race condition that could occur when samplers are deleted in one Context while being used in another. This fixes the last known resource lifetime issue. The multithreading tests should now pass without validation errors. Also adds regression tests to angle_end2end_tests. Bug: angleproject:2464 Change-Id: I9dbed5062a0863b240ddf1a9b5d28560334934de Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1869548 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Ian Elliott <ianelliott@google.com> Reviewed-by: Tim Van Patten <timvp@google.com>
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
//
// Copyright 2016 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.
//
// SamplerVk.cpp:
// Implements the class methods for SamplerVk.
//
#include "libANGLE/renderer/vulkan/SamplerVk.h"
#include "common/debug.h"
#include "libANGLE/Context.h"
#include "libANGLE/renderer/vulkan/vk_utils.h"
namespace rx
{
SamplerVk::SamplerVk(const gl::SamplerState &state) : SamplerImpl(state), mSerial{} {}
SamplerVk::~SamplerVk() = default;
void SamplerVk::onDestroy(const gl::Context *context)
{
ContextVk *contextVk = vk::GetImpl(context);
mSampler.release(contextVk->getRenderer());
}
angle::Result SamplerVk::syncState(const gl::Context *context, const bool dirty)
{
ContextVk *contextVk = vk::GetImpl(context);
RendererVk *renderer = contextVk->getRenderer();
if (mSampler.valid())
{
if (!dirty)
{
return angle::Result::Continue;
}
mSampler.release(renderer);
}
const gl::Extensions &extensions = renderer->getNativeExtensions();
float maxAnisotropy = mState.getMaxAnisotropy();
bool anisotropyEnable = extensions.textureFilterAnisotropic && maxAnisotropy > 1.0f;
VkSamplerCreateInfo samplerInfo = {};
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
samplerInfo.flags = 0;
samplerInfo.magFilter = gl_vk::GetFilter(mState.getMagFilter());
samplerInfo.minFilter = gl_vk::GetFilter(mState.getMinFilter());
samplerInfo.mipmapMode = gl_vk::GetSamplerMipmapMode(mState.getMinFilter());
samplerInfo.addressModeU = gl_vk::GetSamplerAddressMode(mState.getWrapS());
samplerInfo.addressModeV = gl_vk::GetSamplerAddressMode(mState.getWrapT());
samplerInfo.addressModeW = gl_vk::GetSamplerAddressMode(mState.getWrapR());
samplerInfo.mipLodBias = 0.0f;
samplerInfo.anisotropyEnable = anisotropyEnable;
samplerInfo.maxAnisotropy = maxAnisotropy;
samplerInfo.compareEnable = mState.getCompareMode() == GL_COMPARE_REF_TO_TEXTURE;
samplerInfo.compareOp = gl_vk::GetCompareOp(mState.getCompareFunc());
samplerInfo.minLod = mState.getMinLod();
samplerInfo.maxLod = mState.getMaxLod();
samplerInfo.borderColor = VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
samplerInfo.unnormalizedCoordinates = VK_FALSE;
if (!gl::IsMipmapFiltered(mState))
{
// Per the Vulkan spec, GL_NEAREST and GL_LINEAR do not map directly to Vulkan, so
// they must be emulated (See "Mapping of OpenGL to Vulkan filter modes")
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
samplerInfo.minLod = 0.0f;
samplerInfo.maxLod = 0.25f;
}
ANGLE_VK_TRY(contextVk, mSampler.get().init(contextVk->getDevice(), samplerInfo));
// Regenerate the serial on a sampler change.
mSerial = contextVk->generateTextureSerial();
return angle::Result::Continue;
}
} // namespace rx