Commit 66410530 by Luc Ferron Committed by Commit Bot

Vulkan: Textures mipmaps support

Note that generate mipmaps is not yet supported, but uploading mipmaps is. This also enables 64 tests in dEQP gles2 to validate the changes. While trying to enable tests in functional.texture.mipmap.*, I found an issue where the graph ends up in an invalid state and triggers and assert in onReadResource in ContextVk.cpp:188. It seems like an unrelated bug to mip maps, I will investigate to enable these tests separately in a following CL. Bug: angleproject:2479 Change-Id: If51776d8ef3d994bee620d6a1cf982bb51838ff0 Reviewed-on: https://chromium-review.googlesource.com/1022232 Commit-Queue: Luc Ferron <lucferron@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent b3474d9d
......@@ -81,7 +81,7 @@ gl::Error RenderbufferVk::setStorage(const gl::Context *context,
(isDepthOrStencilFormat ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT : 0);
gl::Extents extents(static_cast<int>(width), static_cast<int>(height), 1);
ANGLE_TRY(mImage.init(device, gl::TextureType::_2D, extents, vkFormat, 1, usage));
ANGLE_TRY(mImage.init(device, gl::TextureType::_2D, extents, vkFormat, 1, usage, 1));
VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
ANGLE_TRY(mImage.initMemory(device, renderer->getMemoryProperties(), flags));
......@@ -92,7 +92,7 @@ gl::Error RenderbufferVk::setStorage(const gl::Context *context,
(textureFormat.redBits > 0 ? VK_IMAGE_ASPECT_COLOR_BIT : 0);
ANGLE_TRY(mImage.initImageView(device, gl::TextureType::_2D, aspect, gl::SwizzleState(),
&mImageView));
&mImageView, 1));
// TODO(jmadill): Fold this into the RenderPass load/store ops. http://anglebug.com/2361
vk::CommandBuffer *commandBuffer = nullptr;
......
......@@ -397,7 +397,7 @@ vk::Error WindowSurfaceVk::initializeImpl(RendererVk *renderer)
SwapchainImage &member = mSwapchainImages[imageIndex];
member.image.init2DWeakReference(swapchainImages[imageIndex], extents, format, 1);
member.image.initImageView(device, gl::TextureType::_2D, VK_IMAGE_ASPECT_COLOR_BIT,
gl::SwizzleState(), &member.imageView);
gl::SwizzleState(), &member.imageView, 1);
// Set transfer dest layout, and clear the image to black.
member.image.clearColor(transparentBlack, commandBuffer);
......@@ -419,7 +419,7 @@ vk::Error WindowSurfaceVk::initializeImpl(RendererVk *renderer)
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
ANGLE_TRY(
mDepthStencilImage.init(device, gl::TextureType::_2D, extents, dsFormat, 1, usage));
mDepthStencilImage.init(device, gl::TextureType::_2D, extents, dsFormat, 1, usage, 1));
ANGLE_TRY(mDepthStencilImage.initMemory(device, renderer->getMemoryProperties(),
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
......@@ -433,7 +433,7 @@ vk::Error WindowSurfaceVk::initializeImpl(RendererVk *renderer)
mDepthStencilImage.clearDepthStencil(aspect, depthStencilClearValue, commandBuffer);
ANGLE_TRY(mDepthStencilImage.initImageView(device, gl::TextureType::_2D, aspect,
gl::SwizzleState(), &mDepthStencilImageView));
gl::SwizzleState(), &mDepthStencilImageView, 1));
mDepthStencilRenderTarget.resource = this;
mDepthStencilRenderTarget.image = &mDepthStencilImage;
......
......@@ -183,7 +183,7 @@ PixelBuffer::SubresourceUpdate::SubresourceUpdate(const SubresourceUpdate &other
TextureVk::TextureVk(const gl::TextureState &state) : TextureImpl(state)
{
mRenderTarget.image = &mImage;
mRenderTarget.imageView = &mImageView;
mRenderTarget.imageView = &mBaseLevelImageView;
mRenderTarget.resource = this;
}
......@@ -216,13 +216,6 @@ gl::Error TextureVk::setImage(const gl::Context *context,
ContextVk *contextVk = vk::GetImpl(context);
RendererVk *renderer = contextVk->getRenderer();
// TODO(jmadill): support multi-level textures.
if (index.getLevelIndex() != 0)
{
UNIMPLEMENTED();
return gl::InternalError();
}
// Convert internalFormat to sized internal format.
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat, type);
......@@ -418,9 +411,11 @@ vk::Error TextureVk::ensureImageInitialized(RendererVk *renderer)
(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
ANGLE_TRY(mImage.init(device, mState.getType(), extents, format, 1, usage));
const uint32_t levelCount = getLevelCount();
ANGLE_TRY(mImage.init(device, mState.getType(), extents, format, 1, usage, levelCount));
VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
ANGLE_TRY(mImage.initMemory(device, renderer->getMemoryProperties(), flags));
gl::SwizzleState mappedSwizzle;
......@@ -428,7 +423,9 @@ vk::Error TextureVk::ensureImageInitialized(RendererVk *renderer)
// TODO(jmadill): Separate imageviews for RenderTargets and Sampling.
ANGLE_TRY(mImage.initImageView(device, mState.getType(), VK_IMAGE_ASPECT_COLOR_BIT,
mappedSwizzle, &mImageView));
mappedSwizzle, &mMipmapImageView, levelCount));
ANGLE_TRY(mImage.initImageView(device, mState.getType(), VK_IMAGE_ASPECT_COLOR_BIT,
mappedSwizzle, &mBaseLevelImageView, 1));
// TODO(jmadill): Fold this into the RenderPass load/store ops. http://anglebug.com/2361
......@@ -463,7 +460,7 @@ gl::Error TextureVk::syncState(const gl::Context *context, const gl::Texture::Di
samplerInfo.flags = 0;
samplerInfo.magFilter = gl_vk::GetFilter(samplerState.magFilter);
samplerInfo.minFilter = gl_vk::GetFilter(samplerState.minFilter);
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
samplerInfo.mipmapMode = gl_vk::GetSamplerMipmapMode(samplerState.minFilter);
samplerInfo.addressModeU = gl_vk::GetSamplerAddressMode(samplerState.wrapS);
samplerInfo.addressModeV = gl_vk::GetSamplerAddressMode(samplerState.wrapT);
samplerInfo.addressModeW = gl_vk::GetSamplerAddressMode(samplerState.wrapR);
......@@ -472,8 +469,8 @@ gl::Error TextureVk::syncState(const gl::Context *context, const gl::Texture::Di
samplerInfo.maxAnisotropy = 1.0f;
samplerInfo.compareEnable = VK_FALSE;
samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
samplerInfo.minLod = 0.0f;
samplerInfo.maxLod = 1.0f;
samplerInfo.minLod = samplerState.minLod;
samplerInfo.maxLod = samplerState.maxLod;
samplerInfo.borderColor = VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
samplerInfo.unnormalizedCoordinates = VK_FALSE;
......@@ -508,7 +505,14 @@ const vk::ImageHelper &TextureVk::getImage() const
const vk::ImageView &TextureVk::getImageView() const
{
ASSERT(mImage.valid());
return mImageView;
const GLenum minFilter = mState.getSamplerState().minFilter;
if (minFilter == GL_LINEAR || minFilter == GL_NEAREST)
{
return mBaseLevelImageView;
}
return mMipmapImageView;
}
const vk::Sampler &TextureVk::getSampler() const
......@@ -520,8 +524,16 @@ const vk::Sampler &TextureVk::getSampler() const
void TextureVk::releaseImage(const gl::Context *context, RendererVk *renderer)
{
mImage.release(renderer->getCurrentQueueSerial(), renderer);
renderer->releaseResource(*this, &mImageView);
renderer->releaseResource(*this, &mBaseLevelImageView);
renderer->releaseResource(*this, &mMipmapImageView);
onStateChange(context, angle::SubjectMessage::DEPENDENT_DIRTY_BITS);
}
uint32_t TextureVk::getLevelCount() const
{
ASSERT(mState.getEffectiveBaseLevel() == 0);
// getMipmapMaxLevel will be 0 here if mipmaps are not used, so the levelCount is always +1.
return mState.getMipmapMaxLevel() + 1;
}
} // namespace rx
......@@ -150,9 +150,11 @@ class TextureVk : public TextureImpl, public vk::CommandGraphResource
private:
void releaseImage(const gl::Context *context, RendererVk *renderer);
uint32_t getLevelCount() const;
vk::ImageHelper mImage;
vk::ImageView mImageView;
vk::ImageView mBaseLevelImageView;
vk::ImageView mMipmapImageView;
vk::Sampler mSampler;
RenderTargetVk mRenderTarget;
......
......@@ -489,7 +489,8 @@ Error ImageHelper::init(VkDevice device,
const gl::Extents &extents,
const Format &format,
GLint samples,
VkImageUsageFlags usage)
VkImageUsageFlags usage,
uint32_t mipLevels)
{
ASSERT(!valid());
......@@ -507,7 +508,7 @@ Error ImageHelper::init(VkDevice device,
imageInfo.extent.width = static_cast<uint32_t>(extents.width);
imageInfo.extent.height = static_cast<uint32_t>(extents.height);
imageInfo.extent.depth = 1;
imageInfo.mipLevels = 1;
imageInfo.mipLevels = mipLevels;
imageInfo.arrayLayers = mLayerCount;
imageInfo.samples = gl_vk::GetSamples(samples);
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
......@@ -548,7 +549,8 @@ Error ImageHelper::initImageView(VkDevice device,
gl::TextureType textureType,
VkImageAspectFlags aspectMask,
const gl::SwizzleState &swizzleMap,
ImageView *imageViewOut)
ImageView *imageViewOut,
uint32_t levelCount)
{
VkImageViewCreateInfo viewInfo;
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
......@@ -563,7 +565,7 @@ Error ImageHelper::initImageView(VkDevice device,
viewInfo.components.a = gl_vk::GetSwizzle(swizzleMap.swizzleAlpha);
viewInfo.subresourceRange.aspectMask = aspectMask;
viewInfo.subresourceRange.baseMipLevel = 0;
viewInfo.subresourceRange.levelCount = 1;
viewInfo.subresourceRange.levelCount = levelCount;
viewInfo.subresourceRange.baseArrayLayer = 0;
viewInfo.subresourceRange.layerCount = mLayerCount;
......@@ -701,7 +703,7 @@ void ImageHelper::changeLayoutWithStages(VkImageAspectFlags aspectMask,
// TODO(jmadill): Is this needed for mipped/layer images?
imageMemoryBarrier.subresourceRange.aspectMask = aspectMask;
imageMemoryBarrier.subresourceRange.baseMipLevel = 0;
imageMemoryBarrier.subresourceRange.levelCount = 1;
imageMemoryBarrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
imageMemoryBarrier.subresourceRange.baseArrayLayer = 0;
imageMemoryBarrier.subresourceRange.layerCount = mLayerCount;
......@@ -743,7 +745,7 @@ void ImageHelper::clearColor(const VkClearColorValue &color, CommandBuffer *comm
VkImageSubresourceRange range;
range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
range.baseMipLevel = 0;
range.levelCount = 1;
range.levelCount = VK_REMAINING_MIP_LEVELS;
range.baseArrayLayer = 0;
range.layerCount = mLayerCount;
......
......@@ -167,7 +167,8 @@ class ImageHelper final : angle::NonCopyable
const gl::Extents &extents,
const Format &format,
GLint samples,
VkImageUsageFlags usage);
VkImageUsageFlags usage,
uint32_t mipLevels);
Error initMemory(VkDevice device,
const MemoryProperties &memoryProperties,
VkMemoryPropertyFlags flags);
......@@ -175,7 +176,8 @@ class ImageHelper final : angle::NonCopyable
gl::TextureType textureType,
VkImageAspectFlags aspectMask,
const gl::SwizzleState &swizzleMap,
ImageView *imageViewOut);
ImageView *imageViewOut,
uint32_t levelCount);
Error init2DStaging(VkDevice device,
const MemoryProperties &memoryProperties,
const Format &format,
......
......@@ -1158,6 +1158,24 @@ VkFilter GetFilter(const GLenum filter)
}
}
VkSamplerMipmapMode GetSamplerMipmapMode(const GLenum filter)
{
switch (filter)
{
case GL_LINEAR:
case GL_LINEAR_MIPMAP_LINEAR:
case GL_NEAREST_MIPMAP_LINEAR:
return VK_SAMPLER_MIPMAP_MODE_LINEAR;
case GL_NEAREST:
case GL_NEAREST_MIPMAP_NEAREST:
case GL_LINEAR_MIPMAP_NEAREST:
return VK_SAMPLER_MIPMAP_MODE_NEAREST;
default:
UNIMPLEMENTED();
return VK_SAMPLER_MIPMAP_MODE_MAX_ENUM;
}
}
VkSamplerAddressMode GetSamplerAddressMode(const GLenum wrap)
{
switch (wrap)
......
......@@ -651,6 +651,7 @@ namespace gl_vk
{
VkRect2D GetRect(const gl::Rectangle &source);
VkFilter GetFilter(const GLenum filter);
VkSamplerMipmapMode GetSamplerMipmapMode(const GLenum filter);
VkSamplerAddressMode GetSamplerAddressMode(const GLenum wrap);
VkPrimitiveTopology GetPrimitiveTopology(GLenum mode);
VkCullModeFlags GetCullMode(const gl::RasterizerState &rasterState);
......
......@@ -197,44 +197,13 @@
2161 VULKAN : dEQP-GLES2.functional.buffer.* = SKIP
2161 VULKAN : dEQP-GLES2.functional.light_amount.* = SKIP
2161 VULKAN : dEQP-GLES2.functional.shaders.* = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.2d.64x64_l8_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.2d.64x64_rgba4444_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.2d.64x64_rgb888_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.2d.64x64_rgba8888_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.2d.512x512_l8_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.2d.512x512_rgba4444_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.2d.512x512_rgb888_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.2d.512x512_rgba8888_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.2d.1024x1024_l8_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.2d.1024x1024_rgba4444_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.2d.1024x1024_rgb888_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.2d.1024x1024_rgba8888_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.2d.2048x2048_l8_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.2d.2048x2048_rgba4444_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.2d.2048x2048_rgb888_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.2d.2048x2048_rgba8888_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.cube.16x16_rgba4444_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.cube.16x16_rgb888_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.cube.16x16_rgba8888_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.cube.64x64_l8_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.cube.64x64_rgba4444_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.cube.64x64_rgb888_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.cube.64x64_rgba8888_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.cube.128x128_l8_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.cube.128x128_rgba4444_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.cube.128x128_rgb888_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.cube.128x128_rgba8888_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.cube.256x256_l8_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.cube.256x256_rgb888_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.cube.256x256_rgba8888_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.cube.512x512_l8_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.cube.512x512_rgb888_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.cube.512x512_rgba8888_mipmap = SKIP
2161 VULKAN : dEQP-GLES2.functional.texture.filtering.cube.* = SKIP
2161 VULKAN : dEQP-GLES2.functional.texture.filtering.nearest_mipmap_* = SKIP
2161 VULKAN : dEQP-GLES2.functional.texture.filtering.linear_mipmap_* = SKIP
2161 VULKAN : dEQP-GLES2.functional.texture.mipmap.* = SKIP
2161 VULKAN : dEQP-GLES2.functional.texture.specification.* = SKIP
2161 VULKAN : dEQP-GLES2.functional.texture.specification.basic_texsubimage2d.* = SKIP
2161 VULKAN : dEQP-GLES2.functional.texture.specification.texsubimage2d_* = SKIP
2161 VULKAN : dEQP-GLES2.functional.texture.specification.basic_copytex* = SKIP
2161 VULKAN : dEQP-GLES2.functional.texture.completeness.* = SKIP
2161 VULKAN : dEQP-GLES2.functional.texture.vertex.* = SKIP
2161 VULKAN : dEQP-GLES2.functional.fragment_ops.random.* = SKIP
......
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