Bug 89622

Summary: Drivers/Gallium/swrast: Pixel image limited to GL_MAX_TEXTURE_SIZE
Product: Mesa Reporter: Dan Sebald <daniel.sebald>
Component: Drivers/Gallium/llvmpipeAssignee: mesa-dev
Status: RESOLVED MOVED QA Contact: mesa-dev
Severity: normal    
Priority: medium CC: daniel.sebald
Version: git   
Hardware: Other   
OS: All   
Whiteboard:
i915 platform: i915 features:
Attachments: Clipping in the x-dimension
Clipping in the y-dimension
Fixed image in x-dimension
Fixed image in y-dimension

Description Dan Sebald 2015-03-18 02:25:22 UTC
First, I want to point out that building Mesa from scratch *without* the options

--with-dri-drivers=nouveau --with-gallium-drivers=nouveau

produces no nouveau_dri.so library file.  There is a nouveau_vieux_dri.so, but no nouveau_dri.so.  When I then run an app that accesses this newly built mesa library files I see the warning message:

libGL error: unable to load driver: nouveau_dri.so
libGL error: driver pointer missing
libGL error: failed to load driver: nouveau

It's no harm of course, but if this should not be happening--given nourveau_dri.so--wasn't built, I'll file a bug report.

OK, I filed a bug report about vertical white lines in the legacy swrast_dri.so associated with intervals of GL_MAX_TEXTURE_SIZE in the x dimension of the input image:

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

I then went to try the newer Gallium version of the software implementation and found that a limitation is placed on the size of the input image to GL_MAX_TEXTURE_SIZE.  This can be seen in frame buffer images I will attach, Screenshot-incomplete_image_x-dimension.png and Screenshot-incomplete_image_y-dimension.png where only a portion of the gradient image appears.  The source of this limitation is in src/mesa/state_tracker/st_cb_drawpixels.c.  Out of curiousity, I removed the limitation as follows:

--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -1110,14 +1110,6 @@ st_DrawPixels(struct gl_context *ctx, GLint x, GLint y,
 
    st_validate_state(st);
 
-   /* Limit the size of the glDrawPixels to the max texture size.
-    * Strictly speaking, that's not correct but since we don't handle
-    * larger images yet, this is better than crashing.
-    */
-   clippedUnpack = *unpack;
-   unpack = &clippedUnpack;
-   clamp_size(st->pipe, &width, &height, &clippedUnpack);
-
    if (format == GL_DEPTH_STENCIL)
       write_stencil = write_depth = GL_TRUE;
    else if (format == GL_STENCIL_INDEX)

and the result is that the image comes out fine.

So, what is the problem here?  Is it that not all systems are ensured to have non-paged memory, and my system just happens to have it?  Can this be tested and adjusted accordingly?  More generally, it seems that the Gallium version of pixel zoom/draw can be done in a more straightforward way than legacy swrast is doing.  Notice that Gallium is treating the image as blocks (i.e., the clip affects both width and height).  It shouldn't be difficult to write a double loop to write to the frame buffer in blocks (unless there is a problem of not being able to select the memory page in the st_DrawPixels() routine because that is done prior to the function call).  What role does the st->pipe play in affecting size of writes?
Comment 1 Dan Sebald 2015-03-18 02:26:43 UTC
Created attachment 114408 [details]
Clipping in the x-dimension
Comment 2 Dan Sebald 2015-03-18 02:27:21 UTC
Created attachment 114409 [details]
Clipping in the y-dimension
Comment 3 Dan Sebald 2015-03-18 02:27:59 UTC
Created attachment 114410 [details]
Fixed image in x-dimension
Comment 4 Dan Sebald 2015-03-18 02:28:49 UTC
Created attachment 114411 [details]
Fixed image in y-dimension
Comment 5 Ilia Mirkin 2015-03-18 02:48:53 UTC
(In reply to Dan Sebald from comment #0)
> First, I want to point out that building Mesa from scratch *without* the
> options
> 
> --with-dri-drivers=nouveau --with-gallium-drivers=nouveau
> 
> produces no nouveau_dri.so library file.  There is a nouveau_vieux_dri.so,
> but no nouveau_dri.so.  When I then run an app that accesses this newly
> built mesa library files I see the warning message:
> 
> libGL error: unable to load driver: nouveau_dri.so
> libGL error: driver pointer missing
> libGL error: failed to load driver: nouveau
> 
> It's no harm of course, but if this should not be happening--given
> nourveau_dri.so--wasn't built, I'll file a bug report.

libGL has no idea what's built. It's told by your X server (via DRI2) that it should look for a DRI driver called "nouveau", so it looks for "nouveau_dri.so".

> OK, I filed a bug report about vertical white lines in the legacy
> swrast_dri.so associated with intervals of GL_MAX_TEXTURE_SIZE in the x
> dimension of the input image:
> 
> https://bugs.freedesktop.org/show_bug.cgi?id=89586
> 
> I then went to try the newer Gallium version of the software implementation
> and found that a limitation is placed on the size of the input image to
> GL_MAX_TEXTURE_SIZE.  This can be seen in frame buffer images I will attach,
> Screenshot-incomplete_image_x-dimension.png and
> Screenshot-incomplete_image_y-dimension.png where only a portion of the
> gradient image appears.  The source of this limitation is in
> src/mesa/state_tracker/st_cb_drawpixels.c.  Out of curiousity, I removed the
> limitation as follows:
> 
> --- a/src/mesa/state_tracker/st_cb_drawpixels.c
> +++ b/src/mesa/state_tracker/st_cb_drawpixels.c
> @@ -1110,14 +1110,6 @@ st_DrawPixels(struct gl_context *ctx, GLint x, GLint
> y,
>  
>     st_validate_state(st);
>  
> -   /* Limit the size of the glDrawPixels to the max texture size.
> -    * Strictly speaking, that's not correct but since we don't handle
> -    * larger images yet, this is better than crashing.
> -    */
> -   clippedUnpack = *unpack;
> -   unpack = &clippedUnpack;
> -   clamp_size(st->pipe, &width, &height, &clippedUnpack);
> -
>     if (format == GL_DEPTH_STENCIL)
>        write_stencil = write_depth = GL_TRUE;
>     else if (format == GL_STENCIL_INDEX)
> 
> and the result is that the image comes out fine.
> 
> So, what is the problem here?  Is it that not all systems are ensured to
> have non-paged memory, and my system just happens to have it?  Can this be
> tested and adjusted accordingly?  More generally, it seems that the Gallium
> version of pixel zoom/draw can be done in a more straightforward way than
> legacy swrast is doing.  Notice that Gallium is treating the image as blocks
> (i.e., the clip affects both width and height).  It shouldn't be difficult
> to write a double loop to write to the frame buffer in blocks (unless there
> is a problem of not being able to select the memory page in the
> st_DrawPixels() routine because that is done prior to the function call). 
> What role does the st->pipe play in affecting size of writes?

For those of us still getting with the program... let's say that max_texture_size = 128 (for simplicity). Is the situation that you have a (say) 256-pixel wide image that you're feeding to glDrawPixels to be put onto a 128-wide texture, and you're using glPixelZoom(0.5) to achieve this?
Comment 6 Dan Sebald 2015-03-18 03:31:27 UTC
Correct.  -1 < xfactor < 1, excluding 0.
Comment 7 Dan Sebald 2015-03-18 03:33:19 UTC
Oh, and attempting to load suitable driver first is fair.
Comment 8 Ilia Mirkin 2015-03-18 03:47:08 UTC
(In reply to Dan Sebald from comment #0)
> So, what is the problem here?  Is it that not all systems are ensured to
> have non-paged memory, and my system just happens to have it?  Can this be
> tested and adjusted accordingly?  More generally, it seems that the Gallium
> version of pixel zoom/draw can be done in a more straightforward way than
> legacy swrast is doing.  Notice that Gallium is treating the image as blocks
> (i.e., the clip affects both width and height).  It shouldn't be difficult
> to write a double loop to write to the frame buffer in blocks (unless there
> is a problem of not being able to select the memory page in the
> st_DrawPixels() routine because that is done prior to the function call). 
> What role does the st->pipe play in affecting size of writes?

Worrying about mmu-less (or non-page-on-demand) issues is not something we do.

Basically st_DrawPixels takes the pixel data, sticks it into a texture, and then uses shaders to texture that onto the framebuffer. Obviously the texture can't be larger than MAX_TEXTURE_SIZE. However no harm done if you cut up the source data into MAX_TEXTURE_SIZE-sized blocks and discarded fragments that were not going to be covered by that texture slice (or even better, set the viewport or scissors appropriately). If you were going to be sneaky, you could even concoct some scheme to use a 2d array texture, although ultimately even that has limits.

I don't immediately see a way to transfer a non-0,0-origin block of pixels from memory into a texture, but I'm sure it's reasonably easy to do, and a helper probably exists for some other functions. (Maybe it can be specified as a gl_pixelstore_attrib? It has a SkipRows/SkipPixels attribute.)
Comment 9 GitLab Migration User 2019-09-18 18:31:39 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/mesa/mesa/issues/232.

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.