Home > Enterprise >  Shader working on my laptop, but not on my desktop
Shader working on my laptop, but not on my desktop

Time:02-26

I already posted this question on unity answers yesterday, but maybe anyone here can help? I've been trying to do some stuff that involves getting an image from a native plugin (in the form of a .dll file). I load the image data into a native buffer and then push that to the gpu in the form of a structured compute buffer. From there, I display the image using a shader (basically just doing something like uint idx = x y * width to get the correct index). And this works great on my laptop (ignore the low resolution, I lowered it to be able to inspect the values for each pixel; this is exactly how it's supposed to look).

working

But when I try it on my desktop, all I get is this mess:

broken

It's clearly displaying something, I'm almost able to make out contours of the text (it doesn't seem like I'm just getting random noise). But I can't seem to work out what's wrong here.

So far I've tried:

  • syncing the code across the two devices (it's excactly the same)
  • changing the unity version (tried 2020.3.26f1 and 2021.2.12f on both machines)
  • updating the graphics drivers
  • checking the directx version (DirectX 12 on both)
  • changing the editor game window resolution
  • comparing the contents of the buffer (the ComputeBuffer.GetData method is getting the same completely valid values on both machines)
  • building the project on both machines (both builds are working on my laptop and broken on my desktop)

Especially the last point really confused me. I'm running the same executable on both machines and it's working on my laptop with integrated graphics (not sure wether that could be relevant) but not on my desktop with a more modern dedicated gpu? The only idea I have left is that there might be some kind of optimization going on with my desktop's amd gpu that's not happening on my laptop's intel gpu. Any ideas on what I could try in the radeon software? Maybe it could even be some sort of bug (with unity or with my graphics driver)?

I'd be more than happy about any ideas on what could be the problem here (cause I have no clue at this point). And sorry if my grammar is a bit off at times, not a native speaker.

EDIT: Here's the shader I use to display the image.

Shader "Hidden/ReadUnpacked"
{
    Properties
    {
        _MainTex("Texture", 2D) = "white" {}
    }
        SubShader
    {
        // No culling or depth
        Cull Off ZWrite Off ZTest Always

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            static const uint PACKED_SIZE = 3;
            static const uint PIXELS_PER_PACK = 4;
            static const uint BYTES_PER_PIXEL = 8;
            static const uint PERCISION = 0xFF;     // 0xFF = 2^8

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            struct packed4
            {
                uint p[PACKED_SIZE];
            };

            struct unpacked4
            {
                fixed4 p[PIXELS_PER_PACK];
            };

            StructuredBuffer<packed4> InputBuffer;
            uint ImgIdx;
            float2 Resolution;
            float2 TexelOffset;

            fixed unpackSingle(packed4 val, uint idx)
            {
                uint pid = idx / PIXELS_PER_PACK;                   // pixel index
                uint sid = idx % PIXELS_PER_PACK * BYTES_PER_PIXEL; // shift index

                return ((val.p[pid] >> sid) & PERCISION) / (half)PERCISION;
            }

            unpacked4 unpack(packed4 packed)
            {
                unpacked4 unpacked;
                half r, g, b;
                uint idx = 0;

                [unroll(PIXELS_PER_PACK)] for (uint i = 0; i < PIXELS_PER_PACK; i  )
                {
                    fixed4 upx = fixed4(0, 0, 0, 1);

                    [unroll(PACKED_SIZE)] for (uint j = 0; j < PACKED_SIZE; j  )
                    {
                        upx[j] = unpackSingle(packed, idx  );
                    }

                    unpacked.p[i] = upx;
                }

                return unpacked;
            }

            fixed4 samplePackedBuffer(float2 uv)
            {
                int2 tc = float2(uv.x, 1 - uv.y) * Resolution;
                uint idx = tc.x   tc.y * Resolution.x;      // image pixel index
                idx  = Resolution.x * Resolution.y * ImgIdx;
                uint gid = floor(idx / PIXELS_PER_PACK);    // packed global index
                uint lid = idx % PIXELS_PER_PACK;           // packed local index

                packed4 ppx = InputBuffer[gid];
                unpacked4 upx = unpack(ppx);
                return upx.p[lid];
            }

            v2f vert(appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                fixed4 col = samplePackedBuffer(i.uv);

                return col;
            }
            ENDCG
        }
    }
}

CodePudding user response:

You should check all other 3D APIs (D3D11, Vulkan, OpenGL,...).

  • Related