Re: Fwd: [Mesa-users] Issues with removal of classic OSMesa
Andreas Fänger <[email protected]>
| Newsgroups | gmane.comp.video.mesa3d.devel,gmane.comp.video.mesa3d.user |
|---|---|
| Message-ID | <[email protected]> |
>> > 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 _______________________________________________ mesa-dev mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-dev
AnisotropyTest.java
(text/plain, 7.7 KB)
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();
}
}