Jump to content
  • Advertisement
Sign in to follow this  
leonard2012

Use DXGI_FORMAT_R8G8B8A8_UINT texture format in pixel shader

This topic is 2273 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

Hi all,
I tried to draw a 2D texture of R8G8B8A8_UINT format. Each texel is packed with the code

UINT *pt = texels;
unsigned char *pp = (unsigned char *)pixels;
for ( int i = 0; i < height; i++ )
for ( int j = 0; j < width; j++ ) {
r = UINT(*pp++);
g = UINT(*pp++);
b = UINT(*pp++);
a = UINT(*pp++);
*pt++ = r<<24 | g<<16 | b<<8 | a;
}

and unpacked in pixel shader like

float4 texPS(float4 posH : SV_POSITION,
float2 oTexC : TEXCOORD) : SV_Target
{
uint diffuse = gDiffuseMap.Sample( gTextureSampler, oTexC );
uint a = (diffuse & 0x000000FF);
uint b = (diffuse & 0x0000FF00) >> 8;
uint g = (diffuse & 0x00FF0000) >> 16;
uint r = (diffuse & 0xFF000000) >> 24;
return float4(r, g, b, a) / 255.0f;
}

Unfortunately this does not work, the error message triggered by DrawIndex function is:
[indent=1]D3D10: ERROR: ID3D10Device::DrawIndexed: The resource return type for component 0 declared in the shader code (FLOAT) is not compatible with the resource type bound to slot 0 of the Pixel Shader unit (UINT). This is invalid if the shader actually uses the view (e.g. it is not skipped due to shader code branching). [ EXECUTION ERROR #361: DEVICE_DRAW_RESOURCE_RETURN_TYPE_MISMATCH ]

[indent=1]D3D10: ERROR: ID3D10Device::DrawIndexed: The Shader Resource View in slot 0 of the Pixel Shader unit is using the Format (R8G8B8A8_UINT). This format does not support 'Sample', 'SampleLevel', 'SampleBias' or 'SampleGrad', at least one of which is being used on the Resource by the shader. This is invalid if the shader actually uses the view (e.g. it is not skipped due to shader code branching). [ EXECUTION ERROR #371: DEVICE_DRAW_RESOURCE_FORMAT_SAMPLE_UNSUPPORTED ]

I change the texture format to R32_UINT but still fails with similar error message:
[indent=1]D3D10: ERROR: ID3D10Device::DrawIndexed: The resource return type for component 0 declared in the shader code (FLOAT) is not compatible with the resource type bound to slot 0 of the Pixel Shader unit (UINT). This is invalid if the shader actually uses the view (e.g. it is not skipped due to shader code branching). [ EXECUTION ERROR #361: DEVICE_DRAW_RESOURCE_RETURN_TYPE_MISMATCH ]

[indent=1]D3D10: ERROR: ID3D10Device::DrawIndexed: The Shader Resource View in slot 0 of the Pixel Shader unit is using the Format (R32_UINT). This format does not support 'Sample', 'SampleLevel', 'SampleBias' or 'SampleGrad', at least one of which is being used on the Resource by the shader. This is invalid if the shader actually uses the view (e.g. it is not skipped due to shader code branching). [ EXECUTION ERROR #371: DEVICE_DRAW_RESOURCE_FORMAT_SAMPLE_UNSUPPORTED ]


It seems that Texture2D::Sample function does not support R32_UINT and R8G8B8A8_UINT format.

Share this post


Link to post
Share on other sites
Advertisement
To sample a UINT format, you need to declare your texture with a uint return type in your shader. The default is float4, which is why you're getting those errors.

For R8G8B8A8_UINT, you'll get 4 UINT's in your shader (not 1 uint, which is what your shader code is assuming). So you want to declare your texture like this:

Texture2D<uint4> gDiffuseMap;


For R32_UINT, you would declare it like this:

Texture2D<uint> gDiffuseMap;


However in you're just going to divide by 255 to get a [0,1] format, then you can just use a UNORM format and the texture unit will do the conversion for you.

Share this post


Link to post
Share on other sites
Thanks for your response, MJP. I followed your method to use R32_INT texture format. The packing code is the same as in my first post. This is part of the effect file:

Texture2D<uint> gDiffuseMap;
SamplerState gTextureSampler
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Wrap;
AddressV = Wrap;
};
uint texPS(float4 posH : SV_POSITION,
float2 oTexC : TEXCOORD) : SV_Target
{
return gDiffuseMap.Sample( gTextureSampler, oTexC );
}


However this effect file fail to compile:

2>E:\Projects\micaps\private\micaps\render\directx\shader.fx(70,5): error X4582: cannot sample from non-floating point texture formats.

2>E:\Projects\micaps\private\micaps\render\directx\shader.fx(84,25): There was an error compiling expression

Share this post


Link to post
Share on other sites
Yeah you have to use Load or the [] operator with integer formats, since filtering isn't supported.

Like I said earlier if you use R8G8B8A8_UNORM format instead and declare your Texture2D with float4 return type then you can use Sample and get the result you're expecting without having to manually unpack in the shader.

Share this post


Link to post
Share on other sites

Yeah you have to use Load or the [] operator with integer formats, since filtering isn't supported.

Like I said earlier if you use R8G8B8A8_UNORM format instead and declare your Texture2D with float4 return type then you can use Sample and get the result you're expecting without having to manually unpack in the shader.

Thank you MJP, I use R8G8B8A8_UNORM format and it works. The pixel shader code in effect file is clean and simple

Texture2D gDiffuseMap;
float4 texPS(float4 posH : SV_POSITION,
float2 oTexC : TEXCOORD) : SV_Target
{
return gDiffuseMap.Sample( gTextureSampler, oTexC );
}

Share this post


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

×

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!