Commit f256339a by Geoff Lang Committed by Commit Bot

Vulkan: Implement eglBindTexImage

Now that vk::ImageHelper is stored as a pointer, it can be shared between an offscreen surface and texture. BUG=angleproject:3073 Change-Id: I91e520259106eef497950b8b2e622fbf910f7444 Reviewed-on: https://chromium-review.googlesource.com/c/1412234 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 82e12fd6
...@@ -256,6 +256,11 @@ angle::Result OffscreenSurfaceVk::initializeContents(const gl::Context *context, ...@@ -256,6 +256,11 @@ angle::Result OffscreenSurfaceVk::initializeContents(const gl::Context *context,
return angle::Result::Continue; return angle::Result::Continue;
} }
vk::ImageHelper *OffscreenSurfaceVk::getColorAttachmentImage()
{
return &mColorAttachment.image;
}
WindowSurfaceVk::SwapchainImage::SwapchainImage() = default; WindowSurfaceVk::SwapchainImage::SwapchainImage() = default;
WindowSurfaceVk::SwapchainImage::~SwapchainImage() = default; WindowSurfaceVk::SwapchainImage::~SwapchainImage() = default;
......
...@@ -60,6 +60,8 @@ class OffscreenSurfaceVk : public SurfaceImpl ...@@ -60,6 +60,8 @@ class OffscreenSurfaceVk : public SurfaceImpl
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 *getColorAttachmentImage();
private: private:
struct AttachmentImage final : angle::NonCopyable struct AttachmentImage final : angle::NonCopyable
{ {
......
...@@ -11,10 +11,13 @@ ...@@ -11,10 +11,13 @@
#include "common/debug.h" #include "common/debug.h"
#include "image_util/generatemip.inl" #include "image_util/generatemip.inl"
#include "libANGLE/Config.h"
#include "libANGLE/Context.h" #include "libANGLE/Context.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/RendererVk.h" #include "libANGLE/renderer/vulkan/RendererVk.h"
#include "libANGLE/renderer/vulkan/SurfaceVk.h"
#include "libANGLE/renderer/vulkan/vk_format_utils.h" #include "libANGLE/renderer/vulkan/vk_format_utils.h"
#include "third_party/trace_event/trace_event.h" #include "third_party/trace_event/trace_event.h"
...@@ -120,7 +123,7 @@ angle::Result TextureVk::generateMipmapLevelsWithCPU(ContextVk *contextVk, ...@@ -120,7 +123,7 @@ angle::Result TextureVk::generateMipmapLevelsWithCPU(ContextVk *contextVk,
// TextureVk implementation. // TextureVk implementation.
TextureVk::TextureVk(const gl::TextureState &state, RendererVk *renderer) TextureVk::TextureVk(const gl::TextureState &state, RendererVk *renderer)
: TextureImpl(state), mImage(nullptr) : TextureImpl(state), mOwnsImage(false), mImage(nullptr)
{} {}
TextureVk::~TextureVk() = default; TextureVk::~TextureVk() = default;
...@@ -130,11 +133,8 @@ void TextureVk::onDestroy(const gl::Context *context) ...@@ -130,11 +133,8 @@ void TextureVk::onDestroy(const gl::Context *context)
ContextVk *contextVk = vk::GetImpl(context); ContextVk *contextVk = vk::GetImpl(context);
RendererVk *renderer = contextVk->getRenderer(); RendererVk *renderer = contextVk->getRenderer();
releaseImage(renderer); releaseAndDeleteImage(context, renderer);
releaseStagingBuffer(renderer);
renderer->releaseObject(renderer->getCurrentQueueSerial(), &mSampler); renderer->releaseObject(renderer->getCurrentQueueSerial(), &mSampler);
SafeDelete(mImage);
} }
angle::Result TextureVk::setImage(const gl::Context *context, angle::Result TextureVk::setImage(const gl::Context *context,
...@@ -560,22 +560,40 @@ angle::Result TextureVk::setImageExternal(const gl::Context *context, ...@@ -560,22 +560,40 @@ angle::Result TextureVk::setImageExternal(const gl::Context *context,
return angle::Result::Stop; return angle::Result::Stop;
} }
void TextureVk::releaseAndDeleteImage(const gl::Context *context, RendererVk *renderer)
{
if (mImage)
{
releaseImage(renderer);
releaseStagingBuffer(renderer);
SafeDelete(mImage);
}
}
angle::Result TextureVk::ensureImageAllocated(RendererVk *renderer) angle::Result TextureVk::ensureImageAllocated(RendererVk *renderer)
{ {
if (mImage == nullptr) if (mImage == nullptr)
{ {
mImage = new vk::ImageHelper(); setImageHelper(renderer, new vk::ImageHelper(), true);
mImage->initStagingBuffer(renderer);
mRenderTarget.init(mImage, &mDrawBaseLevelImageView, 0, this);
// Force re-creation of cube map render targets next time they are needed
mCubeMapRenderTargets.clear();
} }
return angle::Result::Continue; return angle::Result::Continue;
} }
void TextureVk::setImageHelper(RendererVk *renderer, vk::ImageHelper *imageHelper, bool selfOwned)
{
ASSERT(mImage == nullptr);
mOwnsImage = selfOwned;
mImage = imageHelper;
mImage->initStagingBuffer(renderer);
mRenderTarget.init(mImage, &mDrawBaseLevelImageView, 0, this);
// Force re-creation of cube map render targets next time they are needed
mCubeMapRenderTargets.clear();
}
angle::Result TextureVk::redefineImage(const gl::Context *context, angle::Result TextureVk::redefineImage(const gl::Context *context,
const gl::ImageIndex &index, const gl::ImageIndex &index,
const gl::InternalFormat &internalFormat, const gl::InternalFormat &internalFormat,
...@@ -584,6 +602,10 @@ angle::Result TextureVk::redefineImage(const gl::Context *context, ...@@ -584,6 +602,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
// redefine an external image.
ASSERT(mImage == nullptr || mOwnsImage);
if (!size.empty()) if (!size.empty())
{ {
ANGLE_TRY(ensureImageAllocated(renderer)); ANGLE_TRY(ensureImageAllocated(renderer));
...@@ -746,14 +768,27 @@ angle::Result TextureVk::setBaseLevel(const gl::Context *context, GLuint baseLev ...@@ -746,14 +768,27 @@ angle::Result TextureVk::setBaseLevel(const gl::Context *context, GLuint baseLev
angle::Result TextureVk::bindTexImage(const gl::Context *context, egl::Surface *surface) angle::Result TextureVk::bindTexImage(const gl::Context *context, egl::Surface *surface)
{ {
ANGLE_VK_UNREACHABLE(vk::GetImpl(context)); ContextVk *contextVk = vk::GetImpl(context);
return angle::Result::Stop; RendererVk *renderer = contextVk->getRenderer();
releaseAndDeleteImage(context, renderer);
// eglBindTexImage can only be called with pbuffer (offscreen) surfaces
OffscreenSurfaceVk *offscreenSurface = GetImplAs<OffscreenSurfaceVk>(surface);
setImageHelper(renderer, offscreenSurface->getColorAttachmentImage(), false);
const vk::Format &format = renderer->getFormat(surface->getConfig()->renderTargetFormat);
return initImageViews(contextVk, format, 1);
} }
angle::Result TextureVk::releaseTexImage(const gl::Context *context) angle::Result TextureVk::releaseTexImage(const gl::Context *context)
{ {
ANGLE_VK_UNREACHABLE(vk::GetImpl(context)); ContextVk *contextVk = vk::GetImpl(context);
return angle::Result::Stop; RendererVk *renderer = contextVk->getRenderer();
releaseImage(renderer);
return angle::Result::Continue;
} }
angle::Result TextureVk::getAttachmentRenderTarget(const gl::Context *context, angle::Result TextureVk::getAttachmentRenderTarget(const gl::Context *context,
...@@ -965,6 +1000,20 @@ angle::Result TextureVk::initImage(ContextVk *contextVk, ...@@ -965,6 +1000,20 @@ angle::Result TextureVk::initImage(ContextVk *contextVk,
ANGLE_TRY(mImage->initMemory(contextVk, renderer->getMemoryProperties(), flags)); ANGLE_TRY(mImage->initMemory(contextVk, renderer->getMemoryProperties(), flags));
ANGLE_TRY(initImageViews(contextVk, format, levelCount));
// TODO(jmadill): Fold this into the RenderPass load/store ops. http://anglebug.com/2361
VkClearColorValue black = {{0, 0, 0, 1.0f}};
mImage->clearColor(black, 0, levelCount, commandBuffer);
return angle::Result::Continue;
}
angle::Result TextureVk::initImageViews(ContextVk *contextVk,
const vk::Format &format,
uint32_t levelCount)
{
ASSERT(mImage != nullptr);
gl::SwizzleState mappedSwizzle; gl::SwizzleState mappedSwizzle;
MapSwizzleState(format, mState.getSwizzleState(), &mappedSwizzle); MapSwizzleState(format, mState.getSwizzleState(), &mappedSwizzle);
...@@ -975,9 +1024,6 @@ angle::Result TextureVk::initImage(ContextVk *contextVk, ...@@ -975,9 +1024,6 @@ angle::Result TextureVk::initImage(ContextVk *contextVk,
ANGLE_TRY(mImage->initImageView(contextVk, mState.getType(), VK_IMAGE_ASPECT_COLOR_BIT, ANGLE_TRY(mImage->initImageView(contextVk, mState.getType(), VK_IMAGE_ASPECT_COLOR_BIT,
gl::SwizzleState(), &mDrawBaseLevelImageView, 1)); gl::SwizzleState(), &mDrawBaseLevelImageView, 1));
// TODO(jmadill): Fold this into the RenderPass load/store ops. http://anglebug.com/2361
VkClearColorValue black = {{0, 0, 0, 1.0f}};
mImage->clearColor(black, 0, levelCount, commandBuffer);
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -985,7 +1031,14 @@ void TextureVk::releaseImage(RendererVk *renderer) ...@@ -985,7 +1031,14 @@ void TextureVk::releaseImage(RendererVk *renderer)
{ {
if (mImage) if (mImage)
{ {
mImage->releaseImage(renderer); if (mOwnsImage)
{
mImage->releaseImage(renderer);
}
else
{
mImage = nullptr;
}
} }
Serial currentSerial = renderer->getCurrentQueueSerial(); Serial currentSerial = renderer->getCurrentQueueSerial();
......
...@@ -149,7 +149,9 @@ class TextureVk : public TextureImpl ...@@ -149,7 +149,9 @@ class TextureVk : public TextureImpl
angle::Result ensureImageInitialized(ContextVk *contextVk); angle::Result ensureImageInitialized(ContextVk *contextVk);
private: private:
void releaseAndDeleteImage(const gl::Context *context, RendererVk *renderer);
angle::Result ensureImageAllocated(RendererVk *renderer); angle::Result ensureImageAllocated(RendererVk *renderer);
void setImageHelper(RendererVk *renderer, vk::ImageHelper *imageHelper, bool selfOwned);
angle::Result redefineImage(const gl::Context *context, angle::Result redefineImage(const gl::Context *context,
const gl::ImageIndex &index, const gl::ImageIndex &index,
...@@ -213,6 +215,9 @@ class TextureVk : public TextureImpl ...@@ -213,6 +215,9 @@ class TextureVk : public TextureImpl
void releaseImage(RendererVk *renderer); void releaseImage(RendererVk *renderer);
void releaseStagingBuffer(RendererVk *renderer); void releaseStagingBuffer(RendererVk *renderer);
uint32_t getLevelCount() const; uint32_t getLevelCount() const;
angle::Result initImageViews(ContextVk *contextVk,
const vk::Format &format,
uint32_t levelCount);
angle::Result initCubeMapRenderTargets(ContextVk *contextVk); angle::Result initCubeMapRenderTargets(ContextVk *contextVk);
angle::Result ensureImageInitializedImpl(ContextVk *contextVk, angle::Result ensureImageInitializedImpl(ContextVk *contextVk,
...@@ -220,6 +225,7 @@ class TextureVk : public TextureImpl ...@@ -220,6 +225,7 @@ class TextureVk : public TextureImpl
uint32_t levelCount, uint32_t levelCount,
const vk::Format &format); const vk::Format &format);
bool mOwnsImage;
vk::ImageHelper *mImage; vk::ImageHelper *mImage;
vk::ImageView mDrawBaseLevelImageView; vk::ImageView mDrawBaseLevelImageView;
vk::ImageView mReadBaseLevelImageView; vk::ImageView mReadBaseLevelImageView;
......
...@@ -235,8 +235,8 @@ egl::Config GenerateDefaultConfig(const RendererVk *renderer, ...@@ -235,8 +235,8 @@ egl::Config GenerateDefaultConfig(const RendererVk *renderer,
config.blueSize = colorFormat.blueBits; config.blueSize = colorFormat.blueBits;
config.alphaSize = colorFormat.alphaBits; config.alphaSize = colorFormat.alphaBits;
config.alphaMaskSize = 0; config.alphaMaskSize = 0;
config.bindToTextureRGB = EGL_FALSE; config.bindToTextureRGB = colorFormat.format == GL_RGB;
config.bindToTextureRGBA = EGL_FALSE; config.bindToTextureRGBA = colorFormat.format == GL_RGBA || colorFormat.format == GL_BGRA_EXT;
config.colorBufferType = EGL_RGB_BUFFER; config.colorBufferType = EGL_RGB_BUFFER;
config.configCaveat = EGL_NONE; config.configCaveat = EGL_NONE;
config.conformant = 0; config.conformant = 0;
......
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