Jump to content
  • Advertisement
Sign in to follow this  
Happy SDE

Packoffset question

This topic is 991 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

What is the use of packoffset?
 

In many tutorials I found people use it everywhere and I placed it until recently almost everywhere in my code, for example:
(register(b1) is here because it is a second buffer for a shader)

cbuffer PointLight: register(b1)
{
	float3 LightPosWS     : packoffset(c0);
	float  CosOuterCone   : packoffset(c0.w);
	float3 LightColor     : packoffset(c1);
	float  CosInnerCone   : packoffset(c1.w);
	float3 LightDirWS     : packoffset(c2);
	float  LightIntensity : packoffset(c2.w);
};

Without “packoffset” this code works the same.

 

20 minutes ago I’ve made a test and placed a lot of unaligned by 16-byte boundary data there.
In Debug and Release modes I can see the data inside video card’s buffer in places where I am expecting them to be without adding some “packoffset” keyword.

 

Question: in what situations it is useful to use “packoffset” keyword?

//C++
struct Extra //Non-aligned with 16 byte boundary
{
	XMFLOAT3 f1;
	XMFLOAT4 f2;
};
struct AmbData
{
	XMFLOAT3 color;
	Extra    extra[16]; // non-aligned in this structure
	float    padding;   // Align AmbData with 4 bytes to create buffer
};

//Test
void DefPass2::updatePsAmbientLightCb(const RdAmbientLight& light)
{
	D3D11_MAPPED_SUBRESOURCE res;
	_check_hr(m_context->Map(m_psAmbientCb.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &res));

	AmbData data;
	data.color = light.color;
	for (int t = 0; t < 16; ++t)
	{
		float i = (float)t;
		data.extra[t].f1 = { i, i, i };
		data.extra[t].f2 = { i +200, i + 200, i + 200, i + 200 };
	}
	data.padding = -1;

	memcpy(res.pData, &data, sizeof(data));

	m_context->Unmap(m_psAmbientCb.Get(), 0);
}
//HLSL
struct Extra
{
	float3 f1;
	float4 f2;
};

cbuffer AmbientLight: register(b1)
{
	float3 LightColor;
	Extra  extra[16];
	float  pad;
};
Edited by Happy SDE

Share this post


Link to post
Share on other sites
Advertisement

It lets you decouple the memory locations from their order in the struct. 

 

There's an implicit layout that you can figure out by looking at the struct if you know the alignment rules so it's not necessary to have them and sometimes weirdly verbose and potentially makes your code more brittle as you have two things to update every time you reorder your structs.

 

In C++ it's by default different because it's unlikely that your structs are 16 byte aligned. But you could do __declspec(align(16)) and then it would be quite similar, and you wouldn't need a padding variable (not that you should do this). 

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!