Commit 3d2de99e by Shahbaz Youssefi 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. The conversion between the two is given by: levelIndexGL = levelIndexVk + baseLevel; Bug: angleproject:4695 Change-Id: I84ecbaf867d00a40fb39b6db7ad79658016f4d9a Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2235362 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent d80d9044
...@@ -1700,10 +1700,10 @@ angle::Result FramebufferVk::readPixelsImpl(ContextVk *contextVk, ...@@ -1700,10 +1700,10 @@ angle::Result FramebufferVk::readPixelsImpl(ContextVk *contextVk,
void *pixels) void *pixels)
{ {
ANGLE_TRACE_EVENT0("gpu.angle", "FramebufferVk::readPixelsImpl"); ANGLE_TRACE_EVENT0("gpu.angle", "FramebufferVk::readPixelsImpl");
uint32_t level = renderTarget->getLevelIndex(); uint32_t levelGL = renderTarget->getLevelIndex();
uint32_t layer = renderTarget->getLayerIndex(); uint32_t layer = renderTarget->getLayerIndex();
return renderTarget->getImage().readPixels(contextVk, area, packPixelsParams, copyAspectFlags, return renderTarget->getImage().readPixels(contextVk, area, packPixelsParams, copyAspectFlags,
level, layer, pixels, &mReadPixelBuffer); levelGL, layer, pixels, &mReadPixelBuffer);
} }
gl::Extents FramebufferVk::getReadImageExtents() const gl::Extents FramebufferVk::getReadImageExtents() const
......
...@@ -1199,8 +1199,8 @@ angle::Result TextureVk::copyAndStageImageSubresource(ContextVk *contextVk, ...@@ -1199,8 +1199,8 @@ angle::Result TextureVk::copyAndStageImageSubresource(ContextVk *contextVk,
const gl::ImageDesc &desc, const gl::ImageDesc &desc,
bool ignoreLayerCount, bool ignoreLayerCount,
uint32_t currentLayer, uint32_t currentLayer,
uint32_t sourceMipLevel, uint32_t srcLevelVk,
uint32_t stagingDstMipLevel) uint32_t dstLevelGL)
{ {
const gl::Extents &baseLevelExtents = desc.size; const gl::Extents &baseLevelExtents = desc.size;
...@@ -1221,9 +1221,9 @@ angle::Result TextureVk::copyAndStageImageSubresource(ContextVk *contextVk, ...@@ -1221,9 +1221,9 @@ angle::Result TextureVk::copyAndStageImageSubresource(ContextVk *contextVk,
vk::BufferHelper *stagingBuffer = nullptr; vk::BufferHelper *stagingBuffer = nullptr;
vk::StagingBufferOffsetArray stagingBufferOffsets = {0, 0}; vk::StagingBufferOffsetArray stagingBufferOffsets = {0, 0};
size_t bufferSize = 0; size_t bufferSize = 0;
ANGLE_TRY(mImage->copyImageDataToBuffer(contextVk, sourceMipLevel, layerCount, currentLayer, ANGLE_TRY(mImage->copyImageDataToBuffer(contextVk, srcLevelVk, layerCount, currentLayer, area,
area, &stagingBuffer, &bufferSize, &stagingBuffer, &bufferSize, &stagingBufferOffsets,
&stagingBufferOffsets, nullptr)); nullptr));
// Stage an update to the new image // Stage an update to the new image
ASSERT(stagingBuffer); ASSERT(stagingBuffer);
...@@ -1238,7 +1238,7 @@ angle::Result TextureVk::copyAndStageImageSubresource(ContextVk *contextVk, ...@@ -1238,7 +1238,7 @@ angle::Result TextureVk::copyAndStageImageSubresource(ContextVk *contextVk,
bufferImageHeight = std::max(bufferImageHeight, desc.format.info->compressedBlockHeight); bufferImageHeight = std::max(bufferImageHeight, desc.format.info->compressedBlockHeight);
} }
ANGLE_TRY(mImage->stageSubresourceUpdateFromBuffer( ANGLE_TRY(mImage->stageSubresourceUpdateFromBuffer(
contextVk, bufferSize, stagingDstMipLevel, currentLayer, layerCount, bufferRowLength, contextVk, bufferSize, dstLevelGL, currentLayer, layerCount, bufferRowLength,
bufferImageHeight, updatedExtents, offset, stagingBuffer, stagingBufferOffsets)); bufferImageHeight, updatedExtents, offset, stagingBuffer, stagingBufferOffsets));
return angle::Result::Continue; return angle::Result::Continue;
...@@ -1305,47 +1305,31 @@ angle::Result TextureVk::respecifyImageAttributesAndLevels(ContextVk *contextVk, ...@@ -1305,47 +1305,31 @@ angle::Result TextureVk::respecifyImageAttributesAndLevels(ContextVk *contextVk,
mImage->getLayerCount(), commandBuffer)); mImage->getLayerCount(), commandBuffer));
} }
bool baseLevelChanged = baseLevel != previousBaseLevel;
// After flushing, track the new levels (they are used in the flush, hence the wait) // After flushing, track the new levels (they are used in the flush, hence the wait)
mImage->setBaseAndMaxLevels(baseLevel, maxLevel); mImage->setBaseAndMaxLevels(baseLevel, maxLevel);
// Next, back up any data we need to preserve by staging it as updates to the new image. // Next, back up any data we need to preserve by staging it as updates to the new image.
// Stage updates for all levels in the GL texture, while preserving the data in the vkImage. // Preserve the data in the Vulkan image. GL texture's staged updates that correspond to levels
// This ensures we propagate all the current image data, even as max level moves around. // outside the range of the Vulkan image will remain intact.
uint32_t updateCount =
std::max<GLuint>(mState.getMipmapMaxLevel() + 1, mImage->getLevelCount());
// The staged updates won't be applied until the image has the requisite mip levels // The staged updates won't be applied until the image has the requisite mip levels
for (uint32_t layer = 0; layer < mImage->getLayerCount(); layer++) for (uint32_t layer = 0; layer < mImage->getLayerCount(); layer++)
{ {
for (uint32_t level = 0; level < updateCount; level++) for (uint32_t levelVK = 0; levelVK < mImage->getLevelCount(); levelVK++)
{ {
if (mImage->isUpdateStaged(level, layer)) // Vulkan level 0 previously aligned with whatever the base level was.
{ uint32_t levelGL = levelVK + previousBaseLevel;
// If there is still an update staged for the surface at the designated
// layer/level, we don't need to propagate any data from this image. ASSERT(!mImage->isUpdateStaged(levelGL, layer));
// This can happen for original texture levels that have never fit into
// the vkImage due to base/max level, and for vkImage data that has been
// staged by previous calls to respecifyImageAttributesAndLevels that didn't fit
// into the new vkImage.
continue;
}
// Pull data from the current image and stage it as an update for the new image // Pull data from the current image and stage it as an update for the new image
// First we populate the staging buffer with current level data // First we populate the staging buffer with current level data
const gl::ImageDesc &desc = const gl::ImageDesc &desc =
mState.getImageDesc(gl::TextureTypeToTarget(mState.getType(), layer), level); mState.getImageDesc(gl::TextureTypeToTarget(mState.getType(), layer), levelGL);
// We need to adjust the source Vulkan level to reflect the previous base level.
// vk level 0 previously aligned with whatever the base level was.
uint32_t srcLevelVK = baseLevelChanged ? level - previousBaseLevel : level;
ASSERT(srcLevelVK <= mImage->getLevelCount());
ANGLE_TRY( ANGLE_TRY(copyAndStageImageSubresource(contextVk, desc, true, layer, levelVK, levelGL));
copyAndStageImageSubresource(contextVk, desc, true, layer, srcLevelVK, level));
} }
} }
......
...@@ -356,8 +356,8 @@ class TextureVk : public TextureImpl, public angle::ObserverInterface ...@@ -356,8 +356,8 @@ class TextureVk : public TextureImpl, public angle::ObserverInterface
const gl::ImageDesc &desc, const gl::ImageDesc &desc,
bool ignoreLayerCount, bool ignoreLayerCount,
uint32_t currentLayer, uint32_t currentLayer,
uint32_t sourceLevel, uint32_t srcLevelVk,
uint32_t stagingDstMipLevel); uint32_t dstLevelGL);
angle::Result initImageViews(ContextVk *contextVk, angle::Result initImageViews(ContextVk *contextVk,
const vk::Format &format, const vk::Format &format,
const bool sized, const bool sized,
......
...@@ -3246,14 +3246,14 @@ void ImageHelper::resolve(ImageHelper *dest, ...@@ -3246,14 +3246,14 @@ void ImageHelper::resolve(ImageHelper *dest,
} }
void ImageHelper::removeStagedUpdates(ContextVk *contextVk, void ImageHelper::removeStagedUpdates(ContextVk *contextVk,
uint32_t levelIndex, uint32_t levelIndexGL,
uint32_t layerIndex) uint32_t layerIndex)
{ {
// Find any staged updates for this index and removes them from the pending list. // Find any staged updates for this index and removes them from the pending list.
for (size_t index = 0; index < mSubresourceUpdates.size();) for (size_t index = 0; index < mSubresourceUpdates.size();)
{ {
auto update = mSubresourceUpdates.begin() + index; auto update = mSubresourceUpdates.begin() + index;
if (update->isUpdateToLayerLevel(layerIndex, levelIndex)) if (update->isUpdateToLayerLevel(layerIndex, levelIndexGL))
{ {
update->release(contextVk->getRenderer()); update->release(contextVk->getRenderer());
mSubresourceUpdates.erase(update); mSubresourceUpdates.erase(update);
...@@ -3556,7 +3556,7 @@ angle::Result ImageHelper::stageSubresourceUpdateAndGetData(ContextVk *contextVk ...@@ -3556,7 +3556,7 @@ angle::Result ImageHelper::stageSubresourceUpdateAndGetData(ContextVk *contextVk
angle::Result ImageHelper::stageSubresourceUpdateFromBuffer(ContextVk *contextVk, angle::Result ImageHelper::stageSubresourceUpdateFromBuffer(ContextVk *contextVk,
size_t allocationSize, size_t allocationSize,
uint32_t mipLevel, uint32_t mipLevelGL,
uint32_t baseArrayLayer, uint32_t baseArrayLayer,
uint32_t layerCount, uint32_t layerCount,
uint32_t bufferRowLength, uint32_t bufferRowLength,
...@@ -3574,7 +3574,7 @@ angle::Result ImageHelper::stageSubresourceUpdateFromBuffer(ContextVk *contextVk ...@@ -3574,7 +3574,7 @@ angle::Result ImageHelper::stageSubresourceUpdateFromBuffer(ContextVk *contextVk
copy[0].bufferRowLength = bufferRowLength; copy[0].bufferRowLength = bufferRowLength;
copy[0].bufferImageHeight = bufferImageHeight; copy[0].bufferImageHeight = bufferImageHeight;
copy[0].imageSubresource.aspectMask = getAspectFlags(); copy[0].imageSubresource.aspectMask = getAspectFlags();
copy[0].imageSubresource.mipLevel = mipLevel; copy[0].imageSubresource.mipLevel = mipLevelGL;
copy[0].imageSubresource.baseArrayLayer = baseArrayLayer; copy[0].imageSubresource.baseArrayLayer = baseArrayLayer;
copy[0].imageSubresource.layerCount = layerCount; copy[0].imageSubresource.layerCount = layerCount;
copy[0].imageOffset = offset; copy[0].imageOffset = offset;
...@@ -3589,7 +3589,7 @@ angle::Result ImageHelper::stageSubresourceUpdateFromBuffer(ContextVk *contextVk ...@@ -3589,7 +3589,7 @@ angle::Result ImageHelper::stageSubresourceUpdateFromBuffer(ContextVk *contextVk
copy[1].bufferRowLength = bufferRowLength; copy[1].bufferRowLength = bufferRowLength;
copy[1].bufferImageHeight = bufferImageHeight; copy[1].bufferImageHeight = bufferImageHeight;
copy[1].imageSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; copy[1].imageSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
copy[1].imageSubresource.mipLevel = mipLevel; copy[1].imageSubresource.mipLevel = mipLevelGL;
copy[1].imageSubresource.baseArrayLayer = baseArrayLayer; copy[1].imageSubresource.baseArrayLayer = baseArrayLayer;
copy[1].imageSubresource.layerCount = layerCount; copy[1].imageSubresource.layerCount = layerCount;
copy[1].imageOffset = offset; copy[1].imageOffset = offset;
...@@ -3847,7 +3847,7 @@ angle::Result ImageHelper::allocateStagingMemory(ContextVk *contextVk, ...@@ -3847,7 +3847,7 @@ angle::Result ImageHelper::allocateStagingMemory(ContextVk *contextVk,
} }
angle::Result ImageHelper::flushSingleSubresourceStagedUpdates(ContextVk *contextVk, angle::Result ImageHelper::flushSingleSubresourceStagedUpdates(ContextVk *contextVk,
uint32_t level, uint32_t levelGL,
uint32_t layer, uint32_t layer,
CommandBuffer *commandBuffer, CommandBuffer *commandBuffer,
ClearValuesArray *deferredClears, ClearValuesArray *deferredClears,
...@@ -3862,7 +3862,7 @@ angle::Result ImageHelper::flushSingleSubresourceStagedUpdates(ContextVk *contex ...@@ -3862,7 +3862,7 @@ angle::Result ImageHelper::flushSingleSubresourceStagedUpdates(ContextVk *contex
{ {
SubresourceUpdate &update = mSubresourceUpdates[updateIndex]; SubresourceUpdate &update = mSubresourceUpdates[updateIndex];
if (update.isUpdateToLayerLevel(layer, level)) if (update.isUpdateToLayerLevel(layer, levelGL))
{ {
// On any data update, exit out. We'll need to do a full upload. // On any data update, exit out. We'll need to do a full upload.
if (update.updateSource != UpdateSource::Clear || if (update.updateSource != UpdateSource::Clear ||
...@@ -3888,19 +3888,20 @@ angle::Result ImageHelper::flushSingleSubresourceStagedUpdates(ContextVk *contex ...@@ -3888,19 +3888,20 @@ angle::Result ImageHelper::flushSingleSubresourceStagedUpdates(ContextVk *contex
deferredClears->store(deferredClearIndex, update.aspectFlags, update.value); deferredClears->store(deferredClearIndex, update.aspectFlags, update.value);
// We process the updates again to erase any clears for this level. // We process the updates again to erase any clears for this level.
removeStagedUpdates(contextVk, level, layer); removeStagedUpdates(contextVk, levelGL, layer);
return angle::Result::Continue; return angle::Result::Continue;
} }
// Otherwise we proceed with a normal update. // Otherwise we proceed with a normal update.
} }
return flushStagedUpdates(contextVk, level, level + 1, layer, layer + 1, commandBuffer); uint32_t levelVK = levelGL - mBaseLevel;
return flushStagedUpdates(contextVk, levelVK, levelVK + 1, layer, layer + 1, commandBuffer);
} }
angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk, angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk,
uint32_t levelStart, uint32_t levelVKStart,
uint32_t levelEnd, uint32_t levelVKEnd,
uint32_t layerStart, uint32_t layerStart,
uint32_t layerEnd, uint32_t layerEnd,
CommandBuffer *commandBuffer) CommandBuffer *commandBuffer)
...@@ -3910,6 +3911,9 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk, ...@@ -3910,6 +3911,9 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk,
return angle::Result::Continue; return angle::Result::Continue;
} }
const uint32_t levelGLStart = levelVKStart + mBaseLevel;
const uint32_t levelGLEnd = levelVKEnd + mBaseLevel;
ANGLE_TRY(mStagingBuffer.flush(contextVk)); ANGLE_TRY(mStagingBuffer.flush(contextVk));
std::vector<SubresourceUpdate> updatesToKeep; std::vector<SubresourceUpdate> updatesToKeep;
...@@ -3933,12 +3937,12 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk, ...@@ -3933,12 +3937,12 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk,
(update.updateSource == UpdateSource::Image && update.image.image != nullptr && (update.updateSource == UpdateSource::Image && update.image.image != nullptr &&
update.image.image->valid())); update.image.image->valid()));
uint32_t updateMipLevel; uint32_t updateMipLevelGL;
uint32_t updateBaseLayer; uint32_t updateBaseLayer;
uint32_t updateLayerCount; uint32_t updateLayerCount;
if (update.updateSource == UpdateSource::Clear) if (update.updateSource == UpdateSource::Clear)
{ {
updateMipLevel = update.clear.levelIndex; updateMipLevelGL = update.clear.levelIndex;
updateBaseLayer = update.clear.layerIndex; updateBaseLayer = update.clear.layerIndex;
updateLayerCount = update.clear.layerCount; updateLayerCount = update.clear.layerCount;
if (updateLayerCount == static_cast<uint32_t>(gl::ImageIndex::kEntireLevel)) if (updateLayerCount == static_cast<uint32_t>(gl::ImageIndex::kEntireLevel))
...@@ -3949,16 +3953,16 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk, ...@@ -3949,16 +3953,16 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk,
else else
{ {
const VkImageSubresourceLayers &dstSubresource = update.dstSubresource(); const VkImageSubresourceLayers &dstSubresource = update.dstSubresource();
updateMipLevel = dstSubresource.mipLevel; updateMipLevelGL = dstSubresource.mipLevel;
updateBaseLayer = dstSubresource.baseArrayLayer; updateBaseLayer = dstSubresource.baseArrayLayer;
updateLayerCount = dstSubresource.layerCount; updateLayerCount = dstSubresource.layerCount;
ASSERT(updateLayerCount != static_cast<uint32_t>(gl::ImageIndex::kEntireLevel)); ASSERT(updateLayerCount != static_cast<uint32_t>(gl::ImageIndex::kEntireLevel));
} }
// If the update level is not within the requested range, skip the update. // If the update level is not within the requested range, skip the update.
const bool isUpdateLevelOutsideRange = const bool isUpdateLevelOutsideRange = updateMipLevelGL < levelGLStart ||
updateMipLevel < (levelStart + mBaseLevel) || updateMipLevelGL >= levelGLEnd ||
(updateMipLevel >= (levelEnd + mBaseLevel) || updateMipLevel > mMaxLevel); updateMipLevelGL > mMaxLevel;
// If the update layers don't intersect the requested layers, skip the update. // If the update layers don't intersect the requested layers, skip the update.
const bool areUpdateLayersOutsideRange = const bool areUpdateLayersOutsideRange =
...@@ -3970,10 +3974,10 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk, ...@@ -3970,10 +3974,10 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk,
continue; continue;
} }
uint32_t updateMipLevelVK = updateMipLevelGL - mBaseLevel;
if (mBaseLevel > 0) if (mBaseLevel > 0)
{ {
// We need to shift the miplevel in the update to fall into the vkiamge // We need to shift the miplevel in the update to fall into the vkiamge
updateMipLevel -= mBaseLevel;
if (update.updateSource == UpdateSource::Clear) if (update.updateSource == UpdateSource::Clear)
{ {
update.clear.levelIndex -= mBaseLevel; update.clear.levelIndex -= mBaseLevel;
...@@ -3998,7 +4002,7 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk, ...@@ -3998,7 +4002,7 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk,
{ {
const uint64_t subresourceHashRange = angle::Bit<uint64_t>(updateLayerCount) - 1; const uint64_t subresourceHashRange = angle::Bit<uint64_t>(updateLayerCount) - 1;
const uint32_t subresourceHashOffset = const uint32_t subresourceHashOffset =
(updateMipLevel * mLayerCount + updateBaseLayer) % kMaxParallelSubresourceUpload; (updateMipLevelVK * mLayerCount + updateBaseLayer) % kMaxParallelSubresourceUpload;
const uint64_t subresourceHash = const uint64_t subresourceHash =
ANGLE_ROTL64(subresourceHashRange, subresourceHashOffset); ANGLE_ROTL64(subresourceHashRange, subresourceHashOffset);
...@@ -4013,8 +4017,8 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk, ...@@ -4013,8 +4017,8 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk,
if (update.updateSource == UpdateSource::Clear) if (update.updateSource == UpdateSource::Clear)
{ {
ASSERT(updateMipLevel == update.clear.levelIndex); ASSERT(updateMipLevelVK == update.clear.levelIndex);
clear(update.clear.aspectFlags, update.clear.value, updateMipLevel, updateBaseLayer, clear(update.clear.aspectFlags, update.clear.value, updateMipLevelVK, updateBaseLayer,
updateLayerCount, commandBuffer); updateLayerCount, commandBuffer);
} }
else if (update.updateSource == UpdateSource::Buffer) else if (update.updateSource == UpdateSource::Buffer)
...@@ -4061,7 +4065,7 @@ angle::Result ImageHelper::flushAllStagedUpdates(ContextVk *contextVk) ...@@ -4061,7 +4065,7 @@ angle::Result ImageHelper::flushAllStagedUpdates(ContextVk *contextVk)
return flushStagedUpdates(contextVk, 0, mLevelCount, 0, mLayerCount, commandBuffer); return flushStagedUpdates(contextVk, 0, mLevelCount, 0, mLayerCount, commandBuffer);
} }
bool ImageHelper::isUpdateStaged(uint32_t level, uint32_t layer) bool ImageHelper::isUpdateStaged(uint32_t levelGL, uint32_t layer)
{ {
// Check to see if any updates are staged for the given level and layer // Check to see if any updates are staged for the given level and layer
...@@ -4072,25 +4076,25 @@ bool ImageHelper::isUpdateStaged(uint32_t level, uint32_t layer) ...@@ -4072,25 +4076,25 @@ bool ImageHelper::isUpdateStaged(uint32_t level, uint32_t layer)
for (SubresourceUpdate &update : mSubresourceUpdates) for (SubresourceUpdate &update : mSubresourceUpdates)
{ {
uint32_t updateMipLevel; uint32_t updateMipLevelGL;
uint32_t updateBaseLayer; uint32_t updateBaseLayer;
uint32_t updateLayerCount; uint32_t updateLayerCount;
if (update.updateSource == UpdateSource::Clear) if (update.updateSource == UpdateSource::Clear)
{ {
updateMipLevel = update.clear.levelIndex; updateMipLevelGL = update.clear.levelIndex;
updateBaseLayer = update.clear.layerIndex; updateBaseLayer = update.clear.layerIndex;
updateLayerCount = update.clear.layerCount; updateLayerCount = update.clear.layerCount;
} }
else else
{ {
const VkImageSubresourceLayers &dstSubresource = update.dstSubresource(); const VkImageSubresourceLayers &dstSubresource = update.dstSubresource();
updateMipLevel = dstSubresource.mipLevel; updateMipLevelGL = dstSubresource.mipLevel;
updateBaseLayer = dstSubresource.baseArrayLayer; updateBaseLayer = dstSubresource.baseArrayLayer;
updateLayerCount = dstSubresource.layerCount; updateLayerCount = dstSubresource.layerCount;
} }
if (updateMipLevel == level) if (updateMipLevelGL == levelGL)
{ {
if (layer >= updateBaseLayer && layer < (updateBaseLayer + updateLayerCount)) if (layer >= updateBaseLayer && layer < (updateBaseLayer + updateLayerCount))
{ {
...@@ -4234,7 +4238,7 @@ angle::Result ImageHelper::GetReadPixelsParams(ContextVk *contextVk, ...@@ -4234,7 +4238,7 @@ angle::Result ImageHelper::GetReadPixelsParams(ContextVk *contextVk,
angle::Result ImageHelper::readPixelsForGetImage(ContextVk *contextVk, angle::Result ImageHelper::readPixelsForGetImage(ContextVk *contextVk,
const gl::PixelPackState &packState, const gl::PixelPackState &packState,
gl::Buffer *packBuffer, gl::Buffer *packBuffer,
uint32_t level, uint32_t levelGL,
uint32_t layer, uint32_t layer,
GLenum format, GLenum format,
GLenum type, GLenum type,
...@@ -4271,9 +4275,10 @@ angle::Result ImageHelper::readPixelsForGetImage(ContextVk *contextVk, ...@@ -4271,9 +4275,10 @@ angle::Result ImageHelper::readPixelsForGetImage(ContextVk *contextVk,
PackPixelsParams params; PackPixelsParams params;
GLuint outputSkipBytes = 0; GLuint outputSkipBytes = 0;
uint32_t width = std::max(1u, mExtents.width >> level); const uint32_t levelVK = levelGL - mBaseLevel;
uint32_t height = std::max(1u, mExtents.height >> level); const uint32_t width = std::max(1u, mExtents.width >> levelVK);
uint32_t depth = std::max(1u, mExtents.depth >> level); const uint32_t height = std::max(1u, mExtents.height >> levelVK);
const uint32_t depth = std::max(1u, mExtents.depth >> levelVK);
gl::Rectangle area(0, 0, width, height); gl::Rectangle area(0, 0, width, height);
ANGLE_TRY(GetReadPixelsParams(contextVk, packState, packBuffer, format, type, area, area, ANGLE_TRY(GetReadPixelsParams(contextVk, packState, packBuffer, format, type, area, area,
...@@ -4289,7 +4294,7 @@ angle::Result ImageHelper::readPixelsForGetImage(ContextVk *contextVk, ...@@ -4289,7 +4294,7 @@ angle::Result ImageHelper::readPixelsForGetImage(ContextVk *contextVk,
// Depth > 1 means this is a 3D texture and we need to copy all layers // Depth > 1 means this is a 3D texture and we need to copy all layers
for (layer = 0; layer < depth; layer++) for (layer = 0; layer < depth; layer++)
{ {
ANGLE_TRY(readPixels(contextVk, area, params, aspectFlags, level, layer, ANGLE_TRY(readPixels(contextVk, area, params, aspectFlags, levelGL, layer,
static_cast<uint8_t *>(pixels) + outputSkipBytes, static_cast<uint8_t *>(pixels) + outputSkipBytes,
&stagingBuffer.get())); &stagingBuffer.get()));
...@@ -4298,7 +4303,7 @@ angle::Result ImageHelper::readPixelsForGetImage(ContextVk *contextVk, ...@@ -4298,7 +4303,7 @@ angle::Result ImageHelper::readPixelsForGetImage(ContextVk *contextVk,
} }
else else
{ {
ANGLE_TRY(readPixels(contextVk, area, params, aspectFlags, level, layer, ANGLE_TRY(readPixels(contextVk, area, params, aspectFlags, levelGL, layer,
static_cast<uint8_t *>(pixels) + outputSkipBytes, static_cast<uint8_t *>(pixels) + outputSkipBytes,
&stagingBuffer.get())); &stagingBuffer.get()));
} }
...@@ -4310,7 +4315,7 @@ angle::Result ImageHelper::readPixels(ContextVk *contextVk, ...@@ -4310,7 +4315,7 @@ angle::Result ImageHelper::readPixels(ContextVk *contextVk,
const gl::Rectangle &area, const gl::Rectangle &area,
const PackPixelsParams &packPixelsParams, const PackPixelsParams &packPixelsParams,
VkImageAspectFlagBits copyAspectFlags, VkImageAspectFlagBits copyAspectFlags,
uint32_t level, uint32_t levelGL,
uint32_t layer, uint32_t layer,
void *pixels, void *pixels,
DynamicBuffer *stagingBuffer) DynamicBuffer *stagingBuffer)
...@@ -4326,7 +4331,7 @@ angle::Result ImageHelper::readPixels(ContextVk *contextVk, ...@@ -4326,7 +4331,7 @@ angle::Result ImageHelper::readPixels(ContextVk *contextVk,
ImageHelper *src = this; ImageHelper *src = this;
ASSERT(!isUpdateStaged(level, layer)); ASSERT(!isUpdateStaged(levelGL, layer));
if (isMultisampled) if (isMultisampled)
{ {
...@@ -4359,7 +4364,7 @@ angle::Result ImageHelper::readPixels(ContextVk *contextVk, ...@@ -4359,7 +4364,7 @@ angle::Result ImageHelper::readPixels(ContextVk *contextVk,
VkImageSubresourceLayers srcSubresource = {}; VkImageSubresourceLayers srcSubresource = {};
srcSubresource.aspectMask = copyAspectFlags; srcSubresource.aspectMask = copyAspectFlags;
srcSubresource.mipLevel = level; srcSubresource.mipLevel = levelGL - mBaseLevel;
srcSubresource.baseArrayLayer = layer; srcSubresource.baseArrayLayer = layer;
srcSubresource.layerCount = 1; srcSubresource.layerCount = 1;
...@@ -4398,8 +4403,6 @@ angle::Result ImageHelper::readPixels(ContextVk *contextVk, ...@@ -4398,8 +4403,6 @@ angle::Result ImageHelper::readPixels(ContextVk *contextVk,
// Make the resolved image the target of buffer copy. // Make the resolved image the target of buffer copy.
src = &resolvedImage.get(); src = &resolvedImage.get();
level = 0;
layer = 0;
srcOffset = {0, 0, 0}; srcOffset = {0, 0, 0};
srcSubresource.baseArrayLayer = 0; srcSubresource.baseArrayLayer = 0;
srcSubresource.layerCount = 1; srcSubresource.layerCount = 1;
...@@ -4508,15 +4511,15 @@ void ImageHelper::SubresourceUpdate::release(RendererVk *renderer) ...@@ -4508,15 +4511,15 @@ void ImageHelper::SubresourceUpdate::release(RendererVk *renderer)
} }
bool ImageHelper::SubresourceUpdate::isUpdateToLayerLevel(uint32_t layerIndex, bool ImageHelper::SubresourceUpdate::isUpdateToLayerLevel(uint32_t layerIndex,
uint32_t levelIndex) const uint32_t levelIndexGL) const
{ {
if (updateSource == UpdateSource::Clear) if (updateSource == UpdateSource::Clear)
{ {
return clear.levelIndex == levelIndex && clear.layerIndex == layerIndex; return clear.levelIndex == levelIndexGL && clear.layerIndex == layerIndex;
} }
const VkImageSubresourceLayers &dst = dstSubresource(); const VkImageSubresourceLayers &dst = dstSubresource();
return dst.baseArrayLayer == layerIndex && dst.mipLevel == levelIndex; return dst.baseArrayLayer == layerIndex && dst.mipLevel == levelIndexGL;
} }
void ImageHelper::appendSubresourceUpdate(SubresourceUpdate &&update) void ImageHelper::appendSubresourceUpdate(SubresourceUpdate &&update)
......
...@@ -1164,7 +1164,7 @@ class ImageHelper final : public Resource, public angle::Subject ...@@ -1164,7 +1164,7 @@ class ImageHelper final : public Resource, public angle::Subject
void resolve(ImageHelper *dest, const VkImageResolve &region, CommandBuffer *commandBuffer); void resolve(ImageHelper *dest, const VkImageResolve &region, CommandBuffer *commandBuffer);
// Data staging // Data staging
void removeStagedUpdates(ContextVk *contextVk, uint32_t levelIndex, uint32_t layerIndex); void removeStagedUpdates(ContextVk *contextVk, uint32_t levelIndexGL, uint32_t layerIndex);
angle::Result stageSubresourceUpdateImpl(ContextVk *contextVk, angle::Result stageSubresourceUpdateImpl(ContextVk *contextVk,
const gl::ImageIndex &index, const gl::ImageIndex &index,
...@@ -1198,7 +1198,7 @@ class ImageHelper final : public Resource, public angle::Subject ...@@ -1198,7 +1198,7 @@ class ImageHelper final : public Resource, public angle::Subject
angle::Result stageSubresourceUpdateFromBuffer(ContextVk *contextVk, angle::Result stageSubresourceUpdateFromBuffer(ContextVk *contextVk,
size_t allocationSize, size_t allocationSize,
uint32_t mipLevel, uint32_t mipLevelGL,
uint32_t baseArrayLayer, uint32_t baseArrayLayer,
uint32_t layerCount, uint32_t layerCount,
uint32_t bufferRowLength, uint32_t bufferRowLength,
...@@ -1246,7 +1246,7 @@ class ImageHelper final : public Resource, public angle::Subject ...@@ -1246,7 +1246,7 @@ class ImageHelper final : public Resource, public angle::Subject
// Flush staged updates for a single subresource. Can optionally take a parameter to defer // Flush staged updates for a single subresource. Can optionally take a parameter to defer
// clears to a subsequent RenderPass load op. // clears to a subsequent RenderPass load op.
angle::Result flushSingleSubresourceStagedUpdates(ContextVk *contextVk, angle::Result flushSingleSubresourceStagedUpdates(ContextVk *contextVk,
uint32_t level, uint32_t levelGL,
uint32_t layer, uint32_t layer,
CommandBuffer *commandBuffer, CommandBuffer *commandBuffer,
ClearValuesArray *deferredClears, ClearValuesArray *deferredClears,
...@@ -1267,7 +1267,7 @@ class ImageHelper final : public Resource, public angle::Subject ...@@ -1267,7 +1267,7 @@ class ImageHelper final : public Resource, public angle::Subject
// as with renderbuffers or surface images. // as with renderbuffers or surface images.
angle::Result flushAllStagedUpdates(ContextVk *contextVk); angle::Result flushAllStagedUpdates(ContextVk *contextVk);
bool isUpdateStaged(uint32_t level, uint32_t layer); bool isUpdateStaged(uint32_t levelGL, uint32_t layer);
bool hasStagedUpdates() const { return !mSubresourceUpdates.empty(); } bool hasStagedUpdates() const { return !mSubresourceUpdates.empty(); }
// changeLayout automatically skips the layout change if it's unnecessary. This function can be // changeLayout automatically skips the layout change if it's unnecessary. This function can be
...@@ -1346,7 +1346,7 @@ class ImageHelper final : public Resource, public angle::Subject ...@@ -1346,7 +1346,7 @@ class ImageHelper final : public Resource, public angle::Subject
angle::Result readPixelsForGetImage(ContextVk *contextVk, angle::Result readPixelsForGetImage(ContextVk *contextVk,
const gl::PixelPackState &packState, const gl::PixelPackState &packState,
gl::Buffer *packBuffer, gl::Buffer *packBuffer,
uint32_t level, uint32_t levelGL,
uint32_t layer, uint32_t layer,
GLenum format, GLenum format,
GLenum type, GLenum type,
...@@ -1356,7 +1356,7 @@ class ImageHelper final : public Resource, public angle::Subject ...@@ -1356,7 +1356,7 @@ class ImageHelper final : public Resource, public angle::Subject
const gl::Rectangle &area, const gl::Rectangle &area,
const PackPixelsParams &packPixelsParams, const PackPixelsParams &packPixelsParams,
VkImageAspectFlagBits copyAspectFlags, VkImageAspectFlagBits copyAspectFlags,
uint32_t level, uint32_t levelGL,
uint32_t layer, uint32_t layer,
void *pixels, void *pixels,
DynamicBuffer *stagingBuffer); DynamicBuffer *stagingBuffer);
...@@ -1411,11 +1411,12 @@ class ImageHelper final : public Resource, public angle::Subject ...@@ -1411,11 +1411,12 @@ class ImageHelper final : public Resource, public angle::Subject
const VkImageSubresourceLayers &dstSubresource() const const VkImageSubresourceLayers &dstSubresource() const
{ {
// Note: destination mip level includes base level.
ASSERT(updateSource == UpdateSource::Buffer || updateSource == UpdateSource::Image); ASSERT(updateSource == UpdateSource::Buffer || updateSource == UpdateSource::Image);
return updateSource == UpdateSource::Buffer ? buffer.copyRegion.imageSubresource return updateSource == UpdateSource::Buffer ? buffer.copyRegion.imageSubresource
: image.copyRegion.dstSubresource; : image.copyRegion.dstSubresource;
} }
bool isUpdateToLayerLevel(uint32_t layerIndex, uint32_t levelIndex) const; bool isUpdateToLayerLevel(uint32_t layerIndex, uint32_t levelIndexGL) const;
UpdateSource updateSource; UpdateSource updateSource;
union union
......
...@@ -464,9 +464,6 @@ TEST_P(FramebufferTest_ES3, TextureAttachmentMipLevels) ...@@ -464,9 +464,6 @@ TEST_P(FramebufferTest_ES3, TextureAttachmentMipLevels)
TEST_P(FramebufferTest_ES3, TextureAttachmentMipLevelsReadBack) TEST_P(FramebufferTest_ES3, TextureAttachmentMipLevelsReadBack)
{ {
// http://anglebug.com/4695
ANGLE_SKIP_TEST_IF(IsVulkan());
GLFramebuffer framebuffer; GLFramebuffer framebuffer;
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
......
...@@ -2412,11 +2412,6 @@ TEST_P(Texture2DTestES3, FramebufferTextureChangingBaselevel) ...@@ -2412,11 +2412,6 @@ TEST_P(Texture2DTestES3, FramebufferTextureChangingBaselevel)
// preserves the other mips' data. // preserves the other mips' data.
TEST_P(Texture2DBaseMaxTestES3, ExtendMipChainAfterRedefine) TEST_P(Texture2DBaseMaxTestES3, ExtendMipChainAfterRedefine)
{ {
// Affected by two bugs:
// - http://anglebug.com/4695
// - http://anglebug.com/4696
ANGLE_SKIP_TEST_IF(IsVulkan());
// http://anglebug.com/4699 // http://anglebug.com/4699
ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsOSX()); ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsOSX());
...@@ -2442,6 +2437,9 @@ TEST_P(Texture2DBaseMaxTestES3, ExtendMipChainAfterRedefine) ...@@ -2442,6 +2437,9 @@ TEST_P(Texture2DBaseMaxTestES3, ExtendMipChainAfterRedefine)
// Mip 1 is green. Verify this. // Mip 1 is green. Verify this.
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
// http://anglebug.com/4696
ANGLE_SKIP_TEST_IF(IsVulkan());
// Add mip 0 and rebase the mip chain. // Add mip 0 and rebase the mip chain.
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kMip0Size, kMip0Size, 0, GL_RGBA, GL_UNSIGNED_BYTE, glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kMip0Size, kMip0Size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
mipData.data() + getMipDataOffset(kMip0Size, 0)); mipData.data() + getMipDataOffset(kMip0Size, 0));
......
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