Commit d192e933 by Cody Northrop Committed by Commit Bot

Vulkan: Support binding texture levels as a rendertarget

This CL refactors how TextureVk handles rendertargets. It removes the single rendertarget that previously supported 2D, and expands the layer/level list of rendertargets to handle all cases. Bug: angleproject:3184 Bug: angleproject:3996 Test: Texture2DTestES3.FramebufferTextureChangingBaselevel/ES3_Vulkan Test: FramebufferRenderMipmapTest.RenderToMipmap/ES2_Vulkan Test: FramebufferRenderMipmapTest.RenderToMipmap/ES3_Vulkan Test: ComputeShaderTest.ImageStoreMipmapSlice/ES3_1_Vulkan Change-Id: I466d0389cc6744994f88c40cc388fca694b53a99 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1854895Reviewed-by: 's avatarIan Elliott <ianelliott@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Cody Northrop <cnorthrop@google.com>
parent bbf0ce28
...@@ -79,6 +79,11 @@ void GetRenderTargetLayerCountAndIndex(vk::ImageHelper *image, ...@@ -79,6 +79,11 @@ void GetRenderTargetLayerCountAndIndex(vk::ImageHelper *image,
{ {
switch (index.getType()) switch (index.getType())
{ {
case gl::TextureType::_2D:
*layerIndex = 0;
*layerCount = 1;
return;
case gl::TextureType::CubeMap: case gl::TextureType::CubeMap:
*layerIndex = index.cubeMapFaceIndex(); *layerIndex = index.cubeMapFaceIndex();
*layerCount = gl::kCubeFaceCount; *layerCount = gl::kCubeFaceCount;
...@@ -894,10 +899,12 @@ void TextureVk::setImageHelper(ContextVk *contextVk, ...@@ -894,10 +899,12 @@ void TextureVk::setImageHelper(ContextVk *contextVk,
mImage->initStagingBuffer(contextVk->getRenderer(), format, vk::kStagingBufferFlags, mImage->initStagingBuffer(contextVk->getRenderer(), format, vk::kStagingBufferFlags,
mStagingBufferInitialSize); mStagingBufferInitialSize);
mRenderTarget.init(mImage, &mDrawImageView, getNativeImageLevel(0), getNativeImageLayer(0)); // Force re-creation of render targets next time they are needed
for (vk::RenderTargetVector &renderTargetLevels : mRenderTargets)
// Force re-creation of layered render targets next time they are needed {
mLayerRenderTargets.clear(); renderTargetLevels.clear();
}
mRenderTargets.clear();
mSerial = contextVk->generateTextureSerial(); mSerial = contextVk->generateTextureSerial();
} }
...@@ -1251,31 +1258,18 @@ angle::Result TextureVk::getAttachmentRenderTarget(const gl::Context *context, ...@@ -1251,31 +1258,18 @@ angle::Result TextureVk::getAttachmentRenderTarget(const gl::Context *context,
GLsizei samples, GLsizei samples,
FramebufferAttachmentRenderTarget **rtOut) FramebufferAttachmentRenderTarget **rtOut)
{ {
// Non-zero mip level attachments are an ES 3.0 feature. ASSERT(imageIndex.getLevelIndex() >= 0);
ASSERT(imageIndex.getLevelIndex() == 0);
ContextVk *contextVk = vk::GetImpl(context); ContextVk *contextVk = vk::GetImpl(context);
ANGLE_TRY(ensureImageInitialized(contextVk)); ANGLE_TRY(ensureImageInitialized(contextVk));
GLuint layerIndex = 0, layerCount = 0; GLuint layerIndex = 0, layerCount = 0;
GetRenderTargetLayerCountAndIndex(mImage, imageIndex, &layerCount, &layerIndex);
switch (imageIndex.getType()) ANGLE_TRY(initRenderTargets(contextVk, layerCount, imageIndex.getLevelIndex()));
{
case gl::TextureType::_2D:
*rtOut = &mRenderTarget;
break;
case gl::TextureType::CubeMap:
case gl::TextureType::_2DArray:
case gl::TextureType::_3D:
// Special handling required for different types, grab the count and index
GetRenderTargetLayerCountAndIndex(mImage, imageIndex, &layerCount, &layerIndex);
ANGLE_TRY(initLayerRenderTargets(contextVk, layerCount)); ASSERT(imageIndex.getLevelIndex() < static_cast<int32_t>(mRenderTargets.size()));
*rtOut = &mLayerRenderTargets[layerIndex]; *rtOut = &mRenderTargets[imageIndex.getLevelIndex()][layerIndex];
break;
default:
UNREACHABLE();
}
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -1317,20 +1311,27 @@ angle::Result TextureVk::ensureImageInitializedImpl(ContextVk *contextVk, ...@@ -1317,20 +1311,27 @@ angle::Result TextureVk::ensureImageInitializedImpl(ContextVk *contextVk,
commandBuffer); commandBuffer);
} }
angle::Result TextureVk::initLayerRenderTargets(ContextVk *contextVk, GLuint layerCount) angle::Result TextureVk::initRenderTargets(ContextVk *contextVk,
GLuint layerCount,
GLuint levelIndex)
{ {
if (mRenderTargets.size() <= levelIndex)
{
mRenderTargets.resize(levelIndex + 1);
}
// Lazy init. Check if already initialized. // Lazy init. Check if already initialized.
if (!mLayerRenderTargets.empty()) if (!mRenderTargets[levelIndex].empty())
return angle::Result::Continue; return angle::Result::Continue;
mLayerRenderTargets.resize(layerCount); mRenderTargets[levelIndex].resize(layerCount);
for (uint32_t layerIndex = 0; layerIndex < layerCount; ++layerIndex) for (uint32_t layerIndex = 0; layerIndex < layerCount; ++layerIndex)
{ {
const vk::ImageView *drawView; const vk::ImageView *drawView;
ANGLE_TRY(getLayerLevelDrawImageView(contextVk, layerIndex, 0, &drawView)); ANGLE_TRY(getLayerLevelDrawImageView(contextVk, layerIndex, levelIndex, &drawView));
mLayerRenderTargets[layerIndex].init(mImage, drawView, getNativeImageLevel(0), mRenderTargets[levelIndex][layerIndex].init(
getNativeImageLayer(layerIndex)); mImage, drawView, getNativeImageLevel(levelIndex), getNativeImageLayer(layerIndex));
} }
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -1692,13 +1693,6 @@ angle::Result TextureVk::initImageViews(ContextVk *contextVk, ...@@ -1692,13 +1693,6 @@ angle::Result TextureVk::initImageViews(ContextVk *contextVk,
layerCount)); layerCount));
} }
if (!format.imageFormat().isBlock)
{
ANGLE_TRY(mImage->initLayerImageView(contextVk, mState.getType(), aspectFlags,
gl::SwizzleState(), &mDrawImageView, baseLevel, 1,
baseLayer, layerCount));
}
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -1718,7 +1712,13 @@ void TextureVk::releaseImage(ContextVk *contextVk) ...@@ -1718,7 +1712,13 @@ void TextureVk::releaseImage(ContextVk *contextVk)
releaseImageViews(contextVk); releaseImageViews(contextVk);
mLayerRenderTargets.clear(); for (vk::RenderTargetVector &renderTargetLevels : mRenderTargets)
{
// Clear the layers tracked for each level
renderTargetLevels.clear();
}
// Then clear the levels
mRenderTargets.clear();
onStagingBufferChange(); onStagingBufferChange();
} }
...@@ -1728,7 +1728,6 @@ void TextureVk::releaseImageViews(ContextVk *contextVk) ...@@ -1728,7 +1728,6 @@ void TextureVk::releaseImageViews(ContextVk *contextVk)
contextVk->addGarbage(&mReadImageView); contextVk->addGarbage(&mReadImageView);
contextVk->addGarbage(&mFetchImageView); contextVk->addGarbage(&mFetchImageView);
contextVk->addGarbage(&mStencilReadImageView); contextVk->addGarbage(&mStencilReadImageView);
contextVk->addGarbage(&mDrawImageView);
for (vk::ImageViewVector &layerViews : mLayerLevelDrawImageViews) for (vk::ImageViewVector &layerViews : mLayerLevelDrawImageViews)
{ {
......
...@@ -299,7 +299,7 @@ class TextureVk : public TextureImpl ...@@ -299,7 +299,7 @@ class TextureVk : public TextureImpl
const bool sized, const bool sized,
uint32_t levelCount, uint32_t levelCount,
uint32_t layerCount); uint32_t layerCount);
angle::Result initLayerRenderTargets(ContextVk *contextVk, GLuint layerCount); angle::Result initRenderTargets(ContextVk *contextVk, GLuint layerCount, GLuint levelIndex);
vk::ImageView *getLevelImageViewImpl(vk::ImageViewVector *imageViews, size_t level); vk::ImageView *getLevelImageViewImpl(vk::ImageViewVector *imageViews, size_t level);
vk::ImageView *getLayerLevelImageViewImpl(vk::LayerLevelImageViewVector *imageViews, vk::ImageView *getLayerLevelImageViewImpl(vk::LayerLevelImageViewVector *imageViews,
size_t layer, size_t layer,
...@@ -334,15 +334,16 @@ class TextureVk : public TextureImpl ...@@ -334,15 +334,16 @@ class TextureVk : public TextureImpl
vk::ImageView mStencilReadImageView; vk::ImageView mStencilReadImageView;
// Draw views. // Draw views.
vk::ImageView mDrawImageView;
vk::LayerLevelImageViewVector mLayerLevelDrawImageViews; vk::LayerLevelImageViewVector mLayerLevelDrawImageViews;
// Storage image views. // Storage image views.
vk::ImageViewVector mLevelStorageImageViews; vk::ImageViewVector mLevelStorageImageViews;
vk::Sampler mSampler; vk::Sampler mSampler;
RenderTargetVk mRenderTarget;
std::vector<RenderTargetVk> mLayerRenderTargets; // Render targets stored as vector of vectors
// Level is first dimension, layer is second
std::vector<vk::RenderTargetVector> mRenderTargets;
// The serial is used for cache indexing. // The serial is used for cache indexing.
Serial mSerial; Serial mSerial;
......
...@@ -124,6 +124,8 @@ void RendererVk::ensureCapsInitialized() const ...@@ -124,6 +124,8 @@ void RendererVk::ensureCapsInitialized() const
// Vulkan natively supports 32-bit indices, entry in kIndexTypeMap // Vulkan natively supports 32-bit indices, entry in kIndexTypeMap
mNativeExtensions.elementIndexUint = true; mNativeExtensions.elementIndexUint = true;
mNativeExtensions.fboRenderMipmap = true;
// https://vulkan.lunarg.com/doc/view/1.0.30.0/linux/vkspec.chunked/ch31s02.html // https://vulkan.lunarg.com/doc/view/1.0.30.0/linux/vkspec.chunked/ch31s02.html
mNativeCaps.maxElementIndex = std::numeric_limits<GLuint>::max() - 1; mNativeCaps.maxElementIndex = std::numeric_limits<GLuint>::max() - 1;
mNativeCaps.max3DTextureSize = limitsVk.maxImageDimension3D; mNativeCaps.max3DTextureSize = limitsVk.maxImageDimension3D;
......
...@@ -597,6 +597,8 @@ std::string GetMappedSamplerName(const std::string &originalName); ...@@ -597,6 +597,8 @@ std::string GetMappedSamplerName(const std::string &originalName);
using ImageViewVector = std::vector<ImageView>; using ImageViewVector = std::vector<ImageView>;
// A vector of vector of image views. Primary index is layer, secondary index is level. // A vector of vector of image views. Primary index is layer, secondary index is level.
using LayerLevelImageViewVector = std::vector<ImageViewVector>; using LayerLevelImageViewVector = std::vector<ImageViewVector>;
// A vector of rendertargets
using RenderTargetVector = std::vector<RenderTargetVk>;
} // namespace vk } // namespace vk
......
...@@ -3010,9 +3010,6 @@ TEST_P(ComputeShaderTest, ImageStoreMipmapSlice) ...@@ -3010,9 +3010,6 @@ TEST_P(ComputeShaderTest, ImageStoreMipmapSlice)
// TODO(xinghua.cao@intel.com): http://anglebug.com/3101 // TODO(xinghua.cao@intel.com): http://anglebug.com/3101
ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL()); ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
// Non-zero-level render target attachments are not yet supported. http://anglebug.com/3184
ANGLE_SKIP_TEST_IF(IsVulkan());
GLTexture texture[2]; GLTexture texture[2];
GLFramebuffer framebuffer; GLFramebuffer framebuffer;
constexpr char kCS[] = R"(#version 310 es constexpr char kCS[] = R"(#version 310 es
......
...@@ -163,4 +163,5 @@ ANGLE_INSTANTIATE_TEST(FramebufferRenderMipmapTest, ...@@ -163,4 +163,5 @@ ANGLE_INSTANTIATE_TEST(FramebufferRenderMipmapTest,
ES3_OPENGL(), ES3_OPENGL(),
ES2_OPENGLES(), ES2_OPENGLES(),
ES3_OPENGLES(), ES3_OPENGLES(),
ES2_VULKAN()); ES2_VULKAN(),
ES3_VULKAN());
...@@ -2017,8 +2017,8 @@ TEST_P(Texture2DTestES3, FramebufferTextureChangingBaselevel) ...@@ -2017,8 +2017,8 @@ TEST_P(Texture2DTestES3, FramebufferTextureChangingBaselevel)
// TODO(geofflang): Investigate on D3D11. http://anglebug.com/2291 // TODO(geofflang): Investigate on D3D11. http://anglebug.com/2291
ANGLE_SKIP_TEST_IF(IsD3D11()); ANGLE_SKIP_TEST_IF(IsD3D11());
// TODO(cnorthrop): Framebuffer level support. http://anglebug.com/3184 // TODO(cnorthrop): Failing on Vulkan/Windows/AMD. http://anglebug.com/3996
ANGLE_SKIP_TEST_IF(IsVulkan()); ANGLE_SKIP_TEST_IF(IsVulkan() && IsWindows() && IsAMD());
setUpProgram(); setUpProgram();
......
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