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

glTextureView() and GL_STENCIL_INDEX bug on Intel UHD620

Tarquiscani__Andrea
917 Views

System Setup Information:
-----------------------------------------

System Used: HP ENVY Laptop 17-ae142ng
CPU SKU: i7-8550U CPU
GPU SKU: Intel UHD Graphics 620
Processor Line: Kaby Lake R
System BIOS Version: Insyde F.28, 29/04/2019
CMOS settings:
Graphics Driver Version: 25.20.100.6519
GOP/VBIOS Version:
Operating System: Microsoft Windows 10 Home 64bit
OS Version: 10.0.18362 Build 18362
API: OpenGL 4.3
Occurs on non-Intel GPUs?: No

Steps to Reproduce:
-------------------------------


I'm using a texture view to ease the access to the stencil index of a depth-stencil texture. It works perfectly fine on the dedicated nVidia GPU, but doesn't work on the integrated Intel GPU. I know that the stencil values are there in the depth-stencil texture because I checked them via glGetTexImage(). But when I access these values in the shader (by the texture view) I get only zeroes.

I did some tests. If I set the parameter GL_DEPTH_STENCIL_TEXTURE_MODE to GL_STENCIL_INDEX directly on the depth-stencil texture, avoiding the use of the texture view, then it works fine. If I use the texture view to retrieve the depth component (leaving GL_DEPTH_STENCIL_TEXTURE_MODE to the default value, i.e. GL_DEPTH_COMPONENT), then the texture view works fine. It seems that only the combination of both produces an error.

The full minimal code is pretty long, so I removed certain parts, but I can provide the full code if needed.

filter.fragmentshader

#version 430 core
out vec4 fs_frag_color;

in vec2 vs_tex_coords;

layout (binding = 0) uniform usampler2D u_stencil_tex;


void main()
{   
    uint draw_count = texture(u_stencil_tex, vs_tex_coords).r;

    // Show stencil buffer
    if(draw_count == 1)
    {
        fs_frag_color = vec4(0, 1, 0, 1);
    }
    else if(draw_count > 1 && draw_count <= 10)
    {
        float orange_shade = float(draw_count + 5) / 15.0;
        fs_frag_color = vec4(orange_shade, orange_shade, 0 ,1);
    }
    else if(draw_count > 10 && draw_count <= 50)
    {
        float red_shade = float(draw_count + 5) / 55.0;
        fs_frag_color = vec4(red_shade, 0, 0, 1);
    }
    else
    {
        fs_frag_color = vec4(0, 0, 0, 1);
    }
}

main.cpp

int main(void)
{
    //Initialize GLFW and open a window with a 4.3 OpenGL context
    // ...

    glEnable(GL_DEBUG_OUTPUT);
    glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
    glDebugMessageCallback(debugMessage_callback, nullptr);



    Shader main_shader;
    main_shader.load("shader.vs", "shader.fs");

    Shader filter_shader;
    filter_shader.load("filter.vs", "filter.fs");


    //CUBE VAO
    GLuint cube_VAO;
    GLuint cube_VBO;
    glGenVertexArrays(1, &cube_VAO);
    glGenBuffers(1, &cube_VBO);
    glBindVertexArray(cube_VAO);
        // cube_VAO settings...
    glBindVertexArray(0);


    //OFFSCREEN FBO
    GLuint offscreen_FBO = 0;
    GLuint offscreen_colorTex = 0;
    GLuint offscreen_depthStencilTex = 0;
    GLuint offscreen_stencilTexView = 0;

    int offscreen_width, offscreen_height;
    glfwGetFramebufferSize(window1, &offscreen_width, &offscreen_height);
    glGenFramebuffers(1, &offscreen_FBO);
    glBindFramebuffer(GL_FRAMEBUFFER, offscreen_FBO);

        glGenTextures(1, &offscreen_colorTex);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, offscreen_colorTex);
            glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, offscreen_width, 
                           offscreen_height);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glBindTexture(GL_TEXTURE_2D, 0); //unbind

        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                               GL_TEXTURE_2D, offscreen_colorTex, 0);

        static GLenum offscreen_drawBuffers[] = { GL_COLOR_ATTACHMENT0 };
        glDrawBuffers(1, offscreen_drawBuffers);


        glGenTextures(1, &offscreen_depthStencilTex);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, offscreen_depthStencilTex);
            glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, 
                           offscreen_width, offscreen_height);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glBindTexture(GL_TEXTURE_2D, 0); //unbind

        // Attach the depth and stencil texture to the framebuffer
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, 
                               GL_TEXTURE_2D, offscreen_depthStencilTex, 0);


        // >>>>>>
        // >>>>>>  Here the important block
        // >>>>>>
        glGenTextures(1, &offscreen_stencilTexView);
        glTextureView(offscreen_stencilTexView, GL_TEXTURE_2D, 
                      offscreen_depthStencilTex, GL_DEPTH24_STENCIL8, 0, 1, 0, 1);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, offscreen_stencilTexView);
            glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, 
                            GL_STENCIL_INDEX);
        glBindTexture(GL_TEXTURE_2D, 0);
        // ^^^^^^
        // ^^^^^^  Here the important block
        // ^^^^^^


        // Check if the framebuffer is complete
        if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
            throw std::runtime_error("The offscreen FBO is not complete.");

    glBindFramebuffer(GL_FRAMEBUFFER, 0); //unbind



    // WINDOW RECTANGLE VAO
    GLuint wRect_VAO;
    GLuint wRect_VBO;
    glGenVertexArrays(1, &wRect_VAO);
    glGenBuffers(1, &wRect_VBO);
    glBindVertexArray(wRect_VAO);
        // wRect_VAO settings ...
    glBindVertexArray(0);


    while (!glfwWindowShouldClose(window1))
    {
        float ratio;
        int width, height;

        glfwGetFramebufferSize(window1, &width, &height);
        ratio = width / (float)height;

        glViewport(0, 0, width, height);


        // Drawing on the offscreen FBO
        glBindFramebuffer(GL_FRAMEBUFFER, offscreen_FBO);
            glEnable(GL_DEPTH_TEST);

            glEnable(GL_STENCIL_TEST);
                glStencilFunc(GL_ALWAYS, 1, 0xFF); //stencil test always pass
                glStencilOp(GL_KEEP, GL_INCR, GL_INCR); //the value stored in the stencil buffer is increased every time a fragment is not discarded

            glClearColor(1.f, 1.f, 1.f, 1.f);
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

            main_shader.bind();

            glm::mat4 view(1.0f); view = glm::translate(view, glm::vec3(0.f, 0.f, -3.f));
            glm::mat4 projection = glm::perspective(glm::radians(45.f), 800.f / 600.f, 0.1f, 100.0f);
            glm::mat4 model(1.f);
            model = glm::rotate(model, glm::radians(static_cast<float>(glfwGetTime() * 20.f)), glm::vec3(1.f, 1.f, 0.f));
            main_shader.set_mat4("model", model);
            main_shader.set_mat4("view", view);
            main_shader.set_mat4("projection", projection);

            glBindVertexArray(cube_VAO);
                glDrawArrays(GL_TRIANGLES, 0, 36);
            glBindVertexArray(0);

        // Drawing on the default FBO
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
            glDisable(GL_DEPTH_TEST);
            glClearColor(0.f, 1.f, 1.f, 1.f);
            glClear(GL_COLOR_BUFFER_BIT);

            filter_shader.bind();

            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, offscreen_stencilTexView);

            glBindVertexArray(wRect_VAO);
                glDrawArrays(GL_TRIANGLES, 0, 6);
            glBindVertexArray(0);                                   
        glBindFramebuffer(GL_FRAMEBUFFER, 0);


        glfwSwapBuffers(window1);


        glfwPollEvents();
    }

    //Destroy the window and shut down GLFW ...
}

 

Expected Results:
-------------------------------

I expect to access the texture in the fragment shader and use the actual values stored inside.

 

Actual Results:
-------------------------------

Black screen. I can't access the actual values of the texture in the fragment shader. I got only zeroes.

0 Kudos
0 Replies
Reply