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).
But when I try it on my desktop, all I get is this mess:
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,...).