pal1000 / mesa-dist-win

Pre-built Mesa3D drivers for Windows
MIT License
907 stars 80 forks source link

SWR Drivers result in a black screen. #22

Open human-0 opened 5 years ago

human-0 commented 5 years ago

Using the SWR drivers (GALLIUM_DRIVER=swr) results in a completely black screen. The code:

Why do these not work?

pal1000 commented 5 years ago

For starters swr has fewer extensions than both llvmpipe and softpipe. It is in the last place on Mesamatrix leader board. Maybe you are using something it can't handle or it's bug. A testcase would help as I could try reproducing it. If it's a bug then we'll have to escalate it upstream.

human-0 commented 5 years ago

It should be able to handle it. It' works in OpenGL 3.3 and anything not supported should create a null ptr, but that doesn't seem to happen. The only possible extensions not supported by SWR below 3.3 are "Extensions that are not part of any OpenGL or OpenGL ES version", which are related to textures and int64, which I'm not using. For example, this will not work with SWR

int main() {

    if (!glfwInit())
            throw std::runtime_error("Failed to initialize GLFW");
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    GLFWwindow* window = glfwCreateWindow(1280, 720, "test", nullptr, nullptr);
    if (!window) {
        const char* message;
        int err = glfwGetError(&message);
        std::cout << message << std::endl;
        if (err == GLFW_VERSION_UNAVAILABLE)
            std::cout << "OpenGL 3.3 is required" << std::endl;
        throw std::runtime_error("Failed to create window");
    }

    glfwMakeContextCurrent(window);
    gladLoadGLLoader(reinterpret_cast<GLADloadproc>(glfwGetProcAddress));

    GLuint vao, vbo, ibo;
    GLfloat position[] =
    {
        -0.5f, -0.5f, 0.0f,
        0.5f, -0.5f, 0.0f,
        0.5f, 0.5f, 0.0f,
        -0.5f, 0.5f, 0.0f
    };

    GLuint indices[] =
    {
        0, 1, 2,
        0, 2, 3
    };

    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(position), position, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);

    glGenBuffers(1, &ibo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    GLuint vertex = glCreateShader(GL_VERTEX_SHADER), fragment = glCreateShader(GL_FRAGMENT_SHADER);

    {

        const char* shaderSource =
            "#version 330 core\n"
            "layout(location = 0) in vec3 position;\n"
            "\n"
            "void main()\n"
            "{\n"
            "gl_Position = vec4(position, 1.0);\n"
            "}\n"
            "";

        glShaderSource(vertex, 1, &shaderSource, 0);
        glCompileShader(vertex);

        GLint result;
        glGetShaderiv(vertex, GL_COMPILE_STATUS, &result);
        if (result == GL_FALSE)
        {
            char buffer[512];
            glGetShaderInfoLog(vertex, 512, nullptr, buffer);
            std::cerr << "Failed to compile shader: " << buffer << std::endl;
        }
    }

    {

        const char* shaderSource =
            "#version 330 core\n"
            "layout(location = 0) out vec4 col;\n"
            "\n"
            "void main()\n"
            "{\n"
            "col = vec4(0.3, 0.8, 0.2, 1.0);\n"
            "}\n"
            "";

        glShaderSource(fragment, 1, &shaderSource, 0);
        glCompileShader(fragment);

        GLint result;
        glGetShaderiv(fragment, GL_COMPILE_STATUS, &result);
        if (result == GL_FALSE)
        {
            char buffer[512];
            glGetShaderInfoLog(fragment, 512, nullptr, buffer);
            std::cerr << "Failed to compile shader: " << buffer << std::endl;
        }
    }

    GLuint program = glCreateProgram();
    glAttachShader(program, vertex);
    glAttachShader(program, fragment);

    glLinkProgram(program);
    glValidateProgram(program);

    GLint result;
    glGetProgramiv(program, GL_LINK_STATUS, &result);
    if (result == GL_FALSE)
    {
        char buffer[1024];
        glGetProgramInfoLog(program, 1024, nullptr, buffer);
        std::cerr << "Failed to link program: " << buffer << std::endl;
    }

    glUseProgram(program);

    double time = glfwGetTime();
    int count = 0;
    while (!glfwWindowShouldClose(window))
    {
        glClear(GL_COLOR_BUFFER_BIT);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

        count++;
        if (glfwGetTime() - time >= 1.0)
        {
            std::cout << count << std::endl;
            time = glfwGetTime();
            count = 0;
        }

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    return 0;
}

VS 2019 solution

pal1000 commented 5 years ago

The testcase doesn't need MESA_GL_VERSION_OVERRIDE or MESA_GLSL_VERSION_OVERRIDE to work because you are using OpenGL 3.3 core profile.

This is what Mesa3D software rendering stack supports for each OpenGL context:

Compatibility profile Core profile or forward compatible context
3.1 3.3

The problem here however seams to be the failure of this testcase or GLFW library itself to use swr driver, because when I try to run using swr it doesn't even get to the test window, instead I get this error: WGL: Failed to load opengl32.dll: A dynamic link library (DLL) initialization routine failed.

human-0 commented 5 years ago

That is very strange. I didn't get that error. Maybe try using per app deployment (which I was using).

pal1000 commented 5 years ago

Per app deployment is exactly what I was using as that's where swrtest.exe.local comes from so this is getting interesting. I also retried with .local file removed and no difference. Also of note is the fact that you may have a newer CPU generation which can run swrAVX2. You mentioned a system with OpenGL 4.3 in the beginning of this thread which matches OpenGL support of 4th generation Intel Core integrated graphics driver. 4th generation Intel Core is the first CPU generation that can run swrAVX2. It is very well possible that swrAVX2 fails differently than swrAVX. You can try renaming swrAVX2.dll symbolic link made by per-app deployment to force fallback to swrAVX.

human-0 commented 5 years ago

swrAVX does not result in a black screen like swrAVX2 does. However, at many resolutions such as 360p, 720p, 1080p and 1440p, it still does not render properly. For example, 1280x720 won't work but 1281x720 and 1280x721 will. Some 16:9 resolutions will work but not those which are multiples of 360p (although I've only tested up to 1440p). Here This is the rendering at 720p. It should just be a green rectangle but there are very obvious problems with it.

pal1000 commented 5 years ago

There is enough evidence for this to be an upstream bug, so there is nothing I can do about it. Go here to continue your journey.

I saw scratches like those when testing PPSSPP emulator UI with swr. Looking at tests you did at various resolutions it looks like an off by 1 error.

human-0 commented 5 years ago

What about swrAVX2 not working at all?

pal1000 commented 5 years ago

swrAVX2 can't run on my system as my CPU doesn't meet the requirements for it, so Mesa3D falls back to swrAVX automatically. What is your CPU model? Though probably it meets the requirements for swrAVX2 otherwise we wouldn't have this very different behavior.

human-0 commented 5 years ago

I'm running Intel Skylake (6th gen). I'm pretty sure it doesn't work on Haswell (4th gen) either.

pal1000 commented 5 years ago

Haswell is minimum for swrAVX2 so on both systems you mentioned it uses swrAVX2 by default unless swrAVX2 is removed or renamed to force fallback to swrAVX. In any case you clearly need advanced support from upstream community.

In my case beside that error message I mentioned, it looks like swrtest.exe crashes in Mesa3D opengl32.dll during load of swrAVX.dll according Windows Reliability Monitor.

pal1000 commented 5 years ago

Upstream bug report: https://bugs.freedesktop.org/show_bug.cgi?id=110468