> I've fixed all the issues in that area, and I believe llvmpipe and
> softpipe mostly produce the same or very similiar results.
>
> I'm not overly impressed though by the texture quality at least the
> furmark trace shows as very blurry.
>
> Also the Vulkan CTS expects linear aniso to operate differently to how
> this has done it.
>
> Andreas, can you comment on this trace?
> 
https://tracie.freedesktop.org/dashboard/imagediff/mesa/mesa/7150044/gputest/furmark.trace/
>
> I'm pretty sure softpipe looks the same locally for the same trace,
> and it just seems overly blurry.

1) Is it blurry in all cases you have tried or are there test cases
where it is better?

I've only noticed it with furmark, but I don't have a lot of test
cases, the GL CTS passes, the Vulkan CTS does look blurry and fails
but it's unlikely that is due to the blur.

2) Are the results better compared to linear?

I'm not sure, better is pretty subjective measure here,

3) Is the reference image produced with another anisotropy
implementation or with linear?

The reference image is produced with whatever llvmpipe path was taken
before this, which I assume is linear.


If 2) is not what you expect, then maybe the softpipe version is not
correct (anymore).

In general, I remember that results are a bit more blurry (compared to
linear) in the non-anisotropy case, ie. when textures are displayed
undistorted at 100%. But this doesn't seem to be the case in the trace
image here.

I'd be interested in any test data you have or any output, afaics the
llvmpipe output pretty much matches the softpipe output and if the
softpipe output is currently acceptable then we should merge the MR to
equalise them, and then fix any subsequent things on top in parallel.

I'd like to solve the VK CTS issue which does a linear vs anisotropic
compare and expects only a moderate amount of difference and we seem
to exceed the difference threshold.

I've created and attached a simple test case. Note that this is a java application using the fixed function pipeline and is based on bindings to osmesa/classic swrast, as we are not using softpipe at all. But it is very simple and should not require much work to adapt it to another language/environment (hopefully).

Just change maxAnisotropy to either 16 or 1 to switch between using anisotropic filtering or not.

The texture has been taken from the wikipedia page https://en.wikipedia.org/wiki/Anisotropic_filtering#/media/File:Anisotropic_filtering_en.png

The following images show results for both settings:

image with anisotropic filtering (16)
https://pasteboard.co/JNyFRkr.png

image without anisotropic filtering
https://pasteboard.co/JNyFlWb.png

Andreas
package test;

import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.File;
import java.io.IOException;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Iterator;

import javax.imageio.ImageIO;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;

public class AnisotropyTest implements GLEventListener
{
    public static int IMAGE_WIDTH=1280;
    public static int IMAGE_HEIGHT=960;
    
    HashMap textures=new HashMap();
    TextureLoader loader=new TextureLoader();
    
    /**
     * Set to 0 or 1 to turn off anisotropic filtering.
     * Set to 16 for highest anisotropic filtering quality.
     */
    protected float maxAnisotropy=16;
    
    public AnisotropyTest()
    {    
    }
    
    protected void bindTexture(GL gl, String textureName)
    {
        Object o=textures.get(textureName);
        if(o==null)
        {
            BufferedImage bi=loader.loadTexture(textureName);
            if(bi==null) return;
            
            DirectBufferedImage image=(DirectBufferedImage)bi;
            int format;
            switch(image.getDirectType())
            {
                case DirectBufferedImage.DIRECT_RGB: format=GL.GL_RGB;
                                                      break;
                case DirectBufferedImage.DIRECT_RGBA: format=GL.GL_RGBA;
                                                      break;
                default:
                    throw new RuntimeException(
                    "bindTexture: unknown coloring type 
"+image.getDirectType());
            }
            
            int texName[]=new int[1];
            makeTexture(gl, bi, format, texName);
            
            textures.put(textureName, texName[0]);
        }
        else
        {
            int texture=((Integer)o).intValue();
            gl.glBindTexture(GL.GL_TEXTURE_2D, texture);
        }
    }
    
    private void makeTexture(GL gl, BufferedImage image, int format, int 
texName[])
    {
        gl.glGenTextures (1, texName, 0);

        gl.glBindTexture (GL.GL_TEXTURE_2D, texName[0]);
        
        gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, 
GL.GL_REPEAT);
        gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, 
GL.GL_REPEAT);

        gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER,
            GL.GL_LINEAR);
        gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER,
            GL.GL_LINEAR_MIPMAP_LINEAR);
        gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_GENERATE_MIPMAP, GL.GL_TRUE);
        
        if(gl.isExtensionAvailable("GL_EXT_texture_filter_anisotropic") &&
                (maxAnisotropy<0 || maxAnisotropy>1)) 
        {
            float max[] = new float[1];
            gl.glGetFloatv(GL.GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, max, 0 );
            // in case a user defined maxAnisotropy is provided, use lower 
value of both limits
            gl.glTexParameterf(GL.GL_TEXTURE_2D, 
GL.GL_TEXTURE_MAX_ANISOTROPY_EXT,
                    maxAnisotropy>0 ? Math.min(maxAnisotropy, max[0]) : max[0]);
        }
        
        DataBufferByte bb=(DataBufferByte)image.getData().getDataBuffer();
        Buffer buffer=ByteBuffer.wrap(bb.getData());
        
        if(image.getWidth()<4)
        {
            int a[]=new int[1];
            gl.glGetIntegerv(GL.GL_UNPACK_ALIGNMENT, a, 0);
            int alignment=a[0];
            
            if(alignment>1)
            {
                int bytesPerElement=format==GL.GL_RGB ? 3 : 4;
                int srcRowLength=image.getWidth()*bytesPerElement;
                
                int padding = srcRowLength % alignment;
                if(padding>0)
                {
                    int dstRowLength=srcRowLength + alignment - padding;
                    
                    byte src[]=bb.getData();
                    byte dst[]=new byte[dstRowLength*image.getHeight()];
                    
                    for(int y=0, s=0, d=0; y<image.getHeight(); y++, 
s+=srcRowLength, d+=dstRowLength)
                    {
                        System.arraycopy(src, s, dst, d, srcRowLength);
                    }
                    
                    buffer=ByteBuffer.wrap(dst);
                }
            }
        }
        
        gl.glTexImage2D (GL.GL_TEXTURE_2D, 0, format, image.getWidth(),
            image.getHeight(), 0, format, GL.GL_UNSIGNED_BYTE, buffer);
    }
    
    /**
     * Deletes all cached textures from the specified GL and removes
     * all objects from the cache.
     */
    protected void deleteTextures(GL gl)
    {
        int texNames[]=new int[textures.size()];
        
        int i=0;
        for(Iterator it=textures.values().iterator(); it.hasNext(); )
        {
            texNames[i++]=((Integer)it.next()).intValue();
        }
        textures.clear();
        
        if(texNames.length>0) gl.glDeleteTextures(texNames.length, texNames, 0);
    }
    
    public void display(GLAutoDrawable drawable)
    {
        GL gl=drawable.getGL();
        GLU glu=new GLU();
        
        gl.glEnable(GL.GL_DEPTH_TEST);
        
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glLoadIdentity();
        
        
        // glu.gluPerspective(60, 1.0 * 640 / 480, 0.1, 300.0);
        // the same ass above
        double persp[]= {1.299038, 0.0, 0.0, 0.0, 0.0, 1.7320509, 0.0, 0.0, 
0.0, 0.0, -1.002002, -1.0, 0.0, 0.0, -0.2002002, 0.0};
        gl.glLoadMatrixd(persp, 0);
        
        gl.glMatrixMode(GL.GL_MODELVIEW);
        double camera[]= {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 
1.0, 0.0, 0.0, -5.1, -10.0, 1.0};
        gl.glLoadMatrixd(camera, 0);
        
        
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

        gl.glEnable(GL.GL_TEXTURE_2D);

        // https://upload.wikimedia.org/wikipedia/commons/9/92/Cobblestones.JPG
        bindTexture(gl, "Cobblestones.JPG");
        
        double width=2272;
        double height=1704;
        
        double scale=40;
        float w=(float)(width/scale);
        float h=(float)(height/scale);
        
        gl.glBegin(GL.GL_QUADS);
        
        gl.glTexCoord2f(0.0f, 0.0f);
        gl.glVertex3f(-w/2, 0.0f, -h);
        gl.glTexCoord2f(0.0f, 10.0f);
        gl.glVertex3f(w/2, 0.0f, -h);
        gl.glTexCoord2f(10.0f, 10.0f);
        gl.glVertex3f(w/2, 0.0f, 0.0f);
        gl.glTexCoord2f(10.0f, 0.0f);
        gl.glVertex3f(-w/2, 0.0f, 0.0f);
        
        gl.glEnd();
        
        gl.glFinish();

        deleteTextures(gl);
    }

    public void displayChanged(GLAutoDrawable drawable,
        boolean modeChanged, boolean deviceChanged)
    {
    }

    public void init(GLAutoDrawable drawable)
    {
    }

    public void reshape(GLAutoDrawable drawable,
        int x, int y, int width, int height)
    {
    }
    
    public static void main(String[] args)
    {
        AnisotropyTest anisotropyTest=new AnisotropyTest();
        
        OSMesaDrawable drawable=new OSMesaDrawable();
        drawable.addGLEventListener(anisotropyTest);

        DirectBufferedImage 
image=DirectBufferedImage.getDirectImageRGBA(IMAGE_WIDTH, IMAGE_HEIGHT);
        drawable.setImage(image);

        drawable.display();

        try
        {
            ImageIO.write(image, "png", new File("test_aniso.png"));
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }

        drawable.removeGLEventListener(anisotropyTest);
        drawable.dispose();
    }
}
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to