Commit cb16fb5f by Cody Northrop Committed by Commit Bot

Vulkan: Support texture base and max levels

The Vulkan backend uses a vkImage that matches the number of effective levels in the GL texture. This is due to the fact that GL textures can have really strange layouts that only make sense when base level and max level are applied. For instance, take the following layout with disjoint mip levels: Level 0: 4x4 RGBA Level 1: 2x2 RGBA Level 2: 10x10 RGB If base level is set to zero and max level is set to 1, the image is still considered mip-complete: Level 0: 4x4 RGBA ==> Base Level 0 ==> Level 0: 4x4 RGBA Level 1: 2x2 RGBA ==> Max Level 1 ==> Level 1: 2x2 RGBA Level 2: 10x10 RGB If base and max level are then both set to 2, the texture is still considered complete, but of a different size and format: Level 0: 4x4 RGBA Level 1: 2x2 RGBA Level 2: 10x10 RGB ==> Base/Max Level 2 ==> Level 2: 10x10 RGB When the base or max level is changed, we must recreate the vkImage to match the new level count. To support that, we: - Stage updates from the current image to the new image - Only stage updates if there aren't already staged updates for a level - Free the current image and so it can be recreated at the next draw This CL does the following: - Refactors TextureVk::copyImageDataToBuffer to support staging updates without flush - Adds TextureVk::copyImageDataToBufferAndGetData to support previous use model - Adds TextureVk::changeLevels, triggered during syncState, which stages updates and releases the current image. - Updates ImageHelper::flushStagedUpdates to understand base/max levels - Updates TextureVk::ensureImageInitialized and TextureVk::generateMipmap to account for base/max level - Tracks base and max levels in ImageHelper - Adds ImageHelper::stageSubresourceUpdateFromBuffer to support this use case - Adds ImageHelper::isUpdateStaged to determine if changeLevels should propagate data - Makes gl::TextureTypeToTarget available for use outside of ImageIndex - Enables several deqp and end2end tests Bug: angleproject:3148 Test: dEQP-GLES3.functional.texture.mipmap.*base_level* Test: dEQP-GLES3.functional.texture.mipmap.*max_level* Change-Id: I14ca071c9c62eb310dfed7ef9290dc65fc3ff696 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1776933Reviewed-by: 's avatarCourtney Goeltzenleuchter <courtneygo@google.com> Commit-Queue: Cody Northrop <cnorthrop@google.com>
parent 57b37b6b
...@@ -54,6 +54,19 @@ GLint TextureTargetToLayer(TextureTarget target) ...@@ -54,6 +54,19 @@ GLint TextureTargetToLayer(TextureTarget target)
} }
} }
bool IsArrayTarget(TextureTarget target)
{
switch (target)
{
case TextureTarget::_2DArray:
case TextureTarget::_2DMultisampleArray:
return true;
default:
return false;
}
}
} // anonymous namespace
TextureTarget TextureTypeToTarget(TextureType type, GLint layerIndex) TextureTarget TextureTypeToTarget(TextureType type, GLint layerIndex)
{ {
if (type == TextureType::CubeMap) if (type == TextureType::CubeMap)
...@@ -69,19 +82,6 @@ TextureTarget TextureTypeToTarget(TextureType type, GLint layerIndex) ...@@ -69,19 +82,6 @@ TextureTarget TextureTypeToTarget(TextureType type, GLint layerIndex)
} }
} }
bool IsArrayTarget(TextureTarget target)
{
switch (target)
{
case TextureTarget::_2DArray:
case TextureTarget::_2DMultisampleArray:
return true;
default:
return false;
}
}
} // anonymous namespace
ImageIndex::ImageIndex() ImageIndex::ImageIndex()
: mType(TextureType::InvalidEnum), mLevelIndex(0), mLayerIndex(0), mLayerCount(kEntireLevel) : mType(TextureType::InvalidEnum), mLevelIndex(0), mLayerIndex(0), mLayerCount(kEntireLevel)
{} {}
......
...@@ -123,6 +123,9 @@ class ImageIndexIterator ...@@ -123,6 +123,9 @@ class ImageIndexIterator
ImageIndex mCurrentIndex; ImageIndex mCurrentIndex;
}; };
TextureTarget TextureTypeToTarget(TextureType type, GLint layerIndex);
} // namespace gl } // namespace gl
#endif // LIBANGLE_IMAGE_INDEX_H_ #endif // LIBANGLE_IMAGE_INDEX_H_
...@@ -100,10 +100,10 @@ angle::Result MemoryObjectVk::createImage(const gl::Context *context, ...@@ -100,10 +100,10 @@ angle::Result MemoryObjectVk::createImage(const gl::Context *context,
uint32_t layerCount; uint32_t layerCount;
gl_vk::GetExtentsAndLayerCount(type, size, &vkExtents, &layerCount); gl_vk::GetExtentsAndLayerCount(type, size, &vkExtents, &layerCount);
ANGLE_TRY(image->initExternal(contextVk, type, vkExtents, vkFormat, 1, imageUsageFlags, ANGLE_TRY(image->initExternal(
vk::ImageLayout::ExternalPreInitialized, contextVk, type, vkExtents, vkFormat, 1, imageUsageFlags,
&externalMemoryImageCreateInfo, static_cast<uint32_t>(levels), vk::ImageLayout::ExternalPreInitialized, &externalMemoryImageCreateInfo, 0,
layerCount)); static_cast<uint32_t>(levels) - 1, static_cast<uint32_t>(levels), layerCount));
VkMemoryRequirements externalMemoryRequirements; VkMemoryRequirements externalMemoryRequirements;
image->getImage().getMemoryRequirements(renderer->getDevice(), &externalMemoryRequirements); image->getImage().getMemoryRequirements(renderer->getDevice(), &externalMemoryRequirements);
......
...@@ -107,11 +107,12 @@ angle::Result OverlayVk::createFont(ContextVk *contextVk) ...@@ -107,11 +107,12 @@ angle::Result OverlayVk::createFont(ContextVk *contextVk)
fontDataBuffer.get().onExternalWrite(VK_ACCESS_HOST_WRITE_BIT); fontDataBuffer.get().onExternalWrite(VK_ACCESS_HOST_WRITE_BIT);
// Create the font image. // Create the font image.
ANGLE_TRY(mFontImage.init( ANGLE_TRY(
contextVk, gl::TextureType::_2D, mFontImage.init(contextVk, gl::TextureType::_2D,
VkExtent3D{gl::overlay::kFontImageWidth, gl::overlay::kFontImageHeight, 1}, VkExtent3D{gl::overlay::kFontImageWidth, gl::overlay::kFontImageHeight, 1},
rendererVk->getFormat(angle::FormatID::R8_UNORM), 1, rendererVk->getFormat(angle::FormatID::R8_UNORM), 1,
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 1, gl::overlay::kFontCount)); VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 0, 0, 1,
gl::overlay::kFontCount));
ANGLE_TRY(mFontImage.initMemory(contextVk, rendererVk->getMemoryProperties(), ANGLE_TRY(mFontImage.initMemory(contextVk, rendererVk->getMemoryProperties(),
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)); VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
ANGLE_TRY(mFontImage.initImageView(contextVk, gl::TextureType::_2DArray, ANGLE_TRY(mFontImage.initImageView(contextVk, gl::TextureType::_2DArray,
...@@ -186,7 +187,8 @@ angle::Result OverlayVk::cullWidgets(ContextVk *contextVk) ...@@ -186,7 +187,8 @@ angle::Result OverlayVk::cullWidgets(ContextVk *contextVk)
ANGLE_TRY(mCulledWidgets.init(contextVk, gl::TextureType::_2D, culledWidgetsExtent, ANGLE_TRY(mCulledWidgets.init(contextVk, gl::TextureType::_2D, culledWidgetsExtent,
rendererVk->getFormat(angle::FormatID::R32G32_UINT), 1, rendererVk->getFormat(angle::FormatID::R32G32_UINT), 1,
VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 1, 1)); VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 0, 0, 1,
1));
ANGLE_TRY(mCulledWidgets.initMemory(contextVk, rendererVk->getMemoryProperties(), ANGLE_TRY(mCulledWidgets.initMemory(contextVk, rendererVk->getMemoryProperties(),
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)); VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
ANGLE_TRY(mCulledWidgets.initImageView(contextVk, gl::TextureType::_2D, ANGLE_TRY(mCulledWidgets.initImageView(contextVk, gl::TextureType::_2D,
......
...@@ -73,7 +73,7 @@ angle::Result RenderbufferVk::setStorageImpl(const gl::Context *context, ...@@ -73,7 +73,7 @@ angle::Result RenderbufferVk::setStorageImpl(const gl::Context *context,
VkExtent3D extents = {static_cast<uint32_t>(width), static_cast<uint32_t>(height), 1u}; VkExtent3D extents = {static_cast<uint32_t>(width), static_cast<uint32_t>(height), 1u};
ANGLE_TRY(mImage->init(contextVk, gl::TextureType::_2D, extents, vkFormat, ANGLE_TRY(mImage->init(contextVk, gl::TextureType::_2D, extents, vkFormat,
static_cast<uint32_t>(samples), usage, 1, 1)); static_cast<uint32_t>(samples), usage, 0, 0, 1, 1));
VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
ANGLE_TRY(mImage->initMemory(contextVk, renderer->getMemoryProperties(), flags)); ANGLE_TRY(mImage->initMemory(contextVk, renderer->getMemoryProperties(), flags));
......
...@@ -143,7 +143,8 @@ angle::Result OffscreenSurfaceVk::AttachmentImage::initialize(DisplayVk *display ...@@ -143,7 +143,8 @@ angle::Result OffscreenSurfaceVk::AttachmentImage::initialize(DisplayVk *display
VkExtent3D extents = {std::max(static_cast<uint32_t>(width), 1u), VkExtent3D extents = {std::max(static_cast<uint32_t>(width), 1u),
std::max(static_cast<uint32_t>(height), 1u), 1u}; std::max(static_cast<uint32_t>(height), 1u), 1u};
ANGLE_TRY(image.init(displayVk, gl::TextureType::_2D, extents, vkFormat, samples, usage, 1, 1)); ANGLE_TRY(
image.init(displayVk, gl::TextureType::_2D, extents, vkFormat, samples, usage, 0, 0, 1, 1));
VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
ANGLE_TRY(image.initMemory(displayVk, renderer->getMemoryProperties(), flags)); ANGLE_TRY(image.initMemory(displayVk, renderer->getMemoryProperties(), flags));
...@@ -771,7 +772,7 @@ angle::Result WindowSurfaceVk::createSwapChain(vk::Context *context, ...@@ -771,7 +772,7 @@ angle::Result WindowSurfaceVk::createSwapChain(vk::Context *context,
const VkImageUsageFlags usage = kSurfaceVKColorImageUsageFlags; const VkImageUsageFlags usage = kSurfaceVKColorImageUsageFlags;
ANGLE_TRY(mColorImageMS.init(context, gl::TextureType::_2D, vkExtents, format, samples, ANGLE_TRY(mColorImageMS.init(context, gl::TextureType::_2D, vkExtents, format, samples,
usage, 1, 1)); usage, 0, 0, 1, 1));
ANGLE_TRY(mColorImageMS.initMemory(context, renderer->getMemoryProperties(), ANGLE_TRY(mColorImageMS.initMemory(context, renderer->getMemoryProperties(),
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)); VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
...@@ -814,7 +815,7 @@ angle::Result WindowSurfaceVk::createSwapChain(vk::Context *context, ...@@ -814,7 +815,7 @@ angle::Result WindowSurfaceVk::createSwapChain(vk::Context *context,
const VkImageUsageFlags dsUsage = kSurfaceVKDepthStencilImageUsageFlags; const VkImageUsageFlags dsUsage = kSurfaceVKDepthStencilImageUsageFlags;
ANGLE_TRY(mDepthStencilImage.init(context, gl::TextureType::_2D, vkExtents, dsFormat, ANGLE_TRY(mDepthStencilImage.init(context, gl::TextureType::_2D, vkExtents, dsFormat,
samples, dsUsage, 1, 1)); samples, dsUsage, 0, 0, 1, 1));
ANGLE_TRY(mDepthStencilImage.initMemory(context, renderer->getMemoryProperties(), ANGLE_TRY(mDepthStencilImage.initMemory(context, renderer->getMemoryProperties(),
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)); VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
......
...@@ -207,6 +207,7 @@ class TextureVk : public TextureImpl ...@@ -207,6 +207,7 @@ class TextureVk : public TextureImpl
const vk::Format &format, const vk::Format &format,
uint32_t imageLevelOffset, uint32_t imageLevelOffset,
uint32_t imageLayerOffset, uint32_t imageLayerOffset,
uint32_t imageBaseLevel,
bool selfOwned); bool selfOwned);
void updateImageHelper(ContextVk *contextVk, const vk::Format &internalFormat); void updateImageHelper(ContextVk *contextVk, const vk::Format &internalFormat);
...@@ -231,12 +232,21 @@ class TextureVk : public TextureImpl ...@@ -231,12 +232,21 @@ class TextureVk : public TextureImpl
const uint8_t *pixels, const uint8_t *pixels,
const vk::Format &vkFormat); const vk::Format &vkFormat);
angle::Result copyImageDataToBuffer(ContextVk *contextVk, angle::Result copyImageDataToBufferAndGetData(ContextVk *contextVk,
size_t sourceLevel, size_t sourceLevel,
uint32_t layerCount, uint32_t layerCount,
const gl::Rectangle &sourceArea, const gl::Rectangle &sourceArea,
uint8_t **outDataPtr); uint8_t **outDataPtr);
angle::Result copyImageDataToBuffer(ContextVk *contextVk,
size_t sourceLevel,
uint32_t layerCount,
uint32_t layer,
const gl::Box &sourceArea,
VkBuffer *stagingBufferHandleOut,
VkDeviceSize *stagingOffsetOut,
uint8_t **outDataPtr);
angle::Result generateMipmapsWithCPU(const gl::Context *context); angle::Result generateMipmapsWithCPU(const gl::Context *context);
angle::Result generateMipmapLevelsWithCPU(ContextVk *contextVk, angle::Result generateMipmapLevelsWithCPU(ContextVk *contextVk,
...@@ -326,6 +336,8 @@ class TextureVk : public TextureImpl ...@@ -326,6 +336,8 @@ class TextureVk : public TextureImpl
const TextureVkViews *getTextureViews() const; const TextureVkViews *getTextureViews() const;
angle::Result changeLevels(ContextVk *contextVk, GLuint baseLevel, GLuint maxLevel);
bool mOwnsImage; bool mOwnsImage;
gl::TextureType mImageNativeType; gl::TextureType mImageNativeType;
......
...@@ -128,7 +128,7 @@ angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk ...@@ -128,7 +128,7 @@ angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk
mImage = new vk::ImageHelper(); mImage = new vk::ImageHelper();
ANGLE_TRY(mImage->initExternal(displayVk, gl::TextureType::_2D, vkExtents, vkFormat, 1, usage, ANGLE_TRY(mImage->initExternal(displayVk, gl::TextureType::_2D, vkExtents, vkFormat, 1, usage,
vk::ImageLayout::ExternalPreInitialized, vk::ImageLayout::ExternalPreInitialized,
&externalMemoryImageCreateInfo, 1, 1)); &externalMemoryImageCreateInfo, 0, 0, 1, 1));
VkImportAndroidHardwareBufferInfoANDROID importHardwareBufferInfo = {}; VkImportAndroidHardwareBufferInfoANDROID importHardwareBufferInfo = {};
importHardwareBufferInfo.sType = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID; importHardwareBufferInfo.sType = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID;
......
...@@ -1464,6 +1464,8 @@ ImageHelper::ImageHelper() ...@@ -1464,6 +1464,8 @@ ImageHelper::ImageHelper()
mSamples(0), mSamples(0),
mCurrentLayout(ImageLayout::Undefined), mCurrentLayout(ImageLayout::Undefined),
mCurrentQueueFamilyIndex(std::numeric_limits<uint32_t>::max()), mCurrentQueueFamilyIndex(std::numeric_limits<uint32_t>::max()),
mBaseLevel(0),
mMaxLevel(0),
mLayerCount(0), mLayerCount(0),
mLevelCount(0) mLevelCount(0)
{} {}
...@@ -1477,6 +1479,8 @@ ImageHelper::ImageHelper(ImageHelper &&other) ...@@ -1477,6 +1479,8 @@ ImageHelper::ImageHelper(ImageHelper &&other)
mSamples(other.mSamples), mSamples(other.mSamples),
mCurrentLayout(other.mCurrentLayout), mCurrentLayout(other.mCurrentLayout),
mCurrentQueueFamilyIndex(other.mCurrentQueueFamilyIndex), mCurrentQueueFamilyIndex(other.mCurrentQueueFamilyIndex),
mBaseLevel(other.mBaseLevel),
mMaxLevel(other.mMaxLevel),
mLayerCount(other.mLayerCount), mLayerCount(other.mLayerCount),
mLevelCount(other.mLevelCount), mLevelCount(other.mLevelCount),
mStagingBuffer(std::move(other.mStagingBuffer)), mStagingBuffer(std::move(other.mStagingBuffer)),
...@@ -1484,6 +1488,8 @@ ImageHelper::ImageHelper(ImageHelper &&other) ...@@ -1484,6 +1488,8 @@ ImageHelper::ImageHelper(ImageHelper &&other)
{ {
ASSERT(this != &other); ASSERT(this != &other);
other.mCurrentLayout = ImageLayout::Undefined; other.mCurrentLayout = ImageLayout::Undefined;
other.mBaseLevel = 0;
other.mMaxLevel = 0;
other.mLayerCount = 0; other.mLayerCount = 0;
other.mLevelCount = 0; other.mLevelCount = 0;
} }
...@@ -1508,11 +1514,14 @@ angle::Result ImageHelper::init(Context *context, ...@@ -1508,11 +1514,14 @@ angle::Result ImageHelper::init(Context *context,
const Format &format, const Format &format,
GLint samples, GLint samples,
VkImageUsageFlags usage, VkImageUsageFlags usage,
uint32_t baseLevel,
uint32_t maxLevel,
uint32_t mipLevels, uint32_t mipLevels,
uint32_t layerCount) uint32_t layerCount)
{ {
return initExternal(context, textureType, extents, format, samples, usage, return initExternal(context, textureType, extents, format, samples, usage,
ImageLayout::Undefined, nullptr, mipLevels, layerCount); ImageLayout::Undefined, nullptr, baseLevel, maxLevel, mipLevels,
layerCount);
} }
angle::Result ImageHelper::initExternal(Context *context, angle::Result ImageHelper::initExternal(Context *context,
...@@ -1523,6 +1532,8 @@ angle::Result ImageHelper::initExternal(Context *context, ...@@ -1523,6 +1532,8 @@ angle::Result ImageHelper::initExternal(Context *context,
VkImageUsageFlags usage, VkImageUsageFlags usage,
ImageLayout initialLayout, ImageLayout initialLayout,
const void *externalImageCreateInfo, const void *externalImageCreateInfo,
uint32_t baseLevel,
uint32_t maxLevel,
uint32_t mipLevels, uint32_t mipLevels,
uint32_t layerCount) uint32_t layerCount)
{ {
...@@ -1531,6 +1542,8 @@ angle::Result ImageHelper::initExternal(Context *context, ...@@ -1531,6 +1542,8 @@ angle::Result ImageHelper::initExternal(Context *context,
mExtents = extents; mExtents = extents;
mFormat = &format; mFormat = &format;
mSamples = samples; mSamples = samples;
mBaseLevel = baseLevel;
mMaxLevel = maxLevel;
mLevelCount = mipLevels; mLevelCount = mipLevels;
mLayerCount = layerCount; mLayerCount = layerCount;
...@@ -1803,6 +1816,17 @@ void ImageHelper::changeLayoutAndQueue(VkImageAspectFlags aspectMask, ...@@ -1803,6 +1816,17 @@ void ImageHelper::changeLayoutAndQueue(VkImageAspectFlags aspectMask,
forceChangeLayoutAndQueue(aspectMask, newLayout, newQueueFamilyIndex, commandBuffer); forceChangeLayoutAndQueue(aspectMask, newLayout, newQueueFamilyIndex, commandBuffer);
} }
uint32_t ImageHelper::getBaseLevel()
{
return mBaseLevel;
}
void ImageHelper::setBaseAndMaxLevels(uint32_t baseLevel, uint32_t maxLevel)
{
mBaseLevel = baseLevel;
mMaxLevel = maxLevel;
}
void ImageHelper::forceChangeLayoutAndQueue(VkImageAspectFlags aspectMask, void ImageHelper::forceChangeLayoutAndQueue(VkImageAspectFlags aspectMask,
ImageLayout newLayout, ImageLayout newLayout,
uint32_t newQueueFamilyIndex, uint32_t newQueueFamilyIndex,
...@@ -2310,6 +2334,38 @@ angle::Result ImageHelper::stageSubresourceUpdateAndGetData(ContextVk *contextVk ...@@ -2310,6 +2334,38 @@ angle::Result ImageHelper::stageSubresourceUpdateAndGetData(ContextVk *contextVk
return angle::Result::Continue; return angle::Result::Continue;
} }
angle::Result ImageHelper::stageSubresourceUpdateFromBuffer(ContextVk *contextVk,
size_t allocationSize,
uint32_t mipLevel,
uint32_t baseArrayLayer,
uint32_t layerCount,
const gl::Extents &glExtents,
const gl::Offset &offset,
VkBuffer stagingBufferHandle,
VkDeviceSize stagingOffset)
{
// This function stages an update from explicitly provided handle and offset
// It is used when the texture base level has changed, and we need to propagate data
VkBufferImageCopy copy = {};
copy.bufferOffset = stagingOffset;
copy.bufferRowLength = glExtents.width;
copy.bufferImageHeight = glExtents.height;
copy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
copy.imageSubresource.mipLevel = mipLevel;
copy.imageSubresource.baseArrayLayer = baseArrayLayer;
copy.imageSubresource.layerCount = layerCount;
ASSERT(getAspectFlags() == VK_IMAGE_ASPECT_COLOR_BIT);
gl_vk::GetOffset(offset, &copy.imageOffset);
gl_vk::GetExtent(glExtents, &copy.imageExtent);
mSubresourceUpdates.emplace_back(stagingBufferHandle, copy);
return angle::Result::Continue;
}
angle::Result ImageHelper::stageSubresourceUpdateFromFramebuffer( angle::Result ImageHelper::stageSubresourceUpdateFromFramebuffer(
const gl::Context *context, const gl::Context *context,
const gl::ImageIndex &index, const gl::ImageIndex &index,
...@@ -2555,7 +2611,9 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk, ...@@ -2555,7 +2611,9 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk,
// If the update level is not within the requested range, skip the update. // If the update level is not within the requested range, skip the update.
const bool isUpdateLevelOutsideRange = const bool isUpdateLevelOutsideRange =
updateMipLevel < levelStart || updateMipLevel >= levelEnd; updateMipLevel < (levelStart + mBaseLevel) ||
(updateMipLevel > (levelEnd + mBaseLevel) || updateMipLevel > mMaxLevel);
// If the update layers don't intersect the requested layers, skip the update. // If the update layers don't intersect the requested layers, skip the update.
const bool areUpdateLayersOutsideRange = const bool areUpdateLayersOutsideRange =
updateBaseLayer + updateLayerCount <= layerStart || updateBaseLayer >= layerEnd; updateBaseLayer + updateLayerCount <= layerStart || updateBaseLayer >= layerEnd;
...@@ -2566,6 +2624,23 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk, ...@@ -2566,6 +2624,23 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk,
continue; continue;
} }
if (mBaseLevel > 0)
{
// We need to shift the miplevel in the update to fall into the vkiamge
if (update.updateSource == SubresourceUpdate::UpdateSource::Clear)
{
update.clear.levelIndex -= mBaseLevel;
}
else if (update.updateSource == SubresourceUpdate::UpdateSource::Buffer)
{
update.buffer.copyRegion.imageSubresource.mipLevel -= mBaseLevel;
}
else if (update.updateSource == SubresourceUpdate::UpdateSource::Image)
{
update.image.copyRegion.dstSubresource.mipLevel -= mBaseLevel;
}
}
if (updateLayerCount >= kMaxParallelSubresourceUpload) if (updateLayerCount >= kMaxParallelSubresourceUpload)
{ {
// If there are more subresources than bits we can track, always insert a barrier. // If there are more subresources than bits we can track, always insert a barrier.
...@@ -2633,6 +2708,48 @@ angle::Result ImageHelper::flushAllStagedUpdates(ContextVk *contextVk) ...@@ -2633,6 +2708,48 @@ angle::Result ImageHelper::flushAllStagedUpdates(ContextVk *contextVk)
return flushStagedUpdates(contextVk, 0, mLevelCount, 0, mLayerCount, commandBuffer); return flushStagedUpdates(contextVk, 0, mLevelCount, 0, mLayerCount, commandBuffer);
} }
bool ImageHelper::isUpdateStaged(uint32_t level, uint32_t layer)
{
// Check to see if any updates are staged for the given level and layer
if (mSubresourceUpdates.empty())
{
return false;
}
for (SubresourceUpdate &update : mSubresourceUpdates)
{
uint32_t updateMipLevel;
uint32_t updateBaseLayer;
uint32_t updateLayerCount;
if (update.updateSource == SubresourceUpdate::UpdateSource::Clear)
{
updateMipLevel = update.clear.levelIndex;
updateBaseLayer = update.clear.layerIndex;
updateLayerCount = update.clear.layerCount;
}
else
{
const VkImageSubresourceLayers &dstSubresource = update.dstSubresource();
updateMipLevel = dstSubresource.mipLevel;
updateBaseLayer = dstSubresource.baseArrayLayer;
updateLayerCount = dstSubresource.layerCount;
}
if (updateMipLevel == level)
{
if (layer >= updateBaseLayer && layer < (updateBaseLayer + updateLayerCount))
{
// The level matches, and the layer is within the range
return true;
}
}
}
return false;
}
// ImageHelper::SubresourceUpdate implementation // ImageHelper::SubresourceUpdate implementation
ImageHelper::SubresourceUpdate::SubresourceUpdate() ImageHelper::SubresourceUpdate::SubresourceUpdate()
: updateSource(UpdateSource::Buffer), buffer{VK_NULL_HANDLE} : updateSource(UpdateSource::Buffer), buffer{VK_NULL_HANDLE}
......
...@@ -654,6 +654,8 @@ class ImageHelper final : public CommandGraphResource ...@@ -654,6 +654,8 @@ class ImageHelper final : public CommandGraphResource
const Format &format, const Format &format,
GLint samples, GLint samples,
VkImageUsageFlags usage, VkImageUsageFlags usage,
uint32_t baseLevel,
uint32_t maxLevel,
uint32_t mipLevels, uint32_t mipLevels,
uint32_t layerCount); uint32_t layerCount);
angle::Result initExternal(Context *context, angle::Result initExternal(Context *context,
...@@ -664,6 +666,8 @@ class ImageHelper final : public CommandGraphResource ...@@ -664,6 +666,8 @@ class ImageHelper final : public CommandGraphResource
VkImageUsageFlags usage, VkImageUsageFlags usage,
ImageLayout initialLayout, ImageLayout initialLayout,
const void *externalImageCreateInfo, const void *externalImageCreateInfo,
uint32_t baseLevel,
uint32_t maxLevel,
uint32_t mipLevels, uint32_t mipLevels,
uint32_t layerCount); uint32_t layerCount);
angle::Result initMemory(Context *context, angle::Result initMemory(Context *context,
...@@ -779,6 +783,16 @@ class ImageHelper final : public CommandGraphResource ...@@ -779,6 +783,16 @@ class ImageHelper final : public CommandGraphResource
const gl::Offset &offset, const gl::Offset &offset,
uint8_t **destData); uint8_t **destData);
angle::Result stageSubresourceUpdateFromBuffer(ContextVk *contextVk,
size_t allocationSize,
uint32_t mipLevel,
uint32_t baseArrayLayer,
uint32_t layerCount,
const gl::Extents &glExtents,
const gl::Offset &offset,
VkBuffer stagingBufferHandle,
VkDeviceSize stagingOffset);
angle::Result stageSubresourceUpdateFromFramebuffer(const gl::Context *context, angle::Result stageSubresourceUpdateFromFramebuffer(const gl::Context *context,
const gl::ImageIndex &index, const gl::ImageIndex &index,
const gl::Rectangle &sourceArea, const gl::Rectangle &sourceArea,
...@@ -827,6 +841,8 @@ class ImageHelper final : public CommandGraphResource ...@@ -827,6 +841,8 @@ class ImageHelper final : public CommandGraphResource
// as with renderbuffers or surface images. // as with renderbuffers or surface images.
angle::Result flushAllStagedUpdates(ContextVk *contextVk); angle::Result flushAllStagedUpdates(ContextVk *contextVk);
bool isUpdateStaged(uint32_t level, uint32_t layer);
bool hasStagedUpdates() const { return !mSubresourceUpdates.empty(); } bool hasStagedUpdates() const { return !mSubresourceUpdates.empty(); }
// changeLayout automatically skips the layout change if it's unnecessary. This function can be // changeLayout automatically skips the layout change if it's unnecessary. This function can be
...@@ -848,6 +864,9 @@ class ImageHelper final : public CommandGraphResource ...@@ -848,6 +864,9 @@ class ImageHelper final : public CommandGraphResource
uint32_t newQueueFamilyIndex, uint32_t newQueueFamilyIndex,
CommandBuffer *commandBuffer); CommandBuffer *commandBuffer);
uint32_t getBaseLevel();
void setBaseAndMaxLevels(uint32_t baseLevel, uint32_t maxLevel);
private: private:
void forceChangeLayoutAndQueue(VkImageAspectFlags aspectMask, void forceChangeLayoutAndQueue(VkImageAspectFlags aspectMask,
ImageLayout newLayout, ImageLayout newLayout,
...@@ -941,6 +960,8 @@ class ImageHelper final : public CommandGraphResource ...@@ -941,6 +960,8 @@ class ImageHelper final : public CommandGraphResource
uint32_t mCurrentQueueFamilyIndex; uint32_t mCurrentQueueFamilyIndex;
// Cached properties. // Cached properties.
uint32_t mBaseLevel;
uint32_t mMaxLevel;
uint32_t mLayerCount; uint32_t mLayerCount;
uint32_t mLevelCount; uint32_t mLevelCount;
......
...@@ -581,12 +581,6 @@ ...@@ -581,12 +581,6 @@
2672 VULKAN : dEQP-GLES3.functional.draw.random.* = SKIP 2672 VULKAN : dEQP-GLES3.functional.draw.random.* = SKIP
// Base/Max levels: // Base/Max levels:
3148 VULKAN : dEQP-GLES3.functional.state_query.texture.texture_2d_texture_base_level_gettexparameter* = SKIP
3148 VULKAN : dEQP-GLES3.functional.state_query.texture.texture_3d_texture_base_level_gettexparameter* = SKIP
3148 VULKAN : dEQP-GLES3.functional.state_query.texture.texture_2d_array_texture_base_level_gettexparameter* = SKIP
3148 VULKAN : dEQP-GLES3.functional.state_query.texture.texture_cube_map_texture_base_level_gettexparameter* = SKIP
3148 VULKAN : dEQP-GLES3.functional.texture.mipmap.*base_level* = SKIP
3148 VULKAN : dEQP-GLES3.functional.texture.mipmap.*max_level* = FAIL
3148 VULKAN : dEQP-GLES3.functional.shaders.texture_functions.texturesize.* = SKIP 3148 VULKAN : dEQP-GLES3.functional.shaders.texture_functions.texturesize.* = SKIP
// Misc unimplemented: // Misc unimplemented:
......
...@@ -666,6 +666,10 @@ TEST_P(MipmapTest, RenderOntoLevelZeroAfterGenerateMipmap) ...@@ -666,6 +666,10 @@ TEST_P(MipmapTest, RenderOntoLevelZeroAfterGenerateMipmap)
// already uploaded before. The test expects that mip to be usable. // already uploaded before. The test expects that mip to be usable.
TEST_P(MipmapTest, DefineValidExtraLevelAndUseItLater) TEST_P(MipmapTest, DefineValidExtraLevelAndUseItLater)
{ {
// TODO(cnorthrop): Enabled the group to cover texture base level, but this test
// needs some triage: http://anglebug.com/3148
ANGLE_SKIP_TEST_IF(IsVulkan());
glBindTexture(GL_TEXTURE_2D, mTexture2D); glBindTexture(GL_TEXTURE_2D, mTexture2D);
GLubyte *levels[] = {mLevelZeroBlueInitData.data(), mLevelOneGreenInitData.data(), GLubyte *levels[] = {mLevelZeroBlueInitData.data(), mLevelOneGreenInitData.data(),
...@@ -940,6 +944,10 @@ TEST_P(MipmapTestES3, MipmapForDeepTextureArray) ...@@ -940,6 +944,10 @@ TEST_P(MipmapTestES3, MipmapForDeepTextureArray)
// Then tests if the mipmaps are rendered correctly for all two layers. // Then tests if the mipmaps are rendered correctly for all two layers.
TEST_P(MipmapTestES3, MipmapsForTexture3D) TEST_P(MipmapTestES3, MipmapsForTexture3D)
{ {
// TODO(cnorthrop): Enabled the group to cover texture base level, but this test
// needs some triage: http://anglebug.com/3148
ANGLE_SKIP_TEST_IF(IsVulkan());
int px = getWindowWidth() / 2; int px = getWindowWidth() / 2;
int py = getWindowHeight() / 2; int py = getWindowHeight() / 2;
...@@ -1184,6 +1192,9 @@ TEST_P(MipmapTestES3, GenerateMipmapBaseLevelOutOfRange) ...@@ -1184,6 +1192,9 @@ TEST_P(MipmapTestES3, GenerateMipmapBaseLevelOutOfRange)
// be clamped, so the call doesn't generate an error. // be clamped, so the call doesn't generate an error.
TEST_P(MipmapTestES3, GenerateMipmapBaseLevelOutOfRangeImmutableTexture) TEST_P(MipmapTestES3, GenerateMipmapBaseLevelOutOfRangeImmutableTexture)
{ {
// TODO(cnorthrop): Interacts with immutable texture supprt: http://anglebug.com/3148
ANGLE_SKIP_TEST_IF(IsVulkan());
glBindTexture(GL_TEXTURE_2D, mTexture); glBindTexture(GL_TEXTURE_2D, mTexture);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1); glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
...@@ -1215,6 +1226,9 @@ TEST_P(MipmapTestES3, BaseLevelTextureBug) ...@@ -1215,6 +1226,9 @@ TEST_P(MipmapTestES3, BaseLevelTextureBug)
// Probably not Intel. // Probably not Intel.
ANGLE_SKIP_TEST_IF(IsOSX() && (IsNVIDIA() || IsIntel())); ANGLE_SKIP_TEST_IF(IsOSX() && (IsNVIDIA() || IsIntel()));
// TODO(cnorthrop): Figure out what's going on here: http://anglebug.com/3148
ANGLE_SKIP_TEST_IF(IsVulkan());
std::vector<GLColor> texDataRed(2u * 2u, GLColor::red); std::vector<GLColor> texDataRed(2u * 2u, GLColor::red);
glBindTexture(GL_TEXTURE_2D, mTexture); glBindTexture(GL_TEXTURE_2D, mTexture);
...@@ -1244,5 +1258,6 @@ ANGLE_INSTANTIATE_TEST(MipmapTest, ...@@ -1244,5 +1258,6 @@ ANGLE_INSTANTIATE_TEST(MipmapTest,
ES3_OPENGL(), ES3_OPENGL(),
ES2_OPENGLES(), ES2_OPENGLES(),
ES3_OPENGLES(), ES3_OPENGLES(),
ES2_VULKAN()); ES2_VULKAN(),
ANGLE_INSTANTIATE_TEST(MipmapTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); ES3_VULKAN());
ANGLE_INSTANTIATE_TEST(MipmapTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES(), ES3_VULKAN());
...@@ -1970,6 +1970,8 @@ TEST_P(Texture2DTestES3, TextureImplPropogatesDirtyBits) ...@@ -1970,6 +1970,8 @@ TEST_P(Texture2DTestES3, TextureImplPropogatesDirtyBits)
ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsOpenGL()); ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsOpenGL());
// D3D Debug device reports an error. http://anglebug.com/3501 // D3D Debug device reports an error. http://anglebug.com/3501
ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D11()); ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D11());
// TODO(cnorthrop): Needs triage on Vulkan backend. http://anglebug.com/3148
ANGLE_SKIP_TEST_IF(IsVulkan());
// The workaround in the GL backend required to trigger this bug generates driver warning // The workaround in the GL backend required to trigger this bug generates driver warning
// messages. // messages.
...@@ -2015,6 +2017,9 @@ TEST_P(Texture2DTestES3, FramebufferTextureChangingBaselevel) ...@@ -2015,6 +2017,9 @@ TEST_P(Texture2DTestES3, FramebufferTextureChangingBaselevel)
// TODO(geofflang): Investigate on D3D11. http://anglebug.com/2291 // TODO(geofflang): Investigate on D3D11. http://anglebug.com/2291
ANGLE_SKIP_TEST_IF(IsD3D11()); ANGLE_SKIP_TEST_IF(IsD3D11());
// TODO(cnorthrop): Framebuffer level support. http://anglebug.com/3148
ANGLE_SKIP_TEST_IF(IsVulkan());
setUpProgram(); setUpProgram();
constexpr GLint width = 8; constexpr GLint width = 8;
...@@ -2301,6 +2306,9 @@ TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensio ...@@ -2301,6 +2306,9 @@ TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensio
// TODO(crbug.com/998505): Test failing on Android FYI Release (NVIDIA Shield TV) // TODO(crbug.com/998505): Test failing on Android FYI Release (NVIDIA Shield TV)
ANGLE_SKIP_TEST_IF(IsNVIDIAShield()); ANGLE_SKIP_TEST_IF(IsNVIDIAShield());
// TODO(cnorthrop): Depth vs. array issue in VK backend. http://anglebug.com/3148
ANGLE_SKIP_TEST_IF(IsVulkan());
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_3D, m2DArrayTexture); glBindTexture(GL_TEXTURE_3D, m2DArrayTexture);
std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red); std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
...@@ -2672,6 +2680,9 @@ TEST_P(ShadowSamplerPlusSampler3DTestES3, ShadowSamplerPlusSampler3DDraw) ...@@ -2672,6 +2680,9 @@ TEST_P(ShadowSamplerPlusSampler3DTestES3, ShadowSamplerPlusSampler3DDraw)
// samplerCubeShadow: TextureCube + SamplerComparisonState // samplerCubeShadow: TextureCube + SamplerComparisonState
TEST_P(SamplerTypeMixTestES3, SamplerTypeMixDraw) TEST_P(SamplerTypeMixTestES3, SamplerTypeMixDraw)
{ {
// TODO(cnorthrop): Requires non-color staging buffer support. http://anglebug.com/3148
ANGLE_SKIP_TEST_IF(IsVulkan());
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, mTexture2D); glBindTexture(GL_TEXTURE_2D, mTexture2D);
GLubyte texData[4]; GLubyte texData[4];
...@@ -4771,6 +4782,9 @@ TEST_P(Texture2DTestES3, DepthTexturesWithMipmaps) ...@@ -4771,6 +4782,9 @@ TEST_P(Texture2DTestES3, DepthTexturesWithMipmaps)
// Seems to fail on AMD D3D11. Possibly driver bug. http://anglebug.com/3342 // Seems to fail on AMD D3D11. Possibly driver bug. http://anglebug.com/3342
ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsD3D11()); ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsD3D11());
// TODO(cnorthrop): Also failing on Vulkan/Windows/AMD. http://anglebug.com/3148
ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsVulkan());
const int size = getWindowWidth(); const int size = getWindowWidth();
auto dim = [size](int level) { return size >> level; }; auto dim = [size](int level) { return size >> level; };
...@@ -5392,6 +5406,9 @@ TEST_P(Texture2DTestES3, GenerateMipmapAndBaseLevelLUMA) ...@@ -5392,6 +5406,9 @@ TEST_P(Texture2DTestES3, GenerateMipmapAndBaseLevelLUMA)
// this led to not sampling your texture data when minification occurred. // this led to not sampling your texture data when minification occurred.
TEST_P(Texture2DTestES3, MinificationWithSamplerNoMipmapping) TEST_P(Texture2DTestES3, MinificationWithSamplerNoMipmapping)
{ {
// TODO: Triage this failure on Vulkan: http://anglebug.com/3148
ANGLE_SKIP_TEST_IF(IsVulkan());
constexpr char kVS[] = constexpr char kVS[] =
"#version 300 es\n" "#version 300 es\n"
"out vec2 texcoord;\n" "out vec2 texcoord;\n"
...@@ -5659,8 +5676,8 @@ ANGLE_INSTANTIATE_TEST(SamplerArrayAsFunctionParameterTest, ...@@ -5659,8 +5676,8 @@ ANGLE_INSTANTIATE_TEST(SamplerArrayAsFunctionParameterTest,
ES2_OPENGL(), ES2_OPENGL(),
ES2_OPENGLES(), ES2_OPENGLES(),
ES2_VULKAN()); ES2_VULKAN());
ANGLE_INSTANTIATE_TEST(Texture2DTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); ANGLE_INSTANTIATE_TEST(Texture2DTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES(), ES3_VULKAN());
ANGLE_INSTANTIATE_TEST(Texture3DTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); ANGLE_INSTANTIATE_TEST(Texture3DTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES(), ES3_VULKAN());
ANGLE_INSTANTIATE_TEST(Texture2DIntegerAlpha1TestES3, ANGLE_INSTANTIATE_TEST(Texture2DIntegerAlpha1TestES3,
ES3_D3D11(), ES3_D3D11(),
ES3_OPENGL(), ES3_OPENGL(),
...@@ -5680,7 +5697,11 @@ ANGLE_INSTANTIATE_TEST(SamplerTypeMixTestES3, ...@@ -5680,7 +5697,11 @@ ANGLE_INSTANTIATE_TEST(SamplerTypeMixTestES3,
ES3_OPENGL(), ES3_OPENGL(),
ES3_OPENGLES(), ES3_OPENGLES(),
ES3_VULKAN()); ES3_VULKAN());
ANGLE_INSTANTIATE_TEST(Texture2DArrayTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); ANGLE_INSTANTIATE_TEST(Texture2DArrayTestES3,
ES3_D3D11(),
ES3_OPENGL(),
ES3_OPENGLES(),
ES3_VULKAN());
ANGLE_INSTANTIATE_TEST(TextureSizeTextureArrayTest, ES3_D3D11(), ES3_OPENGL()); ANGLE_INSTANTIATE_TEST(TextureSizeTextureArrayTest, ES3_D3D11(), ES3_OPENGL());
ANGLE_INSTANTIATE_TEST(SamplerInStructTest, ANGLE_INSTANTIATE_TEST(SamplerInStructTest,
ES2_D3D11(), ES2_D3D11(),
...@@ -5747,13 +5768,16 @@ ANGLE_INSTANTIATE_TEST(Texture2DFloatTestES2, ...@@ -5747,13 +5768,16 @@ ANGLE_INSTANTIATE_TEST(Texture2DFloatTestES2,
ES2_OPENGL(), ES2_OPENGL(),
ES2_OPENGLES(), ES2_OPENGLES(),
ES2_VULKAN()); ES2_VULKAN());
ANGLE_INSTANTIATE_TEST(TextureCubeTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); ANGLE_INSTANTIATE_TEST(TextureCubeTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES(), ES3_VULKAN());
ANGLE_INSTANTIATE_TEST(Texture2DIntegerTestES3, ES3_D3D11(), ES3_OPENGL()); ANGLE_INSTANTIATE_TEST(Texture2DIntegerTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_VULKAN());
ANGLE_INSTANTIATE_TEST(TextureCubeIntegerTestES3, ES3_D3D11(), ES3_OPENGL()); ANGLE_INSTANTIATE_TEST(TextureCubeIntegerTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_VULKAN());
ANGLE_INSTANTIATE_TEST(TextureCubeIntegerEdgeTestES3, ES3_D3D11(), ES3_OPENGL()); ANGLE_INSTANTIATE_TEST(TextureCubeIntegerEdgeTestES3, ES3_D3D11(), ES3_OPENGL());
ANGLE_INSTANTIATE_TEST(Texture2DIntegerProjectiveOffsetTestES3, ES3_D3D11(), ES3_OPENGL()); ANGLE_INSTANTIATE_TEST(Texture2DIntegerProjectiveOffsetTestES3,
ANGLE_INSTANTIATE_TEST(Texture2DArrayIntegerTestES3, ES3_D3D11(), ES3_OPENGL()); ES3_D3D11(),
ANGLE_INSTANTIATE_TEST(Texture3DIntegerTestES3, ES3_D3D11(), ES3_OPENGL()); ES3_OPENGL(),
ES3_VULKAN());
ANGLE_INSTANTIATE_TEST(Texture2DArrayIntegerTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_VULKAN());
ANGLE_INSTANTIATE_TEST(Texture3DIntegerTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_VULKAN());
ANGLE_INSTANTIATE_TEST(Texture2DDepthTest, ANGLE_INSTANTIATE_TEST(Texture2DDepthTest,
ES2_D3D9(), ES2_D3D9(),
ES2_D3D11(), ES2_D3D11(),
......
...@@ -1201,6 +1201,9 @@ TEST_P(VertexAttributeTest, DrawArraysWithBufferOffset) ...@@ -1201,6 +1201,9 @@ TEST_P(VertexAttributeTest, DrawArraysWithBufferOffset)
// TODO(geofflang): Figure out why this is broken on AMD OpenGL // TODO(geofflang): Figure out why this is broken on AMD OpenGL
ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL()); ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
// TODO(cnorthrop): Test this again on more recent drivers. http://anglebug.com/3148
ANGLE_SKIP_TEST_IF(IsLinux() && IsNVIDIA() && IsVulkan());
initBasicProgram(); initBasicProgram();
glUseProgram(mProgram); glUseProgram(mProgram);
......
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