Commit a280c671 by Charlie Lao Committed by Angle LUCI CQ

Vulkan: Move framebuffer dirty bits handling after texture

When texture changes, it notify the observer. Framebuffer object is one of the observer and is able to respond to the changes in texture object. In this specific case, when texture called TextureVk::releaseImage and requires framebuffer object to syncState and call TextureVk::initRenderTargets. The problem right now is that framebuffer object's dirty bits are processed before texture, which means if the texture is being used by currently bound framebuffer object, it will not trigger the FBO's dirty bit handling. This CL moves container object dirty bit (DIRTY_OBJECT_DRAW_FRAMEBUFFER and DIRTY_OBJECT_READ_FRAMEBUFFER) after texture/image object's dirty bits. Bug: chromium:1212206 Bug: chromium:1197431 Change-Id: I95723da1ce5b8936d66692242f2e25e7a73bafe6 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2915764 Commit-Queue: Charlie Lao <cclao@google.com> Reviewed-by: 's avatarIan Elliott <ianelliott@google.com> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent ecf2956d
...@@ -704,12 +704,12 @@ class State : angle::NonCopyable ...@@ -704,12 +704,12 @@ class State : angle::NonCopyable
DIRTY_OBJECT_IMAGES_INIT, DIRTY_OBJECT_IMAGES_INIT,
DIRTY_OBJECT_READ_ATTACHMENTS, DIRTY_OBJECT_READ_ATTACHMENTS,
DIRTY_OBJECT_DRAW_ATTACHMENTS, DIRTY_OBJECT_DRAW_ATTACHMENTS,
DIRTY_OBJECT_READ_FRAMEBUFFER,
DIRTY_OBJECT_DRAW_FRAMEBUFFER,
DIRTY_OBJECT_VERTEX_ARRAY, DIRTY_OBJECT_VERTEX_ARRAY,
DIRTY_OBJECT_TEXTURES, // Top-level dirty bit. Also see mDirtyTextures. DIRTY_OBJECT_TEXTURES, // Top-level dirty bit. Also see mDirtyTextures.
DIRTY_OBJECT_IMAGES, // Top-level dirty bit. Also see mDirtyImages. DIRTY_OBJECT_IMAGES, // Top-level dirty bit. Also see mDirtyImages.
DIRTY_OBJECT_SAMPLERS, // Top-level dirty bit. Also see mDirtySamplers. DIRTY_OBJECT_SAMPLERS, // Top-level dirty bit. Also see mDirtySamplers.
DIRTY_OBJECT_READ_FRAMEBUFFER,
DIRTY_OBJECT_DRAW_FRAMEBUFFER,
DIRTY_OBJECT_PROGRAM, DIRTY_OBJECT_PROGRAM,
DIRTY_OBJECT_UNKNOWN, DIRTY_OBJECT_UNKNOWN,
DIRTY_OBJECT_MAX = DIRTY_OBJECT_UNKNOWN, DIRTY_OBJECT_MAX = DIRTY_OBJECT_UNKNOWN,
...@@ -943,9 +943,9 @@ class State : angle::NonCopyable ...@@ -943,9 +943,9 @@ class State : angle::NonCopyable
using DirtyObjectHandler = angle::Result (State::*)(const Context *context, Command command); using DirtyObjectHandler = angle::Result (State::*)(const Context *context, Command command);
static constexpr DirtyObjectHandler kDirtyObjectHandlers[DIRTY_OBJECT_MAX] = { static constexpr DirtyObjectHandler kDirtyObjectHandlers[DIRTY_OBJECT_MAX] = {
&State::syncActiveTextures, &State::syncTexturesInit, &State::syncImagesInit, &State::syncActiveTextures, &State::syncTexturesInit, &State::syncImagesInit,
&State::syncReadAttachments, &State::syncDrawAttachments, &State::syncReadFramebuffer, &State::syncReadAttachments, &State::syncDrawAttachments, &State::syncVertexArray,
&State::syncDrawFramebuffer, &State::syncVertexArray, &State::syncTextures, &State::syncTextures, &State::syncImages, &State::syncSamplers,
&State::syncImages, &State::syncSamplers, &State::syncProgram}; &State::syncReadFramebuffer, &State::syncDrawFramebuffer, &State::syncProgram};
// Robust init must happen before Framebuffer init for the Vulkan back-end. // Robust init must happen before Framebuffer init for the Vulkan back-end.
static_assert(DIRTY_OBJECT_ACTIVE_TEXTURES < DIRTY_OBJECT_TEXTURES_INIT, "init order"); static_assert(DIRTY_OBJECT_ACTIVE_TEXTURES < DIRTY_OBJECT_TEXTURES_INIT, "init order");
...@@ -959,14 +959,21 @@ class State : angle::NonCopyable ...@@ -959,14 +959,21 @@ class State : angle::NonCopyable
static_assert(DIRTY_OBJECT_IMAGES_INIT == 2, "check DIRTY_OBJECT_IMAGES_INIT index"); static_assert(DIRTY_OBJECT_IMAGES_INIT == 2, "check DIRTY_OBJECT_IMAGES_INIT index");
static_assert(DIRTY_OBJECT_READ_ATTACHMENTS == 3, "check DIRTY_OBJECT_READ_ATTACHMENTS index"); static_assert(DIRTY_OBJECT_READ_ATTACHMENTS == 3, "check DIRTY_OBJECT_READ_ATTACHMENTS index");
static_assert(DIRTY_OBJECT_DRAW_ATTACHMENTS == 4, "check DIRTY_OBJECT_DRAW_ATTACHMENTS index"); static_assert(DIRTY_OBJECT_DRAW_ATTACHMENTS == 4, "check DIRTY_OBJECT_DRAW_ATTACHMENTS index");
static_assert(DIRTY_OBJECT_READ_FRAMEBUFFER == 5, "check DIRTY_OBJECT_READ_FRAMEBUFFER index"); static_assert(DIRTY_OBJECT_VERTEX_ARRAY == 5, "check DIRTY_OBJECT_VERTEX_ARRAY index");
static_assert(DIRTY_OBJECT_DRAW_FRAMEBUFFER == 6, "check DIRTY_OBJECT_DRAW_FRAMEBUFFER index"); static_assert(DIRTY_OBJECT_TEXTURES == 6, "check DIRTY_OBJECT_TEXTURES index");
static_assert(DIRTY_OBJECT_VERTEX_ARRAY == 7, "check DIRTY_OBJECT_VERTEX_ARRAY index"); static_assert(DIRTY_OBJECT_IMAGES == 7, "check DIRTY_OBJECT_IMAGES index");
static_assert(DIRTY_OBJECT_TEXTURES == 8, "check DIRTY_OBJECT_TEXTURES index"); static_assert(DIRTY_OBJECT_SAMPLERS == 8, "check DIRTY_OBJECT_SAMPLERS index");
static_assert(DIRTY_OBJECT_IMAGES == 9, "check DIRTY_OBJECT_IMAGES index"); static_assert(DIRTY_OBJECT_READ_FRAMEBUFFER == 9, "check DIRTY_OBJECT_READ_FRAMEBUFFER index");
static_assert(DIRTY_OBJECT_SAMPLERS == 10, "check DIRTY_OBJECT_SAMPLERS index"); static_assert(DIRTY_OBJECT_DRAW_FRAMEBUFFER == 10, "check DIRTY_OBJECT_DRAW_FRAMEBUFFER index");
static_assert(DIRTY_OBJECT_PROGRAM == 11, "check DIRTY_OBJECT_PROGRAM index"); static_assert(DIRTY_OBJECT_PROGRAM == 11, "check DIRTY_OBJECT_PROGRAM index");
// Container (FBO) object must handled after the texture so that if texture code adds dirty bit
// to container object, they will be picked up in the same draw call.
static_assert(DIRTY_OBJECT_TEXTURES < DIRTY_OBJECT_READ_FRAMEBUFFER,
"State::syncDirtyObjects order");
static_assert(DIRTY_OBJECT_TEXTURES < DIRTY_OBJECT_DRAW_FRAMEBUFFER,
"State::syncDirtyObjects order");
// Dispatch table for buffer update functions. // Dispatch table for buffer update functions.
static const angle::PackedEnumMap<BufferBinding, BufferBindingSetter> kBufferSetters; static const angle::PackedEnumMap<BufferBinding, BufferBindingSetter> kBufferSetters;
......
...@@ -3335,9 +3335,6 @@ TEST_P(FramebufferTest, BindAndDrawDifferentSizedFBOs) ...@@ -3335,9 +3335,6 @@ TEST_P(FramebufferTest, BindAndDrawDifferentSizedFBOs)
// LINEAR_MIPMAP_LINEAR did not make any changes. // LINEAR_MIPMAP_LINEAR did not make any changes.
TEST_P(FramebufferTest_ES3, FramebufferBindToNewLevelAfterMaxIncreaseShouldntCrash) TEST_P(FramebufferTest_ES3, FramebufferBindToNewLevelAfterMaxIncreaseShouldntCrash)
{ {
// http://crbug.com/1197431
ANGLE_SKIP_TEST_IF(IsVulkan());
constexpr char kFS[] = R"(precision mediump float; constexpr char kFS[] = R"(precision mediump float;
uniform sampler2D u_tex0; uniform sampler2D u_tex0;
void main() { void main() {
......
...@@ -4247,7 +4247,7 @@ TEST_P(Texture2DBaseMaxTestES3, RedefineIncompatibleLevelBeyondMaxLevel) ...@@ -4247,7 +4247,7 @@ TEST_P(Texture2DBaseMaxTestES3, RedefineIncompatibleLevelBeyondMaxLevel)
TEST_P(Texture2DBaseMaxTestES3, Fuzz545ImmutableTexRenderFeedback) TEST_P(Texture2DBaseMaxTestES3, Fuzz545ImmutableTexRenderFeedback)
{ {
// http://crbug.com/1212206 // http://crbug.com/1212206
ANGLE_SKIP_TEST_IF(IsVulkan() || IsMetal()); ANGLE_SKIP_TEST_IF(IsMetal());
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D()); ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
......
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