PDA

View Full Version : ATI Fragment Shader



simon.anderson
01-08-2015, 07:42 PM
Hi,
I'm a newbie with GLSL and currently experiencing a crash in a fragment shader on my ATI FirePro V and have no idea why.

If I take out the for-loop it seems to work, although I don't think that should matter. Are there issues with for loops on ATI cards? Could the vertex shader be the cause of the problem instead?

It runs fine on my intel and NVidia cards. Any help would be much appreciated - here's the complete code for the fragment shader:


struct Accumulator
{
float m_sumOfWeightedValues;
float m_sumOfWeights;
};

void main()
{
Accumulator acc = Accumulator(0.0f,0.0f);

// For each cell in range
for(int x=0;x<=1;x++)
{
acc.m_sumOfWeights = 0.0f;
acc.m_sumOfWeightedValues = 0.0f;
}

// Should never be greater than 0;
if( acc.m_sumOfWeights > 0.0f )
{
float w = 1.0f;
s_frag_color = texture(s_texture_1,vec2(w,0),0);
}
}


Cheers,
Simon

Alfonse Reinheart
01-08-2015, 08:11 PM
What happens if you manually unroll the loop? Also, are you aware that the loop runs twice?

simon.anderson
01-08-2015, 10:17 PM
Thanks Alfonse,

it's fine if I unroll the loop. Yes - I am aware the loop runs twice - it's just a hack of the original code so I can reproduce the crash. The problem is I can't unroll the original loop (this code is edited) as it is of variable length.

It should never reach the line - s_frag_color = texture(s_texture_1,vec2(w,0),0); - but for some reason when I take it out it fixes the crash. I think maybe some memory is getting trashed elsewhere in another shader file.

Cheers,
Simon

Alfonse Reinheart
01-08-2015, 11:08 PM
The only thing I see about the code you posted that is wrong is the fact that s_frag_color does not always have a value being written to it. While this leads to an undefined value being written, I don't think it this form of undefined behavior is allowed to lead to a crash.

Also, what exactly do you mean when you say that it crashes? Does the GPU lock up and have to be reset? Or is it something else?

simon.anderson
01-08-2015, 11:26 PM
Ok thanks. I mean the application running the shader crashes and windows presents a message saying something similar to "the graphics driver crashed and has recovered". So windows recovers ok but the program crashes out completely.

Actually, if I comment out the associated vertex shader completely it works also:

//
// Vertex Shader
//
in float4 s_attribute_0;
in half4 s_attribute_1;
in half4 s_attribute_2;

out vec3 normalisedFragmentLoc;

void main()
{
float4 row_0,row_1,row_2;

row_0 = s_transform[0];
row_1 = s_transform[1];
row_2 = s_transform[2];

float4 position = float4(s_attribute_0.x,s_attribute_0.y,s_attribute _2.w,1.0f);
float4 vertex = float4(dot(row_0,position),dot(row_1,position),dot (row_2,position),1.0f);

gl_Position = getPosition(vertex);
normalisedFragmentLoc = s_attribute_1.xyz;
}

Alfonse Reinheart
01-08-2015, 11:46 PM
in float4 s_attribute_0;

There is no such type in GLSL as float4. What language are you compiling in?

simon.anderson
01-09-2015, 12:11 AM
Sorry - I just realised the game engine I'm using compiles compiles HLSL.

The exact Vertex and Fragment shaders are as follows:


#include <core/shaders/default/common/vertex_base.h>
/*
Trivial vertex shader for IDW - just passes the uv (representing the vertex position in
normalised query volume space) along as a varying vec3.
*/
/************************************************** ****************************\
*
* OpenGL/OpenGLES
*
\************************************************* *****************************/
#ifdef OPENGL || OPENGLES
in float4 s_attribute_0;
in half4 s_attribute_1;
in half4 s_attribute_2;
out vec3 normalisedFragmentLoc;
void main()
{
float4 row_0,row_1,row_2;
row_0 = s_transform[0];
row_1 = s_transform[1];
row_2 = s_transform[2];
float4 position = float4(s_attribute_0.x,s_attribute_0.y,s_attribute _2.w,1.0f);
float4 vertex = float4(dot(row_0,position),dot(row_1,position),dot (row_2,position),1.0f);
gl_Position = getPosition(vertex);
//normalisedFragmentLoc = s_attribute_1.xyz;
}
#elif DIRECT3D10 || DIRECT3D11
/************************************************** ****************************\
*
* DirectX 10/11
*
\************************************************* *****************************/
#endif






/*
Not so trivial fragment shader for IDW - for each pixel we find the (inverse distance weighted) interpolated value
based on nearby measurements.
*/
#include <core/shaders/default/common/fragment_base.h>
/************************************************** ****************************\
*
* OpenGL/OpenGLES
*
\************************************************* *****************************/
#ifdef OPENGL || OPENGLES
in vec3 normalisedFragmentLoc;
uniform sampler2D s_texture_0; // Drill data measurements. Each texel has the position and value of a down hole measurement, and
// each row contains samples positioned within a cell of a regular lattice spanning the volume of interest.
uniform sampler2D s_texture_1; // LUT texture to transform from value to color - should be in a seperate pass so that we render *values* in here not the value to color mapping.
// Set from script based on dataset
uniform vec4 volume_range;
uniform vec4 grid_size;
// User controlled parameters
uniform float idw_range;
uniform float idw_rangeMultiplierZ;
uniform float idw_exponent;
uniform float idw_linearFadeFactor;
uniform float idw_ignoreTopDist;
uniform float apply_mapping;
struct Accumulator
{
float m_sumOfWeightedValues;
float m_sumOfWeights;
};
float GetWeightedAverage(Accumulator acc)
{
return acc.m_sumOfWeightedValues / acc.m_sumOfWeights;
}
float worldSpaceDistance(vec3 a, vec3 b )
{
vec3 v = volume_range.xyz * (a - b );
v.z *= idw_rangeMultiplierZ;
return length( v );
}
void Gather(in int row, in int rowLength, inout Accumulator acc)
{
// First two texels represent the bounding box
vec4 minV = texelFetch(s_texture_0,ivec2(0,row),0);
vec4 maxV = texelFetch(s_texture_0,ivec2(1,row),0);
vec3 closePoint = clamp( normalisedFragmentLoc, minV.xyz, maxV.xyz );
if( worldSpaceDistance( normalisedFragmentLoc, closePoint ) < idw_range )
{
int sampleCount = int(minV.w * rowLength);
for(int i=0;i<sampleCount;i++)
{
vec4 texel = texelFetch(s_texture_0,ivec2(i+2,row),0);
float d = worldSpaceDistance( normalisedFragmentLoc, texel.xyz );
if( d < idw_range && texel.z < idw_ignoreTopDist )
{
float weight = 1.0f / pow(d,idw_exponent);
weight *= (1.0f - idw_linearFadeFactor * (d / idw_range));
acc.m_sumOfWeights += weight;
acc.m_sumOfWeightedValues += weight * texel.w;
}
}
}
}
void main()
{
ivec2 encodedSize = textureSize(s_texture_0,0);

Accumulator acc = Accumulator(0.0f,0.0f);
// Compensate for sqaushed Z
vec3 radiusNormalised = idw_range / volume_range.xyz;
radiusNormalised.z /= idw_rangeMultiplierZ;

// Index into the lattice
ivec3 maxRange = ivec3(grid_size.xyz) - ivec3(1);
ivec3 minV = clamp( ivec3(floor( (normalisedFragmentLoc - radiusNormalised) * grid_size.xyz )),ivec3(0),maxRange );
ivec3 maxV = clamp( ivec3(floor( (normalisedFragmentLoc + radiusNormalised) * grid_size.xyz )),ivec3(0),maxRange );
// For each cell in range
for(int x=minV.x;x<=maxV.x;x++)
{
for(int y=minV.y;y<=maxV.y;y++)
{
for(int z=minV.z;z<=maxV.z;z++)
{
// Find the row in the texture where all values are encoded for this cell
int index = int(x + y * grid_size.x + z * (grid_size.x * grid_size.y));
Gather(index,encodedSize.x,acc);
}
}
}
// Operate in 2 modes -> either render raw result, or render color mapped result
if( apply_mapping < 1.0f )
{
if( acc.m_sumOfWeights > 0.0f )
{
float w = GetWeightedAverage(acc);
s_frag_color = vec4(vec3(w),1);
}
else
{
s_frag_color = vec4(0);
}
}
else
{
if( acc.m_sumOfWeights > 0.0f )
{
// Clamp uv to half texel from edge to avoid interpolation / wrapping.
float padding = 0.5f / textureSize(s_texture_1,0).x;
float w = clamp(GetWeightedAverage(acc),padding,1.0f - padding);
s_frag_color = texture(s_texture_1,vec2(w,0),0);
}
else
{
discard;
}
}
}
/************************************************** ****************************\
*
* DirectX 10/11
*
\************************************************* *****************************/
#elif DIRECT3D10 || DIRECT3D11
#endif

Dark Photon
01-09-2015, 06:52 AM
(An aside: Simon, please use ... or
... blocks around your GLSL source code. It makes it much easier to read. Updated your last post with this. Thanks.)