Commit 71bb0267 by Jamie Madill Committed by Commit Bot

Vulkan: Implement cube map render targets.

Each TextureVk now stores vectors of RenderTargetVks and ImageViews associated with the image faces. They are initialized lazily when the RenderTarget is queried in getAttachmentRenderTarget. There's still one missing edge case for handling clear with the Framebuffer when using cube maps. Also one additional test failure on Android. Bug: angleproject:2470 Change-Id: Ib959a3434a992cef010a11940cf2ee49e118ac17 Reviewed-on: https://chromium-review.googlesource.com/1220727Reviewed-by: 's avatarFrank Henigman <fjhenigman@chromium.org> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 0226041b
...@@ -26,6 +26,11 @@ RenderTargetVk::~RenderTargetVk() ...@@ -26,6 +26,11 @@ RenderTargetVk::~RenderTargetVk()
{ {
} }
RenderTargetVk::RenderTargetVk(RenderTargetVk &&other)
: mImage(other.mImage), mImageView(other.mImageView), mResource(other.mResource)
{
}
void RenderTargetVk::onColorDraw(vk::CommandGraphResource *framebufferVk, void RenderTargetVk::onColorDraw(vk::CommandGraphResource *framebufferVk,
vk::CommandBuffer *commandBuffer, vk::CommandBuffer *commandBuffer,
vk::RenderPassDesc *renderPassDesc) vk::RenderPassDesc *renderPassDesc)
......
...@@ -38,6 +38,9 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget ...@@ -38,6 +38,9 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget
vk::CommandGraphResource *resource); vk::CommandGraphResource *resource);
~RenderTargetVk(); ~RenderTargetVk();
// Used in std::vector initialization.
RenderTargetVk(RenderTargetVk &&other);
// Note: RenderTargets should be called in order, with the depth/stencil onRender last. // Note: RenderTargets should be called in order, with the depth/stencil onRender last.
void onColorDraw(vk::CommandGraphResource *framebufferVk, void onColorDraw(vk::CommandGraphResource *framebufferVk,
vk::CommandBuffer *commandBuffer, vk::CommandBuffer *commandBuffer,
......
...@@ -1025,16 +1025,25 @@ gl::Error TextureVk::getAttachmentRenderTarget(const gl::Context *context, ...@@ -1025,16 +1025,25 @@ gl::Error TextureVk::getAttachmentRenderTarget(const gl::Context *context,
const gl::ImageIndex &imageIndex, const gl::ImageIndex &imageIndex,
FramebufferAttachmentRenderTarget **rtOut) FramebufferAttachmentRenderTarget **rtOut)
{ {
// TODO(jmadill): Handle cube textures. http://anglebug.com/2470
ASSERT(imageIndex.getType() == gl::TextureType::_2D);
// Non-zero mip level attachments are an ES 3.0 feature. // Non-zero mip level attachments are an ES 3.0 feature.
ASSERT(imageIndex.getLevelIndex() == 0 && !imageIndex.hasLayer()); ASSERT(imageIndex.getLevelIndex() == 0);
ContextVk *contextVk = vk::GetImpl(context); ContextVk *contextVk = vk::GetImpl(context);
ANGLE_TRY(ensureImageInitialized(contextVk)); ANGLE_TRY(ensureImageInitialized(contextVk));
*rtOut = &mRenderTarget; switch (imageIndex.getType())
{
case gl::TextureType::_2D:
*rtOut = &mRenderTarget;
break;
case gl::TextureType::CubeMap:
ANGLE_TRY(initCubeMapRenderTargets(contextVk));
*rtOut = &mCubeMapRenderTargets[imageIndex.cubeMapFaceIndex()];
break;
default:
UNREACHABLE();
}
return gl::NoError(); return gl::NoError();
} }
...@@ -1060,7 +1069,25 @@ angle::Result TextureVk::ensureImageInitialized(ContextVk *contextVk) ...@@ -1060,7 +1069,25 @@ angle::Result TextureVk::ensureImageInitialized(ContextVk *contextVk)
ANGLE_TRY(initImage(contextVk, format, baseLevelExtents, levelCount, commandBuffer)); ANGLE_TRY(initImage(contextVk, format, baseLevelExtents, levelCount, commandBuffer));
} }
ANGLE_TRY(mPixelBuffer.flushUpdatesToImage(contextVk, levelCount, &mImage, commandBuffer)); return mPixelBuffer.flushUpdatesToImage(contextVk, levelCount, &mImage, commandBuffer);
}
angle::Result TextureVk::initCubeMapRenderTargets(ContextVk *contextVk)
{
// Lazy init. Check if already initialized.
if (!mCubeMapFaceImageViews.empty())
return angle::Result::Continue();
mCubeMapFaceImageViews.resize(gl::kCubeFaceCount);
for (size_t cubeMapFaceIndex = 0; cubeMapFaceIndex < gl::kCubeFaceCount; ++cubeMapFaceIndex)
{
vk::ImageView &imageView = mCubeMapFaceImageViews[cubeMapFaceIndex];
ANGLE_TRY(mImage.initLayerImageView(contextVk, gl::TextureType::CubeMap,
VK_IMAGE_ASPECT_COLOR_BIT, gl::SwizzleState(),
&imageView, 1, cubeMapFaceIndex, 1));
mCubeMapRenderTargets.emplace_back(&mImage, &imageView, this);
}
return angle::Result::Continue(); return angle::Result::Continue();
} }
...@@ -1101,8 +1128,7 @@ gl::Error TextureVk::syncState(const gl::Context *context, const gl::Texture::Di ...@@ -1101,8 +1128,7 @@ gl::Error TextureVk::syncState(const gl::Context *context, const gl::Texture::Di
samplerInfo.borderColor = VK_BORDER_COLOR_INT_TRANSPARENT_BLACK; samplerInfo.borderColor = VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
samplerInfo.unnormalizedCoordinates = VK_FALSE; samplerInfo.unnormalizedCoordinates = VK_FALSE;
ANGLE_TRY(mSampler.init(contextVk, samplerInfo)); return mSampler.init(contextVk, samplerInfo);
return gl::NoError();
} }
gl::Error TextureVk::setStorageMultisample(const gl::Context *context, gl::Error TextureVk::setStorageMultisample(const gl::Context *context,
...@@ -1190,6 +1216,14 @@ void TextureVk::releaseImage(const gl::Context *context, RendererVk *renderer) ...@@ -1190,6 +1216,14 @@ void TextureVk::releaseImage(const gl::Context *context, RendererVk *renderer)
mImage.release(renderer->getCurrentQueueSerial(), renderer); mImage.release(renderer->getCurrentQueueSerial(), renderer);
renderer->releaseObject(getStoredQueueSerial(), &mBaseLevelImageView); renderer->releaseObject(getStoredQueueSerial(), &mBaseLevelImageView);
renderer->releaseObject(getStoredQueueSerial(), &mMipmapImageView); renderer->releaseObject(getStoredQueueSerial(), &mMipmapImageView);
for (vk::ImageView &imageView : mCubeMapFaceImageViews)
{
renderer->releaseObject(getStoredQueueSerial(), &imageView);
}
mCubeMapFaceImageViews.clear();
mCubeMapRenderTargets.clear();
onStateChange(context, angle::SubjectMessage::DEPENDENT_DIRTY_BITS); onStateChange(context, angle::SubjectMessage::DEPENDENT_DIRTY_BITS);
} }
......
...@@ -250,6 +250,7 @@ class TextureVk : public TextureImpl, public vk::CommandGraphResource ...@@ -250,6 +250,7 @@ class TextureVk : public TextureImpl, public vk::CommandGraphResource
angle::Result getCommandBufferForWrite(ContextVk *contextVk, angle::Result getCommandBufferForWrite(ContextVk *contextVk,
vk::CommandBuffer **commandBufferOut); vk::CommandBuffer **commandBufferOut);
uint32_t getLevelCount() const; uint32_t getLevelCount() const;
angle::Result initCubeMapRenderTargets(ContextVk *contextVk);
vk::ImageHelper mImage; vk::ImageHelper mImage;
vk::ImageView mBaseLevelImageView; vk::ImageView mBaseLevelImageView;
...@@ -257,6 +258,8 @@ class TextureVk : public TextureImpl, public vk::CommandGraphResource ...@@ -257,6 +258,8 @@ class TextureVk : public TextureImpl, public vk::CommandGraphResource
vk::Sampler mSampler; vk::Sampler mSampler;
RenderTargetVk mRenderTarget; RenderTargetVk mRenderTarget;
std::vector<vk::ImageView> mCubeMapFaceImageViews;
std::vector<RenderTargetVk> mCubeMapRenderTargets;
PixelBuffer mPixelBuffer; PixelBuffer mPixelBuffer;
}; };
......
...@@ -584,6 +584,19 @@ angle::Result ImageHelper::initImageView(Context *context, ...@@ -584,6 +584,19 @@ angle::Result ImageHelper::initImageView(Context *context,
ImageView *imageViewOut, ImageView *imageViewOut,
uint32_t levelCount) uint32_t levelCount)
{ {
return initLayerImageView(context, textureType, aspectMask, swizzleMap, imageViewOut,
levelCount, 0, mLayerCount);
}
angle::Result ImageHelper::initLayerImageView(Context *context,
gl::TextureType textureType,
VkImageAspectFlags aspectMask,
const gl::SwizzleState &swizzleMap,
ImageView *imageViewOut,
uint32_t levelCount,
uint32_t baseArrayLayer,
uint32_t layerCount)
{
VkImageViewCreateInfo viewInfo; VkImageViewCreateInfo viewInfo;
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
viewInfo.pNext = nullptr; viewInfo.pNext = nullptr;
...@@ -608,8 +621,8 @@ angle::Result ImageHelper::initImageView(Context *context, ...@@ -608,8 +621,8 @@ angle::Result ImageHelper::initImageView(Context *context,
viewInfo.subresourceRange.aspectMask = aspectMask; viewInfo.subresourceRange.aspectMask = aspectMask;
viewInfo.subresourceRange.baseMipLevel = 0; viewInfo.subresourceRange.baseMipLevel = 0;
viewInfo.subresourceRange.levelCount = levelCount; viewInfo.subresourceRange.levelCount = levelCount;
viewInfo.subresourceRange.baseArrayLayer = 0; viewInfo.subresourceRange.baseArrayLayer = baseArrayLayer;
viewInfo.subresourceRange.layerCount = mLayerCount; viewInfo.subresourceRange.layerCount = layerCount;
ANGLE_TRY(imageViewOut->init(context, viewInfo)); ANGLE_TRY(imageViewOut->init(context, viewInfo));
return angle::Result::Continue(); return angle::Result::Continue();
......
...@@ -180,6 +180,14 @@ class ImageHelper final : angle::NonCopyable ...@@ -180,6 +180,14 @@ class ImageHelper final : angle::NonCopyable
angle::Result initMemory(Context *context, angle::Result initMemory(Context *context,
const MemoryProperties &memoryProperties, const MemoryProperties &memoryProperties,
VkMemoryPropertyFlags flags); VkMemoryPropertyFlags flags);
angle::Result initLayerImageView(Context *context,
gl::TextureType textureType,
VkImageAspectFlags aspectMask,
const gl::SwizzleState &swizzleMap,
ImageView *imageViewOut,
uint32_t levelCount,
uint32_t baseArrayLayer,
uint32_t layerCount);
angle::Result initImageView(Context *context, angle::Result initImageView(Context *context,
gl::TextureType textureType, gl::TextureType textureType,
VkImageAspectFlags aspectMask, VkImageAspectFlags aspectMask,
......
...@@ -684,9 +684,6 @@ TEST_P(CopyTextureTest, Alpha) ...@@ -684,9 +684,6 @@ TEST_P(CopyTextureTest, Alpha)
// Test that copying to cube maps works // Test that copying to cube maps works
TEST_P(CopyTextureTest, CubeMapTarget) TEST_P(CopyTextureTest, CubeMapTarget)
{ {
// TODO(jmadill): Support cube map framebuffer attachments. http://anglebug.com/2470
ANGLE_SKIP_TEST_IF(IsVulkan());
if (!checkExtensions()) if (!checkExtensions())
{ {
return; return;
......
...@@ -272,9 +272,6 @@ TEST_P(FramebufferFormatsTest, RenderbufferMultisample_STENCIL_INDEX8) ...@@ -272,9 +272,6 @@ TEST_P(FramebufferFormatsTest, RenderbufferMultisample_STENCIL_INDEX8)
// Test that binding an incomplete cube map is rejected by ANGLE. // Test that binding an incomplete cube map is rejected by ANGLE.
TEST_P(FramebufferFormatsTest, IncompleteCubeMap) TEST_P(FramebufferFormatsTest, IncompleteCubeMap)
{ {
// TODO(jmadill): Handle cube textures. http://anglebug.com/2470
ANGLE_SKIP_TEST_IF(IsVulkan());
// First make a complete CubeMap. // First make a complete CubeMap.
glGenTextures(1, &mTexture); glGenTextures(1, &mTexture);
glBindTexture(GL_TEXTURE_CUBE_MAP, mTexture); glBindTexture(GL_TEXTURE_CUBE_MAP, mTexture);
......
...@@ -767,8 +767,9 @@ TEST_P(MipmapTest, MipMapGenerationD3D9Bug) ...@@ -767,8 +767,9 @@ TEST_P(MipmapTest, MipMapGenerationD3D9Bug)
// works as expected. It tests enabling/disabling mipmaps, generating mipmaps, and rendering to level zero. // works as expected. It tests enabling/disabling mipmaps, generating mipmaps, and rendering to level zero.
TEST_P(MipmapTest, TextureCubeGeneralLevelZero) TEST_P(MipmapTest, TextureCubeGeneralLevelZero)
{ {
// TODO(jmadill): Cube map attachments http://anglebug.com/2470 // This test seems to fail only on Android Vulkan.
ANGLE_SKIP_TEST_IF(IsVulkan()); // TODO(jmadill): Diagnose and fix. http://anglebug.com/2470
ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());
glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube); glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
...@@ -808,9 +809,6 @@ TEST_P(MipmapTest, TextureCubeGeneralLevelZero) ...@@ -808,9 +809,6 @@ TEST_P(MipmapTest, TextureCubeGeneralLevelZero)
// This test ensures that rendering to level-zero of a TextureCube works as expected. // This test ensures that rendering to level-zero of a TextureCube works as expected.
TEST_P(MipmapTest, TextureCubeRenderToLevelZero) TEST_P(MipmapTest, TextureCubeRenderToLevelZero)
{ {
// TODO(jmadill): Cube map attachments http://anglebug.com/2470
ANGLE_SKIP_TEST_IF(IsVulkan());
glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube); glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
// Draw. Since the negative-Y face's is blue, this should be blue. // Draw. Since the negative-Y face's is blue, this should be blue.
......
...@@ -1374,9 +1374,6 @@ TEST_P(Texture2DTestWithDrawScale, MipmapsTwice) ...@@ -1374,9 +1374,6 @@ TEST_P(Texture2DTestWithDrawScale, MipmapsTwice)
// https://code.google.com/p/angleproject/issues/detail?id=849 // https://code.google.com/p/angleproject/issues/detail?id=849
TEST_P(TextureCubeTest, CubeMapFBO) TEST_P(TextureCubeTest, CubeMapFBO)
{ {
// TODO(jmadill): Cube map render targets. http://anglebug.com/2470
ANGLE_SKIP_TEST_IF(IsVulkan());
GLuint fbo; GLuint fbo;
glGenFramebuffers(1, &fbo); glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo);
......
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