Commit 0df0b79c by Ian Elliott Committed by Commit Bot

Vulkan: Optimize changing texture max level

For applications that frequently change the texture max level, to a value that is a subset of the texture's maximum levels, just recreate the VkImageView's. Test: NBA 2K20 game play Bug: b/160976091 Change-Id: I62a05a90cdb90147056ba8cec960c2114479ec37 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2300532Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Ian Elliott <ianelliott@google.com>
parent 49108a12
...@@ -97,7 +97,7 @@ TextureState::TextureState(TextureType type) ...@@ -97,7 +97,7 @@ TextureState::TextureState(TextureType type)
mSamplerState(SamplerState::CreateDefaultForTarget(type)), mSamplerState(SamplerState::CreateDefaultForTarget(type)),
mSrgbOverride(SrgbOverride::Default), mSrgbOverride(SrgbOverride::Default),
mBaseLevel(0), mBaseLevel(0),
mMaxLevel(1000), mMaxLevel(kInitialMaxLevel),
mDepthStencilTextureMode(GL_DEPTH_COMPONENT), mDepthStencilTextureMode(GL_DEPTH_COMPONENT),
mImmutableFormat(false), mImmutableFormat(false),
mImmutableLevels(0), mImmutableLevels(0),
......
...@@ -48,6 +48,8 @@ class Sampler; ...@@ -48,6 +48,8 @@ class Sampler;
class State; class State;
class Texture; class Texture;
constexpr GLuint kInitialMaxLevel = 1000;
bool IsMipmapFiltered(const SamplerState &samplerState); bool IsMipmapFiltered(const SamplerState &samplerState);
struct ImageDesc final struct ImageDesc final
......
...@@ -1523,9 +1523,11 @@ angle::Result TextureVk::updateBaseMaxLevels(ContextVk *contextVk, ...@@ -1523,9 +1523,11 @@ angle::Result TextureVk::updateBaseMaxLevels(ContextVk *contextVk,
// Track the previous levels for use in update loop below // Track the previous levels for use in update loop below
uint32_t previousBaseLevel = mImage->getBaseLevel(); uint32_t previousBaseLevel = mImage->getBaseLevel();
uint32_t previousMaxLevel = mImage->getMaxLevel();
ASSERT(baseLevel <= maxLevel);
bool baseLevelChanged = baseLevel != previousBaseLevel; bool baseLevelChanged = baseLevel != previousBaseLevel;
bool maxLevelChanged = (mImage->getLevelCount() + previousBaseLevel) != (maxLevel + 1); bool maxLevelChanged = (previousMaxLevel != maxLevel);
if (!(baseLevelChanged || maxLevelChanged)) if (!(baseLevelChanged || maxLevelChanged))
{ {
...@@ -1543,6 +1545,33 @@ angle::Result TextureVk::updateBaseMaxLevels(ContextVk *contextVk, ...@@ -1543,6 +1545,33 @@ angle::Result TextureVk::updateBaseMaxLevels(ContextVk *contextVk,
return angle::Result::Continue; return angle::Result::Continue;
} }
// With a valid image, check if only changing the maxLevel to a subset of the texture's actual
// number of mip levels
if (!baseLevelChanged && (maxLevel < baseLevel + mImage->getLevelCount()))
{
// Don't need to respecify the texture; just redo the texture's vkImageViews
ASSERT(maxLevelChanged);
// Release the current vkImageViews
RendererVk *renderer = contextVk->getRenderer();
mImageViews.release(renderer);
// Track the levels in our ImageHelper
mImage->setBaseAndMaxLevels(baseLevel, maxLevel);
// Update the texture's serial so that the descriptor set is updated correctly
mSerial = contextVk->generateTextureSerial();
// Change the vkImageViews
const gl::ImageDesc &baseLevelDesc = mState.getBaseLevelDesc();
// We use a special layer count here to handle EGLImages. They might only be
// looking at one layer of a cube or 2D array texture.
uint32_t layerCount =
mState.getType() == gl::TextureType::_2D ? 1 : mImage->getLayerCount();
return initImageViews(contextVk, mImage->getFormat(), baseLevelDesc.format.info->sized,
maxLevel - baseLevel + 1, layerCount);
}
return respecifyImageAttributesAndLevels(contextVk, previousBaseLevel, baseLevel, maxLevel); return respecifyImageAttributesAndLevels(contextVk, previousBaseLevel, baseLevel, maxLevel);
} }
......
...@@ -1361,6 +1361,7 @@ class ImageHelper final : public Resource, public angle::Subject ...@@ -1361,6 +1361,7 @@ class ImageHelper final : public Resource, public angle::Subject
uint32_t getBaseLevel() const { return mBaseLevel; } uint32_t getBaseLevel() const { return mBaseLevel; }
void setBaseAndMaxLevels(uint32_t baseLevel, uint32_t maxLevel); void setBaseAndMaxLevels(uint32_t baseLevel, uint32_t maxLevel);
uint32_t getMaxLevel() const { return mMaxLevel; }
angle::Result copyImageDataToBuffer(ContextVk *contextVk, angle::Result copyImageDataToBuffer(ContextVk *contextVk,
size_t sourceLevelGL, size_t sourceLevelGL,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment