Commit 9a9ef0ae by Courtney Goeltzenleuchter Committed by Commit Bot

Vulkan: Fix RTs attached to textures with non-0 mip

Cleared confusion between GL level indices and VK level indices by adding the corresponding suffix to variables and function arguments. A handful of places that sent one index and expected the other are fixed. A couple more places needed this adjustment that were missed in the first CL. Also included a test to provoke those situations. The conversion between the two is given by: levelIndexGL = levelIndexVk + baseLevel; Bug: angleproject:4695 Change-Id: I3b8e5699abee1b011e52b666e6e245f44cb8ad6f Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2302549Reviewed-by: 's avatarCody Northrop <cnorthrop@google.com> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Courtney Goeltzenleuchter <courtneygo@google.com>
parent bcec11c2
......@@ -28,7 +28,7 @@ RenderTargetVk::~RenderTargetVk() {}
RenderTargetVk::RenderTargetVk(RenderTargetVk &&other)
: mImage(other.mImage),
mImageViews(other.mImageViews),
mLevelIndex(other.mLevelIndex),
mLevelIndexGL(other.mLevelIndexGL),
mLayerIndex(other.mLayerIndex),
mContentDefined(other.mContentDefined)
{
......@@ -37,13 +37,13 @@ RenderTargetVk::RenderTargetVk(RenderTargetVk &&other)
void RenderTargetVk::init(vk::ImageHelper *image,
vk::ImageViewHelper *imageViews,
uint32_t levelIndex,
uint32_t levelIndexGL,
uint32_t layerIndex)
{
mImage = image;
mImageViews = imageViews;
mLevelIndex = levelIndex;
mLayerIndex = layerIndex;
mImage = image;
mImageViews = imageViews;
mLevelIndexGL = levelIndexGL;
mLayerIndex = layerIndex;
// We are being conservative here since our targeted optimization is to skip surfaceVK's depth
// buffer load after swap call.
mContentDefined = true;
......@@ -53,7 +53,7 @@ void RenderTargetVk::reset()
{
mImage = nullptr;
mImageViews = nullptr;
mLevelIndex = 0;
mLevelIndexGL = 0;
mLayerIndex = 0;
mContentDefined = false;
}
......@@ -62,10 +62,10 @@ ImageViewSerial RenderTargetVk::getAssignImageViewSerial(ContextVk *contextVk)
{
ASSERT(mImageViews);
ASSERT(mLayerIndex < std::numeric_limits<uint16_t>::max());
ASSERT(mLevelIndex < std::numeric_limits<uint16_t>::max());
ASSERT(mLevelIndexGL < std::numeric_limits<uint16_t>::max());
ImageViewSerial imageViewSerial =
mImageViews->getAssignSerial(contextVk, mLevelIndex, mLayerIndex);
mImageViews->getAssignSerial(contextVk, mLevelIndexGL, mLayerIndex);
ASSERT(imageViewSerial.getValue() < std::numeric_limits<uint32_t>::max());
return imageViewSerial;
}
......@@ -112,7 +112,8 @@ angle::Result RenderTargetVk::getImageView(ContextVk *contextVk,
const vk::ImageView **imageViewOut) const
{
ASSERT(mImage && mImage->valid() && mImageViews);
return mImageViews->getLevelLayerDrawImageView(contextVk, *mImage, mLevelIndex, mLayerIndex,
int32_t levelVK = mLevelIndexGL - mImage->getBaseLevel();
return mImageViews->getLevelLayerDrawImageView(contextVk, *mImage, levelVK, mLayerIndex,
imageViewOut);
}
......@@ -146,7 +147,8 @@ const vk::Format &RenderTargetVk::getImageFormat() const
gl::Extents RenderTargetVk::getExtents() const
{
ASSERT(mImage && mImage->valid());
return mImage->getLevelExtents2D(static_cast<uint32_t>(mLevelIndex));
uint32_t levelVK = mLevelIndexGL - mImage->getBaseLevel();
return mImage->getLevelExtents2D(levelVK);
}
void RenderTargetVk::updateSwapchainImage(vk::ImageHelper *image, vk::ImageViewHelper *imageViews)
......@@ -175,13 +177,13 @@ angle::Result RenderTargetVk::flushStagedUpdates(ContextVk *contextVk,
}
ASSERT(mImage->valid());
if (!mImage->isUpdateStaged(mLevelIndex, layerIndex))
if (!mImage->isUpdateStaged(mLevelIndexGL, layerIndex))
return angle::Result::Continue;
vk::CommandBuffer *commandBuffer;
ANGLE_TRY(contextVk->endRenderPassAndGetCommandBuffer(&commandBuffer));
return mImage->flushSingleSubresourceStagedUpdates(
contextVk, mLevelIndex, layerIndex, commandBuffer, deferredClears, deferredClearIndex);
contextVk, mLevelIndexGL, layerIndex, commandBuffer, deferredClears, deferredClearIndex);
}
void RenderTargetVk::retainImageViews(ContextVk *contextVk) const
......@@ -194,16 +196,16 @@ gl::ImageIndex RenderTargetVk::getImageIndex() const
// Determine the GL type from the Vk Image properties.
if (mImage->getType() == VK_IMAGE_TYPE_3D)
{
return gl::ImageIndex::Make3D(mLevelIndex, mLayerIndex);
return gl::ImageIndex::Make3D(mLevelIndexGL, mLayerIndex);
}
// We don't need to distinguish 2D array and cube.
if (mImage->getLayerCount() > 1)
{
return gl::ImageIndex::Make2DArray(mLevelIndex, mLayerIndex);
return gl::ImageIndex::Make2DArray(mLevelIndexGL, mLayerIndex);
}
ASSERT(mLayerIndex == 0);
return gl::ImageIndex::Make2D(mLevelIndex);
return gl::ImageIndex::Make2D(mLevelIndexGL);
}
} // namespace rx
......@@ -44,7 +44,7 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget
void init(vk::ImageHelper *image,
vk::ImageViewHelper *imageViews,
uint32_t levelIndex,
uint32_t levelIndexGL,
uint32_t layerIndex);
void reset();
// This returns the serial from underlying ImageViewHelper, first assigning one if required
......@@ -69,7 +69,7 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget
const vk::Format &getImageFormat() const;
gl::Extents getExtents() const;
uint32_t getLevelIndex() const { return mLevelIndex; }
uint32_t getLevelIndex() const { return mLevelIndexGL; }
uint32_t getLayerIndex() const { return mLayerIndex; }
gl::ImageIndex getImageIndex() const;
......@@ -91,7 +91,7 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget
private:
vk::ImageHelper *mImage;
vk::ImageViewHelper *mImageViews;
uint32_t mLevelIndex;
uint32_t mLevelIndexGL;
uint32_t mLayerIndex;
// Right now we are only tracking depth/stencil buffer. We could expand it to cover color
// buffers if needed in future.
......
......@@ -1981,10 +1981,11 @@ angle::Result TextureVk::getLevelLayerImageView(ContextVk *contextVk,
{
ASSERT(mImage && mImage->valid());
uint32_t nativeLevel = getNativeImageLevel(static_cast<uint32_t>(level));
uint32_t levelGL = getNativeImageLevel(static_cast<uint32_t>(level));
uint32_t nativeLayer = getNativeImageLayer(static_cast<uint32_t>(layer));
return mImageViews.getLevelLayerDrawImageView(contextVk, *mImage, nativeLevel, nativeLayer,
uint32_t levelVK = levelGL - mImage->getBaseLevel();
return mImageViews.getLevelLayerDrawImageView(contextVk, *mImage, levelVK, nativeLayer,
imageViewOut);
}
......
......@@ -434,7 +434,7 @@ uint32_t GetImageLayerCountForView(const ImageHelper &image)
return image.getExtents().depth > 1 ? image.getExtents().depth : image.getLayerCount();
}
ImageView *GetLevelImageView(ImageViewVector *imageViews, uint32_t level, uint32_t levelCount)
ImageView *GetLevelImageView(ImageViewVector *imageViews, uint32_t levelVK, uint32_t levelCount)
{
// Lazily allocate the storage for image views. We allocate the full level count because we
// don't want to trigger any std::vector reallocations. Reallocations could invalidate our
......@@ -443,9 +443,9 @@ ImageView *GetLevelImageView(ImageViewVector *imageViews, uint32_t level, uint32
{
imageViews->resize(levelCount);
}
ASSERT(imageViews->size() > level);
ASSERT(imageViews->size() > levelVK);
return &(*imageViews)[level];
return &(*imageViews)[levelVK];
}
// Special rules apply to VkBufferImageCopy with depth/stencil. The components are tightly packed
......@@ -2847,13 +2847,13 @@ angle::Result ImageHelper::initLayerImageView(Context *context,
VkImageAspectFlags aspectMask,
const gl::SwizzleState &swizzleMap,
ImageView *imageViewOut,
uint32_t baseMipLevel,
uint32_t baseMipLevelVK,
uint32_t levelCount,
uint32_t baseArrayLayer,
uint32_t layerCount) const
{
return initLayerImageViewImpl(context, textureType, aspectMask, swizzleMap, imageViewOut,
baseMipLevel, levelCount, baseArrayLayer, layerCount,
baseMipLevelVK, levelCount, baseArrayLayer, layerCount,
mFormat->vkImageFormat, nullptr);
}
......@@ -2863,7 +2863,7 @@ angle::Result ImageHelper::initLayerImageViewImpl(
VkImageAspectFlags aspectMask,
const gl::SwizzleState &swizzleMap,
ImageView *imageViewOut,
uint32_t baseMipLevel,
uint32_t baseMipLevelVK,
uint32_t levelCount,
uint32_t baseArrayLayer,
uint32_t layerCount,
......@@ -2892,7 +2892,7 @@ angle::Result ImageHelper::initLayerImageViewImpl(
viewInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
}
viewInfo.subresourceRange.aspectMask = aspectMask;
viewInfo.subresourceRange.baseMipLevel = baseMipLevel;
viewInfo.subresourceRange.baseMipLevel = baseMipLevelVK;
viewInfo.subresourceRange.levelCount = levelCount;
viewInfo.subresourceRange.baseArrayLayer = baseArrayLayer;
viewInfo.subresourceRange.layerCount = layerCount;
......@@ -3027,20 +3027,20 @@ VkImageLayout ImageHelper::getCurrentLayout() const
return kImageMemoryBarrierData[mCurrentLayout].layout;
}
gl::Extents ImageHelper::getLevelExtents(uint32_t level) const
gl::Extents ImageHelper::getLevelExtents(uint32_t levelVK) const
{
// Level 0 should be the size of the extents, after that every time you increase a level
// you shrink the extents by half.
uint32_t width = std::max(mExtents.width >> level, 1u);
uint32_t height = std::max(mExtents.height >> level, 1u);
uint32_t depth = std::max(mExtents.depth >> level, 1u);
uint32_t width = std::max(mExtents.width >> levelVK, 1u);
uint32_t height = std::max(mExtents.height >> levelVK, 1u);
uint32_t depth = std::max(mExtents.depth >> levelVK, 1u);
return gl::Extents(width, height, depth);
}
gl::Extents ImageHelper::getLevelExtents2D(uint32_t level) const
gl::Extents ImageHelper::getLevelExtents2D(uint32_t levelVK) const
{
gl::Extents extents = getLevelExtents(level);
gl::Extents extents = getLevelExtents(levelVK);
extents.depth = 1;
return extents;
}
......@@ -5194,7 +5194,7 @@ angle::Result ImageViewHelper::initSRGBReadViews(ContextVk *contextVk,
angle::Result ImageViewHelper::getLevelDrawImageView(ContextVk *contextVk,
gl::TextureType viewType,
const ImageHelper &image,
uint32_t level,
uint32_t levelVK,
uint32_t layer,
VkImageUsageFlags imageUsageFlags,
VkFormat vkImageFormat,
......@@ -5202,7 +5202,7 @@ angle::Result ImageViewHelper::getLevelDrawImageView(ContextVk *contextVk,
{
retain(&contextVk->getResourceUseList());
ImageView *imageView = GetLevelImageView(&mLevelDrawImageViews, level, image.getLevelCount());
ImageView *imageView = GetLevelImageView(&mLevelDrawImageViews, levelVK, image.getLevelCount());
*imageViewOut = imageView;
if (imageView->valid())
......@@ -5212,13 +5212,13 @@ angle::Result ImageViewHelper::getLevelDrawImageView(ContextVk *contextVk,
// Create the view. Note that storage images are not affected by swizzle parameters.
return image.initAliasedLayerImageView(contextVk, viewType, image.getAspectFlags(),
gl::SwizzleState(), imageView, level, 1, layer,
gl::SwizzleState(), imageView, levelVK, 1, layer,
image.getLayerCount(), imageUsageFlags, vkImageFormat);
}
angle::Result ImageViewHelper::getLevelLayerDrawImageView(ContextVk *contextVk,
const ImageHelper &image,
uint32_t level,
uint32_t levelVK,
uint32_t layer,
const ImageView **imageViewOut)
{
......@@ -5237,7 +5237,7 @@ angle::Result ImageViewHelper::getLevelLayerDrawImageView(ContextVk *contextVk,
ASSERT(mLayerLevelDrawImageViews.size() > layer);
ImageView *imageView =
GetLevelImageView(&mLayerLevelDrawImageViews[layer], level, image.getLevelCount());
GetLevelImageView(&mLayerLevelDrawImageViews[layer], levelVK, image.getLevelCount());
*imageViewOut = imageView;
if (imageView->valid())
......@@ -5250,14 +5250,14 @@ angle::Result ImageViewHelper::getLevelLayerDrawImageView(ContextVk *contextVk,
// don't have swizzle.
gl::TextureType viewType = Get2DTextureType(1, image.getSamples());
return image.initLayerImageView(contextVk, viewType, image.getAspectFlags(), gl::SwizzleState(),
imageView, level, 1, layer, 1);
imageView, levelVK, 1, layer, 1);
}
ImageViewSerial ImageViewHelper::getAssignSerial(ContextVk *contextVk,
uint32_t level,
uint32_t levelGL,
uint32_t layer)
{
LayerLevel layerLevelPair = {layer, level};
LayerLevel layerLevelPair = {layer, levelGL};
if (mSerialCache.find(layerLevelPair) == mSerialCache.end())
{
mSerialCache[layerLevelPair] = contextVk->generateAttachmentImageViewSerial();
......
......@@ -1645,7 +1645,7 @@ class ImageViewHelper : angle::NonCopyable
angle::Result getLevelDrawImageView(ContextVk *contextVk,
gl::TextureType viewType,
const ImageHelper &image,
uint32_t level,
uint32_t levelVK,
uint32_t layer,
VkImageUsageFlags imageUsageFlags,
VkFormat vkImageFormat,
......@@ -1654,12 +1654,12 @@ class ImageViewHelper : angle::NonCopyable
// Creates a view with a single layer of the level.
angle::Result getLevelLayerDrawImageView(ContextVk *contextVk,
const ImageHelper &image,
uint32_t level,
uint32_t levelVK,
uint32_t layer,
const ImageView **imageViewOut);
// Return unique Serial for this imageView, first assigning it if it hasn't yet been set
ImageViewSerial getAssignSerial(ContextVk *contextVk, uint32_t level, uint32_t layer);
ImageViewSerial getAssignSerial(ContextVk *contextVk, uint32_t levelGL, uint32_t layer);
private:
ImageView &getReadImageView()
......
......@@ -513,6 +513,46 @@ TEST_P(FramebufferTest_ES3, TextureAttachmentMipLevelsReadBack)
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
}
// TextureAttachmentMipLevelsReadBackWithDraw is a copy of TextureAttachmentMipLevelsReadBack except
// for adding a draw after the last clear. The draw forces ANGLE's Vulkan backend to use the
// framebuffer that is level 1 of the texture which will trigger the mismatch use of the GL level
// and Vulkan level in referring to that rendertarget.
TEST_P(FramebufferTest_ES3, TextureAttachmentMipLevelsReadBackWithDraw)
{
#if defined(ADDRESS_SANITIZER)
// http://anglebug.com/4737
ANGLE_SKIP_TEST_IF(IsOSX());
#endif
ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
GLFramebuffer framebuffer;
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
GLTexture texture;
glBindTexture(GL_TEXTURE_2D, texture);
const std::array<GLColor, 2 * 2> mip0Data = {GLColor::red, GLColor::red, GLColor::red,
GLColor::red};
const std::array<GLColor, 1 * 1> mip1Data = {GLColor::green};
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip0Data.data());
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip1Data.data());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 1);
EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
glClearColor(0, 0, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// This draw triggers the use of the framebuffer
glUseProgram(greenProgram);
drawQuad(greenProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
ASSERT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}
// Test that passing an attachment COLOR_ATTACHMENTm where m is equal to MAX_COLOR_ATTACHMENTS
// generates an INVALID_OPERATION.
// OpenGL ES Version 3.0.5 (November 3, 2016), 4.4.2.4 Attaching Texture Images to a Framebuffer, p.
......
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