Commit fe59f6b5 by Geoff Lang Committed by Commit Bot

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: 's avatarJamie Madill <jmadill@chromium.org>
parent abf6dbbb
...@@ -197,6 +197,7 @@ rx::FramebufferAttachmentObjectImpl *ExternalImageSibling::getAttachmentImpl() c ...@@ -197,6 +197,7 @@ rx::FramebufferAttachmentObjectImpl *ExternalImageSibling::getAttachmentImpl() c
ImageState::ImageState(EGLenum target, ImageSibling *buffer, const AttributeMap &attribs) ImageState::ImageState(EGLenum target, ImageSibling *buffer, const AttributeMap &attribs)
: label(nullptr), : label(nullptr),
target(target),
imageIndex(GetImageIndex(target, attribs)), imageIndex(GetImageIndex(target, attribs)),
source(buffer), source(buffer),
targets(), targets(),
...@@ -242,6 +243,8 @@ void Image::onDestroy(const Display *display) ...@@ -242,6 +243,8 @@ void Image::onDestroy(const Display *display)
mState.source = nullptr; mState.source = nullptr;
} }
mImplementation->onDestroy(display);
} }
Image::~Image() Image::~Image()
......
...@@ -110,6 +110,7 @@ struct ImageState : private angle::NonCopyable ...@@ -110,6 +110,7 @@ struct ImageState : private angle::NonCopyable
~ImageState(); ~ImageState();
EGLLabelKHR label; EGLLabelKHR label;
EGLenum target;
gl::ImageIndex imageIndex; gl::ImageIndex imageIndex;
ImageSibling *source; ImageSibling *source;
std::set<ImageSibling *> targets; std::set<ImageSibling *> targets;
......
...@@ -45,6 +45,8 @@ class ImageImpl : angle::NonCopyable ...@@ -45,6 +45,8 @@ class ImageImpl : angle::NonCopyable
public: public:
ImageImpl(const egl::ImageState &state) : mState(state) {} ImageImpl(const egl::ImageState &state) : mState(state) {}
virtual ~ImageImpl() {} virtual ~ImageImpl() {}
virtual void onDestroy(const egl::Display *display) {}
virtual egl::Error initialize(const egl::Display *display) = 0; virtual egl::Error initialize(const egl::Display *display) = 0;
virtual angle::Result orphan(const gl::Context *context, egl::ImageSibling *sibling) = 0; virtual angle::Result orphan(const gl::Context *context, egl::ImageSibling *sibling) = 0;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "libANGLE/Context.h" #include "libANGLE/Context.h"
#include "libANGLE/Display.h" #include "libANGLE/Display.h"
#include "libANGLE/renderer/vulkan/ContextVk.h" #include "libANGLE/renderer/vulkan/ContextVk.h"
#include "libANGLE/renderer/vulkan/ImageVk.h"
#include "libANGLE/renderer/vulkan/RendererVk.h" #include "libANGLE/renderer/vulkan/RendererVk.h"
#include "libANGLE/renderer/vulkan/SurfaceVk.h" #include "libANGLE/renderer/vulkan/SurfaceVk.h"
#include "libANGLE/renderer/vulkan/SyncVk.h" #include "libANGLE/renderer/vulkan/SyncVk.h"
...@@ -135,8 +136,7 @@ ImageImpl *DisplayVk::createImage(const egl::ImageState &state, ...@@ -135,8 +136,7 @@ ImageImpl *DisplayVk::createImage(const egl::ImageState &state,
EGLenum target, EGLenum target,
const egl::AttributeMap &attribs) const egl::AttributeMap &attribs)
{ {
UNIMPLEMENTED(); return new ImageVk(state, context);
return static_cast<ImageImpl *>(0);
} }
rx::ContextImpl *DisplayVk::createContext(const gl::State &state, rx::ContextImpl *DisplayVk::createContext(const gl::State &state,
...@@ -183,6 +183,16 @@ void DisplayVk::generateExtensions(egl::DisplayExtensions *outExtensions) const ...@@ -183,6 +183,16 @@ void DisplayVk::generateExtensions(egl::DisplayExtensions *outExtensions) const
outExtensions->fenceSync = true; outExtensions->fenceSync = true;
outExtensions->waitSync = 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;
} }
void DisplayVk::generateCaps(egl::Caps *outCaps) const void DisplayVk::generateCaps(egl::Caps *outCaps) const
......
...@@ -11,25 +11,106 @@ ...@@ -11,25 +11,106 @@
#include "common/debug.h" #include "common/debug.h"
#include "libANGLE/Context.h" #include "libANGLE/Context.h"
#include "libANGLE/Display.h"
#include "libANGLE/renderer/vulkan/ContextVk.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" #include "libANGLE/renderer/vulkan/vk_utils.h"
namespace rx 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() {} 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) 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::Result ImageVk::orphan(const gl::Context *context, egl::ImageSibling *sibling)
{ {
ANGLE_VK_UNREACHABLE(vk::GetImpl(context)); if (sibling == mState.source)
return angle::Result::Stop; {
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 } // namespace rx
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#define LIBANGLE_RENDERER_VULKAN_IMAGEVK_H_ #define LIBANGLE_RENDERER_VULKAN_IMAGEVK_H_
#include "libANGLE/renderer/ImageImpl.h" #include "libANGLE/renderer/ImageImpl.h"
#include "libANGLE/renderer/vulkan/vk_helpers.h"
namespace rx namespace rx
{ {
...@@ -18,11 +19,21 @@ namespace rx ...@@ -18,11 +19,21 @@ namespace rx
class ImageVk : public ImageImpl class ImageVk : public ImageImpl
{ {
public: public:
ImageVk(const egl::ImageState &state); ImageVk(const egl::ImageState &state, const gl::Context *context);
~ImageVk() override; ~ImageVk() override;
void onDestroy(const egl::Display *display) override;
egl::Error initialize(const egl::Display *display) override; egl::Error initialize(const egl::Display *display) override;
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; }
private:
bool mOwnsImage;
vk::ImageHelper *mImage;
const gl::Context *mContext;
}; };
} // namespace rx } // namespace rx
......
...@@ -10,7 +10,9 @@ ...@@ -10,7 +10,9 @@
#include "libANGLE/renderer/vulkan/RenderbufferVk.h" #include "libANGLE/renderer/vulkan/RenderbufferVk.h"
#include "libANGLE/Context.h" #include "libANGLE/Context.h"
#include "libANGLE/Image.h"
#include "libANGLE/renderer/vulkan/ContextVk.h" #include "libANGLE/renderer/vulkan/ContextVk.h"
#include "libANGLE/renderer/vulkan/ImageVk.h"
#include "libANGLE/renderer/vulkan/RendererVk.h" #include "libANGLE/renderer/vulkan/RendererVk.h"
namespace rx namespace rx
...@@ -24,7 +26,7 @@ constexpr VkClearColorValue kBlackClearColorValue = {{0}}; ...@@ -24,7 +26,7 @@ constexpr VkClearColorValue kBlackClearColorValue = {{0}};
} // anonymous namespace } // anonymous namespace
RenderbufferVk::RenderbufferVk(const gl::RenderbufferState &state) RenderbufferVk::RenderbufferVk(const gl::RenderbufferState &state)
: RenderbufferImpl(state), mImage(nullptr) : RenderbufferImpl(state), mOwnsImage(false), mImage(nullptr)
{} {}
RenderbufferVk::~RenderbufferVk() {} RenderbufferVk::~RenderbufferVk() {}
...@@ -33,15 +35,7 @@ void RenderbufferVk::onDestroy(const gl::Context *context) ...@@ -33,15 +35,7 @@ void RenderbufferVk::onDestroy(const gl::Context *context)
{ {
ContextVk *contextVk = vk::GetImpl(context); ContextVk *contextVk = vk::GetImpl(context);
RendererVk *renderer = contextVk->getRenderer(); RendererVk *renderer = contextVk->getRenderer();
releaseAndDeleteImage(context, renderer);
if (mImage)
{
mImage->releaseImage(renderer);
mImage->releaseStagingBuffer(renderer);
SafeDelete(mImage);
}
renderer->releaseObject(renderer->getCurrentQueueSerial(), &mImageView);
} }
angle::Result RenderbufferVk::setStorage(const gl::Context *context, angle::Result RenderbufferVk::setStorage(const gl::Context *context,
...@@ -53,6 +47,11 @@ angle::Result RenderbufferVk::setStorage(const gl::Context *context, ...@@ -53,6 +47,11 @@ angle::Result RenderbufferVk::setStorage(const gl::Context *context,
RendererVk *renderer = contextVk->getRenderer(); RendererVk *renderer = contextVk->getRenderer();
const vk::Format &vkFormat = renderer->getFormat(internalformat); const vk::Format &vkFormat = renderer->getFormat(internalformat);
if (!mOwnsImage)
{
releaseAndDeleteImage(context, renderer);
}
if (mImage != nullptr && mImage->valid()) if (mImage != nullptr && mImage->valid())
{ {
// Check against the state if we need to recreate the storage. // Check against the state if we need to recreate the storage.
...@@ -60,8 +59,7 @@ angle::Result RenderbufferVk::setStorage(const gl::Context *context, ...@@ -60,8 +59,7 @@ angle::Result RenderbufferVk::setStorage(const gl::Context *context,
static_cast<GLsizei>(width) != mState.getWidth() || static_cast<GLsizei>(width) != mState.getWidth() ||
static_cast<GLsizei>(height) != mState.getHeight()) static_cast<GLsizei>(height) != mState.getHeight())
{ {
mImage->releaseImage(renderer); releaseImage(context, renderer);
renderer->releaseObject(renderer->getCurrentQueueSerial(), &mImageView);
} }
} }
...@@ -69,7 +67,8 @@ angle::Result RenderbufferVk::setStorage(const gl::Context *context, ...@@ -69,7 +67,8 @@ angle::Result RenderbufferVk::setStorage(const gl::Context *context,
{ {
if (mImage == nullptr) if (mImage == nullptr)
{ {
mImage = new vk::ImageHelper(); mImage = new vk::ImageHelper();
mOwnsImage = true;
} }
const angle::Format &textureFormat = vkFormat.textureFormat(); const angle::Format &textureFormat = vkFormat.textureFormat();
...@@ -126,8 +125,26 @@ angle::Result RenderbufferVk::setStorageMultisample(const gl::Context *context, ...@@ -126,8 +125,26 @@ angle::Result RenderbufferVk::setStorageMultisample(const gl::Context *context,
angle::Result RenderbufferVk::setStorageEGLImageTarget(const gl::Context *context, angle::Result RenderbufferVk::setStorageEGLImageTarget(const gl::Context *context,
egl::Image *image) egl::Image *image)
{ {
ANGLE_VK_UNREACHABLE(vk::GetImpl(context)); ContextVk *contextVk = vk::GetImpl(context);
return angle::Result::Stop; RendererVk *renderer = contextVk->getRenderer();
releaseAndDeleteImage(context, renderer);
ImageVk *imageVk = vk::GetImpl(image);
mImage = imageVk->getImage();
mOwnsImage = false;
const vk::Format &vkFormat = renderer->getFormat(image->getFormat().info->sizedInternalFormat);
const angle::Format &textureFormat = vkFormat.textureFormat();
VkImageAspectFlags aspect = vk::GetFormatAspectFlags(textureFormat);
ANGLE_TRY(mImage->initImageView(contextVk, gl::TextureType::_2D, aspect, gl::SwizzleState(),
&mImageView, 1));
mRenderTarget.init(mImage, &mImageView, 0, nullptr);
return angle::Result::Continue;
} }
angle::Result RenderbufferVk::getAttachmentRenderTarget(const gl::Context *context, angle::Result RenderbufferVk::getAttachmentRenderTarget(const gl::Context *context,
...@@ -147,4 +164,34 @@ angle::Result RenderbufferVk::initializeContents(const gl::Context *context, ...@@ -147,4 +164,34 @@ angle::Result RenderbufferVk::initializeContents(const gl::Context *context,
return angle::Result::Continue; return angle::Result::Continue;
} }
void RenderbufferVk::releaseOwnershipOfImage(const gl::Context *context)
{
ContextVk *contextVk = vk::GetImpl(context);
RendererVk *renderer = contextVk->getRenderer();
mOwnsImage = false;
releaseAndDeleteImage(context, renderer);
}
void RenderbufferVk::releaseAndDeleteImage(const gl::Context *context, RendererVk *renderer)
{
releaseImage(context, renderer);
SafeDelete(mImage);
}
void RenderbufferVk::releaseImage(const gl::Context *context, RendererVk *renderer)
{
if (mImage && mOwnsImage)
{
mImage->releaseImage(renderer);
mImage->releaseStagingBuffer(renderer);
}
else
{
mImage = nullptr;
}
renderer->releaseObject(renderer->getCurrentQueueSerial(), &mImageView);
}
} // namespace rx } // namespace rx
...@@ -44,7 +44,14 @@ class RenderbufferVk : public RenderbufferImpl ...@@ -44,7 +44,14 @@ class RenderbufferVk : public RenderbufferImpl
angle::Result initializeContents(const gl::Context *context, angle::Result initializeContents(const gl::Context *context,
const gl::ImageIndex &imageIndex) override; const gl::ImageIndex &imageIndex) override;
vk::ImageHelper *getImage() const { return mImage; }
void releaseOwnershipOfImage(const gl::Context *context);
private: private:
void releaseAndDeleteImage(const gl::Context *context, RendererVk *renderer);
void releaseImage(const gl::Context *context, RendererVk *renderer);
bool mOwnsImage;
vk::ImageHelper *mImage; vk::ImageHelper *mImage;
vk::ImageView mImageView; vk::ImageView mImageView;
RenderTargetVk mRenderTarget; RenderTargetVk mRenderTarget;
......
...@@ -13,9 +13,11 @@ ...@@ -13,9 +13,11 @@
#include "image_util/generatemip.inl" #include "image_util/generatemip.inl"
#include "libANGLE/Config.h" #include "libANGLE/Config.h"
#include "libANGLE/Context.h" #include "libANGLE/Context.h"
#include "libANGLE/Image.h"
#include "libANGLE/Surface.h" #include "libANGLE/Surface.h"
#include "libANGLE/renderer/vulkan/ContextVk.h" #include "libANGLE/renderer/vulkan/ContextVk.h"
#include "libANGLE/renderer/vulkan/FramebufferVk.h" #include "libANGLE/renderer/vulkan/FramebufferVk.h"
#include "libANGLE/renderer/vulkan/ImageVk.h"
#include "libANGLE/renderer/vulkan/RendererVk.h" #include "libANGLE/renderer/vulkan/RendererVk.h"
#include "libANGLE/renderer/vulkan/SurfaceVk.h" #include "libANGLE/renderer/vulkan/SurfaceVk.h"
#include "libANGLE/renderer/vulkan/vk_format_utils.h" #include "libANGLE/renderer/vulkan/vk_format_utils.h"
...@@ -528,6 +530,11 @@ angle::Result TextureVk::setStorage(const gl::Context *context, ...@@ -528,6 +530,11 @@ angle::Result TextureVk::setStorage(const gl::Context *context,
ContextVk *contextVk = GetAs<ContextVk>(context->getImplementation()); ContextVk *contextVk = GetAs<ContextVk>(context->getImplementation());
RendererVk *renderer = contextVk->getRenderer(); RendererVk *renderer = contextVk->getRenderer();
if (!mOwnsImage)
{
releaseAndDeleteImage(context, renderer);
}
ANGLE_TRY(ensureImageAllocated(renderer)); ANGLE_TRY(ensureImageAllocated(renderer));
const vk::Format &format = renderer->getFormat(internalFormat); const vk::Format &format = renderer->getFormat(internalFormat);
...@@ -547,8 +554,18 @@ angle::Result TextureVk::setEGLImageTarget(const gl::Context *context, ...@@ -547,8 +554,18 @@ angle::Result TextureVk::setEGLImageTarget(const gl::Context *context,
gl::TextureType type, gl::TextureType type,
egl::Image *image) egl::Image *image)
{ {
ANGLE_VK_UNREACHABLE(vk::GetImpl(context)); ContextVk *contextVk = vk::GetImpl(context);
return angle::Result::Stop; RendererVk *renderer = contextVk->getRenderer();
releaseAndDeleteImage(context, renderer);
ImageVk *imageVk = vk::GetImpl(image);
setImageHelper(renderer, imageVk->getImage(), false);
const vk::Format &format = renderer->getFormat(image->getFormat().info->sizedInternalFormat);
ANGLE_TRY(initImageViews(contextVk, format, 1));
return angle::Result::Continue;
} }
angle::Result TextureVk::setImageExternal(const gl::Context *context, angle::Result TextureVk::setImageExternal(const gl::Context *context,
...@@ -602,9 +619,10 @@ angle::Result TextureVk::redefineImage(const gl::Context *context, ...@@ -602,9 +619,10 @@ angle::Result TextureVk::redefineImage(const gl::Context *context,
ContextVk *contextVk = vk::GetImpl(context); ContextVk *contextVk = vk::GetImpl(context);
RendererVk *renderer = contextVk->getRenderer(); RendererVk *renderer = contextVk->getRenderer();
// Make sure the image is not allocated yet or it is owned by this texture. We don't want to if (!mOwnsImage)
// redefine an external image. {
ASSERT(mImage == nullptr || mOwnsImage); releaseAndDeleteImage(context, renderer);
}
if (!size.empty()) if (!size.empty())
{ {
...@@ -929,6 +947,15 @@ angle::Result TextureVk::initializeContents(const gl::Context *context, ...@@ -929,6 +947,15 @@ angle::Result TextureVk::initializeContents(const gl::Context *context,
return angle::Result::Continue; return angle::Result::Continue;
} }
void TextureVk::releaseOwnershipOfImage(const gl::Context *context)
{
ContextVk *contextVk = vk::GetImpl(context);
RendererVk *renderer = contextVk->getRenderer();
mOwnsImage = false;
releaseAndDeleteImage(context, renderer);
}
const vk::ImageView &TextureVk::getReadImageView() const const vk::ImageView &TextureVk::getReadImageView() const
{ {
ASSERT(mImage->valid()); ASSERT(mImage->valid());
......
...@@ -139,6 +139,8 @@ class TextureVk : public TextureImpl ...@@ -139,6 +139,8 @@ class TextureVk : public TextureImpl
return *mImage; return *mImage;
} }
void releaseOwnershipOfImage(const gl::Context *context);
const vk::ImageView &getReadImageView() const; const vk::ImageView &getReadImageView() const;
angle::Result getLayerLevelDrawImageView(vk::Context *context, angle::Result getLayerLevelDrawImageView(vk::Context *context,
size_t layer, size_t layer,
......
...@@ -50,6 +50,12 @@ void GenerateCaps(const VkPhysicalDeviceProperties &physicalDeviceProperties, ...@@ -50,6 +50,12 @@ void GenerateCaps(const VkPhysicalDeviceProperties &physicalDeviceProperties,
outExtensions->textureBorderClamp = false; // not implemented yet outExtensions->textureBorderClamp = false; // not implemented yet
outExtensions->translatedShaderSource = true; outExtensions->translatedShaderSource = true;
outExtensions->eglImage = true;
// TODO(geofflang): Support GL_OES_EGL_image_external. http://anglebug.com/2668
outExtensions->eglImageExternal = false;
// TODO(geofflang): Support GL_OES_EGL_image_external_essl3. http://anglebug.com/2668
outExtensions->eglImageExternalEssl3 = false;
// Only expose robust buffer access if the physical device supports it. // Only expose robust buffer access if the physical device supports it.
outExtensions->robustBufferAccessBehavior = physicalDeviceFeatures.robustBufferAccess; outExtensions->robustBufferAccessBehavior = physicalDeviceFeatures.robustBufferAccess;
......
...@@ -1958,7 +1958,7 @@ angle::Result ImageHelper::allocateStagingMemory(ContextVk *contextVk, ...@@ -1958,7 +1958,7 @@ angle::Result ImageHelper::allocateStagingMemory(ContextVk *contextVk,
newBufferAllocatedOut); newBufferAllocatedOut);
} }
angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk, angle::Result ImageHelper::flushStagedUpdates(Context *context,
uint32_t levelCount, uint32_t levelCount,
vk::CommandBuffer *commandBuffer) vk::CommandBuffer *commandBuffer)
{ {
...@@ -1967,9 +1967,9 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk, ...@@ -1967,9 +1967,9 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk,
return angle::Result::Continue; return angle::Result::Continue;
} }
RendererVk *renderer = contextVk->getRenderer(); RendererVk *renderer = context->getRenderer();
ANGLE_TRY(mStagingBuffer.flush(contextVk)); ANGLE_TRY(mStagingBuffer.flush(context));
std::vector<SubresourceUpdate> updatesToKeep; std::vector<SubresourceUpdate> updatesToKeep;
...@@ -2025,7 +2025,7 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk, ...@@ -2025,7 +2025,7 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk,
if (mSubresourceUpdates.empty()) if (mSubresourceUpdates.empty())
{ {
mStagingBuffer.releaseRetainedBuffers(contextVk->getRenderer()); mStagingBuffer.releaseRetainedBuffers(context->getRenderer());
} }
else else
{ {
......
...@@ -659,7 +659,7 @@ class ImageHelper final : public CommandGraphResource ...@@ -659,7 +659,7 @@ class ImageHelper final : public CommandGraphResource
VkDeviceSize *offsetOut, VkDeviceSize *offsetOut,
bool *newBufferAllocatedOut); bool *newBufferAllocatedOut);
angle::Result flushStagedUpdates(ContextVk *contextVk, angle::Result flushStagedUpdates(Context *context,
uint32_t levelCount, uint32_t levelCount,
vk::CommandBuffer *commandBuffer); vk::CommandBuffer *commandBuffer);
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
namespace egl namespace egl
{ {
class Display; class Display;
class Image;
} }
namespace gl namespace gl
...@@ -55,6 +56,7 @@ namespace rx ...@@ -55,6 +56,7 @@ namespace rx
{ {
class CommandGraphResource; class CommandGraphResource;
class DisplayVk; class DisplayVk;
class ImageVk;
class RenderTargetVk; class RenderTargetVk;
class RendererVk; class RendererVk;
class RenderPassCache; class RenderPassCache;
...@@ -136,6 +138,12 @@ struct ImplTypeHelper<egl::Display> ...@@ -136,6 +138,12 @@ struct ImplTypeHelper<egl::Display>
using ImplType = DisplayVk; using ImplType = DisplayVk;
}; };
template <>
struct ImplTypeHelper<egl::Image>
{
using ImplType = ImageVk;
};
template <typename T> template <typename T>
using GetImplType = typename ImplTypeHelper<T>::ImplType; using GetImplType = typename ImplTypeHelper<T>::ImplType;
......
...@@ -272,6 +272,14 @@ ...@@ -272,6 +272,14 @@
2546 ANDROID : dEQP-EGL.functional.thread_cleanup.multi_context_* = SKIP 2546 ANDROID : dEQP-EGL.functional.thread_cleanup.multi_context_* = SKIP
2546 ANDROID : dEQP-EGL.functional.thread_cleanup.single_context_* = FAIL 2546 ANDROID : dEQP-EGL.functional.thread_cleanup.single_context_* = FAIL
// Vulkan
3081 VULKAN : dEQP-EGL.functional.image.create.gles2_renderbuffer_depth16_depth_buffer = SKIP
3081 VULKAN : dEQP-EGL.functional.image.create.gles2_renderbuffer_stencil_stencil_buffer = SKIP
3081 VULKAN : dEQP-EGL.functional.image.modify.renderbuffer_depth16_renderbuffer_clear_depth = SKIP
3081 VULKAN : dEQP-EGL.functional.image.modify.renderbuffer_stencil_renderbuffer_clear_stencil = SKIP
3081 VULKAN : dEQP-EGL.functional.image.render_multiple_contexts.gles2_renderbuffer_depth16_depth_buffer = SKIP
3081 VULKAN : dEQP-EGL.functional.image.render_multiple_contexts.gles2_renderbuffer_stencil_stencil_buffer = SKIP
// ES 1 tests // ES 1 tests
2306 WIN MAC LINUX : dEQP-EGL.functional.color_clears.single_context.gles1* = FAIL 2306 WIN MAC LINUX : dEQP-EGL.functional.color_clears.single_context.gles1* = FAIL
2306 WIN MAC LINUX : dEQP-EGL.functional.color_clears.multi_context.gles1* = FAIL 2306 WIN MAC LINUX : dEQP-EGL.functional.color_clears.multi_context.gles1* = FAIL
......
...@@ -514,6 +514,19 @@ TEST_P(ImageTest, ANGLEExtensionAvailability) ...@@ -514,6 +514,19 @@ TEST_P(ImageTest, ANGLEExtensionAvailability)
EXPECT_FALSE(hasExternalESSL3Ext()); EXPECT_FALSE(hasExternalESSL3Ext());
} }
} }
else if (IsVulkan())
{
EXPECT_TRUE(hasOESExt());
// TODO(geofflang): Support GL_OES_EGL_image_external. http://anglebug.com/2668
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(hasRenderbufferExt());
// TODO(geofflang): Support GL_OES_EGL_image_external_essl3. http://anglebug.com/2668
EXPECT_FALSE(hasExternalESSL3Ext());
}
else else
{ {
EXPECT_FALSE(hasOESExt()); EXPECT_FALSE(hasOESExt());
...@@ -1620,6 +1633,10 @@ TEST_P(ImageTest, MipLevels) ...@@ -1620,6 +1633,10 @@ TEST_P(ImageTest, MipLevels)
// Also fails on NVIDIA Shield TV bot. // Also fails on NVIDIA Shield TV bot.
ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES()); ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());
// TODO(geofflang): Support creating EGL images from non-zero mipmaps in Vulkan.
// http://anglebug.com/2668
ANGLE_SKIP_TEST_IF(IsVulkan());
EGLWindow *window = getEGLWindow(); EGLWindow *window = getEGLWindow();
ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt()); ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
...@@ -1846,6 +1863,10 @@ TEST_P(ImageTest, RespecificationOfOtherLevel) ...@@ -1846,6 +1863,10 @@ TEST_P(ImageTest, RespecificationOfOtherLevel)
// image does not cause orphaning on Qualcomm devices. http://anglebug.com/2744 // image does not cause orphaning on Qualcomm devices. http://anglebug.com/2744
ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES()); ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());
// It is undefined what happens to the mip 0 of the dest texture after it is orphaned. Some
// backends explicitly copy the data but Vulkan does not.
ANGLE_SKIP_TEST_IF(IsVulkan());
EGLWindow *window = getEGLWindow(); EGLWindow *window = getEGLWindow();
ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt()); ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
......
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