mirror of
https://github.com/godotengine/godot-angle-static.git
synced 2026-01-06 02:09:55 +03:00
Vulkan: Fix EGL Surface robust init.
The error here was related to using a single cache variable for the robust init setting for all the surfaces in a DisplayVk. Fix this by passing down the robust init setting from the SurfaceVk to image init. Bug: angleproject:5274 Change-Id: I9bc9c20990268d1d5166411fb53f8f2593fd1971 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2510694 Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
This commit is contained in:
@@ -44,6 +44,11 @@ SurfaceState::~SurfaceState()
|
||||
delete config;
|
||||
}
|
||||
|
||||
bool SurfaceState::isRobustResourceInitEnabled() const
|
||||
{
|
||||
return attributes.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE;
|
||||
}
|
||||
|
||||
Surface::Surface(EGLint surfaceType,
|
||||
const egl::Config *config,
|
||||
const AttributeMap &attributes,
|
||||
|
||||
@@ -48,6 +48,8 @@ struct SurfaceState final : private angle::NonCopyable
|
||||
SurfaceState(const egl::Config *configIn, const AttributeMap &attributesIn);
|
||||
~SurfaceState();
|
||||
|
||||
bool isRobustResourceInitEnabled() const;
|
||||
|
||||
EGLLabelKHR label;
|
||||
const egl::Config *config;
|
||||
AttributeMap attributes;
|
||||
|
||||
@@ -469,12 +469,6 @@ CommandProcessor::CommandProcessor(RendererVk *renderer)
|
||||
|
||||
CommandProcessor::~CommandProcessor() = default;
|
||||
|
||||
bool CommandProcessor::isRobustResourceInitEnabled() const
|
||||
{
|
||||
// Unused for worker thread, just return false.
|
||||
return false;
|
||||
}
|
||||
|
||||
vk::Error CommandProcessor::getAndClearPendingError()
|
||||
{
|
||||
std::lock_guard<std::mutex> queueLock(mErrorMutex);
|
||||
|
||||
@@ -215,8 +215,6 @@ class CommandProcessor : public vk::Context
|
||||
const char *function,
|
||||
unsigned int line) override;
|
||||
|
||||
bool isRobustResourceInitEnabled() const override;
|
||||
|
||||
// Entry point for command processor thread, calls processTasksImpl to do the
|
||||
// work. called by RendererVk::initialization on main thread
|
||||
void processTasks();
|
||||
|
||||
@@ -641,7 +641,7 @@ class ContextVk : public ContextImpl, public vk::Context
|
||||
const ProgramExecutableVk *getExecutable() const { return mExecutable; }
|
||||
ProgramExecutableVk *getExecutable() { return mExecutable; }
|
||||
|
||||
bool isRobustResourceInitEnabled() const override;
|
||||
bool isRobustResourceInitEnabled() const;
|
||||
|
||||
// occlusion query
|
||||
void beginOcclusionQuery(QueryVk *queryVk);
|
||||
|
||||
@@ -26,8 +26,7 @@ DisplayVk::DisplayVk(const egl::DisplayState &state)
|
||||
: DisplayImpl(state),
|
||||
vk::Context(new RendererVk()),
|
||||
mScratchBuffer(1000u),
|
||||
mSavedError({VK_SUCCESS, "", "", 0}),
|
||||
mHasSurfaceWithRobustInit(false)
|
||||
mSavedError({VK_SUCCESS, "", "", 0})
|
||||
{}
|
||||
|
||||
DisplayVk::~DisplayVk()
|
||||
@@ -114,22 +113,12 @@ SurfaceImpl *DisplayVk::createWindowSurface(const egl::SurfaceState &state,
|
||||
EGLNativeWindowType window,
|
||||
const egl::AttributeMap &attribs)
|
||||
{
|
||||
if (attribs.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE)
|
||||
{
|
||||
mHasSurfaceWithRobustInit = true;
|
||||
}
|
||||
|
||||
return createWindowSurfaceVk(state, window);
|
||||
}
|
||||
|
||||
SurfaceImpl *DisplayVk::createPbufferSurface(const egl::SurfaceState &state,
|
||||
const egl::AttributeMap &attribs)
|
||||
{
|
||||
if (attribs.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE)
|
||||
{
|
||||
mHasSurfaceWithRobustInit = true;
|
||||
}
|
||||
|
||||
ASSERT(mRenderer);
|
||||
return new OffscreenSurfaceVk(state, mRenderer);
|
||||
}
|
||||
@@ -299,12 +288,6 @@ void DisplayVk::populateFeatureList(angle::FeatureList *features)
|
||||
mRenderer->getFeatures().populateFeatureList(features);
|
||||
}
|
||||
|
||||
bool DisplayVk::isRobustResourceInitEnabled() const
|
||||
{
|
||||
// We return true if any surface was created with robust resource init enabled.
|
||||
return mHasSurfaceWithRobustInit;
|
||||
}
|
||||
|
||||
void ShareGroupVk::onDestroy(const egl::Display *display)
|
||||
{
|
||||
DisplayVk *displayVk = vk::GetImpl(display);
|
||||
|
||||
@@ -124,8 +124,6 @@ class DisplayVk : public DisplayImpl, public vk::Context
|
||||
|
||||
void populateFeatureList(angle::FeatureList *features) override;
|
||||
|
||||
bool isRobustResourceInitEnabled() const override;
|
||||
|
||||
ShareGroupImpl *createShareGroup() override;
|
||||
|
||||
protected:
|
||||
@@ -141,7 +139,6 @@ class DisplayVk : public DisplayImpl, public vk::Context
|
||||
mutable angle::ScratchBuffer mScratchBuffer;
|
||||
|
||||
vk::Error mSavedError;
|
||||
bool mHasSurfaceWithRobustInit;
|
||||
};
|
||||
|
||||
} // namespace rx
|
||||
|
||||
@@ -1575,9 +1575,9 @@ angle::Result FramebufferVk::updateColorAttachment(const gl::Context *context,
|
||||
updateActiveColorMasks(colorIndexGL, actualFormat.redBits > 0, actualFormat.greenBits > 0,
|
||||
actualFormat.blueBits > 0, actualFormat.alphaBits > 0);
|
||||
|
||||
const angle::Format &sourceFormat = renderTarget->getImageFormat().intendedFormat();
|
||||
mEmulatedAlphaAttachmentMask.set(colorIndexGL,
|
||||
sourceFormat.alphaBits == 0 && actualFormat.alphaBits > 0);
|
||||
const angle::Format &intendedFormat = renderTarget->getImageFormat().intendedFormat();
|
||||
mEmulatedAlphaAttachmentMask.set(
|
||||
colorIndexGL, intendedFormat.alphaBits == 0 && actualFormat.alphaBits > 0);
|
||||
|
||||
contextVk->updateColorMasks(context->getState().getBlendStateExt());
|
||||
|
||||
|
||||
@@ -204,11 +204,11 @@ angle::Result MemoryObjectVk::createImage(ContextVk *contextVk,
|
||||
// ANGLE_external_objects_flags allows create flags to be specified by the application instead
|
||||
// of getting defaulted to zero. Note that the GL enum values constituting the bits of
|
||||
// |createFlags| are identical to their corresponding Vulkan value.
|
||||
ANGLE_TRY(image->initExternal(contextVk, type, vkExtents, vkFormat, 1, imageUsageFlags,
|
||||
createFlags, vk::ImageLayout::Undefined,
|
||||
&externalMemoryImageCreateInfo, gl::LevelIndex(0),
|
||||
gl::LevelIndex(static_cast<uint32_t>(levels) - 1),
|
||||
static_cast<uint32_t>(levels), layerCount));
|
||||
ANGLE_TRY(image->initExternal(
|
||||
contextVk, type, vkExtents, vkFormat, 1, imageUsageFlags, createFlags,
|
||||
vk::ImageLayout::Undefined, &externalMemoryImageCreateInfo, gl::LevelIndex(0),
|
||||
gl::LevelIndex(static_cast<uint32_t>(levels) - 1), static_cast<uint32_t>(levels),
|
||||
layerCount, contextVk->isRobustResourceInitEnabled()));
|
||||
|
||||
VkMemoryRequirements externalMemoryRequirements;
|
||||
image->getImage().getMemoryRequirements(renderer->getDevice(), &externalMemoryRequirements);
|
||||
|
||||
@@ -105,13 +105,16 @@ angle::Result OverlayVk::createFont(ContextVk *contextVk)
|
||||
ANGLE_TRY(fontDataBuffer.get().flush(renderer, 0, fontDataBuffer.get().getSize()));
|
||||
fontDataBuffer.get().unmap(renderer);
|
||||
|
||||
// Don't use robust resource init for overlay widgets.
|
||||
bool useRobustInit = false;
|
||||
|
||||
// Create the font image.
|
||||
ANGLE_TRY(
|
||||
mFontImage.init(contextVk, gl::TextureType::_2D,
|
||||
VkExtent3D{gl::overlay::kFontImageWidth, gl::overlay::kFontImageHeight, 1},
|
||||
renderer->getFormat(angle::FormatID::R8_UNORM), 1,
|
||||
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
gl::LevelIndex(0), gl::LevelIndex(0), 1, gl::overlay::kFontCount));
|
||||
ANGLE_TRY(mFontImage.init(
|
||||
contextVk, gl::TextureType::_2D,
|
||||
VkExtent3D{gl::overlay::kFontImageWidth, gl::overlay::kFontImageHeight, 1},
|
||||
renderer->getFormat(angle::FormatID::R8_UNORM), 1,
|
||||
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, gl::LevelIndex(0),
|
||||
gl::LevelIndex(0), 1, gl::overlay::kFontCount, useRobustInit));
|
||||
ANGLE_TRY(mFontImage.initMemory(contextVk, renderer->getMemoryProperties(),
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
|
||||
ANGLE_TRY(mFontImage.initImageView(contextVk, gl::TextureType::_2DArray,
|
||||
@@ -176,10 +179,13 @@ angle::Result OverlayVk::cullWidgets(ContextVk *contextVk)
|
||||
UnsignedCeilDivide(mPresentImageExtent.width, mSubgroupSize[0]),
|
||||
UnsignedCeilDivide(mPresentImageExtent.height, mSubgroupSize[1]), 1};
|
||||
|
||||
// Don't use robust resource init for overlay widgets.
|
||||
bool useRobustInit = false;
|
||||
|
||||
ANGLE_TRY(mCulledWidgets.init(contextVk, gl::TextureType::_2D, culledWidgetsExtent,
|
||||
renderer->getFormat(angle::FormatID::R32G32_UINT), 1,
|
||||
VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
gl::LevelIndex(0), gl::LevelIndex(0), 1, 1));
|
||||
gl::LevelIndex(0), gl::LevelIndex(0), 1, 1, useRobustInit));
|
||||
ANGLE_TRY(mCulledWidgets.initMemory(contextVk, renderer->getMemoryProperties(),
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
|
||||
ANGLE_TRY(mCulledWidgets.initImageView(contextVk, gl::TextureType::_2D,
|
||||
|
||||
@@ -97,9 +97,11 @@ angle::Result RenderbufferVk::setStorageImpl(const gl::Context *context,
|
||||
|
||||
const uint32_t imageSamples = isRenderToTexture ? 1 : samples;
|
||||
|
||||
bool robustInit = contextVk->isRobustResourceInitEnabled();
|
||||
|
||||
VkExtent3D extents = {static_cast<uint32_t>(width), static_cast<uint32_t>(height), 1u};
|
||||
ANGLE_TRY(mImage->init(contextVk, gl::TextureType::_2D, extents, vkFormat, imageSamples, usage,
|
||||
gl::LevelIndex(0), gl::LevelIndex(0), 1, 1));
|
||||
gl::LevelIndex(0), gl::LevelIndex(0), 1, 1, robustInit));
|
||||
|
||||
VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||
ANGLE_TRY(mImage->initMemory(contextVk, renderer->getMemoryProperties(), flags));
|
||||
@@ -112,7 +114,8 @@ angle::Result RenderbufferVk::setStorageImpl(const gl::Context *context,
|
||||
mMultisampledImageViews.init(renderer);
|
||||
|
||||
ANGLE_TRY(mMultisampledImage.initImplicitMultisampledRenderToTexture(
|
||||
contextVk, renderer->getMemoryProperties(), gl::TextureType::_2D, samples, *mImage));
|
||||
contextVk, renderer->getMemoryProperties(), gl::TextureType::_2D, samples, *mImage,
|
||||
robustInit));
|
||||
|
||||
mRenderTarget.init(&mMultisampledImage, &mMultisampledImageViews, mImage, &mImageViews,
|
||||
gl::LevelIndex(0), 0, RenderTargetTransience::MultisampledTransient);
|
||||
|
||||
@@ -160,7 +160,8 @@ angle::Result OffscreenSurfaceVk::AttachmentImage::initialize(DisplayVk *display
|
||||
EGLint width,
|
||||
EGLint height,
|
||||
const vk::Format &vkFormat,
|
||||
GLint samples)
|
||||
GLint samples,
|
||||
bool isRobustResourceInitEnabled)
|
||||
{
|
||||
RendererVk *renderer = displayVk->getRenderer();
|
||||
|
||||
@@ -172,7 +173,7 @@ angle::Result OffscreenSurfaceVk::AttachmentImage::initialize(DisplayVk *display
|
||||
VkExtent3D extents = {std::max(static_cast<uint32_t>(width), 1u),
|
||||
std::max(static_cast<uint32_t>(height), 1u), 1u};
|
||||
ANGLE_TRY(image.init(displayVk, gl::TextureType::_2D, extents, vkFormat, samples, usage,
|
||||
gl::LevelIndex(0), gl::LevelIndex(0), 1, 1));
|
||||
gl::LevelIndex(0), gl::LevelIndex(0), 1, 1, isRobustResourceInitEnabled));
|
||||
|
||||
VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||
ANGLE_TRY(image.initMemory(displayVk, renderer->getMemoryProperties(), flags));
|
||||
@@ -188,7 +189,8 @@ angle::Result OffscreenSurfaceVk::AttachmentImage::initializeWithExternalMemory(
|
||||
EGLint height,
|
||||
const vk::Format &vkFormat,
|
||||
GLint samples,
|
||||
void *buffer)
|
||||
void *buffer,
|
||||
bool isRobustResourceInitEnabled)
|
||||
{
|
||||
RendererVk *renderer = displayVk->getRenderer();
|
||||
|
||||
@@ -202,7 +204,7 @@ angle::Result OffscreenSurfaceVk::AttachmentImage::initializeWithExternalMemory(
|
||||
VkExtent3D extents = {std::max(static_cast<uint32_t>(width), 1u),
|
||||
std::max(static_cast<uint32_t>(height), 1u), 1u};
|
||||
ANGLE_TRY(image.init(displayVk, gl::TextureType::_2D, extents, vkFormat, samples, usage,
|
||||
gl::LevelIndex(0), gl::LevelIndex(0), 1, 1));
|
||||
gl::LevelIndex(0), gl::LevelIndex(0), 1, 1, isRobustResourceInitEnabled));
|
||||
|
||||
VkImportMemoryHostPointerInfoEXT importMemoryHostPointerInfo = {};
|
||||
importMemoryHostPointerInfo.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT;
|
||||
@@ -267,10 +269,13 @@ angle::Result OffscreenSurfaceVk::initializeImpl(DisplayVk *displayVk)
|
||||
GLint samples = GetSampleCount(mState.config);
|
||||
ANGLE_VK_CHECK(displayVk, samples > 0, VK_ERROR_INITIALIZATION_FAILED);
|
||||
|
||||
bool robustInit = mState.isRobustResourceInitEnabled();
|
||||
|
||||
if (config->renderTargetFormat != GL_NONE)
|
||||
{
|
||||
ANGLE_TRY(mColorAttachment.initialize(
|
||||
displayVk, mWidth, mHeight, renderer->getFormat(config->renderTargetFormat), samples));
|
||||
ANGLE_TRY(mColorAttachment.initialize(displayVk, mWidth, mHeight,
|
||||
renderer->getFormat(config->renderTargetFormat),
|
||||
samples, robustInit));
|
||||
mColorRenderTarget.init(&mColorAttachment.image, &mColorAttachment.imageViews, nullptr,
|
||||
nullptr, gl::LevelIndex(0), 0, RenderTargetTransience::Default);
|
||||
}
|
||||
@@ -278,7 +283,8 @@ angle::Result OffscreenSurfaceVk::initializeImpl(DisplayVk *displayVk)
|
||||
if (config->depthStencilFormat != GL_NONE)
|
||||
{
|
||||
ANGLE_TRY(mDepthStencilAttachment.initialize(
|
||||
displayVk, mWidth, mHeight, renderer->getFormat(config->depthStencilFormat), samples));
|
||||
displayVk, mWidth, mHeight, renderer->getFormat(config->depthStencilFormat), samples,
|
||||
robustInit));
|
||||
mDepthStencilRenderTarget.init(&mDepthStencilAttachment.image,
|
||||
&mDepthStencilAttachment.imageViews, nullptr, nullptr,
|
||||
gl::LevelIndex(0), 0, RenderTargetTransience::Default);
|
||||
@@ -994,12 +1000,15 @@ angle::Result WindowSurfaceVk::createSwapChain(vk::Context *context,
|
||||
VkExtent3D vkExtents;
|
||||
gl_vk::GetExtent(rotatedExtents, &vkExtents);
|
||||
|
||||
bool robustInit = mState.isRobustResourceInitEnabled();
|
||||
|
||||
if (samples > 1)
|
||||
{
|
||||
const VkImageUsageFlags usage = kSurfaceVkColorImageUsageFlags;
|
||||
|
||||
ANGLE_TRY(mColorImageMS.init(context, gl::TextureType::_2D, vkExtents, format, samples,
|
||||
usage, gl::LevelIndex(0), gl::LevelIndex(0), 1, 1));
|
||||
usage, gl::LevelIndex(0), gl::LevelIndex(0), 1, 1,
|
||||
robustInit));
|
||||
ANGLE_TRY(mColorImageMS.initMemory(context, renderer->getMemoryProperties(),
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
|
||||
|
||||
@@ -1014,7 +1023,8 @@ angle::Result WindowSurfaceVk::createSwapChain(vk::Context *context,
|
||||
for (uint32_t imageIndex = 0; imageIndex < imageCount; ++imageIndex)
|
||||
{
|
||||
SwapchainImage &member = mSwapchainImages[imageIndex];
|
||||
member.image.init2DWeakReference(context, swapchainImages[imageIndex], extents, format, 1);
|
||||
member.image.init2DWeakReference(context, swapchainImages[imageIndex], extents, format, 1,
|
||||
robustInit);
|
||||
member.imageViews.init(renderer);
|
||||
}
|
||||
|
||||
@@ -1027,7 +1037,7 @@ angle::Result WindowSurfaceVk::createSwapChain(vk::Context *context,
|
||||
|
||||
ANGLE_TRY(mDepthStencilImage.init(context, gl::TextureType::_2D, vkExtents, dsFormat,
|
||||
samples, dsUsage, gl::LevelIndex(0), gl::LevelIndex(0), 1,
|
||||
1));
|
||||
1, robustInit));
|
||||
ANGLE_TRY(mDepthStencilImage.initMemory(context, renderer->getMemoryProperties(),
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
|
||||
|
||||
|
||||
@@ -87,14 +87,16 @@ class OffscreenSurfaceVk : public SurfaceVk
|
||||
EGLint width,
|
||||
EGLint height,
|
||||
const vk::Format &vkFormat,
|
||||
GLint samples);
|
||||
GLint samples,
|
||||
bool isRobustResourceInitEnabled);
|
||||
|
||||
angle::Result initializeWithExternalMemory(DisplayVk *displayVk,
|
||||
EGLint width,
|
||||
EGLint height,
|
||||
const vk::Format &vkFormat,
|
||||
GLint samples,
|
||||
void *buffer);
|
||||
void *buffer,
|
||||
bool isRobustResourceInitEnabled);
|
||||
|
||||
void destroy(const egl::Display *display);
|
||||
|
||||
|
||||
@@ -1920,9 +1920,13 @@ angle::Result TextureVk::getAttachmentRenderTarget(const gl::Context *context,
|
||||
RendererVk *renderer = contextVk->getRenderer();
|
||||
mMultisampledImageViews[renderToTextureIndex].init(renderer);
|
||||
|
||||
// The MSAA image always comes from the single sampled one, so disable robust init.
|
||||
bool useRobustInit = false;
|
||||
|
||||
// Create the implicit multisampled image.
|
||||
ANGLE_TRY(multisampledImage->initImplicitMultisampledRenderToTexture(
|
||||
contextVk, renderer->getMemoryProperties(), mState.getType(), samples, *mImage));
|
||||
contextVk, renderer->getMemoryProperties(), mState.getType(), samples, *mImage,
|
||||
useRobustInit));
|
||||
}
|
||||
|
||||
// Don't flush staged updates here. We'll handle that in FramebufferVk so it can defer clears.
|
||||
@@ -2382,10 +2386,11 @@ angle::Result TextureVk::initImage(ContextVk *contextVk,
|
||||
gl_vk::GetExtentsAndLayerCount(mState.getType(), extents, &vkExtent, &layerCount);
|
||||
GLint samples = mState.getBaseLevelDesc().samples ? mState.getBaseLevelDesc().samples : 1;
|
||||
|
||||
ANGLE_TRY(mImage->initExternal(
|
||||
contextVk, mState.getType(), vkExtent, format, samples, mImageUsageFlags, mImageCreateFlags,
|
||||
vk::ImageLayout::Undefined, nullptr, gl::LevelIndex(mState.getEffectiveBaseLevel()),
|
||||
gl::LevelIndex(mState.getEffectiveMaxLevel()), levelCount, layerCount));
|
||||
ANGLE_TRY(mImage->initExternal(contextVk, mState.getType(), vkExtent, format, samples,
|
||||
mImageUsageFlags, mImageCreateFlags, vk::ImageLayout::Undefined,
|
||||
nullptr, gl::LevelIndex(mState.getEffectiveBaseLevel()),
|
||||
gl::LevelIndex(mState.getEffectiveMaxLevel()), levelCount,
|
||||
layerCount, contextVk->isRobustResourceInitEnabled()));
|
||||
|
||||
const VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||
|
||||
|
||||
@@ -202,12 +202,16 @@ angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk
|
||||
|
||||
mImage = new vk::ImageHelper();
|
||||
|
||||
// disable robust init for this external image.
|
||||
bool robustInitEnabled = false;
|
||||
|
||||
mImage->setTilingMode(imageTilingMode);
|
||||
ANGLE_TRY(mImage->initExternal(
|
||||
displayVk, gl::TextureType::_2D, vkExtents,
|
||||
bufferFormatProperties.format == VK_FORMAT_UNDEFINED ? externalVkFormat : vkFormat, 1,
|
||||
usage, vk::kVkImageCreateFlagsNone, vk::ImageLayout::ExternalPreInitialized,
|
||||
&externalMemoryImageCreateInfo, gl::LevelIndex(0), gl::LevelIndex(0), 1, 1));
|
||||
&externalMemoryImageCreateInfo, gl::LevelIndex(0), gl::LevelIndex(0), 1, 1,
|
||||
robustInitEnabled));
|
||||
|
||||
VkImportAndroidHardwareBufferInfoANDROID importHardwareBufferInfo = {};
|
||||
importHardwareBufferInfo.sType = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID;
|
||||
|
||||
@@ -117,7 +117,7 @@ angle::Result IOSurfaceSurfaceVkMac::initializeImpl(DisplayVk *displayVk)
|
||||
ANGLE_TRY(mColorAttachment.initializeWithExternalMemory(
|
||||
displayVk, mWidth, mHeight,
|
||||
renderer->getFormat(kIOSurfaceFormats[mFormatIndex].nativeSizedInternalFormat), samples,
|
||||
IOSurfaceGetBaseAddressOfPlane(mIOSurface, mPlane)));
|
||||
IOSurfaceGetBaseAddressOfPlane(mIOSurface, mPlane), mState.isRobustResourceInitEnabled()));
|
||||
mColorRenderTarget.init(&mColorAttachment.image, &mColorAttachment.imageViews, nullptr, nullptr,
|
||||
gl::LevelIndex(0), 0, RenderTargetTransience::Default);
|
||||
|
||||
|
||||
@@ -3230,11 +3230,12 @@ angle::Result ImageHelper::init(Context *context,
|
||||
gl::LevelIndex baseLevel,
|
||||
gl::LevelIndex maxLevel,
|
||||
uint32_t mipLevels,
|
||||
uint32_t layerCount)
|
||||
uint32_t layerCount,
|
||||
bool isRobustResourceInitEnabled)
|
||||
{
|
||||
return initExternal(context, textureType, extents, format, samples, usage,
|
||||
kVkImageCreateFlagsNone, ImageLayout::Undefined, nullptr, baseLevel,
|
||||
maxLevel, mipLevels, layerCount);
|
||||
maxLevel, mipLevels, layerCount, isRobustResourceInitEnabled);
|
||||
}
|
||||
|
||||
angle::Result ImageHelper::initExternal(Context *context,
|
||||
@@ -3249,7 +3250,8 @@ angle::Result ImageHelper::initExternal(Context *context,
|
||||
gl::LevelIndex baseLevel,
|
||||
gl::LevelIndex maxLevel,
|
||||
uint32_t mipLevels,
|
||||
uint32_t layerCount)
|
||||
uint32_t layerCount,
|
||||
bool isRobustResourceInitEnabled)
|
||||
{
|
||||
ASSERT(!valid());
|
||||
ASSERT(!IsAnySubresourceContentDefined(mContentDefined));
|
||||
@@ -3297,7 +3299,7 @@ angle::Result ImageHelper::initExternal(Context *context,
|
||||
|
||||
ANGLE_VK_TRY(context, mImage.init(context->getDevice(), imageInfo));
|
||||
|
||||
stageClearIfEmulatedFormat(context);
|
||||
stageClearIfEmulatedFormat(isRobustResourceInitEnabled);
|
||||
|
||||
if (initialLayout != ImageLayout::Undefined)
|
||||
{
|
||||
@@ -3625,7 +3627,8 @@ void ImageHelper::init2DWeakReference(Context *context,
|
||||
VkImage handle,
|
||||
const gl::Extents &glExtents,
|
||||
const Format &format,
|
||||
GLint samples)
|
||||
GLint samples,
|
||||
bool isRobustResourceInitEnabled)
|
||||
{
|
||||
ASSERT(!valid());
|
||||
ASSERT(!IsAnySubresourceContentDefined(mContentDefined));
|
||||
@@ -3641,7 +3644,7 @@ void ImageHelper::init2DWeakReference(Context *context,
|
||||
|
||||
mImage.setHandle(handle);
|
||||
|
||||
stageClearIfEmulatedFormat(context);
|
||||
stageClearIfEmulatedFormat(isRobustResourceInitEnabled);
|
||||
}
|
||||
|
||||
angle::Result ImageHelper::init2DStaging(Context *context,
|
||||
@@ -3695,7 +3698,8 @@ angle::Result ImageHelper::initImplicitMultisampledRenderToTexture(
|
||||
const MemoryProperties &memoryProperties,
|
||||
gl::TextureType textureType,
|
||||
GLint samples,
|
||||
const ImageHelper &resolveImage)
|
||||
const ImageHelper &resolveImage,
|
||||
bool isRobustResourceInitEnabled)
|
||||
{
|
||||
ASSERT(!valid());
|
||||
ASSERT(samples > 1);
|
||||
@@ -3721,11 +3725,11 @@ angle::Result ImageHelper::initImplicitMultisampledRenderToTexture(
|
||||
: VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
||||
constexpr VkImageCreateFlags kMultisampledCreateFlags = 0;
|
||||
|
||||
ANGLE_TRY(initExternal(context, textureType, resolveImage.getExtents(),
|
||||
resolveImage.getFormat(), samples, kMultisampledUsageFlags,
|
||||
kMultisampledCreateFlags, ImageLayout::Undefined, nullptr,
|
||||
resolveImage.getBaseLevel(), resolveImage.getMaxLevel(),
|
||||
resolveImage.getLevelCount(), resolveImage.getLayerCount()));
|
||||
ANGLE_TRY(initExternal(
|
||||
context, textureType, resolveImage.getExtents(), resolveImage.getFormat(), samples,
|
||||
kMultisampledUsageFlags, kMultisampledCreateFlags, ImageLayout::Undefined, nullptr,
|
||||
resolveImage.getBaseLevel(), resolveImage.getMaxLevel(), resolveImage.getLevelCount(),
|
||||
resolveImage.getLayerCount(), isRobustResourceInitEnabled));
|
||||
|
||||
const VkMemoryPropertyFlags kMultisampledMemoryFlags =
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
|
||||
@@ -4851,10 +4855,10 @@ angle::Result ImageHelper::stageRobustResourceClearWithFormat(ContextVk *context
|
||||
return angle::Result::Continue;
|
||||
}
|
||||
|
||||
void ImageHelper::stageClearIfEmulatedFormat(Context *context)
|
||||
void ImageHelper::stageClearIfEmulatedFormat(bool isRobustResourceInitEnabled)
|
||||
{
|
||||
// Skip staging extra clears if robust resource init is enabled.
|
||||
if (!mFormat->hasEmulatedImageChannels() || context->isRobustResourceInitEnabled())
|
||||
if (!mFormat->hasEmulatedImageChannels() || isRobustResourceInitEnabled)
|
||||
return;
|
||||
|
||||
VkClearValue clearValue;
|
||||
|
||||
@@ -1276,7 +1276,8 @@ class ImageHelper final : public Resource, public angle::Subject
|
||||
gl::LevelIndex baseLevel,
|
||||
gl::LevelIndex maxLevel,
|
||||
uint32_t mipLevels,
|
||||
uint32_t layerCount);
|
||||
uint32_t layerCount,
|
||||
bool isRobustResourceInitEnabled);
|
||||
angle::Result initExternal(Context *context,
|
||||
gl::TextureType textureType,
|
||||
const VkExtent3D &extents,
|
||||
@@ -1289,7 +1290,8 @@ class ImageHelper final : public Resource, public angle::Subject
|
||||
gl::LevelIndex baseLevel,
|
||||
gl::LevelIndex maxLevel,
|
||||
uint32_t mipLevels,
|
||||
uint32_t layerCount);
|
||||
uint32_t layerCount,
|
||||
bool isRobustResourceInitEnabled);
|
||||
angle::Result initMemory(Context *context,
|
||||
const MemoryProperties &memoryProperties,
|
||||
VkMemoryPropertyFlags flags);
|
||||
@@ -1345,7 +1347,8 @@ class ImageHelper final : public Resource, public angle::Subject
|
||||
const MemoryProperties &memoryProperties,
|
||||
gl::TextureType textureType,
|
||||
GLint samples,
|
||||
const ImageHelper &resolveImage);
|
||||
const ImageHelper &resolveImage,
|
||||
bool isRobustResourceInitEnabled);
|
||||
// Release the underlining VkImage object for garbage collection.
|
||||
void releaseImage(RendererVk *renderer);
|
||||
// Similar to releaseImage, but also notify all contexts in the same share group to stop
|
||||
@@ -1365,7 +1368,8 @@ class ImageHelper final : public Resource, public angle::Subject
|
||||
VkImage handle,
|
||||
const gl::Extents &glExtents,
|
||||
const Format &format,
|
||||
GLint samples);
|
||||
GLint samples,
|
||||
bool isRobustResourceInitEnabled);
|
||||
void resetImageWeakReference();
|
||||
|
||||
const Image &getImage() const { return mImage; }
|
||||
@@ -1743,7 +1747,7 @@ class ImageHelper final : public Resource, public angle::Subject
|
||||
|
||||
// If the image has emulated channels, we clear them once so as not to leave garbage on those
|
||||
// channels.
|
||||
void stageClearIfEmulatedFormat(Context *context);
|
||||
void stageClearIfEmulatedFormat(bool isRobustResourceInitEnabled);
|
||||
|
||||
void clearColor(const VkClearColorValue &color,
|
||||
LevelIndex baseMipLevelVk,
|
||||
|
||||
@@ -174,10 +174,6 @@ class Context : angle::NonCopyable
|
||||
VkDevice getDevice() const;
|
||||
RendererVk *getRenderer() const { return mRenderer; }
|
||||
|
||||
// This is a special override needed so we can determine if we need to initialize images.
|
||||
// It corresponds to the EGL or GL extensions depending on the vk::Context type.
|
||||
virtual bool isRobustResourceInitEnabled() const = 0;
|
||||
|
||||
protected:
|
||||
RendererVk *const mRenderer;
|
||||
};
|
||||
|
||||
@@ -50,37 +50,47 @@ class EGLSurfaceTest : public ANGLETest
|
||||
mOSWindow->initialize("EGLSurfaceTest", 64, 64);
|
||||
}
|
||||
|
||||
void tearDownContextAndSurface()
|
||||
{
|
||||
if (mDisplay == EGL_NO_DISPLAY)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
|
||||
if (mWindowSurface != EGL_NO_SURFACE)
|
||||
{
|
||||
eglDestroySurface(mDisplay, mWindowSurface);
|
||||
mWindowSurface = EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
if (mPbufferSurface != EGL_NO_SURFACE)
|
||||
{
|
||||
eglDestroySurface(mDisplay, mPbufferSurface);
|
||||
mPbufferSurface = EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
if (mContext != EGL_NO_CONTEXT)
|
||||
{
|
||||
eglDestroyContext(mDisplay, mContext);
|
||||
mContext = EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
if (mSecondContext != EGL_NO_CONTEXT)
|
||||
{
|
||||
eglDestroyContext(mDisplay, mSecondContext);
|
||||
mSecondContext = EGL_NO_CONTEXT;
|
||||
}
|
||||
}
|
||||
|
||||
// Release any resources created in the test body
|
||||
void testTearDown() override
|
||||
{
|
||||
tearDownContextAndSurface();
|
||||
|
||||
if (mDisplay != EGL_NO_DISPLAY)
|
||||
{
|
||||
eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
|
||||
if (mWindowSurface != EGL_NO_SURFACE)
|
||||
{
|
||||
eglDestroySurface(mDisplay, mWindowSurface);
|
||||
mWindowSurface = EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
if (mPbufferSurface != EGL_NO_SURFACE)
|
||||
{
|
||||
eglDestroySurface(mDisplay, mPbufferSurface);
|
||||
mPbufferSurface = EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
if (mContext != EGL_NO_CONTEXT)
|
||||
{
|
||||
eglDestroyContext(mDisplay, mContext);
|
||||
mContext = EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
if (mSecondContext != EGL_NO_CONTEXT)
|
||||
{
|
||||
eglDestroyContext(mDisplay, mSecondContext);
|
||||
mSecondContext = EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
eglTerminate(mDisplay);
|
||||
mDisplay = EGL_NO_DISPLAY;
|
||||
}
|
||||
@@ -119,29 +129,33 @@ class EGLSurfaceTest : public ANGLETest
|
||||
ASSERT_EGL_SUCCESS();
|
||||
}
|
||||
|
||||
void initializeContext()
|
||||
void initializeSingleContext(EGLContext *context)
|
||||
{
|
||||
EGLint contextAttibutes[] = {EGL_CONTEXT_CLIENT_VERSION, GetParam().majorVersion, EGL_NONE};
|
||||
|
||||
mContext = eglCreateContext(mDisplay, mConfig, nullptr, contextAttibutes);
|
||||
ASSERT_EGL_SUCCESS();
|
||||
|
||||
mSecondContext = eglCreateContext(mDisplay, mConfig, nullptr, contextAttibutes);
|
||||
*context = eglCreateContext(mDisplay, mConfig, nullptr, contextAttibutes);
|
||||
ASSERT_EGL_SUCCESS();
|
||||
}
|
||||
|
||||
void initializeSurface(EGLConfig config)
|
||||
void initializeContext()
|
||||
{
|
||||
initializeSingleContext(&mContext);
|
||||
initializeSingleContext(&mSecondContext);
|
||||
}
|
||||
|
||||
void initializeSurfaceWithAttribs(EGLConfig config,
|
||||
const std::vector<EGLint> &additionalAttributes)
|
||||
{
|
||||
mConfig = config;
|
||||
|
||||
EGLint surfaceType = EGL_NONE;
|
||||
eglGetConfigAttrib(mDisplay, mConfig, EGL_SURFACE_TYPE, &surfaceType);
|
||||
|
||||
std::vector<EGLint> windowAttributes;
|
||||
windowAttributes.push_back(EGL_NONE);
|
||||
|
||||
if (surfaceType & EGL_WINDOW_BIT)
|
||||
{
|
||||
std::vector<EGLint> windowAttributes = additionalAttributes;
|
||||
windowAttributes.push_back(EGL_NONE);
|
||||
|
||||
// Create first window surface
|
||||
mWindowSurface = eglCreateWindowSurface(mDisplay, mConfig, mOSWindow->getNativeWindow(),
|
||||
windowAttributes.data());
|
||||
@@ -150,8 +164,9 @@ class EGLSurfaceTest : public ANGLETest
|
||||
|
||||
if (surfaceType & EGL_PBUFFER_BIT)
|
||||
{
|
||||
std::vector<EGLint> pbufferAttributes = additionalAttributes;
|
||||
|
||||
// Give pbuffer non-zero dimensions.
|
||||
std::vector<EGLint> pbufferAttributes;
|
||||
pbufferAttributes.push_back(EGL_WIDTH);
|
||||
pbufferAttributes.push_back(64);
|
||||
pbufferAttributes.push_back(EGL_HEIGHT);
|
||||
@@ -165,7 +180,13 @@ class EGLSurfaceTest : public ANGLETest
|
||||
initializeContext();
|
||||
}
|
||||
|
||||
void initializeSurfaceWithDefaultConfig(bool requireWindowSurface)
|
||||
void initializeSurface(EGLConfig config)
|
||||
{
|
||||
std::vector<EGLint> additionalAttributes;
|
||||
initializeSurfaceWithAttribs(config, additionalAttributes);
|
||||
}
|
||||
|
||||
EGLConfig chooseDefaultConfig(bool requireWindowSurface) const
|
||||
{
|
||||
const EGLint configAttributes[] = {EGL_RED_SIZE,
|
||||
EGL_DONT_CARE,
|
||||
@@ -187,10 +208,18 @@ class EGLSurfaceTest : public ANGLETest
|
||||
|
||||
EGLint configCount;
|
||||
EGLConfig config;
|
||||
ASSERT_TRUE(eglChooseConfig(mDisplay, configAttributes, &config, 1, &configCount) ||
|
||||
(configCount != 1) == EGL_TRUE);
|
||||
if (eglChooseConfig(mDisplay, configAttributes, &config, 1, &configCount) != EGL_TRUE)
|
||||
return nullptr;
|
||||
if (configCount != 1)
|
||||
return nullptr;
|
||||
return config;
|
||||
}
|
||||
|
||||
initializeSurface(config);
|
||||
void initializeSurfaceWithDefaultConfig(bool requireWindowSurface)
|
||||
{
|
||||
EGLConfig defaultConfig = chooseDefaultConfig(requireWindowSurface);
|
||||
ASSERT_NE(defaultConfig, nullptr);
|
||||
initializeSurface(defaultConfig);
|
||||
}
|
||||
|
||||
GLuint createProgram()
|
||||
@@ -1162,6 +1191,102 @@ TEST_P(EGLSurfaceTestD3D11, CreateSurfaceWithMSAA)
|
||||
|
||||
#endif // ANGLE_ENABLE_D3D11
|
||||
|
||||
// Verify switching between a surface with robust resource init and one without still clears alpha.
|
||||
TEST_P(EGLSurfaceTest, RobustResourceInitAndEmulatedAlpha)
|
||||
{
|
||||
// http://anglebug.com/5279
|
||||
ANGLE_SKIP_TEST_IF(IsNVIDIA() && isGLRenderer() && IsLinux());
|
||||
|
||||
// http://anglebug.com/5280
|
||||
ANGLE_SKIP_TEST_IF(IsAndroid() && IsNexus5X() && isGLESRenderer());
|
||||
|
||||
initializeDisplay();
|
||||
ASSERT_NE(mDisplay, EGL_NO_DISPLAY);
|
||||
|
||||
ANGLE_SKIP_TEST_IF(
|
||||
!IsEGLDisplayExtensionEnabled(mDisplay, "EGL_ANGLE_robust_resource_initialization"));
|
||||
|
||||
// Initialize and draw red to a Surface with robust resource init enabled.
|
||||
constexpr EGLint kRGBAAttributes[] = {EGL_RED_SIZE, 8,
|
||||
EGL_GREEN_SIZE, 8,
|
||||
EGL_BLUE_SIZE, 8,
|
||||
EGL_ALPHA_SIZE, 8,
|
||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||
EGL_NONE};
|
||||
|
||||
EGLint configCount = 0;
|
||||
EGLConfig rgbaConfig = nullptr;
|
||||
ASSERT_EGL_TRUE(eglChooseConfig(mDisplay, kRGBAAttributes, &rgbaConfig, 1, &configCount));
|
||||
ASSERT_EQ(configCount, 1);
|
||||
ASSERT_NE(rgbaConfig, nullptr);
|
||||
|
||||
std::vector<EGLint> robustInitAttribs;
|
||||
robustInitAttribs.push_back(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE);
|
||||
robustInitAttribs.push_back(EGL_TRUE);
|
||||
|
||||
initializeSurfaceWithAttribs(rgbaConfig, robustInitAttribs);
|
||||
ASSERT_EGL_SUCCESS();
|
||||
ASSERT_NE(mWindowSurface, EGL_NO_SURFACE);
|
||||
|
||||
initializeSingleContext(&mContext);
|
||||
ASSERT_EGL_SUCCESS();
|
||||
ASSERT_NE(mContext, EGL_NO_CONTEXT);
|
||||
|
||||
eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
|
||||
ASSERT_EGL_SUCCESS();
|
||||
eglSwapBuffers(mDisplay, mWindowSurface);
|
||||
|
||||
// RGBA robust init setup complete. Draw red and verify.
|
||||
{
|
||||
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
|
||||
glUseProgram(program);
|
||||
|
||||
drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
|
||||
|
||||
eglSwapBuffers(mDisplay, mWindowSurface);
|
||||
}
|
||||
|
||||
tearDownContextAndSurface();
|
||||
|
||||
// Create second RGB surface with robust resource disabled.
|
||||
constexpr EGLint kRGBAttributes[] = {EGL_RED_SIZE, 8,
|
||||
EGL_GREEN_SIZE, 8,
|
||||
EGL_BLUE_SIZE, 8,
|
||||
EGL_ALPHA_SIZE, 0,
|
||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||
EGL_NONE};
|
||||
|
||||
configCount = 0;
|
||||
EGLConfig rgbConfig = nullptr;
|
||||
ASSERT_EGL_TRUE(eglChooseConfig(mDisplay, kRGBAttributes, &rgbConfig, 1, &configCount));
|
||||
ASSERT_EQ(configCount, 1);
|
||||
ASSERT_NE(rgbConfig, nullptr);
|
||||
|
||||
initializeSurface(rgbConfig);
|
||||
ASSERT_EGL_SUCCESS();
|
||||
ASSERT_NE(mWindowSurface, EGL_NO_SURFACE);
|
||||
|
||||
initializeSingleContext(&mContext);
|
||||
ASSERT_EGL_SUCCESS();
|
||||
ASSERT_NE(mContext, EGL_NO_CONTEXT);
|
||||
|
||||
eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
|
||||
ASSERT_EGL_SUCCESS();
|
||||
|
||||
// RGB non-robust init setup complete. Draw red and verify.
|
||||
{
|
||||
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
|
||||
glUseProgram(program);
|
||||
|
||||
drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
|
||||
|
||||
eglSwapBuffers(mDisplay, mWindowSurface);
|
||||
}
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
ANGLE_INSTANTIATE_TEST(EGLSurfaceTest,
|
||||
|
||||
Reference in New Issue
Block a user