| // |
| // 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 |