Vulkan: Remove image views forced to one mip level
textureSize requires the view to reflect actual mip levels, so
we can't artificially limit the view based on filtering mode.
This CL removes those views.
That unearthed a problem where the VK backend wasn't properly
implementing non-mipmapped filter modes. There is a blurb in
the Vulkan spec about this:
There are no Vulkan filter modes that directly correspond to OpenGL
minification filters of GL_LINEAR or GL_NEAREST, but they can be
emulated using VK_SAMPLER_MIPMAP_MODE_NEAREST, minLod = 0, and
maxLod = 0.25, and using minFilter = VK_FILTER_LINEAR or
minFilter = VK_FILTER_NEAREST, respectively.
So this CL also adds that emulation.
Bug: angleproject:3948
Test: TextureSizeTextureArrayTest.BaseLevelVariesInTextureArray
Test: dEQP-GLES3.functional.shaders.texture_functions.texturesize.*
Change-Id: I81d5c3417e7d9abd0cdd058b935963706024a28f
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1835937
Reviewed-by: Tim Van Patten <timvp@google.com>
Commit-Queue: Cody Northrop <cnorthrop@google.com>
diff --git a/src/libANGLE/renderer/vulkan/SamplerVk.cpp b/src/libANGLE/renderer/vulkan/SamplerVk.cpp
index 39b247b..74169b7 100644
--- a/src/libANGLE/renderer/vulkan/SamplerVk.cpp
+++ b/src/libANGLE/renderer/vulkan/SamplerVk.cpp
@@ -69,6 +69,15 @@
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();
diff --git a/src/libANGLE/renderer/vulkan/TextureVk.cpp b/src/libANGLE/renderer/vulkan/TextureVk.cpp
index 8bea3f2..5942851 100644
--- a/src/libANGLE/renderer/vulkan/TextureVk.cpp
+++ b/src/libANGLE/renderer/vulkan/TextureVk.cpp
@@ -112,11 +112,9 @@
void TextureVk::TextureVkViews::release(ContextVk *contextVk)
{
- contextVk->addGarbage(&mDrawBaseLevelImageView);
- contextVk->addGarbage(&mReadBaseLevelImageView);
- contextVk->addGarbage(&mReadMipmapImageView);
- contextVk->addGarbage(&mFetchBaseLevelImageView);
- contextVk->addGarbage(&mFetchMipmapImageView);
+ contextVk->addGarbage(&mDrawImageView);
+ contextVk->addGarbage(&mReadImageView);
+ contextVk->addGarbage(&mFetchImageView);
}
angle::Result TextureVk::generateMipmapLevelsWithCPU(ContextVk *contextVk,
@@ -955,9 +953,8 @@
mImage->initStagingBuffer(contextVk->getRenderer(), format, vk::kStagingBufferFlags,
mStagingBufferInitialSize);
- mRenderTarget.init(mImage, &mDefaultViews.mDrawBaseLevelImageView,
- &mDefaultViews.mFetchBaseLevelImageView, getNativeImageLevel(0),
- getNativeImageLayer(0));
+ mRenderTarget.init(mImage, &mDefaultViews.mDrawImageView, &mDefaultViews.mFetchImageView,
+ getNativeImageLevel(0), getNativeImageLayer(0));
// Force re-creation of layered render targets next time they are needed
mLayerRenderTargets.clear();
@@ -1487,6 +1484,15 @@
samplerInfo.borderColor = VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
samplerInfo.unnormalizedCoordinates = VK_FALSE;
+ if (!gl::IsMipmapFiltered(samplerState))
+ {
+ // 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.
@@ -1543,18 +1549,13 @@
ASSERT(mImage->valid());
const TextureVkViews *activeView = getTextureViews();
- if (!gl::IsMipmapFiltered(mState.getSamplerState()))
- {
- return activeView->mReadBaseLevelImageView;
- }
-
- return activeView->mReadMipmapImageView;
+ return activeView->mReadImageView;
}
const vk::ImageView &TextureVk::getFetchImageView() const
{
- if (!mDefaultViews.mFetchBaseLevelImageView.valid())
+ if (!mDefaultViews.mFetchImageView.valid())
{
return getReadImageView();
}
@@ -1562,12 +1563,7 @@
ASSERT(mImage->valid());
const TextureVkViews *activeView = getTextureViews();
- if (!gl::IsMipmapFiltered(mState.getSamplerState()))
- {
- return activeView->mFetchBaseLevelImageView;
- }
-
- return activeView->mFetchMipmapImageView;
+ return activeView->mFetchImageView;
}
vk::ImageView *TextureVk::getLayerLevelImageViewImpl(vk::LayerLevelImageViewVector *imageViews,
@@ -1752,10 +1748,7 @@
uint32_t baseLayer = getNativeImageLayer(0);
ANGLE_TRY(mImage->initLayerImageView(contextVk, mState.getType(), aspectFlags, mappedSwizzle,
- &view->mReadMipmapImageView, baseLevel, levelCount,
- baseLayer, layerCount));
- ANGLE_TRY(mImage->initLayerImageView(contextVk, mState.getType(), aspectFlags, mappedSwizzle,
- &view->mReadBaseLevelImageView, baseLevel, 1, baseLayer,
+ &view->mReadImageView, baseLevel, levelCount, baseLayer,
layerCount));
if (mState.getType() == gl::TextureType::CubeMap ||
mState.getType() == gl::TextureType::_2DArray ||
@@ -1764,17 +1757,14 @@
gl::TextureType arrayType = vk::Get2DTextureType(layerCount, mImage->getSamples());
ANGLE_TRY(mImage->initLayerImageView(contextVk, arrayType, aspectFlags, mappedSwizzle,
- &view->mFetchMipmapImageView, baseLevel, levelCount,
- baseLayer, layerCount));
- ANGLE_TRY(mImage->initLayerImageView(contextVk, arrayType, aspectFlags, mappedSwizzle,
- &view->mFetchBaseLevelImageView, baseLevel, 1,
+ &view->mFetchImageView, baseLevel, levelCount,
baseLayer, layerCount));
}
if (!format.imageFormat().isBlock)
{
ANGLE_TRY(mImage->initLayerImageView(contextVk, mState.getType(), aspectFlags,
- gl::SwizzleState(), &view->mDrawBaseLevelImageView,
- baseLevel, 1, baseLayer, layerCount));
+ gl::SwizzleState(), &view->mDrawImageView, baseLevel,
+ 1, baseLayer, layerCount));
}
return angle::Result::Continue;
diff --git a/src/libANGLE/renderer/vulkan/TextureVk.h b/src/libANGLE/renderer/vulkan/TextureVk.h
index 6c3f02a..b8edc6d 100644
--- a/src/libANGLE/renderer/vulkan/TextureVk.h
+++ b/src/libANGLE/renderer/vulkan/TextureVk.h
@@ -186,11 +186,9 @@
void release(ContextVk *contextVk);
- vk::ImageView mDrawBaseLevelImageView;
- vk::ImageView mReadBaseLevelImageView;
- vk::ImageView mReadMipmapImageView;
- vk::ImageView mFetchBaseLevelImageView;
- vk::ImageView mFetchMipmapImageView;
+ vk::ImageView mDrawImageView;
+ vk::ImageView mReadImageView;
+ vk::ImageView mFetchImageView;
};
// Transform an image index from the frontend into one that can be used on the backing
diff --git a/src/libANGLE/renderer/vulkan/vk_utils.cpp b/src/libANGLE/renderer/vulkan/vk_utils.cpp
index 2b0dba6..d332b87 100644
--- a/src/libANGLE/renderer/vulkan/vk_utils.cpp
+++ b/src/libANGLE/renderer/vulkan/vk_utils.cpp
@@ -694,10 +694,10 @@
{
switch (filter)
{
- case GL_LINEAR:
case GL_LINEAR_MIPMAP_LINEAR:
case GL_NEAREST_MIPMAP_LINEAR:
return VK_SAMPLER_MIPMAP_MODE_LINEAR;
+ case GL_LINEAR:
case GL_NEAREST:
case GL_NEAREST_MIPMAP_NEAREST:
case GL_LINEAR_MIPMAP_NEAREST:
diff --git a/src/tests/gl_tests/TextureTest.cpp b/src/tests/gl_tests/TextureTest.cpp
index ad68542..6031f04 100644
--- a/src/tests/gl_tests/TextureTest.cpp
+++ b/src/tests/gl_tests/TextureTest.cpp
@@ -5699,7 +5699,7 @@
ES3_OPENGL(),
ES3_OPENGLES(),
ES3_VULKAN());
-ANGLE_INSTANTIATE_TEST(TextureSizeTextureArrayTest, ES3_D3D11(), ES3_OPENGL());
+ANGLE_INSTANTIATE_TEST(TextureSizeTextureArrayTest, ES3_D3D11(), ES3_OPENGL(), ES3_VULKAN());
ANGLE_INSTANTIATE_TEST(SamplerInStructTest,
ES2_D3D11(),
ES2_D3D9(),