Vulkan: Implement EGL Images for 2D and Renderbuffer sources.
No support for non-zero mipmaps as sources yet.
Suppress dEQP tests due to apparent driver bugs with scissored clears on depth
or stencil attachments.
BUG=angleproject:2668
Change-Id: Idaa5e70ce9b0c91232fbb989cbf4de1b9134aafb
Reviewed-on: https://chromium-review.googlesource.com/c/1415010
Commit-Queue: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/ImageVk.cpp b/src/libANGLE/renderer/vulkan/ImageVk.cpp
index 5ad2903..a804547 100644
--- a/src/libANGLE/renderer/vulkan/ImageVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ImageVk.cpp
@@ -11,25 +11,106 @@
#include "common/debug.h"
#include "libANGLE/Context.h"
+#include "libANGLE/Display.h"
#include "libANGLE/renderer/vulkan/ContextVk.h"
+#include "libANGLE/renderer/vulkan/DisplayVk.h"
+#include "libANGLE/renderer/vulkan/RenderbufferVk.h"
+#include "libANGLE/renderer/vulkan/TextureVk.h"
#include "libANGLE/renderer/vulkan/vk_utils.h"
namespace rx
{
-ImageVk::ImageVk(const egl::ImageState &state) : ImageImpl(state) {}
+ImageVk::ImageVk(const egl::ImageState &state, const gl::Context *context)
+ : ImageImpl(state), mOwnsImage(false), mImage(nullptr), mContext(context)
+{}
ImageVk::~ImageVk() {}
+void ImageVk::onDestroy(const egl::Display *display)
+{
+ DisplayVk *displayVk = vk::GetImpl(display);
+ RendererVk *renderer = displayVk->getRenderer();
+
+ if (mImage != nullptr && mOwnsImage)
+ {
+ mImage->releaseImage(renderer);
+ mImage->releaseStagingBuffer(renderer);
+ delete mImage;
+ }
+ mImage = nullptr;
+}
+
egl::Error ImageVk::initialize(const egl::Display *display)
{
- UNIMPLEMENTED();
- return egl::EglBadAccess();
+
+ if (egl::IsTextureTarget(mState.target))
+ {
+ TextureVk *textureVk = GetImplAs<TextureVk>(GetAs<gl::Texture>(mState.source));
+
+ // Make sure the texture has created its backing storage
+ ASSERT(mContext != nullptr);
+ ContextVk *contextVk = vk::GetImpl(mContext);
+ ANGLE_TRY(ResultToEGL(textureVk->ensureImageInitialized(contextVk)));
+
+ mImage = &textureVk->getImage();
+
+ // The staging buffer for a texture source should already be initialized
+
+ mOwnsImage = false;
+
+ ASSERT(mState.imageIndex.getLevelIndex() == 0);
+ }
+ else if (egl::IsRenderbufferTarget(mState.target))
+ {
+ RenderbufferVk *renderbufferVk =
+ GetImplAs<RenderbufferVk>(GetAs<gl::Renderbuffer>(mState.source));
+ mImage = renderbufferVk->getImage();
+
+ // Make sure a staging buffer is ready to use to upload data
+ ASSERT(mContext != nullptr);
+ ContextVk *contextVk = vk::GetImpl(mContext);
+ RendererVk *renderer = contextVk->getRenderer();
+ mImage->initStagingBuffer(renderer);
+
+ mOwnsImage = false;
+ }
+ else
+ {
+ UNREACHABLE();
+ return egl::EglBadAccess();
+ }
+
+ return egl::NoError();
}
angle::Result ImageVk::orphan(const gl::Context *context, egl::ImageSibling *sibling)
{
- ANGLE_VK_UNREACHABLE(vk::GetImpl(context));
- return angle::Result::Stop;
+ if (sibling == mState.source)
+ {
+ if (egl::IsTextureTarget(mState.target))
+ {
+ TextureVk *textureVk = GetImplAs<TextureVk>(GetAs<gl::Texture>(mState.source));
+ ASSERT(mImage == &textureVk->getImage());
+ textureVk->releaseOwnershipOfImage(context);
+ mOwnsImage = true;
+ }
+ else if (egl::IsRenderbufferTarget(mState.target))
+ {
+ RenderbufferVk *renderbufferVk =
+ GetImplAs<RenderbufferVk>(GetAs<gl::Renderbuffer>(mState.source));
+ ASSERT(mImage == renderbufferVk->getImage());
+ renderbufferVk->releaseOwnershipOfImage(context);
+ mOwnsImage = true;
+ }
+ else
+ {
+ ANGLE_VK_UNREACHABLE(vk::GetImpl(context));
+ return angle::Result::Stop;
+ }
+ }
+
+ return angle::Result::Continue;
}
+
} // namespace rx