Commit ce9be8c7 by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Have a cubemap as 2D-array view handy

Previously, only texture copies used a shader that performed texelFetch(). To support cubemaps, a hack was used to temporarily create a 2D array view. With upcoming support for multisample resolve, more shaders will be using texelFetch() all requiring this workaround. This change instead makes sure that a separate view is created for cubemaps for the purpose of being used with these shaders. As a result, we have three logical views on textures and render targets: - Draw: a view that can be used as a color/depth/stencil attachment - Read: a view that can be used to sample from - Fetch: a view that can be used to fetch from The fetch view is generally the same as the read view, except for cube maps. Bug: angleproject:3200 Change-Id: I21547f728c16f0aa8f0fcae152c400b5cc1565da Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1628585 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 46fe0e4b
......@@ -18,7 +18,11 @@
namespace rx
{
RenderTargetVk::RenderTargetVk()
: mImage(nullptr), mImageView(nullptr), mLevelIndex(0), mLayerIndex(0)
: mImage(nullptr),
mImageView(nullptr),
mCubeImageFetchView(nullptr),
mLevelIndex(0),
mLayerIndex(0)
{}
RenderTargetVk::~RenderTargetVk() {}
......@@ -26,17 +30,20 @@ RenderTargetVk::~RenderTargetVk() {}
RenderTargetVk::RenderTargetVk(RenderTargetVk &&other)
: mImage(other.mImage),
mImageView(other.mImageView),
mCubeImageFetchView(other.mCubeImageFetchView),
mLevelIndex(other.mLevelIndex),
mLayerIndex(other.mLayerIndex)
{}
void RenderTargetVk::init(vk::ImageHelper *image,
vk::ImageView *imageView,
vk::ImageView *cubeImageFetchView,
size_t levelIndex,
size_t layerIndex)
{
mImage = image;
mImageView = imageView;
mCubeImageFetchView = cubeImageFetchView;
mLevelIndex = levelIndex;
mLayerIndex = layerIndex;
}
......@@ -45,6 +52,7 @@ void RenderTargetVk::reset()
{
mImage = nullptr;
mImageView = nullptr;
mCubeImageFetchView = nullptr;
mLevelIndex = 0;
mLayerIndex = 0;
}
......@@ -108,6 +116,12 @@ vk::ImageView *RenderTargetVk::getReadImageView() const
return getDrawImageView();
}
vk::ImageView *RenderTargetVk::getFetchImageView() const
{
return mCubeImageFetchView && mCubeImageFetchView->valid() ? mCubeImageFetchView
: getReadImageView();
}
const vk::Format &RenderTargetVk::getImageFormat() const
{
ASSERT(mImage && mImage->valid());
......@@ -125,6 +139,7 @@ void RenderTargetVk::updateSwapchainImage(vk::ImageHelper *image, vk::ImageView
ASSERT(image && image->valid() && imageView && imageView->valid());
mImage = image;
mImageView = imageView;
mCubeImageFetchView = nullptr;
}
vk::ImageHelper *RenderTargetVk::getImageForRead(vk::CommandGraphResource *readingResource,
......
......@@ -45,6 +45,7 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget
void init(vk::ImageHelper *image,
vk::ImageView *imageView,
vk::ImageView *cubeImageFetchView,
size_t levelIndex,
size_t layerIndex);
void reset();
......@@ -68,6 +69,10 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget
vk::ImageView *getDrawImageView() const;
vk::ImageView *getReadImageView() const;
// GLSL's texelFetch() needs a 2D array view to read from cube maps. This function returns the
// same view as `getReadImageView()`, except for cubemaps, in which case it returns a 2D array
// view of it.
vk::ImageView *getFetchImageView() const;
const vk::Format &getImageFormat() const;
gl::Extents getExtents() const;
......@@ -85,6 +90,8 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget
// Note that the draw and read image views are the same, given the requirements of a render
// target.
vk::ImageView *mImageView;
// For cubemaps, a 2D-array view is also created to be used with shaders that use texelFetch().
vk::ImageView *mCubeImageFetchView;
size_t mLevelIndex;
size_t mLayerIndex;
};
......
......@@ -87,7 +87,7 @@ angle::Result RenderbufferVk::setStorage(const gl::Context *context,
// Clear the renderbuffer if it has emulated channels.
mImage->clearIfEmulatedFormat(vk::GetImpl(context), gl::ImageIndex::Make2D(0), vkFormat);
mRenderTarget.init(mImage, &mImageView, 0, 0);
mRenderTarget.init(mImage, &mImageView, nullptr, 0, 0);
}
return angle::Result::Continue;
......@@ -134,7 +134,19 @@ angle::Result RenderbufferVk::setStorageEGLImageTarget(const gl::Context *contex
gl::SwizzleState(), &mImageView, imageVk->getImageLevel(),
1, imageVk->getImageLayer(), 1));
mRenderTarget.init(mImage, &mImageView, imageVk->getImageLevel(), imageVk->getImageLayer());
if (imageVk->getImageTextureType() == gl::TextureType::CubeMap)
{
gl::TextureType arrayType = imageVk->getImage()->getSamples() > 1
? gl::TextureType::_2DMultisampleArray
: gl::TextureType::_2DArray;
ANGLE_TRY(mImage->initLayerImageView(contextVk, arrayType, aspect, gl::SwizzleState(),
&mCubeImageFetchView, imageVk->getImageLevel(), 1,
imageVk->getImageLayer(), 1));
}
mRenderTarget.init(mImage, &mImageView,
mCubeImageFetchView.valid() ? &mCubeImageFetchView : nullptr,
imageVk->getImageLevel(), imageVk->getImageLayer());
return angle::Result::Continue;
}
......@@ -185,6 +197,7 @@ void RenderbufferVk::releaseImage(const gl::Context *context, RendererVk *render
}
renderer->releaseObject(renderer->getCurrentQueueSerial(), &mImageView);
renderer->releaseObject(renderer->getCurrentQueueSerial(), &mCubeImageFetchView);
}
} // namespace rx
......@@ -54,6 +54,7 @@ class RenderbufferVk : public RenderbufferImpl
bool mOwnsImage;
vk::ImageHelper *mImage;
vk::ImageView mImageView;
vk::ImageView mCubeImageFetchView;
RenderTargetVk mRenderTarget;
};
......
......@@ -163,9 +163,9 @@ OffscreenSurfaceVk::OffscreenSurfaceVk(const egl::SurfaceState &surfaceState,
EGLint height)
: SurfaceVk(surfaceState), mWidth(width), mHeight(height)
{
mColorRenderTarget.init(&mColorAttachment.image, &mColorAttachment.imageView, 0, 0);
mColorRenderTarget.init(&mColorAttachment.image, &mColorAttachment.imageView, nullptr, 0, 0);
mDepthStencilRenderTarget.init(&mDepthStencilAttachment.image,
&mDepthStencilAttachment.imageView, 0, 0);
&mDepthStencilAttachment.imageView, nullptr, 0, 0);
}
OffscreenSurfaceVk::~OffscreenSurfaceVk() {}
......@@ -374,8 +374,8 @@ WindowSurfaceVk::WindowSurfaceVk(const egl::SurfaceState &surfaceState,
{
// Initialize the color render target with the multisampled targets. If not multisampled, the
// render target will be updated to refer to a swapchain image on every acquire.
mColorRenderTarget.init(&mColorImageMS, &mColorImageViewMS, 0, 0);
mDepthStencilRenderTarget.init(&mDepthStencilImage, &mDepthStencilImageView, 0, 0);
mColorRenderTarget.init(&mColorImageMS, &mColorImageViewMS, nullptr, 0, 0);
mDepthStencilRenderTarget.init(&mDepthStencilImage, &mDepthStencilImageView, nullptr, 0, 0);
}
WindowSurfaceVk::~WindowSurfaceVk()
......
......@@ -153,6 +153,8 @@ class TextureVk : public TextureImpl
void releaseOwnershipOfImage(const gl::Context *context);
const vk::ImageView &getReadImageView() const;
// A special view for cube maps as a 2D array, used with shaders that do texelFetch().
const vk::ImageView &getFetchImageView() const;
angle::Result getLayerLevelDrawImageView(vk::Context *context,
size_t layer,
size_t level,
......@@ -249,7 +251,6 @@ class TextureVk : public TextureImpl
const gl::Offset &destOffset,
const vk::Format &destFormat,
size_t sourceLevel,
size_t sourceLayer,
const gl::Rectangle &sourceArea,
bool isSrcFlipY,
bool unpackFlipY,
......@@ -293,10 +294,13 @@ class TextureVk : public TextureImpl
vk::ImageView mDrawBaseLevelImageView;
vk::ImageView mReadBaseLevelImageView;
vk::ImageView mReadMipmapImageView;
vk::ImageView mFetchBaseLevelImageView;
vk::ImageView mFetchMipmapImageView;
std::vector<std::vector<vk::ImageView>> mLayerLevelDrawImageViews;
vk::Sampler mSampler;
RenderTargetVk mRenderTarget;
std::vector<vk::ImageView> mLayerFetchImageView;
std::vector<RenderTargetVk> mCubeMapRenderTargets;
};
......
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