Jump to content
  • Advertisement
Magogan

Shader doesn't work on AMD GPUs with latest driver

Recommended Posts

Posted (edited)

Hi,

I use the following shader (HLSL) to scale positions, normals, and depth for post processing:

 

Texture2D normalTexture : register(t0);
Texture2D positionTexture : register(t1);
Texture2D<float> depthTexture : register(t2);


static const uint POST_PROCESSING_SCALING_MASK = 0xC0;
static const uint POST_PROCESSING_SCALING_FULL = 0x00;
static const uint POST_PROCESSING_SCALING_HALF = 0x40;
static const uint POST_PROCESSING_SCALING_QUARTER = 0x80;


cbuffer PixelBuffer{
    float fogStart;
    float fogMax;
    uint Flags;
    float Gamma;


    float3 fogColor;
    float SpaceAlpha;


    float FrameTime;
    float MinHDRBrightness;
    float MaxHDRBrightness;
    float ScreenWidth;


    float3 SemiTransparentLightColor;
    float ScreenHeight;


    float SpaceAlphaFarAway;
    float SpaceAlphaNearPlanets;
    float HDRFalloffFactor;
    float InverseGamma;


    float3 CameraLiquidColor;
    float CameraLiquidVisualRange;


    float CameraInLiquidMinLerpFactor;
    float CameraInLiquidMaxLerpFactor;
    float MinCloudBrightness;
    float MaxCloudBrightness;


    float4 BorderColor;


    float3 SunColor;
    float padding0;
};


struct PixelInputType{
    float4 position : SV_POSITION;
};



struct PixelOutputType{
    float4 normal : SV_Target0;
    float4 position : SV_Target1;
    float depth : SV_Depth;
};


PixelOutputType main(PixelInputType input){
    PixelOutputType output;
    const uint ScalingFlag = (Flags & POST_PROCESSING_SCALING_MASK) >> 6;


    uint3 TexCoords = uint3(uint2(input.position.xy) << ScalingFlag, 0);
    const uint Max = (1 << ScalingFlag) << ScalingFlag;
    uint UsedIndex = 0xFFFFFFFF;
    for (uint i = 0; i < Max && i < 16; ++i) {
        const uint3 CurrentTexCoords = TexCoords + uint3(i & ((1 << ScalingFlag) - 1), i >> ScalingFlag, 0);
        output.position = positionTexture.Load(CurrentTexCoords);
        if (output.position.w >= 0.0f) {    
            UsedIndex = i;
            break;            
        }        
    }
    if (UsedIndex == 0xFFFFFFFF) {
        output.normal = float4(0, 0, 0, 0);
        output.depth = 1.0f;
        discard;
    }
    else {
        const uint3 CurrentTexCoords2 = TexCoords + uint3(UsedIndex & ((1 << ScalingFlag) - 1), UsedIndex >> ScalingFlag, 0);
        output.normal = normalTexture.Load(CurrentTexCoords2);
        output.depth = depthTexture.Load(CurrentTexCoords2);
    }
    return output;
}

 

It doesn't work with the latest drivers on AMD graphics cards, neither on my laptop (R7 M270) nor one of my friend's computers (RX 480).

It works perfectly on Nvidia/Intel GPUs and it worked with older drivers on my laptop, too.

On AMD GPUs, it outputs wrong data, i.e. output.position.w < 0 even though that is impossible (if it is < 0, UsedIndex will be 0xFFFFFFFF, therefore the pixel will be discarded). If I manually set output.position.w = 0 in both of the branches on (UsedIndex == 0xFFFFFFFF), it outputs 0 in the w component. If I set it in only one of the branches (doesn't matter which one), then output.position.w is negative in the output.

The other output (positions.xyz, normals.xyz, and depth) seems to be correct, but I'm not sure about normals.w.

It literally makes no sense and I think it's a driver bug, what can I do?

Cheers,

Magogan

Edit: If I add the following code before returning output, it gets even weirder:

if (output.position.w < 0) {
	output.position.w = 0;
}
else {
	output.position.w = 1;	
}

After that, output.position.w is neither 0 nor 1, but something such that it is not >= 0, so probably NAN or negative. WTF?

Edited by Magogan

Share this post


Link to post
Share on other sites
Advertisement

How do you declare your GBuffer multiple render target buffers?

If shader is compiled and linked, it should not be the source of problem at all.

Share this post


Link to post
Share on other sites
1 minute ago, JohnnyCode said:

How do you declare your GBuffer multiple render target buffers?

What?

1 minute ago, JohnnyCode said:

If shader is compiled and linked, it should not be the source of problem at all.

You would think so... And you would be wrong...

Share this post


Link to post
Share on other sites

My question was quite clear, your pixel function outputs to 3 render targets of likely float components per channels.

You also sample one float per component texture.

If you think modifying your shader will solve your issue while it was succefully compiled, good luck then.

Share this post


Link to post
Share on other sites
Just now, JohnnyCode said:

My question was quite clear, your pixel function outputs to 3 render targets of likely float components per channels.

Yes? It just works like that. I don't understand the question.

Share this post


Link to post
Share on other sites
Posted (edited)

if its driver version related, it could be driver bug, you can write to amd support about it.

Edited by joeblack

Share this post


Link to post
Share on other sites
Just now, joeblack said:

if its driver version related, it could be driver bug.

I'm like 80% sure it is, but how do I get AMD to fix it, without my game being as popular as The Witcher or Battlefield? How can I find a workaround in the meantime?

Share this post


Link to post
Share on other sites

you can write to amd forums/support mail. it looks that problem is in positiontexture. Have you checked content of that texture ?

Share this post


Link to post
Share on other sites
Posted (edited)
2 minutes ago, joeblack said:

you can write to amd forums/support mail.

And you think they will fix it?

2 minutes ago, joeblack said:

it looks that problem is in positiontexture. Have you checked content of that texture ?

Yes, the texture is correct. Otherwise it wouldn't work with Nvidia/Intel GPUs (and an older version of the AMD driver on my laptop). And even if the texture is not correct, that wouldn't explain the behavior I observed.

Edited by Magogan

Share this post


Link to post
Share on other sites

Well it depends, on AMD speed.

What is format of texture ? did you checked shader that is writing to it ?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • 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!