diff options
author | Jason Ekstrand <[email protected]> | 2017-03-17 17:31:44 -0700 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2017-04-04 18:33:52 -0700 |
commit | 651ec926fc10258ddc567da44c231d5303b8740f (patch) | |
tree | b2a09499f3c7ba382d3c38f2804aef38bc1edcc8 /src/intel/vulkan/anv_allocator.c | |
parent | 439da38d184b5e9dddcfb245a2454879e7632649 (diff) |
anv: Add support for 48-bit addresses
This commit adds support for using the full 48-bit address space on
Broadwell and newer hardware. Thanks to certain limitations, not all
objects can be placed above the 32-bit boundary. In particular, general
and state base address need to live within 32 bits. (See also
Wa32bitGeneralStateOffset and Wa32bitInstructionBaseOffset.) In order
to handle this, we add a supports_48bit_address field to anv_bo and only
set EXEC_OBJECT_SUPPORTS_48B_ADDRESS if that bit is set. We set the bit
for all client-allocated memory objects but leave it false for
driver-allocated objects. While this is more conservative than needed,
all driver allocations should easily fit in the first 32 bits of address
space and keeps things simple because we don't have to think about
whether or not any given one of our allocation data structures will be
used in a 48-bit-unsafe way.
Reviewed-by: Kristian H. Kristensen <[email protected]>
Diffstat (limited to 'src/intel/vulkan/anv_allocator.c')
-rw-r--r-- | src/intel/vulkan/anv_allocator.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/src/intel/vulkan/anv_allocator.c b/src/intel/vulkan/anv_allocator.c index 45c663b6707..78327df3439 100644 --- a/src/intel/vulkan/anv_allocator.c +++ b/src/intel/vulkan/anv_allocator.c @@ -475,6 +475,32 @@ anv_block_pool_grow(struct anv_block_pool *pool, struct anv_block_state *state) * values back into pool. */ pool->map = map + center_bo_offset; pool->center_bo_offset = center_bo_offset; + + /* For block pool BOs we have to be a bit careful about where we place them + * in the GTT. There are two documented workarounds for state base address + * placement : Wa32bitGeneralStateOffset and Wa32bitInstructionBaseOffset + * which state that those two base addresses do not support 48-bit + * addresses and need to be placed in the bottom 32-bit range. + * Unfortunately, this is not quite accurate. + * + * The real problem is that we always set the size of our state pools in + * STATE_BASE_ADDRESS to 0xfffff (the maximum) even though the BO is most + * likely significantly smaller. We do this because we do not no at the + * time we emit STATE_BASE_ADDRESS whether or not we will need to expand + * the pool during command buffer building so we don't actually have a + * valid final size. If the address + size, as seen by STATE_BASE_ADDRESS + * overflows 48 bits, the GPU appears to treat all accesses to the buffer + * as being out of bounds and returns zero. For dynamic state, this + * usually just leads to rendering corruptions, but shaders that are all + * zero hang the GPU immediately. + * + * The easiest solution to do is exactly what the bogus workarounds say to + * do: restrict these buffers to 32-bit addresses. We could also pin the + * BO to some particular location of our choosing, but that's significantly + * more work than just not setting a flag. So, we explicitly DO NOT set + * the EXEC_OBJECT_SUPPORTS_48B_ADDRESS flag and the kernel does all of the + * hard work for us. + */ anv_bo_init(&pool->bo, gem_handle, size); pool->bo.map = map; |