Hash :
0561884e
Author :
Date :
2023-04-26T17:26:42
Vulkan: Dirty VertexArray binding bit if buffer storage change In crrev.com/c/3669603, we did optimization for black_desert_mobile that when vertex array is unbound, we remove vertex array from buffer's observer list to reduce overhead of observer notifications when buffer is been modified. To compensate for the lost notification, when vertex array is bound, we always assume every buffer that is bound to vertex array has been dirtied, for the simplicity at that time. This CL further the optimization of that CL. In this CL, I moved the dirty bit set into backend and improves vulkan backend by checking buffer's serial number and only dirty the binding if the serial has changed. Given this, now we can also remove all the non-current vertex array from buffer's observer list (previously it is heuristic based with a hard coded observer count limit). This and the previous CL improves asphalt_9 by ~1%. Bug: b/277644512 Change-Id: Ibc3f8e3df9fe70c6879e0b2bca86d8487a9dba73 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4481241 Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Yuxin Hu <yuxinhu@google.com> Commit-Queue: Charlie Lao <cclao@google.com>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
//
// Copyright 2017 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Unit tests for VertexArray and related classes.
//
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "common/bitset_utils.h"
#include "common/utilities.h"
#include "libANGLE/VertexArray.h"
using namespace gl;
// Tests that function GetIndexFromDirtyBit computes the index properly.
TEST(VertexArrayTest, VerifyGetIndexFromDirtyBit)
{
VertexArray::DirtyBits dirtyBits;
constexpr size_t bits[] = {2, 4, 9, 16, 25, 35};
constexpr GLint count = sizeof(bits) / sizeof(size_t);
for (GLint i = 0; i < count; i++)
{
dirtyBits.set(bits[i]);
}
for (size_t dirtyBit : dirtyBits)
{
const size_t index = VertexArray::GetVertexIndexFromDirtyBit(dirtyBit);
if (dirtyBit < VertexArray::DIRTY_BIT_ATTRIB_0)
{
continue;
}
else if (dirtyBit < VertexArray::DIRTY_BIT_ATTRIB_MAX)
{
EXPECT_EQ(dirtyBit - VertexArray::DIRTY_BIT_ATTRIB_0, index);
}
else if (dirtyBit < VertexArray::DIRTY_BIT_BINDING_MAX)
{
EXPECT_EQ(dirtyBit - VertexArray::DIRTY_BIT_BINDING_0, index);
}
else if (dirtyBit < VertexArray::DIRTY_BIT_BUFFER_DATA_MAX)
{
EXPECT_EQ(dirtyBit - VertexArray::DIRTY_BIT_BUFFER_DATA_0, index);
}
else
ASSERT_TRUE(false);
}
}