Path: blob/main_old/src/tests/gl_tests/DrawBaseVertexBaseInstanceTest.cpp
1693 views
//1// Copyright 2019 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// DrawBaseVertexBaseInstanceTest: Tests of GL_ANGLE_base_vertex_base_instance78#include "gpu_info_util/SystemInfo.h"9#include "test_utils/ANGLETest.h"10#include "test_utils/gl_raii.h"1112#include <numeric>1314using namespace angle;1516namespace17{1819// Create a kWidth * kHeight canvas equally split into kCountX * kCountY tiles20// each containing a quad partially covering each tile21constexpr uint32_t kWidth = 256;22constexpr uint32_t kHeight = 256;23constexpr uint32_t kCountX = 8;24constexpr uint32_t kCountY = 8;25constexpr std::array<GLfloat, 2> kTileSize = {261.f / static_cast<GLfloat>(kCountX),271.f / static_cast<GLfloat>(kCountY),28};29constexpr std::array<uint32_t, 2> kTilePixelSize = {kWidth / kCountX, kHeight / kCountY};30constexpr std::array<GLfloat, 2> kQuadRadius = {0.25f * kTileSize[0], 0.25f * kTileSize[1]};31constexpr std::array<uint32_t, 2> kPixelCheckSize = {32static_cast<uint32_t>(kQuadRadius[0] * kWidth),33static_cast<uint32_t>(kQuadRadius[1] * kHeight)};3435constexpr std::array<GLfloat, 2> getTileCenter(uint32_t x, uint32_t y)36{37return {38kTileSize[0] * (0.5f + static_cast<GLfloat>(x)),39kTileSize[1] * (0.5f + static_cast<GLfloat>(y)),40};41}42constexpr std::array<std::array<GLfloat, 3>, 4> getQuadVertices(uint32_t x, uint32_t y)43{44const auto center = getTileCenter(x, y);45return {46std::array<GLfloat, 3>{center[0] - kQuadRadius[0], center[1] - kQuadRadius[1], 0.0f},47std::array<GLfloat, 3>{center[0] + kQuadRadius[0], center[1] - kQuadRadius[1], 0.0f},48std::array<GLfloat, 3>{center[0] + kQuadRadius[0], center[1] + kQuadRadius[1], 0.0f},49std::array<GLfloat, 3>{center[0] - kQuadRadius[0], center[1] + kQuadRadius[1], 0.0f},50};51}5253enum class BaseVertexOption54{55NoBaseVertex,56UseBaseVertex57};5859enum class BaseInstanceOption60{61NoBaseInstance,62UseBaseInstance63};6465enum class BufferDataUsageOption66{67StaticDraw,68DynamicDraw69};7071using DrawBaseVertexBaseInstanceTestParams = std::72tuple<angle::PlatformParameters, BaseVertexOption, BaseInstanceOption, BufferDataUsageOption>;7374struct PrintToStringParamName75{76std::string operator()(77const ::testing::TestParamInfo<DrawBaseVertexBaseInstanceTestParams> &info) const78{79::std::stringstream ss;80ss << std::get<0>(info.param) << "_"81<< (std::get<3>(info.param) == BufferDataUsageOption::StaticDraw ? "_StaticDraw"82: "_DynamicDraw")83<< (std::get<2>(info.param) == BaseInstanceOption::UseBaseInstance ? "_UseBaseInstance"84: "")85<< (std::get<1>(info.param) == BaseVertexOption::UseBaseVertex ? "_UseBaseVertex" : "");86return ss.str();87}88};8990// These tests check correctness of the ANGLE_base_vertex_base_instance extension.91// An array of quads is drawn across the screen.92// gl_VertexID, gl_InstanceID, gl_BaseVertex, and gl_BaseInstance93// are checked by using them to select the color of the draw.94class DrawBaseVertexBaseInstanceTest95: public ANGLETestBase,96public ::testing::TestWithParam<DrawBaseVertexBaseInstanceTestParams>97{98protected:99DrawBaseVertexBaseInstanceTest() : ANGLETestBase(std::get<0>(GetParam()))100{101setWindowWidth(kWidth);102setWindowHeight(kHeight);103setConfigRedBits(8);104setConfigGreenBits(8);105setConfigBlueBits(8);106setConfigAlphaBits(8);107108// Rects in the same column are within a vertex array, testing gl_VertexID, gl_BaseVertex109// Rects in the same row are drawn by instancing, testing gl_InstanceID, gl_BaseInstance110111mIndices = {0, 1, 2, 0, 2, 3};112113for (uint32_t y = 0; y < kCountY; ++y)114{115// v3 ---- v2116// | |117// | |118// v0 ---- v1119120const auto vs = getQuadVertices(0, y);121122for (const auto &v : vs)123{124mVertices.insert(mVertices.end(), v.begin(), v.end());125}126127for (GLushort i : mIndices)128{129mNonIndexedVertices.insert(mNonIndexedVertices.end(), vs[i].begin(), vs[i].end());130}131}132133mRegularIndices.resize(kCountY * mIndices.size());134for (uint32_t i = 0; i < kCountY; i++)135{136uint32_t oi = 6 * i;137uint32_t ov = 4 * i;138for (uint32_t j = 0; j < 6; j++)139{140mRegularIndices[oi + j] = mIndices[j] + ov;141}142}143144std::iota(mInstancedArrayId.begin(), mInstancedArrayId.end(), 0.0f);145std::reverse_copy(mInstancedArrayId.begin(), mInstancedArrayId.end(),146mInstancedArrayColorId.begin());147}148149void SetUp() override { ANGLETestBase::ANGLETestSetUp(); }150151bool useBaseVertexBuiltin() const152{153return std::get<1>(GetParam()) == BaseVertexOption::UseBaseVertex;154}155156bool useBaseInstanceBuiltin() const157{158return std::get<2>(GetParam()) == BaseInstanceOption::UseBaseInstance;159}160161GLenum getBufferDataUsage() const162{163return std::get<3>(GetParam()) == BufferDataUsageOption::StaticDraw ? GL_STATIC_DRAW164: GL_DYNAMIC_DRAW;165}166167std::string vertexShaderSource300(bool isDrawArrays, bool isMultiDraw, bool divisorTest)168{169// Each color channel is to test the value of170// R: gl_InstanceID and gl_BaseInstance171// G: gl_VertexID and gl_BaseVertex172// B: gl_BaseVertex173174std::stringstream shader;175shader << ("#version 300 es\n")176<< (isMultiDraw ? "#extension GL_ANGLE_multi_draw : require\n" : "")177<< ("#extension GL_ANGLE_base_vertex_base_instance : require\n")178<< "#define kCountX " << kCountX << "\n"179<< "#define kCountY " << kCountY << "\n"180<< R"(181in vec2 vPosition;182)" << (useBaseInstanceBuiltin() ? "" : "in float vInstanceID;\n")183<< (!divisorTest ? "" : "in float vInstanceColorID;\n") << R"(184out vec4 color;185void main()186{187const float xStep = 1.0 / float(kCountX);188const float yStep = 1.0 / float(kCountY);189float x_id = )"190<< (useBaseInstanceBuiltin() ? " float(gl_InstanceID + gl_BaseInstance);"191: "vInstanceID;")192<< "float x_color = "193<< (divisorTest ? "xStep * (vInstanceColorID + 1.0f);" : " 1.0 - xStep * x_id;")194<< R"(195float y_id = float(gl_VertexID / )"196<< (isDrawArrays ? "6" : "4") << R"();197198color = vec4(199x_color,2001.0 - yStep * y_id,201)" << (useBaseVertexBuiltin() ? "1.0 - yStep * float(gl_BaseVertex) / 4.0" : "1.0")202<< R"(,2031);204205mat3 transform = mat3(1.0);206transform[2][0] = x_id * xStep;207208gl_Position = vec4(transform * vec3(vPosition, 1.0) * 2.0 - 1.0, 1);209})";210211return shader.str();212}213214std::string fragmentShaderSource300()215{216return217R"(#version 300 es218precision mediump float;219in vec4 color;220out vec4 o_color;221void main()222{223o_color = color;224})";225}226227void setupProgram(GLProgram &program,228bool isDrawArrays = true,229bool isMultiDraw = false,230bool isDivisorTest = false)231{232program.makeRaster(vertexShaderSource300(isDrawArrays, isMultiDraw, isDivisorTest).c_str(),233fragmentShaderSource300().c_str());234EXPECT_GL_NO_ERROR();235ASSERT_TRUE(program.valid());236glUseProgram(program.get());237mPositionLoc = glGetAttribLocation(program.get(), "vPosition");238if (!useBaseInstanceBuiltin())239{240mInstanceIDLoc = glGetAttribLocation(program.get(), "vInstanceID");241mInstanceColorIDLoc = glGetAttribLocation(program.get(), "vInstanceColorID");242}243}244245void setupNonIndexedBuffers(GLBuffer &vertexBuffer)246{247glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer.get());248glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mNonIndexedVertices.size(),249mNonIndexedVertices.data(), getBufferDataUsage());250251ASSERT_GL_NO_ERROR();252}253254void setupIndexedBuffers(GLBuffer &vertexBuffer, GLBuffer &indexBuffer)255{256glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);257glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mVertices.size(), mVertices.data(),258getBufferDataUsage());259260glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);261glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * mIndices.size(), mIndices.data(),262getBufferDataUsage());263264ASSERT_GL_NO_ERROR();265}266267void setupInstanceIDBuffer(GLBuffer &instanceIDBuffer)268{269glBindBuffer(GL_ARRAY_BUFFER, instanceIDBuffer);270glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mInstancedArrayId.size(),271mInstancedArrayId.data(), getBufferDataUsage());272273ASSERT_GL_NO_ERROR();274}275276void setupInstanceColorIDBuffer(GLBuffer &instanceIDBuffer)277{278glBindBuffer(GL_ARRAY_BUFFER, instanceIDBuffer);279glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mInstancedArrayColorId.size(),280mInstancedArrayColorId.data(), getBufferDataUsage());281282ASSERT_GL_NO_ERROR();283}284285void setupRegularIndexedBuffer(GLBuffer &indexBuffer)286{287glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);288glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * mRegularIndices.size(),289mRegularIndices.data(), getBufferDataUsage());290291ASSERT_GL_NO_ERROR();292}293294void setupPositionVertexAttribPointer()295{296glEnableVertexAttribArray(mPositionLoc);297glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);298}299300void setupInstanceIDVertexAttribPointer(GLuint instanceIDLoc)301{302glEnableVertexAttribArray(instanceIDLoc);303glVertexAttribPointer(instanceIDLoc, 1, GL_FLOAT, GL_FALSE, 0, 0);304glVertexAttribDivisor(instanceIDLoc, 1);305}306307void doDrawArraysInstancedBaseInstance()308{309glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);310311const uint32_t countPerDraw = kCountY * 6;312313for (uint32_t i = 0; i < kCountX; i += 2)314{315glDrawArraysInstancedBaseInstanceANGLE(GL_TRIANGLES, 0, countPerDraw, 2, i);316}317}318319void doMultiDrawArraysInstancedBaseInstance()320{321glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);322323const uint32_t countPerDraw = kCountY * 6;324325const GLsizei drawCount = kCountX / 2;326const std::vector<GLsizei> counts(drawCount, countPerDraw);327const std::vector<GLsizei> firsts(drawCount, 0);328const std::vector<GLsizei> instanceCounts(drawCount, 2);329std::vector<GLuint> baseInstances(drawCount);330for (size_t i = 0; i < drawCount; i++)331{332baseInstances[i] = i * 2;333}334glMultiDrawArraysInstancedBaseInstanceANGLE(GL_TRIANGLES, firsts.data(), counts.data(),335instanceCounts.data(), baseInstances.data(),336drawCount);337}338339void doDrawElementsInstancedBaseVertexBaseInstance()340{341glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);342343const uint32_t countPerDraw = 6;344345for (uint32_t v = 0; v < kCountY; v++)346{347for (uint32_t i = 0; i < kCountX; i += 2)348{349glDrawElementsInstancedBaseVertexBaseInstanceANGLE(350GL_TRIANGLES, countPerDraw, GL_UNSIGNED_SHORT,351reinterpret_cast<GLvoid *>(static_cast<uintptr_t>(0)), 2, v * 4, i);352}353}354}355356// Call this after the *BaseVertexBaseInstance draw call to check if value of BaseVertex and357// BaseInstance are reset to zero358void doDrawArraysBaseInstanceReset()359{360glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);361glDrawArraysInstanced(GL_TRIANGLES, 0, 6 * kCountY, 1);362}363364void doDrawElementsBaseVertexBaseInstanceReset()365{366glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);367glDrawElementsInstanced(GL_TRIANGLES, 6 * kCountY, GL_UNSIGNED_SHORT,368reinterpret_cast<GLvoid *>(static_cast<uintptr_t>(0)), 1);369}370371void doMultiDrawElementsInstancedBaseVertexBaseInstance()372{373glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);374375const GLsizei drawCount = kCountX * kCountY / 2;376const std::vector<GLsizei> counts(drawCount, 6);377const std::vector<GLsizei> instanceCounts(drawCount, 2);378const std::vector<GLvoid *> indices(drawCount, 0);379std::vector<GLint> baseVertices(drawCount);380std::vector<GLuint> baseInstances(drawCount);381382GLsizei b = 0;383for (uint32_t v = 0; v < kCountY; v++)384{385for (uint32_t i = 0; i < kCountX; i += 2)386{387baseVertices[b] = v * 4;388baseInstances[b] = i;389b++;390}391}392393glMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE(394GL_TRIANGLES, counts.data(), GL_UNSIGNED_SHORT, indices.data(), instanceCounts.data(),395baseVertices.data(), baseInstances.data(), drawCount);396}397398void checkDrawResult(bool hasBaseVertex, bool oneColumn = false)399{400uint32_t numColums = oneColumn ? 1 : kCountX;401for (uint32_t y = 0; y < kCountY; ++y)402{403for (uint32_t x = 0; x < numColums; ++x)404{405uint32_t center_x = x * kTilePixelSize[0] + kTilePixelSize[0] / 2;406uint32_t center_y = y * kTilePixelSize[1] + kTilePixelSize[1] / 2;407408EXPECT_PIXEL_NEAR(center_x - kPixelCheckSize[0] / 2,409center_y - kPixelCheckSize[1] / 2,410256.0 * (1.0 - (float)x / (float)kCountX),411256.0 * (1.0 - (float)y / (float)kCountY),412useBaseVertexBuiltin() && hasBaseVertex && !oneColumn413? 256.0 * (1.0 - (float)y / (float)kCountY)414: 255,415255, 3);416}417}418}419420void TearDown() override { ANGLETestBase::ANGLETestTearDown(); }421422bool requestDrawBaseVertexBaseInstanceExtension()423{424if (IsGLExtensionRequestable("GL_ANGLE_base_vertex_base_instance"))425{426glRequestExtensionANGLE("GL_ANGLE_base_vertex_base_instance");427}428429if (!IsGLExtensionEnabled("GL_ANGLE_base_vertex_base_instance"))430{431return false;432}433434return true;435}436437bool requestInstancedExtension()438{439if (IsGLExtensionRequestable("GL_ANGLE_instanced_arrays"))440{441glRequestExtensionANGLE("GL_ANGLE_instanced_arrays");442}443444if (!IsGLExtensionEnabled("GL_ANGLE_instanced_arrays"))445{446return false;447}448449return true;450}451452bool requestExtensions()453{454if (getClientMajorVersion() <= 2)455{456if (!requestInstancedExtension())457{458return false;459}460}461return requestDrawBaseVertexBaseInstanceExtension();462}463464// Used for base vertex base instance draw calls465std::vector<GLushort> mIndices;466std::vector<GLfloat> mVertices;467std::vector<GLfloat> mNonIndexedVertices;468// Used when gl_BaseInstance is not used469std::array<GLfloat, kCountX> mInstancedArrayId;470std::array<GLfloat, kCountX> mInstancedArrayColorId;471// Used for regular draw calls without base vertex base instance472std::vector<GLushort> mRegularIndices;473GLint mPositionLoc;474GLuint mInstanceIDLoc;475GLuint mInstanceColorIDLoc;476};477478// Tests that compile a program with the extension succeeds479TEST_P(DrawBaseVertexBaseInstanceTest, CanCompile)480{481ANGLE_SKIP_TEST_IF(!requestExtensions());482GLProgram p0;483setupProgram(p0, true, false);484GLProgram p1;485setupProgram(p1, true, true);486GLProgram p2;487setupProgram(p2, false, false);488GLProgram p3;489setupProgram(p3, false, true);490}491492// Tests if baseInstance works properly with instanced array with non-zero divisor493TEST_P(DrawBaseVertexBaseInstanceTest, BaseInstanceDivisor)494{495ANGLE_SKIP_TEST_IF(!requestExtensions());496ANGLE_SKIP_TEST_IF(useBaseInstanceBuiltin());497498GLProgram program;499setupProgram(program, true, false, true);500501GLBuffer nonIndexedVertexBuffer;502setupNonIndexedBuffers(nonIndexedVertexBuffer);503setupPositionVertexAttribPointer();504505GLBuffer instanceIDBuffer;506GLBuffer instanceColorIDBuffer;507508setupInstanceIDBuffer(instanceIDBuffer);509setupInstanceIDVertexAttribPointer(mInstanceIDLoc);510setupInstanceColorIDBuffer(instanceColorIDBuffer);511setupInstanceIDVertexAttribPointer(mInstanceColorIDLoc);512513doDrawArraysInstancedBaseInstance();514EXPECT_GL_NO_ERROR();515checkDrawResult(false);516517doDrawArraysBaseInstanceReset();518EXPECT_GL_NO_ERROR();519checkDrawResult(false, true);520521GLProgram programIndexed;522setupProgram(programIndexed, false, false, true);523524GLBuffer indexBuffer;525GLBuffer vertexBuffer;526setupIndexedBuffers(vertexBuffer, indexBuffer);527setupPositionVertexAttribPointer();528529glBindBuffer(GL_ARRAY_BUFFER, instanceIDBuffer);530setupInstanceIDVertexAttribPointer(mInstanceIDLoc);531glBindBuffer(GL_ARRAY_BUFFER, instanceColorIDBuffer);532setupInstanceIDVertexAttribPointer(mInstanceColorIDLoc);533534doDrawElementsInstancedBaseVertexBaseInstance();535EXPECT_GL_NO_ERROR();536checkDrawResult(true);537538setupRegularIndexedBuffer(indexBuffer);539doDrawElementsBaseVertexBaseInstanceReset();540EXPECT_GL_NO_ERROR();541checkDrawResult(false, true);542}543544// Tests basic functionality of glDrawArraysInstancedBaseInstance545TEST_P(DrawBaseVertexBaseInstanceTest, DrawArraysInstancedBaseInstance)546{547// TODO(shrekshao): Temporarily skip this test548// before we could try updating win AMD bot driver version549// after Lab team fixed issues with ssh into bot machines550// Currently this test fail on certain Win7/Win2008Server AMD GPU551// with driver version 23.20.185.235 when using OpenGL backend.552// This failure couldn't be produced on local Win10 AMD machine with latest driver installed553// Same for the MultiDrawArraysInstancedBaseInstance test554if (IsAMD() && IsWindows() && IsDesktopOpenGL())555{556SystemInfo *systemInfo = GetTestSystemInfo();557if (!systemInfo->gpus.empty())558{559ANGLE_SKIP_TEST_IF(0x6613 == systemInfo->gpus[systemInfo->activeGPUIndex].deviceId);560}561}562563ANGLE_SKIP_TEST_IF(!requestExtensions());564565GLProgram program;566setupProgram(program, true);567568GLBuffer vertexBuffer;569setupNonIndexedBuffers(vertexBuffer);570setupPositionVertexAttribPointer();571572GLBuffer instanceIDBuffer;573if (!useBaseInstanceBuiltin())574{575setupInstanceIDBuffer(instanceIDBuffer);576setupInstanceIDVertexAttribPointer(mInstanceIDLoc);577}578579doDrawArraysInstancedBaseInstance();580EXPECT_GL_NO_ERROR();581checkDrawResult(false);582583doDrawArraysBaseInstanceReset();584EXPECT_GL_NO_ERROR();585checkDrawResult(false, true);586}587588// Tests basic functionality of glMultiDrawArraysInstancedBaseInstance589TEST_P(DrawBaseVertexBaseInstanceTest, MultiDrawArraysInstancedBaseInstance)590{591if (IsAMD() && IsWindows() && IsDesktopOpenGL())592{593SystemInfo *systemInfo = GetTestSystemInfo();594if (!(systemInfo->activeGPUIndex < 0 || systemInfo->gpus.empty()))595{596ANGLE_SKIP_TEST_IF(0x6613 == systemInfo->gpus[systemInfo->activeGPUIndex].deviceId);597}598}599600ANGLE_SKIP_TEST_IF(!requestExtensions());601602GLProgram program;603setupProgram(program, true, true);604605GLBuffer vertexBuffer;606setupNonIndexedBuffers(vertexBuffer);607setupPositionVertexAttribPointer();608609GLBuffer instanceIDBuffer;610if (!useBaseInstanceBuiltin())611{612setupInstanceIDBuffer(instanceIDBuffer);613setupInstanceIDVertexAttribPointer(mInstanceIDLoc);614}615616doMultiDrawArraysInstancedBaseInstance();617EXPECT_GL_NO_ERROR();618checkDrawResult(false);619620doDrawArraysBaseInstanceReset();621EXPECT_GL_NO_ERROR();622checkDrawResult(false, true);623}624625// Tests basic functionality of glDrawElementsInstancedBaseVertexBaseInstance626TEST_P(DrawBaseVertexBaseInstanceTest, DrawElementsInstancedBaseVertexBaseInstance)627{628ANGLE_SKIP_TEST_IF(!requestExtensions());629630GLProgram program;631setupProgram(program, false);632633GLBuffer indexBuffer;634GLBuffer vertexBuffer;635setupIndexedBuffers(vertexBuffer, indexBuffer);636setupPositionVertexAttribPointer();637638GLBuffer instanceIDBuffer;639if (!useBaseInstanceBuiltin())640{641setupInstanceIDBuffer(instanceIDBuffer);642setupInstanceIDVertexAttribPointer(mInstanceIDLoc);643}644645doDrawElementsInstancedBaseVertexBaseInstance();646EXPECT_GL_NO_ERROR();647checkDrawResult(true);648649setupRegularIndexedBuffer(indexBuffer);650doDrawElementsBaseVertexBaseInstanceReset();651EXPECT_GL_NO_ERROR();652checkDrawResult(true, true);653}654655// Tests basic functionality of glMultiDrawElementsInstancedBaseVertexBaseInstance656TEST_P(DrawBaseVertexBaseInstanceTest, MultiDrawElementsInstancedBaseVertexBaseInstance)657{658ANGLE_SKIP_TEST_IF(!requestExtensions());659660GLProgram program;661setupProgram(program, false, true);662663GLBuffer indexBuffer;664GLBuffer vertexBuffer;665setupIndexedBuffers(vertexBuffer, indexBuffer);666setupPositionVertexAttribPointer();667668GLBuffer instanceIDBuffer;669if (!useBaseInstanceBuiltin())670{671setupInstanceIDBuffer(instanceIDBuffer);672setupInstanceIDVertexAttribPointer(mInstanceIDLoc);673}674675doMultiDrawElementsInstancedBaseVertexBaseInstance();676EXPECT_GL_NO_ERROR();677checkDrawResult(true);678679setupRegularIndexedBuffer(indexBuffer);680doDrawElementsBaseVertexBaseInstanceReset();681EXPECT_GL_NO_ERROR();682checkDrawResult(true, true);683}684685const angle::PlatformParameters platforms[] = {686ES3_D3D11(),687ES3_OPENGL(),688ES3_OPENGLES(),689ES3_VULKAN(),690};691692GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DrawBaseVertexBaseInstanceTest);693INSTANTIATE_TEST_SUITE_P(694,695DrawBaseVertexBaseInstanceTest,696testing::Combine(697testing::ValuesIn(::angle::FilterTestParams(platforms, ArraySize(platforms))),698testing::Values(BaseVertexOption::NoBaseVertex, BaseVertexOption::UseBaseVertex),699testing::Values(BaseInstanceOption::NoBaseInstance, BaseInstanceOption::UseBaseInstance),700testing::Values(BufferDataUsageOption::StaticDraw, BufferDataUsageOption::DynamicDraw)),701PrintToStringParamName());702703} // namespace704705706