src/third_party/angle/src/tests/gl_tests/DrawElementsTest.cpp
// Test a state desync that can occur when using a streaming index buffer in GL in concert with
// deleting the applied index buffer.
Test a state desync that can occur when using a streaming index buffer in GL in concert with
deleting the applied index buffer.
Test a state desync that can occur when using a streaming index buffer in GL in concert with deleting the applied index buffer .
TEST_P(DrawElementsTest, DeletingAfterStreamingIndexes)
{
    constexpr char kVS[] =
        "attribute vec2 position;\n"
        "attribute vec2 testFlag;\n"
        "varying vec2 v_data;\n"
        "void main() {\n"
        "  gl_Position = vec4(position, 0, 1);\n"
        "  v_data = testFlag;\n"
        "}";
    constexpr char kFS[] =
        "varying highp vec2 v_data;\n"
        "void main() {\n"
        "  gl_FragColor = vec4(v_data, 0, 1);\n"
        "}";
    mProgram = CompileProgram(kVS, kFS);
    ASSERT_NE(0u, mProgram);
    glUseProgram(mProgram);
    GLint positionLocation = glGetAttribLocation(mProgram, "position");
    ASSERT_NE(-1, positionLocation);
    GLint testFlagLocation = glGetAttribLocation(mProgram, "testFlag");
    ASSERT_NE(-1, testFlagLocation);
    mIndexBuffers.resize(3u);
    glGenBuffers(3, &mIndexBuffers[0]);
    mVertexArrays.resize(2);
    glGenVertexArrays(2, &mVertexArrays[0]);
    mVertexBuffers.resize(2);
    glGenBuffers(2, &mVertexBuffers[0]);
    std::vector<GLuint> indexData[2];
    indexData[0].push_back(0);
    indexData[0].push_back(1);
    indexData[0].push_back(2);
    indexData[0].push_back(2);
    indexData[0].push_back(3);
    indexData[0].push_back(0);
    indexData[1] = indexData[0];
    for (GLuint &item : indexData[1])
    {
        item += 4u;
    }
    std::vector<GLfloat> positionData = {
                                         -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f,
                                         -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f};
    std::vector<GLfloat> testFlagData = {
                                         1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
                                         0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f};
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[0]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indexData[0].size(), &indexData[0][0],
                 GL_STATIC_DRAW);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[2]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indexData[0].size(), &indexData[0][0],
                 GL_STATIC_DRAW);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[1]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indexData[1].size(), &indexData[1][0],
                 GL_STATIC_DRAW);
    glBindVertexArray(mVertexArrays[0]);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[1]);
    glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffers[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * positionData.size(), &positionData[0],
                 GL_STATIC_DRAW);
    glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
    glEnableVertexAttribArray(positionLocation);
    glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffers[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * testFlagData.size(), &testFlagData[0],
                 GL_STATIC_DRAW);
    glVertexAttribPointer(testFlagLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
    glEnableVertexAttribArray(testFlagLocation);
    glBindVertexArray(mVertexArrays[1]);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[0]);
    glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffers[0]);
    glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
    glEnableVertexAttribArray(positionLocation);
    glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffers[1]);
    glVertexAttribPointer(testFlagLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
    glEnableVertexAttribArray(testFlagLocation);
    ASSERT_GL_NO_ERROR();
    glBindVertexArray(mVertexArrays[0]);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
    glBindVertexArray(mVertexArrays[1]);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    glBindVertexArray(mVertexArrays[0]);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
    glDeleteBuffers(1, &mIndexBuffers[2]);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
    ASSERT_GL_NO_ERROR();
}
TEST_P ( DrawElementsTest , DeletingAfterStreamingIndexes ) { constexpr char kVS [ ] = " \n " " \n " " \n " " \n " " \n " " \n " " " ; constexpr char kFS [ ] = " \n " " \n " " \n " " " ; mProgram = CompileProgram ( kVS , kFS ) ; ASSERT_NE ( 0u , mProgram ) ; glUseProgram ( mProgram ) ; GLint positionLocation = glGetAttribLocation ( mProgram , " " ) ; ASSERT_NE ( -1 , positionLocation ) ; GLint testFlagLocation = glGetAttribLocation ( mProgram , " " ) ; ASSERT_NE ( -1 , testFlagLocation ) ; mIndexBuffers . resize ( 3u ) ; glGenBuffers ( 3 , & mIndexBuffers [ 0 ] ) ; mVertexArrays . resize ( 2 ) ; glGenVertexArrays ( 2 , & mVertexArrays [ 0 ] ) ; mVertexBuffers . resize ( 2 ) ; glGenBuffers ( 2 , & mVertexBuffers [ 0 ] ) ; std :: vector < GLuint > indexData [ 2 ] ; indexData [ 0 ] . push_back ( 0 ) ; indexData [ 0 ] . push_back ( 1 ) ; indexData [ 0 ] . push_back ( 2 ) ; indexData [ 0 ] . push_back ( 2 ) ; indexData [ 0 ] . push_back ( 3 ) ; indexData [ 0 ] . push_back ( 0 ) ; indexData [ 1 ] = indexData [ 0 ] ; for ( GLuint & item : indexData [ 1 ] ) { item += 4u ; } std :: vector < GLfloat > positionData = { -1.0f , 1.0f , -1.0f , -1.0f , 1.0f , -1.0f , 1.0f , 1.0f , -1.0f , 1.0f , -1.0f , -1.0f , 1.0f , -1.0f , 1.0f , 1.0f } ; std :: vector < GLfloat > testFlagData = { 1.0f , 0.0f , 1.0f , 0.0f , 1.0f , 0.0f , 1.0f , 0.0f , 0.0f , 1.0f , 0.0f , 1.0f , 0.0f , 1.0f , 0.0f , 1.0f } ; glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER , mIndexBuffers [ 0 ] ) ; glBufferData ( GL_ELEMENT_ARRAY_BUFFER , sizeof ( GLuint ) * indexData [ 0 ] . size ( ) , & indexData [ 0 ] [ 0 ] , GL_STATIC_DRAW ) ; glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER , mIndexBuffers [ 2 ] ) ; glBufferData ( GL_ELEMENT_ARRAY_BUFFER , sizeof ( GLuint ) * indexData [ 0 ] . size ( ) , & indexData [ 0 ] [ 0 ] , GL_STATIC_DRAW ) ; glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER , mIndexBuffers [ 1 ] ) ; glBufferData ( GL_ELEMENT_ARRAY_BUFFER , sizeof ( GLuint ) * indexData [ 1 ] . size ( ) , & indexData [ 1 ] [ 0 ] , GL_STATIC_DRAW ) ; glBindVertexArray ( mVertexArrays [ 0 ] ) ; glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER , mIndexBuffers [ 1 ] ) ; glBindBuffer ( GL_ARRAY_BUFFER , mVertexBuffers [ 0 ] ) ; glBufferData ( GL_ARRAY_BUFFER , sizeof ( GLfloat ) * positionData . size ( ) , & positionData [ 0 ] , GL_STATIC_DRAW ) ; glVertexAttribPointer ( positionLocation , 2 , GL_FLOAT , GL_FALSE , sizeof ( GLfloat ) * 2 , nullptr ) ; glEnableVertexAttribArray ( positionLocation ) ; glBindBuffer ( GL_ARRAY_BUFFER , mVertexBuffers [ 1 ] ) ; glBufferData ( GL_ARRAY_BUFFER , sizeof ( GLfloat ) * testFlagData . size ( ) , & testFlagData [ 0 ] , GL_STATIC_DRAW ) ; glVertexAttribPointer ( testFlagLocation , 2 , GL_FLOAT , GL_FALSE , sizeof ( GLfloat ) * 2 , nullptr ) ; glEnableVertexAttribArray ( testFlagLocation ) ; glBindVertexArray ( mVertexArrays [ 1 ] ) ; glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER , mIndexBuffers [ 0 ] ) ; glBindBuffer ( GL_ARRAY_BUFFER , mVertexBuffers [ 0 ] ) ; glVertexAttribPointer ( positionLocation , 2 , GL_FLOAT , GL_FALSE , sizeof ( GLfloat ) * 2 , nullptr ) ; glEnableVertexAttribArray ( positionLocation ) ; glBindBuffer ( GL_ARRAY_BUFFER , mVertexBuffers [ 1 ] ) ; glVertexAttribPointer ( testFlagLocation , 2 , GL_FLOAT , GL_FALSE , sizeof ( GLfloat ) * 2 , nullptr ) ; glEnableVertexAttribArray ( testFlagLocation ) ; ASSERT_GL_NO_ERROR ( ) ; glBindVertexArray ( mVertexArrays [ 0 ] ) ; glDrawElements ( GL_TRIANGLES , 6 , GL_UNSIGNED_INT , nullptr ) ; EXPECT_PIXEL_COLOR_EQ ( 0 , 0 , GLColor :: green ) ; glBindVertexArray ( mVertexArrays [ 1 ] ) ; glDrawElements ( GL_TRIANGLES , 6 , GL_UNSIGNED_INT , nullptr ) ; EXPECT_PIXEL_COLOR_EQ ( 0 , 0 , GLColor :: red ) ; glBindVertexArray ( mVertexArrays [ 0 ] ) ; glDrawElements ( GL_TRIANGLES , 6 , GL_UNSIGNED_INT , nullptr ) ; EXPECT_PIXEL_COLOR_EQ ( 0 , 0 , GLColor :: green ) ; glDeleteBuffers ( 1 , & mIndexBuffers [ 2 ] ) ; glDrawElements ( GL_TRIANGLES , 6 , GL_UNSIGNED_INT , nullptr ) ; EXPECT_PIXEL_COLOR_EQ ( 0 , 0 , GLColor :: green ) ; ASSERT_GL_NO_ERROR ( ) ; }
Test a state desync that can occur when using a streaming index buffer in GL in concert with
deleting the applied index buffer.
Test a state desync that can occur when using a streaming index buffer in GL in concert with deleting the applied index buffer .
// Init program // quad verts // Repeat position data // red // green // Initialize first vertex array with second index buffer // Initialize second vertex array with first index buffer // Trigger the bug here.