Jogl: fragment program is over native resource limits

I use jogl to read the two fragment programs. It seems the simple fragment program can pass the native resource limit test. However, the more complicated fragment program can not pass the native resource limits test. Can someone give me some suggestions on the error causation and work around? If I use C and OpenGL, both of the fragment programs work all right. What the “native resource limits” means in Jogl?

Hopefully, Ken can give me certain input on this.

Thanks.

I post my jogl testing code and the two fragment programs below,

/************** Jogl testing code ****************/
// profile = GL.GL_FRAGMENT_PROGRAM_ARB
// FileUtils as given in the jogl.demo.util
private int loadProgram(GL gl, int profile) throws IOException {
String fileNm = “isosurface_sm3.fp”;
FileInputStream in;
fileNm = “VolumeRenderPyramidF.ocg”;
in = new FileInputStream(fileNm);

  String programBuffer = FileUtils.loadStreamIntoString(in);
  int[] tmpInt = new int[1];
  gl.glGenProgramsARB(1, tmpInt, 0);
  int res = tmpInt[0];
  gl.glBindProgramARB(profile, res);
  gl.glProgramStringARB(profile, GL.GL_PROGRAM_FORMAT_ASCII_ARB,
                        programBuffer.length(), programBuffer);
  int[] errPos = new int[1];
  gl.glGetIntegerv(GL.GL_PROGRAM_ERROR_POSITION_ARB, errPos, 0);
  if (errPos[0] >= 0) {
    String kind = "Program";
    if (profile == GL.GL_VERTEX_PROGRAM_ARB) {
      kind = "Vertex program";
    }
    else if (profile == GL.GL_FRAGMENT_PROGRAM_ARB) {
      kind = "Fragment program";
    }
    System.out.println(kind + " failed to load:");
    String errMsg = gl.glGetString(GL.GL_PROGRAM_ERROR_STRING_ARB);
    if (errMsg == null) {
      System.out.println("[No error message available]");
    }
    else {
      System.out.println("Error message: \"" + errMsg + "\"");
    }
    System.out.println("Error occurred at position " + errPos[0] +
                       " in program:");
    int endPos = errPos[0];
    while (endPos < programBuffer.length() &&
           programBuffer.charAt(endPos) != '\n') {
      ++endPos;
    }
    System.out.println(programBuffer.substring(errPos[0], endPos));
    throw new GLException("Error loading " + kind);
  }
  else {
    if (profile == GL.GL_FRAGMENT_PROGRAM_ARB) {
      int[] isNative = new int[1];
      gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB,
                           GL.GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB,
                           isNative, 0);
      if (isNative[0] != 1) {
        /*******************************   Native limit test  *******************/
        System.out.println(
            "WARNING: fragment program is over native resource limits");
        Thread.dumpStack();
      }
    }
  }
  return res;
} 

/***** simple fragment code: “VolumeRenderPyramidF.ocg” ****************************/
!!FP1.0

NV_fragment_program generated by NVIDIA Cg compiler

cgc version 1.1.0003, build date Mar 4 2003 12:32:10

command line args: -q -profile fp30 -entry FragmentProgram

#vendor NVIDIA Corporation
#version 1.0.02
#profile fp30
#program FragmentProgram
#semantic FragmentProgram.USTexture
#semantic FragmentProgram.ColorMap
#var float4 inTex : $vin.TEXCOORD0 : TEXCOORD0 : 0 : 1
#var float4 sColor0 : $vout.COLOR0 : COLOR0 : 1 : 1
#var sampler3D USTexture : : texunit 0 : 2 : 1
#var sampler1D ColorMap : : texunit 1 : 3 : 1
MOVX H0, f[TEX0];
MULX H0.z, H0.z, H0.w;
TXP R0, H0, TEX0, 3D;
TEX o[COLR], R0.x, TEX1, 1D;

If you get artifacts, try this instead:

MOVR R0, f[TEX0];

MULR R0.z, R0.z, R0.w;

TXP R0, R0, TEX0, 3D;

TEX o[COLR], R0.x, TEX1, 1D;

END

4 instructions, 1 R-regs, 1 H-regs.

End of program

/*** complicated fragment program: isosurface_sm3.fp *************************/
!!ARBfp1.0
OPTION NV_fragment_program2;

Filename: volume_sm3.fp

#! VOLUME = 0
#! TRANSFERFUNCTION = 1
#! BACKGROUND = 2

r = step

g = gradient scale

b = gradient offset

a = z-value of background plane

PARAM params = program.local[0];

r = texture coordinate scale

g = number of iterations

b = isovalue of isosurface

PARAM params2 = program.local[1];
PARAM center = program.local[2];
PARAM texMax = program.local[3];

PARAM scaleFactors = program.local[5];

TEMP geomDir;
TEMP geomPos;
TEMP texblen;
TEMP diffVec;
TEMP scalar;
TEMP camera;
TEMP normal;
TEMP temp1;
TEMP temp2;
TEMP temp;
TEMP pos;
TEMP src;
TEMP dst;
TEMP dir;
TEMP tex;

Compute the ray’s starting point

MOV geomPos, fragment.texcoord[0];
MUL pos, geomPos, scaleFactors;
MOV pos.a, 0.0;

Compute the camera position by translating the origin to the center of the

volume

MOV camera, state.matrix.modelview.invtrans.row[3];

Compute the ray direction

SUB geomDir, geomPos, camera;

Normalize the direction (done manually instead of with NRM to improve

accuracy)

DP3 geomDir.w, geomDir, geomDir;
RSQ geomDir.w, geomDir.w;
MUL geomDir, geomDir, geomDir.w;
MOV geomDir.w, 0.0;

MUL dir, geomDir, scaleFactors;

Initialize scalar value

RGB = gradient, alpha = scalar value

TXL scalar, pos, texture[0], 3D;
MOV scalar.g, scalar.a;
MOV scalar.a, 0.0;

Initialize destination color

MOV dst, 0.0;

Move one step forward

MAD pos, dir, params.r, pos;

REP params2.g;
REP params2.g;

	# Lookup new scalar value
	TXL tex, pos, texture[0], 3D;
	MOV scalar.r, tex.a;

	# Lookup color in pre-int texture
	TXL src, scalar, texture[1], 2D;

	# TODO Early ray termination (no gain of speed so far)
	#SUBC texblen.r, 1.0, dst.a;
	#BRK (LE.x);

	# Perform blending
	SUB texblen.r, 1.0, dst.a;
	MAD_SAT dst, src, texblen.r, dst;

	# Move one step forward
	MAD pos, dir, params.r, pos;

	# Terminate loop if outside volume
	SGE temp1, pos, 0.0;
	SLE temp2, pos, texMax;
	DP3 temp1.r, temp1, temp2;
	SEQC temp1.r, temp1.r, 3.0;
	BRK (EQ.x);

	# Save current scalar value
	MOV scalar.g, scalar.r;

ENDREP;

BRK (LE.x);

ENDREP;

Compute the normal of the background plane (this is just the negative view

direction which initially is (0, 0, -1))

MOV normal, state.matrix.modelview.row[2];

Compute the plane constant (we want the plane to be located in the volume

center)

DP3 temp1.r, normal, center;

Move the plane behind the volume: d’ = <n,(x - l n)> = <n, x> - l <n, n>;

l = 0.71 is chosen since it is greater than half the cube diagonal

DP3 temp1.g, normal, normal;
MAD temp1.r, temp1.g, -.71, temp1.r;

Compute ray parameter

DP3 temp1.g, normal, geomPos;
SUB temp1.g, temp1.r, temp1.g;
DP3 temp1.b, normal, geomDir;
DIV temp.r, temp1.g, temp1.b;

Compute ray/plane intersection

MAD temp.rgb, temp.r, geomDir, geomPos;

Compute the difference vector

SUB diffVec, temp, center;

Compute the texture coordinates

DP3 temp.r, diffVec, state.matrix.modelview.row[0];
DP3 temp.g, diffVec, state.matrix.modelview.row[1];
MUL temp.rg, temp, params2.r;

Center background image

ADD temp.rg, temp, .5;

Look up the texel value

TEX temp.rgb, temp, texture[2], 2D;
MOV temp.a, 1.0;

Blend the background pixel

SUB texblen, 1.0, dst.a;
MAD dst, temp, texblen.x, dst;

Write the output color

MOV result.color, dst;

END

JOGL does no interposition in this area (or any other one, for the most part) and just passes the program down to C. I don’t know exactly what could be going wrong or working differently in your case. If you can provide a complete, small and self-contained test case (the analogous C code would be helpful too) we can try to look into it further.

Ken,

http://home.gwu.edu/~ruida/temp.rar

I post the link for the jogl testting program. The program just test the native resource limits.
Under the loadProgram() method of vRender.java, switch the following two lines, you will see the error message.

String fileNm = “isosurface_sm3.fp”;
fileNm = “VolumeRenderPyramidF.ocg”;

For the C and OpenGl working version, see the link below. isosurface_sm3.fp is just one volume shader fragment program.
http://www.vis.uni-stuttgart.de/eng/research/fields/current/spvolren/spvolren_src.zip

Let me know, if you need more resource.

Sorry, but this isn’t a complete enough side-by-side test case. I don’t see any data files for the spvolren package, in particular, so can’t run it side-by-side with your Java version. I note that the C sources do a scan over the incoming fragment program which your Java sources aren’t doing, but I don’t think that changes the behavior of the fragment program, only counts the number of texture units it’s using. On my machine I get the following error when running your Java sources:


Fragment program failed to load:
Error message: "line 2, column 8:  error: program option type not supported on t
his hardware
line 93, column 5:  error: Looping statement nested too deeply.
line 95, column 6:  error: Looping statement nested too deeply.
line 104, column 6:  error: IF statement nested too deeply.
line 185, column 14:  error: BRK statement not inside a loop.
line 186, column 8:  error: ENDIF without matching IF.
line 198, column 13:  error: BRK statement not inside a loop.
line 202, column 8:  error: ENDREP without matching REP.
line 204, column 12:  error: BRK statement not inside a loop.
line 206, column 7:  error: ENDREP without matching REP.
"
Error occurred at position 18 in program:
NV_fragment_program2;
javax.media.opengl.GLException: Error loading Fragment program
        at vRender.loadProgram(vRender.java:114)
        at vRender.initGPU(vRender.java:135)
        at vRender.init(vRender.java:19)
        at com.sun.opengl.impl.GLDrawableHelper.init(GLDrawableHelper.java:72)

So basically I can’t see the error you’re seeing. It looks like my machine (Quadro FX Go700, mobile chip, with recent NVidia drivers) doesn’t support this particular syntax in ARB_fragment_program.

Ken,

I use GeForce 6800 GS, 256 MB.

Show the following msg
“WARNING: fragment program is over native resource limits”

hm… maybe you update for a new Nvidia card?

For spvolren package, I used the .NET 2003 to build and run the project., everything is fine.

Thanks,

In order for me to investigate this further I’ll need precise instructions on how to run the spvolren package. I was able to successfully build it, but don’t know how to run it and it doesn’t seem to come with any data files.

Ken,

Following link includes the data. Sorry for this.

http://wwwvis.informatik.uni-stuttgart.de/eng/research/fields/current/spvolren/

Under my spvolren/data directory, I put the data files. i.e. head256.dat. head256.raw, etc.

.NET 2003, Project->spvolren properties-> Debugging

Command: C:\Documents and Settings\yourname\Desktop\spvolren\debug\spvolren.exe
Command Arguments: data\head256.dat
Working Direcotry: C:\Documents and Settings\yourname\Desktop\spvolren\debug

Build and Run should be straight forward.

Let me know if you still encounter compiling and running problems.

Thanks,