Vulkan: Fix importing layered AHBs

Bug: angleproject:6475
Change-Id: Iceb0880cadc54552d3f01593d2e12088cafa10cc
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3198733
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
This commit is contained in:
Shahbaz Youssefi 2021-09-30 23:44:54 -04:00 коммит произвёл Angle LUCI CQ
Родитель 8fbce1e02e
Коммит f3334d0361
5 изменённых файлов: 54 добавлений и 30 удалений

Просмотреть файл

@ -1313,7 +1313,7 @@ angle::Result TextureVk::setStorageExternalMemory(const gl::Context *context,
gl::Format glFormat(internalFormat);
ANGLE_TRY(initImageViews(contextVk, format.getActualImageFormat(getRequiredImageAccess()),
glFormat.info->sized, static_cast<uint32_t>(levels),
mImage->getLayerCount()));
getImageViewLayerCount()));
return angle::Result::Continue;
}
@ -1367,7 +1367,7 @@ angle::Result TextureVk::setEGLImageTarget(const gl::Context *context,
ASSERT(type != gl::TextureType::CubeMap);
ANGLE_TRY(initImageViews(contextVk, format.getActualImageFormat(getRequiredImageAccess()),
image->getFormat().info->sized, 1, 1));
image->getFormat().info->sized, 1, getImageViewLayerCount()));
// Transfer the image to this queue if needed
uint32_t rendererQueueFamilyIndex = renderer->getQueueFamilyIndex();
@ -1983,13 +1983,9 @@ angle::Result TextureVk::updateBaseMaxLevels(ContextVk *contextVk,
// Update the current max level in ImageViewHelper
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->getActualFormat(),
baseLevelDesc.format.info->sized, maxLevel - baseLevel + 1,
layerCount);
getImageViewLayerCount());
}
return respecifyImageStorage(contextVk);
@ -3239,17 +3235,22 @@ vk::ImageOrBufferViewSubresourceSerial TextureVk::getBufferViewSerial() const
return mBufferViews.getSerial();
}
angle::Result TextureVk::refreshImageViews(ContextVk *contextVk)
uint32_t TextureVk::getImageViewLayerCount() const
{
// 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 mState.getType() == gl::TextureType::_2D || mState.getType() == gl::TextureType::External
? 1
: mImage->getLayerCount();
}
angle::Result TextureVk::refreshImageViews(ContextVk *contextVk)
{
getImageViews().release(contextVk->getRenderer());
const gl::ImageDesc &baseLevelDesc = mState.getBaseLevelDesc();
ANGLE_TRY(initImageViews(contextVk, mImage->getActualFormat(), baseLevelDesc.format.info->sized,
mImage->getLevelCount(), layerCount));
mImage->getLevelCount(), getImageViewLayerCount()));
// Let any Framebuffers know we need to refresh the RenderTarget cache.
onStateChange(angle::SubjectMessage::SubjectChanged);

Просмотреть файл

@ -295,6 +295,9 @@ class TextureVk : public TextureImpl, public angle::ObserverInterface
gl::LevelIndex getNativeImageLevel(gl::LevelIndex frontendLevel) const;
uint32_t getNativeImageLayer(uint32_t frontendLayer) const;
// Get the layer count for views.
uint32_t getImageViewLayerCount() const;
void releaseAndDeleteImageAndViews(ContextVk *contextVk);
angle::Result ensureImageAllocated(ContextVk *contextVk, const vk::Format &format);
void setImageHelper(ContextVk *contextVk,

Просмотреть файл

@ -267,6 +267,9 @@ angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk
VkExtent3D vkExtents;
gl_vk::GetExtent(mSize, &vkExtents);
const uint32_t layerCount = mSize.depth;
vkExtents.depth = 1;
mImage = new vk::ImageHelper();
// disable robust init for this external image.
@ -280,11 +283,13 @@ angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk
}
const vk::Format &format =
bufferFormatProperties.format == VK_FORMAT_UNDEFINED ? externalVkFormat : vkFormat;
ANGLE_TRY(mImage->initExternal(
displayVk, gl::TextureType::_2D, vkExtents, format.getIntendedFormatID(),
format.getActualRenderableImageFormatID(), 1, usage, imageCreateFlags,
vk::ImageLayout::ExternalPreInitialized, &externalMemoryImageCreateInfo, gl::LevelIndex(0),
1, 1, robustInitEnabled, nullptr, hasProtectedContent()));
const gl::TextureType textureType =
layerCount > 1 ? gl::TextureType::_2DArray : gl::TextureType::_2D;
ANGLE_TRY(mImage->initExternal(displayVk, textureType, vkExtents, format.getIntendedFormatID(),
format.getActualRenderableImageFormatID(), 1, usage,
imageCreateFlags, vk::ImageLayout::ExternalPreInitialized,
&externalMemoryImageCreateInfo, gl::LevelIndex(0), 1, layerCount,
robustInitEnabled, nullptr, hasProtectedContent()));
VkImportAndroidHardwareBufferInfoANDROID importHardwareBufferInfo = {};
importHardwareBufferInfo.sType = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID;

Просмотреть файл

@ -214,12 +214,10 @@
// Reading back the contents of an RGBX image initialized with non-255 alpha returns the original alpha (instead of 255)
6472 ANDROID GLES : ImageTestES3.RGBXAHBImportThenUpload/* = SKIP
6474 ANDROID GLES : ImageTestES3.RGBXAHBImportMultipleLayers/* = SKIP
6472 ANDROID GLES : ImageTestES3.RGBXAHBImportMultipleLayers/* = SKIP
// Unimplemented fallback path for when format is not renderable or AHB hasn't specified the GPU_FRAMEBUFFER usage.
6151 ANDROID VULKAN : ImageTestES3.RGBXAHBImportNoFramebufferUsage/* = SKIP
// Views of layered AHB are not layered.
6475 ANDROID VULKAN : ImageTestES3.RGBXAHBImportMultipleLayers/* = SKIP
// Nexus 5X expectations.
6149 NEXUS5X GLES : GLSLTest_ES31.StructAndArrayEqualOperator/* = SKIP

Просмотреть файл

@ -462,6 +462,16 @@ class ImageTest : public ANGLETest
ASSERT_GL_NO_ERROR();
}
size_t getLayerPitch(size_t height, size_t rowStride)
{
// Undocumented alignment of layer stride. This is potentially platform dependent, but
// allows functionality to be tested.
constexpr size_t kLayerAlignment = 4096;
const size_t layerSize = height * rowStride;
return (layerSize + kLayerAlignment - 1) & ~(kLayerAlignment - 1);
}
struct AHBPlaneData
{
const GLubyte *data;
@ -490,6 +500,8 @@ class ImageTest : public ANGLETest
size_t planeHeight = (isYUV && planeIdx > 0) ? (height / 2) : height;
size_t planeWidth = (isYUV && planeIdx > 0) ? (width / 2) : width;
size_t layerPitch = getLayerPitch(planeHeight, plane.rowStride);
for (size_t z = 0; z < depth; z++)
{
const uint8_t *srcDepthSlice =
@ -504,9 +516,8 @@ class ImageTest : public ANGLETest
for (size_t x = 0; x < planeWidth; x++)
{
const uint8_t *src = srcRow + x * planeData.bytesPerPixel;
uint8_t *dst = reinterpret_cast<uint8_t *>(plane.data) +
(z * planeHeight + y) * plane.rowStride +
x * plane.pixelStride;
uint8_t *dst = reinterpret_cast<uint8_t *>(plane.data) + z * layerPitch +
y * plane.rowStride + x * plane.pixelStride;
memcpy(dst, src, planeData.bytesPerPixel);
}
}
@ -525,16 +536,20 @@ class ImageTest : public ANGLETest
// Need to grab the stride the implementation might have enforced
AHardwareBuffer_Desc aHardwareBufferDescription = {};
AHardwareBuffer_describe(aHardwareBuffer, &aHardwareBufferDescription);
const uint32_t stride = aHardwareBufferDescription.stride;
const size_t stride = aHardwareBufferDescription.stride * data[0].bytesPerPixel;
size_t layerPitch = getLayerPitch(height, stride);
uint32_t rowSize = stride * height;
for (uint32_t i = 0; i < depth * height; i++)
for (size_t z = 0; z < depth; z++)
{
uint32_t dstPtrOffset = stride * i * (uint32_t)data[0].bytesPerPixel;
uint32_t srcPtrOffset = width * i * (uint32_t)data[0].bytesPerPixel;
for (uint32_t y = 0; y < height; y++)
{
size_t dstPtrOffset = z * layerPitch + y * stride;
size_t srcPtrOffset = (z * height + y) * width * data[0].bytesPerPixel;
uint8_t *dst = reinterpret_cast<uint8_t *>(mappedMemory) + dstPtrOffset;
memcpy(dst, data[0].data + srcPtrOffset, rowSize);
uint8_t *dst = reinterpret_cast<uint8_t *>(mappedMemory) + dstPtrOffset;
memcpy(dst, data[0].data + srcPtrOffset, rowSize);
}
}
res = AHardwareBuffer_unlock(aHardwareBuffer, nullptr);
@ -794,6 +809,7 @@ class ImageTest : public ANGLETest
const size_t planeHeight = (isYUV && planeIdx > 0) ? (height / 2) : height;
const size_t planeWidth = (isYUV && planeIdx > 0) ? (width / 2) : width;
size_t layerPitch = getLayerPitch(planeHeight, plane.rowStride);
uint32_t xStart = 0;
uint32_t xEnd = planeWidth;
@ -827,7 +843,7 @@ class ImageTest : public ANGLETest
referenceData + planeData.bytesPerPixel);
const uint8_t *ahbData = reinterpret_cast<uint8_t *>(plane.data) +
(z * planeHeight + y) * plane.rowStride +
z * layerPitch + y * plane.rowStride +
x * plane.pixelStride;
std::vector<uint8_t> ahb(ahbData, ahbData + planeData.bytesPerPixel);
@ -842,7 +858,8 @@ class ImageTest : public ANGLETest
ASSERT_EQ(1u, data.size());
ASSERT_FALSE(isYUV);
const uint32_t rowStride = aHardwareBufferDescription.stride;
const uint32_t rowStride = aHardwareBufferDescription.stride * data[0].bytesPerPixel;
size_t layerPitch = getLayerPitch(height, rowStride);
void *mappedMemory = nullptr;
ASSERT_EQ(0, AHardwareBuffer_lock(source, AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY, -1,
@ -879,7 +896,7 @@ class ImageTest : public ANGLETest
referenceData + data[0].bytesPerPixel);
const uint8_t *ahbData = reinterpret_cast<uint8_t *>(mappedMemory) +
(z * height + y) * rowStride +
z * layerPitch + y * rowStride +
x * data[0].bytesPerPixel;
std::vector<uint8_t> ahb(ahbData, ahbData + data[0].bytesPerPixel);