locked
How to query hardware tile size for tiled resources in DirectX 11.2 ?

    Question

  • I'm using a HD7850, and I was trying to see how I can implement tiled resources in DirectX 11.2 and since I also got an OpenGL renderer, there I can do something like

    glGetInternalformativ( GL_TEXTURE_2D, GL_RGBA8, GL_VIRTUAL_PAGE_SIZE_X_ARB, sizeof( int ), &X );//returns X=512
    glGetInternalformativ( GL_TEXTURE_2D, GL_RGBA8, GL_VIRTUAL_PAGE_SIZE_Y_ARB, sizeof( int ), &Y );//returns Y=256

    Which gives me the sizes by which the width/height must be divisible in order to make a sparse texture, but on DX11.2 I haven't found such a mechanism although the runtime actually knows what these values are ( see below )

    Upon a naive texture create of an arbitrary size say 1920x1080 I get this debug message:

    D3D11 ERROR: ID3D11Device::CreateTexture2D: The Dimensions are invalid. Width (value = 1920) and Height (value = 1080) must match. [ STATE_CREATION ERROR #101: CREATETEXTURE2D_INVALIDDIMENSIONS]
    D3D11 ERROR: ID3D11Device::CreateTexture2D: On a device with Tier 1 Tiled Resources support, Tiled Resources cannot be created with both more than one array slice and any mipmap that has a dimension not a multiple of a tile in extent. For the Tiled Resource being created, Mip [0] has (width=1920, height=1080) while the tile dimension for the given format is (width=512, height=256).  [ STATE_CREATION ERROR #101: CREATETEXTURE2D_INVALIDDIMENSIONS]

    It would be cool to know if Tier 2 actually supports arbitrary sizes (somehow), although I do get the feeling I have to manage that on my own ( I don't know everything about tiled resources yet, so correct me if I seem like a noob).

    So my question remains, how do I query the size of a tile ?

    PS: The Sample project just uses 1024x1024 without any queries which could fail if future hardware has a page size of say 768x768

    PS2: If this doesn't exist, please include it in DirectX 12 ?


    http://www.facebook.com/relativegames

    Saturday, April 19, 2014 6:05 PM

Answers

  • The tile size in bytes will be 64kB for the foreseeable future.  This is the granularity of the pages in the GPU MMU page table, so it is not easy to change.  If hardware does change to a new page size in some distant era (10 years?) it will be a nice multiple of the current 64kB page/tile size.

    While the tile size in *bytes* is fixed, the tile size in *pixels* may get larger as new compression formats appear that can pack more pixels into those same 64kB of memory.  I assume documentation will describe this once those formats are added.

    In any case, the tile sizes for D3D are completely determined by the bit depth of the texture used.  There is no variance across GPU vendors.  Applications never need to query the system they are on.  The documentation that needs to be posted on MSDN is this:

    0.5B/pix (e.g. BC1,BC4) = 512x256

    1B/pix (e.g.A8,BC2,BC7) = 256x256

    2B/pix (e.g.R8G8,R16f)    = 256x128

    4B/pix (e.g. RGBA8,R32F) = 128x128

    8B/pix (e.g. R16G16B16A16F) = 128x64

    16B/pix (e.g. R32G32B32A32F) = 64x64

    The advantage of this approach is that applications can pre-author their tile data on the disk ('wad' file), whereas with gl, you may have to re-tile all your content based on the GPU in the end-user's machine.

    https://tiledresources.codeplex.com/


    Kaz

    Thursday, April 24, 2014 6:20 PM

All replies

  • D3D implementations all support the same tile size of 64kBytes.  So you know the dimensions based on the bit depth:  1B/pix (e.g.A8,BC2,BC7) = 256x256, 2B/pix (e.g.R8G8,R16f) = 256x128, 4B/pix (e.g. RGBA8) = 128x128, etc. Non-power-of-2 bit-depths are not supported.
    Monday, April 21, 2014 6:46 PM
  • Well I'm sorry to disappoint but I was making a BC1 texture (from the tiled resources demo) and it fails at 256x256 or 512x512 (  "Mip [0] has (width=256, height=256) while the tile dimension for the given format is (width=512, height=256)" ), so it basically works only with multiples of the tile's width & height. If I actually knew what the base tile size is I could at least figure out the closest match to pass to CreateTexture2D. Right now, an algorithm that would work everywhere would just need to test random tile sizes until one matches, figure out the implementation size and then compute a size based on my needs (from my example, I would extend 1920x1080 to 2048x1280 for my card, but on other cards, this would be different).

    If what you are saying about the size in kilobytes is true, it still raises problems. A 64 KB tile could either be 512x256 (like on my card) or 256x512 on other cards, which is the same size but since the dimensions are inverted I would end up with the closest sized texture of 2048x1536.


    http://www.facebook.com/relativegames

    Tuesday, April 22, 2014 8:11 AM
  • Sorry, I didn't explain about BC1.  It is always 512x256 as you note.

    Because DX11 is a fairly rigorous standard in this area, the tile shapes for all formats are the same across all cards.  That's why there is no API to query it.  BC1 is always 512x256.  (in any texture where the tile is not square the shape will always be 2:1 landscape, so the horizontal width is 2x the vertical height).

    So since the surface should be an integer multiple of the tile size, in this case for a 1920x1080 surface, 2048x1280 should work on all cards.

    Note: the point of tiled resources is to enable massive textures (like 16kx16k), and then map only a few tiles to the screen from the resident pool.  So its pretty rare that someone would want to create a tiled resource only about the size of one screen.


    Kaz

    Thursday, April 24, 2014 1:28 AM
  • I did imagined someone would make huge virtual textures and I know DX has rigorous standards, but I also imagine that in the future tile sizes will inevitably increase. The thing I'm asking is, will all future tile sizes be a multiple of the current tile size ? Increasing the tile size by 2x, 4x would always work for 16K x 16K but increasing the tile shape by 7.5X will inevitably fail at some point in the future even if the tile is bigger. Also what happens when a future tile size is bigger than 1024x1024 (the one the demo uses) ? We will inevitably want to select between different tile sizes like it is possible in OpenGL.

    As a side note is there any official documentation on msdn about tile sizes and formats ?


    http://www.facebook.com/relativegames


    Thursday, April 24, 2014 9:36 AM
  • The tile size in bytes will be 64kB for the foreseeable future.  This is the granularity of the pages in the GPU MMU page table, so it is not easy to change.  If hardware does change to a new page size in some distant era (10 years?) it will be a nice multiple of the current 64kB page/tile size.

    While the tile size in *bytes* is fixed, the tile size in *pixels* may get larger as new compression formats appear that can pack more pixels into those same 64kB of memory.  I assume documentation will describe this once those formats are added.

    In any case, the tile sizes for D3D are completely determined by the bit depth of the texture used.  There is no variance across GPU vendors.  Applications never need to query the system they are on.  The documentation that needs to be posted on MSDN is this:

    0.5B/pix (e.g. BC1,BC4) = 512x256

    1B/pix (e.g.A8,BC2,BC7) = 256x256

    2B/pix (e.g.R8G8,R16f)    = 256x128

    4B/pix (e.g. RGBA8,R32F) = 128x128

    8B/pix (e.g. R16G16B16A16F) = 128x64

    16B/pix (e.g. R32G32B32A32F) = 64x64

    The advantage of this approach is that applications can pre-author their tile data on the disk ('wad' file), whereas with gl, you may have to re-tile all your content based on the GPU in the end-user's machine.

    https://tiledresources.codeplex.com/


    Kaz

    Thursday, April 24, 2014 6:20 PM
  • UPDATE : In d3d11.h from the Windows 8.1 SDK there's this

    #define    D3D11_2_TILED_RESOURCE_TILE_SIZE_IN_BYTES    ( 65536 )

    I also tested on Nvidia GTX 650 and noticed some interesting things ! The first being that it supports Tiled Resources Tier 1 and the DirectX 11.2 API ( You can get a ID3D11DeviceContext2 and use it) which was a bit unexpected. I then noticed that creating a BC1 on size 1920x1080 actually returns S_OK if ArraySize = 1.

    I tried creating textures of various other sizes and I seem to get the same errors about the fixed tile size mentioned above. At least now I know for sure that tiled resources have cross vendor support.


    http://www.facebook.com/relativegames




    Tuesday, April 29, 2014 1:27 PM