Skip to main content
GameDev.net gamedev.net
🔒 Locked

[solved] shader version & render target size

Started by vokuhila Aug 21, 2006 at 4:29 PM 1 replies 650+ views
Original Post
vokuhila
vokuhila
Hi, I need to filter my shadowmap textures to make the shadows blury. I got two filters the user can select from. The first is a simple linear filter, using a shader of version 1.1. The second one is a gaussian filter which uses PS 2.0. The user can also select the size of the shadowmaps. I think the engine will support sizes of 768, 1024, 1536 and 2048 pixels. Now the problem is that the gaussian filter (PS 2.0) doesn't work on rendertagets which are not power of 2 (1536 for example). The resulting image has some vertical stripes in it, but nothing that looks like the expected picture. However, It works perfectly on textures which are power of two. The linear filter (PS 1.1) works on every texture size. My graphics device is a Radeon 9800. Is this behaviour documented somewhere? Is there any Direct3D flag I can check? [Edited by - vokuhila on August 21, 2006 5:08:04 PM]
S1CA
S1CA
Check out the D3DPTEXTURECAPS_NONPOW2CONDITIONAL device cap (a D3DCAPS9.TextureCaps flag) which means "this device does support non-power-of-two textures, but there are some [documented] restrictions". The Radeon 9800 specifies that cap - could one of the restrictions be what you're seeing ?.


From the docs:

Quote:

D3DPTEXTURECAPS_NONPOW2CONDITIONAL
D3DPTEXTURECAPS_POW2 is also set, conditionally supports the use of 2D textures with dimensions that are not powers of two. A device that exposes this capability can use such a texture if all of the following requirements are met.

The texture addressing mode for the texture stage is set to D3DTADDRESS_CLAMP.
Texture wrapping for the texture stage is disabled (D3DRS_WRAP n set to 0).
Mipmapping is not in use (use magnification filter only).
Texture formats must not be D3DFMT_DXT1 through D3DFMT_DXT5.
If this flag is not set, and D3DPTEXTURECAPS_POW2 is also not set, then unconditional support is provided for 2D textures with dimensions that are not powers of two.

A texture that is not a power of two cannot be set at a stage that will be read based on a shader computation (such as the bem - ps and texm3x3 - ps instructions in pixel shaders versions 1_0 to 1_3). For example, these textures can be used to store bumps that will be fed into texture reads, but not the environment maps that are used in texbem - ps, texbeml - ps, and texm3x3spec - ps. This means that a texture with dimensions that are not powers of two cannot be addressed or sampled using texture coordinates computed within the shader. This type of operation is known as a dependent read and cannot be performed on these types of textures.


Odd that it works with SM 1.1 but not SM 2.0, but hardware and drivers can be strange like that (unless your 2.0 shader is performing some sort of dependent read to decide which texels to sample in the filter of course?).
Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site
vokuhila
vokuhila
Thank you S1CA, this is exactly what I was looking for (I checked the caps list before posting but was blind somehow)

The shader has no dependent reads.

So the solution will be to check for 3DPTEXTURECAPS_NONPOW2CONDITIONAL, and if that flag is enabled I simply round down to the next power of 2 size.


Thanks again, rating++ ;-)


EDIT:
I found out that it wasn't a problem with the device. My gauss shader produced inverted y coordinates in the range [-1,0]. No problem for pow of 2 textures, because the wraping hides that error. However, on non pow of 2 textures the texture coordinates get clamped automatically as documented. So that is where the vertical stripes came from.

[Edited by - vokuhila on August 22, 2006 11:06:14 AM]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.