Commit eca36cb5 by Geoff Lang Committed by Commit Bot

Vulkan: Support EGL images sourced from cube maps.

Store an image array offset and source texture type in ImageVk to select the correct cube face from the source texture. BUG=angleproject:2668 Change-Id: I03ad25feccb769c906dd28fb573ec342e7816863 Reviewed-on: https://chromium-review.googlesource.com/c/1422542 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent 341304d8
......@@ -184,15 +184,13 @@ void DisplayVk::generateExtensions(egl::DisplayExtensions *outExtensions) const
outExtensions->fenceSync = true;
outExtensions->waitSync = true;
outExtensions->image = true;
outExtensions->imageBase = true;
outExtensions->imagePixmap = false; // ANGLE does not support pixmaps
outExtensions->glTexture2DImage = true;
// TODO(geofflang): Support EGL_KHR_gl_texture_cubemap_image. http://anglebug.com/2668
outExtensions->glTextureCubemapImage = false;
// TODO(geofflang): Support ES3 and EGL_KHR_gl_texture_3D_image. http://anglebug.com/2668
outExtensions->glTexture3DImage = false;
outExtensions->glRenderbufferImage = true;
outExtensions->image = true;
outExtensions->imageBase = true;
outExtensions->imagePixmap = false; // ANGLE does not support pixmaps
outExtensions->glTexture2DImage = true;
outExtensions->glTextureCubemapImage = true;
outExtensions->glTexture3DImage = false;
outExtensions->glRenderbufferImage = true;
}
void DisplayVk::generateCaps(egl::Caps *outCaps) const
......
......@@ -58,7 +58,9 @@ egl::Error ImageVk::initialize(const egl::Display *display)
mOwnsImage = false;
mImageLevel = mState.imageIndex.getLevelIndex();
mImageTextureType = mState.imageIndex.getType();
mImageLevel = mState.imageIndex.getLevelIndex();
mImageLayer = mState.imageIndex.hasLayer() ? mState.imageIndex.getLayerIndex() : 0;
}
else if (egl::IsRenderbufferTarget(mState.target))
{
......@@ -74,7 +76,9 @@ egl::Error ImageVk::initialize(const egl::Display *display)
mOwnsImage = false;
mImageLevel = 0;
mImageTextureType = gl::TextureType::_2D;
mImageLevel = 0;
mImageLayer = 0;
}
else
{
......
......@@ -28,10 +28,14 @@ class ImageVk : public ImageImpl
angle::Result orphan(const gl::Context *context, egl::ImageSibling *sibling) override;
vk::ImageHelper *getImage() const { return mImage; }
gl::TextureType getImageTextureType() const { return mImageTextureType; }
uint32_t getImageLevel() const { return mImageLevel; }
uint32_t getImageLayer() const { return mImageLayer; }
private:
gl::TextureType mImageTextureType;
uint32_t mImageLevel;
uint32_t mImageLayer;
bool mOwnsImage;
vk::ImageHelper *mImage;
......
......@@ -139,10 +139,12 @@ angle::Result RenderbufferVk::setStorageEGLImageTarget(const gl::Context *contex
VkImageAspectFlags aspect = vk::GetFormatAspectFlags(textureFormat);
ANGLE_TRY(mImage->initImageView(contextVk, gl::TextureType::_2D, aspect, gl::SwizzleState(),
&mImageView, imageVk->getImageLevel(), 1));
ANGLE_TRY(mImage->initLayerImageView(contextVk, imageVk->getImageTextureType(), aspect,
gl::SwizzleState(), &mImageView, imageVk->getImageLevel(),
1, imageVk->getImageLayer(), 1));
mRenderTarget.init(mImage, &mImageView, imageVk->getImageLevel(), 0, nullptr);
mRenderTarget.init(mImage, &mImageView, imageVk->getImageLevel(), imageVk->getImageLayer(),
nullptr);
return angle::Result::Continue;
}
......
......@@ -564,7 +564,8 @@ angle::Result TextureVk::setEGLImageTarget(const gl::Context *context,
releaseAndDeleteImage(context, renderer);
ImageVk *imageVk = vk::GetImpl(image);
setImageHelper(renderer, imageVk->getImage(), imageVk->getImageLevel(), false);
setImageHelper(renderer, imageVk->getImage(), imageVk->getImageTextureType(),
imageVk->getImageLevel(), imageVk->getImageLayer(), false);
const vk::Format &format = renderer->getFormat(image->getFormat().info->sizedInternalFormat);
ANGLE_TRY(initImageViews(contextVk, format, 1));
......@@ -583,9 +584,22 @@ angle::Result TextureVk::setImageExternal(const gl::Context *context,
gl::ImageIndex TextureVk::getNativeImageIndex(const gl::ImageIndex &inputImageIndex) const
{
return gl::ImageIndex::MakeFromType(
inputImageIndex.getType(), getNativeImageLevel(inputImageIndex.getLevelIndex()),
inputImageIndex.getLayerIndex(), inputImageIndex.getLayerCount());
// The input index can be a specific layer (for cube maps, 2d arrays, etc) or mImageLayerOffset
// can be non-zero but both of these cannot be true at the same time. EGL images can source
// from a cube map or 3D texture but can only be a 2D destination.
ASSERT(!(inputImageIndex.hasLayer() && mImageLayerOffset > 0));
// handle the special-case where image index can represent a whole level of a texture
GLint resultImageLayer = inputImageIndex.getLayerIndex();
if (inputImageIndex.getType() != mImageNativeType)
{
ASSERT(!inputImageIndex.hasLayer());
resultImageLayer = mImageLayerOffset;
}
return gl::ImageIndex::MakeFromType(mImageNativeType,
getNativeImageLevel(inputImageIndex.getLevelIndex()),
resultImageLayer, inputImageIndex.getLayerCount());
}
uint32_t TextureVk::getNativeImageLevel(uint32_t frontendLevel) const
......@@ -593,6 +607,11 @@ uint32_t TextureVk::getNativeImageLevel(uint32_t frontendLevel) const
return mImageLevelOffset + frontendLevel;
}
uint32_t TextureVk::getNativeImageLayer(uint32_t frontendLayer) const
{
return mImageLayerOffset + frontendLayer;
}
void TextureVk::releaseAndDeleteImage(const gl::Context *context, RendererVk *renderer)
{
if (mImage)
......@@ -607,7 +626,7 @@ angle::Result TextureVk::ensureImageAllocated(RendererVk *renderer)
{
if (mImage == nullptr)
{
setImageHelper(renderer, new vk::ImageHelper(), 0, true);
setImageHelper(renderer, new vk::ImageHelper(), mState.getType(), 0, 0, true);
}
return angle::Result::Continue;
......@@ -615,17 +634,22 @@ angle::Result TextureVk::ensureImageAllocated(RendererVk *renderer)
void TextureVk::setImageHelper(RendererVk *renderer,
vk::ImageHelper *imageHelper,
uint32_t imageMipOffset,
gl::TextureType imageType,
uint32_t imageLevelOffset,
uint32_t imageLayerOffset,
bool selfOwned)
{
ASSERT(mImage == nullptr);
mOwnsImage = selfOwned;
mImageLevelOffset = imageMipOffset;
mImageNativeType = imageType;
mImageLevelOffset = imageLevelOffset;
mImageLayerOffset = imageLayerOffset;
mImage = imageHelper;
mImage->initStagingBuffer(renderer);
mRenderTarget.init(mImage, &mDrawBaseLevelImageView, getNativeImageLevel(0), 0, this);
mRenderTarget.init(mImage, &mDrawBaseLevelImageView, getNativeImageLevel(0),
getNativeImageLayer(0), this);
// Force re-creation of cube map render targets next time they are needed
mCubeMapRenderTargets.clear();
......@@ -814,8 +838,8 @@ angle::Result TextureVk::bindTexImage(const gl::Context *context, egl::Surface *
// eglBindTexImage can only be called with pbuffer (offscreen) surfaces
OffscreenSurfaceVk *offscreenSurface = GetImplAs<OffscreenSurfaceVk>(surface);
setImageHelper(renderer, offscreenSurface->getColorAttachmentImage(), surface->getMipmapLevel(),
false);
setImageHelper(renderer, offscreenSurface->getColorAttachmentImage(), mState.getType(),
surface->getMipmapLevel(), 0, false);
const vk::Format &format = renderer->getFormat(surface->getConfig()->renderTargetFormat);
return initImageViews(contextVk, format, 1);
......@@ -902,7 +926,7 @@ angle::Result TextureVk::initCubeMapRenderTargets(ContextVk *contextVk)
vk::ImageView *imageView;
ANGLE_TRY(getLayerLevelDrawImageView(contextVk, cubeMapFaceIndex, 0, &imageView));
mCubeMapRenderTargets[cubeMapFaceIndex].init(mImage, imageView, getNativeImageLevel(0),
cubeMapFaceIndex, this);
getNativeImageLayer(cubeMapFaceIndex), this);
}
return angle::Result::Continue;
}
......@@ -1023,7 +1047,7 @@ angle::Result TextureVk::getLayerLevelDrawImageView(vk::Context *context,
// don't have swizzle.
return mImage->initLayerImageView(context, mState.getType(), VK_IMAGE_ASPECT_COLOR_BIT,
gl::SwizzleState(), *imageViewOut, getNativeImageLevel(level),
1, layer, 1);
1, getNativeImageLayer(layer), 1);
}
const vk::Sampler &TextureVk::getSampler() const
......@@ -1070,14 +1094,19 @@ angle::Result TextureVk::initImageViews(ContextVk *contextVk,
// TODO: Support non-zero base level for ES 3.0 by passing it to getNativeImageLevel.
// http://anglebug.com/3148
uint32_t baseLevel = getNativeImageLevel(0);
ANGLE_TRY(mImage->initImageView(contextVk, mState.getType(), VK_IMAGE_ASPECT_COLOR_BIT,
mappedSwizzle, &mReadMipmapImageView, baseLevel, levelCount));
ANGLE_TRY(mImage->initImageView(contextVk, mState.getType(), VK_IMAGE_ASPECT_COLOR_BIT,
mappedSwizzle, &mReadBaseLevelImageView, baseLevel, 1));
ANGLE_TRY(mImage->initImageView(contextVk, mState.getType(), VK_IMAGE_ASPECT_COLOR_BIT,
gl::SwizzleState(), &mDrawBaseLevelImageView, baseLevel, 1));
uint32_t baseLevel = getNativeImageLevel(0);
uint32_t baseLayer = getNativeImageLayer(0);
uint32_t layerCount = mState.getType() == gl::TextureType::CubeMap ? gl::kCubeFaceCount : 1;
ANGLE_TRY(mImage->initLayerImageView(contextVk, mState.getType(), VK_IMAGE_ASPECT_COLOR_BIT,
mappedSwizzle, &mReadMipmapImageView, baseLevel,
levelCount, baseLayer, layerCount));
ANGLE_TRY(mImage->initLayerImageView(contextVk, mState.getType(), VK_IMAGE_ASPECT_COLOR_BIT,
mappedSwizzle, &mReadBaseLevelImageView, baseLevel, 1,
baseLayer, layerCount));
ANGLE_TRY(mImage->initLayerImageView(contextVk, mState.getType(), VK_IMAGE_ASPECT_COLOR_BIT,
gl::SwizzleState(), &mDrawBaseLevelImageView, baseLevel, 1,
baseLayer, layerCount));
return angle::Result::Continue;
}
......
......@@ -155,12 +155,15 @@ class TextureVk : public TextureImpl
// ImageHelper, taking into account mipmap or cube face offsets
gl::ImageIndex getNativeImageIndex(const gl::ImageIndex &inputImageIndex) const;
uint32_t getNativeImageLevel(uint32_t frontendLevel) const;
uint32_t getNativeImageLayer(uint32_t frontendLayer) const;
void releaseAndDeleteImage(const gl::Context *context, RendererVk *renderer);
angle::Result ensureImageAllocated(RendererVk *renderer);
void setImageHelper(RendererVk *renderer,
vk::ImageHelper *imageHelper,
uint32_t imageMipOffset,
gl::TextureType imageType,
uint32_t imageLevelOffset,
uint32_t imageLayerOffset,
bool selfOwned);
angle::Result redefineImage(const gl::Context *context,
......@@ -237,6 +240,12 @@ class TextureVk : public TextureImpl
bool mOwnsImage;
gl::TextureType mImageNativeType;
// The layer offset to apply when converting from a frontend texture layer to a texture layer in
// mImage. Used when this texture sources a cube map face or 3D texture layer from an EGL image.
uint32_t mImageLayerOffset;
// The level offset to apply when converting from a frontend texture level to texture level in
// mImage.
uint32_t mImageLevelOffset;
......
......@@ -521,8 +521,7 @@ TEST_P(ImageTest, ANGLEExtensionAvailability)
EXPECT_FALSE(hasExternalExt());
EXPECT_TRUE(hasBaseExt());
EXPECT_TRUE(has2DTextureExt());
// TODO(geofflang): Support EGL_KHR_gl_texture_cubemap_image. http://anglebug.com/2668
EXPECT_FALSE(hasCubemapExt());
EXPECT_TRUE(hasCubemapExt());
EXPECT_TRUE(hasRenderbufferExt());
// TODO(geofflang): Support GL_OES_EGL_image_external_essl3. http://anglebug.com/2668
EXPECT_FALSE(hasExternalESSL3Ext());
......
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