Commit 3d2de99e by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Fix RTs attached to textures with non-0 mip

Cleared confusion between GL level indices and VK level indices by adding the corresponding suffix to variables and function arguments. A handful of places that sent one index and expected the other are fixed. The conversion between the two is given by: levelIndexGL = levelIndexVk + baseLevel; Bug: angleproject:4695 Change-Id: I84ecbaf867d00a40fb39b6db7ad79658016f4d9a Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2235362 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent d80d9044
......@@ -1700,10 +1700,10 @@ angle::Result FramebufferVk::readPixelsImpl(ContextVk *contextVk,
void *pixels)
{
ANGLE_TRACE_EVENT0("gpu.angle", "FramebufferVk::readPixelsImpl");
uint32_t level = renderTarget->getLevelIndex();
uint32_t levelGL = renderTarget->getLevelIndex();
uint32_t layer = renderTarget->getLayerIndex();
return renderTarget->getImage().readPixels(contextVk, area, packPixelsParams, copyAspectFlags,
level, layer, pixels, &mReadPixelBuffer);
levelGL, layer, pixels, &mReadPixelBuffer);
}
gl::Extents FramebufferVk::getReadImageExtents() const
......
......@@ -1199,8 +1199,8 @@ angle::Result TextureVk::copyAndStageImageSubresource(ContextVk *contextVk,
const gl::ImageDesc &desc,
bool ignoreLayerCount,
uint32_t currentLayer,
uint32_t sourceMipLevel,
uint32_t stagingDstMipLevel)
uint32_t srcLevelVk,
uint32_t dstLevelGL)
{
const gl::Extents &baseLevelExtents = desc.size;
......@@ -1221,9 +1221,9 @@ angle::Result TextureVk::copyAndStageImageSubresource(ContextVk *contextVk,
vk::BufferHelper *stagingBuffer = nullptr;
vk::StagingBufferOffsetArray stagingBufferOffsets = {0, 0};
size_t bufferSize = 0;
ANGLE_TRY(mImage->copyImageDataToBuffer(contextVk, sourceMipLevel, layerCount, currentLayer,
area, &stagingBuffer, &bufferSize,
&stagingBufferOffsets, nullptr));
ANGLE_TRY(mImage->copyImageDataToBuffer(contextVk, srcLevelVk, layerCount, currentLayer, area,
&stagingBuffer, &bufferSize, &stagingBufferOffsets,
nullptr));
// Stage an update to the new image
ASSERT(stagingBuffer);
......@@ -1238,7 +1238,7 @@ angle::Result TextureVk::copyAndStageImageSubresource(ContextVk *contextVk,
bufferImageHeight = std::max(bufferImageHeight, desc.format.info->compressedBlockHeight);
}
ANGLE_TRY(mImage->stageSubresourceUpdateFromBuffer(
contextVk, bufferSize, stagingDstMipLevel, currentLayer, layerCount, bufferRowLength,
contextVk, bufferSize, dstLevelGL, currentLayer, layerCount, bufferRowLength,
bufferImageHeight, updatedExtents, offset, stagingBuffer, stagingBufferOffsets));
return angle::Result::Continue;
......@@ -1305,47 +1305,31 @@ angle::Result TextureVk::respecifyImageAttributesAndLevels(ContextVk *contextVk,
mImage->getLayerCount(), commandBuffer));
}
bool baseLevelChanged = baseLevel != previousBaseLevel;
// After flushing, track the new levels (they are used in the flush, hence the wait)
mImage->setBaseAndMaxLevels(baseLevel, maxLevel);
// Next, back up any data we need to preserve by staging it as updates to the new image.
// Stage updates for all levels in the GL texture, while preserving the data in the vkImage.
// This ensures we propagate all the current image data, even as max level moves around.
uint32_t updateCount =
std::max<GLuint>(mState.getMipmapMaxLevel() + 1, mImage->getLevelCount());
// Preserve the data in the Vulkan image. GL texture's staged updates that correspond to levels
// outside the range of the Vulkan image will remain intact.
// The staged updates won't be applied until the image has the requisite mip levels
for (uint32_t layer = 0; layer < mImage->getLayerCount(); layer++)
{
for (uint32_t level = 0; level < updateCount; level++)
for (uint32_t levelVK = 0; levelVK < mImage->getLevelCount(); levelVK++)
{
if (mImage->isUpdateStaged(level, layer))
{
// If there is still an update staged for the surface at the designated
// layer/level, we don't need to propagate any data from this image.
// This can happen for original texture levels that have never fit into
// the vkImage due to base/max level, and for vkImage data that has been
// staged by previous calls to respecifyImageAttributesAndLevels that didn't fit
// into the new vkImage.
continue;
}
// Vulkan level 0 previously aligned with whatever the base level was.
uint32_t levelGL = levelVK + previousBaseLevel;
ASSERT(!mImage->isUpdateStaged(levelGL, layer));
// Pull data from the current image and stage it as an update for the new image
// First we populate the staging buffer with current level data
const gl::ImageDesc &desc =
mState.getImageDesc(gl::TextureTypeToTarget(mState.getType(), layer), level);
// We need to adjust the source Vulkan level to reflect the previous base level.
// vk level 0 previously aligned with whatever the base level was.
uint32_t srcLevelVK = baseLevelChanged ? level - previousBaseLevel : level;
ASSERT(srcLevelVK <= mImage->getLevelCount());
mState.getImageDesc(gl::TextureTypeToTarget(mState.getType(), layer), levelGL);
ANGLE_TRY(
copyAndStageImageSubresource(contextVk, desc, true, layer, srcLevelVK, level));
ANGLE_TRY(copyAndStageImageSubresource(contextVk, desc, true, layer, levelVK, levelGL));
}
}
......
......@@ -356,8 +356,8 @@ class TextureVk : public TextureImpl, public angle::ObserverInterface
const gl::ImageDesc &desc,
bool ignoreLayerCount,
uint32_t currentLayer,
uint32_t sourceLevel,
uint32_t stagingDstMipLevel);
uint32_t srcLevelVk,
uint32_t dstLevelGL);
angle::Result initImageViews(ContextVk *contextVk,
const vk::Format &format,
const bool sized,
......
......@@ -3246,14 +3246,14 @@ void ImageHelper::resolve(ImageHelper *dest,
}
void ImageHelper::removeStagedUpdates(ContextVk *contextVk,
uint32_t levelIndex,
uint32_t levelIndexGL,
uint32_t layerIndex)
{
// Find any staged updates for this index and removes them from the pending list.
for (size_t index = 0; index < mSubresourceUpdates.size();)
{
auto update = mSubresourceUpdates.begin() + index;
if (update->isUpdateToLayerLevel(layerIndex, levelIndex))
if (update->isUpdateToLayerLevel(layerIndex, levelIndexGL))
{
update->release(contextVk->getRenderer());
mSubresourceUpdates.erase(update);
......@@ -3556,7 +3556,7 @@ angle::Result ImageHelper::stageSubresourceUpdateAndGetData(ContextVk *contextVk
angle::Result ImageHelper::stageSubresourceUpdateFromBuffer(ContextVk *contextVk,
size_t allocationSize,
uint32_t mipLevel,
uint32_t mipLevelGL,
uint32_t baseArrayLayer,
uint32_t layerCount,
uint32_t bufferRowLength,
......@@ -3574,7 +3574,7 @@ angle::Result ImageHelper::stageSubresourceUpdateFromBuffer(ContextVk *contextVk
copy[0].bufferRowLength = bufferRowLength;
copy[0].bufferImageHeight = bufferImageHeight;
copy[0].imageSubresource.aspectMask = getAspectFlags();
copy[0].imageSubresource.mipLevel = mipLevel;
copy[0].imageSubresource.mipLevel = mipLevelGL;
copy[0].imageSubresource.baseArrayLayer = baseArrayLayer;
copy[0].imageSubresource.layerCount = layerCount;
copy[0].imageOffset = offset;
......@@ -3589,7 +3589,7 @@ angle::Result ImageHelper::stageSubresourceUpdateFromBuffer(ContextVk *contextVk
copy[1].bufferRowLength = bufferRowLength;
copy[1].bufferImageHeight = bufferImageHeight;
copy[1].imageSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
copy[1].imageSubresource.mipLevel = mipLevel;
copy[1].imageSubresource.mipLevel = mipLevelGL;
copy[1].imageSubresource.baseArrayLayer = baseArrayLayer;
copy[1].imageSubresource.layerCount = layerCount;
copy[1].imageOffset = offset;
......@@ -3847,7 +3847,7 @@ angle::Result ImageHelper::allocateStagingMemory(ContextVk *contextVk,
}
angle::Result ImageHelper::flushSingleSubresourceStagedUpdates(ContextVk *contextVk,
uint32_t level,
uint32_t levelGL,
uint32_t layer,
CommandBuffer *commandBuffer,
ClearValuesArray *deferredClears,
......@@ -3862,7 +3862,7 @@ angle::Result ImageHelper::flushSingleSubresourceStagedUpdates(ContextVk *contex
{
SubresourceUpdate &update = mSubresourceUpdates[updateIndex];
if (update.isUpdateToLayerLevel(layer, level))
if (update.isUpdateToLayerLevel(layer, levelGL))
{
// On any data update, exit out. We'll need to do a full upload.
if (update.updateSource != UpdateSource::Clear ||
......@@ -3888,19 +3888,20 @@ angle::Result ImageHelper::flushSingleSubresourceStagedUpdates(ContextVk *contex
deferredClears->store(deferredClearIndex, update.aspectFlags, update.value);
// We process the updates again to erase any clears for this level.
removeStagedUpdates(contextVk, level, layer);
removeStagedUpdates(contextVk, levelGL, layer);
return angle::Result::Continue;
}
// Otherwise we proceed with a normal update.
}
return flushStagedUpdates(contextVk, level, level + 1, layer, layer + 1, commandBuffer);
uint32_t levelVK = levelGL - mBaseLevel;
return flushStagedUpdates(contextVk, levelVK, levelVK + 1, layer, layer + 1, commandBuffer);
}
angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk,
uint32_t levelStart,
uint32_t levelEnd,
uint32_t levelVKStart,
uint32_t levelVKEnd,
uint32_t layerStart,
uint32_t layerEnd,
CommandBuffer *commandBuffer)
......@@ -3910,6 +3911,9 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk,
return angle::Result::Continue;
}
const uint32_t levelGLStart = levelVKStart + mBaseLevel;
const uint32_t levelGLEnd = levelVKEnd + mBaseLevel;
ANGLE_TRY(mStagingBuffer.flush(contextVk));
std::vector<SubresourceUpdate> updatesToKeep;
......@@ -3933,12 +3937,12 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk,
(update.updateSource == UpdateSource::Image && update.image.image != nullptr &&
update.image.image->valid()));
uint32_t updateMipLevel;
uint32_t updateMipLevelGL;
uint32_t updateBaseLayer;
uint32_t updateLayerCount;
if (update.updateSource == UpdateSource::Clear)
{
updateMipLevel = update.clear.levelIndex;
updateMipLevelGL = update.clear.levelIndex;
updateBaseLayer = update.clear.layerIndex;
updateLayerCount = update.clear.layerCount;
if (updateLayerCount == static_cast<uint32_t>(gl::ImageIndex::kEntireLevel))
......@@ -3949,16 +3953,16 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk,
else
{
const VkImageSubresourceLayers &dstSubresource = update.dstSubresource();
updateMipLevel = dstSubresource.mipLevel;
updateMipLevelGL = dstSubresource.mipLevel;
updateBaseLayer = dstSubresource.baseArrayLayer;
updateLayerCount = dstSubresource.layerCount;
ASSERT(updateLayerCount != static_cast<uint32_t>(gl::ImageIndex::kEntireLevel));
}
// If the update level is not within the requested range, skip the update.
const bool isUpdateLevelOutsideRange =
updateMipLevel < (levelStart + mBaseLevel) ||
(updateMipLevel >= (levelEnd + mBaseLevel) || updateMipLevel > mMaxLevel);
const bool isUpdateLevelOutsideRange = updateMipLevelGL < levelGLStart ||
updateMipLevelGL >= levelGLEnd ||
updateMipLevelGL > mMaxLevel;
// If the update layers don't intersect the requested layers, skip the update.
const bool areUpdateLayersOutsideRange =
......@@ -3970,10 +3974,10 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk,
continue;
}
uint32_t updateMipLevelVK = updateMipLevelGL - mBaseLevel;
if (mBaseLevel > 0)
{
// We need to shift the miplevel in the update to fall into the vkiamge
updateMipLevel -= mBaseLevel;
if (update.updateSource == UpdateSource::Clear)
{
update.clear.levelIndex -= mBaseLevel;
......@@ -3998,7 +4002,7 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk,
{
const uint64_t subresourceHashRange = angle::Bit<uint64_t>(updateLayerCount) - 1;
const uint32_t subresourceHashOffset =
(updateMipLevel * mLayerCount + updateBaseLayer) % kMaxParallelSubresourceUpload;
(updateMipLevelVK * mLayerCount + updateBaseLayer) % kMaxParallelSubresourceUpload;
const uint64_t subresourceHash =
ANGLE_ROTL64(subresourceHashRange, subresourceHashOffset);
......@@ -4013,8 +4017,8 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk,
if (update.updateSource == UpdateSource::Clear)
{
ASSERT(updateMipLevel == update.clear.levelIndex);
clear(update.clear.aspectFlags, update.clear.value, updateMipLevel, updateBaseLayer,
ASSERT(updateMipLevelVK == update.clear.levelIndex);
clear(update.clear.aspectFlags, update.clear.value, updateMipLevelVK, updateBaseLayer,
updateLayerCount, commandBuffer);
}
else if (update.updateSource == UpdateSource::Buffer)
......@@ -4061,7 +4065,7 @@ angle::Result ImageHelper::flushAllStagedUpdates(ContextVk *contextVk)
return flushStagedUpdates(contextVk, 0, mLevelCount, 0, mLayerCount, commandBuffer);
}
bool ImageHelper::isUpdateStaged(uint32_t level, uint32_t layer)
bool ImageHelper::isUpdateStaged(uint32_t levelGL, uint32_t layer)
{
// Check to see if any updates are staged for the given level and layer
......@@ -4072,25 +4076,25 @@ bool ImageHelper::isUpdateStaged(uint32_t level, uint32_t layer)
for (SubresourceUpdate &update : mSubresourceUpdates)
{
uint32_t updateMipLevel;
uint32_t updateMipLevelGL;
uint32_t updateBaseLayer;
uint32_t updateLayerCount;
if (update.updateSource == UpdateSource::Clear)
{
updateMipLevel = update.clear.levelIndex;
updateMipLevelGL = update.clear.levelIndex;
updateBaseLayer = update.clear.layerIndex;
updateLayerCount = update.clear.layerCount;
}
else
{
const VkImageSubresourceLayers &dstSubresource = update.dstSubresource();
updateMipLevel = dstSubresource.mipLevel;
updateMipLevelGL = dstSubresource.mipLevel;
updateBaseLayer = dstSubresource.baseArrayLayer;
updateLayerCount = dstSubresource.layerCount;
}
if (updateMipLevel == level)
if (updateMipLevelGL == levelGL)
{
if (layer >= updateBaseLayer && layer < (updateBaseLayer + updateLayerCount))
{
......@@ -4234,7 +4238,7 @@ angle::Result ImageHelper::GetReadPixelsParams(ContextVk *contextVk,
angle::Result ImageHelper::readPixelsForGetImage(ContextVk *contextVk,
const gl::PixelPackState &packState,
gl::Buffer *packBuffer,
uint32_t level,
uint32_t levelGL,
uint32_t layer,
GLenum format,
GLenum type,
......@@ -4271,9 +4275,10 @@ angle::Result ImageHelper::readPixelsForGetImage(ContextVk *contextVk,
PackPixelsParams params;
GLuint outputSkipBytes = 0;
uint32_t width = std::max(1u, mExtents.width >> level);
uint32_t height = std::max(1u, mExtents.height >> level);
uint32_t depth = std::max(1u, mExtents.depth >> level);
const uint32_t levelVK = levelGL - mBaseLevel;
const uint32_t width = std::max(1u, mExtents.width >> levelVK);
const uint32_t height = std::max(1u, mExtents.height >> levelVK);
const uint32_t depth = std::max(1u, mExtents.depth >> levelVK);
gl::Rectangle area(0, 0, width, height);
ANGLE_TRY(GetReadPixelsParams(contextVk, packState, packBuffer, format, type, area, area,
......@@ -4289,7 +4294,7 @@ angle::Result ImageHelper::readPixelsForGetImage(ContextVk *contextVk,
// Depth > 1 means this is a 3D texture and we need to copy all layers
for (layer = 0; layer < depth; layer++)
{
ANGLE_TRY(readPixels(contextVk, area, params, aspectFlags, level, layer,
ANGLE_TRY(readPixels(contextVk, area, params, aspectFlags, levelGL, layer,
static_cast<uint8_t *>(pixels) + outputSkipBytes,
&stagingBuffer.get()));
......@@ -4298,7 +4303,7 @@ angle::Result ImageHelper::readPixelsForGetImage(ContextVk *contextVk,
}
else
{
ANGLE_TRY(readPixels(contextVk, area, params, aspectFlags, level, layer,
ANGLE_TRY(readPixels(contextVk, area, params, aspectFlags, levelGL, layer,
static_cast<uint8_t *>(pixels) + outputSkipBytes,
&stagingBuffer.get()));
}
......@@ -4310,7 +4315,7 @@ angle::Result ImageHelper::readPixels(ContextVk *contextVk,
const gl::Rectangle &area,
const PackPixelsParams &packPixelsParams,
VkImageAspectFlagBits copyAspectFlags,
uint32_t level,
uint32_t levelGL,
uint32_t layer,
void *pixels,
DynamicBuffer *stagingBuffer)
......@@ -4326,7 +4331,7 @@ angle::Result ImageHelper::readPixels(ContextVk *contextVk,
ImageHelper *src = this;
ASSERT(!isUpdateStaged(level, layer));
ASSERT(!isUpdateStaged(levelGL, layer));
if (isMultisampled)
{
......@@ -4359,7 +4364,7 @@ angle::Result ImageHelper::readPixels(ContextVk *contextVk,
VkImageSubresourceLayers srcSubresource = {};
srcSubresource.aspectMask = copyAspectFlags;
srcSubresource.mipLevel = level;
srcSubresource.mipLevel = levelGL - mBaseLevel;
srcSubresource.baseArrayLayer = layer;
srcSubresource.layerCount = 1;
......@@ -4398,8 +4403,6 @@ angle::Result ImageHelper::readPixels(ContextVk *contextVk,
// Make the resolved image the target of buffer copy.
src = &resolvedImage.get();
level = 0;
layer = 0;
srcOffset = {0, 0, 0};
srcSubresource.baseArrayLayer = 0;
srcSubresource.layerCount = 1;
......@@ -4508,15 +4511,15 @@ void ImageHelper::SubresourceUpdate::release(RendererVk *renderer)
}
bool ImageHelper::SubresourceUpdate::isUpdateToLayerLevel(uint32_t layerIndex,
uint32_t levelIndex) const
uint32_t levelIndexGL) const
{
if (updateSource == UpdateSource::Clear)
{
return clear.levelIndex == levelIndex && clear.layerIndex == layerIndex;
return clear.levelIndex == levelIndexGL && clear.layerIndex == layerIndex;
}
const VkImageSubresourceLayers &dst = dstSubresource();
return dst.baseArrayLayer == layerIndex && dst.mipLevel == levelIndex;
return dst.baseArrayLayer == layerIndex && dst.mipLevel == levelIndexGL;
}
void ImageHelper::appendSubresourceUpdate(SubresourceUpdate &&update)
......
......@@ -1164,7 +1164,7 @@ class ImageHelper final : public Resource, public angle::Subject
void resolve(ImageHelper *dest, const VkImageResolve &region, CommandBuffer *commandBuffer);
// Data staging
void removeStagedUpdates(ContextVk *contextVk, uint32_t levelIndex, uint32_t layerIndex);
void removeStagedUpdates(ContextVk *contextVk, uint32_t levelIndexGL, uint32_t layerIndex);
angle::Result stageSubresourceUpdateImpl(ContextVk *contextVk,
const gl::ImageIndex &index,
......@@ -1198,7 +1198,7 @@ class ImageHelper final : public Resource, public angle::Subject
angle::Result stageSubresourceUpdateFromBuffer(ContextVk *contextVk,
size_t allocationSize,
uint32_t mipLevel,
uint32_t mipLevelGL,
uint32_t baseArrayLayer,
uint32_t layerCount,
uint32_t bufferRowLength,
......@@ -1246,7 +1246,7 @@ class ImageHelper final : public Resource, public angle::Subject
// Flush staged updates for a single subresource. Can optionally take a parameter to defer
// clears to a subsequent RenderPass load op.
angle::Result flushSingleSubresourceStagedUpdates(ContextVk *contextVk,
uint32_t level,
uint32_t levelGL,
uint32_t layer,
CommandBuffer *commandBuffer,
ClearValuesArray *deferredClears,
......@@ -1267,7 +1267,7 @@ class ImageHelper final : public Resource, public angle::Subject
// as with renderbuffers or surface images.
angle::Result flushAllStagedUpdates(ContextVk *contextVk);
bool isUpdateStaged(uint32_t level, uint32_t layer);
bool isUpdateStaged(uint32_t levelGL, uint32_t layer);
bool hasStagedUpdates() const { return !mSubresourceUpdates.empty(); }
// changeLayout automatically skips the layout change if it's unnecessary. This function can be
......@@ -1346,7 +1346,7 @@ class ImageHelper final : public Resource, public angle::Subject
angle::Result readPixelsForGetImage(ContextVk *contextVk,
const gl::PixelPackState &packState,
gl::Buffer *packBuffer,
uint32_t level,
uint32_t levelGL,
uint32_t layer,
GLenum format,
GLenum type,
......@@ -1356,7 +1356,7 @@ class ImageHelper final : public Resource, public angle::Subject
const gl::Rectangle &area,
const PackPixelsParams &packPixelsParams,
VkImageAspectFlagBits copyAspectFlags,
uint32_t level,
uint32_t levelGL,
uint32_t layer,
void *pixels,
DynamicBuffer *stagingBuffer);
......@@ -1411,11 +1411,12 @@ class ImageHelper final : public Resource, public angle::Subject
const VkImageSubresourceLayers &dstSubresource() const
{
// Note: destination mip level includes base level.
ASSERT(updateSource == UpdateSource::Buffer || updateSource == UpdateSource::Image);
return updateSource == UpdateSource::Buffer ? buffer.copyRegion.imageSubresource
: image.copyRegion.dstSubresource;
}
bool isUpdateToLayerLevel(uint32_t layerIndex, uint32_t levelIndex) const;
bool isUpdateToLayerLevel(uint32_t layerIndex, uint32_t levelIndexGL) const;
UpdateSource updateSource;
union
......
......@@ -464,9 +464,6 @@ TEST_P(FramebufferTest_ES3, TextureAttachmentMipLevels)
TEST_P(FramebufferTest_ES3, TextureAttachmentMipLevelsReadBack)
{
// http://anglebug.com/4695
ANGLE_SKIP_TEST_IF(IsVulkan());
GLFramebuffer framebuffer;
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
......
......@@ -2412,11 +2412,6 @@ TEST_P(Texture2DTestES3, FramebufferTextureChangingBaselevel)
// preserves the other mips' data.
TEST_P(Texture2DBaseMaxTestES3, ExtendMipChainAfterRedefine)
{
// Affected by two bugs:
// - http://anglebug.com/4695
// - http://anglebug.com/4696
ANGLE_SKIP_TEST_IF(IsVulkan());
// http://anglebug.com/4699
ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsOSX());
......@@ -2442,6 +2437,9 @@ TEST_P(Texture2DBaseMaxTestES3, ExtendMipChainAfterRedefine)
// Mip 1 is green. Verify this.
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
// http://anglebug.com/4696
ANGLE_SKIP_TEST_IF(IsVulkan());
// Add mip 0 and rebase the mip chain.
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kMip0Size, kMip0Size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
mipData.data() + getMipDataOffset(kMip0Size, 0));
......
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