Path: blob/main_old/src/tests/gl_tests/DrawBaseVertexVariantsTest.cpp
1693 views
//1// Copyright 2020 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//56// DrawBaseVertexVariantsTest: Tests variants of drawElements*BaseVertex* call from different7// extensions89#include "gpu_info_util/SystemInfo.h"10#include "test_utils/ANGLETest.h"11#include "test_utils/gl_raii.h"1213#include <numeric>1415using namespace angle;1617namespace18{1920// Create a kWidth * kHeight canvas equally split into kCountX * kCountY tiles21// each containing a quad partially covering each tile22constexpr uint32_t kWidth = 256;23constexpr uint32_t kHeight = 256;24constexpr uint32_t kCountX = 8;25constexpr uint32_t kCountY = 8;26constexpr int kBoxCount = kCountX * kCountY;27constexpr uint32_t kIndexPatternRepeatCount = 3;28constexpr std::array<GLfloat, 2> kTileSize = {291.f / static_cast<GLfloat>(kCountX),301.f / static_cast<GLfloat>(kCountY),31};32constexpr std::array<uint32_t, 2> kTilePixelSize = {kWidth / kCountX, kHeight / kCountY};33constexpr std::array<GLfloat, 2> kQuadRadius = {0.25f * kTileSize[0], 0.25f * kTileSize[1]};34constexpr std::array<uint32_t, 2> kPixelCheckSize = {35static_cast<uint32_t>(kQuadRadius[0] * kWidth),36static_cast<uint32_t>(kQuadRadius[1] * kHeight)};37constexpr GLenum kBufferDataUsage[] = {GL_STATIC_DRAW, GL_DYNAMIC_DRAW, GL_STREAM_DRAW};3839constexpr std::array<GLfloat, 2> GetTileCenter(uint32_t x, uint32_t y)40{41return {42kTileSize[0] * (0.5f + static_cast<GLfloat>(x)),43kTileSize[1] * (0.5f + static_cast<GLfloat>(y)),44};45}46constexpr std::array<std::array<GLfloat, 2>, 4> GetQuadVertices(uint32_t x, uint32_t y)47{48const auto center = GetTileCenter(x, y);49return {50std::array<GLfloat, 2>{center[0] - kQuadRadius[0], center[1] - kQuadRadius[1]},51std::array<GLfloat, 2>{center[0] + kQuadRadius[0], center[1] - kQuadRadius[1]},52std::array<GLfloat, 2>{center[0] + kQuadRadius[0], center[1] + kQuadRadius[1]},53std::array<GLfloat, 2>{center[0] - kQuadRadius[0], center[1] + kQuadRadius[1]},54};55}5657enum class DrawCallVariants58{59DrawElementsBaseVertex,60DrawElementsInstancedBaseVertex,61DrawRangeElementsBaseVertex,62DrawElementsInstancedBaseVertexBaseInstance63};6465using DrawBaseVertexVariantsTestParams = std::tuple<angle::PlatformParameters, GLenum>;6667std::string DrawBaseVertexVariantsTestPrint(68const ::testing::TestParamInfo<DrawBaseVertexVariantsTestParams> ¶msInfo)69{70const DrawBaseVertexVariantsTestParams ¶ms = paramsInfo.param;71std::ostringstream out;7273out << std::get<0>(params) << "__";7475switch (std::get<1>(params))76{77case GL_STATIC_DRAW:78out << "STATIC_DRAW";79break;80case GL_DYNAMIC_DRAW:81out << "DYNAMIC_DRAW";82break;83case GL_STREAM_DRAW:84out << "STREAM_DRAW";85break;86default:87out << "UPDATE_THIS_SWITCH";88break;89}9091return out.str();92}9394// These tests check correctness of variants of baseVertex draw calls from different extensions9596class DrawBaseVertexVariantsTest : public ANGLETestWithParam<DrawBaseVertexVariantsTestParams>97{98protected:99DrawBaseVertexVariantsTest()100{101setWindowWidth(kWidth);102setWindowHeight(kHeight);103setConfigRedBits(8);104setConfigGreenBits(8);105setConfigBlueBits(8);106setConfigAlphaBits(8);107108std::array<GLushort, 6> indices = {0, 1, 2, 0, 2, 3};109mIndices.resize(indices.size() * kIndexPatternRepeatCount);110for (uint32_t i = 0; i < kIndexPatternRepeatCount; i++)111{112size_t o = i * indices.size();113size_t vo = i * 4; // each quad has 4 vertices, index offset by 4114for (size_t j = 0; j < indices.size(); j++)115{116mIndices[o + j] = vo + indices[j];117}118}119120mColorPalette = {GLColor(0x7f, 0x7f, 0x7f, 0xff),121GLColor::red,122GLColor::green,123GLColor::yellow,124GLColor::blue,125GLColor::magenta,126GLColor::cyan,127GLColor::white};128129for (uint32_t y = 0; y < kCountY; ++y)130{131for (uint32_t x = 0; x < kCountX; ++x)132{133// v3 ---- v2134// | |135// | |136// v0 ---- v1137138const auto vs = ::GetQuadVertices(x, y);139140for (const auto &v : vs)141{142mVertices.insert(mVertices.end(), v.begin(), v.end());143}144145const auto &colorPicked = mColorPalette[(x + y) % mColorPalette.size()];146for (int i = 0; i < 4; ++i)147{148mVertexColors.push_back(colorPicked.R);149mVertexColors.push_back(colorPicked.G);150mVertexColors.push_back(colorPicked.B);151mVertexColors.push_back(colorPicked.A);152}153}154}155156mRegularIndices.resize(kCountY * kCountX * mIndices.size());157for (uint32_t y = 0; y < kCountY; y++)158{159for (uint32_t x = 0; x < kCountX; x++)160{161uint32_t i = x + y * kCountX;162uint32_t oi = 6 * i;163uint32_t ov = 4 * i;164for (uint32_t j = 0; j < 6; j++)165{166mRegularIndices[oi + j] = mIndices[j] + ov;167}168}169}170}171172void setupProgram(GLProgram &program)173{174constexpr char vs[] = R"(175precision mediump float;176attribute vec2 vPosition;177attribute vec4 vColor;178varying vec4 color;179void main()180{181gl_Position = vec4(vec3(vPosition, 1.0) * 2.0 - 1.0, 1.0);182color = vColor;183})";184constexpr char fs[] = R"(185precision mediump float;186varying vec4 color;187void main()188{189gl_FragColor = color;190})";191program.makeRaster(vs, fs);192EXPECT_GL_NO_ERROR();193ASSERT_TRUE(program.valid());194glUseProgram(program.get());195mPositionLoc = glGetAttribLocation(program.get(), "vPosition");196ASSERT_NE(-1, mPositionLoc);197mColorLoc = glGetAttribLocation(program.get(), "vColor");198ASSERT_NE(-1, mColorLoc);199}200201void setupIndexedBuffers(GLBuffer &vertexPositionBuffer,202GLBuffer &vertexColorBuffer,203GLBuffer &indexBuffer)204{205GLenum usage = std::get<1>(GetParam());206207glBindBuffer(GL_ARRAY_BUFFER, vertexColorBuffer);208glBufferData(GL_ARRAY_BUFFER, sizeof(GLubyte) * mVertexColors.size(), mVertexColors.data(),209usage);210211glEnableVertexAttribArray(mColorLoc);212glVertexAttribPointer(mColorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);213214glBindBuffer(GL_ARRAY_BUFFER, vertexPositionBuffer);215glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mVertices.size(), mVertices.data(), usage);216217glEnableVertexAttribArray(mPositionLoc);218glVertexAttribPointer(mPositionLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);219220glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);221glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * mIndices.size(), mIndices.data(),222usage);223224ASSERT_GL_NO_ERROR();225}226227void doDrawElementsBaseVertexVariants(DrawCallVariants drawCallType)228{229glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);230231int baseRepetition = 0;232int i = 0;233234// Start at various repetitions within the patterned index buffer to exercise base235// index.236237static_assert(kIndexPatternRepeatCount >= 3, "Repeat pattern count should be at least 3");238239while (i < kBoxCount)240{241int repetitionCount = std::min(3 - baseRepetition, kBoxCount - i);242243updateVertexColorData(i, repetitionCount);244245switch (drawCallType)246{247case DrawCallVariants::DrawElementsInstancedBaseVertexBaseInstance:248glDrawElementsInstancedBaseVertexBaseInstanceANGLE(249GL_TRIANGLES, repetitionCount * 6, GL_UNSIGNED_SHORT,250reinterpret_cast<GLvoid *>(251static_cast<uintptr_t>(baseRepetition * 6 * sizeof(GLushort))),2521, (i - baseRepetition) * 4, 0);253break;254case DrawCallVariants::DrawElementsBaseVertex:255glDrawElementsBaseVertexEXT(256GL_TRIANGLES, repetitionCount * 6, GL_UNSIGNED_SHORT,257reinterpret_cast<GLvoid *>(258static_cast<uintptr_t>(baseRepetition * 6 * sizeof(GLushort))),259(i - baseRepetition) * 4);260break;261case DrawCallVariants::DrawElementsInstancedBaseVertex:262glDrawElementsInstancedBaseVertexEXT(263GL_TRIANGLES, repetitionCount * 6, GL_UNSIGNED_SHORT,264reinterpret_cast<GLvoid *>(265static_cast<uintptr_t>(baseRepetition * 6 * sizeof(GLushort))),2661, (i - baseRepetition) * 4);267break;268case DrawCallVariants::DrawRangeElementsBaseVertex:269glDrawRangeElementsBaseVertexEXT(270GL_TRIANGLES, baseRepetition * 4,271(baseRepetition + repetitionCount) * 4 - 1, repetitionCount * 6,272GL_UNSIGNED_SHORT,273reinterpret_cast<GLvoid *>(274static_cast<uintptr_t>(baseRepetition * 6 * sizeof(GLushort))),275(i - baseRepetition) * 4);276break;277default:278EXPECT_TRUE(false);279break;280}281282baseRepetition = (baseRepetition + 1) % 3;283i += repetitionCount;284}285286EXPECT_GL_NO_ERROR();287checkDrawResult();288}289290void updateVertexColorData(GLint drawnQuadCount, GLint toDrawQuadCount)291{292// update the vertex color of the next [count] of quads to draw293if (std::get<1>(GetParam()) == GL_STATIC_DRAW)294{295return;296}297298GLint offset = sizeof(GLubyte) * drawnQuadCount * 4 * sizeof(GLColor);299300for (GLint i = 0; i < toDrawQuadCount; i++)301{302const GLColor &color = mColorPalette[(drawnQuadCount + i) % mColorPalette.size()];303for (GLint j = 0; j < 4; j++)304{305glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(GLColor), color.data());306offset += sizeof(GLColor);307}308}309}310311void checkDrawResult()312{313bool dynamicLayout = std::get<1>(GetParam()) == GL_STATIC_DRAW ? false : true;314315for (uint32_t y = 0; y < kCountY; ++y)316{317for (uint32_t x = 0; x < kCountX; ++x)318{319uint32_t center_x = x * kTilePixelSize[0] + kTilePixelSize[0] / 2;320uint32_t center_y = y * kTilePixelSize[1] + kTilePixelSize[1] / 2;321322const auto &color =323mColorPalette[(dynamicLayout ? x : x + y) % mColorPalette.size()];324325EXPECT_PIXEL_NEAR(center_x - kPixelCheckSize[0] / 2,326center_y - kPixelCheckSize[1] / 2, color[0], color[1], color[2],327color[3], 1);328}329}330}331332bool requestAngleBaseVertexBaseInstanceExtensions()333{334if (getClientMajorVersion() <= 2)335{336if (!EnsureGLExtensionEnabled("GL_ANGLE_instanced_arrays"))337{338return false;339}340}341return EnsureGLExtensionEnabled("GL_ANGLE_base_vertex_base_instance");342}343344bool requestNativeBaseVertexExtensions()345{346return (EnsureGLExtensionEnabled("GL_OES_draw_elements_base_vertex") ||347EnsureGLExtensionEnabled("GL_EXT_draw_elements_base_vertex"));348}349350std::vector<GLushort> mIndices;351std::vector<GLfloat> mVertices;352std::vector<GLubyte> mVertexColors;353354std::vector<GLColor> mColorPalette;355std::vector<GLushort> mRegularIndices;356GLint mPositionLoc;357GLint mColorLoc;358};359360// Test drawElementsBaseVertex from OES/EXT_draw_elements_base_vertex361TEST_P(DrawBaseVertexVariantsTest, DrawElementsBaseVertex)362{363ANGLE_SKIP_TEST_IF(!requestNativeBaseVertexExtensions());364365GLProgram program;366setupProgram(program);367368GLBuffer indexBuffer;369GLBuffer vertexPositionBuffer;370GLBuffer vertexColorBuffer;371setupIndexedBuffers(vertexPositionBuffer, vertexColorBuffer, indexBuffer);372373// for potential update vertex color later374glBindBuffer(GL_ARRAY_BUFFER, vertexColorBuffer);375376doDrawElementsBaseVertexVariants(DrawCallVariants::DrawElementsBaseVertex);377}378379// Test drawElementsInstancedBaseVertex from OES/EXT_draw_elements_base_vertex380TEST_P(DrawBaseVertexVariantsTest, DrawElementsInstancedBaseVertex)381{382ANGLE_SKIP_TEST_IF(!requestNativeBaseVertexExtensions());383384GLProgram program;385setupProgram(program);386387GLBuffer indexBuffer;388GLBuffer vertexPositionBuffer;389GLBuffer vertexColorBuffer;390setupIndexedBuffers(vertexPositionBuffer, vertexColorBuffer, indexBuffer);391392// for potential update vertex color later393glBindBuffer(GL_ARRAY_BUFFER, vertexColorBuffer);394395doDrawElementsBaseVertexVariants(DrawCallVariants::DrawElementsInstancedBaseVertex);396}397398// Test drawRangeElementsBaseVertex from OES/EXT_draw_elements_base_vertex399TEST_P(DrawBaseVertexVariantsTest, DrawRangeElementsBaseVertex)400{401ANGLE_SKIP_TEST_IF(!requestNativeBaseVertexExtensions());402403GLProgram program;404setupProgram(program);405406GLBuffer indexBuffer;407GLBuffer vertexPositionBuffer;408GLBuffer vertexColorBuffer;409setupIndexedBuffers(vertexPositionBuffer, vertexColorBuffer, indexBuffer);410411// for potential update vertex color later412glBindBuffer(GL_ARRAY_BUFFER, vertexColorBuffer);413414doDrawElementsBaseVertexVariants(DrawCallVariants::DrawRangeElementsBaseVertex);415}416417// Test drawElementsInstancedBaseVertexBaseInstance from ANGLE_base_vertex_base_instance418TEST_P(DrawBaseVertexVariantsTest, DrawElementsInstancedBaseVertexBaseInstance)419{420ANGLE_SKIP_TEST_IF(!requestAngleBaseVertexBaseInstanceExtensions());421422GLProgram program;423setupProgram(program);424425GLBuffer indexBuffer;426GLBuffer vertexPositionBuffer;427GLBuffer vertexColorBuffer;428setupIndexedBuffers(vertexPositionBuffer, vertexColorBuffer, indexBuffer);429430// for potential update vertex color later431glBindBuffer(GL_ARRAY_BUFFER, vertexColorBuffer);432433doDrawElementsBaseVertexVariants(DrawCallVariants::DrawElementsInstancedBaseVertexBaseInstance);434}435436GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DrawBaseVertexVariantsTest);437ANGLE_INSTANTIATE_TEST_COMBINE_1(DrawBaseVertexVariantsTest,438DrawBaseVertexVariantsTestPrint,439testing::ValuesIn(kBufferDataUsage),440ES3_D3D11(),441ES3_OPENGL(),442ES3_OPENGLES(),443ES3_VULKAN());444445} // namespace446447448