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 @@ ...@@ -2,11 +2,11 @@
"ANGLE format:src/libANGLE/renderer/angle_format.py": "ANGLE format:src/libANGLE/renderer/angle_format.py":
"b18ca0fe4835114a4a2f54977b19e798", "b18ca0fe4835114a4a2f54977b19e798",
"ANGLE format:src/libANGLE/renderer/angle_format_data.json": "ANGLE format:src/libANGLE/renderer/angle_format_data.json":
"1ab73531d2d9655e669b5560fb43c698", "288d2f350948f8b1928c249234a44b25",
"ANGLE format:src/libANGLE/renderer/angle_format_map.json": "ANGLE format:src/libANGLE/renderer/angle_format_map.json":
"be9f9bdbdf785dda05920146e8c55dbb", "be9f9bdbdf785dda05920146e8c55dbb",
"ANGLE format:src/libANGLE/renderer/gen_angle_format_table.py": "ANGLE format:src/libANGLE/renderer/gen_angle_format_table.py":
"809c5211278023fc159ff276d5fa6f7b", "00d5b2293e79d71e8d4212d1190a6426",
"ANGLE load functions table:src/libANGLE/renderer/gen_load_functions_table.py": "ANGLE load functions table:src/libANGLE/renderer/gen_load_functions_table.py":
"8afc7eecce2a3ba9f0b4beacb1aa7fe2", "8afc7eecce2a3ba9f0b4beacb1aa7fe2",
"ANGLE load functions table:src/libANGLE/renderer/load_functions_data.json": "ANGLE load functions table:src/libANGLE/renderer/load_functions_data.json":
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
"DXGI format:src/libANGLE/renderer/d3d/d3d11/gen_dxgi_format_table.py": "DXGI format:src/libANGLE/renderer/d3d/d3d11/gen_dxgi_format_table.py":
"8ea01df6cb7f160772d3c85dd5164890", "8ea01df6cb7f160772d3c85dd5164890",
"DXGI format:src/libANGLE/renderer/gen_angle_format_table.py": "DXGI format:src/libANGLE/renderer/gen_angle_format_table.py":
"809c5211278023fc159ff276d5fa6f7b", "00d5b2293e79d71e8d4212d1190a6426",
"ESSL static builtins:src/compiler/translator/builtin_function_declarations.txt": "ESSL static builtins:src/compiler/translator/builtin_function_declarations.txt":
"e5e567406476306ea06984d885be028d", "e5e567406476306ea06984d885be028d",
"ESSL static builtins:src/compiler/translator/builtin_variables.json": "ESSL static builtins:src/compiler/translator/builtin_variables.json":
...@@ -90,7 +90,7 @@ ...@@ -90,7 +90,7 @@
"Vulkan format:src/libANGLE/renderer/vulkan/gen_vk_format_table.py": "Vulkan format:src/libANGLE/renderer/vulkan/gen_vk_format_table.py":
"61a7752424595e24edff0c1f1784e18e", "61a7752424595e24edff0c1f1784e18e",
"Vulkan format:src/libANGLE/renderer/vulkan/vk_format_map.json": "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": "Vulkan internal shader programs:src/libANGLE/renderer/vulkan/gen_vk_internal_shaders.py":
"1c64f7187357d7561c984ec57d251e74", "1c64f7187357d7561c984ec57d251e74",
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/src/BufferUtils.comp": "Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/src/BufferUtils.comp":
......
...@@ -32,5 +32,161 @@ ...@@ -32,5 +32,161 @@
}, },
"B8G8R8A8_TYPELESS_SRGB": { "B8G8R8A8_TYPELESS_SRGB": {
"glInternalFormat": "GL_BGRA8_SRGB_ANGLEX" "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): ...@@ -259,13 +259,23 @@ def json_to_table_data(format_id, json, angle_to_gl):
if format_id == "B8G8R8A8_UNORM": if format_id == "B8G8R8A8_UNORM":
parsed["fastCopyFunctions"] = "BGRACopyFunctions" parsed["fastCopyFunctions"] = "BGRACopyFunctions"
sum_of_bits = 0 is_block = format_id.endswith("_BLOCK")
for channel in angle_format.kChannels:
sum_of_bits += int(parsed[channel]) pixel_bytes = 0
parsed["pixelBytes"] = sum_of_bits / 8 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["componentAlignmentMask"] = get_component_alignment_mask(
parsed["channels"], parsed["bits"]) 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" parsed["isFixed"] = "true" if "FIXED" in format_id else "false"
return format_entry_template.format(**parsed) return format_entry_template.format(**parsed)
......
...@@ -64,17 +64,16 @@ egl::Error ImageVk::initialize(const egl::Display *display) ...@@ -64,17 +64,16 @@ egl::Error ImageVk::initialize(const egl::Display *display)
} }
else else
{ {
RendererVk *renderer = nullptr;
if (egl::IsRenderbufferTarget(mState.target)) if (egl::IsRenderbufferTarget(mState.target))
{ {
RenderbufferVk *renderbufferVk = RenderbufferVk *renderbufferVk =
GetImplAs<RenderbufferVk>(GetAs<gl::Renderbuffer>(mState.source)); GetImplAs<RenderbufferVk>(GetAs<gl::Renderbuffer>(mState.source));
mImage = renderbufferVk->getImage(); mImage = renderbufferVk->getImage();
// Make sure a staging buffer is ready to use to upload data
ASSERT(mContext != nullptr); ASSERT(mContext != nullptr);
ContextVk *contextVk = vk::GetImpl(mContext); renderer = vk::GetImpl(mContext)->getRenderer();
RendererVk *renderer = contextVk->getRenderer(); ;
mImage->initStagingBuffer(renderer);
} }
else if (egl::IsExternalImageTarget(mState.target)) else if (egl::IsExternalImageTarget(mState.target))
{ {
...@@ -82,11 +81,8 @@ egl::Error ImageVk::initialize(const egl::Display *display) ...@@ -82,11 +81,8 @@ egl::Error ImageVk::initialize(const egl::Display *display)
GetImplAs<ExternalImageSiblingVk>(GetAs<egl::ExternalImageSibling>(mState.source)); GetImplAs<ExternalImageSiblingVk>(GetAs<egl::ExternalImageSibling>(mState.source));
mImage = externalImageSibling->getImage(); mImage = externalImageSibling->getImage();
// Make sure a staging buffer is ready to use to upload data
ASSERT(mContext == nullptr); ASSERT(mContext == nullptr);
DisplayVk *displayVk = vk::GetImpl(display); renderer = vk::GetImpl(display)->getRenderer();
RendererVk *renderer = displayVk->getRenderer();
mImage->initStagingBuffer(renderer);
} }
else else
{ {
...@@ -94,6 +90,9 @@ egl::Error ImageVk::initialize(const egl::Display *display) ...@@ -94,6 +90,9 @@ egl::Error ImageVk::initialize(const egl::Display *display)
return egl::EglBadAccess(); return egl::EglBadAccess();
} }
// Make sure a staging buffer is ready to use to upload data
mImage->initStagingBuffer(renderer, mImage->getFormat());
mOwnsImage = false; mOwnsImage = false;
mImageTextureType = gl::TextureType::_2D; mImageTextureType = gl::TextureType::_2D;
......
...@@ -958,23 +958,23 @@ angle::Result RendererVk::initializeDevice(DisplayVk *displayVk, uint32_t queueF ...@@ -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.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT;
divisorFeatures.vertexAttributeInstanceRateDivisor = true; divisorFeatures.vertexAttributeInstanceRateDivisor = true;
float zeroPriority = 0.0f; float zeroPriority = 0.0f;
VkDeviceQueueCreateInfo queueCreateInfo = {}; VkDeviceQueueCreateInfo queueCreateInfo = {};
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueCreateInfo.flags = 0; queueCreateInfo.flags = 0;
queueCreateInfo.queueFamilyIndex = queueFamilyIndex; queueCreateInfo.queueFamilyIndex = queueFamilyIndex;
queueCreateInfo.queueCount = 1; queueCreateInfo.queueCount = 1;
queueCreateInfo.pQueuePriorities = &zeroPriority; queueCreateInfo.pQueuePriorities = &zeroPriority;
// Initialize the device // Initialize the device
VkDeviceCreateInfo createInfo = {}; VkDeviceCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
createInfo.flags = 0; createInfo.flags = 0;
createInfo.queueCreateInfoCount = 1; createInfo.queueCreateInfoCount = 1;
createInfo.pQueueCreateInfos = &queueCreateInfo; createInfo.pQueueCreateInfos = &queueCreateInfo;
createInfo.enabledLayerCount = enabledDeviceLayerNames.size(); createInfo.enabledLayerCount = enabledDeviceLayerNames.size();
createInfo.ppEnabledLayerNames = enabledDeviceLayerNames.data(); createInfo.ppEnabledLayerNames = enabledDeviceLayerNames.data();
if (vkGetPhysicalDeviceProperties2KHR && if (vkGetPhysicalDeviceProperties2KHR &&
ExtensionFound(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, deviceExtensionNames)) ExtensionFound(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, deviceExtensionNames))
......
...@@ -87,6 +87,9 @@ class TextureVk : public TextureImpl ...@@ -87,6 +87,9 @@ class TextureVk : public TextureImpl
bool unpackUnmultiplyAlpha, bool unpackUnmultiplyAlpha,
const gl::Texture *source) override; const gl::Texture *source) override;
angle::Result copyCompressedTexture(const gl::Context *context,
const gl::Texture *source) override;
angle::Result setStorage(const gl::Context *context, angle::Result setStorage(const gl::Context *context,
gl::TextureType type, gl::TextureType type,
size_t levels, size_t levels,
...@@ -158,19 +161,36 @@ class TextureVk : public TextureImpl ...@@ -158,19 +161,36 @@ class TextureVk : public TextureImpl
uint32_t getNativeImageLayer(uint32_t frontendLayer) const; uint32_t getNativeImageLayer(uint32_t frontendLayer) const;
void releaseAndDeleteImage(const gl::Context *context, RendererVk *renderer); 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, void setImageHelper(RendererVk *renderer,
vk::ImageHelper *imageHelper, vk::ImageHelper *imageHelper,
gl::TextureType imageType, gl::TextureType imageType,
const vk::Format &format,
uint32_t imageLevelOffset, uint32_t imageLevelOffset,
uint32_t imageLayerOffset, uint32_t imageLayerOffset,
bool selfOwned); bool selfOwned);
void updateImageHelper(RendererVk *renderer, const vk::Format &internalFormat);
angle::Result redefineImage(const gl::Context *context, angle::Result redefineImage(const gl::Context *context,
const gl::ImageIndex &index, const gl::ImageIndex &index,
const gl::InternalFormat &internalFormat, const vk::Format &format,
const gl::Extents &size); 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, angle::Result copyImageDataToBuffer(ContextVk *contextVk,
size_t sourceLevel, size_t sourceLevel,
uint32_t layerCount, uint32_t layerCount,
......
...@@ -45,12 +45,13 @@ void RendererVk::ensureCapsInitialized() const ...@@ -45,12 +45,13 @@ void RendererVk::ensureCapsInitialized() const
mNativeExtensions.textureStorage = true; mNativeExtensions.textureStorage = true;
mNativeExtensions.framebufferBlit = true; mNativeExtensions.framebufferBlit = true;
mNativeExtensions.copyTexture = true; mNativeExtensions.copyTexture = true;
mNativeExtensions.copyCompressedTexture = true;
mNativeExtensions.debugMarker = true; mNativeExtensions.debugMarker = true;
mNativeExtensions.robustness = true; mNativeExtensions.robustness = true;
mNativeExtensions.textureBorderClamp = false; // not implemented yet mNativeExtensions.textureBorderClamp = false; // not implemented yet
mNativeExtensions.translatedShaderSource = true; mNativeExtensions.translatedShaderSource = true;
mNativeExtensions.eglImage = true; mNativeExtensions.eglImage = true;
mNativeExtensions.eglImageExternal = true; mNativeExtensions.eglImageExternal = true;
// TODO(geofflang): Support GL_OES_EGL_image_external_essl3. http://anglebug.com/2668 // TODO(geofflang): Support GL_OES_EGL_image_external_essl3. http://anglebug.com/2668
mNativeExtensions.eglImageExternalEssl3 = false; mNativeExtensions.eglImageExternalEssl3 = false;
......
...@@ -138,21 +138,17 @@ ...@@ -138,21 +138,17 @@
"D24_UNORM_S8_UINT": "VK_FORMAT_D24_UNORM_S8_UINT", "D24_UNORM_S8_UINT": "VK_FORMAT_D24_UNORM_S8_UINT",
"D32_FLOAT_S8X24_UINT": "VK_FORMAT_D32_SFLOAT_S8_UINT", "D32_FLOAT_S8X24_UINT": "VK_FORMAT_D32_SFLOAT_S8_UINT",
"BC1_RGB_UNORM_BLOCK": "VK_FORMAT_BC1_RGB_UNORM_BLOCK", "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_UNORM_BLOCK": "VK_FORMAT_BC1_RGBA_UNORM_BLOCK",
"BC1_RGBA_SRGB_BLOCK": "VK_FORMAT_BC1_RGBA_SRGB_BLOCK", "BC1_RGBA_UNORM_SRGB_BLOCK": "VK_FORMAT_BC1_RGBA_SRGB_BLOCK",
"BC2_UNORM_BLOCK": "VK_FORMAT_BC2_UNORM_BLOCK", "BC2_RGBA_UNORM_BLOCK": "VK_FORMAT_BC2_UNORM_BLOCK",
"BC2_SRGB_BLOCK": "VK_FORMAT_BC2_SRGB_BLOCK", "BC2_RGBA_UNORM_SRGB_BLOCK": "VK_FORMAT_BC2_SRGB_BLOCK",
"BC3_UNORM_BLOCK": "VK_FORMAT_BC3_UNORM_BLOCK", "BC3_RGBA_UNORM_BLOCK": "VK_FORMAT_BC3_UNORM_BLOCK",
"BC3_SRGB_BLOCK": "VK_FORMAT_BC3_SRGB_BLOCK", "BC3_RGBA_UNORM_SRGB_BLOCK": "VK_FORMAT_BC3_SRGB_BLOCK",
"BC4_UNORM_BLOCK": "VK_FORMAT_BC4_UNORM_BLOCK", "BPTC_RGB_UNSIGNED_FLOAT_BLOCK": "VK_FORMAT_BC6H_UFLOAT_BLOCK",
"BC4_SNORM_BLOCK": "VK_FORMAT_BC4_SNORM_BLOCK", "BPTC_RGB_SIGNED_FLOAT_BLOCK": "VK_FORMAT_BC6H_SFLOAT_BLOCK",
"BC5_UNORM_BLOCK": "VK_FORMAT_BC5_UNORM_BLOCK", "BPTC_RGBA_UNORM_BLOCK": "VK_FORMAT_BC7_UNORM_BLOCK",
"BC5_SNORM_BLOCK": "VK_FORMAT_BC5_SNORM_BLOCK", "BPTC_SRGB_ALPHA_UNORM_BLOCK": "VK_FORMAT_BC7_SRGB_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",
"ETC2_R8G8B8_UNORM_BLOCK": "VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK", "ETC2_R8G8B8_UNORM_BLOCK": "VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK",
"ETC2_R8G8B8_SRGB_BLOCK": "VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK", "ETC2_R8G8B8_SRGB_BLOCK": "VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK",
"ETC2_R8G8B8A1_UNORM_BLOCK": "VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK", "ETC2_R8G8B8A1_UNORM_BLOCK": "VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK",
......
...@@ -491,7 +491,15 @@ void Format::initialize(RendererVk *renderer, const angle::Format &angleFormat) ...@@ -491,7 +491,15 @@ void Format::initialize(RendererVk *renderer, const angle::Format &angleFormat)
break; break;
case angle::FormatID::BC1_RGBA_UNORM_SRGB_BLOCK: 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; break;
case angle::FormatID::BC1_RGB_UNORM_BLOCK: case angle::FormatID::BC1_RGB_UNORM_BLOCK:
...@@ -507,39 +515,111 @@ void Format::initialize(RendererVk *renderer, const angle::Format &angleFormat) ...@@ -507,39 +515,111 @@ void Format::initialize(RendererVk *renderer, const angle::Format &angleFormat)
break; break;
case angle::FormatID::BC1_RGB_UNORM_SRGB_BLOCK: 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; break;
case angle::FormatID::BC2_RGBA_UNORM_BLOCK: 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; break;
case angle::FormatID::BC2_RGBA_UNORM_SRGB_BLOCK: 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; break;
case angle::FormatID::BC3_RGBA_UNORM_BLOCK: 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; break;
case angle::FormatID::BC3_RGBA_UNORM_SRGB_BLOCK: 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; break;
case angle::FormatID::BPTC_RGBA_UNORM_BLOCK: 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; break;
case angle::FormatID::BPTC_RGB_SIGNED_FLOAT_BLOCK: 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; break;
case angle::FormatID::BPTC_RGB_UNSIGNED_FLOAT_BLOCK: 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; break;
case angle::FormatID::BPTC_SRGB_ALPHA_UNORM_BLOCK: 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; break;
case angle::FormatID::D16_UNORM: case angle::FormatID::D16_UNORM:
......
...@@ -142,6 +142,42 @@ void Format::initBufferFallback(RendererVk *renderer, const BufferFormatInitInfo ...@@ -142,6 +142,42 @@ void Format::initBufferFallback(RendererVk *renderer, const BufferFormatInitInfo
vertexLoadRequiresConversion = info[i].vertexLoadRequiresConversion; 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) bool operator==(const Format &lhs, const Format &rhs)
{ {
return &lhs == &rhs; return &lhs == &rhs;
...@@ -216,6 +252,14 @@ void MapSwizzleState(const vk::Format &format, ...@@ -216,6 +252,14 @@ void MapSwizzleState(const vk::Format &format,
{ {
const angle::Format &angleFormat = format.angleFormat(); 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) switch (format.internalFormat)
{ {
case GL_LUMINANCE8_OES: case GL_LUMINANCE8_OES:
......
...@@ -66,6 +66,13 @@ struct Format final : private angle::NonCopyable ...@@ -66,6 +66,13 @@ struct Format final : private angle::NonCopyable
const angle::Format &textureFormat() const { return angle::Format::Get(textureFormatID); } const angle::Format &textureFormat() const { return angle::Format::Get(textureFormatID); }
const angle::Format &bufferFormat() const { return angle::Format::Get(bufferFormatID); } 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; angle::FormatID angleFormatID;
GLenum internalFormat; GLenum internalFormat;
angle::FormatID textureFormatID; angle::FormatID textureFormatID;
......
...@@ -240,10 +240,7 @@ void DynamicBuffer::init(size_t alignment, RendererVk *renderer) ...@@ -240,10 +240,7 @@ void DynamicBuffer::init(size_t alignment, RendererVk *renderer)
mMinSize = std::min<size_t>(mMinSize, 0x1000); mMinSize = std::min<size_t>(mMinSize, 0x1000);
} }
ASSERT(alignment > 0); updateAlignment(renderer, alignment);
mAlignment = std::max(
alignment,
static_cast<size_t>(renderer->getPhysicalDeviceProperties().limits.nonCoherentAtomSize));
} }
DynamicBuffer::~DynamicBuffer() DynamicBuffer::~DynamicBuffer()
...@@ -404,6 +401,27 @@ void DynamicBuffer::destroy(VkDevice device) ...@@ -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) void DynamicBuffer::setMinimumSizeForTesting(size_t minSize)
{ {
// This will really only have an effect next time we call allocate. // This will really only have an effect next time we call allocate.
...@@ -1249,11 +1267,9 @@ ImageHelper::~ImageHelper() ...@@ -1249,11 +1267,9 @@ ImageHelper::~ImageHelper()
ASSERT(!valid()); 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. mStagingBuffer.updateAlignment(renderer, format.getImageCopyBufferAlignment());
// https://www.khronos.org/registry/vulkan/specs/1.0/man/html/VkBufferImageCopy.html
mStagingBuffer.init(4, renderer);
} }
angle::Result ImageHelper::init(Context *context, angle::Result ImageHelper::init(Context *context,
...@@ -1816,8 +1832,47 @@ angle::Result ImageHelper::stageSubresourceUpdate(ContextVk *contextVk, ...@@ -1816,8 +1832,47 @@ angle::Result ImageHelper::stageSubresourceUpdate(ContextVk *contextVk,
const vk::Format &vkFormat = renderer->getFormat(formatInfo.sizedInternalFormat); const vk::Format &vkFormat = renderer->getFormat(formatInfo.sizedInternalFormat);
const angle::Format &storageFormat = vkFormat.textureFormat(); const angle::Format &storageFormat = vkFormat.textureFormat();
size_t outputRowPitch = storageFormat.pixelBytes * extents.width; size_t outputRowPitch;
size_t outputDepthPitch = outputRowPitch * extents.height; 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; VkBuffer bufferHandle = VK_NULL_HANDLE;
...@@ -1837,8 +1892,8 @@ angle::Result ImageHelper::stageSubresourceUpdate(ContextVk *contextVk, ...@@ -1837,8 +1892,8 @@ angle::Result ImageHelper::stageSubresourceUpdate(ContextVk *contextVk,
VkBufferImageCopy copy = {}; VkBufferImageCopy copy = {};
copy.bufferOffset = stagingOffset; copy.bufferOffset = stagingOffset;
copy.bufferRowLength = extents.width; copy.bufferRowLength = bufferRowLength;
copy.bufferImageHeight = extents.height; copy.bufferImageHeight = bufferImageHeight;
copy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; copy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
copy.imageSubresource.mipLevel = index.getLevelIndex(); copy.imageSubresource.mipLevel = index.getLevelIndex();
copy.imageSubresource.baseArrayLayer = index.hasLayer() ? index.getLayerIndex() : 0; copy.imageSubresource.baseArrayLayer = index.hasLayer() ? index.getLayerIndex() : 0;
...@@ -2054,9 +2109,6 @@ angle::Result ImageHelper::flushStagedUpdates(Context *context, ...@@ -2054,9 +2109,6 @@ angle::Result ImageHelper::flushStagedUpdates(Context *context,
} }
else 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, update.image.image->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT,
vk::ImageLayout::TransferSrc, commandBuffer); vk::ImageLayout::TransferSrc, commandBuffer);
......
...@@ -67,6 +67,9 @@ class DynamicBuffer : angle::NonCopyable ...@@ -67,6 +67,9 @@ class DynamicBuffer : angle::NonCopyable
BufferHelper *getCurrentBuffer() { return mBuffer; } BufferHelper *getCurrentBuffer() { return mBuffer; }
size_t getAlignment() { return mAlignment; }
void updateAlignment(RendererVk *renderer, size_t alignment);
// For testing only! // For testing only!
void setMinimumSizeForTesting(size_t minSize); void setMinimumSizeForTesting(size_t minSize);
...@@ -525,7 +528,7 @@ class ImageHelper final : public CommandGraphResource ...@@ -525,7 +528,7 @@ class ImageHelper final : public CommandGraphResource
ImageHelper(ImageHelper &&other); ImageHelper(ImageHelper &&other);
~ImageHelper() override; ~ImageHelper() override;
void initStagingBuffer(RendererVk *renderer); void initStagingBuffer(RendererVk *renderer, const vk::Format &format);
angle::Result init(Context *context, angle::Result init(Context *context,
gl::TextureType textureType, gl::TextureType textureType,
......
...@@ -260,6 +260,8 @@ TEST_P(CopyCompressedTextureTest, InvalidTextureIds) ...@@ -260,6 +260,8 @@ TEST_P(CopyCompressedTextureTest, InvalidTextureIds)
return; return;
} }
ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_EXT_texture_compression_dxt1"));
glBindTexture(GL_TEXTURE_2D, mTextures[0]); 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_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
...@@ -297,6 +299,8 @@ TEST_P(CopyCompressedTextureTest, BindingPoints) ...@@ -297,6 +299,8 @@ TEST_P(CopyCompressedTextureTest, BindingPoints)
return; return;
} }
ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_EXT_texture_compression_dxt1"));
glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[0]); 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_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, 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) ...@@ -224,10 +224,89 @@ TEST_P(DXT1CompressedTextureTest, CopyTexSubImage2DDisallowed)
ASSERT_GL_ERROR(GL_INVALID_OPERATION); 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) TEST_P(DXT1CompressedTextureTestES3, PBOCompressedTexImage)
...@@ -321,90 +400,6 @@ TEST_P(DXT1CompressedTextureTestES3, CompressedTexSubImageValidation) ...@@ -321,90 +400,6 @@ TEST_P(DXT1CompressedTextureTestES3, CompressedTexSubImageValidation)
ASSERT_GL_ERROR(GL_INVALID_VALUE); 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 validation of glCompressedTexSubImage3D with DXT formats
TEST_P(DXT1CompressedTextureTestES3, CopyTexSubImage3DDisallowed) TEST_P(DXT1CompressedTextureTestES3, CopyTexSubImage3DDisallowed)
{ {
...@@ -431,10 +426,9 @@ ANGLE_INSTANTIATE_TEST(DXT1CompressedTextureTest, ...@@ -431,10 +426,9 @@ ANGLE_INSTANTIATE_TEST(DXT1CompressedTextureTest,
ES2_OPENGL(), ES2_OPENGL(),
ES3_OPENGL(), ES3_OPENGL(),
ES2_OPENGLES(), ES2_OPENGLES(),
ES3_OPENGLES()); ES3_OPENGLES(),
ES2_VULKAN());
// Use this to select which configurations (e.g. which renderer, which GLES major version) these // Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against. // tests should be run against.
ANGLE_INSTANTIATE_TEST(DXT1CompressedTextureTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); 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() ...@@ -2573,9 +2573,6 @@ void main()
// Test dimension and image size validation of compressed textures // Test dimension and image size validation of compressed textures
TEST_P(WebGLCompatibilityTest, CompressedTextureS3TC) TEST_P(WebGLCompatibilityTest, CompressedTextureS3TC)
{ {
// Missing compressed Texture support. http://anglebug.com/2904
ANGLE_SKIP_TEST_IF(IsVulkan());
if (extensionRequestable("GL_EXT_texture_compression_dxt1")) if (extensionRequestable("GL_EXT_texture_compression_dxt1"))
{ {
glRequestExtensionANGLE("GL_EXT_texture_compression_dxt1"); glRequestExtensionANGLE("GL_EXT_texture_compression_dxt1");
...@@ -4391,9 +4388,6 @@ void WebGLCompatibilityTest::validateCompressedTexImageExtensionFormat(GLenum fo ...@@ -4391,9 +4388,6 @@ void WebGLCompatibilityTest::validateCompressedTexImageExtensionFormat(GLenum fo
const std::string &extName, const std::string &extName,
bool subImageAllowed) bool subImageAllowed)
{ {
// Missing compressed Texture support. http://anglebug.com/2904
ANGLE_SKIP_TEST_IF(IsVulkan());
std::vector<GLubyte> data(blockSize, 0u); std::vector<GLubyte> data(blockSize, 0u);
GLTexture texture; 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