Jump to content
  • Advertisement
Sign in to follow this  
ade-the-heat

gpgpu shader problem

This topic is 4232 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi Most of my gpgpu shaders are relatively efficient. Except one ! It's basically used to set boundary values of velocity vectors in a simulation. As a snippet from hell check the below and then tell me how I can make it shorter/clearer/faster han the many many 'if' statements in it. Each check is to see whereabouts the pixel represents in the xyz plane
void main()
{
	vec4 outTex = vec4(texture2D(inTexture, gl_TexCoord[0].st));
	vec4 inTex;
	vec4 inTex1;
	vec4 inTex2;
	vec4 inLookupTex;
	//float offsetIdx;
	bool donePixel=false;
	
	float widthF = float(width)+3.0;
	int i=int(mod(gl_TexCoord[0].s, widthF)) -1;
	int j=int(floor(gl_TexCoord[0].s/widthF))-1;
	int k=int(gl_TexCoord[0].t)-1;
	
	float idx = gl_TexCoord[0].s+gl_TexCoord[0].t*((float(width)+3.0)*(float(depth)+3.0));

	//if (idx >= (MINIDXVAL_F-xStep) && idx<=(MINIDXVAL_F-xStep))
	{
		//offsetIdx = texture2D(indxLookupTexture, gl_TexCoord[0].st+vec2(xStep,0)).x;
		//get i value from this
		if (i==0)
		{
			inTex = vec4(texture2D(inTexture, gl_TexCoord[0].st+vec2(xStep,0)));
			gl_FragColor = outTex;
			donePixel=true;
		}
	}

	if (!donePixel) // && (idx >= (MINIDXVAL_F+xStep) && idx<=(MAXIDXVAL_F+xStep)))
	{
		//offsetIdx = texture2D(indxLookupTexture, gl_TexCoord[0].st-vec2(xStep,0)).x;
		if (i==width)
		{
			inTex = vec4(texture2D(inTexture, gl_TexCoord[0].st-vec2(xStep,0)));
			gl_FragColor = outTex;
			donePixel=true;
		}
	}

	if (!donePixel) // && (idx >= (MINIDXVAL_F-yStep) && idx<=(MAXIDXVAL_F-yStep)))
	{
		//offsetIdx = texture2D(indxLookupTexture, gl_TexCoord[0].st+vec2(yStep,0)).x;
		if (j==0)
		{
			inTex = vec4(texture2D(inTexture, gl_TexCoord[0].st+vec2(yStep,0)));
			gl_FragColor = outTex;
			donePixel=true;
		}
	}

	if (!donePixel) // && (idx >= (MINIDXVAL_F+yStep) && idx<=(MAXIDXVAL_F+yStep)))
	{
		//offsetIdx = texture2D(indxLookupTexture, gl_TexCoord[0].st-vec2(yStep,0)).x;
		if (j==depth)
		{
			inTex = vec4(texture2D(inTexture, gl_TexCoord[0].st-vec2(yStep,0)));
			
			//outTex[channel] = dir == DIRY ? -inTex[channel]  : inTex[channel];
			gl_FragColor = outTex;
			donePixel=true;
		}
	}


	if (!donePixel) // && (idx >= (MINIDXVAL_F-zStep) && idx<=(MAXIDXVAL_F-zStep)))
	{
		//offsetIdx = texture2D(indxLookupTexture, gl_TexCoord[0].st+vec2(0,zStep)).x;
		if (k==0)
		{
			inTex = vec4(texture2D(inTexture, gl_TexCoord[0].st+vec2(0,zStep)));
			//outTex[channel] = dir == DIRY ? -inTex[channel]  : inTex[channel];
			gl_FragColor = outTex;
			donePixel=true;
		}
	}

	if (!donePixel) // && (idx >= (MINIDXVAL_F+xStep) && idx<=(MAXIDXVAL_F+zStep)))
	{
		//offsetIdx = texture2D(indxLookupTexture, gl_TexCoord[0].st-vec2(0,zStep)).x;
		if (k==height)
		{
			inTex = vec4(texture2D(inTexture, gl_TexCoord[0].st-vec2(0,zStep)));
			//outTex[channel] = dir == DIRZ ? -inTex[channel]  : inTex[channel];
			gl_FragColor = outTex;
			donePixel=true;
		}
	}


	if (!donePixel) // && (idx >= (MINIDXVAL_F-yStep-zStep) && idx<=(MAXIDXVAL_F-yStep-zStep)))
	{
		//offsetIdx = texture2D(indxLookupTexture, gl_TexCoord[0].st+vec2(yStep,0)+vec2(0,zStep)).x;
		if ((j==0)&&(k==0))
		{
			inTex = vec4(texture2D(inTexture, gl_TexCoord[0].st+vec2(yStep,0)));
			inTex1 = vec4(texture2D(inTexture, gl_TexCoord[0].st+vec2(0,zStep)));
			//outTex[channel] = (inTex[channel] + inTex1[channel])/2.0;
			gl_FragColor = outTex;
			donePixel=true;
		}
	}


	if (!donePixel) // && (idx >= (MINIDXVAL_F-yStep+zStep) && idx<=(MAXIDXVAL_F-yStep+zStep)))
	{
		//offsetIdx = texture2D(indxLookupTexture, gl_TexCoord[0].st+vec2(yStep,0)-vec2(0,zStep)).x;
		if ((j==0) && (k==height))
		{
			inTex = vec4(texture2D(inTexture, gl_TexCoord[0].st+vec2(yStep,0)));
			inTex1 = vec4(texture2D(inTexture, gl_TexCoord[0].st-vec2(0,zStep)));
			
			//outTex[channel] = (inTex[channel] + inTex1[channel])/2.0;
			gl_FragColor = outTex;
			donePixel=true;
		}
	}

	if (!donePixel) // && (idx >= (MINIDXVAL_F+yStep-zStep) && idx<=(MAXIDXVAL_F+yStep-zStep)))
	{
		//offsetIdx = texture2D(indxLookupTexture, gl_TexCoord[0].st-vec2(yStep,0)+vec2(0,zStep)).x;
		if ((j==depth) && (k==0))
		{
			inTex = vec4(texture2D(inTexture, gl_TexCoord[0].st-vec2(yStep,0)));
			inTex1 = vec4(texture2D(inTexture, gl_TexCoord[0].st+vec2(0,zStep)));

			//outTex[channel] = (inTex[channel] + inTex1[channel])/2.0;
			gl_FragColor = outTex;
			donePixel=true;
		}
	}

	if (!donePixel) // && (idx >= (MINIDXVAL_F-yStep-zStep) && idx<=(MAXIDXVAL_F-yStep-zStep)))
	{
		//offsetIdx = texture2D(indxLookupTexture, gl_TexCoord[0].st+vec2(yStep,0)+vec2(0,zStep)).x;
		if ((j==depth) && (k==height))
		{
			inTex = vec4(texture2D(inTexture, gl_TexCoord[0].st+vec2(yStep,0)));
			inTex1 = vec4(texture2D(inTexture, gl_TexCoord[0].st+vec2(0,zStep)));
			//outTex[channel] = (inTex[channel] + inTex1[channel])/2.0;
			gl_FragColor = outTex;
			donePixel=true;
		}
	}



	if (!donePixel) // && (idx >= (MINIDXVAL_F+xStep+zStep) && idx<=(MAXIDXVAL_F+xStep+zStep)))
	{
		//offsetIdx = texture2D(indxLookupTexture, gl_TexCoord[0].st-vec2(yStep,0)-vec2(0,zStep)).x;
		if ((i==0) && (k==0))
		{
			inTex = vec4(texture2D(inTexture, gl_TexCoord[0].st-vec2(yStep,0)));
			inTex1 = vec4(texture2D(inTexture, gl_TexCoord[0].st-vec2(0,zStep)));
			//outTex[channel] = (inTex[channel] + inTex1[channel])/2.0;
			gl_FragColor = outTex;
			donePixel=true;
		}
	}


	if (!donePixel) // && (idx >= (MINIDXVAL_F+xStep-zStep) && idx<=(MAXIDXVAL_F+xStep-zStep)))
	{
		//offsetIdx = texture2D(indxLookupTexture, gl_TexCoord[0].st-vec2(xStep,0)+vec2(0,zStep)).x;
		if ((i==0) && (k==height))
		{
			inTex = vec4(texture2D(inTexture, gl_TexCoord[0].st-vec2(xStep,0)));
			inTex1 = vec4(texture2D(inTexture, gl_TexCoord[0].st+vec2(0,zStep)));
			//outTex[channel] = (inTex[channel] + inTex1[channel])/2.0;
			gl_FragColor = outTex;
			donePixel=true;
		}
	}


	if (!donePixel) // && (idx >= (MINIDXVAL_F-xStep+zStep) && idx<=(MAXIDXVAL_F-xStep+zStep)))
	{
		//offsetIdx = texture2D(indxLookupTexture, gl_TexCoord[0].st+vec2(xStep,0)-vec2(0,zStep)).x;
		if ((i==width) && (k==0))
		{
			inTex = vec4(texture2D(inTexture, gl_TexCoord[0].st+vec2(xStep,0)));
			inTex1 = vec4(texture2D(inTexture, gl_TexCoord[0].st-vec2(0,zStep)));
			//outTex[channel] = (inTex[channel] + inTex1[channel])/2.0;
			gl_FragColor = outTex;
			donePixel=true;
		}
	}

	if (!donePixel) // && (idx >= (MINIDXVAL_F-xStep-zStep) && idx<=(MAXIDXVAL_F-xStep-zStep)))
	{
		//offsetIdx = texture2D(indxLookupTexture, gl_TexCoord[0].st+vec2(xStep,0)+vec2(0,zStep)).x;
		if ((i==width) && (k==height))
		{
			inTex = vec4(texture2D(inTexture, gl_TexCoord[0].st+vec2(xStep,0)));
			inTex1 = vec4(texture2D(inTexture, gl_TexCoord[0].st+vec2(0,zStep)));
			//outTex[channel] = (inTex[channel] + inTex1[channel])/2.0;
			gl_FragColor = outTex;
			donePixel=true;
		}
	}

	//vertical edges
	if (!donePixel) // && (idx >= (MINIDXVAL_F+xStep+yStep) && idx<=(MAXIDXVAL_F+xStep+yStep)))
	{
		//offsetIdx = texture2D(indxLookupTexture, gl_TexCoord[0].st-vec2(xStep,0)-vec2(yStep,0)).x;
		if ((i==0) && (j==0))
		{
			inTex = vec4(texture2D(inTexture, gl_TexCoord[0].st-vec2(xStep,0)));
			inTex1 = vec4(texture2D(inTexture, gl_TexCoord[0].st-vec2(yStep,0)));
			
			//outTex[channel] = (inTex[channel] + inTex1[channel])/2.0;
			gl_FragColor = outTex;
			donePixel=true;
		}
	}

	if (!donePixel) // && (idx >= (MINIDXVAL_F+xStep-yStep) && idx<=(MAXIDXVAL_F+xStep-yStep)))
	{
		//offsetIdx = texture2D(indxLookupTexture, gl_TexCoord[0].st-vec2(xStep,0)+vec2(yStep,0)).x;
		if ((i==0) && (j==depth))
		{
			inTex = vec4(texture2D(inTexture, gl_TexCoord[0].st-vec2(xStep,0)));
			inTex1 = vec4(texture2D(inTexture, gl_TexCoord[0].st-vec2(yStep,0)));
			//outTex[channel] = (inTex[channel] + inTex1[channel])/2.0;
			gl_FragColor = outTex;
			donePixel=true;
		}
	}

	if (!donePixel) // && (idx >= (MINIDXVAL_F-xStep+yStep) && idx<=(MAXIDXVAL_F-xStep+yStep)))
	{
		//offsetIdx = texture2D(indxLookupTexture, gl_TexCoord[0].st+vec2(xStep,0)-vec2(yStep,0)).x;
		if ((i==width) && (j==0))
		{
			inTex = vec4(texture2D(inTexture, gl_TexCoord[0].st+vec2(xStep,0)));
			inTex1 = vec4(texture2D(inTexture, gl_TexCoord[0].st-vec2(yStep,0)));
			gl_FragColor = outTex;
			donePixel=true;
		}
	}


	if (!donePixel) // && (idx >= (MINIDXVAL_F-xStep-yStep) && idx<=(MAXIDXVAL_F-xStep-yStep)))
	{
		//offsetIdx = texture2D(indxLookupTexture, gl_TexCoord[0].st+vec2(xStep,0)+vec2(yStep,0)).x;
		if ((i==width) && (j==depth))
		{
			inTex = vec4(texture2D(inTexture, gl_TexCoord[0].st+vec2(xStep,0)));
			inTex1 = vec4(texture2D(inTexture, gl_TexCoord[0].st+vec2(yStep,0)));
			//outTex[channel] = (inTex[channel] + inTex1[channel])/2.0;
			gl_FragColor = outTex;
			donePixel=true;
		}
	}

	if (!donePixel)
		discard;
		
}





Share this post


Link to post
Share on other sites
Advertisement
First of all let me say that i'm not the most appropriate person to answer shader performance questions, neither i understand what the shader does, but i have one comment.

I think the logic of the shader is wrong. I.e. suppose that for one pixel the condition i==0 is true. This will result in executing the first of the if-statements which in turn will set the donePixel flag to true. If this happens, then all the conditionals which include i==0 are redundant because donePixel is already true, and they wont be executed, despite the fact (e.g.) that j == 0 too. Hope that makes sense. I'm not really sure how much it will help if you reorganize the code.

About the performance, i'd suggest taking a look at the produced assembly in order to see if conditionals are actually used or if the whole shader is being executed for each pixel (which could be the case even if conditionals are used, iirc). You have 31 uncommented texture2D() calls which are too much, i think. On the good side is that you aren't actually using the results from the fetches, so probably the compiler has already eliminated them.

HellRaiZer

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!