Commit 76bd848c by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Support ETC, S3TC and BPTC compressed textures

Fixes the format table so the correct Vulkan format for the types are generated. Additionally, implements CHROMIUM_copy_compressed_texture as well as other functions relevant to initializing compressed textures. Bug: angleproject:2670, angleproject:2904 Change-Id: I682d36574262525027cddf8f329515f38cd77dc0 Reviewed-on: https://chromium-review.googlesource.com/c/1468048 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@google.com>
parent 1581ff03
......@@ -2,11 +2,11 @@
"ANGLE format:src/libANGLE/renderer/angle_format.py":
"b18ca0fe4835114a4a2f54977b19e798",
"ANGLE format:src/libANGLE/renderer/angle_format_data.json":
"1ab73531d2d9655e669b5560fb43c698",
"288d2f350948f8b1928c249234a44b25",
"ANGLE format:src/libANGLE/renderer/angle_format_map.json":
"be9f9bdbdf785dda05920146e8c55dbb",
"ANGLE format:src/libANGLE/renderer/gen_angle_format_table.py":
"809c5211278023fc159ff276d5fa6f7b",
"00d5b2293e79d71e8d4212d1190a6426",
"ANGLE load functions table:src/libANGLE/renderer/gen_load_functions_table.py":
"8afc7eecce2a3ba9f0b4beacb1aa7fe2",
"ANGLE load functions table:src/libANGLE/renderer/load_functions_data.json":
......@@ -34,7 +34,7 @@
"DXGI format:src/libANGLE/renderer/d3d/d3d11/gen_dxgi_format_table.py":
"8ea01df6cb7f160772d3c85dd5164890",
"DXGI format:src/libANGLE/renderer/gen_angle_format_table.py":
"809c5211278023fc159ff276d5fa6f7b",
"00d5b2293e79d71e8d4212d1190a6426",
"ESSL static builtins:src/compiler/translator/builtin_function_declarations.txt":
"e5e567406476306ea06984d885be028d",
"ESSL static builtins:src/compiler/translator/builtin_variables.json":
......@@ -90,7 +90,7 @@
"Vulkan format:src/libANGLE/renderer/vulkan/gen_vk_format_table.py":
"61a7752424595e24edff0c1f1784e18e",
"Vulkan format:src/libANGLE/renderer/vulkan/vk_format_map.json":
"6e6f7cf9afd17860169b590621c3dcc1",
"992749b88763adb66003fe5d801b5ded",
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/gen_vk_internal_shaders.py":
"1c64f7187357d7561c984ec57d251e74",
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/src/BufferUtils.comp":
......
......@@ -32,5 +32,161 @@
},
"B8G8R8A8_TYPELESS_SRGB": {
"glInternalFormat": "GL_BGRA8_SRGB_ANGLEX"
},
"ASTC_4x4_SRGB_BLOCK": {
"blockPixelBytes": "16"
},
"ASTC_4x4_UNORM_BLOCK": {
"blockPixelBytes": "16"
},
"ASTC_5x4_SRGB_BLOCK": {
"blockPixelBytes": "16"
},
"ASTC_5x4_UNORM_BLOCK": {
"blockPixelBytes": "16"
},
"ASTC_5x5_SRGB_BLOCK": {
"blockPixelBytes": "16"
},
"ASTC_5x5_UNORM_BLOCK": {
"blockPixelBytes": "16"
},
"ASTC_6x5_SRGB_BLOCK": {
"blockPixelBytes": "16"
},
"ASTC_6x5_UNORM_BLOCK": {
"blockPixelBytes": "16"
},
"ASTC_6x6_SRGB_BLOCK": {
"blockPixelBytes": "16"
},
"ASTC_6x6_UNORM_BLOCK": {
"blockPixelBytes": "16"
},
"ASTC_8x5_SRGB_BLOCK": {
"blockPixelBytes": "16"
},
"ASTC_8x5_UNORM_BLOCK": {
"blockPixelBytes": "16"
},
"ASTC_8x6_SRGB_BLOCK": {
"blockPixelBytes": "16"
},
"ASTC_8x6_UNORM_BLOCK": {
"blockPixelBytes": "16"
},
"ASTC_8x8_SRGB_BLOCK": {
"blockPixelBytes": "16"
},
"ASTC_8x8_UNORM_BLOCK": {
"blockPixelBytes": "16"
},
"ASTC_10x5_SRGB_BLOCK": {
"blockPixelBytes": "16"
},
"ASTC_10x5_UNORM_BLOCK": {
"blockPixelBytes": "16"
},
"ASTC_10x6_SRGB_BLOCK": {
"blockPixelBytes": "16"
},
"ASTC_10x6_UNORM_BLOCK": {
"blockPixelBytes": "16"
},
"ASTC_10x8_SRGB_BLOCK": {
"blockPixelBytes": "16"
},
"ASTC_10x8_UNORM_BLOCK": {
"blockPixelBytes": "16"
},
"ASTC_10x10_SRGB_BLOCK": {
"blockPixelBytes": "16"
},
"ASTC_10x10_UNORM_BLOCK": {
"blockPixelBytes": "16"
},
"ASTC_12x10_SRGB_BLOCK": {
"blockPixelBytes": "16"
},
"ASTC_12x10_UNORM_BLOCK": {
"blockPixelBytes": "16"
},
"ASTC_12x12_SRGB_BLOCK": {
"blockPixelBytes": "16"
},
"ASTC_12x12_UNORM_BLOCK": {
"blockPixelBytes": "16"
},
"BC1_RGB_UNORM_BLOCK": {
"blockPixelBytes": "8"
},
"BC1_RGBA_UNORM_BLOCK": {
"blockPixelBytes": "8"
},
"BC1_RGBA_UNORM_SRGB_BLOCK": {
"blockPixelBytes": "8"
},
"BC1_RGB_UNORM_SRGB_BLOCK": {
"blockPixelBytes": "8"
},
"BC2_RGBA_UNORM_BLOCK": {
"blockPixelBytes": "16"
},
"BC2_RGBA_UNORM_SRGB_BLOCK": {
"blockPixelBytes": "16"
},
"BC3_RGBA_UNORM_BLOCK": {
"blockPixelBytes": "16"
},
"BC3_RGBA_UNORM_SRGB_BLOCK": {
"blockPixelBytes": "16"
},
"BPTC_SRGB_ALPHA_UNORM_BLOCK": {
"blockPixelBytes": "16"
},
"BPTC_RGB_SIGNED_FLOAT_BLOCK": {
"blockPixelBytes": "16"
},
"BPTC_RGB_UNSIGNED_FLOAT_BLOCK": {
"blockPixelBytes": "16"
},
"BPTC_RGBA_UNORM_BLOCK": {
"blockPixelBytes": "16"
},
"EAC_R11_SNORM_BLOCK": {
"blockPixelBytes": "8"
},
"EAC_R11_UNORM_BLOCK": {
"blockPixelBytes": "8"
},
"EAC_R11G11_SNORM_BLOCK": {
"blockPixelBytes": "16"
},
"EAC_R11G11_UNORM_BLOCK": {
"blockPixelBytes": "16"
},
"ETC1_R8G8B8_UNORM_BLOCK": {
"blockPixelBytes": "8"
},
"ETC1_LOSSY_DECODE_R8G8B8_UNORM_BLOCK": {
"blockPixelBytes": "8"
},
"ETC2_R8G8B8_SRGB_BLOCK": {
"blockPixelBytes": "8"
},
"ETC2_R8G8B8_UNORM_BLOCK": {
"blockPixelBytes": "8"
},
"ETC2_R8G8B8A1_SRGB_BLOCK": {
"blockPixelBytes": "8"
},
"ETC2_R8G8B8A1_UNORM_BLOCK": {
"blockPixelBytes": "8"
},
"ETC2_R8G8B8A8_UNORM_BLOCK": {
"blockPixelBytes": "16"
},
"ETC2_R8G8B8A8_SRGB_BLOCK": {
"blockPixelBytes": "16"
}
}
......@@ -259,13 +259,23 @@ def json_to_table_data(format_id, json, angle_to_gl):
if format_id == "B8G8R8A8_UNORM":
parsed["fastCopyFunctions"] = "BGRACopyFunctions"
sum_of_bits = 0
for channel in angle_format.kChannels:
sum_of_bits += int(parsed[channel])
parsed["pixelBytes"] = sum_of_bits / 8
is_block = format_id.endswith("_BLOCK")
pixel_bytes = 0
if is_block:
assert 'blockPixelBytes' in parsed, \
'Compressed format %s requires its block size to be specified in angle_format_data.json' % \
format_id
pixel_bytes = parsed['blockPixelBytes']
else:
sum_of_bits = 0
for channel in angle_format.kChannels:
sum_of_bits += int(parsed[channel])
pixel_bytes = sum_of_bits / 8
parsed["pixelBytes"] = pixel_bytes
parsed["componentAlignmentMask"] = get_component_alignment_mask(
parsed["channels"], parsed["bits"])
parsed["isBlock"] = "true" if format_id.endswith("_BLOCK") else "false"
parsed["isBlock"] = "true" if is_block else "false"
parsed["isFixed"] = "true" if "FIXED" in format_id else "false"
return format_entry_template.format(**parsed)
......
......@@ -64,17 +64,16 @@ egl::Error ImageVk::initialize(const egl::Display *display)
}
else
{
RendererVk *renderer = nullptr;
if (egl::IsRenderbufferTarget(mState.target))
{
RenderbufferVk *renderbufferVk =
GetImplAs<RenderbufferVk>(GetAs<gl::Renderbuffer>(mState.source));
mImage = renderbufferVk->getImage();
// Make sure a staging buffer is ready to use to upload data
ASSERT(mContext != nullptr);
ContextVk *contextVk = vk::GetImpl(mContext);
RendererVk *renderer = contextVk->getRenderer();
mImage->initStagingBuffer(renderer);
renderer = vk::GetImpl(mContext)->getRenderer();
;
}
else if (egl::IsExternalImageTarget(mState.target))
{
......@@ -82,11 +81,8 @@ egl::Error ImageVk::initialize(const egl::Display *display)
GetImplAs<ExternalImageSiblingVk>(GetAs<egl::ExternalImageSibling>(mState.source));
mImage = externalImageSibling->getImage();
// Make sure a staging buffer is ready to use to upload data
ASSERT(mContext == nullptr);
DisplayVk *displayVk = vk::GetImpl(display);
RendererVk *renderer = displayVk->getRenderer();
mImage->initStagingBuffer(renderer);
renderer = vk::GetImpl(display)->getRenderer();
}
else
{
......@@ -94,6 +90,9 @@ egl::Error ImageVk::initialize(const egl::Display *display)
return egl::EglBadAccess();
}
// Make sure a staging buffer is ready to use to upload data
mImage->initStagingBuffer(renderer, mImage->getFormat());
mOwnsImage = false;
mImageTextureType = gl::TextureType::_2D;
......
......@@ -958,23 +958,23 @@ angle::Result RendererVk::initializeDevice(DisplayVk *displayVk, uint32_t queueF
divisorFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT;
divisorFeatures.vertexAttributeInstanceRateDivisor = true;
float zeroPriority = 0.0f;
float zeroPriority = 0.0f;
VkDeviceQueueCreateInfo queueCreateInfo = {};
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueCreateInfo.flags = 0;
queueCreateInfo.queueFamilyIndex = queueFamilyIndex;
queueCreateInfo.queueCount = 1;
queueCreateInfo.pQueuePriorities = &zeroPriority;
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueCreateInfo.flags = 0;
queueCreateInfo.queueFamilyIndex = queueFamilyIndex;
queueCreateInfo.queueCount = 1;
queueCreateInfo.pQueuePriorities = &zeroPriority;
// Initialize the device
VkDeviceCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
createInfo.flags = 0;
createInfo.queueCreateInfoCount = 1;
createInfo.pQueueCreateInfos = &queueCreateInfo;
createInfo.enabledLayerCount = enabledDeviceLayerNames.size();
createInfo.ppEnabledLayerNames = enabledDeviceLayerNames.data();
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
createInfo.flags = 0;
createInfo.queueCreateInfoCount = 1;
createInfo.pQueueCreateInfos = &queueCreateInfo;
createInfo.enabledLayerCount = enabledDeviceLayerNames.size();
createInfo.ppEnabledLayerNames = enabledDeviceLayerNames.data();
if (vkGetPhysicalDeviceProperties2KHR &&
ExtensionFound(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, deviceExtensionNames))
......
......@@ -87,6 +87,9 @@ class TextureVk : public TextureImpl
bool unpackUnmultiplyAlpha,
const gl::Texture *source) override;
angle::Result copyCompressedTexture(const gl::Context *context,
const gl::Texture *source) override;
angle::Result setStorage(const gl::Context *context,
gl::TextureType type,
size_t levels,
......@@ -158,19 +161,36 @@ class TextureVk : public TextureImpl
uint32_t getNativeImageLayer(uint32_t frontendLayer) const;
void releaseAndDeleteImage(const gl::Context *context, RendererVk *renderer);
angle::Result ensureImageAllocated(RendererVk *renderer);
angle::Result ensureImageAllocated(RendererVk *renderer, const vk::Format &format);
void setImageHelper(RendererVk *renderer,
vk::ImageHelper *imageHelper,
gl::TextureType imageType,
const vk::Format &format,
uint32_t imageLevelOffset,
uint32_t imageLayerOffset,
bool selfOwned);
void updateImageHelper(RendererVk *renderer, const vk::Format &internalFormat);
angle::Result redefineImage(const gl::Context *context,
const gl::ImageIndex &index,
const gl::InternalFormat &internalFormat,
const vk::Format &format,
const gl::Extents &size);
angle::Result setImageImpl(const gl::Context *context,
const gl::ImageIndex &index,
const gl::InternalFormat &formatInfo,
const gl::Extents &size,
GLenum type,
const gl::PixelUnpackState &unpack,
const uint8_t *pixels);
angle::Result setSubImageImpl(const gl::Context *context,
const gl::ImageIndex &index,
const gl::Box &area,
const gl::InternalFormat &formatInfo,
GLenum type,
const gl::PixelUnpackState &unpack,
const uint8_t *pixels);
angle::Result copyImageDataToBuffer(ContextVk *contextVk,
size_t sourceLevel,
uint32_t layerCount,
......
......@@ -45,12 +45,13 @@ void RendererVk::ensureCapsInitialized() const
mNativeExtensions.textureStorage = true;
mNativeExtensions.framebufferBlit = true;
mNativeExtensions.copyTexture = true;
mNativeExtensions.copyCompressedTexture = true;
mNativeExtensions.debugMarker = true;
mNativeExtensions.robustness = true;
mNativeExtensions.textureBorderClamp = false; // not implemented yet
mNativeExtensions.translatedShaderSource = true;
mNativeExtensions.eglImage = true;
mNativeExtensions.eglImage = true;
mNativeExtensions.eglImageExternal = true;
// TODO(geofflang): Support GL_OES_EGL_image_external_essl3. http://anglebug.com/2668
mNativeExtensions.eglImageExternalEssl3 = false;
......
......@@ -138,21 +138,17 @@
"D24_UNORM_S8_UINT": "VK_FORMAT_D24_UNORM_S8_UINT",
"D32_FLOAT_S8X24_UINT": "VK_FORMAT_D32_SFLOAT_S8_UINT",
"BC1_RGB_UNORM_BLOCK": "VK_FORMAT_BC1_RGB_UNORM_BLOCK",
"BC1_RGB_SRGB_BLOCK": "VK_FORMAT_BC1_RGB_SRGB_BLOCK",
"BC1_RGB_UNORM_SRGB_BLOCK": "VK_FORMAT_BC1_RGB_SRGB_BLOCK",
"BC1_RGBA_UNORM_BLOCK": "VK_FORMAT_BC1_RGBA_UNORM_BLOCK",
"BC1_RGBA_SRGB_BLOCK": "VK_FORMAT_BC1_RGBA_SRGB_BLOCK",
"BC2_UNORM_BLOCK": "VK_FORMAT_BC2_UNORM_BLOCK",
"BC2_SRGB_BLOCK": "VK_FORMAT_BC2_SRGB_BLOCK",
"BC3_UNORM_BLOCK": "VK_FORMAT_BC3_UNORM_BLOCK",
"BC3_SRGB_BLOCK": "VK_FORMAT_BC3_SRGB_BLOCK",
"BC4_UNORM_BLOCK": "VK_FORMAT_BC4_UNORM_BLOCK",
"BC4_SNORM_BLOCK": "VK_FORMAT_BC4_SNORM_BLOCK",
"BC5_UNORM_BLOCK": "VK_FORMAT_BC5_UNORM_BLOCK",
"BC5_SNORM_BLOCK": "VK_FORMAT_BC5_SNORM_BLOCK",
"BC6H_UFLOAT_BLOCK": "VK_FORMAT_BC6H_UFLOAT_BLOCK",
"BC6H_SFLOAT_BLOCK": "VK_FORMAT_BC6H_SFLOAT_BLOCK",
"BC7_UNORM_BLOCK": "VK_FORMAT_BC7_UNORM_BLOCK",
"BC7_SRGB_BLOCK": "VK_FORMAT_BC7_SRGB_BLOCK",
"BC1_RGBA_UNORM_SRGB_BLOCK": "VK_FORMAT_BC1_RGBA_SRGB_BLOCK",
"BC2_RGBA_UNORM_BLOCK": "VK_FORMAT_BC2_UNORM_BLOCK",
"BC2_RGBA_UNORM_SRGB_BLOCK": "VK_FORMAT_BC2_SRGB_BLOCK",
"BC3_RGBA_UNORM_BLOCK": "VK_FORMAT_BC3_UNORM_BLOCK",
"BC3_RGBA_UNORM_SRGB_BLOCK": "VK_FORMAT_BC3_SRGB_BLOCK",
"BPTC_RGB_UNSIGNED_FLOAT_BLOCK": "VK_FORMAT_BC6H_UFLOAT_BLOCK",
"BPTC_RGB_SIGNED_FLOAT_BLOCK": "VK_FORMAT_BC6H_SFLOAT_BLOCK",
"BPTC_RGBA_UNORM_BLOCK": "VK_FORMAT_BC7_UNORM_BLOCK",
"BPTC_SRGB_ALPHA_UNORM_BLOCK": "VK_FORMAT_BC7_SRGB_BLOCK",
"ETC2_R8G8B8_UNORM_BLOCK": "VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK",
"ETC2_R8G8B8_SRGB_BLOCK": "VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK",
"ETC2_R8G8B8A1_UNORM_BLOCK": "VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK",
......
......@@ -491,7 +491,15 @@ void Format::initialize(RendererVk *renderer, const angle::Format &angleFormat)
break;
case angle::FormatID::BC1_RGBA_UNORM_SRGB_BLOCK:
// This format is not implemented in Vulkan.
internalFormat = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
textureFormatID = angle::FormatID::BC1_RGBA_UNORM_SRGB_BLOCK;
vkTextureFormat = VK_FORMAT_BC1_RGBA_SRGB_BLOCK;
textureInitializerFunction = nullptr;
bufferFormatID = angle::FormatID::BC1_RGBA_UNORM_SRGB_BLOCK;
vkBufferFormat = VK_FORMAT_BC1_RGBA_SRGB_BLOCK;
vkBufferFormatIsPacked = false;
vertexLoadFunction = nullptr;
vertexLoadRequiresConversion = false;
break;
case angle::FormatID::BC1_RGB_UNORM_BLOCK:
......@@ -507,39 +515,111 @@ void Format::initialize(RendererVk *renderer, const angle::Format &angleFormat)
break;
case angle::FormatID::BC1_RGB_UNORM_SRGB_BLOCK:
// This format is not implemented in Vulkan.
internalFormat = GL_COMPRESSED_SRGB_S3TC_DXT1_EXT;
textureFormatID = angle::FormatID::BC1_RGB_UNORM_SRGB_BLOCK;
vkTextureFormat = VK_FORMAT_BC1_RGB_SRGB_BLOCK;
textureInitializerFunction = nullptr;
bufferFormatID = angle::FormatID::BC1_RGB_UNORM_SRGB_BLOCK;
vkBufferFormat = VK_FORMAT_BC1_RGB_SRGB_BLOCK;
vkBufferFormatIsPacked = false;
vertexLoadFunction = nullptr;
vertexLoadRequiresConversion = false;
break;
case angle::FormatID::BC2_RGBA_UNORM_BLOCK:
// This format is not implemented in Vulkan.
internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE;
textureFormatID = angle::FormatID::BC2_RGBA_UNORM_BLOCK;
vkTextureFormat = VK_FORMAT_BC2_UNORM_BLOCK;
textureInitializerFunction = nullptr;
bufferFormatID = angle::FormatID::BC2_RGBA_UNORM_BLOCK;
vkBufferFormat = VK_FORMAT_BC2_UNORM_BLOCK;
vkBufferFormatIsPacked = false;
vertexLoadFunction = nullptr;
vertexLoadRequiresConversion = false;
break;
case angle::FormatID::BC2_RGBA_UNORM_SRGB_BLOCK:
// This format is not implemented in Vulkan.
internalFormat = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
textureFormatID = angle::FormatID::BC2_RGBA_UNORM_SRGB_BLOCK;
vkTextureFormat = VK_FORMAT_BC2_SRGB_BLOCK;
textureInitializerFunction = nullptr;
bufferFormatID = angle::FormatID::BC2_RGBA_UNORM_SRGB_BLOCK;
vkBufferFormat = VK_FORMAT_BC2_SRGB_BLOCK;
vkBufferFormatIsPacked = false;
vertexLoadFunction = nullptr;
vertexLoadRequiresConversion = false;
break;
case angle::FormatID::BC3_RGBA_UNORM_BLOCK:
// This format is not implemented in Vulkan.
internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE;
textureFormatID = angle::FormatID::BC3_RGBA_UNORM_BLOCK;
vkTextureFormat = VK_FORMAT_BC3_UNORM_BLOCK;
textureInitializerFunction = nullptr;
bufferFormatID = angle::FormatID::BC3_RGBA_UNORM_BLOCK;
vkBufferFormat = VK_FORMAT_BC3_UNORM_BLOCK;
vkBufferFormatIsPacked = false;
vertexLoadFunction = nullptr;
vertexLoadRequiresConversion = false;
break;
case angle::FormatID::BC3_RGBA_UNORM_SRGB_BLOCK:
// This format is not implemented in Vulkan.
internalFormat = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
textureFormatID = angle::FormatID::BC3_RGBA_UNORM_SRGB_BLOCK;
vkTextureFormat = VK_FORMAT_BC3_SRGB_BLOCK;
textureInitializerFunction = nullptr;
bufferFormatID = angle::FormatID::BC3_RGBA_UNORM_SRGB_BLOCK;
vkBufferFormat = VK_FORMAT_BC3_SRGB_BLOCK;
vkBufferFormatIsPacked = false;
vertexLoadFunction = nullptr;
vertexLoadRequiresConversion = false;
break;
case angle::FormatID::BPTC_RGBA_UNORM_BLOCK:
// This format is not implemented in Vulkan.
internalFormat = GL_COMPRESSED_RGBA_BPTC_UNORM_EXT;
textureFormatID = angle::FormatID::BPTC_RGBA_UNORM_BLOCK;
vkTextureFormat = VK_FORMAT_BC7_UNORM_BLOCK;
textureInitializerFunction = nullptr;
bufferFormatID = angle::FormatID::BPTC_RGBA_UNORM_BLOCK;
vkBufferFormat = VK_FORMAT_BC7_UNORM_BLOCK;
vkBufferFormatIsPacked = false;
vertexLoadFunction = nullptr;
vertexLoadRequiresConversion = false;
break;
case angle::FormatID::BPTC_RGB_SIGNED_FLOAT_BLOCK:
// This format is not implemented in Vulkan.
internalFormat = GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT;
textureFormatID = angle::FormatID::BPTC_RGB_SIGNED_FLOAT_BLOCK;
vkTextureFormat = VK_FORMAT_BC6H_SFLOAT_BLOCK;
textureInitializerFunction = nullptr;
bufferFormatID = angle::FormatID::BPTC_RGB_SIGNED_FLOAT_BLOCK;
vkBufferFormat = VK_FORMAT_BC6H_SFLOAT_BLOCK;
vkBufferFormatIsPacked = false;
vertexLoadFunction = nullptr;
vertexLoadRequiresConversion = false;
break;
case angle::FormatID::BPTC_RGB_UNSIGNED_FLOAT_BLOCK:
// This format is not implemented in Vulkan.
internalFormat = GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT;
textureFormatID = angle::FormatID::BPTC_RGB_UNSIGNED_FLOAT_BLOCK;
vkTextureFormat = VK_FORMAT_BC6H_UFLOAT_BLOCK;
textureInitializerFunction = nullptr;
bufferFormatID = angle::FormatID::BPTC_RGB_UNSIGNED_FLOAT_BLOCK;
vkBufferFormat = VK_FORMAT_BC6H_UFLOAT_BLOCK;
vkBufferFormatIsPacked = false;
vertexLoadFunction = nullptr;
vertexLoadRequiresConversion = false;
break;
case angle::FormatID::BPTC_SRGB_ALPHA_UNORM_BLOCK:
// This format is not implemented in Vulkan.
internalFormat = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT;
textureFormatID = angle::FormatID::BPTC_SRGB_ALPHA_UNORM_BLOCK;
vkTextureFormat = VK_FORMAT_BC7_SRGB_BLOCK;
textureInitializerFunction = nullptr;
bufferFormatID = angle::FormatID::BPTC_SRGB_ALPHA_UNORM_BLOCK;
vkBufferFormat = VK_FORMAT_BC7_SRGB_BLOCK;
vkBufferFormatIsPacked = false;
vertexLoadFunction = nullptr;
vertexLoadRequiresConversion = false;
break;
case angle::FormatID::D16_UNORM:
......
......@@ -142,6 +142,42 @@ void Format::initBufferFallback(RendererVk *renderer, const BufferFormatInitInfo
vertexLoadRequiresConversion = info[i].vertexLoadRequiresConversion;
}
size_t Format::getImageCopyBufferAlignment() const
{
// vkCmdCopyBufferToImage must have an offset that is a multiple of 4 as well as a multiple
// of the pixel block size.
// https://www.khronos.org/registry/vulkan/specs/1.0/man/html/VkBufferImageCopy.html
//
// We need lcm(4, blockSize) (lcm = least common multiplier). Since 4 is constant, this
// can be calculated as:
//
// | blockSize blockSize % 4 == 0
// | 4 * blockSize blockSize % 4 == 1
// lcm(4, blockSize) = <
// | 2 * blockSize blockSize % 4 == 2
// | 4 * blockSize blockSize % 4 == 3
//
// This means:
//
// - blockSize % 2 != 0 gives a 4x multiplier
// - else blockSize % 4 != 0 gives a 2x multiplier
// - else there's no multiplier.
//
const angle::Format &format = textureFormat();
if (!format.isBlock)
{
// Currently, 4 is sufficient for any known non-block format.
return 4;
}
const size_t blockSize = format.pixelBytes;
const size_t multiplier = blockSize % 2 != 0 ? 4 : blockSize % 4 != 0 ? 2 : 1;
const size_t alignment = multiplier * blockSize;
return alignment;
}
bool operator==(const Format &lhs, const Format &rhs)
{
return &lhs == &rhs;
......@@ -216,6 +252,14 @@ void MapSwizzleState(const vk::Format &format,
{
const angle::Format &angleFormat = format.angleFormat();
if (angleFormat.isBlock)
{
// No need to override swizzles for compressed images, as they are not emulated.
// Either way, angleFormat.xBits (with x in {red, green, blue, alpha}) is zero for blocked
// formats so the following code would incorrectly turn its swizzle to (0, 0, 0, 1).
return;
}
switch (format.internalFormat)
{
case GL_LUMINANCE8_OES:
......
......@@ -66,6 +66,13 @@ struct Format final : private angle::NonCopyable
const angle::Format &textureFormat() const { return angle::Format::Get(textureFormatID); }
const angle::Format &bufferFormat() const { return angle::Format::Get(bufferFormatID); }
// Get buffer alignment for image-copy operations (to or from a buffer).
const gl::InternalFormat &getInternalFormatInfo(GLenum type) const
{
return gl::GetInternalFormatInfo(internalFormat, type);
}
size_t getImageCopyBufferAlignment() const;
angle::FormatID angleFormatID;
GLenum internalFormat;
angle::FormatID textureFormatID;
......
......@@ -240,10 +240,7 @@ void DynamicBuffer::init(size_t alignment, RendererVk *renderer)
mMinSize = std::min<size_t>(mMinSize, 0x1000);
}
ASSERT(alignment > 0);
mAlignment = std::max(
alignment,
static_cast<size_t>(renderer->getPhysicalDeviceProperties().limits.nonCoherentAtomSize));
updateAlignment(renderer, alignment);
}
DynamicBuffer::~DynamicBuffer()
......@@ -404,6 +401,27 @@ void DynamicBuffer::destroy(VkDevice device)
}
}
void DynamicBuffer::updateAlignment(RendererVk *renderer, size_t alignment)
{
ASSERT(alignment > 0);
size_t atomSize =
static_cast<size_t>(renderer->getPhysicalDeviceProperties().limits.nonCoherentAtomSize);
// We need lcm(alignment, atomSize), we are assuming one divides the other so std::max() could
// be used instead.
ASSERT(alignment % atomSize == 0 || atomSize % alignment == 0);
alignment = std::max(alignment, atomSize);
// If alignment has changed, make sure the next allocation is done at an aligned offset.
if (alignment != mAlignment)
{
mNextAllocationOffset = roundUp(mNextAllocationOffset, static_cast<uint32_t>(alignment));
}
mAlignment = alignment;
}
void DynamicBuffer::setMinimumSizeForTesting(size_t minSize)
{
// This will really only have an effect next time we call allocate.
......@@ -1249,11 +1267,9 @@ ImageHelper::~ImageHelper()
ASSERT(!valid());
}
void ImageHelper::initStagingBuffer(RendererVk *renderer)
void ImageHelper::initStagingBuffer(RendererVk *renderer, const vk::Format &format)
{
// vkCmdCopyBufferToImage must have an offset that is a multiple of 4.
// https://www.khronos.org/registry/vulkan/specs/1.0/man/html/VkBufferImageCopy.html
mStagingBuffer.init(4, renderer);
mStagingBuffer.updateAlignment(renderer, format.getImageCopyBufferAlignment());
}
angle::Result ImageHelper::init(Context *context,
......@@ -1816,8 +1832,47 @@ angle::Result ImageHelper::stageSubresourceUpdate(ContextVk *contextVk,
const vk::Format &vkFormat = renderer->getFormat(formatInfo.sizedInternalFormat);
const angle::Format &storageFormat = vkFormat.textureFormat();
size_t outputRowPitch = storageFormat.pixelBytes * extents.width;
size_t outputDepthPitch = outputRowPitch * extents.height;
size_t outputRowPitch;
size_t outputDepthPitch;
uint32_t bufferRowLength;
uint32_t bufferImageHeight;
if (storageFormat.isBlock)
{
const gl::InternalFormat &storageFormatInfo = vkFormat.getInternalFormatInfo(type);
GLuint rowPitch;
GLuint depthPitch;
ANGLE_VK_CHECK_MATH(contextVk, storageFormatInfo.computeCompressedImageSize(
gl::Extents(extents.width, 1, 1), &rowPitch));
ANGLE_VK_CHECK_MATH(contextVk,
storageFormatInfo.computeCompressedImageSize(
gl::Extents(extents.width, extents.height, 1), &depthPitch));
outputRowPitch = rowPitch;
outputDepthPitch = depthPitch;
angle::CheckedNumeric<uint32_t> checkedRowLength =
rx::CheckedRoundUp<uint32_t>(extents.width, storageFormatInfo.compressedBlockWidth);
angle::CheckedNumeric<uint32_t> checkedImageHeight =
rx::CheckedRoundUp<uint32_t>(extents.height, storageFormatInfo.compressedBlockHeight);
ANGLE_VK_CHECK_MATH(contextVk, checkedRowLength.IsValid());
ANGLE_VK_CHECK_MATH(contextVk, checkedImageHeight.IsValid());
bufferRowLength = checkedRowLength.ValueOrDie();
bufferImageHeight = checkedImageHeight.ValueOrDie();
}
else
{
outputRowPitch = storageFormat.pixelBytes * extents.width;
outputDepthPitch = outputRowPitch * extents.height;
bufferRowLength = extents.width;
bufferImageHeight = extents.height;
ASSERT(storageFormat.pixelBytes != 0);
}
VkBuffer bufferHandle = VK_NULL_HANDLE;
......@@ -1837,8 +1892,8 @@ angle::Result ImageHelper::stageSubresourceUpdate(ContextVk *contextVk,
VkBufferImageCopy copy = {};
copy.bufferOffset = stagingOffset;
copy.bufferRowLength = extents.width;
copy.bufferImageHeight = extents.height;
copy.bufferRowLength = bufferRowLength;
copy.bufferImageHeight = bufferImageHeight;
copy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
copy.imageSubresource.mipLevel = index.getLevelIndex();
copy.imageSubresource.baseArrayLayer = index.hasLayer() ? index.getLayerIndex() : 0;
......@@ -2054,9 +2109,6 @@ angle::Result ImageHelper::flushStagedUpdates(Context *context,
}
else
{
// Note: currently, the staging images are only made through color attachment writes. If
// they were written to otherwise in the future, the src stage of this transition should
// be adjusted appropriately.
update.image.image->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT,
vk::ImageLayout::TransferSrc, commandBuffer);
......
......@@ -67,6 +67,9 @@ class DynamicBuffer : angle::NonCopyable
BufferHelper *getCurrentBuffer() { return mBuffer; }
size_t getAlignment() { return mAlignment; }
void updateAlignment(RendererVk *renderer, size_t alignment);
// For testing only!
void setMinimumSizeForTesting(size_t minSize);
......@@ -525,7 +528,7 @@ class ImageHelper final : public CommandGraphResource
ImageHelper(ImageHelper &&other);
~ImageHelper() override;
void initStagingBuffer(RendererVk *renderer);
void initStagingBuffer(RendererVk *renderer, const vk::Format &format);
angle::Result init(Context *context,
gl::TextureType textureType,
......
......@@ -260,6 +260,8 @@ TEST_P(CopyCompressedTextureTest, InvalidTextureIds)
return;
}
ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_EXT_texture_compression_dxt1"));
glBindTexture(GL_TEXTURE_2D, mTextures[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
......@@ -297,6 +299,8 @@ TEST_P(CopyCompressedTextureTest, BindingPoints)
return;
}
ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_EXT_texture_compression_dxt1"));
glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[0]);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
......
......@@ -224,10 +224,89 @@ TEST_P(DXT1CompressedTextureTest, CopyTexSubImage2DDisallowed)
ASSERT_GL_ERROR(GL_INVALID_OPERATION);
}
class DXT1CompressedTextureTestES3 : public DXT1CompressedTextureTest
{};
TEST_P(DXT1CompressedTextureTest, PBOCompressedTexStorage)
{
ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_EXT_texture_compression_dxt1"));
ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
!extensionEnabled("GL_NV_pixel_buffer_object"));
ANGLE_SKIP_TEST_IF(
getClientMajorVersion() < 3 &&
(!extensionEnabled("GL_EXT_texture_storage") || !extensionEnabled("GL_OES_rgb8_rgba8")));
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
if (getClientMajorVersion() < 3)
{
glTexStorage2DEXT(GL_TEXTURE_2D, pixel_levels, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
pixel_0_width, pixel_0_height);
}
else
{
glTexStorage2D(GL_TEXTURE_2D, pixel_levels, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width,
pixel_0_height);
}
EXPECT_GL_NO_ERROR();
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
glBufferData(GL_PIXEL_UNPACK_BUFFER, pixel_0_size, nullptr, GL_STREAM_DRAW);
EXPECT_GL_NO_ERROR();
glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_0_size, pixel_0_data);
glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pixel_0_width, pixel_0_height,
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_size, nullptr);
glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_1_size, pixel_1_data);
glCompressedTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, pixel_1_width, pixel_1_height,
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_1_size, nullptr);
glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_2_size, pixel_2_data);
glCompressedTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, pixel_2_width, pixel_2_height,
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_2_size, nullptr);
glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_3_size, pixel_3_data);
glCompressedTexSubImage2D(GL_TEXTURE_2D, 3, 0, 0, pixel_3_width, pixel_3_height,
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_3_size, nullptr);
glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_4_size, pixel_4_data);
glCompressedTexSubImage2D(GL_TEXTURE_2D, 4, 0, 0, pixel_4_width, pixel_4_height,
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_4_size, nullptr);
glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_5_size, pixel_5_data);
glCompressedTexSubImage2D(GL_TEXTURE_2D, 5, 0, 0, pixel_5_width, pixel_5_height,
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_5_size, nullptr);
glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_6_size, pixel_6_data);
glCompressedTexSubImage2D(GL_TEXTURE_2D, 6, 0, 0, pixel_6_width, pixel_6_height,
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_6_size, nullptr);
glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_7_size, pixel_7_data);
glCompressedTexSubImage2D(GL_TEXTURE_2D, 7, 0, 0, pixel_7_width, pixel_7_height,
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_7_size, nullptr);
glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_8_size, pixel_8_data);
glCompressedTexSubImage2D(GL_TEXTURE_2D, 8, 0, 0, pixel_8_width, pixel_8_height,
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_8_size, nullptr);
glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_9_size, pixel_9_data);
glCompressedTexSubImage2D(GL_TEXTURE_2D, 9, 0, 0, pixel_9_width, pixel_9_height,
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_9_size, nullptr);
EXPECT_GL_NO_ERROR();
glUseProgram(mTextureProgram);
glUniform1i(mTextureUniformLocation, 0);
drawQuad(mTextureProgram, "position", 0.5f);
EXPECT_GL_NO_ERROR();
glDeleteTextures(1, &texture);
EXPECT_GL_NO_ERROR();
}
class DXT1CompressedTextureTestD3D11 : public DXT1CompressedTextureTest
class DXT1CompressedTextureTestES3 : public DXT1CompressedTextureTest
{};
TEST_P(DXT1CompressedTextureTestES3, PBOCompressedTexImage)
......@@ -321,90 +400,6 @@ TEST_P(DXT1CompressedTextureTestES3, CompressedTexSubImageValidation)
ASSERT_GL_ERROR(GL_INVALID_VALUE);
}
TEST_P(DXT1CompressedTextureTestD3D11, PBOCompressedTexStorage)
{
if (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_texture_compression_dxt1"))
{
return;
}
if (getClientMajorVersion() < 3 &&
(!extensionEnabled("GL_EXT_texture_storage") || !extensionEnabled("GL_OES_rgb8_rgba8")))
{
return;
}
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
if (getClientMajorVersion() < 3)
{
glTexStorage2DEXT(GL_TEXTURE_2D, pixel_levels, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
pixel_0_width, pixel_0_height);
}
else
{
glTexStorage2D(GL_TEXTURE_2D, pixel_levels, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width,
pixel_0_height);
}
EXPECT_GL_NO_ERROR();
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
glBufferData(GL_PIXEL_UNPACK_BUFFER, pixel_0_size, nullptr, GL_STREAM_DRAW);
EXPECT_GL_NO_ERROR();
glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_0_size, pixel_0_data);
glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pixel_0_width, pixel_0_height,
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_size, nullptr);
glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_1_size, pixel_1_data);
glCompressedTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, pixel_1_width, pixel_1_height,
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_1_size, nullptr);
glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_2_size, pixel_2_data);
glCompressedTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, pixel_2_width, pixel_2_height,
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_2_size, nullptr);
glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_3_size, pixel_3_data);
glCompressedTexSubImage2D(GL_TEXTURE_2D, 3, 0, 0, pixel_3_width, pixel_3_height,
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_3_size, nullptr);
glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_4_size, pixel_4_data);
glCompressedTexSubImage2D(GL_TEXTURE_2D, 4, 0, 0, pixel_4_width, pixel_4_height,
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_4_size, nullptr);
glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_5_size, pixel_5_data);
glCompressedTexSubImage2D(GL_TEXTURE_2D, 5, 0, 0, pixel_5_width, pixel_5_height,
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_5_size, nullptr);
glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_6_size, pixel_6_data);
glCompressedTexSubImage2D(GL_TEXTURE_2D, 6, 0, 0, pixel_6_width, pixel_6_height,
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_6_size, nullptr);
glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_7_size, pixel_7_data);
glCompressedTexSubImage2D(GL_TEXTURE_2D, 7, 0, 0, pixel_7_width, pixel_7_height,
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_7_size, nullptr);
glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_8_size, pixel_8_data);
glCompressedTexSubImage2D(GL_TEXTURE_2D, 8, 0, 0, pixel_8_width, pixel_8_height,
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_8_size, nullptr);
glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_9_size, pixel_9_data);
glCompressedTexSubImage2D(GL_TEXTURE_2D, 9, 0, 0, pixel_9_width, pixel_9_height,
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_9_size, nullptr);
EXPECT_GL_NO_ERROR();
glUseProgram(mTextureProgram);
glUniform1i(mTextureUniformLocation, 0);
drawQuad(mTextureProgram, "position", 0.5f);
EXPECT_GL_NO_ERROR();
glDeleteTextures(1, &texture);
EXPECT_GL_NO_ERROR();
}
// Test validation of glCompressedTexSubImage3D with DXT formats
TEST_P(DXT1CompressedTextureTestES3, CopyTexSubImage3DDisallowed)
{
......@@ -431,10 +426,9 @@ ANGLE_INSTANTIATE_TEST(DXT1CompressedTextureTest,
ES2_OPENGL(),
ES3_OPENGL(),
ES2_OPENGLES(),
ES3_OPENGLES());
ES3_OPENGLES(),
ES2_VULKAN());
// Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against.
ANGLE_INSTANTIATE_TEST(DXT1CompressedTextureTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
ANGLE_INSTANTIATE_TEST(DXT1CompressedTextureTestD3D11, ES2_D3D11(), ES3_D3D11(), ES2_D3D11_FL9_3());
......@@ -2573,9 +2573,6 @@ void main()
// Test dimension and image size validation of compressed textures
TEST_P(WebGLCompatibilityTest, CompressedTextureS3TC)
{
// Missing compressed Texture support. http://anglebug.com/2904
ANGLE_SKIP_TEST_IF(IsVulkan());
if (extensionRequestable("GL_EXT_texture_compression_dxt1"))
{
glRequestExtensionANGLE("GL_EXT_texture_compression_dxt1");
......@@ -4391,9 +4388,6 @@ void WebGLCompatibilityTest::validateCompressedTexImageExtensionFormat(GLenum fo
const std::string &extName,
bool subImageAllowed)
{
// Missing compressed Texture support. http://anglebug.com/2904
ANGLE_SKIP_TEST_IF(IsVulkan());
std::vector<GLubyte> data(blockSize, 0u);
GLTexture texture;
......
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