Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 8 of 8

Thread: ATI Fragment Shader

  1. #1
    Junior Member Newbie
    Join Date
    Jan 2015
    Posts
    4

    ATI Fragment Shader

    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

  2. #2
    Senior Member OpenGL Lord
    Join Date
    May 2009
    Posts
    6,067
    What happens if you manually unroll the loop? Also, are you aware that the loop runs twice?

  3. #3
    Junior Member Newbie
    Join Date
    Jan 2015
    Posts
    4
    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

  4. #4
    Senior Member OpenGL Lord
    Join Date
    May 2009
    Posts
    6,067
    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?

  5. #5
    Junior Member Newbie
    Join Date
    Jan 2015
    Posts
    4
    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;
    }

  6. #6
    Senior Member OpenGL Lord
    Join Date
    May 2009
    Posts
    6,067
    Code :
    in float4 s_attribute_0;

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

  7. #7
    Junior Member Newbie
    Join Date
    Jan 2015
    Posts
    4
    Sorry - I just realised the game engine I'm using compiles compiles HLSL.

    The exact Vertex and Fragment shaders are as follows:

    Code glsl:
    #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




    Code glsl:
    /*
        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
    Last edited by Dark Photon; 01-09-2015 at 06:50 AM.

  8. #8
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,569
    (An aside: Simon, please use [highlight=glsl]...[/highlight] or [code]...[/code] blocks around your GLSL source code. It makes it much easier to read. Updated your last post with this. Thanks.)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •