Commit e2881e25 by Mohan Maiya Committed by Angle LUCI CQ

Vulkan: Handle incompatible pipeline layouts

It is necessary that a pipeline layout be compatible with active textures. Make sure to recreate the pipeline layout otherwise. Bug: b/155487768 Bug: angleproject:5033 Bug: angleproject:5773 Test: ImageTest.SourceAHBTarget2DExternalCycleThroughRgbAndYuvTargets*Vulkan Change-Id: Iab371a9035b6cd143585e5000e2e68c7302ef447 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2992056 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent 5f869b74
......@@ -4995,7 +4995,8 @@ angle::Result ContextVk::updateActiveTextures(const gl::Context *context)
const gl::ActiveTextureMask &activeTextures = executable->getActiveSamplersMask();
const gl::ActiveTextureTypeArray &textureTypes = executable->getActiveSamplerTypes();
bool recreatePipelineLayout = false;
bool anyTextureHasImmutableSampler = false;
bool recreatePipelineLayout = false;
for (size_t textureUnit : activeTextures)
{
gl::Texture *texture = textures[textureUnit];
......@@ -5073,10 +5074,17 @@ angle::Result ContextVk::updateActiveTextures(const gl::Context *context)
textureVk->getImageViewSubresourceSerial(samplerState);
mActiveTexturesDesc.update(textureUnit, imageViewSerial, samplerHelper.getSamplerSerial());
anyTextureHasImmutableSampler =
textureVk->getImage().hasImmutableSampler() || anyTextureHasImmutableSampler;
recreatePipelineLayout =
textureVk->getAndResetImmutableSamplerDirtyState() || recreatePipelineLayout;
}
if (anyTextureHasImmutableSampler != mExecutable->usesImmutableSamplers())
{
recreatePipelineLayout = true;
}
// Recreate the pipeline layout, if necessary.
if (recreatePipelineLayout)
{
......
......@@ -248,6 +248,7 @@ void ProgramInfo::release(ContextVk *contextVk)
ProgramExecutableVk::ProgramExecutableVk()
: mEmptyDescriptorSets{},
mNumDefaultUniformDescriptors(0),
mUsesImmutableSamplers(false),
mUniformBufferDescriptorType(VK_DESCRIPTOR_TYPE_MAX_ENUM),
mProgram(nullptr),
mProgramPipeline(nullptr),
......@@ -266,6 +267,7 @@ void ProgramExecutableVk::reset(ContextVk *contextVk)
{
descriptorSetLayout.reset();
}
mUsesImmutableSamplers = false;
mPipelineLayout.reset();
mDescriptorSets.fill(VK_NULL_HANDLE);
......@@ -703,6 +705,7 @@ void ProgramExecutableVk::addTextureDescriptorSetDesc(
(*activeTextures)[textureUnit].texture->getSampler().get();
descOut->update(info.binding, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, arraySize,
activeStages, &immutableSampler);
mUsesImmutableSamplers = true;
}
else
{
......
......@@ -192,6 +192,8 @@ class ProgramExecutableVk
return mUniformBufferDescriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
}
bool usesImmutableSamplers() const { return mUsesImmutableSamplers; }
void accumulateCacheStats(VulkanCacheType cacheType, const CacheStats &cacheStats);
ProgramExecutablePerfCounters getAndResetObjectPerfCounters();
......@@ -275,6 +277,7 @@ class ProgramExecutableVk
// We keep a reference to the pipeline and descriptor set layouts. This ensures they don't get
// deleted while this program is in use.
bool mUsesImmutableSamplers;
vk::BindingPointer<vk::PipelineLayout> mPipelineLayout;
vk::DescriptorSetLayoutPointerArray mDescriptorSetLayouts;
......
......@@ -2030,6 +2030,90 @@ TEST_P(ImageTest, SourceAHBTarget2DExternalCycleThroughRgbAndYuvSources)
destroyAndroidHardwareBuffer(rgbSource);
}
// Testing source AHB EGL images, target 2D external textures, cycling through RGB and YUV targets.
TEST_P(ImageTest, SourceAHBTarget2DExternalCycleThroughRgbAndYuvTargets)
{
// http://issuetracker.google.com/175021871
ANGLE_SKIP_TEST_IF(IsPixel2() || IsPixel2XL());
ANGLE_SKIP_TEST_IF(!IsAndroid());
EGLWindow *window = getEGLWindow();
ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
// Create RGBA Image
GLubyte rgbaColor[4] = {0, 0, 255, 255};
AHardwareBuffer *rgbaSource;
EGLImageKHR rgbaImage;
createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
kDefaultAttribs, {{rgbaColor, 4}}, &rgbaSource,
&rgbaImage);
// Create YUV Image
// 3 planes of data
GLubyte dataY[4] = {40, 40, 40, 40};
GLubyte dataCb[1] = {
240,
};
GLubyte dataCr[1] = {
109,
};
GLubyte expectedRgbColor[4] = {0, 0, 255, 255};
AHardwareBuffer *yuvSource;
EGLImageKHR yuvImage;
createEGLImageAndroidHardwareBufferSource(
2, 2, 1, AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420, kDefaultAttribs,
{{dataY, 1}, {dataCb, 1}, {dataCr, 1}}, &yuvSource, &yuvImage);
// Create texture target siblings to bind the egl images
// Create YUV target and bind the image
GLTexture yuvTarget;
glBindTexture(GL_TEXTURE_EXTERNAL_OES, yuvTarget);
// Disable mipmapping
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
ASSERT_GL_NO_ERROR();
glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, yuvImage);
ASSERT_GL_NO_ERROR();
// Create RGBA target and bind the image
GLTexture rgbaTarget;
glBindTexture(GL_TEXTURE_EXTERNAL_OES, rgbaTarget);
// Disable mipmapping
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
ASSERT_GL_NO_ERROR();
glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, rgbaImage);
ASSERT_GL_NO_ERROR();
// Cycle through targets
// YUV target
glBindTexture(GL_TEXTURE_EXTERNAL_OES, yuvTarget);
// Expect render target to have the same color as expectedRgbColor
verifyResultsExternal(yuvTarget, expectedRgbColor);
// RGBA target
glBindTexture(GL_TEXTURE_EXTERNAL_OES, rgbaTarget);
// Expect render target to have the same color as rgbColor
verifyResultsExternal(rgbaTarget, rgbaColor);
// YUV target
glBindTexture(GL_TEXTURE_EXTERNAL_OES, yuvTarget);
// Expect render target to have the same color as expectedRgbColor
verifyResultsExternal(yuvTarget, expectedRgbColor);
// Clean up
eglDestroyImageKHR(window->getDisplay(), yuvImage);
destroyAndroidHardwareBuffer(yuvSource);
eglDestroyImageKHR(window->getDisplay(), rgbaImage);
destroyAndroidHardwareBuffer(rgbaSource);
}
// Testing source AHB EGL image, target 2D texture retaining initial data.
TEST_P(ImageTest, SourceAHBTarget2DRetainInitialData)
{
......
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