Graphics
Intel® graphics drivers and software, compatibility, troubleshooting, performance, and optimization
21571 Discussions

OpenGL bug only on Intel Iris XE

kodo_simio
Beginner
795 Views

The following code causes flickering geometry for me under the following conditions:

  • If multisampling is enabled at any sample resolution
  • If the GL_TEXTURE_2D_ARRAY txtures are rendered last (it doesn't happen if the GL_TEXTURE_2D textures are rendered last)
  • It only appears to happen on my Intel Iris XE integrated card and not on the dedicated NVidea one

The code is a complete program that only uses GLFW and GLM as dependencies.

I've stripped out all error checking code for brevity but I'm certain there are no explicit errors in the code.

If the code looks a little strange that's because it is extracted from a MUCH larger rendering API in a way that repos the issue.

Any help or insight would be greatly appreciated.

 

const char* tvc = R"(
#version 330 core

layout(location = 0) in vec2 a_position;
layout(location = 1) in vec2 a_uv;
layout(location = 2) in vec4 a_color;

uniform mat4 u_projTrans;

out vec2 v_uv;
out vec4 v_color;

void main()
{
    gl_Position = u_projTrans * vec4(a_position, 0.0, 1.0);
    v_uv = a_uv;
    v_color = a_color;
}
)";
const char* tfc = R"(
#version 330 core

uniform sampler2D u_texture;

in vec2 v_uv;
in vec4 v_color;

out vec4 fragColor;

void main()
{
    fragColor = v_color * texture(u_texture, v_uv);
}
)";

const char* avc = R"(
#version 330 core

layout(location = 0) in vec2 a_position;
layout(location = 1) in vec3 a_uv;
layout(location = 2) in float a_layer;
layout(location = 3) in vec4 a_color;

uniform mat4 u_projTrans;

out vec3 v_uv;
out vec4 v_color;

void main()
{
    gl_Position = u_projTrans * vec4(a_position, 0.0, 1.0);
    v_uv = vec3(a_uv.xy, a_layer);
    v_color = a_color;
}
)";
const char* afc = R"(
#version 330 core

uniform sampler2DArray u_texture;

in vec3 v_uv;
in vec4 v_color;

out vec4 fragColor;

void main()
{
    fragColor = v_color * texture(u_texture, v_uv);
}
)";

inline unsigned int create_shader(const char* vertCode, const char* fragCode, unsigned int textureLocation)
{
    unsigned int vid = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vid, 1, &vertCode, NULL);
    glCompileShader(vid);
    unsigned int fid = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fid, 1, &fragCode, NULL);
    glCompileShader(fid);
    unsigned int shaderID = glCreateProgram();
    glAttachShader(shaderID, vid);
    glAttachShader(shaderID, fid);
    glLinkProgram(shaderID);
    glDeleteShader(vid);
    glDeleteShader(fid);
    glUseProgram(shaderID);
    glUniform1i(glGetUniformLocation(shaderID, "u_texture"), textureLocation);
    return shaderID;
}

inline unsigned int create_texture_2d(int w, int h, void* data)
{
    unsigned int textureID;
    glGenTextures(1, &textureID);
    glBindTexture(GL_TEXTURE_2D, textureID);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glBindTexture(GL_TEXTURE_2D, 0);
    return textureID;
}

inline unsigned int create_texture_2d_array(int w, int h, int layers, void* data)
{
    unsigned int textureID;
    glGenTextures(1, &textureID);
    glBindTexture(GL_TEXTURE_2D_ARRAY, textureID);
    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, w, h, layers, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
    glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
    return textureID;
}

struct TextureVertex
{
    glm::vec2   position;
    glm::vec2   uv;
    glm::u8vec4 color;
};

struct TextureArrayVertex
{
    glm::vec2   position;
    glm::vec2   uv;
    float       layer;
    glm::u8vec4 color;
};

inline void make_textured_quad(TextureVertex* vertices, float x, float y, float width, float height, glm::u8vec4 color)
{
    float r = x + width;
    float b = y + height;
    vertices[0] = { { x, y }, { 0.0f, 1.0f }, color };
    vertices[1] = { { x, b }, { 0.0f, 0.0f }, color };
    vertices[2] = { { r, b }, { 1.0f, 0.0f }, color };
    vertices[3] = { { r, b }, { 1.0f, 0.0f }, color };
    vertices[4] = { { r, y }, { 1.0f, 1.0f }, color };
    vertices[5] = { { x, y }, { 0.0f, 1.0f }, color };
}

inline void make_textured_array_quad(TextureArrayVertex* vertices, float x, float y, float width, float height, float layer, glm::u8vec4 color)
{
    float r = x + width;
    float b = y + height;
    vertices[0] = { { x, y }, { 0.0f, 1.0f }, layer, color };
    vertices[1] = { { x, b }, { 0.0f, 0.0f }, layer, color };
    vertices[2] = { { r, b }, { 1.0f, 0.0f }, layer, color };
    vertices[3] = { { r, b }, { 1.0f, 0.0f }, layer, color };
    vertices[4] = { { r, y }, { 1.0f, 1.0f }, layer, color };
    vertices[5] = { { x, y }, { 0.0f, 1.0f }, layer, color };
}

inline void use_shader(unsigned int shaderID, glm::mat4& matrix)
{
    glUseProgram(shaderID);
    glUniformMatrix4fv(glGetUniformLocation(shaderID, "u_projTrans"), 1, GL_FALSE, &matrix[0][0]);
}

inline void bind_texture(GLenum textureType, unsigned int unit, unsigned int textureID)
{
    glActiveTexture(GL_TEXTURE0 + unit);
    glBindTexture(textureType, textureID);
}

template<typename VertexType>
inline void upload_and_draw(unsigned int vaoid, unsigned int vboid, unsigned int vertexCount, VertexType* vertices)
{
    glBindVertexArray(vaoid);
    glBindBuffer(GL_ARRAY_BUFFER, vboid);
    glBufferSubData(GL_ARRAY_BUFFER, 0, vertexCount * sizeof(VertexType), vertices);
    glDrawArrays(GL_TRIANGLES, 0, vertexCount);
}

int main()
{
    if (!glfwInit()) return EXIT_FAILURE;

    int w = 900;
    int h = 500;

    glfwWindowHint(GLFW_SAMPLES, 4);
    glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
    glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_TRUE);
    glfwWindowHint(GLFW_STENCIL_BITS, 8);
    glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
    glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE);
    glfwWindowHint(GLFW_DECORATED, GLFW_TRUE);
    glfwWindowHint(GLFW_FOCUSED, GLFW_TRUE);
    glfwWindowHint(GLFW_MAXIMIZED, GLFW_FALSE);

    GLFWwindow* glfwWindow = glfwCreateWindow(w, h, "Test", NULL, NULL);

    if (!glfwWindow)
    {
        glfwTerminate();
        return EXIT_FAILURE;
    }

    glfwMakeContextCurrent(glfwWindow);

    glewExperimental = GL_TRUE;
    if (glewInit() != GLEW_OK)
    {
        glfwTerminate();
        return EXIT_FAILURE;
    }

    glfwSwapInterval(1);

    unsigned char whiteData[]{ 255, 255, 255, 255 };
    unsigned char blueData[]{ 0, 0, 255, 255 };
    unsigned char arrayData[]{ 255, 0, 255, 255, 0, 255, 255, 255 };

    TextureVertex      tvs[12];
    TextureArrayVertex avs[12];

    make_textured_quad(tvs + 0, 10, 10, 100, 200, { 255,255,255,255 });
    make_textured_quad(tvs + 6, 120, 10, 100, 200, { 255,255,255,255 });
    make_textured_array_quad(avs + 0, 230, 10, 100, 200, 0, { 255,255,255,255 });
    make_textured_array_quad(avs + 6, 340, 10, 100, 200, 1, { 255,255,255,255 });

    unsigned int capacity = 1000;
    unsigned int texVAOID;
    unsigned int texVBOID;
    unsigned int arrVAOID;
    unsigned int arrVBOID;
    unsigned int textureShaderID;
    unsigned int arrayShaderID;
    unsigned int whiteTexID;
    unsigned int blueTexID;
    unsigned int arrayTexID;

    glGenVertexArrays(1, &texVAOID);
    glBindVertexArray(texVAOID);
    glGenBuffers(1, &texVBOID);
    glBindBuffer(GL_ARRAY_BUFFER, texVBOID);
    glBufferData(GL_ARRAY_BUFFER, capacity * sizeof(TextureVertex), nullptr, GL_DYNAMIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(TextureVertex), (const void*)offsetof(TextureVertex, position));
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(TextureVertex), (const void*)offsetof(TextureVertex, uv));
    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(TextureVertex), (const void*)offsetof(TextureVertex, color));
    glBindVertexArray(0);

    glGenVertexArrays(1, &arrVAOID);
    glBindVertexArray(arrVAOID);
    glGenBuffers(1, &arrVBOID);
    glBindBuffer(GL_ARRAY_BUFFER, arrVBOID);
    glBufferData(GL_ARRAY_BUFFER, capacity * sizeof(TextureArrayVertex), nullptr, GL_DYNAMIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(TextureArrayVertex), (const void*)offsetof(TextureArrayVertex, position));
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(TextureArrayVertex), (const void*)offsetof(TextureArrayVertex, uv));
    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(TextureArrayVertex), (const void*)offsetof(TextureArrayVertex, layer));
    glEnableVertexAttribArray(3);
    glVertexAttribPointer(3, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(TextureArrayVertex), (const void*)offsetof(TextureArrayVertex, color));
    glBindVertexArray(0);

    textureShaderID = create_shader(tvc, tfc, 0);
    arrayShaderID   = create_shader(avc, afc, 1);

    whiteTexID = create_texture_2d(1, 1, whiteData);
    blueTexID  = create_texture_2d(1, 1, blueData);
    arrayTexID = create_texture_2d_array(1, 1, 2, arrayData);

    while (!glfwWindowShouldClose(glfwWindow))
    {
        glfwPollEvents();

        glfwGetFramebufferSize(glfwWindow, &w, &h);

        glm::mat4 matrix = glm::ortho(0.0f, (float)w, (float)h, 0.0f, -1.0f, 1.0f);

        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glDisable(GL_DEPTH_TEST);
        glViewport(0, 0, w, h);
        glClearColor(0.6f, 0.2f, 0.6f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        use_shader(textureShaderID, matrix);
        
        bind_texture(GL_TEXTURE_2D, 0, whiteTexID);
        
        upload_and_draw(texVAOID, texVBOID, 6, tvs);
        
        bind_texture(GL_TEXTURE_2D, 0, blueTexID);

        upload_and_draw(texVAOID, texVBOID, 6, tvs + 6);

        bind_texture(GL_TEXTURE_2D, 0, whiteTexID);
        
        use_shader(arrayShaderID, matrix);

        bind_texture(GL_TEXTURE_2D_ARRAY, 1, arrayTexID);
        
        upload_and_draw(arrVAOID, arrVBOID, 12, avs);

        glfwSwapBuffers(glfwWindow);
    }

    glfwTerminate();

    return EXIT_SUCCESS;
}  

 

0 Kudos
1 Reply
IsaacQ_Intel
Employee
754 Views

Hello kodo_simio

 

Thank you for posting on the Intel️® communities.

 

Please, create an account to submit your inquiry in our Intel®️ Developer Zone, as the document you refer to comes from this website. So, you receive further troubleshooting support and get access to documentation. 

 

Intel®️ Developer Zone - Contact Page 


Since the thread is related to the Developer Zone, we will close it. If you need any additional information, please submit a new question as this thread will no longer be monitored.  

 

Best regards,

Isaac Q. 

Intel Customer Support Technician


0 Kudos
Reply