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 @@ ...@@ -18,7 +18,11 @@
namespace rx namespace rx
{ {
RenderTargetVk::RenderTargetVk() RenderTargetVk::RenderTargetVk()
: mImage(nullptr), mImageView(nullptr), mLevelIndex(0), mLayerIndex(0) : mImage(nullptr),
mImageView(nullptr),
mCubeImageFetchView(nullptr),
mLevelIndex(0),
mLayerIndex(0)
{} {}
RenderTargetVk::~RenderTargetVk() {} RenderTargetVk::~RenderTargetVk() {}
...@@ -26,17 +30,20 @@ RenderTargetVk::~RenderTargetVk() {} ...@@ -26,17 +30,20 @@ RenderTargetVk::~RenderTargetVk() {}
RenderTargetVk::RenderTargetVk(RenderTargetVk &&other) RenderTargetVk::RenderTargetVk(RenderTargetVk &&other)
: mImage(other.mImage), : mImage(other.mImage),
mImageView(other.mImageView), mImageView(other.mImageView),
mCubeImageFetchView(other.mCubeImageFetchView),
mLevelIndex(other.mLevelIndex), mLevelIndex(other.mLevelIndex),
mLayerIndex(other.mLayerIndex) mLayerIndex(other.mLayerIndex)
{} {}
void RenderTargetVk::init(vk::ImageHelper *image, void RenderTargetVk::init(vk::ImageHelper *image,
vk::ImageView *imageView, vk::ImageView *imageView,
vk::ImageView *cubeImageFetchView,
size_t levelIndex, size_t levelIndex,
size_t layerIndex) size_t layerIndex)
{ {
mImage = image; mImage = image;
mImageView = imageView; mImageView = imageView;
mCubeImageFetchView = cubeImageFetchView;
mLevelIndex = levelIndex; mLevelIndex = levelIndex;
mLayerIndex = layerIndex; mLayerIndex = layerIndex;
} }
...@@ -45,6 +52,7 @@ void RenderTargetVk::reset() ...@@ -45,6 +52,7 @@ void RenderTargetVk::reset()
{ {
mImage = nullptr; mImage = nullptr;
mImageView = nullptr; mImageView = nullptr;
mCubeImageFetchView = nullptr;
mLevelIndex = 0; mLevelIndex = 0;
mLayerIndex = 0; mLayerIndex = 0;
} }
...@@ -108,6 +116,12 @@ vk::ImageView *RenderTargetVk::getReadImageView() const ...@@ -108,6 +116,12 @@ vk::ImageView *RenderTargetVk::getReadImageView() const
return getDrawImageView(); return getDrawImageView();
} }
vk::ImageView *RenderTargetVk::getFetchImageView() const
{
return mCubeImageFetchView && mCubeImageFetchView->valid() ? mCubeImageFetchView
: getReadImageView();
}
const vk::Format &RenderTargetVk::getImageFormat() const const vk::Format &RenderTargetVk::getImageFormat() const
{ {
ASSERT(mImage && mImage->valid()); ASSERT(mImage && mImage->valid());
...@@ -125,6 +139,7 @@ void RenderTargetVk::updateSwapchainImage(vk::ImageHelper *image, vk::ImageView ...@@ -125,6 +139,7 @@ void RenderTargetVk::updateSwapchainImage(vk::ImageHelper *image, vk::ImageView
ASSERT(image && image->valid() && imageView && imageView->valid()); ASSERT(image && image->valid() && imageView && imageView->valid());
mImage = image; mImage = image;
mImageView = imageView; mImageView = imageView;
mCubeImageFetchView = nullptr;
} }
vk::ImageHelper *RenderTargetVk::getImageForRead(vk::CommandGraphResource *readingResource, vk::ImageHelper *RenderTargetVk::getImageForRead(vk::CommandGraphResource *readingResource,
......
...@@ -45,6 +45,7 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget ...@@ -45,6 +45,7 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget
void init(vk::ImageHelper *image, void init(vk::ImageHelper *image,
vk::ImageView *imageView, vk::ImageView *imageView,
vk::ImageView *cubeImageFetchView,
size_t levelIndex, size_t levelIndex,
size_t layerIndex); size_t layerIndex);
void reset(); void reset();
...@@ -68,6 +69,10 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget ...@@ -68,6 +69,10 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget
vk::ImageView *getDrawImageView() const; vk::ImageView *getDrawImageView() const;
vk::ImageView *getReadImageView() 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; const vk::Format &getImageFormat() const;
gl::Extents getExtents() const; gl::Extents getExtents() const;
...@@ -85,6 +90,8 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget ...@@ -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 // Note that the draw and read image views are the same, given the requirements of a render
// target. // target.
vk::ImageView *mImageView; 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 mLevelIndex;
size_t mLayerIndex; size_t mLayerIndex;
}; };
......
...@@ -87,7 +87,7 @@ angle::Result RenderbufferVk::setStorage(const gl::Context *context, ...@@ -87,7 +87,7 @@ angle::Result RenderbufferVk::setStorage(const gl::Context *context,
// Clear the renderbuffer if it has emulated channels. // Clear the renderbuffer if it has emulated channels.
mImage->clearIfEmulatedFormat(vk::GetImpl(context), gl::ImageIndex::Make2D(0), vkFormat); 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; return angle::Result::Continue;
...@@ -134,7 +134,19 @@ angle::Result RenderbufferVk::setStorageEGLImageTarget(const gl::Context *contex ...@@ -134,7 +134,19 @@ angle::Result RenderbufferVk::setStorageEGLImageTarget(const gl::Context *contex
gl::SwizzleState(), &mImageView, imageVk->getImageLevel(), gl::SwizzleState(), &mImageView, imageVk->getImageLevel(),
1, imageVk->getImageLayer(), 1)); 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; return angle::Result::Continue;
} }
...@@ -185,6 +197,7 @@ void RenderbufferVk::releaseImage(const gl::Context *context, RendererVk *render ...@@ -185,6 +197,7 @@ void RenderbufferVk::releaseImage(const gl::Context *context, RendererVk *render
} }
renderer->releaseObject(renderer->getCurrentQueueSerial(), &mImageView); renderer->releaseObject(renderer->getCurrentQueueSerial(), &mImageView);
renderer->releaseObject(renderer->getCurrentQueueSerial(), &mCubeImageFetchView);
} }
} // namespace rx } // namespace rx
...@@ -54,6 +54,7 @@ class RenderbufferVk : public RenderbufferImpl ...@@ -54,6 +54,7 @@ class RenderbufferVk : public RenderbufferImpl
bool mOwnsImage; bool mOwnsImage;
vk::ImageHelper *mImage; vk::ImageHelper *mImage;
vk::ImageView mImageView; vk::ImageView mImageView;
vk::ImageView mCubeImageFetchView;
RenderTargetVk mRenderTarget; RenderTargetVk mRenderTarget;
}; };
......
...@@ -163,9 +163,9 @@ OffscreenSurfaceVk::OffscreenSurfaceVk(const egl::SurfaceState &surfaceState, ...@@ -163,9 +163,9 @@ OffscreenSurfaceVk::OffscreenSurfaceVk(const egl::SurfaceState &surfaceState,
EGLint height) EGLint height)
: SurfaceVk(surfaceState), mWidth(width), mHeight(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, mDepthStencilRenderTarget.init(&mDepthStencilAttachment.image,
&mDepthStencilAttachment.imageView, 0, 0); &mDepthStencilAttachment.imageView, nullptr, 0, 0);
} }
OffscreenSurfaceVk::~OffscreenSurfaceVk() {} OffscreenSurfaceVk::~OffscreenSurfaceVk() {}
...@@ -374,8 +374,8 @@ WindowSurfaceVk::WindowSurfaceVk(const egl::SurfaceState &surfaceState, ...@@ -374,8 +374,8 @@ WindowSurfaceVk::WindowSurfaceVk(const egl::SurfaceState &surfaceState,
{ {
// Initialize the color render target with the multisampled targets. If not multisampled, the // 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. // render target will be updated to refer to a swapchain image on every acquire.
mColorRenderTarget.init(&mColorImageMS, &mColorImageViewMS, 0, 0); mColorRenderTarget.init(&mColorImageMS, &mColorImageViewMS, nullptr, 0, 0);
mDepthStencilRenderTarget.init(&mDepthStencilImage, &mDepthStencilImageView, 0, 0); mDepthStencilRenderTarget.init(&mDepthStencilImage, &mDepthStencilImageView, nullptr, 0, 0);
} }
WindowSurfaceVk::~WindowSurfaceVk() WindowSurfaceVk::~WindowSurfaceVk()
......
...@@ -153,6 +153,8 @@ class TextureVk : public TextureImpl ...@@ -153,6 +153,8 @@ class TextureVk : public TextureImpl
void releaseOwnershipOfImage(const gl::Context *context); void releaseOwnershipOfImage(const gl::Context *context);
const vk::ImageView &getReadImageView() const; 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, angle::Result getLayerLevelDrawImageView(vk::Context *context,
size_t layer, size_t layer,
size_t level, size_t level,
...@@ -249,7 +251,6 @@ class TextureVk : public TextureImpl ...@@ -249,7 +251,6 @@ class TextureVk : public TextureImpl
const gl::Offset &destOffset, const gl::Offset &destOffset,
const vk::Format &destFormat, const vk::Format &destFormat,
size_t sourceLevel, size_t sourceLevel,
size_t sourceLayer,
const gl::Rectangle &sourceArea, const gl::Rectangle &sourceArea,
bool isSrcFlipY, bool isSrcFlipY,
bool unpackFlipY, bool unpackFlipY,
...@@ -293,10 +294,13 @@ class TextureVk : public TextureImpl ...@@ -293,10 +294,13 @@ class TextureVk : public TextureImpl
vk::ImageView mDrawBaseLevelImageView; vk::ImageView mDrawBaseLevelImageView;
vk::ImageView mReadBaseLevelImageView; vk::ImageView mReadBaseLevelImageView;
vk::ImageView mReadMipmapImageView; vk::ImageView mReadMipmapImageView;
vk::ImageView mFetchBaseLevelImageView;
vk::ImageView mFetchMipmapImageView;
std::vector<std::vector<vk::ImageView>> mLayerLevelDrawImageViews; std::vector<std::vector<vk::ImageView>> mLayerLevelDrawImageViews;
vk::Sampler mSampler; vk::Sampler mSampler;
RenderTargetVk mRenderTarget; RenderTargetVk mRenderTarget;
std::vector<vk::ImageView> mLayerFetchImageView;
std::vector<RenderTargetVk> mCubeMapRenderTargets; 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