Open human-0 opened 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.
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;
}
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.
That is very strange. I didn't get that error. Maybe try using per app deployment (which I was using).
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.
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). This is the rendering at 720p. It should just be a green rectangle but there are very obvious problems with it.
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.
What about swrAVX2 not working at all?
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.
I'm running Intel Skylake (6th gen). I'm pretty sure it doesn't work on Haswell (4th gen) either.
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.
Upstream bug report: https://bugs.freedesktop.org/show_bug.cgi?id=110468
Using the SWR drivers (
GALLIUM_DRIVER=swr
) results in a completely black screen. The code:glGetError()
MESA_GL_VERSION_OVERRIDE
andMESA_GLSL_VERION_OVERRIDE
Why do these not work?