Sign in to follow this  
Happy SDE

Write as R32_UINT, read as R8G8B8A8_UNORM.

Recommended Posts

Hi forum!

I would like to write to texture 3 material parameters.

Each of the parameters are unorm 8 bit values, packed as one uint.

The idea is to write to texture R32_UINT, and read from it as R8G8B8A8_UNORM.

cbuffer PsCb
{
	uint   Mat; //Packed: RGB - material, A-not in use yet
	float3 pad;
}

struct PsOut
{
	...
	uint material : SV_TARGET2; //RGB - material, A-not in use yet
};

PsOut main(float3 normalVS : NORMAL, float2 uv : TEXCOORD0)
{
	PsOut ret;
	
	...
	ret.material = Mat;  //???

	return ret;
}

But any my attempt to create such kind of texture were errors/warnings from DX runtime like:

The Format (0x1c, R8G8B8A8_UNORM) is invalid, when creating a View; it is not a fully qualified Format castable from the Format of the Resource (0x27, R32_TYPELESS)

The only solution I can imagine – is to manually repack uint32 material data on a shader to 4 floats.

Is there an elegant way to write to texture R32_UINT, and read it as R8G8B8A8_UNORM via hardware or I should unpack uint to 4 floats?

Thanks in advance!

Edited by Happy SDE

Share this post


Link to post
Share on other sites

For render target views and shader resource views, the format that you use has to be from the same "family" as the format that you used when you created the actual texture resource. So if you create the texture with DXGI_FORMAT_R8G8B8A8_TYPELESS, you can create an RTV or SRV with any of the formats that start with "DXGI_FORMAT_R8G8B8A8". This doesn't include DXGI_FORMAT_R32_UINT, which is why the debug layer is complaining to you. The only exception to this rule is for unordered access views, which allow re-casting any 32-bit format as R32_UINT/INT/FLOAT so that you can work around limitations regarding reading from UAV's in FEATURE_LEVEL_11_0.

For your case, returning float's from your pixel shader that get converted to R8G8B8A8_UNORM should work fine. Just compute the [0-255] integer value that you want to store in each component, then divide by 255.0f. Alternatively, if you would prefer to output the raw integer value you can use R8G8B8A8_UINT to avoid any conversion issues:

uint4 output = uint4(Mat & 0xFF, (Mat >> 8) & 0xFF, (Mat >> 16) & 0xFF, 0);

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this