0

I have a HLSL shader (compiled using fxc and ps_2_b) that is giving me flickering artifacts. First I need to establish that all the variables seem to be constant, and their values with the following shader:

float4 src_rect : register(c0);

float4 main(float2 uv : TEXCOORD) : COLOR {
    float2 uvmin = {src_rect.x, src_rect.z};
    float2 uvmax = {src_rect.y, src_rect.w};
    float2 uv1 = (uv - uvmin)/(uvmax - uvmin);

    float4 c = 1;

    c.rgb = 0;
    if (uv.x == 639)
        c.rg = 1;
    else if (uv.y == 359)
        c.g = 1;
    else if (uv.y == 0)
        c.b = 1;
    else if (uv.x == 0)
        c.gb = 1;
    else {
        if ((uvmin.x == 0) && (uvmin.y == 0)
            && (uvmax.x == 640) && (uvmax.y == 360))
            c.rgb = float3(1, 0, 0);
    }

    return c;
}

Here is the output of this shader:

Image

So uvmin = {0, 0} and uvmax = {640, 360}. The top-left pixel uv is (0, 0) and the bottom-right pixel uv is (639, 359). Here's a shader reproducing my issue:

float4 src_rect : register(c0);

float4 main(float2 uv : TEXCOORD) : COLOR {
    float2 uvmin = {src_rect.x, src_rect.z};
    float2 uvmax = {src_rect.y, src_rect.w};
    float2 uv1 = (uv - uvmin)/(uvmax - uvmin);

    float4 c = 1;

    c.rgb = 0;
    if (uv.x == 639)
        c.rg = 1;
    else if (uv.y == 359)
        c.g = 1;
    else if (uv.y == 0)
        c.b = 1;
    else if (uv.x == 0)
        c.gb = 1;
    else {
        c.rgb = frac(floor(uv1.x*1.001)*9.999);
    }

    return c;
}

The output of this shader produces the output below, but with the white parts flickering black and white:

Image

If I plug the values for uvmin and uvmax in as constants, the problem no longer occurs. Here is the shader:

float4 src_rect : register(c0);

float4 main(float2 uv : TEXCOORD) : COLOR {
    float2 uvmin = {0, 0};
    float2 uvmax = {640, 360};
    float2 uv1 = (uv - uvmin)/(uvmax - uvmin);

    float4 c = 1;

    c.rgb = 0;
    if (uv.x == 639)
        c.rg = 1;
    else if (uv.y == 359)
        c.g = 1;
    else if (uv.y == 0)
        c.b = 1;
    else if (uv.x == 0)
        c.gb = 1;
    else {
        c.rgb = frac(floor(uv1.x*1.001)*9.999);
    }

    return c;
}

StackOVerflow won't let me include a link to the output, but it is the same as the initial image but with black instead of red.

dsffsd
  • 1
  • 1
  • There's way to little information in your question. Maybe, it is a range problem (i.e. `src_rect` is measured in pixels and `uv` is measured in normalized coordinates `\in [0, 1]`). – Nico Schertler Oct 06 '15 at 08:07
  • If you `return float4(0,1,0,1);` does it flicker between black and green, or does something else happen? – MooseBoys Oct 06 '15 at 23:36
  • @MooseBoys If I return a constant the screen doesn't flicker. – dsffsd Oct 07 '15 at 01:57
  • @Nico Schertler the uv and src_rect are both in pixels. – dsffsd Oct 07 '15 at 02:00
  • @Nico Shertler In any case, why the flickering? The variables are all constant. – dsffsd Oct 07 '15 at 02:03
  • I just re-tested this. uvmin == {0, 0}, uvmax == {640, 360}. The uv coordinate of the top left pixel is (0, 0) and the coordinate of the bottom right pixel is (639, 359). – dsffsd Oct 07 '15 at 02:51
  • Is it possible that this is a driver bug? I don't wish to be presumptuous – dsffsd Oct 07 '15 at 03:14
  • 1
    You can test if it's a driver bug with a [reference device](https://msdn.microsoft.com/en-us/library/windows/desktop/bb219625(v=vs.85).aspx). – Nico Schertler Oct 07 '15 at 06:27
  • Thanks. That's very useful to know. With the reference device I get exactly the output I expect, with no flickering. But this doesn't really prove it's an implementation bug. Should I report this to the vendor? What's the best next step? – dsffsd Oct 08 '15 at 02:48
  • If the driver behaves differently than the reference device, it is very likely a bug. But reporting a bug for a 5-year old API implementation seems unnecessary. The obvious solution would be to use DX 11. You can try to find an engineer at the vendor's who can help you work around the problem. But due to DX9's age, you will have to find a very enthusiastic engineer. – Nico Schertler Oct 08 '15 at 15:13
  • @dsffsd What are you actually trying to achieve? `frac(floor(uv1.x*1.001)*9.999)` is a very odd value to render... – MooseBoys Oct 10 '15 at 04:41
  • This is a reduced test case. The original shader was generating noise and then quantizing it. – dsffsd Oct 11 '15 at 13:30

0 Answers0