Commit a2129356 by Cody Northrop Committed by Commit Bot

Vulkan: Add support for 2D array textures

Includes changes from jmadill to align with Vulkan backend design. Correctly setting layer count and depth when the texture type is 2Darray. Vulkan requires depth of 1 for 2Darray textures. Bug: angleproject:3189 Change-Id: I0d58c33fcd75b1d768ea0308ac6e54230d8cfcc5 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1721169Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarJonah Ryan-Davis <jonahr@google.com> Commit-Queue: Cody Northrop <cnorthrop@google.com>
parent 7e50f4cd
......@@ -56,7 +56,7 @@ SampleApplication::SampleApplication(std::string name,
mEGLWindow(nullptr),
mOSWindow(nullptr)
{
mPlatformParams.renderer = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
mPlatformParams.renderer = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
if (argc > 1 && strncmp(argv[1], kUseAngleArg, strlen(kUseAngleArg)) == 0)
{
......
......@@ -235,7 +235,7 @@ int main(int argc, char *argv[])
case 'y': resources.EXT_YUV_target = 1; break;
default: failCode = EFailUsage;
}
// clang-format on
// clang-format on
}
else
{
......
......@@ -158,12 +158,24 @@ TextureType SamplerTypeToTextureType(GLenum samplerType)
}
}
bool IsMultisampled(gl::TextureType type)
bool IsMultisampled(TextureType type)
{
switch (type)
{
case gl::TextureType::_2DMultisample:
case gl::TextureType::_2DMultisampleArray:
case TextureType::_2DMultisample:
case TextureType::_2DMultisampleArray:
return true;
default:
return false;
}
}
bool IsArrayTextureType(TextureType type)
{
switch (type)
{
case TextureType::_2DArray:
case TextureType::_2DMultisampleArray:
return true;
default:
return false;
......
......@@ -214,6 +214,7 @@ using ShaderMap = angle::PackedEnumMap<ShaderType, T>;
TextureType SamplerTypeToTextureType(GLenum samplerType);
bool IsMultisampled(gl::TextureType type);
bool IsArrayTextureType(gl::TextureType type);
enum class PrimitiveMode : uint8_t
{
......
......@@ -97,11 +97,12 @@ angle::Result MemoryObjectVk::createImage(const gl::Context *context,
externalMemoryImageCreateInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
VkExtent3D vkExtents;
gl_vk::GetExtent(size, &vkExtents);
uint32_t layerCount;
gl_vk::GetExtentsAndLayerCount(type, size, &vkExtents, &layerCount);
ANGLE_TRY(image->initExternal(contextVk, type, vkExtents, vkFormat, 1, imageUsageFlags,
vk::ImageLayout::ExternalPreInitialized,
&externalMemoryImageCreateInfo, levels, 1));
&externalMemoryImageCreateInfo, levels, layerCount));
VkMemoryRequirements externalMemoryRequirements;
image->getImage().getMemoryRequirements(renderer->getDevice(), &externalMemoryRequirements);
......
......@@ -566,7 +566,7 @@ angle::Result ProgramVk::linkImpl(const gl::Context *glContext, gl::InfoLog &inf
uint32_t storageBlockCount = static_cast<uint32_t>(mState.getShaderStorageBlocks().size());
uint32_t atomicCounterBufferCount =
static_cast<uint32_t>(mState.getAtomicCounterBuffers().size());
uint32_t textureCount = static_cast<uint32_t>(mState.getSamplerBindings().size());
uint32_t textureCount = static_cast<uint32_t>(mState.getSamplerBindings().size());
if (renderer->getFeatures().bindEmptyForUnusedDescriptorSets.enabled)
{
......
......@@ -120,6 +120,9 @@ angle::Result TextureVk::generateMipmapLevelsWithCPU(ContextVk *contextVk,
TextureVk::TextureVk(const gl::TextureState &state, RendererVk *renderer)
: TextureImpl(state),
mOwnsImage(false),
mImageNativeType(gl::TextureType::InvalidEnum),
mImageLayerOffset(0),
mImageLevelOffset(0),
mImage(nullptr),
mStagingBufferInitialSize(vk::kStagingBufferSize)
{}
......@@ -738,7 +741,7 @@ angle::Result TextureVk::setStorageExternalMemory(const gl::Context *context,
ANGLE_TRY(
memoryObjectVk->createImage(context, type, levels, internalFormat, size, offset, mImage));
ANGLE_TRY(initImageViews(contextVk, format, levels));
ANGLE_TRY(initImageViews(contextVk, format, levels, mImage->getLayerCount()));
// TODO(spang): This needs to be reworked when semaphores are added.
// http://anglebug.com/3289
......@@ -770,7 +773,8 @@ angle::Result TextureVk::setEGLImageTarget(const gl::Context *context,
setImageHelper(contextVk, imageVk->getImage(), imageVk->getImageTextureType(), format,
imageVk->getImageLevel(), imageVk->getImageLayer(), false);
ANGLE_TRY(initImageViews(contextVk, format, 1));
ASSERT(type != gl::TextureType::CubeMap);
ANGLE_TRY(initImageViews(contextVk, format, 1, 1));
// Transfer the image to this queue if needed
uint32_t rendererQueueFamilyIndex = renderer->getQueueFamilyIndex();
......@@ -1065,7 +1069,8 @@ angle::Result TextureVk::bindTexImage(const gl::Context *context, egl::Surface *
setImageHelper(contextVk, offscreenSurface->getColorAttachmentImage(), mState.getType(), format,
surface->getMipmapLevel(), 0, false);
return initImageViews(contextVk, format, 1);
ASSERT(mImage->getLayerCount() == 1);
return initImageViews(contextVk, format, 1, 1);
}
angle::Result TextureVk::releaseTexImage(const gl::Context *context)
......@@ -1195,8 +1200,14 @@ angle::Result TextureVk::syncState(const gl::Context *context,
{
if (mImage && mImage->valid())
{
// We use a special layer count here to handle EGLImages. They might only be
// looking at one layer of a cube or 2D array texture.
uint32_t layerCount =
mState.getType() == gl::TextureType::_2D ? 1 : mImage->getLayerCount();
releaseImageViews(contextVk);
ANGLE_TRY(initImageViews(contextVk, mImage->getFormat(), mImage->getLevelCount()));
ANGLE_TRY(initImageViews(contextVk, mImage->getFormat(), mImage->getLevelCount(),
layerCount));
}
}
......@@ -1360,24 +1371,23 @@ angle::Result TextureVk::initImage(ContextVk *contextVk,
}
VkExtent3D vkExtent;
gl_vk::GetExtent(extents, &vkExtent);
uint32_t layerCount;
gl_vk::GetExtentsAndLayerCount(mState.getType(), extents, &vkExtent, &layerCount);
ANGLE_TRY(mImage->init(contextVk, mState.getType(), vkExtent, format, 1, imageUsageFlags,
levelCount,
mState.getType() == gl::TextureType::CubeMap ? gl::kCubeFaceCount : 1));
levelCount, layerCount));
const VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
ANGLE_TRY(mImage->initMemory(contextVk, renderer->getMemoryProperties(), flags));
ANGLE_TRY(initImageViews(contextVk, format, levelCount));
ANGLE_TRY(initImageViews(contextVk, format, levelCount, layerCount));
// If the image has an emulated channel, always clear it. These channels will be masked out in
// future writes, and shouldn't contain uninitialized values.
if (format.hasEmulatedImageChannels())
{
uint32_t levelCount = mImage->getLevelCount();
uint32_t layerCount = mImage->getLayerCount();
for (uint32_t level = 0; level < levelCount; ++level)
{
......@@ -1394,7 +1404,8 @@ angle::Result TextureVk::initImage(ContextVk *contextVk,
angle::Result TextureVk::initImageViews(ContextVk *contextVk,
const vk::Format &format,
uint32_t levelCount)
uint32_t levelCount,
uint32_t layerCount)
{
ASSERT(mImage != nullptr);
......@@ -1403,9 +1414,9 @@ angle::Result TextureVk::initImageViews(ContextVk *contextVk,
// TODO: Support non-zero base level for ES 3.0 by passing it to getNativeImageLevel.
// http://anglebug.com/3148
uint32_t baseLevel = getNativeImageLevel(0);
uint32_t baseLayer = getNativeImageLayer(0);
uint32_t layerCount = mState.getType() == gl::TextureType::CubeMap ? gl::kCubeFaceCount : 1;
uint32_t baseLevel = getNativeImageLevel(0);
uint32_t baseLayer = getNativeImageLayer(0);
VkImageAspectFlags aspectFlags = vk::GetFormatAspectFlags(format.angleFormat());
// If we are reading a depth buffer, select only the depth component/aspect
if (aspectFlags & VK_IMAGE_ASPECT_DEPTH_BIT)
......@@ -1419,7 +1430,9 @@ angle::Result TextureVk::initImageViews(ContextVk *contextVk,
ANGLE_TRY(mImage->initLayerImageView(contextVk, mState.getType(), aspectFlags, mappedSwizzle,
&mReadBaseLevelImageView, baseLevel, 1, baseLayer,
layerCount));
if (mState.getType() == gl::TextureType::CubeMap)
if (mState.getType() == gl::TextureType::CubeMap ||
mState.getType() == gl::TextureType::_2DArray ||
mState.getType() == gl::TextureType::_2DMultisampleArray)
{
gl::TextureType arrayType = vk::Get2DTextureType(layerCount, mImage->getSamples());
......
......@@ -278,7 +278,8 @@ class TextureVk : public TextureImpl
uint32_t getLevelCount() const;
angle::Result initImageViews(ContextVk *contextVk,
const vk::Format &format,
uint32_t levelCount);
uint32_t levelCount,
uint32_t layerCount);
angle::Result initCubeMapRenderTargets(ContextVk *contextVk);
angle::Result ensureImageInitializedImpl(ContextVk *contextVk,
......
......@@ -1517,17 +1517,18 @@ angle::Result ImageHelper::initExternal(Context *context,
{
ASSERT(!valid());
// Validate that the input layerCount is compatible with the texture type
ASSERT(textureType != gl::TextureType::_3D || layerCount == 1);
ASSERT(textureType != gl::TextureType::External || layerCount == 1);
ASSERT(textureType != gl::TextureType::Rectangle || layerCount == 1);
ASSERT(textureType != gl::TextureType::CubeMap || layerCount == gl::kCubeFaceCount);
mExtents = extents;
mFormat = &format;
mSamples = samples;
mLayerCount = layerCount;
mLevelCount = mipLevels;
mLayerCount = layerCount;
// Validate that mLayerCount is compatible with the texture type
ASSERT(textureType != gl::TextureType::_3D || mLayerCount == 1);
ASSERT(textureType != gl::TextureType::_2DArray || mExtents.depth == 1);
ASSERT(textureType != gl::TextureType::External || mLayerCount == 1);
ASSERT(textureType != gl::TextureType::Rectangle || mLayerCount == 1);
ASSERT(textureType != gl::TextureType::CubeMap || mLayerCount == gl::kCubeFaceCount);
VkImageCreateInfo imageInfo = {};
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
......@@ -2171,16 +2172,27 @@ angle::Result ImageHelper::stageSubresourceUpdate(ContextVk *contextVk,
VkBufferImageCopy copy = {};
VkImageAspectFlags aspectFlags = GetFormatAspectFlags(vkFormat.imageFormat());
copy.bufferOffset = stagingOffset;
copy.bufferRowLength = bufferRowLength;
copy.bufferImageHeight = bufferImageHeight;
copy.imageSubresource.mipLevel = index.getLevelIndex();
copy.imageSubresource.baseArrayLayer = index.hasLayer() ? index.getLayerIndex() : 0;
copy.imageSubresource.layerCount = index.getLayerCount();
copy.bufferOffset = stagingOffset;
copy.bufferRowLength = bufferRowLength;
copy.bufferImageHeight = bufferImageHeight;
copy.imageSubresource.mipLevel = index.getLevelIndex();
copy.imageSubresource.layerCount = index.getLayerCount();
gl_vk::GetOffset(offset, &copy.imageOffset);
gl_vk::GetExtent(glExtents, &copy.imageExtent);
if (gl::IsArrayTextureType(index.getType()))
{
copy.imageSubresource.baseArrayLayer = offset.z;
copy.imageOffset.z = 0;
copy.imageExtent.depth = 1;
}
else
{
copy.imageSubresource.baseArrayLayer = index.hasLayer() ? index.getLayerIndex() : 0;
}
if (stencilAllocationSize > 0)
{
// Note: Stencil is always one byte
......@@ -2203,13 +2215,12 @@ angle::Result ImageHelper::stageSubresourceUpdate(ContextVk *contextVk,
stencilCopy.bufferOffset = stagingOffset;
stencilCopy.bufferRowLength = bufferRowLength;
stencilCopy.bufferImageHeight = bufferImageHeight;
stencilCopy.imageSubresource.mipLevel = index.getLevelIndex();
stencilCopy.imageSubresource.baseArrayLayer = index.hasLayer() ? index.getLayerIndex() : 0;
stencilCopy.imageSubresource.layerCount = index.getLayerCount();
gl_vk::GetOffset(offset, &stencilCopy.imageOffset);
gl_vk::GetExtent(glExtents, &stencilCopy.imageExtent);
stencilCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
stencilCopy.imageSubresource.mipLevel = copy.imageSubresource.mipLevel;
stencilCopy.imageSubresource.baseArrayLayer = copy.imageSubresource.baseArrayLayer;
stencilCopy.imageSubresource.layerCount = copy.imageSubresource.layerCount;
stencilCopy.imageOffset = copy.imageOffset;
stencilCopy.imageExtent = copy.imageExtent;
stencilCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
mSubresourceUpdates.emplace_back(bufferHandle, stencilCopy);
aspectFlags &= ~VK_IMAGE_ASPECT_STENCIL_BIT;
......
......@@ -894,6 +894,34 @@ void GetViewport(const gl::Rectangle &viewport,
viewportOut->height = -viewportOut->height;
}
}
void GetExtentsAndLayerCount(gl::TextureType textureType,
const gl::Extents &extents,
VkExtent3D *extentsOut,
uint32_t *layerCountOut)
{
extentsOut->width = extents.width;
extentsOut->height = extents.height;
switch (textureType)
{
case gl::TextureType::CubeMap:
extentsOut->depth = 1;
*layerCountOut = gl::kCubeFaceCount;
break;
case gl::TextureType::_2DArray:
case gl::TextureType::_2DMultisampleArray:
extentsOut->depth = 1;
*layerCountOut = extents.depth;
break;
default:
extentsOut->depth = extents.depth;
*layerCountOut = 1;
break;
}
}
} // namespace gl_vk
namespace vk_gl
......
......@@ -607,6 +607,11 @@ void GetViewport(const gl::Rectangle &viewport,
bool invertViewport,
GLint renderAreaHeight,
VkViewport *viewportOut);
void GetExtentsAndLayerCount(gl::TextureType textureType,
const gl::Extents &extents,
VkExtent3D *extentsOut,
uint32_t *layerCountOut);
} // namespace gl_vk
namespace vk_gl
......
......@@ -541,25 +541,12 @@
3188 VULKAN : dEQP-GLES3.functional.texture.units.4_units.only_3d.* = SKIP
// 2D array (anglebug.com/3189), new formats in ES 3.0 (anglebug.com/3190):
3189 VULKAN : dEQP-GLES3.functional.shaders.texture_functions.*2darray* = SKIP
3189 VULKAN : dEQP-GLES3.functional.fbo.completeness.layer.2darr* = SKIP
3189 VULKAN : dEQP-GLES3.functional.fbo.color.tex2darray.* = SKIP
3189 VULKAN : dEQP-GLES3.functional.state_query.texture.*2d_array* = SKIP
3189 VULKAN : dEQP-GLES3.functional.texture.format.*2d_array* = SKIP
3189 VULKAN : dEQP-GLES3.functional.texture.filtering.*2d_array* = SKIP
3189 VULKAN : dEQP-GLES3.functional.texture.shadow.2d_array.* = SKIP
3189 VULKAN : dEQP-GLES3.functional.texture.specification.basic_teximage3d.*2d_array* = FAIL
3189 VULKAN : dEQP-GLES3.functional.texture.specification.texstorage3d.format.*2d_array = FAIL
3189 VULKAN : dEQP-GLES3.functional.texture.specification.texstorage3d.size.2d_array_2x2x2_2_levels = FAIL
3189 VULKAN : dEQP-GLES3.functional.texture.specification.texstorage3d.size.2d_array_32x64x3_4_levels = FAIL
3189 VULKAN : dEQP-GLES3.functional.texture.specification.texstorage3d.size.2d_array_57x63x5* = FAIL
3189 VULKAN : dEQP-GLES3.functional.texture.specification.texstorage3d.size.2d_array_64x32x3_7_levels = FAIL
3189 VULKAN : dEQP-GLES3.functional.texture.specification.teximage3d_depth*2d_array = FAIL
3189 VULKAN : dEQP-GLES3.functional.texture.specification.texsubimage3d_depth*2d_array = FAIL
// New or broken formats in ES 3.0:
3190 VULKAN : dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb9* = FAIL
3190 VULKAN : dEQP-GLES3.functional.texture.specification.texstorage2d.format.depth32* = FAIL
3190 VULKAN : dEQP-GLES3.functional.texture.specification.texstorage3d.format.depth32* = SKIP
3190 VULKAN : dEQP-GLES3.functional.texture.specification.basic_teximage2d.rgb9_e5_* = FAIL
3190 VULKAN : dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgb9* = FAIL
3190 VULKAN : dEQP-GLES3.functional.texture.specification.basic_texsubimage2d.rgb9_e5_* = FAIL
......@@ -575,9 +562,8 @@
3190 VULKAN : dEQP-GLES3.functional.texture.specification.texsubimage3d_pbo.* = FAIL
3190 VULKAN : dEQP-GLES3.functional.texture.specification.texsubimage3d_pbo.rgb8_* = SKIP
3190 VULKAN : dEQP-GLES3.functional.texture.specification.texsubimage3d_unpack_params.rgb8_skip_images = FAIL
3190 VULKAN : dEQP-GLES3.functional.texture.specification.teximage2d_depth.depth32f_stencil8 = FAIL
3190 VULKAN : dEQP-GLES3.functional.texture.specification.teximage2d_depth_pbo.* = FAIL
3190 VULKAN : dEQP-GLES3.functional.texture.specification.texsubimage2d_depth.depth32f_stencil8 = FAIL
3190 VULKAN : dEQP-GLES3.functional.texture.specification.teximage3d_depth_pbo.* = SKIP
3190 VULKAN : dEQP-GLES3.functional.texture.specification.teximage3d_unpack_params.r8_* = FAIL
3190 VULKAN : dEQP-GLES3.functional.texture.specification.texsubimage3d_unpack_params.r8_* = FAIL
3190 VULKAN : dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgb9* = FAIL
......@@ -588,14 +574,12 @@
3190 VULKAN : dEQP-GLES3.functional.texture.format.sized.3d.r11* = SKIP
// Functional texture general failures:
3190 VULKAN : dEQP-GLES3.functional.texture.vertex.2d.* = SKIP
3190 VULKAN : dEQP-GLES3.functional.texture.vertex.cube.* = SKIP
3190 VULKAN : dEQP-GLES3.functional.texture.vertex.2d_array.* = SKIP
3190 VULKAN : dEQP-GLES3.functional.texture.units.*2d* = SKIP
3190 VULKAN : dEQP-GLES3.functional.texture.units.*cube* = SKIP
3190 VULKAN : dEQP-GLES3.functional.texture.units.*mixed* = SKIP
3190 VULKAN : dEQP-GLES3.functional.texture.units.all_units.* = SKIP
3190 VULKAN : dEQP-GLES3.functional.texture.units.8_units.* = SKIP
3190 VULKAN : dEQP-GLES3.functional.texture.units.4_units.mixed.8 = SKIP
3190 VULKAN : dEQP-GLES3.functional.texture.units.8_units.*.2 = SKIP
3190 VULKAN : dEQP-GLES3.functional.texture.units.8_units.*.7 = SKIP
3190 VULKAN : dEQP-GLES3.functional.texture.units.8_units.only_cube.0 = SKIP
3190 VULKAN : dEQP-GLES3.functional.texture.units.8_units.mixed.8 = SKIP
// Formats:
3677 ANDROID VULKAN : dEQP-GLES3.functional.fbo.completeness.renderable.renderbuffer.color0.rgba32f = FAIL
......@@ -614,6 +598,7 @@
2905 VULKAN : dEQP-GLES3.functional.fbo.depth.depth_test_clamp.depth_component32f = FAIL
2905 VULKAN : dEQP-GLES3.functional.fbo.depth.depth_test_clamp.depth32f_stencil8 = FAIL
2905 VULKAN : dEQP-GLES3.functional.texture.format.sized.*.depth32f_stencil8* = FAIL
2905 VULKAN : dEQP-GLES3.functional.texture.specification.*_depth.depth32f_stencil8* = SKIP
// Shader support:
3219 VULKAN : dEQP-GLES3.functional.negative_api.shader.link_program = FAIL
......
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