Graphics
Intel® graphics drivers and software, compatibility, troubleshooting, performance, and optimization
21693 Discussions

HLSL shader, issue with asuint/bit packing

Juliean
Novice
3,644 Views

I'm experiencing issues with a 2d tilemap-shader of mine, on a range of variety of intel-HD graphics chips.

The issue arised when I changed my algorithm to pack the offsets for each tile into the tilemap in one float, using bit-packing:

const auto makePackedTile = [&](uint16_t offX, uint16_t offY, uint8_t autotileId)
{
	AE_ASSERT(autotileId <= 8);
	uint32_t packed = autotileId;
	
	AE_ASSERT(offX <= 512);
	AE_ASSERT(offY <= 512);

	packed |= offX << 4;
	packed |= offY << 18;

	AE_ASSERT((packed & 0x0F) == autotileId);
	AE_ASSERT(((packed >> 4) & 0x3fff) == offX);
	AE_ASSERT((packed >> 18) == offY);

	return std::bit_cast<float>(packed);
};

Those values are stored in a 3d-RG32F-type texture, which is then read by my shader:

int2 calculateTileOffsets(uint packedTile, float autotileData[9])
{
	uint autotileId = packedTile & 0x0F;
	
	int2 vOffset;
	vOffset.x = (packedTile >> 4) & 0x3fff;
	vOffset.y = autotileData[autotileId];
	vOffset.y += packedTile >> 18;
	
	return vOffset;
}

// usage:
float2 tile = Tilemap.SampleLevel( PointClamp, float3(In[0].vPos.zw / vTileHeight.yz,(Out.layer + 0.5f)/numRealLayers),  0);
uint packedTile = asuint(tile.x);
if (packedTile != -1)
{
	Out.vPos.z = 1.0f - (tile.y + curr * 0.0000001f);
	float2 vTex0 = calculateTileOffsets(packedTile, autotileData) * vTileHeight.wx;

On any other card, including DX11-Reference-device, this shader works fine. On Intel GPU/driver, it will render the wrong tiles. From testing, it seems that the result aquired from asuint/the bit-unpacking it wrong. The content of cbuffers and the texture seems to be consistent with other devices. Also the float that I write into the texture in general seems to be correctly read back by the shader.

I haven't further been able to determine any plausable cause for this issue, or if there is anything wrong with the shader itself. I thereby belive that this most be some sort of bug in the intel-hardware or driver. Thus, I've attached a sample-project that you can run, to see the difference on nvidia/amd VS intel (for reference, it at least happens on Intel HD 4600, in case some cards might not exhibit this behaviour). Simply run the "bin/Acclimate Player.exe", and you should see as correct output, a rainbow-pattern 256x256 pixels repeated a few times across the screen. On Intel, you would get the upper-most 32x3px pixel tile (red-purple) repeated all over the screen.

I've also attached the full shader, in case graphics-debugger doesn't allow you to see it naturally. Please let me know if this is actually a bug with Intel GPU, or if there is anything I'm doing wrong in the shader.

0 Kudos
1 Solution
Juliean
Novice
3,613 Views

I actually found the/a solution. It seems to be something with the way of sampling from the 3D-texture.

I changed

float2 tile = Tilemap.SampleLevel( PointClamp, float3(In[0].vPos.zw / vTileHeight.yz,(Out.layer + 0.5f)/numRealLayers),  0);

to

float2 tile = Tilemap.Load(int4(In[0].vPos.zw, Out.layer, 0, 0));

Which seems to fix the problem on my test-system. Still not sure what exactly is wrong, and why it only broke a while ago. I could go back in my repository to see what the causing change where, but don't have the patience right now. Plus-side, the new solution appear to also be faster, which is why I even got the idea to change it in the first place (at least it is simpler and requires less data to be put in the cbuffer; though I'd have to benchmark).

Still, if somebody has any insight why the old version might work on Nvidia and not on others, I'd be (mildy) curious.

View solution in original post

0 Kudos
4 Replies
Stefan3D
Honored Contributor II
3,627 Views

Looks OK with my NVIDIA GPU, but on my AMD APU as you describe it for Intel.

Maybe RenderDoc helps?

 

AMD-Cezanne.png

Juliean
Novice
3,623 Views

AMD as well? That sounds bad, I though I could hotfix the issue by forcing the application so select the dedicated GPU, if available for most users.

I did have a look with the integrated graphics-debugger of visual studio, but didn't get far. I'll check out RenderDoc and see if its shader debugger is any better.

Though one thing I forgot, I tried replacing the components in "vOffset" in the function with static values of the tile-offsets, and it does render that tile if I do so. So the issue must be (somehow) in the bit-unmasking. Though I have no clue how I could express those differently, or if there is something wrong with it.

0 Kudos
Juliean
Novice
3,614 Views

I actually found the/a solution. It seems to be something with the way of sampling from the 3D-texture.

I changed

float2 tile = Tilemap.SampleLevel( PointClamp, float3(In[0].vPos.zw / vTileHeight.yz,(Out.layer + 0.5f)/numRealLayers),  0);

to

float2 tile = Tilemap.Load(int4(In[0].vPos.zw, Out.layer, 0, 0));

Which seems to fix the problem on my test-system. Still not sure what exactly is wrong, and why it only broke a while ago. I could go back in my repository to see what the causing change where, but don't have the patience right now. Plus-side, the new solution appear to also be faster, which is why I even got the idea to change it in the first place (at least it is simpler and requires less data to be put in the cbuffer; though I'd have to benchmark).

Still, if somebody has any insight why the old version might work on Nvidia and not on others, I'd be (mildy) curious.

0 Kudos
AndrewG_Intel
Employee
3,557 Views

Hello @Juliean


Thank you for posting on the Intel® communities.

We are glad to know that you were able to find a solution to the issue.


We would like to inform you that due to the Intel® HD Graphics 4600 has been discontinued, Intel Customer Service no longer supports inquiries for it, but perhaps fellow community members have the knowledge to jump in and help. You may also find the Discontinued Products website helpful to address your request.


In addition, for further assistance developing with Intel® Products, you may also refer to the Developer Software Forums and post your question under the proper subforum.


Finally, please keep in mind that this thread will no longer be monitored by Intel. Thank you for your understanding.


Best regards,

Andrew G.

Intel Customer Support Technician


0 Kudos
Reply