зеркало из https://github.com/AvaloniaUI/angle.git
Vulkan: Add a perf test for pre-rotation code injection
A test is added that dispatches a large number of vertex shaders, generating primitives that are all culled. The vertex shaders are simple so that code injected for pre-rotation would make up the majority of the shader code. Bug: angleproject:5478 Change-Id: I75092cb25e6427449251985f56e54f89813dec32 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2615821 Reviewed-by: Charlie Lao <cclao@google.com> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
This commit is contained in:
Родитель
2aa4f7e521
Коммит
7cdda2dc5f
|
@ -20,6 +20,7 @@ angle_perf_tests_sources = [
|
|||
"perf_tests/MultisampledRenderToTexturePerf.cpp",
|
||||
"perf_tests/MultiviewPerf.cpp",
|
||||
"perf_tests/PointSprites.cpp",
|
||||
"perf_tests/PreRotationPerf.cpp",
|
||||
"perf_tests/TextureSampling.cpp",
|
||||
"perf_tests/TextureUploadPerf.cpp",
|
||||
"perf_tests/TexturesPerf.cpp",
|
||||
|
|
|
@ -0,0 +1,211 @@
|
|||
//
|
||||
// Copyright 2020 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.
|
||||
//
|
||||
// PreRotationBenchmark:
|
||||
// Performance test for pre-rotation code generation.
|
||||
//
|
||||
|
||||
#include "ANGLEPerfTest.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
#include <sstream>
|
||||
|
||||
#include "test_utils/gl_raii.h"
|
||||
#include "util/shader_utils.h"
|
||||
|
||||
using namespace angle;
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr unsigned int kIterationsPerStep = 20;
|
||||
|
||||
enum class PreRotation
|
||||
{
|
||||
_0,
|
||||
_90,
|
||||
_180,
|
||||
_270,
|
||||
};
|
||||
|
||||
struct PreRotationParams final : public RenderTestParams
|
||||
{
|
||||
PreRotationParams()
|
||||
{
|
||||
iterationsPerStep = kIterationsPerStep;
|
||||
trackGpuTime = true;
|
||||
|
||||
preRotation = PreRotation::_0;
|
||||
}
|
||||
|
||||
std::string story() const override;
|
||||
|
||||
PreRotation preRotation;
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const PreRotationParams ¶ms)
|
||||
{
|
||||
return os << params.backendAndStory().substr(1);
|
||||
}
|
||||
|
||||
std::string PreRotationParams::story() const
|
||||
{
|
||||
std::stringstream strstr;
|
||||
|
||||
strstr << RenderTestParams::story();
|
||||
|
||||
switch (preRotation)
|
||||
{
|
||||
case PreRotation::_0:
|
||||
strstr << "_NoPreRotation";
|
||||
break;
|
||||
case PreRotation::_90:
|
||||
strstr << "_PreRotate90";
|
||||
break;
|
||||
case PreRotation::_180:
|
||||
strstr << "_PreRotate180";
|
||||
break;
|
||||
case PreRotation::_270:
|
||||
strstr << "_PreRotate270";
|
||||
break;
|
||||
}
|
||||
|
||||
return strstr.str();
|
||||
}
|
||||
|
||||
class PreRotationBenchmark : public ANGLERenderTest,
|
||||
public ::testing::WithParamInterface<PreRotationParams>
|
||||
{
|
||||
public:
|
||||
PreRotationBenchmark();
|
||||
|
||||
void initializeBenchmark() override;
|
||||
void destroyBenchmark() override;
|
||||
|
||||
void drawBenchmark() override;
|
||||
|
||||
protected:
|
||||
GLuint mProgram = 0;
|
||||
};
|
||||
|
||||
PreRotationBenchmark::PreRotationBenchmark() : ANGLERenderTest("PreRotation", GetParam()) {}
|
||||
|
||||
void PreRotationBenchmark::initializeBenchmark()
|
||||
{
|
||||
constexpr char kVS[] = R"(
|
||||
attribute mediump vec4 positionIn;
|
||||
void main()
|
||||
{
|
||||
gl_Position = positionIn;
|
||||
})";
|
||||
|
||||
constexpr char kFS[] = R"(precision mediump float;
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(0);
|
||||
})";
|
||||
|
||||
mProgram = CompileProgram(kVS, kFS);
|
||||
ASSERT_NE(0u, mProgram);
|
||||
|
||||
glUseProgram(mProgram);
|
||||
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
|
||||
|
||||
// Perform a draw so everything is flushed.
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
|
||||
ASSERT_GL_NO_ERROR();
|
||||
}
|
||||
|
||||
void PreRotationBenchmark::destroyBenchmark()
|
||||
{
|
||||
glDeleteProgram(mProgram);
|
||||
}
|
||||
|
||||
void PreRotationBenchmark::drawBenchmark()
|
||||
{
|
||||
const auto ¶ms = GetParam();
|
||||
|
||||
constexpr uint32_t kDrawCallSize = 100'000;
|
||||
|
||||
GLint attribLocation = glGetAttribLocation(mProgram, "positionIn");
|
||||
ASSERT_NE(-1, attribLocation);
|
||||
|
||||
startGpuTimer();
|
||||
for (unsigned int iteration = 0; iteration < params.iterationsPerStep; ++iteration)
|
||||
{
|
||||
// Set the position attribute such that every generated primitive is out of bounds and is
|
||||
// clipped. This means the test is spending its time almost entirely with vertex shaders.
|
||||
// The vertex shader itself is simple so that any code that is added for pre-rotation will
|
||||
// contribute a comparably sizable chunk of code.
|
||||
switch (iteration % 5)
|
||||
{
|
||||
case 0:
|
||||
glVertexAttrib4f(attribLocation, -2.0f, 0.0f, 0.0f, 1.0f);
|
||||
break;
|
||||
case 1:
|
||||
glVertexAttrib4f(attribLocation, 2.0f, 0.0f, 0.0f, 1.0f);
|
||||
break;
|
||||
case 2:
|
||||
glVertexAttrib4f(attribLocation, 0.0f, -2.0f, 0.0f, 1.0f);
|
||||
break;
|
||||
case 3:
|
||||
glVertexAttrib4f(attribLocation, 0.0f, 2.0f, 0.0f, 1.0f);
|
||||
break;
|
||||
case 4:
|
||||
glVertexAttrib4f(attribLocation, 0.0f, 0.0f, -2.0f, 1.0f);
|
||||
break;
|
||||
}
|
||||
|
||||
// Draw many points, all which are culled.
|
||||
glDrawArrays(GL_POINTS, 0, kDrawCallSize);
|
||||
}
|
||||
stopGpuTimer();
|
||||
|
||||
ASSERT_GL_NO_ERROR();
|
||||
}
|
||||
|
||||
PreRotationParams VulkanParams(PreRotation preRotation)
|
||||
{
|
||||
PreRotationParams params;
|
||||
params.eglParameters = egl_platform::VULKAN();
|
||||
params.preRotation = preRotation;
|
||||
|
||||
switch (preRotation)
|
||||
{
|
||||
case PreRotation::_0:
|
||||
break;
|
||||
case PreRotation::_90:
|
||||
params.eglParameters.emulatedPrerotation = 90;
|
||||
break;
|
||||
case PreRotation::_180:
|
||||
params.eglParameters.emulatedPrerotation = 180;
|
||||
break;
|
||||
case PreRotation::_270:
|
||||
params.eglParameters.emulatedPrerotation = 270;
|
||||
break;
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
TEST_P(PreRotationBenchmark, Run)
|
||||
{
|
||||
run();
|
||||
}
|
||||
|
||||
using namespace params;
|
||||
|
||||
ANGLE_INSTANTIATE_TEST(PreRotationBenchmark,
|
||||
VulkanParams(PreRotation::_0),
|
||||
VulkanParams(PreRotation::_90),
|
||||
VulkanParams(PreRotation::_180),
|
||||
VulkanParams(PreRotation::_270));
|
Загрузка…
Ссылка в новой задаче