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