Bug 80115

Summary: MESA_META_DRAW_BUFFERS induced GL_INVALID_VALUE errors
Product: Mesa Reporter: jpsinthemix
Component: Mesa coreAssignee: Ian Romanick <idr>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: medium CC: kenneth
Version: 10.2   
Hardware: x86 (IA32)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:

Description jpsinthemix 2014-06-17 00:57:41 UTC
Hi,

After upgrading to mesa-10.2.1, I began to see a lot of GL_INVALID_VALUE errors under kde, eg,

kwin(982) KWin::checkGLError: GL error ( PostPaint ):  "GL_INVALID_VALUE"

With mesa-10.1.5, no such errors occur. Modifying a MESA_DEBUG message in mesa-10.2.1/src/mesa/main/buffers.c:_mesa_DrawBuffers():303 to print actual values, gives

Mesa: User error: GL_INVALID_VALUE in glDrawBuffersARB(n: 8 Const.MaxDrawBuffers: 1)
kwin(908) KWin::checkGLError: GL error ( update texture ):  "GL_INVALID_VALUE"

It turns out that the problem appears in the mesa-10.2.1-rc1 -> mesa-10.2.1-rc2, transition, with this set of commits:

2014-05-07 meta: Only clear the requested color buffers.                        Kenneth Graunke 1 -2/+49
2014-05-07 meta: Add infrastructure for saving/restoring the DrawBuffers state. Kenneth Graunke 2 -0/+42
2014-05-07 meta: Add a new MESA_META_DRAW_BUFFERS bit.                          Kenneth Graunke 4 -4/+6


I have a bunch of laptops, mostly kinda old, and several have radeon graphics controllers, eg, RV200/M7 [Mobility Radeon 7500]. It turns out that the MESA_META_DRAW_BUFFERS commit (specifically, the "Add infrastructure for saving/restoring .." commit) uses MAX_DRAW_BUFFERS, and passes this value to _mesa_DrawBuffers():

diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
index 36150a5..7c84c33 100644
--- a/src/mesa/drivers/common/meta.c
+++ b/src/mesa/drivers/common/meta.c
@@ -1176,6 +1211,10 @@ _mesa_meta_end(struct gl_context *ctx)
        ctx->CurrentRenderbuffer->Name != save->RenderbufferName)
       _mesa_BindRenderbuffer(GL_RENDERBUFFER, save->RenderbufferName);

+   if (state & MESA_META_DRAW_BUFFERS) {
+      _mesa_DrawBuffers(MAX_DRAW_BUFFERS, save->ColorDrawBuffers);
+   }
+
    ctx->Meta->SaveStackDepth--;


Then, in mesa-10.2.1/src/mesa/main/buffers.c:_mesa_DrawBuffers():303, we have

315     * From the OpenGL 3.0 specification, page 258:
316     * "An INVALID_VALUE error is generated if n is greater than
317     *  MAX_DRAW_BUFFERS."
318     */
319    if (n < 0 || n > (GLsizei) ctx->Const.MaxDrawBuffers) {
320       _mesa_error(ctx, GL_INVALID_VALUE, "glDrawBuffersARB(n)");
321       return;
322    }

For the radeon case, ctx->Const.MaxDrawBuffers = 1, while MAX_DRAW_BUFFERS = 8, hence the error.


As a quick "fix" to have mesa-10.2.1 usable for radeon controllers, I use a simple patch:

---
Attempting to draw MAX_DRAW_BUFFERS here results in many INVALID_VALUE errors
in _mesa_DrawBuffers(), at least for [AMD/ATI] RV200/M7 [Mobility Radeon 7500]
chips (Radeon driver) where ctx->Const.MaxDrawBuffers=1 is less than MAX_DRAW_BUFFERS.

Do not try to draw more saved color buffers than we actually have saved.

diff -Npur mesa-10.2.1.old/src/mesa/drivers/common/meta.c mesa-10.2.1.new/src/mesa/drivers/common/meta.c
--- mesa-10.2.1.old/src/mesa/drivers/common/meta.c      2014-05-30 18:09:47.000000000 -0400
+++ mesa-10.2.1.new/src/mesa/drivers/common/meta.c      2014-06-16 19:57:14.505961190 -0400
@@ -1213,7 +1213,10 @@ _mesa_meta_end(struct gl_context *ctx)
       _mesa_BindRenderbuffer(GL_RENDERBUFFER, save->RenderbufferName);

    if (state & MESA_META_DRAW_BUFFERS) {
-      _mesa_DrawBuffers(MAX_DRAW_BUFFERS, save->ColorDrawBuffers);
+      int c = 0;
+      while (save->ColorDrawBuffers[c] && c < sizeof(save->ColorDrawBuffers))
+          ++c;
+      _mesa_DrawBuffers(c, save->ColorDrawBuffers);
    }

    ctx->Meta->SaveStackDepth--;
---

As long as memset() is used (mesa-10.2.1/src/mesa/drivers/common/meta.c:_mesa_meta_begin():796):

802       memset(save->ColorDrawBuffers, 0, sizeof(save->ColorDrawBuffers));

this appears to be safe, however, maybe it would be more efficient to save the actual number of saved buffers (real_color_buffers in meta.c) in a new parameter under ctx?

thanks much for your time, and the great software,
John
john@juluka: ~
$ cat 00-mesa-10.2.1-GL_INVALID_VALUE.br
Hi,

After upgrading to mesa-10.2.1, I began to see a lot of GL_INVALID_VALUE errors under kde, eg,

kwin(982) KWin::checkGLError: GL error ( PostPaint ):  "GL_INVALID_VALUE"

With mesa-10.1.5, no such errors occur. Modifying a MESA_DEBUG message in mesa-10.2.1/src/mesa/main/buffers.c:_mesa_DrawBuffers():303 to print actual values, gives

Mesa: User error: GL_INVALID_VALUE in glDrawBuffersARB(n: 8 Const.MaxDrawBuffers: 1)
kwin(908) KWin::checkGLError: GL error ( update texture ):  "GL_INVALID_VALUE"

It turns out that the problem appears in the mesa-10.2.1-rc1 -> mesa-10.2.1-rc2, transition, with this set of commits:

2014-05-07 meta: Only clear the requested color buffers.                        Kenneth Graunke 1 -2/+49
2014-05-07 meta: Add infrastructure for saving/restoring the DrawBuffers state. Kenneth Graunke 2 -0/+42
2014-05-07 meta: Add a new MESA_META_DRAW_BUFFERS bit.                          Kenneth Graunke 4 -4/+6


I have a bunch of laptops, mostly kinda old, and several have radeon graphics controllers, eg, RV200/M7 [Mobility Radeon 7500]. It turns out that the MESA_META_DRAW_BUFFERS commit (specifically, the "Add infrastructure for saving/restoring .." commit) uses MAX_DRAW_BUFFERS, and passes this value to _mesa_DrawBuffers():

diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
index 36150a5..7c84c33 100644
--- a/src/mesa/drivers/common/meta.c
+++ b/src/mesa/drivers/common/meta.c
@@ -1176,6 +1211,10 @@ _mesa_meta_end(struct gl_context *ctx)
        ctx->CurrentRenderbuffer->Name != save->RenderbufferName)
       _mesa_BindRenderbuffer(GL_RENDERBUFFER, save->RenderbufferName);

+   if (state & MESA_META_DRAW_BUFFERS) {
+      _mesa_DrawBuffers(MAX_DRAW_BUFFERS, save->ColorDrawBuffers);
+   }
+
    ctx->Meta->SaveStackDepth--;


Then, in mesa-10.2.1/src/mesa/main/buffers.c:_mesa_DrawBuffers():303, we have

315     * From the OpenGL 3.0 specification, page 258:
316     * "An INVALID_VALUE error is generated if n is greater than
317     *  MAX_DRAW_BUFFERS."
318     */
319    if (n < 0 || n > (GLsizei) ctx->Const.MaxDrawBuffers) {
320       _mesa_error(ctx, GL_INVALID_VALUE, "glDrawBuffersARB(n)");
321       return;
322    }

For the radeon case, ctx->Const.MaxDrawBuffers = 1, while MAX_DRAW_BUFFERS = 8, hence the error.


As a quick "fix" to have mesa-10.2.1 usable for radeon controllers, I use a simple patch:

---
Attempting to draw MAX_DRAW_BUFFERS here results in many INVALID_VALUE errors
in _mesa_DrawBuffers(), at least for [AMD/ATI] RV200/M7 [Mobility Radeon 7500]
chips (Radeon driver) where ctx->Const.MaxDrawBuffers=1 is less than MAX_DRAW_BUFFERS.

Do not try to draw more saved color buffers than we actually have saved.

diff -Npur mesa-10.2.1.old/src/mesa/drivers/common/meta.c mesa-10.2.1.new/src/mesa/drivers/common/meta.c
--- mesa-10.2.1.old/src/mesa/drivers/common/meta.c      2014-05-30 18:09:47.000000000 -0400
+++ mesa-10.2.1.new/src/mesa/drivers/common/meta.c      2014-06-16 19:57:14.505961190 -0400
@@ -1213,7 +1213,10 @@ _mesa_meta_end(struct gl_context *ctx)
       _mesa_BindRenderbuffer(GL_RENDERBUFFER, save->RenderbufferName);

    if (state & MESA_META_DRAW_BUFFERS) {
-      _mesa_DrawBuffers(MAX_DRAW_BUFFERS, save->ColorDrawBuffers);
+      int c = 0;
+      while (save->ColorDrawBuffers[c] && c < sizeof(save->ColorDrawBuffers))
+          ++c;
+      _mesa_DrawBuffers(c, save->ColorDrawBuffers);
    }

    ctx->Meta->SaveStackDepth--;
---

As long as memset() is used (mesa-10.2.1/src/mesa/drivers/common/meta.c:_mesa_meta_begin():796):

802       memset(save->ColorDrawBuffers, 0, sizeof(save->ColorDrawBuffers));

this appears to be safe, however, maybe it would be more efficient to save the actual number of saved buffers (real_color_buffers in meta.c) in a new parameter under ctx?

thanks much for your time, and the great software,
John
Comment 1 jpsinthemix 2014-06-17 01:04:45 UTC
oops, pasted in description twice; sorry about that..
Comment 2 luigi 2014-06-17 13:45:23 UTC
hi.i set environment vars like:

MESA_DEBUG=1  LIBGL_DEBUG=verbose

i cannot see any libgl error in my kwin.log [1]  for mesa-10.2.1

But this was slightly happen to me:

 https://bugs.freedesktop.org/show_bug.cgi?id=80069

Also its interesting to see this line into xorg.log [2]:

[     5.547] removing GPU device /sys/devices/pci0000:00/0000:00:02.0/drm/card0 /dev/dri/card0
[     5.547] xf86: remove device 0 /sys/devices/pci0000:00/0000:00:02.0/drm/card0
[     5.547] failed to find screen to remove

[1]  http://pastebin.com/qhRk2DTy
[2]  http://pastebin.com/ezX04Gzc
Comment 3 jpsinthemix 2014-06-17 18:09:37 UTC
(In reply to comment #2)
> hi.i set environment vars like:
> 
> MESA_DEBUG=1  LIBGL_DEBUG=verbose
> 
> i cannot see any libgl error in my kwin.log [1]  for mesa-10.2.1
> 
> But this was slightly happen to me:
> 
>  https://bugs.freedesktop.org/show_bug.cgi?id=80069
> 
> Also its interesting to see this line into xorg.log [2]:
> 
> [     5.547] removing GPU device
> /sys/devices/pci0000:00/0000:00:02.0/drm/card0 /dev/dri/card0
> [     5.547] xf86: remove device 0
> /sys/devices/pci0000:00/0000:00:02.0/drm/card0
> [     5.547] failed to find screen to remove
> 
> [1]  http://pastebin.com/qhRk2DTy
> [2]  http://pastebin.com/ezX04Gzc

If you set MESA_DEBUG=1 and you do not see this:

Mesa: User error: GL_INVALID_VALUE in glDrawBuffersARB(n)

in ~/.xsession-errors, then your problem is probably different from this one.
Comment 4 Ian Romanick 2014-06-17 18:19:17 UTC
Patch sent to the mesa-dev mailing list:

http://lists.freedesktop.org/archives/mesa-dev/2014-June/061633.html

This should fix the problem.  Please test and let me know the results.

Thanks.
Comment 5 jpsinthemix 2014-06-17 22:49:50 UTC
(In reply to comment #4)
> Patch sent to the mesa-dev mailing list:
> 
> http://lists.freedesktop.org/archives/mesa-dev/2014-June/061633.html
> 
> This should fix the problem.  Please test and let me know the results.
> 
> Thanks.

Looks good; thanks much
Comment 6 Ian Romanick 2014-06-18 21:47:57 UTC
Fixed on master by the following commit.  This should get picked to the 10.2 branch soon, and it should be in 10.2.2.

commit cc219d1d6567cfada5d8e9adf01c2f00e00c93ca
Author: Ian Romanick <ian.d.romanick@intel.com>
Date:   Tue Jun 17 11:14:17 2014 -0700

    meta: Respect the driver's maximum number of draw buffers
    
    Commit c1c1cf5f9 added infrastructure for saving and restoring draw
    buffer state.  However, it universially used MAX_DRAW_BUFFERS, but many
    drivers support far fewer than that at limit.  For example, the radeon
    and i915 drivers only support 1.  Using MAX_DRAW_BUFFERS causes meta to
    generate GL errors.
    
    Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=80115
    Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
    Tested-by: Kenneth Graunke <kenneth@whitecape.org> [on Broadwell]
    Tested-by: jpsinthemix@verizon.net
    Cc: "10.2" <mesa-stable@lists.freedesktop.org>

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.