cancel
Showing results for 
Search instead for 
Did you mean: 

OpenGL & Vulkan

beosar
Journeyman III

Driver bug?

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,

Christopher

Edit: Adding [unroll] to the loop fixes the problem, it seems the driver can't handle Texture2D.Load() correctly in a loop.

0 Likes
8 Replies
dorisyan
Staff

Hi beosar‌, thanks for your report, we will investigate it soon.

0 Likes
dorisyan
Staff

Hi beosar‌, Could your please provide a minimal code that can reproduce your problem?

0 Likes

I've made a zip file (see attachment) with my Visual Studio 2015 project, where I removed most of the unnecessary stuff. There is a text file "steps_to_reproduce.txt" that explains what to do and some things you can experiment with (most of them I've already mentioned here).

If you have any questions regarding my code, feel free to ask. It's from a somewhat large game and I couldn't remove everything, I'm sorry.

0 Likes
dorisyan
Staff

Hi, dipak‌, I just find this is a D3D issue, could you please help me connect D3D team? Thanks!

0 Likes

Surely. I've sent you an email with appropriate contacts. 

Thanks.

0 Likes
dorisyan
Staff

Hi beosar‌, could you tell me the release version of passing driver? Thanks!

0 Likes

Hi dorisyan,

I don't use my laptop very often. Apparently, I previously installed a new driver on January 12, 2016. It worked with that one. If you can install the drivers since then, you can find the one that broke it with maybe 5 installations using binary search. I don't have access to the drivers, otherwise I would do that. And the installation of the older drivers crashed with a bluescreen on my laptop, not sure why.

A friend of mine with an AMD graphics card played it on September 19, 2018, and had no problems if he recalls it correctly, but he doesn't know which driver version he used back then (probably only a few months old, so June/July 2018 maybe). It doesn't work with the newest one on his PC, too.

0 Likes
dorisyan
Staff

Hi beosar‌, this issue has been fixed, thanks for your report !

0 Likes