Advertisement

UINT64 for resource size but only UINT32 for the resource view

Started by October 12, 2017 11:14 AM
6 comments, last by Matias Goldberg 7 years, 3 months ago

Hello guys,

I am wondering why D3D12 resource size has type UINT64 while resource view size is limited to UINT32.


typedef struct D3D12_RESOURCE_DESC {
  …	
  UINT64                   Width;
  … 
} D3D12_RESOURCE_DESC;

Vertex buffer view can be described in UINT32 types.


typedef struct D3D12_VERTEX_BUFFER_VIEW {
  D3D12_GPU_VIRTUAL_ADDRESS BufferLocation;
  UINT                      SizeInBytes;
  UINT                      StrideInBytes;
} D3D12_VERTEX_BUFFER_VIEW;

For the buffer we can specify offset for the first element as UINT64 but the buffer view should still be defined in UINT32 terms.


typedef struct D3D12_BUFFER_SRV {
  UINT64                 FirstElement;
  UINT                   NumElements;
  UINT                   StructureByteStride;
  D3D12_BUFFER_SRV_FLAGS Flags;
} D3D12_BUFFER_SRV;

Does it really mean that we can create, for instance, structured buffer of floats having MAX_UNIT64 elements (MAX_UNIT64 * sizeof(float) in byte size) but are not be able to create shader resource view which will enclose it completely since we are limited by UINT range?

Is there a specific reason for this? HLSL is restricted to UINT32 values. Calling function GetDimensions() on the resource of UINT64 size will not be able to produce valid values. I guess, it could be one of the reasons.

 

Thanks!

GPU address space is likely 64bit, so the memory allocator will work with these sizes, however descriptors are generally bitpacked as small as possible, so some sensible limits are chosen to help that goal.

Advertisement

The GPU's address space is likely quite a bit smaller than the full 64-bits. It may be as small as 32-bits on some older Intel parts, limiting you to resources no larger than 4GB in size, but 38 on newer ones I think. AMD's parts have generally been around the 40-bit or 48-bit range, and I think NVIDIA is 40 too.

You can query for MaxGPUVirtualAddressBitsPerResource from this structure: https://msdn.microsoft.com/en-us/library/windows/desktop/dn770364(v=vs.85).aspx

I've come pretty close with my sparse voxel work to hitting the 40-bit limit (an 8K * 8K * 8K R8 texture is 512GB / 39 bits), but generally only the 32-bit limit is going to pose anyone any problems.

Adam Miles - Principal Software Development Engineer - Microsoft Xbox Advanced Technology Group

Quote

but generally only the 32-bit limit is going to pose anyone any problems.

@ajmiles

Thank you for the info! Can you please rephrase the statetement I do not really grasp what you mean here

 

15 minutes ago, _void_ said:

@ajmiles

Thank you for the info! Can you please rephrase the statetement I do not really grasp what you mean here

 

Sorry, I was referring specifically to the older Intel Haswell parts only supporting a 32-bit virtual address per resource, it was actually 31-bits according to this table https://en.wikipedia.org/wiki/Feature_levels_in_Direct3D#Support_matrix. If on the Haswell GPUs you can only have a 2GB resource, or even 2GB per process as that table suggests, then it can be a bit restrictive.

One way to do Texture Streaming on D3D12 is to reserve virtual address space for the entire texture's mip chain, even including higher resolution mips that aren't yet streamed in due to proximity to the object. You can then using the Reserved Resources (aka Tiled Resources) API to commit physical memory to higher resolution mips as and when they get loaded. However, if you're always going to allocate the full amount of virtual memory, then you can run out of it very quickly, even if you're careful to only use 1GB of physical memory at any one time.

Adam Miles - Principal Software Development Engineer - Microsoft Xbox Advanced Technology Group

This has nothing to do with VA sizes.  The problem is that lots of HW is restricted to the HW limits that D3D11 specifies.

https://msdn.microsoft.com/en-us/library/windows/desktop/ff819065(v=vs.85).aspx

See VB:

D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP (2³²)

See SRV:

D3D11_REQ_BUFFER_RESOURCE_TEXEL_COUNT_2_TO_EXP (2²⁷) texels

Your resource can be larger than these values because a single resource can be offsetted for each of their bindings.

Advertisement
On 10/12/2017 at 8:14 AM, _void_ said:

Hello guys,

Does it really mean that we can create, for instance, structured buffer of floats having MAX_UNIT64 elements (MAX_UNIT64 * sizeof(float) in byte size) but are not be able to create shader resource view which will enclose it completely since we are limited by UINT range?

Yes. Everyone has cleared up that his is a HW limitation.

But I don't think nobody has hinted the obvious: You can create more than one view. The most common scenario is for manually managing memory: creating a large pool, and then having different meshes / const buffers / structured buffers living as views to subregions of it.

You just can't access all of it all at once. Though for example if you have a 6GB buffer, you could create 3 views of 2GBs each and bind them all 3 to the same shader.

This topic is closed to new replies.

Advertisement