Bug 105807

Summary: [Regression, bisected]: 3D Rendering not working correctly in Warhammer 40k: Dawn of War II
Product: Mesa Reporter: ben <ben>
Component: Mesa coreAssignee: mesa-dev
Status: RESOLVED FIXED QA Contact: mesa-dev
Severity: normal    
Priority: medium CC: asmith, maraeo
Version: git   
Hardware: x86-64 (AMD64)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:
Attachments: Incorrect 3D rendering (black/white shadows)
Ingame Image

Description ben@besd.de 2018-03-29 12:42:54 UTC
Created attachment 138418 [details]
Incorrect 3D rendering (black/white shadows)

Hi all,

rendering in Warhammer 40k: Dawn of War II breaks with the commit below.
In the menu only black and white shadows appear instead of 3d figure (see screenshot). In the game no 3d objects are visible only colorful shadows.

Works fine with 17.3.7.


a0c8b49284efe736849c0a45920ad0a1bbd8d93d is the first bad commit
commit a0c8b49284efe736849c0a45920ad0a1bbd8d93d
Author: Marek Olšák <marek.olsak@amd.com>
Date:   Wed Feb 14 20:13:40 2018 +0100

    mesa: enable OpenGL 3.1 with ARB_compatibility
    
    Tested-by: Dieter Nützel <Dieter@nuetzel-hh.de>
    Reviewed-by: Brian Paul <brianp@vmware.com>

:040000 040000 e77355f4d5979f42b5e8f55dd6c6ea62cba32ff3 24f0fe1b3e5f9d1daa801a706299f0115f9d8f2d M	docs
:040000 040000 89d6cc6fe13b05f4625fb48abbb94050f0cb5c96 3b91e5c0091caf1426b09568846f8f2b3bc64803 M	src
'bisect run' erfolgreich ausgeführt
Comment 1 ben@besd.de 2018-03-29 12:43:29 UTC
Created attachment 138419 [details]
Ingame Image
Comment 2 Timothy Arceri 2018-04-10 07:14:25 UTC
Works correctly in radeonsi doesn't work in i965. Probably requires more restrictions when 3.1 compant not available. Moving to i965 where it's less likely to get forgotten about.
Comment 3 Timothy Arceri 2018-04-10 11:14:38 UTC
Ok, it seems the problem is due to a mismatch in OpenGL version vs GLSL version. After the bisected commit i965 started reporting:

OpenGL version string: 3.0 Mesa 18.1.0-devel (git-7fe586f6fb)
OpenGL shading language version string: 1.40

Rather than:

OpenGL version string: 3.0 Mesa 18.1.0-devel (git-7fe586f6fb)
OpenGL shading language version string: 1.30

I'll see if I can come up with a patch.
Comment 4 Timothy Arceri 2018-04-10 11:42:01 UTC
Thanks for the bug report.

Fix sent to list:

https://patchwork.freedesktop.org/patch/216148/
Comment 5 ben@besd.de 2018-04-10 13:50:36 UTC
Hi Timothy, 
I think you're on the right track but radeonsi git also (still) doesnt work as of just now.

I get

glXCreateContextAttribsARB(dpy = 0x45623f0, config = 0x46f4a70, share_context = NULL, direct = True, attrib_list = {GLX_CONTEXT_MAJOR_VERSION_ARB, 4, GLX_CONTEXT_MINOR_VERSION_ARB, 5, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, GLX_NO_RESET_NOTIFICATION_ARB, 0}) = 0x4723d10

from the game. It shows the bug.
I dont know how to spot the GLSL version, any pointers?

If I do force the GL version to something like 3.0, 3.1 or 3.1COMPAT or
force MESA_GLSL_VERSION_OVERRIDE=130
I get this 

1187 glXCreateContextAttribsARB(dpy = 0x52213f0, config = 0x53b3a70, share_context = NULL, direct = True, attrib_list = {GLX_CONTEXT_MAJOR_VERSION_ARB, 4, GLX_CONTEXT_MINOR_VERSION_ARB, 5, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, GLX_NO_RESET_NOTIFICATION_ARB, 0}) = NULL
1189 glXCreateContextAttribsARB(dpy = 0x52213f0, config = 0x53b3a70, share_context = NULL, direct = True, attrib_list = {GLX_CONTEXT_MAJOR_VERSION_ARB, 4, GLX_CONTEXT_MINOR_VERSION_ARB, 4, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, GLX_NO_RESET_NOTIFICATION_ARB, 0}) = NULL
1191 glXCreateContextAttribsARB(dpy = 0x52213f0, config = 0x53b3a70, share_context = NULL, direct = True, attrib_list = {GLX_CONTEXT_MAJOR_VERSION_ARB, 4, GLX_CONTEXT_MINOR_VERSION_ARB, 3, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, GLX_NO_RESET_NOTIFICATION_ARB, 0}) = NULL
1193 glXCreateContextAttribsARB(dpy = 0x52213f0, config = 0x53b3a70, share_context = NULL, direct = True, attrib_list = {GLX_CONTEXT_MAJOR_VERSION_ARB, 4, GLX_CONTEXT_MINOR_VERSION_ARB, 2, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, GLX_NO_RESET_NOTIFICATION_ARB, 0}) = NULL
1195 glXCreateContextAttribsARB(dpy = 0x52213f0, config = 0x53b3a70, share_context = NULL, direct = True, attrib_list = {GLX_CONTEXT_MAJOR_VERSION_ARB, 4, GLX_CONTEXT_MINOR_VERSION_ARB, 1, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, GLX_NO_RESET_NOTIFICATION_ARB, 0}) = NULL
1197 glXCreateContextAttribsARB(dpy = 0x52213f0, config = 0x53b3a70, share_context = NULL, direct = True, attrib_list = {GLX_CONTEXT_MAJOR_VERSION_ARB, 4, GLX_CONTEXT_MINOR_VERSION_ARB, 0, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, GLX_NO_RESET_NOTIFICATION_ARB, 0}) = NULL
1199 glXCreateContextAttribsARB(dpy = 0x52213f0, config = 0x53b3a70, share_context = NULL, direct = True, attrib_list = {GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 3, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, GLX_NO_RESET_NOTIFICATION_ARB, 0}) = NULL
1201 glXCreateContextAttribsARB(dpy = 0x52213f0, config = 0x53b3a70, share_context = NULL, direct = True, attrib_list = {GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 2, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, GLX_NO_RESET_NOTIFICATION_ARB, 0}) = NULL
1203 glXCreateContextAttribsARB(dpy = 0x52213f0, config = 0x53b3a70, share_context = NULL, direct = True, attrib_list = {GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 1, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, GLX_NO_RESET_NOTIFICATION_ARB, 0}) = 0x554b1f0

(forcing FC seems to screw up the loader). And then the game works.
Comment 6 ben@besd.de 2018-04-10 14:11:29 UTC
I've uploaded traces
https://github.com/bendat78/mymesa/tree/mymesa2/testresults/dow2/xz
Comment 7 Alan Swanson 2018-04-10 14:23:49 UTC
Just to confirm with Ben, this very definitely affects radeonsi not just i965. Forcing MESA_GLSL_VERSION_OVERRIDE=130 resolves issue so perhaps a game issue with GLSL 1.4?
Comment 8 ben@besd.de 2018-04-10 14:43:57 UTC
These are from shaderdumps (good thing I have the sha naming in place otherwise these would have been overwritten ;)

When GLSL is not forced

[require]
GLSL >= 0.00 // this is generated by OpenGL so maybe something is going on there

[fragment shader]
#version 140
#extension GL_ARB_explicit_attrib_location : enable

When forcing GLSL 1.3

[require]
GLSL >= 1.30

[vertex shader]
#version 130
#extension GL_ARB_explicit_attrib_location : enable
Comment 9 Timothy Arceri 2018-04-10 20:57:14 UTC
(In reply to Alan Swanson from comment #7)
> Just to confirm with Ben, this very definitely affects radeonsi not just
> i965. Forcing MESA_GLSL_VERSION_OVERRIDE=130 resolves issue so perhaps a
> game issue with GLSL 1.4?

What version of Mesa are you guys testing with? Are you testing with git master?
Comment 10 Timothy Arceri 2018-04-10 22:09:22 UTC
(In reply to Timothy Arceri from comment #9)
> (In reply to Alan Swanson from comment #7)
> > Just to confirm with Ben, this very definitely affects radeonsi not just
> > i965. Forcing MESA_GLSL_VERSION_OVERRIDE=130 resolves issue so perhaps a
> > game issue with GLSL 1.4?
> 
> What version of Mesa are you guys testing with? Are you testing with git
> master?

Nevermind this was my mistake I was testing with 18.0 on radeonsi which I thought had the enable OpenGL 3.1 patch but seem it doesn't. I've pushed my patch so this issue should now be fixed in drivers other than radeonsi.
Comment 11 ben@besd.de 2018-04-11 18:56:48 UTC
I think this function is the problem:

/**
 * Return the string for a glGetString(GL_SHADING_LANGUAGE_VERSION) query.
 */
static const GLubyte *
shading_language_version(struct gl_context *ctx)
{
   switch (ctx->API) {
   case API_OPENGL_COMPAT:
   case API_OPENGL_CORE:
      switch (ctx->Const.GLSLVersion) {
      case 120:
         return (const GLubyte *) "1.20";
      case 130:
         return (const GLubyte *) "1.30";
      case 140:
         return (const GLubyte *) "1.40";
      case 150:
         return (const GLubyte *) "1.50";
      case 330:
         return (const GLubyte *) "3.30";
      case 400:
         return (const GLubyte *) "4.00";
      case 410:
         return (const GLubyte *) "4.10";
      case 420:
         return (const GLubyte *) "4.20";
      case 430:
         return (const GLubyte *) "4.30";
      case 440:
         return (const GLubyte *) "4.40";
      case 450:
         return (const GLubyte *) "4.50";
      case 460:
         return (const GLubyte *) "4.60";
      default:
         _mesa_problem(ctx,
                       "Invalid GLSL version in shading_language_version()");
         return (const GLubyte *) 0;
      }
      break;

   case API_OPENGLES2:
      switch (ctx->Version) {
      case 20:
         return (const GLubyte *) "OpenGL ES GLSL ES 1.0.16";
      case 30:
         return (const GLubyte *) "OpenGL ES GLSL ES 3.00";
      case 31:
         return (const GLubyte *) "OpenGL ES GLSL ES 3.10";
      case 32:
         return (const GLubyte *) "OpenGL ES GLSL ES 3.20";
      default:
         _mesa_problem(ctx,
                       "Invalid OpenGL ES version in shading_language_version()");
         return (const GLubyte *) 0;
      }
   case API_OPENGLES:
      /* fall-through */

   default:
      _mesa_problem(ctx, "Unexpected API value in shading_language_version()");
      return (const GLubyte *) 0;
   }
}
Comment 12 ben@besd.de 2018-04-11 18:58:16 UTC
OpenGL core spec 4.5 page 4 specifies:

"The core profile of OpenGL 4.5 is also guaranteed to support all previous ver-
sions of the OpenGL Shading Language back to version  1.40. In some implemen-
tations the core profile may also support earlier versions of the OpenGL Shading
Language, and may support compatibility profile versions of the OpenGL Shading
Language for versions 1.40 and earlier. In this case, errors will be generated when
using language features such as compatibility profile built-ins not supported by the
core profile API.  The #version strings for all supported versions of the OpenGL
Shading Language may be queried as described in section 22.2."

But I think the above version returns 0 in cases where you request a glsl version that is lower and not a list of supported glsl versions like the function below:
Comment 13 ben@besd.de 2018-04-11 19:00:09 UTC
from mesa/main/version.c: (the one above is getstring.c)


int
_mesa_get_shading_language_version(const struct gl_context *ctx,
                                   int index,
                                   char **versionOut)
{
   int n = 0;

#define GLSL_VERSION(S) \
   if (n++ == index) \
      *versionOut = S

   /* GLSL core */
   if (ctx->Const.GLSLVersion >= 460)
      GLSL_VERSION("460");
   if (ctx->Const.GLSLVersion >= 450)
      GLSL_VERSION("450");
   if (ctx->Const.GLSLVersion >= 440)
      GLSL_VERSION("440");
   if (ctx->Const.GLSLVersion >= 430)
      GLSL_VERSION("430");
   if (ctx->Const.GLSLVersion >= 420)
      GLSL_VERSION("420");
   if (ctx->Const.GLSLVersion >= 410)
      GLSL_VERSION("410");
   if (ctx->Const.GLSLVersion >= 400)
      GLSL_VERSION("400");
   if (ctx->Const.GLSLVersion >= 330)
      GLSL_VERSION("330");
   if (ctx->Const.GLSLVersion >= 150)
      GLSL_VERSION("150");
   if (ctx->Const.GLSLVersion >= 140)
      GLSL_VERSION("140");
   if (ctx->Const.GLSLVersion >= 130)
      GLSL_VERSION("130");
   if (ctx->Const.GLSLVersion >= 120)
      GLSL_VERSION("120");
   /* The GL spec says to return the empty string for GLSL 1.10 */
   if (ctx->Const.GLSLVersion >= 110)
      GLSL_VERSION("");

   /* GLSL es */
   if ((ctx->API == API_OPENGLES2 && ctx->Version >= 32) ||
        ctx->Extensions.ARB_ES3_2_compatibility)
      GLSL_VERSION("320 es");
   if (_mesa_is_gles31(ctx) || ctx->Extensions.ARB_ES3_1_compatibility)
      GLSL_VERSION("310 es");
   if (_mesa_is_gles3(ctx) || ctx->Extensions.ARB_ES3_compatibility)
      GLSL_VERSION("300 es");
   if (ctx->API == API_OPENGLES2 || ctx->Extensions.ARB_ES2_compatibility)
      GLSL_VERSION("100");

#undef GLSL_VERSION

   return n;
}
Comment 14 ben@besd.de 2018-04-11 19:02:03 UTC
That would explain why a program gets a zero in return when requesting a shader language lower than the one hardcoded in comment 11. Which is exactly what happen in comment 8.

Or at least that seems reasonable doesnt it?
Comment 15 ben@besd.de 2018-04-11 20:08:40 UTC
I'm probably too tired, but this should work I think except it doesnt.


// Little test program to dump supported shader versions

// compiled like this
// gcc test.c -I/usr/include/GL/ -L/usr/lib/x86_64-linux-gnu -lglut -lGLU -lGL -lGLEW -o test

#include "glew.h"
#include "glut.h"
#include <GL/glcorearb.h>
#include <stdio.h>

int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutCreateWindow("GLUT");
    glewInit();

    printf("OpenGL version supported by this platform (%s): \n",
           glGetString(GL_VERSION));

    int num_glsls = 0;
    glGetIntegerv(GL_NUM_SHADING_LANGUAGE_VERSIONS, &num_glsls); 
// supposed to be at least 3 according to page 617 of the OpenGL 4.5 core spec
// currently seems to be 0
    printf("GLSL versions supported by this platform: %d", num_glsls);

// this doesnt do anything even though it should
    for (int i = 0; i++; i < num_glsls) {
       printf("OpenGLSL versions supported by this platform (%s): \n",
              glGetStringi(GL_SHADING_LANGUAGE_VERSION, 0));
    }
}
Comment 16 Timothy Arceri 2018-04-11 23:50:21 UTC
Ok so I found the problem. We didn't support compat shaders on GLSL 1.40 only on GLSL versions higher and lower.

I think the Version == 0 might be a separate issue as per comment 15 and it would be great if you could create a piglit test for that. I'll need to write a piglit test for this GLSL 1.40 compat shaders bug too.

Fix:
https://patchwork.freedesktop.org/patch/216621/
Comment 17 Timothy Arceri 2018-04-12 01:54:05 UTC
Thanks again for the report and for bisecting.

Fixed by:

commit c7e3d31b0b5f22299a6bd72655502ce8427b40bf
Author: Timothy Arceri <tarceri@itsqueeze.com>
Date:   Thu Apr 12 09:23:02 2018 +1000

    glsl: fix compat shaders in GLSL 1.40
    
    The compatibility and core tokens were not added until GLSL 1.50,
    for GLSL 1.40 just assume all shaders built with a compat profile
    are compat shaders.
    
    Fixes rendering issues in Dawn of War II on radeonsi which has
    enabled OpenGL 3.1 compat support.
    
    Fixes: a0c8b49284ef "mesa: enable OpenGL 3.1 with ARB_compatibility"
    
    Reviewed-by: Marek Olšák <marek.olsak@amd.com>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105807
Comment 18 ben@besd.de 2018-04-12 05:38:49 UTC
Just confirmed that it works now.

Thanks!

Maybe this should be in stable too?
Comment 19 Timothy Arceri 2018-04-12 07:41:25 UTC
(In reply to ben@besd.de from comment #18)
> Just confirmed that it works now.
> 
> Thanks!
> 
> Maybe this should be in stable too?

Fixes: a0c8b49284ef "mesa: enable OpenGL 3.1 with ARB_compatibility"

Means it will automatically get picked up by the stable scripts for inclusion into any stable release that contains that commit.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.