blob: 74169b7d49ad3b4871d15b8a562e0a27cc2da9f9 [file] [log] [blame]
//
// 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);
contextVk->addGarbage(&mSampler);
}
const vk::Sampler &SamplerVk::getSampler() const
{
ASSERT(mSampler.valid());
return mSampler;
}
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;
}
contextVk->addGarbage(&mSampler);
}
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.init(contextVk->getDevice(), samplerInfo));
// Regenerate the serial on a sampler change.
mSerial = contextVk->generateTextureSerial();
return angle::Result::Continue;
}
} // namespace rx