Add new Vulkan uniform update test.

This covers a specific case with multiple programs and descriptor
set caching. It could get tripped up by more complicated patterns
in the trace tests.

Bug: angleproject:6776
Change-Id: Ic8e42e55e60ef0fc01f0386712d3457abeea94e9
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3426884
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
Reviewed-by: Yuxin Hu <yuxinhu@google.com>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
This commit is contained in:
Jamie Madill
2022-01-30 14:00:48 -05:00
committed by Angle LUCI CQ
parent 464396c7b9
commit 4a65040b67
4 changed files with 86 additions and 0 deletions

View File

@@ -21,6 +21,7 @@
#include "libANGLE/renderer/vulkan/TextureVk.h"
#include "test_utils/gl_raii.h"
#include "util/EGLWindow.h"
#include "util/random_utils.h"
#include "util/shader_utils.h"
using namespace angle;
@@ -77,6 +78,13 @@ class VulkanUniformUpdatesTest : public ANGLETest
kMaxSetsMultiplierForTesting);
}
void setExplicitMaxSetsLimit(uint32_t limit)
{
rx::vk::DynamicDescriptorPool::SetMaxSetsPerPoolForTesting(limit);
rx::vk::DynamicDescriptorPool::SetMaxSetsPerPoolMultiplierForTesting(
kMaxSetsMultiplierForTesting);
}
private:
EGLContext mLastContext;
uint32_t mMaxSetsPerPool;
@@ -543,6 +551,67 @@ void main()
}
}
// Covers a usage pattern where two programs share a descriptor pool.
TEST_P(VulkanUniformUpdatesTest, MultipleProgramsShareDescriptors)
{
setExplicitMaxSetsLimit(2);
// Set a min size so uniform updates allocate a new buffer every 2nd time.
rx::ContextVk *contextVk = hackANGLE();
contextVk->setDefaultUniformBlocksMinSizeForTesting(512);
static constexpr size_t kNumPrograms = 2;
static constexpr size_t kDrawIterations = 4;
static constexpr GLint kPosLoc = 0;
std::array<GLuint, kNumPrograms> programs = {};
for (GLuint &program : programs)
{
auto preLinkCallback = [](GLuint program) {
glBindAttribLocation(program, kPosLoc, essl1_shaders::PositionAttrib());
};
program = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor(),
preLinkCallback);
ASSERT_NE(program, 0u);
}
const std::array<Vector3, 6> &quadVerts = GetQuadVertices();
GLBuffer vbo;
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, quadVerts.size() * sizeof(quadVerts[0]), quadVerts.data(),
GL_STATIC_DRAW);
glVertexAttribPointer(kPosLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glEnableVertexAttribArray(kPosLoc);
ASSERT_GL_NO_ERROR();
RNG rng;
for (size_t drawIteration = 0; drawIteration < kDrawIterations; ++drawIteration)
{
for (GLuint program : programs)
{
Vector3 randVec = RandomVec3(rng.randomInt(), 0.0f, 1.0f);
glUseProgram(program);
glUniform4f(0, randVec.x(), randVec.y(), randVec.z(), 1.0f);
glDrawArrays(GL_TRIANGLES, 0, 6);
EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(randVec), 5);
}
}
ASSERT_GL_NO_ERROR();
for (GLuint &program : programs)
{
glDeleteProgram(program);
}
}
ANGLE_INSTANTIATE_TEST(VulkanUniformUpdatesTest, ES2_VULKAN(), ES3_VULKAN());
// This test tries to test uniform data update while switching between PPO and monolithic program.

View File

@@ -224,6 +224,13 @@ GLColorRGB::GLColorRGB(const Vector3 &floatColor)
: R(ColorDenorm(floatColor.x())), G(ColorDenorm(floatColor.y())), B(ColorDenorm(floatColor.z()))
{}
GLColor::GLColor(const Vector3 &floatColor)
: R(ColorDenorm(floatColor.x())),
G(ColorDenorm(floatColor.y())),
B(ColorDenorm(floatColor.z())),
A(255)
{}
GLColor::GLColor(const Vector4 &floatColor)
: R(ColorDenorm(floatColor.x())),
G(ColorDenorm(floatColor.y())),

View File

@@ -130,6 +130,7 @@ struct GLColor
{
constexpr GLColor() : R(0), G(0), B(0), A(0) {}
constexpr GLColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a) : R(r), G(g), B(b), A(a) {}
GLColor(const angle::Vector3 &floatColor);
GLColor(const angle::Vector4 &floatColor);
GLColor(GLuint colorValue);

View File

@@ -70,6 +70,15 @@ inline void FillVectorWithRandomUBytes(std::vector<uint8_t> *data)
FillVectorWithRandomUBytes(&rng, data);
}
inline Vector3 RandomVec3(int seed, float minValue, float maxValue)
{
RNG rng(seed);
srand(seed);
return Vector3(rng.randomFloatBetween(minValue, maxValue),
rng.randomFloatBetween(minValue, maxValue),
rng.randomFloatBetween(minValue, maxValue));
}
inline Vector4 RandomVec4(int seed, float minValue, float maxValue)
{
RNG rng(seed);